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

Side by Side Diff: samples/GoogleIO-2009/step14.html

Issue 149438: Add Google IO sample. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/o3d/
Patch Set: '' Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « samples/GoogleIO-2009/step13.html ('k') | samples/MANIFEST » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 <!--
2 Copyright 2009, Google Inc.
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above
12 copyright notice, this list of conditions and the following disclaimer
13 in the documentation and/or other materials provided with the
14 distribution.
15 * Neither the name of Google Inc. nor the names of its
16 contributors may be used to endorse or promote products derived from
17 this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 -->
31 <!--
32 Google I/O O3D Sample.
33
34 This sample shows the steps to make a simple frame rate independent game.
35 -->
36 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
37 "http://www.w3.org/TR/html4/loose.dtd">
38 <html>
39 <head>
40 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
41 <title>
42 Google I/O O3D Sample
43 </title>
44 <style type="text/css">
45 html, body {
46 height: 100%;
47 margin: 0;
48 padding: 0;
49 border: none;
50 font-family: Arial, sans-serif;
51 }
52 </style>
53 <!-- Include sample javascript library functions-->
54 <script type="text/javascript" src="../o3djs/base.js"></script>
55
56 <!-- Our javascript code -->
57 <script type="text/javascript">
58 o3djs.require('o3djs.util');
59 o3djs.require('o3djs.math');
60 o3djs.require('o3djs.rendergraph');
61 o3djs.require('o3djs.primitives');
62 o3djs.require('o3djs.material');
63 o3djs.require('o3djs.particles');
64 o3djs.require('o3djs.scene');
65 o3djs.require('o3djs.pack');
66 o3djs.require('o3djs.loader');
67
68 // Events
69 // init() once the page has finished loading.
70 // unload() when the page is unloaded.
71 window.onload = init;
72 window.onunload= unload;
73
74 // constants
75 var MOVE_VELOCITY = 25; // in units per second.
76 var JUMP_VELOCITY = 100;
77 var GRAVITY = -500;
78
79 // global variables
80 var g_o3dElement;
81 var g_o3d;
82 var g_math;
83 var g_client;
84 var g_viewInfo;
85 var g_pack;
86 var g_root;
87 var g_globalParams;
88 var g_o3dWidth;
89 var g_o3dHeight;
90 var g_o3dElement;
91 var g_keyDown = []; // which keys are down by key code.
92 var g_playerTransform;
93 var g_playerPosition = [0, 0, 0];
94 var g_playerDirection = 0;
95 var g_animParam;
96 var g_playerMode;
97 var g_eye = [15, 25, 50];
98 var g_target = [0, 10, 0];
99 var g_up = [0, 1, 0];
100 var g_viewMatrix;
101 var g_moveMatrix;
102 var g_canJump = true;
103 var g_jumping = false;
104 var g_playerVelocity = [0, 0, 0];
105 var g_targetDirection = 0;
106 var g_worldTransform;
107 var g_particleSystem;
108 var g_poofEmitter;
109 var g_poof;
110
111 var g_anims = {
112 idle1: {startFrame: 0, endFrame: 30},
113 walk: {startFrame: 31, endFrame: 71},
114 jumpStart: {startFrame: 72, endFrame: 87},
115 jumpUp: {startFrame: 87, endFrame: 87},
116 jumpCrest: {startFrame: 87, endFrame: 91},
117 jumpFall: {startFrame: 91, endFrame: 91},
118 jumpLand: {startFrame: 91, endFrame: 110},
119 run: {startFrame: 111, endFrame: 127},
120 idle2: {startFrame: 128, endFrame: 173},
121 idle3: {startFrame: 174, endFrame: 246},
122 idle4: {startFrame: 247, endFrame: 573}};
123
124 var g_animation;
125 var g_animTimer;
126
127 /**
128 * Updates the projection matrix.
129 */
130 function updateProjection() {
131 g_viewInfo.drawContext.projection = g_math.matrix4.perspective(
132 g_math.degToRad(45), // field of view.
133 g_o3dWidth / g_o3dHeight, // aspect ratio
134 0.1, // Near plane.
135 15000); // Far plane.
136 }
137
138 /**
139 * Given a view matrix computes an movement matrix to make it easy
140 * to move something relative to the camera view in the XZ plane.
141 * @param {!o3djs.math.Matrix4} viewMatrix A view matrix.
142 * @return {!o3djs.math.Matrix4} A movement matrix.
143 */
144 function computeMoveMatrixFromViewMatrix(viewMatrix) {
145 var cameraMatrix = g_math.matrix4.inverse(viewMatrix);
146 var xAxis = g_math.cross([0, 1, 0], cameraMatrix[2].slice(0, 3));
147 var zAxis = g_math.cross(xAxis, [0, 1, 0]);
148 return [
149 xAxis.concat(0),
150 [0, 1, 0, 0],
151 zAxis.concat(0),
152 [0, 0, 0, 1]];
153 }
154
155 /*
156 * Updates the camera.
157 */
158 function updateCamera() {
159 g_viewMatrix = g_math.matrix4.lookAt(g_eye, g_target, g_up);
160 g_viewInfo.drawContext.view = g_viewMatrix;
161 g_moveMatrix = computeMoveMatrixFromViewMatrix(g_viewMatrix);
162 };
163
164 /**
165 * Updates global variables of the client's size if they have changed.
166 */
167 function updateClientSize() {
168 var newWidth = g_client.width;
169 var newHeight = g_client.height;
170 if (g_o3dWidth != newWidth || g_o3dHeight != newHeight) {
171 g_o3dWidth = newWidth;
172 g_o3dHeight = newHeight;
173 updateProjection();
174 }
175 }
176
177 /**
178 * Start an animation.
179 * @param {!Object} animation to start.
180 */
181 function startAnimation(animation) {
182 g_animation = animation;
183 g_animTimer = g_animation.startTime;
184 }
185
186 /**
187 * Starts a new mode.
188 * @param {number} mode Mode to start.
189 */
190 function startMode(mode) {
191 if (mode != g_playerMode) {
192 g_playerMode = mode;
193 mode.init();
194 }
195 }
196
197 /**
198 * Creates the client area.
199 */
200 function init() {
201 o3djs.util.makeClients(initStep2);
202 }
203
204 /**
205 * Initializes O3D and creates one shape.
206 * @param {Array} clientElements Array of o3d object elements.
207 */
208 function initStep2(clientElements) {
209 // Initializes global variables and libraries.
210 g_o3dElement = clientElements[0];
211 g_o3d = g_o3dElement.o3d;
212 g_math = o3djs.math;
213 g_client = g_o3dElement.client;
214
215 // Convert anim frames to anim times.
216 for (var animName in g_anims) {
217 var anim = g_anims[animName];
218 anim.startTime = anim.startFrame / 30;
219 anim.endTime = anim.endFrame / 30;
220 anim.timeRange = anim.endTime - anim.startTime;
221 }
222
223 // Creates a pack to manage our resources/assets
224 g_pack = g_client.createPack();
225
226 g_root = g_pack.createObject('Transform');
227
228 g_viewInfo = o3djs.rendergraph.createBasicView(
229 g_pack,
230 g_root,
231 g_client.renderGraphRoot);
232
233 updateCamera();
234
235 g_globalParams = o3djs.material.createAndBindStandardParams(g_pack);
236 g_globalParams.lightWorldPos.value = [600, 2000, 400];
237 g_globalParams.lightColor.value = [1, 1, 1, 1];
238
239 // Load character.
240 var transform = g_pack.createObject('Transform');
241 g_playerTransform = transform;
242 var playerPack = g_client.createPack();
243 var paramObject = playerPack.createObject('ParamObject');
244 g_animParam = paramObject.createParam('animTime', 'ParamFloat');
245 var loader = o3djs.loader.createLoader(initStep3);
246 loader.loadScene(g_client, playerPack, g_playerTransform,
247 'assets/character.o3dtgz', prepareScene,
248 {opt_animSource: g_animParam});
249 var worldPack = g_client.createPack();
250 g_worldTransform = worldPack.createObject('Transform');
251 loader.loadScene(g_client, worldPack, g_worldTransform,
252 'assets/background.o3dtgz', prepareScene)
253 loader.finish();
254 }
255
256 /**
257 * Setup the just loaded scene.
258 * @param {!o3d.Pack} pack The pack the scene was loaded into.
259 * @param {!o3d.Transform} parent The parent of the scene.
260 * @param {*} exception An exception or null if success.
261 */
262 function prepareScene(pack, parent, exception) {
263 o3djs.pack.preparePack(pack, g_viewInfo);
264 o3djs.material.bindParams(pack, g_globalParams);
265 parent.parent = g_root;
266 }
267
268 /**
269 * Continue setting up after the both the model and character have loaded.
270 */
271 function initStep3() {
272 // Fix for artists not using the same scale on background vs character
273 g_worldTransform.scale(10, 10, 10);
274 // Fix for current collada import bugs.
275 var m = g_client.getObjects('Road', 'o3d.Material')[0];
276 m.getParam('shininess').value = 100;
277
278 g_particleSystem = o3djs.particles.createParticleSystem(g_pack, g_viewInfo);
279 g_poofEmitter = g_particleSystem.createParticleEmitter();
280 g_poofEmitter.setState(o3djs.particles.ParticleStateIds.ADD);
281 g_poofEmitter.setColorRamp(
282 [1, 1, 1, 0.3,
283 1, 1, 1, 0]);
284 g_poofEmitter.setParameters({
285 numParticles: 30,
286 lifeTime: 0.5,
287 startTime: 0,
288 startSize: 5,
289 endSize: 10,
290 spinSpeedRange: 10},
291 function(index, parameters) {
292 var angle = Math.random() * 2 * Math.PI;
293 parameters.velocity = g_math.matrix4.transformPoint(
294 g_math.matrix4.rotationY(angle), [25, 2.5, 0]);
295 parameters.acceleration = g_math.mulVectorVector(
296 parameters.velocity, [-1.5, 1, -1.5]);
297 });
298 g_poof = g_poofEmitter.createOneShot(g_root);
299
300 // Setup a render callback for per frame processing.
301 g_client.setRenderCallback(onRender);
302
303 o3djs.event.addEventListener(g_o3dElement, 'keydown', onKeyDown);
304 o3djs.event.addEventListener(g_o3dElement, 'keyup', onKeyUp);
305
306 window.g_finished = true; // for selenium testing.
307 window.o3d_prepForSelenium = function() {
308 g_animParam.value = 0;
309 g_animParam = {value: 0};
310 }
311 }
312
313 /**
314 * Tracks key down events.
315 * @param {Event} e keyboard event.
316 */
317 function onKeyDown(e) {
318 g_keyDown[e.keyCode] = true;
319 }
320
321 /**
322 * Tracks key up events.
323 * @param {Event} e keyboard event.
324 */
325 function onKeyUp(e) {
326 g_keyDown[e.keyCode] = false;
327 }
328
329 /**
330 * Look at keys.
331 */
332 function handleMoveKeys(elapsedTime) {
333 var directionX = 0;
334 var directionZ = 0;
335
336 if (g_keyDown[37] || g_keyDown[65]) { directionX = -1; }
337 if (g_keyDown[39] || g_keyDown[68]) { directionX = 1; }
338 if (g_keyDown[38] || g_keyDown[87]) { directionZ = -1; }
339 if (g_keyDown[40] || g_keyDown[83]) { directionZ = 1; }
340
341 if (g_canJump) {
342 if (g_keyDown[32]) {
343 startMode(g_modes.JUMP);
344 }
345 } else {
346 if (!g_jumping) {
347 if (!g_keyDown[32]) {
348 g_canJump = true;
349 }
350 }
351 }
352
353 if (directionX != 0 || directionZ != 0) {
354 if (!g_jumping) {
355 startMode(g_modes.WALK);
356 }
357 var moveTranslation = g_math.matrix4.transformPoint(
358 g_moveMatrix,
359 [MOVE_VELOCITY * directionX, 0, MOVE_VELOCITY * directionZ]);
360 g_targetDirection = Math.atan2(moveTranslation[0],
361 moveTranslation[2]);
362 g_playerVelocity[0] = moveTranslation[0];
363 g_playerVelocity[2] = moveTranslation[2];
364 } else {
365 g_playerVelocity[0] = 0;
366 g_playerVelocity[2] = 0;
367 if (!g_jumping) {
368 startMode(g_modes.IDLE);
369 }
370 }
371 }
372
373 /**
374 * Move the camera.
375 */
376 function moveCamera() {
377 var newTarget = [g_playerPosition[0], 10, g_playerPosition[2]];
378 g_target = g_math.lerpVector(g_target, newTarget, 0.03);
379 updateCamera();
380 }
381
382 /**
383 * Updates the direction.
384 * @param {number} elapsedTime Time elasped since last frame.
385 */
386 function updateDirection(elapsedTime) {
387 g_playerDirection = g_math.lerpRadian(g_playerDirection, g_targetDirection,
388 0.2);
389 }
390
391 /**
392 * Adds gravity to velocity.
393 * @param {number} elapsedTime Time elasped since last frame.
394 */
395 function calculateGravity(elapsedTime) {
396 g_playerVelocity[1] += GRAVITY * elapsedTime;
397 }
398
399 /**
400 * Updates the player's position.
401 * @param {number} elapsedTime Time elasped since last frame.
402 */
403 function updateMovement(elapsedTime) {
404 g_playerPosition = g_math.addVector(g_playerPosition,
405 g_math.mulVectorScalar(g_playerVelocity,
406 elapsedTime));
407 }
408
409 var g_modes = {};
410
411 /**
412 * Handle idle mode.
413 */
414 g_modes.IDLE = {
415 init: function() {
416 startAnimation(g_anims.idle1);
417 g_jumping = false;
418 },
419 handle: function(elapsedTime) {
420 updateDirection(elapsedTime);
421 g_animTimer += elapsedTime;
422 if (g_animTimer >= g_animation.endTime) {
423 // Pick an idle at random.
424 var idle = 0;
425 if (Math.random() > 0.8) {
426 // Choose another idle.
427 idle = Math.floor(Math.random() * 10 / 3);
428 if (idle > 3) {
429 idle = 3;
430 }
431 }
432 var idleName = 'idle' + (idle + 1);
433 startAnimation(g_anims[idleName]);
434 }
435 }
436 };
437
438 /**
439 * Handle walk mode.
440 */
441 g_modes.WALK = {
442 init: function() {
443 startAnimation(g_anims.run);
444 g_jumping = false;
445 },
446 handle: function(elapsedTime) {
447 updateDirection(elapsedTime);
448 updateMovement(elapsedTime);
449 g_animTimer += elapsedTime;
450 if (g_animTimer >= g_animation.endTime) {
451 g_animTimer = g_math.modClamp(g_animTimer,
452 g_animation.timeRange,
453 g_animation.startTime);
454 }
455 }
456 };
457
458 /**
459 * Handle jump mode.
460 */
461 g_modes.JUMP = {
462 init: function() {
463 startAnimation(g_anims.jumpStart);
464 g_jumping = true;
465 g_canJump = false;
466 g_playerVelocity[1] = JUMP_VELOCITY;
467 },
468 handle: function(elapsedTime) {
469 g_animTimer += elapsedTime;
470 if (g_animTimer >= g_animation.endTime) {
471 startMode(g_modes.JUMP_UP);
472 }
473 }
474 };
475
476 g_modes.JUMP_UP = {
477 init: function() {
478 startAnimation(g_anims.jumpUp);
479 },
480 handle: function(elapsedTime) {
481 updateDirection(elapsedTime);
482 calculateGravity(elapsedTime);
483 updateMovement(elapsedTime);
484 if (g_playerVelocity[1] < 10) {
485 startMode(g_modes.JUMP_CREST);
486 }
487 }
488 };
489
490 g_modes.JUMP_CREST = {
491 init: function() {
492 startAnimation(g_anims.jumpCrest);
493 },
494 handle: function(elapsedTime) {
495 updateDirection(elapsedTime);
496 calculateGravity(elapsedTime);
497 updateMovement(elapsedTime);
498 g_animTimer += elapsedTime;
499 if (g_animTimer >= g_animation.endTime) {
500 startMode(g_modes.JUMP_FALL);
501 }
502 }
503 };
504
505 g_modes.JUMP_FALL = {
506 init: function() {
507 startAnimation(g_anims.jumpFall);
508 },
509 handle: function(elapsedTime) {
510 updateDirection(elapsedTime);
511 calculateGravity(elapsedTime);
512 updateMovement(elapsedTime);
513 if (g_playerPosition[1] <= 0) {
514 startMode(g_modes.JUMP_LAND);
515 g_playerPosition[1] = 0;
516 g_playerVelocity[1] = 0;
517 g_poof.trigger(g_playerPosition);
518 }
519 }
520 };
521
522 g_modes.JUMP_LAND = {
523 init: function() {
524 startAnimation(g_anims.jumpLand);
525 },
526 handle: function(elapsedTime) {
527 updateDirection(elapsedTime);
528 g_animTimer += elapsedTime;
529 if (g_animTimer >= g_animation.endTime) {
530 g_jumping = false;
531 startMode(g_modes.IDLE);
532 }
533 }
534 };
535
536 function updatePlayer() {
537 g_animParam.value = g_animTimer;
538 g_playerTransform.identity();
539 g_playerTransform.translate(g_playerPosition);
540 g_playerTransform.rotateY(g_playerDirection);
541 }
542
543 /**
544 * Called every frame.
545 * @param {!o3d.RenderEvent} renderEvent Rendering Information.
546 */
547 function onRender(renderEvent) {
548 var elapsedTime = renderEvent.elapsedTime;
549 updateClientSize();
550 handleMoveKeys(elapsedTime);
551 g_playerMode.handle(elapsedTime);
552 updatePlayer();
553 moveCamera();
554 };
555
556 /**
557 * Remove any callbacks so they don't get called after the page has unloaded.
558 */
559 function unload() {
560 if (g_client) {
561 g_client.cleanup();
562 }
563 }
564 </script>
565 </head>
566 <body>
567 <table style="width: 100%; height:100%;">
568 <tr style="height: 50px;"><td>
569 <div style="width: 100%; height: 50px; font-size: large;">
570 <img src="assets/colorbar.png" width="100%" height="10px"/><br/>
571 Google I/O 2009 O3D Sample
572 </div>
573 </td></tr>
574 <tr style="height: 100%;"><td>
575 <div style="width: 100%; height: 100%;">
576 <div id="o3d" style="width: 100%; height: 100%;"></div>
577 </div>
578 </td></tr>
579 </table>
580 </body>
581 </html>
OLDNEW
« no previous file with comments | « samples/GoogleIO-2009/step13.html ('k') | samples/MANIFEST » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698