@zylem/behaviors 0.4.1 → 0.5.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 (145) hide show
  1. package/README.md +13 -1
  2. package/dist/{behavior-system-y8SGrGWy.d.ts → behavior-system-CeJXzNvr.d.ts} +305 -17
  3. package/dist/{chunk-GFARAJV2.js → chunk-2PAHQZZD.js} +44 -73
  4. package/dist/chunk-2PAHQZZD.js.map +1 -0
  5. package/dist/chunk-52FJIDGL.js +30 -0
  6. package/dist/chunk-52FJIDGL.js.map +1 -0
  7. package/dist/{chunk-UYFOLI2X.js → chunk-5A5AYP2C.js} +1 -1
  8. package/dist/{chunk-UYFOLI2X.js.map → chunk-5A5AYP2C.js.map} +1 -1
  9. package/dist/{chunk-A4CA35DQ.js → chunk-5EBIIYZD.js} +25 -45
  10. package/dist/chunk-5EBIIYZD.js.map +1 -0
  11. package/dist/{chunk-4L36OPY2.js → chunk-5NJGASUJ.js} +81 -135
  12. package/dist/chunk-5NJGASUJ.js.map +1 -0
  13. package/dist/{chunk-27UPCP5B.js → chunk-5UMCWV5A.js} +22 -13
  14. package/dist/chunk-5UMCWV5A.js.map +1 -0
  15. package/dist/chunk-5WRI5ZAA.js +31 -0
  16. package/dist/chunk-5WRI5ZAA.js.map +1 -0
  17. package/dist/{chunk-5SM5SH5O.js → chunk-7JLWZXPA.js} +2 -2
  18. package/dist/{chunk-Z72F2ENM.js → chunk-AEBDZWCP.js} +17 -26
  19. package/dist/chunk-AEBDZWCP.js.map +1 -0
  20. package/dist/chunk-AS3HR7AS.js +188 -0
  21. package/dist/chunk-AS3HR7AS.js.map +1 -0
  22. package/dist/chunk-E4X4YJZB.js +841 -0
  23. package/dist/chunk-E4X4YJZB.js.map +1 -0
  24. package/dist/{chunk-VMQHNJJI.js → chunk-F6ESSHQK.js} +17 -23
  25. package/dist/chunk-F6ESSHQK.js.map +1 -0
  26. package/dist/chunk-GQAPBNGT.js +210 -0
  27. package/dist/chunk-GQAPBNGT.js.map +1 -0
  28. package/dist/chunk-JGXRQUTC.js +191 -0
  29. package/dist/chunk-JGXRQUTC.js.map +1 -0
  30. package/dist/{chunk-BXP4K7RF.js → chunk-JVADRLWX.js} +57 -186
  31. package/dist/chunk-JVADRLWX.js.map +1 -0
  32. package/dist/{chunk-ZA43LPRM.js → chunk-KIYUUSPK.js} +2 -2
  33. package/dist/{chunk-QDCJLJUV.js → chunk-KOWGILCN.js} +22 -13
  34. package/dist/chunk-KOWGILCN.js.map +1 -0
  35. package/dist/{chunk-WWVD5DR5.js → chunk-M3QDKKDF.js} +2 -8
  36. package/dist/chunk-M3QDKKDF.js.map +1 -0
  37. package/dist/{chunk-FTDZAKZW.js → chunk-NQPYMUDF.js} +7 -5
  38. package/dist/{chunk-FTDZAKZW.js.map → chunk-NQPYMUDF.js.map} +1 -1
  39. package/dist/{chunk-XP3ASVGJ.js → chunk-NW4SE5XW.js} +2 -2
  40. package/dist/{chunk-KDY5N6J4.js → chunk-OPZ2LVS2.js} +1 -22
  41. package/dist/{chunk-KDY5N6J4.js.map → chunk-OPZ2LVS2.js.map} +1 -1
  42. package/dist/{chunk-5XZWTFGF.js → chunk-PLIXVF7B.js} +3 -3
  43. package/dist/chunk-PLIXVF7B.js.map +1 -0
  44. package/dist/{chunk-Y7YIAWPW.js → chunk-SGHIGTVZ.js} +1 -11
  45. package/dist/{chunk-Y7YIAWPW.js.map → chunk-SGHIGTVZ.js.map} +1 -1
  46. package/dist/{chunk-UL6Q5HDP.js → chunk-TBUKJKY6.js} +3 -25
  47. package/dist/chunk-TBUKJKY6.js.map +1 -0
  48. package/dist/chunk-VFDUKGRZ.js +155 -0
  49. package/dist/chunk-VFDUKGRZ.js.map +1 -0
  50. package/dist/chunk-VT3H43QA.js +288 -0
  51. package/dist/chunk-VT3H43QA.js.map +1 -0
  52. package/dist/chunk-W26PHBME.js +309 -0
  53. package/dist/chunk-W26PHBME.js.map +1 -0
  54. package/dist/components-BANNjAZP.d.ts +30 -0
  55. package/dist/cooldown.d.ts +2 -2
  56. package/dist/cooldown.js +1 -0
  57. package/dist/coordinators/boundary-ricochet-3d.d.ts +4 -4
  58. package/dist/coordinators/boundary-ricochet-3d.js +1 -0
  59. package/dist/coordinators/boundary-ricochet.d.ts +4 -4
  60. package/dist/coordinators/boundary-ricochet.js +3 -2
  61. package/dist/coordinators/first-person-shooter.js +1 -0
  62. package/dist/coordinators/multidirectional-space-shooter.d.ts +3 -3
  63. package/dist/coordinators/multidirectional-space-shooter.js +5 -3
  64. package/dist/coordinators/top-down-shooter.d.ts +3 -3
  65. package/dist/coordinators/top-down-shooter.js +5 -3
  66. package/dist/core.d.ts +288 -8
  67. package/dist/core.js +480 -13
  68. package/dist/core.js.map +1 -1
  69. package/dist/destructible-3d.d.ts +32 -4
  70. package/dist/destructible-3d.js +2 -1
  71. package/dist/destructible-prebake.js +1 -0
  72. package/dist/{entity-types-CmtQ-IBp.d.ts → entity-types-DhfsZbSK.d.ts} +5 -3
  73. package/dist/first-person.d.ts +27 -38
  74. package/dist/first-person.js +8 -8
  75. package/dist/index.d.ts +14 -15
  76. package/dist/index.js +37 -52
  77. package/dist/jumper-2d.d.ts +3 -17
  78. package/dist/jumper-2d.js +4 -9
  79. package/dist/jumper-3d.d.ts +5 -39
  80. package/dist/jumper-3d.js +5 -10
  81. package/dist/{moveable-Cl9h-_w7.d.ts → moveable-XhzWPAw5.d.ts} +21 -4
  82. package/dist/particle-emitter/presets.js +1 -0
  83. package/dist/particle-emitter.d.ts +3 -3
  84. package/dist/particle-emitter.js +3 -2
  85. package/dist/platformer-2d.d.ts +13 -82
  86. package/dist/platformer-2d.js +4 -5
  87. package/dist/platformer-3d.d.ts +13 -78
  88. package/dist/platformer-3d.js +4 -5
  89. package/dist/ricochet-2d.d.ts +3 -3
  90. package/dist/ricochet-2d.js +4 -3
  91. package/dist/ricochet-3d.d.ts +3 -3
  92. package/dist/ricochet-3d.js +4 -3
  93. package/dist/runtime-2d.d.ts +2 -2
  94. package/dist/runtime-2d.js +1 -0
  95. package/dist/runtime-2d.js.map +1 -1
  96. package/dist/screen-visibility.d.ts +2 -2
  97. package/dist/screen-visibility.js +1 -0
  98. package/dist/screen-wrap.d.ts +2 -2
  99. package/dist/screen-wrap.js +4 -3
  100. package/dist/shooter-2d.d.ts +3 -3
  101. package/dist/shooter-2d.js +4 -3
  102. package/dist/thruster.d.ts +5 -34
  103. package/dist/thruster.js +4 -6
  104. package/dist/top-down-movement.d.ts +9 -27
  105. package/dist/top-down-movement.js +6 -6
  106. package/dist/{vector-Bm65-FOG.d.ts → vector-DjhLUrak.d.ts} +2 -4
  107. package/dist/world-boundary-2d.d.ts +2 -2
  108. package/dist/world-boundary-2d.js +5 -4
  109. package/dist/world-boundary-3d.d.ts +2 -2
  110. package/dist/world-boundary-3d.js +4 -3
  111. package/package.json +2 -3
  112. package/dist/chunk-27UPCP5B.js.map +0 -1
  113. package/dist/chunk-4L36OPY2.js.map +0 -1
  114. package/dist/chunk-4URF65BR.js +0 -44
  115. package/dist/chunk-4URF65BR.js.map +0 -1
  116. package/dist/chunk-5XZWTFGF.js.map +0 -1
  117. package/dist/chunk-67XLJ26X.js +0 -536
  118. package/dist/chunk-67XLJ26X.js.map +0 -1
  119. package/dist/chunk-75FJIUIG.js +0 -240
  120. package/dist/chunk-75FJIUIG.js.map +0 -1
  121. package/dist/chunk-A4CA35DQ.js.map +0 -1
  122. package/dist/chunk-BXP4K7RF.js.map +0 -1
  123. package/dist/chunk-F72WX4MH.js +0 -422
  124. package/dist/chunk-F72WX4MH.js.map +0 -1
  125. package/dist/chunk-GFARAJV2.js.map +0 -1
  126. package/dist/chunk-JXMF4NUI.js +0 -309
  127. package/dist/chunk-JXMF4NUI.js.map +0 -1
  128. package/dist/chunk-OTLSUYQQ.js +0 -29
  129. package/dist/chunk-OTLSUYQQ.js.map +0 -1
  130. package/dist/chunk-Q75LKHDF.js +0 -56
  131. package/dist/chunk-Q75LKHDF.js.map +0 -1
  132. package/dist/chunk-QDCJLJUV.js.map +0 -1
  133. package/dist/chunk-RDHSHEZM.js +0 -479
  134. package/dist/chunk-RDHSHEZM.js.map +0 -1
  135. package/dist/chunk-UIG7MWS2.js +0 -518
  136. package/dist/chunk-UIG7MWS2.js.map +0 -1
  137. package/dist/chunk-UL6Q5HDP.js.map +0 -1
  138. package/dist/chunk-VMQHNJJI.js.map +0 -1
  139. package/dist/chunk-WWVD5DR5.js.map +0 -1
  140. package/dist/chunk-Z72F2ENM.js.map +0 -1
  141. package/dist/components-BWG1GkZA.d.ts +0 -20
  142. package/dist/use-behavior-B85d5u7-.d.ts +0 -13
  143. /package/dist/{chunk-5SM5SH5O.js.map → chunk-7JLWZXPA.js.map} +0 -0
  144. /package/dist/{chunk-ZA43LPRM.js.map → chunk-KIYUUSPK.js.map} +0 -0
  145. /package/dist/{chunk-XP3ASVGJ.js.map → chunk-NW4SE5XW.js.map} +0 -0
@@ -0,0 +1,191 @@
1
+ import {
2
+ createJumpInput3D
3
+ } from "./chunk-4WH2ZN7P.js";
4
+ import {
5
+ SyncStateMachine,
6
+ import_typescript_fsm
7
+ } from "./chunk-AS3HR7AS.js";
8
+ import {
9
+ STAGE_INPUT_BUTTON_JUMP,
10
+ readBehaviorSnapshot
11
+ } from "./chunk-E4X4YJZB.js";
12
+ import {
13
+ defineBehavior
14
+ } from "./chunk-EZNCCO4L.js";
15
+
16
+ // src/lib/behaviors/jumper-3d/jumper-3d-fsm.ts
17
+ var Jumper3DState = /* @__PURE__ */ ((Jumper3DState2) => {
18
+ Jumper3DState2["Grounded"] = "grounded";
19
+ Jumper3DState2["Jumping"] = "jumping";
20
+ Jumper3DState2["Falling"] = "falling";
21
+ return Jumper3DState2;
22
+ })(Jumper3DState || {});
23
+ var Jumper3DEvent = /* @__PURE__ */ ((Jumper3DEvent2) => {
24
+ Jumper3DEvent2["Jump"] = "jump";
25
+ Jumper3DEvent2["Fall"] = "fall";
26
+ Jumper3DEvent2["Land"] = "land";
27
+ return Jumper3DEvent2;
28
+ })(Jumper3DEvent || {});
29
+ var Jumper3DFSM = class {
30
+ constructor(ctx) {
31
+ this.ctx = ctx;
32
+ this.machine = new SyncStateMachine(
33
+ "grounded" /* Grounded */,
34
+ [
35
+ // Grounded
36
+ (0, import_typescript_fsm.t)("grounded" /* Grounded */, "jump" /* Jump */, "jumping" /* Jumping */),
37
+ (0, import_typescript_fsm.t)("grounded" /* Grounded */, "fall" /* Fall */, "falling" /* Falling */),
38
+ (0, import_typescript_fsm.t)("grounded" /* Grounded */, "land" /* Land */, "grounded" /* Grounded */),
39
+ // Jumping
40
+ (0, import_typescript_fsm.t)("jumping" /* Jumping */, "fall" /* Fall */, "falling" /* Falling */),
41
+ (0, import_typescript_fsm.t)("jumping" /* Jumping */, "land" /* Land */, "grounded" /* Grounded */),
42
+ (0, import_typescript_fsm.t)("jumping" /* Jumping */, "jump" /* Jump */, "jumping" /* Jumping */),
43
+ // Falling
44
+ (0, import_typescript_fsm.t)("falling" /* Falling */, "land" /* Land */, "grounded" /* Grounded */),
45
+ (0, import_typescript_fsm.t)("falling" /* Falling */, "jump" /* Jump */, "jumping" /* Jumping */),
46
+ (0, import_typescript_fsm.t)("falling" /* Falling */, "fall" /* Fall */, "falling" /* Falling */)
47
+ ]
48
+ );
49
+ }
50
+ ctx;
51
+ machine;
52
+ getState() {
53
+ return this.machine.getState();
54
+ }
55
+ dispatch(event) {
56
+ if (this.machine.can(event)) {
57
+ this.machine.syncDispatch(event);
58
+ }
59
+ }
60
+ isJumping() {
61
+ return this.getState() === "jumping" /* Jumping */;
62
+ }
63
+ isFalling() {
64
+ return this.getState() === "falling" /* Falling */;
65
+ }
66
+ isGrounded() {
67
+ return this.getState() === "grounded" /* Grounded */;
68
+ }
69
+ getJumpsUsed() {
70
+ return this.ctx.state.jumpsUsed;
71
+ }
72
+ /**
73
+ * Translate a tick event into an FSM dispatch.
74
+ * Also handles the implicit Grounded→Falling transition when the entity
75
+ * is no longer grounded but no explicit event was emitted (e.g. walked
76
+ * off a ledge without jumping).
77
+ */
78
+ applyTickEvent(tickEvent, isGrounded) {
79
+ switch (tickEvent) {
80
+ case "jump":
81
+ this.dispatch("jump" /* Jump */);
82
+ break;
83
+ case "fall":
84
+ this.dispatch("fall" /* Fall */);
85
+ break;
86
+ case "land":
87
+ this.dispatch("land" /* Land */);
88
+ break;
89
+ default:
90
+ if (!isGrounded && this.getState() === "grounded" /* Grounded */) {
91
+ this.dispatch("fall" /* Fall */);
92
+ }
93
+ if (isGrounded && this.getState() !== "grounded" /* Grounded */) {
94
+ this.dispatch("land" /* Land */);
95
+ }
96
+ break;
97
+ }
98
+ }
99
+ };
100
+
101
+ // src/lib/behaviors/jumper-3d/jumper-3d.descriptor.ts
102
+ var defaultOptions = {
103
+ jumpHeight: 2.5,
104
+ gravity: 20,
105
+ maxJumps: 1,
106
+ resetJumpsOnGround: true,
107
+ coyoteTimeMs: 100,
108
+ jumpBufferMs: 80,
109
+ groundRayLength: 1,
110
+ debugGroundProbe: false
111
+ };
112
+ var JUMPER_BEHAVIOR_KEY = /* @__PURE__ */ Symbol.for("zylem:behavior:jumper-3d");
113
+ var Jumper3DBehaviorSystem = class {
114
+ constructor(wasmStage, getBehaviorLinks) {
115
+ this.wasmStage = wasmStage;
116
+ this.getBehaviorLinks = getBehaviorLinks;
117
+ }
118
+ wasmStage;
119
+ getBehaviorLinks;
120
+ attachedRuntimeSlots = /* @__PURE__ */ new Set();
121
+ update(_ecs, _delta) {
122
+ const links = this.getBehaviorLinks?.(JUMPER_BEHAVIOR_KEY);
123
+ if (!links) return;
124
+ for (const link of links) {
125
+ const gameEntity = link.entity;
126
+ const jumperRef = link.ref;
127
+ const options = jumperRef.options;
128
+ const handle = gameEntity.runtimeHandle ?? -1;
129
+ if (!this.wasmStage || handle < 0) continue;
130
+ if (!gameEntity.$jumper) {
131
+ gameEntity.$jumper = createJumpInput3D();
132
+ }
133
+ this.ensureWasmAttached(handle, options);
134
+ jumperRef.__wasmStage = this.wasmStage;
135
+ jumperRef.__entity = gameEntity;
136
+ const input = gameEntity.$jumper;
137
+ const jumpPressed = !!(input.jumpPressed || input.jumpHeld);
138
+ this.wasmStage.writeInputButton(handle, STAGE_INPUT_BUTTON_JUMP, jumpPressed);
139
+ }
140
+ }
141
+ ensureWasmAttached(handle, options) {
142
+ if (!this.wasmStage || this.attachedRuntimeSlots.has(handle)) return;
143
+ const jumpForce = Math.sqrt(2 * (options.gravity ?? 20) * (options.jumpHeight ?? 2.5));
144
+ this.wasmStage.attachJumper3D(handle, {
145
+ jumpForce,
146
+ maxJumps: options.maxJumps ?? 1,
147
+ gravity: options.gravity ?? 20,
148
+ coyoteTime: (options.coyoteTimeMs ?? 100) / 1e3,
149
+ jumpBufferTime: (options.jumpBufferMs ?? 80) / 1e3
150
+ });
151
+ this.attachedRuntimeSlots.add(handle);
152
+ }
153
+ destroy(_ecs) {
154
+ this.attachedRuntimeSlots.clear();
155
+ }
156
+ };
157
+ var Jumper3DBehavior = defineBehavior({
158
+ name: "jumper-3d",
159
+ defaultOptions,
160
+ systemFactory: (ctx) => new Jumper3DBehaviorSystem(
161
+ ctx.wasmStage ?? null,
162
+ ctx.getBehaviorLinks
163
+ ),
164
+ // Handles read the runtime snapshot buffer (previous-step values). The
165
+ // Rust behavior is the single source of truth.
166
+ createHandle: (ref) => {
167
+ const jumpsUsed = () => readBehaviorSnapshot(ref)?.jumpCount ?? 0;
168
+ return {
169
+ getState: () => {
170
+ const snapshot = readBehaviorSnapshot(ref);
171
+ if (!snapshot) return "grounded" /* Grounded */;
172
+ if (snapshot.grounded) return "grounded" /* Grounded */;
173
+ return snapshot.verticalVelocity > 0 ? "jumping" /* Jumping */ : "falling" /* Falling */;
174
+ },
175
+ isJumping: () => {
176
+ const snapshot = readBehaviorSnapshot(ref);
177
+ return snapshot ? !snapshot.grounded && snapshot.verticalVelocity > 0 : false;
178
+ },
179
+ getJumpsUsed: jumpsUsed,
180
+ getJumpsRemaining: () => (ref.options.maxJumps ?? 1) - jumpsUsed()
181
+ };
182
+ }
183
+ });
184
+
185
+ export {
186
+ Jumper3DState,
187
+ Jumper3DEvent,
188
+ Jumper3DFSM,
189
+ Jumper3DBehavior
190
+ };
191
+ //# sourceMappingURL=chunk-JGXRQUTC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/behaviors/jumper-3d/jumper-3d-fsm.ts","../src/lib/behaviors/jumper-3d/jumper-3d.descriptor.ts"],"sourcesContent":["/**\n * Jumper 3D Finite State Machine\n *\n * Three high-level states driven by events emitted from the behavior tick:\n * Grounded ──Jump──▶ Jumping\n * Grounded ──Fall──▶ Falling (walked off a ledge)\n * Jumping ──Fall──▶ Falling (apex / descending)\n * Jumping ──Jump──▶ Jumping (multi-jump)\n * Jumping ──Land──▶ Grounded (rare — very short hop)\n * Falling ──Land──▶ Grounded\n * Falling ──Jump──▶ Jumping (air-jump while falling)\n */\n\nimport { SyncStateMachine, t } from '../../core/utility/sync-state-machine';\nimport type { JumpState3D } from './components';\n\nexport enum Jumper3DState {\n\tGrounded = 'grounded',\n\tJumping = 'jumping',\n\tFalling = 'falling',\n}\n\nexport enum Jumper3DEvent {\n\tJump = 'jump',\n\tFall = 'fall',\n\tLand = 'land',\n}\n\nexport interface Jumper3DFSMContext {\n\tstate: JumpState3D;\n}\n\nexport class Jumper3DFSM {\n\tmachine: SyncStateMachine<Jumper3DState, Jumper3DEvent, never>;\n\n\tconstructor(private ctx: Jumper3DFSMContext) {\n\t\tthis.machine = new SyncStateMachine<Jumper3DState, Jumper3DEvent, never>(\n\t\t\tJumper3DState.Grounded,\n\t\t\t[\n\t\t\t\t// Grounded\n\t\t\t\tt(Jumper3DState.Grounded, Jumper3DEvent.Jump, Jumper3DState.Jumping),\n\t\t\t\tt(Jumper3DState.Grounded, Jumper3DEvent.Fall, Jumper3DState.Falling),\n\t\t\t\tt(Jumper3DState.Grounded, Jumper3DEvent.Land, Jumper3DState.Grounded),\n\n\t\t\t\t// Jumping\n\t\t\t\tt(Jumper3DState.Jumping, Jumper3DEvent.Fall, Jumper3DState.Falling),\n\t\t\t\tt(Jumper3DState.Jumping, Jumper3DEvent.Land, Jumper3DState.Grounded),\n\t\t\t\tt(Jumper3DState.Jumping, Jumper3DEvent.Jump, Jumper3DState.Jumping),\n\n\t\t\t\t// Falling\n\t\t\t\tt(Jumper3DState.Falling, Jumper3DEvent.Land, Jumper3DState.Grounded),\n\t\t\t\tt(Jumper3DState.Falling, Jumper3DEvent.Jump, Jumper3DState.Jumping),\n\t\t\t\tt(Jumper3DState.Falling, Jumper3DEvent.Fall, Jumper3DState.Falling),\n\t\t\t],\n\t\t);\n\t}\n\n\tgetState(): Jumper3DState {\n\t\treturn this.machine.getState();\n\t}\n\n\tdispatch(event: Jumper3DEvent): void {\n\t\tif (this.machine.can(event)) {\n\t\t\tthis.machine.syncDispatch(event);\n\t\t}\n\t}\n\n\tisJumping(): boolean {\n\t\treturn this.getState() === Jumper3DState.Jumping;\n\t}\n\n\tisFalling(): boolean {\n\t\treturn this.getState() === Jumper3DState.Falling;\n\t}\n\n\tisGrounded(): boolean {\n\t\treturn this.getState() === Jumper3DState.Grounded;\n\t}\n\n\tgetJumpsUsed(): number {\n\t\treturn this.ctx.state.jumpsUsed;\n\t}\n\n\t/**\n\t * Translate a tick event into an FSM dispatch.\n\t * Also handles the implicit Grounded→Falling transition when the entity\n\t * is no longer grounded but no explicit event was emitted (e.g. walked\n\t * off a ledge without jumping).\n\t */\n\tapplyTickEvent(tickEvent: string, isGrounded: boolean): void {\n\t\tswitch (tickEvent) {\n\t\t\tcase 'jump':\n\t\t\t\tthis.dispatch(Jumper3DEvent.Jump);\n\t\t\t\tbreak;\n\t\t\tcase 'fall':\n\t\t\t\tthis.dispatch(Jumper3DEvent.Fall);\n\t\t\t\tbreak;\n\t\t\tcase 'land':\n\t\t\t\tthis.dispatch(Jumper3DEvent.Land);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// No explicit event — detect implicit fall\n\t\t\t\tif (!isGrounded && this.getState() === Jumper3DState.Grounded) {\n\t\t\t\t\tthis.dispatch(Jumper3DEvent.Fall);\n\t\t\t\t}\n\t\t\t\tif (isGrounded && this.getState() !== Jumper3DState.Grounded) {\n\t\t\t\t\tthis.dispatch(Jumper3DEvent.Land);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n","/**\n * Jumper 3D Behavior Descriptor\n *\n * Type-safe descriptor for the jumper-3d behavior system.\n * Provides `entity.use()` API for composable 3D jumping.\n */\n\nimport { defineBehavior } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport { Jumper3DState } from './jumper-3d-fsm';\nimport {\n\tcreateJumpInput3D,\n\ttype JumpConfig3D,\n\ttype JumpInput3D,\n\ttype JumpState3D,\n} from './components';\nimport {\n\tSTAGE_INPUT_BUTTON_JUMP,\n\treadBehaviorSnapshot,\n\ttype BehaviorRuntime,\n} from '../../runtime/wasm-stage-runtime';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Options exposed through entity.use()\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface Jumper3DBehaviorOptions {\n\t/** Desired peak height in world units (default: 2.5) */\n\tjumpHeight?: number;\n\t/** Gravity magnitude applied by the behavior (default: 20) */\n\tgravity?: number;\n\t/** Terminal fall speed (optional) */\n\tmaxFallSpeed?: number;\n\t/** Max concurrent jumps, 1 = single, 2 = double, etc. (default: 1) */\n\tmaxJumps?: number;\n\t/** Reset jump counter on ground (default: true) */\n\tresetJumpsOnGround?: boolean;\n\t/** Reset jump counter on wall contact (default: undefined) */\n\tresetJumpsOnWall?: boolean;\n\t/** Coyote time in ms (default: 100) */\n\tcoyoteTimeMs?: number;\n\t/** Jump buffer in ms (default: 80) */\n\tjumpBufferMs?: number;\n\t/** Min cooldown between jumps in ms (optional) */\n\tminTimeBetweenJumpsMs?: number;\n\t/** Variable jump height config (optional) */\n\tvariableJump?: JumpConfig3D['variableJump'];\n\t/** Planar control config (optional) */\n\tplanar?: JumpConfig3D['planar'];\n\t/** Fall tuning (optional) */\n\tfall?: JumpConfig3D['fall'];\n\t/** Ground-detection ray length (default: 1.0) */\n\tgroundRayLength?: number;\n\t/** Max support distance that counts as grounded and can snap to ground */\n\tsnapToGroundDistance?: number;\n\t/** Enable debug visualization for ground probe rays (default: false) */\n\tdebugGroundProbe?: boolean;\n}\n\nconst defaultOptions: Jumper3DBehaviorOptions = {\n\tjumpHeight: 2.5,\n\tgravity: 20,\n\tmaxJumps: 1,\n\tresetJumpsOnGround: true,\n\tcoyoteTimeMs: 100,\n\tjumpBufferMs: 80,\n\tgroundRayLength: 1.0,\n\tdebugGroundProbe: false,\n};\n\nconst JUMPER_BEHAVIOR_KEY = Symbol.for('zylem:behavior:jumper-3d');\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Entity shape expected by the system\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface Jumper3DEntity {\n\tuuid: string;\n\ttransformStore: import('../../capabilities/transform-store').TransformState;\n\tjumper: JumpConfig3D;\n\t$jumper: JumpInput3D;\n\tjumperState: JumpState3D;\n}\n\nexport function isJumper3DGrounded(params: {\n\tsupportToi?: number | null;\n\tvelocityY: number;\n\tsnapToGroundDistance?: number;\n}): boolean {\n\tif (params.snapToGroundDistance != null) {\n\t\treturn (\n\t\t\tparams.supportToi != null &&\n\t\t\tparams.supportToi <= params.snapToGroundDistance &&\n\t\t\tparams.velocityY <= 0.25\n\t\t);\n\t}\n\n\treturn (\n\t\tparams.supportToi != null &&\n\t\tparams.velocityY > -2.0 &&\n\t\tparams.velocityY < 2.0\n\t);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Behavior System adapter\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Forwards jump input into the wasm runtime. The Rust `jumper_3d` Stage\n * behavior (ground probe + jump core) is the single simulation path; handles\n * read its state back via the snapshot buffer.\n */\nclass Jumper3DBehaviorSystem implements BehaviorSystem {\n\tprivate attachedRuntimeSlots = new Set<number>();\n\n\tconstructor(\n\t\tprivate wasmStage: BehaviorRuntime | null,\n\t\tprivate getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t) {}\n\n\tupdate(_ecs: unknown, _delta: number): void {\n\t\tconst links = this.getBehaviorLinks?.(JUMPER_BEHAVIOR_KEY);\n\t\tif (!links) return;\n\n\t\tfor (const link of links) {\n\t\t\tconst gameEntity = link.entity as any;\n\t\t\tconst jumperRef = link.ref as any;\n\n\t\t\tconst options = jumperRef.options as Jumper3DBehaviorOptions;\n\t\t\tconst handle = (gameEntity.runtimeHandle ?? -1) as number;\n\t\t\tif (!this.wasmStage || handle < 0) continue;\n\n\t\t\tif (!gameEntity.$jumper) {\n\t\t\t\tgameEntity.$jumper = createJumpInput3D();\n\t\t\t}\n\n\t\t\tthis.ensureWasmAttached(handle, options);\n\t\t\tjumperRef.__wasmStage = this.wasmStage;\n\t\t\tjumperRef.__entity = gameEntity;\n\t\t\tconst input = gameEntity.$jumper as JumpInput3D;\n\t\t\tconst jumpPressed = !!(input.jumpPressed || input.jumpHeld);\n\t\t\tthis.wasmStage.writeInputButton(handle, STAGE_INPUT_BUTTON_JUMP, jumpPressed);\n\t\t}\n\t}\n\n\tprivate ensureWasmAttached(handle: number, options: Jumper3DBehaviorOptions): void {\n\t\tif (!this.wasmStage || this.attachedRuntimeSlots.has(handle)) return;\n\t\tconst jumpForce = Math.sqrt(2 * (options.gravity ?? 20) * (options.jumpHeight ?? 2.5));\n\t\tthis.wasmStage.attachJumper3D(handle, {\n\t\t\tjumpForce,\n\t\t\tmaxJumps: options.maxJumps ?? 1,\n\t\t\tgravity: options.gravity ?? 20,\n\t\t\tcoyoteTime: (options.coyoteTimeMs ?? 100) / 1000,\n\t\t\tjumpBufferTime: (options.jumpBufferMs ?? 80) / 1000,\n\t\t});\n\t\tthis.attachedRuntimeSlots.add(handle);\n\t}\n\n\tdestroy(_ecs: unknown): void {\n\t\tthis.attachedRuntimeSlots.clear();\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Public descriptor\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Jumper3DBehavior — composable 3D jump behavior.\n *\n * Provides height-based jumping, multi-jump, coyote time, jump buffering,\n * variable jump height, configurable fall gravity, and optional air control.\n *\n * Designed to compose with any movement controller (e.g. FirstPersonBehavior)\n * — the controller writes X/Z velocity and Jumper3DBehavior writes Y velocity.\n *\n * @example\n * ```typescript\n * import { Jumper3DBehavior } from \"@zylem/game-lib/behavior\";\n *\n * const jumper = player.use(Jumper3DBehavior, {\n * jumpHeight: 2.5,\n * gravity: 20,\n * maxJumps: 2,\n * coyoteTimeMs: 100,\n * jumpBufferMs: 80,\n * variableJump: { enabled: true, cutGravityMultiplier: 3 },\n * fall: { fallGravityMultiplier: 1.5 },\n * });\n *\n * player.onUpdate(({ inputs }) => {\n * player.$jumper.jumpPressed = inputs.p1.buttons.A.pressed;\n * player.$jumper.jumpHeld = inputs.p1.buttons.A.held > 0;\n * player.$jumper.jumpReleased = inputs.p1.buttons.A.released;\n *\n * const state = jumper.getState(); // Grounded | Jumping | Falling\n * });\n * ```\n */\nexport const Jumper3DBehavior = defineBehavior<\n\tJumper3DBehaviorOptions,\n\t{\n\t\tgetState: () => Jumper3DState;\n\t\tisJumping: () => boolean;\n\t\tgetJumpsUsed: () => number;\n\t\tgetJumpsRemaining: () => number;\n\t},\n\tJumper3DEntity\n>({\n\tname: 'jumper-3d',\n\tdefaultOptions,\n\tsystemFactory: (ctx) =>\n\t\tnew Jumper3DBehaviorSystem(\n\t\t\tctx.wasmStage ?? null,\n\t\t\tctx.getBehaviorLinks,\n\t\t),\n\t// Handles read the runtime snapshot buffer (previous-step values). The\n\t// Rust behavior is the single source of truth.\n\tcreateHandle: (ref) => {\n\t\tconst jumpsUsed = () => readBehaviorSnapshot(ref)?.jumpCount ?? 0;\n\t\treturn {\n\t\t\tgetState: () => {\n\t\t\t\tconst snapshot = readBehaviorSnapshot(ref);\n\t\t\t\tif (!snapshot) return Jumper3DState.Grounded;\n\t\t\t\tif (snapshot.grounded) return Jumper3DState.Grounded;\n\t\t\t\treturn snapshot.verticalVelocity > 0\n\t\t\t\t\t? Jumper3DState.Jumping\n\t\t\t\t\t: Jumper3DState.Falling;\n\t\t\t},\n\t\t\tisJumping: () => {\n\t\t\t\tconst snapshot = readBehaviorSnapshot(ref);\n\t\t\t\treturn snapshot ? !snapshot.grounded && snapshot.verticalVelocity > 0 : false;\n\t\t\t},\n\t\t\tgetJumpsUsed: jumpsUsed,\n\t\t\tgetJumpsRemaining: () => (ref.options.maxJumps ?? 1) - jumpsUsed(),\n\t\t};\n\t},\n});\n"],"mappings":"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","names":["Jumper3DState","Jumper3DEvent"]}
@@ -10,11 +10,6 @@ import {
10
10
  } from "./chunk-EZNCCO4L.js";
