Search Unity

Unity Physics Discussion

Discussion in 'Data Oriented Technology Stack' started by smcclelland, Mar 18, 2019.

  1. Shinyclef

    Shinyclef

    Joined:
    Nov 20, 2013
    Posts:
    364
    Currently, I'm using unity physics to utilise triggers for projectile hits and queries, particularly DistanceCast for nearest enemy searches, and RayCast for mouse selection.

    I would note that I am likely to eventually start using collisions and velocity, I'm just focused on other things right now. I thought it odd that kinematics were eating so much CPU time with the solver considering it would be impossible to move them anyway. I'm testing with a good 5-10k entities though, and ironing out bottlenecks to see how far I can push it.
     
    steveeHavok likes this.
  2. alia_0

    alia_0

    Joined:
    Nov 28, 2012
    Posts:
    9
    Hello there! I have recently attempted to use Unity.Physics.MeshCollider.Create as a replacement for PhysX.MeshBake and I ended up with some surprising results. For a mesh with 1961 triangles (triangle soup) I got the following timings from Create():

    Weld: 65ms
    DominantGeo: 20ms
    BVH construction: 32ms
    and some 18ms for the rest of the function.

    This was pretty normative for the rest of the meshes that had tris in the range of 1k -> 6k.

    I am assuming im doing something _really_ wrong at this point.

    Example mesh for reference:

    How I was using it:
    Code (CSharp):
    1.                
    2. Unity.Entities.Entity entity = EntityManager.CreateEntity(new Unity.Entities.ComponentType[] { });
    3. EntityManager.AddComponentData(entity, new Unity.Transforms.LocalToWorld { });
    4. EntityManager.AddComponentData(entity, new Unity.Transforms.Translation { Value = trans });
    5. EntityManager.AddComponentData(entity, new Unity.Transforms.Rotation { Value = { } });
    6.  
    7. var collider = Unity.Physics.MeshCollider.Create(verts, indxs);
    8. var colliderComponent = new Unity.Physics.PhysicsCollider { Value = collider };
    9. EntityManager.AddComponentData(entity, colliderComponent);
    10.  
     
  3. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    4,671
    MeshCollider generation isn't using bursted code right now and generally slow. We are aware of it and will optimize.
     
    alia_0 and steveeHavok like this.
  4. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    110
    I know the good folk are working on that announcement very soon, so I won't spoil their thunder.
    I also know we have certainly not forgotten you little solo indies, and that you should not be scared at all ;-)
     
  5. Gaaammmler

    Gaaammmler

    Joined:
    Apr 10, 2018
    Posts:
    11
    Hello Guys,

    i read about the possibility to overwrite the Collision Logic from Unity.physics in ecs, how can i do that? I didnt find some Examples for it in the Physics sample: https://github.com/Unity-Technologi...UnityPhysicsExamples/Documentation/samples.md

    I didnt need the 3d Tree approach, i can simplify it for my Game to Spatial hashing.

    Also i dont know how i get the RayCast only for the terrain and ignore Entitys on the Way. How do i create the Filter for that:
    Code (CSharp):
    1.  RaycastInput positionRay = new RaycastInput
    2.                 {
    3.                     Ray = new Unity.Physics.Ray(playerInput.Ray.origin, playerInput.Ray.direction * 1000),
    4.                     Filter = CollisionFilter.Default
    5.                 };
    6.                 Unity.Physics.RaycastHit hit;
    7.                 if (CollisionWorldSystem.CastRay(positionRay, out hit))
    8.                 {
    9.  
    10.                     position = new float3(hit.Position.x, hit.Position.y + 1, hit.Position.z);
    11.                 }
    Im a beginner with Unity but i love the ecs approach.
     
  6. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,064
    The examples of modifying physics logic are here: https://github.com/Unity-Technologi...hysicsExamples/Assets/Demos/5. Modify/Scripts
     
  7. elcionap

    elcionap

    Joined:
    Jan 11, 2016
    Posts:
    87
    Testing IContactsJob with SimulationCallbacks.Phase.PostCreateContacts are giving me some odd behaviour. It's always skipping the "first" contact. Testing with two spheres don't give any data back and with three give only one contact.

    Debugging NarrowPhase.ProcessBodyPairsJob source is capturing the correct number of contacts. But when iterating the contacts (com.unity.physics@0.1.0-preview\Unity.Physics\Dynamics\Simulation\IContactsJob.cs:177) the iterator constructor is reading the first contact, zeroing RemainingItemCount without this being considerate in HasItemsLeft check in the while.
    Changing HasItemsLeft() to iterator.m_LastHeader != null made it work but obviously it's not the best fix.

    Just submitted an repro case: 1160777.

    []'s
     
    steveeHavok likes this.
  8. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    1,656
    OK sorry so slow reply I've been debugging this for ages.
    normalizeSafe did not help (i did not expect as target was the mouse position so exact match was low)

    Here's a small repo. Simply run it in editor vs a windows IL2CPP build and compare the behaviour. Click to move.

    -edit-

    enabling vsync slows down speed in build. but i don't think this should be the case because only velocity is being set.
     

    Attached Files:

    Last edited: Jun 7, 2019
  9. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    787
    I'm using ICollisionEventsJob and ITriggerEventsJob and none of them get used.
    I tried lots of things like adding/removing:

    [UpdateAfter(typeof(StepPhysicsWorld))]
    [UpdateBefore(typeof(EndFramePhysicsSystem))]


    but the only thing that seems to make a difference (but only sometimes) is when I have a physics debug in my scene and then toggle on "DrawCollisionEvents" and "DrawTriggerEvents". But that might just be a coincidence becasue sometimes just waiting or "lagging" the editor for a bit also randomly makes it work.

    Am I missing something here??

    Here is my full code: https://pastebin.com/EVqwarRw

    Please note that everything that is commented out in that code was just from experimentation. (except for the
    //if(bulletGroup.Exists(a))
    filters which I want to leave commented out always for now).

    The strange part is that the collisions seem to randomly work, sometimes, but I have no clue when or why.

    All my bullet entities have (at least) the following components (in addition to 'Bullet'): Translation, Rotation, LocalToWorld, PhysicsCollider (with a SphereCollider.Create), PhysicsGravityFactor, PhysicsMass (with CreateKinematic and MassProperties.UnitSphere), PhysicsVelocity.


    Any ideas? (2019.3.0a4, newest preview packages from the package manager)

    edit: just for now the goal is to just destroy any entities that collide with each other.

    edit2: DrawTriggerEvents also clearly shows that the system seems to find/recognize the trigger events: https://i.imgur.com/p50ziVy.png (dont mind the visual representation being a little smaller than the actual spheres being used, if I turn on DrawColliders everything is also as expected)
     
    Last edited: Jun 7, 2019
  10. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    424
    Thanks for the awesome explanations! Joachim cleared up a lot of my concerns with the unsafe collider API. I have an idea now how to rebase my CCDE on top of Unity.Physics, so I'll be keeping an even closer eye on this development. I'm very curious about your examples for non-gameplay critical simulations. That almost sounds like we might be seeing cloth or softbody solvers in the future. :D

    Out of curiosity, do you know what the plan is going to be for terrain colliders? I'm mostly curious if the plan is to use the concave mesh code path, use the grid for narrowing x and z and some BVH of minmax heights for y, or some other approach? Terrain is the next big item I need to tackle for my CCDE on the primitive solver backend.
     
  11. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    110
    Thanks for this. We hit this recently as well. I've added your post to the issue.
     
  12. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    110
    Can you check in the Entity Debugger and make sure
    PhysicsBulletCollisionSystem
    is actually running? In the past, we found an issue with StepPhysicsWorld where the system wouldn't stay active and we needed to add in an EntityQuery just to keep it alive (see com.unity.physics@0.1.0-preview/Unity.Physics/com.unity.physics/Unity.Physics/ECS/Systems/StepPhysicsWorld.cs line 51).
    I should really go back and look to see it that is still necessary.
     
  13. Shinyclef

    Shinyclef

    Joined:
    Nov 20, 2013
    Posts:
    364
    Have you tried [AlwaysUpdateSystem]?
     
    steveeHavok likes this.
  14. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    110
    I can imagine some fun usecases where cloth or softbody solvers are gameplay critical :)
    I was thinking about elements that need a simulation but shouldn't impact the gameplay mechanisms.
    For example, the aerials, doors and mudflaps on the Humvee in the RaycastCar demo are constrained to the vehicle itself and in the main simulation. These bodies are very light compared to the chassis and don't have any collisions enabled, but they will have an, admittedly tiny, effect on the vehicle handling.
    They are will also have a bigger effect on the determinism of the core gameplay simulation in a networked scenario. Butterflies wings and all that! As non-gameplay critical elements, we won't want the bother sending the door, aerial and mudflaps transforms over the network. If they are in the main simulation though and we don't send them, then determinism is lost. So, while needing a simulation to look good, they should be off in a separate simulation, that would only be stepped only on the more powerful clients.

    Regarding the Terrain Collider, the easiest thing I can do it give you the comments from the TerrainCollider code changes that are currently under review:

    Code (CSharp):
    1.    
    2.     // A collider representing a heightfield.
    3.     // Heights are quantized to a signed 16 bit integer
    4.     // Four height samples at (i, j), (i + 1, j), (i, j + 1), (i + 1, j + 1) make a quad.
    5.     // The quad is triangulated with an edge connecting (i + 1, j) to (i, j + 1).
    6.     // Queries are accelerated with a tree whose leaves are quads and whose interior nodes
    7.     // each have four equal-sized children.
    8.     // Warning: This is just the header, it is followed by variable sized data in memory.
    9.     // Therefore this struct must always be passed by reference, never by value.
    10.     public struct TerrainCollider : ICompositeCollider
    11.     {
    12.         // TerrainCollider offers two methods for rigid body collision with performance / quality tradeoffs
    13.         public enum CollisionMethod
    14.         {
    15.             // Each vertex of the other shape is projected downward onto the terrain and a contact plane is generated from
    16.             // the triangle.  This is very fast, but it is possible for the other shape's edges and faces to penetrate edges
    17.             // and vertices of the terrain, or for the other shape to tunnel completely through steep faces in the terrain.
    18.             // It works best with relatively smooth terrain, and worst with cliffs and sharp peaks.  It also has the trait
    19.             // that bodies below the terrain but within its AABB will be pushed up, even if they are not touching the
    20.             // surface triangles.
    21.             VertexSamples,
    22.  
    23.             // In this mode the collision behaves exactly as if it were a MeshCollider.
    24.             Triangles
    25.         }
    26.         .....
    27.     }
    28.  
    and for creation you currently supply an int2 size specifing the number of height samples in each dimension, a float3 scale to transform from heightfield space to local space, a float* heights pointer to the sample data and a CollisionMethod as described above:

    Code (CSharp):
    1.             BlobAssetReference<Unity.Physics.Collider> collider = Unity.Physics.TerrainCollider.Create(size, scale, heights, Method);
    Its likely highly that the first release of this will require the TerrainCollider to be setup in code, as the Editor side support hasn't been prioritised yet.
     
  15. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    110
    If you want to skip the world and collision filter setup altogether, you can raycast directly against your terrains collider itself e.g.
    RaycastQueries.RayCollider(positionRay,physicsCollider.ColliderPtr, hit)

    Note that these lower level functions work in the local space of the collider, so the Start and End of the RaycastInput struct (or Ray origin and direction in previews < 0.1.0) need appropriately transformed by the Entity's Translation and Rotation. As would the resulting hit.Position if you needed it in world space.
     
  16. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    787
    StepPhysicsWorld is running in the entity debugger (~3ms) and it runs on all the bullets Another thing that confirms it is that they're moving at all. Since they use PhysicsVelocity they wouldn't move at all otherwise.

    As for PhysicsBulletCollisionSystem:
    It seems to be running (~0.06ms) in the entity debugger.
    I've also added the AlwaysUpdate attribute, and I've set a breakpoint in OnUpdate which always gets triggered, so the jobs are getting scheduled 100%.
    However the jobs Execute methods are only called very rarely. If I let it run for a minute or so then it might get called a few (maybe 1-10) times...

    The collision events are still always showing the collisions perfectly no matter what. It's really just the ICollisionEventsJob and ITriggerEventsJob that are not/randomly working.
     
    lemon222 likes this.
  17. Gaaammmler

    Gaaammmler

    Joined:
    Apr 10, 2018
    Posts:
    11
    First of all thank you for your help steveeHavok and PhilSA,

    i will include the new Raycast, because i only need to check for the terrain.

    One thing i still dont understand is how to override the Method for the caluclation of the 3d Tree to make it as Spatial Hashing. The only 4 SimulationCallbacks Phases explained here, have from the first Callback i can overwrite, the sorting included:(
    Unity.Physics.SimulationCallbacks.Phase.PostCreateDispatchPairs: It has also performed some sorting) Link: https://docs.unity3d.com/Packages/com.unity.physics@0.0/manual/simulation_modification.html

    Maybe im not understanding something here, i hope someone can help me to understand how to overwrite the sorting with the spatialhashing sorting im only need.
     
  18. SebLazyWizard

    SebLazyWizard

    Joined:
    Jun 15, 2018
    Posts:
    10
    How are the friction and damping values applied?
    Are they handled as quadratic or linear drag?
    If the latter is the case, can we make it quadratic drag without fiddling with external forces at run-time?
     
  19. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    110
    Thanks for the details. I need to test on 2019.3.x. Still on 2019.1.x here. There was a bug found recently that might be related to your problem, though if the debug visualisation is working then it shouldn't. Check out: https://forum.unity.com/threads/unity-physics-discussion.646486/page-11#post-4621444
    Can you also make sure the 2d. Events demo are working for you? I'll download the latest 2019.3 editor now as well.
     
    Shinyclef likes this.
  20. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    1,154
    Is there a way currently to hook up your own physics forces on internal iterations so you can modify these custom forces between each individual iteration? It basically would allow all kinds of fancy custom forces you'd want to compute more frequently than broadphase and collisions in general.
     
  21. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    424
    Oh wow! Terrain Collider support is a lot further down the pipeline than I was expecting. Good to know it is BVH-based with an optimized construction code-path. I'm not concerned about Editor side support. The level designer I work with likes to use the tree painter for everything but trees so I have to build a custom conversion solution to support that workflow anyways. DOTS finally lets me get the correct colliders on those "trees". :p

    I am surprised that the heightfield is using 16bit heights rather than bake in the heightscale into floats. I guess I'll just have to wait to see the implementation to figure out the magic reasoning!
     
  22. Srokaaa

    Srokaaa

    Joined:
    Sep 18, 2018
    Posts:
    72
    Unfortunately this is still not working for me, neither collision nor trigger events are raised. As soon as I change one of the colliding bodes Motion Type to Dynamic both Collision and Trigger events are sent. Maybe this is the source of the problem that @dadude123 has in the discussion above.

    Btw. we could really use some hero forum admin splitting this discussion into separate threads because I am getting lost in all what's happening here
     
    lemon222 and steveeHavok like this.
  23. WAYN_Group

    WAYN_Group

    Joined:
    Mar 16, 2019
    Posts:
    62
    Hi,
    To detect the colision of my bullets I moved from raycasting to trigger events. The code is much cleaner but I have one question and one issue.

    Question :
    If I'm not mistaken the trigger sample does not run on the main thread but is not multythreaded either. If so is there a plan to make it "multithreadable" ?

    Issue :
    I have a system that spwan multiple bullets simultaneously in a grid pattern. When spaning a 1x2 or 2x1 grid, no issue. But once I go to 2x2 I have an error in the console comming from the ITriggerEventsJob. It does not prevent the systems to work as expected. The issue also appears only when the bullet are spanwed at the same same position. Tried addiong an epsilon but does not solve the issue. Only making them spawn without overlaping make the error deasapear. It does not reproduce just by adding multiple bullets to the scene from the inspector.

    The error :

    upload_2019-6-8_14-29-29.png

    The code used to spawn the bullets :
    Code (CSharp):
    1. struct GridShotJob : IJobForEachWithEntity<Shot, Magazine, SoundFX,LocalToWorld, GridShot>
    2.         {
    3.             // A command buffer that support parallel writes.
    4.             public EntityCommandBuffer.Concurrent CommandBuffer;
    5.             // Time since the last frame.
    6.             [ReadOnly] public float DeltaTime;
    7.  
    8.             public void Execute(Entity entity, int index, ref Shot shot, ref Magazine magazine, ref SoundFX sfx,
    9.                 [ReadOnly] ref LocalToWorld location, [ReadOnly] ref GridShot gridShot)
    10.             {
    11.                 if(!Shot.IsTriggered(ref shot, DeltaTime)) return;
    12.  
    13.                 if (Magazine.IsMagazineEmpty(ref magazine)) return;
    14.  
    15.                 //Normalize verctor to match drawn gizmos and be independant of scale.
    16.                 float3 normalizedForward = math.normalizesafe(location.Forward);
    17.                 float3 normalizedRight = math.normalizesafe(location.Right);
    18.                 float3 normalizedUp = math.normalizesafe(location.Up);
    19.  
    20.                 float xRange = (float)gridShot.SizeX / 2;
    21.                 float yRange = (float)gridShot.SizeY / 2;
    22.                 for (float x = -xRange; x < xRange; x++)
    23.                 {
    24.                     for (float y = -yRange; y < yRange; y++)
    25.                     {
    26.                         // Create the bullet
    27.                         var instance = CommandBuffer.Instantiate(index, shot.Projectile);
    28.  
    29.                         // Place it at the end of the gun
    30.  
    31.  
    32.                         //CommandBuffer.SetComponent(index, instance, new Translation { Value = location.Position}); // --> Error in that case.
    33.                         CommandBuffer.SetComponent(index, instance, new Translation { Value = location.Position + (normalizedRight * (x * float.Epsilon)) + (normalizedUp * (y * float.Epsilon)) }); // --> Error in that case.
    34.                         //CommandBuffer.SetComponent(index, instance, new Translation { Value = location.Position + (normalizedRight * (x + .5f)) + (normalizedUp * (y + .5f)) }); // --> No error in that case.
    35.                         float3 projectileDirection = (normalizedForward * gridShot.Density) + (normalizedRight * (x + .5f)) + (normalizedUp * (y + .5f));
    36.                         CommandBuffer.SetComponent(index, instance, new Rotation { Value = quaternion.LookRotationSafe(projectileDirection, normalizedUp) });
    37.                         CommandBuffer.SetComponent(index, instance, new LocalToWorld { Value = float4x4.LookAt(location.Position, projectileDirection, normalizedUp) });
    38.  
    39.                         // Save the speed on the projectile to avoid calculating it.
    40.                         CommandBuffer.AddComponent(index, instance, new Speed() { Value = shot.Speed });
    41.  
    42.                         // Make it move forward
    43.                         CommandBuffer.SetComponent(index, instance, new PhysicsVelocity { Linear = (projectileDirection) * shot.Speed });
    44.                     }
    45.                 }
    46.  
    47.  
    48.  
    49.                 SoundFX.PlaySFXAt(ref sfx, location.Position);
    50.             }
    51.  
    52.  
    53.         }
    Attached my project to reproduce :
    0) Open project in Unity 2019.1.5f1
    1) Open the SurvivalShooterScene
    2) Press run
    3) Click on the game window to shoot in any direction.

    EDIT : if you keep shooting you'l gate the same massege with a different index once the bullets start overlaping.
    You'l alslo end up with thi message :
    upload_2019-6-8_18-47-48.png

    I think there is something going on with the fact that I destroy bullets from the event job. Idexes get messed up and end up desychroinized wich make the event defauilt to the first entity instead of the entity that was out of bound.

    I'll try deporting the destruction loigic in another job see if it fix the second error message.

    EDIT2 : simply removed destruction of bullet all together but it did not change a thing...

    EDIT 3 : Adding a job.Complete() after scheduling the job seems to solve both issues. But my understanding is that in that case, the main thread waits for the job to finish making the advatage of the job mute, am I wrong ?
     

    Attached Files:

    Last edited: Jun 8, 2019
  24. thelebaron

    thelebaron

    Joined:
    Jun 2, 2013
    Posts:
    277
    Is it yet possible to ignore a specific collider/s when raycasting? ie when shooting a weapon, to ignore yourself? I saw a discussion about this a few pages back, but I didnt see anything in the recent updates that indicated any changes there.
     
  25. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    110
    This is how damping affects the velocities from Integrator.cs
    Code (CSharp):
    1.                 // Update velocities
    2.                 {
    3.                     // gravity
    4.                     motionVelocity.LinearVelocity += Gravity * motionData.GravityFactor * Timestep;
    5.  
    6.                     // damping
    7.                     motionVelocity.LinearVelocity *= math.clamp(1.0f - motionData.LinearDamping * Timestep, 0.0f, 1.0f);
    8.                     motionVelocity.AngularVelocity *= math.clamp(1.0f - motionData.AngularDamping * Timestep, 0.0f, 1.0f);
    9.                 }
    You can play about with the 'p' value here as a visual aid to how damping kills velocity over time. Damping ranges from 0 to f, where f is the simulation frequency (50hz by default with Unity). Then, if f = 50 then all velocity is damped in a single frame.

    Friction is more complicated and handled in ContactJacobians.cs (ContactJacobian.Solve).
    Code (CSharp):
    1.             // Solve friction
    2.             if (sumImpulses > 0.0f)
    3.             {
    4.                 // Choose friction axes
    5.                 Math.CalculatePerpendicularNormalized(BaseJacobian.Normal, out float3 frictionDir0, out float3 frictionDir1);
    6.  
    7.                 // Calculate impulses for full stop
    8.                 float3 imp;
    9.                 {
    10.                     // Calculate the jacobian dot velocity for each of the friction jacobians
    11.                     float3 extraFrictionDv = jacHeader.HasSurfaceVelocity ? jacHeader.AccessSurfaceVelocity().ExtraFrictionDv : float3.zero;
    12.                     float dv0 = extraFrictionDv.x - BaseContactJacobian.GetJacVelocity(frictionDir0, Friction0, tempVelocityA, tempVelocityB);
    13.                     float dv1 = extraFrictionDv.y - BaseContactJacobian.GetJacVelocity(frictionDir1, Friction1, tempVelocityA, tempVelocityB);
    14.                     float dva = extraFrictionDv.z - math.csum(AngularFriction.AngularA * tempVelocityA.AngularVelocity + AngularFriction.AngularB * tempVelocityB.AngularVelocity);
    15.  
    16.                     // Reassemble the effective mass matrix
    17.                     float3 effectiveMassDiag = new float3(Friction0.EffectiveMass, Friction1.EffectiveMass, AngularFriction.EffectiveMass);
    18.                     float3x3 effectiveMass = JacobianUtilities.BuildSymmetricMatrix(effectiveMassDiag, FrictionEffectiveMassOffDiag);
    19.  
    20.                     // Calculate the impulse
    21.                     imp = math.mul(effectiveMass, new float3(dv0, dv1, dva));
    22.                 }
    23.  
    24.                 // Clip TODO.ma calculate some contact radius and use it to influence balance between linear and angular friction
    25.                 float maxImpulse = sumImpulses * CoefficientOfFriction * stepInput.InvNumSolverIterations;
    26.                 float frictionImpulseSquared = math.lengthsq(imp);
    27.                 imp *= math.min(1.0f, maxImpulse * math.rsqrt(frictionImpulseSquared));
    28.  
    29.                 // Apply impulses
    30.                 ApplyImpulse(imp.x, frictionDir0, Friction0, ref tempVelocityA, ref tempVelocityB);
    31.                 ApplyImpulse(imp.y, frictionDir1, Friction1, ref tempVelocityA, ref tempVelocityB);
    32.  
    33.                 tempVelocityA.ApplyAngularImpulse(imp.z * AngularFriction.AngularA);
    34.                 tempVelocityB.ApplyAngularImpulse(imp.z * AngularFriction.AngularB);
    35.  
    36.                 // Accumulate them
    37.                 Friction0.Impulse += imp.x;
    38.                 Friction1.Impulse += imp.y;
    39.                 AngularFriction.Impulse += imp.z;
    40.             }
    41.  
    42.             // Write back
    43.             velocityA = tempVelocityA;
    44.             velocityB = tempVelocityB;
    45.         }
    We are planning on including the contact friction impulses in collision events so that you can reference them from an ICollisionEventJob
     
  26. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    110
    Not at minute, no. I'd love to hear whay fancy custom forces you have in mind though?
     
  27. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    110
    I'm not sure what you are trying to do here. Can you give me a higher level explanation? Do you want to completely replace the BoundingVolumeHierarchy in general or are you are trying to create your own physics collider type which needs its own mid-phase query layer? If you are trying to create your own collider type then the Terrain Collider code, when released, might help as a reference as it has it uses its own quad tree.
     
  28. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    110
    Its logged but we didn't get to it for the last preview release. The best current workaround is still a custom collector (as the Mouse Pick Behavior is doing).
     
    thelebaron likes this.
  29. Gaaammmler

    Gaaammmler

    Joined:
    Apr 10, 2018
    Posts:
    11
    Yea i want to completly replace the BoundingVolumeHierarchy, for my game i only need a Spatial Hashing approach. I will build the pairs that maybe Collide for the later Calculations, this Collision Groups are now build inside the BoundingVolumeHierarchy but i want it to replace with a Spatial Hashing() approach.

    I hope you understand what i mean, i'm relativ new to the ECS Model and Unity.
    Thank you for helping me.
     
  30. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    1,154
    I'm doing a lot of vehicle physics and would want to ultimately use DOTS for all these sims. Basically why I'd want this is because it would let me do suspension and tire physics for example at 540Hz but do collision checks at 60-120Hz rate. Chassis related things + tire models benefit a lot from these extra iterations and DOTS with Burst can handle the amount of work just fine. It's just pure waste to run the whole physics loop with broadphase and collision resolving at same rate as the internal sim iterations as the collisions don't affect the perceived simulation fidelity the same way (unless you make some crash test simulation). And since physics already has concept of internal iterations, it would be more logical to hook up things there instead of just manually force the iteration counts to 1 and then prevent broadphase from running again on each simulation pass.

    There's also another way to do this and it's to run custom integrator x times on each full simulation pass and just use it to figure out the forces needed to get to same end point on single physics step but it's kinda hack to work around the limitations of the physics engine api.

    Besides the examples I gave here, you can think of the quadratic air drag asked earlier here. If you could add the forces for it on each internal iteration, it would be treated the same way as the linear damping and would be more precise as it gets new data on each run. Of course in case of air drag most games need, this doesn't make much of a difference but used it as example still.
     
    Last edited: Jun 11, 2019
    SamOld and steveeHavok like this.
  31. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    110
    Thanks, that makes sense. Ultimately the number of solver iterations is used in Solver.cs and
    ScheduleSolveJacobiansJobs
    . So to achieve the sort of thing you describe, I would think that we would end up implementing another custom JacobianType and Solve function. More interesting aerodynamics might actually be a little trickier to implement as the current codeflow is centered around body pairs (contacting, overlapping or jointed). That said, there is a default static rigid body created that is used for joints connected to 'the world', rather than other bodies.
    I don't have an update on public access to the Unity.Physics codebase via github yet, but working through and sharing the implementation of this sort of customisation will be much easier once it is available.

    EDIT: It is worth highlighting that unless we can work this sort of change into something like a general
    PhysicsForce: IComponentData
    then your application becomes restricted to working with Unity Physics only. This usecase would likely be well below the Physics Data level and so won't be accessible to any other engine plugins. I've logged this as an issue to be investigated further.
     
    Last edited: Jun 11, 2019
    SamOld and rizu like this.
  32. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    110
    If you want to use all the world queries available within Unity Physics (distance, raycast, collider cast), you are still going to need the BVH constructed. If you don't need the queries and only wish to have rigid bodies bouncing around and use the lower level raycast functions directly, then you can strip out the call
    Broadphase.ScheduleBuildJobs
    in the
    BuildPhysicsWorld
    system. Next you would need to implement your own equivalent of
    Broadphase.ScheduleFindOverlapsJobs
    in the
    StepPhysicsWorld
    system. All that said, I haven't tried out this sort of change and you'll need to change the Unity.Physics code directly. As I mentioned in this link, tweaking the Unity Physics codebase will be much easier when there is public access to the github repo.
     
  33. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    1,154
    Thank you for taking your time to respond. I do get what I ask is bit niche so I totally understand if it's not going to go high on priority list. I mainly wonder about the possibility as Unity Physics has different architecture that it could have room for new more efficient approaches. If this isn't feasible to do on Unity Physics, one could always do separate solvers to hook into Unity Physics like mentioned on the earlier post. I'll investigate the structure myself further once I get more confidence working with DOTS systems, thanks again for all the info. :)
     
    steveeHavok likes this.
  34. Gaaammmler

    Gaaammmler

    Joined:
    Apr 10, 2018
    Posts:
    11
    Thank you for the Reply. So i will wait until the github get public access.
     
  35. SebLazyWizard

    SebLazyWizard

    Joined:
    Jun 15, 2018
    Posts:
    10
    So I would still need to skip the in-built damping and apply external forces in order to archive a more realistic quadratic drag simulation.
    I'm curious why most physics engines use a simplified linear drag approach, even though there's no real relation to the realistic drag equation in fluid dynamics. Is it just for the sake of simplicity or are there other reasons aswell?

    I ran into another problem;
    I tried to set the mass distribution parameters of the script PhysicsBody from within another MonoBehavior script (using OnValidate), but each parameter is private, so it's not possible to do so.
    What I want to archive is to set the mass distribution parameters of a prefab in edit mode.
    Any clues how to do that?
     
  36. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    424
    Just as a heads up, I've been experimenting a little with different broadphases and I can right now safely say that it is going to be extremely difficult to get any performance gain out of spatial hashing over the latest implementation of the BVH, which is crazy fast. But the other main reason is that the other approaches are a little bit crippled by Burst's inability to invoke simd branch instructions, which impacts the core of most AABB test algorithms. That crippled algorithm isn't used in the BVH.

    So if you need an actual physics simulation or queries, I wouldn't even bother since physics simulations are almost always working with sparse data and heavy clustering, or at least to the extent that the BVH wins out performance-wise. Otherwise, I don't know why you are even trying to use Unity.Physics. If you need grids for custom game logic, you can easily query bodies in an AABB.
     
  37. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,357
    So testing out using the new physics for raycasting static objects and trying to figure out how to tie a RaycastHit back to the collider it hit. ColliderKey looks like it might be helpful but it's not obvious what it's intended use is.
     
  38. Shinyclef

    Shinyclef

    Joined:
    Nov 20, 2013
    Posts:
    364
    @snacktime
    Entity e = collisionWorld.Bodies[hit.RigidBodyIndex].Entity;
    Pasted from phone hope its clear. This was from a distance cast but should be the same.

    Edit. Sorry you asked for collider. I'll check when I'm home if it's not similar enough.
     
  39. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,357
    Ya but I'm not using rigidbodies.
     
  40. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,357
    But since I planned on disabling the physics systems most of the time anyways precisely because no rigidbodies, I might as well just use them as they won't cost me anything. But if there is a supported way without rigidbodies I'd prefer that.
     
  41. Shinyclef

    Shinyclef

    Joined:
    Nov 20, 2013
    Posts:
    364
    Oh I see, in this case I'm not sure.
     
  42. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,357
    Ok so I just missed the doc section on collider keys. So those won't help me.
     
  43. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    110
    Ok, this one is fun! First, making the trigger sample "multithreadable" is something on the list for the future. Note that the Trigger events are only processed on a single thread at the minute.

    You have two issues with your setup at the minute. One for
    DestroyOnCollisionSystem 
    and one in conjunction with
    GridShotSystem
    .
    The
    foreachIndex:
    error is happening because the
    DestroyOnCollisionSystem 
    needs to
    UpdateAfter(typeof(StepPhysicsWorld))
    . This error is hit because the trigger event mechanism hasn't been initialised before the first physics step. Thats on us and I'll log an issue to make it cleaner. You might what to specific an appropriate UpdateBefore or After on GridShotSystem as well.

    Fixing that step gives this error instead:
    Code (CSharp):
    1. ArgumentException: The previously scheduled job DestroyOnCollisionSystem:ProjectileDamageJob writes to the NativeArray ProjectileDamageJob.UserJobData.CommandBuffer. You must call JobHandle.Complete() on the job DestroyOnCollisionSystem:ProjectileDamageJob, before you can write to the NativeArray safely.
    This goes away if you add a call to
    m_EntityCommandBufferSystem.AddJobHandleForProducer
    in
    DestroyOnCollisionSystem.OnUpdate
    .

    Was this call missing deliberately?

    In case it was deliberate you could also force a dependancy between the job by adding a
    public JobHandle ScheduledJob
    ; to DestroyOnCollisionSystem. Then have GridShotSystem update after DestroyOnCollisionSystem. And finally, in
    GridShotSystem.OnUpdate
    tweak
    inputDeps = JobHandle.CombineDependencies(inputDeps, World.GetOrCreateSystem<DestroyOnCollisionSystem>().ScheduledJob);
    .
    This works the other way round as well. I don't know what dependancies you want between your systems.
     
    WAYN_Group likes this.
  44. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    110
    Are you calling raycast at the world level? Static objects will still be Rigid Bodies in the world, they just won't have an motion properties. You can raycast directly again a Collider using the lower level static functions in the Unity.Physics.RaycastQueries class.
    The ColliderKey is for getting leaf nodes from a collider hierarchy. Check out the '3. Query AllHitsDistanceTest' sample for an example usecase. The
    DrawLeafCollider 
    function in QueryTester.cs uses the ColliderKey it to highlight the child collider that was hit in the test.
    If this doesn't help can you let me know what you higher level use-case is?
     
  45. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    915
    @steveeHavok I did not have the time to play with the physic system, but I follow this thread and wanted to thank you for your excellent engagement with the community.
     
    Sarkahn, GliderGuy and steveeHavok like this.
  46. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    110
    Most answers to why questions about real-time physics engines drop back to performance. Its always performance vs behavior. Simple is cheap, and often good enough.
    Are you working on something that requires more accurate aerodynamics?
    If someone does want more complexity for any piece of the engine, then at worse the engine should not block them from adding in the complexity for themselves. At best, complexity should be easily swapped in. I will see about adding a buoyancy or wind demo and look at changes needed to the engine if it isn't easy.

    Also, I haven't tried tweaking PhysicsBody myself but does setting
    PhysicsBody.OverrideDefaultMassDistribution
    to true and assigning a new
    MassDistrubution
    struct to
    PhysicsBody.CustomMassDistribution
    not give you want you need?
     
  47. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,357
    Couple of challenges I've hit now with static colliders and raycasting.

    Main one is how to handle dependencies between my jobs doing raycasts against the world and jobs in BuildPhysicsWorld when adding colliders during gameplay. The approach I found is rather cumbersome.

    1. Schedule my raycast jobs from a system that runs after BuildPhysicsWorld.
    2. Combine dependencies on BuildPhysicsWorld.FinalJobHandle.
    3. Complete my jobs from a system that runs before BuildPhysicsWorld.

    The next issue is the main thread time BuildPhysicsWorld takes with a few mesh colliders (1ms+). Somewhere around 200k vertices and a third as many triangles total.

    Now my stuff being static I'm thinking the best solution is simply disable all the physics systems by default and then tick manually and call Complete on their job handles after adding/removing colliders. Does that sound reasonable?
     
  48. SebLazyWizard

    SebLazyWizard

    Joined:
    Jun 15, 2018
    Posts:
    10
    Yea that works like a charm, thanks for clearing that up.
    Code (CSharp):
    1.         var physicsBody = GetComponent<PhysicsBody>();
    2.         physicsBody.OverrideDefaultMassDistribution = true;
    3.  
    4.         var massDistrubution = new MassDistribution();
    5.         massDistrubution.Transform = new RigidTransform(quaternion.identity, new float3(0, 0, 0.1f));
    6.         massDistrubution.InertiaTensor = new float3(0.4f);
    7.  
    8.         physicsBody.CustomMassDistribution = massDistrubution;
     
    steveeHavok likes this.
  49. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,357
    So there are some gotcha's with the manual tick approach. You have to ensure it gets an initial tick the way the logic for determining when to update works. The one I haven't figured out how to deal with quite yet is that system destruction doesn't appear to go in the order of system update. So when BuildPhysicsWorld is destroyed it can't dispose stuff correctly, because my jobs have a dependency still. I can of course work around this but the more hacks I have to use to get to the end goal is making me question if it's worth it at this point.

    That's basically where I am at now. Query performance with burst is good, but not significantly better then the job based Physix raycasting. I do get a significant amount of flexibility with Unity physics. Being able to do raycast calls inline with complex sequential logic is a big win really over the batched approach. Not having to go out to the main thread to tie a hit to what it hit, that's a pretty big win.
     
  50. WAYN_Group

    WAYN_Group

    Joined:
    Mar 16, 2019
    Posts:
    62
    Hi @steveeHavok, thanks for looking at my setup. The missing part about the compand buffer was deliberate as adding it did not change the error and did not prevent the bullets from beeing destroyed. Also I mistakenly thought it was requiered for concurrent command buffer for some reason...
    I'll make the changes you pointed out and think a bit more about dependencies between my job. I idealy would like to have as little explicit dependencies has possible to make things more modular.
     
    steveeHavok likes this.