Closed JuanCab closed 6 years ago
There are two points to take into account when "resetting" a camera:
When setting position
and up
vector, the rotation of the camera doesn't necessarily change. The best way to achieve what you want is likely to use camera.lookat([x, y, z])
.
The "standard way" of setting up a renderer normally adds an OrbitControls
. It keeps its own reference to an orbit point. While the camera only looks in a specific direction, the orbit control orbits around a 3D point. Directly modifying the camera does not update the orbit. This is what is causing your rendering to start "working again" after interacting with the scene. You can programmatically set the orbit target with orbit.target = (x, y, z)
, but this is currently not synced back from the front-end (this should ideally be fixed). For this reason, you might need to do a cycle (orbit.target = [0, 0, 0]; orbit.target = [x, y, z]
although that might fail for x = y = z = 0
).
Sorry my question/issue wasn't clearly stated...
I am using OrbitControls
, so using camera.lookat([x, y, z])
doesn't achieve what I want. The idea was to allow someone to move around the origin of the view of a simulation, but then allow them to reset a view to an "overhead view" in an OrbitControls
guided view. So I was moving the camera back to being over the seen and looking down on it. That works in that the camera moves, but then the renderer doesn't re-display the scene until the user interacts with it.
The actual code defining my camera and controller is
import pythreejs as p3j
# Lots of code clipped out here as not critical to understanding the problem
starcam = p3j.PerspectiveCamera(position=[0, 0, 3*xmax], up=[0, 1, 0],
children=[p3j.DirectionalLight(color='white',
position=[1.5*xmax, 1.5*xmax, 1.5*xmax],
intensity=1)])
controller = p3j.OrbitControls(controlling=starcam, enableRotate=True, enableZoom=False,
minPolarAngle=0, maxPolarAngle=np.pi, target = [0, 0, 0])
renderer2 = p3j.Renderer(camera=starcam,
scene=scene2,
controls=[controller],
width=view_width, height=view_height)
The behavior you describe in your second point is the problem, that when I reset the starcam
camera position
and up
the rendering starts to work only after an interaction. I would be nice it there was some way to programmatically refresh the renderer after an unexpected change like this.
I did think of trying to do this with a animation of a position track, but AnimationAction
doesn't appear to have a way to automatically start when called or to not display the controls. I'd like to use a button to "reset to overhead".
There is actually a reset()
function on the JS side of OrbitController
. It seems like it might make sense to expose that to the kernel side!
For now, you can call it directly with controller.exec_three_obj_method('reset')
.
It should probably also get a method to "sync" to the camera after another source changes the camera, but that will need some careful consideration of how to best achieve it.
So, I wanted to offer my students unused to 3D widgets the ability to have a push button that would reset the view. However when I do the following
the scene disappears. It is clear if I then interact with the scene, it appears having reset position and view. Am I missing something to trigger a scene re-rendering after changing the camera? This isn't an animation, just a simple 'reset' of position.