Search Unity

Any plans to expose exact force and torque added during collision phase?

Discussion in 'Physics' started by KeithKong, Dec 17, 2017.

  1. KeithKong

    KeithKong

    Joined:
    May 31, 2015
    Posts:
    73
    This has been a huge limitation for me since picking up unity. So there's "Collision.relativeVelocity" which doesn't even represent a before/after change. There's "Collision.impulse" which gives some kind of averaged force. But collisions add force at points resulting in both force and torque impulses being applied to the object. So what does an average "impulse" even mean realistically? Are they just cutting out the torque and not including it arbitrarily?

    It seems to me the obvious and most useful information would be the combined force/torque added from each contact point to each of the objects in the collision. I'm currently working on custom physical joints and they work smoothly and beautifully but for the fact I can't accurately account for collision forces immediately.

    Are there any plans to expose this information? Even for tasks like calculating damage (which do okay using the current information) it would be more accurate and consistent.
     
    Last edited: Dec 17, 2017
  2. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    Collision.impulse is what you're looking for. It's the impulse applied to the object at the contact point.

    An impulse is a force applied during a given time. In this case, the impulse is a force applied during a single simulation step. Thus, just divide the impulse by Time.deltaTime to get the actual force:

    Code (CSharp):
    1. Vector3 force = collision.impulse / Time.deltaTime;
    Note: this calculation works in FixedUpdate. Otherwise, use Time.fixedDeltaTime instead of Time.deltaTime.

    The torque is a consequence of applying a force not in the center of mass. The torque value may be calculated as the cross product of the force with the relative position of the contact point. I don't know the correct way to calculate it in Unity because a single collision is reported as a list of contact points.
     
  3. Deleted User

    Deleted User

    Guest

    I think you might need to try Time.fixedDeltaTime - I'm not sure.
     
  4. KeithKong

    KeithKong

    Joined:
    May 31, 2015
    Posts:
    73
    Thanks for your input Edy. However, I don't think you read my post carefully. I already understand translation between velocity/acceleration/force/impulse and I have a fairly advanced understanding of physics in general. In my post I explained how an impulse can not possibly represent all of the changes applied between the objects.

    At best Collision.impulse represents the linear difference in impact force between the two collision objects. At worst, it only represents the force applied to the object receiving the callback. In either case, it still excludes the angular impact (torque) applied to either object.

    I'm looking for a complete and accurate combined force and torque applied to both objects due only to the collision (independent of gravity/other collisions/random forces applied in the same fixed update).
     
  5. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    I think I did, but maybe I didn't explain the topic correctly. English is not my native language, sorry.

    Collision.impulse is the impulse applied at the contact point where the objects have collided in order to prevent them to inter-penetrate. When the contact point is not the center of mass, and also the direction of the impulse is not aligned with the center of mass, that impulse also causes a change in the angular momentum (= a torque).

    The torque T may be computed from the impulse and the contact point:

    F = I / t
    T = r x F

    where F is the force applied during the physics step, t is the time the force has been applied (deltaTime) and r is the vector from the center of mass to the contact point where the impulse I is applied. x is the cross product.

    When a force F is applied to a rigidbody not in the center of mass, the same force causes both a linear acceleration and an angular acceleration. The linear acceleration will always be the same (a = F / m). The angular acceleration depends on the contact point (vector r in the formula above), and may be calculated in a similar way using the inertia tensor of the rigidbody (angular acceleration = torque / inertia tensor).

    In the case of two bodies colliding collision.impulse is applied to both bodies in opposite directions at the contact point.

    EDIT: In summary, my point is that collision.impulse and the contact point represent all the changes in lineal and angular velocities in the colliding objects.
     
    Last edited: Dec 21, 2017
    Magic73 and metroidsnes like this.
  6. KeithKong

    KeithKong

    Joined:
    May 31, 2015
    Posts:
    73
    I see where we are not understanding each other. I had the same idea but the problem with your explanation is that a Collision object contains contact points (plural) so it's ambiguous what position the "impulse" would apply to.

    As I mentioned I understand the physics end, I've already implemented custom methods that perfectly imitate any form of AddForce/AddTorque/AddForceAtPosition. But do you average the contact points for Collision.impulse? Because that doesn't really make any sense physically.

    Thanks for the attention to this post by the way! You're going above and beyond with depth.
     
    Last edited: Dec 28, 2017
  7. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    You're right. I had assumed that the impulse would be consistent with the average of the contact points, but I've done some tests and that's not the case.

    I've dug further into the topic. The PhysX collision information is referenced here:

    http://docs.nvidia.com/gameworks/co...x/apireference/files/structPxContactPair.html

    And the contact point information is here:

    http://docs.nvidia.com/gameworks/co...reference/files/structPxContactPairPoint.html

    As you can see, PhysX reports a single impulse per each contact point. However, Unity exposes a single impulse value per collision. We may assume that Unity is averaging the impulses from all the contact points. As you pointed out, that doesn't make any sense physically.

    We should ask @yant if this can be corrected, as it's an important issue. I also had plans on using the impulse for advanced collision processing in one of my projects.
     
    Magic73 and KeithKong like this.
  8. KeithKong

    KeithKong

    Joined:
    May 31, 2015
    Posts:
    73
    Just wanted to bump this to see if @yant could chime in. Should this be added to feedback for voting? This seems more like a bug as it's implemented incorrectly but I'm not very familiar with how Unity handles issues.
     
  9. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    I asked @yant directly and he told that this should totally happen, but at this time they're entirely focused on the upcoming PhysX update. I think we may expect this change after the update has been rolled out and stabilized.
     
  10. KeithKong

    KeithKong

    Joined:
    May 31, 2015
    Posts:
    73
    Good to hear, thanks for updating me!
     
  11. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    596
    I think Edy's right -- we could expose the per-contact impulses, as it makes a lot of sense physics-wise. One possible caveat on the way is that doing so we increase the footprint of the Collision structure which is getting allocated on the heap, thus being an extra GC pressure factor. Many devs reported that OnCollisionStay is not as useful as it potentially could be for that particular reason over the years. There is a plan to address that as well - we'd make it so that you get the contacts as arrays directly, on demand. 2D already does something like that, but we were going to take it another step forward and make it unified between 2D and 3D. Will have to be addressed after the PhysX upgrade, as Edy pointed out.

    Hope that's a useful perspective.
     
    KeithKong and Edy like this.
  12. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    It's really useful, thanks so much for the update!
     
  13. blade_sk

    blade_sk

    Joined:
    Oct 9, 2017
    Posts:
    2
    This is still an issue.You can either get a list of contact points, but without impulses applied to them or you get a sum of impulses, but without a point the sum is applied to. This makes it impossible to modify the collision in any useful way. My use case is to amplify particular collisions, but this doesn't seem doable with what's available now (Unity 2018.3.8).
     
  14. cdca7694

    cdca7694

    Joined:
    Sep 8, 2019
    Posts:
    2
    I am trying to do robotics simulation with collision detection in unity, going to use it as a force sensor. I am trapped with this problem now, wondering is it fixed nowadays?
     
  15. cdca7694

    cdca7694

    Joined:
    Sep 8, 2019
    Posts:
    2
    I'm glad to have suggestions from developers like you. Is the modification you mentioned be done until today?