Reputation: 433
I'm making a 3D-game using C++ and Irrlicht. It is a FPS-style game, so player should be able to carry weapons. But I've been struggling with calculating the position relative to the camera. If camera wouldn't rotate, calculation would be easy:
// node is camera's child
vector3df modifier = vector3df(2, 0, 2);
node->setPosition(node->getPosition() + modifier);
But however, camera isn't a static but a rotating object, so things are a bit more complicated. Here's an image which hopefully crearifies what I'm trying to say:
This should work in all dimensions, X, Y and Z. I think there's only two trigonometric functions for this kind of purpose, sine and cosine, which are for calculating X and Y coordinates. Am I at the wrong path or can they be applied to this? Or is there a solution in Irrlicht itself? There's the code which I've tried to use (found it from SO):
vector3df obj = vector3df(2, 0, 2);
vector3df n = vector3df(0, 0, 0);
n.X = obj.X * cos(60 * DEGTORAD) - obj.Z * sin(60 * DEGTORAD);
n.Z = obj.Z * cos(60 * DEGTORAD) + obj.X * sin(60 * DEGTORAD);
node->setPosition(node->getPosition() + n);
But the weapon just flies forward.
I would be glad for any kind of help or guidance.
P.S. Hopefully this question is clearer than the previous one
Upvotes: 1
Views: 1703
Reputation: 3795
The problem with your code is that the rotation is performed around the origin, not around the camera.
What you want to do is to rotate the object (weapon) around the center of the camera by the angle that the camera rotates:
In order to do that you need to perform the following steps:
1 - Translate all the points so that the center of the camera is at the origin,
2 - Apply the rotation matrix (angle is alpha):
[cos (alpha) -sin (alpha)]
[sin (alpha) cos (alpha)]
3 - Undo the step 1 on the rotated point.
Sample algorithm:
Position of the weapon: (xObject, yObject)
Position of the camera: (xCamera, yCamera)
Turning angle: alpha
//step 1:
xObject -= xCamera;
yObject -= yCamera;
// step 2
xRot = xObject * cos(alpha) - yObject * sin(alpha);
yRot = xObject * sin(alpha) + yObject * cos(alpha);
// step 3:
xObject = xRot + xCamera;
yObject = yRot + yCamera;
This algorithm is on XY plane but can be modified for XZ plane. Assuming that in your code obj
represent the position of the weapon. Your code can be something like:
...
// Step 1
obj.X-=cam.X;
obj.Z-=cam.Z;
//Step 2
n.X = obj.X * cos(60 * DEGTORAD) - obj.Z * sin(60 * DEGTORAD);
n.Z = obj.Z * cos(60 * DEGTORAD) + obj.X * sin(60 * DEGTORAD);
// Step 3
obj.X = n.X + cam.X;
obj.Z = n.Z + cam.Z;
...
Hope that helps!
Upvotes: 1