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
Esse commit está contido em:
+1
-1
@@ -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 = {
|
||||
|
||||
+1
-1
@@ -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 = {
|
||||
|
||||
Arquivo binário não exibido.
|
Depois Largura: | Altura: | Tamanho: 1.9 KiB |
@@ -0,0 +1,8 @@
|
||||
html, body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário