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.