Irrlicht and RTS camera code how to keep from rotating below ground surface?

Started by
2 comments, last by MARS_999 10 years, 1 month ago

I am not sure what I need to modify to keep my camera from rotating 360 degrees when pressing right mouse button. Right now the camera can move below the ground and completely rotate 360 degrees.

THis code is from a tutorial/example someone made... so I am not sure what is going on. I am assuming I need to modify something in the on animate()...

Or could I somehow use a AABB box and do some kind of collision with the ground and the camera? IF so how do I go about this in the code they wrote.

Thanks!

#ifndef RTSCAMERA_H
#define RTSCAMERA_H 
 
class RTSCamera : public irr::scene::ICameraSceneNode 
{ 
public: 
  RTSCamera(irr::IrrlichtDevice* devicepointer, irr::scene::ISceneNode* parent, 
    irr::scene::ISceneManager* smgr, irr::s32 id,
irr::f32 rotatespeed = -1000.0f, irr::f32 zoomspeed = 1000.0f, 
irr::f32 translationspeed = 1000.0f); 
 
      virtual ~RTSCamera(); 
 
      //Events 
      virtual void render(); 
      virtual bool OnEvent(const irr::SEvent& event); 
      virtual void OnRegisterSceneNode(); 
      virtual void OnAnimate(irr::u32 timeMs); 
 
      //Setup 
      virtual void setInputReceiverEnabled(bool enabled); 
      virtual bool isInputReceiverEnabled() const; 
 
      //Gets 
 virtual const irr::core::aabbox3d<irr::f32>& getBoundingBox() const;
 virtual const irr::core::matrix4& getProjectionMatrix() const;
 virtual const irr::scene::SViewFrustum* getViewFrustum() const;
 virtual const irr::core::vector3df& getTarget() const;
 virtual const irr::core::matrix4& getViewMatrix() const;
 virtual const irr::core::vector3df& getUpVector() const;
      virtual irr::f32 getNearValue() const; 
 virtual irr::f32 getFarValue() const;
 virtual irr::f32 getAspectRatio() const;
 virtual irr::f32 getFOV() const;
 
      //Sets 
 virtual void setNearValue(irr::f32 zn);
 virtual void setFarValue(irr::f32 zf);
 virtual void setAspectRatio(irr::f32 aspect);
 virtual void setFOV(irr::f32 fovy);
 virtual void setUpVector(const irr::core::vector3df& pos);
 virtual void setProjectionMatrix(const irr::core::matrix4& projection);
      virtual void setPosition(const irr::core::vector3df& newpos); 
 virtual void setTarget(const irr::core::vector3df& newpos);
 
     virtual void setRotation(const irr::core::vector3df &) {} 
     virtual void setProjectionMatrix(const irr::core::matrix4 &,bool) {} 
     virtual void setViewMatrixAffector(const irr::core::matrix4 &) {} 
     virtual const irr::core::matrix4& getViewMatrixAffector() const {return irr::core::IdentityMatrix;}; 
     virtual void bindTargetAndRotation(bool) {} 
     virtual bool getTargetAndRotationBinding() const {return 0;} 
 
virtual void setZoomSpeed(irr::f32 value);
virtual void setTranslateSpeed(irr::f32 value);
virtual void setRotationSpeed(irr::f32 value);
 
 
      //Helper Functions 
      //virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0); 
      //virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); 
      void pointCameraAtNode(ISceneNode* selectednode); 
 void setMinZoom(irr::f32 amount);
 void setMaxZoom(irr::f32 amount);
 
      //Type Return 
 virtual irr::scene::ESCENE_NODE_TYPE getType() const { return irr::scene::ESNT_CAMERA; }
 
      //Public Attributes 
      bool atMinDistance; 
      bool atMaxDistance; 
      ISceneNode* selectednode; 
 
protected: 
      //Properties 
 irr::core::vector3df Target;
 irr::core::vector3df UpVector;
 irr::core::matrix4 Projection;
 irr::core::matrix4 View;
 irr::scene::SViewFrustum ViewArea;
 irr::core::aabbox3d<irr::f32> BBox;
      bool InputReceiverEnabled; 
 irr::core::dimension2d<irr::f32> screenDim;
      irr::f32 Fovy;      // Field of view, in radians. 
 irr::f32 Aspect;   // Aspect ratio. 
 irr::f32 ZNear;   // value of the near view-plane. 
 irr::f32 ZFar;   // Z-value of the far view-plane. 
 
      void recalculateProjectionMatrix(); 
      void recalculateViewArea(); 
 
private: 
      irr::IrrlichtDevice* device; 
      irr::core::vector3df Pos; 
      bool zooming, rotating, moving, translating; 
 irr::f32 zoomSpeed;
 irr::f32 translateSpeed;
 irr::f32 rotateSpeed;
 irr::f32 rotateStartX, rotateStartY;
 irr::f32 zoomStartX, zoomStartY;
 irr::f32 translateStartX, translateStartY;
 irr::f32 currentZoom;
 irr::f32 rotX, rotY;
 irr::core::vector3df oldTarget;
      irr::core::vector2df MousePos; 
      bool Keys[irr::KEY_KEY_CODES_COUNT]; 
      bool MouseKeys[3]; 
 irr::f32 targetMinDistance;
 irr::f32 targetMaxDistance;
 
      enum MOUSE_BUTTON 
      { 
         MOUSE_BUTTON_RIGHT, 
         MOUSE_BUTTON_MIDDLE, 
         MOUSE_BUTTON_LEFT 
      }; 
 
      void allKeysUp(); 
      void allMouseButtonsUp(); 
 bool isKeyDown(irr::s32 key);
 bool isMouseButtonDown(irr::s32 key);
      void animate(); 
      void updateAnimationState(); 
}; 
 
#endif 
 

#include "stdafx.h" 
 
RTSCamera::RTSCamera(irr::IrrlichtDevice* devicepointer, irr::scene::ISceneNode* parent,
irr::scene::ISceneManager* smgr, irr::s32 id,
irr::f32 rotatespeed, irr::f32 zoomspeed,
irr::f32 translationspeed) : ICameraSceneNode(parent, smgr, id, 
  irr::core::vector3df(1.0f, 1.0f, 1.0f),
  irr::core::vector3df(0.0f, 0.0f, 0.0f),
          irr::core::vector3df(1.0f, 1.0f, 1.0f)), 
  InputReceiverEnabled(true)
{ 
   device = devicepointer; 
   BBox.reset(0,0,0); 
 
   UpVector.set(0.0f, 1.0f, 0.0f); 
 
   // set default projection 
   Fovy = irr::core::PI / 2.5f;   // Field of view, in radians. 
   Aspect = 4.0f / 3.0f;          // Aspect ratio. 
   ZNear = 1.0f;                  // value of the near view-plane. 
   ZFar = 100000.0f;              // Z-value of the far view-plane. 
 
   irr::video::IVideoDriver* d = smgr->getVideoDriver(); 
   if (d) 
  Aspect = (irr::f32)d->getCurrentRenderTargetSize().Width / (irr::f32)d->getCurrentRenderTargetSize().Height;
 
   zooming  = false; 
   rotating = false; 
   moving   = false; 
   translating = false; 
   zoomSpeed   = zoomspeed; 
   rotateSpeed = rotatespeed;
   translateSpeed = translationspeed;
   targetMinDistance = 1.0f; 
   targetMaxDistance = 2000.0f; 
   Target.set(0.0f,0.0f,0.0f); 
   rotX = 0; 
   rotY = 0; 
   oldTarget = Target; 
 
   atMinDistance = false; 
   atMaxDistance = false; 
 
   allKeysUp(); 
   allMouseButtonsUp(); 
 
   recalculateProjectionMatrix(); 
   recalculateViewArea(); 
 
   smgr->setActiveCamera(this); 
} 
 
RTSCamera::~RTSCamera() 
{ 
} 
 
