Add support for cameras

This commit is contained in:
Edwin Jakobs
2020-05-26 19:29:08 +02:00
parent 5869b8d023
commit 158af5fb3b
5 changed files with 122 additions and 2 deletions

View File

@@ -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/camera/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 cameras = scene.root.findContent { this as? PerspectiveCamera }
extend {
sceneData.animations[0].applyToTargets(seconds.mod_(sceneData.animations[0].duration))
drawer.view = cameras[0].content.viewMatrix
drawer.projection = cameras[0].content.projectionMatrix
drawer.clear(ColorRGBa.PINK)
renderer.draw(drawer, scene)
}
}
}

View File

@@ -0,0 +1,32 @@
package org.openrndr.extra.dnk3
import org.openrndr.math.Matrix44
import org.openrndr.math.transforms.ortho
import org.openrndr.math.transforms.perspective
class PerspectiveCamera(var node: SceneNode) : Camera() {
override val projectionMatrix: Matrix44
get() = perspective(fov, aspectRatio, near, far)
override val viewMatrix: Matrix44
get() = node.worldTransform.inversed
var aspectRatio: Double = 16.0 / 9.0
var fov = 45.0
var far = 100.0
var near = 0.1
}
class OrthographicCamera(var node: SceneNode) : Camera() {
override val projectionMatrix: Matrix44
get() = ortho(xMag, yMag, near, far)
override val viewMatrix: Matrix44
get() = node.worldTransform.inversed
var xMag = 1.0
var yMag = 1.0
var near = 0.1
var far = 100.0
}

View File

@@ -58,3 +58,7 @@ abstract class Light : Entity() {
var color: ColorRGBa = ColorRGBa.WHITE
}
abstract class Camera : Entity() {
abstract val projectionMatrix: Matrix44
abstract val viewMatrix: Matrix44
}

View File

@@ -28,7 +28,7 @@ class GltfAsset(val generator: String?, val version: String?)
class GltfScene(val nodes: IntArray)
class GltfNode(val name:String,
class GltfNode(val name: String,
val children: IntArray?,
val matrix: DoubleArray?,
val scale: DoubleArray?,
@@ -36,6 +36,7 @@ class GltfNode(val name:String,
val translation: DoubleArray?,
val mesh: Int?,
val skin: Int?,
val camera: Int?,
val extensions: GltfNodeExtensions?)
class KHRLightsPunctualIndex(val light: Int)
@@ -260,6 +261,11 @@ class KHRLightsPunctual(val lights: List<KHRLightsPunctualLight>)
class GltfExtensions(val KHR_lights_punctual: KHRLightsPunctual?)
class GltfCameraPerspective(val aspectRatio: Double?, val yfov: Double, val zfar: Double?, val znear: Double)
class GltfCameraOrthographic(val xmag: Double, val ymag: Double, val zfar: Double, val znear: Double)
class GltfCamera(val name: String?, val type: String, val perspective: GltfCameraPerspective?, val orthographic: GltfCameraOrthographic?)
class GltfFile(
val asset: GltfAsset?,
val scene: Int?,
@@ -275,7 +281,8 @@ class GltfFile(
val samplers: List<GltfSampler>?,
val animations: List<GltfAnimation>?,
val skins: List<GltfSkin>?,
val extensions: GltfExtensions?
val extensions: GltfExtensions?,
val cameras: List<GltfCamera>?
) {
@Transient
lateinit var file: File

View File

@@ -259,6 +259,28 @@ fun GltfFile.buildSceneNodes(): GltfSceneData {
}
}
fun GltfCamera.createSceneCamera(sceneNode: SceneNode): Camera {
return when (type) {
"perspective" -> {
PerspectiveCamera(sceneNode).apply {
aspectRatio = perspective?.aspectRatio ?: aspectRatio
far = perspective?.zfar ?: far
near = perspective?.znear ?: near
fov = perspective?.yfov?.let { Math.toDegrees(it) } ?: fov
}
}
"orthographic" -> {
OrthographicCamera(sceneNode).apply {
xMag = orthographic?.xmag ?: xMag
yMag = orthographic?.ymag ?: yMag
near = orthographic?.znear ?: near
far = orthographic?.zfar ?: far
}
}
else -> error("unsupported camera type: $type")
}
}
val scenes = scenes.map { scene ->
scene.nodes.map { node ->
val gltfNode = nodes[node]
@@ -271,6 +293,11 @@ fun GltfFile.buildSceneNodes(): GltfSceneData {
val skin = gltfNode.skin?.let { (skins!!)[it] }
sceneNode.entities.add(meshes[it].createSceneMesh(skin))
}
gltfNode.camera?.let {
sceneNode.entities.add(cameras!![it].createSceneCamera(sceneNode))
}
gltfNode.extensions?.let { exts ->
exts.KHR_lights_punctual?.let { lightIndex ->
extensions?.KHR_lights_punctual?.lights?.get(lightIndex.light)?.let { light ->