Skip to content

Commit

Permalink
basic observer motion #2
Browse files Browse the repository at this point in the history
  • Loading branch information
oseiskar committed Dec 31, 2015
1 parent d0923ab commit 67d4e6b
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 25 deletions.
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
<script src="js-libs/ShaderLoader.min.js"></script>
<script src="js-libs/mustache.min.js"></script>
<script src="js-libs/dat.gui.min.js"></script>
<script src="three-js-monkey-patch.js"></script>

<script id="vertex-shader" type="x-shader/x-vertex">

Expand Down
108 changes: 83 additions & 25 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,63 @@

if ( ! Detector.webgl ) Detector.addGetWebGLMessage();


function Observer() {
this.position = new THREE.Vector3(1,0,0);
this.position = new THREE.Vector3(10,0,0);
this.velocity = new THREE.Vector3(0,1,0);
this.orientation = new THREE.Matrix3();
this.time = 0.0;
}

Observer.prototype.orbitalFrame = function() {
var orbital_y = observer.velocity.clone().normalize();
var orbital_z = (new THREE.Vector3())
.crossVectors(orbital_y, observer.position).normalize();
var orbital_x = (new THREE.Vector3()).crossVectors(orbital_y, orbital_z);

return (new THREE.Matrix4()).makeBasis(
orbital_x,
orbital_y,
orbital_z
).linearPart();
};

Observer.prototype.move = function(dt) {

dt *= shader.parameters.time_scale;

var r;
var v = 0;

// motion on a pre-defined cirular orbit
if (shader.parameters.observer_motion) {

r = shader.parameters.observer_distance;
v = 1.0 / Math.sqrt(2.0*(r-1.0));
var ang_vel = v / r;
var angle = -this.time * ang_vel;

var s = Math.sin(angle), c = Math.cos(angle);

this.position.set(c*r, s*r, 0);
this.velocity.set(-s*v, c*v, 0);

var alpha = degToRad(shader.parameters.observer_orbital_inclination);
var orbit_coords = (new THREE.Matrix4()).makeRotationY(alpha);

this.position.applyMatrix4(orbit_coords);
this.velocity.applyMatrix4(orbit_coords);
}
else {
r = this.position.length();
}

if (shader.parameters.gravitational_time_dilation) {
dt = Math.sqrt((dt*dt * (1.0 - v*v)) / (1-1.0/r));
}

this.time += dt;
};

var container, stats;
var camera, scene, renderer, cameraControls, shader = null;
var observer = new Observer();
Expand All @@ -28,7 +77,8 @@ function Shader(mustacheTemplate) {
light_travel_time: true,
time_scale: 1.0,
observer_motion: true,
observer_distance: 15.0
observer_distance: 15.0,
observer_orbital_inclination: 10
};
var that = this;
this.needsUpdate = false;
Expand Down Expand Up @@ -185,7 +235,9 @@ function setupGUI() {
var gui = new dat.GUI();
gui.add(shader.parameters, 'accretion_disk').onChange(updateShader);

gui.add(shader.parameters, 'observer_motion').onChange(updateShader);
gui.add(shader.parameters, 'observer_motion').onChange(updateCamera);
gui.add(shader.parameters, 'observer_distance').min(1.1).max(30)
.onChange(updateCamera);

gui.add(shader.parameters, 'planet').onChange(updateShader);
gui.add(shader.parameters, 'planet_distance').min(1.5).onChange(updateUniforms);
Expand All @@ -204,8 +256,7 @@ function onWindowResize( event ) {

function initializeCamera(camera) {

var pitchAngle = 10.0, yawAngle = 115.0;
var dist = 20.0;
var pitchAngle = 10.0, yawAngle = 100.0;

// there are nicely named methods such as "lookAt" in the camera object
// but there do not do a thing to the projection matrix due to an internal
Expand All @@ -215,31 +266,45 @@ function initializeCamera(camera) {

var m = camera.matrixWorldInverse.elements;

camera.position.set(m[2]*dist, m[6]*dist, m[10]*dist);
camera.position.set(m[2], m[6], m[10]);
}

function updateCamera( event ) {

var dist = camera.position.length();
var zoom_dist = camera.position.length();
var m = camera.matrixWorldInverse.elements;
var camera_matrix;

if (shader.parameters.observer_motion) {
camera_matrix = new THREE.Matrix3();
}
else {
camera_matrix = observer.orientation;
}

// y and z swapped for a nicer coordinate system
var camera_matrix = new THREE.Matrix3();
camera_matrix.set(
// row-major, not the same as .elements (nice)
// y and z swapped for a nicer coordinate system
m[0], m[1], m[2],
m[8], m[9], m[10],
m[4], m[5], m[6]
);

observer.orientation = camera_matrix;
if (shader.parameters.observer_motion) {

observer.orientation = observer.orbitalFrame().multiply(camera_matrix);

var p = new THREE.Vector3(
camera_matrix.elements[6],
camera_matrix.elements[7],
camera_matrix.elements[8]);
} else {

observer.position.set(-p.x*dist, -p.y*dist, -p.z*dist);
var p = new THREE.Vector3(
camera_matrix.elements[6],
camera_matrix.elements[7],
camera_matrix.elements[8]);

var dist = shader.parameters.observer_distance;
observer.position.set(-p.x*dist, -p.y*dist, -p.z*dist);
observer.velocity.set(0,0,0);
}
}

function frobeniusDistance(matrix1, matrix2) {
Expand Down Expand Up @@ -280,15 +345,8 @@ var getFrameDuration = (function() {
})();

function render() {

var dt = getFrameDuration() * shader.parameters.time_scale;

if (shader.parameters.gravitational_time_dilation) {
var observer_r = camera.position.length();
dt = dt * 1.0 / Math.sqrt(1-1.0/observer_r);
}

observer.time += dt;
observer.move(getFrameDuration());
if (shader.parameters.observer_motion) updateCamera();
updateUniforms();
renderer.render( scene, camera );
}
28 changes: 28 additions & 0 deletions three-js-monkey-patch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* why is this not there in the first place :( */
THREE.Matrix3.prototype.multiply = function(another_matrix) {
var b = another_matrix.elements;
var a = this.elements;
this.set(
a[0]*b[0] + a[3]*b[1] + a[6]*b[2],
a[0]*b[3] + a[3]*b[4] + a[6]*b[5],
a[0]*b[6] + a[3]*b[7] + a[6]*b[8],
a[1]*b[0] + a[4]*b[1] + a[7]*b[2],
a[1]*b[3] + a[4]*b[4] + a[7]*b[5],
a[1]*b[6] + a[4]*b[7] + a[7]*b[8],
a[2]*b[0] + a[5]*b[1] + a[8]*b[2],
a[2]*b[3] + a[5]*b[4] + a[8]*b[5],
a[2]*b[6] + a[5]*b[7] + a[8]*b[8]
);
return this;
};

THREE.Matrix4.prototype.linearPart = function() {
var m = new THREE.Matrix3();
var te = this.elements;
m.set(
te[0], te[1], te[2],
te[4], te[5], te[6],
te[8], te[9], te[10]
);
return m;
};

0 comments on commit 67d4e6b

Please sign in to comment.