You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers. No questions about C++ programming or topics which are answered in the tutorials!
I'm trying to port Irrlicht to my 3D Editor and want to use my own camera which inherits from CCameraSceneNode and I'm having a problem with making it rotate correctly. The reason I'm not using CCameraMayaSceneNode is because it seems to be rotating around the loaded model rather than the camera's origin which is not what I want.
I think what I need to do is rotate the target (lookat) around the camera's position and then move the camera in the direction it's looking, this will give the right movement for the editor.
I still haven't really got my head around the target and position thing, I'm guessing it's just used to get a direction vector?
If anyone has some camera moving code that will do what I want, it would be most appreciated if they could show it to me
If I read it correctly you appear to be trying to rotate the camera in a user-defined direction, so why don't you have a look at the SetRotation functions?
Hmmm. Maybe my understanding is wrong, but I figure if you're having the user "wandering" around the level, being able to look left/right, up/down and then move in that direction.
If that is so, I would assume that the SceneNode's SetRotation method should do the trick:
Store the rotations as two euler angles - separately, since you may get rounding problems if you go back and forth between a matrix and euler angles. Keep them in radians, and make sure to let them wrap around. (between -PI and +PI, or between 0 and 2*PI depending on your preference)
Whenever the euler angles - let's call them yaw and pitch - are updated, simply use the camera's SetRotation method with the euler angles in vector format.
Leave roll at 0 unless you want the user to get dizzy...
My experience comes from modding with Unreal/UT - I'm not that much into Irrlicht yet, so I'm not sure about which euler angle goes into which vector component, so you'll have to figure that out yourself I'm afraid.
There is one more potential pitfall: for some reason the irrlicht docu states "This only modifies the relative rotation of the node"...
/** Gets the shortest arc quaternion to rotate this vector to the destination
vector.
@remarks
Don't call this if you think the dest vector can be close to the inverse
of the from vector, since then ANY axis of rotation is ok.
*/
void Quaternion::RotationQuaternionFromTo(const Vector3& from, const Vector3& dest)
{
// Based on Stan Melax's article in Game Programming Gems
// Copy, since cannot modify local
Vector3 v0 = from;
Vector3 v1 = dest;
v0.normalise();
v1.normalise();
Vector3 c = v0.crossProduct(v1);
// NB if the crossProduct approaches zero, we get unstable because ANY axis will do
// when v0 == -v1
f32 d = v0.dotProduct(v1);
// If dot == 1, vectors are the same
if (d >= 1.0f)
{
*this=Quaternion::IDENTITY;
}
f32 s =Sqrt( (1+d)*2 );
f32 invs = 1 / s;
this->x = c.x * invs;
this->y = c.y * invs;
this->z = c.z * invs;
this->w = s * 0.5;
}
CustomCameraClass::Animate()
{
// Other stuff to detect if you are rotating then...
nRotX = (rotateStartX - MousePos.X) * 500.0f;
rotateStartX = MousePos.X;
nRotY = (rotateStartY - MousePos.Y) * -500.0f;
rotateStartY = MousePos.Y;
// Not really sure what this is for but it seems to like it.
nRotY = (f32)fmod(nRotY, 360.0f);
nRotX = (f32)fmod(nRotX, 360.0f);
// Only seem to need to update the target not the camera's rotation.
Target.rotateXZBy(nRotX, this->getPosition());
Target.rotateYZBy(nRotY, this->getPosition());
// Keep 'up' in sync.
UpVector.rotateYZBy(nRotY, core::vector3df(0,0,0));
UpVector.normalize();
}
Works fine for rotating the camera all the way around its Z axis (looking up and down) and all the way round its Y axis but not both at the same time (skews the camera - seems like it's rotation around its X axis), does anyone know why