cannon.js官网:http://www.cannonjs.org/
使用初衷:
开发微信3d小游戏,使用three.js做3d渲染,某些情况需要物理引擎。微信对游戏代码大小有限制,4M。虽然许多教程推荐Physijs,该引擎基于ammo.js,对three.js进行了封装,易用,但是在微信小游戏中,需要修改源码进行适配,适配运行时一般的手机不是一般得卡(未细研究,估计是由于该引擎使用webworker有关)。另外,该引擎代码量也较大。
相比之下,cannon.js 更为轻量——min版130k。向量、材质、形状等用起来也比较符合three.js的使用习惯。
开始
1.首先分别在画面世界和物理世界中实现要模拟的物体
//three.js 画个球
var geometry = new THREE.SphereGeometry(1, 32, 32);
var material = new THREE.MeshPhongMaterial({map: texture});
var mesh = new THREE.Mesh(geometry, material);
//cannon.js 模拟球
var body = new CANNON.Body({ mass: mass, material: new CANNON.Material({ friction: 0.5, restitution: 0.7}) });
var shape = new CANNON.Sphere(1);
body.addShape(shape);
cannon.js 构建物体的语法是不是和three.js很像,物体是body,需要形状shape,材质material。具体构建物体细节详见文档吧。。。
2.设置世界
three.js 世界初始化略。。
cannon:
let world = new CANNON.World();
world.gravity.set(0, -9.8, 0);
world.broadphase = new CANNON.NaiveBroadphase();
world.solver.iterations = 10;
3.让物理世界动起来,cannon和three类似,我们把两者放一起模拟
update:function () {
world.step(1 / 60);
//three.js 的 render
renderer.render(World.scene, World.camera);
}
4.让物体动起来。我们需要把three中的物体和物理世界的物体绑定。
var animate = function () {
update();
//这两行,让mesh的位置、四元数和body保持一致
mesh.position.copy(body.position);
mesh.quaternion.copy(body.quaternion);
requestAnimationFrame( animate );
};
animate();
基本用法就是这样。
小问题
1. cannon在构建box形状的物体时,
//若three中
var geo = new THREE.BoxGeometry(1,1,1);
//那么cannon中,形状使用的尺寸为半数
var shape = new CANNON.Box(new CANNON.Vec3(0.5,0.5,0.5));
2.想让物体有时受到重力,有时不受重力影响,这个需求的解决方案在Stack Overflow上看到有这么解决的:
//在需要的时候,在world.step()之前,将目标物体body在y轴方向上的重力抵消掉
update:function () {
body.force.y -= -9.8*body.mass;//-9.8为物理世界重力值
world.step(1 / 60);
renderer.render(World.scene, World.camera);
}
希望可以发现更好的方法。
to be continued..
刚开始用cannon,后续会继续踩坑。。