转: 在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函 ...
随机推荐
- 从头认识Spring-2.1 自己主动装配(2)-byType(2)
为了解决配置文件中面出现多个同类型的Bean而byType无法匹配的问题.引入了primary和autowire-candidate属性. 1.primary 因为全部bean默认的primary都是 ...
- leetcode关于数组的问题
关于数组的几道面试题 [Leetcode] 628. 三个数的最大乘积 解题思路: 这个一开始我是没想到思路的(除了遍历),因为有正负号的问题,后来看了一下别人的思路然后自己写的,思路是这样的: 三个 ...
- 25个可遇不可求的jQuery插件
随着jQuery插件在网站建设过程中的使用率不断的增加,所以有必要跟进时代步伐开发出一些新的插件/代码片段,以此来巩固并提高前端用户体验,将用户体验提升到一个新的高度. 接下来所推荐的这些插件中有滑块 ...
- [VS2010搭建汇编开发环境win32和x64]
场景: 1. 虽然使用MASM32也可以编译运行汇编程序,但是既然装了VS2010,它也能支持编译运行汇编吧.不然微软的开发人员难道还不用vs写汇编程序了? http://www.masm32.com ...
- 【ElasticSearch】ElasticSearch-索引优化-自定义索引
ElasticSearch-索引优化-自定义索引 es 指定 索引 字段_百度搜索 [es]创建索引和映射 - 匡子语 - 博客园 reindex,增加字段,并新增数据 - Elastic中文社区 e ...
- SQLSERVER 免费对比数据库结构和数据的工具支持:SQL Server 2012, SQL Server 2008 and SQL Server 2005
New xSQL Schema Compare - version 5 Compare the schemas of two SQL Server databases, review differen ...
- 下载google play下的app
1.打开appk downland网站 https://apps.evozi.com/apk-downloader/?id=com.cmcm.live 2. 把google play的链接直接贴入 输 ...
- Java程序猿的JavaScript学习笔记(1——理念)
计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...
- Node.js 笔记(一) nodejs、npm、express安装
Windows平台下的node.js安装 直接去nodejs的官网http://nodejs.org/上下载nodejs安装程序,双击安装就可以了 测试安装是否成功: 在命令行输入 node –v 应 ...
- linux 文件系统与磁盘修复
fsck修复受损的文件系统 Linux不正常关机,有时候再次启动时会报文件系统损坏,如何修复文件? 首先会让你输入root用户的密码. 1)出错的时候如果告诉你是哪一块硬盘的分区有问题,比如是/ ...