Translation and scaling (when applied in that order) are trivially combined;
save a matrix multiply for every actor. (Maybe we can avoid doing any, for objects which are neither rotated nor scaled--such as those positioned based on their parent--but I'm not sure it's worth it.) Rotations can be combined without doing a full matrix multiply, too; if an actor rotates at all, only do one matrix multiply.
This commit is contained in:
@@ -151,6 +151,40 @@ void RageMatrixScaling( RageMatrix* pOut, float x, float y, float z )
|
||||
pOut->m[2][2] = z;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return:
|
||||
*
|
||||
* RageMatrix translate;
|
||||
* RageMatrixTranslation( &translate, fTransX, fTransY, fTransZ );
|
||||
* RageMatrix scale;
|
||||
* RageMatrixScaling( &scale, fScaleX, float fScaleY, float fScaleZ );
|
||||
* RageMatrixMultiply( pOut, &translate, &scale );
|
||||
*/
|
||||
void RageMatrixTranslateAndScale( RageMatrix* pOut,
|
||||
float fTransX, float fTransY, float fTransZ,
|
||||
float fScaleX, float fScaleY, float fScaleZ )
|
||||
{
|
||||
pOut->m00 = fScaleX;
|
||||
pOut->m01 = 0;
|
||||
pOut->m02 = 0;
|
||||
pOut->m03 = 0;
|
||||
|
||||
pOut->m10 = 0;
|
||||
pOut->m11 = fScaleY;
|
||||
pOut->m12 = 0;
|
||||
pOut->m13 = 0;
|
||||
|
||||
pOut->m20 = 0;
|
||||
pOut->m21 = 0;
|
||||
pOut->m22 = fScaleZ;
|
||||
pOut->m23 = 0;
|
||||
|
||||
pOut->m30 = fTransX;
|
||||
pOut->m31 = fTransY;
|
||||
pOut->m32 = fTransZ;
|
||||
pOut->m33 = 1;
|
||||
}
|
||||
|
||||
void RageMatrixRotationX( RageMatrix* pOut, float theta )
|
||||
{
|
||||
theta *= PI/180;
|
||||
@@ -187,6 +221,59 @@ void RageMatrixRotationZ( RageMatrix* pOut, float theta )
|
||||
pOut->m[1][0] = -pOut->m[0][1];
|
||||
}
|
||||
|
||||
/* Return RageMatrixRotationX(rX) * RageMatrixRotationY(rY) * RageMatrixRotationZ(rZ)
|
||||
* quickly (without actually doing two complete matrix multiplies), by removing the
|
||||
* parts of the matrix multiplies that we know will be 0. */
|
||||
void RageMatrixRotationXYZ( RageMatrix* pOut, float rX, float rY, float rZ )
|
||||
{
|
||||
rX *= PI/180;
|
||||
rY *= PI/180;
|
||||
rZ *= PI/180;
|
||||
|
||||
const float cX = cosf(rX);
|
||||
const float sX = sinf(rX);
|
||||
const float cY = cosf(rY);
|
||||
const float sY = sinf(rY);
|
||||
const float cZ = cosf(rZ);
|
||||
const float sZ = sinf(rZ);
|
||||
|
||||
/*
|
||||
* X*Y:
|
||||
* RageMatrix(
|
||||
* cY, sY*sX, sY*cX, 0,
|
||||
* 0, cX, -sX, 0,
|
||||
* -sY, cY*sX, cY*cX, 0,
|
||||
* 0, 0, 0, 1
|
||||
* );
|
||||
*
|
||||
* X*Y*Z:
|
||||
*
|
||||
* RageMatrix(
|
||||
* cZ*cY, cZ*sY*sX+sZ*cX, cZ*sY*cX+sZ*(-sX), 0,
|
||||
* (-sZ)*cY, (-sZ)*sY*sX+cZ*cX, (-sZ)*sY*cX+cZ*(-sX), 0,
|
||||
* -sY, cY*sX, cY*cX, 0,
|
||||
* 0, 0, 0, 1
|
||||
* );
|
||||
*/
|
||||
|
||||
pOut->m00 = cZ*cY;
|
||||
pOut->m01 = cZ*sY*sX+sZ*cX;
|
||||
pOut->m02 = cZ*sY*cX+sZ*(-sX);
|
||||
pOut->m03 = 0;
|
||||
pOut->m10 = (-sZ)*cY;
|
||||
pOut->m11 = (-sZ)*sY*sX+cZ*cX;
|
||||
pOut->m12 = (-sZ)*sY*cX+cZ*(-sX);
|
||||
pOut->m13 = 0;
|
||||
pOut->m20 = -sY;
|
||||
pOut->m21 = cY*sX;
|
||||
pOut->m22 = cY*cX;
|
||||
pOut->m23 = 0;
|
||||
pOut->m30 = 0;
|
||||
pOut->m31 = 0;
|
||||
pOut->m32 = 0;
|
||||
pOut->m33 = 1;
|
||||
}
|
||||
|
||||
/* This is similar in style to Actor::Command. However, Actors don't store
|
||||
* matrix stacks; they only store offsets and scales, and compound them into
|
||||
* a single transformations at once. This makes some things easy, but it's not
|
||||
|
||||
Reference in New Issue
Block a user