123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238 |
- import mitt from 'mitt'
- import libTransform from 'coordtransform';
- import axios from 'axios' //{ axios } from '@/api'
- let requestLoadCount = 0
- let maxLoadingCount = 2; //正在加载模型的最大数目
- //0看看,1看见,2深时,3用户上传三维模型,4深时mesh,5深光点云,6深光mesh
- const ModelTypes = {
- 0 : {name:'看看(八目)', panos4dkk:true},
- 1 : {name:'看见(双目转台)', panos4dkk:true, rot90:true},
- 2 : {name:'深时', },
- 3 : {name:'用户上传三维模型'},
- 4 : {name:'深时mesh(激光转台)',panos4dkk:true, rot90:true},//3dtiles or obj
- 5 : {name:'深光点云' },
- 6 : {name:'深光mesh',panos4dkk:true, rot90:true},//3dtiles
- 7 : {name:'圆周率相机' },//圆周率相机场景
- }
- let cesAspect , cesImageryProvider
- const Id_noIntersect = -100 //path绘制在地图上的点,modelId传这个值,勿更改
- let isValidPoint = (modelId)=>{//所存的modelId没被删或者它本身不在模型上
- return modelId == Id_noIntersect || viewer.objs.children.concat(viewer.scene.pointclouds).some(e=>e.dataset_id == modelId )
- }
- let curSelectPath
- {
- // 84坐标转高德 (国外地区用84,所以地理注册时填的是84,我这需要转成高德)
- const wgs84ToAMap = (pos ) => {
- const latlng = libTransform.wgs84togcj02(pos.x, pos.y)
- return {
- x: latlng[0],
- y: latlng[1]
- }
- }
- // 高德坐标转84
- const aMapToWgs84 = (pos ) => {
- const latlng = libTransform.gcj02towgs84(pos.x, pos.y)
- return {
- x: latlng[0],
- y: latlng[1]
- }
- }
- window.AMapWith84__ = { //在Potree里setLonlat时不管转不转效果都一样 很奇怪,所以这里改名。只在ces
- aMapToWgs84, wgs84ToAMap
- }
- }
- //江门本地版本
- export const enter = ({ dom, mapDom, isLocal, lonlat, scenes, laserRoot, laserOSSRoot, panoOSSRoot,ossRoot }) => {
-
- console.warn('新的页面')
- Potree.settings.isOfficial = true //标记为正式、非测试版本
- //Potree.fileServer = axios
- Potree.settings.libsUrl = './lib/'
- let loadStartTime = Date.now()
- //正式环境(本地调试会打不开)
- if (location.host === 'mix3d.4dkankan.com') {
- Potree.settings.urls.prefix = Potree.settings.urls.prefix6
- Potree.settings.webSite = 'datav1'
- } else if (location.host === 'xfhd.4dkankan.com') {
- Potree.settings.urls.prefix = Potree.settings.urls.prefix7
- Potree.settings.webSite = 'datav1'
- }
- if(window.offline){//离线版
- Potree.settings.urls.templates = {
- depthTex : 'swss/{sceneCode}/www/{sceneCode}/wwwroot/{sceneCode}/data/{sceneCode}/depthmap',
- vision : '/swkk/{sceneCode}/wwwroot/scene_view_data/{sceneCode}/images/vision.txt'
- }
- Potree.fileStorage = {
- get(url){
- return new Promise(async function(resolve,reject){
- try {
- let data = await window.offlineData[url]
- if(data){
- resolve(data)
- }
- }catch(e){
- console.error('没找到', url, e)
- reject()
- }
- })
-
- }
- }
-
- }
- if(laserRoot != void 0){
- Potree.settings.urls.prefix = Potree.settings.urls.handlePrefix(laserRoot)
- }
-
- if(laserOSSRoot != void 0){
- Potree.settings.urls.setPrefix(1, laserOSSRoot) //dep ..
- }
- if(panoOSSRoot != void 0){
- Potree.settings.urls.setPrefix(3, panoOSSRoot) //tile
- Potree.settings.urls.setPrefix(8, panoOSSRoot)//vision.txt
- //Potree.settings.urls.panoPrefix = panoOSSRoot //vision.txt
- }
- if(ossRoot){
- Potree.settings.urls.ossRoot/* panoPrefix */ = Potree.settings.urls.handlePrefix(ossRoot) //vision.txt
- }
- Potree.settings.cloudAddMapping = true
- Potree.settings.webSite = 'datav1' //depthTex
-
-
-
-
-
- const mapBus = mitt(), sceneBus = mitt()
-
-
- let isLocal2 = true
- if(isLocal2){//本地配置
- Potree.settings.isLocal = Potree.settings.tileOriginUrl = isLocal2
- }
-
- Potree.settings.showCompass = true
- Potree.settings.compassDom = dom.querySelector('#direction')
- Potree.settings.mergeType2 = true //标识新版
- Potree.settings.modelSkybox = true //是否将全景图贴在模型上(会导致卡顿)。若不显示模型将不显示Reticule
- Potree.settings.tiles3DMaxMemory = 300 //稍微增加点
- Potree.settings.mergeTransCtlOnClick = true
- Potree.settings.canWalkThroughModel = true
- window.cesErrorWords = '内存占用过高,建议关闭部分场景或升级显卡。'
- window.cesErrorCallback = ()=>{
- //sdk.setBackdrop('none')
- }
-
- let { THREE } = Potree.mergeEditStart(dom, mapDom)
- let {MergeEditor, AnimationEditor} = viewer.modules
- Potree.settings.unableNavigate = true
- Potree.setLonlat(lonlat[0], lonlat[1])
-
- if(window.offline){//离线版 改目录
- viewer.images360.tileDownloader.getTiles = function(d, sceneNum, useV4url, model){
- let kankan = !model.isPointcloud //ModelTypes[model.props.fromType].panos4dkk
- if(kankan){
- return `/swkk/${sceneNum}/wwwroot/scene_view_data/${sceneNum}/images/${d}`
- }else{
- return `/swss/${sceneNum}/www/${sceneNum}/scene_view_data/${sceneNum}/images/${d}`
- }
- }
- }
-
- /* Potree.loadControlPoint = async function(callback,sceneCode,onError,prefix){//点云绑定地图
- let path = `/laser/jm/${sceneCode}/getDataSetAndControlPoint`
- return Potree.loadFile(path, {
- fetchMethod: 'post'
- }, callback,onError)
- } */
-
-
-
-
- //因为getPose里用的是target,俯视的yaw不准,所以限制一下不要完全俯视
- viewer.mainViewport.view.maxPitch-=0.001
- viewer.mainViewport.view.minPitch+=0.001
-
- viewer.addEventListener('camera_changed', e => {
- var camera = e.viewport.camera
- var pos = camera.position
- if (e.viewport.name == 'MainView' ) {
- sceneBus.emit('cameraChange', { x: pos.x, y: pos.y, z: pos.z, rotate: camera.rotation })
- Potree.Common.intervalTool.isWaiting('updateCamNear', ()=>{
- updateCamNear()
- }, 1000)
- updateCamFar()
- if(e.changeInfo.positionChanged){
- viewer.objs.children.forEach(model=>{
- model.result_.updateVisiByRange && model.result_.updateVisiByRange()
- })
- }
- }
- if (e.viewport.name == 'MainView' || e.viewport.name == 'top' ) {
- updateMap()
- }
- })
- viewer.addEventListener('shelterComputed', (e)=>{
- //console.log('shelterComputed')
- var camera = viewer.mainViewport.camera
- var pos = camera.position
- sceneBus.emit('cameraChange', { x: pos.x, y: pos.y, z: pos.z, rotate: camera.rotation })
- })
- //-------------------------------------
- let modelAinB = (A,B)=>{ //B的expand(5m) bound完全包含A
- let boundB = B.boundingBox.clone().expandByVector(new THREE.Vector3(5,5,5)).applyMatrix4(B.matrixWorld)
- let boundA = A.boundingBox.clone().applyMatrix4(A.matrixWorld)
- return boundB.containsBox(boundA)
- }
-
- let changeMeshVisi = (object, show) => {
- if(show == void 0) show = Potree.settings.displayMode == 'showPointCloud' || object == viewer.images360.currentPano.pointcloud && Potree.settings.modelSkybox || object.showInPano //showInPano: 装饰物,一直显示
- || !object.panos && modelAinB(object, viewer.images360.currentPano.pointcloud) //装饰物
- Potree.Utils.updateVisible(object, 'showPanos', show)
- }
-
- if(Potree.settings.canWalkThroughModel){
- let lastModel
- viewer.images360.addEventListener('flyToPano',(e)=>{//开始漫游 漫游到另一个模型就要选中这个模型?
- let model = e.toPano.pano.pointcloud
- if(lastModel != model){
- changeMeshVisi(model, true)
- //MergeEditor.selectModel(model)
- //model.result_.flyInPano(e.toPano.pano, {dontFly:true}) //切换模型显示,因为flyInPano有事件怕乱所以统一用这个函数
- updateCamNear()
- }
-
- })
- viewer.images360.addEventListener('flyToPanoDone',(e)=>{
- if(!e.makeIt)return
- let model = viewer.images360.currentPano.pointcloud
- if(lastModel != model){
- lastModel?.isModel && changeMeshVisi(lastModel, false)
- sceneBus.emit('panoModelChange', model.result_ )
- }
- lastModel = model
- })
- }
-
-
- viewer.images360.addEventListener('endChangeMode',(e)=>{
- sceneBus.emit('modeChange', {mode: e.mode == 'showPanos' ? 'pano' : 'fuse', model : e.mode == 'showPanos' && viewer.images360.currentPano.pointcloud.result_} )
-
- Potree.Utils.updateVisible(MergeEditor.transformControls, 'showPanos', e.mode == 'showPointCloud')
- Potree.Utils.updateVisible(MergeEditor.boxHelper, 'showPanos', e.mode == 'showPointCloud')
-
- if(e.mode == 'showPanos'){
- viewer.setControls( viewer.fpControls )
- viewer.removeEventListener('camera_changed', camera_changed)
- }else{
- viewer.addEventListener('camera_changed', camera_changed)
- }
-
- viewer.objs.children.forEach((e)=>{changeMeshVisi(e)})
-
- Potree.settings.canWalkThroughModel || viewer.images360.panos.forEach(pano => {
- pano.setEnable(e.mode == 'showPanos' ? pano.pointcloud == viewer.images360.currentPano.model : true)
- })
-
- Potree.settings.unableNavigate = e.mode == 'showPointCloud'
- updateCamNear()
- })
-
-
- let camera_changed = (e) => {
- if (e.viewport.name == 'MainView' && e.changeInfo.positionChanged) {
- //viewer.mainViewport.camera.position
- viewer.mainViewport.view.radius = 0.1 //使pivot在面前一丢丢距离
- viewer.setControls(viewer.orbitControls)
- viewer.removeEventListener('camera_changed', camera_changed)
-
- }
- }
- let requestInPano = false
- //-------------------------------------
- /* viewer.inputHandler.addEventListener('keydown', (e)=>{
- if(e.event.key == "e" ){
- MergeEditor.transformControls.mode = 'rotate'
- }else if(e.event.key == "w"){
- MergeEditor.transformControls.mode = 'translate'
- }else if(e.event.key == "s"){
- MergeEditor.transformControls.mode = 'scale'
- }
- }) */
- viewer.addEventListener('webglError', e => {
- console.error('viewer webglError: ' + e)
- let memory = '. \n jsHeapSizeLimit:'+ performance.memory.jsHeapSizeLimit/ 1e6 + ', usedJSHeapSize: '+performance.memory.usedJSHeapSize/ 1e6 + '(M)'
- sceneBus.emit('webglError', { msg: e.msg + memory })
- })
- viewer.compass.setAutoDisplay(true)
- /* mapBus.on('visible', v => {
- //console.log('mapBus visible', v)
- viewer.mapViewer.visible = v
- if (v) {
- viewer.mapViewer.mapLayer.needUpdate = true
- }
- viewer.mapViewer.dispatchEvent({type:'forceVisible',visible:v})
- }) */
- {
- let index = 1;
- //let setDisplay()
- if (!Potree.isIframeChild) {
- /* viewer.addEventListener('createIframe',(e)=>{//创建了子页面
- }) */
- window.winIndex = 0;
- window.iframeCreated = function (iframe) {
- let child = iframe.contentWindow
- child.winIndex = index++
- //案件里视图提取页面子页面覆盖了父级页面,父级的模型可以隐藏以释放内存
- console.error('createdIframe', child.winIndex, child.location.href)
- viewer.setDisplay(false)
- child.beforeDestroy = function () { //注:在前端仍会找不到beforeDestroy,可能contentWindow变更??所以手动调用setDisplay
- console.warn('beforeDestroy', child.winIndex)
- child.viewer && child.viewer.setDisplay(false)
- //如果是四维看看的场景,先不管了,页面被销毁应该就没了吧
- viewer.setDisplay(true)//恢复主页的模型显示
- if (!child.viewer) {
- try {
- let player = child.__sdk.core.get('Player')
- /* let runtime = player.model._3dTilesRuntime
- let tileset = runtime.getTileset()
- tileset._cache.trim(); //使下一次update时dispose所有不可见的tiles
- let sceneRenderer = child.__sdk.core.get('SceneRenderer')
- player.model.visible = false
- runtime.update(16, sceneRenderer.renderer, sceneRenderer.camera, true) //没用,为何_trimTiles的while无法进入
- */
- player.model.traverse(e => {
- e.geometry && e.geometry.dispose()
- if (e.material) {
- e.material.map && e.material.map.dispose()
- if (e.material.uniforms && e.material.uniforms.map && e.material.uniforms.map.value) {
- e.material.uniforms.map.value.dispose()
- }
- }
- }) //效果甚微
- /* let sceneRenderer = child.__sdk.core.get('SceneRenderer')
- sceneRenderer.renderer.render(sceneRenderer.scene, sceneRenderer.camera)
- */
- } catch (e) {
- console.log(e)
- }
- }
- }
- }
- //不知道删除iframe时是否那些模型还在内存里,需要释放吗? 如果要需要加一个事件
- } else {
- }
- }
- window.THREE = THREE
- //isLocal = false
- let autoLoads = /* window.autoLoads = */ []
- let readyToAddModel
-
- let mainBackground = viewer.background
- const units = { 1: 'metric', 2: 'imperial' }
- let getMeasureType = function (type, unit = 1) {
- let info
- switch (type) {
- case 'free':
- info = { measureType: 'Distance' }
- break
- case 'area':
- info = { measureType: 'Area' }
- break
- case 'vertical':
- info = { measureType: 'Ver Distance' }
- break
- default:
- console.error('无此 measure type')
- }
- info.unit = units[unit]
- return info
- }
- let getMeasureFunction = function (measure, bus) {
- measure.addEventListener('highlight', (e) => {
- if(measure.type == 'Path'){
- bus.emit(e.state ? 'enter' : 'leave')
- }else{
- bus.emit('highlight', e.state)
- }
-
- })
- let update = (e)=>{ //拖拽结束后发送changeCallBack
- if (measure.parent) {
- //未被删除
- console.warn('changePoints', measure.dataset_points.length )
- if(measure.type == 'Path'){
- bus.emit('changePoints', measure.dataset_points.map((p,i)=>{return {
- position: (p || measure.points[i]).clone(),
- modelId: measure.points_datasets[i] == void 0 ? Id_noIntersect : measure.points_datasets[i],
- name: measure.markerLabels[i].originText
- }}))
- }else{
- bus.emit('update', [
- measure.dataset_points.map(p => p.clone()),
- measure.points_datasets
- ])
- }
- }
- }
- measure.addEventListener('marker_dropped', update)
- measure.addEventListener('changed', update)
- measure.addEventListener('createDone', update)
- measure.addEventListener('changeByHistory', update);
-
- return {
- /* quit: () => {
- Potree.Log('quit结束且删除: ' + measure.id, '#00c7b2')
- viewer.dispatchEvent({ type: 'cancel_insertions', remove: true, measure })
- }, //触发结束。退出测量模式,清除之前操作 */
- destroy: () => {
- viewer.dispatchEvent({ type: 'cancel_insertions', remove: true, measure })
-
- viewer.scene.removeMeasurement(measure)
- },
- /* getPoints: () => {
- return measure.points
- },
- getDatasetLocations: () => {
- return measure.dataset_points
- },
- getDatasets: () => {
- return measure.points_datasets
- },
- getDatasetId: () => {
- return measure.datasetId
- }, */
- getArea: () => {
- return measure.area //{value:area, string:..}
- },
- getDistance: () => {
- if (measure.points.length < 2) return 0
- var value = measure.points[0].distanceTo(measure.points[1])
- return {
- value, //米
- string: measure.getConvertString(value, 'distance')
- }
- },
- //手动开启或关闭:
- show: () => {
- Potree.Utils.updateVisible(measure, 'inListByUser', true)
- },
- hide: () => {
- Potree.Utils.updateVisible(measure, 'inListByUser', false)
- },
- fly() {
- if(measure.type == 'Path') Potree.settings.displayMode = 'showPointCloud'
-
- let result = viewer.focusOnObject(measure, 'measure', 1200, {dontLookUp:measure.type == 'Path', maxDis: measure.fadeFar && measure.fadeFar*1.5})
-
- return result.msg ? result.msg : result.promise
- //返回值 1 deferred 表示即将位移 2 'posNoChange' 表示已在最佳位置 3 'tooFar' 表示距离最佳位置太远
- },
- changeSelect(isHight) {
- //console.log('2d->3d isHight ', isHight)
- measure.setSelected(isHight, 'byList')
- },
- }
- }
-
- let sdk = Potree.sdk = {
- sceneBus, mapBus,
-
-
- canTurnToPanoMode(pos, far=Potree.config.panoFieldRadius) {
- pos = pos ? new THREE.Vector3().copy(pos) : viewer.images360.position
- let pano = viewer.images360.findNearestPano(pos)
- if (pano && pano.position.distanceTo(pos) < far * pano.pointcloud.scale.x) {
- return {model:pano.pointcloud.result_}
- }
- //poschange后会调用这个,如果返回false会变为点云模式,且不会自动变回原先的模式
- },
-
-
-
- getPositionByScreen(pos2d, hopeModelId) {//通过屏幕坐标获取真实坐标 . hopeModelId: 如果指定了模型,优先返回hopeModelId上的intersect
- //console.log('getPositionByScreen',hopeModelId)
- hopeModelId = null
- let worldPos, localPos, modelId, intersect, normal, localNormal
- let Handler = viewer.inputHandler
- let reGet = () => {//不使用当前鼠标所在位置的intersect,单独算
- pos2d.clientX = pos2d.x
- pos2d.clientY = pos2d.y
- pos2d.onlyGetIntersect = true
- pos2d.whichPointcloud = true
- if (hopeModelId != void 0) {//隐藏其他的模型
- let models = MergeEditor.getAllObjects()
- models.forEach(model => {
- Potree.Utils.updateVisible(model, 'forPick', model.dataset_id == hopeModelId)
- })
- }
- let intersect2 = Handler.onMouseMove(pos2d)
- if (hopeModelId != void 0) {//恢复
- let models = MergeEditor.getAllObjects()
- models.forEach(model => {
- Potree.Utils.updateVisible(model, 'forPick', true)
- })
- }
- if (intersect2 && intersect2.location) {
- intersect = intersect2
- }
- }
- if (pos2d && pos2d.inDrag) {
- reGet()
- } else {
- intersect = Handler.intersect
- if (intersect) {
- modelId = intersect.pointcloud ? intersect.pointcloud.dataset_id : intersect.object.dataset_id
- if (hopeModelId != void 0 && modelId != hopeModelId) {
- reGet()
- }
- }
- }
- if (intersect && intersect.location) {
- modelId = intersect.pointcloud ? intersect.pointcloud.dataset_id : intersect.object.dataset_id
- /* if(hopeModelId != void 0 && modelId != hopeModelId){
- return null
- } */
- worldPos = intersect.location.clone()
- localPos = Potree.Utils.datasetPosTransform({ toDataset: true, datasetId: modelId, position: worldPos })
- normal = intersect.normal
- localNormal = intersect.localNormal
- } else return null
-
- return { worldPos, modelId, normal, localPos, localNormal }
- },
- getScreenByPosition(pos3d, modelId, canShelter/* , disToCameraLimit */) {//通过模型局部坐标获取屏幕坐标
- //console.log('getScreenByPoint ')
- let isLocal = modelId != void 0
- pos3d = new THREE.Vector3().copy(pos3d)
- let worldPos = isLocal ? Potree.Utils.datasetPosTransform({ fromDataset: true, datasetId: modelId, position: pos3d }) : pos3d
- if (!worldPos) return
- if (canShelter) {
- if (viewer.inputHandler.ifBlockedByIntersect(worldPos, 0.1, true)) return { trueSide: false };
- }
- var viewport = viewer.mainViewport
- var camera = viewport.camera
- var dom = viewer.renderArea
- /* if (tagLimitDis != void 0) {
- if (camera.position.distanceToSquared(worldPos) > Math.pow(tagLimitDis, 2)) return false
- } */
- //console.log('getScreenByPoint ' + pos3d.toArray())
- return Potree.Utils.getPos2d(worldPos, viewport, dom)
- },
- setCameraFov(fov) {
- viewer.setFOV(fov)
- },
-
- screenshot: (width, height/* , bgOpacity=0 */ ) => {//
- //截图
- let bgOpacity = Potree.settings.showCesium ? 0 : 1 /* viewer.background == 'skybox' */ //因为要画map底图所以上层只能透明。之后需要的话再改
-
- console.log('bgOpacity', bgOpacity)
-
- Potree.Utils.updateVisible(MergeEditor.boxHelper, 'screenshot', false)
- Potree.Utils.updateVisible(viewer.scene.overlayScene, 'screenshot', false) //hide all
-
-
- var { getImagePromise, finishPromise } = viewer.startScreenshot({ type: 'default', /* useRenderTarget:true, */bgOpacity }, width, height)
- var deferred = $.Deferred();
- finishPromise.done(({ dataUrl }) => {
- if(Potree.settings.displayMode != 'showPanos' && Potree.settings.showCesium){//need map background
- Potree.cesScreenshot(width, height).done((mapBGurl)=>{
- let img = new Image(); img.src = dataUrl
- let imgBG = new Image(); imgBG.src = mapBGurl
- let loadCount = 0
- img.onload = imgBG.onload = ()=>{
- loadCount++;
- if(loadCount == 2){
- let url = Potree.Common.imgAddLabel(imgBG,img,{leftRatioToImg:0,topRatioToImg:0})
- deferred.resolve(url)
- }
- }
- })
- }else{
- deferred.resolve(dataUrl)
- }
-
-
- Potree.Utils.updateVisible(MergeEditor.boxHelper, 'screenshot', true)
- Potree.Utils.updateVisible(viewer.scene.overlayScene, 'screenshot', true)
- })
- return deferred.promise()
- },
- getPose() {//获取当前点位和朝向
-
- const camera = viewer.scene.getActiveCamera()
- const target = viewer.scene.view.getPivot().clone()
- const position = viewer.scene.view.position.clone()
- const pose = { position, target, displayMode:Potree.settings.displayMode }
- if(Potree.settings.displayMode == 'showPanos'){
- let model = viewer.images360.currentPano.pointcloud
- pose.panoId = viewer.images360.currentPano.originID
- pose.model = model.result_
-
- pose.posInModel = Potree.Utils.datasetPosTransform({ toDataset: true, position: camera.position.clone(), object:model })
- pose.rotInModel = Potree.Utils.datasetRotTransform({ toDataset: true, quaternion: camera.quaternion.clone(), getQuaternion: true, pointcloud:model }).toArray() //拿第一个数据集
-
- }
-
- //console.log('getPose',position, target)
- return pose
- },
- comeTo(o = {}) {
- //console.log('comeTo',o.position, o.target)
- //飞到某个点
-
- let deferred = $.Deferred()
- if(o.panoId != void 0){
- let model = o.model.model
- let pano = model.panos.find(a=>a.originID == o.panoId)
- if(pano){
- o.rotInModel = new THREE.Quaternion().fromArray(o.rotInModel)
- let quaternion = Potree.Utils.datasetRotTransform({ fromDataset: true, quaternion: o.rotInModel, getQuaternion: true, object:model})
- o.model.flyInPano(pano, {quaternion, duration:0, callback(){
- o.callback && o.callback()
- deferred.resolve(true)
- }})
- return deferred.promise()
-
- }else{
- console.warn('没有找到漫游点',o)
- }
- }/* else if(requestInPano){
- requestInPano.result_.flyOutPano()
- } */else{
- if (o.modelId != void 0) {
- ['position', 'target'].forEach(e => {
- if (o[e]) {
- o[e] = Potree.Utils.datasetPosTransform({ fromDataset: true, datasetId: o.modelId, position: o[e] })
- }
- })
- }
- }
-
-
- if (o.distance || o.maxDis) {
- //o.isFlyToTag = true
- let requestShowPano
- let position = o.target || o.position
- if(o.isFlyToTag){
- let r = sdk.canTurnToPanoMode(position, 5)//热点新需求:如果附近有漫游点就飞到全景模式
- if(r){
- requestShowPano = true
- }else{
- Potree.settings.displayMode = 'showPointCloud'
- }
- }
- let rusult = viewer.focusOnObject({ position }, 'tag', null, { distance: o.distance || 1, maxDis : o.maxDis, requestShowPano /* , checkIntersect:true */ })
- rusult.promise.then(()=>{
- if(o.isFlyToTag){
- Potree.settings.displayMode = requestShowPano ? 'showPanos' : 'showPointCloud'
- }
-
- })
- return rusult.promise
-
- }
-
- viewer.scene.view.setView($.extend({}, o, {
- duration: o.dur,
- callback: () => {
- o.callback && o.callback()
- deferred.resolve(true)
- }
- }))
- return deferred.promise()
- },
- setBackdrop(sky, type, { scale, rotate }={}) {//天空盒背景
- //console.log('天空盒背景', sky,type)
- let setGroundAndText = (color) => {
- MergeEditor.secondCompass.dom.find(".dirText").css({ 'color': color })
- viewer.compass.dom.find(".dirText").css({ 'color': color })
- MergeEditor.ground.material.uniforms.uColor.value.set(color)
- //MergeEditor.ground.children[0].material.color.set(color)
- }
- viewer.dispatchEvent('content_changed')
-
-
- if(type == 'map'){
- MergeEditor.setGroundPlaneImg(null)
- viewer.setBackground(mainBackground)
- Potree.settings.showCesium = true
- buildMap()
- viewer.backgroundOpacity = 0
- return
- }else{
- Potree.settings.showCesium = false
- }
- if (type == 'bimg') {//地面图
- MergeEditor.setGroundPlaneImg(sky, scale, rotate)
- setGroundAndText('#e0e0e0')
- viewer.setBackground(mainBackground)
- } else {
- MergeEditor.setGroundPlaneImg(null)
- if (sky == 'none') {
- viewer.setBackground(mainBackground)
- setGroundAndText('#eee')
- } else if (sky[0] == '#') {
- viewer.setBackground(new THREE.Color(sky))
- let color = sky == '#fff' ? '#666' : sky == '#333' ? '#eee' : '#bbb' //反相
- setGroundAndText(color)
- } else if (type == 'image-map' || type == 'vector-map') {//影像|矢量 地图
- } else {//环境
- sky = ossRoot + sky
- viewer.setBackground('skybox', sky)
- setGroundAndText('#e0e0e0')
- }
- }
-
- },
- /* switchMapType(type) {
- let map = viewer.mapViewer.mapLayer.maps.find(e => e.name == 'map')
- map.switchStyle(type )
- }, */
- switchMapType(type){//切换成江门的卫星或标准
- if(window.location.href.includes('localhost:7173')/* || Potree.browser.urlHasValue('testMap') */ ) return
- console.log('switchMapType',type)
- let maximumLevel, url
- if(type == 'satellite'){
- maximumLevel = 18
- url = "//a.map.jms.gd/tile/weixing/{z}/{x}/{y}.png"
- }else{
- maximumLevel = 19
- url = "//a.map.jms.gd/tile/gd_xiangtu/{z}/{x}/{y}.png"
- }
- cesImageryProvider = new Cesium.UrlTemplateImageryProvider({ //直接用84坐标,不用转高德
- url,
- crossOrigin: 'anonymous',
- minimumLevel: 0,
- maximumLevel,
- tilingScheme: new AmapMercatorTilingScheme(), //修改投影,从84->高德
- })
- if(Potree.settings.showCesium){
- cesiumViewer.imageryLayers.removeAll();
- cesiumViewer.imageryLayers.addImageryProvider(cesImageryProvider);
- }
- },
-
-
- enableMap(mapArea, latlng) {
- if (!viewer.mapViewer) {
- //--------------------------------
- viewer.mapViewer = new Potree.MapViewer(mapArea)
- viewer.mapViewer.initProjection()
- //focus
- let boundSize = new THREE.Vector3(200, 150, 1).max(viewer.bound.boundSize)
- viewer.mapViewer.addEventListener('viewerResize', () => {
- viewer.mapViewer.moveTo(viewer.bound.center, boundSize, 0)
- }, { once: true })
- }
- },
- enterSceneGuide(pathArr) {//导览 (不需要修改参数)
- let editor = viewer.modules.CamAniEditor
- console.log('pathArr', pathArr)
-
- //console.log('enterSceneGuide',pathArr)
- pathArr.forEach(e=>{
- if(e.panoId != void 0){
- e.model = e.model.model
- }
- })
- let data = {
- //duration: pathArr.slice(0, pathArr.length - 1).reduce(function (total, currentValue) { return total + currentValue.time }, 0), //总时长(要去掉最后一个,因为已到终点,该点time无意义)
- points: pathArr,
- useDurSlice: true
- }
-
-
-
- let ani = editor.createMulAnimation(data)
-
-
- //注:最多只存在一条导览
- let bus = mitt()
- //播放完成
- ani.event_.addEventListener('playDone', () => {
- bus.emit('playComplete')
- viewer.images360.panos.forEach(e=>e.marker && Potree.Utils.updateVisible(e, 'playAni', true))
- })
- //切换点
- ani.event_.addEventListener('updateCurrentIndex', e => {
- bus.emit('changePoint', e.currentIndex + 1)
- })
- return {
- bus,
- play() {
- MergeEditor.selectModel(null)
- viewer.images360.panos.forEach(e=>e.marker && Potree.Utils.updateVisible(e, 'playAni', false))
- ani.play()
- },
- pause() {
- viewer.images360.panos.forEach(e=>e.marker && Potree.Utils.updateVisible(e, 'playAni', true))
- ani.stop()
- },
- clear() {
- ani.remove()
- },
- }
- },
- //[path1, paht2], { time, speed }
- calcPathInfo(paths, info) { //传入的time, speed仅有一个。返回完整的 time, speed
- //这一版的control似乎无法在某个位置上改变角度,位置和角度一般都是一起变的,所以先不增加单位更换功能。
- let pos1 = new THREE.Vector3().copy(paths[0].position)
- let pos2 = new THREE.Vector3().copy(paths[1].position)
- let dis = pos1.distanceTo(pos2)
- if (info.time != void 0) {
- info.speed = dis / info.time
- } else {
- info.time = dis / info.speed
- }
- return info
- },
- addModel(props) {
- let model
- let bus = props.bus = mitt()
- //console.log('--addModel',props)
- props.isFirstLoad = isLocal ? props.bottom == void 0 : (props.isDynamicAdded || props.mode == 'single') // 在编辑时用户添加的 或 展示单个模型 (props.mode='single'模型展示页, props.mode='many'融合页)
- if (props.opacity == void 0) props.opacity = 100
- //if (props.type == 'obj') props.type = 'glb'
- props.scale && (props.scale /= 100)
-
- let getBaseRotation = () => {
- if(ModelTypes[props.fromType]?.rot90 && props.type != 'obj'){
- return new THREE.Euler(Math.PI / 2, 0, 0)
- } else return new THREE.Euler(0, 0, 0)
- }
- let getDefaultRotation = () => {
- if(model.lonLatRot){
- return model.lonLatRot
- }else{
- return getBaseRotation()
- }
- }
-
- if (props.rotation) {
- if (props.rotation._x == void 0 && props.rotation.x != void 0) {
- props.rotation = new THREE.Euler().setFromVector3(props.rotation)
- }
- }
- props.baseRotation = getBaseRotation()
-
- props.is4dkkModel = ModelTypes[props.fromType].panos4dkk
-
-
- if (!props.isFirstLoad) {
- if (autoLoads.length == 0) { //首次加载
- setTimeout(() => {
- let sizes = autoLoads.map(e => e.size || 0)
- console.log('需要请求加载的模型大小为', sizes, '总大小', sizes.reduce(function (total, currentValue) {
- let current = parseFloat(currentValue)
- return total + ((typeof currentValue == 'number' || currentValue.includes('M')) ? current : current / 1024)
- }, 0))
- readyToAddModel = true //准备开始加载
- loadNext()//startLoad(autoLoads[0])
- }, 30)
- }
- autoLoads.push(props)
- readyToAddModel = false
- } else {
- readyToAddModel = true
-
- }
-
-
-
-
- let done = (model_) => {
- model = model_
- model.result_ = result
- model.props = props
- result.model = model
- model.fromType = ModelTypes[props.fromType].name
- if (!props.isFirstLoad) {
- model.visible = false//先不显示,防止卡顿
- }
- model.showInPano = /* !model.is4dkkModel// */props.raw.showInPano //现在不用这个,所有模型都可见,非is4dkkModel的还显示原本的贴图
- props.opacity < 100 && result.changeOpacity(props.opacity)
- model.addEventListener('changeSelect', (e) => {
- bus.emit('changeSelect', e.selected)
- })
- let lastState = {}
- model.addEventListener('transformChanged', (e) => {
- let msg = {byControl:!!e.byControl} //byControl代表是手动用控制轴修改 动画文件要改帧
- if (!lastState.position || !model.position.equals(lastState.position)) {
- lastState.position = msg.position = model.position.clone()
- //console.log('change pos', model.name, model.position.toArray())
- }
- if (!lastState.rotation || !model.rotation.equals(lastState.rotation)) {
- lastState.rotation = msg.rotation = model.rotation.clone()
- }
- if (lastState.scale == void 0 || model.scale.x * 100 != lastState.scale) {
- lastState.scale = msg.scale = model.scale.x * 100
- }
- msg = Potree.Common.CloneObject(msg)
- //console.log(model.name, msg)
- bus.emit('transformChanged', msg)
- })
- spliceFromArr(model, props, true)
-
- model.addEventListener('changeSelect', (e) => {
- MergeEditor.transformControls.visible && e.selected && MergeEditor.transformControls.attach(model, e.clickPos) //: MergeEditor.transformControls.detach()
- })
- MergeEditor.modelAdded(model)
-
-
-
- if (props.mode == 'single') {//模型查看页
- MergeEditor.noNeedSelection = true
- setTimeout(() => {
- MergeEditor.focusOn([model], 1000, true, true)
- }, 1)
- }
- if(ModelTypes[props.fromType].panos4dkk){
- Potree.load4dkkPanos(props.raw.num, model, getBaseRotation(), () => {
- bus.emit('loadDone',model)
- }, props.fromType == 0 ? '2k' : '4k' ) //看看场景是2k
- } else {
- bus.emit('loadDone',model)
- }
- //console.log('loadDone' )
- }
- let progressFun = (progress) => {
- bus.emit('loadProgress', progress)
- }
- let onError = function (xhr) {
- bus.emit('loadError', xhr)
- console.log('loadError!!!!!!!!!', Potree.Common.getNameFromURL(props.url), props.size, xhr)
- spliceFromArr(model, props, false)
- }
- //try {
- // props.url = JSON.parse(props.url) //去掉 '\'
-
- /* if(props.modelType != 'pointcloud' ){//当前本地版这么写
- let addPrefix = (e)=> Potree.settings.urls.getPrefix(3,props) + '/profile'+ e
- if(props.url instanceof Array){
- props.url = props.url.map(e=>addPrefix(e))
- }else{
- props.url = addPrefix(props.url)
- }
- } */
-
- //} catch (e) { }
- props.raw.panoRoot = props.raw.panoOSSRoot + (props.raw.mapping?('/'+props.raw.mapping):'')
- props.done = done; props.progressFun = progressFun; props.onError = onError
- if (readyToAddModel) {
- if (autoLoads.filter(e => e.loading).length < maxLoadingCount) {
- startLoad(props)
- }
- }
-
- let scaleMeasure
- let result = {
- bus,
- model,
- getDefaultRotation,
- supportPano() { //是否支持全景图
- return model?.panos?.length > 0
- },
- flyInPano(pano, {dontFly, quaternion, duration}={}) {// 飞入全景图
- requestInPano = model
- pano = pano || viewer.images360.findNearestPano(null, model.panos)
- if (pano) {
- dontFly || viewer.images360.flyToPano({ pano, canCancelLast: true, quaternion, duration})
- Potree.settings.displayMode = 'showPanos'
-
- }
- },
- flyOutPano() {// 飞出全景图(就是切换到正常融合视角)
- requestInPano = false
- Potree.settings.displayMode = 'showPointCloud'
- /* setTimeout(() => {//在下一帧再变,因为3dtiles需要更新一下才会显示tiles
- if (!requestInPano) {
- Potree.settings.displayMode = 'showPointCloud'
- Potree.Utils.updateVisible(MergeEditor.boxHelper, 'showPanos', true)
- }
- }, 50) */
-
- },
- changeShow(show) {
- props.show = show //for autoLoads show model
- if (model) {
- Potree.Utils.updateVisible(model, 'datasetSelection', show)
- if (model.panos) {
- model.panos.forEach(e => e.setEnable(show))
- }
- viewer.dispatchEvent('content_changed')
- }
- },
- changeSelect(state) {
- //console.error('select', state)
- if (model) {
- let fly = viewer.images360.latestRequestMode != 'showPanos'
- MergeEditor.selectModel(model, state, fly, true)
- updateCamNear()
-
- //console.log('changeSelect', props.id, state)
- }
- },
- changeScale(s) {
- if (model) {
- s /= 100
- if (model.scale.x == s) return
- //MergeEditor.history.beforeChange(model)//但不知道什么时候结束拖拽
- model.scale.set(s, s, s)
- model.isPointcloud && model.changePointSize(/* Potree.config.material.realPointSize * s */)
- model.dispatchEvent("scale_changed")
-
- }
- },
- changeOpacity(opacity) { //见笔记:透明物体的材质设置
- if (opacity == void 0) opacity = 100
- opacity /= 100
- MergeEditor.changeOpacity(model, opacity)
- },
- changeBottom(z) {
- /* model && MergeEditor.setModelBtmHeight(model,z)
- model.dispatchEvent('transformChanged') //改了position */
- },
- changePosition(pos) {//校准取消时执行
- //console.log('changePosition', model.name, pos.x, pos.y, pos.z)
- if(pos.x == 0 && pos.y == 0 && pos.z == 0 && model.lonLatPos ){
- model && model.position.copy(model.lonLatPos)
- console.log('changePosition 使用经纬度坐标', model.name )
- }else{
- model && model.position.copy(pos)
- }
- model.dispatchEvent({ type: 'position_changed' })
- },
- changeRotation(rot) {//校准取消时执行
- //console.log('changeRotation', model.name, rot.x, rot.y, rot.z)
- /* if(rot.x == 0 && rot.y == 0 && rot.z == 0 && model.lonLatRot ){
- model && model.rotation.copy(model.lonLatRot)
- console.log('changePosition 使用经纬度坐标', model.name )
- }else{ */
- model && model.rotation.setFromVector3(rot)
- //}
- model.dispatchEvent({ type: 'rotation_changed' , by2d:true})
- },
- enterRotateMode() {
- if (model) {
- if (MergeEditor.split) {//分屏校准
- MergeEditor.setTransformState('rotate')
- MergeEditor.transformControls2.attach(model)
- MergeEditor.transformControls2.mode = 'rotate'
- }
- MergeEditor.transformControls.attach(model)
- MergeEditor.transformControls.mode = 'rotate'
- }
- },
- enterMoveMode() {
- console.log('enterMoveMode')
- if (model) {
- if (MergeEditor.split) {//分屏校准
- MergeEditor.setTransformState('translate')
- MergeEditor.transformControls2.attach(model)
- MergeEditor.transformControls2.mode = 'translate'
- }
- MergeEditor.transformControls.attach(model)
- MergeEditor.transformControls.mode = 'translate'
- }
- },
- leaveTransform() {
- console.log('leaveTransform')
- if (MergeEditor.split) {//分屏校准
- MergeEditor.setTransformState(null)
- } else {
- MergeEditor.transformControls.detach()
- MergeEditor.transformControls2.detach()
- }
- MergeEditor.history.clear()
- },
- enterAlignment() {//开始校准
- result.leaveTransform()
- MergeEditor.enterSplit()
- if(Potree.settings.showCesium){
- cesiumViewer.scene.canvas.style.width = '50%'
- //cesiumViewer.resize()
- }
- let bus = new mitt()
- return {
- bus
- }
- },
- leaveAlignment() {
- //console.log('leaveAlignment',model.position, model.rotation)
- MergeEditor.leaveSplit()
- MergeEditor.transformControls.detach()
- MergeEditor.transformControls2.detach()
- if(Potree.settings.showCesium){
- cesiumViewer.scene.canvas.style.width = ''
- updateMap()
- }
- },
- enterScaleSet() {//设置比例
- let bus = new mitt()
- let length, measureBuilded;
- //viewer.outlinePass.selectedObjects = []
- if (!Potree.Utils.isInsideFrustum(model.boundingBox.clone().applyMatrix4(model.matrixWorld), viewer.scene.getActiveCamera())) {
- MergeEditor.focusOn(model, 600)
- }
- MergeEditor.getAllObjects().forEach(m => {//隐藏其他的模型
- if (m != model) Potree.Utils.updateVisible(m, 'enterScaleSet', false)
- })
- result.oldFar = Potree.settings.cameraFar
- model.enterScaleOldState_ = {
- //view: viewer.mainViewport.view.clone(),
- scale: model.scale.x,
- far: Potree.settings.cameraFar
- }
-
-
-
- let setScale = () => {
- if (length == void 0 || !measureBuilded) return
- let vec = new THREE.Vector3().subVectors(viewer.mainViewport.camera.position, scaleMeasure.points[1])
- let dis = scaleMeasure.points[0].distanceTo(scaleMeasure.points[1])
- let s = length / Math.max(dis,0.00001)
- result.changeScale(model.scale.x * s * 100)
- /* setTimeout(()=>{
- viewer.focusOnObject(scaleMeasure , 'measure', 500)
- },1) */
- let newCamPos = new THREE.Vector3().addVectors(scaleMeasure.points[1], vec.multiplyScalar(s))
- viewer.scene.view.setView({
- position: newCamPos, target: scaleMeasure.getCenter(), duration: 0, callback: () => {
- //更改target到measure中心的好处就是可以让相机绕measure中心转,坏处是每次更改都会变一下画面
- //Potree.settings.cameraFar = Math.max(model.enterScaleOldState_.far, viewer.scene.view.position.distanceTo(model.boundCenter) + model.boundingBox.clone().applyMatrix4(model.matrixWorld).getSize(new THREE.Vector3).length())
- //use updateCamFar()
- }
- })
-
- }
- return {
- bus,
- setLength(v) {
- if (!v) return
- length = v
- setScale()
- },
- startMeasure() {
- if (scaleMeasure) {
- viewer.dispatchEvent({ type: 'cancel_insertions', remove: true, measure: scaleMeasure })
- viewer.scene.removeMeasurement(scaleMeasure)
- }
- measureBuilded = false
- scaleMeasure = viewer.measuringTool.startInsertion(
- { measureType: "Distance", unit: "metric" },
- () => {
- //done:
- //bus.emit('end' ) //完成
- measureBuilded = true
- setScale()
- },
- () => {
- //cancel
- //bus.emit('quit') //删除
- }
- )
- scaleMeasure.forbitRepeatPoint = true //两个点不能相同,否则长度是0
- scaleMeasure.addEventListener('marker_dropped', (e) => {//拖拽结束后发送changeCallBack
- if (scaleMeasure.parent) {
- //未被删除
- measureBuilded && setScale()
- }
- })
- }
- }
- },
- leaveScaleSet() {
- if (scaleMeasure) {
- viewer.dispatchEvent({ type: 'cancel_insertions', remove: true, measure: scaleMeasure })
- viewer.scene.removeMeasurement(scaleMeasure)
- scaleMeasure = null
- }
- //viewer.outlinePass.selectedObjects = [model];
- MergeEditor.getAllObjects().forEach(m => {//恢复其他的模型
- if (m != model) Potree.Utils.updateVisible(m, 'enterScaleSet', true)
- })
-
- setTimeout(()=>{//可能还原了 相机位置移动回去
- if(model.scale.x == model.enterScaleOldState_.scale){
- MergeEditor.focusOn(model, 0) //reset orbitcontrol's minRadius //viewer.mainViewport.view.copy(model.enterScaleOldState_.view)
- //Potree.settings.cameraFar = model.enterScaleOldState_.far
- }
- },10)
-
-
- },
- destroy() {
- model && MergeEditor.removeModel(model)
- result.changeSelect(false)
- viewer.dispatchEvent('content_changed')
- }
- }
- return result
- },
- //测量线的点都附着于各个模型,当模型变化时,点跟着变化。
- // 新的测量创建方法,传入type 返回新测量对象
- startMeasure(type) {
- // 寻创建的测量对象有上面绘画测量对象的所有方法
- const bus = mitt()
- let info = getMeasureType(type)
- let measure = viewer.measuringTool.startInsertion(
- info,
- () => {
- //done:
- bus.emit('submit')
- },
- () => {
- //cancel
- bus.emit('cancel'/* , ret */) //删除
- }
- )
- Potree.Log('startMeasure: ' + measure.id, '#00c7b2')
- /* let cancel = ()=>{
- Potree.Log('clear删除: ' + measure.id, '#00c7b2')
- viewer.dispatchEvent({ type: 'cancel_insertions', remove: true, measure })
- viewer.scene.removeMeasurement(measure)
- } */
- let result = {
- bus,
- ...getMeasureFunction(measure, bus),
- }
- /* StartMeasure = Measure & {
- // 多了cancel 取消测量的事件,没有参数
- // 多了invalidPoint 当用户测量了无效点时的事件,抛出无效原因
- bus: Emitter<{ cancel: void; invalidPoint: string }>
- } */
- return result
- },
- // 绘画测量线(非新增使用)
- // type = 'free' (自由) || 'vertical' (垂直) || 'area' (面积)
- // positions 点数组 构成如下 [{ point: {x,y,z}, modelId: 1 }]
- drawMeasure(type, dataset_points, points_datasets) {
- // 返回测量对象有如下
- const bus = mitt()
- let info = getMeasureType(type /* , unit */)
- //info.points = positions
- info.dataset_points = dataset_points
- info.points_datasets = points_datasets
- //info.sid = sid
- info.bus = bus
- let measure = viewer.measuringTool.createMeasureFromData(info)
- if (!measure) return { bus }
- Potree.Log('drawMeasure由数据新建: ' + measure.id, '#00c7b2')
- let result = {
- bus,
- setPositions(dataset_points, points_datasets) {//用于恢复measure的点,不会修改点的个数
- measure.dataset_points = dataset_points.map(e => {
- return e && new THREE.Vector3().copy(e)
- })
- measure.points_datasets = points_datasets
- measure.points = measure.dataset_points.map((p, i) => {
- return Potree.Utils.datasetPosTransform({ fromDataset: true, datasetId: measure.points_datasets[i], position: p })
- })
- measure.getPoint2dInfo(measure.points)
- measure.update({ ifUpdateMarkers: true })
- measure.setSelected(false)//隐藏edgelabel
- },
- ...getMeasureFunction(measure, bus),
- }
- return result
- },
- /* export type PathProps = {
- // 线段名称
- name: string,
- // 是否显示名称,
- showName: boolean,
- // 文字大小
- fontSize: number,
- // 是否显示方向,
- showDirection: boolean,
- // 方向是否反向
- reverseDirection: boolean,
- line: {
- width: number,
- color: string,
- altitudeAboveGround: number
- position: SceneLocalPos,
- normal: SceneLocalPos,
- modelId: string
- },
- points: {
- // 点位名称
- name: string,
- position: SceneLocalPos,
- modelId: string,
- }[]
- }
-
-
-
-
- bus: Emitter<{
- // 标注点击事件
- click: void;
- // 鼠标移入标注事件
- enter: void;
- // 鼠标移出标注事件
- leave: void;
- // 线段坐标更改事件
- linePositionChange: {
- pos: SceneLocalPos,
- normal: SceneLocalPos,
- modelId: string
- }
- // 路径点位置变更
- changePoints: PathProps['points']
- // 距离相机位置变更
- toCameraDistanceChange: number
- }>;
-
-
-
-
-
- */
- createPath(props){//路线
-
- //console.log('createPath', props)
- let bus = mitt()
-
-
- let path
- let info = {type : 'Path', minMarkers : 2, title:props.name, lineHeight : props.line.altitudeAboveGround }
-
-
- if(props.points.length == 0){
- path = viewer.measuringTool.startInsertion( info, () => {
- bus.emit("drawed" ); //完成
- })
- viewer.dispatchEvent({ type: 'cancel_insertions', dontRemove: true, measure:path }) //要等进入编辑才能继续编辑
- }else{
-
- let originPointCount = props.points.length
- props.points = props.points.filter(e=> isValidPoint(e.modelId))
- info.points_datasets = props.points.map(e=> e.modelId == Id_noIntersect ? null : e.modelId)
- info.dataset_points = info.points = props.points.map(e=>e.position)//当该点不在任何模型上时,记录的是世界坐标,所以两个都赋值,过后根据有无datasetID选择
-
- path = viewer.measuringTool.createMeasureFromData(info);
-
- if(props.line.position) {
- if(isValidPoint(props.line.modelId)){
- let pos = props.line.modelId == Id_noIntersect ? new THREE.Vector3().copy(props.line.position) :
- Potree.Utils.datasetPosTransform({fromDataset:true, position: props.line.position, datasetId: props.line.modelId })
- path.updateTitlePos(pos)
- }else{
- console.log('path label pos 因模型被删而去除', info.title )
- }
- }
- if(props.points.length < originPointCount ) {
- path.dispatchEvent('createDone')
- console.log('path点因模型被删减少', info.title, originPointCount,'->',props.points.length)
- }
-
- }
- {
- let curSelectMarker
- path.addEventListener('markerSelect',(e)=>{
- let msg
- if(e.cancel){
- curSelectMarker == e.marker && (msg = -1) //是当前选中的marker就取消
- }else{
- curSelectMarker = e.marker
- msg = path.markers.indexOf(e.marker)
- }
- //msg != void 0 && console.log('msg',msg)
- msg != void 0 && bus.emit('activePoint', msg )
- })
- path.addEventListener('titlePosChanged',(e)=>{
- //console.log('titlePosChanged',path.title, e.position.clone())
- bus.emit('linePositionChange', {
- modelId: e.root ? e.root.dataset_id : Id_noIntersect,
- pos: e.root ? Potree.Utils.datasetPosTransform({toDataset:true, position: e.position.clone(), datasetId: e.root.dataset_id }) : e.position.clone()
- })
- })
-
- path.addEventListener('chose',(e)=>{
- switchSelect(e.state)
- bus.emit('focus', e.state)
- })
-
- }
- let funs = getMeasureFunction(path, bus)
-
- let switchSelect = (state)=>{//切换选择,最多一个选中
- if(state){
- curSelectPath && curSelectPath.setSelected('unclick' ) //取消上一个选中的
- curSelectPath = path
- }else{
- curSelectPath == path && (curSelectPath = null)
- }
- }
- let functions = Object.assign(funs,{
- bus,
- path,
- changeEditMode(state){//进入编辑
- if(!state){
- viewer.dispatchEvent({ type: 'cancel_insertions', dontRemove: true, measure:path })
- }
- path.setEditEnable(state)
- },
-
- changeCanEdit(state){//是否点击pen图标以加点和删点
- if(state){
- if(path.points.length < 2){//继续绘制
- info.resume = true, info.measure = path
- path = viewer.measuringTool.startInsertion( info, () => {
- bus.emit("drawed" ); //完成
- })
- }
- }else{
- viewer.dispatchEvent({ type: 'cancel_insertions', dontRemove: true, measure:path })
- }
- console.log('changeCanEdit',state)
- path.setAddOrRemPoint(state)
- },
- visibility(v){
- //console.log('visibility', path.title, v)
- Potree.Utils.updateVisible(path,'user', v)
- },
- visibilityName(v){
- path.setTitleVisi(path.titleLabel.parent, v, 'user')
- },
- changeName(name){
- path.setTitle(name)
- },
- changePointName(index,name){
- path.setMarkerTitle(index, name)
- },
- changePathPoints(points){
- console.log('changePathPoints??????????',points)
- },
- deletePoint(index){
- path.removePoint(index)
- },
- changeFontSize(fontsize){
- path.setFontSize(fontsize)
- },
- changeLine({width,color,altitudeAboveGround}){
- path.setPathWidth(width)
- path.setColor(color)
- path.setLineHeight(altitudeAboveGround)
- },
- changeVisibilityRange(far){//设置消失距离
- path.setFadeFar(far== -1 ? 0 : far)
- },
- highlight(state){
- path.setSelected(state?'hover':'unhover', true)
- },
- focus(state){
- switchSelect(state)
- path.setSelected(state?'click':'unclick', true)
- },
- changeDirection(show,reverse){
- path.setArrowDisplay(show)
- path.setReverse(reverse)
- },
- createAni(tension){
- let distance = path.totalLength
- let pathPoints = path.points.map(e=>e.clone().add(new THREE.Vector3(0,0,1.5))) //在地面之上一定高度
- if(path.reverse) pathPoints.reverse()
-
-
- const speed = 3, //m/s
- turnDisPerRad = 1.5,
- maxTurnDis = 3,//拐弯最大距离
- maxRoadTurnRatio = 0.8 //每段路单次转弯最大比例,防止拐弯占据一整条路直到下一个点
- let roadLens = []
- let vecs = pathPoints.map((p,i)=>{
- if(i==0)return
- let last = pathPoints[i-1]
- roadLens.push(p.distanceTo(last))
- return new THREE.Vector3().subVectors(p,last).normalize()
- })
- let turnDis = vecs.map((vec,i)=>{//在每个转折点拐弯前后需要的米数
- if(i==0 || i==vecs.length-1)return 0
- let next = vecs[i+1]
- let angle = next.angleTo(vec)
- return Math.min(turnDisPerRad * angle / 2, maxTurnDis )
- })
- let points = []
- let len = pathPoints.length
- for(let i=0;i<len;i++){
- let thisPoint = pathPoints[i]
- let nextPoint = pathPoints[i+1]
- if(i==0 || i==len-1){//首尾的点直接加入,其他点不加
- points.push({
- position: thisPoint.clone(),
- target: i==0 ? nextPoint.clone() : pathPoints[len-1].clone().add(vecs[len-1])
- })
- }
-
- if(i<len-1){ //加入每段边要加入的两个(or一个)拐点 ,拐点之间方向沿着路径
- let turnDis1 = Math.min(turnDis[i], roadLens[i] * maxRoadTurnRatio)
- let turnDis2 = Math.min(turnDis[i+1], roadLens[i] * maxRoadTurnRatio)
- let turnDisSum = turnDis1 + turnDis2 //两端拐弯距离之和。
-
- if(turnDisSum > roadLens[i]){//如果超过了路长度, 该条路就只有一个拐点
- turnDis1 = turnDis1 / turnDisSum * roadLens[i]
- let p = thisPoint.clone().add(vecs[i+1].clone().multiplyScalar(turnDis1))
- points.push({position: p, target: nextPoint.clone()})
- }else{
- if(turnDis1>0){ //i==0时为0
- let turnPoint1 = thisPoint.clone().add(vecs[i+1].clone().multiplyScalar(turnDis1))
- points.push({position: turnPoint1, target: nextPoint.clone()})
- }
- if(turnDis2>0){//i==len-2时为0
- let turnPoint2 = nextPoint.clone().sub(vecs[i+1].clone().multiplyScalar(turnDis2))
- points.push({position:turnPoint2, target: nextPoint.clone()})
- }
- }
- }
- }
- //加后缀&test以看路线
-
- let data = {
- name : 'path_guideTour',
- duration : distance / speed,
- points,
- tension
-
- }
- path.animation_ = viewer.modules.CamAniEditor.createAnimation(data)
- },
-
-
- play(playDone){
- if(path.points.length < 2)return playDone && playDone() //no points
-
-
- let oldStates = {
- editEnable: path.editEnable,
- addOrRemovePoint: path.addOrRemovePoint
- }
- path.editEnable && functions.changeEditMode(false)
- path.addOrRemovePoint && path.setAddOrRemPoint(false)
-
- if(Potree.settings.pathSmooth){
- let curve = path.curve.clone();
- curve.points.forEach(e=>e.z += 2)
-
- if(path.reverse) curve.points.reverse()
-
-
- //let geoPoints = path.geoPoints.map(e=> e.clone().add(new THREE.Vector3(0,0,2)) )//height
- let duration = path.totalLength / 3
- //let tangentDt = path.totalLength * 0.0001
- path.animation_ = viewer.modules.CamAniEditor.createCurveAni(curve, duration )
- }else{
- functions.createAni();//不传参数时路径最圆润缓和,但会脱离原路径。传参后除了拐弯都按路径,参数越大越圆润,但容易有折回的bug。 如果没有严格要求就不传参效果最佳。
- }
- path.animation_.play()
- path.animation_.addEventListener('playDone', () => {
- oldStates.editEnable && functions.changeEditMode(true)
- oldStates.addOrRemovePoint && path.setAddOrRemPoint(true)
- playDone && playDone()
- },{once:true})
- },
- pause(){
- path.animation_?.pause()
- path.animation_ && viewer.modules.CamAniEditor.removeAnimation(path.animation_)
- path.animation_ = null
- }
-
- })
-
-
- /* for(let i in functions){
- if(functions[i] instanceof Function){
- let oldFun = functions[i]
- functions[i] = function(){
- console.warn('path', i, path.title, ...arguments)
- oldFun.apply(this, arguments)
- }
- }
- } */
-
- path.functions = functions
-
- props.line && functions.changeLine(props.line)
-
-
- return functions
-
-
-
-
- },
- startAddSth(){//开始添加热点
- Potree.settings.disableClick = true //禁止点击事件,尤其是全景模式下,否则会走到下一个点
- viewer.dispatchEvent('start_inserting_tag')
- },
- endAddSth(){
- Potree.settings.disableClick = false
- viewer.dispatchEvent('endTagMove')
- },
- createTagging(props){
- let bus = mitt()
-
- //console.warn('createTagging', props)
- let root = viewer.scene.pointclouds.concat(viewer.objs.children).find(e=>e.dataset_id == props.modelId)
- if(!root){
- return console.error('热点没有找到该modelId,模型是否已经删除?')
- }
-
- let info = {
- position: new THREE.Vector3().copy(props.position), //局部坐标
- normal: props.normal ? new THREE.Vector3().copy(props.normal) : new THREE.Vector3(0,0,1),
- root, lineLength: props.altitudeAboveGround,
- title: props.title, fontsize: props.fontSize
- }
- let tag = viewer.tagTool.createTagFromData(info)
-
-
- tag.addEventListener('mouseover',()=>{
- bus.emit('enter')
- })
- tag.addEventListener('mouseleave',()=>{
- bus.emit('leave')
- })
- tag.addEventListener('click',()=>{
- bus.emit('click')
- })
- tag.addEventListener('posChanged',(e)=>{
- bus.emit('changePosition', {
- modelId: tag.root.dataset_id,
- normal: tag.normal.clone(),
- pos: tag.position.clone()
- })
- })
-
-
-
- tag.functions = {
- bus,
- changeType(type){
- //console.log('changeType', tag.title, type)
- let onMesh = type == '3d'
- if(tag.onMesh != onMesh){
- tag.changeOnMesh(onMesh)
- }
- },
- visibility(v){// 标注可见性
- //console.log('visibility', tag.title, v)
- Potree.Utils.updateVisible(tag,'user', v)
- viewer.dispatchEvent('content_changed')
- },
- visibilityTitle(v){
- tag.setTitleVisi(v, 'user')
- },
- changePosition({modelId,position,normal}){
- let root = viewer.scene.pointclouds.concat(viewer.objs.children).find(e=>e.dataset_id == props.modelId)
- tag.changePos({root,position,normal})
- },
- changeImage(url){
- tag.changeMap(ossRoot + '/' +url)
- },
- changeTitle(title){
- tag.setTitle(title)
- },
- changeMat({scale,rotation}){//大小旋转 贴墙时
- tag.setFaceAngle(rotation)
- tag.changeSpotScale(scale)
- },
- changeFontSize(fontsize){
- tag.setFontSize(fontsize)
- },
- // 更改离地高度
- changeLineHeight(height){//线长
- tag.changeLineLen(height)
- },
- changeCanMove(canMove){
- //console.log('changeCanMove', tag.title, canMove)
- tag.dragEnable = canMove
- },
-
- getImageCenter(){ //热点在模型的本地坐标
- if(!tag.parent)return new THREE.Vector3
- tag.titleLabel.sprite.update()
- let pos = tag.onMesh ? tag.position : tag.titleLabel.parent.position.clone().applyMatrix4(tag.matrixWorld).applyMatrix4(tag.root.matrixWorld.clone().invert())
- //console.log(props.title, 'getImageCenter', pos.toArray(), tag.lineLength)
- return pos
- },
-
- getCameraDisSquared(){//距离intersect的位置
- return viewer.mainViewport.camera.position.distanceToSquared(tag.getWorldPosition(new THREE.Vector3)) /* < tag.farSquared */
- },
- destory(){
- tag.dispose()
- },
-
- }
- tag.functions.changeImage(props.image)
- /*
-
- tag.functions.changeType(props.type)
-
- */
-
-
- return tag.functions
-
- },
-
- showGrid() {
- Potree.Utils.updateVisible(viewer.modules.MergeEditor.ground, 'hideGrid', true)
- viewer.dispatchEvent('content_changed')
- },
- hideGrid() {
- Potree.Utils.updateVisible(viewer.modules.MergeEditor.ground, 'hideGrid', false)
- viewer.dispatchEvent('content_changed')
- }
- }
-
- function spliceFromArr(model, props, loaded){
- //let autoLoads.find()
- props.loadFinish = true
- props.loading = false
- if (loaded) {
- props.loaded = true
- props.model = model
- } else {
- props.error = true
- }
- /* let haventLoad = autoLoads.filter(e=>!e.loading && !e.loadFinish);
- if( haventLoad[0]){
- startLoad(haventLoad[0])
- */
- if (!loadNext()) {
- if (autoLoads.filter(e => !e.loadFinish).length == 0 && autoLoads.filter(e => e.loaded).length > 0 && !props.isFirstLoad) {//设置相机位置:当自动开始加载第一个模型时(其余的也跟着自动加载),等这批加载完后;
- let autoLoadsDone = autoLoads.filter(e => e.loaded).map(e => e.model)
- let loadTimeCost = Date.now() - loadStartTime
- console.log('所有模型加载完毕, 耗时', parseInt(loadTimeCost) )
-
- autoLoads.filter(e => e.loaded && e.show).forEach(e => e.model.visible = true)
- MergeEditor.focusOn(autoLoadsDone, 1000, true, true)
- autoLoads.length = 0
- }
- }
- }
-
-
- function loadNext(){
- let haventLoad = autoLoads.filter(e => !e.loading && !e.loadFinish);
- let loading = autoLoads.filter(e => e.loading);
- let needLoad = haventLoad.slice(0, maxLoadingCount - loading.length)
- needLoad.forEach(e => startLoad(e))
- return haventLoad.length > 0
- }
-
- function startLoad(prop){
- /* if(prop.raw.visible !== 1){//用于临时隐藏
- setTimeout(()=>{
- spliceFromArr(null, prop, false)
- prop.bus.emit('loadError' )
- },1)
- return
- } */
-
- if(prop.loading || prop.loadFinish)return
-
- Potree.Log(`--开始加载--`, { font: { color: '#f68' } });
- console.log('id:', prop.id, ', title:', prop.title, ', filename:', Potree.Common.getNameFromURL(prop.url), ', type:', prop.type, prop)
- prop.unlit = prop.renderType != 'normal'
- prop.maximumScreenSpaceError = 70
- prop.prefix = prop.raw.prefix
- /* laserRoot != void 0 && (prop.prefix = laserRoot) //prefix for getdataset
- //Potree.settings.urls.prefix = prop.prefix = '' */
-
- Potree.addModel(prop, prop.done, prop.progressFun, prop.onError)
- prop.loading = true
- }
- function buildMap(){
- if (Potree.settings.showCesium && !window.cesiumViewer) {
- viewer.backgroundOpacity = 0
- //密钥
- Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2ZGM2YzY0ZC1kNWE0LTRiYTgtYTkwNS1kYmJiODRjMWUwMmQiLCJpZCI6MjMzMTQ1LCJpYXQiOjE3MjI5OTUwNTB9.niqpkl6xOkQ2KeJjelyDDDydmSGqKXKb5cX2NyxSNAw'
-
-
-
- window.cesiumViewer = new Cesium.Viewer('app', {
- useDefaultRenderLoop: true,
- requestRenderMode: true, //add 只有需要render时才会render,如tile加载完后、镜头移动后
- animation: false,
- baseLayerPicker: false,
- fullscreenButton: false,
- geocoder: false,
- homeButton: false,
- infoBox: false,
- sceneModePicker: false,
- selectionIndicator: false,
- timeline: false,
- navigationHelpButton: false,
- //高德秘钥版 imageryProvider: new Cesium.AmapImageryProvider({key, mapStyle: 'normal'})
- //报错 401 (Unauthorized) 的方法 https://blog.csdn.net/LBY_XK/article/details/121992641
- //terrainShadows: Cesium.ShadowMode.DISABLED, //terrain地形 //自带的地图直接用84坐标
- });
-
- let satellite = true
- let gaoDeImageryProvider = cesImageryProvider || new Cesium.UrlTemplateImageryProvider({
- url: `http://wprd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=${satellite?6:7}&x={x}&y={y}&z={z}&layer=6&token=YOUR_API_KEY`, //style=6是卫星,7是标准
- minimumLevel: 0,
- maximumLevel: satellite?18:19,
- credit: new Cesium.Credit('高德地图'),
- tilingScheme: new AmapMercatorTilingScheme(), //修改投影,从84->高德
- crossOrigin: 'anonymous',
- })
- cesiumViewer.imageryLayers.removeAll();
- cesiumViewer.imageryLayers.addImageryProvider(gaoDeImageryProvider);
-
- //叠一层文字上去
- let gaoDeImageryProvider2 = cesImageryProvider || new Cesium.UrlTemplateImageryProvider({
- url: `http://wprd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}&layer=6&token=YOUR_API_KEY`, //style=6是卫星,7是标准
- minimumLevel: 0,
- maximumLevel: 18,
- credit: new Cesium.Credit('高德地图'),
- tilingScheme: new AmapMercatorTilingScheme(), //修改投影,从84->高德
- crossOrigin: 'anonymous',
- })
- cesiumViewer.imageryLayers.addImageryProvider(gaoDeImageryProvider2);
-
-
-
- Potree.cesScreenshot = (w,h)=>{
- console.log('cesScreenshot',w,h)
- cesiumViewer.scene.canvas.style.width = w+'px'
- cesiumViewer.scene.canvas.style.height = h+'px'
- cesiumViewer.scene.canvas.style.visibility = 'hidden'
- cesiumViewer.resize()
- cesAspect = w/h
- let deferred = $.Deferred();
-
- updateMap(w/h)//hfov可能改变了需要update。
-
- setTimeout(()=>{ //延迟是似乎还要做别的处理,否则立即截图的话可能得到绿色底图(俯视状态容易触发)
- let oldMode = window.cesiumViewer._cesiumWidget._scene.requestRenderMode
- window.cesiumViewer._cesiumWidget._scene.requestRenderMode = 0 //强制render,否则会黑屏
- cesiumViewer.render();
- let dataUrl = window.cesiumViewer.scene.canvas.toDataURL('image/png')
- window.cesiumViewer._cesiumWidget._scene.requestRenderMode = oldMode
-
- //Potree.Common.downloadFile(dataUrl, 'screenshot.png')
- cesAspect = null
- cesiumViewer.scene.canvas.style.width = ''
- cesiumViewer.scene.canvas.style.height = ''
- cesiumViewer.scene.canvas.style.visibility = ''
-
- deferred.resolve(dataUrl)
- },200) //时间短了容易黑屏
-
-
- return deferred.promise()
-
- }
- }
- updateMap()
-
-
- }
-
-
- function updateCamNear(type){// 有的漫游场景模型缩放的很小(0.1%),需要缩小near才能看见, 但会造成z-fighting, 离远了看大模型会闪烁
- const min = 0.0001, max = 0.1
- let near , bigScale = 0.2
-
- if(Potree.settings.displayMode == 'showPanos'/* && type != 'cameraMove' */){
- let currentModel = viewer.images360.currentPano.pointcloud
- near = Potree.math.linearClamp(currentModel.scale.x, [0, 1], [min, max])
-
- }else/* if(type == 'cameraMove') */{
- //没有完美的解决方式,优先考虑选中的模型。否则优先考虑离得近的。 另外尽量用大的,因为缩很小的情况很少。
- //虽然案例说应该看model.bound.size,但如果非场景模型,缩很小的话也不需要凑近看。
- let allModels = viewer.objs.children.concat(viewer.scene.pointclouds)
- if(allModels.length == 0)return
- allModels.sort((a,b)=>{return a.scale.x - b.scale.x})
-
- let minS = allModels[0].scale.x, maxS = allModels.pop().scale.x
- let considerModel
- if(minS>bigScale) near = max
- else{
- if(MergeEditor.selected){
- considerModel = MergeEditor.selected
- near = Potree.math.linearClamp(considerModel.scale.x, [0, bigScale], [min, max])
- }else{
- //allModels = allModels.filter() //写不下去了好难,就算了吧, 折中
- near = Potree.math.linearClamp(minS, [0, bigScale], [max/4, max])
- }
- }
- }
-
- if(near != viewer.mainViewport.camera.near){
- console.log('updateNear',near)
- viewer.mainViewport.camera.near = near
- viewer.mainViewport.camera.updateProjectionMatrix()
- viewer.dispatchEvent('content_changed')
- }
-
- }
- function updateCamFar(){
- let expand = 1.1 //for label
- Potree.settings.cameraFar = THREE.Math.clamp((viewer.bound.boundingBox.distanceToPoint(viewer.mainViewport.camera.position)+viewer.bound.boundSize.length() ) * expand , 10000, 100000000000)
-
- }
- function updateMap(){
-
- if (Potree.settings.showCesium && Potree.settings.displayMode == 'showPointCloud') {
- let camera = MergeEditor.split ? viewer.viewports.find(e=>e.name == 'top').camera : viewer.mainViewport.camera
- let pPos = new THREE.Vector3(0, 0, 0).applyMatrix4(camera.matrixWorld);
-
- let orientation
- let toCes = (pos) => {
- let xy = [pos.x, pos.y];
- let height = pos.z;
- let deg = viewer.transform.lonlatToLocal.inverse(xy) // toMap.forward(xy);
- let cPos = Cesium.Cartesian3.fromDegrees(...deg, height);
- //console.log('toCes',cPos,height) //数字过大如e35会崩溃
- return cPos;
- };
- let cPos = toCes(pPos);
-
-
-
- if(MergeEditor.split){
- orientation = {
- heading: Cesium.Math.toRadians(0.0), // 方向角
- pitch: Cesium.Math.toRadians(-90.0), // 俯仰角
- roll: 0.0 // 翻滚角
- }
-
- if(!cesiumViewer.camera.perpFrustum_){
- cesiumViewer.camera.perpFrustum_ = cesiumViewer.camera.frustum
- cesiumViewer.camera.frustum = new Cesium.OrthographicOffCenterFrustum({//OrthographicFrustum OrthographicOffCenterFrustum
- left: -10000, // 左边界
- right: 10000, // 右边界
- bottom: -10000, // 下边界
- top: 10000, // 上边界
- near: 1.0, // 近裁剪面距离
- far: 100000000.0, // 远裁剪面距离
- })
- }
-
- cesiumViewer.camera.frustum.left = camera.left / camera.zoom
- cesiumViewer.camera.frustum.right = camera.right / camera.zoom
- cesiumViewer.camera.frustum.top = camera.top / camera.zoom
- cesiumViewer.camera.frustum.bottom = camera.bottom / camera.zoom
- }else{
-
- cesiumViewer.camera.perpFrustum_ && (cesiumViewer.camera.frustum = cesiumViewer.camera.perpFrustum_, cesiumViewer.camera.perpFrustum_ = null) //恢复
-
- //let pRight = new THREE.Vector3(600, 0, 0).applyMatrix4(camera.matrixWorld);
- let pUp = new THREE.Vector3(0, 600, 0).applyMatrix4(camera.matrixWorld);
- let pTarget = viewer.scene.view.getPivot();
-
- let cUpTarget = toCes(pUp);
- let cTarget = toCes(pTarget);
- let cDir = Cesium.Cartesian3.subtract(cTarget, cPos, new Cesium.Cartesian3());
- let cUp = Cesium.Cartesian3.subtract(cUpTarget, cPos, new Cesium.Cartesian3());
- cDir = Cesium.Cartesian3.normalize(cDir, new Cesium.Cartesian3());
- cUp = Cesium.Cartesian3.normalize(cUp, new Cesium.Cartesian3());
- //console.log('ces', 'cPos', cPos, 'cDir',cDir, 'cUp', cUp)
- orientation = {
- direction: cDir,
- up: cUp
- }
- let aspect = cesAspect || camera.aspect;
- //console.log('updateMap', aspect)
-
- if (aspect < 1) {
- let fovy = Math.PI * (viewer.scene.getActiveCamera().fov / 180);
- cesiumViewer.camera.frustum.fov = fovy;
- } else {
- let fovy = Math.PI * (viewer.scene.getActiveCamera().fov / 180);
- let fovx = Math.atan(Math.tan(0.5 * fovy) * aspect) * 2
- cesiumViewer.camera.frustum.fov = fovx;
- }
- }
-
-
- cesiumViewer.camera.setView({
- destination: cPos,
- orientation
- });
-
-
- cesiumViewer.scene.globe.show = camera.position.z > 0 //在地面之下地球会闪烁,故隐藏
- cesiumViewer.render(); //立即render,否则会和点云render不同步而错位
- }//cesium测试沙盒 https://sandcastle.cesium.com/
- }
-
-
-
- class AmapMercatorTilingScheme extends Cesium.WebMercatorTilingScheme {
- constructor(options) {
- super(options)
- let projection = new Cesium.WebMercatorProjection()
- this._projection.project = function(cartographic, result) {
- //WGS84转GCJ02坐标
- /* result = gcoord.transform([
- Cesium.Math.toDegrees(cartographic.longitude),
- Cesium.Math.toDegrees(cartographic.latitude)
- ], gcoord.WGS84, gcoord.GCJ02) */
- result = AMapWith84__.wgs84ToAMap({
- x: Cesium.Math.toDegrees(cartographic.longitude),
- y: Cesium.Math.toDegrees(cartographic.latitude)
- })
- result = projection.project(new Cesium.Cartographic(Cesium.Math.toRadians(result.x),Cesium.Math.toRadians(result.y)))
- return new Cesium.Cartesian2(result.x,result.y)
- }
- this._projection.unproject = function(cartesian, result) {
- let cartographic = projection.unproject(cartesian)
- //GCJ02转WGS84坐标
- /* result = gcoord.transform([
- Cesium.Math.toDegrees(cartographic.longitude),
- Cesium.Math.toDegrees(cartographic.latitude)
- ], gcoord.GCJ02, gcoord.WGS84) */
- result = AMapWith84__.aMapToWgs84({
- x: Cesium.Math.toDegrees(cartographic.longitude),
- y: Cesium.Math.toDegrees(cartographic.latitude)
- })
- return new Cesium.Cartographic(Cesium.Math.toRadians(result.x),Cesium.Math.toRadians(result.y))
- }
- }
- }//see : https://blog.csdn.net/hongxianqiang/article/details/140541555 cesium加载高德地图并纠偏
-
- return sdk
- }
-
- /*
- 暂定不同场景间的漫游点不能互通。虽然它们可能是摆放正确的,如果是组成一整个场景的话还是要打通……
- 不互通的方法是设置pano.enable
-
- 现在需要互通了。但是还需要设置neibgbours, 有点麻烦,暂时没写。
- */
- export default enter
|