diff options
author | luchen@google.com <luchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-27 22:21:56 +0000 |
---|---|---|
committer | luchen@google.com <luchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-27 22:21:56 +0000 |
commit | e1f44a476fbea342821e6aeb734231c606fe49d4 (patch) | |
tree | ba3f27407b3ba59e545a499e74ef508bf3e31136 /o3d/samples | |
parent | b713fa5924ad131e13dc3dd148e1a3cb2eaed010 (diff) | |
download | chromium_src-e1f44a476fbea342821e6aeb734231c606fe49d4.zip chromium_src-e1f44a476fbea342821e6aeb734231c606fe49d4.tar.gz chromium_src-e1f44a476fbea342821e6aeb734231c606fe49d4.tar.bz2 |
o3d-webgl: Adding particles demo to repository.
Review URL: http://codereview.chromium.org/3047004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@53858 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/samples')
-rw-r--r-- | o3d/samples/o3d-webgl-samples/particles.html | 596 |
1 files changed, 596 insertions, 0 deletions
diff --git a/o3d/samples/o3d-webgl-samples/particles.html b/o3d/samples/o3d-webgl-samples/particles.html new file mode 100644 index 0000000..6a4f185 --- /dev/null +++ b/o3d/samples/o3d-webgl-samples/particles.html @@ -0,0 +1,596 @@ +<!-- +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. +--> + +<!-- +Particles. + +This example shows using the javascript particle library. +--> +<!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> +Particles. +</title> +<!-- Include sample javascript library functions--> +<script type="text/javascript" src="../o3djs/base.js"></script> +<script type="text/javascript" src="../o3d-webgl/base.js"></script> +<!-- Our javascript code --> +<script type="text/javascript" id="o3dscript"> +o3djs.base.o3d = o3d; +o3djs.require('o3djs.webgl'); +o3djs.require('o3djs.util'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.quaternions'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.particles'); +o3djs.require('o3djs.loader'); + +// global variables +var g_o3d; +var g_math; +var g_client; +var g_viewInfo; +var g_pack; +var g_particleSystem; +var g_clockParam; +var g_textures = []; +var g_emitters = []; // so we can find in the debugger to edit in real time. +var g_poofs = []; +var g_keyDown = []; +var g_poofIndex = 0; +var g_trail; +var g_trailParameters; + +var MAX_POOFS = 3; + +/** + * Loads a texture. + * @param {!o3djs.loader.Loader} loader Loader to use to load texture. + * @param {string} url relativel url of texture. + * @param {number} index Index at which to record texture. + */ +function loadTexture(loader, url, index) { + loader.loadTexture( + g_pack, + o3djs.util.getAbsoluteURI(url), + function(texture, exception) { + if (exception) { + alert(exception); + } else { + g_textures[index] = texture; + } + }); +} + +/** + * Creates the client area. + */ +function init() { + // These are here so they are shared by both V8 and the browser. + window.g_finished = false; // for selenium + window.g_timeMult = 1; + window.g_clock = 0; + + // Comment out the line below to run the sample in the browser JavaScript + // engine. This may be helpful for debugging. + o3djs.util.setMainEngine(o3djs.util.Engine.V8); + o3djs.particles.setLanguage('glsl'); + + o3djs.webgl.makeClients(initStep2); +} + +/** + * Initializes O3D and creates one shape. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + var o3dElement = clientElements[0]; + g_o3d = o3dElement.o3d; + g_math = o3djs.math; + window.g_client = g_client = o3dElement.client; + + // Creates a pack to manage our resources/assets + g_pack = g_client.createPack(); + + g_viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_client.root, + g_client.renderGraphRoot); + + g_viewInfo.drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(30), // 30 degree fov. + g_client.width / g_client.height, + 0.1, // Near plane. + 5000); // Far plane. + + g_viewInfo.drawContext.view = g_math.matrix4.lookAt( + [500, 1000, 1000], // eye + [0, 200, 0], // target + [0, 1, 0]); // up + + // Load textures. This happens asynchronously. + var loader = o3djs.loader.createLoader(initStep3); + loadTexture(loader, '../assets/particle-anim.png', 0); + loadTexture(loader, '../assets/ripple.png', 1); + loader.finish(); +} + +function initStep3() { + // Normally we wouldn't pass in a clock and the particle system would handle + // this for me but for selenium testing we need to be able to control the + // clock so we're passing in our own clock param. + var paramObject = g_pack.createObject('ParamObject'); + g_clockParam = paramObject.createParam('clock', 'ParamFloat'); + + // Normally we wouldn't pass in a random function but for selenium we need + // the particle system to produce the exact same results each time so + // we're passing in a predictable random function. + g_particleSystem = o3djs.particles.createParticleSystem( + g_pack, + g_viewInfo, + g_clockParam, + g_math.pseudoRandom); + setupFlame(); + setupNaturalGasFlame(); + setupSmoke(); + setupWhiteEnergy(); + setupGoogle(); + setupRain(); + setupRipples(); + setupAnim(); + setupBall(); + setupCube(); + setupPoof(); + setupTrail(); + + window.document.onkeypress = onKeyPress; + window.document.onkeydown = onKeyDown; + window.document.onkeyup = onKeyUp; + + // Setup an onrender callback for animation. + g_client.setRenderCallback(onrender); + + window.g_finished = true; // for selenium testing. +} + +function onKeyPress(event) { + event = event || window.event; + + var keyChar = String.fromCharCode(o3djs.event.getEventKeyChar(event)); + // Just in case they have capslock on. + keyChar = keyChar.toLowerCase(); + + switch (keyChar) { + case 'p': + triggerPoof(); + break; + } +} + +function onKeyDown(event) { + event = event || window.event; + g_keyDown[o3djs.event.getEventKeyChar(event)] = true; +} + +function onKeyUp(event) { + event = event || window.event; + g_keyDown[o3djs.event.getEventKeyChar(event)] = false; +} + +function setupFlame() { + var transform = g_pack.createObject('Transform'); + transform.parent = g_client.root; + transform.translate(-300, 0, 0); + + var emitter = g_particleSystem.createParticleEmitter(); + g_emitters.push(emitter); + emitter.setState(o3djs.particles.ParticleStateIds.ADD); + emitter.setColorRamp( + [1, 1, 0, 1, + 1, 0, 0, 1, + 0, 0, 0, 1, + 0, 0, 0, 0.5, + 0, 0, 0, 0]); + emitter.setParameters({ + numParticles: 20, + lifeTime: 2, + timeRange: 2, + startSize: 50, + endSize: 90, + velocity:[0, 60, 0], velocityRange: [15, 15, 15], + worldAcceleration: [0, -20, 0], + spinSpeedRange: 4}); + transform.addShape(emitter.shape); +} + +function setupNaturalGasFlame() { + var transform = g_pack.createObject('Transform'); + transform.parent = g_client.root; + transform.translate(-200, 0, 0); + + var emitter = g_particleSystem.createParticleEmitter(); + g_emitters.push(emitter); + emitter.setState(o3djs.particles.ParticleStateIds.ADD); + emitter.setColorRamp( + [0.2, 0.2, 1, 1, + 0, 0, 1, 1, + 0, 0, 1, 0.5, + 0, 0, 1, 0]); + emitter.setParameters({ + numParticles: 20, + lifeTime: 2, + timeRange: 2, + startSize: 50, + endSize: 20, + velocity:[0, 60, 0], + worldAcceleration: [0, -20, 0], + spinSpeedRange: 4}); + transform.addShape(emitter.shape); +} + +function setupSmoke() { + var transform = g_pack.createObject('Transform'); + transform.parent = g_client.root; + transform.translate(-100, 0, 0); + + var emitter = g_particleSystem.createParticleEmitter(); + g_emitters.push(emitter); + emitter.setState(o3djs.particles.ParticleStateIds.BLEND); + emitter.setColorRamp( + [0, 0, 0, 1, + 0, 0, 0, 0]); + emitter.setParameters({ + numParticles: 20, + lifeTime: 2, + timeRange: 2, + startSize: 100, + endSize: 150, + velocity: [0, 200, 0], velocityRange: [20, 0, 20], + worldAcceleration: [0, -25, 0], + spinSpeedRange: 4}); + transform.addShape(emitter.shape); +} + +function setupWhiteEnergy() { + var transform = g_pack.createObject('Transform'); + transform.parent = g_client.root; + transform.translate(0, 0, 0); + + var emitter = g_particleSystem.createParticleEmitter(); + g_emitters.push(emitter); + emitter.setState(o3djs.particles.ParticleStateIds.ADD); + emitter.setColorRamp( + [1, 1, 1, 1, + 1, 1, 1, 0]); + emitter.setParameters({ + numParticles: 80, + lifeTime: 2, + timeRange: 2, + startSize: 100, + endSize: 100, + positionRange: [100, 0, 100], + velocityRange: [20, 0, 20]}); + transform.addShape(emitter.shape); +} + +function setupRipples() { + var transform = g_pack.createObject('Transform'); + transform.parent = g_client.root; + transform.translate(-200, 0, 300); + + var emitter = g_particleSystem.createParticleEmitter(g_textures[1]); + g_emitters.push(emitter); + emitter.setState(o3djs.particles.ParticleStateIds.BLEND); + emitter.setColorRamp( + [0.7, 0.8, 1, 1, + 1, 1, 1, 0]); + emitter.setParameters({ + numParticles: 20, + lifeTime: 2, + timeRange: 2, + startSize: 50, + endSize: 200, + positionRange: [100, 0, 100], + billboard: false}); + transform.addShape(emitter.shape); +} + +function setupGoogle() { + var image = [ + '.XXXX...XXXXX...XXXXX.', + 'X....X.......X..X....X', + 'X....X...XXXXX..X....X', + 'X....X.......X..X....X', + '.XXXX...XXXXX...XXXXX.']; + var height = image.length; + var width = image[0].length; + + // Make an array of positions based on the text image. + var positions = []; + for (var yy = 0; yy < height; ++yy) { + for (var xx = 0; xx < width; ++xx) { + if (image[yy].substring(xx, xx + 1) == 'X') { + positions.push([(xx - width * 0.5) * 10, + -(yy - height * 0.5) * 10]); + } + } + } + var transform = g_pack.createObject('Transform'); + transform.parent = g_client.root; + transform.translate(100, 200, 0); + + var emitter = g_particleSystem.createParticleEmitter(); + g_emitters.push(emitter); + emitter.setState(o3djs.particles.ParticleStateIds.ADD); + emitter.setColorRamp( + [1, 0, 0, 1, + 0, 1, 0, 1, + 0, 0, 1, 1, + 1, 1, 0, 0]); + emitter.setParameters({ + numParticles: positions.length * 4, + lifeTime: 2, + timeRange: 2, + startSize: 25, + endSize: 50, + positionRange: [2, 0, 2], + velocity: [1, 0, 1]}, + function(particleIndex, parameters) { + //var index = particleIndex; + var index = Math.floor(g_math.pseudoRandom() * positions.length); + index = Math.min(index, positions.length - 1); + parameters.position[0] = positions[index][0]; + parameters.position[1] = positions[index][1]; + }); + transform.addShape(emitter.shape); +} + +function setupRain() { + var transform = g_pack.createObject('Transform'); + transform.parent = g_client.root; + transform.translate(200, 200, 0); + + var emitter = g_particleSystem.createParticleEmitter(); + g_emitters.push(emitter); + emitter.setState(o3djs.particles.ParticleStateIds.BLEND); + emitter.setColorRamp( + [0.2, 0.2, 1, 1]); + emitter.setParameters({ + numParticles: 80, + lifeTime: 2, + timeRange: 2, + startSize: 5, + endSize: 5, + positionRange: [100, 0, 100], + velocity: [0,-150,0]}); + transform.addShape(emitter.shape); +} + +function setupAnim(texture) { + var transform = g_pack.createObject('Transform'); + transform.parent = g_client.root; + transform.translate(300, 0, 0); + + var emitter = g_particleSystem.createParticleEmitter(g_textures[0]); + g_emitters.push(emitter); + emitter.setColorRamp( + [1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 0]); + emitter.setParameters({ + numParticles: 20, + numFrames: 8, + frameDuration: 0.25, + frameStartRange: 8, + lifeTime: 2, + timeRange: 2, + startSize: 50, + endSize: 90, + positionRange: [10, 10, 10], + velocity:[0, 200, 0], velocityRange: [75, 15, 75], + acceleration: [0, -150, 0], + spinSpeedRange: 1}); + transform.addShape(emitter.shape); +} + +function setupBall() { + var transform = g_pack.createObject('Transform'); + transform.parent = g_client.root; + transform.translate(-400, 0, -200); + + var emitter = g_particleSystem.createParticleEmitter(g_textures[1]); + g_emitters.push(emitter); + emitter.setState(o3djs.particles.ParticleStateIds.BLEND); + emitter.setColorRamp( + [1, 1, 1, 1, + 1, 1, 1, 0]); + emitter.setParameters({ + numParticles: 300, + lifeTime: 2, + timeRange: 2, + startSize: 10, + endSize: 50, + colorMult: [1, 1, 0.5, 1], colorMultRange: [0, 0, 0.5, 0], + billboard: false}, + function(particleIndex, parameters) { + var matrix = g_math.matrix4.rotationY( + g_math.pseudoRandom() * Math.PI * 2); + g_math.matrix4.rotateX(matrix, g_math.pseudoRandom() * Math.PI); + var position = g_math.matrix4.transformDirection(matrix, [0, 100, 0]); + parameters.position = position; + parameters.orientation = o3djs.quaternions.rotationToQuaternion(matrix); + }); + transform.addShape(emitter.shape); +} + +function setupCube() { + var transform = g_pack.createObject('Transform'); + transform.parent = g_client.root; + transform.translate(200, 0, -300); + + var emitter = g_particleSystem.createParticleEmitter(g_textures[1]); + g_emitters.push(emitter); + emitter.setState(o3djs.particles.ParticleStateIds.ADD); + emitter.setColorRamp( + [1, 1, 1, 1, + 0, 0, 1, 1, + 1, 1, 1, 0]); + emitter.setParameters({ + numParticles: 300, + lifeTime: 2, + timeRange: 2, + startSize: 10, + endSize: 50, + colorMult: [0.8, 0.9, 1, 1], + billboard: false}, + function(particleIndex, parameters) { + var matrix = g_math.matrix4.rotationY( + Math.floor(g_math.pseudoRandom() * 4) * Math.PI * 0.5); + g_math.matrix4.rotateX( + matrix, + Math.floor(g_math.pseudoRandom() * 3) * Math.PI * 0.5); + parameters.orientation = o3djs.quaternions.rotationToQuaternion(matrix); + var position = g_math.matrix4.transformDirection( + matrix, + [g_math.pseudoRandom() * 200 - 100, + 100, + g_math.pseudoRandom() * 200 - 100]); + parameters.position = position; + }); + transform.addShape(emitter.shape); +} + +function setupPoof() { + var emitter = g_particleSystem.createParticleEmitter(); + emitter.setState(o3djs.particles.ParticleStateIds.ADD); + emitter.setColorRamp( + [1, 1, 1, 0.3, + 1, 1, 1, 0]); + emitter.setParameters({ + numParticles: 30, + lifeTime: 1.5, + startTime: 0, + startSize: 50, + endSize: 200, + spinSpeedRange: 10}, + function(index, parameters) { + var angle = Math.random() * 2 * Math.PI; + parameters.velocity = g_math.matrix4.transformPoint( + g_math.matrix4.rotationY(angle), [300, 0, 0]); + parameters.acceleration = g_math.mulVectorVector( + parameters.velocity, [-0.3, 0, -0.3]); + }); + // make 3 poofs one shots + for (var ii = 0; ii < MAX_POOFS; ++ii) { + g_poofs[ii] = emitter.createOneShot(g_client.root); + } +} + +function triggerPoof() { + // We have multiple poofs because if you only have one and it is still going + // when you trigger it a second time it will immediately start over. + g_poofs[g_poofIndex].trigger([100 + 100 * g_poofIndex, 0, 300]); + g_poofIndex++; + if (g_poofIndex == MAX_POOFS) { + g_poofIndex = 0; + } +} + +function setupTrail() { + g_trailParameters = { + numParticles: 2, + lifeTime: 2, + startSize: 10, + endSize: 90, + velocityRange: [20, 20, 20], + spinSpeedRange: 4}; + g_trail = g_particleSystem.createTrail( + g_client.root, + 1000, + g_trailParameters); + g_trail.setState(o3djs.particles.ParticleStateIds.ADD); + g_trail.setColorRamp( + [1, 0, 0, 1, + 1, 1, 0, 1, + 1, 1, 1, 0]); +} + +function leaveTrail() { + var trailClock = window.g_clock * -0.8; + g_trail.birthParticles( + [Math.sin(trailClock) * 400, 200, Math.cos(trailClock) * 400]); +} + +/** + * Called every frame. + * @param {!o3d.RenderEvent} renderEvent Rendering Information. + */ +function onrender(renderEvent) { + var elapsedTime = renderEvent.elapsedTime; + window.g_clock += elapsedTime * window.g_timeMult; + + if (g_keyDown[84]) { // 'T' key. + leaveTrail(); + } + + var cameraClock = window.g_clock * 0.3; + g_viewInfo.drawContext.view = g_math.matrix4.lookAt( + [Math.sin(cameraClock) * 1500, 500, Math.cos(cameraClock) * 1500], // eye + [0, 100, 0], // target + [0, 1, 0]); // up + + g_clockParam.value = window.g_clock; +} + +/** + * 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 onload="init();" onunload="unload();"> +<h1>Particles</h1> +<br/> +<!-- Start of O3D plugin --> +<div id="o3d" style="width: 800px; height: 600px;"></div> +<!-- End of O3D plugin --> +Press 'P' to make a poof.<br/> +Hold 'T' to make a trail. +</body> +</html> |