RTS Camera
RTS Camera
Hi,
I have found a great rtc camera, by Cmd Kewin.
Unfortunatly, it doesn't work with irrlicht 1.5
Whatever I change in the code, I keep getting errors like 'cannot initiate abstract class due to the following members' and then a whole list.
I use visual studio 2008
http://www.irrlicht3d.org/wiki/index.ph ... ByCmdKewin
Any ideas?
-- The output from VS
>------ Build started: Project: Trinity, Configuration: Debug Win32 ------
1>Compiling...
1>game.cpp
1>c:\trinity\trinity\game.cpp(29) : error C2259: 'RTSCamera' : cannot instantiate abstract class
1> due to following members:
1> 'void irr::scene::ICameraSceneNode::setRotation(const irr::core::vector3df &)' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(77) : see declaration of 'irr::scene::ICameraSceneNode::setRotation'
1> 'void irr::scene::ICameraSceneNode::setProjectionMatrix(const irr::core::matrix4 &,bool)' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(45) : see declaration of 'irr::scene::ICameraSceneNode::setProjectionMatrix'
1> 'const irr::core::matrix4 &irr::scene::ICameraSceneNode::getProjectionMatrix(void) const' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(49) : see declaration of 'irr::scene::ICameraSceneNode::getProjectionMatrix'
1> 'const irr::core::matrix4 &irr::scene::ICameraSceneNode::getViewMatrix(void) const' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(53) : see declaration of 'irr::scene::ICameraSceneNode::getViewMatrix'
1> 'const irr::core::vector3df &irr::scene::ICameraSceneNode::getTarget(void) const' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(81) : see declaration of 'irr::scene::ICameraSceneNode::getTarget'
1> 'const irr::core::vector3df &irr::scene::ICameraSceneNode::getUpVector(void) const' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(89) : see declaration of 'irr::scene::ICameraSceneNode::getUpVector'
1> 'irr::f32 irr::scene::ICameraSceneNode::getNearValue(void) const' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(93) : see declaration of 'irr::scene::ICameraSceneNode::getNearValue'
1> 'irr::f32 irr::scene::ICameraSceneNode::getFarValue(void) const' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(97) : see declaration of 'irr::scene::ICameraSceneNode::getFarValue'
1> 'irr::f32 irr::scene::ICameraSceneNode::getAspectRatio(void) const' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(101) : see declaration of 'irr::scene::ICameraSceneNode::getAspectRatio'
1> 'irr::f32 irr::scene::ICameraSceneNode::getFOV(void) const' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(105) : see declaration of 'irr::scene::ICameraSceneNode::getFOV'
1> 'const irr::scene::SViewFrustum *irr::scene::ICameraSceneNode::getViewFrustum(void) const' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(126) : see declaration of 'irr::scene::ICameraSceneNode::getViewFrustum'
1> 'bool irr::scene::ICameraSceneNode::isInputReceiverEnabled(void) const' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(134) : see declaration of 'irr::scene::ICameraSceneNode::isInputReceiverEnabled'
1> 'void irr::scene::ICameraSceneNode::bindTargetAndRotation(bool)' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(152) : see declaration of 'irr::scene::ICameraSceneNode::bindTargetAndRotation'
1> 'bool irr::scene::ICameraSceneNode::getTargetAndRotationBinding(void) const' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(156) : see declaration of 'irr::scene::ICameraSceneNode::getTargetAndRotationBinding'
1> 'bool irr::scene::ICameraSceneNode::OnEvent(const irr::SEvent &)' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(62) : see declaration of 'irr::scene::ICameraSceneNode::OnEvent'
1>c:\rellion soft\trinity\trinity\game.cpp(48) : warning C4018: '>=' : signed/unsigned mismatch
1>RTSCamera.cpp
1>c:\rellion soft\trinity\trinity\rtscamera.cpp(146) : error C2039: 'OnPreRender' : is not a member of 'irr::scene::ISceneNode'
1> c:\library\irrlicht1.5\include\iscenenode.h(35) : see declaration of 'irr::scene::ISceneNode'
1>Generating Code...
1>Build Time 0:00
1>Build log was saved at "file://c:\Trinity\Trinity\Debug\BuildLog.htm"
1>Trinity - 2 error(s), 1 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I have found a great rtc camera, by Cmd Kewin.
Unfortunatly, it doesn't work with irrlicht 1.5
Whatever I change in the code, I keep getting errors like 'cannot initiate abstract class due to the following members' and then a whole list.
I use visual studio 2008
http://www.irrlicht3d.org/wiki/index.ph ... ByCmdKewin
Any ideas?
-- The output from VS
>------ Build started: Project: Trinity, Configuration: Debug Win32 ------
1>Compiling...
1>game.cpp
1>c:\trinity\trinity\game.cpp(29) : error C2259: 'RTSCamera' : cannot instantiate abstract class
1> due to following members:
1> 'void irr::scene::ICameraSceneNode::setRotation(const irr::core::vector3df &)' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(77) : see declaration of 'irr::scene::ICameraSceneNode::setRotation'
1> 'void irr::scene::ICameraSceneNode::setProjectionMatrix(const irr::core::matrix4 &,bool)' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(45) : see declaration of 'irr::scene::ICameraSceneNode::setProjectionMatrix'
1> 'const irr::core::matrix4 &irr::scene::ICameraSceneNode::getProjectionMatrix(void) const' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(49) : see declaration of 'irr::scene::ICameraSceneNode::getProjectionMatrix'
1> 'const irr::core::matrix4 &irr::scene::ICameraSceneNode::getViewMatrix(void) const' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(53) : see declaration of 'irr::scene::ICameraSceneNode::getViewMatrix'
1> 'const irr::core::vector3df &irr::scene::ICameraSceneNode::getTarget(void) const' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(81) : see declaration of 'irr::scene::ICameraSceneNode::getTarget'
1> 'const irr::core::vector3df &irr::scene::ICameraSceneNode::getUpVector(void) const' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(89) : see declaration of 'irr::scene::ICameraSceneNode::getUpVector'
1> 'irr::f32 irr::scene::ICameraSceneNode::getNearValue(void) const' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(93) : see declaration of 'irr::scene::ICameraSceneNode::getNearValue'
1> 'irr::f32 irr::scene::ICameraSceneNode::getFarValue(void) const' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(97) : see declaration of 'irr::scene::ICameraSceneNode::getFarValue'
1> 'irr::f32 irr::scene::ICameraSceneNode::getAspectRatio(void) const' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(101) : see declaration of 'irr::scene::ICameraSceneNode::getAspectRatio'
1> 'irr::f32 irr::scene::ICameraSceneNode::getFOV(void) const' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(105) : see declaration of 'irr::scene::ICameraSceneNode::getFOV'
1> 'const irr::scene::SViewFrustum *irr::scene::ICameraSceneNode::getViewFrustum(void) const' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(126) : see declaration of 'irr::scene::ICameraSceneNode::getViewFrustum'
1> 'bool irr::scene::ICameraSceneNode::isInputReceiverEnabled(void) const' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(134) : see declaration of 'irr::scene::ICameraSceneNode::isInputReceiverEnabled'
1> 'void irr::scene::ICameraSceneNode::bindTargetAndRotation(bool)' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(152) : see declaration of 'irr::scene::ICameraSceneNode::bindTargetAndRotation'
1> 'bool irr::scene::ICameraSceneNode::getTargetAndRotationBinding(void) const' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(156) : see declaration of 'irr::scene::ICameraSceneNode::getTargetAndRotationBinding'
1> 'bool irr::scene::ICameraSceneNode::OnEvent(const irr::SEvent &)' : is abstract
1> c:\library\irrlicht1.5\include\icamerascenenode.h(62) : see declaration of 'irr::scene::ICameraSceneNode::OnEvent'
1>c:\rellion soft\trinity\trinity\game.cpp(48) : warning C4018: '>=' : signed/unsigned mismatch
1>RTSCamera.cpp
1>c:\rellion soft\trinity\trinity\rtscamera.cpp(146) : error C2039: 'OnPreRender' : is not a member of 'irr::scene::ISceneNode'
1> c:\library\irrlicht1.5\include\iscenenode.h(35) : see declaration of 'irr::scene::ISceneNode'
1>Generating Code...
1>Build Time 0:00
1>Build log was saved at "file://c:\Trinity\Trinity\Debug\BuildLog.htm"
1>Trinity - 2 error(s), 1 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Last edited by kevin[be] on Sun Jun 07, 2009 7:36 pm, edited 2 times in total.
-
- Competition winner
- Posts: 1123
- Joined: Sun Jun 10, 2007 11:14 pm
-
- Admin
- Posts: 14143
- Joined: Wed Apr 19, 2006 9:20 pm
- Location: Oldenburg(Oldb), Germany
- Contact:
No, an empty function would beMidnight wrote:he means thisnetkoji wrote:(I suspect that defining empty functions would help just fine).
object() = 0;
Code: Select all
func() {}
-
- Posts: 219
- Joined: Fri Feb 19, 2010 4:03 pm
- Location: Estonia
Hi,
I'm trying to make the same camera code work with Irrlicht 1.7 and getting same errors for the 5 missing functions. I have defined empty functions for them in the form:
virtual void bindTargetAndRotation( bool bound) {};
virtual void setRotation( const core::vector3df & rotation) {};
virtual void setViewMatrixAffector( const core::matrix4 & affector ) {};
virtual bool getTargetAndRotationBinding(void) const {};
virtual const core::matrix4& getViewMatrixAffector() const {};
The problem is, for the first three which are void it works fine, for the last 2 it gives me error:
1>c:\documents and settings\...\...\visual studio 2008\projects\rtscamera\rtscamera\rtscamera.h(44) : error C4716: 'RTSCamera::getTargetAndRotationBinding' : must return a value
1>c:\documents and settings\...\...\visual studio 2008\projects\rtscamera\rtscamera\rtscamera.h(45) : error C4716: 'RTSCamera::getViewMatrixAffector' : must return a value
Can someone please help me out here?
Many thanks!
/regards
I'm trying to make the same camera code work with Irrlicht 1.7 and getting same errors for the 5 missing functions. I have defined empty functions for them in the form:
virtual void bindTargetAndRotation( bool bound) {};
virtual void setRotation( const core::vector3df & rotation) {};
virtual void setViewMatrixAffector( const core::matrix4 & affector ) {};
virtual bool getTargetAndRotationBinding(void) const {};
virtual const core::matrix4& getViewMatrixAffector() const {};
The problem is, for the first three which are void it works fine, for the last 2 it gives me error:
1>c:\documents and settings\...\...\visual studio 2008\projects\rtscamera\rtscamera\rtscamera.h(44) : error C4716: 'RTSCamera::getTargetAndRotationBinding' : must return a value
1>c:\documents and settings\...\...\visual studio 2008\projects\rtscamera\rtscamera\rtscamera.h(45) : error C4716: 'RTSCamera::getViewMatrixAffector' : must return a value
Can someone please help me out here?
Many thanks!
/regards
-
- Admin
- Posts: 14143
- Joined: Wed Apr 19, 2006 9:20 pm
- Location: Oldenburg(Oldb), Germany
- Contact:
You shouldn't derive from ICamera, but use a camera animator instead. That will avoid most of these problems. But it also requires lots of refactoring in this case.
The errors simply tell you that the functions require something to return. Since your function implementations won't do anything useful anyway, just return false in the first case and core::IdtentityMatrix in the second.
The errors simply tell you that the functions require something to return. Since your function implementations won't do anything useful anyway, just return false in the first case and core::IdtentityMatrix in the second.
-
- Posts: 219
- Joined: Fri Feb 19, 2010 4:03 pm
- Location: Estonia
Thanks hybrid, I got it working to my satisfaction with Irrlicht 1.7 though had to make a few changes here and there.
What I cant figure out is why colllision detection is not working on it?? If I change the camera to FPS the collison works perfectly, hence, the problem lies somewhere within the RTS class. Any ideas??
Here follows the complete code for anyone who may wish to use it with Irrlicht 1.7:
rtscamera.h
rtscamera.cpp
and here is how I'm using it:
main.cpp
cheers!
What I cant figure out is why colllision detection is not working on it?? If I change the camera to FPS the collison works perfectly, hence, the problem lies somewhere within the RTS class. Any ideas??
Here follows the complete code for anyone who may wish to use it with Irrlicht 1.7:
rtscamera.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 irr::core::IdentityMatrix;};
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
rtscamera.cpp
Code: Select all
#include "rtscamera.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);
}
and here is how I'm using it:
main.cpp
Code: Select all
#include <irrlicht.h>
#include <iostream>
#include "rtscamera.h"
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif
// event reciever
class MyEventReceiver : public IEventReceiver
{
public:
// This is the one method that we have to implement
virtual bool OnEvent(const SEvent& event)
{
// Remember whether each key is down or up
if (event.EventType == irr::EET_KEY_INPUT_EVENT)
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
// This is used to check whether a key is being held down
virtual bool IsKeyDown(EKEY_CODE keyCode) const
{
return KeyIsDown[keyCode];
}
MyEventReceiver()
{
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
KeyIsDown[i] = false;
}
private:
// We use this array to store the current state of each key
bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
int main()
{
// create device
MyEventReceiver receiver;
IrrlichtDevice* device = createDevice(EDT_OPENGL,
dimension2d<u32>(1024, 768), 16, false, false, false, &receiver);
if (device == 0)
return 1; // could not create selected driver.
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
//Make the background
device->getFileSystem()->addZipFileArchive("map-20kdm2.pk3");
scene::IAnimatedMesh* mesh = smgr->getMesh("20kdm2.bsp");
scene::ISceneNode* bg = smgr->addOctreeSceneNode(mesh->getMesh(0));
bg->setPosition(core::vector3df(-1300,-144,-1249));
//Triangle Selecty-ness on the background
scene::ITriangleSelector* selector = 0;
selector = smgr->createOctreeTriangleSelector(mesh->getMesh(0), bg, 128);
bg->setTriangleSelector(selector);
selector->drop();
//add RTS Camera
RTSCamera* camera = new RTSCamera(device,smgr->getRootSceneNode(),smgr,-1,100.0f,10.0f,10.0f);
//ICameraSceneNode *camera= smgr->addCameraSceneNodeFPS(0, 50.0f,0.2f,-1,0,0,true,0.0f,false,true);
camera->setPosition(vector3df(0,9,-14));
camera->setTranslateSpeed(5);//speed of cam movement
camera->setRotationSpeed(50);//speed of cam rotation
//Set collision for camera
scene::ISceneNodeAnimator *collision = smgr->createCollisionResponseAnimator(
selector,camera,core::vector3df(20,40,20),
core::vector3df(0,-2,0),
core::vector3df(0,0,0),
0.0f);
camera->addAnimator(collision);
collision->drop();
int lastFPS = -1;
while(device->run())
{
if (device->isWindowActive())
{
//eventReceiver.endEventProcess();
driver->beginScene(true, true, video::SColor(255,200,200,200));
smgr->drawAll();
driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps)
{
core::stringw str = L"Irrlicht Engine - Quake 3 Map example [";
str += driver->getName();
str += "] FPS:";
str += fps;
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
//eventReceiver.startEventProcess();
}
else
device->yield();
}
/*
In the end, delete the Irrlicht device.
*/
device->drop();
return 0;
}
cheers!
to live, is natural; to die, is not!
-
- Posts: 219
- Joined: Fri Feb 19, 2010 4:03 pm
- Location: Estonia
hybrid wrote:You shouldn't derive from ICamera, but use a camera animator instead.
ok, if all I want is to have a simple camera which moves forwards/backwards with up/down keys and rotates with left/right keys, what would be the best and easiest way of doing it? Do I still need a camera animator for achieving this?
/regards
to live, is natural; to die, is not!
I added the rtscamera.cpp to my project but when I compile my main.cpp I get an error on line 134:
if ( core::equals ( fabs ( dp ), 1.f ) )
No idea why I can't get this to work...
if ( core::equals ( fabs ( dp ), 1.f ) )
No idea why I can't get this to work...
Last edited by Jumach on Thu Mar 18, 2010 7:50 am, edited 1 time in total.
-
- Posts: 219
- Joined: Fri Feb 19, 2010 4:03 pm
- Location: Estonia
Jumach wrote:I get an error on line 93 :RTSCamera* camera = new RTSCamera(device,smgr->getRootSceneNode(),smgr,-1,100.0f,10.0f,10.0f);
The error says it is an undefined reference...Did I put the rtscamera.h file in the wrong place? Why am I getting this error?
Yes, this could mean it's not finding the rtscamera.h file. Which OS you're using? which IDE? would be easier to tell if you post the actual error (just copy/paste)
to live, is natural; to die, is not!