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

312 lines
6.7 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 = {};
}
if (apiMatrix4 instanceof GameLib.Matrix4) {
return 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.toApiObject = function () {
return new GameLib.API.Matrix4(
this.rows[0].toApiObject(),
this.rows[1].toApiObject(),
this.rows[2].toApiObject(),
this.rows[3].toApiObject()
);
};
/**
* Creates a GameLib.Matrix4 from an Object matrix
* @param graphics GameLib.D3.Graphics
* @param objectMatrix Object
* @param parentObject
* @returns {GameLib.Matrix4}
* @constructor
*/
GameLib.Matrix4.FromObject = function(graphics, objectMatrix, parentObject) {
var apiMatrix = new GameLib.API.Matrix4.FromObject(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;
};