three-base 2.0.142 → 2.0.145

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 (227) 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 +511 -511
  10. package/FPScontrol.js +1799 -1799
  11. package/FPScontrol.ts +1855 -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 +247 -247
  33. package/Mirror.d.ts +25 -25
  34. package/Mirror.js +143 -143
  35. package/MktMesh/MktMesh.d.ts +301 -291
  36. package/MktMesh/MktMesh.js +1064 -1045
  37. package/MktMesh/MktMesh.ts +32 -11
  38. package/MktMesh/assetUrl.d.ts +59 -35
  39. package/MktMesh/assetUrl.js +154 -69
  40. package/MktMesh/assetUrl.ts +155 -69
  41. package/MktMesh/mktMappingShader.d.ts +12 -12
  42. package/MktMesh/mktMappingShader.js +138 -138
  43. package/MktMesh/mktMappingShader.ts +139 -139
  44. package/MktMesh/mktShader.d.ts +263 -263
  45. package/MktMesh/mktShader.js +1236 -1236
  46. package/MktMesh/mktShader.ts +1344 -1344
  47. package/MktMesh/panoBitmapTexture.d.ts +25 -25
  48. package/MktMesh/panoBitmapTexture.js +52 -52
  49. package/MktMesh/panoBitmapTexture.ts +54 -54
  50. package/MktMesh/panoSlotBind.d.ts +29 -29
  51. package/MktMesh/panoSlotBind.js +106 -106
  52. package/MktMesh/panoSlotBind.ts +153 -153
  53. package/MktMesh/panoSlotRoster.d.ts +22 -22
  54. package/MktMesh/panoSlotRoster.js +169 -169
  55. package/MktMesh/panoSlotRoster.ts +168 -168
  56. package/MktMesh/panoTileStitcher.d.ts +119 -119
  57. package/MktMesh/panoTileStitcher.js +529 -529
  58. package/MktMesh/panoTileStitcher.ts +616 -616
  59. package/MktMesh/types.d.ts +75 -75
  60. package/MktMesh/types.js +1 -1
  61. package/MktMesh/wallCapTessellate.d.ts +33 -33
  62. package/MktMesh/wallCapTessellate.js +97 -97
  63. package/MktMesh/wallCapTessellate.ts +68 -68
  64. package/PipeMesh/PathGeometry.d.ts +44 -44
  65. package/PipeMesh/PathGeometry.js +307 -307
  66. package/PipeMesh/PathPoint.d.ts +17 -17
  67. package/PipeMesh/PathPoint.js +31 -31
  68. package/PipeMesh/PathPointList.d.ts +31 -31
  69. package/PipeMesh/PathPointList.js +209 -209
  70. package/PipeMesh/PathTubeGeometry.d.ts +25 -25
  71. package/PipeMesh/PathTubeGeometry.js +130 -130
  72. package/PipeMesh/PipeMesh.d.ts +25 -25
  73. package/PipeMesh/PipeMesh.js +63 -63
  74. package/PipeMesh/index.d.ts +1 -1
  75. package/PipeMesh/index.js +1 -1
  76. package/PlaneModal1/PlaneModal1.d.ts +34 -34
  77. package/PlaneModal1/PlaneModal1.js +109 -109
  78. package/PlaneModal1/index.d.ts +1 -1
  79. package/PlaneModal1/index.js +1 -1
  80. package/PlaneText.d.ts +27 -27
  81. package/PlaneText.js +35 -35
  82. package/PlaneWithHtml.d.ts +13 -13
  83. package/PlaneWithHtml.js +64 -64
  84. package/PointLight/PointLight.d.ts +13 -13
  85. package/PointLight/PointLight.js +64 -64
  86. package/PointLight/index.d.ts +1 -1
  87. package/PointLight/index.js +1 -1
  88. package/Sky/Sky.d.ts +9 -9
  89. package/Sky/Sky.js +22 -22
  90. package/Sky/index.d.ts +1 -1
  91. package/Sky/index.js +1 -1
  92. package/SpotLight.d.ts +6 -6
  93. package/SpotLight.js +72 -72
  94. package/SpriteModal1/SpriteModal1.d.ts +33 -33
  95. package/SpriteModal1/SpriteModal1.js +116 -116
  96. package/SpriteModal1/index.d.ts +1 -1
  97. package/SpriteModal1/index.js +1 -1
  98. package/SpriteText.d.ts +46 -46
  99. package/SpriteText.js +176 -176
  100. package/SpriteText2.d.ts +48 -48
  101. package/SpriteText2.js +223 -223
  102. package/SpriteText3.d.ts +86 -86
  103. package/SpriteText3.js +517 -517
  104. package/SpriteText3.ts +599 -599
  105. package/SpriteWithHtml.d.ts +9 -9
  106. package/SpriteWithHtml.js +44 -44
  107. package/Text3D/Text3D.d.ts +20 -20
  108. package/Text3D/Text3D.js +58 -58
  109. package/Text3D/fontController.d.ts +60 -60
  110. package/Text3D/fontController.js +166 -166
  111. package/Text3D/index.d.ts +1 -1
  112. package/Text3D/index.js +1 -1
  113. package/ThreeBase.d.ts +248 -248
  114. package/ThreeBase.js +1202 -1202
  115. package/ThreeBase.ts +1314 -1314
  116. package/ThreeMouse.d.ts +53 -54
  117. package/ThreeMouse.js +453 -453
  118. package/Transition.d.ts +45 -45
  119. package/Transition.js +209 -209
  120. package/Water/Water.d.ts +5 -5
  121. package/Water/Water.js +44 -44
  122. package/Water/index.d.ts +2 -2
  123. package/Water/index.js +2 -2
  124. package/WaterFlow/FloatingDuck.d.ts +88 -88
  125. package/WaterFlow/FloatingDuck.js +307 -307
  126. package/WaterFlow/FloatingDuck.ts +445 -445
  127. package/WaterFlow/GPUFluidSimulation.d.ts +56 -56
  128. package/WaterFlow/GPUFluidSimulation.js +781 -781
  129. package/WaterFlow/GPUFluidSimulation.ts +827 -827
  130. package/WaterFlow/ReservoirSystem.d.ts +106 -106
  131. package/WaterFlow/ReservoirSystem.js +611 -611
  132. package/WaterFlow/ReservoirSystem.ts +754 -754
  133. package/WaterFlow/SPHField.d.ts +35 -35
  134. package/WaterFlow/SPHField.js +203 -203
  135. package/WaterFlow/SPHField.ts +228 -228
  136. package/WaterFlow/ScreenSpaceFluidPass.d.ts +69 -69
  137. package/WaterFlow/ScreenSpaceFluidPass.js +728 -728
  138. package/WaterFlow/ScreenSpaceFluidPass.ts +789 -789
  139. package/WaterFlow/ShallowWaterSurface.d.ts +45 -45
  140. package/WaterFlow/ShallowWaterSurface.js +438 -438
  141. package/WaterFlow/ShallowWaterSurface.ts +510 -510
  142. package/WaterFlow/WaterFlow.d.ts +87 -87
  143. package/WaterFlow/WaterFlow.js +171 -171
  144. package/WaterFlow/WaterFlow.ts +219 -219
  145. package/WaterFlow/types.d.ts +161 -161
  146. package/WaterFlow/types.js +1 -1
  147. package/WaterFlow/types.ts +189 -189
  148. package/WaterFlow/waterFlowPass.d.ts +3 -3
  149. package/WaterFlow/waterFlowPass.js +20 -20
  150. package/WaterFlow/waterFlowPass.ts +40 -40
  151. package/collisionOBB.d.ts +42 -42
  152. package/collisionOBB.js +112 -112
  153. package/collisionOBB.ts +108 -108
  154. package/declare.d.ts +25 -25
  155. package/index.d.ts +1 -1
  156. package/index.js +1 -1
  157. package/instanced/InstancedBatch.d.ts +57 -57
  158. package/instanced/InstancedBatch.js +348 -348
  159. package/instanced/InstancedBatch.ts +406 -406
  160. package/instanced/InstancedChild.d.ts +174 -174
  161. package/instanced/InstancedChild.js +264 -264
  162. package/instanced/InstancedChild.ts +327 -327
  163. package/instanced/InstancedGroup.d.ts +43 -43
  164. package/instanced/InstancedGroup.js +126 -126
  165. package/instanced/InstancedGroup.ts +137 -137
  166. package/instanced/InstancedMeshBase.d.ts +38 -38
  167. package/instanced/InstancedMeshBase.js +282 -282
  168. package/instanced/InstancedTemplate.d.ts +46 -46
  169. package/instanced/InstancedTemplate.js +125 -125
  170. package/keyControls.d.ts +29 -30
  171. package/keyControls.js +101 -101
  172. package/lensflare/LensFlare.d.ts +39 -39
  173. package/lensflare/LensFlare.js +284 -284
  174. package/package.json +6 -1
  175. package/pass/bloom_pass.d.ts +2 -2
  176. package/pass/bloom_pass.js +174 -174
  177. package/pass/cover_pass.d.ts +2 -2
  178. package/pass/cover_pass.js +108 -108
  179. package/pass/debugDepthState.d.ts +20 -20
  180. package/pass/debugDepthState.js +9 -9
  181. package/pass/debugDepthState.ts +22 -22
  182. package/pass/depthTestBias.d.ts +12 -12
  183. package/pass/depthTestBias.js +12 -12
  184. package/pass/depthTestBias.ts +12 -12
  185. package/pass/effectUserData.d.ts +27 -27
  186. package/pass/effectUserData.js +1 -1
  187. package/pass/effectUserData.ts +46 -46
  188. package/pass/frosted_glass_pass.d.ts +2 -2
  189. package/pass/frosted_glass_pass.js +150 -150
  190. package/pass/fsQuad.d.ts +9 -9
  191. package/pass/fsQuad.js +28 -28
  192. package/pass/glow_pass.d.ts +2 -2
  193. package/pass/glow_pass.js +350 -350
  194. package/pass/screen_bloom_pass.d.ts +11 -11
  195. package/pass/screen_bloom_pass.js +136 -136
  196. package/pass/ssao_pass.d.ts +88 -88
  197. package/pass/ssao_pass.js +799 -799
  198. package/pass/ssao_pass.ts +918 -918
  199. package/pass/stroke_pass.d.ts +2 -2
  200. package/pass/stroke_pass.js +267 -267
  201. package/shaders/FXAAShaderMaterial.d.ts +3 -3
  202. package/shaders/FXAAShaderMaterial.js +20 -20
  203. package/shaders/baseDepthVisShader.d.ts +11 -11
  204. package/shaders/baseDepthVisShader.js +36 -36
  205. package/shaders/baseDepthVisShader.ts +36 -36
  206. package/shaders/baseTextureToRenderShader.d.ts +2 -2
  207. package/shaders/baseTextureToRenderShader.js +19 -19
  208. package/shaders/copyShader.d.ts +3 -3
  209. package/shaders/copyShader.js +13 -13
  210. package/shaders/debugDepthCompareShader.d.ts +14 -14
  211. package/shaders/debugDepthCompareShader.js +49 -49
  212. package/shaders/debugDepthCompareShader.ts +50 -50
  213. package/shaders/debugDepthJudgeShader.d.ts +18 -18
  214. package/shaders/debugDepthJudgeShader.js +52 -52
  215. package/shaders/debugDepthJudgeShader.ts +54 -54
  216. package/shaders/debugExcludedShader.d.ts +13 -13
  217. package/shaders/debugExcludedShader.js +46 -46
  218. package/shaders/debugExcludedShader.ts +48 -48
  219. package/spriteTextBg.d.ts +1 -1
  220. package/spriteTextBg.js +20 -20
  221. package/spriteTextBg.ts +20 -20
  222. package/threeLoader.d.ts +35 -35
  223. package/threeLoader.js +518 -518
  224. package/threeUtils.d.ts +53 -53
  225. package/threeUtils.js +329 -329
  226. package/types.d.ts +2 -2
  227. 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
+ }