CHavokPhysicsAnimator.h
Code: Select all
#ifndef HAVOK_ANIMATOR_H
#define HAVOK_ANIMATOR_H
//Havok includes.
//===========================================================
#include <Common/Base/hkBase.h>
#include <Common/Base/System/hkBaseSystem.h>
#include <Common/Base/System/Error/hkDefaultError.h>
#include <Common/Base/Memory/System/Util/hkMemoryInitUtil.h>
#include <Common/Base/Monitor/hkMonitorStream.h>
#include <Common/Base/Memory/System/hkMemorySystem.h>
// Dynamics includes
#include <Physics/Collide/hkpCollide.h>
#include <Physics/Collide/Agent/ConvexAgent/SphereBox/hkpSphereBoxAgent.h>
#include <Physics/Collide/Shape/Convex/Box/hkpBoxShape.h>
#include <Physics/Collide/Shape/Convex/Sphere/hkpSphereShape.h>
#include <Physics/Collide/Shape/Compound/Collection/ExtendedMeshShape/hkpExtendedMeshShape.h>
#include <Physics/Collide/Dispatch/hkpAgentRegisterUtil.h>
#include <Physics/Collide/Query/CastUtil/hkpWorldRayCastInput.h>
#include <Physics/Collide/Query/CastUtil/hkpWorldRayCastOutput.h>
#include <Physics/Dynamics/World/hkpWorld.h>
#include <Physics/Dynamics/Entity/hkpRigidBody.h>
#include <Physics/Utilities/Dynamics/Inertia/hkpInertiaTensorComputer.h>
#include <Common/Base/Thread/Job/ThreadPool/Cpu/hkCpuJobThreadPool.h>
#include <Common/Base/Thread/Job/ThreadPool/Spu/hkSpuJobThreadPool.h>
#include <Common/Base/Thread/JobQueue/hkJobQueue.h>
//===========================================================
#include <Irrlicht.h>
using namespace irr;
using namespace scene;
using namespace core;
//===========================================================================
//Conversion helper functions.
//===========================================================================
//Vector conversion helper functions.
hkVector4 convertVectors(core::vector3df& IrrlichtVector);
core::vector3df convertVectors(hkVector4 &HavokVector);
//Quaternion conversion functions.
core::quaternion convertQuaternions(hkQuaternion& HavokRotation);
hkQuaternion convertQuaternions(core::quaternion& IrrlichtRotation);
hkQuaternion convertToQuaternion(core::vector3df& eulerAngles);
//Mesh conversion.
//MUST have only one meshbuffer.
//hkpConvexShape* convertMeshToConvexHull(scene::IMesh* IrrlichtMesh);//TO BE IMPLEMENTED LATER.
hkpExtendedMeshShape* convertMeshes(scene::IMesh* IrrlichtMesh, irr::core::vector3df scale);
//===========================================================================
//Havok animator
//===========================================================================
class CHavokPhysicsAnimator : public ISceneNodeAnimator
{
public:
//Many different constructors.
CHavokPhysicsAnimator(hkpWorld* world, hkpRigidBodyCinfo* rigidBodyInfo, scene::ISceneNode* node );
CHavokPhysicsAnimator(hkpWorld* world, IMesh* mesh, int mass, scene::ISceneNode* node );
CHavokPhysicsAnimator(hkpWorld* world, hkpShape* shape, int mass, scene::ISceneNode* node );
~CHavokPhysicsAnimator();
//Returns the rigid body object.
hkpRigidBody* getRigidBody(){return m_rigidBody;};
//Updates the positions of the objects.
void animateNode(scene::ISceneNode* node, u32 timeMs);
//Returns the type of scene node animator.
scene::ESCENE_NODE_ANIMATOR_TYPE getType() const;
//Sets whether to update rotations or not.
void setRotationUpdate(bool updateRotations){m_rotationUpdate = updateRotations;};
virtual ISceneNodeAnimator* createClone(ISceneNode *node, ISceneManager *newManager=0){return 0;};
private:
//This animators rigid body.
hkpRigidBody* m_rigidBody;
//Physics world
hkpWorld* m_world;
//Mass
int m_mass;
//Rotation update: defaults to true.
bool m_rotationUpdate;
};
#endif//HAVOK_ANIMATOR_H
Code: Select all
#include "../include/CHavokPhysicsAnimator.h"
const int ESNAT_HAVOK_PHYSICS = MAKE_IRR_ID('h','k','p','a');
const char* havok_physics_typename = "HavokPhysicsAnimator";
//===========================================================================
//Conversion helper functions.
//===========================================================================
//Conversion functions.
hkVector4 convertVectors(core::vector3df& IrrlichtVector)
{
hkVector4 out;
out.set((hkReal)IrrlichtVector.X, (hkReal)IrrlichtVector.Y, (hkReal)IrrlichtVector.Z);
return out;
}
core::vector3df convertVectors(hkVector4& HavokVector)
{
vector3df out;
out.X = HavokVector(0);
out.Y = HavokVector(1);
out.Z = HavokVector(2);
return out;
}
core::quaternion convertQuaternions(hkQuaternion& HavokRotation)
{
core::quaternion out(HavokRotation(0), HavokRotation(1), HavokRotation(2), HavokRotation(3) );
return out;
}
hkQuaternion convertQuaternions(core::quaternion& IrrlichtRotation)
{
hkQuaternion out(IrrlichtRotation.X, IrrlichtRotation.Y, IrrlichtRotation.Z, IrrlichtRotation.W);
return out;
}
hkQuaternion convertToQuaternion(core::vector3df& eulerAngles)
{
core::quaternion out(eulerAngles);
return convertQuaternions(out);
}
hkRotation convertRotations(core::vector3df& eulerAngles)
{
hkQuaternion quat = convertToQuaternion(eulerAngles);
hkRotation out;
out.set(quat);
return out;
}
hkpExtendedMeshShape* convertMeshes(scene::IMesh* mesh, irr::core::vector3df scale)
{
//Thanks to: luthyr from Irrlicht for this code.
hkpExtendedMeshShape* meshShape = new hkpExtendedMeshShape;
for (irr::u32 i = 0; i < mesh->getMeshBufferCount(); i++)
{
irr::scene::IMeshBuffer* mb = mesh->getMeshBuffer(i);
irr::f32* vertexBuffer = new irr::f32[mb->getVertexCount() * 3];
irr::u16* indexBuffer = mb->getIndices();
int tmpCounter = 0;
for (irr::u32 x = 0; x < mb->getVertexCount(); x++)
{
vector3df tmp = mb->getPosition(x);
vertexBuffer[tmpCounter] = tmp.X * scale.X;
vertexBuffer[tmpCounter+1] = tmp.Y * scale.Y;
vertexBuffer[tmpCounter+2] = tmp.Z * scale.Z;
tmpCounter += 3;
}
hkpExtendedMeshShape::TrianglesSubpart part;
part.m_vertexBase = vertexBuffer;
part.m_vertexStriding = sizeof(float) * 3;
part.m_numVertices = mb->getVertexCount();
part.m_indexBase = indexBuffer;
part.m_indexStriding = sizeof(unsigned short)*3;
part.m_numTriangleShapes = mb->getIndexCount()/3;
part.m_stridingType = hkpExtendedMeshShape::INDICES_INT16;
meshShape->addTrianglesSubpart(part);
}
return meshShape;
}
//===========================================================================
//Animator implementation.
//===========================================================================
//Constructors
CHavokPhysicsAnimator::CHavokPhysicsAnimator(hkpWorld *world, hkpRigidBodyCinfo *rigidBodyInfo, scene::ISceneNode* node)
:ISceneNodeAnimator()
{
m_world = world;
m_mass = (int)rigidBodyInfo->m_mass;
//Create rigid body.
m_rigidBody = new hkpRigidBody(*rigidBodyInfo);
//Add rigid body to world.
m_world->addEntity(m_rigidBody);
m_rigidBody->removeReference();
rigidBodyInfo->m_shape->removeReference();
//Orient the rigid body.
hkVector4 pos;
vector3df IrrPos = node->getPosition();
pos = convertVectors(IrrPos);
m_rigidBody->setPosition(pos);
hkQuaternion quat;
vector3df rot = node->getRotation();
quat = convertToQuaternion(rot);
m_rigidBody->setRotation(quat);
}
CHavokPhysicsAnimator::CHavokPhysicsAnimator(hkpWorld *world, hkpShape* shape, int mass, scene::ISceneNode* node)
:ISceneNodeAnimator()
{
m_world = world;
m_mass = mass;
//Create rigid body info.
hkpRigidBodyCinfo rigidBodyInfo;
rigidBodyInfo.m_shape = shape;
rigidBodyInfo.m_mass = (hkReal)mass;
//Create the rigid body.
m_rigidBody = new hkpRigidBody(rigidBodyInfo);
//Add rigid body to world.
m_world->addEntity(m_rigidBody);
m_rigidBody->removeReference();
shape->removeReference();
//Orient the rigid body.
hkVector4 pos;
vector3df IrrPos = node->getPosition();
pos = convertVectors(IrrPos);
m_rigidBody->setPosition(pos);
hkQuaternion quat;
vector3df rot = node->getRotation();
quat = convertToQuaternion(rot);
m_rigidBody->setRotation(quat);
}
CHavokPhysicsAnimator::CHavokPhysicsAnimator(hkpWorld* world, IMesh* mesh, int mass, scene::ISceneNode* node )
:ISceneNodeAnimator()
{
m_world = world;
m_mass = mass;
//Create rigid body info.
hkpRigidBodyCinfo rigidBodyInfo;
rigidBodyInfo.m_shape = convertMeshes(mesh, core::vector3df(1,1,1));
rigidBodyInfo.m_mass = (hkReal)mass;
//Create the rigid body.
m_rigidBody = new hkpRigidBody(rigidBodyInfo);
//Add rigid body to world.
m_world->addEntity(m_rigidBody);
m_rigidBody->removeReference();
rigidBodyInfo.m_shape->removeReference();
//Orient the rigid body.
hkVector4 pos;
vector3df IrrPos = node->getPosition();
pos = convertVectors(IrrPos);
m_rigidBody->setPosition(pos);
hkQuaternion quat;
vector3df rot = node->getRotation();
quat = convertToQuaternion(rot);
m_rigidBody->setRotation(quat);
}
//Destructor
CHavokPhysicsAnimator::~CHavokPhysicsAnimator()
{
//Activate the entity to turn the simulation island back on.
m_rigidBody->activate();
m_world->removeEntity(m_rigidBody);
}
//Animate node.
void CHavokPhysicsAnimator::animateNode(irr::scene::ISceneNode *node, irr::u32 timeMs)
{
//Sanity check.
if (!node)
return;
//Don't do anything if it isn't active.
if ( m_rigidBody->isActive() )
{
//Convert vectors.
hkVector4 hkVect = m_rigidBody->getPosition();
vector3df pos = convertVectors( hkVect );
printf("\n Converted vectors. \n");
///Update position.
node->setPosition( pos );
printf("\n Updated rigid body position. \n");
if ( m_rotationUpdate )
{
//Convert quaternions.
hkQuaternion hkQuat = m_rigidBody->getRotation();
core::quaternion quat = convertQuaternions(hkQuat);
printf("\n Converted quaternions. \n");
//Update rotation.
//Thanks to: xDan
core::vector3df eulerRadians;
quat.toEuler(eulerRadians);
node->setRotation(eulerRadians * core::RADTODEG);
printf("\n Updated rigid body rotation. \n");
}
}
}
//Gets the type.
scene::ESCENE_NODE_ANIMATOR_TYPE CHavokPhysicsAnimator::getType() const
{
return (scene::ESCENE_NODE_ANIMATOR_TYPE)ESNAT_HAVOK_PHYSICS;
};