@needle-tools/engine 3.2.14-alpha → 3.3.0-alpha
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/CHANGELOG.md +17 -0
- package/dist/needle-engine.js +42139 -35749
- package/dist/needle-engine.min.js +694 -516
- package/dist/needle-engine.umd.cjs +696 -518
- package/lib/engine/codegen/register_types.js +4 -2
- package/lib/engine/codegen/register_types.js.map +1 -1
- package/lib/engine/engine_addressables.d.ts +3 -3
- package/lib/engine/engine_addressables.js +30 -9
- package/lib/engine/engine_addressables.js.map +1 -1
- package/lib/engine/engine_element.js +1 -1
- package/lib/engine/engine_element.js.map +1 -1
- package/lib/engine/engine_gameobject.d.ts +2 -1
- package/lib/engine/engine_gameobject.js +17 -0
- package/lib/engine/engine_gameobject.js.map +1 -1
- package/lib/engine/engine_input.js +10 -0
- package/lib/engine/engine_input.js.map +1 -1
- package/lib/engine/engine_license.js +11 -24
- package/lib/engine/engine_license.js.map +1 -1
- package/lib/engine/engine_math.d.ts +4 -0
- package/lib/engine/engine_math.js +6 -0
- package/lib/engine/engine_math.js.map +1 -1
- package/lib/engine-components/AnimatorController.js +7 -2
- package/lib/engine-components/AnimatorController.js.map +1 -1
- package/lib/engine-components/OrbitControls.js +13 -4
- package/lib/engine-components/OrbitControls.js.map +1 -1
- package/lib/engine-components/SceneSwitcher.d.ts +1 -1
- package/lib/engine-components/SceneSwitcher.js +25 -1
- package/lib/engine-components/SceneSwitcher.js.map +1 -1
- package/lib/engine-components/TransformGizmo.d.ts +8 -4
- package/lib/engine-components/TransformGizmo.js +62 -63
- package/lib/engine-components/TransformGizmo.js.map +1 -1
- package/lib/engine-components/codegen/components.d.ts +2 -1
- package/lib/engine-components/codegen/components.js +2 -1
- package/lib/engine-components/codegen/components.js.map +1 -1
- package/lib/engine-components/export/usdz/USDZExporter.d.ts +1 -0
- package/lib/engine-components/export/usdz/USDZExporter.js +10 -2
- package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
- package/lib/engine-components/ui/Button.js +9 -5
- package/lib/engine-components/ui/Button.js.map +1 -1
- package/lib/engine-components/ui/Canvas.d.ts +13 -6
- package/lib/engine-components/ui/Canvas.js +101 -37
- package/lib/engine-components/ui/Canvas.js.map +1 -1
- package/lib/engine-components/ui/EventSystem.d.ts +6 -0
- package/lib/engine-components/ui/EventSystem.js +4 -4
- package/lib/engine-components/ui/EventSystem.js.map +1 -1
- package/lib/engine-components/ui/Graphic.d.ts +5 -2
- package/lib/engine-components/ui/Graphic.js +38 -7
- package/lib/engine-components/ui/Graphic.js.map +1 -1
- package/lib/engine-components/ui/Image.d.ts +1 -0
- package/lib/engine-components/ui/Image.js +10 -1
- package/lib/engine-components/ui/Image.js.map +1 -1
- package/lib/engine-components/ui/InputField.d.ts +1 -0
- package/lib/engine-components/ui/InputField.js +8 -0
- package/lib/engine-components/ui/InputField.js.map +1 -1
- package/lib/engine-components/ui/Interfaces.d.ts +8 -0
- package/lib/engine-components/ui/Outline.d.ts +7 -0
- package/lib/engine-components/ui/Outline.js +21 -0
- package/lib/engine-components/ui/Outline.js.map +1 -0
- package/lib/engine-components/ui/RectTransform.d.ts +29 -11
- package/lib/engine-components/ui/RectTransform.js +178 -46
- package/lib/engine-components/ui/RectTransform.js.map +1 -1
- package/lib/engine-components/ui/Text.d.ts +13 -10
- package/lib/engine-components/ui/Text.js +177 -246
- package/lib/engine-components/ui/Text.js.map +1 -1
- package/lib/engine-components/utils/LookAt.d.ts +7 -0
- package/lib/engine-components/utils/LookAt.js +29 -0
- package/lib/engine-components/utils/LookAt.js.map +1 -0
- package/lib/engine-components/webxr/WebXRImageTracking.d.ts +8 -0
- package/lib/engine-components/webxr/WebXRImageTracking.js +79 -3
- package/lib/engine-components/webxr/WebXRImageTracking.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/engine/codegen/register_types.js +4 -2
- package/src/engine/engine_addressables.ts +28 -10
- package/src/engine/engine_element.ts +1 -1
- package/src/engine/engine_gameobject.ts +18 -1
- package/src/engine/engine_input.ts +11 -0
- package/src/engine/engine_license.ts +12 -25
- package/src/engine/engine_math.ts +10 -0
- package/src/engine-components/AnimatorController.ts +7 -1
- package/src/engine-components/OrbitControls.ts +14 -6
- package/src/engine-components/SceneSwitcher.ts +28 -3
- package/src/engine-components/TransformGizmo.ts +64 -70
- package/src/engine-components/codegen/components.ts +2 -1
- package/src/engine-components/export/usdz/USDZExporter.ts +7 -2
- package/src/engine-components/ui/Button.ts +14 -9
- package/src/engine-components/ui/Canvas.ts +104 -40
- package/src/engine-components/ui/EventSystem.ts +16 -9
- package/src/engine-components/ui/Graphic.ts +44 -8
- package/src/engine-components/ui/Image.ts +10 -1
- package/src/engine-components/ui/InputField.ts +9 -1
- package/src/engine-components/ui/Interfaces.ts +12 -0
- package/src/engine-components/ui/Outline.ts +13 -0
- package/src/engine-components/ui/RectTransform.ts +203 -60
- package/src/engine-components/ui/Text.ts +284 -265
- package/src/engine-components/utils/LookAt.ts +21 -0
- package/src/engine-components/webxr/WebXRImageTracking.ts +85 -10
- package/lib/engine-components/ui/Keyboard.d.ts +0 -31
- package/lib/engine-components/ui/Keyboard.js +0 -178
- package/lib/engine-components/ui/Keyboard.js.map +0 -1
- package/src/engine-components/ui/Keyboard.ts +0 -204
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { serializable } from "../../engine/engine_serialization";
|
|
2
|
+
import { Behaviour } from "../Component";
|
|
3
|
+
import { Object3D } from "three";
|
|
4
|
+
import { getWorldPosition, lookAtInverse } from "../../engine/engine_three_utils";
|
|
5
|
+
|
|
6
|
+
export class LookAt extends Behaviour {
|
|
7
|
+
|
|
8
|
+
@serializable(Object3D)
|
|
9
|
+
target?: Object3D;
|
|
10
|
+
|
|
11
|
+
@serializable()
|
|
12
|
+
invertForward: boolean = false;
|
|
13
|
+
|
|
14
|
+
onBeforeRender(): void {
|
|
15
|
+
if (!this.target) return;
|
|
16
|
+
if (!this.invertForward)
|
|
17
|
+
this.gameObject.lookAt(getWorldPosition(this.target!));
|
|
18
|
+
else
|
|
19
|
+
lookAtInverse(this.gameObject, getWorldPosition(this.target!));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
import { WebXR } from "./WebXR";
|
|
2
2
|
import { serializable } from "../../engine/engine_serialization";
|
|
3
|
-
import { Behaviour } from "../Component";
|
|
4
|
-
import {
|
|
3
|
+
import { Behaviour, GameObject } from "../Component";
|
|
4
|
+
import { Object3D, Quaternion, Vector3 } from "three";
|
|
5
5
|
import { CircularBuffer, getParam } from "../../engine/engine_utils";
|
|
6
|
+
import { AssetReference } from "../../engine/engine_addressables";
|
|
6
7
|
|
|
7
8
|
// https://github.com/immersive-web/marker-tracking/blob/main/explainer.md
|
|
8
9
|
|
|
9
10
|
const debug = getParam("debugimagetracking");
|
|
10
11
|
|
|
11
|
-
const _scaleTemp = new Vector3();
|
|
12
|
-
|
|
13
12
|
export class WebXRTrackedImage {
|
|
14
13
|
|
|
15
|
-
|
|
16
14
|
get url(): string { return this._trackedImage.image ?? ""; }
|
|
17
15
|
get widthInMeters() { return this._trackedImage.widthInMeters ?? undefined; }
|
|
18
16
|
get bitmap(): ImageBitmap { return this._bitmap; }
|
|
17
|
+
get model(): WebXRImageTrackingModel { return this._trackedImage; }
|
|
19
18
|
readonly measuredSize: number;
|
|
20
19
|
readonly state: "tracked" | "emulated";
|
|
21
20
|
|
|
@@ -64,7 +63,7 @@ export class WebXRTrackedImage {
|
|
|
64
63
|
}
|
|
65
64
|
}
|
|
66
65
|
|
|
67
|
-
private readonly _trackingComponent: WebXRImageTracking
|
|
66
|
+
private readonly _trackingComponent: WebXRImageTracking;
|
|
68
67
|
private readonly _trackedImage: WebXRImageTrackingModel;
|
|
69
68
|
private readonly _bitmap: ImageBitmap;
|
|
70
69
|
private readonly _pose: any;
|
|
@@ -90,6 +89,14 @@ export class WebXRImageTrackingModel {
|
|
|
90
89
|
@serializable()
|
|
91
90
|
widthInMeters!: number;
|
|
92
91
|
|
|
92
|
+
@serializable(AssetReference)
|
|
93
|
+
object?: AssetReference;
|
|
94
|
+
|
|
95
|
+
@serializable()
|
|
96
|
+
createObjectInstance: boolean = false;
|
|
97
|
+
|
|
98
|
+
@serializable()
|
|
99
|
+
imageDoesNotMove: boolean = false;
|
|
93
100
|
}
|
|
94
101
|
|
|
95
102
|
export class WebXRImageTracking extends Behaviour {
|
|
@@ -97,9 +104,6 @@ export class WebXRImageTracking extends Behaviour {
|
|
|
97
104
|
@serializable(WebXRImageTrackingModel)
|
|
98
105
|
trackedImages!: WebXRImageTrackingModel[];
|
|
99
106
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
107
|
private readonly trackedImageIndexMap: Map<number, WebXRImageTrackingModel> = new Map();
|
|
104
108
|
|
|
105
109
|
private static _imageElements: Map<string, ImageBitmap | null> = new Map();
|
|
@@ -125,13 +129,16 @@ export class WebXRImageTracking extends Behaviour {
|
|
|
125
129
|
|
|
126
130
|
onEnable(): void {
|
|
127
131
|
WebXR.addEventListener("modify-ar-options", this.onModifyAROptions);
|
|
132
|
+
WebXR.addEventListener("xrStarted", this.onXRStarted);
|
|
133
|
+
this.addEventListener("image-tracking", this.onImageTrackingUpdate)
|
|
128
134
|
}
|
|
129
135
|
|
|
130
136
|
onDisable(): void {
|
|
131
137
|
WebXR.removeEventListener("modify-ar-options", this.onModifyAROptions);
|
|
138
|
+
WebXR.removeEventListener("xrStarted", this.onXRStarted);
|
|
139
|
+
this.removeEventListener("image-tracking", this.onImageTrackingUpdate)
|
|
132
140
|
}
|
|
133
141
|
|
|
134
|
-
|
|
135
142
|
private onModifyAROptions = (event: any) => {
|
|
136
143
|
const options = event.detail;
|
|
137
144
|
const features = options.optionalFeatures || [];
|
|
@@ -154,6 +161,74 @@ export class WebXRImageTracking extends Behaviour {
|
|
|
154
161
|
}
|
|
155
162
|
}
|
|
156
163
|
|
|
164
|
+
private imageToObjectMap: Map<WebXRImageTrackingModel, { object: GameObject | null, frames: number }> = new Map();
|
|
165
|
+
|
|
166
|
+
private onImageTrackingUpdate = (event: any) => {
|
|
167
|
+
const images = event.detail as WebXRTrackedImage[];
|
|
168
|
+
|
|
169
|
+
// disable any objects that are no longer tracked
|
|
170
|
+
for (const [model, object] of this.imageToObjectMap) {
|
|
171
|
+
if (!object.object || !model) continue;
|
|
172
|
+
let found = false;
|
|
173
|
+
for (const trackedImage of images) {
|
|
174
|
+
if (trackedImage.model === model) {
|
|
175
|
+
found = true;
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (!found) {
|
|
180
|
+
GameObject.setActive(object.object, false);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
for (const image of images) {
|
|
185
|
+
const model = image.model;
|
|
186
|
+
// don't do anything if we don't have an object to track - can be handled externally through events
|
|
187
|
+
if (!model.object) continue;
|
|
188
|
+
|
|
189
|
+
let trackedData = this.imageToObjectMap.get(model);
|
|
190
|
+
if (trackedData === undefined) {
|
|
191
|
+
trackedData = { object: null, frames: 0 };
|
|
192
|
+
this.imageToObjectMap.set(model, trackedData);
|
|
193
|
+
|
|
194
|
+
model.object.loadAssetAsync().then((asset: GameObject | null) => {
|
|
195
|
+
if (model.createObjectInstance)
|
|
196
|
+
asset = GameObject.instantiate(asset);
|
|
197
|
+
|
|
198
|
+
if (asset) {
|
|
199
|
+
trackedData!.object = asset;
|
|
200
|
+
if (asset !== this.gameObject)
|
|
201
|
+
this.gameObject.add(asset);
|
|
202
|
+
image.applyToObject(asset);
|
|
203
|
+
if (!asset.activeSelf)
|
|
204
|
+
GameObject.setActive(asset, true);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
trackedData.frames++;
|
|
210
|
+
|
|
211
|
+
// TODO we could do a bit more here: e.g. sample for the first 1s or so of getting pose data
|
|
212
|
+
// to improve the tracking quality a bit.
|
|
213
|
+
if (model.imageDoesNotMove && trackedData.frames > 10)
|
|
214
|
+
continue;
|
|
215
|
+
|
|
216
|
+
if (!trackedData.object) continue;
|
|
217
|
+
|
|
218
|
+
image.applyToObject(trackedData.object);
|
|
219
|
+
if (!trackedData.object.activeSelf)
|
|
220
|
+
GameObject.setActive(trackedData.object, true);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
private onXRStarted = (_: any) => {
|
|
226
|
+
// clear out all frame counters for tracking
|
|
227
|
+
for (const trackedData of this.imageToObjectMap.values()) {
|
|
228
|
+
trackedData.frames = 0;
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
|
|
157
232
|
onBeforeRender(frame: XRFrame | null): void {
|
|
158
233
|
//@ts-ignore
|
|
159
234
|
if (frame?.session && typeof frame.getImageTrackingResults === "function") {
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { BaseUIComponent } from './BaseUIComponent';
|
|
2
|
-
import { Text } from './Text';
|
|
3
|
-
declare enum KeymapOption {
|
|
4
|
-
fr = 0,
|
|
5
|
-
ru = 1,
|
|
6
|
-
de = 2,
|
|
7
|
-
es = 3,
|
|
8
|
-
el = 4,
|
|
9
|
-
nord = 5,
|
|
10
|
-
eng = 6
|
|
11
|
-
}
|
|
12
|
-
export declare class Keyboard extends BaseUIComponent {
|
|
13
|
-
font?: string;
|
|
14
|
-
text?: Text;
|
|
15
|
-
keymap?: KeymapOption;
|
|
16
|
-
padding?: number;
|
|
17
|
-
margin?: number;
|
|
18
|
-
fontSize?: number;
|
|
19
|
-
borderRadius?: number;
|
|
20
|
-
private colors;
|
|
21
|
-
awake(): void;
|
|
22
|
-
onEnable(): void;
|
|
23
|
-
onDisable(): void;
|
|
24
|
-
private keyboard;
|
|
25
|
-
private _lastKeyPressed;
|
|
26
|
-
private _lastKeyPressedStartTime;
|
|
27
|
-
private _lastKeyPressedTime;
|
|
28
|
-
private makeKeyboard;
|
|
29
|
-
private tryAppend;
|
|
30
|
-
}
|
|
31
|
-
export {};
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
import * as ThreeMeshUI from 'three-mesh-ui';
|
|
2
|
-
import * as THREE from 'three';
|
|
3
|
-
import { BaseUIComponent, includesDir } from './BaseUIComponent';
|
|
4
|
-
import { RectTransform } from './RectTransform';
|
|
5
|
-
import { GameObject } from '../Component';
|
|
6
|
-
var KeymapOption;
|
|
7
|
-
(function (KeymapOption) {
|
|
8
|
-
KeymapOption[KeymapOption["fr"] = 0] = "fr";
|
|
9
|
-
KeymapOption[KeymapOption["ru"] = 1] = "ru";
|
|
10
|
-
KeymapOption[KeymapOption["de"] = 2] = "de";
|
|
11
|
-
KeymapOption[KeymapOption["es"] = 3] = "es";
|
|
12
|
-
KeymapOption[KeymapOption["el"] = 4] = "el";
|
|
13
|
-
KeymapOption[KeymapOption["nord"] = 5] = "nord";
|
|
14
|
-
KeymapOption[KeymapOption["eng"] = 6] = "eng";
|
|
15
|
-
})(KeymapOption || (KeymapOption = {}));
|
|
16
|
-
// see https://github.com/felixmariotto/three-mesh-ui/blob/master/examples/keyboard.js
|
|
17
|
-
export class Keyboard extends BaseUIComponent {
|
|
18
|
-
font;
|
|
19
|
-
text;
|
|
20
|
-
keymap;
|
|
21
|
-
padding;
|
|
22
|
-
margin;
|
|
23
|
-
fontSize;
|
|
24
|
-
borderRadius;
|
|
25
|
-
colors = {
|
|
26
|
-
keyboardBack: 0x858585,
|
|
27
|
-
panelBack: 0x262626,
|
|
28
|
-
button: 0x363636,
|
|
29
|
-
hovered: 0x1c1c1c,
|
|
30
|
-
selected: 0x109c5d,
|
|
31
|
-
};
|
|
32
|
-
awake() {
|
|
33
|
-
super.awake();
|
|
34
|
-
const langKey = KeymapOption[this.keymap || KeymapOption.eng];
|
|
35
|
-
this.makeKeyboard(langKey);
|
|
36
|
-
}
|
|
37
|
-
onEnable() {
|
|
38
|
-
this.addShadowComponent(this.keyboard);
|
|
39
|
-
}
|
|
40
|
-
onDisable() {
|
|
41
|
-
this.removeShadowComponent();
|
|
42
|
-
}
|
|
43
|
-
keyboard = null;
|
|
44
|
-
_lastKeyPressed;
|
|
45
|
-
_lastKeyPressedStartTime = 0;
|
|
46
|
-
_lastKeyPressedTime = 0;
|
|
47
|
-
makeKeyboard(language) {
|
|
48
|
-
if (!language && !navigator.language) {
|
|
49
|
-
language = "en";
|
|
50
|
-
}
|
|
51
|
-
const fontName = this.font ? this.font : "arial";
|
|
52
|
-
const rt = GameObject.getComponent(this.gameObject, RectTransform);
|
|
53
|
-
if (!rt) {
|
|
54
|
-
console.error("Missing rect transform, please add this component inside a canvas");
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
const opts = {
|
|
58
|
-
...rt.getBasicOptions(),
|
|
59
|
-
margin: this.margin || 0,
|
|
60
|
-
padding: this.padding || 0,
|
|
61
|
-
language: language,
|
|
62
|
-
fontFamily: includesDir + "/" + fontName + "-msdf.json",
|
|
63
|
-
fontTexture: includesDir + "/" + fontName + ".png",
|
|
64
|
-
fontSize: this.fontSize || 6,
|
|
65
|
-
backgroundColor: new THREE.Color(this.colors.keyboardBack),
|
|
66
|
-
backspaceTexture: includesDir + '/backspace.png',
|
|
67
|
-
shiftTexture: includesDir + '/shift.png',
|
|
68
|
-
enterTexture: includesDir + '/enter.png',
|
|
69
|
-
borderRadius: this.borderRadius || 0,
|
|
70
|
-
autoLayout: false,
|
|
71
|
-
};
|
|
72
|
-
// const ws = getWorldScale(this.gameObject);
|
|
73
|
-
const scale = this.gameObject.scale;
|
|
74
|
-
opts.width *= this.gameObject.scale.x;
|
|
75
|
-
opts.height *= this.gameObject.scale.y;
|
|
76
|
-
opts.fontSize *= Math.max(scale.x, scale.y);
|
|
77
|
-
this.keyboard = new ThreeMeshUI.Keyboard(opts);
|
|
78
|
-
// const scale = this.gameObject.scale;
|
|
79
|
-
// const max = Math.max(scale.x, scale.y, scale.z);
|
|
80
|
-
this.gameObject.scale.set(1, 1, 1);
|
|
81
|
-
//@ts-ignore
|
|
82
|
-
this.keyboard.keys.forEach((key) => {
|
|
83
|
-
key.setupState({
|
|
84
|
-
state: 'normal',
|
|
85
|
-
attributes: {
|
|
86
|
-
offset: 0.003,
|
|
87
|
-
backgroundColor: new THREE.Color(this.colors.button),
|
|
88
|
-
backgroundOpacity: 1
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
key.setState("normal");
|
|
92
|
-
key.setupState({
|
|
93
|
-
state: 'hovered',
|
|
94
|
-
attributes: {
|
|
95
|
-
offset: 0.3,
|
|
96
|
-
backgroundColor: new THREE.Color(this.colors.hovered),
|
|
97
|
-
backgroundOpacity: 1
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
key.setupState({
|
|
101
|
-
state: 'pressed',
|
|
102
|
-
attributes: {
|
|
103
|
-
offset: 0.1,
|
|
104
|
-
backgroundColor: new THREE.Color(this.colors.selected),
|
|
105
|
-
backgroundOpacity: 1
|
|
106
|
-
},
|
|
107
|
-
// triggered when the user clicked on a keyboard's key
|
|
108
|
-
onSet: () => {
|
|
109
|
-
const input = key.info.input;
|
|
110
|
-
const cmd = key.info.command;
|
|
111
|
-
if (this._lastKeyPressed !== input) {
|
|
112
|
-
this._lastKeyPressedStartTime = this.context.time.time;
|
|
113
|
-
}
|
|
114
|
-
else if (this.context.time.time - this._lastKeyPressedTime > .05) {
|
|
115
|
-
// there was probably a key up inbetween
|
|
116
|
-
this._lastKeyPressedStartTime = this.context.time.time;
|
|
117
|
-
}
|
|
118
|
-
else if (this.context.time.time - this._lastKeyPressedStartTime < .5
|
|
119
|
-
|| cmd == "switch"
|
|
120
|
-
|| cmd == "shift"
|
|
121
|
-
|| cmd == "switch-set") {
|
|
122
|
-
this._lastKeyPressedTime = this.context.time.time;
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
this._lastKeyPressedTime = this.context.time.time;
|
|
126
|
-
this._lastKeyPressed = input;
|
|
127
|
-
// if the key have a command (eg: 'backspace', 'switch', 'enter'...)
|
|
128
|
-
// special actions are taken
|
|
129
|
-
if (cmd) {
|
|
130
|
-
switch (cmd) {
|
|
131
|
-
// switch between panels
|
|
132
|
-
case 'switch':
|
|
133
|
-
//@ts-ignore
|
|
134
|
-
this.keyboard.setNextPanel();
|
|
135
|
-
break;
|
|
136
|
-
// switch between panel charsets (eg: russian/english)
|
|
137
|
-
case 'switch-set':
|
|
138
|
-
//@ts-ignore
|
|
139
|
-
this.keyboard.setNextCharset();
|
|
140
|
-
break;
|
|
141
|
-
case 'enter':
|
|
142
|
-
this.tryAppend('\n');
|
|
143
|
-
break;
|
|
144
|
-
case 'space':
|
|
145
|
-
this.tryAppend(' ');
|
|
146
|
-
break;
|
|
147
|
-
case 'backspace':
|
|
148
|
-
//@ts-ignore
|
|
149
|
-
if (!this.text?.text?.length)
|
|
150
|
-
break;
|
|
151
|
-
if (this.text?.text)
|
|
152
|
-
this.text.text = this.text.text.substring(0, this.text.text.length - 1) || "";
|
|
153
|
-
break;
|
|
154
|
-
case 'shift':
|
|
155
|
-
//@ts-ignore
|
|
156
|
-
this.keyboard.toggleCase();
|
|
157
|
-
break;
|
|
158
|
-
}
|
|
159
|
-
;
|
|
160
|
-
// print a glyph, if any
|
|
161
|
-
}
|
|
162
|
-
else if (key.info.input !== undefined) {
|
|
163
|
-
this.tryAppend(key.info.input);
|
|
164
|
-
}
|
|
165
|
-
;
|
|
166
|
-
}
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
;
|
|
171
|
-
tryAppend(char) {
|
|
172
|
-
if (this.text) {
|
|
173
|
-
this.text.text += char;
|
|
174
|
-
this.markDirty();
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
//# sourceMappingURL=Keyboard.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Keyboard.js","sourceRoot":"","sources":["../../../src/engine-components/ui/Keyboard.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
import * as ThreeMeshUI from 'three-mesh-ui'
|
|
2
|
-
import * as THREE from 'three'
|
|
3
|
-
import { BaseUIComponent, includesDir } from './BaseUIComponent';
|
|
4
|
-
import { Text } from './Text';
|
|
5
|
-
import { getWorldScale } from '../../engine/engine_three_utils';
|
|
6
|
-
import { RectTransform } from './RectTransform';
|
|
7
|
-
import { GameObject } from '../Component';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
enum KeymapOption {
|
|
11
|
-
fr,
|
|
12
|
-
ru,
|
|
13
|
-
de,
|
|
14
|
-
es,
|
|
15
|
-
el,
|
|
16
|
-
nord,
|
|
17
|
-
eng
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
// see https://github.com/felixmariotto/three-mesh-ui/blob/master/examples/keyboard.js
|
|
22
|
-
export class Keyboard extends BaseUIComponent {
|
|
23
|
-
|
|
24
|
-
font?: string;
|
|
25
|
-
text?: Text;
|
|
26
|
-
keymap?: KeymapOption;
|
|
27
|
-
padding?: number;
|
|
28
|
-
margin?: number;
|
|
29
|
-
fontSize?: number;
|
|
30
|
-
borderRadius?: number;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
private colors = {
|
|
34
|
-
keyboardBack: 0x858585,
|
|
35
|
-
panelBack: 0x262626,
|
|
36
|
-
button: 0x363636,
|
|
37
|
-
hovered: 0x1c1c1c,
|
|
38
|
-
selected: 0x109c5d,
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
awake() {
|
|
43
|
-
super.awake();
|
|
44
|
-
const langKey = KeymapOption[this.keymap || KeymapOption.eng];
|
|
45
|
-
this.makeKeyboard(langKey);
|
|
46
|
-
}
|
|
47
|
-
onEnable(): void {
|
|
48
|
-
this.addShadowComponent(this.keyboard);
|
|
49
|
-
}
|
|
50
|
-
onDisable(): void {
|
|
51
|
-
this.removeShadowComponent();
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
private keyboard: ThreeMeshUI.Keyboard | null = null!;
|
|
55
|
-
private _lastKeyPressed: any;
|
|
56
|
-
private _lastKeyPressedStartTime: number = 0;
|
|
57
|
-
private _lastKeyPressedTime: number = 0;
|
|
58
|
-
|
|
59
|
-
private makeKeyboard(language?: string) {
|
|
60
|
-
|
|
61
|
-
if (!language && !navigator.language) {
|
|
62
|
-
language = "en";
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const fontName = this.font ? this.font : "arial";
|
|
66
|
-
|
|
67
|
-
const rt = GameObject.getComponent(this.gameObject, RectTransform);
|
|
68
|
-
if(!rt){
|
|
69
|
-
console.error("Missing rect transform, please add this component inside a canvas");
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
const opts = {
|
|
73
|
-
...rt.getBasicOptions(),
|
|
74
|
-
margin: this.margin || 0,
|
|
75
|
-
padding: this.padding || 0,
|
|
76
|
-
language: language,
|
|
77
|
-
fontFamily: includesDir + "/" + fontName + "-msdf.json",
|
|
78
|
-
fontTexture: includesDir + "/" + fontName + ".png",
|
|
79
|
-
fontSize: this.fontSize || 6, // fontSize will propagate to the keys blocks
|
|
80
|
-
backgroundColor: new THREE.Color(this.colors.keyboardBack),
|
|
81
|
-
backspaceTexture: includesDir + '/backspace.png',
|
|
82
|
-
shiftTexture: includesDir + '/shift.png',
|
|
83
|
-
enterTexture: includesDir + '/enter.png',
|
|
84
|
-
borderRadius: this.borderRadius || 0,
|
|
85
|
-
autoLayout: false,
|
|
86
|
-
|
|
87
|
-
};
|
|
88
|
-
// const ws = getWorldScale(this.gameObject);
|
|
89
|
-
const scale = this.gameObject.scale;
|
|
90
|
-
opts.width *= this.gameObject.scale.x;
|
|
91
|
-
opts.height *= this.gameObject.scale.y;
|
|
92
|
-
opts.fontSize *= Math.max(scale.x, scale.y);
|
|
93
|
-
this.keyboard = new ThreeMeshUI.Keyboard(opts);
|
|
94
|
-
|
|
95
|
-
// const scale = this.gameObject.scale;
|
|
96
|
-
// const max = Math.max(scale.x, scale.y, scale.z);
|
|
97
|
-
this.gameObject.scale.set(1, 1, 1);
|
|
98
|
-
|
|
99
|
-
//@ts-ignore
|
|
100
|
-
this.keyboard.keys.forEach((key) => {
|
|
101
|
-
|
|
102
|
-
key.setupState({
|
|
103
|
-
state: 'normal',
|
|
104
|
-
attributes: {
|
|
105
|
-
offset: 0.003,
|
|
106
|
-
backgroundColor: new THREE.Color(this.colors.button),
|
|
107
|
-
backgroundOpacity: 1
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
key.setState("normal");
|
|
111
|
-
|
|
112
|
-
key.setupState({
|
|
113
|
-
state: 'hovered',
|
|
114
|
-
attributes: {
|
|
115
|
-
offset: 0.3,
|
|
116
|
-
backgroundColor: new THREE.Color(this.colors.hovered),
|
|
117
|
-
backgroundOpacity: 1
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
key.setupState({
|
|
122
|
-
state: 'pressed',
|
|
123
|
-
attributes: {
|
|
124
|
-
offset: 0.1,
|
|
125
|
-
backgroundColor: new THREE.Color(this.colors.selected),
|
|
126
|
-
backgroundOpacity: 1
|
|
127
|
-
},
|
|
128
|
-
// triggered when the user clicked on a keyboard's key
|
|
129
|
-
onSet: () => {
|
|
130
|
-
const input = key.info.input;
|
|
131
|
-
const cmd = key.info.command;
|
|
132
|
-
if (this._lastKeyPressed !== input) {
|
|
133
|
-
this._lastKeyPressedStartTime = this.context.time.time;
|
|
134
|
-
}
|
|
135
|
-
else if (this.context.time.time - this._lastKeyPressedTime > .05) {
|
|
136
|
-
// there was probably a key up inbetween
|
|
137
|
-
this._lastKeyPressedStartTime = this.context.time.time;
|
|
138
|
-
}
|
|
139
|
-
else if (this.context.time.time - this._lastKeyPressedStartTime < .5
|
|
140
|
-
|| cmd == "switch"
|
|
141
|
-
|| cmd == "shift"
|
|
142
|
-
|| cmd == "switch-set"
|
|
143
|
-
) {
|
|
144
|
-
this._lastKeyPressedTime = this.context.time.time;
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
this._lastKeyPressedTime = this.context.time.time;
|
|
148
|
-
this._lastKeyPressed = input;
|
|
149
|
-
// if the key have a command (eg: 'backspace', 'switch', 'enter'...)
|
|
150
|
-
// special actions are taken
|
|
151
|
-
if (cmd) {
|
|
152
|
-
switch (cmd) {
|
|
153
|
-
// switch between panels
|
|
154
|
-
case 'switch':
|
|
155
|
-
//@ts-ignore
|
|
156
|
-
this.keyboard.setNextPanel();
|
|
157
|
-
break;
|
|
158
|
-
|
|
159
|
-
// switch between panel charsets (eg: russian/english)
|
|
160
|
-
case 'switch-set':
|
|
161
|
-
//@ts-ignore
|
|
162
|
-
this.keyboard.setNextCharset();
|
|
163
|
-
break;
|
|
164
|
-
|
|
165
|
-
case 'enter':
|
|
166
|
-
this.tryAppend('\n');
|
|
167
|
-
break;
|
|
168
|
-
|
|
169
|
-
case 'space':
|
|
170
|
-
this.tryAppend(' ');
|
|
171
|
-
break;
|
|
172
|
-
|
|
173
|
-
case 'backspace':
|
|
174
|
-
//@ts-ignore
|
|
175
|
-
if (!this.text?.text?.length) break
|
|
176
|
-
if (this.text?.text)
|
|
177
|
-
this.text.text = this.text.text.substring(0, this.text.text.length - 1) || ""
|
|
178
|
-
break;
|
|
179
|
-
|
|
180
|
-
case 'shift':
|
|
181
|
-
//@ts-ignore
|
|
182
|
-
this.keyboard.toggleCase();
|
|
183
|
-
break;
|
|
184
|
-
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
// print a glyph, if any
|
|
188
|
-
} else if (key.info.input !== undefined) {
|
|
189
|
-
this.tryAppend(key.info.input);
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
}
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
});
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
private tryAppend(char: string) {
|
|
199
|
-
if (this.text) {
|
|
200
|
-
this.text.text += char;
|
|
201
|
-
this.markDirty();
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|