import { DebugTilesRenderer as TilesRenderer, InfiniteGridHelper } from '../src/index.js'; import { Scene, DirectionalLight, AmbientLight, WebGLRenderer, PerspectiveCamera, Group, sRGBEncoding, FogExp2, CameraHelper, Color } from 'three'; import { FlyOrbitControls } from './FlyOrbitControls.js'; import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js'; import { LoadingManager } from 'three'; import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'; import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; import * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils'; let camera, controls, scene, renderer; let thirdPersonCamera, thirdPersonRenderer, thirdPersonControls, cameraHelper let groundTiles, skyTiles; let tilesRendererArr = []; let statsContainer const params = { errorTarget: 45, displayBoxBounds: false, fog: false, showThirdPerson: false, }; init(); render(); function init() { const fog = new FogExp2( 0xd8cec0, .0075, 250 ); scene = new Scene(); // primary camera view renderer = new WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); renderer.setClearColor( 0xd8cec0 ); renderer.outputEncoding = sRGBEncoding; document.body.appendChild( renderer.domElement ); renderer.domElement.tabIndex = 1; camera = new PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 4000 ); camera.position.set( 20, 10, 20 ); cameraHelper = new CameraHelper( camera ); scene.add( cameraHelper ); // controls controls = new FlyOrbitControls( camera, renderer.domElement ); controls.screenSpacePanning = false; controls.minDistance = 1; controls.maxDistance = 2000; //controls.maxPolarAngle = Math.PI / 2; controls.baseSpeed = 0.1; controls.fastSpeed = 0.2; //加 // Third person camera view thirdPersonCamera = new PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 4000 ); thirdPersonCamera.position.set( 50, 40, 40 ); thirdPersonCamera.lookAt( 0, 0, 0 ); thirdPersonRenderer = new WebGLRenderer( { antialias: true } ); thirdPersonRenderer.setPixelRatio( window.devicePixelRatio ); thirdPersonRenderer.setSize( window.innerWidth, window.innerHeight ); thirdPersonRenderer.setClearColor( 0x0f1416 ); thirdPersonRenderer.outputEncoding = sRGBEncoding; document.body.appendChild( thirdPersonRenderer.domElement ); thirdPersonRenderer.domElement.style.position = 'fixed'; thirdPersonRenderer.domElement.style.left = '5px'; thirdPersonRenderer.domElement.style.bottom = '5px'; thirdPersonRenderer.domElement.style.width = '30%'; thirdPersonRenderer.domElement.style.height = '50%'; thirdPersonRenderer.domElement.tabIndex = 1; thirdPersonControls = new FlyOrbitControls( thirdPersonCamera, thirdPersonRenderer.domElement ); thirdPersonControls.screenSpacePanning = false; thirdPersonControls.minDistance = 1; thirdPersonControls.maxDistance = 2000; let ground = new InfiniteGridHelper(1, 10000, new Color('#fff'), 10000, 0.2, 0.3) scene.add(ground) ground.lookAt(0,1,0) // lights const dirLight = new DirectionalLight( 0xffffff ); dirLight.position.set( 1, 2, 3 ); scene.add( dirLight ); const ambLight = new AmbientLight( 0xffffff, 0.2 ); scene.add( ambLight ); const tilesParent = new Group(); tilesParent.rotation.set( Math.PI / 2, 0, 0 ); scene.add( tilesParent ); /* //groundTiles = new TilesRenderer( 'https://raw.githubusercontent.com/NASA-AMMOS/3DTilesSampleData/master/msl-dingo-gap/0528_0260184_to_s64o256_colorize/0528_0260184_to_s64o256_colorize/0528_0260184_to_s64o256_colorize_tileset.json' ); groundTiles = new TilesRenderer('https://testgis.4dage.com/LVBADUI_qp/tileset.json'); groundTiles.fetchOptions.mode = 'cors'; groundTiles.lruCache.minSize = 900; groundTiles.lruCache.maxSize = 1300; groundTiles.errorTarget = 12; */ //https://testgis.4dage.com/gaoling0805-qp/ loadTileSet('https://testgis.4dage.com/LVBADUI_qp/',camera,renderer); //loadTileSet('https://testgis.4dage.com/gaoling0805-qp/',camera,renderer); // skyTiles = new TilesRenderer( 'https://raw.githubusercontent.com/NASA-AMMOS/3DTilesSampleData/master/msl-dingo-gap/0528_0260184_to_s64o256_colorize/0528_0260184_to_s64o256_sky/0528_0260184_to_s64o256_sky_tileset.json' ); // skyTiles.fetchOptions.mode = 'cors'; // skyTiles.lruCache = groundTiles.lruCache; // tilesParent.add( groundTiles.group, skyTiles.group ); onWindowResize(); window.addEventListener( 'resize', onWindowResize, false ); const gui = new GUI(); gui.add( params, 'fog' ).onChange( v => { scene.fog = v ? fog : null; } ); gui.add( params, 'displayBoxBounds' ); gui.add( params, 'errorTarget', 0, 100 ); gui.add( params, 'showThirdPerson' ); gui.open(); statsContainer = document.createElement( 'div' ); statsContainer.style.position = 'absolute'; statsContainer.style.top = 0; statsContainer.style.left = 0; statsContainer.style.color = 'white'; statsContainer.style.width = '100%'; statsContainer.style.textAlign = 'center'; statsContainer.style.padding = '5px'; statsContainer.style.pointerEvents = 'none'; statsContainer.style.lineHeight = '1.5em'; document.body.appendChild( statsContainer ); /* // Stats stats = new Stats(); stats.showPanel( 0 ); document.body.appendChild( stats.dom ); */ } function loadTileSet(qzpath,camera,renderer){ // 加载json,解析json 取出children中的路径进行拼装加载 //const qzpath = 'http://192.168.1.136:8077/sqsftilte/' //get(qzpath + 'tileset.json').then((res)=>{ //debugger; fetch(qzpath + 'tileset.json').then(response => response.json()).then(data => { console.log(data) const tilesetArr = data.root.children for (const tilese of tilesetArr) { // console.log(qzpath + tilese.content.uri) const tilesRenderer = new TilesRenderer( qzpath + tilese.content.uri ) const gltfLoader = new GLTFLoader( tilesRenderer.manager ); const dracoLoader = new DRACOLoader( tilesRenderer.manager ); dracoLoader.setDecoderPath( 'https://unpkg.com/three@0.128.0/examples/js/libs/draco/gltf/' ); gltfLoader.setDRACOLoader( dracoLoader ); tilesRenderer.manager.addHandler( /\.gltf$/, gltfLoader ); tilesRenderer.manager.addHandler( /\.glb$/, gltfLoader ); tilesRenderer.setCamera( camera ) tilesRenderer.setResolutionFromRenderer( camera, renderer ) const tilesObj = tilesRenderer.group tilesObj.rotation.set(-Math.PI / 2, 0, 0) scene.add( tilesObj ) tilesRendererArr.push(tilesRenderer) //xzw: Multiple TilesRenderers with Shared Caches and Queues if(tilesRendererArr[0]){ // set the second renderer to share the cache and queues from the first, 否则卡顿. tilesRenderer.lruCache = tilesRendererArr[0].lruCache; tilesRenderer.downloadQueue = tilesRendererArr[0].downloadQueue; tilesRenderer.parseQueue = tilesRendererArr[0].parseQueue; } //但还是比只有一个tileRenderer卡顿 } }); // fetch(qzpath + 'tileset.json').then((res)=>{ // // console.log(res) // const tilesetArr = res.root.children // for (const tilese of tilesetArr) { // // console.log(qzpath + tilese.content.uri) // const tilesRenderer = new TilesRenderer( qzpath + tilese.content.uri ) // tilesRenderer.setCamera( camera ) // tilesRenderer.setResolutionFromRenderer( camera, renderer ) // const tilesObj = tilesRenderer.group // tilesObj.rotation.set(-Math.PI / 2, 0, 0) // scene.add( tilesObj ) // tilesRendererArr.push(tilesRenderer) // } //}) } function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight ); renderer.setPixelRatio( window.devicePixelRatio ); thirdPersonCamera.aspect = thirdPersonRenderer.domElement.clientWidth / thirdPersonRenderer.domElement.clientHeight; thirdPersonCamera.updateProjectionMatrix(); thirdPersonRenderer.setSize( thirdPersonRenderer.domElement.clientWidth, thirdPersonRenderer.domElement.clientHeight, false); thirdPersonRenderer.setPixelRatio( window.devicePixelRatio ); } function render() { requestAnimationFrame( render ); camera.updateMatrixWorld(); cameraHelper.visible = false; let downloading = 0, parsing = 0, visibles = 0, count = 0 for (const tilesRenderer of tilesRendererArr) { //xzw add --------- tilesRenderer.errorTarget = params.errorTarget; tilesRenderer.displayBoxBounds = params.displayBoxBounds; //----------------- tilesRenderer.update() downloading += tilesRenderer.stats.downloading parsing += tilesRenderer.stats.parsing visibles += tilesRenderer.group.children.length - 2 const geomSet = new Set(); tilesRenderer.traverse( tile => { const scene = tile.cached.scene; if ( scene ) { scene.traverse( c => { if ( c.geometry ) { geomSet.add( c.geometry ); } } ); } } ); geomSet.forEach( g => { let u = BufferGeometryUtils.estimateBytesUsed( g ); count += u //console.log(g.uuid) } ); } let cacheFullness = tilesRendererArr[0] ? tilesRendererArr[0].lruCache.itemList.length / tilesRendererArr[0].lruCache.maxSize : 0; // render third person view thirdPersonRenderer.domElement.style.visibility = params.showThirdPerson ? 'visible' : 'hidden'; if ( params.showThirdPerson ) { if(thirdPersonRenderer.domElement.style != 'block'){ thirdPersonRenderer.domElement.style.display = 'block' onWindowResize() } cameraHelper.update(); cameraHelper.visible = true//! params.orthographic; /* if ( params.showSecondView ) { secondCameraHelper.update(); secondCameraHelper.visible = true; } */ //const dist = thirdPersonCamera.position.distanceTo( rayIntersect.position ); //rayIntersect.scale.setScalar( dist * thirdPersonCamera.fov / 6000 ); thirdPersonRenderer.render( scene, thirdPersonCamera ); }else{ thirdPersonRenderer.domElement.style.display = 'none' } renderer.render( scene, camera ); let str = `Downloading: ${ downloading } Parsing: ${ parsing } Visible: ${visibles}`; //if ( params.enableCacheDisplay ) { str += `
Cache: ${ ( 100 * cacheFullness ).toFixed( 2 ) }% ~${ ( count / 1000 / 1000 ).toFixed( 2 ) }mb`; //} //if ( params.enableRendererStats ) { const memory = renderer.info.memory; const programCount = renderer.info.programs.length; str += `
Geometries: ${ memory.geometries } Textures: ${ memory.textures } Programs: ${ programCount }`; //} //if ( statsContainer.innerHTML !== str ) { statsContainer.innerHTML = str; //} }