path follow component migrated to editor

beta.r3js.org
Theunis J. Botha 2016-12-07 15:20:41 +01:00
parent 89d7883418
commit f774cad759
12 changed files with 755 additions and 229 deletions

View File

@ -0,0 +1,36 @@
/**
* Api Matrix 4
* @param row0 GameLib.D3.API.Vector4
* @param row1 GameLib.D3.API.Vector4
* @param row2 GameLib.D3.API.Vector4
* @param row3 GameLib.D3.API.Vector4
* @constructor
*/
GameLib.D3.API.Matrix4 = function ApiMatrix4(
row0,
row1,
row2,
row3
) {
this.rows = [];
if (GameLib.D3.Utils.UndefinedOrNull(row0)) {
row0 = new GameLib.D3.API.Vector4(1, 0, 0, 0);
}
this.rows[0] = row0;
if (GameLib.D3.Utils.UndefinedOrNull(row1)) {
row1 = new GameLib.D3.API.Vector4(0, 1, 0, 0);
}
this.rows[1] = row1;
if (GameLib.D3.Utils.UndefinedOrNull(row2)) {
row2 = new GameLib.D3.API.Vector4(0, 0, 1, 0);
}
this.rows[2] = row2;
if (GameLib.D3.Utils.UndefinedOrNull(row3)) {
row3 = new GameLib.D3.API.Vector4(0, 0, 0, 1);
}
this.rows[3] = row3;
};

View File

