r3-legacy/src/game-lib-world.js

297 lines
7.8 KiB
JavaScript
Raw Normal View History

2016-10-14 12:32:53 +02:00
/**
* 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;
2016-10-28 11:47:50 +02:00
this.engine = engine;
2016-10-14 12:32:53 +02:00
this.engine.isNotCannonThrow();
2016-10-28 11:47:50 +02:00
this.instance = this.createInstance();
2016-10-14 12:32:53 +02:00
};
2016-10-28 11:47:50 +02:00
/**
* private
* @returns {GameLib.D3.World|GameLib.D3.Physics.World|*}
*/
GameLib.D3.World.prototype.createInstance = function() {
2016-10-14 12:32:53 +02:00
2016-10-28 11:47:50 +02:00
var instance = new this.engine.instance.World();
2016-10-14 12:32:53 +02:00
2016-10-28 11:47:50 +02:00
instance.broadphase = this.broadphase.instance;
2016-10-14 12:32:53 +02:00
2016-10-28 11:47:50 +02:00
instance.solver = this.solver.instance;
2016-10-14 12:32:53 +02:00
2016-10-28 11:47:50 +02:00
instance.gravity.x = this.gravity.x;
instance.gravity.y = this.gravity.y;
instance.gravity.z = this.gravity.z;
2016-10-14 12:32:53 +02:00
2016-10-28 11:47:50 +02:00
instance.name = this.name;
2016-10-14 12:32:53 +02:00
2016-10-28 11:47:50 +02:00
return instance;
2016-10-14 12:32:53 +02:00
};
2016-10-28 11:47:50 +02:00
/**
*
* @param rigidBody GameLib.D3.RigidBody
* @constructor
*/
GameLib.D3.World.prototype.addRigidBody = function(
rigidBody
2016-10-14 12:32:53 +02:00
) {
2016-10-28 11:47:50 +02:00
this.instance.addBody(rigidBody.instance);
2016-10-14 12:32:53 +02:00
};
2016-10-28 11:47:50 +02:00
/**
*
* @param vehicle (GameLib.D3.RigidBodyVehicle | GameLib.D3.RaycastVehicle)
* @constructor
*/
GameLib.D3.World.prototype.addVehicle = function(
2016-10-14 12:32:53 +02:00
vehicle // note: physics.vehicle
) {
2016-10-28 11:47:50 +02:00
vehicle.instance.addToWorld(this.world.instance);
2016-10-14 12:32:53 +02:00
};
2016-10-28 11:47:50 +02:00
GameLib.D3.World.prototype.step = function(
2016-10-14 12:32:53 +02:00
timeStep
) {
2016-10-28 11:47:50 +02:00
// todo: figure out, why this call to internal step is more stable for trimesh collisions.....
//this.worldObject.internalStep(timeStep);
//return;
2016-10-14 12:32:53 +02:00
2016-10-28 11:47:50 +02:00
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;
}
2016-10-14 12:32:53 +02:00
2016-10-28 11:47:50 +02:00
var timeSinceLastCall = now - this.lastCallTime;
2016-10-14 12:32:53 +02:00
2016-10-28 11:47:50 +02:00
this.instance.step(timeStep, timeSinceLastCall);
2016-10-14 12:32:53 +02:00
2016-10-28 11:47:50 +02:00
this.lastCallTime = now;
2016-10-14 12:32:53 +02:00
};
2016-10-18 13:37:38 +02:00
GameLib.D3.World.prototype.GetIndexedVertices = function(
2016-10-14 12:32:53 +02:00
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;
}
};
2016-10-28 11:47:50 +02:00
/**
* TODO: FIX
* @param triangleMeshShape
* @param normalLength
* @param scale
* @param opacity
* @param wireframeColor
* @returns {THREE.Mesh|this.meshes}
* @constructor
*/
GameLib.D3.World.GenerateWireframeViewMesh = function(
2016-10-14 12:32:53 +02:00
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;
};
2016-10-28 11:47:50 +02:00
/**
* TODO: FIX
* @param threeMesh
* @param mass
* @param friction
* @param createCollisionSubMeshes
* @param facesPerSubsection
* @param subsectionsToMerge
* @returns {Array}
* @constructor
*/
GameLib.D3.World.GenerateTriangleCollisionMesh = function(
2016-10-14 12:32:53 +02:00
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++;
}
};