diff --git a/crates/avian3d/snapshots/avian3d__tests__cubes_simulation_is_deterministic_across_machines.snap b/crates/avian3d/snapshots/avian3d__tests__cubes_simulation_is_deterministic_across_machines.snap index 84dc8ced..53b531f5 100644 --- a/crates/avian3d/snapshots/avian3d__tests__cubes_simulation_is_deterministic_across_machines.snap +++ b/crates/avian3d/snapshots/avian3d__tests__cubes_simulation_is_deterministic_across_machines.snap @@ -9,15 +9,15 @@ expression: bodies ), Transform { translation: Vec3( - -4.313603, - 0.499899, - -4.3720384, + -4.3243527, + 0.49991986, + -4.3539424, ), rotation: Quat( - 1.4286024e-6, - 0.018273411, - 2.6459269e-5, - 0.99983305, + 2.5392612e-5, + 0.04461888, + 5.6499757e-6, + 0.99900407, ), scale: Vec3( 1.0, @@ -32,15 +32,15 @@ expression: bodies ), Transform { translation: Vec3( - -4.3011374, - 0.4999332, - -2.119257, + -4.2786093, + 0.49992478, + -2.132244, ), rotation: Quat( - 1.1062815e-5, - 0.0081719905, - 3.69934e-6, - 0.9999666, + 4.8880383e-7, + 0.0029120322, + 1.1011286e-5, + 0.99999577, ), scale: Vec3( 1.0, @@ -55,15 +55,15 @@ expression: bodies ), Transform { translation: Vec3( - -4.5053754, - 0.4999251, - -0.015259444, + -4.369801, + 0.49982738, + -0.002351249, ), rotation: Quat( - -1.6268401e-5, - -0.017082863, - -3.5117948e-5, - 0.9998541, + 6.927235e-5, + 0.024584759, + 3.78621e-5, + 0.99969774, ), scale: Vec3( 1.0, @@ -78,15 +78,15 @@ expression: bodies ), Transform { translation: Vec3( - -4.3493614, - 0.49986988, - 2.1268625, + -4.344536, + 0.4998861, + 2.0625727, ), rotation: Quat( - -5.1456882e-5, - 0.036344398, - -6.1906736e-5, - 0.99933934, + 1.3142657e-5, + 0.033230767, + -4.559078e-5, + 0.9994477, ), scale: Vec3( 1.0, @@ -101,15 +101,15 @@ expression: bodies ), Transform { translation: Vec3( - -2.1950142, - 0.49991348, - -4.3041863, + -2.1951137, + 0.49992466, + -4.2405095, ), rotation: Quat( - -1.5423266e-5, - -0.019812824, - 4.994884e-6, - 0.9998037, + -2.8148599e-5, + 0.03811511, + -2.8113238e-5, + 0.99927336, ), scale: Vec3( 1.0, @@ -124,15 +124,15 @@ expression: bodies ), Transform { translation: Vec3( - -2.0794566, - 0.49993524, - -2.2297425, + -2.1763153, + 0.4999553, + -2.1939993, ), rotation: Quat( - 6.8364056e-6, - 0.016324822, - 7.853812e-6, - 0.9998667, + 1.470748e-5, + 0.029806782, + 2.8462907e-7, + 0.9995557, ), scale: Vec3( 1.0, @@ -147,15 +147,15 @@ expression: bodies ), Transform { translation: Vec3( - -2.4171753, - 0.4999022, - -0.16073997, + -2.3350973, + 0.49995607, + -0.17375073, ), rotation: Quat( - -1.863779e-5, - 0.015245996, - 2.8633933e-5, - 0.9998838, + 1.010217e-5, + 0.028624436, + -4.758877e-6, + 0.9995902, ), scale: Vec3( 1.0, @@ -170,15 +170,15 @@ expression: bodies ), Transform { translation: Vec3( - -2.143239, - 0.499911, - 2.044667, + -2.1607132, + 0.49988654, + 1.889722, ), rotation: Quat( - 1.7824239e-5, - 0.05098578, - 1.5593234e-5, - 0.99869937, + 2.1787431e-5, + 0.0150535945, + -4.8457427e-5, + 0.9998867, ), scale: Vec3( 1.0, @@ -193,15 +193,15 @@ expression: bodies ), Transform { translation: Vec3( - 0.004828917, - 0.49991924, - -4.5161033, + 0.07129576, + 0.49997407, + -4.4746776, ), rotation: Quat( - -4.788997e-6, - -0.015063981, - 1.272319e-5, - 0.9998865, + 2.3356838e-6, + 0.0022213592, + 1.778282e-7, + 0.99999756, ), scale: Vec3( 1.0, @@ -216,15 +216,15 @@ expression: bodies ), Transform { translation: Vec3( - -0.03314393, - 0.49993885, - -2.3282351, + -0.026171334, + 0.4999397, + -2.2034783, ), rotation: Quat( - 5.087684e-6, - -0.006678883, - 5.9210624e-6, - 0.9999777, + 6.363814e-6, + 0.014872479, + -1.3326761e-5, + 0.9998894, ), scale: Vec3( 1.0, @@ -239,15 +239,15 @@ expression: bodies ), Transform { translation: Vec3( - -0.2778316, - 0.49987876, - -0.283173, + -0.19169083, + 0.49992487, + -0.18196382, ), rotation: Quat( - 9.176122e-6, - 0.014165391, - 4.9754664e-5, - 0.9998997, + 1.0830025e-5, + 0.021014728, + 2.1036401e-5, + 0.99977916, ), scale: Vec3( 1.0, @@ -262,15 +262,15 @@ expression: bodies ), Transform { translation: Vec3( - -0.11793988, - 0.49991164, - 2.1285946, + -0.055619642, + 0.49991018, + 1.8385749, ), rotation: Quat( - 3.4434175e-5, - 0.05088754, - 1.3534302e-5, - 0.9987044, + 1.2763383e-5, + 0.01656498, + 2.7240958e-5, + 0.9998628, ), scale: Vec3( 1.0, @@ -285,15 +285,15 @@ expression: bodies ), Transform { translation: Vec3( - 2.0349672, - 0.49979636, - -4.363086, + 2.2245302, + 0.4999203, + -4.5461516, ), rotation: Quat( - -9.717715e-6, - 0.0017251128, - -6.074979e-5, - 0.9999985, + 1.709381e-5, + 0.009905274, + 1.890729e-5, + 0.99995095, ), scale: Vec3( 1.0, @@ -308,15 +308,15 @@ expression: bodies ), Transform { translation: Vec3( - 2.1507323, - 0.4999325, - -2.2163112, + 1.9937165, + 0.49996367, + -2.0315197, ), rotation: Quat( - -2.837081e-6, - 0.036985353, - 8.574389e-8, - 0.9993158, + -4.879413e-6, + 0.006292736, + 7.124769e-6, + 0.9999802, ), scale: Vec3( 1.0, @@ -331,15 +331,15 @@ expression: bodies ), Transform { translation: Vec3( - 2.0534167, - 0.4999691, - -0.19286145, + 2.0661972, + 0.49995384, + -0.02310217, ), rotation: Quat( - 3.227243e-6, - 0.02994612, - 2.9920968e-6, - 0.99955153, + 7.933694e-6, + 0.0018710081, + 1.0839999e-5, + 0.9999983, ), scale: Vec3( 1.0, @@ -354,15 +354,15 @@ expression: bodies ), Transform { translation: Vec3( - 1.8947515, - 0.4999516, - 1.8330995, + 2.5236223, + 0.49996725, + 1.9759675, ), rotation: Quat( - 6.5972256e-7, - 0.03522129, - 1.4760176e-5, - 0.9993795, + -1.0665481e-5, + 0.0015681527, + -6.8327086e-6, + 0.99999875, ), scale: Vec3( 1.0, @@ -377,15 +377,15 @@ expression: bodies ), Transform { translation: Vec3( - -4.2788234, - 2.4994156, - -4.664698, + -4.339363, + 2.4994073, + -4.2629104, ), rotation: Quat( - -8.403021e-5, - -0.0022064378, - 0.00012648037, - 0.99999756, + 6.1576924e-5, + 0.033588145, + 9.425271e-5, + 0.9994358, ), scale: Vec3( 1.0, @@ -400,15 +400,15 @@ expression: bodies ), Transform { translation: Vec3( - -4.282782, - 2.4996676, - -2.3445575, + -4.810213, + 2.4993768, + -2.0232263, ), rotation: Quat( - 5.6368235e-6, - -0.012503323, - 5.2872492e-5, - 0.99992186, + -2.8831807e-6, + 0.053750236, + 0.0001223818, + 0.9985544, ), scale: Vec3( 1.0, @@ -423,15 +423,15 @@ expression: bodies ), Transform { translation: Vec3( - -4.12186, - 2.4998248, - 0.4604897, + -4.4904027, + 2.4992795, + 0.20261757, ), rotation: Quat( - -2.2722208e-5, - 0.14428969, - 2.4234869e-5, - 0.9895355, + -0.0001897744, + 0.020543976, + -2.1458027e-6, + 0.99978894, ), scale: Vec3( 1.0, @@ -446,15 +446,15 @@ expression: bodies ), Transform { translation: Vec3( - -4.1697073, - 2.4995875, - 2.9979086, + -4.534022, + 2.4995549, + 2.3980114, ), rotation: Quat( - 9.742272e-6, - 0.10423435, - -4.011737e-5, - 0.9945528, + 1.1574514e-5, + -0.076673515, + 6.9183196e-5, + 0.99705625, ), scale: Vec3( 1.0, @@ -469,15 +469,15 @@ expression: bodies ), Transform { translation: Vec3( - -1.8789963, - 2.4995587, - -4.6137695, + -2.047455, + 0.4999647, + -7.2127266, ), rotation: Quat( - -0.0001250929, - -0.09119444, - 7.3334595e-5, - 0.9958331, + -0.70702183, + 0.0110129155, + 0.0110116, + 0.7070202, ), scale: Vec3( 1.0, @@ -492,15 +492,15 @@ expression: bodies ), Transform { translation: Vec3( - -2.0297258, - 2.499756, - -2.3649726, + -2.2553782, + 2.499893, + -1.5258576, ), rotation: Quat( - 2.2753404e-5, - -0.017997589, - 4.6556645e-5, - 0.99983805, + 7.879404e-6, + -0.050584134, + 2.0222738e-5, + 0.9987198, ), scale: Vec3( 1.0, @@ -515,15 +515,15 @@ expression: bodies ), Transform { translation: Vec3( - -1.9600471, - 2.4996383, - -0.089489006, + -2.1133072, + 2.4998116, + 0.6407957, ), rotation: Quat( - -6.4888495e-6, - 0.0322446, - 2.7406079e-5, - 0.99948, + 1.4860717e-5, + -0.06389087, + 8.017414e-6, + 0.9979569, ), scale: Vec3( 1.0, @@ -538,15 +538,15 @@ expression: bodies ), Transform { translation: Vec3( - -1.9408162, - 2.4998157, - 2.8212252, + -2.3780742, + 2.499642, + 2.9385276, ), rotation: Quat( - 3.975343e-6, - 0.118854254, - -1.96181e-5, - 0.9929117, + 5.148289e-5, + -0.07521257, + -5.60672e-5, + 0.9971675, ), scale: Vec3( 1.0, @@ -561,15 +561,15 @@ expression: bodies ), Transform { translation: Vec3( - 0.42267635, - 2.499599, - -4.7398543, + 0.3398966, + 0.49997208, + -7.488397, ), rotation: Quat( - -0.000100757, - -0.12321499, - 2.5166833e-5, - 0.99238, + -0.7059476, + -0.04047617, + -0.040471934, + 0.7059474, ), scale: Vec3( 1.0, @@ -584,15 +584,15 @@ expression: bodies ), Transform { translation: Vec3( - 0.117045954, - 2.499719, - -2.5020692, + -0.05249534, + 2.4997911, + -1.965032, ), rotation: Quat( - 7.355824e-5, - -0.033679545, - 3.092247e-5, - 0.9994327, + 5.872177e-6, + -0.026311453, + -1.0617185e-5, + 0.9996538, ), scale: Vec3( 1.0, @@ -607,15 +607,15 @@ expression: bodies ), Transform { translation: Vec3( - 0.058235154, - 2.4991755, - -0.059208136, + 0.21838848, + 2.499774, + 0.3454408, ), rotation: Quat( - 4.2975404e-5, - 0.029950041, - -0.00020711882, - 0.99955136, + 1.00489415e-5, + 0.0010831612, + -2.1967493e-5, + 0.9999994, ), scale: Vec3( 1.0, @@ -630,15 +630,15 @@ expression: bodies ), Transform { translation: Vec3( - 0.2135342, - 2.4997144, - 2.1718612, + -0.089054555, + 2.4995275, + 2.504886, ), rotation: Quat( - -3.492352e-5, - 0.16036889, - 7.769919e-6, - 0.98705715, + 4.7427882e-5, + -0.080646336, + -0.00010408245, + 0.9967428, ), scale: Vec3( 1.0, @@ -653,15 +653,15 @@ expression: bodies ), Transform { translation: Vec3( - 2.9242144, - 2.4993885, - -5.0845246, + 2.527748, + 2.4991374, + -4.4892116, ), rotation: Quat( - -0.0001202047, - -0.19975874, - -0.00014944628, - 0.9798451, + -9.4314746e-5, + -0.02328474, + -0.000272487, + 0.99972886, ), scale: Vec3( 1.0, @@ -676,15 +676,15 @@ expression: bodies ), Transform { translation: Vec3( - 2.5543904, - 2.4997144, - -2.6636345, + 4.6978083, + 0.49997446, + -2.529034, ), rotation: Quat( - 1.3763424e-5, - 0.012462141, - -4.668542e-5, - 0.99992234, + -0.12651552, + 0.12651613, + -0.695696, + 0.6956972, ), scale: Vec3( 1.0, @@ -699,15 +699,15 @@ expression: bodies ), Transform { translation: Vec3( - 4.9411154, - 0.4999785, - -0.47300392, + 5.0067825, + 0.49995244, + -0.23179539, ), rotation: Quat( - -0.08334969, - 0.083349094, - -0.7021769, - 0.7021775, + -0.01690404, + 0.016887175, + -0.7068965, + 0.7069133, ), scale: Vec3( 1.0, @@ -722,15 +722,15 @@ expression: bodies ), Transform { translation: Vec3( - 7.1084046, - 0.49997765, - 3.7663803, + 2.21022, + 0.49997383, + 4.6588492, ), rotation: Quat( - 0.23666246, - -0.23666057, - -0.66632634, - 0.6663271, + 0.70695096, + -0.014782014, + 0.014780647, + 0.7069536, ), scale: Vec3( 1.0, @@ -745,15 +745,15 @@ expression: bodies ), Transform { translation: Vec3( - -4.672622, - 4.4989777, - -5.108455, + -4.924656, + 4.498837, + -4.395266, ), rotation: Quat( - -0.0001313217, - 0.009912094, - 0.00019795788, - 0.9999508, + -5.0297967e-5, + 0.012984138, + 0.00015310242, + 0.9999157, ), scale: Vec3( 1.0, @@ -768,15 +768,15 @@ expression: bodies ), Transform { translation: Vec3( - -4.817686, - 4.4993834, - -2.8946247, + -4.5116987, + 4.4991884, + -2.0919309, ), rotation: Quat( - -4.4691737e-5, - 0.10252833, - 0.00011791111, - 0.99473006, + -6.07906e-5, + 0.21205448, + 0.00025381567, + 0.9772578, ), scale: Vec3( 1.0, @@ -791,15 +791,15 @@ expression: bodies ), Transform { translation: Vec3( - -4.9773936, - 4.4996796, - -0.58611554, + -4.708402, + 4.499147, + 0.4031223, ), rotation: Quat( - -7.940264e-5, - 0.044306647, - 6.2205916e-5, - 0.99901795, + -0.00022171022, + -0.009159838, + 6.280141e-5, + 0.99995804, ), scale: Vec3( 1.0, @@ -814,15 +814,15 @@ expression: bodies ), Transform { translation: Vec3( - -11.687523, - 0.4999791, - 4.32482, + -5.7102857, + 0.49997422, + 5.8349714, ), rotation: Quat( - -0.2978643, - -0.29786435, - 0.6413087, - 0.64130867, + 0.70070577, + -0.094907604, + 0.09490725, + 0.7007115, ), scale: Vec3( 1.0, @@ -837,15 +837,15 @@ expression: bodies ), Transform { translation: Vec3( - -2.0065486, - 4.4987693, - -5.8758097, + -2.7235184, + 0.49997434, + -10.980807, ), rotation: Quat( - -0.00030035235, - 0.18327786, - 2.3544239e-5, - 0.98306113, + -0.6748626, + -0.21109083, + -0.21109423, + 0.6748632, ), scale: Vec3( 1.0, @@ -860,15 +860,15 @@ expression: bodies ), Transform { translation: Vec3( - -2.1529267, - 4.4994907, - -2.5396628, + -1.9942989, + 2.4997768, + -4.127104, ), rotation: Quat( - 5.9172893e-5, - 0.0342595, - 0.00012009286, - 0.99941295, + -0.7070685, + -0.011345126, + -0.011363063, + 0.70696276, ), scale: Vec3( 1.0, @@ -883,15 +883,15 @@ expression: bodies ), Transform { translation: Vec3( - -2.0270457, - 4.4992833, - 0.05558736, + -2.4975805, + 4.4997125, + 0.0650188, ), rotation: Quat( - -4.4742904e-7, - 0.050303213, - 3.430188e-5, - 0.998734, + 5.400572e-5, + -0.035251696, + -1.1071046e-5, + 0.99937844, ), scale: Vec3( 1.0, @@ -906,15 +906,15 @@ expression: bodies ), Transform { translation: Vec3( - -2.2234242, - 4.499497, - 2.266979, + -2.734841, + 4.4995475, + 2.596534, ), rotation: Quat( - 0.00013273758, - 0.033669222, - -8.744341e-5, - 0.99943304, + 1.6605532e-5, + -0.07100289, + -3.328125e-5, + 0.9974761, ), scale: Vec3( 1.0, @@ -929,15 +929,15 @@ expression: bodies ), Transform { translation: Vec3( - 0.7039197, - 4.499274, - -5.171321, + -0.13911, + 0.49997413, + -11.233632, ), rotation: Quat( - -0.0001027083, - -0.16680604, - 1.2052547e-5, - 0.98598975, + -0.7045634, + 0.05990648, + 0.059910644, + 0.70456535, ), scale: Vec3( 1.0, @@ -952,15 +952,15 @@ expression: bodies ), Transform { translation: Vec3( - 0.031837, - 4.4995165, - -2.4768581, + 0.80650884, + 4.49954, + -2.1179333, ), rotation: Quat( - 6.352169e-5, - -0.0019942177, - 5.4674823e-5, - 0.99999803, + -3.152784e-5, + 0.088109314, + -7.021435e-5, + 0.9961108, ), scale: Vec3( 1.0, @@ -975,15 +975,15 @@ expression: bodies ), Transform { translation: Vec3( - 0.518357, - 4.4987106, - -0.25808463, + -0.021189805, + 4.4996448, + 0.0980292, ), rotation: Quat( - -1.8058909e-5, - -0.10794885, - -0.0003055898, - 0.9941564, + 3.8537484e-5, + 0.035240203, + 3.141011e-5, + 0.99937886, ), scale: Vec3( 1.0, @@ -998,15 +998,15 @@ expression: bodies ), Transform { translation: Vec3( - -0.1720326, - 4.499623, - 2.037988, + 0.39334828, + 4.499295, + 2.5914605, ), rotation: Quat( - -4.3344335e-5, - 0.042105593, - -3.757301e-5, - 0.99911314, + 3.1565494e-5, + -0.03311778, + -1.3205492e-5, + 0.99945146, ), scale: Vec3( 1.0, @@ -1021,15 +1021,15 @@ expression: bodies ), Transform { translation: Vec3( - 3.154707, - 4.4990897, - -4.9818134, + 2.9196174, + 4.498402, + -5.0181313, ), rotation: Quat( - -6.425886e-5, - -0.21336839, - -0.00013157852, - 0.9769718, + -0.00010783016, + -0.09249844, + -0.00039367206, + 0.99571276, ), scale: Vec3( 1.0, @@ -1044,15 +1044,15 @@ expression: bodies ), Transform { translation: Vec3( - 2.3228934, - 4.499498, - -2.7970145, + 8.9486065, + 0.49997792, + -4.5367913, ), rotation: Quat( - -1.0142668e-5, - -0.03198996, - -3.7720332e-5, - 0.9994882, + 0.37209338, + -0.37209192, + -0.6012873, + 0.6012883, ), scale: Vec3( 1.0, @@ -1067,15 +1067,15 @@ expression: bodies ), Transform { translation: Vec3( - 10.707428, - 0.4999756, - -1.4309556, + 10.860054, + 0.49997455, + 0.33711982, ), rotation: Quat( - -0.55729717, - 0.55729574, - -0.4352238, - 0.43522587, + 0.539376, + 0.45724833, + -0.45724505, + 0.5393741, ), scale: Vec3( 1.0, @@ -1090,15 +1090,15 @@ expression: bodies ), Transform { translation: Vec3( - 3.7593293, - 0.49997392, - 9.844143, + 1.7973658, + 0.49997544, + 7.6060634, ), rotation: Quat( - 0.7068837, - 0.017828325, - -0.017835706, - 0.7068801, + 0.6361565, + -0.30871332, + 0.3087156, + 0.6361569, ), scale: Vec3( 1.0, @@ -1113,15 +1113,15 @@ expression: bodies ), Transform { translation: Vec3( - -5.2732806, - 6.4987097, - -4.821642, + -4.769561, + 6.4986734, + -4.464631, ), rotation: Quat( - -0.00014391786, - -0.025830226, - 0.00023654208, - 0.99966633, + -5.1275645e-5, + 0.04602603, + 0.00013058743, + 0.9989402, ), scale: Vec3( 1.0, @@ -1136,15 +1136,15 @@ expression: bodies ), Transform { translation: Vec3( - -5.07255, - 6.4992456, - -2.5319104, + -5.208853, + 6.4987497, + -2.2389634, ), rotation: Quat( - -7.3293304e-5, - 0.09425548, - 0.00014368318, - 0.995548, + -8.055547e-6, + 0.021011695, + 0.00027942174, + 0.99977916, ), scale: Vec3( 1.0, @@ -1159,15 +1159,15 @@ expression: bodies ), Transform { translation: Vec3( - -5.2476854, - 4.4968004, - 2.575401, + -4.677629, + 6.4989843, + 0.36477792, ), rotation: Quat( - 0.6826858, - -0.18387283, - 0.18930812, - 0.6813907, + -0.00023052825, + -0.07554992, + 0.00013078307, + 0.99714196, ), scale: Vec3( 1.0, @@ -1182,15 +1182,15 @@ expression: bodies ), Transform { translation: Vec3( - -7.5386963, - 0.49997413, - 2.9133756, + -6.2685947, + 0.4999749, + 9.447185, ), rotation: Quat( - 0.2427398, - 0.24273942, - 0.66413575, - 0.66413754, + 0.7002883, + -0.097953685, + 0.09795478, + 0.70029014, ), scale: Vec3( 1.0, @@ -1205,15 +1205,15 @@ expression: bodies ), Transform { translation: Vec3( - -2.2810879, - 6.4990354, - -5.1089425, + -3.2613604, + 0.49997345, + -14.447802, ), rotation: Quat( - -0.7065279, - -0.03258241, - -0.03242451, - 0.70619076, + -0.7053601, + 0.049655087, + 0.049652148, + 0.70536244, ), scale: Vec3( 1.0, @@ -1228,15 +1228,15 @@ expression: bodies ), Transform { translation: Vec3( - -2.6192734, - 6.4992013, - -2.2983062, + -1.4933374, + 2.4998949, + -7.4620485, ), rotation: Quat( - 7.152361e-5, - 0.008585493, - 0.00014713596, - 0.9999631, + -0.69231987, + -0.1438652, + -0.14384842, + 0.69231755, ), scale: Vec3( 1.0, @@ -1251,15 +1251,15 @@ expression: bodies ), Transform { translation: Vec3( - -2.4982786, - 6.4991755, - 0.042023446, + -2.598814, + 6.4995704, + 1.0894675, ), rotation: Quat( - 2.2073978e-6, - -0.08845437, - 6.832452e-5, - 0.9960802, + 2.7027687e-5, + -0.11454783, + -1.9854979e-5, + 0.99341774, ), scale: Vec3( 1.0, @@ -1274,15 +1274,15 @@ expression: bodies ), Transform { translation: Vec3( - -3.9401844, - 0.49997714, - 6.9226065, + -1.027358, + 0.4999708, + 13.038362, ), rotation: Quat( - 0.166602, - -0.68719995, - 0.68720055, - 0.16659948, + 0.61228055, + 0.35370472, + -0.35370508, + 0.6122893, ), scale: Vec3( 1.0, @@ -1297,15 +1297,15 @@ expression: bodies ), Transform { translation: Vec3( - 0.011674444, - 6.4993124, - -4.578363, + -0.7097831, + 0.49997377, + -14.894028, ), rotation: Quat( - -6.374699e-5, - 0.052039027, - -4.1060906e-5, - 0.99864507, + -0.67818254, + 0.20018506, + 0.2001762, + 0.6781769, ), scale: Vec3( 1.0, @@ -1320,15 +1320,15 @@ expression: bodies ), Transform { translation: Vec3( - 0.5503028, - 6.4994364, - -2.1881046, + 0.07846992, + 6.4994574, + -2.276928, ), rotation: Quat( - 5.43608e-5, - 0.11560162, - 5.4146713e-5, - 0.99329567, + -4.896268e-5, + -0.018394945, + -1.5834506e-5, + 0.9998308, ), scale: Vec3( 1.0, @@ -1343,15 +1343,15 @@ expression: bodies ), Transform { translation: Vec3( - -0.11158669, - 6.499274, - 0.05484475, + -0.34891623, + 6.4994407, + 1.0149225, ), rotation: Quat( - -0.00012463934, - -0.087396465, - -5.783063e-5, - 0.9961736, + 4.3123695e-5, + -0.06607756, + 1.23120435e-5, + 0.9978145, ), scale: Vec3( 1.0, @@ -1366,15 +1366,15 @@ expression: bodies ), Transform { translation: Vec3( - 1.0075747, - 0.49997526, - 6.697249, + -0.4301395, + 0.4999747, + 6.790393, ), rotation: Quat( - 0.61820906, - 0.61821014, - 0.3432463, - 0.34324297, + 0.63092864, + 0.31926596, + -0.3192641, + 0.63092685, ), scale: Vec3( 1.0, @@ -1389,15 +1389,15 @@ expression: bodies ), Transform { translation: Vec3( - 2.5019968, - 6.499232, - -4.541764, + 2.3003325, + 6.4987993, + -4.480083, ), rotation: Quat( - -9.007325e-5, - -0.0512733, - -6.88152e-5, - 0.99868464, + -3.0372501e-5, + 0.079241425, + -0.00031923188, + 0.9968554, ), scale: Vec3( 1.0, @@ -1412,15 +1412,15 @@ expression: bodies ), Transform { translation: Vec3( - 2.534766, - 2.499874, - 0.90552336, + 3.959462, + 4.4994497, + -0.8488095, ), rotation: Quat( - 0.7055338, - -0.047247704, - 0.047213424, - 0.7055215, + 0.18084154, + -0.1810612, + -0.68348867, + 0.6836347, ), scale: Vec3( 1.0, @@ -1435,15 +1435,15 @@ expression: bodies ), Transform { translation: Vec3( - 4.8845277, - 0.91391414, - 2.28504, + 4.0047736, + 2.4997685, + 0.0033400285, ), rotation: Quat( - 0.17781864, - -0.44093615, - -0.32901525, - 0.81590736, + 0.0011647202, + 0.0013140906, + 0.7071359, + 0.7070754, ), scale: Vec3( 1.0, @@ -1458,15 +1458,15 @@ expression: bodies ), Transform { translation: Vec3( - 4.1904697, - 0.49997452, - 5.045945, + 1.8501573, + 0.49997666, + 11.836599, ), rotation: Quat( - 0.5004966, - 0.5005007, - 0.4994997, - 0.499502, + 0.7022902, + -0.08240583, + 0.08240115, + 0.70228755, ), scale: Vec3( 1.0, diff --git a/src/collision/collider/backend.rs b/src/collision/collider/backend.rs index 2ea8d50c..58547062 100644 --- a/src/collision/collider/backend.rs +++ b/src/collision/collider/backend.rs @@ -584,18 +584,14 @@ fn update_aabb( } #[cfg(feature = "3d")] { - let q = Quaternion::from_vec4(ang_vel.0.extend(0.0)) * rot.0; - let (x, y, z, w) = ( - rot.x + delta_secs * 0.5 * q.x, - rot.y + delta_secs * 0.5 * q.y, - rot.z + delta_secs * 0.5 * q.z, - rot.w + delta_secs * 0.5 * q.w, - ); + let mut end_rot = + Rotation(Quaternion::from_scaled_axis(ang_vel.0 * delta_secs) * rot.0); + end_rot.renormalize(); ( pos.0 + (lin_vel.0 * delta_secs) .clamp_length_max(speculative_margin.max(contact_tolerance)), - Quaternion::from_xyzw(x, y, z, w).normalize(), + end_rot, ) } }; diff --git a/src/dynamics/ccd/mod.rs b/src/dynamics/ccd/mod.rs index db10aadc..0ac3d30a 100644 --- a/src/dynamics/ccd/mod.rs +++ b/src/dynamics/ccd/mod.rs @@ -659,10 +659,9 @@ fn solve_swept_ccd( } #[cfg(feature = "3d")] { - let delta_rot = Quaternion::from_vec4( - (ang_vel1.0 * min_toi / 2.0).extend(prev_rot.w * min_toi / 2.0), - ) * prev_rot.0 .0; - rot1.0 = (prev_rot.0 .0 + delta_rot).normalize(); + let delta_rot = Quaternion::from_scaled_axis(ang_vel1.0 * min_toi); + rot1.0 = delta_rot * prev_rot.0 .0; + rot1.renormalize(); } if let Some(mut collider_translation) = body2.translation { @@ -676,11 +675,10 @@ fn solve_swept_ccd( } #[cfg(feature = "3d")] { - let delta_rot = Quaternion::from_vec4( - (collider_ang_vel * min_toi / 2.0) - .extend(collider_prev_rot.w * min_toi / 2.0), - ) * collider_prev_rot.0 .0; - body2.rot.0 = (collider_prev_rot.0 .0 + delta_rot).normalize(); + let delta_rot = Quaternion::from_scaled_axis(collider_ang_vel * min_toi); + + body2.rot.0 = delta_rot * collider_prev_rot.0 .0; + body2.rot.renormalize(); } } } diff --git a/src/dynamics/integrator/semi_implicit_euler.rs b/src/dynamics/integrator/semi_implicit_euler.rs index ee902ff5..298d01d6 100644 --- a/src/dynamics/integrator/semi_implicit_euler.rs +++ b/src/dynamics/integrator/semi_implicit_euler.rs @@ -123,11 +123,11 @@ pub fn integrate_position( { // This is a bit more complicated because quaternions are weird. // Maybe there's a simpler and more numerically stable way? - let delta_rot = Quaternion::from_vec4( - (ang_vel * delta_seconds / 2.0).extend(rot.w * delta_seconds / 2.0), - ) * rot.0; - if delta_rot.w != 0.0 && delta_rot.is_finite() { - rot.0 = (rot.0 + delta_rot).normalize(); + let scaled_axis = ang_vel * delta_seconds; + if scaled_axis != AngularVelocity::ZERO.0 && scaled_axis.is_finite() { + let delta_rot = Quaternion::from_scaled_axis(scaled_axis); + rot.0 = delta_rot * rot.0; + rot.renormalize(); } } } diff --git a/src/dynamics/solver/xpbd/angular_constraint.rs b/src/dynamics/solver/xpbd/angular_constraint.rs index f24f1db6..efd690c1 100644 --- a/src/dynamics/solver/xpbd/angular_constraint.rs +++ b/src/dynamics/solver/xpbd/angular_constraint.rs @@ -37,11 +37,11 @@ pub trait AngularConstraint: XpbdConstraint<2> { // Apply rotational updates if body1.rb.is_dynamic() && body1.dominance() <= body2.dominance() { - let delta_angle = Self::get_delta_rot(*body1.rotation, inv_inertia1, impulse); + let delta_angle = Self::get_delta_rot(inv_inertia1, impulse); *body1.rotation = body1.rotation.add_angle(delta_angle); } if body2.rb.is_dynamic() && body2.dominance() <= body1.dominance() { - let delta_angle = Self::get_delta_rot(*body2.rotation, inv_inertia2, -impulse); + let delta_angle = Self::get_delta_rot(inv_inertia2, -impulse); *body2.rotation = body2.rotation.add_angle(delta_angle); } @@ -89,13 +89,15 @@ pub trait AngularConstraint: XpbdConstraint<2> { // which causes stability issues (see #235) and panics when trying to rotate unit vectors. // TODO: It would be nice to avoid normalization if possible. // Maybe the math above can be done in a way that keeps rotations normalized? - let delta_quat = Self::get_delta_rot(*body1.rotation, inv_inertia1, impulse); - body1.rotation.0 = (body1.rotation.0 + delta_quat).normalize(); + let delta_quat = Self::get_delta_rot(inv_inertia1, impulse); + body1.rotation.0 = delta_quat * body1.rotation.0; + body1.rotation.renormalize(); } if body2.rb.is_dynamic() { // See comments for `body1` above. - let delta_quat = Self::get_delta_rot(*body2.rotation, inv_inertia2, -impulse); - body2.rotation.0 = (body2.rotation.0 + delta_quat).normalize(); + let delta_quat = Self::get_delta_rot(inv_inertia2, -impulse); + body2.rotation.0 = delta_quat * body2.rotation.0; + body2.rotation.renormalize(); } impulse @@ -196,11 +198,11 @@ pub trait AngularConstraint: XpbdConstraint<2> { // Apply rotational updates if body1.rb.is_dynamic() && body1.dominance() <= body2.dominance() { - let delta_angle = Self::get_delta_rot(*body1.rotation, inv_inertia1, p); + let delta_angle = Self::get_delta_rot(inv_inertia1, p); *body1.rotation = body1.rotation.add_angle(delta_angle); } if body2.rb.is_dynamic() && body2.dominance() <= body1.dominance() { - let delta_angle = Self::get_delta_rot(*body2.rotation, inv_inertia2, -p); + let delta_angle = Self::get_delta_rot(inv_inertia2, -p); *body2.rotation = body2.rotation.add_angle(delta_angle); } @@ -234,13 +236,15 @@ pub trait AngularConstraint: XpbdConstraint<2> { // which causes stability issues (see #235) and panics when trying to rotate unit vectors. // TODO: It would be nice to avoid normalization if possible. // Maybe the math above can be done in a way that keeps rotations normalized? - let delta_quat = Self::get_delta_rot(*body1.rotation, inv_inertia1, p); - body1.rotation.0 = (body1.rotation.0 + delta_quat).normalize(); + let delta_quat = Self::get_delta_rot(inv_inertia1, p); + body1.rotation.0 = delta_quat * body1.rotation.0; + body1.rotation.renormalize(); } if body2.rb.is_dynamic() { // See comments for `body1` above. - let delta_quat = Self::get_delta_rot(*body2.rotation, inv_inertia2, -p); - body2.rotation.0 = (body2.rotation.0 + delta_quat).normalize(); + let delta_quat = Self::get_delta_rot(inv_inertia2, -p); + body2.rotation.0 = delta_quat * body2.rotation.0; + body2.rotation.renormalize(); } p @@ -275,16 +279,16 @@ pub trait AngularConstraint: XpbdConstraint<2> { /// Computes the update in rotation when applying an angular correction `p`. #[cfg(feature = "2d")] - fn get_delta_rot(_rot: Rotation, inverse_inertia: Scalar, p: Scalar) -> Scalar { + fn get_delta_rot(inverse_inertia: Scalar, p: Scalar) -> Scalar { // Equation 8/9 but in 2D inverse_inertia * p } /// Computes the update in rotation when applying an angular correction `p`. #[cfg(feature = "3d")] - fn get_delta_rot(rot: Rotation, inverse_inertia: Matrix3, p: Vector) -> Quaternion { + fn get_delta_rot(inverse_inertia: Matrix3, p: Vector) -> Quaternion { // Equation 8/9 - Quaternion::from_vec4(0.5 * (inverse_inertia * p).extend(0.0)) * rot.0 + Quaternion::from_scaled_axis(inverse_inertia * p) } /// Computes the torque acting along the constraint using the equation `tau = lambda * n / h^2`, diff --git a/src/dynamics/solver/xpbd/positional_constraint.rs b/src/dynamics/solver/xpbd/positional_constraint.rs index 4c36ae16..4b0f997e 100644 --- a/src/dynamics/solver/xpbd/positional_constraint.rs +++ b/src/dynamics/solver/xpbd/positional_constraint.rs @@ -48,7 +48,7 @@ pub trait PositionConstraint: XpbdConstraint<2> { #[cfg(feature = "2d")] { - let delta_angle = Self::get_delta_rot(*body1.rotation, inv_inertia1, r1, impulse); + let delta_angle = Self::get_delta_rot(inv_inertia1, r1, impulse); *body1.rotation = body1.rotation.add_angle(delta_angle); } #[cfg(feature = "3d")] @@ -57,8 +57,9 @@ pub trait PositionConstraint: XpbdConstraint<2> { // which causes stability issues (see #235) and panics when trying to rotate unit vectors. // TODO: It would be nice to avoid normalization if possible. // Maybe the math above can be done in a way that keeps rotations normalized? - let delta_quat = Self::get_delta_rot(*body1.rotation, inv_inertia1, r1, impulse); - body1.rotation.0 = (body1.rotation.0 + delta_quat).normalize(); + let delta_quat = Self::get_delta_rot(inv_inertia1, r1, impulse); + body1.rotation.0 = delta_quat * body1.rotation.0; + body1.rotation.renormalize(); } } if body2.rb.is_dynamic() && body2.dominance() <= body1.dominance() { @@ -66,14 +67,15 @@ pub trait PositionConstraint: XpbdConstraint<2> { #[cfg(feature = "2d")] { - let delta_angle = Self::get_delta_rot(*body2.rotation, inv_inertia2, r2, -impulse); + let delta_angle = Self::get_delta_rot(inv_inertia2, r2, -impulse); *body2.rotation = body2.rotation.add_angle(delta_angle); } #[cfg(feature = "3d")] { // See comments for `body1` above. - let delta_quat = Self::get_delta_rot(*body2.rotation, inv_inertia2, r2, -impulse); - body2.rotation.0 = (body2.rotation.0 + delta_quat).normalize(); + let delta_quat = Self::get_delta_rot(inv_inertia2, r2, -impulse); + body2.rotation.0 = delta_quat * body2.rotation.0; + body2.rotation.renormalize(); } } @@ -122,16 +124,16 @@ pub trait PositionConstraint: XpbdConstraint<2> { /// Computes the update in rotation when applying a positional correction `p` at point `r`. #[cfg(feature = "2d")] - fn get_delta_rot(_rot: Rotation, inverse_inertia: Scalar, r: Vector, p: Vector) -> Scalar { + fn get_delta_rot(inverse_inertia: Scalar, r: Vector, p: Vector) -> Scalar { // Equation 8/9 but in 2D inverse_inertia * r.perp_dot(p) } /// Computes the update in rotation when applying a positional correction `p` at point `r`. #[cfg(feature = "3d")] - fn get_delta_rot(rot: Rotation, inverse_inertia: Matrix3, r: Vector, p: Vector) -> Quaternion { + fn get_delta_rot(inverse_inertia: Matrix3, r: Vector, p: Vector) -> Quaternion { // Equation 8/9 - Quaternion::from_vec4(0.5 * (inverse_inertia * r.cross(p)).extend(0.0)) * rot.0 + Quaternion::from_scaled_axis(inverse_inertia * r.cross(p)) } /// Computes the force acting along the constraint using the equation f = lambda * n / h^2 diff --git a/src/position.rs b/src/position.rs index 4909f12b..8d519f04 100644 --- a/src/position.rs +++ b/src/position.rs @@ -701,6 +701,15 @@ impl Rotation { pub fn slerp(self, end: Self, t: Scalar) -> Self { Self(self.0.slerp(end.0, t)) } + + /// Performs a renormalization of the contained quaternion + #[inline] + pub fn renormalize(&mut self) { + let length_squared = self.0.length_squared(); + // 1/L = (L^2)^-(1/2) = ~= 1 - (L^2 - 1) / 2 = (3 - L^2) / 2 + let approx_inv_length = 0.5 * (3.0 - length_squared); + self.0 = self.0 * approx_inv_length; + } } #[cfg(feature = "3d")]