mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 11:24:56 -04:00
test every quad of side for face culling
This workarounds unoptimized face properties and fixes culling between grass blocks
This commit is contained in:
parent
4ab3fc08a7
commit
1c4e5e9eae
@ -58,168 +58,144 @@ class FaceCullingTest {
|
||||
assertFalse(FaceCulling.canCull(createState(), face, Directions.DOWN, null))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun selfNotTouching() {
|
||||
val face = createFace(properties = null)
|
||||
val neighbour = createBlock()
|
||||
assertFalse(FaceCulling.canCull(createState(), face, Directions.DOWN, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun neighbourNotTouching() {
|
||||
val face = createFace()
|
||||
val neighbour = createBlock(properties = null)
|
||||
assertFalse(FaceCulling.canCull(createState(), face, Directions.DOWN, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fullNeighbour() {
|
||||
val face = createFace()
|
||||
val neighbour = createBlock()
|
||||
assertTrue(FaceCulling.canCull(createState(), face, Directions.DOWN, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun sizeMatch() {
|
||||
val face = createFace(properties = FaceProperties(Vec2(0.0f, 0.5f), Vec2(1.0f, 0.5f), TextureTransparencies.OPAQUE))
|
||||
val neighbour = createBlock(properties = side(FaceProperties(Vec2(0.0f, 0.5f), Vec2(1.0f, 0.5f), TextureTransparencies.OPAQUE)))
|
||||
assertTrue(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun greaterNeighbour() {
|
||||
val face = createFace(properties = FaceProperties(Vec2(0.0f, 0.5f), Vec2(1.0f, 0.5f), TextureTransparencies.OPAQUE))
|
||||
val neighbour = createBlock(properties = side(FaceProperties(Vec2(0.0f, 0.5f), Vec2(1.0f, 0.6f), TextureTransparencies.OPAQUE)))
|
||||
assertTrue(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun smallerNeighbour() {
|
||||
val face = createFace(properties = FaceProperties(Vec2(0.0f, 0.5f), Vec2(1.0f, 0.5f), TextureTransparencies.OPAQUE))
|
||||
val neighbour = createBlock(properties = side(FaceProperties(Vec2(0.0f, 0.5f), Vec2(1.0f, 0.4f), TextureTransparencies.OPAQUE)))
|
||||
assertFalse(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun noSize() {
|
||||
val face = createFace(properties = FaceProperties(Vec2(0.0f, 0.5f), Vec2(1.0f, 0.5f), TextureTransparencies.OPAQUE))
|
||||
val neighbour = createBlock(properties = side(FaceProperties(Vec2(0.1f, 0.5f), Vec2(1.0f, 0.5f), TextureTransparencies.OPAQUE)))
|
||||
assertTrue(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shiftedNeighbour1() {
|
||||
val face = createFace(properties = FaceProperties(Vec2(0.0f, 0.4f), Vec2(1.0f, 0.5f), TextureTransparencies.OPAQUE))
|
||||
val neighbour = createBlock(properties = side(FaceProperties(Vec2(0.1f, 0.4f), Vec2(1.0f, 0.5f), TextureTransparencies.OPAQUE)))
|
||||
assertFalse(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shiftedNeighbour2() {
|
||||
val face = createFace(properties = FaceProperties(Vec2(0.0f, 0.4f), Vec2(1.0f, 0.5f), TextureTransparencies.OPAQUE))
|
||||
val neighbour = createBlock(properties = side(FaceProperties(Vec2(0.1f, 0.4f), Vec2(1.0f, 0.6f), TextureTransparencies.OPAQUE)))
|
||||
assertFalse(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shiftedNeighbour3() {
|
||||
val face = createFace(properties = FaceProperties(Vec2(0.1f, 0.8f), Vec2(0.9f, 0.9f), TextureTransparencies.OPAQUE))
|
||||
val neighbour = createBlock(properties = side(FaceProperties(Vec2(0.1f, 0.5f), Vec2(0.95f, 0.95f), TextureTransparencies.OPAQUE)))
|
||||
assertTrue(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun multipleNeighbourFaces() {
|
||||
val face = createFace(properties = FaceProperties(Vec2(0.1f, 0.3f), Vec2(0.9f, 0.9f), TextureTransparencies.OPAQUE))
|
||||
val neighbour = createBlock(properties = side(FaceProperties(Vec2(0.1f, 0.2f), Vec2(0.95f, 0.4f), TextureTransparencies.OPAQUE), FaceProperties(Vec2(0.1f, 0.4f), Vec2(0.95f, 0.6f), TextureTransparencies.OPAQUE), FaceProperties(Vec2(0.1f, 0.6f), Vec2(0.95f, 0.95f), TextureTransparencies.OPAQUE)))
|
||||
assertTrue(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `transparent side on opaque neighbour`() {
|
||||
val face = createFace(transparency = TextureTransparencies.TRANSPARENT)
|
||||
val neighbour = createBlock(transparency = TextureTransparencies.OPAQUE)
|
||||
assertTrue(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `translucent side on opaque neighbour`() {
|
||||
val face = createFace(transparency = TextureTransparencies.TRANSLUCENT)
|
||||
val neighbour = createBlock(transparency = TextureTransparencies.OPAQUE)
|
||||
assertTrue(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `opaque side on transparent neighbour`() {
|
||||
val face = createFace(transparency = TextureTransparencies.OPAQUE)
|
||||
val neighbour = createBlock(transparency = TextureTransparencies.TRANSPARENT)
|
||||
assertFalse(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `opaque side on translucent neighbour`() {
|
||||
val face = createFace(transparency = TextureTransparencies.OPAQUE)
|
||||
val neighbour = createBlock(transparency = TextureTransparencies.TRANSLUCENT)
|
||||
assertFalse(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `same block, both sides transparent`() {
|
||||
val face = createFace(transparency = TextureTransparencies.TRANSPARENT)
|
||||
val neighbour = createBlock(transparency = TextureTransparencies.TRANSPARENT)
|
||||
assertTrue(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `same block, both sides translucent`() {
|
||||
val face = createFace(transparency = TextureTransparencies.TRANSLUCENT)
|
||||
val neighbour = createBlock(transparency = TextureTransparencies.TRANSLUCENT)
|
||||
assertTrue(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `different block, both sides transparent`() {
|
||||
val face = createFace(transparency = TextureTransparencies.TRANSPARENT)
|
||||
val neighbour = createBlock(transparency = TextureTransparencies.TRANSPARENT)
|
||||
assertFalse(FaceCulling.canCull(createState(1), face, Directions.EAST, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `different block, both sides translucent`() {
|
||||
val face = createFace(transparency = TextureTransparencies.TRANSLUCENT)
|
||||
val neighbour = createBlock(transparency = TextureTransparencies.TRANSLUCENT)
|
||||
assertFalse(FaceCulling.canCull(createState(1), face, Directions.EAST, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `same block, transparent sides, force no cull`() {
|
||||
val face = createFace(transparency = TextureTransparencies.TRANSPARENT)
|
||||
val neighbour = createBlock(transparency = TextureTransparencies.TRANSPARENT)
|
||||
assertFalse(FaceCulling.canCull(createBlock(forceNoCull()), face, Directions.EAST, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `same block, translucent sides, force no cull`() {
|
||||
val face = createFace(transparency = TextureTransparencies.TRANSLUCENT)
|
||||
val neighbour = createBlock(transparency = TextureTransparencies.TRANSLUCENT)
|
||||
assertFalse(FaceCulling.canCull(createBlock(forceNoCull()), face, Directions.EAST, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `opaque side on transparent block`() {
|
||||
val face = createFace(transparency = TextureTransparencies.OPAQUE)
|
||||
val neighbour = createBlock(transparency = TextureTransparencies.TRANSPARENT)
|
||||
assertFalse(FaceCulling.canCull(createBlock(), face, Directions.EAST, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `transparent side on opaque block`() {
|
||||
val face = createFace(transparency = TextureTransparencies.TRANSPARENT)
|
||||
val neighbour = createBlock(transparency = TextureTransparencies.OPAQUE)
|
||||
assertTrue(FaceCulling.canCull(createBlock(), face, Directions.EAST, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `opaque but no invoked custom cull`() {
|
||||
val block = object : Block(minosoft("dummy"), BlockSettings()), CustomBlockCulling {
|
||||
override val hardness get() = Broken()
|
||||
@ -233,8 +209,16 @@ class FaceCullingTest {
|
||||
assertTrue(FaceCulling.canCull(createBlock(block), face, Directions.EAST, neighbour))
|
||||
}
|
||||
|
||||
private fun side(vararg properties: FaceProperties): SideProperties {
|
||||
return SideProperties(arrayOf(*properties), properties.first().transparency)
|
||||
|
||||
fun `opaque but neighbour opaque and transparent`() { // grass block + overlay
|
||||
val face = createFace(TextureTransparencies.OPAQUE, properties = FaceProperties(Vec2(0.0f, 0.0f), Vec2(1.0f, 1.0f), TextureTransparencies.OPAQUE))
|
||||
val neighbour = createBlock(properties = side(FaceProperties(Vec2(0.0f, 0.0f), Vec2(1.0f, 1.0f), TextureTransparencies.OPAQUE), FaceProperties(Vec2(0.0f, 0.0f), Vec2(1.0f, 1.0f), TextureTransparencies.TRANSPARENT), transparency = null))
|
||||
assertTrue(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour))
|
||||
}
|
||||
|
||||
|
||||
private fun side(vararg properties: FaceProperties, transparency: TextureTransparencies? = properties.first().transparency): SideProperties {
|
||||
return SideProperties(arrayOf(*properties), transparency)
|
||||
}
|
||||
|
||||
private fun forceNoCull() = object : Block(minosoft("dummy"), BlockSettings()), CustomBlockCulling {
|
||||
|
@ -36,12 +36,21 @@ object FaceCulling {
|
||||
// impossible to see that face
|
||||
return true
|
||||
}
|
||||
if (neighbourProperties.transparency == null) {
|
||||
for (property in neighbourProperties.faces) {
|
||||
if (property.transparency != TextureTransparencies.OPAQUE) continue
|
||||
if (!properties.isCoveredBy(property)) continue
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if (state.block is CustomBlockCulling) {
|
||||
return state.block.shouldCull(state, properties, direction, neighbour)
|
||||
}
|
||||
|
||||
if (neighbourProperties.transparency == null) return false // can not determinate it
|
||||
if (neighbourProperties.transparency == null) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (state.block != neighbour.block) return false
|
||||
if (neighbourProperties.transparency == properties.transparency) return true
|
||||
@ -59,17 +68,26 @@ object FaceCulling {
|
||||
var area = 0.0f
|
||||
|
||||
for (quad in this.faces) {
|
||||
val width = minOf(target.end.x, quad.end.x) - maxOf(quad.start.x, target.start.x)
|
||||
val height = minOf(target.end.y, quad.end.y) - maxOf(quad.start.y, target.start.y)
|
||||
|
||||
area += width * height
|
||||
area += quad.getSideArea(target)
|
||||
}
|
||||
|
||||
return area
|
||||
}
|
||||
|
||||
private fun FaceProperties.getSideArea(target: FaceProperties): Float {
|
||||
val width = minOf(target.end.x, end.x) - maxOf(start.x, target.start.x)
|
||||
val height = minOf(target.end.y, end.y) - maxOf(start.y, target.start.y)
|
||||
|
||||
return width * height
|
||||
}
|
||||
|
||||
fun FaceProperties.isCoveredBy(properties: SideProperties): Boolean {
|
||||
val area = properties.getSideArea(this)
|
||||
return surface <= area
|
||||
}
|
||||
|
||||
fun FaceProperties.isCoveredBy(properties: FaceProperties): Boolean {
|
||||
val area = properties.getSideArea(this)
|
||||
return surface <= area
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user