diff --git a/bak/game-lib-d3-broadphase.js b/bak/game-lib-d3-broadphase.js deleted file mode 100644 index eb2bf5d..0000000 --- a/bak/game-lib-d3-broadphase.js +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Physics Broadphase Superset - * @param id - * @param name String - * @param broadphaseType Number - * @param engine GameLib.D3.Engine - * @constructor - */ -GameLib.D3.Broadphase = function Broadphase( - id, - name, - broadphaseType, - engine -) { - this.id = id; - - if (typeof name == 'undefined') { - name = 'broadphase-' + broadphaseType; - } - this.name = name; - - if (typeof broadphaseType == 'undefined') { - broadphaseType = GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE; - } - this.broadphaseType = broadphaseType; - - this.engine = engine; - this.engine.isNotCannonThrow(); - - this.instance = this.createInstance(); -}; - -/** - * Creates a custom Broadphase instance based on the engine type - */ -GameLib.D3.Broadphase.prototype.createInstance = function() { - - var instance = null; - - if (this.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE) { - instance = new this.engine.instance.NaiveBroadphase(); - } else if (this.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID) { - instance = new this.engine.instance.GridBroadphase(); - } else if (this.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP) { - instance = new this.engine.instance.SAPBroadphase(); - } else { - console.warn('Unsupported broadphase type: ' + this.broadphaseType); - throw new Error('Unsupported broadphase type: ' + this.broadphaseType); - } - - return instance; -}; - -GameLib.D3.Broadphase.prototype.toApiBroadphase = function() { - return null; -}; - -/** - * Broadphase Types - * @type {number} - */ -GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE = 0x1; -GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID = 0x2; -GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP = 0x3; \ No newline at end of file diff --git a/src/game-lib-a-component-a.js b/src/game-lib-a-component-a.js index 97863f2..c103045 100644 --- a/src/game-lib-a-component-a.js +++ b/src/game-lib-a-component-a.js @@ -119,6 +119,10 @@ GameLib.Component.COMPONENT_ENTITY = 0x20; GameLib.Component.COMPONENT_MESH_SPHERE = 0x21; GameLib.Component.COMPONENT_MESH_PLANE = 0x22; GameLib.Component.COMPONENT_MESH_CURVE = 0x23; +GameLib.Component.COMPONENT_WORLD = 0x24; +GameLib.Component.COMPONENT_BROADPHASE = 0x25; +GameLib.Component.COMPONENT_SOLVER = 0x25; +GameLib.Component.COMPONENT_RIGID_BODY = 0x26; /** * Returns string name for component number @@ -163,6 +167,9 @@ GameLib.Component.GetComponentName = function(number) { case 0x21 : return 'GameLib.D3.Mesh.Sphere'; case 0x22 : return 'GameLib.D3.Mesh.Plane'; case 0x23 : return 'GameLib.D3.Mesh.Curve'; + case 0x24 : return 'GameLib.D3.World'; + case 0x25 : return 'GameLib.D3.Broadphase'; + case 0x26 : return 'GameLib.D3.RigidBody'; break; } }; diff --git a/src/game-lib-d3-api-broadphase.js b/src/game-lib-d3-api-broadphase.js new file mode 100644 index 0000000..9822881 --- /dev/null +++ b/src/game-lib-d3-api-broadphase.js @@ -0,0 +1,53 @@ +/** + * Raw Broadphase API object - should always correspond with the Broadphase Schema + * @param id + * @param name + * @param broadphaseType + * @param parentEntity + * @constructor + */ +GameLib.D3.API.Broadphase = function( + id, + name, + broadphaseType, + parentEntity +) { + + if (GameLib.Utils.UndefinedOrNull(id)) { + id = GameLib.Utils.RandomId(); + } + this.id = id; + + if (GameLib.Utils.UndefinedOrNull(name)) { + name = 'Broadphase (' + this.id + ')'; + } + this.name = name; + + if (GameLib.Utils.UndefinedOrNull(broadphaseType)) { + broadphaseType = GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE; + } + this.broadphaseType = broadphaseType; + + if (GameLib.Utils.UndefinedOrNull(parentEntity)) { + parentEntity = null; + } + this.parentEntity = parentEntity; +}; + +GameLib.D3.API.Broadphase.prototype = Object.create(GameLib.Component.prototype); +GameLib.D3.API.Broadphase.prototype.constructor = GameLib.D3.API.Broadphase; + +/** + * Creates an API Broadphase from an Object Broadphase + * @param objectBroadphase + * @constructor + */ +GameLib.D3.API.Broadphase.FromObject = function(objectBroadphase) { + return new GameLib.D3.API.Broadphase( + objectBroadphase.id, + objectBroadphase.name, + objectBroadphase.broadphaseType, + objectBroadphase.parentEntity + ); +}; + diff --git a/src/game-lib-d3-api-world.js b/src/game-lib-d3-api-world.js new file mode 100644 index 0000000..839977a --- /dev/null +++ b/src/game-lib-d3-api-world.js @@ -0,0 +1,77 @@ +/** + * Raw World API object - should always correspond with the World Schema + * @param id + * @param name + * @param gravity + * @param broadphase + * @param solver + * @param rigidBodies + * @param parentEntity + * @constructor + */ +GameLib.D3.API.World = function( + id, + name, + gravity, + broadphase, + solver, + rigidBodies, + parentEntity +) { + + if (GameLib.Utils.UndefinedOrNull(id)) { + id = GameLib.Utils.RandomId(); + } + this.id = id; + + if (GameLib.Utils.UndefinedOrNull(name)) { + name = 'World (' + this.id + ')'; + } + this.name = name; + + if (GameLib.Utils.UndefinedOrNull(gravity)) { + gravity = -9.81; + } + this.gravity = gravity; + + if (GameLib.Utils.UndefinedOrNull(broadphase)) { + broadphase = null; + } + this.broadphase = broadphase; + + if (GameLib.Utils.UndefinedOrNull(solver)) { + solver = null; + } + this.solver = solver; + + if (GameLib.Utils.UndefinedOrNull(rigidBodies)) { + rigidBodies = []; + } + this.rigidBodies = rigidBodies; + + if (GameLib.Utils.UndefinedOrNull(parentEntity)) { + parentEntity = null; + } + this.parentEntity = parentEntity; +}; + +GameLib.D3.API.World.prototype = Object.create(GameLib.Component.prototype); +GameLib.D3.API.World.prototype.constructor = GameLib.D3.API.World; + +/** + * Creates an API World from an Object World + * @param objectWorld + * @constructor + */ +GameLib.D3.API.World.FromObject = function(objectWorld) { + return new GameLib.D3.API.World( + objectWorld.id, + objectWorld.name, + objectWorld.gravity, + objectWorld.broadphase, + objectWorld.solver, + objectWorld.rigidBodies, + objectWorld.parentEntity + ); +}; + diff --git a/src/game-lib-d3-broadphase.js b/src/game-lib-d3-broadphase.js new file mode 100644 index 0000000..7b66ff0 --- /dev/null +++ b/src/game-lib-d3-broadphase.js @@ -0,0 +1,112 @@ +/** + * Broadphase Runtime + * @param physics GameLib.D3.Graphics + * @param apiBroadphase GameLib.D3.API.Broadphase + * @constructor + */ +GameLib.D3.Broadphase = function ( + physics, + apiBroadphase +) { + + this.physics = physics; + this.physics.isNotCannonThrow(); + + if (GameLib.Utils.UndefinedOrNull(apiBroadphase)) { + apiBroadphase = {}; + } + + if (apiBroadphase instanceof GameLib.D3.Broadphase) { + return apiBroadphase; + } + + GameLib.D3.API.Broadphase.call( + this, + apiBroadphase.id, + apiBroadphase.name, + apiBroadphase.broadphaseType, + apiBroadphase.parentEntity + ); + + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_BROADPHASE, + { + } + ); +}; + +GameLib.D3.Broadphase.prototype = Object.create(GameLib.D3.API.Broadphase.prototype); +GameLib.D3.Broadphase.prototype.constructor = GameLib.D3.Broadphase; + +/** + * + * @returns {*} + */ +GameLib.D3.Broadphase.prototype.createInstance = function() { + + + //todo + var instance = null; + + if (this.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE) { + instance = new this.engine.instance.NaiveBroadphase(); + } else if (this.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID) { + instance = new this.engine.instance.GridBroadphase(); + } else if (this.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP) { + instance = new this.engine.instance.SAPBroadphase(); + } else { + console.warn('Unsupported broadphase type: ' + this.broadphaseType); + throw new Error('Unsupported broadphase type: ' + this.broadphaseType); + } + + return instance; +}; + +/** + * + */ +GameLib.D3.Broadphase.prototype.updateInstance = function() { + //todo +}; + +/** + * GameLib.D3.Broadphase to GameLib.D3.API.Broadphase + * @returns {GameLib.D3.API.Broadphase} + */ +GameLib.D3.Broadphase.prototype.toApiObject = function() { + + var apiBroadphase = new GameLib.D3.API.Broadphase( + this.id, + this.name, + this.broadphaseType, + GameLib.Utils.IdOrNull(this.parentEntity) + ); + + return apiBroadphase; +}; + +/** + * GameLib.D3.Broadphase from Object Broadphase + * @param graphics + * @param objectComponent + * @returns {GameLib.D3.Broadphase} + * @constructor + */ +GameLib.D3.Broadphase.FromObject = function(graphics, objectComponent) { + + var apiBroadphase = GameLib.D3.API.Broadphase.FromObject(objectComponent); + + return new GameLib.D3.Broadphase( + graphics, + apiBroadphase + ); +}; + +/** + * Broadphase Types + * @type {number} + */ +GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE = 0x1; +GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID = 0x2; +GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP = 0x3; \ No newline at end of file diff --git a/src/game-lib-d3-world.js b/src/game-lib-d3-world.js new file mode 100644 index 0000000..a37c900 --- /dev/null +++ b/src/game-lib-d3-world.js @@ -0,0 +1,873 @@ +/** + * World SuperSet - contains the custom world instance + * @constructor + * @param physics + * @param apiWorld + */ +GameLib.D3.World = function( + physics, + apiWorld +) { + + this.physics = physics; + this.physics.isNotCannonThrow(); + + if (GameLib.Utils.UndefinedOrNull(apiWorld)) { + apiWorld = {}; + } + + if (apiWorld instanceof GameLib.D3.World) { + return apiWorld; + } + + GameLib.D3.API.World.call( + this, + apiWorld.id, + apiWorld.name, + apiWorld.gravity, + apiWorld.broadphase, + apiWorld.solver, + apiWorld.rigidBodies, + apiWorld.parentEntity + ); + + if (this.broadphase instanceof GameLib.D3.API.Broadphase) { + return new GameLib.D3.Broadphase( + this.physics, + this.broadphase + ); + } + + if (this.solver instanceof GameLib.D3.API.Solver) { + return new GameLib.D3.Solver( + this.physics, + this.broadphase + ); + } + + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_WORLD, + { + 'broadphase' : [GameLib.D3.Broadphase], + 'solver' : [GameLib.D3.Solver], + 'rigidBodies' : [GameLib.D3.RigidBody] + } + ); +}; + +GameLib.D3.World.prototype = Object.create(GameLib.D3.API.World.prototype); +GameLib.D3.World.prototype.constructor = GameLib.D3.World; + +/** + * private + * @returns {GameLib.D3.World|GameLib.D3.Physics.World|*} + */ +GameLib.D3.World.prototype.createInstance = function() { + var instance = new CANNON.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; + return instance; +}; + +/** + * + */ +GameLib.D3.World.prototype.updateInstance = function() { + this.instance.broadphase = this.broadphase.instance; + this.instance.solver = this.solver.instance; + this.instance.gravity.x = this.gravity.x; + this.instance.gravity.y = this.gravity.y; + this.instance.gravity.z = this.gravity.z; +}; + +/** + * GameLib.D3.World to GameLib.D3.API.World + * @returns {GameLib.D3.API.World} + */ +GameLib.D3.World.prototype.toApiObject = function() { + + var apiWorld = new GameLib.D3.API.World( + this.id, + this.name, + this.gravity.toApiObject(), + this.GameLib.Utils.IdOrNull(this.broadphase), + this.GameLib.Utils.IdOrNull(this.solver), + this.rigidBodies.map(function(body){ + return GameLib.Utils.IdOrNull(body); + }), + GameLib.Utils.IdOrNull(this.parentEntity) + ); + + return apiWorld; +}; + +/** + * GameLib.D3.World from Object World + * @param graphics + * @param objectComponent + * @returns {GameLib.D3.World} + * @constructor + */ +GameLib.D3.World.FromObject = function(graphics, objectComponent) { + var apiWorld = GameLib.D3.API.World.FromObject(objectComponent); + return new GameLib.D3.World( + graphics, + apiWorld + ); +}; + +GameLib.D3.World.prototype.step = function(deltaTime) { + + if (this.isCannon) { + this.instance.step(deltaTime); + } + + // if (this.isOimo) { + // //TODO: oimo + // } + +}; + +// +// GameLib.D3.World.prototype.step = function( +// fixedStep, +// dtStep +// ) { +// +// }; +// +// GameLib.D3.World.prototype.generateWireframeViewTriangleMesh = function( +// graphics, +// triangleMeshShape, +// normalLength, +// scale, +// opacity, +// wireframeColor +// ) { +// graphics.isNotThreeThrow(); +// this.engine.isNotCannonThrow(); +// +// if(typeof normalLength == 'undefined') { +// normalLength = 10; +// } +// +// if(typeof scale == 'undefined') { +// scale = new graphics.instance.Vector3(1, 1, 1); +// } +// +// if(typeof opacity == 'undefined') { +// opacity = 0.5; +// } +// +// if(typeof wireframeColor == 'undefined') { +// wireframeColor = 0xfefefe; +// } +// +// var graphicsGeometry = new graphics.instance.Geometry(); +// +// var wireframeMesh = new graphics.instance.Mesh( +// graphicsGeometry, +// new graphics.instance.MeshBasicMaterial({ +// color: wireframeColor, +// wireframe: true, +// opacity: opacity +// }) +// ); +// +// for(var v = 0, l = triangleMeshShape.instance.vertices.length / 3; v < l; ++v) { +// graphicsGeometry.vertices.push( +// new graphics.instance.Vector3( +// triangleMeshShape.instance.vertices[v * 3], +// triangleMeshShape.instance.vertices[v * 3 + 1], +// triangleMeshShape.instance.vertices[v * 3 + 2] +// ) +// ); +// } +// +// for(var i = 0, l = triangleMeshShape.instance.indices.length / 3; i < l; ++i) { +// var i0 = triangleMeshShape.instance.indices[i * 3]; +// var i1 = triangleMeshShape.instance.indices[i * 3 + 1]; +// var i2 = triangleMeshShape.instance.indices[i * 3 + 2]; +// +// graphicsGeometry.faces.push( +// new graphics.instance.Face3( +// i0, +// i1, +// i2 +// ) +// ); +// +// // Center point on the current triangle +// +// var centroid = new graphics.instance.Vector3() +// .add(graphicsGeometry.vertices[i0]) +// .add(graphicsGeometry.vertices[i1]) +// .add(graphicsGeometry.vertices[i2]) +// .divideScalar(3); +// +// // Get the normal from the mesh shape itself +// var normal = new this.engine.instance.Vec3(); +// triangleMeshShape.instance.getNormal(i , normal); +// +// var arrow = new graphics.instance.ArrowHelper( +// new graphics.instance.Vector3( +// normal.x, +// normal.y, +// normal.z +// ), +// centroid, +// normalLength, +// new graphics.instance.Color( +// normal.x, +// normal.y, +// normal.z +// ) +// ); +// wireframeMesh.add( arrow ); +// } +// +// wireframeMesh.scale.x = scale.x; +// wireframeMesh.scale.y = scale.y; +// wireframeMesh.scale.z = scale.z; +// +// return wireframeMesh; +// }; +// +// /** +// * @param convexPolyMeshShape GameLib.D3.Shape +// * @param normalLength Number +// * @param scale GameLib.API.Vector3 +// * @param opacity Number +// * @param wireframeColor HexCode +// * @param graphics THREE +// * @returns {THREE.Mesh|this.meshes} +// * @constructor +// */ +// GameLib.D3.World.prototype.generateWireframeViewConvexPolyMesh = function( +// graphics, +// convexPolyMeshShape, +// normalLength, +// scale, +// opacity, +// wireframeColor +// ) { +// graphics.isNotThreeThrow(); +// this.engine.isNotCannonThrow(); +// +// if(typeof normalLength == 'undefined') { +// normalLength = 10; +// } +// +// if(typeof scale == 'undefined') { +// scale = new graphics.instance.Vector3(1, 1, 1); +// } +// +// if(typeof opacity == 'undefined') { +// opacity = 0.5; +// } +// +// if(typeof wireframeColor == 'undefined') { +// wireframeColor = 0xfefefe; +// } +// +// +// var graphicsGeometry = new graphics.instance.Geometry(); +// var wireframeMesh = new graphics.instance.Mesh( +// graphicsGeometry, +// new graphics.instance.MeshBasicMaterial({ +// color: wireframeColor, +// wireframe: true, +// opacity: opacity +// }) +// ); +// +// for(var i = 0, l = convexPolyMeshShape.instance.vertices.length; i < l; i++) { +// var vertex = convexPolyMeshShape.instance.vertices[i]; +// graphicsGeometry.vertices.push(new graphics.instance.Vector3(vertex.x, vertex.y, vertex.z)); +// } +// +// for(var i = 0, l = convexPolyMeshShape.instance.faces.length; i < l; i++) { +// var face = convexPolyMeshShape.instance.faces[i]; +// +// var i0 = face[0]; +// var i1 = face[1]; +// var i2 = face[2]; +// +// graphicsGeometry.faces.push(new graphics.instance.Face3(i0, i1, i2)); +// +// // Center point on the current triangle +// var centroid = new graphics.instance.Vector3() +// .add(graphicsGeometry.vertices[i0]) +// .add(graphicsGeometry.vertices[i1]) +// .add(graphicsGeometry.vertices[i2]) +// .divideScalar(3); +// +// var normalVec3 = convexPolyMeshShape.instance.faceNormals[i]; +// var normal = new graphics.instance.Vector3( +// normalVec3.x, +// normalVec3.y, +// normalVec3.z +// ); +// +// var arrow = new graphics.instance.ArrowHelper( +// normal, +// centroid, +// normalLength, +// new graphics.instance.Color( +// normal.x, +// normal.y, +// normal.z +// ) +// ); +// +// wireframeMesh.add( arrow ); +// } +// +// wireframeMesh.scale.x = scale.x; +// wireframeMesh.scale.y = scale.y; +// wireframeMesh.scale.z = scale.z; +// +// return wireframeMesh; +// }; +// +// /** +// * @param graphics GameLib.D3.Graphics +// * @param graphicsMesh THREE.Mesh +// * @param mass Number +// * @param friction Number +// * @param createCollisionSubMeshes Boolean +// * @param facesPerSubsection Number +// * @param subsectionsToMerge Number +// * @returns {Object} +// * @constructor +// */ +// GameLib.D3.World.prototype.generateTriangleMeshShapeDivided = function( +// graphics, +// graphicsMesh, +// mass, +// friction, +// createCollisionSubMeshes, +// facesPerSubsection, +// subsectionsToMerge +// ) { +// graphics.isNotThreeThrow(); +// this.engine.isNotCannonThrow(); +// +// if(mass == null || typeof mass == 'undefined') { +// mass = 0; +// } +// +// if(friction == null || typeof friction == 'undefined') { +// friction = 10; +// } +// +// if(createCollisionSubMeshes == null || typeof createCollisionSubMeshes == 'undefined') { +// createCollisionSubMeshes = false; +// } +// +// var processedFaces = 0; +// var facesPerSubSection = facesPerSubsection || 0; +// var subMeshesToMerge = subsectionsToMerge || 0; +// var totalAmtFaces = graphicsMesh.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; +// +// var meshShape = new this.engine.instance.Trimesh(vertices, indicies); +// +// meshShape.setScale(new this.engine.instance.Vec3( +// graphicsMesh.scale.x, +// graphicsMesh.scale.y, +// graphicsMesh.scale.z +// )); +// +// meshShape.updateAABB(); +// meshShape.updateNormals(); +// meshShape.updateEdges(); +// meshShape.updateBoundingSphereRadius(); +// meshShape.updateTree(); +// +// body = new this.engine.instance.Body({ +// mass: mass, +// friction: friction +// }); +// body.addShape(meshShape); +// +// pairs.push({ +// threeObject : createCollisionSubMeshes ? null : graphicsMesh, +// physicsObject : body +// }); +// +// vertices = []; +// indicies = []; +// processedFaces = 0; +// +// if(i == totalAmtFaces) { +// return pairs; +// } +// } +// +// var face = graphicsMesh.geometry.faces[i]; +// indicies.push(indicies.length); +// indicies.push(indicies.length); +// indicies.push(indicies.length); +// +// var v0 = graphicsMesh.geometry.vertices[face.a]; +// var v1 = graphicsMesh.geometry.vertices[face.b]; +// var v2 = graphicsMesh.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++; +// } +// }; +// +// GameLib.D3.World.prototype.generateConvexPolyShape = function( +// graphics, +// mesh +// ) { +// var processedFaces = 0; +// var facesPerSubSection = 2; // *2 -> SUBDIVISION MESH +// var subMeshesToMerge = 4; // *2 -> SUBDIVISION MESH +// var facesToProcess = subMeshesToMerge * facesPerSubSection; +// +// var vertices = []; +// var indicies = []; +// +// for(var i = 0; i <= mesh.geometry.faces.length; i++) { +// if(processedFaces == facesToProcess || i == mesh.geometry.faces.length) { +// +// // try and create convex poly........... +// var convexIndices = []; +// for(var index = 0; index < indicies.length / 3; index++) { +// convexIndices.push([ indicies[index * 3], indicies[index * 3 + 1], indicies[index * 3 + 2] ]); +// } +// +// var convexVertices = []; +// for(var vert = 0; vert < vertices.length / 3; vert++) { +// convexVertices[vert] = new CANNON.Vec3(vertices[vert * 3] * mesh.scale.x, vertices[vert * 3 + 1] * mesh.scale.y, vertices[vert * 3 + 2] * mesh.scale.z); +// } +// +// var meshShape = new GameLib.D3.Shape(this.engine, GameLib.D3.Shape.SHAPE_TYPE_CONVEX_HULL, {x:1,y:1,z:1},convexVertices, convexIndices); +// +// var body = new GameLib.D3.RigidBody(this.engine, 0, 1); +// body.addShape(meshShape); +// +// this.addRigidBody(body); +// +// vertices = []; +// indicies = []; +// processedFaces = 0; +// +// console.log("SPLIT MESH TO CONVEX POLY"); +// +// if(i == mesh.geometry.faces.length) { +// break; +// } +// } +// +// var face = mesh.geometry.faces[i]; +// indicies.push(indicies.length); +// indicies.push(indicies.length); +// indicies.push(indicies.length); +// +// var v0 = mesh.geometry.vertices[face.a]; +// var v1 = mesh.geometry.vertices[face.b]; +// var v2 = mesh.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++; +// } +// +// }; +// +// /** +// * @param graphics GameLib.D3.Graphics +// * @param graphicsMesh THREE.Mesh +// * @returns {GameLib.D3.Shape} +// * @constructor +// */ +// GameLib.D3.World.prototype.generateTriangleMeshShape = function( +// graphics, +// graphicsMesh +// ) { +// +// // - - - - - - - - - - - - - - - - - - - - - - - - - +// // Note: I did not test this yet with the API data. +// // - - - - - - - - - - - - - - - - - - - - - - - - - +// +// var scaledVertices = []; +// for(var i = 0, l = graphicsMesh.geometry.vertices.length; i < l; i++) { +// +// var vertex = graphicsMesh.geometry.vertices[i]; +// +// scaledVertices.push(new this.engine.instance.Vec3( +// vertex.x * graphicsMesh.scale.x, +// vertex.y * graphicsMesh.scale.y, +// vertex.z * graphicsMesh.scale.z +// )); +// } +// +// var triangleFaces = []; +// for(var f = 0, fl = graphicsMesh.geometry.faces.length; f < fl; f++) { +// var i0 = graphicsMesh.geometry.faces[f].a; +// var i1 = graphicsMesh.geometry.faces[f].b; +// var i2 = graphicsMesh.geometry.faces[f].c; +// +// triangleFaces.push([ +// i0, i1, i2 +// ]); +// } +// +// // - - - - - - - - - - - - - - - - - - - +// // Create collision mesh +// // - - - - - - - - - - - - - - - - - - - +// +// var reindexedFaces = {}; +// var vertices = []; +// var faces = []; +// +// var processedFaces = 0; +// var totalFacesToProcess = triangleFaces.length; +// var flLastIndex = 0; +// +// for(var f = 0; f < totalFacesToProcess; f++) { +// +// var i0 = triangleFaces[f][0]; +// var i1 = triangleFaces[f][1]; +// var i2 = triangleFaces[f][2]; +// +// if(typeof reindexedFaces[i0] === 'undefined') { +// vertices.push(scaledVertices[i0].x, scaledVertices[i0].y, scaledVertices[i0].z); +// reindexedFaces[i0] = flLastIndex; +// flLastIndex++; +// } +// +// if(typeof reindexedFaces[i1] === 'undefined') { +// vertices.push(scaledVertices[i1].x, scaledVertices[i1].y, scaledVertices[i1].z); +// reindexedFaces[i1] = flLastIndex; +// flLastIndex++; +// } +// +// if(typeof reindexedFaces[i2] === 'undefined') { +// vertices.push(scaledVertices[i2].x, scaledVertices[i2].y, scaledVertices[i2].z); +// reindexedFaces[i2] = flLastIndex; +// flLastIndex++; +// } +// +// faces.push(reindexedFaces[i0], reindexedFaces[i1], reindexedFaces[i2]); +// +// processedFaces++; +// } +// +// return new GameLib.D3.Shape(this.engine, GameLib.D3.Shape.SHAPE_TYPE_TRIMESH, {x : 1, y : 1, z : 1}, vertices, faces); +// }; +// +// /** +// * @param triangleMeshBody GameLib.D3.RigidBody +// * @param rayscale Number +// * @param maxTriangleDistance Number +// * @param createCompoundShape Boolean +// * @param graphics GameLib.D3.Graphics +// * @param triangleMeshShapes GameLib.D3.Shape[] +// * @param createDebugView Boolean +// * @returns {GameLib.D3.RigidBody} +// * @constructor +// */ +// GameLib.D3.World.prototype.fixupTriangleMeshShape = function( +// triangleMeshBody, +// triangleMeshShapes, +// rayscale, +// maxTriangleDistance, +// createCompoundShape, +// graphics, +// createDebugView +// ) { +// this.engine.isNotCannonThrow(); +// +// graphics.isNotThreeThrow(); +// +// if(rayscale == null || typeof rayscale == 'undefined' || rayscale == 0) { +// rayscale = 10; +// } +// +// if(maxTriangleDistance == null || typeof maxTriangleDistance == 'undefined') { +// maxTriangleDistance = 13; +// } +// +// var world = this.instance; +// +// var raycastResult = new this.engine.instance.RaycastResult(); +// +// var brokenFaceIndicators = []; +// +// var totalFaces = 0; +// var totalBrokenFaces = 0; +// var totalFixedFaces = 0; +// var fixedTriangleMeshObjects = []; +// +// for(var i in triangleMeshShapes) { +// var trimesh = triangleMeshShapes[i].instance; +// +// var brokenFaces = []; +// totalFaces += (trimesh.indices.length / 3); +// +// for(var face = 0; face < trimesh.indices.length / 3; face++) { +// +// var i0 = trimesh.indices[face * 3]; +// var i1 = trimesh.indices[face * 3 + 1]; +// var i2 = trimesh.indices[face * 3 + 2]; +// +// var triangleCenterPoint = new graphics.instance.Vector3() +// .add(new graphics.instance.Vector3( +// trimesh.vertices[i0 * 3], +// trimesh.vertices[i0 * 3 + 1], +// trimesh.vertices[i0 * 3 + 2]) +// ) +// .add(new graphics.instance.Vector3( +// trimesh.vertices[i1 * 3], +// trimesh.vertices[i1 * 3 + 1], +// trimesh.vertices[i1 * 3 + 2]) +// ) +// .add(new graphics.instance.Vector3( +// trimesh.vertices[i2 * 3], +// trimesh.vertices[i2 * 3 + 1], +// trimesh.vertices[i2 * 3 + 2]) +// ) +// .divideScalar(3); +// +// var triangleNormal = new this.engine.instance.Vec3(); +// trimesh.getNormal(face , triangleNormal); +// +// var from = new this.engine.instance.Vec3( +// triangleCenterPoint.x + triangleNormal.x, +// triangleCenterPoint.y + triangleNormal.y, +// triangleCenterPoint.z + triangleNormal.z +// ); +// +// var to = new this.engine.instance.Vec3( +// from.x - triangleNormal.x * rayscale, +// from.y - triangleNormal.y * rayscale, +// from.z - triangleNormal.z * rayscale +// ); +// +// world.raycastClosest(from, to, {}, raycastResult); +// +// // visualize results +// if(createDebugView){ +// var graphicsGeometry = new graphics.instance.Geometry(); +// var wireframeMesh = new graphics.instance.Mesh( +// graphicsGeometry, +// new graphics.instance.MeshBasicMaterial({ +// color: 0xff0000, +// wireframe: true, +// opacity: 1 +// }) +// ); +// +// var arrow = new graphics.instance.ArrowHelper( +// new graphics.instance.Vector3( +// triangleNormal.x, +// triangleNormal.y, +// triangleNormal.z +// ).normalize(), +// +// new graphics.instance.Vector3( +// from.x, +// from.y, +// from.z +// ), +// +// rayscale / 2, +// raycastResult.hasHit ? new graphics.instance.Color(0, 1, 0) +// : new graphics.instance.Color(1, 0, 0) +// ); +// +// wireframeMesh.add( arrow ); +// brokenFaceIndicators.push(wireframeMesh); +// } +// +// if(!raycastResult.hasHit) { +// brokenFaces.push({ +// faceIndex : face, +// +// vertices : [ +// new this.engine.instance.Vec3( +// trimesh.vertices[i0 * 3], +// trimesh.vertices[i0 * 3 + 1], +// trimesh.vertices[i0 * 3 + 2] +// ), +// +// new this.engine.instance.Vec3( +// trimesh.vertices[i1 * 3], +// trimesh.vertices[i1 * 3 + 1], +// trimesh.vertices[i1 * 3 + 2] +// ), +// +// new this.engine.instance.Vec3( +// trimesh.vertices[i2 * 3], +// trimesh.vertices[i2 * 3 + 1], +// trimesh.vertices[i2 * 3 + 2] +// ) +// ], +// +// center : triangleCenterPoint, +// +// parent : trimesh +// }); +// } +// } +// +// // fix up broken faces +// +// var bFaceIndexed = {}; +// for(var b = 0; b < brokenFaces.length; b++) { +// var brokenFace = brokenFaces[b]; +// +// if(brokenFace.marked) { +// continue; +// } +// +// bFaceIndexed[b] = { +// indices : [], +// vertices : [] +// }; +// +// var indicesAmount = bFaceIndexed[b].indices.length; +// +// // add the current broken face itself to the array +// bFaceIndexed[b].indices.push( +// indicesAmount, +// indicesAmount + 1, +// indicesAmount + 2 +// ); +// +// bFaceIndexed[b].vertices.push( +// brokenFace.vertices[0].x, +// brokenFace.vertices[0].y, +// brokenFace.vertices[0].z +// ); +// +// bFaceIndexed[b].vertices.push( +// brokenFace.vertices[1].x, +// brokenFace.vertices[1].y, +// brokenFace.vertices[1].z +// ); +// +// bFaceIndexed[b].vertices.push( +// brokenFace.vertices[2].x, +// brokenFace.vertices[2].y, +// brokenFace.vertices[2].z +// ); +// +// for(var bb = 0; bb < brokenFaces.length; bb++) { +// +// if(bb == b) { +// continue; +// } +// +// var otherBrokenFace = brokenFaces[bb]; +// +// if(otherBrokenFace.marked) { +// continue; +// } +// +// if(brokenFace.center.distanceTo(otherBrokenFace.center) <= maxTriangleDistance) { +// var indicesAmount = bFaceIndexed[b].indices.length; +// +// bFaceIndexed[b].indices.push( +// indicesAmount, +// indicesAmount + 1, +// indicesAmount + 2 +// ); +// +// bFaceIndexed[b].vertices.push( +// otherBrokenFace.vertices[0].x, +// otherBrokenFace.vertices[0].y, +// otherBrokenFace.vertices[0].z +// ); +// +// bFaceIndexed[b].vertices.push( +// otherBrokenFace.vertices[1].x, +// otherBrokenFace.vertices[1].y, +// otherBrokenFace.vertices[1].z +// ); +// +// bFaceIndexed[b].vertices.push( +// otherBrokenFace.vertices[2].x, +// otherBrokenFace.vertices[2].y, +// otherBrokenFace.vertices[2].z +// ); +// +// otherBrokenFace.marked = true; +// } +// } +// } +// +// +// // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// // Decide if we want to create new rigiwyd bodies, or create a compound mesh +// // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// +// for(var e in bFaceIndexed) { +// var element = bFaceIndexed[e]; +// +// var shape = new GameLib.D3.Shape(this.engine, GameLib.D3.Shape.SHAPE_TYPE_TRIMESH, { x : 1, y : 1, z : 1 }, element.vertices, element.indices); +// +// if(createCompoundShape) { +// triangleMeshBody.addShape(shape); +// } else { +// +// var body = new GameLib.D3.RigidBody(this.engine, 0, 12); +// +// //TODO: this is just a hack. +// body.instance.collisionFilterGroup = 1 | 2; // puts this body in two groups. +// +// body.addShape(shape); +// this.addRigidBody(body); +// } +// +// fixedTriangleMeshObjects.push(shape); +// totalFixedFaces += element.indices.length / 3; +// } +// +// // TODO: remove duplicate indices +// /*trimesh.updateNormals(); +// trimesh.updateEdges(); +// trimesh.updateTree(); +// trimesh.updateAABB(); +// trimesh.updateBoundingSphereRadius();*/ +// +// // map faceIndex to flat face index (faceIndex * 3) +0, 1, 2 -> triangle indices +// console.log("i = " + i, brokenFaces); +// totalBrokenFaces += brokenFaces.length; +// } +// +// console.log("total faces", totalFaces); +// console.log("total broken faces", totalBrokenFaces); +// console.log("broken faces in percent", (totalBrokenFaces / totalFaces) * 100); +// console.log("total fixed faces", totalFixedFaces); +// console.log("fixed triangle mesh shapes", fixedTriangleMeshObjects.length); +// +// return { +// brokenFaceIndicators : brokenFaceIndicators, +// fixedTriangleMeshShapes : fixedTriangleMeshObjects +// }; +// }; \ No newline at end of file diff --git a/src/game-lib-system-physics.js b/src/game-lib-system-physics.js new file mode 100644 index 0000000..bb3f681 --- /dev/null +++ b/src/game-lib-system-physics.js @@ -0,0 +1,69 @@ +/** + * System takes care of updating all the entities (based on their component data) + * @param graphics + * @param apiSystem GameLib.API.System + * @constructor + */ +GameLib.System.Physics = function( + graphics, + apiSystem +) { + + GameLib.System.call( + this, + graphics, + apiSystem + ); + +}; + +GameLib.System.Physics.prototype = Object.create(GameLib.System.prototype); +GameLib.System.Physics.prototype.constructor = GameLib.System.Physics; + +GameLib.System.Physics.prototype.start = function() { + + this.worlds = GameLib.EntityManager.Instance.query( + [ + GameLib.D3.World + ] + ); + + this.rigidBodyEntities = GameLib.EntityManager.Instance.query( + [ + GameLib.D3.RigidBody + ] + ); + +}; + +/** + * Update script + */ +GameLib.System.Physics.prototype.update = function() { + + /** + * TODO: progress the world according to delta time + */ + this.worlds.map(function( + world + ){ + world.step(1 / 60.0); + }); + + this.rigidBodyEntities.map( + + function (rigidBody) { + + /** + * TODO: update mesh position based on rigidbody position + */ + } + ); + +}; + +GameLib.System.Physics.prototype.stop = function() { + this.worlds = []; + this.rigidBodyEntities = []; +}; +