ThreeJS—物理引擎

ThreeJS物理引擎

对于物理引擎ThreeJS是没有对其进行封装的,官方中给出案例中直接使用AmmoJS(使用 Emscripten将Bullet物理引擎的C++源码直接转换成JS),渲染引擎和物理引擎结合来实现碰撞检测、自由落体等物理现象,其核心实质就是将物理引擎的计算结果更新到渲染引擎中

1.初始化物理引擎

var collisionConfiguration = new Ammo.btDefaultCollisionConfiguration();
var dispatcher = new Ammo.btCollisionDispatcher( collisionConfiguration );
var broadphase = new Ammo.btDbvtBroadphase();
var solver = new Ammo.btSequentialImpulseConstraintSolver();
var physicsWorld = new Ammo.btDiscreteDynamicsWorld( dispatcher, broadphase, solver, collisionConfiguration );// 创建物理世界
var physicsWorld.setGravity( new Ammo.btVector3( 0, - 6, 0 ) );// 重力

2.创建碰撞器和刚体

使用过Unity的同仁应该非常了解刚体和碰撞器,碰撞器包含很多种类型诸如立方体、球、胶囊体等等,在AmmoJS中也同样需要创建这些东西,这就是btBoxShape(碰撞器,可以有多种类型诸如btCylinderShape、btConeShape、btSphereShape)和btRigidBody(刚体)。

var sx = 50;
// 创建渲染对象
var threeObject = new THREE.Mesh( new THREE.BoxBufferGeometry( sx, sx, sx, 1, 1, 1 ),m
	aterial);
// 创建碰撞器形状
var shape = new Ammo.btBoxShape( new Ammo.btVector3( sx * 0.5, sx * 0.5, sx * 0.5 ) );
shape.setMargin( margin );
var mass = objectSize * 5;// 质量
var localInertia = new Ammo.btVector3( 0, 0, 0 );// 惯性
shape.calculateLocalInertia( mass, localInertia );
var transform = new Ammo.btTransform();// 变换组件,控制碰撞器的旋转和位置
transform.setIdentity();// 单位矩阵
var pos = threeObject.position;
// 根据渲染对象设置碰撞器的位置
transform.setOrigin( new Ammo.btVector3( pos.x, pos.y, pos.z ) );
// 撞见运动状态
var motionState = new Ammo.btDefaultMotionState( transform );
// 刚体创建信息
var rbInfo = new Ammo.btRigidBodyConstructionInfo( mass, motionState, shape, localInertia );
// 创建刚体
var body = new Ammo.btRigidBody( rbInfo );

尤其需要说明的是btDefaultMotionState和btTransform,该刚体的运动状态包含在btDefaultMotionState中,可以从中获取到btTransform对象,里面存放着该碰撞器在物理世界中实时的计算结果;我们需要为某种渲染对象比如立方体创建一个与之匹配的btBoxShape对象,使用btTransform对象控制该shape的变换来紧紧包围渲染对象,切记:当通过渲染对象的旋转平移来设置btTransform时,一定要将渲染对象转换到世界坐标系下再设置btTransform

3.同步物理引擎计算结果到渲染引擎

为渲染对象创建刚体之后,需要在帧函数中实时更新同步物理引擎计算结果到渲染引擎,即:将每个渲染对象的刚体对象运动状态实时更新到渲染对象上,获取刚体运动状态btDefaultMotionState中的btTransform对象,这个对象就是一个矩阵,里面包含着旋转平移缩放,从矩阵中解压出position、rotation为渲染对象赋值。

physicsWorld.stepSimulation( deltaTime, 10 );

var ms = objPhys.getMotionState();// 获取运动状态

var transformAux1 = new Ammo.btTransform();// 创建变换矩阵

if ( ms ) {

	ms.getWorldTransform( transformAux1 );// 从运动状态获取变换矩阵
	var p = transformAux1.getOrigin();// 获取位置
	var q = transformAux1.getRotation();// 获取旋转
	objThree.position.set( p.x(), p.y(), p.z() );// 设置渲染对象位置
	objThree.quaternion.set( q.x(), q.y(), q.z(), q.w() );// 设置渲染对象旋转

}

通过不断同步物理引擎数据到渲染引擎,来实现对碰撞结果的实时展现,也可以这样说:物理引擎计算数据驱动渲染引擎显示。另外btRigidBody刚体对象还可以设置是否受重力影响、在某个方向为该刚体施加一个力、设置刚体的速度等等,打个断点看看API基本就会用了。

注:如文章中有任何错误,请一定批评勘正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Superman_ztf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值