年后第一天上班,郭先生来说一说cannon.js的ConvexPolyhedron(多边形),cannon.js是一个物理引擎,内部通过连续的计算得到各个时间点的数据的状态,three.js的模型可以定时的应用这些状态来达到运动的效果,但是在应用的时候cannon数据模型和three模型一般都是不同的(而且多数情况下都是不一样的),因为更大的cannon数据模型会带来更多的性能问题,并且有的时候是没有必要的,比如说上一篇我们用圆柱来模拟保龄球瓶。但是有一些时候还是需要使用相对复杂的cannon多边形来对应three模型的,比如使用一个比较大的模型,那么它的细节就会很大程度的影响物理效果。那么我们来制作一个这样的场景,效果如下图,在线案例请点击博客原文。
1. cannon.js物理引擎多边形ConvexPolyhedron的构造函数
ConvexPolyhedron ( points faces )
构造函数一共需要两个参数,points是一个Vec3类型的数组,也就是包含所有点的数组,faces是一个组成每个小三角面的二维数组,这个就和THREE.Face3比较类似,比如说我们像制作出一个四面体,
var points = [ new CANNON.Vec3(0,0,0), new CANNON.Vec3(2,0,0), new CANNON.Vec3(0,2,0), new CANNON.Vec3(0,0,2) ]; var faces = [ [0,3,2], [0,1,3], [0,2,1], [1,2,3], ] var convex = new CANNON.ConvexPolyhedron( points faces );
如果了解three.js,那么这个东西是很好理解的。
2. 实现一个使用ConvexPolyhedron(多边形)的场景
场景如上图,包括一个ParametricGeometry、一个TorusGeometry和一个TorusKnotGeometry一共三个几何体,首先我们用three.js先制作出来三个几何体,我们既可以使用几何体制作出网格,也可以制作出cannon.js多边形
1. 制作three几何体
parametricGeom = new THREE.ParametricGeometry( (u, v, target) => { let x = Math.sin(Math.PI * 2 * u) * 10 * Math.abs(Math.sin(Math.PI * v)); let y = v * 20 - 10; let z = Math.cos(Math.PI * 2 * u) * 10 * Math.abs(Math.cos(Math.PI * v)); target.set(x, y, z); }, 30, 12 ); torusGeom = new THREE.TorusGeometry(5, 2, 16, 8); torusKnotGeom = new THREE.TorusKnotGeometry(5, 1.5, 80, 8, 2, 3); for(let i=0; i<parametricGeom.faces.length; i++) { color.setHSL(Math.random(), 0.5, 0.5); parametricGeom.faces[i].color.copy(color); } for(let i=0; i<torusGeom.faces.length; i++) { color.setHSL(Math.random(), 0.5, 0.5); torusGeom.faces[i].color.copy(color); } for(let i=0; i<torusKnotGeom.faces.length; i++) { color.setHSL(Math.random(), 0.5, 0.5); torusKnotGeom.faces[i].color.copy(color); }
这里就制作出了三个几何体,并为每个小三角面上了色。
2. 用既有的three几何体制作cannon多边形
let parametricShape = this.createConvex(parametricGeom); let torusShape = this.createConvex(torusGeom); let torusKnotShape = this.createConvex(torusKnotGeom); parametricBody = new CANNON.Body({ mass: 0, position: new CANNON.Vec3(-20, 6, 0), material: new CANNON.Material({friction: 0, restitution: 1}), shape: parametricShape }) torusBody = new CANNON.Body({ mass: 0, position: new CANNON.Vec3(0, 6, 0), material: new CANNON.Material({friction: 0, restitution: 1}), shape: torusShape }) torusKnotBody = new CANNON.Body({ mass: 0, position: new CANNON.Vec3(20, 6, 0), material: new CANNON.Material({friction: 0, restitution: 1}), shape: torusKnotShape }) world.addBody(parametricBody); world.addBody(torusBody); world.addBody(torusKnotBody); createConvex(geometry) { let vertices = []; let faces = []; for(let i=0; i<geometry.vertices.length; i++) { vertices.push(new CANNON.Vec3(geometry.vertices[i].x, geometry.vertices[i].y, geometry.vertices[i].z)); } for(let i=0; i<geometry.faces.length; i++) { faces.push([geometry.faces[i].a, geometry.faces[i].b, geometry.faces[i].c]); } return new CANNON.ConvexPolyhedron(vertices, faces); }
three的点和faces面存在geometry.vertices中和geometry.faces中,我们需要取出来并整理成我们想要的形式。然后下一步就是创建three.js网格,我们就不赘述了。
主要代码就是这么多。其实知道了cannon多边形的构造方法,我们很容易就制作出想要的多边形,这很大程度上丰富了物理世界。下一篇我们继续说一说cannon.js的约束
转载请注明地址:郭先生的博客