CHavokPhysicsAnimator

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
3DModelerMan
Posts: 1691
Joined: Sun May 18, 2008 9:42 pm

CHavokPhysicsAnimator

Post by 3DModelerMan »

Okay, I've made a Havok physics animator. It isn't finished yet, so I'll update as I go. Here it is. I've tested it a little bit.

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
CHavokPhysicsAnimator.cpp

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;
};
That would be illogical captain...

My first full game:
http://www.kongregate.com/games/3DModel ... tor#tipjar
Post Reply