转: 在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;
}
转载于:https://www.cnblogs.com/skyofbitbit/p/4083080.html
转: 在Ogre中使用Havok物理引擎(源码)相关推荐
- Havok物理引擎与Unity3D的结合
背景 在重度手游的研发过程当中,游戏中的车辆模拟,场景互动,特效展示等功能很多时候需要物理引擎的介入,以提供丰富的交互体验.目前3D手游的开发主要工具是使用Unity3D引擎,于是,如何在Unity3 ...
- Havok物理引擎_百度百科
Havok 来源:百度百科 目录 Havok概述 Havok的组成 Havok Physic Havok FX Havok Animation Havok Behavior Havok Cloth ...
- Havok物理引擎不完全指南--从入门到放弃
Havok物理引擎不完全指南–从入门到放弃 Havok概述 Havok,全称为Havok Game Dynamics SDK,译作Havok游戏动力开发包. 人们经常说到的,与PhysX相提并论的Ha ...
- havok物理引擎_统一中的Havok物理
havok物理引擎 As announced at Game Developers Conference (GDC) 2019, Havok Physics is now available as a ...
- Havok物理引擎与Unity3D游戏的结合
背景 在重度手游的研发过程当中,游戏中的车辆模拟,场景互动,特效展示等功能很多时候需要物理引擎的介入,以提供丰富的交互体验.目前3D手游的开发主要工具是使用Unity3D引擎,于是,如何在Unity3 ...
- havok物理引擎快速入门指南翻译
花了2天时间完成了这个翻译, 需要有C++基础, 是通过haovk引擎做物理动画的基础. 到intel官方网站注册一个帐号可以免费获取havok SDK, 这是SDK中的一个文档的翻译. [翻译]Ha ...
- 正则表达式引擎 源码 c#_如何在C#中构建正则表达式引擎
正则表达式引擎 源码 c# 更新: (Update:) See my Unicode enabled offering here 在这里查看启用Unicode的产品 先决条件 (Prerequisit ...
- cocos creator 游戏源码_Cocos Creator 3D引擎源码阅读之授之以渔 源码阅读
源码阅读 动静之法 静 找到引擎源码的所在 在编辑器的右上角有一个大按钮 在VSCode里开打engine目录 引擎源码就在红色标中的cocos文件夹里,如下图 让我们来看一下引擎的目录结构 可以看到 ...
- 【Unity开源项目精选】Unity引擎源码的C#部分
洪流学堂,让你快人几步.你好,我是你的技术探路者郑洪智,你可以叫我大智. 今天给你分享一个Unity开源项目,我们一起来看看吧! Unity引擎源码的C#部分 Unity 引擎和编辑器源代码的 C# ...
最新文章
- Linux那些事儿 之 戏说USB(11)繁华落尽
- 40.lombok在IntelliJ IDEA下的使用
- 19日零时起降低成品油价格 燃油税元旦起开征
- 【阿里云课程】详解深度学习优化:参数初始化,激活函数,标准化,池化
- Prototype原型模式(创建型模式)
- 字符识别(模板匹配BP神经网络训练)
- python常用模块用法_python常用模块(一)
- Java中注解学习系列教程-1
- 利用nginx集群式部署服务器中,数据同步问题
- 数据库的设计与连接、站点的搭建
- 我有一朋友生意做的红红火火
- expect脚本教程_Expect脚本SSH示例教程
- 推荐两个有意思的公号
- KITTI数据集calib文件解析
- 小钛掐指一算,今年的尖货市场不简单 | 活动预告
- 全网最全软件测试面试题,拿不到offer算我输!
- python2.7安装教程windowsxp_怎么在windows xp 下安装python 2.7
- 来自#Devoxx 2014的WebSocket螺母和螺栓的幻灯片
- 计算机 教授级职称评定,工程技术应用研究员(俗称正高,教授级高工等等)职称评定...
- Centos7 下mysql8.0的安装以及修改初始密码;