作者: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物理引擎(源码)的更多相关文章

  1. ROS_Kinetic_07 ROS中机器人三维物理引擎高保真仿真利器gazebo 7.0

    ROS_Kinetic_07 ROS中机器人三维物理引擎高保真仿真利器gazebo 7.0 ROS kinetic中的gazebo版本是7.0,有很多新的特性. 首先,启动gazebo: ~$ gaz ...

  2. Fabric2.2中的Raft共识模块源码分析

    引言 Hyperledger Fabric是当前比较流行的一种联盟链系统,它隶属于Linux基金会在2015年创建的超级账本项目且是这个项目最重要的一个子项目.目前,与Hyperledger的另外几个 ...

  3. eclipse中tomcat调试正确关联源码

    1.build path中jar包关联本地源码 2.tomcat中添加source关联工程lib下的jar包 以上两步即可. 可解决tomcat直接关联本地源码debug时无法计算表达式的情况. 错误 ...

  4. 动态语言切换(续)-designer中的retranslateUi(带源码)

    本站所有文章由本站和原作者保留一切权力,仅在保留本版权信息.原文链接.原文作者的情况下允许转载,转载请勿删改原文内容, 并不得用于商业用途. 谢谢合作.原文链接:动态语言切换(续)-designer中 ...

  5. RocketMQ中Broker的HA策略源码分析

    Broker的HA策略分为两部分①同步元数据②同步消息数据 同步元数据 在Slave启动时,会启动一个定时任务用来从master同步元数据 if (role == BrokerRole.SLAVE) ...

  6. Chrome V8 引擎源码剖析

    Chrome V8 引擎源码剖析 V8 https://github.com/v8/v8 array & sort https://github.com/v8/v8/search?l=Java ...

  7. cocos2d-x中的Box2D物理引擎

    在Cocos2d-x中集成了2个物理引擎,一个是Chipmunk,一个是Box2D.前者是用C语言编写的,文档和例子相对较少:Box2D是用C++写的,并且有比较完善的文档和资料.所以在需要使用物理引 ...

  8. Egret中使用P2物理引擎

    游戏中的对象按照物理规律移动,体现重力.引力.反作用力.加速度等物体特性,实现自由落体.摇摆运动.抛物线运动,以及物理碰撞现象的模拟.用于模拟物理碰撞.物理运动的引擎称为物理引擎. 来自瑞典斯德哥尔摩 ...

  9. Handlebars模板引擎中的each嵌套及源码浅读

    若显示效果不佳,可移步到愚安的小窝 Handlebars模板引擎作为时下最流行的模板引擎之一,已然在开发中为我们提供了无数便利.作为一款无语义的模板引擎,Handlebars只提供极少的helper函 ...

随机推荐

  1. NOI 2015 Bless All!

    明天day1,加油!RP++! (话说出题人貌似是dyf&lyd?好虚啊……

  2. POJ 1719 Shooting Contest(二分图匹配)

    POJ 1719 Shooting Contest id=1719" target="_blank" style="">题目链接 题意:给定一个 ...

  3. go语言之进阶篇单向channel的应用 (生产者,消费者模型)

    1.单向channel的应用 示例: package main import ( "fmt" ) //此通道只能写,不能读 func producer(out chan<- ...

  4. go语言之进阶篇方法表达式

    1.方法表达式 示例: package main import "fmt" type Person struct { name string //名字 sex byte //性别, ...

  5. [leetcode]Candy @ Python

    原题地址:https://oj.leetcode.com/problems/candy/ 题意: There are N children standing in a line. Each child ...

  6. [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 ...

  7. 关于APP接口设计 (转)

    转自:http://blog.csdn.net/gebitan505/article/details/37924711 1.效率:接口访问速度 PHP建议使用YAF框架. 最好使用JSON格式数据,因 ...

  8. 【转】npm install、npm install --save与npm install --save-dev区别

    原文: https://blog.csdn.net/qq_30378229/article/details/78463930 ------------------------------------- ...

  9. ESXI安装时卡在loading ipmi_si_drv的解决方案

    参考:http://x220ak.hatenablog.com/ 在这个界面按下shift+O,输入runweasel noipmiEnabled即可跳过loading ipmi_si_drv的加载

  10. Mathematica 文本界面获得之前的结果

    使用%号做标记.获得文本界面之前的运算结果: