index.js 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348
  1. import mitt from 'mitt'
  2. import axios from 'axios' //{ axios } from '@/api'
  3. let requestLoadCount = 0
  4. export const enter = ({ dom, mapDom, isLocal, lonlat, scenes }) => {
  5. console.warn('新的页面')
  6. Potree.settings.isOfficial = true //标记为正式、非测试版本
  7. //Potree.fileServer = axios
  8. Potree.settings.libsUrl = './lib/'
  9. //正式环境(本地调试会打不开)
  10. if (location.host === 'mix3d.4dkankan.com') {
  11. Potree.settings.urls.prefix = Potree.settings.urls.prefix6
  12. Potree.settings.webSite = 'datav1'
  13. } else if (location.host === 'xfhd.4dkankan.com') {
  14. Potree.settings.urls.prefix = Potree.settings.urls.prefix7
  15. Potree.settings.webSite = 'datav1'
  16. }
  17. const mapBus = mitt(), sceneBus = mitt()
  18. const tagLimitDis = 8;
  19. Potree.settings.showCompass = true
  20. Potree.settings.compassDom = dom.querySelector('#direction')
  21. Potree.settings.showObjectsOnMap = true
  22. Potree.settings.mergeType2 = true //标识新版
  23. Potree.settings.modelSkybox = true //是否将全景图贴在模型上(会导致卡顿)。若不显示模型将不显示Reticule
  24. Potree.settings.tiles3DMaxMemory = 300 //稍微增加点
  25. //Potree.settings.mergeTransCtlOnClick = true
  26. Potree.settings.canWalkThroughModel = true
  27. let { THREE } = Potree.mergeEditStart(dom, mapDom)
  28. let MergeEditor = viewer.modules.MergeEditor
  29. Potree.settings.unableNavigate = false
  30. Potree.settings.showCesium = true
  31. if (Potree.settings.showCesium) {
  32. viewer.backgroundOpacity = 0
  33. Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2ZGM2YzY0ZC1kNWE0LTRiYTgtYTkwNS1kYmJiODRjMWUwMmQiLCJpZCI6MjMzMTQ1LCJpYXQiOjE3MjI5OTUwNTB9.niqpkl6xOkQ2KeJjelyDDDydmSGqKXKb5cX2NyxSNAw'
  34. window.cesiumViewer = new Cesium.Viewer('app', {
  35. useDefaultRenderLoop: true,
  36. requestRenderMode: true, //add 只有需要render时才会render,如tile加载完后、镜头移动后
  37. animation: false,
  38. baseLayerPicker: false,
  39. fullscreenButton: false,
  40. geocoder: false,
  41. homeButton: false,
  42. infoBox: false,
  43. sceneModePicker: false,
  44. selectionIndicator: false,
  45. timeline: false,
  46. navigationHelpButton: false,
  47. //imageryProvider : Cesium.createOpenStreetMapImageryProvider({url : 'https://a.tile.openstreetmap.org/'}),
  48. imageryProvider: Cesium.UrlTemplateImageryProvider({ //直接用84坐标,不用转高德
  49. //"https://wprd04.is.autonavi.com/appmaptile?lang=zh_cn&style=7&yrs=m&x=${x}&y=${y}&z=${z}" //
  50. //url : 'https://webst0{0-7}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}&token=YOUR_API_KEY',
  51. url: 'https://wprd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}&token=YOUR_API_KEY',
  52. minimumLevel: 0,
  53. maximumLevel: 19
  54. }),
  55. //高德秘钥版 imageryProvider: new Cesium.AmapImageryProvider({key, mapStyle: 'normal'})
  56. //报错 401 (Unauthorized) 的方法 https://blog.csdn.net/LBY_XK/article/details/121992641
  57. terrainShadows: Cesium.ShadowMode.DISABLED, //terrain地形
  58. });
  59. //lonlat = [113.595236803415,22.3665168584444]//[113.600356,22.364093]
  60. Potree.setLonlat(lonlat[0], lonlat[1])
  61. }
  62. if(Potree.settings.canWalkThroughModel){
  63. let lastPano
  64. viewer.images360.addEventListener('flyToPano',(e)=>{//漫游到另一个模型就要选中这个模型
  65. let model = e.toPano.pano.pointcloud
  66. if(lastPano?.pointcloud != model && model != MergeEditor.selected){
  67. MergeEditor.selectModel(model)
  68. model.result_.flyInPano(e.toPano.pano, {dontFly:true}) //切换模型显示,因为flyInPano有事件怕乱所以统一用这个函数
  69. }
  70. lastPano = e.toPano.pano
  71. })
  72. }
  73. viewer.addEventListener('camera_changed', e => {
  74. var camera = e.viewport.camera
  75. var pos = camera.position
  76. if (e.viewport.name == 'MainView') {
  77. sceneBus.emit('cameraChange', { x: pos.x, y: pos.y, z: pos.z, rotate: camera.rotation })
  78. if (Potree.settings.showCesium && Potree.settings.displayMode == 'showPointCloud') {
  79. let pPos = new THREE.Vector3(0, 0, 0).applyMatrix4(camera.matrixWorld);
  80. let pRight = new THREE.Vector3(600, 0, 0).applyMatrix4(camera.matrixWorld);
  81. let pUp = new THREE.Vector3(0, 600, 0).applyMatrix4(camera.matrixWorld);
  82. let pTarget = viewer.scene.view.getPivot();
  83. let toCes = (pos) => {
  84. let xy = [pos.x, pos.y];
  85. let height = pos.z;
  86. let deg = viewer.transform.lonlatToLocal.inverse(xy) // toMap.forward(xy);
  87. let cPos = Cesium.Cartesian3.fromDegrees(...deg, height);
  88. return cPos;
  89. };
  90. let cPos = toCes(pPos);
  91. let cUpTarget = toCes(pUp);
  92. let cTarget = toCes(pTarget);
  93. let cDir = Cesium.Cartesian3.subtract(cTarget, cPos, new Cesium.Cartesian3());
  94. let cUp = Cesium.Cartesian3.subtract(cUpTarget, cPos, new Cesium.Cartesian3());
  95. cDir = Cesium.Cartesian3.normalize(cDir, new Cesium.Cartesian3());
  96. cUp = Cesium.Cartesian3.normalize(cUp, new Cesium.Cartesian3());
  97. cesiumViewer.camera.setView({
  98. destination: cPos,
  99. orientation: {
  100. direction: cDir,
  101. up: cUp
  102. }
  103. });
  104. let aspect = viewer.scene.getActiveCamera().aspect;
  105. if (aspect < 1) {
  106. let fovy = Math.PI * (viewer.scene.getActiveCamera().fov / 180);
  107. cesiumViewer.camera.frustum.fov = fovy;
  108. } else {
  109. let fovy = Math.PI * (viewer.scene.getActiveCamera().fov / 180);
  110. let fovx = Math.atan(Math.tan(0.5 * fovy) * aspect) * 2
  111. cesiumViewer.camera.frustum.fov = fovx;
  112. }
  113. cesiumViewer.render(); //立即render,否则会和点云render不同步而错位
  114. }
  115. }
  116. })
  117. viewer.inputHandler.addEventListener('keydown', (e)=>{
  118. if(e.event.key == "e" ){
  119. MergeEditor.transformControls.mode = 'rotate'
  120. }else if(e.event.key == "w"){
  121. MergeEditor.transformControls.mode = 'translate'
  122. }else if(e.event.key == "s"){
  123. MergeEditor.transformControls.mode = 'scale'
  124. }
  125. })
  126. viewer.addEventListener('webglError', e => {
  127. console.error('viewer webglError: ' + e)
  128. sceneBus.emit('webglError', { msg: e.msg })
  129. })
  130. viewer.compass.setAutoDisplay(true)
  131. /* mapBus.on('visible', v => {
  132. //console.log('mapBus visible', v)
  133. viewer.mapViewer.visible = v
  134. if (v) {
  135. viewer.mapViewer.mapLayer.needUpdate = true
  136. }
  137. viewer.mapViewer.dispatchEvent({type:'forceVisible',visible:v})
  138. }) */
  139. {
  140. let index = 1;
  141. //let setDisplay()
  142. if (!Potree.isIframeChild) {
  143. /* viewer.addEventListener('createIframe',(e)=>{//创建了子页面
  144. }) */
  145. window.winIndex = 0;
  146. window.iframeCreated = function (iframe) {
  147. let child = iframe.contentWindow
  148. child.winIndex = index++
  149. //案件里视图提取页面子页面覆盖了父级页面,父级的模型可以隐藏以释放内存
  150. console.error('createdIframe', child.winIndex, child.location.href)
  151. viewer.setDisplay(false)
  152. child.beforeDestroy = function () { //注:在前端仍会找不到beforeDestroy,可能contentWindow变更??所以手动调用setDisplay
  153. console.warn('beforeDestroy', child.winIndex)
  154. child.viewer && child.viewer.setDisplay(false)
  155. //如果是四维看看的场景,先不管了,页面被销毁应该就没了吧
  156. viewer.setDisplay(true)//恢复主页的模型显示
  157. if (!child.viewer) {
  158. try {
  159. let player = child.__sdk.core.get('Player')
  160. /* let runtime = player.model._3dTilesRuntime
  161. let tileset = runtime.getTileset()
  162. tileset._cache.trim(); //使下一次update时dispose所有不可见的tiles
  163. let sceneRenderer = child.__sdk.core.get('SceneRenderer')
  164. player.model.visible = false
  165. runtime.update(16, sceneRenderer.renderer, sceneRenderer.camera, true) //没用,为何_trimTiles的while无法进入
  166. */
  167. player.model.traverse(e => {
  168. e.geometry && e.geometry.dispose()
  169. if (e.material) {
  170. e.material.map && e.material.map.dispose()
  171. if (e.material.uniforms && e.material.uniforms.map && e.material.uniforms.map.value) {
  172. e.material.uniforms.map.value.dispose()
  173. }
  174. }
  175. }) //效果甚微
  176. /* let sceneRenderer = child.__sdk.core.get('SceneRenderer')
  177. sceneRenderer.renderer.render(sceneRenderer.scene, sceneRenderer.camera)
  178. */
  179. } catch (e) {
  180. console.log(e)
  181. }
  182. }
  183. }
  184. }
  185. //不知道删除iframe时是否那些模型还在内存里,需要释放吗? 如果要需要加一个事件
  186. } else {
  187. }
  188. }
  189. window.THREE = THREE
  190. //isLocal = false
  191. let autoLoads = /* window.autoLoads = */ []
  192. let readyToAddModel
  193. let maxLoadingCount = /* isLocal ? 1 : */2; //正在加载模型的最大数目
  194. let mainBackground = viewer.background
  195. const units = { 1: 'metric', 2: 'imperial' }
  196. let getMeasureType = function (type, unit = 1) {
  197. let info
  198. switch (type) {
  199. case 'free':
  200. info = { measureType: 'Distance' }
  201. break
  202. case 'area':
  203. info = { measureType: 'Area' }
  204. break
  205. case 'vertical':
  206. info = { measureType: 'Ver Distance' }
  207. break
  208. default:
  209. console.error('无此 measure type')
  210. }
  211. info.unit = units[unit]
  212. return info
  213. }
  214. let getMeasureFunction = function (measure, bus) {
  215. measure.addEventListener('highlight', (e) => {
  216. //console.log('3d->2d highlight',e.state)
  217. bus.emit('highlight', e.state)
  218. })
  219. measure.addEventListener('marker_dropped', (e) => {//拖拽结束后发送changeCallBack
  220. if (measure.parent) {
  221. //未被删除
  222. bus.emit('update', [
  223. measure.dataset_points.map(p => p.clone()),
  224. measure.points_datasets
  225. ])
  226. }
  227. })
  228. return {
  229. /* quit: () => {
  230. Potree.Log('quit结束且删除: ' + measure.id, '#00c7b2')
  231. viewer.dispatchEvent({ type: 'cancel_insertions', remove: true, measure })
  232. }, //触发结束。退出测量模式,清除之前操作 */
  233. destroy: () => {
  234. viewer.dispatchEvent({ type: 'cancel_insertions', remove: true, measure })
  235. viewer.scene.removeMeasurement(measure)
  236. },
  237. /* getPoints: () => {
  238. return measure.points
  239. },
  240. getDatasetLocations: () => {
  241. return measure.dataset_points
  242. },
  243. getDatasets: () => {
  244. return measure.points_datasets
  245. },
  246. getDatasetId: () => {
  247. return measure.datasetId
  248. }, */
  249. getArea: () => {
  250. return measure.area //{value:area, string:..}
  251. },
  252. getDistance: () => {
  253. if (measure.points.length < 2) return 0
  254. var value = measure.points[0].distanceTo(measure.points[1])
  255. return {
  256. value, //米
  257. string: measure.getConvertString(value, 'distance')
  258. }
  259. },
  260. //手动开启或关闭:
  261. show: () => {
  262. Potree.Utils.updateVisible(measure, 'inListByUser', true)
  263. },
  264. hide: () => {
  265. Potree.Utils.updateVisible(measure, 'inListByUser', false)
  266. },
  267. fly() {
  268. let result = viewer.focusOnObject(measure, 'measure', 1200)
  269. return result.msg ? result.msg : result.promise
  270. //返回值 1 deferred 表示即将位移 2 'posNoChange' 表示已在最佳位置 3 'tooFar' 表示距离最佳位置太远
  271. },
  272. changeSelect(isHight) {
  273. console.log('2d->3d isHight ', isHight)
  274. measure.setSelected(isHight, 'byList')
  275. },
  276. }
  277. }
  278. let camera_changed = (e) => {
  279. if (e.viewport.name == 'MainView' && e.changeInfo.positionChanged) {
  280. //viewer.mainViewport.camera.position
  281. viewer.mainViewport.view.radius = 0.1 //使pivot在面前一丢丢距离
  282. viewer.setControls(viewer.orbitControls)
  283. viewer.removeEventListener('camera_changed', camera_changed)
  284. }
  285. }
  286. let requestInPano = false
  287. let sdk = {
  288. sceneBus, mapBus,
  289. canTurnToPanoMode(pos) {
  290. pos = pos ? new THREE.Vector3().copy(pos) : viewer.images360.position
  291. let pano = viewer.images360.findNearestPano(pos)
  292. if (pano && pano.position.distanceTo(pos) < Potree.config.panoFieldRadius) {
  293. return {model:pano.pointcloud.result_}
  294. }
  295. //poschange后会调用这个,如果返回false会变为点云模式,且不会自动变回原先的模式
  296. },
  297. getPositionByScreen(pos2d, hopeModelId) {//通过屏幕坐标获取真实坐标 . hopeModelId: 如果指定了模型,优先返回hopeModelId上的intersect
  298. //console.log('getPositionByScreen',hopeModelId)
  299. hopeModelId = null
  300. let worldPos, localPos, modelId, intersect
  301. let Handler = viewer.inputHandler
  302. let reGet = () => {//不使用当前鼠标所在位置的intersect,单独算
  303. pos2d.clientX = pos2d.x
  304. pos2d.clientY = pos2d.y
  305. pos2d.onlyGetIntersect = true
  306. pos2d.whichPointcloud = true
  307. if (hopeModelId != void 0) {//隐藏其他的模型
  308. let models = MergeEditor.getAllObjects()
  309. models.forEach(model => {
  310. Potree.Utils.updateVisible(model, 'forPick', model.dataset_id == hopeModelId)
  311. })
  312. }
  313. let intersect2 = Handler.onMouseMove(pos2d)
  314. if (hopeModelId != void 0) {//恢复
  315. let models = MergeEditor.getAllObjects()
  316. models.forEach(model => {
  317. Potree.Utils.updateVisible(model, 'forPick', true)
  318. })
  319. }
  320. if (intersect2 && intersect2.location) {
  321. intersect = intersect2
  322. }
  323. }
  324. if (pos2d && pos2d.inDrag) {
  325. reGet()
  326. } else {
  327. intersect = Handler.intersect
  328. if (intersect) {
  329. modelId = intersect.pointcloud ? intersect.pointcloud.dataset_id : intersect.object.dataset_id
  330. if (hopeModelId != void 0 && modelId != hopeModelId) {
  331. reGet()
  332. }
  333. }
  334. }
  335. if (intersect && intersect.location) {
  336. modelId = intersect.pointcloud ? intersect.pointcloud.dataset_id : intersect.object.dataset_id
  337. /* if(hopeModelId != void 0 && modelId != hopeModelId){
  338. return null
  339. } */
  340. worldPos = intersect.location.clone()
  341. localPos = Potree.Utils.datasetPosTransform({ toDataset: true, datasetId: modelId, position: worldPos })
  342. } else return null
  343. return { worldPos, modelId, localPos }
  344. },
  345. getScreenByPosition(pos3d, modelId, canShelter/* , disToCameraLimit */) {//通过模型局部坐标获取屏幕坐标
  346. //console.log('getScreenByPoint ')
  347. let isLocal = modelId != void 0
  348. pos3d = new THREE.Vector3().copy(pos3d)
  349. let worldPos = isLocal ? Potree.Utils.datasetPosTransform({ fromDataset: true, datasetId: modelId, position: pos3d }) : pos3d
  350. if (!worldPos) return
  351. if (canShelter) {
  352. if (viewer.inputHandler.ifBlockedByIntersect(worldPos, 0.1, true)) return { trueSide: false };
  353. }
  354. var viewport = viewer.mainViewport
  355. var camera = viewport.camera
  356. var dom = viewer.renderArea
  357. if (tagLimitDis != void 0) {
  358. if (camera.position.distanceToSquared(worldPos) > Math.pow(tagLimitDis, 2)) return false
  359. }
  360. //console.log('getScreenByPoint ' + pos3d.toArray())
  361. return Potree.Utils.getPos2d(worldPos, viewport, dom)
  362. },
  363. setCameraFov(fov) {
  364. viewer.setFOV(fov)
  365. },
  366. screenshot: (width, height, bgOpacity = 1) => {
  367. //截图
  368. var { getImagePromise, finishPromise } = viewer.startScreenshot({ type: 'default', /* useRenderTarget:true, */bgOpacity }, width, height)
  369. var deferred = $.Deferred();
  370. finishPromise.done(({ dataUrl }) => {
  371. deferred.resolve(dataUrl)
  372. })
  373. return deferred.promise()
  374. },
  375. getPose() {//获取当前点位和朝向
  376. const camera = viewer.scene.getActiveCamera()
  377. const target = viewer.scene.view.getPivot().clone()
  378. const position = viewer.scene.view.position.clone()
  379. const pose = { position, target, displayMode:Potree.settings.displayMode }
  380. if(Potree.settings.displayMode == 'showPanos'){
  381. pose.panoId = viewer.images360.currentPano.originID
  382. pose.model = viewer.images360.currentPano.pointcloud.result_
  383. pose.posInModel = Potree.Utils.datasetPosTransform({ toDataset: true, position: camera.position.clone(), object:pose.model })
  384. pose.rotInModel = Potree.Utils.datasetRotTransform({ toDataset: true, quaternion: camera.position.clone(), getQuaternion: true, object:pose.model }) //拿第一个数据集
  385. }
  386. //console.log('getPose',position, target)
  387. return pose
  388. },
  389. comeTo(o = {}) {
  390. //console.log('comeTo',o.position, o.target)
  391. //飞到某个点
  392. /* if (o.modelId) {
  393. ['position', 'target'].forEach(e => {
  394. if (o[e]) {
  395. o[e] = Potree.Utils.datasetPosTransform({ fromDataset: true, datasetId: o.modelId, position: o[e] })
  396. }
  397. })
  398. } */
  399. let deferred = $.Deferred()
  400. if(o.displayMode == 'showPanos'){
  401. let pano = o.model.panos.find(a=>a.originID == e.panoId)
  402. if(pano){
  403. let quaternion = Potree.Utils.datasetRotTransform({ fromDataset: true, quaternion: o.rotInModel, getQuaternion: true, object:o.model })
  404. o.model.result_.flyInPano(pano, {quaternion, callback(){
  405. o.callback && o.callback()
  406. deferred.resolve(true)
  407. }})
  408. return deferred.promise()
  409. }else{
  410. console.warn('没有找到漫游点',o)
  411. }
  412. }
  413. if (o.distance) {
  414. let position = o.target || o.position
  415. return viewer.focusOnObject({ position }, 'tag', null, { distance: o.distance }).promise
  416. }
  417. viewer.scene.view.setView($.extend({}, o, {
  418. duration: o.dur,
  419. callback: () => {
  420. o.callback && o.callback()
  421. deferred.resolve(true)
  422. }
  423. }))
  424. return deferred.promise()
  425. },
  426. setBackdrop(sky, type, { scale, rotate }) {//天空盒背景
  427. //console.log('天空盒背景', sky,type)
  428. let setGroundAndText = (color) => {
  429. MergeEditor.secondCompass.dom.find(".dirText").css({ 'color': color })
  430. viewer.compass.dom.find(".dirText").css({ 'color': color })
  431. MergeEditor.ground.material.uniforms.uColor.value.set(color)
  432. //MergeEditor.ground.children[0].material.color.set(color)
  433. }
  434. if (type == 'bimg') {//地面图
  435. MergeEditor.setGroundPlaneImg(sky, scale, rotate)
  436. setGroundAndText('#e0e0e0')
  437. viewer.setBackground(mainBackground)
  438. } else {
  439. MergeEditor.setGroundPlaneImg(null)
  440. if (sky == 'none') {
  441. viewer.setBackground(mainBackground)
  442. setGroundAndText('#eee')
  443. } else if (sky[0] == '#') {
  444. viewer.setBackground(new THREE.Color(sky))
  445. let color = sky == '#fff' ? '#666' : sky == '#333' ? '#eee' : '#bbb' //反相
  446. setGroundAndText(color)
  447. } else if (type == 'image-map' || type == 'vector-map') {//影像|矢量 地图
  448. } else {//环境
  449. viewer.setBackground('skybox', sky)
  450. setGroundAndText('#e0e0e0')
  451. }
  452. }
  453. viewer.dispatchEvent('content_changed')
  454. },
  455. switchMapType(type) {
  456. let map = viewer.mapViewer.mapLayer.maps.find(e => e.name == 'map')
  457. map.switchStyle(type/* map.style == 'satellite' ? 'standard' : 'satellite' */)
  458. },
  459. enableMap(mapArea, latlng) {
  460. if (!viewer.mapViewer) {
  461. //--------------------------------
  462. viewer.mapViewer = new Potree.MapViewer(mapArea)
  463. viewer.mapViewer.initProjection()
  464. //focus
  465. let boundSize = new THREE.Vector3(200, 150, 1).max(viewer.bound.boundSize)
  466. viewer.mapViewer.addEventListener('viewerResize', () => {
  467. viewer.mapViewer.moveTo(viewer.bound.center, boundSize, 0)
  468. }, { once: true })
  469. }
  470. },
  471. enterSceneGuide(pathArr) {//导览 (不需要修改参数)
  472. let editor = viewer.modules.CamAniEditor
  473. console.log('pathArr', pathArr)
  474. //console.log('enterSceneGuide',pathArr)
  475. let data = {
  476. //duration: pathArr.slice(0, pathArr.length - 1).reduce(function (total, currentValue) { return total + currentValue.time }, 0), //总时长(要去掉最后一个,因为已到终点,该点time无意义)
  477. points: pathArr,
  478. useDurSlice: true
  479. }
  480. data.pathArr.forEach(e=>{
  481. if(e.inPano){
  482. e.model = e.model.model
  483. }
  484. })
  485. let ani = editor.createMulAnimation(data)
  486. //注:最多只存在一条导览
  487. let bus = mitt()
  488. //播放完成
  489. ani.event_.addEventListener('playDone', () => {
  490. bus.emit('playComplete')
  491. })
  492. //切换点
  493. ani.event_.addEventListener('updateCurrentIndex', e => {
  494. bus.emit('changePoint', e.currentIndex + 1)
  495. })
  496. return {
  497. bus,
  498. play() {
  499. MergeEditor.selectModel(null)
  500. ani.play()
  501. },
  502. pause() {
  503. ani.pause()
  504. },
  505. clear() {
  506. ani.remove()
  507. },
  508. }
  509. },
  510. //[path1, paht2], { time, speed }
  511. calcPathInfo(paths, info) { //传入的time, speed仅有一个。返回完整的 time, speed
  512. //这一版的control似乎无法在某个位置上改变角度,位置和角度一般都是一起变的,所以先不增加单位更换功能。
  513. let pos1 = new THREE.Vector3().copy(paths[0].position)
  514. let pos2 = new THREE.Vector3().copy(paths[1].position)
  515. let dis = pos1.distanceTo(pos2)
  516. if (info.time != void 0) {
  517. info.speed = dis / info.time
  518. } else {
  519. info.time = dis / info.speed
  520. }
  521. return info
  522. },
  523. addModel(props) {
  524. let bus = props.bus = mitt()
  525. //console.log('addModel',props)
  526. props.isFirstLoad = isLocal ? props.bottom == void 0 : (props.isDynamicAdded || props.mode == 'single') // 在编辑时用户添加的 或 展示单个模型 (props.mode='single'模型展示页, props.mode='many'融合页)
  527. if (props.opacity == void 0) props.opacity = 1
  528. if (props.type == 'obj') props.type = 'glb'
  529. props.scale /= 100
  530. if (props.rotation) {
  531. if (props.rotation._x == void 0 && props.rotation.x != void 0) {
  532. props.rotation = new THREE.Euler().setFromVector3(props.rotation)
  533. }
  534. }
  535. let getDefaultRotation = () => {
  536. //0看看,1看见,2深时,3用户上传三维模型,4深时mesh,5深光点云,6深光mesh
  537. if (props.fromType == 1 || props.fromType == 6 || props.fromType == 4 && props.type != 'glb') {//来自4dkk的3dtiles初始需要转90度
  538. return new THREE.Euler(Math.PI / 2, 0, 0)
  539. } else return new THREE.Euler(0, 0, 0)
  540. }
  541. if (!props.isFirstLoad) {
  542. if (autoLoads.length == 0) { //首次加载
  543. setTimeout(() => {
  544. let sizes = autoLoads.map(e => e.size || 0)
  545. console.log('需要请求加载的模型大小为', sizes, '总大小', sizes.reduce(function (total, currentValue) {
  546. let current = parseFloat(currentValue)
  547. return total + ((typeof currentValue == 'number' || currentValue.includes('M')) ? current : current / 1024)
  548. }, 0))
  549. readyToAddModel = true //准备开始加载
  550. loadNext()//startLoad(autoLoads[0])
  551. }, 30)
  552. }
  553. autoLoads.push(props)
  554. readyToAddModel = false
  555. } else {
  556. readyToAddModel = true
  557. props.rotation = getDefaultRotation()
  558. }
  559. let model
  560. let done = (model_) => {
  561. model = model_
  562. model.result_ = result
  563. if (!props.isFirstLoad) {
  564. model.visible = false//先不显示,防止卡顿
  565. }
  566. model.showInPano = props.raw.showInPano
  567. props.opacity < 100 && result.changeOpacity(props.opacity)
  568. model.addEventListener('changeSelect', (e) => {
  569. bus.emit('changeSelect', e.selected)
  570. })
  571. let lastState = {}
  572. model.addEventListener('transformChanged', (e) => {
  573. let msg = {}
  574. if (!lastState.position || !model.position.equals(lastState.position)) {
  575. lastState.position = msg.position = model.position.clone()
  576. }
  577. if (!lastState.rotation || !model.rotation.equals(lastState.rotation)) {
  578. lastState.rotation = msg.rotation = model.rotation.clone()
  579. }
  580. if (lastState.scale == void 0 || model.scale.x * 100 != lastState.scale) {
  581. lastState.scale = msg.scale = model.scale.x * 100
  582. }
  583. msg = Potree.Common.CloneObject(msg)
  584. //console.log(msg)
  585. bus.emit('transformChanged', msg)
  586. })
  587. spliceFromArr(model, props, true)
  588. /* model.addEventListener('changeSelect', (e) => {
  589. e.selected ? MergeEditor.transformControls.attach(model, e.clickPos) : MergeEditor.transformControls.detach()
  590. }) */
  591. if (props.mode == 'single') {//模型查看页
  592. MergeEditor.noNeedSelection = true
  593. setTimeout(() => {
  594. MergeEditor.focusOn([model], 1000, true, true)
  595. }, 1)
  596. }
  597. if (props.fromType == 6 || props.fromType == 4 || props.fromType == 0 || props.fromType == 1) {
  598. Potree.load4dkkPanos(props.raw.num, model, () => {
  599. bus.emit('loadDone')
  600. })
  601. } else {
  602. bus.emit('loadDone')
  603. }
  604. //console.log('loadDone' )
  605. }
  606. let progressFun = (progress) => {
  607. bus.emit('loadProgress', progress)
  608. }
  609. let onError = function (xhr) {
  610. bus.emit('loadError', xhr)
  611. console.log('loadError!!!!!!!!!', Potree.Common.getNameFromURL(props.url), props.size, xhr)
  612. spliceFromArr(model, props, false)
  613. }
  614. try {
  615. props.url = JSON.parse(props.url) //去掉 '\'
  616. } catch (e) { }
  617. props.done = done; props.progressFun = progressFun; props.onError = onError
  618. if (readyToAddModel) {
  619. if (autoLoads.filter(e => e.loading).length < maxLoadingCount) {
  620. startLoad(props)
  621. }
  622. }
  623. let scaleMeasure
  624. let result = {
  625. bus,
  626. model,
  627. getDefaultRotation,
  628. supportPano() { //是否支持全景图
  629. return model.panos && model.panos.length > 0
  630. },
  631. flyInPano(pano, {dontFly, quaternion}={}) {// 飞入全景图
  632. requestInPano = model
  633. pano = pano || viewer.images360.findNearestPano(null, model.panos)
  634. if (pano) {
  635. viewer.removeEventListener('camera_changed', camera_changed)
  636. Potree.settings.canWalkThroughModel || viewer.images360.panos.forEach(pano => {
  637. pano.setEnable(pano.pointcloud == model)
  638. })
  639. viewer.setControls(viewer.fpControls)
  640. //MergeEditor.transformControls.detach(model)
  641. Potree.Utils.updateVisible(MergeEditor.transformControls, 'showPanos', false)
  642. Potree.Utils.updateVisible(MergeEditor.boxHelper, 'showPanos', false)
  643. let changeVisi = (object) => {
  644. Potree.Utils.updateVisible(object, 'showPanos', object == model && Potree.settings.modelSkybox || object.showInPano)
  645. }
  646. let eventName = Potree.settings.displayMode != 'showPanos' ? 'endChangeMode' : 'flyToPanoDone'
  647. viewer.images360.addEventListener(eventName, (e) => {
  648. if (Potree.settings.displayMode == 'showPanos' && requestInPano == model) {
  649. //Potree.Utils.updateVisible(viewer.objs, 'showPanos', false)
  650. viewer.objs.children.forEach(changeVisi)
  651. }
  652. }, { once: true })
  653. dontFly || viewer.images360.flyToPano({ pano, canCancelLast: true, quaternion })
  654. Potree.settings.displayMode = 'showPanos'
  655. }
  656. },
  657. flyOutPano() {// 飞出全景图(就是切换到正常融合视角)
  658. requestInPano = false
  659. let panoPos = viewer.images360.position.clone()
  660. //Potree.Utils.updateVisible(viewer.objs, 'showPanos', true)
  661. let changeVisi = (object) => {
  662. Potree.Utils.updateVisible(object, 'showPanos', true)
  663. }
  664. viewer.objs.children.forEach(changeVisi)
  665. Potree.settings.canWalkThroughModel || viewer.images360.panos.forEach(pano => {
  666. pano.setEnable(true)
  667. })
  668. Potree.Utils.updateVisible(MergeEditor.transformControls, 'showPanos', true)
  669. setTimeout(() => {//在下一帧再变,因为3dtiles需要更新一下才会显示tiles
  670. if (!requestInPano) {
  671. Potree.settings.displayMode = 'showPointCloud'
  672. Potree.Utils.updateVisible(MergeEditor.boxHelper, 'showPanos', true)
  673. }
  674. }, 50)
  675. viewer.addEventListener('camera_changed', camera_changed)
  676. },
  677. changeShow(show) {
  678. props.show = show //for autoLoads show model
  679. if (model) {
  680. Potree.Utils.updateVisible(model, 'datasetSelection', show)
  681. if (model.panos) {
  682. model.panos.forEach(e => e.setEnable(show))
  683. }
  684. viewer.dispatchEvent('content_changed')
  685. }
  686. },
  687. changeSelect(state) {
  688. console.error('select', state)
  689. if (model) {
  690. let fly = viewer.images360.latestRequestMode != 'showPanos'
  691. MergeEditor.selectModel(model, state, fly, true)
  692. if (state && viewer.inputHandler.selection[0]) {
  693. MergeEditor.transformControls.attach(model) //viewer.transformObject(model); //交换
  694. }
  695. //console.log('changeSelect', props.id, state)
  696. }
  697. },
  698. changeScale(s) {
  699. if (model) {
  700. s /= 100
  701. if (model.scale.x == s) return
  702. //MergeEditor.history.beforeChange(model)//但不知道什么时候结束拖拽
  703. model.scale.set(s, s, s)
  704. model.isPointcloud && model.changePointSize(Potree.config.material.realPointSize * s)
  705. model.dispatchEvent("scale_changed")
  706. }
  707. },
  708. changeOpacity(opacity) { //见笔记:透明物体的材质设置
  709. if (opacity == void 0) opacity = 100
  710. opacity /= 100
  711. MergeEditor.changeOpacity(model, opacity)
  712. },
  713. changeBottom(z) {
  714. /* model && MergeEditor.setModelBtmHeight(model,z)
  715. model.dispatchEvent('transformChanged') //改了position */
  716. },
  717. changePosition(pos) {//校准取消时执行
  718. console.log('changePosition', pos.x, pos.y, pos.z)
  719. model && model.position.copy(pos)
  720. model.dispatchEvent({ type: 'position_changed' })
  721. },
  722. changeRotation(rot) {//校准取消时执行
  723. console.log('changeRotation', rot.x, rot.y, rot.z)
  724. model && model.rotation.setFromVector3(rot)
  725. model.dispatchEvent({ type: 'rotation_changed' })
  726. },
  727. enterRotateMode() {
  728. if (model) {
  729. if (MergeEditor.split) {//分屏校准
  730. MergeEditor.setTransformState('rotate')
  731. MergeEditor.transformControls2.attach(model)
  732. MergeEditor.transformControls2.mode = 'rotate'
  733. }
  734. MergeEditor.transformControls.attach(model)
  735. MergeEditor.transformControls.mode = 'rotate'
  736. }
  737. },
  738. enterMoveMode() {
  739. console.log('enterMoveMode')
  740. if (model) {
  741. if (MergeEditor.split) {//分屏校准
  742. MergeEditor.setTransformState('translate')
  743. MergeEditor.transformControls2.attach(model)
  744. MergeEditor.transformControls2.mode = 'translate'
  745. }
  746. MergeEditor.transformControls.attach(model)
  747. MergeEditor.transformControls.mode = 'translate'
  748. }
  749. },
  750. leaveTransform() {
  751. console.log('leaveTransform')
  752. if (MergeEditor.split) {//分屏校准
  753. MergeEditor.setTransformState(null)
  754. } else {
  755. MergeEditor.transformControls.detach()
  756. MergeEditor.transformControls2.detach()
  757. }
  758. MergeEditor.history.clear()
  759. },
  760. enterAlignment() {//开始校准
  761. result.leaveTransform()
  762. MergeEditor.enterSplit()
  763. //console.log('enterAlignment',model.position, model.rotation)
  764. let bus = new mitt()
  765. /* MergeEditor.transformControls.attach(model)
  766. MergeEditor.transformControls.mode = 'translate' */
  767. return {
  768. bus
  769. }
  770. },
  771. leaveAlignment() {
  772. //console.log('leaveAlignment',model.position, model.rotation)
  773. MergeEditor.leaveSplit()
  774. MergeEditor.transformControls.detach()
  775. MergeEditor.transformControls2.detach()
  776. },
  777. enterScaleSet() {//设置比例
  778. let bus = new mitt()
  779. let length, measureBuilded;
  780. viewer.outlinePass.selectedObjects = []
  781. if (!Potree.Utils.isInsideFrustum(model.boundingBox.clone().applyMatrix4(model.matrixWorld), viewer.scene.getActiveCamera())) {
  782. MergeEditor.focusOn(model, 600)
  783. }
  784. MergeEditor.getAllObjects().forEach(m => {//隐藏其他的模型
  785. if (m != model) Potree.Utils.updateVisible(m, 'enterScaleSet', false)
  786. })
  787. let setScale = () => {
  788. if (length == void 0 || !measureBuilded) return
  789. let vec = new THREE.Vector3().subVectors(viewer.mainViewport.camera.position, scaleMeasure.points[1])
  790. let s = length / (scaleMeasure.points[0].distanceTo(scaleMeasure.points[1]))
  791. result.changeScale(model.scale.x * s * 100)
  792. /* setTimeout(()=>{
  793. viewer.focusOnObject(scaleMeasure , 'measure', 500)
  794. },1) */
  795. let newCamPos = new THREE.Vector3().addVectors(scaleMeasure.points[1], vec.multiplyScalar(s))
  796. viewer.scene.view.setView({
  797. position: newCamPos, target: scaleMeasure.getCenter(), duration: 0, callback: () => {
  798. //更改target到measure中心的好处就是可以让相机绕measure中心转,坏处是每次更改都会变一下画面
  799. }
  800. })
  801. }
  802. return {
  803. bus,
  804. setLength(v) {
  805. if (!v) return
  806. length = v
  807. setScale()
  808. },
  809. startMeasure() {
  810. if (scaleMeasure) {
  811. viewer.dispatchEvent({ type: 'cancel_insertions', remove: true, measure: scaleMeasure })
  812. viewer.scene.removeMeasurement(scaleMeasure)
  813. }
  814. measureBuilded = false
  815. scaleMeasure = viewer.measuringTool.startInsertion(
  816. { measureType: "Distance", unit: "metric" },
  817. () => {
  818. //done:
  819. //bus.emit('end' ) //完成
  820. measureBuilded = true
  821. setScale()
  822. },
  823. () => {
  824. //cancel
  825. //bus.emit('quit') //删除
  826. }
  827. )
  828. scaleMeasure.addEventListener('marker_dropped', (e) => {//拖拽结束后发送changeCallBack
  829. if (scaleMeasure.parent) {
  830. //未被删除
  831. measureBuilded && setScale()
  832. }
  833. })
  834. }
  835. }
  836. },
  837. leaveScaleSet() {
  838. if (scaleMeasure) {
  839. viewer.dispatchEvent({ type: 'cancel_insertions', remove: true, measure: scaleMeasure })
  840. viewer.scene.removeMeasurement(scaleMeasure)
  841. scaleMeasure = null
  842. }
  843. viewer.outlinePass.selectedObjects = [model];
  844. MergeEditor.getAllObjects().forEach(m => {//恢复其他的模型
  845. if (m != model) Potree.Utils.updateVisible(m, 'enterScaleSet', true)
  846. })
  847. },
  848. destroy() {
  849. model && MergeEditor.removeModel(model)
  850. viewer.dispatchEvent('content_changed')
  851. }
  852. }
  853. return result
  854. },
  855. //测量线的点都附着于各个模型,当模型变化时,点跟着变化。
  856. // 新的测量创建方法,传入type 返回新测量对象
  857. startMeasure(type) {
  858. // 寻创建的测量对象有上面绘画测量对象的所有方法
  859. const bus = mitt()
  860. let info = getMeasureType(type)
  861. let measure = viewer.measuringTool.startInsertion(
  862. info,
  863. () => {
  864. //done:
  865. /* bus.emit('submit', {
  866. dataset_points: measure.dataset_points.map(p=>p.clone()) ,
  867. points_datasets: measure.points_datasets
  868. } ) //完成 */
  869. bus.emit('submit')
  870. bus.emit('update', [
  871. measure.dataset_points.map(p => p.clone()),
  872. measure.points_datasets
  873. ])
  874. },
  875. () => {
  876. //cancel
  877. bus.emit('cancel'/* , ret */) //删除
  878. }
  879. )
  880. Potree.Log('startMeasure: ' + measure.id, '#00c7b2')
  881. /* let cancel = ()=>{
  882. Potree.Log('clear删除: ' + measure.id, '#00c7b2')
  883. viewer.dispatchEvent({ type: 'cancel_insertions', remove: true, measure })
  884. viewer.scene.removeMeasurement(measure)
  885. } */
  886. let result = {
  887. bus,
  888. ...getMeasureFunction(measure, bus),
  889. }
  890. /* StartMeasure = Measure & {
  891. // 多了cancel 取消测量的事件,没有参数
  892. // 多了invalidPoint 当用户测量了无效点时的事件,抛出无效原因
  893. bus: Emitter<{ cancel: void; invalidPoint: string }>
  894. } */
  895. return result
  896. },
  897. // 绘画测量线(非新增使用)
  898. // type = 'free' (自由) || 'vertical' (垂直) || 'area' (面积)
  899. // positions 点数组 构成如下 [{ point: {x,y,z}, modelId: 1 }]
  900. drawMeasure(type, dataset_points, points_datasets) {
  901. // 返回测量对象有如下
  902. const bus = mitt()
  903. let info = getMeasureType(type /* , unit */)
  904. //info.points = positions
  905. info.dataset_points = dataset_points
  906. info.points_datasets = points_datasets
  907. //info.sid = sid
  908. info.bus = bus
  909. let measure = viewer.measuringTool.createMeasureFromData(info)
  910. if (!measure) return { bus }
  911. Potree.Log('drawMeasure由数据新建: ' + measure.id, '#00c7b2')
  912. let result = {
  913. bus,
  914. setPositions(dataset_points, points_datasets) {//用于恢复measure的点,不会修改点的个数
  915. measure.dataset_points = dataset_points.map(e => {
  916. return e && new THREE.Vector3().copy(e)
  917. })
  918. measure.points_datasets = points_datasets
  919. measure.points = measure.dataset_points.map((p, i) => {
  920. return Potree.Utils.datasetPosTransform({ fromDataset: true, datasetId: measure.points_datasets[i], position: p })
  921. })
  922. measure.getPoint2dInfo(measure.points)
  923. measure.update({ ifUpdateMarkers: true })
  924. measure.setSelected(false)//隐藏edgelabel
  925. },
  926. ...getMeasureFunction(measure, bus),
  927. }
  928. return result
  929. },
  930. addTag(info) {//加热点
  931. let bus = mitt()
  932. let tag
  933. let done = () => {
  934. bus.emit('added')
  935. bus.emit('update', { position: tag.position.clone(), normal: o.normal.clone(), modelId: tag.root.dataset_id })
  936. tag = tag_
  937. tag.spot.addEventListener('mouseover', () => {
  938. bus.emit('hoverState', true)
  939. })
  940. tag.spot.addEventListener('mouseout', () => {
  941. bus.emit('hoverState', false)
  942. })
  943. }
  944. if (!info.position) {
  945. viewer.tagTool.startInsertion().done(tag_ => {
  946. done()
  947. })
  948. } else {
  949. info.root = MergeEditor.getAllObjects().find(e => e.dataset_id == info.modelId)
  950. if (!info.root) {
  951. console.error('没有找到该modelId')
  952. }
  953. tag = viewer.tagTool.createTagFromData(info)
  954. done()
  955. }
  956. let result = {
  957. bus,
  958. getScreenPos() {
  959. let pos3d = new THREE.Vector3().setFromMatrixPosition(tag.matrixWorld)
  960. return sdk.getScreenByPosition(pos3d)
  961. },
  962. show() {
  963. Potree.Utils.updateVisible(tag, 'byList', true)
  964. },
  965. hide() {
  966. Potree.Utils.updateVisible(tag, 'byList', false)
  967. },
  968. destroy() {
  969. if (tag) {
  970. tag.dispose()
  971. }
  972. viewer.dispatchEvent({ type: 'cancel_insertions', remove: true })
  973. },
  974. changeTitle(title) {
  975. tag.changeTitle(title)
  976. }
  977. }
  978. return result
  979. },
  980. showGrid() {
  981. Potree.Utils.updateVisible(viewer.modules.MergeEditor.ground, 'hideGrid', true)
  982. viewer.dispatchEvent('content_changed')
  983. },
  984. hideGrid() {
  985. Potree.Utils.updateVisible(viewer.modules.MergeEditor.ground, 'hideGrid', false)
  986. viewer.dispatchEvent('content_changed')
  987. }
  988. }
  989. function spliceFromArr(model, props, loaded){
  990. //let autoLoads.find()
  991. props.loadFinish = true
  992. props.loading = false
  993. if (loaded) {
  994. props.loaded = true
  995. props.model = model
  996. } else {
  997. props.error = true
  998. }
  999. /* let haventLoad = autoLoads.filter(e=>!e.loading && !e.loadFinish);
  1000. if( haventLoad[0]){
  1001. startLoad(haventLoad[0])
  1002. */
  1003. if (!loadNext()) {
  1004. if (autoLoads.filter(e => !e.loadFinish).length == 0 && autoLoads.filter(e => e.loaded).length > 0 && !props.isFirstLoad) {//设置相机位置:当自动开始加载第一个模型时(其余的也跟着自动加载),等这批加载完后;
  1005. let autoLoadsDone = autoLoads.filter(e => e.loaded).map(e => e.model)
  1006. console.log('所有模型加载完毕')
  1007. autoLoads.filter(e => e.loaded && e.show).forEach(e => e.model.visible = true)
  1008. MergeEditor.focusOn(autoLoadsDone, 1000, true, true)
  1009. autoLoads.length = 0
  1010. }
  1011. }
  1012. }
  1013. function loadNext(){
  1014. let haventLoad = autoLoads.filter(e => !e.loading && !e.loadFinish);
  1015. let loading = autoLoads.filter(e => e.loading);
  1016. let needLoad = haventLoad.slice(0, maxLoadingCount - loading.length)
  1017. needLoad.forEach(e => startLoad(e))
  1018. return haventLoad.length > 0
  1019. }
  1020. function startLoad(prop){
  1021. /* if(prop.raw.visible !== 1){//用于临时隐藏
  1022. setTimeout(()=>{
  1023. spliceFromArr(null, prop, false)
  1024. prop.bus.emit('loadError' )
  1025. },1)
  1026. return
  1027. } */
  1028. if(prop.loading || prop.loadFinish)return
  1029. Potree.Log(`--开始加载--`, { font: { color: '#f68' } });
  1030. console.log('id:', prop.id, ', title:', prop.title, ', filename:', Potree.Common.getNameFromURL(prop.url), ', type:', prop.type, prop)
  1031. prop.unlit = prop.renderType != 'normal'
  1032. prop.maximumScreenSpaceError = 70
  1033. prop.prefix = prop.raw.prefix
  1034. Potree.addModel(prop, prop.done, prop.progressFun, prop.onError)
  1035. prop.loading = true
  1036. }
  1037. return sdk
  1038. }
  1039. /*
  1040. 暂定不同场景间的漫游点不能互通。虽然它们可能是摆放正确的,如果是组成一整个场景的话还是要打通……
  1041. 不互通的方法是设置pano.enable
  1042. */
  1043. export default enter