@woosh/meep-engine 2.109.12 → 2.109.13

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
@@ -5,7 +5,7 @@
5
5
  "description": "Fully featured ECS game engine written in JavaScript",
6
6
  "type": "module",
7
7
  "author": "Alexander Goldring",
8
- "version": "2.109.12",
8
+ "version": "2.109.13",
9
9
  "main": "build/meep.module.js",
10
10
  "module": "build/meep.module.js",
11
11
  "exports": {
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * Checks that elements in supplied arrays are exactly equal within a certain range defined by a pair of offsets and element count (length)
3
3
  * @template T
4
- * @param {T[]} a
4
+ * @param {T[]|Float32Array} a
5
5
  * @param {number} offset_a
6
- * @param {T[]} b
6
+ * @param {T[]|Float32Array} b
7
7
  * @param {number} offset_b
8
8
  * @param {number} length
9
9
  * @returns {boolean}
10
10
  */
11
- export function array_range_equal_strict<T>(a: T[], offset_a: number, b: T[], offset_b: number, length: number): boolean;
11
+ export function array_range_equal_strict<T>(a: Float32Array | T[], offset_a: number, b: Float32Array | T[], offset_b: number, length: number): boolean;
12
12
  //# sourceMappingURL=array_range_equal_strict.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"array_range_equal_strict.d.ts","sourceRoot":"","sources":["../../../../../src/core/collection/array/array_range_equal_strict.js"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,8DANW,MAAM,oBAEN,MAAM,UACN,MAAM,GACJ,OAAO,CAanB"}
1
+ {"version":3,"file":"array_range_equal_strict.d.ts","sourceRoot":"","sources":["../../../../../src/core/collection/array/array_range_equal_strict.js"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,6EANW,MAAM,mCAEN,MAAM,UACN,MAAM,GACJ,OAAO,CAanB"}
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Checks that elements in supplied arrays are exactly equal within a certain range defined by a pair of offsets and element count (length)
3
3
  * @template T
4
- * @param {T[]} a
4
+ * @param {T[]|Float32Array} a
5
5
  * @param {number} offset_a
6
- * @param {T[]} b
6
+ * @param {T[]|Float32Array} b
7
7
  * @param {number} offset_b
8
8
  * @param {number} length
9
9
  * @returns {boolean}
@@ -6,8 +6,38 @@ export class Ray3 extends Float32Array {
6
6
  set tMax(arg: any);
7
7
  get tMax(): any;
8
8
  6: any;
9
- get direction(): Float32Array;
10
- get origin(): Float32Array;
9
+ /**
10
+ *
11
+ * @param {number[]|Float32Array} v
12
+ */
13
+ set direction(arg: number[] | Float32Array);
14
+ get direction(): number[] | Float32Array;
15
+ /**
16
+ *
17
+ * @param {number[]|Float32Array} v
18
+ */
19
+ set origin(arg: number[] | Float32Array);
20
+ get origin(): number[] | Float32Array;
21
+ /**
22
+ *
23
+ * @param {number} x
24
+ * @param {number} y
25
+ * @param {number} z
26
+ */
27
+ setOrigin(x: number, y: number, z: number): void;
28
+ 0: number;
29
+ 1: number;
30
+ 2: number;
31
+ /**
32
+ *
33
+ * @param {number} x
34
+ * @param {number} y
35
+ * @param {number} z
36
+ */
37
+ setDirection(x: number, y: number, z: number): void;
38
+ 3: number;
39
+ 4: number;
40
+ 5: number;
11
41
  /**
12
42
  *
13
43
  * @param {number} distance
@@ -28,6 +58,7 @@ export class Ray3 extends Float32Array {
28
58
  * @param {Ray3} other
29
59
  */
30
60
  copy(other: Ray3): void;
61
+ hash(): number;
31
62
  /**
32
63
  *
33
64
  * @param {Ray3} other
@@ -1 +1 @@
1
- {"version":3,"file":"Ray3.d.ts","sourceRoot":"","sources":["../../../../../src/core/geom/3d/Ray3.js"],"names":[],"mappings":"AAKA;;GAEG;AACH;IACI,cAKC;IAMD,mBAEC;IAND,gBAEC;IAGG,OAAW;IAGf,8BAEC;IAED,2BAEC;IAED;;;OAGG;IACH,uBAFW,MAAM,QAMhB;IAED;;;OAGG;IACH,iBAFW,MAAM,EAAE,UAAM,YAAY,QAepC;IAED;;;OAGG;IACH,SAFa,IAAI,CAQhB;IAED;;;OAGG;IACH,YAFW,IAAI,QAId;IAED;;;;OAIG;IACH,cAHW,IAAI,GACF,OAAO,CAInB;CACJ"}
1
+ {"version":3,"file":"Ray3.d.ts","sourceRoot":"","sources":["../../../../../src/core/geom/3d/Ray3.js"],"names":[],"mappings":"AAOA;;GAEG;AACH;IACI,cAKC;IAMD,mBAEC;IAND,gBAEC;IAGG,OAAW;IAOf;;;OAGG;IACH,4CAEC;IAVD,yCAEC;IAcD;;;OAGG;IACH,yCAEC;IAVD,sCAEC;IAUD;;;;;OAKG;IACH,aAJW,MAAM,KACN,MAAM,KACN,MAAM,QAMhB;IAHG,UAAW;IACX,UAAW;IACX,UAAW;IAGf;;;;;OAKG;IACH,gBAJW,MAAM,KACN,MAAM,KACN,MAAM,QAMhB;IAHG,UAAW;IACX,UAAW;IACX,UAAW;IAGf;;;OAGG;IACH,uBAFW,MAAM,QAMhB;IAED;;;OAGG;IACH,iBAFW,MAAM,EAAE,UAAM,YAAY,QAepC;IAED;;;OAGG;IACH,SAFa,IAAI,CAQhB;IAED;;;OAGG;IACH,YAFW,IAAI,QAId;IAED,eAEC;IAED;;;;OAIG;IACH,cAHW,IAAI,GACF,OAAO,CAInB;CACJ"}
@@ -1,4 +1,6 @@
1
+ import { array_copy } from "../../collection/array/array_copy.js";
1
2
  import { array_range_equal_strict } from "../../collection/array/array_range_equal_strict.js";
3
+ import { computeHashFloatArray } from "../../math/hash/computeHashFloatArray.js";
2
4
  import { v3_matrix4_multiply } from "../vec3/v3_matrix4_multiply.js";
3
5
  import { v3_matrix4_rotate } from "../vec3/v3_matrix4_rotate.js";
4
6
  import { ray3_interval_array_apply_matrix4 } from "./ray/ray3_interval_array_apply_matrix4.js";
@@ -26,10 +28,50 @@ export class Ray3 extends Float32Array {
26
28
  return new Float32Array(this.buffer, this.byteOffset + 3 * 4, 3);
27
29
  }
28
30
 
31
+ /**
32
+ *
33
+ * @param {number[]|Float32Array} v
34
+ */
35
+ set direction(v) {
36
+ array_copy(v, 0, this, 3, 3);
37
+ }
38
+
29
39
  get origin() {
30
40
  return new Float32Array(this.buffer, this.byteOffset, 3);
31
41
  }
32
42
 
43
+ /**
44
+ *
45
+ * @param {number[]|Float32Array} v
46
+ */
47
+ set origin(v) {
48
+ array_copy(v, 0, this, 0, 3);
49
+ }
50
+
51
+ /**
52
+ *
53
+ * @param {number} x
54
+ * @param {number} y
55
+ * @param {number} z
56
+ */
57
+ setOrigin(x, y, z) {
58
+ this[0] = x;
59
+ this[1] = y;
60
+ this[2] = z;
61
+ }
62
+
63
+ /**
64
+ *
65
+ * @param {number} x
66
+ * @param {number} y
67
+ * @param {number} z
68
+ */
69
+ setDirection(x, y, z) {
70
+ this[3] = x;
71
+ this[4] = y;
72
+ this[5] = z;
73
+ }
74
+
33
75
  /**
34
76
  *
35
77
  * @param {number} distance
@@ -79,6 +121,10 @@ export class Ray3 extends Float32Array {
79
121
  this.set(other);
80
122
  }
81
123
 
124
+ hash() {
125
+ return computeHashFloatArray(this);
126
+ }
127
+
82
128
  /**
83
129
  *
84
130
  * @param {Ray3} other
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @see https://en.wikipedia.org/wiki/Focal_length
3
+ * @param {number} focal_length (in mm)
4
+ * @param {number} [sensor_width] Width of camera sensor (in mm)
5
+ * @returns {number} in Radians
6
+ */
7
+ export function focal_length_to_fov(focal_length: number, sensor_width?: number): number;
8
+ //# sourceMappingURL=focal_length_to_fov.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focal_length_to_fov.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/ecs/camera/focal_length_to_fov.js"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,kDAJW,MAAM,iBACN,MAAM,GACJ,MAAM,CAMlB"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @see https://en.wikipedia.org/wiki/Focal_length
3
+ * @param {number} focal_length (in mm)
4
+ * @param {number} [sensor_width] Width of camera sensor (in mm)
5
+ * @returns {number} in Radians
6
+ */
7
+ export function focal_length_to_fov(focal_length, sensor_width = 35) {
8
+
9
+ return 2 * Math.atan(sensor_width / (2 * focal_length));
10
+
11
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"Gizmo.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/render/gizmo/Gizmo.js"],"names":[],"mappings":"AAEA,iDAA2D;6CAFd,mCAAmC"}
1
+ {"version":3,"file":"Gizmo.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/render/gizmo/Gizmo.js"],"names":[],"mappings":"AAEA;;;GAGG;AACH,oBAFU,4BAA4B,CAEqB;6CANd,mCAAmC"}
@@ -1,3 +1,7 @@
1
1
  import { GizmoShapeRenderingInterface } from "./GizmoShapeRenderingInterface.js";
2
2
 
3
+ /**
4
+ *
5
+ * @type {GizmoShapeRenderingInterface}
6
+ */
3
7
  export const Gizmo = GizmoShapeRenderingInterface.INSTANCE;
@@ -1 +1 @@
1
- {"version":3,"file":"GizmoShapeRenderingInterface.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/render/gizmo/GizmoShapeRenderingInterface.js"],"names":[],"mappings":"AAyCA;;GAEG;AACH;IAGQ;;;;OAIG;IACH,gBAA2B;IAE3B,kCAA8F;IAC9F,iCAA6F;IAI7F,mCAA2G;IAC3G,kCAAiG;IAKjG,eAA0B;IAG9B,+CAQC;IAED;;;;;OAKG;IACH,qBAJW,MAAM,QAAQ,EAAE,sBAChB,MAAM,WACN,MAAM,EAAE,UAYlB;IAED,cAOC;IAED;;;;OAIG;IACH,yBAMC;IAED;;;OAGG;IACH,sBAEC;IAED;;;;OAIG;IACH,wBAHW,MAAM,EAAE,QACR,MAAM,EAAE,QAKlB;IAED;;;;OAIG;IACH,uBAHW,MAAM,EAAE,QACR,MAAM,EAAE,QAKlB;IAED;;;;OAIG;IACH,gBAHW,MAAM,EAAE,MACR,MAAM,EAAE,QAIlB;IAGD;;;;OAIG;IACH,0BAHW,MAAM,EAAE,UACR,MAAM,QAKhB;IAED;;;;OAIG;IACH,yBAHW,MAAM,EAAE,UACR,MAAM,QAKhB;CACJ;;;;mCA7KkC,iDAAiD;sBAQ9D,aAAa"}
1
+ {"version":3,"file":"GizmoShapeRenderingInterface.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/render/gizmo/GizmoShapeRenderingInterface.js"],"names":[],"mappings":"AAyCA;;GAEG;AACH;IAGQ;;;;OAIG;IACH,gBAA6C;IAE7C,kCAA8F;IAC9F,iCAA6F;IAI7F,mCAA2G;IAC3G,kCAAiG;IAKjG,eAA0B;IAG9B,+CAQC;IAED;;;;;OAKG;IACH,qBAJW,MAAM,QAAQ,EAAE,sBAChB,MAAM,WACN,MAAM,EAAE,UAYlB;IAED,cAOC;IAED;;;;OAIG;IACH,yBAMC;IAED;;;OAGG;IACH,sBAEC;IAED;;;;OAIG;IACH,wBAHW,MAAM,EAAE,QACR,MAAM,EAAE,QAKlB;IAED;;;;OAIG;IACH,uBAHW,MAAM,EAAE,QACR,MAAM,EAAE,QAKlB;IAED;;;;OAIG;IACH,gBAHW,MAAM,EAAE,MACR,MAAM,EAAE,QAIlB;IAGD;;;;OAIG;IACH,0BAHW,MAAM,EAAE,UACR,MAAM,QAKhB;IAED;;;;OAIG;IACH,yBAHW,MAAM,EAAE,UACR,MAAM,QAKhB;CACJ;;;;mCAtKkC,iDAAiD;sBAC9D,aAAa"}
@@ -1,13 +1,13 @@
1
- import { array_copy } from "../../../../core/collection/array/array_copy.js";
2
- import { assert } from "../../../../core/assert.js";
3
- import { InstancedMeshGroup } from "../../geometry/instancing/InstancedMeshGroup.js";
4
1
  import { BoxBufferGeometry, LineBasicMaterial, MeshBasicMaterial, OctahedronBufferGeometry } from "three";
