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
* @param id String
* @param name String
* @param vertices GameLib.D3.API.Vector3[]
* @constructor
*/
GameLib.D3.API.Spline = function(

View File

@ -1,6 +1,15 @@
GameLib.D3.API.Vector2 = function Vector2(x, y) {
this.x = x || 0;
this.y = y || 0;
GameLib.D3.API.Vector2 = function ApiVector2(x, y) {
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 () {

View File

@ -1,5 +1,18 @@
GameLib.D3.API.Vector3 = function Vector3(x, y, z) {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
GameLib.D3.API.Vector3 = function ApiVector3(x, y, z) {
if (GameLib.D3.Utils.UndefinedOrNull(x)) {
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) {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
this.w = w || 1;
GameLib.D3.API.Vector4 = function ApiVector4(x, y, z, w) {
if (GameLib.D3.Utils.UndefinedOrNull(x)) {
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;
if (GameLib.D3.Utils.UndefinedOrNull(w)) {
w = 1;
}
this.w = w;
};

View File

@ -1,88 +1,212 @@
/**
*
* @param id
* @param name
* This component makes the parentEntity (ex. car) follow the path provided by the spline
* @param id String
* @param name String
* @param graphics GameLib.D3.Graphics
* @param parentEntity GameLib.D3.Entity
* @param spline GameLib.D3.Spline
* @param meshes[] GameLib.D3.Mesh
* @param accel
* @param maxSpeed
* @param baseOffset
* @param maxOffset
* @param steeringSpeed
* @param mesh GameLib.D3.Mesh
* @param accelleration Number
* @param maxSpeed Number
* @param baseOffset GameLib.D3.Vector
* @param maxOffset GameLib.D3.Vector
* @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
*/
GameLib.D3.ComponentPathFollowing = function ComponentPathFollowing(
id,
name,
graphics,
parentEntity,
spline,
meshes,
accel,
mesh,
accelleration,
maxSpeed,
baseOffset,
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;
}
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.trackThreeMeshArray = mesh;
this.maxSpeed = maxSpeed || 10.0;
this.accel = accel || 2.0;
if (GameLib.D3.Utils.UndefinedOrNull(mesh)) {
mesh = null;
}
this.mesh = mesh;
this.baseOffset = baseOffset || new GameLib.D3.API.Vector3();
this.maxOffset = maxOffset || new GameLib.D3.API.Vector3(10, 10, 10);
this.steeringSpeed = steeringSpeed || 1.0;
if (GameLib.D3.Utils.UndefinedOrNull(maxSpeed)) {
maxSpeed = 0.03;
}
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__
this.offset = new GameLib.D3.API.Vector3(); // this one is our destination offset
this.currentOffset = new GameLib.D3.API.Vector3();
this.currentPathValue = 0.0;
this.currentSpeed = 0.0;
this.direction = 0;
this.pastNormal = new THREE.Vector3(0,0,0);
//#endif
if (GameLib.D3.Utils.UndefinedOrNull(maxOffset)) {
maxOffset = new GameLib.D3.Vector3(graphics, this, new GameLib.D3.API.Vector3(10, 10, 10), 0.1);
}
this.maxOffset = maxOffset;
if (GameLib.D3.Utils.UndefinedOrNull(steeringSpeed)) {
steeringSpeed = 1.0;
}
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);
};
//#ifdef RUNTIME__
ComponentPathFollowing_Three_Raycaster = new THREE.Raycaster();
///////////////////////// Methods to override //////////////////////////
GameLib.D3.ComponentPathFollowing.prototype.onUpdate = function(
deltaTime,
parentEntity
deltaTime
) {
if(this.spline && this.trackThreeMeshArray) {
if (this.spline && this.mesh) {
// current speed
this.maxSpeed = 0.03;
this.accel = 0.1;
this.currentSpeed += this.accel * deltaTime * this.direction;
this.currentSpeed += this.accelleration * deltaTime * this.direction;
if(this.currentSpeed > this.maxSpeed) {
this.currentSpeed = this.maxSpeed;
}
this.grain = (this.currentSpeed / 100.0);
//this.grain = (deltaTime / 100.0);
var currentPosition = this.splineCurve3.getPointAt(this.currentPathValue);
this.currentPosition = this.spline.getPointAt(this.currentPathValue);
this.currentPathValue += this.grain;
@ -94,126 +218,148 @@ GameLib.D3.ComponentPathFollowing.prototype.onUpdate = function(
this.currentPathValue = 0.0;
}
var futurePosition = this.splineCurve3.getPointAt(this.currentPathValue);
this.futurePosition = this.spline.getPointAt(this.currentPathValue);
// - - - - - - - - - - - - -
// Ray trace from the future position.
// - - - - - - - - -- - - - -
ComponentPathFollowing_Three_Raycaster.set(
futurePosition,
new THREE.Vector3(
0,
-1,
0
)
this.raycaster.setPosition(
this.futurePosition
);
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]
);
// var futureNormal = new THREE.Vector3(0, 1, 0);
// var futurePositionRayCasted = new THREE.Vector3(
// futurePosition.x,
// futurePosition.y,
// futurePosition.z
// );
if(intersect && intersect.length > 0) {
futureNormal = intersect[0].face.normal;
futurePositionRayCasted = intersect[0].point;
break;
}
}
var normal = this.raycaster.getFaceNormal(this.mesh);
this.up.x = this.mx(normal.x);
this.up.y = this.my(normal.y);
this.up.z = this.mz(normal.z);
this.up.updateInstance();
// - - - - - - - - - - - - -
// Ray trace from the current position.
// - - - - - - - - -- - - - -
//
// ComponentPathFollowing_Three_Raycaster.set(
// currentPosition,
// new THREE.Vector3(
// 0,
// -1,
// 0
// )
// );
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 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.meshes[m].instance
// );
//
// 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 avgNormal = (this.pastNormal).add(futureNormal).normalize();
// this.pastNormal = futureNormal;
var matrix = new THREE.Matrix4().lookAt(
currentPosition,
futurePosition,
avgNormal
this.rotationMatrix.lookAt(
this.currentPosition,
this.futurePosition,
this.up
);
var quaternion = new THREE.Quaternion().setFromRotationMatrix(matrix);
this.rotationVector.setFromRotationMatrix(this.rotationMatrix);
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,
(this.grain * this.steeringSpeed)
);
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 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,
// (this.grain * this.steeringSpeed)
// );
//
// 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);
// apply to parent rigidbody instead of direclty to the mesh.
/* 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 = 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 Position
*/
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;
parentEntity.quaternion.y = quaternion.y;
parentEntity.quaternion.z = quaternion.z;
parentEntity.quaternion.w = quaternion.w;
/**
* Update Rotation
*/
this.parentEntity.quaternion.x = this.rotationVector.x;
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
* @constructor
*/
GameLib.D3.Entity = function(
GameLib.D3.Entity = function Entity(
apiEntity,
parentScene,
mesh
@ -41,17 +41,28 @@ GameLib.D3.Entity.prototype.update = 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 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;
if (this.mesh) {
/**
* Normalize to prevent stretching
*/
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(
row0,
row1,
row2,
row3
graphics,
parentObject,
matrix4,
grain
) {
this.identity();
if (row0) {
this.rows[0] = row0;
for (var property in matrix4) {
if (matrix4.hasOwnProperty(property)) {
this[property] = matrix4[property];
}
}
if (row1) {
this.rows[1] = row1;
GameLib.D3.Utils.Extend(GameLib.D3.Matrix4, GameLib.D3.API.Matrix4);
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) {
this.rows[2] = row2;
if (!instance) {
instance = new THREE.Matrix4();
}
if (row3) {
this.rows[3] = row3;
}
instance.set(
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) {
@ -101,34 +185,55 @@ GameLib.D3.Matrix4.prototype.identity = function () {
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) {
z.z = 1;
}
this.rows[1].x = this.instance.elements[4];
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) {
z.x += 0.0001;
x = up.cross(z).normalize();
}
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;
this.rows[3].x = this.instance.elements[12];
this.rows[3].y = this.instance.elements[13];
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 z = pv.subtract(target).normalize();
//
// if (z.squared() === 0) {
// z.z = 1;
// }
//
// var x = up.cross(z).normalize();
//
// if (x.squared() === 0) {
// z.x += 0.0001;
// x = up.cross(z).normalize();
// }
//
// 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.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
*/
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;
};

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
* @constructor
*/
GameLib.D3.Spline = function(
GameLib.D3.Spline = function Spline(
graphics,
apiSpline
) {
@ -30,7 +30,7 @@ GameLib.D3.Spline.prototype.createInstance = function(update) {
var vertices = [];
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].y,
this.vertices[v].z
@ -47,4 +47,19 @@ GameLib.D3.Spline.prototype.updateInstance = function() {
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
* @constructor
*/
GameLib.D3.Vector4 = function RuntimeVector4(graphics, parentObject, vector4, grain) {
GameLib.D3.Vector4 = function RuntimeVector4(
graphics,
parentObject,
vector4,
grain
) {
for (var property in vector4) {
if (vector4.hasOwnProperty(property)) {
@ -46,7 +51,7 @@ GameLib.D3.Vector4.prototype.createInstance = function(update) {
instance.z = this.z;
instance.w = this.w;
} 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;
@ -116,20 +121,31 @@ GameLib.D3.Vector4.prototype.multiply = function (s) {
GameLib.D3.Vector4.prototype.normalize = function () {
// note - leave w untouched
var EPSILON = 0.000001;
this.updateInstance();
var v2 = this.x * this.x + this.y * this.y + this.z * this.z;
this.instance.normalize();
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;
this.x = this.instance.x;
this.y = this.instance.y;
this.z = this.instance.z;
this.w = this.instance.w;
//
//
//
// // note - leave w untouched
// 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;
};
@ -376,3 +392,17 @@ GameLib.D3.Vector4.Points.prototype.toOrigin = function () {
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;
};