bool RTSCamera::OnEvent(const irr::SEvent& event) 
{ 
   if (!InputReceiverEnabled) 
      return false; 
 
   irr::core::dimension2d<irr::u32> ssize = SceneManager->getVideoDriver()->getScreenSize(); 
   if(event.EventType == irr::EET_MOUSE_INPUT_EVENT)
   { 
      //printf("a\n"); 
      switch(event.MouseInput.Event) 
      { 
 case irr::EMIE_LMOUSE_PRESSED_DOWN:
            selectednode = SceneManager->getSceneCollisionManager()->getSceneNodeFromScreenCoordinatesBB(device->getCursorControl()->getPosition()); 
if(selectednode && selectednode->getType() == irr::scene::ESNT_BILLBOARD)
            { 
               pointCameraAtNode(selectednode); 
            } 
            else 
            { 
               selectednode = NULL; 
               MouseKeys[0] = true; 
            } 
            break; 
 case irr::EMIE_RMOUSE_PRESSED_DOWN:
            MouseKeys[2] = true; 
            break; 
 case irr::EMIE_MMOUSE_PRESSED_DOWN:
            MouseKeys[1] = true; 
            break; 
 case irr::EMIE_LMOUSE_LEFT_UP:
            MouseKeys[0] = false; 
            break; 
 case irr::EMIE_RMOUSE_LEFT_UP:
            MouseKeys[2] = false; 
            break; 
 case irr::EMIE_MMOUSE_LEFT_UP:
            MouseKeys[1] = false; 
            break; 
 case irr::EMIE_MOUSE_MOVED:
            { 
  irr::video::IVideoDriver* driver = SceneManager->getVideoDriver();
               if (driver) 
               { 
  MousePos.X = event.MouseInput.X / (irr::f32)ssize.Width;
  MousePos.Y = event.MouseInput.Y / (irr::f32)ssize.Height;
               } 
            } 
            break; 
 case irr::EMIE_MOUSE_WHEEL:
{
currentZoom -= event.MouseInput.Wheel * zoomSpeed; 
if(currentZoom < 50.0f)//I added this code...
currentZoom = 50.0f;
if(currentZoom > 100.0f)
currentZoom = 100.0f;
}
            break; 
         default: 
            break; 
      } 
 
      return true; 
   } 
 
   if(event.EventType == irr::EET_KEY_INPUT_EVENT)
   { 
      Keys[event.KeyInput.Key] = event.KeyInput.PressedDown; 
      return true; 
   } 
 
   return false; 
} 
 
void RTSCamera::OnRegisterSceneNode() 
{ 
    
irr::core::vector3df pos = getAbsolutePosition();
irr::core::vector3df tgtv = Target - pos;
tgtv.normalize(); 
 
irr::core::vector3df up = UpVector;
up.normalize();
 
   irr::f32 dp = tgtv.dotProduct(up);
 
   if(irr::core::equals(fabs(dp), 1.f))
   { 
      up.X += 0.5f; 
   } 
 
   //ViewArea.Matrices [ ETS_VIEW ].buildCameraLookAtMatrixLH(pos, Target, up); 
   ViewArea.getTransform(irr::video::ETS_VIEW).buildCameraLookAtMatrixLH(pos, Target, up);
   //ViewArea.setTransformState ( ETS_VIEW ); 
   recalculateViewArea(); 
 
   if( SceneManager->getActiveCamera () == this ) 
  SceneManager->registerNodeForRendering(this, irr::scene::ESNRP_CAMERA);
 
   if(IsVisible) 
      ISceneNode::OnRegisterSceneNode(); 
    
} 
 
void RTSCamera::render() 
{ 
irr::video::IVideoDriver* driver = SceneManager->getVideoDriver();
   if ( driver) 
   { 
      //driver->setTransform(ETS_PROJECTION, ViewArea.Matrices [ ETS_PROJECTION ] ); 
  driver->setTransform(irr::video::ETS_PROJECTION, ViewArea.getTransform(irr::video::ETS_PROJECTION));
      //driver->setTransform(ETS_VIEW, ViewArea.Matrices [ ETS_VIEW ] ); 
  driver->setTransform(irr::video::ETS_VIEW, ViewArea.getTransform(irr::video::ETS_VIEW));
   } 
} 
 
void RTSCamera::OnAnimate(irr::u32 timeMs)
{ 
   animate(); 
 
   ISceneNode::setPosition(Pos); 
   updateAbsolutePosition(); 
} 
 
void RTSCamera::setInputReceiverEnabled(bool enabled) 
{ 
   InputReceiverEnabled = enabled; 
} 
 
bool RTSCamera::isInputReceiverEnabled() const 
{ 
   _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; 
   return InputReceiverEnabled; 
} 
 
const irr::core::aabbox3d<irr::f32>& RTSCamera::getBoundingBox() const
{ 
   return ViewArea.getBoundingBox(); 
} 
 
const irr::core::matrix4& RTSCamera::getProjectionMatrix() const
{ 
   //return ViewArea.Matrices [ ETS_PROJECTION ]; 
return ViewArea.getTransform(irr::video::ETS_PROJECTION);
} 
 
