Delay in dynamics object POS retrieval [SOLVED]



  • On 06/06/2016 at 14:02, xxxxxxxx wrote:

    Hi,

    In attempting to store the frame-by-frame position of an object being driven by a rigid body simulation/dynamics tag, it seems like there is a delay in the object coordinates retrieved by python, and the actual position.

    For example, creating a simple dynamics scene with a cube (rigid body tag) and a floor (collider body tag), I put a python tag on the cube with the following code:

    import c4d
      
    def main() :
        cTime = doc.GetTime().GetFrame(doc.GetFps())
        cPos  = op.GetObject().GetMg().off
        print cTime, cPos
      
    
    

    If I step through the project frame by frame, the console prints out the correct position values.  But if I play the animation, and then hit pause , it seems to perform one last iteration to update to the correct position--but it registers on the same frame.

    This is causing issues in a different application where I am trying to approximate velocity/accel based on previous, current, and next frame positions.

    Can anyone help me understand why that delay is happening, or what I might be able to do to prevent/work around it?

    Thanks,
    --Marcus



  • On 13/06/2016 at 02:40, xxxxxxxx wrote:

    Hello,

    by default the Python tag is not only executed when the current frame is changed. It is executed every time the scene is executed (something in the scene changed etc.).

    But you could enable the "Frame Dependent" option on the Python tag. Then the tag will only be executed when the frame changed.

    Best wishes,
    Sebastian



  • On 13/06/2016 at 07:41, xxxxxxxx wrote:

    Thanks, Sebastian -- that solved the odd delay issue I thought I was seeing, so it all works as I expected now!  But using that method means that my user data button no longer works, I'm assuming since the script isn't being continually evaluated to catch the message update.

    From what I've read before, am I correct in understanding the user data button has been updated in R17?  Would that be the appropriate way to work with the button, or should I just look for a different method?

    Basically I'd like to give the user the ability to flush out the data that has been stored in a Base-Container within the script.

    Thanks again,
    --Marcus



  • On 13/06/2016 at 09:04, xxxxxxxx wrote:

    Hello,

    can you describe some more what you are actually doing? Can you provide some code that shows how you catch that user data button message?

    Best wishes,
    Sebastian



  • On 13/06/2016 at 13:29, xxxxxxxx wrote:

    Hi Sebastian,

    I'm storing position values on a per frame basis in a BaseContainer created in the python tag itself.  I wanted have both options of either reading/writing data to the container.  It would be using standard playback to cache position values, and if the user decided, they could simply read those values rather than update/store new ones.  It therefore gives the same playback flexibility as a dynamics cache--you can scrub back and forth once the position values have all been cached.

    But I also wanted to give the user the ability to clear the cache, just as the dynamics cache does, and used code I found in this post for catching the user data button being pressed:

        if id == c4d.MSG_DESCRIPTION_CHECKUPDATE:
            try:
                if data["descid"][1].dtype == c4d.DTYPE_BUTTON:
                    buttonID = data["descid"][1].id
                    
                    if buttonID == 24:                            #If "CLEAR CACHE" is pressed...
                        pvaData.FlushAll()                        #Clear all cached data
    

    I hope that makes sense, and thanks for the help!
    --Marcus



  • On 14/06/2016 at 02:15, xxxxxxxx wrote:

    Hello,

    the following code seems to work perfectly fine with R17 SP2 even if "Frame Dependent" is enabled.

      
    import c4d  
      
    def main() :  
      cTime = doc.GetTime().GetFrame(doc.GetFps())  
      cPos  = op.GetObject().GetMg().off  
      print cTime, cPos  
        
    def message(id,data) :  
      
      if id == c4d.MSG_DESCRIPTION_CHECKUPDATE:  
      
          if data["descid"][1].dtype == c4d.DTYPE_BUTTON:  
      
              buttonID = data["descid"][1].id  
                
              if buttonID == 1 :  
                  print "press button"  
    

    Best wishes,
    Sebastian



  • On 16/06/2016 at 06:05, xxxxxxxx wrote:

    Sebastian,

    I tried it again, and you are correct, it worked just fine for me in R16 as well.  I found that the button worked as I expected while the animation was playing (and thus the tag was running), but while it was paused, the code in the tag was not being evaluated since it is now "frame dependent."

    The flush function was working correctly, but my feedback fields in the user data were simply not being updated, so it appeared superficially that it wasn't working.  I simply moved the line of code which updates the user data feedback field from the main() in to the message() portion for each respective button.

    All is working as it should -- the help is much appreciated!
    --Marcus


Log in to reply