Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Import animation data using Melange lib

    SDK Help
    0
    3
    210
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      On 15/07/2014 at 11:33, xxxxxxxx wrote:

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

      ---------
      Hello all,

      I'm trying to read the animation data from a C4D file using the melange lib, but I'm having all sorts of problems.
      My first problem is related to the rotation axis. I have 2 different files, in both files I have a rotation around the Z axis. The problem starts when I create a keyframe. In one of the files, this rotation is applied as a "Rotation.B" whereas in the other file, I get "Rotation.P". Note that in both cases I rotated the model around the Z axis!

      Then when I'm importing each of these files into my program, the conversion from HPB into XYZ results in different rotations, however, The Rotation.B is converted into a rotation around Z and  the Rotation.P is converted into a rotation around Y for the other, which seems that HPB is directly converted into XYZ.

      Another problem I'm having is related to the point of rotation/scale. I'm getting 3 vectors from each keyframe (move, rotate, scale). I then create a transformation matrix with them, but applying this matrix directly will transform my model from within its center, independently of the point of rotation I used in Cinema4D. I'm almost definitely missing something here.

      Here is a draft of my current code:

      CTrack *track = op->GetFirstCTrack();
      while (track)
      {
              DescID testID = track->GetDescriptionID();
              DescLevel lv1 = testID[0];
              DescLevel lv2 = testID[1];
        
              CCurve *curve = track->GetCurve();
              if (curve)
              {
                      LONG keyCount = curve->GetKeyCount();
        
                      CKey *key = NULL;
                      BaseTime time;
                      for (LONG i=0; i<keyCount; ++i)
                      {
                              key = curve->GetKey(i);
                              time = key->GetTime();
        
                              if (track->GetTrackCategory() == PSEUDO_VALUE)
                              {
                                      const LONG keyId = time.GetFrame(animProps.fps);
        
                                      if (animData.keyframes.find(keyId) == animData.keyframes.end())
                                              animData.keyframes[keyId] = MelangeStoreKeyframe(keyId);
        
                                      MelangeStoreKeyframe &keyframe = animData.keyframes[keyId];
        
                                      switch (lv1.id)
                                      {
                                              case ID_BASEOBJECT_REL_POSITION:
                                                      switch (lv2.id)
                                                      {
                                                              case VECTOR_X: keyframe.position[0] = key->GetValue(); break;
                                                              case VECTOR_Y: keyframe.position[1] = key->GetValue(); break;
                                                              case VECTOR_Z: keyframe.position[2] = key->GetValue(); break;
                                                      }
                                                      break;
        
                                              case ID_BASEOBJECT_REL_ROTATION:
                                                      switch (lv2.id)
                                                      {
                                                              case VECTOR_X: keyframe.rotation[0] = key->GetValue(); break;
                                                              case VECTOR_Y: keyframe.rotation[1] = key->GetValue(); break;
                                                              case VECTOR_Z: keyframe.rotation[2] = key->GetValue(); break;
                                                      }
                                                      break;
        
                                              case ID_BASEOBJECT_REL_SCALE:
                                                      switch (lv2.id)
                                                      {
                                                              case VECTOR_X: keyframe.scale[0] = key->GetValue(); break;
                                                              case VECTOR_Y: keyframe.scale[1] = key->GetValue(); break;
                                                              case VECTOR_Z: keyframe.scale[2] = key->GetValue(); break;
                                                      }
                                                      break;
                                      }
                              }
                      }
              }
              track = track->GetNext();
      }
      

      On a final note, I'm not considering the global matrix of the model, which for my understanding, represents the model matrix at the current frame when exported.

              PolygonObject *op = (PolygonObject* )GetNode();
              Matrix mg	= op->GetMg();
      

      I'm not applying this matrix (mg) to the model's vertexes nor the animation transforms (position, scale, rotation).

      Also, it would be great is someone pointed me out some examples about this matter, I'm a little bit lost here.

      Thanks in advance!

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 17/07/2014 at 07:05, xxxxxxxx wrote:

        Well... I think I'm getting somewhere.

        I cannot discard the model global matrix, but I don't know exactly what to do with it. Also, I don't understand the relation of this matrix with the values read from each keyframe.

        Currently, if my model has no animation data, I simply multiply the global matrix by each vertex, and get exactly the same thing as in Cinema4D. However if my model do has animation data, I can't seem to get the same result.

        Should I multiply each keyframe position, scale and rotation values (read as the previous post) by the global matrix, and also multiply each vertex by the same matrix?

        I tried this, no luck yet!

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 27/01/2015 at 19:05, xxxxxxxx wrote:

          Once again, I'll answer my own question, so others with the same problem could understand what's going on with C4D animations in melange.

          So this is how it works:
          the Matrix Global op->GetMg(), is nothing more than the matrix containing the transformation for a specific object when the C4D file was saved. This means that if we have an animation with 2 keyframes 0 to 10, and we save the file with the cursor in frame 10, we get the transformation the object has  in the keyframe 10.

          Now, the data read from each keyframe: What we have to do here, is collect all the data we can for each keyframe, like my initial code does. But, because most of the time, a keyframe only has 1 or 2 transforms, like position_x and rotation_h or scale_z, we need to figure out all the missing data, and for that, we should use op->GetRelPos(), op->GetRelScale() and op->GetRelRot(), then simply set all the missing data with the values read from these calls. Example:

          keyframe 0:
          we got from the my code above:
          position_x, position_y, scale_x, rotation_h, rotation_b for example

          so we still need:
          position_z, scale_y, scale_z and rotation_p

          we get these like so:
          position_z = op->GetRelPos().z
          scale_y = op->GetRelScale().y
          ... and so on...

          NOTE: you can do this the other way around, set all transforms to their "base" values using those functions, and then read the animation data, and replace the corresponding values.

          Just do this for all the keyframes and we're done. (I mean... we still need to deal with interpolation, but that's another story)

          1 Reply Last reply Reply Quote 0
          • First post
            Last post