diff --git a/defines/editor.js b/defines/editor.js index a3d2723..076a55e 100644 --- a/defines/editor.js +++ b/defines/editor.js @@ -1 +1,2 @@ //#define EDITOR__ +//#define DEBUG__ \ No newline at end of file diff --git a/defines/runtime.js b/defines/runtime.js index a3097b4..5ebd2fa 100644 --- a/defines/runtime.js +++ b/defines/runtime.js @@ -1 +1,2 @@ -//#define RUNTIME__ \ No newline at end of file +//#define RUNTIME__ +//#define DEBUG__ \ No newline at end of file diff --git a/src/game-lib-api-entity.js b/src/game-lib-api-entity.js index 965548a..a9b0a1d 100644 --- a/src/game-lib-api-entity.js +++ b/src/game-lib-api-entity.js @@ -61,3 +61,44 @@ GameLib.D3.API.Entity = function Entity( } this.mesh = mesh; }; + + +GameLib.D3.Entity = function Entity( + id, + name, + ids, + position, + quaternion, + scale +) { + this.id = id; + + if (GameLib.D3.Utils.UndefinedOrNull(name)) { + name = this.constructor.name; + } + this.name = name; + + if (GameLib.D3.Utils.UndefinedOrNull(ids)) { + ids = []; + } + this.ids = ids; + + // constructed at runtime + this.parentScene = null; + this.mesh = null; + + if(GameLib.D3.Utils.UndefinedOrNull(position)) { + position = new GameLib.D3.Vector3(0, 0, 0); + } + this.position = position; + + if(GameLib.D3.Utils.UndefinedOrNull(quaternion)) { + quaternion = new GameLib.D3.Vector4(0, 0, 0, 1); + } + this.quaternion = quaternion; + + if(GameLib.D3.Utils.UndefinedOrNull(scale)) { + scale = new GameLib.D3.Vector3(1, 1, 1); + } + this.scale = scale; +}; \ No newline at end of file diff --git a/src/game-lib-component-camera.js b/src/game-lib-component-camera.js index 7e51ae9..fa01219 100644 --- a/src/game-lib-component-camera.js +++ b/src/game-lib-component-camera.js @@ -28,7 +28,7 @@ GameLib.D3.ComponentCamera = function ComponentCamera( } // Component fields - this.camera = camera; + this.camera = camera.instance; }; ///////////////////////// Methods to override ////////////////////////// @@ -36,11 +36,11 @@ GameLib.D3.ComponentCamera.prototype.onLateUpdate = function( deltaTime, parentEntity ) { - if (this.camera) { - this.camera.instance.quaternion.copy(parentEntity.quaternion); - this.camera.instance.position.copy(parentEntity.position); - } else { - console.warn('Camera Component Camera not set!'); - throw new Error('Camera Component Camera not set!'); - } + this.camera.quaternion.copy(parentEntity.quaternion).normalize(); + this.camera.position.copy(parentEntity.position); + + parentEntity.quaternion.x = this.camera.quaternion.x; + parentEntity.quaternion.y = this.camera.quaternion.y; + parentEntity.quaternion.z = this.camera.quaternion.z; + parentEntity.quaternion.w = this.camera.quaternion.w; }; \ No newline at end of file diff --git a/src/game-lib-component-entity-parent.js b/src/game-lib-component-entity-parent.js index 54b12fb..b854918 100644 --- a/src/game-lib-component-entity-parent.js +++ b/src/game-lib-component-entity-parent.js @@ -1,14 +1,16 @@ /** * - * @param id - * @param name - * @param parent + * @param id {String} + * @param name {String} + * @param parent {GameLib.D3.Entity} + * @param centerToOrigin {Boolean} * @constructor */ GameLib.D3.ComponentEntityParent = function ComponentEntityParent( id, name, - parent + parent, + centerToOrigin ) { this.id = id || GameLib.D3.Tools.RandomId(); @@ -19,13 +21,19 @@ GameLib.D3.ComponentEntityParent = function ComponentEntityParent( this.parent = parent; this.parentEntity = null; + this.centerToOrigin = centerToOrigin; this.originPosition = new GameLib.D3.API.Vector3(0, 0, 0); - // Todo: this should be executed somewhere in game-lib-z, so that we don't execute it on every construction of an object. GameLib.D3.Utils.Extend(GameLib.D3.ComponentEntityParent, GameLib.D3.ComponentInterface); }; //#ifdef RUNTIME__ + +if(typeof THREE !== "undefined") { + ComponentEntityParent_TmpVector = new THREE.Vector3(); + ComponentEntityParent_TmpQuaternion = new THREE.Quaternion(); +} + ///////////////////////// Methods to override ////////////////////////// GameLib.D3.ComponentEntityParent.prototype.onLateUpdate = function( deltaTime, @@ -34,16 +42,50 @@ GameLib.D3.ComponentEntityParent.prototype.onLateUpdate = function( if(parentEntity && this.parent) { - // parentEntity = this component's parent - parentEntity.position.x = this.parent.position.x /*+ this.parentOrigin.x + this.originPosition.x*/; - parentEntity.position.y = this.parent.position.y /*+ this.parentOrigin.y + this.originPosition.y*/; - parentEntity.position.z = this.parent.position.z /*+ this.parentOrigin.z + this.originPosition.z*/; + if(this.centerToOrigin) { + this.parentEntity.position.x = ((this.parent.origin.x - this.originPosition.x) * this.parent.scale.x); + this.parentEntity.position.y = ((this.parent.origin.y - this.originPosition.y) * this.parent.scale.y); + this.parentEntity.position.z = ((this.parent.origin.z - this.originPosition.z) * this.parent.scale.z); - parentEntity.quaternion.x = this.parent.quaternion.x; - parentEntity.quaternion.y = this.parent.quaternion.y; - parentEntity.quaternion.z = this.parent.quaternion.z; - parentEntity.quaternion.w = this.parent.quaternion.w; + // apply quaternion + // + ComponentEntityParent_TmpQuaternion.set( + this.parent.quaternion.x, + this.parent.quaternion.y, + this.parent.quaternion.z, + this.parent.quaternion.w + ); + + ComponentEntityParent_TmpVector = + ComponentEntityParent_TmpVector.set( + this.parentEntity.position.x, + this.parentEntity.position.y, + this.parentEntity.position.z + ).applyQuaternion( + ComponentEntityParent_TmpQuaternion + ); + + this.parentEntity.position.x = ComponentEntityParent_TmpVector.x + this.parent.position.x; + this.parentEntity.position.y = ComponentEntityParent_TmpVector.y + this.parent.position.y; + this.parentEntity.position.z = ComponentEntityParent_TmpVector.z + this.parent.position.z; + + } else { + this.parentEntity.position.x = this.parent.position.x; + this.parentEntity.position.y = this.parent.position.y; + this.parentEntity.position.z = this.parent.position.z; + } + + this.parentEntity.quaternion.x = this.parent.quaternion.x; + this.parentEntity.quaternion.y = this.parent.quaternion.y; + this.parentEntity.quaternion.z = this.parent.quaternion.z; + this.parentEntity.quaternion.w = this.parent.quaternion.w; + + this.parentEntity.scale.x = this.parent.scale.x; + this.parentEntity.scale.y = this.parent.scale.y; + this.parentEntity.scale.z = this.parent.scale.z; + + this.parentEntity.mesh.updateMatrix(); } }; @@ -53,17 +95,21 @@ GameLib.D3.ComponentEntityParent.prototype.onSetParentEntity = function( ) { if(parentEntity && parentEntity.mesh) { - /* var scale = parentEntity.mesh.scale.clone(); - /!* parentEntity.mesh.updateMatrix(); - parentEntity.mesh.geometry.applyMatrix( parentEntity.mesh.matrix ); - parentEntity.mesh.updateMatrix();*!/ - */ + // The entities should already be scaled down and stuff + // The matrix transform should already be applied to the geometry. - /*this.parentOrigin = this.parent.mesh.geometry.center(); - this.originPosition = parentEntity.mesh.geometry.center();*/ + if(this.centerToOrigin) { + if(GameLib.D3.Utils.UndefinedOrNull(this.parent.origin)) { + this.parent.origin = this.parent.mesh.geometry.center(); + parentEntity.position.x = this.parent.position.x - this.parent.origin.x; + parentEntity.position.y = this.parent.position.y - this.parent.origin.y; + parentEntity.position.z = this.parent.position.z - this.parent.origin.z; + } + + this.originPosition = parentEntity.mesh.geometry.center(); + } - // don't forget to set the scale on the entity itself!!! } }; diff --git a/src/game-lib-component-entity-permutation.js b/src/game-lib-component-entity-permutation.js index 2ef0d5a..49a751a 100644 --- a/src/game-lib-component-entity-permutation.js +++ b/src/game-lib-component-entity-permutation.js @@ -23,11 +23,20 @@ GameLib.D3.ComponentEntityPermutation = function ComponentEntityPermutation( this.parentEntity = null; - this.positionOffset = positionOffset || new GameLib.D3.API.Vector3(0, 0, 0); - this.quaternionOffset = quaternionOffset || new GameLib.D3.API.Vector4(0, 0, 0, 1); - this.scaleOffset = scaleOffset || new GameLib.D3.API.Vector3(0, 0, 0); + if(GameLib.D3.Utils.UndefinedOrNull(positionOffset)) { + positionOffset = new GameLib.D3.Vector3(0, 0, 0); + } this.positionOffset = positionOffset; + + + if(GameLib.D3.Utils.UndefinedOrNull(quaternionOffset)) { + quaternionOffset = new GameLib.D3.Vector4(0, 0, 0, 1); + } this.quaternionOffset = quaternionOffset; + + + if(GameLib.D3.Utils.UndefinedOrNull(scaleOffset)) { + scaleOffset = new GameLib.D3.Vector3(1, 1, 1); + } this.scaleOffset = scaleOffset; - // Todo: this should be executed somewhere in game-lib-z, so that we don't execute it on every construction of an object. GameLib.D3.Utils.Extend(GameLib.D3.ComponentEntityPermutation, GameLib.D3.ComponentInterface); }; @@ -62,7 +71,7 @@ GameLib.D3.ComponentEntityPermutation.prototype.onUpdate = function( ComponentEntityPermutation_scale.copy(parentEntity.scale); ComponentEntityPermutation_offsetScale.copy(this.scaleOffset); - ComponentEntityPermutation_scale = ComponentEntityPermutation_scale.add(ComponentEntityPermutation_offsetScale); + ComponentEntityPermutation_scale = ComponentEntityPermutation_scale.multiply(ComponentEntityPermutation_offsetScale); parentEntity.position.x = ComponentEntityPermutation_position.x; parentEntity.position.y = ComponentEntityPermutation_position.y; diff --git a/src/game-lib-component-mesh-permutation.js b/src/game-lib-component-mesh-permutation.js index 3966f13..fb5502b 100644 --- a/src/game-lib-component-mesh-permutation.js +++ b/src/game-lib-component-mesh-permutation.js @@ -23,9 +23,9 @@ GameLib.D3.ComponentMeshPermutation = function ComponentMeshPermutation( this.parentEntity = null; - this.positionOffset = positionOffset || new GameLib.D3.API.Vector3(0, 0, 0); - this.quaternionOffset = quaternionOffset || new GameLib.D3.API.Vector4(0, 0, 0, 1); - this.scaleOffset = scaleOffset || new GameLib.D3.API.Vector3(0, 0, 0); + this.positionOffset = positionOffset || new GameLib.D3.Vector3(0, 0, 0); + this.quaternionOffset = quaternionOffset || new GameLib.D3.Vector4(0, 0, 0, 1); + this.scaleOffset = scaleOffset || new GameLib.D3.Vector3(1, 1, 1); // Todo: this should be executed somewhere in game-lib-z, so that we don't execute it on every construction of an object. GameLib.D3.Utils.Extend(GameLib.D3.ComponentMeshPermutation, GameLib.D3.ComponentInterface); @@ -62,7 +62,7 @@ GameLib.D3.ComponentMeshPermutation.prototype.onLateUpdate = function( ComponentMeshPermutation_scale.copy(parentEntity.mesh.scale); ComponentMeshPermutation_offsetScale.copy(this.scaleOffset); - ComponentMeshPermutation_scale = ComponentMeshPermutation_scale.add(ComponentMeshPermutation_offsetScale); + ComponentMeshPermutation_scale = ComponentMeshPermutation_scale.multiply(ComponentMeshPermutation_offsetScale); parentEntity.mesh.position.copy(ComponentMeshPermutation_position); parentEntity.mesh.quaternion.copy(ComponentMeshPermutation_quaternion); diff --git a/src/game-lib-component-offsettor.js b/src/game-lib-component-offsettor.js new file mode 100644 index 0000000..c7e0a87 --- /dev/null +++ b/src/game-lib-component-offsettor.js @@ -0,0 +1,66 @@ +/** + * + * @param id + * @param name + * @param axis {GameLib.D3.Vector3} + * @param getOffsetFunc {function} + * @param userData {Object} + * @constructor + */ +GameLib.D3.ComponentOffsettor = function ComponentOffsettor( + id, + name, + axis, + getOffsetFunc, + userData +) { + this.id = id || GameLib.D3.Tools.RandomId(); + + if (typeof name == 'undefined') { + name = this.constructor.name; + } + this.name = name; + this.parentEntity = null; + + this.axis = axis || new GameLib.D3.Vector3(); + this.offset = 1; + var component = this; + this.getOffsetFunc = getOffsetFunc || function(entity, component, userData){ return component.offset; }; + this.userData = userData; + + GameLib.D3.Utils.Extend(GameLib.D3.ComponentOffsettor, GameLib.D3.ComponentInterface); +}; + +//#ifdef RUNTIME__ + +///////////////////////// Methods to override ////////////////////////// +GameLib.D3.ComponentOffsettor.prototype.onLateUpdate = function( + deltaTime, + parentEntity +) { + if(parentEntity) { + + var pos = new THREE.Vector3( + this.axis.x, + this.axis.y, + this.axis.z + ).normalize().applyQuaternion( + new THREE.Quaternion( + parentEntity.quaternion.x, + parentEntity.quaternion.y, + parentEntity.quaternion.z, + parentEntity.quaternion.w + ) + ).multiplyScalar(this.getOffsetFunc( + parentEntity, + this, + this.userData + )); + + parentEntity.position.x += pos.x; + parentEntity.position.y += pos.y; + parentEntity.position.z += pos.z; + parentEntity.mesh.updateMatrix(); + } +}; +//#endif \ No newline at end of file diff --git a/src/game-lib-component-path-ai.js b/src/game-lib-component-path-ai.js index 6a85d37..3700ea5 100644 --- a/src/game-lib-component-path-ai.js +++ b/src/game-lib-component-path-ai.js @@ -31,47 +31,69 @@ GameLib.D3.ComponentPathAI = function ComponentPathAI( //#ifdef RUNTIME__ + +var componentPathAI_Raycast = function(from, to, settings, world) { + /* var raycastResult = new sys.physicsEngine.instance.RaycastResult(); + world.raycastClosest(from, to, settings, raycastResult); + return raycastResult;*/ +}; + + ///////////////////////// Methods to override ////////////////////////// GameLib.D3.ComponentPathAI.prototype.onUpdate = function( deltaTime, parentEntity ) { - var forward = false; + var forward = true; var backward = false; var left = false; var right = false; - /*if (this.keyForwardPressed) { // Forward [i] + // Ray tracing part. + + var scaledSensorLengthOffset = this.pathFollowingComponent.currentSpeed; + + /*world.raycastClosest( + fromC, + + toC, + + {}, + + result + );*/ + + + + + if(forward && !backward) { this.pathFollowingComponent.direction = 1; - } else if (this.keyBackPressed){ + } else if (backward && !forward) { this.pathFollowingComponent.direction = -1; } else { this.pathFollowingComponent.direction = 0; } - // left right - if (this.keyLeftPressed) { // Left [j] + if(left && !right) { this.pathFollowingComponent.offset.x = 0; this.pathFollowingComponent.offset.y = 0; this.pathFollowingComponent.offset.z = 1; - } else if (this.keyRightPressed) { // Right [l] + } else if (right && !left) { this.pathFollowingComponent.offset.x = 0; this.pathFollowingComponent.offset.y = 0; this.pathFollowingComponent.offset.z = -1; - }*/ - - // tell path following component to move forward - this.pathFollowingComponent.direction = 1; - - - - + } else { + this.pathFollowingComponent.offset.x = 0; + this.pathFollowingComponent.offset.y = 0; + this.pathFollowingComponent.offset.z = 0; + } // - - -- - - - - -- - - - - - - - - - - - - - - // D E B U G G I N G // - - - - - - - - - - - - - - - - - - + //#ifdef DEBUG__ if(this.sensorVisualizer) { for(var i = 0, l = this.sensors.length; i < l; ++i) { @@ -145,6 +167,7 @@ GameLib.D3.ComponentPathAI.prototype.onUpdate = function( } } + //#endif }; diff --git a/src/game-lib-component-path-controls.js b/src/game-lib-component-path-controls.js index 54ce11c..80aa98c 100644 --- a/src/game-lib-component-path-controls.js +++ b/src/game-lib-component-path-controls.js @@ -39,7 +39,8 @@ GameLib.D3.ComponentPathControls.prototype.onUpdate = function( if (this.keyForwardPressed) { // Forward [i] this.pathFollowingComponent.direction = 1; } else if (this.keyBackPressed){ - this.pathFollowingComponent.direction = -1; + this.pathFollowingComponent.direction = 0; + // this.pathFollowingComponent.direction = -1; } else { this.pathFollowingComponent.direction = 0; } diff --git a/src/game-lib-component-path-following.js b/src/game-lib-component-path-following.js index 3055590..eeb8b72 100644 --- a/src/game-lib-component-path-following.js +++ b/src/game-lib-component-path-following.js @@ -2,8 +2,9 @@ * * @param id * @param name - * @param spline - * @param acceleration + * @param splineCurve3 + * @param trackThreeMeshArray + * @param accel * @param maxSpeed * @param baseOffset * @param maxOffset @@ -13,9 +14,9 @@ GameLib.D3.ComponentPathFollowing = function ComponentPathFollowing( id, name, - spline, + splineCurve3, trackThreeMeshArray, - acceleration, + accel, maxSpeed, baseOffset, maxOffset, @@ -30,25 +31,28 @@ GameLib.D3.ComponentPathFollowing = function ComponentPathFollowing( this.name = name; this.parentEntity = null; - this.spline = spline; + this.splineCurve3 = splineCurve3; this.trackThreeMeshArray = trackThreeMeshArray; this.maxSpeed = maxSpeed || 10.0; - this.acceleration = acceleration || 2.0; + this.accel = accel || 2.0; - this.baseOffset = baseOffset || new GameLib.D3.API.Vector3(); - this.maxOffset = maxOffset || new GameLib.D3.API.Vector3(10, 10, 10); + this.baseOffset = baseOffset || new GameLib.D3.Vector3(); + this.maxOffset = maxOffset || new GameLib.D3.Vector3(10, 10, 10); this.steeringSpeed = steeringSpeed || 1.0; - //#ifdef RUNTIME__ // runtime code - this.offset = new GameLib.D3.API.Vector3(); // this one is our destination offset - this.currentOffset = new GameLib.D3.API.Vector3(); + + //#ifdef RUNTIME__ + this.offset = new GameLib.D3.Vector3(); // this one is our destination offset + this.currentOffset = new GameLib.D3.Vector3(); this.currentPathValue = 0.0; this.currentSpeed = 0.0; this.direction = 0; //#endif + + // extend GameLib.D3.Utils.Extend(GameLib.D3.ComponentPathFollowing, GameLib.D3.ComponentInterface); }; @@ -62,7 +66,7 @@ GameLib.D3.ComponentPathFollowing.prototype.onUpdate = function( parentEntity ) { - if(this.spline && this.trackThreeMeshArray) { + if(this.splineCurve3 && this.trackThreeMeshArray) { if(this.currentPathValue >= 1 || this.currentPathValue < 0) { this.currentPathValue = 0; @@ -70,7 +74,7 @@ GameLib.D3.ComponentPathFollowing.prototype.onUpdate = function( //To maintain a constant speed, you use .getPointAt( t ) instead of .getPoint( t ). //http://stackoverflow.com/questions/18400667/three-js-object-following-a-spline-path-rotation-tanget-issues-constant-sp - var position = this.spline.getPointAt(this.currentPathValue); + var position = this.splineCurve3.getPointAt(this.currentPathValue); // Update the current thing @@ -92,11 +96,11 @@ GameLib.D3.ComponentPathFollowing.prototype.onUpdate = function( nextIndex = 0; } - var nextPoint = this.spline.getPointAt(nextIndex); - + var nextPoint = this.splineCurve3.getPointAt(nextIndex); // - - - - - - - - - - - - - - // Raytrace from thhe current position. + // Ray trace from the current position. + // - - - - - - - - -- - - - - ComponentPathFollowing_Three_Raycaster.set( position, new THREE.Vector3( @@ -106,7 +110,6 @@ GameLib.D3.ComponentPathFollowing.prototype.onUpdate = function( ) ); - var normal = new THREE.Vector3(0, 1, 0); for(var m = 0, ml = this.trackThreeMeshArray.length; m < ml; ++m) { @@ -115,9 +118,7 @@ GameLib.D3.ComponentPathFollowing.prototype.onUpdate = function( ); if(intersect) { - normal = intersect[0].face.normal; - break; } } @@ -126,46 +127,44 @@ GameLib.D3.ComponentPathFollowing.prototype.onUpdate = function( var matrix = new THREE.Matrix4().lookAt(position, nextPoint, normal); var quaternion = new THREE.Quaternion().setFromRotationMatrix(matrix); - { // update position + // update position - t = deltaTime * ((this.currentSpeed / this.maxSpeed) * this.steeringSpeed); // put this into another variable - t = t * t * t * (t * (6.0 * t - 15.0) + 10.0); + t = deltaTime * ((this.currentSpeed / this.maxSpeed) * this.steeringSpeed); // put this into another variable + t = t * t * t * (t * (6.0 * t - 15.0) + 10.0); - var targetVector = new THREE.Vector3( - this.maxOffset.x * this.offset.x, - this.maxOffset.y * this.offset.y, - this.maxOffset.z * this.offset.z - ); + var targetVector = new THREE.Vector3( + this.maxOffset.x * this.offset.x, + this.maxOffset.y * this.offset.y, + this.maxOffset.z * this.offset.z + ); - var lerpedOffset = new THREE.Vector3( - this.currentOffset.x, - this.currentOffset.y, - this.currentOffset.z - ).lerp(targetVector, t); + var lerpedOffset = new THREE.Vector3( + this.currentOffset.x, + this.currentOffset.y, + this.currentOffset.z + ).lerp(targetVector, t); - this.currentOffset.x = lerpedOffset.x; - this.currentOffset.y = lerpedOffset.y; - this.currentOffset.z = lerpedOffset.z; + this.currentOffset.x = lerpedOffset.x; + this.currentOffset.y = lerpedOffset.y; + this.currentOffset.z = lerpedOffset.z; - var transformedOffset = new THREE.Vector3( - this.baseOffset.x + lerpedOffset.x, - this.baseOffset.y + lerpedOffset.y, - this.baseOffset.z + lerpedOffset.z - ).applyQuaternion(quaternion); + var transformedOffset = new THREE.Vector3( + this.baseOffset.x + lerpedOffset.x, + this.baseOffset.y + lerpedOffset.y, + this.baseOffset.z + lerpedOffset.z + ).applyQuaternion(quaternion); - // apply to parent rigidbody instead of direclty to the mesh. - parentEntity.position.x = position.x + transformedOffset.x; - parentEntity.position.y = position.y + transformedOffset.y; - parentEntity.position.z = position.z + transformedOffset.z; - } - { - // update rotation - parentEntity.quaternion.x = quaternion.x; - parentEntity.quaternion.y = quaternion.y; - parentEntity.quaternion.z = quaternion.z; - parentEntity.quaternion.w = quaternion.w; - } + // apply to parent rigidbody instead of direclty to the mesh. + parentEntity.position.x = position.x + transformedOffset.x; + parentEntity.position.y = position.y + transformedOffset.y; + parentEntity.position.z = position.z + transformedOffset.z; + + // update rotation + parentEntity.quaternion.x = quaternion.x; + parentEntity.quaternion.y = quaternion.y; + parentEntity.quaternion.z = quaternion.z; + parentEntity.quaternion.w = quaternion.w; } }; @@ -175,7 +174,7 @@ GameLib.D3.ComponentPathFollowing.prototype.onSetParentEntity = function( parentScene, parentEntity ) { - if(!this.spline) { + if(!this.splineCurve3) { console.error("NO PATH GIVEN"); } }; \ No newline at end of file diff --git a/src/game-lib-component-rotator.js b/src/game-lib-component-rotator.js new file mode 100644 index 0000000..69f6d3b --- /dev/null +++ b/src/game-lib-component-rotator.js @@ -0,0 +1,71 @@ +/** + * + * @param id + * @param name + * @param axis {GameLib.D3.Vector3} + * @param getRotationFunc {Function} + * @param userData {Object} + * @constructor + */ +GameLib.D3.ComponentRotator = function ComponentRotator( + id, + name, + axis, + getRotationFunc, + userData +) { + this.id = id || GameLib.D3.Tools.RandomId(); + + if (typeof name == 'undefined') { + name = this.constructor.name; + } + this.name = name; + this.parentEntity = null; + + this.rotation = 0; + var component = this; + this.axis = axis || new GameLib.D3.Vector3(); + this.getRotationFunc = getRotationFunc || function(entity, component, userData){ return component.rotation; }; + this.userData = userData; + + GameLib.D3.Utils.Extend(GameLib.D3.ComponentRotator, GameLib.D3.ComponentInterface); +}; + +//#ifdef RUNTIME__ + +///////////////////////// Methods to override ////////////////////////// +GameLib.D3.ComponentRotator.prototype.onLateUpdate = function( + deltaTime, + parentEntity +) { + if(parentEntity) { + + var quat = new THREE.Quaternion( + parentEntity.quaternion.x, + parentEntity.quaternion.y, + parentEntity.quaternion.z, + parentEntity.quaternion.w + ).multiply( + new THREE.Quaternion().setFromAxisAngle( + new THREE.Vector3( + this.axis.x, + this.axis.y, + this.axis.z + ), + this.getRotationFunc( + parentEntity, + this, + this.userData + ) + ) + ); + + parentEntity.quaternion.x = quat.x; + parentEntity.quaternion.y = quat.y; + parentEntity.quaternion.z = quat.z; + parentEntity.quaternion.w = quat.w; + + parentEntity.mesh.updateMatrix(); + } +}; +//#endif \ No newline at end of file diff --git a/src/game-lib-entity.js b/src/game-lib-entity.js index 767605d..f10dd51 100644 --- a/src/game-lib-entity.js +++ b/src/game-lib-entity.js @@ -26,26 +26,35 @@ GameLib.D3.Entity = function( GameLib.D3.Entity.prototype.update = function( deltaTime ) { - for (var componentId in this.ids) { - if (this.ids.hasOwnProperty(componentId)) { - var id = this.ids[componentId]; - var component = this.parentScene.idToComponent[id]; - if (component && component.onUpdate) { - component.onUpdate(deltaTime, this); - } + for(var c in this.ids) { + var id = this.ids[c]; + var component = this.parentScene.idToComponent[id]; + if(component && component.onUpdate) { + component.onUpdate(deltaTime, this); } } - if (this.mesh) { - this.mesh.position.set(this.position.x, this.position.y, this.position.z); - this.mesh.quaternion.set(this.quaternion.x, this.quaternion.y, this.quaternion.z, this.quaternion.w); - this.mesh.scale.set(this.scale.x, this.scale.y, this.scale.z); - this.mesh.updateInstance(); - } + // todo: maybe we only need to call this AFTER late update + this.updateMesh(); this.onUpdate(deltaTime); }; +GameLib.D3.Entity.prototype.updateMesh = function() { + if(this.mesh) { + this.mesh.position.set(this.position.x, this.position.y, this.position.z); + this.mesh.scale.set(this.scale.x, this.scale.y, this.scale.z); + this.mesh.quaternion.set(this.quaternion.x, this.quaternion.y, this.quaternion.z, this.quaternion.w).normalize(); + + // normalize the quaternion, if we have a mesh. + // if we don't do this, then the mesh will get stretched + this.quaternion.x = this.mesh.quaternion.x; + this.quaternion.y = this.mesh.quaternion.y; + this.quaternion.z = this.mesh.quaternion.z; + this.quaternion.w = this.mesh.quaternion.w; + } +}; + /** * Late updates the Entity and it's components * @param deltaTime Number @@ -53,16 +62,16 @@ GameLib.D3.Entity.prototype.update = function( GameLib.D3.Entity.prototype.lateUpdate = function( deltaTime ) { - for (var componentId in this.ids) { - if (this.ids.hasOwnProperty(componentId)) { - var id = this.ids[componentId]; - var component = this.parentScene.idToComponent[id]; - if (component && component.onLateUpdate) { - component.onLateUpdate(deltaTime, this); - } + for(var c in this.ids) { + var id = this.ids[c]; + var component = this.parentScene.idToComponent[id]; + if(component && component.onLateUpdate) { + component.onLateUpdate(deltaTime, this); } } + this.updateMesh(); + this.onLateUpdate(deltaTime); }; @@ -109,6 +118,12 @@ GameLib.D3.Entity.prototype.addComponent = function( } }; +GameLib.D3.Entity.prototype.removeComponent = function(component) { + if(component && component.id && this.parentScene.idToComponent[component.id]) { + this.ids = this.ids.splice(this.ids.indexOf(component), 1); + delete this.parentScene.idToComponent[component.id]; + } +}; GameLib.D3.Entity.prototype.getComponent = function( componentType diff --git a/src/game-lib-rigid-body.js b/src/game-lib-rigid-body.js index 214525c..594b267 100644 --- a/src/game-lib-rigid-body.js +++ b/src/game-lib-rigid-body.js @@ -16,6 +16,7 @@ * @param collisionFilterMask * @param fixedRotation * @param shape GameLib.D3.Shape + * @param kinematic Boolean * @returns {GameLib.D3.Physics.RigidBody} * @constructor */ @@ -35,7 +36,8 @@ GameLib.D3.RigidBody = function( collisionFilterGroup, collisionFilterMask, fixedRotation, - shape + shape, + kinematic ) { this.id = GameLib.D3.Tools.RandomId(); this.position = position || new GameLib.D3.API.Vector3(); @@ -53,6 +55,7 @@ GameLib.D3.RigidBody = function( this.collisionFilterMask = typeof collisionFilterMask == "undefined" ? 1 : collisionFilterMask; this.fixedRotation = typeof fixedRotation == "undefined" ? false : fixedRotation; this.shape = typeof shape == "undefined" ? null : shape; + this.kinematic = kinematic || false; this.engine = engine; this.engine.isNotCannonThrow(); @@ -150,19 +153,39 @@ GameLib.D3.RigidBody.prototype.onUpdate = function( parentEntity ) { if(parentEntity) { - var quaternion = new THREE.Quaternion(); - quaternion.copy(this.instance.quaternion); + if (this.kinematic) { + // reapply the entity's transform back to the rigid body, since it is kinematic + this.instance.position.x = parentEntity.position.x; + this.instance.position.y = parentEntity.position.y; + this.instance.position.z = parentEntity.position.z; - var position = new THREE.Vector3(); - position.copy(this.instance.position); + this.instance.quaternion.x = parentEntity.quaternion.x; + this.instance.quaternion.y = parentEntity.quaternion.y; + this.instance.quaternion.z = parentEntity.quaternion.z; + this.instance.quaternion.w = parentEntity.quaternion.w; - parentEntity.position.x = position.x; - parentEntity.position.y = position.y; - parentEntity.position.z = position.z; + this.instance.inertia.x = 0; + this.instance.inertia.y = 0; + this.instance.inertia.z = 0; - parentEntity.quaternion.x = quaternion.x; - parentEntity.quaternion.y = quaternion.y; - parentEntity.quaternion.z = quaternion.z; - parentEntity.quaternion.w = quaternion.w; + this.instance.velocity.x = 0; + this.instance.velocity.y = 0; + this.instance.velocity.z = 0; + } else { + var quaternion = new THREE.Quaternion(); + quaternion.copy(this.instance.quaternion); + + var position = new THREE.Vector3(); + position.copy(this.instance.position); + + parentEntity.position.x = position.x; + parentEntity.position.y = position.y; + parentEntity.position.z = position.z; + + parentEntity.quaternion.x = quaternion.x; + parentEntity.quaternion.y = quaternion.y; + parentEntity.quaternion.z = quaternion.z; + parentEntity.quaternion.w = quaternion.w; + } } }; \ No newline at end of file