zoukankan      html  css  js  c++  java
  • [Havok] Havok Physics物理引擎的学习入门

    来源:http://www.cnblogs.com/hellohuan/archive/2008/09/03/1283410.html

    这几天在看Intel公司刚刚收购开放下载的havok物理引擎,有几点感受。为了研究havok,多么猥琐阴险狡诈的招都被我使了出来,在google上搜过n个正则关键字,去过专业的物理研究论坛,去了havok的官方网站,去了Interhavok论坛。最后没找到多少资料,没找到一个小例子。所以只得再havok SDKsDocDemo下面逛,看英文,猜代码意图。浑浑噩噩的过了两天。

    Havokdemo看过的肯定知道,框架做得相当复杂和诡异,其实并不适合去学习。The framework of the demos is very complex and esoteric. I do not want to understand these complex framework, Because I have a practical application in my framework, companies have the framework of the company, no one will want to make their own framework replaced for a physical engine.这是我发在havok论坛上的帖子。

    这也难怪,havok引擎刚刚开放下载,国内应用的都少,教程更是别提。我这几天算是过得比较痛苦,写个简单的入门文档,希望抛砖引玉,帮大家简单入入门,完全没有误人子弟的意思,大家别拍我~ ~我做的主要是havok的刚体碰撞。简单的20 * 20 的正方体自由下落在一平面上。

    首先,关于Havok的几个简单的物理概念:

    hkpWorld havok的物理世界场景 场景有其自己的属性,如万有引力等,每个havok的仿真场景可以有一个或者多个hkpWorld的实例。

    hkpRigidBody havok的刚体,刚体可以有自己的运动属性,并能通过setMotionType来设置修改。

    hkVisualDebugger 关于havok的一个很好的调试工具

    下面是整个程序的简单代码,没有用图形库输出图形,可以通过havok自带的工具VisualDebugger工具来查看刚体。省略了部分内存方面的代码,我也不是很明白。

    int main(int argc, const char** argv)
    {
    // 创建physics world 通过填充hkpWorldCinfo
    hkpWorld* physicsWorld;
    {
    // 创建物理世界:
    hkpWorldCinfo worldInfo;
    worldInfo.m_simulationType
    = hkpWorldCinfo::SIMULATION_TYPE_MULTITHREADED;
    worldInfo.m_gravity.
    set(0.0f, -9.8f, 0.0f);
    physicsWorld
    = new hkpWorld(worldInfo);
    }
    physicsWorld
    ->markForWrite();
    {
    hkpAgentRegisterUtil::registerAllAgents( physicsWorld
    ->getCollisionDispatcher() );
    }
    // 在这里创建我们的刚体模拟
    setupPhysics( physicsWorld );
    // 初始化VisualDebugger工具
    hkVisualDebugger* vdb = setupVisualDebugger(context);

    hkReal timestep
    = 1.f / 60.f;
    int numSteps = int(60.f / timestep);
    for ( int i = 0; i < numSteps; ++i )
    {
    // 可以得到刚体的一些实时信息,借助图形库进行渲染
    hkVector4 pos = g_ball->getPosition();
    printf(
    "[%f,%f,%f]"n", pos(0), pos(1), pos(2));
    }
    hkBaseSystem::quit();
    return 0;
    }

    void setupPhysics(hkpWorld* physicsWorld)
    {
    // 创建地面的 静态刚体
    {
    hkpRigidBodyCinfo boxInfo;
    hkVector4 boxSize(
    5.0f, 0.5f , 5.0f);
    hkpBoxShape
    * boxShape = new hkpBoxShape(boxSize);
    boxInfo.m_shape
    = boxShape;
    boxInfo.m_motionType
    = hkpMotion::MOTION_FIXED;
    boxInfo.m_position.
    set(0.0f, 0.0f, 0.0f);
    boxInfo.m_restitution
    = 0.9f;

    hkpRigidBody
    * floor = new hkpRigidBody(boxInfo);
    boxShape
    ->removeReference();
    g_ball
    = floor;
    physicsWorld
    ->addEntity(floor);
    floor
    ->removeReference();
    }
    // 创建 20 * 20 的盒子
    const hkReal boxDim = 0.2f; // This is the size of the cube side of the box
    const hkReal boxRadius = boxDim * 0.01f; // 盒子的角度 这个有问题 原来这个是大小
    const hkReal gapx = boxDim * 0.05f; // This is the gap betwen boxes 间距是盒子大小的多少比率
    const hkReal gapy = boxRadius;
    const hkReal heightOffGround = 10.0f; // This is the height of the pyramid off the gound
    int pyramidSize = 20; // This is the number of boxes along the base (also vertically)
    // 长方体的长宽
    hkReal extendedBoxDimX = boxDim + gapx;
    //hkReal extendedBoxDimY = boxDim + gapy;
    hkReal extendedBoxDimZ = boxDim + gapx;
    hkVector4 startPos(
    0.0f , heightOffGround + gapy + boxDim * 0.5f, 0.0f);
    // Build pyramid 构建
    {
    hkVector4 boxRadii(boxDim
    *.5f, boxDim *.5f, boxDim *.5f);
    hkpShape
    * boxShape = new hkpBoxShape( boxRadii , boxRadius );
    // 变成横向的一块下来 20 * 20的盒子
    for(int i=0; i<pyramidSize; i++)
    {
    // This constructs a row, from left to right 从左到右
    hkVector4 start(0, 0, extendedBoxDimZ * i);
    for(int j=0; j< pyramidSize; j++)
    {
    hkVector4 boxPos(start);
    hkVector4 shift(j
    * extendedBoxDimX, 0.0f, 0.0f);
    boxPos.setAdd4(boxPos, shift);
    boxPos.setAdd4(boxPos, startPos);

    hkpRigidBodyCinfo boxInfo;
    //盒子的质量
    boxInfo.m_mass = 100.0f;
    // calculate the correct inertia 惯性与质量有关
    hkReal d = boxInfo.m_mass * boxDim * boxDim / 6.0f;

    // for small boxes increase inertia slightly
    if ( boxRadius < 0.1f )
    {
    d
    *= 2.0f;
    if ( boxRadius < 0.03f )
    {
    d
    *= 2.0f;
    }
    }
    boxInfo.m_inertiaTensor.setDiagonal(d,d,d);
    boxInfo.m_shape
    = boxShape;
    boxInfo.m_motionType
    = hkpMotion::MOTION_DYNAMIC;
    boxInfo.m_position
    = boxPos;
    boxInfo.m_restitution
    = 0.5f; // 表面的弹力
    boxInfo.m_friction = 0.6f; // 表面的摩擦
    boxInfo.m_solverDeactivation = hkpRigidBodyCinfo::SOLVER_DEACTIVATION_MAX;
    hkpRigidBody
    * boxRigidBody = new hkpRigidBody(boxInfo);
    //将所有的刚体添加到世界中
    physicsWorld->addEntity( boxRigidBody );
    boxRigidBody
    ->removeReference();
    }
    }
    boxShape
    ->removeReference();
    }
    }

    我们只要在自己的代码中调用Havok API构建抽象的物理世界,抽象的物体,即给出物理世界的数据,就能直接通过hkVisualDebugger接口的socket连接发送世界数据到HavokVisualDebugger宿主程序,并在其可视化物理场景视图中显示出来。以下是在工具下的两张截图:


    demo框架中:

    程序的可运行代码:

    https://files.cnblogs.com/hellohuan/ConsoleMain.rar

    个性签名:做要做好,做到不三不四不如不做。
  • 相关阅读:
    安卓高级6 拍照或者从相册获取图片 并检测旋转角度或者更新画册扫描
    安卓高级6 玩转AppBarLayout,更酷炫的顶部栏 Toolbar
    安卓高级6 CoordinatorLayout
    安卓高级6 SnackBar
    android addCategory()等说明
    Eclipse如何解决启动慢?
    Java基础知识总结(绝对经典)
    java反射详解 三
    java反射详解 二
    java反射详解 一
  • 原文地址:https://www.cnblogs.com/hcbin/p/1860527.html
Copyright © 2011-2022 走看看