mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 18:34:56 -04:00
improve voxel side calculating
Less memory allocation, faster performance, better results. Still not perfect
This commit is contained in:
parent
199aab67d7
commit
aca80648d3
@ -15,8 +15,8 @@ package de.bixilon.minosoft.data.registries.blocks.light
|
||||
|
||||
import de.bixilon.minosoft.data.Axes
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.registries.shapes.side.SideQuad
|
||||
import de.bixilon.minosoft.data.registries.shapes.side.VoxelSide
|
||||
import de.bixilon.minosoft.data.registries.shapes.side.VoxelSideSet
|
||||
import de.bixilon.minosoft.data.registries.shapes.voxel.AbstractVoxelShape
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
|
||||
|
||||
@ -34,7 +34,8 @@ class DirectedProperty(
|
||||
companion object {
|
||||
private val TRUE = BooleanArray(Directions.SIZE) { true }
|
||||
private val FALSE = BooleanArray(Directions.SIZE) { false }
|
||||
private val FULL_SIDE = VoxelSide(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
private val FULL_SIDE = SideQuad(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
private val REQUIRED_SURFACE_AREA = FULL_SIDE.surfaceArea() - 0.0001f // add some padding for floating point
|
||||
|
||||
private val BooleanArray.isSimple: Boolean?
|
||||
get() {
|
||||
@ -69,11 +70,13 @@ class DirectedProperty(
|
||||
}
|
||||
|
||||
|
||||
private fun AbstractVoxelShape.getSide(side: Directions): VoxelSideSet {
|
||||
private fun AbstractVoxelShape.getSide(side: Directions): VoxelSide? {
|
||||
// ToDo: This whole calculation is technically wrong, it could be that 2 different sides of 2 blocks are "free". That means that light can still not pass the blocks, but
|
||||
// this algorithm does not cover it. Let's see it as performance hack
|
||||
|
||||
val sides: MutableSet<VoxelSide> = ObjectOpenHashSet()
|
||||
if (this.aabbs == 0) return null
|
||||
|
||||
val sides: MutableSet<SideQuad> = ObjectOpenHashSet()
|
||||
|
||||
for (aabb in this) {
|
||||
when (side.axis) {
|
||||
@ -81,41 +84,60 @@ class DirectedProperty(
|
||||
if ((side == Directions.DOWN && aabb.min.y != 0.0) || (side == Directions.UP && aabb.max.y != 1.0)) {
|
||||
continue
|
||||
}
|
||||
sides += VoxelSide(aabb.min.x, aabb.min.z, aabb.max.x, aabb.max.z)
|
||||
val side = SideQuad(aabb.min.x, aabb.min.z, aabb.max.x, aabb.max.z)
|
||||
if (side.surfaceArea() > 0.0f) {
|
||||
sides += side
|
||||
}
|
||||
}
|
||||
|
||||
Axes.X -> {
|
||||
if ((side == Directions.WEST && aabb.min.x != 0.0) || (side == Directions.EAST && aabb.max.x != 1.0)) {
|
||||
continue
|
||||
}
|
||||
sides += VoxelSide(aabb.min.y, aabb.min.z, aabb.max.y, aabb.max.z)
|
||||
val side = SideQuad(aabb.min.y, aabb.min.z, aabb.max.y, aabb.max.z)
|
||||
if (side.surfaceArea() > 0.0f) {
|
||||
sides += side
|
||||
}
|
||||
}
|
||||
|
||||
Axes.Z -> {
|
||||
if ((side == Directions.NORTH && aabb.min.z != 0.0) || (side == Directions.SOUTH && aabb.max.z != 1.0)) {
|
||||
continue
|
||||
}
|
||||
sides += VoxelSide(aabb.min.x, aabb.min.y, aabb.max.x, aabb.max.y)
|
||||
val side = SideQuad(aabb.min.x, aabb.min.y, aabb.max.x, aabb.max.y)
|
||||
if (side.surfaceArea() > 0.0f) {
|
||||
sides += side
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return VoxelSideSet(sides)
|
||||
if (sides.isEmpty()) return null
|
||||
|
||||
return VoxelSide(sides)
|
||||
}
|
||||
|
||||
private fun VoxelSide.getSideArea(target: SideQuad): Float {
|
||||
// overlapping is broken, see https://stackoverflow.com/questions/7342935/algorithm-to-compute-total-area-covered-by-a-set-of-overlapping-segments
|
||||
var area = 0.0f
|
||||
|
||||
for (quad in this) {
|
||||
val width = minOf(target.max.x, quad.max.x) - maxOf(quad.min.x, target.min.x)
|
||||
val height = minOf(target.max.y, quad.max.y) - maxOf(quad.min.y, target.min.y)
|
||||
|
||||
area += width * height
|
||||
}
|
||||
|
||||
return area
|
||||
}
|
||||
|
||||
fun AbstractVoxelShape.isSideCovered(direction: Directions): Boolean {
|
||||
val side = getSide(direction)
|
||||
if (side.isEmpty()) {
|
||||
return false
|
||||
}
|
||||
// this should be improved: https://stackoverflow.com/questions/76373725/check-if-a-quad-is-fully-covered-by-a-set-of-others
|
||||
val side = getSide(direction) ?: return false
|
||||
|
||||
val rest = FULL_SIDE - side
|
||||
var compacted = rest.compact()
|
||||
if (rest != compacted) {
|
||||
compacted = FULL_SIDE - compacted
|
||||
}
|
||||
val surface = side.getSideArea(FULL_SIDE)
|
||||
|
||||
return !FULL_SIDE.touches(compacted)
|
||||
return surface >= REQUIRED_SURFACE_AREA
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.data.registries.shapes.side
|
||||
|
||||
import com.google.common.base.Objects
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
|
||||
|
||||
data class SideQuad(
|
||||
val min: Vec2,
|
||||
val max: Vec2,
|
||||
) {
|
||||
private val hashCode = Objects.hashCode(min.hashCode(), max.hashCode())
|
||||
|
||||
constructor(minX: Float, minZ: Float, maxX: Float, maxZ: Float) : this(Vec2(minOf(minX, maxX), minOf(minZ, maxZ)), Vec2(maxOf(minX, maxX), maxOf(minZ, maxZ)))
|
||||
constructor(minX: Double, minZ: Double, maxX: Double, maxZ: Double) : this(Vec2(minOf(minX, maxX).toFloat(), minOf(minZ, maxZ).toFloat()), Vec2(maxOf(minX, maxX).toFloat(), maxOf(minZ, maxZ).toFloat()))
|
||||
|
||||
|
||||
fun touches(other: SideQuad): Boolean {
|
||||
return !(this.min.x > other.max.x || other.min.x > this.max.x || this.min.y > other.max.y || other.min.y > this.max.y)
|
||||
}
|
||||
|
||||
infix operator fun minus(set: VoxelSide): VoxelSide {
|
||||
val result: MutableSet<SideQuad> = ObjectOpenHashSet()
|
||||
|
||||
for (side in set.sides) {
|
||||
result += (this minus side).sides
|
||||
}
|
||||
|
||||
return VoxelSide(result)
|
||||
}
|
||||
|
||||
infix operator fun minus(other: SideQuad): VoxelSide {
|
||||
val result: MutableSet<SideQuad> = ObjectOpenHashSet()
|
||||
|
||||
|
||||
if (other.min.x > min.x && other.min.x < max.x) {
|
||||
result += SideQuad(min.x, min.y, other.min.x, max.y)
|
||||
}
|
||||
if (other.min.y > min.y && other.min.y < max.y) {
|
||||
result += SideQuad(min.x, min.y, max.x, other.min.y)
|
||||
}
|
||||
|
||||
if (max.x > other.max.x) {
|
||||
result += SideQuad(other.max.x, min.y, max.x, max.y)
|
||||
}
|
||||
if (max.y > other.max.y) {
|
||||
result += SideQuad(min.x, other.max.y, max.x, max.y)
|
||||
}
|
||||
|
||||
|
||||
return VoxelSide(result)
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return hashCode
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other !is SideQuad) return false
|
||||
if (hashCode != other.hashCode) return false
|
||||
return min == other.min && max == other.max
|
||||
}
|
||||
|
||||
fun surfaceArea(): Float {
|
||||
val surface = (max.x - min.x) * (max.y - min.y)
|
||||
if (surface <= 0.0f) return 0.0f
|
||||
return surface
|
||||
}
|
||||
}
|
@ -13,105 +13,23 @@
|
||||
|
||||
package de.bixilon.minosoft.data.registries.shapes.side
|
||||
|
||||
import com.google.common.base.Objects
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
|
||||
class VoxelSide(
|
||||
val sides: Set<SideQuad>,
|
||||
) : Iterable<SideQuad> {
|
||||
|
||||
data class VoxelSide(
|
||||
val min: Vec2,
|
||||
val max: Vec2,
|
||||
) {
|
||||
private val hashCode = Objects.hashCode(min.hashCode(), max.hashCode())
|
||||
fun isEmpty(): Boolean = sides.isEmpty()
|
||||
|
||||
constructor(minX: Float, minZ: Float, maxX: Float, maxZ: Float) : this(Vec2(minOf(minX, maxX), minOf(minZ, maxZ)), Vec2(maxOf(minX, maxX), maxOf(minZ, maxZ)))
|
||||
constructor(minX: Double, minZ: Double, maxX: Double, maxZ: Double) : this(Vec2(minOf(minX, maxX).toFloat(), minOf(minZ, maxZ).toFloat()), Vec2(maxOf(minX, maxX).toFloat(), maxOf(minZ, maxZ).toFloat()))
|
||||
|
||||
|
||||
fun touches(set: VoxelSideSet): Boolean {
|
||||
for (side in set) {
|
||||
if (touches(side)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun touches(other: VoxelSide): Boolean {
|
||||
return !(this.min.x > other.max.x || other.min.x > this.max.x || this.min.y > other.max.y || other.min.y > this.max.y)
|
||||
}
|
||||
|
||||
infix operator fun minus(set: VoxelSideSet): VoxelSideSet {
|
||||
val result: MutableSet<VoxelSide> = ObjectOpenHashSet()
|
||||
|
||||
for (side in set.sides) {
|
||||
result += (this minus side).sides
|
||||
}
|
||||
|
||||
return VoxelSideSet(result)
|
||||
}
|
||||
|
||||
infix operator fun minus(other: VoxelSide): VoxelSideSet {
|
||||
val result: MutableSet<VoxelSide> = ObjectOpenHashSet()
|
||||
|
||||
|
||||
if (other.min.x > min.x && other.min.x < max.x) {
|
||||
result += VoxelSide(min.x, min.y, other.min.x, max.y)
|
||||
}
|
||||
if (other.min.y > min.y && other.min.y < max.y) {
|
||||
result += VoxelSide(min.x, min.y, max.x, other.min.y)
|
||||
}
|
||||
|
||||
if (max.x > other.max.x) {
|
||||
result += VoxelSide(other.max.x, min.y, max.x, max.y)
|
||||
}
|
||||
if (max.y > other.max.y) {
|
||||
result += VoxelSide(min.x, other.max.y, max.x, max.y)
|
||||
}
|
||||
|
||||
|
||||
return VoxelSideSet(result)
|
||||
}
|
||||
|
||||
infix fun or(other: VoxelSide): VoxelSide {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
fun compact(side: VoxelSide): VoxelSideSet {
|
||||
var minX = min.x
|
||||
var minY = min.y
|
||||
var maxX = max.x
|
||||
var maxY = max.y
|
||||
|
||||
var changes = 0
|
||||
if (side.min.y == minY && side.min.x < minX) {
|
||||
minX = side.min.x; changes++
|
||||
} else if (side.min.x == minX && side.min.y < minY) {
|
||||
minY = side.min.y;changes++
|
||||
}
|
||||
|
||||
if (side.max.y == maxY && side.max.x > maxX) {
|
||||
maxX = side.max.x;changes++
|
||||
} else if (side.max.x == maxX && side.min.y > maxY) {
|
||||
maxY = side.max.y;changes++
|
||||
}
|
||||
|
||||
if (changes == 0) {
|
||||
val set: MutableSet<VoxelSide> = ObjectOpenHashSet(2)
|
||||
set += this
|
||||
set += side
|
||||
return VoxelSideSet(set)
|
||||
}
|
||||
|
||||
return VoxelSideSet(setOf(VoxelSide(minX, minY, maxX, maxY)))
|
||||
override fun iterator(): Iterator<SideQuad> {
|
||||
return sides.iterator()
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return hashCode
|
||||
return sides.hashCode()
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other !is VoxelSide) return false
|
||||
if (hashCode != other.hashCode) return false
|
||||
return min == other.min && max == other.max
|
||||
if (hashCode() != other.hashCode()) return false
|
||||
return sides == other.sides
|
||||
}
|
||||
}
|
||||
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.data.registries.shapes.side
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
|
||||
|
||||
class VoxelSideSet(
|
||||
val sides: Set<VoxelSide>,
|
||||
) : Iterable<VoxelSide> {
|
||||
|
||||
fun isEmpty(): Boolean = sides.isEmpty()
|
||||
|
||||
override fun iterator(): Iterator<VoxelSide> {
|
||||
return sides.iterator()
|
||||
}
|
||||
|
||||
fun compact(): VoxelSideSet {
|
||||
if (this.sides.size <= 1) {
|
||||
return this
|
||||
}
|
||||
|
||||
val next: MutableSet<VoxelSide> = ObjectOpenHashSet()
|
||||
|
||||
val array = this.sides.toTypedArray()
|
||||
for (i in 1 until sides.size) {
|
||||
next += array[i - 1].compact(array[i])
|
||||
}
|
||||
val set = VoxelSideSet(next)
|
||||
|
||||
if (next.size < this.sides.size) {
|
||||
return set.compact()
|
||||
}
|
||||
|
||||
return set
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return sides.hashCode()
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other !is VoxelSideSet) return false
|
||||
if (hashCode() != other.hashCode()) return false
|
||||
return sides == other.sides
|
||||
}
|
||||
}
|
@ -80,7 +80,7 @@ internal class DirectedPropertyTest {
|
||||
assertTrue(shape.isSideCovered(Directions.EAST))
|
||||
}
|
||||
|
||||
// @Test // TODO: This test is correct, isSideCovered is broken
|
||||
@Test
|
||||
fun testSideCovered6() {
|
||||
val shape = VoxelShape(
|
||||
AABB(0.0f, 0.0f, 0.0f, 1.0f, 0.5f, 1.0f),
|
||||
@ -109,4 +109,35 @@ internal class DirectedPropertyTest {
|
||||
assertFalse(shape.isSideCovered(Directions.WEST))
|
||||
assertFalse(shape.isSideCovered(Directions.EAST))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSideCovered8() { // overlapping
|
||||
val shape = VoxelShape(
|
||||
AABB(0.0f, 0.0f, 0.0f, 1.0f, 0.6f, 1.0f),
|
||||
AABB(0.0f, 0.4f, 0.5f, 1.0f, 1.0f, 1.0f),
|
||||
)
|
||||
|
||||
assertTrue(shape.isSideCovered(Directions.DOWN))
|
||||
assertFalse(shape.isSideCovered(Directions.UP))
|
||||
assertFalse(shape.isSideCovered(Directions.NORTH))
|
||||
assertTrue(shape.isSideCovered(Directions.SOUTH))
|
||||
assertFalse(shape.isSideCovered(Directions.WEST))
|
||||
assertFalse(shape.isSideCovered(Directions.EAST))
|
||||
}
|
||||
|
||||
// @Test // TODO: This test is correct, isSideCovered is broken
|
||||
fun testSideCovered9() { // overlapping
|
||||
val shape = VoxelShape(
|
||||
AABB(0.0f, 0.0f, 0.0f, 1.0f, 0.6f, 1.0f),
|
||||
AABB(0.1f, 0.0f, 0.0f, 0.9f, 0.8f, 1.0f),
|
||||
AABB(0.0f, 0.4f, 0.5f, 1.0f, 0.9f, 1.0f),
|
||||
)
|
||||
|
||||
assertTrue(shape.isSideCovered(Directions.DOWN))
|
||||
assertFalse(shape.isSideCovered(Directions.UP))
|
||||
assertFalse(shape.isSideCovered(Directions.NORTH))
|
||||
assertTrue(shape.isSideCovered(Directions.SOUTH))
|
||||
assertFalse(shape.isSideCovered(Directions.WEST))
|
||||
assertFalse(shape.isSideCovered(Directions.EAST))
|
||||
}
|
||||
}
|
||||
|
@ -20,15 +20,15 @@ internal class VoxelSideTest {
|
||||
|
||||
@Test
|
||||
fun testMinus1() {
|
||||
val a = VoxelSide(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = VoxelSide(0.0f, 0.0f, 0.5f, 0.5f)
|
||||
val a = SideQuad(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = SideQuad(0.0f, 0.0f, 0.5f, 0.5f)
|
||||
|
||||
val result = a - b
|
||||
|
||||
assertEquals(
|
||||
setOf(
|
||||
VoxelSide(0.0f, 0.5f, 1.0f, 1.0f),
|
||||
VoxelSide(0.5f, 0.0f, 1.0f, 1.0f),
|
||||
SideQuad(0.0f, 0.5f, 1.0f, 1.0f),
|
||||
SideQuad(0.5f, 0.0f, 1.0f, 1.0f),
|
||||
),
|
||||
result.sides
|
||||
)
|
||||
@ -36,17 +36,17 @@ internal class VoxelSideTest {
|
||||
|
||||
@Test
|
||||
fun testMinus2() {
|
||||
val a = VoxelSide(1.0f, 1.0f, 4.0f, 4.0f)
|
||||
val b = VoxelSide(2.0f, 2.0f, 3.0f, 3.0f)
|
||||
val a = SideQuad(1.0f, 1.0f, 4.0f, 4.0f)
|
||||
val b = SideQuad(2.0f, 2.0f, 3.0f, 3.0f)
|
||||
|
||||
val result = a - b
|
||||
|
||||
assertEquals(
|
||||
setOf(
|
||||
VoxelSide(1.0f, 1.0f, 4.0f, 2.0f),
|
||||
VoxelSide(3.0f, 1.0f, 4.0f, 4.0f),
|
||||
VoxelSide(1.0f, 3.0f, 4.0f, 4.0f),
|
||||
VoxelSide(1.0f, 1.0f, 2.0f, 4.0f),
|
||||
SideQuad(1.0f, 1.0f, 4.0f, 2.0f),
|
||||
SideQuad(3.0f, 1.0f, 4.0f, 4.0f),
|
||||
SideQuad(1.0f, 3.0f, 4.0f, 4.0f),
|
||||
SideQuad(1.0f, 1.0f, 2.0f, 4.0f),
|
||||
),
|
||||
result.sides
|
||||
)
|
||||
@ -54,60 +54,29 @@ internal class VoxelSideTest {
|
||||
|
||||
@Test
|
||||
fun testMinus3() {
|
||||
val a = VoxelSide(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = VoxelSide(1.0f, 1.0f, 2.0f, 2.0f)
|
||||
val a = SideQuad(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = SideQuad(1.0f, 1.0f, 2.0f, 2.0f)
|
||||
|
||||
val result = a - b
|
||||
|
||||
assertEquals(emptySet<VoxelSide>(), result.sides)
|
||||
assertEquals(emptySet<SideQuad>(), result.sides)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMinus4() {
|
||||
val a = VoxelSide(0.0f, 0.0f, 0.5f, 0.5f)
|
||||
val b = VoxelSide(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val a = SideQuad(0.0f, 0.0f, 0.5f, 0.5f)
|
||||
val b = SideQuad(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
|
||||
val result = a - b
|
||||
|
||||
assertEquals(emptySet<VoxelSide>(), result.sides)
|
||||
assertEquals(emptySet<SideQuad>(), result.sides)
|
||||
}
|
||||
|
||||
private fun testOr1() {
|
||||
val a = VoxelSide(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = VoxelSide(0.0f, 0.0f, 0.5f, 0.5f)
|
||||
|
||||
val or = a or b
|
||||
assertEquals(or, b)
|
||||
}
|
||||
|
||||
private fun testOr2() {
|
||||
val a = VoxelSide(0.0f, 0.0f, 3.0f, 3.0f)
|
||||
val b = VoxelSide(1.0f, 1.0f, 2.0f, 2.0f)
|
||||
|
||||
val or = a or b
|
||||
assertEquals(or, b)
|
||||
}
|
||||
|
||||
private fun testOr3() {
|
||||
val a = VoxelSide(1.0f, 1.0f, 2.0f, 2.0f)
|
||||
val b = VoxelSide(0.0f, 0.0f, 3.0f, 3.0f)
|
||||
|
||||
val or = a or b
|
||||
assertEquals(or, a)
|
||||
}
|
||||
|
||||
private fun testOr4() {
|
||||
val a = VoxelSide(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = VoxelSide(0.0f, 0.0f, 0.5f, 1.0f)
|
||||
|
||||
val or = a or b
|
||||
assertEquals(or, b)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTouches1() {
|
||||
val a = VoxelSide(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = VoxelSide(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val a = SideQuad(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = SideQuad(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
|
||||
assertTrue(a.touches(b))
|
||||
assertTrue(b.touches(a))
|
||||
@ -115,8 +84,8 @@ internal class VoxelSideTest {
|
||||
|
||||
@Test
|
||||
fun testTouches2() {
|
||||
val a = VoxelSide(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = VoxelSide(0.0f, 0.0f, 0.5f, 0.5f)
|
||||
val a = SideQuad(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = SideQuad(0.0f, 0.0f, 0.5f, 0.5f)
|
||||
|
||||
assertTrue(a.touches(b))
|
||||
assertTrue(b.touches(a))
|
||||
@ -124,8 +93,8 @@ internal class VoxelSideTest {
|
||||
|
||||
@Test
|
||||
fun testTouches3() {
|
||||
val a = VoxelSide(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = VoxelSide(-1.0f, -1.0f, 0.5f, 0.5f)
|
||||
val a = SideQuad(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = SideQuad(-1.0f, -1.0f, 0.5f, 0.5f)
|
||||
|
||||
assertTrue(a.touches(b))
|
||||
assertTrue(b.touches(a))
|
||||
@ -133,8 +102,8 @@ internal class VoxelSideTest {
|
||||
|
||||
@Test
|
||||
fun testTouches4() {
|
||||
val a = VoxelSide(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = VoxelSide(-1.0f, -1.0f, 2.0f, 2.0f)
|
||||
val a = SideQuad(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = SideQuad(-1.0f, -1.0f, 2.0f, 2.0f)
|
||||
|
||||
assertTrue(a.touches(b))
|
||||
assertTrue(b.touches(a))
|
||||
@ -142,8 +111,8 @@ internal class VoxelSideTest {
|
||||
|
||||
@Test
|
||||
fun testTouches5() {
|
||||
val a = VoxelSide(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = VoxelSide(0.1f, -1.0f, 2.0f, 0.9f)
|
||||
val a = SideQuad(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = SideQuad(0.1f, -1.0f, 2.0f, 0.9f)
|
||||
|
||||
assertTrue(a.touches(b))
|
||||
assertTrue(b.touches(a))
|
||||
@ -151,8 +120,8 @@ internal class VoxelSideTest {
|
||||
|
||||
@Test
|
||||
fun testTouches6() {
|
||||
val a = VoxelSide(0.0f, 0.0f, 3.0f, 3.0f)
|
||||
val b = VoxelSide(1.0f, 1.0f, 2.0f, 2.0f)
|
||||
val a = SideQuad(0.0f, 0.0f, 3.0f, 3.0f)
|
||||
val b = SideQuad(1.0f, 1.0f, 2.0f, 2.0f)
|
||||
|
||||
assertTrue(a.touches(b))
|
||||
assertTrue(b.touches(a))
|
||||
@ -160,8 +129,8 @@ internal class VoxelSideTest {
|
||||
|
||||
@Test
|
||||
fun testTouches7() {
|
||||
val a = VoxelSide(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = VoxelSide(1.0f, 1.0f, 2.0f, 2.0f)
|
||||
val a = SideQuad(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = SideQuad(1.0f, 1.0f, 2.0f, 2.0f)
|
||||
|
||||
assertTrue(a.touches(b))
|
||||
assertTrue(b.touches(a))
|
||||
@ -169,8 +138,8 @@ internal class VoxelSideTest {
|
||||
|
||||
@Test
|
||||
fun testTouches8() {
|
||||
val a = VoxelSide(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = VoxelSide(2.0f, 2.0f, 3.0f, 3.0f)
|
||||
val a = SideQuad(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = SideQuad(2.0f, 2.0f, 3.0f, 3.0f)
|
||||
|
||||
assertFalse(a.touches(b))
|
||||
assertFalse(b.touches(a))
|
||||
@ -178,8 +147,8 @@ internal class VoxelSideTest {
|
||||
|
||||
@Test
|
||||
fun testTouches9() {
|
||||
val a = VoxelSide(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = VoxelSide(0.0f, 2.0f, 3.0f, 3.0f)
|
||||
val a = SideQuad(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = SideQuad(0.0f, 2.0f, 3.0f, 3.0f)
|
||||
|
||||
assertFalse(a.touches(b))
|
||||
assertFalse(b.touches(a))
|
||||
@ -187,8 +156,8 @@ internal class VoxelSideTest {
|
||||
|
||||
@Test
|
||||
fun testTouches10() {
|
||||
val a = VoxelSide(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = VoxelSide(2.0f, 0.0f, 3.0f, 3.0f)
|
||||
val a = SideQuad(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val b = SideQuad(2.0f, 0.0f, 3.0f, 3.0f)
|
||||
|
||||
assertFalse(a.touches(b))
|
||||
assertFalse(b.touches(a))
|
||||
@ -196,8 +165,8 @@ internal class VoxelSideTest {
|
||||
|
||||
@Test
|
||||
fun testTouches11() {
|
||||
val a = VoxelSide(2.0f, 0.0f, 3.0f, 3.0f)
|
||||
val b = VoxelSide(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val a = SideQuad(2.0f, 0.0f, 3.0f, 3.0f)
|
||||
val b = SideQuad(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
|
||||
assertFalse(a.touches(b))
|
||||
assertFalse(b.touches(a))
|
||||
@ -205,8 +174,8 @@ internal class VoxelSideTest {
|
||||
|
||||
@Test
|
||||
fun testTouches12() {
|
||||
val a = VoxelSide(0.0f, 2.0f, 3.0f, 3.0f)
|
||||
val b = VoxelSide(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val a = SideQuad(0.0f, 2.0f, 3.0f, 3.0f)
|
||||
val b = SideQuad(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
|
||||
assertFalse(a.touches(b))
|
||||
assertFalse(b.touches(a))
|
||||
@ -214,8 +183,8 @@ internal class VoxelSideTest {
|
||||
|
||||
@Test
|
||||
fun testTouches13() {
|
||||
val a = VoxelSide(2.0f, 2.0f, 3.0f, 3.0f)
|
||||
val b = VoxelSide(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
val a = SideQuad(2.0f, 2.0f, 3.0f, 3.0f)
|
||||
val b = SideQuad(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
|
||||
assertFalse(a.touches(b))
|
||||
assertFalse(b.touches(a))
|
||||
|
Loading…
x
Reference in New Issue
Block a user