Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
fix(Rendering): device coordinates and physical coordinates
The old code only worked for one set of physical coordinates.

The new code should handle physical coordinates correctly.
  • Loading branch information
Ken Martin committed Mar 22, 2018
1 parent e256858 commit 5c2d3b9
Showing 1 changed file with 48 additions and 29 deletions.
77 changes: 48 additions & 29 deletions Sources/Rendering/Core/Camera/index.js
@@ -1,4 +1,4 @@
import { quat, vec3, vec4, mat3, mat4 } from 'gl-matrix';
import { quat, vec3, vec4, mat4 } from 'gl-matrix';

import macro from 'vtk.js/Sources/macro';
import vtkMath from 'vtk.js/Sources/Common/Core/Math';
Expand Down Expand Up @@ -586,39 +586,58 @@ function vtkCamera(publicAPI, model) {
// device orientation such that the physicalViewUp you set
// in world coordinates looks up, and the physicalViewNorth
// you set in world coorindates will (maybe) point north
//
// NOTE WARNING - much of the documentaiton out there on how
// orientation works is seriously wrong. Even worse the Chrome
// device orientation simulator is completely wrong and should
// never be used. OMG it is so messed up.
//
// how it seems to work on iOS is that the device orientation
// is specified in extrinsic angles with a alpha, beta, gamma
// convention with axes of Z, X, Y (the code below substitutes
// the physical coordinate system for these axes to get the right
// modified coordinate system.
publicAPI.setDeviceAngles = (alpha, beta, gamma, screen) => {
const physVRight = [3];
vtkMath.cross(model.physicalViewNorth, model.physicalViewUp, physVRight);

const rotmat = mat4.create(); // phone to physical coordinates
mat4.rotateZ(rotmat, rotmat, vtkMath.radiansFromDegrees(alpha));
mat4.rotateX(rotmat, rotmat, vtkMath.radiansFromDegrees(beta));
mat4.rotateY(rotmat, rotmat, vtkMath.radiansFromDegrees(gamma));
mat4.rotateZ(rotmat, rotmat, vtkMath.radiansFromDegrees(-screen));
mat4.rotate(
rotmat,
rotmat,
vtkMath.radiansFromDegrees(alpha),
model.physicalViewUp
);
mat4.rotate(rotmat, rotmat, vtkMath.radiansFromDegrees(beta), physVRight);
mat4.rotate(
rotmat,
rotmat,
vtkMath.radiansFromDegrees(gamma),
model.physicalViewNorth
);

const dop = vec3.fromValues(0.0, 0.0, -1.0);
const vup = vec3.fromValues(0.0, 1.0, 0.0);
const newdop = vec3.create();
const newvup = vec3.create();
vec3.transformMat4(newdop, dop, rotmat);
vec3.transformMat4(newvup, vup, rotmat);
mat4.rotate(
rotmat,
rotmat,
vtkMath.radiansFromDegrees(-screen),
model.physicalViewUp
);

// now the physical to vtk world tform
const physVRight = [3];
vtkMath.cross(model.physicalViewNorth, model.physicalViewUp, physVRight);
const phystoworld = mat3.create();
phystoworld[0] = physVRight[0];
phystoworld[1] = physVRight[1];
phystoworld[2] = physVRight[2];
phystoworld[3] = model.physicalViewNorth[0];
phystoworld[4] = model.physicalViewNorth[1];
phystoworld[5] = model.physicalViewNorth[2];
phystoworld[6] = model.physicalViewUp[0];
phystoworld[7] = model.physicalViewUp[1];
phystoworld[8] = model.physicalViewUp[2];
mat3.transpose(phystoworld, phystoworld);
vec3.transformMat3(newdop, newdop, phystoworld);
vec3.transformMat3(newvup, newvup, phystoworld);
const dop = vec3.fromValues(
-model.physicalViewUp[0],
-model.physicalViewUp[1],
-model.physicalViewUp[2]
);
const vup = vec3.fromValues(
model.physicalViewNorth[0],
model.physicalViewNorth[1],
model.physicalViewNorth[2]
);
vec3.transformMat4(dop, dop, rotmat);
vec3.transformMat4(vup, vup, rotmat);

publicAPI.setDirectionOfProjection(newdop[0], newdop[1], newdop[2]);
publicAPI.setViewUp(newvup[0], newvup[1], newvup[2]);
publicAPI.setDirectionOfProjection(dop[0], dop[1], dop[2]);
publicAPI.setViewUp(vup[0], vup[1], vup[2]);
publicAPI.modified();
};

Expand Down

0 comments on commit 5c2d3b9

Please sign in to comment.