Animate objects



  • On 13/11/2014 at 21:03, xxxxxxxx wrote:

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

    ---------
    Hi Folks,
     
    how do I animate a cloned object that has children using the expression priority? I'm currently using the ObjectData plugin's Execute function to test for frame changes, and if true, am running another function that animates the cloned objects. A bit like the following:

    // pseudo code - functions from ObjectData plugin
     
    void MyObject::Execute(...)
    {
        // get current document frame here, test against class-level variable Previous_Frame
     
        if(Current_Frame != Previous_Frame)
        {
            RunUpdate();
        }
    }
     
    void MyObject::RunUpdate(void)
    {
        // get document and animate cloned/held objects here
     
        BaseTime time;
     
        // set time to animate with here
     
        doc->AnimateObject(obj_clone,time,ANIMATEFLAGS_0);
    }
    

    The problem I'm facing is that some of the cloned objects are housing children which use the Expression priority, and hence are not being animated (docs say AnimateObject() doesn't account for expressions). I've also tried the ExecutePasses(), but the program seems to get caught in an endless loop.
     
    Is there a way to accomplish the animating of these cloned objects whose children are using the Expression priority? Or is this going to have to involve using something like a temporary document and polygonizing the scene?
     
    Cheers,
     
    WP.



  • On 14/11/2014 at 09:03, xxxxxxxx wrote:

    Hi,
    can you give me some more information? Perhaps also some more code, which I could throw into one of my projects?



  • On 14/11/2014 at 20:58, xxxxxxxx wrote:

    Hi Andreas,
    yeah sure. There's three parts to the process, GVO (to return the objects), Execution to test for any frame changes, and a custom function to animate/update the clones in question. I've taken some unrelated code out, which pretty much leaves the following:

      
    NOTES:  
    - Clones is the object plugin's class level struct container that holds various arrays used for and with cloned objects  
    - Refresh_Clones is a bool flag that I can use to trigger a manual 'redraw/rebuild' of the object hierarchy in GVO  
    - Plugin is an ObjectData plugin, with the over-ridden AddToExecution(BaseObject* op,PriorityList* list) included  
    

      
    BaseObject* MyObjectPlugin::GetVirtualObjects(BaseObject* op,HierarchyHelp* hh)  
    {  
     if(Refresh_Clones == TRUE || op->CheckCache(hh) == TRUE)  
     {  
      BaseObject *MasterNuller = BaseObject::Alloc(Onull);  
      for(int i = 1; i <= 1;)  
      {  
       if(Clones[i].ClonedObj != NULL)  
       {  
        Clones.ClonedObj[i]->Remove();  
        Clones.ClonedObj[i]->InsertUnderLast(MasterNuller);  
       }  
          
       i++;  
      }  
      Refresh_Clones = FALSE;  
      return MasterNuller;  
     }  
        
     return op->GetCache(hh);  
    }   
    

      
    EXECUTIONRESULT MyObjectPlugin::Execute(BaseObject* op,BaseDocument* doc,BaseThread* bt,LONG priority,EXECUTIONFLAGS flags)  
    {  
     GeData data;  
     doc->GetParameter(DOCUMENT_TIME,data,DESCFLAGS_GET_0);  
     Current_Frame = data.GetTime().GetFrame(doc->GetFps());  
     GePrint("Execute(..) called..");  
     if(Previous_Frame != Current_Frame)  
     {  
      // for the purpose of this, I'll just loop through the one object.   
      // In practice, there could be 2,3 or 4 separately cloned objects,  
      // which each may hold children and an object hierarchy.  
        
      for(int i = 1; i <= 1;)  
      {  
       if(Clones.ClonedObj[i].Clone != NULL && Clones.Display[i] == TRUE)  
       {  
        AnimateClonedProp(doc,i,Current_Frame);  
        EventAdd();  
       }  
       i++;  
      }  
       
      Previous_Frame = Current_Frame;  
     }  
     else  
     {  
      GePrint("Frame has not changed..");  
     }  
        return EXECUTIONRESULT_OK;  
    }  
    
      
    bool MyObjectPlugin::AnimateClonedProp(BaseDocument* doc,int id,int frame)  
    {  
     //   
     //GePrint("Animating and offsetting prop " + LongToString(id) + " by " + LongToString(Clones.Offset[i] * -1.0) + " frames..");  
     //GePrint("Clip.FPs = " + RealToString(Clip.FPs) + " \57 Numerator = " + RealToString(frame + (Clones.Offset[i] * -1.0)));  
       
     Clones.Time.SetDenominator(Clip.FPs);  
     Clones.Time.SetNumerator(frame + (Clones[id].Offset[id] * -1.0));  
     doc->AnimateObject(Clones.ClonedObj[id]Clone,Clones.Time,ANIMATEFLAGS_0);  
     BaseObject *SetHierarchyTester = Clones.ClonedObj[i].Clone->GetDown();  
        
     while(SetHierarchyTester != NULL)  
     {  
      AnimateClonedProp(doc,SetHierarchyTester,id,Clones.ClonedObj[id].Clone);  
      SetHierarchyTester = SetHierarchyTester->GetNext();  
     }  
     //doc->ExecutePasses(NULL,TRUE,TRUE,TRUE,BUILDFLAGS_0);  
     //SetHierarchyTester = NULL;  
     //Refresh_Clones = TRUE;  
     return TRUE;  
    }  
    

    I know there's a few things that probably stick out in the above, but I've left them in just to show where I ended up at! If you need more info let me know. Just FYI, the Clones struct containers are sized/filled when an object is dragged into a link field. I've been testing the code and animation by dropping the content browser's CMotion animated T-Rex under a null object, then dragging/dropping the null object into my plugin's link field. The result I get is that only one object seems to be animated - I don't know which one - but the TRex's mesh etc is all there, so the clone itself appears to be fine. Cheers,
     
    WP.


Log in to reply