剖析three.js案例中物理引擎Ammo.js的使用方法,其中包含运动、碰撞、检测、自由落体、碰撞器、冻结、自定义更新等功能,有大量代码通过链接方式转到gitee,可以根据代码对照使用
主要剖析的是threejs中提供的ammo案例,相对于原本案例,本篇文章精简了一些代码,提取了一些方法,新增了一些可配置参数,并结合我上一篇文章three.js——镜头跟踪 做了一个小Demo。
先看一下效果
从图片中可以看出来,小球在落地时,触碰到人物模型的头部,改变了运动方向,后面人物模型行走时,可以踢球,改变球的运动速度。
场景
基础场景
基础场景参照three.js——镜头跟踪
物理引擎
引入ammo.js
html
复制代码
<script src="../node_modules/three/examples/jsm/libs/ammo.wasm.js"></script>
因为是demo所以直接在html入口文件通过链接方式引入的ammo.js
,项目中有需要也可以通过modlue模式在ts文件import
方式引用;
在使用ammo的文件中从window中提取该变量
typescript
复制代码
let Ammo = (window as any).Ammo
渲染
typescript
复制代码
Ammo().then(function (AmmoLib) { Ammo = AmmoLib; (window as any).Ammo = Ammo init(); animate(); });
threejs
的渲染要在物理引擎注册之后调用,然后在runder中更新物理引擎,渲染先放下,先从注册物理引擎开始
注册物理引擎
typescript
复制代码
export let physicsWorld: any export let dispatcher: any // 初始化物理引擎 export function initPhysics() { let Ammo = (window as any).Ammo // 注册碰撞器 let collisionConfiguration = new Ammo.btDefaultCollisionConfiguration(); // 注册碰撞器内容 之后的碰撞检测会使用到 dispatcher = new Ammo.btCollisionDispatcher(collisionConfiguration); let broadphase = new Ammo.btDbvtBroadphase(); let solver = new Ammo.btSequentialImpulseConstraintSolver(); // 注册物理世界 后续受物理作用的模型都需要放在这里,供ammp更新 physicsWorld = new Ammo.btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration); // 设置初始化重力,重力是向下作用力,所以在这里取反,其实初始值设置成负数是同样的 physicsWorld.setGravity(new Ammo.btVector3(0, - gravityConstant, 0)); }
除了必须的参数,setGravity
这个方法是经常用到的,设置重力,上述代码设置的是物理引擎的重力(引力),可以模拟地球引力、月球引力等,参数<0为向下作用力,参数>0为向上作用力即有重力的物体在这个物理世界,是做向上运动的,例子等讲到注册物理体的时候一起看一下