一文搞懂:【Havok】

简介: 一文搞懂:【Havok】

来源:


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


Havok的demo看过的肯定知道,框架做得相当复杂和诡异,其实并不适合去学习。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 [/span> 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)


{


// 创建地面的 静态刚体


{


//代码效果参考:http://hnjlyzjd.com/hw/wz_25482.html

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 间距是盒子大小的多少比率


//代码效果参考:http://hnjlyzjd.com/hw/wz_25480.html

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[/span>pyramidSize; i++)


{


// This constructs a row, from left to right 从左到右


hkVector4 start(0, 0, extendedBoxDimZ i);


for(int j=0; j[/span> 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 [/span> 0.1f )


{


d = 2.0f;


if ( boxRadius [/span> 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框架中:


程序的可运行代码:


个性签名:做要做好,做到不三不四不如不做。

相关文章
|
弹性计算 搜索推荐 网络安全
使用阿里云ECS搭建Perforce服务器用于Unreal(虚幻,Ue4)项目版本管理
游戏项目通常有很多二进制文件,如游戏贴图和各类游戏资产。使用面向文本文件的版本管理工具如git时,会导致诸多问题:1. 分支和版本的增加使项目迅速膨胀。2. 受到代码仓库的文件大小限制而无法上传文件。虚幻官方推荐面向文件的Perforce或SVN作为版本同步工具,本文介绍如何使用阿里云ECS搭建Perforce版本管理服务器的流程。
使用阿里云ECS搭建Perforce服务器用于Unreal(虚幻,Ue4)项目版本管理
|
消息中间件
如何rabbitMQ进行消费限速
如何rabbitMQ进行消费限速
613 0
|
7月前
|
存储 数据采集 数据管理
《深度揭秘:数据库表结构设计的艺术与科学》
在数字化时代,数据库是企业数据管理的核心,而表结构设计直接影响系统性能与稳定性。设计合理的数据库表结构需从六大方面入手:精准把握业务需求,确保设计贴合实际;遵循规范化原则,减少冗余并维护一致性;审慎选择数据类型,平衡存储与性能;确保数据完整性,保障数据质量;优化查询性能,提升响应速度;注重前瞻性与灵活性,适应未来变化。这是一项融合业务理解、技术考量与实践经验的综合性任务,对构建高效、稳定、可扩展的数据库系统至关重要。
190 25
|
移动开发 JavaScript 数据可视化
|
11月前
|
Android开发
Eclipse 修改字符集
Eclipse 修改字符集
155 2
|
12月前
|
设计模式 安全 Java
C# 一分钟浅谈:设计模式之单例模式
【10月更文挑战第9天】单例模式是软件开发中最常用的设计模式之一,旨在确保一个类只有一个实例,并提供一个全局访问点。本文介绍了单例模式的基本概念、实现方式(包括饿汉式、懒汉式和使用 `Lazy<T>` 的方法)、常见问题(如多线程和序列化问题)及其解决方案,并通过代码示例详细说明了这些内容。希望本文能帮助你在实际开发中更好地应用单例模式,提高代码质量和可维护性。
395 1
|
弹性计算 编解码 大数据
小鹏汽车核心业务迁移至阿里云倚天实例,节省20%算力成本
9月20日,在2024云栖大会上,小鹏汽车宣布车联网、官网、商城、大数据等核心业务已迁移至阿里云倚天实例,节省了超过20%的算力成本。
421 14
|
Rust 安全 程序员
使用Rust进行系统编程:安全性优势深度解析
【5月更文挑战第14天】Rust,Mozilla开发的系统编程语言,以其内存安全、并发支持和静态类型系统在系统编程中脱颖而出。所有权和借用检查机制消除内存错误,无锁并发原语提升安全性,静态类型减少运行时错误,最小权限原则降低权限风险。强大的社区支持和安全审计进一步确保了代码的安全性和稳定性,使Rust成为安全高效系统编程的理想选择。
|
存储 数据挖掘 Python
Python技术分享:实现选择文件或目录路径的方法
Python技术分享:实现选择文件或目录路径的方法
931 2
|
Linux 测试技术 iOS开发
Meson:现代的构建系统
Meson:现代的构建系统
709 0