@needle-tools/engine 4.10.0-next.4f9d92a → 4.10.0-next.55c0bf9
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-BeZ_xmJa.js → needle-engine.bundle-CUo74dPe.js} +5431 -5613
- package/dist/{needle-engine.bundle-D4dO0t5I.umd.cjs → needle-engine.bundle-Cf5H9Zy9.umd.cjs} +137 -148
- package/dist/{needle-engine.bundle-C3bpSNYu.min.js → needle-engine.bundle-DlAVTipB.min.js} +153 -164
- package/dist/needle-engine.js +257 -258
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/lib/engine/codegen/register_types.js +0 -2
- package/lib/engine/codegen/register_types.js.map +1 -1
- package/lib/engine/engine_camera.d.ts +1 -7
- package/lib/engine/engine_camera.fit.d.ts +1 -1
- package/lib/engine/engine_camera.fit.js +30 -3
- package/lib/engine/engine_camera.fit.js.map +1 -1
- package/lib/engine/engine_camera.js +6 -46
- package/lib/engine/engine_camera.js.map +1 -1
- package/lib/engine/engine_context.d.ts +0 -6
- package/lib/engine/engine_context.js +9 -48
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/extensions/NEEDLE_lightmaps.js +1 -1
- package/lib/engine/extensions/NEEDLE_lightmaps.js.map +1 -1
- package/lib/engine/webcomponents/logo-element.d.ts +1 -1
- package/lib/engine/webcomponents/logo-element.js +5 -29
- package/lib/engine/webcomponents/logo-element.js.map +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.js +3 -4
- package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.loading.d.ts +1 -0
- package/lib/engine/webcomponents/needle-engine.loading.js +36 -3
- package/lib/engine/webcomponents/needle-engine.loading.js.map +1 -1
- package/lib/engine-components/OrbitControls.d.ts +1 -4
- package/lib/engine-components/OrbitControls.js +6 -30
- package/lib/engine-components/OrbitControls.js.map +1 -1
- package/lib/engine-components/Renderer.js +1 -6
- package/lib/engine-components/Renderer.js.map +1 -1
- package/lib/engine-components/codegen/components.d.ts +0 -1
- package/lib/engine-components/codegen/components.js +0 -1
- package/lib/engine-components/codegen/components.js.map +1 -1
- package/lib/engine-components/timeline/PlayableDirector.d.ts +0 -7
- package/lib/engine-components/timeline/PlayableDirector.js +0 -7
- package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
- package/lib/engine-components/timeline/TimelineModels.d.ts +1 -9
- package/lib/engine-components/timeline/TimelineTracks.js +2 -4
- package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
- package/lib/engine-components/utils/LookAt.js +1 -5
- package/lib/engine-components/utils/LookAt.js.map +1 -1
- package/lib/engine-components/web/Clickthrough.js +2 -10
- package/lib/engine-components/web/Clickthrough.js.map +1 -1
- package/lib/engine-components/web/ScrollFollow.d.ts +0 -22
- package/lib/engine-components/web/ScrollFollow.js +13 -124
- package/lib/engine-components/web/ScrollFollow.js.map +1 -1
- package/lib/engine-components/web/index.d.ts +0 -1
- package/lib/engine-components/web/index.js +0 -1
- package/lib/engine-components/web/index.js.map +1 -1
- package/package.json +1 -1
- package/src/engine/codegen/register_types.ts +0 -2
- package/src/engine/engine_camera.fit.ts +32 -2
- package/src/engine/engine_camera.ts +8 -62
- package/src/engine/engine_context.ts +10 -50
- package/src/engine/extensions/NEEDLE_lightmaps.ts +1 -1
- package/src/engine/webcomponents/logo-element.ts +4 -29
- package/src/engine/webcomponents/needle menu/needle-menu.ts +3 -4
- package/src/engine/webcomponents/needle-engine.loading.ts +32 -32
- package/src/engine-components/OrbitControls.ts +1 -40
- package/src/engine-components/Renderer.ts +1 -6
- package/src/engine-components/codegen/components.ts +0 -1
- package/src/engine-components/timeline/PlayableDirector.ts +0 -9
- package/src/engine-components/timeline/TimelineModels.ts +1 -9
- package/src/engine-components/timeline/TimelineTracks.ts +2 -4
- package/src/engine-components/utils/LookAt.ts +1 -5
- package/src/engine-components/web/Clickthrough.ts +2 -11
- package/src/engine-components/web/ScrollFollow.ts +15 -149
- package/src/engine-components/web/index.ts +1 -2
- package/lib/engine-components/web/ViewBox.d.ts +0 -16
- package/lib/engine-components/web/ViewBox.js +0 -186
- package/lib/engine-components/web/ViewBox.js.map +0 -1
- package/src/engine-components/web/ViewBox.ts +0 -202
|
@@ -175,10 +175,8 @@ export class AnimationTrackHandler extends TrackHandler {
|
|
|
175
175
|
// which means we want to notify the object that it's not animated anymore
|
|
176
176
|
// and the animator can then take over
|
|
177
177
|
onStateChanged() {
|
|
178
|
-
if (this._animator)
|
|
179
|
-
|
|
180
|
-
setObjectAnimated(this._animator.gameObject, this, this.director.enabled && this.director.weight > 0);
|
|
181
|
-
}
|
|
178
|
+
if (this._animator)
|
|
179
|
+
setObjectAnimated(this._animator.gameObject, this, this.director.isPlaying);
|
|
182
180
|
}
|
|
183
181
|
|
|
184
182
|
createHooks(clipModel: Models.AnimationClipModel, clip) {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Matrix4, Object3D, Quaternion, Vector3 } from "three";
|
|
2
2
|
|
|
3
|
-
import { isDevEnvironment } from "../../engine/debug/index.js";
|
|
4
3
|
import { serializable } from "../../engine/engine_serialization.js";
|
|
5
4
|
import { lookAtObject } from "../../engine/engine_three_utils.js";
|
|
6
5
|
import { type UsdzBehaviour } from "../../engine-components/export/usdz/extensions/behavior/Behaviour.js";
|
|
@@ -43,10 +42,7 @@ export class LookAt extends Behaviour implements UsdzBehaviour {
|
|
|
43
42
|
/** @internal */
|
|
44
43
|
onBeforeRender(): void {
|
|
45
44
|
let target: Object3D | null | undefined = this.target;
|
|
46
|
-
if (!target)
|
|
47
|
-
target = this.context.mainCamera;
|
|
48
|
-
if (isDevEnvironment()) console.warn(`[LookAt] No target set on ${this.name}, using main camera as target.`);
|
|
49
|
-
}
|
|
45
|
+
if (!target) target = this.context.mainCamera;
|
|
50
46
|
if (!target) return;
|
|
51
47
|
|
|
52
48
|
let copyTargetRotation = this.copyTargetRotation;
|
|
@@ -1,21 +1,12 @@
|
|
|
1
1
|
import { NEPointerEvent } from "../../engine/engine_input.js";
|
|
2
2
|
import { onStart } from "../../engine/engine_lifecycle_api.js";
|
|
3
|
-
import { addAttributeChangeCallback } from "../../engine/engine_utils.js";
|
|
4
3
|
import { Behaviour } from "../Component.js";
|
|
5
4
|
|
|
6
5
|
// Automatically add ClickThrough component if "clickthrough" attribute is present on the needle-engine element
|
|
7
6
|
onStart(ctx => {
|
|
8
7
|
const attribute = ctx.domElement.getAttribute("clickthrough");
|
|
9
|
-
if (
|
|
10
|
-
|
|
11
|
-
addAttributeChangeCallback(ctx.domElement, "clickthrough", () => {
|
|
12
|
-
const attribute = ctx.domElement.getAttribute("clickthrough");
|
|
13
|
-
comp.enabled = clickthroughEnabled(attribute);
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function clickthroughEnabled(val: string | null) {
|
|
18
|
-
return val !== null && val !== "0" && val !== "false";
|
|
8
|
+
if (attribute !== null && attribute !== "0" && attribute !== "false") {
|
|
9
|
+
ctx.scene.addComponent(ClickThrough);
|
|
19
10
|
}
|
|
20
11
|
});
|
|
21
12
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Box3, Object3D } from "three";
|
|
2
2
|
import { element } from "three/src/nodes/TSL.js";
|
|
3
|
-
|
|
4
3
|
import { Context } from "../../engine/engine_context.js";
|
|
4
|
+
|
|
5
5
|
import { Mathf } from "../../engine/engine_math.js";
|
|
6
6
|
import { serializable } from "../../engine/engine_serialization.js";
|
|
7
7
|
import { getBoundingBox } from "../../engine/engine_three_utils.js";
|
|
@@ -150,8 +150,7 @@ export class ScrollFollow extends Behaviour {
|
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
|
|
154
|
-
{
|
|
153
|
+
if (this._current_value !== this._appliedValue) {
|
|
155
154
|
this._appliedValue = this._current_value;
|
|
156
155
|
|
|
157
156
|
let defaultPrevented = false;
|
|
@@ -243,8 +242,7 @@ export class ScrollFollow extends Behaviour {
|
|
|
243
242
|
|
|
244
243
|
if (target instanceof PlayableDirector) {
|
|
245
244
|
this.handleTimelineTarget(target, value);
|
|
246
|
-
if (target.isPlaying) target.
|
|
247
|
-
target.evaluate();
|
|
245
|
+
if (!target.isPlaying) target.evaluate();
|
|
248
246
|
}
|
|
249
247
|
else if (target instanceof Animator) {
|
|
250
248
|
target.setFloat("scroll", value);
|
|
@@ -294,35 +292,18 @@ export class ScrollFollow extends Behaviour {
|
|
|
294
292
|
let scrollRegionEnd = 0;
|
|
295
293
|
markersArray.length = 0;
|
|
296
294
|
|
|
297
|
-
|
|
298
|
-
let markerIndex = 0;
|
|
299
|
-
|
|
300
|
-
// https://scroll-driven-animations.style/tools/view-timeline/ranges
|
|
301
|
-
for (const marker of director.foreachMarker<ScrollMarkerModel & { element?: HTMLElement | null, needsUpdate?: boolean, timeline?: ViewTimeline }>("ScrollMarker")) {
|
|
302
|
-
|
|
303
|
-
const index = markerIndex++;
|
|
295
|
+
for (const marker of director.foreachMarker<ScrollMarkerModel & { element?: HTMLElement | null, needsUpdate?: boolean }>("ScrollMarker")) {
|
|
304
296
|
|
|
305
297
|
// Get marker elements from DOM
|
|
306
|
-
if ((marker.element === undefined || marker.needsUpdate === true || /** element is not in DOM anymore? */ (!marker.element?.parentNode))) {
|
|
298
|
+
if (marker.selector?.length && (marker.element === undefined || marker.needsUpdate === true || /** element is not in DOM anymore? */ (!marker.element?.parentNode))) {
|
|
307
299
|
marker.needsUpdate = false;
|
|
308
300
|
try {
|
|
309
|
-
marker.element =
|
|
310
|
-
if (debug) console.debug("ScrollMarker found on page", marker.element, marker.
|
|
311
|
-
// if (!marker.element) {
|
|
312
|
-
// marker.timeline = undefined;
|
|
313
|
-
// continue;
|
|
314
|
-
// }
|
|
315
|
-
// else {
|
|
316
|
-
// /** @ts-ignore */
|
|
317
|
-
// marker.timeline = new ViewTimeline({
|
|
318
|
-
// subject: marker.element,
|
|
319
|
-
// axis: 'block', // https://drafts.csswg.org/scroll-animations/#scroll-notation
|
|
320
|
-
// });
|
|
321
|
-
// }
|
|
301
|
+
marker.element = document.querySelector<HTMLElement>(marker.selector) || null;
|
|
302
|
+
if (debug) console.debug("ScrollMarker found on page", marker.element, marker.selector);
|
|
322
303
|
}
|
|
323
304
|
catch (error) {
|
|
324
305
|
marker.element = null;
|
|
325
|
-
console.error("ScrollMarker selector is not valid: " + marker.
|
|
306
|
+
console.error("ScrollMarker selector is not valid: " + marker.selector + "\n", error);
|
|
326
307
|
}
|
|
327
308
|
}
|
|
328
309
|
|
|
@@ -350,28 +331,11 @@ export class ScrollFollow extends Behaviour {
|
|
|
350
331
|
weightsArray.length = 0;
|
|
351
332
|
let sum = 0;
|
|
352
333
|
|
|
353
|
-
// We keep a separate count here in case there are some markers that could not be resolved so point to *invalid* elements - the timeline should fallback to 0-1 scroll behaviour then
|
|
354
334
|
let markerCount = 0;
|
|
355
335
|
for (const marker of markersArray) {
|
|
356
336
|
|
|
357
337
|
if (!marker.element) continue;
|
|
358
338
|
|
|
359
|
-
markerCount += 1;
|
|
360
|
-
|
|
361
|
-
// const timeline = marker.timeline;
|
|
362
|
-
// if (timeline) {
|
|
363
|
-
// const time01 = calculateTimelinePositionNormalized(timeline);
|
|
364
|
-
// if (time01 > 0 && time01 <= 1) {
|
|
365
|
-
// const overlap = calculateTimelinePositionNormalized(timeline!);
|
|
366
|
-
// const weight = overlap;
|
|
367
|
-
// // console.log(marker.element.className, time01)
|
|
368
|
-
// weightsArray.push({ time: marker.time, weight: weight });
|
|
369
|
-
// sum += weight;
|
|
370
|
-
// }
|
|
371
|
-
// }
|
|
372
|
-
// continue;
|
|
373
|
-
// if(this.context.time.frame % 10 === 0) console.log(marker.element?.className, timeline, calculateTimelinePositionNormalized(timeline!));
|
|
374
|
-
|
|
375
339
|
const top = marker.element.offsetTop;
|
|
376
340
|
const height = marker.element.offsetHeight;
|
|
377
341
|
const bottom = top + height;
|
|
@@ -392,6 +356,7 @@ export class ScrollFollow extends Behaviour {
|
|
|
392
356
|
const overlapTop = Math.max(top, currentTop);
|
|
393
357
|
const overlapBottom = Math.min(bottom, currentBottom);
|
|
394
358
|
overlap = Math.max(0, overlapBottom - overlapTop);
|
|
359
|
+
// console.log(marker.element.className, overlap)
|
|
395
360
|
}
|
|
396
361
|
|
|
397
362
|
markerCount += 1;
|
|
@@ -407,124 +372,25 @@ export class ScrollFollow extends Behaviour {
|
|
|
407
372
|
}
|
|
408
373
|
else if (weightsArray.length > 0) {
|
|
409
374
|
// normalize and calculate weighted time
|
|
410
|
-
let time = 0;
|
|
411
|
-
for (const
|
|
412
|
-
const weight =
|
|
413
|
-
// console.log(weight.toFixed(2))
|
|
375
|
+
let time = weightsArray[0].time;
|
|
376
|
+
for (const o of weightsArray) {
|
|
377
|
+
const weight = o.weight / Math.max(0.00001, sum);
|
|
414
378
|
// lerp time based on weight
|
|
415
|
-
const diff = Math.abs(
|
|
379
|
+
const diff = Math.abs(o.time - time);
|
|
416
380
|
time += diff * weight;
|
|
417
381
|
}
|
|
418
|
-
|
|
419
|
-
if (this.damping <= 0)
|
|
420
|
-
director.time = time;
|
|
421
|
-
else
|
|
422
|
-
director.time = Mathf.lerp(director.time, time, this.context.time.deltaTime / this.damping);
|
|
382
|
+
director.time = time;
|
|
423
383
|
}
|
|
424
384
|
}
|
|
425
385
|
|
|
426
386
|
}
|
|
427
387
|
|
|
428
|
-
|
|
429
|
-
|
|
430
388
|
const weightsArray: OverlapInfo[] = [];
|
|
431
|
-
const markersArray: (ScrollMarkerModel & { element?: HTMLElement | null
|
|
389
|
+
const markersArray: (ScrollMarkerModel & { element?: HTMLElement | null })[] = [];
|
|
432
390
|
|
|
433
391
|
type OverlapInfo = {
|
|
434
392
|
/** Marker time */
|
|
435
393
|
time: number,
|
|
436
394
|
/** Overlap in pixels */
|
|
437
395
|
weight: number,
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
// type SelectorCache = {
|
|
442
|
-
// /** The selector used to query the *elements */
|
|
443
|
-
// selector: string,
|
|
444
|
-
// elements: Element[] | null,
|
|
445
|
-
// usedElementCount: number,
|
|
446
|
-
// }
|
|
447
|
-
// const querySelectorResults: Array<SelectorCache> = [];
|
|
448
|
-
|
|
449
|
-
const needleScrollMarkerCacheKey = "data-timeline-marker";
|
|
450
|
-
const needleScrollMarkerIndexCache = new Map<number, Element | null>();
|
|
451
|
-
const needleScrollMarkerNameCache = new Map<string, Element | null>();
|
|
452
|
-
let needsScrollMarkerRefresh = true;
|
|
453
|
-
|
|
454
|
-
function tryGetElementsForSelector(index: number, name: string): Element | null {
|
|
455
|
-
|
|
456
|
-
if (!needsScrollMarkerRefresh) {
|
|
457
|
-
let element = name?.length ? needleScrollMarkerNameCache.get(name) : null;
|
|
458
|
-
if (element) return element;
|
|
459
|
-
element = needleScrollMarkerIndexCache.get(index) || null;
|
|
460
|
-
return element;
|
|
461
|
-
}
|
|
462
|
-
needsScrollMarkerRefresh = false;
|
|
463
|
-
needleScrollMarkerIndexCache.clear();
|
|
464
|
-
const markers = document.querySelectorAll(`[data-timeline-marker]`);
|
|
465
|
-
markers.forEach((m, i) => {
|
|
466
|
-
needleScrollMarkerIndexCache.set(i, m);
|
|
467
|
-
const name = m.getAttribute("data-timeline-marker");
|
|
468
|
-
if (name?.length) needleScrollMarkerNameCache.set(name, m);
|
|
469
|
-
});
|
|
470
|
-
const element = needleScrollMarkerIndexCache.get(index) || null;
|
|
471
|
-
return element;
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
/* e.g.
|
|
475
|
-
<div class="section behind start" data-needle-scroll-marker>
|
|
476
|
-
*/
|
|
477
|
-
// console.log(index, element)
|
|
478
|
-
if (element) return element;
|
|
479
|
-
|
|
480
|
-
// for (const entry of querySelectorResults) {
|
|
481
|
-
// if (entry.selector === selector) {
|
|
482
|
-
// const index = entry.usedElementCount++;
|
|
483
|
-
// return entry.elements && index < entry.elements.length ? entry.elements[index] : null;
|
|
484
|
-
// }
|
|
485
|
-
// }
|
|
486
|
-
// const elements = document.querySelectorAll(selector);
|
|
487
|
-
// querySelectorResults.push({ selector, elements: Array.from(elements), usedElementCount: 1 });
|
|
488
|
-
// if (elements.length > 0) return elements[0];
|
|
489
|
-
return null;
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
// #region ScrollTimeline
|
|
494
|
-
|
|
495
|
-
function calculateTimelinePositionNormalized(timeline: ViewTimeline) {
|
|
496
|
-
if (!timeline.source) return 0;
|
|
497
|
-
const currentTime = timeline.currentTime;
|
|
498
|
-
const duration = timeline.duration;
|
|
499
|
-
let durationValue = 1;
|
|
500
|
-
if (duration.unit === "seconds") {
|
|
501
|
-
durationValue = duration.value;
|
|
502
|
-
}
|
|
503
|
-
else if (duration.unit === "percent") {
|
|
504
|
-
durationValue = duration.value;
|
|
505
|
-
}
|
|
506
|
-
const t01 = currentTime.unit === "seconds" ? (currentTime.value / durationValue) : (currentTime.value / 100);
|
|
507
|
-
return t01;
|
|
508
|
-
}
|
|
509
|
-
function calculateNormalizedOverlap(timeline: ViewTimeline) {
|
|
510
|
-
if (!timeline.source) return 0;
|
|
511
|
-
const start = timeline.startOffset;
|
|
512
|
-
const end = timeline.endOffset;
|
|
513
|
-
const total = start.value + end.value;
|
|
514
|
-
if (total <= 0) return 1;
|
|
515
|
-
const startNorm = start.value / total;
|
|
516
|
-
const endNorm = end.value / total;
|
|
517
|
-
return 1 - (startNorm + endNorm);
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
declare global {
|
|
522
|
-
interface ViewTimeline {
|
|
523
|
-
axis: 'block' | 'inline';
|
|
524
|
-
currentTime: { unit: 'seconds' | 'percent', value: number };
|
|
525
|
-
duration: { unit: 'seconds' | 'percent', value: number };
|
|
526
|
-
source: Element | null;
|
|
527
|
-
startOffset: { unit: 'px', value: number };
|
|
528
|
-
endOffset: { unit: 'px', value: number };
|
|
529
|
-
}
|
|
530
396
|
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { Behaviour } from "../Component.js";
|
|
2
|
-
export declare class ViewBox extends Behaviour {
|
|
3
|
-
static instances: ViewBox[];
|
|
4
|
-
referenceFieldOfView: number;
|
|
5
|
-
debug: boolean;
|
|
6
|
-
awake(): void;
|
|
7
|
-
onEnable(): void;
|
|
8
|
-
onDisable(): void;
|
|
9
|
-
onBeforeRender(): void;
|
|
10
|
-
/**
|
|
11
|
-
* Cover fit
|
|
12
|
-
*/
|
|
13
|
-
private fit;
|
|
14
|
-
private projectBoxIntoCamera;
|
|
15
|
-
private _projectedBoxElement;
|
|
16
|
-
}
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
};
|
|
7
|
-
var ViewBox_1;
|
|
8
|
-
import { PerspectiveCamera } from "three";
|
|
9
|
-
import { isDevEnvironment } from "../../engine/debug/debug.js";
|
|
10
|
-
import { Gizmos } from "../../engine/engine_gizmos.js";
|
|
11
|
-
import { serializable } from "../../engine/engine_serialization_decorator.js";
|
|
12
|
-
import { getTempVector } from "../../engine/engine_three_utils.js";
|
|
13
|
-
import { registerType } from "../../engine/engine_typestore.js";
|
|
14
|
-
import { getParam } from "../../engine/engine_utils.js";
|
|
15
|
-
import { Behaviour } from "../Component.js";
|
|
16
|
-
const debugParam = getParam("debugviewbox");
|
|
17
|
-
let ViewBox = ViewBox_1 = class ViewBox extends Behaviour {
|
|
18
|
-
static instances = [];
|
|
19
|
-
referenceFieldOfView = 60;
|
|
20
|
-
debug = false;
|
|
21
|
-
awake() {
|
|
22
|
-
// this.referenceFieldOfView = (this.context.mainCamera as PerspectiveCamera)?.fov || 60;
|
|
23
|
-
// setInterval(()=>{
|
|
24
|
-
// this.enabled = !this.enabled
|
|
25
|
-
// }, 1000)
|
|
26
|
-
}
|
|
27
|
-
onEnable() {
|
|
28
|
-
if (debugParam || this.debug || isDevEnvironment())
|
|
29
|
-
console.debug("[ViewBox] Using camera fov:", this.referenceFieldOfView);
|
|
30
|
-
ViewBox_1.instances.push(this);
|
|
31
|
-
}
|
|
32
|
-
onDisable() {
|
|
33
|
-
const idx = ViewBox_1.instances.indexOf(this);
|
|
34
|
-
if (idx !== -1)
|
|
35
|
-
ViewBox_1.instances.splice(idx, 1);
|
|
36
|
-
}
|
|
37
|
-
onBeforeRender() {
|
|
38
|
-
if (this.context.isInXR)
|
|
39
|
-
return;
|
|
40
|
-
const isActive = ViewBox_1.instances[ViewBox_1.instances.length - 1] === this;
|
|
41
|
-
if (!isActive) {
|
|
42
|
-
if (debugParam || this.debug)
|
|
43
|
-
Gizmos.DrawWireBox(this.gameObject.worldPosition, this.gameObject.worldScale, 0x333333);
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
if (debugParam || this.debug)
|
|
47
|
-
Gizmos.DrawWireBox(this.gameObject.worldPosition, this.gameObject.worldScale, 0xdddd00);
|
|
48
|
-
// calculate box size to fit the camera frustrum size at the current position (just scale)
|
|
49
|
-
const camera = this.context.mainCamera;
|
|
50
|
-
if (!camera)
|
|
51
|
-
return;
|
|
52
|
-
if (!(camera instanceof PerspectiveCamera)) {
|
|
53
|
-
// TODO: support orthographic camera
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
if (this.referenceFieldOfView === undefined || this.referenceFieldOfView <= 0) {
|
|
57
|
-
if (debugParam || this.debug)
|
|
58
|
-
console.warn("[ViewBox] No valid referenceFieldOfView set, cannot adjust box size:", this.referenceFieldOfView);
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
const domWidth = this.context.domWidth;
|
|
62
|
-
const domHeight = this.context.domHeight;
|
|
63
|
-
let rectPosX = 0;
|
|
64
|
-
let rectPosY = 0;
|
|
65
|
-
let rectWidth = domWidth;
|
|
66
|
-
let rectHeight = domHeight;
|
|
67
|
-
let diffWidth = 1;
|
|
68
|
-
let diffHeight = 1;
|
|
69
|
-
// use focus rect if available
|
|
70
|
-
const focusRectSize = this.context.focusRectSize;
|
|
71
|
-
if (focusRectSize) {
|
|
72
|
-
// console.log(focusRectSize)
|
|
73
|
-
rectPosX = focusRectSize.x;
|
|
74
|
-
rectPosY = focusRectSize.y;
|
|
75
|
-
rectWidth = focusRectSize.width;
|
|
76
|
-
rectHeight = focusRectSize.height;
|
|
77
|
-
diffWidth = domWidth / rectWidth;
|
|
78
|
-
diffHeight = domHeight / rectHeight;
|
|
79
|
-
}
|
|
80
|
-
// const view = camera.view;
|
|
81
|
-
const view = camera.view;
|
|
82
|
-
const zoom = camera.zoom;
|
|
83
|
-
const aspect = camera.aspect;
|
|
84
|
-
const fov = camera.fov;
|
|
85
|
-
camera.view = null;
|
|
86
|
-
camera.zoom = 1;
|
|
87
|
-
// camera.aspect = rectWidth / rectHeight;
|
|
88
|
-
camera.fov = this.referenceFieldOfView;
|
|
89
|
-
camera.updateProjectionMatrix();
|
|
90
|
-
const boxPosition = this.gameObject.worldPosition;
|
|
91
|
-
const boxScale = this.gameObject.worldScale;
|
|
92
|
-
// const fov = this.referenceFieldOfView
|
|
93
|
-
const distance = camera.worldPosition.distanceTo(boxPosition);
|
|
94
|
-
const vFOV = this.referenceFieldOfView * Math.PI / 180; // convert vertical fov to radians
|
|
95
|
-
const height = 2 * Math.tan(vFOV / 2) * distance; // visible height
|
|
96
|
-
const width = height * camera.aspect; // visible width
|
|
97
|
-
const projectedBox = this.projectBoxIntoCamera(boxPosition, boxScale, camera, height * .5);
|
|
98
|
-
const boxWidth = (projectedBox.maxX - projectedBox.minX);
|
|
99
|
-
const boxHeight = (projectedBox.maxY - projectedBox.minY);
|
|
100
|
-
// TODO: take the rect size different into account
|
|
101
|
-
const scale = this.fit(boxWidth * camera.aspect, boxHeight, width / diffWidth, height / diffHeight);
|
|
102
|
-
const vec = getTempVector(boxPosition);
|
|
103
|
-
vec.project(camera);
|
|
104
|
-
this.context.focusRectSettings.offsetX = vec.x;
|
|
105
|
-
this.context.focusRectSettings.offsetY = vec.y;
|
|
106
|
-
this.context.focusRectSettings.zoom = scale;
|
|
107
|
-
// if we don't have a focus rect yet, set it to the dom element
|
|
108
|
-
if (!this.context.focusRect)
|
|
109
|
-
this.context.setCameraFocusRect(this.context.domElement);
|
|
110
|
-
// Reset values
|
|
111
|
-
camera.view = view;
|
|
112
|
-
camera.zoom = zoom;
|
|
113
|
-
camera.aspect = aspect;
|
|
114
|
-
camera.fov = fov;
|
|
115
|
-
// camera.updateProjectionMatrix();
|
|
116
|
-
// BACKLOG: some code for box scale of an object (different component)
|
|
117
|
-
// this.gameObject.worldScale = getTempVector(width, height, worldscale.z);
|
|
118
|
-
// this.gameObject.scale.multiplyScalar(.98)
|
|
119
|
-
// const minscale = Math.min(width, height);
|
|
120
|
-
// console.log(width, height);
|
|
121
|
-
// this.gameObject.worldScale = getTempVector(scale, scale, scale);
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Cover fit
|
|
125
|
-
*/
|
|
126
|
-
fit(width1, height1, width2, height2) {
|
|
127
|
-
const scaleX = width2 / width1;
|
|
128
|
-
const scaleY = height2 / height1;
|
|
129
|
-
return Math.min(scaleX, scaleY);
|
|
130
|
-
}
|
|
131
|
-
projectBoxIntoCamera(position, scale, camera, diff) {
|
|
132
|
-
const factor = .5 * diff;
|
|
133
|
-
const corners = [
|
|
134
|
-
getTempVector(-scale.x * factor, -scale.y * factor, -scale.z * factor),
|
|
135
|
-
getTempVector(scale.x * factor, -scale.y * factor, -scale.z * factor),
|
|
136
|
-
getTempVector(-scale.x * factor, scale.y * factor, -scale.z * factor),
|
|
137
|
-
getTempVector(scale.x * factor, scale.y * factor, -scale.z * factor),
|
|
138
|
-
getTempVector(-scale.x * factor, -scale.y * factor, scale.z * factor),
|
|
139
|
-
getTempVector(scale.x * factor, -scale.y * factor, scale.z * factor),
|
|
140
|
-
getTempVector(-scale.x * factor, scale.y * factor, scale.z * factor),
|
|
141
|
-
getTempVector(scale.x * factor, scale.y * factor, scale.z * factor),
|
|
142
|
-
];
|
|
143
|
-
let minX = Number.POSITIVE_INFINITY;
|
|
144
|
-
let maxX = Number.NEGATIVE_INFINITY;
|
|
145
|
-
let minY = Number.POSITIVE_INFINITY;
|
|
146
|
-
let maxY = Number.NEGATIVE_INFINITY;
|
|
147
|
-
for (let i = 0; i < corners.length; i++) {
|
|
148
|
-
const c = corners[i];
|
|
149
|
-
c.add(position);
|
|
150
|
-
c.project(camera);
|
|
151
|
-
if (c.x < minX)
|
|
152
|
-
minX = c.x;
|
|
153
|
-
if (c.x > maxX)
|
|
154
|
-
maxX = c.x;
|
|
155
|
-
if (c.y < minY)
|
|
156
|
-
minY = c.y;
|
|
157
|
-
if (c.y > maxY)
|
|
158
|
-
maxY = c.y;
|
|
159
|
-
}
|
|
160
|
-
// if(!this._projectedBoxElement) {
|
|
161
|
-
// this._projectedBoxElement = document.createElement("div");
|
|
162
|
-
// this.context.domElement.appendChild(this._projectedBoxElement);
|
|
163
|
-
// }
|
|
164
|
-
// this._projectedBoxElement.style.position = "fixed";
|
|
165
|
-
// this._projectedBoxElement.style.outline = "10px solid red";
|
|
166
|
-
// this._projectedBoxElement.style.left = ((minX * .5 + .5) * this.context.domWidth) + "px";
|
|
167
|
-
// this._projectedBoxElement.style.top = ((-maxY * .5 + .5) * this.context.domHeight) + "px";
|
|
168
|
-
// this._projectedBoxElement.style.width = ((maxX - minX) * .5 * this.context.domWidth) + "px";
|
|
169
|
-
// this._projectedBoxElement.style.height = ((maxY - minY) * .5 * this.context.domHeight) + "px";
|
|
170
|
-
// this._projectedBoxElement.style.pointerEvents = "none";
|
|
171
|
-
// this._projectedBoxElement.style.zIndex = "1000";
|
|
172
|
-
return { minX, maxX, minY, maxY };
|
|
173
|
-
}
|
|
174
|
-
_projectedBoxElement = null;
|
|
175
|
-
};
|
|
176
|
-
__decorate([
|
|
177
|
-
serializable()
|
|
178
|
-
], ViewBox.prototype, "referenceFieldOfView", void 0);
|
|
179
|
-
__decorate([
|
|
180
|
-
serializable()
|
|
181
|
-
], ViewBox.prototype, "debug", void 0);
|
|
182
|
-
ViewBox = ViewBox_1 = __decorate([
|
|
183
|
-
registerType
|
|
184
|
-
], ViewBox);
|
|
185
|
-
export { ViewBox };
|
|
186
|
-
//# sourceMappingURL=ViewBox.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ViewBox.js","sourceRoot":"","sources":["../../../src/engine-components/web/ViewBox.ts"],"names":[],"mappings":"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"}
|