Author: CYM
As we all know, Ogre is a graphics rendering engine with a high rating, and Havok is a world-class physical engine. Today, it took some time to combine the two into a Demo.
Havok seems to be rarely studied in China, and I cannot find much information on the internet. So let's share the source code first ..
Demonstrate scenarios where a lot of sticks are dropped to the ground
-------------------------------------------- Gorgeous split line ---------------------------------------------------------------
The gray part is temporarily useless code.
//-----------------------------------------------------------------------------
// Class name: CCYMBasePhysical physical class (independent class)
// Description: used to process physical computing.
// File: CYMBasePhysical. h
// Prepared by: CYM
//-----------------------------------------------------------------------------
# Pragma once
# Include <initguid. h>
# Include <stdio. h>
# Include <Windows. h>
// Include the header file related to Havok
// Mathematical Library and basic Library
# 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>
# Include <Common/Base/Memory/Allocator/Malloc/hkMallocAllocator. h>
# Include <Common/Base/Types/Geometry/hkStridedVertices. h>
// Serialization
# Include <Common/Serialize/Util/hkSerializeUtil. h>
# Include <Physics/Utilities/Serialize/hkpPhysicsData. h>
# Include <Common/SceneData/Scene/hkxScene. h>
# Include <Common/SceneData/Mesh/hkxMesh. h>
# Include <Common/SceneData/Scene/hkxSceneUtils. h>
# Include <Common/Serialize/Util/hkLoader. h>
# Include <Common/Serialize/Util/hkRootLevelContainer. h>
# Include <Common/Serialize/Util/hkBuiltinTypeRegistry. h>
// Shape
# Include <Physics/Collide/Shape/Compound/Collection/CompressedMesh/hkpCompressedMeshShape. h>
# Include <Physics/Collide/Shape/Compound/Collection/ExtendedMeshShape/hkpExtendedMeshShape. h>
# Include <Physics/Collide/Shape/Compound/Collection/StorageExtendedMesh/hkpStorageExtendedMeshShape. h>
# Include <Physics/Collide/Shape/Compound/Collection/List/hkpListShape. h>
# Include <Physics/Collide/Shape/Convex/Box/hkpBoxShape. h>
# Include <Physics/Collide/Shape/Convex/Sphere/hkpSphereShape. h>
# Include <Physics/Collide/Shape/Compound/Tree/Mopp/hkpMoppBvTreeShape. h>
# Include <Physics/Collide/Shape/Convex/ConvexTranslate/hkpConvexTranslateShape. h>
# Include <Physics/Collide/Shape/HeightField/CompressedSampledHeightField/hkpCompressedSampledHeightFieldShape. h>
# Include <Physics/Collide/Shape/HeightField/TriSampledHeightField/hkpTriSampledHeightFieldCollection. h>
# Include <Physics/Collide/Shape/HeightField/TriSampledHeightField/hkpTriSampledHeightFieldBvTreeShape. h>
// Dynamic database
# 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/Convex/ConvexVertices/hkpConvexVerticesShape. 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>
// Keycode
# Include <Common/Base/keycode. cxx>
# Define HK_FEATURE_REFLECTION_PHYSICS
# Define HK_CLASSES_FILE <Common/Serialize/Classlist/hkClasses. h>
# Define HK_EXCLUDE_FEATURE_MemoryTracker
# Define HK_EXCLUDE_FEATURE_SerializeDeprecatedPre700
# Define HK_EXCLUDE_FEATURE_RegisterVersionPatches
# Define HK_EXCLUDE_LIBRARY_hkGeometryUtilities
# Include <Common/Base/Config/hkProductFeatures. cxx>
Class CPhysical
{
Public:
CPhysical (void );
~ CPhysical (void );
// Initialize Havok physical engine and physical world
Bool InitPhyscal (hkpWorldCinfo * hkWorldInfo );
// Add a rigid body
// Bool AddRigidBody (hkpRigidBodyCinfo * hkRigidInfo, hkpRigidBody * hkRigidBody );
// Add an entity to the physical world
Bool AddEntity (hkpRigidBody * hkRigidBody );
// Create a shape based on the mesh
// HkpShape * BiuldShapeFromXMesh (ID3DXMesh * pMesh );
// Create a shape based on the HKT mesh file
// Const hkpShape * BiuldShapeFromHKT (const char * filename );
// Update the physical world
Void UpdatePhysical (hkReal hkDeltaTime );
// Write data to the physical world
Bool MarkForWrite (void );
Bool UnMarkForWrite (void );
// Read data from the physical world
Bool MarkForRead (void );
Bool UnMarkForRead (void );
// Obtain the physical world
HkpWorld * GetPhysicalworld (void );
Protected:
HkArray
// Error message printing function
// Static void HK_CALL errorReport (const char * msg, void * userArgGivenToInit );
// Havok-related definitions
HkMemoryRouter * m_hkMemoryRouter; // memory router
HkJobThreadPool * m_hkThreadPool; // thread pool
HkJobQueue * m_hkJobQueue; // work queue
HkpWorld * m_hkPhysicsWorld; // physical world
};
//-----------------------------------------------------------------------------
// Class name: CCYMBasePhysical physical class (independent class)
// Description: used to process physical computing.
// File: CYMBasePhysical. cpp
// Prepared by: CYM
//-----------------------------------------------------------------------------
# Include "Physical. h"
CPhysical: CPhysical (void)
{
M_hkMemoryRouter = NULL; // memory router
M_hkThreadPool = NULL; // thread pool
M_hkJobQueue = NULL; // work queue
M_hkPhysicsWorld = NULL; // physical world
}
CPhysical ::~ CPhysical (void)
{
// Remove the physical world
M_hkPhysicsWorld-> markForWrite ();
M_hkPhysicsWorld-> removeReference ();
// Clear the work queue and thread pool
Delete m_hkJobQueue;
M_hkThreadPool-> removeReference ();
// Exit the Havok memory system
HkBaseSystem: quit ();
HkMemoryInitUtil: quit ();
}
Static void HK_CALL errorReport (const char * msg, void * userArgGivenToInit)
{
Printf ("% s", msg );
}
// Initialize Havok physical engine and physical world
Bool CPhysical: InitPhyscal (hkpWorldCinfo * hkWorldInfo)
{
//
// Initialize the basic system and our memory system
//
// Allocate MB of physical solution cache
M_hkMemoryRouter = hkMemoryInitUtil: initDefault (hkMallocAllocator: m_defaultMallocAllocator, hkMemorySystem: FrameInfo (500*1024 ));
HkBaseSystem: init (m_hkMemoryRouter, errorReport );
//
// Initialize multi-threaded classes, hkJobQueue, and hkJobThreadPool
//
Int totalNumThreadsUsed;
HkHardwareInfo hwInfo;
HkGetHardwareInfo (hwInfo );
TotalNumThreadsUsed = hwInfo. m_numThreads;
// We use one less than this for our thread pool, because we must also use this thread for our simulation
HkCpuJobThreadPoolCinfo threadPoolCinfo;
ThreadPoolCinfo. m_numThreads = totalNumThreadsUsed-1;
// Create a thread pool
ThreadPoolCinfo. m_timerBufferPerThreadAllocation = 200000;
M_hkThreadPool = new hkCpuJobThreadPool (threadPoolCinfo );
// Create a work queue
HkJobQueueCinfo info;
Info. m_jobQueueHwSetup.m_numCpuThreads = totalNumThreadsUsed;
M_hkJobQueue = new hkJobQueue (info );
// Activate this thread pool
HkMonitorStream: getInstance (). resize (200000 );
//
// Create a physical world
//
M_hkPhysicsWorld = new hkpWorld (* hkWorldInfo );
// Write data to the physical world
M_hkPhysicsWorld-> markForWrite ();
// Set deactivating
M_hkPhysicsWorld-> m_wantDeactivation = true;
// Register the collision proxy
HkpAgentRegisterUtil: registerAllAgents (m_hkPhysicsWorld-> getCollisionDispatcher ());
// Register a work queue
M_hkPhysicsWorld-> registerWithJobQueue (m_hkJobQueue );
// Stop writing data to the physical world
M_hkPhysicsWorld-> unmarkForWrite ();
Return true;
}
/* // Add a rigid body
Bool CPhysical: AddRigidBody (hkpRigidBodyCinfo * hkRigidInfo, hkpRigidBody * hkRigidBody)
{
// Write data to the physical world
// M_hkPhysicsWorld-> markForWrite ();
// Create a rigid body
HkRigidBody = new hkpRigidBody (* hkRigidInfo );
M_hkPhysicsWorld-> addEntity (hkRigidBody );
// HkRigidBody-> removeReference (); // remove the reference
// Stop writing data to the physical world
// M_hkPhysicsWorld-> unmarkForWrite ();
Return true;
}*/
// Add an entity to the physical world
Bool CPhysical: AddEntity (hkpRigidBody * hkRigidBody)
{
M_hkPhysicsWorld-> addEntity (hkRigidBody );
Return true;
}
/* // Create a shape based on the mesh
HkpShape * CPhysical: BiuldShapeFromXMesh (ID3DXMesh * pMesh)
{
// Obtain the vertex cache of the mesh
LPDIRECT3DVERTEXBUFFER9 lpBuffer = NULL;
PMesh-> GetVertexBuffer (& lpBuffer );
// Obtain the index cache of the grid
LPDIRECT3DINDEXBUFFER9 lpIndexBuffer = NULL;
PMesh-> GetIndexBuffer (& lpIndexBuffer );
// Havok is used to construct a vertex array in the convex shape.
Float * hkVertex = NULL;
HkVertex = new float [pMesh-> GetNumVertices () * 4];
// Obtain the vertex of the grid
CYMFVFVertex1 * pVertex = NULL;
LpBuffer-> Lock (0, 0, (void **) & pVertex, 0 );
// Obtain each vertex of the grid cyclically
For (int I = 0, j = 0; I <pMesh-> GetNumVertices (); I ++)
{
HkVertex [j] = pVertex [I]. _ x;
HkVertex [j + 1] = pVertex [I]. _ y;
HkVertex [j + 2] = pVertex [I]. _ z;
HkVertex [j + 3] = 0.0f;
J + = 4;
}
LpBuffer-> Unlock ();
// Obtain the index value of the grid.
DWORD * hkIndex = NULL;
HkIndex = new DWORD [pMesh-> GetNumFaces () * 6];
// Obtain the index value
DWORD * pIndex = NULL;
LpIndexBuffer-> Lock (0, 0, (void **) & pIndex, 0 );
// Obtain the index value cyclically
For (int I = 0; I <pMesh-> GetNumFaces () * 6; I ++)
{
HkIndex [I] = pIndex [I];
}
LpIndexBuffer-> Unlock ();
// Construct a shape based on the obtained vertex information
HkpExtendedMeshShape * extendedMeshShape = new hkpExtendedMeshShape ();
{
HkpExtendedMeshShape: TrianglesSubpart part;
Part. m_numTriangleShapes = pMesh-> GetNumFaces ();
Part. m_numVertices = pMesh-> GetNumVertices ();
Part. m_vertexBase = hkVertex;
Part. m_stridingType = hkpExtendedMeshShape: INDICES_INT16;
Part. m_vertexStriding = sizeof (hkReal) * 4;
Part. m_indexBase = hkIndex;
Part. m_indexStriding = sizeof (hkUint16) * 6;
ExtendedMeshShape-> addTrianglesSubpart (part );
}
// Int numTriangles = extendedMeshShape-> getNumChildShapes ();
// NumTriangles ++;
// Return extendedMeshShape;
HkStridedVertices * hkStrided = new hkStridedVertices (& hkVertex [0], pMesh-> GetNumVertices ());
HkpConvexShape * shape = new hkpConvexVerticesShape (* hkStrided );
Return extendedMeshShape;
}*/
/* // Create a shape based on the HKT mesh file
Const hkpShape * CPhysical: BiuldShapeFromHKT (const char * filename)
{
// Load the file
HkSerializeUtil: ErrorDetails loadError;
HkResource * loadedData = NULL;
LoadedData = hkSerializeUtil: load (filename, & loadError );
// HK_ASSERT2 (0xa6451543, loadedData! = HK_NULL, "cocould not load file. The error is: \ n" <loadError. defaultMessage. cString ());
: MessageBox (NULL, loadError. defaultMessage. cString (), "error", NULL );
// Get the top level object in the file, which we know is a hkRootLevelContainer
HkRootLevelContainer * container = loadedData-> getContents
HK_ASSERT2 (0xa6451543, container! = HK_NULL, "cocould not load root level obejct ");
// Get the physics data
HkpPhysicsData * physicsData = static_cast
HK_ASSERT2 (0xa6451544, physicsData! = HK_NULL, "cocould not find physics data in root level object ");
HK_ASSERT2 (0x231a7ac2, physicsData-> getPhysicsSystems (). getSize ()> 0, "There are no physics systems in the asset .");
HkpPhysicsSystem * system0 = physicsData-> getPhysicsSystems () [0];
HK_ASSERT2 (0xb377381b, system0-> getRigidBodies (). getSize ()> 0, "There are no rigid bodies in the first physics system .");
HkpRigidBody * system0body0 = system0-> getRigidBodies () [0];
Const hkpShape * shape = system0body0-> getcol1_ablerw ()-> getShape ();
HK_ASSERT2 (0xb377381c, shape, "There first rigid body in the first physics system has no shape .");
// M_externalData.pushBack (loadedData );
Const hkpShape * EMS = shape;
If (EMS-> getType () = HK_SHAPE_MOPP)
{
EMS = static_cast <const hkpMoppBvTreeShape *> (EMS)-> getChild ();
}
HK_ASSERT (0x4f78a915, EMS-> getType () = HK_SHAPE_EXTENDED_MESH );
// If there is a material table in the landscape, we overwrite it with the collision
// Filter infos in this utility so it works with the demo.
If (m_collisionFilterInfos.getSize ())
{
Const hkpExtendedMeshShape * extendedMeshShape = static_cast <const hkpExtendedMeshShape *> (EMS );
For (int I = 0; I <extendedMeshShape-> getNumTrianglesSubparts (); ++ I)
{
Const hkpExtendedMeshShape: Subpart & subPart = extendedMeshShape-> getTrianglesSubpartAt (I );
If (subPart. m_materialBase & subPart. m_materialStriding)
{
For (int j = 0; j <subPart. m_numMaterials; ++ j)
{
(Const_cast
}
}
}
For (int I = 0; I <extendedMeshShape-> getNumShapesSubparts (); ++ I)
{
Const hkpExtendedMeshShape: Subpart & subPart = extendedMeshShape-> getShapesSubpartAt (I );
If (subPart. m_materialBase & subPart. m_materialStriding)
{
For (int j = 0; j <subPart. m_numMaterials; ++ j)
{
(Const_cast
}
}
}
}
Return shape;
}*/
// Update the physical world
Void CPhysical: UpdatePhysical (hkReal hkDeltaTime)
{
// Use multiple threads for a simulation
M_hkPhysicsWorld-> stepMultithreaded (m_hkJobQueue, m_hkThreadPool, hkDeltaTime );
HkMonitorStream: getInstance (). reset ();
M_hkThreadPool-> clearTimerData ();
}
// Write data to the physical world
Bool CPhysical: MarkForWrite (void)
{
M_hkPhysicsWorld-> markForWrite ();
Return true;
}
Bool CPhysical: UnMarkForWrite (void)
{
M_hkPhysicsWorld-> unmarkForWrite ();
Return true;
}
// Read data from the physical world
Bool CPhysical: MarkForRead (void)
{
M_hkPhysicsWorld-> markForRead ();
Return true;
}
Bool CPhysical: UnMarkForRead (void)
{
M_hkPhysicsWorld-> unmarkForRead ();
Return true;
}
// Obtain the physical world
HkpWorld * CPhysical: GetPhysicalworld (void)
{
Return m_hkPhysicsWorld;
}
Go to: use Havok physical engine (source code) in Ogre)