--- Irrlicht.old/CCameraSceneNode.cpp 2005-08-24 16:59:54.000000000 +0200 +++ Irrlicht/CCameraSceneNode.cpp 2005-12-20 13:32:14.000000000 +0100 @@ -15,7 +15,7 @@ //! constructor CCameraSceneNode::CCameraSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, - const core::vector3df& position, const core::vector3df& lookat) + const core::vector3df& position, const core::vector3df& viewDir) : ICameraSceneNode(parent, mgr, id, position, core::vector3df(0.0f, 0.0f, 0.0f), core::vector3df(1.0f, 1.0f, 1.0f)), InputReceiverEnabled(true) { @@ -25,11 +25,6 @@ BBox.reset(0,0,0); - // set default view - - UpVector.set(0.0f, 1.0f, 0.0f); - Target.set(lookat); - // set default projection fovy = core::PI / 2.5f; // Field of view, in radians. @@ -115,6 +110,16 @@ //! \param pos: Look at target of the camera. void CCameraSceneNode::setTarget(const core::vector3df& pos) { + core::matrix4 mat; + mat.setRotationDegrees(getRotation()); + core::vector3df newView = (pos-getPosition()).normalize(); + core::vector3df newUp(mat.M[4], mat.M[5], mat.M[6]); + core::vector3df newRight = newUp.crossProduct(newView).normalize(); + newUp = newRight.crossProduct(newView); + mat.M[0]=newRight.X; mat.M[1]=newRight.Y; mat.M[2]=newRight.Z; + mat.M[4]=newUp.X; mat.M[5]=newUp.Y; mat.M[6]=newUp.Z; + mat.M[8]=newView.X; mat.M[9]=newView.Y; mat.M[10]=newView.Z; + setRotation(mat.getRotationDegrees()); Target = pos; } @@ -124,7 +129,9 @@ //! \return Returns the current look at target of the camera core::vector3df CCameraSceneNode::getTarget() const { - return Target; + core::matrix4 mat; + mat.setRotationDegrees(getRotation()); + return getPosition()+core::vector3df(mat.M[8], mat.M[9], mat.M[10]); } @@ -133,7 +140,17 @@ //! \param pos: New upvector of the camera. void CCameraSceneNode::setUpVector(const core::vector3df& pos) { - UpVector = pos; + core::matrix4 mat; + mat.setRotationDegrees(getRotation()); + core::vector3df view(mat.M[8], mat.M[9], mat.M[10]); + core::vector3df newUp(pos); + core::vector3df newRight = newUp.normalize().crossProduct(view); + newUp = newRight.crossProduct(view); + mat.M[0]=newRight.X; mat.M[1]=newRight.Y; mat.M[2]=newRight.Z; + mat.M[4]=newUp.X; mat.M[5]=newUp.Y; mat.M[6]=newUp.Z; + mat.M[8]=view.X; mat.M[9]=view.Y; mat.M[10]=view.Z; + setRotation(mat.getRotationDegrees()); + UpVector = newUp; } @@ -142,7 +159,9 @@ //! \return Returns the up vector of the camera. core::vector3df CCameraSceneNode::getUpVector() const { - return UpVector; + core::matrix4 mat; + mat.setRotationDegrees(getRotation()); + return core::vector3df(mat.M[4], mat.M[5], mat.M[6]); } @@ -193,7 +212,6 @@ void CCameraSceneNode::recalculateProjectionMatrix() { Projection.buildProjectionMatrixPerspectiveFovLH(fovy, aspect, zn, zf); - //recalculateViewArea(); } @@ -211,22 +229,15 @@ driver->setTransform(video::ETS_PROJECTION, Projection); - // if upvector and vector to the target are the same, we have a - // problem. so solve this problem: + core::matrix4 mat = getAbsoluteTransformation(); - core::vector3df pos = getAbsolutePosition(); - core::vector3df tgtv = Target - pos; - tgtv.normalize(); - - core::vector3df up = UpVector; - up.normalize(); - - f32 dp = tgtv.dotProduct(up); - if ((dp > -1.0001f && dp < -0.9999f) || - (dp < 1.0001f && dp > 0.9999f)) - up.X += 1.0f; + View.M[0] = mat.M[0]; View.M[1] = mat.M[4]; View.M[2] = mat.M[8]; View.M[3] = 0; + View.M[4] = mat.M[1]; View.M[5] = mat.M[5]; View.M[6] = mat.M[9]; View.M[7] = 0; + View.M[8] = mat.M[2]; View.M[9] = mat.M[6]; View.M[10] = mat.M[10]; View.M[11] = 0; + View.M[12]= -(mat.M[0]*mat.M[12] + mat.M[1]*mat.M[13] + mat.M[2]*mat.M[14]); + View.M[13]= -(mat.M[4]*mat.M[12] + mat.M[5]*mat.M[13] + mat.M[6]*mat.M[14]); + View.M[14]= -(mat.M[8]*mat.M[12] + mat.M[9]*mat.M[13] + mat.M[10]*mat.M[14]); - View.buildCameraLookAtMatrixLH(pos, Target, up); recalculateViewArea(); SceneManager->registerNodeForRendering(this, ESNRP_LIGHT_AND_CAMERA);