InputHandler.js 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078
  1. /**
  2. * @author mschuetz / http://mschuetz.at
  3. *
  4. *
  5. */
  6. import * as THREE from "../../libs/three.js/build/three.module.js";
  7. import {KeyCodes} from "../KeyCodes.js";
  8. import {Utils} from "../utils.js";
  9. import {Buttons} from "../defines.js";
  10. import {EventDispatcher} from "../EventDispatcher.js";
  11. export class InputHandler extends EventDispatcher {
  12. constructor (viewer,scene) {
  13. super();
  14. this.viewer = viewer;
  15. this.renderer = viewer.renderer;
  16. this.domElement = this.renderer.domElement;
  17. this.enabled = true;
  18. this.scene = scene;
  19. this.interactiveScenes = [];
  20. this.interactiveObjects = new Set();
  21. this.inputListeners = [];
  22. this.blacklist = new Set();
  23. this.drag = null;
  24. this.mouse = new THREE.Vector2(0, 0);
  25. //add:
  26. this.pointer = new THREE.Vector2(0, 0); //交互点的屏幕坐标,有别于DOM坐标,在此存放NDC坐标。(NDC,三维常用坐标系,二维坐标,整个屏幕映射范围(-1,1),屏幕中心为原点,+Y朝上,+X朝右)
  27. this.mouseDownMouse = new THREE.Vector2(0, 0);
  28. this.selection = [];
  29. this.hoveredElements = [];
  30. this.pressedKeys = {};
  31. this.wheelDelta = 0;
  32. this.speed = 1;
  33. this.logMessages = false;
  34. if (this.domElement.tabIndex === -1) {
  35. this.domElement.tabIndex = 2222;
  36. }
  37. this.domElement.addEventListener('contextmenu', (event) => { event.preventDefault(); }, false);
  38. this.domElement.addEventListener('click', this.onMouseClick.bind(this), false);
  39. this.domElement.addEventListener('mousedown', this.onMouseDown.bind(this), false);
  40. window.addEventListener('mouseup', this.onMouseUp.bind(this), false);
  41. this.domElement.addEventListener('mousemove', this.onMouseMove.bind(this), false);
  42. //add
  43. /* this.domElement.addEventListener("pointerout", this.onMouseUp.bind(this)),
  44. this.domElement.addEventListener("pointercancel", this.onMouseUp.bind(this)),
  45. */
  46. this.domElement.addEventListener('mousewheel', this.onMouseWheel.bind(this), false);
  47. this.domElement.addEventListener('DOMMouseScroll', this.onMouseWheel.bind(this), false); // Firefox
  48. this.domElement.addEventListener('dblclick', this.onDoubleClick.bind(this));
  49. this.domElement.addEventListener('keydown', this.onKeyDown.bind(this));
  50. this.domElement.addEventListener('keyup', this.onKeyUp.bind(this));
  51. this.domElement.addEventListener('touchstart', this.onTouchStart.bind(this));
  52. this.domElement.addEventListener('touchend', this.onTouchEnd.bind(this));
  53. this.domElement.addEventListener('touchmove', this.onTouchMove.bind(this));
  54. }
  55. /* addInputListener (listener) {
  56. this.inputListeners.push(listener);
  57. }
  58. removeInputListener (listener) {
  59. this.inputListeners = this.inputListeners.filter(e => e !== listener);
  60. }
  61. getSortedListeners(){
  62. return this.inputListeners.sort( (a, b) => {
  63. let ia = (a.importance !== undefined) ? a.importance : 0;
  64. let ib = (b.importance !== undefined) ? b.importance : 0;
  65. return ib - ia;
  66. });
  67. } */
  68. onTouchStart (e) {
  69. if (this.logMessages) console.log(this.constructor.name + ': onTouchStart');
  70. e.preventDefault();
  71. if (e.touches.length === 1) { //changedTouches?
  72. let rect = this.domElement.getBoundingClientRect();
  73. let x = e.touches[0].pageX
  74. let y = e.touches[0].pageY
  75. this.dealPointerDown(x,y,e,true)
  76. }
  77. this.viewer.dispatchEvent({
  78. type: /* "global_"+ */e.type, // global_ 是否加上
  79. touches: e.touches,
  80. changedTouches: e.changedTouches
  81. });
  82. //add
  83. this.mouseDownMouse = this.mouse.clone()
  84. }
  85. onTouchEnd (e) {
  86. if (this.logMessages) console.log(this.constructor.name + ': onTouchEnd');
  87. e.preventDefault();
  88. /* this.viewer.dispatchEvent({
  89. type: 'global_drop',
  90. drag: this.drag,
  91. viewer: this.viewer
  92. });
  93. this.drag = null;
  94. this.viewer.dispatchEvent({
  95. type: 'global_' + e.type,
  96. touches: e.touches,
  97. changedTouches: e.changedTouches
  98. }); */
  99. if (e.touches.length === 0) {
  100. let rect = this.domElement.getBoundingClientRect();
  101. let x = e.changedTouches[0].pageX //万一一次松开两个指头的怎么办
  102. let y = e.changedTouches[0].pageY
  103. this.dealPointerUp(x,y,e,true)
  104. }
  105. }
  106. onTouchMove (e) {
  107. if (this.logMessages) console.log(this.constructor.name + ': onTouchMove');
  108. e.preventDefault();
  109. if (e.touches.length === 1) {
  110. let rect = this.domElement.getBoundingClientRect();
  111. let x = e.touches[0].pageX;
  112. let y = e.touches[0].pageY;
  113. //this.mouse.set(x, y);
  114. this.dealPointerMove(x, y, e, true)
  115. /* var { camera, viewport } = this.getPointerInViewport(x, y )
  116. this.hoverViewport = viewport
  117. if(!viewport)return
  118. if (this.drag) {
  119. this.drag.mouse = 1; //why??非左键也非右键的意思?
  120. this.drag.pointerDelta.set(this.pointer.x - this.drag.end.x, this.pointer.y - this.drag.end.y );
  121. this.drag.end.set(this.pointer.x, this.pointer.y);
  122. if (this.logMessages) console.log(this.constructor.name + ': drag: ');
  123. this.viewer.dispatchEvent({
  124. type: 'global_drag',
  125. drag: this.drag,
  126. viewer: this.viewer
  127. });
  128. } */
  129. }
  130. /* for (let inputListener of this.getSortedListeners()) {
  131. inputListener. */this.viewer.dispatchEvent({
  132. type: e.type,
  133. touches: e.touches,
  134. changedTouches: e.changedTouches
  135. });
  136. //}
  137. // DEBUG CODE
  138. // let debugTouches = [...e.touches, {
  139. // pageX: this.domElement.clientWidth / 2,
  140. // pageY: this.domElement.clientHeight / 2}];
  141. // for(let inputListener of this.getSortedListeners()){
  142. // inputListener.dispatchEvent({
  143. // type: e.type,
  144. // touches: debugTouches,
  145. // changedTouches: e.changedTouches
  146. // });
  147. // }
  148. }
  149. onKeyDown (e) {
  150. if (this.logMessages) console.log(this.constructor.name + ': onKeyDown');
  151. // DELETE
  152. if (e.keyCode === KeyCodes.DELETE && this.selection.length > 0) {
  153. this.dispatchEvent({
  154. type: 'delete',
  155. selection: this.selection
  156. });
  157. this.deselectAll();
  158. }
  159. this.dispatchEvent({
  160. type: 'keydown',
  161. keyCode: e.keyCode,
  162. event: e
  163. });
  164. // for(let l of this.getSortedListeners()){
  165. // l.dispatchEvent({
  166. // type: "keydown",
  167. // keyCode: e.keyCode,
  168. // event: e
  169. // });
  170. // }
  171. this.pressedKeys[e.keyCode] = true;
  172. // e.preventDefault();
  173. }
  174. onKeyUp (e) {
  175. if (this.logMessages) console.log(this.constructor.name + ': onKeyUp');
  176. delete this.pressedKeys[e.keyCode];
  177. e.preventDefault();
  178. }
  179. onDoubleClick (e) {
  180. if (this.logMessages) console.log(this.constructor.name + ': onDoubleClick');
  181. let consumed = false;
  182. for (let hovered of this.hoveredElements) {
  183. if (hovered._listeners && hovered._listeners['dblclick']) {
  184. hovered.object.dispatchEvent({
  185. type: 'dblclick',
  186. mouse: this.mouse,
  187. object: hovered.object
  188. });
  189. consumed = true;
  190. break;
  191. }
  192. }
  193. if (!consumed) {
  194. /* for (let inputListener of this.getSortedListeners()) {
  195. inputListener. */this.viewer.dispatchEvent({
  196. type: 'global_dblclick',
  197. mouse: this.mouse,
  198. object: null
  199. });
  200. //}
  201. }
  202. e.preventDefault();
  203. }
  204. onMouseClick (e) {
  205. if (this.logMessages) console.log(this.constructor.name + ': onMouseClick');
  206. e.preventDefault();
  207. }
  208. dealPointerDown(x,y,e,isTouch){
  209. //重新获取一下pointer, 因点击了浏览器的按钮展开列表时 move回来不会触发onmousemove,所以pointer是旧的
  210. var { camera, viewport } = this.getPointerInViewport(x, y )
  211. this.hoverViewport = viewport
  212. if(!viewport)return
  213. e.preventDefault();
  214. //this.onMouseMove(e)//add 重新获取一下mouse, 因在此前canvas可能失去侦听(不记得是什么了。如果一定要的话再写个加侦听的函数,但是直接调用mousemove的话会发送drag,导致magnifier停止渲染)
  215. let consumed = false;
  216. let consume = () => { return consumed = true; };
  217. if (this.hoveredElements.length === 0) {
  218. this.viewer.dispatchEvent({
  219. type: 'global_mousedown',
  220. viewer: this.viewer,
  221. mouse: this.mouse
  222. });
  223. }else{
  224. for(let hovered of this.hoveredElements){
  225. let object = hovered.object;
  226. object.dispatchEvent({
  227. type: 'mousedown',
  228. viewer: this.viewer,
  229. consume: consume
  230. });
  231. if(consumed){
  232. break;
  233. }
  234. }
  235. }
  236. if (!this.drag) {
  237. let target = (isTouch||e.button == THREE.MOUSE.LEFT) && this.hoveredElements.find(el => (//只有左键能拖拽
  238. el.object._listeners &&
  239. el.object._listeners['drag'] &&
  240. el.object._listeners['drag'].length > 0));
  241. if (target) {
  242. this.startDragging(target.object, {location: target.point});
  243. } else {
  244. this.startDragging(null);
  245. }
  246. }
  247. //add
  248. this.drag.pointerDragStart = this.pointer.clone()
  249. this.drag.intersectStart = this.intersectPoint;
  250. this.mouseDownMouse = this.mouse.clone()
  251. this.dragViewport = this.hoverViewport;
  252. }
  253. onMouseDown (e) {
  254. if (this.logMessages) console.log(this.constructor.name + ': onMouseDown');
  255. this.dealPointerDown(e.clientX, e.clientY,e)
  256. }
  257. getEventDesc(e,isTouch){//搜集dispatchEvent要给的一般数据
  258. return {
  259. viewer: this.viewer,
  260. mouse: this.mouse,
  261. pointer:this.pointer,
  262. drag :this.drag,
  263. isAtDomElement: e.target == this.domElement,
  264. dragViewport : this.dragViewport,
  265. hoverViewport: this.hoverViewport,
  266. button: isTouch ? 0 : e.button,
  267. buttons: isTouch ? e.touches.length : e.buttons,
  268. isTouch,
  269. }
  270. }
  271. dealPointerUp(x,y,e,isTouch){
  272. if(!this.drag){// 在canvas外mousedown
  273. return
  274. }
  275. if (this.logMessages) console.log(this.constructor.name + ': onMouseUp');
  276. e.preventDefault();
  277. let pressDistance = this.mouseDownMouse.distanceTo(this.mouse);
  278. let noMovement = this.drag.pointerDelta.length() == 0//this.getNormalizedDrag().length() === 0;
  279. let consumed = false;
  280. let consume = () => { return consumed = true; };
  281. //if (this.hoveredElements.length === 0) {
  282. /* for (let inputListener of this.getSortedListeners()) {
  283. inputListener */this.viewer.dispatchEvent($.extend(
  284. this.getEventDesc(e,isTouch),
  285. {
  286. type: 'global_mouseup',
  287. pressDistance,
  288. consume,
  289. }
  290. ));
  291. /* if(consumed){//??
  292. break;
  293. } */
  294. //}
  295. //}
  296. if (this.hoveredElements.length > 0) {
  297. let hovered = this.hoveredElements
  298. .map(e => e.object)
  299. .find(e => (e._listeners && e._listeners['mouseup']));
  300. if(hovered){
  301. hovered.dispatchEvent({
  302. type: 'mouseup',
  303. viewer: this.viewer,
  304. consume: consume
  305. });
  306. }
  307. }
  308. if (this.drag) {
  309. //拖拽结束
  310. if (this.drag.object/* && e.button == THREE.MOUSE.LEFT */) {//add LEFT
  311. if (this.logMessages) console.log(`${this.constructor.name}: drop ${this.drag.object.name}`);
  312. this.drag.object.dispatchEvent($.extend(
  313. this.getEventDesc(e,isTouch),
  314. {
  315. type: 'drop',
  316. pressDistance,
  317. }
  318. ));
  319. } else {
  320. this.viewer.dispatchEvent($.extend(
  321. this.getEventDesc(e,isTouch),
  322. {
  323. type: 'global_drop',
  324. pressDistance
  325. }
  326. ));
  327. // check for a click
  328. if(pressDistance < Potree.config.clickMaxDragDis){
  329. if(this.hoveredElements && this.hoveredElements[0]){
  330. if (this.logMessages) console.log(`${this.constructor.name}: click ${clicked.name}`);
  331. this.hoveredElements[0].object.dispatchEvent($.extend(
  332. this.getEventDesc(e,isTouch),
  333. {
  334. type: 'click',
  335. pressDistance
  336. }
  337. ));
  338. }else{
  339. this.viewer.dispatchEvent($.extend(
  340. this.getEventDesc(e,isTouch),
  341. {
  342. type: 'global_click',
  343. pressDistance
  344. }
  345. ));
  346. }
  347. }
  348. }
  349. /* let clicked = this.hoveredElements.map(h => h.object).find(v => v === this.drag.object) !== undefined;
  350. if(clicked){
  351. if (this.logMessages) console.log(`${this.constructor.name}: click ${this.drag.object.name}`);
  352. this.drag.object.dispatchEvent({
  353. type: 'click',
  354. viewer: this.viewer,
  355. consume: consume,
  356. });
  357. } */
  358. this.drag = null;
  359. }
  360. this.dragViewport = null
  361. if(!consumed && !this.fixSelection){
  362. if (e.button === THREE.MOUSE.LEFT) {
  363. if (noMovement) {
  364. let selectable = this.hoveredElements
  365. .find(el => el.object._listeners && el.object._listeners['select']);
  366. if (selectable) {
  367. selectable = selectable.object;
  368. if (this.isSelected(selectable)) {
  369. this.selection
  370. .filter(e => e !== selectable)
  371. .forEach(e => this.toggleSelection(e));
  372. } else {
  373. this.deselectAll();
  374. this.toggleSelection(selectable);
  375. }
  376. } else {
  377. this.deselectAll();
  378. }
  379. }
  380. } else if ((e.button === THREE.MOUSE.RIGHT) && noMovement) {
  381. this.deselectAll();
  382. }
  383. }
  384. }
  385. onMouseUp (e) {
  386. this.dealPointerUp(e.clientX, e.clientY, e )
  387. }
  388. getPointerInViewport(clientX, clientY, viewForceAt ){
  389. let rect = this.domElement.getBoundingClientRect();
  390. let x = clientX - rect.left;
  391. let y = clientY - rect.top;
  392. let camera
  393. let viewport
  394. //if(this.viewer.viewports || viewForceAt){
  395. var getDimension = (view)=>{
  396. var left = Math.floor(this.domElement.clientWidth * view.left)
  397. , bottom = this.domElement.clientHeight * view.bottom
  398. , width = Math.floor(this.domElement.clientWidth * view.width)
  399. , height = this.domElement.clientHeight * view.height
  400. , top = Math.floor(this.domElement.clientHeight - bottom - height)
  401. return {left, bottom, width, height, top}
  402. }
  403. var getView = (view, left, bottom, width, height, top)=>{
  404. this.mouse.set(x-left, y - top )
  405. Utils.convertScreenPositionToNDC(this.pointer, this.mouse, width, height);
  406. camera = view.camera;
  407. viewport = view
  408. }
  409. if(viewForceAt){
  410. let {left, bottom, width, height, top} = getDimension(viewForceAt)
  411. getView(viewForceAt, left, bottom, width, height, top)
  412. }else{
  413. var length = this.viewer.viewports.length;
  414. //var getif = false
  415. for(var i=0;i<length;i++){
  416. var view = this.viewer.viewports[i];
  417. if(!view.active)continue
  418. var {left, bottom, width, height, top} = getDimension(view)
  419. if(x >= left && x <= left + width && y >= top && y <= top + height){
  420. getView(view, left, bottom, width, height, top)
  421. //getif = true
  422. break;
  423. }
  424. }
  425. }
  426. /*} else{
  427. camera = this.viewer.scene.getActiveCamera()
  428. this.mouse.set(x , y )
  429. Utils.convertScreenPositionToNDC(this.pointer, this.mouse, this.domElement.clientWidth, this.domElement.clientHeight);
  430. } */
  431. return {
  432. camera, viewport
  433. }
  434. }
  435. onMouseMove (e) {
  436. this.dealPointerMove(e.clientX, e.clientY, e )
  437. }
  438. dealPointerMove(x, y, e, isTouch){
  439. var { camera, viewport } = this.getPointerInViewport(x, y, this.dragViewport)
  440. this.hoverViewport = viewport
  441. if(!viewport)return//刚变化viewport时会找不到
  442. let hoveredElements = this.getHoveredElements();
  443. if(hoveredElements.length > 0){
  444. let names = hoveredElements.map(h => h.object.name).join(", ");
  445. if (this.logMessages) console.log(`${this.constructor.name}: onMouseMove; hovered: '${names}'`);
  446. }
  447. //add
  448. let intersectPoint = viewport.noPointcloud? null : Utils.getMousePointCloudIntersection(
  449. viewport,
  450. this.mouse,
  451. this.pointer,
  452. camera,
  453. this.viewer,
  454. this.viewer.scene.pointclouds,
  455. {pickClipped: true});
  456. if(viewport.camera.type == 'OrthographicCamera'/* == 'mapViewport' */){
  457. let pos3d = new THREE.Vector3(this.pointer.x,this.pointer.y,-1).unproject(viewport.camera); //z:-1朝外
  458. pos3d.setZ(viewer.bound.boundingBox.min.z + 0.2) //大概放地面上
  459. if(!intersectPoint){
  460. intersectPoint = {}
  461. }
  462. intersectPoint.orthoIntersect = pos3d.clone()
  463. }
  464. if(e.onlyGetIntersect){
  465. return intersectPoint
  466. }
  467. e.preventDefault();
  468. if (this.drag) {//有拖拽(不一定拖拽了物体, 也不一定按下了鼠标)
  469. this.drag.mouse = isTouch ? 1 : e.buttons;
  470. this.drag.hoverViewport = this.hoverViewport
  471. this.drag.pointerDelta.set(this.pointer.x - this.drag.end.x, this.pointer.y - this.drag.end.y )
  472. this.drag.end.set(this.pointer.x, this.pointer.y);
  473. if (this.drag.object && (e.buttons == Buttons.NONE || !this.drag.notPressMouse )){//add notPressMouse 如果标记是不需要按鼠标的拖拽,则一旦按下鼠标,就暂停拖拽物体(改为拖拽场景):(如添加测量时突然拖拽画面)
  474. if (this.logMessages) console.log(this.constructor.name + ': drag: ' + this.drag.object.name);
  475. this.drag.object.dispatchEvent($.extend(
  476. this.getEventDesc(e,isTouch),
  477. {
  478. type: 'drag',
  479. intersectPoint,
  480. }
  481. ))
  482. } else {
  483. //add:
  484. this.drag.pointer = this.pointer.clone();
  485. if (this.logMessages) console.log(this.constructor.name + ': drag: ');
  486. let dragConsumed = false;
  487. this.viewer.dispatchEvent($.extend(
  488. this.getEventDesc(e,isTouch),
  489. {
  490. type: 'global_drag',
  491. intersectPoint,
  492. consume: () => {dragConsumed = true;}
  493. }
  494. ))
  495. }
  496. }else{
  497. let curr = hoveredElements.map(a => a.object).find(a => true);
  498. let prev = this.hoveredElements.map(a => a.object).find(a => true);
  499. if(curr !== prev){
  500. if(curr){
  501. if (this.logMessages) console.log(`${this.constructor.name}: mouseover: ${curr.name}`);
  502. curr.dispatchEvent({
  503. type: 'mouseover',
  504. object: curr,
  505. });
  506. }
  507. if(prev){
  508. if (this.logMessages) console.log(`${this.constructor.name}: mouseleave: ${prev.name}`);
  509. prev.dispatchEvent({
  510. type: 'mouseleave',
  511. object: prev,
  512. });
  513. }
  514. }
  515. if(hoveredElements.length > 0){
  516. let object = hoveredElements
  517. .map(e => e.object)
  518. .find(e => (e._listeners && e._listeners['mousemove']));
  519. if(object){
  520. object.dispatchEvent({
  521. type: 'mousemove',
  522. object: object
  523. });
  524. }
  525. }
  526. //仅在鼠标不按下时更新:
  527. {
  528. let handleState = viewer.modules.Alignment.handleState
  529. if(viewport.alignment && handleState && viewport.alignment[handleState]){
  530. if(handleState == 'translate'){
  531. if( intersectPoint && intersectPoint.location ){
  532. viewer.dispatchEvent({
  533. type : "CursorChange", action : "add", name:"movePointcloud"
  534. })
  535. }else{
  536. viewer.dispatchEvent({
  537. type : "CursorChange", action : "remove", name:"movePointcloud"
  538. })
  539. }
  540. }else if(handleState == 'rotate'){
  541. if( intersectPoint && intersectPoint.location ){
  542. viewer.dispatchEvent({
  543. type : "CursorChange", action : "add", name:"rotatePointcloud"
  544. })
  545. }else{
  546. viewer.dispatchEvent({
  547. type : "CursorChange", action : "remove", name:"rotatePointcloud"
  548. })
  549. }
  550. }
  551. }
  552. }
  553. }
  554. if (intersectPoint) {
  555. if(viewer.showCoordType){ //显示坐标位置时
  556. let pos = intersectPoint.point.position.toArray()
  557. if(viewer.showCoordType == "local"){
  558. }else if(viewer.showCoordType == "lonlat"){
  559. pos = viewer.transform.lonlatToLocal.inverse(pos)
  560. }else{
  561. pos = viewer.transform.lonlatToLocal.inverse(pos)
  562. pos = viewer.transform.lonlatTo4550.forward(pos)
  563. }
  564. viewer.dispatchEvent({
  565. type : "coordinateChange", pos
  566. })
  567. }
  568. }
  569. this.intersectPoint = intersectPoint
  570. intersectPoint && (this.hoverViewport.lastIntersect = intersectPoint)
  571. this.viewer.dispatchEvent($.extend(
  572. this.getEventDesc(e,isTouch),
  573. {
  574. type: 'global_mousemove',
  575. intersectPoint,
  576. }
  577. ))
  578. this.hoveredElements = hoveredElements;
  579. }
  580. onMouseWheel(e){
  581. if(!this.enabled) return;
  582. if(this.logMessages) console.log(this.constructor.name + ": onMouseWheel");
  583. e.preventDefault();
  584. let delta = 0;
  585. if (e.wheelDelta !== undefined) { // WebKit / Opera / Explorer 9
  586. delta = e.wheelDelta;
  587. } else if (e.detail !== undefined) { // Firefox
  588. delta = -e.detail;
  589. }
  590. let ndelta = Math.sign(delta);
  591. // this.wheelDelta += Math.sign(delta);
  592. if (this.hoveredElement) {
  593. this.hoveredElement.object.dispatchEvent($.extend(
  594. this.getEventDesc(e,isTouch),
  595. {
  596. type: 'mousewheel',
  597. delta: ndelta,
  598. object: this.hoveredElement.object
  599. }
  600. ));
  601. } else {
  602. this.viewer.dispatchEvent($.extend(
  603. this.getEventDesc(e),
  604. {
  605. type: 'global_mousewheel',
  606. delta: ndelta,
  607. }
  608. ));
  609. }
  610. }
  611. startDragging (object, args = null) {
  612. let name = object ? object.name : "no name";
  613. if (this.logMessages) console.log(`${this.constructor.name}: startDragging: '${name}'`);
  614. this.drag = {
  615. start: this.pointer.clone(),
  616. end: this.pointer.clone(),
  617. pointerDelta: new THREE.Vector2(0, 0),
  618. object: object,
  619. dragViewport : this.hoverViewport, //开始之后就不会变了
  620. hoverViewport: this.hoverViewport //会变化
  621. };
  622. this.viewer.dispatchEvent({
  623. type: "startDragging",
  624. drag: this.drag,
  625. hoverViewport: this.hoverViewport
  626. })
  627. /* console.log('startDragging')
  628. console.log(this.drag.end) */
  629. if (args) {
  630. for (let key of Object.keys(args)) {
  631. this.drag[key] = args[key];
  632. }
  633. }
  634. }
  635. /* getMousePointCloudIntersection (mouse) {
  636. return Utils.getMousePointCloudIntersection(
  637. this.mouse,
  638. this.scene.getActiveCamera(),
  639. this.viewer,
  640. this.scene.pointclouds);
  641. } */
  642. toggleSelection (object) {
  643. let oldSelection = this.selection;
  644. let index = this.selection.indexOf(object);
  645. if (index === -1) {
  646. this.selection.push(object);
  647. object.dispatchEvent({
  648. type: 'select'
  649. });
  650. } else {
  651. this.selection.splice(index, 1);
  652. object.dispatchEvent({
  653. type: 'deselect'
  654. });
  655. }
  656. this.dispatchEvent({
  657. type: 'selection_changed',
  658. oldSelection: oldSelection,
  659. selection: this.selection
  660. });
  661. }
  662. deselect(object){
  663. let oldSelection = this.selection;
  664. let index = this.selection.indexOf(object);
  665. if(index >= 0){
  666. this.selection.splice(index, 1);
  667. object.dispatchEvent({
  668. type: 'deselect'
  669. });
  670. this.dispatchEvent({
  671. type: 'selection_changed',
  672. oldSelection: oldSelection,
  673. selection: this.selection
  674. });
  675. }
  676. }
  677. deselectAll () {
  678. for (let object of this.selection) {
  679. object.dispatchEvent({
  680. type: 'deselect'
  681. });
  682. }
  683. let oldSelection = this.selection;
  684. if (this.selection.length > 0) {
  685. this.selection = [];
  686. this.dispatchEvent({
  687. type: 'selection_changed',
  688. oldSelection: oldSelection,
  689. selection: this.selection
  690. });
  691. }
  692. }
  693. isSelected (object) {
  694. let index = this.selection.indexOf(object);
  695. return index !== -1;
  696. }
  697. registerInteractiveObject(object){
  698. this.interactiveObjects.add(object);
  699. }
  700. removeInteractiveObject(object){
  701. this.interactiveObjects.delete(object);
  702. }
  703. registerInteractiveScene (scene) {
  704. let index = this.interactiveScenes.indexOf(scene);
  705. if (index === -1) {
  706. this.interactiveScenes.push(scene);
  707. }
  708. }
  709. unregisterInteractiveScene (scene) {
  710. let index = this.interactiveScenes.indexOf(scene);
  711. if (index > -1) {
  712. this.interactiveScenes.splice(index, 1);
  713. }
  714. }
  715. getHoveredElement () {
  716. let hoveredElements = this.getHoveredElements();
  717. if (hoveredElements.length > 0) {
  718. return hoveredElements[0];
  719. } else {
  720. return null;
  721. }
  722. }
  723. getHoveredElements () {
  724. let scenes = this.hoverViewport.interactiveScenes || this.interactiveScenes.concat(this.scene);
  725. let interactableListeners = ['mouseup', 'mousemove', 'mouseover', 'mouseleave', 'drag', 'drop', 'click', 'select', 'deselect'];
  726. let interactables = [];
  727. for (let scene of scenes) {
  728. scene.traverseVisible(node => {//检测加了侦听的object
  729. if (node._listeners && node.visible && !this.blacklist.has(node)) {
  730. let hasInteractableListener = interactableListeners.filter((e) => {
  731. return node._listeners[e] !== undefined;
  732. }).length > 0;
  733. if (hasInteractableListener) {
  734. interactables.push(node);
  735. }
  736. }
  737. });
  738. }
  739. let camera = this.hoverViewport.camera
  740. let ray = Utils.mouseToRay(this.pointer, camera );
  741. let raycaster = new THREE.Raycaster();
  742. raycaster.ray.set(ray.origin, ray.direction);
  743. raycaster.camera = camera //add
  744. raycaster.params.Line.threshold = 0.2;
  745. //raycaster.layers.enableAll()//add
  746. viewer.setCameraLayers(raycaster, //设置能识别到的layers(如空间模型里只有mapViewer能识别到marker)
  747. ['sceneObjects','mapObjects','measure','marker','transformationTool'],
  748. this.hoverViewport && this.hoverViewport.extraEnableLayers
  749. )
  750. viewer.emit('raycaster', {viewport: this.hoverViewport})//add
  751. let intersections = raycaster.intersectObjects(interactables.filter(o => o.visible), true); //原本是false 检测不到children
  752. intersections = intersections.map(e=>{//add 转化为interactables
  753. var object = e.object;
  754. do{
  755. if(interactables.includes(object)) {
  756. e.oriObject = e.object;
  757. e.object = object;
  758. break
  759. }
  760. object = object.parent
  761. }while(object)
  762. return e
  763. })
  764. //add for测量线,在检测到sphere时优先选中sphere而非线
  765. intersections = intersections.sort(function(a,b){return b.object.renderOrder-a.object.renderOrder}) // 降序
  766. return intersections;
  767. }
  768. /* setScene (scene) {
  769. this.deselectAll();
  770. this.scene = scene;
  771. } */
  772. update (delta) {
  773. }
  774. /*getNormalizedDrag () {
  775. if (!this.drag) {
  776. return new THREE.Vector2(0, 0);
  777. }
  778. let diff = new THREE.Vector2().subVectors(this.drag.end, this.drag.start);
  779. diff.x = diff.x / this.domElement.clientWidth;
  780. diff.y = diff.y / this.domElement.clientHeight;
  781. return diff;
  782. }
  783. getNormalizedLastDrag () {
  784. if (!this.drag) {
  785. return new THREE.Vector2(0, 0);
  786. }
  787. let mouseDelta = this.drag.mouseDelta.clone();
  788. mouseDelta.x = mouseDelta.x / this.domElement.clientWidth;
  789. mouseDelta.y = mouseDelta.y / this.domElement.clientHeight;
  790. return mouseDelta;
  791. } */
  792. getMouseDirection() {//add
  793. let camera = this.hoverViewport.camera
  794. var t = new THREE.Vector3(this.pointer.x, this.pointer.y, -1).unproject(camera),
  795. i = new THREE.Vector3(this.pointer.x, this.pointer.y, 1).unproject(camera);
  796. return {origin: t, direction:i.clone().sub(t).normalize() }
  797. }
  798. }