feat(All):Initial
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
import {TilesRenderer} from "3d-tiles-renderer";
|
||||
import {GLTFExtensionsPlugin,DebugTilesPlugin} from "3d-tiles-renderer/plugins";
|
||||
import Loader from "@/core/loader/Loader.ts";
|
||||
import {PerspectiveCamera, WebGLRenderer, Group, JSONMeta} from "three";
|
||||
import {deepAssign} from "@/utils";
|
||||
|
||||
export default class Tiles extends Group{
|
||||
type = "TilesGroup";
|
||||
isTilesGroup = true;
|
||||
|
||||
// 默认配置
|
||||
options: ITiles.options = {
|
||||
url:"",
|
||||
reset2origin:true,
|
||||
debug:false,
|
||||
name:"Tiles",
|
||||
errorTarget: 5,
|
||||
LRUCache:{
|
||||
maxSize: 4000,
|
||||
minSize: 3000,
|
||||
maxBytesSize: 0.4 * 2**30,
|
||||
minBytesSize: 0.3 * 2**30,
|
||||
}
|
||||
};
|
||||
|
||||
renderer: TilesRenderer;
|
||||
|
||||
constructor(options:ITiles.options) {
|
||||
super();
|
||||
|
||||
if(!options.url){
|
||||
throw new Error('[Astral 3D]: No url provided.');
|
||||
}
|
||||
|
||||
deepAssign(this.options,options);
|
||||
|
||||
this.name = this.options.name as string;
|
||||
|
||||
this.renderer = this.initRenderer();
|
||||
this.add(this.renderer.group);
|
||||
}
|
||||
|
||||
get group(){
|
||||
return this.renderer.group;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化Tiles渲染器
|
||||
*/
|
||||
initRenderer():TilesRenderer{
|
||||
const tilesRenderer = new TilesRenderer(this.options.url);
|
||||
tilesRenderer.fetchOptions.mode = 'cors';
|
||||
tilesRenderer.errorTarget = this.options.errorTarget || 6;
|
||||
// LRUCache
|
||||
if(this.options.LRUCache){
|
||||
tilesRenderer.lruCache.maxSize = this.options.LRUCache.maxSize || 800;
|
||||
tilesRenderer.lruCache.minSize = this.options.LRUCache.minSize || 600;
|
||||
tilesRenderer.lruCache.maxBytesSize = this.options.LRUCache.maxBytesSize || 0.4 * 2**30;
|
||||
tilesRenderer.lruCache.minBytesSize = this.options.LRUCache.minBytesSize || 0.3 * 2**30;
|
||||
}
|
||||
|
||||
// isTilesGroup是只读的,此处绕过 readonly,防止编译报错
|
||||
(tilesRenderer.group as { isTilesGroup: boolean }).isTilesGroup = false;
|
||||
(tilesRenderer.group as { type: string }).type = "Tiles";
|
||||
tilesRenderer.group.isTiles = true;
|
||||
tilesRenderer.group.proxy = this;
|
||||
|
||||
tilesRenderer.registerPlugin(new GLTFExtensionsPlugin({
|
||||
dracoLoader: Loader.dracoLoader,
|
||||
ktxLoader: Loader.ktx2Loader,
|
||||
}));
|
||||
// Loader.createGLTFLoader(tilesRenderer.manager).then(loader => {
|
||||
// tilesRenderer.manager.addHandler( /\.(gltf|glb)$/g, loader );
|
||||
// })
|
||||
|
||||
// 子级瓦片加载
|
||||
tilesRenderer.addEventListener('load-model', (e) => {
|
||||
e.scene.traverse(c => {
|
||||
c.isTiles = true;
|
||||
// 子级瓦片不允许选中,添加proxy属性让点击此瓦片时选中此组
|
||||
c.proxy = this;
|
||||
|
||||
if(c.type === "Group"){
|
||||
(c as { type: string }).type = "Tiles";
|
||||
}else{
|
||||
(c as { type: string }).type = "Tile";
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
tilesRenderer.addEventListener("load-error", (e) => {
|
||||
console.error(`${tilesRenderer.group.name} load error:`, e);
|
||||
});
|
||||
|
||||
if(this.options.debug){
|
||||
// 注册调试插件
|
||||
tilesRenderer.registerPlugin(new DebugTilesPlugin());
|
||||
// 获取调试插件
|
||||
const debugTilesPlugin = tilesRenderer.getPluginByName('DEBUG_TILES_PLUGIN') as DebugTilesPlugin;
|
||||
// 显示包围盒的线框
|
||||
debugTilesPlugin.displayBoxBounds = true;
|
||||
}
|
||||
|
||||
return tilesRenderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置相机和渲染器
|
||||
*/
|
||||
setCameraAndRenderer(camera:PerspectiveCamera,renderer:WebGLRenderer){
|
||||
this.renderer.setCamera(camera);
|
||||
this.renderer.setResolutionFromRenderer(camera, renderer);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重写clone方法,因为要接收参数
|
||||
*/
|
||||
clone(recursive: boolean = true) {
|
||||
// 断言为可构造类型
|
||||
const Ctor = this.constructor as new (opts: ITiles.options) => this;
|
||||
return new Ctor(this.options).copy(this, recursive);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重写toJSON
|
||||
*/
|
||||
toJSON(meta?: JSONMeta){
|
||||
const json = super.toJSON(meta);
|
||||
json.object.type= "TilesGroup";
|
||||
json.object.options = this.options;
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
static fromJSON(data: { options: ITiles.options,[s:string]:any },copyAttr = true){
|
||||
const tiles = new Tiles(data.options);
|
||||
|
||||
if(copyAttr){
|
||||
data.children = undefined;
|
||||
Loader.objectLoader.copyAttrByData(tiles,data);
|
||||
}
|
||||
|
||||
return tiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新/渲染Tiles
|
||||
*/
|
||||
update(){
|
||||
this.renderer.update();
|
||||
}
|
||||
|
||||
/**
|
||||
* 自我销毁
|
||||
*/
|
||||
dispose(){
|
||||
this.renderer.dispose();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user