Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Immediate Contact Generation

Discussion in 'Physics Previews' started by JuozasK, Nov 23, 2022.

  1. JuozasK

    JuozasK

    Unity Technologies

    Joined:
    Mar 23, 2017
    Posts:
    84


    Hey everyone!


    We’ve got another exciting feature to share with you today! It’s called immediate contact generation! It allows to generate contact points between two shapes, without calling into any of the methods that run the physics scene simulation. Possible use cases would be to get a quick way of checking if objects are overlapping, or to get the contact points for your game logic.


    The feature includes:

    • Basic shape geometry - these are new data structures that match the shapes in PhysX. So that would be Box, Sphere, Capsule, Convex Mesh, Triangle Mesh and Terrain Geometry structures.

    • GeometryHolder object - a data structure that can house any geometry shape and its type. This is the structure that you will be passing into the generate contacts function.

    • ImmediateTransform - a transform containing Position and Rotation that matches PhysX.

    • ImmediatePhysics.GenerateContacts - the main function that takes pairs of shapes and transforms and outputs the contacts to your submitted NativeArray, alongside how many contacts each pair generated.

    The code lives under the UnityEngine.LowLevelPhysics namespace.


    Sidenote: Currently there is no way to create a ConvexMeshGeometry and TriangleMeshGeometry from scratch. These should be taken from the MeshCollider component, with the appropriate convex/non-convex flag applied.


    Since it’s not a very large feature, I’ve created an example script instead of a project, showing the different ways you can use this feature, though descriptions of each structure will be available in the scripting API as always.


    Contact Generation is live since 2023.1.0a21.

    Currently there are no plans to backport it, as usually we don’t backport new features.


    I’m excited to hear your feedback!
     

    Attached Files:

    M_MG_S, Gooren, LudiKha and 8 others like this.
  2. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    Looks great! Here's some quick feedback:

    Code (CSharp):
    1. m_Shape = GetComponent<Collider>().GeometryHolder;
    2. geom1[1] = GetComponent<Collider>().GeometryHolder;
    Shouldn't be "geometryHolder", lowerCamelCase? In Unity API the property names begin with lower case, while method names begin with upper case. Otherwise, "GeometryHolder" is confusing as not only it's not a method, but also it's the type name. All other other properties in Collider follow the correct Unity API convention.

    Code (CSharp):
    1. // If we want to retrieve the BoxGeometry that is stored inside, we have to call the "As" method.
    2. // This will only work if the GeometryHolder was created with the BoxGeometry first, otherwise,
    3. // when you try to retrieve a different shape, it will throw an InvalidOperationException
    4. m_BoxGeometry = m_Shape.As<BoxGeometry>();
    I guess there would also be a method for retrieving the geometry type? So we can compare if the shape is a specific geometry type, something like this:
    Code (CSharp):
    1. Geometry geometry = m_Shape.GetGeometry();
    2. if (geometry is BoxGeometry) Debug.Log("This is a box");
    Which excites me most is:
    Code (csharp):
    1. using UnityEngine.LowLevelPhysics;
    I assume it's not yet documented, as the docs for 2023.1 doesn't include it. I assume it's the placeholder for exposing more low level portions of PhysX :)
     
  3. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    Also, what's the information provided in each contact (ImmediateContact)?
     
  4. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    596
    Hey Edy,

    Good to see an old friend in this forum branch ;-)

    I'll start saying that this is indeed a tiny bit of what we've been hinting at for years -- the complete immediate mode exposed. For this release we've got the most popular request implemented, which is generating contacts. As you'd notice, we're using the raw PhysX structures there, and preserve naming too. This is fairly unusual for Unity code, but the feature is intended to be pretty low-level and for those who understand what they do, and would like to write code as if it's raw SDK there. Hopefully, most if not all of the PxImmediateMode.h could be made available.

    ImmediateContact is actually Gu::ContactPoint, bit to bit. Clearly, not all of these properties get filled up by the contact generator, it's mostly like an exchange structure in PhysX for holding data required for the solver step later.

    Anthony
     
    LudiKha and Edy like this.
  5. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    Hi Anthony, glad to see you're still around :) Good to know about the progress and future plans on the immediate mode.
    Totally understood. I meant about the specific case of Collider.GeometryHolder, which is a property returning an object of type GeometryHolder. Nothing about the type itself, but as per my understanding the name of the property exposed in the Collider component should be geometryHolder, lowerCamelCase. Otherwise it would be contrary to the rest of the properties and methods exposed in Collider.
     
  6. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    596
    Speaking of PascalCase vs camelCase, I believe it's part of the initiative to bring all the Unity APIs the standard C# guidelines.
     
  7. JuozasK

    JuozasK

    Unity Technologies

    Joined:
    Mar 23, 2017
    Posts:
    84
    Yeah, we are using PascalCase for our properties, but the old one's have not been changed yet.

    As for the type, you can query that from the GeometryHolder object directly

    For example,
    Code (CSharp):
    1. GetComponent<Collider>().GeometryHolder.Type
    Which will return you the GeometryType enum which you can use for your checks.
     
    Edy and goncalo-vasconcelos like this.
  8. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    Thank you for the info. I've also seen other parts of Unity also adopting these new standards (Cinemachine 3.0). Do you guys have some guide or refer to some common resource across Unity as reference for the coding style to adopt? I'd just like to be ready to change my APIs as well when it's time to.
     
  9. JuozasK

    JuozasK

    Unity Technologies

    Joined:
    Mar 23, 2017
    Posts:
    84
    We do, though it's based on a mostly superset of Microsoft's Framework Design Guidelines.

    To quote the guidelines
    "Names of Fields
    The field-naming guidelines apply to static public and protected fields. Internal and private fields are not covered by guidelines, and public or protected instance fields are not allowed by the member design guidelines.

    ✔️ DO use PascalCasing in field names."
     
    Edy likes this.
  10. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    Cool, thank you! That guide is very useful.
     
    Last edited: Dec 2, 2022
  11. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447
    First of all, thank you very much for bringing this great feature to Unity :) ... more immediate mode stuff please!

    I've done a few tests combining all kind of geometries, and i think i've found a bug. The problem i'm experiencing is that Transform's rotation and ImmediateMode's Rotation don't match when the geometry involved is a capsule. I have tried with boxes, spheres, cylinders and other convex/non-convex geometries, and they all worked fine.

    For example, when setting the immediate transforms like this:
    Code (CSharp):
    1. // Capsule geometry
    2. immediateTransformsA[0] = new ImmediateTransform
    3. {
    4.        Position = transform.position,
    5.        Rotation = transform.rotation
    6. };
    7.  
    8. // Box geometry
    9. immediateTransformsB[0] = new ImmediateTransform
    10. {
    11.        Position = TargetCollider.transform.position,
    12.        Rotation = TargetCollider.transform.rotation
    13.  };
    This is what happens (red line represents the "contact penetration"):
    Contact generation Not Fixed L.gif

    ... As shown here, the capsule geometry appears to be rotated to the left (z axis) 90 degrees.
    Now, if i rotate the capsule geometry 90 degrees to the right:
    Code (CSharp):
    1. // Capsule geometry
    2. immediateTransformsA[0] = new ImmediateTransform
    3. {
    4.        Position = transform.position,
    5.        Rotation = geometriesA[0].Type == GeometryType.Capsule ? Quaternion.AngleAxis(90f, Vector3.forward) * transform.rotation : transform.rotation
    6. };
    7.  
    8. // Box geometry
    9. immediateTransformsB[0] = new ImmediateTransform
    10. {
    11.        Position = TargetCollider.transform.position,
    12.        Rotation = geometriesB[0].Type == GeometryType.Capsule ? Quaternion.AngleAxis(90f, Vector3.forward) * TargetCollider.transform.rotation : TargetCollider.transform.rotation
    13.  };
    Contact generation real Fixed L.gif

    I'll report this
     
    Last edited: Sep 11, 2023