three.js cannon.js物理引擎之齿轮动画

郭先生今天继续说一说cannon.js物理引擎,并用之前已经学习过的知识实现一个小动画,知识点包括ConvexPolyhedron多边形、Shape几何体、Body刚体、HingeConstraint铰链约束等等知识。因为我之前用纯three.js 的THREEBSP实现过一个静态的齿轮,现在就想配合cannon.js让它的转动更加的符合实际而不是匀速转动。下面我们来说说我们要做的这个案例,这个小案例是由5个齿轮组成,左面两个是固定齿轮,最左面的是有动力的齿轮,我们可以控制它的速度,而右面三个齿轮是可以移动的,我们可以自由移动(有点类似于变速箱),嗯就是怎么简单。下面我们来说一说这个是怎么实现的,效果如下图,在线案例请点击博客原文。

three.js cannon.js物理引擎之齿轮动画

1. three.js 实现齿轮模型

three.js几何体在最前面我已经说过了,实现一个这样的模型(在不考虑引用模型的情况下),我们可以考虑直接使用Geometry来绘制或者向THREE.Group()对象中添加基础几何体来绘制,这里我们使用第二种方法。这里的思路就是使用ConvexGeometry凸包做出锯齿的齿,然后使用圆柱填充即可,如下图,

three.js cannon.js物理引擎之齿轮动画

下面是相关部分代码

var meshA, meshB, meshC, meshD, meshE; var bodyA, bodyB, bodyC, bodyD, bodyE; var axleA, axleB, axleC, axleD, axleE; var pos = [-8.5, 0], pos1 = [6.4, 8], pos2 = [8.5, 0], pos3 = [10.6, -13]; var radius1 = 2, radius2 = 4, radius3 = 6; var length = 0.5, thickness = 3; var sin375 = 0.075, cos375 = 0.997; var sin75 = 0.131, cos75 = 0.991; var sin15 = 0.259, cos15 = 0.966; var params = { positionX: 0, positionY: 0, speed: 1, } var triangleMesh1 = this.getTriangleMesh(sin15, cos15, radius1); var triangleMesh2 = this.getTriangleMesh(sin75, cos75, radius2); var triangleMesh3 = this.getTriangleMesh(sin375, cos375, radius3); meshA = new THREE.Group(); meshB = new THREE.Group(); meshC = new THREE.Group(); meshD = new THREE.Group(); meshE = new THREE.Group(); for(let i=0; i<24; i++) { let angle = Math.PI * 2 * i * 15 / 360; let itemMesh = triangleMesh2.clone(); itemMesh.rotation.z = angle; meshA.add(itemMesh.clone()); meshB.add(itemMesh.clone()); meshD.add(itemMesh.clone()); } for(let i=0; i<12; i++) { let angle = Math.PI * 2 * i * 30 / 360; let itemMesh = triangleMesh1.clone(); itemMesh.rotation.z = angle; meshC.add(itemMesh.clone()); } for(let i=0; i<48; i++) { let angle = Math.PI * 2 * i * 7.5 / 360; let itemMesh = triangleMesh3.clone(); itemMesh.rotation.z = angle; meshE.add(itemMesh.clone()); } let cylindMesh1 = new THREE.Mesh(new THREE.CylinderGeometry(radius1,radius1,thickness,32,1), new THREE.MeshNormalMaterial()); let cylindMesh2 = new THREE.Mesh(new THREE.CylinderGeometry(radius2,radius2,thickness,32,1), new THREE.MeshNormalMaterial()); let cylindMesh3 = new THREE.Mesh(new THREE.CylinderGeometry(radius3,radius3,thickness,32,1), new THREE.MeshNormalMaterial()); cylindMesh1.rotation.x = Math.PI / 2; cylindMesh2.rotation.x = Math.PI / 2; cylindMesh3.rotation.x = Math.PI / 2; meshA.add(cylindMesh2.clone()); meshB.add(cylindMesh2.clone()); meshC.add(cylindMesh1.clone()); meshD.add(cylindMesh2.clone()); meshE.add(cylindMesh3.clone()); let cylindMesh = new THREE.Mesh(new THREE.CylinderGeometry(0.5,0.5,10,6,1), new THREE.MeshPhongMaterial({color: 0xffcc77, flatShading: true})); cylindMesh.rotation.x = Math.PI / 2; meshA.add(cylindMesh.clone()); meshB.add(cylindMesh.clone()); meshC.add(cylindMesh.clone()); meshD.add(cylindMesh.clone()); meshE.add(cylindMesh.clone()); scene.add(meshA); scene.add(meshB); scene.add(meshC); scene.add(meshD); scene.add(meshE); getTriangleMesh(sin, cos, radius) { var pointsArr = [[sin * radius, cos * radius, thickness / 2], [sin * radius, cos * radius, -thickness / 2], [-sin * radius, cos * radius, thickness / 2], [-sin * radius, cos * radius, -thickness / 2], [0, radius + length, thickness / 2], [0, radius + length, -thickness / 2]]; var points = pointsArr.map(d => new THREE.Vector3(d[0],d[1],d[2])); var triangle = new ConvexGeometry(points); return new THREE.Mesh(triangle, new THREE.MeshNormalMaterial());; },

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpgxxd.html