轉: 在Ogre中使用Havok物理引擎(源碼)

來源:互聯網
上載者:User

標籤:http   io   ar   os   使用   sp   for   檔案   資料   

作者:CYM

眾所周知Ogre則是評價很高的一款圖形渲染引擎,Havok則是世界一流的物理引擎,今天花了點時間將兩者結合在了一塊,做了個Demo

由於國內對Havok的研究似乎很少,網上也找不到多少資料,所以先分享一下源碼..

示範了很多棍子掉落在地上的情境

 




--------------------------------------------華麗分割線---------------------------------------------------------------

灰色部分為暫時無用代碼

 

//-----------------------------------------------------------------------------

//類名: CCYMBasePhysical 物理類(獨立類)

//描述: 用於處理物理的計算

//檔案:CYMBasePhysical.h

//作者: CYM

//-----------------------------------------------------------------------------

 

#pragma once

#include <initguid.h>

#include <stdio.h>

#include <Windows.h>

//包涵Havok相關的標頭檔

// 數學庫和基本庫

#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>

 

// 序列化

#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>

 

// 形狀

#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>

 

// 動力學庫

#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);

 

//初始化Havok物理引擎相關和物理世界

bool InitPhyscal(hkpWorldCinfo* hkWorldInfo);

//增加一個剛體

//bool AddRigidBody(hkpRigidBodyCinfo* hkRigidInfo,hkpRigidBody* hkRigidBody);

//向物理世界增加一個實體

bool AddEntity(hkpRigidBody* hkRigidBody);

//根據網格建立形狀

//hkpShape* BiuldShapeFromXMesh(ID3DXMesh* pMesh);

//根據HKT網格檔案建立形狀

//const hkpShape* BiuldShapeFromHKT( const char* filename );

//更新物理世界

void UpdatePhysical(hkReal hkDeltaTime);

 

//向物理世界寫入資料

bool MarkForWrite(void);

bool UnMarkForWrite(void);

//從物理世界讀取資料

bool MarkForRead(void);

bool UnMarkForRead(void);

 

//獲得物理世界

hkpWorld* GetPhysicalworld(void);

 

protected:

hkArray<hkUint32> m_collisionFilterInfos;

//錯誤資訊列印函數

//static void HK_CALL errorReport(const char* msg, void* userArgGivenToInit);

 

//Havok相關的定義

hkMemoryRouter* m_hkMemoryRouter;//記憶體路由器

hkJobThreadPool* m_hkThreadPool;//線程池

hkJobQueue* m_hkJobQueue;//工作隊列

hkpWorld* m_hkPhysicsWorld;//物理世界

};

 

//-----------------------------------------------------------------------------

//類名: CCYMBasePhysical 物理類(獨立類)

//描述: 用於處理物理的計算

//檔案:CYMBasePhysical.cpp

//作者: CYM

//-----------------------------------------------------------------------------

#include "Physical.h"

 

CPhysical::CPhysical(void)

{

m_hkMemoryRouter=NULL;//記憶體路由器

m_hkThreadPool=NULL;//線程池

m_hkJobQueue=NULL;//工作隊列

m_hkPhysicsWorld=NULL;//物理世界

}

 

 

CPhysical::~CPhysical(void)

{

//移除物理世界

m_hkPhysicsWorld->markForWrite();

m_hkPhysicsWorld->removeReference();

 

//清除工作隊列和線程池

delete m_hkJobQueue;

m_hkThreadPool->removeReference();

 

//退出Havok記憶體系統

hkBaseSystem::quit();

    hkMemoryInitUtil::quit();

}

 

static void HK_CALL errorReport(const char* msg, void* userArgGivenToInit)

{

printf("%s", msg);

}

 

//初始化Havok物理引擎相關和物理世界

bool CPhysical::InitPhyscal(hkpWorldCinfo* hkWorldInfo)

{

//

// 初始化基本的系統和我們的記憶體系統

//

// 分配0.5MB的物理解決緩衝

 

m_hkMemoryRouter = hkMemoryInitUtil::initDefault( hkMallocAllocator::m_defaultMallocAllocator, hkMemorySystem::FrameInfo( 500* 1024 ) );

hkBaseSystem::init(m_hkMemoryRouter,errorReport );

 

//

// 初始化多線程類, hkJobQueue, 和 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;

//建立線程池

threadPoolCinfo.m_timerBufferPerThreadAllocation = 200000;

m_hkThreadPool = new hkCpuJobThreadPool( threadPoolCinfo );

//建立工作隊列

hkJobQueueCinfo info;

info.m_jobQueueHwSetup.m_numCpuThreads = totalNumThreadsUsed;

m_hkJobQueue= new hkJobQueue(info);

//為這個線程池啟用

hkMonitorStream::getInstance().resize(200000);

 

//

//建立物理世界

//

m_hkPhysicsWorld = new hkpWorld(*hkWorldInfo);

 

//向物理世界寫入資料

m_hkPhysicsWorld->markForWrite();

//設定去活化

m_hkPhysicsWorld->m_wantDeactivation = true;

 

//註冊碰撞代理

hkpAgentRegisterUtil::registerAllAgents(m_hkPhysicsWorld->getCollisionDispatcher() );

//註冊工作隊列

m_hkPhysicsWorld->registerWithJobQueue(m_hkJobQueue );

 

//終止向物理世界寫入資料

m_hkPhysicsWorld->unmarkForWrite();

 

return true;

 

}

 

