On 20/04/2015 at 13:19, xxxxxxxx wrote:
Hi Andreas,
Yes of course - I've reduced this down as much as possible to avoid a massive posting, so this just has the MoData related bits:
MoData * CAGenerator::GetMoData()
{
if (!IsLibraryInstalled(MODATALIB_ID))
return nullptr;
BaseObject * obj = (BaseObject* )Get();
BaseTag * motag = obj->GetTag(ID_MOTAGDATA);
if (motag == nullptr)
motag = obj->MakeTag(ID_MOTAGDATA);
if (motag == nullptr)
return nullptr;
BaseTag * mocachetag = obj->GetTag(ID_MOBAKETAG);
GetMoDataMessage msg = GetMoDataMessage();
msg.index = 0;
if (mocachetag)
{
mocachetag->Message(MSG_GET_MODATA, &msg);
if (msg.modata)
mdcached = TRUE;
}
if (!msg.modata)
{
mdcached = FALSE;
if (!motag->Message(MSG_GET_MODATA, &msg) || !msg.modata)
return nullptr;
}
if (msg.user_owned)
mduserowned = TRUE;
else
mduserowned = FALSE;
return msg.modata;
}
Bool CAGenerator::AddDefaultArrays(MoData * md)
{
if (md->AddArray(MODATA_MATRIX, DTYPE_MATRIX, "Matrix") == NOTOK) return FALSE;
if (md->AddArray(MODATA_COLOR, DTYPE_VECTOR, "Color") == NOTOK) return FALSE;
if (md->AddArray(MODATA_SIZE, DTYPE_VECTOR, "Size") == NOTOK) return FALSE;
if (md->AddArray(MODATA_UVW, DTYPE_VECTOR, "UVW") == NOTOK) return FALSE;
if (md->AddArray(MODATA_FLAGS, DTYPE_LONG, "Flags", MOGENFLAG_CLONE_ON) == NOTOK) return FALSE;
if (md->AddArray(MODATA_WEIGHT, DTYPE_REAL, "Weight") == NOTOK) return FALSE;
if (md->AddArray(MODATA_CLONE, DTYPE_REAL, "Clone") == NOTOK) return FALSE;
if (md->AddArray(MODATA_TIME, DTYPE_REAL, "Time") == NOTOK) return FALSE;
if (md->AddArray(MODATA_LASTMAT, DTYPE_MATRIX, "Last matrix") == NOTOK) return FALSE;
if (md->AddArray(MODATA_STARTMAT, DTYPE_MATRIX, "Start matrix") == NOTOK) return FALSE;
if (md->AddArray(MODATA_ALT_INDEX, DTYPE_LONG, "Alt index") == NOTOK) return FALSE;
if (md->AddArray(MODATA_FALLOFF_WGT, DTYPE_REAL, "Falloff weight") == NOTOK) return FALSE;
return TRUE;
}
BaseObject* CAGenerator::GetVirtualObjects(BaseObject* op, HierarchyHelp* hh)
{
BaseContainer * data = op->GetDataInstance();
const CustomDataType * effectorsraw = data->GetCustomDataType(ID_MG_MOTIONGENERATOR_EFFECTORLIST, CUSTOMDATATYPE_INEXCLUDE_LIST);
InExcludeData * effectors = nullptr;
if (effectorsraw)
effectors = (InExcludeData* )effectorsraw;
MoData * md = GetMoData();
//If not dirty, return cache
if (!op->CheckCache(hh))
{
if (md && mduserowned)
MoData::Free(md);
return op->GetCache(hh);
}
main = BaseObject::Alloc(Onull);
if (!main) goto Error;
//generate a bunch of objects to insert under main
//run mograph
if (md) //I've also tried skipping this bit in case the MoData was retrieved from the MOBAKETAG
{
{
AutoLocker al(md->GetAutoLock()); //I've tried with and without this
//mograph arrays
MDArray<Matrix> matarray;
md->SetCount(objects->GetCount());
AddDefaultArrays(md);
matarray = md->GetMatrixArray(MODATA_MATRIX);
for (Int i = 0; i < objects->GetCount(); i++)
{
matarray[i].off = position; //this is the start position of our generated objects
}
}
//run effectors
if (effectors)
{
Effector_PassData emsg = Effector_PassData();
emsg.op = op;
emsg.md = md;
emsg.weight = 1.0;
emsg.thread = nullptr;
for (Int i = 0; i < effectors->GetObjectCount(); i++)
{
BaseObject * e = (BaseObject* )effectors->ObjectFromIndex(doc, i);
if (!e) continue;
if (!e->GetDeformMode()) continue;
e->Message(MSG_EXECUTE_EFFECTOR, &emsg);
}
}
}
//use altered MoData here - use the matrix offset array to reposition our generated objects
if (md && mduserowned)
MoData::Free(md);
return main;
Error:
if (md && mduserowned)
MoData::Free(md);
blDelete(main);
return NULL;
}
Thanks for taking the time to look through this,
Dan