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 = () => {
|
updateLoadedMapArea = () => {
|
||||||
if (!this.map) return;
|
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);
|
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) {
|
clearTileCache(newTileCacheHash) {
|
||||||
|
@ -58,6 +58,7 @@ export class ControlsManager {
|
|||||||
this.lastTilt = this.tilt;
|
this.lastTilt = this.tilt;
|
||||||
|
|
||||||
this.lastMapUpdatePosition = this.position.clone();
|
this.lastMapUpdatePosition = this.position.clone();
|
||||||
|
this.lastMapUpdateDistance = this.distance;
|
||||||
|
|
||||||
this.averageDeltaTime = 16;
|
this.averageDeltaTime = 16;
|
||||||
|
|
||||||
@ -156,9 +157,11 @@ export class ControlsManager {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
Math.abs(this.lastMapUpdatePosition.x - this.position.x) >= triggerDistance ||
|
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.lastMapUpdatePosition = this.position.clone();
|
||||||
|
this.lastMapUpdateDistance = this.distance;
|
||||||
this.mapViewer.loadMapArea(this.position.x, this.position.z);
|
this.mapViewer.loadMapArea(this.position.x, this.position.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,13 +38,13 @@ import {
|
|||||||
|
|
||||||
export class LowresTileLoader {
|
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 } );
|
Object.defineProperty( this, 'isLowresTileLoader', { value: true } );
|
||||||
|
|
||||||
this.tilePath = tilePath;
|
this.tilePath = tilePath;
|
||||||
this.tileSettings = tileSettings;
|
this.tileSettings = tileSettings;
|
||||||
this.lod = lod;
|
this.lod = lod;
|
||||||
this.layer = layer;
|
this.loadBlocker = loadBlocker;
|
||||||
this.tileCacheHash = tileCacheHash;
|
this.tileCacheHash = tileCacheHash;
|
||||||
|
|
||||||
this.vertexShader = vertexShader;
|
this.vertexShader = vertexShader;
|
||||||
@ -62,12 +62,13 @@ export class LowresTileLoader {
|
|||||||
this.geometry.translate(tileSettings.tileSize.x / 2 + 1, 0, tileSettings.tileSize.x / 2 + 1);
|
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';
|
let tileUrl = this.tilePath + this.lod + "/" + pathFromCoords(tileX, tileZ) + '.png';
|
||||||
|
|
||||||
|
//await this.loadBlocker();
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.textureLoader.load(tileUrl + '?' + this.tileCacheHash,
|
this.textureLoader.load(tileUrl + '?' + this.tileCacheHash,
|
||||||
texture => {
|
async texture => {
|
||||||
texture.anisotropy = 1;
|
texture.anisotropy = 1;
|
||||||
texture.generateMipmaps = false;
|
texture.generateMipmaps = false;
|
||||||
texture.magFilter = NearestFilter;
|
texture.magFilter = NearestFilter;
|
||||||
@ -77,6 +78,13 @@ export class LowresTileLoader {
|
|||||||
texture.flipY = false;
|
texture.flipY = false;
|
||||||
texture.flatShading = true;
|
texture.flatShading = true;
|
||||||
|
|
||||||
|
await this.loadBlocker();
|
||||||
|
if (cancelCheck()){
|
||||||
|
texture.dispose();
|
||||||
|
reject({status: "cancelled"});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let material = new ShaderMaterial({
|
let material = new ShaderMaterial({
|
||||||
uniforms: {
|
uniforms: {
|
||||||
...this.uniforms,
|
...this.uniforms,
|
||||||
@ -102,7 +110,6 @@ export class LowresTileLoader {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let object = new Mesh(this.geometry, material);
|
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);
|
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);
|
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 id {string}
|
||||||
* @param dataUrl {string}
|
* @param dataUrl {string}
|
||||||
|
* @param loadBlocker {function: Promise<void>}
|
||||||
* @param events {EventTarget}
|
* @param events {EventTarget}
|
||||||
*/
|
*/
|
||||||
constructor(id, dataUrl, events = null) {
|
constructor(id, dataUrl, loadBlocker, events = null) {
|
||||||
Object.defineProperty( this, 'isMap', { value: true } );
|
Object.defineProperty( this, 'isMap', { value: true } );
|
||||||
|
|
||||||
|
this.loadBlocker = loadBlocker;
|
||||||
this.events = events;
|
this.events = events;
|
||||||
|
|
||||||
this.data = {
|
this.data = {
|
||||||
@ -115,12 +117,12 @@ export class Map {
|
|||||||
|
|
||||||
this.hiresMaterial = this.createHiresMaterial(hiresVertexShader, hiresFragmentShader, uniforms, textures);
|
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.hiresTileManager.scene.autoUpdate = false;
|
||||||
|
|
||||||
this.lowresTileManager = [];
|
this.lowresTileManager = [];
|
||||||
for (let i = 0; i < this.data.lowres.lodCount; i++) {
|
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;
|
this.lowresTileManager[i].scene.autoUpdate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ export class Tile {
|
|||||||
this.unload();
|
this.unload();
|
||||||
|
|
||||||
this.unloaded = false;
|
this.unloaded = false;
|
||||||
return tileLoader.load(this.x, this.z)
|
return tileLoader.load(this.x, this.z, () => this.unloaded)
|
||||||
.then(model => {
|
.then(model => {
|
||||||
if (this.unloaded){
|
if (this.unloaded){
|
||||||
Tile.disposeModel(model);
|
Tile.disposeModel(model);
|
||||||
|
@ -35,42 +35,48 @@ export class TileLoader {
|
|||||||
* scale: {x: number, z: number},
|
* scale: {x: number, z: number},
|
||||||
* translate: {x: number, z: number}
|
* translate: {x: number, z: number}
|
||||||
* }}
|
* }}
|
||||||
|
* @param loadBlocker {function: Promise}
|
||||||
* @param tileCacheHash {number}
|
* @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 } );
|
Object.defineProperty( this, 'isTileLoader', { value: true } );
|
||||||
|
|
||||||
this.tilePath = tilePath;
|
this.tilePath = tilePath;
|
||||||
this.material = material;
|
this.material = material;
|
||||||
this.tileSettings = tileSettings;
|
this.tileSettings = tileSettings;
|
||||||
|
|
||||||
this.layer = layer;
|
|
||||||
|
|
||||||
this.tileCacheHash = tileCacheHash;
|
this.tileCacheHash = tileCacheHash;
|
||||||
|
|
||||||
|
this.loadBlocker = loadBlocker;
|
||||||
|
|
||||||
this.fileLoader = new FileLoader();
|
this.fileLoader = new FileLoader();
|
||||||
this.fileLoader.setResponseType('json');
|
this.fileLoader.setResponseType('json');
|
||||||
|
|
||||||
this.bufferGeometryLoader = new BufferGeometryLoader();
|
this.bufferGeometryLoader = new BufferGeometryLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
load = (tileX, tileZ) => {
|
load = (tileX, tileZ, cancelCheck = () => false) => {
|
||||||
let tileUrl = this.tilePath + pathFromCoords(tileX, tileZ) + '.json';
|
let tileUrl = this.tilePath + pathFromCoords(tileX, tileZ) + '.json';
|
||||||
|
|
||||||
|
//await this.loadBlocker();
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.fileLoader.load(tileUrl + '?' + this.tileCacheHash,
|
this.fileLoader.load(tileUrl + '?' + this.tileCacheHash,
|
||||||
json => {
|
async json => {
|
||||||
let geometryJson = json.tileGeometry || {};
|
let geometryJson = json.tileGeometry || {};
|
||||||
if (!geometryJson.type || geometryJson.type !== 'BufferGeometry'){
|
if (!geometryJson.type || geometryJson.type !== 'BufferGeometry'){
|
||||||
reject({status: "empty"});
|
reject({status: "empty"});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await this.loadBlocker();
|
||||||
|
if (cancelCheck()){
|
||||||
|
reject({status: "cancelled"});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let geometry = this.bufferGeometryLoader.parse(geometryJson);
|
let geometry = this.bufferGeometryLoader.parse(geometryJson);
|
||||||
|
|
||||||
let object = new Mesh(geometry, this.material);
|
let object = new Mesh(geometry, this.material);
|
||||||
if (this.layer) object.layers.set(this.layer);
|
|
||||||
|
|
||||||
let tileSize = this.tileSettings.tileSize;
|
let tileSize = this.tileSettings.tileSize;
|
||||||
let translate = this.tileSettings.translate;
|
let translate = this.tileSettings.translate;
|
||||||
|
@ -82,13 +82,18 @@ export class TileManager {
|
|||||||
this.viewDistanceX = viewDistanceX;
|
this.viewDistanceX = viewDistanceX;
|
||||||
this.viewDistanceZ = viewDistanceZ;
|
this.viewDistanceZ = viewDistanceZ;
|
||||||
|
|
||||||
|
if (viewDistanceX <= 0 || viewDistanceZ <= 0) {
|
||||||
|
this.removeAllTiles();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (unloadTiles || this.centerTile.x !== x || this.centerTile.y !== z) {
|
if (unloadTiles || this.centerTile.x !== x || this.centerTile.y !== z) {
|
||||||
this.centerTile.set(x, z);
|
this.centerTile.set(x, z);
|
||||||
this.removeFarTiles();
|
this.removeFarTiles();
|
||||||
|
|
||||||
this.tileMap.setAll(TileMap.EMPTY);
|
this.tileMap.setAll(TileMap.EMPTY);
|
||||||
this.tiles.forEach(tile => {
|
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);
|
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);
|
this.tiles.set(tileHash, tile);
|
||||||
tile.load(this.tileLoader)
|
tile.load(this.tileLoader)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
if (!tile.unloaded)
|
||||||
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);
|
||||||
|
|
||||||
if (this.loadTimeout) clearTimeout(this.loadTimeout);
|
if (this.loadTimeout) clearTimeout(this.loadTimeout);
|
||||||
@ -200,7 +206,7 @@ export class TileManager {
|
|||||||
//alert(this.events, "Failed to load tile: " + error.type, "warning");
|
//alert(this.events, "Failed to load tile: " + error.type, "warning");
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.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--;
|
this.currentlyLoading--;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ vec2 posToMetaUV(vec2 pos) {
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
//discard if hires tile is loaded at that position
|
//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 color = texture(textureImage, posToColorUV(vPosition.xz));
|
||||||
vec4 meta = texture(textureImage, posToMetaUV(vPosition.xz));
|
vec4 meta = texture(textureImage, posToMetaUV(vPosition.xz));
|
||||||
|
Loading…
Reference in New Issue
Block a user