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
Camera rotation woes in my 3D editor
Yep I think I need to rotate the 'lookat' point around the origin of the camera....anyone got any code that does this?
This code seems to kind of work:
Inside my Camera's animate:
This code seems to kind of work:
Inside my Camera's animate:
Code: Select all
// Rotates Y
Target.rotateYZBy(nRotY, this->getAbsolutePosition());
- Nova
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"...
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"...
with a good quaternion class you can do this:
now use it
after that you just get the euler angles from the quaternion and off you go...
salut
Monsieur Belot
Code: Select all
/** 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;
}
Code: Select all
Quaternion rotFT;
Vector3 dir=forward;
Vector3 targetdir=targetPos-myPosition;
if(fixedYAxis){
dir.Y=0;
targetdir.Y=0;
}
targetdir.normalise();
dir.normalise();
// make sure targetdir is not 0
rotFT.RotationQuaternionFromTo(dir,targetdir);
salut
Monsieur Belot
I tried to understand the code from the other posts but couldn't really understand it.
This is what I've got at the moment (rotation only, no movement yet):
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
This is what I've got at the moment (rotation only, no movement yet):
Code: Select all
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();
}
- Nova