diff --git a/build.gradle b/build.gradle index 1692e622..e96f5ab1 100644 --- a/build.gradle +++ b/build.gradle @@ -14,7 +14,7 @@ buildscript { apply plugin: 'org.jetbrains.dokka' project.ext { - openrndrVersion = "0.3.43-rc.2" + openrndrVersion = "0.3.43-rc.3" kotlinVersion = "1.3.72" spekVersion = "2.0.10" libfreenectVersion = "0.5.7-1.5.3" diff --git a/demo-data/gltf-models/directional-light/Scene.glb b/demo-data/gltf-models/directional-light/Scene.glb new file mode 100644 index 00000000..5145de22 Binary files /dev/null and b/demo-data/gltf-models/directional-light/Scene.glb differ diff --git a/demo-data/gltf-models/point-light/Scene.glb b/demo-data/gltf-models/point-light/Scene.glb new file mode 100644 index 00000000..3bd7ef1e Binary files /dev/null and b/demo-data/gltf-models/point-light/Scene.glb differ diff --git a/demo-data/gltf-models/spot-light/Scene.glb b/demo-data/gltf-models/spot-light/Scene.glb new file mode 100644 index 00000000..2b15b6b9 Binary files /dev/null and b/demo-data/gltf-models/spot-light/Scene.glb differ diff --git a/orx-dnk3/src/demo/kotlin/DemoAnimations01.kt b/orx-dnk3/src/demo/kotlin/DemoAnimations01.kt index 8c2cca6b..95f60fc7 100644 --- a/orx-dnk3/src/demo/kotlin/DemoAnimations01.kt +++ b/orx-dnk3/src/demo/kotlin/DemoAnimations01.kt @@ -26,7 +26,7 @@ fun main() = application { } } - val gltf = loadGltfFromFile(File("demo-data/gltf-models/box-animated/BoxAnimated.glb")) + val gltf = loadGltfFromFile(File("demo-data/gltf-models/oh-no-cubes-2.glb")) val scene = Scene(SceneNode()) @@ -53,7 +53,7 @@ fun main() = application { fov = 40.0 } extend { - sceneData.animations[0].applyToTargets(seconds.mod_(4.0)) + sceneData.animations[0].applyToTargets(seconds.mod_(sceneData.animations[0].duration)) drawer.clear(ColorRGBa.PINK) renderer.draw(drawer, scene) } diff --git a/orx-dnk3/src/demo/kotlin/DemoLights01.kt b/orx-dnk3/src/demo/kotlin/DemoLights01.kt new file mode 100644 index 00000000..0d4023eb --- /dev/null +++ b/orx-dnk3/src/demo/kotlin/DemoLights01.kt @@ -0,0 +1,49 @@ +import org.openrndr.application +import org.openrndr.color.ColorRGBa +import org.openrndr.extensions.SingleScreenshot +import org.openrndr.extra.dnk3.* +import org.openrndr.extra.dnk3.gltf.buildSceneNodes +import org.openrndr.extra.dnk3.gltf.loadGltfFromFile +import org.openrndr.extras.camera.Orbital +import org.openrndr.math.* +import org.openrndr.math.transforms.transform +import java.io.File + +fun main() = application { + configure { + width = 1280 + height = 720 + //multisample = WindowMultisample.SampleCount(8) + } + + program { + if (System.getProperty("takeScreenshot") == "true") { + extend(SingleScreenshot()) { + this.outputFile = System.getProperty("screenshotPath") + } + } + + val gltf = loadGltfFromFile(File("demo-data/gltf-models/point-light/Scene.glb")) + val scene = Scene(SceneNode()) + + scene.root.entities.add(HemisphereLight().apply { + upColor = ColorRGBa(0.1, 0.1, 0.4) + downColor = ColorRGBa(0.1, 0.0, 0.0) + }) + + val sceneData = gltf.buildSceneNodes() + scene.root.children.addAll(sceneData.scenes.first()) + + // -- create a renderer + val renderer = dryRenderer() + val orb = extend(Orbital()) { + far = 50.0 + camera.setView(Vector3.ZERO, Spherical(30.50, 26.0, 5.6), 40.0) + } + extend { + sceneData.animations[0].applyToTargets(seconds.mod_(sceneData.animations[0].duration)) + drawer.clear(ColorRGBa.PINK) + renderer.draw(drawer, scene) + } + } +} \ No newline at end of file diff --git a/orx-dnk3/src/demo/kotlin/DemoLights02.kt b/orx-dnk3/src/demo/kotlin/DemoLights02.kt new file mode 100644 index 00000000..58398b2e --- /dev/null +++ b/orx-dnk3/src/demo/kotlin/DemoLights02.kt @@ -0,0 +1,50 @@ +import org.openrndr.application +import org.openrndr.color.ColorRGBa +import org.openrndr.extensions.SingleScreenshot +import org.openrndr.extra.dnk3.* +import org.openrndr.extra.dnk3.gltf.buildSceneNodes +import org.openrndr.extra.dnk3.gltf.loadGltfFromFile +import org.openrndr.extras.camera.Orbital +import org.openrndr.math.* +import org.openrndr.math.transforms.transform +import java.io.File + +fun main() = application { + configure { + width = 1280 + height = 720 + //multisample = WindowMultisample.SampleCount(8) + } + + program { + if (System.getProperty("takeScreenshot") == "true") { + extend(SingleScreenshot()) { + this.outputFile = System.getProperty("screenshotPath") + } + } + + val gltf = loadGltfFromFile(File("demo-data/gltf-models/spot-light/Scene.glb")) + val scene = Scene(SceneNode()) + + scene.root.entities.add(HemisphereLight().apply { + upColor = ColorRGBa(0.1, 0.1, 0.4) + downColor = ColorRGBa(0.1, 0.0, 0.0) + }) + + + val sceneData = gltf.buildSceneNodes() + scene.root.children.addAll(sceneData.scenes.first()) + + // -- create a renderer + val renderer = dryRenderer() + val orb = extend(Orbital()) { + far = 50.0 + camera.setView(Vector3(-0.514, -0.936, -1.122), Spherical(454.346, 25.0, 8.444), 40.0) + } + extend { + sceneData.animations[0].applyToTargets(seconds.mod_(sceneData.animations[0].duration)) + drawer.clear(ColorRGBa.PINK) + renderer.draw(drawer, scene) + } + } +} \ No newline at end of file diff --git a/orx-dnk3/src/demo/kotlin/DemoLights03.kt b/orx-dnk3/src/demo/kotlin/DemoLights03.kt new file mode 100644 index 00000000..8b010e9f --- /dev/null +++ b/orx-dnk3/src/demo/kotlin/DemoLights03.kt @@ -0,0 +1,49 @@ +import org.openrndr.application +import org.openrndr.color.ColorRGBa +import org.openrndr.extensions.SingleScreenshot +import org.openrndr.extra.dnk3.* +import org.openrndr.extra.dnk3.gltf.buildSceneNodes +import org.openrndr.extra.dnk3.gltf.loadGltfFromFile +import org.openrndr.extras.camera.Orbital +import org.openrndr.math.* +import org.openrndr.math.transforms.transform +import java.io.File + +fun main() = application { + configure { + width = 1280 + height = 720 + //multisample = WindowMultisample.SampleCount(8) + } + + program { + if (System.getProperty("takeScreenshot") == "true") { + extend(SingleScreenshot()) { + this.outputFile = System.getProperty("screenshotPath") + } + } + + val gltf = loadGltfFromFile(File("demo-data/gltf-models/directional-light/Scene.glb")) + val scene = Scene(SceneNode()) + + scene.root.entities.add(HemisphereLight().apply { + upColor = ColorRGBa(0.1, 0.1, 0.4) + downColor = ColorRGBa(0.1, 0.0, 0.0) + }) + + val sceneData = gltf.buildSceneNodes() + scene.root.children.addAll(sceneData.scenes.first()) + + // -- create a renderer + val renderer = dryRenderer() + val orb = extend(Orbital()) { + camera.setView(Vector3(-0.49, -0.24, 0.20), Spherical(26.56, 90.0, 6.533), 40.0) + } + + extend { + sceneData.animations[0].applyToTargets(seconds.mod_(sceneData.animations[0].duration)) + drawer.clear(ColorRGBa.PINK) + renderer.draw(drawer, scene) + } + } +} \ No newline at end of file diff --git a/orx-dnk3/src/main/kotlin/PBRMaterial.kt b/orx-dnk3/src/main/kotlin/PBRMaterial.kt index c1d1dd62..73fc53f8 100644 --- a/orx-dnk3/src/main/kotlin/PBRMaterial.kt +++ b/orx-dnk3/src/main/kotlin/PBRMaterial.kt @@ -346,7 +346,6 @@ class PBRMaterial : Material { + p_jointTransforms[j.y] * a_weights.y + p_jointTransforms[j.z] * a_weights.z + p_jointTransforms[j.w] * a_weights.w; - ${if (primitiveContext.hasNormalAttribute) """ x_normal = normalize(mat3(skinTransform) * x_normal); """.trimIndent() else ""} diff --git a/orx-dnk3/src/main/kotlin/gltf/Gltf.kt b/orx-dnk3/src/main/kotlin/gltf/Gltf.kt index 8f065a5b..ea96873b 100644 --- a/orx-dnk3/src/main/kotlin/gltf/Gltf.kt +++ b/orx-dnk3/src/main/kotlin/gltf/Gltf.kt @@ -35,7 +35,15 @@ class GltfNode(val name:String, val rotation: DoubleArray?, val translation: DoubleArray?, val mesh: Int?, - val skin: Int?) + val skin: Int?, + val extensions: GltfNodeExtensions?) + +class KHRLightsPunctualIndex(val light: Int) + +class GltfNodeExtensions(val KHR_lights_punctual: KHRLightsPunctualIndex?) { + +} + class GltfPrimitive(val attributes: LinkedHashMap, val indices: Int?, val mode: Int?, val material: Int) { fun createDrawCommand(gltfFile: GltfFile): GltfDrawCommand { @@ -244,6 +252,14 @@ class GltfChannel(val sampler: Int, val target: GltfChannelTarget) class GltfSkin(val inverseBindMatrices: Int, val joints: IntArray, val skeleton: Int) + +class KHRLightsPunctualLight(val color: DoubleArray?, val type: String, val intensity: Double?, val range: Double, val spot: KHRLightsPunctualLightSpot?) +class KHRLightsPunctualLightSpot(val innerConeAngle: Double?, val outerConeAngle: Double?) + +class KHRLightsPunctual(val lights: List) + +class GltfExtensions(val KHR_lights_punctual: KHRLightsPunctual?) + class GltfFile( val asset: GltfAsset?, val scene: Int?, @@ -258,7 +274,8 @@ class GltfFile( val textures: List?, val samplers: List?, val animations: List?, - val skins: List? + val skins: List?, + val extensions: GltfExtensions? ) { @Transient lateinit var file: File diff --git a/orx-dnk3/src/main/kotlin/gltf/GltfScene.kt b/orx-dnk3/src/main/kotlin/gltf/GltfScene.kt index 78c2c374..c76392fa 100644 --- a/orx-dnk3/src/main/kotlin/gltf/GltfScene.kt +++ b/orx-dnk3/src/main/kotlin/gltf/GltfScene.kt @@ -17,9 +17,9 @@ import kotlin.reflect.KMutableProperty0 class SceneAnimation(var channels: List) { val duration: Double - get() { - return channels.maxBy { it.duration }?.duration ?:0.0 - } + get() { + return channels.maxBy { it.duration }?.duration ?: 0.0 + } fun applyToTargets(input: Double) { @@ -49,6 +49,7 @@ class Vector3Channel(val target: KMutableProperty0, override fun applyToTarget(input: Double) { target.set(keyframer.value(input) ?: default) } + override val duration: Double get() = keyframer.duration() } @@ -270,6 +271,36 @@ fun GltfFile.buildSceneNodes(): GltfSceneData { val skin = gltfNode.skin?.let { (skins!!)[it] } sceneNode.entities.add(meshes[it].createSceneMesh(skin)) } + gltfNode.extensions?.let { exts -> + exts.KHR_lights_punctual?.let { lightIndex -> + extensions?.KHR_lights_punctual?.lights?.get(lightIndex.light)?.let { light -> + val sceneLight = when (light.type) { + "point" -> { + PointLight() + } + "directional" -> { + DirectionalLight().apply { + shadows = Shadows.PCF() + } + } + "spot" -> { + SpotLight().apply { + innerAngle = Math.toDegrees(light.spot!!.innerConeAngle ?: 0.0) + outerAngle = Math.toDegrees(light.spot.outerConeAngle ?: Math.PI / 4.0) + shadows = Shadows.PCF() + } + + } + else -> error("unsupported light type ${light.type}") + } + sceneLight.apply { + val lightColor = (light.color ?: doubleArrayOf(1.0, 1.0, 1.0)) + color = ColorRGBa(lightColor[0], lightColor[1], lightColor[2]) + } + sceneNode.entities.add(sceneLight) + } + } + } } val sceneAnimations = animations?.map { animation ->