Note that there are some explanatory texts on larger screens.

plurals
  1. POTheoretically-plausible collision sorting algorithm
    primarykey
    data
    text
    <p>Say you have a bunch of objects to check for collision. Say you're an enterprising hobbyist programmer learning collision physics. Say you've heard of this marvelous thing where you sort by X, Y or Z position and the X, Y, or Z "worst-case" bounds which allows you to discard whole swathes of objects that "can't possibly" collide. (I haven't implemented swept/continuous collision yet, hence the quote marks).</p> <p>Once that was implemented on the X-axis, I added further Z and Y filters , sorting the X, Z and Y axis lists in turn and breaking when I reached an object that could not be collided with.</p> <p>That all worked rather well, although any speed increase from the last filter was negligible.</p> <p>Then I thought "If I sort them on the X-axis, on the Z-axis if that check returns equivalency, then on the Y-axis if that check returns equivalency, I should be able to toss out sorting the secondary lists." This would drop about 40% from the time taken.</p> <p>So I made it so. And it didn't work - Objects fell through the ground-plane. Other objects hit the ground-plane. It looked like the first set of objects fell through and all others bounced.</p> <p>So, two questions - Could this work and please check my code for errors:</p> <pre><code> bodies.Sort( (a, b) =&gt; { // Should sort the list in X, then Z, then Y order. int signX, signY, signZ; return (signX = Math.Sign((a.LocalPosition.X - a.Bounds.X) - (b.LocalPosition.X - b.Bounds.X))) == 0 ? (signZ = Math.Sign((a.LocalPosition.Z - a.Bounds.Z) - (b.LocalPosition.Z - b.Bounds.Z))) == 0 ? (signY = Math.Sign((a.LocalPosition.Y - a.Bounds.Y) - (b.LocalPosition.Y - b.Bounds.Y))) == 0 ? 0 : signY : signZ : signX; } ); Contact info; List&lt;BodyEnt&gt; checkBodiesZ = new List&lt;BodyEnt&gt;(); List&lt;BodyEnt&gt; checkBodiesY = new List&lt;BodyEnt&gt;(); for (int t = 0; t &lt; bodies.Count; ++t) { checkBodiesZ.Clear(); for (int t2 = t + 1; t2 &lt; bodies.Count; ++t2) { // If we've reached the last object we could collide with, exit. if (bodies[t].LocalPosition.X + bodies[t].Bounds.X &lt;= bodies[t2].LocalPosition.X - bodies[t2].Bounds.X) break; checkBodiesZ.Add(bodies[t2]); } // checkBodiesZ.Sort((a, b) =&gt; { return Math.Sign((a.LocalPosition.Z - a.Bounds.Z) - (b.LocalPosition.Z - b.Bounds.Z)); }); checkBodiesY.Clear(); for (int t2 = 0; t2 &lt; checkBodiesZ.Count; ++t2) { if (bodies[t].LocalPosition.Z + bodies[t].Bounds.Z &lt;= checkBodiesZ[t2].LocalPosition.Z - checkBodiesZ[t2].Bounds.Z) break; checkBodiesY.Add(checkBodiesZ[t2]); } // One of the two sorts I removed in this test. // checkBodiesY.Sort((a, b) =&gt; { return Math.Sign((a.LocalPosition.Y - a.Bounds.Y) - (b.LocalPosition.Y - b.Bounds.Y)); }); for (int t2 = 0; t2 &lt; checkBodiesY.Count; ++t2) { if (bodies[t].LocalPosition.Y + bodies[t].Bounds.Y &lt;= checkBodiesY[t2].LocalPosition.Y - checkBodiesY[t2].Bounds.Y) break; info = bodies[t].CheckCollision(checkBodiesY[t2]); // .CheckCollision() returns null if no collision detected. if (info != null) contacts.Add(info); } } </code></pre> <p>Thanks. :)</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload