250 lines
6.2 KiB
JavaScript
250 lines
6.2 KiB
JavaScript
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;
|
|
|
|
};
|
|
|
|
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 ) );
|
|
}; |