123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456 |
- import * as THREE from "../../libs/three.js/build/three.module.js";
- import {ClipTask, ClipMethod, CameraMode, LengthUnits, ElevationGradientRepeat} from "../defines.js";
- import {Renderer} from "../PotreeRenderer.js";
- import {PotreeRenderer} from "./PotreeRenderer.js";
- import {EDLRenderer} from "./EDLRenderer.js";
- import {HQSplatRenderer} from "./HQSplatRenderer.js";
- import {Scene} from "./Scene.js";
- import {ClippingTool} from "../utils/ClippingTool.js";
- import {TransformationTool} from "../utils/TransformationTool.js";
- import {Utils} from "../utils.js";
- import {MapView} from "./map.js";
- import {MapViewer} from "./map/MapViewer.js";
- import {ProfileWindow, ProfileWindowController} from "./profile.js";
- import {BoxVolume} from "../utils/Volume.js";
- import {Features} from "../Features.js";
- import {Message} from "../utils/Message.js";
- import {Sidebar} from "./sidebar.js";
- import {AnnotationTool} from "../utils/AnnotationTool.js";
- import {MeasuringTool} from "../utils/MeasuringTool.js";
- import {ProfileTool} from "../utils/ProfileTool.js";
- import {VolumeTool} from "../utils/VolumeTool.js";
- import {InputHandler} from "../navigation/InputHandler.js";
- import {NavigationCube} from "./NavigationCube.js";
- import {Compass} from "../utils/Compass.js";
- import {OrbitControls} from "../navigation/OrbitControls.js";
- import {FirstPersonControls} from "../navigation/FirstPersonControls.js";
- import {EarthControls} from "../navigation/EarthControls.js";
- import {DeviceOrientationControls} from "../navigation/DeviceOrientationControls.js";
- import {VRControls} from "../navigation/VRControls.js";
- import { ClassificationScheme } from "../materials/ClassificationScheme.js";
- import { VRButton } from '../../libs/three.js/extra/VRButton.js';
- import {transitions, easing, lerp} from '../utils/transitions.js'
- import JSON5 from "../../libs/json5-2.1.3/json5.mjs";
- import CursorDeal from '../utils/CursorDeal'
- import Common from '../utils/Common'
- import {Clip} from '../modules/clipModel/Clip'
- import {Alignment} from "../modules/datasetAlignment/Alignment.js";
- import {SiteModel} from "../modules/siteModel/SiteModel.js";
- import Magnifier from "../utils/Magnifier.js";
- import Reticule from "../navigation/Reticule.js";
- import Viewport from "./Viewport.js"
- import {ViewerBase} from "./viewerBase.js"
-
- import SplitScreen from '../utils/SplitScreen'
- import cameraLight from "../utils/cameraLight.js";
- import math from "../utils/math.js";
-
- import {UoMService} from '../utils/UnitConvert'
- import {RouteGuider} from '../navigation/RouteGuider'
- import {MeshDraw} from '../utils/DrawUtil'
- let mapArea;
- export class Viewer extends ViewerBase{
-
- constructor(domElement, mapArea_, args = {}){
- super(domElement, $.extend(args,{name:'mainViewer'}));
- window.viewer = this
- this.modules = { //add
- Clip : Clip,
- Alignment : Alignment,
- SiteModel : SiteModel,
- RouteGuider : new RouteGuider,
-
- }
-
- this.testingMaxLevel = true
-
- //add --------
- this.navigateMode = 'free' // 'panorama'; 'free'自由模式是只显示点云或者未进入到漫游点,
- this.isEdit = true
- this.waitQueue = []
- this.unitConvert = new UoMService();
- mapArea = mapArea_
- this.visible = true
- //-------------
-
- var supportExtFragDepth = !!Features.EXT_DEPTH.isSupported() ;//iphoneX居然不支持
- //这意味着边缘增强和测量线遮挡失效
- if(!supportExtFragDepth)console.error('ExtFragDepth unsupported! 边缘增强和测量线遮挡失效')
-
-
- this.guiLoaded = false;
- this.guiLoadTasks = [];
- this.onVrListeners = [];
-
- this.messages = [];
- this.elMessages = $(`
- <div id="message_listing"
- style="position: absolute; z-index: 1000; left: 10px; bottom: 10px">
- </div>`);
- $(domElement).append(this.elMessages);
-
-
- this.paused
-
- document.addEventListener('visibilitychange',(e)=>{
- //console.log('visibilitychange', !document.hidden )
- this.emit('pageVisible', !document.hidden )
- /* if(document.hidden){
- this.paused = true
- }else{
- setTimeout(()=>{
- if(!document.hidden) this.paused = false
- },1000)
- } */
-
- })
-
-
-
- try{
-
- if(!Potree.settings.isOfficial)
- { // generate missing dom hierarchy
- if ($(domElement).find('#potree_map').length === 0) {
- let potreeMap = $(`
- <div id="potree_map" class="mapBox" style="position: absolute; left: 50px; top: 50px; width: 400px; height: 400px; display: none">
- <div id="potree_map_header" style="position: absolute; width: 100%; height: 25px; top: 0px; background-color: rgba(0,0,0,0.5); z-index: 1000; border-top-left-radius: 3px; border-top-right-radius: 3px;">
- </div>
- <div id="potree_map_content" class="map" style="position: absolute; z-index: 100; top: 25px; width: 100%; height: calc(100% - 25px); border: 2px solid rgba(0,0,0,0.5); box-sizing: border-box;"></div>
- </div>
- `);
- $(domElement).append(potreeMap);
- }
- if ($(domElement).find('#potree_description').length === 0) {
- let potreeDescription = $(`<div id="potree_description" class="potree_info_text"></div>`);
- $(domElement).append(potreeDescription);
- }
- if ($(domElement).find('#potree_annotations').length === 0) {
- let potreeAnnotationContainer = $(`
- <div id="potree_annotation_container"
- style="position: absolute; z-index: 100000; width: 100%; height: 100%; pointer-events: none;"></div>`);
- $(domElement).append(potreeAnnotationContainer);
- }
- if ($(domElement).find('#potree_quick_buttons').length === 0) {
- let potreeMap = $(`
- <div id="potree_quick_buttons" class="quick_buttons_container" style="">
- </div>
- `);
-
- $(domElement).append(potreeMap);
- }
-
- //add
- {
-
- if(!mapArea){
- $(domElement).append($("<div id='potree_labels'></div>"))
-
- mapArea = $("<div id='mapGaode'></div>")
- $(domElement).append(mapArea)
- mapArea = mapArea[0]
- }
-
- }
-
-
- let domRoot = this.renderer.domElement.parentElement;
- let elAttach = $("<input type='button' value='test'></input>");
- elAttach.css({
- position : "absolute",
- right : '10%',
- bottom: '20px',
- zIndex: "10000",
- fontSize:'1em', color:"black",
- background:'rgba(255,255,255,0.8)',
- })
- let state = false
- elAttach.on("click", () => {
- window.buttonFunction && window.buttonFunction()
- });
- domRoot.appendChild(elAttach[0]);
-
-
-
-
- }
-
-
- this.pointCloudLoadedCallback = args.onPointCloudLoaded || function () {};
- // if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
- // defaultSettings.navigation = "Orbit";
- // }
- this.server = null;
- this.fov = 60;
- this.isFlipYZ = false;
- this.useDEMCollisions = false;
- this.generateDEM = false;
- this.minNodeSize = 30;
- this.edlStrength = 1.0;
- this.edlRadius = 1.4;
- this.edlOpacity = 1.0;
- this.useEDL = false;
- this.description = "";
- this.classifications = ClassificationScheme.DEFAULT;
- this.moveSpeed = 10;
- this.lengthUnit = LengthUnits.METER;
- this.lengthUnitDisplay = LengthUnits.METER;
- this.showBoundingBox = false;
- this.showAnnotations = true;
- this.freeze = false;
- this.clipTask = ClipTask.HIGHLIGHT;
- this.clipMethod = ClipMethod.INSIDE_ANY;
- this.elevationGradientRepeat = ElevationGradientRepeat.CLAMP;
- this.filterReturnNumberRange = [0, 7];
- this.filterNumberOfReturnsRange = [0, 7];
- this.filterGPSTimeRange = [-Infinity, Infinity];
- this.filterPointSourceIDRange = [0, 65535];
- this.potreeRenderer = null;
- this.edlRenderer = null;
- this.pRenderer = null;
- this.scene = null;
- this.sceneVR = null;
- this.overlay = null;
- this.overlayCamera = null;
- this.inputHandler = null;
- this.controls = null;
- this.clippingTool = null;
- this.transformationTool = null;
- this.navigationCube = null;
- this.compass = null;
-
- this.skybox = null;
- this.clock = new THREE.Clock();
- this.background = null;
-
-
-
- if(args.noDragAndDrop){
-
- }else{
- this.initDragAndDrop();
- }
- if(typeof Stats !== "undefined"){
- this.stats = new Stats();
- this.stats.showPanel( 0 ); // 0: fps, 1: ms, 2: mb, 3+: custom
- document.body.appendChild( this.stats.dom );
- }
- {
- let canvas = this.renderer.domElement;
- canvas.addEventListener("webglcontextlost", (e) => {
- console.log(e);
- this.postMessage("WebGL context lost. \u2639");
- let gl = this.renderer.getContext();
- let error = gl.getError();
- console.log(error);
- this.emit('webglError', 'webglcontextlost')
- }, false);
- }
- {
- this.overlay = new THREE.Scene();
- this.overlayCamera = new THREE.OrthographicCamera(
- 0, 1,
- 1, 0,
- -1000, 1000
- );
- }
-
- this.pRenderer = new Renderer(this.renderer);
-
- {
- let near = 2.5;
- let far = 10.0;
- let fov = 90;
-
- this.shadowTestCam = new THREE.PerspectiveCamera(90, 1, near, far);
- this.shadowTestCam.position.set(3.50, -2.80, 8.561);
- this.shadowTestCam.lookAt(new THREE.Vector3(0, 0, 4.87));
- }
-
- let scene = new Scene(this.renderer);
-
- { // create VR scene
- this.sceneVR = new THREE.Scene();
- // let texture = new THREE.TextureLoader().load(`${Potree.resourcePath}/images/vr_controller_help.jpg`);
- // let plane = new THREE.PlaneBufferGeometry(1, 1, 1, 1);
- // let infoMaterial = new THREE.MeshBasicMaterial({map: texture});
- // let infoNode = new THREE.Mesh(plane, infoMaterial);
- // infoNode.position.set(-0.5, 1, 0);
- // infoNode.scale.set(0.4, 0.3, 1);
- // infoNode.lookAt(0, 1, 0)
- // this.sceneVR.add(infoNode);
- // window.infoNode = infoNode;
- }
- this.setScene(scene);
- {
- this.inputHandler = new InputHandler(this, this.scene.scene);
- //this.inputHandler.setScene(this.scene);
- //this.inputHandler.addInputListener(this);//add
-
-
-
- this.clippingTool = new ClippingTool(this);
- this.transformationTool = new TransformationTool(this);
- this.navigationCube = new NavigationCube(this);
- this.navigationCube.visible = false;
- this.compass = new Compass(this);
-
- //add----------
- this.magnifier = new Magnifier(this);
- this.reticule = new Reticule(this)
- this.scene.scene.add(this.magnifier)
- this.scene.scene.add(this.reticule)
- this.mainViewport = new Viewport( this.scene.view, this.scene.cameraP, {
- left:0, bottom:0, width:1, height: 1, name:'MainView'
- })
- this.viewports = [this.mainViewport]
- this.mapViewer = new MapViewer(mapArea/* $('#mapGaode')[0] */)
-
-
-
- //---------------------------
-
-
- this.createControls();
- this.clippingTool.setScene(this.scene);
-
- let onPointcloudAdded = (e) => {
- if (this.scene.pointclouds.length === 1) {
- let speed = e.pointcloud.boundingBox.getSize(new THREE.Vector3()).length();
- speed = speed / 2000;
- this.setMoveSpeed(speed);
- }
- };
- let onVolumeRemoved = (e) => {
- this.inputHandler.deselect(e.volume);
- };
- this.addEventListener('scene_changed', (e) => {
- this.inputHandler.setScene(e.scene);
- this.clippingTool.setScene(this.scene);
-
- if(!e.scene.hasEventListener("pointcloud_added", onPointcloudAdded)){
- e.scene.addEventListener("pointcloud_added", onPointcloudAdded);
- }
- if(!e.scene.hasEventListener("volume_removed", onPointcloudAdded)){
- e.scene.addEventListener("volume_removed", onVolumeRemoved);
- }
-
- });
- this.scene.addEventListener("volume_removed", onVolumeRemoved);
- this.scene.addEventListener('pointcloud_added', onPointcloudAdded);
- }
- { // set defaults
- this.setFOV(60);
- this.setEDLEnabled(false);
- this.setEDLRadius(1.4);
- this.setEDLStrength(0.4);
- this.setEDLOpacity(1.0);
- this.setClipTask(ClipTask.HIGHLIGHT);
- this.setClipMethod(ClipMethod.INSIDE_ANY);
- this.setPointBudget(1*1000*1000);
- this.setShowBoundingBox(false);
- this.setFreeze(false);
- this.setControls(this.fpControls/* orbitControls */);
- this.setBackground( new THREE.Color(Potree.config.background),1 /* 'gradient' */ );
-
- this.scaleFactor = 1;
- this.loadSettingsFromURL();
- }
- // start rendering!
- //if(args.useDefaultRenderLoop === undefined || args.useDefaultRenderLoop === true){
- //requestAnimationFrame(this.loop.bind(this));
- //}
-
- this.renderer.setAnimationLoop(this.loop.bind(this));
- this.loadGUI = this.loadGUI.bind(this);
- this.annotationTool = new AnnotationTool(this);
- this.measuringTool = new MeasuringTool(this);
- this.profileTool = new ProfileTool(this);
- this.volumeTool = new VolumeTool(this);
-
-
-
-
-
- //-----------
- CursorDeal.init(this)//ADD
-
- this.modules.SiteModel.init()
- this.modules.Alignment.init()
- //-----------
-
-
- }catch(e){
- this.onCrash(e);
- }
-
- //-----------------------add----------------------------------------------------
-
-
-
-
- /* {
- let ratio
- this.addEventListener('resize',(e)=>{
- if(ratio != e.deviceRatio){ //因为devicePixelRatio会影响到点云大小,所以改变时计算下点云大小
- viewer.scene.pointclouds.forEach(p => {
- p.changePointSize()
- })
- }
- ratio = e.deviceRatio
-
- })
- } */
-
- {
- let pointDensity = ''
- Object.defineProperty(Potree.settings , "pointDensity",{
- get: function() {
- return pointDensity
- },
- set: (density)=>{
- if(density && density != pointDensity){
- let pointBudget;
- var config = Potree.config.pointDensity[density];
-
- if(this.magnifier.visible){//放大镜打开时不要切换pointBudget,否则点云会闪烁。这时使用最高密度。
- pointBudget = Potree.config.pointDensity['magnifier'].pointBudget
- }else{
- pointBudget = config.pointBudget
- }
-
- viewer.setPointBudget(pointBudget );
- //Potree.maxPointLevel = config.maxLevel
-
- pointDensity = density
-
- this.setPointLevel()
-
-
- }
- }
- })
-
- let UserPointDensity = ''
- Object.defineProperty(Potree.settings , "UserPointDensity",{
- get: function() {
- return UserPointDensity
- },
- set: (density)=>{
- if(UserPointDensity != density){
- if(Potree.settings.displayMode == 'showPointCloud' && this.viewports.length != 4){//漫游模式和四屏时都有自己的pointDensity
- Potree.settings.pointDensity = density
- }
- UserPointDensity = density
- }
- }
- })
-
- this.on('updateNodeMaxLevel',(pointcloud,nodeMaxLevel)=>{
-
- if(!viewer.testNodeLevelTimer && viewer.testingMaxLevel ){
- viewer.testNodeLevelTimer = setTimeout(()=>{//先加载一段时间最高level的点云。但希望不会刚好附近的点云都没有达到最高的level,否则就要走一段才能了。
- viewer.testingMaxLevel = false
- console.log('结束testingMaxLevel')
- //Potree.settings.pointDensity = Potree.settings.pointDensity
- this.setPointLevel()//重新计算
- },3000)
- viewer.beginTestTime = Date.now()
- }
- console.log('updateNodeMaxLevel ' + pointcloud.dataset_id + " : "+ nodeMaxLevel)
- if(nodeMaxLevel >= 10 && viewer.testingMaxLevel){//10的时候差不多能加载到11和12了。假设最高只有12的话,就到10就可以。不过大多数场景都到不了10,也不知有没有大于10的,如果没有,这里可以写5.
- viewer.testingMaxLevel = false
- console.log('提前结束testingMaxLevel,用时:'+(Date.now()-viewer.beginTestTime))
- //我的电脑用时大概1500
- }
- //Potree.settings.pointDensity = Potree.settings.pointDensity //重新计算
- this.setPointLevel()//重新计算
-
-
- if(!Potree.settings.sizeFitToLevel){
- pointcloud.changePointSize()
-
- }
-
- //见过最小加载到的nodeMaxLevel是4
- })
-
- }
- {
-
- let cameraFar = Potree.settings.cameraFar
- Object.defineProperty(Potree.settings , "cameraFar",{
- get: function() {
- return cameraFar
- },
- set: (far)=>{
- if(far != cameraFar){
- if(Potree.settings.displayMode != 'showPanos'){
- this.mainViewport.camera.far = far;
- this.mainViewport.camera.updateProjectionMatrix()
- }
- cameraFar = far
- }
- }
- })
-
-
-
- }
-
-
- }
-
-
-
-
- setPointLevel(){
- var pointDensity = Potree.settings.pointDensity
- var config = Potree.config.pointDensity[pointDensity];
- this.scene.pointclouds.forEach(e=>{
- if(this.testingMaxLevel){
- e.maxLevel = 12;//先加载到最大的直到测试完毕。由于5个level为一组来加载,所以如果写4最高能加载到5,如果写5最高能加载到下一个级别的最高也就是10
- //console.log('maxLevel: '+e.maxLevel + ' testingMaxLevel中 ' )
- }else{
- let percent = (pointDensity == 'panorama' || 'magnifier') ? config.maxLevelPercent : (Potree.settings.UserDensityPercent == void 0 ? config.maxLevelPercent : Potree.settings.UserDensityPercent)
- e.maxLevel = Math.round( percent * e.nodeMaxLevel);
- console.log('maxLevel: '+e.maxLevel + ', density : '+Potree.settings.pointDensity, ", percent :"+percent);
-
- if(Potree.settings.sizeFitToLevel){
- e.changePointSize()
- }
- e.changePointOpacity()
- }
- })
- /* if(!viewer.testingMaxLevel && Potree.sdk){
- Potree.sdk.scene.changePointSize()
- Potree.sdk.scene.changePointOpacity()
- } */
- }
- onCrash(error){
- $(this.renderArea).empty();
- if ($(this.renderArea).find('#potree_failpage').length === 0) {
- let elFailPage = $(`
- <div id="#potree_failpage" class="potree_failpage">
-
- <h1>Potree Encountered An Error </h1>
- <p>
- This may happen if your browser or graphics card is not supported.
- <br>
- We recommend to use
- <a href="https://www.google.com/chrome/browser" target="_blank" style="color:initial">Chrome</a>
- or
- <a href="https://www.mozilla.org/" target="_blank">Firefox</a>.
- </p>
- <p>
- Please also visit <a href="http://webglreport.com/" target="_blank">webglreport.com</a> and
- check whether your system supports WebGL.
- </p>
- <p>
- If you are already using one of the recommended browsers and WebGL is enabled,
- consider filing an issue report at <a href="https://github.com/potree/potree/issues" target="_blank">github</a>,<br>
- including your operating system, graphics card, browser and browser version, as well as the
- error message below.<br>
- Please do not report errors on unsupported browsers.
- </p>
- <pre id="potree_error_console" style="width: 100%; height: 100%"></pre>
-
- </div>`);
- let elErrorMessage = elFailPage.find('#potree_error_console');
- elErrorMessage.html(error.stack);
- $(this.renderArea).append(elFailPage);
- }
- throw error;
- }
- // ------------------------------------------------------------------------------------
- // Viewer API
- // ------------------------------------------------------------------------------------
- setScene (scene) {
- if (scene === this.scene) {
- return;
- }
- let oldScene = this.scene;
- this.scene = scene;
- this.dispatchEvent({
- type: 'scene_changed',
- oldScene: oldScene,
- scene: scene
- });
- { // Annotations
- $('.annotation').detach();
- // for(let annotation of this.scene.annotations){
- // this.renderArea.appendChild(annotation.domElement[0]);
- // }
- this.scene.annotations.traverse(annotation => {
- this.renderArea.appendChild(annotation.domElement[0]);
- });
- if (!this.onAnnotationAdded) {
- this.onAnnotationAdded = e => {
- // console.log("annotation added: " + e.annotation.title);
- e.annotation.traverse(node => {
- $("#potree_annotation_container").append(node.domElement);
- //this.renderArea.appendChild(node.domElement[0]);
- node.scene = this.scene;
- });
- };
- }
- if (oldScene) {
- oldScene.annotations.removeEventListener('annotation_added', this.onAnnotationAdded);
- }
- this.scene.annotations.addEventListener('annotation_added', this.onAnnotationAdded);
- }
- };
- setControls(controls/* , setSpeed */){
- if (controls !== this.controls) {
- if (this.controls) {
- this.controls.setEnable(false)
- //this.inputHandler.removeInputListener(this.controls);
- this.controls.moveSpeed = this.moveSpeed; //记录 (因为orbit的radius很大,转为firstPerson时要缩小)
- }
- this.controls = controls;
- controls.moveSpeed && this.setMoveSpeed(controls.moveSpeed) //add
-
- this.controls.setEnable(true)
-
- //this.inputHandler.addInputListener(this.controls);
- }
- }
- getControls () {
- if(this.renderer.xr.isPresenting){
- return this.vrControls;
- }else{
- return this.controls;
- }
-
- }
- getMinNodeSize () {
- return this.minNodeSize;
- };
- setMinNodeSize (value) {
- if (this.minNodeSize !== value) {
- this.minNodeSize = value;
- this.dispatchEvent({'type': 'minnodesize_changed', 'viewer': this});
- }
- };
- getBackground () {
- return this.background;
- }
- setBackground(bg){
- if (this.background === bg) {
- return;
- }
- if(bg === "skybox"){
- this.skybox = Utils.loadSkybox(new URL(Potree.resourcePath + '/textures/skybox2/').href);
- }
- this.background = bg;
- this.backgroundOpacity = 1//add
- this.dispatchEvent({'type': 'background_changed', 'viewer': this});
- }
- setDescription (value) {
- this.description = value;
-
- $('#potree_description').html(value);
- //$('#potree_description').text(value);
- }
- getDescription(){
- return this.description;
- }
- setShowBoundingBox (value) {
- if (this.showBoundingBox !== value) {
- this.showBoundingBox = value;
- this.dispatchEvent({'type': 'show_boundingbox_changed', 'viewer': this});
- }
- };
- getShowBoundingBox () {
- return this.showBoundingBox;
- };
-
- setMoveSpeed (value) {
- if (this.getMoveSpeed() !== value) {
- this.mainViewport.setMoveSpeed(value)
- this.dispatchEvent({'type': 'move_speed_changed', 'viewer': this, 'speed': value});
- }
- };
- getMoveSpeed () {
- return this.mainViewport.moveSpeed;
- };
- setWeightClassification (w) {
- for (let i = 0; i < this.scene.pointclouds.length; i++) {
- this.scene.pointclouds[i].material.weightClassification = w;
- this.dispatchEvent({'type': 'attribute_weights_changed' + i, 'viewer': this});
- }
- };
- setFreeze (value) {
- value = Boolean(value);
- if (this.freeze !== value) {
- this.freeze = value;
- this.dispatchEvent({'type': 'freeze_changed', 'viewer': this});
- }
- };
- getFreeze () {
- return this.freeze;
- };
- getClipTask(){
- return this.clipTask;
- }
- getClipMethod(){
- return this.clipMethod;
- }
- setClipTask(value){
- if(this.clipTask !== value){
- this.clipTask = value;
- this.dispatchEvent({
- type: "cliptask_changed",
- viewer: this});
- }
- }
- setClipMethod(value){
- if(this.clipMethod !== value){
- this.clipMethod = value;
-
- this.dispatchEvent({
- type: "clipmethod_changed",
- viewer: this});
- }
- }
- setElevationGradientRepeat(value){
- if(this.elevationGradientRepeat !== value){
- this.elevationGradientRepeat = value;
- this.dispatchEvent({
- type: "elevation_gradient_repeat_changed",
- viewer: this});
- }
- }
- setPointBudget (value) {
- if (Potree.pointBudget !== value) {
- Potree.pointBudget = parseInt(value);
- this.dispatchEvent({'type': 'point_budget_changed', 'viewer': this});
- }
- };
- getPointBudget () {
- return Potree.pointBudget;
- };
- setShowAnnotations (value) {
- if (this.showAnnotations !== value) {
- this.showAnnotations = value;
- this.dispatchEvent({'type': 'show_annotations_changed', 'viewer': this});
- }
- }
- getShowAnnotations () {
- return this.showAnnotations;
- }
-
- setDEMCollisionsEnabled(value){
- if(this.useDEMCollisions !== value){
- this.useDEMCollisions = value;
- this.dispatchEvent({'type': 'use_demcollisions_changed', 'viewer': this});
- };
- };
- getDEMCollisionsEnabled () {
- return this.useDEMCollisions;
- };
- setEDLEnabled (value) {
- value = Boolean(value) && Features.SHADER_EDL.isSupported();
-
- if (this.useEDL !== value) {
- this.useEDL = value;
- this.dispatchEvent({'type': 'use_edl_changed', 'viewer': this});
- }
- };
- getEDLEnabled () {
- return this.useEDL;
- };
- setEDLRadius (value) {
- if (this.edlRadius !== value) {
- this.edlRadius = value;
- this.dispatchEvent({'type': 'edl_radius_changed', 'viewer': this});
- }
- };
- getEDLRadius () {
- return this.edlRadius;
- };
- setEDLStrength (value) {
- if (this.edlStrength !== value) {
- this.edlStrength = value;
- this.dispatchEvent({'type': 'edl_strength_changed', 'viewer': this});
- }
- };
- getEDLStrength () {
- return this.edlStrength;
- };
- setEDLOpacity (value) {
- if (this.edlOpacity !== value) {
- this.edlOpacity = value;
- this.dispatchEvent({'type': 'edl_opacity_changed', 'viewer': this});
- }
- };
- getEDLOpacity () {
- return this.edlOpacity;
- };
- setFOV (value) {
- if (this.fov !== value) {
- let oldFov = this.fov
- this.fov = value;
- this.scene.cameraP.fov = this.fov;
- this.scene.cameraP.updateProjectionMatrix()
- this.dispatchEvent({'type': 'fov_changed', 'viewer': this, oldFov, fov:this.fov});
- }
- };
- getFOV () {
- return this.fov;
- };
- disableAnnotations () {
- this.scene.annotations.traverse(annotation => {
- annotation.domElement.css('pointer-events', 'none');
- // return annotation.visible;
- });
- };
- enableAnnotations () {
- this.scene.annotations.traverse(annotation => {
- annotation.domElement.css('pointer-events', 'auto');
- // return annotation.visible;
- });
- }
- setClassifications(classifications){
- this.classifications = classifications;
- this.dispatchEvent({'type': 'classifications_changed', 'viewer': this});
- }
- setClassificationVisibility (key, value) {
- if (!this.classifications[key]) {
- this.classifications[key] = {visible: value, name: 'no name'};
- this.dispatchEvent({'type': 'classification_visibility_changed', 'viewer': this});
- } else if (this.classifications[key].visible !== value) {
- this.classifications[key].visible = value;
- this.dispatchEvent({'type': 'classification_visibility_changed', 'viewer': this});
- }
- }
- toggleAllClassificationsVisibility(){
- let numVisible = 0;
- let numItems = 0;
- for(const key of Object.keys(this.classifications)){
- if(this.classifications[key].visible){
- numVisible++;
- }
- numItems++;
- }
- let visible = true;
- if(numVisible === numItems){
- visible = false;
- }
- let somethingChanged = false;
- for(const key of Object.keys(this.classifications)){
- if(this.classifications[key].visible !== visible){
- this.classifications[key].visible = visible;
- somethingChanged = true;
- }
- }
- if(somethingChanged){
- this.dispatchEvent({'type': 'classification_visibility_changed', 'viewer': this});
- }
- }
- setFilterReturnNumberRange(from, to){
- this.filterReturnNumberRange = [from, to];
- this.dispatchEvent({'type': 'filter_return_number_range_changed', 'viewer': this});
- }
- setFilterNumberOfReturnsRange(from, to){
- this.filterNumberOfReturnsRange = [from, to];
- this.dispatchEvent({'type': 'filter_number_of_returns_range_changed', 'viewer': this});
- }
- setFilterGPSTimeRange(from, to){
- this.filterGPSTimeRange = [from, to];
- this.dispatchEvent({'type': 'filter_gps_time_range_changed', 'viewer': this});
- }
- setFilterPointSourceIDRange(from, to){
- this.filterPointSourceIDRange = [from, to]
- this.dispatchEvent({'type': 'filter_point_source_id_range_changed', 'viewer': this});
- }
- setLengthUnit (value) {
- switch (value) {
- case 'm':
- this.lengthUnit = LengthUnits.METER;
- this.lengthUnitDisplay = LengthUnits.METER;
- break;
- case 'ft':
- this.lengthUnit = LengthUnits.FEET;
- this.lengthUnitDisplay = LengthUnits.FEET;
- break;
- case 'in':
- this.lengthUnit = LengthUnits.INCH;
- this.lengthUnitDisplay = LengthUnits.INCH;
- break;
- }
- this.dispatchEvent({ 'type': 'length_unit_changed', 'viewer': this, value: value});
- };
- setLengthUnitAndDisplayUnit(lengthUnitValue, lengthUnitDisplayValue) {
- switch (lengthUnitValue) {
- case 'm':
- this.lengthUnit = LengthUnits.METER;
- break;
- case 'ft':
- this.lengthUnit = LengthUnits.FEET;
- break;
- case 'in':
- this.lengthUnit = LengthUnits.INCH;
- break;
- }
- switch (lengthUnitDisplayValue) {
- case 'm':
- this.lengthUnitDisplay = LengthUnits.METER;
- break;
- case 'ft':
- this.lengthUnitDisplay = LengthUnits.FEET;
- break;
- case 'in':
- this.lengthUnitDisplay = LengthUnits.INCH;
- break;
- }
- this.dispatchEvent({ 'type': 'length_unit_changed', 'viewer': this, value: lengthUnitValue });
- };
- zoomTo(node, factor, animationDuration = 0){
- let view = this.scene.view;
- let camera = this.scene.cameraP.clone();
- camera.rotation.copy(this.scene.cameraP.rotation);
- camera.rotation.order = "ZXY";
- camera.rotation.x = Math.PI / 2 + view.pitch;
- camera.rotation.z = view.yaw;
- camera.updateMatrix();
- camera.updateMatrixWorld();
- camera.zoomTo(node, factor);
- let bs;
- if (node.boundingSphere) {
- bs = node.boundingSphere;
- } else if (node.geometry && node.geometry.boundingSphere) {
- bs = node.geometry.boundingSphere;
- } else {
- bs = node.boundingBox.getBoundingSphere(new THREE.Sphere());
- }
- bs = bs.clone().applyMatrix4(node.matrixWorld);
- let startPosition = view.position.clone();
- let endPosition = camera.position.clone();
- let startTarget = view.getPivot();
- let endTarget = bs.center;
- let startRadius = view.radius;
- let endRadius = endPosition.distanceTo(endTarget);
- let easing = TWEEN.Easing.Quartic.Out;
- { // animate camera position
- let pos = startPosition.clone();
- let tween = new TWEEN.Tween(pos).to(endPosition, animationDuration);
- tween.easing(easing);
- tween.onUpdate(() => {
- view.position.copy(pos);
- });
- tween.start();
- }
- { // animate camera target
- let target = startTarget.clone();
- let tween = new TWEEN.Tween(target).to(endTarget, animationDuration);
- tween.easing(easing);
- tween.onUpdate(() => {
- view.lookAt(target);
- });
- tween.onComplete(() => {
- view.lookAt(target);
- this.dispatchEvent({type: 'focusing_finished', target: this});
- });
- this.dispatchEvent({type: 'focusing_started', target: this});
- tween.start();
- }
- };
- moveToGpsTimeVicinity(time){
- const result = Potree.Utils.findClosestGpsTime(time, viewer);
- const box = result.node.pointcloud.deepestNodeAt(result.position).getBoundingBox();
- const diameter = box.min.distanceTo(box.max);
- const camera = this.scene.getActiveCamera();
- const offset = camera.getWorldDirection(new THREE.Vector3()).multiplyScalar(diameter);
- const newCamPos = result.position.clone().sub(offset);
- this.scene.view.position.copy(newCamPos);
- this.scene.view.lookAt(result.position);
- }
- showAbout () {
- $(function () {
- $('#about-panel').dialog();
- });
- };
-
- getGpsTimeExtent(){
- const range = [Infinity, -Infinity];
- for(const pointcloud of this.scene.pointclouds){
- const attributes = pointcloud.pcoGeometry.pointAttributes.attributes;
- const aGpsTime = attributes.find(a => a.name === "gps-time");
- if(aGpsTime){
- range[0] = Math.min(range[0], aGpsTime.range[0]);
- range[1] = Math.max(range[1], aGpsTime.range[1]);
- }
- }
- return range;
- }
- fitToScreen (factor = 1, animationDuration = 0) {
- let box = this.getBoundingBox(this.scene.pointclouds);
- let node = new THREE.Object3D();
- node.boundingBox = box;
- this.zoomTo(node, factor, animationDuration);
- this.controls.stop();
- };
- toggleNavigationCube() {
- this.navigationCube.visible = !this.navigationCube.visible;
- }
- /* setView(pos, view) {
- if(!pos) return;
-
- switch(pos) {
- case "F":
- this.setFrontView(view);
- break;
- case "B":
- this.setBackView(view);
- break;
- case "L":
- this.setLeftView(view);
- break;
- case "R":
- this.setRightView(view);
- break;
- case "U":
- this.setTopView(view);
- break;
- case "D":
- this.setBottomView(view);
- break;
- }
- } */
-
- setTopView(view){
- view = view || this.scene.view
- view.setCubeView("Top")
- this.fitToScreen();
- };
-
- setBottomView(){
- this.scene.view.yaw = -Math.PI;
- this.scene.view.pitch = Math.PI / 2;
-
- this.fitToScreen();
- };
- setFrontView(view){
- view = view || this.scene.view
- view.yaw = 0;
- view.pitch = 0;
- this.fitToScreen();
- };
-
- setBackView(view){
- view = view || this.scene.view
- view.yaw = Math.PI;
- view.pitch = 0;
-
- this.fitToScreen();
- };
- setLeftView(){
- this.scene.view.yaw = -Math.PI / 2;
- this.scene.view.pitch = 0;
- this.fitToScreen();
- };
- setRightView () {
- this.scene.view.yaw = Math.PI / 2;
- this.scene.view.pitch = 0;
- this.fitToScreen();
- };
- flipYZ () {
- this.isFlipYZ = !this.isFlipYZ;
- // TODO flipyz
- console.log('TODO');
- }
-
- setCameraMode(mode){
- this.scene.cameraMode = mode;
- for(let pointcloud of this.scene.pointclouds) {
- pointcloud.material.useOrthographicCamera = mode == CameraMode.ORTHOGRAPHIC;
- }
- }
- getProjection(){
- const pointcloud = this.scene.pointclouds[0];
- if(pointcloud){
- return pointcloud.projection;
- }else{
- return null;
- }
- }
- async loadProject(url){
- const response = await fetch(url);
- if(response.ok){
- const text = await response.text();
- const json = JSON5.parse(text);
- // const json = JSON.parse(text);
- if(json.type === "Potree"){
- Potree.loadProject(viewer, json);
- }
-
- }else{
- console.warn("未能加载:"+url )
- }
-
- }
- saveProject(){
- return Potree.saveProject(this);
- }
-
- loadSettingsFromURL(){
- if(Utils.getParameterByName("pointSize")){
- this.setPointSize(parseFloat(Utils.getParameterByName("pointSize")));
- }
-
- if(Utils.getParameterByName("FOV")){
- this.setFOV(parseFloat(Utils.getParameterByName("FOV")));
- }
-
- if(Utils.getParameterByName("opacity")){
- this.setOpacity(parseFloat(Utils.getParameterByName("opacity")));
- }
-
- if(Utils.getParameterByName("edlEnabled")){
- let enabled = Utils.getParameterByName("edlEnabled") === "true";
- this.setEDLEnabled(enabled);
- }
- if (Utils.getParameterByName('edlRadius')) {
- this.setEDLRadius(parseFloat(Utils.getParameterByName('edlRadius')));
- }
- if (Utils.getParameterByName('edlStrength')) {
- this.setEDLStrength(parseFloat(Utils.getParameterByName('edlStrength')));
- }
- if (Utils.getParameterByName('pointBudget')) {
- this.setPointBudget(parseFloat(Utils.getParameterByName('pointBudget')));
- }
- if (Utils.getParameterByName('showBoundingBox')) {
- let enabled = Utils.getParameterByName('showBoundingBox') === 'true';
- if (enabled) {
- this.setShowBoundingBox(true);
- } else {
- this.setShowBoundingBox(false);
- }
- }
- if (Utils.getParameterByName('material')) {
- let material = Utils.getParameterByName('material');
- this.setMaterial(material);
- }
- if (Utils.getParameterByName('pointSizing')) {
- let sizing = Utils.getParameterByName('pointSizing');
- this.setPointSizing(sizing);
- }
- if (Utils.getParameterByName('quality')) {
- let quality = Utils.getParameterByName('quality');
- this.setQuality(quality);
- }
- if (Utils.getParameterByName('position')) {
- let value = Utils.getParameterByName('position');
- value = value.replace('[', '').replace(']', '');
- let tokens = value.split(';');
- let x = parseFloat(tokens[0]);
- let y = parseFloat(tokens[1]);
- let z = parseFloat(tokens[2]);
- this.scene.view.position.set(x, y, z);
- }
- if (Utils.getParameterByName('target')) {
- let value = Utils.getParameterByName('target');
- value = value.replace('[', '').replace(']', '');
- let tokens = value.split(';');
- let x = parseFloat(tokens[0]);
- let y = parseFloat(tokens[1]);
- let z = parseFloat(tokens[2]);
- this.scene.view.lookAt(new THREE.Vector3(x, y, z));
- }
- if (Utils.getParameterByName('background')) {
- let value = Utils.getParameterByName('background');
- this.setBackground(value);
- }
- // if(Utils.getParameterByName("elevationRange")){
- // let value = Utils.getParameterByName("elevationRange");
- // value = value.replace("[", "").replace("]", "");
- // let tokens = value.split(";");
- // let x = parseFloat(tokens[0]);
- // let y = parseFloat(tokens[1]);
- //
- // this.setElevationRange(x, y);
- // //this.scene.view.target.set(x, y, z);
- // }
- };
- // ------------------------------------------------------------------------------------
- // Viewer Internals
- // ------------------------------------------------------------------------------------
- createControls () {
- { // create FIRST PERSON CONTROLS
- this.fpControls = new FirstPersonControls(this, this.mainViewport);
- this.fpControls.enabled = false;
- this.fpControls.addEventListener('start', this.disableAnnotations.bind(this));
- this.fpControls.addEventListener('end', this.enableAnnotations.bind(this));
- /* this.addEventListener("loadPointCloudDone", ()=>{
- let boundPlane = new THREE.Box3()
- boundPlane.expandByPoint(this.bound.boundingBox.min.clone())//最低高度为bound的最低
- boundPlane.expandByPoint(this.bound.boundingBox.max.clone().setZ(this.bound.center.z))//最高高度为bound的中心高度
- FirstPersonControls.boundPlane = boundPlane
- FirstPersonControls.standardSpeed = THREE.Math.clamp( Math.sqrt(this.bound.boundSize.length() )/ 100 , 0.02,0.5); //在这个boundPlane中的速度
- }) */
-
- }
- // { // create GEO CONTROLS
- // this.geoControls = new GeoControls(this.scene.camera, this.renderer.domElement);
- // this.geoControls.enabled = false;
- // this.geoControls.addEventListener("start", this.disableAnnotations.bind(this));
- // this.geoControls.addEventListener("end", this.enableAnnotations.bind(this));
- // this.geoControls.addEventListener("move_speed_changed", (event) => {
- // this.setMoveSpeed(this.geoControls.moveSpeed);
- // });
- // }
- { // create ORBIT CONTROLS
- this.orbitControls = new OrbitControls(this);
- this.orbitControls.enabled = false;
- this.orbitControls.addEventListener('start', this.disableAnnotations.bind(this));
- this.orbitControls.addEventListener('end', this.enableAnnotations.bind(this));
- }
- { // create EARTH CONTROLS
- this.earthControls = new EarthControls(this);
- this.earthControls.enabled = false;
- this.earthControls.addEventListener('start', this.disableAnnotations.bind(this));
- this.earthControls.addEventListener('end', this.enableAnnotations.bind(this));
- }
- { // create DEVICE ORIENTATION CONTROLS
- this.deviceControls = new DeviceOrientationControls(this);
- this.deviceControls.enabled = false;
- this.deviceControls.addEventListener('start', this.disableAnnotations.bind(this));
- this.deviceControls.addEventListener('end', this.enableAnnotations.bind(this));
- }
- { // create VR CONTROLS
- this.vrControls = new VRControls(this);
- this.vrControls.enabled = false;
- this.vrControls.addEventListener('start', this.disableAnnotations.bind(this));
- this.vrControls.addEventListener('end', this.enableAnnotations.bind(this));
- }
- };
- toggleSidebar () {
- let renderArea = $('#potree_render_area');
- let isVisible = renderArea.css('left') !== '0px';
- if (isVisible) {
- renderArea.css('left', '0px');
- } else {
- renderArea.css('left', '300px');
- }
- };
- toggleMap () {
- // let map = $('#potree_map');
- // map.toggle(100);
- if (this.mapView) {
- this.mapView.toggle();
- }
- };
- onGUILoaded(callback){
- if(this.guiLoaded){
- callback();
- }else{
- this.guiLoadTasks.push(callback);
- }
- }
- promiseGuiLoaded(){
- return new Promise( resolve => {
- if(this.guiLoaded){
- resolve();
- }else{
- this.guiLoadTasks.push(resolve);
- }
-
- });
- }
- loadGUI(callback){
- if(callback){
- this.onGUILoaded(callback);
- }
- let viewer = this;
- let sidebarContainer = $('#potree_sidebar_container');
- sidebarContainer.load(new URL(Potree.scriptPath + '/sidebar.html').href, () => {
- sidebarContainer.css('width', '300px');
- sidebarContainer.css('height', '100%');
- let imgMenuToggle = document.createElement('img');
- imgMenuToggle.src = new URL(Potree.resourcePath + '/icons/menu_button.svg').href;
- imgMenuToggle.onclick = this.toggleSidebar;
- imgMenuToggle.classList.add('potree_menu_toggle');
- let imgMapToggle = document.createElement('img');
- imgMapToggle.src = new URL(Potree.resourcePath + '/icons/map_icon.png').href;
- imgMapToggle.style.display = 'none';
- imgMapToggle.onclick = e => { this.toggleMap(); };
- imgMapToggle.id = 'potree_map_toggle';
-
- let elButtons = $("#potree_quick_buttons").get(0);
- elButtons.append(imgMenuToggle);
- elButtons.append(imgMapToggle);
- /*
- VRButton.createButton(this.renderer).then(vrButton => {
- if(vrButton == null){
- console.log("VR not supported or active.");
- return;
- }
- this.renderer.xr.enabled = true;
- let element = vrButton.element;
- element.style.position = "";
- element.style.bottom = "";
- element.style.left = "";
- element.style.margin = "4px";
- element.style.fontSize = "100%";
- element.style.width = "2.5em";
- element.style.height = "2.5em";
- element.style.padding = "0";
- element.style.textShadow = "black 2px 2px 2px";
- element.style.display = "block";
- elButtons.append(element);
- vrButton.onStart(() => {
- this.dispatchEvent({type: "vr_start"});
- });
- vrButton.onEnd(() => {
- this.dispatchEvent({type: "vr_end"});
- });
- });
-
- this.mapView = new MapView(this);
- this.mapView.init(); */
-
- i18n.init({
- lng: 'en',
- resGetPath: Potree.resourcePath + '/lang/__lng__/__ns__.json',
- preload: ['en', 'fr', 'de', 'jp', 'se', 'es', 'zh'],
- getAsync: true,
- debug: false
- }, function (t) {
- // Start translation once everything is loaded
- $('body').i18n();
- });
- $(() => {
- //initSidebar(this);
- let sidebar = new Sidebar(this);
- sidebar.init();
- this.sidebar = sidebar;
- //if (callback) {
- // $(callback);
- //}
- let elProfile = $('<div>').load(new URL(Potree.scriptPath + '/profile.html').href, () => {
- $(document.body).append(elProfile.children());
- this.profileWindow = new ProfileWindow(this);
- this.profileWindowController = new ProfileWindowController(this);
- $('#profile_window').draggable({
- handle: $('#profile_titlebar'),
- containment: $(document.body)
- });
- $('#profile_window').resizable({
- containment: $(document.body),
- handles: 'n, e, s, w'
- });
- $(() => {
- this.guiLoaded = true;
- for(let task of this.guiLoadTasks){
- task();
- }
- });
- });
-
- });
-
- });
- return this.promiseGuiLoaded();
- }
- setLanguage (lang) {
- i18n.setLng(lang);
- $('body').i18n();
- }
- setServer (server) {
- this.server = server;
- }
- initDragAndDrop(){
- function allowDrag(e) {
- e.dataTransfer.dropEffect = 'copy';
- e.preventDefault();
- }
- let dropHandler = async (event) => {
- console.log(event);
- event.preventDefault();
- for(const item of event.dataTransfer.items){
- console.log(item);
- if(item.kind !== "file"){
- continue;
- }
- const file = item.getAsFile();
- const isJson = file.name.toLowerCase().endsWith(".json");
- const isGeoPackage = file.name.toLowerCase().endsWith(".gpkg");
- if(isJson){
- try{
- const text = await file.text();
- const json = JSON.parse(text);
- if(json.type === "Potree"){
- Potree.loadProject(viewer, json);
- }
- }catch(e){
- console.error("failed to parse the dropped file as JSON");
- console.error(e);
- }
- }else if(isGeoPackage){
- const hasPointcloud = viewer.scene.pointclouds.length > 0;
- if(!hasPointcloud){
- let msg = "At least one point cloud is needed that specifies the ";
- msg += "coordinate reference system before loading vector data.";
- console.error(msg);
- }else{
- proj4.defs("WGS84", "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs");
- proj4.defs("pointcloud", this.getProjection());
- let transform = proj4("WGS84", "pointcloud");
- const buffer = await file.arrayBuffer();
- const params = {
- transform: transform,
- source: file.name,
- };
-
- const geo = await Potree.GeoPackageLoader.loadBuffer(buffer, params);
- viewer.scene.addGeopackage(geo);
- }
- }
-
- }
- };
- $("body")[0].addEventListener("dragenter", allowDrag);
- $("body")[0].addEventListener("dragover", allowDrag);
- $("body")[0].addEventListener("drop", dropHandler);
- }
-
-
-
- updateAnnotations () {
- if(!this.visibleAnnotations){
- this.visibleAnnotations = new Set();
- }
- this.scene.annotations.updateBounds();
- this.scene.cameraP.updateMatrixWorld();
- this.scene.cameraO.updateMatrixWorld();
-
- let distances = [];
- let renderAreaSize = this.renderer.getSize(new THREE.Vector2());
- let viewer = this;
- let visibleNow = [];
- this.scene.annotations.traverse(annotation => {
- if (annotation === this.scene.annotations) {
- return true;
- }
- if (!annotation.visible) {
- return false;
- }
- annotation.scene = this.scene;
- let element = annotation.domElement;
- let position = annotation.position.clone();
- position.add(annotation.offset);
- if (!position) {
- position = annotation.boundingBox.getCenter(new THREE.Vector3());
- }
- let distance = viewer.scene.cameraP.position.distanceTo(position);
- let radius = annotation.boundingBox.getBoundingSphere(new THREE.Sphere()).radius;
- let screenPos = new THREE.Vector3();
- let screenSize = 0;
- {
- // SCREEN POS
- screenPos.copy(position).project(this.scene.getActiveCamera());
- screenPos.x = renderAreaSize.x * (screenPos.x + 1) / 2;
- screenPos.y = renderAreaSize.y * (1 - (screenPos.y + 1) / 2);
- // SCREEN SIZE
- if(viewer.scene.cameraMode == CameraMode.PERSPECTIVE) {
- let fov = Math.PI * viewer.scene.cameraP.fov / 180;
- let slope = Math.tan(fov / 2.0);
- let projFactor = 0.5 * renderAreaSize.y / (slope * distance);
- screenSize = radius * projFactor;
- } else {
- screenSize = Utils.projectedRadiusOrtho(radius, viewer.scene.cameraO.projectionMatrix, renderAreaSize.x, renderAreaSize.y);
- }
- }
- element.css("left", screenPos.x + "px");
- element.css("top", screenPos.y + "px");
- //element.css("display", "block");
- let zIndex = 10000000 - distance * (10000000 / this.scene.cameraP.far);
- if(annotation.descriptionVisible){
- zIndex += 10000000;
- }
- element.css("z-index", parseInt(zIndex));
- if(annotation.children.length > 0){
- let expand = screenSize > annotation.collapseThreshold || annotation.boundingBox.containsPoint(this.scene.getActiveCamera().position);
- annotation.expand = expand;
- if (!expand) {
- //annotation.display = (screenPos.z >= -1 && screenPos.z <= 1);
- let inFrustum = (screenPos.z >= -1 && screenPos.z <= 1);
- if(inFrustum){
- visibleNow.push(annotation);
- }
- }
- return expand;
- } else {
- //annotation.display = (screenPos.z >= -1 && screenPos.z <= 1);
- let inFrustum = (screenPos.z >= -1 && screenPos.z <= 1);
- if(inFrustum){
- visibleNow.push(annotation);
- }
- }
-
- });
- let notVisibleAnymore = new Set(this.visibleAnnotations);
- for(let annotation of visibleNow){
- annotation.display = true;
-
- notVisibleAnymore.delete(annotation);
- }
- this.visibleAnnotations = visibleNow;
- for(let annotation of notVisibleAnymore){
- annotation.display = false;
- }
- }
- updateMaterialDefaults(pointcloud){
- // PROBLEM STATEMENT:
- // * [min, max] of intensity, source id, etc. are computed as point clouds are loaded
- // * the point cloud material won't know the range it should use until some data is loaded
- // * users can modify the range at runtime, but sensible default ranges should be
- // applied even if no GUI is present
- // * display ranges shouldn't suddenly change even if the actual range changes over time.
- // e.g. the root node has intensity range [1, 478]. One of the descendants increases range to
- // [0, 2047]. We should not automatically change to the new range because that would result
- // in sudden and drastic changes of brightness. We should adjust the min/max of the sidebar slider.
- const material = pointcloud.material;
- const attIntensity = pointcloud.getAttribute("intensity");
-
- if(attIntensity != null && material.intensityRange[0] === Infinity){
- material.intensityRange = [...attIntensity.range];
- }
- // const attIntensity = pointcloud.getAttribute("intensity");
- // if(attIntensity && material.intensityRange[0] === Infinity){
- // material.intensityRange = [...attIntensity.range];
- // }
- // let attributes = pointcloud.getAttributes();
- // for(let attribute of attributes.attributes){
- // if(attribute.range){
- // let range = [...attribute.range];
- // material.computedRange.set(attribute.name, range);
- // //material.setRange(attribute.name, range);
- // }
- // }
- }
- update(delta, timestamp){
- if(Potree.measureTimings) performance.mark("update-start");
- this.dispatchEvent({
- type: 'update_start',
- delta: delta,
- timestamp: timestamp});
-
-
- this.updateScreenSize() //判断是否改变canvas大小
-
-
- const scene = this.scene;
- const camera = scene.getActiveCamera();
- const visiblePointClouds = this.scene.pointclouds.filter(pc => pc.visible)
-
- Potree.pointLoadLimit = Potree.pointBudget * 2;
- const lTarget = camera.position.clone().add(camera.getWorldDirection(new THREE.Vector3()).multiplyScalar(1000));
- this.scene.directionalLight.position.copy(camera.position);
- this.scene.directionalLight.lookAt(lTarget);
-
- for (let pointcloud of visiblePointClouds) {
- pointcloud.showBoundingBox = this.showBoundingBox;
- pointcloud.generateDEM = this.generateDEM;
- pointcloud.minimumNodePixelSize = this.minNodeSize;
- let material = pointcloud.material;
- material.uniforms.uFilterReturnNumberRange.value = this.filterReturnNumberRange;
- material.uniforms.uFilterNumberOfReturnsRange.value = this.filterNumberOfReturnsRange;
- material.uniforms.uFilterGPSTimeClipRange.value = this.filterGPSTimeRange;
- material.uniforms.uFilterPointSourceIDClipRange.value = this.filterPointSourceIDRange;
- material.classification = this.classifications;
- material.recomputeClassification();
- this.updateMaterialDefaults(pointcloud);
- }
- {
- if(this.showBoundingBox){
- let bbRoot = this.scene.scene.getObjectByName("potree_bounding_box_root");
- if(!bbRoot){
- let node = new THREE.Object3D();
- node.name = "potree_bounding_box_root";
- this.scene.scene.add(node);
- bbRoot = node;
- }
- let visibleBoxes = [];
- for(let pointcloud of this.scene.pointclouds){
- for(let node of pointcloud.visibleNodes.filter(vn => vn.boundingBoxNode !== undefined)){
- let box = node.boundingBoxNode;
- visibleBoxes.push(box);
- }
- }
- bbRoot.children = visibleBoxes;
- }
- }
- if (!this.freeze) {
-
- /*let cameraGroup = []
- let size = this.renderer.getSize(new THREE.Vector2())
- if(this.viewports){
- this.viewports.forEach(viewport=>{
- if(!viewport.active)return
- cameraGroup.push({camera:viewport.camera, areaSize:new THREE.Vector2(Math.floor(size.x * viewport.width), Math.floor(size.y * viewport.height))})
- })
- }else{
- cameraGroup.push({camera, areaSize:size})
- }
- let result = Potree.updatePointClouds(scene.pointclouds, cameraGroup );
- */
- // DEBUG - ONLY DISPLAY NODES THAT INTERSECT MOUSE
- //if(false){
- // let renderer = viewer.renderer;
- // let mouse = viewer.inputHandler.mouse;
- // let nmouse = {
- // x: (mouse.x / renderer.domElement.clientWidth) * 2 - 1,
- // y: -(mouse.y / renderer.domElement.clientHeight) * 2 + 1
- // };
- // let pickParams = {};
- // //if(params.pickClipped){
- // // pickParams.pickClipped = params.pickClipped;
- // //}
- // pickParams.x = mouse.x;
- // pickParams.y = renderer.domElement.clientHeight - mouse.y;
- // let raycaster = new THREE.Raycaster();
- // raycaster.setFromCamera(nmouse, camera);
- // let ray = raycaster.ray;
- // for(let pointcloud of scene.pointclouds){
- // let nodes = pointcloud.nodesOnRay(pointcloud.visibleNodes, ray);
- // pointcloud.visibleNodes = nodes;
- // }
- //}
- // const tStart = performance.now();
- // const worldPos = new THREE.Vector3();
- // const camPos = viewer.scene.getActiveCamera().getWorldPosition(new THREE.Vector3());
- // let lowestDistance = Infinity;
- // let numNodes = 0;
- // viewer.scene.scene.traverse(node => {
- // node.getWorldPosition(worldPos);
- // const distance = worldPos.distanceTo(camPos);
- // lowestDistance = Math.min(lowestDistance, distance);
- // numNodes++;
- // if(Number.isNaN(distance)){
- // console.error(":(");
- // }
- // });
- // const duration = (performance.now() - tStart).toFixed(2);
- // Potree.debug.computeNearDuration = duration;
- // Potree.debug.numNodes = numNodes;
- //console.log(lowestDistance.toString(2), duration);
- //搬走
- /* const tStart = performance.now();
- const campos = camera.position;
- let closestImage = Infinity;
- for(const images of this.scene.orientedImages){
- for(const image of images.images){
- const distance = image.mesh.position.distanceTo(campos);
- closestImage = Math.min(closestImage, distance);
- }
- }
- const tEnd = performance.now();
- if(result.lowestSpacing !== Infinity){
- let near = result.lowestSpacing * 10.0;
- let far = -this.getBoundingBox().applyMatrix4(camera.matrixWorldInverse).min.z;
- far = Math.max(far * 1.5, 10000);
- near = Math.min(100.0, Math.max(0.01, near));
- near = Math.min(near, closestImage);
- far = Math.max(far, near + 10000);
- if(near === Infinity){
- near = 0.1;
- }
-
- camera.near = near;
- camera.far = far;
- }else{
- // don't change near and far in this case
- }
- if(this.scene.cameraMode == CameraMode.ORTHOGRAPHIC) {
- camera.near = -camera.far;
- }*/
- }
-
-
-
-
-
-
-
-
-
-
- this.scene.cameraP.fov = this.fov;
-
- let controls = this.getControls();
- if (controls === this.deviceControls) {
- this.controls.setScene(scene);
- this.controls.update(delta);
- this.scene.cameraP.position.copy(scene.view.position);
- this.scene.cameraO.position.copy(scene.view.position);
- } else if (controls !== null) {
- controls.setScene(scene);
- controls.update(delta);
-
- //更新camera
- this.viewports.forEach(viewport=>{
- if(!viewport.active)return
- viewport.view.applyToCamera(viewport.camera)
-
- })
- }
-
- /* this.viewports.forEach(e=>{//判断camera画面是否改变
- if(e.cameraChanged()){
- this.dispatchEvent({
- type: "camera_changed",
- camera: e.camera,
- viewport : e
- })
-
- }
- }) */
-
- this.cameraChanged()//判断camera画面是否改变
-
- /* {//判断camera画面是否改变
- if(this._previousCamera === undefined){
- this._previousCamera = this.scene.getActiveCamera().clone();
- this._previousCamera.rotation.copy(this.scene.getActiveCamera().rotation);
- }
- if(!this._previousCamera.matrixWorld.equals(camera.matrixWorld) ||
- !this._previousCamera.projectionMatrix.equals(camera.projectionMatrix)
- ){
- this.dispatchEvent({
- type: "camera_changed",
- previous: this._previousCamera,
- camera: camera
- });
- }
- this._previousCamera = this.scene.getActiveCamera().clone();
- this._previousCamera.rotation.copy(this.scene.getActiveCamera().rotation);
- } */
-
- { // update clip boxes
- let boxes = [];
-
- // volumes with clipping enabled
- //boxes.push(...this.scene.volumes.filter(v => (v.clip)));
- boxes.push(...this.scene.volumes.filter(v => (v.clip && v instanceof BoxVolume)));
- // profile segments
- for(let profile of this.scene.profiles){
- boxes.push(...profile.boxes);
- }
-
- // Needed for .getInverse(), pre-empt a determinant of 0, see #815 / #816
- let degenerate = (box) => box.matrixWorld.determinant() !== 0;
-
- let clipBoxes = boxes.filter(degenerate).map( box => {
- box.updateMatrixWorld();
-
- let boxInverse = box.matrixWorld.clone().invert();
- let boxPosition = box.getWorldPosition(new THREE.Vector3());
- return {box: box, inverse: boxInverse, position: boxPosition};
- });
- let clipPolygons = this.scene.polygonClipVolumes.filter(vol => vol.initialized);
-
- // set clip volumes in material
- for(let pointcloud of visiblePointClouds){
- pointcloud.material.setClipBoxes(clipBoxes);
- pointcloud.material.setClipPolygons(clipPolygons, this.clippingTool.maxPolygonVertices);
- pointcloud.material.clipTask = this.clipTask;
- pointcloud.material.clipMethod = this.clipMethod;
- }
- }
- {
- for(let pointcloud of visiblePointClouds){
- pointcloud.material.elevationGradientRepeat = this.elevationGradientRepeat;
- }
- }
-
- { // update navigation cube
- this.navigationCube.update(camera.rotation);
- }
- this.updateAnnotations();
-
- if(this.mapView){
- this.mapView.update(delta);
- if(this.mapView.sceneProjection){
- $( "#potree_map_toggle" ).css("display", "block");
-
- }
- }
- TWEEN.update(timestamp);
- transitions.update(delta);
- this.transformationTool.update();
-
- this.dispatchEvent({
- type: 'update',
- delta: delta,
- timestamp: timestamp});
-
- if(Potree.measureTimings) {
- performance.mark("update-end");
- performance.measure("update", "update-start", "update-end");
- }
-
-
- //add ------
- this.reticule.updateVisible()
- this.mapViewer.update(delta)
- }
- updateViewPointcloud(camera, areaSize, isViewport){
-
-
- let result = Potree.updatePointClouds(this.scene.pointclouds, camera, areaSize );
-
- //if(isViewport)return
- const tStart = performance.now();
- const campos = camera.position;
- let closestImage = Infinity;
- for(const images of this.scene.orientedImages){
- for(const image of images.images){
- const distance = image.mesh.position.distanceTo(campos);
- closestImage = Math.min(closestImage, distance);
- }
- }
- const tEnd = performance.now();
- //改:不根据点云修改视野near far
- var near = camera.near, far = camera.far
-
- if(!camera.limitFar && result.lowestSpacing !== Infinity){
-
- //let near = result.lowestSpacing * 10.0;
- let far = -this.getBoundingBox().applyMatrix4(camera.matrixWorldInverse).min.z;
- far = Math.max(far * 1.5, 10000);
- //near = Math.min(100.0, Math.max(0.01, near));
- //near = Math.min(near, closestImage);
- far = Math.max(far, near + 10000);
- /* if(near === Infinity){
- near = 0.1;
- } */
-
- //camera.near = near; //为了其他物体的显示,不修改near
- camera.far = far;
- }
- /* if(this.scene.cameraMode == CameraMode.ORTHOGRAPHIC) {//???
- camera.near = -camera.far;
- } */
- if(/* near != camera.near || */far != camera.far){
- camera.updateProjectionMatrix()
- }
-
- //注:pointcloud.visibleNodes会随着near far自动更新
- }
-
-
-
- getPRenderer(){
- if(this.useHQ){
- if (!this.hqRenderer) {
- this.hqRenderer = new HQSplatRenderer(this);
- }
- this.hqRenderer.useEDL = this.useEDL;
- return this.hqRenderer;
- }else{
- /* if (this.useEDL && Features.SHADER_EDL.isSupported()) {
- if (!this.edlRenderer) {
- this.edlRenderer = new EDLRenderer(this);
- }
- return this.edlRenderer;
- } else {
- if (!this.potreeRenderer) {
- this.potreeRenderer = new PotreeRenderer(this);
- }
- return this.potreeRenderer;
- } */
-
- if (!this.edlRenderer) {
- this.edlRenderer = new EDLRenderer(this);
- }
- return this.edlRenderer;
-
- }
- }
- renderVR(){
- let renderer = this.renderer;
- renderer.setClearColor(0x550000, 0);
- renderer.clear();
- let xr = renderer.xr;
- let dbg = new THREE.PerspectiveCamera();
- let xrCameras = xr.getCamera(dbg);
- if(xrCameras.cameras.length !== 2){
- return;
- }
- let makeCam = this.vrControls.getCamera.bind(this.vrControls);
- { // clear framebuffer
- if(viewer.background === "skybox"){
- renderer.setClearColor(0xff0000, 1);
- }else if(viewer.background === "gradient"){
- renderer.setClearColor(0x112233, 1);
- }else if(viewer.background === "black"){
- renderer.setClearColor(0x000000, 1);
- }else if(viewer.background === "white"){
- renderer.setClearColor(0xFFFFFF, 1);
- }else{
- renderer.setClearColor(0x000000, 0);
- }
- renderer.clear();
- }
- // render background
- if(this.background === "skybox"){
- let {skybox} = this;
- let cam = makeCam();
- skybox.camera.rotation.copy(cam.rotation);
- skybox.camera.fov = cam.fov;
- skybox.camera.aspect = cam.aspect;
-
- // let dbg = new THREE.Object3D();
- let dbg = skybox.parent;
- // dbg.up.set(0, 0, 1);
- dbg.rotation.x = Math.PI / 2;
- // skybox.camera.parent = dbg;
- // dbg.children.push(skybox.camera);
- dbg.updateMatrix();
- dbg.updateMatrixWorld();
- skybox.camera.updateMatrix();
- skybox.camera.updateMatrixWorld();
- skybox.camera.updateProjectionMatrix();
- renderer.render(skybox.scene, skybox.camera);
- // renderer.render(skybox.scene, cam);
- }else if(this.background === "gradient"){
- // renderer.render(this.scene.sceneBG, this.scene.cameraBG);
- }
- this.renderer.xr.getSession().updateRenderState({
- depthNear: 0.1,
- depthFar: 10000
- });
-
- let cam = null;
- let view = null;
- { // render world scene
- cam = makeCam();
- cam.position.z -= 0.8 * cam.scale.x;
- cam.parent = null;
- // cam.near = 0.05;
- cam.near = viewer.scene.getActiveCamera().near;
- cam.far = viewer.scene.getActiveCamera().far;
- cam.updateMatrix();
- cam.updateMatrixWorld();
- this.scene.scene.updateMatrix();
- this.scene.scene.updateMatrixWorld();
- this.scene.scene.matrixAutoUpdate = false;
- let camWorld = cam.matrixWorld.clone();
- view = camWorld.clone().invert();
- this.scene.scene.matrix.copy(view);
- this.scene.scene.matrixWorld.copy(view);
- cam.matrix.identity();
- cam.matrixWorld.identity();
- cam.matrixWorldInverse.identity();
- renderer.render(this.scene.scene, cam);
- this.scene.scene.matrixWorld.identity();
- }
-
- for(let pointcloud of this.scene.pointclouds){
- let viewport = xrCameras.cameras[0].viewport;
- pointcloud.material.useEDL = false;
- pointcloud.screenHeight = viewport.height;
- pointcloud.screenWidth = viewport.width;
- // automatically switch to paraboloids because they cause far less flickering in VR,
- // when point sizes are larger than around 2 pixels
- // if(Features.SHADER_INTERPOLATION.isSupported()){
- // pointcloud.material.shape = Potree.PointShape.PARABOLOID;
- // }
- }
-
- // render point clouds
- for(let xrCamera of xrCameras.cameras){
- let v = xrCamera.viewport;
- renderer.setViewport(v.x, v.y, v.width, v.height);
- // xrCamera.fov = 90;
- { // estimate VR fov
- let proj = xrCamera.projectionMatrix;
- let inv = proj.clone().invert();
- let p1 = new THREE.Vector4(0, 1, -1, 1).applyMatrix4(inv);
- let rad = p1.y
- let fov = 180 * (rad / Math.PI);
- xrCamera.fov = fov;
- }
- for(let pointcloud of this.scene.pointclouds){
- const {material} = pointcloud;
- material.useEDL = false;
- }
- let vrWorld = view.clone().invert();
- vrWorld.multiply(xrCamera.matrixWorld);
- let vrView = vrWorld.clone().invert();
- this.pRenderer.render(this.scene.scenePointCloud, xrCamera, null, {
- viewOverride: vrView,
- });
- }
- { // render VR scene
- let cam = makeCam();
- cam.parent = null;
- renderer.render(this.sceneVR, cam);
- }
- renderer.resetState();
- }
- clear(params={}){
- let background = params.background || this.background;
- let backgroundOpacity = params.backgroundOpacity == void 0 ? this.backgroundOpacity : params.backgroundOpacity//如果想完全透明,只需要backgroundOpacity为0
- let renderer = this.renderer
- //let gl = renderer.getContext()
-
- if(background instanceof THREE.Color){ //add
- renderer.setClearColor(background, backgroundOpacity);
- }else if(background === "skybox"){
- renderer.setClearColor(0x000000, 0);
- } else if (background === 'gradient') {
- renderer.setClearColor(0x000000, 0);
- } else if (background === 'black') {
- renderer.setClearColor(0x000000, 1);
- } else if (background === 'white') {
- renderer.setClearColor(0xFFFFFF, 1);
- } else {
- renderer.setClearColor(0x000000, 0);
- }
-
- params.target || renderer.clear();
-
-
- }
-
- renderDefault(params_={}){
-
- if(!this.visible || this.paused )return
-
- let pRenderer = this.getPRenderer();
-
- let renderSize
- if(params_.target){
- renderSize = new THREE.Vector2(params_.target.width, params_.target.height)
- if(!params_.viewports){
- console.warn('必须指定target的viewport! 且target大小和viewport.resolution2相同')
- }
- }else{
- renderSize = this.renderer.getSize(new THREE.Vector2());
- }
-
-
- var viewports = params_.viewports || this.viewports
- let needSResize = viewports.filter(e=>e.active).length > 1 || params_.resize
-
-
-
- viewports.forEach(view=>{
- let params = $.extend({},params_);
- params.viewport = view
- //if(!params.target){
- params.camera = params.camera || view.camera;
- params.extraEnableLayers = view.extraEnableLayers
- params.cameraLayers = view.cameraLayers
- //}
-
- if(!view.active)return
- var left,bottom,width,height
- {
- left = Math.floor(renderSize.x * view.left)
- bottom = Math.floor(renderSize.y * view.bottom)
-
- /* if(params_.target){//有target时最好viewport是专门建出来的
- width = Math.floor(renderSize.x * view.width)
- height = Math.floor(renderSize.y * view.height)
- }else{ */
- width = view.resolution.x // 用的是client的width和height
- height = view.resolution.y
- //}
- if(width == 0 || height == 0)return
-
- let scissorTest = view.width<1 || view.height<1
- if(params_.target){
- params_.target.viewport.set(left, bottom, width, height);
- scissorTest && params_.target.scissor.set(left, bottom, width, height);
- params_.target.scissorTest = scissorTest
- }else{
- this.renderer.setViewport(left, bottom, width, height) //规定视口,影响图形变换
- scissorTest && this.renderer.setScissor( left, bottom, width, height );//规定渲染范围
- this.renderer.setScissorTest( scissorTest );//开启WebGL剪裁测试功能,如果不开启,.setScissor方法设置的范围不起作用 | width==1且height==1时开启会只有鼠标的地方刷新,很奇怪
-
- }
-
- }
-
- if(needSResize){
- this.emitResizeMsg( { viewport:view} )
- }
-
- //needSResize && this.emitResizeMsg({resolution: params_.target ? new THREE.Vector2(width,height) : view.resolution2, left:view.left, bottom:view.bottom })//resize everything such as lines targets
-
-
-
- viewer.dispatchEvent({type: "render.begin", viewer: viewer, viewport:view, params });
-
- if(view.render){
- view.render({
- target: params_.target, renderer:this.renderer, clear:this.clear.bind(this),
- renderOverlay: this.renderOverlay.bind(this), force:!view.noPointcloud //如果要渲染点云,必须也一直渲染地图,否则地图会被覆盖(点云目前未能获取是否改变,也可能有其他动态物体,所以还是一直渲染的好)
- })
- }
-
-
-
-
- if(!view.noPointcloud ){
-
- //if(!params.target){
- //params.width = width; params.height = height;
-
- //}
- if(view.render){
- params.noBG = true
- }
-
-
-
- view.beforeRender && view.beforeRender(view)
-
- this.updateViewPointcloud(params.camera, view.resolution2, true)
-
- params.background = view.background
- params.backgroundColor = view.backgroundColor
- params.backgroundOpacity = view.backgroundOpacity
-
- view.render || this.clear(params)
- pRenderer.clearTargets(params);
- pRenderer.render(params);
-
-
- {//渲染和地图共有的物体
- this.setCameraLayers(params.camera, [ 'bothMapAndScene' ] )
- this.renderer.render(this.scene.scene, params.camera);
- }
-
- this.renderOverlay(params)
-
- view.afterRender && view.afterRender(view)
- }
-
-
-
- this.dispatchEvent({type: "render.end", viewer: this, viewport:view });
- })
-
- this.renderer.setRenderTarget(null)
-
-
- }
-
- setLimitFar(state){//切换是否limitFar
- viewer.mainViewport.camera.limitFar = !!state
- if(state){
- viewer.mainViewport.camera.near = 0.1;
- viewer.mainViewport.camera.far = Potree.settings.displayMode == 'showPanos' ? viewer.farWhenShowPano : Potree.settings.cameraFar;
- viewer.mainViewport.camera.updateProjectionMatrix()
- }
- }
-
- renderOverlay(params){
-
- let camera = params.camera ? params.camera : this.scene.getActiveCamera();
-
- this.reticule.updateAtViewports(params.viewport)
-
-
- //为什么要在点云之后渲染,否则透明失效 、 会被点云覆盖
- let cameraLayers
- if(params.cameraLayers) cameraLayers = params.cameraLayers
- else{
- if(params.isMap)cameraLayers = ['reticule']
- else cameraLayers = ['sceneObjects','marker','reticule' /* 'bothMapAndScene' */];
- }
-
-
- if(cameraLayers.length){
- this.setCameraLayers(camera, cameraLayers, params.extraEnableLayers) //透明贴图层 skybox 、reticule marker 不能遮住测量线
- this.renderer.render(this.scene.scene, camera);
- }
-
- this.dispatchEvent({type: "render.pass.scene", viewer: viewer});
-
- //清除深度 !!!!
- this.renderer.clearDepth();
- //this.transformationTool.update();
-
-
-
- if(!params.magnifier){
- //测量线
- this.dispatchEvent({type: "render.pass.perspective_overlay", camera});
-
- if(!params.screenshot && !params.isMap){
- this.setCameraLayers(camera, ['magnifier']) //magnifier 遮住测量线
- this.renderer.render(this.scene.scene, camera);
- }
- }
-
-
- this.setCameraLayers(camera, ['volume','transformationTool'])
- this.renderer.render(this.clippingTool.sceneVolume, camera);
- this.renderer.render(this.transformationTool.scene, camera);
-
-
- }
-
-
-
-
- setCameraLayers(camera, enableLayers, extraEnableLayers=[]){//add
- camera.layers.disableAll()
- enableLayers.concat(extraEnableLayers).forEach(e=>{
- let layer = Potree.config.renderLayers[e]
- if(layer == void 0){
- console.error('setCameraLayer没找到layer!');
- return
- }
- camera.layers.enable(layer)
- })
- }
- setObjectLayers(object, layerName){//add
- let layer = Potree.config.renderLayers[layerName]
- if(layer == void 0){
- console.error('setCameraLayer没找到layer!');
- return
- }
- object.traverse(e=>{
- e.layers.set(layer)
- })
- }
-
-
- updateVisible(object, reason, ifShow){//当所有加入的条件都不为false时才显示. reason='force'一般是强制、临时的
- if(!object.unvisibleReasons) object.unvisibleReasons = []; //如果length>0代表不可见
- /* let mapChange = ()=>{//还是算了,有时候可见性的改变 在mapViewer和mainViewer中交替,如reticule,就会频繁
- var layers = ['measure','map','mapObjects','bothMapAndScene']
- if(layers.some(e=> object.layers && (object.layers.mask == Potree.config.renderLayers[e]) )) {
- this.mapViewer.dispatchEvent({type:'content_changed'})
- }
- } */
-
- if(ifShow){
- var index = object.unvisibleReasons.indexOf(reason)
- if(index > -1){
- object.unvisibleReasons.splice(index, 1);
- if(object.unvisibleReasons.length == 0){
- object.visible = true;
- //mapChange()
- object.dispatchEvent({
- type: 'isVisible',
- visible:true,
- reason
- })
- }
- }
-
- }else{
- var visiBefore = object.visible
- if(!object.unvisibleReasons.includes(reason)) object.unvisibleReasons.push(reason)
- object.visible = false
- if(visiBefore) {
- //mapChange()
- object.dispatchEvent({
- type: 'isVisible',
- visible:false,
- reason,
- })
- }
-
- }
-
- }
-
- getObjVisiByReason(object,reason){//获取在某条件下是否可见. 注: 用户在数据集选择可不可见为"datasetSelection"
- if(object.visible)return true
- else{
- return !object.unvisibleReasons || !object.unvisibleReasons.includes(reason)
- }
- }
-
-
-
-
-
- /* 大规模WebGL应用引发浏览器崩溃的几种情况及解决办法
- https://blog.csdn.net/weixin_30378311/article/details/94846947 */
-
- render(params){//add params
- if(Potree.measureTimings) performance.mark("render-start");
- // if(!window.unableSetSize) return
- //try{
- //console.log('rendering')//在unfocus页面时就会停止渲染
- const vrActive = this.renderer.xr.isPresenting;
- if(vrActive){
- this.renderVR();
- }else{
- this.renderDefault(params);
- }
- /* }catch(e){
- this.onCrash(e);
- } */
-
- if(Potree.measureTimings){
- performance.mark("render-end");
- performance.measure("render", "render-start", "render-end");
- }
- }
-
- startScreenshot(info={}, width=800, height=400, compressRatio){//add
- let deferred = info.deferred || $.Deferred();
-
- if(this.images360.flying){//如果在飞,飞完再截图
- info.deferred = deferred
- this.images360.once('cameraMoveDone', this.startScreenshot.bind(this, info, width, height, compressRatio))
- return deferred.promise()
- }
-
- var sid = Date.now()
- //抗锯齿待加 1 post处理 2截图大张再抗锯齿缩小
-
- console.log('startScreenshot: '+sid)
-
-
-
- var screenshot = ()=>{
-
- viewer.mapViewer.needRender = true
-
-
- var { buffer } = this.makeScreenshot( new THREE.Vector2(width,height) );
-
- var dataUrl = Potree.Utils.pixelsArrayToDataUrl(buffer, width, height, compressRatio)
-
- if(!Potree.settings.isOfficial){
- Common.downloadFile(dataUrl, 'screenshot.jpg')
- }
-
-
-
- var finish = ()=>{
- deferred.resolve(dataUrl)
- console.log('screenshot done: '+sid)
- }
-
- {//恢复:
-
- if(info.type == 'measure'){
- this.scene.measurements.forEach(e=>this.updateVisible(e, 'screenshot',true))
- info.measurement.setSelected(false, 'screenshot')
- }
- this.images360.panos.forEach(pano=>{
- viewer.updateVisible(pano, 'screenshot', true)
- })
- viewer.updateVisible(this.reticule, 'screenshot', true)
- viewer.updateVisible(this.mapViewer.cursor, 'screenshot', true)
-
- if(oldStates.attachedToViewer != this.mapViewer.attachedToViewer){
- if(info.type == 'measure'){
- this.mapViewer.attachToMainViewer(false )
- }
- }
- mapViewport.camera.zoom = oldStates.mapZoom
- mapViewport.camera.updateProjectionMatrix()
-
- if(Potree.settings.displayMode == 'showPanos') {
- viewer.images360.flyToPano({pano:oldStates.pano, duration:0, callback:()=>{
- finish()
- }})
- }
-
- oldStates.viewports.forEach(old=>{//恢复相机
- var viewport = [mapViewport, mainViewport].find(v=>v.name == old.name);
- viewport.left = old.left;
- viewport.width = old.width;
- viewport.view.copy(old.view)
- viewport.view.applyToCamera(viewport.camera);
-
- })
-
- viewer.updateScreenSize({forceUpdateSize:true})//更新像素
-
- oldStates.viewports.forEach(old=>{//恢复相机
- var viewport = [mapViewport, mainViewport].find(v=>v.name == old.name);
- this.dispatchEvent({ //update map
- type: "camera_changed",
- camera: viewport.camera,
- viewport : viewport
- })
- })
-
- }
-
-
- if(Potree.settings.displayMode != 'showPanos') {
- finish()
- }
-
-
- }
-
- let mapViewport = this.mapViewer.viewports[0]
- let mainViewport = this.mainViewport
- let oldStates = {
- attachedToViewer : this.mapViewer.attachedToViewer,
- viewports : [mapViewport, mainViewport].map(e=>{
- return e.clone()
- }),
- mapZoom: mapViewport.camera.zoom,
- pano: Potree.settings.displayMode == 'showPanos' ? viewer.images360.currentPano : null,
- }
-
-
-
-
- this.images360.panos.forEach(pano=>{//令漫游点不可见
- viewer.updateVisible(pano, 'screenshot', false)
- })
-
- viewer.updateVisible(this.reticule, 'screenshot', false)//令reticule不可见
-
- viewer.updateVisible(this.mapViewer.cursor, 'screenshot', false)//令mapCursor不可见
-
-
- if(info.type == 'measure'){//要截图双屏
- this.scene.measurements.forEach(e=>this.updateVisible(e,'screenshot',e == info.measurement) )
- info.measurement.setSelected(true, 'screenshot')
-
- this.mapViewer.attachToMainViewer(true, 'measure', 0.5 )//不要移动相机去适应
-
- viewer.updateScreenSize({forceUpdateSize:true, width, height}) //更新viewports相机透视
-
- //不同角度截图 得到三维的会不一样,因为focusOnObject是根据方向的
- let promise = this.focusOnObject(info.measurement, 'measure', 0, /* {basePanoSize:1024} */ )
- promise.done(()=>{
- console.log('promise.done')
- this.viewports.forEach(e=>{
- e.view.applyToCamera(e.camera)
-
- this.dispatchEvent({ //update map
- type: "camera_changed",
- camera: e.camera,
- viewport : e
- })
-
- })
-
- let waitMap = ()=>{
- console.log('waitMap: '+sid)
- this.mapViewer.waitLoadDone(screenshot.bind(this))//等待地图所有加载完
-
- }
-
-
- /* if(Potree.settings.displayMode == 'showPanos'){//如果是全景图,要等全景的tile加载完
- //this.images360.checkAndWaitForTiledPanoLoad(this.images360.currentPano, this.images360.qualityManager.standardSize, ()=>{//done
- //loadTiledPano
- if(!this.images360.checkAndWaitForPanoLoad(this.images360.currentPano, this.images360.qualityManager.standardSize, ()=>{//done
- //standardSize maxNavPanoSize
- waitMap()
- })){
- waitMap()
- }
- }else{
- waitMap()
- } */ //512就可以
-
-
- //调不通,暂时先用setTimeout
-
- setTimeout(waitMap.bind(this), 1)
- })
-
- }else{
- screenshot()
- }
-
-
-
-
- return deferred.promise()
-
-
- }
-
- focusOnObject(object, type, duration, o={} ) {
- //飞向热点、测量线等 。
-
- console.log('focusOnObject: '+object.name, type)
-
- let deferred = o.deferred || $.Deferred();
- let target = new THREE.Vector3, //相机focus的位置
- position = new THREE.Vector3, //相机最终位置
- dis; //相机距离目标
- duration = duration == void 0 ? 1000 : duration;
- let camera = viewer.scene.getActiveCamera()
-
-
- if(this.images360.modeChanging){
- this.images360.once('endChangeMode',()=>{
- this.focusOnObject(object, type, duration, $.extend(o,{deferred}))
- })
- return deferred.promise();//不能打扰 从点云转向全景图时 的飞行
- }
- if (type == 'measure') {
-
-
-
- target.copy(object.getCenter())
-
-
- var cameraTemp = camera.clone()
-
- //试试改变位置,直视测量线。能避免倾斜角度造成的非常不居中、以及看不到面的情况
- if(object.facePlane/* && window.focusMeasureFaceToIt */){
- let normal
- if(object.facePlane){
- normal = object.facePlane.normal.clone()
- }
- let angle = this.scene.view.direction.angleTo(normal)
- let minDiff = Math.PI*0.25// 45度
- if(angle>minDiff && angle<Math.PI-minDiff){//当几乎正对时就不执行
- if(angle<Math.PI/2){ //在背面
- normal.negate()
- }
- let dir = new THREE.Vector3().subVectors(camera.position, target).normalize()
- let newDir = new THREE.Vector3().addVectors(dir,normal)//两个角度的中间
- cameraTemp.position.copy(target.clone().add(newDir))
- }
- }else if(object.points.length == 2){ //线段
- let lineDir = new THREE.Vector3().subVectors(object.points[0],object.points[1]).normalize()
- let angle = this.scene.view.direction.angleTo(lineDir)
- let maxDiff = Math.PI*0.25// 45度
- if(angle<maxDiff || angle>Math.PI-maxDiff){//当几乎正对时就不执行
- if(angle>Math.PI/2){ //令dir和lineDir成钝角
- lineDir.negate()
- }
- let dir = new THREE.Vector3().subVectors(camera.position, target).normalize()
- let mid = new THREE.Vector3().addVectors(lineDir, dir).normalize() //中间法向量(如果刚好dir和lineDir反向,那得到的为零向量,就不移动了,但一般不会酱紫吧)
- let newDir = new THREE.Vector3().addVectors(dir, mid)
- cameraTemp.position.copy(target.clone().add(newDir))
- }
- }else{
- console.error('measure 没有facePlane points点数还不为2?')
- }
-
-
- cameraTemp.lookAt(target);
- cameraTemp.updateMatrix();
- cameraTemp.updateMatrixWorld();
- //原始的bound
- let boundOri = new THREE.Box3()
- object.points.forEach(e=>{
- boundOri.expandByPoint(e)
- })
- let boundSizeOri = boundOri.getSize(new THREE.Vector3)
-
- //对镜头的bound
- var inv = cameraTemp.matrixWorldInverse;
-
- let bound = new THREE.Box3()
- object.points.forEach(e=>{
- var p = e.clone().applyMatrix4(inv);
- bound.expandByPoint(p)
- })
- let boundSize = bound.getSize(new THREE.Vector3)
-
-
- if(!this.boundBox){//调试
- this.boundBox = new THREE.Mesh(new THREE.BoxGeometry(1,1,1,1));
- this.boundBox.material.wireframe = true
- this.boundBox.up.set(0,0,1)
- this.boundBox.visible = false //打开以检查box
- this.setObjectLayers(this.boundBox,'sceneObjects')
- this.scene.scene.add(this.boundBox);
- }
-
-
- this.boundBox.position.copy(target)
- this.boundBox.scale.copy(boundSize)
- this.boundBox.lookAt(cameraTemp.position)
-
-
- {
- let scale = 1.1; //稍微放大一些,不然会靠到屏幕边缘
- boundSize.x *= scale
- boundSize.y *= scale
-
- }
-
-
-
- let aspect = boundSize.x / boundSize.y
- if(camera.aspect > aspect){//视野更宽则用bound的纵向来决定
- dis = boundSize.y/2/ Math.tan(THREE.Math.degToRad(camera.fov / 2)) + boundSize.z/2
- }else{
- let hfov = cameraLight.getHFOVForCamera(camera, true);
- dis = boundSize.x/2 / Math.tan(hfov / 2) + boundSize.z/2
- }
-
- //三个顶点以上的由于measure的中心不等于bound的中心,所以点会超出bound外。 且由于视椎近大远小,即使是两个点的,bound居中后线看上去仍旧不居中.
-
-
- if(this.mapViewer.attachedToViewer){
- //console.log('mapFocusOn: '+target.toArray())
- const minBound = new THREE.Vector2(1,1)//针对垂直线,在地图上只有一个点
- let boundSizeMap = boundSizeOri.clone().multiplyScalar(2)
- boundSizeMap.x = Math.max(minBound.x, boundSizeMap.x )
- boundSizeMap.y = Math.max(minBound.y, boundSizeMap.y )
- this.mapViewer.moveTo(target.clone(), boundSizeMap, duration)
- }
-
-
- //获得相机最佳位置
- let dir = new THREE.Vector3().subVectors(cameraTemp.position, target).normalize()
- position.copy(target).add(dir.multiplyScalar(dis))
-
- if(Potree.settings.displayMode == 'showPointCloud'){ //点云
-
-
- }else if(Potree.settings.displayMode == 'showPanos'){//全景 (比较难校准)
- let pano = viewer.images360.fitPanoTowardPoint({
- /*point : target, //不使用目标点来判断是因为缺少measure角度的信息。比如虽然可以靠近线的中心,但是线朝向屏幕,那几乎就是一个点了。
- //bestDistance : dis * 0.5, //乘以小数是为了尽量靠近
- boundSphere: boundOri.getBoundingSphere(new THREE.Sphere), */
-
- point : position,
- bestDistance : 0 ,
- })
-
- pano && viewer.images360.flyToPano({pano, target, duration, deferred, dontMoveMap:true , basePanoSize:o.basePanoSize})//dontMoveMap不要移动map,否则flytopano会自动在map中focus到漫游点的位置,而非测量线了
-
- if(!pano){
- console.error('no pano')
- }
- return deferred
- //出现过到达位置后测量线标签闪烁的情况
- }
-
- } else if (type == 'tag') {
- //dimension = 1
- target.copy(object.position)
- const bestDistance = 2
-
- {
- //console.log('mapFocusOn: '+target.toArray())
- this.mapViewer.moveTo(target.clone(), null, duration)
- }
-
- if(Potree.settings.displayMode == 'showPointCloud'){
- dis = bestDistance
- let dir = new THREE.Vector3().subVectors(camera.position, target).normalize()
- position.copy(target).add(dir.multiplyScalar(dis))
-
- }else if(Potree.settings.displayMode == 'showPanos'){
- let pano = viewer.images360.fitPanoTowardPoint({
- point : target,
- bestDistance //越近越好,但不要太近,bestDistance左右差不多
- })
- pano && viewer.images360.flyToPano({pano, target, duration, deferred, dontMoveMap:true , basePanoSize:o.basePanoSize })
- return deferred
- }
- }
-
-
-
- /*} else if(dimension == 2){//线
-
- }else if(dimension == 3){//面
-
- }else{//立体
-
- } */
- viewer.scene.view.setView(position, target, duration, ()=>{
- console.log('focusOnObjectSuccess: '+object.name, type)
- deferred.resolve()
- })
-
-
-
- return deferred.promise()
- }
-
- resolveTimings(timestamp){
- if(Potree.measureTimings){
- if(!this.toggle){
- this.toggle = timestamp;
- }
- let duration = timestamp - this.toggle;
- if(duration > 1000.0){
-
- let measures = performance.getEntriesByType("measure");
-
- let names = new Set();
- for(let measure of measures){
- names.add(measure.name);
- }
-
- let groups = new Map();
- for(let name of names){
- groups.set(name, {
- measures: [],
- sum: 0,
- n: 0,
- min: Infinity,
- max: -Infinity
- });
- }
-
- for(let measure of measures){
- let group = groups.get(measure.name);
- group.measures.push(measure);
- group.sum += measure.duration;
- group.n++;
- group.min = Math.min(group.min, measure.duration);
- group.max = Math.max(group.max, measure.duration);
- }
- let glQueries = Potree.resolveQueries(this.renderer.getContext());
- for(let [key, value] of glQueries){
- let group = {
- measures: value.map(v => {return {duration: v}}),
- sum: value.reduce( (a, i) => a + i, 0),
- n: value.length,
- min: Math.min(...value),
- max: Math.max(...value)
- };
- let groupname = `[tq] ${key}`;
- groups.set(groupname, group);
- names.add(groupname);
- }
-
- for(let [name, group] of groups){
- group.mean = group.sum / group.n;
- group.measures.sort( (a, b) => a.duration - b.duration );
-
- if(group.n === 1){
- group.median = group.measures[0].duration;
- }else if(group.n > 1){
- group.median = group.measures[parseInt(group.n / 2)].duration;
- }
-
- }
-
- let cn = Array.from(names).reduce( (a, i) => Math.max(a, i.length), 0) + 5;
- let cmin = 10;
- let cmed = 10;
- let cmax = 10;
- let csam = 6;
-
- let message = ` ${"NAME".padEnd(cn)} |`
- + ` ${"MIN".padStart(cmin)} |`
- + ` ${"MEDIAN".padStart(cmed)} |`
- + ` ${"MAX".padStart(cmax)} |`
- + ` ${"SAMPLES".padStart(csam)} \n`;
- message += ` ${"-".repeat(message.length) }\n`;
-
- names = Array.from(names).sort();
- for(let name of names){
- let group = groups.get(name);
- let min = group.min.toFixed(3);
- let median = group.median.toFixed(3);
- let max = group.max.toFixed(3);
- let n = group.n;
-
- message += ` ${name.padEnd(cn)} |`
- + ` ${min.padStart(cmin)} |`
- + ` ${median.padStart(cmed)} |`
- + ` ${max.padStart(cmax)} |`
- + ` ${n.toString().padStart(csam)}\n`;
- }
- message += `\n`;
- console.log(message);
-
- performance.clearMarks();
- performance.clearMeasures();
- this.toggle = timestamp;
- }
- }
- }
- loop(timestamp){
- if(this.stats){
- this.stats.begin();
- }
- if(Potree.measureTimings){
- performance.mark("loop-start");
- }
- this.update(this.clock.getDelta(), timestamp);
- this.magnifier.render();
- this.render();
-
-
-
- // let vrActive = viewer.renderer.xr.isPresenting;
- // if(vrActive){
- // this.update(this.clock.getDelta(), timestamp);
- // this.render();
- // }else{
- // this.update(this.clock.getDelta(), timestamp);
- // this.render();
- // }
- if(Potree.measureTimings){
- performance.mark("loop-end");
- performance.measure("loop", "loop-start", "loop-end");
- }
-
- this.resolveTimings(timestamp);
- Potree.framenumber++;
- if(this.stats){
- this.stats.end();
- }
- }
- postError(content, params = {}){
- let message = this.postMessage(content, params);
- message.element.addClass("potree_message_error");
- return message;
- }
- postMessage(content, params = {}){
- let message = new Message(content);
- let animationDuration = 100;
- message.element.css("display", "none");
- message.elClose.click( () => {
- message.element.slideToggle(animationDuration);
- let index = this.messages.indexOf(message);
- if(index >= 0){
- this.messages.splice(index, 1);
- }
- });
- this.elMessages.prepend(message.element);
- message.element.slideToggle(animationDuration);
- this.messages.push(message);
- if(params.duration !== undefined){
- let fadeDuration = 500;
- let slideOutDuration = 200;
- setTimeout(() => {
- message.element.animate({
- opacity: 0
- }, fadeDuration);
- message.element.slideToggle(slideOutDuration);
- }, params.duration)
- }
- return message;
- }
-
-
-
-
-
- getBoundingBox (pointclouds) {
- //可以直接返回viewer.bound
- if(!this.bound){
- this.updateModelBound()
- }
- return this.bound.boundingBox.clone()//this.scene.getBoundingBox(pointclouds);
- };
- updateModelBound(){
- this.bound = Utils.computePointcloudsBound(this.scene.pointclouds)
- viewer.farWhenShowPano = this.bound.boundSize.length() * 2//全景漫游时要能看到整个skybox
-
-
- let boundPlane = new THREE.Box3()
- boundPlane.expandByPoint(this.bound.boundingBox.min.clone())//最低高度为bound的最低
- boundPlane.expandByPoint(this.bound.boundingBox.max.clone().setZ(this.bound.center.z))//最高高度为bound的中心高度
- FirstPersonControls.boundPlane = boundPlane
- FirstPersonControls.standardSpeed = THREE.Math.clamp( Math.sqrt(this.bound.boundSize.length() )/ 100 , 0.02,0.5); //在这个boundPlane中的速度
-
- viewer.scene.pointclouds.forEach(e=>{//海拔范围
- e.material.heightMin = this.bound.boundingBox.min.z
- e.material.heightMax = this.bound.boundingBox.max.z
- })
-
- }
-
- waitForLoad(object, isLoadedCallback){//等待加载时显示loading。主要是贴图
- this.waitQueue.push({
- object,
- isLoadedCallback,
- })
- 1 === this.waitQueue.length && this.emit("loading", true)
- }
- ifAllLoaded(object){
- if(this.waitQueue.length>0){
- this.waitQueue = this.waitQueue.filter(function(e) {
- return !e.isLoadedCallback()
- })
- }
-
- 0 === this.waitQueue.length && this.emit("loading", false)
- }
-
-
- setView(o={}){
- let callback = ()=>{
- if(o.displayMode){
- Potree.settings.displayMode = o.displayMode
- }
- o.callback && o.callback()
- }
-
- if(o.pano != void 0){//pano 权重高于 position
- this.images360.flyToPano(o)
- }else{
- this.scene.view.setView(o.position, o.target, o.duration, callback)
- }
-
-
- }
-
-
-
- //调试时显示transformControl来调节object
- transformObject(object){
- if(!object.boundingBox){
- object.boundingBox = new THREE.Box3() //任意大小 只是为了显示黄色外框
- //??? computeBoundingBox
- }
- viewer.inputHandler.toggleSelection(object);
- }
-
-
- addObjectTest(){//加水管
-
- if(Potree.settings.number == 't-8KbK1JjubE'){
-
- let boundingBox = new THREE.Box3()
- boundingBox.min.set(-1,-1,-1); boundingBox.max.set(1,1,1)
-
-
- let radius = 0.08;
- let radialSegments = 5
- let radSegments = Math.PI*2 / radialSegments
- var circlePts = [];//横截面
- for(let i=0;i<radialSegments;i++){
- let angle = radSegments * i;
- circlePts.push(new THREE.Vector2(radius * Math.cos(angle), radius * Math.sin(angle) ))
- }
- var count = 0
- var addMesh = (color, path, height)=>{//height:在path之上的高度,负数代表在path之下
- var name = 'cylinder'+count
- var mat = new THREE.MeshStandardMaterial({color, /* wireframe:true, */ depthTest:false, roughness:0.4,metalness:0.5})
- let linePath = path.map(e=>new THREE.Vector3().copy(e).setZ(e.z+height))
- let geo = MeshDraw.getExtrudeGeo( circlePts, null, linePath, 0.2)
- var mesh = new THREE.Mesh(geo,mat);
- mesh.name = name
- window[name] = mesh
-
- mesh.boundingBox = boundingBox
- mesh.matrixAutoUpdate = false
- mesh.matrix.copy(viewer.scene.pointclouds[0].transformMatrix)
- mesh.matrixWorldNeedsUpdate = true
-
- this.scene.scene.add(mesh);
-
- count ++
- }
-
-
- let linePath, height
-
- //地上管子 黄色
- /* linePath = [{"x":-109.83,"y":-68.33,"z":-7.52},{"x":-95.17,"y":-59.3,"z":-7.38}, {"x":-38.75,"y":-24.01,"z":-6.01},{"x":0.5,"y":0.19,"z":-3.89},{"x":42.76,"y":26.88,"z":-1.03}
- , {"x":44.27,"y":28.63,"z":-0.89},{"x":40.22,"y":35.37,"z":-0.67}// 拐弯向右
- , {"x":40.25,"y":36.47,"z":-0.6},{"x":38.69,"y":36.04,"z":18.04}// 拐弯向右
- ] */
- linePath = [{"x":-109.83,"y":-68.33,"z":-7.52},{"x":-95.17,"y":-59.3,"z":-7.38}, {"x":-38.75,"y":-24.01,"z":-6.01},{"x":0.5,"y":0.19,"z":-3.89},{"x":39.29,"y":24.41,"z":-1.31}
- ,{"x":43.58,"y":27.7,"z":-0.97},{"x":40.22,"y":35.37,"z":-0.67}// 拐弯向右
- , {"x":39.18,"y":36.71,"z":0.35},{"x":38.69,"y":36.04,"z":18.04} // 拐弯向上
- ]
- height = radius + 0.05;
- addMesh('#b86', linePath, height)
-
-
-
- //地下管子 藍色
- linePath = [{"x":-108.24,"y":-70.61,"z":-7.52}, {"x":-57.8,"y":-39.31,"z":-6.72},{"x":-18.8,"y":-15.35,"z":-5.01},{"x":55.87,"y":31.67,"z":-0.04},{"x":110.53,"y":66.48,"z":5.14}
- ]
- height = -0.5;
- addMesh('#48a', linePath, height)
-
-
-
- }
-
-
- }
-
- };
- /* t.prototype.getTransformationMatrix = function(t) {//点云截取 所有点在乘上这个矩阵后, 还能落在 1 * 1 * 1的box内的点就是所裁剪的
- var e = this.ViewService.mainView.getVolumeClippingLayer().getBoxFrame()
- , n = (new o.Matrix4).getInverse(e.matrixWorld)
- , i = t.m2w_;
- return (new o.Matrix4).multiplyMatrices(n, i).transpose() */
|