From e85ae8d3e3f51445def517bdd5b53af04766370a Mon Sep 17 00:00:00 2001 From: Twometer Date: Fri, 8 Oct 2021 11:42:31 +0200 Subject: [PATCH] Custom bounding box providers --- neko-demo/assets/shaders/debug.nks | 2 +- neko-demo/src/main/kotlin/DemoApp.kt | 31 +++++++++++++++---- .../de/twometer/neko/player/PickEngine.kt | 2 +- .../component/BoundingBoxProviderComponent.kt | 12 +++++++ .../de/twometer/neko/scene/nodes/Geometry.kt | 7 +++-- 5 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 neko-engine/src/main/kotlin/de/twometer/neko/scene/component/BoundingBoxProviderComponent.kt diff --git a/neko-demo/assets/shaders/debug.nks b/neko-demo/assets/shaders/debug.nks index e57f2a4..a5f4049 100644 --- a/neko-demo/assets/shaders/debug.nks +++ b/neko-demo/assets/shaders/debug.nks @@ -22,6 +22,6 @@ out vec4 color; void main() { - color = vec4(1,1,1,1); + color = vec4(1,1,0,1); } #end fragment \ No newline at end of file diff --git a/neko-demo/src/main/kotlin/DemoApp.kt b/neko-demo/src/main/kotlin/DemoApp.kt index 501035d..bd76768 100644 --- a/neko-demo/src/main/kotlin/DemoApp.kt +++ b/neko-demo/src/main/kotlin/DemoApp.kt @@ -2,16 +2,22 @@ import de.twometer.neko.audio.SoundEngine import de.twometer.neko.core.AppConfig import de.twometer.neko.core.NekoApp import de.twometer.neko.events.KeyPressEvent +import de.twometer.neko.events.RenderForwardEvent +import de.twometer.neko.render.Primitives import de.twometer.neko.res.* +import de.twometer.neko.scene.AABB import de.twometer.neko.scene.Color +import de.twometer.neko.scene.component.BoundingBoxProviderComponent import de.twometer.neko.scene.nodes.* import de.twometer.neko.util.MathF.toRadians import imgui.ImGui import org.greenrobot.eventbus.Subscribe +import org.joml.Matrix4f import org.joml.Vector3f import org.lwjgl.glfw.GLFW.* +import org.lwjgl.opengl.GL11.* -class DemoApp : NekoApp(AppConfig(windowTitle = "Neko Engine Demo")) { +class DemoApp : NekoApp(AppConfig(windowTitle = "Neko Engine Demo", windowIcon = "icon.png")) { private lateinit var girl: ModelNode private lateinit var rin: ModelNode @@ -28,10 +34,23 @@ class DemoApp : NekoApp(AppConfig(windowTitle = "Neko Engine Demo")) { val testFont = FontCache.get("lucida") + scene.rootNode.attachChild(ModelLoader.load("astronaut.fbx").also { + it.transform.translation.set(-1.7f, 0.25f, 16f) + it.transform.rotation.rotateX(toRadians(90f)) + //it.transform.rotation.rotateY(toRadians(-45f)) + it.scanTree(ScanFilters.GEOMETRY) { n -> + n.attachComponent(BoundingBoxProviderComponent { + AABB(Vector3f(), Vector3f(1f, 1f, 1f)) + }) + } + + it.playAnimation(it.animations[1]) + }) + scene.rootNode.attachChild(ModelLoader.load("girl.fbx").also { it.animations.add(AnimationCache.get("walk.ani")) it.transform.scale.set(0.0001) - it.transform.translation.set(-1.7f,0.25f,16f) + it.transform.translation.set(-1.7f, 0.25f, 16f) it.transform.rotation.rotateX(toRadians(90f)) it.transform.rotation.rotateY(toRadians(-5f)) it.playAnimation(it.animations[1]) @@ -80,7 +99,7 @@ class DemoApp : NekoApp(AppConfig(windowTitle = "Neko Engine Demo")) { it.transform.translation.set(2f, 2f, 0f) }) - scene.rootNode.attachChild(ModelLoader.load("skeld.obj")) + //scene.rootNode.attachChild(ModelLoader.load("skeld.obj")) val lightPositions = RawLoader.loadLines("lights.txt") for (pos in lightPositions) { @@ -137,7 +156,7 @@ class DemoApp : NekoApp(AppConfig(windowTitle = "Neko Engine Demo")) { ImGui.text("SCALE:" + this.transform.scale) if (ImGui.button("RESET")) { - this.transform.reset() + this.transform.scale.set(1f, 1f, 1f) } } ImGui.end() @@ -167,7 +186,7 @@ class DemoApp : NekoApp(AppConfig(windowTitle = "Neko Engine Demo")) { } } - /*@Subscribe + @Subscribe fun renderFwd(e: RenderForwardEvent) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) val shader = ShaderCache.get("debug.nks") @@ -183,7 +202,7 @@ class DemoApp : NekoApp(AppConfig(windowTitle = "Neko Engine Demo")) { } glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) - }*/ + } } fun main() { diff --git a/neko-engine/src/main/kotlin/de/twometer/neko/player/PickEngine.kt b/neko-engine/src/main/kotlin/de/twometer/neko/player/PickEngine.kt index 0dc1e13..4a7cfdc 100644 --- a/neko-engine/src/main/kotlin/de/twometer/neko/player/PickEngine.kt +++ b/neko-engine/src/main/kotlin/de/twometer/neko/player/PickEngine.kt @@ -25,7 +25,7 @@ class PickEngine(private val scene: Scene) { val nodes = ArrayList() scene.rootNode.scanTree { if (it is Geometry && it.aabb != null && it.canPick) { - val transformedAABB = it.aabb.transform(it.compositeTransform.matrix) + val transformedAABB = it.aabb!!.transform(it.compositeTransform.matrix) val distSq = scene.camera.position.distanceSquared(transformedAABB.center) if (distSq <= maxDistanceSq) nodes.add(NodeReference(it, transformedAABB, distSq)) diff --git a/neko-engine/src/main/kotlin/de/twometer/neko/scene/component/BoundingBoxProviderComponent.kt b/neko-engine/src/main/kotlin/de/twometer/neko/scene/component/BoundingBoxProviderComponent.kt new file mode 100644 index 0000000..eea0606 --- /dev/null +++ b/neko-engine/src/main/kotlin/de/twometer/neko/scene/component/BoundingBoxProviderComponent.kt @@ -0,0 +1,12 @@ +package de.twometer.neko.scene.component + +import de.twometer.neko.scene.AABB +import de.twometer.neko.scene.nodes.Node + +class BoundingBoxProviderComponent(val provider: (Node) -> AABB) : BaseComponent() { + + override fun createInstance(): BaseComponent { + return BoundingBoxProviderComponent(provider) + } + +} \ No newline at end of file diff --git a/neko-engine/src/main/kotlin/de/twometer/neko/scene/nodes/Geometry.kt b/neko-engine/src/main/kotlin/de/twometer/neko/scene/nodes/Geometry.kt index a6f4537..047af82 100644 --- a/neko-engine/src/main/kotlin/de/twometer/neko/scene/nodes/Geometry.kt +++ b/neko-engine/src/main/kotlin/de/twometer/neko/scene/nodes/Geometry.kt @@ -5,13 +5,14 @@ import de.twometer.neko.scene.AABB import de.twometer.neko.scene.Bone import de.twometer.neko.scene.Material import de.twometer.neko.scene.Mesh +import de.twometer.neko.scene.component.BoundingBoxProviderComponent import de.twometer.neko.scene.component.SkeletonComponent import org.lwjgl.opengl.GL30.* import java.nio.Buffer import java.nio.FloatBuffer import java.nio.IntBuffer -class Geometry(name: String, material: Material = Material.Default, val aabb: AABB? = null) : +class Geometry(name: String, material: Material = Material.Default, private val _aabb: AABB? = null) : RenderableNode(name = name, material = material) { private var vao: Int = -1 @@ -24,6 +25,8 @@ class Geometry(name: String, material: Material = Material.Default, val aabb: AA private var numIndices: Int = -1 private var numVertices: Int = -1 var canPick: Boolean = true + val aabb: AABB? + get() = getComponent()?.provider?.invoke(this) ?: _aabb companion object { const val VertexIdx = 0 @@ -65,7 +68,7 @@ class Geometry(name: String, material: Material = Material.Default, val aabb: AA } override fun createInstance(): Node { - val node = Geometry(name = name, material = material, aabb = aabb) + val node = Geometry(name = name, material = material, _aabb = _aabb) node.initializeFrom(this) node.vao = vao node.vertexBuffer = vertexBuffer