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
|
@@ -1,12 +1,12 @@
|
|
|
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 { t as createNoise2D } from "./noise-CGUMx44x.js";
|
|
8
8
|
import { n as splatWeights, t as buildHeightmap } from "./heightmap-CroQPEER.js";
|
|
9
|
-
import { AdditiveBlending, AnimationClip, AnimationMixer, Box3, BoxGeometry, BufferAttribute, BufferGeometry, CanvasTexture, CapsuleGeometry, Color, ConeGeometry, CubeCamera, CylinderGeometry, DataTexture, DepthTexture, DirectionalLight, DoubleSide, Euler, FloatType, Frustum, Group, HalfFloatType, IcosahedronGeometry, ImageBitmapLoader, InstancedBufferAttribute, InstancedMesh, LinearFilter, LinearMipmapLinearFilter, LoopOnce, LoopRepeat, MathUtils, Matrix4, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshStandardMaterial, NearestFilter, NoBlending, NormalBlending, Object3D, PerspectiveCamera, Plane, PlaneGeometry, PointLight, Points, PointsMaterial, Quaternion, QuaternionKeyframeTrack, RGBADepthPacking, RGBAFormat, RepeatWrapping, SRGBColorSpace, ShaderChunk, ShaderMaterial, Sphere, SphereGeometry, Texture, TextureLoader, UniformsLib, UniformsUtils, Vector2, Vector3, Vector4, VectorKeyframeTrack, WebGLCubeRenderTarget, WebGLRenderTarget } from "three";
|
|
9
|
+
import { AdditiveBlending, AnimationClip, AnimationMixer, Box3, BoxGeometry, BufferAttribute, BufferGeometry, CanvasTexture, CapsuleGeometry, Color, ConeGeometry, CubeCamera, CylinderGeometry, DataTexture, DepthTexture, DirectionalLight, DoubleSide, Euler, FloatType, Frustum, Group, HalfFloatType, IcosahedronGeometry, ImageBitmapLoader, InstancedBufferAttribute, InstancedMesh, LinearFilter, LinearMipmapLinearFilter, LoopOnce, LoopRepeat, MathUtils, Matrix4, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshPhysicalMaterial, MeshStandardMaterial, NearestFilter, NoBlending, NormalBlending, Object3D, PerspectiveCamera, Plane, PlaneGeometry, PointLight, Points, PointsMaterial, Quaternion, QuaternionKeyframeTrack, RGBADepthPacking, RGBAFormat, RepeatWrapping, SRGBColorSpace, ShaderChunk, ShaderMaterial, Sphere, SphereGeometry, Texture, TextureLoader, UniformsLib, UniformsUtils, Vector2, Vector3, Vector4, VectorKeyframeTrack, WebGLCubeRenderTarget, WebGLRenderTarget } from "three";
|
|
10
10
|
import { clone } from "three/addons/utils/SkeletonUtils.js";
|
|
11
11
|
//#region src/3d/camera-rig.ts
|
|
12
12
|
const QUARTER_PITCH = Math.atan(1 / Math.SQRT2);
|
|
@@ -286,7 +286,21 @@ var PhysicsBody3D = class extends Node3D {
|
|
|
286
286
|
static props = { collider: { default: {} } };
|
|
287
287
|
/** The unified collision model: every collider participant can emit these. */
|
|
288
288
|
static signals = ["triggerEnter", "triggerExit"];
|
|
289
|
-
|
|
289
|
+
_collider = {};
|
|
290
|
+
/** @internal Physics resync flag — raised when `collider` is REPLACED. */
|
|
291
|
+
_colliderChanged = false;
|
|
292
|
+
/**
|
|
293
|
+
* Collider shape prop. Change it by REPLACING the object
|
|
294
|
+
* (`body.collider = { shape: 'box', size: [...] }`) — physics rebuilds the
|
|
295
|
+
* body on replacement; in-place mutation of the old object is not watched.
|
|
296
|
+
*/
|
|
297
|
+
get collider() {
|
|
298
|
+
return this._collider;
|
|
299
|
+
}
|
|
300
|
+
set collider(value) {
|
|
301
|
+
this._collider = value;
|
|
302
|
+
this._colliderChanged = true;
|
|
303
|
+
}
|
|
290
304
|
/** Loader hook: bad collider shapes fail at LOAD, not at physics start. */
|
|
291
305
|
static validateJson(node) {
|
|
292
306
|
const body = node;
|
|
@@ -373,6 +387,78 @@ var CharacterBody3D = class extends PhysicsBody3D {
|
|
|
373
387
|
}
|
|
374
388
|
};
|
|
375
389
|
//#endregion
|
|
390
|
+
//#region src/3d/nodes/joint-3d.ts
|
|
391
|
+
/**
|
|
392
|
+
* A physics joint linking its PARENT body to `target` (a node path to the
|
|
393
|
+
* other body). Godot-style placement: the joint lives as a child of body A.
|
|
394
|
+
*
|
|
395
|
+
* { "name": "Hinge", "type": "Joint3D",
|
|
396
|
+
* "props": { "type": "spherical", "target": "%Anchor", "anchor": [0, -20] } }
|
|
397
|
+
*
|
|
398
|
+
* Types: `fixed` welds the bodies rigidly · `spherical` is a ball joint at the
|
|
399
|
+
* anchors · `rope` caps the anchor distance at `length` (m; 0 = measured at
|
|
400
|
+
* creation) · `spring` pulls toward `length` with `stiffness`/`damping`.
|
|
401
|
+
* Anchors are LOCAL meter offsets on each body.
|
|
402
|
+
*/
|
|
403
|
+
var Joint3D = class extends Node3D {
|
|
404
|
+
static typeName = "Joint3D";
|
|
405
|
+
static props = {
|
|
406
|
+
type: {
|
|
407
|
+
default: "spherical",
|
|
408
|
+
options: [
|
|
409
|
+
"fixed",
|
|
410
|
+
"spherical",
|
|
411
|
+
"rope",
|
|
412
|
+
"spring"
|
|
413
|
+
]
|
|
414
|
+
},
|
|
415
|
+
target: { default: "" },
|
|
416
|
+
anchor: { default: [
|
|
417
|
+
0,
|
|
418
|
+
0,
|
|
419
|
+
0
|
|
420
|
+
] },
|
|
421
|
+
targetAnchor: { default: [
|
|
422
|
+
0,
|
|
423
|
+
0,
|
|
424
|
+
0
|
|
425
|
+
] },
|
|
426
|
+
length: { default: 0 },
|
|
427
|
+
stiffness: { default: 50 },
|
|
428
|
+
damping: { default: 5 }
|
|
429
|
+
};
|
|
430
|
+
type = "spherical";
|
|
431
|
+
target = "";
|
|
432
|
+
anchor = [
|
|
433
|
+
0,
|
|
434
|
+
0,
|
|
435
|
+
0
|
|
436
|
+
];
|
|
437
|
+
targetAnchor = [
|
|
438
|
+
0,
|
|
439
|
+
0,
|
|
440
|
+
0
|
|
441
|
+
];
|
|
442
|
+
/** rope/spring rest length in m; 0 = measure body distance at creation. */
|
|
443
|
+
length = 0;
|
|
444
|
+
stiffness = 50;
|
|
445
|
+
damping = 5;
|
|
446
|
+
onEnterTree() {
|
|
447
|
+
if (!(this.parent instanceof PhysicsBody3D)) throw new IncantoError("TREE_VIOLATION", `Joint3D '${this.name}' must be a child of a physics body (its body A); parent is '${this.parent?.name ?? "none"}'.`);
|
|
448
|
+
if (this.target === "") throw new IncantoError("BAD_FORMAT", `Joint3D '${this.name}' needs a "target" node path to the body it links to.`);
|
|
449
|
+
}
|
|
450
|
+
/** @internal The two bodies, resolved (throws on a bad target at step time). */
|
|
451
|
+
_resolveBodies() {
|
|
452
|
+
const a = this.parent;
|
|
453
|
+
const b = this.getNodeOrNull(this.target);
|
|
454
|
+
if (!(b instanceof PhysicsBody3D)) throw new IncantoError("NODE_NOT_FOUND", `Joint3D '${this.name}': target '${this.target}' is not a physics body.`);
|
|
455
|
+
return {
|
|
456
|
+
a,
|
|
457
|
+
b
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
};
|
|
461
|
+
//#endregion
|
|
376
462
|
//#region src/3d/terrain/splat-material.ts
|
|
377
463
|
/** Splice `code` immediately AFTER `marker` — a missing marker is a hard error
|
|
378
464
|
* (a silently unpatched terrain shader renders weight-colored vertex soup). */
|
|
@@ -1362,7 +1448,8 @@ const SHADOW_CONTACT_PUSH = .5;
|
|
|
1362
1448
|
*
|
|
1363
1449
|
* - `texture`: image URL (sRGB), empty = hidden
|
|
1364
1450
|
* - `size [w,h]`: quad size in world metres
|
|
1365
|
-
* - `billboard`: `"y"` upright
|
|
1451
|
+
* - `billboard`: `"y"` upright, screen-aligned yaw (shares the camera heading, so
|
|
1452
|
+
* off-center sprites never roll) · `"full"` face camera · `"none"` fixed
|
|
1366
1453
|
* - `anchor [ax,ay]`: pivot in 0..1 that sits at the node origin; `[0.5,0]` = feet
|
|
1367
1454
|
* - `pixelArt`: nearest-filter for crisp pixels · `alphaTest`: cutout that depth-sorts
|
|
1368
1455
|
*/
|
|
@@ -1395,7 +1482,7 @@ var Sprite3D = class extends Node3D {
|
|
|
1395
1482
|
texture = "";
|
|
1396
1483
|
/** Quad `[width, height]` in world units (metres). */
|
|
1397
1484
|
size = [1, 1];
|
|
1398
|
-
/** `"y"` upright yaw-
|
|
1485
|
+
/** `"y"` upright, screen-aligned yaw (no off-center roll) · `"full"` face camera · `"none"` fixed. */
|
|
1399
1486
|
billboard = "y";
|
|
1400
1487
|
/** Pivot in 0..1 of the sprite that sits at the node origin; `[0.5,0]` = feet. */
|
|
1401
1488
|
anchor = [.5, 0];
|
|
@@ -1538,7 +1625,11 @@ var Sprite3D = class extends Node3D {
|
|
|
1538
1625
|
* caster at the light. Headless runs have no Renderer3D and never call this, so
|
|
1539
1626
|
* plain trees pay nothing. */
|
|
1540
1627
|
_onRender3D(ctx) {
|
|
1541
|
-
if (this.billboard
|
|
1628
|
+
if (this.billboard === "y") {
|
|
1629
|
+
ctx.camera.getWorldDirection(_dir$1);
|
|
1630
|
+
_dir$1.y = 0;
|
|
1631
|
+
if (_dir$1.lengthSq() >= 1e-6) this._faceDir(this._quad(), _dir$1.negate());
|
|
1632
|
+
} else if (this.billboard === "full") this._faceToward(this._quad(), ctx.camera.position);
|
|
1542
1633
|
const caster = this.shadowMesh;
|
|
1543
1634
|
if (caster?.castShadow && ctx.sunDir) {
|
|
1544
1635
|
this._faceDir(caster, ctx.sunDir);
|
|
@@ -1697,8 +1788,6 @@ function resolveFrames(frames, name) {
|
|
|
1697
1788
|
//#region src/3d/nodes/billboard-3d.ts
|
|
1698
1789
|
const _parentQ = new Quaternion();
|
|
1699
1790
|
const _rotQ = new Quaternion();
|
|
1700
|
-
const _pos = new Vector3();
|
|
1701
|
-
const _camPos = new Vector3();
|
|
1702
1791
|
const _dir = new Vector3();
|
|
1703
1792
|
const Z_AXIS = new Vector3(0, 0, 1);
|
|
1704
1793
|
/** Valid `Billboard3D.mode` values — drives the prop options AND validateJson. */
|
|
@@ -1736,7 +1825,7 @@ var Billboard3D = class extends Node3D {
|
|
|
1736
1825
|
options: BILLBOARD_GROUP_MODES
|
|
1737
1826
|
} };
|
|
1738
1827
|
/** `"screen"` copy the camera orientation (screen-aligned) · `"y"` upright
|
|
1739
|
-
* yaw-
|
|
1828
|
+
* screen-aligned yaw (no off-center roll) · `"none"` off (authored rotation applies). */
|
|
1740
1829
|
mode = "screen";
|
|
1741
1830
|
/** Last successfully billboarded WORLD orientation — reapplied on the frames
|
|
1742
1831
|
* where `"y"` has no answer (camera dead overhead), because `_syncObject3D`
|
|
@@ -1759,11 +1848,9 @@ var Billboard3D = class extends Node3D {
|
|
|
1759
1848
|
const o = this._ensureObject3D();
|
|
1760
1849
|
if (this.mode === "screen") ctx.camera.getWorldQuaternion(_rotQ);
|
|
1761
1850
|
else {
|
|
1762
|
-
|
|
1763
|
-
ctx.camera.getWorldPosition(_camPos);
|
|
1764
|
-
_dir.copy(_camPos).sub(_pos);
|
|
1851
|
+
ctx.camera.getWorldDirection(_dir);
|
|
1765
1852
|
_dir.y = 0;
|
|
1766
|
-
if (_dir.lengthSq() >= 1e-
|
|
1853
|
+
if (_dir.lengthSq() >= 1e-6) _rotQ.setFromUnitVectors(Z_AXIS, _dir.negate().normalize());
|
|
1767
1854
|
else if (this._lastDesired) _rotQ.copy(this._lastDesired);
|
|
1768
1855
|
else return;
|
|
1769
1856
|
}
|
|
@@ -4884,6 +4971,9 @@ const MATERIAL_KEYS = [
|
|
|
4884
4971
|
"wireframe",
|
|
4885
4972
|
"flatShading",
|
|
4886
4973
|
"opacity",
|
|
4974
|
+
"clearcoat",
|
|
4975
|
+
"clearcoatRoughness",
|
|
4976
|
+
"envMapIntensity",
|
|
4887
4977
|
"depthTest",
|
|
4888
4978
|
"depthWrite",
|
|
4889
4979
|
"map",
|
|
@@ -4896,7 +4986,8 @@ const MATERIAL_KEYS = [
|
|
|
4896
4986
|
* - `size [x,y,z]`: box extents; sphere/gem radius = x; capsule radius = x,
|
|
4897
4987
|
* height = y; plane = x·z ground plane (laid flat); cylinder radius = x, height = y
|
|
4898
4988
|
* - `material`: `{color, metalness, roughness, wireframe, flatShading, opacity,
|
|
4899
|
-
*
|
|
4989
|
+
* clearcoat, clearcoatRoughness, envMapIntensity, depthTest, depthWrite,
|
|
4990
|
+
* emissive, emissiveIntensity, map, normalMap, repeat}` —
|
|
4900
4991
|
* `map`/`normalMap` are texture URLs loaded lazily (headless-safe: geometry and
|
|
4901
4992
|
* physics never wait on them), tiled by `repeat: [u, v]`. `gem` + `flatShading:
|
|
4902
4993
|
* true` + a low `roughness` reads as a sparkling faceted jewel (spin it for the
|
|
@@ -4937,13 +5028,13 @@ var MeshInstance3D = class extends Node3D {
|
|
|
4937
5028
|
receiveShadow = false;
|
|
4938
5029
|
/** Loader hook: malformed materials fail at LOAD time, not at render. */
|
|
4939
5030
|
static validateJson(node) {
|
|
4940
|
-
|
|
5031
|
+
validateMeshMaterial(node.material, node.name);
|
|
4941
5032
|
}
|
|
4942
5033
|
geometryKey = "";
|
|
4943
5034
|
textureKey = "";
|
|
4944
5035
|
loadedTextures = [];
|
|
4945
5036
|
_createObject3D() {
|
|
4946
|
-
return new Mesh(new BoxGeometry(1, 1, 1), new
|
|
5037
|
+
return new Mesh(new BoxGeometry(1, 1, 1), new MeshPhysicalMaterial());
|
|
4947
5038
|
}
|
|
4948
5039
|
_syncObject3D() {
|
|
4949
5040
|
super._syncObject3D();
|
|
@@ -4955,22 +5046,7 @@ var MeshInstance3D = class extends Node3D {
|
|
|
4955
5046
|
this.geometryKey = key;
|
|
4956
5047
|
}
|
|
4957
5048
|
const mat = m.material;
|
|
4958
|
-
mat
|
|
4959
|
-
mat.metalness = this.material.metalness ?? 0;
|
|
4960
|
-
mat.roughness = this.material.roughness ?? 1;
|
|
4961
|
-
mat.wireframe = this.material.wireframe ?? false;
|
|
4962
|
-
mat.emissive.set(this.material.emissive ?? "#000000");
|
|
4963
|
-
mat.emissiveIntensity = this.material.emissiveIntensity ?? 1;
|
|
4964
|
-
const opacity = this.material.opacity ?? 1;
|
|
4965
|
-
mat.opacity = opacity;
|
|
4966
|
-
mat.transparent = opacity < 1;
|
|
4967
|
-
mat.depthTest = this.material.depthTest ?? true;
|
|
4968
|
-
mat.depthWrite = this.material.depthWrite ?? true;
|
|
4969
|
-
const flat = this.material.flatShading ?? false;
|
|
4970
|
-
if (mat.flatShading !== flat) {
|
|
4971
|
-
mat.flatShading = flat;
|
|
4972
|
-
mat.needsUpdate = true;
|
|
4973
|
-
}
|
|
5049
|
+
applyMeshMaterial(mat, this.material);
|
|
4974
5050
|
this.syncTextures(mat);
|
|
4975
5051
|
m.castShadow = this.castShadow;
|
|
4976
5052
|
m.receiveShadow = this.receiveShadow;
|
|
@@ -5013,11 +5089,42 @@ var MeshInstance3D = class extends Node3D {
|
|
|
5013
5089
|
super.free();
|
|
5014
5090
|
}
|
|
5015
5091
|
};
|
|
5092
|
+
/**
|
|
5093
|
+
* Apply the shared material-prop pipeline (everything except textures) with
|
|
5094
|
+
* reset-to-default semantics: the JSON object IS the material state — a
|
|
5095
|
+
* replaced `{color}` must not keep a stale wireframe from a previous value.
|
|
5096
|
+
* Shared by every node that takes a `MeshMaterialProps` (MeshInstance3D,
|
|
5097
|
+
* LoftMesh3D).
|
|
5098
|
+
*/
|
|
5099
|
+
function applyMeshMaterial(mat, props) {
|
|
5100
|
+
mat.color.set(props.color ?? "#ffffff");
|
|
5101
|
+
mat.metalness = props.metalness ?? 0;
|
|
5102
|
+
mat.roughness = props.roughness ?? 1;
|
|
5103
|
+
mat.wireframe = props.wireframe ?? false;
|
|
5104
|
+
mat.emissive.set(props.emissive ?? "#000000");
|
|
5105
|
+
mat.emissiveIntensity = props.emissiveIntensity ?? 1;
|
|
5106
|
+
const opacity = props.opacity ?? 1;
|
|
5107
|
+
mat.opacity = opacity;
|
|
5108
|
+
mat.transparent = opacity < 1;
|
|
5109
|
+
const clearcoat = props.clearcoat ?? 0;
|
|
5110
|
+
if (mat.clearcoat > 0 !== clearcoat > 0) mat.needsUpdate = true;
|
|
5111
|
+
mat.clearcoat = clearcoat;
|
|
5112
|
+
mat.clearcoatRoughness = props.clearcoatRoughness ?? 0;
|
|
5113
|
+
mat.envMapIntensity = props.envMapIntensity ?? 1;
|
|
5114
|
+
mat.depthTest = props.depthTest ?? true;
|
|
5115
|
+
mat.depthWrite = props.depthWrite ?? true;
|
|
5116
|
+
const flat = props.flatShading ?? false;
|
|
5117
|
+
if (mat.flatShading !== flat) {
|
|
5118
|
+
mat.flatShading = flat;
|
|
5119
|
+
mat.needsUpdate = true;
|
|
5120
|
+
}
|
|
5121
|
+
}
|
|
5016
5122
|
/** Hard-fail on malformed material JSON — typos and bad shapes surface at
|
|
5017
|
-
* load with the valid options, instead of silently rendering defaults.
|
|
5018
|
-
|
|
5123
|
+
* load with the valid options, instead of silently rendering defaults.
|
|
5124
|
+
* Exported for nodes that reuse `MeshMaterialProps` (LoftMesh3D). */
|
|
5125
|
+
function validateMeshMaterial(material, name, typeName = "MeshInstance3D") {
|
|
5019
5126
|
const fail = (message) => {
|
|
5020
|
-
throw new IncantoError("BAD_FORMAT",
|
|
5127
|
+
throw new IncantoError("BAD_FORMAT", `${typeName} '${name}' ${message}`, {
|
|
5021
5128
|
prop: "material",
|
|
5022
5129
|
validOptions: [...MATERIAL_KEYS]
|
|
5023
5130
|
});
|
|
@@ -5036,11 +5143,14 @@ function validateMaterial(material, name) {
|
|
|
5036
5143
|
for (const key of [
|
|
5037
5144
|
"metalness",
|
|
5038
5145
|
"roughness",
|
|
5039
|
-
"opacity"
|
|
5146
|
+
"opacity",
|
|
5147
|
+
"clearcoat",
|
|
5148
|
+
"clearcoatRoughness"
|
|
5040
5149
|
]) {
|
|
5041
5150
|
const value = material[key];
|
|
5042
5151
|
if (value !== void 0 && !(typeof value === "number" && value >= 0 && value <= 1)) fail(`material.${key} must be a number in 0..1, got ${JSON.stringify(value)}.`);
|
|
5043
5152
|
}
|
|
5153
|
+
if (material.envMapIntensity !== void 0 && !(typeof material.envMapIntensity === "number" && Number.isFinite(material.envMapIntensity) && material.envMapIntensity >= 0)) fail(`material.envMapIntensity must be a number >= 0, got ${JSON.stringify(material.envMapIntensity)}.`);
|
|
5044
5154
|
for (const key of [
|
|
5045
5155
|
"wireframe",
|
|
5046
5156
|
"flatShading",
|
|
@@ -5070,6 +5180,185 @@ function buildGeometry(kind, size) {
|
|
|
5070
5180
|
}
|
|
5071
5181
|
}
|
|
5072
5182
|
//#endregion
|
|
5183
|
+
//#region src/3d/nodes/loft-mesh-3d.ts
|
|
5184
|
+
/**
|
|
5185
|
+
* A smooth swept hull ("loft"): superellipse cross-sections interpolated
|
|
5186
|
+
* along Z with rounded end caps and per-vertex normals — curved highlights
|
|
5187
|
+
* and sky reflections sweep across it like sheet metal, which no box/capsule
|
|
5188
|
+
* assembly can do. THE node for vehicle bodies, glass canopies, boat hulls,
|
|
5189
|
+
* fuselages.
|
|
5190
|
+
*
|
|
5191
|
+
* - `sections`: ≥2 stations front→back (see LoftSection)
|
|
5192
|
+
* - `slices`: vertices around each ring (8..64, default 24)
|
|
5193
|
+
* - `smooth`: interpolated rings per section gap (1..16, default 4)
|
|
5194
|
+
* - `material`: same object as MeshInstance3D **minus textures** (a loft has
|
|
5195
|
+
* no UVs — map/normalMap/repeat hard-fail). Pair `clearcoat` paint or a
|
|
5196
|
+
* high `envMapIntensity` glass with the smooth normals for the automotive
|
|
5197
|
+
* look.
|
|
5198
|
+
*/
|
|
5199
|
+
var LoftMesh3D = class extends Node3D {
|
|
5200
|
+
static typeName = "LoftMesh3D";
|
|
5201
|
+
static props = {
|
|
5202
|
+
sections: { default: [] },
|
|
5203
|
+
slices: { default: 24 },
|
|
5204
|
+
smooth: { default: 4 },
|
|
5205
|
+
material: { default: {} },
|
|
5206
|
+
castShadow: { default: false },
|
|
5207
|
+
receiveShadow: { default: false }
|
|
5208
|
+
};
|
|
5209
|
+
sections = [];
|
|
5210
|
+
slices = 24;
|
|
5211
|
+
smooth = 4;
|
|
5212
|
+
material = {};
|
|
5213
|
+
castShadow = false;
|
|
5214
|
+
receiveShadow = false;
|
|
5215
|
+
/** Loader hook: malformed sections/materials fail at LOAD time. */
|
|
5216
|
+
static validateJson(node) {
|
|
5217
|
+
const loft = node;
|
|
5218
|
+
validateSections(loft.sections, node.name);
|
|
5219
|
+
validateMeshMaterial(loft.material, node.name, "LoftMesh3D");
|
|
5220
|
+
for (const key of [
|
|
5221
|
+
"map",
|
|
5222
|
+
"normalMap",
|
|
5223
|
+
"repeat"
|
|
5224
|
+
]) if (loft.material[key] !== void 0) throw new IncantoError("BAD_FORMAT", `LoftMesh3D '${node.name}' material does not support '${key}' — a loft has no UVs; use color/metalness/roughness/clearcoat/envMapIntensity instead.`, { prop: "material" });
|
|
5225
|
+
}
|
|
5226
|
+
geometryKey = "";
|
|
5227
|
+
_createObject3D() {
|
|
5228
|
+
return new Mesh(new BufferGeometry(), new MeshPhysicalMaterial());
|
|
5229
|
+
}
|
|
5230
|
+
_syncObject3D() {
|
|
5231
|
+
super._syncObject3D();
|
|
5232
|
+
const m = this._ensureObject3D();
|
|
5233
|
+
const key = JSON.stringify([
|
|
5234
|
+
this.sections,
|
|
5235
|
+
this.slices,
|
|
5236
|
+
this.smooth
|
|
5237
|
+
]);
|
|
5238
|
+
if (key !== this.geometryKey && this.sections.length >= 2) {
|
|
5239
|
+
m.geometry.dispose();
|
|
5240
|
+
m.geometry = buildLoftGeometry(this.sections, this.slices, this.smooth);
|
|
5241
|
+
this.geometryKey = key;
|
|
5242
|
+
}
|
|
5243
|
+
applyMeshMaterial(m.material, this.material);
|
|
5244
|
+
m.castShadow = this.castShadow;
|
|
5245
|
+
m.receiveShadow = this.receiveShadow;
|
|
5246
|
+
}
|
|
5247
|
+
};
|
|
5248
|
+
function validateSections(sections, name) {
|
|
5249
|
+
const fail = (message) => {
|
|
5250
|
+
throw new IncantoError("BAD_FORMAT", `LoftMesh3D '${name}' ${message}`, { prop: "sections" });
|
|
5251
|
+
};
|
|
5252
|
+
if (!Array.isArray(sections) || sections.length < 2) fail(`sections needs at least 2 stations, got ${JSON.stringify(sections)}.`);
|
|
5253
|
+
for (const [i, s] of sections.entries()) {
|
|
5254
|
+
if (typeof s !== "object" || s === null) fail(`sections[${i}] must be an object.`);
|
|
5255
|
+
for (const k of [
|
|
5256
|
+
"z",
|
|
5257
|
+
"width",
|
|
5258
|
+
"height",
|
|
5259
|
+
"y"
|
|
5260
|
+
]) if (typeof s[k] !== "number" || !Number.isFinite(s[k])) fail(`sections[${i}].${k} must be a finite number, got ${JSON.stringify(s[k])}.`);
|
|
5261
|
+
if (s.width <= 0 || s.height <= 0) fail(`sections[${i}] width/height must be positive, got ${s.width}×${s.height}.`);
|
|
5262
|
+
if (s.corner !== void 0 && !(typeof s.corner === "number" && s.corner >= 0 && s.corner <= 1)) fail(`sections[${i}].corner must be in 0..1, got ${JSON.stringify(s.corner)}.`);
|
|
5263
|
+
if (i > 0 && s.z <= sections[i - 1].z) fail(`sections[].z must be strictly ascending (sections[${i}].z=${s.z}).`);
|
|
5264
|
+
}
|
|
5265
|
+
}
|
|
5266
|
+
/** Endpoint-clamped Catmull-Rom through scalar samples. */
|
|
5267
|
+
function catmullRom(p0, p1, p2, p3, t) {
|
|
5268
|
+
const t2 = t * t;
|
|
5269
|
+
const t3 = t2 * t;
|
|
5270
|
+
return .5 * (2 * p1 + (p2 - p0) * t + (2 * p0 - 5 * p1 + 4 * p2 - p3) * t2 + (-p0 + 3 * p1 - 3 * p2 + p3) * t3);
|
|
5271
|
+
}
|
|
5272
|
+
/** Sample the section list into (K-1)*smooth+1 interpolated rings. */
|
|
5273
|
+
function sampleRings(sections, smooth) {
|
|
5274
|
+
const get = (i) => {
|
|
5275
|
+
const s = sections[Math.max(0, Math.min(sections.length - 1, i))];
|
|
5276
|
+
return {
|
|
5277
|
+
z: s.z,
|
|
5278
|
+
width: s.width,
|
|
5279
|
+
height: s.height,
|
|
5280
|
+
y: s.y,
|
|
5281
|
+
corner: s.corner ?? .7
|
|
5282
|
+
};
|
|
5283
|
+
};
|
|
5284
|
+
const rings = [];
|
|
5285
|
+
for (let i = 0; i < sections.length - 1; i++) {
|
|
5286
|
+
const a = get(i - 1);
|
|
5287
|
+
const b = get(i);
|
|
5288
|
+
const c = get(i + 1);
|
|
5289
|
+
const d = get(i + 2);
|
|
5290
|
+
const steps = i === sections.length - 2 ? smooth + 1 : smooth;
|
|
5291
|
+
for (let s = 0; s < steps; s++) {
|
|
5292
|
+
const t = s / smooth;
|
|
5293
|
+
rings.push({
|
|
5294
|
+
z: catmullRom(a.z, b.z, c.z, d.z, t),
|
|
5295
|
+
width: Math.max(1e-4, catmullRom(a.width, b.width, c.width, d.width, t)),
|
|
5296
|
+
height: Math.max(1e-4, catmullRom(a.height, b.height, c.height, d.height, t)),
|
|
5297
|
+
y: catmullRom(a.y, b.y, c.y, d.y, t),
|
|
5298
|
+
corner: Math.min(1, Math.max(0, catmullRom(a.corner, b.corner, c.corner, d.corner, t)))
|
|
5299
|
+
});
|
|
5300
|
+
}
|
|
5301
|
+
}
|
|
5302
|
+
return rings;
|
|
5303
|
+
}
|
|
5304
|
+
/**
|
|
5305
|
+
* Build the swept surface: ring grid + two cap-centre vertices, indexed
|
|
5306
|
+
* without a seam so `computeVertexNormals` shades the hull perfectly smooth.
|
|
5307
|
+
*/
|
|
5308
|
+
function buildLoftGeometry(sections, slices, smooth) {
|
|
5309
|
+
const S = Math.max(8, Math.min(64, Math.round(slices)));
|
|
5310
|
+
const rings = sampleRings(sections, Math.max(1, Math.min(16, Math.round(smooth))));
|
|
5311
|
+
const R = rings.length;
|
|
5312
|
+
const positions = new Float32Array((R * S + 2) * 3);
|
|
5313
|
+
const first = rings[0];
|
|
5314
|
+
const last = rings[R - 1];
|
|
5315
|
+
positions.set([
|
|
5316
|
+
0,
|
|
5317
|
+
first.y,
|
|
5318
|
+
first.z
|
|
5319
|
+
], 0);
|
|
5320
|
+
positions.set([
|
|
5321
|
+
0,
|
|
5322
|
+
last.y,
|
|
5323
|
+
last.z
|
|
5324
|
+
], 3);
|
|
5325
|
+
for (let i = 0; i < R; i++) {
|
|
5326
|
+
const ring = rings[i];
|
|
5327
|
+
const nTop = 8 - 6 * ring.corner;
|
|
5328
|
+
const nBottom = Math.max(nTop, 5);
|
|
5329
|
+
for (let j = 0; j < S; j++) {
|
|
5330
|
+
const theta = j / S * Math.PI * 2;
|
|
5331
|
+
const c = Math.cos(theta);
|
|
5332
|
+
const sn = Math.sin(theta);
|
|
5333
|
+
const n = sn >= 0 ? nTop : nBottom;
|
|
5334
|
+
const x = ring.width / 2 * Math.sign(c) * Math.abs(c) ** (2 / n);
|
|
5335
|
+
const yy = ring.height / 2 * Math.sign(sn) * Math.abs(sn) ** (2 / n);
|
|
5336
|
+
const v = (2 + i * S + j) * 3;
|
|
5337
|
+
positions[v] = x;
|
|
5338
|
+
positions[v + 1] = ring.y + yy;
|
|
5339
|
+
positions[v + 2] = ring.z;
|
|
5340
|
+
}
|
|
5341
|
+
}
|
|
5342
|
+
const indices = [];
|
|
5343
|
+
const at = (i, j) => 2 + i * S + j % S;
|
|
5344
|
+
for (let i = 0; i < R - 1; i++) for (let j = 0; j < S; j++) {
|
|
5345
|
+
const a = at(i, j);
|
|
5346
|
+
const b = at(i, j + 1);
|
|
5347
|
+
const c = at(i + 1, j);
|
|
5348
|
+
const d = at(i + 1, j + 1);
|
|
5349
|
+
indices.push(a, b, c, b, d, c);
|
|
5350
|
+
}
|
|
5351
|
+
for (let j = 0; j < S; j++) {
|
|
5352
|
+
indices.push(0, at(0, j + 1), at(0, j));
|
|
5353
|
+
indices.push(1, at(R - 1, j), at(R - 1, j + 1));
|
|
5354
|
+
}
|
|
5355
|
+
const geo = new BufferGeometry();
|
|
5356
|
+
geo.setAttribute("position", new BufferAttribute(positions, 3));
|
|
5357
|
+
geo.setIndex(indices);
|
|
5358
|
+
geo.computeVertexNormals();
|
|
5359
|
+
return geo;
|
|
5360
|
+
}
|
|
5361
|
+
//#endregion
|
|
5073
5362
|
//#region src/3d/animation/rigmap.ts
|
|
5074
5363
|
/**
|
|
5075
5364
|
* Mixamo rig name → VRM humanoid bone name (the vibe-starter-3d /
|
|
@@ -5226,7 +5515,9 @@ var ModelInstance3D = class extends Node3D {
|
|
|
5226
5515
|
castShadow: { default: false },
|
|
5227
5516
|
animationLoop: { default: true },
|
|
5228
5517
|
receiveShadow: { default: false },
|
|
5229
|
-
tint: { default: "" }
|
|
5518
|
+
tint: { default: "" },
|
|
5519
|
+
metalness: { default: -1 },
|
|
5520
|
+
roughness: { default: -1 }
|
|
5230
5521
|
};
|
|
5231
5522
|
model = "";
|
|
5232
5523
|
animation = "";
|
|
@@ -5238,6 +5529,12 @@ var ModelInstance3D = class extends Node3D {
|
|
|
5238
5529
|
/** Hex colour multiplied into every material — RESKIN one shared GLB into many
|
|
5239
5530
|
* variants (e.g. a sickly-green zombie from the base human). '' = untinted. */
|
|
5240
5531
|
tint = "";
|
|
5532
|
+
/** Override every material's metalness (0..1); -1 keeps the authored value.
|
|
5533
|
+
* Low-poly kits often ship fully rough — 0.5–0.8 turns flat paint into a
|
|
5534
|
+
* glinting clear-coat under the scene's IBL. Cloned per instance like tint. */
|
|
5535
|
+
metalness = -1;
|
|
5536
|
+
/** Override every material's roughness (0..1); -1 keeps the authored value. */
|
|
5537
|
+
roughness = -1;
|
|
5241
5538
|
store = null;
|
|
5242
5539
|
entry = null;
|
|
5243
5540
|
mountedRef = "";
|
|
@@ -5251,11 +5548,25 @@ var ModelInstance3D = class extends Node3D {
|
|
|
5251
5548
|
* frames after `this.animation` already moved on). */
|
|
5252
5549
|
actionKeys = /* @__PURE__ */ new WeakMap();
|
|
5253
5550
|
warnedClaim = false;
|
|
5254
|
-
/** Per-mesh original (shared) materials, captured at mount so
|
|
5255
|
-
* re-derive from the source. Our clones are tracked for disposal. */
|
|
5551
|
+
/** Per-mesh original (shared) materials, captured at mount so tint/overrides
|
|
5552
|
+
* can always re-derive from the source. Our clones are tracked for disposal. */
|
|
5256
5553
|
tintTargets = [];
|
|
5257
5554
|
tintedClones = [];
|
|
5258
|
-
|
|
5555
|
+
appliedMods = "";
|
|
5556
|
+
/** Named sub-node poses (degrees), re-applied every sync — drive wheels,
|
|
5557
|
+
* turrets, doors from behaviors without touching three directly. */
|
|
5558
|
+
nodePoses = /* @__PURE__ */ new Map();
|
|
5559
|
+
/**
|
|
5560
|
+
* Rotate a named sub-node of the loaded model (local Euler XYZ, degrees) —
|
|
5561
|
+
* e.g. spin a GLB car's `wheel-front-left` every frame, aim a turret, swing a
|
|
5562
|
+
* door. Poses persist and re-apply on every sync (safe to set before the
|
|
5563
|
+
* model finishes loading). Unknown names are ignored. `npx incanto-model
|
|
5564
|
+
* <file>` lists a model's node names.
|
|
5565
|
+
*/
|
|
5566
|
+
poseNode(name, rotation) {
|
|
5567
|
+
this.nodePoses.set(name, rotation);
|
|
5568
|
+
this.applyPoses();
|
|
5569
|
+
}
|
|
5259
5570
|
_createObject3D() {
|
|
5260
5571
|
return new Group();
|
|
5261
5572
|
}
|
|
@@ -5309,7 +5620,7 @@ var ModelInstance3D = class extends Node3D {
|
|
|
5309
5620
|
});
|
|
5310
5621
|
this.tintTargets = [];
|
|
5311
5622
|
this.tintedClones = [];
|
|
5312
|
-
this.
|
|
5623
|
+
this.appliedMods = "";
|
|
5313
5624
|
instance.traverse((obj) => {
|
|
5314
5625
|
const mesh = obj;
|
|
5315
5626
|
if (mesh.isMesh && mesh.material) this.tintTargets.push({
|
|
@@ -5338,34 +5649,51 @@ var ModelInstance3D = class extends Node3D {
|
|
|
5338
5649
|
mesh.receiveShadow = this.receiveShadow;
|
|
5339
5650
|
}
|
|
5340
5651
|
});
|
|
5341
|
-
this.
|
|
5652
|
+
this.applyMaterialMods();
|
|
5653
|
+
this.applyPoses();
|
|
5342
5654
|
this.syncAnimation(assets);
|
|
5343
5655
|
}
|
|
5344
|
-
/**
|
|
5345
|
-
*
|
|
5346
|
-
* mutates the shared source), disposing prior clones on change. */
|
|
5347
|
-
|
|
5348
|
-
|
|
5656
|
+
/** Apply per-instance material mods — `tint` (multiplied into colour) and the
|
|
5657
|
+
* `metalness`/`roughness` overrides — by cloning the captured originals
|
|
5658
|
+
* (never mutates the shared source), disposing prior clones on change. */
|
|
5659
|
+
applyMaterialMods() {
|
|
5660
|
+
const key = `${this.tint}|${this.metalness}|${this.roughness}`;
|
|
5661
|
+
if (key === this.appliedMods) return;
|
|
5349
5662
|
for (const c of this.tintedClones) c.dispose();
|
|
5350
5663
|
this.tintedClones = [];
|
|
5351
5664
|
const tint = this.tint ? new Color(this.tint) : null;
|
|
5665
|
+
const hasMods = tint !== null || this.metalness >= 0 || this.roughness >= 0;
|
|
5352
5666
|
for (const t of this.tintTargets) {
|
|
5353
|
-
if (!
|
|
5667
|
+
if (!hasMods) {
|
|
5354
5668
|
t.mesh.material = t.original;
|
|
5355
5669
|
continue;
|
|
5356
5670
|
}
|
|
5357
|
-
const
|
|
5671
|
+
const modOne = (src) => {
|
|
5358
5672
|
const clone = src.clone();
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5673
|
+
if (tint) {
|
|
5674
|
+
const cm = clone;
|
|
5675
|
+
const sc = src.color;
|
|
5676
|
+
if (cm.color) cm.color = sc ? sc.clone().multiply(tint) : tint.clone();
|
|
5677
|
+
}
|
|
5678
|
+
const pbr = clone;
|
|
5679
|
+
if (this.metalness >= 0 && typeof pbr.metalness === "number") pbr.metalness = this.metalness;
|
|
5680
|
+
if (this.roughness >= 0 && typeof pbr.roughness === "number") pbr.roughness = this.roughness;
|
|
5362
5681
|
clone.userData.incantoTinted = true;
|
|
5363
5682
|
this.tintedClones.push(clone);
|
|
5364
5683
|
return clone;
|
|
5365
5684
|
};
|
|
5366
|
-
t.mesh.material = Array.isArray(t.original) ? t.original.map(
|
|
5685
|
+
t.mesh.material = Array.isArray(t.original) ? t.original.map(modOne) : modOne(t.original);
|
|
5686
|
+
}
|
|
5687
|
+
this.appliedMods = key;
|
|
5688
|
+
}
|
|
5689
|
+
/** Re-apply every queued named-node pose onto the mounted instance. */
|
|
5690
|
+
applyPoses() {
|
|
5691
|
+
if (!this.fitGroup || this.nodePoses.size === 0) return;
|
|
5692
|
+
const DEG = Math.PI / 180;
|
|
5693
|
+
for (const [name, rot] of this.nodePoses) {
|
|
5694
|
+
const obj = this.fitGroup.getObjectByName(name);
|
|
5695
|
+
if (obj) obj.rotation.set(rot[0] * DEG, rot[1] * DEG, rot[2] * DEG);
|
|
5367
5696
|
}
|
|
5368
|
-
this.appliedTint = this.tint;
|
|
5369
5697
|
}
|
|
5370
5698
|
syncAnimation(assets) {
|
|
5371
5699
|
if (!this.mixer || !this.entry || this.playing === this.animation) return;
|
|
@@ -5425,7 +5753,7 @@ var ModelInstance3D = class extends Node3D {
|
|
|
5425
5753
|
for (const c of this.tintedClones) c.dispose();
|
|
5426
5754
|
this.tintedClones = [];
|
|
5427
5755
|
this.tintTargets = [];
|
|
5428
|
-
this.
|
|
5756
|
+
this.appliedMods = "";
|
|
5429
5757
|
this.fitGroup = null;
|
|
5430
5758
|
this.mixer = null;
|
|
5431
5759
|
this.currentAction = null;
|
|
@@ -5572,7 +5900,7 @@ var Particles3D = class Particles3D extends Node3D {
|
|
|
5572
5900
|
gravity: [
|
|
5573
5901
|
(this.gravity[0] ?? 0) * PX_TO_M,
|
|
5574
5902
|
(this.gravity[1] ?? 0) * PX_TO_M,
|
|
5575
|
-
0
|
|
5903
|
+
(this.gravity[2] ?? 0) * PX_TO_M
|
|
5576
5904
|
],
|
|
5577
5905
|
drag: this.drag,
|
|
5578
5906
|
maxParticles: this.maxParticles,
|
|
@@ -5583,6 +5911,7 @@ var Particles3D = class Particles3D extends Node3D {
|
|
|
5583
5911
|
}
|
|
5584
5912
|
update(dt) {
|
|
5585
5913
|
const sim = this._ensureSim();
|
|
5914
|
+
sim.setRate(this.emitting ? this.rate : 0);
|
|
5586
5915
|
if (this.burst > 0 && !this.bursted) {
|
|
5587
5916
|
this.bursted = true;
|
|
5588
5917
|
sim.burst(this.burst);
|
|
@@ -11094,11 +11423,13 @@ function registerNodes3D() {
|
|
|
11094
11423
|
registerNode(Node3D);
|
|
11095
11424
|
registerNode(Particles3D);
|
|
11096
11425
|
registerNode(MeshInstance3D);
|
|
11426
|
+
registerNode(LoftMesh3D);
|
|
11097
11427
|
registerNode(Sprite3D);
|
|
11098
11428
|
registerNode(AnimatedSprite3D);
|
|
11099
11429
|
registerNode(Billboard3D);
|
|
11100
11430
|
registerNode(CharacterController3D);
|
|
11101
11431
|
registerNode(VoxelGrid3D);
|
|
11432
|
+
registerNode(Joint3D);
|
|
11102
11433
|
registerNode(Terrain3D);
|
|
11103
11434
|
registerNode(Water3D);
|
|
11104
11435
|
registerNode(Foliage3D);
|
|
@@ -11114,4 +11445,4 @@ function registerNodes3D() {
|
|
|
11114
11445
|
registerNode(CharacterBody3D);
|
|
11115
11446
|
}
|
|
11116
11447
|
//#endregion
|
|
11117
|
-
export {
|
|
11448
|
+
export { StaticBody3D as A, TERRAIN_THEMES as C, CharacterBody3D as D, Area3D as E, keyboardIntensity as F, movementState as I, rigPose as L, validateCollider3D as M, QUARTER_PITCH as N, PhysicsBody3D as O, cameraRelative as P, DEFAULT_TERRAIN_TEXTURE_BASE as S, Joint3D as T, FLOWER_VARIETIES as _, VoxelGrid3D as a, Billboard3D as b, ModelInstance3D as c, DirectionalLight3D as d, OmniLight3D as f, resolveFlowerDensity as g, Flowers3D as h, VOXEL_PALETTE as i, Node3D as j, RigidBody3D as k, LoftMesh3D as l, DENSITY_PRESETS as m, Water3D as n, Tree3D as o, Foliage3D as p, WATER_MAX_RIPPLES as r, Particles3D as s, registerNodes3D as t, MeshInstance3D as u, CharacterController3D as v, terrainThemeLayers as w, Terrain3D as x, Camera3D as y };
|
package/dist/test.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { c as JsonValue, i as SceneJson } from "./schema-CcoWb32N.js";
|
|
2
|
-
import { O as LogEntry, T as Node, n as BehaviorCtor, v as Engine, w as Scene } from "./behavior-
|
|
3
|
-
import { t as LoadSceneOptions } from "./loader-
|
|
2
|
+
import { O as LogEntry, T as Node, n as BehaviorCtor, v as Engine, w as Scene } from "./behavior-CWhW3oa6.js";
|
|
3
|
+
import { t as LoadSceneOptions } from "./loader-D2u0fVW2.js";
|
|
4
4
|
import { t as IncantoError } from "./errors-BMFaY68Q.js";
|
|
5
5
|
|
|
6
6
|
//#region src/test/index.d.ts
|