转: 在Ogre中使用Havok物理引擎(源码)
作者: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物理引擎(源码)的更多相关文章
- ROS_Kinetic_07 ROS中机器人三维物理引擎高保真仿真利器gazebo 7.0
ROS_Kinetic_07 ROS中机器人三维物理引擎高保真仿真利器gazebo 7.0 ROS kinetic中的gazebo版本是7.0,有很多新的特性. 首先,启动gazebo: ~$ gaz ...
- Fabric2.2中的Raft共识模块源码分析
引言 Hyperledger Fabric是当前比较流行的一种联盟链系统,它隶属于Linux基金会在2015年创建的超级账本项目且是这个项目最重要的一个子项目.目前,与Hyperledger的另外几个 ...
- eclipse中tomcat调试正确关联源码
1.build path中jar包关联本地源码 2.tomcat中添加source关联工程lib下的jar包 以上两步即可. 可解决tomcat直接关联本地源码debug时无法计算表达式的情况. 错误 ...
- 动态语言切换(续)-designer中的retranslateUi(带源码)
本站所有文章由本站和原作者保留一切权力,仅在保留本版权信息.原文链接.原文作者的情况下允许转载,转载请勿删改原文内容, 并不得用于商业用途. 谢谢合作.原文链接:动态语言切换(续)-designer中 ...
- RocketMQ中Broker的HA策略源码分析
Broker的HA策略分为两部分①同步元数据②同步消息数据 同步元数据 在Slave启动时,会启动一个定时任务用来从master同步元数据 if (role == BrokerRole.SLAVE) ...
- Chrome V8 引擎源码剖析
Chrome V8 引擎源码剖析 V8 https://github.com/v8/v8 array & sort https://github.com/v8/v8/search?l=Java ...
- cocos2d-x中的Box2D物理引擎
在Cocos2d-x中集成了2个物理引擎,一个是Chipmunk,一个是Box2D.前者是用C语言编写的,文档和例子相对较少:Box2D是用C++写的,并且有比较完善的文档和资料.所以在需要使用物理引 ...
- Egret中使用P2物理引擎
游戏中的对象按照物理规律移动,体现重力.引力.反作用力.加速度等物体特性,实现自由落体.摇摆运动.抛物线运动,以及物理碰撞现象的模拟.用于模拟物理碰撞.物理运动的引擎称为物理引擎. 来自瑞典斯德哥尔摩 ...
- Handlebars模板引擎中的each嵌套及源码浅读
若显示效果不佳,可移步到愚安的小窝 Handlebars模板引擎作为时下最流行的模板引擎之一,已然在开发中为我们提供了无数便利.作为一款无语义的模板引擎,Handlebars只提供极少的helper函 ...
随机推荐
- NOI 2015 Bless All!
明天day1,加油!RP++! (话说出题人貌似是dyf&lyd?好虚啊……
- POJ 1719 Shooting Contest(二分图匹配)
POJ 1719 Shooting Contest id=1719" target="_blank" style="">题目链接 题意:给定一个 ...
- go语言之进阶篇单向channel的应用 (生产者,消费者模型)
1.单向channel的应用 示例: package main import ( "fmt" ) //此通道只能写,不能读 func producer(out chan<- ...
- go语言之进阶篇方法表达式
1.方法表达式 示例: package main import "fmt" type Person struct { name string //名字 sex byte //性别, ...
- [leetcode]Candy @ Python
原题地址:https://oj.leetcode.com/problems/candy/ 题意: There are N children standing in a line. Each child ...
- [leetcode]Max Points on a Line @ Python
原题地址:https://oj.leetcode.com/problems/max-points-on-a-line/ 题意:Given n points on a 2D plane, find th ...
- 关于APP接口设计 (转)
转自:http://blog.csdn.net/gebitan505/article/details/37924711 1.效率:接口访问速度 PHP建议使用YAF框架. 最好使用JSON格式数据,因 ...
- 【转】npm install、npm install --save与npm install --save-dev区别
原文: https://blog.csdn.net/qq_30378229/article/details/78463930 ------------------------------------- ...
- ESXI安装时卡在loading ipmi_si_drv的解决方案
参考:http://x220ak.hatenablog.com/ 在这个界面按下shift+O,输入runweasel noipmiEnabled即可跳过loading ipmi_si_drv的加载
- Mathematica 文本界面获得之前的结果
使用%号做标记.获得文本界面之前的运算结果: