UNPKG

@c-frame/aframe-physics-system

Version:

Physics system for A-Frame VR, built on Cannon.js & Ammo.js

170 lines (142 loc) 6.09 kB
/** * CANNON.shape2mesh * * Source: https://schteppe.github.io/cannon.js/build/cannon.demo.js * Author: @schteppe */ var CANNON = require('cannon-es'); CANNON.shape2mesh = function(body){ var obj = new THREE.Object3D(); function createBufferGeometry(positions, faces) { var geometry = new THREE.BufferGeometry(); geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) ); geometry.setIndex(faces); geometry.computeBoundingSphere(); return geometry; } for (var l = 0; l < body.shapes.length; l++) { var shape = body.shapes[l]; var mesh; switch(shape.type){ case CANNON.Shape.types.SPHERE: var sphere_geometry = new THREE.SphereGeometry( shape.radius, 8, 8); mesh = new THREE.Mesh( sphere_geometry, this.currentMaterial ); break; case CANNON.Shape.types.PARTICLE: mesh = new THREE.Mesh( this.particleGeo, this.particleMaterial ); var s = this.settings; mesh.scale.set(s.particleSize,s.particleSize,s.particleSize); break; case CANNON.Shape.types.PLANE: var geometry = new THREE.PlaneGeometry(10, 10, 4, 4); mesh = new THREE.Object3D(); var submesh = new THREE.Object3D(); var ground = new THREE.Mesh( geometry, this.currentMaterial ); ground.scale.set(100, 100, 100); submesh.add(ground); ground.castShadow = true; ground.receiveShadow = true; mesh.add(submesh); break; case CANNON.Shape.types.BOX: var box_geometry = new THREE.BoxGeometry( shape.halfExtents.x*2, shape.halfExtents.y*2, shape.halfExtents.z*2 ); mesh = new THREE.Mesh( box_geometry, this.currentMaterial ); break; case CANNON.Shape.types.CONVEXPOLYHEDRON: // Add vertices var positions = [] for (var i = 0; i < shape.vertices.length; i++) { var v = shape.vertices[i]; positions.push(v.x, v.y, v.z); } var faces = [] for(var i=0; i < shape.faces.length; i++){ var face = shape.faces[i]; // add triangles var a = face[0]; for (var j = 1; j < face.length - 1; j++) { var b = face[j]; var c = face[j + 1]; faces.push(a, b, c); } } var geo = createBufferGeometry(positions, faces); mesh = new THREE.Mesh( geo, this.currentMaterial ); break; case CANNON.Shape.types.HEIGHTFIELD: var v0 = new CANNON.Vec3(); var v1 = new CANNON.Vec3(); var v2 = new CANNON.Vec3(); var positions = []; var faces = []; for (var xi = 0; xi < shape.data.length - 1; xi++) { for (var yi = 0; yi < shape.data[xi].length - 1; yi++) { for (var k = 0; k < 2; k++) { shape.getConvexTrianglePillar(xi, yi, k===0); v0.copy(shape.pillarConvex.vertices[0]); v1.copy(shape.pillarConvex.vertices[1]); v2.copy(shape.pillarConvex.vertices[2]); v0.vadd(shape.pillarOffset, v0); v1.vadd(shape.pillarOffset, v1); v2.vadd(shape.pillarOffset, v2); positions.push( v0.x, v0.y, v0.z, v1.x, v1.y, v1.z, v2.x, v2.y, v2.z ); var i = positions.length / 3 - 3; faces.push(i, i+1, i+2); } } } var geometry = createBufferGeometry(positions, faces); mesh = new THREE.Mesh(geometry, this.currentMaterial); break; case CANNON.Shape.types.TRIMESH: var geometry = new THREE.BufferGeometry(); var v0 = new CANNON.Vec3(); var v1 = new CANNON.Vec3(); var v2 = new CANNON.Vec3(); var positions = []; var faces = []; for (var i = 0; i < shape.indices.length / 3; i++) { shape.getTriangleVertices(i, v0, v1, v2); positions.push( v0.x, v0.y, v0.z, v1.x, v1.y, v1.z, v2.x, v2.y, v2.z ); var j = positions.length / 3 - 3; faces.push(j, j+1, j+2); } var geometry = createBufferGeometry(positions, faces); mesh = new THREE.Mesh(geometry, this.currentMaterial); break; default: throw "Visual type not recognized: "+shape.type; } mesh.receiveShadow = true; mesh.castShadow = true; if(mesh.children){ for(var i=0; i<mesh.children.length; i++){ mesh.children[i].castShadow = true; mesh.children[i].receiveShadow = true; if(mesh.children[i]){ for(var j=0; j<mesh.children[i].length; j++){ mesh.children[i].children[j].castShadow = true; mesh.children[i].children[j].receiveShadow = true; } } } } var o = body.shapeOffsets[l]; var q = body.shapeOrientations[l]; mesh.position.set(o.x, o.y, o.z); mesh.quaternion.set(q.x, q.y, q.z, q.w); obj.add(mesh); } return obj; }; module.exports = CANNON.shape2mesh;