Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[orx-camera] OrbitalCamera.isolated is missing a call to update() #321

Open
hamoid opened this issue Aug 3, 2023 · 3 comments
Open

[orx-camera] OrbitalCamera.isolated is missing a call to update() #321

hamoid opened this issue Aug 3, 2023 · 3 comments
Labels
bug Something isn't working

Comments

@hamoid
Copy link
Member

hamoid commented Aug 3, 2023

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
              }
            }
@hamoid hamoid added the bug Something isn't working label Aug 3, 2023
@hamoid
Copy link
Member Author

hamoid commented Aug 3, 2023

Alternatively, I can update the readme to include an example of having 2D graphics behind the interactive camera.

@hamoid
Copy link
Member Author

hamoid commented Mar 4, 2024

Here an example of drawing behind and in front of a 3D interactive layer.

@hamoid
Copy link
Member Author

hamoid commented Mar 4, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant