three-base 2.0.142 → 2.0.166

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.
Files changed (231) hide show
  1. package/DirectionalLight.d.ts +6 -6
  2. package/DirectionalLight.js +68 -68
  3. package/EventMap.d.ts +103 -103
  4. package/EventMap.js +17 -17
  5. package/EventMesh.d.ts +18 -18
  6. package/EventMesh.js +59 -59
  7. package/ExtrudeMesh.d.ts +112 -112
  8. package/ExtrudeMesh.js +342 -342
  9. package/FPScontrol.d.ts +531 -511
  10. package/FPScontrol.js +1866 -1799
  11. package/FPScontrol.ts +1922 -1855
  12. package/Fire/Fire.d.ts +28 -28
  13. package/Fire/Fire.js +80 -80
  14. package/Fire/FireGeometry.d.ts +9 -9
  15. package/Fire/FireGeometry.js +40 -40
  16. package/Fire/FireMaterial.d.ts +28 -28
  17. package/Fire/FireMaterial.js +32 -32
  18. package/Fire/index.d.ts +2 -2
  19. package/Fire/index.js +2 -2
  20. package/GLTFDracoLoader.d.ts +71 -71
  21. package/GLTFDracoLoader.js +266 -266
  22. package/GLTFDracoLoader.ts +1 -1
  23. package/Grass/Grass.d.ts +8 -8
  24. package/Grass/Grass.js +38 -38
  25. package/Grass/index.d.ts +2 -2
  26. package/Grass/index.js +2 -2
  27. package/Ground1/Ground1.d.ts +10 -10
  28. package/Ground1/Ground1.js +71 -71
  29. package/Ground1/index.d.ts +1 -1
  30. package/Ground1/index.js +1 -1
  31. package/MeshBase.d.ts +36 -36
  32. package/MeshBase.js +251 -247
  33. package/MeshBase.ts +6 -2
  34. package/Mirror.d.ts +25 -25
  35. package/Mirror.js +143 -143
  36. package/MktMesh/MktMesh.d.ts +301 -291
  37. package/MktMesh/MktMesh.js +1064 -1045
  38. package/MktMesh/MktMesh.ts +32 -11
  39. package/MktMesh/assetUrl.d.ts +59 -35
  40. package/MktMesh/assetUrl.js +165 -69
  41. package/MktMesh/assetUrl.ts +164 -69
  42. package/MktMesh/mktMappingShader.d.ts +12 -12
  43. package/MktMesh/mktMappingShader.js +138 -138
  44. package/MktMesh/mktMappingShader.ts +139 -139
  45. package/MktMesh/mktShader.d.ts +263 -263
  46. package/MktMesh/mktShader.js +1236 -1236
  47. package/MktMesh/mktShader.ts +1344 -1344
  48. package/MktMesh/panoBitmapTexture.d.ts +25 -25
  49. package/MktMesh/panoBitmapTexture.js +52 -52
  50. package/MktMesh/panoBitmapTexture.ts +54 -54
  51. package/MktMesh/panoSlotBind.d.ts +29 -29
  52. package/MktMesh/panoSlotBind.js +106 -106
  53. package/MktMesh/panoSlotBind.ts +153 -153
  54. package/MktMesh/panoSlotRoster.d.ts +22 -22
  55. package/MktMesh/panoSlotRoster.js +169 -169
  56. package/MktMesh/panoSlotRoster.ts +168 -168
  57. package/MktMesh/panoTileStitcher.d.ts +119 -119
  58. package/MktMesh/panoTileStitcher.js +529 -529
  59. package/MktMesh/panoTileStitcher.ts +616 -616
  60. package/MktMesh/types.d.ts +75 -75
  61. package/MktMesh/types.js +1 -1
  62. package/MktMesh/wallCapTessellate.d.ts +33 -33
  63. package/MktMesh/wallCapTessellate.js +97 -97
  64. package/MktMesh/wallCapTessellate.ts +68 -68
  65. package/PipeMesh/PathGeometry.d.ts +44 -44
  66. package/PipeMesh/PathGeometry.js +307 -307
  67. package/PipeMesh/PathPoint.d.ts +17 -17
  68. package/PipeMesh/PathPoint.js +31 -31
  69. package/PipeMesh/PathPointList.d.ts +31 -31
  70. package/PipeMesh/PathPointList.js +209 -209
  71. package/PipeMesh/PathTubeGeometry.d.ts +25 -25
  72. package/PipeMesh/PathTubeGeometry.js +130 -130
  73. package/PipeMesh/PipeMesh.d.ts +25 -25
  74. package/PipeMesh/PipeMesh.js +63 -63
  75. package/PipeMesh/index.d.ts +1 -1
  76. package/PipeMesh/index.js +1 -1
  77. package/PlaneModal1/PlaneModal1.d.ts +34 -34
  78. package/PlaneModal1/PlaneModal1.js +109 -109
  79. package/PlaneModal1/index.d.ts +1 -1
  80. package/PlaneModal1/index.js +1 -1
  81. package/PlaneText.d.ts +27 -27
  82. package/PlaneText.js +35 -35
  83. package/PlaneWithHtml.d.ts +13 -13
  84. package/PlaneWithHtml.js +66 -64
  85. package/PlaneWithHtml.ts +3 -1
  86. package/PointLight/PointLight.d.ts +13 -13
  87. package/PointLight/PointLight.js +64 -64
  88. package/PointLight/index.d.ts +1 -1
  89. package/PointLight/index.js +1 -1
  90. package/Sky/Sky.d.ts +9 -9
  91. package/Sky/Sky.js +22 -22
  92. package/Sky/index.d.ts +1 -1
  93. package/Sky/index.js +1 -1
  94. package/SpotLight.d.ts +6 -6
  95. package/SpotLight.js +72 -72
  96. package/SpriteModal1/SpriteModal1.d.ts +33 -33
  97. package/SpriteModal1/SpriteModal1.js +116 -116
  98. package/SpriteModal1/index.d.ts +1 -1
  99. package/SpriteModal1/index.js +1 -1
  100. package/SpriteText.d.ts +46 -46
  101. package/SpriteText.js +176 -176
  102. package/SpriteText2.d.ts +48 -48
  103. package/SpriteText2.js +223 -223
  104. package/SpriteText3.d.ts +86 -86
  105. package/SpriteText3.js +517 -517
  106. package/SpriteText3.ts +599 -599
  107. package/SpriteWithHtml.d.ts +9 -9
  108. package/SpriteWithHtml.js +46 -44
  109. package/SpriteWithHtml.ts +3 -1
  110. package/Text3D/Text3D.d.ts +20 -20
  111. package/Text3D/Text3D.js +58 -58
  112. package/Text3D/fontController.d.ts +60 -60
  113. package/Text3D/fontController.js +166 -166
  114. package/Text3D/index.d.ts +1 -1
  115. package/Text3D/index.js +1 -1
  116. package/ThreeBase.d.ts +248 -248
  117. package/ThreeBase.js +1202 -1202
  118. package/ThreeBase.ts +1314 -1314
  119. package/ThreeMouse.d.ts +53 -54
  120. package/ThreeMouse.js +453 -453
  121. package/Transition.d.ts +45 -45
  122. package/Transition.js +209 -209
  123. package/Water/Water.d.ts +5 -5
  124. package/Water/Water.js +44 -44
  125. package/Water/index.d.ts +2 -2
  126. package/Water/index.js +2 -2
  127. package/WaterFlow/FloatingDuck.d.ts +88 -88
  128. package/WaterFlow/FloatingDuck.js +307 -307
  129. package/WaterFlow/FloatingDuck.ts +445 -445
  130. package/WaterFlow/GPUFluidSimulation.d.ts +56 -56
  131. package/WaterFlow/GPUFluidSimulation.js +781 -781
  132. package/WaterFlow/GPUFluidSimulation.ts +827 -827
  133. package/WaterFlow/ReservoirSystem.d.ts +106 -106
  134. package/WaterFlow/ReservoirSystem.js +611 -611
  135. package/WaterFlow/ReservoirSystem.ts +754 -754
  136. package/WaterFlow/SPHField.d.ts +35 -35
  137. package/WaterFlow/SPHField.js +203 -203
  138. package/WaterFlow/SPHField.ts +228 -228
  139. package/WaterFlow/ScreenSpaceFluidPass.d.ts +69 -69
  140. package/WaterFlow/ScreenSpaceFluidPass.js +728 -728
  141. package/WaterFlow/ScreenSpaceFluidPass.ts +789 -789
  142. package/WaterFlow/ShallowWaterSurface.d.ts +45 -45
  143. package/WaterFlow/ShallowWaterSurface.js +438 -438
  144. package/WaterFlow/ShallowWaterSurface.ts +510 -510
  145. package/WaterFlow/WaterFlow.d.ts +87 -87
  146. package/WaterFlow/WaterFlow.js +171 -171
  147. package/WaterFlow/WaterFlow.ts +219 -219
  148. package/WaterFlow/types.d.ts +161 -161
  149. package/WaterFlow/types.js +1 -1
  150. package/WaterFlow/types.ts +189 -189
  151. package/WaterFlow/waterFlowPass.d.ts +3 -3
  152. package/WaterFlow/waterFlowPass.js +20 -20
  153. package/WaterFlow/waterFlowPass.ts +40 -40
  154. package/collisionOBB.d.ts +42 -42
  155. package/collisionOBB.js +112 -112
  156. package/collisionOBB.ts +108 -108
  157. package/declare.d.ts +25 -25
  158. package/index.d.ts +1 -1
  159. package/index.js +1 -1
  160. package/instanced/InstancedBatch.d.ts +57 -57
  161. package/instanced/InstancedBatch.js +348 -348
  162. package/instanced/InstancedBatch.ts +406 -406
  163. package/instanced/InstancedChild.d.ts +174 -174
  164. package/instanced/InstancedChild.js +264 -264
  165. package/instanced/InstancedChild.ts +327 -327
  166. package/instanced/InstancedGroup.d.ts +43 -43
  167. package/instanced/InstancedGroup.js +126 -126
  168. package/instanced/InstancedGroup.ts +137 -137
  169. package/instanced/InstancedMeshBase.d.ts +38 -38
  170. package/instanced/InstancedMeshBase.js +282 -282
  171. package/instanced/InstancedTemplate.d.ts +46 -46
  172. package/instanced/InstancedTemplate.js +125 -125
  173. package/keyControls.d.ts +29 -30
  174. package/keyControls.js +101 -101
  175. package/lensflare/LensFlare.d.ts +39 -39
  176. package/lensflare/LensFlare.js +284 -284
  177. package/package.json +6 -1
  178. package/pass/bloom_pass.d.ts +2 -2
  179. package/pass/bloom_pass.js +174 -174
  180. package/pass/cover_pass.d.ts +2 -2
  181. package/pass/cover_pass.js +108 -108
  182. package/pass/debugDepthState.d.ts +20 -20
  183. package/pass/debugDepthState.js +9 -9
  184. package/pass/debugDepthState.ts +22 -22
  185. package/pass/depthTestBias.d.ts +12 -12
  186. package/pass/depthTestBias.js +12 -12
  187. package/pass/depthTestBias.ts +12 -12
  188. package/pass/effectUserData.d.ts +27 -27
  189. package/pass/effectUserData.js +1 -1
  190. package/pass/effectUserData.ts +46 -46
  191. package/pass/frosted_glass_pass.d.ts +2 -2
  192. package/pass/frosted_glass_pass.js +150 -150
  193. package/pass/fsQuad.d.ts +9 -9
  194. package/pass/fsQuad.js +28 -28
  195. package/pass/glow_pass.d.ts +2 -2
  196. package/pass/glow_pass.js +350 -350
  197. package/pass/screen_bloom_pass.d.ts +11 -11
  198. package/pass/screen_bloom_pass.js +136 -136
  199. package/pass/ssao_pass.d.ts +88 -88
  200. package/pass/ssao_pass.js +799 -799
  201. package/pass/ssao_pass.ts +918 -918
  202. package/pass/stroke_pass.d.ts +2 -2
  203. package/pass/stroke_pass.js +267 -267
  204. package/shaders/FXAAShaderMaterial.d.ts +3 -3
  205. package/shaders/FXAAShaderMaterial.js +20 -20
  206. package/shaders/baseDepthVisShader.d.ts +11 -11
  207. package/shaders/baseDepthVisShader.js +36 -36
  208. package/shaders/baseDepthVisShader.ts +36 -36
  209. package/shaders/baseTextureToRenderShader.d.ts +2 -2
  210. package/shaders/baseTextureToRenderShader.js +19 -19
  211. package/shaders/copyShader.d.ts +3 -3
  212. package/shaders/copyShader.js +13 -13
  213. package/shaders/debugDepthCompareShader.d.ts +14 -14
  214. package/shaders/debugDepthCompareShader.js +49 -49
  215. package/shaders/debugDepthCompareShader.ts +50 -50
  216. package/shaders/debugDepthJudgeShader.d.ts +18 -18
  217. package/shaders/debugDepthJudgeShader.js +52 -52
  218. package/shaders/debugDepthJudgeShader.ts +54 -54
  219. package/shaders/debugExcludedShader.d.ts +13 -13
  220. package/shaders/debugExcludedShader.js +46 -46
  221. package/shaders/debugExcludedShader.ts +48 -48
  222. package/spriteTextBg.d.ts +1 -1
  223. package/spriteTextBg.js +20 -20
  224. package/spriteTextBg.ts +20 -20
  225. package/threeLoader.d.ts +35 -35
  226. package/threeLoader.js +518 -518
  227. package/threeUtils.d.ts +71 -53
  228. package/threeUtils.js +363 -329
  229. package/threeUtils.ts +35 -0
  230. package/types.d.ts +2 -2
  231. package/types.js +6 -6