11
11
 
12
12
  // src/lib/behaviors/destructible-3d/destructible-3d.descriptor.ts
13
- import {
14
- ActiveCollisionTypes,
15
- ColliderDesc,
16
- RigidBodyDesc
17
- } from "@dimforge/rapier3d-compat";
18
13
  import {
19
14
  DestructibleMesh,
20
15
  FractureOptions as PinataFractureOptions
@@ -24,111 +19,14 @@ import {
24
19
  BufferAttribute,
25
20
  Group,
26
21
  Matrix4,
27
- Quaternion as Quaternion2,
22
+ Quaternion,
28
23
  Vector2,
29
24
  Vector3
30
25
  } from "three";
31
26
  import * as Comlink from "comlink";
32
-
33
- // src/lib/physics/physics-pose.ts
34
- import { Quaternion } from "three";
35
- var directBodyPoseHistory = /* @__PURE__ */ new WeakMap();
36
- var _previousQuaternion = new Quaternion();
37
- var _currentQuaternion = new Quaternion();
38
- var _renderQuaternion = new Quaternion();
39
- function clonePhysicsVector3(vector) {
40
- return { x: vector.x, y: vector.y, z: vector.z };
41
- }
42
- function clonePhysicsQuaternion(rotation) {
43
- return { x: rotation.x, y: rotation.y, z: rotation.z, w: rotation.w };
44
- }
45
- function clonePhysicsPose(pose) {
46
- return {
47
- position: clonePhysicsVector3(pose.position),
48
- rotation: clonePhysicsQuaternion(pose.rotation)
49
- };
50
- }
51
- function clampInterpolationAlpha(alpha) {
52
- if (!Number.isFinite(alpha)) return 0;
53
- return Math.max(0, Math.min(1, alpha));
54
- }
55
- function capturePhysicsPose(body) {
56
- return {
57
- position: clonePhysicsVector3(body.translation()),
58
- rotation: clonePhysicsQuaternion(body.rotation())
59
- };
60
- }
61
- function createCollapsedPhysicsPoseHistory(pose) {
62
- const current = clonePhysicsPose(pose);
63
- return {
64
- previous: clonePhysicsPose(current),
65
- current
66
- };
67
- }
68
- function collapseDirectBodyPoseHistory(body) {
69
- const pose = capturePhysicsPose(body);
70
- const history = directBodyPoseHistory.get(body) ?? createCollapsedPhysicsPoseHistory(pose);
71
- history.previous = clonePhysicsPose(pose);
72
- history.current = clonePhysicsPose(pose);
73
- directBodyPoseHistory.set(body, history);
74
- return history;
75
- }
76
- function interpolatePhysicsPose(previous, current, alpha) {
77
- const t = clampInterpolationAlpha(alpha);
78
- _previousQuaternion.set(
79
- previous.rotation.x,
80
- previous.rotation.y,
81
- previous.rotation.z,
82
- previous.rotation.w
83
- );
84
- _currentQuaternion.set(
85
- current.rotation.x,
86
- current.rotation.y,
87
- current.rotation.z,
88
- current.rotation.w
89
- );
90
- _renderQuaternion.slerpQuaternions(
91
- _previousQuaternion,
92
- _currentQuaternion,
93
- t
94
- );
95
- return {
96
- position: {
97
- x: previous.position.x + (current.position.x - previous.position.x) * t,
98
- y: previous.position.y + (current.position.y - previous.position.y) * t,
99
- z: previous.position.z + (current.position.z - previous.position.z) * t
100
- },
101
- rotation: {
102
- x: _renderQuaternion.x,
103
- y: _renderQuaternion.y,
104
- z: _renderQuaternion.z,
105
- w: _renderQuaternion.w
106
- }
107
- };
27
+ function getBodyLike(entity) {
28
+ return entity.body ?? null;
108
29
  }
109
- function getBodyRenderPose(body, alpha) {
110
- if (isRenderPoseProvider(body)) {
111
- return body.getRenderPose(alpha);
112
- }
113
- const history = directBodyPoseHistory.get(body);
114
- if (!history) {
115
- return capturePhysicsPose(body);
116
- }
117
- const latestPose = capturePhysicsPose(body);
118
- if (!posesEqual(latestPose, history.current)) {
119
- const collapsed = collapseDirectBodyPoseHistory(body);
120
- return clonePhysicsPose(collapsed.current);
121
- }
122
- return interpolatePhysicsPose(history.previous, history.current, alpha);
123
- }
124
- function isRenderPoseProvider(value) {
125
- return value != null && typeof value === "object" && typeof value.getPoseHistory === "function" && typeof value.getRenderPose === "function";
126
- }
127
- function posesEqual(a, b) {
128
- return a.position.x === b.position.x && a.position.y === b.position.y && a.position.z === b.position.z && a.rotation.x === b.rotation.x && a.rotation.y === b.rotation.y && a.rotation.z === b.rotation.z && a.rotation.w === b.rotation.w;
129
- }
130
-
131
- // src/lib/behaviors/destructible-3d/destructible-3d.descriptor.ts
132
30
  var DESTRUCTIBLE_3D_BEHAVIOR_KEY = /* @__PURE__ */ Symbol.for(
133
31
  "zylem:behavior:destructible-3d"
134
32
  );
@@ -157,8 +55,7 @@ var defaultOptions = {
157
55
  innerMaterial: null,
158
56
  collider: {
159
57
  shape: "convexHull",
160
- sensor: false,
161
- activeCollisionTypes: ActiveCollisionTypes.DEFAULT
58
+ sensor: false
162
59
  },
163
60
  fragmentPhysics: DEFAULT_FRAGMENT_PHYSICS
164
61
  };
@@ -299,8 +196,7 @@ function resolveColliderOptions(input) {
299
196
  return {
300
197
  shape: input?.shape ?? defaultOptions.collider?.shape ?? "convexHull",
301
198
  sensor: input?.sensor ?? defaultOptions.collider?.sensor ?? false,
302
- collisionGroups: input?.collisionGroups,
303
- activeCollisionTypes: input?.activeCollisionTypes ?? defaultOptions.collider?.activeCollisionTypes ?? ActiveCollisionTypes.DEFAULT
199
+ collisionGroups: input?.collisionGroups
304
200
  };
305
201
  }
306
202
  function resolveFragmentPhysicsOptions(input) {
@@ -445,21 +341,6 @@ function instantiatePrebakedFragments(mesh, innerMaterial, templates) {
445
341
  return fragment;
446
342
  });
447
343
  }
448
- function tagConvexHullCollider(colliderDesc, vertices) {
449
- colliderDesc.__zylemShapeData = {
450
- shape: "convexHull",
451
- vertices: Array.from(vertices)
452
- };
453
- return colliderDesc;
454
- }
455
- function tagTrimeshCollider(colliderDesc, vertices, indices) {
456
- colliderDesc.__zylemShapeData = {
457
- shape: "trimesh",
458
- vertices: Array.from(vertices),
459
- indices: Array.from(indices)
460
- };
461
- return colliderDesc;
462
- }
463
344
  function getFragmentVertices(fragment) {
464
345
  const position = fragment.geometry.getAttribute("position");
465
346
  if (!(position instanceof BufferAttribute)) {
@@ -478,62 +359,56 @@ function getFragmentIndices(fragment) {
478
359
  }
479
360
  return Uint32Array.from({ length: position.count }, (_value, index) => index);
480
361
  }
481
- function createCuboidCollider(fragment) {
362
+ function createCuboidColliderShape(fragment) {
482
363
  const bounds = fragment.geometry.boundingBox ?? new Box3();
483
364
  if (!fragment.geometry.boundingBox) {
484
365
  fragment.geometry.computeBoundingBox();
485
366
  }
486
367
  bounds.copy(fragment.geometry.boundingBox ?? bounds);
487
368
  const size = bounds.getSize(new Vector3());
488
- return ColliderDesc.cuboid(
489
- Math.max(size.x / 2, 1e-3),
490
- Math.max(size.y / 2, 1e-3),
491
- Math.max(size.z / 2, 1e-3)
492
- );
369
+ return {
370
+ type: "box",
371
+ halfExtents: [
372
+ Math.max(size.x / 2, 1e-3),
373
+ Math.max(size.y / 2, 1e-3),
374
+ Math.max(size.z / 2, 1e-3)
375
+ ]
376
+ };
493
377
  }
494
- function createFragmentColliderDesc(fragment, options, translation) {
378
+ function createFragmentColliderDefinition(fragment, options, translation) {
495
379
  const resolved = resolveColliderOptions(options);
496
380
  const vertices = getFragmentVertices(fragment);
497
- let colliderDesc = null;
498
- if (resolved.shape === "convexHull") {
499
- colliderDesc = ColliderDesc.convexHull(vertices);
500
- if (colliderDesc) {
501
- colliderDesc = tagConvexHullCollider(colliderDesc, vertices);
502
- }
381
+ let shape = null;
382
+ if (resolved.shape === "convexHull" && vertices.length >= 12) {
383
+ shape = { type: "convexHull", vertices };
503
384
  }
504
- if (!colliderDesc && resolved.shape === "trimesh") {
505
- const indices = getFragmentIndices(fragment);
506
- colliderDesc = tagTrimeshCollider(
507
- ColliderDesc.trimesh(vertices, indices),
508
- vertices,
509
- indices
510
- );
385
+ if (!shape && resolved.shape === "trimesh") {
386
+ shape = { type: "trimesh", vertices, indices: getFragmentIndices(fragment) };
511
387
  }
512
- if (!colliderDesc) {
513
- colliderDesc = createCuboidCollider(fragment);
388
+ if (!shape) {
389
+ shape = createCuboidColliderShape(fragment);
514
390
  }
391
+ const definition = {
392
+ shape,
393
+ sensor: resolved.sensor
394
+ };
515
395
  if (translation) {
516
- colliderDesc.setTranslation(
517
- translation.x,
518
- translation.y,
519
- translation.z
520
- );
396
+ definition.offset = [translation.x, translation.y, translation.z];
521
397
  }
522
- colliderDesc.setSensor(resolved.sensor);
523
398
  if (resolved.collisionGroups !== void 0) {
524
- colliderDesc.setCollisionGroups(resolved.collisionGroups);
399
+ definition.collisionGroups = resolved.collisionGroups;
525
400
  }
526
- colliderDesc.activeCollisionTypes = resolved.activeCollisionTypes;
527
- return colliderDesc;
401
+ return definition;
528
402
  }
529
403
  function snapshotBody(entity) {
530
- if (!entity.body) {
404
+ const body = getBodyLike(entity);
405
+ if (!body) {
531
406
  return null;
532
407
  }
533
- const translation = entity.body.translation();
534
- const rotation = entity.body.rotation();
535
- const linearVelocity = entity.body.linvel();
536
- const angularVelocity = entity.body.angvel();
408
+ const translation = body.translation();
409
+ const rotation = body.rotation();
410
+ const linearVelocity = body.linvel();
411
+ const angularVelocity = body.angvel();
537
412
  return {
538
413
  translation: { ...translation },
539
414
  rotation: { ...rotation },
@@ -542,13 +417,14 @@ function snapshotBody(entity) {
542
417
  };
543
418
  }
544
419
  function restoreBodySnapshot(entity, snapshot) {
545
- if (!snapshot || !entity.body) {
420
+ const body = getBodyLike(entity);
421
+ if (!snapshot || !body) {
546
422
  return;
547
423
  }
548
- entity.body.setTranslation(snapshot.translation, true);
549
- entity.body.setRotation(snapshot.rotation, true);
550
- entity.body.setLinvel(snapshot.linearVelocity, true);
551
- entity.body.setAngvel(snapshot.angularVelocity, true);
424
+ body.setTranslation(snapshot.translation, true);
425
+ body.setRotation(snapshot.rotation, true);
426
+ body.setLinvel(snapshot.linearVelocity, true);
427
+ body.setAngvel(snapshot.angularVelocity, true);
552
428
  }
553
429
  function attachEntityPhysics(ref, entity, snapshot) {
554
430
  const world = getBehaviorWorld(ref);
@@ -574,7 +450,7 @@ function disposeFragments(fragments) {
574
450
  fragment.geometry.dispose();
575
451
  }
576
452
  }
577
- function syncRuntimeFragmentEntityTransform(entity, interpolationAlpha) {
453
+ function syncRuntimeFragmentEntityTransform(entity, _interpolationAlpha) {
578
454
  const target = entity.group ?? entity.mesh;
579
455
  if (!target) {
580
456
  return;
@@ -583,14 +459,7 @@ function syncRuntimeFragmentEntityTransform(entity, interpolationAlpha) {
583
459
  if (wasmPose && entity.runtimeHandle >= 0) {
584
460
  target.position.set(wasmPose.position.x, wasmPose.position.y, wasmPose.position.z);
585
461
  target.quaternion.set(wasmPose.rotation.x, wasmPose.rotation.y, wasmPose.rotation.z, wasmPose.rotation.w);
586
- return;
587
- }
588
- if (!entity.body) {
589
- return;
590
462
  }
591
- const pose = getBodyRenderPose(entity.body, interpolationAlpha);
592
- target.position.set(pose.position.x, pose.position.y, pose.position.z);
593
- target.quaternion.set(pose.rotation.x, pose.rotation.y, pose.rotation.z, pose.rotation.w);
594
463
  }
595
464
  function bakeScaleIntoFragmentGeometry(fragment, scale) {
596
465
  if (Math.abs(scale.x - 1) < 1e-6 && Math.abs(scale.y - 1) < 1e-6 && Math.abs(scale.z - 1) < 1e-6) {
@@ -619,7 +488,7 @@ function computeFragmentWorldPose(root, fragment) {
619
488
  fragment.updateMatrix();
620
489
  const worldMatrix = new Matrix4().copy(root.matrixWorld).multiply(fragment.matrix);
621
490
  const position = new Vector3();
622
- const rotation = new Quaternion2();
491
+ const rotation = new Quaternion();
623
492
  const scale = new Vector3();
624
493
  worldMatrix.decompose(position, rotation, scale);
625
494
  return {
@@ -699,18 +568,19 @@ function createRuntimeFragmentEntity(createEntity, parentEntity, fragment, index
699
568
  } else if (fragment.material) {
700
569
  entity.materials = [fragment.material];
701
570
  }
702
- entity.colliderDesc = createFragmentColliderDesc(fragment, colliderOptions);
571
+ entity.colliderDesc = createFragmentColliderDefinition(fragment, colliderOptions);
703
572
  entity.colliderDescs = [entity.colliderDesc];
704
- entity.bodyDesc = RigidBodyDesc.dynamic().setTranslation(position.x, position.y, position.z).setCanSleep(false).setCcdEnabled(true);
573
+ const bodyDefinition = {
574
+ kind: "dynamic",
575
+ position: [position.x, position.y, position.z],
576
+ rotation: [rotation.x, rotation.y, rotation.z, rotation.w],
577
+ canSleep: false,
578
+ ccdEnabled: true
579
+ };
580
+ entity.bodyDesc = bodyDefinition;
705
581
  fragment.position.set(0, 0, 0);
706
582
  fragment.quaternion.identity();
707
583
  fragment.scale.set(1, 1, 1);
708
- entity.bodyDesc.setRotation({
709
- x: rotation.x,
710
- y: rotation.y,
711
- z: rotation.z,
712
- w: rotation.w
713
- });
714
584
  return entity;
715
585
  }
716
586
  function unlockIndependentFragmentPhysicsBody(entity) {
@@ -834,7 +704,7 @@ function fractureCompoundEntity(ref, entity, root, fragments, state) {
834
704
  root.add(fragmentContainer);
835
705
  state.fragmentContainer = fragmentContainer;
836
706
  state.fractureMode = "compound";
837
- const colliderDescs = fragments.map((fragment) => createFragmentColliderDesc(
707
+ const colliderDescs = fragments.map((fragment) => createFragmentColliderDefinition(
838
708
  fragment,
839
709
  ref.options.collider,
840
710
  fragment.position
@@ -893,8 +763,9 @@ function fractureIndependentEntity(ref, entity, root, fractureOptions, fragments
893
763
  physicsOptions,
894
764
  sourceVelocity
895
765
  );
896
- fragmentEntity.body?.setLinvel(linearVelocity, true);
897
- fragmentEntity.body?.setAngvel(
766
+ const fragmentBody = getBodyLike(fragmentEntity);
767
+ fragmentBody?.setLinvel(linearVelocity, true);
768
+ fragmentBody?.setAngvel(
898
769
  computeFragmentAngularVelocity(
899
770
  index,
900
771
  physicsOptions.angularVelocity
@@ -1202,4 +1073,4 @@ export {
1202
1073
  DestructibleMesh2 as DestructibleMesh,
1203
1074
  FractureOptions
1204
1075
  };
1205
- //# sourceMappingURL=chunk-BXP4K7RF.js.map
1076
+ //# sourceMappingURL=chunk-JVADRLWX.js.map