commonMain.ru.casperix.math.array.uint8.UByteArray3D.kt Maven / Gradle / Ivy
package ru.casperix.math.array.uint8
import ru.casperix.math.array.ArrayAccessND
import ru.casperix.math.vector.int32.Vector2i
import ru.casperix.math.vector.int32.Vector3i
import kotlinx.serialization.Serializable
/**
* Alternative for ByteMap2D, IntMap2D, Map2D, etc.
* See AlphaMapTest & PixelMapTest for sample
*/
@Serializable
@OptIn(ExperimentalUnsignedTypes::class)
data class UByteArray3D(val data: UByteArray, val dimension: Vector3i) {
val size = dimension.volume()
constructor(dimension: Vector3i) : this(UByteArray(dimension.volume()), dimension)
constructor(sizeX: Int, sizeY: Int, sizeZ: Int) : this(Vector3i(sizeX, sizeY, sizeZ))
init {
if (dimension.lessOrEq(Vector3i.ZERO)) {
throw Error("Dimension must be non negative")
}
if (data.size != size) {
throw Error("Expected size is $size, but actual is ${data.size}")
}
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false
other as UByteArray3D
if (dimension != other.dimension) return false
if (size != other.size) return false
if (!data.contentEquals(other.data)) return false
return true
}
override fun hashCode(): Int {
var result = data.contentHashCode()
result = 31 * result + dimension.hashCode()
result = 31 * result + size.hashCode()
return result
}
fun setByte(position: Vector3i, value:UByte) {
val index = indexFromPosition(position)
data[index]= value
}
fun getByte(position: Vector3i):UByte {
val index = indexFromPosition(position)
return data[index]
}
fun setColumn(position: Vector2i, value: UByteArray) {
if (value.size != dimension.z) throw Error("Expected size is ${dimension.z}, but actual is ${value.size}")
val index = indexFromPosition(position)
val start = index * dimension.z
value.copyInto(data, start)
}
fun getColumn(position: Vector2i): UByteArray {
val index = indexFromPosition(position)
val start = index * dimension.z
return data.sliceArray(start until start + dimension.z)
}
private fun indexFromPosition(position: Vector3i): Int {
return ArrayAccessND.index3D(dimension, position)
}
private fun indexFromPosition(position: Vector2i): Int {
return ArrayAccessND.index2D(dimension.getXY(), position)
}
}