public void Execute(ref ModifiableContactHeader manifold, ref ModifiableContactPoint contact)
        {
            Entity entityA = manifold.EntityA;
            Entity entityB = manifold.EntityB;

            ModifyContactJacobians.ModificationType typeA = ModifyContactJacobians.ModificationType.None;
            if (modificationData.HasComponent(entityA))
            {
                typeA = modificationData[entityA].type;
            }

            ModifyContactJacobians.ModificationType typeB = ModifyContactJacobians.ModificationType.None;
            if (modificationData.HasComponent(entityB))
            {
                typeB = modificationData[entityB].type;
            }

            if (typeA == ModifyContactJacobians.ModificationType.SurfaceVelocity || typeB == ModifyContactJacobians.ModificationType.SurfaceVelocity)
            {
                manifold.JacobianFlags |= JacobianFlags.EnableSurfaceVelocity;
            }
            if (typeA == ModifyContactJacobians.ModificationType.InfiniteInertia || typeB == ModifyContactJacobians.ModificationType.InfiniteInertia)
            {
                manifold.JacobianFlags |= JacobianFlags.EnableMassFactors;
            }
        }
            public void Execute(ref ModifiableContactHeader manifold, ref ModifiableContactPoint contact)
            {
                if (!m_Initialized)
                {
                    m_Initialized   = true;
                    CurrentManifold = manifold;
                    NumContacts     = 0;
                }

                // Header verification
                Assert.AreEqual(manifold.CustomTagsA, (byte)0);
                Assert.AreEqual(manifold.CustomTagsB, (byte)0);
                Assert.AreNotEqual(manifold.BodyIndexA, manifold.BodyIndexB);
                Assert.AreApproximatelyEqual(manifold.CoefficientOfFriction, 0.5f, 0.01f);
                Assert.AreApproximatelyEqual(manifold.CoefficientOfRestitution, 0.0f, 0.01f);
                Assert.AreEqual(manifold.ColliderKeyA.Value, ColliderKey.Empty.Value);
                Assert.AreEqual(manifold.ColliderKeyB.Value, ColliderKey.Empty.Value);
                Assert.AreEqual(manifold.EntityA, Bodies[manifold.BodyIndexA].Entity);
                Assert.AreEqual(manifold.EntityB, Bodies[manifold.BodyIndexB].Entity);
                Assert.AreEqual(manifold.JacobianFlags, (JacobianFlags)0);
                Assert.IsFalse(manifold.Modified);
                Assert.AreEqual(manifold.NumContacts, 4);

                NumContacts++;

                // Contact point verification
                Assert.IsTrue(contact.Index == NumContacts - 1);
                Assert.IsFalse(contact.Modified);

                // Save for later verification
                CurrentManifoldNumContacts[0] = CurrentManifold.NumContacts;
                CurrentManifoldNumContacts[1] = NumContacts;
            }
Beispiel #3
0
 public void Execute(ref ModifiableContactHeader manifold, ref ModifiableContactPoint contact)
 {
     if (ConveyorBelts.HasComponent(manifold.EntityA) || ConveyorBelts.HasComponent(manifold.EntityB))
     {
         manifold.JacobianFlags |= JacobianFlags.EnableSurfaceVelocity;
     }
 }
Beispiel #4
0
        public void Execute(ref ModifiableContactHeader manifold, ref ModifiableContactPoint contact)
        {
            Entity entityA = manifold.Entities.EntityA;
            Entity entityB = manifold.Entities.EntityB;

            ModifyContactJacobians.ModificationType typeA = ModifyContactJacobians.ModificationType.None;
            if (modificationData.Exists(entityA))
            {
                typeA = modificationData[entityA].type;
            }

            ModifyContactJacobians.ModificationType typeB = ModifyContactJacobians.ModificationType.None;
            if (modificationData.Exists(entityB))
            {
                typeB = modificationData[entityB].type;
            }

            if (typeA == ModifyContactJacobians.ModificationType.SurfaceVelocity || typeB == ModifyContactJacobians.ModificationType.SurfaceVelocity)
            {
                manifold.JacobianFlags |= JacobianFlags.EnableSurfaceVelocity;
            }
            if (typeA == ModifyContactJacobians.ModificationType.InfiniteInertia || typeB == ModifyContactJacobians.ModificationType.InfiniteInertia)
            {
                manifold.JacobianFlags |= JacobianFlags.EnableMassFactors;
            }

            /*
             * if (typeA == ModifyContactJacobians.ModificationType.ClippedImpulse || typeB == ModifyContactJacobians.ModificationType.ClippedImpulse)
             * {
             *  //manifold.JacobianFlags |= JacobianFlags.EnableMaxImpulse;
             *  manifold.JacobianFlags |= JacobianFlags.
             * }
             */
        }
        public void Execute(ref ModifiableContactHeader contactHeader, ref ModifiableContactPoint contactPoint)
        {
            bool isBodyA = (contactHeader.EntityA == SurfaceEntity);
            bool isBodyB = (contactHeader.EntityB == SurfaceEntity);

            if (isBodyA || isBodyB)
            {
                if (contactPoint.Index == 0)
                {
                    // if we have a mesh surface we can get the surface normal from the plane of the polygon
                    var rbIdx = CollisionWorld.GetRigidBodyIndex(SurfaceEntity);
                    var body  = CollisionWorld.Bodies[rbIdx];
                    if (body.Collider.Value.CollisionType == CollisionType.Composite)
                    {
                        unsafe
                        {
                            body.Collider.Value.GetLeaf(isBodyA ? contactHeader.ColliderKeyA : contactHeader.ColliderKeyB, out ChildCollider leafCollider);
                            if (leafCollider.Collider->Type == ColliderType.Triangle || leafCollider.Collider->Type == ColliderType.Quad)
                            {
                                PolygonCollider *polygonCollider = (PolygonCollider *)leafCollider.Collider;
                                // Potential optimization: If TransformFromChild has no rotation just use body.WorldFromBody.rot
                                // This is likely if you only have a MeshCollider with no hierarchy.
                                quaternion rotation      = math.mul(body.WorldFromBody.rot, leafCollider.TransformFromChild.rot);
                                float3     surfaceNormal = math.rotate(rotation, polygonCollider->Planes[0].Normal);
                                distanceScale        = math.dot(surfaceNormal, contactHeader.Normal);
                                contactHeader.Normal = surfaceNormal;
                            }
                        }
                    }
                }
                contactPoint.Distance *= distanceScale;
            }
        }
Beispiel #6
0
        public void Execute(ref ModifiableContactHeader contactHeader, ref ModifiableContactPoint contactPoint)
        {
            bool isBodyA = (contactHeader.EntityA == SurfaceEntity);
            bool isBodyB = (contactHeader.EntityB == SurfaceEntity);

            if (isBodyA || isBodyB)
            {
                if (contactPoint.Index == 0)
                {
                    var surfaceNormal = SurfaceNormal;

                    // if we have a mesh surface we can get the surface normal from the plane of the polygon
                    var rbIdx = CollisionWorld.GetRigidBodyIndex(SurfaceEntity);
                    var body  = CollisionWorld.Bodies[rbIdx];
                    if (body.Collider.Value.Type == ColliderType.Mesh)
                    {
                        unsafe
                        {
                            var meshColliderPtr = (MeshCollider *)body.Collider.GetUnsafePtr();
                            meshColliderPtr->GetLeaf(isBodyA ? contactHeader.ColliderKeyA : contactHeader.ColliderKeyB, out var leafCollider);
                            var polygonCollider = (PolygonCollider *)leafCollider.Collider;
                            surfaceNormal = math.rotate(body.WorldFromBody.rot, polygonCollider->Planes[0].Normal);
                        }
                    }

                    var newNormal = surfaceNormal;
                    distanceScale = math.dot(newNormal, contactHeader.Normal);

                    contactHeader.Normal = newNormal;
                }
                contactPoint.Distance *= distanceScale;
            }
        }
            public void Execute(ref ModifiableContactHeader header, ref ModifiableContactPoint point)
            {
                float3 x0 = point.Position;
                float3 x1 = header.Normal * point.Distance;

                OutputStreamContext->Arrow(x0, x1, UnityEngine.Color.green);
                if (DisplayContactIndices)
                {
                    OutputStreamContext->Text(point.Index.ToString().ToCharArray(), x0, UnityEngine.Color.red);
                }
            }