2
+ import { makeHelperBoxGeometry } from "../../../../../editor/process/symbolic/makeHelperBoxGeometry.js";
3
+ import { makeHelperSphereGeometry } from "../../../../../editor/process/symbolic/makeHelperSphereGeometry.js";
4
+ import { assert } from "../../../../core/assert.js";
5
+ import { array_copy } from "../../../../core/collection/array/array_copy.js";
5
6
  import { compose_matrix4_array } from "../../../../core/geom/3d/compose_matrix4_array.js";
6
- import Vector3 from "../../../../core/geom/Vector3.js";
7
7
  import Quaternion from "../../../../core/geom/Quaternion.js";
8
- import { makeHelperBoxGeometry } from "../../../../../editor/process/symbolic/makeHelperBoxGeometry.js";
8
+ import Vector3 from "../../../../core/geom/Vector3.js";
9
9
  import { DrawMode } from "../../ecs/mesh-v2/DrawMode.js";
10
- import { makeHelperSphereGeometry } from "../../../../../editor/process/symbolic/makeHelperSphereGeometry.js";
10
+ import { InstancedMeshGroup } from "../../geometry/instancing/InstancedMeshGroup.js";
11
11
  import { Lines } from "../Lines.js";
12
12
 
13
13
  /**
@@ -47,10 +47,10 @@ export class GizmoShapeRenderingInterface {
47
47
 
48
48
  /**
49
49
  *
50
- * @type {number[]}
50
+ * @type {number[]|Float32Array}
51
51
  * @private
52
52
  */
