Preserve volume in game engine

In Blender 2.57b when applying armature ‘preserve volume’ option preview with character works just fine, but in game engine it does not work (works as if no preserve volume). Anyone can say - if this is bug or feature or if it is possible to fix somehow?

edit: basic example http://www.sim-ai.org/Armature.blend - simple mesh with armature applied,
press P and see there result - as if preserve volume is not applied

I have not used armatures in the BGE yet, so I’m not the one to tell if You made a mistake or not…

but… if not this sort under missing features and an impotent one in my opinion.

Found where this happens, while transferring objects to game engine

bool BL_SkinDeformer::UpdateInternal(bool shape_applied)

modifier

armature_deform_verts( par_arma, m_objMesh, NULL, m_transverts, NULL, m_bmesh->totvert,ARM_DEF_VGROUP, NULL, NULL );

, is called with ARM_DEF_VGROUP flag ( no other flags are present )

I will try to apply other flags ( not sure if it affect anything else ) ( at least setting ARM_DEF_QUATERNION restores functionality in example )
so looks like a bug, which can be avoided.

so I added short deformflag; to class BL_SkinDeformer : public BL_MeshDeformer

and modified constructor

BL_SkinDeformer::BL_SkinDeformer(BL_DeformableGameObject gameobj,
struct Object bmeshobj,
class RAS_MeshObject mesh,
BL_ArmatureObject
arma)
: //
BL_MeshDeformer(gameobj, bmeshobj, mesh),
m_armobj(arma),
m_lastArmaUpdate(-1),
//m_defbase(&bmeshobj->defbase),
m_releaseobject(false),
m_poseApplied(false),
m_recalcNormal(true)
{
copy_m4_m4(m_obmat, bmeshobj->obmat);
deformflag = ARM_DEF_VGROUP;
ModifierData
md;
for (md = (ModifierData
)bmeshobj->modifiers.first; md; md = (ModifierData*)md->next) {
/* armature modifier are handled by SkinDeformer, not ModifierDeformer /
if (md->type == eModifierType_Armature )
{
//continue;
deformflag |= ((ArmatureModifierData
)md)->deformflag;
break;
}

}

};

now bool BL_SkinDeformer::UpdateInternal(bool shape_applied) looks like:

bool BL_SkinDeformer::UpdateInternal(bool shape_applied)
{
/* See if the armature has been updated for this frame */
if (PoseUpdated()){
float obmat[4][4]; // the original object matrice

    /* XXX note: where_is_pose() (from BKE_armature.h) calculates all matrices needed to start deforming */
    /* but it requires the blender object pointer... */
    Object* par_arma = m_armobj->GetArmatureObject();

    //ArmatureModifierData *amd = (ArmatureModifierData*) md;

    if(!shape_applied) {
        /* store verts locally */
        VerifyStorage();
    
        /* duplicate */
        for (int v =0; v<m_bmesh->totvert; v++)
            VECCOPY(m_transverts[v], m_bmesh->mvert[v].co);
    }

    m_armobj->ApplyPose();

    // save matrix first
    copy_m4_m4(obmat, m_objMesh->obmat);
    // set reference matrix
    copy_m4_m4(m_objMesh->obmat, m_obmat);

    armature_deform_verts( par_arma, m_objMesh, NULL, m_transverts, NULL, m_bmesh->totvert, deformflag /*ARM_DEF_VGROUP*/, NULL, NULL );
    
    // restore matrix 
    copy_m4_m4(m_objMesh->obmat, obmat);

#ifdef __NLA_DEFNORMALS
if (m_recalcNormal)
RecalcNormals();
#endif

    /* Update the current frame */
    m_lastArmaUpdate=m_armobj->GetLastFrame();

    m_armobj->RestorePose();
    /* dynamic vertex, cannot use display list */
    m_bDynamic = true;
    /* indicate that the m_transverts and normals are up to date */
    return true;
}

return false;

}

now I have properly preserved volume.
But not sure if this is correct way to make things - so if someone of devs could look into issue, that will be fine

I suggest You open a bug report and attach the patch. Then hopfully some devs will look at it!

Yes submitted.

still besides the fix for example I’m not sure it is right approach (or any side effects ), but hopefully someone will pay attention.

In any case You are intiteld to feel like a hero for some time :slight_smile: