@bloomengine/engine 0.3.1

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 (562) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +169 -0
  3. package/native/android/Cargo.lock +1848 -0
  4. package/native/android/Cargo.toml +20 -0
  5. package/native/android/src/lib.rs +1747 -0
  6. package/native/ios/Cargo.lock +1688 -0
  7. package/native/ios/Cargo.toml +19 -0
  8. package/native/ios/src/lib.rs +2258 -0
  9. package/native/linux/Cargo.lock +1719 -0
  10. package/native/linux/Cargo.toml +22 -0
  11. package/native/linux/src/lib.rs +2236 -0
  12. package/native/macos/Cargo.lock +3310 -0
  13. package/native/macos/Cargo.toml +29 -0
  14. package/native/macos/src/lib.rs +3444 -0
  15. package/native/shared/Cargo.lock +1898 -0
  16. package/native/shared/Cargo.toml +42 -0
  17. package/native/shared/assets/default_font.ttf +0 -0
  18. package/native/shared/build.rs +77 -0
  19. package/native/shared/shaders/common/fog.wgsl +16 -0
  20. package/native/shared/shaders/common/imposter.wgsl +112 -0
  21. package/native/shared/shaders/common/pbr.wgsl +186 -0
  22. package/native/shared/shaders/common/shadows.wgsl +77 -0
  23. package/native/shared/shaders/common/sky.wgsl +8 -0
  24. package/native/shared/shaders/common/tonemap.wgsl +25 -0
  25. package/native/shared/shaders/impulse_field.wgsl +53 -0
  26. package/native/shared/shaders/material_abi.wgsl +360 -0
  27. package/native/shared/shaders/materials/test_minimal.wgsl +42 -0
  28. package/native/shared/src/audio.rs +363 -0
  29. package/native/shared/src/custom_shaders.rs +104 -0
  30. package/native/shared/src/drs.rs +211 -0
  31. package/native/shared/src/engine.rs +186 -0
  32. package/native/shared/src/frame_callbacks.rs +88 -0
  33. package/native/shared/src/geometry.rs +236 -0
  34. package/native/shared/src/handles.rs +76 -0
  35. package/native/shared/src/input.rs +273 -0
  36. package/native/shared/src/jolt_sys.rs +822 -0
  37. package/native/shared/src/lib.rs +43 -0
  38. package/native/shared/src/models.rs +1941 -0
  39. package/native/shared/src/physics_jolt.rs +1528 -0
  40. package/native/shared/src/picking.rs +298 -0
  41. package/native/shared/src/postfx.rs +339 -0
  42. package/native/shared/src/profiler.rs +416 -0
  43. package/native/shared/src/renderer/atmosphere_lut.rs +573 -0
  44. package/native/shared/src/renderer/brdf_lut.rs +154 -0
  45. package/native/shared/src/renderer/formats.rs +778 -0
  46. package/native/shared/src/renderer/graph.rs +465 -0
  47. package/native/shared/src/renderer/hot_reload.rs +390 -0
  48. package/native/shared/src/renderer/impulse_field.rs +455 -0
  49. package/native/shared/src/renderer/material_pipeline.rs +604 -0
  50. package/native/shared/src/renderer/material_system.rs +2106 -0
  51. package/native/shared/src/renderer/mod.rs +13923 -0
  52. package/native/shared/src/renderer/planar_reflection.rs +458 -0
  53. package/native/shared/src/renderer/post_pass.rs +249 -0
  54. package/native/shared/src/renderer/shader_include.rs +205 -0
  55. package/native/shared/src/renderer/shader_library.rs +134 -0
  56. package/native/shared/src/renderer/shaders.rs +5855 -0
  57. package/native/shared/src/renderer/transient.rs +576 -0
  58. package/native/shared/src/renderer/types.rs +259 -0
  59. package/native/shared/src/renderer/util.rs +151 -0
  60. package/native/shared/src/scene.rs +1066 -0
  61. package/native/shared/src/sdf_cache.rs +274 -0
  62. package/native/shared/src/shadows.rs +551 -0
  63. package/native/shared/src/staging.rs +90 -0
  64. package/native/shared/src/string_header.rs +35 -0
  65. package/native/shared/src/text_renderer.rs +456 -0
  66. package/native/shared/src/textures.rs +154 -0
  67. package/native/third_party/JoltPhysics/Jolt/AABBTree/AABBTreeBuilder.cpp +242 -0
  68. package/native/third_party/JoltPhysics/Jolt/AABBTree/AABBTreeBuilder.h +121 -0
  69. package/native/third_party/JoltPhysics/Jolt/AABBTree/AABBTreeToBuffer.h +296 -0
  70. package/native/third_party/JoltPhysics/Jolt/AABBTree/NodeCodec/NodeCodecQuadTreeHalfFloat.h +323 -0
  71. package/native/third_party/JoltPhysics/Jolt/AABBTree/TriangleCodec/TriangleCodecIndexed8BitPackSOA4Flags.h +555 -0
  72. package/native/third_party/JoltPhysics/Jolt/ConfigurationString.h +112 -0
  73. package/native/third_party/JoltPhysics/Jolt/Core/ARMNeon.h +94 -0
  74. package/native/third_party/JoltPhysics/Jolt/Core/Array.h +713 -0
  75. package/native/third_party/JoltPhysics/Jolt/Core/Atomics.h +44 -0
  76. package/native/third_party/JoltPhysics/Jolt/Core/BinaryHeap.h +96 -0
  77. package/native/third_party/JoltPhysics/Jolt/Core/ByteBuffer.h +74 -0
  78. package/native/third_party/JoltPhysics/Jolt/Core/Color.cpp +38 -0
  79. package/native/third_party/JoltPhysics/Jolt/Core/Color.h +98 -0
  80. package/native/third_party/JoltPhysics/Jolt/Core/Core.h +652 -0
  81. package/native/third_party/JoltPhysics/Jolt/Core/FPControlWord.h +143 -0
  82. package/native/third_party/JoltPhysics/Jolt/Core/FPException.h +96 -0
  83. package/native/third_party/JoltPhysics/Jolt/Core/FPFlushDenormals.h +43 -0
  84. package/native/third_party/JoltPhysics/Jolt/Core/Factory.cpp +92 -0
  85. package/native/third_party/JoltPhysics/Jolt/Core/Factory.h +54 -0
  86. package/native/third_party/JoltPhysics/Jolt/Core/FixedSizeFreeList.h +122 -0
  87. package/native/third_party/JoltPhysics/Jolt/Core/FixedSizeFreeList.inl +215 -0
  88. package/native/third_party/JoltPhysics/Jolt/Core/HashCombine.h +234 -0
  89. package/native/third_party/JoltPhysics/Jolt/Core/HashTable.h +876 -0
  90. package/native/third_party/JoltPhysics/Jolt/Core/InsertionSort.h +58 -0
  91. package/native/third_party/JoltPhysics/Jolt/Core/IssueReporting.cpp +27 -0
  92. package/native/third_party/JoltPhysics/Jolt/Core/IssueReporting.h +38 -0
  93. package/native/third_party/JoltPhysics/Jolt/Core/JobSystem.h +311 -0
  94. package/native/third_party/JoltPhysics/Jolt/Core/JobSystem.inl +56 -0
  95. package/native/third_party/JoltPhysics/Jolt/Core/JobSystemSingleThreaded.cpp +65 -0
  96. package/native/third_party/JoltPhysics/Jolt/Core/JobSystemSingleThreaded.h +62 -0
  97. package/native/third_party/JoltPhysics/Jolt/Core/JobSystemThreadPool.cpp +364 -0
  98. package/native/third_party/JoltPhysics/Jolt/Core/JobSystemThreadPool.h +101 -0
  99. package/native/third_party/JoltPhysics/Jolt/Core/JobSystemWithBarrier.cpp +230 -0
  100. package/native/third_party/JoltPhysics/Jolt/Core/JobSystemWithBarrier.h +85 -0
  101. package/native/third_party/JoltPhysics/Jolt/Core/LinearCurve.cpp +51 -0
  102. package/native/third_party/JoltPhysics/Jolt/Core/LinearCurve.h +67 -0
  103. package/native/third_party/JoltPhysics/Jolt/Core/LockFreeHashMap.h +182 -0
  104. package/native/third_party/JoltPhysics/Jolt/Core/LockFreeHashMap.inl +351 -0
  105. package/native/third_party/JoltPhysics/Jolt/Core/Memory.cpp +85 -0
  106. package/native/third_party/JoltPhysics/Jolt/Core/Memory.h +85 -0
  107. package/native/third_party/JoltPhysics/Jolt/Core/Mutex.h +223 -0
  108. package/native/third_party/JoltPhysics/Jolt/Core/MutexArray.h +98 -0
  109. package/native/third_party/JoltPhysics/Jolt/Core/NonCopyable.h +18 -0
  110. package/native/third_party/JoltPhysics/Jolt/Core/Profiler.cpp +677 -0
  111. package/native/third_party/JoltPhysics/Jolt/Core/Profiler.h +301 -0
  112. package/native/third_party/JoltPhysics/Jolt/Core/Profiler.inl +90 -0
  113. package/native/third_party/JoltPhysics/Jolt/Core/QuickSort.h +137 -0
  114. package/native/third_party/JoltPhysics/Jolt/Core/RTTI.cpp +149 -0
  115. package/native/third_party/JoltPhysics/Jolt/Core/RTTI.h +436 -0
  116. package/native/third_party/JoltPhysics/Jolt/Core/Reference.h +244 -0
  117. package/native/third_party/JoltPhysics/Jolt/Core/Result.h +174 -0
  118. package/native/third_party/JoltPhysics/Jolt/Core/STLAlignedAllocator.h +72 -0
  119. package/native/third_party/JoltPhysics/Jolt/Core/STLAllocator.h +127 -0
  120. package/native/third_party/JoltPhysics/Jolt/Core/STLLocalAllocator.h +170 -0
  121. package/native/third_party/JoltPhysics/Jolt/Core/STLTempAllocator.h +80 -0
  122. package/native/third_party/JoltPhysics/Jolt/Core/ScopeExit.h +49 -0
  123. package/native/third_party/JoltPhysics/Jolt/Core/Semaphore.cpp +135 -0
  124. package/native/third_party/JoltPhysics/Jolt/Core/Semaphore.h +68 -0
  125. package/native/third_party/JoltPhysics/Jolt/Core/StaticArray.h +329 -0
  126. package/native/third_party/JoltPhysics/Jolt/Core/StreamIn.h +120 -0
  127. package/native/third_party/JoltPhysics/Jolt/Core/StreamOut.h +97 -0
  128. package/native/third_party/JoltPhysics/Jolt/Core/StreamUtils.h +168 -0
  129. package/native/third_party/JoltPhysics/Jolt/Core/StreamWrapper.h +53 -0
  130. package/native/third_party/JoltPhysics/Jolt/Core/StridedPtr.h +63 -0
  131. package/native/third_party/JoltPhysics/Jolt/Core/StringTools.cpp +101 -0
  132. package/native/third_party/JoltPhysics/Jolt/Core/StringTools.h +38 -0
  133. package/native/third_party/JoltPhysics/Jolt/Core/TempAllocator.h +209 -0
  134. package/native/third_party/JoltPhysics/Jolt/Core/TickCounter.cpp +37 -0
  135. package/native/third_party/JoltPhysics/Jolt/Core/TickCounter.h +58 -0
  136. package/native/third_party/JoltPhysics/Jolt/Core/UnorderedMap.h +80 -0
  137. package/native/third_party/JoltPhysics/Jolt/Core/UnorderedSet.h +32 -0
  138. package/native/third_party/JoltPhysics/Jolt/Geometry/AABox.h +313 -0
  139. package/native/third_party/JoltPhysics/Jolt/Geometry/AABox4.h +224 -0
  140. package/native/third_party/JoltPhysics/Jolt/Geometry/ClipPoly.h +200 -0
  141. package/native/third_party/JoltPhysics/Jolt/Geometry/ClosestPoint.h +498 -0
  142. package/native/third_party/JoltPhysics/Jolt/Geometry/ConvexHullBuilder.cpp +1467 -0
  143. package/native/third_party/JoltPhysics/Jolt/Geometry/ConvexHullBuilder.h +276 -0
  144. package/native/third_party/JoltPhysics/Jolt/Geometry/ConvexHullBuilder2D.cpp +335 -0
  145. package/native/third_party/JoltPhysics/Jolt/Geometry/ConvexHullBuilder2D.h +105 -0
  146. package/native/third_party/JoltPhysics/Jolt/Geometry/ConvexSupport.h +188 -0
  147. package/native/third_party/JoltPhysics/Jolt/Geometry/EPAConvexHullBuilder.h +845 -0
  148. package/native/third_party/JoltPhysics/Jolt/Geometry/EPAPenetrationDepth.h +557 -0
  149. package/native/third_party/JoltPhysics/Jolt/Geometry/Ellipse.h +77 -0
  150. package/native/third_party/JoltPhysics/Jolt/Geometry/GJKClosestPoint.h +945 -0
  151. package/native/third_party/JoltPhysics/Jolt/Geometry/IndexedTriangle.h +130 -0
  152. package/native/third_party/JoltPhysics/Jolt/Geometry/Indexify.cpp +222 -0
  153. package/native/third_party/JoltPhysics/Jolt/Geometry/Indexify.h +19 -0
  154. package/native/third_party/JoltPhysics/Jolt/Geometry/MortonCode.h +40 -0
  155. package/native/third_party/JoltPhysics/Jolt/Geometry/OrientedBox.cpp +178 -0
  156. package/native/third_party/JoltPhysics/Jolt/Geometry/OrientedBox.h +39 -0
  157. package/native/third_party/JoltPhysics/Jolt/Geometry/Plane.h +104 -0
  158. package/native/third_party/JoltPhysics/Jolt/Geometry/RayAABox.h +241 -0
  159. package/native/third_party/JoltPhysics/Jolt/Geometry/RayCapsule.h +37 -0
  160. package/native/third_party/JoltPhysics/Jolt/Geometry/RayCylinder.h +101 -0
  161. package/native/third_party/JoltPhysics/Jolt/Geometry/RaySphere.h +96 -0
  162. package/native/third_party/JoltPhysics/Jolt/Geometry/RayTriangle.h +158 -0
  163. package/native/third_party/JoltPhysics/Jolt/Geometry/Sphere.h +72 -0
  164. package/native/third_party/JoltPhysics/Jolt/Geometry/Triangle.h +34 -0
  165. package/native/third_party/JoltPhysics/Jolt/Jolt.cmake +703 -0
  166. package/native/third_party/JoltPhysics/Jolt/Jolt.h +16 -0
  167. package/native/third_party/JoltPhysics/Jolt/Jolt.natvis +116 -0
  168. package/native/third_party/JoltPhysics/Jolt/Math/BVec16.h +99 -0
  169. package/native/third_party/JoltPhysics/Jolt/Math/BVec16.inl +177 -0
  170. package/native/third_party/JoltPhysics/Jolt/Math/DMat44.h +158 -0
  171. package/native/third_party/JoltPhysics/Jolt/Math/DMat44.inl +310 -0
  172. package/native/third_party/JoltPhysics/Jolt/Math/DVec3.h +291 -0
  173. package/native/third_party/JoltPhysics/Jolt/Math/DVec3.inl +941 -0
  174. package/native/third_party/JoltPhysics/Jolt/Math/Double3.h +48 -0
  175. package/native/third_party/JoltPhysics/Jolt/Math/DynMatrix.h +31 -0
  176. package/native/third_party/JoltPhysics/Jolt/Math/EigenValueSymmetric.h +177 -0
  177. package/native/third_party/JoltPhysics/Jolt/Math/FindRoot.h +42 -0
  178. package/native/third_party/JoltPhysics/Jolt/Math/Float2.h +36 -0
  179. package/native/third_party/JoltPhysics/Jolt/Math/Float3.h +50 -0
  180. package/native/third_party/JoltPhysics/Jolt/Math/Float4.h +44 -0
  181. package/native/third_party/JoltPhysics/Jolt/Math/GaussianElimination.h +102 -0
  182. package/native/third_party/JoltPhysics/Jolt/Math/HalfFloat.h +208 -0
  183. package/native/third_party/JoltPhysics/Jolt/Math/Mat44.h +243 -0
  184. package/native/third_party/JoltPhysics/Jolt/Math/Mat44.inl +952 -0
  185. package/native/third_party/JoltPhysics/Jolt/Math/Math.h +208 -0
  186. package/native/third_party/JoltPhysics/Jolt/Math/MathTypes.h +32 -0
  187. package/native/third_party/JoltPhysics/Jolt/Math/Matrix.h +259 -0
  188. package/native/third_party/JoltPhysics/Jolt/Math/Quat.h +268 -0
  189. package/native/third_party/JoltPhysics/Jolt/Math/Quat.inl +406 -0
  190. package/native/third_party/JoltPhysics/Jolt/Math/Real.h +44 -0
  191. package/native/third_party/JoltPhysics/Jolt/Math/Swizzle.h +19 -0
  192. package/native/third_party/JoltPhysics/Jolt/Math/Trigonometry.h +79 -0
  193. package/native/third_party/JoltPhysics/Jolt/Math/UVec4.h +232 -0
  194. package/native/third_party/JoltPhysics/Jolt/Math/UVec4.inl +636 -0
  195. package/native/third_party/JoltPhysics/Jolt/Math/Vec3.cpp +71 -0
  196. package/native/third_party/JoltPhysics/Jolt/Math/Vec3.h +308 -0
  197. package/native/third_party/JoltPhysics/Jolt/Math/Vec3.inl +942 -0
  198. package/native/third_party/JoltPhysics/Jolt/Math/Vec4.h +320 -0
  199. package/native/third_party/JoltPhysics/Jolt/Math/Vec4.inl +1152 -0
  200. package/native/third_party/JoltPhysics/Jolt/Math/Vector.h +211 -0
  201. package/native/third_party/JoltPhysics/Jolt/ObjectStream/GetPrimitiveTypeOfType.h +54 -0
  202. package/native/third_party/JoltPhysics/Jolt/ObjectStream/ObjectStream.cpp +38 -0
  203. package/native/third_party/JoltPhysics/Jolt/ObjectStream/ObjectStream.h +337 -0
  204. package/native/third_party/JoltPhysics/Jolt/ObjectStream/ObjectStreamBinaryIn.cpp +252 -0
  205. package/native/third_party/JoltPhysics/Jolt/ObjectStream/ObjectStreamBinaryIn.h +57 -0
  206. package/native/third_party/JoltPhysics/Jolt/ObjectStream/ObjectStreamBinaryOut.cpp +165 -0
  207. package/native/third_party/JoltPhysics/Jolt/ObjectStream/ObjectStreamBinaryOut.h +57 -0
  208. package/native/third_party/JoltPhysics/Jolt/ObjectStream/ObjectStreamIn.cpp +635 -0
  209. package/native/third_party/JoltPhysics/Jolt/ObjectStream/ObjectStreamIn.h +148 -0
  210. package/native/third_party/JoltPhysics/Jolt/ObjectStream/ObjectStreamOut.cpp +166 -0
  211. package/native/third_party/JoltPhysics/Jolt/ObjectStream/ObjectStreamOut.h +101 -0
  212. package/native/third_party/JoltPhysics/Jolt/ObjectStream/ObjectStreamTextIn.cpp +418 -0
  213. package/native/third_party/JoltPhysics/Jolt/ObjectStream/ObjectStreamTextIn.h +55 -0
  214. package/native/third_party/JoltPhysics/Jolt/ObjectStream/ObjectStreamTextOut.cpp +255 -0
  215. package/native/third_party/JoltPhysics/Jolt/ObjectStream/ObjectStreamTextOut.h +62 -0
  216. package/native/third_party/JoltPhysics/Jolt/ObjectStream/ObjectStreamTypes.h +26 -0
  217. package/native/third_party/JoltPhysics/Jolt/ObjectStream/SerializableAttribute.h +111 -0
  218. package/native/third_party/JoltPhysics/Jolt/ObjectStream/SerializableAttributeEnum.h +67 -0
  219. package/native/third_party/JoltPhysics/Jolt/ObjectStream/SerializableAttributeTyped.h +60 -0
  220. package/native/third_party/JoltPhysics/Jolt/ObjectStream/SerializableObject.cpp +15 -0
  221. package/native/third_party/JoltPhysics/Jolt/ObjectStream/SerializableObject.h +170 -0
  222. package/native/third_party/JoltPhysics/Jolt/ObjectStream/TypeDeclarations.cpp +70 -0
  223. package/native/third_party/JoltPhysics/Jolt/ObjectStream/TypeDeclarations.h +45 -0
  224. package/native/third_party/JoltPhysics/Jolt/Physics/Body/AllowedDOFs.h +68 -0
  225. package/native/third_party/JoltPhysics/Jolt/Physics/Body/Body.cpp +426 -0
  226. package/native/third_party/JoltPhysics/Jolt/Physics/Body/Body.h +452 -0
  227. package/native/third_party/JoltPhysics/Jolt/Physics/Body/Body.inl +197 -0
  228. package/native/third_party/JoltPhysics/Jolt/Physics/Body/BodyAccess.h +68 -0
  229. package/native/third_party/JoltPhysics/Jolt/Physics/Body/BodyActivationListener.h +28 -0
  230. package/native/third_party/JoltPhysics/Jolt/Physics/Body/BodyCreationSettings.cpp +234 -0
  231. package/native/third_party/JoltPhysics/Jolt/Physics/Body/BodyCreationSettings.h +124 -0
  232. package/native/third_party/JoltPhysics/Jolt/Physics/Body/BodyFilter.h +130 -0
  233. package/native/third_party/JoltPhysics/Jolt/Physics/Body/BodyID.h +101 -0
  234. package/native/third_party/JoltPhysics/Jolt/Physics/Body/BodyInterface.cpp +1099 -0
  235. package/native/third_party/JoltPhysics/Jolt/Physics/Body/BodyInterface.h +324 -0
  236. package/native/third_party/JoltPhysics/Jolt/Physics/Body/BodyLock.h +111 -0
  237. package/native/third_party/JoltPhysics/Jolt/Physics/Body/BodyLockInterface.h +134 -0
  238. package/native/third_party/JoltPhysics/Jolt/Physics/Body/BodyLockMulti.h +120 -0
  239. package/native/third_party/JoltPhysics/Jolt/Physics/Body/BodyManager.cpp +1220 -0
  240. package/native/third_party/JoltPhysics/Jolt/Physics/Body/BodyManager.h +403 -0
  241. package/native/third_party/JoltPhysics/Jolt/Physics/Body/BodyPair.h +36 -0
  242. package/native/third_party/JoltPhysics/Jolt/Physics/Body/BodyType.h +19 -0
  243. package/native/third_party/JoltPhysics/Jolt/Physics/Body/MassProperties.cpp +185 -0
  244. package/native/third_party/JoltPhysics/Jolt/Physics/Body/MassProperties.h +58 -0
  245. package/native/third_party/JoltPhysics/Jolt/Physics/Body/MotionProperties.cpp +92 -0
  246. package/native/third_party/JoltPhysics/Jolt/Physics/Body/MotionProperties.h +308 -0
  247. package/native/third_party/JoltPhysics/Jolt/Physics/Body/MotionProperties.inl +178 -0
  248. package/native/third_party/JoltPhysics/Jolt/Physics/Body/MotionQuality.h +31 -0
  249. package/native/third_party/JoltPhysics/Jolt/Physics/Body/MotionType.h +17 -0
  250. package/native/third_party/JoltPhysics/Jolt/Physics/Character/Character.cpp +354 -0
  251. package/native/third_party/JoltPhysics/Jolt/Physics/Character/Character.h +159 -0
  252. package/native/third_party/JoltPhysics/Jolt/Physics/Character/CharacterBase.cpp +59 -0
  253. package/native/third_party/JoltPhysics/Jolt/Physics/Character/CharacterBase.h +157 -0
  254. package/native/third_party/JoltPhysics/Jolt/Physics/Character/CharacterID.h +98 -0
  255. package/native/third_party/JoltPhysics/Jolt/Physics/Character/CharacterVirtual.cpp +1933 -0
  256. package/native/third_party/JoltPhysics/Jolt/Physics/Character/CharacterVirtual.h +752 -0
  257. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/AABoxCast.h +20 -0
  258. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/ActiveEdgeMode.h +17 -0
  259. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/ActiveEdges.h +114 -0
  260. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/BackFaceMode.h +16 -0
  261. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/BroadPhase/BroadPhase.cpp +16 -0
  262. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/BroadPhase/BroadPhase.h +109 -0
  263. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/BroadPhase/BroadPhaseBruteForce.cpp +313 -0
  264. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/BroadPhase/BroadPhaseBruteForce.h +38 -0
  265. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/BroadPhase/BroadPhaseLayer.h +148 -0
  266. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/BroadPhase/BroadPhaseLayerInterfaceMask.h +92 -0
  267. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/BroadPhase/BroadPhaseLayerInterfaceTable.h +64 -0
  268. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/BroadPhase/BroadPhaseQuadTree.cpp +629 -0
  269. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/BroadPhase/BroadPhaseQuadTree.h +108 -0
  270. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/BroadPhase/BroadPhaseQuery.h +56 -0
  271. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/BroadPhase/ObjectVsBroadPhaseLayerFilterMask.h +35 -0
  272. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/BroadPhase/ObjectVsBroadPhaseLayerFilterTable.h +66 -0
  273. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/BroadPhase/QuadTree.cpp +1768 -0
  274. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/BroadPhase/QuadTree.h +389 -0
  275. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/CastConvexVsTriangles.cpp +107 -0
  276. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/CastConvexVsTriangles.h +46 -0
  277. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/CastResult.h +37 -0
  278. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/CastSphereVsTriangles.cpp +223 -0
  279. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/CastSphereVsTriangles.h +49 -0
  280. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/CollectFacesMode.h +16 -0
  281. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/CollideConvexVsTriangles.cpp +155 -0
  282. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/CollideConvexVsTriangles.h +56 -0
  283. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/CollidePointResult.h +25 -0
  284. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/CollideShape.h +106 -0
  285. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/CollideShapeVsShapePerLeaf.h +94 -0
  286. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/CollideSoftBodyVertexIterator.h +110 -0
  287. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/CollideSoftBodyVerticesVsTriangles.h +102 -0
  288. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/CollideSphereVsTriangles.cpp +121 -0
  289. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/CollideSphereVsTriangles.h +50 -0
  290. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/CollisionCollector.h +109 -0
  291. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/CollisionCollectorImpl.h +219 -0
  292. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/CollisionDispatch.cpp +107 -0
  293. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/CollisionDispatch.h +97 -0
  294. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/CollisionGroup.cpp +35 -0
  295. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/CollisionGroup.h +97 -0
  296. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/ContactListener.h +143 -0
  297. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/EstimateCollisionResponse.cpp +213 -0
  298. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/EstimateCollisionResponse.h +48 -0
  299. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/GroupFilter.cpp +32 -0
  300. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/GroupFilter.h +46 -0
  301. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/GroupFilterTable.cpp +38 -0
  302. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/GroupFilterTable.h +130 -0
  303. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/InternalEdgeRemovingCollector.h +279 -0
  304. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/ManifoldBetweenTwoFaces.cpp +271 -0
  305. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/ManifoldBetweenTwoFaces.h +44 -0
  306. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/NarrowPhaseQuery.cpp +448 -0
  307. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/NarrowPhaseQuery.h +77 -0
  308. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/NarrowPhaseStats.cpp +62 -0
  309. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/NarrowPhaseStats.h +110 -0
  310. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/ObjectLayer.h +111 -0
  311. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/ObjectLayerPairFilterMask.h +52 -0
  312. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/ObjectLayerPairFilterTable.h +78 -0
  313. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/PhysicsMaterial.cpp +35 -0
  314. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/PhysicsMaterial.h +57 -0
  315. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/PhysicsMaterialSimple.cpp +38 -0
  316. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/PhysicsMaterialSimple.h +37 -0
  317. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/RayCast.h +87 -0
  318. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/BoxShape.cpp +318 -0
  319. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/BoxShape.h +115 -0
  320. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/CapsuleShape.cpp +438 -0
  321. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/CapsuleShape.h +129 -0
  322. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/CompoundShape.cpp +433 -0
  323. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/CompoundShape.h +354 -0
  324. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/CompoundShapeVisitors.h +461 -0
  325. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/ConvexHullShape.cpp +1311 -0
  326. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/ConvexHullShape.h +202 -0
  327. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/ConvexShape.cpp +566 -0
  328. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/ConvexShape.h +150 -0
  329. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/CylinderShape.cpp +418 -0
  330. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/CylinderShape.h +126 -0
  331. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/DecoratedShape.cpp +87 -0
  332. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/DecoratedShape.h +80 -0
  333. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/EmptyShape.cpp +64 -0
  334. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/EmptyShape.h +75 -0
  335. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/GetTrianglesContext.h +248 -0
  336. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/HeightFieldShape.cpp +2754 -0
  337. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/HeightFieldShape.h +380 -0
  338. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/MeshShape.cpp +1305 -0
  339. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/MeshShape.h +228 -0
  340. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/MutableCompoundShape.cpp +596 -0
  341. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/MutableCompoundShape.h +176 -0
  342. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/OffsetCenterOfMassShape.cpp +217 -0
  343. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/OffsetCenterOfMassShape.h +140 -0
  344. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/PlaneShape.cpp +541 -0
  345. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/PlaneShape.h +147 -0
  346. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/PolyhedronSubmergedVolumeCalculator.h +319 -0
  347. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/RotatedTranslatedShape.cpp +333 -0
  348. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/RotatedTranslatedShape.h +161 -0
  349. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/ScaleHelpers.h +83 -0
  350. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/ScaledShape.cpp +238 -0
  351. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/ScaledShape.h +145 -0
  352. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/Shape.cpp +325 -0
  353. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/Shape.h +466 -0
  354. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/SphereShape.cpp +347 -0
  355. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/SphereShape.h +125 -0
  356. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/StaticCompoundShape.cpp +674 -0
  357. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/StaticCompoundShape.h +139 -0
  358. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/SubShapeID.h +138 -0
  359. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/SubShapeIDPair.h +65 -0
  360. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/TaperedCapsuleShape.cpp +453 -0
  361. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/TaperedCapsuleShape.gliffy +1 -0
  362. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/TaperedCapsuleShape.h +135 -0
  363. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/TaperedCylinderShape.cpp +691 -0
  364. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/TaperedCylinderShape.h +132 -0
  365. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/TriangleShape.cpp +430 -0
  366. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/Shape/TriangleShape.h +143 -0
  367. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/ShapeCast.h +173 -0
  368. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/ShapeFilter.h +73 -0
  369. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/SimShapeFilter.h +40 -0
  370. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/SimShapeFilterWrapper.h +58 -0
  371. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/SortReverseAndStore.h +48 -0
  372. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/TransformedShape.cpp +180 -0
  373. package/native/third_party/JoltPhysics/Jolt/Physics/Collision/TransformedShape.h +194 -0
  374. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/CalculateSolverSteps.h +70 -0
  375. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/ConeConstraint.cpp +246 -0
  376. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/ConeConstraint.h +133 -0
  377. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/Constraint.cpp +73 -0
  378. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/Constraint.h +243 -0
  379. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/ConstraintManager.cpp +289 -0
  380. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/ConstraintManager.h +100 -0
  381. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/AngleConstraintPart.h +257 -0
  382. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/AxisConstraintPart.h +682 -0
  383. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/DualAxisConstraintPart.h +276 -0
  384. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/GearConstraintPart.h +195 -0
  385. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/HingeRotationConstraintPart.h +222 -0
  386. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/IndependentAxisConstraintPart.h +246 -0
  387. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/PointConstraintPart.h +239 -0
  388. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/RackAndPinionConstraintPart.h +196 -0
  389. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/RotationEulerConstraintPart.h +283 -0
  390. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/RotationQuatConstraintPart.h +246 -0
  391. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/SpringPart.h +169 -0
  392. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/SwingTwistConstraintPart.h +597 -0
  393. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/ContactConstraintManager.cpp +1804 -0
  394. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/ContactConstraintManager.h +524 -0
  395. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/DistanceConstraint.cpp +266 -0
  396. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/DistanceConstraint.h +120 -0
  397. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/FixedConstraint.cpp +215 -0
  398. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/FixedConstraint.h +96 -0
  399. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/GearConstraint.cpp +188 -0
  400. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/GearConstraint.h +116 -0
  401. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/HingeConstraint.cpp +443 -0
  402. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/HingeConstraint.h +205 -0
  403. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/MotorSettings.cpp +43 -0
  404. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/MotorSettings.h +66 -0
  405. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/PathConstraint.cpp +458 -0
  406. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/PathConstraint.h +191 -0
  407. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/PathConstraintPath.cpp +85 -0
  408. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/PathConstraintPath.h +76 -0
  409. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/PathConstraintPathHermite.cpp +308 -0
  410. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/PathConstraintPathHermite.h +54 -0
  411. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/PointConstraint.cpp +157 -0
  412. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/PointConstraint.h +94 -0
  413. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/PulleyConstraint.cpp +253 -0
  414. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/PulleyConstraint.h +137 -0
  415. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/RackAndPinionConstraint.cpp +189 -0
  416. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/RackAndPinionConstraint.h +118 -0
  417. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/SixDOFConstraint.cpp +900 -0
  418. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/SixDOFConstraint.h +289 -0
  419. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/SliderConstraint.cpp +501 -0
  420. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/SliderConstraint.h +198 -0
  421. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/SpringSettings.cpp +35 -0
  422. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/SpringSettings.h +70 -0
  423. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/SwingTwistConstraint.cpp +524 -0
  424. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/SwingTwistConstraint.h +197 -0
  425. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/TwoBodyConstraint.cpp +56 -0
  426. package/native/third_party/JoltPhysics/Jolt/Physics/Constraints/TwoBodyConstraint.h +65 -0
  427. package/native/third_party/JoltPhysics/Jolt/Physics/DeterminismLog.cpp +17 -0
  428. package/native/third_party/JoltPhysics/Jolt/Physics/DeterminismLog.h +159 -0
  429. package/native/third_party/JoltPhysics/Jolt/Physics/EActivation.h +16 -0
  430. package/native/third_party/JoltPhysics/Jolt/Physics/EPhysicsUpdateError.h +37 -0
  431. package/native/third_party/JoltPhysics/Jolt/Physics/IslandBuilder.cpp +492 -0
  432. package/native/third_party/JoltPhysics/Jolt/Physics/IslandBuilder.h +144 -0
  433. package/native/third_party/JoltPhysics/Jolt/Physics/LargeIslandSplitter.cpp +582 -0
  434. package/native/third_party/JoltPhysics/Jolt/Physics/LargeIslandSplitter.h +187 -0
  435. package/native/third_party/JoltPhysics/Jolt/Physics/PhysicsLock.h +169 -0
  436. package/native/third_party/JoltPhysics/Jolt/Physics/PhysicsScene.cpp +261 -0
  437. package/native/third_party/JoltPhysics/Jolt/Physics/PhysicsScene.h +104 -0
  438. package/native/third_party/JoltPhysics/Jolt/Physics/PhysicsSettings.h +125 -0
  439. package/native/third_party/JoltPhysics/Jolt/Physics/PhysicsStepListener.h +37 -0
  440. package/native/third_party/JoltPhysics/Jolt/Physics/PhysicsSystem.cpp +2915 -0
  441. package/native/third_party/JoltPhysics/Jolt/Physics/PhysicsSystem.h +391 -0
  442. package/native/third_party/JoltPhysics/Jolt/Physics/PhysicsUpdateContext.cpp +25 -0
  443. package/native/third_party/JoltPhysics/Jolt/Physics/PhysicsUpdateContext.h +176 -0
  444. package/native/third_party/JoltPhysics/Jolt/Physics/Ragdoll/Ragdoll.cpp +744 -0
  445. package/native/third_party/JoltPhysics/Jolt/Physics/Ragdoll/Ragdoll.h +245 -0
  446. package/native/third_party/JoltPhysics/Jolt/Physics/SoftBody/SoftBodyContactListener.h +55 -0
  447. package/native/third_party/JoltPhysics/Jolt/Physics/SoftBody/SoftBodyCreationSettings.cpp +128 -0
  448. package/native/third_party/JoltPhysics/Jolt/Physics/SoftBody/SoftBodyCreationSettings.h +75 -0
  449. package/native/third_party/JoltPhysics/Jolt/Physics/SoftBody/SoftBodyManifold.h +74 -0
  450. package/native/third_party/JoltPhysics/Jolt/Physics/SoftBody/SoftBodyMotionProperties.cpp +1501 -0
  451. package/native/third_party/JoltPhysics/Jolt/Physics/SoftBody/SoftBodyMotionProperties.h +333 -0
  452. package/native/third_party/JoltPhysics/Jolt/Physics/SoftBody/SoftBodyShape.cpp +354 -0
  453. package/native/third_party/JoltPhysics/Jolt/Physics/SoftBody/SoftBodyShape.h +73 -0
  454. package/native/third_party/JoltPhysics/Jolt/Physics/SoftBody/SoftBodySharedSettings.cpp +1487 -0
  455. package/native/third_party/JoltPhysics/Jolt/Physics/SoftBody/SoftBodySharedSettings.h +390 -0
  456. package/native/third_party/JoltPhysics/Jolt/Physics/SoftBody/SoftBodyUpdateContext.h +63 -0
  457. package/native/third_party/JoltPhysics/Jolt/Physics/SoftBody/SoftBodyVertex.h +36 -0
  458. package/native/third_party/JoltPhysics/Jolt/Physics/StateRecorder.h +136 -0
  459. package/native/third_party/JoltPhysics/Jolt/Physics/StateRecorderImpl.cpp +90 -0
  460. package/native/third_party/JoltPhysics/Jolt/Physics/StateRecorderImpl.h +50 -0
  461. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/MotorcycleController.cpp +306 -0
  462. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/MotorcycleController.h +119 -0
  463. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/TrackedVehicleController.cpp +547 -0
  464. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/TrackedVehicleController.h +169 -0
  465. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/VehicleAntiRollBar.cpp +33 -0
  466. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/VehicleAntiRollBar.h +33 -0
  467. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/VehicleCollisionTester.cpp +376 -0
  468. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/VehicleCollisionTester.h +146 -0
  469. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/VehicleConstraint.cpp +703 -0
  470. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/VehicleConstraint.h +252 -0
  471. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/VehicleController.cpp +17 -0
  472. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/VehicleController.h +87 -0
  473. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/VehicleDifferential.cpp +81 -0
  474. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/VehicleDifferential.h +39 -0
  475. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/VehicleEngine.cpp +122 -0
  476. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/VehicleEngine.h +93 -0
  477. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/VehicleTrack.cpp +52 -0
  478. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/VehicleTrack.h +56 -0
  479. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/VehicleTransmission.cpp +159 -0
  480. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/VehicleTransmission.h +87 -0
  481. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/Wheel.cpp +93 -0
  482. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/Wheel.h +148 -0
  483. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/WheeledVehicleController.cpp +866 -0
  484. package/native/third_party/JoltPhysics/Jolt/Physics/Vehicle/WheeledVehicleController.h +205 -0
  485. package/native/third_party/JoltPhysics/Jolt/RegisterTypes.cpp +204 -0
  486. package/native/third_party/JoltPhysics/Jolt/RegisterTypes.h +29 -0
  487. package/native/third_party/JoltPhysics/Jolt/Renderer/DebugRenderer.cpp +1107 -0
  488. package/native/third_party/JoltPhysics/Jolt/Renderer/DebugRenderer.h +383 -0
  489. package/native/third_party/JoltPhysics/Jolt/Renderer/DebugRendererPlayback.cpp +168 -0
  490. package/native/third_party/JoltPhysics/Jolt/Renderer/DebugRendererPlayback.h +48 -0
  491. package/native/third_party/JoltPhysics/Jolt/Renderer/DebugRendererRecorder.cpp +158 -0
  492. package/native/third_party/JoltPhysics/Jolt/Renderer/DebugRendererRecorder.h +130 -0
  493. package/native/third_party/JoltPhysics/Jolt/Renderer/DebugRendererSimple.cpp +80 -0
  494. package/native/third_party/JoltPhysics/Jolt/Renderer/DebugRendererSimple.h +88 -0
  495. package/native/third_party/JoltPhysics/Jolt/Skeleton/SkeletalAnimation.cpp +165 -0
  496. package/native/third_party/JoltPhysics/Jolt/Skeleton/SkeletalAnimation.h +91 -0
  497. package/native/third_party/JoltPhysics/Jolt/Skeleton/Skeleton.cpp +82 -0
  498. package/native/third_party/JoltPhysics/Jolt/Skeleton/Skeleton.h +72 -0
  499. package/native/third_party/JoltPhysics/Jolt/Skeleton/SkeletonMapper.cpp +237 -0
  500. package/native/third_party/JoltPhysics/Jolt/Skeleton/SkeletonMapper.h +145 -0
  501. package/native/third_party/JoltPhysics/Jolt/Skeleton/SkeletonPose.cpp +87 -0
  502. package/native/third_party/JoltPhysics/Jolt/Skeleton/SkeletonPose.h +82 -0
  503. package/native/third_party/JoltPhysics/Jolt/TriangleSplitter/TriangleSplitter.cpp +73 -0
  504. package/native/third_party/JoltPhysics/Jolt/TriangleSplitter/TriangleSplitter.h +84 -0
  505. package/native/third_party/JoltPhysics/Jolt/TriangleSplitter/TriangleSplitterBinning.cpp +139 -0
  506. package/native/third_party/JoltPhysics/Jolt/TriangleSplitter/TriangleSplitterBinning.h +52 -0
  507. package/native/third_party/JoltPhysics/Jolt/TriangleSplitter/TriangleSplitterMean.cpp +43 -0
  508. package/native/third_party/JoltPhysics/Jolt/TriangleSplitter/TriangleSplitterMean.h +28 -0
  509. package/native/third_party/JoltPhysics/LICENSE +7 -0
  510. package/native/third_party/JoltPhysics/README.md +173 -0
  511. package/native/third_party/bloom_jolt/CMakeLists.txt +78 -0
  512. package/native/third_party/bloom_jolt/include/bloom_jolt.h +519 -0
  513. package/native/third_party/bloom_jolt/src/bloom_jolt.cpp +1780 -0
  514. package/native/tvos/Cargo.lock +1692 -0
  515. package/native/tvos/Cargo.toml +22 -0
  516. package/native/tvos/src/lib.rs +3179 -0
  517. package/native/watchos/Cargo.lock +16 -0
  518. package/native/watchos/Cargo.toml +19 -0
  519. package/native/watchos/shaders/bloom_postfx.metal +99 -0
  520. package/native/watchos/src/BloomWatchApp.swift +1236 -0
  521. package/native/watchos/src/BloomWatchAudio.swift +179 -0
  522. package/native/watchos/src/audio.rs +55 -0
  523. package/native/watchos/src/draw_list.rs +223 -0
  524. package/native/watchos/src/ffi_stubs.rs +454 -0
  525. package/native/watchos/src/lib.rs +1013 -0
  526. package/native/watchos/src/models.rs +746 -0
  527. package/native/watchos/src/postfx.rs +91 -0
  528. package/native/watchos/src/scene.rs +534 -0
  529. package/native/watchos/src/textures.rs +184 -0
  530. package/native/web/Cargo.lock +1656 -0
  531. package/native/web/Cargo.toml +38 -0
  532. package/native/web/bloom_glue.js +218 -0
  533. package/native/web/build.sh +101 -0
  534. package/native/web/index.html +390 -0
  535. package/native/web/jolt_bridge.js +1311 -0
  536. package/native/web/src/lib.rs +2739 -0
  537. package/native/windows/Cargo.lock +1813 -0
  538. package/native/windows/Cargo.toml +31 -0
  539. package/native/windows/src/lib.rs +1933 -0
  540. package/package.json +558 -0
  541. package/src/audio/index.ts +151 -0
  542. package/src/core/colors.ts +56 -0
  543. package/src/core/index.ts +903 -0
  544. package/src/core/keys.ts +63 -0
  545. package/src/core/types.ts +102 -0
  546. package/src/index.ts +158 -0
  547. package/src/math/index.ts +502 -0
  548. package/src/mobile/index.ts +294 -0
  549. package/src/models/index.ts +859 -0
  550. package/src/physics/index.ts +1072 -0
  551. package/src/scene/index.ts +570 -0
  552. package/src/shapes/index.ts +120 -0
  553. package/src/text/index.ts +48 -0
  554. package/src/textures/index.ts +173 -0
  555. package/src/world/index.ts +22 -0
  556. package/src/world/loader.ts +385 -0
  557. package/src/world/prefab.ts +205 -0
  558. package/src/world/saver.ts +61 -0
  559. package/src/world/terrain.ts +254 -0
  560. package/src/world/types.ts +136 -0
  561. package/src/world/validate.ts +202 -0
  562. package/src/world/version.ts +47 -0
