Skip to content

Commit

Permalink
Merge pull request iTowns#293 from iTowns/move_camera_to_scene
Browse files Browse the repository at this point in the history
refactor: move camera and controls to Scene
  • Loading branch information
gchoqueux authored May 4, 2017
2 parents 7cb06ff + f717698 commit 93bafac
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 81 deletions.
33 changes: 30 additions & 3 deletions src/Core/Commander/Interfaces/ApiInterface/ApiGlobe.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import WMTS_Provider from '../../Providers/WMTS_Provider';
import WMS_Provider from '../../Providers/WMS_Provider';
import TileProvider from '../../Providers/TileProvider';
import loadGpx from '../../Providers/GpxUtils';
import { C } from '../../../Geographic/Coordinates';
import { C, ellipsoidSizes } from '../../../Geographic/Coordinates';
import Fetcher from '../../Providers/Fetcher';
import { STRATEGY_MIN_NETWORK_TRAFFIC } from '../../../../Scene/LayerUpdateStrategy';
import GlobeControls from '../../../../Renderer/ThreeExtended/GlobeControls';

var sceneIsLoaded = false;
export const INITIALIZED_EVENT = 'initialized';
Expand Down Expand Up @@ -385,11 +386,14 @@ ApiGlobe.prototype.createSceneGlobe = function createSceneGlobe(coordCarto, view
var gLDebug = false; // true to support GLInspector addon
var debugMode = false;

var coordinate = new C.EPSG_4326(coordCarto.longitude, coordCarto.latitude, coordCarto.altitude);
var positionCamera = new C.EPSG_4326(
coordCarto.longitude,
coordCarto.latitude,
coordCarto.altitude);

// FIXME: the scene is not really in EPSG:4978 atm, some axis are inverted, see
// https://github.com/iTowns/itowns2/pull/246
this.scene = Scene('EPSG:4978', coordinate, viewerDiv, debugMode, gLDebug);
this.scene = Scene('EPSG:4978', positionCamera, viewerDiv, debugMode, gLDebug);

var map = new Globe(gLDebug);

Expand All @@ -411,6 +415,29 @@ ApiGlobe.prototype.createSceneGlobe = function createSceneGlobe(coordCarto, view
this.viewerDiv.dispatchEvent(new CustomEvent(INITIALIZED_EVENT));
});

const size = ellipsoidSizes().x;

// Init camera
this.scene.camera.camera3D.near = Math.max(15.0, 0.000002352 * size);
this.scene.camera.camera3D.far = size * 10;
this.scene.camera.camera3D.updateProjectionMatrix();
this.scene.camera.camera3D.updateMatrixWorld(true);

// Create Control
const positionTargetCamera = positionCamera.clone();
positionTargetCamera.setAltitude(0);

this.scene.controls = new GlobeControls(
this.scene.camera.camera3D,
positionTargetCamera.as('EPSG:4978').xyz(),
this.scene.gfxEngine.renderer.domElement,
this.scene.gfxEngine);
this.scene.controls.rotateSpeed = 0.25;
this.scene.controls.zoomSpeed = 2.0;
this.scene.controls.minDistance = 30;
this.scene.controls.maxDistance = size * 8.0;
this.scene.controls.addEventListener('change', this.scene.gfxEngine.update);

return this.scene;
};

Expand Down
1 change: 0 additions & 1 deletion src/Renderer/ThreeExtended/GlobeControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,6 @@ function GlobeControls(camera, target, domElement, engine) {

// rotate point back to "camera-up-vector-is-up" space
// offset.applyQuaternion( quatInverse );

this.camera.position.copy(cameraTargetOnGlobe.localToWorld(offset));
}

Expand Down
91 changes: 26 additions & 65 deletions src/Renderer/c3DEngine.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,14 @@
/* global Uint8Array, Float64Array, document, window, Image */

import * as THREE from 'three';
import GlobeControls from './ThreeExtended/GlobeControls';
import Camera from './Camera';
import Atmosphere from '../Globe/Atmosphere';
import Capabilities from '../Core/System/Capabilities';
import RendererConstant from './RendererConstant';
import { ellipsoidSizes } from '../Core/Geographic/Coordinates';

var instance3DEngine = null;

