Go to: use Havok physical engine (source code) in Ogre)

Source: Internet
Author: User

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)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.