browser/devtools/tilt/TiltWorkerPicker.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial