Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Resolved RigidBody.AddForce vs PhysicsVelocity.Angular question

Discussion in 'Physics for ECS' started by FareedDudhia, Aug 23, 2023.

  1. FareedDudhia

    FareedDudhia

    Joined:
    Jul 25, 2012
    Posts:
    2
    Hello,

    I've been tearing my hair out for a long time trying to fix what should be a simple world -> local transform (as far as I know).

    I am trying to write an aerodynamics simulation in Unity ECS. In the original code, everything works. It does the following:

    Code (CSharp):
    1. rb.AddForce(currentForceAndTorque.p);
    2. rb.AddTorque(currentForceAndTorque.q);
    AddForce and AddTorque both apply in world space, and the currentForceAndTorque values are calculated in world space, so it all works fine.

    In my code, when I apply my lift and drag with

    Code (CSharp):
    1. physicsVelocity.ApplyLinearImpulse(physicsMass, forceAndTorque[0] * deltaTime);
    It works fine. ApplyLinearImpulse is in world space, so it's all good.

    Initially, I was trying to apply the angular velocity like this:

    Code (CSharp):
    1.  
    2. physicsVelocity.Angular += forceAndTorque[1]  * physicsMass.InverseInertia * deltaTime;
    3.  
    This didn't work -- physicsVelocity.Angular is in local space but my forceAndTorque[1] is in world space. So I tried a lot of different variations of this:

    Code (CSharp):
    1.  
    2. quaternion inverseWorldRotation = math.inverse(vehicleLtw.Rotation);
    3. // Convert world-space torque to local space
    4. float3 localTorque = math.mul(inverseWorldRotation, forceAndTorque[1]);
    5. physicsVelocity.Angular += localTorque  * physicsMass.InverseInertia * deltaTime;
    6.  
    All of them had my plane go totally haywire at the slightest whiff of (non-x-axis) rotation.

    Now I am trying this:

    Code (CSharp):
    1.  
    2. var currentWorldAngularVelocity = math.mul(physicsMass.Transform.rot, physicsVelocity.Angular);
    3. physicsVelocity.SetAngularVelocityWorldSpace(physicsMass, physicsMass.InertiaOrientation, currentWorldAngularVelocity + worldTorque * physicsMass.InverseInertia * deltaTime);
    [/code]

    With pretty much the same result.

    I've also tried pretty much every other possible quaternion available in place of `physicsMass.Transform.rot`, e.g. physicsMass.InertiaOrientation, and the LocalToWorld on the entity as well. I've completely run out of ideas of how to approximate "rigidbody.AddTorque" in ECS.

    I'd really, really appreciate any pointers as to where I'm going wrong here. What I'm trying to do seems so simple, just "AddTorque" but for ECS, but I cannot find anything that is equivalent.

    Update:

    I've now also tried

    Code (CSharp):
    1.  
    2. physicsVelocity.ApplyAngularImpulse(physicsMass, forceAndTorque[1] * deltaTime);
    3.  
    and this also seems to apply the impulse to the wrong axis, also causing the plane to rotate wildly.

    Thanks
     
    Last edited: Aug 23, 2023
  2. daniel-holz

    daniel-holz

    Unity Technologies

    Joined:
    Sep 17, 2021
    Posts:
    213
    The angular velocity is indeed in motion space, which is a specialized local space of the body in which the body's inertia tensor becomes a diagonal matrix, meaning the axes of this space are identical to the principal axes of inertia.

    See here (
    PhysicsVelocity.SetAngularVelocityWorldSpace
    ) for how to navigate between world space and motion space:
    upload_2023-8-30_10-29-6.png

    Another example for this sort of coordinate space transformation can be found in the
    RigidBodyAspect
    , in the
    AngularVelocityWorldSpace
    property:

    upload_2023-8-30_10-31-39.png

    Above you can also clearly see the distinction between this special runtime local space, called motion space, and the actual rigid body local space (edit-time local space).
    The property
    BodyFromMotion_Rot
    is used above to navigate from motion space to local body space.
    The property
    Rotation
    is used above to navigate from local body space to world space.

    If you want to go from motion space to world space, you need to compound both as is done in the
    AngularVelocityWorldSpace
    property.
     
    Last edited: Aug 30, 2023
    Antypodish and FareedDudhia like this.
  3. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,574
    @FareedDudhia

    I am just curious.
    Did you run by any chance into NaN infinite torque and force, in your aerodynamics code conversion?
     
  4. FareedDudhia

    FareedDudhia

    Joined:
    Jul 25, 2012
    Posts:
    2
    @daniel-holz

    Thanks so much for this answer, after much digging I found and solved the issue using some of the code in the examples you screenshotted above. My only remaining question would be how can I browse this code myself? If I could have found the code you linked myself I might have been able to figure it out on my own.

    @Antypodish
    I did, yeah, but my issue in the end was simply that a value for angular velocity was in local/motion? space when it should have been in world space. I can clean up the working code and link it to you if you'd like (might take me a while).
     
    Antypodish likes this.
  5. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,574
    Oh that would be amazing. I looked into same repo, or one of its fork. I have converted it, but had mentioned physics incompatibilities.

    No worry, I will appreciate for the repo, but I am not in a hurry, so do whenever you will get he time.

    Many thx in advance.
     
  6. daniel-holz

    daniel-holz

    Unity Technologies

    Joined:
    Sep 17, 2021
    Posts:
    213
    @FareedDudhia : the code is in the Unity Physics Package within your project.
    You can easily navigate to and inspect the code with an IDE of your choice linked to the Unity Editor.
     
    FareedDudhia likes this.
  7. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,574
    Hey,
    Just a little poke, in case you are busy, or forgot :)
    No rush however.