planets.js Example File
threejs/planets/planets.js
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCanvas3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
Qt.include("three.js")
Qt.include("threex.planets.js")
var SUN = 0;
var MERCURY = 1;
var VENUS = 2;
var EARTH = 3;
var MARS = 4;
var JUPITER = 5;
var SATURN = 6;
var URANUS = 7;
var NEPTUNE = 8;
var NUM_SELECTABLE_PLANETS = 9;
var MOON = 9;
var SOLAR_SYSTEM = 100;
var camera, scene, renderer;
var planetCanvas, mouse, raycaster;
var daysPerFrame;
var daysPerFrameScale;
var planetScale;
var cameraDistance;
var objects = []; // Planet objects
var hitObjects = []; // Planet hit detection objects
var planets = []; // Planet data info
var commonGeometry;
var hitGeometry;
var solarDistance = 2600000;
var saturnOuterRadius = 120.700;
var uranusOuterRadius = 40;
var qmlView;
var oldFocusedPlanetPosition;
var oldCameraPosition;
var defaultCameraPosition;
var y = 2000;
var m = 1;
var D = 1;
// Time scale formula based on http://www.stjarnhimlen.se/comp/ppcomp.html
var startD = 367 * y - 7 * (y + (m + 9) / 12) / 4 + 275 * m / 9 + D - 730530;
var oldTimeD = startD;
var currTimeD = startD;
var auScale = 149597.870700; // AU in thousands of kilometers
var focusedScaling = false;
var focusedMinimumScale = 20;
var actualScale;
function initializeGL(canvas, eventSource, mainView) {
planetCanvas = canvas;
qmlView = mainView;
camera = new THREE.PerspectiveCamera(45, canvas.width / canvas.height, 2500000, 20000000);
defaultCameraPosition = new THREE.Vector3(solarDistance, solarDistance, solarDistance);
camera.position.set(defaultCameraPosition.x, defaultCameraPosition.y, defaultCameraPosition.z);
scene = new THREE.Scene();
var starSphere = THREEx.Planets.createStarfield(8500000);
scene.add(starSphere);
var light = new THREE.PointLight(0x777777, 2);
light.position.set(0, 0, 0);
scene.add(light);
scene.add(new THREE.AmbientLight(0x111111));
loadPlanetData();
createPlanets();
setScale(1200);
camera.lookAt(objects[0].position); // look at the Sun
raycaster = new THREE.Raycaster();
mouse = new THREE.Vector2();
renderer = new THREE.Canvas3DRenderer(
{ canvas: canvas, antialias: true, devicePixelRatio: canvas.devicePixelRatio });
renderer.setPixelRatio(canvas.devicePixelRatio);
renderer.setSize(canvas.width, canvas.height);
eventSource.mouseDown.connect(onDocumentMouseDown);
}
function loadPlanetData() {
// Planet Data
// radius - planet radius in millions of meters
// tilt - planet axis angle
// N1 N2 - longitude of the ascending node
// i1 i2 - inclination to the ecliptic (plane of the Earth's orbit)
// w1 w2 - argument of perihelion
// a1 a2 - semi-major axis, or mean distance from Sun
// e1 e2 - eccentricity (0=circle, 0-1=ellipse, 1=parabola)
// M1 M2 - mean anomaly (0 at perihelion; increases uniformly with time)
// period - sidereal rotation period
// centerOfOrbit - the planet in the center of the orbit
// (orbital elements based on http://www.stjarnhimlen.se/comp/ppcomp.html)
var sun = { radius: 694.439, tilt: 63.87, period: 25.05 };
planets.push(sun);
var mercury = {
radius: 2.433722, tilt: 0.04, N1: 48.3313, N2: 0.0000324587,
i1: 7.0047, i2: 0.0000000500, w1: 29.1241, w2: 0.0000101444,
a1: 0.387098, a2: 0, e1: 0.205635, e2: 0.000000000559,
M1: 168.6562, M2: 4.0923344368, period: 58.646,
centerOfOrbit: SUN
};
planets.push(mercury);
var venus = {
radius: 6.046079, tilt: 177.36, N1: 76.6799, N2: 0.0000246590,
i1: 3.3946, i2: 0.0000000275, w1: 54.8910, w2: 0.0000138374,
a1: 0.723330, a2: 0, e1: 0.006773, e2: -0.000000001302,
M1: 48.0052, M2: 1.6021302244, period: 243.0185,
centerOfOrbit: SUN
};
planets.push(venus);
var earth = {
radius: 6.371, tilt: 25.44, N1: 174.873, N2: 0,
i1: 0.00005, i2: 0, w1: 102.94719, w2: 0,
a1: 1, a2: 0, e1: 0.01671022, e2: 0,
M1: 357.529, M2: 0.985608, period: 0.997,
centerOfOrbit: SUN
};
planets.push(earth);
var mars = {
radius: 3.389372, tilt: 25.19, N1: 49.5574, N2: 0.0000211081,
i1: 1.8497, i2: -0.0000000178, w1: 286.5016, w2: 0.0000292961,
a1: 1.523688, a2: 0, e1: 0.093405, e2: 0.000000002516,
M1: 18.6021, M2: 0.5240207766, period: 1.025957,
centerOfOrbit: SUN
};
planets.push(mars);
var jupiter = {
radius: 71.41254, tilt: 3.13, N1: 100.4542, N2: 0.0000276854,
i1: 1.3030, i2: -0.0000001557, w1: 273.8777, w2: 0.0000164505,
a1: 5.20256, a2: 0, e1: 0.048498, e2: 0.000000004469,
M1: 19.8950, M2: 0.0830853001, period: 0.4135,
centerOfOrbit: SUN
};
planets.push(jupiter);
var saturn = {
radius: 60.19958, tilt: 26.73, N1: 113.6634, N2: 0.0000238980,
i1: 2.4886, i2: -0.0000001081, w1: 339.3939, w2: 0.0000297661,
a1: 9.55475, a2: 0, e1: 0.055546, e2: -0.000000009499,
M1: 316.9670, M2: 0.0334442282, period: 0.4395,
centerOfOrbit: SUN
};
planets.push(saturn);
var uranus = {
radius: 25.5286, tilt: 97.77, N1: 74.0005, N2: 0.000013978,
i1: 0.7733, i2: 0.000000019, w1: 96.6612, w2: 0.000030565,
a1: 19.18171, a2: -0.0000000155, e1: 0.047318, e2: 0.00000000745,
M1: 142.5905, M2: 0.011725806, period: 0.71833,
centerOfOrbit: SUN
};
planets.push(uranus);
var neptune = {
radius: 24.73859, tilt: 28.32, N1: 131.7806, N2: 0.000030173,
i1: 1.7700, i2: -0.000000255, w1: 272.8461, w2: 0.000006027,
a1: 30.05826, a2: 0.00000003313, e1: 0.008606, e2: 0.00000000215,
M1: 260.2471, M2: 0.005995147, period: 0.6713,
centerOfOrbit: SUN
};
planets.push(neptune);
var moon = {
radius: 1.5424, tilt: 28.32, N1: 125.1228, N2: -0.0529538083,
i1: 5.1454, i2: 0, w1: 318.0634, w2: 0.1643573223,
a1: 0.273, a2: 0, e1: 0.054900, e2: 0,
M1: 115.3654, M2: 13.0649929509, period: 27.321582,
centerOfOrbit: EARTH
};
planets.push(moon);
}
function createPlanets() {
objects = [];
commonGeometry = new THREE.BufferGeometry().fromGeometry(new THREE.SphereGeometry(1, 64, 64));
hitGeometry = new THREE.BufferGeometry().fromGeometry(new THREE.SphereGeometry(1, 8, 8));
var ringSegments = 70;
var mesh, innerRadius, outerRadius, ring;
for (var i = 0; i < planets.length; i ++) {
switch (i) {
case SUN:
mesh = createSun(planets[i]["radius"]);
mesh.position.set(0, 0, 0);
break;
case MERCURY:
mesh = createPlanet(planets[i]["radius"], 0.005, 'images/mercurymap.jpg',
'images/mercurybump.jpg');
break;
case VENUS:
mesh = createPlanet(planets[i]["radius"], 0.005, 'images/venusmap.jpg',
'images/venusbump.jpg');
break;
case EARTH:
mesh = createPlanet(planets[i]["radius"], 0.05, 'images/earthmap1k.jpg',
'images/earthbump1k.jpg', 'images/earthspec1k.jpg');
createEarthCloud(mesh);
break;
case MARS:
mesh = createPlanet(planets[i]["radius"], 0.05, 'images/marsmap1k.jpg',
'images/marsbump1k.jpg');
break;
case JUPITER:
mesh = createPlanet(planets[i]["radius"], 0.02, 'images/jupitermap.jpg',
'images/jupitermap.jpg');
break;
case SATURN:
mesh = createPlanet(planets[i]["radius"], 0.05, 'images/saturnmap.jpg',
'images/saturnmap.jpg');
innerRadius = (planets[i]["radius"] + 6.630) / planets[i]["radius"];
outerRadius = (planets[i]["radius"] + saturnOuterRadius) / planets[i]["radius"];
ring = createRing(innerRadius, outerRadius, ringSegments,
'qrc:images/saturnringcolortrans.png');
ring.receiveShadow = true;
ring.castShadow = true;
mesh.add(ring);
break;
case URANUS:
mesh = createPlanet(planets[i]["radius"], 0.05, 'images/uranusmap.jpg',
'images/uranusmap.jpg');
innerRadius = (planets[i]["radius"] + 2) / planets[i]["radius"];
outerRadius = (planets[i]["radius"] + uranusOuterRadius) / planets[i]["radius"];
ring = createRing(innerRadius, outerRadius, ringSegments,
'qrc:images/uranusringcolortrans.png');
ring.receiveShadow = true;
ring.castShadow = true;
mesh.add(ring);
break;
case NEPTUNE:
mesh = createPlanet(planets[i]["radius"], 0.05, 'images/neptunemap.jpg',
'images/neptunemap.jpg');
break;
case MOON:
mesh = createPlanet(planets[i]["radius"], 0.05, 'images/moonmap1k.jpg',
'images/moonbump1k.jpg');
break;
}
objects.push(mesh);
scene.add(mesh);
// Create separate meshes for click detection
var hitMesh = new THREE.Mesh(hitGeometry);
hitMesh.visible = false;
hitObjects.push(hitMesh);
scene.add(hitMesh);
}
}
function createSun(radius) {
var textureLoader = new THREE.TextureLoader();
var texture = textureLoader.load('images/sunmap.jpg');
var material = new THREE.MeshBasicMaterial({ map: texture });
var mesh = new THREE.Mesh(commonGeometry, material);
mesh.scale.set(radius, radius, radius);
mesh.receiveShadow = false;
mesh.castShadow = false;
return mesh;
}
function createPlanet(radius, bumpMapScale, mapTexture, bumpTexture, specularTexture) {
var textureLoader = new THREE.TextureLoader();
var material = new THREE.MeshPhongMaterial({
map: textureLoader.load(mapTexture),
bumpMap: textureLoader.load(bumpTexture),
bumpScale: bumpMapScale
});
if (specularTexture) {
material.specularMap = textureLoader.load(specularTexture);
material.specular = new THREE.Color('grey');
material.shininess = 50.0;
} else {
material.shininess = 1.0;
}
var mesh = new THREE.Mesh(commonGeometry, material);
mesh.scale.set(radius, radius, radius);
return mesh;
}
function createEarthCloud(earthMesh) {
var textureLoader = new THREE.TextureLoader();
var material = new THREE.MeshPhongMaterial({
map: textureLoader.load('qrc:images/earthcloudmapcolortrans.png'),
side: THREE.BackSide,
transparent: true,
opacity: 0.8
});
var mesh = new THREE.Mesh(commonGeometry, material);
var material2 = new THREE.MeshPhongMaterial({
map: textureLoader.load('qrc:images/earthcloudmapcolortrans.png'),
side: THREE.FrontSide,
transparent: true,
opacity: 0.8
});
var mesh2 = new THREE.Mesh(commonGeometry, material2);
mesh.scale.set(1.02, 1.02, 1.02);
earthMesh.add(mesh);
mesh2.scale.set(1.02, 1.02, 1.02);
earthMesh.add(mesh2);
}
function createRing(radius, width, height, texture) {
var textureLoader = new THREE.TextureLoader();
var geometry = new THREE.BufferGeometry().fromGeometry(
new THREEx.Planets._RingGeometry(radius, width, height));
var material = new THREE.MeshPhongMaterial({
map: textureLoader.load(texture),
side: THREE.DoubleSide,
transparent: true,
opacity: 0.8
});
material.map.minFilter = THREE.NearestFilter;
var mesh = new THREE.Mesh(geometry, material);
mesh.lookAt(new THREE.Vector3(0, 90, 0));
return mesh;
}
function createStarfield(radius) {
var textureLoader = new THREE.TextureLoader();
var texture = textureLoader.load('images/galaxy_starfield.png')
var material = new THREE.MeshBasicMaterial({
map: texture,
side: THREE.BackSide
})
var geometry = new THREE.BufferGeometry().fromGeometry(new THREE.SphereGeometry(radius, 32, 32));
var mesh = new THREE.Mesh(geometry, material)
return mesh
}
function onResizeGL(canvas) {
if (camera === undefined) return;
camera.aspect = canvas.width / canvas.height;
camera.updateProjectionMatrix();
renderer.setPixelRatio(canvas.devicePixelRatio);
renderer.setSize(canvas.width, canvas.height);
}
function onSpeedChanged(value) {
daysPerFrameScale = value;
}
function setScale(value, focused) {
// Save actual scale in focus mode
if (!focused)
actualScale = value;
// Limit minimum scaling in focus mode to avoid jitter caused by rounding errors
if (value <= focusedMinimumScale && (focusedScaling || focused)) {
planetScale = focusedMinimumScale;
} else {
planetScale = actualScale;
}
for (var i = 0; i < objects.length; i++) {
var object = objects[i];
// first reset scale
var radius = planets[i]["radius"];
object.scale.set(radius, radius, radius);
if (i === SUN) {
object.scale.multiplyScalar(planetScale / 100);
} else {
object.scale.multiplyScalar(planetScale);
}
hitObjects[i].scale.set(object.scale.x, object.scale.y, object.scale.z);
}
}
function prepareFocusedPlanetAnimation() {
oldCameraPosition = camera.position.clone();
var planet = SUN;
if (qmlView.oldPlanet !== SOLAR_SYSTEM)
planet = qmlView.oldPlanet;
oldFocusedPlanetPosition = objects[planet].position.clone();
qmlView.oldPlanet = qmlView.focusedPlanet;
if (qmlView.focusedPlanet !== SOLAR_SYSTEM && actualScale <= focusedMinimumScale) {
// Limit minimum scaling in focus mode to avoid jitter caused by rounding errors
planetScale = focusedMinimumScale;
setScale(focusedMinimumScale, true);
focusedScaling = true;
} else if (focusedScaling === true) {
// Restore normal scaling
focusedScaling = false;
setScale(actualScale);
}
calculateLookAtOffset();
calculateCameraOffset();
}
function setCameraDistance(distance) {
cameraDistance = distance;
}
function calculateLookAtOffset() {
var offset = oldFocusedPlanetPosition.clone();
var planet = 0;
if (qmlView.focusedPlanet !== SOLAR_SYSTEM)
planet = qmlView.oldPlanet;
var focusedPlanetPosition = objects[planet].position.clone();
offset.sub(focusedPlanetPosition);
qmlView.xLookAtOffset = offset.x;
qmlView.yLookAtOffset = offset.y;
qmlView.zLookAtOffset = offset.z;
}
function calculateCameraOffset() {
var offset = oldCameraPosition.clone();
var planet = 0;
if (qmlView.focusedPlanet !== SOLAR_SYSTEM)
planet = qmlView.focusedPlanet;
var newCameraPosition = getNewCameraPosition(getOuterRadius(planet));
if (qmlView.focusedPlanet !== SUN)
offset.sub(newCameraPosition);
if (qmlView.focusedPlanet === SUN && qmlView.oldPlanet === SOLAR_SYSTEM) {
qmlView.xCameraOffset = Math.abs(offset.x);
qmlView.yCameraOffset = Math.abs(offset.y);
qmlView.zCameraOffset = Math.abs(offset.z);
} else { // from a planet to another
qmlView.xCameraOffset = offset.x;
qmlView.yCameraOffset = offset.y;
qmlView.zCameraOffset = offset.z;
}
}
function getNewCameraPosition( radius ) {
var position;
if (qmlView.focusedPlanet === SOLAR_SYSTEM) {
position = defaultCameraPosition.clone();
position.multiplyScalar(cameraDistance);
} else if (qmlView.focusedPlanet === SUN) {
position = new THREE.Vector3(radius * planetScale * 2,
radius * planetScale * 2,
radius * planetScale * 2);
position.multiplyScalar(cameraDistance);
} else {
var vec1 = objects[qmlView.focusedPlanet].position.clone();
var vec2 = new THREE.Vector3(0, 1, 0);
vec1.normalize();
vec2.cross(vec1);
vec2.multiplyScalar(radius * planetScale * cameraDistance * 4);
vec2.add(objects[qmlView.focusedPlanet].position);
vec1.set(0, radius * planetScale, 0);
vec2.add(vec1);
position = vec2;
}
return position;
}
function onDocumentMouseDown(x, y) {
// Mouse selection for planets and Solar system, not for the Moon.
// Intersection tests are done against a set of cruder hit objects instead of
// actual planet meshes, as checking a lot of faces can be slow.
mouse.set((x / planetCanvas.width) * 2 - 1, - (y / planetCanvas.height ) * 2 + 1);
raycaster.setFromCamera(mouse, camera);
var intersects = [];
var i = 0;
var objectCount = hitObjects.length - 1; // -1 excludes the moon, which is the last object
while (i < objectCount) {
// Update hitObject position
var objectPos = objects[i].position;
var hitObject = hitObjects[i];
hitObject.position.set(objectPos.x, objectPos.y, objectPos.z);
hitObject.updateMatrixWorld();
hitObject.raycast( raycaster, intersects );
i++;
}
intersects.sort( raycaster.ascSort );
var selectedPlanet;
if (intersects.length > 0) {
var intersect = intersects[0];
i = 0;
while (i < objectCount) {
if (intersect.object === hitObjects[i]) {
selectedPlanet = i;
break;
}
i++;
}
if (selectedPlanet < NUM_SELECTABLE_PLANETS) {
qmlView.focusedPlanet = selectedPlanet;
// Limit minimum scaling in focus mode to avoid jitter caused by rounding errors
if (actualScale <= focusedMinimumScale) {
planetScale = focusedMinimumScale;
setScale(focusedMinimumScale, true);
}
focusedScaling = true;
}
} else {
qmlView.focusedPlanet = SOLAR_SYSTEM;
// Restore normal scaling
if (focusedScaling === true) {
focusedScaling = false;
setScale(actualScale);
}
}
}
function paintGL(canvas) {
if (qmlView.focusedPlanet === SOLAR_SYSTEM)
daysPerFrame = daysPerFrameScale * 10;
else
daysPerFrame = daysPerFrameScale * planets[qmlView.focusedPlanet]["period"] / 100;
// Advance the time in days
oldTimeD = currTimeD;
currTimeD = currTimeD + daysPerFrame;
var deltaTimeD = currTimeD - oldTimeD;
// Position the planets orbiting the sun
for (var i = 1; i < objects.length; i ++) {
var object = objects[i];
var planet = planets[i];
// Bumpmaps of mercury, venus, jupiter and moon need special handling
if (i == MERCURY || i == VENUS || i == JUPITER || i == MOON)
object.material.bumpScale = 0.03 * planetScale;
else
object.material.bumpScale = 0.3 * planetScale;
// Calculate the planet orbital elements from the current time in days
var N = (planet["N1"] + planet["N2"] * currTimeD) * Math.PI / 180;
var iPlanet = (planet["i1"] + planet["i2"] * currTimeD) * Math.PI / 180;
var w = (planet["w1"] + planet["w2"] * currTimeD) * Math.PI / 180;
var a = planet["a1"] + planet["a2"] * currTimeD;
var e = planet["e1"] + planet["e2"] * currTimeD;
var M = (planet["M1"] + planet["M2"] * currTimeD) * Math.PI / 180;
var E = M + e * Math.sin(M) * (1.0 + e * Math.cos(M));
var xv = a * (Math.cos(E) - e);
var yv = a * (Math.sqrt(1.0 - e * e) * Math.sin(E));
var v = Math.atan2(yv, xv);
// Calculate the distance (radius)
var r = Math.sqrt(xv * xv + yv * yv);
// From http://www.davidcolarusso.com/astro/
// Modified to compensate for the right handed coordinate system of OpenGL
var xh = r * (Math.cos(N) * Math.cos(v + w)
- Math.sin(N) * Math.sin(v + w) * Math.cos(iPlanet));
var zh = -r * (Math.sin(N) * Math.cos(v + w)
+ Math.cos(N) * Math.sin(v + w) * Math.cos(iPlanet));
var yh = r * (Math.sin(w + v) * Math.sin(iPlanet));
// Apply the position offset from the center of orbit to the bodies
var centerOfOrbit = objects[planet["centerOfOrbit"]];
object.position.set(centerOfOrbit.position.x + xh * auScale,
centerOfOrbit.position.y + yh * auScale,
centerOfOrbit.position.z + zh * auScale);
// Calculate and apply the appropriate axis tilt to the bodies
// and rotate them around the axis
var radians = planet["tilt"] * Math.PI / 180; // tilt in radians
object.rotation.order = 'ZXY';
object.rotation.x = 0;
object.rotation.y += (deltaTimeD / planet["period"]) * 2 * Math.PI;
object.rotation.z = radians;
}
// rotate the Sun
var sun = objects[SUN];
sun.rotation.order = 'ZXY';
sun.rotation.x = 0;
sun.rotation.y += (deltaTimeD / planets[SUN]["period"]) * 2 * Math.PI;
sun.rotation.z = planets[SUN]["tilt"] * Math.PI / 180; // tilt in radians
// calculate the outer radius of the focused item
var outerRadius = getOuterRadius(qmlView.focusedPlanet);
// get the appropriate near plane position for the camera and animate it with QML animations
qmlView.cameraNear = outerRadius;
camera.near = qmlView.cameraNear;
camera.updateProjectionMatrix();
// Calculate and set camera position
var cameraPosition = getNewCameraPosition(outerRadius);
var cameraOffset = new THREE.Vector3(qmlView.xCameraOffset,
qmlView.yCameraOffset,
qmlView.zCameraOffset);
cameraPosition.add(cameraOffset);
camera.position.set(cameraPosition.x, cameraPosition.y, cameraPosition.z);
// Calculate and set camera look-at point
var lookAtPlanet = SUN;
if (qmlView.focusedPlanet !== SOLAR_SYSTEM)
lookAtPlanet = qmlView.focusedPlanet;
var cameraLookAt = objects[lookAtPlanet].position.clone();
var lookAtOffset = new THREE.Vector3(qmlView.xLookAtOffset,
qmlView.yLookAtOffset,
qmlView.zLookAtOffset);
cameraLookAt.add(lookAtOffset);
camera.lookAt(cameraLookAt);
// Render the scene
renderer.render(scene, camera);
}
function getOuterRadius( planet ) {
var outerRadius = solarDistance;
if (planet !== SOLAR_SYSTEM) {
outerRadius = planets[planet]["radius"];
if (planet === SATURN) {
outerRadius =+ saturnOuterRadius;
} else if (planet === URANUS) {
outerRadius =+ uranusOuterRadius;
} else if (planet === SUN) {
outerRadius = planets[planet]["radius"] / 100;
}
}
return outerRadius;
}