const THREE = require('three');
/**
* This provide a full scale minimap. It will always
* display the whole map.
*
* @class
* @author Alan Wu
* @return {Minimap}
*/
exports.Minimap = function (sceneIn) {
let targetScene = sceneIn;
this.camera = new THREE.OrthographicCamera(
-0.5, 0.5, 0.5, -0.5, 0.01, 10);
this.helper = undefined;
let geometry = new THREE.BufferGeometry();
var vertices = new Float32Array( [
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, -1.0, 1.0
] );
let positionAttributes = new THREE.BufferAttribute( vertices, 3 );
geometry.setAttribute( 'position', positionAttributes);
var material = new THREE.MeshBasicMaterial( { color: 0x333333,
depthTest: false,
depthWrite: false,
opacity: 0.5,
transparent: true } );
this.mask = new THREE.Mesh( geometry, material );
let _box = new THREE.Box3();
let _center = new THREE.Vector3();
this.getDiffFromNormalised = (x, y) => {
_box.setFromBufferAttribute(positionAttributes).getCenter(_center);
let coord = _center.clone().project(this.camera);
let new_coord = new THREE.Vector3(x, y, coord.z).unproject(this.camera);
return new_coord.sub(_center);
}
let setCurrentCameraSettings = (diameter, newViewport) => {
if (targetScene.camera.near)
this.camera.near = targetScene.camera.near;
if (newViewport.farPlane)
this.camera.far = newViewport.farPlane;
if (newViewport.eyePosition)
this.camera.position.set(newViewport.eyePosition[0],
newViewport.eyePosition[1], newViewport.eyePosition[2]);
if (newViewport.upVector)
this.camera.up.set(newViewport.upVector[0], newViewport.upVector[1],
newViewport.upVector[2]);
if (newViewport.targetPosition)
this.camera.lookAt(new THREE.Vector3(newViewport.targetPosition[0],
newViewport.targetPosition[1], newViewport.targetPosition[2]));
this.camera.zoom = 1 / diameter;
this.camera.updateProjectionMatrix();
}
this.getBoundary = () => {
let target = new THREE.Vector3().copy(
targetScene.camera.target).project(targetScene.camera);
let v1 = new THREE.Vector3(-1, -1, target.z).unproject(targetScene.camera);
let v2 = new THREE.Vector3(1, -1, target.z).unproject(targetScene.camera);
let v3 = new THREE.Vector3(1, 1, target.z).unproject(targetScene.camera);
let v4 = new THREE.Vector3(-1, 1, target.z).unproject(targetScene.camera);
let array = [v1, v2, v3, v3, v4, v1];
positionAttributes.copyVector3sArray(array);
positionAttributes.needsUpdate = true;
}
this.updateCamera = () => {
this.getBoundary();
let cameraControl = targetScene.getZincCameraControls();
let boundingBox = targetScene.getBoundingBox();
if (boundingBox) {
// enlarge radius to keep image within edge of window
const diameter = boundingBox.min.distanceTo(boundingBox.max);
const radius = diameter / 2.0;
const centreX = (boundingBox.min.x + boundingBox.max.x) / 2.0;
const centreY = (boundingBox.min.y + boundingBox.max.y) / 2.0;
const centreZ = (boundingBox.min.z + boundingBox.max.z) / 2.0;
const clip_factor = 4.0;
const viewport = cameraControl.getViewportFromCentreAndRadius(
centreX, centreY, centreZ, radius, 40, radius * clip_factor);
setCurrentCameraSettings(diameter, viewport);
}
}
}