I got a camera rotation code that is a little jerky. The camera is “shaking” as it rotates.
It is so slight that you cant notice it unless you are close to the object you are rotating about.
The shaking also moves the view a very small amount in a direction that is equal to an axis
shooting out from the object’s parent transformgroup origin towards the object.
The shaking i could almost live with but not the gradual unwanted translation that will eventually move the
camera right trough the object if facing it from the “front” side.
If facing it from the “back” the camera is moved away from the object.
So it’s really simply translating along an axis shooting from the objects parent transformgroup right trough the object.
If facing it from the side there seems to be no translation but maybe it just cant be detected from that perspective.
I previously had a rotation code that didnt have this side effect but on the other hand had other bugs.
What i try to do and how im thinking of the rotation is as follows:
- Move the camera (view) to the virtual world origin.
- Move further to the object that i want to rotate about.
- Make the rotation
- Move back from the rotation center.
- Move back from virtual world origin.
The following code has a simplified version for just rotating about the virtual world origin
and then the “full” version about an object.
In the code the following variables explained:
m_root --> BranchGroup, root of the scengraph.
m_view --> View, the view.
m_nodeSelected --> Node, pointer to a node that has been selected.
There is also the old rotation code commented out that doesnt have the shake
but doesnt account for everything properly (weird rotation).
` /**
* Rotates the camera about the selected node.
* Direction of the rotation is taken from <code>x</code> and <code>y</code>.
*
* @param x
* @param y
*/
public void rotateCameraAboutSelectedNode(float x, float y) {
Transform3D rotationLocation = new Transform3D();
Transform3D cameraLocation = new Transform3D();
Transform3D traslateLocation = new Transform3D();
Matrix3f rotation1 = new Matrix3f();
Matrix3f rotation2 = new Matrix3f();
// Determine camera location
m_view.getTransform(cameraLocation);
// Determine rotation point (node or vworld)
if (m_nodeSelected == null) {
// for rotating about origo this works
m_root.getLocalToVworld(rotationLocation);
// "invert" -> transform to origin
cameraLocation.invert();
// make a rotation
rotation1.setIdentity();
rotation2.rotX(y / 100.0f);
rotation1.mul(rotation2);
rotation2.rotY(x / 100.0f);
rotation1.mul(rotation2);
// multiply with current rotation
cameraLocation.getRotation(rotation2);
rotation1.mul(rotation2);
rotation1.normalize();
// set new rotation
cameraLocation.setRotation(rotation1);
// "invert" -> transform back from origin
cameraLocation.invert();
/* // <-- this is the old rotation
// rotate
rotation1.setIdentity();
rotation2.rotX(y / 100.0f);
rotation1.mul(rotation2);
rotation2.rotY(x / 100.0f);
rotation1.mul(rotation2);
rotationLocation.setRotation(rotation1);
rotationLocation.mul(cameraLocation);
// set new camera transform
cameraLocation.set(rotationLocation);
*/
}
else
{
`
(This is where to look for the bug…)
// for rotating about something else than origo we need slight
// modifications to rotation code
m_root.getLocalToVworld(rotationLocation);
m_nodeSelected.getLocalToVworld(traslateLocation);
// "invert" -> transform to origin
cameraLocation.invert();
// transform to rotation center
cameraLocation.mul(traslateLocation);
// make a rotation
rotation1.setIdentity();
rotation2.rotX(y / 100.0f);
rotation1.mul(rotation2);
rotation2.rotY(x / 100.0f);
rotation1.mul(rotation2);
// multiply with current camera rotation
cameraLocation.getRotation(rotation2);
rotation1.mul(rotation2);
rotation1.normalize();
// set new rotation
cameraLocation.setRotation(rotation1);
// transform away from rotation center
traslateLocation.invert();
cameraLocation.mul(traslateLocation);
// "invert" -> transform back from origin
cameraLocation.invert();
`
/* // <-- old rotation code
// translate to rotation point
rotationLocation.mul(traslateLocation);
// rotate
rotation1.setIdentity();
rotation2.rotX(y / 100.0f);
rotation1.mul(rotation2);
rotation2.rotY(x / 100.0f);
rotation1.mul(rotation2);
rotation1.normalize();
rotationLocation.setRotation(rotation1);
// translate away from rotation point
traslateLocation.invert();
rotationLocation.mul(traslateLocation);
rotationLocation.mul(cameraLocation);
// set new camera transform
cameraLocation.set(rotationLocation);*/
}
try {
m_view.setTransform(cameraLocation);
} catch (Exception e) {
e.printStackTrace();
}
}`
If you can spot the bug or point out any other mistakes like fundamentally wrong use of matrices, please help.