zoukankan      html  css  js  c++  java
  • 转: 在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: "<<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;

    }

  • 相关阅读:
    geoserver发布地图服务WMTS
    geoserver发布地图服务WMS
    geoserver安装部署步骤
    arcgis api 3.x for js 入门开发系列十四最近设施点路径分析(附源码下载)
    arcgis api 3.x for js 入门开发系列十三地图最短路径分析(附源码下载)
    cesium 之自定义气泡窗口 infoWindow 后续优化篇(附源码下载)
    arcgis api 3.x for js 入门开发系列十二地图打印GP服务(附源码下载)
    arcgis api 3.x for js 入门开发系列十一地图统计图(附源码下载)
    arcgis api 3.x for js 入门开发系列十叠加 SHP 图层(附源码下载)
    arcgis api 3.x for js入门开发系列九热力图效果(附源码下载)
  • 原文地址:https://www.cnblogs.com/skyofbitbit/p/4083080.html
Copyright © 2011-2022 走看看