(C++) RTSCamera

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
mikademus
Posts: 7
Joined: Fri May 23, 2008 8:26 pm

Post by mikademus »

If this camera is solid and useful enough, perhaps is could go into the source base as a compliment to the FPSCamera?

Or perhaps both this and the FPSCamera could be moved into an extras namespace or header or something.
renegadeandy
Posts: 122
Joined: Sun May 25, 2008 11:14 pm
Location: Scotland
Contact:

Post by renegadeandy »

With my fairly extended use of this camera its probably not a good idea in the state it was left by the developer.

A lot of some standard things still dont work with it - Ive changed a lot but still dont have collision detection etc working nicely - useful for some nice effects and I suppose it also depends how you want the camera to work.

I could post what I have done to it since - but if you look back at what the developer said about 2 weeks ago he claimed he would be returning to tidy up what he didnt finish here (havent heard anything since) so if anybody can push him to continue developing it that would be great - otherwise I suppose I could also give my latest hybrid version!
NeRoX
Posts: 12
Joined: Fri Jul 11, 2008 8:15 pm

Post by NeRoX »

Im using Irrlicht 1.4.1 and I checking the last code, I added consts where it need and I have problem with it... it's not working.

http://irrlicht.sourceforge.net/phpBB2/ ... 931#163931

Thanks!
night_hawk
Posts: 153
Joined: Mon Mar 03, 2008 8:42 am
Location: Suceava - Romania
Contact:

Post by night_hawk »

Because people want it, here's a version that works with the latest version of irrlicht.

rtscamera2.h

Code: Select all

#ifndef __RTSCAMERA__
#define __RTSCAMERA__

#include <irrlicht.h>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

class RTSCamera : public ICameraSceneNode
{
   public:
      RTSCamera(IrrlichtDevice* devicepointer,ISceneNode* parent,ISceneManager* smgr,s32 id,
         f32 rotateSpeed = -1000.0f,f32 zoomSpeed = 1000.0f,f32 translationSpeed = 1000.0f);

      virtual ~RTSCamera();

      //Events
      virtual void render();
      virtual bool OnEvent(const SEvent& event);
      virtual void OnRegisterSceneNode();
      virtual void OnAnimate(u32 timeMs);

      //Setup
      virtual void setInputReceiverEnabled(bool enabled);
      virtual bool isInputReceiverEnabled() const;

      //Gets
      virtual const aabbox3d<f32>& getBoundingBox() const;
      virtual const matrix4& getProjectionMatrix() const;
      virtual const SViewFrustum* getViewFrustum() const;
      virtual const core::vector3df& getTarget() const;
      virtual const matrix4& getViewMatrix() const;
      virtual const core::vector3df& getUpVector() const;
      virtual f32 getNearValue() const;
      virtual f32 getFarValue() const;
      virtual f32 getAspectRatio() const;
      virtual f32 getFOV() const;

