/** * Runtime Matrix4 * @param graphics * @param parentObject * @param apiMatrix4 * @param grain * @constructor */ GameLib.Matrix4 = function( graphics, parentObject, apiMatrix4, grain ) { GameLib.API.Matrix4.call( this, apiMatrix4.rows[0], apiMatrix4.rows[1], apiMatrix4.rows[2], apiMatrix4.rows[3] ); this.graphics = graphics; this.graphics.isNotThreeThrow(); this.parentObject = parentObject; if (GameLib.Utils.UndefinedOrNull(grain)) { grain = 0.001; } this.grain = grain; this.rows[0] = new GameLib.Vector4( this.graphics, this, this.rows[0], grain ); this.rows[1] = new GameLib.Vector4( this.graphics, this, this.rows[1], grain ); this.rows[2] = new GameLib.Vector4( this.graphics, this, this.rows[2], grain ); this.rows[3] = new GameLib.Vector4( this.graphics, this, this.rows[3], 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) { if (this.parentObject.updateInstance) { this.parentObject.updateInstance(); } } }; /** * GameLib.Matrix4 to GameLib.API.Matrix4 * @returns {*} */ GameLib.Matrix4.prototype.toApiMatrix = function () { return new GameLib.API.Matrix4( this.rows[0].toApiVector(), this.rows[1].toApiVector(), this.rows[2].toApiVector(), this.rows[3].toApiVector() ) }; /** * 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( new GameLib.API.Vector4( objectMatrix[0], objectMatrix[1], objectMatrix[2], objectMatrix[3] ), new GameLib.API.Vector4( objectMatrix[4], objectMatrix[5], objectMatrix[6], objectMatrix[7] ), new GameLib.API.Vector4( objectMatrix[8], objectMatrix[9], objectMatrix[10], objectMatrix[11] ), new GameLib.API.Vector4( objectMatrix[12], objectMatrix[13], objectMatrix[14], objectMatrix[15] ) ); return new GameLib.Matrix4( graphics, parentObject, apiMatrix ) }; GameLib.Matrix4.prototype.lookAt = function (position, target, up) { var pv = new GameLib.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; this.updateInstance(); return this; }; GameLib.Matrix4.prototype.identity = function () { this.rows = [ new GameLib.Vector4( this.graphics, this, new GameLib.API.Vector4(1,0,0,0), this.grain ), new GameLib.Vector4( this.graphics, this, new GameLib.API.Vector4(0,1,0,0), this.grain ), new GameLib.Vector4( this.graphics, this, new GameLib.API.Vector4(0,0,1,0), this.grain ), new GameLib.Vector4( this.graphics, this, new GameLib.API.Vector4(0,0,0,1), this.grain ) ]; }; 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; };