InputHandlerNew.js 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506
  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 Common from "../custom/utils/Common.js";
  10. import DepthBasicMaterial from '../custom/materials/DepthBasicMaterial.js'
  11. import browser from "../custom/utils/browser.js";
  12. import math from "../custom/utils/math.js";
  13. let {Buttons} = Potree.defines
  14. export class InputHandler extends THREE.EventDispatcher {
  15. constructor (viewer,scene) {
  16. super();
  17. this.viewer = viewer;
  18. this.renderer = viewer.renderer;
  19. this.domElement = this.renderer.domElement;
  20. this.enabled = true;
  21. this.scene = scene;
  22. this.interactiveScenes = [];
  23. this.interactiveObjects = new Set();
  24. this.inputListeners = [];
  25. this.blacklist = new Set();
  26. this.drag = null;
  27. this.mouse = new THREE.Vector2(0, 0);
  28. //add:
  29. this.pointer = new THREE.Vector2(0, 0); //交互点的屏幕坐标,有别于DOM坐标,在此存放NDC坐标。(NDC,三维常用坐标系,二维坐标,整个屏幕映射范围(-1,1),屏幕中心为原点,+Y朝上,+X朝右)
  30. this.mouseDownMouse = new THREE.Vector2(0, 0);
  31. this.selection = [];
  32. this.hoveredElements = [];
  33. this.pressedKeys = {};
  34. this.wheelDelta = 0;
  35. this.speed = 1;
  36. this.logMessages = false;
  37. if (this.domElement.tabIndex === -1) {
  38. this.domElement.tabIndex = 2222;
  39. }
  40. this.lastPointerUpTime = 0
  41. this.touches = []
  42. this.interactHistory = {move:0} //add
  43. this.hoverViewport = viewer.viewports[0]
  44. this.domElement.addEventListener('contextmenu', (event) => { event.preventDefault(); }, false);
  45. this.domElement.addEventListener('click', this.onMouseClick.bind(this), false);
  46. this.domElement.addEventListener('mousedown', this.onMouseDown.bind(this), false);
  47. window.addEventListener('mouseup', this.onMouseUp.bind(this), false);
  48. this.domElement.addEventListener('mousemove', this.onMouseMove.bind(this), false);
  49. //add
  50. /* this.domElement.addEventListener("pointerout", this.onMouseUp.bind(this)),
  51. this.domElement.addEventListener("pointercancel", this.onMouseUp.bind(this)),
  52. */
  53. this.domElement.addEventListener('mousewheel', this.onMouseWheel.bind(this), false);
  54. this.domElement.addEventListener('DOMMouseScroll', this.onMouseWheel.bind(this), false); // Firefox
  55. //this.domElement.addEventListener('dblclick', this.onDoubleClick.bind(this)); //因为双击时间间隔是跟随系统的所以不好判断
  56. this.domElement.addEventListener('keydown', this.onKeyDown.bind(this));
  57. window.addEventListener('keyup', this.onKeyUp.bind(this));
  58. //window.addEventListener('focus',()=>{
  59. window.addEventListener('blur',this.onKeyUp.bind(this)); //add
  60. this.domElement.addEventListener('touchstart', this.onTouchStart.bind(this));
  61. this.domElement.addEventListener('touchend', this.onTouchEnd.bind(this));
  62. this.domElement.addEventListener('touchmove', this.onTouchMove.bind(this));
  63. {
  64. this.measuring = [] //正在编辑的measure
  65. //let mesureInfo = new THREE.EventDispatcher()
  66. this.addEventListener('measuring',(e)=>{
  67. //true优先级高于false, 正在添加时dropMarker也不会停止
  68. //Potree.Utils.updateVisible(mesureInfo, e.situation, e.v, 0, e.v?'add':'cancel' )//借用该函数,使true优先级高于false,防止正在添加时dropMarker而停止
  69. if(e.v){
  70. this.measuring.includes(e.object) || this.measuring.push(e.object)
  71. }else{
  72. let index = this.measuring.indexOf(e.object)
  73. index > -1 && this.measuring.splice(index, 1)
  74. }
  75. if(this.measuring.length == 0 && this.measuring.length>0 ){
  76. this.viewer.viewports.forEach((viewport)=>{
  77. this.collectClosePoints(viewport, true )//forceUpdate
  78. })
  79. }
  80. //console.log('measuring',e.v, e.cause, e.situation, this.measuring.length )
  81. })
  82. }
  83. window.viewer.addEventListener('loopStart',()=>{
  84. this.interactHistory = {} //清空
  85. })
  86. }
  87. /* addInputListener (listener) {
  88. this.inputListeners.push(listener);
  89. }
  90. removeInputListener (listener) {
  91. this.inputListeners = this.inputListeners.filter(e => e !== listener);
  92. }
  93. getSortedListeners(){
  94. return this.inputListeners.sort( (a, b) => {
  95. let ia = (a.importance !== undefined) ? a.importance : 0;
  96. let ib = (b.importance !== undefined) ? b.importance : 0;
  97. return ib - ia;
  98. });
  99. } */
  100. //统一跟第一个触碰的viewport相同
  101. updateTouchesInfo(e){
  102. var viewport, pointer, camera
  103. let oldTouches = this.touches
  104. let changedTouches = Array.from(e.changedTouches)
  105. let touches = Array.from(e.touches)
  106. this.touches = touches.map(touch=>{
  107. let touch_ = oldTouches.find(a=>a.touch.identifier == touch.identifier)
  108. let pointer = touch_ && touch_.pointer //复制原先的值
  109. return {
  110. touch, pointer,
  111. }
  112. })
  113. if(e.touches.length > 0){
  114. let newTouches = touches.filter(e=>!
  115. oldTouches.some(a=>a.touch.identifier == e.identifier) && !changedTouches.some(a=>a.identifier == e.identifier)
  116. ) //从按钮处划过时e.touches中会出现this.touches和changedTouches中都没有的identifier
  117. if(newTouches.length>0){
  118. console.warn('has new',newTouches.map(e=>e.identifier))
  119. }
  120. newTouches.concat(changedTouches).forEach(touch=>{ //修改changedTouches的
  121. let touch_ = this.touches.find(a=>a.touch.identifier == touch.identifier)
  122. if(touch_){
  123. let a = this.getPointerInViewport(touch.pageX, touch.pageY, this.dragViewport||viewport, new THREE.Vector2)
  124. touch_.pointer = a.pointer.clone()
  125. viewport = a.viewport; camera = a.camera
  126. }
  127. })
  128. //使用当前touches的平均
  129. if(e.touches.length > 1){
  130. let pageX = Common.average(e.touches, "pageX")
  131. let pageY = Common.average(e.touches, "pageY")
  132. let a = this.getPointerInViewport(pageX, pageY, viewport, new THREE.Vector2)
  133. this.pointer.copy(a.pointer)
  134. //console.log('updateTouchesInfo', this.pointer.clone())
  135. }else{
  136. this.pointer = this.touches[0].pointer.clone() //更新,使用当前touches中的第一个
  137. }
  138. /* if(this.touches.find(e=>!e.pointer)){
  139. console.error(' touches has no pointer', oldTouches.map(e=>e.touch.identifier),
  140. Array.from(e.touches).map(e=>e.identifier), Array.from(e.changedTouches).map(e=>e.identifier) )
  141. } */
  142. //console.log(this.touches)
  143. //console.log('更新pointer1',this.pointer.toArray())
  144. return {viewport, camera/* , pointer:this.pointer */}
  145. }
  146. }
  147. onTouchStart (e) {
  148. if (this.logMessages) console.log(this.constructor.name + ': onTouchStart',this.getTouchInfo(e));
  149. e.preventDefault();
  150. /* if (e.touches.length === 1 || !this.drag) { //!this.drag代表一次性下了两个指头
  151. let rect = this.domElement.getBoundingClientRect();
  152. let x = e.touches[0].pageX
  153. let y = e.touches[0].pageY
  154. this.dealPointerDown(x,y,e,true)
  155. }else{
  156. this.updateTouchesInfo(e)
  157. this.drag.end.copy(this.pointer)
  158. } */
  159. this.dealPointerDown(e,true)
  160. this.viewer.dispatchEvent($.extend(
  161. this.getEventDesc(e,true),
  162. {
  163. type: 'global_' + e.type,
  164. changedTouches: e.changedTouches
  165. }
  166. ));
  167. /* console.log('targetTouches :', Array.from(e.targetTouches).map(e=>'| identifier: '+ e.identifier),
  168. 'changedTouches :', Array.from(e.changedTouches).map(e=>'| identifier: '+ e.identifier)
  169. ) */
  170. //console.log('')
  171. }
  172. /* getTouchInfo(e){
  173. let t = e.targetTouches[0]
  174. return {clientX: t.clientX, clientY:t.clientY, pageX:t.pageX, pageY:t.pageY }
  175. } */
  176. onTouchMove (e) {
  177. if (this.logMessages) console.log(this.constructor.name + ': onTouchMove', this.getTouchInfo(e));
  178. e.preventDefault();
  179. /* if (e.touches.length === 1) {
  180. let rect = this.domElement.getBoundingClientRect();
  181. let x = e.touches[0].pageX;
  182. let y = e.touches[0].pageY;
  183. }else{
  184. this.updateTouchesInfo(e)
  185. this.drag.pointerDelta.subVectors(this.pointer, this.drag.end)
  186. this.drag.end.copy(this.pointer)
  187. }
  188. */
  189. this.dealPointerMove(e, true)
  190. this.viewer.dispatchEvent($.extend(
  191. this.getEventDesc(e,true),
  192. {
  193. type: 'global_' + e.type,
  194. changedTouches: e.changedTouches
  195. }
  196. ));
  197. /* console.log('targetTouches :', Array.from(e.targetTouches).map(e=>'| identifier: '+ e.identifier),
  198. 'changedTouches :', Array.from(e.changedTouches).map(e=>'| identifier: '+ e.identifier)
  199. ) */
  200. }
  201. onTouchEnd (e) {
  202. if (this.logMessages) console.log(this.constructor.name + ': onTouchEnd');
  203. e.preventDefault();
  204. //console.log('onTouchEnd')
  205. this.updateTouchesInfo(e)
  206. /* if (e.touches.length === 0) {
  207. let rect = this.domElement.getBoundingClientRect();
  208. let x = e.changedTouches[0].pageX //万一一次松开两个指头的怎么办
  209. let y = e.changedTouches[0].pageY
  210. this.dealPointerUp(x,y,e,true)
  211. }else {
  212. this.drag.end.copy(this.pointer)
  213. } */
  214. this.dealPointerUp(e,true)
  215. this.viewer.dispatchEvent($.extend(
  216. this.getEventDesc(e,true),
  217. {
  218. type: 'global_' + e.type,
  219. }
  220. ));
  221. //console.log('touchend length '+e.touches.length, this.touches.length)
  222. }
  223. onKeyDown (e) {
  224. if (this.logMessages) console.log(this.constructor.name + ': onKeyDown');
  225. // DELETE
  226. /* if (e.keyCode === KeyCodes.DELETE && this.selection.length > 0) {
  227. this.dispatchEvent({
  228. type: 'delete',
  229. selection: this.selection
  230. });
  231. this.deselectAll();
  232. } */
  233. this.dispatchEvent({
  234. type: 'keydown',
  235. keyCode: e.keyCode,
  236. event: e
  237. });
  238. // for(let l of this.getSortedListeners()){
  239. // l.dispatchEvent({
  240. // type: "keydown",
  241. // keyCode: e.keyCode,
  242. // event: e
  243. // });
  244. // }
  245. this.pressedKeys[e.keyCode] = true;
  246. // e.preventDefault();
  247. }
  248. onKeyUp (e) {
  249. if (this.logMessages) console.log(this.constructor.name + ': onKeyUp');
  250. if(e.keyCode != void 0){
  251. delete this.pressedKeys[e.keyCode];
  252. }else{
  253. this.pressedKeys = {}
  254. }
  255. e.preventDefault();
  256. }
  257. onDoubleClick (e) {
  258. if (this.logMessages) console.log(this.constructor.name + ': onDoubleClick');
  259. let consumed = false;
  260. for (let hovered of this.hoveredElements) {
  261. if (hovered._listeners && hovered._listeners['dblclick']) {
  262. hovered.object.dispatchEvent({
  263. type: 'dblclick',
  264. mouse: this.mouse,
  265. object: hovered.object
  266. });
  267. consumed = true;
  268. break;
  269. }
  270. }
  271. if (!consumed) {
  272. /* for (let inputListener of this.getSortedListeners()) {
  273. inputListener. */this.viewer.dispatchEvent({
  274. type: 'global_dblclick',
  275. mouse: this.mouse,
  276. object: null
  277. });
  278. //}
  279. }
  280. this.needSingleClick = false//add
  281. e.preventDefault();
  282. }
  283. onMouseClick (e) {
  284. if (this.logMessages) console.log(this.constructor.name + ': onMouseClick');
  285. e.preventDefault();
  286. }
  287. dealPointerDown(e,isTouch){
  288. e.preventDefault();
  289. //重新获取一下pointer, 因点击了浏览器的按钮展开列表时 move回来不会触发onmousemove,所以pointer是旧的
  290. if(isTouch){
  291. var { camera, viewport } = this.updateTouchesInfo(e)
  292. if(this.drag){
  293. //因为触屏在按下前缺少pointermove所以要更新下
  294. this.drag.end = this.pointer.clone()
  295. }
  296. }else{
  297. var { camera, viewport } = this.getPointerInViewport(e.clientX, e.clientY )
  298. }
  299. this.dragViewport = this.hoverViewport = viewport
  300. //if(isTouch || !Potree.settings.intersectWhenHover ){
  301. if(isTouch || !this.dragViewport.view.isFlying()){
  302. this.hoveredElements = this.getHoveredElements();
  303. this.intersect = this.getIntersect({viewport, clientX:e.clientX, clientY:e.clientY}) //更新intersect,避免在没有mousemove但flyToPano后intersect未更新。
  304. //this.intersect = this.getWholeIntersect()
  305. } //isTouch必须更新 否则是旧的
  306. if(!viewport)return //why add this?
  307. if (!this.drag) {
  308. let target = (isTouch||e.button == THREE.MOUSE.LEFT) && this.hoveredElements.find(el => (//只有左键能拖拽
  309. el.object._listeners &&
  310. el.object._listeners['drag'] &&
  311. el.object._listeners['drag'].length > 0));
  312. if (target) {
  313. this.startDragging(target.object, {location: target.point});
  314. } else {
  315. this.startDragging(null);
  316. }
  317. }
  318. this.drag.intersectStart = this.intersect;
  319. if(!isTouch || e.touches.length == 1){
  320. let consumed = false;
  321. let consume = () => { return consumed = true; };
  322. //if (this.hoveredElements.length === 0) {
  323. this.viewer.dispatchEvent($.extend(
  324. this.getEventDesc(e,isTouch),
  325. {
  326. type: 'global_mousedown'
  327. }
  328. ));
  329. for(let hovered of this.hoveredElements){
  330. let object = hovered.object;
  331. object.dispatchEvent({
  332. type: 'mousedown',
  333. viewer: this.viewer,
  334. consume: consume
  335. });
  336. if(consumed){
  337. break;
  338. }
  339. }
  340. }
  341. this.mouseDownMouse = this.mouse.clone()
  342. this.pointerDownTime = Date.now()
  343. }
  344. onMouseDown (e) {
  345. if (this.logMessages) console.log(this.constructor.name + ': onMouseDown');
  346. this.dealPointerDown(e)
  347. }
  348. /* getWholeIntersect(hoveredElements, intersectPoint){//add
  349. hoveredElements = hoveredElements || this.hoveredElements
  350. intersectPoint = intersectPoint || this.intersectPoint
  351. if(Potree.settings.intersectOnObjs && hoveredElements[0] && hoveredElements[0].object.isModel){
  352. return {//模拟点云的intersectPoint的结构写法
  353. hoveredElement : hoveredElements[0] ,
  354. location: hoveredElements[0].point,
  355. point: {normal: hoveredElements[0].face.normal },
  356. distance: hoveredElements[0].distance,
  357. object: hoveredElements[0].object
  358. }
  359. }else return intersectPoint
  360. } */
  361. getEventDesc(e,isTouch){//搜集dispatchEvent要给的一般数据
  362. let o = {
  363. viewer: this.viewer,
  364. mouse: this.mouse,
  365. pointer:this.pointer,
  366. drag :this.drag,
  367. isTouch,
  368. dragViewport : this.dragViewport,
  369. hoverViewport: this.hoverViewport,
  370. // button: isTouch ? 0 : e.button,
  371. //intersectPoint:this.intersectPoint,
  372. hoveredElement: this.hoveredElements[0],
  373. intersect: this.intersect//this.getWholeIntersect() , //可能包含mesh上的,针对融合页面
  374. }
  375. if(e){
  376. o.isAtDomElement = e.target == this.domElement
  377. }
  378. if(isTouch){
  379. o.touches = this.touches
  380. }else if(e){
  381. o.button = e.button
  382. o.buttons = e.buttons
  383. }
  384. return o;
  385. }
  386. dealPointerUp(e,isTouch){
  387. if(!this.drag){// 在canvas外mousedown
  388. return
  389. }
  390. this.drag.end.copy(this.pointer)
  391. if(isTouch && e.touches.length >= 1){
  392. return
  393. }
  394. let now = Date.now()
  395. if (this.logMessages) console.log(this.constructor.name + ': onMouseUp');
  396. e.preventDefault();
  397. let pressDistance = this.mouseDownMouse.distanceTo(this.mouse);
  398. let pressTime = now - this.pointerDownTime;
  399. let noMovement = this.drag.pointerDelta.length() == 0//this.getNormalizedDrag().length() === 0;
  400. let consumed = false;
  401. let consume = () => { return consumed = true; };
  402. //if (this.hoveredElements.length === 0) {
  403. /* for (let inputListener of this.getSortedListeners()) {
  404. inputListener */this.viewer.dispatchEvent($.extend(
  405. this.getEventDesc(e,isTouch),
  406. {
  407. type: 'global_mouseup',
  408. pressDistance,
  409. consume,
  410. }
  411. ));
  412. /* if(consumed){//??
  413. break;
  414. } */
  415. //}
  416. //}
  417. if (this.hoveredElements.length > 0) {
  418. let hovered = this.hoveredElements
  419. .map(e => e.object)
  420. .find(e => (e._listeners && e._listeners['mouseup']));
  421. if(hovered){
  422. hovered.dispatchEvent({
  423. type: 'mouseup',
  424. viewer: this.viewer,
  425. consume: consume
  426. });
  427. }
  428. }
  429. if (this.drag) {
  430. //拖拽结束
  431. if (this.drag.object/* && e.button == THREE.MOUSE.LEFT */) {//add LEFT
  432. if (this.logMessages) console.log(`${this.constructor.name}: drop ${this.drag.object.name}`);
  433. this.drag.object.dispatchEvent($.extend(
  434. this.getEventDesc(e,isTouch),
  435. {
  436. type: 'drop',
  437. pressDistance,
  438. pressTime
  439. }
  440. ));
  441. } else {
  442. this.viewer.dispatchEvent($.extend(
  443. this.getEventDesc(e,isTouch),
  444. {
  445. type: 'global_drop',
  446. pressDistance
  447. }
  448. ));
  449. }
  450. // check for a click
  451. if(pressDistance < Potree.config.clickMaxDragDis && pressTime<Potree.config.clickMaxPressTime && !e.unableClick){
  452. let clickElement, consumed = false;
  453. if(this.hoveredElements){
  454. clickElement = this.hoveredElements.find(e=>e.object._listeners['click'])
  455. if(clickElement){
  456. //console.log('clickElement',clickElement)
  457. if (this.logMessages) console.log(`${this.constructor.name}: click ${clickElement.name}`);
  458. clickElement.object.dispatchEvent($.extend(
  459. this.getEventDesc(e,isTouch),
  460. {
  461. type: 'click',
  462. pressDistance
  463. }
  464. ));
  465. }
  466. }
  467. let selectable
  468. if(/* !consumed && */ !this.fixSelection){
  469. if (e.button === THREE.MOUSE.LEFT) {
  470. if (noMovement) {
  471. selectable = this.hoveredElements.find(el => el.object._listeners && el.object._listeners['select']);
  472. if (selectable) {
  473. selectable = selectable.object;
  474. if (this.isSelected(selectable)) {
  475. this.deselectAll();
  476. } else {
  477. this.deselectAll();
  478. this.toggleSelection(selectable);
  479. }
  480. consumed = true //add
  481. } else {
  482. if(this.selection.length>0)consumed = true //add 取消选择后,阻断后续
  483. this.deselectAll();
  484. }
  485. }
  486. } else if ((e.button === THREE.MOUSE.RIGHT) && noMovement) {
  487. this.deselectAll();
  488. }
  489. }
  490. let consume = () => { return consumed = true; };
  491. let desc = this.getEventDesc(e,isTouch)
  492. if(!consumed){
  493. this.viewer.dispatchEvent($.extend(
  494. desc,
  495. {
  496. type: 'global_click',
  497. pressDistance,
  498. clickElement:clickElement/* || selectable */,
  499. consume
  500. }
  501. ));
  502. }
  503. //增加 单击:
  504. this.needSingleClick = true;
  505. consumed || setTimeout(()=>{
  506. if(this.needSingleClick){
  507. this.viewer.dispatchEvent($.extend(
  508. desc,
  509. {
  510. type: 'global_single_click',
  511. pressDistance,
  512. clickElement
  513. }
  514. ));
  515. }
  516. }, Potree.config.doubleClickTime+1)
  517. //自行执行双击:
  518. if(now - this.lastClickTime < Potree.config.doubleClickTime){
  519. this.onDoubleClick(e)
  520. }
  521. this.lastClickTime = now
  522. }
  523. this.drag = null;
  524. }
  525. this.dragViewport = null
  526. }
  527. onMouseUp (e) {
  528. this.dealPointerUp( e )
  529. }
  530. getPointerInViewport(clientX, clientY, viewForceAt, pointer ){
  531. let rect = this.domElement.getBoundingClientRect();
  532. let x = clientX - rect.left;
  533. let y = clientY - rect.top;
  534. let camera
  535. let viewport
  536. pointer = pointer ||this.pointer
  537. //if(this.viewer.viewports || viewForceAt){
  538. var getDimension = (view)=>{
  539. var left = Math.ceil(this.domElement.clientWidth * view.left)
  540. , bottom = Math.ceil(this.domElement.clientHeight * view.bottom)
  541. , width = Math.ceil(this.domElement.clientWidth * view.width)
  542. , height = Math.ceil(this.domElement.clientHeight * view.height)
  543. , top = this.domElement.clientHeight - bottom - height
  544. return {left, bottom, width, height, top}
  545. }
  546. var getView = (view, left, bottom, width, height, top)=>{
  547. this.mouse.set(x-left, y - top )
  548. Utils.convertScreenPositionToNDC(pointer, this.mouse, width, height);
  549. //console.log('更新pointer2',this.pointer.toArray())
  550. camera = view.camera;
  551. viewport = view
  552. }
  553. if(viewForceAt){
  554. let {left, bottom, width, height, top} = getDimension(viewForceAt)
  555. getView(viewForceAt, left, bottom, width, height, top)
  556. }else{
  557. var length = this.viewer.viewports.length;
  558. //var getif = false
  559. for(var i=0;i<length;i++){
  560. var view = this.viewer.viewports[i];
  561. if(!view.active)continue
  562. var {left, bottom, width, height, top} = getDimension(view)
  563. if(x >= left && x <= left + width && y >= top && y <= top + height){
  564. getView(view, left, bottom, width, height, top)
  565. //getif = true
  566. break;
  567. }
  568. }
  569. }
  570. return {
  571. camera, viewport, pointer
  572. }
  573. }
  574. ifBlockedByIntersect({point, margin=0, cameraPos, pickWindowSize, pano, useDepthTex, viewport}={}){//某点是否被遮挡(不允许camera修改位置, 因为depthTex不好置换)
  575. viewport = viewport || this.hoverViewport || viewer.mainViewport
  576. let intersect = this.getIntersect({viewport, onlyGetIntersect:true, pickWindowSize, useDepthTex, point, cameraPos, pano })
  577. let cameraPos_ = (!cameraPos && pano) ? pano.position : (cameraPos||viewport.view.position)
  578. if(intersect && intersect.distance+margin <= point.distanceTo(cameraPos_)){
  579. return intersect //被遮挡
  580. }
  581. //点云模式,对没加载出的点云不准确。 尤其是需要修改相机位置时,因临时修改并不能使点云加载。
  582. }
  583. collectClosePoints(viewport, forceUpdate){//获取吸附点
  584. if(!Potree.settings.adsorption)return
  585. let point2ds = []
  586. //吸附测量线端点
  587. viewer.scene.measurements.forEach(e=>{
  588. if(this.measuring.includes(e)) return//不吸附到正在拖拽的自身
  589. point2ds.push(...e.getPointsPos2d(viewport, forceUpdate))
  590. })
  591. viewer.fixPoints.forEach(e=>{
  592. point2ds.push(e.pos2d)
  593. })
  594. return point2ds
  595. }
  596. getIntersect({viewport, onlyGetIntersect, pickWindowSize, dontIntersect, usePointcloud, useDepthTex, cameraPos, point, pano, clientX, clientY}={}){// usePointcloud:必须使用点云
  597. let intersect, intersectPoint, intersectOnModel, allElements
  598. let camera = viewport.camera
  599. let raycaster
  600. viewer.addTimeMark('getIntersect','start')
  601. let getByDepthTex = ()=>{
  602. let intersect
  603. if(point){
  604. let cameraPos = pano ? pano.position : camera.position
  605. let dir = new THREE.Vector3().subVectors(point, cameraPos).normalize();
  606. intersect = {dir}
  607. }else{
  608. intersect = Utils.getIntersect(camera, [viewer.images360.cube], this.pointer, raycaster)
  609. }
  610. intersectPoint = viewer.images360.depthSampler.sample(intersect, pano, !!point) //可能不准确, 因pano可能未加载depthTex
  611. if(intersectPoint && Potree.settings.depTexLocBindDataset){
  612. intersectPoint.pointcloud = ( pano || viewer.images360.currentPano).pointcloud
  613. //在全景模式下,虽然深度图上的点可能对应别的pointcloud,但因为是在当前全景图处得到的,所以即使将原本对应的点云移走,该点也不移动是有道理的。它可以永远跟着该全景图。
  614. }
  615. }
  616. let getByCloud = ()=>{
  617. let pointer, mouse
  618. if(point){//指定了目标点,而非只是用pointer所在位置
  619. cameraPos && camera.position.copy( cameraPos)
  620. camera.lookAt(point)
  621. camera.updateMatrixWorld()
  622. pointer = this.pointer.clone()
  623. mouse = this.mouse.clone()
  624. this.pointer.set(0,0) //画布中心
  625. this.mouse.set(Math.round(viewport.resolution.x/2), Math.round(viewport.resolution.y/2))
  626. }
  627. intersectPoint = (viewport.noPointcloud || dontIntersect)? null : Utils.getMousePointCloudIntersection(
  628. viewport,
  629. this.mouse,
  630. this.pointer,
  631. camera,
  632. this.viewer,
  633. this.viewer.scene.pointclouds,
  634. {pickClipped: true, isMeasuring: this.measuring.length>0, pickWindowSize, cameraChanged: !!point }
  635. );
  636. //恢复
  637. if(point){
  638. viewport.view.applyToCamera(camera)
  639. this.pointer.copy(pointer)
  640. this.mouse.copy(mouse)
  641. }
  642. }
  643. if(this.measuring.length && Potree.settings.adsorption ){//吸附
  644. let points = this.collectClosePoints(viewport)
  645. let points2 = points.filter(e=>e.trueSide && e.inSight
  646. && math.closeTo(this.mouse, e.posInViewport, Potree.config.measure.adsorptMinDis)
  647. )
  648. let disArr = points2.map(e=> e.pos.distanceToSquared(this.mouse) )
  649. let min = points2.slice().sort((a,b)=>disArr[points.indexOf(a)] - disArr[points.indexOf(b)])
  650. if(min[0]){
  651. intersect = {
  652. //hoveredElement
  653. location: min[0].pos3d,
  654. //point: {normal: allElements[0].face.normal },
  655. //normal
  656. //distance
  657. object: min[0].object,
  658. adsorption:true
  659. }
  660. //console.log('找到吸附点', min[0].pos3d, min[0].object.uuid)
  661. }
  662. viewer.dispatchEvent({
  663. type:'findAdsorption',
  664. intersect
  665. })
  666. }
  667. if(!intersect){
  668. let canUseDepthTex = !Potree.settings.unableUseDepTexPick && (Potree.settings.displayMode == 'showPanos' || useDepthTex)
  669. && viewer.images360.currentPano.pointcloud.hasDepthTex && viewport == viewer.mainViewport && !usePointcloud
  670. //交通的深度图不准,先只用在reticule上
  671. if(canUseDepthTex && this.measuring.length == 0){
  672. getByDepthTex()
  673. }else{
  674. getByCloud()
  675. }
  676. //console.log(viewport.name , intersectPoint && intersectPoint.location )
  677. if(Potree.settings.intersectOnObjs && !dontIntersect){
  678. if(point){
  679. raycaster = new THREE.Raycaster()
  680. var dir = new THREE.Vector3().subVectors(point, camera.position).normalize()
  681. raycaster.set(camera.position, dir) //var origin = new THREE.Vector3(pointer.x, pointer.y, -1).unproject(camera),
  682. }
  683. allElements = this.getHoveredElements(viewer.objs.children, true, raycaster)
  684. if(allElements[0]){
  685. intersectOnModel = {//模拟点云的intersectPoint的结构写法
  686. hoveredElement : allElements[0] ,
  687. location: allElements[0].point,
  688. //point: {normal: allElements[0].face.normal },
  689. normal: allElements[0].face && allElements[0].face.normal,
  690. distance: allElements[0].distance,
  691. object: allElements[0].object
  692. }
  693. }
  694. }
  695. if(intersectPoint && intersectOnModel){
  696. if(intersectPoint.distance < intersectOnModel.distance){
  697. intersect = intersectPoint
  698. }else{
  699. intersect = intersectOnModel
  700. }
  701. }else{
  702. intersect = intersectOnModel || intersectPoint
  703. }
  704. }
  705. if(viewport.camera.type == 'OrthographicCamera'/* == 'mapViewport' */){
  706. let pos3d = new THREE.Vector3(this.pointer.x,this.pointer.y,-1).unproject(viewport.camera); //z:-1朝外
  707. if(!intersect){
  708. intersect = {}
  709. }
  710. intersect.orthoIntersect = pos3d.clone()
  711. }
  712. //记录全部hover到的:
  713. if(intersect){
  714. intersect.allElements = allElements
  715. intersect.pointclouds = intersectPoint ? intersectPoint.pointclouds : []
  716. }
  717. viewer.addTimeMark('getIntersect','end')
  718. //点云费时:2-15ms
  719. //深度图费时: 0.1-0.2ms
  720. this.viewer.dispatchEvent({type:'getIntersect', intersect})
  721. if(onlyGetIntersect){
  722. return intersect
  723. }
  724. if (intersect) {
  725. if(viewer.showCoordType){ //显示坐标位置时
  726. let pos = intersect.point.position.toArray()
  727. if(viewer.showCoordType == "local"){
  728. }else if(viewer.showCoordType == "lonlat"){
  729. pos = viewer.transform.lonlatToLocal.inverse(pos)
  730. }else{
  731. pos = viewer.transform.lonlatToLocal.inverse(pos)
  732. pos = viewer.transform.lonlatTo4550.forward(pos)
  733. }
  734. viewer.dispatchEvent({
  735. type : "coordinateChange", pos
  736. })
  737. }
  738. }
  739. //console.log('getIntersect', !!intersectPoint)
  740. this.intersect = intersect
  741. intersect && (this.hoverViewport.lastIntersect = intersect)
  742. return intersect
  743. }
  744. onMouseMove (e) {
  745. return this.dealPointerMove( e )
  746. }
  747. dealPointerMove(e, isTouch){
  748. if(this.interactHistory.move) return //一帧只触发一次
  749. this.interactHistory.move = 1
  750. if(isTouch){
  751. var { camera, viewport } = this.updateTouchesInfo(e)
  752. }else {
  753. var { camera, viewport } = this.getPointerInViewport(e.clientX, e.clientY, this.dragViewport)
  754. }
  755. this.hoverViewport = viewport
  756. if(!viewport)return//刚变化viewport时会找不到
  757. let isFlying = this.viewer.viewports.some(e=>e.view.isFlying()) || viewer.scene.cameraAnimations.some(c=>c.onUpdate)
  758. let intersect
  759. if(e.onlyGetIntersect || Potree.settings.intersectWhenHover && (!this.drag || this.drag.object || viewport.alignment ) ){ //没有拖拽物体,但按下鼠标了的话,不intersect。触屏的就能直接避免intersect
  760. let dontIntersect = this.drag && viewport.alignment || isFlying /* viewer.images360.flying */ // flying 时可能卡顿
  761. //console.log('dontIntersectPointcloud',dontIntersectPointcloud)
  762. intersect = this.getIntersect(Object.assign({}, e, {viewport, dontIntersect, clientX:e.clientX, clientY:e.clientY })) //数据集多的时候卡顿
  763. //console.log('intersectPoint', intersectPoint)
  764. }
  765. if(e.onlyGetIntersect){
  766. return intersect
  767. }
  768. e.preventDefault();
  769. if (this.drag) {//有拖拽(不一定拖拽了物体, 也不一定按下了鼠标)
  770. this.drag.mouse = isTouch ? 1 : e.buttons;
  771. //add:
  772. //this.drag.pointer = this.pointer.clone();
  773. //this.drag.hoverViewport = this.hoverViewport
  774. this.drag.pointerDelta.subVectors(this.pointer, this.drag.end)
  775. this.drag.end.copy(this.pointer)
  776. if (this.drag.object && (e.buttons == Buttons.NONE || !this.drag.notPressMouse )){//如果是本不需要按鼠标的拖拽,但按下了鼠标,就不执行这段(改为拖拽场景,如添加测量时突然拖拽画面)
  777. if (this.logMessages) console.log(this.constructor.name + ': drag: ' + this.drag.object.name);
  778. this.drag.object.dispatchEvent($.extend(
  779. this.getEventDesc(e,isTouch),
  780. {
  781. type: 'drag', //拖拽物体
  782. }
  783. ))
  784. viewer.dispatchEvent('content_changed')
  785. } else {
  786. if (this.logMessages) console.log(this.constructor.name + ': drag: ');
  787. let dragConsumed = false;
  788. this.viewer.dispatchEvent($.extend(
  789. this.getEventDesc(e,isTouch),
  790. {
  791. type: 'global_drag', //拖拽画面
  792. consume: () => {dragConsumed = true;}
  793. }
  794. ))
  795. }
  796. }
  797. if(!isTouch || e.touches.length == 1){
  798. if((!this.drag || this.drag.notPressMouse || Potree.settings.intersectOnObjs && this.drag.object) && !isFlying){
  799. /* let blacklist = this.drag && this.drag */
  800. let hoveredElements = this.getHoveredElements( );
  801. if(hoveredElements.length > 0){
  802. let names = hoveredElements.map(h => h.object.name).join(", ");
  803. if (this.logMessages) console.log(`${this.constructor.name}: onMouseMove; hovered: '${names}'`);
  804. }
  805. let curr = hoveredElements.map(a => a.object).find(a => true);//只取第一个
  806. let prev = this.lastMouseoverElement //this.hoveredElements.map(a => a.object).find(a => true);
  807. if(curr !== prev){
  808. if(curr){
  809. if (this.logMessages) console.log(`${this.constructor.name}: mouseover: ${curr.name}`);
  810. curr.dispatchEvent({
  811. type: 'mouseover',
  812. object: curr,
  813. });
  814. }
  815. if(prev){
  816. if (this.logMessages) console.log(`${this.constructor.name}: mouseleave: ${prev.name}`);
  817. prev.dispatchEvent({
  818. type: 'mouseleave',
  819. object: prev,
  820. });
  821. }
  822. this.lastMouseoverElement = curr
  823. viewer.dispatchEvent('content_changed')
  824. }
  825. if(hoveredElements.length > 0){
  826. let object = hoveredElements
  827. .map(e => e.object)
  828. .find(e => (e._listeners && e._listeners['mousemove']));
  829. if(object){
  830. object.dispatchEvent({
  831. type: 'mousemove',
  832. object: object
  833. });
  834. }
  835. }
  836. this.hoveredElements = hoveredElements
  837. }
  838. //this.intersect = this.getWholeIntersect()
  839. this.viewer.dispatchEvent($.extend(
  840. this.getEventDesc(e,isTouch),
  841. {
  842. type: 'global_mousemove',
  843. }
  844. ))
  845. }
  846. }
  847. onMouseWheel(e){
  848. if(!this.enabled) return;
  849. if(this.logMessages) console.log(this.constructor.name + ": onMouseWheel");
  850. e.preventDefault();
  851. let delta = 0;
  852. if (e.wheelDelta !== undefined) { // WebKit / Opera / Explorer 9
  853. delta = e.wheelDelta;
  854. } else if (e.detail !== undefined) { // Firefox
  855. delta = -e.detail;
  856. }
  857. let ndelta = Math.sign(delta);
  858. // this.wheelDelta += Math.sign(delta);
  859. if(!this.hoverViewport){//调试手机版时会无
  860. var { viewport } = this.getPointerInViewport(e.clientX, e.clientY )
  861. this.hoverViewport = viewport
  862. }
  863. if (this.hoveredElement) {
  864. this.hoveredElement.object.dispatchEvent($.extend(
  865. this.getEventDesc(e,isTouch),
  866. {
  867. type: 'mousewheel',
  868. delta: ndelta,
  869. object: this.hoveredElement.object
  870. }
  871. ));
  872. } else {
  873. this.viewer.dispatchEvent($.extend(
  874. this.getEventDesc(e),
  875. {
  876. type: 'global_mousewheel',
  877. delta: ndelta,
  878. }
  879. ));
  880. }
  881. setTimeout(()=>{
  882. this.dealPointerMove(e )//add 在更新完view后重新获取intersect 和 drag
  883. },1)//只延迟1会崩溃吗
  884. }
  885. startDragging (object, args = null) {
  886. let name = object ? object.name : "no name";
  887. if (this.logMessages) console.log(`${this.constructor.name}: startDragging: '${name}'`);
  888. this.drag = {
  889. start: this.pointer.clone(),
  890. end: this.pointer.clone(),
  891. pointerDelta: new THREE.Vector2(0, 0),
  892. object: object,
  893. hoverViewport: this.hoverViewport, //会变化
  894. dragViewport: this.hoverViewport, //不变
  895. };
  896. if (args) {
  897. for (let key of Object.keys(args)) {
  898. this.drag[key] = args[key];
  899. }
  900. }
  901. if(object){
  902. object.dispatchEvent($.extend(
  903. this.getEventDesc(),
  904. {
  905. type: 'startDragging'
  906. }
  907. ));
  908. }
  909. }
  910. /* getMousePointCloudIntersection (mouse) {
  911. return Utils.getMousePointCloudIntersection(
  912. this.mouse,
  913. this.scene.getActiveCamera(),
  914. this.viewer,
  915. this.scene.pointclouds);
  916. } */
  917. toggleSelection (object) {
  918. let oldSelection = this.selection;
  919. let index = this.selection.indexOf(object);
  920. if (index === -1) {
  921. this.selection.push(object);
  922. object.dispatchEvent({
  923. type: 'select'
  924. });
  925. } else {
  926. this.selection.splice(index, 1);
  927. object.dispatchEvent({
  928. type: 'deselect'
  929. });
  930. }
  931. this.dispatchEvent({
  932. type: 'selection_changed',
  933. oldSelection: oldSelection,
  934. selection: this.selection
  935. });
  936. viewer.dispatchEvent('content_changed')
  937. }
  938. deselect(object){
  939. let oldSelection = this.selection;
  940. let index = this.selection.indexOf(object);
  941. if(index >= 0){
  942. this.selection.splice(index, 1);
  943. object.dispatchEvent({
  944. type: 'deselect'
  945. });
  946. this.dispatchEvent({
  947. type: 'selection_changed',
  948. oldSelection: oldSelection,
  949. selection: this.selection
  950. });
  951. }
  952. viewer.dispatchEvent('content_changed')
  953. }
  954. deselectAll () {
  955. for (let object of this.selection) {
  956. object.dispatchEvent({
  957. type: 'deselect'
  958. });
  959. }
  960. let oldSelection = this.selection;
  961. if (this.selection.length > 0) {
  962. this.selection = [];
  963. this.dispatchEvent({
  964. type: 'selection_changed',
  965. oldSelection: oldSelection,
  966. selection: this.selection
  967. });
  968. }
  969. viewer.dispatchEvent('content_changed')
  970. }
  971. isSelected (object) {
  972. let index = this.selection.indexOf(object);
  973. return index !== -1;
  974. }
  975. registerInteractiveObject(object){
  976. this.interactiveObjects.add(object);
  977. }
  978. removeInteractiveObject(object){
  979. this.interactiveObjects.delete(object);
  980. }
  981. registerInteractiveScene (scene) {
  982. let index = this.interactiveScenes.indexOf(scene);
  983. if (index === -1) {
  984. this.interactiveScenes.push(scene);
  985. }
  986. }
  987. unregisterInteractiveScene (scene) {
  988. let index = this.interactiveScenes.indexOf(scene);
  989. if (index > -1) {
  990. this.interactiveScenes.splice(index, 1);
  991. }
  992. }
  993. getHoveredElement () {
  994. let hoveredElements = this.getHoveredElements();
  995. if (hoveredElements.length > 0) {
  996. return hoveredElements[0];
  997. } else {
  998. return null;
  999. }
  1000. }
  1001. getHoveredElements (interactables, dontCheckDis, raycaster) {
  1002. if(!interactables){
  1003. let scenes = this.hoverViewport.interactiveScenes || this.interactiveScenes.concat(this.scene);
  1004. let interactableListeners = ['mouseup', 'mousemove', 'mouseover', 'mouseleave', 'drag', 'drop', 'click', 'select', 'deselect'];
  1005. interactables = []
  1006. for (let scene of scenes) {
  1007. scene.traverseVisible(node => {//检测加了侦听的object
  1008. if (node._listeners && node.visible && !this.blacklist.has(node) ) {
  1009. let hasInteractableListener = interactableListeners.filter((e) => {
  1010. return node._listeners[e] !== undefined;
  1011. }).length > 0;
  1012. if (hasInteractableListener) {
  1013. interactables.push(node);
  1014. }
  1015. }
  1016. });
  1017. }
  1018. }else interactables = interactables.filter(e=>e.visible)
  1019. let camera = this.hoverViewport.camera
  1020. if(!raycaster){
  1021. let ray = Utils.mouseToRay(this.pointer, camera );
  1022. raycaster = new THREE.Raycaster();
  1023. raycaster.ray.set(ray.origin, ray.direction);
  1024. raycaster.camera = camera //add
  1025. }
  1026. if(camera.type == "OrthographicCamera"){//使无论多远,threshold区域都是一样宽的
  1027. raycaster.params.Line.threshold = 20/camera.zoom
  1028. }else{
  1029. raycaster.params.Line.threshold = 0.04; //相对长度
  1030. }
  1031. raycaster.params.Line2 = {threshold : browser.isMobile()?100:20 } //拓宽的lineWidth
  1032. //raycaster.layers.enableAll()//add
  1033. Potree.Utils.setCameraLayers(raycaster, //设置能识别到的layers(如空间模型里只有mapViewer能识别到marker)
  1034. ['sceneObjects','mapObjects','measure', 'transformationTool', 'model'],
  1035. this.hoverViewport && this.hoverViewport.extraEnableLayers
  1036. )
  1037. //this.hoverViewport.beforeRender && this.hoverViewport.beforeRender()
  1038. viewer.dispatchEvent( {type:'raycaster', viewport: this.hoverViewport})//add
  1039. let intersections = raycaster.intersectObjects(interactables , true, null, true); //原本是false 检测不到children
  1040. let intersectionsCopy = intersections.slice()
  1041. if(this.intersect && this.intersect.distance != void 0 && !dontCheckDis){//add
  1042. intersections = intersections.filter(e=>{
  1043. let material = e.object.material
  1044. return e.object.pickDontCheckDis || ( material.depthTest == false || material.depthWrite == false) && !material.realUseDepth //!material.depthTestWhenPick
  1045. || ( material.useDepth ? e.distance < this.intersect.distance + material.uniforms.clipDistance.value : e.distance < this.intersect.distance )
  1046. })
  1047. }
  1048. intersections = intersections.map(e=>{//add 转化为interactables
  1049. var object = e.object;
  1050. do{
  1051. if(interactables.includes(object)) {
  1052. e.oriObject = e.object;
  1053. e.object = object;
  1054. break
  1055. }
  1056. object = object.parent
  1057. }while(object)
  1058. return e
  1059. })
  1060. //add for测量线,在检测到sphere时优先选中sphere而非线
  1061. //intersections = intersections.sort(function(a,b){return b.object.renderOrder-a.object.renderOrder}) // 降序
  1062. intersections = intersections.sort(function(a,b){
  1063. let order2 = b.object.pickOrder || 0
  1064. let order1 = a.object.pickOrder || 0
  1065. return order2-order1
  1066. }) // 降序
  1067. return intersections;
  1068. }
  1069. /* setScene (scene) {
  1070. this.deselectAll();
  1071. this.scene = scene;
  1072. } */
  1073. update (delta) {
  1074. }
  1075. /*getNormalizedDrag () {
  1076. if (!this.drag) {
  1077. return new THREE.Vector2(0, 0);
  1078. }
  1079. let diff = new THREE.Vector2().subVectors(this.drag.end, this.drag.start);
  1080. diff.x = diff.x / this.domElement.clientWidth;
  1081. diff.y = diff.y / this.domElement.clientHeight;
  1082. return diff;
  1083. }
  1084. getNormalizedLastDrag () {
  1085. if (!this.drag) {
  1086. return new THREE.Vector2(0, 0);
  1087. }
  1088. let mouseDelta = this.drag.mouseDelta.clone();
  1089. mouseDelta.x = mouseDelta.x / this.domElement.clientWidth;
  1090. mouseDelta.y = mouseDelta.y / this.domElement.clientHeight;
  1091. return mouseDelta;
  1092. } */
  1093. getMouseDirection(pointer) {//add
  1094. pointer = pointer || this.pointer
  1095. let camera = this.hoverViewport.camera
  1096. var t = new THREE.Vector3(pointer.x, pointer.y, -1).unproject(camera),
  1097. i = new THREE.Vector3(pointer.x, pointer.y, 1).unproject(camera);
  1098. return {origin: t, direction:i.clone().sub(t).normalize() }
  1099. }
  1100. }