Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Js fixes #286

Closed
wants to merge 5 commits into from
Closed
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
130 changes: 73 additions & 57 deletions res/threejs/SolveSpaceControls.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/*global THREE Hammer SolvespaceCamera:true SolvespaceControls:true
solvespace:true */

window.devicePixelRatio = window.devicePixelRatio || 1;

SolvespaceCamera = function(renderWidth, renderHeight, scale, up, right, offset) {
Expand All @@ -7,7 +10,7 @@ SolvespaceCamera = function(renderWidth, renderHeight, scale, up, right, offset)

this.renderWidth = renderWidth;
this.renderHeight = renderHeight;
this.zoomScale = scale; /* Avoid namespace collision w/ THREE.Object.scale */
this.zoomScale = scale; // Avoid namespace collision w/ THREE.Object.scale
this.up = up;
this.right = right;
this.offset = offset;
Expand All @@ -25,10 +28,11 @@ SolvespaceCamera.prototype.updateProjectionMatrix = function() {
var n = new THREE.Vector3().crossVectors(this.up, this.right);
var rotate = new THREE.Matrix4().makeBasis(this.right, this.up, n);
rotate.transpose();
/* FIXME: At some point we ended up using row-major.
THREE.js wants column major. Scale/depth correct unaffected b/c diagonal
matrices remain the same when transposed. makeTranslation also makes
a column-major matrix. */
/* Transpose of rotation matrix == inverse. Rotating the camera by a
basis is equivalent to rotating an object by the inverse of the
basis. To mimic Solvespace's behavior, we pan relative to the camera.
So we need to be rotated to where the camera is pointing before panning.
See: https://en.wikipedia.org/wiki/Change_of_basis#Two_dimensions */

/* TODO: If we want perspective, we need an additional matrix
here which will modify w for perspective divide. */
Expand Down Expand Up @@ -58,14 +62,14 @@ SolvespaceCamera.prototype.rotate = function(right, up) {
this.up.applyAxisAngle(oldRight, up);
this.right.applyAxisAngle(oldUp, right);
this.NormalizeProjectionVectors();
}
};

SolvespaceCamera.prototype.offsetProj = function(right, up) {
var shift = new THREE.Vector3(right * this.right.x + up * this.up.x,
right * this.right.y + up * this.up.y,
right * this.right.z + up * this.up.z);
this.offset.add(shift);
}
};

/* Calculate the offset in terms of up and right projection vectors
that will preserve the world coordinates of the current mouse position after
Expand All @@ -86,7 +90,7 @@ SolvespaceCamera.prototype.zoomTo = function(x, y, delta) {
zoomFactor = (-delta * 0.002 + 1);
}
else if(delta > 0) {
zoomFactor = (delta * (-1.0/600.0) + 1)
zoomFactor = (delta * (-1.0/600.0) + 1);
}
else {
return;
Expand All @@ -98,7 +102,7 @@ SolvespaceCamera.prototype.zoomTo = function(x, y, delta) {

this.offset.addScaledVector(this.right, centerRightF - centerRightI);
this.offset.addScaledVector(this.up, centerUpF - centerUpI);
}
};


SolvespaceControls = function(object, domElement) {
Expand All @@ -123,15 +127,16 @@ SolvespaceControls = function(object, domElement) {
var changeEvent = {
type: 'change'
};
/* eslint-disable no-unused-vars */
var startEvent = {
type: 'start'
};
/* eslint-enable no-unused-vars */
var endEvent = {
type: 'end'
};

var _changed = false;
var _mouseMoved = false;
//var _touchPoints = new Array();
var _offsetPrev = new THREE.Vector2(0, 0);
var _offsetCur = new THREE.Vector2(0, 0);
Expand All @@ -147,25 +152,25 @@ SolvespaceControls = function(object, domElement) {
if (typeof this[event.type] == 'function') {
this[event.type](event);
}
}
};

