作者: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物理引擎(源码)相关推荐

  1. Havok物理引擎与Unity3D的结合

    背景 在重度手游的研发过程当中,游戏中的车辆模拟,场景互动,特效展示等功能很多时候需要物理引擎的介入,以提供丰富的交互体验.目前3D手游的开发主要工具是使用Unity3D引擎,于是,如何在Unity3 ...

  2. Havok物理引擎_百度百科

    Havok 来源:百度百科  目录 Havok概述 Havok的组成 Havok Physic Havok FX Havok Animation Havok Behavior Havok Cloth ...

  3. Havok物理引擎不完全指南--从入门到放弃

    Havok物理引擎不完全指南–从入门到放弃 Havok概述 Havok,全称为Havok Game Dynamics SDK,译作Havok游戏动力开发包. 人们经常说到的,与PhysX相提并论的Ha ...

  4. havok物理引擎_统一中的Havok物理

    havok物理引擎 As announced at Game Developers Conference (GDC) 2019, Havok Physics is now available as a ...

  5. Havok物理引擎与Unity3D游戏的结合

    背景 在重度手游的研发过程当中,游戏中的车辆模拟,场景互动,特效展示等功能很多时候需要物理引擎的介入,以提供丰富的交互体验.目前3D手游的开发主要工具是使用Unity3D引擎,于是,如何在Unity3 ...

  6. havok物理引擎快速入门指南翻译

    花了2天时间完成了这个翻译, 需要有C++基础, 是通过haovk引擎做物理动画的基础. 到intel官方网站注册一个帐号可以免费获取havok SDK, 这是SDK中的一个文档的翻译. [翻译]Ha ...

  7. 正则表达式引擎 源码 c#_如何在C#中构建正则表达式引擎

    正则表达式引擎 源码 c# 更新: (Update:) See my Unicode enabled offering here 在这里查看启用Unicode的产品 先决条件 (Prerequisit ...

  8. cocos creator 游戏源码_Cocos Creator 3D引擎源码阅读之授之以渔 源码阅读

    源码阅读 动静之法 静 找到引擎源码的所在 在编辑器的右上角有一个大按钮 在VSCode里开打engine目录 引擎源码就在红色标中的cocos文件夹里,如下图 让我们来看一下引擎的目录结构 可以看到 ...

  9. 【Unity开源项目精选】Unity引擎源码的C#部分

    洪流学堂,让你快人几步.你好,我是你的技术探路者郑洪智,你可以叫我大智. 今天给你分享一个Unity开源项目,我们一起来看看吧! Unity引擎源码的C#部分 Unity 引擎和编辑器源代码的 C# ...

最新文章

  1. POJ - 3160 Father Christmas flymouse tanjar缩点构图+dfs
  2. iOS中代码支持多国语言切换的实现(Xcode5+iOS7)
  3. 查询空值中的注意事项
  4. BigDecimal总结
  5. 软件工程 Beta 阶段 团队贡献分数
  6. 是否可以手动运行一次logrotate检查?
  7. skywalking 6.1 简明指南
  8. 【原创】SSAS-引用维度与多数据源、多数据源视图引发分区错误
  9. 转换成CSV文件、Word、Excel、PDF等的方法--读取CSV文件的方法
  10. (附源码)基于PHP在线考试系统的设计与实现 毕业设计 032028
  11. 计算机视觉 CS231n Course Introduction
  12. 知行之桥EDI系统30天试用导航
  13. 阿里巴巴连接池mysql_阿里巴巴连接池(Druid)
  14. [苹果开发者账号]01 使用Apple Developer app注册提示:未能验证证件
  15. 使用php的curl爬去青果教务系统 课表(转)
  16. 山西3件国宝春节期间亮相《国家宝藏》
  17. 巴比特专访丨Afri谈退出以太坊:再见,“分手”后依然是朋友
  18. 【论文翻译 | AAAI-19】HACUD - 基于分层注意机制的属性异构信息网络现金用户检测
  19. 组装计算机教材杨凤霞教案,高一集合教案
  20. 下载神器IDM安装与使用(保姆级教程)

热门文章

  1. python channels 简介
  2. 显示硬件发展与视频开发系列(6)----显示标注与视频处理单元(3):APU
  3. (轉貼) 未來台北捷運路線圖 (News)
  4. 标准教室照明节能的思考
  5. 2013年06月新萝卜家园Ghost xp3装机版v2013◆年中推荐◆
  6. 互联网究竟带来中心化还是去中心化 那些赚钱的模式 探讨下互联网会把社会改造成什么样子,到底是中心化还是去中心化...
  7. 用意念获取资讯是痴人说梦吗?
  8. PS巧用蒙版另辟徯径mdash;mdash;再造雪景婚纱
  9. 哪一个python编译器?
  10. Pytorch基础知识(9)单目标分割