orx
orx copied to clipboard
[orx-camera] OrbitalCamera.isolated is missing a call to update()
Operating System
Any
OPENRNDR version
0.4.4-SNAPSHOT
ORX version
0.4.4-SNAPSHOT
Java version (if applicable)
No response
Describe the bug
Without a call to .update(timeDelta) OrbitalControls do not work.
This is not an issue if we extend(camera), but doing that does not allow the user to draw background items not affected by the camera. If we only extend(controls) then the controls do not work unless we manually call camera.update(seconds - lastSeconds) and keep track of lastSeconds ourselves.
To call update from OrbitalCamera.isolated() we need access to program. Passing program as an argument instead of drawer changes the API, so I'm not sure what the ideal solution is.
Steps to reproduce the bug
val camera = OrbitalCamera()
val controls = OrbitalControls(camera)
// don't extend camera otherwise we can't draw 2D graphics
// extend(camera)
extend(controls)
extend {
// draw something with ortho projection here
drawer.rectangle(drawer.bounds)
camera.isolated(drawer) {
// draw something in 3D, dragging the mouse does not rotate the camera
}
}
Alternatively, I can update the readme to include an example of having 2D graphics behind the interactive camera.
Here an example of drawing behind and in front of a 3D interactive layer.
I tried the following approach:
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.DrawPrimitive
import org.openrndr.draw.shadeStyle
import org.openrndr.extra.camera.OrbitalCamera
import org.openrndr.extra.camera.OrbitalControls
import org.openrndr.extra.camera.isolated
import org.openrndr.extra.compositor.compose
import org.openrndr.extra.compositor.draw
import org.openrndr.extra.compositor.layer
import org.openrndr.extra.meshgenerators.boxMesh
import org.openrndr.math.Vector3
fun main() = application {
program {
val box = boxMesh(50.0, 20.0, 5.0)
val camera = OrbitalCamera(Vector3.ONE * 20.0, Vector3.ZERO, 90.0, 0.1, 5000.0)
val controls = OrbitalControls(camera)
val gradientShading = shadeStyle {
fragmentTransform = """
vec3 c = sin(v_worldPosition * 0.1) * 0.5 + 0.5;
c = c * (dot(va_normal, vec3(0.1, 0.2, 0.8)) * 0.5 + 0.5);
x_fill = vec4(c, 1.0);
""".trimIndent()
}
val layers = compose {
layer {
draw {
// Draw in 2D on the back
drawer.circle(drawer.bounds.center, 200.0)
}
}
layer {
draw {
// Draw in 3D
camera.isolated(drawer) {
shadeStyle = gradientShading
vertexBuffer(box, DrawPrimitive.TRIANGLES)
}
}
}
layer {
draw {
// Draw in 2D on the front
drawer.strokeWeight = 4.0
drawer.shadeStyle = null
drawer.fill = null
drawer.stroke = ColorRGBa.WHITE
drawer.circle(drawer.bounds.center, 220.0)
}
}
}
extend(camera)
extend(controls)
extend {
layers.draw(drawer)
}
}
}
But as soon as extend(camera) is present, only the 3D layer is rendered, the other two layers are missing. Commenting out that extend reveals the missing layers, but it's no longer interactive. Probably makes sense because the extend can not be applied only to the middle layer.