/* * Copyright 2010, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * Params store data defined name/value pairs on ParamObjects. * Each Param has a name, a type and a value that can be set and queried. * One of their uses is to hold "uniform constants" used to parameterize * shaders. Params can be connected in a source/destination fashion such * that a target Param gets its value from the source param. * @constructor */ o3d.Param = function(param_type_name) { o3d.Param.prototype.output_connections = []; this.outputConnections = []; } o3d.inherit('Param', 'NamedObject'); /** * If true, this param will make sure its input param is up to date when * using it as a source. Default = true. * * This is for helping with Param cycles. * * If paramA gets its value from paramB and paramB gets its value from * paramA: * If you go paramA.value, paramB will evaluate then copy to paramA. * If you go paramB.value, paramA will evaluate then copy to paramB. * If you set paramB.updateInput = false, then: * If you go paramA.value, paramB will evaluate then copy to paramA. * If you go paramB.value, paramB just copy paramA. paramA will NOT evaluate * when paramB asks for its value. */ o3d.Param.prototype.update_input = true; /** * @type {o3d.Param} */ o3d.Param.prototype.inputConnection = null; /** * @type {Array.} */ o3d.Param.prototype.outputConnections = []; /** * @type {o3d.ParamObject} */ o3d.Param.prototype.owner_ = null; /** * Directly binds two Param elements such that this parameter gets its value * from the source parameter. The source must be compatible with this * parameter. * * @param {o3d.Param} source_param The parameter that the value originates * from. Passing in null will unbind any parameter currently bound. * @returns {boolean} True if the bind succeeded. */ o3d.Param.prototype.bind = function(source_param) { source_param.outputConnections.push(this); this.inputConnection = source_param; }; /** * Breaks any input connection coming into the Param. */ o3d.Param.prototype.unbindInput = function() { o3d.notImplemented(); }; /** * Breaks a specific param-bind output connection on this param. * * @param {o3d.Param} destination_param param to unbind. */ o3d.Param.prototype.unbindOutput = function(destination_param) { o3d.notImplemented(); }; /** * Breaks all param-bind output connections on this param. */ o3d.Param.prototype.unbindOutputs = function() { o3d.notImplemented(); }; /** * If true the param is read only. Its value can not be set nor can it be used * as the destination in a ParamBind. */ o3d.Param.prototype.read_only_ = false; /** * The input connection for this param. */ o3d.Param.prototype.input_connection = null; /** * The output connections for this param. */ o3d.Param.prototype.output_connections = []; /** * @constructor */ o3d.ParamBoolean = function() { o3d.Param.call(this); this.value = false; }; o3d.inherit('ParamBoolean', 'Param'); /** * @constructor */ o3d.ParamBoundingBox = function() { o3d.Param.call(this); this.value = null; }; o3d.inherit('ParamBoundingBox', 'Param'); /** * @constructor */ o3d.ParamDrawContext = function() { o3d.Param.call(this); this.value = null; }; o3d.inherit('ParamDrawContext', 'Param'); /** * @constructor */ o3d.ParamDrawList = function() { o3d.Param.call(this); this.value = null; }; o3d.inherit('ParamDrawList', 'Param'); /** * @constructor */ o3d.ParamEffect = function() { o3d.Param.call(this); this.value = null; }; o3d.inherit('ParamEffect', 'Param'); /** * @constructor */ o3d.ParamFloat = function() { o3d.Param.call(this); this.value = 0.0; }; o3d.inherit('ParamFloat', 'Param'); /** * @constructor */ o3d.ParamFloat2 = function() { o3d.Param.call(this); this.value = [0.0, 0.0]; }; o3d.inherit('ParamFloat2', 'Param'); /** * @constructor */ o3d.ParamFloat3 = function() { o3d.Param.call(this); this.value = [0.0, 0.0, 0.0]; }; o3d.inherit('ParamFloat3', 'Param'); /** * @constructor */ o3d.ParamFloat4 = function() { o3d.Param.call(this); this.value = [0.0, 0.0, 0.0, 0.0]; }; o3d.inherit('ParamFloat4', 'Param'); /** * @constructor */ o3d.ParamFunction = function() { o3d.Param.call(this); this.value = null; }; o3d.inherit('ParamFunction', 'Param'); /** * @constructor */ o3d.ParamInteger = function() { o3d.Param.call(this); this.value = 0; }; o3d.inherit('ParamInteger', 'Param'); /** * @constructor */ o3d.ParamMaterial = function() { o3d.Param.call(this); this.value = null; }; o3d.inherit('ParamMaterial', 'Param'); /** * @constructor */ o3d.ParamMatrix4 = function() { o3d.Param.call(this); this.value = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]; }; o3d.inherit('ParamMatrix4', 'Param'); /** * @constructor */ o3d.ParamParamArray = function() { o3d.Param.call(this); this.value = []; }; o3d.inherit('ParamParamArray', 'Param'); /** * @constructor */ o3d.ParamRenderSurface = function() { o3d.Param.call(this); this.value = null; }; o3d.inherit('ParamRenderSurface', 'Param'); /** * @constructor */ o3d.ParamRenderDepthStencilSurface = function() { o3d.Param.call(this); this.value = null; }; o3d.inherit('ParamRenderDepthStencilSurface', 'Param'); /** * @constructor */ o3d.ParamSampler = function() { o3d.Param.call(this); this.value = null; }; o3d.inherit('ParamSampler', 'Param'); /** * @constructor */ o3d.ParamSkin = function() { o3d.Param.call(this); this.value = null; }; o3d.inherit('ParamSkin', 'Param'); /** * @constructor */ o3d.ParamSteamBank = function() { o3d.Param.call(this); this.value = null; }; o3d.inherit('ParamSteamBank', 'Param'); /** * @constructor */ o3d.ParamState = function() { o3d.Param.call(this); this.value = null; }; o3d.inherit('ParamState', 'Param'); /** * @constructor */ o3d.ParamString = function() { o3d.Param.call(this); this.value = null; }; o3d.inherit('ParamString', 'Param'); /** * @constructor */ o3d.ParamTexture = function() { o3d.Param.call(this); this.value = null; }; o3d.inherit('ParamTexture', 'Param'); /** * @constructor */ o3d.ParamTransform = function() { o3d.Param.call(this); this.value = null; }; o3d.inherit('ParamTransform', 'Param'); /** * Base class for the types of matrix4 params that compute their own * value when asked (ProjectionParamMatrix4 etc). * @constructor */ o3d.CompositionParamMatrix4 = function() { o3d.ParamMatrix4.call(this); this.matrix_names_ = []; }; o3d.inherit('CompositionParamMatrix4', 'ParamMatrix4'); /** * The array of names of matrix params for the matrices that are to be * composed to get the value. * @type {Array.} */ o3d.CompositionParamMatrix4.prototype.matrix_names_ = []; /** * Whether the inverse is taken right before returning the value. * @type {Array.} */ o3d.CompositionParamMatrix4.prototype.inverse_ = false; /** * Whether the inverse is taken right before returning the value. * @type {Array.} */ o3d.CompositionParamMatrix4.prototype.transpose_ = false; o3d.CompositionParamMatrix4.prototype.__defineGetter__('value', // TODO(petersont): Cache the result if it hasn't changed. function() { var product = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]; for (var i = 0; i < this.matrix_names_.length; ++i) { o3d.Transform.compose(product, o3d.Param.SAS[this.matrix_names_[i]]); } if (this.inverse_) { o3d.Transform.inverse(product); } if (this.transpose_) { o3d.Transform.transpose(product); } return product; } ); o3d.CompositionParamMatrix4.prototype.__defineSetter__('value', function(value) { } ); /** * @constructor */ o3d.ProjectionParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['projection']; }; o3d.inherit('ProjectionParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.ProjectionInverseParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['projection']; this.inverse_ = true; }; o3d.inherit('ProjectionInverseParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.ProjectionTransposeParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['projection']; this.transpose_ = true; }; o3d.inherit('ProjectionTransposeParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.ProjectionInverseTransposeParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['projection']; this.inverse_ = true; this.transpose_ = true; }; o3d.inherit('ProjectionInverseTransposeParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.ViewParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['view']; }; o3d.inherit('ViewParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.ViewInverseParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['view']; this.inverse_ = true; }; o3d.inherit('ViewInverseParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.ViewTransposeParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['view']; this.transpose_ = true; }; o3d.inherit('ViewTransposeParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.ViewInverseTransposeParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['view']; this.inverse_ = true; this.transpose_ = true; }; o3d.inherit('ViewInverseTransposeParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.ViewProjectionParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['projection', 'view']; }; o3d.inherit('ViewProjectionParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.ViewProjectionInverseParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['projection', 'view']; this.inverse_ = true; }; o3d.inherit('ViewProjectionInverseParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.ViewProjectionTransposeParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['projection', 'view']; this.transpose_ = true; }; o3d.inherit('ViewProjectionTransposeParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.ViewProjectionInverseTransposeParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['projection', 'view']; this.inverse_ = true; this.transpose_ = true; }; o3d.inherit('ViewProjectionInverseTransposeParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.WorldParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['world']; }; o3d.inherit('WorldParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.WorldInverseParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['world']; this.inverse_ = true; }; o3d.inherit('WorldInverseParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.WorldTransposeParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['world']; this.transpose_ = true; }; o3d.inherit('WorldTransposeParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.WorldInverseTransposeParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['world']; this.inverse_ = true; this.transpose_ = true; }; o3d.inherit('WorldInverseTransposeParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.WorldViewParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['view', 'world']; }; o3d.inherit('WorldViewParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.WorldViewInverseParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['view', 'world']; this.inverse_ = true; }; o3d.inherit('WorldViewInverseParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.WorldViewTransposeParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['view', 'world']; this.transpose_ = true; }; o3d.inherit('WorldViewTransposeParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.WorldViewInverseTransposeParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['view', 'world']; this.inverse_ = true; this.transpose_ = true; }; o3d.inherit('WorldViewInverseTransposeParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.WorldViewProjectionParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['projection', 'view', 'world']; }; o3d.inherit('WorldViewProjectionParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.WorldViewProjectionInverseParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['projection', 'view', 'world']; this.inverse_ = true; }; o3d.inherit('WorldViewProjectionInverseParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.WorldViewProjectionTransposeParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['projection', 'view', 'world']; this.transpose_ = true; }; o3d.inherit('WorldViewProjectionTransposeParamMatrix4', 'CompositionParamMatrix4'); /** * @constructor */ o3d.WorldViewProjectionInverseTransposeParamMatrix4 = function() { o3d.CompositionParamMatrix4.call(this); this.matrix_names_ = ['projection', 'view', 'world']; this.inverse_ = true; this.transpose_ = true; }; o3d.inherit('WorldViewProjectionInverseTransposeParamMatrix4', 'CompositionParamMatrix4'); /** * Called to specify the value of a uniform variable. */ o3d.ParamFloat.prototype.applyToLocation = function(gl, location) { gl.uniform4fv(location, this.value); }; /** * Called to specify the value of a uniform variable. */ o3d.ParamFloat2.prototype.applyToLocation = function(gl, location) { gl.uniform2fv(location, this.value); }; /** * Called to specify the value of a uniform variable. */ o3d.ParamFloat3.prototype.applyToLocation = function(gl, location) { gl.uniform3fv(location, this.value); }; /** * Called to specify the value of a uniform variable. */ o3d.ParamFloat4.prototype.applyToLocation = function(gl, location) { gl.uniform4fv(location, this.value); }; /** * Called to specify the value of a uniform variable. */ o3d.ParamMatrix4.prototype.applyToLocation = function(gl, location) { gl.uniformMatrix4fv(location, false, o3d.Transform.flattenMatrix4(this.value)); }; /** * Object to compute all combinations of world/view/projection * inverse/transpose matrices and provide them as parameters. * * @type {o3d.ParamObject} */ o3d.Param.SAS = new o3d.ParamObject; o3d.Param.SAS.createParam('world', 'WorldParamMatrix4'); o3d.Param.SAS.createParam('view', 'ViewParamMatrix4'); o3d.Param.SAS.createParam('projection', 'ProjectionParamMatrix4'); o3d.Param.SAS.createParam('worldView', 'WorldViewParamMatrix4'); o3d.Param.SAS.createParam('viewProjection', 'ViewProjectionParamMatrix4'); o3d.Param.SAS.createParam('worldViewProjection', 'WorldViewProjectionParamMatrix4'); o3d.Param.SAS.createParam('worldI', 'WorldInverseParamMatrix4'); o3d.Param.SAS.createParam('viewI', 'ViewInverseParamMatrix4'); o3d.Param.SAS.createParam('projectionI', 'ProjectionInverseParamMatrix4'); o3d.Param.SAS.createParam('worldViewI', 'WorldViewInverseParamMatrix4'); o3d.Param.SAS.createParam('viewProjectionI', 'ViewProjectionInverseParamMatrix4'); o3d.Param.SAS.createParam('worldViewProjectionI', 'WorldViewProjectionInverseParamMatrix4'); o3d.Param.SAS.createParam('worldT', 'WorldInverseParamMatrix4'); o3d.Param.SAS.createParam('viewT', 'ViewTransposeParamMatrix4'); o3d.Param.SAS.createParam('projectionT', 'ProjectionTransposeParamMatrix4'); o3d.Param.SAS.createParam('worldViewT', 'WorldViewTransposeParamMatrix4'); o3d.Param.SAS.createParam('viewProjectionT', 'ViewProjectionTransposeParamMatrix4'); o3d.Param.SAS.createParam('worldViewProjectionT', 'WorldViewProjectionTransposeParamMatrix4'); o3d.Param.SAS.createParam('worldIT', 'WorldInverseTransposeParamMatrix4'); o3d.Param.SAS.createParam('viewIT', 'ViewInverseTransposeParamMatrix4'); o3d.Param.SAS.createParam('projectionIT', 'ProjectionInverseTransposeParamMatrix4'); o3d.Param.SAS.createParam('worldViewIT', 'WorldViewInverseTransposeParamMatrix4'); o3d.Param.SAS.createParam('viewProjectionIT', 'ViewProjectionInverseTransposeParamMatrix4'); o3d.Param.SAS.createParam('worldViewProjectionIT', 'WorldViewProjectionInverseTransposeParamMatrix4'); /** * Sets the base world matrix that gets use to compute all other products for * SAS parameters. */ o3d.Param.SAS.setWorld = function(world) { this['world'] = world; }; /** * Sets the base world matrix that gets use to compute all other products for * SAS parameters. */ o3d.Param.SAS.setView = function(view) { this['view'] = view; }; /** * Sets the base world matrix that gets use to compute all other products for * SAS parameters. */ o3d.Param.SAS.setProjection = function(projection) { var adjustedProjection = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 2, 0], [0, 0, -1, 1]]; o3d.Transform.compose( adjustedProjection, projection, adjustedProjection); this['projection'] = projection; };