@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.
- package/CHANGELOG.md +13 -0
- package/dist/needle-engine.js +42120 -35732
- package/dist/needle-engine.min.js +687 -495
- package/dist/needle-engine.umd.cjs +689 -497
- 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_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/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/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_math.ts +10 -0
- package/src/engine-components/AnimatorController.ts +7 -1
- package/src/engine-components/OrbitControls.ts +14 -6
- package/src/engine-components/TransformGizmo.ts +64 -70
- package/src/engine-components/codegen/components.ts +2 -1
- 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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@needle-tools/engine",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0-alpha",
|
|
4
4
|
"description": "Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in",
|
|
5
5
|
"main": "dist/needle-engine.umd.cjs",
|
|
6
6
|
"type": "module",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"simplex-noise": "^4.0.1",
|
|
63
63
|
"stats.js": "^0.17.0",
|
|
64
64
|
"three": "npm:@needle-tools/three@^0.146.8",
|
|
65
|
-
"three-mesh-ui": "
|
|
65
|
+
"three-mesh-ui": "npm:@needle-tools/three-mesh-ui@^7.1.4",
|
|
66
66
|
"three.quarks": "^0.7.3",
|
|
67
67
|
"uuid": "^9.0.0",
|
|
68
68
|
"websocket-ts": "^1.1.1"
|
|
@@ -76,13 +76,13 @@ import { Image } from "../../engine-components/ui/Image";
|
|
|
76
76
|
import { InheritVelocityModule } from "../../engine-components/ParticleSystemModules";
|
|
77
77
|
import { InputField } from "../../engine-components/ui/InputField";
|
|
78
78
|
import { Interactable } from "../../engine-components/Interactable";
|
|
79
|
-
import { Keyboard } from "../../engine-components/ui/Keyboard";
|
|
80
79
|
import { LayoutGroup } from "../../engine-components/ui/Layout";
|
|
81
80
|
import { Light } from "../../engine-components/Light";
|
|
82
81
|
import { LimitVelocityOverLifetimeModule } from "../../engine-components/ParticleSystemModules";
|
|
83
82
|
import { LODGroup } from "../../engine-components/LODGroup";
|
|
84
83
|
import { LODModel } from "../../engine-components/LODGroup";
|
|
85
84
|
import { LogStats } from "../../engine-components/debug/LogStats";
|
|
85
|
+
import { LookAt } from "../../engine-components/utils/LookAt";
|
|
86
86
|
import { LookAtConstraint } from "../../engine-components/LookAtConstraint";
|
|
87
87
|
import { MainModule } from "../../engine-components/ParticleSystemModules";
|
|
88
88
|
import { MaskableGraphic } from "../../engine-components/ui/Graphic";
|
|
@@ -97,6 +97,7 @@ import { ObjectRaycaster } from "../../engine-components/ui/Raycaster";
|
|
|
97
97
|
import { OffsetConstraint } from "../../engine-components/OffsetConstraint";
|
|
98
98
|
import { OpenURL } from "../../engine-components/utils/OpenURL";
|
|
99
99
|
import { OrbitControls } from "../../engine-components/OrbitControls";
|
|
100
|
+
import { Outline } from "../../engine-components/ui/Outline";
|
|
100
101
|
import { ParticleBurst } from "../../engine-components/ParticleSystemModules";
|
|
101
102
|
import { ParticleSubEmitter } from "../../engine-components/ParticleSystemSubEmitter";
|
|
102
103
|
import { ParticleSystem } from "../../engine-components/ParticleSystem";
|
|
@@ -266,13 +267,13 @@ TypeStore.add("Image", Image);
|
|
|
266
267
|
TypeStore.add("InheritVelocityModule", InheritVelocityModule);
|
|
267
268
|
TypeStore.add("InputField", InputField);
|
|
268
269
|
TypeStore.add("Interactable", Interactable);
|
|
269
|
-
TypeStore.add("Keyboard", Keyboard);
|
|
270
270
|
TypeStore.add("LayoutGroup", LayoutGroup);
|
|
271
271
|
TypeStore.add("Light", Light);
|
|
272
272
|
TypeStore.add("LimitVelocityOverLifetimeModule", LimitVelocityOverLifetimeModule);
|
|
273
273
|
TypeStore.add("LODGroup", LODGroup);
|
|
274
274
|
TypeStore.add("LODModel", LODModel);
|
|
275
275
|
TypeStore.add("LogStats", LogStats);
|
|
276
|
+
TypeStore.add("LookAt", LookAt);
|
|
276
277
|
TypeStore.add("LookAtConstraint", LookAtConstraint);
|
|
277
278
|
TypeStore.add("MainModule", MainModule);
|
|
278
279
|
TypeStore.add("MaskableGraphic", MaskableGraphic);
|
|
@@ -287,6 +288,7 @@ TypeStore.add("ObjectRaycaster", ObjectRaycaster);
|
|
|
287
288
|
TypeStore.add("OffsetConstraint", OffsetConstraint);
|
|
288
289
|
TypeStore.add("OpenURL", OpenURL);
|
|
289
290
|
TypeStore.add("OrbitControls", OrbitControls);
|
|
291
|
+
TypeStore.add("Outline", Outline);
|
|
290
292
|
TypeStore.add("ParticleBurst", ParticleBurst);
|
|
291
293
|
TypeStore.add("ParticleSubEmitter", ParticleSubEmitter);
|
|
292
294
|
TypeStore.add("ParticleSystem", ParticleSystem);
|
|
@@ -27,8 +27,8 @@ export class Addressables {
|
|
|
27
27
|
|
|
28
28
|
private _assetReferences: { [key: string]: AssetReference } = {};
|
|
29
29
|
|
|
30
|
-
findAssetReference(
|
|
31
|
-
return this._assetReferences[
|
|
30
|
+
findAssetReference(key: string): AssetReference | null {
|
|
31
|
+
return this._assetReferences[key] || null;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
registerAssetReference(ref: AssetReference): AssetReference {
|
|
@@ -48,9 +48,9 @@ export type ProgressCallback = (asset: AssetReference, prog: ProgressEvent) => v
|
|
|
48
48
|
|
|
49
49
|
export class AssetReference {
|
|
50
50
|
|
|
51
|
-
static getOrCreate(sourceId: SourceIdentifier,
|
|
52
|
-
const fullPath = resolveUrl(sourceId,
|
|
53
|
-
if (debug) console.log("GetOrCreate Addressable from", sourceId,
|
|
51
|
+
static getOrCreate(sourceId: SourceIdentifier, url: string, context: Context): AssetReference {
|
|
52
|
+
const fullPath = resolveUrl(sourceId, url);
|
|
53
|
+
if (debug) console.log("GetOrCreate Addressable from", sourceId, url, "FinalPath=", fullPath);
|
|
54
54
|
const addressables = context.addressables;
|
|
55
55
|
const existing = addressables.findAssetReference(fullPath);
|
|
56
56
|
if (existing) return existing;
|
|
@@ -89,19 +89,19 @@ export class AssetReference {
|
|
|
89
89
|
private _isLoadingRawBinary: boolean = false;
|
|
90
90
|
private _rawBinary?: ArrayBuffer | null;
|
|
91
91
|
|
|
92
|
-
constructor(uri: string, hash?: string) {
|
|
92
|
+
constructor(uri: string, hash?: string, asset: any = null) {
|
|
93
93
|
this._url = uri;
|
|
94
94
|
this._hash = hash;
|
|
95
95
|
if (uri.includes("?v="))
|
|
96
96
|
this._hashedUri = uri;
|
|
97
97
|
else
|
|
98
98
|
this._hashedUri = hash ? uri + "?v=" + hash : uri;
|
|
99
|
-
|
|
99
|
+
if (asset !== null) this.asset = asset;
|
|
100
100
|
registerPrefabProvider(this._url, this.onResolvePrefab.bind(this));
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
private async onResolvePrefab(
|
|
104
|
-
if (
|
|
103
|
+
private async onResolvePrefab(url: string): Promise<IGameObject | null> {
|
|
104
|
+
if (url === this.uri) {
|
|
105
105
|
if (this.mustLoad) await this.loadAssetAsync();
|
|
106
106
|
if (this.asset) {
|
|
107
107
|
return this.asset;
|
|
@@ -320,12 +320,30 @@ class AddressableSerializer extends TypeSerializer {
|
|
|
320
320
|
return null;
|
|
321
321
|
}
|
|
322
322
|
if (!context.gltfId) {
|
|
323
|
-
console.error("Missing
|
|
323
|
+
console.error("Missing source id");
|
|
324
324
|
return null;
|
|
325
325
|
}
|
|
326
326
|
const ref = AssetReference.getOrCreate(context.gltfId, data, context.context);
|
|
327
327
|
return ref;
|
|
328
328
|
}
|
|
329
|
+
else if (data instanceof Object3D) {
|
|
330
|
+
if (!context.context) {
|
|
331
|
+
console.error("Missing context");
|
|
332
|
+
return null;
|
|
333
|
+
}
|
|
334
|
+
if (!context.gltfId) {
|
|
335
|
+
console.error("Missing source id");
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
const obj = data;
|
|
339
|
+
const ctx = context.context;
|
|
340
|
+
const guid = obj["guid"] ?? obj.uuid;
|
|
341
|
+
const existing = ctx.addressables.findAssetReference(guid);
|
|
342
|
+
if (existing) return existing;
|
|
343
|
+
const ref = new AssetReference(guid, undefined, obj);
|
|
344
|
+
ctx.addressables.registerAssetReference(ref);
|
|
345
|
+
return ref;
|
|
346
|
+
}
|
|
329
347
|
return null;
|
|
330
348
|
}
|
|
331
349
|
|
|
@@ -3,7 +3,7 @@ import { processNewScripts } from "./engine_mainloop_utils";
|
|
|
3
3
|
import { InstantiateIdProvider } from "./engine_networking_instantiate";
|
|
4
4
|
import { Context, registerComponent } from "./engine_setup";
|
|
5
5
|
import { logHierarchy, setWorldPosition, setWorldQuaternion } from "./engine_three_utils";
|
|
6
|
-
import { GuidsMap, IComponent as Component, IComponent, IGameObject as GameObject, UIDProvider } from "./engine_types";
|
|
6
|
+
import { GuidsMap, IComponent as Component, IComponent, IGameObject as GameObject, UIDProvider, Constructor } from "./engine_types";
|
|
7
7
|
import { getParam, tryFindObject } from "./engine_utils";
|
|
8
8
|
import { apply } from "../engine-components/js-extensions/Object3D";
|
|
9
9
|
import { $isUsingInstancing, InstancingUtil } from "./engine_instancing";
|
|
@@ -163,6 +163,23 @@ export function foreachComponent(instance: Object3D, cb: ForEachComponentCallbac
|
|
|
163
163
|
return internalForEachComponent(instance, cb, recursive);
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
+
export function* foreachComponentEnumerator<T extends IComponent>(instance: Object3D, type?: Constructor<T>, includeChildren: boolean = false): Generator<T> {
|
|
167
|
+
if (!instance?.userData.components) return;
|
|
168
|
+
for (const comp of instance.userData.components) {
|
|
169
|
+
if (type && comp?.isComponent === true && comp instanceof type) {
|
|
170
|
+
yield comp;
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
yield comp;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (includeChildren === true) {
|
|
177
|
+
for (const ch of instance.children) {
|
|
178
|
+
yield* foreachComponentEnumerator(ch, type, true);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
166
183
|
function internalForEachComponent(instance: Object3D, cb: ForEachComponentCallback, recursive: boolean, level: number = 0): any {
|
|
167
184
|
if (!instance) return;
|
|
168
185
|
if (!instance.isObject3D) {
|
|
@@ -512,6 +512,17 @@ export class Input extends EventTarget {
|
|
|
512
512
|
private onDown(evt: PointerEventArgs) {
|
|
513
513
|
if (debug) console.log(evt.pointerType, "DOWN", evt.button);
|
|
514
514
|
if (!this.isInRect(evt)) return;
|
|
515
|
+
|
|
516
|
+
// check if we received an mouse UP event for a touch (for some reason we get a mouse.down for touch.up)
|
|
517
|
+
if (evt.pointerType === PointerType.Mouse) {
|
|
518
|
+
const upTime = this._pointerUpTimestamp[evt.button];
|
|
519
|
+
if (upTime > 0 && upTime === evt.source?.timeStamp) {
|
|
520
|
+
// we received an UP event for a touch, ignore this DOWN event
|
|
521
|
+
if(debug) console.log("Ignoring mouse.down for touch.up");
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
515
526
|
this.setPointerState(evt.button, this._pointerPressed, true);
|
|
516
527
|
this.setPointerState(evt.button, this._pointerDown, true);
|
|
517
528
|
this.setPointerStateT(evt.button, this._pointerEvent, evt.source);
|
|
@@ -49,10 +49,20 @@ class MathHelper {
|
|
|
49
49
|
return radians * 180 / Math.PI;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
readonly Rad2Deg = 180 / Math.PI;
|
|
53
|
+
|
|
52
54
|
toRadians(degrees: number) {
|
|
53
55
|
return degrees * Math.PI / 180;
|
|
54
56
|
}
|
|
55
57
|
|
|
58
|
+
readonly Deg2Rad = Math.PI / 180;
|
|
59
|
+
|
|
60
|
+
readonly Epsilon = 0.00001;
|
|
61
|
+
|
|
62
|
+
tan(radians: number) {
|
|
63
|
+
return Math.tan(radians);
|
|
64
|
+
}
|
|
65
|
+
|
|
56
66
|
gammaToLinear(gamma: number) {
|
|
57
67
|
return Math.pow(gamma, 2.2);
|
|
58
68
|
}
|
|
@@ -7,6 +7,7 @@ import { TypeStore } from "../engine/engine_typestore";
|
|
|
7
7
|
import { assign } from "../engine/engine_serialization_core";
|
|
8
8
|
import { Mathf } from "../engine/engine_math";
|
|
9
9
|
import { isAnimationAction } from "../engine/engine_three_utils";
|
|
10
|
+
import { isDevEnvironment } from "../engine/debug";
|
|
10
11
|
|
|
11
12
|
const debug = getParam("debuganimatorcontroller");
|
|
12
13
|
const debugRootMotion = getParam("debugrootmotion");
|
|
@@ -407,7 +408,12 @@ export class AnimatorController {
|
|
|
407
408
|
}
|
|
408
409
|
}
|
|
409
410
|
}
|
|
410
|
-
else
|
|
411
|
+
else if (isDevEnvironment()) {
|
|
412
|
+
if (!state["__warned_no_motion"]) {
|
|
413
|
+
state["__warned_no_motion"] = true;
|
|
414
|
+
console.warn("No action", state.motion, this);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
411
417
|
|
|
412
418
|
if (debug)
|
|
413
419
|
console.log("TRANSITION FROM " + prev?.name + " TO " + state.name, durationInSec, prevAction, action, action?.getEffectiveTimeScale(), action?.getEffectiveWeight(), action?.isRunning(), action?.isScheduled(), action?.paused);
|
|
@@ -8,7 +8,7 @@ import { getParam, isMobileDevice } from "../engine/engine_utils";
|
|
|
8
8
|
|
|
9
9
|
import { Camera as ThreeCamera, Box3, Object3D, PerspectiveCamera, Vector2, Vector3 } from "three";
|
|
10
10
|
import { OrbitControls as ThreeOrbitControls } from "three/examples/jsm/controls/OrbitControls";
|
|
11
|
-
import { EventSystem, EventSystemEvents } from "./ui/EventSystem";
|
|
11
|
+
import { AfterHandleInputEvent, EventSystem, EventSystemEvents } from "./ui/EventSystem";
|
|
12
12
|
import { ICameraController } from "../engine/engine_types";
|
|
13
13
|
import { setCameraController } from "../engine/engine_camera";
|
|
14
14
|
import { SyncedTransform } from "./SyncedTransform";
|
|
@@ -176,15 +176,22 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
private onControlsChangeStarted() {
|
|
179
|
-
if(this._syncedTransform) {
|
|
179
|
+
if (this._syncedTransform) {
|
|
180
180
|
this._syncedTransform.requestOwnership();
|
|
181
181
|
}
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
private _shouldDisable: boolean = false;
|
|
185
|
-
private afterHandleInput() {
|
|
186
|
-
if (
|
|
187
|
-
|
|
185
|
+
private afterHandleInput(evt: CustomEvent<AfterHandleInputEvent>) {
|
|
186
|
+
if (evt.detail.args.pointerId === 0) {
|
|
187
|
+
if (evt.detail.args.isDown) {
|
|
188
|
+
if (this._controls && this._eventSystem) {
|
|
189
|
+
this._shouldDisable = this._eventSystem.hasActiveUI;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
else if (!evt.detail.args.isPressed || evt.detail.args.isUp) {
|
|
193
|
+
this._shouldDisable = false;
|
|
194
|
+
}
|
|
188
195
|
}
|
|
189
196
|
}
|
|
190
197
|
|
|
@@ -205,6 +212,7 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
205
212
|
|
|
206
213
|
onBeforeRender() {
|
|
207
214
|
if (!this._controls) return;
|
|
215
|
+
if (this._cameraObject !== this.context.mainCamera) return;
|
|
208
216
|
|
|
209
217
|
if (this.context.input.getPointerDown(0) || this.context.input.getPointerDown(1) || this.context.input.getPointerDown(2)) {
|
|
210
218
|
this._inputs += 1;
|
|
@@ -267,7 +275,7 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
267
275
|
if (this._controls && !this.context.isInXR) {
|
|
268
276
|
if (this.debugLog)
|
|
269
277
|
this._controls.domElement = this.context.renderer.domElement;
|
|
270
|
-
this._controls.enabled = !this._shouldDisable;
|
|
278
|
+
this._controls.enabled = !this._shouldDisable && this._camera === this.context.mainCameraComponent;
|
|
271
279
|
this._controls.update();
|
|
272
280
|
}
|
|
273
281
|
}
|
|
@@ -9,57 +9,78 @@ import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
|
|
|
9
9
|
export class TransformGizmo extends Behaviour {
|
|
10
10
|
|
|
11
11
|
@serializable()
|
|
12
|
-
public isGizmo: boolean =
|
|
12
|
+
public isGizmo: boolean = false;
|
|
13
|
+
|
|
14
|
+
@serializable()
|
|
15
|
+
public translationSnap: number = 1;
|
|
16
|
+
|
|
17
|
+
@serializable()
|
|
18
|
+
public rotationSnapAngle: number = 15;
|
|
19
|
+
|
|
20
|
+
@serializable()
|
|
21
|
+
public scaleSnap: number = .25;
|
|
13
22
|
|
|
14
23
|
private control?: TransformControls;
|
|
15
24
|
private orbit?: OrbitControls;
|
|
16
25
|
|
|
17
|
-
|
|
26
|
+
onEnable() {
|
|
18
27
|
if (this.isGizmo && !params.showGizmos) return;
|
|
28
|
+
|
|
19
29
|
if (!this.context.mainCamera) return;
|
|
20
|
-
this.control = new TransformControls(this.context.mainCamera, this.context.renderer.domElement);
|
|
21
|
-
this.control.visible = true;
|
|
22
|
-
this.control.enabled = true;
|
|
23
|
-
this.control.getRaycaster().layers.set(2);
|
|
24
|
-
|
|
25
|
-
this.control.size = 0.6;
|
|
26
|
-
this.control.traverse(x => {
|
|
27
|
-
const mesh = x as Mesh;
|
|
28
|
-
mesh.layers.set(2);
|
|
29
|
-
if (mesh) {
|
|
30
|
-
const gizmoMat = mesh.material as THREE.MeshBasicMaterial;
|
|
31
|
-
if (gizmoMat) {
|
|
32
|
-
gizmoMat.opacity = 0.3;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
30
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
this.
|
|
31
|
+
if (!this.control) {
|
|
32
|
+
this.control = new TransformControls(this.context.mainCamera, this.context.domElement);
|
|
33
|
+
this.control.visible = true;
|
|
34
|
+
this.control.enabled = true;
|
|
35
|
+
this.control.getRaycaster().layers.set(2);
|
|
36
|
+
this.control.size = 1;
|
|
37
|
+
this.control.traverse(x => {
|
|
38
|
+
const mesh = x as Mesh;
|
|
39
|
+
mesh.layers.set(2);
|
|
40
|
+
if (mesh) {
|
|
41
|
+
const gizmoMat = mesh.material as THREE.MeshBasicMaterial;
|
|
42
|
+
if (gizmoMat) {
|
|
43
|
+
gizmoMat.opacity = 0.3;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
this.orbit = GameObject.getComponentInParent(this.context.mainCamera, OrbitControls) ?? undefined;
|
|
42
48
|
}
|
|
43
|
-
}
|
|
44
49
|
|
|
45
|
-
private changeEventListener?: any;
|
|
46
|
-
private windowKeyDownListener?: any;
|
|
47
|
-
private windowKeyUpListener?: any;
|
|
48
|
-
|
|
49
|
-
onEnable() {
|
|
50
50
|
if (this.control) {
|
|
51
51
|
this.context.scene.add(this.control);
|
|
52
52
|
this.control.attach(this.gameObject);
|
|
53
|
+
this.changeEventListener = this.onControlChangedEvent.bind(this);
|
|
54
|
+
this.control?.addEventListener('dragging-changed', this.changeEventListener);
|
|
55
|
+
this.addWindowEvents();
|
|
53
56
|
}
|
|
54
|
-
this.changeEventListener = this.onControlChangedEvent.bind(this);
|
|
55
|
-
this.control?.addEventListener('dragging-changed', this.changeEventListener);
|
|
56
|
-
this.attachWindowEvents();
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
private changeEventListener?: any;
|
|
60
|
+
private windowKeyDownListener?: any;
|
|
61
|
+
private windowKeyUpListener?: any;
|
|
62
|
+
|
|
59
63
|
onDisable() {
|
|
60
64
|
this.control?.removeFromParent();
|
|
61
65
|
if (this.changeEventListener)
|
|
62
66
|
this.control?.removeEventListener('dragging-changed', this.changeEventListener);
|
|
67
|
+
this.removeWindowEvents();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
enableSnapping() {
|
|
71
|
+
if (this.control) {
|
|
72
|
+
this.control.setTranslationSnap(this.translationSnap);
|
|
73
|
+
this.control.setRotationSnap(MathUtils.degToRad(this.rotationSnapAngle));
|
|
74
|
+
this.control.setScaleSnap(this.scaleSnap);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
disableSnapping() {
|
|
79
|
+
if (this.control) {
|
|
80
|
+
this.control.setTranslationSnap(null);
|
|
81
|
+
this.control.setRotationSnap(null);
|
|
82
|
+
this.control.setScaleSnap(null);
|
|
83
|
+
}
|
|
63
84
|
}
|
|
64
85
|
|
|
65
86
|
private onControlChangedEvent(event) {
|
|
@@ -74,12 +95,13 @@ export class TransformGizmo extends Behaviour {
|
|
|
74
95
|
}
|
|
75
96
|
}
|
|
76
97
|
|
|
77
|
-
private
|
|
98
|
+
private addWindowEvents() {
|
|
78
99
|
const control = this.control;
|
|
79
100
|
if (!control) return;
|
|
80
101
|
|
|
81
102
|
if (!this.windowKeyDownListener) {
|
|
82
103
|
this.windowKeyDownListener = (event) => {
|
|
104
|
+
if (!this.enabled) return;
|
|
83
105
|
switch (event.keyCode) {
|
|
84
106
|
|
|
85
107
|
case 81: // Q
|
|
@@ -87,9 +109,7 @@ export class TransformGizmo extends Behaviour {
|
|
|
87
109
|
break;
|
|
88
110
|
|
|
89
111
|
case 16: // Shift
|
|
90
|
-
|
|
91
|
-
control.setRotationSnap(MathUtils.degToRad(15));
|
|
92
|
-
control.setScaleSnap(0.25);
|
|
112
|
+
this.enableSnapping();
|
|
93
113
|
break;
|
|
94
114
|
|
|
95
115
|
case 87: // W
|
|
@@ -103,34 +123,6 @@ export class TransformGizmo extends Behaviour {
|
|
|
103
123
|
case 82: // R
|
|
104
124
|
control.setMode('scale');
|
|
105
125
|
break;
|
|
106
|
-
|
|
107
|
-
/*
|
|
108
|
-
case 67: // C
|
|
109
|
-
const position = currentCamera.position.clone();
|
|
110
|
-
|
|
111
|
-
currentCamera = currentCamera.isPerspectiveCamera ? cameraOrtho : cameraPersp;
|
|
112
|
-
currentCamera.position.copy( position );
|
|
113
|
-
|
|
114
|
-
orbit.object = currentCamera;
|
|
115
|
-
control.camera = currentCamera;
|
|
116
|
-
|
|
117
|
-
currentCamera.lookAt( orbit.target.x, orbit.target.y, orbit.target.z );
|
|
118
|
-
onWindowResize();
|
|
119
|
-
break;
|
|
120
|
-
|
|
121
|
-
case 86: // V
|
|
122
|
-
const randomFoV = Math.random() + 0.1;
|
|
123
|
-
const randomZoom = Math.random() + 0.1;
|
|
124
|
-
|
|
125
|
-
cameraPersp.fov = randomFoV * 160;
|
|
126
|
-
cameraOrtho.bottom = - randomFoV * 500;
|
|
127
|
-
cameraOrtho.top = randomFoV * 500;
|
|
128
|
-
|
|
129
|
-
cameraPersp.zoom = randomZoom * 5;
|
|
130
|
-
cameraOrtho.zoom = randomZoom * 5;
|
|
131
|
-
onWindowResize();
|
|
132
|
-
break;
|
|
133
|
-
*/
|
|
134
126
|
case 187:
|
|
135
127
|
case 107: // +, =, num+
|
|
136
128
|
control.setSize(control.size + 0.1);
|
|
@@ -164,13 +156,10 @@ export class TransformGizmo extends Behaviour {
|
|
|
164
156
|
|
|
165
157
|
if (!this.windowKeyUpListener) {
|
|
166
158
|
this.windowKeyUpListener = (event) => {
|
|
167
|
-
|
|
159
|
+
if (!this.enabled) return;
|
|
168
160
|
switch (event.keyCode) {
|
|
169
|
-
|
|
170
161
|
case 16: // Shift
|
|
171
|
-
|
|
172
|
-
control.setRotationSnap(null);
|
|
173
|
-
control.setScaleSnap(null);
|
|
162
|
+
this.disableSnapping();
|
|
174
163
|
break;
|
|
175
164
|
|
|
176
165
|
}
|
|
@@ -178,8 +167,13 @@ export class TransformGizmo extends Behaviour {
|
|
|
178
167
|
};
|
|
179
168
|
}
|
|
180
169
|
|
|
181
|
-
|
|
170
|
+
|
|
182
171
|
window.addEventListener('keydown', this.windowKeyDownListener);
|
|
183
172
|
window.addEventListener('keyup', this.windowKeyUpListener);
|
|
184
173
|
}
|
|
174
|
+
|
|
175
|
+
private removeWindowEvents() {
|
|
176
|
+
window.removeEventListener('keydown', this.windowKeyDownListener);
|
|
177
|
+
window.removeEventListener('keyup', this.windowKeyUpListener);
|
|
178
|
+
}
|
|
185
179
|
}
|
|
@@ -74,13 +74,13 @@ export { Image } from "../ui/Image";
|
|
|
74
74
|
export { InheritVelocityModule } from "../ParticleSystemModules";
|
|
75
75
|
export { InputField } from "../ui/InputField";
|
|
76
76
|
export { Interactable } from "../Interactable";
|
|
77
|
-
export { Keyboard } from "../ui/Keyboard";
|
|
78
77
|
export { LayoutGroup } from "../ui/Layout";
|
|
79
78
|
export { Light } from "../Light";
|
|
80
79
|
export { LimitVelocityOverLifetimeModule } from "../ParticleSystemModules";
|
|
81
80
|
export { LODGroup } from "../LODGroup";
|
|
82
81
|
export { LODModel } from "../LODGroup";
|
|
83
82
|
export { LogStats } from "../debug/LogStats";
|
|
83
|
+
export { LookAt } from "../utils/LookAt";
|
|
84
84
|
export { LookAtConstraint } from "../LookAtConstraint";
|
|
85
85
|
export { MainModule } from "../ParticleSystemModules";
|
|
86
86
|
export { MaskableGraphic } from "../ui/Graphic";
|
|
@@ -95,6 +95,7 @@ export { ObjectRaycaster } from "../ui/Raycaster";
|
|
|
95
95
|
export { OffsetConstraint } from "../OffsetConstraint";
|
|
96
96
|
export { OpenURL } from "../utils/OpenURL";
|
|
97
97
|
export { OrbitControls } from "../OrbitControls";
|
|
98
|
+
export { Outline } from "../ui/Outline";
|
|
98
99
|
export { ParticleBurst } from "../ParticleSystemModules";
|
|
99
100
|
export { ParticleSubEmitter } from "../ParticleSystemSubEmitter";
|
|
100
101
|
export { ParticleSystem } from "../ParticleSystem";
|
|
@@ -69,9 +69,9 @@ export class Button extends Behaviour implements IPointerEventHandler {
|
|
|
69
69
|
console.log("Button Enter", this.animationTriggers?.highlightedTrigger, this.animator);
|
|
70
70
|
this._isHovered = true;
|
|
71
71
|
if (this.transition == Transition.Animation && this.animationTriggers && this.animator) {
|
|
72
|
-
this.animator.
|
|
72
|
+
this.animator.setTrigger(this.animationTriggers.highlightedTrigger);
|
|
73
73
|
}
|
|
74
|
-
else if(this.transition === Transition.ColorTint && this.colors) {
|
|
74
|
+
else if (this.transition === Transition.ColorTint && this.colors) {
|
|
75
75
|
this._image?.setState("hovered");
|
|
76
76
|
}
|
|
77
77
|
this.context.input.setCursorPointer();
|
|
@@ -82,9 +82,9 @@ export class Button extends Behaviour implements IPointerEventHandler {
|
|
|
82
82
|
console.log("Button Exit", this.animationTriggers?.highlightedTrigger, this.animator);
|
|
83
83
|
this._isHovered = false;
|
|
84
84
|
if (this.transition == Transition.Animation && this.animationTriggers && this.animator) {
|
|
85
|
-
this.animator.
|
|
85
|
+
this.animator.setTrigger(this.animationTriggers.normalTrigger);
|
|
86
86
|
}
|
|
87
|
-
else if(this.transition === Transition.ColorTint && this.colors) {
|
|
87
|
+
else if (this.transition === Transition.ColorTint && this.colors) {
|
|
88
88
|
this._image?.setState("normal");
|
|
89
89
|
}
|
|
90
90
|
this.context.input.setCursorNormal();
|
|
@@ -94,9 +94,9 @@ export class Button extends Behaviour implements IPointerEventHandler {
|
|
|
94
94
|
if (debug)
|
|
95
95
|
console.log("Button Down", this.animationTriggers?.highlightedTrigger, this.animator);
|
|
96
96
|
if (this.transition == Transition.Animation && this.animationTriggers && this.animator) {
|
|
97
|
-
this.animator.
|
|
97
|
+
this.animator.setTrigger(this.animationTriggers.pressedTrigger);
|
|
98
98
|
}
|
|
99
|
-
else if(this.transition === Transition.ColorTint && this.colors) {
|
|
99
|
+
else if (this.transition === Transition.ColorTint && this.colors) {
|
|
100
100
|
this._image?.setState("pressed");
|
|
101
101
|
}
|
|
102
102
|
}
|
|
@@ -105,9 +105,9 @@ export class Button extends Behaviour implements IPointerEventHandler {
|
|
|
105
105
|
if (debug)
|
|
106
106
|
console.warn("Button Up", this.animationTriggers?.highlightedTrigger, this.animator, this._isHovered);
|
|
107
107
|
if (this.transition == Transition.Animation && this.animationTriggers && this.animator) {
|
|
108
|
-
this.animator.
|
|
108
|
+
this.animator.setTrigger(this._isHovered ? this.animationTriggers.highlightedTrigger : this.animationTriggers.normalTrigger);
|
|
109
109
|
}
|
|
110
|
-
else if(this.transition === Transition.ColorTint && this.colors) {
|
|
110
|
+
else if (this.transition === Transition.ColorTint && this.colors) {
|
|
111
111
|
this._image?.setState(this._isHovered ? "hovered" : "normal");
|
|
112
112
|
}
|
|
113
113
|
}
|
|
@@ -197,6 +197,10 @@ export class Button extends Behaviour implements IPointerEventHandler {
|
|
|
197
197
|
private stateSetup(image: Image) {
|
|
198
198
|
image.setInteractable(this.interactable);
|
|
199
199
|
|
|
200
|
+
// @marwie : If this piece of code could be moved to the SimpleStateBehavior instanciation location,
|
|
201
|
+
// Its setup could be eased :
|
|
202
|
+
// @see https://github.com/felixmariotto/three-mesh-ui/blob/7.1.x/examples/ex__keyboard.js#L407
|
|
203
|
+
|
|
200
204
|
const normal = this.getFinalColor(image.color, this.colors?.normalColor);
|
|
201
205
|
const normalState = {
|
|
202
206
|
state: "normal",
|
|
@@ -242,7 +246,8 @@ export class Button extends Behaviour implements IPointerEventHandler {
|
|
|
242
246
|
state: "disabled",
|
|
243
247
|
attributes: {
|
|
244
248
|
backgroundColor: disabled,
|
|
245
|
-
|
|
249
|
+
// @marwie, this disabled alpha property doesn't seem to have the opacity requested in unity
|
|
250
|
+
backgroundOpacity: disabled.alpha
|
|
246
251
|
}
|
|
247
252
|
};
|
|
248
253
|
image.setupState(disabledState);
|