[orx-camera] Add orthogonal projection
This commit is contained in:
@@ -18,8 +18,9 @@ class Orbital : Extension {
|
|||||||
var fov = 90.0
|
var fov = 90.0
|
||||||
var userInteraction = true
|
var userInteraction = true
|
||||||
var keySpeed = 1.0
|
var keySpeed = 1.0
|
||||||
|
var projectionType = ProjectionType.PERSPECTIVE
|
||||||
|
|
||||||
val camera by lazy { OrbitalCamera(eye, lookAt, fov, near, far) }
|
val camera by lazy { println("creating camera $projectionType"); OrbitalCamera(eye, lookAt, fov, near, far, projectionType) }
|
||||||
val controls by lazy { OrbitalControls(camera, userInteraction, keySpeed) }
|
val controls by lazy { OrbitalControls(camera, userInteraction, keySpeed) }
|
||||||
|
|
||||||
override fun setup(program: Program) {
|
override fun setup(program: Program) {
|
||||||
|
|||||||
@@ -10,7 +10,13 @@ import org.openrndr.math.Vector3
|
|||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
import org.openrndr.math.transforms.lookAt as lookAt_
|
import org.openrndr.math.transforms.lookAt as lookAt_
|
||||||
|
|
||||||
class OrbitalCamera(eye: Vector3 = Vector3.ZERO, lookAt: Vector3 = Vector3.UNIT_Z, var fov: Double = 90.0, var near: Double = 0.1, var far: Double = 1000.0) : Extension {
|
enum class ProjectionType {
|
||||||
|
PERSPECTIVE,
|
||||||
|
ORTHOGONAL
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class OrbitalCamera(eye: Vector3 = Vector3.ZERO, lookAt: Vector3 = Vector3.UNIT_Z, var fov: Double = 90.0, var near: Double = 0.1, var far: Double = 1000.0, var projectionType: ProjectionType = ProjectionType.PERSPECTIVE) : 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
|
||||||
@@ -19,6 +25,9 @@ class OrbitalCamera(eye: Vector3 = Vector3.ZERO, lookAt: Vector3 = Vector3.UNIT_
|
|||||||
|
|
||||||
var depthTest = true
|
var depthTest = true
|
||||||
|
|
||||||
|
var magnitude = 100.0
|
||||||
|
var magnitudeEnd = magnitude
|
||||||
|
|
||||||
private var sphericalEnd = Spherical.fromVector(eye)
|
private var sphericalEnd = Spherical.fromVector(eye)
|
||||||
private var lookAtEnd = lookAt
|
private var lookAtEnd = lookAt
|
||||||
private var dirty: Boolean = true
|
private var dirty: Boolean = true
|
||||||
@@ -90,6 +99,11 @@ class OrbitalCamera(eye: Vector3 = Vector3.ZERO, lookAt: Vector3 = Vector3.UNIT_
|
|||||||
dirty = true
|
dirty = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun scale(s: Double) {
|
||||||
|
magnitudeEnd += s
|
||||||
|
dirty = true
|
||||||
|
}
|
||||||
|
|
||||||
fun zoom(degrees: Double) {
|
fun zoom(degrees: Double) {
|
||||||
fovEnd += degrees
|
fovEnd += degrees
|
||||||
dirty = true
|
dirty = true
|
||||||
@@ -108,25 +122,27 @@ class OrbitalCamera(eye: Vector3 = Vector3.ZERO, lookAt: Vector3 = Vector3.UNIT_
|
|||||||
val sphericalDelta = sphericalEnd - spherical
|
val sphericalDelta = sphericalEnd - spherical
|
||||||
val lookAtDelta = lookAtEnd - lookAt
|
val lookAtDelta = lookAtEnd - lookAt
|
||||||
val fovDelta = fovEnd - fov
|
val fovDelta = fovEnd - fov
|
||||||
|
val magnitudeDelta = magnitudeEnd - magnitude
|
||||||
if (
|
if (
|
||||||
abs(sphericalEnd.radius) > EPSILON ||
|
abs(sphericalDelta.radius) > EPSILON ||
|
||||||
abs(sphericalEnd.theta) > EPSILON ||
|
abs(sphericalDelta.theta) > EPSILON ||
|
||||||
abs(sphericalEnd.phi) > EPSILON ||
|
abs(sphericalDelta.phi) > EPSILON ||
|
||||||
abs(lookAtDelta.x) > EPSILON ||
|
abs(lookAtDelta.x) > EPSILON ||
|
||||||
abs(lookAtDelta.y) > EPSILON ||
|
abs(lookAtDelta.y) > EPSILON ||
|
||||||
abs(lookAtDelta.z) > EPSILON ||
|
abs(lookAtDelta.z) > EPSILON ||
|
||||||
abs(fovDelta) > EPSILON
|
abs(fovDelta) > EPSILON
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fov += (fovDelta * dampingFactor)
|
fov += (fovDelta * dampingFactor)
|
||||||
spherical += (sphericalDelta * dampingFactor)
|
spherical += (sphericalDelta * dampingFactor)
|
||||||
spherical = spherical.makeSafe()
|
spherical = spherical.makeSafe()
|
||||||
lookAt += (lookAtDelta * dampingFactor)
|
lookAt += (lookAtDelta * dampingFactor)
|
||||||
|
magnitude += (magnitudeDelta * dampingFactor)
|
||||||
dirty = true
|
dirty = true
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
magnitude = magnitudeEnd
|
||||||
spherical = sphericalEnd.copy()
|
spherical = sphericalEnd.copy()
|
||||||
lookAt = lookAtEnd.copy()
|
lookAt = lookAtEnd.copy()
|
||||||
|
fov = fovEnd
|
||||||
}
|
}
|
||||||
spherical = spherical.makeSafe()
|
spherical = spherical.makeSafe()
|
||||||
}
|
}
|
||||||
@@ -150,7 +166,12 @@ class OrbitalCamera(eye: Vector3 = Vector3.ZERO, lookAt: Vector3 = Vector3.UNIT_
|
|||||||
|
|
||||||
update(delta)
|
update(delta)
|
||||||
|
|
||||||
drawer.perspective(fov, program.window.size.x / program.window.size.y, near, far)
|
if (projectionType == ProjectionType.PERSPECTIVE) {
|
||||||
|
drawer.perspective(fov, drawer.width.toDouble() / drawer.height, near, far)
|
||||||
|
} else {
|
||||||
|
val ar = drawer.width * 1.0 / drawer.height
|
||||||
|
drawer.ortho(-ar * magnitude, ar * magnitude, -1.0 * magnitude, 1.0 * magnitude, -1000.0, 1000.0)
|
||||||
|
}
|
||||||
drawer.view = viewMatrix()
|
drawer.view = viewMatrix()
|
||||||
|
|
||||||
if (depthTest) {
|
if (depthTest) {
|
||||||
@@ -188,7 +209,13 @@ fun OrbitalCamera.isolated(drawer: Drawer, function: Drawer.() -> Unit) {
|
|||||||
* if you don't need to revert back to the orthographic projection.
|
* if you don't need to revert back to the orthographic projection.
|
||||||
*/
|
*/
|
||||||
fun OrbitalCamera.applyTo(drawer: Drawer) {
|
fun OrbitalCamera.applyTo(drawer: Drawer) {
|
||||||
drawer.perspective(fov, drawer.width.toDouble() / drawer.height, near, far)
|
|
||||||
|
if (projectionType == ProjectionType.PERSPECTIVE) {
|
||||||
|
drawer.perspective(fov, drawer.width.toDouble() / drawer.height, near, far)
|
||||||
|
} else {
|
||||||
|
val ar = drawer.width * 1.0 / drawer.height
|
||||||
|
drawer.ortho(-ar, ar, 1.0, -1.0, near, far)
|
||||||
|
}
|
||||||
drawer.view = viewMatrix()
|
drawer.view = viewMatrix()
|
||||||
drawer.drawStyle.depthWrite = true
|
drawer.drawStyle.depthWrite = true
|
||||||
drawer.drawStyle.depthTestPass = DepthTestPass.LESS_OR_EQUAL
|
drawer.drawStyle.depthTestPass = DepthTestPass.LESS_OR_EQUAL
|
||||||
|
|||||||
@@ -22,11 +22,19 @@ class OrbitalControls(val orbitalCamera: OrbitalCamera, val userInteraction: Boo
|
|||||||
|
|
||||||
private fun mouseScrolled(event: MouseEvent) {
|
private fun mouseScrolled(event: MouseEvent) {
|
||||||
if (!event.propagationCancelled) {
|
if (!event.propagationCancelled) {
|
||||||
if (abs(event.rotation.x) > 0.1) return
|
|
||||||
|
|
||||||
when {
|
if (orbitalCamera.projectionType == ProjectionType.PERSPECTIVE) {
|
||||||
event.rotation.y > 0 -> orbitalCamera.dollyIn()
|
if (abs(event.rotation.x) > 0.1) return
|
||||||
event.rotation.y < 0 -> orbitalCamera.dollyOut()
|
when {
|
||||||
|
event.rotation.y > 0 -> orbitalCamera.dollyIn()
|
||||||
|
event.rotation.y < 0 -> orbitalCamera.dollyOut()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (abs(event.rotation.x) > 0.1) return
|
||||||
|
when {
|
||||||
|
event.rotation.y > 0 -> orbitalCamera.scale(1.0)
|
||||||
|
event.rotation.y < 0 -> orbitalCamera.scale(-1.0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user