作者: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. 2.2 dubbo-spi源码解析

    package com.alibaba.dubbo.demo.test; import com.alibaba.dubbo.common.extension.ExtensionLoader; impo ...

  2. Hadoop视频教程汇总

    一 慕课网 1.Hadoop大数据平台架构与实践--基础篇(已学习) 链接:https://www.imooc.com/learn/391 2.Hadoop进阶(已学习) 链接:https://www ...

  3. 学 Win32 汇编[34] - 宏汇编(1)

    从接触 C 语言时, 我就不大喜欢宏; 但为了看懂别人的代码也不得不去了解. 宏可定义在源程序的任意位置, 但一般放在 .data 前面.有些简单的宏可以用 equ.textequ 或 = 来代替, ...

  4. [Spring Boot] Complex Scope Scenarios of a Spring Bean - Mix Prototype and Singleton, ScopeProxy

    We have the following example: @SpringBootApplication public class In28minutesScopeApplication { pri ...

  5. [PureScript] Break up Expressions into Cases in PureScript using Simple Pattern Matching

    Pattern matching in functional programming languages is a way to break up expressions into individua ...

  6. ASP入门(十九)- SELECT 语句

    SELECT 语法 Access 中 SELECT 完整语法如下: SELECT [predicate] { * | table.* | [table.]field1 [AS alias1] [, [ ...

  7. 怎样让孩子爱上设计模式 —— 7.适配器模式(Adapter Pattern)

    怎样让孩子爱上设计模式 -- 7.适配器模式(Adapter Pattern) 标签: 设计模式初涉 概念相关 定义: 适配器模式把一个类的接口变换成client所期待的还有一种接口,从而 使原本因接 ...

  8. CMUSphinx Learn - Basic concepts of speech

    Basic concepts of speech Speech is a complex phenomenon. People rarely understand how is it produced ...

  9. 微信小程序 - 深度定义骨架屏(提示)

    此举每个页面必须创建对应的css样式,比较麻烦(但非常准确),推荐使用组件化的skeleton组件 原理很简单:知晓一下this.setData原理,就OK了,可能大家会因此了解到全屏加载loadin ...

  10. 微软BI 之SSRS 系列 - 报表中分组聚合中处理不规则层次结构的技巧(没有子元素的时候不展开, 删除+符号)

    分组聚合的展开和收起效果在SSRS Report中非常常用,并且有时还要处理一些比较特别的情况.比如分组合并时有的层次结构是不规则的,有的组有两层,遇到这种情况应该如何处理?   注意到下面的这个需求 ...