const bool CCMatrixInverse(CCMatrix &result, CCMatrix &source)
{
    float *m = source.data();
    float *inv = result.data();
    
    inv[0]  = m[5]*m[10]*m[15]  - m[5]*m[11]*m[14]  - m[9]*m[6]*m[15]   + m[9]*m[7]*m[14]   + m[13]*m[6]*m[11]  - m[13]*m[7]*m[10];
    inv[4]  = -m[4]*m[10]*m[15] + m[4]*m[11]*m[14]  + m[8]*m[6]*m[15]   - m[8]*m[7]*m[14]   - m[12]*m[6]*m[11]  + m[12]*m[7]*m[10];
    inv[8]  = m[4]*m[9]*m[15]   - m[4]*m[11]*m[13]	- m[8]*m[5]*m[15]   + m[8]*m[7]*m[13]	+ m[12]*m[5]*m[11]	- m[12]*m[7]*m[9];
    inv[12] = -m[4]*m[9]*m[14]  + m[4]*m[10]*m[13]	+ m[8]*m[5]*m[14]   - m[8]*m[6]*m[13]   - m[12]*m[5]*m[10]	+ m[12]*m[6]*m[9];
    inv[1]	= -m[1]*m[10]*m[15] + m[1]*m[11]*m[14]	+ m[9]*m[2]*m[15]   - m[9]*m[3]*m[14]   - m[13]*m[2]*m[11]	+ m[13]*m[3]*m[10];
    inv[5]	= m[0]*m[10]*m[15]	- m[0]*m[11]*m[14]	- m[8]*m[2]*m[15]   + m[8]*m[3]*m[14]   + m[12]*m[2]*m[11]	- m[12]*m[3]*m[10];
    inv[9]	= -m[0]*m[9]*m[15]  + m[0]*m[11]*m[13]	+ m[8]*m[1]*m[15]   - m[8]*m[3]*m[13]	- m[12]*m[1]*m[11]	+ m[12]*m[3]*m[9];
    inv[13] = m[0]*m[9]*m[14]   - m[0]*m[10]*m[13]	- m[8]*m[1]*m[14]   + m[8]*m[2]*m[13]	+ m[12]*m[1]*m[10]	- m[12]*m[2]*m[9];
    inv[2]	= m[1]*m[6]*m[15]   - m[1]*m[7]*m[14]	- m[5]*m[2]*m[15]   + m[5]*m[3]*m[14]	+ m[13]*m[2]*m[7]	- m[13]*m[3]*m[6];
    inv[6]	= -m[0]*m[6]*m[15]  + m[0]*m[7]*m[14]	+ m[4]*m[2]*m[15]   - m[4]*m[3]*m[14]	- m[12]*m[2]*m[7]	+ m[12]*m[3]*m[6];
    inv[10] = m[0]*m[5]*m[15]   - m[0]*m[7]*m[13]	- m[4]*m[1]*m[15]   + m[4]*m[3]*m[13]	+ m[12]*m[1]*m[7]	- m[12]*m[3]*m[5];
    inv[14] = -m[0]*m[5]*m[14]  + m[0]*m[6]*m[13]	+ m[4]*m[1]*m[14]   - m[4]*m[2]*m[13]	- m[12]*m[1]*m[6]	+ m[12]*m[2]*m[5];
    inv[3]	= -m[1]*m[6]*m[11]  + m[1]*m[7]*m[10]	+ m[5]*m[2]*m[11]   - m[5]*m[3]*m[10]	- m[9]*m[2]*m[7]	+ m[9]*m[3]*m[6];
    inv[7]	= m[0]*m[6]*m[11]   - m[0]*m[7]*m[10]	- m[4]*m[2]*m[11]   + m[4]*m[3]*m[10]	+ m[8]*m[2]*m[7]	- m[8]*m[3]*m[6];
    inv[11] = -m[0]*m[5]*m[11]  + m[0]*m[7]*m[9]	+ m[4]*m[1]*m[11]   - m[4]*m[3]*m[9]	- m[8]*m[1]*m[7]	+ m[8]*m[3]*m[5];
    inv[15] = m[0]*m[5]*m[10]   - m[0]*m[6]*m[9]	- m[4]*m[1]*m[10]   + m[4]*m[2]*m[9]	+ m[8]*m[1]*m[6]	- m[8]*m[2]*m[5];
    
    float det = m[0]*inv[0] + m[1]*inv[4] + m[2]*inv[8] + m[3]*inv[12];
    if( det == 0.0f )
    {
        return false;
    }
    
    det = 1.0f / det;
    for( int i=0; i<16; ++i )
    {
        inv[i] *= det;
    }
    
    return true;
}
Esempio n. 2
0
void CCSetModelViewProjectionMatrix()
{
	const CCMatrix &viewMatrix = CCCameraBase::CurrentCamera->getViewMatrix();
    const CCMatrix &modelMatrix = CCCameraBase::CurrentCamera->pushedMatrix[CCCameraBase::CurrentCamera->currentPush];
    if( gRenderer->openGL2() )
    {
        const CCMatrix &projectionMatrix = CCCameraBase::CurrentCamera->getProjectionMatrix();

        const GLint *uniforms = gRenderer->getShader()->uniforms;
        gRenderer->GLUniformMatrix4fv( uniforms[UNIFORM_PROJECTIONMATRIX], 1, GL_FALSE, projectionMatrix.m );
        gRenderer->GLUniformMatrix4fv( uniforms[UNIFORM_VIEWMATRIX], 1, GL_FALSE, viewMatrix.m );
        gRenderer->GLUniformMatrix4fv( uniforms[UNIFORM_MODELMATRIX], 1, GL_FALSE, modelMatrix.m );

        if( uniforms[UNIFORM_MODELNORMALMATRIX] != -1 )
        {
            static CCMatrix modelViewMatrix;
            modelViewMatrix = viewMatrix;
            CCMatrixMultiply( modelViewMatrix, modelMatrix, modelViewMatrix );

            static CCMatrix inverseModelViewMatrix;
            static CCMatrix modelNormalMatrix;
            CCMatrixInverse( inverseModelViewMatrix, modelViewMatrix );
            CCMatrixTranspose( modelNormalMatrix, inverseModelViewMatrix );
            gRenderer->GLUniformMatrix4fv( uniforms[UNIFORM_MODELNORMALMATRIX], 1, GL_FALSE, modelNormalMatrix.m );
        }
    }
    else
    {
#ifdef IOS
        static CCMatrix modelViewMatrix;
		modelViewMatrix = viewMatrix;
		CCMatrixMultiply( modelViewMatrix, modelMatrix, modelViewMatrix );
        glLoadMatrixf( modelViewMatrix.data() );
#endif
    }
}