Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(284)

Side by Side Diff: samples/siteswap/siteswap.js

Issue 155005: Adding unfinished-but-working siteswap demo, copied from an ancient perforce changelist. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/o3d/
Patch Set: Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « samples/siteswap/siteswap.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // @@REWRITE(insert js-copyright)
2 // @@REWRITE(delete-start)
3 // Copyright 2009 Google Inc. All Rights Reserved
4 // @@REWRITE(delete-end)
5
6 /**
7 * This file contains the top-level logic and o3d-related code for the siteswap
8 * animator.
9 */
10
11 o3djs.require('o3djs.rendergraph');
12 o3djs.require('o3djs.math');
13 o3djs.require('o3djs.primitives');
14 o3djs.require('o3djs.dump');
15
16 // Global variables are all referenced via g, so that either interpreter can
17 // find them easily.
18 var g = {};
19
20 /**
21 * Creates a color based on an input index as a seed.
22 * @param {!number} index the seed value to select the color.
23 * @return {!Array.number} an [r g b a] color.
24 */
25 function createColor(index) {
26 var N = 12; // Number of distinct colors.
27 var root3 = Math.sqrt(3);
28 var theta = 2 * Math.PI * index / N;
29 var sin = Math.sin(theta);
30 var cos = Math.cos(theta);
31 return [(1 / 3 + 2 / 3 * cos) + (1 / 3 - cos / 3 - sin / root3),
32 (1 / 3 - cos / 3 + sin / root3) + (1 / 3 + 2 / 3 * cos),
33 (1 / 3 - cos / 3 - sin / root3) + (1 / 3 - cos / 3 + sin / root3),
34 1];
35 }
36
37 /**
38 * Creates a material, given the index as a seed to make it distinguishable.
39 * @param {number} index an integer used to create a distinctive color.
40 * @return {!o3d.Material} the material.
41 */
42 function createMaterial(index) {
43 var material = g.pack.createObject('Material');
44
45 // Apply our effect to this material. The effect tells the 3D hardware
46 // which shader to use.
47 material.effect = g.effect;
48
49 // Set the material's drawList
50 material.drawList = g.viewInfo.performanceDrawList;
51
52 // This will create our quadColor parameter on the material.
53 g.effect.createUniformParameters(material);
54
55 // Set up the individual parameters in our effect file.
56
57 // Light position
58 var light_pos_param = material.getParam('light_pos');
59 light_pos_param.value = [10, 10, 20];
60
61 // Phong components of the light source
62 var light_ambient_param = material.getParam('light_ambient');
63 var light_diffuse_param = material.getParam('light_diffuse');
64 var light_specular_param = material.getParam('light_specular');
65
66 // White ambient light
67 light_ambient_param.value = [0.04, 0.04, 0.04, 1];
68
69 light_diffuse_param.value = createColor(index);
70 // White specular light
71 light_specular_param.value = [0.5, 0.5, 0.5, 1];
72
73 // Shininess of the material (for specular lighting)
74 var shininess_param = material.getParam('shininess');
75 shininess_param.value = 30.0;
76
77 // Bind the counter's count to the input of the FunctionEval.
78 var paramTime = material.getParam('time');
79 paramTime.bind(g.counter.getParam('count'));
80
81 material.getParam('camera_pos').value = g.eye;
82
83 return material;
84 }
85
86 /**
87 * Gets a material from our cache, creating it if it's not yet been made.
88 * Uses index as a seed to make the material distinguishable.
89 * @param {number} index an integer used to create/fetch a distinctive color.
90 * @return {!o3d.Material} the material.
91 */
92 function getMaterial(index) {
93 g.materials = g.materials || []; // See initStep2 for a comment.
94 if (!g.materials[index]) {
95 g.materials[index] = createMaterial(index);
96 }
97 return g.materials[index];
98 }
99
100 /**
101 * Initializes g.o3d.
102 * @param {Array} clientElements Array of o3d object elements.
103 */
104 function initStep2(clientElements) {
105 // Initializes global variables and libraries.
106 window.g = g;
107
108 // Used to tell whether we need to recompute our view on resize.
109 g.o3dWidth = -1;
110 g.o3dHeight = -1;
111
112 // We create a different material for each color of object.
113 //g.materials = []; // TODO(ericu): If this is executed, we fail. Why?
114
115 // We hold on to all the shapes here so that we can clean them up when we want
116 // to change patterns.
117 g.ballShapes = [];
118 g.handShapes = [];
119
120 g.o3dElement = clientElements[0];
121 g.o3d = g.o3dElement.o3d;
122 g.math = o3djs.math;
123 g.client = g.o3dElement.client;
124
125 // Initialize client sample libraries.
126 o3djs.base.init(g.o3dElement);
127
128 // Create a g.pack to manage our resources/assets
129 g.pack = g.client.createPack();
130
131 // Create the render graph for a view.
132 g.viewInfo = o3djs.rendergraph.createBasicView(
133 g.pack,
134 g.client.root,
135 g.client.renderGraphRoot);
136
137 // Get the default context to hold view/projection matrices.
138 g.context = g.viewInfo.drawContext;
139
140 // Load a simple effect from a textarea.
141 g.effect = g.pack.createObject('Effect');
142 g.effect.loadFromFXString(document.getElementById('shader').value);
143
144 // Eye-position: this is where our camera is located.
145 // Global because each material we create must also know where it is, so that
146 // the shader works properly.
147 g.eye = [1, 6, 10];
148
149 // Target, this is the point at which our camera is pointed.
150 var target = [0, 2, 0];
151
152 // Up-vector, this tells the camera which direction is 'up'.
153 // We define the positive y-direction to be up in this example.
154 var up = [0, 1, 0];
155
156 g.context.view = g.math.matrix4.lookAt(g.eye, target, up);
157
158 // Make a SecondCounter to provide the time for our animation.
159 g.counter = g.pack.createObject('SecondCounter');
160 g.counter.multiplier = 3; // Speed up time; this is in throws per second.
161
162 // Generate the projection and viewProjection matrices based
163 // on the g.o3d plugin size by calling onResize().
164 onResize();
165
166 // If we don't check the size of the client area every frame we don't get a
167 // chance to adjust the perspective matrix fast enough to keep up with the
168 // browser resizing us.
169 // TODO(ericu): Switch to using the resize event once it's checked in.
170 g.client.setRenderCallback(onResize);
171 }
172
173 /**
174 * Stops or starts the animation based on the state of an html checkbox.
175 */
176 function updateAnimating() {
177 var box = document.the_form.check_box;
178 g.counter.running = box.checked;
179 }
180
181 /**
182 * Generates the projection matrix based on the size of the g.o3d plugin
183 * and calculates the view-projection matrix.
184 */
185 function onResize() {
186 var newWidth = g.client.width;
187 var newHeight = g.client.height;
188
189 if (newWidth != g.o3dWidth || newHeight != g.o3dHeight) {
190 debug('resizing');
191 g.o3dWidth = newWidth;
192 g.o3dHeight = newHeight;
193
194 // Create our projection matrix, with a vertical field of view of 45 degrees
195 // a near clipping plane of 0.1 and far clipping plane of 100.
196 g.context.projection = g.math.matrix4.perspective(
197 45 * Math.PI / 180,
198 g.o3dWidth / g.o3dHeight,
199 0.1,
200 100);
201 }
202 }
203
204 /**
205 * Computes and prepares animation of the pattern input via the html form. If
206 * the box is checked, this will immediately begin animation as well.
207 */
208 function onComputePattern() {
209 try {
210 g.counter.removeAllCallbacks();
211 var group = document.the_form.radio_group_hands;
212 var numHands = -1;
213 for (var i = 0; i < group.length; ++i) {
214 if (group[i].checked) {
215 numHands = parseInt(group[i].value);
216 }
217 }
218 var style = 'even';
219 if (document.the_form.pair_hands.checked) {
220 style = 'pairs';
221 }
222 var patternString = document.getElementById('input_pattern').value;
223 var patternData =
224 computeFullPatternFromString(patternString, numHands, style);
225 startAnimation(
226 patternData.numBalls,
227 patternData.numHands,
228 patternData.duration,
229 patternData.ballCurveSets,
230 patternData.handCurveSets);
231 } catch (ex) {
232 popup(stringifyObj(ex));
233 throw ex;
234 }
235 setUpSelection();
236 }
237
238 /**
239 * Removes any callbacks so they don't get called after the page has unloaded.
240 */
241 function cleanup() {
242 g.client.cleanup();
243 }
244
245
246 /**
247 * Dump out a newline-terminated string to the debug console, if available.
248 * @param {!string} s the string to output.
249 */
250 function debug(s) {
251 o3djs.dump.dump(s + '\n');
252 }
253
254 /**
255 * Dump out a newline-terminated string to the debug console, if available,
256 * then display it via an alert.
257 * @param {!string} s the string to output.
258 */
259 function popup(s) {
260 debug(s);
261 window.alert(s);
262 }
263
264 /**
265 * If t, throw an exception.
266 * @param {!bool} t the value to test.
267 */
268 function assert(t) {
269 if (!t) {
270 throw new Error('Assertion failed!');
271 }
272 }
273
274 /**
275 * Convert an object to a string containing a full one-level-deep property
276 * listing, with values.
277 * @param {!Object} o the object to convert.
278 * @return {!string} the converted object.
279 */
280 function stringifyObj(o) {
281 var s = '';
282 for (var i in o) {
283 s += i + ':' + o[i] + '\n';
284 }
285 return s;
286 }
287
288 /**
289 * Add the information in a curve to the params on a shape, such that the vertex
290 * shader will move the shape along the curve at times after timeBase.
291 * @param {!Curve} curve the curve the shape should follow.
292 * @param {!o3d.Shape} shape the shape being moved.
293 * @param {!number} timeBase the base to subtract from the current time when
294 * giving the curve calculation its time input.
295 */
296 function setParamCurveInfo(curve, shape, timeBase) {
297 assert(curve);
298 assert(shape);
299 try {
300 shape.elements[0].getParam('time_base').value = timeBase;
301 shape.elements[0].getParam('coeff_a').value =
302 [curve.xEqn.a, curve.yEqn.a, curve.zEqn.a];
303 shape.elements[0].getParam('coeff_b').value =
304 [curve.xEqn.b, curve.yEqn.b, curve.zEqn.b];
305 shape.elements[0].getParam('coeff_c').value =
306 [curve.xEqn.c, curve.yEqn.c, curve.zEqn.c];
307 shape.elements[0].getParam('coeff_d').value =
308 [curve.xEqn.d, curve.yEqn.d, curve.zEqn.d];
309 shape.elements[0].getParam('coeff_e').value =
310 [curve.xEqn.e, curve.yEqn.e, curve.zEqn.e];
311 shape.elements[0].getParam('coeff_f').value =
312 [curve.xEqn.f, curve.yEqn.f, curve.zEqn.f];
313
314 assert(curve.xEqn.lerpRate == curve.yEqn.lerpRate);
315 assert(curve.xEqn.lerpRate == curve.zEqn.lerpRate);
316 shape.elements[0].getParam('coeff_lerp').value = curve.xEqn.lerpRate;
317 if (curve.xEqn.lerpRate) {
318 shape.elements[0].getParam('coeff_l_a').value =
319 [curve.xEqn.lA, curve.yEqn.lA, curve.zEqn.lA];
320 shape.elements[0].getParam('coeff_l_b').value =
321 [curve.xEqn.lB, curve.yEqn.lB, curve.zEqn.lB];
322 shape.elements[0].getParam('coeff_l_c').value =
323 [curve.xEqn.lC, curve.yEqn.lC, curve.zEqn.lC];
324 }
325 } catch (ex) {
326 debug(ex);
327 throw ex;
328 }
329 }
330
331 /**
332 * Create the params that the shader expects on the supplied shape's first
333 * element.
334 * @param {!o3d.Shape} shape the shape on whose first element to create params.
335 */
336 function createParams(shape) {
337 shape.elements[0].createParam('coeff_a', 'ParamFloat3').value = [0, 0, 0];
338 shape.elements[0].createParam('coeff_b', 'ParamFloat3').value = [0, 0, 0];
339 shape.elements[0].createParam('coeff_c', 'ParamFloat3').value = [0, 0, 0];
340 shape.elements[0].createParam('coeff_d', 'ParamFloat3').value = [0, 0, 0];
341 shape.elements[0].createParam('coeff_e', 'ParamFloat3').value = [0, 0, 0];
342 shape.elements[0].createParam('coeff_f', 'ParamFloat3').value = [0, 0, 0];
343 shape.elements[0].createParam('coeff_l_a', 'ParamFloat3').value = [0, 0, 0];
344 shape.elements[0].createParam('coeff_l_b', 'ParamFloat3').value = [0, 0, 0];
345 shape.elements[0].createParam('coeff_l_c', 'ParamFloat3').value = [0, 0, 0];
346 shape.elements[0].createParam('coeff_lerp', 'ParamFloat').value = 0;
347 shape.elements[0].createParam('time_base', 'ParamFloat').value = 0;
348 }
349
350 /**
351 * Adjust the number of ball shapes in g.pack.
352 * @param {!number} numBalls the number of balls desired.
353 */
354 function setNumBalls(numBalls) {
355 for (var i = 0; i < g.ballShapes.length; ++i) {
356 g.pack.removeObject(g.ballShapes[i]);
357 g.client.root.removeShape(g.ballShapes[i]);
358 }
359 g.ballShapes = [];
360
361 for (var i = 0; i < numBalls; ++i) {
362 var shape = o3djs.primitives.createSphere(g.pack,
363 getMaterial(5 * i),
364 0.10,
365 70,
366 70);
367 shape.name = 'Ball ' + i;
368
369 // generate the draw elements.
370 shape.createDrawElements(g.pack, null);
371
372 // Now attach the sphere to the root of the scene graph.
373 g.client.root.addShape(shape);
374
375 // Create the material params for the shader.
376 createParams(shape);
377
378 g.ballShapes[i] = shape;
379 }
380 }
381
382 /**
383 * Adjust the number of hand shapes in g.pack.
384 * @param {!number} numHands the number of hands desired.
385 */
386 function setNumHands(numHands) {
387 g.counter.removeAllCallbacks();
388
389 for (var i = 0; i < g.handShapes.length; ++i) {
390 g.pack.removeObject(g.handShapes[i]);
391 g.client.root.removeShape(g.handShapes[i]);
392 }
393 g.handShapes = [];
394
395 for (var i = 0; i < numHands; ++i) {
396 var shape = o3djs.primitives.createBox(g.pack,
397 getMaterial(3 * (i + 1)),
398 0.25,
399 0.05,
400 0.25);
401 shape.name = 'Hand ' + i;
402
403 // generate the draw elements.
404 shape.createDrawElements(g.pack, null);
405
406 // Now attach the sphere to the root of the scene graph.
407 g.client.root.addShape(shape);
408
409 // Create the material params for the shader.
410 createParams(shape);
411
412 g.handShapes[i] = shape;
413 }
414 }
415
OLDNEW
« no previous file with comments | « samples/siteswap/siteswap.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698