awesome - sphere shape and plane shape physics working

beta.r3js.org
-=yb4f310 2017-09-11 17:47:32 +02:00
parent 49c35fb35c
commit ce4b1cd260
17 changed files with 605 additions and 301 deletions

View File

@ -78,6 +78,8 @@ GameLib.Event.VISUALIZE = 0x3c;
GameLib.Event.STOP_VISUALIZE = 0x3d; GameLib.Event.STOP_VISUALIZE = 0x3d;
GameLib.Event.FETCH_COMPONENT_TYPES = 0x3e; GameLib.Event.FETCH_COMPONENT_TYPES = 0x3e;
GameLib.Event.FETCH_COMPONENTS = 0x3f; GameLib.Event.FETCH_COMPONENTS = 0x3f;
GameLib.Event.GET_API_URL = 0x40;
GameLib.Event.GET_PHYSICS_ENGINE = 0x41;
/** /**
* Returns string name of event ID * Returns string name of event ID
@ -151,6 +153,8 @@ GameLib.Event.GetEventName = function(number) {
case 0x3d : return 'stop_visualize'; case 0x3d : return 'stop_visualize';
case 0x3e : return 'fetch_component_types'; case 0x3e : return 'fetch_component_types';
case 0x3f : return 'fetch_components'; case 0x3f : return 'fetch_components';
case 0x40 : return 'get_api_url';
case 0x41 : return 'get_physics_engine';
break; break;
} }
@ -326,13 +330,22 @@ GameLib.Event.EmitInstanceEvents = function(component) {
* Publish some event happened with some data * Publish some event happened with some data
* @param eventName * @param eventName
* @param data * @param data
* @param clientCallback
* @param clientErrorCallback
* @returns {number} of callbacks executed * @returns {number} of callbacks executed
*/ */
GameLib.Event.prototype.publish = function( GameLib.Event.prototype.publish = function(
eventName, eventName,
data data,
clientCallback,
clientErrorCallback
) { ) {
return GameLib.Event.Emit(eventName, data); return GameLib.Event.Emit(
eventName,
data,
clientCallback,
clientErrorCallback
);
}; };
/** /**
@ -362,6 +375,12 @@ GameLib.Event.Emit = function(
} }
} }
) )
} else {
if (clientErrorCallback) {
clientErrorCallback({
message : 'No subscriptions for event ' + eventName
})
}
} }
return count; return count;

View File

@ -330,30 +330,44 @@ GameLib.Component.prototype.getStorageDependencies = function() {
GameLib.Component.prototype.save = function() { GameLib.Component.prototype.save = function() {
this.buildIdToObject(); this.publish(
GameLib.Event.GET_API_URL,
null,
function(data) {
this.buildIdToObject();
for (var property in this.idToObject) { for (var property in this.idToObject) {
if ( if (
this.idToObject.hasOwnProperty(property) && this.idToObject.hasOwnProperty(property) &&
this.idToObject[property] instanceof GameLib.Component this.idToObject[property] instanceof GameLib.Component
) { ) {
var apiObject = this.idToObject[property].toApiObject(); var apiObject = this.idToObject[property].toApiObject();
apiObject.componentType = this.idToObject[property].componentType; apiObject.componentType = this.idToObject[property].componentType;
var storageDependencies = this.idToObject[property].getStorageDependencies(); var storageDependencies = this.idToObject[property].getStorageDependencies();
for (var storageProperty in storageDependencies) { for (var storageProperty in storageDependencies) {
if (storageDependencies.hasOwnProperty(storageProperty)) { if (storageDependencies.hasOwnProperty(storageProperty)) {
apiObject[storageProperty] = storageDependencies[storageProperty]; apiObject[storageProperty] = storageDependencies[storageProperty];
} }
} }
this.publish(
GameLib.Event.SAVE_COMPONENT,
{
apiUrl : data.apiUrl,
apiObject : apiObject
}
);
}
}
}.bind(this),
function(error) {
console.error(error);
throw new Error('Failed to get API URL: ' + error.message);
}
);
this.publish(
GameLib.Event.SAVE_COMPONENT,
apiObject
);
}
}
}; };

View File

@ -59,7 +59,7 @@ GameLib.D3.API.Mesh = function(
this.meshType = meshType; this.meshType = meshType;
if (GameLib.Utils.UndefinedOrNull(name)) { if (GameLib.Utils.UndefinedOrNull(name)) {
name = 'Mesh ' + id; name = 'Mesh (' + id + ')';
} }
this.name = name; this.name = name;
@ -99,7 +99,7 @@ GameLib.D3.API.Mesh = function(
this.skinWeights = skinWeights; this.skinWeights = skinWeights;
if (GameLib.Utils.UndefinedOrNull(materials)) { if (GameLib.Utils.UndefinedOrNull(materials)) {
materials = [new GameLib.D3.API.Material(null, GameLib.D3.Material.MATERIAL_TYPE_STANDARD, 'Material Mesh (' + this.id + ')')]; materials = [new GameLib.D3.API.Material(null, GameLib.D3.Material.MATERIAL_TYPE_STANDARD, 'Material (' + this.name + ')')];
} }
this.materials = materials; this.materials = materials;

View File

@ -37,12 +37,18 @@ GameLib.D3.API.PhysicsWorld = function(
this.gravity = gravity; this.gravity = gravity;
if (GameLib.Utils.UndefinedOrNull(broadphase)) { if (GameLib.Utils.UndefinedOrNull(broadphase)) {
broadphase = null; broadphase = new GameLib.D3.API.Broadphase(
null,
'Broadphase (Physics World ' + this.id + ')'
);
} }
this.broadphase = broadphase; this.broadphase = broadphase;
if (GameLib.Utils.UndefinedOrNull(solver)) { if (GameLib.Utils.UndefinedOrNull(solver)) {
solver = null; solver = new GameLib.D3.API.Solver(
null,
'Solver (Physics World ' + this.id + ')'
)
} }
this.solver = solver; this.solver = solver;

View File

@ -42,7 +42,7 @@ GameLib.D3.CustomCode.prototype.constructor = GameLib.D3.CustomCode;
GameLib.D3.CustomCode.prototype.createInstance = function() { GameLib.D3.CustomCode.prototype.createInstance = function() {
try { try {
var instance = new Function('data', this.code); var instance = new Function('data', this.code).bind(this);
return instance; return instance;
} catch (error) { } catch (error) {
/** /**
@ -58,7 +58,7 @@ GameLib.D3.CustomCode.prototype.createInstance = function() {
*/ */
GameLib.D3.CustomCode.prototype.updateInstance = function() { GameLib.D3.CustomCode.prototype.updateInstance = function() {
try { try {
this.instance = new Function('data', this.code); this.instance = new Function('data', this.code).bind(this);
this.publish( this.publish(
GameLib.Event.COMPILE_SUCCESS, GameLib.Event.COMPILE_SUCCESS,
{ {

View File

@ -177,6 +177,8 @@ GameLib.D3.Mesh = function (
*/ */
this.helper = null; this.helper = null;
this.updateRotationFromAxisAngle = true;
GameLib.Component.call( GameLib.Component.call(
this, this,
componentType, componentType,
@ -529,14 +531,22 @@ GameLib.D3.Mesh.prototype.updateInstance = function() {
this.instance.geometry = this.createInstanceGeometry(this.instance.geometry); this.instance.geometry = this.createInstanceGeometry(this.instance.geometry);
} }
this.quaternion.axis.instance.x = this.quaternion.axis.x; if (this.updateRotationFromAxisAngle) {
this.quaternion.axis.instance.y = this.quaternion.axis.y; this.quaternion.axis.instance.x = this.quaternion.axis.x;
this.quaternion.axis.instance.z = this.quaternion.axis.z; this.quaternion.axis.instance.y = this.quaternion.axis.y;
// this.quaternion.axis.instance.z = this.quaternion.axis.z;
// var v = new THREE.Vector3(); this.quaternion.instance.setFromAxisAngle(this.quaternion.axis.instance, this.quaternion.angle);
// v.applyAxisAngle(this.quaternion.axis.instance, this.quaternion.angle); this.instance.quaternion.copy(this.quaternion.instance);
this.quaternion.x = this.quaternion.instance.x;
this.quaternion.instance.setFromAxisAngle(this.quaternion.axis.instance, this.quaternion.angle); this.quaternion.y = this.quaternion.instance.y;
this.quaternion.z = this.quaternion.instance.z;
this.quaternion.w = this.quaternion.instance.w;
} else {
this.instance.quaternion.x = this.quaternion.x;
this.instance.quaternion.y = this.quaternion.y;
this.instance.quaternion.z = this.quaternion.z;
this.instance.quaternion.w = this.quaternion.w;
}
if (this.parentMesh && this.parentMesh.loaded) { if (this.parentMesh && this.parentMesh.loaded) {
@ -548,25 +558,12 @@ GameLib.D3.Mesh.prototype.updateInstance = function() {
this.instance.position.y = this.localPosition.y; this.instance.position.y = this.localPosition.y;
this.instance.position.z = this.localPosition.z; this.instance.position.z = this.localPosition.z;
// this.localRotation.x = this.localRotation.instance.x;
// this.localRotation.y = this.localRotation.instance.y;
// this.localRotation.z = this.localRotation.instance.z;
// this.instance.rotation.x = this.localRotation.x;
// this.instance.rotation.y = this.localRotation.y;
// this.instance.rotation.z = this.localRotation.z;
this.instance.scale.x = this.localScale.x; this.instance.scale.x = this.localScale.x;
this.instance.scale.y = this.localScale.y; this.instance.scale.y = this.localScale.y;
this.instance.scale.z = this.localScale.z; this.instance.scale.z = this.localScale.z;
} else { } else {
// this.localRotation.instance.applyAxisAngle(this.quaternion.axis.instance, this.quaternion.angle);
// this.localRotation.x = this.localRotation.instance.x;
// this.localRotation.y = this.localRotation.instance.y;
// this.localRotation.z = this.localRotation.instance.z;
this.instance.position.x = this.position.x + this.localPosition.x; this.instance.position.x = this.position.x + this.localPosition.x;
this.instance.position.y = this.position.y + this.localPosition.y; this.instance.position.y = this.position.y + this.localPosition.y;
this.instance.position.z = this.position.z + this.localPosition.z; this.instance.position.z = this.position.z + this.localPosition.z;
@ -575,13 +572,7 @@ GameLib.D3.Mesh.prototype.updateInstance = function() {
this.instance.scale.y = this.scale.y * this.localScale.y; this.instance.scale.y = this.scale.y * this.localScale.y;
this.instance.scale.z = this.scale.z * this.localScale.z; this.instance.scale.z = this.scale.z * this.localScale.z;
}
// this.instance.rotateX(this.localRotation.x);
// this.instance.rotateY(this.localRotation.y);
// this.instance.rotateZ(this.localRotation.z);
}
this.instance.quaternion.copy(this.quaternion.instance);
this.instance.up.x = this.up.x; this.instance.up.x = this.up.x;
this.instance.up.y = this.up.y; this.instance.up.y = this.up.y;
@ -879,9 +870,11 @@ GameLib.D3.Mesh.prototype.createInstanceDefaults = function(instance) {
instance.position.y = this.localPosition.y; instance.position.y = this.localPosition.y;
instance.position.z = this.localPosition.z; instance.position.z = this.localPosition.z;
instance.rotation.x = this.localRotation.x; instance.quaternion.x = this.quaternion.x;
instance.rotation.y = this.localRotation.y; instance.quaternion.y = this.quaternion.y;
instance.rotation.z = this.localRotation.z; instance.quaternion.z = this.quaternion.z;
instance.quaternion.w = this.quaternion.w;
instance.quaternion.setFromAxisAngle(this.quaternion.axis.instance, this.quaternion.angle);
instance.scale.x = this.localScale.x; instance.scale.x = this.localScale.x;
instance.scale.y = this.localScale.y; instance.scale.y = this.localScale.y;
@ -896,6 +889,7 @@ GameLib.D3.Mesh.prototype.createInstanceDefaults = function(instance) {
instance.quaternion.y = this.quaternion.y; instance.quaternion.y = this.quaternion.y;
instance.quaternion.z = this.quaternion.z; instance.quaternion.z = this.quaternion.z;
instance.quaternion.w = this.quaternion.w; instance.quaternion.w = this.quaternion.w;
instance.quaternion.setFromAxisAngle(this.quaternion.axis.instance, this.quaternion.angle);
instance.position.x = this.position.x + this.localPosition.x; instance.position.x = this.position.x + this.localPosition.x;
instance.position.y = this.position.y + this.localPosition.y; instance.position.y = this.position.y + this.localPosition.y;
@ -908,10 +902,6 @@ GameLib.D3.Mesh.prototype.createInstanceDefaults = function(instance) {
instance.up.x = this.up.x; instance.up.x = this.up.x;
instance.up.y = this.up.y; instance.up.y = this.up.y;
instance.up.z = this.up.z; instance.up.z = this.up.z;
instance.rotateX(this.localRotation.x);
instance.rotateY(this.localRotation.y);
instance.rotateZ(this.localRotation.z);
} }
instance.renderOrder = this.renderOrder; instance.renderOrder = this.renderOrder;
@ -1044,40 +1034,54 @@ GameLib.D3.Mesh.prototype.applyLocalPositionRotationScale = function() {
this.instance.geometry.applyMatrix(this.instance.matrix); this.instance.geometry.applyMatrix(this.instance.matrix);
this.instance.position.set(0,0,0); this.position.x = 0;
this.instance.rotation.set(0,0,0); this.position.y = 0;
this.position.z = 0;
this.scale.x = 1;
this.scale.y = 1;
this.scale.z = 1;
this.quaternion.axis.x = 0;
this.quaternion.axis.y = 0;
this.quaternion.axis.z = 0;
this.quaternion.axis.w = 1;
this.quaternion.angle = 0;
this.instance.position.set(0,0,0);
this.instance.quaternion.setFromAxisAngle(this.quaternion.axis.instance, this.quaternion.angle);
this.instance.scale.set(1,1,1); this.instance.scale.set(1,1,1);
this.instance.updateMatrix(); this.instance.updateMatrix();
this.updateVerticesFromGeometryInstance(this.instance.geometry); this.updateVerticesFromGeometryInstance(this.instance.geometry);
var geometry = this.createInstanceGeometry(); // var geometry = this.createInstanceGeometry();
//
// /**
// * The face normals got re-calculated - so update again the faces
// */
// this.updateVerticesFromGeometryInstance(this.instance.geometry);
//
// this.instance.geometry = geometry;
/** // this.position.x = 0;
* The face normals got re-calculated - so update again the faces // this.position.y = 0;
*/ // this.position.z = 0;
this.updateVerticesFromGeometryInstance(this.instance.geometry); //
// this.localPosition.x = 0;
this.instance.geometry = geometry; // this.localPosition.y = 0;
// this.localPosition.z = 0;
this.position.x = 0; //
this.position.y = 0; // this.localRotation.x = 0;
this.position.z = 0; // this.localRotation.y = 0;
// this.localRotation.z = 0;
this.localPosition.x = 0; //
this.localPosition.y = 0; // this.localScale.x = 1;
this.localPosition.z = 0; // this.localScale.y = 1;
// this.localScale.z = 1;
this.localRotation.x = 0; //
this.localRotation.y = 0; // this.updateInstance();
this.localRotation.z = 0;
this.localScale.x = 1;
this.localScale.y = 1;
this.localScale.z = 1;
this.updateInstance();
// //
// this.localPosition.x = this.instance.position.x; // this.localPosition.x = this.instance.position.x;
// this.localPosition.y = this.instance.position.y; // this.localPosition.y = this.instance.position.y;
@ -1106,7 +1110,7 @@ GameLib.D3.Mesh.prototype.applyLocalPositionRotationScale = function() {
/** /**
* Gets all children components of this Mesh * Gets all children components of this Mesh (all linked objects only - no object references i.e. string ids)
* @returns {Array} * @returns {Array}
*/ */
GameLib.D3.Mesh.prototype.getChildrenComponents = function() { GameLib.D3.Mesh.prototype.getChildrenComponents = function() {
@ -1116,28 +1120,32 @@ GameLib.D3.Mesh.prototype.getChildrenComponents = function() {
this.materials.map( this.materials.map(
function (material) { function (material) {
GameLib.Utils.PushUnique(components, material); if (material instanceof GameLib.D3.Material) {
GameLib.Utils.PushUnique(components, material);
for (var property in material.linkedObjects) { for (var property in material.linkedObjects) {
if ( if (
material.linkedObjects.hasOwnProperty(property) && material.linkedObjects.hasOwnProperty(property) &&
material.hasOwnProperty(property) && material.hasOwnProperty(property) &&
material[property] && material[property] &&
property !== 'parentEntity' typeof material[property] !== 'string' &&
) { property !== 'parentEntity'
GameLib.Utils.PushUnique(components, material[property]); ) {
for (var tProperty in material[property].linkedObjects) { GameLib.Utils.PushUnique(components, material[property]);
if ( for (var tProperty in material[property].linkedObjects) {
material[property].linkedObjects.hasOwnProperty(tProperty) && if (
material[property].hasOwnProperty(tProperty) && material[property].linkedObjects.hasOwnProperty(tProperty) &&
material[property][tProperty] && material[property].hasOwnProperty(tProperty) &&
tProperty !== 'parentEntity' material[property][tProperty] &&
) { typeof material[property][tProperty] !== 'string' &&
GameLib.Utils.PushUnique(components, material[property][tProperty]); tProperty !== 'parentEntity'
} ) {
} GameLib.Utils.PushUnique(components, material[property][tProperty]);
} }
} }
}
}
}
}.bind(this) }.bind(this)
); );

View File

@ -72,6 +72,10 @@ GameLib.D3.Mesh.Box.prototype.updateInstance = function() {
this.instance.userData.height !== this.height || this.instance.userData.height !== this.height ||
this.instance.userData.depth !== this.depth this.instance.userData.depth !== this.depth
) { ) {
this.instance.userData.width = this.width;
this.instance.userData.height = this.height;
this.instance.userData.depth = this.depth;
var geometry = new THREE.BoxGeometry( var geometry = new THREE.BoxGeometry(
this.width, this.width,
this.height, this.height,

View File

@ -121,6 +121,15 @@ GameLib.D3.Mesh.Cylinder.prototype.updateInstance = function() {
this.instance.userData.thetaStart !== this.thetaStart || this.instance.userData.thetaStart !== this.thetaStart ||
this.instance.userData.thetaLength !== this.thetaLength this.instance.userData.thetaLength !== this.thetaLength
) { ) {
this.instance.userData.radiusTop = this.radiusTop;
this.instance.userData.radiusBottom = this.radiusBottom;
this.instance.userData.height = this.height;
this.instance.userData.radiusSegments = this.radiusSegments;
this.instance.userData.heightSegments = this.heightSegments;
this.instance.userData.openEnded = this.openEnded;
this.instance.userData.thetaStart = this.thetaStart;
this.instance.userData.thetaLength = this.thetaLength;
var geometry = new THREE.CylinderGeometry( var geometry = new THREE.CylinderGeometry(
this.radiusTop, this.radiusTop,
this.radiusBottom, this.radiusBottom,

View File

@ -275,3 +275,47 @@ GameLib.D3.Mesh.Plane.prototype.generateHeightMapFromBumpMap = function() {
// this.updateInstance(); // this.updateInstance();
}; };
GameLib.D3.Mesh.Plane.prototype.createPhysicsObjects = function() {
GameLib.Event.Emit(
GameLib.Event.GET_PHYSICS_ENGINE,
null,
function(data){
var apiShapeSphere = new GameLib.D3.API.Shape(
null,
'Shape Plane (' + this.name + ')'
);
apiShapeSphere.parentMesh = this;
var shapeSphere = new GameLib.D3.Shape.Plane(
data.physics,
apiShapeSphere,
this.radius
);
var apiRigidBody = new GameLib.D3.API.RigidBody(
null,
'Rigid Body (' + this.name + ')'
);
apiRigidBody.shapes.push(shapeSphere);
var rigidBody = new GameLib.D3.RigidBody(
data.physics,
apiRigidBody
);
rigidBody.parentMesh = this;
}.bind(this),
function(error){
console.log(error.message);
throw new Error(error.message);
}
);
};

View File

@ -71,6 +71,11 @@ GameLib.D3.Mesh.Sphere.prototype.updateInstance = function() {
this.instance.userData.heightSegments !== this.heightSegments || this.instance.userData.heightSegments !== this.heightSegments ||
this.instance.userData.radius !== this.radius this.instance.userData.radius !== this.radius
) { ) {
this.instance.userData.widthSegments = this.widthSegments;
this.instance.userData.heightSegments = this.heightSegments;
this.instance.userData.radius = this.radius;
var geometry = new THREE.SphereGeometry( var geometry = new THREE.SphereGeometry(
this.radius, this.radius,
this.widthSegments, this.widthSegments,
@ -103,6 +108,69 @@ GameLib.D3.Mesh.Sphere.prototype.toApiObject = function() {
return apiMesh; return apiMesh;
}; };
GameLib.D3.Mesh.Sphere.prototype.createPhysicsObjects = function() {
GameLib.Event.Emit(
GameLib.Event.GET_PHYSICS_ENGINE,
null,
function(data){
var apiShapeSphere = new GameLib.D3.API.Shape(
null,
'Sphere Shape (' + this.name + ')'
);
apiShapeSphere.parentMesh = this;
var shapeSphere = new GameLib.D3.Shape.Sphere(
data.physics,
apiShapeSphere,
this.radius
);
var apiRigidBody = new GameLib.D3.API.RigidBody(
null,
'Rigid Body (' + this.name + ')',
1,
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);
var rigidBody = new GameLib.D3.RigidBody(
data.physics,
apiRigidBody
);
rigidBody.parentMesh = this;
}.bind(this),
function(error){
console.log(error.message);
throw new Error(error.message);
}
);
};
/** /**
* Converts a standard object mesh to a GameLib.D3.Mesh * Converts a standard object mesh to a GameLib.D3.Mesh
* @param graphics GameLib.D3.Graphics * @param graphics GameLib.D3.Graphics

View File

@ -41,14 +41,14 @@ GameLib.D3.PhysicsWorld = function(
} }
if (this.broadphase instanceof GameLib.D3.API.Broadphase) { if (this.broadphase instanceof GameLib.D3.API.Broadphase) {
return new GameLib.D3.Broadphase( this.broadphase = new GameLib.D3.Broadphase(
this.physics, this.physics,
this.broadphase this.broadphase
); );
} }
if (this.solver instanceof GameLib.D3.API.Solver) { if (this.solver instanceof GameLib.D3.API.Solver) {
return new GameLib.D3.Solver( this.solver = new GameLib.D3.Solver(
this.physics, this.physics,
this.solver this.solver
); );

View File

@ -133,7 +133,20 @@ GameLib.D3.RigidBody.prototype.updateInstance = function() {
this.instance.position.y = this.position.y; this.instance.position.y = this.position.y;
this.instance.position.z = this.position.z; this.instance.position.z = this.position.z;
this.instance.quaternion.setFromAxisAngle(new CANNON.Vec3(this.quaternion.axis.x, this.quaternion.axis.y, this.quaternion.axis.z), this.quaternion.angle); this.quaternion.axis.instance.x = this.quaternion.axis.x;
this.quaternion.axis.instance.y = this.quaternion.axis.y;
this.quaternion.axis.instance.z = this.quaternion.axis.z;
this.instance.quaternion.setFromAxisAngle(this.quaternion.axis.instance, this.quaternion.angle);
this.quaternion.x = this.instance.quaternion.x;
this.quaternion.y = this.instance.quaternion.y;
this.quaternion.z = this.instance.quaternion.z;
this.quaternion.w = this.instance.quaternion.w;
this.parentMesh.position.setFrom(this.position);
this.parentMesh.quaternion.setFrom(this.quaternion);
this.parentMesh.updateInstance();
this.instance.velocity.x = this.velocity.x; this.instance.velocity.x = this.velocity.x;
this.instance.velocity.y = this.velocity.y; this.instance.velocity.y = this.velocity.y;

View File

@ -138,3 +138,34 @@ GameLib.Quaternion.prototype.toApiObject = function() {
this.angle this.angle
); );
}; };
/**
* Checks if quaternion is equal to another quaternion
* @param quaternion
* @returns {boolean}
*/
GameLib.Quaternion.prototype.equals = function(quaternion) {
return (
this.x === quaternion.x &&
this.y === quaternion.y &&
this.z === quaternion.z &&
this.w === quaternion.w &&
this.axis.equals(quaternion.axis) &&
this.angle === quaternion.angle
);
};
GameLib.Quaternion.prototype.setFrom = function(quaternion) {
this.x = quaternion.x;
this.y = quaternion.y;
this.z = quaternion.z;
this.w = quaternion.w;
this.axis.setFrom(quaternion.axis);
this.angle = quaternion.angle;
};
GameLib.Quaternion.prototype.copy = function(quaternion) {
console.log('todo');
};

View File

@ -1451,7 +1451,8 @@ GameLib.System.GUI.prototype.buildGUI = function(data) {
if ( if (
result.template[property] instanceof GameLib.Vector2 || result.template[property] instanceof GameLib.Vector2 ||
result.template[property] instanceof GameLib.Vector3 || result.template[property] instanceof GameLib.Vector3 ||
result.template[property] instanceof GameLib.Vector4 result.template[property] instanceof GameLib.Vector4 ||
result.template[property] instanceof GameLib.Quaternion
) { ) {
if (!result.template[property].equals(component[property])) { if (!result.template[property].equals(component[property])) {
delete result.template[property]; delete result.template[property];
@ -1539,7 +1540,10 @@ GameLib.System.GUI.prototype.buildGUI = function(data) {
continue; continue;
} }
if (componentTemplate.template.linkedObjects[templateProperty] instanceof Array) { if (
componentTemplate.template.linkedObjects &&
componentTemplate.template.linkedObjects[templateProperty] instanceof Array
) {
this.buildArrayManagerControl(folder, componentTemplate, templateProperty); this.buildArrayManagerControl(folder, componentTemplate, templateProperty);
} }

View File

@ -23,6 +23,20 @@ GameLib.System.Physics = function(
this.afterRenderSubscription = null; this.afterRenderSubscription = null;
};
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.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( this.shapeInstanceCreatedSubscription = this.subscribe(
GameLib.Event.SHAPE_INSTANCE_CREATED, GameLib.Event.SHAPE_INSTANCE_CREATED,
this.shapeInstanceCreated this.shapeInstanceCreated
@ -46,19 +60,7 @@ GameLib.System.Physics = function(
this.arrayItemAddedSubscription = this.subscribe( this.arrayItemAddedSubscription = this.subscribe(
GameLib.Event.ARRAY_ITEM_ADDED, GameLib.Event.ARRAY_ITEM_ADDED,
this.arrayItemAdded this.arrayItemAdded
) );
};
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.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.worlds.map( this.worlds.map(
function(world) { function(world) {
@ -104,14 +106,39 @@ GameLib.System.Physics.prototype.beforeRender = function(data) {
this.worlds.map( this.worlds.map(
function(world) { function(world) {
world.instance.step(1 / 60.0); world.instance.step(data.delta);
this.rigidBodies.map( this.rigidBodies.map(
function(rigidBody){ function(rigidBody){
rigidBody.position.x = rigidBody.instance.position.x;
rigidBody.position.y = rigidBody.instance.position.y;
rigidBody.position.z = rigidBody.instance.position.z;
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.parentMesh.position.x = rigidBody.instance.position.x; rigidBody.parentMesh.position.x = rigidBody.instance.position.x;
rigidBody.parentMesh.position.y = rigidBody.instance.position.y; rigidBody.parentMesh.position.y = rigidBody.instance.position.y;
rigidBody.parentMesh.position.z = rigidBody.instance.position.z; rigidBody.parentMesh.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.instance.getVelocityAtWorldPoint(new CANNON.Vec3(0,0,0), rigidBody.velocity.instance);
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.updateInstance();
rigidBody.parentMesh.updateRotationFromAxisAngle = true;
} }
) )
}.bind(this) }.bind(this)
@ -119,9 +146,20 @@ GameLib.System.Physics.prototype.beforeRender = function(data) {
}; };
GameLib.System.Physics.prototype.solverInstanceCreated = function(data) { GameLib.System.Physics.prototype.solverInstanceCreated = function(data) {
console.log(data);
}; };
GameLib.System.Physics.prototype.arrayItemAdded = function(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) { GameLib.System.Physics.prototype.instanceCreated = function(data) {
@ -158,8 +196,17 @@ GameLib.System.Physics.prototype.instanceCreated = function(data) {
data.component.parentMesh = mesh; 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();
} }
}; };

View File

@ -4,7 +4,6 @@
* @param physics * @param physics
* @param coder * @param coder
* @param apiSystem GameLib.API.System * @param apiSystem GameLib.API.System
* @param apiUrl
* @param token * @param token
* @param apiUploadUrl * @param apiUploadUrl
* @param onImageLoaded * @param onImageLoaded
@ -20,7 +19,6 @@ GameLib.System.Storage = function(
physics, physics,
coder, coder,
apiSystem, apiSystem,
apiUrl,
token, token,
apiUploadUrl, apiUploadUrl,
onImageLoaded, onImageLoaded,
@ -44,12 +42,6 @@ GameLib.System.Storage = function(
apiSystem apiSystem
); );
if (GameLib.Utils.UndefinedOrNull(apiUrl)) {
console.warn('Need an API URL for a storage system');
apiUrl = '';
}
this.apiUrl = apiUrl;
if (GameLib.Utils.UndefinedOrNull(token)) { if (GameLib.Utils.UndefinedOrNull(token)) {
token = null; token = null;
} }
@ -159,57 +151,72 @@ GameLib.System.Storage.prototype.start = function() {
GameLib.System.Storage.prototype.delete = function(data) { GameLib.System.Storage.prototype.delete = function(data) {
if (typeof XMLHttpRequest === 'undefined') { this.publish(
console.log('Implement server side delete here'); GameLib.Event.GET_API_URL,
return; null,
} function(urlData) {
data.ids.map(function(id){ if (typeof XMLHttpRequest === 'undefined') {
var xhr = new XMLHttpRequest(); console.log('Implement server side delete here');
return;
xhr.open(
'POST',
this.apiUrl + '/component/delete/' + id
);
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
try {
var response = JSON.parse(this.responseText)
} catch (error) {
GameLib.Event.Emit(
GameLib.Event.DELETE_COMPONENT_ERROR,
{
message: this.responseText
}
)
}
if (response.result === 'success') {
GameLib.Event.Emit(
GameLib.Event.COMPONENT_DELETED,
{
message: response.message || 'Successfully saved the component'
}
)
} else {
GameLib.Event.Emit(
GameLib.Event.DELETE_COMPONENT_ERROR,
{
message: response.message || 'The server responded but failed to save the component'
}
)
}
} }
};
xhr.send(JSON.stringify({ data.ids.map(function(id){
session : this.token
})); var xhr = new XMLHttpRequest();
}.bind(this));
xhr.open(
'POST',
urlData.apiUrl + '/component/delete/' + id
);
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
try {
var response = JSON.parse(this.responseText)
} catch (error) {
GameLib.Event.Emit(
GameLib.Event.DELETE_COMPONENT_ERROR,
{
message: this.responseText
}
)
}
if (response.result === 'success') {
GameLib.Event.Emit(
GameLib.Event.COMPONENT_DELETED,
{
message: response.message || 'Successfully saved the component'
}
)
} else {
GameLib.Event.Emit(
GameLib.Event.DELETE_COMPONENT_ERROR,
{
message: response.message || 'The server responded but failed to save the component'
}
)
}
}
};
xhr.send(JSON.stringify({
session : this.token
}));
}.bind(this));
}.bind(this),
function(error) {
console.error(error.message);
throw new Error(error.message);
}
);
}; };
@ -227,7 +234,7 @@ GameLib.System.Storage.prototype.save = function(data) {
xhr.open( xhr.open(
'POST', 'POST',
this.apiUrl + '/component/create' data.apiUrl + '/component/create'
); );
xhr.setRequestHeader("Accept", "application/json"); xhr.setRequestHeader("Accept", "application/json");
@ -265,13 +272,13 @@ GameLib.System.Storage.prototype.save = function(data) {
}; };
xhr.send(JSON.stringify({ xhr.send(JSON.stringify({
component : data, component : data.apiObject,
session : this.token session : this.token
})); }));
}; };
GameLib.System.Storage.prototype.loadComponent = function(toProcess, includeDependencies, clientCallback, clientErrorCallback) { GameLib.System.Storage.prototype.loadComponent = function(apiUrl, toProcess, includeDependencies, clientCallback, clientErrorCallback) {
var loaded = []; var loaded = [];
@ -579,7 +586,7 @@ GameLib.System.Storage.prototype.loadComponent = function(toProcess, includeDepe
xhr.open( xhr.open(
'GET', 'GET',
this.apiUrl + '/component/load/' + id apiUrl + '/component/load/' + id
); );
xhr.send(); xhr.send();
@ -592,21 +599,32 @@ GameLib.System.Storage.prototype.loadComponent = function(toProcess, includeDepe
*/ */
GameLib.System.Storage.prototype.load = function(data, clientCallback, clientErrorCallback) { GameLib.System.Storage.prototype.load = function(data, clientCallback, clientErrorCallback) {
if (typeof XMLHttpRequest === 'undefined') { this.publish(
console.log('Implement server side load here'); GameLib.Event.GET_API_URL,
return; null,
} function(urlData) {
if (typeof XMLHttpRequest === 'undefined') {
console.log('Implement server side load here');
return;
}
if (data.ids && data.ids.length > 0) { if (data.ids && data.ids.length > 0) {
this.loadComponent( this.loadComponent(
data.ids, urlData.apiUrl,
data.includeDependencies, data.ids,
clientCallback, data.includeDependencies,
clientErrorCallback clientCallback,
)(data.ids[0], null); clientErrorCallback
} else { )(data.ids[0], null);
console.log('No components selected'); } else {
} console.log('No components selected');
}
}.bind(this),
function(error) {
console.error(error.message);
throw new Error(error.message);
}
);
}; };
@ -840,130 +858,143 @@ GameLib.System.Storage.prototype.loadImage = function(data) {
console.log('loading image : ' + data.image.name); console.log('loading image : ' + data.image.name);
var onLoaded = this.onImageLoaded; this.publish(
GameLib.Event.GET_API_URL,
null,
function(urlData) {
var onProgress = this.onImageProgress; var onLoaded = this.onImageLoaded;
var onError = this.onImageError; var onProgress = this.onImageProgress;
var image = data.image; var onError = this.onImageError;
var url = this.apiUrl + image.path + image.fileName + image.extension + '?ts=' + Date.now(); var image = data.image;
var preflight = new XMLHttpRequest(); var url = urlData.apiUrl + image.path + image.fileName + image.extension + '?ts=' + Date.now();
preflight.withCredentials = true; var preflight = new XMLHttpRequest();
preflight.open( preflight.withCredentials = true;
'OPTIONS',
url
);
preflight.setRequestHeader('Content-Type', 'application/json'); preflight.open(
'OPTIONS',
url
);
preflight.onload = function() { preflight.setRequestHeader('Content-Type', 'application/json');
var xhr = new XMLHttpRequest(); preflight.onload = function() {
xhr.withCredentials = true; var xhr = new XMLHttpRequest();
xhr.open('GET', url); xhr.withCredentials = true;
xhr.setRequestHeader('Content-Type', image.contentType); xhr.open('GET', url);
xhr.responseType = 'blob'; xhr.setRequestHeader('Content-Type', image.contentType);
xhr.onload = function() { xhr.responseType = 'blob';
try { xhr.onload = function() {
if (this.response.type !== 'application/json') {
var url = window.URL.createObjectURL(this.response);
} else {
if (onError) {
GameLib.Event.Emit( try {
GameLib.Event.IMAGE_NOT_FOUND, if (this.response.type !== 'application/json') {
var url = window.URL.createObjectURL(this.response);
} else {
if (onError) {
GameLib.Event.Emit(
GameLib.Event.IMAGE_NOT_FOUND,
{
image : image
}
);
onError(image, {message:'Image not found'});
return;
}
}
} catch (error) {
if (onError) {
GameLib.Event.Emit(
GameLib.Event.IMAGE_NOT_FOUND,
{
image : image
}
);
onError(image, {message:'Image not found'});
return;
}
}
var img = document.createElement('img');
img.onload = function() {
window.URL.revokeObjectURL(url);
image.instance = img;
image.loaded = true;
image.publish(
GameLib.Event.IMAGE_INSTANCE_CREATED,
{ {
image : image image: image
} }
); );
onError(image, {message:'Image not found'}); if (onLoaded) {
onLoaded(image, data.createTexture);
}
};
return; img.src = url;
};
xhr.onprogress = function(progressEvent) {
var progress = 0;
if (progressEvent.total !== 0) {
progress = Number(progressEvent.loaded / progressEvent.total);
progress *= 100;
} }
}
} catch (error) { if (onProgress) {
onProgress(image, progress);
}
image.size = progressEvent.total;
};
xhr.onerror = function(error) {
console.warn('image load failed for image ' + image.name);
if (onError) {
onError(image, error)
}
};
xhr.send();
};
preflight.onerror = function(error) {
console.warn('image pre-flight request failed for image ' + image.name);
if (onError) { if (onError) {
onError(image, error);
GameLib.Event.Emit(
GameLib.Event.IMAGE_NOT_FOUND,
{
image : image
}
);
onError(image, {message:'Image not found'});
return;
}
}
var img = document.createElement('img');
img.onload = function() {
window.URL.revokeObjectURL(url);
image.instance = img;
image.loaded = true;
image.publish(
GameLib.Event.IMAGE_INSTANCE_CREATED,
{
image: image
}
);
if (onLoaded) {
onLoaded(image, data.createTexture);
} }
}; };
img.src = url; preflight.send();
}; }.bind(this),
function(error) {
xhr.onprogress = function(progressEvent) { console.error(error.message);
throw new Error(error.message);
var progress = 0;
if (progressEvent.total !== 0) {
progress = Number(progressEvent.loaded / progressEvent.total);
progress *= 100;
}
if (onProgress) {
onProgress(image, progress);
}
image.size = progressEvent.total;
};
xhr.onerror = function(error) {
console.warn('image load failed for image ' + image.name);
if (onError) {
onError(image, error)
}
};
xhr.send();
};
preflight.onerror = function(error) {
console.warn('image pre-flight request failed for image ' + image.name);
if (onError) {
onError(image, error);
} }
}; );
preflight.send();
}; };
GameLib.System.Storage.prototype.stop = function() { GameLib.System.Storage.prototype.stop = function() {

View File

@ -124,3 +124,9 @@ GameLib.Vector3.prototype.copy = function() {
this.grain this.grain
) )
}; };
GameLib.Vector3.prototype.setFrom = function(vector3) {
this.x = vector3.x;
this.y = vector3.y;
this.z = vector3.z;
};