browser/devtools/tilt/TiltWorkerCrafter.js

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:820339f6d438
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";
7
8 /**
9 * Given the initialization data (sizes and information about
10 * each DOM node) this worker sends back the arrays representing
11 * vertices, texture coords, colors, indices and all the needed data for
12 * rendering the DOM visualization mesh.
13 *
14 * Used in the TiltVisualization.Presenter object.
15 */
16 self.onmessage = function TWC_onMessage(event)
17 {
18 let data = event.data;
19 let maxGroupNodes = parseInt(data.maxGroupNodes);
20 let style = data.style;
21 let texWidth = data.texWidth;
22 let texHeight = data.texHeight;
23 let nodesInfo = data.nodesInfo;
24
25 let mesh = {
26 allVertices: [],
27 groups: [],
28 width: 0,
29 height: 0
30 };
31
32 let vertices;
33 let texCoord;
34 let color;
35 let stacksIndices;
36 let wireframeIndices;
37 let index;
38
39 // seed the random function to get the same values each time
40 // we're doing this to avoid ugly z-fighting with overlapping nodes
41 self.random.seed(0);
42
43 // go through all the dom nodes and compute the verts, texcoord etc.
44 for (let n = 0, len = nodesInfo.length; n < len; n++) {
45
46 // check if we need to start creating a new group
47 if (n % maxGroupNodes === 0) {
48 vertices = []; // recreate the arrays used to construct the 3D mesh data
49 texCoord = [];
50 color = [];
51 stacksIndices = [];
52 wireframeIndices = [];
53 index = 0;
54 }
55
56 let info = nodesInfo[n];
57 let coord = info.coord;
58
59 // calculate the stack x, y, z, width and height coordinates
60 let z = coord.depth + coord.thickness;
61 let y = coord.top;
62 let x = coord.left;
63 let w = coord.width;
64 let h = coord.height;
65
66 // the maximum texture size slices the visualization mesh where needed
67 if (x + w > texWidth) {
68 w = texWidth - x;
69 }
70 if (y + h > texHeight) {
71 h = texHeight - y;
72 }
73
74 x += self.random.next();
75 y += self.random.next();
76 w -= self.random.next() * 0.1;
77 h -= self.random.next() * 0.1;
78
79 let xpw = x + w;
80 let yph = y + h;
81 let zmt = coord.depth;
82
83 let xotw = x / texWidth;
84 let yoth = y / texHeight;
85 let xpwotw = xpw / texWidth;
86 let yphoth = yph / texHeight;
87
88 // calculate the margin fill color
89 let fill = style[info.name] || style.highlight.defaultFill;
90
91 let r = fill[0];
92 let g = fill[1];
93 let b = fill[2];
94 let g10 = r * 1.1;
95 let g11 = g * 1.1;
96 let g12 = b * 1.1;
97 let g20 = r * 0.6;
98 let g21 = g * 0.6;
99 let g22 = b * 0.6;
100
101 // compute the vertices
102 vertices.push(x, y, z, /* front */ // 0
103 x, yph, z, // 1
104 xpw, yph, z, // 2
105 xpw, y, z, // 3
106 // we don't duplicate vertices for the left and right faces, because
107 // they can be reused from the bottom and top faces; we do, however,
108 // duplicate some vertices from front face, because it has custom
109 // texture coordinates which are not shared by the other faces
110 x, y, z, /* front */ // 4
111 x, yph, z, // 5
112 xpw, yph, z, // 6
113 xpw, y, z, // 7
114 x, y, zmt, /* back */ // 8
115 x, yph, zmt, // 9
116 xpw, yph, zmt, // 10
117 xpw, y, zmt); // 11
118
119 // compute the texture coordinates
120 texCoord.push(xotw, yoth,
121 xotw, yphoth,
122 xpwotw, yphoth,
123 xpwotw, yoth,
124 -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0);
125
126 // compute the colors for each vertex in the mesh
127 color.push(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
128 g10, g11, g12,
129 g10, g11, g12,
130 g10, g11, g12,
131 g10, g11, g12,
132 g20, g21, g22,
133 g20, g21, g22,
134 g20, g21, g22,
135 g20, g21, g22);
136
137 let i = index; // number of vertex points, used to create the indices array
138 let ip1 = i + 1;
139 let ip2 = ip1 + 1;
140 let ip3 = ip2 + 1;
141 let ip4 = ip3 + 1;
142 let ip5 = ip4 + 1;
143 let ip6 = ip5 + 1;
144 let ip7 = ip6 + 1;
145 let ip8 = ip7 + 1;
146 let ip9 = ip8 + 1;
147 let ip10 = ip9 + 1;
148 let ip11 = ip10 + 1;
149
150 // compute the stack indices
151 stacksIndices.unshift(i, ip1, ip2, i, ip2, ip3,
152 ip8, ip9, ip5, ip8, ip5, ip4,
153 ip7, ip6, ip10, ip7, ip10, ip11,
154 ip8, ip4, ip7, ip8, ip7, ip11,
155 ip5, ip9, ip10, ip5, ip10, ip6);
156
157 // compute the wireframe indices
158 if (coord.thickness !== 0) {
159 wireframeIndices.unshift(i, ip1, ip1, ip2,
160 ip2, ip3, ip3, i,
161 ip8, i, ip9, ip1,
162 ip11, ip3, ip10, ip2);
163 }
164
165 // there are 12 vertices in a stack representing a node
166 index += 12;
167
168 // set the maximum mesh width and height to calculate the center offset
169 mesh.width = Math.max(w, mesh.width);
170 mesh.height = Math.max(h, mesh.height);
171
172 // check if we need to save the currently active group; this happens after
173 // we filled all the "slots" in a group or there aren't any remaining nodes
174 if (((n + 1) % maxGroupNodes === 0) || (n === len - 1)) {
175 mesh.groups.push({
176 vertices: vertices,
177 texCoord: texCoord,
178 color: color,
179 stacksIndices: stacksIndices,
180 wireframeIndices: wireframeIndices
181 });
182 mesh.allVertices = mesh.allVertices.concat(vertices);
183 }
184 }
185
186 self.postMessage(mesh);
187 close();
188 };
189
190 /**
191 * Utility functions for generating random numbers using the Alea algorithm.
192 */
193 self.random = {
194
195 /**
196 * The generator function, automatically created with seed 0.
197 */
198 _generator: null,
199
200 /**
201 * Returns a new random number between [0..1)
202 */
203 next: function RNG_next()
204 {
205 return this._generator();
206 },
207
208 /**
209 * From http://baagoe.com/en/RandomMusings/javascript
210 * Johannes Baagoe <baagoe@baagoe.com>, 2010
211 *
212 * Seeds a random generator function with a set of passed arguments.
213 */
214 seed: function RNG_seed()
215 {
216 let s0 = 0;
217 let s1 = 0;
218 let s2 = 0;
219 let c = 1;
220
221 if (arguments.length === 0) {
222 return this.seed(+new Date());
223 } else {
224 s0 = this.mash(" ");
225 s1 = this.mash(" ");
226 s2 = this.mash(" ");
227
228 for (let i = 0, len = arguments.length; i < len; i++) {
229 s0 -= this.mash(arguments[i]);
230 if (s0 < 0) {
231 s0 += 1;
232 }
233 s1 -= this.mash(arguments[i]);
234 if (s1 < 0) {
235 s1 += 1;
236 }
237 s2 -= this.mash(arguments[i]);
238 if (s2 < 0) {
239 s2 += 1;
240 }
241 }
242
243 let random = function() {
244 let t = 2091639 * s0 + c * 2.3283064365386963e-10; // 2^-32
245 s0 = s1;
246 s1 = s2;
247 return (s2 = t - (c = t | 0));
248 };
249 random.uint32 = function() {
250 return random() * 0x100000000; // 2^32
251 };
252 random.fract53 = function() {
253 return random() +
254 (random() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53
255 };
256 return (this._generator = random);
257 }
258 },
259
260 /**
261 * From http://baagoe.com/en/RandomMusings/javascript
262 * Johannes Baagoe <baagoe@baagoe.com>, 2010
263 */
264 mash: function RNG_mash(data)
265 {
266 let h, n = 0xefc8249d;
267
268 for (let i = 0, data = data.toString(), len = data.length; i < len; i++) {
269 n += data.charCodeAt(i);
270 h = 0.02519603282416938 * n;
271 n = h >>> 0;
272 h -= n;
273 h *= n;
274 n = h >>> 0;
275 h -= n;
276 n += h * 0x100000000; // 2^32
277 }
278 return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
279 }
280 };

mercurial