Set Keyframes

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

On 16/01/2007 at 12:14, xxxxxxxx wrote:

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

---------
Hi everybody,
it seems that keyframing I did in previous versions does not work with R10 anymore. Do you have any experience with it? I know, that the timeline/track/sequence things somehow changed.
But how can I set keyframes?
And: Where can I download SDK for R10. Isn't it ready.
Thanks for your help
Chris

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

On 16/01/2007 at 13:56, xxxxxxxx wrote:

Yes, track/sequence/keys are no longer represented by BaseTrack/BaseSequence/BaseKey - they are deprecated. You must now use CTrack/CCurve/CKey, CCurve being automatically added to the track.

The SDK itself is included with R10, but the SDK documentation still isn't ready it seems.

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

On 16/01/2007 at 23:49, xxxxxxxx wrote:

Thanks for the answer!
Has anybody a small samplecode for this?

Chris

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

On 17/01/2007 at 01:36, xxxxxxxx wrote:

Check out the Morphmixer example in the SDK, especially the static CreateKey function.

cheers,
Matthias

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

On 18/01/2007 at 01:02, xxxxxxxx wrote:

Hello Matthias,
have you already used the CreateKey function?
I transfered it to my plugin and I can complie, but
I don't know, what parameters I have to pass.
What is the Index? Is this ID_BASEOBJECT_POSITION for position?

What about the value. It is just a REAL. But a position is a vector.

Before, I used code I found here in the forum. I set it to the end.
Thanks
Chris
 if(mybo)
 {
  p = mybo->GetPos();
  val[0] = p.x;
  val[1] = p.y;
  val[2] = p.z;
 }
 else return FALSE;
 for (ii=0; ii<3; ii++)
 {
 // check if track exists
 descID = DescID(DescLevel(ID_BASEOBJECT_POSITION, 0, 0), DescLevel(VECTOR_X+ii, 0, 0));
 track = mybo->FindTrack(descID);
 if (!track)
 {
  track = AllocValueTrack(mybo,descID); if (!track) return FALSE;
  mybo->InsertTrackLast(track);
 }
 // check for sequence
 seq = NULL;
 for (seq = track->GetFirstSequence(); seq; seq=seq->GetNext())
 if (time>=seq->GetT1() && time<=seq->GetT2())
  break;
 if (!seq)
 {
  seq = track->AutoAddSequence(mydoc,time);
  if (!seq) return FALSE;
 }
 key = BaseKey::Alloc(seq->GetType()); if (!key) return FALSE;
 av = GetKeyValue(key); if (!av) return FALSE;
 av->value = val[ii];
 key->SetTime(time);
 seq->InsertKey(key);
 }

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

On 18/01/2007 at 04:18, xxxxxxxx wrote:

Yeah ID_BASEOBJECT_POSITION is the ID for the position. Here is some sample code, it is the modified Morphmixer that records a hidden vector parameter. Remember that there are no sequences anymore and everything is now working with DescIDs.

  
#include "c4d.h"  
#include "c4d_symbols.h"  
#include "omorphmixer.h"  
  
class MorphMixerObject : public ObjectData  
{  
     INSTANCEOF(MorphMixerObject,ObjectData)  
  
     public:  
          virtual Bool Init(GeListNode* node);  
          virtual Bool Message(GeListNode *node, LONG type, void *data);  
          virtual BaseObject* GetVirtualObjects(PluginObject *op, HierarchyHelp *hh);  
          virtual Bool GetDDescription(GeListNode *node, Description *description,LONG &flags;);  
  
          static NodeData *Alloc(void) { return gNew MorphMixerObject; }  
};  
  
