@woosh/meep-engine 2.167.0 → 2.168.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.
package/package.json CHANGED
@@ -1,95 +1,95 @@
1
- {
2
- "name": "@woosh/meep-engine",
3
- "license": "UNLICENSED",
4
- "productName": "Meep",
5
- "homepage": "https://meep.company-named.com/",
6
- "description": "Pure JavaScript game engine. Fully featured and production ready.",
7
- "type": "module",
8
- "author": "Alexander Goldring",
9
- "version": "2.167.0",
10
- "main": "build/meep.module.js",
11
- "module": "build/meep.module.js",
12
- "exports": {
13
- "./build/*": "./build/*",
14
- "./src/*": "./src/*",
15
- "./editor/*": "./editor/*",
16
- "./*.md": "./*"
17
- },
18
- "scripts": {
19
- "test:ci": "jest --config ./jest.conf.json --collectCoverage --coverageDirectory=\"./coverage\" --ci --reporters=default --reporters=jest-junit --watchAll=false",
20
- "build-module": "rollup -c rollup.config.js",
21
- "publish-npm": "npm publish",
22
- "generate-types": "npx -p typescript tsc --project tsconfig.types.json || exit 0;"
23
- },
24
- "browserslist": [
25
- "last 2 chrome version",
26
- "last 2 firefox version",
27
- "last 2 safari version"
28
- ],
29
- "files": [
30
- "build",
31
- "src",
32
- "editor",
33
- "samples",
34
- "package.json",
35
- "README.md",
36
- "!src/**/*.spec.js",
37
- "!editor/**/*.spec.js"
38
- ],
39
- "dependencies": {
40
- "gl-matrix": "3.4.3",
41
- "opentype.js": "1.3.3",
42
- "pako": "2.0.3",
43
- "robust-predicates": "3.0.2"
44
- },
45
- "peerDependencies": {
46
- "three": ">=0.135.0"
47
- },
48
- "peerDependenciesMeta": {
49
- "three": {
50
- "optional": true
51
- }
52
- },
53
- "devDependencies": {
54
- "@babel/core": "7.22.15",
55
- "@babel/preset-env": "7.22.15",
56
- "@rollup/plugin-commonjs": "25.0.2",
57
- "@rollup/plugin-node-resolve": "15.1.0",
58
- "@rollup/plugin-strip": "3.0.2",
59
- "@rollup/plugin-terser": "0.4.3",
60
- "@types/jest": "29.5.12",
61
- "@types/three": "^0.135.0",
62
- "babel-jest": "29.7.0",
63
- "jest": "29.7.0",
64
- "jest-environment-jsdom": "29.7.0",
65
- "jest-junit": "16.0.0",
66
- "rollup": "3.26.2",
67
- "typescript": "5.2.2"
68
- },
69
- "keywords": [
70
- "game-engine",
71
- "gamedev",
72
- "ecs",
73
- "entity-component-system",
74
- "data-oriented",
75
- "zero-allocation",
76
- "modular",
77
- "tree-shaking",
78
- "3d",
79
- "webgl",
80
- "webgl2",
81
- "webgpu",
82
- "webaudio",
83
- "particles",
84
- "bvh",
85
- "behavior-tree",
86
- "inverse-kinematics",
87
- "fabrik",
88
- "clustered-lighting",
89
- "color-management",
90
- "typescript"
91
- ],
92
- "engines": {
93
- "node": ">=24"
94
- }
95
- }
1
+ {
2
+ "name": "@woosh/meep-engine",
3
+ "license": "UNLICENSED",
4
+ "productName": "Meep",
5
+ "homepage": "https://meep.company-named.com/",
6
+ "description": "Pure JavaScript game engine. Fully featured and production ready.",
7
+ "type": "module",
8
+ "author": "Alexander Goldring",
9
+ "version": "2.168.1",
10
+ "main": "build/meep.module.js",
11
+ "module": "build/meep.module.js",
12
+ "exports": {
13
+ "./build/*": "./build/*",
14
+ "./src/*": "./src/*",
15
+ "./editor/*": "./editor/*",
16
+ "./*.md": "./*"
17
+ },
18
+ "scripts": {
19
+ "test:ci": "jest --config ./jest.conf.json --collectCoverage --coverageDirectory=\"./coverage\" --ci --reporters=default --reporters=jest-junit --watchAll=false",
20
+ "build-module": "rollup -c rollup.config.js",
21
+ "publish-npm": "npm publish",
22
+ "generate-types": "npx -p typescript tsc --project tsconfig.types.json || exit 0;"
23
+ },
24
+ "browserslist": [
25
+ "last 2 chrome version",
26
+ "last 2 firefox version",
27
+ "last 2 safari version"
28
+ ],
29
+ "files": [
30
+ "build",
31
+ "src",
32
+ "editor",
33
+ "samples",
34
+ "package.json",
35
+ "README.md",
36
+ "!src/**/*.spec.js",
37
+ "!editor/**/*.spec.js"
38
+ ],
39
+ "dependencies": {
40
+ "gl-matrix": "3.4.3",
41
+ "opentype.js": "1.3.3",
42
+ "pako": "2.0.3",
43
+ "robust-predicates": "3.0.2"
44
+ },
45
+ "peerDependencies": {
46
+ "three": ">=0.135.0"
47
+ },
48
+ "peerDependenciesMeta": {
49
+ "three": {
50
+ "optional": true
51
+ }
52
+ },
53
+ "devDependencies": {
54
+ "@babel/core": "7.22.15",
55
+ "@babel/preset-env": "7.22.15",
56
+ "@rollup/plugin-commonjs": "25.0.2",
57
+ "@rollup/plugin-node-resolve": "15.1.0",
58
+ "@rollup/plugin-strip": "3.0.2",
59
+ "@rollup/plugin-terser": "0.4.3",
60
+ "@types/jest": "29.5.12",
61
+ "@types/three": "^0.135.0",
62
+ "babel-jest": "29.7.0",
63
+ "jest": "29.7.0",
64
+ "jest-environment-jsdom": "29.7.0",
65
+ "jest-junit": "16.0.0",
66
+ "rollup": "3.26.2",
67
+ "typescript": "5.2.2"
68
+ },
69
+ "keywords": [
70
+ "game-engine",
71
+ "gamedev",
72
+ "ecs",
73
+ "entity-component-system",
74
+ "data-oriented",
75
+ "zero-allocation",
76
+ "modular",
77
+ "tree-shaking",
78
+ "3d",
79
+ "webgl",
80
+ "webgl2",
81
+ "webgpu",
82
+ "webaudio",
83
+ "particles",
84
+ "bvh",
85
+ "behavior-tree",
86
+ "inverse-kinematics",
87
+ "fabrik",
88
+ "clustered-lighting",
89
+ "color-management",
90
+ "typescript"
91
+ ],
92
+ "engines": {
93
+ "node": ">=24"
94
+ }
95
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"EngineHarness.d.ts","sourceRoot":"","sources":["../../../src/engine/EngineHarness.js"],"names":[],"mappings":"AA6DA;IAmBI;;;;OAIG;IACH,8CAHmB,mBAAmB,UAAQ,MAAM,WACxC,QAAQ,MAAM,CAAC,CAM1B;IAED;;;OAGG;IACH,6BAFW,MAAM,QAYhB;IAkED;;;;;;;;;;;;;OAaG;IACH;QAZyB,MAAM,EAApB,MAAM;QACyB,GAAG;QAClB,MAAM,GAAtB,OAAO;QACQ,QAAQ,GAAvB,MAAM;QACS,KAAK,GAApB,MAAM;QACS,GAAG,GAAlB,MAAM;QACU,QAAQ,GAAxB,OAAO;QACQ,WAAW,GAA1B,MAAM;QACS,WAAW,GAA1B,MAAM;QACS,WAAW,GAA1B,MAAM;QACJ,MAAM,CA+DlB;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH;QApB0B,MAAM,EAArB,MAAM;QACgC,KAAK,GAA3C;YAAC,CAAC,EAAC,MAAM,CAAC;YAAA,CAAC,EAAC,MAAM,CAAC;YAAA,CAAC,EAAC,MAAM,CAAA;SAAC;QACrB,SAAS;QACT,WAAW;QACF,KAAK,GAArB,MAAM;QACU,GAAG,GAAnB,MAAM;QACU,QAAQ,GAAxB,MAAM;QACwB,WAAW,GAAzC;YAAC,CAAC,EAAC,MAAM,CAAC;YAAC,CAAC,EAAC,MAAM,CAAA;SAAC;QACJ,iBAAiB,GAAjC,MAAM;QACW,WAAW,GAA5B,OAAO;QACU,aAAa,GAA9B,OAAO;QACU,YAAY,GAA7B,OAAO;QACU,aAAa,GAA9B,OAAO;QACS,iBAAiB,GAAjC,MAAM;QACU,iBAAiB,GAAjC,MAAM;QACW,gBAAgB,GAAjC,OAAO;QACU,cAAc,GAA/B,OAAO;QACS,mBAAmB,GAAnC,MAAM;QACW,OAAO,GAAxB,OAAO;sBA0EjB;IAGD;;;;;;;;;;;;OAYG;IACH;QAXyB,MAAM,EAApB,MAAM;QACyB,GAAG;QACnB,mBAAmB,GAAlC,MAAM;QACU,UAAU,GAA1B,OAAO;QACO,GAAG,GAAjB,KAAK;QACU,YAAY,GAA3B,MAAM;QACU,YAAY,GAA5B,OAAO;QACO,OAAO,GAArB,KAAK;QACU,gBAAgB,GAA/B,MAAM;QACS,iBAAiB,GAAhC,MAAM;sBAuDhB;IAED;;;;;;;OAOG;IACH;QAN0B,YAAY,GAA3B,MAAM;QACQ,MAAM,EAApB,MAAM;QACS,WAAW,GAA1B,MAAM;QACyB,GAAG;QAChC,QAAQ,MAAM,CAAC,CA2C3B;IAGD;;;;;;;;;;OAUG;IACH,sFATW,MAAM,GAOJ,OAAO,CAsDnB;IAjdG;;;OAGG;IACH,QAFU,MAAM,CAEiC;IAMjD;;;OAGG;IACH,YAFU,eAAQ,IAAI,CAET;IA8BjB;;;;;OAKG;IACH;iCAJmB,mBAAmB,UAAQ,MAAM;8BACzC,OAAO;QACL,QAAQ,MAAM,CAAC,CA0D3B;CAwWJ;;IAID;;;OAGG;IACH,uCAMC;;mBAhhBkB,aAAa;oCACI,0BAA0B;oBAX1C,yBAAyB;mBAK1B,iBAAiB;sBATd,wBAAwB;oBAW1B,8BAA8B"}
1
+ {"version":3,"file":"EngineHarness.d.ts","sourceRoot":"","sources":["../../../src/engine/EngineHarness.js"],"names":[],"mappings":"AA8DA;IAmBI;;;;OAIG;IACH,8CAHmB,mBAAmB,UAAQ,MAAM,WACxC,QAAQ,MAAM,CAAC,CAM1B;IAED;;;OAGG;IACH,6BAFW,MAAM,QAYhB;IAkED;;;;;;;;;;;;;OAaG;IACH;QAZyB,MAAM,EAApB,MAAM;QACyB,GAAG;QAClB,MAAM,GAAtB,OAAO;QACQ,QAAQ,GAAvB,MAAM;QACS,KAAK,GAApB,MAAM;QACS,GAAG,GAAlB,MAAM;QACU,QAAQ,GAAxB,OAAO;QACQ,WAAW,GAA1B,MAAM;QACS,WAAW,GAA1B,MAAM;QACS,WAAW,GAA1B,MAAM;QACJ,MAAM,CA+DlB;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH;QApB0B,MAAM,EAArB,MAAM;QACgC,KAAK,GAA3C;YAAC,CAAC,EAAC,MAAM,CAAC;YAAA,CAAC,EAAC,MAAM,CAAC;YAAA,CAAC,EAAC,MAAM,CAAA;SAAC;QACrB,SAAS;QACT,WAAW;QACF,KAAK,GAArB,MAAM;QACU,GAAG,GAAnB,MAAM;QACU,QAAQ,GAAxB,MAAM;QACwB,WAAW,GAAzC;YAAC,CAAC,EAAC,MAAM,CAAC;YAAC,CAAC,EAAC,MAAM,CAAA;SAAC;QACJ,iBAAiB,GAAjC,MAAM;QACW,WAAW,GAA5B,OAAO;QACU,aAAa,GAA9B,OAAO;QACU,YAAY,GAA7B,OAAO;QACU,aAAa,GAA9B,OAAO;QACS,iBAAiB,GAAjC,MAAM;QACU,iBAAiB,GAAjC,MAAM;QACW,gBAAgB,GAAjC,OAAO;QACU,cAAc,GAA/B,OAAO;QACS,mBAAmB,GAAnC,MAAM;QACW,OAAO,GAAxB,OAAO;sBA0EjB;IAGD;;;;;;;;;;;;OAYG;IACH;QAXyB,MAAM,EAApB,MAAM;QACyB,GAAG;QACnB,mBAAmB,GAAlC,MAAM;QACU,UAAU,GAA1B,OAAO;QACO,GAAG,GAAjB,KAAK;QACU,YAAY,GAA3B,MAAM;QACU,YAAY,GAA5B,OAAO;QACO,OAAO,GAArB,KAAK;QACU,gBAAgB,GAA/B,MAAM;QACS,iBAAiB,GAAhC,MAAM;sBAuDhB;IAED;;;;;;;OAOG;IACH;QAN0B,YAAY,GAA3B,MAAM;QACQ,MAAM,EAApB,MAAM;QACS,WAAW,GAA1B,MAAM;QACyB,GAAG;QAChC,QAAQ,MAAM,CAAC,CA6C3B;IAGD;;;;;;;;;;OAUG;IACH,sFATW,MAAM,GAOJ,OAAO,CAsDnB;IAndG;;;OAGG;IACH,QAFU,MAAM,CAEiC;IAMjD;;;OAGG;IACH,YAFU,eAAQ,IAAI,CAET;IA8BjB;;;;;OAKG;IACH;iCAJmB,mBAAmB,UAAQ,MAAM;8BACzC,OAAO;QACL,QAAQ,MAAM,CAAC,CA0D3B;CA0WJ;;IAID;;;OAGG;IACH,uCAMC;;mBAlhBkB,aAAa;oCACI,0BAA0B;oBAX1C,yBAAyB;mBAK1B,iBAAiB;sBATd,wBAAwB;oBAW1B,8BAA8B"}
@@ -1,4 +1,5 @@
1
1
  import Stats from "three/examples/jsm/libs/stats.module.js";
