Skip to content
This repository has been archived by the owner on Jul 29, 2019. It is now read-only.

Readied 3d camera orientation code for merge into develop branch #2357

Merged
merged 3 commits into from Nov 23, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
46 changes: 45 additions & 1 deletion lib/graph3d/Camera.js
Expand Up @@ -16,13 +16,45 @@ function Camera() {
this.armRotation.horizontal = 0;
this.armRotation.vertical = 0;
this.armLength = 1.7;
this.cameraOffset = new Point3d();
this.offsetMultiplier = 0.6;

this.cameraLocation = new Point3d();
this.cameraRotation = new Point3d(0.5*Math.PI, 0, 0);

this.calculateCameraOrientation();
}

/**
* Set offset camera in camera coordinates
* @param {Number} x offset by camera horisontal
* @param {Number} y offset by camera vertical
*/
Camera.prototype.setOffset = function(x, y) {
var abs = Math.abs,
sign = Math.sign,
mul = this.offsetMultiplier,
border = this.armLength * mul;

if (abs(x) > border) {
x = sign(x) * border;
}
if (abs(y) > border) {
y = sign(y) * border;
}
this.cameraOffset.x = x;
this.cameraOffset.y = y;
this.calculateCameraOrientation();
};

/**
* Get camera offset by horizontal and vertical
* @return {Point3d} x - horizontal offset, y - vertical offset, z - not used
*/
Camera.prototype.getOffset = function(x, y) {
return this.cameraOffset;
};

/**
* Set the location (origin) of the arm
* @param {Number} x Normalized value of x
Expand Down Expand Up @@ -89,6 +121,7 @@ Camera.prototype.setArmLength = function(length) {
if (this.armLength < 0.71) this.armLength = 0.71;
if (this.armLength > 5.0) this.armLength = 5.0;

this.setOffset(this.cameraOffset.x, this.cameraOffset.y);
this.calculateCameraOrientation();
};

Expand Down Expand Up @@ -130,6 +163,17 @@ Camera.prototype.calculateCameraOrientation = function() {
this.cameraRotation.x = Math.PI/2 - this.armRotation.vertical;
this.cameraRotation.y = 0;
this.cameraRotation.z = -this.armRotation.horizontal;

var xa = this.cameraRotation.x;
var ya = this.cameraRotation.y;
var za = this.cameraRotation.z;
var dx = this.cameraOffset.x;
var dy = this.cameraOffset.y;
var sin = Math.sin, cos = Math.cos;

this.cameraLocation.x = this.cameraLocation.x + dx * cos(za) + dy * - sin(za) * cos(xa);
this.cameraLocation.y = this.cameraLocation.y + dx * sin(za) + dy * cos(za) * cos(xa);
this.cameraLocation.z = this.cameraLocation.z + dy * sin(xa);
};

module.exports = Camera;
module.exports = Camera;
74 changes: 49 additions & 25 deletions lib/graph3d/Graph3d.js
Expand Up @@ -1888,6 +1888,19 @@ Graph3d.prototype._redrawDataGraph = function() {
// End methods for drawing points per graph style.
// -----------------------------------------------------------------------------

/**
* Store startX, startY and startOffset for mouse operations
*
* @param {Event} event The event that occurred
*/
Graph3d.prototype._storeMousePosition = function(event) {
// get mouse position (different code for IE and all other browsers)
this.startMouseX = getMouseX(event);
this.startMouseY = getMouseY(event);

this._startCameraOffset = this.camera.getOffset();
};


/**
* Start a moving operation inside the provided parent element
Expand All @@ -1907,9 +1920,7 @@ Graph3d.prototype._onMouseDown = function(event) {
this.leftButtonDown = event.which ? (event.which === 1) : (event.button === 1);
if (!this.leftButtonDown && !this.touchDown) return;

// get mouse position (different code for IE and all other browsers)
this.startMouseX = getMouseX(event);
this.startMouseY = getMouseY(event);
this._storeMousePosition(event);

this.startStart = new Date(this.start);
this.startEnd = new Date(this.end);
Expand Down Expand Up @@ -1940,31 +1951,44 @@ Graph3d.prototype._onMouseMove = function (event) {
// calculate change in mouse position
var diffX = parseFloat(getMouseX(event)) - this.startMouseX;
var diffY = parseFloat(getMouseY(event)) - this.startMouseY;

// move with ctrl or rotate by other
if (event && event.ctrlKey === true) {
// calculate change in mouse position
var scaleX = this.frame.clientWidth * 0.5;
var scaleY = this.frame.clientHeight * 0.5;

var offXNew = (this._startCameraOffset.x || 0) - ((diffX / scaleX) * this.camera.armLength) * 0.8;
var offYNew = (this._startCameraOffset.y || 0) + ((diffY / scaleY) * this.camera.armLength) * 0.8;

this.camera.setOffset(offXNew, offYNew);
this._storeMousePosition(event);
} else {
var horizontalNew = this.startArmRotation.horizontal + diffX / 200;
var verticalNew = this.startArmRotation.vertical + diffY / 200;

var snapAngle = 4; // degrees
var snapValue = Math.sin(snapAngle / 360 * 2 * Math.PI);

// snap horizontally to nice angles at 0pi, 0.5pi, 1pi, 1.5pi, etc...
// the -0.001 is to take care that the vertical axis is always drawn at the left front corner
if (Math.abs(Math.sin(horizontalNew)) < snapValue) {
horizontalNew = Math.round(horizontalNew / Math.PI) * Math.PI - 0.001;
}
if (Math.abs(Math.cos(horizontalNew)) < snapValue) {
horizontalNew = (Math.round(horizontalNew / Math.PI - 0.5) + 0.5) * Math.PI - 0.001;
}

var horizontalNew = this.startArmRotation.horizontal + diffX / 200;
var verticalNew = this.startArmRotation.vertical + diffY / 200;

var snapAngle = 4; // degrees
var snapValue = Math.sin(snapAngle / 360 * 2 * Math.PI);

// snap horizontally to nice angles at 0pi, 0.5pi, 1pi, 1.5pi, etc...
// the -0.001 is to take care that the vertical axis is always drawn at the left front corner
if (Math.abs(Math.sin(horizontalNew)) < snapValue) {
horizontalNew = Math.round((horizontalNew / Math.PI)) * Math.PI - 0.001;
}
if (Math.abs(Math.cos(horizontalNew)) < snapValue) {
horizontalNew = (Math.round((horizontalNew/ Math.PI - 0.5)) + 0.5) * Math.PI - 0.001;
}

// snap vertically to nice angles
if (Math.abs(Math.sin(verticalNew)) < snapValue) {
verticalNew = Math.round((verticalNew / Math.PI)) * Math.PI;
}
if (Math.abs(Math.cos(verticalNew)) < snapValue) {
verticalNew = (Math.round((verticalNew/ Math.PI - 0.5)) + 0.5) * Math.PI;
// snap vertically to nice angles
if (Math.abs(Math.sin(verticalNew)) < snapValue) {
verticalNew = Math.round(verticalNew / Math.PI) * Math.PI;
}
if (Math.abs(Math.cos(verticalNew)) < snapValue) {
verticalNew = (Math.round(verticalNew / Math.PI - 0.5) + 0.5) * Math.PI;
}
this.camera.setArmRotation(horizontalNew, verticalNew);
}

this.camera.setArmRotation(horizontalNew, verticalNew);
this.redraw();

// fire a cameraPositionChange event
Expand Down