@@ -95,6 +95,7 @@
|
|
95
95
|
import { NoiseModule } from "../../engine-components/ParticleSystemModules";
|
96
96
|
import { ObjectRaycaster } from "../../engine-components/ui/Raycaster";
|
97
97
|
import { OffsetConstraint } from "../../engine-components/OffsetConstraint";
|
98
|
+
import { OpenURL } from "../../engine-components/utils/OpenURL";
|
98
99
|
import { OrbitControls } from "../../engine-components/OrbitControls";
|
99
100
|
import { ParticleBurst } from "../../engine-components/ParticleSystemModules";
|
100
101
|
import { ParticleSubEmitter } from "../../engine-components/ParticleSystemSubEmitter";
|
@@ -284,6 +285,7 @@
|
|
284
285
|
TypeStore.add("NoiseModule", NoiseModule);
|
285
286
|
TypeStore.add("ObjectRaycaster", ObjectRaycaster);
|
286
287
|
TypeStore.add("OffsetConstraint", OffsetConstraint);
|
288
|
+
TypeStore.add("OpenURL", OpenURL);
|
287
289
|
TypeStore.add("OrbitControls", OrbitControls);
|
288
290
|
TypeStore.add("ParticleBurst", ParticleBurst);
|
289
291
|
TypeStore.add("ParticleSubEmitter", ParticleSubEmitter);
|
@@ -93,6 +93,7 @@
|
|
93
93
|
export { NoiseModule } from "../ParticleSystemModules";
|
94
94
|
export { ObjectRaycaster } from "../ui/Raycaster";
|
95
95
|
export { OffsetConstraint } from "../OffsetConstraint";
|
96
|
+
export { OpenURL } from "../utils/OpenURL";
|
96
97
|
export { OrbitControls } from "../OrbitControls";
|
97
98
|
export { ParticleBurst } from "../ParticleSystemModules";
|
98
99
|
export { ParticleSubEmitter } from "../ParticleSystemSubEmitter";
|
@@ -6,14 +6,14 @@
|
|
6
6
|
import { Context } from "../../engine/engine_setup";
|
7
7
|
import { OrbitControls } from "../OrbitControls";
|
8
8
|
import { IPointerEventHandler, PointerEventData } from "./PointerEvents";
|
9
|
-
import { Raycaster } from "./Raycaster";
|
9
|
+
import { ObjectRaycaster, Raycaster } from "./Raycaster";
|
10
10
|
import { InputEvents } from "../../engine/engine_input";
|
11
11
|
import { Object3D } from "three";
|
12
12
|
import { ICanvasGroup, IGraphic } from "./Interfaces";
|
13
13
|
import { getParam } from "../../engine/engine_utils";
|
14
14
|
import { UIRaycastUtils } from "./RaycastUtils";
|
15
15
|
import { $shadowDomOwner } from "./BaseUIComponent";
|
16
|
-
import { showBalloonMessage, showBalloonWarning } from "../../engine/debug";
|
16
|
+
import { isDevEnvironment, showBalloonMessage, showBalloonWarning } from "../../engine/debug";
|
17
17
|
|
18
18
|
const debug = getParam("debugeventsystem");
|
19
19
|
|
@@ -86,9 +86,15 @@
|
|
86
86
|
}
|
87
87
|
|
88
88
|
start() {
|
89
|
-
|
90
|
-
|
91
|
-
|
89
|
+
if (this.raycaster.length <= 0) {
|
90
|
+
const res = GameObject.findObjectOfType(Raycaster, this.context);
|
91
|
+
if (!res) {
|
92
|
+
const rc = GameObject.addNewComponent(this.context.scene, ObjectRaycaster);
|
93
|
+
this.raycaster.push(rc);
|
94
|
+
if (isDevEnvironment())
|
95
|
+
console.warn("Added an ObjectRaycaster to the scene because no raycaster was found", this);
|
96
|
+
}
|
97
|
+
}
|
92
98
|
}
|
93
99
|
|
94
100
|
register(rc: Raycaster) {
|
@@ -1,6 +1,5 @@
|
|
1
1
|
import { delay, getParam, isiOS, isMobileDevice, isSafari } from "../../../engine/engine_utils";
|
2
|
-
import { Object3D, Color } from "three";
|
3
|
-
import * as THREE from "three";
|
2
|
+
import { Object3D, Color, Mesh, Matrix4 } from "three";
|
4
3
|
import { USDZExporter as ThreeUSDZExporter } from "three/examples/jsm/exporters/USDZExporter";
|
5
4
|
import { AnimationExtension } from "./extensions/Animation"
|
6
5
|
import { ensureQuicklookLinkIsCreated } from "./utils/quicklook";
|
@@ -72,7 +71,7 @@
|
|
72
71
|
if (!this.objectToExport) this.objectToExport = this.gameObject;
|
73
72
|
|
74
73
|
|
75
|
-
if (isDevEnvironment() && (!this.objectToExport
|
74
|
+
if (isDevEnvironment() && (!this.objectToExport?.children?.length && !(this.objectToExport as Mesh)?.isMesh)) {
|
76
75
|
showBalloonWarning("USDZ Exporter has nothing to export");
|
77
76
|
console.warn("USDZExporter has no objects to export assigned:", this)
|
78
77
|
}
|
@@ -114,7 +113,7 @@
|
|
114
113
|
const scale = 1 / this.webARSessionRoot!.arScale;
|
115
114
|
scene.matrix.makeScale(scale, scale, scale);
|
116
115
|
if (this.webARSessionRoot.invertForward) {
|
117
|
-
scene.matrix.multiply(new
|
116
|
+
scene.matrix.multiply(new Matrix4().makeRotationY(Math.PI));
|
118
117
|
}
|
119
118
|
}
|
120
119
|
|
@@ -0,0 +1,119 @@
|
|
1
|
+
|
2
|
+
import { IPointerClickHandler, PointerEventData } from "../ui";
|
3
|
+
import { Behaviour } from "../Component";
|
4
|
+
import { serializable } from "../../engine/engine_serialization";
|
5
|
+
import { isDevEnvironment, showBalloonMessage } from "../../engine/debug";
|
6
|
+
import { isSafari } from "../../engine/engine_utils";
|
7
|
+
import { ObjectRaycaster, Raycaster } from "../ui/Raycaster";
|
8
|
+
import { tryGetUIComponent } from "../ui/Utils";
|
9
|
+
|
10
|
+
export enum OpenURLMode {
|
11
|
+
NewTab = 0,
|
12
|
+
SameTab = 1,
|
13
|
+
NewWindow = 2
|
14
|
+
}
|
15
|
+
|
16
|
+
export class OpenURL extends Behaviour implements IPointerClickHandler {
|
17
|
+
|
18
|
+
@serializable()
|
19
|
+
clickable: boolean = true;
|
20
|
+
|
21
|
+
@serializable()
|
22
|
+
url?: string;
|
23
|
+
|
24
|
+
@serializable()
|
25
|
+
mode: OpenURLMode = OpenURLMode.NewTab;
|
26
|
+
|
27
|
+
async open() {
|
28
|
+
if (!this.url) {
|
29
|
+
console.error("URL is not set", this);
|
30
|
+
return;
|
31
|
+
}
|
32
|
+
|
33
|
+
this._validateUrl();
|
34
|
+
|
35
|
+
if (isDevEnvironment()) showBalloonMessage("Open URL: " + this.url)
|
36
|
+
|
37
|
+
|
38
|
+
switch (this.mode) {
|
39
|
+
case OpenURLMode.NewTab:
|
40
|
+
if (isSafari()) {
|
41
|
+
globalThis.open(this.url, "_blank");
|
42
|
+
}
|
43
|
+
else
|
44
|
+
globalThis.open(this.url, "_blank");
|
45
|
+
break;
|
46
|
+
case OpenURLMode.SameTab:
|
47
|
+
if (isSafari()) {
|
48
|
+
globalThis.open(this.url, "_top");
|
49
|
+
}
|
50
|
+
else globalThis.open(this.url, "_self");
|
51
|
+
break;
|
52
|
+
case OpenURLMode.NewWindow:
|
53
|
+
if (isSafari()) {
|
54
|
+
globalThis.open(this.url, "_top");
|
55
|
+
}
|
56
|
+
else globalThis.open(this.url, "_new");
|
57
|
+
break;
|
58
|
+
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
start(): void {
|
63
|
+
const raycaster = this.gameObject.getComponentInParent(ObjectRaycaster);
|
64
|
+
if (!raycaster) this.gameObject.addNewComponent(ObjectRaycaster);
|
65
|
+
}
|
66
|
+
|
67
|
+
onEnable(): void {
|
68
|
+
if (isSafari()) window.addEventListener("touchend", this._safariNewTabWorkaround);
|
69
|
+
}
|
70
|
+
onDisable(): void {
|
71
|
+
if (isSafari()) window.removeEventListener("touchend", this._safariNewTabWorkaround);
|
72
|
+
}
|
73
|
+
|
74
|
+
onPointerEnter(args) {
|
75
|
+
if (!args.used && this.clickable)
|
76
|
+
this.context.input.setCursorPointer();
|
77
|
+
}
|
78
|
+
onPointerExit() {
|
79
|
+
if (this.clickable)
|
80
|
+
this.context.input.setCursorNormal();
|
81
|
+
}
|
82
|
+
onPointerClick(args: PointerEventData) {
|
83
|
+
if (this.clickable && !args.used && this.url?.length)
|
84
|
+
this.open();
|
85
|
+
}
|
86
|
+
|
87
|
+
private _safariNewTabWorkaround = () => {
|
88
|
+
if (!this.clickable || !this.url?.length) return;
|
89
|
+
// we only need this workaround for opening a new tab
|
90
|
+
if (this.mode === OpenURLMode.SameTab) return;
|
91
|
+
// When we process the click directly in the browser event we can open a new tab
|
92
|
+
// by emitting a link attribute and calling onClick
|
93
|
+
const raycaster = this.gameObject.getComponentInParent(Raycaster);
|
94
|
+
if (raycaster) {
|
95
|
+
const hits = raycaster.performRaycast();
|
96
|
+
if (!hits) return;
|
97
|
+
for (const hit of hits) {
|
98
|
+
if (hit.object === this.gameObject || tryGetUIComponent(hit.object)?.gameObject === this.gameObject) {
|
99
|
+
this._validateUrl();
|
100
|
+
var a = document.createElement('a') as HTMLAnchorElement;
|
101
|
+
a.setAttribute("target", "_blank");
|
102
|
+
a.setAttribute("href", this.url);
|
103
|
+
a.click();
|
104
|
+
break;
|
105
|
+
}
|
106
|
+
}
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
private _validateUrl() {
|
111
|
+
if (!this.url) return;
|
112
|
+
if (this.url.startsWith("www.")) {
|
113
|
+
if (isDevEnvironment()) {
|
114
|
+
console.warn("URL is not valid, adding https:// to the start of the URL", this.url);
|
115
|
+
}
|
116
|
+
this.url = "https://" + this.url;
|
117
|
+
}
|
118
|
+
}
|
119
|
+
}
|