Delta Time Evaluation



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

    On 23/11/2005 at 07:59, xxxxxxxx wrote:

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

    ---------
    How do I safely measure the time between the last evaluated frame and the current frame. Storing this information in my object only works if I do not use Scene Motion Blur. With SMB the major frame is copied to each minor subframe making delta time evaluation problematic.

    Any thoughts?

    -Chris



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

    On 28/11/2005 at 11:58, xxxxxxxx wrote:

    Hm, interesting problem. I guess if you don't do anything about it then it would work but the effect would be linearised in the sub frames. (As long as it really uses the delta time. I guess step based plugins would be even worse off.)
    Perhaps the thought behind this scheme is that SMB shouldn't change the overall motion of the objects in the scene. Otherwise it would be a pita to test render scenes before the final render if highly non-linear effects are used. I've sent a question to developers to ask if they have any insight on this.



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

    On 04/12/2005 at 08:25, xxxxxxxx wrote:

    Thanks for the info Mikael,

    Did you hear back from from anyone yet? This is a serious issue and we need to find a solution for that.

    Thomas
    3D ATTACK



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

    On 10/12/2005 at 04:48, xxxxxxxx wrote:

    Ok, I now know how it works. That the main frames are cloned for each SMB sub-frame is by design and is not possible to work around for plugins. This means that for 30 FPS x5 SMB the first sub-frame will have a delta-time of 0, the second 1/150, the third 2/150, the fourth 3/150 and the fifth 4/150. Then the next main-frame will have 5/150, with its sub-frames having the same delta-times as before.
    So as long as your plugin simply trusts the delta-times given to it by C4D it should all work out fine and the rendered motion will be continuous, since the delta-times of the sub-frames are a linear build-up to the delta-time of the next main-frame.
    Perhaps there's some part of your problem that I don't understand? Could you clarify why the SMB delta-times cause problems for your plugin?



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

    On 10/12/2005 at 08:51, xxxxxxxx wrote:

    Where do we retrieve the delta-times from C4D?

    Thomas



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

    On 10/12/2005 at 09:03, xxxxxxxx wrote:

    Oh, sorry. I thought you had that part working already. Here's some code I used to test the behaviour of SMB:

        
        
        LONG LookAtCamera::Execute(PluginTag *tag, BaseDocument *doc, BaseObject *op, BaseThread *bt, LONG priority, LONG flags)  
        {  
          BaseTime ct = doc->GetTime();  
          GePrint("Document: " + LongToString((LONG)doc));  
          GePrint("  Tag: " + LongToString((LONG)tag));  
          GePrint("  Current time: " + RealToString(ct.Get()));  
            
          GeData last_time;  
          if (tag->GetParameter(DescLevel(1000001), last_time, 0))  
          {  
            BaseTime lt = last_time.GetTime();  
            GePrint("  Last time: " + RealToString(lt.Get()));  
            GePrint("  Delta time: " + RealToString(ct.Get() - lt.Get()));  
          }  
          tag->SetParameter(DescLevel(1000001), GeData(ct), 0);  
          
          ...  
        }
    

    You should replace 1000001 with a real unique ID from PluginCafe!



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

    On 10/12/2005 at 09:41, xxxxxxxx wrote:

    This code supplies the exact same problem. If you use SMB the delta results ( time between frames ) is not the same every frame. It increases in value. Same problem. We need a way to get the absolute time difference between frames.

    Delta = Current_Time – Previous_Time.

    Current_Time    == Time of current evaluated frame
    Previous_Time   == Time of last evaluated frame ( absolute last frame, the subframe, not the document frame )

    How does one use this to make a simple value evaluate correctly?



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

    On 10/12/2005 at 09:51, xxxxxxxx wrote:

    It won't always give the same delta time between frames, simply because the delta times aren't uniform when using SMB. And SMB isn't the only reason for nonuniform delta times, for example if the user is scrolling the timeline backwards the times will be negative!
    So the easiest strategy is to design plugins without any assumptions about the delta times, just reading the time since the last frame like in the code above.
    To further clarify why the delta times aren't uniform: the code calculates the delta time since the last evaluation in that document. The other subframes happen in another (cloned) document and aren't taken into account. This makes sense, at least for most plugins, since it's the state stored in the document that you will use for the next evaluation.
    If C4D would, in the future or perhaps by some plugin renderer, offer alternative SMB strategies, then the delta times might be different. That's another reason why it's important not to make assumptions about them.
    I hope this information helps! Since it's impossible to get what you want exactly, in order to help you to work around the problem I will need to know more about why the current evaluation strategy doesn't suit your plugin.



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

    On 10/12/2005 at 10:35, xxxxxxxx wrote:

    Pseudo Code:

    Init:
    Index = 0.0;
    Last_Time = 0.0;

    Evaluate:
    if ( current_time == min_time )
    {
        Index = 0.0;
        Last_Time = min_time;
    }
    Delta = current_time – Last_Time;
    Index += StepPerSecond * Delta;

    This works fine until delta becomes unstable in subframes. This means that the increment is no longer uniform. Since the CopyTo function is not called in the cloned document from the previous frame the delta is always the difference between the current subframe and the original document frame.

    So it goes something like this:

    No SMB - 30fps

    Index += 0.033
    Index += 0.033
    Index += 0.033

    SMB – 30fps – 10 subframes

    1. Index += 0.033
    s1. Index += 0.0033
    s2. Index += 0.0066
    s3. Index += 0.0099

    What we are looking for:

    1. Index += 0.0033
    s1. Index += 0.0033
    s2. Index += 0.0033
    s3. Index += 0.0033
    Etc...

    It seems you are saying this is an incorrect approach. How would we go about maintaining a uniform increment? Possibly pre-evaluating an increment? Is a subframe increment ever stored by C4D? How would you write a basic position dampening algorithm? We are obviously missing something very basic.

    Appreciate your help!



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

    On 10/12/2005 at 10:51, xxxxxxxx wrote:

    Basically what I'm saying is that C4D is correct in saying that the delta time is 0.0099 for the third subframe. It is, because that's the time since the last mainframe. And the last mainframe is what was used to create the clone for the third subframe.
    The reason that no CopyTo() occurs between subframe 2 and subframe 3 directly is simply that the subframes aren't cloned that way. Each one is cloned from the mainframe!
    To be even more clear, this is what happens when rendering using SMB in your case:

    • Main document evaluated at 0.0. (Delta time calculation intialized)
    • Main document cloned.
    • Cloned document evaluated at 0.0 for frame 0:0. (Delta time 0.0)
    • Cloned document destroyed.
    • Main document cloned again.
    • Cloned document evaluated at 0.0033 for frame 0:1. (Delta time 0.0033.)
    • Cloned document destroyed.
    • Main document cloned once more, still from the old state at 0.0 since the state at 0.0033 has been destroyed.
    • Cloned document evaluated at 0.0066 for frame 0:1. (Delta time 0.0066.)
    • Cloned document destroyed.
    • ...
    • Main document cloned the last time for this mainframe.
    • Cloned document evaluated at 0.0297 for frame 0:9. (Delta time 0.0297.)
    • Cloned document destroyed.
    • Main document evaluated at 0.033. (Delta time 0.033!)
    • Main document cloned, now from the state at 0.033.
    • Cloned document evaluated at 0.033. (Delta time 0.0!)
    • Cloned document destroyed.
    • Main document cloned, still from the state at 0.033.
    • Cloned document evaluated at 0.0363. (Delta time 0.0033!)
    • Cloned document destroyed.
    • ...

    I hope that has made it's clear exactly how C4D evaluates and clones subframes when SMB is enabled. Now on to the pseudo code you posted and why it doesn't work. I'll post this first part while I'm thinking about that.



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

    On 10/12/2005 at 10:57, xxxxxxxx wrote:

    Would Index be a global variable of any kind? In that case it won't work, since the cloning strategy listed in my post above requires that the subframe evaluations are thrown away.
    As long as index is a variable that's stored (and destroyed) along with the document, then your code looks fine. (Except for the missing 0.0 delta time increments. I'm pretty sure I saw those in my test code, though I can't be bothered to check now.)
    Of course, the only changes to Index that will carry through to the end of the animation are those made for mainframes, += 0.033, since the others will be incrementing an Index variable that's soon to be destroyed.
    And no, delta times are never stored by C4D. You always have to store the time used to calculate the current state of your plugin, so that you can get a correct delta time reading for the next calculation.
    Now, did any of this help? I hope I have explained the cloning part well enough, but please ask if you have further questions on that. Most of it you can see for yourself, when it comes to what really happens, simply by placing GePrint() lines or breakpoints in CopyTo(), Init() and Free().



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

    On 10/12/2005 at 11:01, xxxxxxxx wrote:

    And yes, if uniform delta times are that important to the stability of your numerical algorithm, then you need to do further time subdivisions yourself. I.e. for subframe 3 there would be three steps taken, for subframe 4 there would be four steps.
    I think if possible a dynamic time sub-sampling strategy internal to your plugin might work better, i.e. only do a finer time subdivision if there's lots of stuff going on in the simulation. As long as you eventually end up at the delta times given by C4D it should be fine to do that.


Log in to reply