PLA animation in C++?
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 04/01/2005 at 20:41, xxxxxxxx wrote:
User Information:
Cinema 4D Version: 8.012
Platform: Windows ;
Language(s) : C++ ;---------
Okay, I've checked out every topic on this board. The few which deal with PLA keys and such are strictly COFFEE. C++ does not have a PLATrack and there is not a single example or clue on how to go about creating track, sequence, keys (at the last has a PLAKey) for PLA in C++.Just ONE example would be nice. Maybe I'm not getting it, but I don't even know whether to use AllocValueTrack(), AllocDataTrack() (my choice), or AllocTimeTrack().
Help and thanks,
Robert -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 05/01/2005 at 00:55, xxxxxxxx wrote:
I think that I have it figured out. Setting the VariableTag data size had me stuck until I realized VariableChanged was the only way to update the size.
Once and for all, the first topic with PLA keys in C++:
// Create PLA Key from specified source and destination BaseDocument doc, BaseObject obj, BaseTime time void AnimLoader::CreatePLAKey(PointObject *sobj, BaseDocument *ddoc, BaseObject *dobj, const BaseTime &time;) { BaseTrack *track; // Check for Spla track, create if none if (!(track = dobj->GetTrack(Spla))) { if (!(track = BaseTrack::Alloc(Spla))) throw ErrorException(ERROR_MEMORY, "AnimLoader.CreateKeyFrame.track"); ddoc->AddUndo(UNDO_NEW, track); dobj->InsertTrackLast(track); } // Check for Spla sequence, create if none BaseSequence *seq = NULL; for (seq = track->GetFirstSequence(); seq; seq = seq->GetNext()) { if ((time >= seq->GetT1()) && (time <= seq->GetT2())) break; } if (!seq) { if (!(seq = track->AutoAddSequence(ddoc, time))) throw ErrorException(ERROR_MEMORY, "AnimLoader.CreateKeyFrame.seq"); ddoc->AddUndo(UNDO_NEW, seq); } // Add KeyFrame PLAKey *key; if (!(key = PLAKey::Alloc())) throw ErrorException(ERROR_MEMORY, "AnimLoader.CreateKeyFrame.key"); ddoc->AddUndo(UNDO_NEW, key); key->SetTime(time); seq->InsertKey(key); // Add PLA data LONG count = sobj->GetPointCount(); VariableTag *vtag; if (!(vtag = key->GetPointTag())) throw ErrorException(ERROR_MEMORY, "AnimLoader.CreateKeyFrame.vtag"); // Update array size of vtag VariableChanged vc; vc.old_cnt = vtag->GetDataCount(); vc.new_cnt = count; if (!vtag->Message(MSG_POINTS_CHANGED, &vc;)) throw ErrorException(ERROR_GENERAL, "AnimLoader.CreateKeyFrame","PLA data creation failed"); if (count != vtag->GetDataCount()) throw ErrorException(ERROR_GENERAL, "AnimLoader.CreateKeyFrame","Mismatched Point Count"); CopyMem(sobj->GetPoint(), vtag->GetDataAddress(), count*sizeof(Vector)); vtag->Message(MSG_UPDATE); }
The source object "sobj" is used as the point source for the PLA VariableTag data. Destination BaseDocument "ddoc" contains the PointObject "dobj" that gets the track/sequence/key. Time is the frame at which to insert the key.
Robert
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 20/02/2007 at 08:11, xxxxxxxx wrote:
I there any way to create PLA like function above with C4D 10.0 SDK?
thanks,
Remo -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 20/02/2007 at 08:26, xxxxxxxx wrote:
It can be done, but there are currently limitations of how this can be done. For instance, the VariableTag is no longer available so one must use CTrack::FillKey() with the object containing the track having had its points 'changed' to get the PLA data stored.
This code is not identical to the previous code - in that it is used to convert an animated, rigged figure into an animated Polygon object using PLA. So you'll have to make the changes to reflect the inputs and results desired.
#ifdef C4D_R10 // Fix Animation onto Polygon object as PLA track //*---------------------------------------------------------------------------* Bool FixPolygonAnimation(BaseDocument* doc, PointObject* orig, PointObject* root, LONG fixAnimSample, Real fixAnimBias, BOOL fixAnimSmooth, LONG* partial, LONG elements) //*---------------------------------------------------------------------------* { // Get Destination point array Vector* dpoint = root->GetPointW(); if (!dpoint) return ErrorException::Throw(EE_DIALOG, GeLoadString(IPPERR_GENERAL_TEXT), "FixPolygonAnimation.root", "Has No Points"); // Check for Spla track, create if none DescID descID = DescLevel(ID_ANIM_PLA,ID_ANIM_PLA,0); CTrack* track = root->FindCTrack(descID); if (!track) { track = CTrack::Alloc(root, descID); if (!track) return ErrorException::Throw(EE_DIALOG, GeLoadString(IPPERR_MEMORY_TEXT), "FixPolygonAnimation.track"); root->InsertTrackSorted(track); doc->AddUndo(UNDO_NEW, track); } BaseTime stime = doc->GetMinTime(); BaseTime etime = doc->GetMaxTime(); CCurve* seq = track->GetCurve(); if (!seq) return ErrorException::Throw(EE_DIALOG, GeLoadString(IPPERR_MEMORY_TEXT), "FixPolygonAnimation.seq"); seq->FlushKeys(); // Sample Animation at fixAnimSample intervals ModelingCommandData mcd; mcd.doc = doc; mcd.op = orig; BaseContainer mbc; mbc.SetBool(MDATA_CURRENTSTATETOOBJECT_INHERITANCE, TRUE); mbc.SetBool(MDATA_CURRENTSTATETOOBJECT_KEEPANIMATION, FALSE); mcd.bc = &mbc; mcd.flags = 0; BaseObject* csto; PointObject* defd; CKey* key; const Vector* spoint; Vector* points; Vector* lpoints; DescID biasDID = DescLevel(CK_PLA_BIAS, DTYPE_REAL,0); DescID cubicDID = DescLevel(CK_PLA_CUBIC, DTYPE_BOOL,0); LONG pointCount = root->GetPointCount(); LONG pointSize = pointCount*sizeof(Vector); Real fps = doc->GetFps(); LONG startf = stime.GetFrame(fps); LONG endf = etime.GetFrame(fps); StatusSetText("Fixing Animation for "+orig->GetName()); for (; startf <= endf; startf += fixAnimSample) { stime = BaseTime::BaseTime(startf, fps); // - Animate Document to change the points of orig doc->SetTime(stime); doc->AnimateDocument(NULL, TRUE, TRUE); //doc->AnimateObject(orig, stime, 0L); EventAdd(); if (!SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT, mcd)) return ErrorException::Throw(EE_DIALOG, GeLoadString(IPPERR_MODELINGCOMMAND_TEXT), "FixPolygonAnimation"); csto = static_cast<BaseObject*>(mcd.result->GetIndex(0)); if (!csto) return ErrorException::Throw(EE_DIALOG, GeLoadString(IPPERR_MODELINGCOMMAND_TEXT), "FixPolygonAnimation.csto"); if (csto->IsInstanceOf(Onull)) { defd = ToPoint(csto->GetDown()); if (!defd) return ErrorException::Throw(EE_DIALOG, GeLoadString(IPPERR_MODELINGCOMMAND_TEXT), "FixPolygonAnimation.defd"); } else defd = ToPoint(csto); // - Add KeyFrame key = seq->AddKey(stime); if (!key) { BaseObject::Free(csto); return ErrorException::Throw(EE_DIALOG, GeLoadString(IPPERR_MEMORY_TEXT), "FixPolygonAnimation.key"); } doc->AddUndo(UNDO_NEW, key); // - Add PLA data // + R10 spoint = defd->GetPointR(); if (!spoint) { GePrint("Source Obj has no Points"); BaseObject::Free(csto); break; } // Apply parent animation to points points = defd->GetPointW(); lpoints = points+pointCount; for (; points != lpoints; ++points) (*points) *= orig->GetMg(); #ifdef WIN64 CopyMem(spoint, dpoint, static_cast<VLONG>(pointSize)); #else CopyMem(spoint, dpoint, pointSize); #endif // - R10 if (!track->FillKey(doc,root,key)) { BaseObject::Free(csto); return ErrorException::Throw(EE_DIALOG, "FixPolygonAnimation.FillKey failed"); } // Do these AFTER FillKey()! key->SetParameter(biasDID, GeData(fixAnimBias), 0L); key->SetParameter(cubicDID, GeData(fixAnimSmooth), 0L); BaseObject::Free(csto); // Update progress bar on each frame StatusSetBar(((*partial)*100L)/elements); (*partial)++; } // Clear global matrix Matrix unit; root->SetMg(unit); return TRUE; } #else // Pre-R10 PLA ...
Take care,
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 20/02/2007 at 08:33, xxxxxxxx wrote:
Big thanks Robert, will try it.
I just need to save PhyTools simulation data from array into PLA.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 20/02/2007 at 09:23, xxxxxxxx wrote:
Not sure but what are
ID_ANIM_PLA, CK_PLA_BIAS, CK_PLA_CUBIC ?
Can not find them in SDK. -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 20/02/2007 at 10:00, xxxxxxxx wrote:
OK sorry found them in "modules\newman\res" c4d_symbols.h and ckpla.h
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 20/02/2007 at 10:10, xxxxxxxx wrote:
Yes, in modules:newman:res.
Be careful with XCode - it cannot handle both your c4d_symbols.h and the one there (this is a known issue that will be fixed in the R10 update). I ended up doing something like this as a workaround until then:
#ifdef C4D_R10 // my preprocessor #ifdef XCODE // my preprocessor enum { ID_ANIM_PLA = 100004812 }; #include "ckpla.h" #else #include "newman\res\c4d_symbols.h" #include "newman\res\description\ckpla.h" #endif #endif
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 20/02/2007 at 10:13, xxxxxxxx wrote:
Yes I know this problem, I have just have create my own enum for this.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 21/02/2007 at 02:24, xxxxxxxx wrote:
just one note, accessing PLA info through the SDK is not yet finalized. there will be probably some changes in SDK at a later point, with direct access to the PLA data. can't say when these changes will be made though.
cheers,
Matthias