summaryrefslogtreecommitdiffstats
path: root/o3d/samples/o3djs
diff options
context:
space:
mode:
authorgman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-17 06:26:52 +0000
committergman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-17 06:26:52 +0000
commit1dc3ba84c3da4edfeaf22cedf65750533a20de00 (patch)
tree936325e6f2dd07667fc4161ac524f1ab076aa5bf /o3d/samples/o3djs
parent3d476cf047d6a463d5706f70bfdf5e3787f863ee (diff)
downloadchromium_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.js11
-rw-r--r--o3d/samples/o3djs/effect.js33
-rw-r--r--o3d/samples/o3djs/particles.js392
-rw-r--r--o3d/samples/o3djs/serialization.js195
-rw-r--r--o3d/samples/o3djs/simple.js336
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;
+};
+
+