diff options
author | gman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-17 06:26:52 +0000 |
---|---|---|
committer | gman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-17 06:26:52 +0000 |
commit | 1dc3ba84c3da4edfeaf22cedf65750533a20de00 (patch) | |
tree | 936325e6f2dd07667fc4161ac524f1ab076aa5bf /o3d/samples/o3djs | |
parent | 3d476cf047d6a463d5706f70bfdf5e3787f863ee (diff) | |
download | chromium_src-1dc3ba84c3da4edfeaf22cedf65750533a20de00.zip chromium_src-1dc3ba84c3da4edfeaf22cedf65750533a20de00.tar.gz chromium_src-1dc3ba84c3da4edfeaf22cedf65750533a20de00.tar.bz2 |
adding svn:ignore properties to ignore .o3dtgz
files as well as scons-out etc...
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18599 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/samples/o3djs')
-rw-r--r-- | o3d/samples/o3djs/base.js | 11 | ||||
-rw-r--r-- | o3d/samples/o3djs/effect.js | 33 | ||||
-rw-r--r-- | o3d/samples/o3djs/particles.js | 392 | ||||
-rw-r--r-- | o3d/samples/o3djs/serialization.js | 195 | ||||
-rw-r--r-- | o3d/samples/o3djs/simple.js | 336 |
5 files changed, 801 insertions, 166 deletions
diff --git a/o3d/samples/o3djs/base.js b/o3d/samples/o3djs/base.js index a1cd85f..a68214c 100644 --- a/o3d/samples/o3djs/base.js +++ b/o3d/samples/o3djs/base.js @@ -641,6 +641,17 @@ 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) { + 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/effect.js b/o3d/samples/o3djs/effect.js index d9d22c4..3031cee 100644 --- a/o3d/samples/o3djs/effect.js +++ b/o3d/samples/o3djs/effect.js @@ -737,3 +737,36 @@ o3djs.effect.attachStandardShader = function(pack, } }; +/** + * Creates the uniform parameters needed for an Effect on the given ParamObject. + * @param {!o3d.Pack} pack Pack to create extra objects in like Samplers and + * ParamArrays. + * @param {!o3d.Effect} effect Effect. + * @param {!o3d.ParamObject} paramObject ParamObject on which to create Params. + */ +o3djs.effect.createUniformParameters = function(pack, effect, paramObject) { + effect.createUniformParameters(paramObject); + var infos = effect.getParameterInfo(); + for (var ii = 0; ii < infos.length; ++ii) { + var info = infos[ii]; + if (info.sasClassName.length == 0) { + if (info.numElements > 0) { + var paramArray = pack.createObject('ParamArray'); + var param = paramObject.getParam(info.name); + param.value = paramArray; + paramArray.resize(info.numElements, info.className); + if (info.className == 'o3d.ParamSampler') { + for (var jj = 0; jj < info.numElements; ++jj) { + var sampler = pack.createObject('Sampler'); + paramArray.getParam(jj).value = sampler; + } + } + } else if (info.className == 'o3d.ParamSampler') { + var sampler = pack.createObject('Sampler'); + var param = paramObject.getParam(info.name); + param.value = sampler; + } + } + } +}; + diff --git a/o3d/samples/o3djs/particles.js b/o3d/samples/o3djs/particles.js index 075c363..2b95eda 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,81 @@ 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 + * @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/o3djs/serialization.js b/o3d/samples/o3djs/serialization.js index a8b4ea5..4e00f84 100644 --- a/o3d/samples/o3djs/serialization.js +++ b/o3d/samples/o3djs/serialization.js @@ -65,13 +65,39 @@ o3djs.serialization.supportedVersion = 5; */ o3djs.serialization.Options = goog.typedef; +o3djs.serialization.SceneInfo = function() { + /** + * Extra information from json file. + * type {!Object} + */ + // TODO: It's probably better to just put extra info in a separate file + // in the archive. Though, maybe the code in this file should look it up + // like look for 'extra.json' and attach it here, saving the user from + // having to do it manually. + this.extra = { }; + + /** + * The json that represents the parts the need to be created to make an + * instance of the scene. + * type {!Object} + */ + this.sceneJson = { }; + + /** + * Objects by Id that can be reused for instancing. + * type {!Array.<!Object>} + */ + this.objectsById_ = []; +}; + /** * A Deserializer incrementally deserializes a transform graph. * @constructor + * @param {!o3djs.io.archiveInfo} archiveInfo Archive to load from. * @param {!o3d.Pack} pack The pack to deserialize into. * @param {!Object} json An object tree conforming to the JSON rules. */ -o3djs.serialization.Deserializer = function(pack, json) { +o3djs.serialization.Deserializer = function(archiveInfo, pack, json) { /** * The pack to deserialize into. * @type {!o3d.Pack} @@ -86,9 +112,16 @@ o3djs.serialization.Deserializer = function(pack, json) { /** * The archive from which assets referenced from JSON are retreived. - * @type {o3djs.io.ArchiveInfo} + * @type {!o3djs.io.ArchiveInfo} */ - this.archiveInfo = null; + this.archiveInfo = archiveInfo; + + /** + * Array of objects by id that have already been created during a previous + * deserialization. + * @type {!Array.<!Object>} + */ + this.preLoadedObjectsById = []; /** * A map from classname to a function that will create @@ -140,13 +173,12 @@ o3djs.serialization.Deserializer = function(pack, json) { } return object; }, - 'o3d.Texture2D': function(deserializer, json) { if ('o3d.uri' in json.params) { var uri = json.params['o3d.uri'].value; var rawData = deserializer.archiveInfo.getFileByURI(uri); if (!rawData) { - throw 'Could not find texture ' + uri + ' in the archive'; + throw 'Could not find texture "' + uri + '" in the archive'; } return deserializer.pack.createTextureFromRawData( rawData, @@ -168,9 +200,7 @@ o3djs.serialization.Deserializer = function(pack, json) { if (!rawData) { throw 'Could not find texture ' + uri + ' in the archive'; } - return deserializer.pack.createTextureFromRawData( - rawData, - true); + return deserializer.pack.createTextureFromRawData(rawData, true); } else { return deserializer.pack.createTextureCUBE( json.custom.edgeLength, @@ -223,13 +253,13 @@ o3djs.serialization.Deserializer = function(pack, json) { if ('custom' in json) { for (var i = 0; i < json.custom.vertexStreams.length; ++i) { var streamJson = json.custom.vertexStreams[i]; - var field = deserializer.getObjectById(streamJson.stream.field); + var field = deserializer.getO3DObjectById(streamJson.stream.field); object.setVertexStream(streamJson.stream.semantic, streamJson.stream.semanticIndex, field, streamJson.stream.startIndex); if ('bind' in streamJson) { - var source = deserializer.getObjectById(streamJson.bind); + var source = deserializer.getO3DObjectById(streamJson.bind); object.bindStream(source, streamJson.stream.semantic, streamJson.stream.semanticIndex); @@ -242,13 +272,13 @@ o3djs.serialization.Deserializer = function(pack, json) { if ('custom' in json) { for (var i = 0; i < json.custom.vertexStreams.length; ++i) { var streamJson = json.custom.vertexStreams[i]; - var field = deserializer.getObjectById(streamJson.stream.field); + var field = deserializer.getO3DObjectById(streamJson.stream.field); object.setVertexStream(streamJson.stream.semantic, streamJson.stream.semanticIndex, field, streamJson.stream.startIndex); if ('bind' in streamJson) { - var source = deserializer.getObjectById(streamJson.bind); + var source = deserializer.getO3DObjectById(streamJson.bind); object.bindStream(source, streamJson.stream.semantic, streamJson.stream.semanticIndex); @@ -273,19 +303,27 @@ o3djs.serialization.Deserializer = function(pack, json) { } /** - * An array of all objects deserialized so far, indexed by object id. Id zero - * means null. + * An array of all O3D objects deserialized so far, indexed by object id. Id + * zero means null. * @type {!Array.<(Object|undefined)>} * @private */ - this.objectsById_ = [null]; + this.o3dObjectsById_ = [null]; + + /** + * An array of O3D objects deserialized so far, indexed by position in the + * JSON. + * @type {!Array.<Object>} + * @private + */ + this.o3dObjectsByIndex_ = []; /** - * An array of objects deserialized so far, indexed by position in the JSON. + * An array of all json objects by id. * @type {!Array.<Object>} * @private */ - this.objectsByIndex_ = []; + this.jsonObjectsById_ = []; /** * Array of all classes present in the JSON. @@ -293,8 +331,15 @@ o3djs.serialization.Deserializer = function(pack, json) { * @private */ this.classNames_ = []; + + // TODO: This may be too slow and need to be moved to a phase. for (var className in json.objects) { this.classNames_.push(className); + var jsonObjects = json.objects[className]; + for (var jj = 0; jj < jsonObjects.length; ++jj) { + var jsonObject = jsonObjects[jj]; + this.jsonObjectsById_[jsonObject.id] = jsonObject; + } } /** @@ -333,8 +378,8 @@ o3djs.serialization.Deserializer = function(pack, json) { * @param {number} id The id to lookup. * @return {(Object|undefined)} The object with the given id. */ -o3djs.serialization.Deserializer.prototype.getObjectById = function(id) { - return this.objectsById_[id]; +o3djs.serialization.Deserializer.prototype.getO3DObjectById = function(id) { + return this.o3dObjectsById_[id]; }; /** @@ -346,7 +391,7 @@ o3djs.serialization.Deserializer.prototype.getObjectById = function(id) { */ o3djs.serialization.Deserializer.prototype.addObject = function( id, object) { - this.objectsById_[id] = object; + this.o3dObjectsById_[id] = object; }; /** @@ -373,7 +418,7 @@ o3djs.serialization.Deserializer.prototype.deserializeValue = function( var refId = valueAsObject['ref']; if (refId !== undefined) { - var referenced = this.objectsById_[refId]; + var referenced = this.getO3DObjectById(refId); if (referenced === undefined) { throw 'Could not find object with id ' + refId + '.'; } @@ -404,7 +449,7 @@ o3djs.serialization.Deserializer.prototype.setParamValue_ = function( var bindId = propertyJson['bind']; if (bindId !== undefined) { - var referenced = this.objectsById_[bindId]; + var referenced = this.getO3DObjectById(bindId); if (referenced === undefined) { throw 'Could not find output param with id ' + bindId + '.'; } @@ -432,7 +477,7 @@ o3djs.serialization.Deserializer.prototype.createAndIdentifyParam_ = var paramId = propertyJson['id']; if (paramId !== undefined && param !== null) { - this.objectsById_[paramId] = param; + this.o3dObjectsById_[paramId] = param; } }; @@ -458,7 +503,7 @@ o3djs.serialization.Deserializer.prototype.createObjectsPhase_ = var objectJson = classJson[this.nextObjectIndex_]; var object = undefined; if ('id' in objectJson) { - object = this.objectsById_[objectJson.id]; + object = this.getO3DObjectById(objectJson.id); } if (object === undefined) { if (className in this.createCallbacks) { @@ -467,9 +512,9 @@ o3djs.serialization.Deserializer.prototype.createObjectsPhase_ = object = this.pack.createObject(className); } } - this.objectsByIndex_[this.globalObjectIndex_++] = object; + this.o3dObjectsByIndex_[this.globalObjectIndex_++] = object; if ('id' in objectJson) { - this.objectsById_[objectJson.id] = object; + this.o3dObjectsById_[objectJson.id] = object; } if ('params' in objectJson) { if ('length' in objectJson.params) { @@ -516,7 +561,7 @@ o3djs.serialization.Deserializer.prototype.setPropertiesPhase_ = function( return; var objectJson = classJson[this.nextObjectIndex_]; - var object = this.objectsByIndex_[this.globalObjectIndex_++]; + var object = this.o3dObjectsByIndex_[this.globalObjectIndex_++]; if ('properties' in objectJson) { for (var propertyName in objectJson.properties) { if (propertyName in object) { @@ -646,23 +691,26 @@ o3djs.serialization.Deserializer.prototype.runBackground = function( * called run that does a fixed amount of work and returns. * It returns true until the transform graph is fully deserialized. * It returns false from then on. + * @param {!o3djs.io.archiveInfo} archiveInfo Archive to load from. * @param {!o3d.Pack} pack The pack to create the deserialized * objects in. * @param {!Object} json An object tree conforming to the JSON rules. * @return {!o3djs.serialization.Deserializer} A deserializer object. */ -o3djs.serialization.createDeserializer = function(pack, json) { - return new o3djs.serialization.Deserializer(pack, json); +o3djs.serialization.createDeserializer = function(archiveInfo, pack, json) { + return new o3djs.serialization.Deserializer(archiveInfo, pack, json); }; /** * Deserializes a transform graph. + * @param {!o3djs.io.archiveInfo} archiveInfo Archive to load from. * @param {!o3d.Pack} pack The pack to create the deserialized * objects in. * @param {!Object} json An object tree conforming to the JSON rules. */ -o3djs.serialization.deserialize = function(pack, json) { - var deserializer = o3djs.serialization.createDeserializer(pack, json); +o3djs.serialization.deserialize = function(archiveInfo, pack, json) { + var deserializer = o3djs.serialization.createDeserializer( + archiveInfo, pack, json); deserializer.run(); }; @@ -675,6 +723,87 @@ o3djs.serialization.deserialize = function(pack, json) { * @param {!o3d.Client} client An O3D client object. * @param {!o3d.Pack} pack The pack to create the deserialized objects * in. + * @param {!function(!o3djs.serialization.SceneInfo, *): void} callback A + * function that will be called when deserialization is finished. It will be + * passed an o3djs.serialization.SceneInfo, and an exception which will be + * null on success. + * @param {!o3djs.serialization.Options} opt_options Options. + */ +o3djs.serialization.deserializeArchiveForInstaning = function(archiveInfo, + sceneJsonUri, + client, + pack, + callback, + opt_options) { + opt_options = opt_options || { }; + var jsonFile = archiveInfo.getFileByURI(sceneJsonUri); + if (!jsonFile) { + throw 'Could not find ' + sceneJsonUri + ' in archive'; + } + var parsed = eval('(' + jsonFile.stringValue + ')'); + var deserializer = o3djs.serialization.createDeserializer( + archiveInfo, pack, parsed); + + var names = { + 'o3d.VertexBuffer': true, + 'o3d.SourceBuffer': true, + 'o3d.IndexBuffer': true, + 'o3d.Skin': true, + 'o3d.Curve': true, + 'o3d.Effect': true, + 'o3d.Material': true, + }; + + var finishCallback = function(pack, exception) { + if (!exception) { + var objects = pack.getObjects('o3d.animSourceOwner', 'o3d.ParamObject'); + if (objects.length > 0) { + // Rebind the output connections of the animSource to the user's param. + if (opt_options.opt_animSource) { + var animSource = objects[0].getParam('animSource'); + var outputConnections = animSource.outputConnections; + for (var ii = 0; ii < outputConnections.length; ++ii) { + outputConnections[ii].bind(opt_options.opt_animSource); + } + } + // Remove special object from pack. + for (var ii = 0; ii < objects.length; ++ii) { + pack.removeObject(objects[ii]); + } + } + } + callback(pack, parent, exception); + }; + + if (opt_options.opt_async) { + // TODO: Remove the 5. See deserializer.runBackground comments. + deserializer.runBackground(client, pack, 5, finishCallback); + } else { + var exception = null; + var errorCollector = o3djs.error.createErrorCollector(client); + try { + deserializer.run(); + } catch (e) { + exception = e; + } + if (errorCollector.errors.length > 0) { + exception = errorCollector.errors.join('\n') + + (exception ? ('\n' + exception.toString()) : ''); + } + errorCollector.finish(); + finishCallback(pack, exception); + } +}; + +/** + * Deserializes a single json object named 'scene.json' from a loaded + * o3djs.io.ArchiveInfo. + * @param {!o3djs.io.archiveInfo} archiveInfo Archive to load from. + * @param {string} sceneJsonUri The relative URI of the scene JSON file within + * the archive. + * @param {!o3d.Client} client An O3D client object. + * @param {!o3d.Pack} pack The pack to create the deserialized objects + * in. * @param {!o3d.Transform} parent Transform to parent loaded stuff from. * @param {!function(!o3d.Pack, !o3d.Transform, *): void} callback A function * that will be called when deserialization is finished. It will be passed @@ -695,10 +824,10 @@ o3djs.serialization.deserializeArchive = function(archiveInfo, throw 'Could not find ' + sceneJsonUri + ' in archive'; } var parsed = eval('(' + jsonFile.stringValue + ')'); - var deserializer = o3djs.serialization.createDeserializer(pack, parsed); + var deserializer = o3djs.serialization.createDeserializer( + archiveInfo, pack, parsed); deserializer.addObject(parsed.o3d_rootObject_root, parent); - deserializer.archiveInfo = archiveInfo; var finishCallback = function(pack, exception) { if (!exception) { diff --git a/o3d/samples/o3djs/simple.js b/o3d/samples/o3djs/simple.js index 8bb729b..9aa0157 100644 --- a/o3d/samples/o3djs/simple.js +++ b/o3d/samples/o3djs/simple.js @@ -29,7 +29,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - /** * @fileoverview This file contains functions to make it extremely simple * to get something on the screen in o3d. The disadvantage is it @@ -87,6 +86,8 @@ o3djs.require('o3djs.rendergraph'); o3djs.require('o3djs.pack'); o3djs.require('o3djs.primitives'); o3djs.require('o3djs.io'); +o3djs.require('o3djs.scene'); +o3djs.require('o3djs.camera'); /** * A Module for using o3d in a very simple way. @@ -140,16 +141,52 @@ o3djs.simple.create = function(clientObject) { * @param {!Element} clientObject O3D.Plugin Object. */ o3djs.simple.SimpleInfo = function(clientObject) { + /** + * The O3D Element. + * @type {!Element} + */ this.clientObject = clientObject; + + /** + * The O3D namespace object. + * @type {!o3d} + */ this.o3d = clientObject.o3d; - this.math = o3djs.math; + + /** + * The client object used by the SimpleInfo + * @type {!o3d.Client} + */ this.client = clientObject.client; + + /** + * The main pack for this SimpleInfo. + * @type {!o3d.Pack} + */ this.pack = this.client.createPack(); + + /** + * The root transform for this SimpleInfo + * @type {!o3d.Transform} + */ + this.root = this.pack.createObject('Transform'); + + /** + * The ViewInfo created by this SimpleInfo. + * @type {!o3d.ViewInfo} + */ this.viewInfo = o3djs.rendergraph.createBasicView( this.pack, - this.client.root, + this.root, this.client.renderGraphRoot); - this.id = 0; + + + /** + * The list of objects that need to have an update function called. + * @private + * @type {!Array.<!o3djs.simple.SimpleObject>} + */ + this.updateObjects_ = { }; // Create 1 non-textured material and 1 textured material. // @@ -171,7 +208,7 @@ o3djs.simple.SimpleInfo = function(clientObject) { [0, 0, 0], 'phong'); - this.nonTexturedEffect = material.effect; + this.nonTexturedEffect_ = material.effect; this.pack.removeObject(material); var material = this.pack.createObject('Material'); @@ -181,7 +218,7 @@ o3djs.simple.SimpleInfo = function(clientObject) { [0, 0, 0], 'phong'); - this.texturedEffect = material.effect; + this.texturedEffect_ = material.effect; this.pack.removeObject(material); this.globalParamObject = this.pack.createObject('ParamObject'); @@ -195,7 +232,7 @@ o3djs.simple.SimpleInfo = function(clientObject) { // Attempt to setup a resonable default perspective matrix. this.zNear = 0.1; this.zFar = 1000; - this.fieldOfView = this.math.degToRad(45); + this.fieldOfView = o3djs.math.degToRad(45); this.setPerspectiveMatrix_(); // Attempt to setup a resonable default view. @@ -203,22 +240,50 @@ o3djs.simple.SimpleInfo = function(clientObject) { this.cameraTarget = [0, 0, 0]; this.cameraUp = [0, 1, 0]; this.setViewMatrix_(); + + var that = this; + + this.client.setRenderCallback(function(renderEvent) { + that.onRender(renderEvent.elapsedTime); + }); }; /** * Creates a SimpleShape. A SimpleShape manages a transform with 1 shape that * holds 1 primitive and 1 unique material. * @param {!o3d.Shape} shape that holds 1 primitive and 1 unique material. - * @param {!o3d.Material} material assigned to shape. * @return {!o3djs.simple.SimpleShape} the created SimpleShape. */ -o3djs.simple.SimpleInfo.prototype.createSimpleShape = function(shape, - material) { +o3djs.simple.SimpleInfo.prototype.createSimpleShape = function(shape) { shape.createDrawElements(this.pack, null); var transform = this.pack.createObject('Transform'); - transform.parent = this.client.root; + transform.parent = this.root; transform.addShape(shape); - return new o3djs.simple.SimpleShape(this, transform, material); + return new o3djs.simple.SimpleShape(this, transform); +}; + +o3djs.simple.SimpleInfo.prototype.onRender = function(elapsedTime) { + for (var simpleObject in this.updateObjects_) { + simpleObject.onUpdate(elapsedTime); + } +}; + +/** + * Register an object for updating. You should not call this directly. + * @param {!o3djs.simple.SimpleObject} simpleObject SimpleObject to register. + */ +o3djs.simple.SimpleInfo.prototype.registerObjectForUpdate = + function (simpleObject) { + this.updateObjects_[simpleObject] = true; +}; + +/** + * Unregister an object for updating. You should not call this directly. + * @param {!o3djs.simple.SimpleObject} simpleObject SimpleObject to register. + */ +o3djs.simple.SimpleInfo.prototype.unregisterObjectForUpdate = + function (simpleObject) { + delete this.updateObjects_[simpleObject]; }; /** @@ -226,7 +291,7 @@ o3djs.simple.SimpleInfo.prototype.createSimpleShape = function(shape, * @private */ o3djs.simple.SimpleInfo.prototype.setPerspectiveMatrix_ = function() { - this.viewInfo.drawContext.projection = this.math.matrix4.perspective( + this.viewInfo.drawContext.projection = o3djs.math.matrix4.perspective( this.fieldOfView, this.client.width / this.client.height, this.zNear, @@ -238,7 +303,7 @@ o3djs.simple.SimpleInfo.prototype.setPerspectiveMatrix_ = function() { * @private */ o3djs.simple.SimpleInfo.prototype.setViewMatrix_ = function() { - this.viewInfo.drawContext.view = this.math.matrix4.lookAt( + this.viewInfo.drawContext.view = o3djs.math.matrix4.lookAt( this.cameraPosition, this.cameraTarget, this.cameraUp); @@ -344,7 +409,7 @@ o3djs.simple.SimpleInfo.prototype.createMaterialFromEffect = */ o3djs.simple.SimpleInfo.prototype.createNonTexturedMaterial = function(type) { - var material = this.createMaterialFromEffect(this.nonTexturedEffect); + var material = this.createMaterialFromEffect(this.nonTexturedEffect_); material.getParam('diffuse').set(1, 1, 1, 1); material.getParam('emissive').set(0, 0, 0, 1); material.getParam('ambient').set(0, 0, 0, 1); @@ -359,7 +424,7 @@ o3djs.simple.SimpleInfo.prototype.createNonTexturedMaterial = */ o3djs.simple.SimpleInfo.prototype.createTexturedMaterial = function(type) { - var material = this.createMaterialFromEffect(this.texturedEffect); + var material = this.createMaterialFromEffect(this.texturedEffect_); var samplerParam = material.getParam('diffuseSampler'); var sampler = this.pack.createObject('Sampler'); samplerParam.value = sampler; @@ -375,7 +440,7 @@ o3djs.simple.SimpleInfo.prototype.createTexturedMaterial = o3djs.simple.SimpleInfo.prototype.createCube = function(size) { var material = this.createNonTexturedMaterial('phong'); var shape = o3djs.primitives.createCube(this.pack, material, size); - return this.createSimpleShape(shape, material); + return this.createSimpleShape(shape); }; /** @@ -395,7 +460,7 @@ o3djs.simple.SimpleInfo.prototype.createBox = function(width, width, height, depth); - return this.createSimpleShape(shape, material); + return this.createSimpleShape(shape); }; /** @@ -414,35 +479,57 @@ o3djs.simple.SimpleInfo.prototype.createSphere = function(radius, radius, smoothness * 2, smoothness); - return this.createSimpleShape(shape, material); + return this.createSimpleShape(shape); }; /** * Loads a scene from a URL. - * TODO: Implement * @param {string} url Url of scene to load. - * @return {!o3djs.simple.Scene} A Javascript object to manage the scene. + * @param {!function(o3djs.simple.SimpleScene, *): void} a callback to + * call when the scene is loaded. The first argument will be null if the + * scene failed to load and last object will be an exception. + * @return {!o3djs.io.loadInfo} */ -o3djs.simple.SimpleInfo.prototype.loadScene = function(url) { - if (true) { - throw('not implemented'); - } - return null; +o3djs.simple.SimpleInfo.prototype.loadScene = function(url, callback) { + var pack = this.client.createPack(); + var root = pack.createObject('Transform'); + var paramObject = pack.createObject('ParamObject'); + var animTimeParam = paramObject.createParam('animTime', 'ParamFloat'); + var that = this; + + var prepScene = function(pack, root, exception) { + var simpleScene = null; + if (exception) { + pack.destroy(); + } else { + simpleScene = new o3djs.simple.SimpleScene( + that, url, pack, root, paramObject); + } + callback(simpleScene, exception); + }; + + return o3djs.scene.loadScene( + this.client, + pack, + root, + url, + prepScene, + {opt_animSource: animTimeParam}); }; /** * Moves the camera so everything in the current scene is visible. */ o3djs.simple.SimpleInfo.prototype.viewAll = function() { - var bbox = o3djs.util.getBoundingBoxOfTree(this.client.root); - var target = this.math.lerpVector(bbox.minExtent, bbox.maxExtent, 0.5); + var bbox = o3djs.util.getBoundingBoxOfTree(this.root); + var target = o3djs.math.lerpVector(bbox.minExtent, bbox.maxExtent, 0.5); this.setCameraTarget(target[0], target[1], target[2]); // TODO: Refactor this so it takes a vector from the current camera // position to the center of the scene and moves the camera along that // vector away from the center of the scene until for the given fieldOfView // everything is visible. - var diag = this.math.distance(bbox.minExtent, bbox.maxExtent); - var eye = this.math.addVector(target, [ + var diag = o3djs.math.distance(bbox.minExtent, bbox.maxExtent); + var eye = o3djs.math.addVector(target, [ bbox.maxExtent[0], bbox.minExtent[1] + 0.5 * diag, bbox.maxExtent[2]]); @@ -451,32 +538,100 @@ o3djs.simple.SimpleInfo.prototype.viewAll = function() { }; /** - * A SimpleShape manages a transform with 1 shape that holds 1 primitive - * and 1 unique material. + * An object for managing things simply. * @constructor - * @param {!o3djs.simple.SimpleInfo} simpleInfo SimpleInfo to manage this shape. - * @param {!o3d.Transform} transform Transform with 1 shape that holds 1 - * primitive and 1 unique material. - * @param {!o3d.Material} material assigned to shape. */ -o3djs.simple.SimpleShape = function(simpleInfo, transform, material) { +o3djs.simple.SimpleObject = function() { +}; + +/** + * @param {!o3djs.simple.SimpleInfo} simpleInfo The SimpleInfo to manage this + * object. + * @param {!o3d.Transform} transform Transform that orients this object. + */ +o3djs.simple.SimpleObject.prototype.init = function(simpleInfo, transform) { /** - * The SimpleInfo managing this SimpleShape. + * The SimpleInfo managing this object. * @type {!o3djs.simple.SimpleInfo} */ this.simpleInfo = simpleInfo; /** - * The transform for this SimpleShape. + * The Transform that orients this object. * @type {!o3d.Transform} */ this.transform = transform; /** - * The material for this SimpleShape. - * @type {!o3d.Material} + * The update callback for this object. + * @private + * @type {function(number): void} */ - this.material = material; + this.updateCallback_ = null; + + /** + * The pick callback for this object. + * @private + * @type {function(number): void} + */ + this.pickCallback_ = null; +}; + +o3djs.simple.SimpleObject.prototype.onPicked = function(onPickedCallback) { +}; + +/** + * Used to call the update callback on this object. You should not call this + * directly. Use o3djs.simple.SimpleObject.setOnUpdate to add your own update + * callback. + * @param {number} elapsedTime ElapsedTime in seconds for this frame. + * @see o3djs.simple.SimpleObject.setOnUpdate + */ +o3djs.simple.SimpleObject.prototype.onUpdate = function(elapsedTime) { + if (this.updateCallback_) { + this.updateCallback_(elapsedTime); + } +}; + +/** + * Sets a function to be called every frame for this object. + * @param {function(number): void} onUpdateCallback A function that is passed + * the elapsed time in seconds. Pass in null to clear the callback function. + * @return {function(number): void} The previous callback function. + */ +o3djs.simple.SimpleObject.prototype.setOnUpdate = function(onUpdateCallback) { + if (onUpdateCallback) { + this.simpleInfo.registerObjectForUpdate(this); + } else { + this.simpleInfo.unregisterObjectForUpdate(this); + } + var oldCallback = this.updateCallback_; + this.updateCallback_ = onUpdateCallback; + return oldCallback; +}; + +/** + * A SimpleShape manages a transform with 1 shape that holds 1 primitive + * and 1 unique material. + * @constructor + * @extends o3djs.simple.SimpleObject + * @param {!o3djs.simple.SimpleInfo} simpleInfo The SimpleInfo to manage this + * shape. + * @param {!o3d.Transform} transform Transform with 1 shape that holds 1 + * primitive and 1 unique material. + */ +o3djs.simple.SimpleShape = function(simpleInfo, transform) { + this.init(simpleInfo, transform); +}; + +o3djs.simple.SimpleShape.prototype = new o3djs.simple.SimpleObject(); + +/** + * Gets the current material for this shape. + * @return {!o3d.Material} the material for this SimpleShape. + */ +o3djs.simple.SimpleShape.prototype.getMaterial = function() { + return this.transform.shapes[0].elements[0].material; }; /** @@ -484,10 +639,11 @@ o3djs.simple.SimpleShape = function(simpleInfo, transform, material) { * @param {!o3d.Material} material new material. */ o3djs.simple.SimpleShape.prototype.setMaterial = function(material) { - var old_material = this.material; - this.simpleInfo.pack.removeObject(old_material); + var old_material = this.getMaterial(); + if (old_material != null) { + this.simpleInfo.pack.removeObject(old_material); + } this.transform.shapes[0].elements[0].material = material; - this.material = material; }; /** @@ -499,7 +655,7 @@ o3djs.simple.SimpleShape.prototype.setMaterial = function(material) { */ o3djs.simple.SimpleShape.prototype.setDiffuseColor = function(r, g, b, a) { - var material = this.material; + var material = this.getMaterial(); material.getParam('diffuse').set(r, g, b, a); if (a < 1) { material.drawList = this.simpleInfo.viewInfo.zOrderedDrawList; @@ -513,7 +669,7 @@ o3djs.simple.SimpleShape.prototype.setDiffuseColor = * @return {o3d.Texture} The texture on this shape. May be null. */ o3djs.simple.SimpleShape.prototype.getTexture = function() { - var material = this.material; + var material = this.getMaterial(); var samplerParam = material.getParam('diffuseSampler'); if (samplerParam.className == 'o3d.ParamSampler') { return samplerParam.texture; @@ -537,14 +693,14 @@ o3djs.simple.SimpleShape.prototype.loadTexture = function(url) { function(texture, exception) { if (!exception) { // See if this is a textured material. - var material = that.material; - if (material.effect != that.simpleInfo.texturedEffect) { + var material = that.getMaterial(); + if (material.effect != that.simpleInfo.texturedEffect_) { // replace the material with a textured one. var new_material = that.simpleInfo.createTexturedMaterial('phong'); new_material.copyParams(material); // Reset the effect since copy Params just copied the non-textured // one. - new_material.effect = that.simpleInfo.texturedEffect; + new_material.effect = that.simpleInfo.texturedEffect_; that.setMaterial(new_material); material = new_material; } @@ -556,3 +712,83 @@ o3djs.simple.SimpleShape.prototype.loadTexture = function(url) { }); }; +/** + * An object to simply manage a scene. + * @constructor + * @extends o3djs.simple.SimpleObject + * @param {!o3djs.simple.SimpleInfo} simpleInfo The SimpleInfo to manage this + * scene. + * @param {string} url Url scene was loaded from. + * @param {!o3d.Pack} pack Pack that is managing scene. + * @param {!o3d.Transform} root Root transform of scene. + * @param {!o3d.ParamObject} paramObject the holds global parameters. + */ +o3djs.simple.SimpleScene = function( + simpleInfo, url, pack, root, paramObject) { + this.init(simpleInfo, root); + /** + * The url this scene was loaded from. + * @type {string} + */ + this.url = url; + + /** + * The pack managing this scene. + * @type {!o3d.Pack} + */ + this.pack = pack; + + /** + * The param object holding global parameters for this scene. + * @type {!o3d.Pack} + */ + this.paramObject = paramObject; + + /** + * The animation parameter for this scene. + * @type {!o3d.ParamFloat} + */ + this.animTimeParam = paramObject.getParam('animTime'); + + o3djs.pack.preparePack(pack, simpleInfo.viewInfo); + + this.cameraInfos_ = o3djs.camera.getCameraInfos( + root, + simpleInfo.client.width, + simpleInfo.client.height); + + + /** + * Binds a param if it exists. + * @param {!o3d.ParamObject} paramObject The object that has the param. + * @param {string} paramName name of param. + * @param {!o3d.Param} sourceParam The param to bind to. + */ + var bindParam = function(paramObject, paramName, sourceParam) { + var param = paramObject.getParam(paramName); + if (param) { + param.bind(sourceParam); + } + } + + var materials = pack.getObjectsByClassName('o3d.Material'); + for (var m = 0; m < materials.length; ++m) { + var material = materials[m]; + bindParam(material, 'lightWorldPos', simpleInfo.lightWorldPosParam); + bindParam(material, 'lightColor', simpleInfo.lightColorParam); + } + + this.transform.parent = this.simpleInfo.root; +}; + +o3djs.simple.SimpleScene.prototype = new o3djs.simple.SimpleObject(); + +/** + * Sets the animation time for the scene. + * @param {number} time Animation time in seconds. + */ +o3djs.simple.SimpleScene.prototype.setAnimTime = function(time) { + this.animTimeParam.value = time; +}; + + |