snake5 icon

anim.deformer code fix

snake5 | PRO | 11/04/15 09:24:16 PM UTC | 0 ⭐ | 754 👁️ | Never ⏰ | []
C++ |

2.77 KB

|

None

|

0 👍

/

0 👎

    // produce animation data
#if 1
    for( int i = 0; i < count; ++i )
    {
        m_positions[ i ] = animSource->m_positions[ i ];
        m_rotations[ i ] = animSource->m_rotations[ i ];
        m_scales[ i ] = animSource->m_scales[ i ];
        m_factors[ i ] = animSource->m_factors[ i ];
    }
    if( count > 0 )
    {
        Vec3 off = m_bonePositions[ 0 ] - posns[ 0 ];
        m_positions[ 0 ] += m_invSkinOffsets[ 0 ].TransformNormal( off );
    }
    Mat4 skinXF[ SGRX_MAX_MESH_BONES ];
    for( int i = 0; i < count; ++i )
    {
        skinXF[ i ] = m_mesh->m_bones[ i ].boneOffset;
        if( i > 0 )
        {
            int pid = GetParentBoneID( i );
            skinXF[ i ] = skinXF[ i ] * skinXF[ pid ];
        }
        
        // gather average global target/local original child pos.
        Vec3 avgtgt = V3(0);
        Vec3 avgpos = V3(0);
        int cc = 0;
        for( int ch = i + 1; ch < count; ++ch )
        {
            if( GetParentBoneID( ch ) != i )
                continue;
            avgtgt += m_bonePositions[ ch ];
            avgpos += posns[ ch ];
            cc++;
        }
        
        if( cc == 0 )
            continue;
        
        avgpos /= cc;
        avgtgt /= cc;
        
        Mat4 curxf = Mat4::CreateSRT( m_scales[ i ], m_rotations[ i ], m_positions[ i ] );
        Mat4 inv = Mat4::Identity;
        ( curxf * skinXF[ i ] ).InvertTo( inv );
        avgtgt = inv.TransformPos( avgtgt ).Normalized();
        avgpos = m_invSkinOffsets[ i ].TransformPos( avgpos ).Normalized();
        m_rotations[ i ] = m_rotations[ i ] * Quat::CreateAxisAxis( avgpos, avgtgt );
        
        skinXF[ i ] = Mat4::CreateSRT(
            m_scales[ i ], m_rotations[ i ], m_positions[ i ] ) * skinXF[ i ];
        
        m_factors[ i ] = 1;
    }
#else
    for( int i = 0; i < count; ++i )
    {
        m_positions[ i ] = animSource->m_positions[ i ];
        m_rotations[ i ] = animSource->m_rotations[ i ];
        m_scales[ i ] = animSource->m_scales[ i ];
        m_factors[ i ] = animSource->m_factors[ i ];
        
        int pid = GetParentBoneID( i );
        if( pid >= 0 )
        {
            // rotate bone with axis/angle in bone space
            Vec3 nmdir = m_bonePositions[ i ] - m_bonePositions[ pid ];
            Vec3 omdir = dirs[ i ];
            
            Vec3 tf_nmdir = m_invSkinOffsets[ i ].TransformNormal( nmdir ).Normalized();
            Vec3 tf_omdir = m_invSkinOffsets[ i ].TransformNormal( omdir ).Normalized();
            m_rotations[ i ] = m_rotations[ i ] * Quat::CreateAxisAxis( tf_omdir, tf_nmdir );
            
            // rotate child bones backwards
            for( int ch = i + 1; ch < count; ++ch )
            {
                if( GetParentBoneID( ch ) != i )
                    continue;
                tf_nmdir = m_invSkinOffsets[ ch ].TransformNormal( nmdir ).Normalized();
                tf_omdir = m_invSkinOffsets[ ch ].TransformNormal( omdir ).Normalized();
                m_rotations[ ch ] = m_rotations[ ch ] * Quat::CreateAxisAxis( tf_nmdir, tf_omdir );
            }
        }
        else
        {
            // move bone set in world space
            m_positions[ i ] += m_invSkinOffsets[ i ].TransformNormal( m_bonePositions[ i ] - posns[ i ] );
        }
        m_factors[ i ] = 1;
    }
#endif

Comments