@needle-tools/engine 4.7.1 → 4.7.2-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3782 -3782
- package/LICENSE.md +10 -10
- package/README.md +64 -64
- package/components.needle.json +1 -1
- package/dist/generateMeshBVH.worker-Cdfpaq5W.js +25 -0
- package/dist/gltf-progressive-YjtQYFa9.js +1052 -0
- package/dist/gltf-progressive-yOP1mp5W.min.js +8 -0
- package/dist/gltf-progressive-zdhlW609.umd.cjs +8 -0
- package/dist/{needle-engine.bundle-CN9UC6Ju.min.js → needle-engine.bundle-BhDF-YSv.min.js} +65 -65
- package/dist/{needle-engine.bundle-B7M9iBIa.umd.cjs → needle-engine.bundle-D2myV4E4.umd.cjs} +61 -61
- package/dist/{needle-engine.bundle-BpCihhaP.js → needle-engine.bundle-gp00DTS4.js} +641 -641
- package/dist/needle-engine.d.ts +129 -130
- 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-CjW23fio.umd.cjs → postprocessing-8AQTeZsr.umd.cjs} +2 -2
- package/dist/{postprocessing-xYQWCHFu.min.js → postprocessing-BDScN9yu.min.js} +2 -2
- package/dist/{postprocessing-DYLNOL3W.js → postprocessing-BkxN_08g.js} +3 -3
- package/dist/{three-DuDKwKB8.min.js → three-Boa-jOq-.min.js} +33 -33
- package/dist/{three-DrqIzZTH.js → three-Bz6X1mrw.js} +4198 -4198
- package/dist/{three-B_hneGZr.umd.cjs → three-DMrv-4ar.umd.cjs} +4 -4
- package/dist/{three-examples-X3OadjXB.umd.cjs → three-examples-C7ryg8vN.umd.cjs} +3 -3
- package/dist/{three-examples-DaDLBuy6.min.js → three-examples-DuVhxqft.min.js} +14 -14
- package/dist/{three-examples-B50TT3Iu.js → three-examples-GggCDHv0.js} +5 -5
- package/dist/{three-mesh-ui-CxuWt7m-.js → three-mesh-ui-CLNOfsWn.js} +1 -1
- package/dist/{three-mesh-ui-B3p3gyUz.min.js → three-mesh-ui-CY6Izc7C.min.js} +1 -1
- package/dist/{three-mesh-ui-CQiIQIlA.umd.cjs → three-mesh-ui-CwlN0FUC.umd.cjs} +1 -1
- package/dist/{vendor-BmYIgaS1.js → vendor-BSD1RQIh.js} +3 -3
- package/dist/{vendor-Cavtu3CP.umd.cjs → vendor-DHr4aqIZ.umd.cjs} +3 -3
- package/dist/{vendor-BlSxe9JJ.min.js → vendor-zxXa3Dmr.min.js} +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 +164 -164
- package/lib/engine/engine_addressables.js +601 -601
- 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 +1673 -1673
- 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 +101 -101
- 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 +35 -35
- package/lib/engine/engine_lods.js +160 -160
- package/lib/engine/engine_lods.js.map +1 -1
- 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 +788 -788
- 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 +123 -123
- 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/RendererInstancing.js.map +1 -1
- 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 +59 -59
- 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 +494 -494
- 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/logger.js +327 -327
- 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 +124 -124
- package/plugins/types/vite.d.ts +13 -13
- package/plugins/types/webmanifest.d.ts +32 -32
- package/plugins/vite/alias.js +189 -189
- 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 +147 -147
- package/plugins/vite/license.js +56 -56
- package/plugins/vite/local-files.js +440 -440
- package/plugins/vite/logger.client.js +272 -272
- package/plugins/vite/logger.js +100 -100
- package/plugins/vite/materialx.js +31 -31
- 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 +32 -32
- 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 +671 -671
- 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 +1824 -1824
- 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 +125 -125
- 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 +186 -186
- 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 +928 -928
- 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 +138 -138
- 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 +64 -64
- 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 +572 -572
- 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/dist/api.js +17 -0
- package/src/engine-schemes/dist/api.js.meta +7 -0
- package/src/engine-schemes/dist/schemes.js +25 -0
- package/src/engine-schemes/dist/schemes.js.meta +7 -0
- package/src/engine-schemes/dist/synced-camera-model.js +74 -0
- package/src/engine-schemes/dist/synced-camera-model.js.meta +7 -0
- package/src/engine-schemes/dist/synced-transform-model.js +73 -0
- package/src/engine-schemes/dist/synced-transform-model.js.meta +7 -0
- package/src/engine-schemes/dist/transform.js +46 -0
- package/src/engine-schemes/dist/transform.js.meta +7 -0
- package/src/engine-schemes/dist/vec2.js +32 -0
- package/src/engine-schemes/dist/vec2.js.meta +7 -0
- package/src/engine-schemes/dist/vec3.js +36 -0
- package/src/engine-schemes/dist/vec3.js.meta +7 -0
- package/src/engine-schemes/dist/vec4.js +40 -0
- package/src/engine-schemes/dist/vec4.js.meta +7 -0
- package/src/engine-schemes/dist/vr-user-state-buffer.js +110 -0
- package/src/engine-schemes/dist/vr-user-state-buffer.js.meta +7 -0
- 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-BaNp_Xtp.js +0 -25
- package/dist/gltf-progressive-60Qk5ebF.min.js +0 -8
- package/dist/gltf-progressive-DM5ZiecW.js +0 -1060
- package/dist/gltf-progressive-wxtaVmio.umd.cjs +0 -8
|
@@ -1,745 +1,745 @@
|
|
|
1
|
-
import { BatchedMesh, Color, Matrix4, MeshStandardMaterial, RawShaderMaterial } from "three";
|
|
2
|
-
import { isDevEnvironment, showBalloonError } from "../engine/debug/index.js";
|
|
3
|
-
import { Gizmos } from "../engine/engine_gizmos.js";
|
|
4
|
-
import { $instancingAutoUpdateBounds, $instancingRenderer, NEED_UPDATE_INSTANCE_KEY } from "../engine/engine_instancing.js";
|
|
5
|
-
import { getParam, makeIdFromRandomWords } from "../engine/engine_utils.js";
|
|
6
|
-
import { NEEDLE_progressive } from "../engine/extensions/index.js";
|
|
7
|
-
import { GameObject } from "./Component.js";
|
|
8
|
-
const debugInstancing = getParam("debuginstancing");
|
|
9
|
-
;
|
|
10
|
-
/**
|
|
11
|
-
* Handles instancing for Needle Engine.
|
|
12
|
-
*/
|
|
13
|
-
export class InstancingHandler {
|
|
14
|
-
static instance = new InstancingHandler();
|
|
15
|
-
/** This is the initial instance count when creating a new instancing structure.
|
|
16
|
-
* Override this and the number of max instances that you expect for a given object.
|
|
17
|
-
* The larger the value the more objects can be added without having to resize but it will also consume more memory.
|
|
18
|
-
* (The instancing mesh renderer will grow x2 if the max instance count is reached)
|
|
19
|
-
* @default 4
|
|
20
|
-
* @returns The initial instance count
|
|
21
|
-
* */
|
|
22
|
-
static getStartInstanceCount = (_obj) => {
|
|
23
|
-
return 4;
|
|
24
|
-
};
|
|
25
|
-
objs = [];
|
|
26
|
-
setup(renderer, obj, context, handlesArray, args, level = 0) {
|
|
27
|
-
// make sure setting casting settings are applied so when we add the mesh to the InstancedMesh we can ask for the correct cast shadow setting
|
|
28
|
-
renderer.applySettings(obj);
|
|
29
|
-
const res = this.tryCreateOrAddInstance(obj, context, args);
|
|
30
|
-
if (res) {
|
|
31
|
-
if (handlesArray === null)
|
|
32
|
-
handlesArray = [];
|
|
33
|
-
handlesArray.push(res);
|
|
34
|
-
// load texture lods
|
|
35
|
-
NEEDLE_progressive.assignTextureLOD(res.renderer.material, 0);
|
|
36
|
-
// Load mesh lods
|
|
37
|
-
// TODO: technically for multi meshes we do this work multiple times (we search for meshes in children and then use the renderer sharedMeshes... that doesnt make sense)
|
|
38
|
-
for (let i = 0; i < renderer.sharedMeshes.length; i++) {
|
|
39
|
-
const mesh = renderer.sharedMeshes[i];
|
|
40
|
-
const geometry = mesh.geometry;
|
|
41
|
-
NEEDLE_progressive.assignMeshLOD(mesh, 0).then(lod => {
|
|
42
|
-
if (lod && renderer.activeAndEnabled && geometry != lod) {
|
|
43
|
-
res.setGeometry(lod);
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
else if (level <= 0 && obj.type !== "Mesh") {
|
|
49
|
-
const nextLevel = level + 1;
|
|
50
|
-
for (const ch of obj.children) {
|
|
51
|
-
handlesArray = this.setup(renderer, ch, context, handlesArray, args, nextLevel);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
if (level === 0) {
|
|
55
|
-
// For multi material objects we only want to track the root object's matrix
|
|
56
|
-
if (args.useMatrixWorldAutoUpdate && handlesArray && handlesArray.length >= 0) {
|
|
57
|
-
this.autoUpdateInstanceMatrix(obj);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return handlesArray;
|
|
61
|
-
}
|
|
62
|
-
tryCreateOrAddInstance(obj, context, args) {
|
|
63
|
-
if (obj.type === "Mesh") {
|
|
64
|
-
const index = args.foundMeshes;
|
|
65
|
-
args.foundMeshes += 1;
|
|
66
|
-
if (!args.rend.enableInstancing)
|
|
67
|
-
return null;
|
|
68
|
-
if (args.rend.enableInstancing === true) {
|
|
69
|
-
// instancing is enabled globally
|
|
70
|
-
// continue....
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
if (index >= args.rend.enableInstancing.length) {
|
|
74
|
-
if (debugInstancing)
|
|
75
|
-
console.error("Something is wrong with instance setup", obj, args.rend.enableInstancing, index);
|
|
76
|
-
return null;
|
|
77
|
-
}
|
|
78
|
-
if (!args.rend.enableInstancing[index]) {
|
|
79
|
-
// instancing is disabled
|
|
80
|
-
// console.log("Instancing is disabled", obj);
|
|
81
|
-
return null;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
// instancing is enabled:
|
|
85
|
-
const mesh = obj;
|
|
86
|
-
// const geo = mesh.geometry as BufferGeometry;
|
|
87
|
-
const mat = mesh.material;
|
|
88
|
-
for (const i of this.objs) {
|
|
89
|
-
if (!i.canAdd(mesh.geometry, mat))
|
|
90
|
-
continue;
|
|
91
|
-
const handle = i.addInstance(mesh);
|
|
92
|
-
return handle;
|
|
93
|
-
}
|
|
94
|
-
let maxInstances = InstancingHandler.getStartInstanceCount(obj);
|
|
95
|
-
if (!maxInstances || maxInstances < 0) {
|
|
96
|
-
maxInstances = 4;
|
|
97
|
-
}
|
|
98
|
-
let name = obj.name;
|
|
99
|
-
if (!name?.length)
|
|
100
|
-
name = makeIdFromRandomWords();
|
|
101
|
-
const i = new InstancedMeshRenderer(name, mesh.geometry, mat, maxInstances, context);
|
|
102
|
-
this.objs.push(i);
|
|
103
|
-
const handle = i.addInstance(mesh);
|
|
104
|
-
return handle;
|
|
105
|
-
}
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
108
|
-
autoUpdateInstanceMatrix(obj) {
|
|
109
|
-
const original = obj.matrixWorld["multiplyMatrices"].bind(obj.matrixWorld);
|
|
110
|
-
const previousMatrix = obj.matrixWorld.clone();
|
|
111
|
-
const matrixChangeWrapper = (a, b) => {
|
|
112
|
-
const newMatrixWorld = original(a, b);
|
|
113
|
-
if (obj[NEED_UPDATE_INSTANCE_KEY] || previousMatrix.equals(newMatrixWorld) === false) {
|
|
114
|
-
previousMatrix.copy(newMatrixWorld);
|
|
115
|
-
obj[NEED_UPDATE_INSTANCE_KEY] = true;
|
|
116
|
-
}
|
|
117
|
-
return newMatrixWorld;
|
|
118
|
-
};
|
|
119
|
-
obj.matrixWorld["multiplyMatrices"] = matrixChangeWrapper;
|
|
120
|
-
// wrap matrixWorldNeedsUpdate
|
|
121
|
-
// let originalMatrixWorldNeedsUpdate = obj.matrixWorldNeedsUpdate;
|
|
122
|
-
// Object.defineProperty(obj, "matrixWorldNeedsUpdate", {
|
|
123
|
-
// get: () => {
|
|
124
|
-
// return originalMatrixWorldNeedsUpdate;
|
|
125
|
-
// },
|
|
126
|
-
// set: (value: boolean) => {
|
|
127
|
-
// if(value) console.warn("SET MATRIX WORLD NEEDS UPDATE");
|
|
128
|
-
// originalMatrixWorldNeedsUpdate = value;
|
|
129
|
-
// }
|
|
130
|
-
// });
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* The instance handle is used to interface with the mesh that is rendered using instancing.
|
|
135
|
-
*/
|
|
136
|
-
export class InstanceHandle {
|
|
137
|
-
static all = [];
|
|
138
|
-
/** The name of the object */
|
|
139
|
-
get name() {
|
|
140
|
-
return this.object.name;
|
|
141
|
-
}
|
|
142
|
-
get isActive() {
|
|
143
|
-
return this.__instanceIndex >= 0;
|
|
144
|
-
}
|
|
145
|
-
get vertexCount() {
|
|
146
|
-
return this.object.geometry.attributes.position.count;
|
|
147
|
-
}
|
|
148
|
-
get maxVertexCount() {
|
|
149
|
-
// we get the max of the estimated MAX lod vertex count and the actual vertex count
|
|
150
|
-
return Math.max(this.meshInformation.vertexCount, this.vertexCount);
|
|
151
|
-
}
|
|
152
|
-
get reservedVertexCount() {
|
|
153
|
-
return this.__reservedVertexRange;
|
|
154
|
-
}
|
|
155
|
-
get indexCount() {
|
|
156
|
-
return this.object.geometry.index ? this.object.geometry.index.count : 0;
|
|
157
|
-
}
|
|
158
|
-
get maxIndexCount() {
|
|
159
|
-
// we get the max of the estimated MAX lod index count and the actual index count
|
|
160
|
-
return Math.max(this.meshInformation.indexCount, this.indexCount);
|
|
161
|
-
}
|
|
162
|
-
get reservedIndexCount() {
|
|
163
|
-
return this.__reservedIndexRange;
|
|
164
|
-
}
|
|
165
|
-
/** The object that is being instanced */
|
|
166
|
-
object;
|
|
167
|
-
/** The instancer/BatchedMesh that is rendering this object*/
|
|
168
|
-
renderer;
|
|
169
|
-
/** @internal */
|
|
170
|
-
__instanceIndex = -1;
|
|
171
|
-
/** @internal */
|
|
172
|
-
__reservedVertexRange = 0;
|
|
173
|
-
/** @internal */
|
|
174
|
-
__reservedIndexRange = 0;
|
|
175
|
-
__geometryIndex = -1;
|
|
176
|
-
/** The mesh information of the object - this tries to also calculate the LOD info */
|
|
177
|
-
meshInformation;
|
|
178
|
-
constructor(originalObject, instancer) {
|
|
179
|
-
this.__instanceIndex = -1;
|
|
180
|
-
this.object = originalObject;
|
|
181
|
-
this.renderer = instancer;
|
|
182
|
-
originalObject[$instancingRenderer] = instancer;
|
|
183
|
-
// TODO: this doesn't have LOD information *yet* in some cases - hence we can not rely on it for the max vertex counts
|
|
184
|
-
this.meshInformation = getMeshInformation(originalObject.geometry);
|
|
185
|
-
InstanceHandle.all.push(this);
|
|
186
|
-
}
|
|
187
|
-
/** Calculates the mesh information again
|
|
188
|
-
* @returns true if the vertex count or index count has changed
|
|
189
|
-
*/
|
|
190
|
-
updateMeshInformation() {
|
|
191
|
-
const newMeshInformation = getMeshInformation(this.object.geometry);
|
|
192
|
-
const oldVertexCount = this.meshInformation.vertexCount;
|
|
193
|
-
const oldIndexCount = this.meshInformation.indexCount;
|
|
194
|
-
Object.assign(this.meshInformation, newMeshInformation);
|
|
195
|
-
return oldVertexCount !== this.meshInformation.vertexCount || oldIndexCount !== this.meshInformation.indexCount;
|
|
196
|
-
}
|
|
197
|
-
/** Updates the matrix from the rendered object. Will also call updateWorldMatrix internally */
|
|
198
|
-
updateInstanceMatrix(updateChildren = false, updateMatrix = true) {
|
|
199
|
-
if (this.__instanceIndex < 0)
|
|
200
|
-
return;
|
|
201
|
-
if (updateMatrix)
|
|
202
|
-
this.object.updateWorldMatrix(true, updateChildren);
|
|
203
|
-
this.renderer.updateInstance(this.object.matrixWorld, this.__instanceIndex);
|
|
204
|
-
}
|
|
205
|
-
/** Updates the matrix of the instance */
|
|
206
|
-
setMatrix(matrix) {
|
|
207
|
-
if (this.__instanceIndex < 0)
|
|
208
|
-
return;
|
|
209
|
-
this.renderer.updateInstance(matrix, this.__instanceIndex);
|
|
210
|
-
}
|
|
211
|
-
/** Can be used to change the geometry of this instance */
|
|
212
|
-
setGeometry(geo) {
|
|
213
|
-
if (this.__geometryIndex < 0)
|
|
214
|
-
return false;
|
|
215
|
-
const self = this;
|
|
216
|
-
if (this.vertexCount > this.__reservedVertexRange) {
|
|
217
|
-
return handleInvalidRange(`Instancing: Can not update geometry (${this.name}), reserved vertex range is too small: ${this.__reservedVertexRange.toLocaleString()} < ${this.vertexCount.toLocaleString()} vertices for ${this.name}`);
|
|
218
|
-
}
|
|
219
|
-
if (this.indexCount > this.__reservedIndexRange) {
|
|
220
|
-
return handleInvalidRange(`Instancing: Can not update geometry (${this.name}), reserved index range is too small: ${this.__reservedIndexRange.toLocaleString()} < ${this.indexCount.toLocaleString()} indices for ${this.name}`);
|
|
221
|
-
}
|
|
222
|
-
return this.renderer.updateGeometry(geo, this.__geometryIndex);
|
|
223
|
-
function handleInvalidRange(error) {
|
|
224
|
-
if (self.updateMeshInformation()) {
|
|
225
|
-
// Gizmos.DrawWireSphere(self.object.worldPosition, .5, 0xff0000, 5);
|
|
226
|
-
self.renderer.remove(self, true);
|
|
227
|
-
// Gizmos.DrawWireSphere(self.object.worldPosition, .5, 0x33ff00, 5);
|
|
228
|
-
// self.object.scale.multiplyScalar(10);
|
|
229
|
-
if (self.renderer.add(self)) {
|
|
230
|
-
return true;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
if (isDevEnvironment() || debugInstancing) {
|
|
234
|
-
console.error(error);
|
|
235
|
-
}
|
|
236
|
-
return false;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
/** Adds this object to the instancing renderer (effectively activating instancing) */
|
|
240
|
-
add() {
|
|
241
|
-
if (this.__instanceIndex >= 0)
|
|
242
|
-
return;
|
|
243
|
-
this.renderer.add(this);
|
|
244
|
-
GameObject.markAsInstancedRendered(this.object, true);
|
|
245
|
-
}
|
|
246
|
-
/** Removes this object from the instancing renderer
|
|
247
|
-
* @param delete_ If true, the instance handle will be removed from the global list
|
|
248
|
-
*/
|
|
249
|
-
remove(delete_) {
|
|
250
|
-
if (this.__instanceIndex < 0)
|
|
251
|
-
return;
|
|
252
|
-
this.renderer.remove(this, delete_);
|
|
253
|
-
GameObject.markAsInstancedRendered(this.object, false);
|
|
254
|
-
if (delete_) {
|
|
255
|
-
const i = InstanceHandle.all.indexOf(this);
|
|
256
|
-
if (i >= 0) {
|
|
257
|
-
InstanceHandle.all.splice(i, 1);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
class InstancedMeshRenderer {
|
|
263
|
-
/** The three instanced mesh
|
|
264
|
-
* @link https://threejs.org/docs/#api/en/objects/InstancedMesh
|
|
265
|
-
*/
|
|
266
|
-
get batchedMesh() {
|
|
267
|
-
return this._batchedMesh;
|
|
268
|
-
}
|
|
269
|
-
get visible() {
|
|
270
|
-
return this._batchedMesh.visible;
|
|
271
|
-
}
|
|
272
|
-
set visible(val) {
|
|
273
|
-
this._batchedMesh.visible = val;
|
|
274
|
-
}
|
|
275
|
-
get castShadow() {
|
|
276
|
-
return this._batchedMesh.castShadow;
|
|
277
|
-
}
|
|
278
|
-
set castShadow(val) {
|
|
279
|
-
this._batchedMesh.castShadow = val;
|
|
280
|
-
}
|
|
281
|
-
set receiveShadow(val) {
|
|
282
|
-
this._batchedMesh.receiveShadow = val;
|
|
283
|
-
}
|
|
284
|
-
/** If true, the instancer is allowed to grow when the max instance count is reached */
|
|
285
|
-
allowResize = true;
|
|
286
|
-
/** The name of the instancer */
|
|
287
|
-
name = "";
|
|
288
|
-
/** The added geometry */
|
|
289
|
-
geometry;
|
|
290
|
-
/** The material used for the instanced mesh */
|
|
291
|
-
material;
|
|
292
|
-
/** The current number of instances */
|
|
293
|
-
get count() { return this._currentInstanceCount; }
|
|
294
|
-
/** Update the bounding box and sphere of the instanced mesh
|
|
295
|
-
* @param box If true, update the bounding box
|
|
296
|
-
* @param sphere If true, update the bounding sphere
|
|
297
|
-
*/
|
|
298
|
-
updateBounds(box = true, sphere = true) {
|
|
299
|
-
this._needUpdateBounds = false;
|
|
300
|
-
if (box)
|
|
301
|
-
this._batchedMesh.computeBoundingBox();
|
|
302
|
-
if (sphere)
|
|
303
|
-
this._batchedMesh.computeBoundingSphere();
|
|
304
|
-
if (debugInstancing && this._batchedMesh.boundingSphere) {
|
|
305
|
-
const sphere = this._batchedMesh.boundingSphere;
|
|
306
|
-
// const worldPos = this._batchedMesh.worldPosition.add(sphere.center);
|
|
307
|
-
// const worldRadius = sphere!.radius;
|
|
308
|
-
Gizmos.DrawWireSphere(sphere.center, sphere.radius, 0x00ff00);
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
_context;
|
|
312
|
-
_batchedMesh;
|
|
313
|
-
_handles = [];
|
|
314
|
-
_geometryIds = new Map();
|
|
315
|
-
_maxInstanceCount;
|
|
316
|
-
_currentInstanceCount = 0;
|
|
317
|
-
_currentVertexCount = 0;
|
|
318
|
-
_currentIndexCount = 0;
|
|
319
|
-
_maxVertexCount;
|
|
320
|
-
_maxIndexCount;
|
|
321
|
-
static nullMatrix = new Matrix4();
|
|
322
|
-
/** Check if the geometry can be added to this instancer
|
|
323
|
-
* @param geometry The geometry to check
|
|
324
|
-
* @param material The material of the geometry
|
|
325
|
-
* @returns true if the geometry can be added
|
|
326
|
-
*/
|
|
327
|
-
canAdd(geometry, material) {
|
|
328
|
-
if (this._maxVertexCount > 10_000_000)
|
|
329
|
-
return false;
|
|
330
|
-
// The material instance must match
|
|
331
|
-
// perhaps at some point later we *could* check if it's the same shader and properties but this would be risky
|
|
332
|
-
if (material !== this.material) {
|
|
333
|
-
const canMergeMaterial = false;
|
|
334
|
-
// if (material.type === this.material.type) {
|
|
335
|
-
// switch (material.type) {
|
|
336
|
-
// case "MeshStandardMaterial":
|
|
337
|
-
// // check if the material properties are the same
|
|
338
|
-
// const m0 = this.material as MeshStandardMaterial;
|
|
339
|
-
// const m1 = material as MeshStandardMaterial;
|
|
340
|
-
// if(m0.map !== m1.map) return false;
|
|
341
|
-
// // if(m0.color.equals(m1.color) === false) return false;
|
|
342
|
-
// if(m0.roughness !== m1.roughness) return false;
|
|
343
|
-
// if(m0.metalness !== m1.metalness) return false;
|
|
344
|
-
// if(m0.envMap !== m1.envMap) return false;
|
|
345
|
-
// if(m0.envMapIntensity !== m1.envMapIntensity) return false;
|
|
346
|
-
// if(m0.lightMap !== m1.lightMap) return false;
|
|
347
|
-
// if(m0.lightMapIntensity !== m1.lightMapIntensity) return false;
|
|
348
|
-
// if(m0.aoMap !== m1.aoMap) return false;
|
|
349
|
-
// if(m0.aoMapIntensity !== m1.aoMapIntensity) return false;
|
|
350
|
-
// if(m0.emissive.equals(m1.emissive) === false) return false;
|
|
351
|
-
// if(m0.emissiveIntensity !== m1.emissiveIntensity) return false;
|
|
352
|
-
// if(m0.emissiveMap !== m1.emissiveMap) return false;
|
|
353
|
-
// if(m0.bumpMap !== m1.bumpMap) return false;
|
|
354
|
-
// if(m0.bumpScale !== m1.bumpScale) return false;
|
|
355
|
-
// if(m0.normalMap !== m1.normalMap) return false;
|
|
356
|
-
// if(m0.normalScale.equals(m1.normalScale) === false) return false;
|
|
357
|
-
// if(m0.displacementMap !== m1.displacementMap) return false;
|
|
358
|
-
// if(m0.displacementScale !== m1.displacementScale) return false;
|
|
359
|
-
// if(m0.displacementBias !== m1.displacementBias) return false;
|
|
360
|
-
// if(m0.roughnessMap !== m1.roughnessMap) return false;
|
|
361
|
-
// if(m0.metalnessMap !== m1.metalnessMap) return false;
|
|
362
|
-
// if(m0.alphaMap !== m1.alphaMap) return false;
|
|
363
|
-
// if(m0.envMapIntensity !== m1.envMapIntensity) return false;
|
|
364
|
-
// canMergeMaterial = true;
|
|
365
|
-
// break;
|
|
366
|
-
// }
|
|
367
|
-
// }
|
|
368
|
-
if (!canMergeMaterial) {
|
|
369
|
-
return false;
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
// if(this.geometry !== _geometry) return false;
|
|
373
|
-
// console.log(geometry.name, geometry.uuid);
|
|
374
|
-
if (!this.validateGeometry(geometry))
|
|
375
|
-
return false;
|
|
376
|
-
// const validationMethod = this.inst["_validateGeometry"];
|
|
377
|
-
// if (!validationMethod) throw new Error("InstancedMesh does not have a _validateGeometry method");
|
|
378
|
-
// try {
|
|
379
|
-
// validationMethod.call(this.inst, _geometry);
|
|
380
|
-
// }
|
|
381
|
-
// catch (err) {
|
|
382
|
-
// // console.error(err);
|
|
383
|
-
// return false;
|
|
384
|
-
// }
|
|
385
|
-
const hasSpace = !this.mustGrow(geometry);
|
|
386
|
-
if (hasSpace)
|
|
387
|
-
return true;
|
|
388
|
-
if (this.allowResize)
|
|
389
|
-
return true;
|
|
390
|
-
return false;
|
|
391
|
-
}
|
|
392
|
-
_needUpdateBounds = false;
|
|
393
|
-
_debugMaterial = null;
|
|
394
|
-
constructor(name, geo, material, initialMaxCount, context) {
|
|
395
|
-
this.name = name;
|
|
396
|
-
this.geometry = geo;
|
|
397
|
-
this.material = material;
|
|
398
|
-
this._context = context;
|
|
399
|
-
this._maxInstanceCount = Math.max(2, initialMaxCount);
|
|
400
|
-
if (debugInstancing) {
|
|
401
|
-
this._debugMaterial = createDebugMaterial();
|
|
402
|
-
}
|
|
403
|
-
const estimate = this.tryEstimateVertexCountSize(this._maxInstanceCount, [geo], initialMaxCount);
|
|
404
|
-
this._maxVertexCount = estimate.vertexCount;
|
|
405
|
-
this._maxIndexCount = estimate.indexCount;
|
|
406
|
-
this._batchedMesh = new BatchedMesh(this._maxInstanceCount, this._maxVertexCount, this._maxIndexCount, this._debugMaterial ?? this.material);
|
|
407
|
-
// this.inst = new InstancedMesh(geo, material, count);
|
|
408
|
-
this._batchedMesh[$instancingAutoUpdateBounds] = true;
|
|
409
|
-
// this.inst.count = 0;
|
|
410
|
-
this._batchedMesh.visible = true;
|
|
411
|
-
this._context.scene.add(this._batchedMesh);
|
|
412
|
-
// Not handled by RawShaderMaterial, so we need to set the define explicitly.
|
|
413
|
-
// Edge case: theoretically some users of the material could use it in an
|
|
414
|
-
// instanced fashion, and some others not. In that case, the material would not
|
|
415
|
-
// be able to be shared between the two use cases. We could probably add a
|
|
416
|
-
// onBeforeRender call for the InstancedMesh and set the define there.
|
|
417
|
-
// Same would apply if we support skinning -
|
|
418
|
-
// there we would have to split instanced batches so that the ones using skinning
|
|
419
|
-
// are all in the same batch.
|
|
420
|
-
if (material instanceof RawShaderMaterial) {
|
|
421
|
-
material.defines["USE_INSTANCING"] = true;
|
|
422
|
-
material.needsUpdate = true;
|
|
423
|
-
}
|
|
424
|
-
context.pre_render_callbacks.push(this.onBeforeRender);
|
|
425
|
-
context.post_render_callbacks.push(this.onAfterRender);
|
|
426
|
-
if (debugInstancing) {
|
|
427
|
-
console.log(`Instanced renderer created with ${this._maxInstanceCount} instances, ${this._maxVertexCount} max vertices and ${this._maxIndexCount} max indices for \"${name}\"`);
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
dispose() {
|
|
431
|
-
if (debugInstancing)
|
|
432
|
-
console.warn("Dispose instanced renderer", this.name);
|
|
433
|
-
this._context.scene.remove(this._batchedMesh);
|
|
434
|
-
this._batchedMesh.dispose();
|
|
435
|
-
this._batchedMesh = null;
|
|
436
|
-
this._handles = [];
|
|
437
|
-
}
|
|
438
|
-
addInstance(obj) {
|
|
439
|
-
const handle = new InstanceHandle(obj, this);
|
|
440
|
-
if (obj.castShadow === true && this._batchedMesh.castShadow === false) {
|
|
441
|
-
this._batchedMesh.castShadow = true;
|
|
442
|
-
}
|
|
443
|
-
if (obj.receiveShadow === true && this._batchedMesh.receiveShadow === false) {
|
|
444
|
-
this._batchedMesh.receiveShadow = true;
|
|
445
|
-
}
|
|
446
|
-
try {
|
|
447
|
-
this.add(handle);
|
|
448
|
-
}
|
|
449
|
-
catch (e) {
|
|
450
|
-
console.error(`Failed adding mesh to instancing (object name: \"${obj.name}\", instances: ${this._currentInstanceCount.toLocaleString()}/${this._maxInstanceCount.toLocaleString()}, vertices: ${this._currentVertexCount.toLocaleString()}/${this._maxVertexCount.toLocaleString()}, indices: ${this._currentIndexCount.toLocaleString()}/${this._maxIndexCount.toLocaleString()})\n`, e);
|
|
451
|
-
if (isDevEnvironment()) {
|
|
452
|
-
showBalloonError("Failed instancing mesh. See the browser console for details.");
|
|
453
|
-
debugger;
|
|
454
|
-
}
|
|
455
|
-
return null;
|
|
456
|
-
}
|
|
457
|
-
return handle;
|
|
458
|
-
}
|
|
459
|
-
add(handle) {
|
|
460
|
-
const geo = handle.object.geometry;
|
|
461
|
-
if (!geo || !geo.attributes) {
|
|
462
|
-
console.error("Cannot add object to instancing without geometry", handle.name);
|
|
463
|
-
return false;
|
|
464
|
-
}
|
|
465
|
-
if (this.mustGrow(geo)) {
|
|
466
|
-
if (this.allowResize) {
|
|
467
|
-
this.grow(geo);
|
|
468
|
-
}
|
|
469
|
-
else {
|
|
470
|
-
console.error("Cannot add instance, max count reached", this.name, this.count, this._maxInstanceCount);
|
|
471
|
-
return false;
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
handle.object.updateWorldMatrix(true, true);
|
|
475
|
-
this.addGeometry(handle);
|
|
476
|
-
this._handles[handle.__instanceIndex] = handle;
|
|
477
|
-
this._currentInstanceCount += 1;
|
|
478
|
-
this.markNeedsUpdate();
|
|
479
|
-
if (this._currentInstanceCount > 0)
|
|
480
|
-
this._batchedMesh.visible = true;
|
|
481
|
-
return true;
|
|
482
|
-
}
|
|
483
|
-
remove(handle, delete_) {
|
|
484
|
-
if (!handle) {
|
|
485
|
-
return;
|
|
486
|
-
}
|
|
487
|
-
if (handle.__instanceIndex < 0 || this._handles[handle.__instanceIndex] != handle || this._currentInstanceCount <= 0) {
|
|
488
|
-
// console.warn("Cannot remove instance, handle is invalid", handle.name);
|
|
489
|
-
return;
|
|
490
|
-
}
|
|
491
|
-
this.removeGeometry(handle, delete_);
|
|
492
|
-
this._handles[handle.__instanceIndex] = null;
|
|
493
|
-
handle.__instanceIndex = -1;
|
|
494
|
-
if (this._currentInstanceCount > 0) {
|
|
495
|
-
this._currentInstanceCount -= 1;
|
|
496
|
-
}
|
|
497
|
-
if (this._currentInstanceCount <= 0)
|
|
498
|
-
this._batchedMesh.visible = false;
|
|
499
|
-
this.markNeedsUpdate();
|
|
500
|
-
}
|
|
501
|
-
updateInstance(mat, index) {
|
|
502
|
-
this._batchedMesh.setMatrixAt(index, mat);
|
|
503
|
-
this.markNeedsUpdate();
|
|
504
|
-
}
|
|
505
|
-
updateGeometry(geo, geometryIndex) {
|
|
506
|
-
if (!this.validateGeometry(geo)) {
|
|
507
|
-
return false;
|
|
508
|
-
}
|
|
509
|
-
if (this.mustGrow()) {
|
|
510
|
-
this.grow(geo);
|
|
511
|
-
}
|
|
512
|
-
if (debugInstancing)
|
|
513
|
-
console.debug("[Instancing] UPDATE GEOMETRY at " + geometryIndex, this._batchedMesh["_geometryCount"], geo.name, getMeshInformation(geo), geo.attributes.position.count, geo.index ? geo.index.count : 0);
|
|
514
|
-
this._batchedMesh.setGeometryAt(geometryIndex, geo);
|
|
515
|
-
// for LOD mesh updates we need to make sure to save the geometry index
|
|
516
|
-
this._geometryIds.set(geo, geometryIndex);
|
|
517
|
-
this.markNeedsUpdate();
|
|
518
|
-
return true;
|
|
519
|
-
}
|
|
520
|
-
onBeforeRender = () => {
|
|
521
|
-
// ensure the instanced mesh is rendered / has correct layers
|
|
522
|
-
this._batchedMesh.layers.enableAll();
|
|
523
|
-
if (this._needUpdateBounds && this._batchedMesh[$instancingAutoUpdateBounds] === true) {
|
|
524
|
-
if (debugInstancing === "verbose")
|
|
525
|
-
console.log("Update instancing bounds", this.name, this._batchedMesh.matrixWorldNeedsUpdate);
|
|
526
|
-
this.updateBounds();
|
|
527
|
-
}
|
|
528
|
-
};
|
|
529
|
-
onAfterRender = () => {
|
|
530
|
-
// hide the instanced mesh again when its not being rendered (for raycasting we still use the original object)
|
|
531
|
-
this._batchedMesh.layers.disableAll();
|
|
532
|
-
};
|
|
533
|
-
validateGeometry(geometry) {
|
|
534
|
-
const batchGeometry = this.geometry;
|
|
535
|
-
for (const attributeName in batchGeometry.attributes) {
|
|
536
|
-
if (attributeName === "batchId") {
|
|
537
|
-
continue;
|
|
538
|
-
}
|
|
539
|
-
if (!geometry.hasAttribute(attributeName)) {
|
|
540
|
-
if (isDevEnvironment())
|
|
541
|
-
console.warn(`BatchedMesh: Added geometry missing "${attributeName}". All geometries must have consistent attributes.`);
|
|
542
|
-
// geometry.setAttribute(attributeName, batchGeometry.getAttribute(attributeName).clone());
|
|
543
|
-
return false;
|
|
544
|
-
// throw new Error(`BatchedMesh: Added geometry missing "${attributeName}". All geometries must have consistent attributes.`);
|
|
545
|
-
}
|
|
546
|
-
// const srcAttribute = geometry.getAttribute(attributeName);
|
|
547
|
-
// const dstAttribute = batchGeometry.getAttribute(attributeName);
|
|
548
|
-
// if (srcAttribute.itemSize !== dstAttribute.itemSize || srcAttribute.normalized !== dstAttribute.normalized) {
|
|
549
|
-
// if (debugInstancing) throw new Error('BatchedMesh: All attributes must have a consistent itemSize and normalized value.');
|
|
550
|
-
// return false;
|
|
551
|
-
// }
|
|
552
|
-
}
|
|
553
|
-
return true;
|
|
554
|
-
}
|
|
555
|
-
markNeedsUpdate() {
|
|
556
|
-
if (debugInstancing === "verbose") {
|
|
557
|
-
console.warn("Marking instanced mesh dirty", this.name);
|
|
558
|
-
}
|
|
559
|
-
this._needUpdateBounds = true;
|
|
560
|
-
// this.inst.instanceMatrix.needsUpdate = true;
|
|
561
|
-
}
|
|
562
|
-
/**
|
|
563
|
-
* @param geo The geometry to add (if none is provided it means the geometry is already added and just updated)
|
|
564
|
-
*/
|
|
565
|
-
mustGrow(geo) {
|
|
566
|
-
if (this.count >= this._maxInstanceCount)
|
|
567
|
-
return true;
|
|
568
|
-
if (!geo || !geo.attributes)
|
|
569
|
-
return false;
|
|
570
|
-
const meshInfo = getMeshInformation(geo);
|
|
571
|
-
const newVertexCount = meshInfo.vertexCount;
|
|
572
|
-
const newIndexCount = meshInfo.indexCount;
|
|
573
|
-
return this._currentVertexCount + newVertexCount > this._maxVertexCount || this._currentIndexCount + newIndexCount > this._maxIndexCount;
|
|
574
|
-
}
|
|
575
|
-
grow(geometry) {
|
|
576
|
-
const growFactor = 2;
|
|
577
|
-
const newSize = Math.ceil(this._maxInstanceCount * growFactor);
|
|
578
|
-
// create a new BatchedMesh instance
|
|
579
|
-
const estimatedSpace = this.tryEstimateVertexCountSize(newSize, [geometry]); // geometry.attributes.position.count;
|
|
580
|
-
// const indices = geometry.index ? geometry.index.count : 0;
|
|
581
|
-
const newMaxVertexCount = Math.max(this._maxVertexCount, estimatedSpace.vertexCount);
|
|
582
|
-
const newMaxIndexCount = Math.max(this._maxIndexCount, estimatedSpace.indexCount, Math.ceil(this._maxVertexCount * growFactor));
|
|
583
|
-
if (debugInstancing) {
|
|
584
|
-
const geometryInfo = getMeshInformation(geometry);
|
|
585
|
-
console.warn(`[Instancing] Growing Buffer\nMesh: \"${this.name}${geometry.name?.length ? "/" + geometry.name : ""}\"\n${geometryInfo.vertexCount} vertices, ${geometryInfo.indexCount} indices\nMax count ${this._maxInstanceCount} → ${newSize}\nMax vertex count ${this._maxVertexCount} -> ${newMaxVertexCount}\nMax index count ${this._maxIndexCount} -> ${newMaxIndexCount}`);
|
|
586
|
-
this._debugMaterial = createDebugMaterial();
|
|
587
|
-
}
|
|
588
|
-
else if (isDevEnvironment()) {
|
|
589
|
-
console.debug(`[Instancing] Growing Buffer\nMesh: \"${this.name}${geometry.name?.length ? "/" + geometry.name : ""}\"\nMax count ${this._maxInstanceCount} → ${newSize}\nMax vertex count ${this._maxVertexCount} -> ${newMaxVertexCount}\nMax index count ${this._maxIndexCount} -> ${newMaxIndexCount}`);
|
|
590
|
-
}
|
|
591
|
-
this._maxVertexCount = newMaxVertexCount;
|
|
592
|
-
this._maxIndexCount = newMaxIndexCount;
|
|
593
|
-
const newInst = new BatchedMesh(newSize, this._maxVertexCount, this._maxIndexCount, this._debugMaterial ?? this.material);
|
|
594
|
-
newInst.layers = this._batchedMesh.layers;
|
|
595
|
-
newInst.castShadow = this._batchedMesh.castShadow;
|
|
596
|
-
newInst.receiveShadow = this._batchedMesh.receiveShadow;
|
|
597
|
-
newInst.visible = this._batchedMesh.visible;
|
|
598
|
-
newInst[$instancingAutoUpdateBounds] = this._batchedMesh[$instancingAutoUpdateBounds];
|
|
599
|
-
newInst.matrixAutoUpdate = this._batchedMesh.matrixAutoUpdate;
|
|
600
|
-
newInst.matrixWorldNeedsUpdate = this._batchedMesh.matrixWorldNeedsUpdate;
|
|
601
|
-
newInst.matrixAutoUpdate = this._batchedMesh.matrixAutoUpdate;
|
|
602
|
-
newInst.matrixWorld.copy(this._batchedMesh.matrixWorld);
|
|
603
|
-
newInst.matrix.copy(this._batchedMesh.matrix);
|
|
604
|
-
// dispose the old batched mesh
|
|
605
|
-
this._batchedMesh.dispose();
|
|
606
|
-
this._batchedMesh.removeFromParent();
|
|
607
|
-
this._geometryIds.clear();
|
|
608
|
-
this._batchedMesh = newInst;
|
|
609
|
-
this._maxInstanceCount = newSize;
|
|
610
|
-
// since we have a new batched mesh we need to re-add all the instances
|
|
611
|
-
// fixes https://linear.app/needle/issue/NE-5711
|
|
612
|
-
// add current instances to new instanced mesh
|
|
613
|
-
const original = [...this._handles];
|
|
614
|
-
this._handles = [];
|
|
615
|
-
for (const handle of original) {
|
|
616
|
-
if (handle && handle.__instanceIndex >= 0) {
|
|
617
|
-
this.addGeometry(handle);
|
|
618
|
-
this._handles[handle.__instanceIndex] = handle;
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
this._context.scene.add(newInst);
|
|
622
|
-
}
|
|
623
|
-
tryEstimateVertexCountSize(newMaxInstances, _newGeometries, newGeometriesFactor = 1) {
|
|
624
|
-
/** Used geometries and how many instances use them */
|
|
625
|
-
const usedGeometries = new Map();
|
|
626
|
-
for (const handle of this._handles) {
|
|
627
|
-
if (handle && handle.__instanceIndex >= 0 && handle.object.geometry) {
|
|
628
|
-
if (!usedGeometries.has(handle.object.geometry)) {
|
|
629
|
-
const data = getMeshInformation(handle.object.geometry);
|
|
630
|
-
const meshinfo = { count: 1, ...data };
|
|
631
|
-
usedGeometries.set(handle.object.geometry, meshinfo);
|
|
632
|
-
}
|
|
633
|
-
else {
|
|
634
|
-
const entry = usedGeometries.get(handle.object.geometry);
|
|
635
|
-
entry.count += 1;
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
// then calculate the total vertex count
|
|
640
|
-
let totalVertices = 0;
|
|
641
|
-
let totalIndices = 0;
|
|
642
|
-
// let maxVertices = 0;
|
|
643
|
-
for (const [_geo, data] of usedGeometries) {
|
|
644
|
-
totalVertices += data.vertexCount * data.count;
|
|
645
|
-
totalIndices += data.indexCount * data.count;
|
|
646
|
-
// maxVertices = Math.max(maxVertices, geo.attributes.position.count * count);
|
|
647
|
-
}
|
|
648
|
-
// we calculate the average to make an educated guess of how many vertices will be needed with the new buffer count
|
|
649
|
-
const averageVerts = Math.ceil(totalVertices / Math.max(1, this._currentInstanceCount));
|
|
650
|
-
let maxVertexCount = averageVerts * newMaxInstances;
|
|
651
|
-
const averageIndices = Math.ceil(totalIndices / Math.max(1, this._currentInstanceCount));
|
|
652
|
-
let maxIndexCount = averageIndices * newMaxInstances * 2;
|
|
653
|
-
// if new geometries are provided we *know* that they will be added
|
|
654
|
-
// so we make sure to include them in the calculation
|
|
655
|
-
if (_newGeometries) {
|
|
656
|
-
for (const geo of _newGeometries) {
|
|
657
|
-
const meshinfo = getMeshInformation(geo);
|
|
658
|
-
if (meshinfo != null) {
|
|
659
|
-
maxVertexCount += meshinfo.vertexCount * newGeometriesFactor;
|
|
660
|
-
maxIndexCount += meshinfo.indexCount * newGeometriesFactor;
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
return { vertexCount: maxVertexCount, indexCount: maxIndexCount };
|
|
665
|
-
}
|
|
666
|
-
addGeometry(handle) {
|
|
667
|
-
const obj = handle.object;
|
|
668
|
-
const geo = obj.geometry;
|
|
669
|
-
if (!geo) {
|
|
670
|
-
// if the geometry is null we cannot add it
|
|
671
|
-
return;
|
|
672
|
-
}
|
|
673
|
-
// otherwise add more geometry / instances
|
|
674
|
-
let geometryId = this._geometryIds.get(geo);
|
|
675
|
-
if (geometryId === undefined || geometryId === null) {
|
|
676
|
-
if (debugInstancing)
|
|
677
|
-
console.debug(`[Instancing] > ADD NEW GEOMETRY \"${handle.name} (${geo.name}; ${geo.uuid})\"\n${this._currentInstanceCount} instances, ${handle.maxVertexCount} max vertices, ${handle.maxIndexCount} max indices`);
|
|
678
|
-
geometryId = this._batchedMesh.addGeometry(geo, handle.maxVertexCount, handle.maxIndexCount);
|
|
679
|
-
this._geometryIds.set(geo, geometryId);
|
|
680
|
-
}
|
|
681
|
-
else {
|
|
682
|
-
if (debugInstancing === "verbose")
|
|
683
|
-
console.log(`[Instancing] > ADD INSTANCE \"${handle.name}\"\nGEOMETRY_ID=${geometryId}\n${this._currentInstanceCount} instances`);
|
|
684
|
-
}
|
|
685
|
-
this._currentVertexCount += handle.maxVertexCount;
|
|
686
|
-
this._currentIndexCount += handle.maxIndexCount;
|
|
687
|
-
const i = this._batchedMesh.addInstance(geometryId);
|
|
688
|
-
handle.__geometryIndex = geometryId;
|
|
689
|
-
handle.__instanceIndex = i;
|
|
690
|
-
handle.__reservedVertexRange = handle.maxVertexCount;
|
|
691
|
-
handle.__reservedIndexRange = handle.maxIndexCount;
|
|
692
|
-
this._batchedMesh.setMatrixAt(i, handle.object.matrixWorld);
|
|
693
|
-
if (debugInstancing)
|
|
694
|
-
console.debug(`[Instancing] > ADDED INSTANCE \"${handle.name}\"\nGEOMETRY_ID=${geometryId}\n${this._currentInstanceCount} instances\nIndex: ${handle.__instanceIndex}`);
|
|
695
|
-
}
|
|
696
|
-
removeGeometry(handle, _del) {
|
|
697
|
-
if (handle.__instanceIndex < 0) {
|
|
698
|
-
console.warn("Cannot remove geometry, instance index is invalid", handle.name);
|
|
699
|
-
return;
|
|
700
|
-
}
|
|
701
|
-
// deleteGeometry is currently not useable since there's no optimize method
|
|
702
|
-
// https://github.com/mrdoob/three.js/issues/27985
|
|
703
|
-
// if (del)
|
|
704
|
-
// this.inst.deleteGeometry(handle.__instanceIndex);
|
|
705
|
-
// else
|
|
706
|
-
// this._batchedMesh.setVisibleAt(handle.__instanceIndex, false);
|
|
707
|
-
if (debugInstancing) {
|
|
708
|
-
console.debug(`[Instancing] < REMOVE INSTANCE \"${handle.name}\" at [${handle.__instanceIndex}]\nGEOMETRY_ID=${handle.__geometryIndex}\n${this._currentInstanceCount} instances\nIndex: ${handle.__instanceIndex}`);
|
|
709
|
-
}
|
|
710
|
-
this._batchedMesh.deleteInstance(handle.__instanceIndex);
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
function getMeshInformation(geo) {
|
|
714
|
-
if (!geo) {
|
|
715
|
-
if (isDevEnvironment())
|
|
716
|
-
console.error("Cannot get mesh information from null geometry");
|
|
717
|
-
return { vertexCount: 0, indexCount: 0 };
|
|
718
|
-
}
|
|
719
|
-
let vertexCount = geo.attributes?.position?.count || 0;
|
|
720
|
-
let indexCount = geo.index ? geo.index.count : 0;
|
|
721
|
-
const lodInfo = NEEDLE_progressive.
|
|
722
|
-
if (lodInfo) {
|
|
723
|
-
const lod0 = lodInfo.lods[0];
|
|
724
|
-
let lod0Count = lod0.vertexCount;
|
|
725
|
-
let lod0IndexCount = lod0.indexCount;
|
|
726
|
-
// add some wiggle room: https://linear.app/needle/issue/NE-4505
|
|
727
|
-
const extra = Math.min(200, Math.ceil(lod0Count * .05));
|
|
728
|
-
lod0Count += extra;
|
|
729
|
-
lod0IndexCount += 20;
|
|
730
|
-
vertexCount = Math.max(vertexCount, lod0Count);
|
|
731
|
-
indexCount = Math.max(indexCount, lod0IndexCount);
|
|
732
|
-
}
|
|
733
|
-
vertexCount = Math.ceil(vertexCount);
|
|
734
|
-
indexCount = Math.ceil(indexCount);
|
|
735
|
-
return { vertexCount, indexCount };
|
|
736
|
-
}
|
|
737
|
-
function createDebugMaterial() {
|
|
738
|
-
const mat = new MeshStandardMaterial({ color: new Color(Math.random(), Math.random(), Math.random()) });
|
|
739
|
-
mat.emissive = mat.color;
|
|
740
|
-
mat.emissiveIntensity = .3;
|
|
741
|
-
if (getParam("wireframe"))
|
|
742
|
-
mat.wireframe = true;
|
|
743
|
-
return mat;
|
|
744
|
-
}
|
|
1
|
+
import { BatchedMesh, Color, Matrix4, MeshStandardMaterial, RawShaderMaterial } from "three";
|
|
2
|
+
import { isDevEnvironment, showBalloonError } from "../engine/debug/index.js";
|
|
3
|
+
import { Gizmos } from "../engine/engine_gizmos.js";
|
|
4
|
+
import { $instancingAutoUpdateBounds, $instancingRenderer, NEED_UPDATE_INSTANCE_KEY } from "../engine/engine_instancing.js";
|
|
5
|
+
import { getParam, makeIdFromRandomWords } from "../engine/engine_utils.js";
|
|
6
|
+
import { NEEDLE_progressive } from "../engine/extensions/index.js";
|
|
7
|
+
import { GameObject } from "./Component.js";
|
|
8
|
+
const debugInstancing = getParam("debuginstancing");
|
|
9
|
+
;
|
|
10
|
+
/**
|
|
11
|
+
* Handles instancing for Needle Engine.
|
|
12
|
+
*/
|
|
13
|
+
export class InstancingHandler {
|
|
14
|
+
static instance = new InstancingHandler();
|
|
15
|
+
/** This is the initial instance count when creating a new instancing structure.
|
|
16
|
+
* Override this and the number of max instances that you expect for a given object.
|
|
17
|
+
* The larger the value the more objects can be added without having to resize but it will also consume more memory.
|
|
18
|
+
* (The instancing mesh renderer will grow x2 if the max instance count is reached)
|
|
19
|
+
* @default 4
|
|
20
|
+
* @returns The initial instance count
|
|
21
|
+
* */
|
|
22
|
+
static getStartInstanceCount = (_obj) => {
|
|
23
|
+
return 4;
|
|
24
|
+
};
|
|
25
|
+
objs = [];
|
|
26
|
+
setup(renderer, obj, context, handlesArray, args, level = 0) {
|
|
27
|
+
// make sure setting casting settings are applied so when we add the mesh to the InstancedMesh we can ask for the correct cast shadow setting
|
|
28
|
+
renderer.applySettings(obj);
|
|
29
|
+
const res = this.tryCreateOrAddInstance(obj, context, args);
|
|
30
|
+
if (res) {
|
|
31
|
+
if (handlesArray === null)
|
|
32
|
+
handlesArray = [];
|
|
33
|
+
handlesArray.push(res);
|
|
34
|
+
// load texture lods
|
|
35
|
+
NEEDLE_progressive.assignTextureLOD(res.renderer.material, 0);
|
|
36
|
+
// Load mesh lods
|
|
37
|
+
// TODO: technically for multi meshes we do this work multiple times (we search for meshes in children and then use the renderer sharedMeshes... that doesnt make sense)
|
|
38
|
+
for (let i = 0; i < renderer.sharedMeshes.length; i++) {
|
|
39
|
+
const mesh = renderer.sharedMeshes[i];
|
|
40
|
+
const geometry = mesh.geometry;
|
|
41
|
+
NEEDLE_progressive.assignMeshLOD(mesh, 0).then(lod => {
|
|
42
|
+
if (lod && renderer.activeAndEnabled && geometry != lod) {
|
|
43
|
+
res.setGeometry(lod);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else if (level <= 0 && obj.type !== "Mesh") {
|
|
49
|
+
const nextLevel = level + 1;
|
|
50
|
+
for (const ch of obj.children) {
|
|
51
|
+
handlesArray = this.setup(renderer, ch, context, handlesArray, args, nextLevel);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (level === 0) {
|
|
55
|
+
// For multi material objects we only want to track the root object's matrix
|
|
56
|
+
if (args.useMatrixWorldAutoUpdate && handlesArray && handlesArray.length >= 0) {
|
|
57
|
+
this.autoUpdateInstanceMatrix(obj);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return handlesArray;
|
|
61
|
+
}
|
|
62
|
+
tryCreateOrAddInstance(obj, context, args) {
|
|
63
|
+
if (obj.type === "Mesh") {
|
|
64
|
+
const index = args.foundMeshes;
|
|
65
|
+
args.foundMeshes += 1;
|
|
66
|
+
if (!args.rend.enableInstancing)
|
|
67
|
+
return null;
|
|
68
|
+
if (args.rend.enableInstancing === true) {
|
|
69
|
+
// instancing is enabled globally
|
|
70
|
+
// continue....
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
if (index >= args.rend.enableInstancing.length) {
|
|
74
|
+
if (debugInstancing)
|
|
75
|
+
console.error("Something is wrong with instance setup", obj, args.rend.enableInstancing, index);
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
if (!args.rend.enableInstancing[index]) {
|
|
79
|
+
// instancing is disabled
|
|
80
|
+
// console.log("Instancing is disabled", obj);
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// instancing is enabled:
|
|
85
|
+
const mesh = obj;
|
|
86
|
+
// const geo = mesh.geometry as BufferGeometry;
|
|
87
|
+
const mat = mesh.material;
|
|
88
|
+
for (const i of this.objs) {
|
|
89
|
+
if (!i.canAdd(mesh.geometry, mat))
|
|
90
|
+
continue;
|
|
91
|
+
const handle = i.addInstance(mesh);
|
|
92
|
+
return handle;
|
|
93
|
+
}
|
|
94
|
+
let maxInstances = InstancingHandler.getStartInstanceCount(obj);
|
|
95
|
+
if (!maxInstances || maxInstances < 0) {
|
|
96
|
+
maxInstances = 4;
|
|
97
|
+
}
|
|
98
|
+
let name = obj.name;
|
|
99
|
+
if (!name?.length)
|
|
100
|
+
name = makeIdFromRandomWords();
|
|
101
|
+
const i = new InstancedMeshRenderer(name, mesh.geometry, mat, maxInstances, context);
|
|
102
|
+
this.objs.push(i);
|
|
103
|
+
const handle = i.addInstance(mesh);
|
|
104
|
+
return handle;
|
|
105
|
+
}
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
autoUpdateInstanceMatrix(obj) {
|
|
109
|
+
const original = obj.matrixWorld["multiplyMatrices"].bind(obj.matrixWorld);
|
|
110
|
+
const previousMatrix = obj.matrixWorld.clone();
|
|
111
|
+
const matrixChangeWrapper = (a, b) => {
|
|
112
|
+
const newMatrixWorld = original(a, b);
|
|
113
|
+
if (obj[NEED_UPDATE_INSTANCE_KEY] || previousMatrix.equals(newMatrixWorld) === false) {
|
|
114
|
+
previousMatrix.copy(newMatrixWorld);
|
|
115
|
+
obj[NEED_UPDATE_INSTANCE_KEY] = true;
|
|
116
|
+
}
|
|
117
|
+
return newMatrixWorld;
|
|
118
|
+
};
|
|
119
|
+
obj.matrixWorld["multiplyMatrices"] = matrixChangeWrapper;
|
|
120
|
+
// wrap matrixWorldNeedsUpdate
|
|
121
|
+
// let originalMatrixWorldNeedsUpdate = obj.matrixWorldNeedsUpdate;
|
|
122
|
+
// Object.defineProperty(obj, "matrixWorldNeedsUpdate", {
|
|
123
|
+
// get: () => {
|
|
124
|
+
// return originalMatrixWorldNeedsUpdate;
|
|
125
|
+
// },
|
|
126
|
+
// set: (value: boolean) => {
|
|
127
|
+
// if(value) console.warn("SET MATRIX WORLD NEEDS UPDATE");
|
|
128
|
+
// originalMatrixWorldNeedsUpdate = value;
|
|
129
|
+
// }
|
|
130
|
+
// });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* The instance handle is used to interface with the mesh that is rendered using instancing.
|
|
135
|
+
*/
|
|
136
|
+
export class InstanceHandle {
|
|
137
|
+
static all = [];
|
|
138
|
+
/** The name of the object */
|
|
139
|
+
get name() {
|
|
140
|
+
return this.object.name;
|
|
141
|
+
}
|
|
142
|
+
get isActive() {
|
|
143
|
+
return this.__instanceIndex >= 0;
|
|
144
|
+
}
|
|
145
|
+
get vertexCount() {
|
|
146
|
+
return this.object.geometry.attributes.position.count;
|
|
147
|
+
}
|
|
148
|
+
get maxVertexCount() {
|
|
149
|
+
// we get the max of the estimated MAX lod vertex count and the actual vertex count
|
|
150
|
+
return Math.max(this.meshInformation.vertexCount, this.vertexCount);
|
|
151
|
+
}
|
|
152
|
+
get reservedVertexCount() {
|
|
153
|
+
return this.__reservedVertexRange;
|
|
154
|
+
}
|
|
155
|
+
get indexCount() {
|
|
156
|
+
return this.object.geometry.index ? this.object.geometry.index.count : 0;
|
|
157
|
+
}
|
|
158
|
+
get maxIndexCount() {
|
|
159
|
+
// we get the max of the estimated MAX lod index count and the actual index count
|
|
160
|
+
return Math.max(this.meshInformation.indexCount, this.indexCount);
|
|
161
|
+
}
|
|
162
|
+
get reservedIndexCount() {
|
|
163
|
+
return this.__reservedIndexRange;
|
|
164
|
+
}
|
|
165
|
+
/** The object that is being instanced */
|
|
166
|
+
object;
|
|
167
|
+
/** The instancer/BatchedMesh that is rendering this object*/
|
|
168
|
+
renderer;
|
|
169
|
+
/** @internal */
|
|
170
|
+
__instanceIndex = -1;
|
|
171
|
+
/** @internal */
|
|
172
|
+
__reservedVertexRange = 0;
|
|
173
|
+
/** @internal */
|
|
174
|
+
__reservedIndexRange = 0;
|
|
175
|
+
__geometryIndex = -1;
|
|
176
|
+
/** The mesh information of the object - this tries to also calculate the LOD info */
|
|
177
|
+
meshInformation;
|
|
178
|
+
constructor(originalObject, instancer) {
|
|
179
|
+
this.__instanceIndex = -1;
|
|
180
|
+
this.object = originalObject;
|
|
181
|
+
this.renderer = instancer;
|
|
182
|
+
originalObject[$instancingRenderer] = instancer;
|
|
183
|
+
// TODO: this doesn't have LOD information *yet* in some cases - hence we can not rely on it for the max vertex counts
|
|
184
|
+
this.meshInformation = getMeshInformation(originalObject.geometry);
|
|
185
|
+
InstanceHandle.all.push(this);
|
|
186
|
+
}
|
|
187
|
+
/** Calculates the mesh information again
|
|
188
|
+
* @returns true if the vertex count or index count has changed
|
|
189
|
+
*/
|
|
190
|
+
updateMeshInformation() {
|
|
191
|
+
const newMeshInformation = getMeshInformation(this.object.geometry);
|
|
192
|
+
const oldVertexCount = this.meshInformation.vertexCount;
|
|
193
|
+
const oldIndexCount = this.meshInformation.indexCount;
|
|
194
|
+
Object.assign(this.meshInformation, newMeshInformation);
|
|
195
|
+
return oldVertexCount !== this.meshInformation.vertexCount || oldIndexCount !== this.meshInformation.indexCount;
|
|
196
|
+
}
|
|
197
|
+
/** Updates the matrix from the rendered object. Will also call updateWorldMatrix internally */
|
|
198
|
+
updateInstanceMatrix(updateChildren = false, updateMatrix = true) {
|
|
199
|
+
if (this.__instanceIndex < 0)
|
|
200
|
+
return;
|
|
201
|
+
if (updateMatrix)
|
|
202
|
+
this.object.updateWorldMatrix(true, updateChildren);
|
|
203
|
+
this.renderer.updateInstance(this.object.matrixWorld, this.__instanceIndex);
|
|
204
|
+
}
|
|
205
|
+
/** Updates the matrix of the instance */
|
|
206
|
+
setMatrix(matrix) {
|
|
207
|
+
if (this.__instanceIndex < 0)
|
|
208
|
+
return;
|
|
209
|
+
this.renderer.updateInstance(matrix, this.__instanceIndex);
|
|
210
|
+
}
|
|
211
|
+
/** Can be used to change the geometry of this instance */
|
|
212
|
+
setGeometry(geo) {
|
|
213
|
+
if (this.__geometryIndex < 0)
|
|
214
|
+
return false;
|
|
215
|
+
const self = this;
|
|
216
|
+
if (this.vertexCount > this.__reservedVertexRange) {
|
|
217
|
+
return handleInvalidRange(`Instancing: Can not update geometry (${this.name}), reserved vertex range is too small: ${this.__reservedVertexRange.toLocaleString()} < ${this.vertexCount.toLocaleString()} vertices for ${this.name}`);
|
|
218
|
+
}
|
|
219
|
+
if (this.indexCount > this.__reservedIndexRange) {
|
|
220
|
+
return handleInvalidRange(`Instancing: Can not update geometry (${this.name}), reserved index range is too small: ${this.__reservedIndexRange.toLocaleString()} < ${this.indexCount.toLocaleString()} indices for ${this.name}`);
|
|
221
|
+
}
|
|
222
|
+
return this.renderer.updateGeometry(geo, this.__geometryIndex);
|
|
223
|
+
function handleInvalidRange(error) {
|
|
224
|
+
if (self.updateMeshInformation()) {
|
|
225
|
+
// Gizmos.DrawWireSphere(self.object.worldPosition, .5, 0xff0000, 5);
|
|
226
|
+
self.renderer.remove(self, true);
|
|
227
|
+
// Gizmos.DrawWireSphere(self.object.worldPosition, .5, 0x33ff00, 5);
|
|
228
|
+
// self.object.scale.multiplyScalar(10);
|
|
229
|
+
if (self.renderer.add(self)) {
|
|
230
|
+
return true;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (isDevEnvironment() || debugInstancing) {
|
|
234
|
+
console.error(error);
|
|
235
|
+
}
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/** Adds this object to the instancing renderer (effectively activating instancing) */
|
|
240
|
+
add() {
|
|
241
|
+
if (this.__instanceIndex >= 0)
|
|
242
|
+
return;
|
|
243
|
+
this.renderer.add(this);
|
|
244
|
+
GameObject.markAsInstancedRendered(this.object, true);
|
|
245
|
+
}
|
|
246
|
+
/** Removes this object from the instancing renderer
|
|
247
|
+
* @param delete_ If true, the instance handle will be removed from the global list
|
|
248
|
+
*/
|
|
249
|
+
remove(delete_) {
|
|
250
|
+
if (this.__instanceIndex < 0)
|
|
251
|
+
return;
|
|
252
|
+
this.renderer.remove(this, delete_);
|
|
253
|
+
GameObject.markAsInstancedRendered(this.object, false);
|
|
254
|
+
if (delete_) {
|
|
255
|
+
const i = InstanceHandle.all.indexOf(this);
|
|
256
|
+
if (i >= 0) {
|
|
257
|
+
InstanceHandle.all.splice(i, 1);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
class InstancedMeshRenderer {
|
|
263
|
+
/** The three instanced mesh
|
|
264
|
+
* @link https://threejs.org/docs/#api/en/objects/InstancedMesh
|
|
265
|
+
*/
|
|
266
|
+
get batchedMesh() {
|
|
267
|
+
return this._batchedMesh;
|
|
268
|
+
}
|
|
269
|
+
get visible() {
|
|
270
|
+
return this._batchedMesh.visible;
|
|
271
|
+
}
|
|
272
|
+
set visible(val) {
|
|
273
|
+
this._batchedMesh.visible = val;
|
|
274
|
+
}
|
|
275
|
+
get castShadow() {
|
|
276
|
+
return this._batchedMesh.castShadow;
|
|
277
|
+
}
|
|
278
|
+
set castShadow(val) {
|
|
279
|
+
this._batchedMesh.castShadow = val;
|
|
280
|
+
}
|
|
281
|
+
set receiveShadow(val) {
|
|
282
|
+
this._batchedMesh.receiveShadow = val;
|
|
283
|
+
}
|
|
284
|
+
/** If true, the instancer is allowed to grow when the max instance count is reached */
|
|
285
|
+
allowResize = true;
|
|
286
|
+
/** The name of the instancer */
|
|
287
|
+
name = "";
|
|
288
|
+
/** The added geometry */
|
|
289
|
+
geometry;
|
|
290
|
+
/** The material used for the instanced mesh */
|
|
291
|
+
material;
|
|
292
|
+
/** The current number of instances */
|
|
293
|
+
get count() { return this._currentInstanceCount; }
|
|
294
|
+
/** Update the bounding box and sphere of the instanced mesh
|
|
295
|
+
* @param box If true, update the bounding box
|
|
296
|
+
* @param sphere If true, update the bounding sphere
|
|
297
|
+
*/
|
|
298
|
+
updateBounds(box = true, sphere = true) {
|
|
299
|
+
this._needUpdateBounds = false;
|
|
300
|
+
if (box)
|
|
301
|
+
this._batchedMesh.computeBoundingBox();
|
|
302
|
+
if (sphere)
|
|
303
|
+
this._batchedMesh.computeBoundingSphere();
|
|
304
|
+
if (debugInstancing && this._batchedMesh.boundingSphere) {
|
|
305
|
+
const sphere = this._batchedMesh.boundingSphere;
|
|
306
|
+
// const worldPos = this._batchedMesh.worldPosition.add(sphere.center);
|
|
307
|
+
// const worldRadius = sphere!.radius;
|
|
308
|
+
Gizmos.DrawWireSphere(sphere.center, sphere.radius, 0x00ff00);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
_context;
|
|
312
|
+
_batchedMesh;
|
|
313
|
+
_handles = [];
|
|
314
|
+
_geometryIds = new Map();
|
|
315
|
+
_maxInstanceCount;
|
|
316
|
+
_currentInstanceCount = 0;
|
|
317
|
+
_currentVertexCount = 0;
|
|
318
|
+
_currentIndexCount = 0;
|
|
319
|
+
_maxVertexCount;
|
|
320
|
+
_maxIndexCount;
|
|
321
|
+
static nullMatrix = new Matrix4();
|
|
322
|
+
/** Check if the geometry can be added to this instancer
|
|
323
|
+
* @param geometry The geometry to check
|
|
324
|
+
* @param material The material of the geometry
|
|
325
|
+
* @returns true if the geometry can be added
|
|
326
|
+
*/
|
|
327
|
+
canAdd(geometry, material) {
|
|
328
|
+
if (this._maxVertexCount > 10_000_000)
|
|
329
|
+
return false;
|
|
330
|
+
// The material instance must match
|
|
331
|
+
// perhaps at some point later we *could* check if it's the same shader and properties but this would be risky
|
|
332
|
+
if (material !== this.material) {
|
|
333
|
+
const canMergeMaterial = false;
|
|
334
|
+
// if (material.type === this.material.type) {
|
|
335
|
+
// switch (material.type) {
|
|
336
|
+
// case "MeshStandardMaterial":
|
|
337
|
+
// // check if the material properties are the same
|
|
338
|
+
// const m0 = this.material as MeshStandardMaterial;
|
|
339
|
+
// const m1 = material as MeshStandardMaterial;
|
|
340
|
+
// if(m0.map !== m1.map) return false;
|
|
341
|
+
// // if(m0.color.equals(m1.color) === false) return false;
|
|
342
|
+
// if(m0.roughness !== m1.roughness) return false;
|
|
343
|
+
// if(m0.metalness !== m1.metalness) return false;
|
|
344
|
+
// if(m0.envMap !== m1.envMap) return false;
|
|
345
|
+
// if(m0.envMapIntensity !== m1.envMapIntensity) return false;
|
|
346
|
+
// if(m0.lightMap !== m1.lightMap) return false;
|
|
347
|
+
// if(m0.lightMapIntensity !== m1.lightMapIntensity) return false;
|
|
348
|
+
// if(m0.aoMap !== m1.aoMap) return false;
|
|
349
|
+
// if(m0.aoMapIntensity !== m1.aoMapIntensity) return false;
|
|
350
|
+
// if(m0.emissive.equals(m1.emissive) === false) return false;
|
|
351
|
+
// if(m0.emissiveIntensity !== m1.emissiveIntensity) return false;
|
|
352
|
+
// if(m0.emissiveMap !== m1.emissiveMap) return false;
|
|
353
|
+
// if(m0.bumpMap !== m1.bumpMap) return false;
|
|
354
|
+
// if(m0.bumpScale !== m1.bumpScale) return false;
|
|
355
|
+
// if(m0.normalMap !== m1.normalMap) return false;
|
|
356
|
+
// if(m0.normalScale.equals(m1.normalScale) === false) return false;
|
|
357
|
+
// if(m0.displacementMap !== m1.displacementMap) return false;
|
|
358
|
+
// if(m0.displacementScale !== m1.displacementScale) return false;
|
|
359
|
+
// if(m0.displacementBias !== m1.displacementBias) return false;
|
|
360
|
+
// if(m0.roughnessMap !== m1.roughnessMap) return false;
|
|
361
|
+
// if(m0.metalnessMap !== m1.metalnessMap) return false;
|
|
362
|
+
// if(m0.alphaMap !== m1.alphaMap) return false;
|
|
363
|
+
// if(m0.envMapIntensity !== m1.envMapIntensity) return false;
|
|
364
|
+
// canMergeMaterial = true;
|
|
365
|
+
// break;
|
|
366
|
+
// }
|
|
367
|
+
// }
|
|
368
|
+
if (!canMergeMaterial) {
|
|
369
|
+
return false;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
// if(this.geometry !== _geometry) return false;
|
|
373
|
+
// console.log(geometry.name, geometry.uuid);
|
|
374
|
+
if (!this.validateGeometry(geometry))
|
|
375
|
+
return false;
|
|
376
|
+
// const validationMethod = this.inst["_validateGeometry"];
|
|
377
|
+
// if (!validationMethod) throw new Error("InstancedMesh does not have a _validateGeometry method");
|
|
378
|
+
// try {
|
|
379
|
+
// validationMethod.call(this.inst, _geometry);
|
|
380
|
+
// }
|
|
381
|
+
// catch (err) {
|
|
382
|
+
// // console.error(err);
|
|
383
|
+
// return false;
|
|
384
|
+
// }
|
|
385
|
+
const hasSpace = !this.mustGrow(geometry);
|
|
386
|
+
if (hasSpace)
|
|
387
|
+
return true;
|
|
388
|
+
if (this.allowResize)
|
|
389
|
+
return true;
|
|
390
|
+
return false;
|
|
391
|
+
}
|
|
392
|
+
_needUpdateBounds = false;
|
|
393
|
+
_debugMaterial = null;
|
|
394
|
+
constructor(name, geo, material, initialMaxCount, context) {
|
|
395
|
+
this.name = name;
|
|
396
|
+
this.geometry = geo;
|
|
397
|
+
this.material = material;
|
|
398
|
+
this._context = context;
|
|
399
|
+
this._maxInstanceCount = Math.max(2, initialMaxCount);
|
|
400
|
+
if (debugInstancing) {
|
|
401
|
+
this._debugMaterial = createDebugMaterial();
|
|
402
|
+
}
|
|
403
|
+
const estimate = this.tryEstimateVertexCountSize(this._maxInstanceCount, [geo], initialMaxCount);
|
|
404
|
+
this._maxVertexCount = estimate.vertexCount;
|
|
405
|
+
this._maxIndexCount = estimate.indexCount;
|
|
406
|
+
this._batchedMesh = new BatchedMesh(this._maxInstanceCount, this._maxVertexCount, this._maxIndexCount, this._debugMaterial ?? this.material);
|
|
407
|
+
// this.inst = new InstancedMesh(geo, material, count);
|
|
408
|
+
this._batchedMesh[$instancingAutoUpdateBounds] = true;
|
|
409
|
+
// this.inst.count = 0;
|
|
410
|
+
this._batchedMesh.visible = true;
|
|
411
|
+
this._context.scene.add(this._batchedMesh);
|
|
412
|
+
// Not handled by RawShaderMaterial, so we need to set the define explicitly.
|
|
413
|
+
// Edge case: theoretically some users of the material could use it in an
|
|
414
|
+
// instanced fashion, and some others not. In that case, the material would not
|
|
415
|
+
// be able to be shared between the two use cases. We could probably add a
|
|
416
|
+
// onBeforeRender call for the InstancedMesh and set the define there.
|
|
417
|
+
// Same would apply if we support skinning -
|
|
418
|
+
// there we would have to split instanced batches so that the ones using skinning
|
|
419
|
+
// are all in the same batch.
|
|
420
|
+
if (material instanceof RawShaderMaterial) {
|
|
421
|
+
material.defines["USE_INSTANCING"] = true;
|
|
422
|
+
material.needsUpdate = true;
|
|
423
|
+
}
|
|
424
|
+
context.pre_render_callbacks.push(this.onBeforeRender);
|
|
425
|
+
context.post_render_callbacks.push(this.onAfterRender);
|
|
426
|
+
if (debugInstancing) {
|
|
427
|
+
console.log(`Instanced renderer created with ${this._maxInstanceCount} instances, ${this._maxVertexCount} max vertices and ${this._maxIndexCount} max indices for \"${name}\"`);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
dispose() {
|
|
431
|
+
if (debugInstancing)
|
|
432
|
+
console.warn("Dispose instanced renderer", this.name);
|
|
433
|
+
this._context.scene.remove(this._batchedMesh);
|
|
434
|
+
this._batchedMesh.dispose();
|
|
435
|
+
this._batchedMesh = null;
|
|
436
|
+
this._handles = [];
|
|
437
|
+
}
|
|
438
|
+
addInstance(obj) {
|
|
439
|
+
const handle = new InstanceHandle(obj, this);
|
|
440
|
+
if (obj.castShadow === true && this._batchedMesh.castShadow === false) {
|
|
441
|
+
this._batchedMesh.castShadow = true;
|
|
442
|
+
}
|
|
443
|
+
if (obj.receiveShadow === true && this._batchedMesh.receiveShadow === false) {
|
|
444
|
+
this._batchedMesh.receiveShadow = true;
|
|
445
|
+
}
|
|
446
|
+
try {
|
|
447
|
+
this.add(handle);
|
|
448
|
+
}
|
|
449
|
+
catch (e) {
|
|
450
|
+
console.error(`Failed adding mesh to instancing (object name: \"${obj.name}\", instances: ${this._currentInstanceCount.toLocaleString()}/${this._maxInstanceCount.toLocaleString()}, vertices: ${this._currentVertexCount.toLocaleString()}/${this._maxVertexCount.toLocaleString()}, indices: ${this._currentIndexCount.toLocaleString()}/${this._maxIndexCount.toLocaleString()})\n`, e);
|
|
451
|
+
if (isDevEnvironment()) {
|
|
452
|
+
showBalloonError("Failed instancing mesh. See the browser console for details.");
|
|
453
|
+
debugger;
|
|
454
|
+
}
|
|
455
|
+
return null;
|
|
456
|
+
}
|
|
457
|
+
return handle;
|
|
458
|
+
}
|
|
459
|
+
add(handle) {
|
|
460
|
+
const geo = handle.object.geometry;
|
|
461
|
+
if (!geo || !geo.attributes) {
|
|
462
|
+
console.error("Cannot add object to instancing without geometry", handle.name);
|
|
463
|
+
return false;
|
|
464
|
+
}
|
|
465
|
+
if (this.mustGrow(geo)) {
|
|
466
|
+
if (this.allowResize) {
|
|
467
|
+
this.grow(geo);
|
|
468
|
+
}
|
|
469
|
+
else {
|
|
470
|
+
console.error("Cannot add instance, max count reached", this.name, this.count, this._maxInstanceCount);
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
handle.object.updateWorldMatrix(true, true);
|
|
475
|
+
this.addGeometry(handle);
|
|
476
|
+
this._handles[handle.__instanceIndex] = handle;
|
|
477
|
+
this._currentInstanceCount += 1;
|
|
478
|
+
this.markNeedsUpdate();
|
|
479
|
+
if (this._currentInstanceCount > 0)
|
|
480
|
+
this._batchedMesh.visible = true;
|
|
481
|
+
return true;
|
|
482
|
+
}
|
|
483
|
+
remove(handle, delete_) {
|
|
484
|
+
if (!handle) {
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
if (handle.__instanceIndex < 0 || this._handles[handle.__instanceIndex] != handle || this._currentInstanceCount <= 0) {
|
|
488
|
+
// console.warn("Cannot remove instance, handle is invalid", handle.name);
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
this.removeGeometry(handle, delete_);
|
|
492
|
+
this._handles[handle.__instanceIndex] = null;
|
|
493
|
+
handle.__instanceIndex = -1;
|
|
494
|
+
if (this._currentInstanceCount > 0) {
|
|
495
|
+
this._currentInstanceCount -= 1;
|
|
496
|
+
}
|
|
497
|
+
if (this._currentInstanceCount <= 0)
|
|
498
|
+
this._batchedMesh.visible = false;
|
|
499
|
+
this.markNeedsUpdate();
|
|
500
|
+
}
|
|
501
|
+
updateInstance(mat, index) {
|
|
502
|
+
this._batchedMesh.setMatrixAt(index, mat);
|
|
503
|
+
this.markNeedsUpdate();
|
|
504
|
+
}
|
|
505
|
+
updateGeometry(geo, geometryIndex) {
|
|
506
|
+
if (!this.validateGeometry(geo)) {
|
|
507
|
+
return false;
|
|
508
|
+
}
|
|
509
|
+
if (this.mustGrow()) {
|
|
510
|
+
this.grow(geo);
|
|
511
|
+
}
|
|
512
|
+
if (debugInstancing)
|
|
513
|
+
console.debug("[Instancing] UPDATE GEOMETRY at " + geometryIndex, this._batchedMesh["_geometryCount"], geo.name, getMeshInformation(geo), geo.attributes.position.count, geo.index ? geo.index.count : 0);
|
|
514
|
+
this._batchedMesh.setGeometryAt(geometryIndex, geo);
|
|
515
|
+
// for LOD mesh updates we need to make sure to save the geometry index
|
|
516
|
+
this._geometryIds.set(geo, geometryIndex);
|
|
517
|
+
this.markNeedsUpdate();
|
|
518
|
+
return true;
|
|
519
|
+
}
|
|
520
|
+
onBeforeRender = () => {
|
|
521
|
+
// ensure the instanced mesh is rendered / has correct layers
|
|
522
|
+
this._batchedMesh.layers.enableAll();
|
|
523
|
+
if (this._needUpdateBounds && this._batchedMesh[$instancingAutoUpdateBounds] === true) {
|
|
524
|
+
if (debugInstancing === "verbose")
|
|
525
|
+
console.log("Update instancing bounds", this.name, this._batchedMesh.matrixWorldNeedsUpdate);
|
|
526
|
+
this.updateBounds();
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
onAfterRender = () => {
|
|
530
|
+
// hide the instanced mesh again when its not being rendered (for raycasting we still use the original object)
|
|
531
|
+
this._batchedMesh.layers.disableAll();
|
|
532
|
+
};
|
|
533
|
+
validateGeometry(geometry) {
|
|
534
|
+
const batchGeometry = this.geometry;
|
|
535
|
+
for (const attributeName in batchGeometry.attributes) {
|
|
536
|
+
if (attributeName === "batchId") {
|
|
537
|
+
continue;
|
|
538
|
+
}
|
|
539
|
+
if (!geometry.hasAttribute(attributeName)) {
|
|
540
|
+
if (isDevEnvironment())
|
|
541
|
+
console.warn(`BatchedMesh: Added geometry missing "${attributeName}". All geometries must have consistent attributes.`);
|
|
542
|
+
// geometry.setAttribute(attributeName, batchGeometry.getAttribute(attributeName).clone());
|
|
543
|
+
return false;
|
|
544
|
+
// throw new Error(`BatchedMesh: Added geometry missing "${attributeName}". All geometries must have consistent attributes.`);
|
|
545
|
+
}
|
|
546
|
+
// const srcAttribute = geometry.getAttribute(attributeName);
|
|
547
|
+
// const dstAttribute = batchGeometry.getAttribute(attributeName);
|
|
548
|
+
// if (srcAttribute.itemSize !== dstAttribute.itemSize || srcAttribute.normalized !== dstAttribute.normalized) {
|
|
549
|
+
// if (debugInstancing) throw new Error('BatchedMesh: All attributes must have a consistent itemSize and normalized value.');
|
|
550
|
+
// return false;
|
|
551
|
+
// }
|
|
552
|
+
}
|
|
553
|
+
return true;
|
|
554
|
+
}
|
|
555
|
+
markNeedsUpdate() {
|
|
556
|
+
if (debugInstancing === "verbose") {
|
|
557
|
+
console.warn("Marking instanced mesh dirty", this.name);
|
|
558
|
+
}
|
|
559
|
+
this._needUpdateBounds = true;
|
|
560
|
+
// this.inst.instanceMatrix.needsUpdate = true;
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* @param geo The geometry to add (if none is provided it means the geometry is already added and just updated)
|
|
564
|
+
*/
|
|
565
|
+
mustGrow(geo) {
|
|
566
|
+
if (this.count >= this._maxInstanceCount)
|
|
567
|
+
return true;
|
|
568
|
+
if (!geo || !geo.attributes)
|
|
569
|
+
return false;
|
|
570
|
+
const meshInfo = getMeshInformation(geo);
|
|
571
|
+
const newVertexCount = meshInfo.vertexCount;
|
|
572
|
+
const newIndexCount = meshInfo.indexCount;
|
|
573
|
+
return this._currentVertexCount + newVertexCount > this._maxVertexCount || this._currentIndexCount + newIndexCount > this._maxIndexCount;
|
|
574
|
+
}
|
|
575
|
+
grow(geometry) {
|
|
576
|
+
const growFactor = 2;
|
|
577
|
+
const newSize = Math.ceil(this._maxInstanceCount * growFactor);
|
|
578
|
+
// create a new BatchedMesh instance
|
|
579
|
+
const estimatedSpace = this.tryEstimateVertexCountSize(newSize, [geometry]); // geometry.attributes.position.count;
|
|
580
|
+
// const indices = geometry.index ? geometry.index.count : 0;
|
|
581
|
+
const newMaxVertexCount = Math.max(this._maxVertexCount, estimatedSpace.vertexCount);
|
|
582
|
+
const newMaxIndexCount = Math.max(this._maxIndexCount, estimatedSpace.indexCount, Math.ceil(this._maxVertexCount * growFactor));
|
|
583
|
+
if (debugInstancing) {
|
|
584
|
+
const geometryInfo = getMeshInformation(geometry);
|
|
585
|
+
console.warn(`[Instancing] Growing Buffer\nMesh: \"${this.name}${geometry.name?.length ? "/" + geometry.name : ""}\"\n${geometryInfo.vertexCount} vertices, ${geometryInfo.indexCount} indices\nMax count ${this._maxInstanceCount} → ${newSize}\nMax vertex count ${this._maxVertexCount} -> ${newMaxVertexCount}\nMax index count ${this._maxIndexCount} -> ${newMaxIndexCount}`);
|
|
586
|
+
this._debugMaterial = createDebugMaterial();
|
|
587
|
+
}
|
|
588
|
+
else if (isDevEnvironment()) {
|
|
589
|
+
console.debug(`[Instancing] Growing Buffer\nMesh: \"${this.name}${geometry.name?.length ? "/" + geometry.name : ""}\"\nMax count ${this._maxInstanceCount} → ${newSize}\nMax vertex count ${this._maxVertexCount} -> ${newMaxVertexCount}\nMax index count ${this._maxIndexCount} -> ${newMaxIndexCount}`);
|
|
590
|
+
}
|
|
591
|
+
this._maxVertexCount = newMaxVertexCount;
|
|
592
|
+
this._maxIndexCount = newMaxIndexCount;
|
|
593
|
+
const newInst = new BatchedMesh(newSize, this._maxVertexCount, this._maxIndexCount, this._debugMaterial ?? this.material);
|
|
594
|
+
newInst.layers = this._batchedMesh.layers;
|
|
595
|
+
newInst.castShadow = this._batchedMesh.castShadow;
|
|
596
|
+
newInst.receiveShadow = this._batchedMesh.receiveShadow;
|
|
597
|
+
newInst.visible = this._batchedMesh.visible;
|
|
598
|
+
newInst[$instancingAutoUpdateBounds] = this._batchedMesh[$instancingAutoUpdateBounds];
|
|
599
|
+
newInst.matrixAutoUpdate = this._batchedMesh.matrixAutoUpdate;
|
|
600
|
+
newInst.matrixWorldNeedsUpdate = this._batchedMesh.matrixWorldNeedsUpdate;
|
|
601
|
+
newInst.matrixAutoUpdate = this._batchedMesh.matrixAutoUpdate;
|
|
602
|
+
newInst.matrixWorld.copy(this._batchedMesh.matrixWorld);
|
|
603
|
+
newInst.matrix.copy(this._batchedMesh.matrix);
|
|
604
|
+
// dispose the old batched mesh
|
|
605
|
+
this._batchedMesh.dispose();
|
|
606
|
+
this._batchedMesh.removeFromParent();
|
|
607
|
+
this._geometryIds.clear();
|
|
608
|
+
this._batchedMesh = newInst;
|
|
609
|
+
this._maxInstanceCount = newSize;
|
|
610
|
+
// since we have a new batched mesh we need to re-add all the instances
|
|
611
|
+
// fixes https://linear.app/needle/issue/NE-5711
|
|
612
|
+
// add current instances to new instanced mesh
|
|
613
|
+
const original = [...this._handles];
|
|
614
|
+
this._handles = [];
|
|
615
|
+
for (const handle of original) {
|
|
616
|
+
if (handle && handle.__instanceIndex >= 0) {
|
|
617
|
+
this.addGeometry(handle);
|
|
618
|
+
this._handles[handle.__instanceIndex] = handle;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
this._context.scene.add(newInst);
|
|
622
|
+
}
|
|
623
|
+
tryEstimateVertexCountSize(newMaxInstances, _newGeometries, newGeometriesFactor = 1) {
|
|
624
|
+
/** Used geometries and how many instances use them */
|
|
625
|
+
const usedGeometries = new Map();
|
|
626
|
+
for (const handle of this._handles) {
|
|
627
|
+
if (handle && handle.__instanceIndex >= 0 && handle.object.geometry) {
|
|
628
|
+
if (!usedGeometries.has(handle.object.geometry)) {
|
|
629
|
+
const data = getMeshInformation(handle.object.geometry);
|
|
630
|
+
const meshinfo = { count: 1, ...data };
|
|
631
|
+
usedGeometries.set(handle.object.geometry, meshinfo);
|
|
632
|
+
}
|
|
633
|
+
else {
|
|
634
|
+
const entry = usedGeometries.get(handle.object.geometry);
|
|
635
|
+
entry.count += 1;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
// then calculate the total vertex count
|
|
640
|
+
let totalVertices = 0;
|
|
641
|
+
let totalIndices = 0;
|
|
642
|
+
// let maxVertices = 0;
|
|
643
|
+
for (const [_geo, data] of usedGeometries) {
|
|
644
|
+
totalVertices += data.vertexCount * data.count;
|
|
645
|
+
totalIndices += data.indexCount * data.count;
|
|
646
|
+
// maxVertices = Math.max(maxVertices, geo.attributes.position.count * count);
|
|
647
|
+
}
|
|
648
|
+
// we calculate the average to make an educated guess of how many vertices will be needed with the new buffer count
|
|
649
|
+
const averageVerts = Math.ceil(totalVertices / Math.max(1, this._currentInstanceCount));
|
|
650
|
+
let maxVertexCount = averageVerts * newMaxInstances;
|
|
651
|
+
const averageIndices = Math.ceil(totalIndices / Math.max(1, this._currentInstanceCount));
|
|
652
|
+
let maxIndexCount = averageIndices * newMaxInstances * 2;
|
|
653
|
+
// if new geometries are provided we *know* that they will be added
|
|
654
|
+
// so we make sure to include them in the calculation
|
|
655
|
+
if (_newGeometries) {
|
|
656
|
+
for (const geo of _newGeometries) {
|
|
657
|
+
const meshinfo = getMeshInformation(geo);
|
|
658
|
+
if (meshinfo != null) {
|
|
659
|
+
maxVertexCount += meshinfo.vertexCount * newGeometriesFactor;
|
|
660
|
+
maxIndexCount += meshinfo.indexCount * newGeometriesFactor;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
return { vertexCount: maxVertexCount, indexCount: maxIndexCount };
|
|
665
|
+
}
|
|
666
|
+
addGeometry(handle) {
|
|
667
|
+
const obj = handle.object;
|
|
668
|
+
const geo = obj.geometry;
|
|
669
|
+
if (!geo) {
|
|
670
|
+
// if the geometry is null we cannot add it
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
// otherwise add more geometry / instances
|
|
674
|
+
let geometryId = this._geometryIds.get(geo);
|
|
675
|
+
if (geometryId === undefined || geometryId === null) {
|
|
676
|
+
if (debugInstancing)
|
|
677
|
+
console.debug(`[Instancing] > ADD NEW GEOMETRY \"${handle.name} (${geo.name}; ${geo.uuid})\"\n${this._currentInstanceCount} instances, ${handle.maxVertexCount} max vertices, ${handle.maxIndexCount} max indices`);
|
|
678
|
+
geometryId = this._batchedMesh.addGeometry(geo, handle.maxVertexCount, handle.maxIndexCount);
|
|
679
|
+
this._geometryIds.set(geo, geometryId);
|
|
680
|
+
}
|
|
681
|
+
else {
|
|
682
|
+
if (debugInstancing === "verbose")
|
|
683
|
+
console.log(`[Instancing] > ADD INSTANCE \"${handle.name}\"\nGEOMETRY_ID=${geometryId}\n${this._currentInstanceCount} instances`);
|
|
684
|
+
}
|
|
685
|
+
this._currentVertexCount += handle.maxVertexCount;
|
|
686
|
+
this._currentIndexCount += handle.maxIndexCount;
|
|
687
|
+
const i = this._batchedMesh.addInstance(geometryId);
|
|
688
|
+
handle.__geometryIndex = geometryId;
|
|
689
|
+
handle.__instanceIndex = i;
|
|
690
|
+
handle.__reservedVertexRange = handle.maxVertexCount;
|
|
691
|
+
handle.__reservedIndexRange = handle.maxIndexCount;
|
|
692
|
+
this._batchedMesh.setMatrixAt(i, handle.object.matrixWorld);
|
|
693
|
+
if (debugInstancing)
|
|
694
|
+
console.debug(`[Instancing] > ADDED INSTANCE \"${handle.name}\"\nGEOMETRY_ID=${geometryId}\n${this._currentInstanceCount} instances\nIndex: ${handle.__instanceIndex}`);
|
|
695
|
+
}
|
|
696
|
+
removeGeometry(handle, _del) {
|
|
697
|
+
if (handle.__instanceIndex < 0) {
|
|
698
|
+
console.warn("Cannot remove geometry, instance index is invalid", handle.name);
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
// deleteGeometry is currently not useable since there's no optimize method
|
|
702
|
+
// https://github.com/mrdoob/three.js/issues/27985
|
|
703
|
+
// if (del)
|
|
704
|
+
// this.inst.deleteGeometry(handle.__instanceIndex);
|
|
705
|
+
// else
|
|
706
|
+
// this._batchedMesh.setVisibleAt(handle.__instanceIndex, false);
|
|
707
|
+
if (debugInstancing) {
|
|
708
|
+
console.debug(`[Instancing] < REMOVE INSTANCE \"${handle.name}\" at [${handle.__instanceIndex}]\nGEOMETRY_ID=${handle.__geometryIndex}\n${this._currentInstanceCount} instances\nIndex: ${handle.__instanceIndex}`);
|
|
709
|
+
}
|
|
710
|
+
this._batchedMesh.deleteInstance(handle.__instanceIndex);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
function getMeshInformation(geo) {
|
|
714
|
+
if (!geo) {
|
|
715
|
+
if (isDevEnvironment())
|
|
716
|
+
console.error("Cannot get mesh information from null geometry");
|
|
717
|
+
return { vertexCount: 0, indexCount: 0 };
|
|
718
|
+
}
|
|
719
|
+
let vertexCount = geo.attributes?.position?.count || 0;
|
|
720
|
+
let indexCount = geo.index ? geo.index.count : 0;
|
|
721
|
+
const lodInfo = NEEDLE_progressive.getMeshLODExtension(geo);
|
|
722
|
+
if (lodInfo) {
|
|
723
|
+
const lod0 = lodInfo.lods[0];
|
|
724
|
+
let lod0Count = lod0.vertexCount;
|
|
725
|
+
let lod0IndexCount = lod0.indexCount;
|
|
726
|
+
// add some wiggle room: https://linear.app/needle/issue/NE-4505
|
|
727
|
+
const extra = Math.min(200, Math.ceil(lod0Count * .05));
|
|
728
|
+
lod0Count += extra;
|
|
729
|
+
lod0IndexCount += 20;
|
|
730
|
+
vertexCount = Math.max(vertexCount, lod0Count);
|
|
731
|
+
indexCount = Math.max(indexCount, lod0IndexCount);
|
|
732
|
+
}
|
|
733
|
+
vertexCount = Math.ceil(vertexCount);
|
|
734
|
+
indexCount = Math.ceil(indexCount);
|
|
735
|
+
return { vertexCount, indexCount };
|
|
736
|
+
}
|
|
737
|
+
function createDebugMaterial() {
|
|
738
|
+
const mat = new MeshStandardMaterial({ color: new Color(Math.random(), Math.random(), Math.random()) });
|
|
739
|
+
mat.emissive = mat.color;
|
|
740
|
+
mat.emissiveIntensity = .3;
|
|
741
|
+
if (getParam("wireframe"))
|
|
742
|
+
mat.wireframe = true;
|
|
743
|
+
return mat;
|
|
744
|
+
}
|
|
745
745
|
//# sourceMappingURL=RendererInstancing.js.map
|