smooth follow components

beta.r3js.org
polygonboutique 2016-11-08 11:13:55 +01:00
parent 9208ea9257
commit 32afbd1abb
7 changed files with 171 additions and 36 deletions

View File

@ -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);
}
};

View File

@ -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;
}
};

View File

@ -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);

View File

@ -97,6 +97,7 @@ GameLib.D3.Scene.prototype.createInstance = function (
var scene = new THREE.Scene();
scene.render = true;
return scene;
//return {};
};
/**

View File

@ -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);

View File

@ -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;

View File

@ -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