static Bool CreateKey(BaseDocument *doc, BaseObject *op, const BaseTime &time;, LONG index, Vector value)  
{  
     // check if track exists  
     CTrack *trackx = op->FindCTrack(DescID(DescLevel(MORPHMIXER_POSEOFFSET,DTYPE_VECTOR,0),DescLevel(VECTOR_X,DTYPE_REAL,0)));  
     if (!trackx)  
     {  
          trackx = CTrack::Alloc(op,DescID(DescLevel(MORPHMIXER_POSEOFFSET,DTYPE_VECTOR,0),DescLevel(VECTOR_X,DTYPE_REAL,0))); if (!trackx) return FALSE;  
          op->InsertTrackSorted(trackx);  
     }  
     CKey *key = trackx->GetCurve()->AddKey(time); if (!key) return FALSE;  
     key->SetValue(trackx->GetCurve(),value.x);  
  
     CTrack *tracky = op->FindCTrack(DescID(DescLevel(MORPHMIXER_POSEOFFSET,DTYPE_VECTOR,0),DescLevel(VECTOR_Y,DTYPE_REAL,0)));  
     if (!tracky)  
     {  
          tracky = CTrack::Alloc(op,DescID(DescLevel(MORPHMIXER_POSEOFFSET,DTYPE_VECTOR,0),DescLevel(VECTOR_Y,DTYPE_REAL,0))); if (!tracky) return FALSE;  
          op->InsertTrackSorted(tracky);  
     }  
     key = tracky->GetCurve()->AddKey(time); if (!key) return FALSE;  
     key->SetValue(tracky->GetCurve(),value.y);  
  
     CTrack *trackz = op->FindCTrack(DescID(DescLevel(MORPHMIXER_POSEOFFSET,DTYPE_VECTOR,0),DescLevel(VECTOR_Z,DTYPE_REAL,0)));  
     if (!trackz)  
     {  
          trackz = CTrack::Alloc(op,DescID(DescLevel(MORPHMIXER_POSEOFFSET,DTYPE_VECTOR,0),DescLevel(VECTOR_Z,DTYPE_REAL,0))); if (!trackz) return FALSE;  
          op->InsertTrackSorted(trackz);  
     }  
     key = trackz->GetCurve()->AddKey(time); if (!key) return FALSE;  
     key->SetValue(trackz->GetCurve(),value.z);  
  
     return TRUE;  
}  
  
Bool MorphMixerObject::Init(GeListNode *node)  
{  
     return TRUE;  
}  
Bool MorphMixerObject::GetDDescription(GeListNode *node, Description *description,LONG &flags;)  
{  
     if (!description->LoadDescription(node->GetType())) return FALSE;  
  
     BaseContainer bc2 = GetCustomDataTypeDefault(DTYPE_VECTOR);  
     bc2.SetBool(DESC_HIDE,TRUE);  
     bc2.SetString(DESC_NAME,"Test");  
     bc2.SetString(DESC_SHORT_NAME,"Test");  
     if (!description->SetParameter(DescLevel(MORPHMIXER_POSEOFFSET,DTYPE_VECTOR,0),bc2,DescLevel(ID_OBJECTPROPERTIES))) return FALSE;  
  
     flags |= DESCFLAGS_DESC_LOADED;  
  
     return SUPER::GetDDescription(node,description,flags);  
}  
  
Bool MorphMixerObject::Message(GeListNode *node, LONG type, void *data)  
{  
     switch (type)  
     {  
          case MSG_DESCRIPTION_COMMAND:  
          {  
               DescriptionCommand *dc = (DescriptionCommand* ) data;  
               if (dc->id[0].id==MORPHMIXER_RECORD)  
               {  
                    BaseObject          *op = (BaseObject* )node;  
                    BaseDocument     *doc = node->GetDocument(); if (!doc) break;  
  
                    CreateKey(doc,op,doc->GetTime(),MORPHMIXER_POSEOFFSET,Vector(1,2,3));  
                    EventAdd();  
               }  
          }  
     }  
  
     return TRUE;  
}  
  
// create morphed object  
BaseObject *MorphMixerObject::GetVirtualObjects(PluginObject *op, HierarchyHelp *hh)  
{  
     return NULL;  
}  
  
// be sure to use unique IDs obtained from www.plugincafe.com  
#define ID_MORPHMIXER_OBJECT     1001156  
  
Bool RegisterMorphMixer(void)  
{  
     // decide by name if the plugin shall be registered - just for user convenience  
     String name=GeLoadString(IDS_MORPHMIXER); if (!name.Content()) return TRUE;  
     return RegisterObjectPlugin(ID_MORPHMIXER_OBJECT,name,OBJECT_GENERATOR|OBJECT_INPUT,MorphMixerObject::Alloc,"Omorphmixer","morphmixer.tif",0);  
}  

hope that helps

cheers,
Matthias

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

On 18/01/2007 at 05:45, xxxxxxxx wrote:

Yes! Thank you very much!