function c3DEngine(scene, controlOptions, viewerDiv, debugMode, gLDebug) {
// Constructor

function c3DEngine(scene, viewerDiv, debugMode, gLDebug) {
if (instance3DEngine !== null) {
throw new Error('Cannot instantiate more than one c3DEngine');
}
Expand All @@ -37,31 +34,30 @@ function c3DEngine(scene, controlOptions, viewerDiv, debugMode, gLDebug) {
this.dfar = 0.0;
this.stateRender = RendererConstant.FINAL;
this.positionBuffer = null;

this.camera = new Camera(this.width, this.height, this.debug);
this.scene = scene;

if (this.debug) {
this.camDebug = new THREE.PerspectiveCamera(30, this.camera.ratio);
this.camDebug = new THREE.PerspectiveCamera(30, this.scene.camera.ratio);
}

this.pickingTexture = new THREE.WebGLRenderTarget(this.width, this.height);
this.pickingTexture.texture.minFilter = THREE.LinearFilter;
this.pickingTexture.texture.generateMipmaps = false;

this.renderScene = function renderScene() {
if (this.camera.camHelper())
{ this.camera.camHelper().visible = false; }
if (this.scene.camera.camHelper())
{ this.scene.camera.camHelper().visible = false; }

this.renderer.clear();
this.renderer.setViewport(0, 0, this.width, this.height);
this.renderer.render(this.scene3D, this.camera.camera3D);
this.renderer.render(this.scene3D, this.scene.camera.camera3D);

if (this.debug) {
this.enableRTC(false);
this.camera.camHelper().visible = true;
this.scene.camera.camHelper().visible = true;

var target = this.controls.moveTarget();
var position = this.camera.position();
var position = this.scene.camera.position();
var posDebug = new THREE.Vector3().subVectors(position, target);

posDebug.setLength(posDebug.length() * 2.0);
Expand All @@ -76,24 +72,24 @@ function c3DEngine(scene, controlOptions, viewerDiv, debugMode, gLDebug) {
this.renderer.render(this.scene3D, this.camDebug);

this.enableRTC(true);
this.camera.camHelper().visible = false;
this.scene.camera.camHelper().visible = false;
}
}.bind(this);

this.update = function update() {
this.camera.update();
this.scene.camera.update();
this.updateControl();
this.scene.notifyChange(0, true);
}.bind(this);

this.onWindowResize = function onWindowResize() {
this.width = this.viewerDiv.clientWidth * (this.debug ? 0.5 : 1);
this.height = this.viewerDiv.clientHeight;
this.camera.resize(this.width, this.height);
this.controls.updateCamera(this.camera);
this.scene.camera.resize(this.width, this.height);
this.scene.controls.updateCamera(this.scene.camera);

if (this.camDebug) {
this.camDebug.aspect = this.camera.ratio;
this.camDebug.aspect = this.scene.camera.ratio;
this.camDebug.updateProjectionMatrix();
}

Expand All @@ -102,32 +98,8 @@ function c3DEngine(scene, controlOptions, viewerDiv, debugMode, gLDebug) {
this.update();
}.bind(this);

this.scene = scene;
this.size = this.scene.size().x;

//
// init camera
//
this.camera.setPosition(controlOptions.position);
this.camera.camera3D.near = this.size * 2.333; // if near is too small --> bug no camera helper
this.camera.camera3D.far = this.size * 10;
this.camera.camera3D.updateProjectionMatrix();
this.camera.camera3D.updateMatrixWorld(true);

if (this.debug) {
this.camDebug.position.x = this.size * 6;
this.camDebug.lookAt(new THREE.Vector3(0, 0, 0));
this.camDebug.near = this.size * 0.1;
this.camDebug.far = this.size * 10;
this.camDebug.updateProjectionMatrix();
this.camera.createCamHelper();
this.scene3D.add(this.camera.camHelper());
var axisHelper = new THREE.AxisHelper(this.size * 1.33);
this.scene3D.add(axisHelper);
}

this.camera.camera3D.near = Math.max(15.0, 0.000002352 * this.size);
this.camera.camera3D.updateProjectionMatrix();
// TODO: remove globe dependency
this.size = ellipsoidSizes().x;

//
// Create canvas
Expand All @@ -154,16 +126,6 @@ function c3DEngine(scene, controlOptions, viewerDiv, debugMode, gLDebug) {
// this.viewerDiv.appendChild(canvas);
viewerDiv.appendChild(this.renderer.domElement);

//
// Create Control
//
this.controls = new GlobeControls(this.camera.camera3D, controlOptions.target, this.renderer.domElement, this);
this.controls.rotateSpeed = 0.25;
this.controls.zoomSpeed = 2.0;
this.controls.minDistance = 30;
this.controls.maxDistance = this.size * 8.0;
this.camera.update();

var gl = this.renderer.context;
var maxTexturesUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);

Expand All @@ -183,7 +145,6 @@ function c3DEngine(scene, controlOptions, viewerDiv, debugMode, gLDebug) {
};

window.addEventListener('resize', this.onWindowResize, false);
this.controls.addEventListener('change', this.update);

// select
this.renderer.domElement.addEventListener('selectClick', (event) => {
Expand All @@ -198,7 +159,7 @@ function c3DEngine(scene, controlOptions, viewerDiv, debugMode, gLDebug) {
* @returns {undefined}
*/
c3DEngine.prototype.updateControl = function updateControl() {
var len = this.camera.position().length();
var len = this.scene.camera.position().length();
var lim = this.size * 1.1;

if (len < lim) {
Expand Down Expand Up @@ -334,7 +295,7 @@ c3DEngine.prototype.renderTobuffer = function renderTobuffer(x, y, width, height
this.setStateRender(mode);
this.renderer.clear();
this.renderer.setViewport(x, y, width, height);
this.renderer.render(this.scene3D, this.camera.camera3D, this.pickingTexture);
this.renderer.render(this.scene3D, this.scene.camera.camera3D, this.pickingTexture);
this.setStateRender(originalState);
var pixelBuffer = new Uint8Array(4);
this.renderer.readRenderTargetPixels(this.pickingTexture, x, y, width, height, pixelBuffer);
Expand Down Expand Up @@ -364,7 +325,7 @@ c3DEngine.prototype.bufferToImage = function bufferToImage(pixelBuffer, width, h
};

c3DEngine.prototype.updatePositionBuffer = function updatePositionBuffer() {
this.camera.camera3D.updateMatrixWorld();
this.scene.camera.camera3D.updateMatrixWorld();
this.positionBuffer = this.renderTobuffer(0, 0, this.width, this.height, RendererConstant.DEPTH);
this.renderScene(); // TODO debug to remove white screen, but why?
};
Expand All @@ -385,7 +346,7 @@ c3DEngine.prototype.pickingInPositionBuffer = function pickingInPositionBuffer(m

var glslPosition = new THREE.Vector3(this.positionBuffer[i + 0], this.positionBuffer[i + 1], this.positionBuffer[i + 2]);

var worldPosition = glslPosition.applyMatrix4(this.camera.camera3D.matrixWorld);
var worldPosition = glslPosition.applyMatrix4(this.scene.camera.camera3D.matrixWorld);

return worldPosition;
};
Expand All @@ -400,7 +361,7 @@ c3DEngine.prototype.getPickingPosition = function getPickingPosition(mouse, scen
if (mouse === undefined)
{ mouse = new THREE.Vector2(Math.floor(this.width / 2), Math.floor(this.height / 2)); }

var camera = this.camera.camera3D;
var camera = this.scene.camera.camera3D;

camera.updateMatrixWorld();

Expand Down Expand Up @@ -430,7 +391,7 @@ var unpack1K = function unpack1K(color, factor) {
* @returns {int} uuid's node
* */
c3DEngine.prototype.screenCoordsToNodeId = function screenCoordsToNodeId(mouse) {
var camera = this.camera.camera3D;
var camera = this.scene.camera.camera3D;

camera.updateMatrixWorld();

Expand Down Expand Up @@ -467,7 +428,7 @@ c3DEngine.prototype.getPickingPositionFromDepth = (function getGetPickingPosFrom
if (mouse === undefined)
{ mouse = new THREE.Vector2(Math.floor(this.width / 2), Math.floor(this.height / 2)); }

var camera = this.camera.camera3D;
var camera = this.scene.camera.camera3D;

camera.updateMatrixWorld();

Expand Down Expand Up @@ -509,7 +470,7 @@ c3DEngine.prototype.getPickingPositionFromDepth = (function getGetPickingPosFrom

c3DEngine.prototype.placeDummy = function placeDummy(dummy, position) {
dummy.position.copy(position);
var size = position.clone().sub(this.camera.position()).length() / 200; // TODO distance
var size = position.clone().sub(this.scene.camera.position()).length() / 200; // TODO distance
dummy.scale.copy(new THREE.Vector3(size, size, size));
dummy.lookAt(new THREE.Vector3());
dummy.quaternion.multiply(new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(1, 0, 0), -Math.PI / 2));
Expand Down Expand Up @@ -546,7 +507,7 @@ c3DEngine.prototype.getRTCMatrixFromNode = function getRTCMatrixFromNode(node, c
return new THREE.Matrix4().multiplyMatrices(camera3D.projectionMatrix, mvc);
};

export default function (scene, positionCamera, viewerDiv, debugMode, gLDebug) {
instance3DEngine = instance3DEngine || new c3DEngine(scene, positionCamera, viewerDiv, debugMode, gLDebug);
export default function (scene, viewerDiv, debugMode, gLDebug) {
instance3DEngine = instance3DEngine || new c3DEngine(scene, viewerDiv, debugMode, gLDebug);
return instance3DEngine;
}
23 changes: 11 additions & 12 deletions src/Scene/Scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { ellipsoidSizes } from '../Core/Geographic/Coordinates';
import Layer from './Layer';
import MobileMappingLayer from '../MobileMapping/MobileMappingLayer';
import StyleManager from './Description/StyleManager';
import Camera from '../Renderer/Camera';

var instanceScene = null;

Expand Down Expand Up @@ -45,13 +46,11 @@ function Scene(crs, positionCamera, viewerDiv, debugMode, gLDebug) {
}
this.referenceCrs = crs;

const positionTargetCamera = positionCamera.clone();
positionTargetCamera.setAltitude(0);

const controlOptions = {
position: positionCamera.as(crs).xyz(),
target: positionTargetCamera.as(crs).xyz(),
};
this.camera = new Camera(
viewerDiv.clientWidth * (debugMode ? 0.5 : 1.0),
viewerDiv.clientHeight,
debugMode);
this.camera.setPosition(positionCamera.as(crs).xyz());

this.layers = [];
this.map = null;
Expand All @@ -64,7 +63,8 @@ function Scene(crs, positionCamera, viewerDiv, debugMode, gLDebug) {
this.stylesManager = new StyleManager();

this.gLDebug = gLDebug;
this.gfxEngine = c3DEngine(this, controlOptions, viewerDiv, debugMode, gLDebug);

this.gfxEngine = c3DEngine(this, viewerDiv, debugMode, gLDebug);
this.browserScene = new BrowseTree(this.gfxEngine);

this.needsRedraw = false;
Expand All @@ -84,19 +84,18 @@ Scene.prototype.constructor = Scene;
*/
Scene.prototype.updateCommand = function updateCommand() {
// TODO: Implement Me

};

/**
* @documentation: return current camera
* @returns {Scene_L7.Scene.gfxEngine.camera}
*/
Scene.prototype.currentCamera = function currentCamera() {
return this.gfxEngine.camera;
return this.camera;
};

Scene.prototype.currentControls = function currentControls() {
return this.gfxEngine.controls;
return this.controls;
};

Scene.prototype.getPickPosition = function getPickPosition(mouse) {
Expand Down Expand Up @@ -308,7 +307,7 @@ Scene.prototype.animateTime = function animateTime(value) {
this.browserScene.updateMaterialUniform('lightPosition', this.lightingPos.clone().normalize());
this.layers[0].node.updateLightingPos(this.lightingPos);
if (this.orbitOn) { // ISS orbit is 0.0667 degree per second -> every 60th of sec: 0.00111;
var p = this.gfxEngine.camera.camera3D.position;
var p = this.camera.camera3D.position;
var r = Math.sqrt(p.z * p.z + p.x * p.x);
var alpha = Math.atan2(p.z, p.x) + 0.0001;
p.x = r * Math.cos(alpha);
Expand Down

0 comments on commit 93bafac

Please sign in to comment.