incanto 0.74.0 → 0.76.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/bin/incanto-multiplay.mjs +52 -4
- package/dist/2d.d.ts +83 -7
- package/dist/2d.js +4 -3
- package/dist/3d.d.ts +861 -167
- package/dist/3d.js +6 -6
- package/dist/{agent8-CHTT4unP.js → agent8-B-bh3n0X.js} +1 -1
- package/dist/{audio-player-BOrk4eQx.d.ts → audio-player-BRo2uvG6.d.ts} +23 -2
- package/dist/{behavior-J1cmVah0.d.ts → behavior-B_245qRy.d.ts} +15 -1
- package/dist/{create-game-ssvGvP7W.js → create-game-BMIPKrQW.js} +84 -8
- package/dist/{create-game-BAiA-FjP.js → create-game-Dai5vfVu.js} +80 -11
- package/dist/debug.d.ts +1 -1
- package/dist/{editor-switch-CFU9mCec.d.ts → editor-switch-Bzt0GzVp.d.ts} +13 -3
- package/dist/editor.js +1600 -1529
- package/dist/env.d.ts +1 -1
- package/dist/{environment-presets-BkqlWewf.js → environment-presets-e_9YCnGu.js} +2361 -104
- package/dist/{gameplay-Bxe1sMVT.js → gameplay-Bfff_beb.js} +10919 -6798
- package/dist/gameplay.d.ts +573 -31
- package/dist/gameplay.js +3 -2
- package/dist/index.d.ts +150 -6
- package/dist/index.js +6 -6
- package/dist/{loader-BAeWMYfF.d.ts → loader-CbkVdXL8.d.ts} +2 -2
- package/dist/net.d.ts +2 -2
- package/dist/net.js +2 -2
- package/dist/{physics-2d-C-SfvjzH.js → physics-2d-Tuf5LAyq.js} +250 -31
- package/dist/{physics-3d-rOzeg890.js → physics-3d-C5MOujfQ.js} +673 -51
- package/dist/{picking-BMV34Pjl.js → picking-DIwE48sU.js} +10 -7
- package/dist/{save-slots-CEUGeLuB.js → pose-ByFB_J3O.js} +217 -11
- package/dist/react.d.ts +2 -2
- package/dist/react.js +1 -1
- package/dist/{register-DRQyZKGU.js → register-7E3P1gz6.js} +191 -430
- package/dist/{register-CjociOtt.js → register-B768Qedj.js} +596 -2
- package/dist/{replay-B6BbgGM_.js → replay-DrqQ6dZj.js} +133 -18
- package/dist/{replay-wZK5Ok5c.d.ts → replay-W5nCw_cU.d.ts} +21 -2
- package/dist/{rng-Bb-IutXB.d.ts → rng-BsXZg3D6.d.ts} +7 -0
- package/dist/{split-screen-BxZ5rBe7.js → split-screen-B-dIcQsQ.js} +10 -5
- package/dist/{split-screen-D6sx8z3Z.d.ts → split-screen-CiLJf2-C.d.ts} +3 -3
- package/dist/{sprite-animation-Bz3DHD_4.js → sprite-animation-SQa5gIu2.js} +8 -6
- package/dist/{src-CqtvYtSN.js → src-D823V07k.js} +1 -1
- package/dist/{test-CEl0y2Sw.js → test-CVbxnXlv.js} +487 -82
- package/dist/test.d.ts +90 -12
- package/dist/test.js +2 -2
- package/dist/vite.js +34 -5
- package/editor/assets/{agent8-BlzturGi.js → agent8-DA-I5qhv.js} +1 -1
- package/editor/assets/{debug-BMUi8usj.js → debug-99tEPoGm.js} +1 -1
- package/editor/assets/index-Db74LZY-.js +11579 -0
- package/editor/index.html +1 -1
- package/package.json +1 -1
- package/schemas/scene.schema.json +1639 -280
- package/skills/incanto-3d-character.md +383 -20
- package/skills/incanto-audio.md +24 -2
- package/skills/incanto-building-2d-games.md +21 -2
- package/skills/incanto-building-3d-games.md +38 -3
- package/skills/incanto-editor.md +29 -8
- package/skills/incanto-environment.md +257 -14
- package/skills/incanto-game-feel.md +60 -1
- package/skills/incanto-gameplay-behaviors.md +668 -20
- package/skills/incanto-hud.md +116 -0
- package/skills/incanto-multiplayer.md +141 -2
- package/skills/incanto-node-reference.md +398 -16
- package/skills/incanto-performance.md +32 -0
- package/skills/incanto-physics-and-input.md +241 -13
- package/skills/incanto-playtesting.md +2 -2
- package/skills/incanto-save-slots.md +61 -2
- package/skills/incanto-scene-json-authoring.md +13 -0
- package/skills/incanto-verifying-your-game.md +86 -3
- package/templates-app/beacon-isle-3d/PROJECT/Status.md +12 -0
- package/templates-app/beacon-isle-3d/package.json +1 -1
- package/templates-app/beacon-isle-3d/src/game.scene.json +157 -3
- package/templates-app/molehill-2d/PROJECT/Status.md +7 -0
- package/templates-app/molehill-2d/package.json +1 -1
- package/templates-app/molehill-2d/src/game.scene.json +129 -2
- package/templates-app/platformer-2d/PROJECT/Status.md +7 -0
- package/templates-app/platformer-2d/docs/project-2d-rules.md +3 -2
- package/templates-app/platformer-2d/package.json +1 -1
- package/templates-app/platformer-2d/src/behaviors.ts +40 -26
- package/templates-app/platformer-2d/src/game.scene.json +144 -2
- package/templates-app/platformer-2d/verify.ts +18 -1
- package/templates-app/star-survivor/PROJECT/Status.md +7 -0
- package/templates-app/star-survivor/package.json +1 -1
- package/templates-app/star-survivor/src/behaviors.ts +9 -8
- package/templates-app/star-survivor/src/game.scene.json +142 -4
- package/templates-app/star-survivor/verify.ts +13 -0
- package/templates-app/tps-3d/PROJECT/Status.md +6 -0
- package/templates-app/tps-3d/package.json +1 -1
- package/templates-app/tps-3d/src/game.scene.json +71 -10
- package/templates-app/village-quest-3d/PROJECT/Status.md +7 -0
- package/templates-app/village-quest-3d/package.json +1 -1
- package/templates-app/village-quest-3d/src/behaviors.ts +8 -16
- package/templates-app/village-quest-3d/src/grove.scene.json +121 -5
- package/templates-app/village-quest-3d/src/village.scene.json +126 -2
- package/templates-app/village-quest-3d/verify.ts +52 -2
- package/editor/assets/index-CrUCQoaB.js +0 -11046
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { i as worldPosition } from "./pose-ByFB_J3O.js";
|
|
2
|
+
import { y as AudioPlayer } from "./register-B768Qedj.js";
|
|
2
3
|
import { i as logReport, o as parseDrive } from "./webgl-unavailable-C8aDbGmR.js";
|
|
3
4
|
import { a as frameSignature, i as frameImage, o as frameStats } from "./frame-report-D-_7YF2G.js";
|
|
4
|
-
import { et as worldPosition } from "./gameplay-Bxe1sMVT.js";
|
|
5
5
|
//#region src/core/audio-errors.ts
|
|
6
6
|
/** Every AudioPlayer under `root` whose source could not be played. */
|
|
7
7
|
function audioErrors(root) {
|
|
@@ -359,11 +359,14 @@ async function openBundledEditor(opts) {
|
|
|
359
359
|
await opts.play(working, camera);
|
|
360
360
|
}, "starting the game…");
|
|
361
361
|
},
|
|
362
|
-
...opts.exit ? { onExit: () =>
|
|
363
|
-
handle?.
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
362
|
+
...opts.exit ? { onExit: () => {
|
|
363
|
+
const working = handle?.working();
|
|
364
|
+
return crossFade(async () => {
|
|
365
|
+
handle?.dispose();
|
|
366
|
+
handle = null;
|
|
367
|
+
await opts.exit?.(working);
|
|
368
|
+
}, "back to the game…");
|
|
369
|
+
} } : {}
|
|
367
370
|
});
|
|
368
371
|
}
|
|
369
372
|
/**
|
|
@@ -425,10 +425,12 @@ function nodeRefWarnings(scene, opts = {}) {
|
|
|
425
425
|
if (!bag) continue;
|
|
426
426
|
for (const key of propKeys) {
|
|
427
427
|
const value = bag[key];
|
|
428
|
-
|
|
429
|
-
const
|
|
430
|
-
|
|
431
|
-
|
|
428
|
+
const entries = Array.isArray(value) ? value.flatMap((v, i) => typeof v === "string" && v !== "" ? [[`${key}[${i}]`, v]] : []) : typeof value === "string" && value !== "" ? [[key, value]] : [];
|
|
429
|
+
for (const [where, ref] of entries) {
|
|
430
|
+
const result = resolveRefInJson(root, at, ref);
|
|
431
|
+
if (result.ok) continue;
|
|
432
|
+
warnings.push(`${path}: ${prefix}${where} — ${describeRefProblem(result.problem, ref)} ` + (opts.fragment ? "This path leaves the fragment — only the host scene that instances it can answer, so this is fine if it resolves there and a typo if it does not." : "The scene loads and the prop does nothing."));
|
|
433
|
+
}
|
|
432
434
|
}
|
|
433
435
|
}
|
|
434
436
|
(node.children ?? []).forEach((child, i) => {
|
|
@@ -1231,6 +1233,16 @@ function hasDom() {
|
|
|
1231
1233
|
return typeof document !== "undefined";
|
|
1232
1234
|
}
|
|
1233
1235
|
/**
|
|
1236
|
+
* Is this widget switched off?
|
|
1237
|
+
*
|
|
1238
|
+
* `disabled` belongs to the widgets that can be pressed (`UiButton` today), not
|
|
1239
|
+
* to the base, so this asks rather than declares — a widget that grows the prop
|
|
1240
|
+
* later is out of the ring the day it does.
|
|
1241
|
+
*/
|
|
1242
|
+
function isDisabled(widget) {
|
|
1243
|
+
return widget.disabled === true;
|
|
1244
|
+
}
|
|
1245
|
+
/**
|
|
1234
1246
|
* The overlay container. One per scene is plenty; widgets mount into its
|
|
1235
1247
|
* anchor slots. `zIndex` lifts it above game canvases; the layer never eats
|
|
1236
1248
|
* pointer events (widgets that need clicks opt in individually).
|
|
@@ -1245,11 +1257,26 @@ var HudLayer = class HudLayer extends Node {
|
|
|
1245
1257
|
* layer, Enter / A activates. OFF by default — a game whose HUD has a
|
|
1246
1258
|
* button must not lose its arrow keys the moment one exists.
|
|
1247
1259
|
*/
|
|
1248
|
-
focusNavigation: { default: false }
|
|
1260
|
+
focusNavigation: { default: false },
|
|
1261
|
+
/**
|
|
1262
|
+
* Cinematic bars: the fraction of the layer's height each bar covers,
|
|
1263
|
+
* 0..0.5, drawn full-bleed at the top and bottom edges over every widget.
|
|
1264
|
+
* Two `UiPanel`s could not do this — they sit in anchor slots, inside the
|
|
1265
|
+
* layer's padding, above the dialogue box. Animate it from a behaviour.
|
|
1266
|
+
*/
|
|
1267
|
+
letterbox: {
|
|
1268
|
+
default: 0,
|
|
1269
|
+
range: {
|
|
1270
|
+
min: 0,
|
|
1271
|
+
max: .5
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1249
1274
|
};
|
|
1250
1275
|
zIndex = 100;
|
|
1251
1276
|
visible = true;
|
|
1252
1277
|
focusNavigation = false;
|
|
1278
|
+
letterbox = 0;
|
|
1279
|
+
bars = null;
|
|
1253
1280
|
/** @internal root overlay element (null headless). */
|
|
1254
1281
|
_element = null;
|
|
1255
1282
|
slots = /* @__PURE__ */ new Map();
|
|
@@ -1285,10 +1312,28 @@ var HudLayer = class HudLayer extends Node {
|
|
|
1285
1312
|
this._element = null;
|
|
1286
1313
|
this.slots.clear();
|
|
1287
1314
|
}
|
|
1315
|
+
/** The two bars, made on first use and sized every frame from `letterbox`. */
|
|
1316
|
+
_syncLetterbox() {
|
|
1317
|
+
const el = this._element;
|
|
1318
|
+
if (!el) return;
|
|
1319
|
+
if (!this.bars) {
|
|
1320
|
+
const make = (edge) => {
|
|
1321
|
+
const bar = document.createElement("div");
|
|
1322
|
+
bar.dataset.incantoLetterbox = edge;
|
|
1323
|
+
bar.style.cssText = `position:absolute;left:0px;right:0px;${edge}:0px;height:0%;background:#000;pointer-events:none;z-index:1000;`;
|
|
1324
|
+
el.appendChild(bar);
|
|
1325
|
+
return bar;
|
|
1326
|
+
};
|
|
1327
|
+
this.bars = [make("top"), make("bottom")];
|
|
1328
|
+
}
|
|
1329
|
+
const pct = `${Math.round(Math.min(.5, Math.max(0, this.letterbox)) * 1e4) / 100}%`;
|
|
1330
|
+
for (const bar of this.bars) if (bar.style.height !== pct) bar.style.height = pct;
|
|
1331
|
+
}
|
|
1288
1332
|
update() {
|
|
1289
1333
|
if (this._element) {
|
|
1290
1334
|
this._mount();
|
|
1291
1335
|
this._element.style.display = this.visible ? "" : "none";
|
|
1336
|
+
this._syncLetterbox();
|
|
1292
1337
|
}
|
|
1293
1338
|
if (this.focusNavigation && this.ownsFocus()) this.stepFocus();
|
|
1294
1339
|
}
|
|
@@ -1382,7 +1427,7 @@ var HudLayer = class HudLayer extends Node {
|
|
|
1382
1427
|
if (!this.visible) return out;
|
|
1383
1428
|
const walk = (node) => {
|
|
1384
1429
|
if (node instanceof HudWidgetBase && !node.visible) return;
|
|
1385
|
-
if (node instanceof HudWidgetBase && node.focusable) out.push(node);
|
|
1430
|
+
if (node instanceof HudWidgetBase && node.focusable && !isDisabled(node)) out.push(node);
|
|
1386
1431
|
for (const child of node.children) walk(child);
|
|
1387
1432
|
};
|
|
1388
1433
|
walk(this);
|
|
@@ -2683,7 +2728,8 @@ var InputMap = class {
|
|
|
2683
2728
|
const now = this.pointerPosition();
|
|
2684
2729
|
const movedX = was && now ? now.x - was.x : 0;
|
|
2685
2730
|
const movedY = was && now ? now.y - was.y : 0;
|
|
2686
|
-
|
|
2731
|
+
const native = document.pointerLockElement === target || e.pointerType === void 0 || e.pointerType === "mouse";
|
|
2732
|
+
this.handlePointerMove(native ? e.movementX ?? movedX : movedX, native ? e.movementY ?? movedY : movedY);
|
|
2687
2733
|
}
|
|
2688
2734
|
};
|
|
2689
2735
|
const onCancel = (e) => {
|
|
@@ -5041,8 +5087,9 @@ function wireConnections(root, connections, declareSignals = false) {
|
|
|
5041
5087
|
}
|
|
5042
5088
|
fn.apply(self, args);
|
|
5043
5089
|
};
|
|
5044
|
-
const listener = (...
|
|
5045
|
-
if (conn.filter && !matchesFilter(
|
|
5090
|
+
const listener = (...emitted) => {
|
|
5091
|
+
if (conn.filter && !matchesFilter(emitted[0], conn.filter)) return;
|
|
5092
|
+
const args = conn.args ? [...conn.args] : emitted;
|
|
5046
5093
|
if (conn.once) fromNode.off(conn.signal, listener);
|
|
5047
5094
|
try {
|
|
5048
5095
|
const fn = toNode[conn.handler];
|
|
@@ -5128,7 +5175,8 @@ const CONNECTION_KEYS = [
|
|
|
5128
5175
|
"to",
|
|
5129
5176
|
"handler",
|
|
5130
5177
|
"once",
|
|
5131
|
-
"filter"
|
|
5178
|
+
"filter",
|
|
5179
|
+
"args"
|
|
5132
5180
|
];
|
|
5133
5181
|
/** …and every key its `filter` may carry. */
|
|
5134
5182
|
const FILTER_KEYS = ["group", "tag"];
|
|
@@ -5156,6 +5204,7 @@ function validateConnectionShape(conn) {
|
|
|
5156
5204
|
});
|
|
5157
5205
|
}
|
|
5158
5206
|
if (raw.once !== void 0 && typeof raw.once !== "boolean") throw new IncantoError("BAD_FORMAT", `Connection ${where}: "once" is true or false, not ${JSON.stringify(raw.once)} — every non-empty string is truthy, so it would fire exactly once.`, { prop: "once" });
|
|
5207
|
+
if (raw.args !== void 0 && !Array.isArray(raw.args)) throw new IncantoError("BAD_FORMAT", `Connection ${where}: "args" is a LIST of the arguments to call the handler with, not ${JSON.stringify(raw.args)} — write ["ENRAGED"] rather than "ENRAGED".`, { prop: "args" });
|
|
5159
5208
|
if (raw.filter === void 0) return;
|
|
5160
5209
|
if (typeof raw.filter !== "object" || raw.filter === null || Array.isArray(raw.filter)) throw new IncantoError("BAD_FORMAT", `Connection ${where}: "filter" is {group?, tag?}, not ${JSON.stringify(raw.filter)} — a filter the matcher cannot read passes EVERYTHING.`, { prop: "filter" });
|
|
5161
5210
|
const filter = raw.filter;
|
|
@@ -5755,4 +5804,161 @@ function savesWithoutUid(root) {
|
|
|
5755
5804
|
return out;
|
|
5756
5805
|
}
|
|
5757
5806
|
//#endregion
|
|
5758
|
-
|
|
5807
|
+
//#region src/core/pose.ts
|
|
5808
|
+
/** Duck-type test: every spatial node (Node2D/Node3D) exposes `position: number[]`. */
|
|
5809
|
+
function hasPosition(node) {
|
|
5810
|
+
return Array.isArray(node.position);
|
|
5811
|
+
}
|
|
5812
|
+
const DEG = Math.PI / 180;
|
|
5813
|
+
/** Rotation matrix (row-major 3×3) of an Euler XYZ triple in degrees — three's 'XYZ' order. */
|
|
5814
|
+
function mat3FromEuler(rot) {
|
|
5815
|
+
const a = (rot[0] ?? 0) * DEG;
|
|
5816
|
+
const b = (rot[1] ?? 0) * DEG;
|
|
5817
|
+
const c = (rot[2] ?? 0) * DEG;
|
|
5818
|
+
const ca = Math.cos(a);
|
|
5819
|
+
const sa = Math.sin(a);
|
|
5820
|
+
const cb = Math.cos(b);
|
|
5821
|
+
const sb = Math.sin(b);
|
|
5822
|
+
const cc = Math.cos(c);
|
|
5823
|
+
const sc = Math.sin(c);
|
|
5824
|
+
return [
|
|
5825
|
+
cb * cc,
|
|
5826
|
+
-cb * sc,
|
|
5827
|
+
sb,
|
|
5828
|
+
ca * sc + sa * sb * cc,
|
|
5829
|
+
ca * cc - sa * sb * sc,
|
|
5830
|
+
-sa * cb,
|
|
5831
|
+
sa * sc - ca * sb * cc,
|
|
5832
|
+
sa * cc + ca * sb * sc,
|
|
5833
|
+
ca * cb
|
|
5834
|
+
];
|
|
5835
|
+
}
|
|
5836
|
+
function mat3Mul(a, b) {
|
|
5837
|
+
const o = new Array(9);
|
|
5838
|
+
for (let r = 0; r < 3; r++) for (let c = 0; c < 3; c++) o[r * 3 + c] = a[r * 3] * b[c] + a[r * 3 + 1] * b[3 + c] + a[r * 3 + 2] * b[6 + c];
|
|
5839
|
+
return o;
|
|
5840
|
+
}
|
|
5841
|
+
function mat3Apply(m, v) {
|
|
5842
|
+
const x = v[0] ?? 0;
|
|
5843
|
+
const y = v[1] ?? 0;
|
|
5844
|
+
const z = v[2] ?? 0;
|
|
5845
|
+
return [
|
|
5846
|
+
m[0] * x + m[1] * y + m[2] * z,
|
|
5847
|
+
m[3] * x + m[4] * y + m[5] * z,
|
|
5848
|
+
m[6] * x + m[7] * y + m[8] * z
|
|
5849
|
+
];
|
|
5850
|
+
}
|
|
5851
|
+
function mat3ApplyT(m, v) {
|
|
5852
|
+
const x = v[0] ?? 0;
|
|
5853
|
+
const y = v[1] ?? 0;
|
|
5854
|
+
const z = v[2] ?? 0;
|
|
5855
|
+
return [
|
|
5856
|
+
m[0] * x + m[3] * y + m[6] * z,
|
|
5857
|
+
m[1] * x + m[4] * y + m[7] * z,
|
|
5858
|
+
m[2] * x + m[5] * y + m[8] * z
|
|
5859
|
+
];
|
|
5860
|
+
}
|
|
5861
|
+
const IDENTITY = [
|
|
5862
|
+
1,
|
|
5863
|
+
0,
|
|
5864
|
+
0,
|
|
5865
|
+
0,
|
|
5866
|
+
1,
|
|
5867
|
+
0,
|
|
5868
|
+
0,
|
|
5869
|
+
0,
|
|
5870
|
+
1
|
|
5871
|
+
];
|
|
5872
|
+
/**
|
|
5873
|
+
* The pose of `node`'s PARENT frame in world space, composed through every
|
|
5874
|
+
* spatial ancestor — position AND rotation. It used to sum positions only, so
|
|
5875
|
+
* a child two metres down +z of a hull turned 90° was reported at world +z,
|
|
5876
|
+
* where nothing was drawn: the renderer composes the parent's rotation, and
|
|
5877
|
+
* every reader of this helper (a turret's muzzle, a camera under a rig, a
|
|
5878
|
+
* guard's eyes) disagreed with the picture by exactly that turn.
|
|
5879
|
+
*/
|
|
5880
|
+
function parentPose(node) {
|
|
5881
|
+
const chain = [];
|
|
5882
|
+
for (let at = node.parent; at; at = at.parent) if (hasPosition(at)) chain.push(at);
|
|
5883
|
+
const position = [
|
|
5884
|
+
0,
|
|
5885
|
+
0,
|
|
5886
|
+
0
|
|
5887
|
+
];
|
|
5888
|
+
let rot3 = IDENTITY;
|
|
5889
|
+
let angle2 = 0;
|
|
5890
|
+
for (let i = chain.length - 1; i >= 0; i--) {
|
|
5891
|
+
const n = chain[i];
|
|
5892
|
+
const local = n.position;
|
|
5893
|
+
if (local.length >= 3) {
|
|
5894
|
+
const moved = mat3Apply(rot3, local);
|
|
5895
|
+
position[0] = (position[0] ?? 0) + (moved[0] ?? 0);
|
|
5896
|
+
position[1] = (position[1] ?? 0) + (moved[1] ?? 0);
|
|
5897
|
+
position[2] = (position[2] ?? 0) + (moved[2] ?? 0);
|
|
5898
|
+
if (Array.isArray(n.rotation)) rot3 = mat3Mul(rot3, mat3FromEuler(n.rotation));
|
|
5899
|
+
} else {
|
|
5900
|
+
const a = angle2 * DEG;
|
|
5901
|
+
const x = local[0] ?? 0;
|
|
5902
|
+
const y = local[1] ?? 0;
|
|
5903
|
+
position[0] = (position[0] ?? 0) + x * Math.cos(a) - y * Math.sin(a);
|
|
5904
|
+
position[1] = (position[1] ?? 0) + x * Math.sin(a) + y * Math.cos(a);
|
|
5905
|
+
if (typeof n.rotation === "number") angle2 += n.rotation;
|
|
5906
|
+
}
|
|
5907
|
+
}
|
|
5908
|
+
return {
|
|
5909
|
+
position,
|
|
5910
|
+
rot3,
|
|
5911
|
+
angle2
|
|
5912
|
+
};
|
|
5913
|
+
}
|
|
5914
|
+
/** The node's position in WORLD space — its parents' positions and rotations composed. */
|
|
5915
|
+
function worldPosition(node) {
|
|
5916
|
+
const own = node.position;
|
|
5917
|
+
if (!Array.isArray(own)) return [];
|
|
5918
|
+
const p = parentPose(node);
|
|
5919
|
+
if (own.length >= 3) {
|
|
5920
|
+
const moved = mat3Apply(p.rot3, own);
|
|
5921
|
+
return [
|
|
5922
|
+
(p.position[0] ?? 0) + (moved[0] ?? 0),
|
|
5923
|
+
(p.position[1] ?? 0) + (moved[1] ?? 0),
|
|
5924
|
+
(p.position[2] ?? 0) + (moved[2] ?? 0)
|
|
5925
|
+
];
|
|
5926
|
+
}
|
|
5927
|
+
const a = p.angle2 * DEG;
|
|
5928
|
+
const x = own[0] ?? 0;
|
|
5929
|
+
const y = own[1] ?? 0;
|
|
5930
|
+
return [(p.position[0] ?? 0) + x * Math.cos(a) - y * Math.sin(a), (p.position[1] ?? 0) + x * Math.sin(a) + y * Math.cos(a)];
|
|
5931
|
+
}
|
|
5932
|
+
/**
|
|
5933
|
+
* A LOCAL vector turned into world space by the node's own rotation and every
|
|
5934
|
+
* ancestor's — a barrel's forward, a muzzle's offset, a hardpoint's direction.
|
|
5935
|
+
*
|
|
5936
|
+
* `worldPosition` answers where a node IS; this answers which way it points,
|
|
5937
|
+
* and two games wrote it by hand (a tank's `forwardOf`, an artillery piece's
|
|
5938
|
+
* barrel tip) because nothing else could say it. `worldDirection(node, [0,0,1])`
|
|
5939
|
+
* is the +Z-forward convention every 3D skin in this engine follows.
|
|
5940
|
+
*/
|
|
5941
|
+
function worldDirection(node, local) {
|
|
5942
|
+
const p = parentPose(node);
|
|
5943
|
+
const own = node.rotation;
|
|
5944
|
+
if (local.length >= 3 || Array.isArray(own)) return mat3Apply(Array.isArray(own) ? mat3Mul(p.rot3, mat3FromEuler(own)) : p.rot3, local);
|
|
5945
|
+
const a = (p.angle2 + (typeof own === "number" ? own : 0)) * DEG;
|
|
5946
|
+
const x = local[0] ?? 0;
|
|
5947
|
+
const y = local[1] ?? 0;
|
|
5948
|
+
return [x * Math.cos(a) - y * Math.sin(a), x * Math.sin(a) + y * Math.cos(a)];
|
|
5949
|
+
}
|
|
5950
|
+
/** The local `position` that puts `node` at `world` — the inverse of `worldPosition`. */
|
|
5951
|
+
function localFromWorld(node, world) {
|
|
5952
|
+
const p = parentPose(node);
|
|
5953
|
+
if (world.length >= 3) return mat3ApplyT(p.rot3, [
|
|
5954
|
+
(world[0] ?? 0) - (p.position[0] ?? 0),
|
|
5955
|
+
(world[1] ?? 0) - (p.position[1] ?? 0),
|
|
5956
|
+
(world[2] ?? 0) - (p.position[2] ?? 0)
|
|
5957
|
+
]);
|
|
5958
|
+
const a = -p.angle2 * DEG;
|
|
5959
|
+
const x = (world[0] ?? 0) - (p.position[0] ?? 0);
|
|
5960
|
+
const y = (world[1] ?? 0) - (p.position[1] ?? 0);
|
|
5961
|
+
return [x * Math.cos(a) - y * Math.sin(a), x * Math.sin(a) + y * Math.cos(a)];
|
|
5962
|
+
}
|
|
5963
|
+
//#endregion
|
|
5964
|
+
export { Node as $, isConstRef as A, resolveOrderGroups as B, serializeNode as C, sunDirectionFromElevationAzimuth as D, parseEnvironment3D as E, SceneTree as F, HudLayer as G, handlerShadowWarnings as H, createSaveStore as I, UiBanner as J, HudWidgetBase as K, resetMemorySaves as L, computeViewport as M, resolveViewport as N, sunDirectionFromSky as O, newUid as P, requireText as Q, ORDER_GROUP_BASE as R, Scene as S, horizonColorFromSky as T, sceneDimension as U, InputMap as V, FITS$1 as W, UiText as X, UiBar as Y, requireNumber as Z, stripUids as _, ENGINE_STATE_KEY as a, Behavior as at, loadScene as b, captureBehaviors as c, behaviorSignals as ct, duplicateNode as d, registerBehavior as dt, diagnose as et, isCloned as f, registeredBehaviors as ft, rememberAuthoredPath as g, rebuildOptions as h, worldPosition as i, parseNodePath as it, resolveConstants as j, CONST_REF_KEY as k, restoreBehaviors as l, clearBehaviors as lt, markTemplateName as m, localFromWorld as n, nodeRefWarnings as nt, SaveSlots as o, StubBehavior as ot, markCloned as p, Signal as pt, TAPPABLE as q, worldDirection as r, resolveRefInJson as rt, behaviorsWithoutSave as s, behaviorSchema as st, hasPosition as t, describeRefProblem as tt, savesWithoutUid as u, getBehavior as ut, buildNodeJson as v, SCENE_FORMAT as w, loader_exports as x, buildSceneSubtree as y, effectiveOrder as z };
|
package/dist/react.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { P as Scene, b as Engine, n as BehaviorCtor } from "./behavior-
|
|
2
|
-
import { c as JsonValue } from "./rng-
|
|
1
|
+
import { P as Scene, b as Engine, n as BehaviorCtor } from "./behavior-B_245qRy.js";
|
|
2
|
+
import { c as JsonValue } from "./rng-BsXZg3D6.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-Dai5vfVu.js").then((n) => n.n)).createGame3D(o) : async (o) => (await import("./create-game-BMIPKrQW.js").then((n) => n.n)).createGame2D(o)))(opts);
|
|
160
160
|
if (disposed) {
|
|
161
161
|
next.dispose();
|
|
162
162
|
return;
|