follow, lookat, camera and path following done gulp! :)
parent
f774cad759
commit
accc868f71
|
@ -15,6 +15,7 @@
|
|||
* @param maxY
|
||||
* @param minZ
|
||||
* @param maxZ
|
||||
* @param quaternion GameLib.D3.Vector4
|
||||
* @constructor
|
||||
*/
|
||||
GameLib.D3.API.Camera = function(
|
||||
|
@ -32,7 +33,8 @@ GameLib.D3.API.Camera = function(
|
|||
minY,
|
||||
maxY,
|
||||
minZ,
|
||||
maxZ
|
||||
maxZ,
|
||||
quaternion
|
||||
) {
|
||||
if (GameLib.D3.Utils.UndefinedOrNull(id)) {
|
||||
id = GameLib.D3.Utils.RandomId();
|
||||
|
@ -60,7 +62,7 @@ GameLib.D3.API.Camera = function(
|
|||
this.aspect = aspect;
|
||||
|
||||
if (GameLib.D3.Utils.UndefinedOrNull(near)) {
|
||||
near = 0.1;
|
||||
near = 0.001;
|
||||
}
|
||||
this.near = near;
|
||||
|
||||
|
@ -78,6 +80,11 @@ GameLib.D3.API.Camera = function(
|
|||
}
|
||||
this.position = position;
|
||||
|
||||
if (GameLib.D3.Utils.UndefinedOrNull(quaternion)) {
|
||||
quaternion = new GameLib.D3.API.Vector4();
|
||||
}
|
||||
this.quaternion = quaternion;
|
||||
|
||||
if (GameLib.D3.Utils.UndefinedOrNull(lookAt)) {
|
||||
lookAt = new GameLib.D3.API.Vector3(
|
||||
0,
|
||||
|
|
|
@ -33,4 +33,114 @@ GameLib.D3.API.Matrix4 = function ApiMatrix4(
|
|||
row3 = new GameLib.D3.API.Vector4(0, 0, 0, 1);
|
||||
}
|
||||
this.rows[3] = row3;
|
||||
};
|
||||
};
|
||||
|
||||
GameLib.D3.API.Matrix4.prototype.rotationMatrixX = function (radians) {
|
||||
this.identity();
|
||||
this.rows[1] = new GameLib.D3.API.Vector4(0, Math.cos(radians), -1 * Math.sin(radians), 0);
|
||||
this.rows[2] = new GameLib.D3.API.Vector4(0, Math.sin(radians), Math.cos(radians), 0);
|
||||
return this;
|
||||
};
|
||||
|
||||
GameLib.D3.API.Matrix4.prototype.rotationMatrixY = function (radians) {
|
||||
this.identity();
|
||||
this.rows[0] = new GameLib.D3.API.Vector4(
|
||||
Math.cos(radians),
|
||||
0,
|
||||
Math.sin(radians),
|
||||
0
|
||||
);
|
||||
this.rows[2] = new GameLib.D3.API.Vector4(
|
||||
-1 * Math.sin(radians),
|
||||
0,
|
||||
Math.cos(radians),
|
||||
0
|
||||
);
|
||||
return this;
|
||||
};
|
||||
|
||||
GameLib.D3.API.Matrix4.prototype.rotationMatrixZ = function (radians) {
|
||||
this.identity();
|
||||
this.rows[0] = new GameLib.D3.API.Vector4(Math.cos(radians), -1 * Math.sin(radians), 0, 0);
|
||||
this.rows[1] = new GameLib.D3.API.Vector4(Math.sin(radians), Math.cos(radians), 0, 0);
|
||||
return this;
|
||||
};
|
||||
|
||||
GameLib.D3.API.Matrix4.prototype.rotateX = function (radians, point) {
|
||||
this.identity();
|
||||
this.rotationMatrixX(radians);
|
||||
return this.multiply(point);
|
||||
};
|
||||
|
||||
GameLib.D3.API.Matrix4.prototype.rotateY = function (radians, point) {
|
||||
this.identity();
|
||||
this.rotationMatrixY(radians);
|
||||
return this.multiply(point);
|
||||
};
|
||||
|
||||
GameLib.D3.API.Matrix4.prototype.rotateZ = function (radians, point) {
|
||||
this.identity();
|
||||
this.rotationMatrixZ(radians);
|
||||
return this.multiply(point);
|
||||
};
|
||||
|
||||
GameLib.D3.API.Matrix4.prototype.multiply = function (mvp) {
|
||||
if (mvp instanceof GameLib.D3.API.Vector4) {
|
||||
return new GameLib.D3.API.Vector4(
|
||||
this.rows[0].x * mvp.x + this.rows[0].y * mvp.y + this.rows[0].z * mvp.z + this.rows[0].w * mvp.w,
|
||||
this.rows[1].x * mvp.x + this.rows[1].y * mvp.y + this.rows[1].z * mvp.z + this.rows[1].w * mvp.w,
|
||||
this.rows[2].x * mvp.x + this.rows[2].y * mvp.y + this.rows[2].z * mvp.z + this.rows[2].w * mvp.w,
|
||||
this.rows[3].x * mvp.x + this.rows[3].y * mvp.y + this.rows[3].z * mvp.z + this.rows[3].w * mvp.w
|
||||
);
|
||||
} else if (mvp instanceof GameLib.D3.API.Vector3) {
|
||||
return new GameLib.D3.API.Vector3(
|
||||
this.rows[0].x * mvp.x + this.rows[0].y * mvp.y + this.rows[0].z * mvp.z,
|
||||
this.rows[1].x * mvp.x + this.rows[1].y * mvp.y + this.rows[1].z * mvp.z,
|
||||
this.rows[2].x * mvp.x + this.rows[2].y * mvp.y + this.rows[2].z * mvp.z
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
GameLib.D3.API.Matrix4.prototype.identity = function () {
|
||||
this.rows = [
|
||||
new GameLib.D3.API.Vector4(1, 0, 0, 0),
|
||||
new GameLib.D3.API.Vector4(0, 1, 0, 0),
|
||||
new GameLib.D3.API.Vector4(0, 0, 1, 0),
|
||||
new GameLib.D3.API.Vector4(0, 0, 0, 1)
|
||||
];
|
||||
};
|
||||
|
||||
GameLib.D3.API.Matrix4.prototype.lookAt = function (position, target, up) {
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
|
|
@ -15,4 +15,236 @@ GameLib.D3.API.Vector3 = function ApiVector3(x, y, z) {
|
|||
}
|
||||
this.z = z;
|
||||
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector3.prototype.negate = function() {
|
||||
this.x = -this.x;
|
||||
this.y = -this.y;
|
||||
this.z = -this.z;
|
||||
return this;
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector3.prototype.subtract = function (v) {
|
||||
return new GameLib.D3.API.Vector3(
|
||||
this.x - v.x,
|
||||
this.y - v.y,
|
||||
this.z - v.z
|
||||
);
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector3.prototype.sub = function (v) {
|
||||
return new GameLib.D3.API.Vector3(
|
||||
this.x - v.x,
|
||||
this.y - v.y,
|
||||
this.z - v.z
|
||||
);
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector3.prototype.cross = function (v) {
|
||||
return new GameLib.D3.API.Vector3(
|
||||
this.y * v.z - this.z * v.y,
|
||||
this.z * v.x - this.x * v.z,
|
||||
this.x * v.y - this.y * v.x
|
||||
);
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector3.clockwise = function (u, v, w, viewPoint) {
|
||||
var normal = GameLib.D3.API.Vector3.normal(u, v, w);
|
||||
var uv = u.copy();
|
||||
var winding = normal.dot(uv.subtract(viewPoint));
|
||||
return (winding > 0);
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector3.normal = function (u, v, w) {
|
||||
var vv = v.copy();
|
||||
var wv = w.copy();
|
||||
return vv.subtract(u).cross(wv.subtract(u));
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector3.prototype.lookAt = function (at, up) {
|
||||
var lookAtMatrix = GameLib.D3.API.Matrix4.lookAt(this, at, up);
|
||||
return this.multiply(lookAtMatrix);
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector3.prototype.translate = function (v) {
|
||||
this.x += v.x;
|
||||
this.y += v.y;
|
||||
this.z += v.z;
|
||||
return this;
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector3.prototype.add = function (v) {
|
||||
return new GameLib.D3.API.Vector3(
|
||||
this.x + v.x,
|
||||
this.y + v.y,
|
||||
this.z + v.z
|
||||
);
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector3.prototype.squared = function () {
|
||||
return this.x * this.x + this.y * this.y + this.z * this.z;
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector3.prototype.copy = function () {
|
||||
return new GameLib.D3.API.Vector3(
|
||||
this.x,
|
||||
this.y,
|
||||
this.z
|
||||
);
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector3.prototype.set = function (x, y, z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector3.prototype.lerp = function ( v, alpha ) {
|
||||
return new GameLib.D3.API.Vector3(
|
||||
this.x + ( v.x - this.x ) * alpha,
|
||||
this.y + ( v.y - this.y ) * alpha,
|
||||
this.z + ( v.z - this.z ) * alpha
|
||||
);
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector3.prototype.distanceTo = function(v) {
|
||||
var dx = this.x - v.x,
|
||||
dy = this.y - v.y,
|
||||
dz = this.z - v.z;
|
||||
return Math.sqrt(dx * dx + dy * dy + dz * dz);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
GameLib.D3.API.Vector3.AngleDirection = function(forward, directionToCheck, up) {
|
||||
var perp = forward.cross(directionToCheck);
|
||||
var dir = perp.dot(up);
|
||||
|
||||
if (dir > 0.0) {
|
||||
return 1.0;
|
||||
} else if (dir < 0.0) {
|
||||
return -1.0;
|
||||
} else {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector3.prototype.multiply = function (s) {
|
||||
|
||||
var x, y, z;
|
||||
|
||||
if (s instanceof GameLib.D3.API.Vector3) {
|
||||
|
||||
return new GameLib.D3.API.Vector3(
|
||||
this.x * s.x,
|
||||
this.y * s.y,
|
||||
this.z * s.z
|
||||
)
|
||||
|
||||
} else if (s instanceof GameLib.D3.API.Matrix4) {
|
||||
|
||||
x = s.rows[0].x * this.x + s.rows[0].y * this.y + s.rows[0].z * this.z + s.rows[0].w;
|
||||
y = s.rows[1].x * this.x + s.rows[1].y * this.y + s.rows[1].z * this.z + s.rows[1].w;
|
||||
z = s.rows[2].x * this.x + s.rows[2].y * this.y + s.rows[2].z * this.z + s.rows[2].w;
|
||||
|
||||
return new GameLib.D3.API.Vector3(
|
||||
x,
|
||||
y,
|
||||
z
|
||||
);
|
||||
|
||||
} else if (s instanceof GameLib.D3.API.Matrix3) {
|
||||
|
||||
x = s.rows[0].x * this.x + s.rows[0].y * this.y + s.rows[0].z * this.z;
|
||||
y = s.rows[1].x * this.x + s.rows[1].y * this.y + s.rows[1].z * this.z;
|
||||
z = s.rows[2].x * this.x + s.rows[2].y * this.y + s.rows[2].z * this.z;
|
||||
|
||||
return new GameLib.D3.API.Vector3(
|
||||
x,
|
||||
y,
|
||||
z
|
||||
);
|
||||
|
||||
} else if(!isNaN(parseFloat(s)) && isFinite(s)) {
|
||||
|
||||
return new GameLib.D3.API.Vector3(
|
||||
this.x * s,
|
||||
this.y * s,
|
||||
this.z * s
|
||||
);
|
||||
|
||||
} else {
|
||||
console.log("functionality not implemented - please do this");
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
GameLib.D3.API.Vector3.prototype.dot = function (v) {
|
||||
return (this.x * v.x) + (this.y * v.y) + (this.z * v.z);
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector3.prototype.normalize = function () {
|
||||
var EPSILON = 0.000001;
|
||||
var v2 = this.squared();
|
||||
|
||||
if (v2 < EPSILON) {
|
||||
return this; //do nothing for zero vector
|
||||
}
|
||||
|
||||
var invLength = 1.0 / Math.sqrt(v2);
|
||||
return new GameLib.D3.API.Vector3(
|
||||
this.x * invLength,
|
||||
this.y * invLength,
|
||||
this.z * invLength
|
||||
);
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector3.prototype.clone = function () {
|
||||
return new GameLib.D3.API.Vector3(
|
||||
this.x,
|
||||
this.y,
|
||||
this.z
|
||||
);
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector3.prototype.applyQuaternion = function(q) {
|
||||
var x = this.x, y = this.y, z = this.z;
|
||||
var qx = q.x, qy = q.y, qz = q.z, qw = q.w;
|
||||
|
||||
// calculate quat * vector
|
||||
|
||||
var ix = qw * x + qy * z - qz * y;
|
||||
var iy = qw * y + qz * x - qx * z;
|
||||
var iz = qw * z + qx * y - qy * x;
|
||||
var iw = - qx * x - qy * y - qz * z;
|
||||
|
||||
// calculate result * inverse quat
|
||||
|
||||
this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;
|
||||
this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;
|
||||
this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector3.prototype.clamp = function(min, max) {
|
||||
this.x = Math.max( min.x, Math.min( max.x, this.x ) );
|
||||
this.y = Math.max( min.y, Math.min( max.y, this.y ) );
|
||||
this.z = Math.max( min.z, Math.min( max.z, this.z ) );
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector3.prototype.length = function() {
|
||||
return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector3.prototype.reflect = function(normal) {
|
||||
return this.sub( v1.copy( normal ).multiply( 2 * this.dot( normal ) ) );
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector3.prototype.angleTo = function (v) {
|
||||
var theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) );
|
||||
return Math.acos( exports.Math.clamp( theta, - 1, 1 ) );
|
||||
};
|
|
@ -0,0 +1,97 @@
|
|||
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;
|
||||
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector4.prototype.translate = function (v) {
|
||||
this.x += v.x;
|
||||
this.y += v.y;
|
||||
this.z += v.z;
|
||||
return this;
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector4.prototype.copy = function () {
|
||||
return new GameLib.D3.API.Vector4(
|
||||
this.x,
|
||||
this.y,
|
||||
this.z,
|
||||
this.w
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Note, this normalize function leaves 'w' component untouched
|
||||
*/
|
||||
GameLib.D3.API.Vector4.prototype.normalize = function () {
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector4.prototype.multiply = function (s) {
|
||||
if (s instanceof GameLib.D3.API.Vector3) {
|
||||
this.x *= s.x;
|
||||
this.y *= s.y;
|
||||
this.z *= s.z;
|
||||
} else if (s instanceof GameLib.D3.API.Matrix4) {
|
||||
var x = s.rows[0].x * this.x + s.rows[0].y * this.y + s.rows[0].z * this.z + s.rows[0].w * this.w;
|
||||
var y = s.rows[1].x * this.x + s.rows[1].y * this.y + s.rows[1].z * this.z + s.rows[1].w * this.w;
|
||||
var z = s.rows[2].x * this.x + s.rows[2].y * this.y + s.rows[2].z * this.z + s.rows[2].w * this.w;
|
||||
var w = s.rows[3].x * this.x + s.rows[3].y * this.y + s.rows[3].z * this.z + s.rows[3].w * this.w;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.w = w;
|
||||
} else {
|
||||
console.log("functionality not implemented - please do this");
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector4.prototype.subtract = function (v) {
|
||||
|
||||
if (v instanceof GameLib.D3.API.Vector3) {
|
||||
this.x -= v.x;
|
||||
this.y -= v.y;
|
||||
this.z -= v.z;
|
||||
}
|
||||
|
||||
if (v instanceof GameLib.D3.API.Vector4) {
|
||||
this.x -= v.x;
|
||||
this.y -= v.y;
|
||||
this.z -= v.z;
|
||||
this.w -= v.w;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
|
@ -0,0 +1,224 @@
|
|||
GameLib.D3.API.Vector4.Points = function () {
|
||||
this.vectors = [];
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector4.Points.prototype.add = function (vector) {
|
||||
|
||||
if (vector instanceof GameLib.D3.API.Vector3) {
|
||||
vector = new GameLib.D3.API.Vector4(
|
||||
vector.x,
|
||||
vector.y,
|
||||
vector.z,
|
||||
1
|
||||
)
|
||||
}
|
||||
|
||||
if (!vector instanceof GameLib.D3.API.Vector4) {
|
||||
console.warn("Vector needs to be of type Vector4");
|
||||
throw new Error("Vector needs to be of type Vector4");
|
||||
}
|
||||
|
||||
this.vectors.push(vector);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector4.Points.prototype.copy = function () {
|
||||
|
||||
var vectors = [];
|
||||
|
||||
for (var i = 0; i < this.vectors.length; i++) {
|
||||
vectors.push(this.vectors[i].copy());
|
||||
}
|
||||
|
||||
return vectors;
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector4.Points.prototype.maximizeXDistance = function (grain) {
|
||||
|
||||
// console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2));
|
||||
|
||||
var multiplier = 0;
|
||||
|
||||
var rotationMatrixY = new GameLib.D3.API.Matrix4().rotationMatrixY(grain);
|
||||
|
||||
var totalRadians = 0;
|
||||
|
||||
var backupVectors = this.copy();
|
||||
|
||||
var maxXDistance = 0;
|
||||
|
||||
for (var i = 0; i < Math.PI * 2; i += grain) {
|
||||
|
||||
multiplier++;
|
||||
|
||||
for (var j = 0; j < this.vectors.length; j++) {
|
||||
this.vectors[j] = rotationMatrixY.multiply(this.vectors[j]);
|
||||
}
|
||||
|
||||
var distances = this.distances();
|
||||
|
||||
if (distances.x > maxXDistance) {
|
||||
|
||||
maxXDistance = distances.x;
|
||||
totalRadians = multiplier * grain;
|
||||
}
|
||||
}
|
||||
|
||||
this.vectors = backupVectors;
|
||||
|
||||
// console.log("distance: " + maxXDistance + " radians : " + totalRadians);
|
||||
|
||||
var maxRotationMatrix = new GameLib.D3.API.Matrix4().rotationMatrixY(totalRadians);
|
||||
|
||||
for (var k = 0; k < this.vectors.length; k++) {
|
||||
this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]);
|
||||
}
|
||||
|
||||
// console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2));
|
||||
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector4.Points.prototype.maximizeYDistance = function (grain) {
|
||||
|
||||
// console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2));
|
||||
|
||||
var multiplier = 0;
|
||||
|
||||
var rotationMatrixX = new GameLib.D3.API.Matrix4().rotationMatrixX(grain);
|
||||
|
||||
var totalRadians = 0;
|
||||
|
||||
var backupVectors = this.copy();
|
||||
|
||||
var maxYDistance = 0;
|
||||
|
||||
for (var i = 0; i < Math.PI * 2; i += grain) {
|
||||
|
||||
multiplier++;
|
||||
|
||||
for (var j = 0; j < this.vectors.length; j++) {
|
||||
this.vectors[j] = rotationMatrixX.multiply(this.vectors[j]);
|
||||
}
|
||||
|
||||
var distances = this.distances();
|
||||
|
||||
if (distances.y > maxYDistance) {
|
||||
maxYDistance = distances.y;
|
||||
totalRadians = multiplier * grain;
|
||||
}
|
||||
}
|
||||
|
||||
this.vectors = backupVectors;
|
||||
|
||||
// console.log("distance: " + maxYDistance + " radians : " + totalRadians);
|
||||
|
||||
var maxRotationMatrix = new GameLib.D3.API.Matrix4().rotationMatrixX(totalRadians);
|
||||
|
||||
for (var k = 0; k < this.vectors.length; k++) {
|
||||
this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]);
|
||||
}
|
||||
|
||||
// console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2));
|
||||
|
||||
};
|
||||
|
||||
|
||||
GameLib.D3.API.Vector4.Points.prototype.lookAt = function (at, up) {
|
||||
|
||||
var polyCenter = this.average();
|
||||
|
||||
console.log("poly center : " + JSON.stringify(polyCenter));
|
||||
|
||||
var lookAtMatrix = new GameLib.D3.API.Matrix4().lookAt(polyCenter, at, up);
|
||||
|
||||
lookAtMatrix.rows[0] = new GameLib.D3.API.Vector4(1, 0, 0, 0);
|
||||
lookAtMatrix.rows[1] = new GameLib.D3.API.Vector4(0, 0, 1, 0);
|
||||
lookAtMatrix.rows[2] = new GameLib.D3.API.Vector4(0, 1, 0, 0);
|
||||
|
||||
console.log("look at matrix : " + JSON.stringify(lookAtMatrix, null, 2));
|
||||
|
||||
for (var i = 0; i < this.vectors.length; i++) {
|
||||
console.log("vector " + i + " (before): " + JSON.stringify(this.vectors[i]));
|
||||
this.vectors[i] = lookAtMatrix.multiply(this.vectors[i]);
|
||||
console.log("vector " + i + " (after) : " + JSON.stringify(this.vectors[i]));
|
||||
}
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector4.Points.prototype.distances = function () {
|
||||
|
||||
var minX = this.vectors[0].x;
|
||||
var minY = this.vectors[0].y;
|
||||
var minZ = this.vectors[0].z;
|
||||
|
||||
var maxX = this.vectors[0].x;
|
||||
var maxY = this.vectors[0].y;
|
||||
var maxZ = this.vectors[0].z;
|
||||
|
||||
for (var i = 0; i < this.vectors.length; i++) {
|
||||
if (this.vectors[i].x < minX) {
|
||||
minX = this.vectors[i].x;
|
||||
}
|
||||
if (this.vectors[i].y < minY) {
|
||||
minY = this.vectors[i].y;
|
||||
}
|
||||
if (this.vectors[i].z < minZ) {
|
||||
minZ = this.vectors[i].z;
|
||||
}
|
||||
|
||||
if (this.vectors[i].x > maxX) {
|
||||
maxX = this.vectors[i].x;
|
||||
}
|
||||
if (this.vectors[i].y > maxY) {
|
||||
maxY = this.vectors[i].y;
|
||||
}
|
||||
if (this.vectors[i].z > maxZ) {
|
||||
maxZ = this.vectors[i].z;
|
||||
}
|
||||
}
|
||||
|
||||
return new GameLib.D3.API.Vector3(
|
||||
Math.abs(maxX - minX),
|
||||
Math.abs(maxY - minY),
|
||||
Math.abs(maxY - minZ)
|
||||
)
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector4.Points.prototype.average = function () {
|
||||
var averageX = 0;
|
||||
var averageY = 0;
|
||||
var averageZ = 0;
|
||||
|
||||
for (var i = 0; i < this.vectors.length; i++) {
|
||||
averageX += this.vectors[i].x;
|
||||
averageY += this.vectors[i].y;
|
||||
averageZ += this.vectors[i].z;
|
||||
}
|
||||
|
||||
return new GameLib.D3.API.Vector3(
|
||||
averageX / this.vectors.length,
|
||||
averageY / this.vectors.length,
|
||||
averageZ / this.vectors.length
|
||||
);
|
||||
};
|
||||
|
||||
GameLib.D3.API.Vector4.Points.prototype.negate = function () {
|
||||
|
||||
for (var i = 0; i < this.vectors.length; i++) {
|
||||
this.vectors[i].x *= -1;
|
||||
this.vectors[i].y *= -1;
|
||||
this.vectors[i].z *= -1;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
GameLib.D3.API.Vector4.Points.prototype.toOrigin = function () {
|
||||
|
||||
var distanceFromOrigin = this.average().negate();
|
||||
|
||||
for (var i = 0; i < this.vectors.length; i++) {
|
||||
this.vectors[i].translate(distanceFromOrigin);
|
||||
}
|
||||
};
|
|
@ -1,23 +0,0 @@
|
|||
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;
|
||||
|
||||
};
|
|
@ -24,6 +24,12 @@ GameLib.D3.Camera = function Camera(
|
|||
this.position
|
||||
);
|
||||
|
||||
this.quaternion = new GameLib.D3.Vector4(
|
||||
graphics,
|
||||
this,
|
||||
this.quaternion
|
||||
);
|
||||
|
||||
this.lookAt = new GameLib.D3.Vector3(
|
||||
graphics,
|
||||
this,
|
||||
|
@ -88,9 +94,16 @@ GameLib.D3.Camera.prototype.createInstance = function(update) {
|
|||
instance.far = this.far;
|
||||
}
|
||||
|
||||
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.lookAt(this.lookAt.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;
|
||||
|
||||
// instance.lookAt(this.lookAt.instance);
|
||||
|
||||
instance.updateProjectionMatrix();
|
||||
|
||||
|
|
|
@ -4,31 +4,36 @@
|
|||
* @param id
|
||||
* @param name String
|
||||
* @param camera GameLib.D3.Camera
|
||||
* @param parentEntity GameLib.D3.Entity
|
||||
* @constructor
|
||||
*/
|
||||
GameLib.D3.ComponentCamera = function ComponentCamera(
|
||||
id,
|
||||
name,
|
||||
camera
|
||||
camera,
|
||||
parentEntity
|
||||
) {
|
||||
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;
|
||||
|
||||
// Todo: this should be executed somewhere in game-lib-z, so that we don't execute it on every construction of an object.
|
||||
GameLib.D3.Utils.Extend(GameLib.D3.ComponentCamera, GameLib.D3.ComponentInterface);
|
||||
|
||||
if (typeof camera == 'undefined') {
|
||||
if (GameLib.D3.Utils.UndefinedOrNull(camera)) {
|
||||
camera = null;
|
||||
}
|
||||
this.camera = camera;
|
||||
|
||||
// Component fields
|
||||
this.camera = camera.instance;
|
||||
GameLib.D3.Utils.Extend(GameLib.D3.ComponentCamera, GameLib.D3.ComponentInterface);
|
||||
};
|
||||
|
||||
///////////////////////// Methods to override //////////////////////////
|
||||
|
@ -36,11 +41,25 @@ GameLib.D3.ComponentCamera.prototype.onLateUpdate = function(
|
|||
deltaTime,
|
||||
parentEntity
|
||||
) {
|
||||
this.camera.quaternion.copy(parentEntity.quaternion).normalize();
|
||||
this.camera.position.copy(parentEntity.position);
|
||||
|
||||
parentEntity.quaternion.x = this.camera.quaternion.x;
|
||||
parentEntity.quaternion.y = this.camera.quaternion.y;
|
||||
parentEntity.quaternion.z = this.camera.quaternion.z;
|
||||
parentEntity.quaternion.w = this.camera.quaternion.w;
|
||||
if (this.camera) {
|
||||
|
||||
this.camera.quaternion.copy(this.parentEntity.quaternion);
|
||||
this.camera.quaternion.normalize();
|
||||
|
||||
this.camera.position.copy(this.parentEntity.position);
|
||||
|
||||
this.camera.quaternion.updateInstance();
|
||||
this.camera.position.updateInstance();
|
||||
|
||||
this.parentEntity.quaternion.x = this.camera.quaternion.x;
|
||||
this.parentEntity.quaternion.y = this.camera.quaternion.y;
|
||||
this.parentEntity.quaternion.z = this.camera.quaternion.z;
|
||||
this.parentEntity.quaternion.w = this.camera.quaternion.w;
|
||||
|
||||
this.parentEntity.quaternion.updateInstance();
|
||||
} else {
|
||||
console.warn('no camera object');
|
||||
}
|
||||
|
||||
};
|
|
@ -2,31 +2,49 @@
|
|||
*
|
||||
* @param id
|
||||
* @param name
|
||||
* @param graphics GameLib.D3.Graphics
|
||||
* @param targetEntity GameLib.D3.Entity
|
||||
* @param targetOffset GameLib.D3.API.Vector3
|
||||
* @param minDistance
|
||||
* @param moveSpeed
|
||||
* @param parentEntity
|
||||
* @param target GameLib.D3.Vector3
|
||||
* @param targetToParent GameLib.D3.Vector3
|
||||
* @param rotatedTargetOffset GameLib.D3.Vector3
|
||||
* @param rotated GameLib.D3.Vector4
|
||||
* @constructor
|
||||
*/
|
||||
GameLib.D3.ComponentFollow = function ComponentFollow(
|
||||
id,
|
||||
name,
|
||||
graphics,
|
||||
targetEntity,
|
||||
targetOffset,
|
||||
minDistance,
|
||||
moveSpeed
|
||||
moveSpeed,
|
||||
parentEntity,
|
||||
target,
|
||||
targetToParent,
|
||||
rotatedTargetOffset,
|
||||
rotated
|
||||
) {
|
||||
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;
|
||||
|
||||
// Todo: this should be executed somewhere in game-lib-z, so that we don't execute it on every construction of an object.
|
||||
GameLib.D3.Utils.Extend(GameLib.D3.ComponentFollow, GameLib.D3.ComponentInterface);
|
||||
this.graphics = graphics;
|
||||
this.graphics.isNotThreeThrow();
|
||||
|
||||
this.parentEntity = null;
|
||||
if (GameLib.D3.Utils.UndefinedOrNull(parentEntity)) {
|
||||
parentEntity = null;
|
||||
}
|
||||
this.parentEntity = parentEntity;
|
||||
|
||||
if (GameLib.D3.Utils.UndefinedOrNull(targetEntity)) {
|
||||
targetEntity = null;
|
||||
|
@ -34,20 +52,62 @@ GameLib.D3.ComponentFollow = function ComponentFollow(
|
|||
this.targetEntity = targetEntity;
|
||||
|
||||
if(GameLib.D3.Utils.UndefinedOrNull(targetOffset)) {
|
||||
targetOffset = new GameLib.D3.API.Vector3(0, 0, 0);
|
||||
targetOffset = new GameLib.D3.Vector3(
|
||||
this.graphics,
|
||||
this,
|
||||
new GameLib.D3.API.Vector3(0, 0, 0)
|
||||
);
|
||||
}
|
||||
this.targetOffset = targetOffset;
|
||||
|
||||
this.moveSpeed = moveSpeed || 12.5;
|
||||
this.minDistance = minDistance || 0;
|
||||
};
|
||||
if (GameLib.D3.Utils.UndefinedOrNull(moveSpeed)) {
|
||||
moveSpeed = 12.5;
|
||||
}
|
||||
this.moveSpeed = moveSpeed;
|
||||
|
||||
if(typeof THREE != "undefined") {
|
||||
ComponentFollow_Target_Vec3 = new THREE.Vector3();
|
||||
ComponentFollow_TargetToParent_Vec3 = new THREE.Vector3();
|
||||
ComponentFollow_rotatedTargetOffset_Vec3 = new THREE.Vector3();
|
||||
ComponentFollow_tempQuaternion = new THREE.Quaternion();
|
||||
}
|
||||
if (GameLib.D3.Utils.UndefinedOrNull(minDistance)) {
|
||||
minDistance = 0;
|
||||
}
|
||||
this.minDistance = minDistance;
|
||||
|
||||
if (GameLib.D3.Utils.UndefinedOrNull(target)) {
|
||||
target = new GameLib.D3.Vector3(
|
||||
this.graphics,
|
||||
this,
|
||||
new GameLib.D3.API.Vector3(0, 0, 0)
|
||||
);
|
||||
}
|
||||
this.target = target;
|
||||
|
||||
if (GameLib.D3.Utils.UndefinedOrNull(targetToParent)) {
|
||||
targetToParent = new GameLib.D3.Vector3(
|
||||
this.graphics,
|
||||
this,
|
||||
new GameLib.D3.API.Vector3(0, 0, 0)
|
||||
);
|
||||
}
|
||||
this.targetToParent = targetToParent;
|
||||
|
||||
if (GameLib.D3.Utils.UndefinedOrNull(rotatedTargetOffset)) {
|
||||
rotatedTargetOffset = new GameLib.D3.Vector3(
|
||||
this.graphics,
|
||||
this,
|
||||
new GameLib.D3.API.Vector3(0, 0, 0)
|
||||
);
|
||||
}
|
||||
this.rotatedTargetOffset = rotatedTargetOffset;
|
||||
|
||||
if (GameLib.D3.Utils.UndefinedOrNull(rotated)) {
|
||||
rotated = new GameLib.D3.Vector3(
|
||||
this.graphics,
|
||||
this,
|
||||
new GameLib.D3.API.Vector3(0, 0, 0)
|
||||
);
|
||||
}
|
||||
this.rotated = rotated;
|
||||
|
||||
GameLib.D3.Utils.Extend(GameLib.D3.ComponentFollow, GameLib.D3.ComponentInterface);
|
||||
};
|
||||
|
||||
///////////////////////// Methods to override //////////////////////////
|
||||
GameLib.D3.ComponentFollow.prototype.onUpdate = function(
|
||||
|
@ -55,54 +115,57 @@ GameLib.D3.ComponentFollow.prototype.onUpdate = function(
|
|||
parentEntity
|
||||
) {
|
||||
|
||||
if(this.targetEntity) {
|
||||
if (this.targetEntity) {
|
||||
|
||||
ComponentFollow_tempQuaternion.set(
|
||||
this.targetEntity.quaternion.x,
|
||||
this.targetEntity.quaternion.y,
|
||||
this.targetEntity.quaternion.z,
|
||||
this.targetEntity.quaternion.w
|
||||
);
|
||||
this.rotated.x = this.targetEntity.quaternion.x;
|
||||
this.rotated.y = this.targetEntity.quaternion.y;
|
||||
this.rotated.z = this.targetEntity.quaternion.z;
|
||||
this.rotated.w = this.targetEntity.quaternion.w;
|
||||
|
||||
ComponentFollow_rotatedTargetOffset_Vec3.set(
|
||||
this.targetOffset.x,
|
||||
this.targetOffset.y,
|
||||
this.targetOffset.z
|
||||
);
|
||||
this.rotated.updateInstance();
|
||||
|
||||
ComponentFollow_rotatedTargetOffset_Vec3 =
|
||||
ComponentFollow_rotatedTargetOffset_Vec3.applyQuaternion(
|
||||
ComponentFollow_tempQuaternion
|
||||
);
|
||||
this.rotatedTargetOffset.x = this.targetOffset.x;
|
||||
this.rotatedTargetOffset.y = this.targetOffset.y;
|
||||
this.rotatedTargetOffset.z = this.targetOffset.z;
|
||||
|
||||
ComponentFollow_Target_Vec3.set(
|
||||
this.targetEntity.position.x + ComponentFollow_rotatedTargetOffset_Vec3.x,
|
||||
this.targetEntity.position.y + ComponentFollow_rotatedTargetOffset_Vec3.y,
|
||||
this.targetEntity.position.z + ComponentFollow_rotatedTargetOffset_Vec3.z
|
||||
);
|
||||
this.rotatedTargetOffset.applyQuaternion(this.rotated);
|
||||
|
||||
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
|
||||
);
|
||||
this.rotatedTargetOffset.updateInstance();
|
||||
|
||||
ComponentFollow_TargetToParent_Vec3.normalize();
|
||||
this.target.x = this.targetEntity.position.x + this.rotatedTargetOffset.x;
|
||||
this.target.y = this.targetEntity.position.y + this.rotatedTargetOffset.y;
|
||||
this.target.z = this.targetEntity.position.z + this.rotatedTargetOffset.z;
|
||||
|
||||
ComponentFollow_TargetToParent_Vec3.set(
|
||||
ComponentFollow_TargetToParent_Vec3.x * this.minDistance,
|
||||
ComponentFollow_TargetToParent_Vec3.y * this.minDistance,
|
||||
ComponentFollow_TargetToParent_Vec3.z * this.minDistance
|
||||
);
|
||||
this.target.updateInstance();
|
||||
|
||||
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
|
||||
);
|
||||
this.targetToParent.x = this.parentEntity.position.x - this.targetEntity.position.x;
|
||||
this.targetToParent.y = this.parentEntity.position.y - this.targetEntity.position.y;
|
||||
this.targetToParent.z = this.parentEntity.position.z - this.targetEntity.position.z;
|
||||
|
||||
this.targetToParent.normalize();
|
||||
|
||||
this.targetToParent.x *= this.minDistance;
|
||||
this.targetToParent.y *= this.minDistance;
|
||||
this.targetToParent.z *= this.minDistance;
|
||||
|
||||
this.targetToParent.updateInstance();
|
||||
|
||||
this.target.x = this.target.x + this.targetToParent.x;
|
||||
this.target.y = this.target.y + this.targetToParent.y;
|
||||
this.target.z = this.target.z + this.targetToParent.z;
|
||||
|
||||
this.target.updateInstance();
|
||||
|
||||
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);
|
||||
|
||||
var lerp = this.parentEntity.position.lerp(this.target, t);
|
||||
|
||||
this.parentEntity.position.x = lerp.x;
|
||||
this.parentEntity.position.y = lerp.y;
|
||||
this.parentEntity.position.z = lerp.z;
|
||||
|
||||
this.parentEntity.position.updateInstance();
|
||||
}
|
||||
};
|
|
@ -1,116 +1,128 @@
|
|||
/**
|
||||
*
|
||||
* Looks from parentEntity to targetEntity (default up is 0,1,0)
|
||||
* @param id
|
||||
* @param name
|
||||
* @param targetEntity
|
||||
* @param targetOffset
|
||||
* @param graphics GameLib.D3.Graphics
|
||||
* @param parentEntity GameLib.D3.Entity
|
||||
* @param targetEntity GameLib.D3.Entity
|
||||
* @param targetOffset GameLib.D3.Vector3
|
||||
* @param rotationSpeed
|
||||
* @param lookAtMatrix GameLib.D3.Matrix4
|
||||
* @param up GameLib.D3.Vector3
|
||||
* @constructor
|
||||
*/
|
||||
GameLib.D3.ComponentLookAt = function ComponentLookAt(
|
||||
id,
|
||||
name,
|
||||
graphics,
|
||||
parentEntity,
|
||||
targetEntity,
|
||||
targetOffset,
|
||||
rotationSpeed
|
||||
rotationSpeed,
|
||||
lookAtMatrix,
|
||||
up
|
||||
) {
|
||||
this.id = id || GameLib.D3.Utils.RandomId();
|
||||
this.graphics = graphics;
|
||||
this.graphics.isNotThreeThrow();
|
||||
|
||||
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;
|
||||
|
||||
// Todo: this should be executed somewhere in game-lib-z, so that we don't execute it on every construction of an object.
|
||||
GameLib.D3.Utils.Extend(GameLib.D3.ComponentLookAt, GameLib.D3.ComponentInterface);
|
||||
|
||||
// todo: USE TARGET OFFSET.
|
||||
if (GameLib.D3.Utils.UndefinedOrNull(parentEntity)) {
|
||||
parentEntity = null;
|
||||
}
|
||||
this.parentEntity = parentEntity;
|
||||
|
||||
if (GameLib.D3.Utils.UndefinedOrNull(targetEntity)) {
|
||||
targetEntity = null;
|
||||
}
|
||||
this.targetEntity = targetEntity;
|
||||
|
||||
if(GameLib.D3.Utils.UndefinedOrNull(targetOffset)) {
|
||||
targetOffset = new GameLib.D3.API.Vector3(0, 0, 0);
|
||||
targetOffset = new GameLib.D3.Vector3(
|
||||
this.graphics,
|
||||
this,
|
||||
new GameLib.D3.API.Vector3(0, 0, 0)
|
||||
);
|
||||
}
|
||||
this.targetOffset = targetOffset;
|
||||
|
||||
this.lastTargetQuaternion = new GameLib.D3.API.Vector4(0, 0, 0, 1);
|
||||
this.rotationSpeed = rotationSpeed || 22.0;
|
||||
};
|
||||
if (GameLib.D3.Utils.UndefinedOrNull(rotationSpeed)) {
|
||||
rotationSpeed = 22.0;
|
||||
}
|
||||
this.rotationSpeed = rotationSpeed;
|
||||
|
||||
if(typeof THREE != "undefined") {
|
||||
ComponentLookAt_rotatedTargetOffset = new THREE.Vector3();
|
||||
ComponentLookAt_currentPos = new THREE.Vector3();
|
||||
ComponentLookAt_targetPos = new THREE.Vector3();
|
||||
ComponentLookAt_upVector = new THREE.Vector3(0, 1, 0);
|
||||
ComponentLookAt_targetQuaternion = 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();
|
||||
}
|
||||
if (GameLib.D3.Utils.UndefinedOrNull(lookAtMatrix)) {
|
||||
lookAtMatrix = new GameLib.D3.Matrix4(
|
||||
this.graphics,
|
||||
this,
|
||||
new GameLib.D3.API.Matrix4()
|
||||
);
|
||||
}
|
||||
this.lookAtMatrix = lookAtMatrix;
|
||||
|
||||
if(GameLib.D3.Utils.UndefinedOrNull(up)) {
|
||||
up = new GameLib.D3.Vector3(
|
||||
this.graphics,
|
||||
this,
|
||||
new GameLib.D3.API.Vector3(0, 1, 0)
|
||||
);
|
||||
}
|
||||
this.up = up;
|
||||
|
||||
this.targetPosition = new GameLib.D3.Vector3(
|
||||
this.graphics,
|
||||
this,
|
||||
new GameLib.D3.API.Vector3(0, 0, 0)
|
||||
);
|
||||
|
||||
this.currentRotation = new GameLib.D3.Vector4(
|
||||
this.graphics,
|
||||
this,
|
||||
new GameLib.D3.API.Vector4()
|
||||
);
|
||||
|
||||
GameLib.D3.Utils.Extend(GameLib.D3.ComponentLookAt, GameLib.D3.ComponentInterface);
|
||||
};
|
||||
|
||||
///////////////////////// Methods to override //////////////////////////
|
||||
GameLib.D3.ComponentLookAt.prototype.onUpdate = function(
|
||||
deltaTime,
|
||||
parentEntity
|
||||
) {
|
||||
if(this.targetEntity) {
|
||||
var target = this.targetEntity.position;
|
||||
if (this.targetEntity) {
|
||||
|
||||
ComponentLookAt_currentPos.set(
|
||||
parentEntity.position.x,
|
||||
parentEntity.position.y,
|
||||
parentEntity.position.z
|
||||
this.targetPosition.x = this.targetEntity.position.x + this.targetOffset.x;
|
||||
this.targetPosition.y = this.targetEntity.position.y + this.targetOffset.y;
|
||||
this.targetPosition.z = this.targetEntity.position.z + this.targetOffset.z;
|
||||
|
||||
this.targetPosition.updateInstance();
|
||||
|
||||
this.lookAtMatrix.lookAt(
|
||||
this.parentEntity.position,
|
||||
this.targetPosition,
|
||||
this.up
|
||||
);
|
||||
|
||||
ComponentLookAt_lastRotationQuaternion.set(
|
||||
this.lastTargetQuaternion.x,
|
||||
this.lastTargetQuaternion.y,
|
||||
this.lastTargetQuaternion.z,
|
||||
this.lastTargetQuaternion.w
|
||||
);
|
||||
|
||||
ComponentLookAt_rotatedTargetOffset.set(
|
||||
this.targetOffset.x,
|
||||
this.targetOffset.y,
|
||||
this.targetOffset.z
|
||||
);
|
||||
|
||||
ComponentLookAt_targetQuaternion.set(
|
||||
this.targetEntity.quaternion.x,
|
||||
this.targetEntity.quaternion.y,
|
||||
this.targetEntity.quaternion.z,
|
||||
this.targetEntity.quaternion.w
|
||||
);
|
||||
|
||||
ComponentLookAt_rotatedTargetOffset =
|
||||
ComponentLookAt_rotatedTargetOffset.applyQuaternion(
|
||||
ComponentLookAt_targetQuaternion
|
||||
);
|
||||
|
||||
ComponentLookAt_targetPos.set(
|
||||
target.x + ComponentLookAt_rotatedTargetOffset.x,
|
||||
target.y + ComponentLookAt_rotatedTargetOffset.y,
|
||||
target.z + ComponentLookAt_rotatedTargetOffset.z
|
||||
);
|
||||
|
||||
ComponentLookAt_lookAtMatrix.lookAt(
|
||||
ComponentLookAt_currentPos,
|
||||
ComponentLookAt_targetPos,
|
||||
ComponentLookAt_upVector
|
||||
);
|
||||
|
||||
ComponentLookAt_tmpQuaternion.setFromRotationMatrix(ComponentLookAt_lookAtMatrix);
|
||||
this.currentRotation.setFromRotationMatrix(this.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.currentRotation.slerp(this.currentRotation, 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;
|
||||
this.parentEntity.quaternion.x = this.currentRotation.x;
|
||||
this.parentEntity.quaternion.y = this.currentRotation.y;
|
||||
this.parentEntity.quaternion.z = this.currentRotation.z;
|
||||
this.parentEntity.quaternion.w = this.currentRotation.w;
|
||||
|
||||
this.parentEntity.quaternion.updateInstance();
|
||||
}
|
||||
};
|
|
@ -271,6 +271,33 @@ GameLib.D3.Material.prototype.createInstance = function(update) {
|
|||
fog: this.fog
|
||||
});
|
||||
|
||||
} else if (this.materialType == GameLib.D3.Material.MATERIAL_TYPE_BASIC) {
|
||||
|
||||
instance = new THREE.MeshBasicMaterial({
|
||||
name: this.name,
|
||||
opacity: this.opacity,
|
||||
transparent: this.transparent,
|
||||
blending: this.blending,
|
||||
blendSrc: this.blendSrc,
|
||||
blendDst: this.blendDst,
|
||||
blendEquation: this.blendEquation,
|
||||
depthTest: this.depthTest,
|
||||
depthFunc: this.depthFunc,
|
||||
depthWrite: this.depthWrite,
|
||||
polygonOffset: this.polygonOffset,
|
||||
polygonOffsetFactor: this.polygonOffsetFactor,
|
||||
polygonOffsetUnits: this.polygonOffsetUnits,
|
||||
alphaTest: this.alphaTest,
|
||||
clippingPlanes: this.clippingPlanes,
|
||||
clipShadows: this.clipShadows,
|
||||
overdraw: this.overdraw,
|
||||
visible: this.visible,
|
||||
side: this.side,
|
||||
color: this.color.instance,
|
||||
vertexColors: GameLib.D3.Material.TYPE_NO_COLORS,
|
||||
fog: this.fog
|
||||
});
|
||||
|
||||
} else {
|
||||
console.log("material type is not implemented yet: " + this.materialType + " - material indexes could be screwed up");
|
||||
}
|
||||
|
|
|
@ -108,81 +108,6 @@ GameLib.D3.Matrix4.prototype.updateInstance = function() {
|
|||
this.createInstance(true);
|
||||
};
|
||||
|
||||
GameLib.D3.Matrix4.prototype.rotationMatrixX = function (radians) {
|
||||
this.identity();
|
||||
this.rows[1] = new GameLib.D3.API.Vector4(0, Math.cos(radians), -1 * Math.sin(radians), 0);
|
||||
this.rows[2] = new GameLib.D3.API.Vector4(0, Math.sin(radians), Math.cos(radians), 0);
|
||||
return this;
|
||||
};
|
||||
|
||||
GameLib.D3.Matrix4.prototype.rotationMatrixY = function (radians) {
|
||||
this.identity();
|
||||
this.rows[0] = new GameLib.D3.API.Vector4(
|
||||
Math.cos(radians),
|
||||
0,
|
||||
Math.sin(radians),
|
||||
0
|
||||
);
|
||||
this.rows[2] = new GameLib.D3.API.Vector4(
|
||||
-1 * Math.sin(radians),
|
||||
0,
|
||||
Math.cos(radians),
|
||||
0
|
||||
);
|
||||
return this;
|
||||
};
|
||||
|
||||
GameLib.D3.Matrix4.prototype.rotationMatrixZ = function (radians) {
|
||||
this.identity();
|
||||
this.rows[0] = new GameLib.D3.API.Vector4(Math.cos(radians), -1 * Math.sin(radians), 0, 0);
|
||||
this.rows[1] = new GameLib.D3.API.Vector4(Math.sin(radians), Math.cos(radians), 0, 0);
|
||||
return this;
|
||||
};
|
||||
|
||||
GameLib.D3.Matrix4.prototype.rotateX = function (radians, point) {
|
||||
this.identity();
|
||||
this.rotationMatrixX(radians);
|
||||
return this.multiply(point);
|
||||
};
|
||||
|
||||
GameLib.D3.Matrix4.prototype.rotateY = function (radians, point) {
|
||||
this.identity();
|
||||
this.rotationMatrixY(radians);
|
||||
return this.multiply(point);
|
||||
};
|
||||
|
||||
GameLib.D3.Matrix4.prototype.rotateZ = function (radians, point) {
|
||||
this.identity();
|
||||
this.rotationMatrixZ(radians);
|
||||
return this.multiply(point);
|
||||
};
|
||||
|
||||
GameLib.D3.Matrix4.prototype.multiply = function (mvp) {
|
||||
if (mvp instanceof GameLib.D3.API.Vector4) {
|
||||
return new GameLib.D3.API.Vector4(
|
||||
this.rows[0].x * mvp.x + this.rows[0].y * mvp.y + this.rows[0].z * mvp.z + this.rows[0].w * mvp.w,
|
||||
this.rows[1].x * mvp.x + this.rows[1].y * mvp.y + this.rows[1].z * mvp.z + this.rows[1].w * mvp.w,
|
||||
this.rows[2].x * mvp.x + this.rows[2].y * mvp.y + this.rows[2].z * mvp.z + this.rows[2].w * mvp.w,
|
||||
this.rows[3].x * mvp.x + this.rows[3].y * mvp.y + this.rows[3].z * mvp.z + this.rows[3].w * mvp.w
|
||||
);
|
||||
} else if (mvp instanceof GameLib.D3.API.Vector3) {
|
||||
return new GameLib.D3.API.Vector3(
|
||||
this.rows[0].x * mvp.x + this.rows[0].y * mvp.y + this.rows[0].z * mvp.z,
|
||||
this.rows[1].x * mvp.x + this.rows[1].y * mvp.y + this.rows[1].z * mvp.z,
|
||||
this.rows[2].x * mvp.x + this.rows[2].y * mvp.y + this.rows[2].z * mvp.z
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
GameLib.D3.Matrix4.prototype.identity = function () {
|
||||
this.rows = [
|
||||
new GameLib.D3.API.Vector4(1, 0, 0, 0),
|
||||
new GameLib.D3.API.Vector4(0, 1, 0, 0),
|
||||
new GameLib.D3.API.Vector4(0, 0, 1, 0),
|
||||
new GameLib.D3.API.Vector4(0, 0, 0, 1)
|
||||
];
|
||||
};
|
||||
|
||||
GameLib.D3.Matrix4.prototype.lookAt = function (position, target, up) {
|
||||
|
||||
this.instance.lookAt(position.instance, target.instance, up.instance);
|
||||
|
@ -206,34 +131,5 @@ GameLib.D3.Matrix4.prototype.lookAt = function (position, target, up) {
|
|||
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;
|
||||
|
||||
};
|
||||
|
|
|
@ -23,24 +23,34 @@ GameLib.D3.Mesh = function Mesh(
|
|||
this.position = new GameLib.D3.Vector3(
|
||||
graphics,
|
||||
this,
|
||||
this.position
|
||||
this.position,
|
||||
0.001
|
||||
);
|
||||
|
||||
this.scale = new GameLib.D3.Vector3(
|
||||
graphics,
|
||||
this,
|
||||
this.scale
|
||||
this.scale,
|
||||
0.001
|
||||
);
|
||||
|
||||
this.up = new GameLib.D3.Vector3(
|
||||
graphics,
|
||||
this,
|
||||
this.up
|
||||
this.up,
|
||||
0.001
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* We don't do a Runtime rotation since it interferes with the quaternion update
|
||||
*/
|
||||
this.rotation = new GameLib.D3.Vector3(
|
||||
graphics,
|
||||
this,
|
||||
this.rotation,
|
||||
0.001
|
||||
);
|
||||
|
||||
this.quaternion = new GameLib.D3.Vector4(
|
||||
graphics,
|
||||
|
@ -322,8 +332,20 @@ GameLib.D3.Mesh.prototype.createInstance = function(update) {
|
|||
instance.up.z = this.up.z;
|
||||
|
||||
/**
|
||||
* We don't do rotation - its dealt with by quaternion
|
||||
* We don't do rotation for now - it should be dealt with by quaternion
|
||||
*/
|
||||
// instance.rotation.x = this.rotation.x;
|
||||
// instance.rotation.y = this.rotation.y;
|
||||
// instance.rotation.z = this.rotation.z;
|
||||
//
|
||||
// instance.quaternion.setFromEuler(
|
||||
// new THREE.Euler(
|
||||
// instance.rotation.x,
|
||||
// instance.rotation.y,
|
||||
// instance.rotation.z
|
||||
// )
|
||||
// );
|
||||
//
|
||||
instance.quaternion.x = this.quaternion.x;
|
||||
instance.quaternion.y = this.quaternion.y;
|
||||
instance.quaternion.z = this.quaternion.z;
|
||||
|
|
|
@ -73,238 +73,4 @@ GameLib.D3.Vector3.prototype.toApiVector = function() {
|
|||
this.y,
|
||||
this.z
|
||||
);
|
||||
};
|
||||
|
||||
GameLib.D3.Vector3.prototype.subtract = function (v) {
|
||||
return new GameLib.D3.Vector3(
|
||||
this.x - v.x,
|
||||
this.y - v.y,
|
||||
this.z - v.z
|
||||
);
|
||||
};
|
||||
|
||||
GameLib.D3.Vector3.prototype.sub = function (v) {
|
||||
return new GameLib.D3.Vector3(
|
||||
this.x - v.x,
|
||||
this.y - v.y,
|
||||
this.z - v.z
|
||||
);
|
||||
};
|
||||
|
||||
GameLib.D3.Vector3.prototype.cross = function (v) {
|
||||
return new GameLib.D3.Vector3(
|
||||
this.y * v.z - this.z * v.y,
|
||||
this.z * v.x - this.x * v.z,
|
||||
this.x * v.y - this.y * v.x
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
GameLib.D3.Vector3.clockwise = function (u, v, w, viewPoint) {
|
||||
var normal = GameLib.D3.Vector3.normal(u, v, w);
|
||||
var uv = u.copy();
|
||||
var winding = normal.dot(uv.subtract(viewPoint));
|
||||
return (winding > 0);
|
||||
};
|
||||
|
||||
GameLib.D3.Vector3.normal = function (u, v, w) {
|
||||
var vv = v.copy();
|
||||
var wv = w.copy();
|
||||
return vv.subtract(u).cross(wv.subtract(u));
|
||||
};
|
||||
|
||||
GameLib.D3.Vector3.prototype.lookAt = function (at, up) {
|
||||
var lookAtMatrix = GameLib.D3.Matrix4.lookAt(this, at, up);
|
||||
return this.multiply(lookAtMatrix);
|
||||
};
|
||||
|
||||
GameLib.D3.Vector3.prototype.translate = function (v) {
|
||||
this.x += v.x;
|
||||
this.y += v.y;
|
||||
this.z += v.z;
|
||||
return this;
|
||||
};
|
||||
|
||||
GameLib.D3.Vector3.prototype.add = function (v) {
|
||||
return new GameLib.D3.Vector3(
|
||||
this.x + v.x,
|
||||
this.y + v.y,
|
||||
this.z + v.z
|
||||
);
|
||||
};
|
||||
|
||||
GameLib.D3.Vector3.prototype.squared = function () {
|
||||
return this.x * this.x + this.y * this.y + this.z * this.z;
|
||||
};
|
||||
|
||||
GameLib.D3.Vector3.prototype.copy = function () {
|
||||
return new GameLib.D3.Vector3(
|
||||
this.x,
|
||||
this.y,
|
||||
this.z
|
||||
);
|
||||
};
|
||||
|
||||
GameLib.D3.Vector3.prototype.set = function (x, y, z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
};
|
||||
|
||||
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.distanceTo = function(v) {
|
||||
var dx = this.x - v.x,
|
||||
dy = this.y - v.y,
|
||||
dz = this.z - v.z;
|
||||
return Math.sqrt(dx * dx + dy * dy + dz * dz);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
GameLib.D3.Vector3.AngleDirection = function(forward, directionToCheck, up) {
|
||||
var perp = forward.cross(directionToCheck);
|
||||
var dir = perp.dot(up);
|
||||
|
||||
if (dir > 0.0) {
|
||||
return 1.0;
|
||||
} else if (dir < 0.0) {
|
||||
return -1.0;
|
||||
} else {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
GameLib.D3.Vector3.prototype.multiply = function (s) {
|
||||
if (s instanceof GameLib.D3.Vector3) {
|
||||
|
||||
return new GameLib.D3.Vector3(
|
||||
this.x * s.x,
|
||||
this.y * s.y,
|
||||
this.z * s.z
|
||||
)
|
||||
|
||||
} else if (s instanceof GameLib.D3.Matrix4) {
|
||||
|
||||
var x = s.rows[0].x * this.x + s.rows[0].y * this.y + s.rows[0].z * this.z + s.rows[0].w;
|
||||
var y = s.rows[1].x * this.x + s.rows[1].y * this.y + s.rows[1].z * this.z + s.rows[1].w;
|
||||
var z = s.rows[2].x * this.x + s.rows[2].y * this.y + s.rows[2].z * this.z + s.rows[2].w;
|
||||
|
||||
return new GameLib.D3.Vector3(
|
||||
x,
|
||||
y,
|
||||
z
|
||||
);
|
||||
|
||||
} else if (s instanceof GameLib.D3.Matrix3) {
|
||||
|
||||
var x = s.rows[0].x * this.x + s.rows[0].y * this.y + s.rows[0].z * this.z;
|
||||
var y = s.rows[1].x * this.x + s.rows[1].y * this.y + s.rows[1].z * this.z;
|
||||
var z = s.rows[2].x * this.x + s.rows[2].y * this.y + s.rows[2].z * this.z;
|
||||
|
||||
return new GameLib.D3.Vector3(
|
||||
x,
|
||||
y,
|
||||
z
|
||||
);
|
||||
|
||||
} else if(!isNaN(parseFloat(s)) && isFinite(s)) {
|
||||
|
||||
return new GameLib.D3.Vector3(
|
||||
this.x * s,
|
||||
this.y * s,
|
||||
this.z * s
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
console.log("functionality not implemented - please do this");
|
||||
throw new Error("not implemented");
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
GameLib.D3.Vector3.prototype.dot = function (v) {
|
||||
return (this.x * v.x) + (this.y * v.y) + (this.z * v.z);
|
||||
};
|
||||
|
||||
GameLib.D3.Vector3.prototype.normalize = function () {
|
||||
var EPSILON = 0.000001;
|
||||
var v2 = this.squared();
|
||||
|
||||
if (v2 < EPSILON) {
|
||||
return this; //do nothing for zero vector
|
||||
}
|
||||
|
||||
var invLength = 1.0 / Math.sqrt(v2);
|
||||
return new GameLib.D3.Vector3(
|
||||
this.x * invLength,
|
||||
this.y * invLength,
|
||||
this.z * invLength
|
||||
);
|
||||
};
|
||||
|
||||
GameLib.D3.Vector3.prototype.clone = function () {
|
||||
return new GameLib.D3.Vector3(
|
||||
this.x,
|
||||
this.y,
|
||||
this.z
|
||||
);
|
||||
};
|
||||
|
||||
GameLib.D3.Vector3.prototype.applyQuaternion = function(q) {
|
||||
var x = this.x, y = this.y, z = this.z;
|
||||
var qx = q.x, qy = q.y, qz = q.z, qw = q.w;
|
||||
|
||||
// calculate quat * vector
|
||||
|
||||
var ix = qw * x + qy * z - qz * y;
|
||||
var iy = qw * y + qz * x - qx * z;
|
||||
var iz = qw * z + qx * y - qy * x;
|
||||
var iw = - qx * x - qy * y - qz * z;
|
||||
|
||||
// calculate result * inverse quat
|
||||
|
||||
return new GameLib.D3.Vector3(
|
||||
ix * qw + iw * - qx + iy * - qz - iz * - qy,
|
||||
iy * qw + iw * - qy + iz * - qx - ix * - qz,
|
||||
iz * qw + iw * - qz + ix * - qy - iy * - qx
|
||||
);
|
||||
};
|
||||
|
||||
GameLib.D3.Vector3.prototype.clamp = function(min, max) {
|
||||
this.x = Math.max( min.x, Math.min( max.x, this.x ) );
|
||||
this.y = Math.max( min.y, Math.min( max.y, this.y ) );
|
||||
this.z = Math.max( min.z, Math.min( max.z, this.z ) );
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
GameLib.D3.Vector3.prototype.negate = function() {
|
||||
this.x = -this.x;
|
||||
this.y = -this.y;
|
||||
this.z = -this.z;
|
||||
return this;
|
||||
};
|
||||
|
||||
GameLib.D3.Vector3.prototype.length = function() {
|
||||
return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );
|
||||
};
|
||||
|
||||
GameLib.D3.Vector3.prototype.reflect = function(normal) {
|
||||
return this.sub( v1.copy( normal ).multiply( 2 * this.dot( normal ) ) );
|
||||
};
|
||||
|
||||
GameLib.D3.Vector3.prototype.angleTo = function (v) {
|
||||
var theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) );
|
||||
return Math.acos( exports.Math.clamp( theta, - 1, 1 ) );
|
||||
};
|
|
@ -15,6 +15,8 @@ GameLib.D3.Vector4 = function RuntimeVector4(
|
|||
|
||||
for (var property in vector4) {
|
||||
if (vector4.hasOwnProperty(property)) {
|
||||
|
||||
|
||||
this[property] = vector4[property];
|
||||
}
|
||||
}
|
||||
|
@ -82,43 +84,6 @@ GameLib.D3.Vector4.prototype.toApiVector = function() {
|
|||
);
|
||||
};
|
||||
|
||||
GameLib.D3.Vector4.prototype.translate = function (v) {
|
||||
this.x += v.x;
|
||||
this.y += v.y;
|
||||
this.z += v.z;
|
||||
return this;
|
||||
};
|
||||
|
||||
GameLib.D3.Vector4.prototype.copy = function () {
|
||||
return new GameLib.D3.Vector4(
|
||||
this.x,
|
||||
this.y,
|
||||
this.z,
|
||||
this.w
|
||||
);
|
||||
};
|
||||
|
||||
GameLib.D3.Vector4.prototype.multiply = function (s) {
|
||||
if (s instanceof GameLib.D3.Vector3) {
|
||||
this.x *= s.x;
|
||||
this.y *= s.y;
|
||||
this.z *= s.z;
|
||||
} else if (s instanceof GameLib.D3.Matrix4) {
|
||||
var x = s.rows[0].x * this.x + s.rows[0].y * this.y + s.rows[0].z * this.z + s.rows[0].w * this.w;
|
||||
var y = s.rows[1].x * this.x + s.rows[1].y * this.y + s.rows[1].z * this.z + s.rows[1].w * this.w;
|
||||
var z = s.rows[2].x * this.x + s.rows[2].y * this.y + s.rows[2].z * this.z + s.rows[2].w * this.w;
|
||||
var w = s.rows[3].x * this.x + s.rows[3].y * this.y + s.rows[3].z * this.z + s.rows[3].w * this.w;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.w = w;
|
||||
} else {
|
||||
console.log("functionality not implemented - please do this");
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
GameLib.D3.Vector4.prototype.normalize = function () {
|
||||
|
||||
this.updateInstance();
|
||||
|
@ -129,270 +94,10 @@ GameLib.D3.Vector4.prototype.normalize = function () {
|
|||
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;
|
||||
};
|
||||
|
||||
GameLib.D3.Vector4.prototype.subtract = function (v) {
|
||||
|
||||
if (v instanceof GameLib.D3.API.Vector3) {
|
||||
this.x -= v.x;
|
||||
this.y -= v.y;
|
||||
this.z -= v.z;
|
||||
}
|
||||
|
||||
if (v instanceof GameLib.D3.Vector4) {
|
||||
this.x -= v.x;
|
||||
this.y -= v.y;
|
||||
this.z -= v.z;
|
||||
this.w -= v.w;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
GameLib.D3.Vector4.Points = function () {
|
||||
this.vectors = [];
|
||||
};
|
||||
|
||||
GameLib.D3.Vector4.Points.prototype.add = function (vector) {
|
||||
|
||||
if (vector instanceof GameLib.D3.API.Vector3) {
|
||||
vector = new GameLib.D3.Vector4(
|
||||
vector.x,
|
||||
vector.y,
|
||||
vector.z,
|
||||
1
|
||||
)
|
||||
}
|
||||
|
||||
if (!vector instanceof GameLib.D3.Vector4) {
|
||||
console.warn("Vector needs to be of type Vector4");
|
||||
throw new Error("Vector needs to be of type Vector4");
|
||||
}
|
||||
|
||||
this.vectors.push(vector);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
GameLib.D3.Vector4.Points.prototype.copy = function () {
|
||||
|
||||
var vectors = [];
|
||||
|
||||
for (var i = 0; i < this.vectors.length; i++) {
|
||||
vectors.push(this.vectors[i].copy());
|
||||
}
|
||||
|
||||
return vectors;
|
||||
};
|
||||
|
||||
GameLib.D3.Vector4.Points.prototype.maximizeXDistance = function (grain) {
|
||||
|
||||
// console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2));
|
||||
|
||||
var multiplier = 0;
|
||||
|
||||
var rotationMatrixY = new GameLib.D3.Matrix4().rotationMatrixY(grain);
|
||||
|
||||
var totalRadians = 0;
|
||||
|
||||
var backupVectors = this.copy();
|
||||
|
||||
var maxXDistance = 0;
|
||||
|
||||
for (var i = 0; i < Math.PI * 2; i += grain) {
|
||||
|
||||
multiplier++;
|
||||
|
||||
for (var j = 0; j < this.vectors.length; j++) {
|
||||
this.vectors[j] = rotationMatrixY.multiply(this.vectors[j]);
|
||||
}
|
||||
|
||||
var distances = this.distances();
|
||||
|
||||
if (distances.x > maxXDistance) {
|
||||
|
||||
maxXDistance = distances.x;
|
||||
totalRadians = multiplier * grain;
|
||||
}
|
||||
}
|
||||
|
||||
this.vectors = backupVectors;
|
||||
|
||||
// console.log("distance: " + maxXDistance + " radians : " + totalRadians);
|
||||
|
||||
var maxRotationMatrix = new GameLib.D3.Matrix4().rotationMatrixY(totalRadians);
|
||||
|
||||
for (var k = 0; k < this.vectors.length; k++) {
|
||||
this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]);
|
||||
}
|
||||
|
||||
// console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2));
|
||||
|
||||
};
|
||||
|
||||
GameLib.D3.Vector4.Points.prototype.maximizeYDistance = function (grain) {
|
||||
|
||||
// console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2));
|
||||
|
||||
var multiplier = 0;
|
||||
|
||||
var rotationMatrixX = new GameLib.D3.Matrix4().rotationMatrixX(grain);
|
||||
|
||||
var totalRadians = 0;
|
||||
|
||||
var backupVectors = this.copy();
|
||||
|
||||
var maxYDistance = 0;
|
||||
|
||||
for (var i = 0; i < Math.PI * 2; i += grain) {
|
||||
|
||||
multiplier++;
|
||||
|
||||
for (var j = 0; j < this.vectors.length; j++) {
|
||||
this.vectors[j] = rotationMatrixX.multiply(this.vectors[j]);
|
||||
}
|
||||
|
||||
var distances = this.distances();
|
||||
|
||||
if (distances.y > maxYDistance) {
|
||||
maxYDistance = distances.y;
|
||||
totalRadians = multiplier * grain;
|
||||
}
|
||||
}
|
||||
|
||||
this.vectors = backupVectors;
|
||||
|
||||
// console.log("distance: " + maxYDistance + " radians : " + totalRadians);
|
||||
|
||||
var maxRotationMatrix = new GameLib.D3.Matrix4().rotationMatrixX(totalRadians);
|
||||
|
||||
for (var k = 0; k < this.vectors.length; k++) {
|
||||
this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]);
|
||||
}
|
||||
|
||||
// console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2));
|
||||
|
||||
};
|
||||
|
||||
|
||||
GameLib.D3.Vector4.Points.prototype.lookAt = function (at, up) {
|
||||
|
||||
var polyCenter = this.average();
|
||||
|
||||
console.log("poly center : " + JSON.stringify(polyCenter));
|
||||
|
||||
var lookAtMatrix = new GameLib.D3.Matrix4().lookAt(polyCenter, at, up);
|
||||
|
||||
lookAtMatrix.rows[0] = new GameLib.D3.Vector4(1, 0, 0, 0);
|
||||
lookAtMatrix.rows[1] = new GameLib.D3.Vector4(0, 0, 1, 0);
|
||||
lookAtMatrix.rows[2] = new GameLib.D3.Vector4(0, 1, 0, 0);
|
||||
|
||||
console.log("look at matrix : " + JSON.stringify(lookAtMatrix, null, 2));
|
||||
|
||||
for (var i = 0; i < this.vectors.length; i++) {
|
||||
console.log("vector " + i + " (before): " + JSON.stringify(this.vectors[i]));
|
||||
this.vectors[i] = lookAtMatrix.multiply(this.vectors[i]);
|
||||
console.log("vector " + i + " (after) : " + JSON.stringify(this.vectors[i]));
|
||||
}
|
||||
};
|
||||
|
||||
GameLib.D3.Vector4.Points.prototype.distances = function () {
|
||||
|
||||
var minX = this.vectors[0].x;
|
||||
var minY = this.vectors[0].y;
|
||||
var minZ = this.vectors[0].z;
|
||||
|
||||
var maxX = this.vectors[0].x;
|
||||
var maxY = this.vectors[0].y;
|
||||
var maxZ = this.vectors[0].z;
|
||||
|
||||
for (var i = 0; i < this.vectors.length; i++) {
|
||||
if (this.vectors[i].x < minX) {
|
||||
minX = this.vectors[i].x;
|
||||
}
|
||||
if (this.vectors[i].y < minY) {
|
||||
minY = this.vectors[i].y;
|
||||
}
|
||||
if (this.vectors[i].z < minZ) {
|
||||
minZ = this.vectors[i].z;
|
||||
}
|
||||
|
||||
if (this.vectors[i].x > maxX) {
|
||||
maxX = this.vectors[i].x;
|
||||
}
|
||||
if (this.vectors[i].y > maxY) {
|
||||
maxY = this.vectors[i].y;
|
||||
}
|
||||
if (this.vectors[i].z > maxZ) {
|
||||
maxZ = this.vectors[i].z;
|
||||
}
|
||||
}
|
||||
|
||||
return new GameLib.D3.API.Vector3(
|
||||
Math.abs(maxX - minX),
|
||||
Math.abs(maxY - minY),
|
||||
Math.abs(maxY - minZ)
|
||||
)
|
||||
};
|
||||
|
||||
GameLib.D3.Vector4.Points.prototype.average = function () {
|
||||
var averageX = 0;
|
||||
var averageY = 0;
|
||||
var averageZ = 0;
|
||||
|
||||
for (var i = 0; i < this.vectors.length; i++) {
|
||||
averageX += this.vectors[i].x;
|
||||
averageY += this.vectors[i].y;
|
||||
averageZ += this.vectors[i].z;
|
||||
}
|
||||
|
||||
return new GameLib.D3.API.Vector3(
|
||||
averageX / this.vectors.length,
|
||||
averageY / this.vectors.length,
|
||||
averageZ / this.vectors.length
|
||||
);
|
||||
};
|
||||
|
||||
GameLib.D3.Vector4.Points.prototype.negate = function () {
|
||||
|
||||
for (var i = 0; i < this.vectors.length; i++) {
|
||||
this.vectors[i].x *= -1;
|
||||
this.vectors[i].y *= -1;
|
||||
this.vectors[i].z *= -1;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
GameLib.D3.Vector4.Points.prototype.toOrigin = function () {
|
||||
|
||||
var distanceFromOrigin = this.average().negate();
|
||||
|
||||
for (var i = 0; i < this.vectors.length; i++) {
|
||||
this.vectors[i].translate(distanceFromOrigin);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param matrix4 GameLib.D3.Matrix4
|
||||
|
@ -406,3 +111,23 @@ GameLib.D3.Vector4.prototype.setFromRotationMatrix = function(matrix4) {
|
|||
this.z = this.instance.z;
|
||||
this.w = this.instance.w;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param vector4 GameLib.D3.Vector4
|
||||
* @param t
|
||||
* @returns {GameLib.D3.Vector4}
|
||||
*/
|
||||
GameLib.D3.Vector4.prototype.slerp = function (vector4, t) {
|
||||
|
||||
this.updateInstance();
|
||||
|
||||
this.instance.slerp(vector4.instance, t);
|
||||
|
||||
this.x = this.instance.x;
|
||||
this.y = this.instance.y;
|
||||
this.z = this.instance.z;
|
||||
this.w = this.instance.w;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue