@tresjs/cientos 5.3.1 → 5.4.0

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.
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * name: @tresjs/cientos
3
- * version: v5.3.1
3
+ * version: v5.4.0
4
4
  * (c) 2026
5
5
  * description: Collection of useful helpers and fully functional, ready-made abstractions for Tres
6
6
  * author: Alvaro Saburido <hola@alvarosaburido.dev> (https://github.com/alvarosabu/)
7
7
  */
8
- import { Fragment, Suspense, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, inject, isReactive, isRef, mergeProps, nextTick, normalizeProps, onBeforeUnmount, onMounted, onUnmounted, openBlock, provide, reactive, ref, render, renderList, renderSlot, shallowReactive, shallowRef, toRaw, toRefs, toValue, triggerRef, unref, useAttrs, useSlots, watch, watchEffect, withAsyncContext, withCtx } from "vue";
9
- import { buildGraph, extend, logError, logWarning, normalizeColor, normalizeVectorFlexibleParam, useLoader, useLoop, useTres, useTresContext } from "@tresjs/core";
8
+ import { Fragment, Suspense, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, inject, isReactive, isRef, mergeDefaults, mergeProps, nextTick, normalizeProps, onBeforeUnmount, onMounted, onUnmounted, openBlock, provide, reactive, ref, render, renderList, renderSlot, shallowReactive, shallowRef, toRaw, toRefs, toValue, triggerRef, unref, useAttrs, useSlots, watch, watchEffect, withAsyncContext, withCtx } from "vue";
9
+ import { buildGraph, extend, isObject3D, logError, logWarning, normalizeColor, normalizeVectorFlexibleParam, useLoader, useLoop, useTres, useTresContext } from "@tresjs/core";
10
10
  import * as THREE from "three";
11
11
  import { AdditiveBlending, AlwaysStencilFunc, AnimationMixer, Audio, AudioListener, AudioLoader, BackSide, Box2, Box3, BoxGeometry, BufferAttribute, BufferGeometry, Camera, CatmullRomCurve3, ClampToEdgeWrapping, Clock, Color, CubeCamera, CubeReflectionMapping, CubeTextureLoader, CubicBezierCurve3, DataTexture, DefaultLoadingManager, DepthTexture, DirectionalLight, DoubleSide, EdgesGeometry, EqualStencilFunc, EquirectangularReflectionMapping, Euler, FloatType, FramebufferTexture, FrontSide, Group, HalfFloatType, IcosahedronGeometry, InstancedMesh, InterleavedBuffer, InterleavedBufferAttribute, KeepStencilOp, LOD, LinearFilter, MOUSE, MathUtils, Matrix4, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshLambertMaterial, MeshStandardMaterial, NearestFilter, NoBlending, NotEqualStencilFunc, Object3D, OrthographicCamera, PerspectiveCamera, Plane, PlaneGeometry, Points, PointsMaterial, QuadraticBezierCurve3, Quaternion, REVISION, RGBAFormat, RawShaderMaterial, Raycaster, RepeatWrapping, ReplaceStencilOp, Scene, ShaderChunk, ShaderMaterial, ShapeGeometry, SkinnedMesh, Sphere, Spherical, TOUCH, TangentSpaceNormalMap, Texture, TextureLoader, UVMapping, Uniform, UniformsUtils, UnsignedByteType, Vector2, Vector3, Vector4, VideoTexture, WebGLCubeRenderTarget, WebGLRenderTarget, WebGLRenderer } from "three";
12
12
  import { tryOnScopeDispose, useDebounceFn, useElementSize, useEventListener, useMagicKeys, useMouse, useScroll, useWindowScroll, useWindowSize, watchThrottled, whenever } from "@vueuse/core";
@@ -15,6 +15,7 @@ import BaseCameraControls, { default as CameraControls } from "camera-controls";
15
15
  import CustomShaderMaterial from "three-custom-shader-material/vanilla";
16
16
  import StatsImpl from "stats.js";
17
17
  import StatsGlImpl from "stats-gl";
18
+ import { BVHHelper, MeshBVH, acceleratedRaycast } from "three-mesh-bvh";
18
19
 
19
20
  //#region src/core/abstractions/AnimatedSprite/AtlasAnimationDefinitionParser.ts
20
21
  /**
@@ -3594,19 +3595,16 @@ var CameraControls_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
3594
3595
  const touches = computed(() => getTouches(props.camera || activeCamera.value, props.touches));
3595
3596
  const controlsRef = shallowRef(null);
3596
3597
  extend$1({ CameraControls });
3597
- watchEffect(() => {
3598
- addEventListeners();
3599
- if (controlsRef.value && makeDefault.value) controls.value = controlsRef.value;
3600
- else controls.value = null;
3601
- });
3602
- function addEventListeners() {
3603
- useEventListener(controlsRef.value, "update", () => {
3604
- emit("change", controlsRef.value);
3598
+ whenever(controlsRef, (value) => {
3599
+ value.addEventListener("update", () => {
3600
+ controlsRef.value && emit("change", controlsRef.value);
3605
3601
  invalidate();
3606
3602
  });
3607
- useEventListener(controlsRef.value, "controlend", () => emit("end", controlsRef.value));
3608
- useEventListener(controlsRef.value, "controlstart", () => emit("start", controlsRef.value));
3609
- }
3603
+ value.addEventListener("controlend", () => controlsRef.value && emit("end", controlsRef.value));
3604
+ value.addEventListener("controlstart", () => controlsRef.value && emit("start", controlsRef.value));
3605
+ if (makeDefault.value) controls.value = value;
3606
+ else controls.value = null;
3607
+ }, { once: true });
3610
3608
  const { onBeforeRender } = useLoop();
3611
3609
  onBeforeRender(({ delta }) => {
3612
3610
  if (controlsRef.value?.enabled) controlsRef.value?.update(delta);
@@ -3764,8 +3762,12 @@ var KeyboardControls_vue_vue_type_script_setup_true_lang_default = /* @__PURE__
3764
3762
  else forwardMove.value = 0;
3765
3763
  });
3766
3764
  __expose({ instance: controls });
3767
- const isActive = (isLock) => emit("isLock", isLock);
3768
- const hasChange = (state) => emit("change", state);
3765
+ const isActive = (isLock) => {
3766
+ emit("isLock", isLock);
3767
+ };
3768
+ const hasChange = (state) => {
3769
+ emit("change", state);
3770
+ };
3769
3771
  const moveVector = new Vector3();
3770
3772
  const rotationVector = new Vector3();
3771
3773
  const tmpQuaternion = new Quaternion();
@@ -3776,7 +3778,10 @@ var KeyboardControls_vue_vue_type_script_setup_true_lang_default = /* @__PURE__
3776
3778
  camera?.translateZ(-movementSpeed);
3777
3779
  tmpQuaternion.set(rotationVector.x * rotMult, rotationVector.y * rotMult, rotationVector.z * rotMult, 1).normalize();
3778
3780
  camera?.quaternion.multiply(tmpQuaternion);
3779
- if (sidewardMove.value || forwardMove.value) emit("change", controls.value);
3781
+ if (sidewardMove.value || forwardMove.value) {
3782
+ invalidate();
3783
+ emit("change", controls.value);
3784
+ }
3780
3785
  };
3781
3786
  const { onBeforeRender } = useLoop();
3782
3787
  onBeforeRender(({ delta }) => {
@@ -3808,10 +3813,68 @@ var KeyboardControls_vue_vue_type_script_setup_true_lang_default = /* @__PURE__
3808
3813
  //#region src/core/controls/KeyboardControls.vue
3809
3814
  var KeyboardControls_default = KeyboardControls_vue_vue_type_script_setup_true_lang_default;
3810
3815
 
3816
+ //#endregion
3817
+ //#region src/core/controls/useOrbitLikeControls.ts
3818
+ /** Shared default values for orbit-like controls (excludes touches, mouseButtons, screenSpacePanning). */
3819
+ const ORBIT_LIKE_DEFAULTS = {
3820
+ makeDefault: false,
3821
+ autoRotate: false,
3822
+ autoRotateSpeed: 2,
3823
+ enableDamping: true,
3824
+ dampingFactor: .05,
3825
+ enablePan: true,
3826
+ keyPanSpeed: 7,
3827
+ maxAzimuthAngle: Number.POSITIVE_INFINITY,
3828
+ minAzimuthAngle: Number.NEGATIVE_INFINITY,
3829
+ maxPolarAngle: Math.PI,
3830
+ minPolarAngle: 0,
3831
+ minDistance: 0,
3832
+ maxDistance: Number.POSITIVE_INFINITY,
3833
+ minZoom: 0,
3834
+ maxZoom: Number.POSITIVE_INFINITY,
3835
+ enableZoom: true,
3836
+ zoomSpeed: 1,
3837
+ enableRotate: true,
3838
+ rotateSpeed: 1,
3839
+ target: () => [
3840
+ 0,
3841
+ 0,
3842
+ 0
3843
+ ]
3844
+ };
3845
+ function useOrbitLikeControls(controlsRef, props, emit) {
3846
+ const { controls, invalidate } = useTres();
3847
+ watch(props, () => {
3848
+ invalidate();
3849
+ });
3850
+ whenever(controlsRef, (value) => {
3851
+ value.addEventListener("change", () => {
3852
+ invalidate();
3853
+ if (value) emit("change", controlsRef.value);
3854
+ });
3855
+ value.addEventListener("start", () => {
3856
+ controlsRef.value && emit("start", controlsRef.value);
3857
+ });
3858
+ value.addEventListener("end", () => {
3859
+ controlsRef.value && emit("end", controlsRef.value);
3860
+ });
3861
+ if (props.makeDefault) controls.value = value;
3862
+ else controls.value = null;
3863
+ }, { once: true });
3864
+ const { onBeforeRender } = useLoop();
3865
+ onBeforeRender(() => {
3866
+ if (controlsRef.value && controlsRef.value.enabled && (props.enableDamping || props.autoRotate)) controlsRef.value.update();
3867
+ });
3868
+ onUnmounted(() => {
3869
+ if (controlsRef.value) controlsRef.value.dispose();
3870
+ });
3871
+ }
3872
+
3811
3873
  //#endregion
3812
3874
  //#region src/core/controls/MapControls.vue?vue&type=script&setup=true&lang.ts
3813
3875
  const _hoisted_1$45 = [
3814
3876
  "args",
3877
+ "target",
3815
3878
  "auto-rotate",
3816
3879
  "auto-rotate-speed",
3817
3880
  "enable-damping",
@@ -3827,18 +3890,20 @@ const _hoisted_1$45 = [
3827
3890
  "max-distance",
3828
3891
  "min-zoom",
3829
3892
  "max-zoom",
3893
+ "touches",
3830
3894
  "enable-zoom",
3831
3895
  "zoom-speed",
3832
3896
  "enable-rotate",
3833
- "rotate-speed"
3897
+ "rotate-speed",
3898
+ "mouse-buttons",
3899
+ "screen-space-panning"
3834
3900
  ];
3835
3901
  var MapControls_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
3836
3902
  __name: "MapControls",
3837
- props: {
3903
+ props: /* @__PURE__ */ mergeDefaults({
3838
3904
  makeDefault: {
3839
3905
  type: Boolean,
3840
- required: false,
3841
- default: false
3906
+ required: false
3842
3907
  },
3843
3908
  camera: {
3844
3909
  type: Object,
@@ -3854,33 +3919,27 @@ var MapControls_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
3854
3919
  },
3855
3920
  enableDamping: {
3856
3921
  type: Boolean,
3857
- required: false,
3858
- default: true
3922
+ required: false
3859
3923
  },
3860
3924
  dampingFactor: {
3861
3925
  type: Number,
3862
- required: false,
3863
- default: .05
3926
+ required: false
3864
3927
  },
3865
3928
  autoRotate: {
3866
3929
  type: Boolean,
3867
- required: false,
3868
- default: false
3930
+ required: false
3869
3931
  },
3870
3932
  autoRotateSpeed: {
3871
3933
  type: Number,
3872
- required: false,
3873
- default: 2
3934
+ required: false
3874
3935
  },
3875
3936
  enablePan: {
3876
3937
  type: Boolean,
3877
- required: false,
3878
- default: true
3938
+ required: false
3879
3939
  },
3880
3940
  keyPanSpeed: {
3881
3941
  type: Number,
3882
- required: false,
3883
- default: 7
3942
+ required: false
3884
3943
  },
3885
3944
  keys: {
3886
3945
  type: Object,
@@ -3888,43 +3947,35 @@ var MapControls_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
3888
3947
  },
3889
3948
  maxAzimuthAngle: {
3890
3949
  type: Number,
3891
- required: false,
3892
- default: Number.POSITIVE_INFINITY
3950
+ required: false
3893
3951
  },
3894
3952
  minAzimuthAngle: {
3895
3953
  type: Number,
3896
- required: false,
3897
- default: Number.NEGATIVE_INFINITY
3954
+ required: false
3898
3955
  },
3899
3956
  maxPolarAngle: {
3900
3957
  type: Number,
3901
- required: false,
3902
- default: Math.PI
3958
+ required: false
3903
3959
  },
3904
3960
  minPolarAngle: {
3905
3961
  type: Number,
3906
- required: false,
3907
- default: 0
3962
+ required: false
3908
3963
  },
3909
3964
  minDistance: {
3910
3965
  type: Number,
3911
- required: false,
3912
- default: 0
3966
+ required: false
3913
3967
  },
3914
3968
  maxDistance: {
3915
3969
  type: Number,
3916
- required: false,
3917
- default: Number.POSITIVE_INFINITY
3970
+ required: false
3918
3971
  },
3919
3972
  minZoom: {
3920
3973
  type: Number,
3921
- required: false,
3922
- default: 0
3974
+ required: false
3923
3975
  },
3924
3976
  maxZoom: {
3925
3977
  type: Number,
3926
- required: false,
3927
- default: Number.POSITIVE_INFINITY
3978
+ required: false
3928
3979
  },
3929
3980
  touches: {
3930
3981
  type: Object,
@@ -3932,25 +3983,41 @@ var MapControls_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
3932
3983
  },
3933
3984
  enableZoom: {
3934
3985
  type: Boolean,
3935
- required: false,
3936
- default: true
3986
+ required: false
3937
3987
  },
3938
3988
  zoomSpeed: {
3939
3989
  type: Number,
3940
- required: false,
3941
- default: 1
3990
+ required: false
3942
3991
  },
3943
3992
  enableRotate: {
3944
3993
  type: Boolean,
3945
- required: false,
3946
- default: true
3994
+ required: false
3947
3995
  },
3948
3996
  rotateSpeed: {
3949
3997
  type: Number,
3950
- required: false,
3951
- default: 1
3998
+ required: false
3999
+ },
4000
+ mouseButtons: {
4001
+ type: Object,
4002
+ required: false
4003
+ },
4004
+ screenSpacePanning: {
4005
+ type: Boolean,
4006
+ required: false
3952
4007
  }
3953
- },
4008
+ }, {
4009
+ ...ORBIT_LIKE_DEFAULTS,
4010
+ touches: () => ({
4011
+ ONE: TOUCH.PAN,
4012
+ TWO: TOUCH.DOLLY_ROTATE
4013
+ }),
4014
+ mouseButtons: () => ({
4015
+ LEFT: MOUSE.PAN,
4016
+ MIDDLE: MOUSE.DOLLY,
4017
+ RIGHT: MOUSE.ROTATE
4018
+ }),
4019
+ screenSpacePanning: false
4020
+ }),
3954
4021
  emits: [
3955
4022
  "change",
3956
4023
  "start",
@@ -3959,34 +4026,10 @@ var MapControls_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
3959
4026
  setup(__props, { expose: __expose, emit: __emit }) {
3960
4027
  const props = __props;
3961
4028
  const emit = __emit;
3962
- const { autoRotate, autoRotateSpeed, enableDamping, dampingFactor, enablePan, keyPanSpeed, maxAzimuthAngle, minAzimuthAngle, maxPolarAngle, minPolarAngle, minDistance, maxDistance, minZoom, maxZoom, enableZoom, zoomSpeed, enableRotate, rotateSpeed } = toRefs(props);
3963
- const { camera: activeCamera, renderer, extend: extend$1, controls, invalidate } = useTres();
3964
- watch(props, () => {
3965
- invalidate();
3966
- });
4029
+ const { camera: activeCamera, renderer, extend: extend$1 } = useTres();
3967
4030
  const controlsRef = shallowRef(null);
3968
4031
  extend$1({ MapControls });
3969
- watch(controls, (value) => {
3970
- if (value && props.makeDefault) controls.value = value;
3971
- else controls.value = null;
3972
- });
3973
- function onChange() {
3974
- addEventListeners();
3975
- invalidate();
3976
- emit("change", controlsRef.value);
3977
- }
3978
- function addEventListeners() {
3979
- useEventListener(controlsRef.value, "change", onChange);
3980
- useEventListener(controlsRef.value, "start", () => emit("start", controlsRef.value));
3981
- useEventListener(controlsRef.value, "end", () => emit("end", controlsRef.value));
3982
- }
3983
- const { onBeforeRender } = useLoop();
3984
- onBeforeRender(() => {
3985
- if (controlsRef.value && (enableDamping.value || autoRotate.value)) controlsRef.value.update();
3986
- });
3987
- onUnmounted(() => {
3988
- if (controlsRef.value) controlsRef.value.dispose();
3989
- });
4032
+ useOrbitLikeControls(controlsRef, props, emit);
3990
4033
  __expose({ instance: controlsRef });
3991
4034
  return (_ctx, _cache) => {
3992
4035
  return (__props.camera || unref(activeCamera)) && (__props.domElement || unref(renderer).domElement) ? (openBlock(), createElementBlock("TresMapControls", {
@@ -3994,25 +4037,29 @@ var MapControls_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
3994
4037
  ref_key: "controlsRef",
3995
4038
  ref: controlsRef,
3996
4039
  args: [__props.camera || unref(activeCamera), __props.domElement || unref(renderer).domElement],
3997
- "auto-rotate": unref(autoRotate),
3998
- "auto-rotate-speed": unref(autoRotateSpeed),
3999
- "enable-damping": unref(enableDamping),
4000
- "damping-factor": unref(dampingFactor),
4001
- "enable-pan": unref(enablePan),
4002
- "key-pan-speed": unref(keyPanSpeed),
4040
+ target: __props.target,
4041
+ "auto-rotate": __props.autoRotate,
4042
+ "auto-rotate-speed": __props.autoRotateSpeed,
4043
+ "enable-damping": __props.enableDamping,
4044
+ "damping-factor": __props.dampingFactor,
4045
+ "enable-pan": __props.enablePan,
4046
+ "key-pan-speed": __props.keyPanSpeed,
4003
4047
  keys: __props.keys,
4004
- "max-azimuth-angle": unref(maxAzimuthAngle),
4005
- "min-azimuth-angle": unref(minAzimuthAngle),
4006
- "max-polar-angle": unref(maxPolarAngle),
4007
- "min-polar-angle": unref(minPolarAngle),
4008
- "min-distance": unref(minDistance),
4009
- "max-distance": unref(maxDistance),
4010
- "min-zoom": unref(minZoom),
4011
- "max-zoom": unref(maxZoom),
4012
- "enable-zoom": unref(enableZoom),
4013
- "zoom-speed": unref(zoomSpeed),
4014
- "enable-rotate": unref(enableRotate),
4015
- "rotate-speed": unref(rotateSpeed)
4048
+ "max-azimuth-angle": __props.maxAzimuthAngle,
4049
+ "min-azimuth-angle": __props.minAzimuthAngle,
4050
+ "max-polar-angle": __props.maxPolarAngle,
4051
+ "min-polar-angle": __props.minPolarAngle,
4052
+ "min-distance": __props.minDistance,
4053
+ "max-distance": __props.maxDistance,
4054
+ "min-zoom": __props.minZoom,
4055
+ "max-zoom": __props.maxZoom,
4056
+ touches: __props.touches,
4057
+ "enable-zoom": __props.enableZoom,
4058
+ "zoom-speed": __props.zoomSpeed,
4059
+ "enable-rotate": __props.enableRotate,
4060
+ "rotate-speed": __props.rotateSpeed,
4061
+ "mouse-buttons": __props.mouseButtons,
4062
+ "screen-space-panning": __props.screenSpacePanning
4016
4063
  }, null, 8, _hoisted_1$45)) : createCommentVNode("v-if", true);
4017
4064
  };
4018
4065
  }
@@ -4025,6 +4072,7 @@ var MapControls_default = MapControls_vue_vue_type_script_setup_true_lang_defaul
4025
4072
  //#endregion
4026
4073
  //#region src/core/controls/OrbitControls.vue?vue&type=script&setup=true&lang.ts
4027
4074
  const _hoisted_1$44 = [
4075
+ "args",
4028
4076
  "target",
4029
4077
  "auto-rotate",
4030
4078
  "auto-rotate-speed",
@@ -4047,15 +4095,18 @@ const _hoisted_1$44 = [
4047
4095
  "enable-rotate",
4048
4096
  "rotate-speed",
4049
4097
  "mouse-buttons",
4050
- "args"
4098
+ "screen-space-panning"
4051
4099
  ];
4052
4100
  var OrbitControls_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
4053
4101
  __name: "OrbitControls",
4054
- props: {
4102
+ props: /* @__PURE__ */ mergeDefaults({
4103
+ mouseButtons: {
4104
+ type: Object,
4105
+ required: false
4106
+ },
4055
4107
  makeDefault: {
4056
4108
  type: Boolean,
4057
- required: false,
4058
- default: false
4109
+ required: false
4059
4110
  },
4060
4111
  camera: {
4061
4112
  type: Object,
@@ -4067,42 +4118,31 @@ var OrbitControls_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
4067
4118
  },
4068
4119
  target: {
4069
4120
  type: null,
4070
- required: false,
4071
- default: () => [
4072
- 0,
4073
- 0,
4074
- 0
4075
- ]
4121
+ required: false
4076
4122
  },
4077
4123
  enableDamping: {
4078
4124
  type: Boolean,
4079
- required: false,
4080
- default: true
4125
+ required: false
4081
4126
  },
4082
4127
  dampingFactor: {
4083
4128
  type: Number,
4084
- required: false,
4085
- default: .05
4129
+ required: false
4086
4130
  },
4087
4131
  autoRotate: {
4088
4132
  type: Boolean,
4089
- required: false,
4090
- default: false
4133
+ required: false
4091
4134
  },
4092
4135
  autoRotateSpeed: {
4093
4136
  type: Number,
4094
- required: false,
4095
- default: 2
4137
+ required: false
4096
4138
  },
4097
4139
  enablePan: {
4098
4140
  type: Boolean,
4099
- required: false,
4100
- default: true
4141
+ required: false
4101
4142
  },
4102
4143
  keyPanSpeed: {
4103
4144
  type: Number,
4104
- required: false,
4105
- default: 7
4145
+ required: false
4106
4146
  },
4107
4147
  keys: {
4108
4148
  type: Object,
@@ -4110,82 +4150,73 @@ var OrbitControls_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
4110
4150
  },
4111
4151
  maxAzimuthAngle: {
4112
4152
  type: Number,
4113
- required: false,
4114
- default: Number.POSITIVE_INFINITY
4153
+ required: false
4115
4154
  },
4116
4155
  minAzimuthAngle: {
4117
4156
  type: Number,
4118
- required: false,
4119
- default: Number.NEGATIVE_INFINITY
4157
+ required: false
4120
4158
  },
4121
4159
  maxPolarAngle: {
4122
4160
  type: Number,
4123
- required: false,
4124
- default: Math.PI
4161
+ required: false
4125
4162
  },
4126
4163
  minPolarAngle: {
4127
4164
  type: Number,
4128
- required: false,
4129
- default: 0
4165
+ required: false
4130
4166
  },
4131
4167
  minDistance: {
4132
4168
  type: Number,
4133
- required: false,
4134
- default: 0
4169
+ required: false
4135
4170
  },
4136
4171
  maxDistance: {
4137
4172
  type: Number,
4138
- required: false,
4139
- default: Number.POSITIVE_INFINITY
4173
+ required: false
4140
4174
  },
4141
4175
  minZoom: {
4142
4176
  type: Number,
4143
- required: false,
4144
- default: 0
4177
+ required: false
4145
4178
  },
4146
4179
  maxZoom: {
4147
4180
  type: Number,
4148
- required: false,
4149
- default: Number.POSITIVE_INFINITY
4181
+ required: false
4150
4182
  },
4151
4183
  touches: {
4152
4184
  type: Object,
4153
- required: false,
4154
- default: () => ({
4155
- ONE: TOUCH.ROTATE,
4156
- TWO: TOUCH.DOLLY_PAN
4157
- })
4185
+ required: false
4158
4186
  },
4159
4187
  enableZoom: {
4160
4188
  type: Boolean,
4161
- required: false,
4162
- default: true
4189
+ required: false
4163
4190
  },
4164
4191
  zoomSpeed: {
4165
4192
  type: Number,
4166
- required: false,
4167
- default: 1
4193
+ required: false
4168
4194
  },
4169
4195
  enableRotate: {
4170
4196
  type: Boolean,
4171
- required: false,
4172
- default: true
4197
+ required: false
4173
4198
  },
4174
4199
  rotateSpeed: {
4175
4200
  type: Number,
4176
- required: false,
4177
- default: 1
4201
+ required: false
4178
4202
  },
4179
- mouseButtons: {
4180
- type: Object,
4181
- required: false,
4182
- default: () => ({
4183
- LEFT: MOUSE.ROTATE,
4184
- MIDDLE: MOUSE.DOLLY,
4185
- RIGHT: MOUSE.PAN
4186
- })
4203
+ screenSpacePanning: {
4204
+ type: Boolean,
4205
+ required: false
4187
4206
  }
4188
- },
4207
+ }, {
4208
+ ...ORBIT_LIKE_DEFAULTS,
4209
+ touches: () => ({
4210
+ ONE: TOUCH.ROTATE,
4211
+ TWO: TOUCH.DOLLY_PAN
4212
+ }),
4213
+ mouseButtons: () => ({
4214
+ LEFT: MOUSE.ROTATE,
4215
+ MIDDLE: MOUSE.DOLLY,
4216
+ RIGHT: MOUSE.PAN
4217
+ }),
4218
+ screenSpacePanning: true
4219
+ }),
4189
4220
  emits: [
4190
4221
  "change",
4191
4222
  "start",
@@ -4194,62 +4225,40 @@ var OrbitControls_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
4194
4225
  setup(__props, { expose: __expose, emit: __emit }) {
4195
4226
  const props = __props;
4196
4227
  const emit = __emit;
4197
- const { makeDefault, autoRotate, autoRotateSpeed, enableDamping, dampingFactor, enablePan, keyPanSpeed, maxAzimuthAngle, minAzimuthAngle, maxPolarAngle, minPolarAngle, minDistance, maxDistance, minZoom, maxZoom, enableZoom, zoomSpeed, enableRotate, touches, rotateSpeed, target, mouseButtons } = toRefs(props);
4198
- const { camera: activeCamera, renderer, extend: extend$1, controls, invalidate } = useTres();
4228
+ const { camera: activeCamera, renderer, extend: extend$1 } = useTres();
4199
4229
  const controlsRef = shallowRef(null);
4200
4230
  extend$1({ OrbitControls });
4201
- watch(controlsRef, (value) => {
4202
- addEventListeners();
4203
- if (value && makeDefault.value) controls.value = value;
4204
- else controls.value = null;
4205
- });
4206
- function addEventListeners() {
4207
- useEventListener(controlsRef.value, "change", () => {
4208
- emit("change", controlsRef.value);
4209
- invalidate();
4210
- });
4211
- useEventListener(controlsRef.value, "start", () => emit("start", controlsRef.value));
4212
- useEventListener(controlsRef.value, "end", () => emit("end", controlsRef.value));
4213
- }
4214
- const { onBeforeRender } = useLoop();
4215
- onBeforeRender(() => {
4216
- if (controlsRef.value && (enableDamping.value || autoRotate.value)) {
4217
- controlsRef.value.update();
4218
- if (autoRotate.value) {}
4219
- }
4220
- });
4221
- onUnmounted(() => {
4222
- if (controlsRef.value) controlsRef.value.dispose();
4223
- });
4231
+ useOrbitLikeControls(controlsRef, props, emit);
4224
4232
  __expose({ instance: controlsRef });
4225
4233
  return (_ctx, _cache) => {
4226
4234
  return (__props.camera || unref(activeCamera)) && (__props.domElement || unref(renderer).domElement) ? (openBlock(), createElementBlock("TresOrbitControls", {
4227
4235
  ref_key: "controlsRef",
4228
4236
  ref: controlsRef,
4229
4237
  key: (__props.camera || unref(activeCamera))?.uuid,
4230
- target: unref(target),
4231
- "auto-rotate": unref(autoRotate),
4232
- "auto-rotate-speed": unref(autoRotateSpeed),
4233
- "enable-damping": unref(enableDamping),
4234
- "damping-factor": unref(dampingFactor),
4235
- "enable-pan": unref(enablePan),
4236
- "key-pan-speed": unref(keyPanSpeed),
4238
+ args: [__props.camera || unref(activeCamera), __props.domElement || unref(renderer).domElement],
4239
+ target: __props.target,
4240
+ "auto-rotate": __props.autoRotate,
4241
+ "auto-rotate-speed": __props.autoRotateSpeed,
4242
+ "enable-damping": __props.enableDamping,
4243
+ "damping-factor": __props.dampingFactor,
4244
+ "enable-pan": __props.enablePan,
4245
+ "key-pan-speed": __props.keyPanSpeed,
4237
4246
  keys: __props.keys,
4238
- "max-azimuth-angle": unref(maxAzimuthAngle),
4239
- "min-azimuth-angle": unref(minAzimuthAngle),
4240
- "max-polar-angle": unref(maxPolarAngle),
4241
- "min-polar-angle": unref(minPolarAngle),
4242
- "min-distance": unref(minDistance),
4243
- "max-distance": unref(maxDistance),
4244
- "min-zoom": unref(minZoom),
4245
- "max-zoom": unref(maxZoom),
4246
- touches: unref(touches),
4247
- "enable-zoom": unref(enableZoom),
4248
- "zoom-speed": unref(zoomSpeed),
4249
- "enable-rotate": unref(enableRotate),
4250
- "rotate-speed": unref(rotateSpeed),
4251
- "mouse-buttons": unref(mouseButtons),
4252
- args: [__props.camera || unref(activeCamera), __props.domElement || unref(renderer).domElement]
4247
+ "max-azimuth-angle": __props.maxAzimuthAngle,
4248
+ "min-azimuth-angle": __props.minAzimuthAngle,
4249
+ "max-polar-angle": __props.maxPolarAngle,
4250
+ "min-polar-angle": __props.minPolarAngle,
4251
+ "min-distance": __props.minDistance,
4252
+ "max-distance": __props.maxDistance,
4253
+ "min-zoom": __props.minZoom,
4254
+ "max-zoom": __props.maxZoom,
4255
+ touches: __props.touches,
4256
+ "enable-zoom": __props.enableZoom,
4257
+ "zoom-speed": __props.zoomSpeed,
4258
+ "enable-rotate": __props.enableRotate,
4259
+ "rotate-speed": __props.rotateSpeed,
4260
+ "mouse-buttons": __props.mouseButtons,
4261
+ "screen-space-panning": __props.screenSpacePanning
4253
4262
  }, null, 8, _hoisted_1$44)) : createCommentVNode("v-if", true);
4254
4263
  };
4255
4264
  }
@@ -4306,6 +4315,7 @@ var PointerLockControls_vue_vue_type_script_setup_true_lang_default = /* @__PURE
4306
4315
  controlsRef.value.lock();
4307
4316
  controlsRef.value.addEventListener("lock", () => isLockEmitter(true));
4308
4317
  controlsRef.value.addEventListener("unlock", () => isLockEmitter(false));
4318
+ controlsRef.value.addEventListener("change", () => invalidate());
4309
4319
  invalidate();
4310
4320
  }
4311
4321
  });
@@ -7360,6 +7370,145 @@ function useIntersect(onChange = () => {}) {
7360
7370
  };
7361
7371
  }
7362
7372
 
7373
+ //#endregion
7374
+ //#region src/core/performance/useBVH.ts
7375
+ /**
7376
+ * Vue composable for BVH optimization - speeds up raycasting
7377
+ * Automatically computes boundsTree and assigns acceleratedRaycast for meshes
7378
+ * Not side-effect free: mutates mesh.raycast; reverts to original when disabled or unmounted
7379
+ */
7380
+ const useBVH = (target, { enabled = true, firstHitOnly = false, splitStrategy = "SAH", verbose = false, setBoundingBox = true, maxDepth = 40, maxLeafSize = 10, indirect = false, debug = false } = {}) => {
7381
+ const DEBUG_OPACITY = .3;
7382
+ let processedMeshes = [];
7383
+ const debugGroup = new Group();
7384
+ debugGroup.name = "BVH-Debug-Helpers";
7385
+ const bvhOptions = {
7386
+ splitStrategy,
7387
+ verbose,
7388
+ setBoundingBox,
7389
+ maxDepth,
7390
+ maxLeafSize,
7391
+ indirect
7392
+ };
7393
+ /**
7394
+ * Recursively traverse object3D and find all meshes (including SkinnedMesh)
7395
+ */
7396
+ const getAllMeshes = (object) => {
7397
+ const meshes = [];
7398
+ object.traverse((child) => {
7399
+ if (verbose) console.log(`BVH: Found object - Type: ${child.type}, Name: ${child.name || "unnamed"}`);
7400
+ if ((child instanceof Mesh || child instanceof SkinnedMesh) && "geometry" in child && "material" in child) meshes.push(child);
7401
+ });
7402
+ return meshes;
7403
+ };
7404
+ /**
7405
+ * Apply BVH optimization to a mesh (Mesh or SkinnedMesh)
7406
+ */
7407
+ const applyBVHToMesh = (mesh) => {
7408
+ if (!mesh.geometry?.attributes.position) {
7409
+ if (verbose) console.warn("BVH: Mesh has no geometry or position attribute", mesh);
7410
+ return null;
7411
+ }
7412
+ const originalRaycast = mesh.raycast;
7413
+ try {
7414
+ const boundsTree = new MeshBVH(mesh.geometry, bvhOptions);
7415
+ mesh.geometry.boundsTree = boundsTree;
7416
+ if (firstHitOnly) mesh.raycast = function(raycaster, intersects) {
7417
+ const boundsTree$1 = this.geometry.boundsTree;
7418
+ if (boundsTree$1) {
7419
+ if (!this.layers.test(raycaster.layers)) return;
7420
+ if (!(boundsTree$1 instanceof MeshBVH)) return;
7421
+ const side = (Array.isArray(this.material) ? this.material[0] : this.material)?.side ?? raycaster.params.Mesh?.side;
7422
+ const hit = boundsTree$1.raycastFirst(raycaster.ray, side, raycaster.near, raycaster.far);
7423
+ if (hit) {
7424
+ hit.object = this;
7425
+ intersects.push(hit);
7426
+ }
7427
+ } else originalRaycast.call(this, raycaster, intersects);
7428
+ };
7429
+ else mesh.raycast = acceleratedRaycast;
7430
+ return {
7431
+ mesh,
7432
+ originalRaycast,
7433
+ geometry: mesh.geometry,
7434
+ boundsTree
7435
+ };
7436
+ } catch (error) {
7437
+ if (verbose) console.error("BVH: Failed to create bounds tree for mesh", mesh, error);
7438
+ return null;
7439
+ }
7440
+ };
7441
+ /**
7442
+ * Create debug helper for a processed mesh
7443
+ */
7444
+ const createDebugHelper = (processedMesh) => {
7445
+ if (!!processedMesh.debugHelper || !isObject3D(processedMesh.mesh)) return;
7446
+ const helper = new BVHHelper(processedMesh.mesh, processedMesh.boundsTree, maxDepth);
7447
+ helper.opacity = DEBUG_OPACITY;
7448
+ helper.update();
7449
+ processedMesh.debugHelper = helper;
7450
+ processedMesh.mesh.parent?.add(helper);
7451
+ };
7452
+ /**
7453
+ * Remove debug helper from a processed mesh
7454
+ */
7455
+ const removeDebugHelper = (processedMesh) => {
7456
+ if (!processedMesh.debugHelper) return;
7457
+ processedMesh.debugHelper.removeFromParent();
7458
+ processedMesh.debugHelper = void 0;
7459
+ };
7460
+ /**
7461
+ * Remove BVH optimization from a mesh
7462
+ */
7463
+ const removeBVHFromMesh = (processedMesh) => {
7464
+ const { mesh, originalRaycast, geometry } = processedMesh;
7465
+ removeDebugHelper(processedMesh);
7466
+ mesh.raycast = originalRaycast;
7467
+ if (geometry.disposeBoundsTree) geometry.disposeBoundsTree();
7468
+ else if (geometry.boundsTree) geometry.boundsTree = void 0;
7469
+ };
7470
+ /**
7471
+ * Apply BVH optimization to an object and all its mesh children
7472
+ */
7473
+ const applyBVH = (object) => {
7474
+ if (!toValue(enabled)) {
7475
+ if (verbose) console.log("BVH: Optimization disabled, skipping");
7476
+ return;
7477
+ }
7478
+ getAllMeshes(object).filter((mesh) => !processedMeshes.some((pm) => pm.mesh === mesh)).forEach((mesh) => {
7479
+ const processedMesh = applyBVHToMesh(mesh);
7480
+ if (processedMesh) {
7481
+ processedMeshes.push(processedMesh);
7482
+ if (toValue(debug)) createDebugHelper(processedMesh);
7483
+ }
7484
+ });
7485
+ if (verbose) console.log(`BVH: Applied optimization to ${processedMeshes.length} meshes`);
7486
+ };
7487
+ /**
7488
+ * Remove BVH optimization from all processed meshes
7489
+ */
7490
+ const removeBVH = () => {
7491
+ processedMeshes.forEach(removeBVHFromMesh);
7492
+ processedMeshes = [];
7493
+ };
7494
+ whenever(() => toValue(target), () => {
7495
+ const objectValue = toValue(target);
7496
+ if (objectValue && toValue(enabled)) applyBVH(objectValue);
7497
+ });
7498
+ watch(() => toValue(enabled), (enabled$1) => {
7499
+ if (enabled$1) {
7500
+ const objectValue = toValue(target);
7501
+ if (objectValue) applyBVH(objectValue);
7502
+ } else removeBVH();
7503
+ });
7504
+ watch(() => toValue(debug), () => {
7505
+ processedMeshes.forEach(toValue(debug) ? createDebugHelper : removeDebugHelper);
7506
+ }, { immediate: true });
7507
+ onUnmounted(() => {
7508
+ removeBVH();
7509
+ });
7510
+ };
7511
+
7363
7512
  //#endregion
7364
7513
  //#region src/core/shapes/Box.vue?vue&type=script&setup=true&lang.ts
7365
7514
  const _hoisted_1$32 = ["args"];
@@ -11678,7 +11827,7 @@ var component_vue_vue_type_script_setup_true_lang_default$1 = /* @__PURE__ */ de
11678
11827
  mat.uniforms.uNormal.value = normal;
11679
11828
  mat.uniforms.uTime.value = elapsed / (props.cooldownSec + props.lifetimeSec);
11680
11829
  });
11681
- function isObject3D(o) {
11830
+ function isObject3D$1(o) {
11682
11831
  return o && "isObject3D" in o;
11683
11832
  }
11684
11833
  function isBufferGeometry(o) {
@@ -11687,8 +11836,8 @@ var component_vue_vue_type_script_setup_true_lang_default$1 = /* @__PURE__ */ de
11687
11836
  onMounted(() => {
11688
11837
  if (props.geometry) {
11689
11838
  if (isBufferGeometry(props.geometry)) sparkles.geometry.copy(props.geometry);
11690
- else if (isObject3D(props.geometry) && "geometry" in props.geometry && isBufferGeometry(props.geometry.geometry)) sparkles.geometry.copy(props.geometry.geometry);
11691
- } else if (isObject3D(sparkles.parent) && "geometry" in sparkles.parent && isBufferGeometry(sparkles.parent.geometry)) sparkles.geometry.copy(sparkles.parent.geometry);
11839
+ else if (isObject3D$1(props.geometry) && "geometry" in props.geometry && isBufferGeometry(props.geometry.geometry)) sparkles.geometry.copy(props.geometry.geometry);
11840
+ } else if (isObject3D$1(sparkles.parent) && "geometry" in sparkles.parent && isBufferGeometry(sparkles.parent.geometry)) sparkles.geometry.copy(sparkles.parent.geometry);
11692
11841
  else sparkles.geometry = new IcosahedronGeometry(1, 16);
11693
11842
  if (typeof props.map === "string") {
11694
11843
  const { state: texture$1 } = useTexture(props.map);
@@ -12403,4 +12552,4 @@ function extractBindingPosition(binding) {
12403
12552
  }
12404
12553
 
12405
12554
  //#endregion
12406
- export { component_default as AccumulativeShadows, Align_default as Align, component_default$1 as AnimatedSprite, Backdrop_default as Backdrop, BakeShadows, BaseCameraControls, Billboard_default as Billboard, component_default$2 as Bounds, Box_default as Box, CameraControls_default as CameraControls, CameraShake_default as CameraShake, CatmullRomCurve3_default as CatmullRomCurve3, Circle_default as Circle, CircleShadow_default as CircleShadow, Cone_default as Cone, ContactShadows_default as ContactShadows, component_default$3 as CubeCamera, CubicBezierLine_default as CubicBezierLine, customShaderMaterial_default as CustomShaderMaterial, Cylinder_default as Cylinder, Dodecahedron_default as Dodecahedron, Edges_default as Edges, component_default$4 as Environment, component_default$5 as FBXModel, component_default$6 as Fbo, Fit_default as Fit, component_default$7 as GLTFModel, GlobalAudio, GradientTexture_default as GradientTexture, Grid_default as Grid, component_default$8 as Helper, holographicMaterial_default as HolographicMaterial, HTML_default as Html, Icosahedron_default as Icosahedron, component_default$9 as Image, KeyboardControls_default as KeyboardControls, LOD_default as LOD, component_default$10 as Lensflare, Levioso_default as Levioso, lightformer_default as Lightformer, Line2_default as Line2, MapControls_default as MapControls, MarchingCube_default as MarchingCube, MarchingCubes_default as MarchingCubes, MarchingPlane_default as MarchingPlane, component_default$11 as Mask, meshDiscardMaterial_default as MeshDiscardMaterial, meshGlassMaterial_default as MeshGlassMaterial, meshReflectionMaterial_default as MeshReflectionMaterial, meshWobbleMaterial_default as MeshWobbleMaterial, MouseParallax_default as MouseParallax, Ocean_default as Ocean, Octahedron_default as Octahedron, OrbitControls_default as OrbitControls, component_default$12 as Outline, Plane_default as Plane, component_default$13 as PointMaterial, PointerLockControls_default as PointerLockControls, PositionalAudio_default as PositionalAudio, Precipitation_default as Precipitation, QuadraticBezierLine_default as QuadraticBezierLine, component_default$14 as RandomizedLights, Reflector_default as Reflector, Ring_default as Ring, RoundedBox_default as RoundedBox, component_default$15 as Sampler, ScreenQuad_default as ScreenQuad, ScreenSizer_default as ScreenSizer, ScreenSpace_default as ScreenSpace, ScrollControls_default as ScrollControls, Sky_default as Sky, Smoke_default as Smoke, SoftShadows_default as SoftShadows, component_default$16 as Sparkles, Sphere_default as Sphere, Stage_default as Stage, Stars_default as Stars, Stats, StatsGl, Superformula_default as Superformula, Tetrahedron_default as Tetrahedron, Text3D_default as Text3D, Torus_default as Torus, TorusKnot_default as TorusKnot, TransformControls_default as TransformControls, Tube_default as Tube, component_default$17 as UseSVG, component_default$18 as UseTexture, extractBindingPosition, hasSetter, pick, useAnimations, useEnvironment, useFBO, useFBX, useGLTF, useGLTFExporter, useIntersect, useMask, useProgress, useSVG, useSurfaceSampler, useTexture, useTextures, useVideoTexture };
12555
+ export { component_default as AccumulativeShadows, Align_default as Align, component_default$1 as AnimatedSprite, Backdrop_default as Backdrop, BakeShadows, BaseCameraControls, Billboard_default as Billboard, component_default$2 as Bounds, Box_default as Box, CameraControls_default as CameraControls, CameraShake_default as CameraShake, CatmullRomCurve3_default as CatmullRomCurve3, Circle_default as Circle, CircleShadow_default as CircleShadow, Cone_default as Cone, ContactShadows_default as ContactShadows, component_default$3 as CubeCamera, CubicBezierLine_default as CubicBezierLine, customShaderMaterial_default as CustomShaderMaterial, Cylinder_default as Cylinder, Dodecahedron_default as Dodecahedron, Edges_default as Edges, component_default$4 as Environment, component_default$5 as FBXModel, component_default$6 as Fbo, Fit_default as Fit, component_default$7 as GLTFModel, GlobalAudio, GradientTexture_default as GradientTexture, Grid_default as Grid, component_default$8 as Helper, holographicMaterial_default as HolographicMaterial, HTML_default as Html, Icosahedron_default as Icosahedron, component_default$9 as Image, KeyboardControls_default as KeyboardControls, LOD_default as LOD, component_default$10 as Lensflare, Levioso_default as Levioso, lightformer_default as Lightformer, Line2_default as Line2, MapControls_default as MapControls, MarchingCube_default as MarchingCube, MarchingCubes_default as MarchingCubes, MarchingPlane_default as MarchingPlane, component_default$11 as Mask, meshDiscardMaterial_default as MeshDiscardMaterial, meshGlassMaterial_default as MeshGlassMaterial, meshReflectionMaterial_default as MeshReflectionMaterial, meshWobbleMaterial_default as MeshWobbleMaterial, MouseParallax_default as MouseParallax, Ocean_default as Ocean, Octahedron_default as Octahedron, OrbitControls_default as OrbitControls, component_default$12 as Outline, Plane_default as Plane, component_default$13 as PointMaterial, PointerLockControls_default as PointerLockControls, PositionalAudio_default as PositionalAudio, Precipitation_default as Precipitation, QuadraticBezierLine_default as QuadraticBezierLine, component_default$14 as RandomizedLights, Reflector_default as Reflector, Ring_default as Ring, RoundedBox_default as RoundedBox, component_default$15 as Sampler, ScreenQuad_default as ScreenQuad, ScreenSizer_default as ScreenSizer, ScreenSpace_default as ScreenSpace, ScrollControls_default as ScrollControls, Sky_default as Sky, Smoke_default as Smoke, SoftShadows_default as SoftShadows, component_default$16 as Sparkles, Sphere_default as Sphere, Stage_default as Stage, Stars_default as Stars, Stats, StatsGl, Superformula_default as Superformula, Tetrahedron_default as Tetrahedron, Text3D_default as Text3D, Torus_default as Torus, TorusKnot_default as TorusKnot, TransformControls_default as TransformControls, Tube_default as Tube, component_default$17 as UseSVG, component_default$18 as UseTexture, extractBindingPosition, hasSetter, pick, useAnimations, useBVH, useEnvironment, useFBO, useFBX, useGLTF, useGLTFExporter, useIntersect, useMask, useProgress, useSVG, useSurfaceSampler, useTexture, useTextures, useVideoTexture };