Ticket #2026: skinning_update.patch

File skinning_update.patch, 28.8 KB (added by sanderd17, 11 years ago)
  • source/graphics/Model.cpp

     
    175175        ValidatePosition();
    176176
    177177        // extend bounds by vertex positions at the frame
     178        CVector3D tempRes;
    178179        for (size_t i=0;i<numverts;i++)
    179180        {
    180             result += CModelDef::SkinPoint(verts[i], GetAnimatedBoneMatrices());
     181            CModelDef::SkinPoint(verts[i], GetAnimatedBoneMatrices(), tempRes);
     182            result += tempRes;
    181183        }
    182184        // advance to next frame
    183185        m_AnimTime += anim->GetFrameTime();
     
    192194/////////////////////////////////////////////////////////////////////////////////////////////////////////////
    193195const CBoundingBoxAligned CModel::GetWorldBoundsRec()
    194196{
    195     CBoundingBoxAligned bounds = GetWorldBounds();
    196     for (size_t i = 0; i < m_Props.size(); ++i)
     197    CBoundingBoxAligned bounds (GetWorldBounds());
     198    const size_t propSize = m_Props.size();
     199    for (size_t i = 0; i < propSize; i++)
    197200        bounds += m_Props[i].m_Model->GetWorldBoundsRec();
    198201    return bounds;
    199202}
     
    203206    CBoundingBoxAligned objBounds = GetObjectBounds();      // updates the (children-not-included) object-space bounds if necessary
    204207
    205208    // now extend these bounds to include the props' selection bounds (if any)
    206     for (size_t i = 0; i < m_Props.size(); ++i)
     209    const size_t propSize = m_Props.size();
     210    for (size_t i = 0; i < propSize; ++i)
    207211    {
    208212        const Prop& prop = m_Props[i];
    209213        if (prop.m_Hidden)
     
    332336        ENSURE(m_PositionValid);
    333337        return;
    334338    }
    335 
    336     if (m_Anim && m_BoneMatrices)
    337     {
    338 //      PROFILE( "generating bone matrices" );
    339339   
    340         ENSURE(m_pModelDef->GetNumBones() == m_Anim->m_AnimDef->GetNumKeys());
    341    
    342         m_Anim->m_AnimDef->BuildBoneMatrices(m_AnimTime, m_BoneMatrices, !(m_Flags & MODELFLAG_NOLOOPANIMATION));
    343     }
    344     else if (m_BoneMatrices)
     340    const size_t numBones = m_pModelDef->GetNumBones();
     341    const bool hasBones = m_BoneMatrices && numBones != 0;     
     342        // For CPU skinning, we precompute as much as possible so that the only
     343        // per-vertex work is a single matrix*vec multiplication.
     344        // For GPU skinning, we try to minimise CPU work by doing most computation
     345        // in the vertex shader instead.
     346        // Using g_Renderer.m_Options to detect CPU vs GPU is a bit hacky,
     347        // and this doesn't allow the setting to change at runtime, but there isn't
     348        // an obvious cleaner way to determine what data needs to be computed,
     349        // and GPU skinning is a rarely-used experimental feature anyway.
     350    const bool worldSpaceBoneMatrices = !g_Renderer.m_Options.m_GPUSkinning;
     351    const bool computeBlendMatrices = !g_Renderer.m_Options.m_GPUSkinning;
     352    const CMatrix3D transform (GetTransform());
     353    CMatrix3D * const bonesMatrices = m_BoneMatrices;
     354    if (hasBones)
    345355    {
    346         // Bones but no animation - probably a buggy actor forgot to set up the animation,
    347         // so just render it in its bind pose
    348356
    349         for (size_t i = 0; i < m_pModelDef->GetNumBones(); i++)
     357        if (m_Anim)
    350358        {
    351             m_BoneMatrices[i].SetIdentity();
    352             m_BoneMatrices[i].Rotate(m_pModelDef->GetBones()[i].m_Rotation);
    353             m_BoneMatrices[i].Translate(m_pModelDef->GetBones()[i].m_Translation);
     359    //      PROFILE( "generating bone matrices" );
     360   
     361            ENSURE(numBones == m_Anim->m_AnimDef->GetNumKeys());
     362   
     363            m_Anim->m_AnimDef->BuildBoneMatrices(m_AnimTime, bonesMatrices, !(m_Flags & MODELFLAG_NOLOOPANIMATION));
    354364        }
    355     }
     365        else
     366        {
     367            // Bones but no animation - probably a buggy actor forgot to set up the animation,
     368            // so just render it in its bind pose
     369            const CBoneState * const boneStates = m_pModelDef->GetBones();
     370            for (size_t i = 0; i < numBones; i++)
     371            {
     372                bonesMatrices[i].SetIdentity();
     373                bonesMatrices[i].Rotate(boneStates[i].m_Rotation);
     374                bonesMatrices[i].Translate(boneStates[i].m_Translation);
     375            }
     376        }
    356377
    357     // For CPU skinning, we precompute as much as possible so that the only
    358     // per-vertex work is a single matrix*vec multiplication.
    359     // For GPU skinning, we try to minimise CPU work by doing most computation
    360     // in the vertex shader instead.
    361     // Using g_Renderer.m_Options to detect CPU vs GPU is a bit hacky,
    362     // and this doesn't allow the setting to change at runtime, but there isn't
    363     // an obvious cleaner way to determine what data needs to be computed,
    364     // and GPU skinning is a rarely-used experimental feature anyway.
    365     bool worldSpaceBoneMatrices = !g_Renderer.m_Options.m_GPUSkinning;
    366     bool computeBlendMatrices = !g_Renderer.m_Options.m_GPUSkinning;
    367378
    368     if (m_BoneMatrices && worldSpaceBoneMatrices)
    369     {
    370         // add world-space transformation to m_BoneMatrices
    371         const CMatrix3D transform = GetTransform();
    372         for (size_t i = 0; i < m_pModelDef->GetNumBones(); i++)
    373             m_BoneMatrices[i].Concatenate(transform);
     379
     380        if (worldSpaceBoneMatrices)
     381        {
     382            // add world-space transformation to m_BoneMatrices
     383            for (size_t i = 0; i < numBones; i++)
     384                bonesMatrices[i].Concatenate(transform);
     385        }
    374386    }
    375 
    376387    // our own position is now valid; now we can safely update our props' positions without fearing
    377388    // that doing so will cause a revalidation of this model (see recursion above).
    378389    m_PositionValid = true;
     
    386397
    387398        if (prop.m_Point->m_BoneIndex != 0xff)
    388399        {
    389             CMatrix3D boneMatrix = m_BoneMatrices[prop.m_Point->m_BoneIndex];
     400            CMatrix3D boneMatrix = (bonesMatrices[prop.m_Point->m_BoneIndex]);
    390401            if (!worldSpaceBoneMatrices)
    391                 boneMatrix.Concatenate(GetTransform());
     402                boneMatrix.Concatenate(transform);
    392403            proptransform.Concatenate(boneMatrix);
    393404        }
    394405        else
     
    420431        prop.m_Model->ValidatePosition();
    421432    }
    422433
    423     if (m_BoneMatrices)
     434    if (hasBones)
    424435    {
    425         for (size_t i = 0; i < m_pModelDef->GetNumBones(); i++)
     436        const CMatrix3D * const inverseBoneMatrices = m_pModelDef->GetInverseBindBoneMatrices();
     437        for (size_t i = 0; i < numBones; i++)
    426438        {
    427             m_BoneMatrices[i] = m_BoneMatrices[i] * m_pModelDef->GetInverseBindBoneMatrices()[i];
     439            bonesMatrices[i].mul(inverseBoneMatrices[i]);
    428440        }
    429441
    430442        // Note: there is a special case of joint influence, in which the vertex
     
    433445        //  of bones. But since we're skinning in world space, we use the model's
    434446        //  world space transform and store that matrix in this special index.
    435447        //  (see http://trac.wildfiregames.com/ticket/1012)
    436         m_BoneMatrices[m_pModelDef->GetNumBones()] = m_Transform;
     448        bonesMatrices[numBones] = m_Transform;
    437449
    438450        if (computeBlendMatrices)
    439             m_pModelDef->BlendBoneMatrices(m_BoneMatrices);
     451            m_pModelDef->BlendBoneMatrices(bonesMatrices);
    440452    }
    441453}
    442454
  • source/graphics/ModelDef.cpp

     
    3131#endif
    3232
    3333CVector3D CModelDef::SkinPoint(const SModelVertex& vtx,
    34                                const CMatrix3D newPoseMatrices[])
     34                               const CMatrix3D newPoseMatrices[],
     35                               CVector3D &result)
    3536{
    36     CVector3D result (0, 0, 0);
     37    const uint8_t * const blendBones = vtx.m_Blend.m_Bone;
     38    const float * const blendWeight = vtx.m_Blend.m_Weight;
     39    const CVector3D &coords = vtx.m_Coords;
     40   
     41    if (blendWeight[0] != 0.0 && blendBones[0] != 0xff)
     42        result.mulStore(newPoseMatrices[blendBones[0]].Transform(coords), blendWeight[0]);
     43    if (blendWeight[1] != 0.0 && blendBones[1] != 0xff)
     44        result.mulAdd(newPoseMatrices[blendBones[1]].Transform(coords), blendWeight[1]);
     45    if (blendWeight[2] != 0.0 && blendBones[2] != 0xff)
     46        result.mulAdd(newPoseMatrices[blendBones[2]].Transform(coords), blendWeight[2]);
     47    if (blendWeight[3] != 0.0 && blendBones[3] != 0xff)
     48        result.mulAdd(newPoseMatrices[blendBones[3]].Transform(coords), blendWeight[3]);
    3749
    38     for (int i = 0; i < SVertexBlend::SIZE && vtx.m_Blend.m_Bone[i] != 0xff; ++i)
     50    /*
     51    result *= 0;
     52    for (int i = 0; i < SVertexBlend::SIZE && blendBones[i] != 0xff; i++)
    3953    {
    40         result += newPoseMatrices[vtx.m_Blend.m_Bone[i]].Transform(vtx.m_Coords) * vtx.m_Blend.m_Weight[i];
    41     }
    42 
     54        if (blendWeight[i] != 0.0)
     55            result.mulAdd(newPoseMatrices[blendBones[i]].Transform(coords), blendWeight[i]);
     56    }*/
    4357    return result;
    4458}
    4559
    4660CVector3D CModelDef::SkinNormal(const SModelVertex& vtx,
    47                                 const CMatrix3D newPoseMatrices[])
     61                                const CMatrix3D newPoseMatrices[],
     62                                CVector3D& result)
    4863{
    4964    // To be correct, the normal vectors apparently need to be multiplied by the
    5065    // inverse of the transpose. Unfortunately inverses are slow.
     
    6984    // (This isn't very good as a proof, but it's better than assuming M is
    7085    // orthogonal when it's clearly not.)
    7186
    72     CVector3D result (0, 0, 0);
     87    const uint8_t * const blendBones = vtx.m_Blend.m_Bone;
     88    const float * const blendWeight = vtx.m_Blend.m_Weight;
     89    const CVector3D &normal = vtx.m_Norm;
     90    result *= 0;
     91    if (blendWeight[0] != 0.0 && blendBones[0] != 0xff)
     92            result.mulStore(newPoseMatrices[blendBones[0]].Rotate(normal), blendWeight[0]);
     93    if (blendWeight[1] != 0.0 && blendBones[1] != 0xff)
     94            result.mulAdd(newPoseMatrices[blendBones[1]].Rotate(normal), blendWeight[1]);
     95    if (blendWeight[2] != 0.0 && blendBones[2] != 0xff)
     96            result.mulAdd(newPoseMatrices[blendBones[2]].Rotate(normal), blendWeight[2]);
     97    if (blendWeight[3] != 0.0 && blendBones[3] != 0xff)
     98            result.mulAdd(newPoseMatrices[blendBones[3]].Rotate(normal), blendWeight[3]);
     99    /*
     100    result *= 0;
     101    for (int i = 0; i < SVertexBlend::SIZE && blendBones[i] != 0xff; i++)
     102    {
     103        if (blendWeight[i] != 0.0f)
     104            result.mulAdd(newPoseMatrices[blendBones[i]].Rotate(normal), blendWeight[i]);
     105    }*/
    73106
    74     for (int i = 0; i < SVertexBlend::SIZE && vtx.m_Blend.m_Bone[i] != 0xff; ++i)
    75     {
    76         result += newPoseMatrices[vtx.m_Blend.m_Bone[i]].Rotate(vtx.m_Norm) * vtx.m_Blend.m_Weight[i];
    77     }
    78    
     107
    79108    // If there was more than one influence, the result is probably not going
    80109    // to be of unit length (since it's a weighted sum of several independent
    81110    // unit vectors), so we need to normalise it.
    82111    // (It's fairly common to only have one influence, so it seems sensible to
    83112    // optimise that case a bit.)
    84     if (vtx.m_Blend.m_Bone[1] != 0xff) // if more than one influence
     113    if (blendBones[1] != 0xff) // if more than one influence
    85114        result.Normalize();
    86115
    87116    return result;
     
    88117}
    89118
    90119void CModelDef::SkinPointsAndNormals(
    91         size_t numVertices,
     120        const size_t numVertices,
    92121        const VertexArrayIterator<CVector3D>& Position,
    93122        const VertexArrayIterator<CVector3D>& Normal,
    94         const SModelVertex* vertices,
    95         const size_t* blendIndices,
     123        const SModelVertex* const vertices,
     124        const size_t * const blendIndices,
    96125        const CMatrix3D newPoseMatrices[])
    97126{
    98127    // To avoid some performance overhead, get the raw vertex array pointers
    99     char* PositionData = Position.GetData();
    100     size_t PositionStride = Position.GetStride();
    101     char* NormalData = Normal.GetData();
    102     size_t NormalStride = Normal.GetStride();
     128    char* const PositionData = Position.GetData();
     129    const size_t PositionStride = Position.GetStride();
     130    char* const NormalData = Normal.GetData();
     131    const size_t NormalStride = Normal.GetStride();
    103132
    104     for (size_t j = 0; j < numVertices; ++j)
     133    for (size_t j = 0; j < numVertices; j++)
    105134    {
    106135        const SModelVertex& vtx = vertices[j];
    107136
    108         CVector3D pos = newPoseMatrices[blendIndices[j]].Transform(vtx.m_Coords);
    109         CVector3D norm = newPoseMatrices[blendIndices[j]].Rotate(vtx.m_Norm);
     137        CVector3D pos (newPoseMatrices[blendIndices[j]].Transform(vtx.m_Coords));
     138        CVector3D norm (newPoseMatrices[blendIndices[j]].Rotate(vtx.m_Norm));
    110139
    111140        // If there was more than one influence, the result is probably not going
    112141        // to be of unit length (since it's a weighted sum of several independent
     
    123152
    124153#if ARCH_X86_X64
    125154void CModelDef::SkinPointsAndNormals_SSE(
    126         size_t numVertices,
     155        const size_t numVertices,
    127156        const VertexArrayIterator<CVector3D>& Position,
    128157        const VertexArrayIterator<CVector3D>& Normal,
    129158        const SModelVertex* vertices,
    130         const size_t* blendIndices,
     159        const size_t * const blendIndices,
    131160        const CMatrix3D newPoseMatrices[])
    132161{
    133162    // To avoid some performance overhead, get the raw vertex array pointers
    134163    char* PositionData = Position.GetData();
    135     size_t PositionStride = Position.GetStride();
     164    const size_t PositionStride = Position.GetStride();
    136165    char* NormalData = Normal.GetData();
    137     size_t NormalStride = Normal.GetStride();
     166    const size_t NormalStride = Normal.GetStride();
    138167
    139168    // Must be aligned correctly for SSE
    140169    ASSERT((intptr_t)newPoseMatrices % 16 == 0);
     
    206235void CModelDef::BlendBoneMatrices(
    207236        CMatrix3D boneMatrices[])
    208237{
     238
    209239    for (size_t i = 0; i < m_NumBlends; ++i)
    210240    {
    211241        const SVertexBlend& blend = m_pBlends[i];
    212242        CMatrix3D& boneMatrix = boneMatrices[m_NumBones + 1 + i];
     243        const uint8_t * const blendBones = blend.m_Bone;
     244        const float * const blendWeight = blend.m_Weight;
    213245       
    214246        // Note: there is a special case of joint influence, in which the vertex
    215247        //  is influenced by the bind-shape matrix instead of a particular bone,
     
    218250        //  set up this matrix in boneMatrices.
    219251        //  (see http://trac.wildfiregames.com/ticket/1012)
    220252
    221         boneMatrix.Blend(boneMatrices[blend.m_Bone[0]], blend.m_Weight[0]);
    222         for (size_t j = 1; j < SVertexBlend::SIZE && blend.m_Bone[j] != 0xFF; ++j)
    223             boneMatrix.AddBlend(boneMatrices[blend.m_Bone[j]], blend.m_Weight[j]);
     253        boneMatrix.Blend(boneMatrices[blendBones[0]], blendWeight[0]);
     254        /*
     255        for (size_t j = 1; j < SVertexBlend::SIZE && blendBones[j] != 0xFF; ++j)
     256        {
     257            if (blendWeight[j] != 0.0)
     258                boneMatrix.AddBlend(boneMatrices[blendBones[j]], blendWeight[j]);
     259        }*/     
     260        if (blendWeight[1] != 0.0 && blendBones[1] != 0xff)
     261            boneMatrix.AddBlend(boneMatrices[blendBones[1]], blendWeight[1]);
     262        if (blendWeight[2] != 0.0 && blendBones[2] != 0xff)
     263            boneMatrix.AddBlend(boneMatrices[blendBones[2]], blendWeight[2]);
     264        if (blendWeight[3] != 0.0 && blendBones[3] != 0xff)
     265            boneMatrix.AddBlend(boneMatrices[blendBones[3]], blendWeight[3]);
    224266    }
    225267}
    226268
     
    400442
    401443            for (size_t i = 0; i < mdef->m_NumVertices; ++i)
    402444            {
    403                 mdef->m_pVertices[i].m_Coords = SkinPoint(mdef->m_pVertices[i], &bindPose[0]);
    404                 mdef->m_pVertices[i].m_Norm = SkinNormal(mdef->m_pVertices[i], &bindPose[0]);
     445                mdef->m_pVertices[i].m_Coords = SkinPoint(mdef->m_pVertices[i], &bindPose[0], mdef->m_pVertices[i].m_Coords);
     446                SkinNormal(mdef->m_pVertices[i], &bindPose[0], mdef->m_pVertices[i].m_Norm);
    405447            }
    406448        }
    407449    }
  • source/graphics/ModelDef.h

     
    8484// with multiple bones
    8585struct SVertexBlend
    8686{
    87     enum { SIZE = 4 };
     87    enum { SIZE = 4 }; // WARNING ANY MODIFICATION TO SIZE NEED to add/change loop unroll in SKinPoint/SkinNormal/BlendBonesMatrices
    8888    // index of the influencing bone, or 0xff if none
    8989    u8 m_Bone[SIZE];
    9090    // weight of the influence; all weights sum to 1
     
    193193     * @return new world-space vertex coordinates
    194194     */
    195195    static CVector3D SkinPoint(const SModelVertex& vtx,
    196         const CMatrix3D newPoseMatrices[]);
     196        const CMatrix3D newPoseMatrices[],
     197        CVector3D &result);
    197198
    198199    /**
    199200     * Transform the given vertex's normal from the bind pose into the new pose.
     
    201202     * @return new world-space vertex normal
    202203     */
    203204    static CVector3D SkinNormal(const SModelVertex& vtx,
    204         const CMatrix3D newPoseMatrices[]);
     205        const CMatrix3D newPoseMatrices[],
     206        CVector3D &result);
    205207
    206208    /**
    207209     * Transform vertices' positions and normals.
     
    209211     * but slightly more efficient.)
    210212     */
    211213    static void SkinPointsAndNormals(
    212         size_t numVertices,
     214        const size_t numVertices,
    213215        const VertexArrayIterator<CVector3D>& Position,
    214216        const VertexArrayIterator<CVector3D>& Normal,
    215217        const SModelVertex* vertices,
    216         const size_t* blendIndices,
     218        const size_t* const blendIndices,
    217219        const CMatrix3D newPoseMatrices[]);
    218220
    219221#if ARCH_X86_X64
     
    221223     * SSE-optimised version of SkinPointsAndNormals.
    222224     */
    223225    static void SkinPointsAndNormals_SSE(
    224         size_t numVertices,
     226        const size_t numVertices,
    225227        const VertexArrayIterator<CVector3D>& Position,
    226228        const VertexArrayIterator<CVector3D>& Normal,
    227229        const SModelVertex* vertices,
    228         const size_t* blendIndices,
     230        const size_t* const blendIndices,
    229231        const CMatrix3D newPoseMatrices[]);
    230232#endif
    231233
  • source/maths/Matrix3D.cpp

     
    5858//The following clear the matrix and set the
    5959//rotation of each of the 3 axes
    6060
    61 void CMatrix3D::SetXRotation (float angle)
     61void CMatrix3D::SetXRotation (const float angle)
    6262{
    6363    const float Cos = cosf (angle);
    6464    const float Sin = sinf (angle);
     
    6969    _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f;
    7070}
    7171
    72 void CMatrix3D::SetYRotation (float angle)
     72void CMatrix3D::SetYRotation (const float angle)
    7373{
    7474    const float Cos = cosf (angle);
    7575    const float Sin = sinf (angle);
     
    8080    _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f;
    8181}
    8282
    83 void CMatrix3D::SetZRotation (float angle)
     83void CMatrix3D::SetZRotation (const float angle)
    8484{
    8585    const float Cos = cosf (angle);
    8686    const float Sin = sinf (angle);
     
    9494//The following apply a rotation to the matrix
    9595//about each of the axes;
    9696
    97 void CMatrix3D::RotateX (float angle)
     97void CMatrix3D::RotateX (const float angle)
    9898{
    9999    const float Cos = cosf (angle);
    100100    const float Sin = sinf (angle);
     
    114114    _34 = Sin * tmp_24 + Cos * _34;
    115115}
    116116
    117 void CMatrix3D::RotateY (float angle)
     117void CMatrix3D::RotateY (const float angle)
    118118{
    119119    const float Cos = cosf (angle);
    120120    const float Sin = sinf (angle);
     
    134134    _34 = -Sin * tmp_14 + Cos * _34;
    135135}
    136136
    137 void CMatrix3D::RotateZ (float angle)
     137void CMatrix3D::RotateZ (const float angle)
    138138{
    139139    const float Cos = cosf (angle);
    140140    const float Sin = sinf (angle);
     
    155155}
    156156
    157157//Sets the translation of the matrix
    158 void CMatrix3D::SetTranslation (float x, float y, float z)
     158void CMatrix3D::SetTranslation (const float x, const float y, const float z)
    159159{
    160160    _11=1.0f; _12=0.0f; _13=0.0f; _14=x;
    161161    _21=0.0f; _22=1.0f; _23=0.0f; _24=y;
     
    169169}
    170170
    171171//Applies a translation to the matrix
    172 void CMatrix3D::Translate(float x, float y, float z)
     172void CMatrix3D::Translate(const float x, const float y, const float z)
    173173{
    174174    _14 += x;
    175175    _24 += y;
     
    183183    _34 += vector.Z;
    184184}
    185185
    186 void CMatrix3D::PostTranslate(float x, float y, float z)
     186void CMatrix3D::PostTranslate(const float x, const float y, const float z)
    187187{
    188188    // Equivalent to "m.SetTranslation(x, y, z); *this = *this * m;"
    189189    _14 += _11*x + _12*y + _13*z;
     
    198198}
    199199
    200200//Clears and sets the scaling of the matrix
    201 void CMatrix3D::SetScaling (float x_scale, float y_scale, float z_scale)
     201void CMatrix3D::SetScaling (const float x_scale, const float y_scale, const float z_scale)
    202202{
    203203    _11=x_scale; _12=0.0f;    _13=0.0f;    _14=0.0f;
    204204    _21=0.0f;    _22=y_scale; _23=0.0f;    _24=0.0f;
     
    207207}
    208208
    209209//Scales the matrix
    210 void CMatrix3D::Scale (float x_scale, float y_scale, float z_scale)
     210void CMatrix3D::Scale (const float x_scale, const float y_scale, const float z_scale)
    211211{
    212212    _11 *= x_scale;
    213213    _12 *= x_scale;
  • source/maths/Matrix3D.h

     
    9898    }
    9999
    100100    // matrix multiplication
    101     CMatrix3D operator*(const CMatrix3D &matrix) const
     101    CMatrix3D operator*(const CMatrix3D& matrix) const
    102102    {
    103103        return CMatrix3D(
    104104            _11*matrix._11 + _12*matrix._21 + _13*matrix._31 + _14*matrix._41,
     
    124124    }
    125125
    126126    // matrix multiplication/assignment
    127     CMatrix3D& operator*=(const CMatrix3D &matrix)
     127    CMatrix3D& operator*=(const CMatrix3D& matrix)
    128128    {
    129129        Concatenate(matrix);
    130130        return *this;
     
    142142    }
    143143
    144144    // matrix addition
    145     CMatrix3D operator+(const CMatrix3D &m) const
     145    CMatrix3D operator+(const CMatrix3D& m) const
    146146    {
    147147        return CMatrix3D(
    148148            _11+m._11, _12+m._12, _13+m._13, _14+m._14,
     
    153153    }
    154154
    155155    // matrix addition/assignment
    156     CMatrix3D& operator+=(const CMatrix3D &m)
     156    CMatrix3D& operator+=(const CMatrix3D& m)
    157157    {
    158158        _11 += m._11; _21 += m._21; _31 += m._31; _41 += m._41;
    159159        _12 += m._12; _22 += m._22; _32 += m._32; _42 += m._42;
     
    163163    }
    164164
    165165    // equality
    166     bool operator==(const CMatrix3D &m) const
     166    bool operator==(const CMatrix3D& m) const
    167167    {
    168168        return _11 == m._11 && _21 == m._21 && _31 == m._31 && _41 == m._41 &&
    169169                 _12 == m._12 && _22 == m._22 && _32 == m._32 && _42 == m._42 &&
     
    187187    // concatenate arbitrary matrix onto this matrix
    188188    void Concatenate(const CMatrix3D& m)
    189189    {
    190         (*this) = m * (*this);
     190        //(*this) = m * (*this);
     191        premul(m);
    191192    }
     193    // mul and add wihtout stack alloc
     194    void mulAdd(const CMatrix3D& matrixA, const CMatrix3D& matrixB)
     195    {
     196        _11 +=  matrixA._11*matrixB._11 +matrixA._12*matrixB._21 +matrixA._13*matrixB._31 +matrixA._14*matrixB._41;
     197        _12 +=  matrixA._11*matrixB._12 +matrixA._12*matrixB._22 +matrixA._13*matrixB._32 +matrixA._14*matrixB._42;
     198        _13 +=  matrixA._11*matrixB._13 +matrixA._12*matrixB._23 +matrixA._13*matrixB._33 +matrixA._14*matrixB._43;
     199        _14 +=  matrixA._11*matrixB._14 +matrixA._12*matrixB._24 +matrixA._13*matrixB._34 +matrixA._14*matrixB._44;
     200       
     201        _21 +=  matrixA._21*matrixB._11 +matrixA._22*matrixB._21 +matrixA._23*matrixB._31 +matrixA._24*matrixB._41;
     202        _22 +=  matrixA._21*matrixB._12 +matrixA._22*matrixB._22 +matrixA._23*matrixB._32 +matrixA._24*matrixB._42;
     203        _23 +=  matrixA._21*matrixB._13 +matrixA._22*matrixB._23 +matrixA._23*matrixB._33 +matrixA._24*matrixB._43;
     204        _24 +=  matrixA._21*matrixB._14 +matrixA._22*matrixB._24 +matrixA._23*matrixB._34 +matrixA._24*matrixB._44;
     205       
     206        _31 +=  matrixA._31*matrixB._11 +matrixA._32*matrixB._21 +matrixA._33*matrixB._31 +matrixA._34*matrixB._41;
     207        _32 +=  matrixA._31*matrixB._12 +matrixA._32*matrixB._22 +matrixA._33*matrixB._32 +matrixA._34*matrixB._42;
     208        _33 +=  matrixA._31*matrixB._13 +matrixA._32*matrixB._23 +matrixA._33*matrixB._33 +matrixA._34*matrixB._43;
     209        _34 +=  matrixA._31*matrixB._14 +matrixA._32*matrixB._24 +matrixA._33*matrixB._34 +matrixA._34*matrixB._44;
     210       
     211        _41 +=  matrixA._41*matrixB._11 +matrixA._42*matrixB._21 +matrixA._43*matrixB._31 +matrixA._44*matrixB._41;
     212        _42 +=  matrixA._41*matrixB._12 +matrixA._42*matrixB._22 +matrixA._43*matrixB._32 +matrixA._44*matrixB._42;
     213        _43 +=  matrixA._41*matrixB._13 +matrixA._42*matrixB._23 +matrixA._43*matrixB._33 +matrixA._44*matrixB._43;
     214        _44 +=  matrixA._41*matrixB._14 +matrixA._42*matrixB._24 +matrixA._43*matrixB._34 +matrixA._44*matrixB._44;
     215           
     216    }
     217    // mul and and store wihtout stack alloc
     218    void mul(const CMatrix3D& matrixA, const CMatrix3D& matrixB)
     219    {
     220        _11 =   matrixA._11*matrixB._11 +matrixA._12*matrixB._21 +matrixA._13*matrixB._31 +matrixA._14*matrixB._41;
     221        _12 =   matrixA._11*matrixB._12 +matrixA._12*matrixB._22 +matrixA._13*matrixB._32 +matrixA._14*matrixB._42;
     222        _13 =   matrixA._11*matrixB._13 +matrixA._12*matrixB._23 +matrixA._13*matrixB._33 +matrixA._14*matrixB._43;
     223        _14 =   matrixA._11*matrixB._14 +matrixA._12*matrixB._24 +matrixA._13*matrixB._34 +matrixA._14*matrixB._44;
     224       
     225        _21 =   matrixA._21*matrixB._11 +matrixA._22*matrixB._21 +matrixA._23*matrixB._31 +matrixA._24*matrixB._41;
     226        _22 =   matrixA._21*matrixB._12 +matrixA._22*matrixB._22 +matrixA._23*matrixB._32 +matrixA._24*matrixB._42;
     227        _23 =   matrixA._21*matrixB._13 +matrixA._22*matrixB._23 +matrixA._23*matrixB._33 +matrixA._24*matrixB._43;
     228        _24 =   matrixA._21*matrixB._14 +matrixA._22*matrixB._24 +matrixA._23*matrixB._34 +matrixA._24*matrixB._44;
     229       
     230        _31 =   matrixA._31*matrixB._11 +matrixA._32*matrixB._21 +matrixA._33*matrixB._31 +matrixA._34*matrixB._41;
     231        _32 =   matrixA._31*matrixB._12 +matrixA._32*matrixB._22 +matrixA._33*matrixB._32 +matrixA._34*matrixB._42;
     232        _33 =   matrixA._31*matrixB._13 +matrixA._32*matrixB._23 +matrixA._33*matrixB._33 +matrixA._34*matrixB._43;
     233        _34 =   matrixA._31*matrixB._14 +matrixA._32*matrixB._24 +matrixA._33*matrixB._34 +matrixA._34*matrixB._44;
     234       
     235        _41 =   matrixA._41*matrixB._11 +matrixA._42*matrixB._21 +matrixA._43*matrixB._31 +matrixA._44*matrixB._41;
     236        _42 =   matrixA._41*matrixB._12 +matrixA._42*matrixB._22 +matrixA._43*matrixB._32 +matrixA._44*matrixB._42;
     237        _43 =   matrixA._41*matrixB._13 +matrixA._42*matrixB._23 +matrixA._43*matrixB._33 +matrixA._44*matrixB._43;
     238        _44 =   matrixA._41*matrixB._14 +matrixA._42*matrixB._24 +matrixA._43*matrixB._34 +matrixA._44*matrixB._44;
     239           
     240    }
     241   
     242    // matrix pre multiplication wihtout object alloc.
     243    void premul(const CMatrix3D& matrixA)
     244    {   
     245        const float __11 = matrixA._11*_11 + matrixA._12*_21 + matrixA._13*_31 + matrixA._14*_41;
     246        const float __12 = matrixA._11*_12 + matrixA._12*_22 + matrixA._13*_32 + matrixA._14*_42;
     247        const float __13 = matrixA._11*_13 + matrixA._12*_23 + matrixA._13*_33 + matrixA._14*_43;
     248        const float __14 = matrixA._11*_14 + matrixA._12*_24 + matrixA._13*_34 + matrixA._14*_44;
     249             
     250        const float __21 = matrixA._21*_11 + matrixA._22*_21 + matrixA._23*_31 + matrixA._24*_41;
     251        const float __22 = matrixA._21*_12 + matrixA._22*_22 + matrixA._23*_32 + matrixA._24*_42;
     252        const float __23 = matrixA._21*_13 + matrixA._22*_23 + matrixA._23*_33 + matrixA._24*_43;
     253        const float __24 = matrixA._21*_14 + matrixA._22*_24 + matrixA._23*_34 + matrixA._24*_44;
     254             
     255        const float __31 = matrixA._31*_11 + matrixA._32*_21 + matrixA._33*_31 + matrixA._34*_41;
     256        const float __32 = matrixA._31*_12 + matrixA._32*_22 + matrixA._33*_32 + matrixA._34*_42;
     257        const float __33 = matrixA._31*_13 + matrixA._32*_23 + matrixA._33*_33 + matrixA._34*_43;
     258        const float __34 = matrixA._31*_14 + matrixA._32*_24 + matrixA._33*_34 + matrixA._34*_44;
     259             
     260        const float __41 = matrixA._41*_11 + matrixA._42*_21 + matrixA._43*_31 + matrixA._44*_41;
     261        const float __42 = matrixA._41*_12 + matrixA._42*_22 + matrixA._43*_32 + matrixA._44*_42;
     262        const float __43 = matrixA._41*_13 + matrixA._42*_23 + matrixA._43*_33 + matrixA._44*_43;
     263        const float __44 = matrixA._41*_14 + matrixA._42*_24 + matrixA._43*_34 + matrixA._44*_44;
    192264
     265        _11 = __11;
     266        _21 = __21;
     267        _31 = __31;
     268        _41 = __41;
     269         
     270        _12 = __12;
     271        _22 = __22;
     272        _32 = __32;
     273        _42 = __42;
     274         
     275        _13 = __13;
     276        _23 = __23;
     277        _33 = __33;
     278        _43 = __43;
     279         
     280        _14 = __14;
     281        _24 = __24;
     282        _34 = __34;
     283        _44 = __44;
     284
     285    }
     286    // matrix multiplication wihtout object alloc.
     287    void mul(const CMatrix3D& matrixB)
     288    {   
     289        float __1, __2, __3, __4;
     290
     291        __1 = _11*matrixB._11 + _12*matrixB._21 + _13*matrixB._31 + _14*matrixB._41;
     292        __2 = _11*matrixB._12 + _12*matrixB._22 + _13*matrixB._32 + _14*matrixB._42;
     293        __3 = _11*matrixB._13 + _12*matrixB._23 + _13*matrixB._33 + _14*matrixB._43;
     294        __4 = _11*matrixB._14 + _12*matrixB._24 + _13*matrixB._34 + _14*matrixB._44;
     295             
     296        _11 = __1;  _12 = __2;  _13 = __3;  _14 = __4;
     297
     298        __1 = _21*matrixB._11 + _22*matrixB._21 + _23*matrixB._31 + _24*matrixB._41;
     299        __2 = _21*matrixB._12 + _22*matrixB._22 + _23*matrixB._32 + _24*matrixB._42;
     300        __3 = _21*matrixB._13 + _22*matrixB._23 + _23*matrixB._33 + _24*matrixB._43;
     301        __4 = _21*matrixB._14 + _22*matrixB._24 + _23*matrixB._34 + _24*matrixB._44;
     302             
     303        _21 = __1;  _22 = __2;  _23 = __3;  _24 = __4;
     304
     305        __1 = _31*matrixB._11 + _32*matrixB._21 + _33*matrixB._31 + _34*matrixB._41;
     306        __2 = _31*matrixB._12 + _32*matrixB._22 + _33*matrixB._32 + _34*matrixB._42;
     307        __3 = _31*matrixB._13 + _32*matrixB._23 + _33*matrixB._33 + _34*matrixB._43;
     308        __4 = _31*matrixB._14 + _32*matrixB._24 + _33*matrixB._34 + _34*matrixB._44;
     309             
     310        _31 = __1;  _32 = __2;  _33 = __3;  _34 = __4;
     311
     312        __1 = _41*matrixB._11 + _42*matrixB._21 + _43*matrixB._31 + _44*matrixB._41;
     313        __2 = _41*matrixB._12 + _42*matrixB._22 + _43*matrixB._32 + _44*matrixB._42;
     314        __3 = _41*matrixB._13 + _42*matrixB._23 + _43*matrixB._33 + _44*matrixB._43;
     315        __4 = _41*matrixB._14 + _42*matrixB._24 + _43*matrixB._34 + _44*matrixB._44;
     316       
     317        _41 = __1;  _42 = __2;  _43 = __3;  _44 = __4;
     318    }
    193319    // blend matrix using only 4x3 subset
    194     void Blend(const CMatrix3D& m, float f)
     320    void Blend(const CMatrix3D& m, const float f)
    195321    {
    196322        _11 = m._11*f; _21 = m._21*f; _31 = m._31*f;
    197323        _12 = m._12*f; _22 = m._22*f; _32 = m._32*f;
     
    200326    }
    201327
    202328    // blend matrix using only 4x3 and add onto existing blend
    203     void AddBlend(const CMatrix3D& m, float f)
     329    void AddBlend(const CMatrix3D& m, const float f)
    204330    {
    205331        _11 += m._11*f; _21 += m._21*f; _31 += m._31*f;
    206332        _12 += m._12*f; _22 += m._22*f; _32 += m._32*f;
  • source/maths/Vector3D.h

     
    8181        {
    8282            return CVector3D(X * value, Y * value, Z * value);
    8383        }
     84       
     85        void mulAdd(const CVector3D& vector, const float value)
     86        {
     87            X += vector.X * value;
     88            Y += vector.Y * value;
     89            Z += vector.Z * value;
     90        }
     91        void mulStore(const CVector3D& vector, const float value)
     92        {
     93            X = vector.X * value;
     94            Y = vector.Y * value;
     95            Z = vector.Z * value;
     96        }
     97        void mul(const float value)
     98        {
     99            X *= value;
     100            Y *= value;
     101            Z *= value;
     102        }
    84103
    85104        CVector3D& operator*=(float value)
    86105        {