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