How to use OrbitalCamera and OrbitalControls in only some parts of your program?

Since camera.update(deltaTime) would no longer work (deltaTime no longer exists), I’m sharing a newer approach.

A fixed 2D circle in the background, an interactive 3D shape in the middle, and a fixed 2D ring on front of everything.

sketches.Orbital_01-2024-02-08-19.42.15

imports
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.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()
        }

        var secondsLast = seconds

        //extend(camera)
        extend(controls)
        extend {
            camera.update(seconds - secondsLast)
            secondsLast = seconds

            // Draw in 2D on the back
            drawer.circle(drawer.bounds.center, 200.0)

            // Draw in 3D
            camera.isolated(drawer) {
                drawer.shadeStyle = gradientShading
                drawer.vertexBuffer(box, DrawPrimitive.TRIANGLES)
            }

            // 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)
        }
    }
}

Note: if you don’t need to revert back to 2D (ortho) mode, you can use

camera.applyTo(drawer)

instead of

camera.isolated(drawer) { ... }

which is a tiny bit faster.