Orbital Camera is an extension that can manage it's own life-cycle

This commit is contained in:
Ricardo Matias
2019-11-21 13:56:09 +01:00
parent 7377f35a00
commit ead9b8a0d3
2 changed files with 68 additions and 18 deletions

View File

@@ -1,3 +1,38 @@
# orx-camera
3D camera and controls for OPENRNDR. This supersedes the to be deprecated functionality in OPENRNDR.
3D camera and controls for OPENRNDR. This supersedes the to be deprecated functionality in OPENRNDR.
## Usage
```kotlin
val camera = OrbitalCamera(Vector3.UNIT_Z * 1000.0, Vector3.ZERO, 90.0, 0.1, 2000.0)
val controls = OrbitalControls(camera, keySpeed = 10.0)
val debug3d = Debug3D(1000, 100)
extend(camera)
extend(controls) // adds both mouse and keyboard bindings
extend {
debug3d.draw(drawer)
drawer.perspective(90.0, width*1.0 / height, 0.1, 5000.0)
drawer.shadeStyle = shadeStyle {
vertexTransform = """x_viewMatrix = p_view"""
parameter("view", camera.viewMatrix())
}
drawer.fill = ColorRGBa.PINK
drawer.circle(0.0, 0.0, 500.0)
}
```
### Keybindings
* `w` - move forwards (+z)
* `s` - move backwards (-z)
* `Left` or `a` - strafe left (-x)
* `Right` or `d` - strafe right (+x)
* `Up` or `e` - move up (+y)
* `Down` or `q` - move up (-y)
* `Page Up` - zoom in
* `Page Down` - zoom out

View File

@@ -1,21 +1,15 @@
package org.openrndr.extras.camera
import org.openrndr.*
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.DrawPrimitive
import org.openrndr.Extension
import org.openrndr.Program
import org.openrndr.draw.Drawer
import org.openrndr.draw.isolated
import org.openrndr.draw.vertexBuffer
import org.openrndr.draw.vertexFormat
import org.openrndr.math.Matrix44
import org.openrndr.math.Spherical
import org.openrndr.math.Vector2
import org.openrndr.math.Vector3
import kotlin.math.abs
import org.openrndr.math.transforms.lookAt as lookAt_
class OrbitalCamera(eye: Vector3, lookAt: Vector3, var fov:Double) {
class OrbitalCamera(eye: Vector3, lookAt: Vector3, var fov: Double, var near: Double = 0.1, var far: Double = 1000.0) : Extension {
// current position in spherical coordinates
var spherical = Spherical.fromVector(eye)
private set
@@ -25,6 +19,7 @@ class OrbitalCamera(eye: Vector3, lookAt: Vector3, var fov:Double) {
private var sphericalEnd = Spherical.fromVector(eye)
private var lookAtEnd = lookAt.copy()
private var dirty: Boolean = true
private var lastSeconds: Double = -1.0
var fovEnd = fov
@@ -105,13 +100,13 @@ class OrbitalCamera(eye: Vector3, lookAt: Vector3, var fov:Double) {
val lookAtDelta = lookAtEnd - lookAt
val fovDelta = fovEnd - fov
if (
Math.abs(sphericalEnd.radius) > EPSILON ||
Math.abs(sphericalEnd.theta) > EPSILON ||
Math.abs(sphericalEnd.phi) > EPSILON ||
Math.abs(lookAtDelta.x) > EPSILON ||
Math.abs(lookAtDelta.y) > EPSILON ||
Math.abs(lookAtDelta.z) > EPSILON ||
Math.abs(fovDelta) > EPSILON
abs(sphericalEnd.radius) > EPSILON ||
abs(sphericalEnd.theta) > EPSILON ||
abs(sphericalEnd.phi) > EPSILON ||
abs(lookAtDelta.x) > EPSILON ||
abs(lookAtDelta.y) > EPSILON ||
abs(lookAtDelta.z) > EPSILON ||
abs(fovDelta) > EPSILON
) {
fov += (fovDelta * dampingFactor)
@@ -134,6 +129,26 @@ class OrbitalCamera(eye: Vector3, lookAt: Vector3, var fov:Double) {
companion object {
private const val EPSILON = 0.000001
}
// EXTENSION
override var enabled: Boolean = true
override fun beforeDraw(drawer: Drawer, program: Program) {
if (lastSeconds == -1.0) lastSeconds = program.seconds
val delta = program.seconds - lastSeconds
lastSeconds = program.seconds
update(delta)
drawer.perspective(fov, program.window.size.x / program.window.size.y, near, far)
drawer.view = viewMatrix()
}
override fun afterDraw(drawer: Drawer, program: Program) {
drawer.view = Matrix44.IDENTITY
drawer.ortho()
}
}