diff options
author | gman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-10 23:14:53 +0000 |
---|---|---|
committer | gman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-10 23:14:53 +0000 |
commit | a6974dc7ec62727d5edbbad9b49c052005e5193f (patch) | |
tree | 664297499f44a249d9684a33796be1a35926f0b4 /o3d | |
parent | 24a4d10647ee76bae3d977caba9e8b13b5b81cf4 (diff) | |
download | chromium_src-a6974dc7ec62727d5edbbad9b49c052005e5193f.zip chromium_src-a6974dc7ec62727d5edbbad9b49c052005e5193f.tar.gz chromium_src-a6974dc7ec62727d5edbbad9b49c052005e5193f.tar.bz2 |
Add Google IO sample.
Review URL: http://codereview.chromium.org/149438
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20437 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d')
23 files changed, 4899 insertions, 4 deletions
@@ -2,7 +2,7 @@ vars = { "chromium_trunk": "http://src.chromium.org/svn/trunk", "nixysa_rev": "25", - "o3d_code_rev": "89", + "o3d_code_rev": "91", } deps = { diff --git a/o3d/DEPS_gyp b/o3d/DEPS_gyp index 0fbc533..5afa3a2 100644 --- a/o3d/DEPS_gyp +++ b/o3d/DEPS_gyp @@ -3,7 +3,7 @@ vars = { "http://src.chromium.org/svn/trunk", "nixysa_rev": "25", "chromium_rev": "19057", - "o3d_code_rev": "87", + "o3d_code_rev": "91", } deps = { diff --git a/o3d/samples/GoogleIO-2009/assets/colorbar.png b/o3d/samples/GoogleIO-2009/assets/colorbar.png Binary files differnew file mode 100644 index 0000000..629c378 --- /dev/null +++ b/o3d/samples/GoogleIO-2009/assets/colorbar.png diff --git a/o3d/samples/GoogleIO-2009/assets/style.css b/o3d/samples/GoogleIO-2009/assets/style.css new file mode 100644 index 0000000..71fc441 --- /dev/null +++ b/o3d/samples/GoogleIO-2009/assets/style.css @@ -0,0 +1,8 @@ +html, body {
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ border: none;
+ font-family: Arial, sans-serif;
+}
+
diff --git a/o3d/samples/GoogleIO-2009/shaders/checker.shader b/o3d/samples/GoogleIO-2009/shaders/checker.shader new file mode 100644 index 0000000..a6c2ae8 --- /dev/null +++ b/o3d/samples/GoogleIO-2009/shaders/checker.shader @@ -0,0 +1,111 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// The 4x4 world view projection matrix. +float4x4 worldViewProjection : WORLDVIEWPROJECTION; +float4x4 worldInverseTranspose : WORLDINVERSETRANSPOSE; +float4x4 world : WORLD; + +// light position +float3 lightWorldPos; +float3 lightColor; + +// input parameters for our vertex shader +struct VertexShaderInput { + float4 position : POSITION; + float4 normal : NORMAL; + float2 texcoord : TEXCOORD0; +}; + +// input parameters for our pixel shader +struct PixelShaderInput { + float4 position : POSITION; + float2 texcoord : TEXCOORD0; + float3 normal : TEXCOORD1; + float3 worldPosition : TEXCOORD2; +}; + +// function for getting the checker pattern +float4 checker(float2 uv) { + float checkSize = 10; + float fmodResult = fmod(floor(checkSize * uv.x) + floor(checkSize * uv.y), + 2.0); + return (fmodResult < 1) ? + float4(0.4, 0.5, 0.5, 1) : + float4(0.6, 0.8, 0.8, 1); +} + +/** + * Our vertex shader. In the vertex shader, we calculate the lighting. + * Then we'll combine it with our checker pattern input the pixel shader. + */ +PixelShaderInput vertexShaderFunction(VertexShaderInput input) { + PixelShaderInput output; + + // Transform position into clip space. + output.position = mul(input.position, worldViewProjection); + + // Transform normal into world space, where we can do lighting + // calculations even if the world transform contains scaling. + output.normal = mul(input.normal, worldInverseTranspose).xyz; + + // Calculate surface position in world space. + output.worldPosition = mul(input.position, world).xyz; + + output.texcoord = input.texcoord; + + return output; +} + +/** + * Our pixel shader. We take the lighting color we got from the vertex sahder + * and combine it with our checker pattern. We only need to use the x + * coordinate of our input.col because we gave it uniform color + */ +float4 pixelShaderFunction(PixelShaderInput input): COLOR { + float3 surfaceToLight = normalize(lightWorldPos - input.worldPosition); + + float3 worldNormal = normalize(input.normal); + + // Apply diffuse lighting in world space in case the world transform + // contains scaling. + float4 check = checker(input.texcoord); + float4 directionalIntensity = saturate(dot(worldNormal, surfaceToLight)); + float4 outColor = directionalIntensity * check; + return float4(outColor.rgb, 1); +} + +// Here we tell our effect file *which* functions are +// our vertex and pixel shaders. + +// #o3d VertexShaderEntryPoint vertexShaderFunction +// #o3d PixelShaderEntryPoint pixelShaderFunction +// #o3d MatrixLoadOrder RowMajor diff --git a/o3d/samples/GoogleIO-2009/step01.html b/o3d/samples/GoogleIO-2009/step01.html new file mode 100644 index 0000000..d105a59 --- /dev/null +++ b/o3d/samples/GoogleIO-2009/step01.html @@ -0,0 +1,176 @@ +<!-- +Copyright 2009, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<!-- +Google I/O O3D Sample. + +This sample shows the steps to make a simple frame rate independent game. +--> +<!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> +Google I/O O3D Sample +</title> +<style type="text/css"> + html, body { + height: 100%; + margin: 0; + padding: 0; + border: none; + font-family: Arial, sans-serif; + } +</style> +<!-- Include sample javascript library functions--> +<script type="text/javascript" src="../o3djs/base.js"></script> + +<!-- Our javascript code --> +<script type="text/javascript"> +o3djs.require('o3djs.util'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.rendergraph'); + +// Events +// init() once the page has finished loading. +// unload() when the page is unloaded. +window.onload = init; +window.onunload= unload; + +// global variables +var g_o3dElement; +var g_o3d; +var g_math; +var g_client; +var g_viewInfo; +var g_pack; +var g_root; +var g_globalParams; +var g_o3dWidth; +var g_o3dHeight; +var g_o3dElement; +var g_eye = [15, 25, 50]; +var g_target = [0, 10, 0]; +var g_up = [0, 1, 0]; +var g_viewMatrix; + +/** + * Updates the projection matrix. + */ +function updateProjection() { + g_viewInfo.drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(45), // field of view. + g_o3dWidth / g_o3dHeight, // aspect ratio + 0.1, // Near plane. + 5000); // Far plane. +} + +/* + * Updates the camera. + */ +function updateCamera() { + g_viewMatrix = g_math.matrix4.lookAt(g_eye, g_target, g_up); + g_viewInfo.drawContext.view = g_viewMatrix; +}; + +/** + * Updates global variables of the client's size if they have changed. + */ +function updateClientSize() { + var newWidth = g_client.width; + var newHeight = g_client.height; + if (g_o3dWidth != newWidth || g_o3dHeight != newHeight) { + g_o3dWidth = newWidth; + g_o3dHeight = newHeight; + updateProjection(); + } +} + +/** + * Creates the client area. + */ +function init() { + o3djs.util.makeClients(initStep2); +} + +/** + * Initializes O3D and creates one shape. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + g_o3dElement = clientElements[0]; + g_o3d = g_o3dElement.o3d; + g_math = o3djs.math; + g_client = g_o3dElement.client; + + // Creates a pack to manage our resources/assets + g_pack = g_client.createPack(); + + g_root = g_pack.createObject('Transform'); + + g_viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_root, + g_client.renderGraphRoot); + + updateClientSize(); + updateCamera(); + + window.g_finished = true; // for selenium testing. +} + +/** + * Remove any callbacks so they don't get called after the page has unloaded. + */ +function unload() { + if (g_client) { + g_client.cleanup(); + } +} +</script> +</head> +<body> +<table style="width: 100%; height:100%;"> + <tr style="height: 50px;"><td> + <div style="width: 100%; height: 50px; font-size: large;"> + <img src="assets/colorbar.png" width="100%" height="10px"/><br/> + Google I/O 2009 O3D Sample + </div> + </td></tr> + <tr style="height: 100%;"><td> + <div style="width: 100%; height: 100%;"> + <div id="o3d" style="width: 100%; height: 100%;"></div> + </div> + </td></tr> +</table> +</body> +</html> diff --git a/o3d/samples/GoogleIO-2009/step02.html b/o3d/samples/GoogleIO-2009/step02.html new file mode 100644 index 0000000..74f3b0f --- /dev/null +++ b/o3d/samples/GoogleIO-2009/step02.html @@ -0,0 +1,206 @@ +<!-- +Copyright 2009, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<!-- +Google I/O O3D Sample. + +This sample shows the steps to make a simple frame rate independent game. +--> +<!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> +Google I/O O3D Sample +</title> +<style type="text/css"> + html, body { + height: 100%; + margin: 0; + padding: 0; + border: none; + font-family: Arial, sans-serif; + } +</style> +<!-- Include sample javascript library functions--> +<script type="text/javascript" src="../o3djs/base.js"></script> + +<!-- Our javascript code --> +<script type="text/javascript"> +o3djs.require('o3djs.util'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.primitives'); +o3djs.require('o3djs.material'); + +// Events +// init() once the page has finished loading. +// unload() when the page is unloaded. +window.onload = init; +window.onunload= unload; + +// global variables +var g_o3dElement; +var g_o3d; +var g_math; +var g_client; +var g_viewInfo; +var g_pack; +var g_root; +var g_playerTransform; +var g_globalParams; +var g_o3dWidth; +var g_o3dHeight; +var g_o3dElement; +var g_eye = [15, 25, 50]; +var g_target = [0, 10, 0]; +var g_up = [0, 1, 0]; +var g_viewMatrix; + +/** + * Updates the projection matrix. + */ +function updateProjection() { + g_viewInfo.drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(45), // field of view. + g_o3dWidth / g_o3dHeight, // aspect ratio + 0.1, // Near plane. + 5000); // Far plane. +} + +/* + * Updates the camera. + */ +function updateCamera() { + g_viewMatrix = g_math.matrix4.lookAt(g_eye, g_target, g_up); + g_viewInfo.drawContext.view = g_viewMatrix; +}; + +/** + * Updates global variables of the client's size if they have changed. + */ +function updateClientSize() { + var newWidth = g_client.width; + var newHeight = g_client.height; + if (g_o3dWidth != newWidth || g_o3dHeight != newHeight) { + g_o3dWidth = newWidth; + g_o3dHeight = newHeight; + updateProjection(); + } +} + +/** + * Creates the client area. + */ +function init() { + o3djs.util.makeClients(initStep2); +} + +/** + * Initializes O3D and creates one shape. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + g_o3dElement = clientElements[0]; + g_o3d = g_o3dElement.o3d; + g_math = o3djs.math; + g_client = g_o3dElement.client; + + // Creates a pack to manage our resources/assets + g_pack = g_client.createPack(); + + g_root = g_pack.createObject('Transform'); + + g_viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_root, + g_client.renderGraphRoot); + + updateClientSize(); + updateCamera(); + + var redMaterial = o3djs.material.createBasicMaterial( + g_pack, + g_viewInfo, + [0.2, 1, 0.2, 1]); // green + + var checkerMaterial = o3djs.material.createMaterialFromFile( + g_pack, 'shaders/checker.shader', g_viewInfo.performanceDrawList); + + g_globalParams = o3djs.material.createAndBindStandardParams(g_pack); + g_globalParams.lightWorldPos.value = [30, 60, 40]; + g_globalParams.lightColor.value = [1, 1, 1, 1]; + + // Create a ground plane. + var shape = o3djs.primitives.createPlane( + g_pack, checkerMaterial, 100, 100, 10, 10); + var transform = g_pack.createObject('Transform'); + transform.parent = g_root; + transform.addShape(shape); + + // Create a cylinder. + var shape = o3djs.primitives.createCylinder( + g_pack, redMaterial, 2.5, 5, 20, 1, + g_math.matrix4.translation([0, 2.5, 0])); + g_playerTransform = g_pack.createObject('Transform'); + g_playerTransform.parent = g_root; + g_playerTransform.addShape(shape); + + window.g_finished = true; // for selenium testing. +} + +/** + * Remove any callbacks so they don't get called after the page has unloaded. + */ +function unload() { + if (g_client) { + g_client.cleanup(); + } +} +</script> +</head> +<body> +<table style="width: 100%; height:100%;"> + <tr style="height: 50px;"><td> + <div style="width: 100%; height: 50px; font-size: large;"> + <img src="assets/colorbar.png" width="100%" height="10px"/><br/> + Google I/O 2009 O3D Sample + </div> + </td></tr> + <tr style="height: 100%;"><td> + <div style="width: 100%; height: 100%;"> + <div id="o3d" style="width: 100%; height: 100%;"></div> + </div> + </td></tr> +</table> +</body> +</html> diff --git a/o3d/samples/GoogleIO-2009/step03.html b/o3d/samples/GoogleIO-2009/step03.html new file mode 100644 index 0000000..8f6aaa9 --- /dev/null +++ b/o3d/samples/GoogleIO-2009/step03.html @@ -0,0 +1,254 @@ +<!-- +Copyright 2009, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<!-- +Google I/O O3D Sample. + +This sample shows the steps to make a simple frame rate independent game. +--> +<!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> +Google I/O O3D Sample +</title> +<link rel="stylesheet" type="text/css" href="assets/style.css" /> +<!-- Include sample javascript library functions--> +<script type="text/javascript" src="../o3djs/base.js"></script> + +<!-- Our javascript code --> +<script type="text/javascript"> +o3djs.require('o3djs.util'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.primitives'); +o3djs.require('o3djs.material'); + +// Events +// init() once the page has finished loading. +// unload() when the page is unloaded. +window.onload = init; +window.onunload= unload; + +// global variables +var g_o3dElement; +var g_o3d; +var g_math; +var g_client; +var g_viewInfo; +var g_pack; +var g_root; +var g_globalParams; +var g_o3dWidth; +var g_o3dHeight; +var g_o3dElement; +var g_keyDown = []; // which keys are down by key code. +var g_playerTransform; +var g_playerXPosition = 0; +var g_playerZPosition = 0; +var g_eye = [15, 25, 50]; +var g_target = [0, 10, 0]; +var g_up = [0, 1, 0]; +var g_viewMatrix; + +/** + * Updates the projection matrix. + */ +function updateProjection() { + g_viewInfo.drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(45), // field of view. + g_o3dWidth / g_o3dHeight, // aspect ratio + 0.1, // Near plane. + 5000); // Far plane. +} + +/* + * Updates the camera. + */ +function updateCamera() { + g_viewMatrix = g_math.matrix4.lookAt(g_eye, g_target, g_up); + g_viewInfo.drawContext.view = g_viewMatrix; +}; + +/** + * Updates global variables of the client's size if they have changed. + */ +function updateClientSize() { + var newWidth = g_client.width; + var newHeight = g_client.height; + if (g_o3dWidth != newWidth || g_o3dHeight != newHeight) { + g_o3dWidth = newWidth; + g_o3dHeight = newHeight; + updateProjection(); + } +} + +/** + * Creates the client area. + */ +function init() { + o3djs.util.makeClients(initStep2); +} + +/** + * Initializes O3D and creates one shape. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + g_o3dElement = clientElements[0]; + g_o3d = g_o3dElement.o3d; + g_math = o3djs.math; + g_client = g_o3dElement.client; + + // Creates a pack to manage our resources/assets + g_pack = g_client.createPack(); + + g_root = g_pack.createObject('Transform'); + + g_viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_root, + g_client.renderGraphRoot); + + updateCamera(); + + var redMaterial = o3djs.material.createBasicMaterial( + g_pack, + g_viewInfo, + [0.2, 1, 0.2, 1]); // green + + var checkerMaterial = o3djs.material.createMaterialFromFile( + g_pack, 'shaders/checker.shader', g_viewInfo.performanceDrawList); + + g_globalParams = o3djs.material.createAndBindStandardParams(g_pack); + g_globalParams.lightWorldPos.value = [30, 60, 40]; + g_globalParams.lightColor.value = [1, 1, 1, 1]; + + // Create a ground plane. + var shape = o3djs.primitives.createPlane( + g_pack, checkerMaterial, 100, 100, 10, 10); + var transform = g_pack.createObject('Transform'); + transform.parent = g_root; + transform.addShape(shape); + + // Create a cylinder. + var shape = o3djs.primitives.createCylinder( + g_pack, redMaterial, 2.5, 5, 20, 1, + g_math.matrix4.translation([0, 2.5, 0])); + var transform = g_pack.createObject('Transform'); + transform.parent = g_root; + transform.addShape(shape); + + g_playerTransform = transform; + + // Setup a render callback for per frame processing. + g_client.setRenderCallback(onRender); + + o3djs.event.addEventListener(g_o3dElement, 'keydown', onKeyDown); + o3djs.event.addEventListener(g_o3dElement, 'keyup', onKeyUp); + + window.g_finished = true; // for selenium testing. +} + +/** + * Tracks key down events. + * @param {Event} e keyboard event. + */ +function onKeyDown(e) { + g_keyDown[e.keyCode] = true; +} + +/** + * Tracks key up events. + * @param {Event} e keyboard event. + */ +function onKeyUp(e) { + g_keyDown[e.keyCode] = false; +} + +/** + * Look at keys. + */ +function handleMoveKeys() { + var directionX = 0; + var directionZ = 0; + + if (g_keyDown[37] || g_keyDown[65]) { directionX = -3; } + if (g_keyDown[39] || g_keyDown[68]) { directionX = 3; } + if (g_keyDown[38] || g_keyDown[87]) { directionZ = -3; } + if (g_keyDown[40] || g_keyDown[83]) { directionZ = 3; } + + g_playerXPosition += directionX; + g_playerZPosition += directionZ; + + g_playerTransform.identity(); + g_playerTransform.translate(g_playerXPosition, 0, g_playerZPosition); +} + +/** + * Called every frame. + * @param {!o3d.RenderEvent} renderEvent Rendering Information. + */ +function onRender(renderEvent) { + var elapsedTime = renderEvent.elapsedTime; + + updateClientSize(); + handleMoveKeys(); +}; + +/** + * Remove any callbacks so they don't get called after the page has unloaded. + */ +function unload() { + if (g_client) { + g_client.cleanup(); + } +} +</script> +</head> +<body> +<table style="width: 100%; height:100%;"> + <tr style="height: 50px;"><td> + <div style="width: 100%; height: 50px; font-size: large;"> + <img src="assets/colorbar.png" width="100%" height="10px"/><br/> + Google I/O 2009 O3D Sample + </div> + </td></tr> + <tr style="height: 100%;"><td> + <div style="width: 100%; height: 100%;"> + <div id="o3d" style="width: 100%; height: 100%;"></div> + </div> + </td></tr> +</table> +</body> +</html> diff --git a/o3d/samples/GoogleIO-2009/step04.html b/o3d/samples/GoogleIO-2009/step04.html new file mode 100644 index 0000000..93bd8ed --- /dev/null +++ b/o3d/samples/GoogleIO-2009/step04.html @@ -0,0 +1,264 @@ +<!-- +Copyright 2009, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<!-- +Google I/O O3D Sample. + +This sample shows the steps to make a simple frame rate independent game. +--> +<!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> +Google I/O O3D Sample +</title> +<style type="text/css"> + html, body { + height: 100%; + margin: 0; + padding: 0; + border: none; + font-family: Arial, sans-serif; + } +</style> +<!-- Include sample javascript library functions--> +<script type="text/javascript" src="../o3djs/base.js"></script> + +<!-- Our javascript code --> +<script type="text/javascript"> +o3djs.require('o3djs.util'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.primitives'); +o3djs.require('o3djs.material'); + +// Events +// init() once the page has finished loading. +// unload() when the page is unloaded. +window.onload = init; +window.onunload= unload; + +// constants +var MOVE_VELOCITY = 25; // in units per second. + +// global variables +var g_o3dElement; +var g_o3d; +var g_math; +var g_client; +var g_viewInfo; +var g_pack; +var g_globalParams; +var g_o3dWidth; +var g_o3dHeight; +var g_o3dElement; +var g_keyDown = []; // which keys are down by key code. +var g_playerTransform; +var g_playerXPosition = 0; +var g_playerZPosition = 0; +var g_eye = [15, 25, 50]; +var g_target = [0, 10, 0]; +var g_up = [0, 1, 0]; +var g_viewMatrix; + +/** + * Updates the projection matrix. + */ +function updateProjection() { + g_viewInfo.drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(45), // field of view. + g_o3dWidth / g_o3dHeight, // aspect ratio + 0.1, // Near plane. + 5000); // Far plane. +} + +/* + * Updates the camera. + */ +function updateCamera() { + g_viewMatrix = g_math.matrix4.lookAt(g_eye, g_target, g_up); + g_viewInfo.drawContext.view = g_viewMatrix; +}; + +/** + * Updates global variables of the client's size if they have changed. + */ +function updateClientSize() { + var newWidth = g_client.width; + var newHeight = g_client.height; + if (g_o3dWidth != newWidth || g_o3dHeight != newHeight) { + g_o3dWidth = newWidth; + g_o3dHeight = newHeight; + updateProjection(); + } +} + +/** + * Creates the client area. + */ +function init() { + o3djs.util.makeClients(initStep2); +} + +/** + * Initializes O3D and creates one shape. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + g_o3dElement = clientElements[0]; + g_o3d = g_o3dElement.o3d; + g_math = o3djs.math; + g_client = g_o3dElement.client; + + // Creates a pack to manage our resources/assets + g_pack = g_client.createPack(); + + g_root = g_pack.createObject('Transform'); + + g_viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_root, + g_client.renderGraphRoot); + + updateCamera(); + + var redMaterial = o3djs.material.createBasicMaterial( + g_pack, + g_viewInfo, + [0.2, 1, 0.2, 1]); // green + + var checkerMaterial = o3djs.material.createMaterialFromFile( + g_pack, 'shaders/checker.shader', g_viewInfo.performanceDrawList); + + g_globalParams = o3djs.material.createAndBindStandardParams(g_pack); + g_globalParams.lightWorldPos.value = [30, 60, 40]; + g_globalParams.lightColor.value = [1, 1, 1, 1]; + + // Create a ground plane. + var shape = o3djs.primitives.createPlane( + g_pack, checkerMaterial, 100, 100, 10, 10); + var transform = g_pack.createObject('Transform'); + transform.parent = g_root; + transform.addShape(shape); + + // Create a cylinder. + var shape = o3djs.primitives.createCylinder( + g_pack, redMaterial, 2.5, 5, 20, 1, + g_math.matrix4.translation([0, 2.5, 0])); + var transform = g_pack.createObject('Transform'); + transform.parent = g_root; + transform.addShape(shape); + + g_playerTransform = transform; + + // Setup a render callback for per frame processing. + g_client.setRenderCallback(onRender); + + o3djs.event.addEventListener(g_o3dElement, 'keydown', onKeyDown); + o3djs.event.addEventListener(g_o3dElement, 'keyup', onKeyUp); + + window.g_finished = true; // for selenium testing. +} + +/** + * Tracks key down events. + * @param {Event} e keyboard event. + */ +function onKeyDown(e) { + g_keyDown[e.keyCode] = true; +} + +/** + * Tracks key up events. + * @param {Event} e keyboard event. + */ +function onKeyUp(e) { + g_keyDown[e.keyCode] = false; +} + +/** + * Look at keys. + */ +function handleMoveKeys(elapsedTime) { + var directionX = 0; + var directionZ = 0; + + if (g_keyDown[37] || g_keyDown[65]) { directionX = -1; } + if (g_keyDown[39] || g_keyDown[68]) { directionX = 1; } + if (g_keyDown[38] || g_keyDown[87]) { directionZ = -1; } + if (g_keyDown[40] || g_keyDown[83]) { directionZ = 1; } + + g_playerXPosition += MOVE_VELOCITY * directionX * elapsedTime; + g_playerZPosition += MOVE_VELOCITY * directionZ * elapsedTime; + + g_playerTransform.identity(); + g_playerTransform.translate(g_playerXPosition, 0, g_playerZPosition); +} + +/** + * Called every frame. + * @param {!o3d.RenderEvent} renderEvent Rendering Information. + */ +function onRender(renderEvent) { + var elapsedTime = renderEvent.elapsedTime; + + updateClientSize(); + handleMoveKeys(elapsedTime); +}; + +/** + * Remove any callbacks so they don't get called after the page has unloaded. + */ +function unload() { + if (g_client) { + g_client.cleanup(); + } +} +</script> +</head> +<body> +<table style="width: 100%; height:100%;"> + <tr style="height: 50px;"><td> + <div style="width: 100%; height: 50px; font-size: large;"> + <img src="assets/colorbar.png" width="100%" height="10px"/><br/> + Google I/O 2009 O3D Sample + </div> + </td></tr> + <tr style="height: 100%;"><td> + <div style="width: 100%; height: 100%;"> + <div id="o3d" style="width: 100%; height: 100%;"></div> + </div> + </td></tr> +</table> +</body> +</html> diff --git a/o3d/samples/GoogleIO-2009/step05.html b/o3d/samples/GoogleIO-2009/step05.html new file mode 100644 index 0000000..2c79086 --- /dev/null +++ b/o3d/samples/GoogleIO-2009/step05.html @@ -0,0 +1,292 @@ +<!-- +Copyright 2009, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<!-- +Google I/O O3D Sample. + +This sample shows the steps to make a simple frame rate independent game. +--> +<!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> +Google I/O O3D Sample +</title> +<style type="text/css"> + html, body { + height: 100%; + margin: 0; + padding: 0; + border: none; + font-family: Arial, sans-serif; + } +</style> +<!-- Include sample javascript library functions--> +<script type="text/javascript" src="../o3djs/base.js"></script> + +<!-- Our javascript code --> +<script type="text/javascript"> +o3djs.require('o3djs.util'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.primitives'); +o3djs.require('o3djs.material'); + +// Events +// init() once the page has finished loading. +// unload() when the page is unloaded. +window.onload = init; +window.onunload= unload; + +// constants +var MOVE_VELOCITY = 25; // in units per second. + +// global variables +var g_o3dElement; +var g_o3d; +var g_math; +var g_client; +var g_viewInfo; +var g_pack; +var g_root; +var g_globalParams; +var g_o3dWidth; +var g_o3dHeight; +var g_o3dElement; +var g_keyDown = []; // which keys are down by key code. +var g_playerTransform; +var g_playerXPosition = 0; +var g_playerZPosition = 0; +var g_eye = [15, 25, 50]; +var g_target = [0, 10, 0]; +var g_up = [0, 1, 0]; +var g_viewMatrix; +var g_moveMatrix; + +/** + * Updates the projection matrix. + */ +function updateProjection() { + g_viewInfo.drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(45), // field of view. + g_o3dWidth / g_o3dHeight, // aspect ratio + 0.1, // Near plane. + 5000); // Far plane. +} + +/** + * Given a view matrix computes an movement matrix to make it easy + * to move something relative to the camera view in the XZ plane. + * @param {!o3djs.math.Matrix4} viewMatrix A view matrix. + * @return {!o3djs.math.Matrix4} A movement matrix. + */ +function computeMoveMatrixFromViewMatrix(viewMatrix) { + var cameraMatrix = g_math.matrix4.inverse(viewMatrix); + var xAxis = g_math.cross([0, 1, 0], cameraMatrix[2].slice(0, 3)); + var zAxis = g_math.cross(xAxis, [0, 1, 0]); + return [ + xAxis.concat(0), + [0, 1, 0, 0], + zAxis.concat(0), + [0, 0, 0, 1]]; +} + +/* + * Updates the camera. + */ +function updateCamera() { + g_viewMatrix = g_math.matrix4.lookAt(g_eye, g_target, g_up); + g_viewInfo.drawContext.view = g_viewMatrix; + g_moveMatrix = computeMoveMatrixFromViewMatrix(g_viewMatrix); +}; + +/** + * Updates global variables of the client's size if they have changed. + */ +function updateClientSize() { + var newWidth = g_client.width; + var newHeight = g_client.height; + if (g_o3dWidth != newWidth || g_o3dHeight != newHeight) { + g_o3dWidth = newWidth; + g_o3dHeight = newHeight; + updateProjection(); + } +} + +/** + * Creates the client area. + */ +function init() { + o3djs.util.makeClients(initStep2); +} + +/** + * Initializes O3D and creates one shape. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + g_o3dElement = clientElements[0]; + g_o3d = g_o3dElement.o3d; + g_math = o3djs.math; + g_client = g_o3dElement.client; + + // Creates a pack to manage our resources/assets + g_pack = g_client.createPack(); + + g_root = g_pack.createObject('Transform'); + + g_viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_root, + g_client.renderGraphRoot); + + updateCamera(); + + var redMaterial = o3djs.material.createBasicMaterial( + g_pack, + g_viewInfo, + [0.2, 1, 0.2, 1]); // green + + var checkerMaterial = o3djs.material.createMaterialFromFile( + g_pack, 'shaders/checker.shader', g_viewInfo.performanceDrawList); + + g_globalParams = o3djs.material.createAndBindStandardParams(g_pack); + g_globalParams.lightWorldPos.value = [30, 60, 40]; + g_globalParams.lightColor.value = [1, 1, 1, 1]; + + // Create a ground plane. + var shape = o3djs.primitives.createPlane( + g_pack, checkerMaterial, 100, 100, 10, 10); + var transform = g_pack.createObject('Transform'); + transform.parent = g_root; + transform.addShape(shape); + + // Create a cylinder. + var shape = o3djs.primitives.createCylinder( + g_pack, redMaterial, 2.5, 5, 20, 1, + g_math.matrix4.translation([0, 2.5, 0])); + var transform = g_pack.createObject('Transform'); + transform.parent = g_root; + transform.addShape(shape); + + g_playerTransform = transform; + + // Setup a render callback for per frame processing. + g_client.setRenderCallback(onRender); + + o3djs.event.addEventListener(g_o3dElement, 'keydown', onKeyDown); + o3djs.event.addEventListener(g_o3dElement, 'keyup', onKeyUp); + + window.g_finished = true; // for selenium testing. +} + +/** + * Tracks key down events. + * @param {Event} e keyboard event. + */ +function onKeyDown(e) { + g_keyDown[e.keyCode] = true; +} + +/** + * Tracks key up events. + * @param {Event} e keyboard event. + */ +function onKeyUp(e) { + g_keyDown[e.keyCode] = false; +} + +/** + * Look at keys. + */ +function handleMoveKeys(elapsedTime) { + var directionX = 0; + var directionZ = 0; + + if (g_keyDown[37] || g_keyDown[65]) { directionX = -1; } + if (g_keyDown[39] || g_keyDown[68]) { directionX = 1; } + if (g_keyDown[38] || g_keyDown[87]) { directionZ = -1; } + if (g_keyDown[40] || g_keyDown[83]) { directionZ = 1; } + + if (directionX != 0 || directionZ != 0) { + var moveTranslation = g_math.matrix4.transformPoint( + g_moveMatrix, + [MOVE_VELOCITY * directionX * elapsedTime, + 0, + MOVE_VELOCITY * directionZ * elapsedTime]); + + g_playerXPosition += moveTranslation[0]; + g_playerZPosition += moveTranslation[2]; + + g_playerTransform.identity(); + g_playerTransform.translate(g_playerXPosition, 0, g_playerZPosition); + } +} + +/** + * Called every frame. + * @param {!o3d.RenderEvent} renderEvent Rendering Information. + */ +function onRender(renderEvent) { + var elapsedTime = renderEvent.elapsedTime; + + updateClientSize(); + handleMoveKeys(elapsedTime); +}; + +/** + * Remove any callbacks so they don't get called after the page has unloaded. + */ +function unload() { + if (g_client) { + g_client.cleanup(); + } +} +</script> +</head> +<body> +<table style="width: 100%; height:100%;"> + <tr style="height: 50px;"><td> + <div style="width: 100%; height: 50px; font-size: large;"> + <img src="assets/colorbar.png" width="100%" height="10px"/><br/> + Google I/O 2009 O3D Sample + </div> + </td></tr> + <tr style="height: 100%;"><td> + <div style="width: 100%; height: 100%;"> + <div id="o3d" style="width: 100%; height: 100%;"></div> + </div> + </td></tr> +</table> +</body> +</html> diff --git a/o3d/samples/GoogleIO-2009/step06.html b/o3d/samples/GoogleIO-2009/step06.html new file mode 100644 index 0000000..131ff43 --- /dev/null +++ b/o3d/samples/GoogleIO-2009/step06.html @@ -0,0 +1,301 @@ +<!-- +Copyright 2009, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<!-- +Google I/O O3D Sample. + +This sample shows the steps to make a simple frame rate independent game. +--> +<!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> +Google I/O O3D Sample +</title> +<style type="text/css"> + html, body { + height: 100%; + margin: 0; + padding: 0; + border: none; + font-family: Arial, sans-serif; + } +</style> +<!-- Include sample javascript library functions--> +<script type="text/javascript" src="../o3djs/base.js"></script> + +<!-- Our javascript code --> +<script type="text/javascript"> +o3djs.require('o3djs.util'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.primitives'); +o3djs.require('o3djs.material'); + +// Events +// init() once the page has finished loading. +// unload() when the page is unloaded. +window.onload = init; +window.onunload= unload; + +// constants +var MOVE_VELOCITY = 25; // in units per second. + +// global variables +var g_o3dElement; +var g_o3d; +var g_math; +var g_client; +var g_viewInfo; +var g_pack; +var g_root; +var g_globalParams; +var g_o3dWidth; +var g_o3dHeight; +var g_o3dElement; +var g_keyDown = []; // which keys are down by key code. +var g_playerTransform; +var g_playerXPosition = 0; +var g_playerZPosition = 0; +var g_eye = [15, 25, 50]; +var g_target = [0, 10, 0]; +var g_up = [0, 1, 0]; +var g_viewMatrix; +var g_moveMatrix; + +/** + * Updates the projection matrix. + */ +function updateProjection() { + g_viewInfo.drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(45), // field of view. + g_o3dWidth / g_o3dHeight, // aspect ratio + 0.1, // Near plane. + 5000); // Far plane. +} + +/** + * Given a view matrix computes an movement matrix to make it easy + * to move something relative to the camera view in the XZ plane. + * @param {!o3djs.math.Matrix4} viewMatrix A view matrix. + * @return {!o3djs.math.Matrix4} A movement matrix. + */ +function computeMoveMatrixFromViewMatrix(viewMatrix) { + var cameraMatrix = g_math.matrix4.inverse(viewMatrix); + var xAxis = g_math.cross([0, 1, 0], cameraMatrix[2].slice(0, 3)); + var zAxis = g_math.cross(xAxis, [0, 1, 0]); + return [ + xAxis.concat(0), + [0, 1, 0, 0], + zAxis.concat(0), + [0, 0, 0, 1]]; +} + +/* + * Updates the camera. + */ +function updateCamera() { + g_viewMatrix = g_math.matrix4.lookAt(g_eye, g_target, g_up); + g_viewInfo.drawContext.view = g_viewMatrix; + g_moveMatrix = computeMoveMatrixFromViewMatrix(g_viewMatrix); +}; + +/** + * Updates global variables of the client's size if they have changed. + */ +function updateClientSize() { + var newWidth = g_client.width; + var newHeight = g_client.height; + if (g_o3dWidth != newWidth || g_o3dHeight != newHeight) { + g_o3dWidth = newWidth; + g_o3dHeight = newHeight; + updateProjection(); + } +} + +/** + * Creates the client area. + */ +function init() { + o3djs.util.makeClients(initStep2); +} + +/** + * Initializes O3D and creates one shape. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + g_o3dElement = clientElements[0]; + g_o3d = g_o3dElement.o3d; + g_math = o3djs.math; + g_client = g_o3dElement.client; + + // Creates a pack to manage our resources/assets + g_pack = g_client.createPack(); + + g_root = g_pack.createObject('Transform'); + + g_viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_root, + g_client.renderGraphRoot); + + updateCamera(); + + var redMaterial = o3djs.material.createBasicMaterial( + g_pack, + g_viewInfo, + [0.2, 1, 0.2, 1]); // green + + var checkerMaterial = o3djs.material.createMaterialFromFile( + g_pack, 'shaders/checker.shader', g_viewInfo.performanceDrawList); + + g_globalParams = o3djs.material.createAndBindStandardParams(g_pack); + g_globalParams.lightWorldPos.value = [30, 60, 40]; + g_globalParams.lightColor.value = [1, 1, 1, 1]; + + // Create a ground plane. + var shape = o3djs.primitives.createPlane( + g_pack, checkerMaterial, 100, 100, 10, 10); + var transform = g_pack.createObject('Transform'); + transform.parent = g_root; + transform.addShape(shape); + + // Create a cylinder. + var shape = o3djs.primitives.createCylinder( + g_pack, redMaterial, 2.5, 5, 20, 1, + g_math.matrix4.translation([0, 2.5, 0])); + var transform = g_pack.createObject('Transform'); + transform.parent = g_root; + transform.addShape(shape); + + g_playerTransform = transform; + + // Setup a render callback for per frame processing. + g_client.setRenderCallback(onRender); + + o3djs.event.addEventListener(g_o3dElement, 'keydown', onKeyDown); + o3djs.event.addEventListener(g_o3dElement, 'keyup', onKeyUp); + + window.g_finished = true; // for selenium testing. +} + +/** + * Tracks key down events. + * @param {Event} e keyboard event. + */ +function onKeyDown(e) { + g_keyDown[e.keyCode] = true; +} + +/** + * Tracks key up events. + * @param {Event} e keyboard event. + */ +function onKeyUp(e) { + g_keyDown[e.keyCode] = false; +} + +/** + * Look at keys. + */ +function handleMoveKeys(elapsedTime) { + var directionX = 0; + var directionZ = 0; + + if (g_keyDown[37] || g_keyDown[65]) { directionX = -1; } + if (g_keyDown[39] || g_keyDown[68]) { directionX = 1; } + if (g_keyDown[38] || g_keyDown[87]) { directionZ = -1; } + if (g_keyDown[40] || g_keyDown[83]) { directionZ = 1; } + + if (directionX != 0 || directionZ != 0) { + var moveTranslation = g_math.matrix4.transformPoint( + g_moveMatrix, + [MOVE_VELOCITY * directionX * elapsedTime, + 0, + MOVE_VELOCITY * directionZ * elapsedTime]); + + g_playerXPosition += moveTranslation[0]; + g_playerZPosition += moveTranslation[2]; + + g_playerTransform.identity(); + g_playerTransform.translate(g_playerXPosition, 0, g_playerZPosition); + } +} + +/** + * Move the camera. + */ +function moveCamera() { + g_target = [g_playerXPosition, 10, g_playerZPosition]; + updateCamera(); +} + +/** + * Called every frame. + * @param {!o3d.RenderEvent} renderEvent Rendering Information. + */ +function onRender(renderEvent) { + var elapsedTime = renderEvent.elapsedTime; + + updateClientSize(); + handleMoveKeys(elapsedTime); + moveCamera(); +}; + +/** + * Remove any callbacks so they don't get called after the page has unloaded. + */ +function unload() { + if (g_client) { + g_client.cleanup(); + } +} +</script> +</head> +<body> +<table style="width: 100%; height:100%;"> + <tr style="height: 50px;"><td> + <div style="width: 100%; height: 50px; font-size: large;"> + <img src="assets/colorbar.png" width="100%" height="10px"/><br/> + Google I/O 2009 O3D Sample + </div> + </td></tr> + <tr style="height: 100%;"><td> + <div style="width: 100%; height: 100%;"> + <div id="o3d" style="width: 100%; height: 100%;"></div> + </div> + </td></tr> +</table> +</body> +</html> diff --git a/o3d/samples/GoogleIO-2009/step07.html b/o3d/samples/GoogleIO-2009/step07.html new file mode 100644 index 0000000..4c61f93 --- /dev/null +++ b/o3d/samples/GoogleIO-2009/step07.html @@ -0,0 +1,302 @@ +<!-- +Copyright 2009, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<!-- +Google I/O O3D Sample. + +This sample shows the steps to make a simple frame rate independent game. +--> +<!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> +Google I/O O3D Sample +</title> +<style type="text/css"> + html, body { + height: 100%; + margin: 0; + padding: 0; + border: none; + font-family: Arial, sans-serif; + } +</style> +<!-- Include sample javascript library functions--> +<script type="text/javascript" src="../o3djs/base.js"></script> + +<!-- Our javascript code --> +<script type="text/javascript"> +o3djs.require('o3djs.util'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.primitives'); +o3djs.require('o3djs.material'); + +// Events +// init() once the page has finished loading. +// unload() when the page is unloaded. +window.onload = init; +window.onunload= unload; + +// constants +var MOVE_VELOCITY = 25; // in units per second. + +// global variables +var g_o3dElement; +var g_o3d; +var g_math; +var g_client; +var g_viewInfo; +var g_pack; +var g_root; +var g_globalParams; +var g_o3dWidth; +var g_o3dHeight; +var g_o3dElement; +var g_keyDown = []; // which keys are down by key code. +var g_playerTransform; +var g_playerXPosition = 0; +var g_playerZPosition = 0; +var g_eye = [15, 25, 50]; +var g_target = [0, 10, 0]; +var g_up = [0, 1, 0]; +var g_viewMatrix; +var g_moveMatrix; + +/** + * Updates the projection matrix. + */ +function updateProjection() { + g_viewInfo.drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(45), // field of view. + g_o3dWidth / g_o3dHeight, // aspect ratio + 0.1, // Near plane. + 5000); // Far plane. +} + +/** + * Given a view matrix computes an movement matrix to make it easy + * to move something relative to the camera view in the XZ plane. + * @param {!o3djs.math.Matrix4} viewMatrix A view matrix. + * @return {!o3djs.math.Matrix4} A movement matrix. + */ +function computeMoveMatrixFromViewMatrix(viewMatrix) { + var cameraMatrix = g_math.matrix4.inverse(viewMatrix); + var xAxis = g_math.cross([0, 1, 0], cameraMatrix[2].slice(0, 3)); + var zAxis = g_math.cross(xAxis, [0, 1, 0]); + return [ + xAxis.concat(0), + [0, 1, 0, 0], + zAxis.concat(0), + [0, 0, 0, 1]]; +} + +/* + * Updates the camera. + */ +function updateCamera() { + g_viewMatrix = g_math.matrix4.lookAt(g_eye, g_target, g_up); + g_viewInfo.drawContext.view = g_viewMatrix; + g_moveMatrix = computeMoveMatrixFromViewMatrix(g_viewMatrix); +}; + +/** + * Updates global variables of the client's size if they have changed. + */ +function updateClientSize() { + var newWidth = g_client.width; + var newHeight = g_client.height; + if (g_o3dWidth != newWidth || g_o3dHeight != newHeight) { + g_o3dWidth = newWidth; + g_o3dHeight = newHeight; + updateProjection(); + } +} + +/** + * Creates the client area. + */ +function init() { + o3djs.util.makeClients(initStep2); +} + +/** + * Initializes O3D and creates one shape. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + g_o3dElement = clientElements[0]; + g_o3d = g_o3dElement.o3d; + g_math = o3djs.math; + g_client = g_o3dElement.client; + + // Creates a pack to manage our resources/assets + g_pack = g_client.createPack(); + + g_root = g_pack.createObject('Transform'); + + g_viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_root, + g_client.renderGraphRoot); + + updateCamera(); + + var redMaterial = o3djs.material.createBasicMaterial( + g_pack, + g_viewInfo, + [0.2, 1, 0.2, 1]); // green + + var checkerMaterial = o3djs.material.createMaterialFromFile( + g_pack, 'shaders/checker.shader', g_viewInfo.performanceDrawList); + + g_globalParams = o3djs.material.createAndBindStandardParams(g_pack); + g_globalParams.lightWorldPos.value = [30, 60, 40]; + g_globalParams.lightColor.value = [1, 1, 1, 1]; + + // Create a ground plane. + var shape = o3djs.primitives.createPlane( + g_pack, checkerMaterial, 100, 100, 10, 10); + var transform = g_pack.createObject('Transform'); + transform.parent = g_root; + transform.addShape(shape); + + // Create a cylinder. + var shape = o3djs.primitives.createCylinder( + g_pack, redMaterial, 2.5, 5, 20, 1, + g_math.matrix4.translation([0, 2.5, 0])); + var transform = g_pack.createObject('Transform'); + transform.parent = g_root; + transform.addShape(shape); + + g_playerTransform = transform; + + // Setup a render callback for per frame processing. + g_client.setRenderCallback(onRender); + + o3djs.event.addEventListener(g_o3dElement, 'keydown', onKeyDown); + o3djs.event.addEventListener(g_o3dElement, 'keyup', onKeyUp); + + window.g_finished = true; // for selenium testing. +} + +/** + * Tracks key down events. + * @param {Event} e keyboard event. + */ +function onKeyDown(e) { + g_keyDown[e.keyCode] = true; +} + +/** + * Tracks key up events. + * @param {Event} e keyboard event. + */ +function onKeyUp(e) { + g_keyDown[e.keyCode] = false; +} + +/** + * Look at keys. + */ +function handleMoveKeys(elapsedTime) { + var directionX = 0; + var directionZ = 0; + + if (g_keyDown[37] || g_keyDown[65]) { directionX = -1; } + if (g_keyDown[39] || g_keyDown[68]) { directionX = 1; } + if (g_keyDown[38] || g_keyDown[87]) { directionZ = -1; } + if (g_keyDown[40] || g_keyDown[83]) { directionZ = 1; } + + if (directionX != 0 || directionZ != 0) { + var moveTranslation = g_math.matrix4.transformPoint( + g_moveMatrix, + [MOVE_VELOCITY * directionX * elapsedTime, + 0, + MOVE_VELOCITY * directionZ * elapsedTime]); + + g_playerXPosition += moveTranslation[0]; + g_playerZPosition += moveTranslation[2]; + + g_playerTransform.identity(); + g_playerTransform.translate(g_playerXPosition, 0, g_playerZPosition); + } +} + +/** + * Move the camera. + */ +function moveCamera() { + var newTarget = [g_playerXPosition, 10, g_playerZPosition]; + g_target = g_math.lerpVector(g_target, newTarget, 0.03); + updateCamera(); +} + +/** + * Called every frame. + * @param {!o3d.RenderEvent} renderEvent Rendering Information. + */ +function onRender(renderEvent) { + var elapsedTime = renderEvent.elapsedTime; + + updateClientSize(); + handleMoveKeys(elapsedTime); + moveCamera(); +}; + +/** + * Remove any callbacks so they don't get called after the page has unloaded. + */ +function unload() { + if (g_client) { + g_client.cleanup(); + } +} +</script> +</head> +<body> +<table style="width: 100%; height:100%;"> + <tr style="height: 50px;"><td> + <div style="width: 100%; height: 50px; font-size: large;"> + <img src="assets/colorbar.png" width="100%" height="10px"/><br/> + Google I/O 2009 O3D Sample + </div> + </td></tr> + <tr style="height: 100%;"><td> + <div style="width: 100%; height: 100%;"> + <div id="o3d" style="width: 100%; height: 100%;"></div> + </div> + </td></tr> +</table> +</body> +</html> diff --git a/o3d/samples/GoogleIO-2009/step08.html b/o3d/samples/GoogleIO-2009/step08.html new file mode 100644 index 0000000..dc3084c --- /dev/null +++ b/o3d/samples/GoogleIO-2009/step08.html @@ -0,0 +1,330 @@ +<!-- +Copyright 2009, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<!-- +Google I/O O3D Sample. + +This sample shows the steps to make a simple frame rate independent game. +--> +<!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> +Google I/O O3D Sample +</title> +<style type="text/css"> + html, body { + height: 100%; + margin: 0; + padding: 0; + border: none; + font-family: Arial, sans-serif; + } +</style> +<!-- Include sample javascript library functions--> +<script type="text/javascript" src="../o3djs/base.js"></script> + +<!-- Our javascript code --> +<script type="text/javascript"> +o3djs.require('o3djs.util'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.primitives'); +o3djs.require('o3djs.material'); + +// Events +// init() once the page has finished loading. +// unload() when the page is unloaded. +window.onload = init; +window.onunload= unload; + +// constants +var MOVE_VELOCITY = 25; // in units per second. +var JUMP_VELOCITY = 100; +var GRAVITY = -500; + +// global variables +var g_o3dElement; +var g_o3d; +var g_math; +var g_client; +var g_viewInfo; +var g_pack; +var g_root; +var g_globalParams; +var g_o3dWidth; +var g_o3dHeight; +var g_o3dElement; +var g_keyDown = []; // which keys are down by key code. +var g_playerTransform; +var g_playerXPosition = 0; +var g_playerYPosition = 0; +var g_playerZPosition = 0; +var g_eye = [15, 25, 50]; +var g_target = [0, 10, 0]; +var g_up = [0, 1, 0]; +var g_viewMatrix; +var g_moveMatrix; +var g_canJump = true; +var g_jumping = false; +var g_playerYVelocity = 0; + +/** + * Updates the projection matrix. + */ +function updateProjection() { + g_viewInfo.drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(45), // field of view. + g_o3dWidth / g_o3dHeight, // aspect ratio + 0.1, // Near plane. + 5000); // Far plane. +} + +/** + * Given a view matrix computes an movement matrix to make it easy + * to move something relative to the camera view in the XZ plane. + * @param {!o3djs.math.Matrix4} viewMatrix A view matrix. + * @return {!o3djs.math.Matrix4} A movement matrix. + */ +function computeMoveMatrixFromViewMatrix(viewMatrix) { + var cameraMatrix = g_math.matrix4.inverse(viewMatrix); + var xAxis = g_math.cross([0, 1, 0], cameraMatrix[2].slice(0, 3)); + var zAxis = g_math.cross(xAxis, [0, 1, 0]); + return [ + xAxis.concat(0), + [0, 1, 0, 0], + zAxis.concat(0), + [0, 0, 0, 1]]; +} + +/* + * Updates the camera. + */ +function updateCamera() { + g_viewMatrix = g_math.matrix4.lookAt(g_eye, g_target, g_up); + g_viewInfo.drawContext.view = g_viewMatrix; + g_moveMatrix = computeMoveMatrixFromViewMatrix(g_viewMatrix); +}; + +/** + * Updates global variables of the client's size if they have changed. + */ +function updateClientSize() { + var newWidth = g_client.width; + var newHeight = g_client.height; + if (g_o3dWidth != newWidth || g_o3dHeight != newHeight) { + g_o3dWidth = newWidth; + g_o3dHeight = newHeight; + updateProjection(); + } +} + +/** + * Creates the client area. + */ +function init() { + o3djs.util.makeClients(initStep2); +} + +/** + * Initializes O3D and creates one shape. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + g_o3dElement = clientElements[0]; + g_o3d = g_o3dElement.o3d; + g_math = o3djs.math; + g_client = g_o3dElement.client; + + // Creates a pack to manage our resources/assets + g_pack = g_client.createPack(); + + g_root = g_pack.createObject('Transform'); + + g_viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_root, + g_client.renderGraphRoot); + + updateCamera(); + + var redMaterial = o3djs.material.createBasicMaterial( + g_pack, + g_viewInfo, + [0.2, 1, 0.2, 1]); // green + + var checkerMaterial = o3djs.material.createMaterialFromFile( + g_pack, 'shaders/checker.shader', g_viewInfo.performanceDrawList); + + g_globalParams = o3djs.material.createAndBindStandardParams(g_pack); + g_globalParams.lightWorldPos.value = [30, 60, 40]; + g_globalParams.lightColor.value = [1, 1, 1, 1]; + + // Create a ground plane. + var shape = o3djs.primitives.createPlane( + g_pack, checkerMaterial, 100, 100, 10, 10); + var transform = g_pack.createObject('Transform'); + transform.parent = g_root; + transform.addShape(shape); + + // Create a cylinder. + var shape = o3djs.primitives.createCylinder( + g_pack, redMaterial, 2.5, 5, 20, 1, + g_math.matrix4.translation([0, 2.5, 0])); + var transform = g_pack.createObject('Transform'); + transform.parent = g_root; + transform.addShape(shape); + + g_playerTransform = transform; + + // Setup a render callback for per frame processing. + g_client.setRenderCallback(onRender); + + o3djs.event.addEventListener(g_o3dElement, 'keydown', onKeyDown); + o3djs.event.addEventListener(g_o3dElement, 'keyup', onKeyUp); + + window.g_finished = true; // for selenium testing. +} + +/** + * Tracks key down events. + * @param {Event} e keyboard event. + */ +function onKeyDown(e) { + g_keyDown[e.keyCode] = true; +} + +/** + * Tracks key up events. + * @param {Event} e keyboard event. + */ +function onKeyUp(e) { + g_keyDown[e.keyCode] = false; +} + +/** + * Look at keys. + */ +function handleMoveKeys(elapsedTime) { + var directionX = 0; + var directionZ = 0; + + if (g_keyDown[37] || g_keyDown[65]) { directionX = -1; } + if (g_keyDown[39] || g_keyDown[68]) { directionX = 1; } + if (g_keyDown[38] || g_keyDown[87]) { directionZ = -1; } + if (g_keyDown[40] || g_keyDown[83]) { directionZ = 1; } + + if (g_canJump) { + if (g_keyDown[32]) { + g_jumping = true; + g_canJump = false; + g_playerYVelocity = JUMP_VELOCITY; + } + } else { + if (g_jumping) { + g_playerYVelocity += GRAVITY * elapsedTime; + g_playerYPosition += g_playerYVelocity * elapsedTime; + if (g_playerYPosition <= 0) { + g_playerYPosition = 0; + g_jumping = false; + } + } else { + if (!g_keyDown[32]) { + g_canJump = true; + } + } + } + + if (directionX != 0 || directionZ != 0) { + var moveTranslation = g_math.matrix4.transformPoint( + g_moveMatrix, + [MOVE_VELOCITY * directionX * elapsedTime, + 0, + MOVE_VELOCITY * directionZ * elapsedTime]); + + g_playerXPosition += moveTranslation[0]; + g_playerZPosition += moveTranslation[2]; + } + + g_playerTransform.identity(); + g_playerTransform.translate( + g_playerXPosition, g_playerYPosition, g_playerZPosition); +} + +/** + * Move the camera. + */ +function moveCamera() { + var newTarget = [g_playerXPosition, 10, g_playerZPosition]; + g_target = g_math.lerpVector(g_target, newTarget, 0.03); + updateCamera(); +} + +/** + * Called every frame. + * @param {!o3d.RenderEvent} renderEvent Rendering Information. + */ +function onRender(renderEvent) { + var elapsedTime = renderEvent.elapsedTime; + + updateClientSize(); + handleMoveKeys(elapsedTime); + moveCamera(); +}; + +/** + * Remove any callbacks so they don't get called after the page has unloaded. + */ +function unload() { + if (g_client) { + g_client.cleanup(); + } +} +</script> +</head> +<body> +<table style="width: 100%; height:100%;"> + <tr style="height: 50px;"><td> + <div style="width: 100%; height: 50px; font-size: large;"> + <img src="assets/colorbar.png" width="100%" height="10px"/><br/> + Google I/O 2009 O3D Sample + </div> + </td></tr> + <tr style="height: 100%;"><td> + <div style="width: 100%; height: 100%;"> + <div id="o3d" style="width: 100%; height: 100%;"></div> + </div> + </td></tr> +</table> +</body> +</html> diff --git a/o3d/samples/GoogleIO-2009/step09.html b/o3d/samples/GoogleIO-2009/step09.html new file mode 100644 index 0000000..ce931be --- /dev/null +++ b/o3d/samples/GoogleIO-2009/step09.html @@ -0,0 +1,358 @@ +<!-- +Copyright 2009, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<!-- +Google I/O O3D Sample. + +This sample shows the steps to make a simple frame rate independent game. +--> +<!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> +Google I/O O3D Sample +</title> +<style type="text/css"> + html, body { + height: 100%; + margin: 0; + padding: 0; + border: none; + font-family: Arial, sans-serif; + } +</style> +<!-- Include sample javascript library functions--> +<script type="text/javascript" src="../o3djs/base.js"></script> + +<!-- Our javascript code --> +<script type="text/javascript"> +o3djs.require('o3djs.util'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.primitives'); +o3djs.require('o3djs.material'); +o3djs.require('o3djs.particles'); + +// Events +// init() once the page has finished loading. +// unload() when the page is unloaded. +window.onload = init; +window.onunload= unload; + +// constants +var MOVE_VELOCITY = 25; // in units per second. +var JUMP_VELOCITY = 100; +var GRAVITY = -500; + +// global variables +var g_o3dElement; +var g_o3d; +var g_math; +var g_client; +var g_viewInfo; +var g_pack; +var g_root; +var g_globalParams; +var g_o3dWidth; +var g_o3dHeight; +var g_o3dElement; +var g_keyDown = []; // which keys are down by key code. +var g_playerTransform; +var g_playerXPosition = 0; +var g_playerYPosition = 0; +var g_playerZPosition = 0; +var g_eye = [15, 25, 50]; +var g_target = [0, 10, 0]; +var g_up = [0, 1, 0]; +var g_viewMatrix; +var g_moveMatrix; +var g_canJump = true; +var g_jumping = false; +var g_playerYVelocity = 0; +var g_particleSystem; +var g_poofEmitter; +var g_poof; + +/** + * Updates the projection matrix. + */ +function updateProjection() { + g_viewInfo.drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(45), // field of view. + g_o3dWidth / g_o3dHeight, // aspect ratio + 0.1, // Near plane. + 5000); // Far plane. +} + +/** + * Given a view matrix computes an movement matrix to make it easy + * to move something relative to the camera view in the XZ plane. + * @param {!o3djs.math.Matrix4} viewMatrix A view matrix. + * @return {!o3djs.math.Matrix4} A movement matrix. + */ +function computeMoveMatrixFromViewMatrix(viewMatrix) { + var cameraMatrix = g_math.matrix4.inverse(viewMatrix); + var xAxis = g_math.cross([0, 1, 0], cameraMatrix[2].slice(0, 3)); + var zAxis = g_math.cross(xAxis, [0, 1, 0]); + return [ + xAxis.concat(0), + [0, 1, 0, 0], + zAxis.concat(0), + [0, 0, 0, 1]]; +} + +/* + * Updates the camera. + */ +function updateCamera() { + g_viewMatrix = g_math.matrix4.lookAt(g_eye, g_target, g_up); + g_viewInfo.drawContext.view = g_viewMatrix; + g_moveMatrix = computeMoveMatrixFromViewMatrix(g_viewMatrix); +}; + +/** + * Updates global variables of the client's size if they have changed. + */ +function updateClientSize() { + var newWidth = g_client.width; + var newHeight = g_client.height; + if (g_o3dWidth != newWidth || g_o3dHeight != newHeight) { + g_o3dWidth = newWidth; + g_o3dHeight = newHeight; + updateProjection(); + } +} + +/** + * Creates the client area. + */ +function init() { + o3djs.util.makeClients(initStep2); +} + +/** + * Initializes O3D and creates one shape. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + g_o3dElement = clientElements[0]; + g_o3d = g_o3dElement.o3d; + g_math = o3djs.math; + g_client = g_o3dElement.client; + + // Creates a pack to manage our resources/assets + g_pack = g_client.createPack(); + + g_root = g_pack.createObject('Transform'); + + g_viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_root, + g_client.renderGraphRoot); + + updateCamera(); + + var redMaterial = o3djs.material.createBasicMaterial( + g_pack, + g_viewInfo, + [0.2, 1, 0.2, 1]); // green + + var checkerMaterial = o3djs.material.createMaterialFromFile( + g_pack, 'shaders/checker.shader', g_viewInfo.performanceDrawList); + + g_globalParams = o3djs.material.createAndBindStandardParams(g_pack); + g_globalParams.lightWorldPos.value = [30, 60, 40]; + g_globalParams.lightColor.value = [1, 1, 1, 1]; + + // Create a ground plane. + var shape = o3djs.primitives.createPlane( + g_pack, checkerMaterial, 100, 100, 10, 10); + var transform = g_pack.createObject('Transform'); + transform.parent = g_root; + transform.addShape(shape); + + // Create a cylinder. + var shape = o3djs.primitives.createCylinder( + g_pack, redMaterial, 2.5, 5, 20, 1, + g_math.matrix4.translation([0, 2.5, 0])); + var transform = g_pack.createObject('Transform'); + transform.parent = g_root; + transform.addShape(shape); + + g_playerTransform = transform; + + g_particleSystem = o3djs.particles.createParticleSystem(g_pack, g_viewInfo); + g_poofEmitter = g_particleSystem.createParticleEmitter(); + g_poofEmitter.setState(o3djs.particles.ParticleStateIds.ADD); + g_poofEmitter.setColorRamp( + [1, 1, 1, 0.3, + 1, 1, 1, 0]); + g_poofEmitter.setParameters({ + numParticles: 30, + lifeTime: 0.5, + startTime: 0, + startSize: 5, + endSize: 10, + spinSpeedRange: 10}, + function(index, parameters) { + var angle = Math.random() * 2 * Math.PI; + parameters.velocity = g_math.matrix4.transformPoint( + g_math.matrix4.rotationY(angle), [25, 2.5, 0]); + parameters.acceleration = g_math.mulVectorVector( + parameters.velocity, [-1.5, 1, -1.5]); + }); + g_poof = g_poofEmitter.createOneShot(g_root); + + // Setup a render callback for per frame processing. + g_client.setRenderCallback(onRender); + + o3djs.event.addEventListener(g_o3dElement, 'keydown', onKeyDown); + o3djs.event.addEventListener(g_o3dElement, 'keyup', onKeyUp); + + window.g_finished = true; // for selenium testing. +} + +/** + * Tracks key down events. + * @param {Event} e keyboard event. + */ +function onKeyDown(e) { + g_keyDown[e.keyCode] = true; +} + +/** + * Tracks key up events. + * @param {Event} e keyboard event. + */ +function onKeyUp(e) { + g_keyDown[e.keyCode] = false; +} + +/** + * Look at keys. + */ +function handleMoveKeys(elapsedTime) { + var directionX = 0; + var directionZ = 0; + + if (g_keyDown[37] || g_keyDown[65]) { directionX = -1; } + if (g_keyDown[39] || g_keyDown[68]) { directionX = 1; } + if (g_keyDown[38] || g_keyDown[87]) { directionZ = -1; } + if (g_keyDown[40] || g_keyDown[83]) { directionZ = 1; } + + if (g_canJump) { + if (g_keyDown[32]) { + g_jumping = true; + g_canJump = false; + g_playerYVelocity = JUMP_VELOCITY; + } + } else { + if (g_jumping) { + g_playerYVelocity += GRAVITY * elapsedTime; + g_playerYPosition += g_playerYVelocity * elapsedTime; + if (g_playerYPosition <= 0) { + g_playerYPosition = 0; + g_poof.trigger( + [g_playerXPosition, g_playerYPosition, g_playerZPosition]); + g_jumping = false; + } + } else { + if (!g_keyDown[32]) { + g_canJump = true; + } + } + } + + if (directionX != 0 || directionZ != 0) { + var moveTranslation = g_math.matrix4.transformPoint( + g_moveMatrix, + [MOVE_VELOCITY * directionX * elapsedTime, + 0, + MOVE_VELOCITY * directionZ * elapsedTime]); + + g_playerXPosition += moveTranslation[0]; + g_playerZPosition += moveTranslation[2]; + } + + g_playerTransform.identity(); + g_playerTransform.translate( + g_playerXPosition, g_playerYPosition, g_playerZPosition); +} + +/** + * Move the camera. + */ +function moveCamera() { + var newTarget = [g_playerXPosition, 10, g_playerZPosition]; + g_target = g_math.lerpVector(g_target, newTarget, 0.03); + updateCamera(); +} + +/** + * Called every frame. + * @param {!o3d.RenderEvent} renderEvent Rendering Information. + */ +function onRender(renderEvent) { + var elapsedTime = renderEvent.elapsedTime; + + updateClientSize(); + handleMoveKeys(elapsedTime); + moveCamera(); +}; + +/** + * Remove any callbacks so they don't get called after the page has unloaded. + */ +function unload() { + if (g_client) { + g_client.cleanup(); + } +} +</script> +</head> +<body> +<table style="width: 100%; height:100%;"> + <tr style="height: 50px;"><td> + <div style="width: 100%; height: 50px; font-size: large;"> + <img src="assets/colorbar.png" width="100%" height="10px"/><br/> + Google I/O 2009 O3D Sample + </div> + </td></tr> + <tr style="height: 100%;"><td> + <div style="width: 100%; height: 100%;"> + <div id="o3d" style="width: 100%; height: 100%;"></div> + </div> + </td></tr> +</table> +</body> +</html> diff --git a/o3d/samples/GoogleIO-2009/step10.html b/o3d/samples/GoogleIO-2009/step10.html new file mode 100644 index 0000000..965ef7c --- /dev/null +++ b/o3d/samples/GoogleIO-2009/step10.html @@ -0,0 +1,361 @@ +<!-- +Copyright 2009, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<!-- +Google I/O O3D Sample. + +This sample shows the steps to make a simple frame rate independent game. +--> +<!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> +Google I/O O3D Sample +</title> +<style type="text/css"> + html, body { + height: 100%; + margin: 0; + padding: 0; + border: none; + font-family: Arial, sans-serif; + } +</style> +<!-- Include sample javascript library functions--> +<script type="text/javascript" src="../o3djs/base.js"></script> + +<!-- Our javascript code --> +<script type="text/javascript"> +o3djs.require('o3djs.util'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.primitives'); +o3djs.require('o3djs.material'); +o3djs.require('o3djs.particles'); +o3djs.require('o3djs.scene'); +o3djs.require('o3djs.pack'); + +// Events +// init() once the page has finished loading. +// unload() when the page is unloaded. +window.onload = init; +window.onunload= unload; + +// constants +var MOVE_VELOCITY = 25; // in units per second. +var JUMP_VELOCITY = 100; +var GRAVITY = -500; + +// global variables +var g_o3dElement; +var g_o3d; +var g_math; +var g_client; +var g_viewInfo; +var g_pack; +var g_root; +var g_globalParams; +var g_o3dWidth; +var g_o3dHeight; +var g_o3dElement; +var g_keyDown = []; // which keys are down by key code. +var g_playerTransform; +var g_playerXPosition = 0; +var g_playerYPosition = 0; +var g_playerZPosition = 0; +var g_eye = [15, 25, 50]; +var g_target = [0, 10, 0]; +var g_up = [0, 1, 0]; +var g_viewMatrix; +var g_moveMatrix; +var g_canJump = true; +var g_jumping = false; +var g_playerYVelocity = 0; +var g_particleSystem; +var g_poofEmitter; +var g_poof; + +/** + * Updates the projection matrix. + */ +function updateProjection() { + g_viewInfo.drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(45), // field of view. + g_o3dWidth / g_o3dHeight, // aspect ratio + 0.1, // Near plane. + 5000); // Far plane. +} + +/** + * Given a view matrix computes an movement matrix to make it easy + * to move something relative to the camera view in the XZ plane. + * @param {!o3djs.math.Matrix4} viewMatrix A view matrix. + * @return {!o3djs.math.Matrix4} A movement matrix. + */ +function computeMoveMatrixFromViewMatrix(viewMatrix) { + var cameraMatrix = g_math.matrix4.inverse(viewMatrix); + var xAxis = g_math.cross([0, 1, 0], cameraMatrix[2].slice(0, 3)); + var zAxis = g_math.cross(xAxis, [0, 1, 0]); + return [ + xAxis.concat(0), + [0, 1, 0, 0], + zAxis.concat(0), + [0, 0, 0, 1]]; +} + +/* + * Updates the camera. + */ +function updateCamera() { + g_viewMatrix = g_math.matrix4.lookAt(g_eye, g_target, g_up); + g_viewInfo.drawContext.view = g_viewMatrix; + g_moveMatrix = computeMoveMatrixFromViewMatrix(g_viewMatrix); +}; + +/** + * Updates global variables of the client's size if they have changed. + */ +function updateClientSize() { + var newWidth = g_client.width; + var newHeight = g_client.height; + if (g_o3dWidth != newWidth || g_o3dHeight != newHeight) { + g_o3dWidth = newWidth; + g_o3dHeight = newHeight; + updateProjection(); + } +} + +/** + * Creates the client area. + */ +function init() { + o3djs.util.makeClients(initStep2); +} + +/** + * Initializes O3D and creates one shape. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + g_o3dElement = clientElements[0]; + g_o3d = g_o3dElement.o3d; + g_math = o3djs.math; + g_client = g_o3dElement.client; + + // Creates a pack to manage our resources/assets + g_pack = g_client.createPack(); + + g_root = g_pack.createObject('Transform'); + + g_viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_root, + g_client.renderGraphRoot); + + updateCamera(); + + var checkerMaterial = o3djs.material.createMaterialFromFile( + g_pack, 'shaders/checker.shader', g_viewInfo.performanceDrawList); + + g_globalParams = o3djs.material.createAndBindStandardParams(g_pack); + g_globalParams.lightWorldPos.value = [30, 60, 40]; + g_globalParams.lightColor.value = [1, 1, 1, 1]; + + // Create a ground plane. + var shape = o3djs.primitives.createPlane( + g_pack, checkerMaterial, 100, 100, 10, 10); + var transform = g_pack.createObject('Transform'); + transform.parent = g_root; + transform.addShape(shape); + + // Load character. + var transform = g_pack.createObject('Transform'); + g_playerTransform = transform; + var playerPack = g_client.createPack(); + o3djs.scene.loadScene(g_client, playerPack, g_playerTransform, + 'assets/character.o3dtgz', initStep3); +} + +/** + * Continue setting up after the model has loaded. + */ +function initStep3(playerPack, parent, exception) { + o3djs.pack.preparePack(playerPack, g_viewInfo); + o3djs.material.bindParams(playerPack, g_globalParams); + g_playerTransform.parent = g_root; + + g_particleSystem = o3djs.particles.createParticleSystem(g_pack, g_viewInfo); + g_poofEmitter = g_particleSystem.createParticleEmitter(); + g_poofEmitter.setState(o3djs.particles.ParticleStateIds.ADD); + g_poofEmitter.setColorRamp( + [1, 1, 1, 0.3, + 1, 1, 1, 0]); + g_poofEmitter.setParameters({ + numParticles: 30, + lifeTime: 0.5, + startTime: 0, + startSize: 5, + endSize: 10, + spinSpeedRange: 10}, + function(index, parameters) { + var angle = Math.random() * 2 * Math.PI; + parameters.velocity = g_math.matrix4.transformPoint( + g_math.matrix4.rotationY(angle), [25, 2.5, 0]); + parameters.acceleration = g_math.mulVectorVector( + parameters.velocity, [-1.5, 1, -1.5]); + }); + g_poof = g_poofEmitter.createOneShot(g_root); + + // Setup a render callback for per frame processing. + g_client.setRenderCallback(onRender); + + o3djs.event.addEventListener(g_o3dElement, 'keydown', onKeyDown); + o3djs.event.addEventListener(g_o3dElement, 'keyup', onKeyUp); + + window.g_finished = true; // for selenium testing. +} + +/** + * Tracks key down events. + * @param {Event} e keyboard event. + */ +function onKeyDown(e) { + g_keyDown[e.keyCode] = true; +} + +/** + * Tracks key up events. + * @param {Event} e keyboard event. + */ +function onKeyUp(e) { + g_keyDown[e.keyCode] = false; +} + +/** + * Look at keys. + */ +function handleMoveKeys(elapsedTime) { + var directionX = 0; + var directionZ = 0; + + if (g_keyDown[37] || g_keyDown[65]) { directionX = -1; } + if (g_keyDown[39] || g_keyDown[68]) { directionX = 1; } + if (g_keyDown[38] || g_keyDown[87]) { directionZ = -1; } + if (g_keyDown[40] || g_keyDown[83]) { directionZ = 1; } + + if (g_canJump) { + if (g_keyDown[32]) { + g_jumping = true; + g_canJump = false; + g_playerYVelocity = JUMP_VELOCITY; + } + } else { + if (g_jumping) { + g_playerYVelocity += GRAVITY * elapsedTime; + g_playerYPosition += g_playerYVelocity * elapsedTime; + if (g_playerYPosition <= 0) { + g_playerYPosition = 0; + g_poof.trigger( + [g_playerXPosition, g_playerYPosition, g_playerZPosition]); + g_jumping = false; + } + } else { + if (!g_keyDown[32]) { + g_canJump = true; + } + } + } + + if (directionX != 0 || directionZ != 0) { + var moveTranslation = g_math.matrix4.transformPoint( + g_moveMatrix, + [MOVE_VELOCITY * directionX * elapsedTime, + 0, + MOVE_VELOCITY * directionZ * elapsedTime]); + + g_playerXPosition += moveTranslation[0]; + g_playerZPosition += moveTranslation[2]; + } + + g_playerTransform.identity(); + g_playerTransform.translate( + g_playerXPosition, g_playerYPosition, g_playerZPosition); +} + +/** + * Move the camera. + */ +function moveCamera() { + var newTarget = [g_playerXPosition, 10, g_playerZPosition]; + g_target = g_math.lerpVector(g_target, newTarget, 0.03); + updateCamera(); +} + +/** + * Called every frame. + * @param {!o3d.RenderEvent} renderEvent Rendering Information. + */ +function onRender(renderEvent) { + var elapsedTime = renderEvent.elapsedTime; + + updateClientSize(); + handleMoveKeys(elapsedTime); + moveCamera(); +}; + +/** + * Remove any callbacks so they don't get called after the page has unloaded. + */ +function unload() { + if (g_client) { + g_client.cleanup(); + } +} +</script> +</head> +<body> +<table style="width: 100%; height:100%;"> + <tr style="height: 50px;"><td> + <div style="width: 100%; height: 50px; font-size: large;"> + <img src="assets/colorbar.png" width="100%" height="10px"/><br/> + Google I/O 2009 O3D Sample + </div> + </td></tr> + <tr style="height: 100%;"><td> + <div style="width: 100%; height: 100%;"> + <div id="o3d" style="width: 100%; height: 100%;"></div> + </div> + </td></tr> +</table> +</body> +</html> diff --git a/o3d/samples/GoogleIO-2009/step11.html b/o3d/samples/GoogleIO-2009/step11.html new file mode 100644 index 0000000..1db5557 --- /dev/null +++ b/o3d/samples/GoogleIO-2009/step11.html @@ -0,0 +1,365 @@ +<!-- +Copyright 2009, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<!-- +Google I/O O3D Sample. + +This sample shows the steps to make a simple frame rate independent game. +--> +<!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> +Google I/O O3D Sample +</title> +<style type="text/css"> + html, body { + height: 100%; + margin: 0; + padding: 0; + border: none; + font-family: Arial, sans-serif; + } +</style> +<!-- Include sample javascript library functions--> +<script type="text/javascript" src="../o3djs/base.js"></script> + +<!-- Our javascript code --> +<script type="text/javascript"> +o3djs.require('o3djs.util'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.primitives'); +o3djs.require('o3djs.material'); +o3djs.require('o3djs.particles'); +o3djs.require('o3djs.scene'); +o3djs.require('o3djs.pack'); + +// Events +// init() once the page has finished loading. +// unload() when the page is unloaded. +window.onload = init; +window.onunload= unload; + +// constants +var MOVE_VELOCITY = 25; // in units per second. +var JUMP_VELOCITY = 100; +var GRAVITY = -500; + +// global variables +var g_o3dElement; +var g_o3d; +var g_math; +var g_client; +var g_viewInfo; +var g_pack; +var g_root; +var g_globalParams; +var g_o3dWidth; +var g_o3dHeight; +var g_o3dElement; +var g_keyDown = []; // which keys are down by key code. +var g_playerTransform; +var g_playerXPosition = 0; +var g_playerYPosition = 0; +var g_playerZPosition = 0; +var g_playerDirection = 0; +var g_eye = [15, 25, 50]; +var g_target = [0, 10, 0]; +var g_up = [0, 1, 0]; +var g_viewMatrix; +var g_moveMatrix; +var g_canJump = true; +var g_jumping = false; +var g_playerYVelocity = 0; +var g_particleSystem; +var g_poofEmitter; +var g_poof; + +/** + * Updates the projection matrix. + */ +function updateProjection() { + g_viewInfo.drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(45), // field of view. + g_o3dWidth / g_o3dHeight, // aspect ratio + 0.1, // Near plane. + 5000); // Far plane. +} + +/** + * Given a view matrix computes an movement matrix to make it easy + * to move something relative to the camera view in the XZ plane. + * @param {!o3djs.math.Matrix4} viewMatrix A view matrix. + * @return {!o3djs.math.Matrix4} A movement matrix. + */ +function computeMoveMatrixFromViewMatrix(viewMatrix) { + var cameraMatrix = g_math.matrix4.inverse(viewMatrix); + var xAxis = g_math.cross([0, 1, 0], cameraMatrix[2].slice(0, 3)); + var zAxis = g_math.cross(xAxis, [0, 1, 0]); + return [ + xAxis.concat(0), + [0, 1, 0, 0], + zAxis.concat(0), + [0, 0, 0, 1]]; +} + +/* + * Updates the camera. + */ +function updateCamera() { + g_viewMatrix = g_math.matrix4.lookAt(g_eye, g_target, g_up); + g_viewInfo.drawContext.view = g_viewMatrix; + g_moveMatrix = computeMoveMatrixFromViewMatrix(g_viewMatrix); +}; + +/** + * Updates global variables of the client's size if they have changed. + */ +function updateClientSize() { + var newWidth = g_client.width; + var newHeight = g_client.height; + if (g_o3dWidth != newWidth || g_o3dHeight != newHeight) { + g_o3dWidth = newWidth; + g_o3dHeight = newHeight; + updateProjection(); + } +} + +/** + * Creates the client area. + */ +function init() { + o3djs.util.makeClients(initStep2); +} + +/** + * Initializes O3D and creates one shape. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + g_o3dElement = clientElements[0]; + g_o3d = g_o3dElement.o3d; + g_math = o3djs.math; + g_client = g_o3dElement.client; + + // Creates a pack to manage our resources/assets + g_pack = g_client.createPack(); + + g_root = g_pack.createObject('Transform'); + + g_viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_root, + g_client.renderGraphRoot); + + updateCamera(); + + var checkerMaterial = o3djs.material.createMaterialFromFile( + g_pack, 'shaders/checker.shader', g_viewInfo.performanceDrawList); + + g_globalParams = o3djs.material.createAndBindStandardParams(g_pack); + g_globalParams.lightWorldPos.value = [30, 60, 40]; + g_globalParams.lightColor.value = [1, 1, 1, 1]; + + // Create a ground plane. + var shape = o3djs.primitives.createPlane( + g_pack, checkerMaterial, 100, 100, 10, 10); + var transform = g_pack.createObject('Transform'); + transform.parent = g_root; + transform.addShape(shape); + + // Load character. + var transform = g_pack.createObject('Transform'); + g_playerTransform = transform; + var playerPack = g_client.createPack(); + o3djs.scene.loadScene(g_client, playerPack, g_playerTransform, + 'assets/character.o3dtgz', initStep3); +} + +/** + * Continue setting up after the model has loaded. + */ +function initStep3(playerPack, parent, exception) { + o3djs.pack.preparePack(playerPack, g_viewInfo); + o3djs.material.bindParams(playerPack, g_globalParams); + g_playerTransform.parent = g_root; + + g_particleSystem = o3djs.particles.createParticleSystem(g_pack, g_viewInfo); + g_poofEmitter = g_particleSystem.createParticleEmitter(); + g_poofEmitter.setState(o3djs.particles.ParticleStateIds.ADD); + g_poofEmitter.setColorRamp( + [1, 1, 1, 0.3, + 1, 1, 1, 0]); + g_poofEmitter.setParameters({ + numParticles: 30, + lifeTime: 0.5, + startTime: 0, + startSize: 5, + endSize: 10, + spinSpeedRange: 10}, + function(index, parameters) { + var angle = Math.random() * 2 * Math.PI; + parameters.velocity = g_math.matrix4.transformPoint( + g_math.matrix4.rotationY(angle), [25, 2.5, 0]); + parameters.acceleration = g_math.mulVectorVector( + parameters.velocity, [-1.5, 1, -1.5]); + }); + g_poof = g_poofEmitter.createOneShot(g_root); + + // Setup a render callback for per frame processing. + g_client.setRenderCallback(onRender); + + o3djs.event.addEventListener(g_o3dElement, 'keydown', onKeyDown); + o3djs.event.addEventListener(g_o3dElement, 'keyup', onKeyUp); + + window.g_finished = true; // for selenium testing. +} + +/** + * Tracks key down events. + * @param {Event} e keyboard event. + */ +function onKeyDown(e) { + g_keyDown[e.keyCode] = true; +} + +/** + * Tracks key up events. + * @param {Event} e keyboard event. + */ +function onKeyUp(e) { + g_keyDown[e.keyCode] = false; +} + +/** + * Look at keys. + */ +function handleMoveKeys(elapsedTime) { + var directionX = 0; + var directionZ = 0; + + if (g_keyDown[37] || g_keyDown[65]) { directionX = -1; } + if (g_keyDown[39] || g_keyDown[68]) { directionX = 1; } + if (g_keyDown[38] || g_keyDown[87]) { directionZ = -1; } + if (g_keyDown[40] || g_keyDown[83]) { directionZ = 1; } + + if (g_canJump) { + if (g_keyDown[32]) { + g_jumping = true; + g_canJump = false; + g_playerYVelocity = JUMP_VELOCITY; + } + } else { + if (g_jumping) { + g_playerYVelocity += GRAVITY * elapsedTime; + g_playerYPosition += g_playerYVelocity * elapsedTime; + if (g_playerYPosition <= 0) { + g_playerYPosition = 0; + g_poof.trigger( + [g_playerXPosition, g_playerYPosition, g_playerZPosition]); + g_jumping = false; + } + } else { + if (!g_keyDown[32]) { + g_canJump = true; + } + } + } + + if (directionX != 0 || directionZ != 0) { + var moveTranslation = g_math.matrix4.transformPoint( + g_moveMatrix, + [MOVE_VELOCITY * directionX * elapsedTime, + 0, + MOVE_VELOCITY * directionZ * elapsedTime]); + var targetDirection = Math.atan2(moveTranslation[0], moveTranslation[2]); + g_playerDirection = g_math.lerpRadian(g_playerDirection, targetDirection, + 0.2); + g_playerXPosition += moveTranslation[0]; + g_playerZPosition += moveTranslation[2]; + } + + g_playerTransform.identity(); + g_playerTransform.translate( + g_playerXPosition, g_playerYPosition, g_playerZPosition); + g_playerTransform.rotateY(g_playerDirection); +} + +/** + * Move the camera. + */ +function moveCamera() { + var newTarget = [g_playerXPosition, 10, g_playerZPosition]; + g_target = g_math.lerpVector(g_target, newTarget, 0.03); + updateCamera(); +} + +/** + * Called every frame. + * @param {!o3d.RenderEvent} renderEvent Rendering Information. + */ +function onRender(renderEvent) { + var elapsedTime = renderEvent.elapsedTime; + + updateClientSize(); + handleMoveKeys(elapsedTime); + moveCamera(); +}; + +/** + * Remove any callbacks so they don't get called after the page has unloaded. + */ +function unload() { + if (g_client) { + g_client.cleanup(); + } +} +</script> +</head> +<body> +<table style="width: 100%; height:100%;"> + <tr style="height: 50px;"><td> + <div style="width: 100%; height: 50px; font-size: large;"> + <img src="assets/colorbar.png" width="100%" height="10px"/><br/> + Google I/O 2009 O3D Sample + </div> + </td></tr> + <tr style="height: 100%;"><td> + <div style="width: 100%; height: 100%;"> + <div id="o3d" style="width: 100%; height: 100%;"></div> + </div> + </td></tr> +</table> +</body> +</html> diff --git a/o3d/samples/GoogleIO-2009/step12.html b/o3d/samples/GoogleIO-2009/step12.html new file mode 100644 index 0000000..cb07ce7 --- /dev/null +++ b/o3d/samples/GoogleIO-2009/step12.html @@ -0,0 +1,394 @@ +<!-- +Copyright 2009, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<!-- +Google I/O O3D Sample. + +This sample shows the steps to make a simple frame rate independent game. +--> +<!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> +Google I/O O3D Sample +</title> +<style type="text/css"> + html, body { + height: 100%; + margin: 0; + padding: 0; + border: none; + font-family: Arial, sans-serif; + } +</style> +<!-- Include sample javascript library functions--> +<script type="text/javascript" src="../o3djs/base.js"></script> + +<!-- Our javascript code --> +<script type="text/javascript"> +o3djs.require('o3djs.util'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.primitives'); +o3djs.require('o3djs.material'); +o3djs.require('o3djs.particles'); +o3djs.require('o3djs.scene'); +o3djs.require('o3djs.pack'); + +// Events +// init() once the page has finished loading. +// unload() when the page is unloaded. +window.onload = init; +window.onunload= unload; + +// constants +var MOVE_VELOCITY = 25; // in units per second. +var JUMP_VELOCITY = 100; +var GRAVITY = -500; + +// global variables +var g_o3dElement; +var g_o3d; +var g_math; +var g_client; +var g_viewInfo; +var g_pack; +var g_root; +var g_globalParams; +var g_o3dWidth; +var g_o3dHeight; +var g_o3dElement; +var g_keyDown = []; // which keys are down by key code. +var g_playerTransform; +var g_playerXPosition = 0; +var g_playerYPosition = 0; +var g_playerZPosition = 0; +var g_playerDirection = 0; +var g_animParam; +var g_playerMode; +var g_eye = [15, 25, 50]; +var g_target = [0, 10, 0]; +var g_up = [0, 1, 0]; +var g_viewMatrix; +var g_moveMatrix; +var g_canJump = true; +var g_jumping = false; +var g_playerYVelocity = 0; +var g_particleSystem; +var g_poofEmitter; +var g_poof; + +var IDLE_START_TIME = 247 / 30; +var IDLE_END_TIME = 573 / 30; +var IDLE_TIME_RANGE = IDLE_END_TIME - IDLE_START_TIME; + +var g_animTimer = IDLE_START_TIME; + +/** + * Updates the projection matrix. + */ +function updateProjection() { + g_viewInfo.drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(45), // field of view. + g_o3dWidth / g_o3dHeight, // aspect ratio + 0.1, // Near plane. + 5000); // Far plane. +} + +/** + * Given a view matrix computes an movement matrix to make it easy + * to move something relative to the camera view in the XZ plane. + * @param {!o3djs.math.Matrix4} viewMatrix A view matrix. + * @return {!o3djs.math.Matrix4} A movement matrix. + */ +function computeMoveMatrixFromViewMatrix(viewMatrix) { + var cameraMatrix = g_math.matrix4.inverse(viewMatrix); + var xAxis = g_math.cross([0, 1, 0], cameraMatrix[2].slice(0, 3)); + var zAxis = g_math.cross(xAxis, [0, 1, 0]); + return [ + xAxis.concat(0), + [0, 1, 0, 0], + zAxis.concat(0), + [0, 0, 0, 1]]; +} + +/* + * Updates the camera. + */ +function updateCamera() { + g_viewMatrix = g_math.matrix4.lookAt(g_eye, g_target, g_up); + g_viewInfo.drawContext.view = g_viewMatrix; + g_moveMatrix = computeMoveMatrixFromViewMatrix(g_viewMatrix); +}; + +/** + * Updates global variables of the client's size if they have changed. + */ +function updateClientSize() { + var newWidth = g_client.width; + var newHeight = g_client.height; + if (g_o3dWidth != newWidth || g_o3dHeight != newHeight) { + g_o3dWidth = newWidth; + g_o3dHeight = newHeight; + updateProjection(); + } +} + +/** + * Creates the client area. + */ +function init() { + o3djs.util.makeClients(initStep2); +} + +/** + * Initializes O3D and creates one shape. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + g_o3dElement = clientElements[0]; + g_o3d = g_o3dElement.o3d; + g_math = o3djs.math; + g_client = g_o3dElement.client; + + // Creates a pack to manage our resources/assets + g_pack = g_client.createPack(); + + g_root = g_pack.createObject('Transform'); + + g_viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_root, + g_client.renderGraphRoot); + + updateCamera(); + + var checkerMaterial = o3djs.material.createMaterialFromFile( + g_pack, 'shaders/checker.shader', g_viewInfo.performanceDrawList); + + g_globalParams = o3djs.material.createAndBindStandardParams(g_pack); + g_globalParams.lightWorldPos.value = [30, 60, 40]; + g_globalParams.lightColor.value = [1, 1, 1, 1]; + + // Create a ground plane. + var shape = o3djs.primitives.createPlane( + g_pack, checkerMaterial, 100, 100, 10, 10); + var transform = g_pack.createObject('Transform'); + transform.parent = g_root; + transform.addShape(shape); + + // Load character. + var transform = g_pack.createObject('Transform'); + g_playerTransform = transform; + var playerPack = g_client.createPack(); + var paramObject = playerPack.createObject('ParamObject'); + g_animParam = paramObject.createParam('animTime', 'ParamFloat'); + o3djs.scene.loadScene(g_client, playerPack, g_playerTransform, + 'assets/character.o3dtgz', initStep3, + {opt_animSource: g_animParam}); +} + +/** + * Continue setting up after the model has loaded. + */ +function initStep3(playerPack, parent, exception) { + o3djs.pack.preparePack(playerPack, g_viewInfo); + o3djs.material.bindParams(playerPack, g_globalParams); + g_playerTransform.parent = g_root; + + g_particleSystem = o3djs.particles.createParticleSystem(g_pack, g_viewInfo); + g_poofEmitter = g_particleSystem.createParticleEmitter(); + g_poofEmitter.setState(o3djs.particles.ParticleStateIds.ADD); + g_poofEmitter.setColorRamp( + [1, 1, 1, 0.3, + 1, 1, 1, 0]); + g_poofEmitter.setParameters({ + numParticles: 30, + lifeTime: 0.5, + startTime: 0, + startSize: 5, + endSize: 10, + spinSpeedRange: 10}, + function(index, parameters) { + var angle = Math.random() * 2 * Math.PI; + parameters.velocity = g_math.matrix4.transformPoint( + g_math.matrix4.rotationY(angle), [25, 2.5, 0]); + parameters.acceleration = g_math.mulVectorVector( + parameters.velocity, [-1.5, 1, -1.5]); + }); + g_poof = g_poofEmitter.createOneShot(g_root); + + // Setup a render callback for per frame processing. + g_client.setRenderCallback(onRender); + + o3djs.event.addEventListener(g_o3dElement, 'keydown', onKeyDown); + o3djs.event.addEventListener(g_o3dElement, 'keyup', onKeyUp); + + window.g_finished = true; // for selenium testing. + window.o3d_prepForSelenium = function() { + g_animParam.value = 0; + g_animParam = {value: 0}; + } +} + +/** + * Tracks key down events. + * @param {Event} e keyboard event. + */ +function onKeyDown(e) { + g_keyDown[e.keyCode] = true; +} + +/** + * Tracks key up events. + * @param {Event} e keyboard event. + */ +function onKeyUp(e) { + g_keyDown[e.keyCode] = false; +} + +/** + * Look at keys. + */ +function handleMoveKeys(elapsedTime) { + var directionX = 0; + var directionZ = 0; + + if (g_keyDown[37] || g_keyDown[65]) { directionX = -1; } + if (g_keyDown[39] || g_keyDown[68]) { directionX = 1; } + if (g_keyDown[38] || g_keyDown[87]) { directionZ = -1; } + if (g_keyDown[40] || g_keyDown[83]) { directionZ = 1; } + + if (g_canJump) { + if (g_keyDown[32]) { + g_jumping = true; + g_canJump = false; + g_playerYVelocity = JUMP_VELOCITY; + } + } else { + if (g_jumping) { + g_playerYVelocity += GRAVITY * elapsedTime; + g_playerYPosition += g_playerYVelocity * elapsedTime; + if (g_playerYPosition <= 0) { + g_playerYPosition = 0; + g_poof.trigger( + [g_playerXPosition, g_playerYPosition, g_playerZPosition]); + g_jumping = false; + } + } else { + if (!g_keyDown[32]) { + g_canJump = true; + } + } + } + + if (directionX != 0 || directionZ != 0) { + var moveTranslation = g_math.matrix4.transformPoint( + g_moveMatrix, + [MOVE_VELOCITY * directionX * elapsedTime, + 0, + MOVE_VELOCITY * directionZ * elapsedTime]); + var targetDirection = Math.atan2(moveTranslation[0], moveTranslation[2]); + g_playerDirection = g_math.lerpRadian(g_playerDirection, targetDirection, + 0.2); + g_playerXPosition += moveTranslation[0]; + g_playerZPosition += moveTranslation[2]; + } + + g_playerTransform.identity(); + g_playerTransform.translate( + g_playerXPosition, g_playerYPosition, g_playerZPosition); + g_playerTransform.rotateY(g_playerDirection); +} + +/** + * Move the camera. + */ +function moveCamera() { + var newTarget = [g_playerXPosition, 10, g_playerZPosition]; + g_target = g_math.lerpVector(g_target, newTarget, 0.03); + updateCamera(); +} + +/** + * Deal with player animation. + */ +function handleAnimation(elapsedTime) { + g_animTimer += elapsedTime; + if (g_animTimer >= IDLE_END_TIME) { + g_animTimer = g_math.modClamp(g_animTimer, + IDLE_TIME_RANGE, + IDLE_START_TIME); + } + g_animParam.value = g_animTimer; +} + +/** + * Called every frame. + * @param {!o3d.RenderEvent} renderEvent Rendering Information. + */ +function onRender(renderEvent) { + var elapsedTime = renderEvent.elapsedTime; + + updateClientSize(); + handleMoveKeys(elapsedTime); + handleAnimation(elapsedTime); + moveCamera(); +}; + +/** + * Remove any callbacks so they don't get called after the page has unloaded. + */ +function unload() { + if (g_client) { + g_client.cleanup(); + } +} +</script> +</head> +<body> +<table style="width: 100%; height:100%;"> + <tr style="height: 50px;"><td> + <div style="width: 100%; height: 50px; font-size: large;"> + <img src="assets/colorbar.png" width="100%" height="10px"/><br/> + Google I/O 2009 O3D Sample + </div> + </td></tr> + <tr style="height: 100%;"><td> + <div style="width: 100%; height: 100%;"> + <div id="o3d" style="width: 100%; height: 100%;"></div> + </div> + </td></tr> +</table> +</body> +</html> diff --git a/o3d/samples/GoogleIO-2009/step13.html b/o3d/samples/GoogleIO-2009/step13.html new file mode 100644 index 0000000..a995627 --- /dev/null +++ b/o3d/samples/GoogleIO-2009/step13.html @@ -0,0 +1,570 @@ +<!-- +Copyright 2009, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<!-- +Google I/O O3D Sample. + +This sample shows the steps to make a simple frame rate independent game. +--> +<!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> +Google I/O O3D Sample +</title> +<style type="text/css"> + html, body { + height: 100%; + margin: 0; + padding: 0; + border: none; + font-family: Arial, sans-serif; + } +</style> +<!-- Include sample javascript library functions--> +<script type="text/javascript" src="../o3djs/base.js"></script> + +<!-- Our javascript code --> +<script type="text/javascript"> +o3djs.require('o3djs.util'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.primitives'); +o3djs.require('o3djs.material'); +o3djs.require('o3djs.particles'); +o3djs.require('o3djs.scene'); +o3djs.require('o3djs.pack'); + +// Events +// init() once the page has finished loading. +// unload() when the page is unloaded. +window.onload = init; +window.onunload= unload; + +// constants +var MOVE_VELOCITY = 25; // in units per second. +var JUMP_VELOCITY = 100; +var GRAVITY = -500; + +// global variables +var g_o3dElement; +var g_o3d; +var g_math; +var g_client; +var g_viewInfo; +var g_pack; +var g_root; +var g_globalParams; +var g_o3dWidth; +var g_o3dHeight; +var g_o3dElement; +var g_keyDown = []; // which keys are down by key code. +var g_playerTransform; +var g_playerPosition = [0, 0, 0]; +var g_playerDirection = 0; +var g_animParam; +var g_playerMode; +var g_eye = [15, 25, 50]; +var g_target = [0, 10, 0]; +var g_up = [0, 1, 0]; +var g_viewMatrix; +var g_moveMatrix; +var g_canJump = true; +var g_jumping = false; +var g_playerVelocity = [0, 0, 0]; +var g_targetDirection = 0; +var g_particleSystem; +var g_poofEmitter; +var g_poof; + +var g_anims = { + idle1: {startFrame: 0, endFrame: 30}, + walk: {startFrame: 31, endFrame: 71}, + jumpStart: {startFrame: 72, endFrame: 87}, + jumpUp: {startFrame: 87, endFrame: 87}, + jumpCrest: {startFrame: 87, endFrame: 91}, + jumpFall: {startFrame: 91, endFrame: 91}, + jumpLand: {startFrame: 91, endFrame: 110}, + run: {startFrame: 111, endFrame: 127}, + idle2: {startFrame: 128, endFrame: 173}, + idle3: {startFrame: 174, endFrame: 246}, + idle4: {startFrame: 247, endFrame: 573}}; + +var g_animation; +var g_animTimer; + +/** + * Updates the projection matrix. + */ +function updateProjection() { + g_viewInfo.drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(45), // field of view. + g_o3dWidth / g_o3dHeight, // aspect ratio + 0.1, // Near plane. + 5000); // Far plane. +} + +/** + * Given a view matrix computes an movement matrix to make it easy + * to move something relative to the camera view in the XZ plane. + * @param {!o3djs.math.Matrix4} viewMatrix A view matrix. + * @return {!o3djs.math.Matrix4} A movement matrix. + */ +function computeMoveMatrixFromViewMatrix(viewMatrix) { + var cameraMatrix = g_math.matrix4.inverse(viewMatrix); + var xAxis = g_math.cross([0, 1, 0], cameraMatrix[2].slice(0, 3)); + var zAxis = g_math.cross(xAxis, [0, 1, 0]); + return [ + xAxis.concat(0), + [0, 1, 0, 0], + zAxis.concat(0), + [0, 0, 0, 1]]; +} + +/* + * Updates the camera. + */ +function updateCamera() { + g_viewMatrix = g_math.matrix4.lookAt(g_eye, g_target, g_up); + g_viewInfo.drawContext.view = g_viewMatrix; + g_moveMatrix = computeMoveMatrixFromViewMatrix(g_viewMatrix); +}; + +/** + * Updates global variables of the client's size if they have changed. + */ +function updateClientSize() { + var newWidth = g_client.width; + var newHeight = g_client.height; + if (g_o3dWidth != newWidth || g_o3dHeight != newHeight) { + g_o3dWidth = newWidth; + g_o3dHeight = newHeight; + updateProjection(); + } +} + +/** + * Start an animation. + * @param {!Object} animation to start. + */ +function startAnimation(animation) { + g_animation = animation; + g_animTimer = g_animation.startTime; +} + +/** + * Starts a new mode. + * @param {number} mode Mode to start. + */ +function startMode(mode) { + if (mode != g_playerMode) { + g_playerMode = mode; + mode.init(); + } +} + +/** + * Creates the client area. + */ +function init() { + o3djs.util.makeClients(initStep2); +} + +/** + * Initializes O3D and creates one shape. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + g_o3dElement = clientElements[0]; + g_o3d = g_o3dElement.o3d; + g_math = o3djs.math; + g_client = g_o3dElement.client; + + // Convert anim frames to anim times. + for (var animName in g_anims) { + var anim = g_anims[animName]; + anim.startTime = anim.startFrame / 30; + anim.endTime = anim.endFrame / 30; + anim.timeRange = anim.endTime - anim.startTime; + } + + // Creates a pack to manage our resources/assets + g_pack = g_client.createPack(); + + g_root = g_pack.createObject('Transform'); + + g_viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_root, + g_client.renderGraphRoot); + + updateCamera(); + + var checkerMaterial = o3djs.material.createMaterialFromFile( + g_pack, 'shaders/checker.shader', g_viewInfo.performanceDrawList); + + g_globalParams = o3djs.material.createAndBindStandardParams(g_pack); + g_globalParams.lightWorldPos.value = [30, 60, 40]; + g_globalParams.lightColor.value = [1, 1, 1, 1]; + + // Create a ground plane. + var shape = o3djs.primitives.createPlane( + g_pack, checkerMaterial, 100, 100, 10, 10); + var transform = g_pack.createObject('Transform'); + transform.parent = g_root; + transform.addShape(shape); + + // Load character. + var transform = g_pack.createObject('Transform'); + g_playerTransform = transform; + var playerPack = g_client.createPack(); + var paramObject = playerPack.createObject('ParamObject'); + g_animParam = paramObject.createParam('animTime', 'ParamFloat'); + o3djs.scene.loadScene(g_client, playerPack, g_playerTransform, + 'assets/character.o3dtgz', initStep3, + {opt_animSource: g_animParam}); +} + +/** + * Continue setting up after the model has loaded. + */ +function initStep3(playerPack, parent, exception) { + o3djs.pack.preparePack(playerPack, g_viewInfo); + o3djs.material.bindParams(playerPack, g_globalParams); + g_playerTransform.parent = g_root; + + g_particleSystem = o3djs.particles.createParticleSystem(g_pack, g_viewInfo); + g_poofEmitter = g_particleSystem.createParticleEmitter(); + g_poofEmitter.setState(o3djs.particles.ParticleStateIds.ADD); + g_poofEmitter.setColorRamp( + [1, 1, 1, 0.3, + 1, 1, 1, 0]); + g_poofEmitter.setParameters({ + numParticles: 30, + lifeTime: 0.5, + startTime: 0, + startSize: 5, + endSize: 10, + spinSpeedRange: 10}, + function(index, parameters) { + var angle = Math.random() * 2 * Math.PI; + parameters.velocity = g_math.matrix4.transformPoint( + g_math.matrix4.rotationY(angle), [25, 2.5, 0]); + parameters.acceleration = g_math.mulVectorVector( + parameters.velocity, [-1.5, 1, -1.5]); + }); + g_poof = g_poofEmitter.createOneShot(g_root); + + // Setup a render callback for per frame processing. + g_client.setRenderCallback(onRender); + + o3djs.event.addEventListener(g_o3dElement, 'keydown', onKeyDown); + o3djs.event.addEventListener(g_o3dElement, 'keyup', onKeyUp); + + window.g_finished = true; // for selenium testing. + window.o3d_prepForSelenium = function() { + g_animParam.value = 0; + g_animParam = {value: 0}; + } +} + +/** + * Tracks key down events. + * @param {Event} e keyboard event. + */ +function onKeyDown(e) { + g_keyDown[e.keyCode] = true; +} + +/** + * Tracks key up events. + * @param {Event} e keyboard event. + */ +function onKeyUp(e) { + g_keyDown[e.keyCode] = false; +} + +/** + * Look at keys. + */ +function handleMoveKeys(elapsedTime) { + var directionX = 0; + var directionZ = 0; + + if (g_keyDown[37] || g_keyDown[65]) { directionX = -1; } + if (g_keyDown[39] || g_keyDown[68]) { directionX = 1; } + if (g_keyDown[38] || g_keyDown[87]) { directionZ = -1; } + if (g_keyDown[40] || g_keyDown[83]) { directionZ = 1; } + + if (g_canJump) { + if (g_keyDown[32]) { + startMode(g_modes.JUMP); + } + } else { + if (!g_jumping) { + if (!g_keyDown[32]) { + g_canJump = true; + } + } + } + + if (directionX != 0 || directionZ != 0) { + if (!g_jumping) { + startMode(g_modes.WALK); + } + var moveTranslation = g_math.matrix4.transformPoint( + g_moveMatrix, + [MOVE_VELOCITY * directionX, 0, MOVE_VELOCITY * directionZ]); + g_targetDirection = Math.atan2(moveTranslation[0], + moveTranslation[2]); + g_playerVelocity[0] = moveTranslation[0]; + g_playerVelocity[2] = moveTranslation[2]; + } else { + g_playerVelocity[0] = 0; + g_playerVelocity[2] = 0; + if (!g_jumping) { + startMode(g_modes.IDLE); + } + } +} + +/** + * Moves the camera. + */ +function moveCamera() { + var newTarget = [g_playerPosition[0], 10, g_playerPosition[2]]; + g_target = g_math.lerpVector(g_target, newTarget, 0.03); + updateCamera(); +} + +/** + * Updates the direction. + * @param {number} elapsedTime Time elasped since last frame. + */ +function updateDirection(elapsedTime) { + g_playerDirection = g_math.lerpRadian(g_playerDirection, g_targetDirection, + 0.2); +} + +/** + * Adds gravity to velocity. + * @param {number} elapsedTime Time elasped since last frame. + */ +function calculateGravity(elapsedTime) { + g_playerVelocity[1] += GRAVITY * elapsedTime; +} + +/** + * Updates the player's position. + * @param {number} elapsedTime Time elasped since last frame. + */ +function updateMovement(elapsedTime) { + g_playerPosition = g_math.addVector(g_playerPosition, + g_math.mulVectorScalar(g_playerVelocity, + elapsedTime)); +} + +var g_modes = {}; + +/** + * Handle idle mode. + */ +g_modes.IDLE = { + init: function() { + startAnimation(g_anims.idle1); + g_jumping = false; + }, + handle: function(elapsedTime) { + updateDirection(elapsedTime); + g_animTimer += elapsedTime; + if (g_animTimer >= g_animation.endTime) { + // Pick an idle at random. + var idle = 0; + if (Math.random() > 0.8) { + // Choose another idle. + idle = Math.floor(Math.random() * 10 / 3); + if (idle > 3) { + idle = 3; + } + } + var idleName = 'idle' + (idle + 1); + startAnimation(g_anims[idleName]); + } + } +}; + +/** + * Handle walk mode. + */ +g_modes.WALK = { + init: function() { + startAnimation(g_anims.run); + g_jumping = false; + }, + handle: function(elapsedTime) { + updateDirection(elapsedTime); + updateMovement(elapsedTime); + g_animTimer += elapsedTime; + if (g_animTimer >= g_animation.endTime) { + g_animTimer = g_math.modClamp(g_animTimer, + g_animation.timeRange, + g_animation.startTime); + } + } +}; + +/** + * Handle jump mode. + */ +g_modes.JUMP = { + init: function() { + startAnimation(g_anims.jumpStart); + g_jumping = true; + g_canJump = false; + g_playerVelocity[1] = JUMP_VELOCITY; + }, + handle: function(elapsedTime) { + g_animTimer += elapsedTime; + if (g_animTimer >= g_animation.endTime) { + startMode(g_modes.JUMP_UP); + } + } +}; + +g_modes.JUMP_UP = { + init: function() { + startAnimation(g_anims.jumpUp); + }, + handle: function(elapsedTime) { + updateDirection(elapsedTime); + calculateGravity(elapsedTime); + updateMovement(elapsedTime); + if (g_playerVelocity[1] < 10) { + startMode(g_modes.JUMP_CREST); + } + } +}; + +g_modes.JUMP_CREST = { + init: function() { + startAnimation(g_anims.jumpCrest); + }, + handle: function(elapsedTime) { + updateDirection(elapsedTime); + calculateGravity(elapsedTime); + updateMovement(elapsedTime); + g_animTimer += elapsedTime; + if (g_animTimer >= g_animation.endTime) { + startMode(g_modes.JUMP_FALL); + } + } +}; + +g_modes.JUMP_FALL = { + init: function() { + startAnimation(g_anims.jumpFall); + }, + handle: function(elapsedTime) { + updateDirection(elapsedTime); + calculateGravity(elapsedTime); + updateMovement(elapsedTime); + if (g_playerPosition[1] <= 0) { + startMode(g_modes.JUMP_LAND); + g_playerPosition[1] = 0; + g_playerVelocity[1] = 0; + g_poof.trigger(g_playerPosition); + } + } +}; + +g_modes.JUMP_LAND = { + init: function() { + startAnimation(g_anims.jumpLand); + }, + handle: function(elapsedTime) { + updateDirection(elapsedTime); + g_animTimer += elapsedTime; + if (g_animTimer >= g_animation.endTime) { + g_jumping = false; + startMode(g_modes.IDLE); + } + } +}; + +function updatePlayer() { + g_animParam.value = g_animTimer; + g_playerTransform.identity(); + g_playerTransform.translate(g_playerPosition); + g_playerTransform.rotateY(g_playerDirection); +} + +/** + * Called every frame. + * @param {!o3d.RenderEvent} renderEvent Rendering Information. + */ +function onRender(renderEvent) { + var elapsedTime = renderEvent.elapsedTime; + + updateClientSize(); + handleMoveKeys(elapsedTime); + g_playerMode.handle(elapsedTime); + updatePlayer(); + moveCamera(); +}; + +/** + * Remove any callbacks so they don't get called after the page has unloaded. + */ +function unload() { + if (g_client) { + g_client.cleanup(); + } +} +</script> +</head> +<body> +<table style="width: 100%; height:100%;"> + <tr style="height: 50px;"><td> + <div style="width: 100%; height: 50px; font-size: large;"> + <img src="assets/colorbar.png" width="100%" height="10px"/><br/> + Google I/O 2009 O3D Sample + </div> + </td></tr> + <tr style="height: 100%;"><td> + <div style="width: 100%; height: 100%;"> + <div id="o3d" style="width: 100%; height: 100%;"></div> + </div> + </td></tr> +</table> +</body> +</html> diff --git a/o3d/samples/GoogleIO-2009/step14.html b/o3d/samples/GoogleIO-2009/step14.html new file mode 100644 index 0000000..031f858 --- /dev/null +++ b/o3d/samples/GoogleIO-2009/step14.html @@ -0,0 +1,581 @@ +<!-- +Copyright 2009, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<!-- +Google I/O O3D Sample. + +This sample shows the steps to make a simple frame rate independent game. +--> +<!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> +Google I/O O3D Sample +</title> +<style type="text/css"> + html, body { + height: 100%; + margin: 0; + padding: 0; + border: none; + font-family: Arial, sans-serif; + } +</style> +<!-- Include sample javascript library functions--> +<script type="text/javascript" src="../o3djs/base.js"></script> + +<!-- Our javascript code --> +<script type="text/javascript"> +o3djs.require('o3djs.util'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.primitives'); +o3djs.require('o3djs.material'); +o3djs.require('o3djs.particles'); +o3djs.require('o3djs.scene'); +o3djs.require('o3djs.pack'); +o3djs.require('o3djs.loader'); + +// Events +// init() once the page has finished loading. +// unload() when the page is unloaded. +window.onload = init; +window.onunload= unload; + +// constants +var MOVE_VELOCITY = 25; // in units per second. +var JUMP_VELOCITY = 100; +var GRAVITY = -500; + +// global variables +var g_o3dElement; +var g_o3d; +var g_math; +var g_client; +var g_viewInfo; +var g_pack; +var g_root; +var g_globalParams; +var g_o3dWidth; +var g_o3dHeight; +var g_o3dElement; +var g_keyDown = []; // which keys are down by key code. +var g_playerTransform; +var g_playerPosition = [0, 0, 0]; +var g_playerDirection = 0; +var g_animParam; +var g_playerMode; +var g_eye = [15, 25, 50]; +var g_target = [0, 10, 0]; +var g_up = [0, 1, 0]; +var g_viewMatrix; +var g_moveMatrix; +var g_canJump = true; +var g_jumping = false; +var g_playerVelocity = [0, 0, 0]; +var g_targetDirection = 0; +var g_worldTransform; +var g_particleSystem; +var g_poofEmitter; +var g_poof; + +var g_anims = { + idle1: {startFrame: 0, endFrame: 30}, + walk: {startFrame: 31, endFrame: 71}, + jumpStart: {startFrame: 72, endFrame: 87}, + jumpUp: {startFrame: 87, endFrame: 87}, + jumpCrest: {startFrame: 87, endFrame: 91}, + jumpFall: {startFrame: 91, endFrame: 91}, + jumpLand: {startFrame: 91, endFrame: 110}, + run: {startFrame: 111, endFrame: 127}, + idle2: {startFrame: 128, endFrame: 173}, + idle3: {startFrame: 174, endFrame: 246}, + idle4: {startFrame: 247, endFrame: 573}}; + +var g_animation; +var g_animTimer; + +/** + * Updates the projection matrix. + */ +function updateProjection() { + g_viewInfo.drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(45), // field of view. + g_o3dWidth / g_o3dHeight, // aspect ratio + 0.1, // Near plane. + 15000); // Far plane. +} + +/** + * Given a view matrix computes an movement matrix to make it easy + * to move something relative to the camera view in the XZ plane. + * @param {!o3djs.math.Matrix4} viewMatrix A view matrix. + * @return {!o3djs.math.Matrix4} A movement matrix. + */ +function computeMoveMatrixFromViewMatrix(viewMatrix) { + var cameraMatrix = g_math.matrix4.inverse(viewMatrix); + var xAxis = g_math.cross([0, 1, 0], cameraMatrix[2].slice(0, 3)); + var zAxis = g_math.cross(xAxis, [0, 1, 0]); + return [ + xAxis.concat(0), + [0, 1, 0, 0], + zAxis.concat(0), + [0, 0, 0, 1]]; +} + +/* + * Updates the camera. + */ +function updateCamera() { + g_viewMatrix = g_math.matrix4.lookAt(g_eye, g_target, g_up); + g_viewInfo.drawContext.view = g_viewMatrix; + g_moveMatrix = computeMoveMatrixFromViewMatrix(g_viewMatrix); +}; + +/** + * Updates global variables of the client's size if they have changed. + */ +function updateClientSize() { + var newWidth = g_client.width; + var newHeight = g_client.height; + if (g_o3dWidth != newWidth || g_o3dHeight != newHeight) { + g_o3dWidth = newWidth; + g_o3dHeight = newHeight; + updateProjection(); + } +} + +/** + * Start an animation. + * @param {!Object} animation to start. + */ +function startAnimation(animation) { + g_animation = animation; + g_animTimer = g_animation.startTime; +} + +/** + * Starts a new mode. + * @param {number} mode Mode to start. + */ +function startMode(mode) { + if (mode != g_playerMode) { + g_playerMode = mode; + mode.init(); + } +} + +/** + * Creates the client area. + */ +function init() { + o3djs.util.makeClients(initStep2); +} + +/** + * Initializes O3D and creates one shape. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + g_o3dElement = clientElements[0]; + g_o3d = g_o3dElement.o3d; + g_math = o3djs.math; + g_client = g_o3dElement.client; + + // Convert anim frames to anim times. + for (var animName in g_anims) { + var anim = g_anims[animName]; + anim.startTime = anim.startFrame / 30; + anim.endTime = anim.endFrame / 30; + anim.timeRange = anim.endTime - anim.startTime; + } + + // Creates a pack to manage our resources/assets + g_pack = g_client.createPack(); + + g_root = g_pack.createObject('Transform'); + + g_viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_root, + g_client.renderGraphRoot); + + updateCamera(); + + g_globalParams = o3djs.material.createAndBindStandardParams(g_pack); + g_globalParams.lightWorldPos.value = [600, 2000, 400]; + g_globalParams.lightColor.value = [1, 1, 1, 1]; + + // Load character. + var transform = g_pack.createObject('Transform'); + g_playerTransform = transform; + var playerPack = g_client.createPack(); + var paramObject = playerPack.createObject('ParamObject'); + g_animParam = paramObject.createParam('animTime', 'ParamFloat'); + var loader = o3djs.loader.createLoader(initStep3); + loader.loadScene(g_client, playerPack, g_playerTransform, + 'assets/character.o3dtgz', prepareScene, + {opt_animSource: g_animParam}); + var worldPack = g_client.createPack(); + g_worldTransform = worldPack.createObject('Transform'); + loader.loadScene(g_client, worldPack, g_worldTransform, + 'assets/background.o3dtgz', prepareScene) + loader.finish(); +} + +/** + * Setup the just loaded scene. + * @param {!o3d.Pack} pack The pack the scene was loaded into. + * @param {!o3d.Transform} parent The parent of the scene. + * @param {*} exception An exception or null if success. + */ +function prepareScene(pack, parent, exception) { + o3djs.pack.preparePack(pack, g_viewInfo); + o3djs.material.bindParams(pack, g_globalParams); + parent.parent = g_root; +} + +/** + * Continue setting up after the both the model and character have loaded. + */ +function initStep3() { + // Fix for artists not using the same scale on background vs character + g_worldTransform.scale(10, 10, 10); + // Fix for current collada import bugs. + var m = g_client.getObjects('Road', 'o3d.Material')[0]; + m.getParam('shininess').value = 100; + + g_particleSystem = o3djs.particles.createParticleSystem(g_pack, g_viewInfo); + g_poofEmitter = g_particleSystem.createParticleEmitter(); + g_poofEmitter.setState(o3djs.particles.ParticleStateIds.ADD); + g_poofEmitter.setColorRamp( + [1, 1, 1, 0.3, + 1, 1, 1, 0]); + g_poofEmitter.setParameters({ + numParticles: 30, + lifeTime: 0.5, + startTime: 0, + startSize: 5, + endSize: 10, + spinSpeedRange: 10}, + function(index, parameters) { + var angle = Math.random() * 2 * Math.PI; + parameters.velocity = g_math.matrix4.transformPoint( + g_math.matrix4.rotationY(angle), [25, 2.5, 0]); + parameters.acceleration = g_math.mulVectorVector( + parameters.velocity, [-1.5, 1, -1.5]); + }); + g_poof = g_poofEmitter.createOneShot(g_root); + + // Setup a render callback for per frame processing. + g_client.setRenderCallback(onRender); + + o3djs.event.addEventListener(g_o3dElement, 'keydown', onKeyDown); + o3djs.event.addEventListener(g_o3dElement, 'keyup', onKeyUp); + + window.g_finished = true; // for selenium testing. + window.o3d_prepForSelenium = function() { + g_animParam.value = 0; + g_animParam = {value: 0}; + } +} + +/** + * Tracks key down events. + * @param {Event} e keyboard event. + */ +function onKeyDown(e) { + g_keyDown[e.keyCode] = true; +} + +/** + * Tracks key up events. + * @param {Event} e keyboard event. + */ +function onKeyUp(e) { + g_keyDown[e.keyCode] = false; +} + +/** + * Look at keys. + */ +function handleMoveKeys(elapsedTime) { + var directionX = 0; + var directionZ = 0; + + if (g_keyDown[37] || g_keyDown[65]) { directionX = -1; } + if (g_keyDown[39] || g_keyDown[68]) { directionX = 1; } + if (g_keyDown[38] || g_keyDown[87]) { directionZ = -1; } + if (g_keyDown[40] || g_keyDown[83]) { directionZ = 1; } + + if (g_canJump) { + if (g_keyDown[32]) { + startMode(g_modes.JUMP); + } + } else { + if (!g_jumping) { + if (!g_keyDown[32]) { + g_canJump = true; + } + } + } + + if (directionX != 0 || directionZ != 0) { + if (!g_jumping) { + startMode(g_modes.WALK); + } + var moveTranslation = g_math.matrix4.transformPoint( + g_moveMatrix, + [MOVE_VELOCITY * directionX, 0, MOVE_VELOCITY * directionZ]); + g_targetDirection = Math.atan2(moveTranslation[0], + moveTranslation[2]); + g_playerVelocity[0] = moveTranslation[0]; + g_playerVelocity[2] = moveTranslation[2]; + } else { + g_playerVelocity[0] = 0; + g_playerVelocity[2] = 0; + if (!g_jumping) { + startMode(g_modes.IDLE); + } + } +} + +/** + * Move the camera. + */ +function moveCamera() { + var newTarget = [g_playerPosition[0], 10, g_playerPosition[2]]; + g_target = g_math.lerpVector(g_target, newTarget, 0.03); + updateCamera(); +} + +/** + * Updates the direction. + * @param {number} elapsedTime Time elasped since last frame. + */ +function updateDirection(elapsedTime) { + g_playerDirection = g_math.lerpRadian(g_playerDirection, g_targetDirection, + 0.2); +} + +/** + * Adds gravity to velocity. + * @param {number} elapsedTime Time elasped since last frame. + */ +function calculateGravity(elapsedTime) { + g_playerVelocity[1] += GRAVITY * elapsedTime; +} + +/** + * Updates the player's position. + * @param {number} elapsedTime Time elasped since last frame. + */ +function updateMovement(elapsedTime) { + g_playerPosition = g_math.addVector(g_playerPosition, + g_math.mulVectorScalar(g_playerVelocity, + elapsedTime)); +} + +var g_modes = {}; + +/** + * Handle idle mode. + */ +g_modes.IDLE = { + init: function() { + startAnimation(g_anims.idle1); + g_jumping = false; + }, + handle: function(elapsedTime) { + updateDirection(elapsedTime); + g_animTimer += elapsedTime; + if (g_animTimer >= g_animation.endTime) { + // Pick an idle at random. + var idle = 0; + if (Math.random() > 0.8) { + // Choose another idle. + idle = Math.floor(Math.random() * 10 / 3); + if (idle > 3) { + idle = 3; + } + } + var idleName = 'idle' + (idle + 1); + startAnimation(g_anims[idleName]); + } + } +}; + +/** + * Handle walk mode. + */ +g_modes.WALK = { + init: function() { + startAnimation(g_anims.run); + g_jumping = false; + }, + handle: function(elapsedTime) { + updateDirection(elapsedTime); + updateMovement(elapsedTime); + g_animTimer += elapsedTime; + if (g_animTimer >= g_animation.endTime) { + g_animTimer = g_math.modClamp(g_animTimer, + g_animation.timeRange, + g_animation.startTime); + } + } +}; + +/** + * Handle jump mode. + */ +g_modes.JUMP = { + init: function() { + startAnimation(g_anims.jumpStart); + g_jumping = true; + g_canJump = false; + g_playerVelocity[1] = JUMP_VELOCITY; + }, + handle: function(elapsedTime) { + g_animTimer += elapsedTime; + if (g_animTimer >= g_animation.endTime) { + startMode(g_modes.JUMP_UP); + } + } +}; + +g_modes.JUMP_UP = { + init: function() { + startAnimation(g_anims.jumpUp); + }, + handle: function(elapsedTime) { + updateDirection(elapsedTime); + calculateGravity(elapsedTime); + updateMovement(elapsedTime); + if (g_playerVelocity[1] < 10) { + startMode(g_modes.JUMP_CREST); + } + } +}; + +g_modes.JUMP_CREST = { + init: function() { + startAnimation(g_anims.jumpCrest); + }, + handle: function(elapsedTime) { + updateDirection(elapsedTime); + calculateGravity(elapsedTime); + updateMovement(elapsedTime); + g_animTimer += elapsedTime; + if (g_animTimer >= g_animation.endTime) { + startMode(g_modes.JUMP_FALL); + } + } +}; + +g_modes.JUMP_FALL = { + init: function() { + startAnimation(g_anims.jumpFall); + }, + handle: function(elapsedTime) { + updateDirection(elapsedTime); + calculateGravity(elapsedTime); + updateMovement(elapsedTime); + if (g_playerPosition[1] <= 0) { + startMode(g_modes.JUMP_LAND); + g_playerPosition[1] = 0; + g_playerVelocity[1] = 0; + g_poof.trigger(g_playerPosition); + } + } +}; + +g_modes.JUMP_LAND = { + init: function() { + startAnimation(g_anims.jumpLand); + }, + handle: function(elapsedTime) { + updateDirection(elapsedTime); + g_animTimer += elapsedTime; + if (g_animTimer >= g_animation.endTime) { + g_jumping = false; + startMode(g_modes.IDLE); + } + } +}; + +function updatePlayer() { + g_animParam.value = g_animTimer; + g_playerTransform.identity(); + g_playerTransform.translate(g_playerPosition); + g_playerTransform.rotateY(g_playerDirection); +} + +/** + * Called every frame. + * @param {!o3d.RenderEvent} renderEvent Rendering Information. + */ +function onRender(renderEvent) { + var elapsedTime = renderEvent.elapsedTime; + updateClientSize(); + handleMoveKeys(elapsedTime); + g_playerMode.handle(elapsedTime); + updatePlayer(); + moveCamera(); +}; + +/** + * Remove any callbacks so they don't get called after the page has unloaded. + */ +function unload() { + if (g_client) { + g_client.cleanup(); + } +} +</script> +</head> +<body> +<table style="width: 100%; height:100%;"> + <tr style="height: 50px;"><td> + <div style="width: 100%; height: 50px; font-size: large;"> + <img src="assets/colorbar.png" width="100%" height="10px"/><br/> + Google I/O 2009 O3D Sample + </div> + </td></tr> + <tr style="height: 100%;"><td> + <div style="width: 100%; height: 100%;"> + <div id="o3d" style="width: 100%; height: 100%;"></div> + </div> + </td></tr> +</table> +</body> +</html> diff --git a/o3d/samples/MANIFEST b/o3d/samples/MANIFEST index f7f7d63..5cb2ff6 100644 --- a/o3d/samples/MANIFEST +++ b/o3d/samples/MANIFEST @@ -44,6 +44,25 @@ beachdemo/assets/pe_mist.png beachdemo/assets/sky-cubemap.dds beachdemo/beachdemo.html beachdemo/beachdemo.js +GoogleIO-2009/step01.html +GoogleIO-2009/step02.html +GoogleIO-2009/step03.html +GoogleIO-2009/step04.html +GoogleIO-2009/step05.html +GoogleIO-2009/step06.html +GoogleIO-2009/step07.html +GoogleIO-2009/step08.html +GoogleIO-2009/step09.html +GoogleIO-2009/step10.html +GoogleIO-2009/step11.html +GoogleIO-2009/step12.html +GoogleIO-2009/step13.html +GoogleIO-2009/step14.html +GoogleIO-2009/shaders/checker.shader +GoogleIO-2009/assets/background.o3dtgz +GoogleIO-2009/assets/character.o3dtgz +GoogleIO-2009/assets/colorbar.png +GoogleIO-2009/assets/style.css box2d-3d/box2d-3d.html box2d-3d/demos/LICENSE.txt box2d-3d/demos/README.o3d diff --git a/o3d/samples/build.scons b/o3d/samples/build.scons index c1324ba..608b2ad 100644 --- a/o3d/samples/build.scons +++ b/o3d/samples/build.scons @@ -254,7 +254,8 @@ z_up_env = env.Clone(UP_AXIS='0,0,1') models = [ {'path': 'beachdemo/convert_assets/beachdemo.zip', 'env': z_up_env}, {'path': 'beachdemo/convert_assets/beach-low-poly.dae', 'env': z_up_env}, - + {'path': 'GoogleIO-2009/convert_assets/background.zip', 'env': y_up_env}, + {'path': 'GoogleIO-2009/convert_assets/character.zip', 'env': y_up_env}, {'path': 'home-configurators/convert_cbassets/House_Roofless.kmz', 'env': z_up_env}, diff --git a/o3d/samples/particles.html b/o3d/samples/particles.html index a82b334..244b621 100644 --- a/o3d/samples/particles.html +++ b/o3d/samples/particles.html @@ -594,6 +594,6 @@ function unload() { <div id="o3d" style="width: 800px; height: 600px;"></div> <!-- End of O3D plugin --> Press 'P' to make a poof.<br/> -Press 'T' to make a trail. +Hold 'T' to make a trail. </body> </html> diff --git a/o3d/tests/selenium/sample_list.txt b/o3d/tests/selenium/sample_list.txt index 786bbc4..2774574 100644 --- a/o3d/tests/selenium/sample_list.txt +++ b/o3d/tests/selenium/sample_list.txt @@ -107,6 +107,8 @@ medium zsorting screenshot pdiff_threshold(39500) #large box2d-3d/box2d-3d timeout(45000) except(*googlechrome) large simpleviewer/simpleviewer screenshot pdiff_threshold(100) large trends/trends timeout(30000) +medium GoogleIO-2009/step09 screenshot pdiff_threshold(1900) +large GoogleIO-2009/step14 screenshot pdiff_threshold(4900) # -- tests below this line are tests for which there is a python # function to custom run the test. As such, only the 'except' and |