mirror of
https://github.com/BlueMap-Minecraft/BlueMapWeb.git
synced 2024-09-27 13:12:46 +02:00
Improvements to tile-loading and other fixes
This commit is contained in:
parent
d9ffe6453f
commit
bb4928c72f
@ -369,7 +369,11 @@ export class MapViewer {
|
||||
|
||||
updateLoadedMapArea = () => {
|
||||
if (!this.map) return;
|
||||
if (this.controlsManager.distance < 1000) {
|
||||
this.map.loadMapArea(this.data.loadedCenter.x, this.data.loadedCenter.y, this.data.loadedHiresViewDistance, this.data.loadedLowresViewDistance);
|
||||
} else {
|
||||
this.map.loadMapArea(this.data.loadedCenter.x, this.data.loadedCenter.y, 0, this.data.loadedLowresViewDistance);
|
||||
}
|
||||
}
|
||||
|
||||
clearTileCache(newTileCacheHash) {
|
||||
|
@ -58,6 +58,7 @@ export class ControlsManager {
|
||||
this.lastTilt = this.tilt;
|
||||
|
||||
this.lastMapUpdatePosition = this.position.clone();
|
||||
this.lastMapUpdateDistance = this.distance;
|
||||
|
||||
this.averageDeltaTime = 16;
|
||||
|
||||
@ -156,9 +157,11 @@ export class ControlsManager {
|
||||
|
||||
if (
|
||||
Math.abs(this.lastMapUpdatePosition.x - this.position.x) >= triggerDistance ||
|
||||
Math.abs(this.lastMapUpdatePosition.z - this.position.z) >= triggerDistance
|
||||
Math.abs(this.lastMapUpdatePosition.z - this.position.z) >= triggerDistance ||
|
||||
(this.distance < 1000 && this.lastMapUpdateDistance > 1000)
|
||||
) {
|
||||
this.lastMapUpdatePosition = this.position.clone();
|
||||
this.lastMapUpdateDistance = this.distance;
|
||||
this.mapViewer.loadMapArea(this.position.x, this.position.z);
|
||||
}
|
||||
}
|
||||
|
@ -38,13 +38,13 @@ import {
|
||||
|
||||
export class LowresTileLoader {
|
||||
|
||||
constructor(tilePath, tileSettings, lod, vertexShader, fragmentShader, uniforms, tileCacheHash = 0, layer = 0) {
|
||||
constructor(tilePath, tileSettings, lod, vertexShader, fragmentShader, uniforms, loadBlocker = () => Promise.resolve(), tileCacheHash = 0) {
|
||||
Object.defineProperty( this, 'isLowresTileLoader', { value: true } );
|
||||
|
||||
this.tilePath = tilePath;
|
||||
this.tileSettings = tileSettings;
|
||||
this.lod = lod;
|
||||
this.layer = layer;
|
||||
this.loadBlocker = loadBlocker;
|
||||
this.tileCacheHash = tileCacheHash;
|
||||
|
||||
this.vertexShader = vertexShader;
|
||||
@ -62,12 +62,13 @@ export class LowresTileLoader {
|
||||
this.geometry.translate(tileSettings.tileSize.x / 2 + 1, 0, tileSettings.tileSize.x / 2 + 1);
|
||||
}
|
||||
|
||||
load = (tileX, tileZ) => {
|
||||
load = (tileX, tileZ, cancelCheck = () => false) => {
|
||||
let tileUrl = this.tilePath + this.lod + "/" + pathFromCoords(tileX, tileZ) + '.png';
|
||||
|
||||
//await this.loadBlocker();
|
||||
return new Promise((resolve, reject) => {
|
||||
this.textureLoader.load(tileUrl + '?' + this.tileCacheHash,
|
||||
texture => {
|
||||
async texture => {
|
||||
texture.anisotropy = 1;
|
||||
texture.generateMipmaps = false;
|
||||
texture.magFilter = NearestFilter;
|
||||
@ -77,6 +78,13 @@ export class LowresTileLoader {
|
||||
texture.flipY = false;
|
||||
texture.flatShading = true;
|
||||
|
||||
await this.loadBlocker();
|
||||
if (cancelCheck()){
|
||||
texture.dispose();
|
||||
reject({status: "cancelled"});
|
||||
return;
|
||||
}
|
||||
|
||||
let material = new ShaderMaterial({
|
||||
uniforms: {
|
||||
...this.uniforms,
|
||||
@ -102,7 +110,6 @@ export class LowresTileLoader {
|
||||
});
|
||||
|
||||
let object = new Mesh(this.geometry, material);
|
||||
if (this.layer) object.layers.set(this.layer);
|
||||
|
||||
const scale = Math.pow(this.tileSettings.lodFactor, this.lod - 1);
|
||||
object.position.set(tileX * this.tileSettings.tileSize.x * scale, 0, tileZ * this.tileSettings.tileSize.z * scale);
|
||||
|
@ -46,11 +46,13 @@ export class Map {
|
||||
/**
|
||||
* @param id {string}
|
||||
* @param dataUrl {string}
|
||||
* @param loadBlocker {function: Promise<void>}
|
||||
* @param events {EventTarget}
|
||||
*/
|
||||
constructor(id, dataUrl, events = null) {
|
||||
constructor(id, dataUrl, loadBlocker, events = null) {
|
||||
Object.defineProperty( this, 'isMap', { value: true } );
|
||||
|
||||
this.loadBlocker = loadBlocker;
|
||||
this.events = events;
|
||||
|
||||
this.data = {
|
||||
@ -115,12 +117,12 @@ export class Map {
|
||||
|
||||
this.hiresMaterial = this.createHiresMaterial(hiresVertexShader, hiresFragmentShader, uniforms, textures);
|
||||
|
||||
this.hiresTileManager = new TileManager(new Scene(), new TileLoader(`${this.data.dataUrl}tiles/0/`, this.hiresMaterial, this.data.hires, tileCacheHash), this.onTileLoad("hires"), this.onTileUnload("hires"), this.events);
|
||||
this.hiresTileManager = new TileManager(new Scene(), new TileLoader(`${this.data.dataUrl}tiles/0/`, this.hiresMaterial, this.data.hires, this.loadBlocker, tileCacheHash), this.onTileLoad("hires"), this.onTileUnload("hires"), this.events);
|
||||
this.hiresTileManager.scene.autoUpdate = false;
|
||||
|
||||
this.lowresTileManager = [];
|
||||
for (let i = 0; i < this.data.lowres.lodCount; i++) {
|
||||
this.lowresTileManager[i] = new TileManager(new Scene(), new LowresTileLoader(`${this.data.dataUrl}tiles/`, this.data.lowres, i + 1, lowresVertexShader, lowresFragmentShader, uniforms, tileCacheHash), this.onTileLoad("lowres"), this.onTileUnload("lowres"), this.events);
|
||||
this.lowresTileManager[i] = new TileManager(new Scene(), new LowresTileLoader(`${this.data.dataUrl}tiles/`, this.data.lowres, i + 1, lowresVertexShader, lowresFragmentShader, uniforms, async () => {}, tileCacheHash), this.onTileLoad("lowres"), this.onTileUnload("lowres"), this.events);
|
||||
this.lowresTileManager[i].scene.autoUpdate = false;
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ export class Tile {
|
||||
this.unload();
|
||||
|
||||
this.unloaded = false;
|
||||
return tileLoader.load(this.x, this.z)
|
||||
return tileLoader.load(this.x, this.z, () => this.unloaded)
|
||||
.then(model => {
|
||||
if (this.unloaded){
|
||||
Tile.disposeModel(model);
|
||||
|
@ -35,42 +35,48 @@ export class TileLoader {
|
||||
* scale: {x: number, z: number},
|
||||
* translate: {x: number, z: number}
|
||||
* }}
|
||||
* @param loadBlocker {function: Promise}
|
||||
* @param tileCacheHash {number}
|
||||
* @param layer {number}
|
||||
*/
|
||||
constructor(tilePath, material, tileSettings, tileCacheHash = 0, layer = 0) {
|
||||
constructor(tilePath, material, tileSettings, loadBlocker = () => Promise.resolve(), tileCacheHash = 0) {
|
||||
Object.defineProperty( this, 'isTileLoader', { value: true } );
|
||||
|
||||
this.tilePath = tilePath;
|
||||
this.material = material;
|
||||
this.tileSettings = tileSettings;
|
||||
|
||||
this.layer = layer;
|
||||
|
||||
this.tileCacheHash = tileCacheHash;
|
||||
|
||||
this.loadBlocker = loadBlocker;
|
||||
|
||||
this.fileLoader = new FileLoader();
|
||||
this.fileLoader.setResponseType('json');
|
||||
|
||||
this.bufferGeometryLoader = new BufferGeometryLoader();
|
||||
}
|
||||
|
||||
load = (tileX, tileZ) => {
|
||||
load = (tileX, tileZ, cancelCheck = () => false) => {
|
||||
let tileUrl = this.tilePath + pathFromCoords(tileX, tileZ) + '.json';
|
||||
|
||||
//await this.loadBlocker();
|
||||
return new Promise((resolve, reject) => {
|
||||
this.fileLoader.load(tileUrl + '?' + this.tileCacheHash,
|
||||
json => {
|
||||
async json => {
|
||||
let geometryJson = json.tileGeometry || {};
|
||||
if (!geometryJson.type || geometryJson.type !== 'BufferGeometry'){
|
||||
reject({status: "empty"});
|
||||
return;
|
||||
}
|
||||
|
||||
await this.loadBlocker();
|
||||
if (cancelCheck()){
|
||||
reject({status: "cancelled"});
|
||||
return;
|
||||
}
|
||||
|
||||
let geometry = this.bufferGeometryLoader.parse(geometryJson);
|
||||
|
||||
let object = new Mesh(geometry, this.material);
|
||||
if (this.layer) object.layers.set(this.layer);
|
||||
|
||||
let tileSize = this.tileSettings.tileSize;
|
||||
let translate = this.tileSettings.translate;
|
||||
|
@ -82,13 +82,18 @@ export class TileManager {
|
||||
this.viewDistanceX = viewDistanceX;
|
||||
this.viewDistanceZ = viewDistanceZ;
|
||||
|
||||
if (viewDistanceX <= 0 || viewDistanceZ <= 0) {
|
||||
this.removeAllTiles();
|
||||
return;
|
||||
}
|
||||
|
||||
if (unloadTiles || this.centerTile.x !== x || this.centerTile.y !== z) {
|
||||
this.centerTile.set(x, z);
|
||||
this.removeFarTiles();
|
||||
|
||||
this.tileMap.setAll(TileMap.EMPTY);
|
||||
this.tiles.forEach(tile => {
|
||||
if (!tile.loading) {
|
||||
if (!tile.loading && !tile.unloaded) {
|
||||
this.tileMap.setTile(tile.x - this.centerTile.x + TileManager.tileMapHalfSize, tile.z - this.centerTile.y + TileManager.tileMapHalfSize, TileMap.LOADED);
|
||||
}
|
||||
});
|
||||
@ -187,6 +192,7 @@ export class TileManager {
|
||||
this.tiles.set(tileHash, tile);
|
||||
tile.load(this.tileLoader)
|
||||
.then(() => {
|
||||
if (!tile.unloaded)
|
||||
this.tileMap.setTile(tile.x - this.centerTile.x + TileManager.tileMapHalfSize, tile.z - this.centerTile.y + TileManager.tileMapHalfSize, TileMap.LOADED);
|
||||
|
||||
if (this.loadTimeout) clearTimeout(this.loadTimeout);
|
||||
@ -200,7 +206,7 @@ export class TileManager {
|
||||
//alert(this.events, "Failed to load tile: " + error.type, "warning");
|
||||
})
|
||||
.finally(() => {
|
||||
this.tileMap.setTile(tile.x - this.centerTile.x + TileManager.tileMapHalfSize, tile.z - this.centerTile.y + TileManager.tileMapHalfSize, TileMap.LOADED);
|
||||
//this.tileMap.setTile(tile.x - this.centerTile.x + TileManager.tileMapHalfSize, tile.z - this.centerTile.y + TileManager.tileMapHalfSize, TileMap.LOADED);
|
||||
this.currentlyLoading--;
|
||||
});
|
||||
|
||||
|
@ -73,7 +73,7 @@ vec2 posToMetaUV(vec2 pos) {
|
||||
|
||||
void main() {
|
||||
//discard if hires tile is loaded at that position
|
||||
//if (vDistance < 900.0 && texture(hiresTileMap.map, ((vWorldPosition.xz - hiresTileMap.translate) / hiresTileMap.scale - hiresTileMap.pos) / hiresTileMap.size + 0.5).r > 0.75) discard;
|
||||
if (vDistance < 900.0 && texture(hiresTileMap.map, ((vWorldPosition.xz - hiresTileMap.translate) / hiresTileMap.scale - hiresTileMap.pos) / hiresTileMap.size + 0.5).r > 0.75) discard;
|
||||
|
||||
vec4 color = texture(textureImage, posToColorUV(vPosition.xz));
|
||||
vec4 meta = texture(textureImage, posToMetaUV(vPosition.xz));
|
||||
|
Loading…
Reference in New Issue
Block a user