Orbital Camera is an extension that can manage it's own life-cycle
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user