mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-18 03:44:54 -04:00
aabb iterator: don't use IntRange, reduce more allocations
This commit is contained in:
parent
d711e077b7
commit
a21b1ea4c9
@ -17,44 +17,44 @@ import de.bixilon.minosoft.data.world.World
|
||||
import de.bixilon.minosoft.data.world.chunk.chunk.Chunk
|
||||
import de.bixilon.minosoft.data.world.iterator.WorldIterator
|
||||
import de.bixilon.minosoft.data.world.positions.BlockPosition
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.ceil
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.floor
|
||||
|
||||
class AABBIterator(
|
||||
private val rangeX: IntRange,
|
||||
private val rangeY: IntRange,
|
||||
private val rangeZ: IntRange,
|
||||
val min: BlockPosition,
|
||||
val max: BlockPosition,
|
||||
) : Iterator<BlockPosition> {
|
||||
private var count = 0
|
||||
private var x = rangeX.first
|
||||
private var y = rangeY.first
|
||||
private var z = rangeZ.first
|
||||
private var current = min
|
||||
|
||||
val size = maxOf(0, max.x - min.x + 1) * maxOf(0, max.y - min.y + 1) * maxOf(0, max.z - min.z + 1)
|
||||
|
||||
val size: Int = maxOf(0, rangeX.last - rangeX.first + 1) * maxOf(0, rangeY.last - rangeY.first + 1) * maxOf(0, rangeZ.last - rangeZ.first + 1)
|
||||
|
||||
constructor(aabb: AABB) : this(AABB.getRange(aabb.min.x, aabb.max.x), AABB.getRange(aabb.min.y, aabb.max.y), AABB.getRange(aabb.min.z, aabb.max.z))
|
||||
constructor(min: BlockPosition, max: BlockPosition) : this(min.x..max.x, min.y..max.y, min.z..max.z)
|
||||
constructor(minX: Int, minY: Int, minZ: Int, maxX: Int, maxY: Int, maxZ: Int) : this(minX..maxX, minY..maxY, minZ..maxZ)
|
||||
|
||||
constructor(aabb: AABB) : this(aabb.min.floor, aabb.max.ceil - 1)
|
||||
constructor(minX: Int, minY: Int, minZ: Int, maxX: Int, maxY: Int, maxZ: Int) : this(BlockPosition(minX, minY, minZ), BlockPosition(maxX, maxY, maxZ))
|
||||
|
||||
override fun hasNext(): Boolean {
|
||||
return count < size
|
||||
}
|
||||
|
||||
override fun next(): BlockPosition {
|
||||
if (count >= size) throw IllegalStateException("No positions available anymore!")
|
||||
if (!hasNext()) throw IllegalStateException("No positions available anymore!")
|
||||
|
||||
val current = current
|
||||
var next = current
|
||||
|
||||
val position = BlockPosition(x, y, z)
|
||||
if (z < rangeZ.last) z++ else {
|
||||
z = rangeZ.first
|
||||
if (y < rangeY.last) y++ else {
|
||||
y = rangeY.first
|
||||
if (x < rangeX.last) x++
|
||||
if (next.x < max.x) next = next.plusX() else {
|
||||
next = next.with(x = min.x)
|
||||
if (next.z < max.z) next = next.plusZ() else {
|
||||
next = next.with(z = min.z)
|
||||
|
||||
if (next.y < max.y) next = next.plusY()
|
||||
}
|
||||
}
|
||||
|
||||
this.current = next
|
||||
|
||||
count++
|
||||
return position
|
||||
return current
|
||||
}
|
||||
|
||||
fun blocks(world: World, chunk: Chunk? = null): WorldIterator {
|
||||
|
@ -159,14 +159,17 @@ object VecUtil {
|
||||
return (((axisHash and 0xF) / 15.0f) - 0.5f) / 2.0f
|
||||
}
|
||||
|
||||
return Vec3(
|
||||
val offset = Vec3(
|
||||
x = horizontal(positionHash),
|
||||
y = if (offsetType === RandomOffsetTypes.XYZ) {
|
||||
(((positionHash shr 4 and 0xF) / 15.0f) - 1.0f) / 5.0f
|
||||
} else {
|
||||
0.0f
|
||||
},
|
||||
z = horizontal(positionHash shr 8)).clamp(-maxModelOffset, maxModelOffset)
|
||||
z = horizontal(positionHash shr 8))
|
||||
offset.clampAssign(-maxModelOffset, maxModelOffset)
|
||||
|
||||
return offset
|
||||
}
|
||||
|
||||
fun Vec3.clampAssign(min: Float, max: Float) {
|
||||
@ -174,6 +177,7 @@ object VecUtil {
|
||||
this.y = y.clamp(min, max)
|
||||
this.z = z.clamp(min, max)
|
||||
}
|
||||
|
||||
fun Vec3.clamp(min: Float, max: Float): Vec3 {
|
||||
return Vec3(
|
||||
x = x.clamp(min, max),
|
||||
|
@ -45,8 +45,11 @@ object Vec3dUtil {
|
||||
val Vec3d.Companion.MAX: Vec3d
|
||||
get() = Vec3d(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE)
|
||||
|
||||
val Vec3d.floor: Vec3i
|
||||
get() = Vec3i(this.x.floor, this.y.floor, this.z.floor)
|
||||
val Vec3d.floor: BlockPosition
|
||||
get() = BlockPosition(this.x.floor, this.y.floor, this.z.floor)
|
||||
|
||||
val Vec3d.ceil: BlockPosition
|
||||
get() = BlockPosition(this.x.ceil, this.y.ceil, this.z.ceil)
|
||||
|
||||
val Vec3d.blockPosition: BlockPosition
|
||||
get() = BlockPosition(this.x.floor, this.y.floor, this.z.floor)
|
||||
|
@ -41,6 +41,7 @@ import de.bixilon.minosoft.protocol.PlayerPublicKey
|
||||
import de.bixilon.minosoft.protocol.network.session.play.PlaySession
|
||||
import de.bixilon.minosoft.protocol.packets.s2c.play.sound.PlayedSound
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition.VELOCITY_NETWORK_DIVIDER
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_14W04A
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_14W21A
|
||||
@ -378,7 +379,7 @@ class PlayInByteBuffer : InByteBuffer {
|
||||
}
|
||||
|
||||
fun readVelocity(): Vec3d {
|
||||
return Vec3d(readShort(), readShort(), readShort()) * (1.0f / ProtocolDefinition.VELOCITY_NETWORK_DIVIDER)
|
||||
return Vec3d(readShort() * (1.0 / VELOCITY_NETWORK_DIVIDER), readShort() * (1.0 / VELOCITY_NETWORK_DIVIDER), readShort() * (1.0 / VELOCITY_NETWORK_DIVIDER))
|
||||
}
|
||||
|
||||
fun readVibrationSource(): VibrationSource {
|
||||
|
@ -27,7 +27,39 @@ class AABBIteratorTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun singleBlock() {
|
||||
fun `correct min and max`() {
|
||||
val iterator = AABBIterator(1, 2, 3, 4, 5, 6)
|
||||
assertEquals(iterator.min, BlockPosition(1, 2, 3))
|
||||
assertEquals(iterator.max, BlockPosition(4, 5, 6))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct floor and ceil not`() {
|
||||
val iterator = AABB(1.0, 2.0, 3.0, 4.0, 5.0, 6.0).positions()
|
||||
assertEquals(iterator.min, BlockPosition(1, 2, 3))
|
||||
assertEquals(iterator.max, BlockPosition(3, 4, 5))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct floor and ceil`() {
|
||||
val iterator = AABB(1.2, 2.2, 3.3, 4.5, 5.7, 6.4).positions()
|
||||
assertEquals(iterator.min, BlockPosition(1, 2, 3))
|
||||
assertEquals(iterator.max, BlockPosition(4, 5, 6))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `less than single block`() {
|
||||
val aabb = AABB(0.0, 0.0, 0.0, 0.1, 0.1, 0.1)
|
||||
|
||||
val positions = aabb.positions()
|
||||
assertEquals(1, positions.size)
|
||||
assertTrue(positions.hasNext())
|
||||
assertEquals(BlockPosition(0, 0, 0), positions.next())
|
||||
assertFalse(positions.hasNext())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `exactly one block`() {
|
||||
val aabb = AABB(0.0, 0.0, 0.0, 1.0, 1.0, 1.0)
|
||||
|
||||
val positions = aabb.positions()
|
||||
@ -43,14 +75,14 @@ class AABBIteratorTest {
|
||||
|
||||
val positions = aabb.positions()
|
||||
assertEquals(24, positions.size)
|
||||
val set: MutableSet<BlockPosition> = mutableSetOf()
|
||||
val set: MutableSet<BlockPosition> = hashSetOf()
|
||||
|
||||
for (position in positions) {
|
||||
set += position
|
||||
}
|
||||
assertEquals(24, set.size)
|
||||
|
||||
assertEquals(setOf(
|
||||
assertEquals(hashSetOf(
|
||||
BlockPosition(0, 0, 0),
|
||||
BlockPosition(0, 0, 1),
|
||||
BlockPosition(0, 0, 2),
|
||||
@ -108,9 +140,10 @@ class AABBIteratorTest {
|
||||
|
||||
val positions = aabb.positions()
|
||||
assertEquals(64, positions.size)
|
||||
for (x in -2 until 2) {
|
||||
for (y in -2 until 2) {
|
||||
for (z in -2 until 2) {
|
||||
|
||||
for (y in -2 until 2) {
|
||||
for (z in -2 until 2) {
|
||||
for (x in -2 until 2) {
|
||||
assertEquals(BlockPosition(x, y, z), positions.next())
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user