package/ThreeMouse.js CHANGED
@@ -1,453 +1,453 @@
1
- //
2
- //
3
- //
4
- //
5
- //
6
- // 启动鼠标事件
7
- import { InstancedMesh, Mesh, Raycaster, Vector2 } from "three";
8
- import { debounce } from "lodash";
9
- import { computeBoundsTree, acceleratedRaycast } from "three-mesh-bvh";
10
- /** 安全地分发事件到 Object3D 对象 */
11
- function dispatchObjectEvent(object, event) {
12
- // 使用双重断言来安全地传递事件对象
13
- object.dispatchEvent(event);
14
- }
15
- /** Patch Mesh.raycast with BVH acceleration. Call once before using ThreeMouse. */
16
- export function initBVHRaycast() {
17
- if (Mesh.prototype.raycast !== acceleratedRaycast) {
18
- Mesh.prototype.raycast = acceleratedRaycast;
19
- }
20
- }
21
- export { computeBoundsTree, acceleratedRaycast };
22
- /**
23
- * js 专用的鼠标拾取模型对象
24
- */
25
- export default class ThreeMouse {
26
- constructor(renderer, camera, scene) {
27
- this._renderer = renderer;
28
- this._camera = camera;
29
- this._scene = scene;
30
- this._frame = this._renderer.info.render.frame;
31
- this._renderer.domElement.addEventListener("mouseenter", () => {
32
- this._mouseInRenderer = true;
33
- }, true); //鼠标进入开启拾取
34
- this._renderer.domElement.addEventListener("mouseleave", this._mouseleave, true); //鼠标离开停止拾取
35
- this._renderer.domElement.addEventListener("mousemove", this._mousemove, true); //鼠标移动监听事件
36
- this._renderer.domElement.addEventListener("pointerdown", this._mousedown, true); //鼠标按下监听事件
37
- this._renderer.domElement.addEventListener("pointerup", this._mouseup, true); //鼠标弹起监听事件
38
- }
39
- // 渲染器
40
- _renderer;
41
- _camera;
42
- _scene;
43
- // 固定的实例化分组器(由 ThreeBase 注入),用于把 InstancedMesh 命中路由到 InstancedChild
44
- instancedGroup;
45
- // 鼠标在渲染器上面的位置
46
- _mosePosition = new Vector2(0, 0);
47
- // 鼠标按下的位置 如果和鼠标弹起的位置相同 才算一次有效的点击事件
48
- _mouseDownPosition = new Vector2(0, 0);
49
- //当前鼠标指针上的对象
50
- _mesh_on;
51
- //鼠标按下的对象
52
- _mesh_Down;
53
- //射线拾取器
54
- _raycaster = new Raycaster();
55
- // 当前渲染的帧数 ( 鼠标滑动事件 一帧只需要执行费一次即可 )
56
- _frame = 0;
57
- //鼠标是否在渲染器上
58
- _mouseInRenderer = false;
59
- // 鼠标滑动的事件
60
- _mousemoveEvent;
61
- // 鼠标事件
62
- _mouseEvent;
63
- // 需要被拾取的对象数组
64
- _object3ds = [];
65
- // 点击次数
66
- _click_num = 0;
67
- // 获取拾取到的对象
68
- _getSelected(object3ds) {
69
- let intersection;
70
- if (object3ds.length) {
71
- intersection = this._raycaster.intersectObjects(object3ds, false)[0];
72
- }
73
- return intersection;
74
- }
75
- // 判断对象上面是否有事件
76
- hasEvent(object, types = []) {
77
- if (!object) {
78
- return false;
79
- }
80
- // 如果 启用事件为关闭的话就不执行事件
81
- if (object["userData"] && object["userData"]["enableEvent"] === false) {
82
- return false;
83
- }
84
- // 注意:three 的 hasEventListener(type, null) 因 indexOf(null) 永远 -1 而恒返回 false,
85
- // 无法用来判断"是否存在任意监听器"。改为直接读取私有 _listeners 表判断该类型是否有监听。
86
- const listeners = object._listeners;
87
- const hasevent = types.some((type) => {
88
- return !!(listeners && listeners[type] && listeners[type].length > 0);
89
- });
90
- return hasevent;
91
- }
92
- // 判断对象上是否有鼠标样式
93
- hasCursor(object) {
94
- if (!object) {
95
- return false;
96
- }
97
- // 如果 启用事件为关闭的话就不执行事件
98
- if (object["userData"] && object["userData"]["enableEvent"] === false) {
99
- return false;
100
- }
101
- if (object["userData"] && object["userData"]["cursor"]) {
102
- return true;
103
- }
104
- }
105
- // 把命中的对象解析为事件派发目标:若命中 InstancedMesh 且属于某个 batch,
106
- // 则路由到对应的 InstancedChild(逻辑实例),使实例成为透明事件接收端。
107
- resolveTarget(object, instanceId) {
108
- if (object instanceof InstancedMesh && this.instancedGroup) {
109
- const child = this.instancedGroup.resolveInstance(object, instanceId);
110
- if (child) {
111
- return child;
112
- }
113
- }
114
- return object;
115
- }
116
- // 分发鼠标拾取事件
117
- dispatchEvent() {
118
- // 提取有事件的对象
119
- const meshs = [];
120
- this._scene.traverseVisible((mesh) => {
121
- // 逻辑实例节点(InstancedChild)自身不渲染、无几何,跳过收集(命中由 InstancedMesh 路由回来)
122
- if (mesh.userData?.__instancedChild) {
123
- return;
124
- }
125
- // 判断对象是否有指定的事件
126
- if (this.hasCursor(mesh) ||
127
- this.hasEvent(mesh, [
128
- "leftclick",
129
- "rightclick",
130
- "click",
131
- "dbclick",
132
- "mouseenter",
133
- "mouseleave",
134
- "mousemove",
135
- "mousedown",
136
- "mouseup",
137
- ])) {
138
- if (mesh instanceof Mesh &&
139
- !mesh.geometry.boundsTree &&
140
- mesh.geometry.attributes.position &&
141
- mesh.geometry.attributes.position.count > 0) {
142
- computeBoundsTree.apply(mesh.geometry);
143
- // disposeBoundsTree.apply((mesh as Mesh).geometry);
144
- }
145
- meshs.push(mesh);
146
- }
147
- });
148
- this._object3ds = meshs;
149
- // 收集可拾取的 InstancedMesh(仅含注册了监听的已就绪 batch)
150
- if (this.instancedGroup) {
151
- this.instancedGroup.collectPickable(meshs);
152
- }
153
- // 没有鼠标事件就不往下执行了
154
- if (!this._mousemoveEvent || !this._mouseInRenderer) {
155
- return;
156
- }
157
- // 拾取模型
158
- let intersection = this._getSelected(meshs);
159
- if (intersection) {
160
- const { face, object } = intersection;
161
- // face && face.normal.applyMatrix4(object.matrixWorld);
162
- const MouseEvent = Object.assign(intersection, {
163
- // 将来可能用到的对象
164
- e: this._mousemoveEvent,
165
- renderer: this._renderer,
166
- camera: this._camera,
167
- object: intersection.object,
168
- type: this._mousemoveEvent.type,
169
- offsetX: this._mousemoveEvent.offsetX,
170
- offsetY: this._mousemoveEvent.offsetY,
171
- x: this._mousemoveEvent.x,
172
- y: this._mousemoveEvent.y,
173
- });
174
- // 命中 InstancedMesh 时,把派发目标重定向到对应的 InstancedChild
175
- const _target = this.resolveTarget(intersection.object, intersection.instanceId);
176
- if (_target)
177
- MouseEvent.object = _target;
178
- // 触发滑动事件
179
- if (this._mesh_on === MouseEvent.object) {
180
- if (this.hasEvent(MouseEvent.object, ["mousemove"])) {
181
- MouseEvent.type = "mousemove";
182
- dispatchObjectEvent(MouseEvent.object, MouseEvent);
183
- }
184
- // 鼠标划入滑出事件
185
- }
186
- else if (this._mesh_on !== MouseEvent.object) {
187
- if (this.hasEvent(this._mesh_on, ["mouseleave"])) {
188
- MouseEvent.type = "mouseleave";
189
- dispatchObjectEvent(this._mesh_on, MouseEvent);
190
- }
191
- if (this.hasEvent(MouseEvent.object, ["mouseenter"])) {
192
- MouseEvent.type = "mouseenter";
193
- dispatchObjectEvent(MouseEvent.object, MouseEvent);
194
- }
195
- }
196
- this._mesh_on = MouseEvent.object || undefined; // 设置为当前鼠标上的对象
197
- // 鼠标样式
198
- if (this._mesh_on &&
199
- this._mesh_on.userData &&
200
- this._mesh_on.userData.cursor) {
201
- this._renderer.domElement.style.cursor = this._mesh_on.userData.cursor;
202
- }
203
- else {
204
- this._renderer.domElement.style.cursor = "auto";
205
- }
206
- }
207
- else {
208
- if (this.hasEvent(this._mesh_on, ["mouseleave"])) {
209
- // 鼠标离开事件
210
- dispatchObjectEvent(this._mesh_on, {
211
- e: this._mouseEvent,
212
- renderer: this._renderer,
213
- camera: this._camera,
214
- object: this._mesh_on,
215
- type: "mouseleave",
216
- offsetX: this._mousemoveEvent.offsetX,
217
- offsetY: this._mousemoveEvent.offsetY,
218
- x: this._mousemoveEvent.x,
219
- y: this._mousemoveEvent.y,
220
- });
221
- }
222
- // 置空当前鼠标上面的对象
223
- this._mesh_on = undefined;
224
- this._renderer.domElement.style.cursor = "auto"; // 鼠标样式
225
- }
226
- }
227
- // 鼠标离开事件
228
- _mouseleave = (e) => {
229
- this._mouseEvent = e;
230
- this._mouseInRenderer = false;
231
- // 鼠标离开事件
232
- if (this._mousemoveEvent && this.hasEvent(this._mesh_on, ["mouseleave"])) {
233
- dispatchObjectEvent(this._mesh_on, {
234
- e: this._mouseEvent,
235
- renderer: this._renderer,
236
- camera: this._camera,
237
- object: this._mesh_on,
238
- type: "mouseleave",
239
- offsetX: this._mousemoveEvent.offsetX,
240
- offsetY: this._mousemoveEvent.offsetY,
241
- x: this._mousemoveEvent.x,
242
- y: this._mousemoveEvent.y,
243
- });
244
- }
245
- // 置空当前鼠标上面的对象
246
- this._mesh_on = undefined;
247
- this._renderer.domElement.style.cursor = "auto"; // 鼠标样式
248
- };
249
- // 鼠标滑动 设置鼠标位置
250
- _mousemove = (e) => {
251
- this._mousemoveEvent = e;
252
- this._frame = this._renderer.info.render.frame;
253
- if (document.pointerLockElement) {
254
- // 如果当前有元素 锁住了鼠标
255
- this._mosePosition.set(0, 0); // 鼠标就指向canvas 的正中心
256
- }
257
- else {
258
- this._mosePosition.x = (e.offsetX / this._renderer.domElement.offsetWidth) * 2 - 1;
259
- this._mosePosition.y = -(e.offsetY / this._renderer.domElement.offsetHeight) * 2 + 1;
260
- }
261
- this._raycaster.setFromCamera(this._mosePosition, this._camera); // 设置射线拾取的参数
262
- };
263
- // 鼠标按下事件
264
- _mousedown = (e) => {
265
- this._mouseEvent = e;
266
- // 记录按下的位置
267
- this._mouseDownPosition.set(e.offsetX, e.offsetY);
268
- this._mousemove(e);
269
- let intersection = this._getSelected(this._object3ds);
270
- if (!intersection || !this._mousemoveEvent) {
271
- return;
272
- }
273
- // 命中 InstancedMesh 时把派发目标重定向到 InstancedChild,并改写 intersection.object
274
- this._mesh_Down = this._mesh_on = this.resolveTarget(intersection.object, intersection.instanceId);
275
- intersection.object = this._mesh_Down;
276
- // 触发鼠标按下事件
277
- if (this.hasEvent(this._mesh_Down, ["mousedown"])) {
278
- dispatchObjectEvent(this._mesh_Down, {
279
- e: this._mouseEvent,
280
- ...intersection,
281
- renderer: this._renderer,
282
- camera: this._camera,
283
- object: intersection.object,
284
- type: "mousedown",
285
- offsetX: this._mousemoveEvent.offsetX,
286
- offsetY: this._mousemoveEvent.offsetY,
287
- x: this._mousemoveEvent.x,
288
- y: this._mousemoveEvent.y,
289
- });
290
- }
291
- };
292
- // 鼠标弹起事件
293
- _mouseup = debounce(async (e) => {
294
- this._mouseEvent = e;
295
- // 提取有事件的对象
296
- const meshs = [];
297
- let intersection = this._getSelected(this._object3ds);
298
- if (!intersection || !this._mousemoveEvent) {
299
- return;
300
- }
301
- // 命中 InstancedMesh 时把派发目标重定向到 InstancedChild,并改写 intersection.object
302
- this._mesh_on = this.resolveTarget(intersection.object, intersection.instanceId);
303
- intersection.object = this._mesh_on;
304
- if (this.hasEvent(this._mesh_on, ["mouseup"])) {
305
- dispatchObjectEvent(this._mesh_on, {
306
- e: this._mouseEvent,
307
- ...intersection,
308
- renderer: this._renderer,
309
- camera: this._camera,
310
- object: intersection.object,
311
- type: "mouseup",
312
- offsetX: this._mousemoveEvent.offsetX,
313
- offsetY: this._mousemoveEvent.offsetY,
314
- x: this._mousemoveEvent.x,
315
- y: this._mousemoveEvent.y,
316
- });
317
- }
318
- // 触发鼠标弹起事件
319
- if (this._mesh_Down &&
320
- this._mesh_Down === this._mesh_on &&
321
- Math.abs(this._mouseDownPosition.x - e.offsetX) < 5 &&
322
- Math.abs(this._mouseDownPosition.y - e.offsetY) < 5) {
323
- // 是否有双击事件
324
- if (this.hasEvent(this._mesh_Down, ["dbclick"])) {
325
- this._click_num++;
326
- await new Promise((resolve) => setTimeout(resolve, 200));
327
- // 只点击了一次
328
- if (this._click_num === 1) {
329
- if (this.hasEvent(this._mesh_Down, ["click"])) {
330
- dispatchObjectEvent(this._mesh_Down, {
331
- e: this._mouseEvent,
332
- ...intersection,
333
- renderer: this._renderer,
334
- camera: this._camera,
335
- object: intersection.object,
336
- type: "click",
337
- offsetX: this._mousemoveEvent.offsetX,
338
- offsetY: this._mousemoveEvent.offsetY,
339
- x: this._mousemoveEvent.x,
340
- y: this._mousemoveEvent.y,
341
- });
342
- }
343
- if (this.hasEvent(this._mesh_Down, ["leftclick"]) && e.button === 0) {
344
- dispatchObjectEvent(this._mesh_Down, {
345
- e: this._mouseEvent,
346
- ...intersection,
347
- renderer: this._renderer,
348
- camera: this._camera,
349
- object: intersection.object,
350
- type: "leftclick",
351
- offsetX: this._mousemoveEvent.offsetX,
352
- offsetY: this._mousemoveEvent.offsetY,
353
- x: this._mousemoveEvent.x,
354
- y: this._mousemoveEvent.y,
355
- });
356
- }
357
- if (this.hasEvent(this._mesh_Down, ["rightclick"]) &&
358
- e.button === 2) {
359
- dispatchObjectEvent(this._mesh_Down, {
360
- e: this._mouseEvent,
361
- ...intersection,
362
- renderer: this._renderer,
363
- camera: this._camera,
364
- object: intersection.object,
365
- type: "rightclick",
366
- offsetX: this._mousemoveEvent.offsetX,
367
- offsetY: this._mousemoveEvent.offsetY,
368
- x: this._mousemoveEvent.x,
369
- y: this._mousemoveEvent.y,
370
- });
371
- }
372
- }
373
- else if (this._click_num > 1) {
374
- if (this.hasEvent(this._mesh_Down, ["dbclick"]) &&
375
- new Date().valueOf() - this._click_num > 1 &&
376
- e.button === 0) {
377
- dispatchObjectEvent(this._mesh_Down, {
378
- e: this._mouseEvent,
379
- ...intersection,
380
- renderer: this._renderer,
381
- camera: this._camera,
382
- object: intersection.object,
383
- type: "dbclick",
384
- offsetX: this._mousemoveEvent.offsetX,
385
- offsetY: this._mousemoveEvent.offsetY,
386
- x: this._mousemoveEvent.x,
387
- y: this._mousemoveEvent.y,
388
- });
389
- }
390
- }
391
- }
392
- else {
393
- if (this.hasEvent(this._mesh_Down, ["click"])) {
394
- dispatchObjectEvent(this._mesh_Down, {
395
- e: this._mouseEvent,
396
- ...intersection,
397
- renderer: this._renderer,
398
- camera: this._camera,
399
- object: intersection.object,
400
- type: "click",
401
- offsetX: this._mousemoveEvent.offsetX,
402
- offsetY: this._mousemoveEvent.offsetY,
403
- x: this._mousemoveEvent.x,
404
- y: this._mousemoveEvent.y,
405
- });
406
- }
407
- if (this.hasEvent(this._mesh_Down, ["leftclick"]) && e.button === 0) {
408
- dispatchObjectEvent(this._mesh_Down, {
409
- e: this._mouseEvent,
410
- ...intersection,
411
- renderer: this._renderer,
412
- camera: this._camera,
413
- object: intersection.object,
414
- type: "leftclick",
415
- offsetX: this._mousemoveEvent.offsetX,
416
- offsetY: this._mousemoveEvent.offsetY,
417
- x: this._mousemoveEvent.x,
418
- y: this._mousemoveEvent.y,
419
- });
420
- }
421
- if (this.hasEvent(this._mesh_Down, ["rightclick"]) && e.button === 2) {
422
- dispatchObjectEvent(this._mesh_Down, {
423
- e: this._mouseEvent,
424
- ...intersection,
425
- renderer: this._renderer,
426
- camera: this._camera,
427
- object: intersection.object,
428
- type: "rightclick",
429
- offsetX: this._mousemoveEvent.offsetX,
430
- offsetY: this._mousemoveEvent.offsetY,
431
- x: this._mousemoveEvent.x,
432
- y: this._mousemoveEvent.y,
433
- });
434
- }
435
- }
436
- this._click_num = 0;
437
- }
438
- });
439
- /** 设置 Points(点云)拾取阈值(世界单位),数值越大越容易点中。
440
- * 全景纹理标记改用 Points 后,通过它调节点击命中范围。 */
441
- setPointsThreshold(threshold) {
442
- this._raycaster.params.Points.threshold = threshold;
443
- }
444
- /** 移除 canvas 上的所有鼠标/指针事件监听(渲染器销毁时调用)。
445
- * 注:mouseenter 为内联匿名监听,销毁时 canvas 已脱离 DOM,无需显式移除。 */
446
- dispose() {
447
- const dom = this._renderer.domElement;
448
- dom.removeEventListener("mouseleave", this._mouseleave, true);
449
- dom.removeEventListener("mousemove", this._mousemove, true);
450
- dom.removeEventListener("pointerdown", this._mousedown, true);
451
- dom.removeEventListener("pointerup", this._mouseup, true);
452
- }
453
- }
1
+ //
2
+ //
3
+ //
4
+ //
5
+ //
6
+ // 启动鼠标事件
7
+ import { InstancedMesh, Mesh, Raycaster, Vector2 } from "three";
8
+ import { debounce } from "lodash";
9
+ import { computeBoundsTree, acceleratedRaycast } from "three-mesh-bvh";
10
+ /** 安全地分发事件到 Object3D 对象 */
11
+ function dispatchObjectEvent(object, event) {
12
+ // 使用双重断言来安全地传递事件对象
13
+ object.dispatchEvent(event);
14
+ }
15
+ /** Patch Mesh.raycast with BVH acceleration. Call once before using ThreeMouse. */
16
+ export function initBVHRaycast() {
17
+ if (Mesh.prototype.raycast !== acceleratedRaycast) {
18
+ Mesh.prototype.raycast = acceleratedRaycast;
19
+ }
20
+ }
21
+ export { computeBoundsTree, acceleratedRaycast };
22
+ /**
23
+ * js 专用的鼠标拾取模型对象
24
+ */
25
+ export default class ThreeMouse {
26
+ constructor(renderer, camera, scene) {
27
+ this._renderer = renderer;
28
+ this._camera = camera;
29
+ this._scene = scene;
30
+ this._frame = this._renderer.info.render.frame;
31
+ this._renderer.domElement.addEventListener("mouseenter", () => {
32
+ this._mouseInRenderer = true;
33
+ }, true); //鼠标进入开启拾取
34
+ this._renderer.domElement.addEventListener("mouseleave", this._mouseleave, true); //鼠标离开停止拾取
35
+ this._renderer.domElement.addEventListener("mousemove", this._mousemove, true); //鼠标移动监听事件
36
+ this._renderer.domElement.addEventListener("pointerdown", this._mousedown, true); //鼠标按下监听事件
37
+ this._renderer.domElement.addEventListener("pointerup", this._mouseup, true); //鼠标弹起监听事件
38
+ }
39
+ // 渲染器
40
+ _renderer;
41
+ _camera;
42
+ _scene;
43
+ // 固定的实例化分组器(由 ThreeBase 注入),用于把 InstancedMesh 命中路由到 InstancedChild
44
+ instancedGroup;
45
+ // 鼠标在渲染器上面的位置
46
+ _mosePosition = new Vector2(0, 0);
47
+ // 鼠标按下的位置 如果和鼠标弹起的位置相同 才算一次有效的点击事件
48
+ _mouseDownPosition = new Vector2(0, 0);
49
+ //当前鼠标指针上的对象
50
+ _mesh_on;
51
+ //鼠标按下的对象
52
+ _mesh_Down;
53
+ //射线拾取器
54
+ _raycaster = new Raycaster();
55
+ // 当前渲染的帧数 ( 鼠标滑动事件 一帧只需要执行费一次即可 )
56
+ _frame = 0;
57
+ //鼠标是否在渲染器上
58
+ _mouseInRenderer = false;
59
+ // 鼠标滑动的事件
60
+ _mousemoveEvent;
61
+ // 鼠标事件
62
+ _mouseEvent;
63
+ // 需要被拾取的对象数组
64
+ _object3ds = [];
65
+ // 点击次数
66
+ _click_num = 0;
67
+ // 获取拾取到的对象
68
+ _getSelected(object3ds) {
69
+ let intersection;
70
+ if (object3ds.length) {
71
+ intersection = this._raycaster.intersectObjects(object3ds, false)[0];
72
+ }
73
+ return intersection;
74
+ }
75
+ // 判断对象上面是否有事件
76
+ hasEvent(object, types = []) {
77
+ if (!object) {
78
+ return false;
79
+ }
80
+ // 如果 启用事件为关闭的话就不执行事件
81
+ if (object["userData"] && object["userData"]["enableEvent"] === false) {
82
+ return false;
83
+ }
84
+ // 注意:three 的 hasEventListener(type, null) 因 indexOf(null) 永远 -1 而恒返回 false,
85
+ // 无法用来判断"是否存在任意监听器"。改为直接读取私有 _listeners 表判断该类型是否有监听。
86
+ const listeners = object._listeners;
87
+ const hasevent = types.some((type) => {
88
+ return !!(listeners && listeners[type] && listeners[type].length > 0);
89
+ });
90
+ return hasevent;
91
+ }
92
+ // 判断对象上是否有鼠标样式
93
+ hasCursor(object) {
94
+ if (!object) {
95
+ return false;
96
+ }
97
+ // 如果 启用事件为关闭的话就不执行事件
98
+ if (object["userData"] && object["userData"]["enableEvent"] === false) {
99
+ return false;
100
+ }
101
+ if (object["userData"] && object["userData"]["cursor"]) {
102
+ return true;
103
+ }
104
+ }
105
+ // 把命中的对象解析为事件派发目标:若命中 InstancedMesh 且属于某个 batch,
106
+ // 则路由到对应的 InstancedChild(逻辑实例),使实例成为透明事件接收端。
107
+ resolveTarget(object, instanceId) {
108
+ if (object instanceof InstancedMesh && this.instancedGroup) {
109
+ const child = this.instancedGroup.resolveInstance(object, instanceId);
110
+ if (child) {
111
+ return child;
112
+ }
113
+ }
114
+ return object;
115
+ }
116
+ // 分发鼠标拾取事件
117
+ dispatchEvent() {
118
+ // 提取有事件的对象
119
+ const meshs = [];
120
+ this._scene.traverseVisible((mesh) => {
121
+ // 逻辑实例节点(InstancedChild)自身不渲染、无几何,跳过收集(命中由 InstancedMesh 路由回来)
122
+ if (mesh.userData?.__instancedChild) {
123
+ return;
124
+ }
125
+ // 判断对象是否有指定的事件
126
+ if (this.hasCursor(mesh) ||
127
+ this.hasEvent(mesh, [
128
+ "leftclick",
129
+ "rightclick",
130
+ "click",
131
+ "dbclick",
132
+ "mouseenter",
133
+ "mouseleave",
134
+ "mousemove",
135
+ "mousedown",
136
+ "mouseup",
137
+ ])) {
138
+ if (mesh instanceof Mesh &&
139
+ !mesh.geometry.boundsTree &&
140
+ mesh.geometry.attributes.position &&
141
+ mesh.geometry.attributes.position.count > 0) {
142
+ computeBoundsTree.apply(mesh.geometry);
143
+ // disposeBoundsTree.apply((mesh as Mesh).geometry);
144
+ }
145
+ meshs.push(mesh);
146
+ }
147
+ });
148
+ this._object3ds = meshs;
149
+ // 收集可拾取的 InstancedMesh(仅含注册了监听的已就绪 batch)
150
+ if (this.instancedGroup) {
151
+ this.instancedGroup.collectPickable(meshs);
152
+ }
153
+ // 没有鼠标事件就不往下执行了
154
+ if (!this._mousemoveEvent || !this._mouseInRenderer) {
155
+ return;
156
+ }
157
+ // 拾取模型
158
+ let intersection = this._getSelected(meshs);
159
+ if (intersection) {
160
+ const { face, object } = intersection;
161
+ // face && face.normal.applyMatrix4(object.matrixWorld);
162
+ const MouseEvent = Object.assign(intersection, {
163
+ // 将来可能用到的对象
164
+ e: this._mousemoveEvent,
165
+ renderer: this._renderer,
166
+ camera: this._camera,
167
+ object: intersection.object,
168
+ type: this._mousemoveEvent.type,
169
+ offsetX: this._mousemoveEvent.offsetX,
170
+ offsetY: this._mousemoveEvent.offsetY,
171
+ x: this._mousemoveEvent.x,
172
+ y: this._mousemoveEvent.y,
173
+ });
174
+ // 命中 InstancedMesh 时,把派发目标重定向到对应的 InstancedChild
175
+ const _target = this.resolveTarget(intersection.object, intersection.instanceId);
176
+ if (_target)
177
+ MouseEvent.object = _target;
178
+ // 触发滑动事件
179
+ if (this._mesh_on === MouseEvent.object) {
180
+ if (this.hasEvent(MouseEvent.object, ["mousemove"])) {
181
+ MouseEvent.type = "mousemove";
182
+ dispatchObjectEvent(MouseEvent.object, MouseEvent);
183
+ }
184
+ // 鼠标划入滑出事件
185
+ }
186
+ else if (this._mesh_on !== MouseEvent.object) {
187
+ if (this.hasEvent(this._mesh_on, ["mouseleave"])) {
188
+ MouseEvent.type = "mouseleave";
189
+ dispatchObjectEvent(this._mesh_on, MouseEvent);
190
+ }
191
+ if (this.hasEvent(MouseEvent.object, ["mouseenter"])) {
192
+ MouseEvent.type = "mouseenter";
193
+ dispatchObjectEvent(MouseEvent.object, MouseEvent);
194
+ }
195
+ }
196
+ this._mesh_on = MouseEvent.object || undefined; // 设置为当前鼠标上的对象
197
+ // 鼠标样式
198
+ if (this._mesh_on &&
199
+ this._mesh_on.userData &&
200
+ this._mesh_on.userData.cursor) {
201
+ this._renderer.domElement.style.cursor = this._mesh_on.userData.cursor;
202
+ }
203
+ else {
204
+ this._renderer.domElement.style.cursor = "auto";
205
+ }
206
+ }
207
+ else {
208
+ if (this.hasEvent(this._mesh_on, ["mouseleave"])) {
209
+ // 鼠标离开事件
210
+ dispatchObjectEvent(this._mesh_on, {
211
+ e: this._mouseEvent,
212
+ renderer: this._renderer,
213
+ camera: this._camera,
214
+ object: this._mesh_on,
215
+ type: "mouseleave",
216
+ offsetX: this._mousemoveEvent.offsetX,
217
+ offsetY: this._mousemoveEvent.offsetY,
218
+ x: this._mousemoveEvent.x,
219
+ y: this._mousemoveEvent.y,
220
+ });
221
+ }
222
+ // 置空当前鼠标上面的对象
223
+ this._mesh_on = undefined;
224
+ this._renderer.domElement.style.cursor = "auto"; // 鼠标样式
225
+ }
226
+ }
227
+ // 鼠标离开事件
228
+ _mouseleave = (e) => {
229
+ this._mouseEvent = e;
230
+ this._mouseInRenderer = false;
231
+ // 鼠标离开事件
232
+ if (this._mousemoveEvent && this.hasEvent(this._mesh_on, ["mouseleave"])) {
233
+ dispatchObjectEvent(this._mesh_on, {
234
+ e: this._mouseEvent,
235
+ renderer: this._renderer,
236
+ camera: this._camera,
237
+ object: this._mesh_on,
238
+ type: "mouseleave",
239
+ offsetX: this._mousemoveEvent.offsetX,
240
+ offsetY: this._mousemoveEvent.offsetY,
241
+ x: this._mousemoveEvent.x,
242
+ y: this._mousemoveEvent.y,
243
+ });
244
+ }
245
+ // 置空当前鼠标上面的对象
246
+ this._mesh_on = undefined;
247
+ this._renderer.domElement.style.cursor = "auto"; // 鼠标样式
248
+ };
249
+ // 鼠标滑动 设置鼠标位置
250
+ _mousemove = (e) => {
251
+ this._mousemoveEvent = e;
252
+ this._frame = this._renderer.info.render.frame;
253
+ if (document.pointerLockElement) {
254
+ // 如果当前有元素 锁住了鼠标
255
+ this._mosePosition.set(0, 0); // 鼠标就指向canvas 的正中心
256
+ }
257
+ else {
258
+ this._mosePosition.x = (e.offsetX / this._renderer.domElement.offsetWidth) * 2 - 1;
259
+ this._mosePosition.y = -(e.offsetY / this._renderer.domElement.offsetHeight) * 2 + 1;
260
+ }
261
+ this._raycaster.setFromCamera(this._mosePosition, this._camera); // 设置射线拾取的参数
262
+ };
263
+ // 鼠标按下事件
264
+ _mousedown = (e) => {
265
+ this._mouseEvent = e;
266
+ // 记录按下的位置
267
+ this._mouseDownPosition.set(e.offsetX, e.offsetY);
268
+ this._mousemove(e);
269
+ let intersection = this._getSelected(this._object3ds);
270
+ if (!intersection || !this._mousemoveEvent) {
271
+ return;
272
+ }
273
+ // 命中 InstancedMesh 时把派发目标重定向到 InstancedChild,并改写 intersection.object
274
+ this._mesh_Down = this._mesh_on = this.resolveTarget(intersection.object, intersection.instanceId);
275
+ intersection.object = this._mesh_Down;
276
+ // 触发鼠标按下事件
277
+ if (this.hasEvent(this._mesh_Down, ["mousedown"])) {
278
+ dispatchObjectEvent(this._mesh_Down, {
279
+ e: this._mouseEvent,
280
+ ...intersection,
281
+ renderer: this._renderer,
282
+ camera: this._camera,
283
+ object: intersection.object,
284
+ type: "mousedown",
285
+ offsetX: this._mousemoveEvent.offsetX,
286
+ offsetY: this._mousemoveEvent.offsetY,
287
+ x: this._mousemoveEvent.x,
288
+ y: this._mousemoveEvent.y,
289
+ });
290
+ }
291
+ };
292
+ // 鼠标弹起事件
293
+ _mouseup = debounce(async (e) => {
294
+ this._mouseEvent = e;
295
+ // 提取有事件的对象
296
+ const meshs = [];
297
+ let intersection = this._getSelected(this._object3ds);
298
+ if (!intersection || !this._mousemoveEvent) {
299
+ return;
300
+ }
301
+ // 命中 InstancedMesh 时把派发目标重定向到 InstancedChild,并改写 intersection.object
302
+ this._mesh_on = this.resolveTarget(intersection.object, intersection.instanceId);
303
+ intersection.object = this._mesh_on;
304
+ if (this.hasEvent(this._mesh_on, ["mouseup"])) {
305
+ dispatchObjectEvent(this._mesh_on, {
306
+ e: this._mouseEvent,
307
+ ...intersection,
308
+ renderer: this._renderer,
309
+ camera: this._camera,
310
+ object: intersection.object,
311
+ type: "mouseup",
312
+ offsetX: this._mousemoveEvent.offsetX,
313
+ offsetY: this._mousemoveEvent.offsetY,
314
+ x: this._mousemoveEvent.x,
315
+ y: this._mousemoveEvent.y,
316
+ });
317
+ }
318
+ // 触发鼠标弹起事件
319
+ if (this._mesh_Down &&
320
+ this._mesh_Down === this._mesh_on &&
321
+ Math.abs(this._mouseDownPosition.x - e.offsetX) < 5 &&
322
+ Math.abs(this._mouseDownPosition.y - e.offsetY) < 5) {
323
+ // 是否有双击事件
324
+ if (this.hasEvent(this._mesh_Down, ["dbclick"])) {
325
+ this._click_num++;
326
+ await new Promise((resolve) => setTimeout(resolve, 200));
327
+ // 只点击了一次
328
+ if (this._click_num === 1) {
329
+ if (this.hasEvent(this._mesh_Down, ["click"])) {
330
+ dispatchObjectEvent(this._mesh_Down, {
331
+ e: this._mouseEvent,
332
+ ...intersection,
333
+ renderer: this._renderer,
334
+ camera: this._camera,
335
+ object: intersection.object,
336
+ type: "click",
337
+ offsetX: this._mousemoveEvent.offsetX,
338
+ offsetY: this._mousemoveEvent.offsetY,
339
+ x: this._mousemoveEvent.x,
340
+ y: this._mousemoveEvent.y,
341
+ });
342
+ }
343
+ if (this.hasEvent(this._mesh_Down, ["leftclick"]) && e.button === 0) {
344
+ dispatchObjectEvent(this._mesh_Down, {
345
+ e: this._mouseEvent,
346
+ ...intersection,
347
+ renderer: this._renderer,
348
+ camera: this._camera,
349
+ object: intersection.object,
350
+ type: "leftclick",
351
+ offsetX: this._mousemoveEvent.offsetX,
352
+ offsetY: this._mousemoveEvent.offsetY,
353
+ x: this._mousemoveEvent.x,
354
+ y: this._mousemoveEvent.y,
355
+ });
356
+ }
357
+ if (this.hasEvent(this._mesh_Down, ["rightclick"]) &&
358
+ e.button === 2) {
359
+ dispatchObjectEvent(this._mesh_Down, {
360
+ e: this._mouseEvent,
361
+ ...intersection,
362
+ renderer: this._renderer,
363
+ camera: this._camera,
364
+ object: intersection.object,
365
+ type: "rightclick",
366
+ offsetX: this._mousemoveEvent.offsetX,
367
+ offsetY: this._mousemoveEvent.offsetY,
368
+ x: this._mousemoveEvent.x,
369
+ y: this._mousemoveEvent.y,
370
+ });
371
+ }
372
+ }
373
+ else if (this._click_num > 1) {
374
+ if (this.hasEvent(this._mesh_Down, ["dbclick"]) &&
375
+ new Date().valueOf() - this._click_num > 1 &&
376
+ e.button === 0) {
377
+ dispatchObjectEvent(this._mesh_Down, {
378
+ e: this._mouseEvent,
379
+ ...intersection,
380
+ renderer: this._renderer,
381
+ camera: this._camera,
382
+ object: intersection.object,
383
+ type: "dbclick",
384
+ offsetX: this._mousemoveEvent.offsetX,
385
+ offsetY: this._mousemoveEvent.offsetY,
386
+ x: this._mousemoveEvent.x,
387
+ y: this._mousemoveEvent.y,
388
+ });
389
+ }
390
+ }
391
+ }
392
+ else {
393
+ if (this.hasEvent(this._mesh_Down, ["click"])) {
394
+ dispatchObjectEvent(this._mesh_Down, {
395
+ e: this._mouseEvent,
396
+ ...intersection,
397
+ renderer: this._renderer,
398
+ camera: this._camera,
399
+ object: intersection.object,
400
+ type: "click",
401
+ offsetX: this._mousemoveEvent.offsetX,
402
+ offsetY: this._mousemoveEvent.offsetY,
403
+ x: this._mousemoveEvent.x,
404
+ y: this._mousemoveEvent.y,
405
+ });
406
+ }
407
+ if (this.hasEvent(this._mesh_Down, ["leftclick"]) && e.button === 0) {
408
+ dispatchObjectEvent(this._mesh_Down, {
409
+ e: this._mouseEvent,
410
+ ...intersection,
411
+ renderer: this._renderer,
412
+ camera: this._camera,
413
+ object: intersection.object,
414
+ type: "leftclick",
415
+ offsetX: this._mousemoveEvent.offsetX,
416
+ offsetY: this._mousemoveEvent.offsetY,
417
+ x: this._mousemoveEvent.x,
418
+ y: this._mousemoveEvent.y,
419
+ });
420
+ }
421
+ if (this.hasEvent(this._mesh_Down, ["rightclick"]) && e.button === 2) {
422
+ dispatchObjectEvent(this._mesh_Down, {
423
+ e: this._mouseEvent,
424
+ ...intersection,
425
+ renderer: this._renderer,
426
+ camera: this._camera,
427
+ object: intersection.object,
428
+ type: "rightclick",
429
+ offsetX: this._mousemoveEvent.offsetX,
430
+ offsetY: this._mousemoveEvent.offsetY,
431
+ x: this._mousemoveEvent.x,
432
+ y: this._mousemoveEvent.y,
433
+ });
434
+ }
435
+ }
436
+ this._click_num = 0;
437
+ }
438
+ });
439
+ /** 设置 Points(点云)拾取阈值(世界单位),数值越大越容易点中。
440
+ * 全景纹理标记改用 Points 后,通过它调节点击命中范围。 */
441
+ setPointsThreshold(threshold) {
442
+ this._raycaster.params.Points.threshold = threshold;
443
+ }
444
+ /** 移除 canvas 上的所有鼠标/指针事件监听(渲染器销毁时调用)。
445
+ * 注:mouseenter 为内联匿名监听,销毁时 canvas 已脱离 DOM,无需显式移除。 */
446
+ dispose() {
447
+ const dom = this._renderer.domElement;
448
+ dom.removeEventListener("mouseleave", this._mouseleave, true);
449
+ dom.removeEventListener("mousemove", this._mousemove, true);
450
+ dom.removeEventListener("pointerdown", this._mousedown, true);
451
+ dom.removeEventListener("pointerup", this._mouseup, true);
452
+ }
453
+ }