diff --git a/cocos2d/core/CCCamera.js b/cocos2d/core/CCCamera.js index 79fe599b66..ea6c6db8c7 100644 --- a/cocos2d/core/CCCamera.js +++ b/cocos2d/core/CCCamera.js @@ -62,7 +62,7 @@ cc.Camera = cc.Class.extend({ * constructor of cc.Camera */ ctor:function () { - this._lookupMatrix = new cc.kmMat4(); + this._lookupMatrix = new cc.math.Matrix4(); this.restore(); }, @@ -103,7 +103,7 @@ cc.Camera = cc.Class.extend({ this._upY = 1.0; this._upZ = 0.0; - cc.kmMat4Identity( this._lookupMatrix ); + this._lookupMatrix.identity(); this._dirty = false; }, @@ -113,14 +113,10 @@ cc.Camera = cc.Class.extend({ */ locate:function () { if (this._dirty) { - var eye = new cc.kmVec3(), center = new cc.kmVec3(), up = new cc.kmVec3(); - - cc.kmVec3Fill( eye, this._eyeX, this._eyeY , this._eyeZ ); - cc.kmVec3Fill( center, this._centerX, this._centerY, this._centerZ); - - cc.kmVec3Fill( up, this._upX, this._upY, this._upZ); - cc.kmMat4LookAt( this._lookupMatrix, eye, center, up); - + var eye = new cc.math.Vec3(this._eyeX, this._eyeY , this._eyeZ), + center = new cc.math.Vec3(this._centerX, this._centerY, this._centerZ), + up = new cc.math.Vec3(this._upX, this._upY, this._upZ); + this._lookupMatrix.lookAt(eye, center, up); this._dirty = false; } cc.kmGLMultMatrix( this._lookupMatrix); @@ -128,17 +124,13 @@ cc.Camera = cc.Class.extend({ _locateForRenderer: function(matrix){ if (this._dirty) { - var eye = new cc.kmVec3(), center = new cc.kmVec3(), up = new cc.kmVec3(); - - cc.kmVec3Fill( eye, this._eyeX, this._eyeY , this._eyeZ ); - cc.kmVec3Fill( center, this._centerX, this._centerY, this._centerZ); - - cc.kmVec3Fill( up, this._upX, this._upY, this._upZ); - cc.kmMat4LookAt( this._lookupMatrix, eye, center, up); - + var eye = new cc.math.Vec3(this._eyeX, this._eyeY , this._eyeZ), + center = new cc.math.Vec3(this._centerX, this._centerY, this._centerZ), + up = new cc.math.Vec3(this._upX, this._upY, this._upZ); + this._lookupMatrix.lookAt(eye, center, up); this._dirty = false; } - cc.kmMat4Multiply(matrix, matrix, this._lookupMatrix); + matrix.multiply(this._lookupMatrix); }, /** diff --git a/cocos2d/core/CCDirector.js b/cocos2d/core/CCDirector.js index b9cfbc1437..99988bd431 100644 --- a/cocos2d/core/CCDirector.js +++ b/cocos2d/core/CCDirector.js @@ -27,13 +27,14 @@ cc.g_NumberOfDraws = 0; cc.GLToClipTransform = function (transformOut) { - var projection = new cc.kmMat4(); - cc.kmGLGetMatrix(cc.KM_GL_PROJECTION, projection); + //var projection = new cc.math.Matrix4(); + //cc.kmGLGetMatrix(cc.KM_GL_PROJECTION, projection); + cc.kmGLGetMatrix(cc.KM_GL_PROJECTION, transformOut); - var modelview = new cc.kmMat4(); + var modelview = new cc.math.Matrix4(); cc.kmGLGetMatrix(cc.KM_GL_MODELVIEW, modelview); - cc.kmMat4Multiply(transformOut, projection, modelview); + transformOut.multiply(modelview); }; //---------------------------------------------------------------------------------------------------------------------- diff --git a/cocos2d/core/CCDirectorWebGL.js b/cocos2d/core/CCDirectorWebGL.js index d5468d4fe0..0747f31794 100644 --- a/cocos2d/core/CCDirectorWebGL.js +++ b/cocos2d/core/CCDirectorWebGL.js @@ -57,13 +57,11 @@ if (cc._renderType === cc._RENDER_TYPE_WEBGL) { case cc.Director.PROJECTION_2D: cc.kmGLMatrixMode(cc.KM_GL_PROJECTION); cc.kmGLLoadIdentity(); - var orthoMatrix = new cc.kmMat4(); - cc.kmMat4OrthographicProjection( - orthoMatrix, + var orthoMatrix = cc.math.Matrix4.createOrthographicProjection( -ox, - size.width - ox, + size.width - ox, -oy, - size.height - oy, + size.height - oy, -1024, 1024); cc.kmGLMultMatrix(orthoMatrix); cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW); @@ -71,21 +69,21 @@ if (cc._renderType === cc._RENDER_TYPE_WEBGL) { break; case cc.Director.PROJECTION_3D: var zeye = _t.getZEye(); - var matrixPerspective = new cc.kmMat4(), matrixLookup = new cc.kmMat4(); + var matrixPerspective = new cc.math.Matrix4(), matrixLookup = new cc.math.Matrix4(); cc.kmGLMatrixMode(cc.KM_GL_PROJECTION); cc.kmGLLoadIdentity(); // issue #1334 - cc.kmMat4PerspectiveProjection(matrixPerspective, 60, size.width / size.height, 0.1, zeye * 2); + matrixPerspective = cc.math.Matrix4.createPerspectiveProjection(60, size.width / size.height, 0.1, zeye * 2); cc.kmGLMultMatrix(matrixPerspective); cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW); cc.kmGLLoadIdentity(); - var eye = cc.kmVec3Fill(null, -ox + size.width / 2, -oy + size.height / 2, zeye); - var center = cc.kmVec3Fill(null, -ox + size.width / 2, -oy + size.height / 2, 0.0); - var up = cc.kmVec3Fill(null, 0.0, 1.0, 0.0); - cc.kmMat4LookAt(matrixLookup, eye, center, up); + var eye = new cc.math.Vec3(-ox + size.width / 2, -oy + size.height / 2, zeye); + var center = new cc.math.Vec3( -ox + size.width / 2, -oy + size.height / 2, 0.0); + var up = new cc.math.Vec3( 0.0, 1.0, 0.0); + matrixLookup.lookAt(eye, center, up); cc.kmGLMultMatrix(matrixLookup); break; case cc.Director.PROJECTION_CUSTOM: @@ -238,38 +236,31 @@ if (cc._renderType === cc._RENDER_TYPE_WEBGL) { }; _p.convertToGL = function (uiPoint) { - var transform = new cc.kmMat4(); + var transform = new cc.math.Matrix4(); cc.GLToClipTransform(transform); - var transformInv = new cc.kmMat4(); - cc.kmMat4Inverse(transformInv, transform); + var transformInv = transform.inverse(); // Calculate z=0 using -> transform*[0, 0, 0, 1]/w var zClip = transform.mat[14] / transform.mat[15]; - var glSize = this._openGLView.getDesignResolutionSize(); - var clipCoord = new cc.kmVec3(2.0 * uiPoint.x / glSize.width - 1.0, 1.0 - 2.0 * uiPoint.y / glSize.height, zClip); - - var glCoord = new cc.kmVec3(); - cc.kmVec3TransformCoord(glCoord, clipCoord, transformInv); - + var glCoord = new cc.math.Vec3(2.0 * uiPoint.x / glSize.width - 1.0, 1.0 - 2.0 * uiPoint.y / glSize.height, zClip); + glCoord.transformCoord(transformInv); return cc.p(glCoord.x, glCoord.y); }; _p.convertToUI = function (glPoint) { - var transform = new cc.kmMat4(); + var transform = new cc.math.Matrix4(); cc.GLToClipTransform(transform); - var clipCoord = new cc.kmVec3(); + var clipCoord = new cc.math.Vec3(glPoint.x, glPoint.y, 0.0); // Need to calculate the zero depth from the transform. - var glCoord = new cc.kmVec3(glPoint.x, glPoint.y, 0.0); - cc.kmVec3TransformCoord(clipCoord, glCoord, transform); + clipCoord.transformCoord(transform); var glSize = this._openGLView.getDesignResolutionSize(); return cc.p(glSize.width * (clipCoord.x * 0.5 + 0.5), glSize.height * (-clipCoord.y * 0.5 + 0.5)); }; - _p.getVisibleSize = function () { //if (this._openGLView) { return this._openGLView.getVisibleSize(); diff --git a/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js b/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js index d0fc3a4afd..5342f1c3a5 100644 --- a/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js +++ b/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js @@ -26,11 +26,11 @@ cc.Node.WebGLRenderCmd = function (renderable) { cc.Node.RenderCmd.call(this, renderable); - var mat4 = new cc.kmMat4(); - mat4.mat[2] = mat4.mat[3] = mat4.mat[6] = mat4.mat[7] = mat4.mat[8] = mat4.mat[9] = mat4.mat[11] = mat4.mat[14] = 0.0; - mat4.mat[10] = mat4.mat[15] = 1.0; + var mat4 = new cc.math.Matrix4(), mat = mat4.mat; + mat[2] = mat[3] = mat[6] = mat[7] = mat[8] = mat[9] = mat[11] = mat[14] = 0.0; + mat[10] = mat[15] = 1.0; this._transform4x4 = mat4; - this._stackMatrix = new cc.kmMat4(); + this._stackMatrix = new cc.math.Matrix4(); this._shaderProgram = null; this._camera = null; @@ -223,15 +223,15 @@ apy = 0 | apy; } //cc.kmGLTranslatef(apx, apy, 0); - var translation = new cc.kmMat4(); - cc.kmMat4Translation(translation, apx, apy, 0); - cc.kmMat4Multiply(stackMatrix, stackMatrix, translation); + var translation = cc.math.Matrix4.createByTranslation(apx, apy, 0, t4x4); //t4x4 as a temp matrix + stackMatrix.multiply(translation); node._camera._locateForRenderer(stackMatrix); - //cc.kmGLTranslatef(-apx, -apy, 0); - cc.kmMat4Translation(translation, -apx, -apy, 0); - cc.kmMat4Multiply(stackMatrix, stackMatrix, translation); + //cc.kmGLTranslatef(-apx, -apy, 0); optimize at here : kmGLTranslatef + translation = cc.math.Matrix4.createByTranslation(apx, apy, 0, translation); + stackMatrix.multiply(translation); + t4x4.identity(); //reset t4x4; } else { node._camera._locateForRenderer(stackMatrix); } diff --git a/cocos2d/effects/CCGrid.js b/cocos2d/effects/CCGrid.js index 04719e1df9..a7276fe7c4 100644 --- a/cocos2d/effects/CCGrid.js +++ b/cocos2d/effects/CCGrid.js @@ -229,16 +229,15 @@ cc.GridBase = cc.Class.extend(/** @lends cc.GridBase# */{ // XXX: Camera should be applied in the AnchorPoint // //cc.kmGLTranslatef(offset.x, offset.y, 0); - var translation = new cc.kmMat4(); - cc.kmMat4Translation(translation, offset.x, offset.y, 0); - cc.kmMat4Multiply(stackMatrix, stackMatrix, translation); + var translation = cc.math.Matrix4.createByTranslation(offset.x, offset.y, 0); + stackMatrix.multiply(translation); //target.getCamera().locate(); target._camera._locateForRenderer(stackMatrix); //cc.kmGLTranslatef(-offset.x, -offset.y, 0); - cc.kmMat4Translation(translation, -offset.x, -offset.y, 0); - cc.kmMat4Multiply(stackMatrix, stackMatrix, translation); + translation = cc.math.Matrix4.createByTranslation(-offset.x, -offset.y, 0, translation); + stackMatrix.multiply(translation); } cc.glBindTexture2D(this._texture); @@ -265,8 +264,7 @@ cc.GridBase = cc.Class.extend(/** @lends cc.GridBase# */{ cc.kmGLMatrixMode(cc.KM_GL_PROJECTION); cc.kmGLLoadIdentity(); - var orthoMatrix = new cc.kmMat4(); - cc.kmMat4OrthographicProjection(orthoMatrix, 0, winSize.width, 0, winSize.height, -1, 1); + var orthoMatrix = cc.math.Matrix4.createOrthographicProjection(0, winSize.width, 0, winSize.height, -1, 1); cc.kmGLMultMatrix(orthoMatrix); cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW); diff --git a/cocos2d/kazmath/aabb.js b/cocos2d/kazmath/aabb.js index 8fafef6f67..8c5dc5b664 100644 --- a/cocos2d/kazmath/aabb.js +++ b/cocos2d/kazmath/aabb.js @@ -27,42 +27,52 @@ */ /** - * A struture that represents an axis-aligned - * bounding box. + * A structure that represents an axis-aligned bounding box. + * cc.kmAABB => cc.math.AABB */ -cc.kmAABB = function (min, max) { +cc.math.AABB = function (min, max) { /** The max corner of the box */ - this.min = min || new cc.kmVec3(); + this.min = min || new cc.math.Vec3(); /** The min corner of the box */ - this.max = max || new cc.kmVec3(); + this.max = max || new cc.math.Vec3(); }; /** - * Returns KM_TRUE if point is in the specified AABB, returns - * KM_FALSE otherwise. + * Returns true if point is in the specified AABB, returns false otherwise. + * @param {cc.math.Vec3} point + * @returns {boolean} */ -cc.kmAABBContainsPoint = function (pPoint, pBox) { - if (pPoint.x >= pBox.min.x && pPoint.x <= pBox.max.x && +cc.math.AABB.prototype.containsPoint = function (point) { + return (point.x >= this.min.x && point.x <= this.max.x && + point.y >= this.min.y && point.y <= this.max.y && + point.z >= this.min.z && point.z <= this.max.z); +}; + +/** + * Returns true if point is in the specified AABB, returns + * false otherwise. + */ +cc.math.AABB.containsPoint = function (pPoint, pBox) { + return (pPoint.x >= pBox.min.x && pPoint.x <= pBox.max.x && pPoint.y >= pBox.min.y && pPoint.y <= pBox.max.y && - pPoint.z >= pBox.min.z && pPoint.z <= pBox.max.z) { - return cc.KM_TRUE; - } - return cc.KM_FALSE; + pPoint.z >= pBox.min.z && pPoint.z <= pBox.max.z); }; /** - * Assigns pIn to pOut, returns pOut. + * Assigns aabb to current AABB object + * @param {cc.math.AABB} aabb */ -cc.kmAABBAssign = function (pOut, pIn) { - cc.kmVec3Assign(pOut.min, pIn.min); - cc.kmVec3Assign(pOut.max, pIn.max); - return pOut; +cc.math.AABB.prototype.assignFrom = function(aabb){ + this.min.assignFrom(aabb.min); + this.max.assignFrom(aabb.max); }; /** - * Scales pIn by s, stores the resulting AABB in pOut. Returns pOut + * Assigns pIn to pOut, returns pOut. */ -cc.kmAABBScale = function (pOut, pIn, s) { - cc.log("cc.kmAABBScale hasn't been supported."); +cc.math.AABB.assign = function (pOut, pIn) { //cc.kmAABBAssign + pOut.min.assignFrom(pIn.min); + pOut.max.assignFrom(pIn.max); + return pOut; }; diff --git a/cocos2d/kazmath/gl/mat4stack.js b/cocos2d/kazmath/gl/mat4stack.js index b87450e9c7..b11fd6b1cf 100644 --- a/cocos2d/kazmath/gl/mat4stack.js +++ b/cocos2d/kazmath/gl/mat4stack.js @@ -26,33 +26,54 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -cc.km_mat4_stack = function(capacity, item_count, top, stack){ - this.top = top ; - this.stack = stack ; -}; - -cc.km_mat4_stack.INITIAL_SIZE = 30; - -cc.km_mat4_stack_initialize = function(stack){ - stack.stack = []; //allocate the memory - stack.top = null; //Set the top to NULL -}; - -cc.km_mat4_stack_push = function(stack, item){ - stack.stack.push(stack.top); - stack.top = new cc.kmMat4(); - cc.kmMat4Assign(stack.top, item); -}; - -cc.km_mat4_stack_pop = function(stack, pOut){ - stack.top = stack.stack.pop(); -}; - -cc.km_mat4_stack_release = function(stack){ - stack.stack = null; - stack.top = null; - stack = null; -}; +(function(cc){ + /** + * The stack of cc.math.Matrix4 + * @param {cc.math.Matrix4} [top] + * @param {Array} [stack] + * @constructor + */ + cc.math.Matrix4Stack = function(top, stack) { + this.top = top; + this.stack = stack || []; + }; + cc.km_mat4_stack = cc.math.Matrix4Stack; + var proto = cc.math.Matrix4Stack.prototype; + + proto.initialize = function() { //cc.km_mat4_stack_initialize + this.stack.length = 0; + this.top = null; + }; + + //for compatibility + cc.km_mat4_stack_push = function(stack, item){ + stack.stack.push(stack.top); + stack.top = new cc.math.Matrix4(item); + }; + + cc.km_mat4_stack_pop = function(stack, pOut){ + stack.top = stack.stack.pop(); + }; + + cc.km_mat4_stack_release = function(stack){ + stack.stack = null; + stack.top = null; + }; + + proto.push = function(item) { + this.stack.push(this.top); + this.top = new cc.math.Matrix4(item); + }; + + proto.pop = function() { + this.top = this.stack.pop(); + }; + + proto.release = function(){ + this.stack = null; + this.top = null; + }; +})(cc); diff --git a/cocos2d/kazmath/gl/matrix.js b/cocos2d/kazmath/gl/matrix.js index ed579f8c0f..574bd0dd5d 100644 --- a/cocos2d/kazmath/gl/matrix.js +++ b/cocos2d/kazmath/gl/matrix.js @@ -26,144 +26,142 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -cc.KM_GL_MODELVIEW = 0x1700; +(function(cc) { + cc.KM_GL_MODELVIEW = 0x1700; + cc.KM_GL_PROJECTION = 0x1701; + cc.KM_GL_TEXTURE = 0x1702; -cc.KM_GL_PROJECTION = 0x1701; + cc.modelview_matrix_stack = new cc.math.Matrix4Stack(); + cc.projection_matrix_stack = new cc.math.Matrix4Stack(); + cc.texture_matrix_stack = new cc.math.Matrix4Stack(); -cc.KM_GL_TEXTURE = 0x1702; + cc.current_stack = null; + var initialized = false; -cc.modelview_matrix_stack = new cc.km_mat4_stack(); -cc.projection_matrix_stack = new cc.km_mat4_stack(); -cc.texture_matrix_stack = new cc.km_mat4_stack(); + cc.lazyInitialize = function () { + if (!initialized) { + var identity = new cc.math.Matrix4(); //Temporary identity matrix -cc.current_stack = null; + //Initialize all 3 stacks + cc.modelview_matrix_stack.initialized(); + cc.projection_matrix_stack.initialized(); + cc.texture_matrix_stack.initialized(); -cc.initialized = false; - -cc.lazyInitialize = function () { - if (!cc.initialized) { - var identity = new cc.kmMat4(); //Temporary identity matrix - - //Initialize all 3 stacks - cc.km_mat4_stack_initialize(cc.modelview_matrix_stack); - cc.km_mat4_stack_initialize(cc.projection_matrix_stack); - cc.km_mat4_stack_initialize(cc.texture_matrix_stack); - - cc.current_stack = cc.modelview_matrix_stack; - cc.initialized = true; - cc.kmMat4Identity(identity); - - //Make sure that each stack has the identity matrix - cc.km_mat4_stack_push(cc.modelview_matrix_stack, identity); - cc.km_mat4_stack_push(cc.projection_matrix_stack, identity); - cc.km_mat4_stack_push(cc.texture_matrix_stack, identity); - } -}; - -cc.lazyInitialize(); - -cc.kmGLFreeAll = function () { - //Clear the matrix stacks - cc.km_mat4_stack_release(cc.modelview_matrix_stack); - cc.km_mat4_stack_release(cc.projection_matrix_stack); - cc.km_mat4_stack_release(cc.texture_matrix_stack); - - //Delete the matrices - cc.initialized = false; //Set to uninitialized - cc.current_stack = null; //Set the current stack to point nowhere -}; - -cc.kmGLPushMatrix = function () { - cc.km_mat4_stack_push(cc.current_stack, cc.current_stack.top); -}; - -cc.kmGLPushMatrixWitMat4 = function (saveMat) { - cc.current_stack.stack.push(cc.current_stack.top); - cc.kmMat4Assign(saveMat, cc.current_stack.top); - cc.current_stack.top = saveMat; -}; - -cc.kmGLPopMatrix = function () { - //No need to lazy initialize, you shouldnt be popping first anyway! - //cc.km_mat4_stack_pop(cc.current_stack, null); - cc.current_stack.top = cc.current_stack.stack.pop(); -}; - -cc.kmGLMatrixMode = function (mode) { - //cc.lazyInitialize(); - switch (mode) { - case cc.KM_GL_MODELVIEW: cc.current_stack = cc.modelview_matrix_stack; - break; - case cc.KM_GL_PROJECTION: - cc.current_stack = cc.projection_matrix_stack; - break; - case cc.KM_GL_TEXTURE: - cc.current_stack = cc.texture_matrix_stack; - break; - default: - throw "Invalid matrix mode specified"; //TODO: Proper error handling - break; - } -}; - -cc.kmGLLoadIdentity = function () { - //cc.lazyInitialize(); - cc.kmMat4Identity(cc.current_stack.top); //Replace the top matrix with the identity matrix -}; - -cc.kmGLLoadMatrix = function (pIn) { - //cc.lazyInitialize(); - cc.kmMat4Assign(cc.current_stack.top, pIn); -}; - -cc.kmGLMultMatrix = function (pIn) { - //cc.lazyInitialize(); - cc.kmMat4Multiply(cc.current_stack.top, cc.current_stack.top, pIn); -}; - -cc.kmGLTranslatef = function (x, y, z) { - var translation = new cc.kmMat4(); - - //Create a rotation matrix using the axis and the angle - cc.kmMat4Translation(translation, x, y, z); - - //Multiply the rotation matrix by the current matrix - cc.kmMat4Multiply(cc.current_stack.top, cc.current_stack.top, translation); -}; - -cc.kmGLRotatef = function (angle, x, y, z) { - var axis = new cc.kmVec3(x, y, z); - var rotation = new cc.kmMat4(); - - //Create a rotation matrix using the axis and the angle - cc.kmMat4RotationAxisAngle(rotation, axis, cc.kmDegreesToRadians(angle)); - - //Multiply the rotation matrix by the current matrix - cc.kmMat4Multiply(cc.current_stack.top, cc.current_stack.top, rotation); -}; - -cc.kmGLScalef = function (x, y, z) { - var scaling = new cc.kmMat4(); - cc.kmMat4Scaling(scaling, x, y, z); - cc.kmMat4Multiply(cc.current_stack.top, cc.current_stack.top, scaling); -}; - -cc.kmGLGetMatrix = function (mode, pOut) { - //cc.lazyInitialize(); - - switch (mode) { - case cc.KM_GL_MODELVIEW: - cc.kmMat4Assign(pOut, cc.modelview_matrix_stack.top); - break; - case cc.KM_GL_PROJECTION: - cc.kmMat4Assign(pOut, cc.projection_matrix_stack.top); - break; - case cc.KM_GL_TEXTURE: - cc.kmMat4Assign(pOut, cc.texture_matrix_stack.top); - break; - default: - throw "Invalid matrix mode specified"; //TODO: Proper error handling - break; - } -}; + cc.initialized = true; + identity.identity(); + + //Make sure that each stack has the identity matrix + cc.modelview_matrix_stack.push(identity); + cc.projection_matrix_stack.push(identity); + cc.texture_matrix_stack.push(identity); + } + }; + + cc.lazyInitialize(); + + cc.kmGLFreeAll = function () { + //Clear the matrix stacks + cc.modelview_matrix_stack.release(); + cc.modelview_matrix_stack = null; + cc.projection_matrix_stack.release(); + cc.projection_matrix_stack = null; + cc.texture_matrix_stack.release(); + cc.texture_matrix_stack = null; + + //Delete the matrices + cc.initialized = false; //Set to uninitialized + cc.current_stack = null; //Set the current stack to point nowhere + }; + + cc.kmGLPushMatrix = function () { + cc.current_stack.push(cc.current_stack.top); + }; + + cc.kmGLPushMatrixWitMat4 = function (saveMat) { + cc.current_stack.stack.push(cc.current_stack.top); + saveMat.assignFrom(cc.current_stack.top); + cc.current_stack.top = saveMat; + }; + + cc.kmGLPopMatrix = function () { + //No need to lazy initialize, you shouldnt be popping first anyway! + //cc.km_mat4_stack_pop(cc.current_stack, null); + cc.current_stack.top = cc.current_stack.stack.pop(); + }; + + cc.kmGLMatrixMode = function (mode) { + //cc.lazyInitialize(); + switch (mode) { + case cc.KM_GL_MODELVIEW: + cc.current_stack = cc.modelview_matrix_stack; + break; + case cc.KM_GL_PROJECTION: + cc.current_stack = cc.projection_matrix_stack; + break; + case cc.KM_GL_TEXTURE: + cc.current_stack = cc.texture_matrix_stack; + break; + default: + throw "Invalid matrix mode specified"; //TODO: Proper error handling + break; + } + }; + + cc.kmGLLoadIdentity = function () { + //cc.lazyInitialize(); + cc.current_stack.top.identity(); //Replace the top matrix with the identity matrix + }; + + cc.kmGLLoadMatrix = function (pIn) { + //cc.lazyInitialize(); + cc.current_stack.top.assignFrom(pIn); + }; + + cc.kmGLMultMatrix = function (pIn) { + //cc.lazyInitialize(); + cc.current_stack.top.multiply(pIn); + }; + + var tempMatrix = new cc.math.Matrix4(); //an internal matrix + cc.kmGLTranslatef = function (x, y, z) { + //Create a rotation matrix using translation + var translation = cc.math.Matrix4.createByTranslation(x, y, z, tempMatrix); + + //Multiply the rotation matrix by the current matrix + cc.current_stack.top.multiply(translation); + }; + + var tempVector3 = new cc.math.Vec3(x, y, z); + cc.kmGLRotatef = function (angle, x, y, z) { + tempVector3.fill(x, y, z); + //Create a rotation matrix using the axis and the angle + var rotation = cc.math.Matrix4.createByAxisAndAngle(tempVector3, cc.degreesToRadians(angle), tempMatrix); + + //Multiply the rotation matrix by the current matrix + cc.current_stack.top.multiply(rotation); + }; + + cc.kmGLScalef = function (x, y, z) { + var scaling = cc.math.Matrix4.createByScale(x, y, z, tempMatrix); + cc.current_stack.top.multiply(scaling); + }; + + cc.kmGLGetMatrix = function (mode, pOut) { + //cc.lazyInitialize(); + switch (mode) { + case cc.KM_GL_MODELVIEW: + pOut.assignFrom(cc.modelview_matrix_stack.top); + break; + case cc.KM_GL_PROJECTION: + pOut.assignFrom(cc.projection_matrix_stack.top); + break; + case cc.KM_GL_TEXTURE: + pOut.assignFrom(cc.texture_matrix_stack.top); + break; + default: + throw "Invalid matrix mode specified"; //TODO: Proper error handling + break; + } + }; +})(cc); diff --git a/cocos2d/kazmath/mat3.js b/cocos2d/kazmath/mat3.js index fea8559630..737bc9b77f 100644 --- a/cocos2d/kazmath/mat3.js +++ b/cocos2d/kazmath/mat3.js @@ -27,301 +27,317 @@ */ var Float32Array = Float32Array || Array; - -cc.kmMat3 = function () { - this.mat = new Float32Array([0, 0, 0, - 0, 0, 0, - 0, 0, 0]); -}; - -cc.kmMat3Fill = function (pOut, pMat) { - for (var i = 0; i < 9; i++) { - pOut.mat[i] = pMat; - } - return pOut; -}; - -cc.kmMat3Adjugate = function (pOut, pIn) { - pOut.mat[0] = pIn.mat[4] * pIn.mat[8] - pIn.mat[5] * pIn.mat[7]; - pOut.mat[1] = pIn.mat[2] * pIn.mat[7] - pIn.mat[1] * pIn.mat[8]; - pOut.mat[2] = pIn.mat[1] * pIn.mat[5] - pIn.mat[2] * pIn.mat[4]; - pOut.mat[3] = pIn.mat[5] * pIn.mat[6] - pIn.mat[3] * pIn.mat[8]; - pOut.mat[4] = pIn.mat[0] * pIn.mat[8] - pIn.mat[2] * pIn.mat[6]; - pOut.mat[5] = pIn.mat[2] * pIn.mat[3] - pIn.mat[0] * pIn.mat[5]; - pOut.mat[6] = pIn.mat[3] * pIn.mat[7] - pIn.mat[4] * pIn.mat[6]; - - // XXX: pIn.mat[9] is invalid! -// pOut.mat[7] = pIn.mat[1] * pIn.mat[6] - pIn.mat[9] * pIn.mat[7]; - pOut.mat[8] = pIn.mat[0] * pIn.mat[4] - pIn.mat[1] * pIn.mat[3]; - - return pOut; -}; - -cc.kmMat3Identity = function (pOut) { - pOut.mat[1] = pOut.mat[2] = pOut.mat[3] = - pOut.mat[5] = pOut.mat[6] = pOut.mat[7] = 0; - pOut.mat[0] = pOut.mat[4] = pOut.mat[8] = 1.0; - return pOut; -}; - -cc.kmMat3Inverse = function (pOut, pDeterminate, pM) { - var detInv; - var adjugate = new cc.kmMat3(); - - if (pDeterminate === 0.0) - return null; - - detInv = 1.0 / pDeterminate; - - cc.kmMat3Adjugate(adjugate, pM); - cc.kmMat3ScalarMultiply(pOut, adjugate, detInv); - - return pOut; -}; - -cc.kmMat3._identity = - new Float32Array([1.0, 0.0, 0.0, - 0.0, 1.0, 0.0, - 0.0, 0.0, 1.0]); - -cc.kmMat3IsIdentity = function (pIn) { - for (var i = 0; i < 9; i++) { - if (cc.kmMat3._identity[i] !== pIn.mat[i]) - return false; - } - return true; -}; - -cc.kmMat3Transpose = function (pOut, pIn) { - var z, x; - for (z = 0; z < 3; ++z) { - for (x = 0; x < 3; ++x) - pOut.mat[(z * 3) + x] = pIn.mat[(x * 3) + z]; - } - - return pOut; -}; - -cc.kmMat3Determinant = function (pIn) { - var output; - /* - calculating the determinant following the rule of sarus, - | 0 3 6 | 0 3 | - m = | 1 4 7 | 1 4 | - | 2 5 8 | 2 5 | - now sum up the products of the diagonals going to the right (i.e. 0,4,8) - and substract the products of the other diagonals (i.e. 2,4,6) - */ - - output = pIn.mat[0] * pIn.mat[4] * pIn.mat[8] + pIn.mat[1] * pIn.mat[5] * pIn.mat[6] + pIn.mat[2] * pIn.mat[3] * pIn.mat[7]; - output -= pIn.mat[2] * pIn.mat[4] * pIn.mat[6] + pIn.mat[0] * pIn.mat[5] * pIn.mat[7] + pIn.mat[1] * pIn.mat[3] * pIn.mat[8]; - - return output; -}; - -cc.kmMat3Multiply = function (pOut, pM1, pM2) { - var m1 = pM1.mat, m2 = pM2.mat; - - pOut.mat[0] = m1[0] * m2[0] + m1[3] * m2[1] + m1[6] * m2[2]; - pOut.mat[1] = m1[1] * m2[0] + m1[4] * m2[1] + m1[7] * m2[2]; - pOut.mat[2] = m1[2] * m2[0] + m1[5] * m2[1] + m1[8] * m2[2]; - - pOut.mat[3] = m1[0] * m2[3] + m1[3] * m2[4] + m1[6] * m2[5]; - pOut.mat[4] = m1[1] * m2[3] + m1[4] * m2[4] + m1[7] * m2[5]; - pOut.mat[5] = m1[2] * m2[3] + m1[5] * m2[4] + m1[8] * m2[5]; - - pOut.mat[6] = m1[0] * m2[6] + m1[3] * m2[7] + m1[6] * m2[8]; - pOut.mat[7] = m1[1] * m2[6] + m1[4] * m2[7] + m1[7] * m2[8]; - pOut.mat[8] = m1[2] * m2[6] + m1[5] * m2[7] + m1[8] * m2[8]; - - return pOut; -}; - -cc.kmMat3ScalarMultiply = function (pOut, pM, pFactor) { - for (var i = 0; i < 9; i++) { - pOut.mat[i] = pM.mat[i] * pFactor; - } - return pOut; -}; - -cc.kmMat3RotationAxisAngle = function (pOut, axis, radians) { - var rcos = Math.cos(radians); - var rsin = Math.sin(radians); - - pOut.mat[0] = rcos + axis.x * axis.x * (1 - rcos); - pOut.mat[1] = axis.z * rsin + axis.y * axis.x * (1 - rcos); - pOut.mat[2] = -axis.y * rsin + axis.z * axis.x * (1 - rcos); - - pOut.mat[3] = -axis.z * rsin + axis.x * axis.y * (1 - rcos); - pOut.mat[4] = rcos + axis.y * axis.y * (1 - rcos); - pOut.mat[5] = axis.x * rsin + axis.z * axis.y * (1 - rcos); - - pOut.mat[6] = axis.y * rsin + axis.x * axis.z * (1 - rcos); - pOut.mat[7] = -axis.x * rsin + axis.y * axis.z * (1 - rcos); - pOut.mat[8] = rcos + axis.z * axis.z * (1 - rcos); - - return pOut; -}; - -cc.kmMat3Assign = function (pOut, pIn) { - if(pOut == pIn) { - cc.log("cc.kmMat3Assign(): pOut equals pIn"); - return pOut; - } - - for (var i = 0; i < 9; i++) - pOut.mat[i] = pIn.mat[i]; - return pOut; -}; - -cc.kmMat3AreEqual = function (pMat1, pMat2) { - if (pMat1 == pMat2) - return true; - - for (var i = 0; i < 9; ++i) { - if (!(pMat1.mat[i] + cc.kmEpsilon > pMat2.mat[i] && - pMat1.mat[i] - cc.kmEpsilon < pMat2.mat[i])) { - return false; +(function(cc){ + cc.math.Matrix3 = function(mat3) { + if (mat3) { + this.mat = new Float32Array(mat3); + } else { + this.mat = new Float32Array([0, 0, 0, + 0, 0, 0, + 0, 0, 0]); + } + }; + cc.kmMat3 = cc.math.Matrix3; + var proto = cc.math.Matrix3.prototype; + + proto.fill = function(mat3) { //cc.kmMat3Fill + var mat = this.mat, matIn = mat3.mat; + mat[0] = matIn[0]; + mat[1] = matIn[1]; + mat[2] = matIn[2]; + mat[3] = matIn[3]; + mat[4] = matIn[4]; + mat[5] = matIn[5]; + mat[6] = matIn[6]; + mat[7] = matIn[7]; + mat[8] = matIn[8]; + return this; + }; + + proto.adjugate = function(){ //= cc.kmMat3Adjugate + var mat = this.mat; + var m0 = mat[0], m1 = mat[1], m2 = mat[2], m3 = mat[3], m4 = mat[4], + m5 = mat[5], m6 = mat[6], m7 = mat[7], m8 = mat[8]; + mat[0] = m4 * m8 - m5 * m7; + mat[1] = m2 * m7 - m1 * m8; + mat[2] = m1 * m5 - m2 * m4; + mat[3] = m5 * m6 - m3 * m8; + mat[4] = m0 * m8 - m2 * m6; + mat[5] = m2 * m3 - m0 * m5; + mat[6] = m3 * m7 - m4 * m6; + + // XXX: pIn.mat[9] is invalid! + //mat[7] = m1 * m6 - pIn.mat[9] * m7; + mat[8] = m0 * m4 - m1 * m3; + return this; + }; + + proto.identity = function() { //cc.kmMat3Identity + var mat = this.mat; + mat[1] = mat[2] = mat[3] = + mat[5] = mat[6] = mat[7] = 0; + mat[0] = mat[4] = mat[8] = 1.0; + return this; + }; + + var tmpMatrix = new cc.math.Matrix3(); // internal matrix + + proto.inverse = function(determinate){ //cc.kmMat3Inverse + if (determinate === 0.0) + return this; + tmpMatrix.assignFrom(this); + var detInv = 1.0 / determinate; + this.adjugate(); + this.multiplyScalar(detInv); + return this; + }; + + proto.isIdentity = function(){ //= cc.kmMat3IsIdentity + var mat = this.mat; + return (mat[0] === 1 && mat[1] === 0 && mat[2] === 0 + && mat[3] === 0 && mat[4] === 1 && mat[5] === 0 + && mat[6] === 0 && mat[7] === 0 && mat[8] === 1); + }; + + proto.transpose = function(){ // cc.kmMat3Transpose + var mat = this.mat; + var m1 = mat[1], m2 = mat[2], m3 = mat[3], m5 = mat[5], + m6 = mat[6], m7 = mat[7]; + // m0 = mat[0],m8 = mat[8], m4 = mat[4]; + //mat[0] = m0; + //mat[8] = m8; + //mat[4] = m4 + mat[1] = m3; + mat[2] = m6; + mat[3] = m1; + mat[5] = m7; + mat[6] = m2; + mat[7] = m5; + return this; + }; + + proto.determinant = function(){ + var mat = this.mat; + /* + calculating the determinant following the rule of sarus, + | 0 3 6 | 0 3 | + m = | 1 4 7 | 1 4 | + | 2 5 8 | 2 5 | + now sum up the products of the diagonals going to the right (i.e. 0,4,8) + and substract the products of the other diagonals (i.e. 2,4,6) + */ + var output = mat[0] * mat[4] * mat[8] + mat[1] * mat[5] * mat[6] + mat[2] * mat[3] * mat[7]; + output -= mat[2] * mat[4] * mat[6] + mat[0] * mat[5] * mat[7] + mat[1] * mat[3] * mat[8]; + return output; + }; + + proto.multiply = function(mat3){ + var m1 = this.mat, m2 = mat3.mat; + var a0 = m1[0], a1 = m1[1], a2 = m1[2], a3 = m1[3], a4 = m1[4], a5 = m1[5], + a6 = m1[6], a7 = m1[7], a8 = m1[8]; + var b0 = m2[0], b1 = m2[1], b2 = m2[2], b3 = m2[3], b4 = m2[4], b5 = m2[5], + b6 = m2[6], b7 = m2[7], b8 = m2[8]; + + m1[0] = a0 * b0 + a3 * b1 + a6 * b2; + m1[1] = a1 * b0 + a4 * b1 + a7 * b2; + m1[2] = a2 * b0 + a5 * b1 + a8 * b2; + + m1[3] = a2 * b0 + a5 * b1 + a8 * b2; + m1[4] = a1 * b3 + a4 * b4 + a7 * b5; + m1[5] = a2 * b3 + a5 * b4 + a8 * b5; + + m1[6] = a0 * b6 + a3 * b7 + a6 * b8; + m1[7] = a1 * b6 + a4 * b7 + a7 * b8; + m1[8] = a2 * b6 + a5 * b7 + a8 * b8; + return this; + }; + + proto.multiplyScalar = function(factor) { + var mat = this.mat; + mat[0] *= factor; + mat[1] *= factor; + mat[2] *= factor; + mat[3] *= factor; + mat[4] *= factor; + mat[5] *= factor; + mat[6] *= factor; + mat[7] *= factor; + mat[8] *= factor; + return this; + }; + + cc.math.Matrix3.rotationAxisAngle = function(axis, radians) { //cc.kmMat3RotationAxisAngle + var rcos = Math.cos(radians), rsin = Math.sin(radians); + var retMat = new cc.math.Matrix3(); + var mat = retMat.mat; + + mat[0] = rcos + axis.x * axis.x * (1 - rcos); + mat[1] = axis.z * rsin + axis.y * axis.x * (1 - rcos); + mat[2] = -axis.y * rsin + axis.z * axis.x * (1 - rcos); + + mat[3] = -axis.z * rsin + axis.x * axis.y * (1 - rcos); + mat[4] = rcos + axis.y * axis.y * (1 - rcos); + mat[5] = axis.x * rsin + axis.z * axis.y * (1 - rcos); + + mat[6] = axis.y * rsin + axis.x * axis.z * (1 - rcos); + mat[7] = -axis.x * rsin + axis.y * axis.z * (1 - rcos); + mat[8] = rcos + axis.z * axis.z * (1 - rcos); + + return retMat; + }; + + proto.assignFrom = function(matIn){ // cc.kmMat3Assign + if(this === matIn) { + cc.log("cc.math.Matrix3.assign(): current matrix equals matIn"); + return this; } + var mat = this.mat, m2 = matIn.mat; + mat[0] = m2[0]; + mat[1] = m2[1]; + mat[2] = m2[2]; + mat[3] = m2[3]; + mat[4] = m2[4]; + mat[5] = m2[5]; + mat[6] = m2[6]; + mat[7] = m2[7]; + mat[8] = m2[8]; + return this; + }; + + proto.equals = function(mat3) { + if (this === mat3) + return true; + var EPSILON = cc.math.EPSILON,m1 = this.mat, m2 = mat3.mat; + for (var i = 0; i < 9; ++i) { + if (!(m1[i] + EPSILON > m2[i] && m1[i] - EPSILON < m2[i])) + return false; + } + return true; + }; + + cc.math.Matrix3.createByRotationX = function(radians) { + var retMat = new cc.math.Matrix3(), mat = retMat.mat; + mat[0] = 1.0; + mat[1] = 0.0; + mat[2] = 0.0; + + mat[3] = 0.0; + mat[4] = Math.cos(radians); + mat[5] = Math.sin(radians); + + mat[6] = 0.0; + mat[7] = -Math.sin(radians); + mat[8] = Math.cos(radians); + return retMat; + }; + + cc.math.Matrix3.createByRotationY = function(radians) { + /* + | cos(A) 0 sin(A) | + M = | 0 1 0 | + | -sin(A) 0 cos(A) | + */ + var retMat = new cc.math.Matrix3(), mat = retMat.mat; + mat[0] = Math.cos(radians); + mat[1] = 0.0; + mat[2] = -Math.sin(radians); + + mat[3] = 0.0; + mat[4] = 1.0; + mat[5] = 0.0; + + mat[6] = Math.sin(radians); + mat[7] = 0.0; + mat[8] = Math.cos(radians); + return retMat; + }; + + cc.math.Matrix3.createByRotationZ = function(radians) { + /* + | cos(A) -sin(A) 0 | + M = | sin(A) cos(A) 0 | + | 0 0 1 | + */ + var retMat = new cc.math.Matrix3(), mat = retMat.mat; + mat[0] = Math.cos(radians); + mat[1] = -Math.sin(radians); + mat[2] = 0.0; + + mat[3] = Math.sin(radians); + mat[4] = Math.cos(radians); + mat[5] = 0.0; + + mat[6] = 0.0; + mat[7] = 0.0; + mat[8] = 1.0; + return retMat; + }; + + cc.math.Matrix3.createByRotation = function(radians) { + /* + | cos(A) -sin(A) 0 | + M = | sin(A) cos(A) 0 | + | 0 0 1 | + */ + var retMat = new cc.math.Matrix3(), mat = retMat.mat; + mat[0] = Math.cos(radians); + mat[1] = Math.sin(radians); + mat[2] = 0.0; + + mat[3] = -Math.sin(radians); + mat[4] = Math.cos(radians); + mat[5] = 0.0; + + mat[6] = 0.0; + mat[7] = 0.0; + mat[8] = 1.0; + return retMat; + }; + + cc.math.Matrix3.createByScale = function(x, y) { + var ret = new cc.math.Matrix3(); + ret.identity(); + ret.mat[0] = x; + ret.mat[4] = y; + return ret; + }; + + cc.math.Matrix3.createByTranslation = function(x, y){ + var ret = new cc.math.Matrix3(); + ret.identity(); + ret.mat[6] = x; + ret.mat[7] = y; + return ret; + }; + + cc.math.Matrix3.createByQuaternion = function(quaternion) { //cc.kmMat3RotationQuaternion + if(!quaternion) + return null; + + var ret = new cc.math.Matrix3(), mat = ret.mat; + // First row + mat[0] = 1.0 - 2.0 * (quaternion.y * quaternion.y + quaternion.z * quaternion.z); + mat[1] = 2.0 * (quaternion.x * quaternion.y - quaternion.w * quaternion.z); + mat[2] = 2.0 * (quaternion.x * quaternion.z + quaternion.w * quaternion.y); + + // Second row + mat[3] = 2.0 * (quaternion.x * quaternion.y + quaternion.w * quaternion.z); + mat[4] = 1.0 - 2.0 * (quaternion.x * quaternion.x + quaternion.z * quaternion.z); + mat[5] = 2.0 * (quaternion.y * quaternion.z - quaternion.w * quaternion.x); + + // Third row + mat[6] = 2.0 * (quaternion.x * quaternion.z - quaternion.w * quaternion.y); + mat[7] = 2.0 * (quaternion.y * quaternion.z + quaternion.w * quaternion.x); + mat[8] = 1.0 - 2.0 * (quaternion.x * quaternion.x + quaternion.y * quaternion.y); + return ret; + }; + + proto.rotationToAxisAngle = function() { //cc.kmMat3RotationToAxisAngle + return cc.math.Quaternion.rotationMatrix(this).toAxisAndAngle(); } +})(cc); + - return true; -}; - -cc.kmMat3RotationX = function (pOut, radians) { - /* - | 1 0 0 | - M = | 0 cos(A) -sin(A) | - | 0 sin(A) cos(A) | - - */ - - pOut.mat[0] = 1.0; - pOut.mat[1] = 0.0; - pOut.mat[2] = 0.0; - - pOut.mat[3] = 0.0; - pOut.mat[4] = Math.cos(radians); - pOut.mat[5] = Math.sin(radians); - - pOut.mat[6] = 0.0; - pOut.mat[7] = -Math.sin(radians); - pOut.mat[8] = Math.cos(radians); - - return pOut; -}; - -cc.kmMat3RotationY = function (pOut, radians) { - /* - | cos(A) 0 sin(A) | - M = | 0 1 0 | - | -sin(A) 0 cos(A) | - */ - - pOut.mat[0] = Math.cos(radians); - pOut.mat[1] = 0.0; - pOut.mat[2] = -Math.sin(radians); - - pOut.mat[3] = 0.0; - pOut.mat[4] = 1.0; - pOut.mat[5] = 0.0; - - pOut.mat[6] = Math.sin(radians); - pOut.mat[7] = 0.0; - pOut.mat[8] = Math.cos(radians); - - return pOut; -}; - -cc.kmMat3RotationZ = function (pOut, radians) { - /* - | cos(A) -sin(A) 0 | - M = | sin(A) cos(A) 0 | - | 0 0 1 | - */ - pOut.mat[0] = Math.cos(radians); - pOut.mat[1] = -Math.sin(radians); - pOut.mat[2] = 0.0; - - pOut.mat[3] = Math.sin(radians); - pOut.mat[4] = Math.cos(radians); - pOut.mat[5] = 0.0; - - pOut.mat[6] = 0.0; - pOut.mat[7] = 0.0; - pOut.mat[8] = 1.0; - - return pOut; -}; - -cc.kmMat3Rotation = function (pOut, radians) { - /* - | cos(A) -sin(A) 0 | - M = | sin(A) cos(A) 0 | - | 0 0 1 | - */ - pOut.mat[0] = Math.cos(radians); - pOut.mat[1] = Math.sin(radians); - pOut.mat[2] = 0.0; - - pOut.mat[3] = -Math.sin(radians); - pOut.mat[4] = Math.cos(radians); - pOut.mat[5] = 0.0; - - pOut.mat[6] = 0.0; - pOut.mat[7] = 0.0; - pOut.mat[8] = 1.0; - return pOut; -}; - -cc.kmMat3Scaling = function (pOut, x, y) { -// memset(pOut.mat, 0, sizeof(float) * 9); - cc.kmMat3Identity(pOut); - pOut.mat[0] = x; - pOut.mat[4] = y; - - return pOut; -}; - -cc.kmMat3Translation = function (pOut, x, y) { -// memset(pOut.mat, 0, sizeof(float) * 9); - cc.kmMat3Identity(pOut); - pOut.mat[6] = x; - pOut.mat[7] = y; -// pOut.mat[8] = 1.0; - - return pOut; -}; - -cc.kmMat3RotationQuaternion = function (pOut, pIn) { - if (!pIn || !pOut) - return null; - - // First row - pOut.mat[0] = 1.0 - 2.0 * (pIn.y * pIn.y + pIn.z * pIn.z); - pOut.mat[1] = 2.0 * (pIn.x * pIn.y - pIn.w * pIn.z); - pOut.mat[2] = 2.0 * (pIn.x * pIn.z + pIn.w * pIn.y); - - // Second row - pOut.mat[3] = 2.0 * (pIn.x * pIn.y + pIn.w * pIn.z); - pOut.mat[4] = 1.0 - 2.0 * (pIn.x * pIn.x + pIn.z * pIn.z); - pOut.mat[5] = 2.0 * (pIn.y * pIn.z - pIn.w * pIn.x); - - // Third row - pOut.mat[6] = 2.0 * (pIn.x * pIn.z - pIn.w * pIn.y); - pOut.mat[7] = 2.0 * (pIn.y * pIn.z + pIn.w * pIn.x); - pOut.mat[8] = 1.0 - 2.0 * (pIn.x * pIn.x + pIn.y * pIn.y); - - return pOut; -}; - -cc.kmMat3RotationToAxisAngle = function (pAxis, radians, pIn) { - /*Surely not this easy?*/ - var temp; - cc.kmQuaternionRotationMatrix(temp, pIn); - cc.kmQuaternionToAxisAngle(temp, pAxis, radians); - return pAxis; -}; diff --git a/cocos2d/kazmath/mat4.js b/cocos2d/kazmath/mat4.js index 9c62be7284..45b9a1d59b 100644 --- a/cocos2d/kazmath/mat4.js +++ b/cocos2d/kazmath/mat4.js @@ -26,784 +26,989 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/** - *

- A 4x4 matrix
-
- mat =
- | 0 4 8 12 |
- | 1 5 9 13 |
- | 2 6 10 14 |
- | 3 7 11 15 | -

- */ -cc.kmMat4 = function () { - this.mat = new Float32Array([0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0]); -}; +(function(cc) { + /** + *

+ * A 4x4 matrix
+ *
+ * mat =
+ * | 0 4 8 12 |
+ * | 1 5 9 13 |
+ * | 2 6 10 14 |
+ * | 3 7 11 15 | + *

+ * @param {cc.math.Matrix4} [mat4] + */ + cc.math.Matrix4 = function (mat4) { + if(mat4){ + this.mat = new Float32Array(mat4.mat); + } else { + this.mat = new Float32Array([0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0]); + } + }; + cc.kmMat4 = cc.math.Matrix4; + var proto = cc.math.Matrix4.prototype; -/** - * Fills a kmMat4 structure with the values from a 16 element array of floats - * @Params pOut - A pointer to the destination matrix - * @Params pMat - A 16 element array of floats - * @Return Returns pOut so that the call can be nested - */ -cc.kmMat4Fill = function (pOut, pMat) { - pOut.mat[0] = pOut.mat[1] = pOut.mat[2] =pOut.mat[3] = - pOut.mat[4] =pOut.mat[5] =pOut.mat[6] =pOut.mat[7] = - pOut.mat[8] =pOut.mat[9] =pOut.mat[10] =pOut.mat[11] = - pOut.mat[12] =pOut.mat[13] =pOut.mat[14] =pOut.mat[15] =pMat; -}; + /** + * Fills a cc.math.Matrix4 structure with the values from a 16 element array of floats + * @param {Array} scalarArr + */ + proto.fill = function(scalarArr){ //cc.kmMat4Fill + var mat = this.mat; + for(var i = 0; i < 16; i++){ + mat[i] = scalarArr[i]; + } + return this; + }; -/** - * Sets pOut to an identity matrix returns pOut - * @Params pOut - A pointer to the matrix to set to identity - * @Return Returns pOut so that the call can be nested - */ -cc.kmMat4Identity = function (pOut) { - pOut.mat[1] = pOut.mat[2] = pOut.mat[3] - = pOut.mat[4] = pOut.mat[6] = pOut.mat[7] - = pOut.mat[8] = pOut.mat[9] = pOut.mat[11] - = pOut.mat[12] = pOut.mat[13] = pOut.mat[14] = 0; - pOut.mat[0] = pOut.mat[5] = pOut.mat[10] = pOut.mat[15] = 1.0; - return pOut; -}; - -cc.kmMat4._get = function (pIn, row, col) { - return pIn.mat[row + 4 * col]; -}; - -cc.kmMat4._set = function (pIn, row, col, value) { - pIn.mat[row + 4 * col] = value; -}; - -cc.kmMat4._swap = function (pIn, r1, c1, r2, c2) { - var tmp = cc.kmMat4._get(pIn, r1, c1); - cc.kmMat4._set(pIn, r1, c1, cc.kmMat4._get(pIn, r2, c2)); - cc.kmMat4._set(pIn, r2, c2, tmp); -}; - -//Returns an upper and a lower triangular matrix which are L and R in the Gauss algorithm -cc.kmMat4._gaussj = function (a, b) { - var i, icol = 0, irow = 0, j, k, l, ll, n = 4, m = 4; - var big, dum, pivinv; - var indxc = [0, 0, 0, 0]; - var indxr = [0, 0, 0, 0]; - var ipiv = [0, 0, 0, 0]; - - /* for (j = 0; j < n; j++) { - ipiv[j] = 0; - }*/ - - for (i = 0; i < n; i++) { - big = 0.0; - for (j = 0; j < n; j++) { - if (ipiv[j] != 1) { - for (k = 0; k < n; k++) { - if (ipiv[k] == 0) { - if (Math.abs(cc.kmMat4._get(a, j, k)) >= big) { - big = Math.abs(cc.kmMat4._get(a, j, k)); - irow = j; - icol = k; + /** + * Sets pOut to an identity matrix returns pOut + * @Params pOut - A pointer to the matrix to set to identity + * @Return Returns pOut so that the call can be nested + */ + cc.kmMat4Identity = function (pOut) { + var mat = pOut.mat; + mat[1] = mat[2] = mat[3] = mat[4] = mat[6] = mat[7] + = mat[8] = mat[9] = mat[11] = mat[12] = mat[13] = mat[14] = 0; + mat[0] = mat[5] = mat[10] = mat[15] = 1.0; + return pOut; + }; + + /** + * Sets matrix to identity value. + * @returns {cc.math.Matrix4} + */ + proto.identity = function(){ + var mat = this.mat; + mat[1] = mat[2] = mat[3] = mat[4] = mat[6] = mat[7] + = mat[8] = mat[9] = mat[11] = mat[12] = mat[13] = mat[14] = 0; + mat[0] = mat[5] = mat[10] = mat[15] = 1.0; + return this; + }; + + proto.get = function(row, col){ + return this.mat[row + 4 * col]; + }; + + proto.set = function(row, col, value){ + this.mat[row + 4 * col] = value; + }; + + proto.swap = function(r1, c1, r2, c2) { +/* var tmp = this.get(r1, c1); + this.set(r1, c1, this.get(r2, c2)); + this.set(r2, c2, tmp);*/ + var mat = this.mat, tmp = mat[r1 + 4 * c1]; + mat[r1 + 4 * c1] = mat[r2 + 4 * c2]; + mat[r2 + 4 * c2] = tmp; + }; + + //Returns an upper and a lower triangular matrix which are L and R in the Gauss algorithm + cc.math.Matrix4._gaussj = function (a, b) { + var i, icol = 0, irow = 0, j, k, l, ll, n = 4, m = 4, selElement; + var big, dum, pivinv; + var indxc = [0, 0, 0, 0], indxr = [0, 0, 0, 0], ipiv = [0, 0, 0, 0]; + + /* for (j = 0; j < n; j++) { + ipiv[j] = 0; + }*/ + + for (i = 0; i < n; i++) { + big = 0.0; + for (j = 0; j < n; j++) { + if (ipiv[j] !== 1) { + for (k = 0; k < n; k++) { + if (ipiv[k] === 0) { + selElement = Math.abs(a.get(j, k)); + if (selElement >= big) { + big = selElement; + irow = j; + icol = k; + } } } } } - } - ++(ipiv[icol]); - if (irow != icol) { - for (l = 0; l < n; l++) - cc.kmMat4._swap(a, irow, l, icol, l); - for (l = 0; l < m; l++) - cc.kmMat4._swap(b, irow, l, icol, l); - } - indxr[i] = irow; - indxc[i] = icol; - if (cc.kmMat4._get(a, icol, icol) == 0.0) - return cc.KM_FALSE; - - pivinv = 1.0 / cc.kmMat4._get(a, icol, icol); - cc.kmMat4._set(a, icol, icol, 1.0); - for (l = 0; l < n; l++) - cc.kmMat4._set(a, icol, l, cc.kmMat4._get(a, icol, l) * pivinv); - - for (l = 0; l < m; l++) - cc.kmMat4._set(b, icol, l, cc.kmMat4._get(b, icol, l) * pivinv); - - for (ll = 0; ll < n; ll++) { - if (ll != icol) { - dum = cc.kmMat4._get(a, ll, icol); - cc.kmMat4._set(a, ll, icol, 0.0); + ++(ipiv[icol]); + if (irow != icol) { for (l = 0; l < n; l++) - cc.kmMat4._set(a, ll, l, cc.kmMat4._get(a, ll, l) - cc.kmMat4._get(a, icol, l) * dum); - + a.swap(irow, l, icol, l); for (l = 0; l < m; l++) - cc.kmMat4._set(b, ll, l, cc.kmMat4._get(a, ll, l) - cc.kmMat4._get(b, icol, l) * dum); + b.swap(irow, l, icol, l); } - } - } -// This is the end of the main loop over columns of the reduction. It only remains to unscram- -// ble the solution in view of the column interchanges. We do this by interchanging pairs of -// columns in the reverse order that the permutation was built up. - for (l = n - 1; l >= 0; l--) { - if (indxr[l] != indxc[l]) { - for (k = 0; k < n; k++) - cc.kmMat4._swap(a, k, indxr[l], k, indxc[l]); - } - } - return cc.KM_TRUE; -}; - -cc.kmMat4._identity = - new Float32Array([1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0]); - -/** - * Calculates the inverse of pM and stores the result in - * pOut. - * @Return Returns NULL if there is no inverse, else pOut - */ -cc.kmMat4Inverse = function (pOut, pM) { - var inv = new cc.kmMat4(); - var tmp = new cc.kmMat4(); + indxr[i] = irow; + indxc[i] = icol; + if (a.get(icol, icol) === 0.0) + return false; - cc.kmMat4Assign(inv, pM); - cc.kmMat4Identity(tmp); - - if (cc.kmMat4._gaussj(inv, tmp) == cc.KM_FALSE) - return null; + pivinv = 1.0 / a.get(icol, icol); + a.set(icol, icol, 1.0); + for (l = 0; l < n; l++) + a.set(icol, l, a.get(icol, l) * pivinv); - cc.kmMat4Assign(pOut, inv); - return pOut; -}; + for (l = 0; l < m; l++) + b.set(icol, l, b.get(icol, l) * pivinv); -/** - * Returns KM_TRUE if pIn is an identity matrix - * KM_FALSE otherwise - */ -cc.kmMat4IsIdentity = function (pIn) { - for (var i = 0; i < 16; i++) { - if (cc.kmMat4._identity[i] != pIn.mat[i]) - return false; - } - return true; -}; + for (ll = 0; ll < n; ll++) { + if (ll != icol) { + dum = a.get(ll, icol); + a.set(ll, icol, 0.0); + for (l = 0; l < n; l++) + a.set(ll, l, a.get(ll, l) - a.get(icol, l) * dum); -/** - * Sets pOut to the transpose of pIn, returns pOut - */ -cc.kmMat4Transpose = function (pOut, pIn) { - var x, z, outArr = pOut.mat,inArr = pIn.mat; - for (z = 0; z < 4; ++z) { - for (x = 0; x < 4; ++x) - outArr[(z * 4) + x] = inArr[(x * 4) + z]; - } - return pOut; -}; + for (l = 0; l < m; l++) + b.set(ll, l, a.get(ll, l) - b.get(icol, l) * dum); + } + } + } + // This is the end of the main loop over columns of the reduction. It only remains to unscram- + // ble the solution in view of the column interchanges. We do this by interchanging pairs of + // columns in the reverse order that the permutation was built up. + for (l = n - 1; l >= 0; l--) { + if (indxr[l] != indxc[l]) { + for (k = 0; k < n; k++) + a.swap(k, indxr[l], k, indxc[l]); + } + } + return true; + }; -/** - * Multiplies pM1 with pM2, stores the result in pOut, returns pOut - */ -cc.kmMat4Multiply = function (pOut, pM1, pM2) { - // Cache the matrix values (makes for huge speed increases!) - var outArray = pOut.mat; - var a00 = pM1.mat[0], a01 = pM1.mat[1], a02 = pM1.mat[2], a03 = pM1.mat[3]; - var a10 = pM1.mat[4], a11 = pM1.mat[5], a12 = pM1.mat[6], a13 = pM1.mat[7]; - var a20 = pM1.mat[8], a21 = pM1.mat[9], a22 = pM1.mat[10], a23 = pM1.mat[11]; - var a30 = pM1.mat[12], a31 = pM1.mat[13], a32 = pM1.mat[14], a33 = pM1.mat[15]; - - var b00 = pM2.mat[0], b01 = pM2.mat[1], b02 = pM2.mat[2], b03 = pM2.mat[3]; - var b10 = pM2.mat[4], b11 = pM2.mat[5], b12 = pM2.mat[6], b13 = pM2.mat[7]; - var b20 = pM2.mat[8], b21 = pM2.mat[9], b22 = pM2.mat[10], b23 = pM2.mat[11]; - var b30 = pM2.mat[12], b31 = pM2.mat[13], b32 = pM2.mat[14], b33 = pM2.mat[15]; - - outArray[0] = b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30; - outArray[1] = b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31; - outArray[2] = b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32; - outArray[3] = b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33; - outArray[4] = b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30; - outArray[5] = b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31; - outArray[6] = b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32; - outArray[7] = b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33; - outArray[8] = b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30; - outArray[9] = b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31; - outArray[10] = b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32; - outArray[11] = b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33; - outArray[12] = b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30; - outArray[13] = b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31; - outArray[14] = b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32; - outArray[15] = b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33; - return pOut; -}; - -cc.getMat4MultiplyValue = function (pM1, pM2) { - var m1 = pM1.mat, m2 = pM2.mat; - var mat = new Float32Array(16); - - mat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3]; - mat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3]; - mat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3]; - mat[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3]; - - mat[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7]; - mat[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7]; - mat[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7]; - mat[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7]; - - mat[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11]; - mat[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11]; - mat[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11]; - mat[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11]; - - mat[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15]; - mat[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15]; - mat[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15]; - mat[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15]; - - return mat; -}; - -cc.getMat4MultiplyWithMat4 = function (pM1, pM2, swapMat) { - var m1 = pM1.mat, m2 = pM2.mat; - var mat = swapMat.mat; - - mat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3]; - mat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3]; - mat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3]; - mat[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3]; - - mat[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7]; - mat[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7]; - mat[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7]; - mat[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7]; - - mat[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11]; - mat[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11]; - mat[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11]; - mat[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11]; - - mat[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15]; - mat[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15]; - mat[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15]; - mat[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15]; - - return swapMat.mat; -}; + var identityMatrix = new cc.math.Matrix4().identity(); + /** + * Calculates the inverse of pM and stores the result in pOut. + * Please use matrix4's inverse function instead. + * @Return Returns NULL if there is no inverse, else pOut + */ + cc.kmMat4Inverse = function (pOut, pM) { + var inv = new cc.math.Matrix4(pM); + if (cc.math.Matrix4._gaussj(inv, identityMatrix) === false) + return null; + pOut.assignFrom(inv); + return pOut; + }; -/** - * Assigns the value of pIn to pOut - */ -cc.kmMat4Assign = function (pOut, pIn) { - if(pOut == pIn) { - cc.log("cc.kmMat4Assign(): pOut equals pIn"); + /** + * Calculates the inverse of current matrix. + * @returns {cc.math.Matrix4} Returns null if there is no inverse, else returns a new inverse matrix object + */ + proto.inverse = function(){ //cc.kmMat4Inverse + var inv = new cc.math.Matrix4(this); + if (cc.math.Matrix4._gaussj(inv, identityMatrix) === false) + return null; + return inv; + }; + + /** + * Returns true if current matrix is an identity matrix, false otherwise + */ + proto.isIdentity = function () { // cc.kmMat4IsIdentity + var mat = this.mat; + return (mat[0] === 1 && mat[1] === 0 && mat[2] === 0 && mat[3] === 0 + && mat[4] === 0 && mat[5] === 1 && mat[6] === 0 && mat[7] === 0 + && mat[8] === 0 && mat[9] === 0 && mat[10] === 1 && mat[11] === 0 + && mat[12] === 0 && mat[13] === 0 && mat[14] === 0 && mat[15] === 1); + }; + + /** + * transpose the current matrix + */ + proto.transpose = function() { // cc.kmMat4Transpose + var mat = this.mat; + var m1 = mat[1], m2 = mat[2], m3 = mat[3], + m4 = mat[4], m6 = mat[6], m7 = mat[7], + m8 = mat[8], m9 = mat[9], m11 = mat[11], + m12 = mat[12], m13 = mat[13], m14 = mat[14]; + mat[1] = m4; + mat[2] = m8; + mat[3] = m12; + + mat[4] = m1; + mat[6] = m9; + mat[7] = m13; + + mat[8] = m2; + mat[9] = m6; + mat[11] = m14; + + mat[12] = m3; + mat[13] = m7; + mat[14] = m11; + return this; + }; + + /** + * Multiplies pM1 with pM2, stores the result in pOut, returns pOut + */ + cc.kmMat4Multiply = function (pOut, pM1, pM2) { + // Cache the matrix values (makes for huge speed increases!) + var outArray = pOut.mat, mat1 = pM1.mat, mat2 = pM2.mat; + var a00 = mat1[0], a01 = mat1[1], a02 = mat1[2], a03 = mat1[3]; + var a10 = mat1[4], a11 = mat1[5], a12 = mat1[6], a13 = mat1[7]; + var a20 = mat1[8], a21 = mat1[9], a22 = mat1[10], a23 = mat1[11]; + var a30 = mat1[12], a31 = mat1[13], a32 = mat1[14], a33 = mat1[15]; + + var b00 = mat2[0], b01 = mat2[1], b02 = mat2[2], b03 = mat2[3]; + var b10 = mat2[4], b11 = mat2[5], b12 = mat2[6], b13 = mat2[7]; + var b20 = mat2[8], b21 = mat2[9], b22 = mat2[10], b23 = mat2[11]; + var b30 = mat2[12], b31 = mat2[13], b32 = mat2[14], b33 = mat2[15]; + + outArray[0] = b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30; + outArray[1] = b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31; + outArray[2] = b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32; + outArray[3] = b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33; + outArray[4] = b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30; + outArray[5] = b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31; + outArray[6] = b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32; + outArray[7] = b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33; + outArray[8] = b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30; + outArray[9] = b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31; + outArray[10] = b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32; + outArray[11] = b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33; + outArray[12] = b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30; + outArray[13] = b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31; + outArray[14] = b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32; + outArray[15] = b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33; return pOut; - } + }; - var outArr = pOut.mat; - var inArr = pIn.mat; + /** + * current matrix multiplies with other matrix mat4 + * @param {cc.math.Matrix4} mat4 + * @returns {cc.math.Matrix4} + */ + proto.multiply = function(mat4){ + // Cache the matrix values (makes for huge speed increases!) + var mat = this.mat, mat2 = mat4.mat; + var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3]; + var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7]; + var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11]; + var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15]; + + var b00 = mat2[0], b01 = mat2[1], b02 = mat2[2], b03 = mat2[3]; + var b10 = mat2[4], b11 = mat2[5], b12 = mat2[6], b13 = mat2[7]; + var b20 = mat2[8], b21 = mat2[9], b22 = mat2[10], b23 = mat2[11]; + var b30 = mat2[12], b31 = mat2[13], b32 = mat2[14], b33 = mat2[15]; + + mat[0] = b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30; + mat[1] = b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31; + mat[2] = b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32; + mat[3] = b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33; + mat[4] = b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30; + mat[5] = b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31; + mat[6] = b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32; + mat[7] = b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33; + mat[8] = b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30; + mat[9] = b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31; + mat[10] = b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32; + mat[11] = b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33; + mat[12] = b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30; + mat[13] = b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31; + mat[14] = b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32; + mat[15] = b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33; + return this; + }; + + cc.getMat4MultiplyValue = function (pM1, pM2) { + var m1 = pM1.mat, m2 = pM2.mat; + var mat = new Float32Array(16); + + mat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3]; + mat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3]; + mat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3]; + mat[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3]; + + mat[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7]; + mat[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7]; + mat[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7]; + mat[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7]; + + mat[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11]; + mat[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11]; + mat[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11]; + mat[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11]; + + mat[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15]; + mat[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15]; + mat[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15]; + mat[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15]; + + return mat; + }; + + /** + * Assigns the value of pIn to pOut + */ + cc.kmMat4Assign = function (pOut, pIn) { + if (pOut === pIn) { + cc.log("cc.kmMat4Assign(): pOut equals pIn"); + return pOut; + } - outArr[0] = inArr[0]; - outArr[1] = inArr[1]; - outArr[2] = inArr[2]; - outArr[3] = inArr[3]; + var outArr = pOut.mat; + var inArr = pIn.mat; - outArr[4] = inArr[4]; - outArr[5] = inArr[5]; - outArr[6] = inArr[6]; - outArr[7] = inArr[7]; + outArr[0] = inArr[0]; + outArr[1] = inArr[1]; + outArr[2] = inArr[2]; + outArr[3] = inArr[3]; - outArr[8] = inArr[8]; - outArr[9] = inArr[9]; - outArr[10] = inArr[10]; - outArr[11] = inArr[11]; + outArr[4] = inArr[4]; + outArr[5] = inArr[5]; + outArr[6] = inArr[6]; + outArr[7] = inArr[7]; - outArr[12] = inArr[12]; - outArr[13] = inArr[13]; - outArr[14] = inArr[14]; - outArr[15] = inArr[15]; - return pOut; -}; + outArr[8] = inArr[8]; + outArr[9] = inArr[9]; + outArr[10] = inArr[10]; + outArr[11] = inArr[11]; -/** - * Returns KM_TRUE if the 2 matrices are equal (approximately) - */ -cc.kmMat4AreEqual = function (pMat1, pMat2) { - if(pMat1 == pMat2){ - cc.log("cc.kmMat4AreEqual(): pMat1 and pMat2 are same object."); - return true; - } + outArr[12] = inArr[12]; + outArr[13] = inArr[13]; + outArr[14] = inArr[14]; + outArr[15] = inArr[15]; + return pOut; + }; - for (var i = 0; i < 16; i++) { - if (!(pMat1.mat[i] + cc.kmEpsilon > pMat2.mat[i] && - pMat1.mat[i] - cc.kmEpsilon < pMat2.mat[i])) { - return false; + /** + * Assigns the value of current matrix from mat4 + * @param {cc.math.Matrix4} mat4 + * @returns {cc.math.Matrix4} + */ + proto.assignFrom = function(mat4) { + if (this == mat4) { + cc.log("cc.mat.Matrix4.assignFrom(): mat4 equals current matrix"); + return this; } - } - return true; -}; - -/** - * Builds an X-axis rotation matrix and stores it in pOut, returns pOut - */ -cc.kmMat4RotationX = function (pOut, radians) { - /* - | 1 0 0 0 | - M = | 0 cos(A) -sin(A) 0 | - | 0 sin(A) cos(A) 0 | - | 0 0 0 1 | - + var outArr = this.mat, inArr = mat4.mat; + + outArr[0] = inArr[0]; + outArr[1] = inArr[1]; + outArr[2] = inArr[2]; + outArr[3] = inArr[3]; + + outArr[4] = inArr[4]; + outArr[5] = inArr[5]; + outArr[6] = inArr[6]; + outArr[7] = inArr[7]; + + outArr[8] = inArr[8]; + outArr[9] = inArr[9]; + outArr[10] = inArr[10]; + outArr[11] = inArr[11]; + + outArr[12] = inArr[12]; + outArr[13] = inArr[13]; + outArr[14] = inArr[14]; + outArr[15] = inArr[15]; + return this; + }; + + /** + * Returns true if current matrix equal mat4 (approximately) + * @param {cc.math.Matrix4} mat4 + * @returns {boolean} */ + proto.equals = function(mat4) { + if (this === mat4) { + cc.log("cc.kmMat4AreEqual(): pMat1 and pMat2 are same object."); + return true; + } + var matA = this.mat, matB = mat4.mat, EPSILON = cc.math.EPSILON; + for (var i = 0; i < 16; i++) { + if (!(matA[i] + EPSILON > matB[i] && matA[i] - EPSILON < matB[i])) + return false; + } + return true; + }; - pOut.mat[0] = 1.0; - pOut.mat[1] = 0.0; - pOut.mat[2] = 0.0; - pOut.mat[3] = 0.0; - - pOut.mat[4] = 0.0; - pOut.mat[5] = Math.cos(radians); - pOut.mat[6] = Math.sin(radians); - pOut.mat[7] = 0.0; - - pOut.mat[8] = 0.0; - pOut.mat[9] = -Math.sin(radians); - pOut.mat[10] = Math.cos(radians); - pOut.mat[11] = 0.0; - - pOut.mat[12] = 0.0; - pOut.mat[13] = 0.0; - pOut.mat[14] = 0.0; - pOut.mat[15] = 1.0; - - return pOut; -}; - -/** - * Builds a rotation matrix using the rotation around the Y-axis - * The result is stored in pOut, pOut is returned. - */ -cc.kmMat4RotationY = function (pOut, radians) { - /* - | cos(A) 0 sin(A) 0 | - M = | 0 1 0 0 | - | -sin(A) 0 cos(A) 0 | - | 0 0 0 1 | - */ - pOut.mat[0] = Math.cos(radians); - pOut.mat[1] = 0.0; - pOut.mat[2] = -Math.sin(radians); - pOut.mat[3] = 0.0; - - pOut.mat[4] = 0.0; - pOut.mat[5] = 1.0; - pOut.mat[6] = 0.0; - pOut.mat[7] = 0.0; - - pOut.mat[8] = Math.sin(radians); - pOut.mat[9] = 0.0; - pOut.mat[10] = Math.cos(radians); - pOut.mat[11] = 0.0; - - pOut.mat[12] = 0.0; - pOut.mat[13] = 0.0; - pOut.mat[14] = 0.0; - pOut.mat[15] = 1.0; - - return pOut; -}; - -/** - * Builds a rotation matrix around the Z-axis. The resulting - * matrix is stored in pOut. pOut is returned. - */ -cc.kmMat4RotationZ = function (pOut, radians) { - /* - | cos(A) -sin(A) 0 0 | - M = | sin(A) cos(A) 0 0 | - | 0 0 1 0 | - | 0 0 0 1 | - */ - pOut.mat[0] = Math.cos(radians); - pOut.mat[1] = Math.sin(radians); - pOut.mat[2] = 0.0; - pOut.mat[3] = 0.0; - - pOut.mat[4] = -Math.sin(radians); - pOut.mat[5] = Math.cos(radians); - pOut.mat[6] = 0.0; - pOut.mat[7] = 0.0; - - pOut.mat[8] = 0.0; - pOut.mat[9] = 0.0; - pOut.mat[10] = 1.0; - pOut.mat[11] = 0.0; - - pOut.mat[12] = 0.0; - pOut.mat[13] = 0.0; - pOut.mat[14] = 0.0; - pOut.mat[15] = 1.0; - - return pOut; -}; - -/** - * Builds a rotation matrix from pitch, yaw and roll. The resulting - * matrix is stored in pOut and pOut is returned - */ -cc.kmMat4RotationPitchYawRoll = function (pOut, pitch, yaw, roll) { - var cr = Math.cos(pitch); - var sr = Math.sin(pitch); - var cp = Math.cos(yaw); - var sp = Math.sin(yaw); - var cy = Math.cos(roll); - var sy = Math.sin(roll); - var srsp = sr * sp; - var crsp = cr * sp; - - pOut.mat[0] = cp * cy; - pOut.mat[4] = cp * sy; - pOut.mat[8] = -sp; - - pOut.mat[1] = srsp * cy - cr * sy; - pOut.mat[5] = srsp * sy + cr * cy; - pOut.mat[9] = sr * cp; - - pOut.mat[2] = crsp * cy + sr * sy; - pOut.mat[6] = crsp * sy - sr * cy; - pOut.mat[10] = cr * cp; - - pOut.mat[3] = pOut.mat[7] = pOut.mat[11] = 0.0; - pOut.mat[15] = 1.0; - - return pOut; -}; - -/** Converts a quaternion to a rotation matrix, - * the result is stored in pOut, returns pOut - */ -cc.kmMat4RotationQuaternion = function (pOut, pQ) { - pOut.mat[0] = 1.0 - 2.0 * (pQ.y * pQ.y + pQ.z * pQ.z ); - pOut.mat[1] = 2.0 * (pQ.x * pQ.y + pQ.z * pQ.w); - pOut.mat[2] = 2.0 * (pQ.x * pQ.z - pQ.y * pQ.w); - pOut.mat[3] = 0.0; - - // Second row - pOut.mat[4] = 2.0 * ( pQ.x * pQ.y - pQ.z * pQ.w ); - pOut.mat[5] = 1.0 - 2.0 * ( pQ.x * pQ.x + pQ.z * pQ.z ); - pOut.mat[6] = 2.0 * (pQ.z * pQ.y + pQ.x * pQ.w ); - pOut.mat[7] = 0.0; - - // Third row - pOut.mat[8] = 2.0 * ( pQ.x * pQ.z + pQ.y * pQ.w ); - pOut.mat[9] = 2.0 * ( pQ.y * pQ.z - pQ.x * pQ.w ); - pOut.mat[10] = 1.0 - 2.0 * ( pQ.x * pQ.x + pQ.y * pQ.y ); - pOut.mat[11] = 0.0; - - // Fourth row - pOut.mat[12] = 0; - pOut.mat[13] = 0; - pOut.mat[14] = 0; - pOut.mat[15] = 1.0; - - return pOut; -}; - -/** Build a 4x4 OpenGL transformation matrix using a 3x3 rotation matrix, - * and a 3d vector representing a translation. Assign the result to pOut, - * pOut is also returned. - */ -cc.kmMat4RotationTranslation = function (pOut, rotation, translation) { - pOut.mat[0] = rotation.mat[0]; - pOut.mat[1] = rotation.mat[1]; - pOut.mat[2] = rotation.mat[2]; - pOut.mat[3] = 0.0; - - pOut.mat[4] = rotation.mat[3]; - pOut.mat[5] = rotation.mat[4]; - pOut.mat[6] = rotation.mat[5]; - pOut.mat[7] = 0.0; - - pOut.mat[8] = rotation.mat[6]; - pOut.mat[9] = rotation.mat[7]; - pOut.mat[10] = rotation.mat[8]; - pOut.mat[11] = 0.0; - - pOut.mat[12] = translation.x; - pOut.mat[13] = translation.y; - pOut.mat[14] = translation.z; - pOut.mat[15] = 1.0; - - return pOut; -}; - -/** Builds a scaling matrix */ -cc.kmMat4Scaling = function (pOut, x, y, z) { - pOut.mat[0] = x; - pOut.mat[5] = y; - pOut.mat[10] = z; - pOut.mat[15] = 1.0; - pOut.mat[1] = pOut.mat[2] = pOut.mat[3] = - pOut.mat[4] = pOut.mat[6] = pOut.mat[7] = - pOut.mat[8] = pOut.mat[9] = pOut.mat[11] = - pOut.mat[12] = pOut.mat[13] = pOut.mat[14] = 0; - return pOut; -}; - -/** - * Builds a translation matrix. All other elements in the matrix - * will be set to zero except for the diagonal which is set to 1.0 - */ -cc.kmMat4Translation = function (pOut, x, y, z) { - //FIXME: Write a test for this - pOut.mat[0] = pOut.mat[5] = pOut.mat[10] = pOut.mat[15] = 1.0; - pOut.mat[1] = pOut.mat[2] = pOut.mat[3] = - pOut.mat[4] = pOut.mat[6] = pOut.mat[7] = - pOut.mat[8] = pOut.mat[9] = pOut.mat[11] = 0.0; - pOut.mat[12] = x; - pOut.mat[13] = y; - pOut.mat[14] = z; - return pOut; -}; - -/** - * Get the up vector from a matrix. pIn is the matrix you - * wish to extract the vector from. pOut is a pointer to the - * kmVec3 structure that should hold the resulting vector - */ -cc.kmMat4GetUpVec3 = function (pOut, pIn) { - pOut.x = pIn.mat[4]; - pOut.y = pIn.mat[5]; - pOut.z = pIn.mat[6]; - cc.kmVec3Normalize(pOut, pOut); - return pOut; -}; - -/** Extract the right vector from a 4x4 matrix. The result is - * stored in pOut. Returns pOut. - */ -cc.kmMat4GetRightVec3 = function (pOut, pIn) { - pOut.x = pIn.mat[0]; - pOut.y = pIn.mat[1]; - pOut.z = pIn.mat[2]; - cc.kmVec3Normalize(pOut, pOut); - return pOut; -}; - -/** - * Extract the forward vector from a 4x4 matrix. The result is - * stored in pOut. Returns pOut. - */ -cc.kmMat4GetForwardVec3 = function (pOut, pIn) { - pOut.x = pIn.mat[8]; - pOut.y = pIn.mat[9]; - pOut.z = pIn.mat[10]; - cc.kmVec3Normalize(pOut, pOut); - return pOut; -}; - -/** - * Creates a perspective projection matrix in the - * same way as gluPerspective - */ -cc.kmMat4PerspectiveProjection = function (pOut, fovY, aspect, zNear, zFar) { - var r = cc.kmDegreesToRadians(fovY / 2); - var deltaZ = zFar - zNear; - var s = Math.sin(r); - - if (deltaZ == 0 || s == 0 || aspect == 0) - return null; - - //cos(r) / sin(r) = cot(r) - var cotangent = Math.cos(r) / s; - - cc.kmMat4Identity(pOut); - pOut.mat[0] = cotangent / aspect; - pOut.mat[5] = cotangent; - pOut.mat[10] = -(zFar + zNear) / deltaZ; - pOut.mat[11] = -1; - pOut.mat[14] = -2 * zNear * zFar / deltaZ; - pOut.mat[15] = 0; - - return pOut; -}; - -/** Creates an orthographic projection matrix like glOrtho */ -cc.kmMat4OrthographicProjection = function (pOut, left, right, bottom, top, nearVal, farVal) { - cc.kmMat4Identity(pOut); - pOut.mat[0] = 2 / (right - left); - pOut.mat[5] = 2 / (top - bottom); - pOut.mat[10] = -2 / (farVal - nearVal); - pOut.mat[12] = -((right + left) / (right - left)); - pOut.mat[13] = -((top + bottom) / (top - bottom)); - pOut.mat[14] = -((farVal + nearVal) / (farVal - nearVal)); - return pOut; -}; - -/** - * Builds a translation matrix in the same way as gluLookAt() - * the resulting matrix is stored in pOut. pOut is returned. - */ -cc.kmMat4LookAt = function (pOut, pEye, pCenter, pUp) { - var f = new cc.kmVec3(), up = new cc.kmVec3(), s = new cc.kmVec3(), u = new cc.kmVec3(); - var translate = new cc.kmMat4(); - - cc.kmVec3Subtract(f, pCenter, pEye); - cc.kmVec3Normalize(f, f); - - cc.kmVec3Assign(up, pUp); - cc.kmVec3Normalize(up, up); - - cc.kmVec3Cross(s, f, up); - cc.kmVec3Normalize(s, s); - - cc.kmVec3Cross(u, s, f); - cc.kmVec3Normalize(s, s); - - cc.kmMat4Identity(pOut); + /** + * Builds an X-axis rotation matrix and stores it in matrix, returns matrix, if matrix is null, create a new matrix + * @param {Number} radians + * @param {cc.math.Matrix4} [matrix] + * @returns {cc.math.Matrix4} + */ + cc.math.Matrix4.createByRotationX = function(radians, matrix) { //cc.kmMat4RotationX + /* + | 1 0 0 0 | + M = | 0 cos(A) -sin(A) 0 | + | 0 sin(A) cos(A) 0 | + | 0 0 0 1 | + */ + matrix = matrix || new cc.math.Matrix4(); + var mat = matrix.mat; + mat[0] = 1.0; + mat[3] = mat[2] = mat[1] = 0.0; + + mat[4] = 0.0; + mat[5] = Math.cos(radians); + mat[6] = Math.sin(radians); + mat[7] = 0.0; + + mat[8] = 0.0; + mat[9] = -Math.sin(radians); + mat[10] = Math.cos(radians); + mat[11] = 0.0; + + mat[14] = mat[13] = mat[12] = 0.0; + mat[15] = 1.0; + return matrix; + }; + + /** + * Builds a rotation matrix using the rotation around the Y-axis, The result is stored in matrix, matrix is returned. + * @param {Number} radians + * @param {cc.math.Matrix4} [matrix] + * @returns {*} + */ + cc.math.Matrix4.createByRotationY = function(radians, matrix) { // cc.kmMat4RotationY + /* + | cos(A) 0 sin(A) 0 | + M = | 0 1 0 0 | + | -sin(A) 0 cos(A) 0 | + | 0 0 0 1 | + */ + matrix = matrix || new cc.math.Matrix4(); + var mat = matrix.mat; + mat[0] = Math.cos(radians); + mat[1] = 0.0; + mat[2] = -Math.sin(radians); + mat[3] = 0.0; + + mat[7] = mat[6] = mat[4] = 0.0; + mat[5] = 1.0; + + mat[8] = Math.sin(radians); + mat[9] = 0.0; + mat[10] = Math.cos(radians); + mat[11] = 0.0; + + mat[14] = mat[13] = mat[12] = 0.0; + mat[15] = 1.0; + return matrix; + }; + + /** + * Builds a rotation matrix around the Z-axis. The resulting matrix is stored in matrix. matrix is returned. + * @param {Number} radians + * @param {cc.math.Matrix4} matrix + * @return {cc.math.Matrix4} + */ + cc.math.Matrix4.createByRotationZ = function(radians, matrix){ // cc.kmMat4RotationZ + /* + | cos(A) -sin(A) 0 0 | + M = | sin(A) cos(A) 0 0 | + | 0 0 1 0 | + | 0 0 0 1 | + */ + matrix = matrix || new cc.math.Matrix4(); + var mat = matrix.mat; + mat[0] = Math.cos(radians); + mat[1] = Math.sin(radians); + mat[3] = mat[2] = 0.0; + + mat[4] = -Math.sin(radians); + mat[5] = Math.cos(radians); + mat[7] = mat[6] = 0.0; + + mat[11] = mat[9] = mat[8] = 0.0; + mat[10] = 1.0; + + mat[14] = mat[13] = mat[12] = 0.0; + mat[15] = 1.0; + + return matrix; + }; + + /** + * Builds a rotation matrix from pitch, yaw and roll. The resulting matrix is stored in parameter matrix and returns. + * @param {Number} pitch + * @param {Number} yaw + * @param {Number} roll + * @param {cc.math.Matrix4} [matrix] if matrix is undefined, creates a new matrix. + * @returns {cc.math.Matrix4} + */ + cc.math.Matrix4.createByPitchYawRoll = function(pitch, yaw, roll, matrix) { + matrix = matrix || new cc.math.Matrix4(); + var cr = Math.cos(pitch), sr = Math.sin(pitch); + var cp = Math.cos(yaw), sp = Math.sin(yaw); + var cy = Math.cos(roll), sy = Math.sin(roll); + var srsp = sr * sp, crsp = cr * sp; + var mat = matrix.mat; + + mat[0] = cp * cy; + mat[4] = cp * sy; + mat[8] = -sp; + + mat[1] = srsp * cy - cr * sy; + mat[5] = srsp * sy + cr * cy; + mat[9] = sr * cp; + + mat[2] = crsp * cy + sr * sy; + mat[6] = crsp * sy - sr * cy; + mat[10] = cr * cp; + + mat[3] = mat[7] = mat[11] = 0.0; + mat[15] = 1.0; + return matrix; + }; + + /** + * Builds a matrix by a quaternion. + * @param {cc.math.Quaternion} quaternion + * @param {cc.math.Matrix4} [matrix] if matrix is undefined, creates a new matrix. + * @returns {cc.math.Matrix4} + */ + cc.math.Matrix4.createByQuaternion = function(quaternion, matrix) { + matrix = matrix || new cc.math.Matrix4(); + var mat = matrix.mat; + mat[0] = 1.0 - 2.0 * (quaternion.y * quaternion.y + quaternion.z * quaternion.z ); + mat[1] = 2.0 * (quaternion.x * quaternion.y + quaternion.z * quaternion.w); + mat[2] = 2.0 * (quaternion.x * quaternion.z - quaternion.y * quaternion.w); + mat[3] = 0.0; + + // Second row + mat[4] = 2.0 * ( quaternion.x * quaternion.y - quaternion.z * quaternion.w ); + mat[5] = 1.0 - 2.0 * ( quaternion.x * quaternion.x + quaternion.z * quaternion.z ); + mat[6] = 2.0 * (quaternion.z * quaternion.y + quaternion.x * quaternion.w ); + mat[7] = 0.0; + + // Third row + mat[8] = 2.0 * ( quaternion.x * quaternion.z + quaternion.y * quaternion.w ); + mat[9] = 2.0 * ( quaternion.y * quaternion.z - quaternion.x * quaternion.w ); + mat[10] = 1.0 - 2.0 * ( quaternion.x * quaternion.x + quaternion.y * quaternion.y ); + mat[11] = 0.0; + + // Fourth row + mat[14] = mat[13] = mat[12] = 0; + mat[15] = 1.0; + return matrix; + }; + + /** + * Build a 4x4 OpenGL transformation matrix using a 3x3 rotation matrix, and a 3d vector representing a translation. + * @param {cc.math.Matrix3} rotation + * @param {cc.math.Vec3} translation + * @param {cc.math.Matrix4} [matrix] if matrix is undefined, creates a new matrix. + * @returns {cc.math.Matrix4} + */ + cc.math.Matrix4.createByRotationTranslation = function(rotation, translation, matrix) { + matrix = matrix || new cc.math.Matrix4(); + var mat = matrix.mat, rMat = rotation.mat; + mat[0] = rMat[0]; + mat[1] = rMat[1]; + mat[2] = rMat[2]; + mat[3] = 0.0; + + mat[4] = rMat[3]; + mat[5] = rMat[4]; + mat[6] = rMat[5]; + mat[7] = 0.0; + + mat[8] = rMat[6]; + mat[9] = rMat[7]; + mat[10] = rMat[8]; + mat[11] = 0.0; + + mat[12] = translation.x; + mat[13] = translation.y; + mat[14] = translation.z; + mat[15] = 1.0; + return matrix; + }; + + /** + * Builds a scaling matrix + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @param {cc.math.Matrix4} [matrix] if matrix is undefined, creates a new matrix. + * @returns {cc.math.Matrix4} + */ + cc.math.Matrix4.createByScale = function(x, y, z, matrix) { //cc.kmMat4Scaling + matrix = matrix || new cc.math.Matrix4(); + var mat = matrix.mat; + mat[0] = x; + mat[5] = y; + mat[10] = z; + mat[15] = 1.0; + mat[1] = mat[2] = mat[3] = mat[4] = mat[6] = mat[7] = + mat[8] = mat[9] = mat[11] = mat[12] = mat[13] = mat[14] = 0; + return matrix; + }; + + /** + * Builds a translation matrix. All other elements in the matrix + * will be set to zero except for the diagonal which is set to 1.0 + */ + cc.kmMat4Translation = function (pOut, x, y, z) { + //FIXME: Write a test for this + pOut.mat[0] = pOut.mat[5] = pOut.mat[10] = pOut.mat[15] = 1.0; + pOut.mat[1] = pOut.mat[2] = pOut.mat[3] = + pOut.mat[4] = pOut.mat[6] = pOut.mat[7] = + pOut.mat[8] = pOut.mat[9] = pOut.mat[11] = 0.0; + pOut.mat[12] = x; + pOut.mat[13] = y; + pOut.mat[14] = z; + return pOut; + }; + + /** + * Builds a translation matrix. + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @param {cc.math.Matrix4} [matrix] if matrix is undefined, creates a new matrix. + * @returns {cc.math.Matrix4} + */ + cc.math.Matrix4.createByTranslation = function(x, y, z, matrix){ //cc.kmMat4Translation + matrix = matrix || new cc.math.Matrix4(); + matrix.identity(); + matrix.mat[12] = x; + matrix.mat[13] = y; + matrix.mat[14] = z; + return matrix; + }; + + /** + * Get the up vector from a matrix. + * @returns {cc.math.Vec3} + */ + proto.getUpVec3 = function() { + var mat = this.mat; + var ret = new cc.math.Vec3(mat[4],mat[5], mat[6]); + return ret.normalize(); + }; + + /** + * Extract the right vector from a 4x4 matrix. + * @returns {cc.math.Vec3} + */ + proto.getRightVec3 = function(){ + var mat = this.mat; + var ret = new cc.math.Vec3(mat[0],mat[1], mat[2]); + return ret.normalize(); + }; + + /** + * Extract the forward vector from a 4x4 matrix. + * @returns {cc.math.Vec3} + */ + proto.getForwardVec3 = function() { + var mat = this.mat; + var ret = new cc.math.Vec3(mat[8],mat[9], mat[10]); + return ret.normalize(); + }; + + /** + * Creates a perspective projection matrix in the + * same way as gluPerspective + */ + cc.kmMat4PerspectiveProjection = function (pOut, fovY, aspect, zNear, zFar) { + var r = cc.degreesToRadians(fovY / 2); + var deltaZ = zFar - zNear; + var s = Math.sin(r); + + if (deltaZ == 0 || s == 0 || aspect == 0) + return null; + + //cos(r) / sin(r) = cot(r) + var cotangent = Math.cos(r) / s; + pOut.identity(); + pOut.mat[0] = cotangent / aspect; + pOut.mat[5] = cotangent; + pOut.mat[10] = -(zFar + zNear) / deltaZ; + pOut.mat[11] = -1; + pOut.mat[14] = -2 * zNear * zFar / deltaZ; + pOut.mat[15] = 0; - pOut.mat[0] = s.x; - pOut.mat[4] = s.y; - pOut.mat[8] = s.z; + return pOut; + }; + + /** + * Creates a perspective projection matrix in the same way as gluPerspective + * @param {Number} fovY + * @param {Number} aspect + * @param {Number} zNear + * @param {Number} zFar + * @returns {cc.math.Matrix4|Null} + */ + cc.math.Matrix4.createPerspectiveProjection = function(fovY, aspect, zNear, zFar){ + var r = cc.degreesToRadians(fovY / 2), deltaZ = zFar - zNear; + var s = Math.sin(r); + + if (deltaZ == 0 || s == 0 || aspect == 0) + return null; + + //cos(r) / sin(r) = cot(r) + var cotangent = Math.cos(r) / s; + var matrix = new cc.math.Matrix4(), mat = matrix.mat; + matrix.identity(); + mat[0] = cotangent / aspect; + mat[5] = cotangent; + mat[10] = -(zFar + zNear) / deltaZ; + mat[11] = -1; + mat[14] = -2 * zNear * zFar / deltaZ; + mat[15] = 0; + return matrix; + }; + + /** Creates an orthographic projection matrix like glOrtho */ + cc.kmMat4OrthographicProjection = function (pOut, left, right, bottom, top, nearVal, farVal) { + pOut.identity(); + pOut.mat[0] = 2 / (right - left); + pOut.mat[5] = 2 / (top - bottom); + pOut.mat[10] = -2 / (farVal - nearVal); + pOut.mat[12] = -((right + left) / (right - left)); + pOut.mat[13] = -((top + bottom) / (top - bottom)); + pOut.mat[14] = -((farVal + nearVal) / (farVal - nearVal)); + return pOut; + }; + + /** + * Creates an orthographic projection matrix like glOrtho + * @param {Number} left + * @param {Number} right + * @param {Number} bottom + * @param {Number} top + * @param {Number} nearVal + * @param {Number} farVal + * @returns {cc.math.Matrix4} + */ + cc.math.Matrix4.createOrthographicProjection = function (left, right, bottom, top, nearVal, farVal) { + var matrix = new cc.math.Matrix4(), mat = matrix.mat; + matrix.identity(); + mat[0] = 2 / (right - left); + mat[5] = 2 / (top - bottom); + mat[10] = -2 / (farVal - nearVal); + mat[12] = -((right + left) / (right - left)); + mat[13] = -((top + bottom) / (top - bottom)); + mat[14] = -((farVal + nearVal) / (farVal - nearVal)); + return matrix; + }; + + /** + * Builds a translation matrix in the same way as gluLookAt() + * the resulting matrix is stored in pOut. pOut is returned. + */ + cc.kmMat4LookAt = function (pOut, pEye, pCenter, pUp) { + var f = new cc.math.Vec3(pCenter), up = new cc.math.Vec3(pUp); + f.subtract(pEye); + f.normalize(); + up.normalize(); - pOut.mat[1] = u.x; - pOut.mat[5] = u.y; - pOut.mat[9] = u.z; + var s = new cc.math.Vec3(f); + s.cross(up); + s.normalize(); - pOut.mat[2] = -f.x; - pOut.mat[6] = -f.y; - pOut.mat[10] = -f.z; + var u = new cc.math.Vec3(s); + u.cross(f); + s.normalize(); - cc.kmMat4Translation(translate, -pEye.x, -pEye.y, -pEye.z); - cc.kmMat4Multiply(pOut, pOut, translate); + pOut.identity(); - return pOut; -}; + pOut.mat[0] = s.x; + pOut.mat[4] = s.y; + pOut.mat[8] = s.z; -/** - * Build a rotation matrix from an axis and an angle. Result is stored in pOut. - * pOut is returned. - */ -cc.kmMat4RotationAxisAngle = function (pOut, axis, radians) { - var rcos = Math.cos(radians); - var rsin = Math.sin(radians); + pOut.mat[1] = u.x; + pOut.mat[5] = u.y; + pOut.mat[9] = u.z; - var normalizedAxis = new cc.kmVec3(); - cc.kmVec3Normalize(normalizedAxis, axis); + pOut.mat[2] = -f.x; + pOut.mat[6] = -f.y; + pOut.mat[10] = -f.z; - pOut.mat[0] = rcos + normalizedAxis.x * normalizedAxis.x * (1 - rcos); - pOut.mat[1] = normalizedAxis.z * rsin + normalizedAxis.y * normalizedAxis.x * (1 - rcos); - pOut.mat[2] = -normalizedAxis.y * rsin + normalizedAxis.z * normalizedAxis.x * (1 - rcos); - pOut.mat[3] = 0.0; + var translate = cc.math.Matrix4.createByTranslation(-pEye.x, -pEye.y, -pEye.z); + pOut.multiply(translate); + return pOut; + }; + + var tempMatrix = new cc.math.Matrix4(); // an internal matrix + proto.lookAt = function(eyeVec, centerVec, upVec) { + var f = new cc.math.Vec3(centerVec), up = new cc.math.Vec3(upVec), mat = this.mat; + f.subtract(eyeVec); + f.normalize(); + up.normalize(); + + var s = new cc.math.Vec3(f); + s.cross(up); + s.normalize(); + + var u = new cc.math.Vec3(s); + u.cross(f); + s.normalize(); + + this.identity(); + mat[0] = s.x; + mat[4] = s.y; + mat[8] = s.z; + + mat[1] = u.x; + mat[5] = u.y; + mat[9] = u.z; + + mat[2] = -f.x; + mat[6] = -f.y; + mat[10] = -f.z; + + tempMatrix = cc.math.Matrix4.createByTranslation(-eyeVec.x, -eyeVec.y, -eyeVec.z, tempMatrix); + this.multiply(tempMatrix); + return this; + }; + + /** + * Build a rotation matrix from an axis and an angle. Result is stored in pOut. + * pOut is returned. + */ + cc.kmMat4RotationAxisAngle = function (pOut, axis, radians) { + var rcos = Math.cos(radians), rsin = Math.sin(radians); - pOut.mat[4] = -normalizedAxis.z * rsin + normalizedAxis.x * normalizedAxis.y * (1 - rcos); - pOut.mat[5] = rcos + normalizedAxis.y * normalizedAxis.y * (1 - rcos); - pOut.mat[6] = normalizedAxis.x * rsin + normalizedAxis.z * normalizedAxis.y * (1 - rcos); - pOut.mat[7] = 0.0; + var normalizedAxis = new cc.math.Vec3(axis); + normalizedAxis.normalize(); - pOut.mat[8] = normalizedAxis.y * rsin + normalizedAxis.x * normalizedAxis.z * (1 - rcos); - pOut.mat[9] = -normalizedAxis.x * rsin + normalizedAxis.y * normalizedAxis.z * (1 - rcos); - pOut.mat[10] = rcos + normalizedAxis.z * normalizedAxis.z * (1 - rcos); - pOut.mat[11] = 0.0; + pOut.mat[0] = rcos + normalizedAxis.x * normalizedAxis.x * (1 - rcos); + pOut.mat[1] = normalizedAxis.z * rsin + normalizedAxis.y * normalizedAxis.x * (1 - rcos); + pOut.mat[2] = -normalizedAxis.y * rsin + normalizedAxis.z * normalizedAxis.x * (1 - rcos); + pOut.mat[3] = 0.0; - pOut.mat[12] = 0.0; - pOut.mat[13] = 0.0; - pOut.mat[14] = 0.0; - pOut.mat[15] = 1.0; + pOut.mat[4] = -normalizedAxis.z * rsin + normalizedAxis.x * normalizedAxis.y * (1 - rcos); + pOut.mat[5] = rcos + normalizedAxis.y * normalizedAxis.y * (1 - rcos); + pOut.mat[6] = normalizedAxis.x * rsin + normalizedAxis.z * normalizedAxis.y * (1 - rcos); + pOut.mat[7] = 0.0; - return pOut; -}; + pOut.mat[8] = normalizedAxis.y * rsin + normalizedAxis.x * normalizedAxis.z * (1 - rcos); + pOut.mat[9] = -normalizedAxis.x * rsin + normalizedAxis.y * normalizedAxis.z * (1 - rcos); + pOut.mat[10] = rcos + normalizedAxis.z * normalizedAxis.z * (1 - rcos); + pOut.mat[11] = 0.0; -/** - * Extract a 3x3 rotation matrix from the input 4x4 transformation. - * Stores the result in pOut, returns pOut - */ -cc.kmMat4ExtractRotation = function (pOut, pIn) { - pOut.mat[0] = pIn.mat[0]; - pOut.mat[1] = pIn.mat[1]; - pOut.mat[2] = pIn.mat[2]; - - pOut.mat[3] = pIn.mat[4]; - pOut.mat[4] = pIn.mat[5]; - pOut.mat[5] = pIn.mat[6]; - - pOut.mat[6] = pIn.mat[8]; - pOut.mat[7] = pIn.mat[9]; - pOut.mat[8] = pIn.mat[10]; - - return pOut; -}; - -cc.kmMat4ExtractPlane = function (pOut, pIn, plane) { - switch (plane) { - case cc.KM_PLANE_RIGHT: - pOut.a = pIn.mat[3] - pIn.mat[0]; - pOut.b = pIn.mat[7] - pIn.mat[4]; - pOut.c = pIn.mat[11] - pIn.mat[8]; - pOut.d = pIn.mat[15] - pIn.mat[12]; - break; - case cc.KM_PLANE_LEFT: - pOut.a = pIn.mat[3] + pIn.mat[0]; - pOut.b = pIn.mat[7] + pIn.mat[4]; - pOut.c = pIn.mat[11] + pIn.mat[8]; - pOut.d = pIn.mat[15] + pIn.mat[12]; - break; - case cc.KM_PLANE_BOTTOM: - pOut.a = pIn.mat[3] + pIn.mat[1]; - pOut.b = pIn.mat[7] + pIn.mat[5]; - pOut.c = pIn.mat[11] + pIn.mat[9]; - pOut.d = pIn.mat[15] + pIn.mat[13]; - break; - case cc.KM_PLANE_TOP: - pOut.a = pIn.mat[3] - pIn.mat[1]; - pOut.b = pIn.mat[7] - pIn.mat[5]; - pOut.c = pIn.mat[11] - pIn.mat[9]; - pOut.d = pIn.mat[15] - pIn.mat[13]; - break; - case cc.KM_PLANE_FAR: - pOut.a = pIn.mat[3] - pIn.mat[2]; - pOut.b = pIn.mat[7] - pIn.mat[6]; - pOut.c = pIn.mat[11] - pIn.mat[10]; - pOut.d = pIn.mat[15] - pIn.mat[14]; - break; - case cc.KM_PLANE_NEAR: - pOut.a = pIn.mat[3] + pIn.mat[2]; - pOut.b = pIn.mat[7] + pIn.mat[6]; - pOut.c = pIn.mat[11] + pIn.mat[10]; - pOut.d = pIn.mat[15] + pIn.mat[14]; - break; - default: - cc.log("cc.kmMat4ExtractPlane(): Invalid plane index"); - break; - } - - var t = Math.sqrt(pOut.a * pOut.a + - pOut.b * pOut.b + - pOut.c * pOut.c); - pOut.a /= t; - pOut.b /= t; - pOut.c /= t; - pOut.d /= t; - - return pOut; -}; + pOut.mat[12] = 0.0; + pOut.mat[13] = 0.0; + pOut.mat[14] = 0.0; + pOut.mat[15] = 1.0; -/** - * Take the rotation from a 4x4 transformation matrix, and return it as an axis and an angle (in radians) - * returns the output axis. - */ -cc.kmMat4RotationToAxisAngle = function (pAxis, radians, pIn) { - /*Surely not this easy?*/ - var temp = new cc.kmQuaternion(); - var rotation = new cc.kmMat3(); - cc.kmMat4ExtractRotation(rotation, pIn); - cc.kmQuaternionRotationMatrix(temp, rotation); - cc.kmQuaternionToAxisAngle(temp, pAxis, radians); - return pAxis; -}; + return pOut; + }; + + /** + * Build a rotation matrix from an axis and an angle. + * @param {cc.math.Vec3} axis + * @param {Number} radians + * @param {cc.math.Matrix4} [matrix] + * @returns {cc.math.Matrix4} + */ + cc.math.Matrix4.createByAxisAndAngle = function(axis, radians, matrix) { + matrix = matrix || new cc.math.Matrix4(); + var mat = this.mat, rcos = Math.cos(radians), rsin = Math.sin(radians) ; + + var normalizedAxis = new cc.math.Vec3(axis); + normalizedAxis.normalize(); + + mat[0] = rcos + normalizedAxis.x * normalizedAxis.x * (1 - rcos); + mat[1] = normalizedAxis.z * rsin + normalizedAxis.y * normalizedAxis.x * (1 - rcos); + mat[2] = -normalizedAxis.y * rsin + normalizedAxis.z * normalizedAxis.x * (1 - rcos); + mat[3] = 0.0; + + mat[4] = -normalizedAxis.z * rsin + normalizedAxis.x * normalizedAxis.y * (1 - rcos); + mat[5] = rcos + normalizedAxis.y * normalizedAxis.y * (1 - rcos); + mat[6] = normalizedAxis.x * rsin + normalizedAxis.z * normalizedAxis.y * (1 - rcos); + mat[7] = 0.0; + + mat[8] = normalizedAxis.y * rsin + normalizedAxis.x * normalizedAxis.z * (1 - rcos); + mat[9] = -normalizedAxis.x * rsin + normalizedAxis.y * normalizedAxis.z * (1 - rcos); + mat[10] = rcos + normalizedAxis.z * normalizedAxis.z * (1 - rcos); + mat[11] = 0.0; + + mat[12] = mat[13] = mat[14] = 0.0; + mat[15] = 1.0; + return matrix; + }; + + /** + * Extract a 3x3 rotation matrix from the input 4x4 transformation. + * @returns {cc.math.Matrix3} + */ + proto.extractRotation = function(){ + var matrix = new cc.math.Matrix3(), mat4 = this.mat, mat3 = matrix.mat; + mat3[0] = mat4[0]; + mat3[1] = mat4[1]; + mat3[2] = mat4[2]; + + mat3[3] = mat4[4]; + mat3[4] = mat4[5]; + mat3[5] = mat4[6]; + + mat3[6] = mat4[8]; + mat3[7] = mat4[9]; + mat3[8] = mat4[10]; + return matrix; + }; + + proto.extractPlane = function(planeType) { + var plane = new cc.math.Plane(), mat = this.mat; + switch (planeType) { + case cc.math.Plane.RIGHT: + plane.a = mat[3] - mat[0]; + plane.b = mat[7] - mat[4]; + plane.c = mat[11] - mat[8]; + plane.d = mat[15] - mat[12]; + break; + case cc.math.Plane.LEFT: + plane.a = mat[3] + mat[0]; + plane.b = mat[7] + mat[4]; + plane.c = mat[11] + mat[8]; + plane.d = mat[15] + mat[12]; + break; + case cc.math.Plane.BOTTOM: + plane.a = mat[3] + mat[1]; + plane.b = mat[7] + mat[5]; + plane.c = mat[11] + mat[9]; + plane.d = mat[15] + mat[13]; + break; + case cc.math.Plane.TOP: + plane.a = mat[3] - mat[1]; + plane.b = mat[7] - mat[5]; + plane.c = mat[11] - mat[9]; + plane.d = mat[15] - mat[13]; + break; + case cc.math.Plane.FAR: + plane.a = mat[3] - mat[2]; + plane.b = mat[7] - mat[6]; + plane.c = mat[11] - mat[10]; + plane.d = mat[15] - mat[14]; + break; + case cc.math.Plane.NEAR: + plane.a = mat[3] + mat[2]; + plane.b = mat[7] + mat[6]; + plane.c = mat[11] + mat[10]; + plane.d = mat[15] + mat[14]; + break; + default: + cc.log("cc.math.Matrix4.extractPlane: Invalid plane index"); + break; + } + var t = Math.sqrt(plane.a * plane.a + plane.b * plane.b + plane.c * plane.c); + plane.a /= t; + plane.b /= t; + plane.c /= t; + plane.d /= t; + return plane; + }; + + /** + * Take the rotation from a 4x4 transformation matrix, and return it as an axis and an angle (in radians) + * @returns {*|{axis: cc.math.Vec3, angle: number}} + */ + proto.toAxisAndAngle = function() { + /*Surely not this easy?*/ + var rotation = this.extractRotation(); + var temp = cc.math.Quaternion.rotationMatrix(rotation); + return temp.toAxisAndAngle(); + }; +})(cc); diff --git a/cocos2d/kazmath/plane.js b/cocos2d/kazmath/plane.js index 02acd8399b..94ab4e9b71 100644 --- a/cocos2d/kazmath/plane.js +++ b/cocos2d/kazmath/plane.js @@ -29,156 +29,109 @@ /** * @ignore */ -cc.KM_PLANE_LEFT = 0; +(function(cc){ + cc.math.Plane = function (a, b, c, d) { + if (a && b === undefined) { + this.a = a.a; + this.b = a.b; + this.c = a.c; + this.d = a.d; + } else { + this.a = a || 0; + this.b = b || 0; + this.c = c || 0; + this.d = d || 0; + } + }; + cc.kmPlane = cc.math.Plane; + var proto = cc.math.Plane.prototype; + + cc.math.Plane.LEFT = 0; + + cc.math.Plane.RIGHT = 1; + + cc.math.Plane.BOTTOM = 2; + + cc.math.Plane.TOP = 3; + + cc.math.Plane.NEAR = 4; + + cc.math.Plane.FAR = 5; + + cc.math.Plane.POINT_INFRONT_OF_PLANE = 0; + + cc.math.Plane.POINT_BEHIND_PLANE = 1; + + cc.math.Plane.POINT_ON_PLANE = 2; + + proto.dot = function(vec4){ //cc.kmPlaneDot + return (this.a * vec4.x + this.b * vec4.y + this.c * vec4.z + this.d * vec4.w); + }; + + proto.dotCoord = function(vec3) { //=cc.kmPlaneDotCoord + return (this.a * vec3.x + this.b * vec3.y + this.c * vec3.z + this.d); + }; + + proto.dotNormal = function(vec3) { //=cc.kmPlaneDotNormal + return (this.a * vec3.x + this.b * vec3.y + this.c * vec3.z); + }; + + cc.math.Plane.fromPointNormal = function(vec3, normal) { //cc.kmPlaneFromPointNormal + /* + Planea = Nx + Planeb = Ny + Planec = Nz + Planed = −N⋅P + */ + return new cc.math.Plane(normal.x, normal.y, normal.z, -normal.dot(vec3)); + }; + + cc.math.Plane.fromPoints = function(vec1, vec2, vec3) { //cc.kmPlaneFromPoints + /* + v = (B − A) × (C − A) + n = 1⁄|v| v + Outa = nx + Outb = ny + Outc = nz + Outd = −n⋅A + */ + var v1 = new cc.math.Vec3(vec2), v2 = new cc.math.Vec3(vec3), plane = new cc.math.Plane(); + v1.subtract(vec1); //Create the vectors for the 2 sides of the triangle + v2.subtract(vec1); + v1.cross(v2); // Use the cross product to get the normal + v1.normalize(); //Normalize it and assign to pOut.m_N + + plane.a = v1.x; + plane.b = v1.y; + plane.c = v1.z; + plane.d = v1.scale(-1.0).dot(vec1); + return plane; + }; + + proto.normalize = function(){ //cc.kmPlaneNormalize + var n = new cc.math.Vec3(this.a, this.b, this.c), l = 1.0 / n.length(); //Get 1/length + n.normalize(); //Normalize the vector and assign to pOut + this.a = n.x; + this.b = n.y; + this.c = n.z; + this.d = this.d * l; //Scale the D value and assign to pOut + return this; + }; + + proto.classifyPoint = function(vec3) { + // This function will determine if a point is on, in front of, or behind + // the plane. First we store the dot product of the plane and the point. + var distance = this.a * vec3.x + this.b * vec3.y + this.c * vec3.z + this.d; + + // Simply put if the dot product is greater than 0 then it is infront of it. + // If it is less than 0 then it is behind it. And if it is 0 then it is on it. + if(distance > 0.001) + return cc.math.Plane.POINT_INFRONT_OF_PLANE; + if(distance < -0.001) + return cc.math.Plane.POINT_BEHIND_PLANE; + return cc.math.Plane.POINT_ON_PLANE; + }; +})(cc); -cc.KM_PLANE_RIGHT = 1; - -cc.KM_PLANE_BOTTOM = 2; - -cc.KM_PLANE_TOP = 3; - -cc.KM_PLANE_NEAR = 4; - -cc.KM_PLANE_FAR = 5; - -cc.kmPlane = function (a, b, c, d) { - this.a = a || 0; - this.b = b || 0; - this.c = c || 0; - this.d = d || 0; -}; - -cc.POINT_INFRONT_OF_PLANE = 0; - -cc.POINT_BEHIND_PLANE = 1; - -cc.POINT_ON_PLANE = 2; - -cc.kmPlaneDot = function(pP, pV){ - //a*x + b*y + c*z + d*w - return (pP.a * pV.x + - pP.b * pV.y + - pP.c * pV.z + - pP.d * pV.w); -}; - -cc.kmPlaneDotCoord = function(pP, pV){ - return (pP.a * pV.x + - pP.b * pV.y + - pP.c * pV.z + pP.d); -}; - -cc.kmPlaneDotNormal = function(pP, pV){ - return (pP.a * pV.x + - pP.b * pV.y + - pP.c * pV.z); -}; - -cc.kmPlaneFromPointNormal = function(pOut, pPoint, pNormal){ - /* - Planea = Nx - Planeb = Ny - Planec = Nz - Planed = −N⋅P - */ - pOut.a = pNormal.x; - pOut.b = pNormal.y; - pOut.c = pNormal.z; - pOut.d = -cc.kmVec3Dot(pNormal, pPoint); - - return pOut; -}; - -/** - * Creates a plane from 3 points. The result is stored in pOut. - * pOut is returned. - */ -cc.kmPlaneFromPoints = function(pOut, p1, p2, p3){ - /* - v = (B − A) × (C − A) - n = 1⁄|v| v - Outa = nx - Outb = ny - Outc = nz - Outd = −n⋅A - */ - - var n = new cc.kmVec3(), v1 = new cc.kmVec3(), v2 = new cc.kmVec3(); - cc.kmVec3Subtract(v1, p2, p1); //Create the vectors for the 2 sides of the triangle - cc.kmVec3Subtract(v2, p3, p1); - cc.kmVec3Cross(n, v1, v2); //Use the cross product to get the normal - - cc.kmVec3Normalize(n, n); //Normalize it and assign to pOut.m_N - - pOut.a = n.x; - pOut.b = n.y; - pOut.c = n.z; - pOut.d = cc.kmVec3Dot(cc.kmVec3Scale(n, n, -1.0), p1); - - return pOut; -}; - -cc.kmPlaneIntersectLine = function(pOut, pP, pV1, pV2){ - throw "cc.kmPlaneIntersectLine() hasn't been implemented."; - /* - n = (Planea, Planeb, Planec) - d = V − U - Out = U − d⋅(Pd + n⋅U)⁄(d⋅n) [iff d⋅n ≠ 0] - */ - //var d = new cc.kmVec3(); - - //cc.kmVec3Subtract(d, pV2, pV1); //Get the direction vector - - //TODO: Continue here! - /*if (fabs(kmVec3Dot(&pP.m_N, &d)) > kmEpsilon) - { - //If we get here then the plane and line are parallel (i.e. no intersection) - pOut = nullptr; //Set to nullptr - - return pOut; - } */ - - //return null; -}; - -cc.kmPlaneNormalize = function(pOut, pP){ - var n = new cc.kmVec3(); - - n.x = pP.a; - n.y = pP.b; - n.z = pP.c; - - var l = 1.0 / cc.kmVec3Length(n); //Get 1/length - cc.kmVec3Normalize(n, n); //Normalize the vector and assign to pOut - - pOut.a = n.x; - pOut.b = n.y; - pOut.c = n.z; - - pOut.d = pP.d * l; //Scale the D value and assign to pOut - - return pOut; -}; - -cc.kmPlaneScale = function(pOut, pP, s){ - cc.log("cc.kmPlaneScale() has not been implemented."); -}; - -/** - * Returns POINT_INFRONT_OF_PLANE if pP is infront of pIn. Returns - * POINT_BEHIND_PLANE if it is behind. Returns POINT_ON_PLANE otherwise - */ -cc.kmPlaneClassifyPoint = function(pIn, pP){ - // This function will determine if a point is on, in front of, or behind - // the plane. First we store the dot product of the plane and the point. - var distance = pIn.a * pP.x + pIn.b * pP.y + pIn.c * pP.z + pIn.d; - - // Simply put if the dot product is greater than 0 then it is infront of it. - // If it is less than 0 then it is behind it. And if it is 0 then it is on it. - if(distance > 0.001) return cc.POINT_INFRONT_OF_PLANE; - if(distance < -0.001) return cc.POINT_BEHIND_PLANE; - - return cc.POINT_ON_PLANE; -}; diff --git a/cocos2d/kazmath/quaternion.js b/cocos2d/kazmath/quaternion.js index 1a863f372b..13e9d67ef6 100644 --- a/cocos2d/kazmath/quaternion.js +++ b/cocos2d/kazmath/quaternion.js @@ -26,463 +26,425 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/** - * The Quaternion class - * @param {Number} x - * @param {Number} y - * @param {Number} z - * @param {Number} w - * @constructor - */ -cc.kmQuaternion = function (x, y, z, w) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0; - this.w = w || 0; -}; - -///< Returns pOut, sets pOut to the conjugate of pIn -cc.kmQuaternionConjugate = function (pOut, pIn) { - pOut.x = -pIn.x; - pOut.y = -pIn.y; - pOut.z = -pIn.z; - pOut.w = pIn.w; - - return pOut; -}; - -///< Returns the dot product of the 2 quaternions -cc.kmQuaternionDot = function (q1, q2) { - // A dot B = B dot A = AtBt + AxBx + AyBy + AzBz - return (q1.w * q2.w + - q1.x * q2.x + - q1.y * q2.y + - q1.z * q2.z); -}; - -///< Returns the exponential of the quaternion -cc.kmQuaternionExp = function (pOut, pIn) { - //TODO not implement - //cc.assert(0); - return pOut; -}; - -///< Makes the passed quaternion an identity quaternion -cc.kmQuaternionIdentity = function (pOut) { - pOut.x = 0.0; - pOut.y = 0.0; - pOut.z = 0.0; - pOut.w = 1.0; - - return pOut; -}; - -///< Returns the inverse of the passed Quaternion -cc.kmQuaternionInverse = function (pOut, pIn) { - var l = cc.kmQuaternionLength(pIn); - var tmp = new cc.kmQuaternion(); - - if (Math.abs(l) > cc.kmEpsilon) { - pOut.x = 0.0; - pOut.y = 0.0; - pOut.z = 0.0; - pOut.w = 0.0; - return pOut; - } - - ///Get the conjugute and divide by the length - cc.kmQuaternionScale(pOut, - cc.kmQuaternionConjugate(tmp, pIn), 1.0 / l); - - return pOut; -}; - -///< Returns true if the quaternion is an identity quaternion -cc.kmQuaternionIsIdentity = function (pIn) { - return (pIn.x == 0.0 && pIn.y == 0.0 && pIn.z == 0.0 && - pIn.w == 1.0); -}; - -///< Returns the length of the quaternion -cc.kmQuaternionLength = function (pIn) { - return Math.sqrt(cc.kmQuaternionLengthSq(pIn)); -}; - -///< Returns the length of the quaternion squared (prevents a sqrt) -cc.kmQuaternionLengthSq = function (pIn) { - return pIn.x * pIn.x + pIn.y * pIn.y + - pIn.z * pIn.z + pIn.w * pIn.w; -}; - -///< Returns the natural logarithm -cc.kmQuaternionLn = function (pOut, pIn) { - /* - A unit quaternion, is defined by: - Q == (cos(theta), sin(theta) * v) where |v| = 1 - The natural logarithm of Q is, ln(Q) = (0, theta * v) +(function(cc) { + /** + * The Quaternion class + * @param {Number|cc.math.Quaternion} [x=0] + * @param {Number} [y=0] + * @param {Number} [z=0] + * @param {Number} [w=0] + * @constructor */ - //assert(0); - //TODO not implement - return pOut; -}; - -///< Multiplies 2 quaternions together -cc.kmQuaternionMultiply = function (pOut, q1, q2) { - pOut.w = q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z; - pOut.x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y; - pOut.y = q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z; - pOut.z = q1.w * q2.z + q1.z * q2.w + q1.x * q2.y - q1.y * q2.x; - - return pOut; -}; - -///< Normalizes a quaternion -cc.kmQuaternionNormalize = function (pOut, pIn) { - var length = cc.kmQuaternionLength(pIn); - if(Math.abs(length) <= cc.kmEpsilon) - throw "cc.kmQuaternionNormalize(): pIn is an invalid value"; - cc.kmQuaternionScale(pOut, pIn, 1.0 / length); - - return pOut; -}; - -///< Rotates a quaternion around an axis -cc.kmQuaternionRotationAxis = function (pOut, pV, angle) { - var rad = angle * 0.5; - var scale = Math.sin(rad); - - pOut.w = Math.cos(rad); - pOut.x = pV.x * scale; - pOut.y = pV.y * scale; - pOut.z = pV.z * scale; - - return pOut; -}; - -///< Creates a quaternion from a rotation matrix -cc.kmQuaternionRotationMatrix = function (pOut, pIn) { - /* - Note: The OpenGL matrices are transposed from the description below - taken from the Matrix and Quaternion FAQ - - if ( mat[0] > mat[5] && mat[0] > mat[10] ) { // Column 0: - S = sqrt( 1.0 + mat[0] - mat[5] - mat[10] ) * 2; - X = 0.25 * S; - Y = (mat[4] + mat[1] ) / S; - Z = (mat[2] + mat[8] ) / S; - W = (mat[9] - mat[6] ) / S; - } else if ( mat[5] > mat[10] ) { // Column 1: - S = sqrt( 1.0 + mat[5] - mat[0] - mat[10] ) * 2; - X = (mat[4] + mat[1] ) / S; - Y = 0.25 * S; - Z = (mat[9] + mat[6] ) / S; - W = (mat[2] - mat[8] ) / S; - } else { // Column 2: - S = sqrt( 1.0 + mat[10] - mat[0] - mat[5] ) * 2; - X = (mat[2] + mat[8] ) / S; - Y = (mat[9] + mat[6] ) / S; - Z = 0.25 * S; - W = (mat[4] - mat[1] ) / S; - } - */ - var x, y, z, w; - var m4x4 = []; - var scale = 0.0; - var diagonal = 0.0; - - if (!pIn) { - return null; - } - - /* 0 3 6 - 1 4 7 - 2 5 8 - - 0 1 2 3 - 4 5 6 7 - 8 9 10 11 - 12 13 14 15*/ - - m4x4[0] = pIn.mat[0]; - m4x4[1] = pIn.mat[3]; - m4x4[2] = pIn.mat[6]; - m4x4[4] = pIn.mat[1]; - m4x4[5] = pIn.mat[4]; - m4x4[6] = pIn.mat[7]; - m4x4[8] = pIn.mat[2]; - m4x4[9] = pIn.mat[5]; - m4x4[10] = pIn.mat[8]; - m4x4[15] = 1; - var pMatrix = m4x4[0]; - - diagonal = pMatrix[0] + pMatrix[5] + pMatrix[10] + 1; - - if (diagonal > cc.kmEpsilon) { - // Calculate the scale of the diagonal - scale = Math.sqrt(diagonal) * 2; - - // Calculate the x, y, x and w of the quaternion through the respective equation - x = ( pMatrix[9] - pMatrix[6] ) / scale; - y = ( pMatrix[2] - pMatrix[8] ) / scale; - z = ( pMatrix[4] - pMatrix[1] ) / scale; - w = 0.25 * scale; - } else { - // If the first element of the diagonal is the greatest value - if (pMatrix[0] > pMatrix[5] && pMatrix[0] > pMatrix[10]) { - // Find the scale according to the first element, and double that value - scale = Math.sqrt(1.0 + pMatrix[0] - pMatrix[5] - pMatrix[10]) * 2.0; - - // Calculate the x, y, x and w of the quaternion through the respective equation - x = 0.25 * scale; - y = (pMatrix[4] + pMatrix[1] ) / scale; - z = (pMatrix[2] + pMatrix[8] ) / scale; - w = (pMatrix[9] - pMatrix[6] ) / scale; - } - // Else if the second element of the diagonal is the greatest value - else if (pMatrix[5] > pMatrix[10]) { - // Find the scale according to the second element, and double that value - scale = Math.sqrt(1.0 + pMatrix[5] - pMatrix[0] - pMatrix[10]) * 2.0; - - // Calculate the x, y, x and w of the quaternion through the respective equation - x = (pMatrix[4] + pMatrix[1] ) / scale; - y = 0.25 * scale; - z = (pMatrix[9] + pMatrix[6] ) / scale; - w = (pMatrix[2] - pMatrix[8] ) / scale; + cc.math.Quaternion = function (x, y, z, w) { + if (x && y === undefined) { + this.x = x.x; + this.y = x.y; + this.z = x.z; + this.w = x.w; } else { - // Else the third element of the diagonal is the greatest value - - // Find the scale according to the third element, and double that value - scale = Math.sqrt(1.0 + pMatrix[10] - pMatrix[0] - pMatrix[5]) * 2.0; - - // Calculate the x, y, x and w of the quaternion through the respective equation - x = (pMatrix[2] + pMatrix[8] ) / scale; - y = (pMatrix[9] + pMatrix[6] ) / scale; - z = 0.25 * scale; - w = (pMatrix[4] - pMatrix[1] ) / scale; + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + this.w = w || 0; } - } - - pOut.x = x; - pOut.y = y; - pOut.z = z; - pOut.w = w; - - return pOut; -}; - -///< Create a quaternion from yaw, pitch and roll -cc.kmQuaternionRotationYawPitchRoll = function (pOut, yaw, pitch, roll) { - var ex, ey, ez; // temp half euler angles - var cr, cp, cy, sr, sp, sy, cpcy, spsy; // temp vars in roll,pitch yaw - - ex = cc.kmDegreesToRadians(pitch) / 2.0; // convert to rads and half them - ey = cc.kmDegreesToRadians(yaw) / 2.0; - ez = cc.kmDegreesToRadians(roll) / 2.0; + }; + cc.kmQuaternion = cc.math.Quaternion; + var proto = cc.math.Quaternion.prototype; - cr = Math.cos(ex); - cp = Math.cos(ey); - cy = Math.cos(ez); - - sr = Math.sin(ex); - sp = Math.sin(ey); - sy = Math.sin(ez); - - cpcy = cp * cy; - spsy = sp * sy; - - pOut.w = cr * cpcy + sr * spsy; - - pOut.x = sr * cpcy - cr * spsy; - pOut.y = cr * sp * cy + sr * cp * sy; - pOut.z = cr * cp * sy - sr * sp * cy; - - cc.kmQuaternionNormalize(pOut, pOut); - - return pOut; -}; - -///< Interpolate between 2 quaternions -cc.kmQuaternionSlerp = function (pOut, q1, q2, t) { - /*float CosTheta = Q0.DotProd(Q1); - float Theta = acosf(CosTheta); - float SinTheta = sqrtf(1.0f-CosTheta*CosTheta); - - float Sin_T_Theta = sinf(T*Theta)/SinTheta; - float Sin_OneMinusT_Theta = sinf((1.0f-T)*Theta)/SinTheta; - - Quaternion Result = Q0*Sin_OneMinusT_Theta; - Result += (Q1*Sin_T_Theta); - - return Result;*/ - - if (q1.x == q2.x && - q1.y == q2.y && - q1.z == q2.z && - q1.w == q2.w) { - - pOut.x = q1.x; - pOut.y = q1.y; - pOut.z = q1.z; - pOut.w = q1.w; - - return pOut; - } - - var ct = cc.kmQuaternionDot(q1, q2); - var theta = Math.acos(ct); - var st = Math.sqrt(1.0 - cc.kmSQR(ct)); - - var stt = Math.sin(t * theta) / st; - var somt = Math.sin((1.0 - t) * theta) / st; - - var temp = new cc.kmQuaternion(), temp2 = new cc.kmQuaternion(); - cc.kmQuaternionScale(temp, q1, somt); - cc.kmQuaternionScale(temp2, q2, stt); - cc.kmQuaternionAdd(pOut, temp, temp2); - - return pOut; -}; - -///< Get the axis and angle of rotation from a quaternion -cc.kmQuaternionToAxisAngle = function (pIn, pAxis, pAngle) { - var tempAngle; // temp angle - var scale; // temp vars - - tempAngle = Math.acos(pIn.w); - scale = Math.sqrt(cc.kmSQR(pIn.x) + cc.kmSQR(pIn.y) + cc.kmSQR(pIn.z)); - - if (((scale > -cc.kmEpsilon) && scale < cc.kmEpsilon) - || (scale < 2 * cc.kmPI + cc.kmEpsilon && scale > 2 * cc.kmPI - cc.kmEpsilon)) { // angle is 0 or 360 so just simply set axis to 0,0,1 with angle 0 - pAngle = 0.0; - - pAxis.x = 0.0; - pAxis.y = 0.0; - pAxis.z = 1.0; - } else { - pAngle = tempAngle * 2.0; // angle in radians - - pAxis.x = pIn.x / scale; - pAxis.y = pIn.y / scale; - pAxis.z = pIn.z / scale; - cc.kmVec3Normalize(pAxis, pAxis); - } -}; - -///< Scale a quaternion -cc.kmQuaternionScale = function (pOut, pIn, s) { - pOut.x = pIn.x * s; - pOut.y = pIn.y * s; - pOut.z = pIn.z * s; - pOut.w = pIn.w * s; - - return pOut; -}; - -cc.kmQuaternionAssign = function (pOut, pIn) { - pOut.x = pIn.x; - pOut.y = pIn.y; - pOut.z = pIn.z; - pOut.w = pIn.w; - - return pOut; -}; + /** + * Sets the conjugate of quaternion to self + * @param {cc.math.Quaternion} quaternion + */ + proto.conjugate = function (quaternion) { //= cc.kmQuaternionConjugate + this.x = -quaternion.x; + this.y = -quaternion.y; + this.z = -quaternion.z; + this.w = quaternion.w; + return this; + }; + + /** + * Returns the dot product of the current quaternion and parameter quaternion + * @param quaternion + * @returns {number} + */ + proto.dot = function(quaternion) { // = cc.kmQuaternionDot + // A dot B = B dot A = AtBt + AxBx + AyBy + AzBz + return (this.w * quaternion.w + this.x * quaternion.x + this.y * quaternion.y + this.z * quaternion.z); + }; + + /** + * Returns the exponential of the quaternion, this function doesn't implemented. + * @returns {cc.math.Quaternion} + */ + proto.exponential = function(){ //=cc.kmQuaternionExp + return this; + }; -cc.kmQuaternionAdd = function (pOut, pQ1, pQ2) { - pOut.x = pQ1.x + pQ2.x; - pOut.y = pQ1.y + pQ2.y; - pOut.z = pQ1.z + pQ2.z; - pOut.w = pQ1.w + pQ2.w; - - return pOut; -}; - -/** Adapted from the OGRE engine! - - Gets the shortest arc quaternion to rotate this vector to the destination - vector. - @remarks - If you call this with a dest vector that is close to the inverse - of this vector, we will rotate 180 degrees around the 'fallbackAxis' - (if specified, or a generated axis if not) since in this case - ANY axis of rotation is valid. - */ -cc.kmQuaternionRotationBetweenVec3 = function (pOut, vec1, vec2, fallback) { - var v1 = new cc.kmVec3(), v2 = new cc.kmVec3(); - var a; + /** + * Makes the current quaternion an identity quaternion + */ + proto.identity = function(){ //=cc.kmQuaternionIdentity + this.x = 0.0; + this.y = 0.0; + this.z = 0.0; + this.w = 1.0; + return this; + }; + + /** + * Inverses the value of current Quaternion + */ + proto.inverse = function(){ //=cc.kmQuaternionInverse + var len = this.length(); + if (Math.abs(len) > cc.math.EPSILON) { + this.x = 0.0; + this.y = 0.0; + this.z = 0.0; + this.w = 0.0; + return this; + } - cc.kmVec3Assign(v1, vec1); - cc.kmVec3Assign(v2, vec2); + ///Get the conjugute and divide by the length + this.conjugate(this).scale(1.0 / len); + return this; + }; - cc.kmVec3Normalize(v1, v1); - cc.kmVec3Normalize(v2, v2); + /** + * Returns true if the quaternion is an identity quaternion + * @returns {boolean} + */ + proto.isIdentity = function(){ //=cc.kmQuaternionIsIdentity + return (this.x == 0.0 && this.y == 0.0 && this.z == 0.0 && this.w == 1.0); + }; - a = cc.kmVec3Dot(v1, v2); + /** + * Returns the length of the quaternion + * @returns {number} + */ + proto.length = function() { //=cc.kmQuaternionLength + return Math.sqrt(this.lengthSq()); + }; - if (a >= 1.0) { - cc.kmQuaternionIdentity(pOut); - return pOut; - } + /** + * Returns the length of the quaternion squared (prevents a sqrt) + * @returns {number} + */ + proto.lengthSq = function() { //=cc.kmQuaternionLengthSq + return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; + }; + + /** + * Uses current quaternion multiplies other quaternion. + * @param {cc.math.Quaternion} quaternion + * @returns {cc.math.Quaternion} + */ + proto.multiply = function(quaternion) { //cc.kmQuaternionMultiply + var x = this.x, y = this.y, z = this.z, w = this.w; + this.w = w * quaternion.w - x * quaternion.x - y * quaternion.y - z * quaternion.z; + this.x = w * quaternion.x + x * quaternion.w + y * quaternion.z - z * quaternion.y; + this.y = w * quaternion.y + y * quaternion.w + z * quaternion.x - x * quaternion.z; + this.z = w * quaternion.z + z * quaternion.w + x * quaternion.y - y * quaternion.x; + return this; + }; + + /** + * Normalizes a quaternion + * @returns {cc.math.Quaternion} + */ + proto.normalize = function(){ //=cc.kmQuaternionNormalize + var length = this.length(); + if (Math.abs(length) <= cc.math.EPSILON) + throw "current quaternion is an invalid value"; + this.scale(1.0 / length); + return this; + }; + + /** + * Rotates a quaternion around an axis and an angle + * @param {cc.math.Vec3} axis + * @param {Number} angle + */ + proto.rotationAxis = function(axis, angle){ //cc.kmQuaternionRotationAxis + var rad = angle * 0.5, scale = Math.sin(rad); + this.w = Math.cos(rad); + this.x = axis.x * scale; + this.y = axis.y * scale; + this.z = axis.z * scale; + return this; + }; + + /** + * Creates a quaternion from a rotation matrix + * @param mat3 + * @returns {*} + */ + cc.math.Quaternion.rotationMatrix = function (mat3) { //cc.kmQuaternionRotationMatrix + if (!mat3) + return null; + + var x, y, z, w; + var m4x4 = [], mat = mat3.mat, scale = 0.0; + + /* 0 3 6 + 1 4 7 + 2 5 8 + + 0 1 2 3 + 4 5 6 7 + 8 9 10 11 + 12 13 14 15*/ + m4x4[0] = mat[0]; + m4x4[1] = mat[3]; + m4x4[2] = mat[6]; + m4x4[4] = mat[1]; + m4x4[5] = mat[4]; + m4x4[6] = mat[7]; + m4x4[8] = mat[2]; + m4x4[9] = mat[5]; + m4x4[10] = mat[8]; + m4x4[15] = 1; + var pMatrix = m4x4[0]; + + var diagonal = pMatrix[0] + pMatrix[5] + pMatrix[10] + 1; + if (diagonal > cc.math.EPSILON) { + // Calculate the scale of the diagonal + scale = Math.sqrt(diagonal) * 2; - if (a < (1e-6 - 1.0)) { - if (Math.abs(cc.kmVec3LengthSq(fallback)) < cc.kmEpsilon) { - cc.kmQuaternionRotationAxis(pOut, fallback, cc.kmPI); + // Calculate the x, y, x and w of the quaternion through the respective equation + x = ( pMatrix[9] - pMatrix[6] ) / scale; + y = ( pMatrix[2] - pMatrix[8] ) / scale; + z = ( pMatrix[4] - pMatrix[1] ) / scale; + w = 0.25 * scale; } else { - var axis = new cc.kmVec3(); - var X = new cc.kmVec3(); - X.x = 1.0; - X.y = 0.0; - X.z = 0.0; - - cc.kmVec3Cross(axis, X, vec1); - - //If axis is zero - if (Math.abs(cc.kmVec3LengthSq(axis)) < cc.kmEpsilon) { - var Y = new cc.kmVec3(); - Y.x = 0.0; - Y.y = 1.0; - Y.z = 0.0; - - cc.kmVec3Cross(axis, Y, vec1); + // If the first element of the diagonal is the greatest value + if (pMatrix[0] > pMatrix[5] && pMatrix[0] > pMatrix[10]) { + // Find the scale according to the first element, and double that value + scale = Math.sqrt(1.0 + pMatrix[0] - pMatrix[5] - pMatrix[10]) * 2.0; + + // Calculate the x, y, x and w of the quaternion through the respective equation + x = 0.25 * scale; + y = (pMatrix[4] + pMatrix[1] ) / scale; + z = (pMatrix[2] + pMatrix[8] ) / scale; + w = (pMatrix[9] - pMatrix[6] ) / scale; + } + // Else if the second element of the diagonal is the greatest value + else if (pMatrix[5] > pMatrix[10]) { + // Find the scale according to the second element, and double that value + scale = Math.sqrt(1.0 + pMatrix[5] - pMatrix[0] - pMatrix[10]) * 2.0; + + // Calculate the x, y, x and w of the quaternion through the respective equation + x = (pMatrix[4] + pMatrix[1] ) / scale; + y = 0.25 * scale; + z = (pMatrix[9] + pMatrix[6] ) / scale; + w = (pMatrix[2] - pMatrix[8] ) / scale; + } else { + // Else the third element of the diagonal is the greatest value + + // Find the scale according to the third element, and double that value + scale = Math.sqrt(1.0 + pMatrix[10] - pMatrix[0] - pMatrix[5]) * 2.0; + + // Calculate the x, y, x and w of the quaternion through the respective equation + x = (pMatrix[2] + pMatrix[8] ) / scale; + y = (pMatrix[9] + pMatrix[6] ) / scale; + z = 0.25 * scale; + w = (pMatrix[4] - pMatrix[1] ) / scale; } - - cc.kmVec3Normalize(axis, axis); - cc.kmQuaternionRotationAxis(pOut, axis, cc.kmPI); } - } else { - var s = Math.sqrt((1 + a) * 2); - var invs = 1 / s; - - var c = new cc.kmVec3(); - cc.kmVec3Cross(c, v1, v2); - - pOut.x = c.x * invs; - pOut.y = c.y * invs; - pOut.z = c.z * invs; - pOut.w = s * 0.5; - - cc.kmQuaternionNormalize(pOut, pOut); - } - return pOut; -}; - -cc.kmQuaternionMultiplyVec3 = function (pOut, q, v) { - var uv = new cc.kmVec3(), uuv = new cc.kmVec3(), qvec = new cc.kmVec3(); - - qvec.x = q.x; - qvec.y = q.y; - qvec.z = q.z; + return new cc.math.Quaternion(x, y, z, w); + }; + + /** + * Create a quaternion from yaw, pitch and roll + * @param yaw + * @param pitch + * @param roll + * @returns {cc.math.Quaternion} + */ + cc.math.Quaternion.rotationYawPitchRoll = function (yaw, pitch, roll) { //cc.kmQuaternionRotationYawPitchRoll + var ex, ey, ez; // temp half euler angles + var cr, cp, cy, sr, sp, sy, cpcy, spsy; // temp vars in roll,pitch yaw + + ex = cc.degreesToRadians(pitch) / 2.0; // convert to rads and half them + ey = cc.degreesToRadians(yaw) / 2.0; + ez = cc.degreesToRadians(roll) / 2.0; + + cr = Math.cos(ex); + cp = Math.cos(ey); + cy = Math.cos(ez); + + sr = Math.sin(ex); + sp = Math.sin(ey); + sy = Math.sin(ez); + + cpcy = cp * cy; + spsy = sp * sy; + + var ret = new cc.math.Quaternion(); + ret.w = cr * cpcy + sr * spsy; + ret.x = sr * cpcy - cr * spsy; + ret.y = cr * sp * cy + sr * cp * sy; + ret.z = cr * cp * sy - sr * sp * cy; + ret.normalize(); + return ret; + }; + + /** + * Interpolate with other quaternions + * @param {cc.math.Quaternion} quaternion + * @param {Number} t + * @returns {cc.math.Quaternion} + */ + proto.slerp = function(quaternion, t) { //=cc.kmQuaternionSlerp + if (this.x === quaternion.x && this.y === quaternion.y && this.z === quaternion.z && this.w === quaternion.w) { + return this; + } + var ct = this.dot(quaternion), theta = Math.acos(ct), st = Math.sqrt(1.0 - cc.math.square(ct)); + var stt = Math.sin(t * theta) / st, somt = Math.sin((1.0 - t) * theta) / st; + var temp2 = new cc.math.Quaternion(quaternion); + this.scale(somt); + temp2.scale(stt); + this.add(temp2); + return this; + }; + + /** + * Get the axis and angle of rotation from a quaternion + * @returns {{axis: cc.math.Vec3, angle: number}} + */ + proto.toAxisAndAngle = function(){ //=cc.kmQuaternionToAxisAngle + var tempAngle; // temp angle + var scale; // temp vars + var retAngle, retAxis = new cc.math.Vec3(); + + tempAngle = Math.acos(this.w); + scale = Math.sqrt(cc.math.square(this.x) + cc.math.square(this.y) + cc.math.square(this.z)); + + if (((scale > -cc.math.EPSILON) && scale < cc.math.EPSILON) + || (scale < 2 * Math.PI + cc.math.EPSILON && scale > 2 * Math.PI - cc.math.EPSILON)) { // angle is 0 or 360 so just simply set axis to 0,0,1 with angle 0 + retAngle = 0.0; + retAxis.x = 0.0; + retAxis.y = 0.0; + retAxis.z = 1.0; + } else { + retAngle = tempAngle * 2.0; // angle in radians + retAxis.x = this.x / scale; + retAxis.y = this.y / scale; + retAxis.z = this.z / scale; + retAxis.normalize(); + } + return {axis: retAxis, angle: retAngle}; + }; - cc.kmVec3Cross(uv, qvec, v); - cc.kmVec3Cross(uuv, qvec, uv); + /** + * Scale a quaternion + * @param {Number} scale + */ + proto.scale = function(scale) { //cc.kmQuaternionScale + this.x *= scale; + this.y *= scale; + this.z *= scale; + this.w *= scale; + return this; + }; + + /** + * Assign current quaternion value from a quaternion. + * @param {cc.math.Quaternion} quaternion + * @returns {cc.math.Quaternion} current quaternion + */ + proto.assignFrom = function(quaternion){ //=cc.kmQuaternionAssign + this.x = quaternion.x; + this.y = quaternion.y; + this.z = quaternion.z; + this.w = quaternion.w; + return this; + }; + + /** + * Adds other quaternion + * @param {cc.math.Quaternion} quaternion + * @returns {cc.math.Quaternion} + */ + proto.add = function(quaternion) { //cc.kmQuaternionAdd + this.x += quaternion.x; + this.y += quaternion.y; + this.z += quaternion.z; + this.w += quaternion.w; + return this; + }; + + /** + *

+ * Adapted from the OGRE engine!
+ * Gets the shortest arc quaternion to rotate this vector to the destination vector.
+ * @remarks
+ * If you call this with a destination vector that is close to the inverse
+ * of this vector, we will rotate 180 degrees around the 'fallbackAxis'
+ * (if specified, or a generated axis if not) since in this case ANY axis of rotation is valid. + *

+ * @param {cc.math.Vec3} vec1 + * @param {cc.math.Vec3} vec2 + * @param {cc.math.Vec3} fallback + * @returns {cc.math.Quaternion} + */ + cc.math.Quaternion.rotationBetweenVec3 = function(vec1, vec2, fallback) { //cc.kmQuaternionRotationBetweenVec3 + var v1 = new cc.math.Vec3(vec1), v2 = new cc.math.Vec3(vec2); + v1.normalize(); + v2.normalize(); + var a = v1.dot(v2), quaternion = new cc.math.Quaternion(); + + if (a >= 1.0) { + quaternion.identity(); + return quaternion; + } - cc.kmVec3Scale(uv, uv, (2.0 * q.w)); - cc.kmVec3Scale(uuv, uuv, 2.0); + if (a < (1e-6 - 1.0)) { + if (Math.abs(fallback.lengthSq()) < cc.math.EPSILON) { + quaternion.rotationAxis(fallback, Math.PI); + } else { + var axis = new cc.math.Vec3(1.0, 0.0, 0.0); + axis.cross(vec1); + + //If axis is zero + if (Math.abs(axis.lengthSq()) < cc.math.EPSILON) { + axis.fill(0.0, 1.0, 0.0); + axis.cross(vec1); + } + axis.normalize(); + quaternion.rotationAxis(axis, Math.PI); + } + } else { + var s = Math.sqrt((1 + a) * 2), invs = 1 / s; + v1.cross(v2); + quaternion.x = v1.x * invs; + quaternion.y = v1.y * invs; + quaternion.z = v1.z * invs; + quaternion.w = s * 0.5; + quaternion.normalize(); + } + return quaternion; + }; - cc.kmVec3Add(pOut, v, uv); - cc.kmVec3Add(pOut, pOut, uuv); + /** + * Current quaternion multiplies a vec3 + * @param {cc.math.Vec3} vec + * @returns {cc.math.Vec3} + */ + proto.multiplyVec3 = function(vec){ //=cc.kmQuaternionMultiplyVec3 + var x = this.x, y = this.y, z = this.z, retVec = new cc.math.Vec3(vec); + var uv = new cc.math.Vec3(x, y, z), uuv = new cc.math.Vec3(x, y, z); + uv.cross(vec); + uuv.cross(uv); + uv.scale((2.0 * q.w)); + uuv.scale(2.0); + + retVec.add(uv); + retVec.add(uuv); + return retVec; + }; +})(cc); - return pOut; -}; diff --git a/cocos2d/kazmath/ray2.js b/cocos2d/kazmath/ray2.js index e9edbcd13d..5a29794e88 100644 --- a/cocos2d/kazmath/ray2.js +++ b/cocos2d/kazmath/ray2.js @@ -26,138 +26,115 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -cc.kmRay2 = function(start, dir){ - this.start = start || new cc.kmVec2(); - this.start = start || new cc.kmVec2(); -}; - -cc.kmRay2Fill = function(ray, px, py,vx,vy){ - ray.start.x = px; - ray.start.y = py; - ray.dir.x = vx; - ray.dir.y = vy; -}; - -cc.kmRay2IntersectLineSegment = function(ray, p1, p2, intersection){ - var x1 = ray.start.x; - var y1 = ray.start.y; - var x2 = ray.start.x + ray.dir.x; - var y2 = ray.start.y + ray.dir.y; - var x3 = p1.x; - var y3 = p1.y; - var x4 = p2.x; - var y4 = p2.y; - - var denom = (y4 -y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); - var ua, x, y; - //If denom is zero, the lines are parallel - if(denom > -cc.kmEpsilon && denom < cc.kmEpsilon) { - return cc.KM_FALSE; - } +(function(cc){ + cc.math.Ray2 = function (start, dir) { // = cc.kmRay2 + this.start = start || new cc.math.Vec2(); + this.dir = dir || new cc.math.Vec2(); + }; + + cc.math.Ray2.prototype.fill = function (px, py, vx, vy) { // = cc.kmRay2Fill + this.start.x = px; + this.start.y = py; + this.dir.x = vx; + this.dir.y = vy; + }; + + cc.math.Ray2.prototype.intersectLineSegment = function (p1, p2, intersection) { // = cc.kmRay2IntersectLineSegment + var x1 = this.start.x, y1 = this.start.y; + var x2 = this.start.x + this.dir.x, y2 = this.start.y + this.dir.y; + var x3 = p1.x, y3 = p1.y; + var x4 = p2.x, y4 = p2.y; + + var denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); + var ua, x, y; + //If denom is zero, the lines are parallel + if (denom > -cc.math.EPSILON && denom < cc.math.EPSILON) + return false; + + ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom; + //var ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom; + + x = x1 + ua * (x2 - x1); + y = y1 + ua * (y2 - y1); + + if (x < Math.min(p1.x, p2.x) - cc.math.EPSILON || + x > Math.max(p1.x, p2.x) + cc.math.EPSILON || + y < Math.min(p1.y, p2.y) - cc.math.EPSILON || + y > Math.max(p1.y, p2.y) + cc.math.EPSILON) { + //Outside of line + //printf("Outside of line, %f %f (%f %f)(%f, %f)\n", x, y, p1.x, p1.y, p2.x, p2.y); + return false; + } - ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom; -// var ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom; + if (x < Math.min(x1, x2) - cc.math.EPSILON || + x > Math.max(x1, x2) + cc.math.EPSILON || + y < Math.min(y1, y2) - cc.math.EPSILON || + y > Math.max(y1, y2) + cc.math.EPSILON) { + //printf("Outside of ray, %f %f (%f %f)(%f, %f)\n", x, y, x1, y1, x2, y2); + return false; + } - x = x1 + ua * (x2 - x1); - y = y1 + ua * (y2 - y1); + intersection.x = x; + intersection.y = y; + return true; + }; - if(x < cc.kmMin(p1.x, p2.x) - cc.kmEpsilon || - x > cc.kmMax(p1.x, p2.x) + cc.kmEpsilon || - y < cc.kmMin(p1.y, p2.y) - cc.kmEpsilon || - y > cc.kmMax(p1.y, p2.y) + cc.kmEpsilon) { - //Outside of line - //printf("Outside of line, %f %f (%f %f)(%f, %f)\n", x, y, p1.x, p1.y, p2.x, p2.y); - return cc.KM_FALSE; - } + function calculate_line_normal(p1, p2, normalOut){ + var tmp = new cc.math.Vec2(p2); + tmp.subtract(p1); - if(x < cc.kmMin(x1, x2) - cc.kmEpsilon || - x > cc.kmMax(x1, x2) + cc.kmEpsilon || - y < cc.kmMin(y1, y2) - cc.kmEpsilon || - y > cc.kmMax(y1, y2) + cc.kmEpsilon) { - //printf("Outside of ray, %f %f (%f %f)(%f, %f)\n", x, y, x1, y1, x2, y2); - return cc.KM_FALSE; + normalOut.x = -tmp.y; + normalOut.y = tmp.x; + normalOut.normalize(); + //TODO: should check that the normal is pointing out of the triangle } - intersection.x = x; - intersection.y = y; - - return cc.KM_TRUE; -}; - -cc.calculate_line_normal = function(p1, p2, normal_out){ - var tmp = new cc.kmVec2(); - cc.kmVec2Subtract(tmp, p2, p1); //Get direction vector - - normal_out.x = -tmp.y; - normal_out.y = tmp.x; - cc.kmVec2Normalize(normal_out, normal_out); - - //TODO: should check that the normal is pointing out of the triangle -}; - -cc.kmRay2IntersectTriangle = function(ray, p1, p2, p3, intersection, normal_out){ - var intersect = new cc.kmVec2(); - var final_intersect = new cc.kmVec2(); - var normal = new cc.kmVec2(); - var distance = 10000.0; - var intersected = cc.KM_FALSE; - - var tmp,this_distance; - - if(cc.kmRay2IntersectLineSegment(ray, p1, p2, intersect)) { - tmp = new cc.kmVec2(); - - intersected = cc.KM_TRUE; - this_distance = cc.kmVec2Length(cc.kmVec2Subtract(tmp, intersect, ray.start)); - if(this_distance < distance) { - final_intersect.x = intersect.x; - final_intersect.y = intersect.y; - distance = this_distance; - - cc.calculate_line_normal(p1, p2, normal); + cc.math.Ray2.prototype.intersectTriangle = function(p1, p2, p3, intersection, normal_out){ + var intersect = new cc.math.Vec2(), final_intersect = new cc.math.Vec2(); + var normal = new cc.math.Vec2(), distance = 10000.0, intersected = false; + var this_distance; + + if(this.intersectLineSegment(p1, p2, intersect)) { + intersected = true; + this_distance = intersect.subtract(this.start).length(); + if(this_distance < distance) { + final_intersect.x = intersect.x; + final_intersect.y = intersect.y; + distance = this_distance; + calculate_line_normal(p1, p2, normal); + } } - } - - if(cc.kmRay2IntersectLineSegment(ray, p2, p3, intersect)) { - tmp = new cc.kmVec2(); - intersected = cc.KM_TRUE; - this_distance = cc.kmVec2Length(cc.kmVec2Subtract(tmp, intersect, ray.start)); - if(this_distance < distance) { - final_intersect.x = intersect.x; - final_intersect.y = intersect.y; - distance = this_distance; - - cc.calculate_line_normal(p2, p3, normal); + if(this.intersectLineSegment(p2, p3, intersect)) { + intersected = true; + this_distance = intersect.subtract(this.start).length(); + if(this_distance < distance) { + final_intersect.x = intersect.x; + final_intersect.y = intersect.y; + distance = this_distance; + calculate_line_normal(p2, p3, normal); + } } - } - - if(cc.kmRay2IntersectLineSegment(ray, p3, p1, intersect)) { - tmp = new cc.kmVec2(); - intersected = cc.KM_TRUE; - this_distance = cc.kmVec2Length(cc.kmVec2Subtract(tmp, intersect, ray.start)); - if(this_distance < distance) { - final_intersect.x = intersect.x; - final_intersect.y = intersect.y; - distance = this_distance; - - cc.calculate_line_normal(p3, p1, normal); + if(this.intersectLineSegment(p3, p1, intersect)) { + intersected = true; + this_distance = intersect.subtract(this.start).length(); + if(this_distance < distance) { + final_intersect.x = intersect.x; + final_intersect.y = intersect.y; + distance = this_distance; + calculate_line_normal(p3, p1, normal); + } } - } - if(intersected) { - intersection.x = final_intersect.x; - intersection.y = final_intersect.y; - if(normal_out) { - normal_out.x = normal.x; - normal_out.y = normal.y; + if(intersected) { + intersection.x = final_intersect.x; + intersection.y = final_intersect.y; + if(normal_out) { + normal_out.x = normal.x; + normal_out.y = normal.y; + } } - } - - return intersected; -}; - -cc.kmRay2IntersectCircle = function(ray, centre, radius, intersection) { - cc.log("cc.kmRay2IntersectCircle() has not been implemented."); -}; \ No newline at end of file + return intersected; + }; +})(cc); diff --git a/cocos2d/kazmath/utility.js b/cocos2d/kazmath/utility.js index 4f1d8153c7..9cd3fb4c71 100644 --- a/cocos2d/kazmath/utility.js +++ b/cocos2d/kazmath/utility.js @@ -26,51 +26,29 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /** - * @ignore + *

The main namespace of Cocos2d-html5's math library,
+ * all math core classes, functions, properties and constants are defined in this namespace

+ * @namespace + * @name cc.math */ -cc.kmScalar = Number; - -cc.kmBool = Number; - -cc.kmEnum = Number; - -cc.KM_FALSE = 0; +cc.math = cc.math || {}; -cc.KM_TRUE = 1; +//cc.kmPIOver180 = 0.017453; please use cc.RAD -cc.kmPI = 3.141592; +//cc.kmPIUnder180 = 57.295779; please use cc.DEG -cc.kmPIOver180 = 0.017453; - -cc.kmPIUnder180 = 57.295779; - -cc.kmEpsilon = 1.0 / 64.0; +cc.math.EPSILON = 1.0 / 64.0; //cc.kmEpsilon /** * Returns the square of s (e.g. s*s) * @param {Number} s */ -cc.kmSQR = function(s){ +cc.math.square = function(s){ return s*s; }; -cc.kmDegreesToRadians = function(degrees){ - return degrees * cc.kmPIOver180; -}; - -cc.kmRadiansToDegrees = function(radians){ - return radians * cc.kmPIUnder180; -}; - -cc.kmMin = function(lhs,rhs){ - return (lhs < rhs)? lhs : rhs; -}; - -cc.kmMax = function(lhs,rhs){ - return (lhs > rhs)? lhs : rhs; -}; - -cc.kmAlmostEqual = function(lhs,rhs){ - return (lhs + cc.kmEpsilon > rhs && lhs - cc.kmEpsilon < rhs); +cc.math.almostEqual = function(lhs,rhs){ + return (lhs + cc.math.EPSILON > rhs && lhs - cc.math.EPSILON < rhs); }; diff --git a/cocos2d/kazmath/vec2.js b/cocos2d/kazmath/vec2.js index 888b234bf1..a682bc4853 100644 --- a/cocos2d/kazmath/vec2.js +++ b/cocos2d/kazmath/vec2.js @@ -26,82 +26,88 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -cc.kmVec2 = function (x, y) { - this.x = x || 0; - this.y = y || 0; -}; +(function(cc){ + cc.math.Vec2 = function (x, y) { + if(y === undefined){ + this.x = x.x; + this.y = x.y; + }else{ + this.x = x || 0; + this.y = y || 0; + } + }; + + var proto = cc.math.Vec2.prototype; + proto.fill = function(x, y){ // = cc.kmVec2Fill + this.x = x; + this.y = y; + }; + + proto.length = function(){ // = cc.kmVec2Length + return Math.sqrt(cc.math.square(this.x) + cc.math.square(this.y)); + }; + + proto.lengthSq = function(){ // = cc.kmVec2LengthSq + return cc.math.square(this.x) + cc.math.square(this.y); + }; + + proto.normalize = function(){ // = cc.kmVec2Normalize + var l = 1.0 / this.length(); + this.x *= l; + this.y *= l; + return this; + }; + + cc.math.Vec2.add = function (pOut, pV1, pV2) { // = cc.kmVec2Add + pOut.x = pV1.x + pV2.x; + pOut.y = pV1.y + pV2.y; + return pOut + }; + + proto.add = function(vec){ // = cc.kmVec2Add + this.x += vec.x; + this.y += vec.y; + return this; + }; + + proto.dot = function (vec) { //cc.kmVec2Dot + return this.x * vec.x + this.y * vec.y; + }; + + cc.math.Vec2.subtract = function (pOut, pV1, pV2) { // = cc.kmVec2Subtract + pOut.x = pV1.x - pV2.x; + pOut.y = pV1.y - pV2.y; + return pOut; + }; + + proto.subtract = function(vec){ // = cc.kmVec2Subtract + this.x -= vec.x; + this.y -= vec.y; + return this; + }; + + proto.transform = function (mat3) { // = cc.kmVec2Transform + var x = this.x, y = this.y; + this.x = x * mat3.mat[0] + y * mat3.mat[3] + mat3.mat[6]; + this.y = x * mat3.mat[1] + y * mat3.mat[4] + mat3.mat[7]; + return this; + }; + + cc.math.Vec2.scale = function (pOut, pIn, s) { // = cc.kmVec2Scale + pOut.x = pIn.x * s; + pOut.y = pIn.y * s; + return pOut; + }; + + proto.scale = function(s) { // = cc.kmVec2Scale + this.x *= s; + this.y *= s; + return this; + }; + + proto.equals = function (vec) { // = cc.kmVec2AreEqual + return (this.x < vec.x + cc.math.EPSILON && this.x > vec.x - cc.math.EPSILON) && + (this.y < vec.y + cc.math.EPSILON && this.y > vec.y - cc.math.EPSILON); + }; +})(cc); -cc.kmVec2Fill = function (pOut, x, y) { - pOut.x = x; - pOut.y = y; - return pOut; -}; - -cc.kmVec2Length = function (pIn) { - return Math.sqrt(cc.kmSQR(pIn.x) + cc.kmSQR(pIn.y)); -}; - -cc.kmVec2LengthSq = function (pIn) { - return cc.kmSQR(pIn.x) + cc.kmSQR(pIn.y); -}; - -cc.kmVec2Normalize = function (pOut, pIn) { - var l = 1.0 / cc.kmVec2Length(pIn); - - var v = new cc.kmVec2(); - v.x = pIn.x * l; - v.y = pIn.y * l; - - pOut.x = v.x; - pOut.y = v.y; - - return pOut; -}; - -cc.kmVec2Add = function (pOut, pV1, pV2) { - pOut.x = pV1.x + pV2.x; - pOut.y = pV1.y + pV2.y; - - return pOut -}; - -cc.kmVec2Dot = function (pV1, pV2) { - return pV1.x * pV2.x + pV1.y * pV2.y; -}; - -cc.kmVec2Subtract = function (pOut, pV1, pV2) { - pOut.x = pV1.x - pV2.x; - pOut.y = pV1.y - pV2.y; - - return pOut; -}; - -cc.kmVec2Transform = function (pOut, pV, pM) { - var v= new cc.kmVec2(); - - v.x = pV.x * pM.mat[0] + pV.y * pM.mat[3] + pM.mat[6]; - v.y = pV.x * pM.mat[1] + pV.y * pM.mat[4] + pM.mat[7]; - - pOut.x = v.x; - pOut.y = v.y; - - return pOut; -}; - -cc.kmVec2TransformCoord = function (pOut, pV, pM) { - return null; -}; - -cc.kmVec2Scale = function (pOut, pIn, s) { - pOut.x = pIn.x * s; - pOut.y = pIn.y * s; - - return pOut; -}; - -cc.kmVec2AreEqual = function (p1, p2) { - return ( - (p1.x < p2.x + cc.kmEpsilon && p1.x > p2.x - cc.kmEpsilon) && - (p1.y < p2.y + cc.kmEpsilon && p1.y > p2.y - cc.kmEpsilon) - ); -}; diff --git a/cocos2d/kazmath/vec3.js b/cocos2d/kazmath/vec3.js index 07dc0fb4ea..de64594604 100644 --- a/cocos2d/kazmath/vec3.js +++ b/cocos2d/kazmath/vec3.js @@ -26,173 +26,165 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -cc.kmVec3 = function (x, y, z) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0; -}; - -cc.kmVec3Fill = function(pOut, x, y , z){ - if(!pOut) - return new cc.kmVec3(x, y , z); - pOut.x = x; - pOut.y = y; - pOut.z = z; - return pOut; -}; - -cc.kmVec3Length = function(pIn){ - return Math.sqrt(cc.kmSQR(pIn.x) + cc.kmSQR(pIn.y) + cc.kmSQR(pIn.z)); -}; - -cc.kmVec3LengthSq = function(pIn){ - return cc.kmSQR(pIn.x) + cc.kmSQR(pIn.y) + cc.kmSQR(pIn.z) -} ; - -cc.kmVec3Normalize = function(pOut,pIn){ - var l = 1.0 / cc.kmVec3Length(pIn); - - pOut.x = pIn.x * l; - pOut.y = pIn.y * l; - pOut.z = pIn.z * l; - return pOut; -}; - -cc.kmVec3Cross = function(pOut, pV1,pV2){ - pOut.x = (pV1.y * pV2.z) - (pV1.z * pV2.y); - pOut.y = (pV1.z * pV2.x) - (pV1.x * pV2.z); - pOut.z = (pV1.x * pV2.y) - (pV1.y * pV2.x); - return pOut; -}; - -cc.kmVec3Dot = function(pV1, pV2){ - return ( pV1.x * pV2.x - + pV1.y * pV2.y - + pV1.z * pV2.z ); -} ; - -cc.kmVec3Add = function(pOut, pV1, pV2){ - pOut.x = pV1.x + pV2.x; - pOut.y = pV1.y + pV2.y; - pOut.z = pV1.z + pV2.z; - return pOut; -}; - -cc.kmVec3Subtract = function(pOut, pV1, pV2){ - pOut.x = pV1.x - pV2.x; - pOut.y = pV1.y - pV2.y; - pOut.z = pV1.z - pV2.z; - return pOut; -}; - -cc.kmVec3Transform = function(pOut, pV, pM){ - /* - a = (Vx, Vy, Vz, 1) - b = (a×M)T - Out = (bx, by, bz) - */ - pOut.x = pV.x * pM.mat[0] + pV.y * pM.mat[4] + pV.z * pM.mat[8] + pM.mat[12]; - pOut.y = pV.x * pM.mat[1] + pV.y * pM.mat[5] + pV.z * pM.mat[9] + pM.mat[13]; - pOut.z = pV.x * pM.mat[2] + pV.y * pM.mat[6] + pV.z * pM.mat[10] + pM.mat[14]; - return pOut; -}; - -cc.kmVec3TransformNormal = function(pOut, pV, pM){ - /* - a = (Vx, Vy, Vz, 0) - b = (a×M)T - Out = (bx, by, bz) - */ - //Omits the translation, only scaling + rotating - pOut.x = pV.x * pM.mat[0] + pV.y * pM.mat[4] + pV.z * pM.mat[8]; - pOut.y = pV.x * pM.mat[1] + pV.y * pM.mat[5] + pV.z * pM.mat[9]; - pOut.z = pV.x * pM.mat[2] + pV.y * pM.mat[6] + pV.z * pM.mat[10]; - return pOut; -}; - -cc.kmVec3TransformCoord = function(pOut,pV,pM){ - /* - a = (Vx, Vy, Vz, 1) - b = (a×M)T - Out = 1⁄bw(bx, by, bz) - */ - var v = new cc.kmVec4(); - var inV = new cc.kmVec4(); - cc.kmVec4Fill(inV, pV.x, pV.y, pV.z, 1.0); - - cc.kmVec4Transform(v, inV,pM); - - pOut.x = v.x / v.w; - pOut.y = v.y / v.w; - pOut.z = v.z / v.w; - - return pOut; -}; - -cc.kmVec3Scale = function(pOut, pIn, s){ - pOut.x = pIn.x * s; - pOut.y = pIn.y * s; - pOut.z = pIn.z * s; - - return pOut; -}; - -cc.kmVec3AreEqual = function(p1, p2){ - if ((p1.x < (p2.x + cc.kmEpsilon) && p1.x > (p2.x - cc.kmEpsilon)) && - (p1.y < (p2.y + cc.kmEpsilon) && p1.y > (p2.y - cc.kmEpsilon)) && - (p1.z < (p2.z + cc.kmEpsilon) && p1.z > (p2.z - cc.kmEpsilon))) { - return 1; - } - - return 0; -}; - -cc.kmVec3InverseTransform = function(pOut, pVect,pM){ - var v1 = new cc.kmVec3(pVect.x - pM.mat[12], pVect.y - pM.mat[13],pVect.z - pM.mat[14]); - - pOut.x = v1.x * pM.mat[0] + v1.y * pM.mat[1] + v1.z * pM.mat[2]; - pOut.y = v1.x * pM.mat[4] + v1.y * pM.mat[5] + v1.z * pM.mat[6]; - pOut.z = v1.x * pM.mat[8] + v1.y * pM.mat[9] + v1.z * pM.mat[10]; - - return pOut; -}; - -cc.kmVec3InverseTransformNormal = function(pOut, pVect, pM){ - pOut.x = pVect.x * pM.mat[0] + pVect.y * pM.mat[1] + pVect.z * pM.mat[2]; - pOut.y = pVect.x * pM.mat[4] + pVect.y * pM.mat[5] + pVect.z * pM.mat[6]; - pOut.z = pVect.x * pM.mat[8] + pVect.y * pM.mat[9] + pVect.z * pM.mat[10]; - - return pOut; -}; - -cc.kmVec3Assign = function(pOut,pIn){ - if (pOut == pIn) - return pOut; - - pOut.x = pIn.x; - pOut.y = pIn.y; - pOut.z = pIn.z; - return pOut; -}; - -cc.kmVec3Zero = function(pOut){ - pOut.x = 0.0; - pOut.y = 0.0; - pOut.z = 0.0; - - return pOut; -}; - -cc.kmVec3ToTypeArray = function(vecValue){ - if(!vecValue) - return null; - - var tyArr = new Float32Array(3); - tyArr[0] = vecValue.x; - tyArr[1] = vecValue.y; - tyArr[2] = vecValue.z; - return tyArr; -}; +(function(cc) { + cc.kmVec3 = cc.math.Vec3 = function (x, y, z) { + if(x && y === undefined){ + this.x = x.x; + this.y = x.y; + this.z = x.z; + } else { + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + } + }; + + var proto = cc.math.Vec3.prototype; + + proto.fill = function (x, y, z) { // =cc.kmVec3Fill + if (x && y === undefined) { + this.x = x.x; + this.y = x.y; + this.z = x.z; + } else { + this.x = x; + this.y = y; + this.z = z; + } + return this; + }; + + proto.length = function () { //=cc.kmVec3Length + return Math.sqrt(cc.math.square(this.x) + cc.math.square(this.y) + cc.math.square(this.z)); + }; + + proto.lengthSq = function () { //=cc.kmVec3LengthSq + return cc.math.square(this.x) + cc.math.square(this.y) + cc.math.square(this.z) + }; + + proto.normalize = function () { //= cc.kmVec3Normalize + var l = 1.0 / this.length(); + this.x *= l; + this.y *= l; + this.z *= l; + return this; + }; + + proto.cross = function (vec3) { //= cc.kmVec3Cross + var x = this.x, y = this.y, z = this.z; + this.x = (y * vec3.z) - (z * vec3.y); + this.y = (z * vec3.x) - (x * vec3.z); + this.z = (x * vec3.y) - (y * vec3.x); + return this; + }; + + proto.dot = function (vec) { //= cc.kmVec3Dot + return ( this.x * vec.x + this.y * vec.y + this.z * vec.z ); + }; + + proto.add = function(vec){ //= cc.kmVec3Add + this.x += vec.x; + this.y += vec.y; + this.z += vec.z; + return this; + }; + + proto.subtract = function (vec) { // = cc.kmVec3Subtract + this.x -= vec.x; + this.y -= vec.y; + this.z -= vec.z; + return this; + }; + + proto.transform = function (mat4) { // = cc.kmVec3Transform + var x = this.x, y = this.y, z = this.z, mat = mat4.mat; + this.x = x * mat[0] + y * mat[4] + z * mat[8] + mat[12]; + this.y = x * mat[1] + y * mat[5] + z * mat[9] + mat[13]; + this.z = x * mat[2] + y * mat[6] + z * mat[10] + mat[14]; + return this; + }; + + proto.transformNormal = function(mat4){ + /* + a = (Vx, Vy, Vz, 0) + b = (a×M)T + Out = (bx, by, bz) + */ + //Omits the translation, only scaling + rotating + var x = this.x, y = this.y, z = this.z, mat = mat4.mat; + this.x = x * mat[0] + y * mat[4] + z * mat[8]; + this.y = x * mat[1] + y * mat[5] + z * mat[9]; + this.z = x * mat[2] + y * mat[6] + z * mat[10]; + return this; + }; + + proto.transformCoord = function(mat4){ // = cc.kmVec3TransformCoord + /* + a = (Vx, Vy, Vz, 1) + b = (a×M)T + Out = 1⁄bw(bx, by, bz) + */ + var v = new cc.math.Vec4(this.x, this.y, this.z, 1.0); + v.transform(mat4); + this.x = v.x / v.w; + this.y = v.y / v.w; + this.z = v.z / v.w; + return this; + }; + + proto.scale = function(scale){ // = cc.kmVec3Scale + this.x *= scale; + this.y *= scale; + this.z *= scale; + return this; + }; + + proto.equals = function(vec){ // = cc.kmVec3AreEqual + var EPSILON = cc.math.EPSILON; + return (this.x < (vec.x + EPSILON) && this.x > (vec.x - EPSILON)) && + (this.y < (vec.y + EPSILON) && this.y > (vec.y - EPSILON)) && + (this.z < (vec.z + EPSILON) && this.z > (vec.z - EPSILON)); + }; + + proto.inverseTransform = function(mat4){ //= cc.kmVec3InverseTransform + var mat = mat4.mat; + var v1 = new cc.math.Vec3(this.x - mat[12], this.y - mat[13], this.z - mat[14]); + this.x = v1.x * mat[0] + v1.y * mat[1] + v1.z * mat[2]; + this.y = v1.x * mat[4] + v1.y * mat[5] + v1.z * mat[6]; + this.z = v1.x * mat[8] + v1.y * mat[9] + v1.z * mat[10]; + return this; + }; + + proto.inverseTransformNormal = function(mat4){ // = cc.kmVec3InverseTransformNormal + var x = this.x, y = this.y, z = this.z, mat = mat4.mat; + this.x = x * mat[0] + y * mat[1] + z * mat[2]; + this.y = x * mat[4] + y * mat[5] + z * mat[6]; + this.z = x * mat[8] + y * mat[9] + z * mat[10]; + return this; + }; + + proto.assignFrom = function(vec){ + if(!vec) + return this; + this.x = vec.x; + this.y = vec.y; + this.z = vec.z; + return this; + }; + + cc.math.Vec3.zero = function(vec){ // = cc.kmVec3Zero + vec.x = vec.y = vec.z = 0.0; + return vec; + }; + + proto.toTypeArray = function(){ //cc.kmVec3ToTypeArray + var tyArr = new Float32Array(3); + tyArr[0] = this.x; + tyArr[1] = this.y; + tyArr[2] = this.z; + return tyArr; + }; +})(cc); diff --git a/cocos2d/kazmath/vec4.js b/cocos2d/kazmath/vec4.js index 9712743fff..fb2e376380 100644 --- a/cocos2d/kazmath/vec4.js +++ b/cocos2d/kazmath/vec4.js @@ -26,133 +26,133 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -cc.kmVec4 = function (x, y, z, w) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0; - this.w = w || 0; -}; - - -cc.kmVec4Fill = function(outVec, x, y ,z, w){ - outVec.x = x; - outVec.y = y; - outVec.z = z; - outVec.w = w; - return outVec; -}; - -cc.kmVec4Add = function(outVec, pV1, pV2){ - outVec.x = pV1.x + pV2.x; - outVec.y = pV1.y + pV2.y; - outVec.z = pV1.z + pV2.z; - outVec.w = pV1.w + pV2.w; - - return outVec; -}; - -cc.kmVec4Dot = function( vec1, vec2){ - return ( vec1.x * vec2.x - + vec1.y * vec2.y - + vec1.z * vec2.z - + vec1.w * vec2.w ); -}; - -cc.kmVec4Length = function(inVec){ - return Math.sqrt(cc.kmSQR(inVec.x) + cc.kmSQR(inVec.y) + cc.kmSQR(inVec.z) + cc.kmSQR(inVec.w)); -}; - -cc.kmVec4LengthSq = function(inVec){ - return cc.kmSQR(inVec.x) + cc.kmSQR(inVec.y) + cc.kmSQR(inVec.z) + cc.kmSQR(inVec.w); -}; - -cc.kmVec4Lerp = function(outVec, pV1, pV2, t){ - return outVec; -}; - -cc.kmVec4Normalize = function(outVec, inVec){ - var l = 1.0 / cc.kmVec4Length(inVec); - - outVec.x *= l; - outVec.y *= l; - outVec.z *= l; - outVec.w *= l; - - return outVec; -}; - -cc.kmVec4Scale = function(outVec, inVec, scale){ - cc.kmVec4Normalize(outVec, inVec); - - outVec.x *= scale; - outVec.y *= scale; - outVec.z *= scale; - outVec.w *= scale; - return outVec; -}; - -cc.kmVec4Subtract = function(outVec,vec1, vec2){ - outVec.x = vec1.x - vec2.x; - outVec.y = vec1.y - vec2.y; - outVec.z = vec1.z - vec2.z; - outVec.w = vec1.w - vec2.w; - - return outVec; -}; - -cc.kmVec4Transform = function(outVec, vec,mat4Obj){ - outVec.x = vec.x * mat4Obj.mat[0] + vec.y * mat4Obj.mat[4] + vec.z * mat4Obj.mat[8] + vec.w * mat4Obj.mat[12]; - outVec.y = vec.x * mat4Obj.mat[1] + vec.y * mat4Obj.mat[5] + vec.z * mat4Obj.mat[9] + vec.w * mat4Obj.mat[13]; - outVec.z = vec.x * mat4Obj.mat[2] + vec.y * mat4Obj.mat[6] + vec.z * mat4Obj.mat[10] + vec.w * mat4Obj.mat[14]; - outVec.w = vec.x * mat4Obj.mat[3] + vec.y * mat4Obj.mat[7] + vec.z * mat4Obj.mat[11] + vec.w * mat4Obj.mat[15]; - return outVec; -}; - -cc.kmVec4TransformArray = function(outVec,outStride,vecObj,stride,mat4Obj,count){ - var i = 0; - //Go through all of the vectors - while (i < count) { - var currIn = vecObj + (i * stride); //Get a pointer to the current input - var out = outVec + (i * outStride); //and the current output - cc.kmVec4Transform(out, currIn, mat4Obj); //Perform transform on it - ++i; - } - - return outVec; -}; - -cc.kmVec4AreEqual = function(vec1,vec2){ - return ( - (vec1.x < vec2.x + cc.kmEpsilon && vec1.x > vec2.x - cc.kmEpsilon) && - (vec1.y < vec2.y + cc.kmEpsilon && vec1.y > vec2.y - cc.kmEpsilon) && - (vec1.z < vec2.z + cc.kmEpsilon && vec1.z > vec2.z - cc.kmEpsilon) && - (vec1.w < vec2.w + cc.kmEpsilon && vec1.w > vec2.w - cc.kmEpsilon) - ); -}; - -cc.kmVec4Assign = function(destVec, srcVec){ - if(destVec == srcVec){ - cc.log("destVec and srcVec are same object"); - return destVec; - } - - destVec.x = srcVec.x; - destVec.y = srcVec.y; - destVec.z = srcVec.z; - destVec.w = srcVec.w; - - return destVec; -}; - -cc.kmVec4ToTypeArray = function(vecValue){ - if(!vecValue) - return null; - - var tyArr = new Float32Array(4); - tyArr[0] = vecValue.x; - tyArr[1] = vecValue.y; - tyArr[2] = vecValue.z; - tyArr[3] = vecValue.w; - return tyArr; -}; +(function(cc) { + cc.math.Vec4 = function (x, y, z, w) { + if (x && y === undefined) { + this.x = x.x; + this.y = x.y; + this.z = x.z; + this.w = x.w; + } else { + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + this.w = w || 0; + } + }; + cc.kmVec4 = cc.math.Vec4; + var proto = cc.math.Vec4.prototype; + + proto.fill = function (x, y, z, w) { //=cc.kmVec4Fill + if (x && y === undefined) { + this.x = x.x; + this.y = x.y; + this.z = x.z; + this.w = x.w; + } else { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + }; + + proto.add = function(vec) { //cc.kmVec4Add + if(!vec) + return this; + this.x += vec.x; + this.y += vec.y; + this.z += vec.z; + this.w += vec.w; + return this; + }; + + proto.dot = function(vec){ //cc.kmVec4Dot + return ( this.x * vec.x + this.y * vec.y + this.z * vec.z + this.w * vec.w ); + }; + + proto.length = function(){ //=cc.kmVec4Length + return Math.sqrt(cc.math.square(this.x) + cc.math.square(this.y) + cc.math.square(this.z) + cc.math.square(this.w)); + }; + + proto.lengthSq = function(){ //=cc.kmVec4LengthSq + return cc.math.square(this.x) + cc.math.square(this.y) + cc.math.square(this.z) + cc.math.square(this.w); + }; + + proto.lerp = function(vec, t){ //= cc.kmVec4Lerp + //not implemented + return this; + }; + + proto.normalize = function() { // cc.kmVec4Normalize + var l = 1.0 / this.length(); + this.x *= l; + this.y *= l; + this.z *= l; + this.w *= l; + return this; + }; + + proto.scale = function(scale){ //= cc.kmVec4Scale + /// Scales a vector to the required length. This performs a Normalize before multiplying by S. + this.normalize(); + this.x *= scale; + this.y *= scale; + this.z *= scale; + this.w *= scale; + return this; + }; + + proto.subtract = function(vec) { + this.x -= vec.x; + this.y -= vec.y; + this.z -= vec.z; + this.w -= vec.w; + }; + + proto.transform = function(mat4) { + var x = this.x, y = this.y, z = this.z, w = this.w, mat = mat4.mat; + this.x = x * mat[0] + y * mat[4] + z * mat[8] + w * mat[12]; + this.y = x * mat[1] + y * mat[5] + z * mat[9] + w * mat[13]; + this.z = x * mat[2] + y * mat[6] + z * mat[10] + w * mat[14]; + this.w = x * mat[3] + y * mat[7] + z * mat[11] + w * mat[15]; + return this; + }; + + cc.math.Vec4.transformArray = function(vecArray, mat4){ + var retArray = []; + for (var i = 0; i < vecArray.length; i++) { + var selVec = new cc.math.Vec4(vecArray[i]); + selVec.transform(mat4); + retArray.push(selVec); + } + return retArray; + }; + + proto.equals = function(vec){ //=cc.kmVec4AreEqual + var EPSILON = cc.math.EPSILON; + return (this.x < vec.x + EPSILON && this.x > vec.x - EPSILON) && + (this.y < vec.y + EPSILON && this.y > vec.y - EPSILON) && + (this.z < vec.z + EPSILON && this.z > vec.z - EPSILON) && + (this.w < vec.w + EPSILON && this.w > vec.w - EPSILON); + }; + + proto.assignFrom = function(vec) { //= cc.kmVec4Assign + this.x = vec.x; + this.y = vec.y; + this.z = vec.z; + this.w = vec.w; + return this; + }; + + proto.toTypeArray = function(){ //cc.kmVec4ToTypeArray + var tyArr = new Float32Array(4); + tyArr[0] = this.x; + tyArr[1] = this.y; + tyArr[2] = this.z; + tyArr[3] = this.w; + return tyArr; + }; +})(cc); + diff --git a/cocos2d/node-grid/CCNodeGrid.js b/cocos2d/node-grid/CCNodeGrid.js index f75ce939f8..3426e84d74 100644 --- a/cocos2d/node-grid/CCNodeGrid.js +++ b/cocos2d/node-grid/CCNodeGrid.js @@ -80,7 +80,7 @@ cc.NodeGrid = cc.Node.extend({ t4x4Mat[14] = this._vertexZ; //optimize performance for Javascript - cc.kmMat4Multiply(topMat4, topMat4, t4x4); // = cc.kmGLMultMatrix(this._transform4x4); + topMat4.multiply(t4x4) ; // = cc.kmGLMultMatrix(this._transform4x4); // XXX: Expensive calls. Camera should be integrated into the cached affine matrix if (this._camera != null && !(this.grid && this.grid.isActive())) { diff --git a/cocos2d/render-texture/CCRenderTextureWebGLRenderCmd.js b/cocos2d/render-texture/CCRenderTextureWebGLRenderCmd.js index 4a2e48cb63..5238694b38 100644 --- a/cocos2d/render-texture/CCRenderTextureWebGLRenderCmd.js +++ b/cocos2d/render-texture/CCRenderTextureWebGLRenderCmd.js @@ -239,9 +239,8 @@ var widthRatio = size.width / texSize.width; var heightRatio = size.height / texSize.height; - var orthoMatrix = new cc.kmMat4(); - cc.kmMat4OrthographicProjection(orthoMatrix, -1.0 / widthRatio, 1.0 / widthRatio, - -1.0 / heightRatio, 1.0 / heightRatio, -1, 1); + var orthoMatrix = cc.math.Matrix4.createOrthographicProjection(-1.0 / widthRatio, 1.0 / widthRatio, + -1.0 / heightRatio, 1.0 / heightRatio, -1, 1); cc.kmGLMultMatrix(orthoMatrix); //calculate viewport diff --git a/cocos2d/shaders/CCGLProgram.js b/cocos2d/shaders/CCGLProgram.js index 1b429a9734..c8812bcac4 100644 --- a/cocos2d/shaders/CCGLProgram.js +++ b/cocos2d/shaders/CCGLProgram.js @@ -543,9 +543,9 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * will update the builtin uniforms if they are different than the previous call for this same shader program. */ setUniformsForBuiltins: function () { - var matrixP = new cc.kmMat4(); - var matrixMV = new cc.kmMat4(); - var matrixMVP = new cc.kmMat4(); + var matrixP = new cc.math.Matrix4(); + var matrixMV = new cc.math.Matrix4(); + var matrixMVP = new cc.math.Matrix4(); cc.kmGLGetMatrix(cc.KM_GL_PROJECTION, matrixP); cc.kmGLGetMatrix(cc.KM_GL_MODELVIEW, matrixMV); @@ -576,9 +576,9 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ if(!node || !node._renderCmd) return; - var matrixP = new cc.kmMat4(); + var matrixP = new cc.math.Matrix4(); //var matrixMV = new cc.kmMat4(); - var matrixMVP = new cc.kmMat4(); + var matrixMVP = new cc.math.Matrix4(); cc.kmGLGetMatrix(cc.KM_GL_PROJECTION, matrixP); //cc.kmGLGetMatrix(cc.KM_GL_MODELVIEW, node._stackMatrix); diff --git a/extensions/ccui/base-classes/CCProtectedNodeWebGLRenderCmd.js b/extensions/ccui/base-classes/CCProtectedNodeWebGLRenderCmd.js index b4581dbaaf..476c790a5f 100644 --- a/extensions/ccui/base-classes/CCProtectedNodeWebGLRenderCmd.js +++ b/extensions/ccui/base-classes/CCProtectedNodeWebGLRenderCmd.js @@ -129,15 +129,15 @@ apy = 0 | apy; } //cc.kmGLTranslatef(apx, apy, 0); - var translation = new cc.kmMat4(); - cc.kmMat4Translation(translation, apx, apy, 0); - cc.kmMat4Multiply(stackMatrix, stackMatrix, translation); + var translation = cc.math.Matrix4.createByTranslation(apx, apy, 0, t4x4); //t4x4 as a temp matrix + stackMatrix.multiply(translate); node._camera._locateForRenderer(stackMatrix); //cc.kmGLTranslatef(-apx, -apy, 0); - cc.kmMat4Translation(translation, -apx, -apy, 0); - cc.kmMat4Multiply(stackMatrix, stackMatrix, translation); + translation = cc.math.Matrix4.createByTranslation(-apx, -apy, 0, translation); + stackMatrix.multiply(translation); + t4x4.identity(); //reset t4x4; } else { node._camera._locateForRenderer(stackMatrix); }