转: 在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(AbstractRoutingDataSource)实现动态数据源切换
转自: http://blog.51cto.com/linhongyu/1615895 一.前言 近期一项目A需实现数据同步到另一项目B数据库中,在不改变B项目的情况下,只好选择项目A中切换数据源,直 ...
- ASP.NET网页中RAR、DOC、PDF等文件下载功能实例源代码
以前做asp.net下载功能的时候都是采用:<a href="http://www.wang0214.com/wgcms">下载</a>的方式来实现下载. ...
- CSS-返回顶部代码
现在的网站基本上都是长页面,多的有四五屏,少的话也有两三屏,页面太长有的时候为了提升用户体验,会在页面右边出现一个回到顶部的按钮,这样能快速回到顶部,以免在滑动页面出现视觉屏幕,回到顶部一般有四种方式 ...
- JQuery-Dialog(弹出窗口,遮蔽窗口)
在Ajax中经常用到的弹出窗口和遮蔽窗口.自己写肯定是一个最佳方案,但时间和成本上,还是决定了寻找现成的吧.大概罗列一下.需要我满足我几个条件 一定要简洁方便 拥有遮蔽功能,Model Dialog ...
- eclipse如何debug调试jdk源码,并显示局部变量
http://blog.csdn.net/xuefeng0707/article/details/8738869 http://blog.csdn.net/leehsiao/article/detai ...
- JqueryValidate表单相同Name不校验问题解决
在使用Jquery validate中遇到一个问题,当表单元素有name相同字段时,validate只校验表单元素name第一个值是否通过校验,比如 <input type="text ...
- Oracle聚合连接字符串
问题需求 现有一个数据表,如下: ID CODE NAME 1 A 张三 2 A 李四 3 B 王五 4 C 赵六 5 C 孙七 ...
- 视图控制器生命周期中各个重要的方法(Swift) (Important Methods during the Lifecycle of a View Controller)
1. init(coder:) 它是视图控制器从故事板创建实例的默认初始化函数.(It is the initializer for UIViewController instances create ...
- JavaScript编程(终极篇)
JavaScript 实现是由以下 3 个不同部分组成的: 核心(ECMAScript) 文档对象模型(DOM) 浏览器对象模型(BOM) 1.数据类型 typeof 运算符 对变量 ...
- Python+OpenCV实现FasterRcnn样本查看器
一.上代码 import cv2 import os def get_samples(dir): datasets = [] files = os.listdir(dir) for file in f ...