browser/devtools/tilt/TiltWorkerPicker.js

Wed, 31 Dec 2014 13:27:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 13:27:57 +0100
branch
TOR_BUG_3246
changeset 6
8bccb770b82d
permissions
-rw-r--r--

Ignore runtime configuration files generated during quality assurance.

     1 /* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set ts=2 et sw=2 tw=80: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 "use strict";
     8 /**
     9  * This worker handles picking, given a set of vertices and a ray (calculates
    10  * the intersection points and offers back information about the closest hit).
    11  *
    12  * Used in the TiltVisualization.Presenter object.
    13  */
    14 self.onmessage = function TWP_onMessage(event)
    15 {
    16   let data = event.data;
    17   let vertices = data.vertices;
    18   let ray = data.ray;
    20   let intersection = null;
    21   let hit = [];
    23   // calculates the squared distance between two points
    24   function dsq(p1, p2) {
    25     let xd = p2[0] - p1[0];
    26     let yd = p2[1] - p1[1];
    27     let zd = p2[2] - p1[2];
    29     return xd * xd + yd * yd + zd * zd;
    30   }
    32   // check each stack face in the visualization mesh for intersections with
    33   // the mouse ray (using a ray picking algorithm)
    34   for (let i = 0, len = vertices.length; i < len; i += 36) {
    36     // the front quad
    37     let v0f = [vertices[i],      vertices[i + 1],  vertices[i + 2]];
    38     let v1f = [vertices[i + 3],  vertices[i + 4],  vertices[i + 5]];
    39     let v2f = [vertices[i + 6],  vertices[i + 7],  vertices[i + 8]];
    40     let v3f = [vertices[i + 9],  vertices[i + 10], vertices[i + 11]];
    42     // the back quad
    43     let v0b = [vertices[i + 24], vertices[i + 25], vertices[i + 26]];
    44     let v1b = [vertices[i + 27], vertices[i + 28], vertices[i + 29]];
    45     let v2b = [vertices[i + 30], vertices[i + 31], vertices[i + 32]];
    46     let v3b = [vertices[i + 33], vertices[i + 34], vertices[i + 35]];
    48     // don't do anything with degenerate quads
    49     if (!v0f[0] && !v1f[0] && !v2f[0] && !v3f[0]) {
    50       continue;
    51     }
    53     // for each triangle in the stack box, check for the intersections
    54     if (self.intersect(v0f, v1f, v2f, ray, hit) || // front left
    55         self.intersect(v0f, v2f, v3f, ray, hit) || // front right
    56         self.intersect(v0b, v1b, v1f, ray, hit) || // left back
    57         self.intersect(v0b, v1f, v0f, ray, hit) || // left front
    58         self.intersect(v3f, v2b, v3b, ray, hit) || // right back
    59         self.intersect(v3f, v2f, v2b, ray, hit) || // right front
    60         self.intersect(v0b, v0f, v3f, ray, hit) || // top left
    61         self.intersect(v0b, v3f, v3b, ray, hit) || // top right
    62         self.intersect(v1f, v1b, v2b, ray, hit) || // bottom left
    63         self.intersect(v1f, v2b, v2f, ray, hit)) { // bottom right
    65       // calculate the distance between the intersection hit point and camera
    66       let d = dsq(hit, ray.origin);
    68       // we're picking the closest stack in the mesh from the camera
    69       if (intersection === null || d < intersection.distance) {
    70         intersection = {
    71           // each mesh stack is composed of 12 vertices, so there's information
    72           // about a node once in 12 * 3 = 36 iterations (to avoid duplication)
    73           index: i / 36,
    74           distance: d
    75         };
    76       }
    77     }
    78   }
    80   self.postMessage(intersection);
    81   close();
    82 };
    84 /**
    85  * Utility function for finding intersections between a ray and a triangle.
    86  */
    87 self.intersect = (function() {
    89   // creates a new instance of a vector
    90   function create() {
    91     return new Float32Array(3);
    92   }
    94   // performs a vector addition
    95   function add(aVec, aVec2, aDest) {
    96     aDest[0] = aVec[0] + aVec2[0];
    97     aDest[1] = aVec[1] + aVec2[1];
    98     aDest[2] = aVec[2] + aVec2[2];
    99     return aDest;
   100   }
   102   // performs a vector subtraction
   103   function subtract(aVec, aVec2, aDest) {
   104     aDest[0] = aVec[0] - aVec2[0];
   105     aDest[1] = aVec[1] - aVec2[1];
   106     aDest[2] = aVec[2] - aVec2[2];
   107     return aDest;
   108   }
   110   // performs a vector scaling
   111   function scale(aVec, aVal, aDest) {
   112     aDest[0] = aVec[0] * aVal;
   113     aDest[1] = aVec[1] * aVal;
   114     aDest[2] = aVec[2] * aVal;
   115     return aDest;
   116   }
   118   // generates the cross product of two vectors
   119   function cross(aVec, aVec2, aDest) {
   120     let x = aVec[0];
   121     let y = aVec[1];
   122     let z = aVec[2];
   123     let x2 = aVec2[0];
   124     let y2 = aVec2[1];
   125     let z2 = aVec2[2];
   127     aDest[0] = y * z2 - z * y2;
   128     aDest[1] = z * x2 - x * z2;
   129     aDest[2] = x * y2 - y * x2;
   130     return aDest;
   131   }
   133   // calculates the dot product of two vectors
   134   function dot(aVec, aVec2) {
   135     return aVec[0] * aVec2[0] + aVec[1] * aVec2[1] + aVec[2] * aVec2[2];
   136   }
   138   let edge1 = create();
   139   let edge2 = create();
   140   let pvec = create();
   141   let tvec = create();
   142   let qvec = create();
   143   let lvec = create();
   145   // checks for ray-triangle intersections using the Fast Minimum-Storage
   146   // (simplified) algorithm by Tomas Moller and Ben Trumbore
   147   return function intersect(aVert0, aVert1, aVert2, aRay, aDest) {
   148     let dir = aRay.direction;
   149     let orig = aRay.origin;
   151     // find vectors for two edges sharing vert0
   152     subtract(aVert1, aVert0, edge1);
   153     subtract(aVert2, aVert0, edge2);
   155     // begin calculating determinant - also used to calculate the U parameter
   156     cross(dir, edge2, pvec);
   158     // if determinant is near zero, ray lines in plane of triangle
   159     let inv_det = 1 / dot(edge1, pvec);
   161     // calculate distance from vert0 to ray origin
   162     subtract(orig, aVert0, tvec);
   164     // calculate U parameter and test bounds
   165     let u = dot(tvec, pvec) * inv_det;
   166     if (u < 0 || u > 1) {
   167       return false;
   168     }
   170     // prepare to test V parameter
   171     cross(tvec, edge1, qvec);
   173     // calculate V parameter and test bounds
   174     let v = dot(dir, qvec) * inv_det;
   175     if (v < 0 || u + v > 1) {
   176       return false;
   177     }
   179     // calculate T, ray intersects triangle
   180     let t = dot(edge2, qvec) * inv_det;
   182     scale(dir, t, lvec);
   183     add(orig, lvec, aDest);
   184     return true;
   185   };
   186 }());

mercurial