r3-legacy/src/game-lib-matrix-4.js

312 lines
6.9 KiB
JavaScript

/**
* Runtime Matrix4
* @param graphics
* @param parentObject
* @param apiMatrix4
* @param grain
* @constructor
*/
GameLib.Matrix4 = function(
graphics,
apiMatrix4,
parentObject,
grain
) {
this.graphics = graphics;
this.graphics.isNotThreeThrow();
if (GameLib.Utils.UndefinedOrNull(apiMatrix4)) {
apiMatrix4 = {};
}
GameLib.API.Matrix4.call(
this,
apiMatrix4.rows[0],
apiMatrix4.rows[1],
apiMatrix4.rows[2],
apiMatrix4.rows[3]
);
if (GameLib.Utils.UndefinedOrNull(parentObject)) {
parentObject = null;
}
this.parentObject = parentObject;
if (GameLib.Utils.UndefinedOrNull(grain)) {
grain = 0.001;
}
this.grain = grain;
this.rows = this.rows.map(
function(row) {
if (row instanceof GameLib.API.Vector4) {
return new GameLib.Vector4(
this.graphics,
row,
this,
this.grain
);
} else {
console.warn('Attempted conversion of wrong instance');
throw new Error('Attempted conversion of wrong instance');
}
}.bind(this)
);
this.forward = new GameLib.Vector4(
this.graphics,
this.forward,
this,
this.grain
);
this.left = new GameLib.Vector4(
this.graphics,
this.left,
this,
this.grain
);
this.up = new GameLib.Vector4(
this.graphics,
this.up,
this,
this.grain
);
this.instance = this.createInstance();
};
GameLib.Matrix4.prototype = Object.create(GameLib.API.Matrix4.prototype);
GameLib.Matrix4.prototype.constructor = GameLib.Matrix4;
/**
* Creates a matrix 4 instance (currently from graphics lib)
* @param update
*/
GameLib.Matrix4.prototype.createInstance = function(update) {
var instance = null;
if (update) {
instance = this.instance;
}
if (!instance) {
instance = new THREE.Matrix4();
}
/**
* We transpose our matrix when we send it to three since we use a different ordering system
* They say they use
*/
instance.set(
this.rows[0].x,
this.rows[1].x,
this.rows[2].x,
this.rows[3].x,
this.rows[0].y,
this.rows[1].y,
this.rows[2].y,
this.rows[3].y,
this.rows[0].z,
this.rows[1].z,
this.rows[2].z,
this.rows[3].z,
this.rows[0].w,
this.rows[1].w,
this.rows[2].w,
this.rows[3].w
);
return instance;
};
/**
* Updates this instance
*/
GameLib.Matrix4.prototype.updateInstance = function() {
this.createInstance(true);
if (this.parentObject &&
this.parentObject.updateInstance) {
this.parentObject.updateInstance();
}
};
/**
* GameLib.Matrix4 to GameLib.API.Matrix4
* @returns {*}
*/
GameLib.Matrix4.prototype.toApiMatrix = function () {
return this.rows.map(
function(row) {
if (row instanceof GameLib.Vector4) {
return row.toApiVector();
} else {
console.warn('Incompatible conversion to API matrix for vector: ', row);
throw new Error('Incompatible conversion to API matrix for a vector');
}
}
);
};
/**
* Creates a GameLib.Matrix4 from an Object matrix
* @param graphics GameLib.D3.Graphics
* @param objectMatrix Object
* @param parentObject
* @returns {GameLib.Matrix4}
* @constructor
*/
GameLib.Matrix4.FromObjectMatrix = function(graphics, objectMatrix, parentObject) {
var apiMatrix = new GameLib.API.Matrix4.FromObjectMatrix(objectMatrix);
return new GameLib.Matrix4(
graphics,
parentObject,
apiMatrix
)
};
/**
* Lookat
* @param position
* @param target
* @param up
* @returns {GameLib.Matrix4}
*/
GameLib.Matrix4.prototype.lookAt = function (position, target, up) {
var pv = new GameLib.API.Vector3(position.x, position.y, position.z);
var forward = pv.subtract(target).normalize();
if (forward.squared() === 0) {
forward.z = 1;
}
var left = up.cross(forward).normalize();
if (left.squared() === 0) {
forward.x += 0.0001;
left = up.cross(forward).normalize();
}
var _up = forward.cross(left);
this.rows[0].x = left.x;
this.rows[0].y = left.y;
this.rows[0].z = left.z;
this.rows[1].x = _up.x;
this.rows[1].y = _up.y;
this.rows[1].z = _up.z;
this.rows[2].x = forward.x;
this.rows[2].y = forward.y;
this.rows[2].z = forward.z;
this.forward.x = forward.x;
this.forward.y = forward.y;
this.forward.z = forward.z;
this.left.x = left.x;
this.left.y = left.y;
this.left.z = left.z;
this.up.x = _up.x;
this.up.y = _up.y;
this.up.z = _up.z;
this.updateInstance();
return this;
};
/**
* Identity
*/
GameLib.Matrix4.prototype.identity = function () {
this.rows = [
new GameLib.Vector4(
this.graphics,
new GameLib.API.Vector4(1,0,0,0),
this,
this.grain
),
new GameLib.Vector4(
this.graphics,
new GameLib.API.Vector4(0,1,0,0),
this,
this.grain
),
new GameLib.Vector4(
this.graphics,
new GameLib.API.Vector4(0,0,1,0),
this,
this.grain
),
new GameLib.Vector4(
this.graphics,
new GameLib.API.Vector4(0,0,0,1),
this,
this.grain
)
];
};
/**
* Transpose
* @returns {GameLib.Matrix4}
*/
GameLib.Matrix4.prototype.transpose = function () {
this.temp[0].x = this.rows[0].x;
this.temp[0].y = this.rows[1].x;
this.temp[0].z = this.rows[2].x;
this.temp[0].w = this.rows[3].x;
this.temp[1].x = this.rows[0].y;
this.temp[1].y = this.rows[1].y;
this.temp[1].z = this.rows[2].y;
this.temp[1].w = this.rows[3].y;
this.temp[2].x = this.rows[0].z;
this.temp[2].y = this.rows[1].z;
this.temp[2].z = this.rows[2].z;
this.temp[2].w = this.rows[3].z;
this.temp[3].x = this.rows[0].w;
this.temp[3].y = this.rows[1].w;
this.temp[3].z = this.rows[2].w;
this.temp[3].w = this.rows[3].w;
this.rows[0].x = this.temp[0].x;
this.rows[0].y = this.temp[0].y;
this.rows[0].z = this.temp[0].z;
this.rows[0].w = this.temp[0].w;
this.rows[1].x = this.temp[1].x;
this.rows[1].y = this.temp[1].y;
this.rows[1].z = this.temp[1].z;
this.rows[1].w = this.temp[1].w;
this.rows[2].x = this.temp[2].x;
this.rows[2].y = this.temp[2].y;
this.rows[2].z = this.temp[2].z;
this.rows[2].w = this.temp[2].w;
this.rows[3].x = this.temp[3].x;
this.rows[3].y = this.temp[3].y;
this.rows[3].z = this.temp[3].z;
this.rows[3].w = this.temp[3].w;
return this;
};