It actually supports some low level physics by calculating the movement speed from
some Acceleration / Attenuation values.
Here is the code:
JoystickCameraAnimator.h
Code: Select all
#ifndef __JOYSTICKCAMERAANIMATOR_H__
#define __JOYSTICKCAMERAANIMATOR_H__
#include <irrlicht.h>
class JoystickCameraAnimator : public irr::scene::ISceneNodeAnimator
{
static const irr::u32 BrakeButton = 6;
irr::u32 LastAnimationTime;
irr::core::vector3df rotation;
irr::f32 Acceleration, Velocity, Brake;
irr::f32 MaxRoll, MaxPitch, MaxAcceleration, Attenuation, MaxBrake;
public:
JoystickCameraAnimator(irr::f32 maxRoll, irr::f32 maxPitch, irr::f32 maxAcceleration,
irr::f32 attenuation, irr::f32 brake)
:
Velocity(0), MaxRoll(maxRoll), MaxPitch(maxPitch), MaxAcceleration(maxAcceleration),
Attenuation(attenuation), MaxBrake(brake)
{}
virtual ~JoystickCameraAnimator() {}
virtual irr::scene::ISceneNodeAnimator* createClone(irr::scene::ISceneNode*, irr::scene::ISceneManager*)
{
return new JoystickCameraAnimator(MaxRoll, MaxPitch, MaxAcceleration, Attenuation, MaxBrake);
}
virtual bool isEventReceiverEnabled() const
{
return true;
}
virtual bool OnEvent(const irr::SEvent&);
virtual void animateNode(irr::scene::ISceneNode*, irr::u32);
};
#endif /*__JOYSTICKCAMERAANIMATOR_H__*/Code: Select all
#include "JoystickCameraAnimator.h"
using namespace irr;
bool JoystickCameraAnimator::OnEvent(const SEvent &event)
{
if (event.EventType == irr::EET_JOYSTICK_INPUT_EVENT)
{
rotation.X = (f32) event.JoystickEvent.Axis[1] / 32768 * MaxPitch * -1;
rotation.Z = (f32) event.JoystickEvent.Axis[0] / 32768 * MaxRoll * -1;
Acceleration = (f32) (event.JoystickEvent.Axis[2] - 32768) / 65536 * -1;
if (Acceleration < 0.0001) Acceleration = 0;
Acceleration *= MaxAcceleration;
if (event.JoystickEvent.IsButtonPressed(BrakeButton))
Brake = MaxBrake;
else
Brake = 0;
return true;
}
else return false;
}
void JoystickCameraAnimator::animateNode(scene::ISceneNode *node, u32 time)
{
if (node->getType() != scene::ESNT_CAMERA) return;
scene::ICameraSceneNode* camera = static_cast< scene::ICameraSceneNode* >(node);
f32 timeDiff = (f32) ( time - LastAnimationTime );
LastAnimationTime = time;
rotation *= timeDiff;
core::matrix4 m, n;
m.setRotationDegrees(camera->getRotation());
n.setRotationDegrees(rotation);
m *= n;
camera->setRotation(m.getRotationDegrees());
Velocity += (Acceleration - Velocity * Velocity * Attenuation - Brake) * timeDiff;
if (Velocity < 0.01) Velocity = 0;
core::vector3df distance(0.0f, 0.0f, Velocity);
m.transformVect(distance);
camera->setPosition(camera->getPosition() + distance);
core::vector3df upvector(0.0f, 1.0f, 0.0f);
m.transformVect(upvector);
camera->setUpVector(upvector);
core::vector3df forward(0.0f, 0.0f, 1.0f);
m.transformVect(forward);
camera->setTarget(camera->getPosition() + forward);
camera->updateAbsolutePosition();
}Code: Select all
scene::ICameraSceneNode* camera = smgr->addCameraSceneNode();
scene::ISceneNodeAnimator* anm = new JoystickCameraAnimator(0.2, 0.1, 0.02, 0.0005, 0.01);
smgr->setActiveCamera(camera);
camera->addAnimator(anm);
anm->drop();