When to create keyframes?



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 18/12/2008 at 01:17, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   10 & 11 
    Platform:   Windows  ; Mac  ;  
    Language(s) :     C++  ;

    ---------
    Hi,

    I need to create keyframes from within the GetVirtualObjects() function of my ObjectData plugin. As I have learned from experience and from the SDK, this is a bad thing, because in R10 is may crash and in R11 it will crash.

    What I want to do is a key frame baking function for my plugin. The user clicks a button in the plugin, I catch the click in the plugin's Message() function. I set a Bool variable "RecordMode" to TRUE. Then a loop from the first to the last frame of the scene will run, animating the document to each frame of the scene; each time triggering the GetVirtualObjects(). In the GetVirtualObjects(), I check if "RecordMode" is TRUE. If so, I want to create keyframes for several objects in the scene.

    As I said, creating the keyframes directly in the GetVirtualObjects() will crash R11, because it's not thread safe. I have now two possibilities:

    1. Create the keyframes in the plugin's Message() function.
    This would mean to run the above mentioned loop, trigger GetVirtualObjects() and then create the keyframes. Sounds good, but unfortunately, GetVirtualObjects() always seems to be called last. Whatever keyframes I create, they're created before GetVirtualObjects() did its work.
    Question: Is there a way to manually FORCE GetVirtualObjects() to be called?

    2. Call a MessageData plugin to create the keyframes
    Very little is known about the MessageData. As I understood it, I could call a MessageData plugin from the end of my GetVirtualObjects(). It would create the keyframes and not get me into trouble with thread stuff. I see there's also a (very) little example in the SDK.
    Question: Will a MessageData plugin help me, and if so: how would I pass the required data (e.g. a Pointer to an object in the scene) to it?

    Long text, sorry. I really hope somebody can help. Thanks in advance!

    Greetings,
    Jack



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 18/12/2008 at 05:32, xxxxxxxx wrote:

    Is threading the problem, anyway?

    In R11 I get crashes *everytime* I use the following function *anywhere* in an ObjectData plugin:

    > Bool CreateVectorKey(BaseDocument \*doc, BaseObject \*op, const BaseTime &time;, LONG index, Vector value) \> { \>      // check if tracks exist \>      CTrack \*trackX = op->FindCTrack(DescID(DescLevel(index,DTYPE_VECTOR,0),DescLevel(VECTOR_X,DTYPE_REAL,0))); \>      CTrack \*trackY = op->FindCTrack(DescID(DescLevel(index,DTYPE_VECTOR,0),DescLevel(VECTOR_Y,DTYPE_REAL,0))); \>      CTrack \*trackZ = op->FindCTrack(DescID(DescLevel(index,DTYPE_VECTOR,0),DescLevel(VECTOR_Z,DTYPE_REAL,0))); \> \>      StopAllThreads(); \>      if (!trackX) \>      { \>           trackX = CTrack::Alloc(op,DescID(DescLevel(index,DTYPE_VECTOR,0),DescLevel(VECTOR_X,DTYPE_REAL,0))); \>           op->InsertTrackSorted(trackX); \>      } \>      if (!trackY) \>      { \>           trackY = CTrack::Alloc(op,DescID(DescLevel(index,DTYPE_VECTOR,0),DescLevel(VECTOR_Y,DTYPE_REAL,0))); \>           op->InsertTrackSorted(trackY); \>      } \>      if (!trackZ) \>      { \>           trackZ = CTrack::Alloc(op,DescID(DescLevel(index,DTYPE_VECTOR,0),DescLevel(VECTOR_Z,DTYPE_REAL,0))); \>           op->InsertTrackSorted(trackZ); \>      } \> \>      CKey \*keyX = trackX->GetCurve()->AddKey(time); if (!keyX) return FALSE; \>      CKey \*keyY = trackY->GetCurve()->AddKey(time); if (!keyY) return FALSE; \>      CKey \*keyZ = trackZ->GetCurve()->AddKey(time); if (!keyZ) return FALSE; \> \>      keyX->SetValue(trackX->GetCurve(),value.x); \>      keyY->SetValue(trackY->GetCurve(),value.y); \>      keyZ->SetValue(trackZ->GetCurve(),value.z); \> \>      return TRUE; \> }

    The very same code works absolutely fine in another plugin of mine, which is a TagData plugin.

    It is sure that the problem is caused by the above shown code. If I don't call it, no crash happens. Unfortunately, the crash doesn't happen immediately when calling the code but some time later, outside my code. So I just see the disassembler when it happens.

    This is annoying. Does really nobody have an idea how to set keyframes from the Message() function of an ObjectData plugin, in a way that it works in R10 and R11?

    Thanks in advance.

    Greetings,
    Jack



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 28/12/2008 at 12:10, xxxxxxxx wrote:

    it's quit similar to my code, except that I included more checks against failure. I use it in object plugins as well as in tag plugins. No problems by now.

    My object is a generator object without using GetVirtualObject(). Maybe try to insert a further execution call, that you use for your recording stuff.

    > \> Bool XY::AddToExecution(PluginObject\* op, PriorityList\* list) \> { \>      list->Add(op, EXECUTION_EXPRESSION, 0); \>      return TRUE; \> } \>

    This is my key writer:

    > \>      CTrack               \*track; \>      CCurve               \*seq; \>      CKey               \*key; \> \>      val[0] = value.x; \>      val[1] = value.y; \>      val[2] = value.z; \> \>      for (i=0; i<3; i++) \>      { \>           // check if track exists \>                descID = DescID(DescLevel(index, DTYPE_VECTOR, 0), DescLevel(VECTOR_X+i, DTYPE_REAL, 0)); \>                track = op->FindCTrack(descID); \>                if (!track) \>                { \>                     track = CTrack::Alloc(op,descID); \>                     if (!track) \>                          return FALSE; \>                     op->InsertTrackSorted(track); \>                } \>                seq = track->GetCurve(); \>                if (!seq) \>                     return FALSE; \>                key = seq->AddKey(time); \>                if (!key) \>                     return FALSE; \>                key->SetValue(seq, val[i]); \>            \>      } \>



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 30/12/2008 at 07:59, xxxxxxxx wrote:

    Howdy,

    I'm not that familiar with GetVirtualObjects() but after looking at the Atom.cpp SDK example, I notice that when it generates the objects, the generated objects are not inserted into the document.

    So, my question would be, are you trying to set keys for a virtual (generated) object that is not inserted into the document, and is it even possible to set keys for virtual objects?

    Adios,
    Cactus Dan



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 31/12/2008 at 07:23, xxxxxxxx wrote:

    Hi,

    first of all, thank you Robert. But I think the method of keyframe creation is not the problem. I use the exact same function in another plugin of mine, in the Execute() function of an expression tag. It works fine there, in all releases. I bet it's a threading problem.

    Dan: The virtual hierachy is returned as the result of GetVirtualObjects(). You are right, setting keyframes for the virtual objects would not make much sense.
    In my plugin, I implemented a function for converting the virtual objects to real objects. If the user activates that function, the virtual hierarchy is inserted into the document. Then I just work on the real objects instead of the virtual objects, and return NULL from GetVirtualObjects(). I only try to create keyframes for the real objects.

    Maybe I'll make a recorder tag that will create the keyframes, I'll think about it next year ;-)

    Happy New Year to all of you!

    Cheers,
    Jack



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 31/12/2008 at 08:42, xxxxxxxx wrote:

    Howdy,

    Ah, OK. Yes that makes much more sense. :o)

    Well, can you store the PSR values in the plugin's container or an array when GetVirtualObjects() is called and set the keys afterwards?

    Using the Atom.cpp as an example and a MessageData plugin, I noticed that the core messages EVMSG_CHANGE is sent before GetVirtualObjects() and EVMSG_DOCUMENTRECALCULATED is sent after GetVirtualObjects(), if that helps. ;o)

    Adios,
    Cactus Dan



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 06/01/2009 at 02:33, xxxxxxxx wrote:

    I am not sure what you want to achieve, as far as I understand it you want to cache the translations of your virtual objects?

    cheers,
    Matthias



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 06/01/2009 at 05:19, xxxxxxxx wrote:

    I want to cache the translations (and rotations, scale etc) of child objects of my Generator Object, since the Bake function in the timeline doesn't seem to notice they are being moved.

    Anyway, it's not that important, but I'd still be interested in a solution.

    Greetings,
    Jack


Log in to reply