From 32afbd1abbab624ccd24f3b79399d8e7201a671d Mon Sep 17 00:00:00 2001 From: polygonboutique Date: Tue, 8 Nov 2016 11:13:55 +0100 Subject: [PATCH] smooth follow components --- src/game-lib-component-follow.js | 44 ++++++++++++++---- src/game-lib-component-look-at.js | 76 ++++++++++++++++++++++--------- src/game-lib-game.js | 3 +- src/game-lib-scene.js | 1 + src/game-lib-shape.js | 7 ++- src/game-lib-vector-3.js | 8 ++++ src/game-lib-world.js | 68 ++++++++++++++++++++++++++- 7 files changed, 171 insertions(+), 36 deletions(-) diff --git a/src/game-lib-component-follow.js b/src/game-lib-component-follow.js index 05df78e..162f9dc 100644 --- a/src/game-lib-component-follow.js +++ b/src/game-lib-component-follow.js @@ -12,7 +12,7 @@ GameLib.D3.ComponentFollow = function( // this.targetEntity = targetEntity; - this.moveSpeed = 2.5; + this.moveSpeed = 12.5; if(GameLib.D3.Utils.UndefinedOrNull(targetOffset)) { @@ -23,19 +23,45 @@ GameLib.D3.ComponentFollow = function( this.minDistance = minDistance || 0; }; +ComponentFollow_Target_Vec3 = new THREE.Vector3(); +ComponentFollow_TargetToParent_Vec3 = new THREE.Vector3(); + ///////////////////////// Methods to override ////////////////////////// GameLib.D3.ComponentFollow.prototype.onUpdate = function( deltaTime, parentEntity ) { - if(this.targetEntity) { - var target = new THREE.Vector3().copy(this.targetEntity.position); - target.x += this.targetOffset.x; - target.y += this.targetOffset.y; - target.z += this.targetOffset.z; - if(target.distanceTo(parentEntity.position) > this.minDistance) { - parentEntity.position = parentEntity.position.lerp(target, this.moveSpeed * deltaTime); - } + if(this.targetEntity) { + + ComponentFollow_Target_Vec3.set( + this.targetEntity.position.x + this.targetOffset.x, + this.targetEntity.position.y + this.targetOffset.y, + this.targetEntity.position.z + this.targetOffset.z + ); + + ComponentFollow_TargetToParent_Vec3.set( + parentEntity.position.x - this.targetEntity.position.x, + parentEntity.position.y - this.targetEntity.position.y, + parentEntity.position.z - this.targetEntity.position.z + ); + + ComponentFollow_TargetToParent_Vec3.normalize(); + + ComponentFollow_TargetToParent_Vec3.set( + ComponentFollow_TargetToParent_Vec3.x * this.minDistance, + ComponentFollow_TargetToParent_Vec3.y * this.minDistance, + ComponentFollow_TargetToParent_Vec3.z * this.minDistance + ); + + ComponentFollow_Target_Vec3.set( + ComponentFollow_Target_Vec3.x + ComponentFollow_TargetToParent_Vec3.x, + ComponentFollow_Target_Vec3.y + ComponentFollow_TargetToParent_Vec3.y, + ComponentFollow_Target_Vec3.z + ComponentFollow_TargetToParent_Vec3.z + ); + + var t = deltaTime * this.moveSpeed; + //t = t * t * t * (t * (6.0 * t - 15.0) + 10.0); + parentEntity.position = parentEntity.position.lerp(ComponentFollow_Target_Vec3, t); } }; \ No newline at end of file diff --git a/src/game-lib-component-look-at.js b/src/game-lib-component-look-at.js index a876cdb..811ab40 100644 --- a/src/game-lib-component-look-at.js +++ b/src/game-lib-component-look-at.js @@ -11,9 +11,27 @@ GameLib.D3.ComponentLookAt = function( // todo: USE TARGET OFFSET. this.targetEntity = targetEntity; - this.targetOffset = targetOffset || new GameLib.D3.Vector3(0, 0, 0); + + if(GameLib.D3.Utils.UndefinedOrNull(targetOffset)) { + targetOffset = new GameLib.D3.Vector3(0, 0, 0); + } + this.targetOffset = targetOffset; + + this.lastTargetPosition = new GameLib.D3.Vector3(0, 0, 0); + this.lastTargetQuaternion = new GameLib.D3.Vector4(0, 0, 0, 1); + this.rotationSpeed = 22.0; }; + +ComponentLookAt_currentPos = new THREE.Vector3(); +ComponentLookAt_targetPos = new THREE.Vector3(); +ComponentLookAt_upVector = new THREE.Vector3(0, 1, 0); +ComponentLookAt_parentQuaternion = new THREE.Quaternion(0, 0, 0, 1); +ComponentLookAt_tmpQuaternion = new THREE.Quaternion(0, 0, 0, 1); +ComponentLookAt_newRotationQuaternion = new THREE.Quaternion(0, 0, 0, 1); +ComponentLookAt_lastRotationQuaternion = new THREE.Quaternion(0, 0, 0, 1); +ComponentLookAt_lookAtMatrix = new THREE.Matrix4(); + ///////////////////////// Methods to override ////////////////////////// GameLib.D3.ComponentLookAt.prototype.onUpdate = function( deltaTime, @@ -21,28 +39,42 @@ GameLib.D3.ComponentLookAt.prototype.onUpdate = function( ) { if(this.targetEntity) { var target = this.targetEntity.position; - var lookAtMatrix = new THREE.Matrix4().lookAt( - new THREE.Vector3( - parentEntity.position.x, - parentEntity.position.y, - parentEntity.position.z - ), - new THREE.Vector3( - target.x, - target.y, - target.z - ), - new THREE.Vector3( - 0, - 1, - 0 - ) + + ComponentLookAt_currentPos.set( + parentEntity.position.x, + parentEntity.position.y, + parentEntity.position.z ); - var quaternion = new THREE.Quaternion().setFromRotationMatrix(lookAtMatrix); - this.parentEntity.quaternion.x = quaternion.x; - this.parentEntity.quaternion.y = quaternion.y; - this.parentEntity.quaternion.z = quaternion.z; - this.parentEntity.quaternion.w = quaternion.w; + ComponentLookAt_lastRotationQuaternion.set( + this.lastTargetQuaternion.x, + this.lastTargetQuaternion.y, + this.lastTargetQuaternion.z, + this.lastTargetQuaternion.w + ); + + ComponentLookAt_targetPos.set( + target.x + this.targetOffset.x, + target.y + this.targetOffset.y, + target.z + this.targetOffset.z + ); + + ComponentLookAt_lookAtMatrix.lookAt( + ComponentLookAt_currentPos, + ComponentLookAt_targetPos, + ComponentLookAt_upVector + ); + + ComponentLookAt_tmpQuaternion.setFromRotationMatrix(ComponentLookAt_lookAtMatrix); + + var t = deltaTime * this.rotationSpeed; + t = t * t * t * (t * (6.0 * t - 15.0) + 10.0); + + THREE.Quaternion.slerp(ComponentLookAt_lastRotationQuaternion, ComponentLookAt_tmpQuaternion, ComponentLookAt_newRotationQuaternion, t); + + this.parentEntity.quaternion.x = this.lastTargetQuaternion.x = ComponentLookAt_newRotationQuaternion.x; + this.parentEntity.quaternion.y = this.lastTargetQuaternion.y = ComponentLookAt_newRotationQuaternion.y; + this.parentEntity.quaternion.z = this.lastTargetQuaternion.z = ComponentLookAt_newRotationQuaternion.z; + this.parentEntity.quaternion.w = this.lastTargetQuaternion.w = ComponentLookAt_newRotationQuaternion.w; } }; \ No newline at end of file diff --git a/src/game-lib-game.js b/src/game-lib-game.js index 1c8a19c..70cdadd 100644 --- a/src/game-lib-game.js +++ b/src/game-lib-game.js @@ -44,7 +44,8 @@ GameLib.D3.Game.prototype.update = function( for(var w in scene.worlds) { var world = scene.worlds[w]; - world.step(fixedDt); + // NOTE: We are calling the step function with a variable timestep! + world.step(dt); } scene.update(dt); diff --git a/src/game-lib-scene.js b/src/game-lib-scene.js index b8457e1..36919e7 100644 --- a/src/game-lib-scene.js +++ b/src/game-lib-scene.js @@ -97,6 +97,7 @@ GameLib.D3.Scene.prototype.createInstance = function ( var scene = new THREE.Scene(); scene.render = true; return scene; + //return {}; }; /** diff --git a/src/game-lib-shape.js b/src/game-lib-shape.js index 3ae8381..7494c3b 100644 --- a/src/game-lib-shape.js +++ b/src/game-lib-shape.js @@ -139,8 +139,11 @@ GameLib.D3.Shape.prototype.createInstance = function() { } ); } else if (this.shapeType == GameLib.D3.Shape.SHAPE_TYPE_CONVEX_HULL) { - console.warn('Shape type not implemented: ' + this.shapeType); - throw new Error('Shape type not implemented: ' + this.shapeType); + + instance = new this.engine.instance.ConvexPolyhedron( + this.vertices, this.indices + ); + } else { console.warn('Shape type not implemented: ' + this.shapeType); throw new Error('Shape type not implemented: ' + this.shapeType); diff --git a/src/game-lib-vector-3.js b/src/game-lib-vector-3.js index fee45c1..8ca7cfe 100644 --- a/src/game-lib-vector-3.js +++ b/src/game-lib-vector-3.js @@ -90,6 +90,14 @@ GameLib.D3.Vector3.prototype.copy = function () { ); }; +GameLib.D3.Vector3.prototype.lerp = function ( v, alpha ) { + return new GameLib.D3.Vector3( + this.x + ( v.x - this.x ) * alpha, + this.y + ( v.y - this.y ) * alpha, + this.z + ( v.z - this.z ) * alpha + ); +}; + GameLib.D3.Vector3.prototype.multiply = function (s) { if (s instanceof GameLib.D3.Vector3) { this.x *= s.x; diff --git a/src/game-lib-world.js b/src/game-lib-world.js index 1ea9861..1052503 100644 --- a/src/game-lib-world.js +++ b/src/game-lib-world.js @@ -106,10 +106,12 @@ GameLib.D3.World.prototype.step = function( timeStep ) { // todo: figure out, why this call to internal step is more stable for trimesh collisions..... - //this.worldObject.internalStep(timeStep); + //this.instance.internalStep(timeStep); //return; + //console.log("this should not be called."); - var now = performance.now() / 1000; + //var now = Date.now() / 1000; + var now = null; if(!this.lastCallTime){ // last call time not saved, cant guess elapsed time. Take a simple step. this.instance.step(timeStep); @@ -448,6 +450,68 @@ GameLib.D3.World.prototype.generateTriangleMeshShapeDivided = function( } }; +GameLib.D3.World.prototype.generateConvexPolyShape = function( + graphics, + mesh +) { + var processedFaces = 0; + var facesPerSubSection = 2; // *2 -> SUBDIVISION MESH + var subMeshesToMerge = 4; // *2 -> SUBDIVISION MESH + var facesToProcess = subMeshesToMerge * facesPerSubSection; + + var vertices = []; + var indicies = []; + + for(var i = 0; i <= mesh.geometry.faces.length; i++) { + if(processedFaces == facesToProcess || i == mesh.geometry.faces.length) { + + // try and create convex poly........... + var convexIndices = []; + for(var index = 0; index < indicies.length / 3; index++) { + convexIndices.push([ indicies[index * 3], indicies[index * 3 + 1], indicies[index * 3 + 2] ]); + } + + var convexVertices = []; + for(var vert = 0; vert < vertices.length / 3; vert++) { + convexVertices[vert] = new CANNON.Vec3(vertices[vert * 3] * mesh.scale.x, vertices[vert * 3 + 1] * mesh.scale.y, vertices[vert * 3 + 2] * mesh.scale.z); + } + + var meshShape = new GameLib.D3.Shape(this.engine, GameLib.D3.Shape.SHAPE_TYPE_CONVEX_HULL, {x:1,y:1,z:1},convexVertices, convexIndices); + + var body = new GameLib.D3.RigidBody(this.engine, 0, 1); + body.addShape(meshShape); + + this.addRigidBody(body); + + vertices = []; + indicies = []; + processedFaces = 0; + + console.log("SPLIT MESH TO CONVEX POLY"); + + if(i == mesh.geometry.faces.length) { + break; + } + } + + var face = mesh.geometry.faces[i]; + indicies.push(indicies.length); + indicies.push(indicies.length); + indicies.push(indicies.length); + + var v0 = mesh.geometry.vertices[face.a]; + var v1 = mesh.geometry.vertices[face.b]; + var v2 = mesh.geometry.vertices[face.c]; + + vertices.push(v0.x, v0.y, v0.z); + vertices.push(v1.x, v1.y, v1.z); + vertices.push(v2.x, v2.y, v2.z); + + processedFaces++; + } + +}; + /** * @param graphics GameLib.D3.Graphics * @param graphicsMesh THREE.Mesh