/**
* @module CameraGui
* @description [Camera]{@link https://threejs.org/docs/index.html#api/en/cameras/PerspectiveCamera} graphical user interface.
*
* @author [Andrej Hristoliubov]{@link https://anhr.github.io/AboutMe/}
*
* @copyright 2011 Data Arts Team, Google Creative Lab
*
* @license under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
//import { dat } from './dat/dat.module.js';
import functionsFolder from './functionsFolder.js';
//import setOptions from './setOptions.js'
//import Options from './Options.js'
import Player from './player/player.js';
import three from './three.js'
class CameraGui {
/**
* [Camera]{@link https://threejs.org/docs/index.html#api/en/cameras/PerspectiveCamera} settings graphical user interface
* @param {THREE.PerspectiveCamera} camera [PerspectiveCamera]{@link https://threejs.org/docs/index.html#api/en/cameras/PerspectiveCamera}
* @param {Options} options See the <b>options</b> parameter of the <a href="../../myThree/jsdoc/module-MyThree-MyThree.html" target="_blank">MyThree</a> class.
* The following options are available.
* @param {OrbitControls} [options.orbitControls] [OrbitControls]{@link https://threejs.org/docs/index.html#examples/en/controls/OrbitControls}.
* @param {Function} [options.getLanguageCode=language code of your browser] returns the "primary language" subtag of the version of the browser.
* @param {object} [options.scales={}] axes scales.
* See the <b>options.scales</b> parameter of the <a href="../../../myThree/jsdoc/module-MyThree-MyThree.html" target="_blank">MyThree</a> class.
* @param {GUI} [gui] is [new dat.GUI(...)]{@link https://github.com/anhr/dat.gui} parent folder.
*/
constructor( camera, options, gui ) {
//Deprecated. Use options.cameraGui = this;
//Player.cameraGui = this;
// options = options || new Options();
if ( !options.boOptions ) {
console.error( 'CameraGui: call options = new Options( options ) first' );
return;
}
gui = gui || options.dat.gui;
if ( !gui || options.dat.cameraGui === false )
return;
const dat = three.dat,//options.dat.dat,
THREE = three.THREE;
options.cameraGui = this;
//scales
// setOptions.setScales( options );
// options.setScales();
//Обновить значения органов управления когда пользователь с помощью мыши передвинул камеру
if ( options.orbitControls )
options.orbitControls.addEventListener( 'change', function () {
update();
} );
//Localization
const lang = {
camera: 'Camera',
position: 'Position',
positionTitle: 'Camera position',
distanceToCamera: 'Distance',
distanceToCameraTitle: 'Distance from the camera to the point at which the camera is looking',
look: 'Look',
lookTitle: 'Camera is look at a selected point during playing.',
defaultButton: 'Default',
defaultTitle: 'Restore default camera settings.',
};
/*/
const _languageCode = options.getLanguageCode === undefined ? 'en'//Default language is English
: options.getLanguageCode();
*/
switch ( options.getLanguageCode() ) {
case 'ru'://Russian language
lang.camera = 'Камера';
lang.position = 'Позиция';
lang.positionTitle = 'Позиция камеры';
lang.distanceToCamera = 'Расстояние';
lang.distanceToCameraTitle = 'Расстояние между камерой и точкой, на которую она смотрит.',
lang.look = 'Следить';
lang.lookTitle = 'Камера следит за выбранной точкой во время проигрывания.';
lang.defaultButton = 'Восстановить';
lang.defaultTitle = 'Восстановить настройки камеры по умолчанию.';
break;
default://Custom language
if ( ( options.lang === undefined ) || ( options.lang.languageCode != _languageCode ) )
break;
Object.keys( options.lang ).forEach( function ( key ) {
if ( lang[key] === undefined )
return;
lang[key] = options.lang[key];
} );
}
const fCamera = gui.addFolder( lang.camera ),
fPosition = fCamera.addFolder( lang.position ),
controllersPosition = {
x: options.scales.x ? dat.controllerZeroStep( fPosition, camera.position, 'x', function ( value ) {
camera.position.x = value;
} ) : undefined,
y: options.scales.y ? dat.controllerZeroStep( fPosition, camera.position, 'y', function ( value ) {
camera.position.y = value;
} ) : undefined,
z: options.scales.z ? dat.controllerZeroStep( fPosition, camera.position, 'z', function ( value ) {
camera.position.z = value;
} ) : undefined,
};
dat.folderNameAndTitle( fPosition, lang.position, lang.positionTitle );
if ( controllersPosition.x ) dat.controllerNameAndTitle( controllersPosition.x, options.scales.x.name );
if ( controllersPosition.y ) dat.controllerNameAndTitle( controllersPosition.y, options.scales.y.name );
if ( controllersPosition.z ) dat.controllerNameAndTitle( controllersPosition.z, options.scales.z.name );
var controllersDistance, defaultDistance, funcFolder, controllerLook;
//Camera target
// Может устанвливаться только если создан проигрыватель options.player,
//потому что при установке птички 'Look' - Следить в guiSelectPoint, вызывается options.player.selectScene()
if ( options.player ) {
/*
Player.cameraTarget.init( { camera: camera }, options );
const cameraTarget = Player.cameraTarget.get();
*/
options.playerOptions.cameraTarget.init( { camera: camera }, options );
const cameraTarget = options.playerOptions.cameraTarget.get();
controllerLook = fCamera.add( cameraTarget, 'boLook' ).onChange( function ( boLook ) {
// if ( Player.player ) Player.player.selectScene();
if ( options.player ) {
cameraTarget.boMaual = true;
options.player.selectScene();
cameraTarget.boMaual = false;
}
if ( boLook )
return;
/*
if ( Player.orbitControls )
Player.orbitControls.reset();//обязательно вызвать controls.saveState();
*/
if ( options.orbitControls )
options.orbitControls.reset();//обязательно вызвать controls.saveState();
} );
dat.controllerNameAndTitle( controllerLook, lang.look, lang.lookTitle );
const fDistanceToCamera = fCamera.addFolder( lang.distanceToCamera ),
distance = {
x: Player.execFunc( cameraTarget.distanceToCamera, 'x', undefined, options ),
y: Player.execFunc( cameraTarget.distanceToCamera, 'y', undefined, options ),
z: Player.execFunc( cameraTarget.distanceToCamera, 'z', undefined, options ),
};
function setDistance( axisName, value ) {
if ( isNaN( value ) ) return;
if ( camera.userData.cameraTarget ) camera.userData.cameraTarget.distanceToCameraCur[axisName] = value;
// const cameraTarget = Player.cameraTarget.get();
cameraTarget.distanceToCameraCur[axisName] = value;
cameraTarget.setCameraPosition();
update();
}
controllersDistance = {
x: dat.controllerZeroStep( fDistanceToCamera, distance, 'x', function ( value ) {
// camera.userData.cameraTarget.distanceToCameraCur.x = value;
setDistance( 'x', value );
} ),
y: dat.controllerZeroStep( fDistanceToCamera, distance, 'y', function ( value ) {
// Player.cameraTarget.get().distanceToCameraCur.y = value;
setDistance( 'y', value );
} ),
z: dat.controllerZeroStep( fDistanceToCamera, distance, 'z', function ( value ) {
// camera.userData.cameraTarget.distanceToCameraCur.z = value;
setDistance( 'z', value );
} ),
};
defaultDistance = { x: distance.x, y: distance.y, z: distance.z };
dat.folderNameAndTitle( fDistanceToCamera, lang.distanceToCamera, lang.distanceToCameraTitle );
if ( options.scales.x ) dat.controllerNameAndTitle( controllersDistance.x, options.scales.x.name );
if ( options.scales.y ) dat.controllerNameAndTitle( controllersDistance.y, options.scales.y.name );
if ( options.scales.z ) dat.controllerNameAndTitle( controllersDistance.z, options.scales.z.name );
funcFolder = new functionsFolder( fDistanceToCamera, function ( func, axisName ) {
// const cameraTarget = Player.cameraTarget.get();
const cameraTarget = options.playerOptions.cameraTarget.get();
cameraTarget.distanceToCamera[axisName] = func;
const value = Player.execFunc( cameraTarget.distanceToCamera, axisName, options.time );//Player.getTime() );
controllersDistance[axisName].setValue( value, true );
// Player.cameraTarget.init( { camera: camera }, options );
options.playerOptions.cameraTarget.init( { camera: camera }, options );
}, options, cameraTarget.distanceToCamera/*, {
getLanguageCode: options.getLanguageCode,
vector: cameraTarget.distanceToCamera,
}*/ );
}
//Default button
const defaultPosition = { x: camera.position.x, y: camera.position.y, z: camera.position.z },
defaultTarget = options.orbitControls ?
{
x: options.orbitControls.target.x,
y: options.orbitControls.target.y,
z: options.orbitControls.target.z,
} :
{ x: 0, y: 0, z: 0 };//default camera look at zero coordinate
dat.controllerNameAndTitle( fCamera.add( {
defaultF: function ( value ) {
controllersPosition.x.setValue( defaultPosition.x );
controllersPosition.y.setValue( defaultPosition.y );
controllersPosition.z.setValue( defaultPosition.z );
camera.position.copy( defaultPosition );
camera.lookAt( defaultTarget );
if ( options.orbitControls ) {
options.orbitControls.target.copy( defaultTarget );
options.orbitControls.update();
}
if ( controllersDistance ) {
controllersDistance.x.setValue( defaultDistance.x );
controllersDistance.y.setValue( defaultDistance.y );
controllersDistance.z.setValue( defaultDistance.z );
}
},
}, 'defaultF' ), lang.defaultButton, lang.defaultTitle );
function update() {
// const cameraTarget = Player.cameraTarget.get();
const cameraTarget = options.playerOptions.cameraTarget.get( options );
/*не помню зачем это поставил
if ( !cameraTarget.boLook || !cameraTarget.target )
return;
*/
if ( controllersPosition.x ) controllersPosition.x.setValue( camera.position.x );
if ( controllersPosition.y ) controllersPosition.y.setValue( camera.position.y );
if ( controllersPosition.z ) controllersPosition.z.setValue( camera.position.z );
if ( controllersDistance ) {
const distanceToCamera = cameraTarget.getDistanceToCamera()
if ( controllersDistance.x ) controllersDistance.x.setValue( distanceToCamera.x );
if ( controllersDistance.y ) controllersDistance.y.setValue( distanceToCamera.y );
if ( controllersDistance.z ) controllersDistance.z.setValue( distanceToCamera.z );
}
if ( funcFolder ) funcFolder.setFunction( cameraTarget.distanceToCamera );
}
// if ( this ) {
/**
* Update camera controls.
*/
this.update = function () { update(); }
/**
* Look at selected point
* @param {boolean} [boLook=true] true - look at selected point
*/
this.look = function ( boLook = true ) { if ( controllerLook.getValue() !== boLook ) controllerLook.setValue( boLook ); }
// }
}
}
export default CameraGui;