const irr::scene::SViewFrustum* RTSCamera::getViewFrustum() const
{ 
   return &ViewArea; 
} 
 
const irr::core::vector3df& RTSCamera::getTarget() const
{ 
   return Target; 
} 
 
const irr::core::matrix4& RTSCamera::getViewMatrix() const
{ 
   //return ViewArea.Matrices [ video::ETS_VIEW ]; 
return ViewArea.getTransform(irr::video::ETS_VIEW);
} 
 
const irr::core::vector3df& RTSCamera::getUpVector() const
{ 
   return UpVector; 
} 
 
irr::f32 RTSCamera::getNearValue() const
{ 
   return ZNear; 
} 
 
irr::f32 RTSCamera::getFarValue() const
{ 
   return ZFar; 
} 
 
irr::f32 RTSCamera::getAspectRatio() const
{ 
   return Aspect; 
} 
 
irr::f32 RTSCamera::getFOV() const
{ 
   return Fovy; 
} 
 
void RTSCamera::setNearValue(irr::f32 f)
{ 
   ZNear = f; 
   recalculateProjectionMatrix(); 
} 
 
void RTSCamera::setFarValue(irr::f32 f)
{ 
   ZFar = f; 
   recalculateProjectionMatrix(); 
} 
 
void RTSCamera::setAspectRatio(irr::f32 f)
{ 
   Aspect = f; 
   recalculateProjectionMatrix(); 
} 
 
void RTSCamera::setFOV(irr::f32 f)
{ 
   Fovy = f; 
   recalculateProjectionMatrix(); 
} 
 
void RTSCamera::setUpVector(const irr::core::vector3df& pos)
{ 
   UpVector = pos; 
} 
 
void RTSCamera::setProjectionMatrix(const irr::core::matrix4& projection)
{ 
   //ViewArea.Matrices [ ETS_PROJECTION ] = projection; 
ViewArea.getTransform(irr::video::ETS_PROJECTION) = projection;
   //ViewArea.setTransformState ( ETS_PROJECTION ); 
} 
 
void RTSCamera::setPosition(const irr::core::vector3df& pos)
{ 
   Pos = pos; 
   updateAnimationState(); 
 
   ISceneNode::setPosition(pos); 
} 
 
void RTSCamera::setTarget(const irr::core::vector3df& pos)
{ 
   Target = oldTarget = pos; 
   updateAnimationState(); 
} 
 
void RTSCamera::setZoomSpeed(irr::f32 value)
{ 
   zoomSpeed = value; 
} 
 
void RTSCamera::setTranslateSpeed(irr::f32 value)
{ 
   translateSpeed = value; 
} 
 
void RTSCamera::setRotationSpeed(irr::f32 value)
{ 
   rotateSpeed = value; 
} 
 
void RTSCamera::pointCameraAtNode(ISceneNode* selectednode) 
{ 
irr::core::vector3df totarget = getPosition() - getTarget();
   setPosition(selectednode->getPosition() + (totarget.normalize() * 100)); 
   setTarget(selectednode->getPosition()); 
   updateAnimationState(); 
} 
 
void RTSCamera::setMinZoom(irr::f32 amount)
{ 
   targetMinDistance = amount; 
} 
 
void RTSCamera::setMaxZoom(irr::f32 amount)
{ 
   targetMaxDistance = amount; 
} 
 
void RTSCamera::recalculateProjectionMatrix() 
{ 
   //ViewArea.Matrices [ ETS_PROJECTION ].buildProjectionMatrixPerspectiveFovLH(Fovy, Aspect, ZNear, ZFar); 
ViewArea.getTransform(irr::video::ETS_PROJECTION).buildProjectionMatrixPerspectiveFovLH(Fovy, Aspect, ZNear, ZFar);
   //ViewArea.setTransformState ( ETS_PROJECTION ); 
} 
 
void RTSCamera::recalculateViewArea() 
{ 
   ViewArea.cameraPosition = getAbsolutePosition(); 
   //ViewArea.setFrom ( ViewArea.Matrices [ SViewFrustum::ETS_VIEW_PROJECTION_3 ] ); 
   ViewArea.setFrom(ViewArea.getTransform(irr::video::ETS_PROJECTION)*ViewArea.getTransform(irr::video::ETS_VIEW));
} 
 
void RTSCamera::allKeysUp() 
{ 
for(int i = 0; i < irr::KEY_KEY_CODES_COUNT; i++)
      Keys[i] = false; 
} 
 
