InputHandler.js 29 KB

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