incanto 0.4.2 → 0.5.0
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.
- package/dist/2d.d.ts +74 -6
- package/dist/2d.js +4 -4
- package/dist/3d.d.ts +174 -16
- package/dist/3d.js +4 -4
- package/dist/{audio-player-DqUR3XFs.d.ts → audio-player-DkBqRTs4.d.ts} +1 -1
- package/dist/{behavior-BAQq7HGM.d.ts → behavior-CWhW3oa6.d.ts} +54 -0
- package/dist/{create-game-CZHROKcT.js → create-game-BFESHv1X.js} +37 -25
- package/dist/{create-game-CMS7DiPi.js → create-game-D8UvwXme.js} +231 -8
- package/dist/debug.d.ts +1 -1
- package/dist/{duplicate-DP2WPYom.js → duplicate-BEvGBtb_.js} +1 -1
- package/dist/{gameplay-Ccruc3Wd.js → gameplay-CDFgSG6z.js} +293 -24
- package/dist/gameplay.d.ts +113 -2
- package/dist/gameplay.js +2 -2
- package/dist/index.d.ts +139 -5
- package/dist/index.js +59 -6
- package/dist/{loader-CGs_G-r0.js → loader-B4OEXDZ8.js} +60 -0
- package/dist/{loader-Mo0KghCv.d.ts → loader-D2u0fVW2.d.ts} +1 -1
- package/dist/net.d.ts +1 -1
- package/dist/net.js +1 -1
- package/dist/{particle-sim-DYuSUxvK.js → particle-sim-CFkILGwh.js} +84 -3
- package/dist/{particle-sim-CbN4YUuH.d.ts → particle-sim-CwJ5rI_P.d.ts} +3 -0
- package/dist/{physics-2d-KuMWPTf6.js → physics-2d-KXn1N1jF.js} +95 -10
- package/dist/{physics-3d-CXOBOUKG.js → physics-3d-C58oQzTX.js} +121 -43
- package/dist/react.d.ts +1 -1
- package/dist/react.js +1 -1
- package/dist/{register-B0gq63VW.js → register-C35HDZpm.js} +2 -2
- package/dist/{register-DPEV9_9t.js → register-D71C4rDC.js} +76 -5
- package/dist/{register-BuUV1_KB.js → register-Dl_ixIJe.js} +275 -2
- package/dist/{register-02aSywx2.js → register-DvPHJdVj.js} +390 -59
- package/dist/test.d.ts +2 -2
- package/dist/test.js +10 -10
- package/editor/assets/{agent8-DUVZGcuO.js → agent8-DruKhR22.js} +1 -1
- package/editor/assets/index-D2qufqUo.js +7417 -0
- package/editor/index.html +1 -1
- package/package.json +1 -1
- package/schemas/scene.schema.json +847 -133
- package/skills/incanto-3d-models.md +24 -1
- package/skills/incanto-building-3d-games.md +35 -3
- package/skills/incanto-gameplay-behaviors.md +60 -0
- package/skills/incanto-hud.md +58 -0
- package/skills/incanto-node-reference.md +113 -0
- package/skills/incanto-physics-and-input.md +47 -0
- package/editor/assets/index-DsM2Yp9F.js +0 -7365
|
@@ -49,6 +49,9 @@ declare class ParticleSim {
|
|
|
49
49
|
private spawnAccumulator;
|
|
50
50
|
private everSpawned;
|
|
51
51
|
constructor(config: ParticleSimConfig, rng: Rng);
|
|
52
|
+
/** Change the emission rate LIVE (particles/sec; 0 pauses emission) — lets an
|
|
53
|
+
* emitter toggle on/off at runtime (drift smoke, throttle flames). */
|
|
54
|
+
setRate(rate: number): void;
|
|
52
55
|
get count(): number;
|
|
53
56
|
/** True when nothing is alive and at least one particle has ever spawned. */
|
|
54
57
|
get done(): boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
2
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
3
|
-
import { d as
|
|
3
|
+
import { _ as validateCollider2D, d as Area2D, f as CharacterBody2D, g as Node2D, m as RigidBody2D, p as PhysicsBody2D, u as Joint2D } from "./register-D71C4rDC.js";
|
|
4
4
|
import { n as registerDebugSource } from "./debug-draw-CZmOYjL2.js";
|
|
5
5
|
//#region src/2d/physics/physics-2d.ts
|
|
6
6
|
var physics_2d_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -131,16 +131,94 @@ var Physics2D = class {
|
|
|
131
131
|
for (let i = 0; i < raw.length; i++) px[i] = raw[i] * SCALE;
|
|
132
132
|
return px;
|
|
133
133
|
}
|
|
134
|
+
/** Create newly-arrived joints; tear down departed ones. */
|
|
135
|
+
syncJoints(structureChanged) {
|
|
136
|
+
const R = this.R;
|
|
137
|
+
if (structureChanged) {
|
|
138
|
+
for (const [joint, impulse] of this.joints) if (!this.jointSet.has(joint)) {
|
|
139
|
+
this.world.removeImpulseJoint(impulse, true);
|
|
140
|
+
this.joints.delete(joint);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
for (const joint of this.jointSet) {
|
|
144
|
+
if (this.joints.has(joint)) continue;
|
|
145
|
+
const { a, b } = joint._resolveBodies();
|
|
146
|
+
const ea = this.entries.get(a);
|
|
147
|
+
const eb = this.entries.get(b);
|
|
148
|
+
if (!ea || !eb) continue;
|
|
149
|
+
const a1 = {
|
|
150
|
+
x: (joint.anchor[0] ?? 0) / SCALE,
|
|
151
|
+
y: (joint.anchor[1] ?? 0) / SCALE
|
|
152
|
+
};
|
|
153
|
+
const a2 = {
|
|
154
|
+
x: (joint.targetAnchor[0] ?? 0) / SCALE,
|
|
155
|
+
y: (joint.targetAnchor[1] ?? 0) / SCALE
|
|
156
|
+
};
|
|
157
|
+
let length = joint.length / SCALE;
|
|
158
|
+
if (joint.length === 0 && (joint.type === "rope" || joint.type === "spring")) {
|
|
159
|
+
const ta = ea.body.translation();
|
|
160
|
+
const tb = eb.body.translation();
|
|
161
|
+
length = Math.hypot(tb.x - ta.x, tb.y - ta.y);
|
|
162
|
+
}
|
|
163
|
+
let data;
|
|
164
|
+
if (joint.type === "fixed") data = R.JointData.fixed(a1, 0, a2, 0);
|
|
165
|
+
else if (joint.type === "rope") data = R.JointData.rope(length, a1, a2);
|
|
166
|
+
else if (joint.type === "spring") data = R.JointData.spring(length, joint.stiffness, joint.damping, a1, a2);
|
|
167
|
+
else data = R.JointData.revolute(a1, a2);
|
|
168
|
+
this.joints.set(joint, this.world.createImpulseJoint(data, ea.body, eb.body, true));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* World-space raycast in PIXELS (y-down). `exclude` skips that body — a
|
|
173
|
+
* shooter probing from inside its own collider needs it. Sensors (Area2D)
|
|
174
|
+
* never block rays. Returns distance (px), the surface normal, and the hit
|
|
175
|
+
* body — or null.
|
|
176
|
+
*/
|
|
177
|
+
castRay(origin, dir, maxLen, exclude, opts) {
|
|
178
|
+
const len = Math.hypot(dir[0], dir[1]) || 1;
|
|
179
|
+
const ray = new this.R.Ray({
|
|
180
|
+
x: origin[0] / SCALE,
|
|
181
|
+
y: origin[1] / SCALE
|
|
182
|
+
}, {
|
|
183
|
+
x: dir[0] / len,
|
|
184
|
+
y: dir[1] / len
|
|
185
|
+
});
|
|
186
|
+
const excludeCollider = exclude ? this.entries.get(exclude)?.collider : void 0;
|
|
187
|
+
const flags = opts?.staticOnly ? this.R.QueryFilterFlags.EXCLUDE_DYNAMIC | this.R.QueryFilterFlags.EXCLUDE_KINEMATIC : void 0;
|
|
188
|
+
const hit = this.world.castRayAndGetNormal(ray, maxLen / SCALE, true, flags, void 0, excludeCollider, void 0, (collider) => !collider.isSensor());
|
|
189
|
+
if (!hit) return null;
|
|
190
|
+
return {
|
|
191
|
+
distance: hit.timeOfImpact * SCALE,
|
|
192
|
+
normal: [hit.normal.x, hit.normal.y],
|
|
193
|
+
node: this.byColliderHandle.get(hit.collider.handle) ?? null
|
|
194
|
+
};
|
|
195
|
+
}
|
|
134
196
|
dispose() {
|
|
135
197
|
this.disconnect();
|
|
136
198
|
this.unregisterDebug();
|
|
137
199
|
this.world.free();
|
|
138
200
|
}
|
|
201
|
+
lastStructure = -1;
|
|
202
|
+
lastRoot = null;
|
|
203
|
+
jointSet = /* @__PURE__ */ new Set();
|
|
204
|
+
joints = /* @__PURE__ */ new Map();
|
|
205
|
+
bodySet = /* @__PURE__ */ new Set();
|
|
139
206
|
syncBodies() {
|
|
140
207
|
const scene = this.engine.scene;
|
|
141
208
|
if (!scene) return;
|
|
142
|
-
const
|
|
143
|
-
|
|
209
|
+
const version = scene.tree._structureVersion;
|
|
210
|
+
const structureChanged = version !== this.lastStructure || scene.root !== this.lastRoot;
|
|
211
|
+
if (structureChanged) {
|
|
212
|
+
this.lastStructure = version;
|
|
213
|
+
this.lastRoot = scene.root;
|
|
214
|
+
this.bodySet.clear();
|
|
215
|
+
collectBodies(scene.root, this.bodySet);
|
|
216
|
+
}
|
|
217
|
+
if (structureChanged) {
|
|
218
|
+
this.jointSet.clear();
|
|
219
|
+
collectJoints(scene.root, this.jointSet);
|
|
220
|
+
}
|
|
221
|
+
const seen = this.bodySet;
|
|
144
222
|
for (const node of seen) {
|
|
145
223
|
if (node.collider.shape === void 0) {
|
|
146
224
|
const stale = this.entries.get(node);
|
|
@@ -157,7 +235,7 @@ var Physics2D = class {
|
|
|
157
235
|
continue;
|
|
158
236
|
}
|
|
159
237
|
const existing = this.entries.get(node);
|
|
160
|
-
if (existing &&
|
|
238
|
+
if (existing && node._colliderChanged) {
|
|
161
239
|
this.byColliderHandle.delete(existing.collider.handle);
|
|
162
240
|
this.world.removeRigidBody(existing.body);
|
|
163
241
|
this.entries.delete(node);
|
|
@@ -165,11 +243,14 @@ var Physics2D = class {
|
|
|
165
243
|
}
|
|
166
244
|
this.ensureEntry(node);
|
|
167
245
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
this.
|
|
171
|
-
|
|
172
|
-
|
|
246
|
+
this.syncJoints(structureChanged);
|
|
247
|
+
if (structureChanged) {
|
|
248
|
+
for (const [node, e] of this.entries) if (!seen.has(node)) {
|
|
249
|
+
this.byColliderHandle.delete(e.collider.handle);
|
|
250
|
+
this.world.removeRigidBody(e.body);
|
|
251
|
+
this.entries.delete(node);
|
|
252
|
+
node._physics = null;
|
|
253
|
+
}
|
|
173
254
|
}
|
|
174
255
|
}
|
|
175
256
|
ensureEntry(node) {
|
|
@@ -199,7 +280,6 @@ var Physics2D = class {
|
|
|
199
280
|
e = {
|
|
200
281
|
body,
|
|
201
282
|
collider,
|
|
202
|
-
colliderKey: JSON.stringify(node.collider),
|
|
203
283
|
lastX: wx,
|
|
204
284
|
lastY: wy,
|
|
205
285
|
lastVX: 0,
|
|
@@ -207,6 +287,7 @@ var Physics2D = class {
|
|
|
207
287
|
};
|
|
208
288
|
this.entries.set(node, e);
|
|
209
289
|
this.byColliderHandle.set(collider.handle, node);
|
|
290
|
+
node._colliderChanged = false;
|
|
210
291
|
node._physics = this;
|
|
211
292
|
return e;
|
|
212
293
|
}
|
|
@@ -234,6 +315,10 @@ var Physics2D = class {
|
|
|
234
315
|
return e;
|
|
235
316
|
}
|
|
236
317
|
};
|
|
318
|
+
function collectJoints(node, out) {
|
|
319
|
+
if (node instanceof Joint2D) out.add(node);
|
|
320
|
+
for (const c of node.children) collectJoints(c, out);
|
|
321
|
+
}
|
|
237
322
|
function collectBodies(node, out) {
|
|
238
323
|
if (node instanceof PhysicsBody2D) out.add(node);
|
|
239
324
|
for (const c of node.children) collectBodies(c, out);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
2
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
3
3
|
import { n as registerDebugSource } from "./debug-draw-CZmOYjL2.js";
|
|
4
|
-
import {
|
|
4
|
+
import { D as CharacterBody3D, E as Area3D, M as validateCollider3D, O as PhysicsBody3D, T as Joint3D, j as Node3D, k as RigidBody3D, x as Terrain3D } from "./register-DvPHJdVj.js";
|
|
5
5
|
import { Euler, Quaternion } from "three";
|
|
6
6
|
//#region src/3d/physics/physics-3d.ts
|
|
7
7
|
var physics_3d_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -91,35 +91,33 @@ var Physics3D = class {
|
|
|
91
91
|
];
|
|
92
92
|
node._interpPrev = node._interpCurr ?? next;
|
|
93
93
|
node._interpCurr = next;
|
|
94
|
-
node.position
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
];
|
|
94
|
+
const pos = node.position;
|
|
95
|
+
pos[0] = next[0];
|
|
96
|
+
pos[1] = next[1];
|
|
97
|
+
pos[2] = next[2];
|
|
99
98
|
}
|
|
100
99
|
if (node instanceof RigidBody3D) {
|
|
101
100
|
if (!node.fixedRotation) {
|
|
102
101
|
const q = e.body.rotation();
|
|
103
102
|
eulerScratch.setFromQuaternion(quatScratch.set(q.x, q.y, q.z, q.w), "XYZ");
|
|
104
|
-
node.rotation
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
];
|
|
103
|
+
const rot = node.rotation;
|
|
104
|
+
rot[0] = eulerScratch.x / DEG;
|
|
105
|
+
rot[1] = eulerScratch.y / DEG;
|
|
106
|
+
rot[2] = eulerScratch.z / DEG;
|
|
109
107
|
}
|
|
110
108
|
const lv = e.body.linvel();
|
|
111
|
-
node.linearVelocity
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
];
|
|
116
|
-
e.lastV =
|
|
117
|
-
|
|
118
|
-
lv.y,
|
|
119
|
-
lv.z
|
|
120
|
-
];
|
|
109
|
+
const nv = node.linearVelocity;
|
|
110
|
+
nv[0] = lv.x;
|
|
111
|
+
nv[1] = lv.y;
|
|
112
|
+
nv[2] = lv.z;
|
|
113
|
+
e.lastV[0] = lv.x;
|
|
114
|
+
e.lastV[1] = lv.y;
|
|
115
|
+
e.lastV[2] = lv.z;
|
|
121
116
|
}
|
|
122
|
-
|
|
117
|
+
const wp = worldPosition3D(node);
|
|
118
|
+
e.last[0] = wp[0];
|
|
119
|
+
e.last[1] = wp[1];
|
|
120
|
+
e.last[2] = wp[2];
|
|
123
121
|
}
|
|
124
122
|
this.events.drainCollisionEvents((h1, h2, started) => {
|
|
125
123
|
const a = this.byColliderHandle.get(h1);
|
|
@@ -162,11 +160,27 @@ var Physics3D = class {
|
|
|
162
160
|
this.unregisterDebug();
|
|
163
161
|
this.world.free();
|
|
164
162
|
}
|
|
163
|
+
lastStructure = -1;
|
|
164
|
+
lastRoot = null;
|
|
165
|
+
jointSet = /* @__PURE__ */ new Set();
|
|
166
|
+
joints = /* @__PURE__ */ new Map();
|
|
167
|
+
bodySet = /* @__PURE__ */ new Set();
|
|
165
168
|
syncBodies() {
|
|
166
169
|
const scene = this.engine.scene;
|
|
167
170
|
if (!scene) return;
|
|
168
|
-
const
|
|
169
|
-
|
|
171
|
+
const version = scene.tree._structureVersion;
|
|
172
|
+
const structureChanged = version !== this.lastStructure || scene.root !== this.lastRoot;
|
|
173
|
+
if (structureChanged) {
|
|
174
|
+
this.lastStructure = version;
|
|
175
|
+
this.lastRoot = scene.root;
|
|
176
|
+
this.bodySet.clear();
|
|
177
|
+
collectBodies(scene.root, this.bodySet);
|
|
178
|
+
}
|
|
179
|
+
if (structureChanged) {
|
|
180
|
+
this.jointSet.clear();
|
|
181
|
+
collectJoints(scene.root, this.jointSet);
|
|
182
|
+
}
|
|
183
|
+
const seen = this.bodySet;
|
|
170
184
|
for (const node of seen) {
|
|
171
185
|
if (node.collider.shape === void 0) {
|
|
172
186
|
const stale = this.entries.get(node);
|
|
@@ -184,7 +198,7 @@ var Physics3D = class {
|
|
|
184
198
|
continue;
|
|
185
199
|
}
|
|
186
200
|
const existing = this.entries.get(node);
|
|
187
|
-
if (existing &&
|
|
201
|
+
if (existing && node._colliderChanged) {
|
|
188
202
|
this.byColliderHandle.delete(existing.collider.handle);
|
|
189
203
|
this.world.removeRigidBody(existing.body);
|
|
190
204
|
this.entries.delete(node);
|
|
@@ -193,12 +207,15 @@ var Physics3D = class {
|
|
|
193
207
|
}
|
|
194
208
|
this.ensureEntry(node);
|
|
195
209
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
this.
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
210
|
+
this.syncJoints(structureChanged);
|
|
211
|
+
if (structureChanged) {
|
|
212
|
+
for (const [node, e] of this.entries) if (!seen.has(node)) {
|
|
213
|
+
this.byColliderHandle.delete(e.collider.handle);
|
|
214
|
+
this.world.removeRigidBody(e.body);
|
|
215
|
+
this.entries.delete(node);
|
|
216
|
+
node._physics = null;
|
|
217
|
+
node._interpPrev = node._interpCurr = null;
|
|
218
|
+
}
|
|
202
219
|
}
|
|
203
220
|
}
|
|
204
221
|
ensureEntry(node) {
|
|
@@ -231,7 +248,6 @@ var Physics3D = class {
|
|
|
231
248
|
if (node instanceof RigidBody3D) colDesc.setMass(node.mass).setFriction(node.friction).setRestitution(node.restitution);
|
|
232
249
|
const collider = this.world.createCollider(colDesc, body);
|
|
233
250
|
e = {
|
|
234
|
-
colliderKey: JSON.stringify(node.collider),
|
|
235
251
|
body,
|
|
236
252
|
collider,
|
|
237
253
|
last: [
|
|
@@ -247,6 +263,7 @@ var Physics3D = class {
|
|
|
247
263
|
};
|
|
248
264
|
this.entries.set(node, e);
|
|
249
265
|
this.byColliderHandle.set(collider.handle, node);
|
|
266
|
+
node._colliderChanged = false;
|
|
250
267
|
node._physics = this;
|
|
251
268
|
if (node instanceof RigidBody3D) node._physics3d = this;
|
|
252
269
|
return e;
|
|
@@ -258,7 +275,9 @@ var Physics3D = class {
|
|
|
258
275
|
y: p[1],
|
|
259
276
|
z: p[2]
|
|
260
277
|
}, true);
|
|
261
|
-
e.last = p;
|
|
278
|
+
e.last[0] = p[0];
|
|
279
|
+
e.last[1] = p[1];
|
|
280
|
+
e.last[2] = p[2];
|
|
262
281
|
node._interpPrev = node._interpCurr = null;
|
|
263
282
|
}
|
|
264
283
|
if (node instanceof RigidBody3D) {
|
|
@@ -304,6 +323,51 @@ var Physics3D = class {
|
|
|
304
323
|
0
|
|
305
324
|
];
|
|
306
325
|
}
|
|
326
|
+
/** Create newly-arrived joints; tear down departed ones. */
|
|
327
|
+
syncJoints(structureChanged) {
|
|
328
|
+
const R = this.R;
|
|
329
|
+
if (structureChanged) {
|
|
330
|
+
for (const [joint, impulse] of this.joints) if (!this.jointSet.has(joint)) {
|
|
331
|
+
this.world.removeImpulseJoint(impulse, true);
|
|
332
|
+
this.joints.delete(joint);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
for (const joint of this.jointSet) {
|
|
336
|
+
if (this.joints.has(joint)) continue;
|
|
337
|
+
const { a, b } = joint._resolveBodies();
|
|
338
|
+
const ea = this.entries.get(a);
|
|
339
|
+
const eb = this.entries.get(b);
|
|
340
|
+
if (!ea || !eb) continue;
|
|
341
|
+
const a1 = {
|
|
342
|
+
x: joint.anchor[0] ?? 0,
|
|
343
|
+
y: joint.anchor[1] ?? 0,
|
|
344
|
+
z: joint.anchor[2] ?? 0
|
|
345
|
+
};
|
|
346
|
+
const a2 = {
|
|
347
|
+
x: joint.targetAnchor[0] ?? 0,
|
|
348
|
+
y: joint.targetAnchor[1] ?? 0,
|
|
349
|
+
z: joint.targetAnchor[2] ?? 0
|
|
350
|
+
};
|
|
351
|
+
let length = joint.length;
|
|
352
|
+
if (joint.length === 0 && (joint.type === "rope" || joint.type === "spring")) {
|
|
353
|
+
const ta = ea.body.translation();
|
|
354
|
+
const tb = eb.body.translation();
|
|
355
|
+
length = Math.hypot(tb.x - ta.x, tb.y - ta.y, tb.z - ta.z);
|
|
356
|
+
}
|
|
357
|
+
const identity = {
|
|
358
|
+
x: 0,
|
|
359
|
+
y: 0,
|
|
360
|
+
z: 0,
|
|
361
|
+
w: 1
|
|
362
|
+
};
|
|
363
|
+
let data;
|
|
364
|
+
if (joint.type === "fixed") data = R.JointData.fixed(a1, identity, a2, identity);
|
|
365
|
+
else if (joint.type === "rope") data = R.JointData.rope(length, a1, a2);
|
|
366
|
+
else if (joint.type === "spring") data = R.JointData.spring(length, joint.stiffness, joint.damping, a1, a2);
|
|
367
|
+
else data = R.JointData.spherical(a1, a2);
|
|
368
|
+
this.joints.set(joint, this.world.createImpulseJoint(data, ea.body, eb.body, true));
|
|
369
|
+
}
|
|
370
|
+
}
|
|
307
371
|
/**
|
|
308
372
|
* World-space raycast (meters). `exclude` skips that body's collider —
|
|
309
373
|
* ground probes from inside a capsule need it. `opts.staticOnly` hits ONLY the
|
|
@@ -338,6 +402,10 @@ var Physics3D = class {
|
|
|
338
402
|
};
|
|
339
403
|
const quatScratch = new Quaternion();
|
|
340
404
|
const eulerScratch = new Euler();
|
|
405
|
+
function collectJoints(node, out) {
|
|
406
|
+
if (node instanceof Joint3D) out.add(node);
|
|
407
|
+
for (const c of node.children) collectJoints(c, out);
|
|
408
|
+
}
|
|
341
409
|
function collectBodies(node, out) {
|
|
342
410
|
if (node instanceof PhysicsBody3D) out.add(node);
|
|
343
411
|
for (const c of node.children) collectBodies(c, out);
|
|
@@ -346,6 +414,12 @@ function collectBodies(node, out) {
|
|
|
346
414
|
* Composed world position (translation only — ancestor rotation/scale are NOT
|
|
347
415
|
* supported for physics bodies; keep body ancestors untransformed or offset-only).
|
|
348
416
|
*/
|
|
417
|
+
const posScratch = [
|
|
418
|
+
0,
|
|
419
|
+
0,
|
|
420
|
+
0
|
|
421
|
+
];
|
|
422
|
+
/** Writes into the shared scratch — consume before the next call. */
|
|
349
423
|
function worldPosition3D(node) {
|
|
350
424
|
let x = 0;
|
|
351
425
|
let y = 0;
|
|
@@ -355,12 +429,17 @@ function worldPosition3D(node) {
|
|
|
355
429
|
y += n.position[1] ?? 0;
|
|
356
430
|
z += n.position[2] ?? 0;
|
|
357
431
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
];
|
|
432
|
+
posScratch[0] = x;
|
|
433
|
+
posScratch[1] = y;
|
|
434
|
+
posScratch[2] = z;
|
|
435
|
+
return posScratch;
|
|
363
436
|
}
|
|
437
|
+
const offsetScratch = [
|
|
438
|
+
0,
|
|
439
|
+
0,
|
|
440
|
+
0
|
|
441
|
+
];
|
|
442
|
+
/** Writes into the shared scratch — consume before the next call. */
|
|
364
443
|
function parentWorldOffset3D(node) {
|
|
365
444
|
let x = 0;
|
|
366
445
|
let y = 0;
|
|
@@ -370,11 +449,10 @@ function parentWorldOffset3D(node) {
|
|
|
370
449
|
y += n.position[1] ?? 0;
|
|
371
450
|
z += n.position[2] ?? 0;
|
|
372
451
|
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
];
|
|
452
|
+
offsetScratch[0] = x;
|
|
453
|
+
offsetScratch[1] = y;
|
|
454
|
+
offsetScratch[2] = z;
|
|
455
|
+
return offsetScratch;
|
|
378
456
|
}
|
|
379
457
|
function parseCollider3D(R, node) {
|
|
380
458
|
const collider = node.collider;
|
package/dist/react.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { c as JsonValue } from "./schema-CcoWb32N.js";
|
|
2
|
-
import { n as BehaviorCtor, v as Engine, w as Scene } from "./behavior-
|
|
2
|
+
import { n as BehaviorCtor, v as Engine, w as Scene } from "./behavior-CWhW3oa6.js";
|
|
3
3
|
import { CSSProperties, ReactNode } from "react";
|
|
4
4
|
|
|
5
5
|
//#region src/react/index.d.ts
|
package/dist/react.js
CHANGED
|
@@ -156,7 +156,7 @@ function IncantoCanvas(props) {
|
|
|
156
156
|
pointer: latest.pointer,
|
|
157
157
|
...keyboard !== void 0 ? { keyboard } : {}
|
|
158
158
|
};
|
|
159
|
-
const next = await (_gameFactory ?? (mode === "3d" ? async (o) => (await import("./create-game-
|
|
159
|
+
const next = await (_gameFactory ?? (mode === "3d" ? async (o) => (await import("./create-game-D8UvwXme.js").then((n) => n.n)).createGame3D(o) : async (o) => (await import("./create-game-BFESHv1X.js").then((n) => n.n)).createGame2D(o)))(opts);
|
|
160
160
|
if (disposed) {
|
|
161
161
|
next.dispose();
|
|
162
162
|
return;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { f as Node, t as buildNodeJson, y as Signal } from "./loader-
|
|
1
|
+
import { f as Node, t as buildNodeJson, y as Signal } from "./loader-B4OEXDZ8.js";
|
|
2
2
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
3
|
-
import { t as registerCoreNodes } from "./register-
|
|
3
|
+
import { t as registerCoreNodes } from "./register-Dl_ixIJe.js";
|
|
4
4
|
import { n as jsonEquals, t as jsonClone } from "./json-BLk7H2Qa.js";
|
|
5
5
|
import { l as registerNode } from "./registry-BVJ2HbCn.js";
|
|
6
6
|
//#region src/net/network-manager.ts
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { f as Node } from "./loader-
|
|
2
|
-
import { i as applyParticlePreset, r as PARTICLE_PRESET_NAMES, t as ParticleSim } from "./particle-sim-
|
|
1
|
+
import { f as Node } from "./loader-B4OEXDZ8.js";
|
|
2
|
+
import { i as applyParticlePreset, r as PARTICLE_PRESET_NAMES, t as ParticleSim } from "./particle-sim-CFkILGwh.js";
|
|
3
3
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
4
4
|
import { t as Rng } from "./rng-DP-SR7eg.js";
|
|
5
|
-
import { t as registerCoreNodes } from "./register-
|
|
5
|
+
import { t as registerCoreNodes } from "./register-Dl_ixIJe.js";
|
|
6
6
|
import { i as getNodeSchema, l as registerNode } from "./registry-BVJ2HbCn.js";
|
|
7
7
|
import { AdditiveBlending, CanvasTexture, Color, DynamicDrawUsage, Group, InstancedMesh, MathUtils, Matrix4, Mesh, MeshBasicMaterial, NormalBlending, Object3D, PlaneGeometry } from "three";
|
|
8
8
|
//#region src/2d/physics/collider-validate.ts
|
|
@@ -96,7 +96,21 @@ var PhysicsBody2D = class extends Node2D {
|
|
|
96
96
|
static props = { collider: { default: {} } };
|
|
97
97
|
/** The unified collision model: every collider participant can emit these. */
|
|
98
98
|
static signals = ["triggerEnter", "triggerExit"];
|
|
99
|
-
|
|
99
|
+
_collider = {};
|
|
100
|
+
/** @internal Physics resync flag — raised when `collider` is REPLACED. */
|
|
101
|
+
_colliderChanged = false;
|
|
102
|
+
/**
|
|
103
|
+
* Collider shape prop. Change it by REPLACING the object
|
|
104
|
+
* (`body.collider = { shape: 'box', size: [...] }`) — physics rebuilds the
|
|
105
|
+
* body on replacement; in-place mutation of the old object is not watched.
|
|
106
|
+
*/
|
|
107
|
+
get collider() {
|
|
108
|
+
return this._collider;
|
|
109
|
+
}
|
|
110
|
+
set collider(value) {
|
|
111
|
+
this._collider = value;
|
|
112
|
+
this._colliderChanged = true;
|
|
113
|
+
}
|
|
100
114
|
/** Loader hook: bad collider shapes fail at LOAD, not at physics start. */
|
|
101
115
|
static validateJson(node) {
|
|
102
116
|
validateCollider2D(node.collider, node.name);
|
|
@@ -163,6 +177,62 @@ var CharacterBody2D = class extends PhysicsBody2D {
|
|
|
163
177
|
}
|
|
164
178
|
};
|
|
165
179
|
//#endregion
|
|
180
|
+
//#region src/2d/nodes/joint-2d.ts
|
|
181
|
+
/**
|
|
182
|
+
* A physics joint linking its PARENT body to `target` (a node path to the
|
|
183
|
+
* other body). Godot-style placement: the joint lives as a child of body A.
|
|
184
|
+
*
|
|
185
|
+
* { "name": "Hinge", "type": "Joint2D",
|
|
186
|
+
* "props": { "type": "revolute", "target": "%Anchor", "anchor": [0, -20] } }
|
|
187
|
+
*
|
|
188
|
+
* Types: `fixed` welds the bodies rigidly · `revolute` is a pin/hinge at the
|
|
189
|
+
* anchors · `rope` caps the anchor distance at `length` (px; 0 = measured at
|
|
190
|
+
* creation) · `spring` pulls toward `length` with `stiffness`/`damping`.
|
|
191
|
+
* Anchors are LOCAL pixel offsets on each body.
|
|
192
|
+
*/
|
|
193
|
+
var Joint2D = class extends Node2D {
|
|
194
|
+
static typeName = "Joint2D";
|
|
195
|
+
static props = {
|
|
196
|
+
type: {
|
|
197
|
+
default: "revolute",
|
|
198
|
+
options: [
|
|
199
|
+
"fixed",
|
|
200
|
+
"revolute",
|
|
201
|
+
"rope",
|
|
202
|
+
"spring"
|
|
203
|
+
]
|
|
204
|
+
},
|
|
205
|
+
target: { default: "" },
|
|
206
|
+
anchor: { default: [0, 0] },
|
|
207
|
+
targetAnchor: { default: [0, 0] },
|
|
208
|
+
length: { default: 0 },
|
|
209
|
+
stiffness: { default: 50 },
|
|
210
|
+
damping: { default: 5 }
|
|
211
|
+
};
|
|
212
|
+
type = "revolute";
|
|
213
|
+
target = "";
|
|
214
|
+
anchor = [0, 0];
|
|
215
|
+
targetAnchor = [0, 0];
|
|
216
|
+
/** rope/spring rest length in px; 0 = measure body distance at creation. */
|
|
217
|
+
length = 0;
|
|
218
|
+
stiffness = 50;
|
|
219
|
+
damping = 5;
|
|
220
|
+
onEnterTree() {
|
|
221
|
+
if (!(this.parent instanceof PhysicsBody2D)) throw new IncantoError("TREE_VIOLATION", `Joint2D '${this.name}' must be a child of a physics body (its body A); parent is '${this.parent?.name ?? "none"}'.`);
|
|
222
|
+
if (this.target === "") throw new IncantoError("BAD_FORMAT", `Joint2D '${this.name}' needs a "target" node path to the body it links to.`);
|
|
223
|
+
}
|
|
224
|
+
/** @internal The two bodies, resolved (throws on a bad target at step time). */
|
|
225
|
+
_resolveBodies() {
|
|
226
|
+
const a = this.parent;
|
|
227
|
+
const b = this.getNodeOrNull(this.target);
|
|
228
|
+
if (!(b instanceof PhysicsBody2D)) throw new IncantoError("NODE_NOT_FOUND", `Joint2D '${this.name}': target '${this.target}' is not a physics body.`);
|
|
229
|
+
return {
|
|
230
|
+
a,
|
|
231
|
+
b
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
//#endregion
|
|
166
236
|
//#region src/2d/nodes/sprite-2d.ts
|
|
167
237
|
/** Shared unit quad — sprites are sized via the quad's scale, never THREE.Sprite. */
|
|
168
238
|
const UNIT_PLANE$2 = new PlaneGeometry(1, 1);
|
|
@@ -846,6 +916,7 @@ function registerNodes2D() {
|
|
|
846
916
|
registerNode(Area2D);
|
|
847
917
|
registerNode(CharacterBody2D);
|
|
848
918
|
registerNode(CharacterController2D);
|
|
919
|
+
registerNode(Joint2D);
|
|
849
920
|
}
|
|
850
921
|
//#endregion
|
|
851
|
-
export { ColorRect2D as a, AnimatedSprite2D as c,
|
|
922
|
+
export { validateCollider2D as _, ColorRect2D as a, AnimatedSprite2D as c, Area2D as d, CharacterBody2D as f, Node2D as g, StaticBody2D as h, Label as i, Sprite2D as l, RigidBody2D as m, UILayer as n, CharacterController2D as o, PhysicsBody2D as p, Particles2D as r, Camera2D as s, registerNodes2D as t, Joint2D as u };
|