Problems with MorphMixer and Bones



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 15/10/2004 at 14:29, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   8.503 
    Platform:   Windows  ;   
    Language(s) :     C++  ;

    ---------
    Instead of morph Objects, I'm storing the morph information in tags attached to the bones (just for organization - no direct effect on bones). But, the MorphMixer object is causing problems with the geometry as long as bones are fixed. Here's the general hierarchy:

    PolygonObject
    -- MorphMixer Object
    -- Bone MorphTag|MorphTag|...
    -----Bone MorphTag|MorphTag|...
    -----Bone MorphTag|MorphTag|...
    -----etc. on Bone Hierarchy

    Now, the morph sliders are working, the morphs are working, but the cause of the distortion on the overall geometry is hard to determine. Well, here's is the code for applying the morphs. If you see a problem needing attention or have an alternative methodology, please help!

      
    // Create morphed object  
    BaseObject *MorphMixerObject::GetVirtualObjects(PluginObject *op, HierarchyHelp *hh)  
    {  
         Bool               dirty;  
         LONG               index = MORPHMIXER_POSEOFFSET;  
         Vector               *destadr = NULL;  
         BaseObject          *ret = NULL, *orig;  
         BaseContainer     *data = op->GetDataInstance();  
      
         // Get Polygonal Object receiving morphs, return NULL if none  
         if (!(orig = op->GetUp()) || !orig->IsInstanceOf(Opoint)) return NULL;  
      
         // check cache for validity and check master object for changes  
         dirty = op->CheckCache(hh) || op->IsDirty(DIRTY_DATA);  
         orig->Touch();  
         if (!dirty) return op->GetCache(hh);  
      
         // Clone base object  
         if (!(ret = (BaseObject* )orig->GetClone(COPY_NO_HIERARCHY|COPY_NO_ANIMATION|COPY_NO_BITS,NULL))) return NULL;  
         // and transfer tags  
         if (!op->CopyTagsTo(ret,NOTOK,NOTOK,FALSE,NULL))  
         {  
              BaseObject::Free(ret);  
              return NULL;  
         }  
         // transfer name  
         ret->SetName(op->GetName());  
      
         // retrieve destination and base points  
         destadr = ((PolygonObject* )ret)->GetPoint();  
      
         ApplyMorph(GetActiveDocument(), op->GetNext(), orig, destadr, data, &index;);  
      
         // send update message  
         ret->Message(MSG_UPDATE);  
         return ret;  
    }  
    // Apply Morph to MorphMixer- recursive  
    void MorphMixerObject::ApplyMorph(BaseDocument *doc, BaseObject *obj, BaseObject *mobj, Vector *dest, BaseContainer *bc, LONG *index)  
    {  
         LONG               nr;  
         Real               strength;  
         LONG               *indices, *lind;  
         Vector               *deltas;  
         BaseContainer     *pbc;  
         BaseObject          *mo;  
         PluginTag          *pt;  
         struct morphData mData;  
         mData.bGet = TRUE;  
         mData.indices = NULL;  
      
         for (; obj; obj = obj->GetNext())  
         {  
              // Apply related Morphs to MorphMixer list  
              for (nr = 0; pt = (PluginTag* )obj->GetTag(ID_MORPHTAG, nr); nr++)  
              {  
                   // Verify morph object  
                   pbc = pt->GetDataInstance();  
                   if ((mo = pbc->GetObjectLink(MORPHTAG_OPOLYGON_LINK, doc)) != mobj) continue;  
      
                   // Get morph percentage from slider  
                   strength = bc->GetReal(*index);  
      
                   // Get morph point count, indices, and deltas  
                   pt->Message(MSG_CHANGE, &mData;);  
                   indices = mData.indices;  
                   deltas = mData.morphs;  
                   lind = indices+pbc->GetLong(MORPHTAG_MCOUNT_LONG);  
      
                   // Add weighted morph  
                   for (; indices != lind; indices++, deltas++)  
                        dest[*indices] += (*deltas * strength);  
      
                   (*index)++;  
              }  
              ApplyMorph(doc, obj->GetDown(), mobj, dest, bc, index);  
         }  
    }  
    

    Thanks,
    Robert



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 15/10/2004 at 17:22, xxxxxxxx wrote:

    Addendum:

    I find that if I move the MorphMixer object above the mesh object (the one being morphed) and change all of my references to boot, the distortion of the mesh object disappears (yay!), but now, as in another message, the bones do not respond (do not deform the mesh). If I disable the MorphMixer object, the bones work. If I enable it, they don't.

    What needs to be done to fix this?

    Thanks,
    Robert



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 16/10/2004 at 23:58, xxxxxxxx wrote:

    Anyone? Here's the updated code which seems to allow bones to work, but now the morphs 'snap' back as soon as the slider is released. Note that I'm fiddling with the GetClone() flags to see if something works.

      
    // Create morphed object  
    BaseObject *MorphMixerObject::GetVirtualObjects(PluginObject *op, HierarchyHelp *hh)  
    {  
         Bool               dirty;  
         LONG               index = MORPHMIXER_POSEOFFSET;  
         Vector               *destadr;  
         BaseObject          *ret, *orig;  
         BaseContainer     *data = op->GetDataInstance();  
      
         // Get Polygonal Object receiving morphs, return NULL if none  
         if (!(orig = op->GetDown()) || !orig->IsInstanceOf(Opoint)) return NULL;  
      
         // check cache for validity and check master object for changes  
         //op->CheckCache(hh) ||   
         dirty = op->IsDirty(DIRTY_DATA|DIRTY_MATRIX);  
         op->Touch();  
         if (!dirty) return op->GetCache(hh);  
      
         // Clone base object  
         if (!(ret = (BaseObject* )orig->GetClone(COPY_NO_HIERARCHY/*|COPY_NO_ANIMATION|COPY_NO_BITS*/,NULL))) return NULL; //throw ErrorException(ERROR_MEMORY, "MorphMixerObject.GetVirtualObjects.ret");  
         // and transfer tags  
         if (!op->CopyTagsTo(ret,TRUE,FALSE,FALSE,NULL))  
         {  
              BaseObject::Free(ret);  
              return NULL; //throw ErrorException(ERROR_MEMORY, "MorphMixerObject.GetVirtualObjects.CopyTagsTo()");  
         }  
         // transfer name  
         ret->SetName(op->GetName());  
      
         // retrieve destination and base points  
         destadr = ToPoly(ret)->GetPoint();  
      
         ApplyMorph(GetActiveDocument(), orig->GetDown(), orig, destadr, data, &index;);  
      
         // send update message  
         ret->Message(MSG_UPDATE);  
         return ret;  
    }  
    

    Thanks,
    Robert


Log in to reply