@@ -0,0 +1,1528 @@
1
+ //! Jolt-backed physics world for Bloom Engine.
2
+ //!
3
+ //! Wraps `jolt_sys` behind f64 handle registries so Perry FFI can speak to
4
+ //! Jolt using only scalar values.
5
+ //!
6
+ //! Handle conventions:
7
+ //! - bloom handles are 1-based f64 indices into HandleRegistry
8
+ //! - bj_world, bj_shape, bj_body, bj_constraint are native Jolt handles
9
+ //! - Body/constraint handles are scoped to a single world internally
10
+ //!
11
+ //! Thread-safety: Jolt's contact listener runs on job threads; the queue it
12
+ //! fills is already mutex-protected inside `bloom_jolt.cpp`. Everything in
13
+ //! this file is single-threaded (matches Bloom's engine-main-thread model).
14
+
15
+ use crate::handles::HandleRegistry;
16
+ use crate::jolt_sys::*;
17
+
18
+ use std::sync::Once;
19
+
20
+ static GLOBAL_INIT: Once = Once::new();
21
+
22
+ /// Ensures `bj_global_init` is called exactly once per process.
23
+ pub fn ensure_jolt_initialised() {
24
+ GLOBAL_INIT.call_once(|| {
25
+ // SAFETY: called exactly once; bj_global_init is refcounted and idempotent.
26
+ let r = unsafe { bj_global_init() };
27
+ assert_eq!(r, BjResult::Ok, "Jolt global init failed");
28
+ });
29
+ }
30
+
31
+ // ============================================================
32
+ // Cached query results (multi-call read-back pattern)
33
+ // ============================================================
34
+
35
+ #[derive(Default)]
36
+ struct RayHitCache {
37
+ hits: Vec<BjRayHit>,
38
+ }
39
+
40
+ #[derive(Default)]
41
+ struct OverlapCache {
42
+ bodies: Vec<bj_body>,
43
+ }
44
+
45
+ #[derive(Default)]
46
+ struct ContactCache {
47
+ /// Drained from Jolt's queue at the start of each read cycle.
48
+ events: Vec<BjContact>,
49
+ }
50
+
51
+ // ============================================================
52
+ // JoltPhysics — owned by EngineState, indexed by f64 handles
53
+ // ============================================================
54
+
55
+ pub struct JoltPhysics {
56
+ /// Usually a single world; supporting a registry keeps the API symmetric.
57
+ worlds: HandleRegistry<bj_world>,
58
+ /// Shapes live across worlds (refcounted in Jolt). Stored as raw pointer values.
59
+ shapes: HandleRegistry<bj_shape>,
60
+ /// Bodies are world-scoped. We remember which world they belong to.
61
+ bodies: HandleRegistry<(bj_world, bj_body)>,
62
+ /// Constraints similarly scoped.
63
+ constraints: HandleRegistry<(bj_world, bj_constraint)>,
64
+ /// Character controllers — world-scoped like bodies/constraints.
65
+ characters: HandleRegistry<(bj_world, bj_character)>,
66
+ /// Wheeled vehicles — world-scoped; stores bj_vehicle + the chassis body
67
+ /// handle it mapped to (for TS-side getChassis()).
68
+ vehicles: HandleRegistry<(bj_world, bj_vehicle, f64 /*chassis body handle*/)>,
69
+
70
+ ray_hit_cache: RayHitCache,
71
+ overlap_cache: OverlapCache,
72
+ contact_cache: ContactCache,
73
+
74
+ /// Scratch streams for variable-size shape inputs (convex hull points,
75
+ /// mesh vertices/indices, heightfield samples). The TS layer pushes
76
+ /// values via `bloom_physics_scratch_push_*` then calls the shape factory.
77
+ scratch_f32: Vec<f32>,
78
+ scratch_u32: Vec<u32>,
79
+ /// Compound-shape builder state — cleared by compound_begin, extended
80
+ /// by compound_add_child, consumed by compound_end.
81
+ compound_children: Vec<(bj_shape, BjTransform)>,
82
+ }
83
+
84
+ impl Default for JoltPhysics {
85
+ fn default() -> Self { Self::new() }
86
+ }
87
+
88
+ impl JoltPhysics {
89
+ pub fn new() -> Self {
90
+ ensure_jolt_initialised();
91
+ Self {
92
+ worlds: HandleRegistry::new(),
93
+ shapes: HandleRegistry::new(),
94
+ bodies: HandleRegistry::new(),
95
+ constraints: HandleRegistry::new(),
96
+ characters: HandleRegistry::new(),
97
+ vehicles: HandleRegistry::new(),
98
+ ray_hit_cache: RayHitCache::default(),
99
+ overlap_cache: OverlapCache::default(),
100
+ contact_cache: ContactCache::default(),
101
+ scratch_f32: Vec::with_capacity(1024),
102
+ scratch_u32: Vec::with_capacity(512),
103
+ compound_children: Vec::with_capacity(16),
104
+ }
105
+ }
106
+
107
+ // -------------------------------------------------------- Scratch buffer
108
+
109
+ pub fn scratch_reset(&mut self) {
110
+ self.scratch_f32.clear();
111
+ self.scratch_u32.clear();
112
+ }
113
+ pub fn scratch_push_f32(&mut self, v: f32) { self.scratch_f32.push(v); }
114
+ pub fn scratch_push_u32(&mut self, v: u32) { self.scratch_u32.push(v); }
115
+
116
+ pub fn shape_convex_hull_from_scratch(&mut self, num_points: u32, convex_radius: f32) -> f64 {
117
+ let need = (num_points * 3) as usize;
118
+ if self.scratch_f32.len() < need || num_points < 3 { return 0.0; }
119
+ let points: Vec<BjVec3> = (0..num_points as usize).map(|i| BjVec3 {
120
+ x: self.scratch_f32[i * 3],
121
+ y: self.scratch_f32[i * 3 + 1],
122
+ z: self.scratch_f32[i * 3 + 2],
123
+ }).collect();
124
+ self.create_convex_hull_shape(&points, convex_radius)
125
+ }
126
+
127
+ pub fn shape_mesh_from_scratch(&mut self, vertex_count: u32, triangle_count: u32) -> f64 {
128
+ let need_f = (vertex_count * 3) as usize;
129
+ let need_u = (triangle_count * 3) as usize;
130
+ if self.scratch_f32.len() < need_f || self.scratch_u32.len() < need_u { return 0.0; }
131
+ if vertex_count == 0 || triangle_count == 0 { return 0.0; }
132
+ let vertices: Vec<BjVec3> = (0..vertex_count as usize).map(|i| BjVec3 {
133
+ x: self.scratch_f32[i * 3],
134
+ y: self.scratch_f32[i * 3 + 1],
135
+ z: self.scratch_f32[i * 3 + 2],
136
+ }).collect();
137
+ let indices: Vec<u32> = self.scratch_u32[..need_u].to_vec();
138
+ self.create_mesh_shape(&vertices, &indices)
139
+ }
140
+
141
+ #[allow(clippy::too_many_arguments)]
142
+ pub fn shape_heightfield_from_scratch(
143
+ &mut self, sample_count: u32,
144
+ ox: f32, oy: f32, oz: f32, sx: f32, sy: f32, sz: f32, block_size: u32,
145
+ ) -> f64 {
146
+ let need = (sample_count * sample_count) as usize;
147
+ if self.scratch_f32.len() < need || sample_count < 2 { return 0.0; }
148
+ let samples = self.scratch_f32[..need].to_vec();
149
+ self.create_heightfield_shape(
150
+ &samples, sample_count,
151
+ BjVec3 { x: ox, y: oy, z: oz },
152
+ BjVec3 { x: sx, y: sy, z: sz },
153
+ block_size,
154
+ )
155
+ }
156
+
157
+ pub fn compound_begin(&mut self) {
158
+ self.compound_children.clear();
159
+ }
160
+ #[allow(clippy::too_many_arguments)]
161
+ pub fn compound_add_child(&mut self,
162
+ shape_h: f64,
163
+ px: f32, py: f32, pz: f32,
164
+ rx: f32, ry: f32, rz: f32, rw: f32,
165
+ ) {
166
+ if let Some(&shape) = self.shapes.get(shape_h) {
167
+ self.compound_children.push((shape, BjTransform {
168
+ position: BjVec3 { x: px, y: py, z: pz },
169
+ rotation: BjQuat { x: rx, y: ry, z: rz, w: rw },
170
+ }));
171
+ }
172
+ }
173
+ pub fn compound_end(&mut self) -> f64 {
174
+ if self.compound_children.is_empty() { return 0.0; }
175
+ let shapes: Vec<bj_shape> = self.compound_children.iter().map(|(s, _)| *s).collect();
176
+ let xforms: Vec<BjTransform> = self.compound_children.iter().map(|(_, x)| *x).collect();
177
+ let s = unsafe {
178
+ bj_shape_compound_static(shapes.as_ptr(), xforms.as_ptr(), shapes.len() as u32)
179
+ };
180
+ self.compound_children.clear();
181
+ if s == BJ_INVALID { 0.0 } else { self.shapes.alloc(s) }
182
+ }
183
+
184
+ // -------------------------------------------------------- World
185
+
186
+ pub fn create_world(
187
+ &mut self,
188
+ gx: f32, gy: f32, gz: f32,
189
+ max_bodies: u32, num_threads: u32,
190
+ ) -> f64 {
191
+ let desc = BjWorldDesc {
192
+ gravity: BjVec3 { x: gx, y: gy, z: gz },
193
+ max_bodies: if max_bodies > 0 { max_bodies } else { 65536 },
194
+ num_threads,
195
+ ..Default::default()
196
+ };
197
+ let world = unsafe { bj_world_create(&desc) };
198
+ if world == BJ_INVALID { return 0.0; }
199
+ self.worlds.alloc(world)
200
+ }
201
+
202
+ pub fn destroy_world(&mut self, handle: f64) {
203
+ if let Some(world) = self.worlds.free(handle) {
204
+ // Destroy bodies and constraints tied to this world first.
205
+ // (Iterate and collect to avoid borrow conflicts.)
206
+ let body_handles: Vec<f64> = self.bodies.iter()
207
+ .filter(|(_, (w, _))| *w == world)
208
+ .map(|(h, _)| h)
209
+ .collect();
210
+ for h in body_handles {
211
+ if let Some((w, b)) = self.bodies.free(h) {
212
+ unsafe { bj_body_destroy(w, b); }
213
+ }
214
+ }
215
+ let c_handles: Vec<f64> = self.constraints.iter()
216
+ .filter(|(_, (w, _))| *w == world)
217
+ .map(|(h, _)| h)
218
+ .collect();
219
+ for h in c_handles {
220
+ if let Some((w, c)) = self.constraints.free(h) {
221
+ unsafe { bj_constraint_destroy(w, c); }
222
+ }
223
+ }
224
+ unsafe { bj_world_destroy(world); }
225
+ }
226
+ }
227
+
228
+ pub fn set_gravity(&self, world_h: f64, x: f32, y: f32, z: f32) {
229
+ if let Some(&world) = self.worlds.get(world_h) {
230
+ unsafe { bj_world_set_gravity(world, BjVec3 { x, y, z }); }
231
+ }
232
+ }
233
+
234
+ pub fn get_gravity_axis(&self, world_h: f64, axis: u32) -> f64 {
235
+ if let Some(&world) = self.worlds.get(world_h) {
236
+ let mut g = BjVec3::default();
237
+ unsafe { bj_world_get_gravity(world, &mut g); }
238
+ return match axis { 0 => g.x, 1 => g.y, 2 => g.z, _ => 0.0 } as f64;
239
+ }
240
+ 0.0
241
+ }
242
+
243
+ pub fn optimize_broadphase(&self, world_h: f64) {
244
+ if let Some(&world) = self.worlds.get(world_h) {
245
+ unsafe { bj_world_optimize_broadphase(world); }
246
+ }
247
+ }
248
+
249
+ pub fn step(&mut self, world_h: f64, dt: f32, collision_steps: u32) {
250
+ if let Some(&world) = self.worlds.get(world_h) {
251
+ unsafe { bj_world_step(world, dt, collision_steps.max(1)); }
252
+ // Drain contact events into our cache so they survive across queries.
253
+ let count = unsafe { bj_world_contact_count(world) };
254
+ if count > 0 {
255
+ self.contact_cache.events.resize(count as usize, unsafe { std::mem::zeroed() });
256
+ let drained = unsafe {
257
+ bj_world_pop_contacts(world, self.contact_cache.events.as_mut_ptr(), count)
258
+ };
259
+ self.contact_cache.events.truncate(drained as usize);
260
+ } else {
261
+ self.contact_cache.events.clear();
262
+ }
263
+ }
264
+ }
265
+
266
+ pub fn set_layer_collides(&self, world_h: f64, a: u32, b: u32, collides: bool) {
267
+ if let Some(&world) = self.worlds.get(world_h) {
268
+ unsafe { bj_world_set_layer_collides(world, a, b, collides as u8); }
269
+ }
270
+ }
271
+
272
+ pub fn get_layer_collides(&self, world_h: f64, a: u32, b: u32) -> bool {
273
+ if let Some(&world) = self.worlds.get(world_h) {
274
+ return unsafe { bj_world_get_layer_collides(world, a, b) } != 0;
275
+ }
276
+ false
277
+ }
278
+
279
+ pub fn body_count(&self, world_h: f64) -> u32 {
280
+ if let Some(&world) = self.worlds.get(world_h) {
281
+ return unsafe { bj_world_body_count(world) };
282
+ }
283
+ 0
284
+ }
285
+
286
+ pub fn active_body_count(&self, world_h: f64) -> u32 {
287
+ if let Some(&world) = self.worlds.get(world_h) {
288
+ return unsafe { bj_world_active_body_count(world) };
289
+ }
290
+ 0
291
+ }
292
+
293
+ // -------------------------------------------------------- Shapes
294
+
295
+ pub fn create_box_shape(&mut self, hx: f32, hy: f32, hz: f32, convex_radius: f32) -> f64 {
296
+ let s = unsafe { bj_shape_box(BjVec3 { x: hx, y: hy, z: hz }, convex_radius) };
297
+ if s == BJ_INVALID { 0.0 } else { self.shapes.alloc(s) }
298
+ }
299
+
300
+ pub fn create_sphere_shape(&mut self, radius: f32) -> f64 {
301
+ let s = unsafe { bj_shape_sphere(radius) };
302
+ if s == BJ_INVALID { 0.0 } else { self.shapes.alloc(s) }
303
+ }
304
+
305
+ pub fn create_capsule_shape(&mut self, half_height: f32, radius: f32) -> f64 {
306
+ let s = unsafe { bj_shape_capsule(half_height, radius) };
307
+ if s == BJ_INVALID { 0.0 } else { self.shapes.alloc(s) }
308
+ }
309
+
310
+ pub fn create_cylinder_shape(&mut self, half_height: f32, radius: f32, convex_radius: f32) -> f64 {
311
+ let s = unsafe { bj_shape_cylinder(half_height, radius, convex_radius) };
312
+ if s == BJ_INVALID { 0.0 } else { self.shapes.alloc(s) }
313
+ }
314
+
315
+ pub fn create_convex_hull_shape(&mut self, points: &[BjVec3], convex_radius: f32) -> f64 {
316
+ let s = unsafe {
317
+ bj_shape_convex_hull(points.as_ptr(), points.len() as u32, convex_radius)
318
+ };
319
+ if s == BJ_INVALID { 0.0 } else { self.shapes.alloc(s) }
320
+ }
321
+
322
+ pub fn create_mesh_shape(&mut self, vertices: &[BjVec3], indices: &[u32]) -> f64 {
323
+ debug_assert!(indices.len() % 3 == 0);
324
+ let s = unsafe {
325
+ bj_shape_mesh(
326
+ vertices.as_ptr(), vertices.len() as u32,
327
+ indices.as_ptr(), (indices.len() / 3) as u32,
328
+ )
329
+ };
330
+ if s == BJ_INVALID { 0.0 } else { self.shapes.alloc(s) }
331
+ }
332
+
333
+ pub fn create_heightfield_shape(
334
+ &mut self,
335
+ samples: &[f32], sample_count: u32,
336
+ offset: BjVec3, scale: BjVec3, block_size: u32,
337
+ ) -> f64 {
338
+ let s = unsafe {
339
+ bj_shape_heightfield(
340
+ samples.as_ptr(), sample_count, offset, scale, block_size,
341
+ )
342
+ };
343
+ if s == BJ_INVALID { 0.0 } else { self.shapes.alloc(s) }
344
+ }
345
+
346
+ pub fn create_scaled_shape(&mut self, base_h: f64, sx: f32, sy: f32, sz: f32) -> f64 {
347
+ let base = match self.shapes.get(base_h) { Some(&s) => s, None => return 0.0 };
348
+ let s = unsafe { bj_shape_scaled(base, BjVec3 { x: sx, y: sy, z: sz }) };
349
+ if s == BJ_INVALID { 0.0 } else { self.shapes.alloc(s) }
350
+ }
351
+
352
+ pub fn create_offset_com_shape(&mut self, base_h: f64, ox: f32, oy: f32, oz: f32) -> f64 {
353
+ let base = match self.shapes.get(base_h) { Some(&s) => s, None => return 0.0 };
354
+ let s = unsafe { bj_shape_offset_com(base, BjVec3 { x: ox, y: oy, z: oz }) };
355
+ if s == BJ_INVALID { 0.0 } else { self.shapes.alloc(s) }
356
+ }
357
+
358
+ pub fn release_shape(&mut self, handle: f64) {
359
+ if let Some(s) = self.shapes.free(handle) {
360
+ unsafe { bj_shape_release(s); }
361
+ }
362
+ }
363
+
364
+ pub fn shape_bounds_axis(&self, handle: f64, axis: u32) -> f64 {
365
+ if let Some(&s) = self.shapes.get(handle) {
366
+ let mut mn = BjVec3::default();
367
+ let mut mx = BjVec3::default();
368
+ unsafe { bj_shape_get_local_bounds(s, &mut mn, &mut mx); }
369
+ return match axis {
370
+ 0 => mn.x, 1 => mn.y, 2 => mn.z,
371
+ 3 => mx.x, 4 => mx.y, 5 => mx.z,
372
+ _ => 0.0,
373
+ } as f64;
374
+ }
375
+ 0.0
376
+ }
377
+
378
+ pub fn shape_volume(&self, handle: f64) -> f32 {
379
+ self.shapes.get(handle).map(|&s| unsafe { bj_shape_get_volume(s) }).unwrap_or(0.0)
380
+ }
381
+
382
+ // -------------------------------------------------------- Bodies
383
+
384
+ /// Full body descriptor — passed as flat scalars by the FFI wrapper.
385
+ #[allow(clippy::too_many_arguments)]
386
+ pub fn create_body(
387
+ &mut self,
388
+ world_h: f64, shape_h: f64,
389
+ motion_type: u32,
390
+ px: f32, py: f32, pz: f32,
391
+ rx: f32, ry: f32, rz: f32, rw: f32,
392
+ vx: f32, vy: f32, vz: f32,
393
+ wx: f32, wy: f32, wz: f32,
394
+ object_layer: u32,
395
+ is_sensor: bool, allow_sleeping: bool, use_ccd: bool, start_awake: bool,
396
+ friction: f32, restitution: f32,
397
+ lin_damp: f32, ang_damp: f32, gravity_factor: f32,
398
+ mass_override: f32,
399
+ ix: f32, iy: f32, iz: f32,
400
+ user_data: u64,
401
+ ) -> f64 {
402
+ let world = match self.worlds.get(world_h) { Some(&w) => w, None => return 0.0 };
403
+ let shape = match self.shapes.get(shape_h) { Some(&s) => s, None => return 0.0 };
404
+
405
+ let desc = BjBodyDesc {
406
+ motion_type: match motion_type {
407
+ 0 => BjMotionType::Static,
408
+ 1 => BjMotionType::Kinematic,
409
+ _ => BjMotionType::Dynamic,
410
+ },
411
+ position: BjVec3 { x: px, y: py, z: pz },
412
+ rotation: BjQuat { x: rx, y: ry, z: rz, w: rw },
413
+ linear_velocity: BjVec3 { x: vx, y: vy, z: vz },
414
+ angular_velocity: BjVec3 { x: wx, y: wy, z: wz },
415
+ gravity_factor,
416
+ linear_damping: lin_damp,
417
+ angular_damping: ang_damp,
418
+ friction,
419
+ restitution,
420
+ mass_override,
421
+ inertia_diag_override: BjVec3 { x: ix, y: iy, z: iz },
422
+ object_layer,
423
+ is_sensor: is_sensor as u8,
424
+ allow_sleeping: allow_sleeping as u8,
425
+ use_ccd: use_ccd as u8,
426
+ start_awake: start_awake as u8,
427
+ user_data,
428
+ };
429
+ let body = unsafe { bj_body_create(world, shape, &desc) };
430
+ if body == BJ_INVALID { 0.0 } else { self.bodies.alloc((world, body)) }
431
+ }
432
+
433
+ pub fn destroy_body(&mut self, handle: f64) {
434
+ if let Some((world, body)) = self.bodies.free(handle) {
435
+ unsafe { bj_body_destroy(world, body); }
436
+ }
437
+ }
438
+
439
+ fn resolve_body(&self, h: f64) -> Option<(bj_world, bj_body)> {
440
+ self.bodies.get(h).copied()
441
+ }
442
+
443
+ pub fn body_activate(&self, h: f64) {
444
+ if let Some((w, b)) = self.resolve_body(h) { unsafe { bj_body_activate(w, b); } }
445
+ }
446
+ pub fn body_deactivate(&self, h: f64) {
447
+ if let Some((w, b)) = self.resolve_body(h) { unsafe { bj_body_deactivate(w, b); } }
448
+ }
449
+ pub fn body_is_active(&self, h: f64) -> bool {
450
+ self.resolve_body(h).map(|(w, b)| unsafe { bj_body_is_active(w, b) } != 0).unwrap_or(false)
451
+ }
452
+ pub fn body_is_valid(&self, h: f64) -> bool {
453
+ self.resolve_body(h).map(|(w, b)| unsafe { bj_body_is_valid(w, b) } != 0).unwrap_or(false)
454
+ }
455
+
456
+ pub fn body_get_position_axis(&self, h: f64, axis: u32) -> f64 {
457
+ if let Some((w, b)) = self.resolve_body(h) {
458
+ let mut v = BjVec3::default();
459
+ unsafe { bj_body_get_position(w, b, &mut v); }
460
+ return match axis { 0 => v.x, 1 => v.y, 2 => v.z, _ => 0.0 } as f64;
461
+ }
462
+ 0.0
463
+ }
464
+ pub fn body_get_rotation_axis(&self, h: f64, axis: u32) -> f64 {
465
+ if let Some((w, b)) = self.resolve_body(h) {
466
+ let mut q = BjQuat::default();
467
+ unsafe { bj_body_get_rotation(w, b, &mut q); }
468
+ return match axis { 0 => q.x, 1 => q.y, 2 => q.z, 3 => q.w, _ => 0.0 } as f64;
469
+ }
470
+ 0.0
471
+ }
472
+
473
+ pub fn body_set_position(&self, h: f64, x: f32, y: f32, z: f32, activate: bool) {
474
+ if let Some((w, b)) = self.resolve_body(h) {
475
+ unsafe { bj_body_set_position(w, b, BjVec3 { x, y, z }, if activate { BjActivation::Activate } else { BjActivation::DontActivate }); }
476
+ }
477
+ }
478
+ pub fn body_set_rotation(&self, h: f64, x: f32, y: f32, z: f32, ww: f32, activate: bool) {
479
+ if let Some((w, b)) = self.resolve_body(h) {
480
+ unsafe { bj_body_set_rotation(w, b, BjQuat { x, y, z, w: ww }, if activate { BjActivation::Activate } else { BjActivation::DontActivate }); }
481
+ }
482
+ }
483
+ #[allow(clippy::too_many_arguments)]
484
+ pub fn body_set_transform(&self, h: f64, px: f32, py: f32, pz: f32, rx: f32, ry: f32, rz: f32, rw: f32, activate: bool) {
485
+ if let Some((w, b)) = self.resolve_body(h) {
486
+ let x = BjTransform { position: BjVec3 { x: px, y: py, z: pz }, rotation: BjQuat { x: rx, y: ry, z: rz, w: rw } };
487
+ unsafe { bj_body_set_transform(w, b, &x, if activate { BjActivation::Activate } else { BjActivation::DontActivate }); }
488
+ }
489
+ }
490
+ #[allow(clippy::too_many_arguments)]
491
+ pub fn body_move_kinematic(&self, h: f64, px: f32, py: f32, pz: f32, rx: f32, ry: f32, rz: f32, rw: f32, dt: f32) {
492
+ if let Some((w, b)) = self.resolve_body(h) {
493
+ let target = BjTransform { position: BjVec3 { x: px, y: py, z: pz }, rotation: BjQuat { x: rx, y: ry, z: rz, w: rw } };
494
+ unsafe { bj_body_move_kinematic(w, b, &target, dt); }
495
+ }
496
+ }
497
+
498
+ pub fn body_get_linear_velocity_axis(&self, h: f64, axis: u32) -> f64 {
499
+ if let Some((w, b)) = self.resolve_body(h) {
500
+ let mut v = BjVec3::default();
501
+ unsafe { bj_body_get_linear_velocity(w, b, &mut v); }
502
+ return match axis { 0 => v.x, 1 => v.y, 2 => v.z, _ => 0.0 } as f64;
503
+ }
504
+ 0.0
505
+ }
506
+ pub fn body_get_angular_velocity_axis(&self, h: f64, axis: u32) -> f64 {
507
+ if let Some((w, b)) = self.resolve_body(h) {
508
+ let mut v = BjVec3::default();
509
+ unsafe { bj_body_get_angular_velocity(w, b, &mut v); }
510
+ return match axis { 0 => v.x, 1 => v.y, 2 => v.z, _ => 0.0 } as f64;
511
+ }
512
+ 0.0
513
+ }
514
+ pub fn body_get_point_velocity_axis(&self, h: f64, px: f32, py: f32, pz: f32, axis: u32) -> f64 {
515
+ if let Some((w, b)) = self.resolve_body(h) {
516
+ let mut v = BjVec3::default();
517
+ unsafe { bj_body_get_point_velocity(w, b, BjVec3 { x: px, y: py, z: pz }, &mut v); }
518
+ return match axis { 0 => v.x, 1 => v.y, 2 => v.z, _ => 0.0 } as f64;
519
+ }
520
+ 0.0
521
+ }
522
+ pub fn body_set_linear_velocity(&self, h: f64, x: f32, y: f32, z: f32) {
523
+ if let Some((w, b)) = self.resolve_body(h) { unsafe { bj_body_set_linear_velocity(w, b, BjVec3 { x, y, z }); } }
524
+ }
525
+ pub fn body_set_angular_velocity(&self, h: f64, x: f32, y: f32, z: f32) {
526
+ if let Some((w, b)) = self.resolve_body(h) { unsafe { bj_body_set_angular_velocity(w, b, BjVec3 { x, y, z }); } }
527
+ }
528
+
529
+ pub fn body_add_force(&self, h: f64, x: f32, y: f32, z: f32) {
530
+ if let Some((w, b)) = self.resolve_body(h) { unsafe { bj_body_add_force(w, b, BjVec3 { x, y, z }); } }
531
+ }
532
+ pub fn body_add_impulse(&self, h: f64, x: f32, y: f32, z: f32) {
533
+ if let Some((w, b)) = self.resolve_body(h) { unsafe { bj_body_add_impulse(w, b, BjVec3 { x, y, z }); } }
534
+ }
535
+ pub fn body_add_torque(&self, h: f64, x: f32, y: f32, z: f32) {
536
+ if let Some((w, b)) = self.resolve_body(h) { unsafe { bj_body_add_torque(w, b, BjVec3 { x, y, z }); } }
537
+ }
538
+ pub fn body_add_angular_impulse(&self, h: f64, x: f32, y: f32, z: f32) {
539
+ if let Some((w, b)) = self.resolve_body(h) { unsafe { bj_body_add_angular_impulse(w, b, BjVec3 { x, y, z }); } }
540
+ }
541
+ #[allow(clippy::too_many_arguments)]
542
+ pub fn body_add_force_at(&self, h: f64, fx: f32, fy: f32, fz: f32, px: f32, py: f32, pz: f32) {
543
+ if let Some((w, b)) = self.resolve_body(h) {
544
+ unsafe { bj_body_add_force_at(w, b, BjVec3 { x: fx, y: fy, z: fz }, BjVec3 { x: px, y: py, z: pz }); }
545
+ }
546
+ }
547
+ #[allow(clippy::too_many_arguments)]
548
+ pub fn body_add_impulse_at(&self, h: f64, ix: f32, iy: f32, iz: f32, px: f32, py: f32, pz: f32) {
549
+ if let Some((w, b)) = self.resolve_body(h) {
550
+ unsafe { bj_body_add_impulse_at(w, b, BjVec3 { x: ix, y: iy, z: iz }, BjVec3 { x: px, y: py, z: pz }); }
551
+ }
552
+ }
553
+
554
+ pub fn body_set_friction(&self, h: f64, v: f32) { if let Some((w, b)) = self.resolve_body(h) { unsafe { bj_body_set_friction(w, b, v); } } }
555
+ pub fn body_set_restitution(&self, h: f64, v: f32) { if let Some((w, b)) = self.resolve_body(h) { unsafe { bj_body_set_restitution(w, b, v); } } }
556
+ pub fn body_set_linear_damping(&self, h: f64, v: f32) { if let Some((w, b)) = self.resolve_body(h) { unsafe { bj_body_set_linear_damping(w, b, v); } } }
557
+ pub fn body_set_angular_damping(&self, h: f64, v: f32) { if let Some((w, b)) = self.resolve_body(h) { unsafe { bj_body_set_angular_damping(w, b, v); } } }
558
+ pub fn body_set_gravity_factor(&self, h: f64, v: f32) { if let Some((w, b)) = self.resolve_body(h) { unsafe { bj_body_set_gravity_factor(w, b, v); } } }
559
+ pub fn body_set_ccd(&self, h: f64, enabled: bool) { if let Some((w, b)) = self.resolve_body(h) { unsafe { bj_body_set_ccd(w, b, enabled as u8); } } }
560
+ pub fn body_set_motion_type(&self, h: f64, t: u32, activate: bool) {
561
+ if let Some((w, b)) = self.resolve_body(h) {
562
+ let mt = match t { 0 => BjMotionType::Static, 1 => BjMotionType::Kinematic, _ => BjMotionType::Dynamic };
563
+ unsafe { bj_body_set_motion_type(w, b, mt, if activate { BjActivation::Activate } else { BjActivation::DontActivate }); }
564
+ }
565
+ }
566
+ pub fn body_set_object_layer(&self, h: f64, layer: u32) { if let Some((w, b)) = self.resolve_body(h) { unsafe { bj_body_set_object_layer(w, b, layer); } } }
567
+ pub fn body_set_is_sensor(&self, h: f64, enabled: bool) { if let Some((w, b)) = self.resolve_body(h) { unsafe { bj_body_set_is_sensor(w, b, enabled as u8); } } }
568
+ pub fn body_set_allow_sleeping(&self, h: f64, enabled: bool) { if let Some((w, b)) = self.resolve_body(h) { unsafe { bj_body_set_allow_sleeping(w, b, enabled as u8); } } }
569
+ pub fn body_set_shape(&self, h: f64, shape_h: f64, update_mass: bool, activate: bool) {
570
+ if let (Some((w, b)), Some(&s)) = (self.resolve_body(h), self.shapes.get(shape_h)) {
571
+ unsafe { bj_body_set_shape(w, b, s, update_mass as u8, if activate { BjActivation::Activate } else { BjActivation::DontActivate }); }
572
+ }
573
+ }
574
+ pub fn body_lock_rotation_axes(&self, h: f64, x: bool, y: bool, z: bool) {
575
+ if let Some((w, b)) = self.resolve_body(h) { unsafe { bj_body_lock_rotation_axes(w, b, x as u8, y as u8, z as u8); } }
576
+ }
577
+ pub fn body_lock_translation_axes(&self, h: f64, x: bool, y: bool, z: bool) {
578
+ if let Some((w, b)) = self.resolve_body(h) { unsafe { bj_body_lock_translation_axes(w, b, x as u8, y as u8, z as u8); } }
579
+ }
580
+
581
+ pub fn body_get_mass(&self, h: f64) -> f32 { self.resolve_body(h).map(|(w, b)| unsafe { bj_body_get_mass(w, b) }).unwrap_or(0.0) }
582
+ pub fn body_get_friction(&self, h: f64) -> f32 { self.resolve_body(h).map(|(w, b)| unsafe { bj_body_get_friction(w, b) }).unwrap_or(0.0) }
583
+ pub fn body_get_restitution(&self, h: f64) -> f32 { self.resolve_body(h).map(|(w, b)| unsafe { bj_body_get_restitution(w, b) }).unwrap_or(0.0) }
584
+ pub fn body_get_object_layer(&self, h: f64) -> u32 { self.resolve_body(h).map(|(w, b)| unsafe { bj_body_get_object_layer(w, b) }).unwrap_or(0) }
585
+
586
+ pub fn body_set_user_data(&self, h: f64, user_data: u64) {
587
+ if let Some((w, b)) = self.resolve_body(h) { unsafe { bj_body_set_user_data(w, b, user_data); } }
588
+ }
589
+ pub fn body_get_user_data(&self, h: f64) -> u64 {
590
+ self.resolve_body(h).map(|(w, b)| unsafe { bj_body_get_user_data(w, b) }).unwrap_or(0)
591
+ }
592
+
593
+ // -------------------------------------------------------- Queries
594
+
595
+ /// Single-hit raycast. Stores the hit (if any) at cache index 0.
596
+ #[allow(clippy::too_many_arguments)]
597
+ pub fn raycast_closest(
598
+ &mut self, world_h: f64,
599
+ ox: f32, oy: f32, oz: f32,
600
+ dx: f32, dy: f32, dz: f32,
601
+ max_distance: f32, layer_mask: u32,
602
+ ) -> bool {
603
+ self.ray_hit_cache.hits.clear();
604
+ let world = match self.worlds.get(world_h) { Some(&w) => w, None => return false };
605
+ let mut hit: BjRayHit = unsafe { std::mem::zeroed() };
606
+ let any = unsafe {
607
+ bj_query_raycast_closest(world,
608
+ BjVec3 { x: ox, y: oy, z: oz },
609
+ BjVec3 { x: dx, y: dy, z: dz },
610
+ max_distance, layer_mask, &mut hit)
611
+ };
612
+ if any != 0 {
613
+ self.ray_hit_cache.hits.push(hit);
614
+ true
615
+ } else { false }
616
+ }
617
+
618
+ /// Multi-hit raycast. Stores up to max_hits in the cache.
619
+ #[allow(clippy::too_many_arguments)]
620
+ pub fn raycast_all(
621
+ &mut self, world_h: f64,
622
+ ox: f32, oy: f32, oz: f32,
623
+ dx: f32, dy: f32, dz: f32,
624
+ max_distance: f32, layer_mask: u32, max_hits: u32,
625
+ ) -> u32 {
626
+ self.ray_hit_cache.hits.clear();
627
+ let world = match self.worlds.get(world_h) { Some(&w) => w, None => return 0 };
628
+ self.ray_hit_cache.hits.resize(max_hits as usize, unsafe { std::mem::zeroed() });
629
+ let n = unsafe {
630
+ bj_query_raycast_all(world,
631
+ BjVec3 { x: ox, y: oy, z: oz },
632
+ BjVec3 { x: dx, y: dy, z: dz },
633
+ max_distance, layer_mask,
634
+ self.ray_hit_cache.hits.as_mut_ptr(), max_hits)
635
+ };
636
+ self.ray_hit_cache.hits.truncate(n as usize);
637
+ n
638
+ }
639
+
640
+ pub fn ray_hit_count(&self) -> u32 { self.ray_hit_cache.hits.len() as u32 }
641
+ pub fn ray_hit_body(&self, i: usize) -> f64 {
642
+ self.ray_hit_cache.hits.get(i)
643
+ .and_then(|h| self.bodies.iter().find(|(_, (_, b))| *b == h.body).map(|(hh, _)| hh))
644
+ .unwrap_or(0.0)
645
+ }
646
+ /// field: 0..5 = point.xyz, normal.xyz
647
+ pub fn ray_hit_axis(&self, i: usize, field: u32) -> f64 {
648
+ let h = match self.ray_hit_cache.hits.get(i) { Some(v) => v, None => return 0.0 };
649
+ (match field {
650
+ 0 => h.point.x, 1 => h.point.y, 2 => h.point.z,
651
+ 3 => h.normal.x, 4 => h.normal.y, 5 => h.normal.z,
652
+ _ => 0.0,
653
+ }) as f64
654
+ }
655
+ pub fn ray_hit_fraction(&self, i: usize) -> f32 {
656
+ self.ray_hit_cache.hits.get(i).map(|h| h.fraction).unwrap_or(0.0)
657
+ }
658
+ pub fn ray_hit_sub_shape(&self, i: usize) -> u32 {
659
+ self.ray_hit_cache.hits.get(i).map(|h| h.sub_shape_id).unwrap_or(0)
660
+ }
661
+
662
+ pub fn overlap_sphere(&mut self, world_h: f64, cx: f32, cy: f32, cz: f32, r: f32, layer_mask: u32, max_results: u32) -> u32 {
663
+ self.overlap_cache.bodies.clear();
664
+ let world = match self.worlds.get(world_h) { Some(&w) => w, None => return 0 };
665
+ self.overlap_cache.bodies.resize(max_results as usize, BJ_INVALID);
666
+ let n = unsafe {
667
+ bj_query_overlap_sphere(world,
668
+ BjVec3 { x: cx, y: cy, z: cz }, r, layer_mask,
669
+ self.overlap_cache.bodies.as_mut_ptr(), max_results)
670
+ };
671
+ self.overlap_cache.bodies.truncate(n as usize);
672
+ n
673
+ }
674
+
675
+ pub fn overlap_point(&mut self, world_h: f64, px: f32, py: f32, pz: f32, layer_mask: u32, max_results: u32) -> u32 {
676
+ self.overlap_cache.bodies.clear();
677
+ let world = match self.worlds.get(world_h) { Some(&w) => w, None => return 0 };
678
+ self.overlap_cache.bodies.resize(max_results as usize, BJ_INVALID);
679
+ let n = unsafe {
680
+ bj_query_overlap_point(world,
681
+ BjVec3 { x: px, y: py, z: pz }, layer_mask,
682
+ self.overlap_cache.bodies.as_mut_ptr(), max_results)
683
+ };
684
+ self.overlap_cache.bodies.truncate(n as usize);
685
+ n
686
+ }
687
+
688
+ #[allow(clippy::too_many_arguments)]
689
+ pub fn overlap_box(
690
+ &mut self, world_h: f64,
691
+ px: f32, py: f32, pz: f32, rx: f32, ry: f32, rz: f32, rw: f32,
692
+ hx: f32, hy: f32, hz: f32,
693
+ layer_mask: u32, max_results: u32,
694
+ ) -> u32 {
695
+ self.overlap_cache.bodies.clear();
696
+ let world = match self.worlds.get(world_h) { Some(&w) => w, None => return 0 };
697
+ self.overlap_cache.bodies.resize(max_results as usize, BJ_INVALID);
698
+ let xform = BjTransform { position: BjVec3 { x: px, y: py, z: pz }, rotation: BjQuat { x: rx, y: ry, z: rz, w: rw } };
699
+ let n = unsafe {
700
+ bj_query_overlap_box(world, &xform, BjVec3 { x: hx, y: hy, z: hz }, layer_mask,
701
+ self.overlap_cache.bodies.as_mut_ptr(), max_results)
702
+ };
703
+ self.overlap_cache.bodies.truncate(n as usize);
704
+ n
705
+ }
706
+
707
+ pub fn overlap_body(&self, i: usize) -> f64 {
708
+ self.overlap_cache.bodies.get(i)
709
+ .and_then(|bj| self.bodies.iter().find(|(_, (_, b))| *b == *bj).map(|(h, _)| h))
710
+ .unwrap_or(0.0)
711
+ }
712
+
713
+ // -------------------------------------------------------- Constraints
714
+
715
+ fn make_anchors(&self, body_a_h: f64, body_b_h: f64, ax: f32, ay: f32, az: f32, bx: f32, by: f32, bz: f32, world_space: bool) -> Option<(bj_world, BjConstraintAnchors)> {
716
+ let (wa, ba) = self.resolve_body(body_a_h)?;
717
+ let bb = if body_b_h == 0.0 {
718
+ BJ_INVALID
719
+ } else {
720
+ let (wb, bb) = self.resolve_body(body_b_h)?;
721
+ if wb != wa { return None; }
722
+ bb
723
+ };
724
+ Some((wa, BjConstraintAnchors {
725
+ body_a: ba, body_b: bb,
726
+ anchor_a: BjVec3 { x: ax, y: ay, z: az },
727
+ anchor_b: BjVec3 { x: bx, y: by, z: bz },
728
+ use_world_space: world_space as u8,
729
+ }))
730
+ }
731
+
732
+ #[allow(clippy::too_many_arguments)]
733
+ pub fn constraint_fixed(&mut self, body_a: f64, body_b: f64, ax: f32, ay: f32, az: f32, bx: f32, by: f32, bz: f32, world_space: bool) -> f64 {
734
+ let (w, anchors) = match self.make_anchors(body_a, body_b, ax, ay, az, bx, by, bz, world_space) { Some(v) => v, None => return 0.0 };
735
+ let c = unsafe { bj_constraint_fixed(w, &anchors) };
736
+ if c == BJ_INVALID { 0.0 } else { self.constraints.alloc((w, c)) }
737
+ }
738
+
739
+ #[allow(clippy::too_many_arguments)]
740
+ pub fn constraint_point(&mut self, body_a: f64, body_b: f64, ax: f32, ay: f32, az: f32, bx: f32, by: f32, bz: f32, world_space: bool) -> f64 {
741
+ let (w, anchors) = match self.make_anchors(body_a, body_b, ax, ay, az, bx, by, bz, world_space) { Some(v) => v, None => return 0.0 };
742
+ let c = unsafe { bj_constraint_point(w, &anchors) };
743
+ if c == BJ_INVALID { 0.0 } else { self.constraints.alloc((w, c)) }
744
+ }
745
+
746
+ #[allow(clippy::too_many_arguments)]
747
+ pub fn constraint_hinge(
748
+ &mut self, body_a: f64, body_b: f64,
749
+ ax: f32, ay: f32, az: f32, bx: f32, by: f32, bz: f32,
750
+ axis_x: f32, axis_y: f32, axis_z: f32,
751
+ limit_min: f32, limit_max: f32, world_space: bool,
752
+ ) -> f64 {
753
+ let (w, anchors) = match self.make_anchors(body_a, body_b, ax, ay, az, bx, by, bz, world_space) { Some(v) => v, None => return 0.0 };
754
+ let c = unsafe {
755
+ bj_constraint_hinge(w, &anchors, BjVec3 { x: axis_x, y: axis_y, z: axis_z }, limit_min, limit_max)
756
+ };
757
+ if c == BJ_INVALID { 0.0 } else { self.constraints.alloc((w, c)) }
758
+ }
759
+
760
+ #[allow(clippy::too_many_arguments)]
761
+ pub fn constraint_slider(
762
+ &mut self, body_a: f64, body_b: f64,
763
+ ax: f32, ay: f32, az: f32, bx: f32, by: f32, bz: f32,
764
+ axis_x: f32, axis_y: f32, axis_z: f32,
765
+ limit_min: f32, limit_max: f32, world_space: bool,
766
+ ) -> f64 {
767
+ let (w, anchors) = match self.make_anchors(body_a, body_b, ax, ay, az, bx, by, bz, world_space) { Some(v) => v, None => return 0.0 };
768
+ let c = unsafe {
769
+ bj_constraint_slider(w, &anchors, BjVec3 { x: axis_x, y: axis_y, z: axis_z }, limit_min, limit_max)
770
+ };
771
+ if c == BJ_INVALID { 0.0 } else { self.constraints.alloc((w, c)) }
772
+ }
773
+
774
+ #[allow(clippy::too_many_arguments)]
775
+ pub fn constraint_distance(
776
+ &mut self, body_a: f64, body_b: f64,
777
+ ax: f32, ay: f32, az: f32, bx: f32, by: f32, bz: f32,
778
+ min_distance: f32, max_distance: f32, world_space: bool,
779
+ ) -> f64 {
780
+ let (w, anchors) = match self.make_anchors(body_a, body_b, ax, ay, az, bx, by, bz, world_space) { Some(v) => v, None => return 0.0 };
781
+ let c = unsafe { bj_constraint_distance(w, &anchors, min_distance, max_distance) };
782
+ if c == BJ_INVALID { 0.0 } else { self.constraints.alloc((w, c)) }
783
+ }
784
+
785
+ pub fn constraint_destroy(&mut self, handle: f64) {
786
+ if let Some((w, c)) = self.constraints.free(handle) {
787
+ unsafe { bj_constraint_destroy(w, c); }
788
+ }
789
+ }
790
+
791
+ pub fn constraint_set_enabled(&self, handle: f64, enabled: bool) {
792
+ if let Some(&(w, c)) = self.constraints.get(handle) {
793
+ unsafe { bj_constraint_set_enabled(w, c, enabled as u8); }
794
+ }
795
+ }
796
+
797
+ // -------------------------------------------------------- Contacts
798
+
799
+ pub fn contact_count(&self) -> u32 { self.contact_cache.events.len() as u32 }
800
+
801
+ /// field: 0=event, 1=bodyA, 2=bodyB, 3..5=pointA.xyz, 6..8=pointB.xyz,
802
+ /// 9..11=normal.xyz, 12=depth, 13=friction, 14=restitution
803
+ pub fn contact_field(&self, i: usize, field: u32) -> f64 {
804
+ let c = match self.contact_cache.events.get(i) { Some(v) => v, None => return 0.0 };
805
+ let bj_to_bloom = |bj: bj_body| -> f64 {
806
+ self.bodies.iter().find(|(_, (_, b))| *b == bj).map(|(h, _)| h).unwrap_or(0.0)
807
+ };
808
+ match field {
809
+ 0 => c.event as u32 as f64,
810
+ 1 => bj_to_bloom(c.body_a),
811
+ 2 => bj_to_bloom(c.body_b),
812
+ 3 => c.point_a.x as f64, 4 => c.point_a.y as f64, 5 => c.point_a.z as f64,
813
+ 6 => c.point_b.x as f64, 7 => c.point_b.y as f64, 8 => c.point_b.z as f64,
814
+ 9 => c.normal.x as f64, 10=> c.normal.y as f64, 11=> c.normal.z as f64,
815
+ 12 => c.penetration_depth as f64,
816
+ 13 => c.combined_friction as f64,
817
+ 14 => c.combined_restitution as f64,
818
+ _ => 0.0,
819
+ }
820
+ }
821
+
822
+ pub fn clear_contacts(&mut self) { self.contact_cache.events.clear(); }
823
+
824
+ // -------------------------------------------------------- Character controller
825
+
826
+ #[allow(clippy::too_many_arguments)]
827
+ pub fn character_create(
828
+ &mut self, world_h: f64, shape_h: f64,
829
+ up_x: f32, up_y: f32, up_z: f32,
830
+ max_slope_angle: f32, character_padding: f32,
831
+ penetration_recovery_speed: f32, predictive_contact_distance: f32,
832
+ max_strength: f32, mass: f32, object_layer: u32,
833
+ px: f32, py: f32, pz: f32,
834
+ rx: f32, ry: f32, rz: f32, rw: f32,
835
+ ) -> f64 {
836
+ let world = match self.worlds.get(world_h) { Some(&w) => w, None => return 0.0 };
837
+ let shape = match self.shapes.get(shape_h) { Some(&s) => s, None => return 0.0 };
838
+ let desc = BjCharacterDesc {
839
+ up: BjVec3 { x: up_x, y: up_y, z: up_z },
840
+ max_slope_angle, character_padding, penetration_recovery_speed,
841
+ predictive_contact_distance, max_strength, mass, object_layer,
842
+ };
843
+ let c = unsafe {
844
+ bj_character_create(world, shape, &desc,
845
+ BjVec3 { x: px, y: py, z: pz },
846
+ BjQuat { x: rx, y: ry, z: rz, w: rw })
847
+ };
848
+ if c == BJ_INVALID { 0.0 } else { self.characters.alloc((world, c)) }
849
+ }
850
+
851
+ pub fn character_destroy(&mut self, handle: f64) {
852
+ if let Some((w, c)) = self.characters.free(handle) {
853
+ unsafe { bj_character_destroy(w, c); }
854
+ }
855
+ }
856
+
857
+ fn resolve_character(&self, h: f64) -> Option<(bj_world, bj_character)> {
858
+ self.characters.get(h).copied()
859
+ }
860
+
861
+ pub fn character_update(&self, h: f64, dt: f32, gx: f32, gy: f32, gz: f32) {
862
+ if let Some((w, c)) = self.resolve_character(h) {
863
+ unsafe { bj_character_update(w, c, dt, BjVec3 { x: gx, y: gy, z: gz }); }
864
+ }
865
+ }
866
+
867
+ pub fn character_get_position_axis(&self, h: f64, axis: u32) -> f64 {
868
+ if let Some((w, c)) = self.resolve_character(h) {
869
+ let mut v = BjVec3::default();
870
+ unsafe { bj_character_get_position(w, c, &mut v); }
871
+ return match axis { 0 => v.x, 1 => v.y, 2 => v.z, _ => 0.0 } as f64;
872
+ }
873
+ 0.0
874
+ }
875
+ pub fn character_get_rotation_axis(&self, h: f64, axis: u32) -> f64 {
876
+ if let Some((w, c)) = self.resolve_character(h) {
877
+ let mut q = BjQuat::default();
878
+ unsafe { bj_character_get_rotation(w, c, &mut q); }
879
+ return match axis { 0 => q.x, 1 => q.y, 2 => q.z, 3 => q.w, _ => 0.0 } as f64;
880
+ }
881
+ 0.0
882
+ }
883
+ pub fn character_set_position(&self, h: f64, x: f32, y: f32, z: f32) {
884
+ if let Some((w, c)) = self.resolve_character(h) {
885
+ unsafe { bj_character_set_position(w, c, BjVec3 { x, y, z }); }
886
+ }
887
+ }
888
+ pub fn character_set_rotation(&self, h: f64, x: f32, y: f32, z: f32, ww: f32) {
889
+ if let Some((w, c)) = self.resolve_character(h) {
890
+ unsafe { bj_character_set_rotation(w, c, BjQuat { x, y, z, w: ww }); }
891
+ }
892
+ }
893
+ pub fn character_get_linear_velocity_axis(&self, h: f64, axis: u32) -> f64 {
894
+ if let Some((w, c)) = self.resolve_character(h) {
895
+ let mut v = BjVec3::default();
896
+ unsafe { bj_character_get_linear_velocity(w, c, &mut v); }
897
+ return match axis { 0 => v.x, 1 => v.y, 2 => v.z, _ => 0.0 } as f64;
898
+ }
899
+ 0.0
900
+ }
901
+ pub fn character_set_linear_velocity(&self, h: f64, x: f32, y: f32, z: f32) {
902
+ if let Some((w, c)) = self.resolve_character(h) {
903
+ unsafe { bj_character_set_linear_velocity(w, c, BjVec3 { x, y, z }); }
904
+ }
905
+ }
906
+
907
+ pub fn character_get_ground_state(&self, h: f64) -> u32 {
908
+ if let Some((w, c)) = self.resolve_character(h) {
909
+ return unsafe { bj_character_get_ground_state(w, c) } as u32;
910
+ }
911
+ BjGroundState::InAir as u32
912
+ }
913
+ pub fn character_get_ground_normal_axis(&self, h: f64, axis: u32) -> f64 {
914
+ if let Some((w, c)) = self.resolve_character(h) {
915
+ let mut v = BjVec3::default();
916
+ unsafe { bj_character_get_ground_normal(w, c, &mut v); }
917
+ return match axis { 0 => v.x, 1 => v.y, 2 => v.z, _ => 0.0 } as f64;
918
+ }
919
+ 0.0
920
+ }
921
+ pub fn character_get_ground_position_axis(&self, h: f64, axis: u32) -> f64 {
922
+ if let Some((w, c)) = self.resolve_character(h) {
923
+ let mut v = BjVec3::default();
924
+ unsafe { bj_character_get_ground_position(w, c, &mut v); }
925
+ return match axis { 0 => v.x, 1 => v.y, 2 => v.z, _ => 0.0 } as f64;
926
+ }
927
+ 0.0
928
+ }
929
+ pub fn character_get_ground_body(&self, h: f64) -> f64 {
930
+ if let Some((w, c)) = self.resolve_character(h) {
931
+ let bj = unsafe { bj_character_get_ground_body(w, c) };
932
+ if bj == BJ_INVALID { return 0.0; }
933
+ return self.bodies.iter()
934
+ .find(|(_, (_, b))| *b == bj)
935
+ .map(|(h, _)| h)
936
+ .unwrap_or(0.0);
937
+ }
938
+ 0.0
939
+ }
940
+ pub fn character_set_shape(&self, h: f64, shape_h: f64) {
941
+ if let (Some((w, c)), Some(&s)) = (self.resolve_character(h), self.shapes.get(shape_h)) {
942
+ unsafe { bj_character_set_shape(w, c, s); }
943
+ }
944
+ }
945
+
946
+ // -------------------------------------------------------- Soft bodies
947
+
948
+ /// Create a soft body from scratch-buffered vertex+index streams.
949
+ /// scratch_f32 layout: vertex_count * 4 floats (x, y, z, invMass per vertex).
950
+ /// scratch_u32 layout: triangle_count * 3 indices.
951
+ /// inv_mass == 0 pins the vertex.
952
+ #[allow(clippy::too_many_arguments)]
953
+ pub fn soft_body_create_from_scratch(
954
+ &mut self, world_h: f64,
955
+ vertex_count: u32, triangle_count: u32,
956
+ px: f32, py: f32, pz: f32, rx: f32, ry: f32, rz: f32, rw: f32,
957
+ object_layer: u32,
958
+ edge_compliance: f32, gravity_factor: f32, linear_damping: f32, pressure: f32,
959
+ ) -> f64 {
960
+ let need_f = (vertex_count * 4) as usize;
961
+ let need_u = (triangle_count * 3) as usize;
962
+ if self.scratch_f32.len() < need_f || self.scratch_u32.len() < need_u {
963
+ return 0.0;
964
+ }
965
+ if vertex_count < 3 || triangle_count == 0 { return 0.0; }
966
+ let world = match self.worlds.get(world_h) { Some(&w) => w, None => return 0.0 };
967
+
968
+ let body = unsafe {
969
+ bj_soft_body_create(
970
+ world,
971
+ self.scratch_f32.as_ptr(), vertex_count,
972
+ self.scratch_u32.as_ptr(), triangle_count,
973
+ BjVec3 { x: px, y: py, z: pz },
974
+ BjQuat { x: rx, y: ry, z: rz, w: rw },
975
+ object_layer, edge_compliance, gravity_factor, linear_damping, pressure,
976
+ )
977
+ };
978
+ if body == BJ_INVALID { 0.0 } else { self.bodies.alloc((world, body)) }
979
+ }
980
+
981
+ pub fn soft_body_vertex_count(&self, body_h: f64) -> u32 {
982
+ self.resolve_body(body_h)
983
+ .map(|(w, b)| unsafe { bj_soft_body_vertex_count(w, b) })
984
+ .unwrap_or(0)
985
+ }
986
+ pub fn soft_body_get_vertex_axis(&self, body_h: f64, idx: u32, axis: u32) -> f64 {
987
+ if let Some((w, b)) = self.resolve_body(body_h) {
988
+ let mut v = BjVec3::default();
989
+ unsafe { bj_soft_body_get_vertex(w, b, idx, &mut v); }
990
+ return match axis { 0 => v.x, 1 => v.y, 2 => v.z, _ => 0.0 } as f64;
991
+ }
992
+ 0.0
993
+ }
994
+ pub fn soft_body_set_vertex(&self, body_h: f64, idx: u32, x: f32, y: f32, z: f32) {
995
+ if let Some((w, b)) = self.resolve_body(body_h) {
996
+ unsafe { bj_soft_body_set_vertex(w, b, idx, BjVec3 { x, y, z }); }
997
+ }
998
+ }
999
+ pub fn soft_body_set_vertex_inv_mass(&self, body_h: f64, idx: u32, inv_mass: f32) {
1000
+ if let Some((w, b)) = self.resolve_body(body_h) {
1001
+ unsafe { bj_soft_body_set_vertex_inv_mass(w, b, idx, inv_mass); }
1002
+ }
1003
+ }
1004
+
1005
+ // -------------------------------------------------------- Wheeled vehicles
1006
+
1007
+ #[allow(clippy::too_many_arguments)]
1008
+ pub fn vehicle_create(
1009
+ &mut self, world_h: f64, chassis_shape_h: f64,
1010
+ // Axes
1011
+ up_x: f32, up_y: f32, up_z: f32,
1012
+ fw_x: f32, fw_y: f32, fw_z: f32,
1013
+ // 4 wheel positions (flat array of 12 f32s: fl.xyz, fr.xyz, rl.xyz, rr.xyz)
1014
+ w0x: f32, w0y: f32, w0z: f32,
1015
+ w1x: f32, w1y: f32, w1z: f32,
1016
+ w2x: f32, w2y: f32, w2z: f32,
1017
+ w3x: f32, w3y: f32, w3z: f32,
1018
+ // Shared wheel + engine parameters
1019
+ wheel_radius: f32, wheel_width: f32,
1020
+ suspension_min: f32, suspension_max: f32,
1021
+ max_steer_angle: f32, max_brake_torque: f32, max_handbrake_torque: f32,
1022
+ engine_max_torque: f32, max_pitch_roll_angle: f32,
1023
+ object_layer: u32,
1024
+ // Pose
1025
+ px: f32, py: f32, pz: f32, rx: f32, ry: f32, rz: f32, rw: f32,
1026
+ ) -> (f64, f64) {
1027
+ // Returns (vehicle_handle, chassis_body_handle).
1028
+ let world = match self.worlds.get(world_h) { Some(&w) => w, None => return (0.0, 0.0) };
1029
+ let shape = match self.shapes.get(chassis_shape_h) { Some(&s) => s, None => return (0.0, 0.0) };
1030
+
1031
+ let desc = BjVehicleDesc {
1032
+ up: BjVec3 { x: up_x, y: up_y, z: up_z },
1033
+ forward: BjVec3 { x: fw_x, y: fw_y, z: fw_z },
1034
+ wheel_positions: [
1035
+ BjVec3 { x: w0x, y: w0y, z: w0z },
1036
+ BjVec3 { x: w1x, y: w1y, z: w1z },
1037
+ BjVec3 { x: w2x, y: w2y, z: w2z },
1038
+ BjVec3 { x: w3x, y: w3y, z: w3z },
1039
+ ],
1040
+ wheel_radius, wheel_width,
1041
+ suspension_min_length: suspension_min,
1042
+ suspension_max_length: suspension_max,
1043
+ max_steer_angle, max_brake_torque, max_handbrake_torque,
1044
+ engine_max_torque, max_pitch_roll_angle, object_layer,
1045
+ };
1046
+
1047
+ let vehicle = unsafe {
1048
+ bj_vehicle_create(world, shape, &desc,
1049
+ BjVec3 { x: px, y: py, z: pz },
1050
+ BjQuat { x: rx, y: ry, z: rz, w: rw })
1051
+ };
1052
+ if vehicle == BJ_INVALID { return (0.0, 0.0); }
1053
+
1054
+ // Register the chassis as a regular body so TS can query its transform
1055
+ // via normal body APIs.
1056
+ let chassis_bj = unsafe { bj_vehicle_get_chassis(world, vehicle) };
1057
+ let chassis_h = self.bodies.alloc((world, chassis_bj));
1058
+ let vh = self.vehicles.alloc((world, vehicle, chassis_h));
1059
+ (vh, chassis_h)
1060
+ }
1061
+
1062
+ pub fn vehicle_destroy(&mut self, handle: f64) {
1063
+ if let Some((w, v, chassis_h)) = self.vehicles.free(handle) {
1064
+ unsafe { bj_vehicle_destroy(w, v); }
1065
+ // Chassis was removed by vehicle_destroy; free its Rust handle too.
1066
+ let _ = self.bodies.free(chassis_h);
1067
+ }
1068
+ }
1069
+
1070
+ pub fn vehicle_get_chassis(&self, handle: f64) -> f64 {
1071
+ self.vehicles.get(handle).map(|&(_, _, h)| h).unwrap_or(0.0)
1072
+ }
1073
+
1074
+ fn resolve_vehicle(&self, h: f64) -> Option<(bj_world, bj_vehicle)> {
1075
+ self.vehicles.get(h).map(|&(w, v, _)| (w, v))
1076
+ }
1077
+
1078
+ pub fn vehicle_set_input(&self, handle: f64, forward: f32, right: f32, brake: f32, handbrake: f32) {
1079
+ if let Some((w, v)) = self.resolve_vehicle(handle) {
1080
+ unsafe { bj_vehicle_set_input(w, v, forward, right, brake, handbrake); }
1081
+ }
1082
+ }
1083
+
1084
+ pub fn vehicle_get_wheel_transform(&self, handle: f64, wheel_idx: u32, axis: u32) -> f32 {
1085
+ self.resolve_vehicle(handle)
1086
+ .map(|(w, v)| unsafe { bj_vehicle_get_wheel_transform(w, v, wheel_idx, axis) })
1087
+ .unwrap_or(0.0)
1088
+ }
1089
+
1090
+ pub fn vehicle_get_engine_rpm(&self, handle: f64) -> f32 {
1091
+ self.resolve_vehicle(handle)
1092
+ .map(|(w, v)| unsafe { bj_vehicle_get_engine_rpm(w, v) })
1093
+ .unwrap_or(0.0)
1094
+ }
1095
+
1096
+ pub fn vehicle_get_wheel_angular_velocity(&self, handle: f64, wheel_idx: u32) -> f32 {
1097
+ self.resolve_vehicle(handle)
1098
+ .map(|(w, v)| unsafe { bj_vehicle_get_wheel_angular_velocity(w, v, wheel_idx) })
1099
+ .unwrap_or(0.0)
1100
+ }
1101
+ }
1102
+
1103
+ // ============================================================================
1104
+ // FFI macro — generates the bloom_physics_* symbol set in the invoking crate.
1105
+ //
1106
+ // Usage (in a platform crate, e.g. native/macos/src/lib.rs):
1107
+ //
1108
+ // #[inline]
1109
+ // fn bloom_jolt_ffi_physics() -> &'static mut bloom_shared::physics_jolt::JoltPhysics {
1110
+ // &mut engine().jolt
1111
+ // }
1112
+ // bloom_shared::define_physics_ffi!();
1113
+ //
1114
+ // The macro emits #[no_mangle] extern "C" functions, so each platform crate's
1115
+ // staticlib/cdylib independently re-exports the full Perry FFI surface.
1116
+ // ============================================================================
1117
+
1118
+ #[macro_export]
1119
+ macro_rules! define_physics_ffi {
1120
+ () => {
1121
+ // --- World ---
1122
+
1123
+ #[no_mangle] pub extern "C" fn bloom_physics_create_world(gx: f64, gy: f64, gz: f64, max_bodies: f64, num_threads: f64) -> f64 {
1124
+ bloom_jolt_ffi_physics().create_world(gx as f32, gy as f32, gz as f32, max_bodies as u32, num_threads as u32)
1125
+ }
1126
+ #[no_mangle] pub extern "C" fn bloom_physics_destroy_world(world: f64) { bloom_jolt_ffi_physics().destroy_world(world); }
1127
+ #[no_mangle] pub extern "C" fn bloom_physics_set_gravity(world: f64, gx: f64, gy: f64, gz: f64) {
1128
+ bloom_jolt_ffi_physics().set_gravity(world, gx as f32, gy as f32, gz as f32);
1129
+ }
1130
+ #[no_mangle] pub extern "C" fn bloom_physics_get_gravity(world: f64, axis: f64) -> f64 { bloom_jolt_ffi_physics().get_gravity_axis(world, axis as u32) }
1131
+ #[no_mangle] pub extern "C" fn bloom_physics_optimize_broadphase(world: f64) { bloom_jolt_ffi_physics().optimize_broadphase(world); }
1132
+ #[no_mangle] pub extern "C" fn bloom_physics_step(world: f64, dt: f64, collision_steps: f64) {
1133
+ bloom_jolt_ffi_physics().step(world, dt as f32, collision_steps as u32);
1134
+ }
1135
+ #[no_mangle] pub extern "C" fn bloom_physics_set_layer_collides(world: f64, a: f64, b: f64, collides: f64) {
1136
+ bloom_jolt_ffi_physics().set_layer_collides(world, a as u32, b as u32, collides != 0.0);
1137
+ }
1138
+ #[no_mangle] pub extern "C" fn bloom_physics_get_layer_collides(world: f64, a: f64, b: f64) -> f64 {
1139
+ if bloom_jolt_ffi_physics().get_layer_collides(world, a as u32, b as u32) { 1.0 } else { 0.0 }
1140
+ }
1141
+ #[no_mangle] pub extern "C" fn bloom_physics_body_count(world: f64) -> f64 { bloom_jolt_ffi_physics().body_count(world) as f64 }
1142
+ #[no_mangle] pub extern "C" fn bloom_physics_active_body_count(world: f64) -> f64 { bloom_jolt_ffi_physics().active_body_count(world) as f64 }
1143
+
1144
+ // --- Shapes ---
1145
+
1146
+ #[no_mangle] pub extern "C" fn bloom_physics_shape_box(hx: f64, hy: f64, hz: f64, convex_radius: f64) -> f64 {
1147
+ bloom_jolt_ffi_physics().create_box_shape(hx as f32, hy as f32, hz as f32, convex_radius as f32)
1148
+ }
1149
+ #[no_mangle] pub extern "C" fn bloom_physics_shape_sphere(r: f64) -> f64 { bloom_jolt_ffi_physics().create_sphere_shape(r as f32) }
1150
+ #[no_mangle] pub extern "C" fn bloom_physics_shape_capsule(h: f64, r: f64) -> f64 { bloom_jolt_ffi_physics().create_capsule_shape(h as f32, r as f32) }
1151
+ #[no_mangle] pub extern "C" fn bloom_physics_shape_cylinder(h: f64, r: f64, cr: f64) -> f64 {
1152
+ bloom_jolt_ffi_physics().create_cylinder_shape(h as f32, r as f32, cr as f32)
1153
+ }
1154
+ #[no_mangle] pub extern "C" fn bloom_physics_shape_scaled(base: f64, sx: f64, sy: f64, sz: f64) -> f64 {
1155
+ bloom_jolt_ffi_physics().create_scaled_shape(base, sx as f32, sy as f32, sz as f32)
1156
+ }
1157
+ #[no_mangle] pub extern "C" fn bloom_physics_shape_offset_com(base: f64, ox: f64, oy: f64, oz: f64) -> f64 {
1158
+ bloom_jolt_ffi_physics().create_offset_com_shape(base, ox as f32, oy as f32, oz as f32)
1159
+ }
1160
+ #[no_mangle] pub extern "C" fn bloom_physics_shape_release(shape: f64) { bloom_jolt_ffi_physics().release_shape(shape); }
1161
+
1162
+ // Scratch streams for variable-size shape inputs.
1163
+ #[no_mangle] pub extern "C" fn bloom_physics_scratch_reset() { bloom_jolt_ffi_physics().scratch_reset(); }
1164
+ #[no_mangle] pub extern "C" fn bloom_physics_scratch_push_f32(v: f64) { bloom_jolt_ffi_physics().scratch_push_f32(v as f32); }
1165
+ #[no_mangle] pub extern "C" fn bloom_physics_scratch_push_u32(v: f64) { bloom_jolt_ffi_physics().scratch_push_u32(v as u32); }
1166
+
1167
+ // Complex shape factories — consume scratch streams populated by the caller.
1168
+ #[no_mangle] pub extern "C" fn bloom_physics_shape_convex_hull(num_points: f64, convex_radius: f64) -> f64 {
1169
+ bloom_jolt_ffi_physics().shape_convex_hull_from_scratch(num_points as u32, convex_radius as f32)
1170
+ }
1171
+ #[no_mangle] pub extern "C" fn bloom_physics_shape_mesh(vertex_count: f64, triangle_count: f64) -> f64 {
1172
+ bloom_jolt_ffi_physics().shape_mesh_from_scratch(vertex_count as u32, triangle_count as u32)
1173
+ }
1174
+ #[no_mangle] pub extern "C" fn bloom_physics_shape_heightfield(
1175
+ sample_count: f64, ox: f64, oy: f64, oz: f64, sx: f64, sy: f64, sz: f64, block_size: f64,
1176
+ ) -> f64 {
1177
+ bloom_jolt_ffi_physics().shape_heightfield_from_scratch(
1178
+ sample_count as u32, ox as f32, oy as f32, oz as f32,
1179
+ sx as f32, sy as f32, sz as f32, block_size as u32,
1180
+ )
1181
+ }
1182
+
1183
+ // Compound shape builder — begin / add_child (repeat) / end.
1184
+ #[no_mangle] pub extern "C" fn bloom_physics_compound_begin() { bloom_jolt_ffi_physics().compound_begin(); }
1185
+ #[no_mangle] pub extern "C" fn bloom_physics_compound_add_child(
1186
+ shape: f64, px: f64, py: f64, pz: f64, rx: f64, ry: f64, rz: f64, rw: f64,
1187
+ ) {
1188
+ bloom_jolt_ffi_physics().compound_add_child(
1189
+ shape,
1190
+ px as f32, py as f32, pz as f32,
1191
+ rx as f32, ry as f32, rz as f32, rw as f32,
1192
+ );
1193
+ }
1194
+ #[no_mangle] pub extern "C" fn bloom_physics_compound_end() -> f64 {
1195
+ bloom_jolt_ffi_physics().compound_end()
1196
+ }
1197
+ #[no_mangle] pub extern "C" fn bloom_physics_shape_bounds(shape: f64, axis: f64) -> f64 { bloom_jolt_ffi_physics().shape_bounds_axis(shape, axis as u32) }
1198
+ #[no_mangle] pub extern "C" fn bloom_physics_shape_volume(shape: f64) -> f64 { bloom_jolt_ffi_physics().shape_volume(shape) as f64 }
1199
+
1200
+ // --- Bodies ---
1201
+
1202
+ #[no_mangle] pub extern "C" fn bloom_physics_body_create(
1203
+ world: f64, shape: f64, motion_type: f64,
1204
+ px: f64, py: f64, pz: f64,
1205
+ rx: f64, ry: f64, rz: f64, rw: f64,
1206
+ layer: f64,
1207
+ ) -> f64 {
1208
+ bloom_jolt_ffi_physics().create_body(
1209
+ world, shape, motion_type as u32,
1210
+ px as f32, py as f32, pz as f32,
1211
+ rx as f32, ry as f32, rz as f32, rw as f32,
1212
+ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
1213
+ layer as u32,
1214
+ false, true, false, true,
1215
+ 0.2, 0.0, 0.05, 0.05, 1.0,
1216
+ 0.0, 0.0, 0.0, 0.0,
1217
+ 0,
1218
+ )
1219
+ }
1220
+ #[no_mangle] pub extern "C" fn bloom_physics_body_destroy(body: f64) { bloom_jolt_ffi_physics().destroy_body(body); }
1221
+ #[no_mangle] pub extern "C" fn bloom_physics_body_activate(body: f64) { bloom_jolt_ffi_physics().body_activate(body); }
1222
+ #[no_mangle] pub extern "C" fn bloom_physics_body_deactivate(body: f64) { bloom_jolt_ffi_physics().body_deactivate(body); }
1223
+ #[no_mangle] pub extern "C" fn bloom_physics_body_is_active(body: f64) -> f64 { if bloom_jolt_ffi_physics().body_is_active(body) { 1.0 } else { 0.0 } }
1224
+ #[no_mangle] pub extern "C" fn bloom_physics_body_is_valid(body: f64) -> f64 { if bloom_jolt_ffi_physics().body_is_valid(body) { 1.0 } else { 0.0 } }
1225
+
1226
+ #[no_mangle] pub extern "C" fn bloom_physics_body_get_position(body: f64, axis: f64) -> f64 { bloom_jolt_ffi_physics().body_get_position_axis(body, axis as u32) }
1227
+ #[no_mangle] pub extern "C" fn bloom_physics_body_get_rotation(body: f64, axis: f64) -> f64 { bloom_jolt_ffi_physics().body_get_rotation_axis(body, axis as u32) }
1228
+ #[no_mangle] pub extern "C" fn bloom_physics_body_set_position(body: f64, x: f64, y: f64, z: f64, activate: f64) {
1229
+ bloom_jolt_ffi_physics().body_set_position(body, x as f32, y as f32, z as f32, activate != 0.0);
1230
+ }
1231
+ #[no_mangle] pub extern "C" fn bloom_physics_body_set_rotation(body: f64, x: f64, y: f64, z: f64, w: f64, activate: f64) {
1232
+ bloom_jolt_ffi_physics().body_set_rotation(body, x as f32, y as f32, z as f32, w as f32, activate != 0.0);
1233
+ }
1234
+ #[no_mangle] pub extern "C" fn bloom_physics_body_set_transform(
1235
+ body: f64, px: f64, py: f64, pz: f64, rx: f64, ry: f64, rz: f64, rw: f64, activate: f64,
1236
+ ) {
1237
+ bloom_jolt_ffi_physics().body_set_transform(body, px as f32, py as f32, pz as f32, rx as f32, ry as f32, rz as f32, rw as f32, activate != 0.0);
1238
+ }
1239
+ #[no_mangle] pub extern "C" fn bloom_physics_body_move_kinematic(
1240
+ body: f64, px: f64, py: f64, pz: f64, rx: f64, ry: f64, rz: f64, rw: f64, dt: f64,
1241
+ ) {
1242
+ bloom_jolt_ffi_physics().body_move_kinematic(body, px as f32, py as f32, pz as f32, rx as f32, ry as f32, rz as f32, rw as f32, dt as f32);
1243
+ }
1244
+
1245
+ #[no_mangle] pub extern "C" fn bloom_physics_body_get_linear_velocity(body: f64, axis: f64) -> f64 { bloom_jolt_ffi_physics().body_get_linear_velocity_axis(body, axis as u32) }
1246
+ #[no_mangle] pub extern "C" fn bloom_physics_body_get_angular_velocity(body: f64, axis: f64) -> f64 { bloom_jolt_ffi_physics().body_get_angular_velocity_axis(body, axis as u32) }
1247
+ #[no_mangle] pub extern "C" fn bloom_physics_body_get_point_velocity(body: f64, px: f64, py: f64, pz: f64, axis: f64) -> f64 {
1248
+ bloom_jolt_ffi_physics().body_get_point_velocity_axis(body, px as f32, py as f32, pz as f32, axis as u32)
1249
+ }
1250
+ #[no_mangle] pub extern "C" fn bloom_physics_body_set_linear_velocity(body: f64, x: f64, y: f64, z: f64) {
1251
+ bloom_jolt_ffi_physics().body_set_linear_velocity(body, x as f32, y as f32, z as f32);
1252
+ }
1253
+ #[no_mangle] pub extern "C" fn bloom_physics_body_set_angular_velocity(body: f64, x: f64, y: f64, z: f64) {
1254
+ bloom_jolt_ffi_physics().body_set_angular_velocity(body, x as f32, y as f32, z as f32);
1255
+ }
1256
+
1257
+ #[no_mangle] pub extern "C" fn bloom_physics_body_add_force(body: f64, x: f64, y: f64, z: f64) { bloom_jolt_ffi_physics().body_add_force(body, x as f32, y as f32, z as f32); }
1258
+ #[no_mangle] pub extern "C" fn bloom_physics_body_add_impulse(body: f64, x: f64, y: f64, z: f64) { bloom_jolt_ffi_physics().body_add_impulse(body, x as f32, y as f32, z as f32); }
1259
+ #[no_mangle] pub extern "C" fn bloom_physics_body_add_torque(body: f64, x: f64, y: f64, z: f64) { bloom_jolt_ffi_physics().body_add_torque(body, x as f32, y as f32, z as f32); }
1260
+ #[no_mangle] pub extern "C" fn bloom_physics_body_add_angular_impulse(body: f64, x: f64, y: f64, z: f64) { bloom_jolt_ffi_physics().body_add_angular_impulse(body, x as f32, y as f32, z as f32); }
1261
+ #[no_mangle] pub extern "C" fn bloom_physics_body_add_force_at(body: f64, fx: f64, fy: f64, fz: f64, px: f64, py: f64, pz: f64) {
1262
+ bloom_jolt_ffi_physics().body_add_force_at(body, fx as f32, fy as f32, fz as f32, px as f32, py as f32, pz as f32);
1263
+ }
1264
+ #[no_mangle] pub extern "C" fn bloom_physics_body_add_impulse_at(body: f64, ix: f64, iy: f64, iz: f64, px: f64, py: f64, pz: f64) {
1265
+ bloom_jolt_ffi_physics().body_add_impulse_at(body, ix as f32, iy as f32, iz as f32, px as f32, py as f32, pz as f32);
1266
+ }
1267
+
1268
+ #[no_mangle] pub extern "C" fn bloom_physics_body_set_friction(body: f64, v: f64) { bloom_jolt_ffi_physics().body_set_friction(body, v as f32); }
1269
+ #[no_mangle] pub extern "C" fn bloom_physics_body_set_restitution(body: f64, v: f64) { bloom_jolt_ffi_physics().body_set_restitution(body, v as f32); }
1270
+ #[no_mangle] pub extern "C" fn bloom_physics_body_set_linear_damping(body: f64, v: f64) { bloom_jolt_ffi_physics().body_set_linear_damping(body, v as f32); }
1271
+ #[no_mangle] pub extern "C" fn bloom_physics_body_set_angular_damping(body: f64, v: f64) { bloom_jolt_ffi_physics().body_set_angular_damping(body, v as f32); }
1272
+ #[no_mangle] pub extern "C" fn bloom_physics_body_set_gravity_factor(body: f64, v: f64) { bloom_jolt_ffi_physics().body_set_gravity_factor(body, v as f32); }
1273
+ #[no_mangle] pub extern "C" fn bloom_physics_body_set_ccd(body: f64, enabled: f64) { bloom_jolt_ffi_physics().body_set_ccd(body, enabled != 0.0); }
1274
+ #[no_mangle] pub extern "C" fn bloom_physics_body_set_motion_type(body: f64, t: f64, activate: f64) { bloom_jolt_ffi_physics().body_set_motion_type(body, t as u32, activate != 0.0); }
1275
+ #[no_mangle] pub extern "C" fn bloom_physics_body_set_object_layer(body: f64, layer: f64) { bloom_jolt_ffi_physics().body_set_object_layer(body, layer as u32); }
1276
+ #[no_mangle] pub extern "C" fn bloom_physics_body_set_is_sensor(body: f64, enabled: f64) { bloom_jolt_ffi_physics().body_set_is_sensor(body, enabled != 0.0); }
1277
+ #[no_mangle] pub extern "C" fn bloom_physics_body_set_allow_sleeping(body: f64, enabled: f64) { bloom_jolt_ffi_physics().body_set_allow_sleeping(body, enabled != 0.0); }
1278
+ #[no_mangle] pub extern "C" fn bloom_physics_body_set_shape(body: f64, shape: f64, update_mass: f64, activate: f64) {
1279
+ bloom_jolt_ffi_physics().body_set_shape(body, shape, update_mass != 0.0, activate != 0.0);
1280
+ }
1281
+ #[no_mangle] pub extern "C" fn bloom_physics_body_lock_rotation_axes(body: f64, x: f64, y: f64, z: f64) {
1282
+ bloom_jolt_ffi_physics().body_lock_rotation_axes(body, x != 0.0, y != 0.0, z != 0.0);
1283
+ }
1284
+ #[no_mangle] pub extern "C" fn bloom_physics_body_lock_translation_axes(body: f64, x: f64, y: f64, z: f64) {
1285
+ bloom_jolt_ffi_physics().body_lock_translation_axes(body, x != 0.0, y != 0.0, z != 0.0);
1286
+ }
1287
+
1288
+ #[no_mangle] pub extern "C" fn bloom_physics_body_get_mass(body: f64) -> f64 { bloom_jolt_ffi_physics().body_get_mass(body) as f64 }
1289
+ #[no_mangle] pub extern "C" fn bloom_physics_body_get_friction(body: f64) -> f64 { bloom_jolt_ffi_physics().body_get_friction(body) as f64 }
1290
+ #[no_mangle] pub extern "C" fn bloom_physics_body_get_restitution(body: f64) -> f64 { bloom_jolt_ffi_physics().body_get_restitution(body) as f64 }
1291
+ #[no_mangle] pub extern "C" fn bloom_physics_body_get_object_layer(body: f64) -> f64 { bloom_jolt_ffi_physics().body_get_object_layer(body) as f64 }
1292
+ #[no_mangle] pub extern "C" fn bloom_physics_body_set_user_data(body: f64, lo: f64, hi: f64) {
1293
+ let user = (lo as u64) | ((hi as u64) << 32);
1294
+ bloom_jolt_ffi_physics().body_set_user_data(body, user);
1295
+ }
1296
+ #[no_mangle] pub extern "C" fn bloom_physics_body_get_user_data(body: f64, part: f64) -> f64 {
1297
+ let u = bloom_jolt_ffi_physics().body_get_user_data(body);
1298
+ (if part as u32 == 1 { (u >> 32) as u32 } else { u as u32 }) as f64
1299
+ }
1300
+
1301
+ // --- Queries ---
1302
+
1303
+ #[no_mangle] pub extern "C" fn bloom_physics_raycast(
1304
+ world: f64, ox: f64, oy: f64, oz: f64,
1305
+ dx: f64, dy: f64, dz: f64, max_dist: f64, layer_mask: f64,
1306
+ ) -> f64 {
1307
+ if bloom_jolt_ffi_physics().raycast_closest(world, ox as f32, oy as f32, oz as f32, dx as f32, dy as f32, dz as f32, max_dist as f32, layer_mask as u32) { 1.0 } else { 0.0 }
1308
+ }
1309
+ #[no_mangle] pub extern "C" fn bloom_physics_raycast_all(
1310
+ world: f64, ox: f64, oy: f64, oz: f64,
1311
+ dx: f64, dy: f64, dz: f64, max_dist: f64, layer_mask: f64, max_hits: f64,
1312
+ ) -> f64 {
1313
+ bloom_jolt_ffi_physics().raycast_all(world, ox as f32, oy as f32, oz as f32, dx as f32, dy as f32, dz as f32, max_dist as f32, layer_mask as u32, max_hits as u32) as f64
1314
+ }
1315
+ #[no_mangle] pub extern "C" fn bloom_physics_ray_hit_count() -> f64 { bloom_jolt_ffi_physics().ray_hit_count() as f64 }
1316
+ #[no_mangle] pub extern "C" fn bloom_physics_ray_hit_body(i: f64) -> f64 { bloom_jolt_ffi_physics().ray_hit_body(i as usize) }
1317
+ #[no_mangle] pub extern "C" fn bloom_physics_ray_hit_axis(i: f64, field: f64) -> f64 { bloom_jolt_ffi_physics().ray_hit_axis(i as usize, field as u32) }
1318
+ #[no_mangle] pub extern "C" fn bloom_physics_ray_hit_fraction(i: f64) -> f64 { bloom_jolt_ffi_physics().ray_hit_fraction(i as usize) as f64 }
1319
+ #[no_mangle] pub extern "C" fn bloom_physics_ray_hit_sub_shape(i: f64) -> f64 { bloom_jolt_ffi_physics().ray_hit_sub_shape(i as usize) as f64 }
1320
+
1321
+ #[no_mangle] pub extern "C" fn bloom_physics_overlap_sphere(world: f64, cx: f64, cy: f64, cz: f64, r: f64, layer_mask: f64, max_results: f64) -> f64 {
1322
+ bloom_jolt_ffi_physics().overlap_sphere(world, cx as f32, cy as f32, cz as f32, r as f32, layer_mask as u32, max_results as u32) as f64
1323
+ }
1324
+ #[no_mangle] pub extern "C" fn bloom_physics_overlap_point(world: f64, px: f64, py: f64, pz: f64, layer_mask: f64, max_results: f64) -> f64 {
1325
+ bloom_jolt_ffi_physics().overlap_point(world, px as f32, py as f32, pz as f32, layer_mask as u32, max_results as u32) as f64
1326
+ }
1327
+ #[no_mangle] pub extern "C" fn bloom_physics_overlap_box(
1328
+ world: f64, px: f64, py: f64, pz: f64, rx: f64, ry: f64, rz: f64, rw: f64,
1329
+ hx: f64, hy: f64, hz: f64, layer_mask: f64, max_results: f64,
1330
+ ) -> f64 {
1331
+ bloom_jolt_ffi_physics().overlap_box(world, px as f32, py as f32, pz as f32, rx as f32, ry as f32, rz as f32, rw as f32, hx as f32, hy as f32, hz as f32, layer_mask as u32, max_results as u32) as f64
1332
+ }
1333
+ #[no_mangle] pub extern "C" fn bloom_physics_overlap_body(i: f64) -> f64 { bloom_jolt_ffi_physics().overlap_body(i as usize) }
1334
+
1335
+ // --- Constraints ---
1336
+
1337
+ #[no_mangle] pub extern "C" fn bloom_physics_constraint_fixed(
1338
+ body_a: f64, body_b: f64, ax: f64, ay: f64, az: f64, bx: f64, by: f64, bz: f64, world_space: f64,
1339
+ ) -> f64 {
1340
+ bloom_jolt_ffi_physics().constraint_fixed(body_a, body_b, ax as f32, ay as f32, az as f32, bx as f32, by as f32, bz as f32, world_space != 0.0)
1341
+ }
1342
+ #[no_mangle] pub extern "C" fn bloom_physics_constraint_point(
1343
+ body_a: f64, body_b: f64, ax: f64, ay: f64, az: f64, bx: f64, by: f64, bz: f64, world_space: f64,
1344
+ ) -> f64 {
1345
+ bloom_jolt_ffi_physics().constraint_point(body_a, body_b, ax as f32, ay as f32, az as f32, bx as f32, by as f32, bz as f32, world_space != 0.0)
1346
+ }
1347
+ #[no_mangle] pub extern "C" fn bloom_physics_constraint_hinge(
1348
+ body_a: f64, body_b: f64, ax: f64, ay: f64, az: f64, bx: f64, by: f64, bz: f64,
1349
+ axx: f64, axy: f64, axz: f64, lmin: f64, lmax: f64, world_space: f64,
1350
+ ) -> f64 {
1351
+ bloom_jolt_ffi_physics().constraint_hinge(
1352
+ body_a, body_b,
1353
+ ax as f32, ay as f32, az as f32, bx as f32, by as f32, bz as f32,
1354
+ axx as f32, axy as f32, axz as f32,
1355
+ lmin as f32, lmax as f32, world_space != 0.0,
1356
+ )
1357
+ }
1358
+ #[no_mangle] pub extern "C" fn bloom_physics_constraint_slider(
1359
+ body_a: f64, body_b: f64, ax: f64, ay: f64, az: f64, bx: f64, by: f64, bz: f64,
1360
+ axx: f64, axy: f64, axz: f64, lmin: f64, lmax: f64, world_space: f64,
1361
+ ) -> f64 {
1362
+ bloom_jolt_ffi_physics().constraint_slider(
1363
+ body_a, body_b,
1364
+ ax as f32, ay as f32, az as f32, bx as f32, by as f32, bz as f32,
1365
+ axx as f32, axy as f32, axz as f32,
1366
+ lmin as f32, lmax as f32, world_space != 0.0,
1367
+ )
1368
+ }
1369
+ #[no_mangle] pub extern "C" fn bloom_physics_constraint_distance(
1370
+ body_a: f64, body_b: f64, ax: f64, ay: f64, az: f64, bx: f64, by: f64, bz: f64,
1371
+ min_d: f64, max_d: f64, world_space: f64,
1372
+ ) -> f64 {
1373
+ bloom_jolt_ffi_physics().constraint_distance(body_a, body_b, ax as f32, ay as f32, az as f32, bx as f32, by as f32, bz as f32, min_d as f32, max_d as f32, world_space != 0.0)
1374
+ }
1375
+ #[no_mangle] pub extern "C" fn bloom_physics_constraint_destroy(c: f64) { bloom_jolt_ffi_physics().constraint_destroy(c); }
1376
+ #[no_mangle] pub extern "C" fn bloom_physics_constraint_set_enabled(c: f64, enabled: f64) { bloom_jolt_ffi_physics().constraint_set_enabled(c, enabled != 0.0); }
1377
+
1378
+ // --- Contact events ---
1379
+
1380
+ #[no_mangle] pub extern "C" fn bloom_physics_contact_count() -> f64 { bloom_jolt_ffi_physics().contact_count() as f64 }
1381
+ #[no_mangle] pub extern "C" fn bloom_physics_contact_field(i: f64, field: f64) -> f64 { bloom_jolt_ffi_physics().contact_field(i as usize, field as u32) }
1382
+ #[no_mangle] pub extern "C" fn bloom_physics_clear_contacts(world: f64) { let _ = world; bloom_jolt_ffi_physics().clear_contacts(); }
1383
+
1384
+ // --- Character controller (Tier 2) ---
1385
+
1386
+ #[no_mangle] pub extern "C" fn bloom_physics_character_create(
1387
+ world: f64, shape: f64,
1388
+ up_x: f64, up_y: f64, up_z: f64,
1389
+ max_slope_angle: f64, character_padding: f64,
1390
+ penetration_recovery_speed: f64, predictive_contact_distance: f64,
1391
+ max_strength: f64, mass: f64, object_layer: f64,
1392
+ px: f64, py: f64, pz: f64,
1393
+ rx: f64, ry: f64, rz: f64, rw: f64,
1394
+ ) -> f64 {
1395
+ bloom_jolt_ffi_physics().character_create(
1396
+ world, shape,
1397
+ up_x as f32, up_y as f32, up_z as f32,
1398
+ max_slope_angle as f32, character_padding as f32,
1399
+ penetration_recovery_speed as f32, predictive_contact_distance as f32,
1400
+ max_strength as f32, mass as f32, object_layer as u32,
1401
+ px as f32, py as f32, pz as f32,
1402
+ rx as f32, ry as f32, rz as f32, rw as f32,
1403
+ )
1404
+ }
1405
+ #[no_mangle] pub extern "C" fn bloom_physics_character_destroy(c: f64) { bloom_jolt_ffi_physics().character_destroy(c); }
1406
+ #[no_mangle] pub extern "C" fn bloom_physics_character_update(c: f64, dt: f64, gx: f64, gy: f64, gz: f64) {
1407
+ bloom_jolt_ffi_physics().character_update(c, dt as f32, gx as f32, gy as f32, gz as f32);
1408
+ }
1409
+ #[no_mangle] pub extern "C" fn bloom_physics_character_get_position(c: f64, axis: f64) -> f64 {
1410
+ bloom_jolt_ffi_physics().character_get_position_axis(c, axis as u32)
1411
+ }
1412
+ #[no_mangle] pub extern "C" fn bloom_physics_character_get_rotation(c: f64, axis: f64) -> f64 {
1413
+ bloom_jolt_ffi_physics().character_get_rotation_axis(c, axis as u32)
1414
+ }
1415
+ #[no_mangle] pub extern "C" fn bloom_physics_character_set_position(c: f64, x: f64, y: f64, z: f64) {
1416
+ bloom_jolt_ffi_physics().character_set_position(c, x as f32, y as f32, z as f32);
1417
+ }
1418
+ #[no_mangle] pub extern "C" fn bloom_physics_character_set_rotation(c: f64, x: f64, y: f64, z: f64, w: f64) {
1419
+ bloom_jolt_ffi_physics().character_set_rotation(c, x as f32, y as f32, z as f32, w as f32);
1420
+ }
1421
+ #[no_mangle] pub extern "C" fn bloom_physics_character_get_linear_velocity(c: f64, axis: f64) -> f64 {
1422
+ bloom_jolt_ffi_physics().character_get_linear_velocity_axis(c, axis as u32)
1423
+ }
1424
+ #[no_mangle] pub extern "C" fn bloom_physics_character_set_linear_velocity(c: f64, x: f64, y: f64, z: f64) {
1425
+ bloom_jolt_ffi_physics().character_set_linear_velocity(c, x as f32, y as f32, z as f32);
1426
+ }
1427
+ #[no_mangle] pub extern "C" fn bloom_physics_character_get_ground_state(c: f64) -> f64 {
1428
+ bloom_jolt_ffi_physics().character_get_ground_state(c) as f64
1429
+ }
1430
+ #[no_mangle] pub extern "C" fn bloom_physics_character_get_ground_normal(c: f64, axis: f64) -> f64 {
1431
+ bloom_jolt_ffi_physics().character_get_ground_normal_axis(c, axis as u32)
1432
+ }
1433
+ #[no_mangle] pub extern "C" fn bloom_physics_character_get_ground_position(c: f64, axis: f64) -> f64 {
1434
+ bloom_jolt_ffi_physics().character_get_ground_position_axis(c, axis as u32)
1435
+ }
1436
+ #[no_mangle] pub extern "C" fn bloom_physics_character_get_ground_body(c: f64) -> f64 {
1437
+ bloom_jolt_ffi_physics().character_get_ground_body(c)
1438
+ }
1439
+ #[no_mangle] pub extern "C" fn bloom_physics_character_set_shape(c: f64, shape: f64) {
1440
+ bloom_jolt_ffi_physics().character_set_shape(c, shape);
1441
+ }
1442
+
1443
+ // --- Soft bodies (Tier 2) ---
1444
+
1445
+ #[no_mangle] pub extern "C" fn bloom_physics_soft_body_create(
1446
+ world: f64, vertex_count: f64, triangle_count: f64,
1447
+ px: f64, py: f64, pz: f64, rx: f64, ry: f64, rz: f64, rw: f64,
1448
+ object_layer: f64,
1449
+ edge_compliance: f64, gravity_factor: f64, linear_damping: f64, pressure: f64,
1450
+ ) -> f64 {
1451
+ bloom_jolt_ffi_physics().soft_body_create_from_scratch(
1452
+ world, vertex_count as u32, triangle_count as u32,
1453
+ px as f32, py as f32, pz as f32,
1454
+ rx as f32, ry as f32, rz as f32, rw as f32,
1455
+ object_layer as u32,
1456
+ edge_compliance as f32, gravity_factor as f32,
1457
+ linear_damping as f32, pressure as f32,
1458
+ )
1459
+ }
1460
+ #[no_mangle] pub extern "C" fn bloom_physics_soft_body_vertex_count(body: f64) -> f64 {
1461
+ bloom_jolt_ffi_physics().soft_body_vertex_count(body) as f64
1462
+ }
1463
+ #[no_mangle] pub extern "C" fn bloom_physics_soft_body_get_vertex(body: f64, idx: f64, axis: f64) -> f64 {
1464
+ bloom_jolt_ffi_physics().soft_body_get_vertex_axis(body, idx as u32, axis as u32)
1465
+ }
1466
+ #[no_mangle] pub extern "C" fn bloom_physics_soft_body_set_vertex(body: f64, idx: f64, x: f64, y: f64, z: f64) {
1467
+ bloom_jolt_ffi_physics().soft_body_set_vertex(body, idx as u32, x as f32, y as f32, z as f32);
1468
+ }
1469
+ #[no_mangle] pub extern "C" fn bloom_physics_soft_body_set_vertex_inv_mass(body: f64, idx: f64, inv_mass: f64) {
1470
+ bloom_jolt_ffi_physics().soft_body_set_vertex_inv_mass(body, idx as u32, inv_mass as f32);
1471
+ }
1472
+
1473
+ // --- Wheeled vehicles (Tier 2) ---
1474
+ //
1475
+ // vehicle_create returns a packed f64 carrying BOTH the vehicle handle
1476
+ // and the chassis body handle: (vehicle << 20) | chassis_body. This keeps
1477
+ // the FFI scalar-only while letting TS unpack both. Handles stay <2^20
1478
+ // in practice for any realistic scene.
1479
+
1480
+ #[no_mangle] pub extern "C" fn bloom_physics_vehicle_create(
1481
+ world: f64, chassis_shape: f64,
1482
+ up_x: f64, up_y: f64, up_z: f64,
1483
+ fw_x: f64, fw_y: f64, fw_z: f64,
1484
+ w0x: f64, w0y: f64, w0z: f64,
1485
+ w1x: f64, w1y: f64, w1z: f64,
1486
+ w2x: f64, w2y: f64, w2z: f64,
1487
+ w3x: f64, w3y: f64, w3z: f64,
1488
+ wheel_radius: f64, wheel_width: f64,
1489
+ suspension_min: f64, suspension_max: f64,
1490
+ max_steer_angle: f64, max_brake_torque: f64, max_handbrake_torque: f64,
1491
+ engine_max_torque: f64, max_pitch_roll_angle: f64,
1492
+ object_layer: f64,
1493
+ px: f64, py: f64, pz: f64, rx: f64, ry: f64, rz: f64, rw: f64,
1494
+ ) -> f64 {
1495
+ let (vh, _) = bloom_jolt_ffi_physics().vehicle_create(
1496
+ world, chassis_shape,
1497
+ up_x as f32, up_y as f32, up_z as f32,
1498
+ fw_x as f32, fw_y as f32, fw_z as f32,
1499
+ w0x as f32, w0y as f32, w0z as f32,
1500
+ w1x as f32, w1y as f32, w1z as f32,
1501
+ w2x as f32, w2y as f32, w2z as f32,
1502
+ w3x as f32, w3y as f32, w3z as f32,
1503
+ wheel_radius as f32, wheel_width as f32,
1504
+ suspension_min as f32, suspension_max as f32,
1505
+ max_steer_angle as f32, max_brake_torque as f32, max_handbrake_torque as f32,
1506
+ engine_max_torque as f32, max_pitch_roll_angle as f32,
1507
+ object_layer as u32,
1508
+ px as f32, py as f32, pz as f32,
1509
+ rx as f32, ry as f32, rz as f32, rw as f32,
1510
+ );
1511
+ vh
1512
+ }
1513
+ #[no_mangle] pub extern "C" fn bloom_physics_vehicle_destroy(v: f64) { bloom_jolt_ffi_physics().vehicle_destroy(v); }
1514
+ #[no_mangle] pub extern "C" fn bloom_physics_vehicle_get_chassis(v: f64) -> f64 { bloom_jolt_ffi_physics().vehicle_get_chassis(v) }
1515
+ #[no_mangle] pub extern "C" fn bloom_physics_vehicle_set_input(v: f64, forward: f64, right: f64, brake: f64, handbrake: f64) {
1516
+ bloom_jolt_ffi_physics().vehicle_set_input(v, forward as f32, right as f32, brake as f32, handbrake as f32);
1517
+ }
1518
+ #[no_mangle] pub extern "C" fn bloom_physics_vehicle_get_wheel_transform(v: f64, wheel_index: f64, axis: f64) -> f64 {
1519
+ bloom_jolt_ffi_physics().vehicle_get_wheel_transform(v, wheel_index as u32, axis as u32) as f64
1520
+ }
1521
+ #[no_mangle] pub extern "C" fn bloom_physics_vehicle_get_engine_rpm(v: f64) -> f64 {
1522
+ bloom_jolt_ffi_physics().vehicle_get_engine_rpm(v) as f64
1523
+ }
1524
+ #[no_mangle] pub extern "C" fn bloom_physics_vehicle_get_wheel_angular_velocity(v: f64, wheel_index: f64) -> f64 {
1525
+ bloom_jolt_ffi_physics().vehicle_get_wheel_angular_velocity(v, wheel_index as u32) as f64
1526
+ }
1527
+ };
1528
+ }