function mousedown(event) {
event.preventDefault();
event.stopPropagation();

switch (event.button) {
case 0:
_rotateCur.set(event.screenX / window.devicePixelRatio,
event.screenY / window.devicePixelRatio);
_rotateCur.set(event.screenX,
event.screenY);
_rotatePrev.copy(_rotateCur);
document.addEventListener('mousemove', mousemove, false);
document.addEventListener('mousemove', mousemove_rotate, false);
document.addEventListener('mouseup', mouseup, false);
break;
case 2:
_offsetCur.set(event.screenX / window.devicePixelRatio,
event.screenY / window.devicePixelRatio);
_offsetPrev.copy(_offsetCur);
document.addEventListener('mousemove', mousemove, false);
document.addEventListener('mousemove', mousemove_pan, false);
document.addEventListener('mouseup', mouseup, false);
break;
default:
Expand All @@ -183,31 +188,26 @@ SolvespaceControls = function(object, domElement) {
_changed = true;
}

function mousemove(event) {
switch (event.button) {
case 0:
_rotateCur.set(event.screenX / window.devicePixelRatio,
event.screenY / window.devicePixelRatio);
var diff = new THREE.Vector2().subVectors(_rotateCur, _rotatePrev)
.multiplyScalar(1 / object.zoomScale);
object.rotate(-0.3 * Math.PI / 180 * diff.x * object.zoomScale,
-0.3 * Math.PI / 180 * diff.y * object.zoomScale);
_changed = true;
_rotatePrev.copy(_rotateCur);
break;
case 2:
_mouseMoved = true;
_offsetCur.set(event.screenX / window.devicePixelRatio,
event.screenY / window.devicePixelRatio);
var diff = new THREE.Vector2().subVectors(_offsetCur, _offsetPrev)
.multiplyScalar(1 / object.zoomScale);
object.offsetProj(diff.x, -diff.y);
_changed = true;
_offsetPrev.copy(_offsetCur)
break;
}
function mousemove_rotate(event) {
_rotateCur.set(event.screenX,
event.screenY);
var diff = new THREE.Vector2().subVectors(_rotateCur, _rotatePrev)
.multiplyScalar(1 / object.zoomScale);
object.rotate(-0.3 * Math.PI / 180 * diff.x * object.zoomScale,
-0.3 * Math.PI / 180 * diff.y * object.zoomScale);
_changed = true;
_rotatePrev.copy(_rotateCur);
}

function mousemove_pan(event) {
_offsetCur.set(event.screenX / window.devicePixelRatio,
event.screenY / window.devicePixelRatio);
var diff = new THREE.Vector2().subVectors(_offsetCur, _offsetPrev)
.multiplyScalar(window.devicePixelRatio / object.zoomScale);
object.offsetProj(diff.x, -diff.y);
_changed = true;
_offsetPrev.copy(_offsetCur);
}

function mouseup(event) {
/* TODO: Opera mouse gestures will intercept this event, making it
Expand All @@ -217,29 +217,39 @@ SolvespaceControls = function(object, domElement) {
event.preventDefault();
event.stopPropagation();

document.removeEventListener('mousemove', mousemove);
document.removeEventListener('mouseup', mouseup);
switch (event.button) {
case 0:
document.removeEventListener('mousemove', mousemove_rotate);
document.removeEventListener('mouseup', mouseup);
break;
case 2:
document.removeEventListener('mousemove', mousemove_pan);
document.removeEventListener('mouseup', mouseup);
break;
}

_this.dispatchEvent(endEvent);
}

function pan(event) {
/* neWcur - prev does not necessarily equal (cur + diff) - prev.
Floating point is not associative. */
touchDiff = new THREE.Vector2(event.deltaX, event.deltaY);
var touchDiff = new THREE.Vector2(event.deltaX, event.deltaY);
_rotateCur.addVectors(_rotateOrig, touchDiff);
incDiff = new THREE.Vector2().subVectors(_rotateCur, _rotatePrev)
var incDiff = new THREE.Vector2().subVectors(_rotateCur, _rotatePrev)
.multiplyScalar(1 / object.zoomScale);
object.rotate(-0.3 * Math.PI / 180 * incDiff.x * object.zoomScale,
-0.3 * Math.PI / 180 * incDiff.y * object.zoomScale);
_changed = true;
_rotatePrev.copy(_rotateCur);
}

/* eslint-disable no-unused-vars */
function panstart(event) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be replaced with e.g. function panstart(_event) { ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You would think this would be simple, and eslint has an argsIgnorePattern option, but it doesn't work for functions only taking one argument.

The correct way to handle this case is create a custom rule. This implies creating a plugin, which is a node package, and also supplying my .eslintrc (which I prob should supply anyway in the repo, since the linter requires it). I don't actually have node installed atm tho- eslint is provided through atom. So, it's a bit of work :(.

Even as-is, I can reduce the scope of the lint disables by doing the following for each event handler:

    /* eslint-disable no-unused-vars */
    function panstart(_event) {
    /* eslint-enable no-unused-vars */
        /* TODO: Dynamically enable pan function? */
        _rotateOrig.copy(_rotateCur);
    }

/* TODO: Dynamically enable pan function? */
_rotateOrig.copy(_rotateCur);
}
/* eslint-enable no-unused-vars */

function pinchstart(event) {
_prevScale = event.scale;
Expand All @@ -265,29 +275,35 @@ SolvespaceControls = function(object, domElement) {
}

/* A tap will enable panning/disable rotate. */
/* eslint-disable no-unused-vars */
function tap(event) {
panAfterTap.set({enable : true});
_this.touchControls.get('pan').set({enable : false});
}
/* eslint-enable no-unused-vars */

function panaftertap(event) {
touchDiff = new THREE.Vector2(event.deltaX, event.deltaY);
var touchDiff = new THREE.Vector2(event.deltaX, event.deltaY);
_offsetCur.addVectors(_offsetOrig, touchDiff);
incDiff = new THREE.Vector2().subVectors(_offsetCur, _offsetPrev)
var incDiff = new THREE.Vector2().subVectors(_offsetCur, _offsetPrev)
.multiplyScalar(1 / object.zoomScale);
object.offsetProj(incDiff.x, -incDiff.y);
_changed = true;
_offsetPrev.copy(_offsetCur);
}

/* eslint-disable no-unused-vars */
function panaftertapstart(event) {
_offsetOrig.copy(_offsetCur);
}
/* eslint-enable no-unused-vars */

/* eslint-disable no-unused-vars */
function panaftertapend(event) {
panAfterTap.set({enable : false});
_this.touchControls.get('pan').set({enable : true});
}
/* eslint-enable no-unused-vars */

function contextmenu(event) {
event.preventDefault();
Expand All @@ -298,13 +314,13 @@ SolvespaceControls = function(object, domElement) {
_this.dispatchEvent(changeEvent);
_changed = false;
}
}
};

this.domElement.addEventListener('mousedown', mousedown, false);
this.domElement.addEventListener('wheel', wheel, false);
this.domElement.addEventListener('contextmenu', contextmenu, false);

/* Hammer.on wraps addEventListener */
// Hammer.on wraps addEventListener
// Rotate
this.touchControls.on('pan', pan);
this.touchControls.on('panstart', panstart);
Expand All @@ -318,15 +334,14 @@ SolvespaceControls = function(object, domElement) {
this.touchControls.on('panaftertapstart', panaftertapstart);
this.touchControls.on('panaftertap', panaftertap);
this.touchControls.on('panaftertapend', panaftertapend);
}
};

SolvespaceControls.prototype = Object.create(THREE.EventDispatcher.prototype);
SolvespaceControls.prototype.constructor = SolvespaceControls;


/* eslint no-unused-vars: [2, { "vars": "local" }] */
solvespace = function(obj, params) {
var scene, edgeScene, camera, edgeCamera, renderer;
var geometry, controls, material, mesh, edges;
var scene, edgeScene, camera, renderer, controls, mesh, edges;
var width, height, scale, offset, projRight, projUp;
var directionalLightArray = [];

Expand Down Expand Up @@ -366,7 +381,7 @@ solvespace = function(obj, params) {
projRight = params.projRight;
}

domElement = init();
var domElement = init();
lightUpdate();
render();
return domElement;
Expand Down Expand Up @@ -394,7 +409,7 @@ solvespace = function(obj, params) {
scene.add(directionalLight);
}

var lightColor = new THREE.Color(obj.lights.a, obj.lights.a, obj.lights.a);
lightColor = new THREE.Color(obj.lights.a, obj.lights.a, obj.lights.a);
var ambientLight = new THREE.AmbientLight(lightColor.getHex());
scene.add(ambientLight);

Expand Down Expand Up @@ -433,10 +448,10 @@ solvespace = function(obj, params) {
function lightUpdate() {
var changeBasis = new THREE.Matrix4();

// The original light positions were in camera space.
// Project them into standard space using camera's basis
// vectors (up, target, and their cross product).
n = new THREE.Vector3().crossVectors(camera.up, camera.right);
/* The original light positions were in camera space.
Project them into standard space using camera's basis
vectors (up, target, and their cross product). */
var n = new THREE.Vector3().crossVectors(camera.up, camera.right);
changeBasis.makeBasis(camera.right, camera.up, n);

for (var i = 0; i < 2; i++) {
Expand All @@ -459,7 +474,7 @@ solvespace = function(obj, params) {
meshObj.points[i][1], meshObj.points[i][2]));
}

for (var i = 0; i < meshObj.faces.length; i++) {
for (i = 0; i < meshObj.faces.length; i++) {
var currOpacity = ((meshObj.colors[i] & 0xFF000000) >>> 24) / 255.0;
if (opacitiesSeen[currOpacity] === undefined) {
opacitiesSeen[currOpacity] = materialIndex;
Expand Down Expand Up @@ -503,3 +518,4 @@ solvespace = function(obj, params) {
return new THREE.LineSegments(geometry, material);
}
};