@needle-tools/engine 4.7.0-alpha → 4.7.0-next.da47826
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3768 -3768
- package/LICENSE.md +10 -10
- package/README.md +64 -64
- package/components.needle.json +1 -1
- package/dist/generateMeshBVH.worker-BaNp_Xtp.js +25 -0
- package/dist/{gltf-progressive-Bm9eEfgu.min.js → gltf-progressive-Bl4okF1b.min.js} +1 -1
- package/dist/{gltf-progressive-GjIqwSG3.js → gltf-progressive-DSpdn0QT.js} +2 -2
- package/dist/{gltf-progressive-Dn6o99rH.umd.cjs → gltf-progressive-P8b8a0qY.umd.cjs} +1 -1
- package/dist/{needle-engine.bundle-CK8cQ3FX.umd.cjs → needle-engine.bundle-Bu88IoKB.umd.cjs} +57 -57
- package/dist/{needle-engine.bundle-CXtflnL6.js → needle-engine.bundle-CO1Ub9sm.js} +638 -638
- package/dist/{needle-engine.bundle-BEUFTdl6.min.js → needle-engine.bundle-D95XN5pP.min.js} +62 -62
- package/dist/needle-engine.d.ts +130 -129
- package/dist/needle-engine.js +4 -4
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/dist/{postprocessing-8AQTeZsr.umd.cjs → postprocessing-CjW23fio.umd.cjs} +2 -2
- package/dist/{postprocessing-BkxN_08g.js → postprocessing-DYLNOL3W.js} +3 -3
- package/dist/{postprocessing-BDScN9yu.min.js → postprocessing-xYQWCHFu.min.js} +2 -2
- package/dist/{three-DMrv-4ar.umd.cjs → three-B_hneGZr.umd.cjs} +4 -4
- package/dist/{three-Bz6X1mrw.js → three-DrqIzZTH.js} +4198 -4198
- package/dist/{three-Boa-jOq-.min.js → three-DuDKwKB8.min.js} +33 -33
- package/dist/{three-examples-GggCDHv0.js → three-examples-B50TT3Iu.js} +5 -5
- package/dist/{three-examples-DuVhxqft.min.js → three-examples-DaDLBuy6.min.js} +14 -14
- package/dist/{three-examples-C7ryg8vN.umd.cjs → three-examples-X3OadjXB.umd.cjs} +3 -3
- package/dist/{three-mesh-ui-CY6Izc7C.min.js → three-mesh-ui-B3p3gyUz.min.js} +1 -1
- package/dist/{three-mesh-ui-CwlN0FUC.umd.cjs → three-mesh-ui-CQiIQIlA.umd.cjs} +1 -1
- package/dist/{three-mesh-ui-CLNOfsWn.js → three-mesh-ui-CxuWt7m-.js} +1 -1
- package/dist/{vendor-zxXa3Dmr.min.js → vendor-BlSxe9JJ.min.js} +3 -3
- package/dist/{vendor-BSD1RQIh.js → vendor-BmYIgaS1.js} +3 -3
- package/dist/{vendor-DHr4aqIZ.umd.cjs → vendor-Cavtu3CP.umd.cjs} +3 -3
- package/lib/asap/needle-asap.d.ts +1 -1
- package/lib/asap/needle-asap.js +95 -95
- package/lib/asap/sessiongranted.d.ts +3 -3
- package/lib/asap/sessiongranted.js +65 -65
- package/lib/asap/utils.d.ts +1 -1
- package/lib/asap/utils.js +3 -3
- package/lib/engine/analytics/index.d.ts +6 -6
- package/lib/engine/analytics/index.js +12 -12
- package/lib/engine/analytics/lcp.d.ts +3 -3
- package/lib/engine/analytics/lcp.js +34 -34
- package/lib/engine/api.d.ts +82 -82
- package/lib/engine/api.js +81 -81
- package/lib/engine/assets/index.d.ts +11 -11
- package/lib/engine/assets/index.js +47 -47
- package/lib/engine/assets/static.d.ts +1 -1
- package/lib/engine/assets/static.js +4 -4
- package/lib/engine/codegen/register_types.d.ts +1 -1
- package/lib/engine/codegen/register_types.js +300 -300
- package/lib/engine/debug/debug.d.ts +15 -15
- package/lib/engine/debug/debug.js +44 -44
- package/lib/engine/debug/debug_console.d.ts +2 -2
- package/lib/engine/debug/debug_console.js +307 -307
- package/lib/engine/debug/debug_overlay.d.ts +22 -22
- package/lib/engine/debug/debug_overlay.js +316 -316
- package/lib/engine/debug/debug_spatial_console.d.ts +2 -2
- package/lib/engine/debug/debug_spatial_console.js +390 -390
- package/lib/engine/debug/index.d.ts +2 -2
- package/lib/engine/debug/index.js +2 -2
- package/lib/engine/engine_addressables.d.ts +166 -166
- package/lib/engine/engine_addressables.js +608 -608
- package/lib/engine/engine_animation.d.ts +43 -43
- package/lib/engine/engine_animation.js +133 -133
- package/lib/engine/engine_application.d.ts +45 -45
- package/lib/engine/engine_application.js +104 -104
- package/lib/engine/engine_assetdatabase.d.ts +25 -25
- package/lib/engine/engine_assetdatabase.js +346 -346
- package/lib/engine/engine_audio.d.ts +4 -4
- package/lib/engine/engine_audio.js +23 -23
- package/lib/engine/engine_camera.d.ts +13 -13
- package/lib/engine/engine_camera.js +30 -30
- package/lib/engine/engine_components.d.ts +110 -110
- package/lib/engine/engine_components.js +374 -374
- package/lib/engine/engine_components_internal.d.ts +9 -9
- package/lib/engine/engine_components_internal.js +36 -36
- package/lib/engine/engine_constants.d.ts +10 -10
- package/lib/engine/engine_constants.js +41 -41
- package/lib/engine/engine_context.d.ts +475 -475
- package/lib/engine/engine_context.js +1672 -1672
- package/lib/engine/engine_context_registry.d.ts +71 -71
- package/lib/engine/engine_context_registry.js +117 -117
- package/lib/engine/engine_coroutine.d.ts +35 -35
- package/lib/engine/engine_coroutine.js +52 -52
- package/lib/engine/engine_create_objects.d.ts +119 -119
- package/lib/engine/engine_create_objects.js +320 -320
- package/lib/engine/engine_default_parameters.d.ts +2 -2
- package/lib/engine/engine_default_parameters.js +3 -3
- package/lib/engine/engine_editor-sync.d.ts +21 -21
- package/lib/engine/engine_editor-sync.js +4 -4
- package/lib/engine/engine_fileloader.d.ts +2 -2
- package/lib/engine/engine_fileloader.js +8 -8
- package/lib/engine/engine_gameobject.d.ts +68 -68
- package/lib/engine/engine_gameobject.js +619 -619
- package/lib/engine/engine_generic_utils.d.ts +1 -1
- package/lib/engine/engine_generic_utils.js +13 -13
- package/lib/engine/engine_gizmos.d.ts +149 -149
- package/lib/engine/engine_gizmos.js +530 -530
- package/lib/engine/engine_gltf.d.ts +12 -12
- package/lib/engine/engine_gltf.js +15 -15
- package/lib/engine/engine_gltf_builtin_components.d.ts +11 -11
- package/lib/engine/engine_gltf_builtin_components.js +341 -341
- package/lib/engine/engine_hot_reload.d.ts +8 -8
- package/lib/engine/engine_hot_reload.js +197 -197
- package/lib/engine/engine_input.d.ts +362 -362
- package/lib/engine/engine_input.js +1294 -1294
- package/lib/engine/engine_input_utils.d.ts +2 -2
- package/lib/engine/engine_input_utils.js +22 -22
- package/lib/engine/engine_instancing.d.ts +19 -19
- package/lib/engine/engine_instancing.js +39 -39
- package/lib/engine/engine_license.d.ts +11 -11
- package/lib/engine/engine_license.js +369 -369
- package/lib/engine/engine_lifecycle_api.d.ts +83 -83
- package/lib/engine/engine_lifecycle_api.js +106 -106
- package/lib/engine/engine_lifecycle_functions_internal.d.ts +32 -32
- package/lib/engine/engine_lifecycle_functions_internal.js +146 -146
- package/lib/engine/engine_lightdata.d.ts +23 -23
- package/lib/engine/engine_lightdata.js +91 -91
- package/lib/engine/engine_loaders.callbacks.d.ts +97 -97
- package/lib/engine/engine_loaders.callbacks.js +86 -86
- package/lib/engine/engine_loaders.d.ts +48 -48
- package/lib/engine/engine_loaders.gltf.d.ts +13 -13
- package/lib/engine/engine_loaders.gltf.js +62 -62
- package/lib/engine/engine_loaders.js +337 -337
- package/lib/engine/engine_lods.d.ts +31 -31
- package/lib/engine/engine_lods.js +146 -146
- package/lib/engine/engine_mainloop_utils.d.ts +32 -32
- package/lib/engine/engine_mainloop_utils.js +466 -466
- package/lib/engine/engine_math.d.ts +114 -114
- package/lib/engine/engine_math.js +247 -247
- package/lib/engine/engine_modules.d.ts +36 -36
- package/lib/engine/engine_modules.js +85 -85
- package/lib/engine/engine_networking.d.ts +260 -260
- package/lib/engine/engine_networking.js +764 -764
- package/lib/engine/engine_networking_auto.d.ts +24 -24
- package/lib/engine/engine_networking_auto.js +310 -310
- package/lib/engine/engine_networking_blob.d.ts +48 -48
- package/lib/engine/engine_networking_blob.js +228 -228
- package/lib/engine/engine_networking_files.d.ts +35 -35
- package/lib/engine/engine_networking_files.js +172 -172
- package/lib/engine/engine_networking_files_default_components.d.ts +6 -6
- package/lib/engine/engine_networking_files_default_components.js +42 -42
- package/lib/engine/engine_networking_instantiate.d.ts +100 -100
- package/lib/engine/engine_networking_instantiate.js +345 -345
- package/lib/engine/engine_networking_peer.d.ts +15 -15
- package/lib/engine/engine_networking_peer.js +132 -132
- package/lib/engine/engine_networking_streams.d.ts +123 -123
- package/lib/engine/engine_networking_streams.js +645 -645
- package/lib/engine/engine_networking_types.d.ts +22 -22
- package/lib/engine/engine_networking_types.js +7 -7
- package/lib/engine/engine_networking_utils.d.ts +2 -2
- package/lib/engine/engine_networking_utils.js +20 -20
- package/lib/engine/engine_networking_websocket.d.ts +1 -1
- package/lib/engine/engine_networking_websocket.js +2 -2
- package/lib/engine/engine_patcher.d.ts +10 -10
- package/lib/engine/engine_patcher.js +142 -142
- package/lib/engine/engine_physics.d.ts +152 -152
- package/lib/engine/engine_physics.js +645 -645
- package/lib/engine/engine_physics.types.d.ts +40 -40
- package/lib/engine/engine_physics.types.js +33 -33
- package/lib/engine/engine_physics_rapier.d.ts +147 -147
- package/lib/engine/engine_physics_rapier.js +1433 -1433
- package/lib/engine/engine_playerview.d.ts +26 -26
- package/lib/engine/engine_playerview.js +64 -64
- package/lib/engine/engine_scenelighting.d.ts +71 -71
- package/lib/engine/engine_scenelighting.js +226 -226
- package/lib/engine/engine_serialization.d.ts +3 -3
- package/lib/engine/engine_serialization.js +3 -3
- package/lib/engine/engine_serialization_builtin_serializer.d.ts +72 -72
- package/lib/engine/engine_serialization_builtin_serializer.js +403 -403
- package/lib/engine/engine_serialization_core.d.ts +94 -94
- package/lib/engine/engine_serialization_core.js +607 -607
- package/lib/engine/engine_serialization_decorator.d.ts +23 -23
- package/lib/engine/engine_serialization_decorator.js +66 -66
- package/lib/engine/engine_setup.d.ts +1 -1
- package/lib/engine/engine_setup.js +2 -2
- package/lib/engine/engine_shaders.d.ts +53 -53
- package/lib/engine/engine_shaders.js +252 -252
- package/lib/engine/engine_shims.d.ts +4 -4
- package/lib/engine/engine_shims.js +24 -24
- package/lib/engine/engine_test_utils.d.ts +39 -39
- package/lib/engine/engine_test_utils.js +83 -83
- package/lib/engine/engine_texture.d.ts +28 -28
- package/lib/engine/engine_texture.js +64 -64
- package/lib/engine/engine_three_utils.d.ts +204 -204
- package/lib/engine/engine_three_utils.js +784 -784
- package/lib/engine/engine_time.d.ts +51 -51
- package/lib/engine/engine_time.js +82 -82
- package/lib/engine/engine_time_utils.d.ts +88 -88
- package/lib/engine/engine_time_utils.js +215 -215
- package/lib/engine/engine_tonemapping.d.ts +6 -6
- package/lib/engine/engine_tonemapping.js +197 -197
- package/lib/engine/engine_types.d.ts +578 -578
- package/lib/engine/engine_types.js +95 -95
- package/lib/engine/engine_typestore.d.ts +28 -28
- package/lib/engine/engine_typestore.js +55 -55
- package/lib/engine/engine_util_decorator.d.ts +13 -13
- package/lib/engine/engine_util_decorator.js +116 -116
- package/lib/engine/engine_utils.d.ts +248 -248
- package/lib/engine/engine_utils.js +1012 -1012
- package/lib/engine/engine_utils_format.d.ts +24 -24
- package/lib/engine/engine_utils_format.js +239 -239
- package/lib/engine/engine_utils_screenshot.d.ts +159 -159
- package/lib/engine/engine_utils_screenshot.js +522 -522
- package/lib/engine/engine_utils_screenshot.xr.d.ts +5 -5
- package/lib/engine/engine_utils_screenshot.xr.js +90 -90
- package/lib/engine/engine_xr.d.ts +1 -1
- package/lib/engine/engine_xr.js +1 -1
- package/lib/engine/export/gltf/Writers.d.ts +19 -19
- package/lib/engine/export/gltf/Writers.js +24 -24
- package/lib/engine/export/gltf/index.d.ts +11 -11
- package/lib/engine/export/gltf/index.js +123 -123
- package/lib/engine/export/index.d.ts +2 -2
- package/lib/engine/export/index.js +2 -2
- package/lib/engine/export/state.d.ts +7 -7
- package/lib/engine/export/state.js +17 -17
- package/lib/engine/export/utils.d.ts +2 -2
- package/lib/engine/export/utils.js +7 -7
- package/lib/engine/extensions/EXT_texture_exr.d.ts +8 -8
- package/lib/engine/extensions/EXT_texture_exr.js +32 -32
- package/lib/engine/extensions/NEEDLE_animator_controller_model.d.ts +122 -122
- package/lib/engine/extensions/NEEDLE_animator_controller_model.js +95 -95
- package/lib/engine/extensions/NEEDLE_components.d.ts +35 -35
- package/lib/engine/extensions/NEEDLE_components.js +220 -220
- package/lib/engine/extensions/NEEDLE_gameobject_data.d.ts +10 -10
- package/lib/engine/extensions/NEEDLE_gameobject_data.js +57 -57
- package/lib/engine/extensions/NEEDLE_lighting_settings.d.ts +37 -37
- package/lib/engine/extensions/NEEDLE_lighting_settings.js +157 -157
- package/lib/engine/extensions/NEEDLE_lightmaps.d.ts +18 -18
- package/lib/engine/extensions/NEEDLE_lightmaps.js +99 -99
- package/lib/engine/extensions/NEEDLE_persistent_assets.d.ts +11 -11
- package/lib/engine/extensions/NEEDLE_persistent_assets.js +63 -63
- package/lib/engine/extensions/NEEDLE_progressive.d.ts +1 -1
- package/lib/engine/extensions/NEEDLE_progressive.js +1 -1
- package/lib/engine/extensions/NEEDLE_render_objects.d.ts +13 -13
- package/lib/engine/extensions/NEEDLE_render_objects.js +159 -159
- package/lib/engine/extensions/NEEDLE_techniques_webgl.d.ts +38 -38
- package/lib/engine/extensions/NEEDLE_techniques_webgl.js +564 -564
- package/lib/engine/extensions/extension_resolver.d.ts +4 -4
- package/lib/engine/extensions/extension_resolver.js +1 -1
- package/lib/engine/extensions/extension_utils.d.ts +12 -12
- package/lib/engine/extensions/extension_utils.js +152 -152
- package/lib/engine/extensions/extensions.d.ts +32 -32
- package/lib/engine/extensions/extensions.js +107 -107
- package/lib/engine/extensions/index.d.ts +6 -6
- package/lib/engine/extensions/index.js +6 -6
- package/lib/engine/extensions/usage_tracker.d.ts +13 -13
- package/lib/engine/extensions/usage_tracker.js +65 -65
- package/lib/engine/js-extensions/Camera.d.ts +1 -1
- package/lib/engine/js-extensions/Camera.js +39 -39
- package/lib/engine/js-extensions/ExtensionUtils.d.ts +9 -9
- package/lib/engine/js-extensions/ExtensionUtils.js +67 -67
- package/lib/engine/js-extensions/Layers.d.ts +6 -6
- package/lib/engine/js-extensions/Layers.js +22 -22
- package/lib/engine/js-extensions/Object3D.d.ts +120 -120
- package/lib/engine/js-extensions/Object3D.js +136 -136
- package/lib/engine/js-extensions/RGBAColor.d.ts +23 -23
- package/lib/engine/js-extensions/RGBAColor.js +111 -111
- package/lib/engine/js-extensions/Vector.d.ts +3 -3
- package/lib/engine/js-extensions/Vector.js +13 -13
- package/lib/engine/js-extensions/index.d.ts +5 -5
- package/lib/engine/js-extensions/index.js +5 -5
- package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.d.ts +4 -4
- package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +79 -79
- package/lib/engine/shaders/shaderData.d.ts +55 -55
- package/lib/engine/shaders/shaderData.js +58 -58
- package/lib/engine/tests/test_utils.d.ts +2 -2
- package/lib/engine/tests/test_utils.js +53 -53
- package/lib/engine/webcomponents/WebXRButtons.d.ts +56 -56
- package/lib/engine/webcomponents/WebXRButtons.js +230 -230
- package/lib/engine/webcomponents/api.d.ts +5 -5
- package/lib/engine/webcomponents/api.js +4 -4
- package/lib/engine/webcomponents/buttons.d.ts +51 -51
- package/lib/engine/webcomponents/buttons.js +264 -264
- package/lib/engine/webcomponents/fonts.d.ts +9 -9
- package/lib/engine/webcomponents/fonts.js +32 -32
- package/lib/engine/webcomponents/icons.d.ts +9 -9
- package/lib/engine/webcomponents/icons.js +52 -52
- package/lib/engine/webcomponents/index.d.ts +1 -1
- package/lib/engine/webcomponents/index.js +1 -1
- package/lib/engine/webcomponents/logo-element.d.ts +10 -10
- package/lib/engine/webcomponents/logo-element.js +67 -67
- package/lib/engine/webcomponents/needle menu/needle-menu-spatial.d.ts +37 -37
- package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js +513 -513
- package/lib/engine/webcomponents/needle menu/needle-menu.d.ts +155 -155
- package/lib/engine/webcomponents/needle menu/needle-menu.js +1029 -1029
- package/lib/engine/webcomponents/needle-button.d.ts +34 -34
- package/lib/engine/webcomponents/needle-button.js +161 -161
- package/lib/engine/webcomponents/needle-engine.ar-overlay.d.ts +21 -21
- package/lib/engine/webcomponents/needle-engine.ar-overlay.js +166 -166
- package/lib/engine/webcomponents/needle-engine.attributes.d.ts +69 -69
- package/lib/engine/webcomponents/needle-engine.attributes.js +1 -1
- package/lib/engine/webcomponents/needle-engine.d.ts +116 -116
- package/lib/engine/webcomponents/needle-engine.extras.d.ts +6 -6
- package/lib/engine/webcomponents/needle-engine.extras.js +13 -13
- package/lib/engine/webcomponents/needle-engine.js +821 -821
- package/lib/engine/webcomponents/needle-engine.loading.d.ts +44 -44
- package/lib/engine/webcomponents/needle-engine.loading.js +341 -341
- package/lib/engine/xr/NeedleXRController.d.ts +313 -313
- package/lib/engine/xr/NeedleXRController.js +1007 -1007
- package/lib/engine/xr/NeedleXRSession.d.ts +340 -340
- package/lib/engine/xr/NeedleXRSession.js +1463 -1463
- package/lib/engine/xr/NeedleXRSync.d.ts +22 -22
- package/lib/engine/xr/NeedleXRSync.js +188 -188
- package/lib/engine/xr/SceneTransition.d.ts +18 -18
- package/lib/engine/xr/SceneTransition.js +69 -69
- package/lib/engine/xr/TempXRContext.d.ts +34 -34
- package/lib/engine/xr/TempXRContext.js +187 -187
- package/lib/engine/xr/XRRig.d.ts +7 -7
- package/lib/engine/xr/XRRig.js +1 -1
- package/lib/engine/xr/api.d.ts +6 -6
- package/lib/engine/xr/api.js +6 -6
- package/lib/engine/xr/events.d.ts +66 -66
- package/lib/engine/xr/events.js +93 -93
- package/lib/engine/xr/internal.d.ts +12 -12
- package/lib/engine/xr/internal.js +25 -25
- package/lib/engine/xr/usdz.d.ts +12 -12
- package/lib/engine/xr/usdz.js +29 -29
- package/lib/engine/xr/utils.d.ts +11 -11
- package/lib/engine/xr/utils.js +34 -34
- package/lib/engine-components/AlignmentConstraint.d.ts +10 -10
- package/lib/engine-components/AlignmentConstraint.js +39 -39
- package/lib/engine-components/Animation.d.ts +156 -156
- package/lib/engine-components/Animation.js +508 -508
- package/lib/engine-components/AnimationCurve.d.ts +40 -40
- package/lib/engine-components/AnimationCurve.js +159 -159
- package/lib/engine-components/AnimationUtils.d.ts +8 -8
- package/lib/engine-components/AnimationUtils.js +27 -27
- package/lib/engine-components/AnimationUtilsAutoplay.d.ts +1 -1
- package/lib/engine-components/AnimationUtilsAutoplay.js +39 -39
- package/lib/engine-components/Animator.d.ts +217 -217
- package/lib/engine-components/Animator.js +354 -354
- package/lib/engine-components/AnimatorController.d.ts +227 -227
- package/lib/engine-components/AnimatorController.js +1152 -1152
- package/lib/engine-components/AudioListener.d.ts +33 -33
- package/lib/engine-components/AudioListener.js +86 -86
- package/lib/engine-components/AudioSource.d.ts +217 -217
- package/lib/engine-components/AudioSource.js +635 -635
- package/lib/engine-components/AvatarLoader.d.ts +80 -80
- package/lib/engine-components/AvatarLoader.js +231 -231
- package/lib/engine-components/AxesHelper.d.ts +32 -32
- package/lib/engine-components/AxesHelper.js +67 -67
- package/lib/engine-components/BasicIKConstraint.d.ts +9 -9
- package/lib/engine-components/BasicIKConstraint.js +43 -43
- package/lib/engine-components/BoxCollider.d.ts +2 -2
- package/lib/engine-components/BoxCollider.js +2 -2
- package/lib/engine-components/BoxHelperComponent.d.ts +47 -47
- package/lib/engine-components/BoxHelperComponent.js +102 -102
- package/lib/engine-components/Camera.d.ts +231 -231
- package/lib/engine-components/Camera.js +700 -700
- package/lib/engine-components/CameraUtils.d.ts +1 -1
- package/lib/engine-components/CameraUtils.js +121 -121
- package/lib/engine-components/CharacterController.d.ts +55 -55
- package/lib/engine-components/CharacterController.js +236 -236
- package/lib/engine-components/Collider.d.ts +188 -188
- package/lib/engine-components/Collider.js +369 -369
- package/lib/engine-components/Component.d.ts +792 -792
- package/lib/engine-components/Component.js +920 -920
- package/lib/engine-components/ContactShadows.d.ts +94 -94
- package/lib/engine-components/ContactShadows.js +453 -453
- package/lib/engine-components/DeleteBox.d.ts +19 -19
- package/lib/engine-components/DeleteBox.js +58 -58
- package/lib/engine-components/DeviceFlag.d.ts +16 -16
- package/lib/engine-components/DeviceFlag.js +47 -47
- package/lib/engine-components/DragControls.d.ts +170 -170
- package/lib/engine-components/DragControls.js +1421 -1421
- package/lib/engine-components/DropListener.d.ts +215 -215
- package/lib/engine-components/DropListener.js +642 -642
- package/lib/engine-components/Duplicatable.d.ts +35 -35
- package/lib/engine-components/Duplicatable.js +202 -202
- package/lib/engine-components/EventList.d.ts +54 -54
- package/lib/engine-components/EventList.js +232 -232
- package/lib/engine-components/EventTrigger.d.ts +33 -33
- package/lib/engine-components/EventTrigger.js +75 -75
- package/lib/engine-components/EventType.d.ts +22 -22
- package/lib/engine-components/EventType.js +23 -23
- package/lib/engine-components/Fog.d.ts +22 -22
- package/lib/engine-components/Fog.js +61 -61
- package/lib/engine-components/Gizmos.d.ts +17 -17
- package/lib/engine-components/Gizmos.js +64 -64
- package/lib/engine-components/GridHelper.d.ts +20 -20
- package/lib/engine-components/GridHelper.js +54 -54
- package/lib/engine-components/GroundProjection.d.ts +67 -67
- package/lib/engine-components/GroundProjection.js +343 -343
- package/lib/engine-components/Interactable.d.ts +12 -12
- package/lib/engine-components/Interactable.js +12 -12
- package/lib/engine-components/Joints.d.ts +19 -19
- package/lib/engine-components/Joints.js +51 -51
- package/lib/engine-components/LODGroup.d.ts +35 -35
- package/lib/engine-components/LODGroup.js +152 -152
- package/lib/engine-components/Light.d.ts +180 -180
- package/lib/engine-components/Light.js +535 -535
- package/lib/engine-components/LookAtConstraint.d.ts +19 -19
- package/lib/engine-components/LookAtConstraint.js +35 -35
- package/lib/engine-components/NeedleMenu.d.ts +50 -50
- package/lib/engine-components/NeedleMenu.js +92 -92
- package/lib/engine-components/NestedGltf.d.ts +25 -25
- package/lib/engine-components/NestedGltf.js +88 -88
- package/lib/engine-components/Networking.d.ts +54 -54
- package/lib/engine-components/Networking.js +112 -112
- package/lib/engine-components/OffsetConstraint.d.ts +14 -14
- package/lib/engine-components/OffsetConstraint.js +65 -65
- package/lib/engine-components/OrbitControls.d.ts +268 -268
- package/lib/engine-components/OrbitControls.js +1015 -1015
- package/lib/engine-components/PlayerColor.d.ts +19 -19
- package/lib/engine-components/PlayerColor.js +94 -94
- package/lib/engine-components/ReflectionProbe.d.ts +28 -28
- package/lib/engine-components/ReflectionProbe.js +204 -204
- package/lib/engine-components/Renderer.d.ts +153 -153
- package/lib/engine-components/Renderer.js +834 -834
- package/lib/engine-components/RendererInstancing.d.ts +140 -140
- package/lib/engine-components/RendererInstancing.js +744 -744
- package/lib/engine-components/RendererLightmap.d.ts +24 -24
- package/lib/engine-components/RendererLightmap.js +182 -182
- package/lib/engine-components/RigidBody.d.ts +155 -155
- package/lib/engine-components/RigidBody.js +517 -517
- package/lib/engine-components/SceneSwitcher.d.ts +263 -263
- package/lib/engine-components/SceneSwitcher.js +971 -971
- package/lib/engine-components/ScreenCapture.d.ts +144 -144
- package/lib/engine-components/ScreenCapture.js +547 -547
- package/lib/engine-components/ShadowCatcher.d.ts +33 -33
- package/lib/engine-components/ShadowCatcher.js +166 -166
- package/lib/engine-components/Skybox.d.ts +88 -88
- package/lib/engine-components/Skybox.js +469 -469
- package/lib/engine-components/SmoothFollow.d.ts +34 -34
- package/lib/engine-components/SmoothFollow.js +82 -82
- package/lib/engine-components/SpatialTrigger.d.ts +102 -102
- package/lib/engine-components/SpatialTrigger.js +225 -225
- package/lib/engine-components/SpectatorCamera.d.ts +111 -111
- package/lib/engine-components/SpectatorCamera.js +715 -715
- package/lib/engine-components/SphereCollider.d.ts +2 -2
- package/lib/engine-components/SphereCollider.js +2 -2
- package/lib/engine-components/SpriteRenderer.d.ts +132 -132
- package/lib/engine-components/SpriteRenderer.js +472 -472
- package/lib/engine-components/SyncedCamera.d.ts +41 -41
- package/lib/engine-components/SyncedCamera.js +199 -199
- package/lib/engine-components/SyncedRoom.d.ts +106 -106
- package/lib/engine-components/SyncedRoom.js +371 -371
- package/lib/engine-components/SyncedTransform.d.ts +94 -94
- package/lib/engine-components/SyncedTransform.js +331 -331
- package/lib/engine-components/TestRunner.d.ts +16 -16
- package/lib/engine-components/TestRunner.js +102 -102
- package/lib/engine-components/TransformGizmo.d.ts +75 -75
- package/lib/engine-components/TransformGizmo.js +209 -209
- package/lib/engine-components/VideoPlayer.d.ts +184 -184
- package/lib/engine-components/VideoPlayer.js +978 -978
- package/lib/engine-components/Voip.d.ts +67 -67
- package/lib/engine-components/Voip.js +360 -360
- package/lib/engine-components/api.d.ts +51 -51
- package/lib/engine-components/api.js +50 -50
- package/lib/engine-components/avatar/AvatarBlink_Simple.d.ts +11 -11
- package/lib/engine-components/avatar/AvatarBlink_Simple.js +76 -76
- package/lib/engine-components/avatar/AvatarEyeLook_Rotation.d.ts +14 -14
- package/lib/engine-components/avatar/AvatarEyeLook_Rotation.js +68 -68
- package/lib/engine-components/avatar/Avatar_Brain_LookAt.d.ts +29 -29
- package/lib/engine-components/avatar/Avatar_Brain_LookAt.js +121 -121
- package/lib/engine-components/avatar/Avatar_MouthShapes.d.ts +15 -15
- package/lib/engine-components/avatar/Avatar_MouthShapes.js +79 -79
- package/lib/engine-components/avatar/Avatar_MustacheShake.d.ts +9 -9
- package/lib/engine-components/avatar/Avatar_MustacheShake.js +29 -29
- package/lib/engine-components/codegen/components.d.ts +216 -216
- package/lib/engine-components/codegen/components.js +218 -218
- package/lib/engine-components/debug/LogStats.d.ts +5 -5
- package/lib/engine-components/debug/LogStats.js +18 -18
- package/lib/engine-components/export/gltf/GltfExport.d.ts +30 -30
- package/lib/engine-components/export/gltf/GltfExport.js +246 -246
- package/lib/engine-components/export/gltf/index.d.ts +1 -1
- package/lib/engine-components/export/gltf/index.js +1 -1
- package/lib/engine-components/export/index.d.ts +1 -1
- package/lib/engine-components/export/index.js +1 -1
- package/lib/engine-components/export/usdz/Extension.d.ts +22 -22
- package/lib/engine-components/export/usdz/Extension.js +1 -1
- package/lib/engine-components/export/usdz/ThreeUSDZExporter.d.ts +162 -162
- package/lib/engine-components/export/usdz/ThreeUSDZExporter.js +1789 -1789
- package/lib/engine-components/export/usdz/USDZExporter.d.ts +130 -130
- package/lib/engine-components/export/usdz/USDZExporter.js +663 -663
- package/lib/engine-components/export/usdz/extensions/Animation.d.ts +106 -106
- package/lib/engine-components/export/usdz/extensions/Animation.js +1071 -1071
- package/lib/engine-components/export/usdz/extensions/DocumentExtension.d.ts +5 -5
- package/lib/engine-components/export/usdz/extensions/DocumentExtension.js +6 -6
- package/lib/engine-components/export/usdz/extensions/NodeMaterialConverter.d.ts +10 -10
- package/lib/engine-components/export/usdz/extensions/NodeMaterialConverter.js +451 -451
- package/lib/engine-components/export/usdz/extensions/USDZText.d.ts +54 -54
- package/lib/engine-components/export/usdz/extensions/USDZText.js +203 -203
- package/lib/engine-components/export/usdz/extensions/USDZUI.d.ts +8 -8
- package/lib/engine-components/export/usdz/extensions/USDZUI.js +158 -158
- package/lib/engine-components/export/usdz/extensions/behavior/Actions.d.ts +30 -30
- package/lib/engine-components/export/usdz/extensions/behavior/Actions.js +88 -88
- package/lib/engine-components/export/usdz/extensions/behavior/AudioExtension.d.ts +10 -10
- package/lib/engine-components/export/usdz/extensions/behavior/AudioExtension.js +86 -86
- package/lib/engine-components/export/usdz/extensions/behavior/Behaviour.d.ts +28 -28
- package/lib/engine-components/export/usdz/extensions/behavior/Behaviour.js +290 -290
- package/lib/engine-components/export/usdz/extensions/behavior/BehaviourComponents.d.ts +190 -190
- package/lib/engine-components/export/usdz/extensions/behavior/BehaviourComponents.js +1060 -1060
- package/lib/engine-components/export/usdz/extensions/behavior/BehavioursBuilder.d.ts +135 -135
- package/lib/engine-components/export/usdz/extensions/behavior/BehavioursBuilder.js +548 -548
- package/lib/engine-components/export/usdz/extensions/behavior/PhysicsExtension.d.ts +7 -7
- package/lib/engine-components/export/usdz/extensions/behavior/PhysicsExtension.js +115 -115
- package/lib/engine-components/export/usdz/index.d.ts +3 -3
- package/lib/engine-components/export/usdz/index.js +2 -2
- package/lib/engine-components/export/usdz/utils/animationutils.d.ts +7 -7
- package/lib/engine-components/export/usdz/utils/animationutils.js +163 -163
- package/lib/engine-components/export/usdz/utils/quicklook.d.ts +2 -2
- package/lib/engine-components/export/usdz/utils/quicklook.js +43 -43
- package/lib/engine-components/particlesystem/ParticleSystem.d.ts +177 -177
- package/lib/engine-components/particlesystem/ParticleSystem.js +1176 -1176
- package/lib/engine-components/particlesystem/ParticleSystemModules.d.ts +526 -526
- package/lib/engine-components/particlesystem/ParticleSystemModules.js +1930 -1930
- package/lib/engine-components/particlesystem/ParticleSystemSubEmitter.d.ts +25 -25
- package/lib/engine-components/particlesystem/ParticleSystemSubEmitter.js +87 -87
- package/lib/engine-components/particlesystem/api.d.ts +2 -2
- package/lib/engine-components/particlesystem/api.js +2 -2
- package/lib/engine-components/postprocessing/Effects/Antialiasing.d.ts +17 -17
- package/lib/engine-components/postprocessing/Effects/Antialiasing.js +52 -52
- package/lib/engine-components/postprocessing/Effects/BloomEffect.d.ts +46 -46
- package/lib/engine-components/postprocessing/Effects/BloomEffect.js +113 -113
- package/lib/engine-components/postprocessing/Effects/ChromaticAberration.d.ts +11 -11
- package/lib/engine-components/postprocessing/Effects/ChromaticAberration.js +39 -39
- package/lib/engine-components/postprocessing/Effects/ColorAdjustments.d.ts +23 -23
- package/lib/engine-components/postprocessing/Effects/ColorAdjustments.js +111 -111
- package/lib/engine-components/postprocessing/Effects/DepthOfField.d.ts +25 -25
- package/lib/engine-components/postprocessing/Effects/DepthOfField.js +104 -104
- package/lib/engine-components/postprocessing/Effects/EffectWrapper.d.ts +12 -12
- package/lib/engine-components/postprocessing/Effects/EffectWrapper.js +18 -18
- package/lib/engine-components/postprocessing/Effects/Pixelation.d.ts +11 -11
- package/lib/engine-components/postprocessing/Effects/Pixelation.js +32 -32
- package/lib/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusion.d.ts +18 -18
- package/lib/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusion.js +91 -91
- package/lib/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusionN8.d.ts +70 -70
- package/lib/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusionN8.js +176 -176
- package/lib/engine-components/postprocessing/Effects/Sharpening.d.ts +18 -18
- package/lib/engine-components/postprocessing/Effects/Sharpening.js +127 -127
- package/lib/engine-components/postprocessing/Effects/TiltShiftEffect.d.ts +17 -17
- package/lib/engine-components/postprocessing/Effects/TiltShiftEffect.js +70 -70
- package/lib/engine-components/postprocessing/Effects/Tonemapping.d.ts +19 -19
- package/lib/engine-components/postprocessing/Effects/Tonemapping.js +94 -94
- package/lib/engine-components/postprocessing/Effects/Tonemapping.utils.d.ts +13 -13
- package/lib/engine-components/postprocessing/Effects/Tonemapping.utils.js +51 -51
- package/lib/engine-components/postprocessing/Effects/Vignette.d.ts +15 -15
- package/lib/engine-components/postprocessing/Effects/Vignette.js +60 -60
- package/lib/engine-components/postprocessing/PostProcessingEffect.d.ts +90 -90
- package/lib/engine-components/postprocessing/PostProcessingEffect.js +168 -168
- package/lib/engine-components/postprocessing/PostProcessingHandler.d.ts +42 -42
- package/lib/engine-components/postprocessing/PostProcessingHandler.js +480 -480
- package/lib/engine-components/postprocessing/Volume.d.ts +90 -90
- package/lib/engine-components/postprocessing/Volume.js +385 -385
- package/lib/engine-components/postprocessing/VolumeParameter.d.ts +26 -26
- package/lib/engine-components/postprocessing/VolumeParameter.js +136 -136
- package/lib/engine-components/postprocessing/VolumeProfile.d.ts +15 -15
- package/lib/engine-components/postprocessing/VolumeProfile.js +60 -60
- package/lib/engine-components/postprocessing/index.d.ts +6 -6
- package/lib/engine-components/postprocessing/index.js +6 -6
- package/lib/engine-components/postprocessing/utils.d.ts +55 -55
- package/lib/engine-components/postprocessing/utils.js +119 -119
- package/lib/engine-components/timeline/PlayableDirector.d.ts +163 -163
- package/lib/engine-components/timeline/PlayableDirector.js +686 -686
- package/lib/engine-components/timeline/SignalAsset.d.ts +24 -24
- package/lib/engine-components/timeline/SignalAsset.js +130 -130
- package/lib/engine-components/timeline/TimelineModels.d.ts +89 -89
- package/lib/engine-components/timeline/TimelineModels.js +22 -22
- package/lib/engine-components/timeline/TimelineTracks.d.ts +110 -110
- package/lib/engine-components/timeline/TimelineTracks.js +879 -879
- package/lib/engine-components/timeline/index.d.ts +4 -4
- package/lib/engine-components/timeline/index.js +3 -3
- package/lib/engine-components/ui/BaseUIComponent.d.ts +48 -48
- package/lib/engine-components/ui/BaseUIComponent.js +170 -170
- package/lib/engine-components/ui/Button.d.ts +64 -64
- package/lib/engine-components/ui/Button.js +315 -315
- package/lib/engine-components/ui/Canvas.d.ts +74 -74
- package/lib/engine-components/ui/Canvas.js +407 -407
- package/lib/engine-components/ui/CanvasGroup.d.ts +19 -19
- package/lib/engine-components/ui/CanvasGroup.js +58 -58
- package/lib/engine-components/ui/EventSystem.d.ts +125 -125
- package/lib/engine-components/ui/EventSystem.js +765 -765
- package/lib/engine-components/ui/Graphic.d.ts +55 -55
- package/lib/engine-components/ui/Graphic.js +255 -255
- package/lib/engine-components/ui/Image.d.ts +35 -35
- package/lib/engine-components/ui/Image.js +116 -116
- package/lib/engine-components/ui/InputField.d.ts +42 -42
- package/lib/engine-components/ui/InputField.js +268 -268
- package/lib/engine-components/ui/Interfaces.d.ts +38 -38
- package/lib/engine-components/ui/Interfaces.js +12 -12
- package/lib/engine-components/ui/Layout.d.ts +84 -84
- package/lib/engine-components/ui/Layout.js +330 -330
- package/lib/engine-components/ui/Outline.d.ts +7 -7
- package/lib/engine-components/ui/Outline.js +20 -20
- package/lib/engine-components/ui/PointerEvents.d.ts +115 -115
- package/lib/engine-components/ui/PointerEvents.js +145 -145
- package/lib/engine-components/ui/RaycastUtils.d.ts +11 -11
- package/lib/engine-components/ui/RaycastUtils.js +67 -67
- package/lib/engine-components/ui/Raycaster.d.ts +30 -30
- package/lib/engine-components/ui/Raycaster.js +95 -95
- package/lib/engine-components/ui/RectTransform.d.ts +61 -61
- package/lib/engine-components/ui/RectTransform.js +356 -356
- package/lib/engine-components/ui/SpatialHtml.d.ts +8 -8
- package/lib/engine-components/ui/SpatialHtml.js +79 -79
- package/lib/engine-components/ui/Symbols.d.ts +1 -1
- package/lib/engine-components/ui/Symbols.js +1 -1
- package/lib/engine-components/ui/Text.d.ts +78 -78
- package/lib/engine-components/ui/Text.js +539 -539
- package/lib/engine-components/ui/Utils.d.ts +24 -24
- package/lib/engine-components/ui/Utils.js +90 -90
- package/lib/engine-components/ui/index.d.ts +1 -1
- package/lib/engine-components/ui/index.js +1 -1
- package/lib/engine-components/utils/EnvironmentScene.d.ts +5 -5
- package/lib/engine-components/utils/EnvironmentScene.js +205 -205
- package/lib/engine-components/utils/LookAt.d.ts +31 -31
- package/lib/engine-components/utils/LookAt.js +82 -82
- package/lib/engine-components/utils/OpenURL.d.ts +42 -42
- package/lib/engine-components/utils/OpenURL.js +119 -119
- package/lib/engine-components/webxr/Avatar.d.ts +25 -25
- package/lib/engine-components/webxr/Avatar.js +255 -255
- package/lib/engine-components/webxr/TeleportTarget.d.ts +7 -7
- package/lib/engine-components/webxr/TeleportTarget.js +7 -7
- package/lib/engine-components/webxr/WebARCameraBackground.d.ts +30 -30
- package/lib/engine-components/webxr/WebARCameraBackground.js +155 -155
- package/lib/engine-components/webxr/WebARSessionRoot.d.ts +98 -98
- package/lib/engine-components/webxr/WebARSessionRoot.js +770 -770
- package/lib/engine-components/webxr/WebXR.d.ts +232 -232
- package/lib/engine-components/webxr/WebXR.js +561 -561
- package/lib/engine-components/webxr/WebXRAvatar.d.ts +27 -27
- package/lib/engine-components/webxr/WebXRAvatar.js +44 -44
- package/lib/engine-components/webxr/WebXRImageTracking.d.ts +86 -86
- package/lib/engine-components/webxr/WebXRImageTracking.js +471 -471
- package/lib/engine-components/webxr/WebXRPlaneTracking.d.ts +92 -92
- package/lib/engine-components/webxr/WebXRPlaneTracking.js +500 -500
- package/lib/engine-components/webxr/WebXRRig.d.ts +32 -32
- package/lib/engine-components/webxr/WebXRRig.js +72 -72
- package/lib/engine-components/webxr/XRFlag.d.ts +38 -38
- package/lib/engine-components/webxr/XRFlag.js +139 -139
- package/lib/engine-components/webxr/controllers/XRControllerFollow.d.ts +47 -47
- package/lib/engine-components/webxr/controllers/XRControllerFollow.js +120 -120
- package/lib/engine-components/webxr/controllers/XRControllerModel.d.ts +43 -43
- package/lib/engine-components/webxr/controllers/XRControllerModel.js +352 -352
- package/lib/engine-components/webxr/controllers/XRControllerMovement.d.ts +78 -78
- package/lib/engine-components/webxr/controllers/XRControllerMovement.js +506 -506
- package/lib/engine-components/webxr/index.d.ts +3 -3
- package/lib/engine-components/webxr/index.js +3 -3
- package/lib/engine-components/webxr/types.d.ts +3 -3
- package/lib/engine-components/webxr/types.js +1 -1
- package/lib/engine-components-experimental/Presentation.d.ts +6 -6
- package/lib/engine-components-experimental/Presentation.js +9 -9
- package/lib/engine-components-experimental/api.d.ts +4 -4
- package/lib/engine-components-experimental/api.js +4 -4
- package/lib/engine-components-experimental/networking/PlayerSync.d.ts +156 -156
- package/lib/engine-components-experimental/networking/PlayerSync.js +377 -377
- package/lib/engine-schemes/api.d.ts +12 -12
- package/lib/engine-schemes/api.js +12 -12
- package/lib/engine-schemes/schemes.d.ts +7 -7
- package/lib/engine-schemes/schemes.js +19 -19
- package/lib/engine-schemes/synced-camera-model.d.ts +25 -25
- package/lib/engine-schemes/synced-camera-model.js +67 -67
- package/lib/engine-schemes/synced-transform-model.d.ts +31 -31
- package/lib/engine-schemes/synced-transform-model.js +66 -66
- package/lib/engine-schemes/transform.d.ts +12 -12
- package/lib/engine-schemes/transform.js +39 -39
- package/lib/engine-schemes/vec2.d.ts +10 -10
- package/lib/engine-schemes/vec2.js +25 -25
- package/lib/engine-schemes/vec3.d.ts +11 -11
- package/lib/engine-schemes/vec3.js +29 -29
- package/lib/engine-schemes/vec4.d.ts +12 -12
- package/lib/engine-schemes/vec4.js +33 -33
- package/lib/engine-schemes/vr-user-state-buffer.d.ts +37 -37
- package/lib/engine-schemes/vr-user-state-buffer.js +110 -110
- package/lib/include/three/EXT_mesh_gpu_instancing_exporter.d.ts +6 -6
- package/lib/include/three/EXT_mesh_gpu_instancing_exporter.js +45 -45
- package/lib/needle-engine.d.ts +7 -7
- package/lib/needle-engine.js +64 -64
- package/package.json +2 -2
- package/plugins/common/buildinfo.js +64 -64
- package/plugins/common/cloud.js +1 -1
- package/plugins/common/config.cjs +31 -31
- package/plugins/common/config.js +35 -35
- package/plugins/common/files.js +31 -31
- package/plugins/common/generator.js +10 -10
- package/plugins/common/license.js +452 -452
- package/plugins/common/npm.js +15 -15
- package/plugins/common/timers.js +7 -7
- package/plugins/common/version.js +37 -37
- package/plugins/gltf-packer.mjs +1 -1
- package/plugins/next/alias.cjs +39 -39
- package/plugins/next/license.cjs +24 -24
- package/plugins/next/meshbvhworker.cjs +18 -18
- package/plugins/next/next.js +141 -141
- package/plugins/types/index.d.ts +2 -2
- package/plugins/types/license.d.ts +24 -24
- package/plugins/types/needleConfig.d.ts +27 -27
- package/plugins/types/next.d.ts +2 -2
- package/plugins/types/userconfig.d.ts +120 -120
- package/plugins/types/vite.d.ts +13 -13
- package/plugins/types/webmanifest.d.ts +32 -32
- package/plugins/vite/alias.js +174 -174
- package/plugins/vite/asap.js +251 -251
- package/plugins/vite/build-pipeline.js +371 -371
- package/plugins/vite/build.js +19 -19
- package/plugins/vite/buildinfo.js +41 -41
- package/plugins/vite/config.js +106 -106
- package/plugins/vite/copyfiles.js +138 -138
- package/plugins/vite/defines.js +70 -70
- package/plugins/vite/dependencies.js +232 -232
- package/plugins/vite/dependency-watcher.js +237 -237
- package/plugins/vite/drop-client.js +76 -76
- package/plugins/vite/drop.js +87 -87
- package/plugins/vite/editor-connection.js +124 -124
- package/plugins/vite/facebook-instant-games.js +102 -102
- package/plugins/vite/gzip.js +5 -5
- package/plugins/vite/imports-logger.js +143 -143
- package/plugins/vite/index.js +143 -143
- package/plugins/vite/license.js +56 -56
- package/plugins/vite/local-files.js +440 -440
- package/plugins/vite/meta.js +163 -163
- package/plugins/vite/npm.js +7 -7
- package/plugins/vite/peer.js +29 -29
- package/plugins/vite/poster-client.js +73 -73
- package/plugins/vite/poster.js +79 -79
- package/plugins/vite/pwa.js +604 -604
- package/plugins/vite/reload-client.js +15 -15
- package/plugins/vite/reload.js +351 -351
- package/plugins/vite/server.js +66 -66
- package/plugins/vite/transform-codegen.js +55 -55
- package/plugins/vite/transform.js +31 -31
- package/plugins/vite/vite-4.4-hack.js +31 -31
- package/src/asap/needle-asap.ts +111 -111
- package/src/asap/sessiongranted.ts +75 -75
- package/src/asap/utils.ts +4 -4
- package/src/engine/analytics/index.ts +10 -10
- package/src/engine/analytics/lcp.ts +35 -35
- package/src/engine/api.ts +82 -82
- package/src/engine/assets/index.ts +59 -59
- package/src/engine/assets/static.js +5 -5
- package/src/engine/codegen/register_types.ts +300 -300
- package/src/engine/debug/debug.ts +51 -51
- package/src/engine/debug/debug_console.ts +333 -333
- package/src/engine/debug/debug_overlay.ts +332 -332
- package/src/engine/debug/debug_spatial_console.ts +429 -429
- package/src/engine/debug/index.ts +1 -1
- package/src/engine/engine_addressables.ts +680 -680
- package/src/engine/engine_animation.ts +145 -145
- package/src/engine/engine_application.ts +113 -113
- package/src/engine/engine_assetdatabase.ts +389 -389
- package/src/engine/engine_audio.ts +24 -24
- package/src/engine/engine_camera.ts +39 -39
- package/src/engine/engine_components.ts +366 -366
- package/src/engine/engine_components_internal.ts +40 -40
- package/src/engine/engine_constants.ts +52 -52
- package/src/engine/engine_context.ts +1823 -1823
- package/src/engine/engine_context_registry.ts +129 -129
- package/src/engine/engine_coroutine.ts +54 -54
- package/src/engine/engine_create_objects.ts +411 -411
- package/src/engine/engine_default_parameters.ts +3 -3
- package/src/engine/engine_editor-sync.ts +28 -28
- package/src/engine/engine_fileloader.js +9 -9
- package/src/engine/engine_gameobject.ts +712 -712
- package/src/engine/engine_generic_utils.js +13 -13
- package/src/engine/engine_gizmos.ts +577 -577
- package/src/engine/engine_gltf.ts +29 -29
- package/src/engine/engine_gltf_builtin_components.ts +403 -403
- package/src/engine/engine_hot_reload.ts +210 -210
- package/src/engine/engine_input.ts +1500 -1500
- package/src/engine/engine_input_utils.ts +23 -23
- package/src/engine/engine_instancing.ts +45 -45
- package/src/engine/engine_license.ts +386 -386
- package/src/engine/engine_lifecycle_api.ts +113 -113
- package/src/engine/engine_lifecycle_functions_internal.ts +193 -193
- package/src/engine/engine_lightdata.ts +117 -117
- package/src/engine/engine_loaders.callbacks.ts +136 -136
- package/src/engine/engine_loaders.gltf.ts +82 -82
- package/src/engine/engine_loaders.ts +378 -378
- package/src/engine/engine_lods.ts +168 -168
- package/src/engine/engine_mainloop_utils.ts +472 -472
- package/src/engine/engine_math.ts +282 -282
- package/src/engine/engine_modules.ts +83 -83
- package/src/engine/engine_networking.ts +862 -862
- package/src/engine/engine_networking_auto.ts +352 -352
- package/src/engine/engine_networking_blob.ts +275 -275
- package/src/engine/engine_networking_files.ts +217 -217
- package/src/engine/engine_networking_files_default_components.ts +58 -58
- package/src/engine/engine_networking_instantiate.ts +419 -419
- package/src/engine/engine_networking_peer.ts +159 -159
- package/src/engine/engine_networking_streams.ts +713 -713
- package/src/engine/engine_networking_types.ts +24 -24
- package/src/engine/engine_networking_utils.ts +23 -23
- package/src/engine/engine_networking_websocket.ts +2 -2
- package/src/engine/engine_patcher.ts +199 -199
- package/src/engine/engine_physics.ts +783 -783
- package/src/engine/engine_physics.types.ts +46 -46
- package/src/engine/engine_physics_rapier.ts +1577 -1577
- package/src/engine/engine_playerview.ts +80 -80
- package/src/engine/engine_scenelighting.ts +294 -294
- package/src/engine/engine_serialization.ts +2 -2
- package/src/engine/engine_serialization_builtin_serializer.ts +473 -473
- package/src/engine/engine_serialization_core.ts +720 -720
- package/src/engine/engine_serialization_decorator.ts +80 -80
- package/src/engine/engine_setup.ts +1 -1
- package/src/engine/engine_shaders.ts +267 -267
- package/src/engine/engine_shims.ts +32 -32
- package/src/engine/engine_test_utils.ts +109 -109
- package/src/engine/engine_texture.ts +82 -82
- package/src/engine/engine_three_utils.ts +925 -925
- package/src/engine/engine_time.ts +94 -94
- package/src/engine/engine_time_utils.ts +237 -237
- package/src/engine/engine_tonemapping.ts +208 -208
- package/src/engine/engine_types.ts +730 -730
- package/src/engine/engine_typestore.ts +63 -63
- package/src/engine/engine_util_decorator.ts +136 -136
- package/src/engine/engine_utils.ts +1115 -1115
- package/src/engine/engine_utils_format.ts +273 -273
- package/src/engine/engine_utils_screenshot.ts +708 -708
- package/src/engine/engine_utils_screenshot.xr.ts +103 -103
- package/src/engine/export/gltf/Writers.ts +34 -34
- package/src/engine/export/gltf/index.ts +158 -158
- package/src/engine/export/index.ts +2 -2
- package/src/engine/export/state.ts +19 -19
- package/src/engine/export/utils.ts +9 -9
- package/src/engine/extensions/EXT_texture_exr.ts +50 -50
- package/src/engine/extensions/NEEDLE_animator_controller_model.ts +195 -195
- package/src/engine/extensions/NEEDLE_components.ts +268 -268
- package/src/engine/extensions/NEEDLE_gameobject_data.ts +81 -81
- package/src/engine/extensions/NEEDLE_lighting_settings.ts +185 -185
- package/src/engine/extensions/NEEDLE_lightmaps.ts +119 -119
- package/src/engine/extensions/NEEDLE_persistent_assets.ts +76 -76
- package/src/engine/extensions/NEEDLE_render_objects.ts +209 -209
- package/src/engine/extensions/NEEDLE_techniques_webgl.ts +640 -640
- package/src/engine/extensions/extension_resolver.ts +4 -4
- package/src/engine/extensions/extension_utils.ts +166 -166
- package/src/engine/extensions/extensions.ts +140 -140
- package/src/engine/extensions/index.ts +5 -5
- package/src/engine/extensions/usage_tracker.ts +100 -100
- package/src/engine/js-extensions/Camera.ts +37 -37
- package/src/engine/js-extensions/ExtensionUtils.ts +85 -85
- package/src/engine/js-extensions/Layers.ts +23 -23
- package/src/engine/js-extensions/Object3D.ts +296 -296
- package/src/engine/js-extensions/RGBAColor.ts +126 -126
- package/src/engine/js-extensions/Vector.ts +18 -18
- package/src/engine/js-extensions/index.ts +4 -4
- package/src/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +125 -125
- package/src/engine/shaders/shaderData.ts +67 -67
- package/src/engine/tests/test_utils.ts +63 -63
- package/src/engine/webcomponents/WebXRButtons.ts +260 -260
- package/src/engine/webcomponents/api.ts +6 -6
- package/src/engine/webcomponents/buttons.ts +292 -292
- package/src/engine/webcomponents/fonts.ts +41 -41
- package/src/engine/webcomponents/icons.ts +57 -57
- package/src/engine/webcomponents/index.ts +1 -1
- package/src/engine/webcomponents/logo-element.ts +78 -78
- package/src/engine/webcomponents/needle menu/needle-menu-spatial.ts +573 -573
- package/src/engine/webcomponents/needle menu/needle-menu.ts +1118 -1118
- package/src/engine/webcomponents/needle-button.ts +181 -181
- package/src/engine/webcomponents/needle-engine.ar-overlay.ts +186 -186
- package/src/engine/webcomponents/needle-engine.attributes.ts +82 -82
- package/src/engine/webcomponents/needle-engine.extras.ts +16 -16
- package/src/engine/webcomponents/needle-engine.loading.ts +373 -373
- package/src/engine/webcomponents/needle-engine.ts +860 -860
- package/src/engine/xr/NeedleXRController.ts +1125 -1125
- package/src/engine/xr/NeedleXRSession.ts +1624 -1624
- package/src/engine/xr/NeedleXRSync.ts +220 -220
- package/src/engine/xr/SceneTransition.ts +78 -78
- package/src/engine/xr/TempXRContext.ts +216 -216
- package/src/engine/xr/XRRig.ts +9 -9
- package/src/engine/xr/api.ts +5 -5
- package/src/engine/xr/events.ts +102 -102
- package/src/engine/xr/internal.ts +34 -34
- package/src/engine/xr/usdz.ts +30 -30
- package/src/engine/xr/utils.ts +39 -39
- package/src/engine-components/AlignmentConstraint.ts +36 -36
- package/src/engine-components/Animation.ts +557 -557
- package/src/engine-components/AnimationCurve.ts +150 -150
- package/src/engine-components/AnimationUtils.ts +28 -28
- package/src/engine-components/AnimationUtilsAutoplay.ts +43 -43
- package/src/engine-components/Animator.ts +397 -397
- package/src/engine-components/AnimatorController.ts +1293 -1293
- package/src/engine-components/AudioListener.ts +92 -92
- package/src/engine-components/AudioSource.ts +644 -644
- package/src/engine-components/AvatarLoader.ts +263 -263
- package/src/engine-components/AxesHelper.ts +59 -59
- package/src/engine-components/BasicIKConstraint.ts +54 -54
- package/src/engine-components/BoxCollider.ts +1 -1
- package/src/engine-components/BoxHelperComponent.ts +114 -114
- package/src/engine-components/Camera.ts +719 -719
- package/src/engine-components/CameraUtils.ts +136 -136
- package/src/engine-components/CharacterController.ts +253 -253
- package/src/engine-components/Collider.ts +374 -374
- package/src/engine-components/Component.ts +1297 -1297
- package/src/engine-components/ContactShadows.ts +506 -506
- package/src/engine-components/DeleteBox.ts +62 -62
- package/src/engine-components/DeviceFlag.ts +46 -46
- package/src/engine-components/DragControls.ts +1623 -1623
- package/src/engine-components/DropListener.ts +713 -713
- package/src/engine-components/Duplicatable.ts +198 -198
- package/src/engine-components/EventList.ts +266 -266
- package/src/engine-components/EventTrigger.ts +74 -74
- package/src/engine-components/EventType.ts +22 -22
- package/src/engine-components/Fog.ts +60 -60
- package/src/engine-components/Gizmos.ts +56 -56
- package/src/engine-components/GridHelper.ts +48 -48
- package/src/engine-components/GroundProjection.ts +356 -356
- package/src/engine-components/Interactable.ts +14 -14
- package/src/engine-components/Joints.ts +52 -52
- package/src/engine-components/LODGroup.ts +153 -153
- package/src/engine-components/Light.ts +558 -558
- package/src/engine-components/LookAtConstraint.ts +25 -25
- package/src/engine-components/NeedleMenu.ts +84 -84
- package/src/engine-components/NestedGltf.ts +86 -86
- package/src/engine-components/Networking.ts +114 -114
- package/src/engine-components/OffsetConstraint.ts +60 -60
- package/src/engine-components/OrbitControls.ts +1074 -1074
- package/src/engine-components/PlayerColor.ts +103 -103
- package/src/engine-components/ReflectionProbe.ts +220 -220
- package/src/engine-components/Renderer.ts +903 -903
- package/src/engine-components/RendererInstancing.ts +855 -855
- package/src/engine-components/RendererLightmap.ts +198 -198
- package/src/engine-components/RigidBody.ts +526 -526
- package/src/engine-components/SceneSwitcher.ts +1030 -1030
- package/src/engine-components/ScreenCapture.ts +592 -592
- package/src/engine-components/ShadowCatcher.ts +172 -172
- package/src/engine-components/Skybox.ts +475 -475
- package/src/engine-components/SmoothFollow.ts +76 -76
- package/src/engine-components/SpatialTrigger.ts +229 -229
- package/src/engine-components/SpectatorCamera.ts +787 -787
- package/src/engine-components/SphereCollider.ts +1 -1
- package/src/engine-components/SpriteRenderer.ts +468 -468
- package/src/engine-components/SyncedCamera.ts +220 -220
- package/src/engine-components/SyncedRoom.ts +380 -380
- package/src/engine-components/SyncedTransform.ts +383 -383
- package/src/engine-components/TestRunner.ts +118 -118
- package/src/engine-components/TransformGizmo.ts +219 -219
- package/src/engine-components/VideoPlayer.ts +1025 -1025
- package/src/engine-components/Voip.ts +363 -363
- package/src/engine-components/api.ts +60 -60
- package/src/engine-components/avatar/AvatarBlink_Simple.ts +69 -69
- package/src/engine-components/avatar/AvatarEyeLook_Rotation.ts +63 -63
- package/src/engine-components/avatar/Avatar_Brain_LookAt.ts +139 -139
- package/src/engine-components/avatar/Avatar_MouthShapes.ts +83 -83
- package/src/engine-components/avatar/Avatar_MustacheShake.ts +31 -31
- package/src/engine-components/codegen/components.ts +217 -217
- package/src/engine-components/debug/LogStats.ts +21 -21
- package/src/engine-components/export/gltf/GltfExport.ts +265 -265
- package/src/engine-components/export/usdz/Extension.ts +24 -24
- package/src/engine-components/export/usdz/ThreeUSDZExporter.ts +2426 -2426
- package/src/engine-components/export/usdz/USDZExporter.ts +705 -705
- package/src/engine-components/export/usdz/extensions/Animation.ts +1204 -1204
- package/src/engine-components/export/usdz/extensions/DocumentExtension.ts +9 -9
- package/src/engine-components/export/usdz/extensions/NodeMaterialConverter.ts +532 -532
- package/src/engine-components/export/usdz/extensions/USDZText.ts +240 -240
- package/src/engine-components/export/usdz/extensions/USDZUI.ts +189 -189
- package/src/engine-components/export/usdz/extensions/behavior/Actions.ts +99 -99
- package/src/engine-components/export/usdz/extensions/behavior/AudioExtension.ts +102 -102
- package/src/engine-components/export/usdz/extensions/behavior/Behaviour.ts +320 -320
- package/src/engine-components/export/usdz/extensions/behavior/BehaviourComponents.ts +1225 -1225
- package/src/engine-components/export/usdz/extensions/behavior/BehavioursBuilder.ts +646 -646
- package/src/engine-components/export/usdz/extensions/behavior/PhysicsExtension.ts +132 -132
- package/src/engine-components/export/usdz/index.ts +2 -2
- package/src/engine-components/export/usdz/utils/animationutils.ts +191 -191
- package/src/engine-components/export/usdz/utils/quicklook.ts +50 -50
- package/src/engine-components/particlesystem/ParticleSystem.ts +1287 -1287
- package/src/engine-components/particlesystem/ParticleSystemModules.ts +1765 -1765
- package/src/engine-components/particlesystem/ParticleSystemSubEmitter.ts +111 -111
- package/src/engine-components/particlesystem/api.ts +1 -1
- package/src/engine-components/postprocessing/Effects/Antialiasing.ts +57 -57
- package/src/engine-components/postprocessing/Effects/BloomEffect.ts +116 -116
- package/src/engine-components/postprocessing/Effects/ChromaticAberration.ts +37 -37
- package/src/engine-components/postprocessing/Effects/ColorAdjustments.ts +106 -106
- package/src/engine-components/postprocessing/Effects/DepthOfField.ts +103 -103
- package/src/engine-components/postprocessing/Effects/EffectWrapper.ts +25 -25
- package/src/engine-components/postprocessing/Effects/Pixelation.ts +32 -32
- package/src/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusion.ts +90 -90
- package/src/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusionN8.ts +192 -192
- package/src/engine-components/postprocessing/Effects/Sharpening.ts +143 -143
- package/src/engine-components/postprocessing/Effects/TiltShiftEffect.ts +61 -61
- package/src/engine-components/postprocessing/Effects/Tonemapping.ts +103 -103
- package/src/engine-components/postprocessing/Effects/Tonemapping.utils.ts +60 -60
- package/src/engine-components/postprocessing/Effects/Vignette.ts +59 -59
- package/src/engine-components/postprocessing/PostProcessingEffect.ts +192 -192
- package/src/engine-components/postprocessing/PostProcessingHandler.ts +560 -560
- package/src/engine-components/postprocessing/Volume.ts +426 -426
- package/src/engine-components/postprocessing/VolumeParameter.ts +158 -158
- package/src/engine-components/postprocessing/VolumeProfile.ts +61 -61
- package/src/engine-components/postprocessing/index.ts +5 -5
- package/src/engine-components/postprocessing/utils.ts +154 -154
- package/src/engine-components/timeline/PlayableDirector.ts +722 -722
- package/src/engine-components/timeline/SignalAsset.ts +144 -144
- package/src/engine-components/timeline/TimelineModels.ts +92 -92
- package/src/engine-components/timeline/TimelineTracks.ts +967 -967
- package/src/engine-components/timeline/index.ts +3 -3
- package/src/engine-components/ui/BaseUIComponent.ts +203 -203
- package/src/engine-components/ui/Button.ts +307 -307
- package/src/engine-components/ui/Canvas.ts +419 -419
- package/src/engine-components/ui/CanvasGroup.ts +54 -54
- package/src/engine-components/ui/EventSystem.ts +854 -854
- package/src/engine-components/ui/Graphic.ts +275 -275
- package/src/engine-components/ui/Image.ts +112 -112
- package/src/engine-components/ui/InputField.ts +321 -321
- package/src/engine-components/ui/Interfaces.ts +57 -57
- package/src/engine-components/ui/Layout.ts +334 -334
- package/src/engine-components/ui/Outline.ts +13 -13
- package/src/engine-components/ui/PointerEvents.ts +206 -206
- package/src/engine-components/ui/RaycastUtils.ts +69 -69
- package/src/engine-components/ui/Raycaster.ts +102 -102
- package/src/engine-components/ui/RectTransform.ts +375 -375
- package/src/engine-components/ui/SpatialHtml.ts +79 -79
- package/src/engine-components/ui/Symbols.ts +1 -1
- package/src/engine-components/ui/Text.ts +578 -578
- package/src/engine-components/ui/Utils.ts +113 -113
- package/src/engine-components/utils/EnvironmentScene.ts +245 -245
- package/src/engine-components/utils/LookAt.ts +88 -88
- package/src/engine-components/utils/OpenURL.ts +114 -114
- package/src/engine-components/webxr/Avatar.ts +265 -265
- package/src/engine-components/webxr/TeleportTarget.ts +9 -9
- package/src/engine-components/webxr/WebARCameraBackground.ts +175 -175
- package/src/engine-components/webxr/WebARSessionRoot.ts +880 -880
- package/src/engine-components/webxr/WebXR.ts +585 -585
- package/src/engine-components/webxr/WebXRAvatar.ts +66 -66
- package/src/engine-components/webxr/WebXRImageTracking.ts +519 -519
- package/src/engine-components/webxr/WebXRPlaneTracking.ts +570 -570
- package/src/engine-components/webxr/WebXRRig.ts +77 -77
- package/src/engine-components/webxr/XRFlag.ts +147 -147
- package/src/engine-components/webxr/controllers/XRControllerFollow.ts +118 -118
- package/src/engine-components/webxr/controllers/XRControllerModel.ts +373 -373
- package/src/engine-components/webxr/controllers/XRControllerMovement.ts +550 -550
- package/src/engine-components/webxr/index.ts +2 -2
- package/src/engine-components/webxr/types.ts +3 -3
- package/src/engine-components-experimental/Presentation.ts +12 -12
- package/src/engine-components-experimental/api.ts +4 -4
- package/src/engine-components-experimental/networking/PlayerSync.ts +401 -401
- package/src/engine-schemes/COMPILE_SCHEMES.bat +3 -3
- package/src/engine-schemes/COMPILE_TS.bat +11 -11
- package/src/engine-schemes/README.md +1 -1
- package/src/engine-schemes/api.ts +12 -12
- package/src/engine-schemes/schemes.ts +28 -28
- package/src/engine-schemes/synced-camera-model.ts +92 -92
- package/src/engine-schemes/synced-transform-model.ts +90 -90
- package/src/engine-schemes/syncedCamera.fbs +10 -10
- package/src/engine-schemes/transform.ts +50 -50
- package/src/engine-schemes/transforms.fbs +25 -25
- package/src/engine-schemes/vec.fbs +19 -19
- package/src/engine-schemes/vec2.ts +33 -33
- package/src/engine-schemes/vec3.ts +38 -38
- package/src/engine-schemes/vec4.ts +43 -43
- package/src/engine-schemes/vr-user-state-buffer.ts +145 -145
- package/src/engine-schemes/vrUserStateBuffer.fbs +17 -17
- package/src/include/draco/draco_decoder.js +34 -34
- package/src/include/ktx2/basis_transcoder.js +21 -21
- package/src/include/needle/arial-msdf.json +1471 -1471
- package/src/include/three/DragControls.js +231 -231
- package/src/include/three/EXT_mesh_gpu_instancing_exporter.js +66 -66
- package/src/needle-engine.ts +70 -70
- package/dist/generateMeshBVH.worker-Cdfpaq5W.js +0 -25
- package/src/engine-schemes/dist/api.js +0 -17
- package/src/engine-schemes/dist/api.js.meta +0 -7
- package/src/engine-schemes/dist/schemes.js +0 -25
- package/src/engine-schemes/dist/schemes.js.meta +0 -7
- package/src/engine-schemes/dist/synced-camera-model.js +0 -74
- package/src/engine-schemes/dist/synced-camera-model.js.meta +0 -7
- package/src/engine-schemes/dist/synced-transform-model.js +0 -73
- package/src/engine-schemes/dist/synced-transform-model.js.meta +0 -7
- package/src/engine-schemes/dist/transform.js +0 -46
- package/src/engine-schemes/dist/transform.js.meta +0 -7
- package/src/engine-schemes/dist/vec2.js +0 -32
- package/src/engine-schemes/dist/vec2.js.meta +0 -7
- package/src/engine-schemes/dist/vec3.js +0 -36
- package/src/engine-schemes/dist/vec3.js.meta +0 -7
- package/src/engine-schemes/dist/vec4.js +0 -40
- package/src/engine-schemes/dist/vec4.js.meta +0 -7
- package/src/engine-schemes/dist/vr-user-state-buffer.js +0 -110
- package/src/engine-schemes/dist/vr-user-state-buffer.js.meta +0 -7
|
@@ -1,880 +1,880 @@
|
|
|
1
|
-
import { AxesHelper, DoubleSide, Matrix4, Mesh, MeshBasicMaterial, Object3D, Plane, Raycaster, RingGeometry, Scene, Vector3 } from "three";
|
|
2
|
-
|
|
3
|
-
import { isDevEnvironment, showBalloonWarning } from "../../engine/debug/index.js";
|
|
4
|
-
import { AssetReference } from "../../engine/engine_addressables.js";
|
|
5
|
-
import { Context } from "../../engine/engine_context.js";
|
|
6
|
-
import { destroy, instantiate } from "../../engine/engine_gameobject.js";
|
|
7
|
-
import { InputEventQueue, NEPointerEvent } from "../../engine/engine_input.js";
|
|
8
|
-
import { getBoundingBox, getTempVector } from "../../engine/engine_three_utils.js";
|
|
9
|
-
import type { IComponent, IGameObject } from "../../engine/engine_types.js";
|
|
10
|
-
import { DeviceUtilities, getParam } from "../../engine/engine_utils.js";
|
|
11
|
-
import { NeedleXRController, type NeedleXREventArgs, type NeedleXRHitTestResult, NeedleXRSession } from "../../engine/engine_xr.js";
|
|
12
|
-
import { Behaviour, GameObject } from "../Component.js";
|
|
13
|
-
|
|
14
|
-
// https://github.com/takahirox/takahirox.github.io/blob/master/js.mmdeditor/examples/js/controls/DeviceOrientationControls.js
|
|
15
|
-
|
|
16
|
-
const debug = getParam("debugwebxr");
|
|
17
|
-
|
|
18
|
-
const invertForwardMatrix = new Matrix4().makeRotationY(Math.PI);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* The WebARSessionRoot is the root object for a WebAR session and used to place the scene in AR.
|
|
23
|
-
* It is also responsible for scaling the user in AR and optionally creating a XR anchor for the scene placement.
|
|
24
|
-
* @example
|
|
25
|
-
* ```ts
|
|
26
|
-
* WebARSessionRoot.onPlaced((args) => {
|
|
27
|
-
* console.log("Scene has been placed in AR");
|
|
28
|
-
* });
|
|
29
|
-
* ```
|
|
30
|
-
*
|
|
31
|
-
* @category XR
|
|
32
|
-
* @group Components
|
|
33
|
-
*/
|
|
34
|
-
export class WebARSessionRoot extends Behaviour {
|
|
35
|
-
|
|
36
|
-
private static _eventListeners: { [key: string]: Array<(args: { instance: WebARSessionRoot }) => void> } = {};
|
|
37
|
-
/**
|
|
38
|
-
* Event that is called when the scene has been placed in AR.
|
|
39
|
-
* @param cb the callback that is called when the scene has been placed
|
|
40
|
-
* @returns a function to remove the event listener
|
|
41
|
-
*/
|
|
42
|
-
static onPlaced(cb: (args: { instance: WebARSessionRoot }) => void) {
|
|
43
|
-
const event = "placed";
|
|
44
|
-
if (!this._eventListeners[event]) this._eventListeners[event] = [];
|
|
45
|
-
this._eventListeners[event].push(cb);
|
|
46
|
-
return () => {
|
|
47
|
-
const index = this._eventListeners[event].indexOf(cb);
|
|
48
|
-
if (index >= 0) this._eventListeners[event].splice(index, 1);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
private static _hasPlaced: boolean = false;
|
|
53
|
-
/**
|
|
54
|
-
* @returns true if the scene has been placed in AR by the user or automatic placement
|
|
55
|
-
*/
|
|
56
|
-
static get hasPlaced(): boolean {
|
|
57
|
-
return this._hasPlaced;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
/** The scale of the user in AR.
|
|
62
|
-
* **NOTE**: a large value makes the scene appear smaller
|
|
63
|
-
* @default 1
|
|
64
|
-
*/
|
|
65
|
-
get arScale(): number {
|
|
66
|
-
return this._arScale;
|
|
67
|
-
}
|
|
68
|
-
set arScale(val: number) {
|
|
69
|
-
this._arScale = Math.max(0.000001, val);
|
|
70
|
-
this.onSetScale();
|
|
71
|
-
}
|
|
72
|
-
private _arScale: number = 1;
|
|
73
|
-
|
|
74
|
-
/** When enabled the placed scene forward direction will towards the XRRig
|
|
75
|
-
* @deprecated
|
|
76
|
-
* @default false
|
|
77
|
-
*/
|
|
78
|
-
invertForward: boolean = false;
|
|
79
|
-
|
|
80
|
-
/** When assigned this asset will be loaded and visualize the placement while in AR
|
|
81
|
-
* @default null
|
|
82
|
-
*/
|
|
83
|
-
customReticle?: AssetReference;
|
|
84
|
-
|
|
85
|
-
/** Enable touch transform to translate, rotate and scale the scene in AR with multitouch
|
|
86
|
-
* @default true
|
|
87
|
-
*/
|
|
88
|
-
arTouchTransform: boolean = true;
|
|
89
|
-
|
|
90
|
-
/** When enabled the scene will be placed automatically when a point in the real world is found
|
|
91
|
-
* @default false
|
|
92
|
-
*/
|
|
93
|
-
autoPlace: boolean = false;
|
|
94
|
-
|
|
95
|
-
/** When enabled the scene center will be automatically calculated from the content in the scene */
|
|
96
|
-
autoCenter: boolean = false;
|
|
97
|
-
|
|
98
|
-
/** Experimental: When enabled we will create a XR anchor for the scene placement
|
|
99
|
-
* and make sure the scene is at that anchored point during a XR session
|
|
100
|
-
* @default false
|
|
101
|
-
**/
|
|
102
|
-
useXRAnchor: boolean = false;
|
|
103
|
-
|
|
104
|
-
/** true if we're currently placing the scene */
|
|
105
|
-
private _isPlacing = true;
|
|
106
|
-
|
|
107
|
-
/** This is the world matrix of the ar session root when entering webxr
|
|
108
|
-
* it is applied when the scene has been placed (e.g. if the session root is x:10, z:10 we want this position to be the center of the scene)
|
|
109
|
-
*/
|
|
110
|
-
private readonly _startOffset: Matrix4 = new Matrix4();
|
|
111
|
-
|
|
112
|
-
private _createdPlacementObject: Object3D | null = null;
|
|
113
|
-
private readonly _reparentedComponents: Array<{ comp: IComponent, originalObject: IGameObject }> = [];
|
|
114
|
-
|
|
115
|
-
// move objects into a temporary scene while placing (which is not rendered) so that the components won't be disabled during this process
|
|
116
|
-
// e.g. we want the avatar to still be updated while placing
|
|
117
|
-
// another possibly solution would be to ensure from this component that the Rig is *also* not disabled while placing
|
|
118
|
-
private readonly _placementScene: Scene = new Scene();
|
|
119
|
-
|
|
120
|
-
/** the reticles used for placement */
|
|
121
|
-
private readonly _reticle: IGameObject[] = [];
|
|
122
|
-
/** needs to be in sync with the reticles */
|
|
123
|
-
private readonly _hits: XRHitTestResult[] = [];
|
|
124
|
-
|
|
125
|
-
private _placementStartTime: number = -1;
|
|
126
|
-
private _rigPlacementMatrix?: Matrix4;
|
|
127
|
-
/** if useAnchor is enabled this is the anchor we have created on placing the scene using the placement hit */
|
|
128
|
-
private _anchor: XRAnchor | null = null;
|
|
129
|
-
/** user input is used for ar touch transform */
|
|
130
|
-
private userInput?: WebXRSessionRootUserInput;
|
|
131
|
-
|
|
132
|
-
onEnable(): void {
|
|
133
|
-
this.customReticle?.preload();
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
supportsXR(mode: XRSessionMode): boolean {
|
|
137
|
-
return mode === "immersive-ar";
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
onEnterXR(_args: NeedleXREventArgs): void {
|
|
141
|
-
if (debug) console.log("ENTER WEBXR: SessionRoot start...");
|
|
142
|
-
|
|
143
|
-
this._anchor = null;
|
|
144
|
-
WebARSessionRoot._hasPlaced = false;
|
|
145
|
-
|
|
146
|
-
// if (_args.xr.session.enabledFeatures?.includes("image-tracking")) {
|
|
147
|
-
// console.warn("Image tracking is enabled - will not place scene");
|
|
148
|
-
// return;
|
|
149
|
-
// }
|
|
150
|
-
|
|
151
|
-
// save the transform of the session root in the scene to apply it when placing the scene
|
|
152
|
-
this.gameObject.updateMatrixWorld();
|
|
153
|
-
this._startOffset.copy(this.gameObject.matrixWorld);
|
|
154
|
-
|
|
155
|
-
// create a new root object for the session placement scripts
|
|
156
|
-
// and move all the children in the scene in a temporary scene that is not rendered
|
|
157
|
-
const rootObject = new Object3D();
|
|
158
|
-
this._createdPlacementObject = rootObject;
|
|
159
|
-
rootObject.name = "AR Session Root";
|
|
160
|
-
this._placementScene.name = "AR Placement Scene";
|
|
161
|
-
this._placementScene.children.length = 0;
|
|
162
|
-
for (let i = this.context.scene.children.length - 1; i >= 0; i--) {
|
|
163
|
-
const ch = this.context.scene.children[i];
|
|
164
|
-
this._placementScene.add(ch);
|
|
165
|
-
}
|
|
166
|
-
this.context.scene.add(rootObject);
|
|
167
|
-
|
|
168
|
-
if (this.autoCenter) {
|
|
169
|
-
const bounds = getBoundingBox(this._placementScene.children);
|
|
170
|
-
const center = bounds.getCenter(new Vector3());
|
|
171
|
-
const size = bounds.getSize(new Vector3());
|
|
172
|
-
const matrix = new Matrix4();
|
|
173
|
-
matrix.makeTranslation(center.x, center.y - size.y * .5, center.z);
|
|
174
|
-
this._startOffset.multiply(matrix);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// reparent components
|
|
178
|
-
// save which gameobject the sessionroot component was previously attached to
|
|
179
|
-
this._reparentedComponents.length = 0;
|
|
180
|
-
this._reparentedComponents.push({ comp: this, originalObject: this.gameObject });
|
|
181
|
-
GameObject.addComponent(rootObject, this);
|
|
182
|
-
// const webXR = GameObject.findObjectOfType(WebXR2);
|
|
183
|
-
// if (webXR) {
|
|
184
|
-
// this._reparentedComponents.push({ comp: webXR, originalObject: webXR.gameObject });
|
|
185
|
-
// GameObject.addComponent(rootObject, webXR);
|
|
186
|
-
// const playerSync = GameObject.findObjectOfType(XRFlag);
|
|
187
|
-
// }
|
|
188
|
-
|
|
189
|
-
// recreate the reticle every time we enter AR
|
|
190
|
-
for (const ret of this._reticle) {
|
|
191
|
-
destroy(ret);
|
|
192
|
-
}
|
|
193
|
-
this._reticle.length = 0;
|
|
194
|
-
this._isPlacing = true;
|
|
195
|
-
// we want to receive pointer events EARLY and prevent interaction with other objects while placing by stopping the event propagation
|
|
196
|
-
this.context.input.addEventListener("pointerup", this.onPlaceScene, { queue: InputEventQueue.Early });
|
|
197
|
-
}
|
|
198
|
-
onLeaveXR() {
|
|
199
|
-
// TODO: WebARSessionRoot doesnt work when we enter passthrough and leave XR without having placed the session!!!
|
|
200
|
-
this.context.input.removeEventListener("pointerup", this.onPlaceScene, { queue: InputEventQueue.Early });
|
|
201
|
-
this.onRevertSceneChanges();
|
|
202
|
-
// this._anchor?.delete();
|
|
203
|
-
this._anchor = null;
|
|
204
|
-
WebARSessionRoot._hasPlaced = false;
|
|
205
|
-
this._rigPlacementMatrix = undefined;
|
|
206
|
-
}
|
|
207
|
-
onUpdateXR(args: NeedleXREventArgs): void {
|
|
208
|
-
|
|
209
|
-
// disable session placement while images are being tracked
|
|
210
|
-
if (args.xr.isTrackingImages) {
|
|
211
|
-
for (const ret of this._reticle)
|
|
212
|
-
ret.visible = false;
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
if (this._isPlacing) {
|
|
217
|
-
const rigObject = args.xr.rig?.gameObject;
|
|
218
|
-
// the rig should be parented to the scene while placing
|
|
219
|
-
// since the camera is always parented to the rig this ensures that the camera is always rendering
|
|
220
|
-
if (rigObject && rigObject.parent !== this.context.scene) {
|
|
221
|
-
this.context.scene.add(rigObject);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// in pass through mode we want to place the scene using an XR controller
|
|
225
|
-
let controllersDidHit = false;
|
|
226
|
-
// when auto placing we just use the user's view
|
|
227
|
-
if (args.xr.isPassThrough && args.xr.controllers.length > 0 && !this.autoPlace) {
|
|
228
|
-
for (const ctrl of args.xr.controllers) {
|
|
229
|
-
// with this we can only place with the left / first controller right now
|
|
230
|
-
// we also only have one reticle... this should probably be refactored a bit so we can have multiple reticles
|
|
231
|
-
// and then place at the reticle for which the user clicked the place button
|
|
232
|
-
const hit = ctrl.getHitTest();
|
|
233
|
-
if (hit) {
|
|
234
|
-
controllersDidHit = true;
|
|
235
|
-
this.updateReticleAndHits(args.xr, ctrl.index, hit, args.xr.rigScale);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
// in screen AR mode we use "camera" hit testing (or when using the simulator where controller hit testing is not supported)
|
|
240
|
-
if (!controllersDidHit) {
|
|
241
|
-
const hit = args.xr.getHitTest();
|
|
242
|
-
if (hit) {
|
|
243
|
-
this.updateReticleAndHits(args.xr, 0, hit, args.xr.rigScale);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
}
|
|
248
|
-
else {
|
|
249
|
-
// Update anchors, if any
|
|
250
|
-
if (this._anchor && args.xr.referenceSpace) {
|
|
251
|
-
const pose = args.xr.frame.getPose(this._anchor.anchorSpace, args.xr.referenceSpace);
|
|
252
|
-
if (pose && this.context.time.frame % 20 === 0) {
|
|
253
|
-
// apply the anchor pose to one of the reticles
|
|
254
|
-
const converted = args.xr.convertSpace(pose.transform);
|
|
255
|
-
const reticle = this._reticle[0];
|
|
256
|
-
if (reticle) {
|
|
257
|
-
reticle.position.copy(converted.position);
|
|
258
|
-
reticle.quaternion.copy(converted.quaternion);
|
|
259
|
-
this.onApplyPose(reticle);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Scene has been placed
|
|
265
|
-
if (this.arTouchTransform) {
|
|
266
|
-
if (!this.userInput) this.userInput = new WebXRSessionRootUserInput(this.context);
|
|
267
|
-
this.userInput?.enable();
|
|
268
|
-
}
|
|
269
|
-
else this.userInput?.disable();
|
|
270
|
-
if (this.arTouchTransform && this.userInput?.hasChanged) {
|
|
271
|
-
if (args.xr.rig) {
|
|
272
|
-
const rig = args.xr.rig.gameObject;
|
|
273
|
-
this.userInput.applyMatrixTo(rig.matrix, true);
|
|
274
|
-
rig.matrix.decompose(rig.position, rig.quaternion, rig.scale);
|
|
275
|
-
// if the rig is scaled large we want the drag touch to be faster
|
|
276
|
-
this.userInput.factor = rig.scale.x;
|
|
277
|
-
}
|
|
278
|
-
this.userInput.reset();
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
private updateReticleAndHits(_xr: NeedleXRSession, i: number, hit: NeedleXRHitTestResult, scale: number) {
|
|
284
|
-
// save the hit test
|
|
285
|
-
this._hits[i] = hit.hit;
|
|
286
|
-
let reticle = this._reticle[i];
|
|
287
|
-
if (!reticle) {
|
|
288
|
-
if (this.customReticle) {
|
|
289
|
-
if (this.customReticle.asset) {
|
|
290
|
-
reticle = instantiate(this.customReticle.asset);
|
|
291
|
-
}
|
|
292
|
-
else {
|
|
293
|
-
this.customReticle.loadAssetAsync();
|
|
294
|
-
return;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
else {
|
|
298
|
-
reticle = new Mesh(
|
|
299
|
-
new RingGeometry(0.07, 0.09, 32).rotateX(- Math.PI / 2),
|
|
300
|
-
new MeshBasicMaterial({ side: DoubleSide, depthTest: false, depthWrite: false, transparent: true, opacity: 1, color: 0xeeeeee })
|
|
301
|
-
) as any as IGameObject;
|
|
302
|
-
reticle.name = "AR Placement Reticle";
|
|
303
|
-
}
|
|
304
|
-
if (debug) {
|
|
305
|
-
const axes = new AxesHelper(1);
|
|
306
|
-
axes.position.y += .01;
|
|
307
|
-
reticle.add(axes);
|
|
308
|
-
}
|
|
309
|
-
this._reticle[i] = reticle;
|
|
310
|
-
reticle.matrixAutoUpdate = false;
|
|
311
|
-
reticle.visible = false;
|
|
312
|
-
}
|
|
313
|
-
reticle["lastPos"] = reticle["lastPos"] || hit.position.clone();
|
|
314
|
-
reticle["lastQuat"] = reticle["lastQuat"] || hit.quaternion.clone();
|
|
315
|
-
// reticle["targetPos"] = reticle["targetPos"] || hit.position.clone();
|
|
316
|
-
// reticle["targetQuat"] = reticle["targetQuat"] || hit.quaternion.clone();
|
|
317
|
-
|
|
318
|
-
// TODO we likely want the reticle itself to be placed _exactly_ and then the visuals being lerped,
|
|
319
|
-
// Right now this leads to a "rotation glitch" when going from a horizontal to a vertical surface
|
|
320
|
-
reticle.position.copy(reticle["lastPos"].lerp(hit.position, this.context.time.deltaTime / .1));
|
|
321
|
-
reticle["lastPos"].copy(reticle.position);
|
|
322
|
-
reticle.quaternion.copy(reticle["lastQuat"].slerp(hit.quaternion, this.context.time.deltaTime / .05));
|
|
323
|
-
reticle["lastQuat"].copy(reticle.quaternion);
|
|
324
|
-
|
|
325
|
-
// TODO make sure original reticle asset scale is respected, or document it should be uniformly scaled
|
|
326
|
-
// scale *= this.customReticle?.asset?.scale?.x || 1;
|
|
327
|
-
reticle.scale.set(scale, scale, scale);
|
|
328
|
-
|
|
329
|
-
// if (this.invertForward) {
|
|
330
|
-
// reticle.rotateY(Math.PI);
|
|
331
|
-
// }
|
|
332
|
-
|
|
333
|
-
// Workaround: For a custom reticle we apply the view based transform during placement preview
|
|
334
|
-
// See NE-4161 for context
|
|
335
|
-
if (this.customReticle)
|
|
336
|
-
this.applyViewBasedTransform(reticle);
|
|
337
|
-
|
|
338
|
-
reticle.updateMatrix();
|
|
339
|
-
reticle.visible = true;
|
|
340
|
-
if (reticle.parent !== this.context.scene)
|
|
341
|
-
this.context.scene.add(reticle);
|
|
342
|
-
|
|
343
|
-
if (this._placementStartTime < 0) {
|
|
344
|
-
this._placementStartTime = this.context.time.realtimeSinceStartup;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
if (this.autoPlace) {
|
|
348
|
-
this.upVec.set(0, 1, 0).applyQuaternion(reticle.quaternion);
|
|
349
|
-
const isUp = this.upVec.dot(getTempVector(0, 1, 0)) > 0.9;
|
|
350
|
-
if (isUp) {
|
|
351
|
-
// We want the reticle to be at a suitable spot for a moment before we place the scene (not place it immediately)
|
|
352
|
-
let autoplace_timer = reticle["autoplace:timer"] || 0;
|
|
353
|
-
if (autoplace_timer >= 1) {
|
|
354
|
-
reticle.visible = false;
|
|
355
|
-
this.onPlaceScene(null);
|
|
356
|
-
}
|
|
357
|
-
else {
|
|
358
|
-
autoplace_timer += this.context.time.deltaTime;
|
|
359
|
-
reticle["autoplace:timer"] = autoplace_timer;
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
else {
|
|
363
|
-
reticle["autoplace:timer"] = 0;
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
private onPlaceScene = (evt: NEPointerEvent | null) => {
|
|
369
|
-
if (this._isPlacing == false) return;
|
|
370
|
-
if (evt?.used) return;
|
|
371
|
-
|
|
372
|
-
let reticle: IGameObject | undefined = this._reticle[0];
|
|
373
|
-
|
|
374
|
-
if (!reticle) {
|
|
375
|
-
console.warn("No reticle to place...");
|
|
376
|
-
return;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
if (!reticle.visible && !this.autoPlace) {
|
|
380
|
-
console.warn("Reticle is not visible (can not place)");
|
|
381
|
-
return;
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
if (NeedleXRSession.active?.isTrackingImages) {
|
|
385
|
-
console.warn("Scene Placement is disabled while images are being tracked");
|
|
386
|
-
return;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
let hit = this._hits[0];
|
|
390
|
-
|
|
391
|
-
if (evt && evt.origin instanceof NeedleXRController) {
|
|
392
|
-
// until we can use hit testing for both controllers and have multple reticles we only allow placement with the first controller
|
|
393
|
-
const controllerReticle = this._reticle[evt.origin.index];
|
|
394
|
-
if (controllerReticle) {
|
|
395
|
-
reticle = controllerReticle;
|
|
396
|
-
hit = this._hits[evt.origin.index];
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
// if we place the scene we don't want this event to be propagated to any sub-objects (via the EventSystem) anymore and trigger e.g. a click on objects for the "place tap" event
|
|
401
|
-
if (evt) {
|
|
402
|
-
evt.stopImmediatePropagation();
|
|
403
|
-
evt.stopPropagation();
|
|
404
|
-
evt.use();
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
this._isPlacing = false;
|
|
408
|
-
this.context.input.removeEventListener("pointerup", this.onPlaceScene);
|
|
409
|
-
|
|
410
|
-
this.onRevertSceneChanges();
|
|
411
|
-
|
|
412
|
-
// TODO: we should probably use the non-lerped position and quaternion here
|
|
413
|
-
reticle.position.copy(reticle["lastPos"]);
|
|
414
|
-
reticle.quaternion.copy(reticle["lastQuat"]);
|
|
415
|
-
|
|
416
|
-
this.onApplyPose(reticle);
|
|
417
|
-
WebARSessionRoot._hasPlaced = true;
|
|
418
|
-
|
|
419
|
-
if (this.useXRAnchor) {
|
|
420
|
-
this.onCreateAnchor(NeedleXRSession.active!, hit);
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
if (this.context.xr) {
|
|
424
|
-
for (const ctrl of this.context.xr.controllers) {
|
|
425
|
-
ctrl.cancelHitTestSource();
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
private onSetScale() {
|
|
431
|
-
if (!WebARSessionRoot._hasPlaced) return;
|
|
432
|
-
const rig = NeedleXRSession.active?.rig?.gameObject;
|
|
433
|
-
if (rig) {
|
|
434
|
-
const currentScale = NeedleXRSession.active?.rigScale || 1;
|
|
435
|
-
const newScale = (1 / this._arScale) * currentScale;
|
|
436
|
-
const scaleMatrix = new Matrix4().makeScale(newScale, newScale, newScale).invert();
|
|
437
|
-
rig.matrix.premultiply(scaleMatrix);
|
|
438
|
-
rig.matrix.decompose(rig.position, rig.quaternion, rig.scale);
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
private onRevertSceneChanges() {
|
|
443
|
-
for (const ret of this._reticle) {
|
|
444
|
-
if (!ret) continue;
|
|
445
|
-
ret.visible = false;
|
|
446
|
-
ret?.removeFromParent();
|
|
447
|
-
}
|
|
448
|
-
this._reticle.length = 0;
|
|
449
|
-
|
|
450
|
-
for (let i = this._placementScene.children.length - 1; i >= 0; i--) {
|
|
451
|
-
const ch = this._placementScene.children[i];
|
|
452
|
-
this.context.scene.add(ch);
|
|
453
|
-
}
|
|
454
|
-
this._createdPlacementObject?.removeFromParent();
|
|
455
|
-
|
|
456
|
-
for (const reparented of this._reparentedComponents) {
|
|
457
|
-
GameObject.addComponent(reparented.originalObject, reparented.comp);
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
private async onCreateAnchor(session: NeedleXRSession, hit: XRHitTestResult) {
|
|
462
|
-
if (hit.createAnchor === undefined) {
|
|
463
|
-
console.warn("Hit does not support creating an anchor", hit);
|
|
464
|
-
if (isDevEnvironment()) showBalloonWarning("Hit does not support creating an anchor");
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
467
|
-
else {
|
|
468
|
-
const anchor = await hit.createAnchor(session.viewerPose!.transform);
|
|
469
|
-
// make sure the session is still active
|
|
470
|
-
if (session.running && anchor) {
|
|
471
|
-
this._anchor = anchor;
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
private upVec: Vector3 = new Vector3(0, 1, 0);
|
|
477
|
-
private lookPoint: Vector3 = new Vector3();
|
|
478
|
-
private worldUpVec: Vector3 = new Vector3(0, 1, 0);
|
|
479
|
-
|
|
480
|
-
private applyViewBasedTransform(reticle: Object3D) {
|
|
481
|
-
|
|
482
|
-
// Make reticle face the user to unify the placement experience across devices.
|
|
483
|
-
// The pose that we're receiving from the hit test varies between devices:
|
|
484
|
-
// - Quest: currently aligned to the mesh that was hit (depends on room setup), has changed a couple times
|
|
485
|
-
// - Android WebXR: looking at the camera, but pretty random when on a wall
|
|
486
|
-
// - Mozilla WebXR Viewer: aligned to the start of the session
|
|
487
|
-
const camGo = this.context.mainCamera as Object3D as GameObject;
|
|
488
|
-
const reticleGo = reticle as GameObject;
|
|
489
|
-
const camWP = camGo.worldPosition;
|
|
490
|
-
const reticleWp = reticleGo.worldPosition;
|
|
491
|
-
|
|
492
|
-
this.upVec.set(0, 1, 0).applyQuaternion(reticle.quaternion);
|
|
493
|
-
|
|
494
|
-
// upVec may be pointing AWAY from us, we have to flip it if that's the case
|
|
495
|
-
const camPos = camGo.worldPosition;
|
|
496
|
-
if (camPos) {
|
|
497
|
-
const camToReticle = reticle.position.clone().sub(camPos);
|
|
498
|
-
const angle = camToReticle.angleTo(this.upVec);
|
|
499
|
-
if (angle < Math.PI / 2) {
|
|
500
|
-
this.upVec.negate();
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
const upAngle = this.upVec.angleTo(this.worldUpVec) * 180 / Math.PI;
|
|
505
|
-
// For debugging look angle for AR placement
|
|
506
|
-
// Gizmos.DrawDirection(reticle.position, upVec, "blue", 0.1);
|
|
507
|
-
// Gizmos.DrawLabel(reticle.position, upAngle.toFixed(2), 0.1);
|
|
508
|
-
|
|
509
|
-
const angleForWallPlacement = 30;
|
|
510
|
-
if ((upAngle > angleForWallPlacement && upAngle < 180 - angleForWallPlacement) ||
|
|
511
|
-
(upAngle < -angleForWallPlacement && upAngle > -180 + angleForWallPlacement)) {
|
|
512
|
-
|
|
513
|
-
this.lookPoint.copy(reticle.position).add(this.upVec);
|
|
514
|
-
this.lookPoint.y = reticle.position.y;
|
|
515
|
-
reticle.lookAt(this.lookPoint);
|
|
516
|
-
}
|
|
517
|
-
else {
|
|
518
|
-
camWP.y = reticleWp.y;
|
|
519
|
-
reticle.lookAt(camWP);
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
// TODO: ability to scale the reticle so that we can fit the scene depending on the view angle or distance to the reticle.
|
|
523
|
-
// Currently, doing this leads to wrong placement of the scene.
|
|
524
|
-
/*
|
|
525
|
-
const rigScale = NeedleXRSession.active?.rigScale || 1;
|
|
526
|
-
const scale = distance * rigScale;
|
|
527
|
-
reticle.scale.set(scale, scale, scale);
|
|
528
|
-
*/
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
private onApplyPose(reticle: Object3D) {
|
|
532
|
-
const rigObject = NeedleXRSession.active?.rig?.gameObject;
|
|
533
|
-
if (!rigObject) {
|
|
534
|
-
console.warn("No rig object to place");
|
|
535
|
-
return;
|
|
536
|
-
}
|
|
537
|
-
// const rigScale = NeedleXRSession.active?.rigScale || 1;
|
|
538
|
-
|
|
539
|
-
// save the previous rig parent
|
|
540
|
-
const previousParent = rigObject.parent || this.context.scene;
|
|
541
|
-
|
|
542
|
-
// if we have placed this rig before and this is just "replacing" with the anchor
|
|
543
|
-
// we need to make sure the XRRig attached to the reticle is at the same position as last time
|
|
544
|
-
// since in the following code we move it inside the reticle (relative to the reticle)
|
|
545
|
-
if (this._rigPlacementMatrix) {
|
|
546
|
-
this._rigPlacementMatrix?.decompose(rigObject.position, rigObject.quaternion, rigObject.scale);
|
|
547
|
-
}
|
|
548
|
-
else {
|
|
549
|
-
this._rigPlacementMatrix = rigObject.matrix.clone();
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
this.applyViewBasedTransform(reticle);
|
|
553
|
-
reticle.updateMatrix();
|
|
554
|
-
// attach rig to reticle (since the reticle is in rig space it's a easy way to place the rig where we want it relative to the reticle)
|
|
555
|
-
this.context.scene.add(reticle);
|
|
556
|
-
reticle.attach(rigObject);
|
|
557
|
-
reticle.removeFromParent();
|
|
558
|
-
|
|
559
|
-
// move rig now relative to the reticle
|
|
560
|
-
// TODO support scaled reticle
|
|
561
|
-
rigObject.scale.set(this.arScale, this.arScale, this.arScale);
|
|
562
|
-
rigObject.position.multiplyScalar(this.arScale);
|
|
563
|
-
|
|
564
|
-
rigObject.updateMatrix();
|
|
565
|
-
// if invert forward is disabled we need to invert the forward rotation
|
|
566
|
-
// we want to look into positive Z direction (if invertForward is enabled we look into negative Z direction)
|
|
567
|
-
if (this.invertForward)
|
|
568
|
-
rigObject.matrix.premultiply(invertForwardMatrix);
|
|
569
|
-
rigObject.matrix.premultiply(this._startOffset);
|
|
570
|
-
|
|
571
|
-
// apply the rig modifications and add it back to the previous parent
|
|
572
|
-
rigObject.matrix.decompose(rigObject.position, rigObject.quaternion, rigObject.scale);
|
|
573
|
-
previousParent.add(rigObject);
|
|
574
|
-
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
class WebXRSessionRootUserInput {
|
|
582
|
-
private static up = new Vector3(0, 1, 0);
|
|
583
|
-
private static zero = new Vector3(0, 0, 0);
|
|
584
|
-
private static one = new Vector3(1, 1, 1);
|
|
585
|
-
|
|
586
|
-
oneFingerDrag: boolean = true;
|
|
587
|
-
twoFingerRotate: boolean = true;
|
|
588
|
-
twoFingerScale: boolean = true;
|
|
589
|
-
|
|
590
|
-
factor: number = 1;
|
|
591
|
-
|
|
592
|
-
readonly context: Context;
|
|
593
|
-
readonly offset: Matrix4;
|
|
594
|
-
readonly plane: Plane;
|
|
595
|
-
|
|
596
|
-
private _scale: number = 1;
|
|
597
|
-
private _hasChanged: boolean = false;
|
|
598
|
-
|
|
599
|
-
get scale() {
|
|
600
|
-
return this._scale;
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
// readonly translate: Vector3 = new Vector3();
|
|
604
|
-
// readonly rotation: Quaternion = new Quaternion();
|
|
605
|
-
// readonly scale: Vector3 = new Vector3(1, 1, 1);
|
|
606
|
-
|
|
607
|
-
constructor(context: Context) {
|
|
608
|
-
this.context = context;
|
|
609
|
-
this.offset = new Matrix4()
|
|
610
|
-
this.plane = new Plane();
|
|
611
|
-
this.plane.setFromNormalAndCoplanarPoint(WebXRSessionRootUserInput.up, WebXRSessionRootUserInput.zero);
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
private _enabled: boolean = false;
|
|
615
|
-
|
|
616
|
-
reset() {
|
|
617
|
-
this._scale = 1;
|
|
618
|
-
this.offset.identity();
|
|
619
|
-
this._hasChanged = true;
|
|
620
|
-
}
|
|
621
|
-
get hasChanged() { return this._hasChanged; }
|
|
622
|
-
|
|
623
|
-
/**
|
|
624
|
-
* Applies the matrix to the offset matrix
|
|
625
|
-
* @param matrix the matrix to apply the drag offset to
|
|
626
|
-
* @param invert if true the offset matrix will be inverted before applying it to the matrix and premultiplied
|
|
627
|
-
*/
|
|
628
|
-
applyMatrixTo(matrix: Matrix4, invert: boolean) {
|
|
629
|
-
this._hasChanged = false;
|
|
630
|
-
if (invert) {
|
|
631
|
-
this.offset.invert();
|
|
632
|
-
matrix.premultiply(this.offset);
|
|
633
|
-
}
|
|
634
|
-
else
|
|
635
|
-
matrix.multiply(this.offset);
|
|
636
|
-
// if (this._needsUpdate)
|
|
637
|
-
// this.updateMatrix();
|
|
638
|
-
// matrix.premultiply(this._rotationMatrix);
|
|
639
|
-
// matrix.premultiply(this.offset).premultiply(this._rotationMatrix)
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
private readonly currentlyUsedPointerIds = new Set<number>();
|
|
644
|
-
private readonly currentlyUnusedPointerIds = new Set<number>();
|
|
645
|
-
get isActive() {
|
|
646
|
-
return this.currentlyUsedPointerIds.size <= 0 && this.currentlyUnusedPointerIds.size > 0;
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
enable() {
|
|
650
|
-
if (this._enabled) return;
|
|
651
|
-
this._enabled = true;
|
|
652
|
-
|
|
653
|
-
this.context.input.addEventListener("pointerdown", this.onPointerDownEarly, { queue: InputEventQueue.Early });
|
|
654
|
-
this.context.input.addEventListener("pointerdown", this.onPointerDownLate, { queue: InputEventQueue.Late });
|
|
655
|
-
this.context.input.addEventListener("pointerup", this.onPointerUpEarly, { queue: InputEventQueue.Early });
|
|
656
|
-
|
|
657
|
-
// TODO: refactor the following events to use the input system
|
|
658
|
-
window.addEventListener('touchstart', this.touchStart, { passive: false });
|
|
659
|
-
window.addEventListener('touchmove', this.touchMove, { passive: false });
|
|
660
|
-
window.addEventListener('touchend', this.touchEnd, { passive: false });
|
|
661
|
-
}
|
|
662
|
-
disable() {
|
|
663
|
-
if (!this._enabled) return;
|
|
664
|
-
this._enabled = false;
|
|
665
|
-
|
|
666
|
-
this.context.input.removeEventListener("pointerdown", this.onPointerDownEarly, { queue: InputEventQueue.Early });
|
|
667
|
-
this.context.input.removeEventListener("pointerdown", this.onPointerDownLate, { queue: InputEventQueue.Late });
|
|
668
|
-
this.context.input.removeEventListener("pointerup", this.onPointerUpEarly, { queue: InputEventQueue.Early });
|
|
669
|
-
|
|
670
|
-
window.removeEventListener('touchstart', this.touchStart);
|
|
671
|
-
window.removeEventListener('touchmove', this.touchMove);
|
|
672
|
-
window.removeEventListener('touchend', this.touchEnd);
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
private onPointerDownEarly = (e: NEPointerEvent) => {
|
|
676
|
-
if (this.isActive) e.stopPropagation();
|
|
677
|
-
};
|
|
678
|
-
private onPointerDownLate = (e: NEPointerEvent) => {
|
|
679
|
-
if (e.used) this.currentlyUsedPointerIds.add(e.pointerId);
|
|
680
|
-
else if (this.currentlyUsedPointerIds.size <= 0) this.currentlyUnusedPointerIds.add(e.pointerId);
|
|
681
|
-
};
|
|
682
|
-
private onPointerUpEarly = (e: NEPointerEvent) => {
|
|
683
|
-
this.currentlyUsedPointerIds.delete(e.pointerId);
|
|
684
|
-
this.currentlyUnusedPointerIds.delete(e.pointerId);
|
|
685
|
-
};
|
|
686
|
-
|
|
687
|
-
// private _needsUpdate: boolean = true;
|
|
688
|
-
// private _rotationMatrix: Matrix4 = new Matrix4();
|
|
689
|
-
// private updateMatrix() {
|
|
690
|
-
// this._needsUpdate = false;
|
|
691
|
-
// this._rotationMatrix.makeRotationFromQuaternion(this.rotation);
|
|
692
|
-
// this.offset.compose(this.translate, new Quaternion(), this.scale);
|
|
693
|
-
// // const rot = this._tempMatrix.makeRotationY(this.angle);
|
|
694
|
-
// // this.translate.applyMatrix4(rot);
|
|
695
|
-
// // this.offset.elements[12] = this.translate.x;
|
|
696
|
-
// // this.offset.elements[13] = this.translate.y;
|
|
697
|
-
// // this.offset.elements[14] = this.translate.z;
|
|
698
|
-
// // this.offset.premultiply(rot);
|
|
699
|
-
// // const s = this.scale;
|
|
700
|
-
// // this.offset.premultiply(this._tempMatrix.makeScale(s, s, s));
|
|
701
|
-
// }
|
|
702
|
-
|
|
703
|
-
private prev: Map<number, { ignore: boolean, x: number, z: number, screenx: number, screeny: number }> = new Map();
|
|
704
|
-
private _didMultitouch: boolean = false;
|
|
705
|
-
|
|
706
|
-
private touchStart = (evt: TouchEvent) => {
|
|
707
|
-
if (evt.defaultPrevented) return;
|
|
708
|
-
|
|
709
|
-
// let isValidTouch = true;
|
|
710
|
-
// isValidTouch = evt.target === this.context.domElement || evt.target === this.context.renderer.domElement;
|
|
711
|
-
// if (!isValidTouch) {
|
|
712
|
-
// return;
|
|
713
|
-
// }
|
|
714
|
-
|
|
715
|
-
for (let i = 0; i < evt.changedTouches.length; i++) {
|
|
716
|
-
const touch = evt.changedTouches[i];
|
|
717
|
-
// if a user starts swiping in the top area of the screen
|
|
718
|
-
// which might be a gesture to open the menu
|
|
719
|
-
// we ignore it
|
|
720
|
-
const ignore = DeviceUtilities.isAndroidDevice() && touch.clientY < window.innerHeight * .1;
|
|
721
|
-
if (!this.prev.has(touch.identifier))
|
|
722
|
-
this.prev.set(touch.identifier, {
|
|
723
|
-
ignore,
|
|
724
|
-
x: 0,
|
|
725
|
-
z: 0,
|
|
726
|
-
screenx: 0,
|
|
727
|
-
screeny: 0,
|
|
728
|
-
});
|
|
729
|
-
const prev = this.prev.get(touch.identifier);
|
|
730
|
-
if (prev) {
|
|
731
|
-
const pos = this.getPositionOnPlane(touch.clientX, touch.clientY);
|
|
732
|
-
prev.x = pos.x;
|
|
733
|
-
prev.z = pos.z;
|
|
734
|
-
prev.screenx = touch.clientX;
|
|
735
|
-
prev.screeny = touch.clientY;
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
private touchEnd = (evt: TouchEvent) => {
|
|
740
|
-
if (evt.touches.length <= 0) {
|
|
741
|
-
this._didMultitouch = false;
|
|
742
|
-
}
|
|
743
|
-
for (let i = 0; i < evt.changedTouches.length; i++) {
|
|
744
|
-
const touch = evt.changedTouches[i];
|
|
745
|
-
this.prev.delete(touch.identifier);
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
private touchMove = (evt: TouchEvent) => {
|
|
749
|
-
if (evt.defaultPrevented) return;
|
|
750
|
-
if (!this.isActive) return;
|
|
751
|
-
|
|
752
|
-
if (evt.touches.length === 1) {
|
|
753
|
-
// if we had multiple touches before due to e.g. pinching / rotating
|
|
754
|
-
// and stopping one of the touches, we don't want to move the scene suddenly
|
|
755
|
-
// this will be resettet when all touches stop
|
|
756
|
-
if (this._didMultitouch) {
|
|
757
|
-
return;
|
|
758
|
-
}
|
|
759
|
-
const touch = evt.touches[0];
|
|
760
|
-
const prev = this.prev.get(touch.identifier);
|
|
761
|
-
if (!prev || prev.ignore) return;
|
|
762
|
-
const pos = this.getPositionOnPlane(touch.clientX, touch.clientY);
|
|
763
|
-
const dx = pos.x - prev.x;
|
|
764
|
-
const dy = pos.z - prev.z;
|
|
765
|
-
if (dx === 0 && dy === 0) return;
|
|
766
|
-
if (this.oneFingerDrag)
|
|
767
|
-
this.addMovement(dx, dy);
|
|
768
|
-
prev.x = pos.x;
|
|
769
|
-
prev.z = pos.z;
|
|
770
|
-
prev.screenx = touch.clientX;
|
|
771
|
-
prev.screeny = touch.clientY;
|
|
772
|
-
return;
|
|
773
|
-
}
|
|
774
|
-
else if (evt.touches.length === 2) {
|
|
775
|
-
this._didMultitouch = true;
|
|
776
|
-
const touch1 = evt.touches[0];
|
|
777
|
-
const touch2 = evt.touches[1];
|
|
778
|
-
const prev1 = this.prev.get(touch1.identifier);
|
|
779
|
-
const prev2 = this.prev.get(touch2.identifier);
|
|
780
|
-
if (!prev1 || !prev2) return;
|
|
781
|
-
|
|
782
|
-
if (this.twoFingerRotate) {
|
|
783
|
-
const angle1 = Math.atan2(touch1.clientY - touch2.clientY, touch1.clientX - touch2.clientX);
|
|
784
|
-
const lastAngle = Math.atan2(prev1.screeny - prev2.screeny, prev1.screenx - prev2.screenx);
|
|
785
|
-
const angleDiff = angle1 - lastAngle;
|
|
786
|
-
if (Math.abs(angleDiff) > 0.001) {
|
|
787
|
-
this.addRotation(angleDiff);
|
|
788
|
-
}
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
if (this.twoFingerScale) {
|
|
792
|
-
const distx = touch1.clientX - touch2.clientX;
|
|
793
|
-
const disty = touch1.clientY - touch2.clientY;
|
|
794
|
-
const dist = Math.sqrt(distx * distx + disty * disty);
|
|
795
|
-
const lastDistx = prev1.screenx - prev2.screenx;
|
|
796
|
-
const lastDisty = prev1.screeny - prev2.screeny;
|
|
797
|
-
const lastDist = Math.sqrt(lastDistx * lastDistx + lastDisty * lastDisty);
|
|
798
|
-
const distDiff = dist - lastDist;
|
|
799
|
-
if (Math.abs(distDiff) > 2) {
|
|
800
|
-
this.addScale(distDiff)
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
prev1.screenx = touch1.clientX;
|
|
805
|
-
prev1.screeny = touch1.clientY;
|
|
806
|
-
prev2.screenx = touch2.clientX;
|
|
807
|
-
prev2.screeny = touch2.clientY;
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
private readonly _raycaster: Raycaster = new Raycaster();
|
|
812
|
-
private readonly _intersection: Vector3 = new Vector3();
|
|
813
|
-
private readonly _screenPos: Vector3 = new Vector3();
|
|
814
|
-
|
|
815
|
-
private getPositionOnPlane(tx: number, ty: number): Vector3 {
|
|
816
|
-
const camera = this.context.mainCamera!;
|
|
817
|
-
this._screenPos.x = (tx / window.innerWidth) * 2 - 1;
|
|
818
|
-
this._screenPos.y = -(ty / window.innerHeight) * 2 + 1;
|
|
819
|
-
this._screenPos.z = 1;
|
|
820
|
-
|
|
821
|
-
this._screenPos.unproject(camera);
|
|
822
|
-
this._raycaster.set(camera.position, this._screenPos.sub(camera.position));
|
|
823
|
-
this._raycaster.ray.intersectPlane(this.plane, this._intersection);
|
|
824
|
-
return this._intersection;
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
private addMovement(dx: number, dz: number) {
|
|
828
|
-
// this.translate.x -= dx;
|
|
829
|
-
// this.translate.z -= dz;
|
|
830
|
-
// this._needsUpdate = true;
|
|
831
|
-
// return
|
|
832
|
-
|
|
833
|
-
// increase diff if the scene is scaled small
|
|
834
|
-
dx /= this._scale;
|
|
835
|
-
dz /= this._scale;
|
|
836
|
-
|
|
837
|
-
dx *= this.factor;
|
|
838
|
-
dz *= this.factor;
|
|
839
|
-
|
|
840
|
-
// apply it
|
|
841
|
-
this.offset.elements[12] += dx;
|
|
842
|
-
this.offset.elements[14] += dz;
|
|
843
|
-
if (dx !== 0 || dz !== 0)
|
|
844
|
-
this._hasChanged = true;
|
|
845
|
-
};
|
|
846
|
-
|
|
847
|
-
private readonly _tempMatrix: Matrix4 = new Matrix4();
|
|
848
|
-
|
|
849
|
-
private addScale(diff: number) {
|
|
850
|
-
diff /= window.innerWidth
|
|
851
|
-
diff *= -1;
|
|
852
|
-
|
|
853
|
-
// this.scale.x *= 1 + diff;
|
|
854
|
-
// this.scale.y *= 1 + diff;
|
|
855
|
-
// this.scale.z *= 1 + diff;
|
|
856
|
-
// this._needsUpdate = true;
|
|
857
|
-
// return;
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
// we use this factor to modify the translation factor (in apply movement)
|
|
861
|
-
this._scale *= 1 + diff;
|
|
862
|
-
// apply the scale
|
|
863
|
-
this._tempMatrix.makeScale(1 - diff, 1 - diff, 1 - diff);
|
|
864
|
-
this.offset.premultiply(this._tempMatrix);
|
|
865
|
-
if (diff !== 0)
|
|
866
|
-
this._hasChanged = true;
|
|
867
|
-
}
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
private addRotation(rot: number) {
|
|
871
|
-
rot *= -1;
|
|
872
|
-
// this.rotation.multiply(new Quaternion().setFromAxisAngle(WebXRSessionRootUserInput.up, rot));
|
|
873
|
-
// this._needsUpdate = true;
|
|
874
|
-
// return;
|
|
875
|
-
this._tempMatrix.makeRotationY(rot);
|
|
876
|
-
this.offset.premultiply(this._tempMatrix);
|
|
877
|
-
if (rot !== 0)
|
|
878
|
-
this._hasChanged = true;
|
|
879
|
-
}
|
|
880
|
-
}
|
|
1
|
+
import { AxesHelper, DoubleSide, Matrix4, Mesh, MeshBasicMaterial, Object3D, Plane, Raycaster, RingGeometry, Scene, Vector3 } from "three";
|
|
2
|
+
|
|
3
|
+
import { isDevEnvironment, showBalloonWarning } from "../../engine/debug/index.js";
|
|
4
|
+
import { AssetReference } from "../../engine/engine_addressables.js";
|
|
5
|
+
import { Context } from "../../engine/engine_context.js";
|
|
6
|
+
import { destroy, instantiate } from "../../engine/engine_gameobject.js";
|
|
7
|
+
import { InputEventQueue, NEPointerEvent } from "../../engine/engine_input.js";
|
|
8
|
+
import { getBoundingBox, getTempVector } from "../../engine/engine_three_utils.js";
|
|
9
|
+
import type { IComponent, IGameObject } from "../../engine/engine_types.js";
|
|
10
|
+
import { DeviceUtilities, getParam } from "../../engine/engine_utils.js";
|
|
11
|
+
import { NeedleXRController, type NeedleXREventArgs, type NeedleXRHitTestResult, NeedleXRSession } from "../../engine/engine_xr.js";
|
|
12
|
+
import { Behaviour, GameObject } from "../Component.js";
|
|
13
|
+
|
|
14
|
+
// https://github.com/takahirox/takahirox.github.io/blob/master/js.mmdeditor/examples/js/controls/DeviceOrientationControls.js
|
|
15
|
+
|
|
16
|
+
const debug = getParam("debugwebxr");
|
|
17
|
+
|
|
18
|
+
const invertForwardMatrix = new Matrix4().makeRotationY(Math.PI);
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The WebARSessionRoot is the root object for a WebAR session and used to place the scene in AR.
|
|
23
|
+
* It is also responsible for scaling the user in AR and optionally creating a XR anchor for the scene placement.
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* WebARSessionRoot.onPlaced((args) => {
|
|
27
|
+
* console.log("Scene has been placed in AR");
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @category XR
|
|
32
|
+
* @group Components
|
|
33
|
+
*/
|
|
34
|
+
export class WebARSessionRoot extends Behaviour {
|
|
35
|
+
|
|
36
|
+
private static _eventListeners: { [key: string]: Array<(args: { instance: WebARSessionRoot }) => void> } = {};
|
|
37
|
+
/**
|
|
38
|
+
* Event that is called when the scene has been placed in AR.
|
|
39
|
+
* @param cb the callback that is called when the scene has been placed
|
|
40
|
+
* @returns a function to remove the event listener
|
|
41
|
+
*/
|
|
42
|
+
static onPlaced(cb: (args: { instance: WebARSessionRoot }) => void) {
|
|
43
|
+
const event = "placed";
|
|
44
|
+
if (!this._eventListeners[event]) this._eventListeners[event] = [];
|
|
45
|
+
this._eventListeners[event].push(cb);
|
|
46
|
+
return () => {
|
|
47
|
+
const index = this._eventListeners[event].indexOf(cb);
|
|
48
|
+
if (index >= 0) this._eventListeners[event].splice(index, 1);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
private static _hasPlaced: boolean = false;
|
|
53
|
+
/**
|
|
54
|
+
* @returns true if the scene has been placed in AR by the user or automatic placement
|
|
55
|
+
*/
|
|
56
|
+
static get hasPlaced(): boolean {
|
|
57
|
+
return this._hasPlaced;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
/** The scale of the user in AR.
|
|
62
|
+
* **NOTE**: a large value makes the scene appear smaller
|
|
63
|
+
* @default 1
|
|
64
|
+
*/
|
|
65
|
+
get arScale(): number {
|
|
66
|
+
return this._arScale;
|
|
67
|
+
}
|
|
68
|
+
set arScale(val: number) {
|
|
69
|
+
this._arScale = Math.max(0.000001, val);
|
|
70
|
+
this.onSetScale();
|
|
71
|
+
}
|
|
72
|
+
private _arScale: number = 1;
|
|
73
|
+
|
|
74
|
+
/** When enabled the placed scene forward direction will towards the XRRig
|
|
75
|
+
* @deprecated
|
|
76
|
+
* @default false
|
|
77
|
+
*/
|
|
78
|
+
invertForward: boolean = false;
|
|
79
|
+
|
|
80
|
+
/** When assigned this asset will be loaded and visualize the placement while in AR
|
|
81
|
+
* @default null
|
|
82
|
+
*/
|
|
83
|
+
customReticle?: AssetReference;
|
|
84
|
+
|
|
85
|
+
/** Enable touch transform to translate, rotate and scale the scene in AR with multitouch
|
|
86
|
+
* @default true
|
|
87
|
+
*/
|
|
88
|
+
arTouchTransform: boolean = true;
|
|
89
|
+
|
|
90
|
+
/** When enabled the scene will be placed automatically when a point in the real world is found
|
|
91
|
+
* @default false
|
|
92
|
+
*/
|
|
93
|
+
autoPlace: boolean = false;
|
|
94
|
+
|
|
95
|
+
/** When enabled the scene center will be automatically calculated from the content in the scene */
|
|
96
|
+
autoCenter: boolean = false;
|
|
97
|
+
|
|
98
|
+
/** Experimental: When enabled we will create a XR anchor for the scene placement
|
|
99
|
+
* and make sure the scene is at that anchored point during a XR session
|
|
100
|
+
* @default false
|
|
101
|
+
**/
|
|
102
|
+
useXRAnchor: boolean = false;
|
|
103
|
+
|
|
104
|
+
/** true if we're currently placing the scene */
|
|
105
|
+
private _isPlacing = true;
|
|
106
|
+
|
|
107
|
+
/** This is the world matrix of the ar session root when entering webxr
|
|
108
|
+
* it is applied when the scene has been placed (e.g. if the session root is x:10, z:10 we want this position to be the center of the scene)
|
|
109
|
+
*/
|
|
110
|
+
private readonly _startOffset: Matrix4 = new Matrix4();
|
|
111
|
+
|
|
112
|
+
private _createdPlacementObject: Object3D | null = null;
|
|
113
|
+
private readonly _reparentedComponents: Array<{ comp: IComponent, originalObject: IGameObject }> = [];
|
|
114
|
+
|
|
115
|
+
// move objects into a temporary scene while placing (which is not rendered) so that the components won't be disabled during this process
|
|
116
|
+
// e.g. we want the avatar to still be updated while placing
|
|
117
|
+
// another possibly solution would be to ensure from this component that the Rig is *also* not disabled while placing
|
|
118
|
+
private readonly _placementScene: Scene = new Scene();
|
|
119
|
+
|
|
120
|
+
/** the reticles used for placement */
|
|
121
|
+
private readonly _reticle: IGameObject[] = [];
|
|
122
|
+
/** needs to be in sync with the reticles */
|
|
123
|
+
private readonly _hits: XRHitTestResult[] = [];
|
|
124
|
+
|
|
125
|
+
private _placementStartTime: number = -1;
|
|
126
|
+
private _rigPlacementMatrix?: Matrix4;
|
|
127
|
+
/** if useAnchor is enabled this is the anchor we have created on placing the scene using the placement hit */
|
|
128
|
+
private _anchor: XRAnchor | null = null;
|
|
129
|
+
/** user input is used for ar touch transform */
|
|
130
|
+
private userInput?: WebXRSessionRootUserInput;
|
|
131
|
+
|
|
132
|
+
onEnable(): void {
|
|
133
|
+
this.customReticle?.preload();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
supportsXR(mode: XRSessionMode): boolean {
|
|
137
|
+
return mode === "immersive-ar";
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
onEnterXR(_args: NeedleXREventArgs): void {
|
|
141
|
+
if (debug) console.log("ENTER WEBXR: SessionRoot start...");
|
|
142
|
+
|
|
143
|
+
this._anchor = null;
|
|
144
|
+
WebARSessionRoot._hasPlaced = false;
|
|
145
|
+
|
|
146
|
+
// if (_args.xr.session.enabledFeatures?.includes("image-tracking")) {
|
|
147
|
+
// console.warn("Image tracking is enabled - will not place scene");
|
|
148
|
+
// return;
|
|
149
|
+
// }
|
|
150
|
+
|
|
151
|
+
// save the transform of the session root in the scene to apply it when placing the scene
|
|
152
|
+
this.gameObject.updateMatrixWorld();
|
|
153
|
+
this._startOffset.copy(this.gameObject.matrixWorld);
|
|
154
|
+
|
|
155
|
+
// create a new root object for the session placement scripts
|
|
156
|
+
// and move all the children in the scene in a temporary scene that is not rendered
|
|
157
|
+
const rootObject = new Object3D();
|
|
158
|
+
this._createdPlacementObject = rootObject;
|
|
159
|
+
rootObject.name = "AR Session Root";
|
|
160
|
+
this._placementScene.name = "AR Placement Scene";
|
|
161
|
+
this._placementScene.children.length = 0;
|
|
162
|
+
for (let i = this.context.scene.children.length - 1; i >= 0; i--) {
|
|
163
|
+
const ch = this.context.scene.children[i];
|
|
164
|
+
this._placementScene.add(ch);
|
|
165
|
+
}
|
|
166
|
+
this.context.scene.add(rootObject);
|
|
167
|
+
|
|
168
|
+
if (this.autoCenter) {
|
|
169
|
+
const bounds = getBoundingBox(this._placementScene.children);
|
|
170
|
+
const center = bounds.getCenter(new Vector3());
|
|
171
|
+
const size = bounds.getSize(new Vector3());
|
|
172
|
+
const matrix = new Matrix4();
|
|
173
|
+
matrix.makeTranslation(center.x, center.y - size.y * .5, center.z);
|
|
174
|
+
this._startOffset.multiply(matrix);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// reparent components
|
|
178
|
+
// save which gameobject the sessionroot component was previously attached to
|
|
179
|
+
this._reparentedComponents.length = 0;
|
|
180
|
+
this._reparentedComponents.push({ comp: this, originalObject: this.gameObject });
|
|
181
|
+
GameObject.addComponent(rootObject, this);
|
|
182
|
+
// const webXR = GameObject.findObjectOfType(WebXR2);
|
|
183
|
+
// if (webXR) {
|
|
184
|
+
// this._reparentedComponents.push({ comp: webXR, originalObject: webXR.gameObject });
|
|
185
|
+
// GameObject.addComponent(rootObject, webXR);
|
|
186
|
+
// const playerSync = GameObject.findObjectOfType(XRFlag);
|
|
187
|
+
// }
|
|
188
|
+
|
|
189
|
+
// recreate the reticle every time we enter AR
|
|
190
|
+
for (const ret of this._reticle) {
|
|
191
|
+
destroy(ret);
|
|
192
|
+
}
|
|
193
|
+
this._reticle.length = 0;
|
|
194
|
+
this._isPlacing = true;
|
|
195
|
+
// we want to receive pointer events EARLY and prevent interaction with other objects while placing by stopping the event propagation
|
|
196
|
+
this.context.input.addEventListener("pointerup", this.onPlaceScene, { queue: InputEventQueue.Early });
|
|
197
|
+
}
|
|
198
|
+
onLeaveXR() {
|
|
199
|
+
// TODO: WebARSessionRoot doesnt work when we enter passthrough and leave XR without having placed the session!!!
|
|
200
|
+
this.context.input.removeEventListener("pointerup", this.onPlaceScene, { queue: InputEventQueue.Early });
|
|
201
|
+
this.onRevertSceneChanges();
|
|
202
|
+
// this._anchor?.delete();
|
|
203
|
+
this._anchor = null;
|
|
204
|
+
WebARSessionRoot._hasPlaced = false;
|
|
205
|
+
this._rigPlacementMatrix = undefined;
|
|
206
|
+
}
|
|
207
|
+
onUpdateXR(args: NeedleXREventArgs): void {
|
|
208
|
+
|
|
209
|
+
// disable session placement while images are being tracked
|
|
210
|
+
if (args.xr.isTrackingImages) {
|
|
211
|
+
for (const ret of this._reticle)
|
|
212
|
+
ret.visible = false;
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (this._isPlacing) {
|
|
217
|
+
const rigObject = args.xr.rig?.gameObject;
|
|
218
|
+
// the rig should be parented to the scene while placing
|
|
219
|
+
// since the camera is always parented to the rig this ensures that the camera is always rendering
|
|
220
|
+
if (rigObject && rigObject.parent !== this.context.scene) {
|
|
221
|
+
this.context.scene.add(rigObject);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// in pass through mode we want to place the scene using an XR controller
|
|
225
|
+
let controllersDidHit = false;
|
|
226
|
+
// when auto placing we just use the user's view
|
|
227
|
+
if (args.xr.isPassThrough && args.xr.controllers.length > 0 && !this.autoPlace) {
|
|
228
|
+
for (const ctrl of args.xr.controllers) {
|
|
229
|
+
// with this we can only place with the left / first controller right now
|
|
230
|
+
// we also only have one reticle... this should probably be refactored a bit so we can have multiple reticles
|
|
231
|
+
// and then place at the reticle for which the user clicked the place button
|
|
232
|
+
const hit = ctrl.getHitTest();
|
|
233
|
+
if (hit) {
|
|
234
|
+
controllersDidHit = true;
|
|
235
|
+
this.updateReticleAndHits(args.xr, ctrl.index, hit, args.xr.rigScale);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// in screen AR mode we use "camera" hit testing (or when using the simulator where controller hit testing is not supported)
|
|
240
|
+
if (!controllersDidHit) {
|
|
241
|
+
const hit = args.xr.getHitTest();
|
|
242
|
+
if (hit) {
|
|
243
|
+
this.updateReticleAndHits(args.xr, 0, hit, args.xr.rigScale);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
// Update anchors, if any
|
|
250
|
+
if (this._anchor && args.xr.referenceSpace) {
|
|
251
|
+
const pose = args.xr.frame.getPose(this._anchor.anchorSpace, args.xr.referenceSpace);
|
|
252
|
+
if (pose && this.context.time.frame % 20 === 0) {
|
|
253
|
+
// apply the anchor pose to one of the reticles
|
|
254
|
+
const converted = args.xr.convertSpace(pose.transform);
|
|
255
|
+
const reticle = this._reticle[0];
|
|
256
|
+
if (reticle) {
|
|
257
|
+
reticle.position.copy(converted.position);
|
|
258
|
+
reticle.quaternion.copy(converted.quaternion);
|
|
259
|
+
this.onApplyPose(reticle);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Scene has been placed
|
|
265
|
+
if (this.arTouchTransform) {
|
|
266
|
+
if (!this.userInput) this.userInput = new WebXRSessionRootUserInput(this.context);
|
|
267
|
+
this.userInput?.enable();
|
|
268
|
+
}
|
|
269
|
+
else this.userInput?.disable();
|
|
270
|
+
if (this.arTouchTransform && this.userInput?.hasChanged) {
|
|
271
|
+
if (args.xr.rig) {
|
|
272
|
+
const rig = args.xr.rig.gameObject;
|
|
273
|
+
this.userInput.applyMatrixTo(rig.matrix, true);
|
|
274
|
+
rig.matrix.decompose(rig.position, rig.quaternion, rig.scale);
|
|
275
|
+
// if the rig is scaled large we want the drag touch to be faster
|
|
276
|
+
this.userInput.factor = rig.scale.x;
|
|
277
|
+
}
|
|
278
|
+
this.userInput.reset();
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
private updateReticleAndHits(_xr: NeedleXRSession, i: number, hit: NeedleXRHitTestResult, scale: number) {
|
|
284
|
+
// save the hit test
|
|
285
|
+
this._hits[i] = hit.hit;
|
|
286
|
+
let reticle = this._reticle[i];
|
|
287
|
+
if (!reticle) {
|
|
288
|
+
if (this.customReticle) {
|
|
289
|
+
if (this.customReticle.asset) {
|
|
290
|
+
reticle = instantiate(this.customReticle.asset);
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
this.customReticle.loadAssetAsync();
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
reticle = new Mesh(
|
|
299
|
+
new RingGeometry(0.07, 0.09, 32).rotateX(- Math.PI / 2),
|
|
300
|
+
new MeshBasicMaterial({ side: DoubleSide, depthTest: false, depthWrite: false, transparent: true, opacity: 1, color: 0xeeeeee })
|
|
301
|
+
) as any as IGameObject;
|
|
302
|
+
reticle.name = "AR Placement Reticle";
|
|
303
|
+
}
|
|
304
|
+
if (debug) {
|
|
305
|
+
const axes = new AxesHelper(1);
|
|
306
|
+
axes.position.y += .01;
|
|
307
|
+
reticle.add(axes);
|
|
308
|
+
}
|
|
309
|
+
this._reticle[i] = reticle;
|
|
310
|
+
reticle.matrixAutoUpdate = false;
|
|
311
|
+
reticle.visible = false;
|
|
312
|
+
}
|
|
313
|
+
reticle["lastPos"] = reticle["lastPos"] || hit.position.clone();
|
|
314
|
+
reticle["lastQuat"] = reticle["lastQuat"] || hit.quaternion.clone();
|
|
315
|
+
// reticle["targetPos"] = reticle["targetPos"] || hit.position.clone();
|
|
316
|
+
// reticle["targetQuat"] = reticle["targetQuat"] || hit.quaternion.clone();
|
|
317
|
+
|
|
318
|
+
// TODO we likely want the reticle itself to be placed _exactly_ and then the visuals being lerped,
|
|
319
|
+
// Right now this leads to a "rotation glitch" when going from a horizontal to a vertical surface
|
|
320
|
+
reticle.position.copy(reticle["lastPos"].lerp(hit.position, this.context.time.deltaTime / .1));
|
|
321
|
+
reticle["lastPos"].copy(reticle.position);
|
|
322
|
+
reticle.quaternion.copy(reticle["lastQuat"].slerp(hit.quaternion, this.context.time.deltaTime / .05));
|
|
323
|
+
reticle["lastQuat"].copy(reticle.quaternion);
|
|
324
|
+
|
|
325
|
+
// TODO make sure original reticle asset scale is respected, or document it should be uniformly scaled
|
|
326
|
+
// scale *= this.customReticle?.asset?.scale?.x || 1;
|
|
327
|
+
reticle.scale.set(scale, scale, scale);
|
|
328
|
+
|
|
329
|
+
// if (this.invertForward) {
|
|
330
|
+
// reticle.rotateY(Math.PI);
|
|
331
|
+
// }
|
|
332
|
+
|
|
333
|
+
// Workaround: For a custom reticle we apply the view based transform during placement preview
|
|
334
|
+
// See NE-4161 for context
|
|
335
|
+
if (this.customReticle)
|
|
336
|
+
this.applyViewBasedTransform(reticle);
|
|
337
|
+
|
|
338
|
+
reticle.updateMatrix();
|
|
339
|
+
reticle.visible = true;
|
|
340
|
+
if (reticle.parent !== this.context.scene)
|
|
341
|
+
this.context.scene.add(reticle);
|
|
342
|
+
|
|
343
|
+
if (this._placementStartTime < 0) {
|
|
344
|
+
this._placementStartTime = this.context.time.realtimeSinceStartup;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
if (this.autoPlace) {
|
|
348
|
+
this.upVec.set(0, 1, 0).applyQuaternion(reticle.quaternion);
|
|
349
|
+
const isUp = this.upVec.dot(getTempVector(0, 1, 0)) > 0.9;
|
|
350
|
+
if (isUp) {
|
|
351
|
+
// We want the reticle to be at a suitable spot for a moment before we place the scene (not place it immediately)
|
|
352
|
+
let autoplace_timer = reticle["autoplace:timer"] || 0;
|
|
353
|
+
if (autoplace_timer >= 1) {
|
|
354
|
+
reticle.visible = false;
|
|
355
|
+
this.onPlaceScene(null);
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
autoplace_timer += this.context.time.deltaTime;
|
|
359
|
+
reticle["autoplace:timer"] = autoplace_timer;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
reticle["autoplace:timer"] = 0;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
private onPlaceScene = (evt: NEPointerEvent | null) => {
|
|
369
|
+
if (this._isPlacing == false) return;
|
|
370
|
+
if (evt?.used) return;
|
|
371
|
+
|
|
372
|
+
let reticle: IGameObject | undefined = this._reticle[0];
|
|
373
|
+
|
|
374
|
+
if (!reticle) {
|
|
375
|
+
console.warn("No reticle to place...");
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
if (!reticle.visible && !this.autoPlace) {
|
|
380
|
+
console.warn("Reticle is not visible (can not place)");
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
if (NeedleXRSession.active?.isTrackingImages) {
|
|
385
|
+
console.warn("Scene Placement is disabled while images are being tracked");
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
let hit = this._hits[0];
|
|
390
|
+
|
|
391
|
+
if (evt && evt.origin instanceof NeedleXRController) {
|
|
392
|
+
// until we can use hit testing for both controllers and have multple reticles we only allow placement with the first controller
|
|
393
|
+
const controllerReticle = this._reticle[evt.origin.index];
|
|
394
|
+
if (controllerReticle) {
|
|
395
|
+
reticle = controllerReticle;
|
|
396
|
+
hit = this._hits[evt.origin.index];
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// if we place the scene we don't want this event to be propagated to any sub-objects (via the EventSystem) anymore and trigger e.g. a click on objects for the "place tap" event
|
|
401
|
+
if (evt) {
|
|
402
|
+
evt.stopImmediatePropagation();
|
|
403
|
+
evt.stopPropagation();
|
|
404
|
+
evt.use();
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
this._isPlacing = false;
|
|
408
|
+
this.context.input.removeEventListener("pointerup", this.onPlaceScene);
|
|
409
|
+
|
|
410
|
+
this.onRevertSceneChanges();
|
|
411
|
+
|
|
412
|
+
// TODO: we should probably use the non-lerped position and quaternion here
|
|
413
|
+
reticle.position.copy(reticle["lastPos"]);
|
|
414
|
+
reticle.quaternion.copy(reticle["lastQuat"]);
|
|
415
|
+
|
|
416
|
+
this.onApplyPose(reticle);
|
|
417
|
+
WebARSessionRoot._hasPlaced = true;
|
|
418
|
+
|
|
419
|
+
if (this.useXRAnchor) {
|
|
420
|
+
this.onCreateAnchor(NeedleXRSession.active!, hit);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if (this.context.xr) {
|
|
424
|
+
for (const ctrl of this.context.xr.controllers) {
|
|
425
|
+
ctrl.cancelHitTestSource();
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
private onSetScale() {
|
|
431
|
+
if (!WebARSessionRoot._hasPlaced) return;
|
|
432
|
+
const rig = NeedleXRSession.active?.rig?.gameObject;
|
|
433
|
+
if (rig) {
|
|
434
|
+
const currentScale = NeedleXRSession.active?.rigScale || 1;
|
|
435
|
+
const newScale = (1 / this._arScale) * currentScale;
|
|
436
|
+
const scaleMatrix = new Matrix4().makeScale(newScale, newScale, newScale).invert();
|
|
437
|
+
rig.matrix.premultiply(scaleMatrix);
|
|
438
|
+
rig.matrix.decompose(rig.position, rig.quaternion, rig.scale);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
private onRevertSceneChanges() {
|
|
443
|
+
for (const ret of this._reticle) {
|
|
444
|
+
if (!ret) continue;
|
|
445
|
+
ret.visible = false;
|
|
446
|
+
ret?.removeFromParent();
|
|
447
|
+
}
|
|
448
|
+
this._reticle.length = 0;
|
|
449
|
+
|
|
450
|
+
for (let i = this._placementScene.children.length - 1; i >= 0; i--) {
|
|
451
|
+
const ch = this._placementScene.children[i];
|
|
452
|
+
this.context.scene.add(ch);
|
|
453
|
+
}
|
|
454
|
+
this._createdPlacementObject?.removeFromParent();
|
|
455
|
+
|
|
456
|
+
for (const reparented of this._reparentedComponents) {
|
|
457
|
+
GameObject.addComponent(reparented.originalObject, reparented.comp);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
private async onCreateAnchor(session: NeedleXRSession, hit: XRHitTestResult) {
|
|
462
|
+
if (hit.createAnchor === undefined) {
|
|
463
|
+
console.warn("Hit does not support creating an anchor", hit);
|
|
464
|
+
if (isDevEnvironment()) showBalloonWarning("Hit does not support creating an anchor");
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
else {
|
|
468
|
+
const anchor = await hit.createAnchor(session.viewerPose!.transform);
|
|
469
|
+
// make sure the session is still active
|
|
470
|
+
if (session.running && anchor) {
|
|
471
|
+
this._anchor = anchor;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
private upVec: Vector3 = new Vector3(0, 1, 0);
|
|
477
|
+
private lookPoint: Vector3 = new Vector3();
|
|
478
|
+
private worldUpVec: Vector3 = new Vector3(0, 1, 0);
|
|
479
|
+
|
|
480
|
+
private applyViewBasedTransform(reticle: Object3D) {
|
|
481
|
+
|
|
482
|
+
// Make reticle face the user to unify the placement experience across devices.
|
|
483
|
+
// The pose that we're receiving from the hit test varies between devices:
|
|
484
|
+
// - Quest: currently aligned to the mesh that was hit (depends on room setup), has changed a couple times
|
|
485
|
+
// - Android WebXR: looking at the camera, but pretty random when on a wall
|
|
486
|
+
// - Mozilla WebXR Viewer: aligned to the start of the session
|
|
487
|
+
const camGo = this.context.mainCamera as Object3D as GameObject;
|
|
488
|
+
const reticleGo = reticle as GameObject;
|
|
489
|
+
const camWP = camGo.worldPosition;
|
|
490
|
+
const reticleWp = reticleGo.worldPosition;
|
|
491
|
+
|
|
492
|
+
this.upVec.set(0, 1, 0).applyQuaternion(reticle.quaternion);
|
|
493
|
+
|
|
494
|
+
// upVec may be pointing AWAY from us, we have to flip it if that's the case
|
|
495
|
+
const camPos = camGo.worldPosition;
|
|
496
|
+
if (camPos) {
|
|
497
|
+
const camToReticle = reticle.position.clone().sub(camPos);
|
|
498
|
+
const angle = camToReticle.angleTo(this.upVec);
|
|
499
|
+
if (angle < Math.PI / 2) {
|
|
500
|
+
this.upVec.negate();
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
const upAngle = this.upVec.angleTo(this.worldUpVec) * 180 / Math.PI;
|
|
505
|
+
// For debugging look angle for AR placement
|
|
506
|
+
// Gizmos.DrawDirection(reticle.position, upVec, "blue", 0.1);
|
|
507
|
+
// Gizmos.DrawLabel(reticle.position, upAngle.toFixed(2), 0.1);
|
|
508
|
+
|
|
509
|
+
const angleForWallPlacement = 30;
|
|
510
|
+
if ((upAngle > angleForWallPlacement && upAngle < 180 - angleForWallPlacement) ||
|
|
511
|
+
(upAngle < -angleForWallPlacement && upAngle > -180 + angleForWallPlacement)) {
|
|
512
|
+
|
|
513
|
+
this.lookPoint.copy(reticle.position).add(this.upVec);
|
|
514
|
+
this.lookPoint.y = reticle.position.y;
|
|
515
|
+
reticle.lookAt(this.lookPoint);
|
|
516
|
+
}
|
|
517
|
+
else {
|
|
518
|
+
camWP.y = reticleWp.y;
|
|
519
|
+
reticle.lookAt(camWP);
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// TODO: ability to scale the reticle so that we can fit the scene depending on the view angle or distance to the reticle.
|
|
523
|
+
// Currently, doing this leads to wrong placement of the scene.
|
|
524
|
+
/*
|
|
525
|
+
const rigScale = NeedleXRSession.active?.rigScale || 1;
|
|
526
|
+
const scale = distance * rigScale;
|
|
527
|
+
reticle.scale.set(scale, scale, scale);
|
|
528
|
+
*/
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
private onApplyPose(reticle: Object3D) {
|
|
532
|
+
const rigObject = NeedleXRSession.active?.rig?.gameObject;
|
|
533
|
+
if (!rigObject) {
|
|
534
|
+
console.warn("No rig object to place");
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
// const rigScale = NeedleXRSession.active?.rigScale || 1;
|
|
538
|
+
|
|
539
|
+
// save the previous rig parent
|
|
540
|
+
const previousParent = rigObject.parent || this.context.scene;
|
|
541
|
+
|
|
542
|
+
// if we have placed this rig before and this is just "replacing" with the anchor
|
|
543
|
+
// we need to make sure the XRRig attached to the reticle is at the same position as last time
|
|
544
|
+
// since in the following code we move it inside the reticle (relative to the reticle)
|
|
545
|
+
if (this._rigPlacementMatrix) {
|
|
546
|
+
this._rigPlacementMatrix?.decompose(rigObject.position, rigObject.quaternion, rigObject.scale);
|
|
547
|
+
}
|
|
548
|
+
else {
|
|
549
|
+
this._rigPlacementMatrix = rigObject.matrix.clone();
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
this.applyViewBasedTransform(reticle);
|
|
553
|
+
reticle.updateMatrix();
|
|
554
|
+
// attach rig to reticle (since the reticle is in rig space it's a easy way to place the rig where we want it relative to the reticle)
|
|
555
|
+
this.context.scene.add(reticle);
|
|
556
|
+
reticle.attach(rigObject);
|
|
557
|
+
reticle.removeFromParent();
|
|
558
|
+
|
|
559
|
+
// move rig now relative to the reticle
|
|
560
|
+
// TODO support scaled reticle
|
|
561
|
+
rigObject.scale.set(this.arScale, this.arScale, this.arScale);
|
|
562
|
+
rigObject.position.multiplyScalar(this.arScale);
|
|
563
|
+
|
|
564
|
+
rigObject.updateMatrix();
|
|
565
|
+
// if invert forward is disabled we need to invert the forward rotation
|
|
566
|
+
// we want to look into positive Z direction (if invertForward is enabled we look into negative Z direction)
|
|
567
|
+
if (this.invertForward)
|
|
568
|
+
rigObject.matrix.premultiply(invertForwardMatrix);
|
|
569
|
+
rigObject.matrix.premultiply(this._startOffset);
|
|
570
|
+
|
|
571
|
+
// apply the rig modifications and add it back to the previous parent
|
|
572
|
+
rigObject.matrix.decompose(rigObject.position, rigObject.quaternion, rigObject.scale);
|
|
573
|
+
previousParent.add(rigObject);
|
|
574
|
+
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
class WebXRSessionRootUserInput {
|
|
582
|
+
private static up = new Vector3(0, 1, 0);
|
|
583
|
+
private static zero = new Vector3(0, 0, 0);
|
|
584
|
+
private static one = new Vector3(1, 1, 1);
|
|
585
|
+
|
|
586
|
+
oneFingerDrag: boolean = true;
|
|
587
|
+
twoFingerRotate: boolean = true;
|
|
588
|
+
twoFingerScale: boolean = true;
|
|
589
|
+
|
|
590
|
+
factor: number = 1;
|
|
591
|
+
|
|
592
|
+
readonly context: Context;
|
|
593
|
+
readonly offset: Matrix4;
|
|
594
|
+
readonly plane: Plane;
|
|
595
|
+
|
|
596
|
+
private _scale: number = 1;
|
|
597
|
+
private _hasChanged: boolean = false;
|
|
598
|
+
|
|
599
|
+
get scale() {
|
|
600
|
+
return this._scale;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
// readonly translate: Vector3 = new Vector3();
|
|
604
|
+
// readonly rotation: Quaternion = new Quaternion();
|
|
605
|
+
// readonly scale: Vector3 = new Vector3(1, 1, 1);
|
|
606
|
+
|
|
607
|
+
constructor(context: Context) {
|
|
608
|
+
this.context = context;
|
|
609
|
+
this.offset = new Matrix4()
|
|
610
|
+
this.plane = new Plane();
|
|
611
|
+
this.plane.setFromNormalAndCoplanarPoint(WebXRSessionRootUserInput.up, WebXRSessionRootUserInput.zero);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
private _enabled: boolean = false;
|
|
615
|
+
|
|
616
|
+
reset() {
|
|
617
|
+
this._scale = 1;
|
|
618
|
+
this.offset.identity();
|
|
619
|
+
this._hasChanged = true;
|
|
620
|
+
}
|
|
621
|
+
get hasChanged() { return this._hasChanged; }
|
|
622
|
+
|
|
623
|
+
/**
|
|
624
|
+
* Applies the matrix to the offset matrix
|
|
625
|
+
* @param matrix the matrix to apply the drag offset to
|
|
626
|
+
* @param invert if true the offset matrix will be inverted before applying it to the matrix and premultiplied
|
|
627
|
+
*/
|
|
628
|
+
applyMatrixTo(matrix: Matrix4, invert: boolean) {
|
|
629
|
+
this._hasChanged = false;
|
|
630
|
+
if (invert) {
|
|
631
|
+
this.offset.invert();
|
|
632
|
+
matrix.premultiply(this.offset);
|
|
633
|
+
}
|
|
634
|
+
else
|
|
635
|
+
matrix.multiply(this.offset);
|
|
636
|
+
// if (this._needsUpdate)
|
|
637
|
+
// this.updateMatrix();
|
|
638
|
+
// matrix.premultiply(this._rotationMatrix);
|
|
639
|
+
// matrix.premultiply(this.offset).premultiply(this._rotationMatrix)
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
|
|
643
|
+
private readonly currentlyUsedPointerIds = new Set<number>();
|
|
644
|
+
private readonly currentlyUnusedPointerIds = new Set<number>();
|
|
645
|
+
get isActive() {
|
|
646
|
+
return this.currentlyUsedPointerIds.size <= 0 && this.currentlyUnusedPointerIds.size > 0;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
enable() {
|
|
650
|
+
if (this._enabled) return;
|
|
651
|
+
this._enabled = true;
|
|
652
|
+
|
|
653
|
+
this.context.input.addEventListener("pointerdown", this.onPointerDownEarly, { queue: InputEventQueue.Early });
|
|
654
|
+
this.context.input.addEventListener("pointerdown", this.onPointerDownLate, { queue: InputEventQueue.Late });
|
|
655
|
+
this.context.input.addEventListener("pointerup", this.onPointerUpEarly, { queue: InputEventQueue.Early });
|
|
656
|
+
|
|
657
|
+
// TODO: refactor the following events to use the input system
|
|
658
|
+
window.addEventListener('touchstart', this.touchStart, { passive: false });
|
|
659
|
+
window.addEventListener('touchmove', this.touchMove, { passive: false });
|
|
660
|
+
window.addEventListener('touchend', this.touchEnd, { passive: false });
|
|
661
|
+
}
|
|
662
|
+
disable() {
|
|
663
|
+
if (!this._enabled) return;
|
|
664
|
+
this._enabled = false;
|
|
665
|
+
|
|
666
|
+
this.context.input.removeEventListener("pointerdown", this.onPointerDownEarly, { queue: InputEventQueue.Early });
|
|
667
|
+
this.context.input.removeEventListener("pointerdown", this.onPointerDownLate, { queue: InputEventQueue.Late });
|
|
668
|
+
this.context.input.removeEventListener("pointerup", this.onPointerUpEarly, { queue: InputEventQueue.Early });
|
|
669
|
+
|
|
670
|
+
window.removeEventListener('touchstart', this.touchStart);
|
|
671
|
+
window.removeEventListener('touchmove', this.touchMove);
|
|
672
|
+
window.removeEventListener('touchend', this.touchEnd);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
private onPointerDownEarly = (e: NEPointerEvent) => {
|
|
676
|
+
if (this.isActive) e.stopPropagation();
|
|
677
|
+
};
|
|
678
|
+
private onPointerDownLate = (e: NEPointerEvent) => {
|
|
679
|
+
if (e.used) this.currentlyUsedPointerIds.add(e.pointerId);
|
|
680
|
+
else if (this.currentlyUsedPointerIds.size <= 0) this.currentlyUnusedPointerIds.add(e.pointerId);
|
|
681
|
+
};
|
|
682
|
+
private onPointerUpEarly = (e: NEPointerEvent) => {
|
|
683
|
+
this.currentlyUsedPointerIds.delete(e.pointerId);
|
|
684
|
+
this.currentlyUnusedPointerIds.delete(e.pointerId);
|
|
685
|
+
};
|
|
686
|
+
|
|
687
|
+
// private _needsUpdate: boolean = true;
|
|
688
|
+
// private _rotationMatrix: Matrix4 = new Matrix4();
|
|
689
|
+
// private updateMatrix() {
|
|
690
|
+
// this._needsUpdate = false;
|
|
691
|
+
// this._rotationMatrix.makeRotationFromQuaternion(this.rotation);
|
|
692
|
+
// this.offset.compose(this.translate, new Quaternion(), this.scale);
|
|
693
|
+
// // const rot = this._tempMatrix.makeRotationY(this.angle);
|
|
694
|
+
// // this.translate.applyMatrix4(rot);
|
|
695
|
+
// // this.offset.elements[12] = this.translate.x;
|
|
696
|
+
// // this.offset.elements[13] = this.translate.y;
|
|
697
|
+
// // this.offset.elements[14] = this.translate.z;
|
|
698
|
+
// // this.offset.premultiply(rot);
|
|
699
|
+
// // const s = this.scale;
|
|
700
|
+
// // this.offset.premultiply(this._tempMatrix.makeScale(s, s, s));
|
|
701
|
+
// }
|
|
702
|
+
|
|
703
|
+
private prev: Map<number, { ignore: boolean, x: number, z: number, screenx: number, screeny: number }> = new Map();
|
|
704
|
+
private _didMultitouch: boolean = false;
|
|
705
|
+
|
|
706
|
+
private touchStart = (evt: TouchEvent) => {
|
|
707
|
+
if (evt.defaultPrevented) return;
|
|
708
|
+
|
|
709
|
+
// let isValidTouch = true;
|
|
710
|
+
// isValidTouch = evt.target === this.context.domElement || evt.target === this.context.renderer.domElement;
|
|
711
|
+
// if (!isValidTouch) {
|
|
712
|
+
// return;
|
|
713
|
+
// }
|
|
714
|
+
|
|
715
|
+
for (let i = 0; i < evt.changedTouches.length; i++) {
|
|
716
|
+
const touch = evt.changedTouches[i];
|
|
717
|
+
// if a user starts swiping in the top area of the screen
|
|
718
|
+
// which might be a gesture to open the menu
|
|
719
|
+
// we ignore it
|
|
720
|
+
const ignore = DeviceUtilities.isAndroidDevice() && touch.clientY < window.innerHeight * .1;
|
|
721
|
+
if (!this.prev.has(touch.identifier))
|
|
722
|
+
this.prev.set(touch.identifier, {
|
|
723
|
+
ignore,
|
|
724
|
+
x: 0,
|
|
725
|
+
z: 0,
|
|
726
|
+
screenx: 0,
|
|
727
|
+
screeny: 0,
|
|
728
|
+
});
|
|
729
|
+
const prev = this.prev.get(touch.identifier);
|
|
730
|
+
if (prev) {
|
|
731
|
+
const pos = this.getPositionOnPlane(touch.clientX, touch.clientY);
|
|
732
|
+
prev.x = pos.x;
|
|
733
|
+
prev.z = pos.z;
|
|
734
|
+
prev.screenx = touch.clientX;
|
|
735
|
+
prev.screeny = touch.clientY;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
private touchEnd = (evt: TouchEvent) => {
|
|
740
|
+
if (evt.touches.length <= 0) {
|
|
741
|
+
this._didMultitouch = false;
|
|
742
|
+
}
|
|
743
|
+
for (let i = 0; i < evt.changedTouches.length; i++) {
|
|
744
|
+
const touch = evt.changedTouches[i];
|
|
745
|
+
this.prev.delete(touch.identifier);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
private touchMove = (evt: TouchEvent) => {
|
|
749
|
+
if (evt.defaultPrevented) return;
|
|
750
|
+
if (!this.isActive) return;
|
|
751
|
+
|
|
752
|
+
if (evt.touches.length === 1) {
|
|
753
|
+
// if we had multiple touches before due to e.g. pinching / rotating
|
|
754
|
+
// and stopping one of the touches, we don't want to move the scene suddenly
|
|
755
|
+
// this will be resettet when all touches stop
|
|
756
|
+
if (this._didMultitouch) {
|
|
757
|
+
return;
|
|
758
|
+
}
|
|
759
|
+
const touch = evt.touches[0];
|
|
760
|
+
const prev = this.prev.get(touch.identifier);
|
|
761
|
+
if (!prev || prev.ignore) return;
|
|
762
|
+
const pos = this.getPositionOnPlane(touch.clientX, touch.clientY);
|
|
763
|
+
const dx = pos.x - prev.x;
|
|
764
|
+
const dy = pos.z - prev.z;
|
|
765
|
+
if (dx === 0 && dy === 0) return;
|
|
766
|
+
if (this.oneFingerDrag)
|
|
767
|
+
this.addMovement(dx, dy);
|
|
768
|
+
prev.x = pos.x;
|
|
769
|
+
prev.z = pos.z;
|
|
770
|
+
prev.screenx = touch.clientX;
|
|
771
|
+
prev.screeny = touch.clientY;
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
774
|
+
else if (evt.touches.length === 2) {
|
|
775
|
+
this._didMultitouch = true;
|
|
776
|
+
const touch1 = evt.touches[0];
|
|
777
|
+
const touch2 = evt.touches[1];
|
|
778
|
+
const prev1 = this.prev.get(touch1.identifier);
|
|
779
|
+
const prev2 = this.prev.get(touch2.identifier);
|
|
780
|
+
if (!prev1 || !prev2) return;
|
|
781
|
+
|
|
782
|
+
if (this.twoFingerRotate) {
|
|
783
|
+
const angle1 = Math.atan2(touch1.clientY - touch2.clientY, touch1.clientX - touch2.clientX);
|
|
784
|
+
const lastAngle = Math.atan2(prev1.screeny - prev2.screeny, prev1.screenx - prev2.screenx);
|
|
785
|
+
const angleDiff = angle1 - lastAngle;
|
|
786
|
+
if (Math.abs(angleDiff) > 0.001) {
|
|
787
|
+
this.addRotation(angleDiff);
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
if (this.twoFingerScale) {
|
|
792
|
+
const distx = touch1.clientX - touch2.clientX;
|
|
793
|
+
const disty = touch1.clientY - touch2.clientY;
|
|
794
|
+
const dist = Math.sqrt(distx * distx + disty * disty);
|
|
795
|
+
const lastDistx = prev1.screenx - prev2.screenx;
|
|
796
|
+
const lastDisty = prev1.screeny - prev2.screeny;
|
|
797
|
+
const lastDist = Math.sqrt(lastDistx * lastDistx + lastDisty * lastDisty);
|
|
798
|
+
const distDiff = dist - lastDist;
|
|
799
|
+
if (Math.abs(distDiff) > 2) {
|
|
800
|
+
this.addScale(distDiff)
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
prev1.screenx = touch1.clientX;
|
|
805
|
+
prev1.screeny = touch1.clientY;
|
|
806
|
+
prev2.screenx = touch2.clientX;
|
|
807
|
+
prev2.screeny = touch2.clientY;
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
private readonly _raycaster: Raycaster = new Raycaster();
|
|
812
|
+
private readonly _intersection: Vector3 = new Vector3();
|
|
813
|
+
private readonly _screenPos: Vector3 = new Vector3();
|
|
814
|
+
|
|
815
|
+
private getPositionOnPlane(tx: number, ty: number): Vector3 {
|
|
816
|
+
const camera = this.context.mainCamera!;
|
|
817
|
+
this._screenPos.x = (tx / window.innerWidth) * 2 - 1;
|
|
818
|
+
this._screenPos.y = -(ty / window.innerHeight) * 2 + 1;
|
|
819
|
+
this._screenPos.z = 1;
|
|
820
|
+
|
|
821
|
+
this._screenPos.unproject(camera);
|
|
822
|
+
this._raycaster.set(camera.position, this._screenPos.sub(camera.position));
|
|
823
|
+
this._raycaster.ray.intersectPlane(this.plane, this._intersection);
|
|
824
|
+
return this._intersection;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
private addMovement(dx: number, dz: number) {
|
|
828
|
+
// this.translate.x -= dx;
|
|
829
|
+
// this.translate.z -= dz;
|
|
830
|
+
// this._needsUpdate = true;
|
|
831
|
+
// return
|
|
832
|
+
|
|
833
|
+
// increase diff if the scene is scaled small
|
|
834
|
+
dx /= this._scale;
|
|
835
|
+
dz /= this._scale;
|
|
836
|
+
|
|
837
|
+
dx *= this.factor;
|
|
838
|
+
dz *= this.factor;
|
|
839
|
+
|
|
840
|
+
// apply it
|
|
841
|
+
this.offset.elements[12] += dx;
|
|
842
|
+
this.offset.elements[14] += dz;
|
|
843
|
+
if (dx !== 0 || dz !== 0)
|
|
844
|
+
this._hasChanged = true;
|
|
845
|
+
};
|
|
846
|
+
|
|
847
|
+
private readonly _tempMatrix: Matrix4 = new Matrix4();
|
|
848
|
+
|
|
849
|
+
private addScale(diff: number) {
|
|
850
|
+
diff /= window.innerWidth
|
|
851
|
+
diff *= -1;
|
|
852
|
+
|
|
853
|
+
// this.scale.x *= 1 + diff;
|
|
854
|
+
// this.scale.y *= 1 + diff;
|
|
855
|
+
// this.scale.z *= 1 + diff;
|
|
856
|
+
// this._needsUpdate = true;
|
|
857
|
+
// return;
|
|
858
|
+
|
|
859
|
+
|
|
860
|
+
// we use this factor to modify the translation factor (in apply movement)
|
|
861
|
+
this._scale *= 1 + diff;
|
|
862
|
+
// apply the scale
|
|
863
|
+
this._tempMatrix.makeScale(1 - diff, 1 - diff, 1 - diff);
|
|
864
|
+
this.offset.premultiply(this._tempMatrix);
|
|
865
|
+
if (diff !== 0)
|
|
866
|
+
this._hasChanged = true;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
|
|
870
|
+
private addRotation(rot: number) {
|
|
871
|
+
rot *= -1;
|
|
872
|
+
// this.rotation.multiply(new Quaternion().setFromAxisAngle(WebXRSessionRootUserInput.up, rot));
|
|
873
|
+
// this._needsUpdate = true;
|
|
874
|
+
// return;
|
|
875
|
+
this._tempMatrix.makeRotationY(rot);
|
|
876
|
+
this.offset.premultiply(this._tempMatrix);
|
|
877
|
+
if (rot !== 0)
|
|
878
|
+
this._hasChanged = true;
|
|
879
|
+
}
|
|
880
|
+
}
|