File without changes
|
@@ -16,15 +16,18 @@
|
|
16
16
|
* @returns {import('next').NextConfig}
|
17
17
|
*/
|
18
18
|
export const needleNext = (nextConfig, userSettings) => {
|
19
|
-
|
20
|
-
reactStrictMode: true,
|
21
|
-
};
|
19
|
+
console.log("Apply 🌵 needle next config");
|
22
20
|
|
21
|
+
if (!nextConfig)
|
22
|
+
nextConfig = {
|
23
|
+
reactStrictMode: true,
|
24
|
+
};
|
25
|
+
|
23
26
|
// add transpile packages
|
24
27
|
if (!nextConfig.transpilePackages) {
|
25
28
|
nextConfig.transpilePackages = [];
|
26
29
|
}
|
27
|
-
nextConfig.transpilePackages.push("three", "peerjs", "
|
30
|
+
nextConfig.transpilePackages.push("three", "peerjs", "three-mesh-ui");
|
28
31
|
|
29
32
|
// add webpack config
|
30
33
|
if (!nextConfig.webpack) nextConfig.webpack = nextWebPack;
|
@@ -37,6 +40,12 @@
|
|
37
40
|
}
|
38
41
|
/** @param {import ('next').NextConfig config } */
|
39
42
|
function nextWebPack(config, { buildId, dev, isServer, defaultLoaders, webpack }) {
|
43
|
+
|
44
|
+
// workaround: fix type finding in production builds
|
45
|
+
console.log("Apply next webpack config concatentateModules=false, pathinfo=verbose");
|
46
|
+
config.optimization.concatenateModules = false;
|
47
|
+
config.output.pathinfo = 'verbose';
|
48
|
+
|
40
49
|
const meta = getMeta();
|
41
50
|
let useRapier = true;
|
42
51
|
if (userSettings.useRapier === false) useRapier = false;
|
@@ -1,2 +0,0 @@
|
|
1
|
-
Using flatbuffer compiler 2.0
|
2
|
-
https://github.com/google/flatbuffers/releases/tag/v2.0.0
|
@@ -1,7 +1,6 @@
|
|
1
|
-
import {
|
2
|
-
|
3
|
-
import { USDDocument,USDObject } from "../../ThreeUSDZExporter.js";
|
1
|
+
import { Object3D, Matrix4, Material, BufferGeometry } from "three";
|
4
2
|
import { ActionBuilder, ActionModel } from "./BehavioursBuilder.js";
|
3
|
+
import { USDObject, USDDocument } from "../../ThreeUSDZExporter.js";
|
5
4
|
|
6
5
|
export abstract class DocumentAction {
|
7
6
|
|
@@ -1,8 +1,7 @@
|
|
1
|
+
import { Behaviour, GameObject } from "./Component.js";
|
2
|
+
import * as utils from "./../engine/engine_three_utils.js";
|
1
3
|
import { Vector3 } from "three";
|
2
|
-
|
3
4
|
import { serializable } from "../engine/engine_serialization_decorator.js";
|
4
|
-
import * as utils from "./../engine/engine_three_utils.js";
|
5
|
-
import { Behaviour, GameObject } from "./Component.js";
|
6
5
|
|
7
6
|
export class AlignmentConstraint extends Behaviour {
|
8
7
|
|
@@ -1,11 +1,10 @@
|
|
1
|
+
import { Behaviour } from "./Component.js";
|
1
2
|
import { AnimationAction, AnimationClip, AnimationMixer, LoopOnce, LoopRepeat } from "three";
|
2
|
-
|
3
|
+
import { MixerEvent } from "./Animator.js";
|
4
|
+
import { serializable } from "../engine/engine_serialization_decorator.js";
|
3
5
|
import { Mathf } from "../engine/engine_math.js";
|
4
|
-
import { serializable } from "../engine/engine_serialization_decorator.js";
|
5
6
|
import type { Vec2 } from "../engine/engine_types.js";
|
6
7
|
import { getParam } from "../engine/engine_utils.js";
|
7
|
-
import { MixerEvent } from "./Animator.js";
|
8
|
-
import { Behaviour } from "./Component.js";
|
9
8
|
|
10
9
|
const debug = getParam("debuganimation");
|
11
10
|
|
@@ -1,10 +1,9 @@
|
|
1
|
-
import {
|
2
|
-
|
1
|
+
import { GameObject } from "../../../Component.js";
|
3
2
|
import { getParam } from "../../../../engine/engine_utils.js";
|
3
|
+
import { USDObject, buildMatrix, findStructuralNodesInBoneHierarchy, usdNumberFormatting as fn, getPathToSkeleton } from "../ThreeUSDZExporter.js";
|
4
|
+
import type { IUSDExporterExtension } from "../Extension.js";
|
5
|
+
import { Object3D, Matrix4, Vector3, Quaternion, Interpolant, AnimationClip, KeyframeTrack, PropertyBinding, Bone } from "three";
|
4
6
|
import { Animator } from "../../../Animator.js";
|
5
|
-
import { GameObject } from "../../../Component.js";
|
6
|
-
import type { IUSDExporterExtension } from "../Extension.js";
|
7
|
-
import { buildMatrix, findStructuralNodesInBoneHierarchy, getPathToSkeleton,usdNumberFormatting as fn, USDObject } from "../ThreeUSDZExporter.js";
|
8
7
|
|
9
8
|
const debug = getParam("debugusdzanimation");
|
10
9
|
const debugSerialization = getParam("debugusdzanimationserialization");
|
@@ -23,22 +23,6 @@
|
|
23
23
|
@serializable(Keyframe)
|
24
24
|
keys!: Array<Keyframe>;
|
25
25
|
|
26
|
-
clone() {
|
27
|
-
const curve = new AnimationCurve();
|
28
|
-
curve.keys = this.keys?.map(k => {
|
29
|
-
const key = new Keyframe();
|
30
|
-
key.time = k.time;
|
31
|
-
key.value = k.value;
|
32
|
-
key.inTangent = k.inTangent;
|
33
|
-
key.inWeight = k.inWeight;
|
34
|
-
key.outTangent = k.outTangent;
|
35
|
-
key.outWeight = k.outWeight;
|
36
|
-
key.weightedMode = k.weightedMode;
|
37
|
-
return key;
|
38
|
-
}) || [];
|
39
|
-
return curve;
|
40
|
-
}
|
41
|
-
|
42
26
|
get duration(): number {
|
43
27
|
if (!this.keys || this.keys.length == 0) return 0;
|
44
28
|
return this.keys[this.keys.length - 1].time;
|
@@ -54,9 +38,9 @@
|
|
54
38
|
for (let i = 0; i < this.keys.length; i++) {
|
55
39
|
const kf = this.keys[i];
|
56
40
|
if (kf.time <= time) {
|
57
|
-
const hasNextKeyframe = i
|
41
|
+
const hasNextKeyframe = i+1 < this.keys.length;
|
58
42
|
if (hasNextKeyframe) {
|
59
|
-
const nextKf = this.keys[i
|
43
|
+
const nextKf = this.keys[i+1];
|
60
44
|
// if the next
|
61
45
|
if (nextKf.time < time) continue;
|
62
46
|
// tangents are set to Infinity if interpolation is set to constant - in that case we should always return the floored value
|
@@ -1,12 +1,11 @@
|
|
1
|
-
import { Object3D } from "three";
|
2
1
|
import type { GLTF } from "three/examples/jsm/loaders/GLTFLoader.js";
|
3
|
-
|
2
|
+
import { ContextEvent, ContextRegistry } from "../engine/engine_context_registry.js";
|
4
3
|
import { addNewComponent } from "../engine/engine_components.js";
|
5
|
-
import {
|
4
|
+
import { Animator } from "./Animator.js";
|
6
5
|
import { Animation } from "./Animation.js";
|
7
|
-
import { Animator } from "./Animator.js";
|
8
6
|
import { GameObject } from "./Component.js";
|
9
7
|
import { PlayableDirector } from "./timeline/PlayableDirector.js";
|
8
|
+
import { Object3D } from "three";
|
10
9
|
|
11
10
|
|
12
11
|
const $objectAnimationKey = Symbol("objectIsAnimatedData");
|
@@ -1,10 +1,9 @@
|
|
1
|
-
import {
|
2
|
-
|
3
|
-
import { getParam } from "../../../../engine/engine_utils.js";
|
1
|
+
import { Animator } from "../../../Animator.js";
|
4
2
|
import { Animation } from "../../../Animation.js";
|
5
|
-
import {
|
3
|
+
import { Object3D, AnimationClip } from "three";
|
4
|
+
import { AnimationExtension } from "../extensions/Animation.js";
|
6
5
|
import { Behaviour, GameObject } from "../../../Component.js";
|
7
|
-
import {
|
6
|
+
import { getParam } from "../../../../engine/engine_utils.js";
|
8
7
|
import { PlayAnimationOnClick } from "../extensions/behavior/BehaviourComponents.js";
|
9
8
|
|
10
9
|
const debug = getParam("debugusdz");
|
@@ -1,12 +1,11 @@
|
|
1
|
-
import
|
2
|
-
|
3
|
-
import { Mathf } from "../engine/engine_math.js";
|
4
|
-
import { serializable } from "../engine/engine_serialization_decorator.js";
|
1
|
+
import { Behaviour } from "./Component.js";
|
2
|
+
import type { AnimationActionLoopStyles, AnimationAction, AnimationMixer } from "three";
|
5
3
|
import { getParam } from "../engine/engine_utils.js";
|
6
4
|
import type { AnimatorControllerModel } from "../engine/extensions/NEEDLE_animator_controller_model.js";
|
5
|
+
import { AnimatorController } from "./AnimatorController.js";
|
6
|
+
import { serializable } from "../engine/engine_serialization_decorator.js";
|
7
|
+
import { Mathf } from "../engine/engine_math.js";
|
7
8
|
import { getObjectAnimated } from "./AnimationUtils.js";
|
8
|
-
import { AnimatorController } from "./AnimatorController.js";
|
9
|
-
import { Behaviour } from "./Component.js";
|
10
9
|
|
11
10
|
const debug = getParam("debuganimator");
|
12
11
|
|
@@ -1,16 +1,15 @@
|
|
1
|
+
import { Animator } from "./Animator.js";
|
2
|
+
import type { AnimatorControllerModel, Condition, State, Transition } from "../engine/extensions/NEEDLE_animator_controller_model.js";
|
3
|
+
import { AnimatorConditionMode, AnimatorControllerParameterType, AnimatorStateInfo, createMotion, StateMachineBehaviour } from "../engine/extensions/NEEDLE_animator_controller_model.js";
|
1
4
|
import { AnimationAction, AnimationClip, AnimationMixer, AxesHelper, Euler, KeyframeTrack, LoopOnce, Object3D, Quaternion, Vector3 } from "three";
|
2
|
-
|
5
|
+
import { deepClone, getParam } from "../engine/engine_utils.js";
|
6
|
+
import { Context } from "../engine/engine_setup.js";
|
7
|
+
import { TypeStore } from "../engine/engine_typestore.js";
|
8
|
+
import { SerializationContext, TypeSerializer, assign } from "../engine/engine_serialization_core.js";
|
9
|
+
import { Mathf } from "../engine/engine_math.js";
|
10
|
+
import { isAnimationAction } from "../engine/engine_three_utils.js";
|
3
11
|
import { isDevEnvironment } from "../engine/debug/index.js";
|
4
|
-
import { Mathf } from "../engine/engine_math.js";
|
5
12
|
import { InstantiateIdProvider } from "../engine/engine_networking_instantiate.js";
|
6
|
-
import { assign,SerializationContext, TypeSerializer } from "../engine/engine_serialization_core.js";
|
7
|
-
import { Context } from "../engine/engine_setup.js";
|
8
|
-
import { isAnimationAction } from "../engine/engine_three_utils.js";
|
9
|
-
import { TypeStore } from "../engine/engine_typestore.js";
|
10
|
-
import { deepClone, getParam } from "../engine/engine_utils.js";
|
11
|
-
import type { AnimatorControllerModel, Condition, State, Transition } from "../engine/extensions/NEEDLE_animator_controller_model.js";
|
12
|
-
import { AnimatorConditionMode, AnimatorControllerParameterType, AnimatorStateInfo, createMotion, StateMachineBehaviour } from "../engine/extensions/NEEDLE_animator_controller_model.js";
|
13
|
-
import { Animator } from "./Animator.js";
|
14
13
|
|
15
14
|
const debug = getParam("debuganimatorcontroller");
|
16
15
|
const debugRootMotion = getParam("debugrootmotion");
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import { EdgeDetectionMode, SMAAEffect, SMAAPreset } from "postprocessing";
|
2
|
-
|
3
2
|
import { serializable } from "../../../engine/engine_serialization.js";
|
4
3
|
import { type EffectProviderResult, PostProcessingEffect } from "../PostProcessingEffect.js";
|
5
4
|
import { VolumeParameter } from "../VolumeParameter.js";
|
@@ -1,18 +1,20 @@
|
|
1
|
+
export { Behaviour, Component, GameObject } from "./Component.js"
|
1
2
|
export * from "./codegen/components.js";
|
2
|
-
export { Behaviour, Component, GameObject } from "./Component.js"
|
3
3
|
|
4
4
|
// We dont want to export everything in the extensions
|
5
|
-
export
|
5
|
+
export * from "./js-extensions/RGBAColor.js";
|
6
|
+
export * from "./js-extensions/Object3D.js";
|
7
|
+
export * from "./XRFlag.js"
|
8
|
+
|
6
9
|
export * from "./export/index.js"
|
7
|
-
export * from "./js-extensions/Object3D.js";
|
8
|
-
export * from "./js-extensions/RGBAColor.js";
|
9
10
|
export * from "./postprocessing/index.js"
|
10
|
-
export { type ISceneEventListener } from "./SceneSwitcher.js";
|
11
11
|
export * from "./timeline/index.js"
|
12
12
|
export * from "./ui/index.js"
|
13
13
|
export * from "./webxr/index.js"
|
14
|
-
export * from "./webxr/XRFlag.js"
|
15
14
|
|
15
|
+
export { ClearFlags } from "./Camera.js"
|
16
|
+
export { type ISceneEventListener } from "./SceneSwitcher.js";
|
17
|
+
|
16
18
|
import "./CameraUtils.js"
|
17
19
|
import "./AnimationUtils.js"
|
18
20
|
|
@@ -1,42 +1,42 @@
|
|
1
1
|
|
2
|
-
export * from "./
|
2
|
+
export * from "./extensions/index.js";
|
3
3
|
export * from "./engine_addressables.js";
|
4
4
|
export * from "./engine_application.js";
|
5
5
|
export * from "./engine_assetdatabase.js";
|
6
|
+
export * from "./engine_create_objects.js";
|
7
|
+
export * from "./engine_components_internal.js";
|
6
8
|
export * from "./engine_components.js";
|
7
9
|
export * from "./engine_components_internal.js";
|
8
|
-
export * from "./
|
9
|
-
export * from "./engine_constants.js";
|
10
|
+
export * from "./engine_context_registry.js";
|
10
11
|
export * from "./engine_context.js";
|
11
|
-
export * from "./engine_context_registry.js";
|
12
12
|
export * from "./engine_coroutine.js"
|
13
|
-
export * from "./
|
13
|
+
export * from "./engine_constants.js";
|
14
|
+
export * from "./debug/index.js";
|
14
15
|
export * from "./engine_element.js";
|
16
|
+
export * from "./engine_element_loading.js";
|
15
17
|
export * from "./engine_element_attributes.js";
|
16
|
-
export * from "./engine_element_loading.js";
|
17
|
-
export * from "./engine_gameobject.js";
|
18
18
|
export { Gizmos } from "./engine_gizmos.js"
|
19
19
|
export * from "./engine_gltf.js";
|
20
20
|
export * from "./engine_hot_reload.js";
|
21
|
-
export * from "./
|
22
|
-
export { InstancingUtil } from "./engine_instancing.js";
|
23
|
-
export { hasIndieLicense,hasProLicense } from "./engine_license.js";
|
24
|
-
export * from "./engine_lifecycle_api.js";
|
25
|
-
export * from "./engine_math.js";
|
21
|
+
export * from "./engine_gameobject.js";
|
26
22
|
export * from "./engine_networking.js";
|
23
|
+
export * from "./engine_networking_types.js";
|
27
24
|
export { syncField } from "./engine_networking_auto.js";
|
28
25
|
export * from "./engine_networking_files.js";
|
29
26
|
export * from "./engine_networking_instantiate.js";
|
30
|
-
export * from "./engine_networking_peer.js";
|
31
27
|
export * from "./engine_networking_streams.js";
|
32
|
-
export * from "./engine_networking_types.js";
|
33
28
|
export * from "./engine_networking_utils.js";
|
29
|
+
export * from "./engine_networking_peer.js";
|
34
30
|
export * from "./engine_patcher.js";
|
31
|
+
export * from "./engine_playerview.js";
|
35
32
|
export * from "./engine_physics.js";
|
36
33
|
export * from "./engine_physics.types.js";
|
37
34
|
export * from "./engine_physics_rapier.js";
|
38
|
-
export * from "./engine_playerview.js";
|
39
35
|
export * from "./engine_scenelighting.js";
|
36
|
+
export * from "./engine_input.js";
|
37
|
+
export * from "./engine_lifecycle_api.js";
|
38
|
+
export * from "./engine_math.js";
|
39
|
+
export * from "./js-extensions/index.js";
|
40
40
|
export * from "./engine_scenetools.js";
|
41
41
|
export * from "./engine_serialization.js";
|
42
42
|
export { type ISerializable } from "./engine_serialization_core.js";
|
@@ -44,11 +44,12 @@
|
|
44
44
|
export * from "./engine_three_utils.js";
|
45
45
|
export * from "./engine_time.js";
|
46
46
|
export * from "./engine_types.js";
|
47
|
-
export { registerType,TypeStore } from "./engine_typestore.js";
|
48
|
-
export { prefix,validate } from "./engine_util_decorator.js";
|
49
|
-
export * from "./engine_utils.js";
|
50
47
|
export * from "./engine_utils_screenshot.js";
|
51
48
|
export * from "./engine_web_api.js";
|
52
|
-
export * from "./
|
53
|
-
|
54
|
-
export
|
49
|
+
export * from "./engine_utils.js";
|
50
|
+
|
51
|
+
export { TypeStore, registerType } from "./engine_typestore.js";
|
52
|
+
|
53
|
+
export { InstancingUtil } from "./engine_instancing.js";
|
54
|
+
export { validate, prefix } from "./engine_util_decorator.js";
|
55
|
+
export { hasProLicense, hasIndieLicense } from "./engine_license.js";
|
@@ -1,9 +1,8 @@
|
|
1
|
-
import { Object3D } from "three";
|
2
|
-
|
3
|
-
import { AudioSource } from "../../../../AudioSource.js";
|
4
1
|
import { GameObject } from "../../../../Component.js";
|
5
2
|
import type { IUSDExporterExtension } from "../../Extension.js";
|
6
3
|
import { USDObject, USDWriter, USDZExporterContext } from "../../ThreeUSDZExporter.js";
|
4
|
+
import { Object3D } from "three";
|
5
|
+
import { AudioSource } from "../../../../AudioSource.js";
|
7
6
|
|
8
7
|
export class AudioExtension implements IUSDExporterExtension {
|
9
8
|
|
@@ -1,8 +1,7 @@
|
|
1
|
+
import { Behaviour, GameObject } from "./Component.js";
|
1
2
|
import { AudioListener as ThreeAudioListener } from "three";
|
2
|
-
|
3
3
|
import { AudioSource } from "./AudioSource.js";
|
4
4
|
import { Camera } from "./Camera.js";
|
5
|
-
import { Behaviour, GameObject } from "./Component.js";
|
6
5
|
|
7
6
|
|
8
7
|
export class AudioListener extends Behaviour {
|
@@ -1,12 +1,11 @@
|
|
1
|
+
import { Behaviour, GameObject } from "./Component.js";
|
2
|
+
import { PositionalAudioHelper } from 'three/examples/jsm/helpers/PositionalAudioHelper.js';
|
3
|
+
import { AudioListener } from "./AudioListener.js";
|
4
|
+
import * as utils from "../engine/engine_utils.js";
|
5
|
+
import { serializable } from "../engine/engine_serialization_decorator.js";
|
6
|
+
import { ApplicationEvents } from "../engine/engine_application.js";
|
1
7
|
import { Audio, AudioContext, AudioLoader, PositionalAudio } from "three";
|
2
|
-
import { PositionalAudioHelper } from 'three/examples/jsm/helpers/PositionalAudioHelper.js';
|
3
|
-
|
4
8
|
import { isDevEnvironment } from "../engine/debug/index.js";
|
5
|
-
import { ApplicationEvents } from "../engine/engine_application.js";
|
6
|
-
import { serializable } from "../engine/engine_serialization_decorator.js";
|
7
|
-
import * as utils from "../engine/engine_utils.js";
|
8
|
-
import { AudioListener } from "./AudioListener.js";
|
9
|
-
import { Behaviour, GameObject } from "./Component.js";
|
10
9
|
|
11
10
|
|
12
11
|
const debug = utils.getParam("debugaudio");
|
@@ -141,7 +140,7 @@
|
|
141
140
|
if (!listener && this.context.mainCamera) listener = GameObject.addNewComponent(this.context.mainCamera, AudioListener);
|
142
141
|
if (listener?.listener) {
|
143
142
|
this.sound = new PositionalAudio(listener.listener);
|
144
|
-
this.gameObject
|
143
|
+
this.gameObject.add(this.sound);
|
145
144
|
}
|
146
145
|
else if (debug) console.warn("No audio listener found in scene - can not play audio");
|
147
146
|
}
|
@@ -158,9 +157,6 @@
|
|
158
157
|
}
|
159
158
|
|
160
159
|
onEnable(): void {
|
161
|
-
if (this.sound)
|
162
|
-
this.gameObject.add(this.sound);
|
163
|
-
|
164
160
|
if (!AudioSource.userInteractionRegistered) {
|
165
161
|
AudioSource.registerWaitForAllowAudio(() => {
|
166
162
|
if (this.enabled && !this.destroyed && this.shouldPlay)
|
@@ -332,7 +328,6 @@
|
|
332
328
|
if (this.sound && !this.sound.isPlaying) {
|
333
329
|
const muted = this.context.application.muted;
|
334
330
|
if (muted) this.sound.setVolume(0);
|
335
|
-
this.gameObject?.add(this.sound);
|
336
331
|
|
337
332
|
if (this.clip instanceof MediaStream) {
|
338
333
|
|
@@ -416,7 +411,7 @@
|
|
416
411
|
this._hasEnded = true;
|
417
412
|
if (debug)
|
418
413
|
console.log("Audio clip ended", this.clip);
|
419
|
-
this.dispatchEvent(
|
414
|
+
this.sound.dispatchEvent({ type: 'ended', target: this });
|
420
415
|
}
|
421
416
|
|
422
417
|
// this.gameObject.position.x = Math.sin(time.time) * 2;
|
@@ -1,12 +1,11 @@
|
|
1
1
|
import * as THREE from "three";
|
2
|
-
|
3
|
-
import { OwnershipModel } from "../../engine/engine_networking.js";
|
4
|
-
import type { IModel } from "../../engine/engine_networking_types.js";
|
5
|
-
import { Context } from "../../engine/engine_setup.js";
|
6
|
-
import * as utils from "../../engine/engine_three_utils.js";
|
7
2
|
import { TypeStore } from "../../engine/engine_typestore.js";
|
8
3
|
import { Behaviour, GameObject } from "../Component.js";
|
9
4
|
import { AvatarMarker } from "../webxr/WebXRAvatar.js";
|
5
|
+
import * as utils from "../../engine/engine_three_utils.js";
|
6
|
+
import { OwnershipModel } from "../../engine/engine_networking.js";
|
7
|
+
import { Context } from "../../engine/engine_setup.js";
|
8
|
+
import type { IModel } from "../../engine/engine_networking_types.js";
|
10
9
|
|
11
10
|
export class Avatar_POI {
|
12
11
|
|
@@ -1,10 +1,9 @@
|
|
1
|
-
import { Object3D } from "three";
|
2
|
-
|
3
|
-
import { serializable } from "../../engine/engine_serialization_decorator.js";
|
4
|
-
import * as utils from "../../engine/engine_utils.js";
|
5
1
|
import { Behaviour, GameObject } from "../Component.js";
|
6
2
|
import { Voip } from "../Voip.js";
|
7
3
|
import { AvatarMarker } from "../webxr/WebXRAvatar.js";
|
4
|
+
import * as utils from "../../engine/engine_utils.js";
|
5
|
+
import { Object3D } from "three";
|
6
|
+
import { serializable } from "../../engine/engine_serialization_decorator.js";
|
8
7
|
|
9
8
|
const debug = utils.getParam("debugmouth");
|
10
9
|
|
@@ -1,221 +0,0 @@
|
|
1
|
-
import { Object3D, Quaternion, Vector3 } from "three";
|
2
|
-
|
3
|
-
import { AssetReference } from "../../engine/engine_addressables.js";
|
4
|
-
import { ObjectUtils, PrimitiveType } from "../../engine/engine_create_objects.js";
|
5
|
-
import { serializable } from "../../engine/engine_serialization_decorator.js";
|
6
|
-
import { IGameObject } from "../../engine/engine_types.js";
|
7
|
-
import { getParam,PromiseAllWithErrors } from "../../engine/engine_utils.js";
|
8
|
-
import { NeedleXREventArgs, NeedleXRSession, NeedleXRUtils } from "../../engine/xr/index.js";
|
9
|
-
import { PlayerState } from "../../engine-components-experimental/networking/PlayerSync.js";
|
10
|
-
import { Behaviour, GameObject } from "../Component.js";
|
11
|
-
import { SyncedTransform } from "../SyncedTransform.js";
|
12
|
-
import { AvatarMarker } from "./WebXRAvatar.js";
|
13
|
-
import { XRFlag } from "./XRFlag.js";
|
14
|
-
|
15
|
-
const debug = getParam("debugwebxr");
|
16
|
-
|
17
|
-
const flipForwardQuaternion = new Quaternion().setFromAxisAngle(new Vector3(0, 1, 0), Math.PI);
|
18
|
-
|
19
|
-
export class Avatar extends Behaviour {
|
20
|
-
|
21
|
-
@serializable(AssetReference)
|
22
|
-
head?: AssetReference;
|
23
|
-
|
24
|
-
@serializable(AssetReference)
|
25
|
-
leftHand?: AssetReference;
|
26
|
-
|
27
|
-
@serializable(AssetReference)
|
28
|
-
rightHand?: AssetReference;
|
29
|
-
|
30
|
-
private _syncTransforms?: SyncedTransform[];
|
31
|
-
|
32
|
-
async onEnterXR(_args: NeedleXREventArgs) {
|
33
|
-
if (!this.activeAndEnabled) return;
|
34
|
-
if (debug) console.warn("AVATAR ENTER XR", this.guid, this.sourceId, this, this.activeAndEnabled)
|
35
|
-
if (this._syncTransforms)
|
36
|
-
this._syncTransforms.length = 0;
|
37
|
-
await this.prepareAvatar();
|
38
|
-
|
39
|
-
const playerstate = PlayerState.getFor(this);
|
40
|
-
if (playerstate?.owner) {
|
41
|
-
const marker = this.gameObject.addNewComponent(AvatarMarker)!;
|
42
|
-
marker.avatar = this.gameObject;
|
43
|
-
marker.connectionId = playerstate.owner;
|
44
|
-
}
|
45
|
-
else if(this.context.connection.isConnected) console.error("No player state found for avatar", this);
|
46
|
-
}
|
47
|
-
|
48
|
-
onLeaveXR(_args: NeedleXREventArgs): void {
|
49
|
-
const marker = this.gameObject.getComponent(AvatarMarker);
|
50
|
-
if (marker) {
|
51
|
-
marker.destroy();
|
52
|
-
}
|
53
|
-
}
|
54
|
-
|
55
|
-
onUpdateXR(args: NeedleXREventArgs): void {
|
56
|
-
if (!this.activeAndEnabled) return;
|
57
|
-
|
58
|
-
const isLocalPlayer = PlayerState.isLocalPlayer(this);
|
59
|
-
if (!isLocalPlayer) return;
|
60
|
-
|
61
|
-
const xr = args.xr;
|
62
|
-
// make sure the avatar is inside the active rig
|
63
|
-
if (xr.rig && xr.rig.gameObject !== this.gameObject.parent) {
|
64
|
-
this.gameObject.position.set(0, 0, 0);
|
65
|
-
this.gameObject.rotation.set(0, 0, 0);
|
66
|
-
this.gameObject.scale.set(1, 1, 1);
|
67
|
-
xr.rig.gameObject.add(this.gameObject);
|
68
|
-
}
|
69
|
-
// this.gameObject.position.copy(xr.rig!.gameObject.position);
|
70
|
-
// this.gameObject.quaternion.copy(xr.rig!.gameObject.quaternion);
|
71
|
-
// this.gameObject.scale.set(1, 1, 1);
|
72
|
-
|
73
|
-
|
74
|
-
if (this._syncTransforms && isLocalPlayer) {
|
75
|
-
for (const sync of this._syncTransforms) {
|
76
|
-
sync.fastMode = true;
|
77
|
-
if (!sync.isOwned())
|
78
|
-
sync.requestOwnership();
|
79
|
-
}
|
80
|
-
}
|
81
|
-
|
82
|
-
|
83
|
-
// synchronize head
|
84
|
-
if (this.head && this.context.mainCamera) {
|
85
|
-
const headObj = this.head.asset as IGameObject;
|
86
|
-
headObj.position.copy(this.context.mainCamera.position);
|
87
|
-
headObj.quaternion.copy(this.context.mainCamera.quaternion);
|
88
|
-
headObj.quaternion.x *= -1;
|
89
|
-
|
90
|
-
// HACK: XRFlag limitation workaround to make sure first person user head is never rendered
|
91
|
-
if (this.context.time.frameCount % 10 === 0) {
|
92
|
-
const xrflags = GameObject.getComponentsInChildren(this.head.asset, XRFlag);
|
93
|
-
for (const flag of xrflags) {
|
94
|
-
flag.enabled = false;
|
95
|
-
flag.gameObject.visible = false;
|
96
|
-
}
|
97
|
-
}
|
98
|
-
}
|
99
|
-
|
100
|
-
// synchronize hands
|
101
|
-
const leftCtrl = args.xr.leftController;
|
102
|
-
const leftObj = this.leftHand?.asset as Object3D;
|
103
|
-
if (leftCtrl && leftObj) {
|
104
|
-
leftObj.position.copy(leftCtrl.gripPosition);
|
105
|
-
leftObj.quaternion.copy(leftCtrl.gripQuaternion);
|
106
|
-
leftObj.quaternion.multiply(flipForwardQuaternion);
|
107
|
-
leftObj.visible = leftCtrl.isTracking;
|
108
|
-
}
|
109
|
-
|
110
|
-
const right = args.xr.rightController;
|
111
|
-
if (right && this.rightHand?.asset) {
|
112
|
-
const rightObj = this.rightHand.asset as Object3D;
|
113
|
-
rightObj.position.copy(right.gripPosition);
|
114
|
-
rightObj.quaternion.copy(right.gripQuaternion);
|
115
|
-
rightObj.quaternion.multiply(flipForwardQuaternion);
|
116
|
-
rightObj.visible = right.isTracking;
|
117
|
-
}
|
118
|
-
}
|
119
|
-
|
120
|
-
onBeforeRender(): void {
|
121
|
-
if (this.context.time.frame % 10 === 0)
|
122
|
-
this.updateRemoteAvatarVisibility();
|
123
|
-
}
|
124
|
-
|
125
|
-
|
126
|
-
private updateRemoteAvatarVisibility() {
|
127
|
-
if (this.context.connection.isConnected) {
|
128
|
-
const state = PlayerState.getFor(this);
|
129
|
-
if (state && state.isLocalPlayer == false) {
|
130
|
-
|
131
|
-
const sync = NeedleXRSession.getXRSync(this.context);
|
132
|
-
if (sync) {
|
133
|
-
if (sync.hasState(state.owner)) {
|
134
|
-
this.tryFindAvatarObjectsIfMissing();
|
135
|
-
|
136
|
-
const leftObj = this.leftHand?.asset as Object3D;
|
137
|
-
if (leftObj) {
|
138
|
-
leftObj.visible = sync?.isTracking(state.owner, "left") ?? false;
|
139
|
-
}
|
140
|
-
const rightObj = this.rightHand?.asset as Object3D;
|
141
|
-
if (rightObj) {
|
142
|
-
rightObj.visible = sync?.isTracking(state.owner, "right") ?? false;
|
143
|
-
}
|
144
|
-
}
|
145
|
-
}
|
146
|
-
|
147
|
-
// HACK: XRFlag limitation workaround to make sure first person user head of OTHER users is ALWAYS rendered
|
148
|
-
if (this.head?.asset) {
|
149
|
-
const xrflags = GameObject.getComponentsInChildren(this.head.asset, XRFlag);
|
150
|
-
for (const flag of xrflags) {
|
151
|
-
flag.enabled = false;
|
152
|
-
flag.gameObject.visible = true;
|
153
|
-
}
|
154
|
-
}
|
155
|
-
}
|
156
|
-
}
|
157
|
-
}
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
private tryFindAvatarObjectsIfMissing() {
|
162
|
-
// if no avatar objects are set, try to find them
|
163
|
-
if (!this.head || !this.leftHand || !this.rightHand) {
|
164
|
-
const res = { head: this.head, leftHand: this.leftHand, rightHand: this.rightHand };
|
165
|
-
NeedleXRUtils.tryFindAvatarObjects(this.gameObject, this.sourceId || "", res);
|
166
|
-
if (res.head) this.head = res.head;
|
167
|
-
if (res.leftHand) this.leftHand = res.leftHand;
|
168
|
-
if (res.rightHand) this.rightHand = res.rightHand;
|
169
|
-
}
|
170
|
-
}
|
171
|
-
|
172
|
-
private async prepareAvatar() {
|
173
|
-
// if no avatar objects are set, try to find them
|
174
|
-
this.tryFindAvatarObjectsIfMissing();
|
175
|
-
|
176
|
-
if (!this.head) {
|
177
|
-
const head = new Object3D();
|
178
|
-
head.name = "Head";
|
179
|
-
const cube = ObjectUtils.createPrimitive(PrimitiveType.Cube);
|
180
|
-
head.add(cube);
|
181
|
-
this.gameObject.add(head);
|
182
|
-
this.head = new AssetReference("", this.sourceId, head);
|
183
|
-
if (debug) console.log("Create head", head);
|
184
|
-
}
|
185
|
-
|
186
|
-
if (!this.rightHand) {
|
187
|
-
const rightHand = new Object3D();
|
188
|
-
rightHand.name = "Right Hand";
|
189
|
-
this.gameObject.add(rightHand);
|
190
|
-
this.rightHand = new AssetReference("", this.sourceId, rightHand);
|
191
|
-
if (debug) console.log("Create right hand", rightHand);
|
192
|
-
}
|
193
|
-
|
194
|
-
if (!this.leftHand) {
|
195
|
-
const leftHand = new Object3D();
|
196
|
-
leftHand.name = "Left Hand";
|
197
|
-
this.gameObject.add(leftHand);
|
198
|
-
this.leftHand = new AssetReference("", this.sourceId, leftHand);
|
199
|
-
if (debug) console.log("Create left hand", leftHand);
|
200
|
-
}
|
201
|
-
|
202
|
-
await this.loadAvatarObjects(this.head, this.leftHand, this.rightHand);
|
203
|
-
|
204
|
-
if (PlayerState.isLocalPlayer(this.gameObject)) {
|
205
|
-
this._syncTransforms = GameObject.getComponentsInChildren(this.gameObject, SyncedTransform);
|
206
|
-
}
|
207
|
-
}
|
208
|
-
|
209
|
-
|
210
|
-
private async loadAvatarObjects(head: AssetReference, left: AssetReference, right: AssetReference) {
|
211
|
-
const pHead = head.loadAssetAsync();
|
212
|
-
const pHandLeft = left.loadAssetAsync();
|
213
|
-
const pHandRight = right.loadAssetAsync();
|
214
|
-
const promises = new Array<Promise<any>>();
|
215
|
-
if (pHead) promises.push(pHead);
|
216
|
-
if (pHandLeft) promises.push(pHandLeft);
|
217
|
-
if (pHandRight) promises.push(pHandRight);
|
218
|
-
const res = await PromiseAllWithErrors(promises);
|
219
|
-
if (debug) console.log("Avatar loaded results:", res);
|
220
|
-
}
|
221
|
-
}
|
@@ -1,8 +1,7 @@
|
|
1
1
|
import { Object3D } from "three";
|
2
|
-
|
2
|
+
import { Behaviour, GameObject } from "../Component.js";
|
3
|
+
import { XRFlag, XRState } from "../XRFlag.js";
|
3
4
|
import { serializable } from "../../engine/engine_serialization_decorator.js";
|
4
|
-
import { Behaviour, GameObject } from "../Component.js";
|
5
|
-
import { XRFlag, XRState } from "../webxr/XRFlag.js";
|
6
5
|
|
7
6
|
|
8
7
|
export class AvatarBlink_Simple extends Behaviour {
|
@@ -1,11 +1,10 @@
|
|
1
|
+
import { Behaviour, GameObject } from "../Component.js";
|
2
|
+
import * as utils from "../../engine/engine_three_utils.js"
|
1
3
|
import * as THREE from "three";
|
4
|
+
import { Avatar_Brain_LookAt } from "./Avatar_Brain_LookAt.js";
|
5
|
+
import { serializable } from "../../engine/engine_serialization_decorator.js";
|
2
6
|
import { Object3D } from "three";
|
3
7
|
|
4
|
-
import { serializable } from "../../engine/engine_serialization_decorator.js";
|
5
|
-
import * as utils from "../../engine/engine_three_utils.js"
|
6
|
-
import { Behaviour, GameObject } from "../Component.js";
|
7
|
-
import { Avatar_Brain_LookAt } from "./Avatar_Brain_LookAt.js";
|
8
|
-
|
9
8
|
export class AvatarEyeLook_Rotation extends Behaviour {
|
10
9
|
|
11
10
|
@serializable(Object3D)
|
@@ -1,13 +1,12 @@
|
|
1
|
-
import { Box3, Object3D, Vector3 } from "three";
|
2
1
|
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
3
|
-
|
4
|
-
import { InstantiateOptions } from "../engine/engine_gameobject.js";
|
5
|
-
import { getLoader } from "../engine/engine_gltf.js";
|
2
|
+
import * as utils from "../engine/engine_utils.js"
|
6
3
|
import * as loaders from "../engine/engine_loaders.js"
|
7
4
|
import { Context } from "../engine/engine_setup.js";
|
8
|
-
import
|
5
|
+
import { GameObject } from "./Component.js";
|
9
6
|
import { download_file } from "../engine/engine_web_api.js";
|
10
|
-
import {
|
7
|
+
import { getLoader } from "../engine/engine_gltf.js";
|
8
|
+
import { InstantiateOptions } from "../engine/engine_gameobject.js";
|
9
|
+
import { Box3, Object3D, Vector3 } from "three";
|
11
10
|
|
12
11
|
const debug = utils.getParam("debugavatar");
|
13
12
|
|
@@ -1,8 +1,7 @@
|
|
1
|
-
import {
|
2
|
-
|
1
|
+
import { Behaviour } from "./Component.js";
|
3
2
|
import * as params from "../engine/engine_default_parameters.js";
|
4
3
|
import { serializable } from "../engine/engine_serialization_decorator.js";
|
5
|
-
import {
|
4
|
+
import { AxesHelper as _AxesHelper } from "three";
|
6
5
|
|
7
6
|
export class AxesHelper extends Behaviour {
|
8
7
|
@serializable()
|
@@ -1,12 +1,11 @@
|
|
1
1
|
// import { Canvas } from './Canvas.js';
|
2
|
-
import { AxesHelper, Object3D } from 'three';
|
3
2
|
import * as ThreeMeshUI from 'three-mesh-ui';
|
4
|
-
|
5
|
-
import { showGizmos } from '../../engine/engine_default_parameters.js';
|
6
|
-
import { getParam } from '../../engine/engine_utils.js';
|
7
3
|
import { Behaviour, GameObject } from "../Component.js";
|
8
4
|
import { EventSystem } from "./EventSystem.js";
|
5
|
+
import { showGizmos } from '../../engine/engine_default_parameters.js';
|
6
|
+
import { AxesHelper, Object3D } from 'three';
|
9
7
|
import type { ICanvas } from './Interfaces.js';
|
8
|
+
import { getParam } from '../../engine/engine_utils.js';
|
10
9
|
export const includesDir = "./include";
|
11
10
|
|
12
11
|
const debug = getParam("debugshadowcomponents");
|
@@ -25,38 +24,22 @@
|
|
25
24
|
|
26
25
|
export const $shadowDomOwner = Symbol("shadowDomOwner");
|
27
26
|
|
28
|
-
/** Derive from this class if you want to implement your own UI components
|
29
|
-
* It provides utility methods and simplifies managing the underlying three-mesh-ui hierarchy
|
30
|
-
*/
|
31
27
|
export class BaseUIComponent extends Behaviour {
|
32
28
|
|
33
|
-
/** Is this object on the root of the UI hierarchy ? */
|
34
29
|
isRoot() { return this.Root?.gameObject === this.gameObject; }
|
35
30
|
|
36
|
-
/** Access the parent canvas component */
|
37
31
|
get canvas() {
|
38
32
|
const cv = this.Root as any as ICanvas;
|
39
33
|
if (cv?.isCanvas) return cv;
|
40
34
|
return null;
|
41
35
|
}
|
42
|
-
/** @deprecated use `canvas` */
|
43
|
-
protected get Canvas() {
|
44
|
-
return this.canvas;
|
45
|
-
}
|
46
36
|
|
47
|
-
/** Mark the UI dirty which will trigger an THREE-Mesh-UI update */
|
48
37
|
markDirty() {
|
49
38
|
EventSystem.markUIDirty(this.context);
|
50
39
|
}
|
51
40
|
|
52
|
-
|
53
|
-
get shadowComponent() { return this._shadowComponent }
|
54
|
-
private set shadowComponent(val: Object3D | null) {
|
55
|
-
this._shadowComponent = val;
|
56
|
-
}
|
41
|
+
shadowComponent: ThreeMeshUI.Block | null = null;
|
57
42
|
|
58
|
-
private _shadowComponent: Object3D | null = null;
|
59
|
-
|
60
43
|
private _controlsChildLayout = true;
|
61
44
|
get controlsChildLayout(): boolean { return this._controlsChildLayout; }
|
62
45
|
set controlsChildLayout(val: boolean) {
|
@@ -75,6 +58,11 @@
|
|
75
58
|
return this._root;
|
76
59
|
}
|
77
60
|
|
61
|
+
// TODO: rename to canvas
|
62
|
+
protected get Canvas() {
|
63
|
+
return this.canvas;
|
64
|
+
}
|
65
|
+
|
78
66
|
// private _intermediate?: Object3D;
|
79
67
|
protected _parentComponent?: BaseUIComponent | null = undefined;
|
80
68
|
|
@@ -89,10 +77,7 @@
|
|
89
77
|
super.onEnable();
|
90
78
|
}
|
91
79
|
|
92
|
-
|
93
|
-
* @param container the three-mesh-ui object to add
|
94
|
-
* @param parent the parent component to add the object to
|
95
|
-
*/
|
80
|
+
//@ts-ignore
|
96
81
|
protected addShadowComponent(container: any, parent?: BaseUIComponent) {
|
97
82
|
|
98
83
|
this.removeShadowComponent();
|
@@ -149,7 +134,21 @@
|
|
149
134
|
if(debug) console.log(this.shadowComponent)
|
150
135
|
}
|
151
136
|
|
152
|
-
|
137
|
+
|
138
|
+
set(_state: object) {
|
139
|
+
// if (!this.shadowComponent) return;
|
140
|
+
// this.traverseOwnedShadowComponents(this.shadowComponent, this, o => {
|
141
|
+
// for (const ch of o.children) {
|
142
|
+
// console.log(this, ch);
|
143
|
+
// if (ch.isUI && typeof ch.set === "function") {
|
144
|
+
// // ch.set(state);
|
145
|
+
// // ch.update(true, true, true);
|
146
|
+
// }
|
147
|
+
// }
|
148
|
+
// })
|
149
|
+
}
|
150
|
+
|
151
|
+
protected setShadowComponentOwner(current: Object3D | null | undefined) {
|
153
152
|
if (!current) return;
|
154
153
|
// TODO: only traverse our own hierarchy, we can stop if we find another owner
|
155
154
|
if (current[$shadowDomOwner] === undefined || current[$shadowDomOwner] === this) {
|
@@ -172,7 +171,6 @@
|
|
172
171
|
}
|
173
172
|
}
|
174
173
|
|
175
|
-
/** Remove the underlying UI object from the hierarchy */
|
176
174
|
protected removeShadowComponent() {
|
177
175
|
if (this.shadowComponent) {
|
178
176
|
this.shadowComponent.removeFromParent();
|
@@ -1,8 +1,7 @@
|
|
1
|
+
import { Behaviour, GameObject } from "./Component.js";
|
2
|
+
import * as utils from "./../engine/engine_three_utils.js";
|
1
3
|
import { Vector3 } from "three";
|
2
4
|
|
3
|
-
import * as utils from "./../engine/engine_three_utils.js";
|
4
|
-
import { Behaviour, GameObject } from "./Component.js";
|
5
|
-
|
6
5
|
export class BasicIKConstraint extends Behaviour {
|
7
6
|
|
8
7
|
private from!: GameObject;
|
@@ -1,8 +1,8 @@
|
|
1
|
-
import { getParam } from "../../../../../engine/engine_utils.js";
|
2
1
|
import { GameObject } from "../../../../Component.js";
|
3
2
|
import type { IUSDExporterExtension } from "../../Extension.js";
|
4
3
|
import { USDObject, USDWriter, USDZExporterContext } from "../../ThreeUSDZExporter.js";
|
5
4
|
import { BehaviorModel } from "./BehavioursBuilder.js";
|
5
|
+
import { getParam } from "../../../../../engine/engine_utils.js";
|
6
6
|
|
7
7
|
const debug = getParam("debugusdz");
|
8
8
|
|
@@ -1,20 +1,21 @@
|
|
1
|
-
import {
|
2
|
-
|
3
|
-
import { isDevEnvironment, showBalloonWarning } from "../../../../../engine/debug/index.js";
|
4
|
-
import { serializable } from "../../../../../engine/engine_serialization_decorator.js";
|
5
|
-
import { getWorldPosition, getWorldQuaternion, getWorldScale, setWorldPosition, setWorldQuaternion, setWorldScale } from "../../../../../engine/engine_three_utils.js";
|
6
|
-
import type { State } from "../../../../../engine/extensions/NEEDLE_animator_controller_model.js";
|
7
|
-
import { NEEDLE_progressive } from "../../../../../engine/extensions/NEEDLE_progressive.js";
|
1
|
+
import { Behaviour, GameObject } from "../../../../Component.js";
|
8
2
|
import { Animator } from "../../../../Animator.js";
|
9
|
-
import { AudioSource } from "../../../../AudioSource.js";
|
10
|
-
import { Behaviour, GameObject } from "../../../../Component.js";
|
11
3
|
import { Renderer } from "../../../../Renderer.js";
|
4
|
+
import { serializable } from "../../../../../engine/engine_serialization_decorator.js";
|
12
5
|
import type { IPointerClickHandler, PointerEventData } from "../../../../ui/PointerEvents.js";
|
13
|
-
import {
|
6
|
+
import { AnimationExtension, RegisteredAnimationInfo, type UsdzAnimation } from "../Animation.js";
|
7
|
+
import { getWorldPosition, getWorldQuaternion, getWorldScale, setWorldPosition, setWorldQuaternion, setWorldScale } from "../../../../../engine/engine_three_utils.js";
|
8
|
+
|
9
|
+
import { Object3D, Material, Vector3, Quaternion, Mesh, Group } from "three";
|
14
10
|
import { USDDocument, USDObject, USDZExporterContext } from "../../ThreeUSDZExporter.js";
|
15
|
-
|
11
|
+
|
16
12
|
import type { BehaviorExtension, UsdzBehaviour } from "./Behaviour.js";
|
17
|
-
import { ActionBuilder, ActionModel, AuralMode, BehaviorModel,
|
13
|
+
import { ActionBuilder, ActionModel, AuralMode, BehaviorModel, type IBehaviorElement, MotionType, PlayAction, Space, TriggerBuilder, GroupActionModel, MultiplePerformOperation } from "./BehavioursBuilder.js";
|
14
|
+
import { AudioSource } from "../../../../AudioSource.js";
|
15
|
+
import { NEEDLE_progressive } from "../../../../../engine/extensions/NEEDLE_progressive.js";
|
16
|
+
import { isDevEnvironment, showBalloonWarning } from "../../../../../engine/debug/index.js";
|
17
|
+
import { Raycaster, ObjectRaycaster } from "../../../../ui/Raycaster.js";
|
18
|
+
import type { State } from "../../../../../engine/extensions/NEEDLE_animator_controller_model.js";
|
18
19
|
|
19
20
|
function ensureRaycaster(obj: GameObject) {
|
20
21
|
if (!obj) return;
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import { Object3D } from "three";
|
2
|
+
import { USDDocument, USDObject, USDWriter, makeNameSafeForUSD } from "../../ThreeUSDZExporter.js";
|
2
3
|
|
4
|
+
import { BehaviorExtension } from "./Behaviour.js";
|
3
5
|
import { getParam } from "../../../../../engine/engine_utils.js";
|
4
|
-
import { makeNameSafeForUSD,USDDocument, USDObject, USDWriter } from "../../ThreeUSDZExporter.js";
|
5
|
-
import { BehaviorExtension } from "./Behaviour.js";
|
6
6
|
|
7
7
|
const debug = getParam("debugusdz");
|
8
8
|
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import { BlendFunction, BloomEffect, SelectiveBloomEffect } from "postprocessing";
|
2
|
-
|
3
2
|
import { serializable } from "../../../engine/engine_serialization.js";
|
4
3
|
import { PostProcessingEffect } from "../PostProcessingEffect.js";
|
5
4
|
import { VolumeParameter } from "../VolumeParameter.js";
|
@@ -1,9 +1,8 @@
|
|
1
|
-
import {
|
2
|
-
|
1
|
+
import { Behaviour } from "./Component.js";
|
2
|
+
import { getParam } from "../engine/engine_utils.js";
|
3
3
|
import { CreateWireCube, Gizmos } from "../engine/engine_gizmos.js";
|
4
4
|
import { getWorldPosition, getWorldScale } from "../engine/engine_three_utils.js";
|
5
|
-
import {
|
6
|
-
import { Behaviour } from "./Component.js";
|
5
|
+
import { Box3, Color, type ColorRepresentation, LineSegments, Object3D, Vector3 } from "three";
|
7
6
|
|
8
7
|
const gizmos = getParam("gizmos");
|
9
8
|
const debug = getParam("debugboxhelper");
|
@@ -1,15 +1,15 @@
|
|
1
|
-
import { showBalloonMessage } from "../../engine/debug/index.js";
|
2
|
-
import { Gizmos } from "../../engine/engine_gizmos.js";
|
3
|
-
import { PointerType } from "../../engine/engine_input.js";
|
4
|
-
import { serializable } from "../../engine/engine_serialization_decorator.js";
|
5
|
-
import { getParam } from "../../engine/engine_utils.js";
|
6
|
-
import { Animator } from "../Animator.js";
|
7
1
|
import { Behaviour, GameObject } from "../Component.js";
|
8
2
|
import { EventList } from "../EventList.js";
|
3
|
+
import type { IPointerClickHandler, IPointerEnterHandler, IPointerEventHandler, IPointerExitHandler, PointerEventData } from "./PointerEvents.js";
|
4
|
+
import { Image } from "./Image.js";
|
9
5
|
import { RGBAColor } from "../js-extensions/RGBAColor.js";
|
10
|
-
import {
|
11
|
-
import
|
6
|
+
import { serializable } from "../../engine/engine_serialization_decorator.js";
|
7
|
+
import { Animator } from "../Animator.js";
|
8
|
+
import { getParam } from "../../engine/engine_utils.js";
|
9
|
+
import { showBalloonMessage } from "../../engine/debug/index.js";
|
12
10
|
import { GraphicRaycaster, ObjectRaycaster, Raycaster } from "./Raycaster.js";
|
11
|
+
import { PointerType } from "../../engine/engine_input.js";
|
12
|
+
import { Gizmos } from "../../engine/engine_gizmos.js";
|
13
13
|
|
14
14
|
const debug = getParam("debugbutton");
|
15
15
|
|
@@ -120,10 +120,10 @@
|
|
120
120
|
}
|
121
121
|
|
122
122
|
onPointerClick(args: PointerEventData) {
|
123
|
-
if (!this.interactable) return;
|
123
|
+
if (!this.interactable || args.pointerId !== 0) return;
|
124
124
|
|
125
|
-
if (args.button !== 0 && args.event.pointerType === PointerType.Mouse) return;
|
126
125
|
// Button clicks should only run with left mouse button while using mouse
|
126
|
+
if(args.pointerId !== 0 && this.context.input.getIsMouse(args.pointerId)) return;
|
127
127
|
if (debug) {
|
128
128
|
console.warn("Button Click", this.onClick);
|
129
129
|
showBalloonMessage("CLICKED button " + this.name + " at " + this.context.time.frameCount);
|
@@ -1,17 +1,17 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
|
1
|
+
import { Behaviour, GameObject } from "./Component.js";
|
2
|
+
import { getParam } from "../engine/engine_utils.js";
|
3
|
+
import { serializable } from "../engine/engine_serialization_decorator.js";
|
4
|
+
import { RGBAColor } from "./js-extensions/RGBAColor.js";
|
5
|
+
import { Context, XRSessionMode } from "../engine/engine_setup.js";
|
6
|
+
import type { ICamera } from "../engine/engine_types.js"
|
4
7
|
import { isDevEnvironment, showBalloonMessage, showBalloonWarning } from "../engine/debug/index.js";
|
8
|
+
import { getWorldPosition } from "../engine/engine_three_utils.js";
|
5
9
|
import { Gizmos } from "../engine/engine_gizmos.js";
|
6
|
-
|
7
|
-
import {
|
10
|
+
|
11
|
+
import { EquirectangularReflectionMapping, OrthographicCamera, PerspectiveCamera, Ray, SRGBColorSpace, Vector3 } from "three";
|
12
|
+
import { OrbitControls } from "./OrbitControls.js";
|
8
13
|
import { RenderTexture } from "../engine/engine_texture.js";
|
9
|
-
import {
|
10
|
-
import type { ICamera } from "../engine/engine_types.js"
|
11
|
-
import { getParam } from "../engine/engine_utils.js";
|
12
|
-
import { Behaviour, GameObject } from "./Component.js";
|
13
|
-
import { RGBAColor } from "./js-extensions/RGBAColor.js";
|
14
|
-
import { OrbitControls } from "./OrbitControls.js";
|
14
|
+
import { Texture } from "three";
|
15
15
|
|
16
16
|
export enum ClearFlags {
|
17
17
|
Skybox = 1,
|
@@ -350,6 +350,7 @@
|
|
350
350
|
if (this._backgroundBlurriness !== undefined)
|
351
351
|
this.context.scene.backgroundBlurriness = this._backgroundBlurriness;
|
352
352
|
if (this._backgroundIntensity !== undefined)
|
353
|
+
//@ts-ignore
|
353
354
|
this.context.scene.backgroundIntensity = this._backgroundIntensity;
|
354
355
|
|
355
356
|
break;
|
@@ -391,7 +392,7 @@
|
|
391
392
|
if (debug)
|
392
393
|
showBalloonMessage("Environment blend mode: " + environmentBlendMode + " on " + navigator.userAgent);
|
393
394
|
let transparent = environmentBlendMode === 'additive' || environmentBlendMode === 'alpha-blend';
|
394
|
-
if (context.
|
395
|
+
if (context.xrSessionMode === XRSessionMode.ImmersiveAR) {
|
395
396
|
if (environmentBlendMode === "opaque") {
|
396
397
|
// workaround for Quest 2 returning opaque when it should be alpha-blend
|
397
398
|
// check user agent if this is the Quest browser and return true if so
|
@@ -1,15 +1,14 @@
|
|
1
|
+
import { OrbitControls } from "./OrbitControls.js";
|
2
|
+
import { addNewComponent, getOrAddComponent } from "../engine/engine_components.js";
|
1
3
|
import { Object3D } from "three";
|
2
|
-
|
4
|
+
import type { ICamera, IContext } from "../engine/engine_types.js";
|
5
|
+
import { RGBAColor } from "./js-extensions/RGBAColor.js";
|
6
|
+
import { ContextEvent, ContextRegistry } from "../engine/engine_context_registry.js";
|
3
7
|
import { getCameraController } from "../engine/engine_camera.js";
|
4
|
-
import {
|
5
|
-
import { Context } from "../engine/engine_context.js";
|
6
|
-
import { ContextEvent, ContextRegistry } from "../engine/engine_context_registry.js";
|
8
|
+
import { Camera, ClearFlags } from "./Camera.js";
|
7
9
|
import { NeedleEngineHTMLElement } from "../engine/engine_element.js";
|
8
|
-
import type { ICamera, IContext } from "../engine/engine_types.js";
|
9
10
|
import { getParam } from "../engine/engine_utils.js";
|
10
|
-
import {
|
11
|
-
import { RGBAColor } from "./js-extensions/RGBAColor.js";
|
12
|
-
import { OrbitControls } from "./OrbitControls.js";
|
11
|
+
import { Context } from "../engine/engine_context.js";
|
13
12
|
|
14
13
|
const debug = getParam("debugmissingcamera");
|
15
14
|
|
@@ -1,19 +1,17 @@
|
|
1
|
-
import {
|
2
|
-
import * as ThreeMeshUI from 'three-mesh-ui'
|
3
|
-
|
4
|
-
import { Mathf } from "../../engine/engine_math.js";
|
1
|
+
import { updateRenderSettings as updateRenderSettingsRecursive } from "./Utils.js";
|
5
2
|
import { serializable } from "../../engine/engine_serialization_decorator.js";
|
6
3
|
import { FrameEvent } from "../../engine/engine_setup.js";
|
7
|
-
import {
|
8
|
-
import {
|
4
|
+
import { BaseUIComponent, UIRootComponent } from "./BaseUIComponent.js";
|
5
|
+
import { GameObject } from "../Component.js";
|
6
|
+
import { Matrix4, Object3D } from "three";
|
7
|
+
import { RectTransform } from "./RectTransform.js";
|
8
|
+
import type { ICanvas, ICanvasEventReceiver, ILayoutGroup, IRectTransform } from "./Interfaces.js";
|
9
9
|
import { Camera } from "../Camera.js";
|
10
|
-
import { GameObject } from "../Component.js";
|
11
|
-
import { BaseUIComponent, UIRootComponent } from "./BaseUIComponent.js";
|
12
10
|
import { EventSystem } from "./EventSystem.js";
|
13
|
-
import
|
11
|
+
import * as ThreeMeshUI from 'three-mesh-ui'
|
12
|
+
import { getParam } from "../../engine/engine_utils.js";
|
14
13
|
import { LayoutGroup } from "./Layout.js";
|
15
|
-
import {
|
16
|
-
import { updateRenderSettings as updateRenderSettingsRecursive } from "./Utils.js";
|
14
|
+
import { Mathf } from "../../engine/engine_math.js";
|
17
15
|
|
18
16
|
export enum RenderMode {
|
19
17
|
ScreenSpaceOverlay = 0,
|
@@ -202,30 +200,19 @@
|
|
202
200
|
}
|
203
201
|
}
|
204
202
|
|
205
|
-
onEnterXR(args: NeedleXREventArgs): void {
|
206
|
-
if (this.screenspace) {
|
207
|
-
if (args.xr.isVR || args.xr.isPassThrough) {
|
208
|
-
this.gameObject.visible = false;
|
209
|
-
}
|
210
|
-
}
|
211
|
-
}
|
212
|
-
onLeaveXR(args: NeedleXREventArgs): void {
|
213
|
-
if (this.screenspace) {
|
214
|
-
if (args.xr.isVR || args.xr.isPassThrough) {
|
215
|
-
this.gameObject.visible = true;
|
216
|
-
}
|
217
|
-
}
|
218
|
-
}
|
219
|
-
|
220
203
|
onBeforeRenderRoutine = () => {
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
this
|
225
|
-
this.
|
204
|
+
if (this.context.isInVR) {
|
205
|
+
this.onUpdateRenderMode();
|
206
|
+
this.handleLayoutUpdates();
|
207
|
+
// TODO TMUI @swingingtom - For VR this is so we don't have text clipping
|
208
|
+
this.shadowComponent?.updateMatrixWorld(true);
|
209
|
+
this.shadowComponent?.updateWorldMatrix(true, true);
|
210
|
+
this.invokeBeforeRenderEvents();
|
211
|
+
EventSystem.ensureUpdateMeshUI(ThreeMeshUI, this.context, true);
|
226
212
|
return;
|
227
213
|
}
|
228
214
|
|
215
|
+
this.previousParent = this.gameObject.parent;
|
229
216
|
// console.log(this.previousParent?.name + "/" + this.gameObject.name);
|
230
217
|
|
231
218
|
if (this.renderOnTop || this.screenspace) {
|
@@ -244,12 +231,7 @@
|
|
244
231
|
}
|
245
232
|
|
246
233
|
onAfterRenderRoutine = () => {
|
247
|
-
if
|
248
|
-
this.previousParent?.add(this.gameObject);
|
249
|
-
// this is currently causing an error during XR (https://linear.app/needle/issue/NE-4114)
|
250
|
-
// this.gameObject.visible = true;
|
251
|
-
return;
|
252
|
-
}
|
234
|
+
if(this.context.isInVR) return;
|
253
235
|
if ((this.screenspace || this.renderOnTop) && this.previousParent && this.context.mainCamera) {
|
254
236
|
if (this.screenspace) {
|
255
237
|
const camObj = this.context.mainCamera;
|
@@ -294,7 +276,7 @@
|
|
294
276
|
for (const ch of this._rectTransforms) {
|
295
277
|
if (matrixWorldChanged) ch.markDirty();
|
296
278
|
let layout = this._layoutGroups.get(ch.gameObject);
|
297
|
-
if
|
279
|
+
if(ch.isDirty && !layout){
|
298
280
|
layout = ch.gameObject.getComponentInParent(LayoutGroup) as LayoutGroup;
|
299
281
|
}
|
300
282
|
if (ch.isDirty || layout?.isDirty) {
|
@@ -1,9 +1,9 @@
|
|
1
|
-
import {
|
1
|
+
import { Graphic } from "./Graphic.js";
|
2
2
|
import { FrameEvent } from "../../engine/engine_setup.js";
|
3
3
|
import { Behaviour, GameObject } from "../Component.js";
|
4
|
+
import { type ICanvasGroup, type IHasAlphaFactor } from "./Interfaces.js";
|
5
|
+
import { serializable } from "../../engine/engine_serialization_decorator.js";
|
4
6
|
import { BaseUIComponent } from "./BaseUIComponent.js";
|
5
|
-
import { Graphic } from "./Graphic.js";
|
6
|
-
import { type ICanvasGroup, type IHasAlphaFactor } from "./Interfaces.js";
|
7
7
|
|
8
8
|
|
9
9
|
export class CanvasGroup extends Behaviour implements ICanvasGroup {
|
@@ -1,15 +1,14 @@
|
|
1
1
|
import { Quaternion, Ray, Vector2, Vector3 } from "three";
|
2
|
-
|
3
2
|
import { Mathf } from "../engine/engine_math.js";
|
4
|
-
import { RaycastOptions } from "../engine/engine_physics.js";
|
5
3
|
import { serializable } from "../engine/engine_serialization.js";
|
6
|
-
import { getWorldPosition } from "../engine/engine_three_utils.js";
|
7
4
|
import { Collision } from "../engine/engine_types.js";
|
8
|
-
import { getParam } from "../engine/engine_utils.js";
|
9
|
-
import { Animator } from "./Animator.js"
|
10
5
|
import { CapsuleCollider } from "./Collider.js";
|
11
6
|
import { Behaviour, GameObject } from "./Component.js";
|
12
7
|
import { Rigidbody } from "./RigidBody.js";
|
8
|
+
import { Animator } from "./Animator.js"
|
9
|
+
import { RaycastOptions } from "../engine/engine_physics.js";
|
10
|
+
import { getWorldPosition } from "../engine/engine_three_utils.js";
|
11
|
+
import { getParam } from "../engine/engine_utils.js";
|
13
12
|
|
14
13
|
const debug = getParam("debugcharactercontroller");
|
15
14
|
|
@@ -1,6 +1,5 @@
|
|
1
1
|
import { ChromaticAberrationEffect } from "postprocessing";
|
2
2
|
import { Vector2 } from "three";
|
3
|
-
|
4
3
|
import { serializable } from "../../../engine/engine_serialization.js";
|
5
4
|
import { type EffectProviderResult, PostProcessingEffect } from "../PostProcessingEffect.js";
|
6
5
|
import { VolumeParameter } from "../VolumeParameter.js";
|
@@ -1,14 +1,13 @@
|
|
1
|
+
import { Behaviour } from "./Component.js";
|
2
|
+
import { Rigidbody } from "./RigidBody.js";
|
3
|
+
import { serializable } from "../engine/engine_serialization_decorator.js";
|
1
4
|
import { Group, Mesh, Vector3 } from "three"
|
2
|
-
|
3
|
-
import type { PhysicsMaterial } from "../engine/engine_physics.types.js";
|
4
|
-
import { serializable } from "../engine/engine_serialization_decorator.js";
|
5
|
-
import { getWorldScale } from "../engine/engine_three_utils.js";
|
6
5
|
// import { IColliderProvider, registerColliderProvider } from "../engine/engine_physics.js";
|
7
6
|
import type { IBoxCollider, ICollider, ISphereCollider } from "../engine/engine_types.js";
|
7
|
+
import { getWorldScale } from "../engine/engine_three_utils.js";
|
8
|
+
import type { PhysicsMaterial } from "../engine/engine_physics.types.js";
|
8
9
|
import { validate } from "../engine/engine_util_decorator.js";
|
9
10
|
import { unwatchWrite, watchWrite } from "../engine/engine_utils.js";
|
10
|
-
import { Behaviour } from "./Component.js";
|
11
|
-
import { Rigidbody } from "./RigidBody.js";
|
12
11
|
|
13
12
|
|
14
13
|
export class Collider extends Behaviour implements ICollider {
|
@@ -1,10 +1,9 @@
|
|
1
1
|
import { BrightnessContrastEffect, HueSaturationEffect } from "postprocessing";
|
2
|
-
import { LinearToneMapping, NoToneMapping } from "three";
|
3
|
-
|
4
2
|
import { serializable } from "../../../engine/engine_serialization.js";
|
5
3
|
import { type EffectProviderResult, PostProcessingEffect } from "../PostProcessingEffect.js";
|
6
4
|
import { VolumeParameter } from "../VolumeParameter.js";
|
7
5
|
import { registerCustomEffectType } from "../VolumeProfile.js";
|
6
|
+
import { LinearToneMapping, NoToneMapping } from "three";
|
8
7
|
|
9
8
|
|
10
9
|
export class ColorAdjustments extends PostProcessingEffect {
|
@@ -1,17 +1,15 @@
|
|
1
|
-
import {
|
2
|
-
|
3
|
-
import { isDevEnvironment } from "../engine/debug/index.js";
|
4
|
-
import { addNewComponent, destroyComponentInstance, findObjectOfType, findObjectsOfType, getComponent, getComponentInChildren, getComponentInParent, getComponents, getComponentsInChildren, getComponentsInParent, getOrAddComponent, moveComponentInstance, removeComponent } from "../engine/engine_components.js";
|
1
|
+
import { Mathf } from "../engine/engine_math.js";
|
2
|
+
import * as threeutils from "../engine/engine_three_utils.js";
|
5
3
|
import { activeInHierarchyFieldName } from "../engine/engine_constants.js";
|
6
|
-
import {
|
4
|
+
import { Context, FrameEvent } from "../engine/engine_setup.js";
|
7
5
|
import * as main from "../engine/engine_mainloop_utils.js";
|
8
6
|
import { syncDestroy, syncInstantiate } from "../engine/engine_networking_instantiate.js";
|
9
|
-
import {
|
10
|
-
import
|
11
|
-
import
|
12
|
-
import { INeedleXRSessionEventReceiver, NeedleXRControllerEventArgs, NeedleXREventArgs } from "../engine/engine_xr.js";
|
13
|
-
import { IPointerEventHandler, PointerEventData } from "./ui/PointerEvents.js";
|
7
|
+
import type { ConstructorConcrete, SourceIdentifier, IComponent, IGameObject, Constructor, GuidsMap, Collision, ICollider } from "../engine/engine_types.js";
|
8
|
+
import { addNewComponent, destroyComponentInstance, findObjectOfType, findObjectsOfType, getComponent, getComponentInChildren, getComponentInParent, getComponents, getComponentsInChildren, getComponentsInParent, getOrAddComponent, moveComponentInstance, removeComponent } from "../engine/engine_components.js";
|
9
|
+
import { findByGuid, destroy, InstantiateOptions, instantiate, HideFlags, foreachComponent, markAsInstancedRendered, isActiveInHierarchy, isActiveSelf, isUsingInstancing, setActive, isDestroyed, IInstantiateOptions } from "../engine/engine_gameobject.js";
|
14
10
|
|
11
|
+
import { Euler, Object3D, Quaternion, Scene, Vector3 } from "three";
|
12
|
+
import { showBalloonWarning, isDevEnvironment } from "../engine/debug/index.js";
|
15
13
|
|
16
14
|
// export interface ISerializationCallbackReceiver {
|
17
15
|
// onBeforeSerialize?(): object | void;
|
@@ -125,7 +123,7 @@
|
|
125
123
|
main.addScriptToArrays(comp, context!);
|
126
124
|
if (comp.__internalDidAwakeAndStart) return;
|
127
125
|
if (context!.new_script_start.includes(comp) === false) {
|
128
|
-
context!.new_script_start.push(comp as
|
126
|
+
context!.new_script_start.push(comp as Behaviour);
|
129
127
|
}
|
130
128
|
}, true);
|
131
129
|
}
|
@@ -256,7 +254,7 @@
|
|
256
254
|
return getComponentsInParent(go, typeName, arr);
|
257
255
|
}
|
258
256
|
|
259
|
-
public static getAllComponents(go: IGameObject | Object3D):
|
257
|
+
public static getAllComponents(go: IGameObject | Object3D): Behaviour[] {
|
260
258
|
const componentsList = go.userData?.components;
|
261
259
|
const newList = [...componentsList];
|
262
260
|
return newList;
|
@@ -296,7 +294,7 @@
|
|
296
294
|
abstract set worldQuaternion(val: Quaternion);
|
297
295
|
abstract get worldQuaternion(): Quaternion;
|
298
296
|
abstract set worldRotation(val: Vector3);
|
299
|
-
abstract get worldRotation(): Vector3;
|
297
|
+
abstract get worldRotation(): Vector3;
|
300
298
|
abstract set worldScale(val: Vector3);
|
301
299
|
abstract get worldScale(): Vector3;
|
302
300
|
|
@@ -307,28 +305,17 @@
|
|
307
305
|
|
308
306
|
|
309
307
|
|
310
|
-
|
311
|
-
*
|
312
|
-
* The most common lifecycle methods are `awake`, `start`, `onEanble`, `onDisable` `update` and `onDestroy`.
|
313
|
-
* XR specific callbacks include `onEnterXR`, `onLeaveXR`, `onUpdateXR`, `onControllerAdded` and `onControllerRemoved`.
|
314
|
-
* To receive pointer events implement `onPointerDown`, `onPointerUp`, `onPointerEnter`, `onPointerExit` and `onPointerMove`.
|
315
|
-
*/
|
316
|
-
export abstract class Component implements IComponent, EventTarget,
|
317
|
-
Partial<INeedleXRSessionEventReceiver>,
|
318
|
-
Partial<IPointerEventHandler>
|
319
|
-
{
|
308
|
+
export class Component implements IComponent, EventTarget {
|
320
309
|
|
321
310
|
get isComponent(): boolean { return true; }
|
322
311
|
|
323
312
|
private __context: Context | undefined;
|
324
|
-
/** Use the context to get access to many Needle Engine features and use physics, timing, access the camera or scene */
|
325
313
|
get context(): Context {
|
326
314
|
return this.__context ?? Context.Current;
|
327
315
|
}
|
328
316
|
set context(context: Context) {
|
329
317
|
this.__context = context;
|
330
318
|
}
|
331
|
-
/** shorthand for `this.context.scene` */
|
332
319
|
get scene(): Scene { return this.context.scene; }
|
333
320
|
|
334
321
|
get layer(): number {
|
@@ -368,7 +355,7 @@
|
|
368
355
|
return this.gameObject?.userData.hideFlags;
|
369
356
|
}
|
370
357
|
|
371
|
-
|
358
|
+
|
372
359
|
get activeAndEnabled(): boolean {
|
373
360
|
if (this.destroyed) return false;
|
374
361
|
if (this.__isEnabled === false) return false;
|
@@ -398,27 +385,19 @@
|
|
398
385
|
this.gameObject[activeInHierarchyFieldName] = val;
|
399
386
|
}
|
400
387
|
|
401
|
-
/** the object this component is attached to. Note that this is a threejs Object3D with some additional features */
|
402
388
|
gameObject!: GameObject;
|
403
|
-
/** the unique identifier for this component */
|
404
389
|
guid: string = "invalid";
|
405
|
-
/** holds the source identifier this object was created with/from (e.g. if it was part of a glTF file the sourceId holds the url to the glTF) */
|
406
390
|
sourceId?: SourceIdentifier;
|
407
391
|
// transform: Object3D = nullObject;
|
408
392
|
|
409
393
|
/** called on a component with a map of old to new guids (e.g. when instantiate generated new guids and e.g. timeline track bindings needs to remape them) */
|
410
394
|
resolveGuids?(guidsMap: GuidsMap): void;
|
411
395
|
|
412
|
-
/** called once when the component becomes active for the first time
|
413
|
-
* This is the first callback to be called */
|
396
|
+
/** called once when the component becomes active for the first time */
|
414
397
|
awake() { }
|
415
|
-
/** called every time when the component gets enabled (this is invoked after awake and before start)
|
416
|
-
* or when it becomes active in the hierarchy (e.g. if a parent object or this.gameObject gets set to visible)
|
417
|
-
*/
|
398
|
+
/** called every time when the component gets enabled (this is invoked after awake and before start) */
|
418
399
|
onEnable() { }
|
419
|
-
/** called every time the component gets disabled or if a parent object (or this.gameObject) gets set to invisible */
|
420
400
|
onDisable() { }
|
421
|
-
/** Called when the component gets destroyed */
|
422
401
|
onDestroy() {
|
423
402
|
this.__destroyed = true;
|
424
403
|
}
|
@@ -430,17 +409,11 @@
|
|
430
409
|
/** Called for all scripts when the context gets paused or unpaused */
|
431
410
|
onPausedChanged?(isPaused: boolean, wasPaused: boolean): void;
|
432
411
|
|
433
|
-
/** called at the beginning of a frame (once per component) */
|
434
412
|
start?(): void;
|
435
|
-
/** first callback in a frame (called every frame when implemented) */
|
436
413
|
earlyUpdate?(): void;
|
437
|
-
/** regular callback in a frame (called every frame when implemented) */
|
438
414
|
update?(): void;
|
439
|
-
/** late callback in a frame (called every frame when implemented) */
|
440
415
|
lateUpdate?(): void;
|
441
|
-
/** called before the scene gets rendered in the main update loop */
|
442
416
|
onBeforeRender?(frame: XRFrame | null): void;
|
443
|
-
/** called after the scene was rendered */
|
444
417
|
onAfterRender?(): void;
|
445
418
|
|
446
419
|
onCollisionEnter?(col: Collision);
|
@@ -451,79 +424,18 @@
|
|
451
424
|
onTriggerStay?(col: ICollider);
|
452
425
|
onTriggerExit?(col: ICollider);
|
453
426
|
|
454
|
-
|
455
|
-
/** Optional callback, you can implement this to only get callbacks for VR or AR sessions if necessary.
|
456
|
-
* @returns true if the mode is supported (if false the mode is not supported by this ciomponent and it will not receive XR callbacks for this mode)
|
457
|
-
*/
|
458
|
-
supportsXR?(mode: XRSessionMode): boolean;
|
459
|
-
/** Called before the XR session is requested. Use this callback if you want to modify the session init features */
|
460
|
-
onBeforeXR?(mode: XRSessionMode, args: XRSessionInit): void;
|
461
|
-
/** Callback when this component joins a xr session (or becomes active in a running XR session) */
|
462
|
-
onEnterXR?(args: NeedleXREventArgs): void;
|
463
|
-
/** Callback when a xr session updates (while it is still active in XR session) */
|
464
|
-
onUpdateXR?(args: NeedleXREventArgs): void;
|
465
|
-
/** Callback when this component exists a xr session (or when it becomes inactive in a running XR session) */
|
466
|
-
onLeaveXR?(args: NeedleXREventArgs): void;
|
467
|
-
/** Callback when a controller is connected/added while in a XR session
|
468
|
-
* OR when the component joins a running XR session that has already connected controllers
|
469
|
-
* OR when the component becomes active during a running XR session that has already connected controllers */
|
470
|
-
onXRControllerAdded?(args: NeedleXRControllerEventArgs): void;
|
471
|
-
/** callback when a controller is removed while in a XR session
|
472
|
-
* OR when the component becomes inactive during a running XR session
|
473
|
-
*/
|
474
|
-
onXRControllerRemoved?(args: NeedleXRControllerEventArgs): void;
|
475
|
-
|
476
|
-
|
477
|
-
/* IPointerEventReceiver */
|
478
|
-
/* @inheritdoc */
|
479
|
-
onPointerEnter?(args: PointerEventData);
|
480
|
-
onPointerMove?(args: PointerEventData);
|
481
|
-
onPointerExit?(args: PointerEventData);
|
482
|
-
onPointerDown?(args: PointerEventData);
|
483
|
-
onPointerUp?(args: PointerEventData);
|
484
|
-
onPointerClick?(args: PointerEventData);
|
485
|
-
|
486
|
-
|
487
|
-
/** starts a coroutine (javascript generator function)
|
488
|
-
* `yield` will wait for the next frame:
|
489
|
-
* - Use `yield WaitForSeconds(1)` to wait for 1 second.
|
490
|
-
* - Use `yield WaitForFrames(10)` to wait for 10 frames.
|
491
|
-
* - Use `yield new Promise(...)` to wait for a promise to resolve.
|
492
|
-
* @param routine generator function to start
|
493
|
-
* @param evt event to register the coroutine for (default: FrameEvent.Update). Note that all coroutine FrameEvent callbacks are invoked after the matching regular component callbacks. For example `FrameEvent.Update` will be called after regular component `update()` methods)
|
494
|
-
* @returns the generator function (use it to stop the coroutine with `stopCoroutine`)
|
495
|
-
* @example
|
496
|
-
* ```ts
|
497
|
-
* onEnable() { this.startCoroutine(this.myCoroutine()); }
|
498
|
-
* private *myCoroutine() {
|
499
|
-
* while(this.activeAndEnabled) {
|
500
|
-
* console.log("Hello World", this.context.time.frame);
|
501
|
-
* // wait for 5 frames
|
502
|
-
* for(let i = 0; i < 5; i++) yield;
|
503
|
-
* }
|
504
|
-
* }
|
505
|
-
* ```
|
506
|
-
*/
|
507
427
|
startCoroutine(routine: Generator, evt: FrameEvent = FrameEvent.Update): Generator {
|
508
428
|
return this.context.registerCoroutineUpdate(this, routine, evt);
|
509
429
|
}
|
510
|
-
|
511
|
-
* Stop a coroutine that was previously started with `startCoroutine`
|
512
|
-
* @param routine the routine to be stopped
|
513
|
-
* @param evt the frame event to unregister the routine from (default: FrameEvent.Update)
|
514
|
-
*/
|
430
|
+
|
515
431
|
stopCoroutine(routine: Generator, evt: FrameEvent = FrameEvent.Update): void {
|
516
432
|
this.context.unregisterCoroutineUpdate(routine, evt);
|
517
433
|
}
|
518
434
|
|
519
|
-
/** @returns true if this component was destroyed (`this.destroy()`) or the whole object this component was part of */
|
520
435
|
public get destroyed(): boolean {
|
521
436
|
return this.__destroyed;
|
522
437
|
}
|
523
438
|
|
524
|
-
/**
|
525
|
-
* Destroys this component (and removes it from the object)
|
526
|
-
*/
|
527
439
|
public destroy() {
|
528
440
|
if (this.__destroyed) return;
|
529
441
|
this.__internalDestroy();
|
@@ -552,11 +464,7 @@
|
|
552
464
|
|
553
465
|
/** @internal */
|
554
466
|
constructor() {
|
555
|
-
this.
|
556
|
-
this.__didStart = false;
|
557
|
-
this.__didEnable = false;
|
558
|
-
this.__isEnabled = undefined;
|
559
|
-
this.__destroyed = false;
|
467
|
+
this.__internalNewInstanceCreated();
|
560
468
|
}
|
561
469
|
|
562
470
|
|
@@ -758,6 +666,5 @@
|
|
758
666
|
}
|
759
667
|
}
|
760
668
|
|
761
|
-
|
762
|
-
|
763
|
-
export { Component as Behaviour };
|
669
|
+
export class Behaviour extends Component {
|
670
|
+
}
|
@@ -1,4 +1,3 @@
|
|
1
|
-
/* eslint-disable */
|
2
1
|
// Export types
|
3
2
|
export class __Ignore {}
|
4
3
|
export { ActionBuilder } from "../export/usdz/extensions/behavior/BehavioursBuilder.js";
|
@@ -12,11 +11,11 @@
|
|
12
11
|
export { Animator } from "../Animator.js";
|
13
12
|
export { AnimatorController } from "../AnimatorController.js";
|
14
13
|
export { Antialiasing } from "../postprocessing/Effects/Antialiasing.js";
|
14
|
+
export { AttachedObject } from "../webxr/WebXRController.js";
|
15
15
|
export { AudioExtension } from "../export/usdz/extensions/behavior/AudioExtension.js";
|
16
16
|
export { AudioListener } from "../AudioListener.js";
|
17
17
|
export { AudioSource } from "../AudioSource.js";
|
18
18
|
export { AudioTrackHandler } from "../timeline/TimelineTracks.js";
|
19
|
-
export { Avatar } from "../webxr/Avatar.js";
|
20
19
|
export { Avatar_Brain_LookAt } from "../avatar/Avatar_Brain_LookAt.js";
|
21
20
|
export { Avatar_MouthShapes } from "../avatar/Avatar_MouthShapes.js";
|
22
21
|
export { Avatar_MustacheShake } from "../avatar/Avatar_MustacheShake.js";
|
@@ -31,6 +30,7 @@
|
|
31
30
|
export { BasicIKConstraint } from "../BasicIKConstraint.js";
|
32
31
|
export { BehaviorExtension } from "../export/usdz/extensions/behavior/Behaviour.js";
|
33
32
|
export { BehaviorModel } from "../export/usdz/extensions/behavior/BehavioursBuilder.js";
|
33
|
+
export { Behaviour } from "../Component.js";
|
34
34
|
export { Bloom } from "../postprocessing/Effects/Bloom.js";
|
35
35
|
export { BoxCollider } from "../Collider.js";
|
36
36
|
export { BoxGizmo } from "../Gizmos.js";
|
@@ -51,6 +51,7 @@
|
|
51
51
|
export { ColorAdjustments } from "../postprocessing/Effects/ColorAdjustments.js";
|
52
52
|
export { ColorBySpeedModule } from "../ParticleSystemModules.js";
|
53
53
|
export { ColorOverLifetimeModule } from "../ParticleSystemModules.js";
|
54
|
+
export { Component } from "../Component.js";
|
54
55
|
export { ContactShadows } from "../ContactShadows.js";
|
55
56
|
export { ControlTrackHandler } from "../timeline/TimelineTracks.js";
|
56
57
|
export { CustomBranding } from "../export/usdz/USDZExporter.js";
|
@@ -87,6 +88,7 @@
|
|
87
88
|
export { Image } from "../ui/Image.js";
|
88
89
|
export { InheritVelocityModule } from "../ParticleSystemModules.js";
|
89
90
|
export { InputField } from "../ui/InputField.js";
|
91
|
+
export { Interactable } from "../Interactable.js";
|
90
92
|
export { Light } from "../Light.js";
|
91
93
|
export { LimitVelocityOverLifetimeModule } from "../ParticleSystemModules.js";
|
92
94
|
export { LODGroup } from "../LODGroup.js";
|
@@ -100,7 +102,6 @@
|
|
100
102
|
export { MeshRenderer } from "../Renderer.js";
|
101
103
|
export { MinMaxCurve } from "../ParticleSystemModules.js";
|
102
104
|
export { MinMaxGradient } from "../ParticleSystemModules.js";
|
103
|
-
export { NeedleWebXRHtmlElement } from "../webxr/WebXRButtons.js";
|
104
105
|
export { NestedGltf } from "../NestedGltf.js";
|
105
106
|
export { Networking } from "../Networking.js";
|
106
107
|
export { NoiseModule } from "../ParticleSystemModules.js";
|
@@ -124,6 +125,7 @@
|
|
124
125
|
export { PreliminaryAction } from "../export/usdz/extensions/behavior/BehaviourComponents.js";
|
125
126
|
export { PreliminaryTrigger } from "../export/usdz/extensions/behavior/BehaviourComponents.js";
|
126
127
|
export { RawImage } from "../ui/Image.js";
|
128
|
+
export { Raycaster } from "../ui/Raycaster.js";
|
127
129
|
export { Rect } from "../ui/RectTransform.js";
|
128
130
|
export { RectTransform } from "../ui/RectTransform.js";
|
129
131
|
export { ReflectionProbe } from "../ReflectionProbe.js";
|
@@ -151,7 +153,6 @@
|
|
151
153
|
export { SizeOverLifetimeModule } from "../ParticleSystemModules.js";
|
152
154
|
export { SkinnedMeshRenderer } from "../Renderer.js";
|
153
155
|
export { SmoothFollow } from "../SmoothFollow.js";
|
154
|
-
export { SpatialGrabRaycaster } from "../ui/Raycaster.js";
|
155
156
|
export { SpatialHtml } from "../ui/SpatialHtml.js";
|
156
157
|
export { SpatialTrigger } from "../SpatialTrigger.js";
|
157
158
|
export { SpatialTriggerReceiver } from "../SpatialTrigger.js";
|
@@ -166,7 +167,7 @@
|
|
166
167
|
export { SyncedRoom } from "../SyncedRoom.js";
|
167
168
|
export { SyncedTransform } from "../SyncedTransform.js";
|
168
169
|
export { TapGestureTrigger } from "../export/usdz/extensions/behavior/BehaviourComponents.js";
|
169
|
-
export { TeleportTarget } from "../webxr/
|
170
|
+
export { TeleportTarget } from "../webxr/WebXRController.js";
|
170
171
|
export { TestRunner } from "../TestRunner.js";
|
171
172
|
export { TestSimulateUserData } from "../TestRunner.js";
|
172
173
|
export { Text } from "../ui/Text.js";
|
@@ -196,16 +197,20 @@
|
|
196
197
|
export { Volume } from "../postprocessing/Volume.js";
|
197
198
|
export { VolumeParameter } from "../postprocessing/VolumeParameter.js";
|
198
199
|
export { VolumeProfile } from "../postprocessing/VolumeProfile.js";
|
200
|
+
export { VRUserState } from "../webxr/WebXRSync.js";
|
201
|
+
export { WebAR } from "../webxr/WebXR.js";
|
199
202
|
export { WebARCameraBackground } from "../webxr/WebARCameraBackground.js";
|
200
203
|
export { WebARSessionRoot } from "../webxr/WebARSessionRoot.js";
|
201
204
|
export { WebXR } from "../webxr/WebXR.js";
|
205
|
+
export { WebXRAvatar } from "../webxr/WebXRAvatar.js";
|
206
|
+
export { WebXRController } from "../webxr/WebXRController.js";
|
202
207
|
export { WebXRImageTracking } from "../webxr/WebXRImageTracking.js";
|
203
208
|
export { WebXRImageTrackingModel } from "../webxr/WebXRImageTracking.js";
|
204
209
|
export { WebXRPlaneTracking } from "../webxr/WebXRPlaneTracking.js";
|
210
|
+
export { WebXRSync } from "../webxr/WebXRSync.js";
|
205
211
|
export { WebXRTrackedImage } from "../webxr/WebXRImageTracking.js";
|
206
|
-
export {
|
207
|
-
export {
|
208
|
-
export {
|
209
|
-
export { XRFlag } from "../webxr/XRFlag.js";
|
212
|
+
export { XRFlag } from "../XRFlag.js";
|
213
|
+
export { XRGrabModel } from "../webxr/WebXRGrabRendering.js";
|
214
|
+
export { XRGrabRendering } from "../webxr/WebXRGrabRendering.js";
|
210
215
|
export { XRRig } from "../webxr/WebXRRig.js";
|
211
|
-
export { XRState } from "../
|
216
|
+
export { XRState } from "../XRFlag.js";
|
@@ -1,11 +1,11 @@
|
|
1
|
+
import { Behaviour } from "./Component.js";
|
2
|
+
import { serializable } from "../engine/engine_serialization_decorator.js";
|
3
|
+
|
1
4
|
import { CustomBlending, DoubleSide, Group, Matrix4, MaxEquation, Mesh, MeshBasicMaterial, MeshDepthMaterial, MinEquation, OrthographicCamera, PlaneGeometry, ShaderMaterial, WebGLRenderTarget } from "three";
|
2
5
|
import { HorizontalBlurShader } from 'three/examples/jsm/shaders/HorizontalBlurShader.js';
|
3
6
|
import { VerticalBlurShader } from 'three/examples/jsm/shaders/VerticalBlurShader.js';
|
4
|
-
|
5
|
-
import { serializable } from "../engine/engine_serialization_decorator.js";
|
6
7
|
import { getParam } from "../engine/engine_utils.js"
|
7
8
|
import { setCustomVisibility } from "../engine/js-extensions/Layers.js";
|
8
|
-
import { Behaviour } from "./Component.js";
|
9
9
|
|
10
10
|
const debug = getParam("debugcontactshadows");
|
11
11
|
|
@@ -1,7 +1,6 @@
|
|
1
|
+
import { getErrorCount } from "./debug_overlay.js";
|
2
|
+
import { getParam, isMobileDevice } from "../engine_utils.js";
|
1
3
|
import { isLocalNetwork } from "../engine_networking_utils.js";
|
2
|
-
import { getParam, isMobileDevice, isQuest } from "../engine_utils.js";
|
3
|
-
import { isDevEnvironment } from "./debug.js";
|
4
|
-
import { getErrorCount, makeErrorsVisibleForDevelopment } from "./debug_overlay.js";
|
5
4
|
|
6
5
|
let consoleInstance: any = null;
|
7
6
|
let consoleHtmlElement: HTMLElement | null = null;
|
@@ -23,11 +22,8 @@
|
|
23
22
|
currentUrl.searchParams.set("console", "1");
|
24
23
|
console.log("🌵 Tip: You can add the \"?console\" query parameter to the url to show the debug console (on mobile it will automatically open in the bottom right corner when your get errors during development)", "\nOpen this page console: " + currentUrl.toString());
|
25
24
|
}
|
26
|
-
const isMobile = isMobileDevice()
|
25
|
+
const isMobile = isMobileDevice();
|
27
26
|
if (isMobile) {
|
28
|
-
// we need to invoke this here - otherwise we will miss errors that happen after the console is loaded
|
29
|
-
// and calling the method from the root needle-engine.ts import is evaluated later (if we import the method from the toplevel file and then invoke it)
|
30
|
-
makeErrorsVisibleForDevelopment();
|
31
27
|
beginWatchingLogs();
|
32
28
|
createConsole(true);
|
33
29
|
if (isMobile) {
|
@@ -195,7 +191,7 @@
|
|
195
191
|
}
|
196
192
|
`;
|
197
193
|
consoleHtmlElement?.prepend(styles);
|
198
|
-
if (startHidden === true
|
194
|
+
if (startHidden === true)
|
199
195
|
hideDebugConsole();
|
200
196
|
console.log("🌵 Debug console has loaded");
|
201
197
|
}
|
@@ -1,6 +1,6 @@
|
|
1
|
+
import { getParam } from "../engine_utils.js";
|
2
|
+
import { isLocalNetwork } from "../engine_networking_utils.js";
|
1
3
|
import { ContextRegistry } from "../engine_context_registry.js";
|
2
|
-
import { isLocalNetwork } from "../engine_networking_utils.js";
|
3
|
-
import { getParam } from "../engine_utils.js";
|
4
4
|
|
5
5
|
const debug = getParam("debugdebug");
|
6
6
|
let hide = false;
|
@@ -15,7 +15,7 @@
|
|
15
15
|
}
|
16
16
|
|
17
17
|
export function getErrorCount() {
|
18
|
-
return
|
18
|
+
return errorCount;
|
19
19
|
}
|
20
20
|
|
21
21
|
const originalConsoleError = console.error;
|
@@ -37,10 +37,9 @@
|
|
37
37
|
if (hide) return;
|
38
38
|
const isLocal = isLocalNetwork();
|
39
39
|
if (debug) console.log("Is this a local network?", isLocal);
|
40
|
-
if (isLocal)
|
41
|
-
{
|
40
|
+
if (isLocal) {
|
42
41
|
if (debug)
|
43
|
-
console.
|
42
|
+
console.log(window.location.hostname);
|
44
43
|
console.error = patchedConsoleError;
|
45
44
|
window.addEventListener("error", (event) => {
|
46
45
|
if (hide) return;
|
@@ -67,10 +66,10 @@
|
|
67
66
|
}
|
68
67
|
|
69
68
|
|
70
|
-
let
|
69
|
+
let errorCount = 0;
|
71
70
|
|
72
71
|
function onReceivedError() {
|
73
|
-
|
72
|
+
errorCount += 1;
|
74
73
|
}
|
75
74
|
|
76
75
|
function onParseError(args: Array<any>) {
|
@@ -1,6 +1,6 @@
|
|
1
|
+
import { addLog, LogType, setAllowOverlayMessages } from "./debug_overlay.js";
|
2
|
+
import { showDebugConsole } from "./debug_console.js";
|
1
3
|
import { isLocalNetwork } from "../engine_networking_utils.js";
|
2
|
-
import { showDebugConsole } from "./debug_console.js";
|
3
|
-
import { addLog, LogType, setAllowOverlayMessages } from "./debug_overlay.js";
|
4
4
|
|
5
5
|
export { showDebugConsole }
|
6
6
|
export { LogType, setAllowOverlayMessages };
|
@@ -1,6 +1,5 @@
|
|
1
1
|
|
2
2
|
import * as THREE from "three";
|
3
|
-
|
4
3
|
import { syncDestroy } from "../engine/engine_networking_instantiate.js";
|
5
4
|
import { getParam } from "../engine/engine_utils.js";
|
6
5
|
import { BoxHelperComponent } from "./BoxHelperComponent.js";
|
@@ -1,8 +1,7 @@
|
|
1
1
|
import { DepthOfFieldEffect } from "postprocessing";
|
2
|
-
|
2
|
+
import { serializable } from "../../../engine/engine_serialization.js";
|
3
3
|
import { Mathf } from "../../../engine/engine_math.js";
|
4
|
-
import {
|
5
|
-
import { isMobileDevice } from "../../../engine/engine_utils.js";
|
4
|
+
import { getParam, isMobileDevice } from "../../../engine/engine_utils.js";
|
6
5
|
import { PostProcessingEffect } from "../PostProcessingEffect.js";
|
7
6
|
import { VolumeParameter } from "../VolumeParameter.js";
|
8
7
|
import { registerCustomEffectType } from "../VolumeProfile.js";
|
@@ -13,6 +12,8 @@
|
|
13
12
|
Bokeh = 2,
|
14
13
|
}
|
15
14
|
|
15
|
+
const debug = getParam("debugpost");
|
16
|
+
|
16
17
|
export class DepthOfField extends PostProcessingEffect {
|
17
18
|
|
18
19
|
get typeName() {
|
@@ -41,6 +42,8 @@
|
|
41
42
|
bokehScale?: VolumeParameter;
|
42
43
|
|
43
44
|
init() {
|
45
|
+
if (debug) console.log("DOF: INIT");
|
46
|
+
|
44
47
|
this.focalLength.valueProcessor = v => {
|
45
48
|
const t = v / 300;
|
46
49
|
const max = 2;// this.context.mainCameraComponent?.farClipPlane ?? 10;
|
@@ -55,7 +58,10 @@
|
|
55
58
|
}
|
56
59
|
|
57
60
|
onCreateEffect() {
|
58
|
-
if (this.mode === DepthOfFieldMode.Off)
|
61
|
+
if (this.mode === DepthOfFieldMode.Off) {
|
62
|
+
if (debug) console.warn("DepthOfField: Mode is set to Off");
|
63
|
+
return undefined;
|
64
|
+
}
|
59
65
|
|
60
66
|
const factor = 1 / window.devicePixelRatio;
|
61
67
|
|
@@ -78,9 +84,9 @@
|
|
78
84
|
});
|
79
85
|
|
80
86
|
this.focusDistance.onValueChanged = v => {
|
81
|
-
dof.
|
87
|
+
dof.cocMaterial.worldFocusDistance = v;
|
82
88
|
}
|
83
|
-
this.focalLength.onValueChanged = v => dof.
|
89
|
+
this.focalLength.onValueChanged = v => dof.cocMaterial.worldFocusRange = v;
|
84
90
|
this.aperture.onValueChanged = v => dof.bokehScale = v;
|
85
91
|
|
86
92
|
if (this.resolutionScale) this.resolutionScale.onValueChanged = v => dof.resolution.scale = v;
|
@@ -1,6 +1,6 @@
|
|
1
1
|
|
2
|
+
import { isMobileDevice } from "../engine/engine_utils.js";
|
2
3
|
import { serializable } from "../engine/engine_serialization_decorator.js";
|
3
|
-
import { isMobileDevice } from "../engine/engine_utils.js";
|
4
4
|
import { Behaviour, GameObject } from "./Component.js";
|
5
5
|
|
6
6
|
|
@@ -1,126 +1,104 @@
|
|
1
|
-
import {
|
2
|
-
|
3
|
-
import {
|
4
|
-
import {
|
5
|
-
import {
|
1
|
+
import { GameObject } from "./Component.js";
|
2
|
+
import { SyncedTransform } from "./SyncedTransform.js";
|
3
|
+
import type { IPointerDownHandler, IPointerEnterHandler, IPointerEventHandler, IPointerExitHandler, IPointerUpHandler, PointerEventData } from "./ui/PointerEvents.js";
|
4
|
+
import { Context } from "../engine/engine_setup.js";
|
5
|
+
import { Interactable, UsageMarker } from "./Interactable.js";
|
6
|
+
import { Rigidbody } from "./RigidBody.js";
|
7
|
+
import { WebXR } from "./webxr/WebXR.js";
|
8
|
+
import { Avatar_POI } from "./avatar/Avatar_Brain_LookAt.js";
|
6
9
|
import { RaycastOptions } from "../engine/engine_physics.js";
|
7
|
-
import { serializable } from "../engine/engine_serialization_decorator.js";
|
8
|
-
import { Context } from "../engine/engine_setup.js";
|
9
10
|
import { getWorldPosition, setWorldPosition } from "../engine/engine_three_utils.js";
|
10
|
-
import {
|
11
|
-
import {
|
12
|
-
import {
|
13
|
-
import { Avatar_POI } from "./avatar/Avatar_Brain_LookAt.js";
|
14
|
-
import { Behaviour, GameObject } from "./Component.js";
|
15
|
-
import { UsageMarker } from "./Interactable.js";
|
11
|
+
import type { KeyCode } from "../engine/engine_input.js";
|
12
|
+
import { nameofFactory } from "../engine/engine_utils.js";
|
13
|
+
import { InstancingUtil } from "../engine/engine_instancing.js";
|
16
14
|
import { OrbitControls } from "./OrbitControls.js";
|
17
|
-
import {
|
18
|
-
import { SyncedTransform } from "./SyncedTransform.js";
|
19
|
-
import type { IPointerEventHandler, PointerEventData } from "./ui/PointerEvents.js";
|
15
|
+
import { BufferGeometry, Camera, Color, Line, LineBasicMaterial, Matrix4, Mesh, MeshBasicMaterial, Object3D, Plane, Ray, Raycaster, SphereGeometry, Vector2, Vector3 } from "three";
|
20
16
|
import { ObjectRaycaster } from "./ui/Raycaster.js";
|
17
|
+
import { serializable } from "../engine/engine_serialization_decorator.js";
|
21
18
|
|
22
|
-
const debug =
|
19
|
+
const debug = false;
|
23
20
|
|
24
|
-
export enum
|
25
|
-
|
26
|
-
|
27
|
-
/** Object is dragged as if it was attached to the pointer. In 2D, that means it's dragged along the camera screen plane. In XR, it's dragged by the controller/hand. */
|
28
|
-
Attached = 1,
|
29
|
-
/** Object is dragged along the initial raycast hit normal. */
|
30
|
-
HitNormal = 2,
|
31
|
-
/** Combination of XZ and Screen based on the viewing angle. Low angles result in Screen dragging and higher angles in XZ dragging. */
|
32
|
-
DynamicViewAngle = 3,
|
33
|
-
/** The drag plane is adjusted dynamically while dragging. */
|
34
|
-
SnapToSurfaces = 4,
|
21
|
+
export enum DragEvents {
|
22
|
+
SelectStart = "selectstart",
|
23
|
+
SelectEnd = "selectend",
|
35
24
|
}
|
36
25
|
|
37
|
-
|
26
|
+
interface SelectArgs {
|
27
|
+
selected: Object3D;
|
28
|
+
attached: Object3D | GameObject | null;
|
29
|
+
}
|
38
30
|
|
39
|
-
// dragPlane (floor, object, view)
|
40
|
-
// snap to surface (snap orientation?)
|
41
|
-
// two-handed drag (scale, rotate, move)
|
42
|
-
// keep upright (no tilt)
|
43
31
|
|
44
|
-
|
45
|
-
|
46
|
-
|
32
|
+
export interface IDragEventListener {
|
33
|
+
onDragStart?();
|
34
|
+
onDragEnd?();
|
35
|
+
}
|
47
36
|
|
48
|
-
|
49
|
-
@serializable()
|
50
|
-
public snapGridResolution: number = 0.0;
|
51
|
-
|
52
|
-
/** Keep the original rotation of the dragged object. */
|
53
|
-
@serializable()
|
54
|
-
public keepRotation: boolean = true;
|
55
|
-
|
56
|
-
/** How and where the object is dragged along while dragging in XR. */
|
57
|
-
@serializable()
|
58
|
-
public xrDragMode: DragMode = DragMode.Attached;
|
37
|
+
export class DragControls extends Interactable implements IPointerEventHandler {
|
59
38
|
|
60
|
-
|
61
|
-
|
62
|
-
public xrKeepRotation: boolean = false;
|
39
|
+
private static _active: number = 0;
|
40
|
+
public static get HasAnySelected(): boolean { return this._active > 0; }
|
63
41
|
|
64
|
-
/**
|
42
|
+
/** Show's drag gizmos when enabled */
|
65
43
|
@serializable()
|
66
|
-
public
|
44
|
+
public showGizmo: boolean = true;
|
67
45
|
|
68
|
-
/** When enabled
|
46
|
+
/** When enabled DragControls will drag vertically when the object is viewed from a low angle */
|
69
47
|
@serializable()
|
70
|
-
public
|
48
|
+
public useViewAngle: boolean = true;
|
71
49
|
|
72
|
-
|
73
|
-
//
|
50
|
+
public transformSelf: boolean = true;
|
51
|
+
// public transformGroup: boolean = true;
|
52
|
+
// public targets: Object3D[] | null = null;
|
74
53
|
|
75
|
-
|
76
|
-
private static _active: number = 0;
|
77
|
-
|
78
|
-
/** The object to be dragged – we pass this to handlers when they are created */
|
79
|
-
private targetObject: GameObject | null = null;
|
54
|
+
// private controls: Control | null = null;
|
80
55
|
private orbit: OrbitControls | null = null;
|
81
|
-
private _dragHelper: LegacyDragVisualsHelper | null = null;
|
82
|
-
private static lastHovered: Object3D;
|
83
|
-
private _draggingRigidbodies: Rigidbody[] = [];
|
84
|
-
private _potentialDragStartEvt: PointerEventData | null = null;
|
85
|
-
private _dragHandlers: Map<Object3D, IDragHandler> = new Map();
|
86
|
-
private _totalMovement: Vector3 = new Vector3();
|
87
|
-
/** A marker is attached to components that are currently interacted with, to e.g. prevent them from being deleted. */
|
88
|
-
private _marker: UsageMarker | null = null;
|
89
|
-
private _isDragging: boolean = false;
|
90
|
-
private _didDrag: boolean = false;
|
91
56
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
57
|
+
private selectStartEventListener: ((controls: DragControls, args: SelectArgs) => void)[] = [];
|
58
|
+
private selectEndEventListener: Array<Function> = [];
|
59
|
+
private _dragHelper: DragHelper | null = null;
|
60
|
+
|
61
|
+
constructor() {
|
62
|
+
super();
|
63
|
+
this.selectStartEventListener = [];
|
64
|
+
this.selectEndEventListener = [];
|
65
|
+
this._dragDelta = new Vector2();
|
97
66
|
}
|
98
67
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
68
|
+
|
69
|
+
// TODO: Update DragEventListener code
|
70
|
+
addDragEventListener(type: DragEvents, cb: (ctrls: DragControls, args: SelectArgs) => void | Function) {
|
71
|
+
switch (type) {
|
72
|
+
case DragEvents.SelectStart:
|
73
|
+
this.selectStartEventListener.push(cb);
|
74
|
+
break;
|
75
|
+
case DragEvents.SelectEnd:
|
76
|
+
this.selectEndEventListener.push(cb);
|
77
|
+
break;
|
78
|
+
}
|
109
79
|
}
|
110
80
|
|
81
|
+
|
82
|
+
|
111
83
|
start() {
|
112
84
|
this.orbit = GameObject.findObjectOfType(OrbitControls, this.context);
|
113
|
-
if (!this.gameObject.getComponentInParent(ObjectRaycaster))
|
85
|
+
if (!this.gameObject.getComponentInParent(ObjectRaycaster)) {
|
114
86
|
this.gameObject.addNewComponent(ObjectRaycaster);
|
87
|
+
}
|
115
88
|
}
|
116
89
|
|
90
|
+
private static lastHovered: Object3D;
|
91
|
+
private _draggingRigidbodies: Rigidbody[] = [];
|
92
|
+
|
117
93
|
private allowEdit(_obj: Object3D | null = null) {
|
118
94
|
return this.context.connection.allowEditing;
|
119
95
|
}
|
120
96
|
|
121
97
|
onPointerEnter(evt: PointerEventData) {
|
122
98
|
if (!this.allowEdit(this.gameObject)) return;
|
123
|
-
if (
|
99
|
+
if (WebXR.IsInWebXR) return;
|
100
|
+
// const interactable = GameObject.getComponentInParent(evt.object, Interactable);
|
101
|
+
// if (!interactable) return;
|
124
102
|
const dc = GameObject.getComponentInParent(evt.object, DragControls);
|
125
103
|
if (!dc || dc !== this) return;
|
126
104
|
DragControls.lastHovered = evt.object;
|
@@ -129,121 +107,83 @@
|
|
129
107
|
|
130
108
|
onPointerExit(evt: PointerEventData) {
|
131
109
|
if (!this.allowEdit(this.gameObject)) return;
|
132
|
-
if (
|
110
|
+
if (WebXR.IsInWebXR) return;
|
133
111
|
if (DragControls.lastHovered !== evt.object) return;
|
112
|
+
// const interactable = GameObject.getComponentInParent(evt.object, Interactable);
|
113
|
+
// if (!interactable) return;
|
134
114
|
this.context.domElement.style.cursor = 'auto';
|
135
115
|
}
|
136
116
|
|
117
|
+
private _waitingForDragStart: PointerEventData | null = null;
|
118
|
+
|
137
119
|
onPointerDown(args: PointerEventData) {
|
138
120
|
if (!this.allowEdit(this.gameObject)) return;
|
139
|
-
if (
|
140
|
-
DragControls.
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
DragControls._active += 1;
|
150
|
-
|
151
|
-
const newDragHandler = new DragPointerHandler(this, this.targetObject || this.gameObject);
|
152
|
-
this._dragHandlers.set(args.event.space, newDragHandler);
|
153
|
-
|
154
|
-
// We need to turn off OrbitControls immediately, otherwise they still get data for a short moment
|
155
|
-
// and they don't properly handle being disabled while already processing data (smoothing happens when enabling again)
|
156
|
-
if (this.orbit) this.orbit.enabled = false;
|
157
|
-
|
158
|
-
newDragHandler.onDragStart(args);
|
159
|
-
|
160
|
-
if (this._dragHandlers.size === 2) {
|
161
|
-
const iterator = this._dragHandlers.values();
|
162
|
-
const a = iterator.next().value;
|
163
|
-
const b = iterator.next().value;
|
164
|
-
const mtHandler = new MultiTouchDragHandler(this, this.targetObject || this.gameObject, a, b);
|
165
|
-
this._dragHandlers.set(this.gameObject, mtHandler);
|
166
|
-
|
167
|
-
mtHandler.onDragStart(args);
|
168
|
-
}
|
169
|
-
|
170
|
-
args.use();
|
171
|
-
}
|
121
|
+
if (WebXR.IsInWebXR) return;
|
122
|
+
DragControls._active += 1;
|
123
|
+
this._dragDelta.set(0, 0);
|
124
|
+
this._didDrag = false;
|
125
|
+
// Clone to not modify the original event (and this event is used in the actual onDragStart method)
|
126
|
+
this._waitingForDragStart = args.clone();
|
127
|
+
args.stopPropagation();
|
128
|
+
// disabling pointer controls here already, otherwise we get a few frames of movement event in orbit controls and this will rotate the camera sligthly AFTER drag controls dragging ends.
|
129
|
+
if (this.orbit) this.orbit.enabled = false;
|
172
130
|
}
|
173
131
|
|
174
132
|
onPointerMove(args: PointerEventData) {
|
175
|
-
if
|
133
|
+
if(this._isDragging || this._waitingForDragStart !== null) args.use();
|
176
134
|
}
|
177
135
|
|
178
136
|
onPointerUp(args: PointerEventData) {
|
179
|
-
|
180
|
-
if(debug) Gizmos.DrawLabel(args.point ?? this.gameObject.worldPosition, "POINTERUP:" + args.pointerId + ", " + args.button, .03, 3);
|
181
|
-
|
137
|
+
this._waitingForDragStart = null;
|
182
138
|
if (!this.allowEdit(this.gameObject)) return;
|
183
|
-
if (
|
184
|
-
|
139
|
+
if (DragControls._active > 0)
|
140
|
+
DragControls._active -= 1;
|
141
|
+
if (WebXR.IsInWebXR) return;
|
142
|
+
this.onDragEnd(args);
|
143
|
+
args.stopPropagation();
|
144
|
+
if (this.orbit) this.orbit.enabled = true;
|
145
|
+
}
|
185
146
|
|
186
|
-
const handler = this._dragHandlers.get(args.event.space);
|
187
|
-
const mtHandler = this._dragHandlers.get(this.gameObject) as MultiTouchDragHandler;
|
188
|
-
if (mtHandler && (mtHandler.handlerA === handler || mtHandler.handlerB === handler)) {
|
189
|
-
// any of the two handlers has been released, so we can remove the multi-touch handler
|
190
|
-
this._dragHandlers.delete(this.gameObject);
|
191
|
-
mtHandler.onDragEnd(args);
|
192
|
-
}
|
193
147
|
|
194
|
-
if (handler) {
|
195
|
-
if (DragControls._active > 0)
|
196
|
-
DragControls._active -= 1;
|
197
|
-
|
198
|
-
if (handler.onDragEnd) handler.onDragEnd(args);
|
199
|
-
this._dragHandlers.delete(args.event.space);
|
200
|
-
|
201
|
-
if (this._dragHandlers.size === 0) {
|
202
|
-
this.onLastDragEnd(args);
|
203
|
-
}
|
204
|
-
args.use();
|
205
|
-
}
|
206
|
-
|
207
|
-
if (DragControls._active === 0) {
|
208
|
-
if (this.orbit) this.orbit.enabled = true;
|
209
|
-
}
|
210
|
-
}
|
211
|
-
|
212
148
|
update(): void {
|
149
|
+
if (WebXR.IsInWebXR) return;
|
213
150
|
|
214
|
-
for (const handler of this._dragHandlers.values()) {
|
215
|
-
if (handler.collectMovementInfo) handler.collectMovementInfo();
|
216
|
-
// TODO this doesn't make sense, we should instead just use the max here
|
217
|
-
// or even better, each handler can decide on their own how to handle this
|
218
|
-
if (handler.getTotalMovement) this._totalMovement.add(handler.getTotalMovement());
|
219
|
-
}
|
220
|
-
|
221
151
|
// drag start only after having dragged for some pixels
|
222
|
-
if (this.
|
152
|
+
if (this._waitingForDragStart) {
|
223
153
|
if (!this._didDrag) {
|
224
|
-
// this is so we can e.g. process clicks without having a drag change the position
|
225
|
-
//
|
226
|
-
|
154
|
+
// this is so we can e.g. process clicks without having a drag change the position
|
155
|
+
// e.g. a click to rotate the object
|
156
|
+
const delta = this.context.input.getPointerPositionDelta(0);
|
157
|
+
if (delta)
|
158
|
+
this._dragDelta.add(delta);
|
159
|
+
if (this._dragDelta.length() > 2)
|
227
160
|
this._didDrag = true;
|
228
161
|
else return;
|
229
162
|
}
|
230
|
-
const args = this.
|
231
|
-
this.
|
232
|
-
this.
|
163
|
+
const args = this._waitingForDragStart;
|
164
|
+
this._waitingForDragStart = null;
|
165
|
+
this.onDragStart(args);
|
233
166
|
}
|
234
167
|
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
168
|
+
if (this._dragHelper && this._dragHelper.hasSelected) {
|
169
|
+
this.onUpdateDrag();
|
170
|
+
}
|
171
|
+
|
172
|
+
if (this._dragHelper?.hasSelected === false || (this._activePointerId !== undefined && this.context.input.getPointerPressed(this._activePointerId) === false)) {
|
173
|
+
this.onDragEnd(null);
|
174
|
+
}
|
240
175
|
}
|
241
176
|
|
242
|
-
|
243
|
-
private
|
177
|
+
private _isDragging: boolean = false;
|
178
|
+
private _marker: UsageMarker | null = null;
|
179
|
+
private _dragDelta!: Vector2;
|
180
|
+
private _didDrag: boolean = false;
|
181
|
+
private _activePointerId?: number;
|
182
|
+
|
183
|
+
private onDragStart(evt: PointerEventData) {
|
244
184
|
if (!this._dragHelper) {
|
245
185
|
if (this.context.mainCamera)
|
246
|
-
this._dragHelper = new
|
186
|
+
this._dragHelper = new DragHelper(this.context.mainCamera);
|
247
187
|
else
|
248
188
|
return;
|
249
189
|
}
|
@@ -252,17 +192,46 @@
|
|
252
192
|
const dc = GameObject.getComponentInParent(evt.object, DragControls);
|
253
193
|
if (!dc || dc !== this) return;
|
254
194
|
|
255
|
-
const object = this.targetObject || this.gameObject;
|
256
195
|
|
257
|
-
|
196
|
+
let object: Object3D = evt.object;
|
258
197
|
|
198
|
+
if (this.transformSelf) {
|
199
|
+
object = this.gameObject;
|
200
|
+
}
|
201
|
+
|
202
|
+
// raise event
|
203
|
+
const args: { selected: Object3D, attached: Object3D | null } = { selected: object, attached: object };
|
204
|
+
for (const listener of this.selectStartEventListener) {
|
205
|
+
listener(this, args);
|
206
|
+
}
|
207
|
+
|
208
|
+
this._activePointerId = evt.pointerId;
|
209
|
+
|
210
|
+
if (!args.attached) return;
|
211
|
+
if (args.attached !== object) {
|
212
|
+
// // if duplicatable changes the object being dragged
|
213
|
+
// // should it also change the active drag controls (e.g. if it has a own one)
|
214
|
+
// const drag = GameObject.getComponentInParent(args.attached, DragControls);
|
215
|
+
// if (drag && drag !== this) {
|
216
|
+
// // incredibly ugly code to pass the drag controls event to another drag controls instance
|
217
|
+
// // This is necessary since we dont call the onPointerUp events anymore for all objects
|
218
|
+
// // that have previously received the onPointerDown event.
|
219
|
+
// // NOTE: added the EventSystem.raisedPointerDownEvents array again because of this uglyness here. The code was originally removed in 757fc5e5bafd02aa13d6cd35dd5e8729c841465a and now we're adding it in 8ce886d8344d1abd5ebb89ae3e1fb8d6d47293da
|
220
|
+
// this.onDragEnd(null);
|
221
|
+
// drag.onPointerDown(evt);
|
222
|
+
// evt.object = args.attached;
|
223
|
+
// drag.onDragStart(evt);
|
224
|
+
// return;
|
225
|
+
// }
|
226
|
+
}
|
227
|
+
object = args.attached;
|
259
228
|
this._isDragging = true;
|
260
229
|
this._dragHelper.setSelected(object, this.context);
|
261
230
|
if (this.orbit) this.orbit.enabled = false;
|
262
231
|
|
263
232
|
const sync = GameObject.getComponentInChildren(object, SyncedTransform);
|
264
|
-
if (debug)
|
265
|
-
|
233
|
+
if (debug)
|
234
|
+
console.log("DRAG START", sync, object);
|
266
235
|
if (sync) {
|
267
236
|
sync.fastMode = true;
|
268
237
|
sync?.requestOwnership();
|
@@ -270,31 +239,30 @@
|
|
270
239
|
|
271
240
|
this._marker = GameObject.addNewComponent(object, UsageMarker);
|
272
241
|
|
242
|
+
// console.log(object, this._marker);
|
243
|
+
|
273
244
|
this._draggingRigidbodies.length = 0;
|
274
245
|
const rbs = GameObject.getComponentsInChildren(object, Rigidbody);
|
275
246
|
if (rbs)
|
276
247
|
this._draggingRigidbodies.push(...rbs);
|
248
|
+
|
249
|
+
const l = nameofFactory<IDragEventListener>();
|
250
|
+
GameObject.invokeOnChildren(this._dragHelper.selected, l("onDragStart"));
|
277
251
|
}
|
278
252
|
|
279
|
-
|
280
|
-
private onAnyDragUpdate() {
|
253
|
+
private onUpdateDrag() {
|
281
254
|
if (!this._dragHelper) return;
|
282
255
|
this._dragHelper.showGizmo = this.showGizmo;
|
256
|
+
this._dragHelper.useViewAngle = this.useViewAngle;
|
283
257
|
|
284
258
|
this._dragHelper.onUpdate(this.context);
|
285
259
|
for (const rb of this._draggingRigidbodies) {
|
286
260
|
rb.wakeUp();
|
287
261
|
rb.resetVelocities();
|
288
|
-
rb.resetForcesAndTorques();
|
289
262
|
}
|
290
|
-
|
291
|
-
const object = this.targetObject || this.gameObject;
|
292
|
-
|
293
|
-
InstancingUtil.markDirty(object);
|
294
263
|
}
|
295
264
|
|
296
|
-
|
297
|
-
private onLastDragEnd(evt: PointerEventData | null) {
|
265
|
+
private onDragEnd(evt: PointerEventData | null) {
|
298
266
|
if (!this || !this._isDragging) return;
|
299
267
|
this._isDragging = false;
|
300
268
|
if (!this._dragHelper) return;
|
@@ -303,7 +271,8 @@
|
|
303
271
|
}
|
304
272
|
this._draggingRigidbodies.length = 0;
|
305
273
|
const selected = this._dragHelper.selected;
|
306
|
-
if (debug)
|
274
|
+
if (debug)
|
275
|
+
console.log("DRAG END", selected, selected?.visible)
|
307
276
|
this._dragHelper.setSelected(null, this.context);
|
308
277
|
if (this.orbit) this.orbit.enabled = true;
|
309
278
|
if (evt?.object) {
|
@@ -313,751 +282,23 @@
|
|
313
282
|
// sync?.requestOwnership();
|
314
283
|
}
|
315
284
|
}
|
316
|
-
if (this._marker)
|
285
|
+
if (this._marker) {
|
317
286
|
this._marker.destroy();
|
318
|
-
}
|
319
|
-
}
|
320
|
-
|
321
|
-
/** Handles two touch points affecting one object. Allows movement, scale and rotation of objects. */
|
322
|
-
class MultiTouchDragHandler implements IDragHandler {
|
323
|
-
|
324
|
-
handlerA: DragPointerHandler;
|
325
|
-
handlerB: DragPointerHandler;
|
326
|
-
|
327
|
-
private context: Context;
|
328
|
-
private settings: DragControls;
|
329
|
-
private gameObject: GameObject;
|
330
|
-
private _handlerAAttachmentPoint: Vector3 = new Vector3();
|
331
|
-
private _handlerBAttachmentPoint: Vector3 = new Vector3();
|
332
|
-
|
333
|
-
private _followObject: GameObject;
|
334
|
-
private _manipulatorObject: GameObject;
|
335
|
-
private _deviceMode!: XRTargetRayMode;
|
336
|
-
private _followObjectStartWorldQuaternion: Quaternion = new Quaternion();
|
337
|
-
|
338
|
-
constructor(dragControls: DragControls, gameObject: GameObject, pointerA: DragPointerHandler, pointerB: DragPointerHandler) {
|
339
|
-
this.context = dragControls.context;
|
340
|
-
this.settings = dragControls;
|
341
|
-
this.gameObject = gameObject;
|
342
|
-
this.handlerA = pointerA;
|
343
|
-
this.handlerB = pointerB;
|
344
|
-
|
345
|
-
this._followObject = new Object3D() as GameObject;
|
346
|
-
this._manipulatorObject = new Object3D() as GameObject;
|
347
|
-
|
348
|
-
this.context.scene.add(this._manipulatorObject);
|
349
|
-
|
350
|
-
const rig = NeedleXRSession.active?.rig?.gameObject;
|
351
|
-
|
352
|
-
if (!this.handlerA || !this.handlerB || !this.handlerA.hitPointInLocalSpace || !this.handlerB.hitPointInLocalSpace) {
|
353
|
-
console.error("Invalid: MultiTouchDragHandler needs two valid DragPointerHandlers with hitPointInLocalSpace set.");
|
354
|
-
return;
|
355
287
|
}
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
this.gameObject.localToWorld(this._tempVec1);
|
360
|
-
this.gameObject.localToWorld(this._tempVec2);
|
361
|
-
if (rig) {
|
362
|
-
rig.worldToLocal(this._tempVec1);
|
363
|
-
rig.worldToLocal(this._tempVec2);
|
288
|
+
// raise event
|
289
|
+
for (const listener of this.selectEndEventListener) {
|
290
|
+
listener(this);
|
364
291
|
}
|
365
|
-
this._initialDistance = this._tempVec1.distanceTo(this._tempVec2);
|
366
|
-
|
367
|
-
if (this._initialDistance < 0.02) {
|
368
|
-
if (debug) {
|
369
|
|