      //Sets
      virtual void setNearValue(f32 zn);
      virtual void setFarValue(f32 zf);
      virtual void setAspectRatio(f32 aspect);
      virtual void setFOV(f32 fovy);
      virtual void setUpVector(const vector3df& pos);
      virtual void setProjectionMatrix(const matrix4& projection);
      virtual void setPosition(const vector3df& newpos);
      virtual void setTarget(const 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 core::matrix4& getViewMatrixAffector() const {return core::matrix4();};
	  virtual void bindTargetAndRotation(bool) {}
	  virtual bool getTargetAndRotationBinding() const {return 0;}

      virtual void setZoomSpeed(f32 value);
      virtual void setTranslateSpeed(f32 value);
      virtual void setRotationSpeed(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(f32 amount);
      void setMaxZoom(f32 amount);

      //Type Return
      virtual ESCENE_NODE_TYPE getType() const { return ESNT_CAMERA; }

      //Public Attributes
      bool atMinDistance;
      bool atMaxDistance;
      ISceneNode* selectednode;
   protected:
      //Properties
      vector3df Target;
      vector3df UpVector;
      matrix4 Projection;
      matrix4 View;
      SViewFrustum ViewArea;
      aabbox3d<f32> BBox;
      bool InputReceiverEnabled;
      dimension2d<f32> screenDim;
      f32 Fovy;      // Field of view, in radians.
      f32 Aspect;   // Aspect ratio.
      f32 ZNear;   // value of the near view-plane.
      f32 ZFar;   // Z-value of the far view-plane.

      void recalculateProjectionMatrix();
      void recalculateViewArea();

   private:
      IrrlichtDevice* device;
      vector3df Pos;
      bool zooming, rotating, moving, translating;
      f32 zoomSpeed;
      f32 translateSpeed;
      f32 rotateSpeed;
      f32 rotateStartX, rotateStartY;
      f32 zoomStartX, zoomStartY;
      f32 translateStartX, translateStartY;
      f32 currentZoom;
      f32 rotX, rotY;
      vector3df oldTarget;
      vector2df MousePos;
      bool Keys[KEY_KEY_CODES_COUNT];
      bool MouseKeys[3];
      f32 targetMinDistance;
      f32 targetMaxDistance;

      enum MOUSE_BUTTON
      {
         MOUSE_BUTTON_RIGHT,
         MOUSE_BUTTON_MIDDLE,
         MOUSE_BUTTON_LEFT
      };

      void allKeysUp();
      void allMouseButtonsUp();
      bool isKeyDown(s32 key);
      bool isMouseButtonDown(s32 key);
      void animate();
      void updateAnimationState();
};

#endif 
rtscamera2.cpp

Code: Select all

#include "rtscamera2.h"

RTSCamera::RTSCamera(IrrlichtDevice* devicepointer,ISceneNode* parent,ISceneManager* smgr,s32 id,
    f32 rs,f32 zs,f32 ts)
   : ICameraSceneNode(parent,smgr,id,vector3df(1.0f,1.0f,1.0f),vector3df(0.0f,0.0f,0.0f),
               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 = 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.

   IVideoDriver* d = smgr->getVideoDriver();
   if (d)
      Aspect = (f32)d->getCurrentRenderTargetSize().Width / (f32)d->getCurrentRenderTargetSize().Height;

   zooming = false;
   rotating = false;
   moving = false;
   translating = false;
   zoomSpeed = zs;
   rotateSpeed = rs;
   translateSpeed = ts;
   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 SEvent& event)
{
   if (!InputReceiverEnabled)
      return false;

   dimension2d<u32> ssize = SceneManager->getVideoDriver()->getScreenSize();
   if(event.EventType == EET_MOUSE_INPUT_EVENT)
   {
	   //printf("a\n");
      switch(event.MouseInput.Event)
      {
         case EMIE_LMOUSE_PRESSED_DOWN:
            selectednode = SceneManager->getSceneCollisionManager()->getSceneNodeFromScreenCoordinatesBB(device->getCursorControl()->getPosition());
            if(selectednode && selectednode->getType() == ESNT_BILLBOARD)
            {
               pointCameraAtNode(selectednode);
            }
            else
            {
               selectednode = NULL;
               MouseKeys[0] = true;
            }
            break;
         case EMIE_RMOUSE_PRESSED_DOWN:
            MouseKeys[2] = true;
            break;
         case EMIE_MMOUSE_PRESSED_DOWN:
            MouseKeys[1] = true;
            break;
         case EMIE_LMOUSE_LEFT_UP:
            MouseKeys[0] = false;
            break;
         case EMIE_RMOUSE_LEFT_UP:
            MouseKeys[2] = false;
            break;
         case EMIE_MMOUSE_LEFT_UP:
            MouseKeys[1] = false;
            break;
         case EMIE_MOUSE_MOVED:
            {
               IVideoDriver* driver = SceneManager->getVideoDriver();
               if (driver)
               {
                  MousePos.X = event.MouseInput.X / (f32)ssize.Width;
                  MousePos.Y = event.MouseInput.Y / (f32)ssize.Height;
               }
            }
            break;
         case EMIE_MOUSE_WHEEL:
            currentZoom -= event.MouseInput.Wheel * zoomSpeed;
            break;
         default:
            break;
      }

      return true;
   }

   if(event.EventType == EET_KEY_INPUT_EVENT)
   {
      Keys[event.KeyInput.Key] = event.KeyInput.PressedDown;
      return true;
   }

   return false;
}

void RTSCamera::OnRegisterSceneNode()
{
	
   vector3df pos = getAbsolutePosition();
   vector3df tgtv = Target - pos;
   tgtv.normalize();

   vector3df up = UpVector;
   up.normalize();

   f32 dp = tgtv.dotProduct(up);

   if ( core::equals ( fabs ( dp ), 1.f ) )
   {
      up.X += 0.5f;
   }

   //ViewArea.Matrices [ ETS_VIEW ].buildCameraLookAtMatrixLH(pos, Target, up);
   ViewArea.getTransform(ETS_VIEW).buildCameraLookAtMatrixLH(pos, Target, up);
   //ViewArea.setTransformState ( ETS_VIEW );
   recalculateViewArea();

   if( SceneManager->getActiveCamera () == this )
      SceneManager->registerNodeForRendering(this, ESNRP_CAMERA);

   if(IsVisible)
      ISceneNode::OnRegisterSceneNode();
   
}

void RTSCamera::render()
{
   IVideoDriver* driver = SceneManager->getVideoDriver();
   if ( driver)
   {
      //driver->setTransform(ETS_PROJECTION, ViewArea.Matrices [ ETS_PROJECTION ] );
	   driver->setTransform(ETS_PROJECTION, ViewArea.getTransform(ETS_PROJECTION) );
      //driver->setTransform(ETS_VIEW, ViewArea.Matrices [ ETS_VIEW ] );
	   driver->setTransform(ETS_VIEW, ViewArea.getTransform(ETS_VIEW) );
   }
}

void RTSCamera::OnAnimate(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 aabbox3d<f32>& RTSCamera::getBoundingBox() const
{
   return ViewArea.getBoundingBox();
}

const matrix4& RTSCamera::getProjectionMatrix() const
{
   //return ViewArea.Matrices [ ETS_PROJECTION ];
	return ViewArea.getTransform(ETS_PROJECTION);
}

const SViewFrustum* RTSCamera::getViewFrustum() const
{
   return &ViewArea;
}

const core::vector3df& RTSCamera::getTarget() const
{
   return Target;
}

const matrix4& RTSCamera::getViewMatrix() const
{
   //return ViewArea.Matrices [ video::ETS_VIEW ];
	return ViewArea.getTransform(ETS_VIEW);
}

const core::vector3df& RTSCamera::getUpVector() const
{
   return UpVector;
}

f32 RTSCamera::getNearValue() const
{
   return ZNear;
}

f32 RTSCamera::getFarValue() const
{
   return ZFar;
}

f32 RTSCamera::getAspectRatio() const
{
   return Aspect;
}

f32 RTSCamera::getFOV() const
{
   return Fovy;
}

void RTSCamera::setNearValue(f32 f)
{
   ZNear = f;
   recalculateProjectionMatrix();
}

void RTSCamera::setFarValue(f32 f)
{
   ZFar = f;
   recalculateProjectionMatrix();
}

void RTSCamera::setAspectRatio(f32 f)
{
   Aspect = f;
   recalculateProjectionMatrix();
}

void RTSCamera::setFOV(f32 f)
{
   Fovy = f;
   recalculateProjectionMatrix();
}

void RTSCamera::setUpVector(const vector3df& pos)
{
   UpVector = pos;
}

void RTSCamera::setProjectionMatrix(const matrix4& projection)
{
   //ViewArea.Matrices [ ETS_PROJECTION ] = projection;
	ViewArea.getTransform(ETS_PROJECTION) = projection;
   //ViewArea.setTransformState ( ETS_PROJECTION );
}

void RTSCamera::setPosition(const core::vector3df& pos)
{
   Pos = pos;
   updateAnimationState();

   ISceneNode::setPosition(pos);
}

void RTSCamera::setTarget(const core::vector3df& pos)
{
   Target = oldTarget = pos;
   updateAnimationState();
}

void RTSCamera::setZoomSpeed(f32 value)
{
   zoomSpeed = value;
}

void RTSCamera::setTranslateSpeed(f32 value)
{
   translateSpeed = value;
}

void RTSCamera::setRotationSpeed(f32 value)
{
   rotateSpeed = value;
}

void RTSCamera::pointCameraAtNode(ISceneNode* selectednode)
{
   vector3df totarget = getPosition() - getTarget();
   setPosition(selectednode->getPosition() + (totarget.normalize() * 100));
   setTarget(selectednode->getPosition());
   updateAnimationState();
}

void RTSCamera::setMinZoom(f32 amount)
{
   targetMinDistance = amount;
}

void RTSCamera::setMaxZoom(f32 amount)
{
   targetMaxDistance = amount;
}

void RTSCamera::recalculateProjectionMatrix()
{
   //ViewArea.Matrices [ ETS_PROJECTION ].buildProjectionMatrixPerspectiveFovLH(Fovy, Aspect, ZNear, ZFar);
	ViewArea.getTransform(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(ETS_PROJECTION)*ViewArea.getTransform(ETS_VIEW) );
}

void RTSCamera::allKeysUp()
{
   for(int i = 0;i < KEY_KEY_CODES_COUNT;i++)
      Keys[i] = false;
}

void RTSCamera::allMouseButtonsUp()
{
   for (s32 i=0; i<3; ++i)
      MouseKeys[i] = false;
}

bool RTSCamera::isKeyDown(s32 key)
{
   return Keys[key];
}

bool RTSCamera::isMouseButtonDown(s32 key)
{
   return MouseKeys[key];
}

void RTSCamera::animate()
{
   f32 nRotX = rotX;
   f32 nRotY = rotY;
   f32 nZoom = currentZoom;

   vector3df translate(oldTarget);
   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
      {
         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)
      {
         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(KEY_KEY_W) || isKeyDown(KEY_UP) && !zooming)
   {
      if (!translating)
         translating = true;
      else
      {
         vector3df movevector = getPosition() - getTarget();
         movevector.Y = 0;
         movevector.normalize();

         setPosition(getPosition() - movevector * translateSpeed);
         setTarget(getTarget() - movevector * translateSpeed);
         updateAbsolutePosition();
      }
   }
   else if (isKeyDown(KEY_KEY_S) || isKeyDown(KEY_DOWN) && !zooming)
   {
      if (!translating)
         translating = true;
      else
      {
         vector3df movevector = getPosition() - getTarget();
         movevector.Y = 0;
         movevector.normalize();

         setPosition(getPosition() + movevector * translateSpeed);
         setTarget(getTarget() + movevector * translateSpeed);
         updateAbsolutePosition();
      }
   }
   else if (isKeyDown(KEY_KEY_A) || isKeyDown(KEY_LEFT) && !zooming)
   {
      if (!translating)
         translating = true;
      else
      {
         vector3df totargetvector = getPosition() - getTarget();
         totargetvector.normalize();
         vector3df crossvector = totargetvector.crossProduct(getUpVector());
         vector3df strafevector = crossvector.normalize();

         setPosition(getPosition() - strafevector * translateSpeed);
         setTarget(getTarget() - strafevector * translateSpeed);
         updateAbsolutePosition();
      }
   }
   else if (isKeyDown(KEY_KEY_D) || isKeyDown(KEY_RIGHT) && !zooming)
   {
      if (!translating)
         translating = true;
      else
      {
         vector3df totargetvector = getPosition() - getTarget();
         totargetvector.normalize();
         vector3df crossvector = totargetvector.crossProduct(getUpVector());
         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
         {
            vector3df totargetvector = getPosition() - getTarget();
            totargetvector.normalize();
            vector3df crossvector = totargetvector.crossProduct(getUpVector());
            vector3df strafevector = crossvector.normalize();

            setPosition(getPosition() - strafevector * translateSpeed);
            setTarget(getTarget() - strafevector * translateSpeed);
            updateAbsolutePosition();
         }
         else if (MousePos.X > 0.95) //Down
         {
            vector3df totargetvector = getPosition() - getTarget();
            totargetvector.normalize();
            vector3df crossvector = totargetvector.crossProduct(getUpVector());
            vector3df strafevector = crossvector.normalize();

            setPosition(getPosition() + strafevector * translateSpeed);
            setTarget(getTarget() + strafevector * translateSpeed);
            updateAbsolutePosition();
         }
         else if (MousePos.Y < 0.05)   //Up
         {
            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
         {
            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, core::vector3df(0,0,0));
   UpVector.rotateXZBy(-nRotX+180.f, core::vector3df(0,0,0));
}

void RTSCamera::updateAnimationState()
{
   vector3df pos(Pos - Target);

   // X rotation
   vector2df vec2d(pos.X, pos.Z);
   rotX = (f32)vec2d.getAngle();

   // Y rotation
   pos.rotateXZBy(rotX, vector3df());
   vec2d.set(pos.X, pos.Y);
   rotY = -(f32)vec2d.getAngle();

   // Zoom
   currentZoom = (f32)Pos.getDistanceFrom(Target);
} 
random
Posts: 158
Joined: Wed Aug 11, 2010 6:01 am

Post by random »

first i would like to thank you for the script.

and i would like to mention 2 problems occured:

1) with the enumeration for the mousekeys the condition

Code: Select all

if(isMouseButtonDown(MOUSE_BUTTON_LEFT) && !zooming)
is true when the RIGHT mouse button is pressed!

the correct enumartion would be

Code: Select all

      enum MOUSE_BUTTON
      {
        MOUSE_BUTTON_LEFT,
        MOUSE_BUTTON_MIDDLE,
        MOUSE_BUTTON_RIGHT
      };
inside the header file.

without changings to the .cpp file

2) when a GUIElement is viewable and you move the mouse over the GUIElement while pressed the Left Mouse Button (or even the right one regarding the enumeration see point 1) the rotating will NOT stop when you release the mousebutton.

a hack for this is adding some lines here in the .cpp file:

Code: Select all

         case EMIE_MOUSE_MOVED:
            {
                //!mouse left up over gui element hack START
                if (event.MouseInput.isLeftPressed())
                    {
                        MouseKeys[0] = true;
                    }
                    else
                    {
                        MouseKeys[0] = false;
                    }
                    //!mouse left up over gui element hack END
               IVideoDriver* driver = SceneManager->getVideoDriver();
               if (driver)
               {
                  MousePos.X = event.MouseInput.X / (f32)ssize.Width;
                  MousePos.Y = event.MouseInput.Y / (f32)ssize.Height;
               }
            }
            break;
anyway, i like your script very much also if i changed a few things on it, and have to say thank you very much.
havok2063
Posts: 6
Joined: Tue Mar 15, 2011 12:56 am

edge-scrolling and collision detection

Post by havok2063 »

Does anyone know how to turn off the edge-scrolling for this camera? I can't seem to find the relative code that controls it.

Also, the collision detection with the camera isn't working right. Has anyone found a fix for this?

The collision detections works with the standard Maya or FPS camera so I know that part of the code is correct.
havok2063
Posts: 6
Joined: Tue Mar 15, 2011 12:56 am

Post by havok2063 »

I found the section of code in charge of edge-scrolling.

Still have no idea about the collision detection. Any ideas?
jfisher446
Posts: 11
Joined: Mon Mar 14, 2011 10:48 am

Post by jfisher446 »

Haven't had a chance to look at it much, but it may be helpful to others searching to post your edge scrolling findings and solution?

For anyone else wondering:
The following section of RTSCamera::animate() is responsible for edge scrolling, either remove this section or add a condition to allow it to be turned on and off.

Code: Select all

if (!translating && !zooming && !rotating) 
		{ 
			//Mouse Coordinates go from 0 to 1 on both axes 
			if (MousePos.X < 0.05)   //Up 
			{ 
				vector3df totargetvector = getPosition() - getTarget(); 
				totargetvector.normalize(); 
				vector3df crossvector = totargetvector.crossProduct(getUpVector()); 
				vector3df strafevector = crossvector.normalize(); 

				setPosition(getPosition() - strafevector * translateSpeed); 
				setTarget(getTarget() - strafevector * translateSpeed); 
				updateAbsolutePosition(); 
			} 
			else if (MousePos.X > 0.95) //Down 
			{ 
				vector3df totargetvector = getPosition() - getTarget(); 
				totargetvector.normalize(); 
				vector3df crossvector = totargetvector.crossProduct(getUpVector()); 
				vector3df strafevector = crossvector.normalize(); 

				setPosition(getPosition() + strafevector * translateSpeed); 
				setTarget(getTarget() + strafevector * translateSpeed); 
				updateAbsolutePosition(); 
			} 
			else if (MousePos.Y < 0.05)   //Up 
			{ 
				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 
			{ 
				vector3df movevector = getPosition() - getTarget(); 
				movevector.Y = 0; 
				movevector.normalize(); 

				setPosition(getPosition() + movevector * translateSpeed); 
				setTarget(getTarget() + movevector * translateSpeed); 
				updateAbsolutePosition(); 
			} 
		} 

EDIT: I've found another section of code to zoom w/both mouse buttons, on a trackpad so can't test, but follows is my code for zooming with the mouse wheel, as originally posted:
Also, while not collision detection for the camera. this performs a similiar function for me. Now either I couldn't figure it out (newbie) or the ability to limit the zoom between a min and a max is only partially integrated and non-functional. Modifying the onEvent for the mouse wheel as below will correct it. (being a newb, hope it's a correct way of doing it, but it works o.O)

Code: Select all

f32 newZoom = currentZoom; //must be placed at the beginning of the OnEvent (to keep it within range of default. Better way to do this?)

//Then modify this part a ways below in onEvent:
case EMIE_MOUSE_WHEEL: 
			newZoom -= event.MouseInput.Wheel * zoomSpeed; 
			if(newZoom > targetMinDistance && newZoom < targetMaxDistance)
			{
				currentZoom = newZoom;
			}
			else if (event.MouseInput.Wheel < 0) { //zooming out, default to farthest available
				currentZoom = targetMaxDistance;
			}
			else if (event.MouseInput.Wheel > 0) { //zooming in, default to closest available
				currentZoom = targetMinDistance;
			}
			break; 
		default: 
			break; 
		} 
havok2063
Posts: 6
Joined: Tue Mar 15, 2011 12:56 am

Post by havok2063 »

Thanks for posting the code. It totally slipped my mind before. Sorry about that.

I still haven't been able to fix the collision detection yet. I'll keep at it.
Mars_999
Posts: 136
Joined: Sat Dec 08, 2012 7:59 pm

Re: (C++) RTSCamera

Post by Mars_999 »

I see I am not the only one who has issues with this code and not being able to do collision detection with the camera and some object...

ANyone find a solution? I am wanting to keep the camera from leaving my aabb box around the terrain map...

HELP PLEASE!!!
Post Reply