diff options
author | gman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-29 23:17:38 +0000 |
---|---|---|
committer | gman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-29 23:17:38 +0000 |
commit | 2a93b108437a0a23447e078a64a8d1448e7d6514 (patch) | |
tree | a2c6681e3aaeded1f6aeaf4d706476e82b5864ac /o3d/samples | |
parent | 42ca9a490f404c33ab4462ed44afec22c3ecc82b (diff) | |
download | chromium_src-2a93b108437a0a23447e078a64a8d1448e7d6514.zip chromium_src-2a93b108437a0a23447e078a64a8d1448e7d6514.tar.gz chromium_src-2a93b108437a0a23447e078a64a8d1448e7d6514.tar.bz2 |
Added particle trails for things like exhaust on a car.
Review URL: http://codereview.chromium.org/125189
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19549 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/samples')
-rw-r--r-- | o3d/samples/o3djs/base.js | 15 | ||||
-rw-r--r-- | o3d/samples/o3djs/particles.js | 393 | ||||
-rw-r--r-- | o3d/samples/particles.html | 106 |
3 files changed, 429 insertions, 85 deletions
diff --git a/o3d/samples/o3djs/base.js b/o3d/samples/o3djs/base.js index a1cd85f..4807397 100644 --- a/o3d/samples/o3djs/base.js +++ b/o3d/samples/o3djs/base.js @@ -641,6 +641,21 @@ o3djs.base.maybeDeobfuscateFunctionName_ = function(name) { }; /** + * Makes one class inherit from another. + * @param {!Object} subClass Class that wants to inherit. + * @param {!Object} superClass Class to inherit from. + */ +o3djs.base.inherit = function(subClass, superClass) { + /** + * TmpClass. + * @constructor + */ + var TmpClass = function() { }; + TmpClass.prototype = superClass.prototype; + subClass.prototype = new TmpClass(); +}; + +/** * Parses an error stack from an exception * @param {!Exception} excp The exception to get a stack trace from. * @return {!Array.<string>} An array of strings of the stack trace. diff --git a/o3d/samples/o3djs/particles.js b/o3d/samples/o3djs/particles.js index 075c363..324d85a 100644 --- a/o3d/samples/o3djs/particles.js +++ b/o3d/samples/o3djs/particles.js @@ -127,6 +127,7 @@ o3djs.particles.FX_STRINGS = [ ' output.colorMult = input.colorMult;\n' + '\n' + ' float size = lerp(startSize, endSize, percentLife);\n' + + ' size = (percentLife < 0 || percentLife > 1) ? 0 : size;\n' + ' float s = sin(spinStart + spinSpeed * localTime);\n' + ' float c = cos(spinStart + spinSpeed * localTime);\n' + '\n' + @@ -239,6 +240,7 @@ o3djs.particles.FX_STRINGS = [ ' float3 basisZ = viewInverse[1].xyz;\n' + '\n' + ' float size = lerp(startSize, endSize, percentLife);\n' + + ' size = (percentLife < 0 || percentLife > 1) ? 0 : size;\n' + ' float s = sin(spinStart + spinSpeed * localTime);\n' + ' float c = cos(spinStart + spinSpeed * localTime);\n' + '\n' + @@ -269,6 +271,18 @@ o3djs.particles.FX_STRINGS = [ '// #o3d MatrixLoadOrder RowMajor\n'}]; /** + * Corner values. + * @private + * @type {!Array.<!Array.<number>>} + */ +o3djs.particles.CORNERS_ = [ + [-0.5, -0.5], + [+0.5, -0.5], + [+0.5, +0.5], + [-0.5, +0.5]]; + + +/** * Creates a particle system. * You only need one of these to run multiple emitters of different types * of particles. @@ -676,6 +690,42 @@ o3djs.particles.ParticleSystem.prototype.createParticleEmitter = }; /** + * Creates a Trail particle emitter. + * You can use this for jet exhaust, etc... + * @param {!o3d.Transform} parent Transform to put emitter on. + * @param {number} maxParticles Maximum number of particles to appear at once. + * @param {!o3djs.particles.ParticleSpec} parameters The parameters used to + * generate particles. + * @param {!o3d.Texture} opt_texture The texture to use for the particles. + * If you don't supply a texture a default is provided. + * @param {!function(number, !o3djs.particles.ParticleSpec): void} + * opt_perParticleParamSetter A function that is called for each particle to + * allow it's parameters to be adjusted per particle. The number is the + * index of the particle being created, in other words, if numParticles is + * 20 this value will be 0 to 19. The ParticleSpec is a spec for this + * particular particle. You can set any per particle value before returning. + * @param {!o3d.ParamFloat} opt_clockParam A ParamFloat to be the clock for + * the emitter. + * @return {!o3djs.particles.Trail} A Trail object. + */ +o3djs.particles.ParticleSystem.prototype.createTrail = function( + parent, + maxParticles, + parameters, + opt_texture, + opt_perParticleParamSetter, + opt_clockParam) { + return new o3djs.particles.Trail( + this, + parent, + maxParticles, + parameters, + opt_texture, + opt_perParticleParamSetter, + opt_clockParam); +}; + +/** * A ParticleEmitter * @constructor * @param {!o3djs.particles.ParticleSystem} particleSystem The particle system @@ -688,7 +738,6 @@ o3djs.particles.ParticleSystem.prototype.createParticleEmitter = o3djs.particles.ParticleEmitter = function(particleSystem, opt_texture, opt_clockParam) { - opt_clockParam = opt_clockParam || particleSystem.clockParam; var o3d = o3djs.base.o3d; @@ -842,23 +891,29 @@ o3djs.particles.ParticleEmitter.prototype.setColorRamp = function(colorRamp) { }; /** - * Sets the parameters of the particle emitter. - * - * Each of these parameters are in pairs. The used to create a table - * of particle parameters. For each particle a specfic value is - * set like this - * - * particle.field = value + Math.random() - 0.5 * valueRange * 2; - * - * or in English - * - * particle.field = value plus or minus valueRange. - * - * So for example, if you wanted a value from 10 to 20 you'd pass 15 for value - * and 5 for valueRange because - * - * 15 + or - 5 = (10 to 20) - * + * Validates and adds missing particle parameters. + * @param {!o3djs.particles.ParticleSpec} parameters The parameters to validate. + */ +o3djs.particles.ParticleEmitter.prototype.validateParameters = function( + parameters) { + var defaults = new o3djs.particles.ParticleSpec(); + for (var key in parameters) { + if (typeof defaults[key] === 'undefined') { + throw 'unknown particle parameter "' + key + '"'; + } + } + for (var key in defaults) { + if (typeof parameters[key] === 'undefined') { + parameters[key] = defaults[key]; + } + } +}; + +/** + * Creates particles. + * @private + * @param {number} firstParticleIndex Index of first particle to create. + * @param {number} numParticles The number of particles to create. * @param {!o3djs.particles.ParticleSpec} parameters The parameters for the * emitters. * @param {!function(number, !o3djs.particles.ParticleSpec): void} @@ -868,42 +923,28 @@ o3djs.particles.ParticleEmitter.prototype.setColorRamp = function(colorRamp) { * 20 this value will be 0 to 19. The ParticleSpec is a spec for this * particular particle. You can set any per particle value before returning. */ -o3djs.particles.ParticleEmitter.prototype.setParameters = function( +o3djs.particles.ParticleEmitter.prototype.createParticles_ = function( + firstParticleIndex, + numParticles, parameters, opt_perParticleParamSetter) { - var defaults = new o3djs.particles.ParticleSpec(); - for (var key in parameters) { - if (typeof defaults[key] === 'undefined') { - throw 'unknown particle parameter "' + key + '"'; - } - defaults[key] = parameters[key]; - } - - var numParticles = defaults.numParticles; - - var uvLifeTimeFrameStart = []; - var positionStartTime = []; - var velocityStartSize = []; - var accelerationEndSize = []; - var spinStartSpinSpeed = []; - var orientation = []; - var colorMults = []; + var uvLifeTimeFrameStart = this.uvLifeTimeFrameStart_; + var positionStartTime = this.positionStartTime_; + var velocityStartSize = this.velocityStartSize_; + var accelerationEndSize = this.accelerationEndSize_; + var spinStartSpinSpeed = this.spinStartSpinSpeed_; + var orientation = this.orientation_; + var colorMults = this.colorMults_; // Set the globals. this.material.effect = - this.particleSystem.effects[defaults.billboard ? 1 : 0]; - this.material.getParam('timeRange').value = defaults.timeRange; - this.material.getParam('numFrames').value = defaults.numFrames; - this.material.getParam('frameDuration').value = defaults.frameDuration; - this.material.getParam('worldVelocity').value = defaults.worldVelocity; + this.particleSystem.effects[parameters.billboard ? 1 : 0]; + this.material.getParam('timeRange').value = parameters.timeRange; + this.material.getParam('numFrames').value = parameters.numFrames; + this.material.getParam('frameDuration').value = parameters.frameDuration; + this.material.getParam('worldVelocity').value = parameters.worldVelocity; this.material.getParam('worldAcceleration').value = - defaults.worldAcceleration; - - var corners = [ - [-0.5, -0.5], - [+0.5, -0.5], - [+0.5, +0.5], - [-0.5, +0.5]]; + parameters.worldAcceleration; var random = this.particleSystem.randomFunction_; @@ -911,6 +952,7 @@ o3djs.particles.ParticleEmitter.prototype.setParameters = function( return (random() - 0.5) * range * 2; }; + // TODO: change to not allocate. var plusMinusVector = function(range) { var v = []; for (var ii = 0; ii < range.length; ++ii) { @@ -921,44 +963,106 @@ o3djs.particles.ParticleEmitter.prototype.setParameters = function( for (var ii = 0; ii < numParticles; ++ii) { if (opt_perParticleParamSetter) { - opt_perParticleParamSetter(ii, defaults); + opt_perParticleParamSetter(ii, parameters); } - var pLifeTime = defaults.lifeTime; - var pStartTime = (defaults.startTime === null) ? - (ii * defaults.lifeTime / numParticles) : defaults.startTime; - var pFrameStart = defaults.frameStart + plusMinus(defaults.frameStartRange); + var pLifeTime = parameters.lifeTime; + var pStartTime = (parameters.startTime === null) ? + (ii * parameters.lifeTime / numParticles) : parameters.startTime; + var pFrameStart = + parameters.frameStart + plusMinus(parameters.frameStartRange); var pPosition = o3djs.math.addVector( - defaults.position, plusMinusVector(defaults.positionRange)); + parameters.position, plusMinusVector(parameters.positionRange)); var pVelocity = o3djs.math.addVector( - defaults.velocity, plusMinusVector(defaults.velocityRange)); + parameters.velocity, plusMinusVector(parameters.velocityRange)); var pAcceleration = o3djs.math.addVector( - defaults.acceleration, plusMinusVector(defaults.accelerationRange)); + parameters.acceleration, + plusMinusVector(parameters.accelerationRange)); var pColorMult = o3djs.math.addVector( - defaults.colorMult, plusMinusVector(defaults.colorMultRange)); - var pSpinStart = defaults.spinStart + plusMinus(defaults.spinStartRange); - var pSpinSpeed = defaults.spinSpeed + plusMinus(defaults.spinSpeedRange); - var pStartSize = defaults.startSize + plusMinus(defaults.startSizeRange); - var pEndSize = defaults.endSize + plusMinus(defaults.endSizeRange); - var pOrientation = defaults.orientation; + parameters.colorMult, plusMinusVector(parameters.colorMultRange)); + var pSpinStart = + parameters.spinStart + plusMinus(parameters.spinStartRange); + var pSpinSpeed = + parameters.spinSpeed + plusMinus(parameters.spinSpeedRange); + var pStartSize = + parameters.startSize + plusMinus(parameters.startSizeRange); + var pEndSize = parameters.endSize + plusMinus(parameters.endSizeRange); + var pOrientation = parameters.orientation; // make each corner of the particle. for (var jj = 0; jj < 4; ++jj) { - uvLifeTimeFrameStart.push(corners[jj][0], corners[jj][1], pLifeTime, - pFrameStart); - positionStartTime.push( - pPosition[0], pPosition[1], pPosition[2], pStartTime); - velocityStartSize.push( - pVelocity[0], pVelocity[1], pVelocity[2], pStartSize); - accelerationEndSize.push( - pAcceleration[0], pAcceleration[1], pAcceleration[2], pEndSize); - spinStartSpinSpeed.push(pSpinStart, pSpinSpeed, 0, 0); - orientation.push( - pOrientation[0], pOrientation[1], pOrientation[2], pOrientation[3]); - colorMults.push( - pColorMult[0], pColorMult[1], pColorMult[2], pColorMult[3]); + var offset0 = (ii * 4 + jj) * 4; + var offset1 = offset0 + 1; + var offset2 = offset0 + 2; + var offset3 = offset0 + 3; + + uvLifeTimeFrameStart[offset0] = o3djs.particles.CORNERS_[jj][0]; + uvLifeTimeFrameStart[offset1] = o3djs.particles.CORNERS_[jj][1]; + uvLifeTimeFrameStart[offset2] = pLifeTime; + uvLifeTimeFrameStart[offset3] = pFrameStart; + + positionStartTime[offset0] = pPosition[0]; + positionStartTime[offset1] = pPosition[1]; + positionStartTime[offset2] = pPosition[2]; + positionStartTime[offset3] = pStartTime; + + velocityStartSize[offset0] = pVelocity[0]; + velocityStartSize[offset1] = pVelocity[1]; + velocityStartSize[offset2] = pVelocity[2]; + velocityStartSize[offset3] = pStartSize; + + accelerationEndSize[offset0] = pAcceleration[0]; + accelerationEndSize[offset1] = pAcceleration[1]; + accelerationEndSize[offset2] = pAcceleration[2]; + accelerationEndSize[offset3] = pEndSize; + + spinStartSpinSpeed[offset0] = pSpinStart; + spinStartSpinSpeed[offset1] = pSpinSpeed; + spinStartSpinSpeed[offset2] = 0; + spinStartSpinSpeed[offset3] = 0; + + orientation[offset0] = pOrientation[0]; + orientation[offset1] = pOrientation[1]; + orientation[offset2] = pOrientation[2]; + orientation[offset3] = pOrientation[3]; + + colorMults[offset0] = pColorMult[0]; + colorMults[offset1] = pColorMult[1]; + colorMults[offset2] = pColorMult[2]; + colorMults[offset3] = pColorMult[3]; } } + firstParticleIndex *= 4; + this.uvLifeTimeFrameStartField_.setAt( + firstParticleIndex, + uvLifeTimeFrameStart); + this.positionStartTimeField_.setAt( + firstParticleIndex, + positionStartTime); + this.velocityStartSizeField_.setAt( + firstParticleIndex, + velocityStartSize); + this.accelerationEndSizeField_.setAt( + firstParticleIndex, + accelerationEndSize); + this.spinStartSpinSpeedField_.setAt( + firstParticleIndex, + spinStartSpinSpeed); + this.orientationField_.setAt( + firstParticleIndex, + orientation); + this.colorMultField_.setAt( + firstParticleIndex, + colorMults); +}; + +/** + * Allocates particles. + * @private + * @param {number} numParticles Number of particles to allocate. + */ +o3djs.particles.ParticleEmitter.prototype.allocateParticles_ = function( + numParticles) { if (this.vertexBuffer_.numElements != numParticles * 4) { this.vertexBuffer_.allocateElements(numParticles * 4); @@ -970,21 +1074,65 @@ o3djs.particles.ParticleEmitter.prototype.setParameters = function( indices.push(startIndex + 0, startIndex + 2, startIndex + 3); } this.indexBuffer_.set(indices); - } - this.uvLifeTimeFrameStartField_.setAt(0, uvLifeTimeFrameStart); - this.positionStartTimeField_.setAt(0, positionStartTime); - this.velocityStartSizeField_.setAt(0, velocityStartSize); - this.accelerationEndSizeField_.setAt(0, accelerationEndSize); - this.spinStartSpinSpeedField_.setAt(0, spinStartSpinSpeed); - this.orientationField_.setAt(0, orientation); - this.colorMultField_.setAt(0, colorMults); + // We keep these around to avoid memory allocations for trails. + this.uvLifeTimeFrameStart_ = []; + this.positionStartTime_ = []; + this.velocityStartSize_ = []; + this.accelerationEndSize_ = []; + this.spinStartSpinSpeed_ = []; + this.orientation_ = []; + this.colorMults_ = []; + } this.primitive_.numberPrimitives = numParticles * 2; this.primitive_.numberVertices = numParticles * 4; }; /** + * Sets the parameters of the particle emitter. + * + * Each of these parameters are in pairs. The used to create a table + * of particle parameters. For each particle a specfic value is + * set like this + * + * particle.field = value + Math.random() - 0.5 * valueRange * 2; + * + * or in English + * + * particle.field = value plus or minus valueRange. + * + * So for example, if you wanted a value from 10 to 20 you'd pass 15 for value + * and 5 for valueRange because + * + * 15 + or - 5 = (10 to 20) + * + * @param {!o3djs.particles.ParticleSpec} parameters The parameters for the + * emitters. + * @param {!function(number, !o3djs.particles.ParticleSpec): void} + * opt_perParticleParamSetter A function that is called for each particle to + * allow it's parameters to be adjusted per particle. The number is the + * index of the particle being created, in other words, if numParticles is + * 20 this value will be 0 to 19. The ParticleSpec is a spec for this + * particular particle. You can set any per particle value before returning. + */ +o3djs.particles.ParticleEmitter.prototype.setParameters = function( + parameters, + opt_perParticleParamSetter) { + this.validateParameters(parameters); + + var numParticles = parameters.numParticles; + + this.allocateParticles_(numParticles); + + this.createParticles_( + 0, + numParticles, + parameters, + opt_perParticleParamSetter); +}; + +/** * Creates a OneShot particle emitter instance. * You can use this for dust puffs, explosions, fireworks, etc... * @param {!o3d.Transform} opt_parent The parent for the oneshot. @@ -1049,3 +1197,82 @@ o3djs.particles.OneShot.prototype.trigger = function(opt_position, opt_parent) { this.transform.visible = true; this.timeOffsetParam_.value = this.emitter_.clockParam.value; }; + +/** + * A type of emitter to use for particle effects that leave trails like exhaust. + * @constructor + * @extends {o3djs.particles.ParticleEmitter} + * @param {!o3djs.particles.ParticleSystem} particleSystem The particle system + * to manage this emitter. + * @param {!o3d.Transform} parent Transform to put emitter on. + * @param {number} maxParticles Maximum number of particles to appear at once. + * @param {!o3djs.particles.ParticleSpec} parameters The parameters used to + * generate particles. + * @param {!o3d.Texture} opt_texture The texture to use for the particles. + * If you don't supply a texture a default is provided. + * @param {!function(number, !o3djs.particles.ParticleSpec): void} + * opt_perParticleParamSetter A function that is called for each particle to + * allow it's parameters to be adjusted per particle. The number is the + * index of the particle being created, in other words, if numParticles is + * 20 this value will be 0 to 19. The ParticleSpec is a spec for this + * particular particle. You can set any per particle value before returning. + * @param {!o3d.ParamFloat} opt_clockParam A ParamFloat to be the clock for + * the emitter. + */ +o3djs.particles.Trail = function( + particleSystem, + parent, + maxParticles, + parameters, + opt_texture, + opt_perParticleParamSetter, + opt_clockParam) { + o3djs.particles.ParticleEmitter.call( + this, particleSystem, opt_texture, opt_clockParam); + + var pack = particleSystem.pack; + + this.allocateParticles_(maxParticles); + this.validateParameters(parameters); + + this.parameters = parameters; + this.perParticleParamSetter = opt_perParticleParamSetter; + this.birthIndex_ = 0; + this.maxParticles_ = maxParticles; + + /** + * Transform for OneShot. + * @type {!o3d.Transform} + */ + this.transform = pack.createObject('Transform'); + this.transform.addShape(this.shape); + + this.transform.parent = parent; +}; + +o3djs.base.inherit(o3djs.particles.Trail, o3djs.particles.ParticleEmitter); + +/** + * Births particles from this Trail. + * @param {!o3djs.math.Vector3} position Position to birth particles at. + */ +o3djs.particles.Trail.prototype.birthParticles = function(position) { + var numParticles = this.parameters.numParticles; + this.parameters.startTime = this.clockParam.value; + this.parameters.position = position; + while (this.birthIndex_ + numParticles >= this.maxParticles_) { + var numParticlesToEnd = this.maxParticles_ - this.birthIndex_; + this.createParticles_(this.birthIndex_, + numParticlesToEnd, + this.parameters, + this.perParticleParamSetter); + numParticles -= numParticlesToEnd; + this.birthIndex_ = 0; + } + this.createParticles_(this.birthIndex_, + numParticles, + this.parameters, + this.perParticleParamSetter); + this.birthIndex_ += numParticles; +}; + diff --git a/o3d/samples/particles.html b/o3d/samples/particles.html index e3670db..15a7bb9 100644 --- a/o3d/samples/particles.html +++ b/o3d/samples/particles.html @@ -64,6 +64,13 @@ 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. @@ -141,8 +148,6 @@ function initStep2(clientElements) { [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); @@ -174,6 +179,12 @@ function initStep3() { setupAnim(); setupBall(); setupCube(); + setupPoof(); + setupTrail(); + + window.addEventListener('keypress', onKeyPress, true); + window.addEventListener('keydown', onKeyDown, true); + window.addEventListener('keyup', onKeyUp, true); // Setup an onrender callback for animation. g_client.setRenderCallback(onrender); @@ -181,6 +192,30 @@ function initStep3() { 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[event.keyCode] = true; +} + +function onKeyUp(event) { + event = event || window.event; + g_keyDown[event.keyCode] = false; +} + function setupFlame() { var transform = g_pack.createObject('Transform'); transform.parent = g_client.root; @@ -460,6 +495,67 @@ function setupCube() { 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. @@ -468,6 +564,10 @@ 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 @@ -493,5 +593,7 @@ function unload() { <!-- Start of O3D plugin --> <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. </body> </html> |