diff --git a/src/game-lib-component-path-following.js b/src/game-lib-component-path-following.js index 613d924..b665ec0 100644 --- a/src/game-lib-component-path-following.js +++ b/src/game-lib-component-path-following.js @@ -50,6 +50,7 @@ GameLib.D3.ComponentPathFollowing = function ComponentPathFollowing( this.currentPathValue = 0.0; this.currentSpeed = 0.0; this.direction = 0; + this.pastNormal = new THREE.Vector3(0,0,0); //#endif // extend @@ -68,41 +69,39 @@ GameLib.D3.ComponentPathFollowing.prototype.onUpdate = function( if(this.spline && this.trackThreeMeshArray) { - if(this.currentPathValue >= 1 || this.currentPathValue < 0) { - this.currentPathValue = 0; - } + // current speed - //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.instance.getPointAt(this.currentPathValue); + this.maxSpeed = 0.03; + this.accel = 0.1; - - // Update the current thing - var t = deltaTime * this.accel; - t = t * t * t * (t * (6.0 * t - 15.0) + 10.0); - this.currentSpeed = this.currentSpeed + (this.maxSpeed * this.direction - this.currentSpeed) * t; - - // update current path value & check bounds - this.currentPathValue = this.currentPathValue + ( (this.currentPathValue + this.currentSpeed) - this.currentPathValue ) * t; - if(this.currentSpeed >= this.maxSpeed) { + this.currentSpeed += this.accel * deltaTime * this.direction; + if(this.currentSpeed > this.maxSpeed) { this.currentSpeed = this.maxSpeed; - } else if (this.currentSpeed <= 0) { - this.currentSpeed = 0.0; + } + this.grain = (this.currentSpeed / 100.0); + + //this.grain = (deltaTime / 100.0); + + var currentPosition = this.splineCurve3.getPointAt(this.currentPathValue); + + this.currentPathValue += this.grain; + + if (this.currentPathValue >= 1) { + this.currentPathValue = this.currentPathValue - 1; } - - var nextIndex = this.currentPathValue; - if(nextIndex > 1.0) { - nextIndex = 0; + if (this.currentPathValue < 0) { + this.currentPathValue = 0.0; } - var nextPoint = this.spline.instance.getPointAt(nextIndex); + var futurePosition = this.splineCurve3.getPointAt(this.currentPathValue); // - - - - - - - - - - - - - - // Ray trace from the current position. + // Ray trace from the future position. // - - - - - - - - -- - - - - + ComponentPathFollowing_Three_Raycaster.set( - position, + futurePosition, new THREE.Vector3( 0, -1, @@ -110,28 +109,61 @@ GameLib.D3.ComponentPathFollowing.prototype.onUpdate = function( ) ); - var normal = new THREE.Vector3(0, 1, 0); - + var futureNormal = new THREE.Vector3(0, 1, 0); + var futurePositionRayCasted = new THREE.Vector3( + futurePosition.x, + futurePosition.y, + futurePosition.z + ); for(var m = 0, ml = this.trackThreeMeshArray.length; m < ml; ++m) { var intersect = ComponentPathFollowing_Three_Raycaster.intersectObject( this.trackThreeMeshArray[m] ); - if (intersect) { - normal = intersect[0].face.normal; + if(intersect && intersect.length > 0) { + futureNormal = intersect[0].face.normal; + futurePositionRayCasted = intersect[0].point; break; } } + // - - - - - - - - - - - - - + // Ray trace from the current position. + // - - - - - - - - -- - - - - + + ComponentPathFollowing_Three_Raycaster.set( + currentPosition, + new THREE.Vector3( + 0, + -1, + 0 + ) + ); + + var currentNormal = new THREE.Vector3(0, 1, 0); + for(var m = 0, ml = this.trackThreeMeshArray.length; m < ml; ++m) { + var intersect = ComponentPathFollowing_Three_Raycaster.intersectObject( + this.trackThreeMeshArray[m] + ); + + if(intersect && intersect.length > 0) { + currentNormal = intersect[0].face.normal; + break; + } + } + + //var avgNormal = currentNormal.add(this.pastNormal).add(futureNormal).normalize(); + var avgNormal = (this.pastNormal).add(futureNormal).normalize(); + this.pastNormal = futureNormal; + + var matrix = new THREE.Matrix4().lookAt( + currentPosition, + futurePosition, + avgNormal + ); - var matrix = new THREE.Matrix4().lookAt(position, nextPoint, normal); var quaternion = new THREE.Quaternion().setFromRotationMatrix(matrix); - // 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); - var targetVector = new THREE.Vector3( this.maxOffset.x * this.offset.x, this.maxOffset.y * this.offset.y, @@ -142,7 +174,10 @@ GameLib.D3.ComponentPathFollowing.prototype.onUpdate = function( this.currentOffset.x, this.currentOffset.y, this.currentOffset.z - ).lerp(targetVector, t); + ).lerp( + targetVector, + (this.grain * this.steeringSpeed) + ); this.currentOffset.x = lerpedOffset.x; this.currentOffset.y = lerpedOffset.y; @@ -154,11 +189,15 @@ GameLib.D3.ComponentPathFollowing.prototype.onUpdate = function( 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; + /* parentEntity.position.x = futurePositionRayCasted.x + transformedOffset.x; + parentEntity.position.y = futurePositionRayCasted.y + transformedOffset.y + this.parentEntity.mesh.geometry.boundingBox.y; + parentEntity.position.z = futurePositionRayCasted.z + transformedOffset.z; +*/ + + parentEntity.position.x = futurePosition.x + transformedOffset.x; + parentEntity.position.y = futurePosition.y + transformedOffset.y; + parentEntity.position.z = futurePosition.z + transformedOffset.z; // update rotation parentEntity.quaternion.x = quaternion.x; @@ -174,7 +213,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