diff --git a/src/game-lib-a-1-event.js b/src/game-lib-a-1-event.js index b7da5d1..0c761b8 100644 --- a/src/game-lib-a-1-event.js +++ b/src/game-lib-a-1-event.js @@ -80,6 +80,7 @@ GameLib.Event.FETCH_COMPONENT_TYPES = 0x3e; GameLib.Event.FETCH_COMPONENTS = 0x3f; GameLib.Event.GET_API_URL = 0x40; GameLib.Event.GET_PHYSICS_ENGINE = 0x41; +GameLib.Event.PARENT_WORLD_CHANGE = 0x42; /** * Returns string name of event ID @@ -155,6 +156,7 @@ GameLib.Event.GetEventName = function(number) { case 0x3f : return 'fetch_components'; case 0x40 : return 'get_api_url'; case 0x41 : return 'get_physics_engine'; + case 0x42 : return 'parent_world_change'; break; } diff --git a/src/game-lib-a-component-a.js b/src/game-lib-a-component-a.js index adea05c..f4f865f 100644 --- a/src/game-lib-a-component-a.js +++ b/src/game-lib-a-component-a.js @@ -70,6 +70,7 @@ GameLib.Component.prototype.getDependencies = function() { this.linkedObjects.hasOwnProperty(property) && property !== 'parentMesh' && property !== 'parentScene' && + property !== 'parentWorld' && property !== 'parentEntity' && property !== 'parentEntityManager' && this.hasOwnProperty(property) @@ -248,6 +249,7 @@ GameLib.Component.prototype.buildIdToObject = function() { property !== 'parentEntity' && property !== 'parentScene' && property !== 'parentMesh' && + property !== 'parentWorld' && property !== 'parentEntityManager' ) { if (this.linkedObjects[property] instanceof Array) { diff --git a/src/game-lib-d3-api-face.js b/src/game-lib-d3-api-face.js index 55ea21c..86e74fa 100644 --- a/src/game-lib-d3-api-face.js +++ b/src/game-lib-d3-api-face.js @@ -58,7 +58,7 @@ GameLib.D3.API.Face = function( this.materialIndex = materialIndex; if (GameLib.Utils.UndefinedOrNull(uvs)) { - uvs = [[new GameLib.API.Vector2(0,0), new GameLib.API.Vector2(0,0), new GameLib.API.Vector2(0,0)]]; + uvs = [[]]; } this.uvs = uvs; @@ -96,6 +96,46 @@ GameLib.D3.API.Face = function( * @param objectFace */ GameLib.D3.API.Face.FromObject = function(objectFace) { + + var apiUvs = objectFace.uvs.reduce( + + function(result, uvArray, index) { + + result[index] = uvArray.reduce( + function(uvResult, uv) { + uvResult.push(GameLib.API.Vector2.FromObject(uv)); + return uvResult; + }, + [] + ); + + return result; + }, + [] + ); + + var apiVertexColors = objectFace.vertexColors.map( + function(vertexColor) { + return GameLib.API.Color.FromObject(vertexColor); + } + ); + + var apiColor = null; + if (objectFace.color) { + apiColor = GameLib.API.Color.FromObject(objectFace.color); + } + + var apiVertexNormals = objectFace.vertexNormals.map( + function(vertexNormal) { + return GameLib.API.Vector3.FromObject(vertexNormal); + } + ); + + var apiNormal = null; + if (objectFace.normal) { + apiNormal = GameLib.API.Vector3.FromObject(objectFace.normal); + } + return new GameLib.D3.API.Face( objectFace.id, objectFace.name, @@ -103,11 +143,11 @@ GameLib.D3.API.Face.FromObject = function(objectFace) { objectFace.v1index, objectFace.v2index, objectFace.materialIndex, - objectFace.uvs, - objectFace.color, - objectFace.vertexColors, - objectFace.vertexNormals, - objectFace.normal + apiUvs, + apiColor, + apiVertexColors, + apiVertexNormals, + apiNormal ); }; diff --git a/src/game-lib-d3-api-rigid-body.js b/src/game-lib-d3-api-rigid-body.js index 6c548c4..832cfc3 100644 --- a/src/game-lib-d3-api-rigid-body.js +++ b/src/game-lib-d3-api-rigid-body.js @@ -19,6 +19,7 @@ * @param shapes * @param kinematic * @param parentMesh + * @param parentWorld * @param parentEntity * @constructor */ @@ -42,6 +43,7 @@ GameLib.D3.API.RigidBody = function( shapes, kinematic, parentMesh, + parentWorld, parentEntity ) { @@ -140,6 +142,11 @@ GameLib.D3.API.RigidBody = function( } this.parentMesh = parentMesh; + if (GameLib.Utils.UndefinedOrNull(parentWorld)) { + parentWorld = null; + } + this.parentWorld = parentWorld; + if (GameLib.Utils.UndefinedOrNull(parentEntity)) { parentEntity = null; } @@ -175,6 +182,7 @@ GameLib.D3.API.RigidBody.FromObject = function(objectRigidBody) { objectRigidBody.shapes, objectRigidBody.kinematic, objectRigidBody.parentMesh, + objectRigidBody.parentWorld, objectRigidBody.parentEntity ); }; diff --git a/src/game-lib-d3-face.js b/src/game-lib-d3-face.js index 9f560ab..ce2b84a 100644 --- a/src/game-lib-d3-face.js +++ b/src/game-lib-d3-face.js @@ -69,21 +69,52 @@ GameLib.D3.Face = function Face( } - // this.vertexNormals = this.vertexNormals.map(function(vertexNormal){ - // if (vertexNormal instanceof GameLib.Vector3) { - // return vertexNormal; - // } - // - // if (vertexNormal instanceof GameLib.API.Vector3) { - // return new GameLib.Vector3( - // this.graphics, - // vertexNormal, - // this - // ) - // } - // - // console.warn('unknown vertex normal type', vertexNormal); - // }.bind(this)); + this.vertexNormals = this.vertexNormals.map(function(vertexNormal){ + if (vertexNormal instanceof GameLib.Vector3) { + return vertexNormal; + } + + if (vertexNormal instanceof GameLib.API.Vector3) { + return new GameLib.Vector3( + this.implementation, + vertexNormal, + this + ) + } + + console.warn('unknown vertex normal type', vertexNormal); + }.bind(this)); + + this.uvs = this.uvs.reduce( + + function(result, uvArray, index) { + + result[index] = uvArray.reduce( + function(uvResult, uv) { + + if (uv instanceof GameLib.API.Vector2) { + uvResult.push( + new GameLib.Vector2( + this.implementation, + uv, + this + ) + ); + } else { + console.warn('unknown uv type'); + } + + return uvResult; + }.bind(this), + [] + ); + + return result; + + + }.bind(this), + [] + ); this.normal = new GameLib.Vector3( this.implementation, @@ -105,14 +136,36 @@ GameLib.D3.Face.prototype.updateInstance = function() { }; GameLib.D3.Face.prototype.toApiObject = function() { - return new GameLib.D3.API.Face( + + return new GameLib.D3.API.Face( this.id, this.name, this.v0index, this.v1index, this.v2index, this.materialIndex, - this.uvs, + this.uvs.reduce( + function(result, uvArray, index) { + + result[index] = uvArray.reduce( + function(uvResult, uv) { + + if (uv instanceof GameLib.Vector2) { + uvResult.push(uv.toApiObject()); + } else { + console.warn('unknown uv type - cannot commit to API'); + } + + return uvResult; + }.bind(this), + [] + ); + + return result; + + }.bind(this), + [] + ), this.color.toApiObject(), this.vertexColors.map(function(vertexColor){ return vertexColor.toApiObject(); diff --git a/src/game-lib-d3-mesh-0.js b/src/game-lib-d3-mesh-0.js index 765c1f5..1676037 100644 --- a/src/game-lib-d3-mesh-0.js +++ b/src/game-lib-d3-mesh-0.js @@ -366,14 +366,18 @@ GameLib.D3.Mesh.prototype.createInstanceGeometry = function(instanceGeometry) { geometry.faces = this.faces.map( function (face) { - standardUvs.push(face.uvs[0].map( - function(uv) { - return new THREE.Vector2( - uv.x, - uv.y - ) - } - )); + if (face.uvs[0].length > 0) { + standardUvs.push( + face.uvs[0].map( + function(uv) { + return new THREE.Vector2( + uv.x, + uv.y + ) + } + ) + ); + } var faceInstance = new THREE.Face3( face.v0index, @@ -722,18 +726,18 @@ GameLib.D3.Mesh.prototype.updateVerticesFromGeometryInstance = function(geometry face.c, face.materialIndex, [[ - { - x: geometryInstance.faceVertexUvs[0][faceIndex][0].x, - y: geometryInstance.faceVertexUvs[0][faceIndex][0].y - }, - { - x: geometryInstance.faceVertexUvs[0][faceIndex][1].x, - y: geometryInstance.faceVertexUvs[0][faceIndex][1].y - }, - { - x: geometryInstance.faceVertexUvs[0][faceIndex][2].x, - y: geometryInstance.faceVertexUvs[0][faceIndex][2].y - } + new GameLib.API.Vector2( + geometryInstance.faceVertexUvs[0][faceIndex][0].x, + geometryInstance.faceVertexUvs[0][faceIndex][0].y + ), + new GameLib.API.Vector2( + geometryInstance.faceVertexUvs[0][faceIndex][1].x, + geometryInstance.faceVertexUvs[0][faceIndex][1].y + ), + new GameLib.API.Vector2( + geometryInstance.faceVertexUvs[0][faceIndex][2].x, + geometryInstance.faceVertexUvs[0][faceIndex][2].y + ) ]], new GameLib.Color( this.graphics, @@ -1150,6 +1154,34 @@ GameLib.D3.Mesh.prototype.getChildrenComponents = function() { }.bind(this) ); + /** + * Push RigidBodies + */ + var rigidBodies = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.RigidBody); + rigidBodies.map( + function(rigidBody) { + + if (rigidBody.parentMesh === this) { + GameLib.Utils.PushUnique(components, rigidBody); + } + + }.bind(this) + ); + + /** + * Push Shapes + */ + var shapes = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.Shape); + shapes.map( + function(shape) { + + if (shape.parentMesh === this) { + GameLib.Utils.PushUnique(components, shape); + } + + }.bind(this) + ); + return components; }; diff --git a/src/game-lib-d3-mesh-plane.js b/src/game-lib-d3-mesh-plane.js index a28e0f3..f6a76f1 100644 --- a/src/game-lib-d3-mesh-plane.js +++ b/src/game-lib-d3-mesh-plane.js @@ -282,32 +282,64 @@ GameLib.D3.Mesh.Plane.prototype.createPhysicsObjects = function() { GameLib.Event.GET_PHYSICS_ENGINE, null, function(data){ - var apiShapeSphere = new GameLib.D3.API.Shape( + + /** + * Create the plane shape + * @type {GameLib.D3.API.Shape} + */ + var apiShapePlane = new GameLib.D3.API.Shape( null, 'Shape Plane (' + this.name + ')' ); - apiShapeSphere.parentMesh = this; + apiShapePlane.parentMesh = this; - var shapeSphere = new GameLib.D3.Shape.Plane( + var shapePlane = new GameLib.D3.Shape.Plane( data.physics, - apiShapeSphere, - this.radius + apiShapePlane ); var apiRigidBody = new GameLib.D3.API.RigidBody( null, - 'Rigid Body (' + this.name + ')' + 'Rigid Body (' + this.name + ')', + 0, + null, + new GameLib.API.Vector3( + this.position.x, + this.position.y, + this.position.z + ), + new GameLib.API.Quaternion( + this.quaternion.x, + this.quaternion.y, + this.quaternion.z, + this.quaternion.w, + new GameLib.API.Vector3( + this.quaternion.axis.x, + this.quaternion.axis.y, + this.quaternion.axis.z + ), + this.quaternion.angle + ) ); - apiRigidBody.shapes.push(shapeSphere); + apiRigidBody.shapes.push(shapePlane); + apiRigidBody.parentMesh = this; + + /** + * Construct the rigid body + * @type {GameLib.D3.RigidBody} + */ var rigidBody = new GameLib.D3.RigidBody( data.physics, apiRigidBody ); - rigidBody.parentMesh = this; + if (this.parentEntity instanceof GameLib.Entity) { + this.parentEntity.addComponent(shapePlane); + this.parentEntity.addComponent(rigidBody); + } }.bind(this), function(error){ diff --git a/src/game-lib-d3-mesh-sphere.js b/src/game-lib-d3-mesh-sphere.js index 6a87671..aedb4fd 100644 --- a/src/game-lib-d3-mesh-sphere.js +++ b/src/game-lib-d3-mesh-sphere.js @@ -151,6 +151,8 @@ GameLib.D3.Mesh.Sphere.prototype.createPhysicsObjects = function() { ) ); + apiRigidBody.parentMesh = this; + apiRigidBody.shapes.push(shapeSphere); var rigidBody = new GameLib.D3.RigidBody( @@ -158,7 +160,10 @@ GameLib.D3.Mesh.Sphere.prototype.createPhysicsObjects = function() { apiRigidBody ); - rigidBody.parentMesh = this; + if (this.parentEntity instanceof GameLib.Entity) { + this.parentEntity.addComponent(shapeSphere); + this.parentEntity.addComponent(rigidBody); + } }.bind(this), function(error){ diff --git a/src/game-lib-d3-physics-world.js b/src/game-lib-d3-physics-world.js index a646ffc..a1a5b9f 100644 --- a/src/game-lib-d3-physics-world.js +++ b/src/game-lib-d3-physics-world.js @@ -111,18 +111,107 @@ GameLib.D3.PhysicsWorld.prototype.createInstance = function() { function(contactMaterial) { if (contactMaterial && contactMaterial.instance) { instance.addContactMaterial(contactMaterial.instance); + } else { + console.warn('contact materials not loaded at time of PhysicsWorld.createInstance()'); + } + } + ); + + this.rigidBodies.map( + function(rigidBody) { + if (rigidBody && rigidBody.instance) { + /** + * Ensure the rigidBody knows its parentWorld + */ + rigidBody.parentWorld = this; + + /** + * Add the rigid body to the instance world + */ + instance.add(rigidBody.instance); + } else { + console.warn('rigidbodies not loaded at time of PhysicsWorld.createInstance()'); } } ); return instance; + } else { + console.warn('broadphase or solver not loaded during PhysicsWorld.createInstance()'); } return false; }; +GameLib.D3.PhysicsWorld.prototype.addRigidBody = function(rigidBody) { + + if (rigidBody && rigidBody.instance) { + + /** + * Add the rigid body to the instance world + */ + this.instance.add(rigidBody.instance); + + /** + * Remember to set the parentWorld for this rigidBody + * @type {GameLib.D3.PhysicsWorld} + */ + rigidBody.parentWorld = this; + + /** + * Ensure this rigidBody is in our rigidBodies array, just not too many times.. + */ + GameLib.Utils.PushUnique(this.rigidBodies, rigidBody); + + } else { + console.warn('Attempt to add rigidBody ' + rigidBody.name + ' without an instance'); + } +}; + +/** + * + * @param rigidBody + */ +GameLib.D3.PhysicsWorld.prototype.removeRigidBody = function(rigidBody) { + + if (!rigidBody instanceof GameLib.D3.RigidBody) { + console.warn('not a rigid body'); + return; + } + + /** + * Remove the instance + */ + if (rigidBody.instance) { + + this.instance.remove(rigidBody.instance); + + } else { + console.warn('Attempt to remove rigidBody ' + rigidBody.name + ' without an instance'); + } + + /** + * Remember to set the parentWorld for this rigidBody + * @type {GameLib.D3.PhysicsWorld} + */ + rigidBody.parentWorld = null; + + /** + * Remove from this rigidBodies array + */ + var index = this.rigidBodies.indexOf(rigidBody); + + if (index !== -1) { + this.rigidBodies.splice(index, 1); + } else { + console.warn('could not remove a rigidbody from an array where it should have existed'); + } + +}; + + /** * */ @@ -137,7 +226,7 @@ GameLib.D3.PhysicsWorld.prototype.updateInstance = function() { this.instance.solver = this.solver.instance; this.instance.gravity = this.gravity.instance; - //TODO add contact materials + //TODO add contact materials and rigidbodies ? - this functionality is actually part of the physics system.. }; /** @@ -179,18 +268,6 @@ GameLib.D3.PhysicsWorld.FromObject = function(graphics, objectComponent) { ); }; -GameLib.D3.PhysicsWorld.prototype.step = function(deltaTime) { - - if (this.isCannon) { - this.instance.step(deltaTime); - } - - // if (this.isOimo) { - // //TODO: oimo - // } - -}; - // // GameLib.D3.PhysicsWorld.prototype.step = function( // fixedStep, diff --git a/src/game-lib-d3-rigid-body.js b/src/game-lib-d3-rigid-body.js index 92d9219..b011e8b 100644 --- a/src/game-lib-d3-rigid-body.js +++ b/src/game-lib-d3-rigid-body.js @@ -41,6 +41,7 @@ GameLib.D3.RigidBody = function ( apiRigidBody.shapes, apiRigidBody.kinematic, apiRigidBody.parentMesh, + apiRigidBody.parentWorld, apiRigidBody.parentEntity ); @@ -73,7 +74,8 @@ GameLib.D3.RigidBody = function ( GameLib.Component.COMPONENT_RIGID_BODY, { 'shapes' : [GameLib.D3.Shape], - 'parentMesh' : GameLib.D3.Mesh + 'parentMesh' : GameLib.D3.Mesh, + 'parentWorld' : GameLib.D3.PhysicsWorld } ); }; @@ -177,17 +179,12 @@ GameLib.D3.RigidBody.prototype.setFromParentMesh = function() { this.instance.position.y = this.parentMesh.position.y; this.instance.position.z = this.parentMesh.position.z; - // this.parentMesh.quaternion.x = this.parentMesh.instance.quaternion.x; - // this.parentMesh.quaternion.y = this.parentMesh.instance.quaternion.y; - // this.parentMesh.quaternion.z = this.parentMesh.instance.quaternion.z; - // this.parentMesh.quaternion.w = this.parentMesh.instance.quaternion.w; - // - // this.quaternion.x = this.parentMesh.quaternion.x; - // this.quaternion.y = this.parentMesh.quaternion.y; - // this.quaternion.z = this.parentMesh.quaternion.z; - // this.quaternion.w = this.parentMesh.quaternion.w; + this.instance.quaternion.x = this.parentMesh.quaternion.x; + this.instance.quaternion.y = this.parentMesh.quaternion.y; + this.instance.quaternion.z = this.parentMesh.quaternion.z; + this.instance.quaternion.w = this.parentMesh.quaternion.w; - this.updateInstance(); + // this.updateInstance(); }; @@ -217,6 +214,7 @@ GameLib.D3.RigidBody.prototype.toApiObject = function() { this.shapes.map(function(shape){return GameLib.Utils.IdOrNull(shape)}), this.kinematic, GameLib.Utils.IdOrNull(this.parentMesh), + GameLib.Utils.IdOrNull(this.parentWorld), GameLib.Utils.IdOrNull(this.parentEntity) ); diff --git a/src/game-lib-d3-shape-plane.js b/src/game-lib-d3-shape-plane.js index 75762ab..26f1c95 100644 --- a/src/game-lib-d3-shape-plane.js +++ b/src/game-lib-d3-shape-plane.js @@ -31,4 +31,14 @@ GameLib.D3.Shape.Plane.prototype.createInstance = function() { }; GameLib.D3.Shape.Plane.prototype.updateInstance = function() { +}; + +GameLib.D3.Shape.Plane.FromObject = function(physics, objectShape) { + + var apiShape = GameLib.D3.API.Shape.FromObject(objectShape); + + return new GameLib.D3.Shape.Plane( + physics, + apiShape + ); }; \ No newline at end of file diff --git a/src/game-lib-d3-shape-sphere.js b/src/game-lib-d3-shape-sphere.js index d7ec1a9..792a0b1 100644 --- a/src/game-lib-d3-shape-sphere.js +++ b/src/game-lib-d3-shape-sphere.js @@ -43,9 +43,23 @@ GameLib.D3.Shape.Sphere.prototype.createInstance = function() { GameLib.D3.Shape.Sphere.prototype.updateInstance = function() { this.instance.radius = this.radius; - this.instance.updateAABB(); this.instance.updateBoundingSphereRadius(); - this.instance.updateEdges(); - this.instance.updateNormals(); - this.instance.updateTree(); +}; + + +GameLib.D3.Shape.Sphere.prototype.toApiObject = function() { + var apiShape = GameLib.D3.Shape.prototype.toApiObject.call(this); + apiShape.radius = this.radius; + return apiShape; +}; + +GameLib.D3.Shape.Sphere.FromObject = function(physics, objectShape) { + + var apiShape = GameLib.D3.API.Shape.FromObject(objectShape); + + return new GameLib.D3.Shape.Sphere( + physics, + apiShape, + objectShape.radius + ); }; \ No newline at end of file diff --git a/src/game-lib-entity.js b/src/game-lib-entity.js index 96c2618..221f20d 100644 --- a/src/game-lib-entity.js +++ b/src/game-lib-entity.js @@ -56,24 +56,38 @@ GameLib.Entity.prototype.addComponent = function(component) { GameLib.Utils.PushUnique(this.components, component); - /** - * Here we will dig into this component - find all its 'parentEntity' members - and update them accordingly - */ - component.buildIdToObject(); + if (component instanceof GameLib.D3.Mesh) { - /** - * Also add the child components of this component as components of this entity - */ - for (var property in component.idToObject) { - if (component.idToObject.hasOwnProperty(property) && - component.idToObject[property] !== component && - component.idToObject[property] instanceof GameLib.Component - ) { - GameLib.Utils.PushUnique(this.components, component.idToObject[property]); - component.idToObject[property].parentEntity = this; + /** + * For meshes, simply get the children components + * @type {Array} + */ + component.getChildrenComponents().map(function(childComponent){ + GameLib.Utils.PushUnique(this.components, childComponent); + childComponent.parentEntity = this; + }.bind(this)) + + } else { + /** + * Here we will dig into this component - find all its 'parentEntity' members - and update them accordingly + */ + component.buildIdToObject(); + + /** + * Also add the child components of this component as components of this entity + */ + for (var property in component.idToObject) { + if (component.idToObject.hasOwnProperty(property) && + component.idToObject[property] !== component && + component.idToObject[property] instanceof GameLib.Component + ) { + GameLib.Utils.PushUnique(this.components, component.idToObject[property]); + component.idToObject[property].parentEntity = this; + } } } + /** * Finally, we are the boss component - update my parent entity * @type {GameLib.Entity} diff --git a/src/game-lib-gui.js b/src/game-lib-gui.js index 31c8f5e..a0408b1 100644 --- a/src/game-lib-gui.js +++ b/src/game-lib-gui.js @@ -96,7 +96,12 @@ GameLib.GUI.prototype.addFolder = function(folderName) { try { return this.instance.addFolder(folderName); } catch (e) { - console.log(e.message); - return null; + try { + folderName += ' duplicate (' + GameLib.Utils.RandomId() + ')'; + return this.instance.addFolder(folderName); + } catch (e) { + console.log(e.message); + return null; + } } }; diff --git a/src/game-lib-system-gui.js b/src/game-lib-system-gui.js index 3d2d0b6..bc0b7e5 100644 --- a/src/game-lib-system-gui.js +++ b/src/game-lib-system-gui.js @@ -376,10 +376,14 @@ GameLib.System.GUI.prototype.buildParentSelectionControl = function(folder, comp } if (property === 'parentMesh') { - constructor = GameLib.D3.Mesh + constructor = GameLib.D3.Mesh; } - var options = GameLib.EntityManager.Instance.queryComponents(constructor).reduce( + if (property === 'parentWorld') { + constructor = GameLib.D3.PhysicsWorld; + } + + var options = GameLib.EntityManager.Instance.queryComponents(constructor).reduce( function(result, object) { result[object.name] = object; return result; @@ -419,6 +423,17 @@ GameLib.System.GUI.prototype.buildParentSelectionControl = function(folder, comp ); } + if (property === 'parentWorld') { + GameLib.Event.Emit( + GameLib.Event.PARENT_WORLD_CHANGE, + { + originalWorld : this.initialValue, + newWorld : newComponent, + object : component + } + ) + } + }.bind(this) ); @@ -623,6 +638,17 @@ GameLib.System.GUI.prototype.buildSelectControl = function(folder, componentTemp } ); } + + if (property === 'parentWorld') { + GameLib.Event.Emit( + GameLib.Event.PARENT_WORLD_CHANGE, + { + originalWorld : originalComponent, + newWorld : newComponent, + object : component + } + ) + } } ); @@ -1069,9 +1095,13 @@ GameLib.System.GUI.prototype.buildControl = function(folder, componentTemplate, ) { controllers.push(folder.add(object, property, -100, 100, 0.001)); } else if ( - property === 'rrradius' + property === 'friction' ) { controllers.push(folder.add(object, property, 0, 1000, 0.01)); + } else if ( + property === 'mass' + ) { + controllers.push(folder.add(object, property, 0, 1000, 0.1)); } else if ( property === 'thetaLength' || property === 'angle' @@ -1525,6 +1555,7 @@ GameLib.System.GUI.prototype.buildGUI = function(data) { if ( templateProperty === 'parentEntity' || + templateProperty === 'parentWorld' || templateProperty === 'parentMesh' ) { this.buildParentSelectionControl(folder, componentTemplate, templateProperty); diff --git a/src/game-lib-system-linking.js b/src/game-lib-system-linking.js index 4fbe3da..25ca3da 100644 --- a/src/game-lib-system-linking.js +++ b/src/game-lib-system-linking.js @@ -27,6 +27,7 @@ GameLib.System.Linking = function( this.imageNotFoundSubscription = null; this.componentCreatedSubscription = null; this.parentSceneChangeSubscription = null; + this.parentWorldChangeSubscription = null; this.parentEntityChangeSubscription = null; this.meshInstanceCreatedSubscription = null; this.lightInstanceCreatedSubscription = null; @@ -39,6 +40,9 @@ GameLib.System.Linking = function( this.materialTypeChangedSubscription = null; this.arrayItemAddedSubscription = null; this.instanceCreatedSubscription = null; + this.shapeInstanceCreatedSubscription = null; + this.solverInstanceCreatedSubscription = null; + }; GameLib.System.Linking.prototype = Object.create(GameLib.System.prototype); @@ -56,6 +60,11 @@ GameLib.System.Linking.prototype.start = function() { this.onParentSceneChange ); + this.parentWorldChangeSubscription = this.subscribe( + GameLib.Event.PARENT_WORLD_CHANGE, + this.onParentWorldChange + ); + this.parentEntityChangeSubscription = this.subscribe( GameLib.Event.PARENT_ENTITY_CHANGE, this.onParentEntityChange @@ -91,6 +100,11 @@ GameLib.System.Linking.prototype.start = function() { this.materialInstanceCreated ); + this.physicsWorldInstanceCreatedSubscription = this.subscribe( + GameLib.Event.PHYSICS_WORLD_INSTANCE_CREATED, + this.physicsWorldInstanceCreated + ); + this.imageNotFoundSubscription = this.subscribe( GameLib.Event.IMAGE_NOT_FOUND, this.imageNotFound @@ -119,7 +133,23 @@ GameLib.System.Linking.prototype.start = function() { this.arrayItemAddedSubscription = this.subscribe( GameLib.Event.ARRAY_ITEM_ADDED, this.arrayItemAdded - ) + ); + + this.shapeInstanceCreatedSubscription = this.subscribe( + GameLib.Event.SHAPE_INSTANCE_CREATED, + this.shapeInstanceCreated + ); + + this.solverInstanceCreatedSubscription = this.subscribe( + GameLib.Event.SOLVER_INSTANCE_CREATED, + this.solverInstanceCreated + ); + + this.instanceCreatedSubscription = this.subscribe( + GameLib.Event.INSTANCE_CREATED, + this.instanceCreated + ); + }; GameLib.System.Linking.prototype.link = function(component, data) { @@ -659,6 +689,78 @@ GameLib.System.Linking.prototype.imageInstanceCreated = function(data) { }; +GameLib.System.Linking.prototype.solverInstanceCreated = function(data) { + console.log(data); +}; + +GameLib.System.Linking.prototype.arrayItemAdded = function(data) { + if ( + data.component instanceof GameLib.D3.PhysicsWorld && + data.item instanceof GameLib.D3.RigidBody + ) { + data.component.addRigidBody(data.item); + } +}; + +GameLib.System.Linking.prototype.instanceCreated = function(data) { + + if (data.component instanceof GameLib.D3.RaycastVehicle) { + + var worlds = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.PhysicsWorld); + + /** + * First ensure our parent world is linked + */ + worlds.map( + function(world) { + if (data.component.parentWorld === world.id) { + data.component.parentWorld = world; + } + } + ); + + if (!data.component.parentWorld) { + console.log('no parent world'); + } else { + data.component.instance.addToWorld(data.component.parentWorld.instance); + console.log('raycast vehicle instance added to its parent world'); + } + } + + if (data.component instanceof GameLib.D3.RigidBody) { + + var meshes = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.Mesh); + + meshes.map( + function(mesh) { + if (data.component.parentMesh === mesh.id) { + data.component.parentMesh = mesh; + } + } + ); + + this.restart(); + } +}; + +GameLib.System.Linking.prototype.shapeInstanceCreated = function(data) { + + /** + * When a shape instance is created, just check if the parentMesh is loaded somewhere and set it. + * + * We also do the reverse, when a mesh instance is created, we check if its the parent of any shape. + */ + var meshes = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.Mesh); + meshes.map( + function(mesh) { + if (data.shape.parentMesh === mesh.id) { + data.shape.parentMesh = mesh; + } + } + ); +}; + + GameLib.System.Linking.prototype.textureInstanceCreated = function(data) { this.resolveDependencies(data.texture); }; @@ -667,6 +769,37 @@ GameLib.System.Linking.prototype.materialInstanceCreated = function(data) { this.resolveDependencies(data.material); }; +GameLib.System.Linking.prototype.physicsWorldInstanceCreated = function(data) { + + var raycastVehicles = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.RaycastVehicle); + raycastVehicles.map( + function(vehicle) { + if (vehicle.parentWorld === data.world.id) { + vehicle.parentWorld = data.world; + } + } + ); + + var rigidBodies = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.RigidBody); + rigidBodies.map( + function(rigidBody){ + if (rigidBody.parentWorld === data.world.id) { + rigidBody.parentWorld = data.world; + } + } + ); + + var contactMaterials = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.FrictionContactMaterial); + contactMaterials.map( + function(contactMaterial) { + if (contactMaterial.parentWorld === data.world.id) { + contactMaterial.parentWorld = data.world; + } + } + ); + +}; + GameLib.System.Linking.prototype.materialTypeChanged = function(data) { var meshes = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.Mesh); @@ -704,6 +837,27 @@ GameLib.System.Linking.prototype.materialTypeChanged = function(data) { }; +/** + * + * @param data + */ +GameLib.System.Linking.prototype.onParentWorldChange = function(data) { + + if ( + data.object instanceof GameLib.D3.RigidBody + ) { + + if (data.originalWorld instanceof GameLib.D3.PhysicsWorld) { + data.originalWorld.removeRigidBody(data.object); + } + + if (data.newWorld instanceof GameLib.D3.PhysicsWorld) { + data.newWorld.addRigidBody(data.object); + } + } + +}; + /** * Defines what should happen when a parent scene changes * @param data @@ -848,6 +1002,7 @@ GameLib.System.Linking.prototype.stop = function() { this.imageNotFoundSubscription.remove(); this.componentCreatedSubscription.remove(); this.parentSceneChangeSubscription.remove(); + this.parentWorldChangeSubscription.remove(); this.parentEntityChangeSubscription.remove(); this.meshInstanceCreatedSubscription.remove(); this.lightInstanceCreatedSubscription.remove(); @@ -860,5 +1015,8 @@ GameLib.System.Linking.prototype.stop = function() { this.materialTypeChangedSubscription.remove(); this.instanceCreatedSubscription.remove(); this.arrayItemAddedSubscription.remove(); + this.physicsWorldInstanceCreatedSubscription.remove(); + this.shapeInstanceCreatedSubscription.remove(); + this.solverInstanceCreatedSubscription.remove(); }; diff --git a/src/game-lib-system-physics.js b/src/game-lib-system-physics.js index 176cf0b..2a07b1b 100644 --- a/src/game-lib-system-physics.js +++ b/src/game-lib-system-physics.js @@ -13,12 +13,12 @@ GameLib.System.Physics = function( ); this.worlds = []; - this.rigidBodies = []; - this.wheels = []; - this.vehicles = []; + // this.rigidBodies = []; + // this.wheels = []; + // this.vehicles = []; - this.worldSubscription = null; - this.rigidBodySubscription = null; + // this.worldSubscription = null; + // this.rigidBodySubscription = null; this.beforeRenderSubscription = null; this.afterRenderSubscription = null; @@ -33,65 +33,42 @@ GameLib.System.Physics.prototype.constructor = GameLib.System.Physics; GameLib.System.Physics.prototype.start = function() { this.worlds = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.PhysicsWorld); - this.rigidBodies = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.RigidBody); - this.wheels = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.RaycastWheel); - this.vehicles = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.RaycastVehicle); - - this.shapeInstanceCreatedSubscription = this.subscribe( - GameLib.Event.SHAPE_INSTANCE_CREATED, - this.shapeInstanceCreated - ); - - this.solverInstanceCreatedSubscription = this.subscribe( - GameLib.Event.SOLVER_INSTANCE_CREATED, - this.solverInstanceCreated - ); - - this.physicsWorldInstanceCreatedSubscription = this.subscribe( - GameLib.Event.PHYSICS_WORLD_INSTANCE_CREATED, - this.physicsWorldInstanceCreated - ); - - this.instanceCreatedSubscription = this.subscribe( - GameLib.Event.INSTANCE_CREATED, - this.instanceCreated - ); - - this.arrayItemAddedSubscription = this.subscribe( - GameLib.Event.ARRAY_ITEM_ADDED, - this.arrayItemAdded - ); - - this.worlds.map( - function(world) { - world.instance.addEventListener( - 'postStep', - function() { - - this.vehicles.map( - function(vehicle) { - vehicle.instance.wheelInfos.map( - function(wheelInfo, index) { - vehicle.instance.updateWheelTransform(index); - var t = wheelInfo.worldTransform; - // vehicle.wheels[index].instance.position.copy(t.position); - // vehicle.wheels[index].instance.quaternion.copy(t.quaternion); - - // vehicle.raycastWheels[index].parentMesh.localPosition.x = t.position.x; - // vehicle.raycastWheels[index].parentMesh.localPosition.y = t.position.y; - // vehicle.raycastWheels[index].parentMesh.localPosition.z = t.position.z; - - // vehicle.raycastWheels[index].parentMesh.updateInstance(); - } - ); - } - ); + // this.rigidBodies = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.RigidBody); + // this.wheels = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.RaycastWheel); + // this.vehicles = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.RaycastVehicle); - }.bind(this) - ) - }.bind(this) - ); + + // this.worlds.map( + // function(world) { + // world.instance.addEventListener( + // 'postStep', + // function() { + // + // this.vehicles.map( + // function(vehicle) { + // vehicle.instance.wheelInfos.map( + // function(wheelInfo, index) { + // vehicle.instance.updateWheelTransform(index); + // var t = wheelInfo.worldTransform; + // // vehicle.wheels[index].instance.position.copy(t.position); + // // vehicle.wheels[index].instance.quaternion.copy(t.quaternion); + // + // // vehicle.raycastWheels[index].parentMesh.localPosition.x = t.position.x; + // // vehicle.raycastWheels[index].parentMesh.localPosition.y = t.position.y; + // // vehicle.raycastWheels[index].parentMesh.localPosition.z = t.position.z; + // + // // vehicle.raycastWheels[index].parentMesh.updateInstance(); + // } + // ); + // } + // ); + // + // + // }.bind(this) + // ) + // }.bind(this) + // ); this.beforeRenderSubscription = this.subscribe( GameLib.Event.BEFORE_RENDER, @@ -106,173 +83,50 @@ GameLib.System.Physics.prototype.beforeRender = function(data) { this.worlds.map( function(world) { - world.instance.step(data.delta); - this.rigidBodies.map( - function(rigidBody){ - rigidBody.position.x = rigidBody.instance.position.x; - rigidBody.position.y = rigidBody.instance.position.y; - rigidBody.position.z = rigidBody.instance.position.z; + if (world.loaded && world.instance) { - rigidBody.quaternion.x = rigidBody.instance.quaternion.x; - rigidBody.quaternion.y = rigidBody.instance.quaternion.y; - rigidBody.quaternion.z = rigidBody.instance.quaternion.z; - rigidBody.quaternion.w = rigidBody.instance.quaternion.w; + world.instance.step(data.delta); - rigidBody.parentMesh.position.x = rigidBody.instance.position.x; - rigidBody.parentMesh.position.y = rigidBody.instance.position.y; - rigidBody.parentMesh.position.z = rigidBody.instance.position.z; + world.rigidBodies.map( + function(rigidBody){ + rigidBody.position.x = rigidBody.instance.position.x; + rigidBody.position.y = rigidBody.instance.position.y; + rigidBody.position.z = rigidBody.instance.position.z; - rigidBody.parentMesh.quaternion.x = rigidBody.instance.quaternion.x; - rigidBody.parentMesh.quaternion.y = rigidBody.instance.quaternion.y; - rigidBody.parentMesh.quaternion.z = rigidBody.instance.quaternion.z; - rigidBody.parentMesh.quaternion.w = rigidBody.instance.quaternion.w; + rigidBody.quaternion.x = rigidBody.instance.quaternion.x; + rigidBody.quaternion.y = rigidBody.instance.quaternion.y; + rigidBody.quaternion.z = rigidBody.instance.quaternion.z; + rigidBody.quaternion.w = rigidBody.instance.quaternion.w; - rigidBody.instance.getVelocityAtWorldPoint(new CANNON.Vec3(0,0,0), rigidBody.velocity.instance); + rigidBody.parentMesh.position.x = rigidBody.instance.position.x; + rigidBody.parentMesh.position.y = rigidBody.instance.position.y; + rigidBody.parentMesh.position.z = rigidBody.instance.position.z; - rigidBody.velocity.x = rigidBody.velocity.instance.x; - rigidBody.velocity.y = rigidBody.velocity.instance.y; - rigidBody.velocity.z = rigidBody.velocity.instance.z; + rigidBody.parentMesh.quaternion.x = rigidBody.instance.quaternion.x; + rigidBody.parentMesh.quaternion.y = rigidBody.instance.quaternion.y; + rigidBody.parentMesh.quaternion.z = rigidBody.instance.quaternion.z; + rigidBody.parentMesh.quaternion.w = rigidBody.instance.quaternion.w; - rigidBody.parentMesh.updateRotationFromAxisAngle = false; + rigidBody.instance.getVelocityAtWorldPoint(new CANNON.Vec3(0,0,0), rigidBody.velocity.instance); - rigidBody.parentMesh.updateInstance(); + rigidBody.velocity.x = rigidBody.velocity.instance.x; + rigidBody.velocity.y = rigidBody.velocity.instance.y; + rigidBody.velocity.z = rigidBody.velocity.instance.z; + + rigidBody.parentMesh.updateRotationFromAxisAngle = false; + + rigidBody.parentMesh.updateInstance(); + + rigidBody.parentMesh.updateRotationFromAxisAngle = true; + } + ) + } - rigidBody.parentMesh.updateRotationFromAxisAngle = true; - } - ) }.bind(this) ); }; -GameLib.System.Physics.prototype.solverInstanceCreated = function(data) { - - console.log(data); - -}; - -GameLib.System.Physics.prototype.arrayItemAdded = function(data) { - - if ( - data.component instanceof GameLib.D3.PhysicsWorld && - data.item instanceof GameLib.D3.RigidBody - ) { - data.component.instance.add(data.item.instance); - } - -}; - -GameLib.System.Physics.prototype.instanceCreated = function(data) { - - if (data.component instanceof GameLib.D3.RaycastVehicle) { - - var worlds = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.PhysicsWorld); - - /** - * First ensure our parent world is linked - */ - worlds.map( - function(world) { - if (data.component.parentWorld === world.id) { - data.component.parentWorld = world; - } - } - ); - - if (!data.component.parentWorld) { - console.log('no parent world'); - } else { - data.component.instance.addToWorld(data.component.parentWorld.instance); - console.log('raycast vehicle instance added to its parent world'); - } - } - - if (data.component instanceof GameLib.D3.RigidBody) { - var meshes = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.Mesh); - - meshes.map( - function(mesh) { - if (data.component.parentMesh === mesh.id) { - data.component.parentMesh = mesh; - } - } - ); - - /** - * By default - add this rigidbody to all physics worlds - */ - this.worlds.map(function(world){ - world.rigidBodies.push(data.component); - world.instance.add(data.component.instance); - }); - - this.restart(); - } -}; - -GameLib.System.Physics.prototype.physicsWorldInstanceCreated = function(data) { - - var raycastVehicles = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.RaycastVehicle); - - raycastVehicles.map( - function(vehicle) { - if (vehicle.parentWorld === data.world.id) { - vehicle.parentWorld = data.world; - // vehicle.instance.addToWorld(data.world.instance); - } - } - ) - - // var contactMaterials = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.FrictionContactMaterial); - // - // data.world.contactMaterials.map( - // function() { - // if () - // } - // ); - -}; - - -GameLib.System.Physics.prototype.shapeInstanceCreated = function(data) { - - /** - * When a shape instance is created, just check if the parentMesh is loaded somewhere and set it. - * - * We also do the reverse, when a mesh instance is created, we check if its the parent of any shape. - */ - var meshes = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.Mesh); - meshes.map( - function(mesh) { - if (data.shape.parentMesh === mesh.id) { - data.shape.parentMesh = mesh; - } - } - ); - - /** - * We need to now, find the rigid bodies to which the shape belongs, and add it - also the reverse ? - * - * this is not ok - because we are not dealing with links to parent objects - these are dependencies which need - * to be resolved - an array of dependencies... eeek... - */ - // var rigidBodies = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.RigidBody); - // rigidBodies.map(function(rigidBody){ - // - // rigidBody.shapes = rigidBody.shapes.reduce( - // function(result, shape) { - // if (shape === data.shape.id) { - // result.push(data.shape); - // } - // return result; - // }, - // [] - // ); - // - // }); - - -}; GameLib.System.Physics.prototype.stop = function() { @@ -281,14 +135,6 @@ GameLib.System.Physics.prototype.stop = function() { this.wheels = []; this.vehicles = []; - if (this.worldSubscription) { - this.worldSubscription.remove(); - } - - if (this.rigidBodySubscription) { - this.rigidBodySubscription.remove(); - } - if (this.beforeRenderSubscription) { this.beforeRenderSubscription.remove(); } @@ -297,11 +143,5 @@ GameLib.System.Physics.prototype.stop = function() { this.afterRenderSubscription.remove(); } - this.shapeInstanceCreatedSubscription.remove(); - this.solverInstanceCreatedSubscription.remove(); - this.physicsWorldInstanceCreatedSubscription.remove(); - this.instanceCreatedSubscription.remove(); - this.arrayItemAddedSubscription.remove(); - };