Camera update policy

When using multiple cameras (or contexts btw) there is a problem with updating the view matrix: Each time a Camera object is modified it updates the view matrix of the current context. This obviously is wrong if either the camera is not the current camera of the renderer or the current context does not belong to the camera.



My proposal would be to mark cameras as 'dirty' when modifying them and update them before rendering. What do you think?

I kind of agree with that.



This is kind of OT, but not:

One thing that I've done to get around it was make a Camera Manager singleton that creates all of the different camera views that I want to use…  the scene only has the currentCamera which is changed with a key command (so the current camera could be the Cockpit camera now, but a key press makes it the Rear View Camera, etc)



The CameraManager is included as part of the update, so the current camera is updated.



if there is a change in cameras then the current camera is changed then updated(float time) then set as the display renderer camera

currentCamera = rearViewCamera;

currentCamera.update(time);

display.getRenderer().setCamera(currentCamera.getCamera());



I'm getting ready to work on improving the CameraManager I wrote so it has say 10 different camera views (e.g. topDown, left, right, rearView/thirdPerson, cockpit/FPS, and a few other views), apply a CameraInputHandler to match the keypad for rotation (8 is up 2 down, 4 left, 6 right) the cockpit/FPS camera rotates around itself… the other cameras lookAt the object intended.



I think I would prefer enhancing a CameraManager of some sort before I would put my "stamp" of approval on makring a camera as "dirty", but that's just me.  I may not entirely understand why you couldn't update then set the display to the current camera.

camera changes might be hard to detect.

…the get().set(x,y,z) story

Is it possible you'd need the camera to be updated prior to rendering, like GL picking, etc.?  I guess you could manually call it in those cases though.

good point!



I was thinking of a central manager that you added cameras to that were attached to objects like a vehicle or something.  Even a Security camera that was attached to an object like a wall with a set range and motion (like rotating left and right in a pattern).  I wasn't thinking about moving a camera with a set position.



I digress :smiley:

renanse said:

Is it possible you'd need the camera to be updated prior to rendering, like GL picking, etc.?

probably, but maybe it's ok to have the cam info from the last frame? When apps are currently using CameraNode they are likely to use the info from the last frame, also, as SimpleGame calls updateGeometricState after simpleUpdate...
Additionally jME picking (getWorld/ScreenCoordinates) does not use the context but the java-side matricies. We could update them without openGL calls if necessary.

sfera said:

camera changes might be hard to detect.
...the get().set(x,y,z) story

yes, but that's a problem already. When you update the cam this way it won't have any effect until you call some update method. So it would be enough to mark the cam as dirty when some update method is called.

I'm about to commit this defered camera update if nobody objects to it.

I plan do update the Camera in LWJGLRenderer.draw( Spatial ) if it's dirty. Should generate minimum overhead as it's invoked usually only once per render (with little exceptions, e.g. CompositeMesh).

Sounds good, have you noticed any impact in the tests?

no, but I even do not notice an impact of doing a camera update each frame, so it's obviously not enough to look at the framerate. But I think it should be more of a performance benefit as all camera updates in one frame are accumulated end executed once before rendering. The only performance drawback is the additional method call with one if and a field access in it (if no update is needed), this shouldn't be a performance hit.

Correct me if I'm wrong, but manual camera update is still available if needed.

It is. But with Camera.apply() - is that ok? We could do it with update() or onXXXChange, but I don't think that's nice.

As long as it is available should it be necessary for some kind of up-to-date camera matrix read or something, sounds ok to me.

I have checked this in.



@all: please check your tests and apps for any issues. Probably in some rare occasions you'll need to add a renderer.getCamera().apply()…