kopia lustrzana https://github.com/robhawkes/vizicities
207 wiersze
5.0 KiB
JavaScript
Executable File
207 wiersze
5.0 KiB
JavaScript
Executable File
import Tile from './Tile';
|
||
import BoxHelper from '../../vendor/BoxHelper';
|
||
import * as THREE from 'three';
|
||
|
||
// TODO: Make sure nothing is left behind in the heap after calling destroy()
|
||
|
||
class ImageTile extends Tile {
|
||
constructor(quadcode, path, layer) {
|
||
super(quadcode, path, layer);
|
||
}
|
||
|
||
// Request data for the tile
|
||
requestTileAsync() {
|
||
// Making this asynchronous really speeds up the LOD framerate
|
||
setTimeout(() => {
|
||
if (!this._mesh) {
|
||
this._mesh = this._createMesh();
|
||
}
|
||
|
||
this._requestTile();
|
||
}, 0);
|
||
}
|
||
|
||
destroy() {
|
||
// Cancel any pending requests
|
||
this._abortRequest();
|
||
|
||
// Clear image reference
|
||
this._image = null;
|
||
|
||
super.destroy();
|
||
}
|
||
|
||
_createMesh() {
|
||
// Something went wrong and the tile
|
||
//
|
||
// Possibly removed by the cache before loaded
|
||
if (!this._center) {
|
||
return;
|
||
}
|
||
|
||
var mesh = new THREE.Object3D();
|
||
var geom = new THREE.PlaneBufferGeometry(this._side, this._side, 1);
|
||
|
||
var material;
|
||
if (!this._world._environment._skybox) {
|
||
material = new THREE.MeshBasicMaterial({
|
||
depthWrite: false
|
||
});
|
||
|
||
// var material = new THREE.MeshPhongMaterial({
|
||
// depthWrite: false
|
||
// });
|
||
} else {
|
||
// Other MeshStandardMaterial settings
|
||
//
|
||
// material.envMapIntensity will change the amount of colour reflected(?)
|
||
// from the environment map – can be greater than 1 for more intensity
|
||
|
||
material = new THREE.MeshStandardMaterial({
|
||
depthWrite: false
|
||
});
|
||
material.roughness = 1;
|
||
material.metalness = 0.1;
|
||
material.envMap = this._world._environment._skybox.getRenderTarget();
|
||
}
|
||
|
||
var localMesh = new THREE.Mesh(geom, material);
|
||
localMesh.rotation.x = -90 * Math.PI / 180;
|
||
|
||
localMesh.receiveShadow = true;
|
||
|
||
// Setting this causes a depth-buffer intersection issue on the
|
||
// all-the-things example
|
||
// localMesh.renderOrder = 2;
|
||
|
||
mesh.add(localMesh);
|
||
|
||
// Setting this causes a depth-buffer intersection issue on the
|
||
// all-the-things example
|
||
// mesh.renderOrder = 2;
|
||
|
||
mesh.position.x = this._center[0];
|
||
mesh.position.z = this._center[1];
|
||
|
||
// var box = new BoxHelper(localMesh);
|
||
// mesh.add(box);
|
||
//
|
||
// mesh.add(this._createDebugMesh());
|
||
|
||
return mesh;
|
||
}
|
||
|
||
_createDebugMesh() {
|
||
var canvas = document.createElement('canvas');
|
||
canvas.width = 256;
|
||
canvas.height = 256;
|
||
|
||
var context = canvas.getContext('2d');
|
||
context.font = 'Bold 20px Helvetica Neue, Verdana, Arial';
|
||
context.fillStyle = '#ff0000';
|
||
context.fillText(this._quadcode, 20, canvas.width / 2 - 5);
|
||
context.fillText(this._tile.toString(), 20, canvas.width / 2 + 25);
|
||
|
||
var texture = new THREE.Texture(canvas);
|
||
|
||
// Silky smooth images when tilted
|
||
texture.magFilter = THREE.LinearFilter;
|
||
texture.minFilter = THREE.LinearMipMapLinearFilter;
|
||
|
||
// TODO: Set this to renderer.getMaxAnisotropy() / 4
|
||
texture.anisotropy = 4;
|
||
|
||
texture.needsUpdate = true;
|
||
|
||
var material = new THREE.MeshBasicMaterial({
|
||
map: texture,
|
||
transparent: true,
|
||
depthWrite: false
|
||
});
|
||
|
||
var geom = new THREE.PlaneBufferGeometry(this._side, this._side, 1);
|
||
var mesh = new THREE.Mesh(geom, material);
|
||
|
||
mesh.rotation.x = -90 * Math.PI / 180;
|
||
mesh.position.y = 0.1;
|
||
|
||
return mesh;
|
||
}
|
||
|
||
_requestTile() {
|
||
var urlParams = {
|
||
x: this._tile[0],
|
||
y: this._tile[1],
|
||
z: this._tile[2]
|
||
};
|
||
|
||
var url = this._getTileURL(urlParams);
|
||
|
||
var image = document.createElement('img');
|
||
|
||
this._aborted = false;
|
||
|
||
image.addEventListener('load', event => {
|
||
if (this.isAborted()) {
|
||
return;
|
||
}
|
||
|
||
var texture = new THREE.Texture();
|
||
|
||
texture.image = image;
|
||
texture.needsUpdate = true;
|
||
|
||
// Silky smooth images when tilted
|
||
texture.magFilter = THREE.LinearFilter;
|
||
texture.minFilter = THREE.LinearMipMapLinearFilter;
|
||
|
||
// TODO: Set this to renderer.getMaxAnisotropy() / 4
|
||
texture.anisotropy = 4;
|
||
|
||
texture.needsUpdate = true;
|
||
|
||
// Something went wrong and the tile or its material is missing
|
||
//
|
||
// Possibly removed by the cache before the image loaded
|
||
if (!this._mesh || !this._mesh.children[0] || !this._mesh.children[0].material) {
|
||
return;
|
||
}
|
||
|
||
this._mesh.children[0].material.map = texture;
|
||
this._mesh.children[0].material.needsUpdate = true;
|
||
|
||
this._texture = texture;
|
||
this._ready = true;
|
||
}, false);
|
||
|
||
// image.addEventListener('progress', event => {}, false);
|
||
// image.addEventListener('error', event => {}, false);
|
||
|
||
image.crossOrigin = '';
|
||
|
||
// Load image
|
||
image.src = url;
|
||
|
||
this._image = image;
|
||
}
|
||
|
||
_abortRequest() {
|
||
if (!this._image || this._ready) {
|
||
return;
|
||
}
|
||
|
||
this._aborted = true;
|
||
|
||
this._image.src = '';
|
||
}
|
||
}
|
||
|
||
export default ImageTile;
|
||
|
||
var noNew = function(quadcode, path, layer) {
|
||
return new ImageTile(quadcode, path, layer);
|
||
};
|
||
|
||
// Initialise without requiring new keyword
|
||
export {noNew as imageTile};
|