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 # 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 package org.openrndr.extras.camera
import org.openrndr.* import org.openrndr.Extension
import org.openrndr.color.ColorRGBa import org.openrndr.Program
import org.openrndr.draw.DrawPrimitive
import org.openrndr.draw.Drawer 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.Matrix44
import org.openrndr.math.Spherical import org.openrndr.math.Spherical
import org.openrndr.math.Vector2
import org.openrndr.math.Vector3 import org.openrndr.math.Vector3
import kotlin.math.abs
import org.openrndr.math.transforms.lookAt as lookAt_ 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 // current position in spherical coordinates
var spherical = Spherical.fromVector(eye) var spherical = Spherical.fromVector(eye)
private set private set
@@ -25,6 +19,7 @@ class OrbitalCamera(eye: Vector3, lookAt: Vector3, var fov:Double) {
private var sphericalEnd = Spherical.fromVector(eye) private var sphericalEnd = Spherical.fromVector(eye)
private var lookAtEnd = lookAt.copy() private var lookAtEnd = lookAt.copy()
private var dirty: Boolean = true private var dirty: Boolean = true
private var lastSeconds: Double = -1.0
var fovEnd = fov var fovEnd = fov
@@ -105,13 +100,13 @@ class OrbitalCamera(eye: Vector3, lookAt: Vector3, var fov:Double) {
val lookAtDelta = lookAtEnd - lookAt val lookAtDelta = lookAtEnd - lookAt
val fovDelta = fovEnd - fov val fovDelta = fovEnd - fov
if ( if (
Math.abs(sphericalEnd.radius) > EPSILON || abs(sphericalEnd.radius) > EPSILON ||
Math.abs(sphericalEnd.theta) > EPSILON || abs(sphericalEnd.theta) > EPSILON ||
Math.abs(sphericalEnd.phi) > EPSILON || abs(sphericalEnd.phi) > EPSILON ||
Math.abs(lookAtDelta.x) > EPSILON || abs(lookAtDelta.x) > EPSILON ||
Math.abs(lookAtDelta.y) > EPSILON || abs(lookAtDelta.y) > EPSILON ||
Math.abs(lookAtDelta.z) > EPSILON || abs(lookAtDelta.z) > EPSILON ||
Math.abs(fovDelta) > EPSILON abs(fovDelta) > EPSILON
) { ) {
fov += (fovDelta * dampingFactor) fov += (fovDelta * dampingFactor)
@@ -134,6 +129,26 @@ class OrbitalCamera(eye: Vector3, lookAt: Vector3, var fov:Double) {
companion object { companion object {
private const val EPSILON = 0.000001 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()
}
} }