commonMain.ru.casperix.math.array.int8.ByteArray3D.kt Maven / Gradle / Ivy
package ru.casperix.math.array.int8
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
data class ByteArray3D(val data: ByteArray, val dimension: Vector3i) {
val size = dimension.volume()
constructor(dimension: Vector3i) : this(ByteArray(dimension.volume()), dimension)
constructor(sizeX: Int, sizeY: Int, sizeZ: Int) : this(Vector3i(sizeX, sizeY, sizeZ))
init {
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 ByteArray3D
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
return result
}
fun setByte(position: Vector3i, value:Byte) {
val index = indexFromPosition(position)
data[index]= value
}
fun getByte(position: Vector3i):Byte {
val index = indexFromPosition(position)
return data[index]
}
fun setColumn(position: Vector2i, value: ByteArray) {
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): ByteArray {
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)
}
fun positionFromIndex(index: Int): Vector2i {
if (index < 0 || index >= size) throw Error("Index $index is outside array")
val x = index % dimension.x
val y = index / dimension.x
return Vector2i(x, y)
}
}