@needle-tools/engine 3.2.15-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.
Files changed (90) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/needle-engine.js +42120 -35732
  3. package/dist/needle-engine.min.js +687 -495
  4. package/dist/needle-engine.umd.cjs +689 -497
  5. package/lib/engine/codegen/register_types.js +4 -2
  6. package/lib/engine/codegen/register_types.js.map +1 -1
  7. package/lib/engine/engine_addressables.d.ts +3 -3
  8. package/lib/engine/engine_addressables.js +30 -9
  9. package/lib/engine/engine_addressables.js.map +1 -1
  10. package/lib/engine/engine_element.js +1 -1
  11. package/lib/engine/engine_element.js.map +1 -1
  12. package/lib/engine/engine_gameobject.d.ts +2 -1
  13. package/lib/engine/engine_gameobject.js +17 -0
  14. package/lib/engine/engine_gameobject.js.map +1 -1
  15. package/lib/engine/engine_input.js +10 -0
  16. package/lib/engine/engine_input.js.map +1 -1
  17. package/lib/engine/engine_math.d.ts +4 -0
  18. package/lib/engine/engine_math.js +6 -0
  19. package/lib/engine/engine_math.js.map +1 -1
  20. package/lib/engine-components/AnimatorController.js +7 -2
  21. package/lib/engine-components/AnimatorController.js.map +1 -1
  22. package/lib/engine-components/OrbitControls.js +13 -4
  23. package/lib/engine-components/OrbitControls.js.map +1 -1
  24. package/lib/engine-components/TransformGizmo.d.ts +8 -4
  25. package/lib/engine-components/TransformGizmo.js +62 -63
  26. package/lib/engine-components/TransformGizmo.js.map +1 -1
  27. package/lib/engine-components/codegen/components.d.ts +2 -1
  28. package/lib/engine-components/codegen/components.js +2 -1
  29. package/lib/engine-components/codegen/components.js.map +1 -1
  30. package/lib/engine-components/ui/Button.js +9 -5
  31. package/lib/engine-components/ui/Button.js.map +1 -1
  32. package/lib/engine-components/ui/Canvas.d.ts +13 -6
  33. package/lib/engine-components/ui/Canvas.js +101 -37
  34. package/lib/engine-components/ui/Canvas.js.map +1 -1
  35. package/lib/engine-components/ui/EventSystem.d.ts +6 -0
  36. package/lib/engine-components/ui/EventSystem.js +4 -4
  37. package/lib/engine-components/ui/EventSystem.js.map +1 -1
  38. package/lib/engine-components/ui/Graphic.d.ts +5 -2
  39. package/lib/engine-components/ui/Graphic.js +38 -7
  40. package/lib/engine-components/ui/Graphic.js.map +1 -1
  41. package/lib/engine-components/ui/Image.d.ts +1 -0
  42. package/lib/engine-components/ui/Image.js +10 -1
  43. package/lib/engine-components/ui/Image.js.map +1 -1
  44. package/lib/engine-components/ui/InputField.d.ts +1 -0
  45. package/lib/engine-components/ui/InputField.js +8 -0
  46. package/lib/engine-components/ui/InputField.js.map +1 -1
  47. package/lib/engine-components/ui/Interfaces.d.ts +8 -0
  48. package/lib/engine-components/ui/Outline.d.ts +7 -0
  49. package/lib/engine-components/ui/Outline.js +21 -0
  50. package/lib/engine-components/ui/Outline.js.map +1 -0
  51. package/lib/engine-components/ui/RectTransform.d.ts +29 -11
  52. package/lib/engine-components/ui/RectTransform.js +178 -46
  53. package/lib/engine-components/ui/RectTransform.js.map +1 -1
  54. package/lib/engine-components/ui/Text.d.ts +13 -10
  55. package/lib/engine-components/ui/Text.js +177 -246
  56. package/lib/engine-components/ui/Text.js.map +1 -1
  57. package/lib/engine-components/utils/LookAt.d.ts +7 -0
  58. package/lib/engine-components/utils/LookAt.js +29 -0
  59. package/lib/engine-components/utils/LookAt.js.map +1 -0
  60. package/lib/engine-components/webxr/WebXRImageTracking.d.ts +8 -0
  61. package/lib/engine-components/webxr/WebXRImageTracking.js +79 -3
  62. package/lib/engine-components/webxr/WebXRImageTracking.js.map +1 -1
  63. package/lib/tsconfig.tsbuildinfo +1 -1
  64. package/package.json +2 -2
  65. package/src/engine/codegen/register_types.js +4 -2
  66. package/src/engine/engine_addressables.ts +28 -10
  67. package/src/engine/engine_element.ts +1 -1
  68. package/src/engine/engine_gameobject.ts +18 -1
  69. package/src/engine/engine_input.ts +11 -0
  70. package/src/engine/engine_math.ts +10 -0
  71. package/src/engine-components/AnimatorController.ts +7 -1
  72. package/src/engine-components/OrbitControls.ts +14 -6
  73. package/src/engine-components/TransformGizmo.ts +64 -70
  74. package/src/engine-components/codegen/components.ts +2 -1
  75. package/src/engine-components/ui/Button.ts +14 -9
  76. package/src/engine-components/ui/Canvas.ts +104 -40
  77. package/src/engine-components/ui/EventSystem.ts +16 -9
  78. package/src/engine-components/ui/Graphic.ts +44 -8
  79. package/src/engine-components/ui/Image.ts +10 -1
  80. package/src/engine-components/ui/InputField.ts +9 -1
  81. package/src/engine-components/ui/Interfaces.ts +12 -0
  82. package/src/engine-components/ui/Outline.ts +13 -0
  83. package/src/engine-components/ui/RectTransform.ts +203 -60
  84. package/src/engine-components/ui/Text.ts +284 -265
  85. package/src/engine-components/utils/LookAt.ts +21 -0
  86. package/src/engine-components/webxr/WebXRImageTracking.ts +85 -10
  87. package/lib/engine-components/ui/Keyboard.d.ts +0 -31
  88. package/lib/engine-components/ui/Keyboard.js +0 -178
  89. package/lib/engine-components/ui/Keyboard.js.map +0 -1
  90. 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 { Matrix4, Object3D, Quaternion, Vector, Vector3 } from "three";
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
- }