/** * World SuperSet - contains the custom world instance * @param id * @param name * @param engine * @param gravity * @param broadphase * @param solver * @param rigidBodies * @constructor */ GameLib.D3.World = function( id, name, engine, gravity, broadphase, solver, rigidBodies ) { this.id = id; this.name = name; if (typeof gravity == 'undefined') { gravity = new GameLib.D3.Vector3(0, -9.81, 0); } this.gravity = gravity; if (typeof broadphase == 'undefined') { broadphase = new GameLib.D3.Physics.Broadphase( null, 'broadPhaseNaive', GameLib.D3.Physics.BROADPHASE_TYPE_NAIVE ); } this.broadphase = broadphase; if (typeof solver == 'undefined') { solver = new GameLib.D3.Physics.Solver( null, 'GSSolver', GameLib.D3.Physics.GS_SOLVER ); } this.solver = solver; if (typeof rigidBodies == 'undefined') { rigidBodies = []; } this.rigidBodies = rigidBodies; this.engine = engine; this.engine.isNotCannonThrow(); this.instance = this.createInstance(); }; /** * private * @returns {GameLib.D3.World|GameLib.D3.Physics.World|*} */ GameLib.D3.World.prototype.createInstance = function() { var instance = new this.engine.instance.World(); instance.broadphase = this.broadphase.instance; instance.solver = this.solver.instance; instance.gravity.x = this.gravity.x; instance.gravity.y = this.gravity.y; instance.gravity.z = this.gravity.z; instance.name = this.name; return instance; }; /** * * @param rigidBody GameLib.D3.RigidBody * @constructor */ GameLib.D3.World.prototype.addRigidBody = function( rigidBody ) { this.instance.addBody(rigidBody.instance); }; /** * * @param vehicle (GameLib.D3.RigidBodyVehicle | GameLib.D3.RaycastVehicle) * @constructor */ GameLib.D3.World.prototype.addVehicle = function( vehicle // note: physics.vehicle ) { vehicle.instance.addToWorld(this.world.instance); }; GameLib.D3.World.prototype.step = function( timeStep ) { // todo: figure out, why this call to internal step is more stable for trimesh collisions..... //this.worldObject.internalStep(timeStep); //return; var now = performance.now() / 1000; if(!this.lastCallTime){ // last call time not saved, cant guess elapsed time. Take a simple step. this.instance.step(timeStep); this.lastCallTime = now; return; } var timeSinceLastCall = now - this.lastCallTime; this.instance.step(timeStep, timeSinceLastCall); this.lastCallTime = now; }; GameLib.D3.World.prototype.GetIndexedVertices = function( triangleMeshShape ) { if(this.engine.engineType == GameLib.D3.Physics.TYPE_CANNON) { return { vertices : triangleMeshShape.vertices, indices : triangleMeshShape.indices }; } else { // todo: implement this for other physics engines. return null; } }; /** * TODO: FIX * @param triangleMeshShape * @param normalLength * @param scale * @param opacity * @param wireframeColor * @returns {THREE.Mesh|this.meshes} * @constructor */ GameLib.D3.World.GenerateWireframeViewMesh = function( triangleMeshShape, normalLength, scale, opacity, wireframeColor ) { var geometryTHREE = new THREE.Geometry(); var wireframeTHREEMesh = new THREE.Mesh ( geometryTHREE, new THREE.MeshBasicMaterial({ color: wireframeColor ? wireframeColor : 0xfefefe, wireframe: true, opacity: opacity ? opacity : 0.5 }) ); var data = this.GetIndexedVertices(triangleMeshShape); for(var i = 0, l = data.vertices.length / 3; i < l; i++) { geometryTHREE.vertices.push(new THREE.Vector3(data.vertices[i * 3], data.vertices[i * 3 + 1], data.vertices[i * 3 + 2])); } for(var i = 0, l = data.indices.length / 3; i < l; i++) { var i0 = data.indices[i * 3]; var i1 = data.indices[i * 3 + 1]; var i2 = data.indices[i * 3 + 2]; geometryTHREE.faces.push(new THREE.Face3(i0, i1, i2)); // Create debug view for normals // Center point on the mesh itself var centroid = new THREE.Vector3() .add(geometryTHREE.vertices[i0]) .add(geometryTHREE.vertices[i1]) .add(geometryTHREE.vertices[i2]) .divideScalar(3); var normal = null; if(this.engine.engineType == GameLib.D3.Physics.TYPE_CANNON) { var normal = new this.physics.CANNON.Vec3(); triangleMeshShape.getNormal(i, normal); } else { // todo: calculate the normal for v0, v1 & v2 here. } var arrow = new THREE.ArrowHelper(new THREE.Vector3(normal.x, normal.y, normal.z), centroid, normalLength, new THREE.Color(normal.x, normal.y, normal.z)); wireframeTHREEMesh.add( arrow ); } wireframeTHREEMesh.scale.x = scale.x; wireframeTHREEMesh.scale.y = scale.y; wireframeTHREEMesh.scale.z = scale.z; return wireframeTHREEMesh; }; /** * TODO: FIX * @param threeMesh * @param mass * @param friction * @param createCollisionSubMeshes * @param facesPerSubsection * @param subsectionsToMerge * @returns {Array} * @constructor */ GameLib.D3.World.GenerateTriangleCollisionMesh = function( threeMesh, mass, // default = 0 friction, // default = 10 createCollisionSubMeshes, // boolean. default = false facesPerSubsection, // int. default = 0 subsectionsToMerge // int. default = 0 ) { var processedFaces = 0; var facesPerSubSection = facesPerSubsection || 0; var subMeshesToMerge = subsectionsToMerge || 0; var totalAmtFaces = threeMesh.geometry.faces.length; var facesToProcess = createCollisionSubMeshes ? (subMeshesToMerge * facesPerSubSection) : totalAmtFaces; var pairs = []; // output var vertices = []; var indicies = []; for(var i = 0; i <= totalAmtFaces; i++) { if(processedFaces == facesToProcess || i == totalAmtFaces) { var body = null; if(this.engine.engineType == GameLib.D3.Physics.TYPE_CANNON) { var meshShape = new this.physics.CANNON.Trimesh(vertices, indicies); meshShape.setScale(new this.physics.CANNON.Vec3(threeMesh.scale.x, threeMesh.scale.y, threeMesh.scale.z)); meshShape.updateAABB(); meshShape.updateNormals(); meshShape.updateEdges(); meshShape.updateBoundingSphereRadius(); meshShape.updateTree(); body = new this.physics.CANNON.Body({ mass: mass ? mass : 0, friction: friction ? friction : 10 }); body.addShape(meshShape); } else if (this.engine.engineType == GameLib.D3.Physics.Engine.TYPE_AMMO) { } else if (this.engine.engineType == GameLib.D3.Physics.Engine.TYPE_GOBLIN) { } pairs.push({ threeObject : createCollisionSubMeshes ? null : threeMesh, physicsObject : body }); vertices = []; indicies = []; processedFaces = 0; if(i == totalAmtFaces) { return pairs; } } var face = threeMesh.geometry.faces[i]; indicies.push(indicies.length); indicies.push(indicies.length); indicies.push(indicies.length); var v0 = threeMesh.geometry.vertices[face.a]; var v1 = threeMesh.geometry.vertices[face.b]; var v2 = threeMesh.geometry.vertices[face.c]; vertices.push(v0.x, v0.y, v0.z); vertices.push(v1.x, v1.y, v1.z); vertices.push(v2.x, v2.y, v2.z); processedFaces++; } };