Melange - Animate document



  • On 15/12/2017 at 10:15, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   19 
    Platform:      Mac OSX  ; 
    Language(s) :     C++  ;

    ---------
    Hello there,

    I'm building some prototypes with Melange at the moment and I'm trying to work out if it's possible to animate a C4D document from within Melange. The aim is to get position data from various BaseObjects at different frames in the timeline. Some of the useful stuff for this like GetMaxTime() etc are in a private DocumentPref class. Also I can't find anything like ExecutePasses(). SetTime() is available but the object values don't update without functions for updating.

    So, is it possible to animate as if using the normal C++ / Python SDK or am I trying to do something that just isn't supposed to be done :)

      
        BaseObject* ActiveCam = C4Ddoc->GetSceneCamera();
      
        Int32     fps       = C4Ddoc->GetFps();
        BaseTime time       = C4Ddoc->GetTime();
        Int32   frame       = time.GetFrame(fps);
            
        printf("Frame ||  %d  \n", frame);
      
        for (int i=0; i<25; i++) {
            
            C4Ddoc->SetTime(BaseTime(i, fps));
            
            Matrix cam_mat = ActiveCam->GetMg();
            Vector p       = cam_mat.off;
            printf("Camera position || x :  %f , y :  %f , z : %f \n ", p.x,p.y,p.z);  
      
        }
        
      
    
    

    Thanks,

    Adam



  • On 18/12/2017 at 02:37, xxxxxxxx wrote:

    Hi Adam, thanks for writing us.

    Melange provides, to some extents, the means to extract animation data from a native Cinema 4D file by accessing the keyframe values of a proper animation curves. In order to let Melange deliver this functionality the file should come with the animation cached into the file otherwise no data will be found and being ExecutePasses() not available there won't be any chance to update the object state at a specific time.

    It's then relevant to use  "Save Project for Melange..." from the "File" menu or to enable "Save Polygons for Melange" and/or "Save Animation for Melange" in the "File" setting under "Preferences". By using the first option (saving the project) the file generated will provide automatically both geometry and animation information ready to be used by Melange. By using the second  option (setting the options) will make any further file normally saved by Cinema to carry out the data for Melange.
    It's on a case by case basis to use the former or the latter approach, because the second, once set, will always deliver additional data in the file causing it to be bigger and making saving actions to take longer.

    Once the animation data is in the file, then using the BaseDocument::SetTime(), will cause any query to the curves current value to be referred to the proper time and since the values are available for all the frame of the active sequence, you'll be returned with the proper "animated" data.

    This approach works best with key-frame based animation whilst with more advanced animation approached could become more difficult to extract data from.

    Best, Riccardo



  • On 18/12/2017 at 04:41, xxxxxxxx wrote:

    Hi Riccardo, thanks for the response. This makes things much more clear.

    I can access the values I need now by using FindCTrack() & GetValue() etc to get the various values along the timeline.

    Based on this then. I won't be able to use functions like op.GetMg() to get any updated data. If I did want to get an updated matrix for a camera object on each frame (or another BaseObject), I'd have to keyframe all PSR, save the project for melange (in either one of the ways you described) then rebuild it from the Float components of the values from each curve i.e px,py,px,h,b,p,sx,sy,sz? - Just want to confirm that before I start building that in. :)

    Thanks,

    Adam



  • On 19/12/2017 at 03:21, xxxxxxxx wrote:

    Hi Adam,

    the process of caching the animation data is delivered by "Saving project with Melange" (or by enabling the Save Animation option) without having you to set PSR data for each keyframe. To be clear let say you have an object moving from 0,0,0(frame 0) to 0,10,0 (frame 10) then after setting the two keyframes in your timeline, simply save the project for Melange and in your Melange-based code start querying for the object position at the different frame (actually from 0 to 10).

    Best, Riccardo



  • On 19/12/2017 at 04:09, xxxxxxxx wrote:

    OK, I've set a scene up exactly like that. I've set two keys for px,py,pz each. One at the beginning and one at the end of the document (0-10 frames). The project is saved using the save for Melange command. I've used this code to get the position in two ways. Firstly by getting the tracks responsible for the position and second by getting the .off vector of the object matrix and here are the results:

    The code:

        BaseObject* cube = C4Ddoc->GetFirstObject();
      
        Int32     fps       = C4Ddoc->GetFps();
        BaseTime time       = C4Ddoc->GetTime();
        Int32   frame       = time.GetFrame(fps);
        
        
        // For getting the float components of the tracks
        CTrack* track_x  = cube->FindCTrack(DescID(DescLevel(ID_BASEOBJECT_REL_POSITION), DescLevel(VECTOR_X)));
        CTrack* track_y  = cube->FindCTrack(DescID(DescLevel(ID_BASEOBJECT_REL_POSITION), DescLevel(VECTOR_Y)));
        CTrack* track_z  = cube->FindCTrack(DescID(DescLevel(ID_BASEOBJECT_REL_POSITION), DescLevel(VECTOR_Z)));
        
        
        for (int i=0; i<=10; i++) {
            
            C4Ddoc->SetTime(BaseTime(i, fps));
            time       = C4Ddoc->GetTime();
            printf("Frame : || %d \n", C4Ddoc->GetTime().GetFrame(fps));
            
            
            Float32 px = track_x->GetValue(C4Ddoc,time);
            Float32 py = track_y->GetValue(C4Ddoc,time);
            Float32 pz = track_z->GetValue(C4Ddoc,time);
            
            Vector p = Vector(px,py,pz);
            
            printf("Position from track || x :  %f , y :  %f , z : %f \n", p.x,p.y,p.z);
            
            Matrix cube_mat = cube->GetMg();
            Vector mp = cube_mat.off;
        
            printf("Position from matrix || x :  %f , y :  %f , z : %f \n", mp.x,mp.y,mp.z);
            
            printf("=====================================================\n");
    

    And this is what comes out in the console:

    Frame : || 0 
    Position from track || x :  0.000000 , y :  0.000000 , z : 0.000000 
    Position from matrix || x :  0.000000 , y :  0.000000 , z : 0.000000 
    =====================================================
    Frame : || 1 
    Position from track || x :  0.000000 , y :  0.279997 , z : 0.000000 
    Position from matrix || x :  0.000000 , y :  0.000000 , z : 0.000000 
    =====================================================
    Frame : || 2 
    Position from track || x :  0.000000 , y :  1.039998 , z : 0.000000 
    Position from matrix || x :  0.000000 , y :  0.000000 , z : 0.000000 
    =====================================================
    Frame : || 3 
    Position from track || x :  0.000000 , y :  2.160002 , z : 0.000000 
    Position from matrix || x :  0.000000 , y :  0.000000 , z : 0.000000 
    =====================================================
    Frame : || 4 
    Position from track || x :  0.000000 , y :  3.520008 , z : 0.000000 
    Position from matrix || x :  0.000000 , y :  0.000000 , z : 0.000000 
    =====================================================
    Frame : || 5 
    Position from track || x :  0.000000 , y :  4.999986 , z : 0.000000 
    Position from matrix || x :  0.000000 , y :  0.000000 , z : 0.000000 
    =====================================================
    Frame : || 6 
    Position from track || x :  0.000000 , y :  6.479992 , z : 0.000000 
    Position from matrix || x :  0.000000 , y :  0.000000 , z : 0.000000 
    =====================================================
    Frame : || 7 
    Position from track || x :  0.000000 , y :  7.839998 , z : 0.000000 
    Position from matrix || x :  0.000000 , y :  0.000000 , z : 0.000000 
    =====================================================
    Frame : || 8 
    Position from track || x :  0.000000 , y :  8.960002 , z : 0.000000 
    Position from matrix || x :  0.000000 , y :  0.000000 , z : 0.000000 
    =====================================================
    Frame : || 9 
    Position from track || x :  0.000000 , y :  9.720003 , z : 0.000000 
    Position from matrix || x :  0.000000 , y :  0.000000 , z : 0.000000 
    =====================================================
    Frame : || 10 
    Position from track || x :  0.000000 , y :  10.000000 , z : 0.000000 
    Position from matrix || x :  0.000000 , y :  0.000000 , z : 0.000000 
    =====================================================
    

    When you say 'querying for the object position' in your previous post, did you mean one of these methods or something different? - What might I be doing wrong to not see the position values from the matrix?

    Thanks for bearing with me on this :)

    Adam


Log in to reply