Maybe Someone *hint to Niko* could add it to the REAL CollisionResponceAnimator .
Anyway, most of it is Copied from the Current version of CollisionResponseAnimator... so alot of code isn't linked to jumping.
CJumpingAnimator.h
Code: Select all
#ifndef __C_SCENE_NODE_ANIMATOR_JUMPING_COLLISION_RESPONSE_H_INCLUDED__
#define __C_SCENE_NODE_ANIMATOR_JUMPING_COLLISION_RESPONSE_H_INCLUDED__
#include "ISceneNodeAnimatorCollisionResponse.h"
#include "ITimer.h"
namespace irr
{
namespace scene
{
//Basically CSceneNodeAnimatorCollisionResponse but with Jumping...
class CSceneNodeAnimatorJumpingCollisionResponse : public ISceneNodeAnimatorCollisionResponse
{
public:
//! constructor
CSceneNodeAnimatorJumpingCollisionResponse(ISceneManager* scenemanager,
ITriangleSelector* world, ISceneNode* object,
const core::vector3df& ellipsoidRadius = core::vector3df(30,60,30),
const core::vector3df& gravityPerSecond = core::vector3df(0,-100.0f,0),
const core::vector3df& ellipsoidTranslation = core::vector3df(0,0,0),
f32 slidingSpeed = 0.0005f, ITimer* Timer = 0);
//! destructor
virtual ~CSceneNodeAnimatorJumpingCollisionResponse();
//! Returns if the attached scene node is falling, which means that
//! there is no blocking wall from the scene node in the direction of
//! the gravity.
virtual bool isFalling();
//! Sets the radius of the ellipsoid with which collision detection and
//! response is done.
virtual void setEllipsoidRadius(const core::vector3df& radius);
//! Returns the radius of the ellipsoid with wich the collision detection and
//! response is done.
virtual core::vector3df getEllipsoidRadius() const;
//! Sets the gravity of the environment.
virtual void setGravity(const core::vector3df& gravity);
//! Returns current vector of gravity.
virtual core::vector3df getGravity() const;
//! Sets the translation of the ellipsoid for collision detection.
virtual void setEllipsoidTranslation(core::vector3df translation);
//! Returns the translation of the ellipsoid for collision detection.
virtual core::vector3df getEllipsoidTranslation() const;
//! Sets a triangle selector holding all triangles of the world with which
//! the scene node may collide.
virtual void setWorld(ITriangleSelector* newWorld);
//! Returns the current triangle selector containing all triangles for
//! collision detection.
virtual ITriangleSelector* getWorld() const;
//! animates a scene node
virtual void animateNode(ISceneNode* node, u32 timeMs);
//! My code... for jumping:
virtual void jump(const core::vector3df& force, const core::vector3df& change);
private:
core::vector3df LastPosition;
core::vector3df Radius;
core::vector3df CurrGravity;
core::vector3df Change;
core::vector3df Gravity;
core::vector3df Translation;
ITriangleSelector* World;
ISceneNode* Object;
ISceneManager* SceneManager;
ITimer* Timer;
u32 LastTime;
u32 FallStartTime;
u32 LastGTime;
f32 SlidingSpeed;
bool Falling;
core::triangle3df RefTriangle;
};
} // end namespace scene
} // end namespace irr
#endif
Code: Select all
#include "CJumpingAnimator.h"
#include "ISceneCollisionManager.h"
#include "ISceneManager.h"
namespace irr
{
namespace scene
{
//! constructor
CSceneNodeAnimatorJumpingCollisionResponse::CSceneNodeAnimatorJumpingCollisionResponse(
ISceneManager* scenemanager,
ITriangleSelector* world, ISceneNode* object,
const core::vector3df& ellipsoidRadius,
const core::vector3df& gravityPerSecond,
const core::vector3df& ellipsoidTranslation,
f32 slidingSpeed, ITimer* Timer)
: SceneManager(scenemanager), World(world), Object(object),
Radius(ellipsoidRadius), Gravity(gravityPerSecond / 1000.0f), CurrGravity(gravityPerSecond / 1000.0f),
SlidingSpeed(slidingSpeed), Translation(ellipsoidTranslation)
{
if (World)
World->grab();
if (Object)
LastPosition = Object->getPosition();
Falling = false;
LastTime = Timer->getTime();
FallStartTime = LastTime;
RefTriangle.pointA.set(0.0f, 0.0f, 0.0f);
RefTriangle.pointB.set(0.0f, 0.0f, 0.0f);
RefTriangle.pointC.set(0.0f, 0.0f, 0.0f);
}
//! destructor
CSceneNodeAnimatorJumpingCollisionResponse::~CSceneNodeAnimatorJumpingCollisionResponse()
{
if (World)
World->drop();
}
//! Returns if the attached scene node is falling, which means that
//! there is no blocking wall from the scene node in the direction of
//! the gravity.
bool CSceneNodeAnimatorJumpingCollisionResponse::isFalling()
{
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return Falling;
}
//! Sets the radius of the ellipsoid with which collision detection and
//! response is done.
void CSceneNodeAnimatorJumpingCollisionResponse::setEllipsoidRadius(
const core::vector3df& radius)
{
Radius = radius;
}
//! Returns the radius of the ellipsoid with wich the collision detection and
//! response is done.
core::vector3df CSceneNodeAnimatorJumpingCollisionResponse::getEllipsoidRadius() const
{
return Radius;
}
//! Sets the gravity of the environment.
void CSceneNodeAnimatorJumpingCollisionResponse::setGravity(const core::vector3df& gravity)
{
Gravity = gravity;
}
//! Returns current vector of gravity.
core::vector3df CSceneNodeAnimatorJumpingCollisionResponse::getGravity() const
{
return Gravity;
}
//! Sets the translation of the ellipsoid for collision detection.
void CSceneNodeAnimatorJumpingCollisionResponse::setEllipsoidTranslation(core::vector3df translation)
{
Translation = translation;
}
//! Returns the translation of the ellipsoid for collision detection.
core::vector3df CSceneNodeAnimatorJumpingCollisionResponse::getEllipsoidTranslation() const
{
return Translation;
}
//! Sets a triangle selector holding all triangles of the world with which
//! the scene node may collide.
void CSceneNodeAnimatorJumpingCollisionResponse::setWorld(ITriangleSelector* newWorld)
{
if (World)
World->drop();
World = newWorld;
if (World)
World->grab();
}
//! Returns the current triangle selector containing all triangles for
//! collision detection.
ITriangleSelector* CSceneNodeAnimatorJumpingCollisionResponse::getWorld() const
{
return World;
}
//! animates a scene node
void CSceneNodeAnimatorJumpingCollisionResponse::animateNode(ISceneNode* node, u32 timeMs)
{
if (node != Object)
{
return;
}
if (!World)
return;
u32 diff = timeMs - LastTime;
LastTime = timeMs;
LastGTime = timeMs;
if(CurrGravity != Gravity)
{
if(CurrGravity.Y > Gravity.Y)
{
CurrGravity.Y += Change.Y;// * (f32)diff;
}
if(CurrGravity.Y < Gravity.Y)CurrGravity = Gravity;
}
core::vector3df pos = Object->getPosition();
core::vector3df vel = pos - LastPosition;
core::vector3df g = CurrGravity;// * (f32)diff;
if (Falling)
g = CurrGravity * (f32)((timeMs - FallStartTime) * diff);
core::triangle3df triangle = RefTriangle;
if (vel+g != core::vector3df(0,0,0))
{
// TODO: divide SlidingSpeed by frame time
bool f = false;
pos = SceneManager->getSceneCollisionManager()->getCollisionResultPosition(
World, LastPosition-Translation,
Radius, vel, triangle, f, SlidingSpeed, g);
pos += Translation;
if (f)//triangle == RefTriangle)
{
if (!Falling)
FallStartTime = timeMs;
Falling = true;
}
else
Falling = false;
Object->setPosition(pos);
}
LastPosition = Object->getPosition();
}
//This is where I start:
void CSceneNodeAnimatorJumpingCollisionResponse::jump(const core::vector3df& force, const core::vector3df& change)
{
CurrGravity = force / 1000.0f;
Change = change / 1000.0f;
}
} // end namespace scene
} // end namespace irr
Code: Select all
if(GameReceiver.getKeyState(KEY_SPACE) && !g_PhysicsAnim->isFalling())
{
g_PhysicsAnim->jump(vector3df(0,20,0),vector3df(0,-0.5,0));
}