void RTSCamera::allMouseButtonsUp() 
{ 
for(irr::s32 i = 0; i<3; ++i)
      MouseKeys[i] = false; 
} 
 
bool RTSCamera::isKeyDown(irr::s32 key)
{ 
   return Keys[key]; 
} 
 
bool RTSCamera::isMouseButtonDown(irr::s32 key)
{ 
   return MouseKeys[key]; 
} 
 
void RTSCamera::animate() 
{ 
irr::f32 nRotX = rotX;
irr::f32 nRotY = rotY;
irr::f32 nZoom = currentZoom;
 
irr::core::vector3df translate(oldTarget);
irr::core::vector3df tvectX = Pos - Target;
tvectX = tvectX.crossProduct(UpVector); 
tvectX.normalize(); 
 
   //Zoom 
   if (isMouseButtonDown(MOUSE_BUTTON_RIGHT) && isMouseButtonDown(MOUSE_BUTTON_LEFT)) 
   { 
      if (!zooming) 
      { 
         zoomStartX = MousePos.X; 
         zoomStartY = MousePos.Y; 
         zooming = true; 
         nZoom = currentZoom; 
      } 
      else 
      { 
 irr::f32 old = nZoom;
         nZoom += (zoomStartX - MousePos.X) * zoomSpeed * 100; 
 
//         f32 targetMinDistance = 0.1f; 
//         if (nZoom < targetMinDistance) 
//            nZoom = targetMinDistance; 
 
         if (nZoom < targetMinDistance) 
            nZoom = targetMinDistance; 
         else if (nZoom > targetMaxDistance) 
            nZoom = targetMaxDistance; 
 
 
         if (nZoom < 0) 
            nZoom = old; 
      } 
   } 
   else 
   { 
      if (zooming) 
      { 
 irr::f32 old = currentZoom;
         currentZoom = currentZoom + (zoomStartX - MousePos.X ) * zoomSpeed; 
         nZoom = currentZoom; 
 
         if (nZoom < 0) 
            nZoom = currentZoom = old; 
      } 
      zooming = false; 
   } 
 
   //Rotate 
   if(isMouseButtonDown(MOUSE_BUTTON_LEFT) && !zooming) 
   { 
      if (!rotating) 
      { 
         rotateStartX = MousePos.X; 
         rotateStartY = MousePos.Y; 
         rotating = true; 
         nRotX = rotX; 
         nRotY = rotY; 
      } 
      else 
      { 
         nRotX += (rotateStartX - MousePos.X) * rotateSpeed; 
         nRotY += (rotateStartY - MousePos.Y) * rotateSpeed; 
      } 
   } 
   else 
   { 
      if (rotating) 
      { 
         rotX = rotX + (rotateStartX - MousePos.X) * rotateSpeed; 
         rotY = rotY + (rotateStartY - MousePos.Y) * rotateSpeed; 
         nRotX = rotX; 
         nRotY = rotY; 
      } 
 
      rotating = false; 
   } 
 
   //Translate 
   if(isMouseButtonDown(MOUSE_BUTTON_RIGHT) && !zooming) 
   { 
      if (!translating) 
      { 
         translateStartX = MousePos.X; 
         translateStartY = MousePos.Y; 
         translating = true; 
      } 
      else 
      { 
         translate += tvectX * (translateStartX - MousePos.X) * translateSpeed; 
         translate.X += tvectX.Z * (translateStartY - MousePos.Y) * translateSpeed; 
         translate.Z -= tvectX.X * (translateStartY - MousePos.Y) * translateSpeed; 
 
         oldTarget = translate; 
      } 
   } 
   else if(isKeyDown(irr::KEY_KEY_W)  || isKeyDown(irr::KEY_UP)    && !zooming) 
   { 
      if (!translating) 
         translating = true; 
      else 
      { 
 irr::core::vector3df movevector = getPosition() - getTarget();
         movevector.Y = 0; 
         movevector.normalize(); 
 
         setPosition(getPosition() - movevector * translateSpeed); 
         setTarget(getTarget() - movevector * translateSpeed); 
         updateAbsolutePosition(); 
      } 
   } 
   else if(isKeyDown(irr::KEY_KEY_S)  || isKeyDown(irr::KEY_DOWN)  && !zooming)
   { 
      if (!translating) 
         translating = true; 
      else 
      { 
 irr::core::vector3df movevector = getPosition() - getTarget();
         movevector.Y = 0; 
         movevector.normalize(); 
 
         setPosition(getPosition() + movevector * translateSpeed); 
         setTarget(getTarget() + movevector * translateSpeed); 
         updateAbsolutePosition(); 
      } 
   } 
   else if(isKeyDown(irr::KEY_KEY_A)  || isKeyDown(irr::KEY_LEFT)  && !zooming)
   { 
      if (!translating) 
         translating = true; 
      else 
      { 
 irr::core::vector3df totargetvector = getPosition() - getTarget();
         totargetvector.normalize(); 
irr::core::vector3df crossvector = totargetvector.crossProduct(getUpVector());
irr::core::vector3df strafevector = crossvector.normalize();
 
         setPosition(getPosition() - strafevector * translateSpeed); 
         setTarget(getTarget() - strafevector * translateSpeed); 
         updateAbsolutePosition(); 
      } 
   } 
   else if(isKeyDown(irr::KEY_KEY_D)  || isKeyDown(irr::KEY_RIGHT) && !zooming)
   { 
      if (!translating) 
         translating = true; 
      else 
      { 
 irr::core::vector3df totargetvector = getPosition() - getTarget();
         totargetvector.normalize(); 
irr::core::vector3df crossvector = totargetvector.crossProduct(getUpVector());
irr::core::vector3df strafevector = crossvector.normalize();
 
         setPosition(getPosition() + strafevector * translateSpeed); 
         setTarget(getTarget() + strafevector * translateSpeed); 
         updateAbsolutePosition(); 
      } 
   } 
   else 
   { 
      translating = false; 
 
      if (!translating && !zooming && !rotating) 
      { 
         //Mouse Coordinates go from 0 to 1 on both axes 
         if (MousePos.X < 0.05)   //Up 
         { 
irr::core::vector3df totargetvector = getPosition() - getTarget();
            totargetvector.normalize(); 
irr::core::vector3df crossvector = totargetvector.crossProduct(getUpVector());
irr::core::vector3df strafevector = crossvector.normalize();
 
            setPosition(getPosition() - strafevector * translateSpeed); 
            setTarget(getTarget() - strafevector * translateSpeed); 
            updateAbsolutePosition(); 
         } 
         else if (MousePos.X > 0.95) //Down 
         { 
irr::core::vector3df totargetvector = getPosition() - getTarget();
            totargetvector.normalize(); 
irr::core::vector3df crossvector = totargetvector.crossProduct(getUpVector());
irr::core::vector3df strafevector = crossvector.normalize();
 
            setPosition(getPosition() + strafevector * translateSpeed); 
            setTarget(getTarget() + strafevector * translateSpeed); 
            updateAbsolutePosition(); 
         } 
         else if (MousePos.Y < 0.05)   //Up 
         { 
irr::core::vector3df movevector = getPosition() - getTarget();
            movevector.Y = 0; 
            movevector.normalize(); 
 
            setPosition(getPosition() - movevector * translateSpeed); 
            setTarget(getTarget() - movevector * translateSpeed); 
            updateAbsolutePosition(); 
         } 
         else if (MousePos.Y > 0.95) //Down 
         { 
irr::core::vector3df movevector = getPosition() - getTarget();
            movevector.Y = 0; 
            movevector.normalize(); 
 
            setPosition(getPosition() + movevector * translateSpeed); 
            setTarget(getTarget() + movevector * translateSpeed); 
            updateAbsolutePosition(); 
         } 
      } 
   } 
 
   //Set Position 
   Target = translate; 
 
   Pos.X = nZoom + Target.X; 
   Pos.Y = Target.Y; 
   Pos.Z = Target.Z; 
 
   Pos.rotateXYBy(nRotY, Target); 
   Pos.rotateXZBy(-nRotX, Target); 
 
   //Correct Rotation Error 
   UpVector.set(0,1,0); 
   UpVector.rotateXYBy(-nRotY, irr::core::vector3df(0,0,0)); 
   UpVector.rotateXZBy(-nRotX+180.f, irr::core::vector3df(0,0,0)); 
} 
 
