summaryrefslogtreecommitdiffstats
path: root/o3d/samples/siteswap/siteswap.js
diff options
context:
space:
mode:
Diffstat (limited to 'o3d/samples/siteswap/siteswap.js')
-rw-r--r--o3d/samples/siteswap/siteswap.js830
1 files changed, 415 insertions, 415 deletions
diff --git a/o3d/samples/siteswap/siteswap.js b/o3d/samples/siteswap/siteswap.js
index 24a59a7cd..6b77aff 100644
--- a/o3d/samples/siteswap/siteswap.js
+++ b/o3d/samples/siteswap/siteswap.js
@@ -1,415 +1,415 @@
-// @@REWRITE(insert js-copyright)
-// @@REWRITE(delete-start)
-// Copyright 2009 Google Inc. All Rights Reserved
-// @@REWRITE(delete-end)
-
-/**
- * This file contains the top-level logic and o3d-related code for the siteswap
- * animator.
- */
-
-o3djs.require('o3djs.rendergraph');
-o3djs.require('o3djs.math');
-o3djs.require('o3djs.primitives');
-o3djs.require('o3djs.dump');
-
-// Global variables are all referenced via g, so that either interpreter can
-// find them easily.
-var g = {};
-
-/**
- * Creates a color based on an input index as a seed.
- * @param {!number} index the seed value to select the color.
- * @return {!Array.number} an [r g b a] color.
- */
-function createColor(index) {
- var N = 12; // Number of distinct colors.
- var root3 = Math.sqrt(3);
- var theta = 2 * Math.PI * index / N;
- var sin = Math.sin(theta);
- var cos = Math.cos(theta);
- return [(1 / 3 + 2 / 3 * cos) + (1 / 3 - cos / 3 - sin / root3),
- (1 / 3 - cos / 3 + sin / root3) + (1 / 3 + 2 / 3 * cos),
- (1 / 3 - cos / 3 - sin / root3) + (1 / 3 - cos / 3 + sin / root3),
- 1];
-}
-
-/**
- * Creates a material, given the index as a seed to make it distinguishable.
- * @param {number} index an integer used to create a distinctive color.
- * @return {!o3d.Material} the material.
- */
-function createMaterial(index) {
- var material = g.pack.createObject('Material');
-
- // Apply our effect to this material. The effect tells the 3D hardware
- // which shader to use.
- material.effect = g.effect;
-
- // Set the material's drawList
- material.drawList = g.viewInfo.performanceDrawList;
-
- // This will create our quadColor parameter on the material.
- g.effect.createUniformParameters(material);
-
- // Set up the individual parameters in our effect file.
-
- // Light position
- var light_pos_param = material.getParam('light_pos');
- light_pos_param.value = [10, 10, 20];
-
- // Phong components of the light source
- var light_ambient_param = material.getParam('light_ambient');
- var light_diffuse_param = material.getParam('light_diffuse');
- var light_specular_param = material.getParam('light_specular');
-
- // White ambient light
- light_ambient_param.value = [0.04, 0.04, 0.04, 1];
-
- light_diffuse_param.value = createColor(index);
- // White specular light
- light_specular_param.value = [0.5, 0.5, 0.5, 1];
-
- // Shininess of the material (for specular lighting)
- var shininess_param = material.getParam('shininess');
- shininess_param.value = 30.0;
-
- // Bind the counter's count to the input of the FunctionEval.
- var paramTime = material.getParam('time');
- paramTime.bind(g.counter.getParam('count'));
-
- material.getParam('camera_pos').value = g.eye;
-
- return material;
-}
-
-/**
- * Gets a material from our cache, creating it if it's not yet been made.
- * Uses index as a seed to make the material distinguishable.
- * @param {number} index an integer used to create/fetch a distinctive color.
- * @return {!o3d.Material} the material.
- */
-function getMaterial(index) {
- g.materials = g.materials || []; // See initStep2 for a comment.
- if (!g.materials[index]) {
- g.materials[index] = createMaterial(index);
- }
- return g.materials[index];
-}
-
-/**
- * Initializes g.o3d.
- * @param {Array} clientElements Array of o3d object elements.
- */
-function initStep2(clientElements) {
- // Initializes global variables and libraries.
- window.g = g;
-
- // Used to tell whether we need to recompute our view on resize.
- g.o3dWidth = -1;
- g.o3dHeight = -1;
-
- // We create a different material for each color of object.
- //g.materials = []; // TODO(ericu): If this is executed, we fail. Why?
-
- // We hold on to all the shapes here so that we can clean them up when we want
- // to change patterns.
- g.ballShapes = [];
- g.handShapes = [];
-
- g.o3dElement = clientElements[0];
- g.o3d = g.o3dElement.o3d;
- g.math = o3djs.math;
- g.client = g.o3dElement.client;
-
- // Initialize client sample libraries.
- o3djs.base.init(g.o3dElement);
-
- // Create a g.pack to manage our resources/assets
- g.pack = g.client.createPack();
-
- // Create the render graph for a view.
- g.viewInfo = o3djs.rendergraph.createBasicView(
- g.pack,
- g.client.root,
- g.client.renderGraphRoot);
-
- // Get the default context to hold view/projection matrices.
- g.context = g.viewInfo.drawContext;
-
- // Load a simple effect from a textarea.
- g.effect = g.pack.createObject('Effect');
- g.effect.loadFromFXString(document.getElementById('shader').value);
-
- // Eye-position: this is where our camera is located.
- // Global because each material we create must also know where it is, so that
- // the shader works properly.
- g.eye = [1, 6, 10];
-
- // Target, this is the point at which our camera is pointed.
- var target = [0, 2, 0];
-
- // Up-vector, this tells the camera which direction is 'up'.
- // We define the positive y-direction to be up in this example.
- var up = [0, 1, 0];
-
- g.context.view = g.math.matrix4.lookAt(g.eye, target, up);
-
- // Make a SecondCounter to provide the time for our animation.
- g.counter = g.pack.createObject('SecondCounter');
- g.counter.multiplier = 3; // Speed up time; this is in throws per second.
-
- // Generate the projection and viewProjection matrices based
- // on the g.o3d plugin size by calling onResize().
- onResize();
-
- // If we don't check the size of the client area every frame we don't get a
- // chance to adjust the perspective matrix fast enough to keep up with the
- // browser resizing us.
- // TODO(ericu): Switch to using the resize event once it's checked in.
- g.client.setRenderCallback(onResize);
-}
-
-/**
- * Stops or starts the animation based on the state of an html checkbox.
- */
-function updateAnimating() {
- var box = document.the_form.check_box;
- g.counter.running = box.checked;
-}
-
-/**
- * Generates the projection matrix based on the size of the g.o3d plugin
- * and calculates the view-projection matrix.
- */
-function onResize() {
- var newWidth = g.client.width;
- var newHeight = g.client.height;
-
- if (newWidth != g.o3dWidth || newHeight != g.o3dHeight) {
- debug('resizing');
- g.o3dWidth = newWidth;
- g.o3dHeight = newHeight;
-
- // Create our projection matrix, with a vertical field of view of 45 degrees
- // a near clipping plane of 0.1 and far clipping plane of 100.
- g.context.projection = g.math.matrix4.perspective(
- 45 * Math.PI / 180,
- g.o3dWidth / g.o3dHeight,
- 0.1,
- 100);
- }
-}
-
-/**
- * Computes and prepares animation of the pattern input via the html form. If
- * the box is checked, this will immediately begin animation as well.
- */
-function onComputePattern() {
- try {
- g.counter.removeAllCallbacks();
- var group = document.the_form.radio_group_hands;
- var numHands = -1;
- for (var i = 0; i < group.length; ++i) {
- if (group[i].checked) {
- numHands = parseInt(group[i].value);
- }
- }
- var style = 'even';
- if (document.the_form.pair_hands.checked) {
- style = 'pairs';
- }
- var patternString = document.getElementById('input_pattern').value;
- var patternData =
- computeFullPatternFromString(patternString, numHands, style);
- startAnimation(
- patternData.numBalls,
- patternData.numHands,
- patternData.duration,
- patternData.ballCurveSets,
- patternData.handCurveSets);
- } catch (ex) {
- popup(stringifyObj(ex));
- throw ex;
- }
- setUpSelection();
-}
-
-/**
- * Removes any callbacks so they don't get called after the page has unloaded.
- */
-function cleanup() {
- g.client.cleanup();
-}
-
-
-/**
- * Dump out a newline-terminated string to the debug console, if available.
- * @param {!string} s the string to output.
- */
-function debug(s) {
- o3djs.dump.dump(s + '\n');
-}
-
-/**
- * Dump out a newline-terminated string to the debug console, if available,
- * then display it via an alert.
- * @param {!string} s the string to output.
- */
-function popup(s) {
- debug(s);
- window.alert(s);
-}
-
-/**
- * If t, throw an exception.
- * @param {!bool} t the value to test.
- */
-function assert(t) {
- if (!t) {
- throw new Error('Assertion failed!');
- }
-}
-
-/**
- * Convert an object to a string containing a full one-level-deep property
- * listing, with values.
- * @param {!Object} o the object to convert.
- * @return {!string} the converted object.
- */
-function stringifyObj(o) {
- var s = '';
- for (var i in o) {
- s += i + ':' + o[i] + '\n';
- }
- return s;
-}
-
-/**
- * Add the information in a curve to the params on a shape, such that the vertex
- * shader will move the shape along the curve at times after timeBase.
- * @param {!Curve} curve the curve the shape should follow.
- * @param {!o3d.Shape} shape the shape being moved.
- * @param {!number} timeBase the base to subtract from the current time when
- * giving the curve calculation its time input.
- */
-function setParamCurveInfo(curve, shape, timeBase) {
- assert(curve);
- assert(shape);
- try {
- shape.elements[0].getParam('time_base').value = timeBase;
- shape.elements[0].getParam('coeff_a').value =
- [curve.xEqn.a, curve.yEqn.a, curve.zEqn.a];
- shape.elements[0].getParam('coeff_b').value =
- [curve.xEqn.b, curve.yEqn.b, curve.zEqn.b];
- shape.elements[0].getParam('coeff_c').value =
- [curve.xEqn.c, curve.yEqn.c, curve.zEqn.c];
- shape.elements[0].getParam('coeff_d').value =
- [curve.xEqn.d, curve.yEqn.d, curve.zEqn.d];
- shape.elements[0].getParam('coeff_e').value =
- [curve.xEqn.e, curve.yEqn.e, curve.zEqn.e];
- shape.elements[0].getParam('coeff_f').value =
- [curve.xEqn.f, curve.yEqn.f, curve.zEqn.f];
-
- assert(curve.xEqn.lerpRate == curve.yEqn.lerpRate);
- assert(curve.xEqn.lerpRate == curve.zEqn.lerpRate);
- shape.elements[0].getParam('coeff_lerp').value = curve.xEqn.lerpRate;
- if (curve.xEqn.lerpRate) {
- shape.elements[0].getParam('coeff_l_a').value =
- [curve.xEqn.lA, curve.yEqn.lA, curve.zEqn.lA];
- shape.elements[0].getParam('coeff_l_b').value =
- [curve.xEqn.lB, curve.yEqn.lB, curve.zEqn.lB];
- shape.elements[0].getParam('coeff_l_c').value =
- [curve.xEqn.lC, curve.yEqn.lC, curve.zEqn.lC];
- }
- } catch (ex) {
- debug(ex);
- throw ex;
- }
-}
-
-/**
- * Create the params that the shader expects on the supplied shape's first
- * element.
- * @param {!o3d.Shape} shape the shape on whose first element to create params.
- */
-function createParams(shape) {
- shape.elements[0].createParam('coeff_a', 'ParamFloat3').value = [0, 0, 0];
- shape.elements[0].createParam('coeff_b', 'ParamFloat3').value = [0, 0, 0];
- shape.elements[0].createParam('coeff_c', 'ParamFloat3').value = [0, 0, 0];
- shape.elements[0].createParam('coeff_d', 'ParamFloat3').value = [0, 0, 0];
- shape.elements[0].createParam('coeff_e', 'ParamFloat3').value = [0, 0, 0];
- shape.elements[0].createParam('coeff_f', 'ParamFloat3').value = [0, 0, 0];
- shape.elements[0].createParam('coeff_l_a', 'ParamFloat3').value = [0, 0, 0];
- shape.elements[0].createParam('coeff_l_b', 'ParamFloat3').value = [0, 0, 0];
- shape.elements[0].createParam('coeff_l_c', 'ParamFloat3').value = [0, 0, 0];
- shape.elements[0].createParam('coeff_lerp', 'ParamFloat').value = 0;
- shape.elements[0].createParam('time_base', 'ParamFloat').value = 0;
-}
-
-/**
- * Adjust the number of ball shapes in g.pack.
- * @param {!number} numBalls the number of balls desired.
- */
-function setNumBalls(numBalls) {
- for (var i = 0; i < g.ballShapes.length; ++i) {
- g.pack.removeObject(g.ballShapes[i]);
- g.client.root.removeShape(g.ballShapes[i]);
- }
- g.ballShapes = [];
-
- for (var i = 0; i < numBalls; ++i) {
- var shape = o3djs.primitives.createSphere(g.pack,
- getMaterial(5 * i),
- 0.10,
- 70,
- 70);
- shape.name = 'Ball ' + i;
-
- // generate the draw elements.
- shape.createDrawElements(g.pack, null);
-
- // Now attach the sphere to the root of the scene graph.
- g.client.root.addShape(shape);
-
- // Create the material params for the shader.
- createParams(shape);
-
- g.ballShapes[i] = shape;
- }
-}
-
-/**
- * Adjust the number of hand shapes in g.pack.
- * @param {!number} numHands the number of hands desired.
- */
-function setNumHands(numHands) {
- g.counter.removeAllCallbacks();
-
- for (var i = 0; i < g.handShapes.length; ++i) {
- g.pack.removeObject(g.handShapes[i]);
- g.client.root.removeShape(g.handShapes[i]);
- }
- g.handShapes = [];
-
- for (var i = 0; i < numHands; ++i) {
- var shape = o3djs.primitives.createBox(g.pack,
- getMaterial(3 * (i + 1)),
- 0.25,
- 0.05,
- 0.25);
- shape.name = 'Hand ' + i;
-
- // generate the draw elements.
- shape.createDrawElements(g.pack, null);
-
- // Now attach the sphere to the root of the scene graph.
- g.client.root.addShape(shape);
-
- // Create the material params for the shader.
- createParams(shape);
-
- g.handShapes[i] = shape;
- }
-}
-
+// @@REWRITE(insert js-copyright)
+// @@REWRITE(delete-start)
+// Copyright 2009 Google Inc. All Rights Reserved
+// @@REWRITE(delete-end)
+
+/**
+ * This file contains the top-level logic and o3d-related code for the siteswap
+ * animator.
+ */
+
+o3djs.require('o3djs.rendergraph');
+o3djs.require('o3djs.math');
+o3djs.require('o3djs.primitives');
+o3djs.require('o3djs.dump');
+
+// Global variables are all referenced via g, so that either interpreter can
+// find them easily.
+var g = {};
+
+/**
+ * Creates a color based on an input index as a seed.
+ * @param {!number} index the seed value to select the color.
+ * @return {!Array.number} an [r g b a] color.
+ */
+function createColor(index) {
+ var N = 12; // Number of distinct colors.
+ var root3 = Math.sqrt(3);
+ var theta = 2 * Math.PI * index / N;
+ var sin = Math.sin(theta);
+ var cos = Math.cos(theta);
+ return [(1 / 3 + 2 / 3 * cos) + (1 / 3 - cos / 3 - sin / root3),
+ (1 / 3 - cos / 3 + sin / root3) + (1 / 3 + 2 / 3 * cos),
+ (1 / 3 - cos / 3 - sin / root3) + (1 / 3 - cos / 3 + sin / root3),
+ 1];
+}
+
+/**
+ * Creates a material, given the index as a seed to make it distinguishable.
+ * @param {number} index an integer used to create a distinctive color.
+ * @return {!o3d.Material} the material.
+ */
+function createMaterial(index) {
+ var material = g.pack.createObject('Material');
+
+ // Apply our effect to this material. The effect tells the 3D hardware
+ // which shader to use.
+ material.effect = g.effect;
+
+ // Set the material's drawList
+ material.drawList = g.viewInfo.performanceDrawList;
+
+ // This will create our quadColor parameter on the material.
+ g.effect.createUniformParameters(material);
+
+ // Set up the individual parameters in our effect file.
+
+ // Light position
+ var light_pos_param = material.getParam('light_pos');
+ light_pos_param.value = [10, 10, 20];
+
+ // Phong components of the light source
+ var light_ambient_param = material.getParam('light_ambient');
+ var light_diffuse_param = material.getParam('light_diffuse');
+ var light_specular_param = material.getParam('light_specular');
+
+ // White ambient light
+ light_ambient_param.value = [0.04, 0.04, 0.04, 1];
+
+ light_diffuse_param.value = createColor(index);
+ // White specular light
+ light_specular_param.value = [0.5, 0.5, 0.5, 1];
+
+ // Shininess of the material (for specular lighting)
+ var shininess_param = material.getParam('shininess');
+ shininess_param.value = 30.0;
+
+ // Bind the counter's count to the input of the FunctionEval.
+ var paramTime = material.getParam('time');
+ paramTime.bind(g.counter.getParam('count'));
+
+ material.getParam('camera_pos').value = g.eye;
+
+ return material;
+}
+
+/**
+ * Gets a material from our cache, creating it if it's not yet been made.
+ * Uses index as a seed to make the material distinguishable.
+ * @param {number} index an integer used to create/fetch a distinctive color.
+ * @return {!o3d.Material} the material.
+ */
+function getMaterial(index) {
+ g.materials = g.materials || []; // See initStep2 for a comment.
+ if (!g.materials[index]) {
+ g.materials[index] = createMaterial(index);
+ }
+ return g.materials[index];
+}
+
+/**
+ * Initializes g.o3d.
+ * @param {Array} clientElements Array of o3d object elements.
+ */
+function initStep2(clientElements) {
+ // Initializes global variables and libraries.
+ window.g = g;
+
+ // Used to tell whether we need to recompute our view on resize.
+ g.o3dWidth = -1;
+ g.o3dHeight = -1;
+
+ // We create a different material for each color of object.
+ //g.materials = []; // TODO(ericu): If this is executed, we fail. Why?
+
+ // We hold on to all the shapes here so that we can clean them up when we want
+ // to change patterns.
+ g.ballShapes = [];
+ g.handShapes = [];
+
+ g.o3dElement = clientElements[0];
+ g.o3d = g.o3dElement.o3d;
+ g.math = o3djs.math;
+ g.client = g.o3dElement.client;
+
+ // Initialize client sample libraries.
+ o3djs.base.init(g.o3dElement);
+
+ // Create a g.pack to manage our resources/assets
+ g.pack = g.client.createPack();
+
+ // Create the render graph for a view.
+ g.viewInfo = o3djs.rendergraph.createBasicView(
+ g.pack,
+ g.client.root,
+ g.client.renderGraphRoot);
+
+ // Get the default context to hold view/projection matrices.
+ g.context = g.viewInfo.drawContext;
+
+ // Load a simple effect from a textarea.
+ g.effect = g.pack.createObject('Effect');
+ g.effect.loadFromFXString(document.getElementById('shader').value);
+
+ // Eye-position: this is where our camera is located.
+ // Global because each material we create must also know where it is, so that
+ // the shader works properly.
+ g.eye = [1, 6, 10];
+
+ // Target, this is the point at which our camera is pointed.
+ var target = [0, 2, 0];
+
+ // Up-vector, this tells the camera which direction is 'up'.
+ // We define the positive y-direction to be up in this example.
+ var up = [0, 1, 0];
+
+ g.context.view = g.math.matrix4.lookAt(g.eye, target, up);
+
+ // Make a SecondCounter to provide the time for our animation.
+ g.counter = g.pack.createObject('SecondCounter');
+ g.counter.multiplier = 3; // Speed up time; this is in throws per second.
+
+ // Generate the projection and viewProjection matrices based
+ // on the g.o3d plugin size by calling onResize().
+ onResize();
+
+ // If we don't check the size of the client area every frame we don't get a
+ // chance to adjust the perspective matrix fast enough to keep up with the
+ // browser resizing us.
+ // TODO(ericu): Switch to using the resize event once it's checked in.
+ g.client.setRenderCallback(onResize);
+}
+
+/**
+ * Stops or starts the animation based on the state of an html checkbox.
+ */
+function updateAnimating() {
+ var box = document.the_form.check_box;
+ g.counter.running = box.checked;
+}
+
+/**
+ * Generates the projection matrix based on the size of the g.o3d plugin
+ * and calculates the view-projection matrix.
+ */
+function onResize() {
+ var newWidth = g.client.width;
+ var newHeight = g.client.height;
+
+ if (newWidth != g.o3dWidth || newHeight != g.o3dHeight) {
+ debug('resizing');
+ g.o3dWidth = newWidth;
+ g.o3dHeight = newHeight;
+
+ // Create our projection matrix, with a vertical field of view of 45 degrees
+ // a near clipping plane of 0.1 and far clipping plane of 100.
+ g.context.projection = g.math.matrix4.perspective(
+ 45 * Math.PI / 180,
+ g.o3dWidth / g.o3dHeight,
+ 0.1,
+ 100);
+ }
+}
+
+/**
+ * Computes and prepares animation of the pattern input via the html form. If
+ * the box is checked, this will immediately begin animation as well.
+ */
+function onComputePattern() {
+ try {
+ g.counter.removeAllCallbacks();
+ var group = document.the_form.radio_group_hands;
+ var numHands = -1;
+ for (var i = 0; i < group.length; ++i) {
+ if (group[i].checked) {
+ numHands = parseInt(group[i].value);
+ }
+ }
+ var style = 'even';
+ if (document.the_form.pair_hands.checked) {
+ style = 'pairs';
+ }
+ var patternString = document.getElementById('input_pattern').value;
+ var patternData =
+ computeFullPatternFromString(patternString, numHands, style);
+ startAnimation(
+ patternData.numBalls,
+ patternData.numHands,
+ patternData.duration,
+ patternData.ballCurveSets,
+ patternData.handCurveSets);
+ } catch (ex) {
+ popup(stringifyObj(ex));
+ throw ex;
+ }
+ setUpSelection();
+}
+
+/**
+ * Removes any callbacks so they don't get called after the page has unloaded.
+ */
+function cleanup() {
+ g.client.cleanup();
+}
+
+
+/**
+ * Dump out a newline-terminated string to the debug console, if available.
+ * @param {!string} s the string to output.
+ */
+function debug(s) {
+ o3djs.dump.dump(s + '\n');
+}
+
+/**
+ * Dump out a newline-terminated string to the debug console, if available,
+ * then display it via an alert.
+ * @param {!string} s the string to output.
+ */
+function popup(s) {
+ debug(s);
+ window.alert(s);
+}
+
+/**
+ * If t, throw an exception.
+ * @param {!bool} t the value to test.
+ */
+function assert(t) {
+ if (!t) {
+ throw new Error('Assertion failed!');
+ }
+}
+
+/**
+ * Convert an object to a string containing a full one-level-deep property
+ * listing, with values.
+ * @param {!Object} o the object to convert.
+ * @return {!string} the converted object.
+ */
+function stringifyObj(o) {
+ var s = '';
+ for (var i in o) {
+ s += i + ':' + o[i] + '\n';
+ }
+ return s;
+}
+
+/**
+ * Add the information in a curve to the params on a shape, such that the vertex
+ * shader will move the shape along the curve at times after timeBase.
+ * @param {!Curve} curve the curve the shape should follow.
+ * @param {!o3d.Shape} shape the shape being moved.
+ * @param {!number} timeBase the base to subtract from the current time when
+ * giving the curve calculation its time input.
+ */
+function setParamCurveInfo(curve, shape, timeBase) {
+ assert(curve);
+ assert(shape);
+ try {
+ shape.elements[0].getParam('time_base').value = timeBase;
+ shape.elements[0].getParam('coeff_a').value =
+ [curve.xEqn.a, curve.yEqn.a, curve.zEqn.a];
+ shape.elements[0].getParam('coeff_b').value =
+ [curve.xEqn.b, curve.yEqn.b, curve.zEqn.b];
+ shape.elements[0].getParam('coeff_c').value =
+ [curve.xEqn.c, curve.yEqn.c, curve.zEqn.c];
+ shape.elements[0].getParam('coeff_d').value =
+ [curve.xEqn.d, curve.yEqn.d, curve.zEqn.d];
+ shape.elements[0].getParam('coeff_e').value =
+ [curve.xEqn.e, curve.yEqn.e, curve.zEqn.e];
+ shape.elements[0].getParam('coeff_f').value =
+ [curve.xEqn.f, curve.yEqn.f, curve.zEqn.f];
+
+ assert(curve.xEqn.lerpRate == curve.yEqn.lerpRate);
+ assert(curve.xEqn.lerpRate == curve.zEqn.lerpRate);
+ shape.elements[0].getParam('coeff_lerp').value = curve.xEqn.lerpRate;
+ if (curve.xEqn.lerpRate) {
+ shape.elements[0].getParam('coeff_l_a').value =
+ [curve.xEqn.lA, curve.yEqn.lA, curve.zEqn.lA];
+ shape.elements[0].getParam('coeff_l_b').value =
+ [curve.xEqn.lB, curve.yEqn.lB, curve.zEqn.lB];
+ shape.elements[0].getParam('coeff_l_c').value =
+ [curve.xEqn.lC, curve.yEqn.lC, curve.zEqn.lC];
+ }
+ } catch (ex) {
+ debug(ex);
+ throw ex;
+ }
+}
+
+/**
+ * Create the params that the shader expects on the supplied shape's first
+ * element.
+ * @param {!o3d.Shape} shape the shape on whose first element to create params.
+ */
+function createParams(shape) {
+ shape.elements[0].createParam('coeff_a', 'ParamFloat3').value = [0, 0, 0];
+ shape.elements[0].createParam('coeff_b', 'ParamFloat3').value = [0, 0, 0];
+ shape.elements[0].createParam('coeff_c', 'ParamFloat3').value = [0, 0, 0];
+ shape.elements[0].createParam('coeff_d', 'ParamFloat3').value = [0, 0, 0];
+ shape.elements[0].createParam('coeff_e', 'ParamFloat3').value = [0, 0, 0];
+ shape.elements[0].createParam('coeff_f', 'ParamFloat3').value = [0, 0, 0];
+ shape.elements[0].createParam('coeff_l_a', 'ParamFloat3').value = [0, 0, 0];
+ shape.elements[0].createParam('coeff_l_b', 'ParamFloat3').value = [0, 0, 0];
+ shape.elements[0].createParam('coeff_l_c', 'ParamFloat3').value = [0, 0, 0];
+ shape.elements[0].createParam('coeff_lerp', 'ParamFloat').value = 0;
+ shape.elements[0].createParam('time_base', 'ParamFloat').value = 0;
+}
+
+/**
+ * Adjust the number of ball shapes in g.pack.
+ * @param {!number} numBalls the number of balls desired.
+ */
+function setNumBalls(numBalls) {
+ for (var i = 0; i < g.ballShapes.length; ++i) {
+ g.pack.removeObject(g.ballShapes[i]);
+ g.client.root.removeShape(g.ballShapes[i]);
+ }
+ g.ballShapes = [];
+
+ for (var i = 0; i < numBalls; ++i) {
+ var shape = o3djs.primitives.createSphere(g.pack,
+ getMaterial(5 * i),
+ 0.10,
+ 70,
+ 70);
+ shape.name = 'Ball ' + i;
+
+ // generate the draw elements.
+ shape.createDrawElements(g.pack, null);
+
+ // Now attach the sphere to the root of the scene graph.
+ g.client.root.addShape(shape);
+
+ // Create the material params for the shader.
+ createParams(shape);
+
+ g.ballShapes[i] = shape;
+ }
+}
+
+/**
+ * Adjust the number of hand shapes in g.pack.
+ * @param {!number} numHands the number of hands desired.
+ */
+function setNumHands(numHands) {
+ g.counter.removeAllCallbacks();
+
+ for (var i = 0; i < g.handShapes.length; ++i) {
+ g.pack.removeObject(g.handShapes[i]);
+ g.client.root.removeShape(g.handShapes[i]);
+ }
+ g.handShapes = [];
+
+ for (var i = 0; i < numHands; ++i) {
+ var shape = o3djs.primitives.createBox(g.pack,
+ getMaterial(3 * (i + 1)),
+ 0.25,
+ 0.05,
+ 0.25);
+ shape.name = 'Hand ' + i;
+
+ // generate the draw elements.
+ shape.createDrawElements(g.pack, null);
+
+ // Now attach the sphere to the root of the scene graph.
+ g.client.root.addShape(shape);
+
+ // Create the material params for the shader.
+ createParams(shape);
+
+ g.handShapes[i] = shape;
+ }
+}
+