Help with Camera movement

Started by Mr.Marbles, January 13, 2006, 05:37:58 PM

Previous topic - Next topic

Mr.Marbles

Hi,

I'm a new user of the jpct engine, but I've worked with Java3D for about a year, so I have some experience with the scenegraph paradigm. I find there are some significant differences with camera manipulation; with Java3D a camera could be attached to any node in the scenegraph and it's movement would be dictated by the inherited rotaions/translations of its ancestor nodes. In jpct, however, the camera movement needs to be manually controlled. My question is how can I ensure that the camera mimics the exact same motion as an Object3D in the scene? It's important to note that I'm not rotating/translating the Object3D directly, but insted it's being moved through inherited motions from it's ancestor nodes (other Object3Ds). I hope my question is understandable, if not I will try to clarify.

Btw, great work with the jpct engine :!:

EgonOlsen

Maybe


camera.setPosition(obj3d.getTransformedCenter());
camera.align(obj3d);


will do what you need?

Mr.Marbles

EgonOlsen,

Thank-you for the quick reply! The code you suggested will only allow the camera to mimic the Object3D's translations but not its rotations. That is, the camera is always facing the same direction while being translated. For example, if I make my Object3D orbit a point around the y axis, the camera will pan from left to right and move forward and back, following the translation of the object along the orbiting path. I need the camera to also follow the rotations applied to the Object3D. I've had similar results when using the lookAt() method; it follows the object but is always facing the same direction.

EgonOlsen

Hmm...the align() should take care of the rotations, as it should align the camera with the object's z-axis, i.e. the camera should view along the object's (transformed) z-axis. The code inside align() is

backMatrix=object.getRotationMatrix().invert3x3();

...it should work... :?:  :?:

Mr.Marbles

EgonOlsen,

I don't know why but the align() doesn't seem to work. I've even tried to mimic the Object3D's movement with another Object3D:


Object3D cameraBox = Primitives.getCube(10f);
.
.
.
private void moveCamera()
{
cameraBox.getTranslationMatrix().setIdentity();
cameraBox.translate(getObjectToMimic().getTransformedCenter());
cameraBox.align(getObjectToMimic());
}


And this still doesn't work; the rotations are not being copied. The cameraBox object only translates properly, but never rotates. Do you have a working example of the align() method?

Mr.Marbles

After further analysis, it seems that align() only works if I directly rotate the Object3D that I'm trying to mimic with the camera. If that Object3D is rotated as a result of its parent's rotation then the align() does not work. Is this a "feature" of jpct? How can I get the correct rotation information from the Object3D? I.e. rotX, rotY, rotX ?

Mr.Marbles

Still working on this issue...

I'd like to rephrase my question (again  :oops: ). Is there a way to get the orientation of an Object3D with respect to the world coordinate system? Something like a getTransformedCenter() but for orientation (rotation). It looks like all the rotation information stored in an Object3D only describes orientation in the Object3D's local coordinate system.

EgonOlsen

Damn...i should have seen this problem earlier.... :?  You are absolutely right. I'm just not sure if it's a feature, a bug or a bit of both. Anyway, this should work (replace the call to align() with it):

camera.setBack(obj.getWorldTransformation().invert3x3());

Mr.Marbles

EgonOlsen,

Thank-you, that did the job  :D

I'm really curious about why it works though. What's the logic behind taking the inverse of the
Quote... transformation matrix used to transform the object from objectspace into worldspace ...
and setting the camera's         backbuffer to this value  :?:  :?:

EgonOlsen

getWorldTransformation() gets you the combined transformation matrix to transform the object into world space, i.e. the space where you are moving the camera in.
The camera's transformation means actually the world's transformation into camera space (that's a space where the camera is always located at 0,0,0 and looking down the z-axis).
When applying the inverse world transformation to the camera, you are actually reverting the world transformation...it's twisted...difficult to explain...
Imagine the object's center at (0,0,0). You now apply a rotation to it and it's now located at (2,1,0). Assume that this already is it's final transformation to world space. So for the camera, you now need a transformation that brings this point in world space to (0,0,0) (which is the camera's location in camera space). But that's exactly what we already did the other way round, so we just have to take the inverse of what made (0,0,0)->(2,1,0) and we have the desired (2,1,0)->(0,0,0).
Because the camera has no combined tranformation matrix, you have to use the rotational part of the resulting matrix only and do the rest with setPosition(). You could easily derive the value for setPosition() from the  inverted matrix too (by using invert() instead of invert3x3()) if you want to, but it isn't needed and most likely slower due to the more complex inversion of a 4x4 matrix.