Browse Source

Make horizon pitch and roll configurable instead of only support through metadata.

pull/189/head
Matthew Petroff 8 years ago
parent
commit
234201ea41
3 changed files with 61 additions and 43 deletions
  1. +10
    -0
      doc/json-config-parameters.md
  2. +40
    -39
      src/js/libpannellum.js
  3. +11
    -4
      src/js/pannellum.js

+ 10
- 0
doc/json-config-parameters.md View File

@@ -134,6 +134,16 @@ affects the compass, it only has an effect if `compass` is set to `true`.
Specifies a URL for a preview image to display before the panorama is loaded.


### `horizonPitch`

Specifies pitch of image horizon (for correcting non-leveled panoramas).


### `horizonRoll`

Specifies roll of image horizon (for correcting non-leveled panoramas).


### `hotSpots`

This specifies an array of hot spots that can be links to other scenes,


+ 40
- 39
src/js/libpannellum.js View File

@@ -59,8 +59,9 @@ function Renderer(container) {
* @param {number} vaov - Initial vertical angle of view.
* @param {number} voffset - Initial vertical offset angle.
* @param {function} callback - Load callback function.
* @param {Object} [params] - Other configuration parameters (`horizonPitch`, `horizonRoll`).
*/
this.init = function(_image, _imageType, _dynamic, haov, vaov, voffset, callback) {
this.init = function(_image, _imageType, _dynamic, haov, vaov, voffset, callback, params) {
// Default argument for image type
if (typeof _imageType === undefined)
_imageType = 'equirectangular';
@@ -249,9 +250,9 @@ function Renderer(container) {
}

// Store horizon pitch and roll if applicable
if (image.horizonPitch !== undefined && image.horizonRoll !== undefined) {
pose = [image.horizonPitch, image.horizonRoll];
}
if (params !== undefined && (params.horizonPitch !== undefined || params.horizonRoll !== undefined))
pose = [params.horizonPitch == undefined ? 0 : params.horizonPitch,
params.horizonRoll == undefined ? 0 : params.horizonRoll];

// Set 2d texture binding
var glBindType = gl.TEXTURE_2D;
@@ -447,7 +448,41 @@ function Renderer(container) {
params = {};
if (params.roll)
roll = params.roll;

// Apply pitch and roll transformation if applicable
if (pose !== undefined) {
var horizonPitch = pose[0],
horizonRoll = pose[1];

// Calculate new pitch and yaw
var orig_pitch = pitch,
orig_yaw = yaw,
x = Math.cos(horizonRoll) * Math.sin(pitch) * Math.sin(horizonPitch) +
Math.cos(pitch) * (Math.cos(horizonPitch) * Math.cos(yaw) +
Math.sin(horizonRoll) * Math.sin(horizonPitch) * Math.sin(yaw)),
y = -Math.sin(pitch) * Math.sin(horizonRoll) +
Math.cos(pitch) * Math.cos(horizonRoll) * Math.sin(yaw),
z = Math.cos(horizonRoll) * Math.cos(horizonPitch) * Math.sin(pitch) +
Math.cos(pitch) * (-Math.cos(yaw) * Math.sin(horizonPitch) +
Math.cos(horizonPitch) * Math.sin(horizonRoll) * Math.sin(yaw));
pitch = Math.asin(Math.max(Math.min(z, 1), -1));
yaw = Math.atan2(y, x);

// Calculate roll
var v = [Math.cos(orig_pitch) * (Math.sin(horizonRoll) * Math.sin(horizonPitch) * Math.cos(orig_yaw) -
Math.cos(horizonPitch) * Math.sin(orig_yaw)),
Math.cos(orig_pitch) * Math.cos(horizonRoll) * Math.cos(orig_yaw),
Math.cos(orig_pitch) * (Math.cos(horizonPitch) * Math.sin(horizonRoll) * Math.cos(orig_yaw) +
Math.sin(orig_yaw) * Math.sin(horizonPitch))],
w = [-Math.cos(pitch) * Math.sin(yaw), Math.cos(pitch) * Math.cos(yaw)];
var roll_adj = Math.acos(Math.max(Math.min((v[0]*w[0] + v[1]*w[1]) /
(Math.sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]) *
Math.sqrt(w[0]*w[0]+w[1]*w[1])), 1), -1));
if (v[2] < 0)
roll_adj = 2 * Math.PI - roll_adj;
roll += roll_adj;
}

// If no WebGL
if (!gl && (imageType == 'multires' || imageType == 'cubemap')) {
// Determine face transforms
@@ -480,40 +515,6 @@ function Renderer(container) {
var vfov = 2 * Math.atan(Math.tan(hfov * 0.5) / (canvas.width / canvas.height));
focal = 1 / Math.tan(vfov * 0.5);

// Apply pitch and roll transformation if applicable
if (imageType == 'equirectangular' && pose !== undefined) {
var horizonPitch = pose[0],
horizonRoll = pose[1];

// Calculate new pitch and yaw
var orig_pitch = pitch,
orig_yaw = yaw,
x = Math.cos(horizonRoll) * Math.sin(pitch) * Math.sin(horizonPitch) +
Math.cos(pitch) * (Math.cos(horizonPitch) * Math.cos(yaw) +
Math.sin(horizonRoll) * Math.sin(horizonPitch) * Math.sin(yaw)),
y = -Math.sin(pitch) * Math.sin(horizonRoll) +
Math.cos(pitch) * Math.cos(horizonRoll) * Math.sin(yaw),
z = Math.cos(horizonRoll) * Math.cos(horizonPitch) * Math.sin(pitch) +
Math.cos(pitch) * (-Math.cos(yaw) * Math.sin(horizonPitch) +
Math.cos(horizonPitch) * Math.sin(horizonRoll) * Math.sin(yaw));
pitch = Math.asin(Math.max(Math.min(z, 1), -1));
yaw = Math.atan2(y, x);

// Calculate roll
var v = [Math.cos(orig_pitch) * (Math.sin(horizonRoll) * Math.sin(horizonPitch) * Math.cos(orig_yaw) -
Math.cos(horizonPitch) * Math.sin(orig_yaw)),
Math.cos(orig_pitch) * Math.cos(horizonRoll) * Math.cos(orig_yaw),
Math.cos(orig_pitch) * (Math.cos(horizonPitch) * Math.sin(horizonRoll) * Math.cos(orig_yaw) +
Math.sin(orig_yaw) * Math.sin(horizonPitch))],
w = [-Math.cos(pitch) * Math.sin(yaw), Math.cos(pitch) * Math.cos(yaw)];
var roll_adj = Math.acos(Math.max(Math.min((v[0]*w[0] + v[1]*w[1]) /
(Math.sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]) *
Math.sqrt(w[0]*w[0]+w[1]*w[1])), 1), -1));
if (v[2] < 0)
roll_adj = 2 * Math.PI - roll_adj;
roll += roll_adj;
}

// Pass psi, theta, roll, and focal length
gl.uniform1f(program.psi, yaw);
gl.uniform1f(program.theta, pitch);


+ 11
- 4
src/js/pannellum.js View File

@@ -485,8 +485,10 @@ function parseGPanoXMP(image) {
}
}
if (xmp.horizonPitch !== null && xmp.horizonRoll !== null) {
panoImage.horizonPitch = xmp.horizonPitch / 180 * Math.PI;
panoImage.horizonRoll = xmp.horizonRoll / 180 * Math.PI;
if (specifiedPhotoSphereExcludes.indexOf('horizonPitch') < 0)
config.horizonPitch = xmp.horizonPitch / 180 * Math.PI;
if (specifiedPhotoSphereExcludes.indexOf('horizonRoll') < 0)
config.horizonRoll = xmp.horizonRoll / 180 * Math.PI;
}
// TODO: add support for initial view settings
@@ -1355,7 +1357,12 @@ function orientationListener(e) {
*/
function renderInit() {
try {
renderer.init(panoImage, config.type, config.dynamic, config.haov * Math.PI / 180, config.vaov * Math.PI / 180, config.vOffset * Math.PI / 180, renderInitCallback);
var params = {};
if (config.horizonPitch !== undefined)
params.horizonPitch = config.horizonPitch;
if (config.horizonRoll !== undefined)
params.horizonRoll = config.horizonRoll;
renderer.init(panoImage, config.type, config.dynamic, config.haov * Math.PI / 180, config.vaov * Math.PI / 180, config.vOffset * Math.PI / 180, renderInitCallback, params);
if (config.dynamic !== true) {
// Allow image to be garbage collected
panoImage = undefined;
@@ -1568,7 +1575,7 @@ function renderHotSpots() {
function mergeConfig(sceneId) {
config = {};
var k;
var photoSphereExcludes = ['haov', 'vaov', 'vOffset', 'northOffset'];
var photoSphereExcludes = ['haov', 'vaov', 'vOffset', 'northOffset', 'horizonPitch', 'horizonRoll'];
specifiedPhotoSphereExcludes = [];
// Merge default config


Loading…
Cancel
Save