InputHandler.js 29 KB

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