/*//增加一個剛體

bool CPhysical::AddRigidBody(hkpRigidBodyCinfo* hkRigidInfo,hkpRigidBody* hkRigidBody)

{

//向物理世界寫入資料

//m_hkPhysicsWorld->markForWrite();

//建立剛體

hkRigidBody=new hkpRigidBody(*hkRigidInfo);

m_hkPhysicsWorld->addEntity(hkRigidBody);

//hkRigidBody->removeReference();//移除引用

 

//停止向物理世界寫入資料

//m_hkPhysicsWorld->unmarkForWrite();

 

return true;

}*/

 

//向物理世界增加一個實體

bool CPhysical::AddEntity(hkpRigidBody* hkRigidBody)

{

m_hkPhysicsWorld->addEntity(hkRigidBody);

 

return true;

}

 

/*//根據網格建立形狀

hkpShape* CPhysical::BiuldShapeFromXMesh(ID3DXMesh* pMesh)

{

//擷取網格的頂點緩衝

LPDIRECT3DVERTEXBUFFER9 lpBuffer=NULL;

pMesh->GetVertexBuffer(&lpBuffer);

//擷取網格的索引緩衝

LPDIRECT3DINDEXBUFFER9 lpIndexBuffer=NULL;

pMesh->GetIndexBuffer(&lpIndexBuffer);

 

//havok用於構造凸面體形狀的頂點數組

float* hkVertex=NULL;

hkVertex=new float[pMesh->GetNumVertices()*4];

//擷取網格的頂點

CYMFVFVertex1* pVertex=NULL;

lpBuffer->Lock(0,0,(void**)&pVertex,0);

//迴圈擷取網格的每個頂點

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();

 

//擷取網格的索引值

DWORD* hkIndex=NULL;

hkIndex=new DWORD[pMesh->GetNumFaces()*6];

//擷取索引值

DWORD* pIndex=NULL;

lpIndexBuffer->Lock(0,0,(void**)&pIndex,0);

//迴圈擷取索引值

for(int i=0;i<pMesh->GetNumFaces()*6;i++)

{

hkIndex[i]=pIndex[i];

}

lpIndexBuffer->Unlock();

 

//根據擷取的頂點資訊構造一個形狀

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;

}*/

 

/*//根據HKT網格檔案建立形狀

const hkpShape* CPhysical::BiuldShapeFromHKT( const char* filename )

{

//載入檔案

hkSerializeUtil::ErrorDetails loadError;

hkResource* loadedData=NULL;

loadedData = hkSerializeUtil::load( filename, &loadError );

 

//HK_ASSERT2(0xa6451543, loadedData != HK_NULL, "Could not load file. The error is:\n"<<loadError.defaultMessage.cString() );

::MessageBox(NULL,loadError.defaultMessage.cString(),"錯誤",NULL);

// Get the top level object in the file, which we know is a hkRootLevelContainer

hkRootLevelContainer* container = loadedData->getContents<hkRootLevelContainer>();

HK_ASSERT2(0xa6451543, container != HK_NULL, "Could not load root level obejct" );

 

// Get the physics data

hkpPhysicsData* physicsData = static_cast<hkpPhysicsData*>( container->findObjectByType( hkpPhysicsDataClass.getName() ) );

HK_ASSERT2(0xa6451544, physicsData != HK_NULL, "Could 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->getCollidableRw()->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<hkpMeshMaterial*>(hkAddByteOffsetConst( subPart.m_materialBase, j * subPart.m_materialStriding )))->m_filterInfo = m_collisionFilterInfos[ ( i + j ) % m_collisionFilterInfos.getSize() ];

}

}

}

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<hkpMeshMaterial*>(hkAddByteOffsetConst( subPart.m_materialBase, j * subPart.m_materialStriding )))->m_filterInfo = m_collisionFilterInfos[ i + j % m_collisionFilterInfos.getSize() ];

}

}

}

}

 

return shape;

}*/

 

//更新物理世界

void CPhysical::UpdatePhysical(hkReal hkDeltaTime)

{

//使用多線程進行一次類比

m_hkPhysicsWorld->stepMultithreaded(m_hkJobQueue, m_hkThreadPool,hkDeltaTime);

hkMonitorStream::getInstance().reset();

m_hkThreadPool->clearTimerData();

}

 

//向物理世界寫入資料

bool CPhysical::MarkForWrite(void)

{

m_hkPhysicsWorld->markForWrite();

 

return true;

}

 

bool CPhysical::UnMarkForWrite(void)

{

m_hkPhysicsWorld->unmarkForWrite();

 

return true;

}

 

//從物理世界讀取資料

bool CPhysical::MarkForRead(void)

{

m_hkPhysicsWorld->markForRead();

 

return true;

}

 

bool CPhysical::UnMarkForRead(void)

{

m_hkPhysicsWorld->unmarkForRead();

 

return true;

}

 

//擷取物理世界

hkpWorld* CPhysical::GetPhysicalworld(void)

{

return m_hkPhysicsWorld;

}

 

轉: 在Ogre中使用Havok物理引擎(源碼)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.