@needle-tools/engine 3.19.1 → 3.19.2

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.
@@ -13,8 +13,6 @@ import { ICameraController } from "../engine/engine_types.js";
13
13
  import { setCameraController } from "../engine/engine_camera.js";
14
14
  import { SyncedTransform } from "./SyncedTransform.js";
15
15
  import { tryGetUIComponent } from "./ui/Utils.js";
16
- import { GroundProjectedEnv } from "./GroundProjection.js";
17
- import { ShadowCatcher } from "./ShadowCatcher.js";
18
16
  import { GroundProjectedSkybox } from "three/examples/jsm/objects/GroundProjectedSkybox.js";
19
17
 
20
18
  const freeCam = getParam("freecam");
@@ -43,6 +41,9 @@ export class OrbitControls extends Behaviour implements ICameraController {
43
41
 
44
42
  autoRotate: boolean = false;
45
43
  autoRotateSpeed: number = 1.0;
44
+ /** When enabled the scene will be automatically fitted into the camera view in onEnable */
45
+ @serializable()
46
+ autoFit: boolean = false;
46
47
  enableKeys: boolean = true;
47
48
  enableDamping: boolean = true;
48
49
  dampingFactor: number = 0.1;
@@ -81,15 +82,18 @@ export class OrbitControls extends Behaviour implements ICameraController {
81
82
  private _afterHandleInputFn?: any;
82
83
  private _camera: Camera | null = null;
83
84
  private _syncedTransform?: SyncedTransform;
85
+ private _didStart = false;
84
86
 
85
87
  targetElement: HTMLElement | null = null;
86
88
 
87
89
  awake(): void {
90
+ this._didStart = false;
88
91
  this._lookTargetPosition = new Vector3();
89
92
  this._startedListeningToKeyEvents = false;
90
93
  }
91
94
 
92
95
  start() {
96
+ this._didStart = true;
93
97
  if (this.autoTarget) {
94
98
  if (this._controls) {
95
99
  const camGo = GameObject.getComponent(this.gameObject, Camera);
@@ -99,10 +103,19 @@ export class OrbitControls extends Behaviour implements ICameraController {
99
103
  const worldPosition = getWorldPosition(camGo.cam);
100
104
  const distanceToCenter = worldPosition.length();
101
105
  const forward = new Vector3(0, 0, -distanceToCenter).applyMatrix4(camGo.cam.matrixWorld);
102
- this.setTarget(forward, true);
103
106
  }
107
+ if (this.autoTarget && !this.setFromTargetPosition()) {
108
+ const opts = new RaycastOptions();
109
+ // center of the screen:
110
+ opts.screenPoint = new Vector2(0, 0);
111
+ opts.lineThreshold = 0.1;
112
+ const hits = this.context.physics.raycast(opts);
113
+ if (hits.length > 0) {
114
+ this.setTarget(hits[0].point, true);
115
+ }
116
+ }
117
+ if (this.autoFit) this.fitCamera()
104
118
  }
105
- this.startCoroutine(this.startRaycastDelayed());
106
119
  }
107
120
 
108
121
  this._eventSystem = EventSystem.get(this.context) ?? undefined;
@@ -173,6 +186,9 @@ export class OrbitControls extends Behaviour implements ICameraController {
173
186
  }
174
187
  }
175
188
  this._syncedTransform = GameObject.getComponent(this.gameObject, SyncedTransform) ?? undefined;
189
+ if (this._didStart) {
190
+ if (this.autoFit) this.fitCamera()
191
+ }
176
192
  }
177
193
 
178
194
  onDisable() {
@@ -207,20 +223,6 @@ export class OrbitControls extends Behaviour implements ICameraController {
207
223
  }
208
224
  }
209
225
 
210
- // we need to wait one frame (when starting the scene for the very first time)
211
- private * startRaycastDelayed() {
212
- yield;
213
- if (this.autoTarget && !this.setFromTargetPosition()) {
214
- const opts = new RaycastOptions();
215
- // center of the screen:
216
- opts.screenPoint = new Vector2(0, 0);
217
- opts.lineThreshold = 0.1;
218
- const hits = this.context.physics.raycast(opts);
219
- if (hits.length > 0) {
220
- this.setTarget(hits[0].point, true);
221
- }
222
- }
223
- }
224
226
 
225
227
  onBeforeRender() {
226
228
  if (!this._controls) return;
@@ -374,7 +376,7 @@ export class OrbitControls extends Behaviour implements ICameraController {
374
376
  // Adapted from https://discourse.threejs.org/t/camera-zoom-to-fit-object/936/24
375
377
  // Slower but better implementation that takes bones and exact vertex positions into account: https://github.com/google/model-viewer/blob/04e900c5027de8c5306fe1fe9627707f42811b05/packages/model-viewer/src/three-components/ModelScene.ts#L321
376
378
  /** Fits the camera to show the objects provided (defaults to the scene if no objects are passed in) */
377
- fitCamera(objects?: Array<Object3D>, fitOffset: number = 1.1) {
379
+ fitCamera(objects?: Array<Object3D>, fitOffset: number = 1.1, immediate: boolean = true) {
378
380
  const camera = this._cameraObject as PerspectiveCamera;
379
381
  const controls = this._controls as ThreeOrbitControls | null;
380
382
  if (!objects?.length) objects = this.context.scene.children;
@@ -395,6 +397,8 @@ export class OrbitControls extends Behaviour implements ICameraController {
395
397
  const emptyChildren = [];
396
398
  function expandByObjectRecursive(obj: Object3D) {
397
399
  let allowExpanding = true;
400
+ // we dont want to check invisible objects
401
+ if (!obj.visible) return;
398
402
  // ignore Box3Helpers
399
403
  if (obj instanceof Box3Helper) allowExpanding = false;
400
404
  if (obj instanceof GridHelper) allowExpanding = false;
@@ -402,9 +406,16 @@ export class OrbitControls extends Behaviour implements ICameraController {
402
406
  if (obj instanceof GroundProjectedSkybox) allowExpanding = false;
403
407
  // // Ignore shadow catcher geometry
404
408
  if ((obj as Mesh).material instanceof ShadowMaterial) allowExpanding = false;
409
+ // ONLY fit meshes
410
+ if (!(obj instanceof Mesh)) allowExpanding = false;
411
+ // Ignore things parented to the camera + ignore the camera
412
+ if (obj === camera) return;
413
+ // We don't want to fit UI objects
414
+ if (obj["isUI"] === true) return;
405
415
  // If we encountered some geometry that should be ignored
406
416
  // Then we don't want to use that for expanding the view
407
417
  if (allowExpanding) {
418
+ console.log(obj.name, obj.type, obj);
408
419
  // Temporary override children
409
420
  const children_length = obj.children;
410
421
  obj.children = emptyChildren;
@@ -453,7 +464,8 @@ export class OrbitControls extends Behaviour implements ICameraController {
453
464
 
454
465
  controls.maxDistance = distance * 10;
455
466
  controls.minDistance = distance * 0.01;
456
- this.setTarget(center, true);
467
+
468
+ this.setTarget(center, immediate);
457
469
  this.autoTarget = false;
458
470
 
459
471
  // TODO: this doesnt take the Camera component nearClipPlane into account
@@ -463,7 +475,13 @@ export class OrbitControls extends Behaviour implements ICameraController {
463
475
  camera.updateMatrixWorld();
464
476
  camera.updateProjectionMatrix();
465
477
 
466
- setWorldPosition(camera, controls.target.clone().sub(direction));
478
+ if (camera.parent) {
479
+ const cameraLocalPosition = camera.parent!.worldToLocal(controls.target.clone().sub(direction));
480
+ this.setCameraTarget(cameraLocalPosition, immediate);
481
+ }
482
+ else console.error(`Can not fit camera ${camera.name} because it has no parent`)
483
+
484
+ // setWorldPosition(camera, controls.target.clone().sub(direction));
467
485
 
468
486
  if (debugCameraFit) {
469
487
  const helper = new Box3Helper(box);