@series-inc/rundot-syncplay 6.0.0-rc.2 → 6.0.0-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/core/native/physics/abi.cpp +34 -211
  2. package/core/native/physics/abi.hpp +0 -6
  3. package/core/native/physics/articulation.cpp +1434 -0
  4. package/core/native/physics/articulation.hpp +279 -0
  5. package/core/native/physics/buoyancy.cpp +1210 -0
  6. package/core/native/physics/buoyancy.hpp +206 -0
  7. package/core/native/physics/capsule_triangle.cpp +168 -0
  8. package/core/native/physics/capsule_triangle.hpp +40 -0
  9. package/core/native/physics/capsule_triangle_native.inc +271 -0
  10. package/core/native/physics/character.cpp +638 -0
  11. package/core/native/physics/character.hpp +169 -0
  12. package/core/native/physics/cloth.cpp +1401 -0
  13. package/core/native/physics/cloth.hpp +357 -0
  14. package/core/native/physics/constraint_rows.cpp +361 -0
  15. package/core/native/physics/constraint_rows.hpp +68 -0
  16. package/core/native/physics/deformable_query.cpp +1630 -0
  17. package/core/native/physics/deformable_query.hpp +578 -0
  18. package/core/native/physics/distance.cpp +1166 -0
  19. package/core/native/physics/distance.hpp +151 -0
  20. package/core/native/physics/exact/exact-applied.cpp +101 -0
  21. package/core/native/physics/exact/exact-applied.hpp +56 -0
  22. package/core/native/physics/exact/exact-dyadic.cpp +691 -0
  23. package/core/native/physics/exact/exact-dyadic.hpp +58 -0
  24. package/core/native/physics/exact/exact-operation.hpp +51 -0
  25. package/core/native/physics/exact/word-core.hpp +261 -0
  26. package/core/native/physics/extended_abi.cpp +1242 -0
  27. package/core/native/physics/extended_abi.hpp +355 -0
  28. package/core/native/physics/extended_abi_characters.cpp +261 -0
  29. package/core/native/physics/extended_abi_characters.hpp +434 -0
  30. package/core/native/physics/extended_abi_core_features.cpp +713 -0
  31. package/core/native/physics/extended_abi_core_features.hpp +226 -0
  32. package/core/native/physics/extended_abi_deformables.cpp +448 -0
  33. package/core/native/physics/extended_abi_deformables.hpp +867 -0
  34. package/core/native/physics/extended_abi_vehicles.cpp +411 -0
  35. package/core/native/physics/extended_abi_vehicles.hpp +222 -0
  36. package/core/native/physics/fracture.cpp +1981 -0
  37. package/core/native/physics/fracture.hpp +460 -0
  38. package/core/native/physics/gear.cpp +563 -0
  39. package/core/native/physics/gear.hpp +158 -0
  40. package/core/native/physics/geometry_memory.hpp +52 -0
  41. package/core/native/physics/geometry_store.cpp +314 -0
  42. package/core/native/physics/geometry_store.hpp +103 -0
  43. package/core/native/physics/lag_compensation.cpp +1626 -0
  44. package/core/native/physics/lag_compensation.hpp +405 -0
  45. package/core/native/physics/mass_properties.cpp +449 -0
  46. package/core/native/physics/mass_properties.hpp +23 -0
  47. package/core/native/physics/material_pose.hpp +680 -0
  48. package/core/native/physics/particles.cpp +1065 -0
  49. package/core/native/physics/particles.hpp +261 -0
  50. package/core/native/physics/path_joint.cpp +781 -0
  51. package/core/native/physics/path_joint.hpp +154 -0
  52. package/core/native/physics/physics.cpp +11925 -941
  53. package/core/native/physics/physics.hpp +96 -7
  54. package/core/native/physics/planar_deformable.cpp +2433 -0
  55. package/core/native/physics/planar_deformable.hpp +889 -0
  56. package/core/native/physics/platformer_2d.cpp +1353 -0
  57. package/core/native/physics/platformer_2d.hpp +340 -0
  58. package/core/native/physics/powered_ragdoll.cpp +1100 -0
  59. package/core/native/physics/powered_ragdoll.hpp +279 -0
  60. package/core/native/physics/powertrain.cpp +586 -0
  61. package/core/native/physics/powertrain.hpp +180 -0
  62. package/core/native/physics/pulley.cpp +311 -0
  63. package/core/native/physics/pulley.hpp +121 -0
  64. package/core/native/physics/ragdoll.cpp +586 -0
  65. package/core/native/physics/ragdoll.hpp +221 -0
  66. package/core/native/physics/rope.cpp +692 -0
  67. package/core/native/physics/rope.hpp +215 -0
  68. package/core/native/physics/rounded_convex.cpp +1229 -0
  69. package/core/native/physics/rounded_convex.hpp +287 -0
  70. package/core/native/physics/sdf_geometry.cpp +1821 -0
  71. package/core/native/physics/sdf_geometry.hpp +474 -0
  72. package/core/native/physics/soft_body.cpp +1449 -0
  73. package/core/native/physics/soft_body.hpp +328 -0
  74. package/core/native/physics/soft_collision.cpp +1862 -0
  75. package/core/native/physics/soft_collision.hpp +561 -0
  76. package/core/native/physics/surface_velocity.cpp +366 -0
  77. package/core/native/physics/surface_velocity.hpp +243 -0
  78. package/core/native/physics/topology.cpp +123 -33
  79. package/core/native/physics/topology.hpp +37 -4
  80. package/core/native/physics/tracks.cpp +1179 -0
  81. package/core/native/physics/tracks.hpp +404 -0
  82. package/core/native/physics/vehicle.cpp +629 -0
  83. package/core/native/physics/vehicle.hpp +191 -0
  84. package/core/native/physics/voxel_cooking.cpp +1929 -0
  85. package/core/native/physics/voxel_cooking.hpp +395 -0
  86. package/core/native/physics/world.cpp +1131 -391
  87. package/core/native/physics/world.hpp +87 -14
  88. package/core/native/physics/world_abi.cpp +430 -45
  89. package/core/native/physics/world_abi.hpp +72 -4
  90. package/core/native/physics2d/ccd.cpp +1173 -0
  91. package/core/native/physics2d/ccd.hpp +141 -0
  92. package/core/native/physics2d/clock_primitives.hpp +138 -0
  93. package/core/native/physics2d/commands.cpp +12 -4
  94. package/core/native/physics2d/commands.hpp +1 -1
  95. package/core/native/physics2d/compound.cpp +581 -0
  96. package/core/native/physics2d/compound.hpp +248 -0
  97. package/core/native/physics2d/frame_scope.hpp +124 -0
  98. package/core/native/physics2d/joint_phases.hpp +93 -0
  99. package/core/native/physics2d/joints.cpp +573 -127
  100. package/core/native/physics2d/joints.hpp +5 -0
  101. package/core/native/physics2d/owned_abi.cpp +28 -6
  102. package/core/native/physics2d/owned_abi.hpp +15 -10
  103. package/core/native/physics2d/phase_test_hooks.hpp +17 -0
  104. package/core/native/physics2d/physics2d.cpp +950 -71
  105. package/core/native/physics2d/physics2d.hpp +69 -2
  106. package/core/native/physics2d/queries.cpp +9 -2
  107. package/core/native/physics2d/queries.hpp +10 -2
  108. package/core/native/physics2d/world.cpp +379 -44
  109. package/core/native/physics2d/world.hpp +18 -5
  110. package/core/physics2d-owned.d.ts +185 -18
  111. package/core/scripts/build-native.mjs +22 -0
  112. package/core/scripts/build-wasm-physics.mjs +109 -8
  113. package/core/scripts/extended-physics-profile.mjs +634 -0
  114. package/core/src/kinetix-runtime-adapter-utils.mjs +10 -4
  115. package/core/src/kinetix-session-config.mjs +7 -2
  116. package/core/src/physics/abi-constants.mjs +4 -4
  117. package/core/src/physics/articulation.d.mts +194 -0
  118. package/core/src/physics/articulation.mjs +1141 -0
  119. package/core/src/physics/buoyancy.d.mts +66 -0
  120. package/core/src/physics/buoyancy.mjs +112 -0
  121. package/core/src/physics/cloth.d.mts +314 -0
  122. package/core/src/physics/cloth.mjs +1156 -0
  123. package/core/src/physics/deformable-query.d.mts +217 -0
  124. package/core/src/physics/deformable-query.mjs +1412 -0
  125. package/core/src/physics/distance.d.mts +7 -0
  126. package/core/src/physics/distance.mjs +175 -0
  127. package/core/src/physics/extended-wasm-instance.d.mts +5 -0
  128. package/core/src/physics/extended-wasm-instance.mjs +48 -0
  129. package/core/src/physics/feature-api.d.mts +646 -0
  130. package/core/src/physics/feature-api.mjs +98 -0
  131. package/core/src/physics/fracture.d.mts +133 -0
  132. package/core/src/physics/fracture.mjs +1324 -0
  133. package/core/src/physics/gear.d.mts +342 -0
  134. package/core/src/physics/gear.mjs +955 -0
  135. package/core/src/physics/lag-compensation.d.mts +101 -0
  136. package/core/src/physics/lag-compensation.mjs +1100 -0
  137. package/core/src/physics/mass-properties.d.mts +3 -0
  138. package/core/src/physics/mass-properties.mjs +137 -468
  139. package/core/src/physics/particles.d.mts +177 -0
  140. package/core/src/physics/particles.mjs +758 -0
  141. package/core/src/physics/path-joint.d.mts +171 -0
  142. package/core/src/physics/path-joint.mjs +1231 -0
  143. package/core/src/physics/physics-extended-wasm-module.generated.mjs +13 -0
  144. package/core/src/physics/physics-wasm-module.generated.mjs +6 -5
  145. package/core/src/physics/powered-ragdoll.d.mts +188 -0
  146. package/core/src/physics/powered-ragdoll.mjs +1043 -0
  147. package/core/src/physics/powertrain.d.mts +230 -0
  148. package/core/src/physics/powertrain.mjs +621 -0
  149. package/core/src/physics/pulley.d.mts +355 -0
  150. package/core/src/physics/pulley.mjs +686 -0
  151. package/core/src/physics/ragdoll.d.mts +289 -0
  152. package/core/src/physics/ragdoll.mjs +1323 -0
  153. package/core/src/physics/rope.d.mts +40 -0
  154. package/core/src/physics/rope.mjs +319 -0
  155. package/core/src/physics/rounded-convex.d.mts +328 -0
  156. package/core/src/physics/rounded-convex.mjs +1404 -0
  157. package/core/src/physics/sdf-geometry.d.mts +117 -0
  158. package/core/src/physics/sdf-geometry.mjs +1204 -0
  159. package/core/src/physics/soft-body.d.mts +144 -0
  160. package/core/src/physics/soft-body.mjs +1285 -0
  161. package/core/src/physics/soft-collision.d.mts +651 -0
  162. package/core/src/physics/soft-collision.mjs +1883 -0
  163. package/core/src/physics/surface-velocity.d.mts +200 -0
  164. package/core/src/physics/surface-velocity.mjs +722 -0
  165. package/core/src/physics/tracks.d.mts +411 -0
  166. package/core/src/physics/tracks.mjs +1074 -0
  167. package/core/src/physics/vehicle.d.mts +3 -0
  168. package/core/src/physics/vehicle.mjs +172 -0
  169. package/core/src/physics/voxel-cooking.d.mts +203 -0
  170. package/core/src/physics/voxel-cooking.mjs +1430 -0
  171. package/core/src/physics/wasm-instance.mjs +21 -0
  172. package/core/src/physics/world.mjs +250 -23
  173. package/core/src/physics2d/body-state.mjs +178 -15
  174. package/core/src/physics2d/collision.d.mts +50 -0
  175. package/core/src/physics2d/collision.mjs +198 -0
  176. package/core/src/physics2d/compound.mjs +454 -0
  177. package/core/src/physics2d/feature-api.d.mts +5 -0
  178. package/core/src/physics2d/feature-api.mjs +3 -0
  179. package/core/src/physics2d/fluid-state.mjs +145 -0
  180. package/core/src/physics2d/joint-state.mjs +1 -1
  181. package/core/src/physics2d/owned-transport.mjs +28 -14
  182. package/core/src/physics2d/owned-world.mjs +160 -177
  183. package/core/src/physics2d/particle-fluid.d.mts +43 -0
  184. package/core/src/physics2d/particle-fluid.mjs +197 -0
  185. package/core/src/physics2d/physics2d-wasm-module.generated.mjs +10 -10
  186. package/core/src/physics2d/query-codec.mjs +21 -7
  187. package/core/src/physics2d/submerged-geometry.d.mts +32 -0
  188. package/core/src/physics2d/submerged-geometry.mjs +186 -0
  189. package/core/world.d.ts +50 -3
  190. package/dist/authority-room.js +5 -1
  191. package/dist/collider-cooking-hull.d.ts +18 -0
  192. package/dist/collider-cooking-hull.js +248 -0
  193. package/dist/collider-cooking.d.ts +140 -0
  194. package/dist/collider-cooking.js +794 -0
  195. package/dist/compat/v5.d.ts +117 -0
  196. package/dist/compat/v5.js +436 -0
  197. package/dist/movement3d.js +30 -15
  198. package/dist/physics/2d.d.ts +20 -1
  199. package/dist/physics/2d.js +29 -33
  200. package/dist/physics/3d.d.ts +302 -7
  201. package/dist/physics/3d.js +1006 -22
  202. package/dist/run-room-transport.js +5 -1
  203. package/dist/runtime-room-metadata.js +5 -1
  204. package/dist/runtime-session.js +5 -1
  205. package/dist/session-wire.js +6 -2
  206. package/package.json +8 -2
  207. package/core/scripts/run-box3d-benchmark.mjs +0 -350
  208. package/core/src/physics/index.mjs +0 -3169
@@ -173,9 +173,10 @@ namespace {
173
173
 
174
174
  using namespace rundot::kinetix::physics;
175
175
 
176
- static std::array<SixDofC, kMaxSixDofCapacity> g_sixDofConstraints{};
176
+ static std::array<SixDofConstraint, kMaxSixDofCapacity> g_sixDofConstraints{};
177
177
  static std::array<std::uint32_t, kMaxSixDofCapacity> g_sixDofOffsets{};
178
178
  static std::array<std::uint32_t, kMaxSixDofCapacity> g_sixDofLogicalIndices{};
179
+ static std::array<SixDofConstraintOutput, kMaxSixDofCapacity> g_sixDofOutputs{};
179
180
  static std::array<double, kMaxStandardJointCapacity * kJointStride> g_standardJoints{};
180
181
  static std::array<std::uint32_t, kMaxStandardJointCapacity> g_standardLogicalIndices{};
181
182
 
@@ -186,29 +187,6 @@ struct StandardJointAccumulator {
186
187
  };
187
188
  static std::array<StandardJointAccumulator, kMaxStandardJointCapacity> g_standardAccumulators{};
188
189
  static std::array<Body, 4096> g_bodies{};
189
- static std::array<ConstraintBodyMobility, 4096> g_mobility{};
190
-
191
- struct SixDofAccumulator {
192
- std::array<double, 6> limitImpulse{};
193
- std::array<double, 6> motorImpulse{};
194
- std::array<double, 6> springImpulse{};
195
- std::array<bool, 6> limitEngaged{};
196
- std::array<bool, 6> motorActive{};
197
- };
198
- static std::array<SixDofAccumulator, kMaxSixDofCapacity> g_accumulators{};
199
-
200
- // Must match kMaxSixDofRows in constraint_rows.hpp, which is what
201
- // buildSixDofRows can actually emit. This was 12 while the builder produced up to 18,
202
- // so a joint with a limit, a motor and a spring on all six axes lost its last rows in
203
- // silence and those axes moved unconstrained.
204
- constexpr std::uint32_t kMaxSixDofRows = 18;
205
- struct JointRange {
206
- std::uint32_t start = 0;
207
- std::uint32_t count = 0;
208
- };
209
- static std::array<JointRange, kMaxSixDofCapacity> g_ranges{};
210
- static std::array<ConstraintRow6, kMaxSixDofCapacity * kMaxSixDofRows> g_rows{};
211
- static std::array<SixDofMeta, kMaxSixDofCapacity * kMaxSixDofRows> g_meta{};
212
190
 
213
191
  struct Vec3 {
214
192
  double x = 0.0;
@@ -324,91 +302,8 @@ Body unpackBody(const double* bodyData, std::uint32_t offset) {
324
302
  return body;
325
303
  }
326
304
 
327
- void packBody(double* bodyData, std::uint32_t offset, const Body& body) {
328
- bodyData[offset + 0] = body.x;
329
- bodyData[offset + 1] = body.y;
330
- bodyData[offset + 2] = body.z;
331
- bodyData[offset + 3] = body.vx;
332
- bodyData[offset + 4] = body.vy;
333
- bodyData[offset + 5] = body.vz;
334
- const std::uint32_t motionKind = body.dynamic ? 1u : (body.kinematic ? 2u : 0u);
335
- const std::uint32_t motion = motionKind
336
- | (body.trigger ? kMotionTrigger : 0u)
337
- | (body.sensor ? kMotionSensor : 0u)
338
- | (body.sleeping ? kMotionSleeping : 0u)
339
- | (body.angularState ? kMotionAngularState : 0u);
340
- bodyData[offset + 9] = static_cast<double>(motion);
341
- bodyData[offset + 19] = body.angularVelX;
342
- bodyData[offset + 20] = body.angularVelY;
343
- bodyData[offset + 21] = body.angularVelZ;
344
- bodyData[offset + 22] = body.orientationX;
345
- bodyData[offset + 23] = body.orientationY;
346
- bodyData[offset + 24] = body.orientationZ;
347
- bodyData[offset + 25] = body.orientationW;
348
- bodyData[offset + 40] = body.sleepThreshold;
349
- bodyData[offset + 41] = body.sleepEnabled ? 1.0 : 0.0;
350
- bodyData[offset + 42] = body.sleepTime;
351
- bodyData[offset + 43] = body.rollingResistance;
352
- }
353
-
354
- void integrateOrientationStep(Body& body, double timeStep) {
355
- const double halfStep = 0.5 * timeStep;
356
- const double qx = body.orientationX;
357
- const double qy = body.orientationY;
358
- const double qz = body.orientationZ;
359
- const double qw = body.orientationW;
360
- const double wx = body.angularVelX;
361
- const double wy = body.angularVelY;
362
- const double wz = body.angularVelZ;
363
- body.orientationX = qx + halfStep * (wx * qw + wy * qz - wz * qy);
364
- body.orientationY = qy + halfStep * (-wx * qz + wy * qw + wz * qx);
365
- body.orientationZ = qz + halfStep * (wx * qy - wy * qx + wz * qw);
366
- body.orientationW = qw + halfStep * (-wx * qx - wy * qy - wz * qz);
367
- const double lengthSquared = body.orientationX * body.orientationX
368
- + body.orientationY * body.orientationY
369
- + body.orientationZ * body.orientationZ
370
- + body.orientationW * body.orientationW;
371
- if (lengthSquared > 0.0) {
372
- const double invLen = 1.0 / std::sqrt(lengthSquared);
373
- body.orientationX *= invLen;
374
- body.orientationY *= invLen;
375
- body.orientationZ *= invLen;
376
- body.orientationW *= invLen;
377
- }
378
- }
379
-
380
- void finalizeBody(Body& body, const StepOptions& options) {
381
- if ((!body.dynamic && !body.kinematic) || (body.dynamic && body.sleeping)) return;
382
- if (body.dynamic) {
383
- body.vx = quantizeDistance(body.vx * body.linearDamping);
384
- body.vy = quantizeDistance(body.vy * body.linearDamping);
385
- body.vz = quantizeDistance(body.vz * body.linearDamping);
386
- body.angularVelX = quantizeDistance(body.angularVelX * body.angularDamping);
387
- body.angularVelY = quantizeDistance(body.angularVelY * body.angularDamping);
388
- body.angularVelZ = quantizeDistance(body.angularVelZ * body.angularDamping);
389
- }
390
- if ((body.motionLocks & (1u << 0)) != 0) body.vx = 0.0;
391
- if ((body.motionLocks & (1u << 1)) != 0) body.vy = 0.0;
392
- if ((body.motionLocks & (1u << 2)) != 0) body.vz = 0.0;
393
- if ((body.motionLocks & (1u << 3)) != 0) body.angularVelX = 0.0;
394
- if ((body.motionLocks & (1u << 4)) != 0) body.angularVelY = 0.0;
395
- if ((body.motionLocks & (1u << 5)) != 0) body.angularVelZ = 0.0;
396
- if (body.dynamic && options.maximumLinearSpeed > 0.0) {
397
- const double speed = std::sqrt(body.vx * body.vx + body.vy * body.vy + body.vz * body.vz);
398
- if (speed > options.maximumLinearSpeed) {
399
- const double scale = options.maximumLinearSpeed / speed;
400
- body.vx *= scale;
401
- body.vy *= scale;
402
- body.vz *= scale;
403
- }
404
- }
405
- body.x = quantizeDistance(body.x);
406
- body.y = quantizeDistance(body.y);
407
- body.z = quantizeDistance(body.z);
408
- }
409
-
410
305
  void computeAxisStates(
411
- const SixDofC& constraint,
306
+ const SixDofConstraint& constraint,
412
307
  const Body& bodyA,
413
308
  const Body& bodyB,
414
309
  std::array<double, 6>& positions,
@@ -474,65 +369,6 @@ void computeAxisStates(
474
369
  }
475
370
  }
476
371
 
477
- // Solves the six-DOF rows once per substep, at the substep timestep, from inside the
478
- // standard step's loop. Doing it here means the impulse reaches velocity before
479
- // integrateBodyPosition runs, so no position patch is needed afterwards.
480
- struct SixDofSubstepState {
481
- std::uint32_t constraintCount = 0;
482
- std::uint32_t velocityIterations = 1;
483
- };
484
-
485
- void solveSixDofSubstep(Body* bodies, std::uint32_t bodyCount, double substepDt, void* user) {
486
- auto* state = static_cast<SixDofSubstepState*>(user);
487
- if (state == nullptr || state->constraintCount == 0 || bodyCount == 0) return;
488
-
489
- for (std::uint32_t i = 0; i < bodyCount; ++i) {
490
- g_mobility[i] = constraintBodyMobility(bodies[i]);
491
- }
492
-
493
- std::span<Body> bodySpan(bodies, bodyCount);
494
- std::uint32_t totalRows = 0;
495
- for (std::uint32_t j = 0; j < state->constraintCount; ++j) {
496
- g_ranges[j].start = totalRows;
497
- std::span<ConstraintRow6> rSpan(g_rows.data() + totalRows, kMaxSixDofRows);
498
- std::span<SixDofMeta> mSpan(g_meta.data() + totalRows, kMaxSixDofRows);
499
- const std::uint32_t built = buildSixDofRows(
500
- g_sixDofConstraints[j],
501
- bodies[g_sixDofConstraints[j].bodyA],
502
- bodies[g_sixDofConstraints[j].bodyB],
503
- substepDt,
504
- rSpan,
505
- mSpan);
506
- g_ranges[j].count = built;
507
- totalRows += built;
508
- }
509
-
510
- for (std::uint32_t r = 0; r < totalRows; ++r) prepareConstraintRow(g_rows[r], g_mobility);
511
- for (std::uint32_t iter = 0; iter < state->velocityIterations; ++iter) {
512
- for (std::uint32_t r = 0; r < totalRows; ++r) solveConstraintRow(g_rows[r], bodySpan, g_mobility);
513
- }
514
-
515
- for (std::uint32_t j = 0; j < state->constraintCount; ++j) {
516
- for (std::uint32_t r = g_ranges[j].start; r < g_ranges[j].start + g_ranges[j].count; ++r) {
517
- const std::uint8_t a = g_meta[r].axisIndex;
518
- const double imp = g_rows[r].scalar.accumulatedImpulse;
519
- using K = SixDofRowKind;
520
- const auto kind = g_meta[r].kind;
521
- if (kind == K::LinearLock || kind == K::LinearLowerLimit || kind == K::LinearUpperLimit
522
- || kind == K::LinearEqualLimit || kind == K::AngularLock || kind == K::AngularLowerLimit
523
- || kind == K::AngularUpperLimit || kind == K::AngularEqualLimit) {
524
- g_accumulators[j].limitEngaged[a] = true;
525
- g_accumulators[j].limitImpulse[a] += imp;
526
- } else if (kind == K::LinearMotor || kind == K::AngularMotor) {
527
- g_accumulators[j].motorActive[a] = true;
528
- g_accumulators[j].motorImpulse[a] += imp;
529
- } else if (kind == K::LinearSpring || kind == K::AngularSpring) {
530
- g_accumulators[j].springImpulse[a] += imp;
531
- }
532
- }
533
- }
534
- }
535
-
536
372
  std::int32_t stepSoAWithSixDofJoints(
537
373
  double* body_data,
538
374
  std::uint32_t body_count,
@@ -558,8 +394,8 @@ std::int32_t stepSoAWithSixDofJoints(
558
394
  if (bAVal < 0.0 || bBVal < 0.0 || bAVal >= body_count || bBVal >= body_count || bAVal == bBVal) {
559
395
  return 3;
560
396
  }
561
- SixDofC& c = g_sixDofConstraints[sixDofCount];
562
- c = SixDofC{};
397
+ SixDofConstraint& c = g_sixDofConstraints[sixDofCount];
398
+ c = SixDofConstraint{};
563
399
  c.bodyA = static_cast<std::uint32_t>(bAVal);
564
400
  c.bodyB = static_cast<std::uint32_t>(bBVal);
565
401
  c.anchorA = {joint_data[offset + 3], joint_data[offset + 4], joint_data[offset + 5]};
@@ -580,6 +416,8 @@ std::int32_t stepSoAWithSixDofJoints(
580
416
  joint_data[offset + 14], joint_data[offset + 15],
581
417
  joint_data[offset + 16], joint_data[offset + 17]
582
418
  };
419
+ c.maximumLinearForce = joint_data[offset + 92];
420
+ c.maximumAngularTorque = joint_data[offset + 93];
583
421
  for (std::uint32_t a = 0; a < 6; ++a) {
584
422
  std::uint32_t m = static_cast<std::uint32_t>(joint_data[offset + 18 + a]);
585
423
  c.axes[a].limit.mode = m == 1 ? SixDofAxisMode::Locked
@@ -606,7 +444,7 @@ std::int32_t stepSoAWithSixDofJoints(
606
444
 
607
445
  g_sixDofOffsets[sixDofCount] = offset;
608
446
  g_sixDofLogicalIndices[sixDofCount] = logicalIndex;
609
- g_accumulators[sixDofCount] = SixDofAccumulator{};
447
+ g_sixDofOutputs[sixDofCount] = SixDofConstraintOutput{};
610
448
  sixDofCount += 1;
611
449
  offset += slots * kJointStride;
612
450
  } else if (kindVal >= 1.0 && kindVal <= 9.0) {
@@ -622,30 +460,24 @@ std::int32_t stepSoAWithSixDofJoints(
622
460
  logicalIndex += 1;
623
461
  }
624
462
 
625
- const std::uint32_t substeps = std::max(1u, options.substeps);
626
- const std::uint32_t velocity_iterations = std::max(1u, options.velocityIterations);
627
- const double substepDt = options.dtTicks / static_cast<double>(substeps);
628
-
629
- // A six-DOF joint never reaches stepSoAWithJoints, so it takes no part in wake
630
- // propagation or sleep islands. A sleeping body joined to an awake body by a locked
631
- // axis therefore stayed still and stayed asleep. Wake the pair conservatively here.
463
+ std::array<std::array<std::uint32_t, 2>, kMaxSixDofCapacity> connections{};
464
+ std::array<std::array<std::uint32_t, 2>, kMaxSixDofCapacity> collisionExclusions{};
465
+ std::uint32_t collisionExclusionCount = 0;
632
466
  for (std::uint32_t j = 0; j < sixDofCount; ++j) {
633
- const std::uint32_t a = g_sixDofConstraints[j].bodyA;
634
- const std::uint32_t b = g_sixDofConstraints[j].bodyB;
635
- if (a >= body_count || b >= body_count) continue;
636
- double* rowA = body_data + a * kBodyStride;
637
- double* rowB = body_data + b * kBodyStride;
638
- const bool aSleeping = (static_cast<std::uint32_t>(rowA[9]) & kMotionSleeping) != 0;
639
- const bool bSleeping = (static_cast<std::uint32_t>(rowB[9]) & kMotionSleeping) != 0;
640
- if (aSleeping == bSleeping) continue;
641
- double* wake = aSleeping ? rowA : rowB;
642
- wake[9] = static_cast<double>(static_cast<std::uint32_t>(wake[9]) & ~kMotionSleeping);
643
- wake[42] = 0.0;
467
+ connections[j] = {g_sixDofConstraints[j].bodyA, g_sixDofConstraints[j].bodyB};
468
+ if (joint_data[g_sixDofOffsets[j] + 98] == 1.0) {
469
+ collisionExclusions[collisionExclusionCount++] = connections[j];
470
+ }
644
471
  }
645
472
 
646
- SixDofSubstepState sixDofState{sixDofCount, velocity_iterations};
473
+ SixDofSubstepParticipant sixDofParticipant{
474
+ {g_sixDofConstraints.data(), sixDofCount},
475
+ {g_sixDofOutputs.data(), sixDofCount},
476
+ true};
647
477
  const rundot::kinetix::physics::SubstepConstraintHook sixDofHook{
648
- sixDofCount > 0 ? &solveSixDofSubstep : nullptr, &sixDofState};
478
+ sixDofCount > 0 ? &SixDofSubstepParticipant::invoke : nullptr, &sixDofParticipant,
479
+ {connections.data(), sixDofCount},
480
+ {collisionExclusions.data(), collisionExclusionCount}};
649
481
 
650
482
  std::int32_t status = standardCount > 0
651
483
  ? rundot::kinetix::physics::stepSoAWithJoints(
@@ -670,10 +502,6 @@ std::int32_t stepSoAWithSixDofJoints(
670
502
  }
671
503
  }
672
504
 
673
- // The six-DOF rows were solved inside the substep loop by solveSixDofSubstep, so
674
- // there is no full-step post-pass and no `dv * stepDt` position patch any more.
675
- // Refresh the local body copies purely so the telemetry export below can read the
676
- // final state.
677
505
  for (std::uint32_t i = 0; i < body_count; ++i) {
678
506
  g_bodies[i] = unpackBody(body_data, i * kBodyStride);
679
507
  }
@@ -693,24 +521,19 @@ std::int32_t stepSoAWithSixDofJoints(
693
521
  for (std::uint32_t a = 0; a < 6; ++a) {
694
522
  mutJointData[off2 + 0 + a] = pos[a];
695
523
  mutJointData[off2 + 6 + a] = vel[a];
696
- mutJointData[off2 + 12 + a] = g_accumulators[j].limitEngaged[a] ? 1.0 : 0.0;
697
- mutJointData[off2 + 18 + a] = g_accumulators[j].limitImpulse[a];
698
- mutJointData[off2 + 24 + a] = g_accumulators[j].motorActive[a] ? 1.0 : 0.0;
699
- mutJointData[off2 + 30 + a] = g_accumulators[j].motorImpulse[a];
700
- mutJointData[off2 + 36 + a] = g_accumulators[j].springImpulse[a];
701
- mutJointData[off2 + 42 + a] = g_accumulators[j].limitImpulse[a]
702
- + g_accumulators[j].motorImpulse[a] + g_accumulators[j].springImpulse[a];
524
+ mutJointData[off2 + 12 + a] = g_sixDofOutputs[j].limitEngaged[a] ? 1.0 : 0.0;
525
+ mutJointData[off2 + 18 + a] = g_sixDofOutputs[j].limitImpulse[a];
526
+ mutJointData[off2 + 24 + a] = g_sixDofOutputs[j].motorActive[a] ? 1.0 : 0.0;
527
+ mutJointData[off2 + 30 + a] = g_sixDofOutputs[j].motorImpulse[a];
528
+ mutJointData[off2 + 36 + a] = g_sixDofOutputs[j].springImpulse[a];
529
+ mutJointData[off2 + 42 + a] = g_sixDofOutputs[j].limitImpulse[a]
530
+ + g_sixDofOutputs[j].motorImpulse[a] + g_sixDofOutputs[j].springImpulse[a];
703
531
  }
704
- const double linLen = std::sqrt(
705
- mutJointData[off2 + 42] * mutJointData[off2 + 42] +
706
- mutJointData[off2 + 43] * mutJointData[off2 + 43] +
707
- mutJointData[off2 + 44] * mutJointData[off2 + 44]);
708
- const double angLen = std::sqrt(
709
- mutJointData[off2 + 45] * mutJointData[off2 + 45] +
710
- mutJointData[off2 + 46] * mutJointData[off2 + 46] +
711
- mutJointData[off2 + 47] * mutJointData[off2 + 47]);
712
- mutJointData[off2 + 48] = linLen;
713
- mutJointData[off2 + 49] = angLen;
532
+ std::array<double, 2> magnitudes{};
533
+ if (sixDofReactionMagnitudes(g_sixDofOutputs[j], magnitudes)
534
+ != SixDofResponseStatus::Success) return 7;
535
+ mutJointData[off2 + 48] = magnitudes[0];
536
+ mutJointData[off2 + 49] = magnitudes[1];
714
537
  }
715
538
 
716
539
  g_customTelemetryCount = standardCount + sixDofCount;
@@ -5,12 +5,6 @@
5
5
  #include "physics.hpp"
6
6
  #include "constraint_rows.hpp"
7
7
 
8
- namespace rundot::kinetix::physics {
9
- using SixDofC = SixDofConstraint;
10
- using SixDofMeta = SixDofConstraintRowMetadata;
11
- constexpr auto buildSixDofRows = buildSixDofConstraintRows;
12
- }
13
-
14
8
  extern "C" {
15
9
 
16
10
  std::uint32_t rundot_kinetix_physics_abi_version();