diff --git a/BepuPhysics/CollisionDetection/ContactConstraintAccessor.cs b/BepuPhysics/CollisionDetection/ContactConstraintAccessor.cs index f56ad19f7..877446a39 100644 --- a/BepuPhysics/CollisionDetection/ContactConstraintAccessor.cs +++ b/BepuPhysics/CollisionDetection/ContactConstraintAccessor.cs @@ -95,11 +95,19 @@ public abstract unsafe void UpdateConstraintForManifold where TPrestepData : IContactViewablePrestepData + { + void CreateViewer(out UnsafeManifoldViewer viewer); } + //Note that the vast majority of the 'work' done by these accessor implementations is just type definitions used to call back into some other functions that need that type knowledge. - public abstract class ContactConstraintAccessor : ContactConstraintAccessor + public abstract class ContactConstraintAccessor : ContactConstraintAccessor + where TPrestepData : struct, IContactViewablePrestepData where TConstraintDescription : IConstraintDescription where TConstraintCache : IPairCacheEntry { @@ -211,9 +219,19 @@ protected static void CopyContactData(ref NonconvexContactManifold manifold, ref targetContact.PenetrationDepth = sourceContact.Depth; } } + + public unsafe override void GetUnsafeManifoldViewer(Solver solver, in ConstraintLocation location, out UnsafeManifoldViewer viewer) + { + ref var batch = ref solver.Sets[location.SetIndex].Batches[location.BatchIndex]; + ref var typeBatch = ref batch.TypeBatches[batch.TypeIndexToTypeBatchIndex[location.TypeId]]; + BundleIndexing.GetBundleIndices(location.IndexInTypeBatch, out var bundleIndex, out var innerIndex); + ref var prestep = ref GatherScatter.GetOffsetInstance(ref Buffer.Get(typeBatch.PrestepData.Memory, bundleIndex), innerIndex); + prestep.CreateViewer(out viewer); + } } - public class ConvexOneBodyAccessor : - ContactConstraintAccessor + public class ConvexOneBodyAccessor : + ContactConstraintAccessor + where TPrestepData : struct, IContactViewablePrestepData where TConstraintDescription : IConvexOneBodyContactConstraintDescription where TConstraintCache : IPairCacheEntry { @@ -228,8 +246,9 @@ public override void UpdateConstraintForManifold : - ContactConstraintAccessor + public class ConvexTwoBodyAccessor : + ContactConstraintAccessor + where TPrestepData : struct, IContactViewablePrestepData where TConstraintDescription : IConvexTwoBodyContactConstraintDescription where TConstraintCache : IPairCacheEntry { @@ -244,8 +263,9 @@ public override void UpdateConstraintForManifold : - ContactConstraintAccessor + public class NonconvexOneBodyAccessor : + ContactConstraintAccessor + where TPrestepData : struct, IContactViewablePrestepData where TConstraintDescription : INonconvexOneBodyContactConstraintDescription where TConstraintCache : IPairCacheEntry { @@ -263,8 +283,9 @@ public override void UpdateConstraintForManifold : - ContactConstraintAccessor + public class NonconvexTwoBodyAccessor : + ContactConstraintAccessor + where TPrestepData : struct, IContactViewablePrestepData where TConstraintDescription : INonconvexTwoBodyContactConstraintDescription where TConstraintCache : IPairCacheEntry { diff --git a/BepuPhysics/CollisionDetection/NarrowPhase.cs b/BepuPhysics/CollisionDetection/NarrowPhase.cs index 33ebe434b..27012c837 100644 --- a/BepuPhysics/CollisionDetection/NarrowPhase.cs +++ b/BepuPhysics/CollisionDetection/NarrowPhase.cs @@ -125,6 +125,18 @@ protected NarrowPhase() flushWorkerLoop = FlushWorkerLoop; } + /// + /// Gets an unsafe pointer to the solver's prestep data representing a contact manifold. + /// + /// Constraint handle of a contact manifold constraint to view. + /// Unsafe manifold viewer for the requested pair. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void GetUnsafeManifoldViewer(int constraintHandle, out UnsafeManifoldViewer viewer) + { + ref var location = ref Solver.HandleToConstraint[constraintHandle]; + contactConstraintAccessors[location.TypeId].GetUnsafeManifoldViewer(Solver, location, out viewer); + } + public void Prepare(float dt, IThreadDispatcher threadDispatcher = null) { timestepDuration = dt; @@ -137,8 +149,7 @@ public void Prepare(float dt, IThreadDispatcher threadDispatcher = null) protected abstract void OnPreflush(IThreadDispatcher threadDispatcher, bool deterministic); protected abstract void OnPostflush(IThreadDispatcher threadDispatcher); - - bool deterministic; + int flushJobIndex; QuickList flushJobs; IThreadDispatcher threadDispatcher; diff --git a/BepuPhysics/CollisionDetection/UnsafeManifoldViewer.cs b/BepuPhysics/CollisionDetection/UnsafeManifoldViewer.cs new file mode 100644 index 000000000..a7644f36a --- /dev/null +++ b/BepuPhysics/CollisionDetection/UnsafeManifoldViewer.cs @@ -0,0 +1,276 @@ +using BepuPhysics.Constraints; +using BepuUtilities; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Text; + +namespace BepuPhysics.CollisionDetection +{ + /// + /// Data associated with a single contact in a contact manifold. + /// + public struct ContactData + { + /// + /// Offset from the center of body A to the contact. + /// + public Vector3 OffsetA; + /// + /// Normal of the contact surface. + /// + public Vector3 Normal; + /// + /// Penetration depth at the contact location. + /// + public float Depth; + } + + + /// + /// Data shared across an entire contact manifold. + /// + public struct ManifoldData + { + public float FrictionCoefficient; + public SpringSettings SpringSettings; + public float MaximumRecoveryVelocity; + } + + /// + /// Raw data bundle shared across an entire contact manifold. + /// + public struct ManifoldDataWide + { + public Vector FrictionCoefficient; + public SpringSettingsWide SpringSettings; + public Vector MaximumRecoveryVelocity; + } + + + /// + /// Accesses existing contact data in the solver. + /// Movement of memory in the solver may invalidate this view and result in access violations; do not continue to use an instance if anything changes in the solver during its lifespan. + /// + public unsafe struct UnsafeManifoldViewer + { + byte* offsetABase; + byte* normalBase; + byte* depthBase; + byte* common; + int offsetDepthStride; + int normalStride; + + int contactCount; + bool convex; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal UnsafeManifoldViewer(int contactCount, bool convex, void* common, void* offsetABase, int offsetDepthStride, void* normalBase, int normalStride, void* depthBase) + { + this.offsetABase = (byte*)offsetABase; + this.normalBase = (byte*)normalBase; + this.depthBase = (byte*)depthBase; + this.common = (byte*)common; + this.offsetDepthStride = offsetDepthStride; + this.normalStride = normalStride; + + this.contactCount = contactCount; + this.convex = convex; + } + + /// + /// Gets the number of contacts in the manifold. + /// + public int ContactCount => contactCount; + + /// + /// Gets whether this manifold is convex. Convex manifolds share the same normal for every contact; nonconvex manifolds do not. + /// + public bool Convex => convex; + + /// + /// Gets or sets the contact data at the given index in the manifold. + /// + /// Index of the contact to access. + /// Contact data at the given index in the manifold. + public ContactData this[int index] + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + Debug.Assert(index >= 0 && index < contactCount, "Index must be within the contact count."); + ContactData toReturn; + GetOffsetA(index, out toReturn.OffsetA); + GetNormal(index, out toReturn.Normal); + toReturn.Depth = GetDepth(index); + return toReturn; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + set + { + Debug.Assert(index >= 0 && index < contactCount, "Index must be within the contact count."); + SetOffsetA(index, value.OffsetA); + SetNormal(index, value.Normal); + GetDepth(index) = value.Depth; + } + } + + /// + /// Gets a reference to the offset bundle in the solver prestep data. + /// + /// Contact index to access. + /// Reference to a contact's offset bundle in the solver prestep data. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ref Vector3Wide GetOffsetAWide(int index) + { + Debug.Assert(index >= 0 && index < contactCount, "Index must be within the contact count."); + return ref Unsafe.AsRef(offsetABase + offsetDepthStride * index); + } + + /// + /// Gets the offset from body A to the contact for the given contact index. + /// + /// Index of the contact to access. + /// Offset from body A to the contact location. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void GetOffsetA(int index, out Vector3 offsetA) + { + Vector3Wide.ReadFirst(GetOffsetAWide(index), out offsetA); + } + + /// + /// Sets the offset from body A to the contact for the given contact index. + /// + /// Index of the contact to access. + /// New offset from body A to the contact location. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SetOffsetA(int index, in Vector3 offsetA) + { + Vector3Wide.WriteFirst(offsetA, ref GetOffsetAWide(index)); + } + + /// + /// Gets a reference to the normal bundle in the solver prestep data. + /// + /// Contact index to access. + /// Reference to a contact's normal bundle in the solver prestep data. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ref Vector3Wide GetNormalWide(int index) + { + Debug.Assert(index >= 0 && index < contactCount, "Index must be within the contact count."); + return ref Unsafe.AsRef(normalBase + normalStride * index); + } + + /// + /// Gets the normal for the given contact index. + /// + /// Index of the contact to access. + /// Normal for the accessed contact. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void GetNormal(int index, out Vector3 normal) + { + Vector3Wide.ReadFirst(GetNormalWide(index), out normal); + } + + /// + /// Sets the normal for the given contact index. + /// + /// Index of the contact to access. + /// New normal for the accessed contact. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SetNormal(int index, in Vector3 normal) + { + Vector3Wide.WriteFirst(normal, ref GetNormalWide(index)); + } + + /// + /// Gets a reference to the depth in the solver prestep data. + /// + /// Contact index to access. + /// Reference to a contact's depth in the solver prestep data. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ref float GetDepth(int index) + { + Debug.Assert(index >= 0 && index < contactCount, "Index must be within the contact count."); + return ref Unsafe.AsRef(depthBase + offsetDepthStride * index); + } + + /// + /// Gets a reference to the depth bundle in the solver prestep data. + /// + /// Reference to a contact's depth bundle in the solver prestep data. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ref ManifoldDataWide GetManifoldDataWide() + { + //Note that this assumes the memory layout matches the ManifoldDataWide struct. + return ref Unsafe.AsRef(common); + } + + /// + /// Gets the data shared across the entire manifold. + /// + /// Depth for the accessed contact. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void GetManifoldData(out ManifoldData manifoldData) + { + ref var wide = ref GetManifoldDataWide(); + manifoldData.FrictionCoefficient = wide.FrictionCoefficient[0]; + SpringSettingsWide.ReadFirst(wide.SpringSettings, out manifoldData.SpringSettings); + manifoldData.MaximumRecoveryVelocity = wide.MaximumRecoveryVelocity[0]; + } + + /// + /// Sets the data shared across the entire manifold. + /// + /// New manifold data. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SetManifoldData(in ManifoldData manifoldData) + { + ref var wide = ref GetManifoldDataWide(); + GatherScatter.GetFirst(ref wide.FrictionCoefficient) = manifoldData.FrictionCoefficient; + SpringSettingsWide.WriteFirst(manifoldData.SpringSettings, ref wide.SpringSettings); + GatherScatter.GetFirst(ref wide.MaximumRecoveryVelocity) = manifoldData.MaximumRecoveryVelocity; + } + + /// + /// Gets a reference to the friction coefficient for the manifold. + /// + public ref float FrictionCoefficient + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return ref GatherScatter.GetFirst(ref GetManifoldDataWide().FrictionCoefficient); } + } + + /// + /// Gets a reference to the maximum recovery velocity for the manifold. + /// + public ref float MaximumRecoveryVelocity + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return ref GatherScatter.GetFirst(ref GetManifoldDataWide().MaximumRecoveryVelocity); } + } + + /// + /// Gets the spring settings for the manifold. + /// + /// Spring settings for the manifold. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void GetSpringSettings(out SpringSettings springSettings) + { + SpringSettingsWide.ReadFirst(GetManifoldDataWide().SpringSettings, out springSettings); + } + + /// + /// Sets the spring settings for the manifold. + /// + /// Spring settings for the manifold. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SetSpringSettings(in SpringSettings springSettings) + { + SpringSettingsWide.WriteFirst(springSettings, ref GetManifoldDataWide().SpringSettings); + } + + } +} diff --git a/BepuPhysics/Constraints/Contact/ContactConvexTypes.cs b/BepuPhysics/Constraints/Contact/ContactConvexTypes.cs index 76a9af02e..c0b0d3775 100644 --- a/BepuPhysics/Constraints/Contact/ContactConvexTypes.cs +++ b/BepuPhysics/Constraints/Contact/ContactConvexTypes.cs @@ -182,7 +182,7 @@ public int ConstraintTypeId } - public struct Contact1OneBodyPrestepData + public struct Contact1OneBodyPrestepData : IContactViewablePrestepData { //NOTE: Prestep data memory layout is relied upon by the constraint description for marginally more efficient setting and getting. //If you modify this layout, be sure to update the associated ContactManifold4Constraint. @@ -190,12 +190,23 @@ public struct Contact1OneBodyPrestepData public Vector3Wide OffsetA0; public Vector PenetrationDepth0; public Vector3Wide OffsetB; - public Vector FrictionCoefficient; //In a convex manifold, all contacts share the same normal and tangents. public Vector3Wide Normal; + //Note that the positioning of the friction coefficient, spring settings, and maximum recovery velocity are used by the UnsafeManifoldViewer. Careful about moving these. + public Vector FrictionCoefficient; //All contacts also share the spring settings. public SpringSettingsWide SpringSettings; public Vector MaximumRecoveryVelocity; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(1, true, + Unsafe.AsPointer(ref FrictionCoefficient), + Unsafe.AsPointer(ref OffsetA0), Unsafe.SizeOf() + Unsafe.SizeOf>(), + Unsafe.AsPointer(ref Normal), 0, + Unsafe.AsPointer(ref PenetrationDepth0)); + } } public unsafe struct Contact1OneBodyProjection @@ -338,7 +349,7 @@ public int ConstraintTypeId } - public struct Contact2OneBodyPrestepData + public struct Contact2OneBodyPrestepData : IContactViewablePrestepData { //NOTE: Prestep data memory layout is relied upon by the constraint description for marginally more efficient setting and getting. //If you modify this layout, be sure to update the associated ContactManifold4Constraint. @@ -348,12 +359,23 @@ public struct Contact2OneBodyPrestepData public Vector3Wide OffsetA1; public Vector PenetrationDepth1; public Vector3Wide OffsetB; - public Vector FrictionCoefficient; //In a convex manifold, all contacts share the same normal and tangents. public Vector3Wide Normal; + //Note that the positioning of the friction coefficient, spring settings, and maximum recovery velocity are used by the UnsafeManifoldViewer. Careful about moving these. + public Vector FrictionCoefficient; //All contacts also share the spring settings. public SpringSettingsWide SpringSettings; public Vector MaximumRecoveryVelocity; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(2, true, + Unsafe.AsPointer(ref FrictionCoefficient), + Unsafe.AsPointer(ref OffsetA0), Unsafe.SizeOf() + Unsafe.SizeOf>(), + Unsafe.AsPointer(ref Normal), 0, + Unsafe.AsPointer(ref PenetrationDepth0)); + } } public unsafe struct Contact2OneBodyProjection @@ -510,7 +532,7 @@ public int ConstraintTypeId } - public struct Contact3OneBodyPrestepData + public struct Contact3OneBodyPrestepData : IContactViewablePrestepData { //NOTE: Prestep data memory layout is relied upon by the constraint description for marginally more efficient setting and getting. //If you modify this layout, be sure to update the associated ContactManifold4Constraint. @@ -522,12 +544,23 @@ public struct Contact3OneBodyPrestepData public Vector3Wide OffsetA2; public Vector PenetrationDepth2; public Vector3Wide OffsetB; - public Vector FrictionCoefficient; //In a convex manifold, all contacts share the same normal and tangents. public Vector3Wide Normal; + //Note that the positioning of the friction coefficient, spring settings, and maximum recovery velocity are used by the UnsafeManifoldViewer. Careful about moving these. + public Vector FrictionCoefficient; //All contacts also share the spring settings. public SpringSettingsWide SpringSettings; public Vector MaximumRecoveryVelocity; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(3, true, + Unsafe.AsPointer(ref FrictionCoefficient), + Unsafe.AsPointer(ref OffsetA0), Unsafe.SizeOf() + Unsafe.SizeOf>(), + Unsafe.AsPointer(ref Normal), 0, + Unsafe.AsPointer(ref PenetrationDepth0)); + } } public unsafe struct Contact3OneBodyProjection @@ -697,7 +730,7 @@ public int ConstraintTypeId } - public struct Contact4OneBodyPrestepData + public struct Contact4OneBodyPrestepData : IContactViewablePrestepData { //NOTE: Prestep data memory layout is relied upon by the constraint description for marginally more efficient setting and getting. //If you modify this layout, be sure to update the associated ContactManifold4Constraint. @@ -711,12 +744,23 @@ public struct Contact4OneBodyPrestepData public Vector3Wide OffsetA3; public Vector PenetrationDepth3; public Vector3Wide OffsetB; - public Vector FrictionCoefficient; //In a convex manifold, all contacts share the same normal and tangents. public Vector3Wide Normal; + //Note that the positioning of the friction coefficient, spring settings, and maximum recovery velocity are used by the UnsafeManifoldViewer. Careful about moving these. + public Vector FrictionCoefficient; //All contacts also share the spring settings. public SpringSettingsWide SpringSettings; public Vector MaximumRecoveryVelocity; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(4, true, + Unsafe.AsPointer(ref FrictionCoefficient), + Unsafe.AsPointer(ref OffsetA0), Unsafe.SizeOf() + Unsafe.SizeOf>(), + Unsafe.AsPointer(ref Normal), 0, + Unsafe.AsPointer(ref PenetrationDepth0)); + } } public unsafe struct Contact4OneBodyProjection @@ -880,7 +924,7 @@ public int ConstraintTypeId } - public struct Contact1PrestepData + public struct Contact1PrestepData : IContactViewablePrestepData { //NOTE: Prestep data memory layout is relied upon by the constraint description for marginally more efficient setting and getting. //If you modify this layout, be sure to update the associated ContactManifold4Constraint. @@ -888,12 +932,23 @@ public struct Contact1PrestepData public Vector3Wide OffsetA0; public Vector PenetrationDepth0; public Vector3Wide OffsetB; - public Vector FrictionCoefficient; //In a convex manifold, all contacts share the same normal and tangents. public Vector3Wide Normal; + //Note that the positioning of the friction coefficient, spring settings, and maximum recovery velocity are used by the UnsafeManifoldViewer. Careful about moving these. + public Vector FrictionCoefficient; //All contacts also share the spring settings. public SpringSettingsWide SpringSettings; public Vector MaximumRecoveryVelocity; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(1, true, + Unsafe.AsPointer(ref FrictionCoefficient), + Unsafe.AsPointer(ref OffsetA0), Unsafe.SizeOf() + Unsafe.SizeOf>(), + Unsafe.AsPointer(ref Normal), 0, + Unsafe.AsPointer(ref PenetrationDepth0)); + } } public unsafe struct Contact1Projection @@ -1039,7 +1094,7 @@ public int ConstraintTypeId } - public struct Contact2PrestepData + public struct Contact2PrestepData : IContactViewablePrestepData { //NOTE: Prestep data memory layout is relied upon by the constraint description for marginally more efficient setting and getting. //If you modify this layout, be sure to update the associated ContactManifold4Constraint. @@ -1049,12 +1104,23 @@ public struct Contact2PrestepData public Vector3Wide OffsetA1; public Vector PenetrationDepth1; public Vector3Wide OffsetB; - public Vector FrictionCoefficient; //In a convex manifold, all contacts share the same normal and tangents. public Vector3Wide Normal; + //Note that the positioning of the friction coefficient, spring settings, and maximum recovery velocity are used by the UnsafeManifoldViewer. Careful about moving these. + public Vector FrictionCoefficient; //All contacts also share the spring settings. public SpringSettingsWide SpringSettings; public Vector MaximumRecoveryVelocity; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(2, true, + Unsafe.AsPointer(ref FrictionCoefficient), + Unsafe.AsPointer(ref OffsetA0), Unsafe.SizeOf() + Unsafe.SizeOf>(), + Unsafe.AsPointer(ref Normal), 0, + Unsafe.AsPointer(ref PenetrationDepth0)); + } } public unsafe struct Contact2Projection @@ -1214,7 +1280,7 @@ public int ConstraintTypeId } - public struct Contact3PrestepData + public struct Contact3PrestepData : IContactViewablePrestepData { //NOTE: Prestep data memory layout is relied upon by the constraint description for marginally more efficient setting and getting. //If you modify this layout, be sure to update the associated ContactManifold4Constraint. @@ -1226,12 +1292,23 @@ public struct Contact3PrestepData public Vector3Wide OffsetA2; public Vector PenetrationDepth2; public Vector3Wide OffsetB; - public Vector FrictionCoefficient; //In a convex manifold, all contacts share the same normal and tangents. public Vector3Wide Normal; + //Note that the positioning of the friction coefficient, spring settings, and maximum recovery velocity are used by the UnsafeManifoldViewer. Careful about moving these. + public Vector FrictionCoefficient; //All contacts also share the spring settings. public SpringSettingsWide SpringSettings; public Vector MaximumRecoveryVelocity; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(3, true, + Unsafe.AsPointer(ref FrictionCoefficient), + Unsafe.AsPointer(ref OffsetA0), Unsafe.SizeOf() + Unsafe.SizeOf>(), + Unsafe.AsPointer(ref Normal), 0, + Unsafe.AsPointer(ref PenetrationDepth0)); + } } public unsafe struct Contact3Projection @@ -1404,7 +1481,7 @@ public int ConstraintTypeId } - public struct Contact4PrestepData + public struct Contact4PrestepData : IContactViewablePrestepData { //NOTE: Prestep data memory layout is relied upon by the constraint description for marginally more efficient setting and getting. //If you modify this layout, be sure to update the associated ContactManifold4Constraint. @@ -1418,12 +1495,23 @@ public struct Contact4PrestepData public Vector3Wide OffsetA3; public Vector PenetrationDepth3; public Vector3Wide OffsetB; - public Vector FrictionCoefficient; //In a convex manifold, all contacts share the same normal and tangents. public Vector3Wide Normal; + //Note that the positioning of the friction coefficient, spring settings, and maximum recovery velocity are used by the UnsafeManifoldViewer. Careful about moving these. + public Vector FrictionCoefficient; //All contacts also share the spring settings. public SpringSettingsWide SpringSettings; public Vector MaximumRecoveryVelocity; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(4, true, + Unsafe.AsPointer(ref FrictionCoefficient), + Unsafe.AsPointer(ref OffsetA0), Unsafe.SizeOf() + Unsafe.SizeOf>(), + Unsafe.AsPointer(ref Normal), 0, + Unsafe.AsPointer(ref PenetrationDepth0)); + } } public unsafe struct Contact4Projection diff --git a/BepuPhysics/Constraints/Contact/ContactConvexTypes.tt b/BepuPhysics/Constraints/Contact/ContactConvexTypes.tt index 9f839f603..235dc834c 100644 --- a/BepuPhysics/Constraints/Contact/ContactConvexTypes.tt +++ b/BepuPhysics/Constraints/Contact/ContactConvexTypes.tt @@ -147,7 +147,7 @@ for (int i = 0; i < contactCount; ++i) } - public struct Contact<#= contactCount #><#=suffix#>PrestepData + public struct Contact<#= contactCount #><#=suffix#>PrestepData : IContactViewablePrestepData<#=suffix#>PrestepData> { //NOTE: Prestep data memory layout is relied upon by the constraint description for marginally more efficient setting and getting. //If you modify this layout, be sure to update the associated ContactManifold4Constraint. @@ -157,12 +157,23 @@ for (int i = 0; i < contactCount; ++i) public Vector PenetrationDepth<#=i#>; <#}#> public Vector3Wide OffsetB; - public Vector FrictionCoefficient; //In a convex manifold, all contacts share the same normal and tangents. public Vector3Wide Normal; + //Note that the positioning of the friction coefficient, spring settings, and maximum recovery velocity are used by the UnsafeManifoldViewer. Careful about moving these. + public Vector FrictionCoefficient; //All contacts also share the spring settings. public SpringSettingsWide SpringSettings; public Vector MaximumRecoveryVelocity; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(<#=contactCount#>, true, + Unsafe.AsPointer(ref FrictionCoefficient), + Unsafe.AsPointer(ref OffsetA0), Unsafe.SizeOf() + Unsafe.SizeOf>(), + Unsafe.AsPointer(ref Normal), 0, + Unsafe.AsPointer(ref PenetrationDepth0)); + } } public unsafe struct Contact<#= contactCount #><#=suffix#>Projection diff --git a/BepuPhysics/Constraints/Contact/ContactNonconvexTypes.cs b/BepuPhysics/Constraints/Contact/ContactNonconvexTypes.cs index ad1f8e4ce..f68b0566a 100644 --- a/BepuPhysics/Constraints/Contact/ContactNonconvexTypes.cs +++ b/BepuPhysics/Constraints/Contact/ContactNonconvexTypes.cs @@ -53,7 +53,9 @@ public int ConstraintTypeId } - public struct Contact2NonconvexPrestepData : INonconvexTwoBodyContactPrestepWide + public struct Contact2NonconvexPrestepData : + INonconvexTwoBodyContactPrestepWide, + IContactViewablePrestepData { //Note that this layout is defined by the execution order in the prestep. The function accesses it sequentially to ensure the prefetcher can do its job. public NonconvexTwoBodyContactPrestepCommon Common; @@ -71,6 +73,16 @@ public ref NonconvexPrestepData GetFirstContact(ref Contact2NonconvexPrestepData { return ref prestep.Contact0; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(2, false, + Unsafe.AsPointer(ref Common.FrictionCoefficient), + Unsafe.AsPointer(ref Contact0.Offset), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Normal), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Depth)); + } } public struct Contact2NonconvexAccumulatedImpulses @@ -159,7 +171,9 @@ public int ConstraintTypeId } - public struct Contact2NonconvexOneBodyPrestepData : INonconvexOneBodyContactPrestepWide + public struct Contact2NonconvexOneBodyPrestepData : + INonconvexOneBodyContactPrestepWide, + IContactViewablePrestepData { //Note that this layout is defined by the execution order in the prestep. The function accesses it sequentially to ensure the prefetcher can do its job. public NonconvexOneBodyContactPrestepCommon Common; @@ -176,6 +190,16 @@ public ref NonconvexOneBodyContactPrestepCommon GetCommonProperties(ref Contact2 public ref NonconvexPrestepData GetFirstContact(ref Contact2NonconvexOneBodyPrestepData prestep) { return ref prestep.Contact0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(2, false, + Unsafe.AsPointer(ref Common.FrictionCoefficient), + Unsafe.AsPointer(ref Contact0.Offset), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Normal), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Depth)); } } @@ -262,7 +286,9 @@ public int ConstraintTypeId } - public struct Contact3NonconvexPrestepData : INonconvexTwoBodyContactPrestepWide + public struct Contact3NonconvexPrestepData : + INonconvexTwoBodyContactPrestepWide, + IContactViewablePrestepData { //Note that this layout is defined by the execution order in the prestep. The function accesses it sequentially to ensure the prefetcher can do its job. public NonconvexTwoBodyContactPrestepCommon Common; @@ -281,6 +307,16 @@ public ref NonconvexPrestepData GetFirstContact(ref Contact3NonconvexPrestepData { return ref prestep.Contact0; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(3, false, + Unsafe.AsPointer(ref Common.FrictionCoefficient), + Unsafe.AsPointer(ref Contact0.Offset), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Normal), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Depth)); + } } public struct Contact3NonconvexAccumulatedImpulses @@ -372,7 +408,9 @@ public int ConstraintTypeId } - public struct Contact3NonconvexOneBodyPrestepData : INonconvexOneBodyContactPrestepWide + public struct Contact3NonconvexOneBodyPrestepData : + INonconvexOneBodyContactPrestepWide, + IContactViewablePrestepData { //Note that this layout is defined by the execution order in the prestep. The function accesses it sequentially to ensure the prefetcher can do its job. public NonconvexOneBodyContactPrestepCommon Common; @@ -390,6 +428,16 @@ public ref NonconvexOneBodyContactPrestepCommon GetCommonProperties(ref Contact3 public ref NonconvexPrestepData GetFirstContact(ref Contact3NonconvexOneBodyPrestepData prestep) { return ref prestep.Contact0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(3, false, + Unsafe.AsPointer(ref Common.FrictionCoefficient), + Unsafe.AsPointer(ref Contact0.Offset), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Normal), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Depth)); } } @@ -478,7 +526,9 @@ public int ConstraintTypeId } - public struct Contact4NonconvexPrestepData : INonconvexTwoBodyContactPrestepWide + public struct Contact4NonconvexPrestepData : + INonconvexTwoBodyContactPrestepWide, + IContactViewablePrestepData { //Note that this layout is defined by the execution order in the prestep. The function accesses it sequentially to ensure the prefetcher can do its job. public NonconvexTwoBodyContactPrestepCommon Common; @@ -498,6 +548,16 @@ public ref NonconvexPrestepData GetFirstContact(ref Contact4NonconvexPrestepData { return ref prestep.Contact0; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(4, false, + Unsafe.AsPointer(ref Common.FrictionCoefficient), + Unsafe.AsPointer(ref Contact0.Offset), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Normal), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Depth)); + } } public struct Contact4NonconvexAccumulatedImpulses @@ -592,7 +652,9 @@ public int ConstraintTypeId } - public struct Contact4NonconvexOneBodyPrestepData : INonconvexOneBodyContactPrestepWide + public struct Contact4NonconvexOneBodyPrestepData : + INonconvexOneBodyContactPrestepWide, + IContactViewablePrestepData { //Note that this layout is defined by the execution order in the prestep. The function accesses it sequentially to ensure the prefetcher can do its job. public NonconvexOneBodyContactPrestepCommon Common; @@ -611,6 +673,16 @@ public ref NonconvexOneBodyContactPrestepCommon GetCommonProperties(ref Contact4 public ref NonconvexPrestepData GetFirstContact(ref Contact4NonconvexOneBodyPrestepData prestep) { return ref prestep.Contact0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(4, false, + Unsafe.AsPointer(ref Common.FrictionCoefficient), + Unsafe.AsPointer(ref Contact0.Offset), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Normal), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Depth)); } } @@ -701,7 +773,9 @@ public int ConstraintTypeId } - public struct Contact5NonconvexPrestepData : INonconvexTwoBodyContactPrestepWide + public struct Contact5NonconvexPrestepData : + INonconvexTwoBodyContactPrestepWide, + IContactViewablePrestepData { //Note that this layout is defined by the execution order in the prestep. The function accesses it sequentially to ensure the prefetcher can do its job. public NonconvexTwoBodyContactPrestepCommon Common; @@ -722,6 +796,16 @@ public ref NonconvexPrestepData GetFirstContact(ref Contact5NonconvexPrestepData { return ref prestep.Contact0; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(5, false, + Unsafe.AsPointer(ref Common.FrictionCoefficient), + Unsafe.AsPointer(ref Contact0.Offset), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Normal), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Depth)); + } } public struct Contact5NonconvexAccumulatedImpulses @@ -819,7 +903,9 @@ public int ConstraintTypeId } - public struct Contact5NonconvexOneBodyPrestepData : INonconvexOneBodyContactPrestepWide + public struct Contact5NonconvexOneBodyPrestepData : + INonconvexOneBodyContactPrestepWide, + IContactViewablePrestepData { //Note that this layout is defined by the execution order in the prestep. The function accesses it sequentially to ensure the prefetcher can do its job. public NonconvexOneBodyContactPrestepCommon Common; @@ -839,6 +925,16 @@ public ref NonconvexOneBodyContactPrestepCommon GetCommonProperties(ref Contact5 public ref NonconvexPrestepData GetFirstContact(ref Contact5NonconvexOneBodyPrestepData prestep) { return ref prestep.Contact0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(5, false, + Unsafe.AsPointer(ref Common.FrictionCoefficient), + Unsafe.AsPointer(ref Contact0.Offset), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Normal), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Depth)); } } @@ -931,7 +1027,9 @@ public int ConstraintTypeId } - public struct Contact6NonconvexPrestepData : INonconvexTwoBodyContactPrestepWide + public struct Contact6NonconvexPrestepData : + INonconvexTwoBodyContactPrestepWide, + IContactViewablePrestepData { //Note that this layout is defined by the execution order in the prestep. The function accesses it sequentially to ensure the prefetcher can do its job. public NonconvexTwoBodyContactPrestepCommon Common; @@ -953,6 +1051,16 @@ public ref NonconvexPrestepData GetFirstContact(ref Contact6NonconvexPrestepData { return ref prestep.Contact0; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(6, false, + Unsafe.AsPointer(ref Common.FrictionCoefficient), + Unsafe.AsPointer(ref Contact0.Offset), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Normal), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Depth)); + } } public struct Contact6NonconvexAccumulatedImpulses @@ -1053,7 +1161,9 @@ public int ConstraintTypeId } - public struct Contact6NonconvexOneBodyPrestepData : INonconvexOneBodyContactPrestepWide + public struct Contact6NonconvexOneBodyPrestepData : + INonconvexOneBodyContactPrestepWide, + IContactViewablePrestepData { //Note that this layout is defined by the execution order in the prestep. The function accesses it sequentially to ensure the prefetcher can do its job. public NonconvexOneBodyContactPrestepCommon Common; @@ -1074,6 +1184,16 @@ public ref NonconvexOneBodyContactPrestepCommon GetCommonProperties(ref Contact6 public ref NonconvexPrestepData GetFirstContact(ref Contact6NonconvexOneBodyPrestepData prestep) { return ref prestep.Contact0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(6, false, + Unsafe.AsPointer(ref Common.FrictionCoefficient), + Unsafe.AsPointer(ref Contact0.Offset), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Normal), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Depth)); } } @@ -1168,7 +1288,9 @@ public int ConstraintTypeId } - public struct Contact7NonconvexPrestepData : INonconvexTwoBodyContactPrestepWide + public struct Contact7NonconvexPrestepData : + INonconvexTwoBodyContactPrestepWide, + IContactViewablePrestepData { //Note that this layout is defined by the execution order in the prestep. The function accesses it sequentially to ensure the prefetcher can do its job. public NonconvexTwoBodyContactPrestepCommon Common; @@ -1191,6 +1313,16 @@ public ref NonconvexPrestepData GetFirstContact(ref Contact7NonconvexPrestepData { return ref prestep.Contact0; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(7, false, + Unsafe.AsPointer(ref Common.FrictionCoefficient), + Unsafe.AsPointer(ref Contact0.Offset), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Normal), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Depth)); + } } public struct Contact7NonconvexAccumulatedImpulses @@ -1294,7 +1426,9 @@ public int ConstraintTypeId } - public struct Contact7NonconvexOneBodyPrestepData : INonconvexOneBodyContactPrestepWide + public struct Contact7NonconvexOneBodyPrestepData : + INonconvexOneBodyContactPrestepWide, + IContactViewablePrestepData { //Note that this layout is defined by the execution order in the prestep. The function accesses it sequentially to ensure the prefetcher can do its job. public NonconvexOneBodyContactPrestepCommon Common; @@ -1316,6 +1450,16 @@ public ref NonconvexOneBodyContactPrestepCommon GetCommonProperties(ref Contact7 public ref NonconvexPrestepData GetFirstContact(ref Contact7NonconvexOneBodyPrestepData prestep) { return ref prestep.Contact0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(7, false, + Unsafe.AsPointer(ref Common.FrictionCoefficient), + Unsafe.AsPointer(ref Contact0.Offset), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Normal), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Depth)); } } @@ -1412,7 +1556,9 @@ public int ConstraintTypeId } - public struct Contact8NonconvexPrestepData : INonconvexTwoBodyContactPrestepWide + public struct Contact8NonconvexPrestepData : + INonconvexTwoBodyContactPrestepWide, + IContactViewablePrestepData { //Note that this layout is defined by the execution order in the prestep. The function accesses it sequentially to ensure the prefetcher can do its job. public NonconvexTwoBodyContactPrestepCommon Common; @@ -1436,6 +1582,16 @@ public ref NonconvexPrestepData GetFirstContact(ref Contact8NonconvexPrestepData { return ref prestep.Contact0; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(8, false, + Unsafe.AsPointer(ref Common.FrictionCoefficient), + Unsafe.AsPointer(ref Contact0.Offset), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Normal), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Depth)); + } } public struct Contact8NonconvexAccumulatedImpulses @@ -1542,7 +1698,9 @@ public int ConstraintTypeId } - public struct Contact8NonconvexOneBodyPrestepData : INonconvexOneBodyContactPrestepWide + public struct Contact8NonconvexOneBodyPrestepData : + INonconvexOneBodyContactPrestepWide, + IContactViewablePrestepData { //Note that this layout is defined by the execution order in the prestep. The function accesses it sequentially to ensure the prefetcher can do its job. public NonconvexOneBodyContactPrestepCommon Common; @@ -1565,6 +1723,16 @@ public ref NonconvexOneBodyContactPrestepCommon GetCommonProperties(ref Contact8 public ref NonconvexPrestepData GetFirstContact(ref Contact8NonconvexOneBodyPrestepData prestep) { return ref prestep.Contact0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(8, false, + Unsafe.AsPointer(ref Common.FrictionCoefficient), + Unsafe.AsPointer(ref Contact0.Offset), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Normal), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Depth)); } } diff --git a/BepuPhysics/Constraints/Contact/ContactNonconvexTypes.tt b/BepuPhysics/Constraints/Contact/ContactNonconvexTypes.tt index 7e39d0917..0bfbcc9b9 100644 --- a/BepuPhysics/Constraints/Contact/ContactNonconvexTypes.tt +++ b/BepuPhysics/Constraints/Contact/ContactNonconvexTypes.tt @@ -66,12 +66,14 @@ for (int i = 0; i < contactCount ; ++i) } - public struct Contact<#= contactCount #>NonconvexPrestepData : INonconvexTwoBodyContactPrestepWideNonconvexPrestepData> + public struct Contact<#= contactCount #>NonconvexPrestepData : + INonconvexTwoBodyContactPrestepWideNonconvexPrestepData>, + IContactViewablePrestepDataNonconvexPrestepData> { //Note that this layout is defined by the execution order in the prestep. The function accesses it sequentially to ensure the prefetcher can do its job. public NonconvexTwoBodyContactPrestepCommon Common; <# -for (int i = 0; i < contactCount ; ++i) +for (int i = 0; i < contactCount; ++i) {#> public NonconvexPrestepData Contact<#=i#>; <#}#> @@ -87,6 +89,16 @@ for (int i = 0; i < contactCount ; ++i) { return ref prestep.Contact0; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(<#=contactCount#>, false, + Unsafe.AsPointer(ref Common.FrictionCoefficient), + Unsafe.AsPointer(ref Contact0.Offset), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Normal), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Depth)); + } } public struct Contact<#= contactCount #>NonconvexAccumulatedImpulses @@ -184,7 +196,9 @@ for (int i = 0; i < contactCount ; ++i) } - public struct Contact<#= contactCount #>NonconvexOneBodyPrestepData : INonconvexOneBodyContactPrestepWideNonconvexOneBodyPrestepData> + public struct Contact<#= contactCount #>NonconvexOneBodyPrestepData : + INonconvexOneBodyContactPrestepWideNonconvexOneBodyPrestepData>, + IContactViewablePrestepDataNonconvexOneBodyPrestepData> { //Note that this layout is defined by the execution order in the prestep. The function accesses it sequentially to ensure the prefetcher can do its job. public NonconvexOneBodyContactPrestepCommon Common; @@ -204,6 +218,16 @@ for (int i = 0; i < contactCount ; ++i) public ref NonconvexPrestepData GetFirstContact(ref Contact<#= contactCount #>NonconvexOneBodyPrestepData prestep) { return ref prestep.Contact0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void CreateViewer(out UnsafeManifoldViewer viewer) + { + viewer = new UnsafeManifoldViewer(<#=contactCount#>, false, + Unsafe.AsPointer(ref Common.FrictionCoefficient), + Unsafe.AsPointer(ref Contact0.Offset), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Normal), Unsafe.SizeOf(), + Unsafe.AsPointer(ref Contact0.Depth)); } } diff --git a/BepuPhysics/Constraints/Contact/IContactConstraintDescription.cs b/BepuPhysics/Constraints/Contact/IContactConstraintDescription.cs index a55375353..6a5c4f679 100644 --- a/BepuPhysics/Constraints/Contact/IContactConstraintDescription.cs +++ b/BepuPhysics/Constraints/Contact/IContactConstraintDescription.cs @@ -31,12 +31,14 @@ public struct NonconvexConstraintContactData public struct NonconvexTwoBodyManifoldConstraintProperties { public Vector3 OffsetB; + //Note that the positioning of the friction coefficient, spring settings, and maximum recovery velocity are used by the UnsafeManifoldViewer. Careful about moving these. public float FrictionCoefficient; public SpringSettings SpringSettings; public float MaximumRecoveryVelocity; } public struct NonconvexOneBodyManifoldConstraintProperties { + //Note that the positioning of the friction coefficient, spring settings, and maximum recovery velocity are used by the UnsafeManifoldViewer. Careful about moving these. public float FrictionCoefficient; public SpringSettings SpringSettings; public float MaximumRecoveryVelocity; diff --git a/BepuPhysics/DefaultTypes.cs b/BepuPhysics/DefaultTypes.cs index fc34a6a89..3211ce4d5 100644 --- a/BepuPhysics/DefaultTypes.cs +++ b/BepuPhysics/DefaultTypes.cs @@ -67,30 +67,30 @@ public static void RegisterDefaults(Solver solver, NarrowPhase narrowPhase) solver.Register(); solver.Register(); - narrowPhase.RegisterContactConstraintAccessor(new NonconvexTwoBodyAccessor()); - narrowPhase.RegisterContactConstraintAccessor(new NonconvexTwoBodyAccessor()); - narrowPhase.RegisterContactConstraintAccessor(new NonconvexTwoBodyAccessor()); - narrowPhase.RegisterContactConstraintAccessor(new NonconvexTwoBodyAccessor()); - narrowPhase.RegisterContactConstraintAccessor(new NonconvexTwoBodyAccessor()); - narrowPhase.RegisterContactConstraintAccessor(new NonconvexTwoBodyAccessor()); - narrowPhase.RegisterContactConstraintAccessor(new NonconvexTwoBodyAccessor()); - - narrowPhase.RegisterContactConstraintAccessor(new NonconvexOneBodyAccessor()); - narrowPhase.RegisterContactConstraintAccessor(new NonconvexOneBodyAccessor()); - narrowPhase.RegisterContactConstraintAccessor(new NonconvexOneBodyAccessor()); - narrowPhase.RegisterContactConstraintAccessor(new NonconvexOneBodyAccessor()); - narrowPhase.RegisterContactConstraintAccessor(new NonconvexOneBodyAccessor()); - narrowPhase.RegisterContactConstraintAccessor(new NonconvexOneBodyAccessor()); - narrowPhase.RegisterContactConstraintAccessor(new NonconvexOneBodyAccessor()); - - narrowPhase.RegisterContactConstraintAccessor(new ConvexTwoBodyAccessor()); - narrowPhase.RegisterContactConstraintAccessor(new ConvexTwoBodyAccessor()); - narrowPhase.RegisterContactConstraintAccessor(new ConvexTwoBodyAccessor()); - narrowPhase.RegisterContactConstraintAccessor(new ConvexTwoBodyAccessor()); - narrowPhase.RegisterContactConstraintAccessor(new ConvexOneBodyAccessor()); - narrowPhase.RegisterContactConstraintAccessor(new ConvexOneBodyAccessor()); - narrowPhase.RegisterContactConstraintAccessor(new ConvexOneBodyAccessor()); - narrowPhase.RegisterContactConstraintAccessor(new ConvexOneBodyAccessor()); + narrowPhase.RegisterContactConstraintAccessor(new NonconvexTwoBodyAccessor()); + narrowPhase.RegisterContactConstraintAccessor(new NonconvexTwoBodyAccessor()); + narrowPhase.RegisterContactConstraintAccessor(new NonconvexTwoBodyAccessor()); + narrowPhase.RegisterContactConstraintAccessor(new NonconvexTwoBodyAccessor()); + narrowPhase.RegisterContactConstraintAccessor(new NonconvexTwoBodyAccessor()); + narrowPhase.RegisterContactConstraintAccessor(new NonconvexTwoBodyAccessor()); + narrowPhase.RegisterContactConstraintAccessor(new NonconvexTwoBodyAccessor()); + + narrowPhase.RegisterContactConstraintAccessor(new NonconvexOneBodyAccessor()); + narrowPhase.RegisterContactConstraintAccessor(new NonconvexOneBodyAccessor()); + narrowPhase.RegisterContactConstraintAccessor(new NonconvexOneBodyAccessor()); + narrowPhase.RegisterContactConstraintAccessor(new NonconvexOneBodyAccessor()); + narrowPhase.RegisterContactConstraintAccessor(new NonconvexOneBodyAccessor()); + narrowPhase.RegisterContactConstraintAccessor(new NonconvexOneBodyAccessor()); + narrowPhase.RegisterContactConstraintAccessor(new NonconvexOneBodyAccessor()); + + narrowPhase.RegisterContactConstraintAccessor(new ConvexTwoBodyAccessor()); + narrowPhase.RegisterContactConstraintAccessor(new ConvexTwoBodyAccessor()); + narrowPhase.RegisterContactConstraintAccessor(new ConvexTwoBodyAccessor()); + narrowPhase.RegisterContactConstraintAccessor(new ConvexTwoBodyAccessor()); + narrowPhase.RegisterContactConstraintAccessor(new ConvexOneBodyAccessor()); + narrowPhase.RegisterContactConstraintAccessor(new ConvexOneBodyAccessor()); + narrowPhase.RegisterContactConstraintAccessor(new ConvexOneBodyAccessor()); + narrowPhase.RegisterContactConstraintAccessor(new ConvexOneBodyAccessor()); } diff --git a/Demos/Program.cs b/Demos/Program.cs index ea0357d74..f05041c66 100644 --- a/Demos/Program.cs +++ b/Demos/Program.cs @@ -26,5 +26,5 @@ static void Main(string[] args) loop.Dispose(); window.Dispose(); } - } + } } \ No newline at end of file