Search Unity

Smoothing Interpolation goes wrong for 1 frame

Discussion in 'Physics for ECS' started by argibaltzi, Apr 5, 2021.

  1. argibaltzi

    argibaltzi

    Joined:
    Nov 13, 2014
    Posts:
    220
    Hello
    I have recently changed my physics fps to 30 and i am seeing some problems i didnt see before

    I have a system that runs after the FixedStepPhysics
    The system does the following when the bug occurs

    1) Grab a mesh entity (its parent is a physics entity )
    2) Create a new physics entity
    3) put the mesh entity under this new physics entity
    (the mesh entity 3 is supposed to be at the same location it was at 1, this is how i know its wrong location)

    Quite often the first frame this new physics entity appears in a wrong place and the next frame it goes where it should be. I found that its being caused from the interpolation systems but i dont understand where and how.

    I set the ApplySmoothing to 0 to skip interpolation for this frame but it doesn't fix it. Is there anything else i need to take into account?
     
    Last edited: Apr 5, 2021
  2. milos85miki

    milos85miki

    Joined:
    Nov 29, 2019
    Posts:
    197
    Hi @argibaltzi , could you please share the code that changes mesh entity parent and the attributes for your system?
    You should make sure it starts after the ExportDynamicBodiesJob is complete.
     
  3. argibaltzi

    argibaltzi

    Joined:
    Nov 13, 2014
    Posts:
    220
    The code is complex and with many functions but here is a part of it.
    For some cases i was able to copy the smoothing data as well and it solved the problem i think (or reduced it!)
    However i have many other cases which are more complicated and i need to know how to tackle this problem.


    What i am essentially doing is "duplicating" the physics Entity A and moving some of its meshes to physics Entity B

    Code (CSharp):
    1.  
    2.  
    3. // Create new physics entity, use the same tranform and velocity as the other physics entity
    4.  
    5.      
    6. Entity newDebrisVolumeEntity = frameCmd.CreateEntity(GamePhysics.Instance.VoxelVolumeArchetype);
    7.          
    8. frameCmd.SetComponent<Translation>(newDebrisVolumeEntity, parentTranslation);
    9. frameCmd.SetComponent<Rotation>(newDebrisVolumeEntity, parentRotation);
    10. frameCmd.SetComponent<LocalToWorld>(newDebrisVolumeEntity, parentLocalToWorld);
    11.    
    12. // ...
    13.  
    14. frameCmd.SetComponent<Parent>(perMeshDataItem.RenderMeshEntity, new Parent() { Value = newDebrisVolumeEntity });
    15.  
    16. // .... Create collider and some physics stuff
    17.  
    18.  
    19. PhysicsGraphicalSmoothing smoothing = new PhysicsGraphicalSmoothing() { ApplySmoothing = 0, CurrentVelocity = parentVelocity};
    20.  PhysicsGraphicalInterpolationBuffer interpolationBuffer = new PhysicsGraphicalInterpolationBuffer() { PreviousTransform = new RigidTransform(quaternion.identity, float3.zero), PreviousVelocity = parentVelocity };
    21.  
    22. frameCmd.SetComponent<PhysicsGraphicalSmoothing>(entity, parentSmoothing);
    23. frameCmd.SetComponent<PhysicsGraphicalInterpolationBuffer>(entity, parentInterpolationBuffer);
    24.  
    25. frameCmd.SetComponent(entity, physicsMass);
    26. frameCmd.SetComponent(entity, velocityData);
    27. frameCmd.SetComponent(entity, damping);
    28.            

    One guess i have at the moment is Body A (LocalToWorld will change in SmoothRigidBodiesGraphicalMotion) but Body B has no smoothing for this frame and will draw in Bodys A LocalToWorld before the smoothing.

    Physics FPS is 30 and Render is 60


    The other thing i noticed is the position sometimes goes very wrong for 1 frame, as if its interpolating with an identity matrix or something


    I couldn't find ExportDynamicBodiesJob ? Is this a physics system job i should wait for?
     
  4. milos85miki

    milos85miki

    Joined:
    Nov 29, 2019
    Posts:
    197
    ExportDynamicBodiesJob is scheduled in ExportPhysicsWorld. You can get the right job handle by calling ExportPhysicsWorld.GetOutputDependency() .
    Seems like it'd be best if the new entity was created and filled with components before SmoothRigidBodiesGraphicalMotion system (which schedules the SmoothMotionJob). That way, it would be simulated in next frame and after that it'd be interpolated for the first time (first SmoothMotionJob would only set ApplySmoothing to 1).

    Could you please try setting the PreviousTransform in new PhysicsGraphicalInterpolationBuffer to the current transform value, instead of new RigidTransform(quaternion.identity, float3.zero) ?
     
    Last edited: Apr 6, 2021
  5. argibaltzi

    argibaltzi

    Joined:
    Nov 13, 2014
    Posts:
    220
    "Could you please try setting the PreviousTransform in new PhysicsGraphicalInterpolationBuffer to the current transform value, instead of new RigidTransform(quaternion.identity, float3.zero) ?"

    does it matter when the ApplySmoothing is 0?
     
  6. milos85miki

    milos85miki

    Joined:
    Nov 29, 2019
    Posts:
    197
    It shouldn't matter, but I think it's worth trying because you said:
    It's quite hard to guess from the code you pasted. I think it's best to find a body that has a problem and then debug it for a frame or two around the time problem appears. Key systems for interpolation are:
    1. BufferInterpolatedRigidBodiesMotion - schedules UpdateInterpolationBuffersJob, which fills PhysicsGraphicalInterpolationBuffer based on entitie's Translation, Rotation and Velocity. If there's a discrepancy between LocalToWorld and Translation-Rotation, that might be the source of problems
    2. SmoothRigidBodiesGraphicalMotion - schedules SmoothMotionJob which performs the smoothing based on Translation, Rotation and PhysicsGraphicalInterpolationBuffer (velocity is not important for interpolation) and writes the result to LocalToWorld

    I would first check if the jobs are ordered correctly (your job, ExportDynamicBodiesJob and the 2 I mentioned above) in the problematic frame(s) and print relevant positions. Seems like it's safe to ignore rotation, which makes things easier to follow.
     
  7. argibaltzi

    argibaltzi

    Joined:
    Nov 13, 2014
    Posts:
    220
    I was able to solve this problem by keeping interpolation on for all objects and making sure all data is correct, i was hoping disabling interpolation by one frame would be easier... :D
    I will look more into your suggestions and see if i can find whats wrong with that approach when i have some time
    Thanks!
     
    milos85miki likes this.