Beispiel #8
0
            public void Execute(ref ModifiableContactHeader header, ref ModifiableContactPoint point)
            {
                float3 x0 = point.Position;
                float3 x1 = header.Normal * point.Distance;

                OutputStreamContext->Arrow(x0, x1, Unity.DebugDisplay.ColorIndex.Green);
                if (DisplayContactIndices)
                {
                    // The following line is not Burst-compatible
                    OutputStreamContext->Text(point.Index.ToString().ToCharArray(), x0, UnityEngine.Color.red);
                }
            }
        public void Execute(ref ModifiableContactHeader contactHeader, ref ModifiableContactPoint contactPoint)
        {
            bool bUpdateNormal = (contactHeader.BodyIndexPair.BodyAIndex == m_SurfaceRBIdx) || (contactHeader.BodyIndexPair.BodyBIndex == m_SurfaceRBIdx);

            if (bUpdateNormal && contactPoint.Index == 0)
            {
                var newNormal = m_SurfaceNormal;
                distanceScale = math.dot(newNormal, contactHeader.Normal);

                contactHeader.Normal = newNormal;
            }

            if (bUpdateNormal)
            {
                contactPoint.Distance *= distanceScale;
            }
        }
        public unsafe void Execute(ref ModifiableContactHeader contactHeader,
                                   ref ModifiableContactPoint contactPoint)
        {
            // only store the first contact point of any collision
            //   don't need any others since we only need simple collisions
            if (contactPoint.Index == 0)
            {
                int       idxA = contactHeader.BodyIndexPair.BodyAIndex;
                int       idxB = contactHeader.BodyIndexPair.BodyBIndex;
                RigidBody rbA  = world.Bodies[idxA];
                RigidBody rbB  = world.Bodies[idxB];

                int targetIdx = -1, bulletIdx = -1;
                if ((rbA.Collider->Filter.BelongsTo & targetMask) != 0 &&
                    (rbB.Collider->Filter.BelongsTo & bulletMask) != 0)
                {
                    targetIdx = idxA;
                    bulletIdx = idxB;
                }
                else if ((rbB.Collider->Filter.BelongsTo & targetMask) != 0 &&
                         (rbA.Collider->Filter.BelongsTo & bulletMask) != 0)
                {
                    targetIdx = idxB;
                    bulletIdx = idxA;
                }

                if (targetIdx >= 0 && bulletIdx >= 0)
                {
                    collisions.Add(world.Bodies[targetIdx].Entity,
                                   new CollisionInfo {
                        otherEnt   = world.Bodies[bulletIdx].Entity,
                        contactPos = contactPoint.Position
                    });
                }
            }
        }
            public unsafe static void Execute(ref ContactsJobData <T> jobData, IntPtr additionalData,
                                              IntPtr bufferRangePatchData, ref JobRanges jobRanges, int jobIndex)
            {
                var  reader             = new Havok.Physics.HpBlockStreamReader(jobData.ManifoldStream);
                int *pluginIndexToLocal = jobData.PluginIndexToLocal->Data;

                while (reader.HasItems)
                {
                    var header       = (Havok.Physics.HpManifoldStreamHeader *)reader.ReadPtr <Havok.Physics.HpManifoldStreamHeader>();
                    int numManifolds = header->NumManifolds;

                    int bodyIndexA = pluginIndexToLocal[header->BodyIds.BodyIndexA & 0x00ffffff];
                    int bodyIndexB = pluginIndexToLocal[header->BodyIds.BodyIndexB & 0x00ffffff];

                    var userHeader = new ModifiableContactHeader();
                    userHeader.ContactHeader.BodyPair = new BodyIndexPair
                    {
                        BodyIndexA = bodyIndexA,
                        BodyIndexB = bodyIndexB
                    };
                    userHeader.EntityPair = new EntityPair
                    {
                        EntityA = jobData.Bodies[bodyIndexA].Entity,
                        EntityB = jobData.Bodies[bodyIndexB].Entity
                    };

                    while (numManifolds-- > 0)
                    {
                        var manifold = (Havok.Physics.HpManifold *)reader.ReadPtr <Havok.Physics.HpManifold>();

                        userHeader.ContactHeader.NumContacts = manifold->NumPoints;
                        userHeader.ContactHeader.Normal      = manifold->Normal.xyz;
                        var manifoldCache = manifold->m_CollisionCache;
                        userHeader.ContactHeader.CoefficientOfFriction           = manifoldCache->m_friction.Value;
                        userHeader.ContactHeader.CoefficientOfRestitution        = manifoldCache->m_restitution.Value;
                        userHeader.ContactHeader.ColliderKeys.ColliderKeyA.Value = manifold->m_ShapeKeyA;
                        userHeader.ContactHeader.ColliderKeys.ColliderKeyB.Value = manifold->m_ShapeKeyB;

                        Havok.Physics.HpPerManifoldProperty *cdp = manifoldCache->GetCustomPropertyStorage();
                        userHeader.ContactHeader.BodyCustomTags = cdp->m_bodyTagsPair;
                        userHeader.ContactHeader.JacobianFlags  = (JacobianFlags)cdp->m_jacobianFlags;

                        for (int p = 0; p < manifold->NumPoints; p++)
                        {
                            var userContact = new ModifiableContactPoint
                            {
                                Index        = p,
                                ContactPoint = new ContactPoint
                                {
                                    Position = new float3(manifold->Positions[p * 4 + 0], manifold->Positions[p * 4 + 1], manifold->Positions[p * 4 + 2]),
                                    Distance = manifold->Distances[p],
                                }
                            };

                            jobData.UserJobData.Execute(ref userHeader, ref userContact);

                            if (userContact.Modified)
                            {
                                manifold->Positions[p * 4 + 0] = userContact.ContactPoint.Position.x;
                                manifold->Positions[p * 4 + 1] = userContact.ContactPoint.Position.y;
                                manifold->Positions[p * 4 + 2] = userContact.ContactPoint.Position.z;
                                manifold->Distances[p]         = userContact.ContactPoint.Distance;
                            }

                            if (userHeader.Modified)
                            {
                                manifold->Normal.xyz               = userHeader.ContactHeader.Normal;
                                manifoldCache->m_friction.Value    = userHeader.ContactHeader.CoefficientOfFriction;
                                manifoldCache->m_restitution.Value = userHeader.ContactHeader.CoefficientOfRestitution;
                                cdp->m_jacobianFlags               = (byte)userHeader.ContactHeader.JacobianFlags;

                                if ((cdp->m_jacobianFlags & (byte)JacobianFlags.Disabled) != 0)
                                {
                                    manifold->m_ManifoldType        = 3;      // hknpManifoldType::DISABLED
                                    manifoldCache->m_collisionFlags = 1 << 9; // hknpCollisionFlags::DONT_BUILD_CONTACT_JACOBIANS
                                }
                                else
                                {
                                    // Not disabled, so check for other modifications.

                                    if ((cdp->m_jacobianFlags & (byte)JacobianFlags.EnableMassFactors) != 0)
                                    {
                                        manifold->m_DataFields |= 1 << 1; // hknpManifold::INERTIA_MODIFIED
                                        manifold->m_DataFields &= 0xfb;   // ~CONTAINS_TRIANGLE

                                        var mp = (MassFactors *)UnsafeUtility.AddressOf(ref manifold->m_Scratch[0]);
                                        mp->InverseInertiaFactorA = new float3(1);
                                        mp->InverseMassFactorA    = 1.0f;
                                        mp->InverseInertiaFactorB = new float3(1);
                                        mp->InverseMassFactorB    = 1.0f;
                                    }

                                    if ((cdp->m_jacobianFlags & (byte)JacobianFlags.IsTrigger) != 0)
                                    {
                                        manifold->m_ManifoldType = 1; // hknpManifoldType::TRIGGER
                                    }

                                    if ((cdp->m_jacobianFlags & (byte)JacobianFlags.EnableSurfaceVelocity) != 0)
                                    {
                                        manifoldCache->m_collisionFlags |= 1 << 25; // hknpCollisionFlags::ENABLE_SURFACE_VELOCITY
                                    }

                                    if (userHeader.ContactHeader.CoefficientOfRestitution != 0)
                                    {
                                        manifoldCache->m_collisionFlags |= 1 << 20; // hknpCollisionFlags::ENABLE_RESTITUTION
                                    }
                                }
                            }
                        }
                    }
                }
            }
 public void Execute(ref ModifiableContactHeader header, ref ModifiableContactPoint point)
 {
 }