diff options
Diffstat (limited to 'o3d/samples/siteswap/siteswap.html')
-rw-r--r-- | o3d/samples/siteswap/siteswap.html | 646 |
1 files changed, 323 insertions, 323 deletions
diff --git a/o3d/samples/siteswap/siteswap.html b/o3d/samples/siteswap/siteswap.html index 15d7497..06656eb 100644 --- a/o3d/samples/siteswap/siteswap.html +++ b/o3d/samples/siteswap/siteswap.html @@ -1,323 +1,323 @@ -<!-- @@REWRITE(insert html-copyright) -->
-<!--
-O3D Siteswap animator
-@@REWRITE(delete-start)
-Author: Eric Uhrhane (ericu@google.com)
-@@REWRITE(delete-end)
--->
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
- "http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-<meta http-equiv="content-type" content="text/html; charset=UTF-8">
-<title>
- Site Swap Simulator
-</title>
-<style type="text/css">
- html, body {
- height: 100%;
- margin: 0;
- padding: 0;
- border: none;
- }
-</style>
-<!-- Our javascript code -->
-<script type="text/javascript" src="../o3djs/base.js"></script>
-<script type="text/javascript" src="siteswap.js"></script>
-<script type="text/javascript" src="math.js"></script>
-<script type="text/javascript" src="animation.js"></script>
-<script type="text/javascript" id="o3dscript">
-
-o3djs.require('o3djs.util');
-
-// Set up the client area.
-function init() {
- o3djs.util.setMainEngine(o3djs.util.Engine.V8);
- o3djs.util.addScriptUri(''); // Allow V8 to load scripts in the cwd.
- o3djs.util.makeClients(initStep2);
- setUpSelection();
-}
-
-// Select the entire input pattern, so that the user can just type.
-function setUpSelection() {
- var input_pattern = document.getElementById('input_pattern');
- input_pattern.focus();
- input_pattern.selectionStart = 0;
- input_pattern.selectionEnd = input_pattern.value.length;
-}
-
-/*
- * Wrappers to enable button presses to call through to the embedded V8 engine.
- */
-
-// Update whether we're animating or frozen based on the value of the checkbox.
-function updateAnimatingWrapper() {
- g.o3dElement.eval('updateAnimating()');
-}
-
-// Compute a new pattern.
-function onComputePatternWrapper() {
- g.o3dElement.eval('onComputePattern()');
-}
-
-// Adjust the view matrix to the new proportions of the plugin window.
-// TODO: Switch to using the resize event once that's checked in.
-function onResizeWrapper() {
- g.o3dElement.eval('onResize()');
-}
-window.onresize = onResizeWrapper;
-
-// Clean up all our callbacks, etc.
-function cleanupWrapper() {
- if (g && g.o3dElement) {
- g.o3dElement.eval('cleanup()');
- }
-}
-
-// The point of this function is to suppress form submit; we want to use the
-// pattern entered when the user hits return, not submit the page to the
-// webserver.
-function suppressSubmit(event) {
- onComputePatternWrapper(); // TODO: This suppresses form autocomplete storage.
- return false;
-}
-
-</script>
-</head>
-<body onload="init()" onunload="cleanupWrapper()">
-<table width="100%" style="height:100%;">
- <tr>
- <td>
- <h1>Juggler</h1>
- This sample displays a site-swap juggling pattern with animation done by
- a vertex shader.
- <form name="the_form" onsubmit="return suppressSubmit(event)">
- <table>
- <tr>
- <td>
- <table>
- <tr>
- <td>
- <input
- type="radio"
- name="radio_group_hands"
- value="1"
- onclick=onComputePatternWrapper()>
- 1 Hand<br>
- <input
- type="radio"
- name="radio_group_hands"
- value="2"
- onclick=onComputePatternWrapper()
- checked>
- 2 Hands<br>
- <input
- type="radio"
- name="radio_group_hands"
- value="3"
- onclick=onComputePatternWrapper()>
- 3 Hands<br>
- <input
- type="radio"
- name="radio_group_hands"
- value="4"
- onclick=onComputePatternWrapper()>
- 4 Hands<br>
- </td>
- <td>
- <input type="text" name="input_pattern" id="input_pattern"
- value="3 4 5">
- </td>
- <td>
- <input type="checkbox" name="check_box" checked
- onclick=updateAnimatingWrapper()>Animate
- <input
- type="checkbox"
- name="pair_hands"
- onclick=onComputePatternWrapper();
- >Pair Hands
- </td>
- <td>
- <input type="button" name="computePattern"
- value="Compute Pattern"
- onclick=onComputePatternWrapper()>
- </td>
- </tr>
- </table>
- </td>
- <td>
- </td>
- </tr>
- </table>
- </form>
- <table id="container" width="90%" style="height:70%;">
- <tr>
- <td height="100%">
- <!-- Start of g.o3d plugin -->
- <div id="o3d" style="width: 100%; height: 100%;"></div>
- <!-- End of g.o3d plugin -->
- </td>
- </tr>
- </table>
- <!-- a simple way to get a multiline string -->
- <textarea id="shader" name="shader" cols="80" rows="20"
- style="display: none;">
-// the 4x4 world view projection matrix
-float4x4 worldViewProjection : WorldViewProjection;
-
-// positions of the light and camera
-float3 light_pos;
-float3 camera_pos;
-
-// phong lighting properties of the material
-float4 light_ambient;
-float4 light_diffuse;
-float4 light_specular;
-
-// shininess of the material (for specular lighting)
-float shininess;
-
-// time for animation
-float time;
-
-// coefficients for a t^2 + b t + c for each of x, y, z
-float3 coeff_a;
-float3 coeff_b;
-float3 coeff_c;
-
-// flag and coefficient for optional LERP with rate t * coeff_lerp;
-float coeff_lerp;
-
-// coefficients for a t^2 + b t + c for each of x, y, z, for optional LERP
-float3 coeff_l_a;
-float3 coeff_l_b;
-float3 coeff_l_c;
-
-// coefficients for d sin(f t) + e cos(e t) for each of x, y, z
-float3 coeff_d;
-float3 coeff_e;
-float3 coeff_f;
-
-// to be subtracted from time to get the t for the above equation
-float time_base;
-
-// input parameters for our vertex shader
-struct VertexShaderInput {
- float4 position : POSITION;
- float3 normal : NORMAL;
- float4 color : COLOR;
-};
-
-// input parameters for our pixel shader
-// also the output parameters for our vertex shader
-struct PixelShaderInput {
- float4 position : POSITION;
- float3 lightVector : TEXCOORD0;
- float3 normal : TEXCOORD1;
- float3 viewPosition : TEXCOORD2;
- float4 color : COLOR;
-};
-
-/**
- * Vertex Shader - vertex shader for phong illumination
- */
-PixelShaderInput vertexShaderFunction(VertexShaderInput input) {
- /**
- * We use the standard phong illumination equation here.
- * We restrict (clamp) the dot products so that we
- * don't get any negative values.
- * All vectors are normalized for proper calculations.
- *
- * The output color is the summation of the
- * ambient, diffuse, and specular contributions.
- *
- * Note that we have to transform each vertex and normal
- * by the world view projection matrix first.
- */
- PixelShaderInput output;
-
- float t = time - time_base;
- float3 offset = float3(0, 0, 0);
- offset += t * t * coeff_a + t * coeff_b + coeff_c;
- offset += coeff_d * sin(t * coeff_f);
- offset += coeff_e * cos(t * coeff_f);
-
- float3 lerpOffset = t * t * coeff_l_a + t * coeff_l_b + coeff_l_c;
- if (coeff_lerp > 0) {
- float rate = min(coeff_lerp * t, 1);
- float3 lerpVector = float3(rate, rate, rate);
- offset = lerp(offset, lerpOffset, lerpVector);
- } else if (coeff_lerp < 0) {
- float rate = min(-coeff_lerp * t, 1);
- float3 lerpVector = float3(rate, rate, rate);
- offset = lerp(lerpOffset, offset, lerpVector);
- }
-
- input.position = input.position + float4(offset.xyz, 0);
-
- output.position = mul(input.position, worldViewProjection);
-
- /**
- * lightVector - light vector
- * normal - normal vector
- * viewPosition - view vector (from camera)
- */
-
- // NOTE: In this case we do not need to multiply by any matrices since the
- // WORLD transformation matrix is the identity. If you were moving the
- // object such that the WORLD transform matrix was not the identity, you
- // would need to multiply the normal by the WORLDINVERSETTRANSFORM matrix
- // since the normal is in object space. Other values (light_pos, camera_pos)
- // are already in world space.
- float3 lightVector = light_pos - input.position.xyz;
- float3 normal = input.normal;
- float3 viewPosition = camera_pos - input.position.xyz;
-
- output.lightVector = lightVector;
- output.normal = normal;
- output.viewPosition = viewPosition;
- output.color = input.color;
- return output;
-}
-
-/**
- * Pixel Shader
- */
-float4 pixelShaderFunction(PixelShaderInput input): COLOR {
- float3 lightVector = normalize(input.lightVector);
- float3 normal = normalize(input.normal);
- float3 viewPosition = normalize(input.viewPosition);
- float3 halfVector = normalize(lightVector + viewPosition);
-
- // use lit function to calculate phong shading
- // x component contains the ambient coefficient
- // y component contains the diffuse coefficient:
- // max(dot(normal, lightVector),0)
- // z component contains the specular coefficient:
- // dot(normal, lightVector) < 0 || dot(normal, halfVector) < 0 ?
- // 0 : pow(dot(normal, halfVector), shininess)
- // NOTE: This is actually Blinn-Phong shading, not Phong shading
- // which would use the reflection vector instead of the half vector
-
- float4 phong_coeff = lit(dot(normal, lightVector),
- dot(normal, halfVector), shininess);
-
- float4 ambient = light_ambient * phong_coeff.x * input.color;
- float4 diffuse = light_diffuse * phong_coeff.y * input.color;
- float4 specular = light_specular * phong_coeff.z * input.color;
-
- return ambient + diffuse + specular;
-}
-
-// Here we tell our effect file *which* functions are
-// our vertex and pixel shaders.
-
-// #o3d VertexShaderEntryPoint vertexShaderFunction
-// #o3d PixelShaderEntryPoint pixelShaderFunction
-// #o3d MatrixLoadOrder RowMajor
- </textarea>
- </td>
- </tr>
-</table>
-</body>
-</html>
+<!-- @@REWRITE(insert html-copyright) --> +<!-- +O3D Siteswap animator +@@REWRITE(delete-start) +Author: Eric Uhrhane (ericu@google.com) +@@REWRITE(delete-end) +--> +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> +<meta http-equiv="content-type" content="text/html; charset=UTF-8"> +<title> + Site Swap Simulator +</title> +<style type="text/css"> + html, body { + height: 100%; + margin: 0; + padding: 0; + border: none; + } +</style> +<!-- Our javascript code --> +<script type="text/javascript" src="../o3djs/base.js"></script> +<script type="text/javascript" src="siteswap.js"></script> +<script type="text/javascript" src="math.js"></script> +<script type="text/javascript" src="animation.js"></script> +<script type="text/javascript" id="o3dscript"> + +o3djs.require('o3djs.util'); + +// Set up the client area. +function init() { + o3djs.util.setMainEngine(o3djs.util.Engine.V8); + o3djs.util.addScriptUri(''); // Allow V8 to load scripts in the cwd. + o3djs.util.makeClients(initStep2); + setUpSelection(); +} + +// Select the entire input pattern, so that the user can just type. +function setUpSelection() { + var input_pattern = document.getElementById('input_pattern'); + input_pattern.focus(); + input_pattern.selectionStart = 0; + input_pattern.selectionEnd = input_pattern.value.length; +} + +/* + * Wrappers to enable button presses to call through to the embedded V8 engine. + */ + +// Update whether we're animating or frozen based on the value of the checkbox. +function updateAnimatingWrapper() { + g.o3dElement.eval('updateAnimating()'); +} + +// Compute a new pattern. +function onComputePatternWrapper() { + g.o3dElement.eval('onComputePattern()'); +} + +// Adjust the view matrix to the new proportions of the plugin window. +// TODO: Switch to using the resize event once that's checked in. +function onResizeWrapper() { + g.o3dElement.eval('onResize()'); +} +window.onresize = onResizeWrapper; + +// Clean up all our callbacks, etc. +function cleanupWrapper() { + if (g && g.o3dElement) { + g.o3dElement.eval('cleanup()'); + } +} + +// The point of this function is to suppress form submit; we want to use the +// pattern entered when the user hits return, not submit the page to the +// webserver. +function suppressSubmit(event) { + onComputePatternWrapper(); // TODO: This suppresses form autocomplete storage. + return false; +} + +</script> +</head> +<body onload="init()" onunload="cleanupWrapper()"> +<table width="100%" style="height:100%;"> + <tr> + <td> + <h1>Juggler</h1> + This sample displays a site-swap juggling pattern with animation done by + a vertex shader. + <form name="the_form" onsubmit="return suppressSubmit(event)"> + <table> + <tr> + <td> + <table> + <tr> + <td> + <input + type="radio" + name="radio_group_hands" + value="1" + onclick=onComputePatternWrapper()> + 1 Hand<br> + <input + type="radio" + name="radio_group_hands" + value="2" + onclick=onComputePatternWrapper() + checked> + 2 Hands<br> + <input + type="radio" + name="radio_group_hands" + value="3" + onclick=onComputePatternWrapper()> + 3 Hands<br> + <input + type="radio" + name="radio_group_hands" + value="4" + onclick=onComputePatternWrapper()> + 4 Hands<br> + </td> + <td> + <input type="text" name="input_pattern" id="input_pattern" + value="3 4 5"> + </td> + <td> + <input type="checkbox" name="check_box" checked + onclick=updateAnimatingWrapper()>Animate + <input + type="checkbox" + name="pair_hands" + onclick=onComputePatternWrapper(); + >Pair Hands + </td> + <td> + <input type="button" name="computePattern" + value="Compute Pattern" + onclick=onComputePatternWrapper()> + </td> + </tr> + </table> + </td> + <td> + </td> + </tr> + </table> + </form> + <table id="container" width="90%" style="height:70%;"> + <tr> + <td height="100%"> + <!-- Start of g.o3d plugin --> + <div id="o3d" style="width: 100%; height: 100%;"></div> + <!-- End of g.o3d plugin --> + </td> + </tr> + </table> + <!-- a simple way to get a multiline string --> + <textarea id="shader" name="shader" cols="80" rows="20" + style="display: none;"> +// the 4x4 world view projection matrix +float4x4 worldViewProjection : WorldViewProjection; + +// positions of the light and camera +float3 light_pos; +float3 camera_pos; + +// phong lighting properties of the material +float4 light_ambient; +float4 light_diffuse; +float4 light_specular; + +// shininess of the material (for specular lighting) +float shininess; + +// time for animation +float time; + +// coefficients for a t^2 + b t + c for each of x, y, z +float3 coeff_a; +float3 coeff_b; +float3 coeff_c; + +// flag and coefficient for optional LERP with rate t * coeff_lerp; +float coeff_lerp; + +// coefficients for a t^2 + b t + c for each of x, y, z, for optional LERP +float3 coeff_l_a; +float3 coeff_l_b; +float3 coeff_l_c; + +// coefficients for d sin(f t) + e cos(e t) for each of x, y, z +float3 coeff_d; +float3 coeff_e; +float3 coeff_f; + +// to be subtracted from time to get the t for the above equation +float time_base; + +// input parameters for our vertex shader +struct VertexShaderInput { + float4 position : POSITION; + float3 normal : NORMAL; + float4 color : COLOR; +}; + +// input parameters for our pixel shader +// also the output parameters for our vertex shader +struct PixelShaderInput { + float4 position : POSITION; + float3 lightVector : TEXCOORD0; + float3 normal : TEXCOORD1; + float3 viewPosition : TEXCOORD2; + float4 color : COLOR; +}; + +/** + * Vertex Shader - vertex shader for phong illumination + */ +PixelShaderInput vertexShaderFunction(VertexShaderInput input) { + /** + * We use the standard phong illumination equation here. + * We restrict (clamp) the dot products so that we + * don't get any negative values. + * All vectors are normalized for proper calculations. + * + * The output color is the summation of the + * ambient, diffuse, and specular contributions. + * + * Note that we have to transform each vertex and normal + * by the world view projection matrix first. + */ + PixelShaderInput output; + + float t = time - time_base; + float3 offset = float3(0, 0, 0); + offset += t * t * coeff_a + t * coeff_b + coeff_c; + offset += coeff_d * sin(t * coeff_f); + offset += coeff_e * cos(t * coeff_f); + + float3 lerpOffset = t * t * coeff_l_a + t * coeff_l_b + coeff_l_c; + if (coeff_lerp > 0) { + float rate = min(coeff_lerp * t, 1); + float3 lerpVector = float3(rate, rate, rate); + offset = lerp(offset, lerpOffset, lerpVector); + } else if (coeff_lerp < 0) { + float rate = min(-coeff_lerp * t, 1); + float3 lerpVector = float3(rate, rate, rate); + offset = lerp(lerpOffset, offset, lerpVector); + } + + input.position = input.position + float4(offset.xyz, 0); + + output.position = mul(input.position, worldViewProjection); + + /** + * lightVector - light vector + * normal - normal vector + * viewPosition - view vector (from camera) + */ + + // NOTE: In this case we do not need to multiply by any matrices since the + // WORLD transformation matrix is the identity. If you were moving the + // object such that the WORLD transform matrix was not the identity, you + // would need to multiply the normal by the WORLDINVERSETTRANSFORM matrix + // since the normal is in object space. Other values (light_pos, camera_pos) + // are already in world space. + float3 lightVector = light_pos - input.position.xyz; + float3 normal = input.normal; + float3 viewPosition = camera_pos - input.position.xyz; + + output.lightVector = lightVector; + output.normal = normal; + output.viewPosition = viewPosition; + output.color = input.color; + return output; +} + +/** + * Pixel Shader + */ +float4 pixelShaderFunction(PixelShaderInput input): COLOR { + float3 lightVector = normalize(input.lightVector); + float3 normal = normalize(input.normal); + float3 viewPosition = normalize(input.viewPosition); + float3 halfVector = normalize(lightVector + viewPosition); + + // use lit function to calculate phong shading + // x component contains the ambient coefficient + // y component contains the diffuse coefficient: + // max(dot(normal, lightVector),0) + // z component contains the specular coefficient: + // dot(normal, lightVector) < 0 || dot(normal, halfVector) < 0 ? + // 0 : pow(dot(normal, halfVector), shininess) + // NOTE: This is actually Blinn-Phong shading, not Phong shading + // which would use the reflection vector instead of the half vector + + float4 phong_coeff = lit(dot(normal, lightVector), + dot(normal, halfVector), shininess); + + float4 ambient = light_ambient * phong_coeff.x * input.color; + float4 diffuse = light_diffuse * phong_coeff.y * input.color; + float4 specular = light_specular * phong_coeff.z * input.color; + + return ambient + diffuse + specular; +} + +// Here we tell our effect file *which* functions are +// our vertex and pixel shaders. + +// #o3d VertexShaderEntryPoint vertexShaderFunction +// #o3d PixelShaderEntryPoint pixelShaderFunction +// #o3d MatrixLoadOrder RowMajor + </textarea> + </td> + </tr> +</table> +</body> +</html> |