2
+ import { assert } from "../core/assert.js";
2
3
  import { Color } from "../core/color/Color.js";
3
4
 
4
5
  import { noop } from "../core/function/noop.js";
@@ -327,7 +328,7 @@ export class EngineHarness {
327
328
  }
328
329
 
329
330
  if (cameraController) {
330
- EngineHarness.buildOrbitalCameraController({
331
+ await EngineHarness.buildOrbitalCameraController({
331
332
  engine,
332
333
  cameraEntity: cameraEntity
333
334
  });
@@ -430,6 +431,8 @@ export class EngineHarness {
430
431
  cameraEntity = ecd.getAnyComponent(Camera).entity;
431
432
  }
432
433
 
434
+ assert.defined(cameraEntity, "cameraEntity");
435
+
433
436
  const em = engine.entityManager;
434
437
 
435
438
  if (em.getSystem(InputControllerSystem) === null) {
@@ -24,7 +24,8 @@ export const FogOfWarEdgeMode = {
24
24
 
25
25
  /**
26
26
  * The fog EXTENDS outward instead: the border ring mirrors the cells just
27
- * inside it, and pixels with no geometry are left alone entirely.
27
+ * inside it, and a pixel with no geometry is located by projecting its camera
28
+ * ray onto the fog's own ground plane rather than read off the far plane.
28
29
  *
29
30
  * For a world with a VISIBLE boundary — a finite arena the camera can see
30
31
  * past. Under {@link FogOfWarEdgeMode.Conceal} such a scene gets a hard black
@@ -1 +1 @@
1
- {"version":3,"file":"screenSpaceFogOfWarShader.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/ecs/fow/shader/screenSpaceFogOfWarShader.js"],"names":[],"mappings":"AAGA;;;GAGG;AACH,kDAFW,cAAc,CA4LxB;+BAjMyE,OAAO"}
1
+ {"version":3,"file":"screenSpaceFogOfWarShader.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/ecs/fow/shader/screenSpaceFogOfWarShader.js"],"names":[],"mappings":"AAGA;;;GAGG;AACH,kDAFW,cAAc,CAmNxB;+BAxNyE,OAAO"}
@@ -108,25 +108,48 @@ export function buildScreenSpaceFogOfWarShader() {
108
108
  void main(){
109
109
  float sceneDepth = texture2D( tDepth, vUv ).x;
110
110
 
111
- // NOTHING WAS DRAWN HERE. The depth is the buffer's clear value, so
112
- // the position reconstructed from it lands on the far plane: a point
113
- // with no relationship to the scene, whose fog lookup is whatever the
114
- // sampler's clamp happens to return. In a world with a visible
115
- // boundary that is the concealed border ring, and it gets painted
116
- // across the entire void as a hard rectangle on the world's edge.
117
- // Under Extend, leave such a pixel alone rather than fog it on the
118
- // strength of a reconstruction that means nothing.
119
- //
120
- // Under Conceal this branch never taken, so the legacy path is
121
- // bit-identical — including the one case Extend gives up, a real
122
- // surface sitting exactly on the far plane.
111
+ vec3 worldPosition;
112
+
123
113
  if (uEdgeExtend > 0.5 && sceneDepth >= 1.0) {
124
- gl_FragColor = vec4(0.0);
125
- return;
126
- }
114
+ // NOTHING WAS DRAWN HERE, so there is no surface to locate: the
115
+ // depth is the buffer's clear value and computeWorldPosition would
116
+ // hand back a point on the far plane, unrelated to the scene, whose
117
+ // fog lookup is whatever the sampler's clamp happens to return.
118
+ //
119
+ // The fog is a GROUND field though — its sampler is indexed by
120
+ // world XZ and anchored at the world origin (uFogUvTransform is
121
+ // built from size and scale alone, with no Y term), so the
122
+ // meaningful position for such a pixel is where its camera ray
123
+ // crosses that field's own plane, y = 0.
124
+ //
125
+ // PROJECTING rather than skipping is what keeps a world boundary
126
+ // invisible. At the last pixel of ground the surface hit and the
127
+ // plane hit are the same point, so the fog value carries straight
128
+ // on across the edge; skipping instead steps it from whatever the
129
+ // edge reads to nothing at all, and that step is a visible line
130
+ // exactly where the world stops.
131
+ vec3 camPos = uViewInverse[3].xyz;
132
+ vec3 dir = computeWorldPosition(1.0) - camPos;
133
+
134
+ // parallel to the plane, or pointing away from it: nothing to
135
+ // sample, so leave the pixel alone
136
+ if (abs(dir.y) < 1e-6) {
137
+ gl_FragColor = vec4(0.0);
138
+ return;
139
+ }
140
+
141
+ float t = -camPos.y / dir.y;
127
142
 
128
- //get world fragment position
129
- vec3 worldPosition = computeWorldPosition(sceneDepth);
143
+ if (t <= 0.0) {
144
+ gl_FragColor = vec4(0.0);
145
+ return;
146
+ }
147
+
148
+ worldPosition = camPos + dir * t;
149
+ } else {
150
+ //get world fragment position
151
+ worldPosition = computeWorldPosition(sceneDepth);
152
+ }
130
153
 
131
154
  vec2 fogUv = worldPosition.xz * uFogUvTransform.zw + uFogUvTransform.xy;
132
155
 
@@ -60,6 +60,11 @@ declare class Trail2D {
60
60
  * @type {RibbonX|null}
61
61
  */
62
62
  ribbon: RibbonX | null;
63
+ /**
64
+ * transient
65
+ * @type {Mesh|null}
66
+ */
67
+ mesh: Mesh | null;
63
68
  /**
64
69
  * transient
65
70
  * @type {RibbonXMaterialSpec}
@@ -107,7 +112,6 @@ declare class Trail2D {
107
112
  * @param {number} segment_count
108
113
  */
109
114
  build(segment_count: number): void;
110
- mesh: import("three").Mesh<import("three").BufferGeometry, import("three").Material | import("three").Material[]>;
111
115
  /**
112
116
  * Clear the trail's geometry and reset its state.
113
117
  */
@@ -1 +1 @@
1
- {"version":3,"file":"Trail2D.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/ecs/trail2d/Trail2D.js"],"names":[],"mappings":";AAwBA;IAkMI,oCAMC;IAtMD;;;OAGG;IACH,QAFU,MAAM,CAES;IAEzB;;;OAGG;IACH,OAFU,MAAM,CAEM;IAEtB;;;OAGG;IACH,WAFU,cAAc,GAAC,MAAM,CAEC;IAEhC;;;;OAIG;IACH,eAFU,MAAM,CAEuB;IAEvC;;;OAGG;IACH,MAFU,MAAM,CAEP;IAET;;;OAGG;IACH,eAFU,MAAM,CAEE;IAElB;;;OAGG;IACH,qBAFU,MAAM,CAEQ;IAExB;;;OAGG;IACH,yBAFU,MAAM,CAEY;IAE5B;;;;;OAKG;IACH,gBAFU,KAAK,CAEe;IAE9B;;;;OAIG;IACH,iBAFU,OAAO,CAEM;IAEvB;;;OAGG;IACH,QAFU,OAAO,GAAC,IAAI,CAER;IAEd;;;OAGG;IACH,UAFU,mBAAmB,CAEQ;IAErC;;;OAGG;IACH,cAFU,SAAS,CAEG;IAEtB;;;OAGG;IACH,cAAsB;IAEtB,gBAQC;IAMD,4BAEC;IAND,yBAEC;IAMD;;;;OAIG;IACH,cAHW,MAAM,GAAC,YAAY,GACjB,IAAI,CAIhB;IAED;;;;OAIG;IACH,gBAHW,MAAM,GAAC,YAAY,GACjB,IAAI,CAIhB;IAED;;;;OAIG;IACH,gBAHW,MAAM,GAAC,YAAY,SACnB,OAAO,QAQjB;IAED;;;;OAIG;IACH,cAHW,MAAM,GAAC,YAAY,GACjB,OAAO,CAInB;IAED;;;OAGG;IACH,qBAFW,MAAM,QAehB;IADG,kHAAgB;IAGpB;;OAEG;IACH,cAsBC;IAUD;;;;;;;;;;;;;aAkBC;IAGD;;;;;;;;;;;;;;;;;MAUC;IAED;;;OAGG;IACH,cAFW,OAAO,WAWjB;IAED;;;;;;;OAOG;IACH,cANW,MAAM,KACN,MAAM,KACN,MAAM,YACN,MAAM,GACJ,OAAO,CAmEnB;CAEJ;;;;;;+BAtV8B,+BAA+B;sBALxC,iCAAiC;oBACnC,kCAAkC;wBAM9B,0BAA0B;oCACd,sCAAsC;0BAThD,yCAAyC;6BAWtC,mBAAmB;kCADd,wBAAwB"}
1
+ {"version":3,"file":"Trail2D.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/ecs/trail2d/Trail2D.js"],"names":[],"mappings":";AAwBA;IAiNI,oCAMC;IArND;;;OAGG;IACH,QAFU,MAAM,CAES;IAEzB;;;OAGG;IACH,OAFU,MAAM,CAEM;IAEtB;;;OAGG;IACH,WAFU,cAAc,GAAC,MAAM,CAEC;IAEhC;;;;OAIG;IACH,eAFU,MAAM,CAEuB;IAEvC;;;OAGG;IACH,MAFU,MAAM,CAEP;IAET;;;OAGG;IACH,eAFU,MAAM,CAEE;IAElB;;;OAGG;IACH,qBAFU,MAAM,CAEQ;IAExB;;;OAGG;IACH,yBAFU,MAAM,CAEY;IAE5B;;;;;OAKG;IACH,gBAFU,KAAK,CAEe;IAE9B;;;;OAIG;IACH,iBAFU,OAAO,CAEM;IAEvB;;;OAGG;IACH,QAFU,OAAO,GAAC,IAAI,CAER;IAEd;;;OAGG;IACH,MAFU,OAAK,IAAI,CAEP;IAEZ;;;OAGG;IACH,UAFU,mBAAmB,CAEQ;IAErC;;;OAGG;IACH,cAFU,SAAS,CAEG;IAEtB;;;OAGG;IACH,cAAsB;IAEtB,gBAiBC;IAMD,4BAEC;IAND,yBAEC;IAMD;;;;OAIG;IACH,cAHW,MAAM,GAAC,YAAY,GACjB,IAAI,CAIhB;IAED;;;;OAIG;IACH,gBAHW,MAAM,GAAC,YAAY,GACjB,IAAI,CAIhB;IAED;;;;OAIG;IACH,gBAHW,MAAM,GAAC,YAAY,SACnB,OAAO,QAQjB;IAED;;;;OAIG;IACH,cAHW,MAAM,GAAC,YAAY,GACjB,OAAO,CAInB;IAED;;;OAGG;IACH,qBAFW,MAAM,QAehB;IAED;;OAEG;IACH,cAsBC;IAUD;;;;;;;;;;;;;aAkBC;IAGD;;;;;;;;;;;;;;;;;MAUC;IAED;;;OAGG;IACH,cAFW,OAAO,WAWjB;IAED;;;;;;;OAOG;IACH,cANW,MAAM,KACN,MAAM,KACN,MAAM,YACN,MAAM,GACJ,OAAO,CAmEnB;CAEJ;;;;;;+BArW8B,+BAA+B;sBALxC,iCAAiC;oBACnC,kCAAkC;wBAM9B,0BAA0B;oCACd,sCAAsC;0BAThD,yCAAyC;6BAWtC,mBAAmB;kCADd,wBAAwB"}
@@ -94,6 +94,12 @@ class Trail2D {
94
94
  */
95
95
  ribbon = null;
96
96
 
97
+ /**
98
+ * transient
99
+ * @type {Mesh|null}
100
+ */
101
+ mesh = null;
102
+
97
103
  /**
98
104
  * transient
99
105
  * @type {RibbonXMaterialSpec}
@@ -120,6 +126,15 @@ class Trail2D {
120
126
 
121
127
  this.ribbon.dispose();
122
128
  this.ribbon = null;
129
+
130
+ // The mesh's geometry died with the ribbon, so the component must stop
131
+ // claiming to be built: link() would otherwise take its "already built"
132
+ // branch, hang a material on the dead mesh and leave the ribbon null, and
133
+ // the first update would hand that null to the simulator. Dropping Built
134
+ // makes a re-link rebuild instead. The material is owned by the ribbon
135
+ // plugin's cache, so it is not ours to dispose — only to forget.
136
+ this.mesh = null;
137
+ this.clearFlag(Trail2DFlags.Built);
123
138
  }
124
139
 
125
140
  get textureURL() {
@@ -61,7 +61,10 @@ declare class Trail3D {
61
61
  */
62
62
  readonly color: Color;
63
63
  /**
64
- * World offset.
64
+ * Where the trail's head sits relative to the entity, in the entity's LOCAL
65
+ * frame: {@link Trail3DSystem} carries it through the entity's transform, so
66
+ * the offset rotates and scales with the entity rather than being a fixed
67
+ * world-space displacement.
65
68
  * @readonly
66
69
  * @type {Vector3}
67
70
  */
@@ -1 +1 @@
1
- {"version":3,"file":"Trail3D.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/ecs/trail3d/Trail3D.js"],"names":[],"mappings":";AAiCA;;;;;GAKG;AACH;IAoPI,oCAMC;IAxPD;;;OAGG;IACH,QAFU,MAAM,CAES;IAEzB;;;OAGG;IACH,OAFU,MAAM,CAEM;IAEtB;;;;OAIG;IACH,gBAFU,MAAM,CAEyB;IAEzC;;;OAGG;IACH,WAFU,cAAc,GAAC,MAAM,CAEC;IAEhC;;;;OAIG;IACH,eAFU,MAAM,CAEuB;IAEvC;;;OAGG;IACH,MAFU,MAAM,CAEP;IAET;;OAEG;IACH,eAFU,MAAM,CAEE;IAElB;;;OAGG;IACH,qBAFU,MAAM,CAEQ;IAExB;;;OAGG;IACH,yBAFU,MAAM,CAEY;IAE5B;;;;;OAKG;IACH,gBAFU,KAAK,CAEe;IAE9B;;;;OAIG;IACH,iBAFU,OAAO,CAEM;IAEvB;;;OAGG;IACH,MAFU,KAAK,GAAC,IAAI,CAER;IAEZ;;;OAGG;IACH,MAFU,OAAK,IAAI,CAEP;IAEZ;;;OAGG;IACH,UAFU,iBAAiB,CAEQ;IAEnC;;;OAGG;IACH,cAFU,SAAS,CAEG;IAEtB;;;OAGG;IACH,cAAsB;IAEtB,gBAQC;IAMD,4BAEC;IAND,yBAEC;IAUD,6BAEC;IAND,0BAEC;IA0BD;;OAEG;IACH,kCAQC;IA/BD;;;;;;;;;;;;;;;OAeG;IACH,+BAEC;IAeD;;;OAGG;IACH,cAHW,MAAM,GAAC,YAAY,GACjB,IAAI,CAIhB;IAED;;;OAGG;IACH,gBAHW,MAAM,GAAC,YAAY,GACjB,IAAI,CAIhB;IAED;;;OAGG;IACH,gBAHW,MAAM,GAAC,YAAY,SACnB,OAAO,QAQjB;IAED;;;OAGG;IACH,cAHW,MAAM,GAAC,YAAY,GACjB,OAAO,CAInB;IAED;;OAEG;IACH,qBAFW,MAAM,QAoBhB;IAED;;OAEG;IACH,cAmBC;IAUD;;;;;;;;;;;;;;;;aAwBC;IAED;;;;;;;;;;;;;;;;;;;;MAaC;IAED;;OAEG;IACH,cAFW,OAAO,WAcjB;IAkDD;;;;;;OAMG;IACH,cANW,MAAM,KACN,MAAM,KACN,MAAM,YACN,MAAM,GACJ,OAAO,CAiEnB;;CAEJ;;;;;+BA3c8B,+BAA+B;sBAPxC,iCAAiC;oBACnC,kCAAkC;sBAShC,2BAA2B;kCACf,uCAAuC;0BAZ/C,yCAAyC;6BAatC,mBAAmB"}
1
+ {"version":3,"file":"Trail3D.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/ecs/trail3d/Trail3D.js"],"names":[],"mappings":";AAiCA;;;;;GAKG;AACH;IAgQI,oCAMC;IApQD;;;OAGG;IACH,QAFU,MAAM,CAES;IAEzB;;;OAGG;IACH,OAFU,MAAM,CAEM;IAEtB;;;;OAIG;IACH,gBAFU,MAAM,CAEyB;IAEzC;;;OAGG;IACH,WAFU,cAAc,GAAC,MAAM,CAEC;IAEhC;;;;OAIG;IACH,eAFU,MAAM,CAEuB;IAEvC;;;OAGG;IACH,MAFU,MAAM,CAEP;IAET;;OAEG;IACH,eAFU,MAAM,CAEE;IAElB;;;OAGG;IACH,qBAFU,MAAM,CAEQ;IAExB;;;OAGG;IACH,yBAFU,MAAM,CAEY;IAE5B;;;;;OAKG;IACH,gBAFU,KAAK,CAEe;IAE9B;;;;;;;OAOG;IACH,iBAFU,OAAO,CAEM;IAEvB;;;OAGG;IACH,MAFU,KAAK,GAAC,IAAI,CAER;IAEZ;;;OAGG;IACH,MAFU,OAAK,IAAI,CAEP;IAEZ;;;OAGG;IACH,UAFU,iBAAiB,CAEQ;IAEnC;;;OAGG;IACH,cAFU,SAAS,CAEG;IAEtB;;;OAGG;IACH,cAAsB;IAEtB,gBAiBC;IAMD,4BAEC;IAND,yBAEC;IAUD,6BAEC;IAND,0BAEC;IA0BD;;OAEG;IACH,kCAQC;IA/BD;;;;;;;;;;;;;;;OAeG;IACH,+BAEC;IAeD;;;OAGG;IACH,cAHW,MAAM,GAAC,YAAY,GACjB,IAAI,CAIhB;IAED;;;OAGG;IACH,gBAHW,MAAM,GAAC,YAAY,GACjB,IAAI,CAIhB;IAED;;;OAGG;IACH,gBAHW,MAAM,GAAC,YAAY,SACnB,OAAO,QAQjB;IAED;;;OAGG;IACH,cAHW,MAAM,GAAC,YAAY,GACjB,OAAO,CAInB;IAED;;OAEG;IACH,qBAFW,MAAM,QAoBhB;IAED;;OAEG;IACH,cAmBC;IAUD;;;;;;;;;;;;;;;;aAwBC;IAED;;;;;;;;;;;;;;;;;;;;MAaC;IAED;;OAEG;IACH,cAFW,OAAO,WAcjB;IAkDD;;;;;;OAMG;IACH,cANW,MAAM,KACN,MAAM,KACN,MAAM,YACN,MAAM,GACJ,OAAO,CAiEnB;;CAEJ;;;;;+BAvd8B,+BAA+B;sBAPxC,iCAAiC;oBACnC,kCAAkC;sBAShC,2BAA2B;kCACf,uCAAuC;0BAZ/C,yCAAyC;6BAatC,mBAAmB"}