OLD | NEW |
(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 <!-- |
| 33 Particles. |
| 34 |
| 35 This example shows using the javascript particle library. |
| 36 --> |
| 37 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" |
| 38 "http://www.w3.org/TR/html4/loose.dtd"> |
| 39 <html> |
| 40 <head> |
| 41 <meta http-equiv="content-type" content="text/html; charset=UTF-8"> |
| 42 <title> |
| 43 Particles. |
| 44 </title> |
| 45 <!-- Include sample javascript library functions--> |
| 46 <script type="text/javascript" src="../o3djs/base.js"></script> |
| 47 <script type="text/javascript" src="../o3d-webgl/base.js"></script> |
| 48 <!-- Our javascript code --> |
| 49 <script type="text/javascript" id="o3dscript"> |
| 50 o3djs.base.o3d = o3d; |
| 51 o3djs.require('o3djs.webgl'); |
| 52 o3djs.require('o3djs.util'); |
| 53 o3djs.require('o3djs.math'); |
| 54 o3djs.require('o3djs.quaternions'); |
| 55 o3djs.require('o3djs.rendergraph'); |
| 56 o3djs.require('o3djs.particles'); |
| 57 o3djs.require('o3djs.loader'); |
| 58 |
| 59 // global variables |
| 60 var g_o3d; |
| 61 var g_math; |
| 62 var g_client; |
| 63 var g_viewInfo; |
| 64 var g_pack; |
| 65 var g_particleSystem; |
| 66 var g_clockParam; |
| 67 var g_textures = []; |
| 68 var g_emitters = []; // so we can find in the debugger to edit in real time. |
| 69 var g_poofs = []; |
| 70 var g_keyDown = []; |
| 71 var g_poofIndex = 0; |
| 72 var g_trail; |
| 73 var g_trailParameters; |
| 74 |
| 75 var MAX_POOFS = 3; |
| 76 |
| 77 /** |
| 78 * Loads a texture. |
| 79 * @param {!o3djs.loader.Loader} loader Loader to use to load texture. |
| 80 * @param {string} url relativel url of texture. |
| 81 * @param {number} index Index at which to record texture. |
| 82 */ |
| 83 function loadTexture(loader, url, index) { |
| 84 loader.loadTexture( |
| 85 g_pack, |
| 86 o3djs.util.getAbsoluteURI(url), |
| 87 function(texture, exception) { |
| 88 if (exception) { |
| 89 alert(exception); |
| 90 } else { |
| 91 g_textures[index] = texture; |
| 92 } |
| 93 }); |
| 94 } |
| 95 |
| 96 /** |
| 97 * Creates the client area. |
| 98 */ |
| 99 function init() { |
| 100 // These are here so they are shared by both V8 and the browser. |
| 101 window.g_finished = false; // for selenium |
| 102 window.g_timeMult = 1; |
| 103 window.g_clock = 0; |
| 104 |
| 105 // Comment out the line below to run the sample in the browser JavaScript |
| 106 // engine. This may be helpful for debugging. |
| 107 o3djs.util.setMainEngine(o3djs.util.Engine.V8); |
| 108 o3djs.particles.setLanguage('glsl'); |
| 109 |
| 110 o3djs.webgl.makeClients(initStep2); |
| 111 } |
| 112 |
| 113 /** |
| 114 * Initializes O3D and creates one shape. |
| 115 * @param {Array} clientElements Array of o3d object elements. |
| 116 */ |
| 117 function initStep2(clientElements) { |
| 118 // Initializes global variables and libraries. |
| 119 var o3dElement = clientElements[0]; |
| 120 g_o3d = o3dElement.o3d; |
| 121 g_math = o3djs.math; |
| 122 window.g_client = g_client = o3dElement.client; |
| 123 |
| 124 // Creates a pack to manage our resources/assets |
| 125 g_pack = g_client.createPack(); |
| 126 |
| 127 g_viewInfo = o3djs.rendergraph.createBasicView( |
| 128 g_pack, |
| 129 g_client.root, |
| 130 g_client.renderGraphRoot); |
| 131 |
| 132 g_viewInfo.drawContext.projection = g_math.matrix4.perspective( |
| 133 g_math.degToRad(30), // 30 degree fov. |
| 134 g_client.width / g_client.height, |
| 135 0.1, // Near plane. |
| 136 5000); // Far plane. |
| 137 |
| 138 g_viewInfo.drawContext.view = g_math.matrix4.lookAt( |
| 139 [500, 1000, 1000], // eye |
| 140 [0, 200, 0], // target |
| 141 [0, 1, 0]); // up |
| 142 |
| 143 // Load textures. This happens asynchronously. |
| 144 var loader = o3djs.loader.createLoader(initStep3); |
| 145 loadTexture(loader, '../assets/particle-anim.png', 0); |
| 146 loadTexture(loader, '../assets/ripple.png', 1); |
| 147 loader.finish(); |
| 148 } |
| 149 |
| 150 function initStep3() { |
| 151 // Normally we wouldn't pass in a clock and the particle system would handle |
| 152 // this for me but for selenium testing we need to be able to control the |
| 153 // clock so we're passing in our own clock param. |
| 154 var paramObject = g_pack.createObject('ParamObject'); |
| 155 g_clockParam = paramObject.createParam('clock', 'ParamFloat'); |
| 156 |
| 157 // Normally we wouldn't pass in a random function but for selenium we need |
| 158 // the particle system to produce the exact same results each time so |
| 159 // we're passing in a predictable random function. |
| 160 g_particleSystem = o3djs.particles.createParticleSystem( |
| 161 g_pack, |
| 162 g_viewInfo, |
| 163 g_clockParam, |
| 164 g_math.pseudoRandom); |
| 165 setupFlame(); |
| 166 setupNaturalGasFlame(); |
| 167 setupSmoke(); |
| 168 setupWhiteEnergy(); |
| 169 setupGoogle(); |
| 170 setupRain(); |
| 171 setupRipples(); |
| 172 setupAnim(); |
| 173 setupBall(); |
| 174 setupCube(); |
| 175 setupPoof(); |
| 176 setupTrail(); |
| 177 |
| 178 window.document.onkeypress = onKeyPress; |
| 179 window.document.onkeydown = onKeyDown; |
| 180 window.document.onkeyup = onKeyUp; |
| 181 |
| 182 // Setup an onrender callback for animation. |
| 183 g_client.setRenderCallback(onrender); |
| 184 |
| 185 window.g_finished = true; // for selenium testing. |
| 186 } |
| 187 |
| 188 function onKeyPress(event) { |
| 189 event = event || window.event; |
| 190 |
| 191 var keyChar = String.fromCharCode(o3djs.event.getEventKeyChar(event)); |
| 192 // Just in case they have capslock on. |
| 193 keyChar = keyChar.toLowerCase(); |
| 194 |
| 195 switch (keyChar) { |
| 196 case 'p': |
| 197 triggerPoof(); |
| 198 break; |
| 199 } |
| 200 } |
| 201 |
| 202 function onKeyDown(event) { |
| 203 event = event || window.event; |
| 204 g_keyDown[o3djs.event.getEventKeyChar(event)] = true; |
| 205 } |
| 206 |
| 207 function onKeyUp(event) { |
| 208 event = event || window.event; |
| 209 g_keyDown[o3djs.event.getEventKeyChar(event)] = false; |
| 210 } |
| 211 |
| 212 function setupFlame() { |
| 213 var transform = g_pack.createObject('Transform'); |
| 214 transform.parent = g_client.root; |
| 215 transform.translate(-300, 0, 0); |
| 216 |
| 217 var emitter = g_particleSystem.createParticleEmitter(); |
| 218 g_emitters.push(emitter); |
| 219 emitter.setState(o3djs.particles.ParticleStateIds.ADD); |
| 220 emitter.setColorRamp( |
| 221 [1, 1, 0, 1, |
| 222 1, 0, 0, 1, |
| 223 0, 0, 0, 1, |
| 224 0, 0, 0, 0.5, |
| 225 0, 0, 0, 0]); |
| 226 emitter.setParameters({ |
| 227 numParticles: 20, |
| 228 lifeTime: 2, |
| 229 timeRange: 2, |
| 230 startSize: 50, |
| 231 endSize: 90, |
| 232 velocity:[0, 60, 0], velocityRange: [15, 15, 15], |
| 233 worldAcceleration: [0, -20, 0], |
| 234 spinSpeedRange: 4}); |
| 235 transform.addShape(emitter.shape); |
| 236 } |
| 237 |
| 238 function setupNaturalGasFlame() { |
| 239 var transform = g_pack.createObject('Transform'); |
| 240 transform.parent = g_client.root; |
| 241 transform.translate(-200, 0, 0); |
| 242 |
| 243 var emitter = g_particleSystem.createParticleEmitter(); |
| 244 g_emitters.push(emitter); |
| 245 emitter.setState(o3djs.particles.ParticleStateIds.ADD); |
| 246 emitter.setColorRamp( |
| 247 [0.2, 0.2, 1, 1, |
| 248 0, 0, 1, 1, |
| 249 0, 0, 1, 0.5, |
| 250 0, 0, 1, 0]); |
| 251 emitter.setParameters({ |
| 252 numParticles: 20, |
| 253 lifeTime: 2, |
| 254 timeRange: 2, |
| 255 startSize: 50, |
| 256 endSize: 20, |
| 257 velocity:[0, 60, 0], |
| 258 worldAcceleration: [0, -20, 0], |
| 259 spinSpeedRange: 4}); |
| 260 transform.addShape(emitter.shape); |
| 261 } |
| 262 |
| 263 function setupSmoke() { |
| 264 var transform = g_pack.createObject('Transform'); |
| 265 transform.parent = g_client.root; |
| 266 transform.translate(-100, 0, 0); |
| 267 |
| 268 var emitter = g_particleSystem.createParticleEmitter(); |
| 269 g_emitters.push(emitter); |
| 270 emitter.setState(o3djs.particles.ParticleStateIds.BLEND); |
| 271 emitter.setColorRamp( |
| 272 [0, 0, 0, 1, |
| 273 0, 0, 0, 0]); |
| 274 emitter.setParameters({ |
| 275 numParticles: 20, |
| 276 lifeTime: 2, |
| 277 timeRange: 2, |
| 278 startSize: 100, |
| 279 endSize: 150, |
| 280 velocity: [0, 200, 0], velocityRange: [20, 0, 20], |
| 281 worldAcceleration: [0, -25, 0], |
| 282 spinSpeedRange: 4}); |
| 283 transform.addShape(emitter.shape); |
| 284 } |
| 285 |
| 286 function setupWhiteEnergy() { |
| 287 var transform = g_pack.createObject('Transform'); |
| 288 transform.parent = g_client.root; |
| 289 transform.translate(0, 0, 0); |
| 290 |
| 291 var emitter = g_particleSystem.createParticleEmitter(); |
| 292 g_emitters.push(emitter); |
| 293 emitter.setState(o3djs.particles.ParticleStateIds.ADD); |
| 294 emitter.setColorRamp( |
| 295 [1, 1, 1, 1, |
| 296 1, 1, 1, 0]); |
| 297 emitter.setParameters({ |
| 298 numParticles: 80, |
| 299 lifeTime: 2, |
| 300 timeRange: 2, |
| 301 startSize: 100, |
| 302 endSize: 100, |
| 303 positionRange: [100, 0, 100], |
| 304 velocityRange: [20, 0, 20]}); |
| 305 transform.addShape(emitter.shape); |
| 306 } |
| 307 |
| 308 function setupRipples() { |
| 309 var transform = g_pack.createObject('Transform'); |
| 310 transform.parent = g_client.root; |
| 311 transform.translate(-200, 0, 300); |
| 312 |
| 313 var emitter = g_particleSystem.createParticleEmitter(g_textures[1]); |
| 314 g_emitters.push(emitter); |
| 315 emitter.setState(o3djs.particles.ParticleStateIds.BLEND); |
| 316 emitter.setColorRamp( |
| 317 [0.7, 0.8, 1, 1, |
| 318 1, 1, 1, 0]); |
| 319 emitter.setParameters({ |
| 320 numParticles: 20, |
| 321 lifeTime: 2, |
| 322 timeRange: 2, |
| 323 startSize: 50, |
| 324 endSize: 200, |
| 325 positionRange: [100, 0, 100], |
| 326 billboard: false}); |
| 327 transform.addShape(emitter.shape); |
| 328 } |
| 329 |
| 330 function setupGoogle() { |
| 331 var image = [ |
| 332 '.XXXX...XXXXX...XXXXX.', |
| 333 'X....X.......X..X....X', |
| 334 'X....X...XXXXX..X....X', |
| 335 'X....X.......X..X....X', |
| 336 '.XXXX...XXXXX...XXXXX.']; |
| 337 var height = image.length; |
| 338 var width = image[0].length; |
| 339 |
| 340 // Make an array of positions based on the text image. |
| 341 var positions = []; |
| 342 for (var yy = 0; yy < height; ++yy) { |
| 343 for (var xx = 0; xx < width; ++xx) { |
| 344 if (image[yy].substring(xx, xx + 1) == 'X') { |
| 345 positions.push([(xx - width * 0.5) * 10, |
| 346 -(yy - height * 0.5) * 10]); |
| 347 } |
| 348 } |
| 349 } |
| 350 var transform = g_pack.createObject('Transform'); |
| 351 transform.parent = g_client.root; |
| 352 transform.translate(100, 200, 0); |
| 353 |
| 354 var emitter = g_particleSystem.createParticleEmitter(); |
| 355 g_emitters.push(emitter); |
| 356 emitter.setState(o3djs.particles.ParticleStateIds.ADD); |
| 357 emitter.setColorRamp( |
| 358 [1, 0, 0, 1, |
| 359 0, 1, 0, 1, |
| 360 0, 0, 1, 1, |
| 361 1, 1, 0, 0]); |
| 362 emitter.setParameters({ |
| 363 numParticles: positions.length * 4, |
| 364 lifeTime: 2, |
| 365 timeRange: 2, |
| 366 startSize: 25, |
| 367 endSize: 50, |
| 368 positionRange: [2, 0, 2], |
| 369 velocity: [1, 0, 1]}, |
| 370 function(particleIndex, parameters) { |
| 371 //var index = particleIndex; |
| 372 var index = Math.floor(g_math.pseudoRandom() * positions.length); |
| 373 index = Math.min(index, positions.length - 1); |
| 374 parameters.position[0] = positions[index][0]; |
| 375 parameters.position[1] = positions[index][1]; |
| 376 }); |
| 377 transform.addShape(emitter.shape); |
| 378 } |
| 379 |
| 380 function setupRain() { |
| 381 var transform = g_pack.createObject('Transform'); |
| 382 transform.parent = g_client.root; |
| 383 transform.translate(200, 200, 0); |
| 384 |
| 385 var emitter = g_particleSystem.createParticleEmitter(); |
| 386 g_emitters.push(emitter); |
| 387 emitter.setState(o3djs.particles.ParticleStateIds.BLEND); |
| 388 emitter.setColorRamp( |
| 389 [0.2, 0.2, 1, 1]); |
| 390 emitter.setParameters({ |
| 391 numParticles: 80, |
| 392 lifeTime: 2, |
| 393 timeRange: 2, |
| 394 startSize: 5, |
| 395 endSize: 5, |
| 396 positionRange: [100, 0, 100], |
| 397 velocity: [0,-150,0]}); |
| 398 transform.addShape(emitter.shape); |
| 399 } |
| 400 |
| 401 function setupAnim(texture) { |
| 402 var transform = g_pack.createObject('Transform'); |
| 403 transform.parent = g_client.root; |
| 404 transform.translate(300, 0, 0); |
| 405 |
| 406 var emitter = g_particleSystem.createParticleEmitter(g_textures[0]); |
| 407 g_emitters.push(emitter); |
| 408 emitter.setColorRamp( |
| 409 [1, 1, 1, 1, |
| 410 1, 1, 1, 1, |
| 411 1, 1, 1, 0]); |
| 412 emitter.setParameters({ |
| 413 numParticles: 20, |
| 414 numFrames: 8, |
| 415 frameDuration: 0.25, |
| 416 frameStartRange: 8, |
| 417 lifeTime: 2, |
| 418 timeRange: 2, |
| 419 startSize: 50, |
| 420 endSize: 90, |
| 421 positionRange: [10, 10, 10], |
| 422 velocity:[0, 200, 0], velocityRange: [75, 15, 75], |
| 423 acceleration: [0, -150, 0], |
| 424 spinSpeedRange: 1}); |
| 425 transform.addShape(emitter.shape); |
| 426 } |
| 427 |
| 428 function setupBall() { |
| 429 var transform = g_pack.createObject('Transform'); |
| 430 transform.parent = g_client.root; |
| 431 transform.translate(-400, 0, -200); |
| 432 |
| 433 var emitter = g_particleSystem.createParticleEmitter(g_textures[1]); |
| 434 g_emitters.push(emitter); |
| 435 emitter.setState(o3djs.particles.ParticleStateIds.BLEND); |
| 436 emitter.setColorRamp( |
| 437 [1, 1, 1, 1, |
| 438 1, 1, 1, 0]); |
| 439 emitter.setParameters({ |
| 440 numParticles: 300, |
| 441 lifeTime: 2, |
| 442 timeRange: 2, |
| 443 startSize: 10, |
| 444 endSize: 50, |
| 445 colorMult: [1, 1, 0.5, 1], colorMultRange: [0, 0, 0.5, 0], |
| 446 billboard: false}, |
| 447 function(particleIndex, parameters) { |
| 448 var matrix = g_math.matrix4.rotationY( |
| 449 g_math.pseudoRandom() * Math.PI * 2); |
| 450 g_math.matrix4.rotateX(matrix, g_math.pseudoRandom() * Math.PI); |
| 451 var position = g_math.matrix4.transformDirection(matrix, [0, 100, 0]); |
| 452 parameters.position = position; |
| 453 parameters.orientation = o3djs.quaternions.rotationToQuaternion(matrix); |
| 454 }); |
| 455 transform.addShape(emitter.shape); |
| 456 } |
| 457 |
| 458 function setupCube() { |
| 459 var transform = g_pack.createObject('Transform'); |
| 460 transform.parent = g_client.root; |
| 461 transform.translate(200, 0, -300); |
| 462 |
| 463 var emitter = g_particleSystem.createParticleEmitter(g_textures[1]); |
| 464 g_emitters.push(emitter); |
| 465 emitter.setState(o3djs.particles.ParticleStateIds.ADD); |
| 466 emitter.setColorRamp( |
| 467 [1, 1, 1, 1, |
| 468 0, 0, 1, 1, |
| 469 1, 1, 1, 0]); |
| 470 emitter.setParameters({ |
| 471 numParticles: 300, |
| 472 lifeTime: 2, |
| 473 timeRange: 2, |
| 474 startSize: 10, |
| 475 endSize: 50, |
| 476 colorMult: [0.8, 0.9, 1, 1], |
| 477 billboard: false}, |
| 478 function(particleIndex, parameters) { |
| 479 var matrix = g_math.matrix4.rotationY( |
| 480 Math.floor(g_math.pseudoRandom() * 4) * Math.PI * 0.5); |
| 481 g_math.matrix4.rotateX( |
| 482 matrix, |
| 483 Math.floor(g_math.pseudoRandom() * 3) * Math.PI * 0.5); |
| 484 parameters.orientation = o3djs.quaternions.rotationToQuaternion(matrix); |
| 485 var position = g_math.matrix4.transformDirection( |
| 486 matrix, |
| 487 [g_math.pseudoRandom() * 200 - 100, |
| 488 100, |
| 489 g_math.pseudoRandom() * 200 - 100]); |
| 490 parameters.position = position; |
| 491 }); |
| 492 transform.addShape(emitter.shape); |
| 493 } |
| 494 |
| 495 function setupPoof() { |
| 496 var emitter = g_particleSystem.createParticleEmitter(); |
| 497 emitter.setState(o3djs.particles.ParticleStateIds.ADD); |
| 498 emitter.setColorRamp( |
| 499 [1, 1, 1, 0.3, |
| 500 1, 1, 1, 0]); |
| 501 emitter.setParameters({ |
| 502 numParticles: 30, |
| 503 lifeTime: 1.5, |
| 504 startTime: 0, |
| 505 startSize: 50, |
| 506 endSize: 200, |
| 507 spinSpeedRange: 10}, |
| 508 function(index, parameters) { |
| 509 var angle = Math.random() * 2 * Math.PI; |
| 510 parameters.velocity = g_math.matrix4.transformPoint( |
| 511 g_math.matrix4.rotationY(angle), [300, 0, 0]); |
| 512 parameters.acceleration = g_math.mulVectorVector( |
| 513 parameters.velocity, [-0.3, 0, -0.3]); |
| 514 }); |
| 515 // make 3 poofs one shots |
| 516 for (var ii = 0; ii < MAX_POOFS; ++ii) { |
| 517 g_poofs[ii] = emitter.createOneShot(g_client.root); |
| 518 } |
| 519 } |
| 520 |
| 521 function triggerPoof() { |
| 522 // We have multiple poofs because if you only have one and it is still going |
| 523 // when you trigger it a second time it will immediately start over. |
| 524 g_poofs[g_poofIndex].trigger([100 + 100 * g_poofIndex, 0, 300]); |
| 525 g_poofIndex++; |
| 526 if (g_poofIndex == MAX_POOFS) { |
| 527 g_poofIndex = 0; |
| 528 } |
| 529 } |
| 530 |
| 531 function setupTrail() { |
| 532 g_trailParameters = { |
| 533 numParticles: 2, |
| 534 lifeTime: 2, |
| 535 startSize: 10, |
| 536 endSize: 90, |
| 537 velocityRange: [20, 20, 20], |
| 538 spinSpeedRange: 4}; |
| 539 g_trail = g_particleSystem.createTrail( |
| 540 g_client.root, |
| 541 1000, |
| 542 g_trailParameters); |
| 543 g_trail.setState(o3djs.particles.ParticleStateIds.ADD); |
| 544 g_trail.setColorRamp( |
| 545 [1, 0, 0, 1, |
| 546 1, 1, 0, 1, |
| 547 1, 1, 1, 0]); |
| 548 } |
| 549 |
| 550 function leaveTrail() { |
| 551 var trailClock = window.g_clock * -0.8; |
| 552 g_trail.birthParticles( |
| 553 [Math.sin(trailClock) * 400, 200, Math.cos(trailClock) * 400]); |
| 554 } |
| 555 |
| 556 /** |
| 557 * Called every frame. |
| 558 * @param {!o3d.RenderEvent} renderEvent Rendering Information. |
| 559 */ |
| 560 function onrender(renderEvent) { |
| 561 var elapsedTime = renderEvent.elapsedTime; |
| 562 window.g_clock += elapsedTime * window.g_timeMult; |
| 563 |
| 564 if (g_keyDown[84]) { // 'T' key. |
| 565 leaveTrail(); |
| 566 } |
| 567 |
| 568 var cameraClock = window.g_clock * 0.3; |
| 569 g_viewInfo.drawContext.view = g_math.matrix4.lookAt( |
| 570 [Math.sin(cameraClock) * 1500, 500, Math.cos(cameraClock) * 1500], // eye |
| 571 [0, 100, 0], // target |
| 572 [0, 1, 0]); // up |
| 573 |
| 574 g_clockParam.value = window.g_clock; |
| 575 } |
| 576 |
| 577 /** |
| 578 * Remove any callbacks so they don't get called after the page has unloaded. |
| 579 */ |
| 580 function unload() { |
| 581 if (g_client) { |
| 582 g_client.cleanup(); |
| 583 } |
| 584 } |
| 585 </script> |
| 586 </head> |
| 587 <body onload="init();" onunload="unload();"> |
| 588 <h1>Particles</h1> |
| 589 <br/> |
| 590 <!-- Start of O3D plugin --> |
| 591 <div id="o3d" style="width: 800px; height: 600px;"></div> |
| 592 <!-- End of O3D plugin --> |
| 593 Press 'P' to make a poof.<br/> |
| 594 Hold 'T' to make a trail. |
| 595 </body> |
| 596 </html> |
OLD | NEW |