@ -1,5 +1,8 @@
/** /**
* API Spline * API Spline
* @param id String
* @param name String
* @param vertices GameLib.D3.API.Vector3[]
* @constructor * @constructor
*/ */
GameLib.D3.API.Spline = function( GameLib.D3.API.Spline = function(

View File

@ -1,6 +1,15 @@
GameLib.D3.API.Vector2 = function Vector2(x, y) { GameLib.D3.API.Vector2 = function ApiVector2(x, y) {
this.x = x || 0;
this.y = y || 0; if (GameLib.D3.Utils.UndefinedOrNull(x)) {
x = 0;
}
this.x = x;
if (GameLib.D3.Utils.UndefinedOrNull(y)) {
y = 0;
}
this.y = y;
}; };
GameLib.D3.API.Vector2.prototype.copy = function () { GameLib.D3.API.Vector2.prototype.copy = function () {

View File

@ -1,5 +1,18 @@
GameLib.D3.API.Vector3 = function Vector3(x, y, z) { GameLib.D3.API.Vector3 = function ApiVector3(x, y, z) {
this.x = x || 0;
this.y = y || 0; if (GameLib.D3.Utils.UndefinedOrNull(x)) {
this.z = z || 0; x = 0;
}
this.x = x;
if (GameLib.D3.Utils.UndefinedOrNull(y)) {
y = 0;
}
this.y = y;
if (GameLib.D3.Utils.UndefinedOrNull(z)) {
z = 0;
}
this.z = z;
}; };

View File

@ -1,6 +1,23 @@
GameLib.D3.API.Vector4 = function Vector4(x, y, z, w) { GameLib.D3.API.Vector4 = function ApiVector4(x, y, z, w) {
this.x = x || 0;
this.y = y || 0; if (GameLib.D3.Utils.UndefinedOrNull(x)) {
this.z = z || 0; x = 0;
this.w = w || 1; }
this.x = x;
if (GameLib.D3.Utils.UndefinedOrNull(y)) {
y = 0;
}
this.y = y;
if (GameLib.D3.Utils.UndefinedOrNull(z)) {
z = 0;
}
this.z = z;
if (GameLib.D3.Utils.UndefinedOrNull(w)) {
w = 1;
}
this.w = w;
}; };

View File

@ -1,88 +1,212 @@
/** /**
* * This component makes the parentEntity (ex. car) follow the path provided by the spline
* @param id * @param id String
* @param name * @param name String
* @param graphics GameLib.D3.Graphics
* @param parentEntity GameLib.D3.Entity
* @param spline GameLib.D3.Spline * @param spline GameLib.D3.Spline
* @param meshes[] GameLib.D3.Mesh * @param mesh GameLib.D3.Mesh
* @param accel * @param accelleration Number
* @param maxSpeed * @param maxSpeed Number
* @param baseOffset * @param baseOffset GameLib.D3.Vector
* @param maxOffset * @param maxOffset GameLib.D3.Vector
* @param steeringSpeed * @param steeringSpeed Number
* @param offset GameLib.D3.Vector3
* @param currentOffset GameLib.D3.Vector3
* @param currentPathValue Number
* @param currentSpeed Number
* @param direction Number
* @param mx GameLib.D3.Utils.MovingAverage
* @param my GameLib.D3.Utils.MovingAverage
* @param mz GameLib.D3.Utils.MovingAverage
* @param raycaster GameLib.D3.Raycaster
* @param currentPosition GameLib.D3.Vector3
* @param futurePosition GameLib.D3.Vector3
* @param up GameLib.D3.Vector3
* @param rotationMatrix GameLib.D3.Matrix4
* @param rotationVector GameLib.D3.Vector4
* @constructor * @constructor
*/ */
GameLib.D3.ComponentPathFollowing = function ComponentPathFollowing( GameLib.D3.ComponentPathFollowing = function ComponentPathFollowing(
id, id,
name, name,
graphics,
parentEntity,
spline, spline,
meshes, mesh,
accel, accelleration,
maxSpeed, maxSpeed,
baseOffset, baseOffset,
maxOffset, maxOffset,
steeringSpeed steeringSpeed,
offset,
currentOffset,
currentPathValue,
currentSpeed,
direction,
mx,
my,
mz,
raycaster,
currentPosition,
futurePosition,
up,
rotationMatrix,
rotationVector
) { ) {
this.id = id || GameLib.D3.Utils.RandomId(); if (GameLib.D3.Utils.UndefinedOrNull(id)) {
id = GameLib.D3.Utils.RandomId();
}
this.id = id;
if (typeof name == 'undefined') { if (GameLib.D3.Utils.UndefinedOrNull(name)) {
name = this.constructor.name; name = this.constructor.name;
} }
this.name = name; this.name = name;
this.parentEntity = null;
if (GameLib.D3.Utils.UndefinedOrNull(parentEntity)) {
parentEntity = null;
}
this.parentEntity = parentEntity;
if (GameLib.D3.Utils.UndefinedOrNull(spline)) {
spline = null;
}
this.spline = spline; this.spline = spline;
this.trackThreeMeshArray = mesh;
this.maxSpeed = maxSpeed || 10.0; if (GameLib.D3.Utils.UndefinedOrNull(mesh)) {
this.accel = accel || 2.0; mesh = null;
}
this.mesh = mesh;
this.baseOffset = baseOffset || new GameLib.D3.API.Vector3(); if (GameLib.D3.Utils.UndefinedOrNull(maxSpeed)) {
this.maxOffset = maxOffset || new GameLib.D3.API.Vector3(10, 10, 10); maxSpeed = 0.03;
this.steeringSpeed = steeringSpeed || 1.0; }
this.maxSpeed = maxSpeed;
if (GameLib.D3.Utils.UndefinedOrNull(accelleration)) {
accelleration = 0.1;
}
this.accelleration = accelleration;
// runtime code if (GameLib.D3.Utils.UndefinedOrNull(baseOffset)) {
baseOffset = new GameLib.D3.Vector3(graphics, this, new GameLib.D3.API.Vector3(), 0.1);
}
this.baseOffset = baseOffset;
//#ifdef RUNTIME__ if (GameLib.D3.Utils.UndefinedOrNull(maxOffset)) {
this.offset = new GameLib.D3.API.Vector3(); // this one is our destination offset maxOffset = new GameLib.D3.Vector3(graphics, this, new GameLib.D3.API.Vector3(10, 10, 10), 0.1);
this.currentOffset = new GameLib.D3.API.Vector3(); }
this.currentPathValue = 0.0; this.maxOffset = maxOffset;
this.currentSpeed = 0.0;
this.direction = 0; if (GameLib.D3.Utils.UndefinedOrNull(steeringSpeed)) {
this.pastNormal = new THREE.Vector3(0,0,0); steeringSpeed = 1.0;
//#endif }
this.steeringSpeed = steeringSpeed;
if (GameLib.D3.Utils.UndefinedOrNull(offset)) {
offset = new GameLib.D3.Vector3(graphics, this, new GameLib.D3.API.Vector3(), 0.1);
}
this.offset = offset;
if (GameLib.D3.Utils.UndefinedOrNull(currentOffset)) {
currentOffset = new GameLib.D3.Vector3(graphics, this, new GameLib.D3.API.Vector3(), 0.1);
}
this.currentOffset = currentOffset;
if (GameLib.D3.Utils.UndefinedOrNull(currentPathValue)) {
currentPathValue = 0;
}
this.currentPathValue = currentPathValue;
if (GameLib.D3.Utils.UndefinedOrNull(currentSpeed)) {
currentSpeed = 0;
}
this.currentSpeed = currentSpeed;
if (GameLib.D3.Utils.UndefinedOrNull(direction)) {
direction = 1;
}
this.direction = direction;
if (GameLib.D3.Utils.UndefinedOrNull(mx)) {
mx = new GameLib.D3.Utils.MovingAverage(10);
}
this.mx = mx;
if (GameLib.D3.Utils.UndefinedOrNull(my)) {
my = new GameLib.D3.Utils.MovingAverage(10);
}
this.my = my;
if (GameLib.D3.Utils.UndefinedOrNull(mz)) {
mz = new GameLib.D3.Utils.MovingAverage(10);
}
this.mz = mz;
if (GameLib.D3.Utils.UndefinedOrNull(raycaster)) {
raycaster = new GameLib.D3.Raycaster(
graphics,
new GameLib.D3.Vector3(
graphics,
this,
new GameLib.D3.API.Vector3()
),
new GameLib.D3.Vector3(
graphics,
this,
new GameLib.D3.API.Vector3(0, -1, 0)
)
);
}
this.raycaster = raycaster;
if (GameLib.D3.Utils.UndefinedOrNull(currentPosition)) {
currentPosition = new GameLib.D3.Vector3(graphics, this, new GameLib.D3.API.Vector3(), 0.1);
}
this.currentPosition = currentPosition;
if (GameLib.D3.Utils.UndefinedOrNull(futurePosition)) {
futurePosition = new GameLib.D3.Vector3(graphics, this, new GameLib.D3.API.Vector3(), 0.1);
}
this.futurePosition = futurePosition;
if (GameLib.D3.Utils.UndefinedOrNull(up)) {
up = new GameLib.D3.Vector3(graphics, this, new GameLib.D3.API.Vector3(0, 1, 0), 0.1);
}
this.up = up;
if (GameLib.D3.Utils.UndefinedOrNull(rotationMatrix)) {
rotationMatrix = new GameLib.D3.Matrix4(
graphics,
this,
new GameLib.D3.API.Matrix4()
);
}
this.rotationMatrix = rotationMatrix;
if (GameLib.D3.Utils.UndefinedOrNull(rotationVector)) {
rotationVector = new GameLib.D3.Vector4(graphics, this, new GameLib.D3.API.Vector4(), 0.1);
}
this.rotationVector = rotationVector;
// extend
GameLib.D3.Utils.Extend(GameLib.D3.ComponentPathFollowing, GameLib.D3.ComponentInterface); GameLib.D3.Utils.Extend(GameLib.D3.ComponentPathFollowing, GameLib.D3.ComponentInterface);
}; };
//#ifdef RUNTIME__
ComponentPathFollowing_Three_Raycaster = new THREE.Raycaster();
///////////////////////// Methods to override ////////////////////////// ///////////////////////// Methods to override //////////////////////////
GameLib.D3.ComponentPathFollowing.prototype.onUpdate = function( GameLib.D3.ComponentPathFollowing.prototype.onUpdate = function(
deltaTime, deltaTime
parentEntity
) { ) {
if(this.spline && this.trackThreeMeshArray) { if (this.spline && this.mesh) {
// current speed this.currentSpeed += this.accelleration * deltaTime * this.direction;
this.maxSpeed = 0.03;
this.accel = 0.1;
this.currentSpeed += this.accel * deltaTime * this.direction;
if(this.currentSpeed > this.maxSpeed) { if(this.currentSpeed > this.maxSpeed) {
this.currentSpeed = this.maxSpeed; this.currentSpeed = this.maxSpeed;
} }
this.grain = (this.currentSpeed / 100.0); this.grain = (this.currentSpeed / 100.0);
//this.grain = (deltaTime / 100.0); this.currentPosition = this.spline.getPointAt(this.currentPathValue);
var currentPosition = this.splineCurve3.getPointAt(this.currentPathValue);
this.currentPathValue += this.grain; this.currentPathValue += this.grain;
@ -94,126 +218,148 @@ GameLib.D3.ComponentPathFollowing.prototype.onUpdate = function(
this.currentPathValue = 0.0; this.currentPathValue = 0.0;
} }
var futurePosition = this.splineCurve3.getPointAt(this.currentPathValue); this.futurePosition = this.spline.getPointAt(this.currentPathValue);
// - - - - - - - - - - - - - // - - - - - - - - - - - - -
// Ray trace from the future position. // Ray trace from the future position.
// - - - - - - - - -- - - - - // - - - - - - - - -- - - - -
ComponentPathFollowing_Three_Raycaster.set( this.raycaster.setPosition(
futurePosition, this.futurePosition
new THREE.Vector3(
0,
-1,
0
)
); );
var futureNormal = new THREE.Vector3(0, 1, 0); // var futureNormal = new THREE.Vector3(0, 1, 0);
var futurePositionRayCasted = new THREE.Vector3( // var futurePositionRayCasted = new THREE.Vector3(
futurePosition.x, // futurePosition.x,
futurePosition.y, // futurePosition.y,
futurePosition.z // futurePosition.z
); // );
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) { var normal = this.raycaster.getFaceNormal(this.mesh);
futureNormal = intersect[0].face.normal;
futurePositionRayCasted = intersect[0].point; this.up.x = this.mx(normal.x);
break; this.up.y = this.my(normal.y);
} this.up.z = this.mz(normal.z);
}
this.up.updateInstance();
// - - - - - - - - - - - - - // - - - - - - - - - - - - -
// Ray trace from the current position. // Ray trace from the current position.
// - - - - - - - - -- - - - - // - - - - - - - - -- - - - -
//
// ComponentPathFollowing_Three_Raycaster.set(
// currentPosition,
// new THREE.Vector3(
// 0,
// -1,
// 0
// )
// );
ComponentPathFollowing_Three_Raycaster.set( // var currentNormal = new THREE.Vector3(0, 1, 0);
currentPosition, // for(var m = 0, ml = this.trackThreeMeshArray.length; m < ml; ++m) {
new THREE.Vector3( // var intersect = ComponentPathFollowing_Three_Raycaster.intersectObject(
0, // this.meshes[m].instance
-1, // );
0 //
) // if(intersect && intersect.length > 0) {
); // currentNormal = intersect[0].face.normal;
// break;
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 = currentNormal.add(this.pastNormal).add(futureNormal).normalize();
var avgNormal = (this.pastNormal).add(futureNormal).normalize(); // var avgNormal = (this.pastNormal).add(futureNormal).normalize();
this.pastNormal = futureNormal; // this.pastNormal = futureNormal;
var matrix = new THREE.Matrix4().lookAt(
currentPosition, this.rotationMatrix.lookAt(
futurePosition, this.currentPosition,
avgNormal this.futurePosition,
this.up
); );
var quaternion = new THREE.Quaternion().setFromRotationMatrix(matrix); this.rotationVector.setFromRotationMatrix(this.rotationMatrix);
var targetVector = new THREE.Vector3( // var targetVector = new THREE.Vector3(
this.maxOffset.x * this.offset.x, // this.maxOffset.x * this.offset.x,
this.maxOffset.y * this.offset.y, // this.maxOffset.y * this.offset.y,
this.maxOffset.z * this.offset.z // this.maxOffset.z * this.offset.z
); // );
//
var lerpedOffset = new THREE.Vector3( // var lerpedOffset = new THREE.Vector3(
this.currentOffset.x, // this.currentOffset.x,
this.currentOffset.y, // this.currentOffset.y,
this.currentOffset.z // this.currentOffset.z
).lerp( // ).lerp(
targetVector, // targetVector,
(this.grain * this.steeringSpeed) // (this.grain * this.steeringSpeed)
); // );
//
this.currentOffset.x = lerpedOffset.x; // this.currentOffset.x = lerpedOffset.x;
this.currentOffset.y = lerpedOffset.y; // this.currentOffset.y = lerpedOffset.y;
this.currentOffset.z = lerpedOffset.z; // this.currentOffset.z = lerpedOffset.z;
//
var transformedOffset = new THREE.Vector3( // var transformedOffset = new THREE.Vector3(
this.baseOffset.x + lerpedOffset.x, // this.baseOffset.x + lerpedOffset.x,
this.baseOffset.y + lerpedOffset.y, // this.baseOffset.y + lerpedOffset.y,
this.baseOffset.z + lerpedOffset.z // this.baseOffset.z + lerpedOffset.z
).applyQuaternion(quaternion); // ).applyQuaternion(quaternion);
// apply to parent rigidbody instead of direclty to the mesh. // apply to parent rigidbody instead of direclty to the mesh.
/* parentEntity.position.x = futurePositionRayCasted.x + transformedOffset.x; /* parentEntity.position.x = futurePositionRayCasted.x + transformedOffset.x;
parentEntity.position.y = futurePositionRayCasted.y + transformedOffset.y + this.parentEntity.mesh.geometry.boundingBox.y; parentEntity.position.y = futurePositionRayCasted.y + transformedOffset.y + this.parentEntity.mesh.geometry.boundingBox.y;
parentEntity.position.z = futurePositionRayCasted.z + transformedOffset.z; parentEntity.position.z = futurePositionRayCasted.z + transformedOffset.z;
*/ */
parentEntity.position.x = futurePosition.x + transformedOffset.x; /**
parentEntity.position.y = futurePosition.y + transformedOffset.y; * Update Position
parentEntity.position.z = futurePosition.z + transformedOffset.z; */
this.parentEntity.position.x = this.futurePosition.x;// + transformedOffset.x;
this.parentEntity.position.y = this.futurePosition.y;// + transformedOffset.y;
this.parentEntity.position.z = this.futurePosition.z;// + transformedOffset.z;
// update rotation /**
parentEntity.quaternion.x = quaternion.x; * Update Rotation
parentEntity.quaternion.y = quaternion.y; */
parentEntity.quaternion.z = quaternion.z; this.parentEntity.quaternion.x = this.rotationVector.x;
parentEntity.quaternion.w = quaternion.w; this.parentEntity.quaternion.y = this.rotationVector.y;
this.parentEntity.quaternion.z = this.rotationVector.z;
this.parentEntity.quaternion.w = this.rotationVector.w;
// // original code
//
// this.step += this.grain;
//
// if (this.step > 1) {
// this.step = 0;
// }
//
// var lookAtStep = this.step + this.grain * 2;
//
// if (lookAtStep > 1) {
// lookAtStep = 0;
// }
//
// var position = this.scene.splines[0].instance.getPoint(this.step);
// var futurePosition = this.scene.splines[0].instance.getPoint(lookAtStep);
//
// this.raycaster.set(position, new THREE.Vector3(0, -1, 0));
//
// var intersect = this.raycaster.intersectObject(this.scene.meshes[6].instance);
//
// this.scene.entities[1].position.x = position.x;
// this.scene.entities[1].position.y = position.y;
// this.scene.entities[1].position.z = position.z;
//
// var matrix = new THREE.Matrix4().lookAt(position, futurePosition, intersect[0].face.normal);
//
// var quaternion = new THREE.Quaternion().setFromRotationMatrix(matrix);
//
// this.scene.entities[1].quaternion.x = quaternion.x;
// this.scene.entities[1].quaternion.y = quaternion.y;
// this.scene.entities[1].quaternion.z = quaternion.z;
// this.scene.entities[1].quaternion.w = quaternion.w;
} }
};
//#endif
GameLib.D3.ComponentPathFollowing.prototype.onSetParentEntity = function(
parentScene,
parentEntity
) {
if(!this.splineCurve3) {
console.error("NO PATH GIVEN");
}
}; };

