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;
//}
}