diff --git a/package-lock.json b/package-lock.json index 2138aa7..0760d72 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1043,6 +1043,47 @@ "picomatch": "^2.2.2" } }, + "@types/babel__core": { + "version": "7.1.12", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.12.tgz", + "integrity": "sha512-wMTHiiTiBAAPebqaPiPDLFA4LYPKr6Ph0Xq/6rq1Ur3v66HXyG+clfR9CNETkD7MQS8ZHvpQOtA53DLws5WAEQ==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", + "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", + "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.0.tgz", + "integrity": "sha512-kSjgDMZONiIfSH1Nxcr5JIRMwUetDki63FSQfpTCz8ogF3Ulqm8+mr5f78dUYs6vMiB6gBusQqfQmBvHZj/lwg==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", diff --git a/package.json b/package.json index f5f8266..846a7d9 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,10 @@ { "name": "bluemap", - "description": "A Minecraft mapping tool that creates 3D models of your Minecraft worlds and displays them in a web viewer.", + "version": "0.0.0", + "description": "A library to load and display Minecraft maps generated by BlueMap.", "repository": { "type": "git", - "url": "git+https://github.com/BlueMap-Minecraft/BlueMap.git" + "url": "https://github.com/BlueMap-Minecraft/BlueMap.git" }, "keywords": [ "minecraft", @@ -13,27 +14,28 @@ "webgl", "bluemap" ], - "author": "Blue (Lukas Rieger)", + "author": "Lukas Rieger (https://bluecolored.de/)", "license": "MIT", "bugs": { "url": "https://github.com/BlueMap-Minecraft/BlueMap/issues" }, "homepage": "https://bluecolo.red/bluemap", "dependencies": { - "three": "^0.123.0", - "hammerjs": "^2.0.8" + "three": "~0.123.0", + "hammerjs": "~2.0.8" }, "devDependencies": { - "@babel/core": "^7.11.6", - "@babel/plugin-proposal-class-properties": "^7.10.4", - "@babel/polyfill": "^7.11.5", - "@babel/preset-env": "^7.11.5", - "@rollup/plugin-babel": "^5.2.1", - "concurrently": "^5.3.0", - "copyfiles": "^2.3.0", - "http-server": "^0.12.3", - "rollup": "^2.28.2", - "rollup-plugin-terser": "^7.0.2" + "@babel/core": "~7.11.6", + "@babel/plugin-proposal-class-properties": "~7.10.4", + "@babel/polyfill": "~7.11.5", + "@babel/preset-env": "~7.11.5", + "@types/babel__core": "~7.1.9", + "@rollup/plugin-babel": "~5.2.1", + "concurrently": "~5.3.0", + "copyfiles": "~2.3.0", + "http-server": "~0.12.3", + "rollup": "~2.28.2", + "rollup-plugin-terser": "~7.0.2" }, "scripts": { "build": "rollup -c", diff --git a/public/index.html b/public/index.html index ca4c886..518913f 100644 --- a/public/index.html +++ b/public/index.html @@ -8,7 +8,6 @@
- @@ -20,14 +19,53 @@ // show stats panel bluemap.stats.showPanel(1); - let mapControls = bluemap.controlsManager.controls; + let mapControls = new BlueMap.MapControls(bluemap.rootElement); let freeControls = new BlueMap.FreeFlightControls(bluemap.rootElement); + bluemap.controlsManager.controls = mapControls; // load map + const loadMaps = (dataUrl, events = null) => { + function loadSettings() { + return new Promise((resolve, reject) => { + let loader = new THREE.FileLoader(); + loader.setResponseType("json"); + loader.load(dataUrl + "settings.json", + resolve, + () => {}, + () => reject("Failed to load the settings.json!") + ); + }); + } + + return loadSettings().then(settings => { + let maps = []; + + // create maps + if (settings.maps !== undefined){ + for (let mapId in settings.maps) { + if (!settings.maps.hasOwnProperty(mapId)) continue; + + let mapSettings = settings.maps[mapId]; + if (mapSettings.enabled) + maps.push(new BlueMap.Map(mapId, dataUrl + mapId + "/", dataUrl + "settings.json", dataUrl + "textures.json", events)); + } + } + + // sort maps + maps.sort((map1, map2) => { + let sort = settings.maps[map1.id].ordinal - settings.maps[map2.id].ordinal; + if (isNaN(sort)) return 0; + return sort; + }); + + return maps; + }); + } + let maps = []; let markerManager = null; let playerManager = null; - BlueMap.loadMaps("data/", bluemap.events).then(loadedMaps => { + loadMaps("data/", bluemap.events).then(loadedMaps => { maps = loadedMaps; markerManager = new BlueMap.MarkerFileManager(bluemap.markerScene, "data/markers.json", maps[0].id, bluemap.events); @@ -38,7 +76,7 @@ playerManager.update(); playerManager.setAutoUpdateInterval(1000); - bluemap.setMap(maps[0]).then(() => { + bluemap.switchMap(maps[0]).then(() => { playerManager.worldId = maps[0].world; }); }); diff --git a/src/BlueMap.js b/src/BlueMap.js index 1b660d3..45e1e23 100644 --- a/src/BlueMap.js +++ b/src/BlueMap.js @@ -1,58 +1,31 @@ -import {FileLoader, Object3D} from "three"; -import {Map} from "./map/Map"; +import {Object3D} from "three"; export * from "./MapViewer"; + +export * from "./map/Map"; +export * from "./map/Tile"; +export * from "./map/TileLoader"; +export * from "./map/TileManager"; +export * from "./map/TileMap"; + +export * from "./markers/ExtrudeMarker"; +export * from "./markers/HtmlMarker"; +export * from "./markers/LineMarker"; +export * from "./markers/Marker"; export * from "./markers/MarkerFileManager"; +export * from "./markers/MarkerManager"; +export * from "./markers/MarkerSet"; +export * from "./markers/ObjectMarker"; +export * from "./markers/PlayerMarker"; export * from "./markers/PlayerMarkerManager"; +export * from "./markers/PoiMarker"; +export * from "./markers/ShapeMarker"; + export * from "./controls/map/MapControls"; export * from "./controls/freeflight/FreeFlightControls"; -/** - * Loads and returns a promise with an array of Maps loaded from that root-path.
- * DONT FORGET TO dispose() ALL MAPS RETURNED BY THIS METHOD IF YOU DONT NEED THEM ANYMORE! - * @param dataUrl {string} - * @param events {EventTarget} - * @returns {Promise} - */ -export const loadMaps = (dataUrl, events = null) => { - - function loadSettings() { - return new Promise((resolve, reject) => { - let loader = new FileLoader(); - loader.setResponseType("json"); - loader.load(dataUrl + "settings.json", - resolve, - () => {}, - () => reject("Failed to load the settings.json!") - ); - }); - } - - return loadSettings().then(settings => { - let maps = []; - - // create maps - if (settings.maps !== undefined){ - for (let mapId in settings.maps) { - if (!settings.maps.hasOwnProperty(mapId)) continue; - - let mapSettings = settings.maps[mapId]; - if (mapSettings.enabled) - maps.push(new Map(mapId, dataUrl + mapId + "/", events)); - } - } - - // sort maps - maps.sort((map1, map2) => { - let sort = settings.maps[map1.id].ordinal - settings.maps[map2.id].ordinal; - if (isNaN(sort)) return 0; - return sort; - }); - - return maps; - }); - -} +export * from "./util/CombinedCamera"; +export * from "./util/Utils"; /** * @param event {object} diff --git a/src/MapViewer.js b/src/MapViewer.js index 5333261..9a8a619 100644 --- a/src/MapViewer.js +++ b/src/MapViewer.js @@ -1,8 +1,7 @@ -import {Layers, PerspectiveCamera, Raycaster, Scene, Vector2, WebGLRenderer} from "three"; +import {PerspectiveCamera, Raycaster, Scene, Vector2, WebGLRenderer} from "three"; import {Map} from "./map/Map"; import {SkyboxScene} from "./skybox/SkyboxScene"; import {ControlsManager} from "./controls/ControlsManager"; -import {MapControls} from "./controls/map/MapControls"; import Stats from "./util/Stats"; import {alert, dispatchEvent, elementOffset, htmlToElement} from "./util/Utils"; import {TileManager} from "./map/TileManager"; @@ -12,30 +11,19 @@ import {LOWRES_VERTEX_SHADER} from "./map/lowres/LowresVertexShader"; import {LOWRES_FRAGMENT_SHADER} from "./map/lowres/LowresFragmentShader"; import {CombinedCamera} from "./util/CombinedCamera"; import {CSS2DRenderer} from "./util/CSS2DRenderer"; -import {FreeFlightControls} from "./controls/freeflight/FreeFlightControls"; export class MapViewer { - static InteractionType = { - LEFTCLICK: 0, - RIGHTCLICK: 1 - }; - /** * @param element {Element} - * @param dataUrl {string} - * @param liveApiUrl {string} * @param events {EventTarget} */ - constructor(element, dataUrl = "data/", liveApiUrl = "live/", events = element) { + constructor(element, events = element) { Object.defineProperty( this, 'isMapViewer', { value: true } ); this.rootElement = element; this.events = events; - this.dataUrl = dataUrl; - this.liveApiUrl = liveApiUrl; - this.stats = new Stats(); this.stats.hide(); @@ -77,11 +65,7 @@ export class MapViewer { this.camera = new CombinedCamera(75, 1, 0.1, 10000, 0); this.skyboxCamera = new PerspectiveCamera(75, 1, 0.1, 10000); - this.hammer = new Hammer.Manager(this.rootElement); - this.initializeHammer(); - this.controlsManager = new ControlsManager(this, this.camera); - this.controlsManager.controls = new MapControls(this.rootElement); this.raycaster = new Raycaster(); this.raycaster.layers.enableAll(); @@ -97,31 +81,13 @@ export class MapViewer { // initialize this.initializeRootElement(); - // handle some events + // handle window resizes window.addEventListener("resize", this.handleContainerResize); // start render-loop requestAnimationFrame(this.renderLoop); } - initializeHammer() { - let touchTap = new Hammer.Tap({ event: 'tap', pointers: 1, taps: 1, threshold: 2 }); - let touchMove = new Hammer.Pan({ event: 'move', direction: Hammer.DIRECTION_ALL, threshold: 0 }); - let touchTilt = new Hammer.Pan({ event: 'tilt', direction: Hammer.DIRECTION_VERTICAL, pointers: 2, threshold: 0 }); - let touchRotate = new Hammer.Rotate({ event: 'rotate', pointers: 2, threshold: 10 }); - let touchZoom = new Hammer.Pinch({ event: 'zoom', pointers: 2, threshold: 0 }); - - touchTilt.recognizeWith(touchRotate); - touchTilt.recognizeWith(touchZoom); - touchRotate.recognizeWith(touchZoom); - - this.hammer.add(touchTap); - this.hammer.add(touchMove); - this.hammer.add(touchTilt); - this.hammer.add(touchRotate); - this.hammer.add(touchZoom); - } - /** * Initializes the root-element */ @@ -129,14 +95,7 @@ export class MapViewer { this.rootElement.innerHTML = ""; let outerDiv = htmlToElement(`
`); - this.rootElement.appendChild(outerDiv) - this.hammer.on('tap', event => { - let rootOffset = elementOffset(this.rootElement); - this.handleMapInteraction(new Vector2( - ((event.center.x - rootOffset.top) / this.rootElement.clientWidth) * 2 - 1, - -((event.center.y - rootOffset.left) / this.rootElement.clientHeight) * 2 + 1 - )); - }); + this.rootElement.appendChild(outerDiv); // 3d-canvas outerDiv.appendChild(this.renderer.domElement); @@ -168,46 +127,58 @@ export class MapViewer { }; /** - * @param screenPos {{x: number, y:number}} - * @param interactionType {number} + * Triggers an interaction on the screen (map), e.g. a mouse-click. + * + * This will first attempt to invoke the onClick() method on the Object3D (e.g. Markers) that has been clicked. + * And if none of those consumed the event, it will fire a bluemapMapInteraction event. + * + * @param screenPosition {Vector2} - Clicked position on the screen (usually event.x, event.y) + * @param data {object} - Custom event data that will be added to the interaction-event */ - handleMapInteraction(screenPos, interactionType = MapViewer.InteractionType.LEFTCLICK) { + handleMapInteraction(screenPosition, data = {}) { + let rootOffset = elementOffset(this.rootElement); + let normalizedScreenPos = new Vector2( + ((screenPosition.x - rootOffset.top) / this.rootElement.clientWidth) * 2 - 1, + -((screenPosition.y - rootOffset.left) / this.rootElement.clientHeight) * 2 + 1 + ); + if (this.map && this.map.isLoaded){ - this.raycaster.setFromCamera(screenPos, this.camera); + this.raycaster.setFromCamera(normalizedScreenPos, this.camera); - let lowresLayer = new Layers(); - lowresLayer.set(2); - - // check marker interactions - let intersects = this.raycaster.intersectObjects([this.map.scene, this.markerScene], true); + // check Object3D interactions + let intersects = this.raycaster.intersectObjects([this.map.hiresTileManager.scene, this.map.lowresTileManager.scene, this.markerScene], true); let covered = false; for (let i = 0; i < intersects.length; i++) { if (intersects[i].object){ let object = intersects[i].object; + if (object.visible) { if (!covered || (object.material && !object.material.depthTest)) { if (object.onClick({ - interactionType: interactionType, + data: data, intersection: intersects[i] })) return; - covered = true; - } else if (!intersects[i].object.layers.test(lowresLayer)) { + } + + let parentRoot = object; + while(parentRoot.parent) parentRoot = parentRoot.parent; + if (parentRoot !== this.map.lowresTileManager.scene) { covered = true; } } } } + // fire event + dispatchEvent(this.events, "bluemapMapInteraction", { + data: data, + intersections: intersects + }); } } - updateLoadedMapArea = () => { - if (!this.map) return; - - this.map.loadMapArea(this.loadedCenter.x, this.loadedCenter.y, this.loadedHiresViewDistance, this.loadedLowresViewDistance); - } - /** + * @private * The render-loop to update and possibly render a new frame. * @param now {number} the current time in milliseconds */ @@ -235,6 +206,7 @@ export class MapViewer { }; /** + * @private * Renders a frame * @param delta {number} */ @@ -254,25 +226,16 @@ export class MapViewer { this.renderer.render(this.skyboxScene, this.skyboxCamera); this.renderer.clearDepth(); - /* - Layers: - 0 - always visible objects - 1 - hires layer - 2 - lowres layer - */ - if (this.map && this.map.isLoaded) { //update uniforms this.uniforms.hiresTileMap.value.pos.copy(this.map.hiresTileManager.centerTile); - this.camera.layers.set(2); - this.renderer.render(this.map.scene, this.camera); + this.renderer.render(this.map.lowresTileManager.scene, this.camera); this.renderer.clearDepth(); - this.camera.layers.set(0); - if (this.controlsManager.distance < 2000) this.camera.layers.enable(1); - this.renderer.render(this.map.scene, this.camera); - //this.renderer.render(this.map.markerManager.objectMarkerScene, this.camera); - //this.css2dRenderer.render(this.map.markerManager.elementMarkerScene, this.camera); + + if (this.controlsManager.distance < 2000) { + this.renderer.render(this.map.hiresTileManager.scene, this.camera); + } } // render markers @@ -285,7 +248,7 @@ export class MapViewer { * @param map {Map} * @returns Promise */ - setMap(map = null) { + switchMap(map = null) { if (this.map && this.map.isMap) this.map.unload(); this.map = map; @@ -316,6 +279,7 @@ export class MapViewer { } /** + * Loads the given area on the map (and unloads everything outside that area) * @param centerX {number} * @param centerZ {number} * @param hiresViewDistance {number} @@ -329,6 +293,14 @@ export class MapViewer { this.updateLoadedMapArea(); } + /** + * @private + */ + updateLoadedMapArea = () => { + if (!this.map) return; + this.map.loadMapArea(this.loadedCenter.x, this.loadedCenter.y, this.loadedHiresViewDistance, this.loadedLowresViewDistance); + } + /** * @returns {number} */ @@ -344,35 +316,4 @@ export class MapViewer { this.handleContainerResize(); } - // -------------------------- - - /** - * Applies a loaded settings-object (settings.json) - * @param settings {{maps: {}}} - */ - applySettings(settings) { - - // reset maps - this.maps.forEach(map => map.dispose()); - this.maps = []; - - // create maps - if (settings.maps !== undefined){ - for (let mapId in settings.maps) { - if (!settings.maps.hasOwnProperty(mapId)) continue; - - let mapSettings = settings.maps[mapId]; - if (mapSettings.enabled) - this.maps.push(new Map(mapId, this.dataUrl + mapId + "/", this.rootElement)); - } - } - - // sort maps - this.maps.sort((map1, map2) => { - let sort = settings.maps[map1.id].ordinal - settings.maps[map2.id].ordinal; - if (isNaN(sort)) return 0; - return sort; - }); - } - } diff --git a/src/controls/ControlsManager.js b/src/controls/ControlsManager.js index e9e473a..9d00749 100644 --- a/src/controls/ControlsManager.js +++ b/src/controls/ControlsManager.js @@ -116,7 +116,7 @@ export class ControlsManager { if (this.mapViewer.map) { let triggerDistance = 1; if (valueChanged) { - triggerDistance = this.mapViewer.loadedLowresViewDistance * 0.8; + triggerDistance = this.mapViewer.loadedLowresViewDistance * 0.5; } if ( Math.abs(this.lastMapUpdatePosition.x - this.position.x) >= triggerDistance || @@ -128,6 +128,15 @@ export class ControlsManager { } } + /** + * Triggers an interaction on the screen (map), e.g. a mouse-click + * @param screenPosition {THREE.Vector2} - Clicked position on the screen (usually event.x, event.y) + * @param data {object} - Custom event data that will be added to the interaction-event + */ + handleMapInteraction(screenPosition, data = {}) { + this.mapViewer.handleMapInteraction(screenPosition, data); + } + isValueChanged() { return !( this.position.equals(this.lastPosition) && diff --git a/src/controls/freeflight/FreeFlightControls.js b/src/controls/freeflight/FreeFlightControls.js index 1b66359..25f7940 100644 --- a/src/controls/freeflight/FreeFlightControls.js +++ b/src/controls/freeflight/FreeFlightControls.js @@ -75,6 +75,11 @@ export class FreeFlightControls { this.mouseAngle.stop(); this.touchPan.stop(); + this.target.removeEventListener("contextmenu", this.onContextMenu); + this.target.removeEventListener("mousedown", this.onMouseDown); + this.target.removeEventListener("mouseup", this.onMouseUp); + window.removeEventListener("wheel", this.onWheel); + this.started = false; } @@ -98,24 +103,8 @@ export class FreeFlightControls { } initializeHammer() { - let touchTap = new Hammer.Tap({ event: 'tap', pointers: 1, taps: 1, threshold: 2 }); let touchMove = new Hammer.Pan({ event: 'move', pointers: 1, direction: Hammer.DIRECTION_ALL, threshold: 0 }); - let touchTilt = new Hammer.Pan({ event: 'tilt', pointers: 2, direction: Hammer.DIRECTION_VERTICAL, threshold: 0 }); - let touchRotate = new Hammer.Rotate({ event: 'rotate', pointers: 2, threshold: 0 }); - let touchZoom = new Hammer.Pinch({ event: 'zoom', pointers: 2, threshold: 0 }); - - touchMove.recognizeWith(touchRotate); - touchMove.recognizeWith(touchTilt); - touchMove.recognizeWith(touchZoom); - touchTilt.recognizeWith(touchRotate); - touchTilt.recognizeWith(touchZoom); - touchRotate.recognizeWith(touchZoom); - - this.hammer.add(touchTap); - this.hammer.add(touchTilt); this.hammer.add(touchMove); - this.hammer.add(touchRotate); - this.hammer.add(touchZoom); } onContextMenu = evt => { diff --git a/src/controls/map/MapControls.js b/src/controls/map/MapControls.js index 484919f..eafc9d8 100644 --- a/src/controls/map/MapControls.js +++ b/src/controls/map/MapControls.js @@ -2,7 +2,7 @@ import {MouseMoveControls} from "./mouse/MouseMoveControls"; import {MouseZoomControls} from "./mouse/MouseZoomControls"; import {MouseRotateControls} from "./mouse/MouseRotateControls"; import {MouseAngleControls} from "./mouse/MouseAngleControls"; -import {MathUtils} from "three"; +import {MathUtils, Vector2} from "three"; import {animate, EasingFunctions, softClamp, softMin} from "../../util/Utils"; import {MapHeightControls} from "./MapHeightControls"; import {KeyMoveControls} from "./keyboard/KeyMoveControls"; @@ -23,6 +23,8 @@ export class MapControls { */ constructor(rootElement) { this.rootElement = rootElement; + + /** @type {ControlsManager} */ this.manager = null; this.started = false; @@ -58,6 +60,7 @@ export class MapControls { this.manager = manager; this.rootElement.addEventListener("contextmenu", this.onContextMenu); + this.hammer.on("tap", this.onTap); this.mouseMove.start(manager); this.mouseRotate.start(manager); @@ -97,6 +100,7 @@ export class MapControls { stop() { this.rootElement.removeEventListener("contextmenu", this.onContextMenu); + this.hammer.off("tap", this.onTap); this.mouseMove.stop(); this.mouseRotate.stop(); @@ -238,4 +242,8 @@ export class MapControls { evt.preventDefault(); } + onTap = evt => { + this.manager.handleMapInteraction(new Vector2(evt.center.x, evt.center.y)); + } + } \ No newline at end of file diff --git a/src/controls/map/keyboard/KeyZoomControls.js b/src/controls/map/keyboard/KeyZoomControls.js index 74a12d3..1da2b17 100644 --- a/src/controls/map/keyboard/KeyZoomControls.js +++ b/src/controls/map/keyboard/KeyZoomControls.js @@ -6,9 +6,11 @@ export class KeyZoomControls { static KEYS = { IN: [ new KeyCombination("NumpadAdd"), + new KeyCombination("Insert"), ], OUT: [ new KeyCombination("NumpadSubtract"), + new KeyCombination("Home"), ], } @@ -50,8 +52,8 @@ export class KeyZoomControls { * @param map {Map} */ update(delta, map) { - if (this.in) this.deltaZoom += 1; - if (this.out) this.deltaZoom -= 1; + if (this.in) this.deltaZoom -= 1; + if (this.out) this.deltaZoom += 1; if (this.deltaZoom === 0) return; diff --git a/src/map/Map.js b/src/map/Map.js index f279ba8..ff666da 100644 --- a/src/map/Map.js +++ b/src/map/Map.js @@ -14,15 +14,20 @@ export class Map { /** * @param id {string} * @param dataUrl {string} + * @param settingsUrl {string} + * @param texturesUrl {string} * @param events {EventTarget} */ - constructor(id, dataUrl, events = null) { + constructor(id, dataUrl, settingsUrl, texturesUrl, events = null) { Object.defineProperty( this, 'isMap', { value: true } ); this.id = id; this.events = events; this.dataUrl = dataUrl; + this.settingsUrl = settingsUrl; + this.texturesUrl = texturesUrl; + this.name = this.id; this.world = "-"; @@ -41,9 +46,6 @@ export class Map { translate: {x: 2, z: 2} }; - this.scene = new Scene(); - this.scene.autoUpdate = false; - this.raycaster = new Raycaster(); /** @type {ShaderMaterial[]} */ @@ -111,8 +113,11 @@ export class Map { this.hiresMaterial = this.createHiresMaterial(hiresVertexShader, hiresFragmentShader, uniforms, textures); - this.hiresTileManager = new TileManager(this.scene, new TileLoader(`${this.dataUrl}hires/`, this.hiresMaterial, this.hires, 1), this.onTileLoad("hires"), this.onTileUnload("hires"), this.events); - this.lowresTileManager = new TileManager(this.scene, new TileLoader(`${this.dataUrl}lowres/`, this.lowresMaterial, this.lowres, 2), this.onTileLoad("lowres"), this.onTileUnload("lowres"), this.events); + this.hiresTileManager = new TileManager(new Scene(), new TileLoader(`${this.dataUrl}hires/`, this.hiresMaterial, this.hires), this.onTileLoad("hires"), this.onTileUnload("hires"), this.events); + this.lowresTileManager = new TileManager(new Scene(), new TileLoader(`${this.dataUrl}lowres/`, this.lowresMaterial, this.lowres), this.onTileLoad("lowres"), this.onTileUnload("lowres"), this.events); + + this.hiresTileManager.scene.autoUpdate = false; + this.lowresTileManager.scene.autoUpdate = false; alert(this.events, `Map '${this.id}' is loaded.`, "fine"); }); @@ -165,7 +170,7 @@ export class Map { let loader = new FileLoader(); loader.setResponseType("json"); - loader.load(this.dataUrl + "../settings.json", + loader.load(this.settingsUrl, settings => { if (settings.maps && settings.maps[this.id]) { resolve(settings.maps[this.id]); @@ -189,7 +194,7 @@ export class Map { let loader = new FileLoader(); loader.setResponseType("json"); - loader.load(this.dataUrl + "../textures.json", + loader.load(this.texturesUrl, resolve, () => {}, () => reject(`Failed to load the textures.json for map: ${this.id}`) diff --git a/src/map/TileLoader.js b/src/map/TileLoader.js index eabee28..2f5ef68 100644 --- a/src/map/TileLoader.js +++ b/src/map/TileLoader.js @@ -45,6 +45,8 @@ export class TileLoader { object.position.set(tileX * tileSize.x + translate.x, 0, tileZ * tileSize.z + translate.z); object.scale.set(scale.x, 1, scale.z); + object.userData.tileUrl = this.tilePath + pathFromCoords(tileX, tileZ) + '.json'; + object.updateMatrixWorld(true); resolve(object);