View File

@ -5,7 +5,7 @@
* @param mesh * @param mesh
* @constructor * @constructor
*/ */
GameLib.D3.Entity = function( GameLib.D3.Entity = function Entity(
apiEntity, apiEntity,
parentScene, parentScene,
mesh mesh
@ -41,17 +41,28 @@ GameLib.D3.Entity.prototype.update = function(
}; };
GameLib.D3.Entity.prototype.updateMesh = function() { 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 (this.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; * Normalize to prevent stretching
this.quaternion.z = this.mesh.quaternion.z; */
this.quaternion.w = this.mesh.quaternion.w; this.quaternion.normalize();
this.mesh.position.x = this.position.x;
this.mesh.position.y = this.position.y;
this.mesh.position.z = this.position.z;
this.mesh.scale.x = this.scale.x;
this.mesh.scale.y = this.scale.y;
this.mesh.scale.z = this.scale.z;
this.mesh.quaternion.x = this.quaternion.x;
this.mesh.quaternion.y = this.quaternion.y;
this.mesh.quaternion.z = this.quaternion.z;
this.mesh.quaternion.w = this.quaternion.w;
this.mesh.updateInstance();
} }
}; };

View File

@ -1,27 +1,111 @@
/**
* Runtime Matrix4
* @param graphics
* @param parentObject
* @param matrix4
* @param grain
* @constructor
*/
GameLib.D3.Matrix4 = function( GameLib.D3.Matrix4 = function(
row0, graphics,
row1, parentObject,
row2, matrix4,
row3 grain
) { ) {
this.identity(); for (var property in matrix4) {
if (matrix4.hasOwnProperty(property)) {
if (row0) { this[property] = matrix4[property];
this.rows[0] = row0; }
} }
if (row1) { GameLib.D3.Utils.Extend(GameLib.D3.Matrix4, GameLib.D3.API.Matrix4);
this.rows[1] = row1;
this.graphics = graphics;
this.graphics.isNotThreeThrow();
this.parentObject = parentObject;
if (GameLib.D3.Utils.UndefinedOrNull(grain)) {
grain = 0.001;
}
this.grain = grain;
this.rows[0] = new GameLib.D3.Vector4(
this.graphics,
this,
this.rows[0],
grain
);
this.rows[1] = new GameLib.D3.Vector4(
this.graphics,
this,
this.rows[1],
grain
);
this.rows[2] = new GameLib.D3.Vector4(
this.graphics,
this,
this.rows[2],
grain
);
this.rows[3] = new GameLib.D3.Vector4(
this.graphics,
this,
this.rows[3],
grain
);
this.instance = this.createInstance();
};
/**
* Creates a matrix 4 instance (currently from graphics lib)
* @param update
*/
GameLib.D3.Matrix4.prototype.createInstance = function(update) {
var instance = null;
if (update) {
instance = this.instance;
} }
if (row2) { if (!instance) {
this.rows[2] = row2; instance = new THREE.Matrix4();
} }
if (row3) { instance.set(
this.rows[3] = row3; this.rows[0].x,
} this.rows[0].y,
this.rows[0].z,
this.rows[0].w,
this.rows[1].x,
this.rows[1].y,
this.rows[1].z,
this.rows[1].w,
this.rows[2].x,
this.rows[2].y,
this.rows[2].z,
this.rows[2].w,
this.rows[3].x,
this.rows[3].y,
this.rows[3].z,
this.rows[3].w
);
return instance;
};
/**
* Updates this instance
*/
GameLib.D3.Matrix4.prototype.updateInstance = function() {
this.createInstance(true);
}; };
GameLib.D3.Matrix4.prototype.rotationMatrixX = function (radians) { GameLib.D3.Matrix4.prototype.rotationMatrixX = function (radians) {
@ -101,34 +185,55 @@ GameLib.D3.Matrix4.prototype.identity = function () {
GameLib.D3.Matrix4.prototype.lookAt = function (position, target, up) { GameLib.D3.Matrix4.prototype.lookAt = function (position, target, up) {
var pv = new GameLib.D3.API.Vector3(position.x, position.y, position.z); this.instance.lookAt(position.instance, target.instance, up.instance);
var z = pv.subtract(target).normalize(); this.rows[0].x = this.instance.elements[0];
this.rows[0].y = this.instance.elements[1];
this.rows[0].z = this.instance.elements[2];
this.rows[0].w = this.instance.elements[3];
if (z.squared() === 0) { this.rows[1].x = this.instance.elements[4];
z.z = 1; this.rows[1].y = this.instance.elements[5];
} this.rows[1].z = this.instance.elements[6];
this.rows[1].w = this.instance.elements[7];
var x = up.cross(z).normalize(); this.rows[2].x = this.instance.elements[8];
this.rows[2].y = this.instance.elements[9];
this.rows[2].z = this.instance.elements[10];
this.rows[2].w = this.instance.elements[11];
if (x.squared() === 0) { this.rows[3].x = this.instance.elements[12];
z.x += 0.0001; this.rows[3].y = this.instance.elements[13];
x = up.cross(z).normalize(); this.rows[3].z = this.instance.elements[14];
} this.rows[3].w = this.instance.elements[15];
// var pv = new GameLib.D3.API.Vector3(position.x, position.y, position.z);
var y = z.cross(x); //
// var z = pv.subtract(target).normalize();
this.rows[0].x = x.x; //
this.rows[0].y = x.y; // if (z.squared() === 0) {
this.rows[0].z = x.z; // z.z = 1;
// }
this.rows[1].x = y.x; //
this.rows[1].y = y.y; // var x = up.cross(z).normalize();
this.rows[1].z = y.z; //
// if (x.squared() === 0) {
this.rows[2].x = z.x; // z.x += 0.0001;
this.rows[2].y = z.y; // x = up.cross(z).normalize();
this.rows[2].z = z.z; // }
//
return this; // var y = z.cross(x);
//
// this.rows[0].x = x.x;
// this.rows[0].y = x.y;
// this.rows[0].z = x.z;
//
// this.rows[1].x = y.x;
// this.rows[1].y = y.y;
// this.rows[1].z = y.z;
//
// this.rows[2].x = z.x;
// this.rows[2].y = z.y;
// this.rows[2].z = z.z;
//
// return this;
}; };

View File

@ -309,16 +309,25 @@ GameLib.D3.Mesh.prototype.createInstance = function(update) {
instance.gameLibObject = this; instance.gameLibObject = this;
instance.position.copy(this.position.instance); instance.position.x = this.position.x;
instance.position.y = this.position.y;
instance.position.z = this.position.z;
instance.scale.copy(this.scale.instance); instance.scale.x = this.scale.x;
instance.scale.y = this.scale.y;
instance.scale.z = this.scale.z;
instance.up.copy(this.up.instance); instance.up.x = this.up.x;
instance.up.y = this.up.y;
instance.up.z = this.up.z;
/** /**
* We don't do rotation - its dealt with by quaternion * We don't do rotation - its dealt with by quaternion
*/ */
instance.quaternion.copy(this.quaternion.instance); instance.quaternion.x = this.quaternion.x;
instance.quaternion.y = this.quaternion.y;
instance.quaternion.z = this.quaternion.z;
instance.quaternion.w = this.quaternion.w;
return instance; return instance;
}; };

132
src/game-lib-raycaster.js Normal file
View File

@ -0,0 +1,132 @@
/**
* Raycaster for GameLib.D3
* @param graphics GameLib.D3.Graphics
* @param position GameLib.D3.Vector3
* @param direction GameLib.D3.Vector3
* @constructor
*/
GameLib.D3.Raycaster = function(
graphics,
position,
direction
) {
this.graphics = graphics;
this.graphics.isNotThreeThrow();
if (GameLib.D3.Utils.UndefinedOrNull(position)) {
position = new GameLib.D3.Vector3(
graphics,
this,
new GameLib.D3.API.Vector3()
);
}
this.position = position;
if (GameLib.D3.Utils.UndefinedOrNull(direction)) {
direction = new GameLib.D3.Vector3(
graphics,
this,
new GameLib.D3.API.Vector3(0, -1, 0)
);
}
this.direction = direction;
this.instance = this.createInstance();
};
/**
* Creates or updates a raycaster instance
* @param update
*/
GameLib.D3.Raycaster.prototype.createInstance = function(update) {
var instance = null;
if (update) {
instance = this.instance;
} else {
instance = new THREE.Raycaster();
}
instance.set(
this.position.instance,
this.direction.instance
);
return instance;
};
/**
* Sets the direction and position of this raycaster
* @param position GameLib.D3.Vector3
* @param direction GameLib.D3.Vector3
*/
GameLib.D3.Raycaster.prototype.set = function(
position,
direction
) {
this.position = position;
this.direction = direction;
this.position.updateInstance();
this.direction.updateInstance();
this.createInstance(true);
};
/**
* Sets the direction of this raycaster
* @param direction GameLib.D3.Vector3
*/
GameLib.D3.Raycaster.prototype.setDirection = function(
direction
) {
this.direction = direction;
this.direction.updateInstance();
this.createInstance(true);
};
/**
* Sets the position of this raycaster
* @param position GameLib.D3.Vector3
*/
GameLib.D3.Raycaster.prototype.setPosition = function(
position
) {
this.position = position;
this.position.updateInstance();
this.createInstance(true);
};
/**
* Returns the face normal (if any) of an intersection between current ray position, direction and a provided mesh
* @param mesh GameLib.D3.Mesh
* @returns {null | GameLib.D3.Vector3}
*/
GameLib.D3.Raycaster.prototype.getFaceNormal = function(mesh) {
var normal = null;
var intersect = this.instance.intersectObject(
mesh.instance
);
if (intersect && intersect.length > 0) {
normal = new GameLib.D3.Vector3(
this.graphics,
this,
new GameLib.D3.API.Vector3(
intersect[0].face.normal.x,
intersect[0].face.normal.y,
intersect[0].face.normal.z
)
);
}
return normal;
};

View File

@ -4,7 +4,7 @@
* @param apiSpline GameLib.D3.API.Spline * @param apiSpline GameLib.D3.API.Spline
* @constructor * @constructor
*/ */
GameLib.D3.Spline = function( GameLib.D3.Spline = function Spline(
graphics, graphics,
apiSpline apiSpline
) { ) {
@ -30,7 +30,7 @@ GameLib.D3.Spline.prototype.createInstance = function(update) {
var vertices = []; var vertices = [];
for (var v = 0; v < this.vertices.length; v++) { for (var v = 0; v < this.vertices.length; v++) {
vertices.push(new this.graphics.instance.Vector3( vertices.push(new THREE.Vector3(
this.vertices[v].x, this.vertices[v].x,
this.vertices[v].y, this.vertices[v].y,
this.vertices[v].z this.vertices[v].z
@ -47,4 +47,19 @@ GameLib.D3.Spline.prototype.updateInstance = function() {
this.instance = this.createInstance(true); this.instance = this.createInstance(true);
}; };
/**
* Gets the current point from the spline at the proper value
* @param proper Number (fraction between 0 and 1 indicating position on spline)
* @returns {*}
*/
GameLib.D3.Spline.prototype.getPointAt = function(proper) {
var point = this.instance.getPointAt(proper);
return new GameLib.D3.Vector3(
this.graphics,
this,
new GameLib.D3.API.Vector3(point.x, point.y, point.z),
0.1
);
};

View File

@ -6,7 +6,12 @@
* @param grain Number * @param grain Number
* @constructor * @constructor
*/ */
GameLib.D3.Vector4 = function RuntimeVector4(graphics, parentObject, vector4, grain) { GameLib.D3.Vector4 = function RuntimeVector4(
graphics,
parentObject,
vector4,
grain
) {
for (var property in vector4) { for (var property in vector4) {
if (vector4.hasOwnProperty(property)) { if (vector4.hasOwnProperty(property)) {
@ -46,7 +51,7 @@ GameLib.D3.Vector4.prototype.createInstance = function(update) {
instance.z = this.z; instance.z = this.z;
instance.w = this.w; instance.w = this.w;
} else { } else {
instance = new this.graphics.instance.Vector4(this.x, this.y, this.z, this.w); instance = new THREE.Quaternion(this.x, this.y, this.z, this.w);
} }
return instance; return instance;
@ -116,20 +121,31 @@ GameLib.D3.Vector4.prototype.multiply = function (s) {
GameLib.D3.Vector4.prototype.normalize = function () { GameLib.D3.Vector4.prototype.normalize = function () {
// note - leave w untouched this.updateInstance();
var EPSILON = 0.000001;
var v2 = this.x * this.x + this.y * this.y + this.z * this.z; this.instance.normalize();
if (v2 < EPSILON) { this.x = this.instance.x;
return this; //do nothing for zero vector this.y = this.instance.y;
} this.z = this.instance.z;
this.w = this.instance.w;
var invLength = 1 / Math.sqrt(v2); //
//
this.x *= invLength; //
this.y *= invLength; // // note - leave w untouched
this.z *= invLength; // var EPSILON = 0.000001;
//
// var v2 = this.x * this.x + this.y * this.y + this.z * this.z;
//
// if (v2 < EPSILON) {
// return this; //do nothing for zero vector
// }
//
// var invLength = 1 / Math.sqrt(v2);
//
// this.x *= invLength;
// this.y *= invLength;
// this.z *= invLength;
return this; return this;
}; };
@ -376,3 +392,17 @@ GameLib.D3.Vector4.Points.prototype.toOrigin = function () {
this.vectors[i].translate(distanceFromOrigin); this.vectors[i].translate(distanceFromOrigin);
} }
}; };
/**
*
* @param matrix4 GameLib.D3.Matrix4
*/
GameLib.D3.Vector4.prototype.setFromRotationMatrix = function(matrix4) {
this.instance.setFromRotationMatrix(matrix4.instance);
this.x = this.instance.x;
this.y = this.instance.y;
this.z = this.instance.z;
this.w = this.instance.w;
};