272 lines
6.5 KiB
JavaScript
272 lines
6.5 KiB
JavaScript
GameLib.API.Vector3 = function (x, y, z) {
|
|
|
|
if (GameLib.Utils.UndefinedOrNull(x)) {
|
|
x = 0;
|
|
}
|
|
this.x = x;
|
|
|
|
if (GameLib.Utils.UndefinedOrNull(y)) {
|
|
y = 0;
|
|
}
|
|
this.y = y;
|
|
|
|
if (GameLib.Utils.UndefinedOrNull(z)) {
|
|
z = 0;
|
|
}
|
|
this.z = z;
|
|
|
|
};
|
|
|
|
GameLib.API.Vector3.prototype.negate = function() {
|
|
this.x = -this.x;
|
|
this.y = -this.y;
|
|
this.z = -this.z;
|
|
return this;
|
|
};
|
|
|
|
GameLib.API.Vector3.prototype.subtract = function (v) {
|
|
return new GameLib.API.Vector3(
|
|
this.x - v.x,
|
|
this.y - v.y,
|
|
this.z - v.z
|
|
);
|
|
};
|
|
|
|
GameLib.API.Vector3.prototype.sub = function (v) {
|
|
return new GameLib.API.Vector3(
|
|
this.x - v.x,
|
|
this.y - v.y,
|
|
this.z - v.z
|
|
);
|
|
};
|
|
|
|
GameLib.API.Vector3.prototype.equals = function (v) {
|
|
return this.x === v.x && this.y === v.y && this.z === v.z;
|
|
};
|
|
|
|
GameLib.API.Vector3.prototype.cross = function (v) {
|
|
return new GameLib.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.API.Vector3.clockwise = function (u, v, w, viewPoint) {
|
|
var normal = GameLib.API.Vector3.normal(u, v, w);
|
|
var uv = u.copy();
|
|
var winding = normal.dot(uv.subtract(viewPoint));
|
|
return (winding > 0);
|
|
};
|
|
|
|
GameLib.API.Vector3.normal = function (u, v, w) {
|
|
var vv = v.copy();
|
|
var wv = w.copy();
|
|
return vv.subtract(u).cross(wv.subtract(u));
|
|
};
|
|
|
|
GameLib.API.Vector3.prototype.lookAt = function (at, up) {
|
|
var lookAtMatrix = GameLib.API.Matrix4.lookAt(this, at, up);
|
|
return this.multiply(lookAtMatrix);
|
|
};
|
|
|
|
GameLib.API.Vector3.prototype.translate = function (v) {
|
|
this.x += v.x;
|
|
this.y += v.y;
|
|
this.z += v.z;
|
|
return this;
|
|
};
|
|
|
|
GameLib.API.Vector3.prototype.add = function (v) {
|
|
this.x += v.x;
|
|
this.y += v.y;
|
|
this.z += v.z;
|
|
return this;
|
|
};
|
|
|
|
GameLib.API.Vector3.prototype.squared = function () {
|
|
return this.x * this.x + this.y * this.y + this.z * this.z;
|
|
};
|
|
|
|
GameLib.API.Vector3.prototype.copy = function () {
|
|
return new GameLib.API.Vector3(
|
|
this.x,
|
|
this.y,
|
|
this.z
|
|
);
|
|
};
|
|
|
|
GameLib.API.Vector3.prototype.set = function (x, y, z) {
|
|
this.x = x;
|
|
this.y = y;
|
|
this.z = z;
|
|
};
|
|
|
|
GameLib.API.Vector3.prototype.lerp = function ( v, alpha ) {
|
|
return new GameLib.API.Vector3(
|
|
this.x + ( v.x - this.x ) * alpha,
|
|
this.y + ( v.y - this.y ) * alpha,
|
|
this.z + ( v.z - this.z ) * alpha
|
|
);
|
|
};
|
|
|
|
GameLib.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.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;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Multiplies this vector with a scalar, vector or matrix. If you want a copy, copy() it first
|
|
* @param object {Number | GameLib.API.Vector3 | GameLib.API.Vector4 | GameLib.API.Matrix3 | GameLib.API.Matrix4}
|
|
* @param cross boolean true if you want the cross product, otherwise returns the scalar (dot or inner) product
|
|
* @returns {GameLib.API.Vector3 | Number}
|
|
*/
|
|
GameLib.API.Vector3.prototype.multiply = function (object, cross) {
|
|
|
|
var x, y, z;
|
|
|
|
var a = object;
|
|
var b = this;
|
|
|
|
if (GameLib.Utils.UndefinedOrNull(cross)) {
|
|
cross = false;
|
|
}
|
|
|
|
if (typeof object == 'number') {
|
|
|
|
if (cross) {
|
|
this.x *= object;
|
|
this.y *= object;
|
|
this.z *= object;
|
|
return this;
|
|
} else {
|
|
return ((this.x * object) + (this.y * object) + (this.z * object));
|
|
}
|
|
|
|
}
|
|
|
|
if (object instanceof GameLib.API.Vector3) {
|
|
|
|
if (cross) {
|
|
|
|
x = (a.y * b.z) - (a.z * b.y);
|
|
y = (a.z * b.x) - (a.x * b.z);
|
|
z = (a.x * b.y) - (a.y * b.x);
|
|
|
|
this.x = x;
|
|
this.y = y;
|
|
this.z = z;
|
|
|
|
return this;
|
|
|
|
} else {
|
|
return ((this.x * object.x) + (this.y * object.y) + (this.z * object.z));
|
|
}
|
|
|
|
} else {
|
|
console.log("functionality not implemented - please do this");
|
|
throw new Error("not implemented");
|
|
}
|
|
};
|
|
|
|
|
|
GameLib.API.Vector3.prototype.dot = function (v) {
|
|
return (this.x * v.x) + (this.y * v.y) + (this.z * v.z);
|
|
};
|
|
|
|
GameLib.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.API.Vector3(
|
|
this.x * invLength,
|
|
this.y * invLength,
|
|
this.z * invLength
|
|
);
|
|
};
|
|
|
|
GameLib.API.Vector3.prototype.clone = function () {
|
|
return new GameLib.API.Vector3(
|
|
this.x,
|
|
this.y,
|
|
this.z
|
|
);
|
|
};
|
|
|
|
GameLib.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;
|
|
|
|
return this;
|
|
};
|
|
|
|
GameLib.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.API.Vector3.prototype.length = function() {
|
|
return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );
|
|
};
|
|
|
|
GameLib.API.Vector3.prototype.reflect = function(normal) {
|
|
return this.sub( v1.copy( normal ).multiply( 2 * this.dot( normal ) ) );
|
|
};
|
|
|
|
GameLib.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 ) );
|
|
};
|
|
|
|
/**
|
|
* Returns an API vector from an Object vector
|
|
* @param objectVector
|
|
* @constructor
|
|
*/
|
|
GameLib.API.Vector3.FromObject = function (objectVector) {
|
|
return new GameLib.API.Vector3(
|
|
objectVector.x,
|
|
objectVector.y,
|
|
objectVector.z
|
|
)
|
|
};
|