why isn't my OnAnimate() being called ?
Posted: Thu Apr 12, 2007 2:31 pm
Hi !
I'm trying to write a FPS-like camera, with a few modifications (swim up and down, right-click transform the camera in a maya-like camera), but my OnAnimate() function isn't called...
I modified the code from source (CCameraSceneNode and CCameraFPSSceneNode), but I can't see where I'm wrong...
I'm showing the camera like this :
So if someone who knows better can take a look on the sources, I'll be grateful...
Thanks...
myCamera.h :
myCamera.cpp :
I'm trying to write a FPS-like camera, with a few modifications (swim up and down, right-click transform the camera in a maya-like camera), but my OnAnimate() function isn't called...
I modified the code from source (CCameraSceneNode and CCameraFPSSceneNode), but I can't see where I'm wrong...
I'm showing the camera like this :
Code: Select all
ICameraSceneNode* cam = new CMyCamera(0, smgr, device, -1, vector3df(0, 0, -300));
smgr->setActiveCamera(cam);
cam->drop();
Thanks...
myCamera.h :
Code: Select all
#ifndef MYCAMERA_INCLUDED
#define MYCAMERA_INCLUDED
#include <irrlicht.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")
#endif
class CMyCamera : public ICameraSceneNode
{
public:
CMyCamera(ISceneNode* parent, ISceneManager* mgr, IrrlichtDevice* device, s32 id,
const core::vector3df& position = core::vector3df(0,0,0),
const core::vector3df& lookat = core::vector3df(0,0,100));
virtual ~CMyCamera();
virtual bool OnEvent(SEvent event);
virtual void OnAnimate(u32 timeMs);
virtual void setProjectionMatrix(const core::matrix4& projection);
virtual const core::matrix4& getProjectionMatrix();
virtual const core::matrix4& getViewMatrix();
virtual void setTarget(const core::vector3df& pos);
virtual core::vector3df getTarget() const;
virtual void setUpVector(const core::vector3df& pos);
virtual core::vector3df getUpVector() const;
virtual f32 getNearValue();
virtual f32 getFarValue();
virtual f32 getAspectRatio();
virtual f32 getFOV();
virtual void setNearValue(f32 zn);
virtual void setFarValue(f32 zf);
virtual void setAspectRatio(f32 aspect);
virtual void setFOV(f32 fovy);
virtual void OnRegisterSceneNode();
virtual void render();
virtual const core::aabbox3d<f32>& getBoundingBox() const;
virtual const SViewFrustum* getViewFrustum() const;
virtual void setInputReceiverEnabled(bool enabled);
virtual bool isInputReceiverEnabled();
virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0);
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0);
virtual ESCENE_NODE_TYPE getType() { return ESNT_CAMERA; }
virtual core::vector3df getAbsolutePosition() const;
virtual void setRotateSpeed(const f32 speed);
virtual void setMoveSpeed(const f32 speed);
virtual f32 getRotateSpeed();
virtual f32 getMoveSpeed();
protected:
void animate(u32 timeMs);
void recalculateProjectionMatrix();
void recalculateViewArea();
IrrlichtDevice* pDevice;
gui::ICursorControl* CursorControl;
core::position2d<f32> CenterCursor;
bool Keys[8];
core::vector3df Target;
core::vector3df UpVector;
f32 Fovy;
f32 Aspect;
f32 ZNear;
f32 ZFar;
SViewFrustum ViewArea;
bool InputReceiverEnabled;
f32 MoveSpeed;
f32 RotateSpeed;
f32 AroundSpeed;
f32 ZoomSpeed;
bool firstUpdate;
s32 LastAnimationTime;
core::vector3df TargetVector;
};
#endif
Code: Select all
#include "stdafx.h"
#include "myCamera.h"
const f32 MAX_VERTICAL_ANGLE = 88.0f;
CMyCamera::CMyCamera(ISceneNode* parent, ISceneManager* mgr, IrrlichtDevice* device, s32 id, const core::vector3df& position, const core::vector3df& lookat)
: pDevice(device), UpVector(0.0f, 1.0f, 0.0f), Target(lookat), Fovy(core::PI / 2.5f), Aspect(4.0f / 3.0f), ZNear(1.0f), ZFar(3000.0f),
InputReceiverEnabled(true), MoveSpeed(200.0f), RotateSpeed(1500.0f), AroundSpeed(-1500.0f), ZoomSpeed(200.0f),
firstUpdate(true),
ICameraSceneNode(0, mgr, id, position, core::vector3df(0.0f, 0.0f, 0.0f), core::vector3df(1.0f, 1.0f, 1.0f))
{
video::IVideoDriver* d = mgr->getVideoDriver();
if (d)
Aspect = (f32)d->getCurrentRenderTargetSize().Width / (f32)d->getCurrentRenderTargetSize().Height;
if (pDevice)
{
CursorControl = pDevice->getCursorControl();
if (CursorControl)
CursorControl->grab();
}
MoveSpeed /= 1000.0f;
recalculateProjectionMatrix();
recalculateViewArea();
}
CMyCamera::~CMyCamera()
{
if (CursorControl)
CursorControl->drop();
}
bool CMyCamera::OnEvent(SEvent event)
{
if (InputReceiverEnabled)
{
if (event.EventType == EET_KEY_INPUT_EVENT)
switch (event.KeyInput.Key)
{
case irr::KEY_KEY_W :
Keys[0] = event.KeyInput.PressedDown;
return true;
case irr::KEY_KEY_S :
Keys[1] = event.KeyInput.PressedDown;
return true;
case irr::KEY_KEY_A :
Keys[2] = event.KeyInput.PressedDown;
return true;
case irr::KEY_KEY_D :
Keys[3] = event.KeyInput.PressedDown;
return true;
case irr::KEY_KEY_R :
Keys[4] = event.KeyInput.PressedDown;
return true;
case irr::KEY_KEY_F :
Keys[5] = event.KeyInput.PressedDown;
return true;
}
}
return false;
}
void CMyCamera::animate(u32 timeMs)
{
// camera activa ?
const u32 camIsMe = SceneManager->getActiveCamera() == this;
if (firstUpdate)
{
if (CursorControl && camIsMe)
{
CursorControl->setPosition(0.5f, 0.5f);
CenterCursor = CursorControl->getRelativePosition();
}
LastAnimationTime = pDevice->getTimer()->getTime();
firstUpdate = false;
}
// calculeaza diferenta de timp, doar pt. camera activa = curenta
f32 timeDiff = 0.f;
if (camIsMe)
{
timeDiff = (f32)(timeMs - LastAnimationTime);
LastAnimationTime = timeMs;
}
// update position
core::vector3df pos = getPosition();
// Update rotation
//if (InputReceiverEnabled)
{
Target.set(0,0,1);
if (CursorControl && InputReceiverEnabled && camIsMe)
{
core::position2d<f32> cursorpos = CursorControl->getRelativePosition();
if (!core::equals(cursorpos.X, CenterCursor.X) || !core::equals(cursorpos.Y, CenterCursor.Y))
{
RelativeRotation.X *= -1.0f;
RelativeRotation.Y *= -1.0f;
RelativeRotation.Y += (0.5f - cursorpos.X) * RotateSpeed;
RelativeRotation.X = core::clamp(RelativeRotation.X + (0.5f - cursorpos.Y) * RotateSpeed, -MAX_VERTICAL_ANGLE, +MAX_VERTICAL_ANGLE);
RelativeRotation.X *= -1.0f;
RelativeRotation.Y *= -1.0f;
CursorControl->setPosition(0.5f, 0.5f);
CenterCursor = CursorControl->getRelativePosition();
}
}
// set target
core::matrix4 mat;
mat.setRotationDegrees(core::vector3df(RelativeRotation.X, RelativeRotation.Y, 0));
mat.transformVect(Target);
core::vector3df movedir = Target;
movedir.normalize();
if (InputReceiverEnabled && camIsMe)
{
if (Keys[0])
pos += movedir * timeDiff * MoveSpeed;
if (Keys[1])
pos -= movedir * timeDiff * MoveSpeed;
core::vector3df strafevect = Target;
strafevect = strafevect.crossProduct(UpVector);
strafevect.normalize();
if (Keys[2])
pos += strafevect * timeDiff * MoveSpeed;
if (Keys[3])
pos -= strafevect * timeDiff * MoveSpeed;
}
setPosition(pos);
}
TargetVector = Target;
Target += pos;
}
void CMyCamera::OnAnimate(u32 timeMs)
{
animate(timeMs);
core::list<ISceneNodeAnimator*>::Iterator ait = Animators.begin();
for (; ait != Animators.end(); ait++)
(*ait)->animateNode(this, timeMs);
updateAbsolutePosition();
Target = getPosition() + TargetVector;
core::list<ISceneNode*>::Iterator it = Children.begin();
for (; it != Children.end(); it++)
(*it)->OnAnimate(timeMs);
}
void CMyCamera::setInputReceiverEnabled(bool enabled)
{
if(!InputReceiverEnabled && enabled)
firstUpdate = true;
InputReceiverEnabled = enabled;
}
bool CMyCamera::isInputReceiverEnabled()
{
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return InputReceiverEnabled;
}
void CMyCamera::setProjectionMatrix(const core::matrix4& projection)
{
ViewArea.Matrices[video::ETS_PROJECTION] = projection;
ViewArea.setTransformState(video::ETS_PROJECTION);
}
const core::matrix4& CMyCamera::getProjectionMatrix()
{
return ViewArea.Matrices[video::ETS_PROJECTION];
}
const core::matrix4& CMyCamera::getViewMatrix()
{
return ViewArea.Matrices[video::ETS_VIEW];
}
void CMyCamera::setTarget(const core::vector3df& pos)
{
updateAbsolutePosition();
core::vector3df vect = pos - getAbsolutePosition();
vect = vect.getHorizontalAngle();
RelativeRotation.X = vect.X;
RelativeRotation.Y = vect.Y;
if (RelativeRotation.X > MAX_VERTICAL_ANGLE)
RelativeRotation.X -= 360.0f;
}
core::vector3df CMyCamera::getTarget() const
{
return Target;
}
void CMyCamera::setUpVector(const core::vector3df& pos)
{
UpVector = pos;
}
core::vector3df CMyCamera::getUpVector() const
{
return UpVector;
}
f32 CMyCamera::getNearValue()
{
return ZNear;
}
f32 CMyCamera::getFarValue()
{
return ZFar;
}
f32 CMyCamera::getAspectRatio()
{
return Aspect;
}
f32 CMyCamera::getFOV()
{
return Fovy;
}
void CMyCamera::setNearValue(f32 f)
{
ZNear = f;
recalculateProjectionMatrix();
}
void CMyCamera::setFarValue(f32 f)
{
ZFar = f;
recalculateProjectionMatrix();
}
void CMyCamera::setAspectRatio(f32 f)
{
Aspect = f;
recalculateProjectionMatrix();
}
void CMyCamera::setFOV(f32 f)
{
Fovy = f;
recalculateProjectionMatrix();
}
void CMyCamera::recalculateProjectionMatrix()
{
ViewArea.Matrices[video::ETS_PROJECTION].buildProjectionMatrixPerspectiveFovLH(Fovy, Aspect, ZNear, ZFar);
ViewArea.setTransformState(video::ETS_PROJECTION);
}
void CMyCamera::OnRegisterSceneNode()
{
core::vector3df pos = getAbsolutePosition();
core::vector3df tgtv = Target - pos;
tgtv.normalize();
core::vector3df up = UpVector;
up.normalize();
f32 dp = tgtv.dotProduct(up);
if (core::equals(fabs(dp), 1.f))
{
up.X += 0.5f;
}
ViewArea.Matrices[video::ETS_VIEW].buildCameraLookAtMatrixLH(pos, Target, up);
ViewArea.setTransformState(video::ETS_VIEW);
recalculateViewArea();
if (SceneManager->getActiveCamera() == this)
SceneManager->registerNodeForRendering(this, ESNRP_CAMERA);
if (IsVisible)
ISceneNode::OnRegisterSceneNode();
}
void CMyCamera::render()
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
if (driver)
{
driver->setTransform(video::ETS_PROJECTION, ViewArea.Matrices[video::ETS_PROJECTION]);
driver->setTransform(video::ETS_VIEW, ViewArea.Matrices[video::ETS_VIEW]);
}
}
const core::aabbox3d<f32>& CMyCamera::getBoundingBox() const
{
return ViewArea.getBoundingBox();
}
const SViewFrustum* CMyCamera::getViewFrustum() const
{
return &ViewArea;
}
core::vector3df CMyCamera::getAbsolutePosition() const
{
return AbsoluteTransformation.getTranslation();
}
void CMyCamera::recalculateViewArea()
{
ViewArea.cameraPosition = getAbsolutePosition();
ViewArea.setFrom ( ViewArea.Matrices [ SViewFrustum::ETS_VIEW_PROJECTION_3 ] );
/*
video::IVideoDriver* driver = SceneManager->getVideoDriver();
if ( driver)
{
driver->setTransform(video::ETS_PROJECTION, ViewArea.Matrices [ video::ETS_PROJECTION ] );
driver->setTransform(video::ETS_VIEW, ViewArea.Matrices [ video::ETS_VIEW ] );
}
*/
}
void CMyCamera::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options)
{
ISceneNode::serializeAttributes(out, options);
out->addVector3d("Target", Target);
out->addVector3d("UpVector", UpVector);
out->addFloat("Fovy", Fovy);
out->addFloat("Aspect", Aspect);
out->addFloat("ZNear", ZNear);
out->addFloat("ZFar", ZFar);
}
void CMyCamera::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
{
ISceneNode::deserializeAttributes(in, options);
Target = in->getAttributeAsVector3d("Target");
UpVector = in->getAttributeAsVector3d("UpVector");
Fovy = in->getAttributeAsFloat("Fovy");
Aspect = in->getAttributeAsFloat("Aspect");
ZNear = in->getAttributeAsFloat("ZNear");
ZFar = in->getAttributeAsFloat("ZFar");
recalculateProjectionMatrix();
recalculateViewArea();
}
void CMyCamera::setRotateSpeed(const f32 speed)
{
RotateSpeed = speed;
}
void CMyCamera::setMoveSpeed(const f32 speed)
{
MoveSpeed = speed;
}
f32 CMyCamera::getRotateSpeed()
{
return RotateSpeed;
}
f32 CMyCamera::getMoveSpeed()
{
return MoveSpeed;
}
Code: Select all