53
- this.__color = [1, 1, 1, 1];
53
+ this.__color = new Float32Array([1, 1, 1, 1]);
54
54
 
55
55
  this.__boxes_solid = InstancedMeshGroup.from(new BoxBufferGeometry(), new MeshBasicMaterial());
56
56
  this.__boxes_wire = InstancedMeshGroup.from(makeHelperBoxGeometry(), new LineBasicMaterial());
@@ -515,8 +515,6 @@ vec4 lpv_renormalize_weights(in vec4 source) {
515
515
 
516
516
  }
517
517
 
518
-
519
-
520
518
  vec3 lpv_sample_irradiance(vec3 position, vec3 normal, vec3 view_direction) {
521
519
 
522
520
  // Bias the position at which visibility is computed; this
@@ -24,7 +24,7 @@ const ACCUMULATION = `
24
24
 
25
25
  vec3 probe_irradiance = lpv_sample_irradiance( vWorldPosition, world_normal, geometry.viewDir );
26
26
 
27
- irradiance += probe_irradiance * lpv_f_intensity;
27
+ irradiance += probe_irradiance * lpv_f_intensity;
28
28
 
29
29
  }
30
30
 
@@ -1 +1 @@
1
- {"version":3,"file":"PathTracerProbeRenderer.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/sh3/lpv/PathTracerProbeRenderer.js"],"names":[],"mappings":"AAuBA;IACI,mBAA0B;IAC1B,yBAAqB;IACrB,qBAAmB;IACnB,qBAAyB;IAEzB,uBAA6B;IAE7B;;;;;;;;OAQG;IACH,kCAPW,MAAM,aACN,MAAM,YACN,MAAM,EAAE,mBACR,MAAM,UACN,MAAM,EAAE,iBACR,MAAM,QAahB;IAED,iFAuCC;IAKD,mBACC;IAED,4BAKC;CACJ;8BA5F6B,oBAAoB;2BAHvB,8BAA8B;gCADzB,mCAAmC"}
1
+ {"version":3,"file":"PathTracerProbeRenderer.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/sh3/lpv/PathTracerProbeRenderer.js"],"names":[],"mappings":"AAuBA;IACI,mBAA0B;IAC1B,yBAAqB;IACrB,qBAAoB;IACpB,qBAAyB;IAEzB,uBAA6B;IAE7B;;;;;;;;OAQG;IACH,kCAPW,MAAM,aACN,MAAM,YACN,MAAM,EAAE,mBACR,MAAM,UACN,MAAM,EAAE,iBACR,MAAM,QAahB;IAED,iFAuCC;IAKD,mBACC;IAED,4BAKC;CACJ;8BA5F6B,oBAAoB;2BAHvB,8BAA8B;gCADzB,mCAAmC"}
@@ -24,7 +24,7 @@ const sampled_irradiance = new Float32Array(3);
24
24
  export class PathTracerProbeRenderer extends ProbeRenderer {
25
25
  tracer = new PathTracer();
26
26
  max_bounce_count = 7;
27
- sample_count = 192;
27
+ sample_count = 4096;
28
28
  random = seededRandom(0);
29
29
 
30
30
  scene = new PathTracedScene()
@@ -43,13 +43,13 @@ export function bake_octahedral_depth_map(
43
43
  * The lower the resolution - the higher the discontinuities
44
44
  * This is heights of an arch on a unit sphere, where arch spans 1/resolution angle
45
45
  * Half-PI is to get the height at midpoint of the arch
46
- * x2 is to get error over the entire circle, as the previous term only gets us to semicircle
46
+ * x2 is to get error over the entire circle, as the previous term only gets us to semicircle (we can skip this to get half the max rise, or mean)
47
47
  * xMath.SQRT2 is to allow for diagonals between pixels
48
48
  * @type {number}
49
49
  */
50
- const RESOLUTION_BIAS = Math.sin(PI_HALF / resolution) * 2 * Math.SQRT2;
50
+ const RESOLUTION_BIAS = Math.sin(PI_HALF / resolution) * Math.SQRT2;
51
51
 
52
- const NORMAL_BIAS = max_depth * 0.01;
52
+ const NORMAL_BIAS = max_depth * 0.01 + 1e-6;
53
53
 
54
54
  const ray_direction = scratch_ray.direction;
55
55
 
@@ -84,21 +84,21 @@ export function bake_octahedral_depth_map(
84
84
  ray_direction[0], ray_direction[1], ray_direction[2]
85
85
  );
86
86
 
87
- const resolution_bias_offset = distance * RESOLUTION_BIAS;
87
+ const resolution_bias_offset = max_depth * RESOLUTION_BIAS;
88
88
 
89
- const hit_normal_bias = -clamp01(1 - hit_angle_cos) * NORMAL_BIAS;
89
+ const hit_normal_bias = clamp01(1 - hit_angle_cos) * (resolution_bias_offset) + NORMAL_BIAS;
90
90
 
91
91
  // sink the contact into the surface along the hit normal
92
- const biased_hit_x = surface_position_x + surface_normal_x * hit_normal_bias;
93
- const biased_hit_y = surface_position_y + surface_normal_y * hit_normal_bias;
94
- const biased_hit_z = surface_position_z + surface_normal_z * hit_normal_bias;
92
+ const biased_hit_x = surface_position_x - surface_normal_x * hit_normal_bias;
93
+ const biased_hit_y = surface_position_y - surface_normal_y * hit_normal_bias;
94
+ const biased_hit_z = surface_position_z - surface_normal_z * hit_normal_bias;
95
95
 
96
96
  distance = v3_distance(
97
97
  scratch_ray[0], scratch_ray[1], scratch_ray[2],
98
98
  biased_hit_x, biased_hit_y, biased_hit_z
99
99
  );
100
100
 
101
- distance += resolution_bias_offset;
101
+ // distance += resolution_bias_offset;
102
102
  }
103
103
 
104
104
  const pixel_index = oct_y * resolution + oct_x;
@@ -25,6 +25,7 @@ import Quaternion from "../../../core/geom/Quaternion.js";
25
25
  import Vector3 from "../../../core/geom/Vector3.js";
26
26
  import { max2 } from "../../../core/math/max2.js";
27
27
  import { min2 } from "../../../core/math/min2.js";
28
+ import { RAD_TO_DEG } from "../../../core/math/RAD_TO_DEG.js";
28
29
  import { randomFloatBetween } from "../../../core/math/random/randomFloatBetween.js";
29
30
  import { seededRandom } from "../../../core/math/random/seededRandom.js";
30
31
  import { number_pretty_print } from "../../../core/primitives/numbers/number_pretty_print.js";
@@ -39,6 +40,7 @@ import { TransformAttachmentSystem } from "../../ecs/transform-attachment/Transf
39
40
  import { Transform } from "../../ecs/transform/Transform.js";
40
41
  import { EngineHarness } from "../../EngineHarness.js";
41
42
  import { Camera } from "../ecs/camera/Camera.js";
43
+ import { focal_length_to_fov } from "../ecs/camera/focal_length_to_fov.js";
42
44
  import TopDownCameraController from "../ecs/camera/topdown/TopDownCameraController.js";
43
45
  import { Light } from "../ecs/light/Light.js";
44
46
  import LightSystem from "../ecs/light/LightSystem.js";
@@ -243,7 +245,7 @@ async function getVolume({
243
245
  engine,
244
246
  ecd,
245
247
  bounds: mesh_bounds,
246
- density: 500
248
+ density: 5000
247
249
  });
248
250
 
249
251
  const buffer = new BinaryBuffer();
@@ -337,6 +339,7 @@ async function main(engine) {
337
339
  pitch: 1,
338
340
  yaw: -1.54,
339
341
  distance: 54,
342
+ cameraFieldOfView: focal_length_to_fov(50, 25) * RAD_TO_DEG,
340
343
  // shadowmapResolution: 4096
341
344
  });
342
345
 
@@ -381,8 +384,12 @@ async function main(engine) {
381
384
  // const path = 'data/models/LowPolyTownshipSet/Town_Hall/model.gltf';
382
385
  // const path = 'data/models/sibenik/3-window-less/model.gltf';
383
386
  // const path = 'data/models/samples/gi_box_01/model.glb';
384
- const path = 'data/models/sponza-pbr/gltf/sponza.glb';
387
+ // const path = 'data/models/sponza-pbr/gltf/sponza.glb';
385
388
  // const path = 'data/models/pica_pica/pica_pica.gltf';
389
+ // const path = 'data/models/samples/susanne.glb';
390
+ // const path = 'data/models/samples/teapot.gltf';
391
+ const path = 'data/models/samples/salle_de_bain/model.glb';
392
+ // const path = 'data/models/samples/conference/model-no-curtains.glb';
386
393
 
387
394
  const mesh_asset = await engine.assetManager.promise(path, 'model/gltf+json');
388
395
  const gltf = mesh_asset.gltf;
@@ -444,7 +451,7 @@ async function main(engine) {
444
451
  const camera = ecd.getAnyComponent(Camera);
445
452
  camera.component.clip_far = max2(100, model_footprint);
446
453
  const camera_controller = ecd.getComponent(camera.entity, TopDownCameraController);
447
- camera_controller.distanceMax = model_footprint * 1.1;
454
+ camera_controller.distanceMax = model_footprint * 2;
448
455
  camera_controller.distanceMin = min2(camera_controller.distanceMin, model_footprint * 0.01);
449
456
  mesh_bounds.getCenter(camera_controller.target)
450
457