bepu / bepuphysics2

Pure C# 3D real time physics simulation library, now with a higher version number.
Apache License 2.0
2.25k stars 261 forks source link

I'm confused here,ref manifoldWide from ConvexHullPairTester.cs is not a Vector<Convex4ContactManifoldWide> #257

Closed zyxia closed 1 year ago

zyxia commented 1 year ago

https://github.com/bepu/bepuphysics2/blob/2e182a743c7a4e0bd679d71d434955b2ef117d15/BepuPhysics/CollisionDetection/CollisionTasks/ManifoldCandidateHelper.cs#L326

RossNordby commented 1 year ago

Convex4ContactManifoldWide has an array-of-structures-of-array layout, which means it contains N lanes of contact manifolds where N is Vector<float>.Count. GetOffsetInstance interprets the memory of the struct offset by slotIndex lanes. Since the stride matches up, the first lane of the offset instance gives you a convenient way to access the inner lanes without having to do a bunch of manual indexing.

It's not great for performance- many places you see that being used likely should be replaced by some other form of transposition or gather- but I haven't gotten around to doing all of it.

zyxia commented 1 year ago

Does it mean that,when Vector.Count == 4 ,there is an array of Convex4ContactManifoldWide of length 4 here. however , in the ConvexHullPairTester.cs file, I don't see a place to initialize this array, just a ‘Unsafe.SkipInit’. And in the context of this function,It looks like only need one Convex4ContactManifoldWide.

RossNordby commented 1 year ago

Does it mean that,when Vector.Count == 4 ,there is an array of Convex4ContactManifoldWide of length 4 here

Nope, a single instance of Convex4ContactManifoldWide contains within it a series of Vector<T> which each have Vector<float>.Count lanes. That's what the Wide suffix means. Check out the Vector3Wide type for another example- it's three Vector<float> instances, not three float instances.

See here for more information: https://en.wikipedia.org/wiki/AoS_and_SoA

zyxia commented 1 year ago

I understand, just understand OffsetA1[0]-OffsetA0[0] == OffsetA1[1]-OffsetA0[1], and, GatherScatter.GetFirst(ref Unsafe.Add(ref obj.Depth0, 1)) is approximately equal to obj.Depth1. Thank you for your patient explanation.