void RTSCamera::updateAnimationState() 
{ 
irr::core::vector3df pos(Pos - Target);
 
   // X rotation 
irr::core::vector2df vec2d(pos.X, pos.Z);
   rotX = (irr::f32)vec2d.getAngle(); 
 
   // Y rotation 
   pos.rotateXZBy(rotX, irr::core::vector3df());
   vec2d.set(pos.X, pos.Y); 
   rotY = -(irr::f32)vec2d.getAngle(); 
 
   // Zoom 
   currentZoom = (irr::f32)Pos.getDistanceFrom(Target); 
}

Advertisement

Anyone?

Anyone?

It would be helpful to narrow down the problem. I mean, you post >700 lines of code... have you pre-analysed the stuff, can you point us to the methods, which do actually the rotation. This would be really helpful.smile.png

Got me best I can tell is somewhere in this code maybe a fix...

void RTSCamera::animate() 
{ 
irr::f32 nRotX = rotX;
irr::f32 nRotY = rotY;
irr::f32 nZoom = currentZoom;
 
irr::core::vector3df translate(oldTarget);
irr::core::vector3df tvectX = Pos - Target;
tvectX = tvectX.crossProduct(UpVector); 
tvectX.normalize(); 
 
   //Zoom 
   if (isMouseButtonDown(MOUSE_BUTTON_RIGHT) && isMouseButtonDown(MOUSE_BUTTON_LEFT)) 
   { 
      if (!zooming) 
      { 
         zoomStartX = MousePos.X; 
         zoomStartY = MousePos.Y; 
         zooming = true; 
         nZoom = currentZoom; 
      } 
      else 
      { 
 irr::f32 old = nZoom;
         nZoom += (zoomStartX - MousePos.X) * zoomSpeed * 100; 
 
//         f32 targetMinDistance = 0.1f; 
//         if (nZoom < targetMinDistance) 
//            nZoom = targetMinDistance; 
 
         if (nZoom < targetMinDistance) 
            nZoom = targetMinDistance; 
         else if (nZoom > targetMaxDistance) 
            nZoom = targetMaxDistance; 
 
 
         if (nZoom < 0) 
            nZoom = old; 
      } 
   } 
   else 
   { 
      if (zooming) 
      { 
 irr::f32 old = currentZoom;
         currentZoom = currentZoom + (zoomStartX - MousePos.X ) * zoomSpeed; 
         nZoom = currentZoom; 
 
         if (nZoom < 0) 
            nZoom = currentZoom = old; 
      } 
      zooming = false; 
   } 
 
   //Rotate 
   if(isMouseButtonDown(MOUSE_BUTTON_LEFT) && !zooming) 
   { 
      if (!rotating) 
      { 
         rotateStartX = MousePos.X; 
         rotateStartY = MousePos.Y; 
         rotating = true; 
         nRotX = rotX; 
         nRotY = rotY; 
      } 
      else 
      { 
         nRotX += (rotateStartX - MousePos.X) * rotateSpeed; 
         nRotY += (rotateStartY - MousePos.Y) * rotateSpeed; 
      } 
   } 
   else 
   { 
      if (rotating) 
      { 
         rotX = rotX + (rotateStartX - MousePos.X) * rotateSpeed; 
         rotY = rotY + (rotateStartY - MousePos.Y) * rotateSpeed; 
         nRotX = rotX; 
         nRotY = rotY; 
      } 
 
      rotating = false; 
   } 
 
   //Translate 
   if(isMouseButtonDown(MOUSE_BUTTON_RIGHT) && !zooming) 
   { 
      if (!translating) 
      { 
         translateStartX = MousePos.X; 
         translateStartY = MousePos.Y; 
         translating = true; 
      } 
      else 
      { 
         translate += tvectX * (translateStartX - MousePos.X) * translateSpeed; 
         translate.X += tvectX.Z * (translateStartY - MousePos.Y) * translateSpeed; 
         translate.Z -= tvectX.X * (translateStartY - MousePos.Y) * translateSpeed; 
 
         oldTarget = translate; 
      } 
   } 
   else if(isKeyDown(irr::KEY_KEY_W)  || isKeyDown(irr::KEY_UP)    && !zooming) 
   { 
      if (!translating) 
         translating = true; 
      else 
      { 
 irr::core::vector3df movevector = getPosition() - getTarget();
         movevector.Y = 0; 
         movevector.normalize(); 
 
         setPosition(getPosition() - movevector * translateSpeed); 
         setTarget(getTarget() - movevector * translateSpeed); 
         updateAbsolutePosition(); 
      } 
   } 
   else if(isKeyDown(irr::KEY_KEY_S)  || isKeyDown(irr::KEY_DOWN)  && !zooming)
   { 
      if (!translating) 
         translating = true; 
      else 
      { 
 irr::core::vector3df movevector = getPosition() - getTarget();
         movevector.Y = 0; 
         movevector.normalize(); 
 
         setPosition(getPosition() + movevector * translateSpeed); 
         setTarget(getTarget() + movevector * translateSpeed); 
         updateAbsolutePosition(); 
      } 
   } 
   else if(isKeyDown(irr::KEY_KEY_A)  || isKeyDown(irr::KEY_LEFT)  && !zooming)
   { 
      if (!translating) 
         translating = true; 
      else 
      { 
 irr::core::vector3df totargetvector = getPosition() - getTarget();
         totargetvector.normalize(); 
irr::core::vector3df crossvector = totargetvector.crossProduct(getUpVector());
irr::core::vector3df strafevector = crossvector.normalize();
 
         setPosition(getPosition() - strafevector * translateSpeed); 
         setTarget(getTarget() - strafevector * translateSpeed); 
         updateAbsolutePosition(); 
      } 
   } 
   else if(isKeyDown(irr::KEY_KEY_D)  || isKeyDown(irr::KEY_RIGHT) && !zooming)
   { 
      if (!translating) 
         translating = true; 
      else 
      { 
 irr::core::vector3df totargetvector = getPosition() - getTarget();
         totargetvector.normalize(); 
irr::core::vector3df crossvector = totargetvector.crossProduct(getUpVector());
irr::core::vector3df strafevector = crossvector.normalize();
 
         setPosition(getPosition() + strafevector * translateSpeed); 
         setTarget(getTarget() + strafevector * translateSpeed); 
         updateAbsolutePosition(); 
      } 
   } 
   else 
   { 
      translating = false; 
 
      if (!translating && !zooming && !rotating) 
      { 
         //Mouse Coordinates go from 0 to 1 on both axes 
         if (MousePos.X < 0.05)   //Up 
         { 
irr::core::vector3df totargetvector = getPosition() - getTarget();
            totargetvector.normalize(); 
irr::core::vector3df crossvector = totargetvector.crossProduct(getUpVector());
irr::core::vector3df strafevector = crossvector.normalize();
 
            setPosition(getPosition() - strafevector * translateSpeed); 
            setTarget(getTarget() - strafevector * translateSpeed); 
            updateAbsolutePosition(); 
         } 
         else if (MousePos.X > 0.95) //Down 
         { 
irr::core::vector3df totargetvector = getPosition() - getTarget();
            totargetvector.normalize(); 
irr::core::vector3df crossvector = totargetvector.crossProduct(getUpVector());
irr::core::vector3df strafevector = crossvector.normalize();
 
            setPosition(getPosition() + strafevector * translateSpeed); 
            setTarget(getTarget() + strafevector * translateSpeed); 
            updateAbsolutePosition(); 
         } 
         else if (MousePos.Y < 0.05)   //Up 
         { 
irr::core::vector3df movevector = getPosition() - getTarget();
            movevector.Y = 0; 
            movevector.normalize(); 
 
            setPosition(getPosition() - movevector * translateSpeed); 
            setTarget(getTarget() - movevector * translateSpeed); 
            updateAbsolutePosition(); 
         } 
         else if (MousePos.Y > 0.95) //Down 
         { 
irr::core::vector3df movevector = getPosition() - getTarget();
            movevector.Y = 0; 
            movevector.normalize(); 
 
            setPosition(getPosition() + movevector * translateSpeed); 
            setTarget(getTarget() + movevector * translateSpeed); 
            updateAbsolutePosition(); 
         } 
      } 
   } 
 
   //Set Position 
   Target = translate; 
 
   Pos.X = nZoom + Target.X; 
   Pos.Y = Target.Y; 
   Pos.Z = Target.Z; 
 
   Pos.rotateXYBy(nRotY, Target); 
   Pos.rotateXZBy(-nRotX, Target); 
 
   //Correct Rotation Error 
   UpVector.set(0,1,0); 
   UpVector.rotateXYBy(-nRotY, irr::core::vector3df(0,0,0)); 
   UpVector.rotateXZBy(-nRotX+180.f, irr::core::vector3df(0,0,0)); 
} 
[

This topic is closed to new replies.

Advertisement