@needle-tools/engine 4.10.0-beta.2 → 4.10.0-beta.4
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/components.needle.json +1 -1
- package/dist/needle-engine.bundle-BFTyp4Pf.min.js +1652 -0
- package/dist/{needle-engine.bundle-BTgC7uAm.js → needle-engine.bundle-CsVLA8Ze.js} +6482 -6427
- package/dist/{needle-engine.bundle-OTBqjiCd.umd.cjs → needle-engine.bundle-D9nl4ea6.umd.cjs} +139 -137
- package/dist/needle-engine.js +106 -106
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/lib/engine/codegen/register_types.js +2 -2
- package/lib/engine/codegen/register_types.js.map +1 -1
- package/lib/engine/engine_camera.js +5 -5
- package/lib/engine/engine_camera.js.map +1 -1
- package/lib/engine/engine_gizmos.d.ts +11 -10
- package/lib/engine/engine_gizmos.js +24 -10
- package/lib/engine/engine_gizmos.js.map +1 -1
- package/lib/engine/extensions/extension_utils.js +1 -1
- package/lib/engine/extensions/extension_utils.js.map +1 -1
- package/lib/engine/xr/NeedleXRController.d.ts +3 -3
- package/lib/engine/xr/NeedleXRController.js +28 -0
- package/lib/engine/xr/NeedleXRController.js.map +1 -1
- package/lib/engine-components/CameraUtils.js +2 -1
- package/lib/engine-components/CameraUtils.js.map +1 -1
- package/lib/engine-components/codegen/components.d.ts +1 -1
- package/lib/engine-components/codegen/components.js +1 -1
- package/lib/engine-components/codegen/components.js.map +1 -1
- package/lib/engine-components/debug/LogStats.d.ts +1 -0
- package/lib/engine-components/debug/LogStats.js +1 -0
- package/lib/engine-components/debug/LogStats.js.map +1 -1
- package/lib/engine-components/timeline/PlayableDirector.js +1 -1
- package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
- package/lib/engine-components/timeline/TimelineTracks.d.ts +2 -1
- package/lib/engine-components/timeline/TimelineTracks.js +24 -19
- package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
- package/lib/engine-components/web/ScrollFollow.js +36 -34
- package/lib/engine-components/web/ScrollFollow.js.map +1 -1
- package/lib/engine-components/web/ViewBox.d.ts +2 -3
- package/lib/engine-components/web/ViewBox.js +99 -50
- package/lib/engine-components/web/ViewBox.js.map +1 -1
- package/lib/engine-components-experimental/Presentation.d.ts +1 -0
- package/lib/engine-components-experimental/Presentation.js +1 -0
- package/lib/engine-components-experimental/Presentation.js.map +1 -1
- package/package.json +1 -1
- package/src/engine/codegen/register_types.ts +2 -2
- package/src/engine/engine_camera.ts +5 -7
- package/src/engine/engine_gizmos.ts +37 -23
- package/src/engine/extensions/extension_utils.ts +1 -1
- package/src/engine/xr/NeedleXRController.ts +36 -4
- package/src/engine-components/CameraUtils.ts +1 -1
- package/src/engine-components/codegen/components.ts +1 -1
- package/src/engine-components/debug/LogStats.ts +1 -0
- package/src/engine-components/timeline/PlayableDirector.ts +1 -1
- package/src/engine-components/timeline/TimelineTracks.ts +24 -19
- package/src/engine-components/web/ScrollFollow.ts +40 -36
- package/src/engine-components/web/ViewBox.ts +101 -47
- package/src/engine-components-experimental/Presentation.ts +1 -0
- package/dist/needle-engine.bundle-g2_JEHcF.min.js +0 -1650
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Box3, Object3D } from "three";
|
|
2
2
|
import { element } from "three/src/nodes/TSL.js";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { isDevEnvironment } from "../../engine/debug/debug.js";
|
|
5
5
|
import { Mathf } from "../../engine/engine_math.js";
|
|
6
6
|
import { serializable } from "../../engine/engine_serialization.js";
|
|
7
7
|
import { getBoundingBox, setVisibleInCustomShadowRendering } from "../../engine/engine_three_utils.js";
|
|
@@ -174,8 +174,8 @@ export class ScrollFollow extends Behaviour {
|
|
|
174
174
|
|
|
175
175
|
const value = this.invert ? 1 - this._current_value : this._current_value;
|
|
176
176
|
|
|
177
|
-
const height = this._rangeEndValue - this._rangeStartValue;
|
|
178
|
-
const pixelValue = this._rangeStartValue + value * height;
|
|
177
|
+
// const height = this._rangeEndValue - this._rangeStartValue;
|
|
178
|
+
// const pixelValue = this._rangeStartValue + value * height;
|
|
179
179
|
|
|
180
180
|
// apply scroll to target(s)
|
|
181
181
|
if (Array.isArray(this.target)) {
|
|
@@ -186,7 +186,7 @@ export class ScrollFollow extends Behaviour {
|
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
if (debug && this.context.time.frame % 30 === 0) {
|
|
189
|
-
console.debug(`[ScrollFollow] ${this._current_value.toFixed(5)} — ${(this._target_value * 100).toFixed(0)}
|
|
189
|
+
console.debug(`[ScrollFollow] ${this._current_value.toFixed(5)} — ${(this._target_value * 100).toFixed(0)}%, targets [${Array.isArray(this.target) ? this.target.length : 1}]`);
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
192
|
}
|
|
@@ -304,13 +304,15 @@ export class ScrollFollow extends Behaviour {
|
|
|
304
304
|
const index = markerIndex++;
|
|
305
305
|
|
|
306
306
|
// Get marker elements from DOM
|
|
307
|
-
if ((marker.element === undefined || marker.needsUpdate === true || /** element is not in DOM anymore? */ (!marker.element?.parentNode))) {
|
|
307
|
+
if ((marker.element === undefined || marker.needsUpdate === true || /** element is not in DOM anymore? */ (marker.element && !marker.element?.parentNode))) {
|
|
308
308
|
marker.needsUpdate = false;
|
|
309
309
|
try {
|
|
310
|
+
// TODO: with this it's currently not possible to remap markers from HTML. For example if I have two sections and I want to now use the marker["center"] multiple times to stay at that marker for a longer time
|
|
310
311
|
marker.element = tryGetElementsForSelector(index, marker.name) as HTMLElement | null;
|
|
311
|
-
if (debug) console.debug(
|
|
312
|
+
if (debug) console.debug(`ScrollMarker #${index} "${marker.name}" (${marker.time.toFixed(2)}) found`, marker.element);
|
|
312
313
|
if (!marker.element) {
|
|
313
314
|
marker.timeline = undefined;
|
|
315
|
+
if (debug || isDevEnvironment()) console.warn(`No HTML element found for ScrollMarker: ${marker.name} (index ${index})`);
|
|
314
316
|
continue;
|
|
315
317
|
}
|
|
316
318
|
else {
|
|
@@ -370,19 +372,20 @@ export class ScrollFollow extends Behaviour {
|
|
|
370
372
|
const time01 = calculateTimelinePositionNormalized(timeline);
|
|
371
373
|
// remap 0-1 to 0 - 1 - 0 (full weight at center)
|
|
372
374
|
const weight = 1 - Math.abs(time01 - 0.5) * 2;
|
|
375
|
+
const name = marker.name || `marker${i}`;
|
|
373
376
|
if (time01 > 0 && time01 <= 1) {
|
|
374
377
|
const lerpTime = marker.time + (nextTime - marker.time) * time01;
|
|
375
|
-
weightsArray.push({ time: lerpTime, weight: weight });
|
|
378
|
+
weightsArray.push({ name, time: lerpTime, weight: weight });
|
|
376
379
|
sum += weight;
|
|
377
380
|
}
|
|
378
381
|
// Before the first marker is reached
|
|
379
382
|
else if (i === 0 && time01 <= 0) {
|
|
380
|
-
weightsArray.push({ time: 0, weight: 1 });
|
|
383
|
+
weightsArray.push({ name, time: 0, weight: 1 });
|
|
381
384
|
sum += 1;
|
|
382
385
|
}
|
|
383
386
|
// After the last marker is reached
|
|
384
387
|
else if (i === markersArray.length - 1 && time01 >= 1) {
|
|
385
|
-
weightsArray.push({ time: duration, weight: 1 });
|
|
388
|
+
weightsArray.push({ name, time: duration, weight: 1 });
|
|
386
389
|
sum += 1;
|
|
387
390
|
}
|
|
388
391
|
}
|
|
@@ -435,13 +438,16 @@ export class ScrollFollow extends Behaviour {
|
|
|
435
438
|
time += diff * weight;
|
|
436
439
|
}
|
|
437
440
|
}
|
|
438
|
-
if (debug && this.context.time.frame % 20 === 0) console.log(time.toFixed(3), [...weightsArray])
|
|
439
441
|
if (this.damping <= 0) {
|
|
440
442
|
director.time = time;
|
|
441
443
|
}
|
|
442
444
|
else {
|
|
443
445
|
director.time = Mathf.lerp(director.time, time, this.context.time.deltaTime / this.damping);
|
|
444
446
|
}
|
|
447
|
+
|
|
448
|
+
if (debug && this.context.time.frame % 30 === 0) {
|
|
449
|
+
console.log(`[ScrollFollow ] Timeline ${director.name}: ${time.toFixed(3)}`, weightsArray.map(w => `[${w.name} ${(w.weight * 100).toFixed(0)}%]`).join(", "));
|
|
450
|
+
}
|
|
445
451
|
}
|
|
446
452
|
}
|
|
447
453
|
|
|
@@ -450,9 +456,13 @@ export class ScrollFollow extends Behaviour {
|
|
|
450
456
|
|
|
451
457
|
|
|
452
458
|
const weightsArray: OverlapInfo[] = [];
|
|
453
|
-
const markersArray:
|
|
459
|
+
const markersArray: Array<ScrollMarkerModel & {
|
|
460
|
+
element?: HTMLElement | null,
|
|
461
|
+
timeline?: ViewTimeline,
|
|
462
|
+
}> = [];
|
|
454
463
|
|
|
455
464
|
type OverlapInfo = {
|
|
465
|
+
name: string,
|
|
456
466
|
/** Marker time */
|
|
457
467
|
time: number,
|
|
458
468
|
/** Overlap in pixels */
|
|
@@ -468,17 +478,29 @@ type OverlapInfo = {
|
|
|
468
478
|
// }
|
|
469
479
|
// const querySelectorResults: Array<SelectorCache> = [];
|
|
470
480
|
|
|
471
|
-
const needleScrollMarkerCacheKey = "data-timeline-marker";
|
|
472
481
|
const needleScrollMarkerIndexCache = new Map<number, Element | null>();
|
|
473
482
|
const needleScrollMarkerNameCache = new Map<string, Element | null>();
|
|
474
483
|
let needsScrollMarkerRefresh = true;
|
|
475
484
|
|
|
476
|
-
function tryGetElementsForSelector(index: number, name: string): Element | null {
|
|
485
|
+
function tryGetElementsForSelector(index: number, name: string, _cycle: number = 0): Element | null {
|
|
477
486
|
|
|
478
487
|
if (!needsScrollMarkerRefresh) {
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
488
|
+
if (name?.length) {
|
|
489
|
+
const element = needleScrollMarkerNameCache.get(name) || null;
|
|
490
|
+
if (element) return element;
|
|
491
|
+
// const isNumber = !isNaN(Number(name));
|
|
492
|
+
// if (!isNumber) {
|
|
493
|
+
// }
|
|
494
|
+
}
|
|
495
|
+
const element = needleScrollMarkerIndexCache.get(index) || null;
|
|
496
|
+
const value = element?.getAttribute("data-timeline-marker");
|
|
497
|
+
// if (value?.length) {
|
|
498
|
+
// if (cycle === 0) {
|
|
499
|
+
// // if the HTML marker we found by index does define a different marker name we try to find the correct HTML element by name
|
|
500
|
+
// return tryGetElementsForSelector(index, value, 1);
|
|
501
|
+
// }
|
|
502
|
+
// if (isDevEnvironment()) console.warn(`ScrollMarker name mismatch: expected "${name}", got "${value}"`);
|
|
503
|
+
// }
|
|
482
504
|
return element;
|
|
483
505
|
}
|
|
484
506
|
needsScrollMarkerRefresh = false;
|
|
@@ -489,26 +511,8 @@ function tryGetElementsForSelector(index: number, name: string): Element | null
|
|
|
489
511
|
const name = m.getAttribute("data-timeline-marker");
|
|
490
512
|
if (name?.length) needleScrollMarkerNameCache.set(name, m);
|
|
491
513
|
});
|
|
492
|
-
|
|
493
|
-
return
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
/* e.g.
|
|
497
|
-
<div class="section behind start" data-needle-scroll-marker>
|
|
498
|
-
*/
|
|
499
|
-
// console.log(index, element)
|
|
500
|
-
if (element) return element;
|
|
501
|
-
|
|
502
|
-
// for (const entry of querySelectorResults) {
|
|
503
|
-
// if (entry.selector === selector) {
|
|
504
|
-
// const index = entry.usedElementCount++;
|
|
505
|
-
// return entry.elements && index < entry.elements.length ? entry.elements[index] : null;
|
|
506
|
-
// }
|
|
507
|
-
// }
|
|
508
|
-
// const elements = document.querySelectorAll(selector);
|
|
509
|
-
// querySelectorResults.push({ selector, elements: Array.from(elements), usedElementCount: 1 });
|
|
510
|
-
// if (elements.length > 0) return elements[0];
|
|
511
|
-
return null;
|
|
514
|
+
needsScrollMarkerRefresh = false;
|
|
515
|
+
return tryGetElementsForSelector(index, name);
|
|
512
516
|
}
|
|
513
517
|
|
|
514
518
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Camera, PerspectiveCamera, Vector2, Vector3 } from "three";
|
|
1
|
+
import { Camera, PerspectiveCamera, Quaternion, Vector2, Vector3 } from "three";
|
|
2
2
|
|
|
3
3
|
import { isDevEnvironment } from "../../engine/debug/debug.js";
|
|
4
4
|
import { Gizmos } from "../../engine/engine_gizmos.js";
|
|
@@ -6,14 +6,17 @@ import { serializable } from "../../engine/engine_serialization_decorator.js";
|
|
|
6
6
|
import { getTempVector } from "../../engine/engine_three_utils.js";
|
|
7
7
|
import { registerType } from "../../engine/engine_typestore.js";
|
|
8
8
|
import { getParam } from "../../engine/engine_utils.js";
|
|
9
|
+
import { RGBAColor } from "../../engine/js-extensions/RGBAColor.js";
|
|
9
10
|
import { Behaviour } from "../Component.js";
|
|
10
11
|
|
|
12
|
+
|
|
11
13
|
const debugParam = getParam("debugviewbox");
|
|
14
|
+
const disabledGizmoColor = new RGBAColor(.5, .5, .5, .5);
|
|
12
15
|
|
|
13
16
|
@registerType
|
|
14
|
-
export class
|
|
17
|
+
export class ResponsiveBox extends Behaviour {
|
|
15
18
|
|
|
16
|
-
static instances:
|
|
19
|
+
static instances: ResponsiveBox[] = [];
|
|
17
20
|
|
|
18
21
|
@serializable()
|
|
19
22
|
referenceFieldOfView: number = 60;
|
|
@@ -21,30 +24,41 @@ export class ViewBox extends Behaviour {
|
|
|
21
24
|
@serializable()
|
|
22
25
|
debug: boolean = false;
|
|
23
26
|
|
|
24
|
-
awake() {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
27
|
+
// awake() {
|
|
28
|
+
// // this.referenceFieldOfView = (this.context.mainCamera as PerspectiveCamera)?.fov || 60;
|
|
29
|
+
// setInterval(()=>{
|
|
30
|
+
// if(Math.random() > .5)
|
|
31
|
+
// this.enabled = !this.enabled
|
|
32
|
+
// }, 1000)
|
|
33
|
+
// }
|
|
34
|
+
|
|
30
35
|
onEnable(): void {
|
|
31
36
|
if (debugParam || this.debug || isDevEnvironment()) console.debug("[ViewBox] Using camera fov:", this.referenceFieldOfView);
|
|
32
|
-
|
|
37
|
+
ResponsiveBox.instances.push(this);
|
|
38
|
+
// this.context.pre_render_callbacks.push(this.internalUpdate);
|
|
33
39
|
}
|
|
34
40
|
|
|
35
41
|
onDisable(): void {
|
|
36
|
-
|
|
37
|
-
|
|
42
|
+
if (debugParam || this.debug) console.debug("[ViewBox] Disabled");
|
|
43
|
+
const idx = ResponsiveBox.instances.indexOf(this);
|
|
44
|
+
if (idx !== -1) ResponsiveBox.instances.splice(idx, 1);
|
|
45
|
+
this._projectedBoxElement?.remove();
|
|
46
|
+
|
|
47
|
+
// const cb_idx = this.context.pre_render_callbacks.indexOf(this.internalUpdate);
|
|
48
|
+
// if (cb_idx !== -1) this.context.pre_render_callbacks.splice(cb_idx, 1);
|
|
38
49
|
}
|
|
39
50
|
|
|
40
|
-
onBeforeRender() {
|
|
51
|
+
onBeforeRender(): void {
|
|
41
52
|
if (this.context.isInXR) return;
|
|
42
|
-
|
|
53
|
+
if(this.destroyed) return;
|
|
54
|
+
const isActive = ResponsiveBox.instances[ResponsiveBox.instances.length - 1] === this;
|
|
43
55
|
if (!isActive) {
|
|
44
|
-
if (debugParam || this.debug)
|
|
56
|
+
if (debugParam || this.debug) {
|
|
57
|
+
Gizmos.DrawWireBox(this.gameObject.worldPosition, this.gameObject.worldScale, disabledGizmoColor);
|
|
58
|
+
}
|
|
45
59
|
return;
|
|
46
60
|
}
|
|
47
|
-
if (debugParam || this.debug) Gizmos.DrawWireBox(this.gameObject.worldPosition, this.gameObject.worldScale, 0xdddd00);
|
|
61
|
+
if (debugParam || this.debug) Gizmos.DrawWireBox(this.gameObject.worldPosition, this.gameObject.worldScale, 0xdddd00, 0, true, this.gameObject.worldQuaternion);
|
|
48
62
|
|
|
49
63
|
// calculate box size to fit the camera frustrum size at the current position (just scale)
|
|
50
64
|
const camera = this.context.mainCamera;
|
|
@@ -80,44 +94,81 @@ export class ViewBox extends Behaviour {
|
|
|
80
94
|
diffHeight = domHeight / rectHeight;
|
|
81
95
|
}
|
|
82
96
|
|
|
83
|
-
|
|
97
|
+
|
|
84
98
|
const view = camera.view;
|
|
85
99
|
const zoom = camera.zoom;
|
|
86
100
|
const aspect = camera.aspect;
|
|
87
101
|
const fov = camera.fov;
|
|
88
102
|
camera.view = null;
|
|
89
103
|
camera.zoom = 1;
|
|
90
|
-
// camera.aspect = rectWidth / rectHeight;
|
|
91
104
|
camera.fov = this.referenceFieldOfView;
|
|
92
105
|
camera.updateProjectionMatrix();
|
|
93
106
|
|
|
107
|
+
|
|
94
108
|
const boxPosition = this.gameObject.worldPosition;
|
|
95
109
|
const boxScale = this.gameObject.worldScale;
|
|
96
110
|
|
|
111
|
+
const cameraPosition = camera.worldPosition;
|
|
112
|
+
const distance = cameraPosition.distanceTo(boxPosition);
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
// #region camera fixes
|
|
116
|
+
// If the camera is inside the box, move it out
|
|
117
|
+
const boxSizeMax = Math.max(boxScale.x, boxScale.y, boxScale.z);
|
|
118
|
+
const direction = getTempVector(cameraPosition).sub(boxPosition);
|
|
119
|
+
if (distance < boxSizeMax) {
|
|
120
|
+
// move camera out of bounds
|
|
121
|
+
if (this.debug || debugParam) console.warn("[ViewBox] Moving camera out of bounds", distance, "<", boxSizeMax);
|
|
122
|
+
const positionDirection = getTempVector(direction);
|
|
123
|
+
positionDirection.y *= .00000001; // stay on horizontal plane mostly
|
|
124
|
+
positionDirection.normalize();
|
|
125
|
+
const lengthToMove = (boxSizeMax - distance) * 10; // move a bit more than needed
|
|
126
|
+
const newPosition = cameraPosition.add(positionDirection.multiplyScalar(lengthToMove));
|
|
127
|
+
camera.worldPosition = newPosition.lerp(cameraPosition, 1 - this.context.time.deltaTime);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Ensure the camera looks at the ViewBox
|
|
131
|
+
// TOOD: smooth lookat over multiple frames if we have multiple viewboxes
|
|
132
|
+
// const dot = direction.normalize().dot(camera.worldForward);
|
|
133
|
+
// if (dot < .9) {
|
|
134
|
+
// console.log(dot);
|
|
135
|
+
// const targetRotation = direction;
|
|
136
|
+
// const rotation = getTempQuaternion();
|
|
137
|
+
// rotation.setFromUnitVectors(camera.worldForward.multiplyScalar(-1), targetRotation);
|
|
138
|
+
// camera.worldQuaternion = rotation;
|
|
139
|
+
// camera.updateMatrixWorld();
|
|
140
|
+
// }
|
|
141
|
+
const boxPositionInCameraSpace = getTempVector(boxPosition);
|
|
142
|
+
camera.worldToLocal(boxPositionInCameraSpace);
|
|
143
|
+
camera.lookAt(boxPosition);
|
|
144
|
+
camera.updateMatrixWorld();
|
|
97
145
|
|
|
98
146
|
|
|
99
|
-
//
|
|
100
|
-
const distance = camera.worldPosition.distanceTo(boxPosition);
|
|
147
|
+
// #region calculate fit
|
|
101
148
|
const vFOV = this.referenceFieldOfView * Math.PI / 180; // convert vertical fov to radians
|
|
102
149
|
const height = 2 * Math.tan(vFOV / 2) * distance; // visible height
|
|
103
150
|
const width = height * camera.aspect; // visible width
|
|
104
151
|
|
|
105
|
-
const projectedBox = this.projectBoxIntoCamera(
|
|
152
|
+
const projectedBox = this.projectBoxIntoCamera(camera, 1);
|
|
153
|
+
// return
|
|
106
154
|
const boxWidth = (projectedBox.maxX - projectedBox.minX);
|
|
107
155
|
const boxHeight = (projectedBox.maxY - projectedBox.minY);
|
|
108
156
|
|
|
109
|
-
// TODO: take the rect size different into account
|
|
110
157
|
const scale = this.fit(
|
|
111
158
|
boxWidth * camera.aspect,
|
|
112
159
|
boxHeight,
|
|
113
160
|
width / diffWidth,
|
|
114
161
|
height / diffHeight
|
|
115
162
|
);
|
|
163
|
+
// console.log({ scale, width, height, boxWidth: boxWidth * camera.aspect, boxHeight, diffWidth, diffHeight, aspect: camera.aspect, distance })
|
|
164
|
+
// this.context.focusRectSettings.zoom = 1.39;
|
|
165
|
+
// if (!this.context.focusRect) this.context.setCameraFocusRect(this.context.domElement);
|
|
166
|
+
// return
|
|
116
167
|
const vec = getTempVector(boxPosition);
|
|
117
168
|
vec.project(camera);
|
|
118
169
|
this.context.focusRectSettings.offsetX = vec.x;
|
|
119
170
|
this.context.focusRectSettings.offsetY = vec.y;
|
|
120
|
-
this.context.focusRectSettings.zoom = scale;
|
|
171
|
+
this.context.focusRectSettings.zoom = scale / (height * .5);
|
|
121
172
|
// if we don't have a focus rect yet, set it to the dom element
|
|
122
173
|
if (!this.context.focusRect) this.context.setCameraFocusRect(this.context.domElement);
|
|
123
174
|
|
|
@@ -149,19 +200,18 @@ export class ViewBox extends Behaviour {
|
|
|
149
200
|
|
|
150
201
|
|
|
151
202
|
|
|
152
|
-
private projectBoxIntoCamera(
|
|
153
|
-
|
|
154
|
-
const factor = .5 * diff;
|
|
203
|
+
private projectBoxIntoCamera(camera: Camera, _factor: number) {
|
|
204
|
+
const factor = .5 * _factor;
|
|
155
205
|
|
|
156
206
|
const corners = [
|
|
157
|
-
getTempVector(-
|
|
158
|
-
getTempVector(
|
|
159
|
-
getTempVector(-
|
|
160
|
-
getTempVector(
|
|
161
|
-
getTempVector(-
|
|
162
|
-
getTempVector(
|
|
163
|
-
getTempVector(-
|
|
164
|
-
getTempVector(
|
|
207
|
+
getTempVector(-factor, -factor, -factor),
|
|
208
|
+
getTempVector(factor, -factor, -factor),
|
|
209
|
+
getTempVector(-factor, factor, -factor),
|
|
210
|
+
getTempVector(factor, factor, -factor),
|
|
211
|
+
getTempVector(-factor, -factor, factor),
|
|
212
|
+
getTempVector(factor, -factor, factor),
|
|
213
|
+
getTempVector(-factor, factor, factor),
|
|
214
|
+
getTempVector(factor, factor, factor),
|
|
165
215
|
];
|
|
166
216
|
let minX = Number.POSITIVE_INFINITY;
|
|
167
217
|
let maxX = Number.NEGATIVE_INFINITY;
|
|
@@ -169,7 +219,7 @@ export class ViewBox extends Behaviour {
|
|
|
169
219
|
let maxY = Number.NEGATIVE_INFINITY;
|
|
170
220
|
for (let i = 0; i < corners.length; i++) {
|
|
171
221
|
const c = corners[i];
|
|
172
|
-
c.
|
|
222
|
+
c.applyMatrix4(this.gameObject.matrixWorld);
|
|
173
223
|
c.project(camera);
|
|
174
224
|
if (c.x < minX) minX = c.x;
|
|
175
225
|
if (c.x > maxX) maxX = c.x;
|
|
@@ -177,18 +227,22 @@ export class ViewBox extends Behaviour {
|
|
|
177
227
|
if (c.y > maxY) maxY = c.y;
|
|
178
228
|
}
|
|
179
229
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
230
|
+
if (debugParam) {
|
|
231
|
+
if (!this._projectedBoxElement) {
|
|
232
|
+
this._projectedBoxElement = document.createElement("div");
|
|
233
|
+
}
|
|
234
|
+
if (this._projectedBoxElement.parentElement !== this.context.domElement)
|
|
235
|
+
this.context.domElement.appendChild(this._projectedBoxElement);
|
|
236
|
+
this._projectedBoxElement.style.position = "fixed";
|
|
237
|
+
// dotted but with larger gaps
|
|
238
|
+
this._projectedBoxElement.style.outline = "2px dashed rgba(255,0,0,.5)";
|
|
239
|
+
this._projectedBoxElement.style.left = ((minX * .5 + .5) * this.context.domWidth) + "px";
|
|
240
|
+
this._projectedBoxElement.style.top = ((-maxY * .5 + .5) * this.context.domHeight) + "px";
|
|
241
|
+
this._projectedBoxElement.style.width = ((maxX - minX) * .5 * this.context.domWidth) + "px";
|
|
242
|
+
this._projectedBoxElement.style.height = ((maxY - minY) * .5 * this.context.domHeight) + "px";
|
|
243
|
+
this._projectedBoxElement.style.pointerEvents = "none";
|
|
244
|
+
this._projectedBoxElement.style.zIndex = "1000";
|
|
245
|
+
}
|
|
192
246
|
|
|
193
247
|
|
|
194
248
|
return { minX, maxX, minY, maxY };
|