summaryrefslogtreecommitdiffstats
path: root/o3d/samples/o3djs
diff options
context:
space:
mode:
authorbradnelson@google.com <bradnelson@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-28 20:23:26 +0000
committerbradnelson@google.com <bradnelson@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-28 20:23:26 +0000
commitd15f03f7d3aaa253d32c8bfc4f1543f5f9d6eeae (patch)
treee3ae9df25c03721d2889ca4aad346dc7c2d99363 /o3d/samples/o3djs
parente6111af1609505398801eed7619a2f7191fe3a2b (diff)
downloadchromium_src-d15f03f7d3aaa253d32c8bfc4f1543f5f9d6eeae.zip
chromium_src-d15f03f7d3aaa253d32c8bfc4f1543f5f9d6eeae.tar.gz
chromium_src-d15f03f7d3aaa253d32c8bfc4f1543f5f9d6eeae.tar.bz2
Moving o3d up a level, to get it out of chrome checkouts.
BUG=None TEST=None Too large for codereview. Manual review by thaloun and tschelcher. git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79609 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/samples/o3djs')
-rw-r--r--o3d/samples/o3djs/arcball.js162
-rw-r--r--o3d/samples/o3djs/base.js809
-rw-r--r--o3d/samples/o3djs/camera.js364
-rw-r--r--o3d/samples/o3djs/cameracontroller.js396
-rw-r--r--o3d/samples/o3djs/canvas.js438
-rw-r--r--o3d/samples/o3djs/debug.js1031
-rw-r--r--o3d/samples/o3djs/dump.js585
-rw-r--r--o3d/samples/o3djs/effect.js1534
-rw-r--r--o3d/samples/o3djs/element.js212
-rw-r--r--o3d/samples/o3djs/error.js133
-rw-r--r--o3d/samples/o3djs/event.js360
-rw-r--r--o3d/samples/o3djs/fps.js486
-rw-r--r--o3d/samples/o3djs/gpu2d.js800
-rw-r--r--o3d/samples/o3djs/io.js656
-rw-r--r--o3d/samples/o3djs/js_list.manifest63
-rw-r--r--o3d/samples/o3djs/lineprimitives.js396
-rw-r--r--o3d/samples/o3djs/loader.js241
-rw-r--r--o3d/samples/o3djs/manipulators.js1910
-rw-r--r--o3d/samples/o3djs/material.js593
-rw-r--r--o3d/samples/o3djs/math.js3168
-rw-r--r--o3d/samples/o3djs/pack.js71
-rw-r--r--o3d/samples/o3djs/particles.js1510
-rw-r--r--o3d/samples/o3djs/performance.js202
-rw-r--r--o3d/samples/o3djs/picking.js742
-rw-r--r--o3d/samples/o3djs/plugin_math.js2536
-rw-r--r--o3d/samples/o3djs/primitives.js2016
-rw-r--r--o3d/samples/o3djs/quaternions.js520
-rw-r--r--o3d/samples/o3djs/rendergraph.js580
-rw-r--r--o3d/samples/o3djs/scene.js91
-rw-r--r--o3d/samples/o3djs/serialization.js871
-rw-r--r--o3d/samples/o3djs/shape.js140
-rw-r--r--o3d/samples/o3djs/simple.js830
-rw-r--r--o3d/samples/o3djs/test.js342
-rw-r--r--o3d/samples/o3djs/texture.js295
-rw-r--r--o3d/samples/o3djs/util.js1037
-rw-r--r--o3d/samples/o3djs/webgl.js283
36 files changed, 0 insertions, 26403 deletions
diff --git a/o3d/samples/o3djs/arcball.js b/o3d/samples/o3djs/arcball.js
deleted file mode 100644
index ab72be6..0000000
--- a/o3d/samples/o3djs/arcball.js
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// A shout out to Terence J. Grant at tatewake.com for his tutorial on arcball
-// implementations.
-
-/**
- * @fileoverview This file contains functions for implementing an arcball
- * calculation. It puts them in the "arcball" module on the o3djs object.
- *
- * Note: This library is only a sample. It is not meant to be some official
- * library. It is provided only as example code.
- *
- */
-
-o3djs.provide('o3djs.arcball');
-
-o3djs.require('o3djs.math');
-o3djs.require('o3djs.quaternions');
-
-/**
- * A Module for arcball manipulation.
- *
- * This is useful for rotating a model with the mouse.
- *
- * @namespace
- */
-o3djs.arcball = o3djs.arcball || {};
-
-/**
- * Creates a new arcball.
- * @param {number} areaWidth width of area arcball should cover.
- * @param {number} areaHeight height of area arcball should cover.
- * @return {!o3djs.arcball.ArcBall} The created arcball.
- * @see o3djs.arcball
- */
-o3djs.arcball.create = function(areaWidth, areaHeight) {
- return new o3djs.arcball.ArcBall(areaWidth, areaHeight);
-};
-
-/**
- * A class that implements an arcball.
- * @constructor
- * @param {number} areaWidth width of area arcball should cover.
- * @param {number} areaHeight height of area arcball should cover.
- * @see o3djs.arcball
- */
-o3djs.arcball.ArcBall = function(areaWidth, areaHeight) {
- /**
- * The start vector.
- * @private
- * @type {!o3djs.math.Vector3}
- */
- this.startVector_ = [0, 0, 0];
-
- /**
- * The end vector.
- * @private
- * @type {!o3djs.math.Vector3}
- */
- this.endVector_ = [0, 0, 0];
-
- /**
- * The width of the arcBall area.
- * @private
- * @type {number}
- */
- this.areaWidth_ = areaWidth;
-
- /**
- * The height of the arcBall area.
- * @private
- * @type {number}
- */
- this.areaHeight_ = areaHeight;
-};
-
-
-/**
- * Sets the size of the arcball.
- * @param {number} areaWidth width of area arcball should cover.
- * @param {number} areaHeight height of area arcball should cover.
- */
-o3djs.arcball.ArcBall.prototype.setAreaSize = function(areaWidth, areaHeight) {
- this.areaWidth_ = areaWidth;
- this.areaHeight_ = areaHeight;
-};
-
-/**
- * Converts a 2d point to a point on the sphere of radius 1 sphere.
- * @param {!o3djs.math.Vector2} newPoint A point in 2d.
- * @return {!o3djs.math.Vector3} A point on the sphere of radius 1.
- */
-o3djs.arcball.ArcBall.prototype.mapToSphere = function(newPoint) {
- // Copy parameter into temp
- var tempPoint = o3djs.math.copyVector(newPoint);
-
- // Scale to -1.0 <-> 1.0
- tempPoint[0] = tempPoint[0] / this.areaWidth_ * 2.0 - 1.0;
- tempPoint[1] = 1.0 - tempPoint[1] / this.areaHeight_ * 2.0;
-
- // Compute square of length from center
- var lengthSquared = o3djs.math.lengthSquared(tempPoint);
-
- // If the point is mapped outside of the sphere... (length > radius squared)
- if (lengthSquared > 1.0) {
- return o3djs.math.normalize(tempPoint).concat(0);
- } else {
- // Otherwise it's on the inside.
- return tempPoint.concat(Math.sqrt(1.0 - lengthSquared));
- }
-};
-
-/**
- * Records the starting point on the sphere.
- * @param {!o3djs.math.Vector2} newPoint point in 2d.
- */
-o3djs.arcball.ArcBall.prototype.click = function(newPoint) {
- this.startVector_ = this.mapToSphere(newPoint);
-};
-
-/**
- * Computes the rotation of the sphere based on the initial point clicked as
- * set through Arcball.click and the current point passed in as newPoint
- * @param {!o3djs.math.Vector2} newPoint point in 2d.
- * @return {!o3djs.quaternions.Quaternion} A quaternion representing the new
- * orientation.
- */
-o3djs.arcball.ArcBall.prototype.drag = function(newPoint) {
- this.endVector_ = this.mapToSphere(newPoint);
-
- return o3djs.math.cross(this.startVector_, this.endVector_).concat(
- o3djs.math.dot(this.startVector_, this.endVector_));
-};
diff --git a/o3d/samples/o3djs/base.js b/o3d/samples/o3djs/base.js
deleted file mode 100644
index 00c5af8..0000000
--- a/o3d/samples/o3djs/base.js
+++ /dev/null
@@ -1,809 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview Base for all o3d sample utilties.
- * For more information about o3d see
- * http://code.google.com/p/o3d.
- *
- *
- * The main point of this module is to provide a central place to
- * have an init function to register an o3d namespace object because many other
- * modules need access to it.
- */
-
-/**
- * A namespace for all the o3djs utility libraries.
- * @namespace
- */
-var o3djs = o3djs || {};
-
-/**
- * Define this because the Google internal JSCompiler needs goog.typedef below.
- */
-var goog = goog || {};
-
-/**
- * A macro for defining composite types.
- *
- * By assigning goog.typedef to a name, this tells Google internal JSCompiler
- * that this is not the name of a class, but rather it's the name of a composite
- * type.
- *
- * For example,
- * /** @type {Array|NodeList} / goog.ArrayLike = goog.typedef;
- * will tell JSCompiler to replace all appearances of goog.ArrayLike in type
- * definitions with the union of Array and NodeList.
- *
- * Does nothing in uncompiled code.
- */
-goog.typedef = true;
-
-/**
- * Reference to the global context. In most cases this will be 'window'.
- */
-o3djs.global = this;
-
-/**
- * Flag used to force a function to run in the browser when it is called
- * from V8.
- * @type {boolean}
- */
-o3djs.BROWSER_ONLY = true;
-
-/**
- * Array of namespaces that have been provided.
- * @private
- * @type {!Array.<string>}
- */
-o3djs.provided_ = [];
-
-/**
- * Creates object stubs for a namespace. When present in a file,
- * o3djs.provide also indicates that the file defines the indicated
- * object.
- * @param {string} name Name of the object that this file defines.
- * @param {boolean} opt_replace Whether to replace existing namespace.
- */
-o3djs.provide = function(name, opt_replace) {
- // Ensure that the same namespace isn't provided twice.
- if (!opt_replace) {
- if (o3djs.getObjectByName(name) &&
- !o3djs.implicitNamespaces_[name]) {
- throw 'Namespace "' + name + '" already declared.';
- }
- }
-
- var namespace = name;
- while ((namespace = namespace.substring(0, namespace.lastIndexOf('.')))) {
- o3djs.implicitNamespaces_[namespace] = true;
- }
-
- o3djs.exportPath_(name);
- o3djs.provided_.push(name);
-};
-
-
-/**
- * Namespaces implicitly defined by o3djs.provide. For example,
- * o3djs.provide('o3djs.events.Event') implicitly declares
- * that 'o3djs' and 'o3djs.events' must be namespaces.
- *
- * @type {Object}
- * @private
- */
-o3djs.implicitNamespaces_ = {};
-
-/**
- * Builds an object structure for the provided namespace path,
- * ensuring that names that already exist are not overwritten. For
- * example:
- * "a.b.c" -> a = {};a.b={};a.b.c={};
- * Used by o3djs.provide and o3djs.exportSymbol.
- * @param {string} name name of the object that this file defines.
- * @param {Object} opt_object the object to expose at the end of the path.
- * @param {Object} opt_objectToExportTo The object to add the path to; default
- * is |o3djs.global|.
- * @private
- */
-o3djs.exportPath_ = function(name, opt_object, opt_objectToExportTo) {
- var parts = name.split('.');
- var cur = opt_objectToExportTo || o3djs.global;
- var part;
-
- // Internet Explorer exhibits strange behavior when throwing errors from
- // methods externed in this manner. See the testExportSymbolExceptions in
- // base_test.html for an example.
- if (!(parts[0] in cur) && cur.execScript) {
- cur.execScript('var ' + parts[0]);
- }
-
- // Parentheses added to eliminate strict JS warning in Firefox.
- while (parts.length && (part = parts.shift())) {
- if (!parts.length && o3djs.isDef(opt_object)) {
- // last part and we have an object; use it.
- cur[part] = opt_object;
- } else if (cur[part]) {
- cur = cur[part];
- } else {
- cur = cur[part] = {};
- }
- }
-};
-
-
-/**
- * Returns an object based on its fully qualified external name. If you are
- * using a compilation pass that renames property names beware that using this
- * function will not find renamed properties.
- *
- * @param {string} name The fully qualified name.
- * @param {Object} opt_obj The object within which to look; default is
- * |o3djs.global|.
- * @return {Object} The object or, if not found, null.
- */
-o3djs.getObjectByName = function(name, opt_obj) {
- var parts = name.split('.');
- var cur = opt_obj || o3djs.global;
- for (var pp = 0; pp < parts.length; ++pp) {
- var part = parts[pp];
- if (cur[part]) {
- cur = cur[part];
- } else {
- return null;
- }
- }
- return cur;
-};
-
-
-/**
- * Implements a system for the dynamic resolution of dependencies.
- * @param {string} rule Rule to include, in the form o3djs.package.part.
- */
-o3djs.require = function(rule) {
- // TODO(gman): For some unknown reason, when we call
- // o3djs.util.getScriptTagText_ it calls
- // document.getElementsByTagName('script') and for some reason the scripts do
- // not always show up. Calling it here seems to fix that as long as we
- // actually ask for the length, at least in FF 3.5.1 It would be nice to
- // figure out why.
- var dummy = document.getElementsByTagName('script').length;
-
- // if the object already exists we do not need do do anything
- if (o3djs.getObjectByName(rule)) {
- return;
- }
- var path = o3djs.getPathFromRule_(rule);
- if (path) {
- o3djs.included_[path] = true;
- o3djs.writeScripts_();
- } else {
- throw new Error('o3djs.require could not find: ' + rule);
- }
-};
-
-
-/**
- * Path for included scripts.
- * @type {string}
- */
-o3djs.basePath = '';
-
-
-/**
- * Object used to keep track of urls that have already been added. This
- * record allows the prevention of circular dependencies.
- * @type {Object}
- * @private
- */
-o3djs.included_ = {};
-
-
-/**
- * This object is used to keep track of dependencies and other data that is
- * used for loading scripts.
- * @private
- * @type {Object}
- */
-o3djs.dependencies_ = {
- visited: {}, // used when resolving dependencies to prevent us from
- // visiting the file twice.
- written: {} // used to keep track of script files we have written.
-};
-
-
-/**
- * Tries to detect the base path of the o3djs-base.js script that
- * bootstraps the o3djs libraries.
- * @private
- */
-o3djs.findBasePath_ = function() {
- var doc = o3djs.global.document;
- if (typeof doc == 'undefined') {
- return;
- }
- if (o3djs.global.BASE_PATH) {
- o3djs.basePath = o3djs.global.BASE_PATH;
- return;
- } else {
- // HACKHACK to hide compiler warnings :(
- o3djs.global.BASE_PATH = null;
- }
- var scripts = doc.getElementsByTagName('script');
- for (var script, i = 0; script = scripts[i]; i++) {
- var src = script.src;
- var l = src.length;
- if (src.substr(l - 13) == 'o3djs/base.js') {
- o3djs.basePath = src.substr(0, l - 13);
- return;
- }
- }
-};
-
-
-/**
- * Writes a script tag if, and only if, that script hasn't already been added
- * to the document. (Must be called at execution time.)
- * @param {string} src Script source.
- * @private
- */
-o3djs.writeScriptTag_ = function(src) {
- var doc = o3djs.global.document;
- if (typeof doc != 'undefined' &&
- !o3djs.dependencies_.written[src]) {
- o3djs.dependencies_.written[src] = true;
- doc.write('<script type="text/javascript" src="' +
- src + '"></' + 'script>');
- }
-};
-
-
-/**
- * Resolves dependencies based on the dependencies added using addDependency
- * and calls writeScriptTag_ in the correct order.
- * @private
- */
-o3djs.writeScripts_ = function() {
- // the scripts we need to write this time.
- var scripts = [];
- var seenScript = {};
- var deps = o3djs.dependencies_;
-
- function visitNode(path) {
- if (path in deps.written) {
- return;
- }
-
- // we have already visited this one. We can get here if we have cyclic
- // dependencies.
- if (path in deps.visited) {
- if (!(path in seenScript)) {
- seenScript[path] = true;
- scripts.push(path);
- }
- return;
- }
-
- deps.visited[path] = true;
-
- if (!(path in seenScript)) {
- seenScript[path] = true;
- scripts.push(path);
- }
- }
-
- for (var path in o3djs.included_) {
- if (!deps.written[path]) {
- visitNode(path);
- }
- }
-
- for (var i = 0; i < scripts.length; i++) {
- if (scripts[i]) {
- o3djs.writeScriptTag_(o3djs.basePath + scripts[i]);
- } else {
- throw Error('Undefined script input');
- }
- }
-};
-
-
-/**
- * Looks at the dependency rules and tries to determine the script file that
- * fulfills a particular rule.
- * @param {string} rule In the form o3djs.namespace.Class or
- * project.script.
- * @return {string?} Url corresponding to the rule, or null.
- * @private
- */
-o3djs.getPathFromRule_ = function(rule) {
- var parts = rule.split('.');
- return parts.join('/') + '.js';
-};
-
-o3djs.findBasePath_();
-
-/**
- * Returns true if the specified value is not |undefined|.
- * WARNING: Do not use this to test if an object has a property. Use the in
- * operator instead.
- * @param {*} val Variable to test.
- * @return {boolean} Whether variable is defined.
- */
-o3djs.isDef = function(val) {
- return typeof val != 'undefined';
-};
-
-
-/**
- * Exposes an unobfuscated global namespace path for the given object.
- * Note that fields of the exported object *will* be obfuscated,
- * unless they are exported in turn via this function or
- * o3djs.exportProperty.
- *
- * <p>Also handy for making public items that are defined in anonymous
- * closures.
- *
- * ex. o3djs.exportSymbol('Foo', Foo);
- *
- * ex. o3djs.exportSymbol('public.path.Foo.staticFunction',
- * Foo.staticFunction);
- * public.path.Foo.staticFunction();
- *
- * ex. o3djs.exportSymbol('public.path.Foo.prototype.myMethod',
- * Foo.prototype.myMethod);
- * new public.path.Foo().myMethod();
- *
- * @param {string} publicPath Unobfuscated name to export.
- * @param {Object} object Object the name should point to.
- * @param {Object} opt_objectToExportTo The object to add the path to; default
- * is |o3djs.global|.
- */
-o3djs.exportSymbol = function(publicPath, object, opt_objectToExportTo) {
- o3djs.exportPath_(publicPath, object, opt_objectToExportTo);
-};
-
-/**
- * This string contains JavaScript code to initialize a new V8 instance.
- * @private
- * @type {string}
- */
-o3djs.v8Initializer_ = '';
-
-/**
- * This array contains references to objects that v8 needs to bind to when
- * it initializes.
- * @private
- * @type {!Array.<Object>}
- */
-o3djs.v8InitializerArgs_ = [];
-
-/**
- * Converts any JavaScript value to a string representation that when evaluated
- * will result in an equal value.
- * @param {*} value Any value.
- * @return {string} A string representation for the value.
- * @private
- */
-o3djs.valueToString_ = function(value) {
- switch (typeof(value)) {
- case 'undefined':
- return 'undefined';
- case 'string':
- var escaped = escape(value);
- if (escaped === value) {
- return '"' + value + '"';
- } else {
- return 'unescape("' + escaped + '")';
- }
- case 'object':
- if (value === null) {
- return 'null';
- } else {
- // TODO: all the other builtin JavaScript objects like Date,
- // Number, Boolean, etc.
- if (value instanceof RegExp) {
- var result =
- 'new RegExp(' + o3djs.valueToString_(value.source) + ', "';
- if (value.global) {
- result += 'g';
- }
- if (value.ignoreCase) {
- result += 'i';
- }
- if (value.multiline) {
- result += 'm';
- }
- result += '")';
- return result;
- } else if (o3djs.base.isArray(value)) {
- var valueAsArray = /** @type {!Array} */ (value);
- var result = '[';
- var separator = '';
- for (var i = 0; i < valueAsArray.length; ++i) {
- result += separator + o3djs.valueToString_(valueAsArray[i]);
- separator = ',';
- }
- result += ']\n';
- return result;
- } else {
- var valueAsObject = /** @type {!Object} */ (value);
- var result = '{\n';
- var separator = '';
- for (var propertyName in valueAsObject) {
- result += separator + '"' + propertyName + '": ' +
- o3djs.valueToString_(valueAsObject[propertyName]);
- separator = ',';
- }
- result += '}\n';
- return result;
- }
- }
- default:
- return value.toString()
- }
-};
-
-/**
- * Given an object holding a namespace and the name of that namespace,
- * generates a string that when evaluated will populate the namespace.
- * @param {!Object} namespaceObject An object holding a namespace.
- * @param {string} namespaceName The name of the namespace.
- * @param {!Array.<Object>} opt_args An array of objects that will be used
- * together with the initializer string to populate a namespace. The args
- * may be referenced from initializer code as args_[i] where i is the index
- * in the array.
- * @return {string} A string that will populate the namespace.
- * @private
- */
-o3djs.namespaceInitializer_ = function(namespaceObject,
- namespaceName,
- opt_args) {
- var result = namespaceName + ' = {};\n';
- for (var propertyName in namespaceObject) {
- var propertyNamespaceName = namespaceName + '.' + propertyName;
- var propertyValue = namespaceObject[propertyName];
- if (typeof(propertyValue) === 'object' && propertyValue !== null &&
- !o3djs.base.isArray(propertyValue) &&
- !(propertyValue instanceof RegExp)) {
- result += o3djs.namespaceInitializer_(propertyValue,
- propertyNamespaceName);
- } else {
- var valueAsString = o3djs.valueToString_(propertyValue);
-
- // If this is a browser only function then bind to the browser version
- // of the function rather than create a new function in V8.
- if (typeof(propertyValue) == 'function' &&
- valueAsString.indexOf('o3djs.BROWSER_ONLY') != -1) {
- valueAsString = 'args_[' + opt_args.length + ']';
- opt_args.push(propertyValue);
- }
- result += propertyNamespaceName + ' = ' + valueAsString + ';\n';
-
- if (typeof(propertyValue) === 'function' && propertyValue.prototype) {
- result += o3djs.namespaceInitializer_(
- propertyValue.prototype,
- propertyNamespaceName + '.prototype');
- }
- }
- }
- return result;
-};
-
-o3djs.provide('o3djs.base');
-
-/**
- * The base module for o3djs.
- * @namespace
- */
-o3djs.base = o3djs.base || {};
-
-/**
- * The a Javascript copy of the o3d namespace object. (holds constants, enums,
- * etc...)
- * @type {o3d}
- */
-o3djs.base.o3d = null;
-
-/**
- * Whether or not we need to use GLSL instead of HLSL.
- * @type {boolean}
- */
-o3djs.base.glsl = false;
-
-/**
- * Snapshots the current state of all provided namespaces. This state will be
- * used to initialize future V8 instances. It is automatically
- * called by o3djs.util.makeClients.
- */
-o3djs.base.snapshotProvidedNamespaces = function() {
- // Snapshot the V8 initializer string from the current state of browser
- // JavaScript the first time this is called.
- o3djs.v8Initializer_ = 'function(args_) {\n';
- o3djs.v8InitializerArgs_ = [];
- for (var i = 0; i < o3djs.provided_.length; ++i) {
- var object = o3djs.getObjectByName(o3djs.provided_[i]);
- o3djs.v8Initializer_ += o3djs.namespaceInitializer_(
- /** @type {!Object} */ (object),
- o3djs.provided_[i],
- o3djs.v8InitializerArgs_);
- }
-
- o3djs.v8Initializer_ += '}\n';
-};
-
-/**
- * Initializes the o3djs.sample library in a v8 instance. This should be called
- * for every V8 instance that uses the sample library. It is automatically
- * called by o3djs.util.makeClients.
- * @param {!Element} clientObject O3D.Plugin Object.
- */
-o3djs.base.initV8 = function(clientObject) {
- var v8Init = function(initializer, args) {
- // Set up the o3djs namespace.
- var o3djsBrowser = o3djs;
- o3djs = {};
- o3djs.browser = o3djsBrowser;
- o3djs.global = (function() { return this; })();
-
- o3djs.require = function(rule) {}
- o3djs.provide = function(rule) {}
-
- // Evaluate the initializer string with the arguments containing bindings
- // to browser side objects.
- eval('(' + initializer + ')')(args);
-
- // Make sure this points to the o3d namespace for this particular
- // instance of the plugin.
- o3djs.base.o3d = plugin.o3d;
-
- // Save off if we need GLSL.
- o3djs.base.glsl = plugin.client.clientInfo.glsl;
- };
-
- clientObject.eval(v8Init.toString())(o3djs.v8Initializer_,
- o3djs.v8InitializerArgs_);
-};
-
-/**
- * Initializes the o3djs.sample library.
- * Basically all it does is record the o3djs.namespace object which is used by
- * other functions to look up o3d constants.
- *
- * @param {!Element} clientObject O3D.Plugin Object.
- */
-o3djs.base.init = function(clientObject) {
- function recursivelyCopyProperties(object) {
- var copy = {};
- var hasProperties = false;
- for (var key in object) {
- var property = object[key];
- if (typeof property == 'object' || typeof property == 'function') {
- property = recursivelyCopyProperties(property);
- }
- if (typeof property != 'undefined') {
- copy[key] = property;
- hasProperties = true;
- }
- }
- return hasProperties ? copy : undefined;
- }
- try {
- o3djs.base.o3d = recursivelyCopyProperties(clientObject.o3d);
- } catch (e) {
- // Firefox 2 raises an exception when trying to enumerate a NPObject
- o3djs.base.o3d = clientObject.o3d;
- }
- // Because of a bug in chrome, it is not possible for the browser to enumerate
- // the properties of an NPObject.
- // Chrome bug: http://code.google.com/p/chromium/issues/detail?id=5743
- o3djs.base.o3d = o3djs.base.o3d || clientObject.o3d;
- // Save off if we need GLSL.
- o3djs.base.glsl = clientObject.client.clientInfo.glsl;
-};
-
-/**
- * Determine whether a value is an array. Do not use instanceof because that
- * will not work for V8 arrays (the browser thinks they are Objects).
- * @param {*} value A value.
- * @return {boolean} Whether the value is an array.
- */
-o3djs.base.isArray = function(value) {
- var valueAsObject = /** @type {!Object} */ (value);
- return typeof(value) === 'object' && value !== null &&
- 'length' in valueAsObject && 'splice' in valueAsObject;
-};
-
-/**
- * Check if the o3djs library has been initialized.
- * @return {boolean} true if ready, false if not.
- */
-o3djs.base.ready = function() {
- return o3djs.base.o3d != null;
-};
-
-/**
- * A stub for later optionally converting obfuscated names
- * @private
- * @param {string} name Name to un-obfuscate.
- * @return {string} un-obfuscated name.
- */
-o3djs.base.maybeDeobfuscateFunctionName_ = function(name) {
- return name;
-};
-
-/**
- * Makes one class inherit from another.
- * @param {!Object} subClass Class that wants to inherit.
- * @param {!Object} superClass Class to inherit from.
- */
-o3djs.base.inherit = function(subClass, superClass) {
- /**
- * TmpClass.
- * @ignore
- * @constructor
- */
- var TmpClass = function() { };
- TmpClass.prototype = superClass.prototype;
- subClass.prototype = new TmpClass();
-};
-
-/**
- * Parses an error stack from an exception
- * @param {!Exception} excp The exception to get a stack trace from.
- * @return {!Array.<string>} An array of strings of the stack trace.
- */
-o3djs.base.parseErrorStack = function(excp) {
- var stack = [];
- var name;
- var line;
-
- if (!excp || !excp.stack) {
- return stack;
- }
-
- var stacklist = excp.stack.split('\n');
-
- for (var i = 0; i < stacklist.length - 1; i++) {
- var framedata = stacklist[i];
-
- name = framedata.match(/^([a-zA-Z0-9_$]*)/)[1];
- if (name) {
- name = o3djs.base.maybeDeobfuscateFunctionName_(name);
- } else {
- name = 'anonymous';
- }
-
- var result = framedata.match(/(.*:[0-9]+)$/);
- line = result && result[1];
-
- if (!line) {
- line = '(unknown)';
- }
-
- stack[stack.length] = name + ' : ' + line
- }
-
- // remove top level anonymous functions to match IE
- var omitRegexp = /^anonymous :/;
- while (stack.length && omitRegexp.exec(stack[stack.length - 1])) {
- stack.length = stack.length - 1;
- }
-
- return stack;
-};
-
-/**
- * Gets a function name from a function object.
- * @param {!function(...): *} aFunction The function object to try to get a
- * name from.
- * @return {string} function name or 'anonymous' if not found.
- */
-o3djs.base.getFunctionName = function(aFunction) {
- var regexpResult = aFunction.toString().match(/function(\s*)(\w*)/);
- if (regexpResult && regexpResult.length >= 2 && regexpResult[2]) {
- return o3djs.base.maybeDeobfuscateFunctionName_(regexpResult[2]);
- }
- return 'anonymous';
-};
-
-/**
- * Pretty prints an exception's stack, if it has one.
- * @param {Array.<string>} stack An array of errors.
- * @return {string} The pretty stack.
- */
-o3djs.base.formatErrorStack = function(stack) {
- var result = '';
- for (var i = 0; i < stack.length; i++) {
- result += '> ' + stack[i] + '\n';
- }
- return result;
-};
-
-/**
- * Gets a stack trace as a string.
- * @param {number} stripCount The number of entries to strip from the top of the
- * stack. Example: Pass in 1 to remove yourself from the stack trace.
- * @return {string} The stack trace.
- */
-o3djs.base.getStackTrace = function(stripCount) {
- var result = '';
-
- if (typeof(arguments.caller) != 'undefined') { // IE, not ECMA
- for (var a = arguments.caller; a != null; a = a.caller) {
- result += '> ' + o3djs.base.getFunctionName(a.callee) + '\n';
- if (a.caller == a) {
- result += '*';
- break;
- }
- }
- } else { // Mozilla, not ECMA
- // fake an exception so we can get Mozilla's error stack
- var testExcp;
- try {
- eval('var var;');
- } catch (testExcp) {
- var stack = o3djs.base.parseErrorStack(testExcp);
- result += o3djs.base.formatErrorStack(stack.slice(3 + stripCount,
- stack.length));
- }
- }
-
- return result;
-};
-
-/**
- * Sets the error handler on a client to a handler that displays an alert on the
- * first error.
- * @param {!o3d.Client} client The client object of the plugin.
- */
-o3djs.base.setErrorHandler = function(client) {
- client.setErrorCallback(
- function(msg) {
- // Clear the error callback. Otherwise if the callback is happening
- // during rendering it's possible the user will not be able to
- // get out of an infinite loop of alerts.
- client.clearErrorCallback();
- alert('ERROR: ' + msg + '\n' + o3djs.base.getStackTrace(1));
- });
-};
-
-/**
- * Returns true if the user's browser is Microsoft IE.
- * @return {boolean} true if the user's browser is Microsoft IE.
- */
-o3djs.base.IsMSIE = function() {
- var ua = navigator.userAgent.toLowerCase();
- var msie = /msie/.test(ua) && !/opera/.test(ua);
- return msie;
-};
diff --git a/o3d/samples/o3djs/camera.js b/o3d/samples/o3djs/camera.js
deleted file mode 100644
index 9acf95e..0000000
--- a/o3d/samples/o3djs/camera.js
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains various camera utility functions for
- * o3d. It puts them in the "camera" module on the o3djs object.
- *
- * Note: This library is only a sample. It is not meant to be some official
- * library. It is provided only as example code.
- *
- */
-
-o3djs.provide('o3djs.camera');
-
-o3djs.require('o3djs.util');
-o3djs.require('o3djs.math');
-
-/**
- * A Module for camera utilites.
- * @namespace
- */
-o3djs.camera = o3djs.camera || {};
-
-/**
- * Class to hold Camera information.
- * @constructor
- * @param {!o3djs.math.Matrix4} view The 4-by-4 view matrix.
- * @param {number} zNear near z plane.
- * @param {number} zFar far z plane.
- * @param {!o3djs.math.Vector3} opt_eye The eye position.
- * @param {!o3djs.math.Vector3} opt_target The target position.
- * @param {!o3djs.math.Vector3} opt_up The up vector.
- */
-o3djs.camera.CameraInfo = function(view,
- zNear,
- zFar,
- opt_eye,
- opt_target,
- opt_up) {
- /**
- * View Matrix.
- * @type {!o3djs.math.Matrix4}
- */
- this.view = view;
-
- /**
- * Projection Matrix.
- * @type {!o3djs.math.Matrix4}
- */
- this.projection = o3djs.math.matrix4.identity();
-
- /**
- * Projection is orthographic.
- * @type {boolean}
- */
- this.orthographic = false;
-
- /**
- * Near z plane.
- * @type {number}
- */
- this.zNear = zNear;
-
- /**
- * Far z plane.
- * @type {number}
- */
- this.zFar = zFar;
-
- /**
- * Field of view in radians.
- * @type {number}
- */
- this.fieldOfViewRadians = o3djs.math.degToRad(30);
-
- /**
- * Eye position.
- * @type {(!o3djs.math.Vector3|undefined)}
- */
- this.eye = opt_eye;
-
- /**
- * Target position.
- * @type {(!o3djs.math.Vector3|undefined)}
- */
- this.target = opt_target;
-
- /**
- * Up Vector.
- * @type {(!o3djs.math.Vector3|undefined)}
- */
- this.up = opt_up;
-
- /**
- * horizontal magnification for an orthographic view.
- * @type {(number|undefined)}
- */
- this.magX = undefined;
-
- /**
- * vertical magnification for an orthographic view.
- * @type {(number|undefined)}
- */
- this.magY = undefined;
-};
-
-/**
- * Sets the CameraInfo to an orthographic camera.
- * @param {number} magX horizontal magnification.
- * @param {number} magY vertical magnification.
- */
-o3djs.camera.CameraInfo.prototype.setAsOrthographic = function(
- magX, magY) {
- this.orthographic = true
- this.magX = magX;
- this.magY = magY;
-};
-
-/**
- * Sets the CameraInfo to an orthographic camera.
- * @param {number} fieldOfView Field of view in radians.
- */
-o3djs.camera.CameraInfo.prototype.setAsPerspective = function(
- fieldOfView) {
- this.orthographic = false;
- this.fieldOfViewRadians = fieldOfView;
-};
-
-/**
- * Computes a projection matrix for this CameraInfo using the areaWidth
- * and areaHeight passed in.
- *
- * @param {number} areaWidth width of client area.
- * @param {number} areaHeight heigh of client area.
- * @return {!o3djs.math.Matrix4} The computed projection matrix.
- */
-o3djs.camera.CameraInfo.prototype.computeProjection = function(
- areaWidth,
- areaHeight) {
- if (this.orthographic) {
- // TODO: figure out if there is a way to make this take the areaWidth
- // and areaHeight into account. As it is, magX and magY from the
- // collada file are relative to the aspect ratio of Maya's render
- // settings which are not available here.
- // var magX = areaWidth * 0.5 / this.magX;
- // var magY = areaHeight * 0.5 / this.magY;
- var magX = /** @type {number} */ (this.magX);
- var magY = /** @type {number} */ (this.magY);
- this.projection = o3djs.math.matrix4.orthographic(
- -magX, magX, -magY, magY, this.zNear, this.zFar);
- } else {
- this.projection = o3djs.math.matrix4.perspective(
- this.fieldOfViewRadians, // field of view.
- areaWidth / areaHeight, // Aspect ratio.
- this.zNear, // Near plane.
- this.zFar); // Far plane.
- }
- return this.projection;
-};
-
-/**
- * Searches for all nodes with a "o3d.tags" ParamString
- * that contains the word "camera" assuming comma separated
- * words.
- * @param {!o3d.Transform} treeRoot Root of tree to search for cameras.
- * @return {!Array.<!o3d.Transform>} Array of camera transforms.
- */
-o3djs.camera.findCameras = function(treeRoot) {
- return o3djs.util.getTransformsInTreeByTags(treeRoot, 'camera');
-};
-
-/**
- * Creates a object with view and projection matrices using paramters found on
- * the camera 'o3d.projection_near_z', 'o3d.projection_far_z', and
- * 'o3d.perspective_fov_y' as well as the areaWidth and areaHeight passed
- * in.
- * @param {!o3d.Transform} camera Transform with camera information on it.
- * @param {number} areaWidth width of client area.
- * @param {number} areaHeight height of client area.
- * @return {!o3djs.camera.CameraInfo} A CameraInfo object.
- */
-o3djs.camera.getViewAndProjectionFromCamera = function(camera,
- areaWidth,
- areaHeight) {
- var fieldOfView = 30;
- var zNear = 1;
- var zFar = 5000;
- var eye = undefined;
- var target = undefined;
- var up = undefined;
- var view;
- var math = o3djs.math;
- var cameraInfo;
-
- // Check if any LookAt elements were found for the camera and use their
- // values to compute a view matrix.
- var eyeParam = camera.getParam('collada.eyePosition');
- var targetParam = camera.getParam('collada.targetPosition');
- var upParam = camera.getParam('collada.upVector');
- if (eyeParam != null && targetParam != null && upParam != null) {
- eye = eyeParam.value;
- target = targetParam.value;
- up = upParam.value;
- view = math.matrix4.lookAt(eye, target, up);
- } else {
- // Set it to the orientation of the camera.
- view = math.inverse(camera.getUpdatedWorldMatrix());
- }
-
- var projectionType = camera.getParam('collada.projectionType');
- if (projectionType) {
- zNear = camera.getParam('collada.projectionNearZ').value;
- zFar = camera.getParam('collada.projectionFarZ').value;
-
- if (projectionType.value == 'orthographic') {
- var magX = camera.getParam('collada.projectionMagX').value;
- var magY = camera.getParam('collada.projectionMagY').value;
-
- cameraInfo = new o3djs.camera.CameraInfo(view, zNear, zFar);
- cameraInfo.setAsOrthographic(magX, magY);
- } else if (projectionType.value == 'perspective') {
- fieldOfView = camera.getParam('collada.perspectiveFovY').value;
- }
- }
-
- if (!cameraInfo) {
- cameraInfo = new o3djs.camera.CameraInfo(view, zNear, zFar,
- eye, target, up);
- cameraInfo.setAsPerspective(math.degToRad(fieldOfView));
- }
-
- cameraInfo.computeProjection(areaWidth, areaHeight);
- return cameraInfo;
-};
-
-/**
- * Get CameraInfo that represents a view of the bounding box that encompasses
- * a tree of transforms.
- * @param {!o3d.Transform} treeRoot Root of sub tree to get extents from.
- * @param {number} clientWidth width of client area.
- * @param {number} clientHeight height of client area.
- * @return {!o3djs.camera.CameraInfo} A CameraInfo object.
- */
-o3djs.camera.getCameraFitToScene = function(treeRoot,
- clientWidth,
- clientHeight) {
- var math = o3djs.math;
- var box = o3djs.util.getBoundingBoxOfTree(treeRoot);
- var target = math.lerpVector(box.minExtent, box.maxExtent, 0.5);
- var boxDimensions = math.subVector(box.maxExtent, box.minExtent);
- var diag = o3djs.math.distance(box.minExtent, box.maxExtent);
- var eye = math.addVector(target, [boxDimensions[0] * 0.3,
- boxDimensions[1] * 0.7,
- diag * 1.5]);
- var nearPlane = diag / 1000;
- var farPlane = diag * 10;
-
- var up = [0, 1, 0];
- var cameraInfo = new o3djs.camera.CameraInfo(
- math.matrix4.lookAt(eye, target, up),
- nearPlane,
- farPlane);
-
- cameraInfo.setAsPerspective(math.degToRad(45));
- cameraInfo.computeProjection(clientWidth, clientHeight);
- return cameraInfo;
-};
-
-/**
- * Calls findCameras and takes the first camera. Then calls
- * o3djs.camera.getViewAndProjectionFromCamera. If no camera is found it
- * sets up some defaults.
- * @param {!o3d.Transform} treeRoot Root of tree to search for cameras.
- * @param {number} areaWidth Width of client area.
- * @param {number} areaHeight Height of client area.
- * @return {!o3djs.camera.CameraInfo} A CameraInfo object.
- */
-o3djs.camera.getViewAndProjectionFromCameras = function(treeRoot,
- areaWidth,
- areaHeight) {
- var cameras = o3djs.camera.findCameras(treeRoot);
-
- if (cameras.length > 0) {
- return o3djs.camera.getViewAndProjectionFromCamera(cameras[0],
- areaWidth,
- areaHeight);
- } else {
- // There was no camera in the file so make up a hopefully resonable default.
- return o3djs.camera.getCameraFitToScene(treeRoot,
- areaWidth,
- areaHeight);
- }
-};
-
-/**
- * Calls findCameras and creates an array of CameraInfos for each camera found.
- * @param {!o3d.Transform} treeRoot Root of tree to search for cameras.
- * @param {number} areaWidth Width of client area.
- * @param {number} areaHeight Height of client area.
- * @return {!Array.<!o3djs.camera.CameraInfo>} A CameraInfo object.
- */
-o3djs.camera.getCameraInfos = function(treeRoot, areaWidth, areaHeight) {
- var cameras = o3djs.camera.findCameras(treeRoot);
- var cameraInfos = [];
-
- for (var cc = 0; cc < cameras.length; ++cc) {
- cameraInfos.push(o3djs.camera.getViewAndProjectionFromCamera(
- cameras[cc], areaWidth, areaHeight));
- }
- return cameraInfos;
-};
-
-/**
- * Sets the view and projection of a DrawContext to view the bounding box
- * that encompasses the tree of transforms passed.
- *
- * This function is here to help debug a program by providing an easy way to
- * attempt to get your content in front of the camera.
- *
- * @param {!o3d.Transform} treeRoot Root of sub tree to get extents from.
- * @param {number} clientWidth width of client area.
- * @param {number} clientHeight height of client area.
- * @param {!o3d.DrawContext} drawContext DrawContext to set view and
- * projection on.
- */
-o3djs.camera.fitContextToScene = function(treeRoot,
- clientWidth,
- clientHeight,
- drawContext) {
- var cameraInfo = o3djs.camera.getCameraFitToScene(treeRoot,
- clientWidth,
- clientHeight);
- drawContext.view = cameraInfo.view;
- drawContext.projection = cameraInfo.projection;
-};
diff --git a/o3d/samples/o3djs/cameracontroller.js b/o3d/samples/o3djs/cameracontroller.js
deleted file mode 100644
index 69dc100..0000000
--- a/o3d/samples/o3djs/cameracontroller.js
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains sample code for controlling the camera
- * (ie view matrix) using the mouse and keyboard.
- */
-
-o3djs.provide('o3djs.cameracontroller');
-
-o3djs.require('o3djs.math');
-
-/**
- * A Module for user control of the camera / view matrix.
- * @namespace
- */
-o3djs.cameracontroller = o3djs.cameracontroller || {};
-
-/**
- * The possible modes that a CameraController can be in.
- * One of these is usually set when a mouse button is pressed down,
- * and then NONE is set when the mouse button is released.
- * When the mouse is moved, the DragMode determines what effect the mouse move
- * has on the camera parameters (such as position and orientation).
- * If the DragMode is NONE, mouse moves have no effect.
- * @enum {number}
- */
-o3djs.cameracontroller.DragMode = {
- /**
- * Dragging the mouse has no effect.
- */
- NONE: 0,
- /**
- * Dragging left or right changes rotationAngle,
- * dragging up or down changes heightAngle.
- */
- SPIN_ABOUT_CENTER: 1,
- /**
- * Dragging up or down changes the backpedal.
- */
- DOLLY_IN_OUT: 2,
- /**
- * Dragging up or down changes the fieldOfViewAngle.
- */
- ZOOM_IN_OUT: 3,
- /**
- * Dragging up or down changes the amount of perspective.
- * Perspective is focused on the centerPos.
- * If backpedal is negative or zero, there is no effect.
- */
- DOLLY_ZOOM: 4,
- /**
- * Dragging moves the centerPos around the plane perpendicular to
- * the camera view direction.
- */
- MOVE_CENTER_IN_VIEW_PLANE: 5
-};
-
-/**
- * Creates a CameraController.
- * @param {!o3djs.math.Vector3} centerPos The position that the camera is
- * looking at and rotating around; or if backpedal is zero, the location
- * of the camera. In world space.
- * @param {number} backpedal The distance the camera moves back from the
- * centerPos.
- * @param {number} heightAngle The angle the camera rotates up or down
- * (about the x axis that passes through the centerPos). In radians.
- * @param {number} rotationAngle The angle the camera rotates left or right
- * (about the y axis that passes through the centerPos). In radians.
- * @param {number} fieldOfViewAngle The vertical angle of the viewing frustum.
- * In radians, between 0 and PI/2. This does not affect the view matrix,
- * but it can still be useful to let the CameraController control the
- * field of view.
- * @param {function(!o3djs.cameracontroller.CameraController): void}
- * opt_onChange Pointer to a callback to call when the camera changes.
- * @return {!o3djs.cameracontroller.CameraController} The created
- * CameraController.
- */
-o3djs.cameracontroller.createCameraController = function(centerPos,
- backpedal,
- heightAngle,
- rotationAngle,
- fieldOfViewAngle,
- opt_onChange) {
- return new o3djs.cameracontroller.CameraController(centerPos,
- backpedal,
- heightAngle,
- rotationAngle,
- fieldOfViewAngle,
- opt_onChange);
-};
-
-/**
- * Class to hold user-controlled camera information and handle user events.
- * It can control and output a view matrix, and can also control some aspects
- * of a projection matrix.
- *
- * Most of the parameters it controls affect the view matrix, and it can
- * generate a view matrix based on its parameters.
- * It can also control certain parameters that affect the projection matrix,
- * such as field of view. Rather than deal with all the parameters needed for
- * a projection matrix, this class leaves generation of the projection matrix
- * up to the user code, and simply exposes the parameters it has.
- * @constructor
- * @param {!o3djs.math.Vector3} centerPos The position that the camera is
- * looking at and rotating around; or if backpedal is zero, the location
- * of the camera. In world space.
- * @param {number} backpedal The distance the camera moves back from the
- * centerPos.
- * @param {number} heightAngle The angle the camera rotates up or down
- * (about the x axis that passes through the centerPos). In radians.
- * @param {number} rotationAngle The angle the camera rotates left or right
- * (about the y axis that passes through the centerPos). In radians.
- * @param {number} fieldOfViewAngle The vertical angle of the viewing frustum.
- * In radians, between 0 and PI/2. This does not affect the view matrix,
- * but it can still be useful to let this class control the field of view.
- * @param {function(!o3djs.cameracontroller.CameraController): void}
- * opt_onChange Pointer to a callback to call when the camera changes.
- */
-o3djs.cameracontroller.CameraController = function(centerPos,
- backpedal,
- heightAngle,
- rotationAngle,
- fieldOfViewAngle,
- opt_onChange) {
- /**
- * The position that the camera is looking at and rotating around.
- * Or if backpedal is zero, the location of the camera. In world space.
- * @type {!o3djs.math.Vector3}
- */
- this.centerPos = centerPos;
-
- /**
- * The distance the camera moves back from the centerPos.
- * @type {number}
- */
- this.backpedal = backpedal;
-
- /**
- * The angle the camera rotates up or down.
- * @type {number}
- */
- this.heightAngle = heightAngle;
-
- /**
- * The angle the camera rotates left or right.
- * @type {number}
- */
- this.rotationAngle = rotationAngle;
-
- /**
- * The vertical angle of the perspective viewing frustum.
- * In radians, between 0 and PI/2. This does not affect the view matrix.
- * The user code can access this value and use it to construct a
- * projection matrix, or it can simply ignore it.
- * @type {number}
- */
- this.fieldOfViewAngle = fieldOfViewAngle;
-
-
- /**
- * Points to a callback to call when the camera changes.
- * @type {function(!o3djs.cameracontroller.CameraController): void}
- */
- this.onChange = opt_onChange || null;
-
- /**
- * The current mouse-drag mode, ie what happens when you move the mouse.
- * @private
- * @type {o3djs.cameracontroller.DragMode}
- */
- this.dragMode_ = o3djs.cameracontroller.DragMode.NONE;
-
- /**
- * The last X coordinate of the mouse.
- * @private
- * @type {number}
- */
- this.mouseX_ = 0;
-
- /**
- * The last Y coordinate of the mouse.
- * @private
- * @type {number}
- */
- this.mouseY_ = 0;
-
-
- // Some variables to control how quickly the camera changes when you
- // move the mouse a certain distance. Feel free to modify these.
- // Mouse pixels are converted into arbitrary "units" (for lack of
- // a better term), and then "units" are converted into an angle,
- // or a distance, etc as the case may be.
-
- /**
- * Controls how quickly the mouse moves the camera (in general).
- * Used to convert pixels into "units".
- * @type {number}
- */
- this.pixelsPerUnit = 300.0;
-
- /**
- * Controls how quickly the mouse affects rotation angles.
- * Used to convert "units" into radians.
- * @type {number}
- */
- this.radiansPerUnit = 1.0;
-
- /**
- * Controls how quickly the mouse affects camera translation.
- * Used to convert "units" into world space units of distance.
- * @type {number}
- */
- this.distancePerUnit = 10.0;
-
- /**
- * Controls how quickly the mouse affects zooming.
- * Used to convert "units" into zoom factor.
- * @type {number}
- */
- this.zoomPerUnit = 1.0;
-};
-
-/**
- * Calculates the center point and backpedal which will make the
- * camera view the entire supplied bounding box, assuming a symmetric
- * perspective projection. The heightAngle and rotationAngle are
- * unchanged.
- * @param {!o3d.BoundingBox} The bounding box to enclose in the view
- * volume.
- * @param {number} aspectRatio The aspect ratio of the viewing plane.
- */
-o3djs.cameracontroller.CameraController.prototype.viewAll =
- function(boundingBox,
- aspectRatio) {
- // Form a view matrix facing in the correct direction but whose
- // origin is at the center of the bounding box
- var minExtent = boundingBox.minExtent;
- var maxExtent = boundingBox.maxExtent;
- var centerPos = o3djs.math.divVectorScalar(
- o3djs.math.addVector(minExtent, maxExtent), 2.0);
- var viewMatrix = this.calculateViewMatrix_(centerPos, 0);
- var maxBackpedal = 0;
- var vertFOV = this.fieldOfViewAngle;
- var tanVertFOV = Math.tan(vertFOV);
- var horizFOV = Math.atan(aspectRatio * tanVertFOV);
- var tanHorizFOV = Math.tan(horizFOV);
- var extents = [minExtent, maxExtent];
- for (var zi = 0; zi < 2; zi++) {
- for (var yi = 0; yi < 2; yi++) {
- for (var xi = 0; xi < 2; xi++) {
- // Form world space vector of this corner
- var vec = [extents[xi][0], extents[yi][1], extents[zi][2], 1];
- // Transform by the temporary view matrix
- vec = o3djs.math.mulVectorMatrix(vec, viewMatrix);
- // Consider only points on the +z side of the origin
- if (vec[2] >= 0.0) {
- // Figure out the backpedal based on the horizontal and
- // vertical view angles, and the z coordinate of the
- // corner
- maxBackpedal = Math.max(maxBackpedal,
- vec[2] + vec[0] / tanHorizFOV);
- maxBackpedal = Math.max(maxBackpedal,
- vec[2] + vec[1] / tanVertFOV);
- }
- }
- }
- }
- // Now set up the center point, backpedal and distancePerUnit
- this.centerPos = centerPos;
- this.backpedal = maxBackpedal;
- // This is heuristic based on some experimentation
- this.distancePerUnit = maxBackpedal / 5.0;
-};
-
-/**
- * Calculates the view matrix for this camera.
- * @return {!o3djs.math.Matrix4} The view matrix.
- */
-o3djs.cameracontroller.CameraController.prototype.calculateViewMatrix =
- function() {
- return this.calculateViewMatrix_(this.centerPos, this.backpedal);
-};
-
-/**
- * Calculates the view matrix for this camera given the specified
- * center point and backpedal.
- * @param {!o3djs.math.Vector3} centerPoint Center point for the
- * camera.
- * @param {number} backpedal Backpedal from the center point for the
- * camera.
- */
-o3djs.cameracontroller.CameraController.prototype.calculateViewMatrix_ =
- function(centerPoint, backpedal) {
- var matrix4 = o3djs.math.matrix4;
- var view = matrix4.translation(o3djs.math.negativeVector(centerPoint));
- view = matrix4.mul(view, matrix4.rotationY(this.rotationAngle));
- view = matrix4.mul(view, matrix4.rotationX(this.heightAngle));
- view = matrix4.mul(view, matrix4.translation([0, 0, -backpedal]));
- return view;
-};
-
-/**
- * Change the current mouse-drag mode, ie what happens when you move the mouse.
- * Usually you would set it to something when a mouse button is pressed down,
- * and then set it to NONE when the button is released.
- * @param {o3djs.cameracontroller.DragMode} dragMode The new DragMode.
- * @param {number} x The current mouse X coordinate.
- * @param {number} y The current mouse Y coordinate.
- */
-o3djs.cameracontroller.CameraController.prototype.setDragMode =
- function(dragMode, x, y) {
- this.dragMode_ = dragMode;
- this.mouseX_ = x;
- this.mouseY_ = y;
-};
-
-/**
- * Method which should be called by end user code upon receiving a
- * mouse-move event.
- * @param {number} x The new mouse X coordinate.
- * @param {number} y The new mouse Y coordinate.
- */
-o3djs.cameracontroller.CameraController.prototype.mouseMoved = function(x, y) {
- var deltaX = (x - this.mouseX_) / this.pixelsPerUnit;
- var deltaY = (y - this.mouseY_) / this.pixelsPerUnit;
- this.mouseX_ = x;
- this.mouseY_ = y;
-
- if (this.dragMode_ == o3djs.cameracontroller.DragMode.SPIN_ABOUT_CENTER) {
- this.rotationAngle += deltaX * this.radiansPerUnit;
- this.heightAngle += deltaY * this.radiansPerUnit;
- }
- if (this.dragMode_ == o3djs.cameracontroller.DragMode.DOLLY_IN_OUT) {
- this.backpedal += deltaY * this.distancePerUnit;
- }
- if (this.dragMode_ == o3djs.cameracontroller.DragMode.ZOOM_IN_OUT) {
- var width = Math.tan(this.fieldOfViewAngle);
- width *= Math.pow(2, deltaY * this.zoomPerUnit);
- this.fieldOfViewAngle = Math.atan(width);
- }
- if (this.dragMode_ == o3djs.cameracontroller.DragMode.DOLLY_ZOOM) {
- if (this.backpedal > 0) {
- var oldWidth = Math.tan(this.fieldOfViewAngle);
- this.fieldOfViewAngle += deltaY * this.radiansPerUnit;
- this.fieldOfViewAngle = Math.min(this.fieldOfViewAngle, 0.98 * Math.PI/2);
- this.fieldOfViewAngle = Math.max(this.fieldOfViewAngle, 0.02 * Math.PI/2);
- var newWidth = Math.tan(this.fieldOfViewAngle);
- this.backpedal *= oldWidth / newWidth;
- }
- }
- if (this.dragMode_ ==
- o3djs.cameracontroller.DragMode.MOVE_CENTER_IN_VIEW_PLANE) {
- var matrix4 = o3djs.math.matrix4;
- var translationVector = [-deltaX * this.distancePerUnit,
- deltaY * this.distancePerUnit, 0];
- var inverseViewMatrix = matrix4.inverse(this.calculateViewMatrix());
- translationVector = matrix4.transformDirection(
- inverseViewMatrix, translationVector);
- this.centerPos = o3djs.math.addVector(this.centerPos, translationVector);
- }
-
- if (this.onChange != null &&
- this.dragMode_ != o3djs.cameracontroller.DragMode.NONE) {
- this.onChange(this);
- }
-};
diff --git a/o3d/samples/o3djs/canvas.js b/o3d/samples/o3djs/canvas.js
deleted file mode 100644
index fce83b4..0000000
--- a/o3d/samples/o3djs/canvas.js
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains a basic utility library that simplifies the
- * creation of simple 2D Canvas surfaces for the purposes of drawing 2D elements
- * in O3D.
- *
- * Example
- *
- * <pre>
- * &lt;html&gt;&lt;body&gt;
- * &lt;script type="text/javascript" src="o3djs/all.js"&gt;
- * &lt;/script&gt;
- * &lt;script&gt;
- * window.onload = init;
- *
- * function init() {
- * o3djs.base.makeClients(initStep2);
- * }
- *
- * function initStep2(clientElements) {
- * var clientElement = clientElements[0];
- * var client = clientElement.client;
- * var pack = client.createPack();
- * var viewInfo = o3djs.rendergraph.createBasicView(
- * pack,
- * client.root,
- * client.renderGraphRoot);
- *
- * // Create an instance of the canvas utility library.
- * var canvasLib = o3djs.canvas.create(
- * pack, client.root, g_viewInfo);
- *
- * // Create a 700x500 rectangle at (x,y,z) = (4, 10, 0)
- * var canvasQuad = canvasLib.createXYQuad(4, 10, 0, 700, 500, false);
- *
- * // Draw into the canvas.
- * canvasQuad.canvas.clear([1, 0, 0, 1]);
- * canvasQuad.canvas.drawText('Hello', 0, 10, canvasPaint);
- * ...
- * ...
- *
- * // Update the o3d texture associated with the canvas.
- * canvasQuad.updateTexture();
- * }
- * &lt;/script&gt;
- * &lt;div id="o3d" style="width: 600px; height: 600px"&gt;&lt;/div&gt;
- * &lt;/body&gt;&lt;/html&gt;
- * </pre>
- *
- */
-
-o3djs.provide('o3djs.canvas');
-
-o3djs.require('o3djs.effect');
-o3djs.require('o3djs.primitives');
-
-/**
- * A Module for using a 2d canvas.
- * @namespace
- */
-o3djs.canvas = o3djs.canvas || {};
-
-/**
- * Creates an o3djs.canvas library object through which CanvasQuad objects
- * can be created.
- * @param {!o3d.Pack} pack to manage objects created by this library.
- * @param {!o3d.Transform} root Default root for visual objects.
- * @param {!o3djs.rendergraph.ViewInfo} viewInfo A ViewInfo object as
- * created by o3djs.createView which contains draw lists that the created
- * quads will be placed into.
- * @return {!o3djs.canvas.CanvasInfo} A CanvasInfo object containing
- * references to all the common O3D elements used by this instance
- * of the library.
- */
-o3djs.canvas.create = function(pack, root, viewInfo) {
- return new o3djs.canvas.CanvasInfo(pack, root, viewInfo);
-};
-
-/**
- * The shader code used by the canvas quads. It only does two things:
- * 1. Transforms the shape to screen space via the worldViewProjection matrix.
- * 2. Performs a texture lookup to display the contents of the texture
- * bound to texSampler0.
- * @return {string} The shader used canvas quads.
- */
-o3djs.canvas.buildShaderString = function() {
- var p = o3djs.effect;
- var varyingDecls = p.BEGIN_OUT_STRUCT +
- p.VARYING + p.FLOAT4 + ' ' +
- p.VARYING_DECLARATION_PREFIX + 'position' +
- p.semanticSuffix('POSITION') + ';\n' +
- p.VARYING + p.FLOAT2 + ' ' +
- p.VARYING_DECLARATION_PREFIX + 'texCoord' +
- p.semanticSuffix('TEXCOORD0') + ';\n' +
- p.END_STRUCT;
-
- return 'uniform ' + p.MATRIX4 + ' worldViewProjection' +
- p.semanticSuffix('WORLDVIEWPROJECTION') + ';\n\n' +
- p.BEGIN_IN_STRUCT +
- p.ATTRIBUTE + p.FLOAT4 + ' position' +
- p.semanticSuffix('POSITION') + ';\n' +
- p.ATTRIBUTE + p.FLOAT2 + ' texCoord0' +
- p.semanticSuffix('TEXCOORD0') + ';\n' +
- p.END_STRUCT +
- '\n' +
- varyingDecls +
- '\n' +
- p.beginVertexShaderMain() +
- ' ' + p.VERTEX_VARYING_PREFIX + 'position = ' +
- p.mul(p.ATTRIBUTE_PREFIX + 'position',
- 'worldViewProjection') + ';\n' +
- ' ' + p.VERTEX_VARYING_PREFIX + 'texCoord = ' +
- p.ATTRIBUTE_PREFIX + 'texCoord0;\n' +
- p.endVertexShaderMain() +
- '\n' +
- p.pixelShaderHeader() +
- 'uniform ' + p.SAMPLER + ' texSampler0;\n' +
- p.repeatVaryingDecls(varyingDecls) +
- p.beginPixelShaderMain() +
- p.endPixelShaderMain(p.TEXTURE + '2D' +
- '(texSampler0, ' + p.PIXEL_VARYING_PREFIX + 'texCoord)') +
- p.entryPoints() +
- p.matrixLoadOrder();
-};
-
-
-/**
- * The CanvasInfo object creates and keeps references to the O3D objects
- * that are shared between all CanvasQuad objects created through it.
- * @constructor
- * @param {!o3d.Pack} pack Pack to manage CanvasInfo objects.
- * @param {!o3d.Transform} root Default root for visual objects.
- * @param {!o3djs.rendergraph.ViewInfo} viewInfo A ViewInfo object as
- * created by o3djs.createView which contains draw lists that the
- * created quads will be placed into.
- */
-o3djs.canvas.CanvasInfo = function(pack, root, viewInfo) {
- /**
- * The pack being used to manage objects created by this CanvasInfo.
- * @type {!o3d.Pack}
- */
- this.pack = pack;
-
- /**
- * The ViewInfo this CanvasInfo uses for rendering.
- * @type {!o3djs.rendergraph.ViewInfo}
- */
- this.viewInfo = viewInfo;
-
- /**
- * The default root for objects created by this CanvasInfo.
- * @type {!o3d.Transform}
- */
- this.root = root;
-
- /**
- * The Effect object shared by all CanvasQuad instances.
- * @type {!o3d.Effect}
- */
- this.effect_ = this.pack.createObject('Effect');
- this.effect_.loadFromFXString(o3djs.canvas.buildShaderString());
-
- /**
- * Material for canvases with transparent content
- * @type {!o3d.Material}
- */
- this.transparentMaterial_ = this.pack.createObject('Material');
-
- /**
- * Material for canvases with opaque content.
- * @type {!o3d.Material}
- */
- this.opaqueMaterial_ = this.pack.createObject('Material');
-
- this.transparentMaterial_.effect = this.effect_;
- this.opaqueMaterial_.effect = this.effect_;
-
- this.transparentMaterial_.drawList = viewInfo.zOrderedDrawList;
- this.opaqueMaterial_.drawList = viewInfo.performanceDrawList;
-
- /**
- * State object to handle the transparency blending mode
- * for transparent canvas quads.
- * The canvas bitmap already multiplies the color values by alpha. In order
- * to avoid a black halo around text drawn on a transparent background we
- * need to set the blending mode as follows.
- * @type {!o3d.State}
- */
- this.transparentState_ = this.pack.createObject('State');
- this.transparentState_.getStateParam('AlphaBlendEnable').value = true;
- this.transparentState_.getStateParam('SourceBlendFunction').value =
- o3djs.base.o3d.State.BLENDFUNC_ONE;
- this.transparentState_.getStateParam('DestinationBlendFunction').value =
- o3djs.base.o3d.State.BLENDFUNC_INVERSE_SOURCE_ALPHA;
-
- this.transparentMaterial_.state = this.transparentState_;
-
- // Create 2d plane shapes. createPlane makes an XZ plane by default
- // so we pass in matrix to rotate it to an XY plane. We could do
- // all our manipulations in XZ but most people seem to like XY for 2D.
-
- /**
- * A shape for transparent quads.
- * @type {!o3d.Shape}
- */
- this.transparentQuadShape = o3djs.primitives.createPlane(
- this.pack,
- this.transparentMaterial_,
- 1,
- 1,
- 1,
- 1,
- o3djs.math.makeMatrix4(1, 0, 0, 0,
- 0, 0, 1, 0,
- 0, -1, 0 ,0,
- 0, 0, 0, 1));
-
- /**
- * A shape for opaque quads.
- * @type {!o3d.Shape}
- */
- this.opaqueQuadShape = o3djs.primitives.createPlane(
- this.pack,
- this.opaqueMaterial_,
- 1,
- 1,
- 1,
- 1,
- o3djs.math.makeMatrix4(1, 0, 0, 0,
- 0, 0, 1, 0,
- 0, -1, 0 ,0,
- 0, 0, 0, 1));
-};
-/**
- * The CanvasQuad object encapsulates a Transform, a rectangle Shape,
- * an effect that applies a texture to render the quad, and a matching Canvas
- * object that can render into the texture. The dimensions of the texture and
- * the canvas object match those of the quad in order to get pixel-accurate
- * results with the appropriate orthographic projection.
- * The resulting rectangle Shape is positioned at the origin. It can be moved
- * around by setting the localMatrix on the Transform object referenced to by
- * the canvasQuad.transform property.
- * The Canvas associated with the returned CanvasQuad object can be retrieved
- * from the object's 'canvas' property. After issuing any draw commands on the
- * Canvas, you need to call the updateTexture() method on the CanvasQuad to
- * update the contents of the quad surface.
- * @constructor
- * @param {!o3djs.canvas.CanvasInfo} canvasInfo The CanvasInfo object
- * instance creating this CanvasQuad.
- * @param {number} width The width of the quad.
- * @param {number} height The height of the quad.
- * @param {boolean} transparent Set to true if the canvas will
- * be transparent so that the appropriate blending modes are set.
- * @param {!o3d.Transform} opt_parent parent transform to parent
- * the newly created quad under. If no parent transform is provided then
- * the quad gets parented under the CanvasInfo's root.
- */
-o3djs.canvas.CanvasQuad = function(canvasInfo,
- width,
- height,
- transparent,
- opt_parent) {
- /**
- * The CanvasInfo managing this CanvasQuad
- * @type {!o3djs.canvas.CanvasInfo}
- */
- this.canvasInfo = canvasInfo;
- var parentTransform = opt_parent || canvasInfo.root;
-
- // create a transform for positioning
-
- /**
- * A transform for this quad.
- * @type {!o3d.Transform}
- */
- this.transform = canvasInfo.pack.createObject('Transform');
- this.transform.parent = parentTransform;
-
- // create a transform for scaling to the size of the image just so
- // we don't have to manage that manually in the transform above.
-
- /**
- * A scale transform for this quad.
- * You can change the scale the quad without effecting its positon using
- * this transform.
- * @type {!o3d.Transform}
- */
- this.scaleTransform = canvasInfo.pack.createObject('Transform');
- this.scaleTransform.parent = this.transform;
-
- /**
- * The texture the canvas will draw on.
- * @type {!o3d.Texture2D}
- */
- this.texture = /** @type {!o3d.Texture2D} */ (canvasInfo.pack.createTexture2D(
- width,
- height,
- o3djs.base.o3d.Texture.ARGB8,
- 1, // mipmap levels
- false));
-
- // Create a Canvas object to go with the quad.
-
- /**
- * The Canvas object used to draw on this quad.
- * @type {!o3d.Canvas}
- */
- this.canvas = canvasInfo.pack.createObject('Canvas');
- this.canvas.setSize(width, height);
-
- /**
- * The sampler for the texture.
- * @type {!o3d.Sampler}
- */
- this.sampler = canvasInfo.pack.createObject('Sampler');
- this.sampler.addressModeU = o3djs.base.o3d.Sampler.CLAMP;
- this.sampler.addressModeV = o3djs.base.o3d.Sampler.CLAMP;
-
- /**
- * The param sampler for this transform.
- * @private
- * @type {!o3d.ParamSampler}
- */
- this.paramSampler_ = this.scaleTransform.createParam('texSampler0',
- 'ParamSampler');
- this.paramSampler_.value = this.sampler;
-
- this.sampler.texture = this.texture;
- if (transparent) {
- this.scaleTransform.addShape(canvasInfo.transparentQuadShape);
- } else {
- this.scaleTransform.addShape(canvasInfo.opaqueQuadShape);
- }
- this.scaleTransform.translate(width / 2, height / 2, 0);
- this.scaleTransform.scale(width, -height, 1);
-};
-
-/**
- * Copies the current contents of the Canvas object to the texture associated
- * with the quad. This method should be called after any new draw calls have
- * been issued to the CanvasQuad's Canvas object.
- */
-o3djs.canvas.CanvasQuad.prototype.updateTexture = function() {
- var width = this.texture.width;
- var height = this.texture.height;
- this.texture.drawImage(this.canvas, 0, height - 1, width, -height,
- 0, 0, 0, width, height);
-};
-
-/**
- * Creates a CanvasQuad object on the XY plane at the specified position.
- * @param {number} topX The x coordinate of the top left corner of the quad.
- * @param {number} topY The y coordinate of the top left corner of the quad.
- * @param {number} z The z coordinate of the quad. z values are negative
- * numbers, the smaller the number the further back the quad will be.
- * @param {number} width The width of the quad.
- * @param {number} height The height of the quad.
- * @param {boolean} transparent Set to true if the canvas bitmap uses
- * transparency so that the appropriate blending modes are set.
- * @param {!o3d.Transform} opt_parent parent transform to parent the newly
- * created quad under. If no parent transform is provided then the quad
- * gets parented under the CanvasInfo's root.
- * @return {!o3djs.canvas.CanvasQuad} The newly created CanvasQuad object.
- */
-o3djs.canvas.CanvasInfo.prototype.createXYQuad = function(topX,
- topY,
- z,
- width,
- height,
- transparent,
- opt_parent) {
- var canvasQuad = new o3djs.canvas.CanvasQuad(this,
- width,
- height,
- transparent,
- opt_parent);
-
- canvasQuad.transform.translate(topX, topY, z);
- return canvasQuad;
-};
-
-/**
- * Creates a CanvasQuad object of the given size. The resulting rectangle Shape
- * is centered at the origin. It can be moved around by setting the
- * localMatrix on the Transform object referenced to by the canvasQuad.transform
- * property.
- * @param {number} width The width of the quad.
- * @param {number} height The height of the quad.
- * @param {boolean} transparent Set to true if the canvas bitmap uses
- * transparency so that the appropriate blending modes are set.
- * @param {!o3d.Transform} opt_parent parent transform to parent the newly
- * created quad under. If no parent transform is provided then the quad
- * gets parented under the CanvasInfo's root.
- * @return {!o3djs.canvas.CanvasQuad} The newly created CanvasQuad object.
- */
-o3djs.canvas.CanvasInfo.prototype.createQuad = function(width,
- height,
- transparent,
- opt_parent) {
- return new o3djs.canvas.CanvasQuad(this,
- width,
- height,
- transparent,
- opt_parent);
-};
-
-
diff --git a/o3d/samples/o3djs/debug.js b/o3d/samples/o3djs/debug.js
deleted file mode 100644
index f646d90..0000000
--- a/o3d/samples/o3djs/debug.js
+++ /dev/null
@@ -1,1031 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains various functions to help debug for o3d
- * applications.
- *
- * Note: This library is only a sample. It is not meant to be some official
- * library. It is provided only as example code.
- *
- */
-
-o3djs.provide('o3djs.debug');
-
-o3djs.require('o3djs.math');
-o3djs.require('o3djs.primitives');
-o3djs.require('o3djs.lineprimitives');
-
-var O3D_DEBUG_PREFIX = 'o3dDebug_';
-var O3D_DEBUG_PREFIX_LENGTH = O3D_DEBUG_PREFIX.length;
-var O3D_DEBUG_COLOR_PARAM_NAME = O3D_DEBUG_PREFIX + 'Color';
-var O3D_DEBUG_VECTOR_SCALE_PARAM_NAME =
- O3D_DEBUG_PREFIX + 'VectorScale';
-var O3D_DEBUG_AXIS_SHAPE_NAME = O3D_DEBUG_PREFIX + 'AxisShape';
-var O3D_DEBUG_LINE_SHAPE_NAME = O3D_DEBUG_PREFIX + 'LineShape';
-var O3D_DEBUG_SPHERE_SHAPE_NAME = O3D_DEBUG_PREFIX + 'SphereShape';
-var O3D_DEBUG_CUBE_SHAPE_NAME = O3D_DEBUG_PREFIX + 'CubeShape';
-
-var O3D_DEBUG_AXIS_INFO_ = [
- {offset: [1, 0, 0], color: [1, 0, 0, 1]},
- {offset: [0, 1, 0], color: [0, 1, 0, 1]},
- {offset: [0, 0, 1], color: [0, 0, 1, 1]}];
-
-/**
- * Checks whether or not a transform is a debug transform.
- * @param {!o3d.Transform} transform Transform to check.
- * @return {boolean} true if this transform is a debug transform.
- */
-o3djs.debug.isDebugTransform = function(transform) {
- var name = transform.name;
- var isDT =
- name.length >= O3D_DEBUG_PREFIX_LENGTH &&
- name.substr(0, O3D_DEBUG_PREFIX_LENGTH) == O3D_DEBUG_PREFIX;
- return isDT;
-};
-
-/**
- * Gets the debug transform.
- * @private
- * @param {!o3d.Transform} transform Transform to get debug Transform
- * from.
- * @param {string} name Name of debug transform to get.
- * @return {o3d.Transform} Debug Transform or null if not found.
- */
-o3djs.debug.getDebugTransform_ = function(transform, name) {
- if (transform.name == name) {
- return transform;
- } else {
- var children = transform.children;
- for (var cc = 0; cc < children.length; ++cc) {
- if (children[cc].name == name) {
- return children[cc];
- }
- }
- }
- return null;
-};
-
-/**
- * Creates shaders that output the constant color from a parameter.
- * @private
- * @param {string} colorParamName Name of color parameter to use.
- * @return {string} Shader string.
- */
-o3djs.debug.createColorShaders_ = function(colorParamName) {
- var p = o3djs.effect;
- var shaders =
- 'uniform ' + p.MATRIX4 + ' worldViewProjection' +
- p.semanticSuffix('WORLDVIEWPROJECTION') + ';\n' +
- p.BEGIN_IN_STRUCT +
- p.ATTRIBUTE + p.FLOAT4 + ' position' +
- p.semanticSuffix('POSITION') + ';\n' +
- p.END_STRUCT +
- p.BEGIN_OUT_STRUCT +
- p.VARYING + p.FLOAT4 + ' ' + p.VARYING_DECLARATION_PREFIX + 'position' +
- p.semanticSuffix('POSITION') + ';\n' +
- p.END_STRUCT +
- p.beginVertexShaderMain() +
- ' ' + p.VERTEX_VARYING_PREFIX + 'position = ' +
- p.mul(p.ATTRIBUTE_PREFIX + 'position', 'worldViewProjection')
- + ';\n' +
- p.endVertexShaderMain() +
- p.pixelShaderHeader() +
- 'uniform ' + p.FLOAT4 + ' ' + colorParamName + ';\n' +
- p.beginPixelShaderMain() +
- p.endPixelShaderMain(colorParamName) +
- p.entryPoints() +
- p.matrixLoadOrder();
- return shaders;
-};
-
-/**
- * Creates shaders that output the constant color from a parameter and scale
- * the vertices in object space.
- * @private
- * @param {string} colorParamName Name of color parameter to use.
- * @param {string} scaleParamName Name of scale parameter to use.
- * @return {string} Shader string.
- */
-o3djs.debug.createScaleShaders_ = function(colorParamName, scaleParamName) {
- var p = o3djs.effect;
- var shaders =
- 'uniform ' + p.FLOAT3 + ' ' + scaleParamName + ';\n' +
- 'uniform ' + p.MATRIX4 + ' worldViewProjection' +
- p.semanticSuffix('WORLDVIEWPROJECTION') + ';\n' +
- p.BEGIN_IN_STRUCT +
- p.ATTRIBUTE + p.FLOAT4 + ' position' + p.semanticSuffix('POSITION') +
- ';\n' +
- p.END_STRUCT +
- p.BEGIN_OUT_STRUCT +
- p.VARYING + p.FLOAT4 + ' ' + p.VARYING_DECLARATION_PREFIX + 'position' +
- p.semanticSuffix('POSITION') + ';\n' +
- p.END_STRUCT +
- p.beginVertexShaderMain() +
- ' ' + p.FLOAT4 + ' position = ' + p.FLOAT4 + '(\n' +
- ' ' + p.ATTRIBUTE_PREFIX + 'position.x * ' + scaleParamName + '.x,\n' +
- ' ' + p.ATTRIBUTE_PREFIX + 'position.y * ' + scaleParamName + '.y,\n' +
- ' ' + p.ATTRIBUTE_PREFIX + 'position.z * ' + scaleParamName + '.z,\n' +
- ' 1);\n' +
- ' ' + p.VERTEX_VARYING_PREFIX + 'position = ' +
- p.mul('position', 'worldViewProjection') + ';\n' +
- p.endVertexShaderMain() +
- p.pixelShaderHeader() +
- 'uniform ' + p.FLOAT4 + ' ' + colorParamName + ';\n' +
- p.beginPixelShaderMain() +
- p.endPixelShaderMain(colorParamName) +
- p.entryPoints() +
- p.matrixLoadOrder();
- return shaders;
-};
-
-
-/**
- * Defines a namespace for o3djs.debug.
- * @namespace
- */
-o3djs.debug = o3djs.debug || {};
-
-/**
- * An object to manage a single debug line.
- * @constructor
- * @param {!o3djs.debug.DebugLineGroup} debugLineGroup DebugLineGroup
- * this line belongs too.
- */
-o3djs.debug.DebugLine = function(debugLineGroup) {
- /**
- * The DebugLineGroup this DebugLine is managed by.
- * @private
- * @type {!o3djs.debug.DebugLineGroup}
- */
- this.debugLineGroup_ = debugLineGroup;
- var pack = debugLineGroup.getPack();
-
- /**
- * The transform for this DebugLine.
- * @private
- * @type {!o3d.Transform}
- */
- this.transform_ = pack.createObject('Transform');
- this.transform_.name = O3D_DEBUG_LINE_SHAPE_NAME;
- this.transform_.addShape(debugLineGroup.getLineShape());
-
- /**
- * The start position of the line.
- * @private
- * @type {!o3djs.math.Vector3}
- */
- this.start_ = [0, 0, 0];
-
- /**
- * The start position of the line.
- * @private
- * @type {!o3djs.math.Vector3}
- */
- this.end_ = [0, 0, 0];
-
- /**
- * The color param for the line.
- * @private
- * @type {!o3d.ParamFloat4}
- */
- this.colorParam_ = this.transform_.createParam(
- O3D_DEBUG_COLOR_PARAM_NAME, 'ParamFloat4');
- this.colorParam_.value = debugLineGroup.getColor();
-};
-
-/**
- * Destroys this line object cleaning up the resources used by it.
- */
-o3djs.debug.DebugLine.prototype.destroy = function() {
- this.transform_.parent = null;
- this.debugLineGroup_.getPack().removeObject(this.transform_);
-};
-
-/**
- * Returns a unique Id for the line.
- * @return {number} the Id of the line.
- */
-o3djs.debug.DebugLine.prototype.getId = function() {
- return this.transform_.clientId;
-};
-
-/**
- * Updates the line with the current start and end settings.
- * @private
- */
-o3djs.debug.DebugLine.prototype.update_ = function() {
- var math = o3djs.math;
- var vector = math.subVector(this.end_, this.start_);
- var direction = math.normalize(vector);
- var dot = math.dot(direction, [0, 1, 0]);
- var perp1;
- var perp2;
- if (dot > 0.99) {
- perp2 = math.cross([1, 0, 0], direction);
- perp1 = math.cross(perp2, direction);
- } else {
- perp1 = math.cross([0, 1, 0], direction);
- perp2 = math.cross(perp1, direction);
- }
- this.transform_.localMatrix =
- o3djs.math.makeMatrix4(perp2[0], perp2[1], perp2[2], 0,
- direction[0], direction[1], direction[2], 0,
- perp1[0], perp1[1], perp1[2], 0,
- this.start_[0], this.start_[1], this.start_[2], 1);
- this.transform_.scale(1, math.length(vector), 1);
-};
-
-/**
- * Sets the end points of the DebugLine.
- * @param {!o3djs.math.Vector3} start Start point for line.
- * @param {!o3djs.math.Vector3} end End point for line.
- */
-o3djs.debug.DebugLine.prototype.setEndPoints = function(start, end) {
- this.start_ = start;
- this.end_ = end;
- this.update_();
-};
-
-/**
- * Sets the start point of the DebugLine.
- * @param {!o3djs.math.Vector3} start Start point for line.
- */
- o3djs.debug.DebugLine.prototype.setStart = function(start) {
- this.start_ = start;
- this.update_();
-};
-
-/**
- * Sets the end point of the DebugLine.
- * @param {!o3djs.math.Vector3} end End point for line.
- */
-o3djs.debug.DebugLine.prototype.setEnd = function(end) {
- this.end_ = end;
- this.update_();
-};
-
-/**
- * Sets the color of the DebugLine.
- * @param {!o3djs.math.Vector4} color The color of the debug line.
- */
-o3djs.debug.DebugLine.prototype.setColor = function(color) {
- this.colorParam_.value = color;
-};
-
-/**
- * Sets the visibility of the DebugLine.
- * @param {boolean} visible True = visible.
- */
-o3djs.debug.DebugLine.prototype.setVisible = function(visible) {
- this.transform_.parent = visible ? this.debugLineGroup_.getRoot() : null;
-};
-
-/**
- * Removes this line.
- */
-o3djs.debug.DebugLine.prototype.remove = function() {
- this.transform_.parent = null;
- this.debugLineGroup_.remove(this);
-};
-
-/**
- * An object to manage debug lines.
- * @constructor
- * @param {!o3djs.debug.DebugHelper} debugHelper The DebugHelper
- * associated with this object.
- * @param {!o3d.Transform} root Transform to put debug lines under.
- */
-o3djs.debug.DebugLineGroup = function(debugHelper, root) {
- /**
- * The default color to make new lines.
- * @private
- * @type {!o3djs.math.Vector4}
- */
- this.currentColor_ = [1, 1, 1, 1];
-
- /**
- * The lines in this group indexed by clientId.
- * @private
- * @type {!Object.<number, !o3djs.debug.DebugLine>}
- */
- this.lineTransforms_ = { };
-
- /**
- * The unused lines in this group indexed by clientId.
- * @private
- * @type {!Object.<number, !o3djs.debug.DebugLine>}
- */
- this.freeLineTransforms_ = { };
-
- /**
- * The DebugHelper managing this DebugLineGroup.
- * @private
- * @type {!o3djs.debug.DebugHelper}
- */
- this.debugHelper_ = debugHelper;
-
- /**
- * The root transform for lines in this group.
- * @private
- * @type {!o3d.Transform}
- */
- this.root_ = root;
-};
-
-/**
- * Gets the root transform for this line group.
- * @return {!o3d.Transform} The root transform for this line group.
- */
-o3djs.debug.DebugLineGroup.prototype.getRoot = function() {
- return this.root_;
-};
-
-/**
- * Gets the pack for this line group.
- * @return {!o3d.Pack} The pack for this line group.
- */
-o3djs.debug.DebugLineGroup.prototype.getPack = function() {
- return this.debugHelper_.getPack();
-};
-
-/**
- * Gets the shape for lines.
- * @return {!o3d.Shape} The shape for lines.
- */
-o3djs.debug.DebugLineGroup.prototype.getLineShape = function() {
- return this.debugHelper_.getLineShape();
-};
-
-/**
- * Gets the current color for this line group.
- * @return {!o3djs.math.Vector4} The current color.
- */
-o3djs.debug.DebugLineGroup.prototype.getColor = function() {
- return this.currentColor_;
-};
-
-/**
- * Sets the current color for this line group. All lines added after
- * setting this will be this color by default.
- * @param {!o3djs.math.Vector4} color The color for this line group.
- */
-o3djs.debug.DebugLineGroup.prototype.setColor = function(color) {
- this.currentColor_ = color;
-};
-
-/**
- * Gets a debug line. If none exist creates a new one.
- * @private
- * @return {!o3djs.debug.DebugLine} The DebugLine.
- */
-o3djs.debug.DebugLineGroup.prototype.getLine_ = function() {
- for (var sid in this.freeLineTransforms_) {
- var id = /** @type {number} */ (sid);
- var line = this.freeLineTransforms_[id];
- delete this.freeLineTransforms_[id];
- return line;
- }
- return new o3djs.debug.DebugLine(this);
-};
-
-/**
- * Adds a debug line.
- * @param {!o3djs.math.Vector3} opt_start Start position for line.
- * @param {!o3djs.math.Vector3} opt_end End position for line.
- * @param {!o3djs.math.Vector4} opt_color Color for line.
- * @return {!o3djs.debug.DebugLine} The DebugLine.
- */
-o3djs.debug.DebugLineGroup.prototype.addLine = function(opt_start,
- opt_end,
- opt_color) {
- var line = this.getLine_();
- line.setEndPoints(opt_start || [0, 0, 0], opt_end || [0, 0, 0]);
- line.setColor(opt_color || this.currentColor_);
- line.setVisible(true);
- this.lineTransforms_[line.getId()] = line;
- return line;
-};
-
-/**
- * Clears all the lines in this group.
- */
-o3djs.debug.DebugLineGroup.prototype.clear = function() {
- for (var sid in this.lineTransforms_) {
- var id = /** @type {number} */ (sid);
- var line = this.lineTransforms_[id];
- line.setVisible(false);
- this.freeLineTransforms_[id] = line;
- }
- this.lineTransforms_ = { };
-};
-
-/**
- * Destroys a DeubgLineGroup, freeing all its lines and resources.
- */
-o3djs.debug.DebugLineGroup.prototype.destroy = function() {
- this.clear();
- for (var sid in this.freeLineTransforms_) {
- var id = /** @type {number} */ (sid);
- this.freeLineTransforms_[id].destroy();
- }
- this.freeLineTransforms_ = { };
-};
-
-/**
- * Removes a line.
- * @param {!o3djs.debug.DebugLine} line Line to remove.
- */
-o3djs.debug.DebugLineGroup.prototype.remove = function(line) {
- var id = line.getId();
- delete this.lineTransforms_[id];
- this.freeLineTransforms_[id] = line;
-};
-
-/**
- * A Debug object to help with debugging o3d apps.
- *
- * A debug helper object provides functions to help debug your o3d
- * application and manages the resources needed to do that for you. For
- * example it can add axes, spheres and boxes to your transforms as well as
- * draw lines in 3d space given 2 points.
- *
- * @constructor
- * @param {!o3d.Pack} pack Pack for this debug object to use to manage
- * its resources.
- * @param {!o3djs.rendergraph.ViewInfo} viewInfo ViewInfo for debug
- * visuals.
- */
-o3djs.debug.DebugHelper = function(pack, viewInfo) {
- this.pack_ = pack;
- this.viewInfo_ = viewInfo;
- this.axisPrimitives_ = [];
- this.axisShape_ = pack.createObject('Shape');
- this.axisShape_.name = O3D_DEBUG_AXIS_SHAPE_NAME;
- this.lineShape_ = pack.createObject('Shape');
- this.lineShape_.name = O3D_DEBUG_LINE_SHAPE_NAME;
-
- // Setup shape, material, primitive for axes.
- {
- // create a simple material for the axis.
- var effect = pack.createObject('Effect');
- var shaders = o3djs.debug.createScaleShaders_(
- O3D_DEBUG_COLOR_PARAM_NAME,
- O3D_DEBUG_VECTOR_SCALE_PARAM_NAME);
- effect.loadFromFXString(shaders);
- var material = pack.createObject('Material');
- material.effect = effect;
- material.drawList = viewInfo.performanceDrawList;
- effect.createUniformParameters(material);
-
- // Set the default color to white.
- material.getParam(O3D_DEBUG_COLOR_PARAM_NAME).value = [1, 1, 1, 1];
-
- // Set the default scale.
- material.getParam(O3D_DEBUG_VECTOR_SCALE_PARAM_NAME).value =
- [1, 1, 1];
-
- // Create the axis shape.
- for (var ii = 0; ii < O3D_DEBUG_AXIS_INFO_.length; ++ii) {
- var info = O3D_DEBUG_AXIS_INFO_[ii];
- var cubeShape = o3djs.primitives.createCube(
- pack,
- material,
- 1,
- o3djs.math.makeMatrix4(1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- info.offset[0] * 0.5,
- info.offset[1] * 0.5,
- info.offset[2] * 0.5,
- 1));
-
- var cube = cubeShape.elements[0];
- cube.owner = this.axisShape_;
- pack.removeObject(cubeShape);
- cube.createParam(O3D_DEBUG_COLOR_PARAM_NAME, 'ParamFloat4').value =
- info.color;
- cube.createParam(O3D_DEBUG_VECTOR_SCALE_PARAM_NAME, 'ParamFloat3');
- this.axisPrimitives_[ii] = cube;
- }
-
- this.axisMaterial_ = material;
- this.setAxisScale(10, 1);
- }
-
- // Setup shape, material, primitive for debug lines.
- {
- // create a simple material for the debug lines.
- var effect = pack.createObject('Effect');
- var shaders = o3djs.debug.createColorShaders_(O3D_DEBUG_COLOR_PARAM_NAME);
- effect.loadFromFXString(shaders);
- var material = pack.createObject('Material');
- material.effect = effect;
- material.drawList = viewInfo.performanceDrawList;
- effect.createUniformParameters(material);
-
- // Set the default color to white.
- material.getParam(O3D_DEBUG_COLOR_PARAM_NAME).value = [1, 1, 1, 1];
-
- // Create the debug line shape.
- var vertices = [0, 0, 0, 0, 1, 0];
- var streamBank = pack.createObject('StreamBank');
- var primitive = pack.createObject('Primitive');
- var shape = pack.createObject('Shape');
- var vertexBuffer = pack.createObject('VertexBuffer');
- var positionField = vertexBuffer.createField('FloatField', 3);
- vertexBuffer.set(vertices);
- primitive.owner = shape;
- primitive.createDrawElement(pack, null);
- primitive.streamBank = streamBank;
- primitive.material = material;
- primitive.numberVertices = 2;
- primitive.numberPrimitives = 1;
- primitive.primitiveType = o3djs.base.o3d.Primitive.LINELIST;
- streamBank.setVertexStream(o3djs.base.o3d.Stream.POSITION,
- 0,
- positionField,
- 0);
- this.lineShape_ = shape;
- this.lineShape_.name = O3D_DEBUG_LINE_SHAPE_NAME;
- this.lineMaterial_ = material;
- }
-
- {
- this.sphereShape_ = o3djs.lineprimitives.createLineSphere(
- pack,
- this.axisMaterial_,
- 0.5, 8, 8);
- this.sphereShape_.name = O3D_DEBUG_SPHERE_SHAPE_NAME;
- var primitive = this.sphereShape_.elements[0];
- this.sphereScaleParam_ = primitive.createParam(
- O3D_DEBUG_VECTOR_SCALE_PARAM_NAME,
- 'ParamFloat3').value = [1, 1, 1];
- }
-
- {
- this.cubeShape_ = o3djs.lineprimitives.createLineCube(
- pack,
- this.axisMaterial_,
- 1);
- this.cubeShape_.name = O3D_DEBUG_CUBE_SHAPE_NAME;
- var primitive = this.cubeShape_.elements[0];
- this.cubeScaleParam_ = primitive.createParam(
- O3D_DEBUG_VECTOR_SCALE_PARAM_NAME,
- 'ParamFloat3').value = [1, 1, 1];
- }
-};
-
-
-/**
- * Gets the pack for this DebugHelper.
- * @return {!o3d.Pack} The pack for this DebugHelper.
- */
-o3djs.debug.DebugHelper.prototype.getPack = function() {
- return this.pack_;
-};
-
-/**
- * Gets the line shape.
- * @return {!o3d.Shape} The shape for debug lines.
- */
-o3djs.debug.DebugHelper.prototype.getLineShape = function() {
- return this.lineShape_;
-};
-
-/**
- * Sets the length and width of the axis lines.
- * @param {number} length Length of an axis in the direction of the axis.
- * @param {number} width Width of the axis or its thickness.
- */
-o3djs.debug.DebugHelper.prototype.setAxisScale = function(length,
- width) {
- for (var ii = 0; ii < O3D_DEBUG_AXIS_INFO_.length; ++ii) {
- var info = O3D_DEBUG_AXIS_INFO_[ii];
- this.axisPrimitives_[ii].getParam(
- O3D_DEBUG_VECTOR_SCALE_PARAM_NAME).value = [
- info.offset[0] ? length : width,
- info.offset[1] ? length : width,
- info.offset[2] ? length : width];
- }
-};
-
-/**
- * Creates a debug shape at a world position.
- * @private
- * @param {!o3djs.math.Vector3} position Position at which to create shape.
- * @param {!o3d.Shape} shape Shape to add to transform.
- * @return {!o3d.Transform} transform for shape.
- */
-o3djs.debug.DebugHelper.prototype.createShape_ = function(position, shape) {
-
- var debugTransform = this.getPack().createObject('Transform');
- debugTransform.name = shape.name;
- debugTransform.addShape(shape);
- debugTransform.parent = this.viewInfo_.treeRoot;
- debugTransform.translate(position);
- return debugTransform;
-};
-
-/**
- * Adds an debug shape to a transform.
- * @private
- * @param {!o3d.Transform} transform Transform to add shape to.
- * @param {!o3d.Shape} shape Shape to add to transform.
- */
-o3djs.debug.DebugHelper.prototype.addShape_ = function(transform,
- shape) {
-
- var debugTransform = o3djs.debug.getDebugTransform_(transform, shape.name);
- if (!debugTransform) {
- var debugTransform = this.getPack().createObject('Transform');
- debugTransform.name = shape.name;
- debugTransform.addShape(shape);
- debugTransform.parent = transform;
- }
-};
-
-/**
- * Removes a debug shape from a transform
- * @private
- * @param {!o3d.Transform} transform Transform to remove shape from.
- * @param {!o3d.Shape} shape Shape to remove from transform.
- */
-o3djs.debug.DebugHelper.prototype.removeShape_ = function(transform,
- shape) {
- var name = shape.name;
- var debugTransform = o3djs.debug.getDebugTransform_(transform, shape.name);
- if (debugTransform) {
- debugTransform.parent = null;
- this.getPack().removeObject(debugTransform);
- }
-};
-
-/**
- * Adds a debug shape to all transform a tree.
- * @private
- * @param {!o3d.Transform} treeRoot root of tree to add shape to.
- * @param {!o3d.Shape} shape Shape to add to transforms.
- */
-o3djs.debug.DebugHelper.prototype.addShapes_ = function(treeRoot,
- shape) {
- this.addShape_(treeRoot, shape);
- var children = treeRoot.children;
- for (var cc = 0; cc < children.length; ++cc) {
- var child = children[cc];
- if (!o3djs.debug.isDebugTransform(child)) {
- this.addShapes_(child, shape);
- }
- }
-};
-
-/**
- * Removes a debug shape from all transforms in a tree.
- * @private
- * @param {!o3d.Transform} treeRoot root of tree to remove axes from.
- * @param {!o3d.Shape} shape Shape to remove from transforms.
- */
-o3djs.debug.DebugHelper.prototype.removeShapes_ = function(treeRoot,
- shape) {
- this.removeShape_(treeRoot, shape);
- var children = treeRoot.children;
- for (var cc = 0; cc < children.length; ++cc) {
- var child = children[cc];
- if (!o3djs.debug.isDebugTransform(child)) {
- this.removeShapes_(child, shape);
- }
- }
-};
-
-/**
- * Sets a param value on a debug transform. If the param does not exist it
- * will be created.
- * @private
- * @param {!o3d.Transform} transform Transform on which debug transform
- * exists.
- * @param {string} name Name of debug transform.
- * @param {string} paramName Name of param to set.
- * @param {string} paramType type of param to set.
- * @param {*} paramValue value to set param.
- */
-o3djs.debug.DebugHelper.prototype.addSetDebugTransformParam_ = function(
- transform,
- name,
- paramName,
- paramType,
- paramValue) {
- var debugTransform = o3djs.debug.getDebugTransform_(transform, name);
- if (debugTransform) {
- var param = debugTransform.getParam(paramName);
- if (!param) {
- param = debugTransform.createParam(paramName, paramType);
- }
- param.value = paramValue;
- }
-};
-
-/**
- * Adds an axis to a transform.
- * @param {!o3d.Transform} transform Transform to add axis to.
- */
-o3djs.debug.DebugHelper.prototype.addAxis = function(transform) {
- this.addShape_(transform, this.axisShape_);
-};
-
-/**
- * Removes an axis from a transform
- * @param {!o3d.Transform} transform Transform to remove axis from.
- */
-o3djs.debug.DebugHelper.prototype.removeAxis = function(transform) {
- this.removeShape_(transform, this.axisShape_);
-};
-
-/**
- * Adds axes to all transform in a tree.
- * @param {!o3d.Transform} treeRoot root of tree to add axes to.
- */
-o3djs.debug.DebugHelper.prototype.addAxes = function(treeRoot) {
- this.addShapes_(treeRoot, this.axisShape_);
-};
-
-/**
- * Removes axes from all transforms in a tree.
- * @param {!o3d.Transform} treeRoot root of tree to remove axes from.
- */
-o3djs.debug.DebugHelper.prototype.removeAxes = function(treeRoot) {
- this.removeShapes_(treeRoot, this.axisShape_);
-};
-
-/**
- * Set axis color.
- * @param {!o3d.Transform} transform Transform on which to change axis
- * color.
- * @param {!o3djs.math.Vector4} color 4 number array in RGBA format.
- */
-o3djs.debug.DebugHelper.prototype.setAxisColor = function(transform,
- color) {
- this.addSetDebugTransformParam_(transform,
- O3D_DEBUG_AXIS_SHAPE_NAME,
- O3D_DEBUG_COLOR_PARAM_NAME,
- 'ParamFloat4',
- color);
-};
-
-/**
- * Removes the color from an axis.
- * @param {!o3d.Transform} transform Transform on which to remove color.
- */
-o3djs.debug.DebugHelper.prototype.clearAxisColor = function(transform) {
- var debugTransform = o3djs.debug.getDebugTransform_(
- transform,
- O3D_DEBUG_AXIS_SHAPE_NAME);
- if (debugTransform) {
- var colorParam = debugTransform.getParam(O3D_DEBUG_COLOR_PARAM_NAME);
- if (colorParam) {
- debugTransform.removeParam(colorParam);
- }
- }
-};
-
-/**
- * Creates a sphere in world space.
- * @param {!o3djs.math.Vector3} position Position at which to create sphere.
- * @param {!o3djs.math.Vector4} opt_color RGBA color for sphere.
- * @param {number} opt_scale of sphere.
- * @return {!o3d.Transform} transform for sphere.
- */
-o3djs.debug.DebugHelper.prototype.createSphere = function(position,
- opt_color,
- opt_scale) {
- var transform = this.createShape_(position, this.sphereShape_);
- if (opt_color) {
- this.setSphereColor(transform, opt_color);
- }
- if (opt_scale) {
- this.setSphereScale(transform, opt_scale);
- }
- return transform;
-};
-
-/**
- * Adds a sphere to a transform.
- * @param {!o3d.Transform} transform Transform to add sphere to.
- * @param {!o3djs.math.Vector4} opt_color RGBA color for sphere.
- * @param {number} opt_scale of sphere.
- */
-o3djs.debug.DebugHelper.prototype.addSphere = function(transform,
- opt_color,
- opt_scale) {
- this.addShape_(transform, this.sphereShape_);
- if (opt_color) {
- this.setSphereColor(transform, opt_color);
- }
- if (opt_scale) {
- this.setSphereScale(transform, opt_scale);
- }
-};
-
-/**
- * Removes a sphere from a transform
- * @param {!o3d.Transform} transform Transform to remove sphere from.
- */
-o3djs.debug.DebugHelper.prototype.removeSphere = function(transform) {
- this.removeShape_(transform, this.sphereShape_);
-};
-
-/**
- * Adds spheres to all transform a tree.
- * @param {!o3d.Transform} treeRoot root of tree to add spheres to.
- */
-o3djs.debug.DebugHelper.prototype.addSpheres = function(treeRoot) {
- this.addShapes_(treeRoot, this.sphereShape_);
-};
-
-/**
- * Removes spheres from all transforms in a tree.
- * @param {!o3d.Transform} treeRoot root of tree to remove spheres from.
- */
-o3djs.debug.DebugHelper.prototype.removeSpheres = function(treeRoot) {
- this.removeShapes_(treeRoot, this.sphereShape_);
-};
-
-/**
- * Set sphere color.
- * @param {!o3d.Transform} transform Transform on which to change sphere
- * color.
- * @param {!o3djs.math.Vector4} color 4 number array in RGBA format.
- */
-o3djs.debug.DebugHelper.prototype.setSphereColor = function(transform,
- color) {
- this.addSetDebugTransformParam_(transform,
- O3D_DEBUG_SPHERE_SHAPE_NAME,
- O3D_DEBUG_COLOR_PARAM_NAME,
- 'ParamFloat4',
- color);
-};
-
-/**
- * Sets the scale of a debug sphere.
- * @param {!o3d.Transform} transform Transform on which to change sphere
- * scale.
- * @param {number} scale Scale to make the sphere.
- */
-o3djs.debug.DebugHelper.prototype.setSphereScale = function(transform,
- scale) {
- this.addSetDebugTransformParam_(transform,
- O3D_DEBUG_SPHERE_SHAPE_NAME,
- O3D_DEBUG_VECTOR_SCALE_PARAM_NAME,
- 'ParamFloat3',
- [scale, scale, scale]);
-};
-
-/**
- * Creates a cube at a world position..
- * @param {!o3djs.math.Vector3} position Position at which to create sphere.
- * @param {!o3djs.math.Vector4} opt_color RGBA color for cube.
- * @param {number} opt_scale of cube.
- * @return {!o3d.Transform} transform for cube.
- */
-o3djs.debug.DebugHelper.prototype.createCube = function(position,
- opt_color,
- opt_scale) {
- var transform = this.createShape_(position, this.cubeShape_);
- if (opt_color) {
- this.setCubeColor(transform, opt_color);
- }
- if (opt_scale) {
- this.setCubeScale(transform, opt_scale);
- }
- return transform;
-};
-
-/**
- * Adds a cube to a transform.
- * @param {!o3d.Transform} transform Transform to add cube to.
- * @param {!o3djs.math.Vector4} opt_color RGBA color for cube.
- * @param {number} opt_scale of cube.
- */
-o3djs.debug.DebugHelper.prototype.addCube = function(transform,
- opt_color,
- opt_scale) {
- this.addShape_(transform, this.cubeShape_);
- if (opt_color) {
- this.setCubeColor(transform, opt_color);
- }
- if (opt_scale) {
- this.setCubeScale(transform, opt_scale);
- }
-};
-
-/**
- * Removes a cube from a transform
- * @param {!o3d.Transform} transform Transform to remove cube from.
- */
-o3djs.debug.DebugHelper.prototype.removeCube = function(transform) {
- this.removeShape_(transform, this.cubeShape_);
-};
-
-/**
- * Adds cubes to all transform in a tree.
- * @param {!o3d.Transform} treeRoot root of tree to add cubes to.
- */
-o3djs.debug.DebugHelper.prototype.addCubes = function(treeRoot) {
- this.addShapes_(treeRoot, this.cubeShape_);
-};
-
-/**
- * Removes cubes from all transforms in a tree.
- * @param {!o3d.Transform} treeRoot root of tree to remove cubes from.
- */
-o3djs.debug.DebugHelper.prototype.removeCubes = function(treeRoot) {
- this.removeShapes_(treeRoot, this.cubeShape_);
-};
-
-/**
- * Set cube color.
- * @param {!o3d.Transform} transform Transform on which to change cube
- * color.
- * @param {!o3djs.math.Vector3} color 4 number array in RGBA format.
- */
-o3djs.debug.DebugHelper.prototype.setCubeColor = function(transform,
- color) {
- this.addSetDebugTransformParam_(transform,
- O3D_DEBUG_CUBE_SHAPE_NAME,
- O3D_DEBUG_COLOR_PARAM_NAME,
- 'ParamFloat4',
- color);
-};
-
-/**
- * Sets the scale of a cubes.
- * @param {!o3d.Transform} transform Transform on which to change cube
- * scale.
- * @param {number} scale Scale to make the cube.
- */
-o3djs.debug.DebugHelper.prototype.setCubeScale = function(transform,
- scale) {
- this.addSetDebugTransformParam_(transform,
- O3D_DEBUG_CUBE_SHAPE_NAME,
- O3D_DEBUG_VECTOR_SCALE_PARAM_NAME,
- 'ParamFloat3',
- [scale, scale, scale]);
-};
-
-/**
- * Creates a debug line group. A Debug line group's purpose is the let you
- * quickly delete a set of lines.
- * @param {!o3d.Transform} root Root transform to use for lines.
- * @return {!o3djs.debug.DebugLineGroup} The debug line group.
- */
-o3djs.debug.DebugHelper.prototype.createDebugLineGroup =
- function(root) {
- return new o3djs.debug.DebugLineGroup(this, root);
-};
-
-/**
- * Creates a debug helper object.
- *
- * A debug helper object provides functions to help debug your o3d
- * application and manages the resources needed to do that for you. For
- * example it can add axes, spheres and boxes to your transforms as well as
- * draw lines in 3d space given 2 points.
- *
- * @param {!o3d.Pack} pack Pack for DebugHelper to manage its resources
- * with.
- * @param {!o3djs.rendergraph.ViewInfo} viewInfo ViewInfo for debug
- * visuals.
- * @return {!o3djs.debug.DebugHelper} the DebugHelper object.
- */
-o3djs.debug.createDebugHelper = function(pack, viewInfo) {
- return new o3djs.debug.DebugHelper(pack, viewInfo);
-};
-
diff --git a/o3d/samples/o3djs/dump.js b/o3d/samples/o3djs/dump.js
deleted file mode 100644
index 2486f51..0000000
--- a/o3d/samples/o3djs/dump.js
+++ /dev/null
@@ -1,585 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains various dumping functions for o3d. It
- * puts them in the "dump" module on the o3djs object.
- *
- * Note: This library is only a sample. It is not meant to be some official
- * library. It is provided only as example code.
- *
- */
-
-o3djs.provide('o3djs.dump');
-
-/**
- * A Module for dumping information about o3d objects.
- * @namespace
- */
-o3djs.dump = o3djs.dump || {};
-
-/**
- * Dump the 3 elements of an array of numbers.
- * @private
- * @param {string} label Label to put in front of dump.
- * @param {!Array.<number>} object Array.
- * @param {string} opt_prefix Optional prefix for indenting.
- */
-o3djs.dump.dumpXYZ_ = function(label, object, opt_prefix) {
- opt_prefix = opt_prefix || '';
- o3djs.dump.dump(opt_prefix + label + ' : ' + object[0] + ', ' +
- object[1] + ', ' + object[2] + '\n');
-};
-
-/**
- * Dump the 4 elements of an array of numbers.
- * @private
- * @param {string} label Label to put in front of dump.
- * @param {!Array.<number>} object Array.
- * @param {string} opt_prefix Optional prefix for indenting.
- */
-o3djs.dump.dumpXYZW_ = function(label, object, opt_prefix) {
- opt_prefix = opt_prefix || '';
- o3djs.dump.dump(opt_prefix + label + ' : ' +
- object[0] + ', ' +
- object[1] + ', ' +
- object[2] + ', ' +
- object[3] + '\n');
-};
-
-/**
- * Get the name of a function.
- * @private
- * @param {!function(...): *} theFunction Function.
- * @return {string} The function name.
- */
-o3djs.dump.getFunctionName_ = function(theFunction) {
- if (theFunction.name) {
- return theFunction.name;
- }
-
- // try to parse the function name from the definition
- var definition = theFunction.toString();
- var name = definition.substring(definition.indexOf('function') + 8,
- definition.indexOf('('));
- if (name) {
- return name;
- }
-
- // sometimes there won't be a function name
- // like for dynamic functions
- return '*anonymous*';
-};
-
-/**
- * Get the signature of a function.
- * @private
- * @param {!function(...): *} theFunction Function.
- * @return {string} The function signature.
- */
-o3djs.dump.getSignature_ = function(theFunction) {
- var signature = o3djs.dump.getFunctionName_(theFunction);
- signature += '(';
- for (var x = 0; x < theFunction.arguments.length; x++) {
- // trim long arguments
- var nextArgument = theFunction.arguments[x];
- if (nextArgument.length > 30) {
- nextArgument = nextArgument.substring(0, 30) + '...';
- }
-
- // apend the next argument to the signature
- signature += "'" + nextArgument + "'";
-
- // comma separator
- if (x < theFunction.arguments.length - 1) {
- signature += ', ';
- }
- }
- signature += ')';
- return signature;
-};
-
-/**
- * Prints a value the console or log or wherever it thinks is appropriate
- * for debugging.
- * @param {string} string String to print.
- */
-o3djs.dump.dump = function(string) {
- o3djs.BROWSER_ONLY = true;
- if (window.dump) {
- window.dump(string);
- } else if (window.console && window.console.log) {
- window.console.log(string);
- }
-};
-
-/**
- * Gets the value of a matrix as a string.
- * @param {!o3djs.math.Matrix4} matrix Matrix4 to get value of.
- * @param {string} opt_prefix Optional prefix for indenting.
- * @return {string} Value of param.
- */
-o3djs.dump.getMatrixAsString = function(matrix, opt_prefix) {
- opt_prefix = opt_prefix || '';
- var result = opt_prefix + '[';
- for (var i = 0; 1; ++i){
- var mi = matrix[i];
- result += '[';
- for (var j = 0; 1; ++j) {
- result += mi[j];
- if (j < mi.length - 1) {
- result += ', ';
- } else {
- result += ']';
- break;
- }
- }
- if (i < matrix.length - 1) {
- result += '\n';
- result += opt_prefix;
- } else {
- break;
- }
- }
- result += ']';
- return result;
-};
-
-/**
- * Dumps a float3
- * @param {string} label Label to put in front of dump.
- * @param {!o3d.Float3} float3 Float3 to dump.
- * @param {string} opt_prefix optional prefix for indenting.
- */
-o3djs.dump.dumpFloat3 = function(label, float3, opt_prefix) {
- opt_prefix = opt_prefix || '';
- o3djs.dump.dumpXYZ_(label, float3, opt_prefix);
-};
-
-/**
- * Dumps a float4
- * @param {string} label Label to put in front of dump.
- * @param {!o3d.Float4} float4 Float4 to dump.
- * @param {string} opt_prefix optional prefix for indenting.
- */
-o3djs.dump.dumpFloat4 = function(label, float4, opt_prefix) {
- opt_prefix = opt_prefix || '';
- o3djs.dump.dumpXYZW_(label, float4, opt_prefix);
-};
-
-/**
- * Dumps a vector4
- * @param {string} label Label to put in front of dump.
- * @param {!Array.<number>} vector4 vector to dump.
- * @param {string} opt_prefix optional prefix for indenting.
- */
-o3djs.dump.dumpVector4 = function(label, vector4, opt_prefix) {
- opt_prefix = opt_prefix || '';
- o3djs.dump.dumpXYZW_(label, vector4, opt_prefix);
-};
-
-/**
- * Dumps a matrix
- * @param {string} label Label to put in front of dump.
- * @param {!o3djs.math.Matrix4} matrix Matrix to dump.
- * @param {string} opt_prefix optional prefix for indenting.
- */
-o3djs.dump.dumpMatrix = function(label, matrix, opt_prefix) {
- opt_prefix = opt_prefix || '';
- o3djs.dump.dump(
- opt_prefix + label + ' :\n' +
- o3djs.dump.getMatrixAsString(matrix, opt_prefix + ' ') +
- '\n');
-};
-
-/**
- * Dump a bounding box.
- * @param {string} label Label to put in front of dump.
- * @param {!o3d.BoundingBox} boundingBox BoundingBox to dump.
- * @param {string} opt_prefix optional prefix for indenting.
- */
-o3djs.dump.dumpBoundingBox = function(label,
- boundingBox,
- opt_prefix) {
- opt_prefix = opt_prefix || '';
- o3djs.dump.dump(opt_prefix + label + ' :\n');
- o3djs.dump.dumpFloat3('min : ',
- boundingBox.minExtent,
- opt_prefix + ' ');
- o3djs.dump.dumpFloat3('max : ',
- boundingBox.maxExtent,
- opt_prefix + ' ');
-};
-
-/**
- * Gets the value of a parameter as a string.
- * @param {!o3d.Param} param Parameter to get value of.
- * @param {string} opt_prefix Optional prefix for indenting.
- * @return {string} Value of param.
- */
-o3djs.dump.getParamValueAsString = function(param, opt_prefix) {
- opt_prefix = opt_prefix || '';
- var value = '*unknown*';
-
- if (param.isAClassName('o3d.ParamFloat')) {
- value = param.value.toString();
- } else if (param.isAClassName('o3d.ParamFloat2')) {
- value = '[' + param.value[0] + ', ' +
- param.value[1] + ']';
- } else if (param.isAClassName('o3d.ParamFloat3')) {
- value = '[' + param.value[0] + ', ' +
- param.value[1] + ', ' +
- param.value[2] + ']';
- } else if (param.isAClassName('o3d.ParamFloat4')) {
- value = '[' + param.value[0] + ', ' +
- param.value[1] + ', ' +
- param.value[2] + ', ' +
- param.value[3] + ']';
- } else if (param.isAClassName('o3d.ParamInteger')) {
- value = param.value.toString();
- } else if (param.isAClassName('o3d.ParamBoolean')) {
- value = param.value.toString();
- } else if (param.isAClassName('o3d.ParamMatrix4')) {
- value = '\n' + o3djs.dump.getMatrixAsString(param.value,
- opt_prefix + ' ');
- } else if (param.isAClassName('o3d.ParamString')) {
- value = param.value;
- } else if (param.isAClassName('o3d.ParamTexture')) {
- value = param.value;
- value = 'texture : "' + (value ? value.name : 'NULL') + '"';
- } else if (param.isAClassName('o3d.ParamSampler')) {
- value = param.value;
- value = 'sampler : "' + (value ? value.name : 'NULL') + '"';
- } else if (param.isAClassName('o3d.ParamMaterial')) {
- value = param.value;
- value = 'material : "' + (value ? value.name : 'NULL') + '"';
- } else if (param.isAClassName('o3d.ParamEffect')) {
- value = param.value;
- value = 'effect : "' + (value ? value.name : 'NULL') + '"';
- } else if (param.isAClassName('o3d.ParamState')) {
- value = param.value;
- value = 'state : "' + (value ? value.name : 'NULL') + '"';
- } else if (param.isAClassName('o3d.ParamTransform')) {
- value = param.value;
- value = 'transform : "' + (value ? value.name : 'NULL') + '"';
- } else if (param.isAClassName('o3d.ParamDrawList')) {
- value = param.value;
- value = 'drawlist : "' + (value ? value.name : 'NULL') + '"';
- } else if (param.isAClassName('o3d.ParamRenderSurface')) {
- value = param.value;
- value = 'renderSurface : "' + (value ? value.name : 'NULL') + '"';
- } else if (param.isAClassName('o3d.ParamRenderDepthStencilSurface')) {
- value = param.value;
- value = 'renderDepthStencilSurface: "' + (value ? value.name : 'NULL') +
- '"';
- } else if (param.isAClassName('o3d.ParamDrawContext')) {
- value = param.value;
- value = 'drawcontext : "' + (value ? value.name : 'NULL') + '"';
- }
-
- return value;
-};
-
-/**
- * Dumps an single parameter
- * @param {!o3d.Param} param Param to dump.
- * @param {string} opt_prefix Optional prefix for indenting.
- */
-o3djs.dump.dumpParam = function(param, opt_prefix) {
- opt_prefix = opt_prefix || '';
- o3djs.dump.dump (
- opt_prefix + param.className + ' : "' + param.name + '" : ' +
- o3djs.dump.getParamValueAsString(param, opt_prefix) + '\n');
-};
-
-/**
- * Given a ParamObject dumps all the Params on it.
- * @param {!o3d.ParamObject} param_object ParamObject to dump Params of.
- * @param {string} opt_prefix Optional prefix for indenting.
- */
-o3djs.dump.dumpParams = function(param_object, opt_prefix) {
- opt_prefix = opt_prefix || '';
- // print params
- var params = param_object.params;
- for (var p = 0; p < params.length; p++) {
- o3djs.dump.dumpParam(params[p], opt_prefix);
- }
-};
-
-/**
- * Given a ParamObject dumps it and all the Params on it.
- * @param {!o3d.ParamObject} param_object ParamObject to dump.
- * @param {string} opt_prefix Optional prefix for indenting.
- */
-o3djs.dump.dumpParamObject = function(param_object, opt_prefix) {
- opt_prefix = opt_prefix || '';
- o3djs.dump.dump (
- opt_prefix + param_object.className + ' : "' +
- param_object.name + '"\n');
- o3djs.dump.dumpParams(param_object, opt_prefix + ' ');
-};
-
-/**
- * Given a Stream dumps it and all the Params on it.
- * @param {!o3d.Stream} stream Stream to dump.
- * @param {string} opt_prefix Optional prefix for indenting.
- */
-o3djs.dump.dumpStream = function(stream, opt_prefix) {
- opt_prefix = opt_prefix || '';
- o3djs.dump.dump(
- opt_prefix + 'semantic: ' + stream.semantic +
- ', index: ' + stream.semanticIndex +
- ', dataType: ' + stream.dataType +
- ', field: ' + stream.field.name + '\n');
-};
-
-/**
- * Given a element dumps its name, all the Params and DrawElements on
- * it.
- * @param {!o3d.Element} element Element to dump.
- * @param {string} opt_prefix Optional prefix for indenting.
- */
-o3djs.dump.dumpElement = function(element, opt_prefix) {
- opt_prefix = opt_prefix || '';
-
- o3djs.dump.dump (opt_prefix + '------------ Element --------------\n');
-
- // get type
- o3djs.dump.dump (
- opt_prefix + 'Element: "' + element.name + '"\n');
-
- // print params
- o3djs.dump.dump (opt_prefix + ' --Params--\n');
- o3djs.dump.dumpParams (element, opt_prefix + ' ');
-
- // print elements.
- o3djs.dump.dump (opt_prefix + ' --DrawElements--\n');
- var drawElements = element.drawElements;
- for (var g = 0; g < drawElements.length; g++) {
- var drawElement = drawElements[g]
- o3djs.dump.dumpParamObject(drawElement, opt_prefix + ' ');
- }
-
- if (element.isAClassName('o3d.Primitive')) {
- o3djs.dump.dump (
- opt_prefix + ' primitive type: ' + element.primitiveType + '\n');
- o3djs.dump.dump (
- opt_prefix + ' number vertices: ' + element.numberVertices + '\n');
- o3djs.dump.dump (
- opt_prefix + ' number primitives: ' + element.numberPrimitives +
- '\n');
- var streamBank = element.streamBank;
- if (streamBank) {
- var streams = streamBank.vertexStreams;
- for (var ss = 0; ss < streams.length; ss++) {
- var stream = streams[ss];
- o3djs.dump.dump(opt_prefix + ' stream ' + ss + ': ');
- o3djs.dump.dumpStream(stream);
- }
- }
- }
-};
-
-/**
- * Given a shape dumps its name, all the Params and Primitves on
- * it.
- * @param {!o3d.Shape} shape Shape to dump.
- * @param {string} opt_prefix Optional prefix for indenting.
- */
-o3djs.dump.dumpShape = function(shape, opt_prefix) {
- opt_prefix = opt_prefix || '';
-
- o3djs.dump.dump (opt_prefix + '------------ Shape --------------\n');
-
- // get type
- o3djs.dump.dump (
- opt_prefix + 'Shape: "' + shape.name + '"\n');
-
- // print params
- o3djs.dump.dump (opt_prefix + ' --Params--\n');
- o3djs.dump.dumpParams (shape, opt_prefix + ' ');
-
- // print elements.
- o3djs.dump.dump (opt_prefix + ' --Elements--\n');
- var elements = shape.elements;
- for (var p = 0; p < elements.length; p++) {
- var element = elements[p];
- o3djs.dump.dumpElement(element, opt_prefix + ' ');
- }
-};
-
-/**
- * Given a texture dumps its name and other info.
- * it.
- * @param {!o3d.Texture} texture Texture to dump.
- * @param {string} opt_prefix Optional prefix for indenting.
- */
-o3djs.dump.dumpTexture = function(texture, opt_prefix) {
- opt_prefix = opt_prefix || '';
- var uri = '';
- var param = texture.getParam('uri');
- if (param) {
- uri = param.value;
- }
- o3djs.dump.dump (
- opt_prefix + texture.className +
- ' : "' + texture.name +
- '" uri : "' + uri +
- '" width: ' + texture.width +
- ' height: ' + texture.height +
- ' alphaIsOne: ' + texture.alphaIsOne +
- '\n');
-};
-
-/**
- * Given a transform dumps its name and all the Params and Shapes on it.
- * @param {!o3d.Transform} transform Transform to dump.
- * @param {string} opt_prefix Optional prefix for indenting.
- */
-o3djs.dump.dumpTransform = function(transform, opt_prefix) {
- opt_prefix = opt_prefix || '';
-
- o3djs.dump.dump (opt_prefix + '----------- Transform -------------\n');
-
- // get type
- o3djs.dump.dump (
- opt_prefix + 'Transform: ' + transform.name + '"\n');
-
- // print params
- o3djs.dump.dump (opt_prefix + ' --Local Matrix--\n');
- o3djs.dump.dump (
- o3djs.dump.getMatrixAsString(transform.localMatrix,
- opt_prefix + ' ') + '\n');
-
- // print params
- o3djs.dump.dump (opt_prefix + ' --Params--\n');
- o3djs.dump.dumpParams (transform, opt_prefix + ' ');
-
- // print shapes.
- o3djs.dump.dump (opt_prefix + ' --Shapes--\n');
- var shapes = transform.shapes;
- for (var s = 0; s < shapes.length; s++) {
- var shape = shapes[s];
- o3djs.dump.dumpNamedObjectName(shape, opt_prefix + ' ');
- }
-};
-
-/**
- * Dumps an entire transform graph tree.
- * @param {!o3d.Transform} transform Transform to start dumping from.
- * @param {string} opt_prefix Optional prefix for indenting.
- */
-o3djs.dump.dumpTransformTree = function(transform, opt_prefix) {
- opt_prefix = opt_prefix || '';
-
- o3djs.dump.dumpTransform(transform, opt_prefix);
-
- var child_prefix = opt_prefix + ' ';
- var children = transform.children;
- for (var c = 0; c < children.length; c++) {
- o3djs.dump.dumpTransformTree(children[c], child_prefix);
- }
-};
-
-/**
- * Dumps a list of Transforms.
- * @param {!Array.<!o3d.Transform>} transform_list Array of Transforms to dump.
- */
-o3djs.dump.dumpTransformList = function(transform_list) {
- o3djs.dump.dump (transform_list.length + ' transforms in list!!!\n');
- for (var i = 0; i < transform_list.length; i++) {
- o3djs.dump.dumpTransform(transform_list[i]);
- }
-};
-
-/**
- * Dumps the name and class of a NamedObject.
- * @param {!o3d.NamedObject} namedObject to use.
- * @param {string} opt_prefix Optional prefix for indenting.
- */
-o3djs.dump.dumpNamedObjectName = function(namedObject, opt_prefix) {
- opt_prefix = opt_prefix || '';
- o3djs.dump.dump (
- opt_prefix + namedObject.className + ' : "' + namedObject.name +
- '"\n');
-};
-
-/**
- * Dumps a RenderNode and all its paramaters.
- * @param {!o3d.RenderNode} render_node RenderNode to use.
- * @param {string} opt_prefix Optional prefix for indenting.
- */
-o3djs.dump.dumpRenderNode = function(render_node, opt_prefix) {
- opt_prefix = opt_prefix || '';
-
- o3djs.dump.dump (opt_prefix + '----------- Render Node -----------\n');
- // get type
- o3djs.dump.dumpNamedObjectName(render_node, opt_prefix);
-
- // print params
- o3djs.dump.dump (opt_prefix + ' --Params--\n');
- o3djs.dump.dumpParams(render_node, opt_prefix + ' ');
-};
-
-/**
- * Dumps an entire RenderGraph tree.
- * @param {!o3d.RenderNode} render_node RenderNode to start dumping from.
- * @param {string} opt_prefix Optional prefix for indenting.
- */
-o3djs.dump.dumpRenderNodeTree = function(render_node, opt_prefix) {
- opt_prefix = opt_prefix || '';
-
- o3djs.dump.dumpRenderNode(render_node, opt_prefix);
-
- var child_prefix = opt_prefix + ' ';
- // Get the list of children sorted by priority.
- var children = render_node.children.sort(function(a, b) {
- return a.priority - b.priority;
- });
- for (var c = 0; c < children.length; c++) {
- o3djs.dump.dumpRenderNodeTree(children[c], child_prefix);
- }
-};
-
-/**
- * Dumps a javascript stack track.
- */
-o3djs.dump.dumpStackTrace = function() {
- o3djs.dump.dump('Stack trace:\n');
- var nextCaller = arguments.callee.caller;
- while (nextCaller) {
- o3djs.dump.dump(o3djs.dump.getSignature_(nextCaller) + '\n');
- nextCaller = nextCaller.caller;
- }
- o3djs.dump.dump('\n\n');
-};
-
diff --git a/o3d/samples/o3djs/effect.js b/o3d/samples/o3djs/effect.js
deleted file mode 100644
index dc16fd4..0000000
--- a/o3d/samples/o3djs/effect.js
+++ /dev/null
@@ -1,1534 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains various functions related to effects.
- * It puts them in the "effect" module on the o3djs object.
- *
- * Note: This library is only a sample. It is not meant to be some official
- * library. It is provided only as example code.
- *
- */
-
-o3djs.provide('o3djs.effect');
-
-o3djs.require('o3djs.io');
-
-/**
- * A Module for dealing with effects.
- * @namespace
- */
-o3djs.effect = o3djs.effect || {};
-
-/**
- * The name of standard 2 color checker effect.
- * @type {string}
- */
-o3djs.effect.TWO_COLOR_CHECKER_EFFECT_NAME =
- 'o3djs.effect.twoColorCheckerEffect';
-
-
-/**
- * An object containing string constants and functions which are specific to
- * the o3d shading language. When setLanguage gets called the properties of
- * this object get coppied into the o3djs.effect namespace and then get used
- * in shader generation code.
- * @namespace
- */
-o3djs.effect.o3d = {
- LANGUAGE: 'o3d',
- FLOAT2: 'float2',
- FLOAT3: 'float3',
- FLOAT4: 'float4',
- MATRIX4: 'float4x4',
- MATRIX3: 'float3x3',
- MOD: 'fmod',
- ATTRIBUTE: ' ',
- ATTRIBUTE_PREFIX: 'input.',
- VARYING: ' ',
- VARYING_DECLARATION_PREFIX: '',
- VERTEX_VARYING_PREFIX: 'output.',
- PIXEL_VARYING_PREFIX: 'input.',
- TEXTURE: 'tex',
- SAMPLER: 'sampler',
- BEGIN_IN_STRUCT: 'struct InVertex {\n',
- BEGIN_OUT_STRUCT: 'struct OutVertex {\n',
- END_STRUCT: '};\n'
-};
-
-
-/**
- * An object containing string constants and functions which are specific to
- * the o3d shading language. When setLanguage gets called the properties of
- * this object get coppied into the o3djs.effect namespace and then get used
- * in shader generation code.
- * @namespace
- */
-o3djs.effect.glsl = {
- LANGUAGE: 'glsl',
- FLOAT2: 'vec2',
- FLOAT3: 'vec3',
- FLOAT4: 'vec4',
- MATRIX4: 'mat4',
- MATRIX3: 'mat3',
- MOD: 'mod',
- ATTRIBUTE: 'attribute ',
- ATTRIBUTE_PREFIX: '',
- VARYING: 'varying ',
- VARYING_DECLARATION_PREFIX: 'v_',
- VERTEX_VARYING_PREFIX: 'v_',
- PIXEL_VARYING_PREFIX: 'v_',
- TEXTURE: 'texture',
- SAMPLER: 'sampler2D',
- BEGIN_IN_STRUCT: '',
- BEGIN_OUT_STRUCT: '',
- END_STRUCT: '',
- // Only used in GLSL version of getAttributeName_.
- semanticNameMap: {
- 'POSITION' : 'position',
- 'NORMAL' : 'normal',
- 'TANGENT' : 'tangent',
- 'BINORMAL' : 'binormal',
- 'COLOR' : 'color',
- 'TEXCOORD0' : 'texCoord0',
- 'TEXCOORD1' : 'texCoord1',
- 'TEXCOORD2' : 'texCoord2',
- 'TEXCOORD3' : 'texCoord3',
- 'TEXCOORD4' : 'texCoord4',
- 'TEXCOORD5' : 'texCoord5',
- 'TEXCOORD6' : 'texCoord6',
- 'TEXCOORD7' : 'texCoord7'
- }
-};
-
-
-/**
- * The string that goes between the stream name and the semicolon to indicate
- * the semantic.
- * @param {string} name Name of the semantic.
- * @return {string}
- */
-o3djs.effect.glsl.semanticSuffix = function(name) {
- return '';
-};
-
-
-/**
- * The string that goes between the stream name and the semicolon to indicate
- * the semantic.
- * @param {string} name Name of the semantic.
- * @return {string}
- */
-o3djs.effect.o3d.semanticSuffix = function(name) {
- return ' : ' + name;
-};
-
-
-/**
- * Attribute variables in GLSL need to be named by their semantic in
- * order for the implementation to hook them up correctly.
- * @private
- */
-o3djs.effect.glsl.getAttributeName_ = function(name, semantic) {
- var p = o3djs.effect;
- return p.semanticNameMap[semantic];
-};
-
-
-/**
- * This passes through the name in the Cg implementation.
- * @private
- */
-o3djs.effect.o3d.getAttributeName_ = function(name, semantic) {
- return name;
-};
-
-
-/**
- * Generates code to multiply two things.
- * @param {string} a One multiplicand.
- * @param {string} b The other multiplicand.
- * @return {string}
- */
-o3djs.effect.glsl.mul = function(a, b) {
- return '(' + b + ' * ' + a + ')';
-};
-
-
-/**
- * Generates code to multiply two things.
- * @param {string} a One multiplicand.
- * @param {string} b The other multiplicand.
- * @return {string}
- */
-o3djs.effect.o3d.mul = function(a, b) {
- return 'mul(' + a + ', ' + b + ')';
-};
-
-
-/**
- * Generates code for some utility functions
- * (functions defined in cg but not glsl).
- * @return {string} The code for the utility functions.
- */
-o3djs.effect.glsl.utilityFunctions = function() {
- return 'vec4 lit(float l ,float h, float m) {\n' +
- ' return vec4(1.0,\n' +
- ' max(l, 0.0),\n' +
- ' (l > 0.0) ? pow(max(0.0, h), m) : 0.0,\n' +
- ' 1.0);\n' +
- '}\n';
-};
-
-
-/**
- * Generates code for some utility functions
- * (functions defined in cg but not glsl).
- * @return {string} The code for the utility functions.
- */
-o3djs.effect.o3d.utilityFunctions = function() {
- return '';
-}
-
-
-/**
- * The string that starts the vertex shader main function.
- * @return {string} The effect code for the start of the main.
- */
-o3djs.effect.glsl.beginVertexShaderMain = function() {
- return 'void main() {\n';
-};
-
-/**
- * The string that starts the vertex shader main function.
- * @return {string} The effect code for the start of the main.
- */
-o3djs.effect.o3d.beginVertexShaderMain = function() {
- return 'OutVertex vertexShaderFunction(InVertex input) {\n' +
- ' OutVertex output;\n';
-};
-
-/**
- * The string that ends the vertex main function.
- * @return {string}
- */
-o3djs.effect.glsl.endVertexShaderMain = function() {
- return ' gl_Position = ' + o3djs.effect.VERTEX_VARYING_PREFIX +
- 'position;\n}\n';
-};
-
-/**
- * The string that ends the vertex main function.
- * @return {string}
- */
-o3djs.effect.o3d.endVertexShaderMain = function() {
- return ' return output;\n}\n';
-};
-
-
-/**
- * The string that goes infront of the pixel shader main.
- * @param {!o3d.Material} material The material to inspect.
- * @param {boolean} diffuse Whether to include stuff for diffuse calculations.
- * @param {boolean} specular Whether to include stuff for diffuse
- * calculations.
- * @param {boolean} bumpSampler Whether there is a bump sampler.
- * @return {string} The header.
- */
-o3djs.effect.glsl.pixelShaderHeader =
- function(material, diffuse, specular, bumpSampler) {
- return '\n// #o3d SplitMarker\n';
-};
-
-
-/**
- * The string that goes infront of the pixel shader main.
- * @param {!o3d.Material} material The material to inspect.
- * @param {boolean} diffuse Whether to include stuff for diffuse calculations.
- * @param {boolean} specular Whether to include stuff for diffuse
- * calculations.
- * @param {boolean} bumpSampler Whether there is a bump sampler.
- * @return {string} The header.
- */
-o3djs.effect.o3d.pixelShaderHeader =
- function(material, diffuse, specular, bumpSampler) {
- return '';
-};
-
-
-/**
- * Repeats the declarations for the varying parameters if necessary.
- * @param {string} opt_decls The declarations if you know them already.
- * @return {string} Code for the parameter declarations.
- */
-o3djs.effect.glsl.repeatVaryingDecls = function(opt_decls) {
- return (opt_decls ||
- o3djs.effect.varying_decls_ ||
- o3djs.buildVaryingDecls()) +
- '\n';
-};
-
-/**
- * Repeats the declarations for the varying parameters if necessary.
- * @param {string} opt_decls The declarations if you know them already.
- * @return {string} Code for the parameter declarations.
- */
-o3djs.effect.o3d.repeatVaryingDecls = function(opt_decls) {
- return '';
-};
-
-
-/**
- * The string that goes infront of the pixel shader main.
- * @return {string} The effect code for the start of the main.
- */
-o3djs.effect.glsl.beginPixelShaderMain = function() {
- return 'void main() {\n';
-};
-
-
-/**
- * The string that goes infront of the pixel shader main.
- * @return {string} The effect code for the start of the main.
- */
-o3djs.effect.o3d.beginPixelShaderMain = function() {
- return 'float4 pixelShaderFunction(OutVertex input) : COLOR {\n';
-};
-
-
-/**
- * The string that goes at the end of the pixel shader main.
- * @param {string} color The code for the color to return.
- * @return {string} The effect code for the end of the main.
- */
-o3djs.effect.o3d.endPixelShaderMain = function(color) {
- return ' return ' + color + ';\n}\n';
-};
-
-
-/**
- * The string that goes at the end of the pixel shader main.
- * @param {string} color The code for the color to return.
- * @return {string} The effect code for the end of the main.
- */
-o3djs.effect.glsl.endPixelShaderMain = function(color) {
- return ' gl_FragColor = ' + color + ';\n}\n';
-};
-
-
-/**
- * The vertex and fragment shader entry point in the format that
- * o3d parses.
- * @return {string}
- */
-o3djs.effect.o3d.entryPoints = function() {
- return '// #o3d VertexShaderEntryPoint vertexShaderFunction\n' +
- '// #o3d PixelShaderEntryPoint pixelShaderFunction\n';
-};
-
-
-/**
- * The vertex and fragment shader entry points. In glsl, this is unnecessary.
- * @return {string}
- */
-o3djs.effect.glsl.entryPoints = function() {
- return '';
-};
-
-o3djs.effect.glsl.matrixLoadOrder =
-o3djs.effect.o3d.matrixLoadOrder = function() {
- return '// #o3d MatrixLoadOrder RowMajor\n';
-};
-
-
-/**
- * Sets the shader language used. Passing 'glsl' will cause all generated
- * shader code to be in glsl. Passing anything else will result in the
- * default o3d hlsl/cg based shader language.
- * @param {string} language Shader language to use.
- */
-o3djs.effect.setLanguage = function(language) {
- var language_namespace = o3djs.effect.o3d;
- if (language == 'glsl') {
- language_namespace = o3djs.effect.glsl;
- }
- for (var f in o3djs.effect.glsl) {
- o3djs.effect[f] = language_namespace[f];
- }
-
- o3djs.effect.TWO_COLOR_CHECKER_FXSTRING =
- o3djs.effect.buildCheckerShaderString();
-};
-
-/**
- * Gets the language set in the function setLanguage. Returns a string, either
- * 'glsl' or 'o3d'.
- */
-o3djs.effect.getLanguage = function() {
- var language_namespace = o3djs.effect.o3d;
- if (language_namespace == o3djs.effect.glsl) {
- return 'glsl';
- }
- return 'o3d';
-};
-
-
-/**
- * Builds the vertex attribute declarations for a given material.
- * @param {!o3d.Material} material The material to inspect.
- * @param {boolean} diffuse Whether to include stuff for diffuse calculations.
- * @param {boolean} specular Whether to include stuff for diffuse
- * calculations.
- * @param {boolean} bumpSampler Whether there is a bump sampler.
- * @param {boolean} skinning Whether this mesh has a skin.
- * @return {string} The code for the declarations.
- */
-o3djs.effect.buildAttributeDecls =
- function(material, diffuse, specular, bumpSampler, skinning) {
- var str = o3djs.effect.BEGIN_IN_STRUCT +
- o3djs.effect.ATTRIBUTE + o3djs.effect.FLOAT4 + ' ' + 'position' +
- o3djs.effect.semanticSuffix('POSITION') + ';\n';
- if (diffuse || specular) {
- str += o3djs.effect.ATTRIBUTE + o3djs.effect.FLOAT3 + ' ' + 'normal' +
- o3djs.effect.semanticSuffix('NORMAL') + ';\n';
- }
- if (skinning) {
- str += o3djs.effect.ATTRIBUTE + o3djs.effect.FLOAT4 + ' influenceWeights' +
- o3djs.effect.semanticSuffix('BLENDWEIGHT') + ';\n';
- str += o3djs.effect.ATTRIBUTE + o3djs.effect.FLOAT4 + ' influenceIndices' +
- o3djs.effect.semanticSuffix('BLENDINDICES') + ';\n';
- }
- str += o3djs.effect.buildTexCoords(material, false) +
- o3djs.effect.buildBumpInputCoords(bumpSampler) +
- o3djs.effect.END_STRUCT;
- return str;
-};
-
-
-/**
- * Caches the varying parameter declarations to be repeated in the case that
- * we're in glsl and need to declare the varying parameters in both shaders.
- * @type {string}
- */
-o3djs.effect.varying_decls_ = '';
-
-
-/**
- * Builds the varying parameter declarations for a given material.
- * @param {!o3d.Material} material The material to inspect.
- * @param {boolean} diffuse Whether to include stuff for diffuse calculations.
- * @param {boolean} specular Whether to include stuff for diffuse
- * calculations.
- * @param {boolean} bumpSampler Whether there is a bump sampler.
- * @return {string} The code for the declarations.
- */
-o3djs.effect.buildVaryingDecls =
- function(material, diffuse, specular, bumpSampler) {
- var p = o3djs.effect;
- var str = p.BEGIN_OUT_STRUCT +
- p.VARYING + p.FLOAT4 + ' ' +
- p.VARYING_DECLARATION_PREFIX + 'position' +
- p.semanticSuffix('POSITION') + ';\n' +
- p.buildTexCoords(material, true) +
- p.buildBumpOutputCoords(bumpSampler);
- if (diffuse || specular) {
- str += p.VARYING + p.FLOAT3 + ' ' +
- p.VARYING_DECLARATION_PREFIX + 'normal' +
- p.semanticSuffix('TEXCOORD' +
- p.interpolant_++ + '') + ';\n' +
- p.VARYING + p.FLOAT3 + ' ' +
- p.VARYING_DECLARATION_PREFIX + 'surfacePosition' +
- p.semanticSuffix(
- 'TEXCOORD' + p.interpolant_++ + '') + ';\n';
- }
- if (specular) {
- str += p.VARYING + p.FLOAT3 + ' ' +
- p.VARYING_DECLARATION_PREFIX + 'surfaceToView' +
- p.semanticSuffix(
- 'TEXCOORD' + p.interpolant_++ + '') + ';\n';
- }
- str += p.END_STRUCT;
- p.varying_decls_ = str;
- return str;
-};
-
-
-/**
- * An integer value which keeps track of the next available interpolant.
- * @type {number}
- * @private
- */
-o3djs.effect.interpolant_ = 0;
-
-/**
- * Builds the texture coordinate declaration for a given color input
- * (usually emissive, ambient, diffuse or specular). If the color
- * input does not have a sampler, no TEXCOORD declaration is built.
- * @param {!o3d.Material} material The material to inspect.
- * @param {boolean} varying Whether these vertex declarations should
- * be written as varying values.
- * @param {string} name The name of the color input.
- * @return {string} The code for the texture coordinate declaration.
- */
-o3djs.effect.buildTexCoord = function(material, varying, name) {
- var p = o3djs.effect;
- // In the GLSL version we need to name the incoming attributes by
- // the semantic name in order for them to get hooked up correctly.
- if (material.getParam(name + 'Sampler')) {
- if (varying) {
- return ' ' + p.VARYING + p.FLOAT2 + ' ' +
- p.VARYING_DECLARATION_PREFIX + name + 'UV' +
- p.semanticSuffix(
- 'TEXCOORD' + p.interpolant_++ + '') + ';\n';
- } else {
- var desiredName = name + 'UV';
- var semantic = 'TEXCOORD' + p.interpolant_++;
- var outputName = p.getAttributeName_(desiredName, semantic);
- if (p.semanticNameMap) {
- p.nameToSemanticMap_[desiredName] = semantic;
- }
- return ' ' + p.ATTRIBUTE + p.FLOAT2 + ' ' + outputName +
- p.semanticSuffix(semantic) + ';\n';
- }
- } else {
- return '';
- }
-};
-
-/**
- * Builds all the texture coordinate declarations for a vertex attribute
- * declaration.
- * @param {!o3d.Material} material The material to inspect.
- * @param {boolean} varying Whether these vertex declarations should
- * be written as varying values.
- * @return {string} The code for the texture coordinate declarations.
- */
-o3djs.effect.buildTexCoords = function(material, varying) {
- var p = o3djs.effect;
- p.interpolant_ = 0;
- if (!varying) {
- p.nameToSemanticMap_ = {};
- }
- return p.buildTexCoord(material, varying, 'emissive') +
- p.buildTexCoord(material, varying, 'ambient') +
- p.buildTexCoord(material, varying, 'diffuse') +
- p.buildTexCoord(material, varying, 'specular');
-};
-
-
-/**
- * Builds the texture coordinate passthrough statement for a given
- * color input (usually emissive, ambient, diffuse or specular). These
- * assigments are used in the vertex shader to pass the texcoords to be
- * interpolated to the rasterizer. If the color input does not have
- * a sampler, no code is generated.
- * @param {!o3d.Material} material The material to inspect.
- * @param {string} name The name of the color input.
- * @return {string} The code for the texture coordinate passthrough statement.
- */
-o3djs.effect.buildUVPassthrough = function(material, name) {
- var p = o3djs.effect;
- if (material.getParam(name + 'Sampler')) {
- var sourceName = name + 'UV';
- var destName = sourceName;
- var semantic = p.nameToSemanticMap_[sourceName];
- if (semantic) {
- sourceName = p.getAttributeName_(sourceName, semantic);
- }
- return ' ' + p.VERTEX_VARYING_PREFIX + destName + ' = ' +
- p.ATTRIBUTE_PREFIX + sourceName + ';\n';
- } else {
- return '';
- }
-};
-
-
-/**
- * Builds all the texture coordinate passthrough statements for the
- * vertex shader.
- * @param {!o3d.Material} material The material to inspect.
- * @return {string} The code for the texture coordinate passthrough
- * statements.
- */
-o3djs.effect.buildUVPassthroughs = function(material) {
- var p = o3djs.effect;
- // TODO(petersont): in the GLSL implementation we need to generate
- // the code for these attributes before we can pass their values
- // through, because in this implementation their names must be their
- // semantics (i.e., "texCoord4") rather than these chosen names.
- // Currently bumpUV is the only one which does not obey this rule.
- return p.buildUVPassthrough(material, 'emissive') +
- p.buildUVPassthrough(material, 'ambient') +
- p.buildUVPassthrough(material, 'diffuse') +
- p.buildUVPassthrough(material, 'specular') +
- p.buildUVPassthrough(material, 'bump');
-};
-
-
-/**
- * Builds bump input coords if needed.
- * @param {boolean} bumpSampler Whether there is a bump sampler.
- * @return {string} The code for bump input coords.
- */
-o3djs.effect.buildBumpInputCoords = function(bumpSampler) {
- var p = o3djs.effect;
- return bumpSampler ?
- (' ' + p.FLOAT3 + ' tangent' +
- p.semanticSuffix('TANGENT') + ';\n' +
- ' ' + p.FLOAT3 + ' binormal' +
- p.semanticSuffix('BINORMAL') + ';\n' +
- ' ' + p.FLOAT2 + ' bumpUV' +
- p.semanticSuffix(
- 'TEXCOORD' + p.interpolant_++) + ';\n') : '';
-};
-
-
-/**
- * Builds bump output coords if needed.
- * @param {boolean} bumpSampler Whether there is a bump sampler.
- * @return {string} The code for bump input coords.
- */
-o3djs.effect.buildBumpOutputCoords = function(bumpSampler) {
- var p = o3djs.effect;
- return bumpSampler ?
- (' ' + p.FLOAT3 + ' tangent' +
- p.semanticSuffix(
- 'TEXCOORD' + p.interpolant_++) + ';\n' +
- ' ' + p.FLOAT3 + ' binormal' +
- p.semanticSuffix('TEXCOORD' +
- p.interpolant_++) + ';\n' +
- ' ' + p.FLOAT2 + ' bumpUV' +
- p.semanticSuffix(
- 'TEXCOORD' + p.interpolant_++) + ';\n') : '';
-};
-
-
-/**
- * Builds vertex and fragment shader string for a 2-color checker effect.
- * @return {string} The effect code for the shader, ready to be parsed.
- */
-o3djs.effect.buildCheckerShaderString = function() {
- var p = o3djs.effect;
- var varyingDecls = p.BEGIN_OUT_STRUCT +
- p.VARYING + p.FLOAT4 + ' ' +
- p.VARYING_DECLARATION_PREFIX + 'position' +
- p.semanticSuffix('POSITION') + ';\n' +
- p.VARYING + p.FLOAT2 + ' ' +
- p.VARYING_DECLARATION_PREFIX + 'texCoord' +
- p.semanticSuffix('TEXCOORD0') + ';\n' +
- p.VARYING + p.FLOAT3 + ' ' +
- p.VARYING_DECLARATION_PREFIX + 'normal' +
- p.semanticSuffix('TEXCOORD1') + ';\n' +
- p.VARYING + p.FLOAT3 + ' ' +
- p.VARYING_DECLARATION_PREFIX + 'worldPosition' +
- p.semanticSuffix('TEXCOORD2') + ';\n' +
- p.END_STRUCT;
-
- return 'uniform ' + p.MATRIX4 + ' worldViewProjection' +
- p.semanticSuffix('WORLDVIEWPROJECTION') + ';\n' +
- 'uniform ' + p.MATRIX4 + ' worldInverseTranspose' +
- p.semanticSuffix('WORLDINVERSETRANSPOSE') + ';\n' +
- 'uniform ' + p.MATRIX4 + ' world' +
- p.semanticSuffix('WORLD') + ';\n' +
- '\n' +
- p.BEGIN_IN_STRUCT +
- p.ATTRIBUTE + p.FLOAT4 + ' position' +
- p.semanticSuffix('POSITION') + ';\n' +
- p.ATTRIBUTE + p.FLOAT3 + ' normal' +
- p.semanticSuffix('NORMAL') + ';\n' +
- p.ATTRIBUTE + p.FLOAT2 + ' texCoord0' +
- p.semanticSuffix('TEXCOORD0') + ';\n' +
- p.END_STRUCT +
- '\n' +
- varyingDecls +
- '\n' +
- p.beginVertexShaderMain() +
- ' ' + p.VERTEX_VARYING_PREFIX + 'position = ' +
- p.mul(p.ATTRIBUTE_PREFIX + 'position',
- 'worldViewProjection') + ';\n' +
- ' ' + p.VERTEX_VARYING_PREFIX + 'normal = ' +
- p.mul(p.FLOAT4 + '(' +
- p.ATTRIBUTE_PREFIX + 'normal, 0.0)',
- 'worldInverseTranspose') + '.xyz;\n' +
- ' ' + p.VERTEX_VARYING_PREFIX + 'worldPosition = ' +
- p.mul(p.ATTRIBUTE_PREFIX + 'position', 'world') +
- '.xyz;\n' +
- ' ' + p.VERTEX_VARYING_PREFIX + 'texCoord = ' +
- p.ATTRIBUTE_PREFIX + 'texCoord0;\n' +
- p.endVertexShaderMain() +
- '\n' +
- p.pixelShaderHeader() +
- 'uniform ' + p.FLOAT4 + ' color1;\n' +
- 'uniform ' + p.FLOAT4 + ' color2;\n' +
- 'uniform float checkSize;\n' +
- 'uniform ' + p.FLOAT3 + ' lightWorldPos;\n' +
- 'uniform ' + p.FLOAT3 + ' lightColor;\n' +
- '\n' +
- p.repeatVaryingDecls(varyingDecls) +
- p.FLOAT4 + ' checker(' + p.FLOAT2 + ' uv) {\n' +
- ' float fmodResult = ' + p.MOD + '(' +
- ' floor(checkSize * uv.x) + \n' +
- ' floor(checkSize * uv.y), 2.0);\n' +
- ' return (fmodResult < 1.0) ? color1 : color2;\n' +
- '}\n\n' +
- p.beginPixelShaderMain() +
- ' ' + p.FLOAT3 + ' surfaceToLight = \n' +
- ' normalize(lightWorldPos - ' +
- p.PIXEL_VARYING_PREFIX + 'worldPosition);\n' +
- ' ' + p.FLOAT3 + ' worldNormal = normalize(' +
- p.PIXEL_VARYING_PREFIX + 'normal);\n' +
- ' ' + p.FLOAT4 + ' check = checker(' +
- p.PIXEL_VARYING_PREFIX + 'texCoord);\n' +
- ' float directionalIntensity = \n' +
- ' clamp(dot(worldNormal, surfaceToLight), 0.0, 1.0);\n' +
- ' ' + p.FLOAT4 +
- ' outColor = directionalIntensity * check;\n' +
- p.endPixelShaderMain(
- p.FLOAT4 + '(outColor.rgb, check.a)') +
- '\n' +
- p.entryPoints() +
- p.matrixLoadOrder();
-};
-
-
-
-/**
- * The name of the parameter on a material if it's a collada standard
- * material.
- *
- * NOTE: This parameter is just a string attached to a material. It has no
- * meaning to the plugin, it is passed from the conditioner to the
- * javascript libraries so that they can build collada like effects.
- *
- * @type {string}
- */
-o3djs.effect.COLLADA_LIGHTING_TYPE_PARAM_NAME = 'collada.lightingType';
-
-/**
- * The collada standard lighting types.
- * @type {!Object}
- */
-o3djs.effect.COLLADA_LIGHTING_TYPES = {phong: 1,
- lambert: 1,
- blinn: 1,
- constant: 1};
-
-/**
- * The FCollada standard materials sampler parameter name prefixes.
- * @type {!Array.<string>}
- */
-o3djs.effect.COLLADA_SAMPLER_PARAMETER_PREFIXES = ['emissive',
- 'ambient',
- 'diffuse',
- 'specular',
- 'bump'];
-
-/**
- * Check if lighting type is a collada lighting type.
- * @param {string} lightingType Lighting type to check.
- * @return {boolean} true if it's a collada lighting type.
- */
-o3djs.effect.isColladaLightingType = function(lightingType) {
- return o3djs.effect.COLLADA_LIGHTING_TYPES[lightingType.toLowerCase()] == 1;
-};
-
-/**
- * Returns the collada lighting type of a collada standard material.
- * @param {!o3d.Material} material Material to get lighting type from.
- * @return {string} The lighting type or "" if it's not a collada standard
- * material.
- */
-o3djs.effect.getColladaLightingType = function(material) {
- var lightingTypeParam = material.getParam(
- o3djs.effect.COLLADA_LIGHTING_TYPE_PARAM_NAME);
- if (lightingTypeParam) {
- var lightingType = lightingTypeParam.value.toLowerCase();
- if (o3djs.effect.isColladaLightingType(lightingType)) {
- return lightingType;
- }
- }
- return '';
-};
-
-/**
- * Get the number of TEXCOORD streams needed by this material.
- * @param {!o3d.Material} material The material MUST be a standard
- * collada material.
- * @return {number} The number oc TEXCOORD streams needed.
- */
-o3djs.effect.getNumTexCoordStreamsNeeded = function(material) {
- var p = o3djs.effect;
- var lightingType = p.getColladaLightingType(material);
- if (!p.isColladaLightingType(lightingType)) {
- throw 'not a collada standard material';
- }
- var colladaSamplers = p.COLLADA_SAMPLER_PARAMETER_PREFIXES;
- var numTexCoordStreamsNeeded = 0
- for (var cc = 0; cc < colladaSamplers.length; ++cc) {
- var samplerPrefix = colladaSamplers[cc];
- var samplerParam = material.getParam(samplerPrefix + 'Sampler');
- if (samplerParam) {
- ++numTexCoordStreamsNeeded;
- }
- }
- return numTexCoordStreamsNeeded;
-};
-
-/**
- * Loads shader source from an external file and creates shaders for an effect.
- * @param {!o3d.Effect} effect The effect to create the shaders in.
- * @param {string} url The url of the shader source.
- */
-o3djs.effect.loadEffect = function(effect, url) {
- var fxString = o3djs.io.loadTextFileSynchronous(url);
- effect.loadFromFXString(fxString);
-};
-
-/**
- * Creates an effect from a file.
- * If the effect already exists in the pack that effect will be returned.
- * @param {!o3d.Pack} pack Pack to create effect in.
- * @param {string} url Url for effect file.
- * @return {!o3d.Effect} The effect.
- */
-o3djs.effect.createEffectFromFile = function(pack, url) {
- var p = o3djs.effect;
- var effect = pack.getObjects(url, 'o3d.Effect')[0];
- if (!effect) {
- effect = pack.createObject('Effect');
- p.loadEffect(effect, url);
- effect.name = url;
- }
- return effect;
-};
-
-/**
- * Builds a shader string for a given standard COLLADA material type.
- *
- * @param {!o3d.Material} material Material for which to build the shader.
- * @param {string} effectType Type of effect to create ('phong', 'lambert',
- * 'constant', 'blinn').
- * @param {Object} opt_options Parameters to customize shader code generation.
- See o3djs.effect.getStandardShader for details on the possible values.
- * @return {{description: string, shader: string}} A description and the shader
- * string.
- */
-o3djs.effect.buildStandardShaderString = function(material,
- effectType,
- opt_options) {
- if (!opt_options) {
- opt_options = {};
- }
- var numLights = 0;
- var currentLightWorldPos = 'lightWorldPos';
- if (opt_options.lights) {
- numLights = opt_options.lights;
- currentLightWorldPos = 'lightWorldPosList[i]';
- }
- var p = o3djs.effect;
- var bumpSampler = material.getParam('bumpSampler');
- var bumpUVInterpolant;
- var skinning;
-
- var maxSkinInfluences = 4;
-
- // Hardcode reasonable maximum for number of skinning uniforms.
- // glsl: Table 6.19: minimum MAX_VERTEX_UNIFORM_VECTORS is 128.
- // (DX9 requires a minimum of 256, so not a problem in o3d).
- var maxSkinUniforms = 36 * 3;
- if (o3djs.base.o3d && o3djs.base.o3d.SkinEval &&
- o3djs.base.o3d.SkinEval.getMaxNumBones) {
- maxSkinUniforms = o3d.SkinEval.getMaxNumBones(material) * 3;
- skinning = true;
- } else {
- skinning = false;
- }
-
- /**
- * Extracts the texture type from a texture param.
- * @param {!o3d.ParamTexture} textureParam The texture parameter to
- * inspect.
- * @return {string} The texture type (1D, 2D, 3D or CUBE).
- */
- var getTextureType = function(textureParam) {
- var texture = textureParam.value;
- if (!texture) return '2D'; // No texture value, have to make a guess.
- switch (texture.className) {
- case 'o3d.Texture1D' : return '1D';
- case 'o3d.Texture2D' : return '2D';
- case 'o3d.Texture3D' : return '3D';
- case 'o3d.TextureCUBE' : return 'CUBE';
- default : return '2D';
- }
- }
-
- /**
- * Extracts the sampler type from a sampler param. It does it by inspecting
- * the texture associated with the sampler.
- * @param {!o3d.ParamTexture} samplerParam The texture parameter to
- * inspect.
- * @return {string} The texture type (1D, 2D, 3D or CUBE).
- */
- var getSamplerType = function(samplerParam) {
- var sampler = samplerParam.value;
- if (!sampler) return '2D';
- var textureParam = sampler.getParam('Texture');
- if (textureParam)
- return getTextureType(textureParam);
- else
- return '2D';
- };
-
- /**
- * Builds uniform variables common to all standard lighting types.
- * @return {string} The effect code for the common shader uniforms.
- */
- var buildCommonVertexUniforms = function() {
- //var size = numLights ? '['+numLights+']' : '';
- return 'uniform ' + p.MATRIX4 + ' worldViewProjection' +
- p.semanticSuffix('WORLDVIEWPROJECTION') + ';\n';
- };
-
- /**
- * Builds uniform variables common to all standard lighting types.
- * @return {string} The effect code for the common shader uniforms.
- */
- var buildCommonPixelUniforms = function() {
- if (numLights > 0) {
- return 'uniform ' + p.FLOAT4 + ' lightColorList[' + numLights + '];\n' +
- 'uniform ' + p.FLOAT3 + ' lightWorldPosList[' + numLights + '];\n';
- } else {
- return 'uniform ' + p.FLOAT4 + ' lightColor;\n' +
- 'uniform ' + p.FLOAT3 + ' lightWorldPos' + ';\n';
- }
- };
-
- /**
- * Builds uniform variables common to lambert, phong and blinn lighting types.
- * @return {string} The effect code for the common shader uniforms.
- */
- var buildLightingUniforms = function() {
- return 'uniform ' + p.MATRIX4 + ' world' +
- p.semanticSuffix('WORLD') + ';\n' +
- 'uniform ' + p.MATRIX4 +
- ' viewInverse' + p.semanticSuffix('VIEWINVERSE') + ';\n' +
- 'uniform ' + p.MATRIX4 + ' worldInverseTranspose' +
- p.semanticSuffix('WORLDINVERSETRANSPOSE') + ';\n';
- };
-
- /**
- * If skinning is enabled, builds the bone matrix uniform variables needed
- * for skinning. Otherwise, returns the empty string.
- * @return {string} The effect code for skinning uniforms.
- */
- var buildSkinningUniforms = function() {
- return skinning ? 'uniform ' + p.FLOAT4 + ' boneToWorld3x4' +
- '[' + maxSkinUniforms + '];\n' +
- 'uniform float usingSkinShader;\n' : '';
- };
-
- /**
- * Builds uniform parameters for a given color input. If the material
- * has a sampler parameter, a sampler uniform is created, otherwise a
- * float4 color value is created.
- * @param {!o3d.Material} material The material to inspect.
- * @param {!Array.<string>} descriptions Array to add descriptions too.
- * @param {string} name The name of the parameter to look for. Usually
- * emissive, ambient, diffuse or specular.
- * @param {boolean} opt_addColorParam Whether to add a color param if no
- * sampler exists. Default = true.
- * @return {string} The effect code for the uniform parameter.
- */
- var buildColorParam = function(material, descriptions, name,
- opt_addColorParam) {
- if (opt_addColorParam === undefined) {
- opt_addColorParam = true;
- }
- var samplerParam = material.getParam(name + 'Sampler');
- if (samplerParam) {
- var type = getSamplerType(samplerParam);
- descriptions.push(name + type + 'Texture');
- return 'uniform sampler' + type + ' ' + name + 'Sampler;\n'
- } else if (opt_addColorParam) {
- descriptions.push(name + 'Color');
- return 'uniform ' + p.FLOAT4 + ' ' + name + ';\n';
- } else {
- return '';
- }
- };
-
- /**
- * Builds the effect code to retrieve a given color input. If the material
- * has a sampler parameter of that name, a texture lookup is done. Otherwise
- * it's a no-op, since the value is retrieved directly from the color uniform
- * of that name.
- * @param {!o3d.Material} material The material to inspect.
- * @param {string} name The name of the parameter to look for. Usually
- * emissive, ambient, diffuse or specular.
- * @return {string} The effect code for the uniform parameter retrieval.
- */
- var getColorParam = function(material, name) {
- var samplerParam = material.getParam(name + 'Sampler');
- if (samplerParam) {
- var type = getSamplerType(samplerParam);
- return ' ' + p.FLOAT4 + ' ' + name + ' = ' + p.TEXTURE + type +
- '(' + name + 'Sampler, ' +
- p.PIXEL_VARYING_PREFIX + name + 'UV);\n'
- } else {
- return '';
- }
- };
-
- /**
- * Begins a section of code which is to be run once for each light.
- * @return {string} The effect code for the for loop, or the empty string if
- * not using multiple lights.
- */
- var beginLightLoop = function() {
- if (numLights) {
- return ' ' + p.FLOAT4 + ' lightColorDiffuse = ' + p.FLOAT4 + '(0);\n' +
- ' for (int i = 0; i < ' + numLights + '; i++) {\n';
- } else {
- return '';
- }
- };
-
- /**
- * Ends the block of code which is to be run for each light. Adds the current
- * light's color times (diffuseExpression) into lightColorDiffuse.
- * @param {string} diffuseExpression Expression to multiply by light color.
- * @return {string} The effect code to set lightColorDiffuse.
- */
- var endLightLoop = function(diffuseExpression) {
- if (numLights) {
- return ' lightColorDiffuse += ' +
- 'lightColorList[i] * ( ' + diffuseExpression + ');\n' +
- ' }\n';
- } else {
- return ' ' + p.FLOAT4 + ' lightColorDiffuse = ' +
- 'lightColor * (' + diffuseExpression + ');';
- }
- };
-
- /**
- * Builds vertex and fragment shader string for the Constant lighting type.
- * @param {!o3d.Material} material The material for which to build
- * shaders.
- * @param {!Array.<string>} descriptions Array to add descriptions too.
- * @return {string} The effect code for the shader, ready to be parsed.
- */
- var buildConstantShaderString = function(material, descriptions) {
- descriptions.push('constant');
- return buildCommonVertexUniforms() +
- buildSkinningUniforms() +
- buildVertexDecls(material, false, false) +
- p.beginVertexShaderMain() +
- positionVertexShaderCode() +
- p.buildUVPassthroughs(material) +
- p.endVertexShaderMain() +
- p.pixelShaderHeader(material, false, false, bumpSampler) +
- buildCommonPixelUniforms() +
- p.repeatVaryingDecls() +
- buildColorParam(material, descriptions, 'emissive') +
- p.beginPixelShaderMain() +
- getColorParam(material, 'emissive') +
- p.endPixelShaderMain('emissive') +
- p.entryPoints() +
- p.matrixLoadOrder();
- };
-
- /**
- * Builds vertex and fragment shader string for the Lambert lighting type.
- * @param {!o3d.Material} material The material for which to build
- * shaders.
- * @param {!Array.<string>} descriptions Array to add descriptions too.
- * @return {string} The effect code for the shader, ready to be parsed.
- */
- var buildLambertShaderString = function(material, descriptions) {
- descriptions.push('lambert');
- return buildCommonVertexUniforms() +
- buildLightingUniforms() +
- buildSkinningUniforms() +
- buildVertexDecls(material, true, false) +
- p.beginVertexShaderMain() +
- p.buildUVPassthroughs(material) +
- positionVertexShaderCode() +
- normalVertexShaderCode() +
- surfacePositionVertexShaderCode() +
- bumpVertexShaderCode() +
- p.endVertexShaderMain() +
- p.pixelShaderHeader(material, true, false) +
- buildCommonPixelUniforms() +
- p.repeatVaryingDecls() +
- buildColorParam(material, descriptions, 'emissive') +
- buildColorParam(material, descriptions, 'ambient') +
- buildColorParam(material, descriptions, 'diffuse') +
- buildColorParam(material, descriptions, 'bump', false) +
- p.utilityFunctions() +
- p.beginPixelShaderMain() +
- getColorParam(material, 'emissive') +
- getColorParam(material, 'ambient') +
- getColorParam(material, 'diffuse') +
- getNormalShaderCode() +
- beginLightLoop() +
- ' ' + p.FLOAT3 + ' surfaceToLight = normalize(' +
- currentLightWorldPos + ' - ' +
- p.PIXEL_VARYING_PREFIX + 'surfacePosition);\n' +
- ' ' + p.FLOAT4 +
- ' litR = lit(dot(normal, surfaceToLight), 0.0, 0.0);\n' +
- endLightLoop('ambient * diffuse + diffuse * litR.y') +
- p.endPixelShaderMain(p.FLOAT4 +
- '((emissive +\n' +
- ' lightColorDiffuse).rgb,\n' +
- ' diffuse.a)') +
- p.entryPoints() +
- p.matrixLoadOrder();
- };
-
- /**
- * Builds vertex and fragment shader string for the Blinn lighting type.
- * @param {!o3d.Material} material The material for which to build
- * shaders.
- * @param {!Array.<string>} descriptions Array to add descriptions too.
- * @return {string} The effect code for the shader, ready to be parsed.
- * TODO: This is actually just a copy of the Phong code.
- * Change to Blinn.
- */
- var buildBlinnShaderString = function(material, descriptions) {
- descriptions.push('phong');
- return buildCommonVertexUniforms() +
- buildLightingUniforms() +
- buildSkinningUniforms() +
- buildVertexDecls(material, true, true) +
- p.beginVertexShaderMain() +
- p.buildUVPassthroughs(material) +
- positionVertexShaderCode() +
- normalVertexShaderCode() +
- surfacePositionVertexShaderCode() +
- surfaceToViewVertexShaderCode() +
- bumpVertexShaderCode() +
- p.endVertexShaderMain() +
- p.pixelShaderHeader(material, true, true) +
- buildCommonPixelUniforms() +
- p.repeatVaryingDecls() +
- buildColorParam(material, descriptions, 'emissive') +
- buildColorParam(material, descriptions, 'ambient') +
- buildColorParam(material, descriptions, 'diffuse') +
- buildColorParam(material, descriptions, 'specular') +
- buildColorParam(material, descriptions, 'bump', false) +
- 'uniform float shininess;\n' +
- 'uniform float specularFactor;\n' +
- p.utilityFunctions() +
- p.beginPixelShaderMain() +
- getColorParam(material, 'emissive') +
- getColorParam(material, 'ambient') +
- getColorParam(material, 'diffuse') +
- getColorParam(material, 'specular') +
- getNormalShaderCode() +
- ' ' + p.FLOAT3 + ' surfaceToView = normalize(' +
- p.PIXEL_VARYING_PREFIX + 'surfaceToView);\n' +
- beginLightLoop() +
- ' ' + p.FLOAT3 + ' surfaceToLight = normalize(' +
- currentLightWorldPos + ' - ' +
- p.PIXEL_VARYING_PREFIX + 'surfacePosition);\n' +
- ' ' + p.FLOAT3 +
- ' halfVector = normalize(surfaceToLight + surfaceToView);\n' +
- ' ' + p.FLOAT4 +
- ' litR = lit(dot(normal, surfaceToLight), \n' +
- ' dot(normal, halfVector), shininess);\n' +
- endLightLoop('ambient * diffuse + diffuse * litR.y\n' +
- ' + specular * litR.z * specularFactor') +
- p.endPixelShaderMain( p.FLOAT4 +
- '((emissive + lightColorDiffuse).rgb,\n' +
- ' diffuse.a)') +
- p.entryPoints() +
- p.matrixLoadOrder();
- };
-
- /**
- * Builds vertex and fragment shader string for the Phong lighting type.
- * @param {!o3d.Material} material The material for which to build
- * shaders.
- * @param {!Array.<string>} descriptions Array to add descriptions too.
- * @return {string} The effect code for the shader, ready to be parsed.
- */
- var buildPhongShaderString = function(material, descriptions) {
- descriptions.push('phong');
- return buildCommonVertexUniforms() +
- buildLightingUniforms() +
- buildSkinningUniforms() +
- buildVertexDecls(material, true, true) +
- p.beginVertexShaderMain() +
- p.buildUVPassthroughs(material) +
- positionVertexShaderCode() +
- normalVertexShaderCode() +
- surfacePositionVertexShaderCode() +
- surfaceToViewVertexShaderCode() +
- bumpVertexShaderCode() +
- p.endVertexShaderMain() +
- p.pixelShaderHeader(material, true, true) +
- buildCommonPixelUniforms() +
- p.repeatVaryingDecls() +
- buildColorParam(material, descriptions, 'emissive') +
- buildColorParam(material, descriptions, 'ambient') +
- buildColorParam(material, descriptions, 'diffuse') +
- buildColorParam(material, descriptions, 'specular') +
- buildColorParam(material, descriptions, 'bump', false) +
- 'uniform float shininess;\n' +
- 'uniform float specularFactor;\n' +
- p.utilityFunctions() +
- p.beginPixelShaderMain() +
- getColorParam(material, 'emissive') +
- getColorParam(material, 'ambient') +
- getColorParam(material, 'diffuse') +
- getColorParam(material, 'specular') +
- getNormalShaderCode() +
- ' ' + p.FLOAT3 + ' surfaceToView = normalize(' +
- p.PIXEL_VARYING_PREFIX + 'surfaceToView);\n' +
- beginLightLoop() +
- ' ' + p.FLOAT3 + ' surfaceToLight = normalize(' +
- currentLightWorldPos + ' - ' +
- p.PIXEL_VARYING_PREFIX + 'surfacePosition);\n' +
- ' ' + p.FLOAT3 +
- ' halfVector = normalize(surfaceToLight + surfaceToView);\n' +
- ' ' + p.FLOAT4 +
- ' litR = lit(dot(normal, surfaceToLight), \n' +
- ' dot(normal, halfVector), shininess);\n' +
- endLightLoop('ambient * diffuse + diffuse * litR.y +\n' +
- ' + specular * litR.z * specularFactor') +
- p.endPixelShaderMain(p.FLOAT4 +
- '((emissive + lightColorDiffuse).rgb,\n' +
- ' diffuse.a)') +
- p.entryPoints() +
- p.matrixLoadOrder();
- };
-
- /**
- * Builds the position code for the vertex shader.
- * @return {string} The code for the vertex shader.
- */
- var positionVertexShaderCode = function() {
- var attribute_position = p.ATTRIBUTE_PREFIX + 'position';
- if (skinning) {
- return ' ' + p.FLOAT4 + ' weightedpos = ' + attribute_position + ';\n' +
- ' for (int i = 0; i < ' + maxSkinInfluences + '; i++) {\n' +
- ' ' + p.FLOAT4 + ' temp = ' + p.FLOAT4 + '(' +
- 'dot(boneToWorld3x4[int(influenceIndices[i] * 3.0)], ' +
- attribute_position + '),\n' +
- ' dot(boneToWorld3x4[int(influenceIndices[i] * 3.0 + 1.0)], ' +
- attribute_position + '),\n' +
- ' dot(boneToWorld3x4[int(influenceIndices[i] * 3.0 + 2.0)], ' +
- attribute_position + '),\n' +
- ' 1.0);\n' +
- ' weightedpos += usingSkinShader * influenceWeights[i] * ' +
- '(temp - ' + attribute_position + ');\n' +
- ' }\n' +
- ' ' + p.VERTEX_VARYING_PREFIX + 'position = ' +
- p.mul('weightedpos', 'worldViewProjection') + ';\n';
- } else {
- return ' ' + p.VERTEX_VARYING_PREFIX + 'position = ' +
- p.mul(attribute_position, 'worldViewProjection') + ';\n';
- }
- };
-
- /**
- * Builds the normal code for the vertex shader.
- * @return {string} The code for the vertex shader.
- */
- var normalVertexShaderCode = function() {
- var attribute_normal = p.ATTRIBUTE_PREFIX + 'normal';
- if (skinning) {
- return ' ' + p.FLOAT3 + ' weightednorm = ' + attribute_normal + ';\n' +
- ' for (int i = 0; i < ' + maxSkinInfluences + '; i++) {\n' +
- ' ' + p.FLOAT3 + ' temp = ' + p.FLOAT3 + '(' +
- 'dot(boneToWorld3x4[int(influenceIndices[i] * 3.0)].xyz, ' +
- attribute_normal + '),\n' +
- ' dot(boneToWorld3x4[int(influenceIndices[i] * 3.0 + 1.0)].xyz, ' +
- attribute_normal + '),\n' +
- ' dot(boneToWorld3x4[int(influenceIndices[i] * 3.0 + 2.0)].xyz, ' +
- attribute_normal + '));\n' +
- ' weightednorm += usingSkinShader * influenceWeights[i] * ' +
- '(temp - ' + attribute_normal + ');\n' +
- ' }\n' +
- ' ' + p.VERTEX_VARYING_PREFIX + 'normal = ' +
- p.mul(p.FLOAT4 + '(' + 'weightednorm' + ', 0)',
- 'worldInverseTranspose') + '.xyz;\n';
- } else {
- return ' ' + p.VERTEX_VARYING_PREFIX + 'normal = ' +
- p.mul(p.FLOAT4 + '(' +
- attribute_normal + ', 0)', 'worldInverseTranspose') +
- '.xyz;\n';
- }
- };
-
- /**
- * Builds the surface position code for the vertex shader. To support
- * multiple lights, the dot product with each light should then be
- * computed in the fragment shader.
- * @return {string} The code for the vertex shader.
- */
- var surfacePositionVertexShaderCode = function() {
- return ' ' + p.VERTEX_VARYING_PREFIX +
- 'surfacePosition = \n' +
- p.mul(p.ATTRIBUTE_PREFIX + 'position',
- 'world') + '.xyz;\n';
- };
-
- /**
- * Builds the surface to view code for the vertex shader.
- * @return {string} The code for the vertex shader.
- */
- var surfaceToViewVertexShaderCode = function() {
- return ' ' + p.VERTEX_VARYING_PREFIX +
- 'surfaceToView = (viewInverse[3] - ' +
- p.mul(p.ATTRIBUTE_PREFIX + 'position', 'world') + ').xyz;\n';
- };
-
- /**
- * Builds the normal map part of the vertex shader.
- * @param {boolean} opt_bumpSampler Whether there is a bump
- * sampler. Default = false.
- * @return {string} The code for normal mapping in the vertex shader.
- */
- var bumpVertexShaderCode = function(opt_bumpSampler) {
- return bumpSampler ?
- (' ' + p.VERTEX_VARYING_PREFIX + 'binormal = ' +
- p.mul(p.FLOAT4 + '(' +
- p.ATTRIBUTE_PREFIX + 'binormal, 0)',
- 'worldInverseTranspose') + '.xyz;\n' +
- ' ' + p.VERTEX_VARYING_PREFIX + 'tangent = ' +
- p.mul(p.FLOAT4 +
- '(' + p.ATTRIBUTE_PREFIX + 'tangent, 0)',
- 'worldInverseTranspose') + '.xyz;\n') : '';
- };
-
- /**
- * Builds the normal calculation of the pixel shader.
- * @return {string} The code for normal computation in the pixel shader.
- */
- var getNormalShaderCode = function() {
- return bumpSampler ?
- (p.MATRIX3 + ' tangentToWorld = ' + p.MATRIX3 +
- '(' + p.ATTRIBUTE_PREFIX + 'tangent,\n' +
- ' ' +
- p.ATTRIBUTE_PREFIX + 'binormal,\n' +
- ' ' +
- p.ATTRIBUTE_PREFIX + 'normal);\n' +
- p.FLOAT3 + ' tangentNormal = ' + p.TEXTURE + '2D' + '(bumpSampler, ' +
- p.ATTRIBUTE_PREFIX + 'bumpUV.xy).xyz -\n' +
- ' ' + p.FLOAT3 +
- '(0.5, 0.5, 0.5);\n' + p.FLOAT3 + ' normal = ' +
- p.mul('tangentNormal', 'tangentToWorld') + ';\n' +
- 'normal = normalize(' + p.PIXEL_VARYING_PREFIX +
- 'normal);\n') : ' ' + p.FLOAT3 + ' normal = normalize(' +
- p.PIXEL_VARYING_PREFIX + 'normal);\n';
- };
-
- /**
- * Builds the vertex declarations for a given material.
- * @param {!o3d.Material} material The material to inspect.
- * @param {boolean} diffuse Whether to include stuff for diffuse
- * calculations.
- * @param {boolean} specular Whether to include stuff for diffuse
- * calculations.
- * @return {string} The code for the vertex declarations.
- */
- var buildVertexDecls = function(material, diffuse, specular) {
- return p.buildAttributeDecls(
- material, diffuse, specular, bumpSampler, skinning) +
- p.buildVaryingDecls(
- material, diffuse, specular, bumpSampler);
- };
-
-
- // Create a shader string of the appropriate type, based on the
- // effectType.
- var str;
- var descriptions = [];
- if (effectType == 'phong') {
- str = buildPhongShaderString(material, descriptions);
- } else if (effectType == 'lambert') {
- str = buildLambertShaderString(material, descriptions);
- } else if (effectType == 'blinn') {
- str = buildBlinnShaderString(material, descriptions);
- } else if (effectType == 'constant') {
- str = buildConstantShaderString(material, descriptions);
- } else {
- throw ('unknown effect type "' + effectType + '"');
- }
-
- return {description: descriptions.join('_'), shader: str};
-};
-
-/**
- * Gets or builds a shader for given standard COLLADA material type.
- *
- * Looks at the material passed in and assigns it an Effect that matches its
- * Params. If a suitable Effect already exists in pack it will use that Effect.
- *
- * @param {!o3d.Pack} pack Pack in which to create the new Effect.
- * @param {!o3d.Material} material Material for which to build the shader.
- * @param {string} effectType Type of effect to create ('phong', 'lambert',
- * 'constant', 'blinn').
- * @param {Object} opt_options Extra options in the form {lights: number}.
- * If 'lights' is non-zero, creates an array of light params; otherwise
- * only a single light is supported.
- * @return {o3d.Effect} The created effect.
- */
-o3djs.effect.getStandardShader = function(pack,
- material,
- effectType,
- opt_options) {
- var record = o3djs.effect.buildStandardShaderString(material,
- effectType,
- opt_options);
- var effects = pack.getObjectsByClassName('o3d.Effect');
- for (var ii = 0; ii < effects.length; ++ii) {
- if (effects[ii].name == record.description &&
- effects[ii].source == record.shader) {
- return effects[ii];
- }
- }
- var effect = pack.createObject('Effect');
- if (effect) {
- effect.name = record.description;
- if (effect.loadFromFXString(record.shader)) {
- return effect;
- }
- pack.removeObject(effect);
- }
- return null;
-};
-
-/**
- * Attaches a shader for a given standard COLLADA material type to the
- * material.
- *
- * Looks at the material passed in and assigns it an Effect that matches its
- * Params. If a suitable Effect already exists in pack it will use that Effect.
- *
- * @param {!o3d.Pack} pack Pack in which to create the new Effect.
- * @param {!o3d.Material} material Material for which to build the shader.
- * @param {!o3djs.math.Vector3} lightPos Position of the default light.
- * @param {string} effectType Type of effect to create ('phong', 'lambert',
- * 'constant', 'blinn').
- * @param {Object} opt_options Extra options for effect.getStandardShader
- * @return {boolean} True on success.
- */
-o3djs.effect.attachStandardShader = function(pack,
- material,
- lightPos,
- effectType,
- opt_options) {
- var effect = o3djs.effect.getStandardShader(pack,
- material,
- effectType,
- opt_options);
- if (effect) {
- material.effect = effect;
- effect.createUniformParameters(material);
-
- // Set a couple of the default parameters in the hopes that this will
- // help the user get something on the screen. We check to make sure they
- // are not connected to something otherwise we'll get an error.
- var param = material.getParam('lightWorldPos');
- if (param && !param.inputConnection) {
- param.value = lightPos;
- }
- var param = material.getParam('lightColor');
- if (param && !param.inputConnection) {
- param.value = [1, 1, 1, 1];
- }
- return true;
- } else {
- return false;
- }
-};
-
-/**
- * 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;
- }
- }
- }
-};
-
-/**
- * Creates an effect that draws a 2 color procedural checker pattern.
- * @param {!o3d.Pack} pack The pack to create the effect in. If the pack
- * already has an effect with the same name that effect will be returned.
- * @return {!o3d.Effect} The effect.
- */
-o3djs.effect.createCheckerEffect = function(pack) {
- var effects = pack.getObjects(o3djs.effect.TWO_COLOR_CHECKER_EFFECT_NAME,
- 'o3d.Effect');
- if (effects.length > 0) {
- return effects[0];
- }
-
- var effect = pack.createObject('Effect');
- effect.loadFromFXString(o3djs.effect.TWO_COLOR_CHECKER_FXSTRING);
- effect.name = o3djs.effect.TWO_COLOR_CHECKER_EFFECT_NAME;
- return effect;
-};
-
-
-// For compatability with o3d code, the default language is o3d shading
-// language.
-o3djs.effect.setLanguage('o3d');
-
-
diff --git a/o3d/samples/o3djs/element.js b/o3d/samples/o3djs/element.js
deleted file mode 100644
index 0c4593b..0000000
--- a/o3d/samples/o3djs/element.js
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains various functions for helping setup
- * elements for o3d
- */
-
-o3djs.provide('o3djs.element');
-
-o3djs.require('o3djs.math');
-
-/**
- * A Module for element functions.
- * @namespace
- */
-o3djs.element = o3djs.element || {};
-
-/**
- * Sets the bounding box and z sort point of an element.
- * @param {!o3d.Element} element Element to set bounding box and z sort point
- * on.
- */
-o3djs.element.setBoundingBoxAndZSortPoint = function(element) {
- var boundingBox = element.getBoundingBox(0);
- var minExtent = boundingBox.minExtent;
- var maxExtent = boundingBox.maxExtent;
- element.boundingBox = boundingBox;
- element.cull = true;
- element.zSortPoint = o3djs.math.divVectorScalar(
- o3djs.math.addVector(minExtent, maxExtent), 2);
-};
-
-/**
- * Adds missing texture coordinate streams to a primitive.
- *
- * This is very application specific but if it's a primitive
- * and if it uses a collada material the material builder
- * assumes 1 TEXCOORD stream per texture. In other words if you have
- * both a specular texture AND a diffuse texture the builder assumes
- * you have 2 TEXCOORD streams. This assumption is often false.
- *
- * To work around this we check how many streams the material
- * expects and if there are not enough UVs streams we duplicate the
- * last TEXCOORD stream until there are, making a BIG assumption that
- * that will work.
- *
- * The problem is maybe you have 4 textures and each of them share
- * texture coordinates. There is information in the collada file about
- * what stream to connect each texture to.
- *
- * @param {!o3d.Element} element Element to add streams to.
- */
-o3djs.element.addMissingTexCoordStreams = function(element) {
- // TODO: We should store that info. The conditioner should either
- // make streams that way or pass on the info so we can do it here.
- if (element.isAClassName('o3d.Primitive')) {
- var material = /** @type {!o3d.Material} */ (element.material);
- var streamBank = element.streamBank;
- var lightingType = o3djs.effect.getColladaLightingType(material);
- if (lightingType) {
- var numTexCoordStreamsNeeded =
- o3djs.effect.getNumTexCoordStreamsNeeded(material);
- // Count the number of TEXCOORD streams the streamBank has.
- var streams = streamBank.vertexStreams;
- var lastTexCoordStream = null;
- var numTexCoordStreams = 0;
- for (var ii = 0; ii < streams.length; ++ii) {
- var stream = streams[ii];
- if (stream.semantic == o3djs.base.o3d.Stream.TEXCOORD) {
- lastTexCoordStream = stream;
- ++numTexCoordStreams;
- }
- }
- // Add any missing TEXCOORD streams. It might be more efficient for
- // the GPU to create an effect that doesn't need the extra streams
- // but this is a more generic solution because it means we can reuse
- // the same effect.
- for (var ii = numTexCoordStreams;
- ii < numTexCoordStreamsNeeded;
- ++ii) {
- streamBank.setVertexStream(
- lastTexCoordStream.semantic,
- lastTexCoordStream.semanticIndex + ii - numTexCoordStreams + 1,
- lastTexCoordStream.field,
- lastTexCoordStream.startIndex);
- }
- }
- }
-};
-
-/**
- * Copies an element and streambank or buffers so the two will share
- * streambanks, vertex and index buffers.
- * @param {!o3d.Pack} pack Pack to manage created objects.
- * @param {!o3d.Element} sourceElement The element to copy.
- * @return {!o3d.Element} the new copy of sourceElement.
- */
-o3djs.element.duplicateElement = function(pack, sourceElement) {
- var newElement = pack.createObject(sourceElement.className);
- newElement.copyParams(sourceElement);
- // TODO: If we get the chance to parameterize the primitive's settings
- // we can delete this code since copyParams will handle it.
- // For now it only handles primitives by doing it manually.
- if (sourceElement.isAClassName('o3d.Primitive')) {
- newElement.indexBuffer = sourceElement.indexBuffer;
- newElement.startIndex = sourceElement.startIndex;
- newElement.primitiveType = sourceElement.primitiveType;
- newElement.numberVertices = sourceElement.numberVertices;
- newElement.numberPrimitives = sourceElement.numberPrimitives;
- }
- return newElement;
-};
-
-/**
- * Gets the normal for specific triangle in a Primitive in that Primitive's
- * local space.
- *
- * NOTE: THIS FUNCTION IS SLOW! If you want to do collisions you should use a
- * different solution.
- *
- * @param {!o3d.Primitive} primitive Primitive to get normal from. The
- * primitive MUST be a TRIANGLELIST or a TRIANGLESTRIP and it must have a
- * POSITION,0 stream.
- * @param {number} index Index of triangle.
- * @param {boolean} opt_winding The winding of the triangles of the
- * Primitive. False = Clockwise, True = Counterclockwise. The default is
- * false. This is only used for Primitives that have no normals.
- * @return {!o3djs.math.Vector3} The normal for the triangle.
- */
-o3djs.element.getNormalForTriangle = function(primitive, index, opt_winding) {
- // Check that we can do this
- var primitiveType = primitive.primitiveType;
- if (primitiveType != o3djs.base.o3d.Primitive.TRIANGLELIST &&
- primitiveType != o3djs.base.o3d.Primitive.TRIANGLESTRIP) {
- throw 'primitive is not a TRIANGLELIST or TRIANGLESTRIP';
- }
-
- var indexBuffer = primitive.indexBuffer;
- var vertexIndex = (primitiveType == o3djs.base.o3d.Primitive.TRIANGLELIST) ?
- (index * 3) : (index + 2);
- var vertexIndices;
- if (indexBuffer) {
- var indexField = indexBuffer.fields[0];
- vertexIndices = indexField.getAt(vertexIndex, 3);
- } else {
- vertexIndices = [vertexIndex, vertexIndex + 1, vertexIndex + 2]
- }
-
- var normalStream = primitive.streamBank.getVertexStream(
- o3djs.base.o3d.Stream.NORMAL, 0);
- if (normalStream) {
- var normalField = normalStream.field;
- // Look up the 3 normals that make the triangle.
- var summedNormal = [0, 0, 0];
- for (var ii = 0; ii < 3; ++ii) {
- var normal = normalField.getAt(vertexIndices[ii], 1);
- summedNormal = o3djs.math.addVector(summedNormal, normal);
- }
- return o3djs.math.normalize(summedNormal);
- } else {
- var positionStream = primitive.streamBank.getVertexStream(
- o3djs.base.o3d.Stream.POSITION, 0);
- if (!positionStream) {
- throw 'no POSITION,0 stream in primitive';
- }
- var positionField = positionStream.field;
- // Lookup the 3 positions that make the triangle.
- var positions = [];
- for (var ii = 0; ii < 3; ++ii) {
- positions[ii] = positionField.getAt(vertexIndices[ii], 1);
- }
-
- // Compute a face normal from the positions.
- var v0 = o3djs.math.normalize(o3djs.math.subVector(positions[1],
- positions[0]));
- var v1 = o3djs.math.normalize(o3djs.math.subVector(positions[2],
- positions[1]));
- return opt_winding ? o3djs.math.cross(v1, v0) : o3djs.math.cross(v0, v1);
- }
-};
-
-
diff --git a/o3d/samples/o3djs/error.js b/o3d/samples/o3djs/error.js
deleted file mode 100644
index 8fa16ad..0000000
--- a/o3d/samples/o3djs/error.js
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains various error handing functions for o3d.
- *
- */
-
-o3djs.provide('o3djs.error');
-
-/**
- * A Module with various error handing functions.
- *
- * This module is for helping to manage the client's error callback.
- * Because you can not read the current callback on the client we wrap it with
- * these utilities which track the last callback added so as long as you use
- * o3djs.error.setErrorHandler(client, callback) instead of
- * client.setErrorCallback you'll be able to get and restore the error callback
- * when you need to.
- * @namespace
- */
-o3djs.error = o3djs.error || {};
-
-/**
- * A map of error callbacks by client.
- * @private
- * @type {!Array.<(function(string): void|null)>}
- */
-o3djs.error.callbacks_ = [];
-
-/**
- * Sets the error handler on a client to a handler that manages the client's
- * error callback.
- * displays an alert on the first error.
- * @param {!o3d.Client} client The client object of the plugin.
- * @param {(function(string): void|null)} callback The callack to use, null to
- * clear.
- * @return {(function(string): void|null)} the previous error callback for this
- * client.
- */
-o3djs.error.setErrorHandler = function(client, callback) {
- var clientId = client.clientId;
- var old_callback = o3djs.error.callbacks_[clientId];
- o3djs.error.callbacks_[clientId] = callback;
- if (callback) {
- client.setErrorCallback(callback);
- } else {
- client.clearErrorCallback();
- }
- return old_callback;
-};
-
-/**
- * Sets a default error handler on the client.
- * The default error handler displays an alert on the first error encountered.
- * @param {!o3d.Client} client The client object of the plugin.
- */
-o3djs.error.setDefaultErrorHandler = function(client) {
- o3djs.error.setErrorHandler(
- client,
- function(msg) {
- // Clear the error callback. Otherwise if the callback is happening
- // during rendering it's possible the user will not be able to
- // get out of an infinite loop of alerts.
- o3djs.error.setErrorHandler(client, null);
- alert('ERROR: ' + msg);
- });
-};
-
-/**
- * Creates an ErrorCollector.
- * @param {!o3d.Client} client The client object of the plugin.
- * @return {!o3djs.error.ErrorCollector} The created error collector.
- */
-o3djs.error.createErrorCollector = function(client) {
- return new o3djs.error.ErrorCollector(client);
-};
-
-/**
- * An ErrorCollector takes over the client error callback and continues
- * to collect errors until ErrorCollector.finish() is called.
- * @constructor
- * @param {!o3d.Client} client The client object of the plugin.
- */
-o3djs.error.ErrorCollector = function(client) {
- var that = this;
- this.client_ = client;
- /**
- * The collected errors.
- * @type {!Array.<string>}
- */
- this.errors = [];
- this.oldCallback_ = o3djs.error.setErrorHandler(client, function(msg) {
- that.errors.push(msg);
- });
-};
-
-/**
- * Stops the ErrorCollector from collecting errors and restores the previous
- * error callback.
- */
-o3djs.error.ErrorCollector.prototype.finish = function() {
- o3djs.error.setErrorHandler(this.client_, this.oldCallback_);
-};
diff --git a/o3d/samples/o3djs/event.js b/o3d/samples/o3djs/event.js
deleted file mode 100644
index 333aa0c..0000000
--- a/o3d/samples/o3djs/event.js
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains various event related functions for
- * o3d. It puts them in the 'event' module on the o3djs object.
- *
- * TODO Add selenium tests.
- *
- *
- */
-o3djs.provide('o3djs.event');
-
-/**
- * A Module for handling events related to o3d and various browsers.
- * @namespace
- */
-o3djs.event = o3djs.event || {};
-
-/**
- * @param {string} inStr base string.
- * @param {string} extraStr string to append.
- * @return {string} inStr + ' ' + extraStr, or just inStr if extraStr is ''.
- */
-o3djs.event.appendWithSpace = function(inStr, extraStr) {
- return (inStr.length == 0) ? extraStr : inStr + ' ' + extraStr;
-};
-
-/**
- * @param {boolean} state whether to append or not.
- * @param {string} inStr base string.
- * @param {string} extraStr string to append.
- * @return {string} inStr + ' ' + extraStr, or just inStr if state is false.
- */
-o3djs.event.appendWithSpaceIf = function(state, inStr, extraStr) {
- return (state) ? o3djs.event.appendWithSpace(inStr, extraStr) : inStr;
-};
-
-
-/**
- * Builds a DOM-level 3 modifier string for a KeyboardEvent - see
- * http://www.w3.org/TR/DOM-Level-3-Events/events.html
- * #Events-KeyboardEvents-Interfaces.
- * @param {boolean} control whether the control key is down.
- * @param {boolean} alt whether the alt/option key is down.
- * @param {boolean} shift whether the shift key is down.
- * @param {boolean} meta whether the meta/command key is down.
- * @return {string} space delimited list of keys that are down.
- */
-o3djs.event.getModifierString = function(control, alt, shift, meta) {
- var modStr = o3djs.event.appendWithSpaceIf(control, '', 'Control');
- modStr = o3djs.event.appendWithSpaceIf(alt, modStr, 'Alt');
- modStr = o3djs.event.appendWithSpaceIf(shift, modStr, 'Shift');
- return o3djs.event.appendWithSpaceIf(meta, modStr, 'Meta');
-};
-
-
-/**
- * Pad a string with leading zeroes if needed until it is the length desired.
- * @param {string} str The input string, probably representing a number.
- * @param {number} to_length The desired minimum length of string with padding.
- * @return {string} A string padded with leading zeroes as needed to be the
- * length desired.
- */
-o3djs.event.padWithLeadingZeroes = function(str, to_length) {
- while (str.length < to_length)
- str = '0' + str;
- return str;
-};
-
-/**
- * Creates a keyIdentifer string for a given keystroke as specified in the w3c
- * spec on http://www.w3.org/TR/DOM-Level-3-Events/events.html.
- * @param {number} charCode numeric unicode code point as reported by the OS.
- * @param {number} keyCode numeric keyCode as reported by the OS, currently
- * unused but will probably be necessary in the future.
- * @return {string} eg 'Left' or 'U+0040'.
- */
-o3djs.event.getKeyIdentifier = function(charCode, keyCode) {
- if (!charCode) {
- // TODO: This works for webkit for keydown and keyup, for basic
- // alphanumeric keys, at least. Likely it needs lots of work to handle
- // accented characters, various keyboards, etc., as does the rest of our
- // keyboard event code.
- charCode = keyCode;
- }
- switch (charCode) {
- case 3: case 13: return 'Enter'; // spec merges these.
- case 37: return 'Left';
- case 39: return 'Right';
- case 38: return 'Up';
- case 40: return 'Down';
- }
- charCode = (charCode >= 97 && charCode <= 122) ? charCode - 32 : charCode;
- var keyStr = charCode.toString(16).toUpperCase();
- return 'U+' + o3djs.event.padWithLeadingZeroes(keyStr, 4);
-};
-
-
-/** Takes a keyIdentifier string and remaps it to an ASCII/Unicode value
- * suitable for javascript event handling.
- * @param {string} keyIdent a keyIdentifier string as generated above.
- * @return {number} the numeric Unicode code point represented.
- */
-o3djs.event.keyIdentifierToChar = function(keyIdent) {
- if (keyIdent && typeof(keyIdent) == 'string') {
- switch (keyIdent) {
- case 'Enter': return 13;
- case 'Left': return 37;
- case 'Right': return 39;
- case 'Up': return 38;
- case 'Down': return 40;
- }
- if (keyIdent.indexOf('U+') == 0)
- return parseInt(keyIdent.substr(2).toUpperCase(), 16);
- }
- return 0;
-};
-
-/**
- * Extracts the key char in number form from the event, in a cross-browser
- * manner.
- * @param {!Event} event .
- * @return {number} unicode code point for the key.
- */
-o3djs.event.getEventKeyChar = function(event) {
- if (!event) {
- event = window.event;
- }
- var charCode = 0;
- if (event.keyIdentifier)
- charCode = o3djs.event.keyIdentifierToChar(event.keyIdentifier);
- if (!charCode)
- charCode = (window.event) ? window.event.keyCode : event.charCode;
- if (!charCode)
- charCode = event.keyCode;
- return charCode;
-};
-
-
-/**
- * Cancel an event we've handled so it stops propagating upwards.
- * The cancelBubble is for IE, stopPropagation is for all other browsers.
- * preventDefault ensures that the default action is also canceled.
- * @param {!Event} event - the event to cancel.
- */
-o3djs.event.cancel = function(event) {
- if (!event)
- event = window.event;
- event.cancelBubble = true;
- if (event.stopPropagation)
- event.stopPropagation();
- if (event.preventDefault)
- event.preventDefault();
-};
-
-/**
- * Convenience function to setup synthesizing and dispatching of keyboard events
- * whenever the focussed plug-in calls Javascript to report a keyboard action.
- * @param {!Element} pluginObject the <object> where the o3d plugin lives,
- * which the caller probably obtained by calling getElementById.
- */
-o3djs.event.startKeyboardEventSynthesis = function(pluginObject) {
- var handler = function(event) {
- o3djs.event.onKey(event, pluginObject);
- };
-
- o3djs.event.addEventListener(pluginObject, 'keypress', handler);
- o3djs.event.addEventListener(pluginObject, 'keydown', handler);
- o3djs.event.addEventListener(pluginObject, 'keyup', handler);
-};
-
-/**
- * Dispatches a DOM-level 3 KeyboardEvent when called back by the plugin.
- * see http://www.w3.org/TR/DOM-Level-3-Events/events.html
- * #Events-KeyboardEvents-Interfaces
- * see http://developer.mozilla.org/en/DOM/event.initKeyEvent
- * @param {!Event} event an O3D event object.
- * @param {!Element} pluginObject the plugin object on the page.
- */
-o3djs.event.onKey = function(event, pluginObject) {
- var k_evt = o3djs.event.createKeyEvent(event.type, event.charCode,
- event.keyCode, event.ctrlKey, event.altKey, event.shiftKey,
- event.metaKey);
- if (k_evt) {
- if (pluginObject.parentNode.dispatchEvent) {
- // Using the pluginObject itself fails for non-capturing event listeners
- // on keypress events on Firefox only, as far as I've been able to
- // determine. I have no idea why.
- pluginObject.parentNode.dispatchEvent(k_evt);
- } else if (pluginObject.fireEvent) {
- pluginObject.fireEvent('on' + event.type, k_evt);
- }
- }
-};
-
-/**
- * Creates a DOM-level 3 KeyboardEvent.
- * see http://www.w3.org/TR/DOM-Level-3-Events/events.html
- * #Events-KeyboardEvents-Interfaces.
- * see http://developer.mozilla.org/en/DOM/event.initKeyEvent
- * @param {string} eventName one of 'keypress', 'keydown' or 'keyup'.
- * @param {number} charCode the character code for the key.
- * @param {number} keyCode the key code for the key.
- * @param {boolean} control whether the control key is down.
- * @param {boolean} alt whether the alt/option key is down.
- * @param {boolean} shift whether the shift key is down.
- * @param {boolean} meta whether the meta/command key is down.
- */
-o3djs.event.createKeyEvent = function(eventName, charCode, keyCode,
- control, alt, shift, meta) {
- var k_evt;
- var keyIdentifier = o3djs.event.getKeyIdentifier(charCode, keyCode);
- if (document.createEvent) {
- k_evt = document.createEvent('KeyboardEvent');
- if (k_evt.initKeyboardEvent) { // WebKit.
- k_evt.initKeyboardEvent(eventName, true, true, window,
- keyIdentifier, 0,
- control, alt, shift, meta);
- // TODO: These actually fail to do anything in Chrome; those are
- // read-only fields, and it's not setting them in initKeyboardEvent.
- k_evt.charCode = charCode;
- if (eventName == 'keypress')
- k_evt.keyCode = charCode;
- else
- k_evt.keyCode = keyCode;
- } else if (k_evt.initKeyEvent) { // FF.
- k_evt.initKeyEvent(eventName, true, true, window,
- control, alt, shift, meta, keyCode, charCode);
- k_evt.keyIdentifier = keyIdentifier;
- }
- } else if (document.createEventObject) {
- k_evt = document.createEventObject();
- k_evt.ctrlKey = control;
- k_evt.altKey = alt;
- k_evt.shiftKey = shift;
- k_evt.metaKey = meta;
- k_evt.keyCode = charCode; // Emulate IE charcode-in-the-keycode onkeypress.
- k_evt.keyIdentifier = keyIdentifier;
- }
- k_evt.synthetic = true;
- return k_evt;
-};
-
-/*
- * Function to create a closure that will call each event handler in an array
- * whenever it gets called, passing its single argument through to the
- * sub-handlers. The sub-handlers may either be functions or EventListeners.
- * This is generally expected to be used only through
- * o3djs.event.addEventListener.
- * @param {!Array.<*>} listenerSet an array of handlers.
- * @return {!function(*): void} a closure to be used to multiplex out
- * event-handling.
- */
-o3djs.event.createEventHandler = function(listenerSet) {
- return function(event) {
- var length = listenerSet.length;
- for (var index = 0; index < length; ++index) {
- var handler = listenerSet[index];
- if (typeof(handler.handleEvent) == 'function') {
- handler.handleEvent(event);
- } else {
- handler(event);
- }
- }
- }
-};
-
-/**
- * Convenience function to manage event listeners on the o3d plugin object,
- * intended as a drop-in replacement for the DOM addEventListener [with slightly
- * different arguments, but the same effect].
- * @param {!Element} pluginObject the html object where the o3d plugin lives,
- * which the caller probably obtained by calling getElementById or makeClients.
- * @param {string} type the event type on which to trigger, e.g. 'mousedown',
- * 'mousemove', etc.
- * @param {!Object} handler either a function or an EventListener object.
- */
-o3djs.event.addEventListener = function(pluginObject, type, handler) {
- if (!handler || typeof(type) != 'string' ||
- (typeof(handler) != 'function' &&
- typeof(handler.handleEvent) != 'function')) {
- throw new Error('Invalid argument.');
- }
- pluginObject.o3d_eventRegistry = pluginObject.o3d_eventRegistry || [];
- var registry = pluginObject.o3d_eventRegistry;
- var listenerSet = registry[type];
- if (!listenerSet || listenerSet.length == 0) {
- listenerSet = registry[type] = [];
- pluginObject.client.setEventCallback(type,
- o3djs.event.createEventHandler(listenerSet));
- } else {
- for (var index in listenerSet) {
- if (listenerSet[index] == handler) {
- return; // We're idempotent.
- }
- }
- }
- listenerSet.push(handler);
-};
-
-
-/**
- * Convenience function to manage event listeners on the o3d plugin object,
- * intended as a drop-in replacement for the DOM removeEventListener [with
- * slightly different arguments, but the same effect].
- * @param {!Element} pluginObject the <object> where the o3d plugin lives,
- * which the caller probably obtained by calling getElementById.
- * @param {string} type the event type on which the handler to be removed was to
- * trigger, e.g. 'mousedown', 'mousemove', etc.
- * @param {!Object} handler either a function or an EventListener object.
- */
-o3djs.event.removeEventListener = function(pluginObject, type, handler) {
- var registry = pluginObject.o3d_eventRegistry;
- if (!registry) {
- return;
- }
- var listenerSet = registry[type];
- if (!listenerSet) {
- return;
- }
- for (var index in listenerSet) {
- if (listenerSet[index] == handler) {
- if (listenerSet.length == 1) {
- pluginObject.client.clearEventCallback(type);
- }
- listenerSet.splice(index, 1);
- break;
- }
- }
-};
diff --git a/o3d/samples/o3djs/fps.js b/o3d/samples/o3djs/fps.js
deleted file mode 100644
index 51c233d..0000000
--- a/o3d/samples/o3djs/fps.js
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains a class for displaying frames per second.
- */
-
-o3djs.provide('o3djs.fps');
-
-o3djs.require('o3djs.rendergraph');
-o3djs.require('o3djs.canvas');
-o3djs.require('o3djs.effect');
-o3djs.require('o3djs.math');
-o3djs.require('o3djs.primitives');
-
-/**
- * A Module with a fps class for helping to easily display frames per second.
- * @namespace
- */
-o3djs.fps = o3djs.fps || {};
-
-/**
- * Number of frames to average over for computing FPS.
- * @type {number}
- */
-o3djs.fps.NUM_FRAMES_TO_AVERAGE = 16;
-
-/**
- * Colors used for each second of the performance bar.
- * @type {!Array.<!o3djs.math.Vector4>}
- */
-o3djs.fps.PERF_BAR_COLORS = [
- [0, 0, 1, 1],
- [0, 1, 0, 1],
- [1, 1, 0, 1],
- [1, 0.5, 0, 1],
- [1, 0, 0, 1]];
-
-/**
- * Generate a shader to be used by the pref quads.
- * @return {string}
- */
-o3djs.fps.buildShaderString = function() {
- var p = o3djs.effect;
-
- var varyingDecls = p.BEGIN_OUT_STRUCT +
- p.VARYING + p.FLOAT4 + ' ' +
- p.VARYING_DECLARATION_PREFIX + 'position' +
- p.semanticSuffix('POSITION') + ';\n' +
- p.END_STRUCT;
-
- return '' +
- 'uniform ' + p.MATRIX4 + ' worldViewProjection' +
- p.semanticSuffix('WORLDVIEWPROJECTION') + ';\n' +
- '\n' +
- p.BEGIN_IN_STRUCT +
- p.ATTRIBUTE + p.FLOAT4 + ' position' +
- p.semanticSuffix('POSITION') + ';\n' +
- p.END_STRUCT +
- '\n' +
- varyingDecls +
- '\n' +
- p.beginVertexShaderMain() +
- ' ' + p.VERTEX_VARYING_PREFIX + 'position = ' +
- p.mul(p.ATTRIBUTE_PREFIX + 'position',
- 'worldViewProjection') + ';\n' +
- p.endVertexShaderMain() +
- '\n' +
- p.pixelShaderHeader() +
- 'uniform ' + p.FLOAT4 + ' color;\n' +
- p.repeatVaryingDecls(varyingDecls) +
- p.beginPixelShaderMain() +
- p.endPixelShaderMain('color') +
- p.entryPoints() +
- p.matrixLoadOrder();
-};
-
-
-/**
- * Creates an object for displaying frames per second.
- *
- * You can use it like this.
- * <pre>
- * &lt;html&gt;&lt;body&gt;
- * &lt;script type="text/javascript" src="o3djs/base.js"&gt;
- * &lt;/script&gt;
- * &lt;script type="text/javascript"&gt;
- * o3djs.require('o3djs.util');
- * o3djs.require('o3djs.rendergraph');
- * o3djs.require('o3djs.fps');
- * window.onload = init;
- * window.onunload = uninit;
- *
- * var g_client;
- * var g_fpsManager;
- *
- * function init() {
- * o3djs.base.makeClients(initStep2);
- * }
- *
- * function initStep2(clientElements) {
- * var clientElement = clientElements[0];
- * var g_client = clientElement.client;
- * var pack = g_client.createPack();
- * var viewInfo = o3djs.rendergraph.createBasicView(
- * pack,
- * g_client.root,
- * g_client.renderGraphRoot);
- * g_fpsManager = o3djs.fps.createFPSManager(pack,
- * g_client.width,
- * g_client.height,
- * g_client.renderGraphRoot);
- * g_client.setRenderCallback(onRender);
- * }
- *
- * function onrender(renderEvent) {
- * g_fpsManager.update(renderEvent);
- * }
- *
- * function uninit() {
- * if (g_client) {
- * g_client.cleanup();
- * }
- * }
- * &lt;/script&gt;
- * &lt;div id="o3d" style="width: 600px; height: 600px"&gt;&lt;/div&gt;
- * &lt;/body&gt;&lt;/html&gt;
- * </pre>
- *
- * @param {!o3d.Pack} pack Pack to create objects in.
- * @param {number} clientWidth width of client area.
- * @param {number} clientHeight Height of client area.
- * @param {!o3d.RenderNode} opt_parent RenderNode to use as parent for
- * ViewInfo that will be used to render the FPS with.
- * @return {!o3djs.fps.FPSManager} The created FPSManager.
- */
-o3djs.fps.createFPSManager = function(pack,
- clientWidth,
- clientHeight,
- opt_parent) {
- return new o3djs.fps.FPSManager(pack, clientWidth, clientHeight, opt_parent);
-};
-
-/**
- * A class for displaying frames per second.
- * @constructor
- * @param {!o3d.Pack} pack Pack to create objects in.
- * @param {number} clientWidth width of client area.
- * @param {number} clientHeight Height of client area.
- * @param {!o3d.RenderNode} opt_parent RenderNode to use as parent for
- * ViewInfo that will be used to render the FPS with.
- */
-o3djs.fps.FPSManager = function(pack, clientWidth, clientHeight, opt_parent) {
- // total time spent for last N frames.
- this.totalTime_ = 0.0;
-
- // total active time for last N frames.
- this.totalActiveTime_ = 0.0;
-
- // elapsed time for last N frames.
- this.timeTable_ = [];
-
- // active time for last N frames.
- this.activeTimeTable_ = [];
-
- // where to record next elapsed time.
- this.timeTableCursor_ = 0;
-
- // Initialize the FPS elapsed time history table.
- for (var tt = 0; tt < o3djs.fps.NUM_FRAMES_TO_AVERAGE; ++tt) {
- this.timeTable_[tt] = 0.0;
- this.activeTimeTable_[tt] = 0.0;
- }
-
- // The root transform for this sub graph.
- this.root_ = pack.createObject('Transform');
-
- /**
- * The ViewInfo to display FPS.
- * @type {!o3djs.rendergraph.ViewInfo}
- */
- this.viewInfo = o3djs.rendergraph.createBasicView(pack,
- this.root_,
- opt_parent);
- this.viewInfo.root.priority = 100000;
- this.viewInfo.clearBuffer.clearColorFlag = false;
-
- this.viewInfo.zOrderedState.getStateParam('CullMode').value =
- o3djs.base.o3d.State.CULL_NONE;
-
- this.viewInfo.drawContext.view = o3djs.math.matrix4.lookAt(
- [0, 0, 1], // eye
- [0, 0, 0], // target
- [0, 1, 0]); // up
-
- // create a view just for the FPS. That way it's indepdendent of other views.
- this.canvasLib_ = o3djs.canvas.create(pack,
- this.root_,
- this.viewInfo);
-
- this.paint_ = pack.createObject('CanvasPaint');
-
- /**
- * The quad used to display the FPS.
- *
- */
- this.fpsQuad = this.canvasLib_.createXYQuad(0, 0, -1, 64, 32, true);
-
- // create a unit plane with a const color effect we can use to draw
- // rectangles.
- this.colorEffect_ = pack.createObject('Effect');
- this.colorEffect_.loadFromFXString(o3djs.fps.buildShaderString());
- this.colorMaterial_ = pack.createObject('Material');
- this.colorMaterial_.effect = this.colorEffect_;
- this.colorMaterial_.drawList = this.viewInfo.zOrderedDrawList;
- this.colorEffect_.createUniformParameters(this.colorMaterial_);
- this.colorMaterial_.getParam('color').value = [1, 1, 1, 1];
- this.colorQuadShape_ = o3djs.primitives.createPlane(
- pack,
- this.colorMaterial_,
- 1,
- 1,
- 1,
- 1,
- o3djs.math.makeMatrix4(1, 0, 0, 0,
- 0, 0, 1, 0,
- 0, -1, 0, 0,
- 0.5, 0.5, 0, 1));
-
- var barXOffset = 10;
- var barYOffset = 2;
- var barWidth = clientWidth - barXOffset * 2;
- var barHeight = 7;
- this.numPerfBars_ = o3djs.fps.PERF_BAR_COLORS.length - 1;
- this.perfBarRoot_ = pack.createObject('Transform');
- this.perfBarRoot_.parent = this.root_;
- this.perfBarBack_ = new o3djs.fps.ColorRect(
- pack, this.colorQuadShape_, this.perfBarRoot_,
- barXOffset, barYOffset, -3, barWidth, barHeight,
- [0, 0, 0, 1]);
- this.perfMarker_ = [];
- for (var ii = 0; ii < this.numPerfBars_; ++ii) {
- this.perfMarker_[ii] = new o3djs.fps.ColorRect(
- pack, this.colorQuadShape_, this.perfBarRoot_,
- barXOffset + barWidth / (this.numPerfBars_ + 1) * (ii + 1),
- barYOffset - 1, -1,
- 1, barHeight + 2,
- [1, 1, 1, 1]);
- }
- this.perfBar_ = new o3djs.fps.ColorRect(
- pack, this.colorQuadShape_, this.perfBarRoot_,
- barXOffset + 1, barYOffset + 1, -2, 1, barHeight - 2,
- [1, 1, 0, 1]);
- this.perfBarWidth_ = barWidth - 2;
- this.perfBarHeight_ = barHeight - 2;
- this.perfBarXOffset_ = barXOffset;
- this.perfBarYOffset_ = barYOffset;
-
- // set the size and position.
- this.resize(clientWidth, clientHeight);
- this.setPosition(10, 10);
-};
-
-/**
- * Sets the position of the FPS display
- *
- * The position is in pixels assuming the size of the client matches the size
- * last set either on creation or with FPSManager.resize.
- *
- * @param {number} x The x position.
- * @param {number} y The y position.
- */
-o3djs.fps.FPSManager.prototype.setPosition = function(x, y) {
- this.fpsQuad.transform.identity();
- this.fpsQuad.transform.translate(x, y, -1);
-};
-
-/**
- * Sets the visiblity of the fps display.
- * @param {boolean} visible true = visible.
- */
-o3djs.fps.FPSManager.prototype.setVisible = function(visible) {
- this.viewInfo.root.active = visible;
-};
-
-/**
- * Sets the visibility of the performance bar.
- * @param {boolean} visible true = visible.
- */
-o3djs.fps.FPSManager.prototype.setPerfVisible = function(visible) {
- this.perfBarRoot_.visible = visible;
-};
-
-/**
- * Resizes the area for the FPS display.
- * Note: you must call this if your client area changes size.
- * @param {number} clientWidth width of client area.
- * @param {number} clientHeight height of client area.
- */
-o3djs.fps.FPSManager.prototype.resize = function(clientWidth, clientHeight) {
- this.viewInfo.drawContext.projection = o3djs.math.matrix4.orthographic(
- 0 + 0.5,
- clientWidth + 0.5,
- clientHeight + 0.5,
- 0 + 0.5,
- 0.001,
- 1000);
-
- var barWidth = clientWidth - this.perfBarXOffset_ * 2;
- this.perfBarBack_.setSize(barWidth, this.perfBarHeight_);
- for (var ii = 0; ii < this.numPerfBars_; ++ii) {
- this.perfMarker_[ii].setPosition(
- this.perfBarXOffset_ + barWidth / (this.numPerfBars_ + 1) * (ii + 1),
- this.perfBarYOffset_ - 1);
- }
- this.perfBarWidth_ = barWidth - 2;
-};
-
-/**
- * Updates the fps display.
- * You must call this every frame to update the FPS display.
- *
- * <pre>
- * ...
- * client.setRenderCallback(onRender);
- * ...
- * function onRender(renderEvent) {
- * myFpsManager.update(renderEvent);
- * }
- * </pre>
- *
- * @param {!o3d.RenderEvent} renderEvent The object passed into the render
- * callback.
- */
-o3djs.fps.FPSManager.prototype.update = function(renderEvent) {
- var elapsedTime = renderEvent.elapsedTime;
- var activeTime = renderEvent.activeTime;
- // Keep the total time and total active time for the last N frames.
- this.totalTime_ += elapsedTime - this.timeTable_[this.timeTableCursor_];
- this.totalActiveTime_ +=
- activeTime - this.activeTimeTable_[this.timeTableCursor_];
-
- // Save off the elapsed time for this frame so we can subtract it later.
- this.timeTable_[this.timeTableCursor_] = elapsedTime;
- this.activeTimeTable_[this.timeTableCursor_] = activeTime;
-
- // Wrap the place to store the next time sample.
- ++this.timeTableCursor_;
- if (this.timeTableCursor_ == o3djs.fps.NUM_FRAMES_TO_AVERAGE) {
- this.timeTableCursor_ = 0;
- }
-
- // Print the average frame rate for the last N frames as well as the
- // instantaneous frame rate.
- var fps = '' +
- Math.floor((1.0 / (this.totalTime_ /
- o3djs.fps.NUM_FRAMES_TO_AVERAGE)) + 0.5) +
- ' : ' + Math.floor(1.0 / elapsedTime + 0.5);
-
- var canvas = this.fpsQuad.canvas;
- canvas.clear([0, 0, 0, 0]);
-
- var paint = this.paint_;
-
- canvas.saveMatrix();
- paint.setOutline(3, [0, 0, 0, 1]);
- paint.textAlign = o3djs.base.o3d.CanvasPaint.LEFT;
- paint.textSize = 12;
- paint.textTypeface = 'Arial';
- paint.color = [1, 1, 0, 1];
- canvas.drawText(fps, 2, 16, paint);
- canvas.restoreMatrix();
-
- this.fpsQuad.updateTexture();
-
- var frames = this.totalActiveTime_ / o3djs.fps.NUM_FRAMES_TO_AVERAGE /
- (1 / 60.0);
- var colorIndex = Math.min(frames, o3djs.fps.PERF_BAR_COLORS.length - 1);
- colorIndex = Math.floor(Math.max(colorIndex, 0));
-
- if (!isNaN(colorIndex)) {
- this.perfBar_.setColor(o3djs.fps.PERF_BAR_COLORS[colorIndex]);
- this.perfBar_.setSize(frames * this.perfBarWidth_ / this.numPerfBars_,
- this.perfBarHeight_);
- }
-};
-
-/**
- * A Class the manages a color rect.
- * @constructor
- * @param {!o3d.Pack} pack Pack to create things in.
- * @param {!o3d.Shape} shape Shape to use for rectangle.
- * @param {!o3d.Transform} parent Transform to parent rect under.
- * @param {number} x initial x position.
- * @param {number} y initial y position.
- * @param {number} z initial z position.
- * @param {number} width initial width.
- * @param {number} height initial height.
- * @param {!o3djs.math.Vector4} color initial color.
- */
-o3djs.fps.ColorRect = function(pack, shape, parent,
- x, y, z, width, height, color) {
- this.transform_ = pack.createObject('Transform');
- this.colorParam_ = this.transform_.createParam('color', 'ParamFloat4');
- this.transform_.addShape(shape);
- this.transform_.parent = parent;
- this.width_ = 0;
- this.height_ = 0;
- this.x_ = 0;
- this.y_ = 0;
- this.z_ = z;
- this.setPosition(x, y);
- this.setSize(width, height);
- this.setColor(color);
-};
-
-/**
- * Updates the transform of this ColorRect
- * @private
- */
-o3djs.fps.ColorRect.prototype.updateTransform_ = function() {
- this.transform_.identity();
- this.transform_.translate(this.x_, this.y_, this.z_);
- this.transform_.scale(this.width_, this.height_, 1);
-};
-
-/**
- * Sets the position of this ColorRect.
- * @param {number} x x position.
- * @param {number} y y position.
- */
-o3djs.fps.ColorRect.prototype.setPosition = function(x, y) {
- this.x_ = x;
- this.y_ = y;
- this.updateTransform_();
-};
-
-/**
- * Sets the size of this ColorRect
- * @param {number} width width.
- * @param {number} height height.
- */
-o3djs.fps.ColorRect.prototype.setSize = function(width, height) {
- this.width_ = width;
- this.height_ = height;
- this.updateTransform_();
-};
-
-/**
- * Sets the color of this ColorRect.
- * @param {!o3djs.math.Vector4} color initial color.
- */
-o3djs.fps.ColorRect.prototype.setColor = function(color) {
- this.colorParam_.value = color;
-};
-
-
diff --git a/o3d/samples/o3djs/gpu2d.js b/o3d/samples/o3djs/gpu2d.js
deleted file mode 100644
index e4c65f9..0000000
--- a/o3d/samples/o3djs/gpu2d.js
+++ /dev/null
@@ -1,800 +0,0 @@
-/*
- * 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.
- */
-
-
-/**
- * @fileoverview This file provides GPU-accelerated rendering of 2D
- * vector graphics in 3D.
- */
-o3djs.provide('o3djs.gpu2d');
-
-o3djs.require('o3djs.base');
-
-/**
- * A module providing GPU-accelerated rendering of 2D vector graphics
- * in 3D.
- * @namespace
- */
-o3djs.gpu2d = o3djs.gpu2d || {};
-
-/**
- * Creates a new Path, which holds one or more closed contours
- * composed of 2D primitives like lines, quadratic curves, and cubic
- * curves.
- * @param {!o3d.Pack} pack Pack in which geometry and materials
- * associated with the curves will be created.
- * @param {!o3d.DrawList} drawList The DrawList on which the triangle
- * mesh will be drawn. Typically this will be the
- * zOrderedDrawList from an o3djs.rendergraph.ViewInfo.
- * @return {!o3djs.gpu2d.Path} The created Path.
- */
-o3djs.gpu2d.createPath = function(pack,
- drawList) {
- return new o3djs.gpu2d.Path(pack, drawList);
-};
-
-/**
- * Constructs a new Path. Do not call this directly; use
- * o3djs.gpu2d.createPath instead.
- * @param {!o3d.Pack} pack Pack in which geometry and materials
- * associated with the curves will be created.
- * @param {!o3d.DrawList} drawList The DrawList on which the triangle
- * mesh will be drawn. Typically this will be the
- * zOrderedDrawList.
- * @constructor
- */
-o3djs.gpu2d.Path = function(pack, drawList) {
- /**
- * Pack in which curves' geometry and materials are created.
- * @type {!o3d.Pack}
- * @private
- */
- this.pack_ = pack;
-
- /**
- * DrawList in which curves' geometry and materials will be
- * rendered.
- * @type {!o3d.DrawList}
- * @private
- */
- this.drawList_ = drawList;
-
- /**
- * Internal object which manages the triangle mesh associated with
- * the curves.
- * @type {!o3d.ProcessedPath}
- * @private
- */
- this.path_ = pack.createObject('ProcessedPath');
-
- // Set up the Primitives in the ProcessedPath.
- //
- // The mesh is separated into two different regions. The exterior
- // region of the mesh is the portion containing the cubic curve
- // segments. It is this region whose alpha value is computed using
- // Loop and Blinn's shader. The interior region of the mesh is
- // simply filled with a constant alpha. The reason for the split is
- // that it is difficult to assign texture coordinates to cause Loop
- // and Blinn's shader to fill a region with constant alpha. While
- // there is some cost associated with switching shaders and
- // performing two draw calls, doing so simplifies the logic.
-
- // Create state objects so we can turn on alpha blending for the
- // exterior triangles. We also disable backface culling so that we
- // can view the vector shapes from both sides.
- var exteriorState = pack.createObject('State');
- exteriorState.getStateParam('o3d.AlphaBlendEnable').value = true;
- exteriorState.getStateParam('o3d.SourceBlendFunction').value =
- o3djs.base.o3d.State.BLENDFUNC_SOURCE_ALPHA;
- exteriorState.getStateParam('o3d.DestinationBlendFunction').value =
- o3djs.base.o3d.State.BLENDFUNC_INVERSE_SOURCE_ALPHA;
- exteriorState.getStateParam('o3d.CullMode').value =
- o3djs.base.o3d.State.CULL_NONE;
-
- var interiorState = pack.createObject('State');
- interiorState.getStateParam('o3d.CullMode').value =
- o3djs.base.o3d.State.CULL_NONE;
-
- // Create the materials for the exterior and interior regions.
-
- /**
- * The material for the exterior triangles, filled with Loop and
- * Blinn's shader.
- * @type {!o3d.Material}
- * @private
- */
- this.exteriorMaterial_ = pack.createObject('Material');
- this.exteriorMaterial_.name = 'ExteriorMaterial';
- this.exteriorMaterial_.state = exteriorState;
- this.exteriorMaterial_.drawList = drawList;
-
- /**
- * The material for the interior triangles, filled with a solid
- * shader.
- * @type {!o3d.Material}
- * @private
- */
- this.interiorMaterial_ = pack.createObject('Material');
- this.interiorMaterial_.name = 'InteriorMaterial';
- this.interiorMaterial_.state = interiorState;
- this.interiorMaterial_.drawList = drawList;
-
- /**
- * The Shape which is the transform graph's view of the Path.
- * @type {!o3d.Shape}
- */
- this.shape = pack.createObject('Shape');
-
- // Create the exterior region.
- var primitive = pack.createObject('Primitive');
- var streamBank = pack.createObject('StreamBank');
- var vertexBuffer = pack.createObject('VertexBuffer');
- // The coordinates of the triangles are 2D
- var vertices = vertexBuffer.createField('FloatField', 2);
- /**
- * The Field for the exterior vertices.
- * @type {!o3d.FloatField}
- * @private
- */
- this.exteriorVertices_ = vertices;
- // The (Loop/Blinn) texture coordinates are 3D
- var texcoords = vertexBuffer.createField('FloatField', 3);
- /**
- * The Field for the exterior texture coordinates.
- * @type {!o3d.FloatField}
- * @private
- */
- this.exteriorTexCoords_ = texcoords;
- streamBank.setVertexStream(o3djs.base.o3d.Stream.POSITION, 0, vertices, 0);
- streamBank.setVertexStream(o3djs.base.o3d.Stream.TEXCOORD, 0, texcoords, 0);
- primitive.streamBank = streamBank;
- primitive.primitiveType = o3djs.base.o3d.Primitive.TRIANGLELIST;
- primitive.material = this.exteriorMaterial_;
- primitive.owner = this.shape;
- /**
- * The Primitive for the exterior triangles.
- * @type {!o3d.Primitive}
- * @private
- */
- this.exteriorTriangles_ = primitive;
-
- // Create the interior region.
- primitive = pack.createObject('Primitive');
- streamBank = pack.createObject('StreamBank');
- vertexBuffer = pack.createObject('VertexBuffer');
- // The coordinates of the triangles are 2D
- vertices = vertexBuffer.createField('FloatField', 2);
- /**
- * The Field for the interior vertices.
- * @type {!o3d.FloatField}
- * @private
- */
- this.interiorVertices_ = vertices;
- streamBank.setVertexStream(o3djs.base.o3d.Stream.POSITION, 0, vertices, 0);
- primitive.streamBank = streamBank;
- primitive.primitiveType = o3djs.base.o3d.Primitive.TRIANGLELIST;
- primitive.material = this.interiorMaterial_;
- primitive.owner = this.shape;
- /**
- * The Primitive for the interior triangles.
- * @type {!o3d.Primitive}
- * @private
- */
- this.interiorTriangles_ = primitive;
-
- // Initialize the fill to a solid color.
- this.setFill(o3djs.gpu2d.createColor(pack, 0.0, 0.0, 0.0, 1.0));
-
- // Create draw elements for the shape.
- this.shape.createDrawElements(pack, null);
-};
-
-/**
- * Clears out any previously added segments or generated triangles
- * from this Path.
- */
-o3djs.gpu2d.Path.prototype.clear = function() {
- this.path_.clear();
-};
-
-/**
- * Moves the pen to the given absolute X,Y coordinates. If a contour
- * isn't currently open on this path, one is opened.
- * @param {number} x the x coordinate to move to.
- * @param {number} y the y coordinate to move to.
- */
-o3djs.gpu2d.Path.prototype.moveTo = function(x, y) {
- this.path_.moveTo(x, y);
-};
-
-/**
- * Draws a line from the current coordinates to the given absolute
- * X,Y coordinates.
- * @param {number} x the x coordinate to draw a line to.
- * @param {number} y the y coordinate to draw a line to.
- */
-o3djs.gpu2d.Path.prototype.lineTo = function(x, y) {
- this.path_.lineTo(x, y);
-};
-
-/**
- * Draws a quadratic curve from the current coordinates through the
- * given control point and end point, specified in absolute
- * coordinates.
- * @param {number} cx the x coordinate of the quadratic's control point
- * @param {number} cy the y coordinate of the quadratic's control point
- * @param {number} x the x coordinate of the quadratic's end point
- * @param {number} y the y coordinate of the quadratic's end point
- */
-o3djs.gpu2d.Path.prototype.quadraticTo = function(cx, cy, x, y) {
- this.path_.quadraticTo(cx, cy, x, y);
-};
-
-/**
- * Draws a cubic curve from the current coordinates through the
- * given control points and end point, specified in absolute
- * coordinates.
- * @param {number} c0x the x coordinate of the cubic's first control point
- * @param {number} c0y the y coordinate of the cubic's first control point
- * @param {number} c1x the x coordinate of the cubic's second control point
- * @param {number} c1y the y coordinate of the cubic's second control point
- * @param {number} x the x coordinate of the cubic's end point
- * @param {number} y the y coordinate of the cubic's end point
- */
-o3djs.gpu2d.Path.prototype.cubicTo = function(c0x, c0y, c1x, c1y, x, y) {
- this.path_.cubicTo(c0x, c0y, c1x, c1y, x, y);
-};
-
-/**
- * Closes the current contour on this Path.
- */
-o3djs.gpu2d.Path.prototype.close = function() {
- this.path_.close();
-};
-
-/**
- * Updates the triangle mesh associated with this Path. Call this
- * after adding any new segments to the Path.
- */
-o3djs.gpu2d.Path.prototype.update = function() {
- this.path_.createMesh(this.exteriorVertices_,
- this.exteriorTexCoords_,
- this.interiorVertices_);
- var numVertices = this.exteriorVertices_.buffer.numElements;
- if (numVertices == 1) {
- this.exteriorTriangles_.numberVertices = 0;
- this.exteriorTriangles_.numberPrimitives = 0;
- } else {
- this.exteriorTriangles_.numberVertices = numVertices;
- this.exteriorTriangles_.numberPrimitives = numVertices / 3;
- }
- numVertices = this.interiorVertices_.buffer.numElements;
- if (numVertices == 1) {
- this.interiorTriangles_.numberVertices = 0;
- this.interiorTriangles_.numberPrimitives = 0;
- } else {
- this.interiorTriangles_.numberVertices = numVertices;
- this.interiorTriangles_.numberPrimitives = numVertices / 3;
- }
-};
-
-/**
- * Sets the polygon offset parameters for the triangles associated
- * with this Path.
- * @param {number} slopeFactor polygon offset slope factor.
- * @param {number} depthBias polygon offset depth bias.
- */
-o3djs.gpu2d.Path.prototype.setPolygonOffset = function(slopeFactor,
- depthBias) {
- this.exteriorMaterial_.state.getStateParam('o3d.PolygonOffset1').value =
- slopeFactor;
- this.exteriorMaterial_.state.getStateParam('o3d.PolygonOffset2').value =
- depthBias;
- this.interiorMaterial_.state.getStateParam('o3d.PolygonOffset1').value =
- slopeFactor;
- this.interiorMaterial_.state.getStateParam('o3d.PolygonOffset2').value =
- depthBias;
-}
-
-//----------------------------------------------------------------------
-// Fills
-
-/**
- * Sets the fill for this Path.
- * @param {!o3djs.gpu2d.Fill} fill the fill for this Path.
- */
-o3djs.gpu2d.Path.prototype.setFill = function(fill) {
- if (this.fill_) {
- this.fill_.detach_(this);
- }
- this.interiorMaterial_.effect = fill.interiorEffect;
- this.exteriorMaterial_.effect = fill.exteriorEffect;
- this.fill_ = fill;
- fill.attach_(this);
-};
-
-/**
- * Base class for all Fills. Do not call this directly; use, for
- * example, o3djs.gpu2d.createColor instead.
- * @param {!o3d.Pack} pack the Pack in which to create materials.
- * @constructor
- */
-o3djs.gpu2d.Fill = function(pack) {
- this.pack_ = pack;
- this.attachedPaths_ = [];
-};
-
-/**
- * Attaches this Fill to the given path.
- * @param {!o3djs.gpu2d.Path} path Path to attach the fill to.
- * @private
- */
-o3djs.gpu2d.Fill.prototype.attach_ = function(path) {
- if (this.attachedPaths_.indexOf(path) < 0)
- this.attachedPaths_.push(path);
- this.apply_(path);
-};
-
-/**
- * Detaches this Fill from the given path.
- * @param {!o3djs.gpu2d.Path} path Path to detach the fill from.
- * @private
- */
-o3djs.gpu2d.Fill.prototype.detach_ = function(path) {
- var idx = this.attachedPaths_.indexOf(path);
- if (idx >= 0)
- this.attachedPaths_.splice(idx, idx);
-};
-
-/**
- * Applies this Fill to all attached paths.
- * @private
- */
-o3djs.gpu2d.Fill.prototype.applyToPaths_ = function() {
- for (var i = 0; i < this.attachedPaths_.length; i++) {
- this.apply_(this.attachedPaths_[i]);
- }
-};
-
-/**
- * Base "apply" operation for fills -- a no-op.
- * @private
- */
-o3djs.gpu2d.Fill.prototype.apply_ = function(path) {
-};
-
-/**
- * A class for a solid color fill. Do not call this directly; use
- * o3djs.gpu2d.createColor instead.
- * @param {!o3d.Pack} pack the Pack in which to create materials.
- * @constructor
- * @extends {o3djs.gpu2d.Fill}
- */
-o3djs.gpu2d.Color = function(pack) {
- o3djs.gpu2d.Fill.call(this, pack);
- this.interiorEffect =
- o3djs.gpu2d.loadEffect_(pack, o3djs.gpu2d.FillTypes_.COLOR, true);
- this.exteriorEffect =
- o3djs.gpu2d.loadEffect_(pack, o3djs.gpu2d.FillTypes_.COLOR, false);
- this.r_ = 0.0;
- this.g_ = 0.0;
- this.b_ = 0.0;
- this.a_ = 1.0;
-};
-
-o3djs.base.inherit(o3djs.gpu2d.Color,
- o3djs.gpu2d.Fill);
-
-/**
- * Sets the color of this fill.
- * @param {number} r Red component (0.0 - 1.0).
- * @param {number} g Green component (0.0 - 1.0).
- * @param {number} b Blue component (0.0 - 1.0).
- * @param {number} a Alpha component (0.0 - 1.0).
- */
-o3djs.gpu2d.Color.prototype.set = function(r, g, b, a) {
- this.r_ = r;
- this.g_ = g;
- this.b_ = b;
- this.a_ = a;
- this.applyToPaths_();
-};
-
-/**
- * Gets the value of the Color fill as an array.
- * @return {!o3d.Float4}
- */
-o3djs.gpu2d.Color.prototype.get = function() {
- return [this.r_, this.g_, this.b_, this.a_];
-};
-
-/**
- * Applies this color to the given path.
- * @param {!o3djs.gpu2d.Path} path to apply the fill to.
- * @private
- */
-o3djs.gpu2d.Color.prototype.apply_ = function(path) {
- this.applyToMaterial_(path.interiorMaterial_);
- this.applyToMaterial_(path.exteriorMaterial_);
-};
-
-/**
- * Applies this color to the given material
- * @param {!o3d.Material} material to apply the fill to.
- * @private
- */
-o3djs.gpu2d.Color.prototype.applyToMaterial_ = function(material) {
- var paramName = 'color';
- var paramType = 'ParamFloat4';
- var param = material.getParam(paramName);
- if (!param) {
- param = material.createParam(paramName, paramType);
- }
- param.set(this.r_, this.g_, this.b_, this.a_);
-};
-
-/**
- * Creates a solid color fill.
- * @param {!o3d.Pack} pack the Pack in which to create materials.
- * @param {number} red Red component (0.0 - 1.0).
- * @param {number} green Green component (0.0 - 1.0).
- * @param {number} blue Blue component (0.0 - 1.0).
- * @param {number} alpha Alpha component (0.0 - 1.0).
- * @return {!o3djs.gpu2d.Color} The created Color.
- */
-o3djs.gpu2d.createColor = function(pack, red, green, blue, alpha) {
- var result = new o3djs.gpu2d.Color(pack);
- result.set(red, green, blue, alpha);
- return result;
-};
-
-//----------------------------------------------------------------------
-// Shaders and effects
-
-// TODO(kbr): antialiasing in the Cg backend is not supported yet
-// because the ddx and ddy instructions are not part of the shader
-// model 2.0. On Windows we could easily upgrade to ps2.0a, but on Mac
-// and Linux there isn't an easy upgrade path from ARBVP1.0 and
-// ARBFP1.0 which incorporates these instructions.
-//
-// The solution within O3D is to compute the gradients using the
-// closed-form solution in Loop and Blinn's SIGGRAPH '05 paper. This
-// requires computation of the Psi matrix per vertex. In GLSL this is
-// not necessary; derivative instructions are always available there.
-
-/**
- * Generates the source for the shader used on the exterior triangles
- * of the shape -- the ones that evaluate the curve function.
- * @param {boolean} antialias whether to enable antialiasing.
- * @param {string} fillUniforms the uniforms for the fill.
- * @param {string} fillSource the source code snippet for the fill.
- * @return {string}
- * @private
- */
-o3djs.gpu2d.generateLoopBlinnShaderSource_ = function(antialias,
- fillUniforms,
- fillSource) {
- if (o3djs.base.glsl) {
- var result = '' +
- '// Vertex shader\n' +
- 'uniform mat4 worldViewProjection;\n' +
- '\n' +
- 'attribute vec2 position;\n' +
- 'attribute vec3 texCoord0;\n' +
- '\n' +
- 'varying vec3 klm;\n' +
- '\n' +
- 'void main() {\n' +
- ' // TODO(kbr): figure out why this multiplication needs to be\n' +
- ' // transposed compared to the Cg version.\n' +
- ' gl_Position = worldViewProjection * vec4(position, 0.0, 1.0);\n' +
- ' klm = texCoord0;\n' +
- '}\n' +
- '// #o3d SplitMarker\n' +
- '// Fragment shader\n' +
- 'varying vec3 klm;\n' +
- fillUniforms +
- 'void main() {\n';
- var alphaComputation;
- if (antialias) {
- alphaComputation = '' +
- ' // Gradients\n' +
- ' vec3 px = dFdx(klm);\n' +
- ' vec3 py = dFdy(klm);\n' +
- '\n' +
- ' // Chain rule\n' +
- ' float k2 = klm.x * klm.x;\n' +
- ' float c = k2 * klm.x - klm.y * klm.z;\n' +
- ' float k23 = 3.0 * k2;\n' +
- ' float cx = k23 * px.x - klm.z * px.y - klm.y * px.z;\n' +
- ' float cy = k23 * py.x - klm.z * py.y - klm.y * py.z;\n' +
- '\n' +
- ' // Signed distance\n' +
- ' float sd = c / sqrt(cx * cx + cy * cy);\n' +
- '\n' +
- ' // Linear alpha\n' +
- ' // TODO(kbr): figure out why this needs to be\n' +
- ' // negated compared to Cg version, and also why\n' +
- ' // we need an adjustment by +1.0 for it to look good.\n' +
- ' // float alpha = clamp(0.5 - sd, 0.0, 1.0);\n' +
- ' float alpha = clamp(sd + 0.5, 0.0, 1.0);\n';
- } else {
- alphaComputation = '' +
- ' float t = klm.x * klm.x * klm.x - klm.y * klm.z;\n' +
- ' float alpha = clamp(sign(t), 0.0, 1.0);\n';
- }
- return result + alphaComputation +
- '\n' +
- fillSource +
- '}\n' +
- '\n' +
- '// #o3d MatrixLoadOrder RowMajor\n';
- } else {
- antialias = false; // See above why
- var result = '' +
- 'uniform float4x4 worldViewProjection : WORLDVIEWPROJECTION;\n' +
- fillUniforms +
- '\n' +
- 'struct VertexShaderInput {\n' +
- ' float2 position : POSITION;\n' +
- ' float3 klm : TEXCOORD0;\n' +
- '};\n' +
- '\n' +
- 'struct PixelShaderInput {\n' +
- ' float4 position : POSITION;\n' +
- ' float3 klm : TEXCOORD0;\n' +
- '};\n' +
- '\n' +
- 'PixelShaderInput vertexShaderFunction(VertexShaderInput input) {\n' +
- ' PixelShaderInput output;\n' +
- '\n' +
- ' output.position = mul(float4(input.position, 0, 1),\n' +
- ' worldViewProjection);\n' +
- ' output.klm = input.klm;\n' +
- ' return output;\n' +
- '}\n' +
- '\n' +
- 'float4 pixelShaderFunction(PixelShaderInput input) : COLOR {\n' +
- ' float3 klm = input.klm;\n';
- var alphaComputation;
- if (antialias) {
- alphaComputation = '' +
- ' // Gradients\n' +
- ' float3 px = ddx(input.klm);\n' +
- ' float3 py = ddy(input.klm);\n' +
- '\n' +
- ' // Chain rule\n' +
- ' float k2 = klm.x * klm.x;\n' +
- ' float c = k2 * klm.x - klm.y * klm.z;\n' +
- ' float k23 = 3.0 * k2;\n' +
- ' float cx = k23 * px.x - klm.z * px.y - klm.y * px.z;\n' +
- ' float cy = k23 * py.x - klm.z * py.y - klm.y * py.z;\n' +
- '\n' +
- ' // Signed distance\n' +
- ' float sd = c / sqrt(cx * cx + cy * cy);\n' +
- '\n' +
- ' // Linear alpha\n' +
- ' float alpha = clamp(0.5 - sd, 0.0, 1.0);\n';
- } else {
- alphaComputation = '' +
- ' float t = klm.x * klm.x * klm.x - klm.y * klm.z;\n' +
- ' float alpha = clamp(sign(t), 0.0, 1.0);\n';
- }
-
- return result + alphaComputation +
- '\n' +
- fillSource +
- '}\n' +
- '\n' +
- '// #o3d VertexShaderEntryPoint vertexShaderFunction\n' +
- '// #o3d PixelShaderEntryPoint pixelShaderFunction\n' +
- '// #o3d MatrixLoadOrder RowMajor\n';
- }
-};
-
-/**
- * Generates the source for the shader used on the interior triangles
- * of the shape.
- * @param {string} fillUniforms the uniforms for the fill.
- * @param {string} fillSource the source code snippet for the fill.
- * @return {string}
- * @private
- */
-o3djs.gpu2d.generateSolidShaderSource_ = function(fillUniforms, fillSource) {
- if (o3djs.base.glsl) {
- var result = '' +
- '// Vertex shader\n' +
- 'uniform mat4 worldViewProjection;\n' +
- '\n' +
- 'attribute vec2 position;\n' +
- '\n' +
- 'void main() {\n' +
- ' // TODO(kbr): figure out why this multiplication needs to be\n' +
- ' // transposed compared to the Cg version.\n' +
- ' gl_Position = worldViewProjection * vec4(position, 0.0, 1.0);\n' +
- '}\n' +
- '// #o3d SplitMarker\n' +
- '// Fragment shader\n' +
- fillUniforms +
- 'void main() {\n' +
- ' float alpha = 1.0;\n' +
- fillSource +
- '}\n' +
- '\n' +
- '// #o3d MatrixLoadOrder RowMajor\n';
- return result;
- } else {
- var result = '' +
- 'uniform float4x4 worldViewProjection : WORLDVIEWPROJECTION;\n' +
- fillUniforms +
- '\n' +
- 'struct VertexShaderInput {\n' +
- ' float2 position : POSITION;\n' +
- '};\n' +
- '\n' +
- 'struct PixelShaderInput {\n' +
- ' float4 position : POSITION;\n' +
- '};\n' +
- '\n' +
- 'PixelShaderInput vertexShaderFunction(VertexShaderInput input) {\n' +
- ' PixelShaderInput output;\n' +
- '\n' +
- ' output.position = mul(float4(input.position, 0, 1),\n' +
- ' worldViewProjection);\n' +
- ' return output;\n' +
- '}\n' +
- '\n' +
- 'float4 pixelShaderFunction(PixelShaderInput input) : COLOR {\n' +
- ' float alpha = 1.0;\n' +
- fillSource +
- '}\n' +
- '\n' +
- '// #o3d VertexShaderEntryPoint vertexShaderFunction\n' +
- '// #o3d PixelShaderEntryPoint pixelShaderFunction\n' +
- '// #o3d MatrixLoadOrder RowMajor\n';
- return result;
- }
-};
-
-/**
- * Enum for the types of fills.
- * @enum
- * @private
- */
-o3djs.gpu2d.FillTypes_ = {
- COLOR: 0
-};
-
-/**
- * Shader code for the various Cg fills, indexed by FillTypes_.
- * @type {!Array.<{uniforms: string, source: string}>}
- * @private
- */
-o3djs.gpu2d.FILL_CODE_CG_ = [
- { uniforms:
- 'uniform float4 color;\n',
- source:
- 'return float4(color.r, color.g, color.b, color.a * alpha);\n'
- }
-];
-
-/**
- * Shader code for the various fills, indexed by FillTypes_.
- * @type {!Array.<{uniforms: string, source: string}>}
- * @private
- */
-o3djs.gpu2d.FILL_CODE_GLSL_ = [
- { uniforms:
- 'uniform vec4 color;\n',
- source:
- 'gl_FragColor = vec4(color.r, color.g, color.b, color.a * alpha);\n'
- }
-];
-
-/**
- * Cache of effects indexed by pack's client ID. Each entry is an
- * array indexed by fill type.
- * @type {!Array.<!Array.<!o3d.Effect>>}
- * @private
- */
-o3djs.gpu2d.interiorEffectCache_ = [];
-
-/**
- * Cache of effects indexed by pack's client ID. Each entry is an
- * array indexed by fill type.
- * @type {!Array.<!Array.<!o3d.Effect>>}
- * @private
- */
-o3djs.gpu2d.exteriorEffectCache_ = [];
-
-/**
- * Loads a fill effect for a Path.
- * @param {!o3d.Pack} pack the Pack in which to create materials.
- * @param {o3djs.gpu2d.FillTypes_} fillType the fill type to create.
- * @param {boolean} interior whether this effect is filling the solid
- * interior portion of the shape or the exterior region containing
- * the curves.
- * @return {!o3d.Effect}
- * @private
- */
-o3djs.gpu2d.loadEffect_ = function(pack, fillType, interior) {
- var effectCache;
- if (interior) {
- effectCache = o3djs.gpu2d.interiorEffectCache_;
- } else {
- effectCache = o3djs.gpu2d.exteriorEffectCache_;
- }
- var effectList = o3djs.gpu2d.getEffectList_(pack, effectCache);
- var effect = effectList[fillType];
- if (!effect) {
- effect = pack.createObject('Effect');
- var result = false;
- var sourceSnippets;
- if (o3djs.base.glsl) {
- sourceSnippets = o3djs.gpu2d.FILL_CODE_GLSL_[fillType];
- } else {
- sourceSnippets = o3djs.gpu2d.FILL_CODE_CG_[fillType];
- }
- if (interior) {
- result = effect.loadFromFXString(
- o3djs.gpu2d.generateSolidShaderSource_(sourceSnippets.uniforms,
- sourceSnippets.source));
- } else {
- result = effect.loadFromFXString(
- o3djs.gpu2d.generateLoopBlinnShaderSource_(true,
- sourceSnippets.uniforms,
- sourceSnippets.source));
- }
- if (!result) {
- alert('Error loading shader: interior = ' + interior);
- }
- effectList[fillType] = effect;
- }
- return effect;
-};
-
-/**
- * Fetches and/or creates the effect list for a given pack from the
- * passed effect cache.
- * @param {!o3d.Pack} pack the Pack in which to create materials.
- * @param {!Array.<!Array.<!o3d.Effect>>} effectCache the effect cache.
- * @return {!Array.<o3d.Effect>}
- * @private
- */
-o3djs.gpu2d.getEffectList_ = function(pack, effectCache) {
- var list = effectCache[pack.clientId];
- if (!list) {
- list = [];
- effectCache[pack.clientId] = list;
- }
- return list;
-};
-
diff --git a/o3d/samples/o3djs/io.js b/o3d/samples/o3djs/io.js
deleted file mode 100644
index 784e5e0..0000000
--- a/o3d/samples/o3djs/io.js
+++ /dev/null
@@ -1,656 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains various functions and class for io.
- */
-
-o3djs.provide('o3djs.io');
-
-o3djs.require('o3djs.texture');
-
-
-/**
- * A Module with various io functions and classes.
- * @namespace
- */
-o3djs.io = o3djs.io || {};
-
-/**
- * Creates a LoadInfo object.
- * @param {(!o3d.ArchiveRequest|!o3d.FileRequest|!XMLHttpRequest)} opt_request
- * The request to watch.
- * @param {boolean} opt_hasStatus true if opt_request is a
- * o3d.ArchiveRequest vs for example an o3d.FileRequest or an
- * XMLHttpRequest.
- * @return {!o3djs.io.LoadInfo} The new LoadInfo.
- * @see o3djs.io.LoadInfo
- */
-o3djs.io.createLoadInfo = function(opt_request, opt_hasStatus) {
- return new o3djs.io.LoadInfo(opt_request, opt_hasStatus);
-};
-
-/**
- * A class to help with progress reporting for most loading utilities.
- *
- * Example:
- * <pre>
- * var g_loadInfo = null;
- * g_id = window.setInterval(statusUpdate, 500);
- * g_loadInfo = o3djs.scene.loadScene(client, pack, parent,
- * 'http://google.com/somescene.o3dtgz',
- * callback);
- *
- * function callback(pack, parent, exception) {
- * g_loadInfo = null;
- * window.clearInterval(g_id);
- * if (!exception) {
- * // do something with scene just loaded
- * }
- * }
- *
- * function statusUpdate() {
- * if (g_loadInfo) {
- * var progress = g_loadInfo.getKnownProgressInfoSoFar();
- * document.getElementById('loadstatus').innerHTML = progress.percent;
- * }
- * }
- * </pre>
- *
- * @constructor
- * @param {(!o3d.ArchiveRequest|!o3d.FileRequest|!XMLHttpRequest)} opt_request
- * The request to watch.
- * @param {boolean} opt_hasStatus true if opt_request is a
- * o3d.ArchiveRequest vs for example an o3d.FileRequest or an
- * XMLHttpRequest.
- * @see o3djs.scene.loadScene
- * @see o3djs.io.loadArchive
- * @see o3djs.io.loadTexture
- * @see o3djs.loader.Loader
- */
-o3djs.io.LoadInfo = function(opt_request, opt_hasStatus) {
- this.request_ = opt_request;
- this.hasStatus_ = opt_hasStatus;
- this.streamLength_ = 0; // because the request may have been freed.
- this.children_ = [];
-};
-
-/**
- * Adds another LoadInfo as a child of this LoadInfo so they can be
- * managed as a group.
- * @param {!o3djs.io.LoadInfo} loadInfo The child LoadInfo.
- */
-o3djs.io.LoadInfo.prototype.addChild = function(loadInfo) {
- this.children_.push(loadInfo);
-};
-
-/**
- * Marks this LoadInfo as finished.
- */
-o3djs.io.LoadInfo.prototype.finish = function() {
- if (this.request_) {
- if (this.hasStatus_) {
- this.streamLength_ = this.request_.streamLength;
- }
- this.request_ = null;
- }
-};
-
-/**
- * Gets the total bytes that will be streamed known so far.
- * If you are only streaming 1 file then this will be the info for that file but
- * if you have queued up many files using an o3djs.loader.Loader only a couple of
- * files are streamed at a time meaning that the size is not known for files
- * that have yet started to download.
- *
- * If you are downloading many files for your application and you want to
- * provide a progress status you have about 4 options
- *
- * 1) Use LoadInfo.getTotalBytesDownloaded() /
- * LoadInfo.getTotalKnownBytesToStreamSoFar() and just be aware the bar will
- * grown and then shrink as new files start to download and their lengths
- * become known.
- *
- * 2) Use LoadInfo.getTotalRequestsDownloaded() /
- * LoadInfo.getTotalKnownRequestsToStreamSoFar() and be aware the granularity
- * is not all that great since it only reports fully downloaded files. If you
- * are downloading a bunch of small files this might be ok.
- *
- * 3) Put all your files in one archive. Then there will be only one file and
- * method 1 will work well.
- *
- * 4) Figure out the total size in bytes of the files you will download and put
- * that number in your application, then use LoadInfo.getTotalBytesDownloaded()
- * / MY_APPS_TOTAL_BYTES_TO_DOWNLOAD.
- *
- * @return {number} The total number of currently known bytes to be streamed.
- */
-o3djs.io.LoadInfo.prototype.getTotalKnownBytesToStreamSoFar = function() {
- if (!this.streamLength_ && this.request_ && this.hasStatus_) {
- this.streamLength_ = this.request_.streamLength;
- }
- var total = this.streamLength_;
- for (var cc = 0; cc < this.children_.length; ++cc) {
- total += this.children_[cc].getTotalKnownBytesToStreamSoFar();
- }
- return total;
-};
-
-/**
- * Gets the total bytes downloaded so far.
- * @return {number} The total number of currently known bytes to be streamed.
- */
-o3djs.io.LoadInfo.prototype.getTotalBytesDownloaded = function() {
- var total = (this.request_ && this.hasStatus_) ?
- this.request_.bytesReceived : this.streamLength_;
- for (var cc = 0; cc < this.children_.length; ++cc) {
- total += this.children_[cc].getTotalBytesDownloaded();
- }
- return total;
-};
-
-/**
- * Gets the total streams that will be download known so far.
- * We can't know all the streams since you could use an o3djs.loader.Loader
- * object, request some streams, then call this function, then request some
- * more.
- *
- * See LoadInfo.getTotalKnownBytesToStreamSoFar for details.
- * @return {number} The total number of requests currently known to be streamed.
- * @see o3djs.io.LoadInfo.getTotalKnownBytesToStreamSoFar
- */
-o3djs.io.LoadInfo.prototype.getTotalKnownRequestsToStreamSoFar = function() {
- var total = 1;
- for (var cc = 0; cc < this.children_.length; ++cc) {
- total += this.children_[cc].getTotalKnownRequestToStreamSoFar();
- }
- return total;
-};
-
-/**
- * Gets the total requests downloaded so far.
- * @return {number} The total requests downloaded so far.
- */
-o3djs.io.LoadInfo.prototype.getTotalRequestsDownloaded = function() {
- var total = this.request_ ? 0 : 1;
- for (var cc = 0; cc < this.children_.length; ++cc) {
- total += this.children_[cc].getTotalRequestsDownloaded();
- }
- return total;
-};
-
-/**
- * Gets progress info.
- * This is commonly formatted version of the information available from a
- * LoadInfo.
- *
- * See LoadInfo.getTotalKnownBytesToStreamSoFar for details.
- * @return {{percent: number, downloaded: string, totalBytes: string,
- * base: number, suffix: string}} progress info.
- * @see o3djs.io.LoadInfo.getTotalKnownBytesToStreamSoFar
- */
-o3djs.io.LoadInfo.prototype.getKnownProgressInfoSoFar = function() {
- var percent = 0;
- var bytesToDownload = this.getTotalKnownBytesToStreamSoFar();
- var bytesDownloaded = this.getTotalBytesDownloaded();
- if (bytesToDownload > 0) {
- percent = Math.floor(bytesDownloaded / bytesToDownload * 100);
- }
-
- var base = (bytesToDownload < 1024 * 1024) ? 1024 : (1024 * 1024);
-
- return {
- percent: percent,
- downloaded: (bytesDownloaded / base).toFixed(2),
- totalBytes: (bytesToDownload / base).toFixed(2),
- base: base,
- suffix: (base == 1024 ? 'kb' : 'mb')}
-
-};
-
-/**
- * Loads text from an external file. This function is synchronous.
- * @param {string} url The url of the external file.
- * @return {string} the loaded text if the request is synchronous.
- */
-o3djs.io.loadTextFileSynchronous = function(url) {
- o3djs.BROWSER_ONLY = true;
-
- var error = 'loadTextFileSynchronous failed to load url "' + url + '"';
- var request;
- if (!o3djs.base.IsMSIE() && window.XMLHttpRequest) {
- request = new XMLHttpRequest();
- if (request.overrideMimeType) {
- request.overrideMimeType('text/plain');
- }
- } else if (window.ActiveXObject) {
- request = new ActiveXObject('MSXML2.XMLHTTP.3.0');
- } else {
- throw 'XMLHttpRequest is disabled';
- }
- request.open('GET', url, false);
- request.send(null);
- if (request.readyState != 4) {
- throw error;
- }
- return request.responseText;
-};
-
-/**
- * Loads text from an external file. This function is asynchronous.
- * @param {string} url The url of the external file.
- * @param {function(string, *): void} callback A callback passed the loaded
- * string and an exception which will be null on success.
- * @return {!o3djs.io.LoadInfo} A LoadInfo to track progress.
- */
-o3djs.io.loadTextFile = function(url, callback) {
- o3djs.BROWSER_ONLY = true;
-
- var error = 'loadTextFile failed to load url "' + url + '"';
- var request;
- if (!o3djs.base.IsMSIE() && window.XMLHttpRequest) {
- request = new XMLHttpRequest();
- if (request.overrideMimeType) {
- request.overrideMimeType('text/plain');
- }
- } else if (window.ActiveXObject) {
- request = new ActiveXObject('MSXML2.XMLHTTP.3.0');
- } else {
- throw 'XMLHttpRequest is disabled';
- }
- var loadInfo = o3djs.io.createLoadInfo(request, false);
- request.open('GET', url, true);
- var finish = function() {
- if (request.readyState == 4) {
- var text = '';
- // HTTP reports success with a 200 status. The file protocol reports
- // success with zero. HTTP does not use zero as a status code (they
- // start at 100).
- // https://developer.mozilla.org/En/Using_XMLHttpRequest
- var success = request.status == 200 || request.status == 0;
- if (success) {
- text = request.responseText;
- }
- loadInfo.finish();
- callback(text, success ? null : 'could not load: ' + url);
- }
- };
- request.onreadystatechange = finish;
- request.send(null);
- return loadInfo;
-};
-
-/**
- * A ArchiveInfo object loads and manages an archive of files.
- * There are methods for locating a file by uri and for freeing
- * the archive.
- *
- * You can only read archives that have as their first file a file named
- * 'aaaaaaaa.o3d' the contents of the which is 'o3d'. This is to prevent O3D
- * from being used to read arbitrary tar gz files.
- *
- * Example:
- * <pre>
- * var loadInfo = o3djs.io.loadArchive(pack,
- * 'http://google.com/files.o3dtgz',
- * callback);
- *
- * function callback(archiveInfo, exception) {
- * if (!exception) {
- * o3djs.texture.createTextureFromRawData(
- * pack, archiveInfo.getFileByURI('logo.jpg'), true);
- * o3djs.texture.createTextureFromRawData(
- * pack, archiveInfo.getFileByURI('wood/oak.png'), true);
- * o3djs.texture.createTextureFromRawData(
- * pack, archiveInfo.getFileByURI('wood/maple.dds'), true);
- * archiveInfo.destroy();
- * } else {
- * alert(exception);
- * }
- * }
- * </pre>
- *
- * @constructor
- * @param {!o3d.Pack} pack Pack to create request in.
- * @param {string} url The url of the archive file.
- * @param {!function(!o3djs.io.ArchiveInfo, *): void} onFinished A
- * callback that is called when the archive is finished loading and passed
- * the ArchiveInfo and an exception which is null on success.
- */
-o3djs.io.ArchiveInfo = function(pack, url, onFinished) {
- var that = this;
-
- /**
- * The list of files in the archive by uri.
- * @type {!Object}
- */
- this.files = {};
-
- /**
- * The pack used to create the archive request.
- * @type {!o3d.Pack}
- */
- this.pack = pack;
-
- /**
- * True if this archive has not be destroyed.
- * @type {boolean}
- */
- this.destroyed = false;
-
- this.request_ = null;
-
- /**
- * Records each RawData file as it comes in.
- * @private
- * @param {!o3d.RawData} rawData RawData from archive request.
- */
- function addFile(rawData) {
- that.files[rawData.uri] = rawData;
- }
-
- /**
- * The LoadInfo to track loading progress.
- * @type {!o3djs.io.LoadInfo}
- */
- this.loadInfo = o3djs.io.loadArchiveAdvanced(
- pack,
- url,
- addFile,
- function(request, exception) {
- that.request_ = request;
- onFinished(that, exception);
- });
-};
-
-/**
- * Releases all the RAW data associated with this archive. It does not release
- * any objects created from that RAW data.
- */
-o3djs.io.ArchiveInfo.prototype.destroy = function() {
- if (!this.destroyed) {
- this.pack.removeObject(this.request_);
- this.destroyed = true;
- this.files = {};
- }
-};
-
-/**
- * Gets files by regular expression or wildcards from the archive.
- * @param {(string|!RegExp)} uri of file to get. Can have wildcards '*' and '?'.
- * @param {boolean} opt_caseInsensitive Only valid if it's a wildcard string.
- * @return {!Array.<!o3d.RawData>} An array of the matching RawDatas for
- * the files matching or undefined if it doesn't exist.
- */
-o3djs.io.ArchiveInfo.prototype.getFiles = function(uri,
- opt_caseInsensitive) {
- if (!(uri instanceof RegExp)) {
- uri = uri.replace(/(\W)/g, '\\$&');
- uri = uri.replace(/\\\*/g, '.*');
- uri = uri.replace(/\\\?/g, '.');
- uri = new RegExp(uri, opt_caseInsensitive ? 'i' : '');
- }
- var files = [];
- for (var key in this.files) {
- if (uri.test(key)) {
- files.push(this.files[key]);
- }
- }
-
- return files;
-};
-
-/**
- * Gets a file by URI from the archive.
- * @param {string} uri of file to get.
- * @param {boolean} opt_caseInsensitive True to be case insensitive. Default
- * false.
- * @return {(o3d.RawData|undefined)} The RawData for the file or undefined if
- * it doesn't exist.
- */
-o3djs.io.ArchiveInfo.prototype.getFileByURI = function(
- uri,
- opt_caseInsensitive) {
- if (opt_caseInsensitive) {
- uri = uri.toLowerCase();
- for (var key in this.files) {
- if (key.toLowerCase() == uri) {
- return this.files[key];
- }
- }
- return undefined;
- } else {
- return this.files[uri];
- }
-};
-
-/**
- * Loads an archive file.
- * When the entire archive is ready the onFinished callback will be called
- * with an ArchiveInfo for accessing the archive.
- *
- * @param {!o3d.Pack} pack Pack to create request in.
- * @param {string} url The url of the archive file.
- * @param {!function(!o3djs.io.ArchiveInfo, *): void} onFinished A
- * callback that is called when the archive is successfully loaded and an
- * Exception object which is null on success.
- * @return {!o3djs.io.LoadInfo} The a LoadInfo for tracking progress.
- * @see o3djs.io.ArchiveInfo
- */
-o3djs.io.loadArchive = function(pack,
- url,
- onFinished) {
- var archiveInfo = new o3djs.io.ArchiveInfo(pack, url, onFinished);
- return archiveInfo.loadInfo;
-};
-
-/**
- * Loads an archive file. This function is asynchronous. This is a low level
- * version of o3djs.io.loadArchive which can be used for things like
- * progressive loading.
- *
- * @param {!o3d.Pack} pack Pack to create request in.
- * @param {string} url The url of the archive file.
- * @param {!function(!o3d.RawData): void} onFileAvailable A callback, taking a
- * single argument 'data'. As each file is loaded from the archive, this
- * function is called with the file's data.
- * @param {!function(!o3d.ArchiveRequest, *): void} onFinished
- * A callback that is called when the archive is successfully loaded. It is
- * passed the ArchiveRquest and null on success or a javascript exception on
- * failure.
- * @return {!o3djs.io.LoadInfo} A LoadInfo for tracking progress.
- */
-o3djs.io.loadArchiveAdvanced = function(pack,
- url,
- onFileAvailable,
- onFinished) {
- var error = 'loadArchive failed to load url "' + url + '"';
- var request = pack.createArchiveRequest();
- var loadInfo = o3djs.io.createLoadInfo(request, true);
- request.open('GET', url);
- request.onfileavailable = onFileAvailable;
- /**
- * @ignore
- */
- request.onreadystatechange = function() {
- if (request.done) {
- loadInfo.finish();
- var success = request.success;
- var exception = null;
- if (!success) {
- exception = request.error;
- if (!exception) {
- exception = 'unknown error loading archive';
- }
- }
- onFinished(request, exception);
- }
- };
- request.send();
- return loadInfo;
-};
-
-/**
- * Loads RawData.
- *
- * RawData is loaded asynchronously.
- *
- * @param {!o3d.Pack} pack Pack to create the request in.
- * @param {string} url URL of raw data to load.
- * @param {!function(!o3d.FileRequest, o3d.RawData, *): void} callback Callback
- * when RawData is loaded. It will be passed the FileRequest, a RawData and
- * an exception on error or null on success. The RawData is associated with
- * the request so it will stay in memory until you free with request with
- * pack.removeObject(request).
- * @return {!o3djs.io.LoadInfo} A LoadInfo to track progress.
- * @see o3djs.io.loadTexture
- * @see o3djs.io.loadBitmaps
- * @see o3djs.loader.createLoader
- */
-o3djs.io.loadRawData = function(pack, url, callback) {
- var request = pack.createFileRequest('RAWDATA');
- var loadInfo = o3djs.io.createLoadInfo(
- /** @type {!o3d.FileRequest} */ (request),
- false);
- request.open('GET', url, true);
- /**
- * @ignore
- */
- request.onreadystatechange = function() {
- if (request.done) {
- var data = request.data;
- var success = request.success;
- var exception = request.error;
- loadInfo.finish();
- if (!success && !exception) {
- exception = 'unknown error loading RawData: ' + url;
- }
- callback(request, data, success ? null : exception);
- }
- };
- request.send();
- return loadInfo;
-};
-
-/**
- * Loads bitmaps.
- *
- * Bitmaps are loaded asynchronously.
- *
- * Example:
- * <pre>
- * var loadInfo = o3djs.io.loadBitamps(pack,
- * 'http://google.com/someimage.jpg',
- * callback);
- *
- * function callback(bitmaps, exception) {
- * if (!exception) {
- * o3djs.texture.createTextureFromBitmaps(g_pack, bitmaps, true);
- * } else {
- * alert(exception);
- * }
- * }
- * </pre>
- *
- *
- * @param {!o3d.Pack} pack Pack to load texture into.
- * @param {string} url URL of image to load.
- * @param {!function(!Array.<!o3d.Bitmap>, *): void} callback Callback when
- * image is loaded. It will be passed an array of bitmaps and an exception
- * on error or null on success.
- * @param {boolean} opt_generateMips Generate Mips. Default = true.
- * @return {!o3djs.io.LoadInfo} A LoadInfo to track progress.
- * @see o3djs.io.loadTexture
- * @see o3djs.loader.createLoader
- */
-o3djs.io.loadBitmaps = function(pack, url, callback, opt_generateMips) {
- if (typeof opt_generateMips === 'undefined') {
- opt_generateMips = true;
- }
- return o3djs.io.loadRawData(pack, url, function(request, rawData, exception) {
- var bitmaps = [];
- if (!exception) {
- bitmaps = pack.createBitmapsFromRawData(rawData);
- pack.removeObject(request);
- }
- callback(bitmaps, exception);
- });
-};
-
-/**
- * Loads a texture.
- *
- * Textures are loaded asynchronously.
- *
- * Example:
- * <pre>
- * var loadInfo = o3djs.io.loadTexture(pack,
- * 'http://google.com/someimage.jpg',
- * callback);
- *
- * function callback(texture, exception) {
- * if (!exception) {
- * g_mySampler.texture = texture;
- * } else {
- * alert(exception);
- * }
- * }
- * </pre>
- *
- *
- * @param {!o3d.Pack} pack Pack to load texture into.
- * @param {string} url URL of texture to load.
- * @param {!function(o3d.Texture, *): void} callback Callback when
- * texture is loaded. It will be passed the texture and an exception on
- * error or null on success.
- * @param {boolean} opt_generateMips Generate Mips. Default = true.
- * @param {boolean} opt_flip Flip texture. Default = true.
- * @return {!o3djs.io.LoadInfo} A LoadInfo to track progress.
- * @see o3djs.io.loadBitmaps
- * @see o3djs.loader.createLoader
- */
-o3djs.io.loadTexture = function(
- pack, url, callback, opt_generateMips, opt_flip) {
- function onLoaded(request, rawData, exception) {
- var texture = null;
- if (!exception) {
- texture = o3djs.texture.createTextureFromRawData(
- pack, rawData, opt_generateMips, opt_flip);
- pack.removeObject(request);
- }
- callback(texture, exception);
- };
-
- return o3djs.io.loadRawData(pack, url, onLoaded);
-};
-
-
diff --git a/o3d/samples/o3djs/js_list.manifest b/o3d/samples/o3djs/js_list.manifest
deleted file mode 100644
index 5e7423e..0000000
--- a/o3d/samples/o3djs/js_list.manifest
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright 2009, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-[ 'arcball.js',
- 'base.js',
- 'camera.js',
- 'canvas.js',
- 'debug.js',
- 'dump.js',
- 'effect.js',
- 'element.js',
- 'error.js',
- 'event.js',
- 'fps.js',
- 'gpu2d.js',
- 'io.js',
- 'loader.js',
- 'material.js',
- 'manipulators.js',
- 'math.js',
- 'pack.js',
- 'particles.js',
- 'performance.js',
- 'picking.js',
- 'primitives.js',
- 'lineprimitives.js', # lineprimitives.js must come after primitives.js
- 'quaternions.js',
- 'rendergraph.js',
- 'scene.js',
- 'serialization.js',
- 'shape.js',
- 'simple.js',
- 'test.js',
- 'texture.js',
- 'util.js',
-]
-
diff --git a/o3d/samples/o3djs/lineprimitives.js b/o3d/samples/o3djs/lineprimitives.js
deleted file mode 100644
index 4078f9c..0000000
--- a/o3d/samples/o3djs/lineprimitives.js
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains various functions to help
- * create line primitives for o3d applications.
- *
- * Note: This library is only a sample. It is not meant to be some official
- * library. It is provided only as example code.
- *
- */
-
-o3djs.provide('o3djs.lineprimitives');
-
-o3djs.require('o3djs.math');
-o3djs.require('o3djs.primitives');
-
-/**
- * Defines a namespace for o3djs.lineprimitives.
- * @namespace
- */
-o3djs.lineprimitives = o3djs.lineprimitives || {};
-
-/**
- * A LineVertexInfo is a specialization of VertexInfoBase for line based
- * geometry.
- * @constructor
- * @extends {o3djs.primitives.VertexInfoBase}
- */
-o3djs.lineprimitives.LineVertexInfo = function() {
- o3djs.primitives.VertexInfoBase.call(this);
-}
-
-o3djs.base.inherit(o3djs.lineprimitives.LineVertexInfo,
- o3djs.primitives.VertexInfoBase);
-
-/**
- * Returns the number of lines represented by the LineVertexInfo.
- * @return {number} The number of lines represented by LineVertexInfo.
- */
-o3djs.lineprimitives.LineVertexInfo.prototype.numLines = function() {
- return this.indices.length / 2;
-};
-
-/**
- * Adds a line.
- * @param {number} index1 The index of the first vertex of the line.
- * @param {number} index2 The index of the second vertex of the line.
- */
-o3djs.lineprimitives.LineVertexInfo.prototype.addLine = function(
- index1, index2) {
- this.indices.push(index1, index2);
-};
-
-/**
- * Gets the vertex indices of the triangle at the given triangle index.
- * @param {number} triangleIndex The index of the triangle.
- * @return {!Array.<number>} An array of three triangle indices.
- */
-o3djs.lineprimitives.LineVertexInfo.prototype.getLine = function(
- triangleIndex) {
- var indexIndex = triangleIndex * 3;
- return [this.indices[indexIndex + 0],
- this.indices[indexIndex + 1],
- this.indices[indexIndex + 2]];
-};
-
-/**
- * Sets the vertex indices of the line at the given line index.
- * @param {number} lineIndex The index of the line.
- * @param {number} index1 The index of the first vertex of the line.
- * @param {number} index2 The index of the second vertex of the line.
- */
-o3djs.lineprimitives.LineVertexInfo.prototype.setLine = function(
- lineIndex, index1, index2) {
- var indexIndex = lineIndex * 2;
- this.indices[indexIndex + 0] = index1;
- this.indices[indexIndex + 1] = index2;
-};
-
-/**
- * Creates a shape from a LineVertexInfo
- * @param {!o3d.Pack} pack Pack to create objects in.
- * @param {!o3d.Material} material to use.
- * @return {!o3d.Shape} The created shape.
- */
-o3djs.lineprimitives.LineVertexInfo.prototype.createShape = function(
- pack,
- material) {
- return this.createShapeByType(
- pack, material, o3djs.base.o3d.Primitive.LINELIST);
-};
-
-/**
- * Creates a new LineVertexInfo.
- * @return {!o3djs.lineprimitives.LineVertexInfo} The new LineVertexInfo.
- */
-o3djs.lineprimitives.createLineVertexInfo = function() {
- return new o3djs.lineprimitives.LineVertexInfo();
-};
-
-/**
- * Creates the vertices and indices for a cube of lines.
- * The cube will be created around the origin (-size / 2, size / 2).
- * The created cube has a position stream only and can therefore only be used
- * with appropriate shaders.
- *
- * @param {number} size Width, height and depth of the cube.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply all
- * the vertices.
- * @return {!o3djs.lineprimitives.LineVertexInfo} The created cube vertices.
- */
-o3djs.lineprimitives.createLineCubeVertices = function(size, opt_matrix) {
- var k = size / 2;
-
- var vertices = [
- [-k, -k, -k],
- [+k, -k, -k],
- [-k, +k, -k],
- [+k, +k, -k],
- [-k, -k, +k],
- [+k, -k, +k],
- [-k, +k, +k],
- [+k, +k, +k]
- ];
-
- var indices = [
- [0, 1],
- [1, 3],
- [3, 2],
- [2, 0],
- [4, 5],
- [5, 7],
- [7, 6],
- [6, 4],
- [0, 4],
- [1, 5],
- [2, 6],
- [3, 7]
- ];
-
- var vertexInfo = o3djs.lineprimitives.createLineVertexInfo();
- var positionStream = vertexInfo.addStream(
- 3, o3djs.base.o3d.Stream.POSITION);
-
- for (var v = 0; v < vertices.length; ++v) {
- positionStream.addElementVector(vertices[v]);
- }
-
- for (var i = 0; i < indices.length; ++i) {
- vertexInfo.addLine(indices[i][0], indices[i][1]);
- }
-
- if (opt_matrix) {
- vertexInfo.reorient(opt_matrix);
- }
- return vertexInfo;
-};
-
-/**
- * Creates a cube of lines.
- * The cube will be created around the origin (-size / 2, size / 2).
- * The created cube has a position stream only and can therefore only be used
- * with appropriate shaders.
- *
- * @param {!o3d.Pack} pack Pack to create cube elements in.
- * @param {!o3d.Material} material Material to use.
- * @param {number} size Width, height and depth of the cube.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply all
- * the vertices.
- * @return {!o3d.Shape} The created cube.
- */
-o3djs.lineprimitives.createLineCube = function(
- pack,
- material,
- size,
- opt_matrix) {
- var vertexInfo =
- o3djs.lineprimitives.createLineCubeVertices(size, opt_matrix);
- return vertexInfo.createShape(pack, material);
-};
-
-/**
- * Creates sphere vertices.
- * The created sphere has a position stream only and can therefore only be
- * used with appropriate shaders.
- *
- * @param {number} radius radius of the sphere.
- * @param {number} subdivisionsAxis number of steps around the sphere.
- * @param {number} subdivisionsHeight number of steps vertically on the sphere.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply all
- * the vertices.
- * @return {!o3djs.lineprimitives.LineVertexInfo} The created sphere vertices.
- */
-o3djs.lineprimitives.createLineSphereVertices = function(
- radius,
- subdivisionsAxis,
- subdivisionsHeight,
- opt_matrix) {
- if (subdivisionsAxis <= 0 || subdivisionsHeight <= 0) {
- throw Error('subdivisionAxis and subdivisionHeight must be > 0');
- }
-
- // We are going to generate our sphere by iterating through its
- // spherical coordinates and generating 1 quad for each quad on a
- // ring of the sphere.
-
- var vertexInfo = o3djs.lineprimitives.createLineVertexInfo();
- var positionStream = vertexInfo.addStream(
- 3, o3djs.base.o3d.Stream.POSITION);
-
- // Generate the individual vertices in our vertex buffer.
- for (var y = 0; y <= subdivisionsHeight; y++) {
- for (var x = 0; x <= subdivisionsAxis; x++) {
- // Generate a vertex based on its spherical coordinates
- var u = x / subdivisionsAxis
- var v = y / subdivisionsHeight;
- var theta = 2 * Math.PI * u;
- var phi = Math.PI * v;
- var sinTheta = Math.sin(theta);
- var cosTheta = Math.cos(theta);
- var sinPhi = Math.sin(phi);
- var cosPhi = Math.cos(phi);
- var ux = cosTheta * sinPhi;
- var uy = cosPhi;
- var uz = sinTheta * sinPhi;
- positionStream.addElement(radius * ux, radius * uy, radius * uz);
- }
- }
- var numVertsAround = subdivisionsAxis + 1;
-
- for (var x = 0; x < subdivisionsAxis; x++) {
- for (var y = 0; y < subdivisionsHeight; y++) {
- // Make 2 lines per quad.
- vertexInfo.addLine(
- (y + 0) * numVertsAround + x,
- (y + 0) * numVertsAround + x + 1);
- vertexInfo.addLine(
- (y + 0) * numVertsAround + x,
- (y + 1) * numVertsAround + x);
- }
- }
-
- if (opt_matrix) {
- vertexInfo.reorient(opt_matrix);
- }
- return vertexInfo;
-};
-
-/**
- * Creates a sphere.
- * The created sphere has a position stream only and can therefore only be
- * used with appropriate shaders.
- *
- * @param {!o3d.Pack} pack Pack to create sphere elements in.
- * @param {!o3d.Material} material Material to use.
- * @param {number} radius radius of the sphere.
- * @param {number} subdivisionsAxis number of steps around the sphere.
- * @param {number} subdivisionsHeight number of steps vertically on the sphere.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply all
- * the vertices.
- * @return {!o3d.Shape} The created sphere.
- *
- * @see o3d.Pack
- * @see o3d.Shape
- */
-o3djs.lineprimitives.createLineSphere = function(
- pack,
- material,
- radius,
- subdivisionsAxis,
- subdivisionsHeight,
- opt_matrix) {
- var vertexInfo = o3djs.lineprimitives.createLineSphereVertices(
- radius,
- subdivisionsAxis,
- subdivisionsHeight,
- opt_matrix);
-
- return vertexInfo.createShape(pack, material);
-};
-
-/**
- * Creates ring vertices.
- * The ring is a circle in the XZ plane, centered at the origin.
- * The created ring has position, normal, and 1-D texcoord streams.
- * The normals point outwards from the center of the ring.
- * The texture coordinates are based on angle about the center.
- *
- * @param {number} radius Radius of the ring.
- * @param {number} subdivisions Number of steps around the ring.
- * @param {number} maxTexCoord 1-D texture coordinates will range from 0 to
- * this value, based on angle about the center.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply all
- * the vertices.
- * @return {!o3djs.lineprimitives.LineVertexInfo} The created ring vertices.
- */
-o3djs.lineprimitives.createLineRingVertices = function(
- radius,
- subdivisions,
- maxTexCoord,
- opt_matrix) {
- if (subdivisions < 3) {
- throw Error('subdivisions must be >= 3');
- }
-
- var vertexInfo = o3djs.lineprimitives.createLineVertexInfo();
- var positionStream = vertexInfo.addStream(
- 3, o3djs.base.o3d.Stream.POSITION);
- var normalStream = vertexInfo.addStream(
- 3, o3djs.base.o3d.Stream.NORMAL);
- var texCoordStream = vertexInfo.addStream(
- 1, o3djs.base.o3d.Stream.TEXCOORD, 0);
-
- // Generate the individual vertices in our vertex buffer.
- for (var i = 0; i <= subdivisions; i++) {
- var theta = 2 * Math.PI * i / subdivisions;
- positionStream.addElement(radius * Math.cos(theta), 0,
- radius * Math.sin(theta));
- normalStream.addElement(Math.cos(theta), 0, Math.sin(theta));
- texCoordStream.addElement(maxTexCoord * i / subdivisions);
- }
-
- // Connect the vertices by simple lines.
- for (var i = 0; i < subdivisions; i++) {
- vertexInfo.addLine(i, i+1);
- }
-
- if (opt_matrix) {
- vertexInfo.reorient(opt_matrix);
- }
- return vertexInfo;
-};
-
-/**
- * Creates a ring.
- * The ring is a circle in the XZ plane, centered at the origin.
- * The created ring has position, normal, and 1-D texcoord streams.
- * The normals point outwards from the center of the ring.
- * The texture coordinates are based on angle about the center.
- *
- * @param {!o3d.Pack} pack Pack to create ring elements in.
- * @param {!o3d.Material} material Material to use.
- * @param {number} radius Radius of the ring.
- * @param {number} subdivisions Number of steps around the ring.
- * @param {number} maxTexCoord 1-D texture coordinates will range from 0 to
- * this value, based on angle about the center.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply all
- * the vertices.
- * @return {!o3d.Shape} The created ring.
- */
-o3djs.lineprimitives.createLineRing = function(
- pack,
- material,
- radius,
- subdivisions,
- maxTexCoord,
- opt_matrix) {
- var vertexInfo = o3djs.lineprimitives.createLineRingVertices(
- radius,
- subdivisions,
- maxTexCoord,
- opt_matrix);
-
- return vertexInfo.createShape(pack, material);
-};
-
diff --git a/o3d/samples/o3djs/loader.js b/o3d/samples/o3djs/loader.js
deleted file mode 100644
index fa38e2d..0000000
--- a/o3d/samples/o3djs/loader.js
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains a loader class for helping to load
- * muliple assets in an asynchronous manner.
- */
-
-o3djs.provide('o3djs.loader');
-
-o3djs.require('o3djs.io');
-o3djs.require('o3djs.scene');
-
-/**
- * A Module with a loader class for helping to load muliple assets in an
- * asynchronous manner.
- * @namespace
- */
-o3djs.loader = o3djs.loader || {};
-
-/**
- * A simple Loader class to call some callback when everything has loaded.
- * @constructor
- * @param {!function(): void} onFinished Function to call when final item has
- * loaded.
- */
-o3djs.loader.Loader = function(onFinished) {
- this.count_ = 1;
- this.onFinished_ = onFinished;
-
- /**
- * The LoadInfo for this loader you can use to track progress.
- * @type {!o3djs.io.LoadInfo}
- */
- this.loadInfo = o3djs.io.createLoadInfo();
-};
-
-/**
- * Creates a Loader for helping to load a bunch of items asychronously.
- *
- * The way you use this is as follows.
- *
- * <pre>
- * var loader = o3djs.loader.createLoader(myFinishedCallback);
- * loader.loadTexture(pack, texture1Url, callbackForTexture);
- * loader.loadTexture(pack, texture2Url, callbackForTexture);
- * loader.loadTexture(pack, texture3Url, callbackForTexture);
- * loader.finish();
- * </pre>
- *
- * The loader guarantees that myFinishedCallback will be called after
- * all the items have been loaded.
- *
-* @param {!function(): void} onFinished Function to call when final item has
-* loaded.
-* @return {!o3djs.loader.Loader} A Loader Object.
- */
-o3djs.loader.createLoader = function(onFinished) {
- return new o3djs.loader.Loader(onFinished);
-};
-
-/**
- * Loads a texture.
- * @param {!o3d.Pack} pack Pack to load texture into.
- * @param {string} url URL of texture to load.
- * @param {!function(o3d.Texture, *): void} opt_onTextureLoaded
- * optional callback when texture is loaded. It will be passed the texture
- * and an exception which is null on success.
- */
-o3djs.loader.Loader.prototype.loadTexture = function(pack,
- url,
- opt_onTextureLoaded) {
- var that = this; // so the function below can see "this".
- ++this.count_;
- var loadInfo = o3djs.io.loadTexture(pack, url, function(texture, exception) {
- if (opt_onTextureLoaded) {
- opt_onTextureLoaded(texture, exception);
- }
- that.countDown_();
- });
- this.loadInfo.addChild(loadInfo);
-};
-
-/**
- * Loads a RawData.
- * @param {!o3d.Pack} pack Pack to load texture into.
- * @param {string} url URL of image file to load.
- * @param {!function(!o3d.FileRequest, o3d.RawData, *): void} onLoaded Callback
- * when RawData is loaded. It will be passed the request, a RawData and an
- * exception which is null on success. The RawData is associated with
- * the request so it will stay in memory until you free with request with
- * pack.removeObject(request).
- */
-o3djs.loader.Loader.prototype.loadRawData = function(pack,
- url,
- onLoaded) {
- var that = this; // so the function below can see "this".
- ++this.count_;
- var loadInfo = o3djs.io.loadRawData(
- pack, url, function(request, rawData, exception) {
- onLoaded(request, rawData, exception);
- that.countDown_();
- });
- this.loadInfo.addChild(loadInfo);
-};
-
-/**
- * Loads bitmaps.
- * @param {!o3d.Pack} pack Pack to load texture into.
- * @param {string} url URL of image file to load.
- * @param {!function(!Array.<!o3d.Bitmap>, *): void} onBitmapsLoaded Callback
- * when bitmaps are loaded. It will be passed an array of bitmaps and an
- * exception which is null on success.
- */
-o3djs.loader.Loader.prototype.loadBitmaps = function(pack,
- url,
- onBitmapsLoaded) {
- var that = this; // so the function below can see "this".
- ++this.count_;
- var loadInfo = o3djs.io.loadBitmaps(pack, url, function(bitmaps, exception) {
- onBitmapsLoaded(bitmaps, exception);
- that.countDown_();
- });
- this.loadInfo.addChild(loadInfo);
-};
-
-/**
- * Loads a 3d scene.
- * @param {!o3d.Client} client An O3D client object.
- * @param {!o3d.Pack} pack Pack to load texture into.
- * @param {!o3d.Transform} parent Transform to parent scene under.
- * @param {string} url URL of scene to load.
- * @param {!o3djs.serialization.Options} opt_options Options passed into the
- * loader.
- * @param {!function(!o3d.Pack, !o3d.Transform, *): void}
- * opt_onSceneLoaded optional callback when scene is loaded. It will be
- * passed the pack and parent and an exception which is null on success.
- */
-o3djs.loader.Loader.prototype.loadScene = function(client,
- pack,
- parent,
- url,
- opt_onSceneLoaded,
- opt_options) {
- var that = this; // so the function below can see "this".
- ++this.count_;
- var loadInfo = o3djs.scene.loadScene(
- client, pack, parent, url, function(pack, parent, exception) {
- if (opt_onSceneLoaded) {
- opt_onSceneLoaded(pack, parent, exception);
- }
- that.countDown_();
- },
- opt_options);
- this.loadInfo.addChild(loadInfo);
-};
-
-/**
- * Loads a text file.
- * @param {string} url URL of scene to load.
- * @param {!function(string, *): void} onTextLoaded Function to call when
- * the file is loaded. It will be passed the contents of the file as a
- * string and an exception which is null on success.
- */
-o3djs.loader.Loader.prototype.loadTextFile = function(url, onTextLoaded) {
- var that = this; // so the function below can see "this".
- ++this.count_;
- var loadInfo = o3djs.io.loadTextFile(url, function(string, exception) {
- onTextLoaded(string, exception);
- that.countDown_();
- });
- this.loadInfo.addChild(loadInfo);
-};
-
-/**
- * Creates a loader that is tracked by this loader so that when the new loader
- * is finished it will be reported to this loader.
- * @param {!function(): void} onFinished Function to be called when everything
- * loaded with this loader has finished.
- * @return {!o3djs.loader.Loader} The new Loader.
- */
-o3djs.loader.Loader.prototype.createLoader = function(onFinished) {
- var that = this;
- ++this.count_;
- var loader = o3djs.loader.createLoader(function() {
- onFinished();
- that.countDown_();
- });
- this.loadInfo.addChild(loader.loadInfo);
- return loader;
-};
-
-/**
- * Counts down the internal count and if it gets to zero calls the callback.
- * @private
- */
-o3djs.loader.Loader.prototype.countDown_ = function() {
- --this.count_;
- if (this.count_ === 0) {
- this.onFinished_();
- }
-};
-
-/**
- * Finishes the loading process.
- * Actually this just calls countDown_ to account for the count starting at 1.
- */
-o3djs.loader.Loader.prototype.finish = function() {
- this.countDown_();
-};
-
-
diff --git a/o3d/samples/o3djs/manipulators.js b/o3d/samples/o3djs/manipulators.js
deleted file mode 100644
index 4aa300f..0000000
--- a/o3d/samples/o3djs/manipulators.js
+++ /dev/null
@@ -1,1910 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains classes that implement several
- * forms of 2D and 3D manipulation.
- */
-
-o3djs.provide('o3djs.manipulators');
-
-o3djs.require('o3djs.lineprimitives');
-o3djs.require('o3djs.material');
-o3djs.require('o3djs.math');
-o3djs.require('o3djs.picking');
-o3djs.require('o3djs.primitives');
-o3djs.require('o3djs.quaternions');
-
-/**
- * A module implementing several forms of 2D and 3D manipulation.
- * @namespace
- */
-o3djs.manipulators = o3djs.manipulators || {};
-
-/**
- * Creates a new manipulator manager, which maintains multiple
- * manipulators in the same scene. The manager is implicitly
- * associated with a particular O3D client via the Pack which is
- * passed in, although multiple managers can be created for a given
- * client. The manipulators are positioned in world coordinates and
- * are placed in the scene graph underneath the parent transform which
- * is passed in.
- * @param {!o3d.Pack} pack Pack in which manipulators' geometry and
- * materials will be created.
- * @param {!o3d.Transform} parentTransform The parent transform under
- * which the manipulators' geometry should be parented.
- * @param {!o3d.RenderNode} parentRenderNode The parent render node
- * under which the manipulators' draw elements should be placed.
- * @param {number} renderNodePriority The priority that the
- * manipulators' geometry should use for rendering.
- * @param {!o3d.DrawContext} drawContext The DrawContext to use for the
- * manipulators.
- * @return {!o3djs.manipulators.Manager} The created manipulator
- * manager.
- */
-o3djs.manipulators.createManager = function(pack,
- parentTransform,
- parentRenderNode,
- renderNodePriority,
- drawContext) {
- return new o3djs.manipulators.Manager(pack,
- parentTransform,
- parentRenderNode,
- renderNodePriority,
- drawContext);
-};
-
-//
-// Some linear algebra classes.
-// TODO(kbr): find a better home for these.
-//
-
-/**
- * Creates a new Line object, which implements projection and
- * closest-point operations.
- * @constructor
- * @private
- * @param {!o3djs.math.Vector3} opt_direction The direction of the
- * line. Does not need to be normalized but must not be the zero
- * vector. Defaults to [1, 0, 0] if not specified.
- * @param {!o3djs.math.Vector3} opt_point A point through which the
- * line goes. Defaults to [0, 0, 0] if not specified.
- */
-o3djs.manipulators.Line_ = function(opt_direction,
- opt_point) {
- /**
- * The direction of the line.
- * @private
- * @type {!o3djs.math.Vector3}
- */
- this.direction_ = o3djs.math.copyVector(opt_direction || [1, 0, 0]);
- /**
- * A point through which the line goes.
- * @private
- * @type {!o3djs.math.Vector3}
- */
- this.point_ = o3djs.math.copyVector(opt_point || [0, 0, 0]);
- this.recalc_();
-};
-
-/**
- * Sets the direction of this line.
- * @private
- * @param {!o3djs.math.Vector3} direction The new direction of the
- * line. Does not need to be normalized but must not be the zero
- * vector.
- */
-o3djs.manipulators.Line_.prototype.setDirection = function(direction) {
- this.direction_ = o3djs.math.copyVector(direction);
- this.recalc_();
-};
-
-/**
- * Gets the direction of this line.
- * @private
- * @return {!o3djs.math.Vector3} The direction of the line.
- */
-o3djs.manipulators.Line_.prototype.getDirection = function() {
- return this.direction_;
-};
-
-/**
- * Sets one point through which this line travels.
- * @private
- * @param {!o3djs.math.Vector3} point A point which through the line
- * will travel.
- */
-o3djs.manipulators.Line_.prototype.setPoint = function(point) {
- this.point_ = o3djs.math.copyVector(point);
- this.recalc_();
-};
-
-/**
- * Gets one point through which this line travels.
- * @private
- * @return {!o3djs.math.Vector3} A point which through the line
- * travels.
- */
-o3djs.manipulators.Line_.prototype.getPoint = function() {
- return this.point_;
-};
-
-/**
- * Projects a point onto the line.
- * @private
- * @param {!o3djs.math.Vector3} point Point to be projected.
- * @return {!o3djs.math.Vector3} Point on the line closest to the
- * passed point.
- */
-o3djs.manipulators.Line_.prototype.projectPoint = function(point) {
- var dotp = o3djs.math.dot(this.direction_, point);
- return o3djs.math.addVector(this.alongVec_,
- o3djs.math.mulScalarVector(dotp,
- this.direction_));
-};
-
-/**
- * A threshold / error tolerance for determining if a number should be
- * considered zero.
- * @type {!number}
- */
-o3djs.manipulators.EPSILON = 0.00001;
-
-/**
- * A unit vector pointing along the positive X-axis.
- * @type {!o3djs.math.Vector3}
- */
-o3djs.manipulators.X_AXIS = [1, 0, 0];
-
-/**
- * A unit vector pointing along the positive Z-axis.
- * @type {!o3djs.math.Vector3}
- */
-o3djs.manipulators.Z_AXIS = [0, 0, 1];
-
-/**
- * Returns the closest point on this line to the given ray, which is
- * specified by start and end points. If the ray is parallel to the
- * line, returns null.
- * @private
- * @param {!o3djs.math.Vector3} startPoint Start point of ray.
- * @param {!o3djs.math.Vector3} endPoint End point of ray.
- * @return {o3djs.math.Vector3} The closest point on the line to the
- * ray, or null if the ray is parallel to the line.
- */
-o3djs.manipulators.Line_.prototype.closestPointToRay = function(startPoint,
- endPoint) {
- // Consider a two-sided line and a one-sided ray, both in in 3D
- // space, and assume they are not parallel. Their parametric
- // formulation is:
- //
- // p1 = point + t * dir
- // p2 = raystart + u * raydir
- //
- // Here t and u are scalar parameter values, and the other values
- // are three-dimensional vectors. p1 and p2 are arbitrary points on
- // the line and ray, respectively.
- //
- // At the points cp1 and cp2 on these two lines where the line and
- // the ray are closest together, the line segment between cp1 and
- // cp2 is perpendicular to both of the lines.
- //
- // We can therefore write the following equations:
- //
- // dot( dir, (cp2 - cp1)) = 0
- // dot(raydir, (cp2 - cp1)) = 0
- //
- // Define t' and u' as the parameter values for cp1 and cp2,
- // respectively. Expanding, these equations become
- //
- // dot( dir, ((raystart + u' * raydir) - (point + t' * dir))) = 0
- // dot(raydir, ((raystart + u' * raydir) - (point + t' * dir))) = 0
- //
- // With some reshuffling, these can be expressed in vector/matrix
- // form:
- //
- // [ dot( dir, raystart) - dot( dir, point) ]
- // [ dot(raydir, raystart) - dot(raydir, point) ] + (continued)
- //
- // [ -dot( dir, dir) dot( dir, raydir) ] [ t' ] [0]
- // [ -dot(raydir, dir) dot(raydir, raydir) ] * [ u' ] = [0]
- //
- // u' is the parameter for the world space ray being cast into the
- // screen. We can deduce whether the starting point of the ray is
- // actually the closest point to the infinite 3D line by whether the
- // value of u' is less than zero.
- var rayDirection = o3djs.math.subVector(endPoint, startPoint);
- var ddrd = o3djs.math.dot(this.direction_, rayDirection);
- var A = o3djs.math.makeMatrix2(-o3djs.math.lengthSquared(this.direction_),
- ddrd,
- ddrd,
- -o3djs.math.lengthSquared(rayDirection));
- var det = o3djs.math.det2(A);
- if (Math.abs(det) < o3djs.manipulators.EPSILON) {
- return null;
- }
- var Ainv = o3djs.math.inverse2(A);
- var b = [o3djs.math.dot(this.point_, this.direction_) -
- o3djs.math.dot(startPoint, this.direction_),
- o3djs.math.dot(startPoint, rayDirection) -
- o3djs.math.dot(this.point_, rayDirection)];
- var x = o3djs.math.mulMatrixVector(Ainv, b);
- if (x[1] < 0) {
- // Means that start point is closest point to this line
- return startPoint;
- } else {
- return o3djs.math.addVector(this.point_,
- o3djs.math.mulScalarVector(
- x[0],
- this.direction_));
- }
-};
-
-/**
- * Performs internal recalculations when the parameters of the line change.
- * @private
- */
-o3djs.manipulators.Line_.prototype.recalc_ = function() {
- var denom = o3djs.math.lengthSquared(this.direction_);
- if (denom == 0.0) {
- throw 'Line_.recalc_: ERROR: direction was the zero vector (not allowed)';
- }
-
- /**
- * Helper (internal cache) for computing projections along the line.
- * @private
- * @type {!o3djs.math.Vector3}
- */
- this.alongVec_ =
- o3djs.math.subVector(this.point_,
- o3djs.math.mulScalarVector(
- o3djs.math.dot(this.point_,
- this.direction_),
- this.direction_));
-};
-
-/**
- * The default color for manipulators (used when not highlighted).
- * In [r, g, b, a] format.
- * @type {!o3djs.math.Vector4}
- */
-o3djs.manipulators.DEFAULT_COLOR = [0.8, 0.8, 0.8, 1.0];
-
-/**
- * The color used for manipulators when they are highlighted.
- * In [r, g, b, a] format.
- * @type {!o3djs.math.Vector4}
- */
-o3djs.manipulators.HIGHLIGHTED_COLOR = [0.9, 0.9, 0.0, 1.0];
-
-/**
- * Creates a new Plane object.
- * @constructor
- * @private
- * @param {!o3djs.math.Vector3} opt_normal The normal of the
- * plane. Does not need to be unit length, but must not be the zero
- * vector. Defaults to [0, 1, 0] if not specified.
- * @param {!o3djs.math.Vector3} opt_point A point through which the
- * plane passes. Defaults to [0, 0, 0] if not specified.
- */
-o3djs.manipulators.Plane_ = function(opt_normal,
- opt_point) {
- /**
- * A point through which the plane passes.
- * @private
- * @type {!o3djs.math.Vector3}
- */
- this.point_ = o3djs.math.copyVector(opt_point || [0, 0, 0]);
- this.setNormal(opt_normal || [0, 1, 0]);
-};
-
-/**
- * Sets the normal of this plane.
- * @private
- * @param {!o3djs.math.Vector3} normal The new normal of the
- * plane. Does not need to be unit length, but must not be the zero
- * vector.
- */
-o3djs.manipulators.Plane_.prototype.setNormal = function(normal) {
- // Make sure the normal isn't zero.
- var denom = o3djs.math.lengthSquared(normal);
- if (denom == 0.0) {
- throw 'Plane_.setNormal: ERROR: normal was the zero vector (not allowed)';
- }
-
- /**
- * The normal to the plane. Normalized, cannot be zero.
- * @private
- * @type {!o3djs.math.Vector3}
- */
- this.normal_ = o3djs.math.normalize(normal); // Makes copy.
- this.recalc_();
-};
-
-/**
- * Gets the normal of this plane, as a unit vector.
- * @private
- * @return {!o3djs.math.Vector3} The (normalized) normal of the plane.
- */
-o3djs.manipulators.Plane_.prototype.getNormal = function() {
- return this.normal_;
-};
-
-/**
- * Sets one point through which this plane passes.
- * @private
- * @param {!o3djs.math.Vector3} point A point through which the plane passes.
- */
-o3djs.manipulators.Plane_.prototype.setPoint = function(point) {
- this.point_ = o3djs.math.copyVector(point);
- this.recalc_();
-};
-
-/**
- * Gets one point through which this plane passes.
- * @private
- * @return {!o3djs.math.Vector3} A point which through the plane passes.
- */
-o3djs.manipulators.Plane_.prototype.getPoint = function() {
- return this.point_;
-};
-
-/**
- * Projects a point onto the plane.
- * @private
- * @param {!o3djs.math.Vector3} point Point to be projected.
- * @return {!o3djs.math.Vector3} Point on the plane closest to the
- * passed point.
- */
-o3djs.manipulators.Plane_.prototype.projectPoint = function(point) {
- var distFromPlane =
- o3djs.math.dot(this.normal_, point) - this.normalDotPoint_;
- return o3djs.math.subVector(point,
- o3djs.math.mulScalarVector(distFromPlane,
- this.normal_));
-};
-
-/**
- * Intersects a ray with the plane. Returns the point of intersection.
- * This is a two-sided ray cast. If the ray is parallel to the plane,
- * returns null.
- * @private
- * @param {!o3djs.math.Vector3} rayStart Start point of ray.
- * @param {!o3djs.math.Vector3} rayDirection Direction vector of ray.
- * Does not need to be normalized, but must not be the zero vector.
- * @return {o3djs.math.Vector3} The point of intersection of the ray
- * with the plane, or null if the ray is parallel to the plane.
- */
-o3djs.manipulators.Plane_.prototype.intersectRay = function(rayStart,
- rayDirection) {
- var distFromPlane =
- this.normalDotPoint_ - o3djs.math.dot(this.normal_, rayStart);
- var denom = o3djs.math.dot(this.normal_, rayDirection);
- if (denom == 0) {
- return null;
- }
- var t = distFromPlane / denom;
- return o3djs.math.addVector(rayStart,
- o3djs.math.mulScalarVector(t, rayDirection));
-};
-
-/**
- * Performs internal recalculations when the parameters of the plane change.
- * @private
- */
-o3djs.manipulators.Plane_.prototype.recalc_ = function() {
- /**
- * Helper (internal cache) for computing projections into the plane.
- * The dot product between normal_ and point_.
- * @private
- * @type {!number}
- */
- this.normalDotPoint_ = o3djs.math.dot(this.normal_, this.point_);
-};
-
-/**
- * Constructs a new manipulator manager. Do not call this directly;
- * use o3djs.manipulators.createManager instead.
- * @constructor
- * @param {!o3d.Pack} pack Pack in which manipulators' geometry and
- * materials will be created.
- * @param {!o3d.Transform} parentTransform The parent transform under
- * which the manipulators' geometry should be parented.
- * @param {!o3d.RenderNode} parentRenderNode The parent render node
- * under which the manipulators' draw elements should be placed.
- * @param {number} renderNodePriority The priority that the
- * manipulators' geometry should use for rendering.
- * @param {!o3d.DrawContext} drawContext The DrawContext to use for the
- * manipulators.
- */
-o3djs.manipulators.Manager = function(pack,
- parentTransform,
- parentRenderNode,
- renderNodePriority,
- drawContext) {
- /**
- * Pack in which manipulators' geometry and materials are created.
- * @type {!o3d.Pack}
- */
- this.pack = pack;
- /**
- * The ViewInfo used to render the manipulators.
- * @type {!o3djs.rendergraph.ViewInfo}
- */
- this.viewInfo = o3djs.rendergraph.createView(
- pack,
- parentTransform,
- parentRenderNode,
- undefined, // clearColor
- renderNodePriority, // priority
- undefined, // viewport
- undefined, // performanceDrawList
- undefined, // zOrderedDrawList
- drawContext);
-
- // Turn off clearing the color for the manipulators.
- this.viewInfo.clearBuffer.active = false;
-
- // Set the ZComparisonFunction to the opposite of normal so we only
- // draw when we should be obscured for the obscured DrawList.
- var state = this.viewInfo.zOrderedState;
- state.getStateParam('ZComparisonFunction').value =
- o3djs.base.o3d.State.CMP_GREATER;
- // Disable depth writing, otherwise the second pass will have a
- // screwed up depth buffer, and will draw when it shouldn't.
- state.getStateParam('ZWriteEnable').value = false;
-
- // Swap the priorities of the DrawPasses so they get drawn in the
- // opposite order
- var temp = this.viewInfo.performanceDrawPassInfo.root.priority;
- this.viewInfo.performanceDrawPassInfo.root.priority =
- this.viewInfo.zOrderedDrawPassInfo.root.priority
- this.viewInfo.zOrderedDrawPassInfo.root.priority = temp;
-
- // The following two DrawLists are used to render manipulators. We give each
- // manipulator 2 DrawElements so they get drawn twice. Once they are
- // drawn with the reverse of the normal zBuffer test so that only the parts
- // of the manipulator that would be obscured by zbuffering are drawn. Then we
- // draw them again with normal zBuffering test so that the parts that are not
- // obscured get drawn as normal. This allows the obscured parts
- // of the manipulators to be rendered with a different material.
-
- // POTENTIAL PROBLEM: Since we reverse the depth comparison function (and
- // disable depth writing) for the obscured rendering pass, those objects will
- // not have their proper faces showing. So they will look wrong unless we use
- // a constant shader. One possible solution would be to set the stencil
- // buffer to indicate obscured/unobscured, so that we are free to use the
- // depth buffer normally.
-
- /**
- * The DrawList we use to render manipulators that are unobscured by the main
- * scene.
- * @private
- * @type {!o3d.DrawList}
- */
- this.unobscuredDrawList_ = this.viewInfo.performanceDrawList;
-
- /**
- * The DrawList we use to render manipulators that are obscured by the main
- * scene.
- * @private
- * @type {!o3d.DrawList}
- */
- this.obscuredDrawList_ = this.viewInfo.zOrderedDrawList;
-
- /**
- * The parent transform under which the manipulators' geometry
- * shall be parented.
- * @type {!o3d.Transform}
- */
- this.parentTransform = parentTransform;
-
- /**
- * A map from the manip's parent Transform clientId to the manip.
- * @type {!Array.<!o3djs.manipulators.Manip>}
- */
- this.manipsByClientId = [];
-
- /**
- * A PickManager to manage picking for the manipulators.
- * @type {!o3djs.picking.PickManager}
- */
- this.pickManager = o3djs.picking.createPickManager(this.parentTransform);
-
- /**
- * The currently-highlighted manipulator.
- * @type {o3djs.manipulators.Manip}
- */
- this.highlightedManip = null;
-
- /**
- * The manipulator currently being dragged.
- * @private
- * @type {o3djs.manipulators.Manip}
- */
- this.draggedManip_ = null;
-};
-
-/**
- * Gets the constant-color material used for the parts of manipulators that are
- * in front of other objects in the scene.
- * @return {!o3d.Material} A material.
- */
-o3djs.manipulators.Manager.prototype.getUnobscuredConstantMaterial = function() {
- if (!this.unobscuredConstantMaterial_) {
- this.unobscuredConstantMaterial_ =
- o3djs.manipulators.createConstantMaterial(
- this.pack, this.unobscuredDrawList_, [1, 1, 1, 0.8]);
- }
- return this.unobscuredConstantMaterial_;
-};
-
-/**
- * Gets the constant-color material used for the parts of manipulators that are
- * behind other objects in the scene.
- * @return {!o3d.Material} A material.
- */
-o3djs.manipulators.Manager.prototype.getObscuredConstantMaterial = function() {
- if (!this.obscuredConstantMaterial_) {
- this.obscuredConstantMaterial_ =
- o3djs.manipulators.createConstantMaterial(
- this.pack, this.obscuredDrawList_, [1, 1, 1, 0.3]);
- }
- return this.obscuredConstantMaterial_;
-};
-
-/**
- * Gets the material used for the parts of line ring manipulators that are
- * in front of other objects in the scene.
- * @return {!o3d.Material} A material.
- */
-o3djs.manipulators.Manager.prototype.getUnobscuredLineRingMaterial =
- function() {
- if (!this.unobscuredLineRingMaterial_) {
- this.unobscuredLineRingMaterial_ =
- o3djs.manipulators.createLineRingMaterial(
- this.pack, this.unobscuredDrawList_,
- [1, 1, 1, 1], [1, 1, 1, 0.6], false);
- }
- return this.unobscuredLineRingMaterial_;
-};
-
-/**
- * Gets the material used for the parts of line ring manipulators that are
- * behind other objects in the scene.
- * @return {!o3d.Material} A material.
- */
-o3djs.manipulators.Manager.prototype.getObscuredLineRingMaterial = function() {
- if (!this.obscuredLineRingMaterial_) {
- this.obscuredLineRingMaterial_ = o3djs.manipulators.createLineRingMaterial(
- this.pack, this.obscuredDrawList_,
- [1, 1, 1, 0.5], [1, 1, 1, 0.3], true);
- }
- return this.obscuredLineRingMaterial_;
-};
-
-/**
- * Creates a new Translate1 manipulator. A Translate1 moves along the
- * X axis in its local coordinate system.
- * @return {!o3djs.manipulators.Translate1} A new Translate1 manipulator.
- */
-o3djs.manipulators.Manager.prototype.createTranslate1 = function() {
- var manip = new o3djs.manipulators.Translate1(this);
- this.add_(manip);
- return manip;
-};
-
-/**
- * Creates a new Translate2 manipulator. A Translate2 moves around the
- * XY plane in its local coordinate system.
- * @return {!o3djs.manipulators.Translate2} A new Translate2 manipulator.
- */
-o3djs.manipulators.Manager.prototype.createTranslate2 = function() {
- var manip = new o3djs.manipulators.Translate2(this);
- this.add_(manip);
- return manip;
-};
-
-/**
- * Creates a new Rotate1 manipulator. A Rotate1 rotates about the
- * X axis in its local coordinate system.
- * @return {!o3djs.manipulators.Rotate1} A new Rotate1 manipulator.
- */
-o3djs.manipulators.Manager.prototype.createRotate1 = function() {
- var manip = new o3djs.manipulators.Rotate1(this);
- this.add_(manip);
- return manip;
-};
-
-/**
- * Adds a manipulator to this manager's set.
- * @private
- * @param {!o3djs.manipulators.Manip} manip The manipulator to add.
- */
-o3djs.manipulators.Manager.prototype.add_ = function(manip) {
- // Generate draw elements for the manipulator's transform
- manip.getTransform().createDrawElements(this.pack, null);
- // Add the manipulator into our managed list
- this.manipsByClientId[manip.getTransform().clientId] = manip;
-};
-
-/**
- * Event handler for multiple kinds of mouse events.
- * @private
- * @param {number} x The x coordinate of the mouse event.
- * @param {number} y The y coordinate of the mouse event.
- * @param {!o3djs.math.Matrix4} view The current view matrix.
- * @param {!o3djs.math.Matrix4} projection The current projection matrix.
- * @param {number} width The width of the viewport.
- * @param {number} height The height of the viewport.
- * @param {!function(!o3djs.manipulators.Manager,
- * o3djs.picking.PickInfo, o3djs.manipulators.Manip): void} func
- * Callback function. Always receives the manager as argument; if
- * a manipulator was picked, receives non-null PickInfo and Manip
- * arguments, otherwise receives null for both of these arguments.
- */
-o3djs.manipulators.Manager.prototype.handleMouse_ = function(x,
- y,
- view,
- projection,
- width,
- height,
- func) {
- this.pickManager.update();
-
- // Create the world ray
- var worldRay =
- o3djs.picking.clientPositionToWorldRayEx(x, y,
- view, projection,
- width, height);
-
- // Pick against all of the manipulators' geometry
- var pickResult = this.pickManager.pick(worldRay);
- if (pickResult != null) {
- // Find which manipulator we picked.
- // NOTE this assumes some things about the transform graph
- // structure of the manipulators.
- // We may need to index by the parent-parent transform instead, since the
- // shape could be attached to the manip's invisibleTransform_, which is a
- // child of the localTransform_.
- var manip =
- this.manipsByClientId[pickResult.shapeInfo.parent.transform.clientId] ||
- this.manipsByClientId[
- pickResult.shapeInfo.parent.parent.transform.clientId];
- func(this, pickResult, manip);
- } else {
- func(this, null, null);
- }
-};
-
-/**
- * Callback handling the mouse-down event on a manipulator.
- * @private
- * @param {!o3djs.manipulators.Manager} manager The manipulator
- * manager owning the given manipulator.
- * @param {o3djs.picking.PickInfo} pickResult The picking information
- * associated with the mouse-down event.
- * @param {o3djs.manipulators.Manip} manip The manipulator to be
- * selected.
- */
-o3djs.manipulators.mouseDownCallback_ = function(manager,
- pickResult,
- manip) {
- if (manip != null) {
- manager.draggedManip_ = manip;
- manip.makeActive(pickResult);
- }
-};
-
-/**
- * Callback handling the mouse-over event on a manipulator.
- * @private
- * @param {!o3djs.manipulators.Manager} manager The manipulator
- * manager owning the given manipulator.
- * @param {o3djs.picking.PickInfo} pickResult The picking information
- * associated with the mouse-over event.
- * @param {o3djs.manipulators.Manip} manip The manipulator to be
- * highlighted.
- */
-o3djs.manipulators.hoverCallback_ = function(manager,
- pickResult,
- manip) {
- if (manager.highlightedManip != null &&
- manager.highlightedManip != manip) {
- // Un-highlight the previously highlighted manipulator
- manager.highlightedManip.clearHighlight();
- manager.highlightedManip = null;
- }
-
- if (manip != null) {
- manip.highlight(pickResult);
- manager.highlightedManip = manip;
- }
-};
-
-/**
- * Method which should be called by end user code upon receiving a
- * mouse-down event.
- * @param {number} x The x coordinate of the mouse event.
- * @param {number} y The y coordinate of the mouse event.
- * @param {!o3djs.math.Matrix4} view The current view matrix.
- * @param {!o3djs.math.Matrix4} projection The current projection matrix.
- * @param {number} width The width of the viewport.
- * @param {number} height The height of the viewport.
- */
-o3djs.manipulators.Manager.prototype.mousedown = function(x,
- y,
- view,
- projection,
- width,
- height) {
- this.handleMouse_(x, y, view, projection, width, height,
- o3djs.manipulators.mouseDownCallback_);
-};
-
-/**
- * Method which should be called by end user code upon receiving a
- * mouse motion event.
- * @param {number} x The x coordinate of the mouse event.
- * @param {number} y The y coordinate of the mouse event.
- * @param {!o3djs.math.Matrix4} view The current view matrix.
- * @param {!o3djs.math.Matrix4} projection The current projection matrix.
- * @param {number} width The width of the viewport.
- * @param {number} height The height of the viewport.
- */
-o3djs.manipulators.Manager.prototype.mousemove = function(x,
- y,
- view,
- projection,
- width,
- height) {
- if (this.draggedManip_ != null) {
- var worldRay =
- o3djs.picking.clientPositionToWorldRayEx(x, y,
- view, projection,
- width, height);
- this.draggedManip_.drag(worldRay.near, worldRay.far,
- x, y, view, projection, width, height);
- } else {
- this.handleMouse_(x, y, view, projection, width, height,
- o3djs.manipulators.hoverCallback_);
- }
-};
-
-/**
- * Method which should be called by end user code upon receiving a
- * mouse-up event.
- */
-o3djs.manipulators.Manager.prototype.mouseup = function() {
- if (this.draggedManip_ != null) {
- this.draggedManip_.makeInactive();
- this.draggedManip_ = null;
- }
-};
-
-/**
- * Method which should be called by end user code, typically in
- * response to mouse move events, to update the transforms of
- * manipulators which might have been moved either because of
- * manipulators further up the hierarchy, or programmatic changes to
- * transforms.
- */
-o3djs.manipulators.Manager.prototype.updateInactiveManipulators = function() {
- for (var ii in this.manipsByClientId) {
- var manip = this.manipsByClientId[ii];
- if (!manip.isActive()) {
- manip.updateBaseTransformFromAttachedTransform_();
- }
- }
-};
-
-/**
- * Base class for all manipulators.
- * @constructor
- * @param {!o3djs.manipulators.Manager} manager The manager of this
- * manipulator.
- */
-o3djs.manipulators.Manip = function(manager) {
- /**
- * The manager of this manipulator.
- * @private
- * @type {!o3djs.manipulators.Manager}
- */
- this.manager_ = manager;
- var pack = manager.pack;
-
- /**
- * This transform holds the local transformation of the manipulator,
- * which is either applied to the transform to which it is attached,
- * or (see below) consumed by the user in the manipulator's
- * callbacks. After each interaction, if there is an attached
- * transform, this local transform is added in to it and reset to
- * the identity.
- * TODO(kbr): add support for user callbacks on manipulators.
- * @private
- * @type {!o3d.Transform}
- */
- this.localTransform_ = pack.createObject('Transform');
-
- /**
- * This transform provides an offset, if desired, between the
- * manipulator's geometry and the transform (and, implicitly, the
- * shape) to which it is attached. This allows the manipulator to be
- * easily placed below an object, for example.
- * @private
- * @type {!o3d.Transform}
- */
- this.offsetTransform_ = pack.createObject('Transform');
-
- /**
- * This transform is the one which is actually parented to the
- * manager's parentTransform. It is used to place the manipulator in
- * world space, regardless of the world space location of the
- * parentTransform supplied to the manager. If this manipulator is
- * attached to a given transform, then upon completion of a
- * particular drag interaction, this transform is adjusted to take
- * into account the attached transform's new value.
- * @private
- * @type {!o3d.Transform}
- */
- this.baseTransform_ = pack.createObject('Transform');
-
- /**
- * This child transform is used only to hold any invisible shapes
- * we may want. Invisible shapes can be useful for picking. Visibility is
- * controlled by the transform, which is why we need this transform.
- * The local matrix of this transform should only be the identity matrix.
- * @private
- * @type {!o3d.Transform}
- */
- this.invisibleTransform_ = pack.createObject('Transform');
- this.invisibleTransform_.visible = false;
-
- // Hook up these transforms
- this.invisibleTransform_.parent = this.localTransform_;
- this.localTransform_.parent = this.offsetTransform_;
- this.offsetTransform_.parent = this.baseTransform_;
- this.baseTransform_.parent = manager.parentTransform;
-
- // Make the invisible transform pickable even though it's invisible
- manager.pickManager.update();
- var invisibleTransformInfo = manager.pickManager.getTransformInfo(
- this.invisibleTransform_);
- invisibleTransformInfo.pickableEvenIfInvisible = true;
-
- /**
- * This is the transform in the scene graph to which this
- * manipulator is conceptually "attached", and whose local transform
- * we are modifying.
- * @private
- * @type {o3d.Transform}
- */
- this.attachedTransform_ = null;
-
- /**
- * Whether this manipulator is active (ie being dragged).
- * @private
- * @type {boolean}
- */
- this.active_ = false;
-};
-
-/**
- * Adds shapes to the internal transform of this manipulator.
- * @private
- * @param {!Array.<!o3d.Shape>} shapes Array of shapes to add.
- * @param {boolean} opt_visible Whether the added shapes should be visible.
- * Default = true. Invisible geometry can be useful for picking.
- */
-o3djs.manipulators.Manip.prototype.addShapes_ = function(shapes, opt_visible) {
- if (opt_visible == undefined) {
- opt_visible = true;
- }
- for (var ii = 0; ii < shapes.length; ii++) {
- if(opt_visible) {
- this.localTransform_.addShape(shapes[ii]);
- } else {
- this.invisibleTransform_.addShape(shapes[ii]);
- }
- }
-};
-
-/**
- * Returns the "base" transform of this manipulator, which places the
- * origin of the manipulator at the local origin of the attached
- * transform.
- * @private
- * @return {!o3d.Transform} The base transform of this manipulator.
- */
-o3djs.manipulators.Manip.prototype.getBaseTransform_ = function() {
- return this.baseTransform_;
-};
-
-/**
- * Returns the "offset" transform of this manipulator, which allows
- * the manipulator's geometry to be moved or rotated with respect to
- * the local origin of the attached transform.
- * @return {!o3d.Transform} The offset transform of this manipulator.
- */
-o3djs.manipulators.Manip.prototype.getOffsetTransform = function() {
- return this.offsetTransform_;
-};
-
-/**
- * Returns the local transform of this manipulator, which contains the
- * changes that have been made in response to the current drag
- * operation. Upon completion of the drag, this transform's effects
- * are composed in to the attached transform, and this transform is
- * reset to the identity.
- * @return {!o3d.Transform} The local transform of this manipulator.
- */
-o3djs.manipulators.Manip.prototype.getTransform = function() {
- return this.localTransform_;
-};
-
-/**
- * Sets the translation component of the offset transform. This is
- * useful for moving the manipulator's geometry with respect to the
- * local origin of the attached transform.
- * @param {!o3djs.math.Vector3} translation The offset translation for
- * this manipulator.
- */
-o3djs.manipulators.Manip.prototype.setOffsetTranslation =
- function(translation) {
- this.getOffsetTransform().localMatrix =
- o3djs.math.matrix4.setTranslation(this.getOffsetTransform().localMatrix,
- translation);
-};
-
-/**
- * Sets the rotation component of the offset transform. This is useful
- * for orienting the manipulator's geometry with respect to the local
- * origin of the attached transform.
- * @param {!o3djs.quaternions.Quaternion} quaternion The offset
- * rotation for this manipulator.
- */
-o3djs.manipulators.Manip.prototype.setOffsetRotation = function(quaternion) {
- var rot = o3djs.quaternions.quaternionToRotation(quaternion);
- this.getOffsetTransform().localMatrix =
- o3djs.math.matrix4.setUpper3x3(this.getOffsetTransform().localMatrix,
- rot);
-};
-
-/**
- * Explicitly sets the local translation of this manipulator.
- * (TODO(kbr): it is not clear that this capability should be in the
- * API.)
- * @param {!o3djs.math.Vector3} translation The local translation for
- * this manipulator.
- */
-o3djs.manipulators.Manip.prototype.setTranslation = function(translation) {
- this.getTransform().localMatrix =
- o3djs.math.matrix4.setTranslation(this.getTransform().localMatrix,
- translation);
-};
-
-/**
- * Explicitly sets the local rotation of this manipulator. (TODO(kbr):
- * it is not clear that this capability should be in the API.)
- * @param {!o3djs.quaternions.Quaternion} quaternion The local
- * rotation for this manipulator.
- */
-o3djs.manipulators.Manip.prototype.setRotation = function(quaternion) {
- var rot = o3djs.quaternions.quaternionToRotation(quaternion);
- this.getTransform().localMatrix =
- o3djs.math.matrix4.setUpper3x3(this.getTransform().localMatrix,
- rot);
-};
-
-/**
- * Attaches this manipulator to the given transform. Interactions with
- * the manipulator will cause this transform's local matrix to be
- * modified appropriately.
- * @param {!o3d.Transform} transform The transform to which this
- * manipulator should be attached.
- */
-o3djs.manipulators.Manip.prototype.attachTo = function(transform) {
- this.attachedTransform_ = transform;
- // Update our base transform to place the manipulator at exactly the
- // location of the attached transform.
- this.updateBaseTransformFromAttachedTransform_();
-};
-
-/**
- * Highlights this manipulator according to the given pick result.
- * @param {o3djs.picking.PickInfo} pickResult The pick result which
- * caused this manipulator to become highlighted.
- */
-o3djs.manipulators.Manip.prototype.highlight = function(pickResult) {
-};
-
-/**
- * Clears any highlight for this manipulator.
- */
-o3djs.manipulators.Manip.prototype.clearHighlight = function() {
-};
-
-/**
- * Activates this manipulator according to the given pick result. In
- * complex manipulators, picking different portions of the manipulator
- * may result in different forms of interaction.
- * @param {o3djs.picking.PickInfo} pickResult The pick result which
- * caused this manipulator to become active.
- */
-o3djs.manipulators.Manip.prototype.makeActive = function(pickResult) {
- this.active_ = true;
-};
-
-/**
- * Deactivates this manipulator.
- */
-o3djs.manipulators.Manip.prototype.makeInactive = function() {
- this.active_ = false;
-};
-
-/**
- * Drags this manipulator according to the world-space ray specified
- * by startPoint and endPoint, or alternatively the screen space mouse
- * coordinate specified by x and y. makeActive must already have been
- * called with the initial pick result causing this manipulator to
- * become active.
- * @param {!o3djs.math.Vector3} startPoint Start point of the
- * world-space ray through the current mouse position.
- * @param {!o3djs.math.Vector3} endPoint End point of the world-space
- * ray through the current mouse position.
- * @param {number} x The x coordinate of the current mouse position.
- * @param {number} y The y coordinate of the current mouse position.
- * @param {!o3djs.math.Matrix4} view The current view matrix.
- * @param {!o3djs.math.Matrix4} projection The current projection matrix.
- * @param {number} width The width of the viewport.
- * @param {number} height The height of the viewport.
- */
-o3djs.manipulators.Manip.prototype.drag = function(startPoint,
- endPoint,
- x,
- y,
- view,
- projection,
- width,
- height) {
-};
-
-/**
- * Indicates whether this manipulator is active.
- * @return {boolean} Whether this manipulator is active.
- */
-o3djs.manipulators.Manip.prototype.isActive = function() {
- return this.active_;
-};
-
-/**
- * Updates the base transform of this manipulator from the state of
- * its attached transform, resetting the local transform of this
- * manipulator to the identity.
- * @private
- */
-o3djs.manipulators.Manip.prototype.updateBaseTransformFromAttachedTransform_ =
- function() {
- if (this.attachedTransform_ != null) {
- var attWorld = this.attachedTransform_.worldMatrix;
- var parWorld = this.manager_.parentTransform.worldMatrix;
- var parWorldInv = o3djs.math.matrix4.inverse(parWorld);
- this.baseTransform_.localMatrix =
- o3djs.math.matrix4.mul(attWorld, parWorldInv);
- // Reset the manipulator's local matrix to the identity.
- this.localTransform_.localMatrix = o3djs.math.matrix4.identity();
- }
-};
-
-/**
- * Updates this manipulator's attached transform based on the values
- * in the local transform.
- * @private
- */
-o3djs.manipulators.Manip.prototype.updateAttachedTransformFromLocalTransform_ =
- function() {
- if (this.attachedTransform_ != null) {
- // Compute the composition of the base and local transforms.
- // The offset transform is skipped except for transforming the
- // effect of the local matrix through the offset transform.
- var base = this.baseTransform_.worldMatrix;
- var offset = this.offsetTransform_.localMatrix;
- var local = this.localTransform_.localMatrix;
- var offsetInv = o3djs.math.matrix4.inverse(offset);
- // We want totalMat = offsetInv * local * offset * base.
- var totalMat = o3djs.math.matrix4.mul(offsetInv, local);
- totalMat = o3djs.math.matrix4.mul(totalMat, offset);
- totalMat = o3djs.math.matrix4.mul(totalMat, base);
-
- // Set this into the attached transform, taking into account its
- // parent's transform, if any.
- // Note that we can not query the parent's transform directly, so
- // we compute it using a little trick.
- var attWorld = this.attachedTransform_.worldMatrix;
- var attLocal = this.attachedTransform_.localMatrix;
- var attParentMat =
- o3djs.math.matrix4.mul(o3djs.math.matrix4.inverse(attLocal),
- attWorld);
- // Now we can take the inverse of this matrix
- var attParentMatInv = o3djs.math.matrix4.inverse(attParentMat);
- totalMat = o3djs.math.matrix4.mul(totalMat, attParentMatInv);
- this.attachedTransform_.localMatrix = totalMat;
- }
-};
-
-/**
- * Sets the material of the given shape's draw elements.
- * TODO(simonrad): This function is not used, remove it?
- * @private
- * @param {!o3d.Shape} shape Shape to modify the material of.
- * @param {!o3d.Material} material Material to set.
- */
-o3djs.manipulators.Manip.prototype.setMaterial_ = function(shape, material) {
- var elements = shape.elements;
- for (var ii = 0; ii < elements.length; ii++) {
- var drawElements = elements[ii].drawElements;
- for (var jj = 0; jj < drawElements.length; jj++) {
- drawElements[jj].material = material;
- }
- }
-};
-
-/**
- * Sets the materials of the given shapes' draw elements.
- * TODO(simonrad): This function is not used, remove it?
- * @private
- * @param {!Array.<!o3d.Shape>} shapes Array of shapes to modify the materials of.
- * @param {!o3d.Material} material Material to set.
- */
-o3djs.manipulators.Manip.prototype.setMaterials_ = function(shapes, material) {
- for (var ii = 0; ii < shapes.length; ii++) {
- this.setMaterial_(shapes[ii], material);
- }
-};
-
-/**
- * Create the geometry for a double-ended arrow going from
- * (0, -1, 0) to (0, 1, 0), transformed by the given matrix.
- * @private
- * @param {!o3djs.math.Matrix4} matrix A matrix by which to multiply
- * all the vertices.
- * @return {!o3djs.primitives.VertexInfo} The created vertices.
- */
-o3djs.manipulators.createArrowVertices_ = function(matrix) {
- var matrix4 = o3djs.math.matrix4;
-
- var verts = o3djs.primitives.createTruncatedConeVertices(
- 0.15, // Bottom radius.
- 0.0, // Top radius.
- 0.3, // Height.
- 4, // Number of radial subdivisions.
- 1, // Number of vertical subdivisions.
- matrix4.mul(matrix4.translation([0, 0.85, 0]), matrix));
-
- verts.append(o3djs.primitives.createCylinderVertices(
- 0.06, // Radius.
- 1.4, // Height.
- 4, // Number of radial subdivisions.
- 1, // Number of vertical subdivisions.
- matrix));
-
- verts.append(o3djs.primitives.createTruncatedConeVertices(
- 0.0, // Bottom radius.
- 0.15, // Top radius.
- 0.3, // Height.
- 4, // Number of radial subdivisions.
- 1, // Number of vertical subdivisions.
- matrix4.mul(matrix4.translation([0, -0.85, 0]), matrix)));
-
- return verts;
-};
-
-/**
- * A manipulator allowing an object to be dragged along a line.
- * A Translate1 moves along the X axis in its local coordinate system.
- * @constructor
- * @extends {o3djs.manipulators.Manip}
- * @param {!o3djs.manipulators.Manager} manager The manager for the
- * new Translate1 manipulator.
- */
-o3djs.manipulators.Translate1 = function(manager) {
- o3djs.manipulators.Manip.call(this, manager);
-
- var pack = manager.pack;
-
- var shape = manager.translate1Shape_;
- if (!shape) {
- // Create the geometry for the manipulator, which looks like a
- // two-way arrow going from (-1, 0, 0) to (1, 0, 0).
- var verts = o3djs.manipulators.createArrowVertices_(
- o3djs.math.matrix4.rotationZ(Math.PI / 2));
- shape = verts.createShape(pack, manager.getUnobscuredConstantMaterial());
- // Add a second DrawElement to this shape to draw it a second time
- // with a different material when it's obscured.
- shape.createDrawElements(pack, manager.getObscuredConstantMaterial());
- manager.translate1Shape_ = shape;
- }
-
- this.addShapes_([ shape ]);
-
- /**
- * A parameter added to our transform to be able to change the
- * material's color for highlighting.
- * @private
- * @type {!o3d.ParamFloat4}
- */
- this.colorParam_ = this.getTransform().createParam('highlightColor',
- 'ParamFloat4');
- this.clearHighlight();
-
- /**
- * Line along which we are dragging.
- * @private
- * @type {!o3djs.manipulators.Line_}
- */
- this.dragLine_ = new o3djs.manipulators.Line_();
-};
-
-o3djs.base.inherit(o3djs.manipulators.Translate1, o3djs.manipulators.Manip);
-
-o3djs.manipulators.Translate1.prototype.highlight = function(pickResult) {
- // We can use instanced geometry for the entire Translate1 since its
- // entire color changes during highlighting.
- // TODO(kbr): support custom user geometry and associated callbacks.
- this.colorParam_.value = o3djs.manipulators.HIGHLIGHTED_COLOR;
-};
-
-o3djs.manipulators.Translate1.prototype.clearHighlight = function() {
- this.colorParam_.value = o3djs.manipulators.DEFAULT_COLOR;
-};
-
-o3djs.manipulators.Translate1.prototype.makeActive = function(pickResult) {
- o3djs.manipulators.Manip.prototype.makeActive.call(this, pickResult);
- this.highlight(pickResult);
- var localToWorld = this.getTransform().worldMatrix;
- this.dragLine_.setDirection(
- o3djs.math.matrix4.transformDirection(localToWorld,
- o3djs.manipulators.X_AXIS));
- this.dragLine_.setPoint(pickResult.worldIntersectionPosition);
-};
-
-o3djs.manipulators.Translate1.prototype.makeInactive = function() {
- o3djs.manipulators.Manip.prototype.makeInactive.call(this);
- this.clearHighlight();
- this.updateAttachedTransformFromLocalTransform_();
- this.updateBaseTransformFromAttachedTransform_();
-};
-
-o3djs.manipulators.Translate1.prototype.drag = function(startPoint,
- endPoint,
- x,
- y,
- view,
- projection,
- width,
- height) {
- // Algorithm: Find closest point of ray to dragLine_. Subtract this
- // point from the line's point to find difference vector; transform
- // from world to local coordinates to find new local offset of
- // manipulator.
- var closestPoint = this.dragLine_.closestPointToRay(startPoint, endPoint);
- if (closestPoint == null) {
- // Drag axis is parallel to ray. Punt.
- return;
- }
- // Need to do a world-to-local transformation on the difference vector.
- // Note that we also incorporate the translation portion of the matrix.
- var diffVector =
- o3djs.math.subVector(closestPoint, this.dragLine_.getPoint());
- var worldToLocal =
- o3djs.math.matrix4.inverse(this.getTransform().worldMatrix);
- this.getTransform().localMatrix =
- o3djs.math.matrix4.setTranslation(
- this.getTransform().localMatrix,
- o3djs.math.matrix4.transformDirection(worldToLocal,
- diffVector));
- this.updateAttachedTransformFromLocalTransform_();
-};
-
-/**
- * A manipulator allowing an object to be dragged around a plane.
- * A Translate2 moves around the XY plane in its local coordinate system.
- * @constructor
- * @extends {o3djs.manipulators.Manip}
- * @param {!o3djs.manipulators.Manager} manager The manager for the
- * new Translate2 manipulator.
- */
-o3djs.manipulators.Translate2 = function(manager) {
- o3djs.manipulators.Manip.call(this, manager);
-
- var pack = manager.pack;
-
- var shape = manager.Translate2Shape_;
- if (!shape) {
- // Create the geometry for the manipulator, which looks like
- // a two-way arrow going from (-1, 0, 0) to (1, 0, 0),
- // and another one going from (0, -1, 0) to (0, 1, 0).
- var verts = o3djs.manipulators.createArrowVertices_(
- o3djs.math.matrix4.rotationZ(Math.PI / 2));
- verts.append(o3djs.manipulators.createArrowVertices_(
- o3djs.math.matrix4.rotationZ(0)));
- shape = verts.createShape(pack, manager.getUnobscuredConstantMaterial());
- // Add a second DrawElement to this shape to draw it a second time
- // with a different material when it's obscured.
- shape.createDrawElements(pack, manager.getObscuredConstantMaterial());
- manager.Translate2Shape_ = shape;
- }
-
- this.addShapes_([ shape ]);
-
- /**
- * A parameter added to our transform to be able to change the
- * material's color for highlighting.
- * @private
- * @type {!o3d.ParamFloat4}
- */
- this.colorParam_ = this.getTransform().createParam('highlightColor',
- 'ParamFloat4');
- this.clearHighlight();
-
- /**
- * Plane through which we are dragging.
- * @private
- * @type {!o3djs.manipulators.Plane_}
- */
- this.dragPlane_ = new o3djs.manipulators.Plane_();
-};
-
-o3djs.base.inherit(o3djs.manipulators.Translate2, o3djs.manipulators.Manip);
-
-o3djs.manipulators.Translate2.prototype.highlight = function(pickResult) {
- // We can use instanced geometry for the entire Translate2 since its
- // entire color changes during highlighting.
- // TODO(kbr): support custom user geometry and associated callbacks.
- this.colorParam_.value = o3djs.manipulators.HIGHLIGHTED_COLOR;
-};
-
-o3djs.manipulators.Translate2.prototype.clearHighlight = function() {
- this.colorParam_.value = o3djs.manipulators.DEFAULT_COLOR;
-};
-
-o3djs.manipulators.Translate2.prototype.makeActive = function(pickResult) {
- o3djs.manipulators.Manip.prototype.makeActive.call(this, pickResult);
- this.highlight(pickResult);
- var localToWorld = this.getTransform().worldMatrix;
- this.dragPlane_.setNormal(
- o3djs.math.matrix4.transformDirection(localToWorld,
- o3djs.manipulators.Z_AXIS));
- this.dragPlane_.setPoint(pickResult.worldIntersectionPosition);
-};
-
-o3djs.manipulators.Translate2.prototype.makeInactive = function() {
- o3djs.manipulators.Manip.prototype.makeInactive.call(this);
- this.clearHighlight();
- this.updateAttachedTransformFromLocalTransform_();
- this.updateBaseTransformFromAttachedTransform_();
-};
-
-o3djs.manipulators.Translate2.prototype.drag = function(startPoint,
- endPoint,
- x,
- y,
- view,
- projection,
- width,
- height) {
- // Algorithm: Find intersection of ray with dragPlane_. Subtract this
- // point from the plane's point to find difference vector; transform
- // from world to local coordinates to find new local offset of
- // manipulator.
- var intersectPoint = this.dragPlane_.intersectRay(startPoint,
- o3djs.math.subVector(endPoint, startPoint));
- if (intersectPoint == null) {
- // Drag plane is parallel to ray. Punt.
- return;
- }
- // Need to do a world-to-local transformation on the difference vector.
- // Note that we also incorporate the translation portion of the matrix.
- var diffVector =
- o3djs.math.subVector(intersectPoint, this.dragPlane_.getPoint());
- var worldToLocal =
- o3djs.math.matrix4.inverse(this.getTransform().worldMatrix);
- this.getTransform().localMatrix =
- o3djs.math.matrix4.setTranslation(
- this.getTransform().localMatrix,
- o3djs.math.matrix4.transformDirection(worldToLocal,
- diffVector));
- this.updateAttachedTransformFromLocalTransform_();
-};
-
-/**
- * A manipulator allowing an object to be rotated about a single axis.
- * A Rotate1 rotates about the X axis in its local coordinate system.
- * @constructor
- * @extends {o3djs.manipulators.Manip}
- * @param {!o3djs.manipulators.Manager} manager The manager for the
- * new Rotate1 manipulator.
- */
-o3djs.manipulators.Rotate1 = function(manager) {
- o3djs.manipulators.Manip.call(this, manager);
-
- var pack = manager.pack;
-
- var pickShape = manager.Rotate1PickShape_;
- if (!pickShape) {
- // Create the polygon geometry for picking the manipulator, which looks like
- // a torus centered at the origin, with the X axis as its vertical axis.
- var verts = o3djs.primitives.createTorusVertices(
- 1.0,
- 0.1,
- 16,
- 6,
- o3djs.math.matrix4.rotationZ(Math.PI / 2));
- pickShape = verts.createShape(pack, manager.getUnobscuredConstantMaterial());
- manager.Rotate1PickShape_ = pickShape;
- }
-
- var visibleShape = manager.Rotate1VisibleShape_;
- if (!visibleShape) {
- // Create the line geometry for displaying the manipulator, which looks like
- // a ring centered at the origin, with the X axis as its vertical axis.
- var verts = o3djs.lineprimitives.createLineRingVertices(
- 1.0, // radius
- 32, // subdivisions
- 120, // maxTexCoord (this determines the number of stipples)
- o3djs.math.matrix4.rotationZ(Math.PI / 2)); // opt_matrix
- visibleShape = verts.createShape(pack,
- manager.getUnobscuredLineRingMaterial());
- // Add a second DrawElement to this shape to draw it a second time
- // with a different material when it's obscured.
- visibleShape.createDrawElements(
- pack, manager.getObscuredLineRingMaterial());
- manager.Rotate1VisibleShape_ = visibleShape;
- }
-
- this.addShapes_([ pickShape ], false); // Invisible
- this.addShapes_([ visibleShape ]);
-
- /**
- * A parameter added to our transform to be able to change the
- * material's color for highlighting.
- * @private
- * @type {!o3d.ParamFloat4}
- */
- this.colorParam_ = this.getTransform().createParam('highlightColor',
- 'ParamFloat4');
- this.clearHighlight();
-
- /**
- * Line along which we are dragging.
- * We just use this to store the point and direction, not to do any math.
- * @private
- * @type {!o3djs.manipulators.Line_}
- */
- this.dragLine_ = new o3djs.manipulators.Line_();
-};
-
-o3djs.base.inherit(o3djs.manipulators.Rotate1, o3djs.manipulators.Manip);
-
-o3djs.manipulators.Rotate1.prototype.highlight = function(pickResult) {
- // We can use instanced geometry for the entire Rotate1 since its
- // entire color changes during highlighting.
- // TODO(kbr): support custom user geometry and associated callbacks.
- this.colorParam_.value = o3djs.manipulators.HIGHLIGHTED_COLOR;
-};
-
-o3djs.manipulators.Rotate1.prototype.clearHighlight = function() {
- this.colorParam_.value = o3djs.manipulators.DEFAULT_COLOR;
-};
-
-o3djs.manipulators.Rotate1.prototype.makeActive = function(pickResult) {
- o3djs.manipulators.Manip.prototype.makeActive.call(this, pickResult);
- this.highlight(pickResult);
- var localToWorld = this.getTransform().worldMatrix;
- var worldToLocal = o3djs.math.matrix4.inverse(localToWorld);
-
- // Set up the line. The line is tangent to the circle of rotation
- // and passes through the initial pickResult.
- // Do the math in local space.
- // The rotation axis is the X axis, centered at the origin.
- var localIntersectionPosition =
- o3djs.math.matrix4.transformPoint(worldToLocal,
- pickResult.worldIntersectionPosition);
- var localLineDirection = o3djs.math.cross(localIntersectionPosition,
- o3djs.manipulators.X_AXIS);
- this.dragLine_.setDirection(
- o3djs.math.matrix4.transformDirection(localToWorld,
- localLineDirection));
- this.dragLine_.setPoint(pickResult.worldIntersectionPosition);
-
- // TODO(simonrad): It would be nice to draw an arrow on the screen
- // at the click position, indicating the direction of the line.
-};
-
-o3djs.manipulators.Rotate1.prototype.makeInactive = function() {
- o3djs.manipulators.Manip.prototype.makeInactive.call(this);
- this.clearHighlight();
- this.updateAttachedTransformFromLocalTransform_();
- this.updateBaseTransformFromAttachedTransform_();
-};
-
-/**
- * Convert the specified frustum-space position into
- * client coordinates (ie pixels).
- * @private
- * @param {!o3djs.math.Vector3} frustumPoint The point in frustum coordinates
- * to transform.
- * @param {number} width The width of the viewport.
- * @param {number} height The height of the viewport.
- * @return {!o3djs.math.Vector2} The location of frustumPoint on the screen,
- * in client coordinates.
- */
-o3djs.manipulators.frustumPositionToClientPosition_ = function(frustumPoint,
- width,
- height) {
- return [(frustumPoint[0] + 1) * width / 2,
- (-frustumPoint[1] + 1) * height / 2];
-};
-
-o3djs.manipulators.Rotate1.prototype.drag = function(startPoint,
- endPoint,
- x,
- y,
- view,
- projection,
- width,
- height) {
- // Use a simple linear mouse mapping based on distance along the tangent line.
- // Do the dragging in client (screen space) coordinates. This eliminates any
- // degenerate cases involved with a 3D line.
-
- // Compute the position and direction of the line in screen coordinates.
- var viewProjectionMatrix = o3djs.math.matrix4.mul(view, projection);
- var linePoint1 = o3djs.manipulators.frustumPositionToClientPosition_(
- o3djs.math.matrix4.transformPoint(viewProjectionMatrix,
- this.dragLine_.getPoint()),
- width, height);
- var linePoint2 = o3djs.manipulators.frustumPositionToClientPosition_(
- o3djs.math.matrix4.transformPoint(viewProjectionMatrix,
- o3djs.math.addVector(
- this.dragLine_.getPoint(),
- this.dragLine_.getDirection()
- )),
- width, height);
- var lineDirection = o3djs.math.normalize(o3djs.math.subVector(linePoint2,
- linePoint1));
- var mousePoint = [x, y];
-
- // The distance *along the line* that we have dragged, in pixels.
- var dragDistance = o3djs.math.dot(lineDirection, mousePoint) -
- o3djs.math.dot(lineDirection, linePoint1);
-
- // Determine rotation angle based on drag distance relative to
- // the size of the client area.
- var angle = (dragDistance / Math.max(width, height)) * 2 * Math.PI;
- this.getTransform().localMatrix = o3djs.math.matrix4.rotationX(-angle);
- this.updateAttachedTransformFromLocalTransform_();
-};
-
-// The shaders and materials for the manipulators.
-// TODO(simonrad): Find a better place for these?
-
-// The main reason for using custom shader code instead of using standard
-// shaders from the effect library is that we want to do highlighting.
-// We want to supply two color parameters, and have them combined by the shader.
-// One parameter is defined on the material itself, so that we can have
-// different colored materials for obscured vs. unobscured geometry. The other
-// parameter is the highlightColor, which could switch between white and yellow
-// (for example). The highlightColor is usually defined on the transform
-// directly above the manipulator shapes. We want to be able to change the
-// highlightColor for all materials of the manipulator, but still maintain
-// different colors on each individual material.
-// An alternative would be to use standard shaders, and change the colors of
-// each material individually in the highlight() and clearHighlight() methods.
-// If you do this however, you would have to use different materials on each
-// manipulator, so that you can highlight only one.
-// Another alternative would be to do highlighting by swapping materials on
-// the shapes. That is, you would have obscuredHighlightedMaterial and
-// obscuredNonHighlightedMaterial. This might be best.
-
-/**
- * An effect string for the polygon geometry of manipulators.
- * This is the same as the shader returned by buildPhongShaderString(),
- * except that it uses an additional highlightColor uniform parameter
- * to do manipulator highlighting.
- * TODO(simonrad): Make the highlighting easier to see, especially when the
- * shapes are dark and obscured.
- * @private
- * @type {string}
- */
-o3djs.manipulators.phongFXString_ = '' +
- 'uniform float4x4 worldViewProjection : WORLDVIEWPROJECTION;\n' +
- 'uniform float3 lightWorldPos;\n' +
- 'uniform float4 lightColor;\n' +
- 'uniform float4x4 world : WORLD;\n' +
- 'uniform float4x4 viewInverse : VIEWINVERSE;\n' +
- 'uniform float4x4 worldInverseTranspose : WORLDINVERSETRANSPOSE;\n' +
- 'uniform float4 emissive;\n' +
- 'uniform float4 ambient;\n' +
- 'uniform float4 diffuse;\n' +
- 'uniform float4 highlightColor;\n' +
- 'uniform float4 specular;\n' +
- 'uniform float shininess;\n' +
- 'uniform float specularFactor;\n' +
- 'struct InVertex {\n' +
- ' float4 position : POSITION;\n' +
- ' float3 normal : NORMAL;\n' +
- '};\n' +
- 'struct OutVertex {\n' +
- ' float4 position : POSITION;\n' +
- ' float3 normal : TEXCOORD0;\n' +
- ' float3 surfaceToLight: TEXCOORD1;\n' +
- ' float3 surfaceToView : TEXCOORD2;\n' +
- '};\n' +
- 'OutVertex vertexShaderFunction(InVertex input) {\n' +
- ' OutVertex output;\n' +
- ' output.position = mul(input.position, worldViewProjection);\n' +
- ' output.normal = mul(float4(input.normal, 0),\n' +
- ' worldInverseTranspose).xyz;\n' +
- ' output.surfaceToLight = lightWorldPos - \n' +
- ' mul(input.position, world).xyz;\n' +
- ' output.surfaceToView = (viewInverse[3] - mul(input.position,\n' +
- ' world)).xyz;\n' +
- ' return output;\n' +
- '}\n' +
- 'float4 pixelShaderFunction(OutVertex input) : COLOR {\n' +
- ' float4 newDiffuse = diffuse * highlightColor;\n' +
- ' float3 normal = normalize(input.normal);\n' +
- ' float3 surfaceToLight = normalize(input.surfaceToLight);\n' +
- ' float3 surfaceToView = normalize(input.surfaceToView);\n' +
- ' float3 halfVector = normalize(surfaceToLight + surfaceToView);\n' +
- ' float4 litR = lit(dot(normal, surfaceToLight), \n' +
- ' dot(normal, halfVector), shininess);\n' +
- ' return float4((emissive +\n' +
- ' lightColor * (ambient * newDiffuse + newDiffuse * litR.y +\n' +
- ' + specular * litR.z * specularFactor)).rgb, newDiffuse.a);\n' +
- '}\n' +
- '\n' +
- '// #o3d VertexShaderEntryPoint vertexShaderFunction\n' +
- '// #o3d PixelShaderEntryPoint pixelShaderFunction\n' +
- '// #o3d MatrixLoadOrder RowMajor\n';
-
-/**
- * An constant-color effect string.
- * @private
- * @type {string}
- */
-o3djs.manipulators.constantFXString_ = '' +
- 'uniform float4x4 worldViewProjection : WORLDVIEWPROJECTION;\n' +
- 'uniform float4 color;\n' +
- 'uniform float4 highlightColor;\n' +
- '\n' +
- 'struct VertexShaderInput {\n' +
- ' float4 position : POSITION;\n' +
- '};\n' +
- '\n' +
- 'struct PixelShaderInput {\n' +
- ' float4 position : POSITION;\n' +
- '};\n' +
- '\n' +
- 'PixelShaderInput vertexShaderFunction(VertexShaderInput input) {\n' +
- ' PixelShaderInput output;\n' +
- '\n' +
- ' output.position = mul(input.position, worldViewProjection);\n' +
- ' return output;\n' +
- '}\n' +
- '\n' +
- 'float4 pixelShaderFunction(PixelShaderInput input): COLOR {\n' +
- ' return color * highlightColor;\n' +
- '}\n' +
- '\n' +
- '// #o3d VertexShaderEntryPoint vertexShaderFunction\n' +
- '// #o3d PixelShaderEntryPoint pixelShaderFunction\n' +
- '// #o3d MatrixLoadOrder RowMajor\n';
-
-
-/**
- * Returns an effect string for the Rotate1 manipulator's line ring.
- * @private
- * @param {boolean} enableStipple Whether line stippling should be enabled
- * in the shader.
- * @return {string} The created shader source / effect string.
- */
-o3djs.manipulators.getLineRingFXString_ = function(enableStipple) {
- var stippleCode = '';
- if (enableStipple) {
- stippleCode = '' +
- ' // Use the texCoord to do stippling.\n' +
- ' if (input.texCoord.x % 2 > 1) return float4(0, 0, 0, 0);\n';
- }
- return '' +
- 'uniform float4x4 worldViewProjection : WORLDVIEWPROJECTION;\n' +
- '// NOTE: We transform the normals through the\n' +
- '// worldViewProjectionInverseTranspose instead of the\n' +
- '// worldViewInverseTranspose. The projection matrix warps the\n' +
- '// normals in strange ways. One result of this is that the "front\n' +
- '// face" color of the ring can extend around more than 50% of the\n' +
- '// ring. This may be good or bad. If we dont include the projection\n' +
- '// matrix, we always get a 50% split, but we do not account for\n' +
- '// perspective. An alternative would be to get a little more\n' +
- '// complicated, using the positions of the camera and the center\n' +
- '// of the ring.\n' +
- 'uniform float4x4 worldViewProjectionInverseTranspose :\n' +
- ' WORLDVIEWPROJECTIONINVERSETRANSPOSE;\n' +
- 'uniform float4 color1;\n' +
- 'uniform float4 color2;\n' +
- 'uniform float4 highlightColor;\n' +
- '\n' +
- 'struct VertexShaderInput {\n' +
- ' float4 position : POSITION;\n' +
- ' float4 normal : NORMAL;\n' +
- ' float1 texCoord : TEXCOORD0;\n' +
- '};\n' +
- '\n' +
- 'struct PixelShaderInput {\n' +
- ' float4 position : POSITION;\n' +
- ' float3 normal : TEXCOORD0;\n' +
- ' float1 texCoord : TEXCOORD1;\n' +
- '};\n' +
- '\n' +
- 'PixelShaderInput vertexShaderFunction(VertexShaderInput input) {\n' +
- ' PixelShaderInput output;\n' +
- '\n' +
- ' output.position = mul(input.position, worldViewProjection);\n' +
- ' output.normal = mul(input.normal,\n' +
- ' worldViewProjectionInverseTranspose).xyz;\n' +
- ' output.texCoord = input.texCoord;\n' +
- ' return output;\n' +
- '}\n' +
- '\n' +
- 'float4 pixelShaderFunction(PixelShaderInput input): COLOR {\n' +
- stippleCode +
- ' if (input.normal.z < 0) {\n' +
- ' return color1 * highlightColor; // Front face of the ring.\n' +
- ' } else {\n' +
- ' return color2 * highlightColor; // Back face of the ring.\n' +
- ' }\n' +
- '}\n' +
- '\n' +
- '// #o3d VertexShaderEntryPoint vertexShaderFunction\n' +
- '// #o3d PixelShaderEntryPoint pixelShaderFunction\n' +
- '// #o3d MatrixLoadOrder RowMajor\n';
-};
-
-/**
- * Set up the state of a material to allow alpha blending.
- *
- * @param {!o3d.Pack} pack The pack to create the state object in.
- * @param {!o3d.Material} material The material to modify.
- * @param {boolean} discardZeroAlphaPixels Whether incoming pixels that have
- * zero alpha should be discarded.
- */
-o3djs.manipulators.enableAlphaBlendingOnMaterial =
- function(pack, material, discardZeroAlphaPixels) {
- if (!material.state) {
- material.state = pack.createObject('State');
- }
- var state = material.state;
- state.getStateParam('AlphaBlendEnable').value = true;
- state.getStateParam('SourceBlendFunction').value =
- o3djs.base.o3d.State.BLENDFUNC_SOURCE_ALPHA;
- state.getStateParam('DestinationBlendFunction').value =
- o3djs.base.o3d.State.BLENDFUNC_INVERSE_SOURCE_ALPHA;
- state.getStateParam('AlphaTestEnable').value = discardZeroAlphaPixels;
- state.getStateParam('AlphaComparisonFunction').value =
- o3djs.base.o3d.State.CMP_GREATER;
- state.getStateParam('AlphaReference').value = 0;
-};
-
-/**
- * Creates the Rotate1 manipulator's line ring material.
- *
- * @param {!o3d.Pack} pack The pack to create the effect and material in.
- * @param {!o3d.DrawList} drawList The draw list against which
- * the material is created.
- * @param {!o3djs.math.Vector4} color1 A color in the format [r, g, b, a].
- * @param {!o3djs.math.Vector4} color2 A color in the format [r, g, b, a].
- * @param {boolean} enableStipple Whether line stippling should be enabled
- * in the shader.
- * @return {!o3d.Material} The created material.
- */
-o3djs.manipulators.createLineRingMaterial = function(pack,
- drawList,
- color1,
- color2,
- enableStipple) {
- var material = pack.createObject('Material');
- material.effect = pack.createObject('Effect');
- material.effect.loadFromFXString(
- o3djs.manipulators.getLineRingFXString_(enableStipple));
- material.drawList = drawList;
- material.createParam('color1', 'ParamFloat4').value = color1;
- material.createParam('color2', 'ParamFloat4').value = color2;
- o3djs.manipulators.enableAlphaBlendingOnMaterial(pack, material, true);
- return material;
-};
-
-/**
- * Creates a constant-shaded material based on the given single color.
- *
- * @param {!o3d.Pack} pack The pack to create the effect and material in.
- * @param {!o3d.DrawList} drawList The draw list against which
- * the material is created.
- * @param {!o3djs.math.Vector4} color A color in the format [r, g, b, a].
- * @return {!o3d.Material} The created material.
- */
-o3djs.manipulators.createConstantMaterial = function(pack,
- drawList,
- color) {
- var material = pack.createObject('Material');
- material.effect = pack.createObject('Effect');
- material.effect.loadFromFXString(o3djs.manipulators.constantFXString_);
- material.drawList = drawList;
- material.createParam('color', 'ParamFloat4').value = color;
- o3djs.manipulators.enableAlphaBlendingOnMaterial(pack, material, false);
- return material;
-};
-
-/**
- * Creates a phong-shaded material based on the given color.
- *
- * @param {!o3d.Pack} pack The pack to create the effect and material in.
- * @param {!o3d.DrawList} drawList The draw list against which
- * the material is created.
- * @param {!o3djs.math.Vector4} color A color in the format [r, g, b, a].
- * @return {!o3d.Material} The created material.
- */
-o3djs.manipulators.createPhongMaterial = function(pack,
- drawList,
- color) {
- var material = pack.createObject('Material');
- material.effect = pack.createObject('Effect');
- material.effect.loadFromFXString(o3djs.manipulators.phongFXString_);
- material.drawList = drawList;
- material.createParam('diffuse', 'ParamFloat4').value = color;
-
- // Create some suitable defaults for the material.
- material.createParam('emissive', 'ParamFloat4').value = [0, 0, 0, 1];
- material.createParam('ambient', 'ParamFloat4').value = [0.5, 0.5, 0.5, 1];
- material.createParam('specular', 'ParamFloat4').value = [1, 1, 1, 1];
- material.createParam('shininess', 'ParamFloat').value = 50;
- material.createParam('specularFactor', 'ParamFloat').value = 1;
- material.createParam('lightColor', 'ParamFloat4').value = [1, 1, 1, 1];
- material.createParam('lightWorldPos', 'ParamFloat3').value =
- [1000, 2000, 3000];
- // TODO(simonrad): Allow modifying the lightPosition, and/or make it fit in
- // with the surrounding world. We could put the lightWorldPos parameter on
- // the transform or somewhere else.
-
- o3djs.manipulators.enableAlphaBlendingOnMaterial(pack, material, false);
- return material;
-}; \ No newline at end of file
diff --git a/o3d/samples/o3djs/material.js b/o3d/samples/o3djs/material.js
deleted file mode 100644
index e0f89e0..0000000
--- a/o3d/samples/o3djs/material.js
+++ /dev/null
@@ -1,593 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains various functions for helping setup
- * materials for o3d. It puts them in the "material" module on the
- * o3djs object.
- *
- * Note: This library is only a sample. It is not meant to be some official
- * library. It is provided only as example code.
- *
- */
-
-o3djs.provide('o3djs.material');
-
-o3djs.require('o3djs.math');
-o3djs.require('o3djs.effect');
-
-/**
- * A Module for materials.
- * @namespace
- */
-o3djs.material = o3djs.material || {};
-
-/**
- * Checks a material's params by name to see if it possibly has non 1.0 alpha.
- * Given a name, checks for a ParamTexture called 'nameTexture' and if that
- * fails, checks for a ParamFloat4 'name'.
- * @private
- * @param {!o3d.Material} material Materal to check.
- * @param {string} name name of color params to check.
- * @return {{found: boolean, nonOneAlpha: boolean}} found is true if one of
- * the params was found, nonOneAlpha is true if that param had non 1.0
- * alpha.
- */
-o3djs.material.hasNonOneAlpha_ = function(material, name) {
- var found = false;
- var nonOneAlpha = false;
- var texture = null;
- var samplerParam = material.getParam(name + 'Sampler');
- if (samplerParam && samplerParam.isAClassName('o3d.ParamSampler')) {
- found = true;
- var sampler = samplerParam.value;
- if (sampler) {
- texture = sampler.texture;
- }
- } else {
- var textureParam = material.getParam(name + 'Texture');
- if (textureParam && textureParam.isAClassName('o3d.ParamTexture')) {
- found = true;
- texture = textureParam.value;
- }
- }
-
- if (texture && !texture.alphaIsOne) {
- nonOneAlpha = true;
- }
-
- if (!found) {
- var colorParam = material.getParam(name);
- if (colorParam && colorParam.isAClassName('o3d.ParamFloat4')) {
- found = true;
- // TODO: this check does not work. We need to check for the
- // <transparency> and <transparent> elements or something.
- // if (colorParam.value[3] < 1) {
- // nonOneAlpha = true;
- // }
- }
- }
- return {found: found, nonOneAlpha: nonOneAlpha};
-};
-
-/**
- * Prepares a material by setting their drawList and possibly creating
- * an standard effect if one does not already exist.
- *
- * This function is very specific to our sample importer. It expects that if
- * no Effect exists on a material that certain extra Params have been created
- * on the Material to give us instructions on what to Effects to create.
- *
- * @param {!o3d.Pack} pack Pack to manage created objects.
- * @param {!o3djs.rendergraph.ViewInfo} viewInfo as returned from
- * o3djs.rendergraph.createView.
- * @param {!o3d.Material} material to prepare.
- * @param {string} opt_effectType type of effect to create ('phong',
- * 'lambert', 'constant').
- * @param {Object} opt_options Extra options for effect.getStandardShader
- *
- * @see o3djs.material.attachStandardEffect
- */
-o3djs.material.prepareMaterial = function(pack,
- viewInfo,
- material,
- opt_effectType,
- opt_options) {
- // Assume we want the performance list
- var drawList = viewInfo.performanceDrawList;
- // First check if we have a tag telling us that it is or is not
- // transparent
- if (!material.drawList) {
- var param = material.getParam('collada.transparent');
- if (param && param.className == 'o3d.ParamBoolean') {
- material.drawList = param.value ? viewInfo.zOrderedDrawList :
- viewInfo.performanceDrawList;
- }
- }
- // If the material has no effect, try to build shaders for it.
- if (!material.effect) {
- // If the user didn't pass an effect type in see if one was stored there
- // by our importer.
- if (!opt_effectType) {
- // Retrieve the lightingType parameter from the material, if any.
- var lightingType = o3djs.effect.getColladaLightingType(material);
- if (lightingType) {
- opt_effectType = lightingType;
- }
- }
- if (opt_effectType) {
- o3djs.material.attachStandardEffect(pack,
- material,
- viewInfo,
- opt_effectType,
- opt_options);
- // For collada common profile stuff guess what drawList to use. Note: We
- // can only do this for collada common profile stuff because we supply
- // the shaders and therefore now the inputs and how they are used.
- // For other shaders you've got to do this stuff yourself. On top of
- // that this is a total guess. Just because a texture has no alpha
- // it does not follow that you don't want it in the zOrderedDrawList.
- // That is application specific. Here we are just making a guess and
- // hoping that it covers most cases.
- if (material.drawList == null) {
- // Check the common profile params.
- var result = o3djs.material.hasNonOneAlpha_(material, 'diffuse');
- if (!result.found) {
- result = o3djs.material.hasNonOneAlpha_(material, 'emissive');
- }
- if (result.nonOneAlpha) {
- drawList = viewInfo.zOrderedDrawList;
- }
- }
- }
- }
- if (!material.drawList) {
- material.drawList = drawList;
- }
-};
-
-/**
- * Prepares all the materials in the given pack by setting their drawList and
- * if they don't have an Effect, creating one for them.
- *
- * This function is very specific to our sample importer. It expects that if
- * no Effect exists on a material that certain extra Params have been created
- * on the Material to give us instructions on what to Effects to create.
- *
- * @param {!o3d.Pack} pack Pack to prepare.
- * @param {!o3djs.rendergraph.ViewInfo} viewInfo as returned from
- * o3djs.rendergraph.createView.
- * @param {!o3d.Pack} opt_effectPack Pack to create effects in. If this
- * is not specifed the pack to prepare above will be used.
- * @param {Object} opt_options Extra options for effect.getStandardShader
- *
- * @see o3djs.material.prepareMaterial
- */
-o3djs.material.prepareMaterials = function(pack,
- viewInfo,
- opt_effectPack,
- opt_options) {
- var materials = pack.getObjectsByClassName('o3d.Material');
- for (var mm = 0; mm < materials.length; mm++) {
- o3djs.material.prepareMaterial(opt_effectPack || pack,
- viewInfo,
- materials[mm],
- undefined,
- opt_options);
- }
-};
-
-/**
- * Builds a standard effect for a given material.
- * If the material already has an effect, none is created.
- * @param {!o3d.Pack} pack Pack to manage created objects.
- * @param {!o3d.Material} material The material for which to create an
- * effect.
- * @param {string} effectType Type of effect to create ('phong', 'lambert',
- * 'constant').
- * @param {Object} opt_options Extra options for effect.getStandardShader
- *
- * @see o3djs.effect.attachStandardShader
- */
-o3djs.material.attachStandardEffectEx = function(pack,
- material,
- effectType,
- opt_options) {
- if (!material.effect) {
- if (!o3djs.effect.attachStandardShader(pack,
- material,
- [0, 0, 0],
- effectType,
- opt_options)) {
- throw 'Could not attach a standard effect';
- }
- }
-};
-
-/**
- * Builds a standard effect for a given material. The position of the
- * default light is set to the view position. If the material already has
- * an effect, none is created.
- * @param {!o3d.Pack} pack Pack to manage created objects.
- * @param {!o3d.Material} material The material for which to create an
- * effect.
- * @param {!o3djs.rendergraph.ViewInfo} viewInfo as returned from
- * o3djs.rendergraph.createView.
- * @param {string} effectType Type of effect to create ('phong', 'lambert',
- * 'constant').
- * @param {Object} opt_options Extra options for effect.getStandardShader
- *
- * @see o3djs.effect.attachStandardShader
- */
-o3djs.material.attachStandardEffect = function(pack,
- material,
- viewInfo,
- effectType,
- opt_options) {
- if (!material.effect) {
- var lightPos =
- o3djs.math.matrix4.getTranslation(
- o3djs.math.inverse(viewInfo.drawContext.view));
- if (!o3djs.effect.attachStandardShader(pack,
- material,
- lightPos, // TODO(gman): remove this
- effectType,
- opt_options)) {
- throw 'Could not attach a standard effect';
- }
- }
-};
-
-/**
- * Prepares all the materials in the given pack by setting their
- * drawList.
- * @param {!o3d.Pack} pack Pack to manage created objects.
- * @param {!o3d.DrawList} drawList DrawList to assign to materials.
- */
-o3djs.material.setDrawListOnMaterials = function(pack, drawList) {
- var materials = pack.getObjectsByClassName('o3d.Material');
- for (var mm = 0; mm < materials.length; mm++) {
- var material = materials[mm];
- // TODO: look at flags on the material left by the importer
- // to decide which draw list to use.
- material.drawList = drawList;
- }
-};
-
-/**
- * This function creates a basic material for when you just want to get
- * something on the screen quickly without having to manually setup shaders.
- * You can call this function something like.
- *
- * <pre>
- * &lt;html&gt;&lt;body&gt;
- * &lt;script type="text/javascript" src="o3djs/all.js"&gt;
- * &lt;/script&gt;
- * &lt;script&gt;
- * window.onload = init;
- *
- * function init() {
- * o3djs.base.makeClients(initStep2);
- * }
- *
- * function initStep2(clientElements) {
- * var clientElement = clientElements[0];
- * var client = clientElement.client;
- * var pack = client.createPack();
- * var viewInfo = o3djs.rendergraph.createBasicView(
- * pack,
- * client.root,
- * client.renderGraphRoot);
- * var material = o3djs.material.createBasicMaterial(
- * pack,
- * viewInfo,
- * [1, 0, 0, 1]); // red
- * var shape = o3djs.primitives.createCube(pack, material, 10);
- * var transform = pack.createObject('Transform');
- * transform.parent = client.root;
- * transform.addShape(shape);
- * o3djs.camera.fitContextToScene(client.root,
- * client.width,
- * client.height,
- * viewInfo.drawContext);
- * }
- * &lt;/script&gt;
- * &lt;div id="o3d" style="width: 600px; height: 600px"&gt;&lt;/div&gt;
- * &lt;/body&gt;&lt;/html&gt;
- * </pre>
- *
- * @param {!o3d.Pack} pack Pack to manage created objects.
- * @param {!o3djs.rendergraph.ViewInfo} viewInfo as returned from
- * o3djs.rendergraph.createBasicView.
- * @param {(!o3djs.math.Vector4|!o3d.Texture)} colorOrTexture Either a color in
- * the format [r, g, b, a] or an O3D texture.
- * @param {boolean} opt_transparent Whether or not the material is transparent.
- * Defaults to false.
- * @return {!o3d.Material} The created material.
- */
-o3djs.material.createBasicMaterial = function(pack,
- viewInfo,
- colorOrTexture,
- opt_transparent) {
- var material = pack.createObject('Material');
- material.drawList = opt_transparent ? viewInfo.zOrderedDrawList :
- viewInfo.performanceDrawList;
-
- // If it has a length assume it's a color, otherwise assume it's a texture.
- if (colorOrTexture.length) {
- material.createParam('diffuse', 'ParamFloat4').value = colorOrTexture;
- } else {
- var paramSampler = material.createParam('diffuseSampler', 'ParamSampler');
- var sampler = pack.createObject('Sampler');
- paramSampler.value = sampler;
- sampler.texture = colorOrTexture;
- }
-
- // Create some suitable defaults for the material to save the user having
- // to know all this stuff right off the bat.
- material.createParam('emissive', 'ParamFloat4').value = [0, 0, 0, 1];
- material.createParam('ambient', 'ParamFloat4').value = [0, 0, 0, 1];
- material.createParam('specular', 'ParamFloat4').value = [1, 1, 1, 1];
- material.createParam('shininess', 'ParamFloat').value = 50;
- material.createParam('specularFactor', 'ParamFloat').value = 1;
- material.createParam('lightColor', 'ParamFloat4').value = [1, 1, 1, 1];
- var lightPositionParam = material.createParam('lightWorldPos',
- 'ParamFloat3');
-
- o3djs.material.attachStandardEffect(pack, material, viewInfo, 'phong');
-
- // We have to set the light position after calling attachStandardEffect
- // because attachStandardEffect sets it based on the view.
- lightPositionParam.value = [1000, 2000, 3000];
-
- return material;
-};
-
-/**
- * This function creates a constant material. No lighting. It is especially
- * useful for debugging shapes and 2d UI elements.
- *
- * @param {!o3d.Pack} pack Pack to manage created objects.
- * @param {!o3d.DrawList} drawList The DrawList for the material.
- * @param {(!o3djs.math.Vector4|!o3d.Texture)} colorOrTexture Either a color in
- * the format [r, g, b, a] or an O3D texture.
- * @return {!o3d.Material} The created material.
- */
-o3djs.material.createConstantMaterialEx = function(pack,
- drawList,
- colorOrTexture) {
- var material = pack.createObject('Material');
- material.drawList = drawList;
-
- // If it has a length assume it's a color, otherwise assume it's a texture.
- if (colorOrTexture.length) {
- material.createParam('emissive', 'ParamFloat4').value = colorOrTexture;
- } else {
- var paramSampler = material.createParam('emissiveSampler', 'ParamSampler');
- var sampler = pack.createObject('Sampler');
- paramSampler.value = sampler;
- sampler.texture = colorOrTexture;
- }
-
- o3djs.material.attachStandardEffectEx(pack, material, 'constant');
-
- return material;
-};
-
-/**
- * This function creates a constant material. No lighting. It is especially
- * useful for debugging shapes and 2d UI elements.
- *
- * @param {!o3d.Pack} pack Pack to manage created objects.
- * @param {!o3djs.rendergraph.ViewInfo} viewInfo as returned from
- * o3djs.rendergraph.createBasicView.
- * @param {(!o3djs.math.Vector4|!o3d.Texture)} colorOrTexture Either a color in
- * the format [r, g, b, a] or an O3D texture.
- * @param {boolean} opt_transparent Whether or not the material is transparent.
- * Defaults to false.
- * @return {!o3d.Material} The created material.
- */
-o3djs.material.createConstantMaterial = function(pack,
- viewInfo,
- colorOrTexture,
- opt_transparent) {
- return o3djs.material.createConstantMaterialEx(
- pack,
- opt_transparent ? viewInfo.zOrderedDrawList :
- viewInfo.performanceDrawList,
- colorOrTexture)
-};
-
-/**
- * This function creates 2 color procedureal texture material.
- *
- * @see o3djs.material.createBasicMaterial
- *
- * @param {!o3d.Pack} pack Pack to manage created objects.
- * @param {!o3djs.rendergraph.ViewInfo} viewInfo as returned from
- * o3djs.rendergraph.createBasicView.
- * @param {!o3djs.math.Vector4} opt_color1 a color in the format [r, g, b, a].
- * Defaults to a medium blue-green.
- * @param {!o3djs.math.Vector4} opt_color2 a color in the format [r, g, b, a].
- * Defaults to a light blue-green.
- * @param {boolean} opt_transparent Whether or not the material is transparent.
- * Defaults to false.
- * @param {number} opt_checkSize Defaults to 10 units.
- * @return {!o3d.Material} The created material.
- */
-o3djs.material.createCheckerMaterial = function(pack,
- viewInfo,
- opt_color1,
- opt_color2,
- opt_transparent,
- opt_checkSize) {
- opt_color1 = opt_color1 || [0.4, 0.5, 0.5, 1];
- opt_color2 = opt_color2 || [0.6, 0.8, 0.8, 1];
- opt_checkSize = opt_checkSize || 10;
-
- var effect = o3djs.effect.createCheckerEffect(pack);
- var material = pack.createObject('Material');
- material.effect = effect;
- material.drawList = opt_transparent ? viewInfo.zOrderedDrawList :
- viewInfo.performanceDrawList;
- o3djs.effect.createUniformParameters(pack, effect, material);
-
- material.getParam('color1').value = opt_color1;
- material.getParam('color2').value = opt_color2;
- material.getParam('checkSize').value = opt_checkSize;
-
- return material;
-};
-
-/**
- * Creates a material for an effect loaded from a file.
- * If the effect has already been loaded in the pack it will be reused.
- * @param {!o3d.Pack} pack Pack to create effect in.
- * @param {string} url Url for effect file.
- * @param {!o3d.DrawList} drawList DrawList to assign effect to.
- * @return {!o3d.Material} The material.
- */
-o3djs.material.createMaterialFromFile = function(pack, url, drawList) {
- var effect = o3djs.effect.createEffectFromFile(pack, url);
-
- var material = pack.createObject('Material');
- material.effect = effect;
- material.drawList = drawList;
- o3djs.effect.createUniformParameters(pack, effect, material);
-
- return material;
-};
-
-/**
- * Binds params to all materials in a pack by name.
- * @param {!o3d.Material} material Material to bind params on.
- * @param {!Object} params A object where each property is the name of a param
- * and its value is that param.
- */
-o3djs.material.bindParamsOnMaterial = function(material, params) {
- for (var paramName in params) {
- var sourceParam = params[paramName];
- var param = material.getParam(paramName);
- if (param && sourceParam.isAClassName(param.className)) {
- param.bind(sourceParam);
- }
- }
-};
-
-/**
- * Binds params to all materials in a pack by name.
- * @param {!o3d.Pack} pack Pack with materials to bind.
- * @param {!Object} params A object where each property is the name of a param
- * and its value is that param.
- */
-o3djs.material.bindParams = function(pack, params) {
- var materials = pack.getObjectsByClassName('o3d.Material');
- for (var mm = 0; mm < materials.length; ++mm) {
- o3djs.material.bindParamsOnMaterial(materials[mm], params);
- }
-};
-
-/**
- * Creates params from a param spec.
- * @param {!o3d.Pack} pack Pack to create params in.
- * @param {!Object} paramSpec An object where each property is the name of a
- * param and its value is the type of param.
- * @return {!Object} params A object where each property is the name of a param
- * and its value is that param.
- */
-o3djs.material.createParams = function(pack, paramSpec) {
- var paramObject = pack.createObject('ParamObject');
- var params = { };
- for (var paramName in paramSpec) {
- params[paramName] = paramObject.createParam(paramName,
- paramSpec[paramName]);
- }
- return params;
-};
-
-/**
- * Creates the global params need by the shaders built in effect.js
- *
- * The params currently created are 'lightColor' which is a ParamFloat4 and
- * 'lightWorldPos' which is a ParamFloat3. You can set their values like this
- *
- * <pre>
- * var params = o3djs.material.createStandardParams(pack);
- * param.lightColor.value = [1, 0, 0, 1]; // red
- * param.lightWorldPos.value = [1000, 2000, 3000]; // set light position.
- * </pre>
- *
- * Note: This function just creates the params. It does not connect them to
- * anything. See o3djs.material.createAndBindStandardParams,
- * o3djs.material.createParams and o3djs.material.bindParams
- *
- * @see o3djs.material.createAndBindStandardParams
- * @see o3djs.material.createParams
- * @see o3djs.material.bindParams
- *
- * @param {!o3d.Pack} pack Pack to create params in.
- * @return {!Object} params A object where each property is the name of a param
- * and its value is that param.
- */
-o3djs.material.createStandardParams = function(pack) {
- var paramSpec = {
- 'lightColor': 'ParamFloat4',
- 'lightWorldPos': 'ParamFloat3'};
- return o3djs.material.createParams(pack, paramSpec);
-};
-
-/**
- * Creates the global params need by the shaders built in effect.js then binds
- * all the matching params on materials in pack to these global params.
- *
- * The params currently created are 'lightColor' which is a ParamFloat4 and
- * 'lightWorldPos' which is a ParamFloat3. You can set their values like this
- *
- * <pre>
- * var params = o3djs.material.createAndBindStandardParams(pack);
- * param.lightColor.value = [1, 0, 0, 1]; // red
- * param.lightWorldPos.value = [1000, 2000, 3000]; // set light position.
- * </pre>
- *
- * @see o3djs.material.createParams
- * @see o3djs.material.bindParams
- *
- * @param {!o3d.Pack} pack Pack to create params in.
- * @return {!Object} params A object where each property is the name of a param
- * and its value is that param.
- */
-o3djs.material.createAndBindStandardParams = function(pack) {
- var params = o3djs.material.createStandardParams(pack);
- o3djs.material.bindParams(pack, params);
- return params;
-};
-
diff --git a/o3d/samples/o3djs/math.js b/o3d/samples/o3djs/math.js
deleted file mode 100644
index ba07048..0000000
--- a/o3d/samples/o3djs/math.js
+++ /dev/null
@@ -1,3168 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains matrix/vector math functions.
- * It adds them to the "math" module on the o3djs object.
- *
- * o3djs.math supports a row-major and a column-major mode. In both
- * modes, vectors are stored as arrays of numbers, and matrices are also.
- *
- * In row-major mode:
- *
- * - Rows of a matrix are neighboring <dimension> elements in the array.
- * - Entries of a matrix M get accessed in M[row*dimension+column] fashion.
- * - Tuples of coordinates adjacent are interpreted as row-vectors.
- * - A vector v gets transformed by a matrix M by multiplying in the order v*M.
- *
- * In column-major mode:
- *
- * - Columns of a matrix are neighboring <dimension> elements in the array.
- * - Entries of a matrix M get accessed in M[column*dimension+row] fashion.
- * - Tuples of coordinates adjacent are interpreted as column-vectors.
- * - A matrix M transforms a vector v by multiplying in the order M*v.
- *
- * When a function in o3djs.math requires separate row-major and
- * column-major versions, a function with the same name gets added to each of
- * the namespaces o3djs.math.rowMajor and o3djs.math.columnMajor. The
- * function installRowMajorFunctions() or the function
- * installColumnMajorFunctions() should get called during initialization to
- * establish the mode. installRowMajorFunctions() works by iterating through
- * the o3djs.math.rowMajor namespace and for each function foo, setting
- * o3djs.math.foo equal to o3djs.math.rowMajor.foo.
- * installRowMajorFunctions() works the same way, iterating over the columnMajor
- * namespace. At the end of this file, we call installRowMajorFunctions().
- *
- * Switching modes changes two things. It changes how a matrix is encoded as an
- * array, and it changes how the entries of a matrix get interpreted. Because
- * those two things change together, the matrix representing a given
- * transformation of space is the same JavaScript object in either mode.
- * One consequence of this is that very few functions require separate row-major
- * and column-major versions. Typically, a function requires separate versions
- * only if it makes matrix multiplication order explicit, like
- * mulMatrixMatrix(), mulMatrixVector(), or mulVectorMatrix(). Functions which
- * create a new matrix, like scaling(), rotationZYX(), and translation() return
- * the same JavaScript object in either mode, and functions which implicitly
- * multiply like scale(), rotateZYX() and translate() modify the matrix in the
- * same way in either mode.
- *
- * The convention choice made for math functions in this library is independent
- * of the convention choice for how matrices get loaded into shaders. That
- * convention is determined on a per-shader basis.
- *
- * Other utilities in o3djs should avoid making calls to functions that make
- * multiplication order explicit. Instead they should appeal to functions like:
- *
- * o3djs.math.matrix4.transformPoint
- * o3djs.math.matrix4.transformDirection
- * o3djs.math.matrix4.transformNormal
- * o3djs.math.matrix4.transformVector4
- * o3djs.math.matrix4.composition
- * o3djs.math.matrix4.compose
- *
- * These functions multiply matrices implicitly and internally choose the
- * multiplication order to get the right result. That way, utilities which use
- * o3djs.math work in either major mode. Note that this does not necessarily
- * mean all sample code will work even if a line is added which switches major
- * modes, but it does mean that calls to o3djs still do what they are supposed
- * to.
- */
-
-
-var use_plugin_math = false;
-
-if ((typeof o3d != 'undefined') && o3d && o3d.Transform &&
- o3d.Transform.makeIdentityMatrix4_) {
- o3djs.provide('o3djs.math');
-} else {
- use_plugin_math = true;
- o3djs.require('o3djs.plugin_math');
-}
-
-o3djs.provide("o3djs.flat_math");
-
-
-/**
- * A module for math for o3djs.math.
- * @namespace
- */
-o3djs.math = o3djs.math || {};
-
-/**
- * Functions which deal with 4-by-4 transformation matrices are kept in their
- * own namespsace.
- * @namespace
- */
-o3djs.math.matrix4 = o3djs.math.matrix4 || {};
-
-/**
- * Functions that are specifically row major are kept in their own namespace.
- * @namespace
- */
-o3djs.math.rowMajor = o3djs.math.rowMajor || {};
-
-/**
- * Functions that are specifically column major are kept in their own namespace.
- * @namespace
- */
-o3djs.math.columnMajor = o3djs.math.columnMajor || {};
-
-/**
- * Functions that do error checking are stored in their own namespace.
- * @namespace
- */
-o3djs.math.errorCheck = o3djs.math.errorCheck || {};
-
-/**
- * Functions that do no error checking and have a separate version that does in
- * o3djs.math.errorCheck are stored in their own namespace.
- * @namespace
- */
-o3djs.math.errorCheckFree = o3djs.math.errorCheckFree || {};
-
-/**
- * An Array of 2 floats
- * @type {(!Array.<number>|!o3d.Float2)}
- */
-o3djs.math.Vector2 = goog.typedef;
-
-/**
- * An Array of 3 floats
- * @type {(!Array.<number>|!o3d.Float3)}
- */
-o3djs.math.Vector3 = goog.typedef;
-
-/**
- * An Array of 4 floats
- * @type {(!Array.<number>|!o3d.Float4)}
- */
-o3djs.math.Vector4 = goog.typedef;
-
-/**
- * An Array of floats.
- * @type {!Array.<number>}
- */
-o3djs.math.Vector = goog.typedef;
-
-/**
- * A 1x1 Matrix of floats
- * @type {!Array.<!Array.<number>>}
- */
-o3djs.math.Matrix1 = goog.typedef;
-
-/**
- * A 2x2 Matrix of floats
- * @type {!Array.<!Array.<number>>}
- */
-o3djs.math.Matrix2 = goog.typedef;
-
-/**
- * A 3x3 Matrix of floats
- * @type {!Array.<!Array.<number>>}
- */
-o3djs.math.Matrix3 = goog.typedef;
-
-/**
- * A 4x4 Matrix of floats
- * @type {(!Array.<!Array.<number>>|!o3d.Matrix4)}
- */
-o3djs.math.Matrix4 = goog.typedef;
-
-/**
- * A arbitrary size Matrix of floats
- * @type {(!Array.<!Array.<number>>|!o3d.Matrix4)}
- */
-o3djs.math.Matrix = goog.typedef;
-
-
-/**
- * A module for math functions where a matrix is represented as a flat
- * (1-dimensional) array.
- * @namespace
- */
-o3djs.flat_math = o3djs.flat_math || {};
-
-/**
- * A random seed for the pseudoRandom function.
- * @private
- * @type {number}
- */
-o3djs.flat_math.randomSeed_ = 0;
-
-/**
- * A constant for the pseudoRandom function
- * @private
- * @type {number}
- */
-o3djs.flat_math.RANDOM_RANGE_ = Math.pow(2, 32);
-
-/**
- * Functions which deal with 4-by-4 transformation matrices are kept in their
- * own namespsace.
- * @namespace
- */
-o3djs.flat_math.matrix4 = o3djs.flat_math.matrix4 || {};
-
-/**
- * Functions that are specifically row major are kept in their own namespace.
- * @namespace
- */
-o3djs.flat_math.rowMajor = o3djs.flat_math.rowMajor || {};
-
-/**
- * Functions that are specifically column major are kept in their own namespace.
- * @namespace
- */
-o3djs.flat_math.columnMajor = o3djs.flat_math.columnMajor || {};
-
-/**
- * Functions that do error checking are stored in their own namespace.
- * @namespace
- */
-o3djs.flat_math.errorCheck = o3djs.flat_math.errorCheck || {};
-
-/**
- * Functions that do no error checking and have a separate version that does in
- * o3djs.flat_math.errorCheck are stored in their own namespace.
- * @namespace
- */
-o3djs.flat_math.errorCheckFree = o3djs.flat_math.errorCheckFree || {};
-
-/**
- * An Float32Array of 2 floats
- * @type {!Array.<number>}
- */
-o3djs.flat_math.Vector2 = goog.typedef;
-
-/**
- * An Float32Array of 3 floats
- * @type {!Array.<number>}
- */
-o3djs.flat_math.Vector3 = goog.typedef;
-
-/**
- * An Float32Array of 4 floats
- * @type {!Array.<number>}
- */
-o3djs.flat_math.Vector4 = goog.typedef;
-
-
-/**
- * A 1x1 Matrix of floats
- * @type {(!Array.<number>|Float32Array)}
- */
-o3djs.flat_math.Matrix1 = goog.typedef;
-
-/**
- * A 2x2 Matrix of floats
- * @type {(!Array.<number>|Float32Array)}
- */
-o3djs.flat_math.Matrix2 = goog.typedef;
-
-/**
- * A 3x3 Matrix of floats
- * @type {(!Array.<number>|Float32Array)}
- */
-o3djs.flat_math.Matrix3 = goog.typedef;
-
-/**
- * A 4x4 Matrix of floats
- * @type {(!Array.<number>|Float32Array)}
- */
-o3djs.flat_math.Matrix4 = goog.typedef;
-
-o3djs.flat_math.useFloat32Array_ = false;
-
-/**
- * A arbitrary size Matrix of floats
- * @type {(!Array.<number>|Float32Array|o3djs.flat_math.Matrix1|
- * o3djs.flat_math.Matrix2|o3djs.flat_math.Matrix3|o3djs.flat_math.Matrix4)}
- */
-o3djs.flat_math.Matrix = goog.typedef;
-
-/**
- * A arbitrary size Matrix of floats
- * @type {!Array.<number>}
- */
-o3djs.flat_math.Vector = goog.typedef;
-
-
-/**
- * Namespace for Float32Array specific math functions.
- * @namespace
- */
-o3djs.flat_math.Float32Array = {};
-
-/**
- * A arbitrary size Matrix of floats
- * @constructor
- */
-o3djs.flat_math.Float32Array.Matrix = Float32Array;
-
-/**
- * A Float32Array.
- * @constructor
- */
-o3djs.flat_math.Float32Array.Vector = Float32Array;
-
-/**
- * If 16 arguments, this returns a 4x4 matrix
- * with values set to the passed in arguments
- * If 9 arguments returns a 3x3 matrix, if 4 arguments returns a 2x2 matrix.
- * @param {number} a [0][0] element
- * @param {number} b [0][1] element
- * @param {number} c [0][2] element
- * @param {number} d [0][3] element
- * @param {number} e [1][0] element
- * @param {number} f [1][1] element
- * @param {number} g [1][2] element
- * @param {number} h [1][3] element
- * @param {number} i [2][0] element
- * @param {number} j [2][1] element
- * @param {number} k [2][2] element
- * @param {number} l [2][3] element
- * @param {number} m [3][0] element
- * @param {number} n [3][1] element
- * @param {number} o [3][2] element
- * @param {number} p [3][3] element
- * @returns {!o3djs.flat_math.Matrix}
- */
-o3djs.flat_math.Float32Array.makeMatrix = function(
- a, b, c, d,
- e, f, g, h,
- i, j, k, l,
- m, n, o, p) {
- if (p === undefined) {
- if (i === undefined) {
- var retval = new Float32Array(4);
- retval[0] = a;
- retval[1] = b;
- retval[2] = c;
- retval[3] = d;
- return retval;
- }
- var retval = new Float32Array(9);
- retval[0] = a;
- retval[1] = b;
- retval[2] = c;
- retval[3] = d;
- retval[4] = e;
- retval[5] = f;
- retval[6] = g;
- retval[7] = h;
- retval[8] = i;
- return retval;
- }
- var retval = new Float32Array(16);
- retval[0] = a;
- retval[1] = b;
- retval[2] = c;
- retval[3] = d;
- retval[4] = e;
- retval[5] = f;
- retval[6] = g;
- retval[7] = h;
- retval[8] = i;
- retval[9] = j;
- retval[10] = k;
- retval[11] = l;
- retval[12] = m;
- retval[13] = n;
- retval[14] = o;
- retval[15] = p;
- return retval;
-};
-
-/**
- * returns a 2x2 matrix
- * @param {number} a [0][0] element
- * @param {number} b [0][1] element
- * @param {number} c [1][0] element
- * @param {number} d [1][1] element
- * @returns {!o3djs.flat_math.Matrix}
- */
-o3djs.flat_math.Float32Array.makeMatrix2 = function(a,b,
- c,d) {
- var retval = new Float32Array(4);
- retval[0] = a;
- retval[1] = b;
- retval[2] = c;
- retval[3] = d;
- return retval;
-};
-
-/**
- * If returns a 3x3 matrix
- * @param {number} a [0][0] element
- * @param {number} b [0][1] element
- * @param {number} c [0][2] element
- * @param {number} d [1][0] element
- * @param {number} e [1][1] element
- * @param {number} f [1][2] element
- * @param {number} g [2][0] element
- * @param {number} h [2][1] element
- * @param {number} i [2][2] element
- * @return {!o3djs.flat_math.Matrix} the matrix of the above elements
- */
-o3djs.flat_math.Float32Array.makeMatrix3 = function(
- a, b, c,
- d, e, f,
- g, h, i) {
- var retval = new Float32Array(9);
- retval[0] = a;
- retval[1] = b;
- retval[2] = c;
- retval[3] = d;
- retval[4] = e;
- retval[5] = f;
- retval[6] = g;
- retval[7] = h;
- retval[8] = i;
- return retval;
-};
-
-/**
- * returns a 4x4 matrix
- * with values set to the passed in arguments
- * @param {number} a [0][0] element
- * @param {number} b [0][1] element
- * @param {number} c [0][2] element
- * @param {number} d [0][3] element
- * @param {number} e [1][0] element
- * @param {number} f [1][1] element
- * @param {number} g [1][2] element
- * @param {number} h [1][3] element
- * @param {number} i [2][0] element
- * @param {number} j [2][1] element
- * @param {number} k [2][2] element
- * @param {number} l [2][3] element
- * @param {number} m [3][0] element
- * @param {number} n [3][1] element
- * @param {number} o [3][2] element
- * @param {number} p [3][3] element
- * @returns {o3djs.flat_math.Matrix} comprised of the above elements
- */
-o3djs.flat_math.Float32Array.makeMatrix4 = function(
- a, b, c, d,
- e, f, g, h,
- i, j, k, l,
- m, n, o, p) {
- var retval = new Float32Array(16);
- retval[0] = a;
- retval[1] = b;
- retval[2] = c;
- retval[3] = d;
- retval[4] = e;
- retval[5] = f;
- retval[6] = g;
- retval[7] = h;
- retval[8] = i;
- retval[9] = j;
- retval[10] = k;
- retval[11] = l;
- retval[12] = m;
- retval[13] = n;
- retval[14] = o;
- retval[15] = p;
- return retval;
-};
-
-/**
- * Namespace for Array specific math functions
- */
-o3djs.flat_math.Array={};
-
-/**
- * A arbitrary size Matrix of floats
- * @constructor
- */
-o3djs.flat_math.Array.Matrix = Array;
-
-/**
- * An Float32Array of floats.
- * @constructor
- */
-o3djs.flat_math.Array.Vector = Array;
-
-/**
- * If 16 arguments, this returns a 4x4 matrix with values set to the passed
- * in arguments. If 9 arguments returns a 3x3 matrix, if 4 arguments returns
- * a 2x2 matrix
- * @param {number} a [0][0] element
- * @param {number} b [0][1] element
- * @param {number} c [0][2] element
- * @param {number} d [0][3] element
- * @param {number} e [1][0] element
- * @param {number} f [1][1] element
- * @param {number} g [1][2] element
- * @param {number} h [1][3] element
- * @param {number} i [2][0] element
- * @param {number} j [2][1] element
- * @param {number} k [2][2] element
- * @param {number} l [2][3] element
- * @param {number} m [3][0] element
- * @param {number} n [3][1] element
- * @param {number} o [3][2] element
- * @param {number} p [3][3] element
- */
-o3djs.flat_math.Array.makeMatrix = function(
- a, b, c, d,
- e, f, g, h,
- i, j, k, l,
- m, n, o, p) {
- if (p === undefined) {
- if (i === undefined) {
- return [a,b,c,d];
- }
- return [a, b, c, d, e, f, g, h, i];
- }
- return [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p];
-};
-
-/**
- * returns a 2x2 matrix
- * @param {number} a [0][0] element
- * @param {number} b [0][1] element
- * @param {number} c [1][0] element
- * @param {number} d [1][1] element
- * @returns {!o3djs.flat_math.Matrix}
- */
-o3djs.flat_math.Array.makeMatrix2 = function(a, b, c, d) {
- return [a, b, c, d];
-};
-
-/**
- * If returns a 3x3 matrix
- * @param {number} a [0][0] element
- * @param {number} b [0][1] element
- * @param {number} c [0][2] element
- * @param {number} d [1][0] element
- * @param {number} e [1][1] element
- * @param {number} f [1][2] element
- * @param {number} g [2][0] element
- * @param {number} h [2][1] element
- * @param {number} i [2][2] element
- * @return {!o3djs.flat_math.Matrix} the matrix of the above elements
- */
-o3djs.flat_math.Array.makeMatrix3 = function(
- a, b, c,
- d, e, f,
- g, h, i) {
- return [a, b, c, d, e, f, g, h, i];
-};
-
-/**
- * returns a 4x4 matrix
- * with values set to the passed in arguments
- * @param {number} a [0][0] element
- * @param {number} b [0][1] element
- * @param {number} c [0][2] element
- * @param {number} d [0][3] element
- * @param {number} e [1][0] element
- * @param {number} f [1][1] element
- * @param {number} g [1][2] element
- * @param {number} h [1][3] element
- * @param {number} i [2][0] element
- * @param {number} j [2][1] element
- * @param {number} k [2][2] element
- * @param {number} l [2][3] element
- * @param {number} m [3][0] element
- * @param {number} n [3][1] element
- * @param {number} o [3][2] element
- * @param {number} p [3][3] element
- * @returns {o3djs.flat_math.Matrix} comprised of the above elements
- */
-o3djs.flat_math.Array.makeMatrix4 = function(
- a, b, c, d,
- e, f, g, h,
- i, j, k, l,
- m, n, o, p) {
- return [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p];
-};
-
-
-/**
- * Helper function to copy functions from one namespace into another.
- * @param {Object} source The source namespace.
- * @param {Object} target The target namespace.
- */
-o3djs.copyFunctions_ = function(source, target) {
- for (var i in source) {
- var value = source[i];
- // If it's a function, copy it.
- if (value.call) {
- target[i] = value;
- }
- }
-};
-
-
-if (o3djs.flat_math.useFloat32Array_) {
- o3djs.flat_math.Matrix = o3djs.flat_math.Float32Array.Matrix;
- o3djs.flat_math.Vector = o3djs.flat_math.Float32Array.Vector;
- o3djs.copyFunctions_(o3djs.flat_math.Float32Array, o3djs.flat_math);
-} else {
- o3djs.flat_math.Matrix = o3djs.flat_math.Array.Matrix;
- o3djs.flat_math.Vector = o3djs.flat_math.Array.Vector;
- o3djs.copyFunctions_(o3djs.flat_math.Array, o3djs.flat_math);
-}
-
-
-/**
- * Returns a deterministic pseudorandom number between 0 and 1
- * @return {number} a random number between 0 and 1
- */
-o3djs.flat_math.pseudoRandom = function() {
- var math = o3djs.flat_math;
- return (math.randomSeed_ =
- (134775813 * math.randomSeed_ + 1) %
- math.RANDOM_RANGE_) / math.RANDOM_RANGE_;
-};
-
-/**
- * Resets the pseudoRandom function sequence.
- */
-o3djs.flat_math.resetPseudoRandom = function() {
- o3djs.flat_math.randomSeed_ = 0;
-};
-
-/**
- * Converts degrees to radians.
- * @param {number} degrees A value in degrees.
- * @return {number} the value in radians.
- */
-o3djs.flat_math.degToRad = function(degrees) {
- return degrees * Math.PI / 180;
-};
-
-/**
- * Converts radians to degrees.
- * @param {number} radians A value in radians.
- * @return {number} the value in degrees.
- */
-o3djs.flat_math.radToDeg = function(radians) {
- return radians * 180 / Math.PI;
-};
-
-/**
- * Performs linear interpolation on two scalars.
- * Given scalars a and b and interpolation coefficient t, returns
- * (1 - t) * a + t * b.
- * @param {number} a Operand scalar.
- * @param {number} b Operand scalar.
- * @param {number} t Interpolation coefficient.
- * @return {number} The weighted sum of a and b.
- */
-o3djs.flat_math.lerpScalar = function(a, b, t) {
- return (1 - t) * a + t * b;
-};
-
-/**
- * Adds two vectors; assumes a and b have the same dimension.
- * @param {!o3djs.flat_math.Vector} a Operand vector.
- * @param {!o3djs.flat_math.Vector} b Operand vector.
- * @return {!o3djs.flat_math.Vector} The sum of a and b.
- */
-o3djs.flat_math.addVector = function(a, b) {
- var aLength = a.length;
- var r = new o3djs.flat_math.Vector(aLength);
- for (var i = 0; i < aLength; ++i)
- r[i] = a[i] + b[i];
- return r;
-};
-
-/**
- * Subtracts two vectors.
- * @param {!o3djs.flat_math.Vector} a Operand vector.
- * @param {!o3djs.flat_math.Vector} b Operand vector.
- * @return {!o3djs.flat_math.Vector} The difference of a and b.
- */
-o3djs.flat_math.subVector = function(a, b) {
- var aLength = a.length;
- var r = new o3djs.flat_math.Vector(aLength);
- for (var i = 0; i < aLength; ++i)
- r[i] = a[i] - b[i];
- return r;
-};
-
-/**
- * Subtracts two 3d vectors.
- * @param {!o3djs.flat_math.Vector3} a Operand vector.
- * @param {!o3djs.flat_math.Vector3} b Operand vector.
- * @return {!o3djs.flat_math.Vector3} The difference of a and b.
- */
-o3djs.flat_math.subVector3 = function(a, b) {
- var r = new o3djs.flat_math.Vector(3);
- for (var i = 0; i < 3; ++i)
- r[i] = a[i] - b[i];
- return r;
-};
-
-/**
- * Performs linear interpolation on two vectors.
- * Given vectors a and b and interpolation coefficient t, returns
- * (1 - t) * a + t * b.
- * @param {!o3djs.flat_math.Vector} a Operand vector.
- * @param {!o3djs.flat_math.Vector} b Operand vector.
- * @param {number} t Interpolation coefficient.
- * @return {!o3djs.flat_math.Vector} The weighted sum of a and b.
- */
-o3djs.flat_math.lerpVector = function(a, b, t) {
- var aLength = a.length;
- var r = new o3djs.flat_math.Vector(aLength);
- for (var i = 0; i < aLength; ++i)
- r[i] = (1 - t) * a[i] + t * b[i];
- return r;
-};
-
-/**
- * Clamps a value between 0 and range using a modulo.
- * @param {number} v Value to clamp mod.
- * @param {number} range Range to clamp to.
- * @param {number} opt_rangeStart start of range. Default = 0.
- * @return {number} Clamp modded value.
- */
-o3djs.flat_math.modClamp = function(v, range, opt_rangeStart) {
- var start = opt_rangeStart || 0;
- if (range < 0.00001) {
- return start;
- }
- v -= start;
- if (v < 0) {
- v -= Math.floor(v / range) * range;
- } else {
- v = v % range;
- }
- return v + start;
-};
-
-/**
- * Lerps in a circle.
- * Does a lerp between a and b but inside range so for example if
- * range is 100, a is 95 and b is 5 lerping will go in the positive direction.
- * @param {number} a Start value.
- * @param {number} b Target value.
- * @param {number} t Amount to lerp (0 to 1).
- * @param {number} range Range of circle.
- * @return {number} lerped result.
- */
-o3djs.flat_math.lerpCircular = function(a, b, t, range) {
- a = o3djs.flat_math.modClamp(a, range);
- b = o3djs.flat_math.modClamp(b, range);
- var delta = b - a;
- if (Math.abs(delta) > range * 0.5) {
- if (delta > 0) {
- b -= range;
- } else {
- b += range;
- }
- }
- return o3djs.flat_math.modClamp(o3djs.flat_math.lerpScalar(a, b, t), range);
-};
-
-/**
- * Lerps radians.
- * @param {number} a Start value.
- * @param {number} b Target value.
- * @param {number} t Amount to lerp (0 to 1).
- * @return {number} lerped result.
- */
-o3djs.flat_math.lerpRadian = function(a, b, t) {
- return o3djs.flat_math.lerpCircular(a, b, t, Math.PI * 2);
-};
-
-/**
- * Divides a vector by a scalar.
- * @param {!o3djs.flat_math.Vector} v The vector.
- * @param {number} k The scalar.
- * @return {!o3djs.flat_math.Vector} v The vector v divided by k.
- */
-o3djs.flat_math.divVectorScalar = function(v, k) {
- var r = [];
- var vLength = v.length;
- for (var i = 0; i < vLength; ++i)
- r[i] = v[i] / k;
- return r;
-};
-
-/**
- * Computes the dot product of two vectors; assumes that a and b have
- * the same dimension.
- * @param {!o3djs.flat_math.Vector} a Operand vector.
- * @param {!o3djs.flat_math.Vector} b Operand vector.
- * @return {number} The dot product of a and b.
- */
-o3djs.flat_math.dot = function(a, b) {
- var r = 0.0;
- var aLength = a.length;
- for (var i = 0; i < aLength; ++i)
- r += a[i] * b[i];
- return r;
-};
-
-/**
- * Computes the cross product of two vectors; assumes both vectors have
- * three entries.
- * @param {!o3djs.flat_math.Vector} a Operand vector.
- * @param {!o3djs.flat_math.Vector} b Operand vector.
- * @return {!o3djs.flat_math.Vector} The vector a cross b.
- */
-o3djs.flat_math.cross = function(a, b) {
- var r = new o3djs.flat_math.Vector(3);
- r[0] = a[1] * b[2] - a[2] * b[1];
- r[1] = a[2] * b[0] - a[0] * b[2];
- r[2] = a[0] * b[1] - a[1] * b[0];
- return r;
-};
-
-/**
- * Computes the Euclidean length of a vector, i.e. the square root of the
- * sum of the squares of the entries.
- * @param {!o3djs.flat_math.Vector} a The vector.
- * @return {number} The length of a.
- */
-o3djs.flat_math.length = function(a) {
- var r = 0.0;
- var aLength = a.length;
- for (var i = 0; i < aLength; ++i)
- r += a[i] * a[i];
- return Math.sqrt(r);
-};
-
-/**
- * Computes the square of the Euclidean length of a vector, i.e. the sum
- * of the squares of the entries.
- * @param {!o3djs.flat_math.Vector} a The vector.
- * @return {number} The square of the length of a.
- */
-o3djs.flat_math.lengthSquared = function(a) {
- var r = 0.0;
- var aLength = a.length;
- for (var i = 0; i < aLength; ++i)
- r += a[i] * a[i];
- return r;
-};
-
-/**
- * Computes the Euclidean distance between two vectors.
- * @param {!o3djs.flat_math.Vector} a A vector.
- * @param {!o3djs.flat_math.Vector} b A vector.
- * @return {number} The distance between a and b.
- */
-o3djs.flat_math.distance = function(a, b) {
- var r = 0.0;
- var aLength = a.length;
- for (var i = 0; i < aLength; ++i) {
- var t = a[i] - b[i];
- r += t * t;
- }
- return Math.sqrt(r);
-};
-
-/**
- * Computes the square of the Euclidean distance between two vectors.
- * @param {!o3djs.flat_math.Vector} a A vector.
- * @param {!o3djs.flat_math.Vector} b A vector.
- * @return {number} The distance between a and b.
- */
-o3djs.flat_math.distanceSquared = function(a, b) {
- var r = 0.0;
- var aLength = a.length;
- for (var i = 0; i < aLength; ++i) {
- var t = a[i] - b[i];
- r += t * t;
- }
- return r;
-};
-
-/**
- * Divides a vector by its Euclidean length and returns the quotient.
- * @param {!o3djs.flat_math.Vector} a The vector.
- * @return {!o3djs.flat_math.Vector} The normalized vector.
- */
-o3djs.flat_math.normalize = function(a) {
- var aLength = a.length;
- var r = new o3djs.flat_math.Vector(aLength);
- var n = 0.0;
- var i;
- for (i = 0; i < aLength; ++i)
- n += a[i] * a[i];
- n = Math.sqrt(n);
- for (i = 0; i < aLength; ++i)
- r[i] = a[i] / n;
- return r;
-};
-
-/**
- * Adds two matrices; assumes a and b are the same size.
- * @param {!o3djs.flat_math.Matrix} a Operand matrix.
- * @param {!o3djs.flat_math.Matrix} b Operand matrix.
- * @return {!o3djs.flat_math.Matrix} The sum of a and b.
- */
-o3djs.flat_math.addMatrix = function(a, b) {
- var aLength = a.length;
- var r = new o3djs.flat_math.Matrix(aLength);
- for (var i = 0; i < aLength; ++i) {
- r[i] = a[i] + b[i];
- }
- return r;
-};
-
-/**
- * Subtracts two matrices; assumes a and b are the same size.
- * @param {!o3djs.flat_math.Matrix} a Operand matrix.
- * @param {!o3djs.flat_math.Matrix} b Operand matrix.
- * @return {!o3djs.flat_math.Matrix} The sum of a and b.
- */
-o3djs.flat_math.subMatrix = function(a, b) {
- var aLength = a.length;
- var r = new o3djs.flat_math.Matrix(aLength);
- for (var i = 0; i < aLength; ++i) {
- r[i] = a[i] - b[i];
- }
- return r;
-};
-
-/**
- * Performs linear interpolation on two matrices.
- * Given matrices a and b and interpolation coefficient t, returns
- * (1 - t) * a + t * b.
- * @param {!o3djs.flat_math.Matrix} a Operand matrix.
- * @param {!o3djs.flat_math.Matrix} b Operand matrix.
- * @param {number} t Interpolation coefficient.
- * @return {!o3djs.flat_math.Matrix} Interpolated a and b.
- */
-o3djs.flat_math.lerpMatrix = function(a, b, t) {
- var aLength = a.length;
- var r = new o3djs.flat_math.Matrix(aLength);
- for (var i = 0; i < aLength; ++i) {
- r[i] = (1 - t) * a[i] + t * b[i];
- }
- return r;
-};
-
-/**
- * Divides a matrix by a scalar; assumes a and b are the same size.
- * @param {!o3djs.flat_math.Matrix} a Operand matrix.
- * @param {number} b scalar
- * @return {!o3djs.flat_math.Matrix} The division of a by b.
- */
-o3djs.flat_math.divMatrixScalar = function(a, b) {
- var aLength = a.length;
- var r = new o3djs.flat_math.Matrix(aLength);
- for (var i = 0; i < aLength; ++i) {
- r[i] = a[i] / b;
- }
- return r;
-};
-
-/**
- * Negates a scalar.
- * @param {number} a The scalar.
- * @return {number} -a.
- */
-o3djs.flat_math.negativeScalar = function(a) {
- return -a;
-};
-
-/**
- * Negates a vector.
- * @param {!o3djs.flat_math.Vector} v The vector.
- * @return {!o3djs.flat_math.Vector} -v.
- */
-o3djs.flat_math.negativeVector = function(v) {
- var vLength = v.length;
- var r = new o3djs.flat_math.Vector(vLength);
- for (var i = 0; i < vLength; ++i) {
- r[i] = -v[i];
- }
- return r;
-};
-
-/**
- * Negates a matrix.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @return {!o3djs.flat_math.Matrix} -m.
- */
-o3djs.flat_math.negativeMatrix = function(m) {
- var mLength = m.length;
- var r = new o3djs.flat_math.Matrix(mLength);
- for (var i = 0; i < mLength; ++i) {
- r[i] = -m[i];
- }
- return r;
-};
-
-/**
- * Copies a scalar.
- * @param {number} a The scalar.
- * @return {number} a.
- */
-o3djs.flat_math.copyScalar = function(a) {
- return a;
-};
-
-/**
- * Copies a vector.
- * @param {!o3djs.flat_math.Vector} v The vector.
- * @return {!o3djs.flat_math.Vector} A copy of v.
- */
-o3djs.flat_math.copyVector = function(v) {
- var vLength = v.length;
- var r = new o3djs.flat_math.Vector(vLength);
- for (var i = 0; i < vLength; i++)
- r[i] = v[i];
- return r;
-};
-
-/**
- * Copies a vector.
- * @param {!o3djs.flat_math.Vector} v The vector.
- * @param {!o3djs.flat_math.Vector} r Set to a copy of v.
- */
-o3djs.flat_math.copyVectorTo = function(v, r) {
- var vLength = v.length;
- for (var i = 0; i < vLength; i++)
- r[i] = v[i];
-};
-
-/**
- * Copies a matrix.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @return {!o3djs.flat_math.Matrix} A copy of m.
- */
-o3djs.flat_math.copyMatrix = o3djs.flat_math.copyVector;
-
-/**
- * Copies a matrix.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @return {!o3djs.flat_math.Matrix} A copy of m.
- */
-o3djs.flat_math.copyMatrixTo = o3djs.flat_math.copyVectorTo;
-
-/**
- * Returns the elements of a matrix as a copied one-dimensional array. The
- * rows or columns (depending on whether the matrix is row-major or
- * column-major) are concatenated.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @return {!Array.<number>} The matrix's elements as a one-dimensional array.
- */
-o3djs.flat_math.getMatrixElements = o3djs.flat_math.copyMatrix;
-
-/**
- * Multiplies two scalars.
- * @param {number} a Operand scalar.
- * @param {number} b Operand scalar.
- * @return {number} The product of a and b.
- */
-o3djs.flat_math.mulScalarScalar = function(a, b) {
- return a * b;
-};
-
-/**
- * Multiplies a scalar by a vector.
- * @param {number} k The scalar.
- * @param {!o3djs.flat_math.Vector} v The vector.
- * @return {!o3djs.flat_math.Vector} The product of k and v.
- */
-o3djs.flat_math.mulScalarVector = function(k, v) {
- var vLength = v.length;
- var r = new o3djs.flat_math.Vector(vLength);
- for (var i = 0; i < vLength; ++i) {
- r[i] = k * v[i];
- }
- return r;
-};
-
-/**
- * Multiplies a vector by a scalar.
- * @param {!o3djs.flat_math.Vector} v The vector.
- * @param {number} k The scalar.
- * @return {!o3djs.flat_math.Vector} The product of k and v.
- */
-o3djs.flat_math.mulVectorScalar = function(v, k) {
- return o3djs.flat_math.mulScalarVector(k, v);
-};
-
-/**
- * Multiplies a scalar by a matrix.
- * @param {number} k The scalar.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @return {!o3djs.flat_math.Matrix} The product of m and k.
- */
-o3djs.flat_math.mulScalarMatrix = o3djs.flat_math.mulScalarVector;
-
-/**
- * Multiplies a matrix by a scalar.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @param {number} k The scalar.
- * @return {!o3djs.flat_math.Matrix} The product of m and k.
- */
-o3djs.flat_math.mulMatrixScalar = o3djs.flat_math.mulVectorScalar;
-
-/**
- * Multiplies a vector by another vector (component-wise); assumes a and
- * b have the same length.
- * @param {!o3djs.flat_math.Vector} a Operand vector.
- * @param {!o3djs.flat_math.Vector} b Operand vector.
- * @return {!o3djs.flat_math.Vector} The vector of products of entries of a and
- * b.
- */
-o3djs.flat_math.mulVectorVector = function(a, b) {
- var aLength = a.length;
- var r = new o3djs.flat_math.Vector(aLength);
- for (var i = 0; i < aLength; ++i)
- r[i] = a[i] * b[i];
- return r;
-};
-
-/**
- * Divides a vector by another vector (component-wise); assumes a and
- * b have the same length.
- * @param {!o3djs.flat_math.Vector} a Operand vector.
- * @param {!o3djs.flat_math.Vector} b Operand vector.
- * @return {!o3djs.flat_math.Vector} The vector of quotients of entries of a and
- * b.
- */
-o3djs.flat_math.divVectorVector = function(a, b) {
- var aLength = a.length;
- var r = new o3djs.flat_math.Vector(aLength);
- for (var i = 0; i < aLength; ++i)
- r[i] = a[i] / b[i];
- return r;
-};
-
-/**
- * Multiplies a vector by a matrix; treats the vector as a row vector; assumes
- * matrix entries are accessed in [row*4+column] fashion.
- * @param {!o3djs.flat_math.Vector} v The vector.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @return {!o3djs.flat_math.Vector} The product of v and m as a row vector.
- */
-o3djs.flat_math.rowMajor.mulVectorMatrix4 = function(v, m) {
- var r = new o3djs.flat_math.Vector(16);
- for (var i = 0; i < 4; ++i) {
- r[i] = 0.0;
- for (var j = 0; j < 4; ++j)
- r[i] += v[j] * m[j * 4 + i];
- }
- return r;
-};
-
-/**
- * Multiplies a vector by a matrix; treats the vector as a row vector; assumes
- * matrix entries are accessed in [row*2+column] fashion.
- * @param {!o3djs.flat_math.Vector} v The vector.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @returns {!o3djs.flat_math.Vector} The product of v and m as a row vector.
- */
-o3djs.flat_math.rowMajor.mulVectorMatrix2 = function(v, m) {
- var r = new o3djs.flat_math.Vector(4);
- for (var i = 0; i < 2; ++i) {
- r[i] = 0.0;
- for (var j = 0; j < 2; ++j)
- r[i] += v[j] * m[j * 2 + i];
- }
- return r;
-};
-
-
-/**
- * Multiplies a vector by a matrix; treats the vector as a row vector; assumes
- * matrix entries are accessed in [row*3+column] fashion.
- * @param {!o3djs.flat_math.Vector} v The vector.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @returns {!o3djs.flat_math.Vector} The product of v and m as a row vector.
- */
-o3djs.flat_math.rowMajor.mulVectorMatrix3 = function(v, m) {
- var r = new o3djs.flat_math.Vector(9);
- for (var i = 0; i < 3; ++i) {
- r[i] = 0.0;
- for (var j = 0; j < 3; ++j)
- r[i] += v[j] * m[j * 3 + i];
- }
- return r;
-};
-
-
-/**
- * Multiplies a vector by a matrix; treats the vector as a row vector; assumes
- * matrix entries are accessed in [row*dimension+column] fashion.
- * @param {!o3djs.flat_math.Vector} v The vector.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @return {!o3djs.flat_math.Vector} The product of v and m as a row vector.
- */
-o3djs.flat_math.rowMajor.mulVectorMatrix = function(v, m) {
- switch(m.length) {
- case 4:
- return o3djs.flat_math.rowMajor.mulVectorMatrix2(v, m);
- case 9:
- return o3djs.flat_math.rowMajor.mulVectorMatrix3(v, m);
- case 16:
- return o3djs.flat_math.rowMajor.mulVectorMatrix4(v, m);
- default:
- throw "Cannot handle matrices of size other than 3x3 or 4x4";
- }
-};
-
-
-
-/**
- * Multiplies a vector by a matrix; treats the vector as a row vector; assumes
- * matrix entries are accessed in [column*4+row] fashion.
- * @param {!o3djs.flat_math.Vector} v The vector.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @return {!o3djs.flat_math.Vector} The product of v and m as a row vector.
- */
-o3djs.flat_math.rowMajor.mulMatrixVector4 = function(m, v) {
- var r = new o3djs.flat_math.Vector(4);
- var vLength = v.length;
- for (var i = 0; i < 4; ++i) {
- r[i] = 0.0;
- for (var j = 0; j < 4; ++j)
- r[i] += v[j] * m[i * 4 + j];
- }
- return r;
-};
-
-
-/**
- * Multiplies a vector by a matrix; treats the vector as a row vector; assumes
- * matrix entries are accessed in [column*3+row] fashion.
- * @param {!o3djs.flat_math.Vector} v The vector.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @return {!o3djs.flat_math.Vector} The product of v and m as a row vector.
- */
-o3djs.flat_math.rowMajor.mulMatrixVector3 = function(m, v) {
- var r = new o3djs.flat_math.Vector(3);
- var vLength = v.length;
- for (var i = 0; i < 3; ++i) {
- r[i] = 0.0;
- for (var j = 0; j < 3; ++j)
- r[i] += v[j] * m[i * 3 + j];
- }
- return r;
-};
-
-/**
- * Multiplies a vector by a matrix; treats the vector as a row vector; assumes
- * matrix entries are accessed in [column*2+row] fashion.
- * @param {!o3djs.flat_math.Vector} v The vector.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @return {!o3djs.flat_math.Vector} The product of v and m as a row vector.
- */
-o3djs.flat_math.rowMajor.mulMatrixVector2 = function(m, v) {
- var r = new o3djs.flat_math.Vector(2);
-
- var vLength = v.length;
- for (var i = 0; i < 2; ++i) {
- r[i] = 0.0;
- for (var j = 0; j < 2; ++j)
- r[i] += v[j] * m[i * 2 + j];
- }
- return r;
-};
-
-
-/**
- * Multiplies a vector by a matrix; treats the vector as a row vector; assumes
- * matrix entries are accessed in [column*dimension+row] fashion.
- * @param {!o3djs.flat_math.Vector} v The vector.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @return {!o3djs.flat_math.Vector} The product of v and m as a row vector.
- */
-o3djs.flat_math.rowMajor.mulMatrixVector = function(m, v) {
- switch(m.length) {
- case 4:
- return o3djs.flat_math.rowMajor.mulMatrixVector2(m, v);
- case 9:
- return o3djs.flat_math.rowMajor.mulMatrixVector3(m, v);
- case 16:
- return o3djs.flat_math.rowMajor.mulMatrixVector4(m, v);
- default:
- throw "Cannot handle matrices of size other than 3x3 or 4x4";
- }
-};
-
-/**
- * Multiplies a vector by a matrix; treats the vector as a row vector.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @param {!o3djs.flat_math.Vector} v The vector.
- * @return {!o3djs.flat_math.Vector} The product of m and v as a row vector.
- */
-o3djs.flat_math.mulVectorMatrix = null;
-
-/**
- * Multiplies a matrix by a vector; treats the vector as a column vector.
- * assumes matrix entries are accessed in [row][column] fashion.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @param {!o3djs.flat_math.Vector} v The vector.
- * @return {!o3djs.flat_math.Vector} The product of m and v as a column vector.
- */
-o3djs.flat_math.columnMajor.mulVectorMatrix = function (v, m) {
- return o3djs.flat_math.rowMajor.mulMatrixVector(m, v);
-};
-
-/**
- * Multiplies a matrix by a vector; treats the vector as a column vector;
- * assumes matrix entries are accessed in [column][row] fashion.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @param {!o3djs.flat_math.Vector} v The vector.
- * @return {!o3djs.flat_math.Vector} The product of m and v as a column vector.
- */
-o3djs.flat_math.columnMajor.mulMatrixVector = function(m, v) {
- return o3djs.flat_math.rowMajor.mulVectorMatrix(v, m);
-};
-
-/**
- * Multiplies a matrix by a vector; treats the vector as a column vector.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @param {!o3djs.flat_math.Vector} v The vector.
- * @return {!o3djs.flat_math.Vector} The product of m and v as a column vector.
- */
-o3djs.flat_math.mulMatrixVector = null;
-
-/**
- * Multiplies two 2-by-2 matrices; assumes that the given matrices are 2-by-2;
- * assumes matrix entries are accessed in [row][column] fashion.
- * @param {!o3djs.flat_math.Matrix2} a The matrix on the left.
- * @param {!o3djs.flat_math.Matrix2} b The matrix on the right.
- * @return {!o3djs.flat_math.Matrix2} The matrix product of a and b.
- */
-o3djs.flat_math.rowMajor.mulMatrixMatrix2 = function(a, b) {
- var a0 = a[0];
- var a1 = a[1];
- var b0 = b[0];
- var b1 = b[1];
- var a00 = a[0];
- var a01 = a[1];
- var a10 = a[2];
- var a11 = a[3];
- var b00 = b[0];
- var b01 = b[1];
- var b10 = b[2];
- var b11 = b[3];
- return o3djs.flat_math.makeMatrix2(a00 * b00 + a01 * b10, a00 * b01 + a01 * b11,
- a10 * b00 + a11 * b10, a10 * b01 + a11 * b11);
-};
-
-/**
- * Multiplies two 2-by-2 matrices; assumes that the given matrices are 2-by-2;
- * assumes matrix entries are accessed in [column][row] fashion.
- * @param {!o3djs.flat_math.Matrix2} a The matrix on the left.
- * @param {!o3djs.flat_math.Matrix2} b The matrix on the right.
- * @return {!o3djs.flat_math.Matrix2} The matrix product of a and b.
- */
-o3djs.flat_math.columnMajor.mulMatrixMatrix2 = function(a, b) {
- var a0 = a[0];
- var a1 = a[1];
- var b0 = b[0];
- var b1 = b[1];
- var a00 = a[0];
- var a01 = a[1];
- var a10 = a[2];
- var a11 = a[3];
- var b00 = b[0];
- var b01 = b[1];
- var b10 = b[2];
- var b11 = b[3];
- return o3djs.flat_math.makeMatrix2(a00 * b00 + a10 * b01, a01 * b00 + a11 * b01,
- a00 * b10 + a10 * b11, a01 * b10 + a11 * b11);
-};
-
-/**
- * Multiplies two 2-by-2 matrices.
- * @param {!o3djs.flat_math.Matrix2} a The matrix on the left.
- * @param {!o3djs.flat_math.Matrix2} b The matrix on the right.
- * @return {!o3djs.flat_math.Matrix2} The matrix product of a and b.
- */
-o3djs.flat_math.mulMatrixMatrix2 = null;
-
-
-/**
- * Multiplies two 3-by-3 matrices; assumes that the given matrices are 3-by-3;
- * assumes matrix entries are accessed in [row][column] fashion.
- * @param {!o3djs.flat_math.Matrix3} a The matrix on the left.
- * @param {!o3djs.flat_math.Matrix3} b The matrix on the right.
- * @return {!o3djs.flat_math.Matrix3} The matrix product of a and b.
- */
-o3djs.flat_math.rowMajor.mulMatrixMatrix3 = function(a, b) {
- var a0 = a[0];
- var a1 = a[1];
- var a2 = a[2];
- var b0 = b[0];
- var b1 = b[1];
- var b2 = b[2];
- var a00 = a[0];
- var a01 = a[1];
- var a02 = a[2];
- var a10 = a[3];
- var a11 = a[4];
- var a12 = a[5];
- var a20 = a[6];
- var a21 = a[7];
- var a22 = a[8];
- var b00 = b[0];
- var b01 = b[1];
- var b02 = b[2];
- var b10 = b[3];
- var b11 = b[4];
- var b12 = b[5];
- var b20 = b[6];
- var b21 = b[7];
- var b22 = b[8];
- return o3djs.flat_math.makeMatrix3(a00 * b00 + a01 * b10 + a02 * b20,
- a00 * b01 + a01 * b11 + a02 * b21,
- a00 * b02 + a01 * b12 + a02 * b22,
- a10 * b00 + a11 * b10 + a12 * b20,
- a10 * b01 + a11 * b11 + a12 * b21,
- a10 * b02 + a11 * b12 + a12 * b22,
- a20 * b00 + a21 * b10 + a22 * b20,
- a20 * b01 + a21 * b11 + a22 * b21,
- a20 * b02 + a21 * b12 + a22 * b22);
-};
-
-/**
- * Multiplies two 3-by-3 matrices; assumes that the given matrices are 3-by-3;
- * assumes matrix entries are accessed in [column][row] fashion.
- * @param {!o3djs.flat_math.Matrix3} a The matrix on the left.
- * @param {!o3djs.flat_math.Matrix3} b The matrix on the right.
- * @return {!o3djs.flat_math.Matrix3} The matrix product of a and b.
- */
-o3djs.flat_math.columnMajor.mulMatrixMatrix3 = function(a, b) {
-
- var a00 = a[0];
- var a01 = a[1];
- var a02 = a[2];
- var a10 = a[3];
- var a11 = a[4];
- var a12 = a[5];
- var a20 = a[6];
- var a21 = a[7];
- var a22 = a[8];
- var b00 = b[0];
- var b01 = b[1];
- var b02 = b[2];
- var b10 = b[3];
- var b11 = b[4];
- var b12 = b[5];
- var b20 = b[6];
- var b21 = b[7];
- var b22 = b[8];
-
- return o3djs.flat_math.makeMatrix4(a00 * b00 + a10 * b01 + a20 * b02,
- a01 * b00 + a11 * b01 + a21 * b02,
- a02 * b00 + a12 * b01 + a22 * b02,
- a00 * b10 + a10 * b11 + a20 * b12,
- a01 * b10 + a11 * b11 + a21 * b12,
- a02 * b10 + a12 * b11 + a22 * b12,
- a00 * b20 + a10 * b21 + a20 * b22,
- a01 * b20 + a11 * b21 + a21 * b22,
- a02 * b20 + a12 * b21 + a22 * b22);
-};
-
-/**
- * Multiplies two 3-by-3 matrices; assumes that the given matrices are 3-by-3.
- * @param {!o3djs.flat_math.Matrix3} a The matrix on the left.
- * @param {!o3djs.flat_math.Matrix3} b The matrix on the right.
- * @return {!o3djs.flat_math.Matrix3} The matrix product of a and b.
- */
-o3djs.flat_math.mulMatrixMatrix3 = null;
-
-/**
- * Multiplies two 4-by-4 matrices; assumes that the given matrices are 4-by-4;
- * assumes matrix entries are accessed in [row][column] fashion.
- * @param {!o3djs.flat_math.Matrix4} a The matrix on the left.
- * @param {!o3djs.flat_math.Matrix4} b The matrix on the right.
- * @return {!o3djs.flat_math.Matrix4} The matrix product of a and b.
- */
-o3djs.flat_math.rowMajor.mulMatrixMatrix4 = function(a, b) {
-
- var a00 = a[0];
- var a01 = a[1];
- var a02 = a[2];
- var a03 = a[3];
- var a10 = a[4];
- var a11 = a[5];
- var a12 = a[6];
- var a13 = a[7];
- var a20 = a[8];
- var a21 = a[9];
- var a22 = a[10];
- var a23 = a[11];
- var a30 = a[12];
- var a31 = a[13];
- var a32 = a[14];
- var a33 = a[15];
- var b00 = b[0];
- var b01 = b[1];
- var b02 = b[2];
- var b03 = b[3];
- var b10 = b[4];
- var b11 = b[5];
- var b12 = b[6];
- var b13 = b[7];
- var b20 = b[8];
- var b21 = b[9];
- var b22 = b[10];
- var b23 = b[11];
- var b30 = b[12];
- var b31 = b[13];
- var b32 = b[14];
- var b33 = b[15];
- return o3djs.flat_math.makeMatrix4(a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30,
- a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31,
- a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32,
- a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33,
- a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30,
- a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31,
- a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32,
- a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33,
- a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30,
- a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31,
- a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32,
- a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33,
- a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30,
- a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31,
- a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32,
- a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33);
-};
-
-/**
- * Multiplies two 4-by-4 matrices; assumes that the given matrices are 4-by-4;
- * assumes matrix entries are accessed in [column][row] fashion.
- * @param {!o3djs.flat_math.Matrix4} a The matrix on the left.
- * @param {!o3djs.flat_math.Matrix4} b The matrix on the right.
- * @return {!o3djs.flat_math.Matrix4} The matrix product of a and b.
- */
-o3djs.flat_math.columnMajor.mulMatrixMatrix4 = function(a, b) {
-
- var a00 = a[0];
- var a01 = a[1];
- var a02 = a[2];
- var a03 = a[3];
- var a10 = a[4];
- var a11 = a[5];
- var a12 = a[6];
- var a13 = a[7];
- var a20 = a[8];
- var a21 = a[9];
- var a22 = a[10];
- var a23 = a[11];
- var a30 = a[12];
- var a31 = a[13];
- var a32 = a[14];
- var a33 = a[15];
- var b00 = b[0];
- var b01 = b[1];
- var b02 = b[2];
- var b03 = b[3];
- var b10 = b[4];
- var b11 = b[5];
- var b12 = b[6];
- var b13 = b[7];
- var b20 = b[8];
- var b21 = b[9];
- var b22 = b[10];
- var b23 = b[11];
- var b30 = b[12];
- var b31 = b[13];
- var b32 = b[14];
- var b33 = b[15];
- return o3djs.flat_math.makeMatrix4(
- a00 * b00 + a10 * b01 + a20 * b02 + a30 * b03,
- a01 * b00 + a11 * b01 + a21 * b02 + a31 * b03,
- a02 * b00 + a12 * b01 + a22 * b02 + a32 * b03,
- a03 * b00 + a13 * b01 + a23 * b02 + a33 * b03,
- a00 * b10 + a10 * b11 + a20 * b12 + a30 * b13,
- a01 * b10 + a11 * b11 + a21 * b12 + a31 * b13,
- a02 * b10 + a12 * b11 + a22 * b12 + a32 * b13,
- a03 * b10 + a13 * b11 + a23 * b12 + a33 * b13,
- a00 * b20 + a10 * b21 + a20 * b22 + a30 * b23,
- a01 * b20 + a11 * b21 + a21 * b22 + a31 * b23,
- a02 * b20 + a12 * b21 + a22 * b22 + a32 * b23,
- a03 * b20 + a13 * b21 + a23 * b22 + a33 * b23,
- a00 * b30 + a10 * b31 + a20 * b32 + a30 * b33,
- a01 * b30 + a11 * b31 + a21 * b32 + a31 * b33,
- a02 * b30 + a12 * b31 + a22 * b32 + a32 * b33,
- a03 * b30 + a13 * b31 + a23 * b32 + a33 * b33);
-};
-
-/**
- * Multiplies two 4-by-4 matrices; assumes that the given matrices are 4-by-4.
- * @param {!o3djs.flat_math.Matrix4} a The matrix on the left.
- * @param {!o3djs.flat_math.Matrix4} b The matrix on the right.
- * @return {!o3djs.flat_math.Matrix4} The matrix product of a and b.
- */
-o3djs.flat_math.mulMatrixMatrix4 = null;
-
-/**
- * Multiplies two matrices; assumes the matrices are square of size 2, 3 or 4;
- * assumes matrix entries are accessed in row-major fashion.
- * @param {!o3djs.flat_math.Matrix} a The matrix on the left.
- * @param {!o3djs.flat_math.Matrix} b The matrix on the right.
- * @return {!o3djs.flat_math.Matrix} The matrix product of a and b.
- */
-o3djs.flat_math.rowMajor.mulMatrixMatrix = function(a, b) {
- switch(a.length) {
- case 4:
- return o3djs.flat_math.rowMajor.mulMatrixMatrix2(a, b);
- case 9:
- return o3djs.flat_math.rowMajor.mulMatrixMatrix3(a, b);
- case 16:
- return o3djs.flat_math.rowMajor.mulMatrixMatrix4(a, b);
- default:
- throw "Unable to handle irregular matrices or matrices of dim > 4 or < 2";
- }
-};
-
-
-/**
- * Multiplies two matrices; assumes the matrices are square of size 2, 3 or 4;
- * assumes matrix entries are accessed in column-major fashion.
- * @param {!o3djs.flat_math.Matrix} a The matrix on the left.
- * @param {!o3djs.flat_math.Matrix} b The matrix on the right.
- * @return {!o3djs.flat_math.Matrix} The matrix product of a and b.
- */
-o3djs.flat_math.columnMajor.mulMatrixMatrix = function(a, b) {
- switch(a.length) {
- case 4:
- return o3djs.flat_math.columnMajor.mulMatrixMatrix2(a, b);
- case 9:
- return o3djs.flat_math.columnMajor.mulMatrixMatrix3(a, b);
- case 16:
- return o3djs.flat_math.columnMajor.mulMatrixMatrix4(a, b);
- default:
- throw "Unable to handle irregular matrices or matrices of dim > 4 or < 2";
- }
-};
-
-
-/**
- * Multiplies two matrices; assumes that the sizes of the matrices are
- * appropriately compatible; assumes matrix entries are accessed in
- * [column][row] fashion.
- * @param {!o3djs.flat_math.Matrix} a The matrix on the left.
- * @param {!o3djs.flat_math.Matrix} b The matrix on the right.
- * @return {!o3djs.flat_math.Matrix} The matrix product of a and b.
- */
-o3djs.flat_math.rowMajor.generalizedMulMatrixMatrix= function(a, b) {
- var r = [];
- var aRows = a.length;
- var bColumns = b[0].length;
- var bRows = b.length;
- for (var i = 0; i < aRows; ++i) {
- var v = []; // v becomes a row of the answer.
- var ai = a[i]; // ith row of a.
- for (var j = 0; j < bColumns; ++j) {
- v[j] = 0.0;
- for (var k = 0; k < bRows; ++k)
- v[j] += ai[k] * b[k][j]; // kth row, jth column.
- }
- r[i] = v;
- }
- return r;
-};
-
-/**
- * Multiplies two matrices; assumes that the sizes of the matrices are
- * appropriately compatible.
- * @param {!o3djs.flat_math.Matrix} a The matrix on the left.
- * @param {!o3djs.flat_math.Matrix} b The matrix on the right.
- * @return {!o3djs.flat_math.Matrix} The matrix product of a and b.
- */
-o3djs.flat_math.mulMatrixMatrix = null;
-
-/**
- * Gets the jth column of the given matrix m; assumes matrix entries are
- * accessed in [row*dimension+column] fashion.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @param {number} j The index of the desired column.
- * @return {!o3djs.flat_math.Vector} The jth column of m as a vector.
- */
-o3djs.flat_math.rowMajor.column = function(m, j) {
- var mLength = m.length;
- var dimension;
- switch (mLength){
- case 4:
- dimension = 2;
- break;
- case 9:
- dimension = 3;
- break;
- case 16:
- dimension = 4;
- break;
- }
- var r = new o3djs.flat_math.Vector(dimension);
- for (var i = 0; i < dimension; ++i) {
- r[i] = m[i * dimension + j];
- }
- return r;
-};
-
-/**
- * Gets the jth column of the given matrix m; assumes matrix entries are
- * accessed in [column][row] fashion.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @param {number} j The index of the desired column.
- * @return {!o3djs.flat_math.Vector} The jth column of m as a vector.
- */
-o3djs.flat_math.columnMajor.column = function(m, j) {
- var dimension;
- var mLength = m.length;
- switch (mLength){
- case 4:
- dimension = 2;
- break;
- case 9:
- dimension = 3;
- break;
- case 16:
- dimension = 4;
- break;
- default:
- dimension = Math.sqrt(dimension);
- if (Math.round(dimension) * Math.round(dimension) != mLength) {
- throw "Calling column on nonsquare matrix";
- }
- }
- return m.slice(j * dimension, j * dimension + dimension);
-};
-
-/**
- * Gets the jth column of the given matrix m.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @param {number} j The index of the desired column.
- * @return {!o3djs.flat_math.Vector} The jth column of m as a vector.
- */
-o3djs.flat_math.column = null;
-
-/**
- * Gets the ith row of the given matrix m; assumes matrix entries are
- * accessed in [row][column] fashion.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @param {number} i The index of the desired row.
- * @return {!o3djs.flat_math.Vector} The ith row of m.
- */
-o3djs.flat_math.rowMajor.row = o3djs.flat_math.columnMajor.column;
-
-/**
- * Gets the ith row of the given matrix m; assumes matrix entries are
- * accessed in [column][row] fashion.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @param {number} i The index of the desired row.
- * @return {!o3djs.flat_math.Vector} The ith row of m.
- */
-o3djs.flat_math.columnMajor.row = o3djs.flat_math.rowMajor.column;
-
-/**
- * Gets the ith row of the given matrix m.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @param {number} i The index of the desired row.
- * @return {!o3djs.flat_math.Vector} The ith row of m.
- */
-o3djs.flat_math.row = null;
-
-/**
- * Creates an n-by-n identity matrix.
- * @param {number} n The dimension of the identity matrix required.
- * @return {!o3djs.flat_math.Matrix} An n-by-n identity matrix.
- */
-o3djs.flat_math.identity = function(n) {
- var r = new o3djs.flat_math.Matrix(n*n);
-
- for (var j = 0; j < n; ++j) {
- for (var i = 0; i < n; ++i)
- r[j * n + i] = (i == j) ? 1 : 0;
- }
- return r;
-};
-
-/**
- * Takes the transpose of a matrix.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @return {!o3djs.flat_math.Matrix} The transpose of m.
- */
-o3djs.flat_math.transpose = function(m) {
- var mLength = m.length;
- var r = new o3djs.flat_math.Matrix(mLength);
- var dimension;
- switch (mLength){
- case 4:
- dimension = 2;
- break;
- case 9:
- dimension = 3;
- break;
- case 16:
- dimension = 4;
- break;
- default:
- dimension = Math.sqrt(dimension);
- if (Math.round(dimension) * Math.round(dimension) != mLength) {
- throw "Calling transpose on nonsquare matrix";
- }
- }
-
- for (var j = 0; j < dimension; ++j) {
- for (var i = 0; i < dimension; ++i)
- r[j * dimension + i] = m[i * dimension + j];
- }
- return r;
-};
-
-/**
- * Computes the trace (sum of the diagonal entries) of a square matrix;
- * assumes m is square.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @return {number} The trace of m.
- */
-o3djs.flat_math.trace = function(m) {
- var r = 0.0;
- var dimension;
- switch (mLength){
- case 4:
- dimension = 2;
- break;
- case 9:
- dimension = 3;
- break;
- case 16:
- dimension = 4;
- break;
- }
- var mLength = dimension;
- for (var i = 0; i < mLength; ++i)
- r += m[i * dimension + i];
- return r;
-};
-
-/**
- * Computes the determinant of a 1-by-1 matrix.
- * @param {!o3djs.flat_math.Matrix1} m The matrix.
- * @return {number} The determinant of m.
- */
-o3djs.flat_math.det1 = function(m) {
- return m[0];
-};
-
-/**
- * Computes the determinant of a 2-by-2 matrix.
- * @param {!o3djs.flat_math.Matrix2} m The matrix.
- * @return {number} The determinant of m.
- */
-o3djs.flat_math.det2 = function(m) {
- return m[0] * m[3] - m[1] * m[2];
-};
-
-/**
- * Computes the determinant of a 3-by-3 matrix.
- * @param {!o3djs.flat_math.Matrix3} m The matrix.
- * @return {number} The determinant of m.
- */
-o3djs.flat_math.det3 = function(m) {
- return m[8] * (m[0 * 3] * m[4] - m[1] * m[1 * 3]) -
- m[7] * (m[0 * 3] * m[5] - m[2] * m[1 * 3]) +
- m[2 * 3] * (m[1] * m[5] - m[2] * m[4]);
-};
-
-/**
- * Computes the determinant of a 4-by-4 matrix.
- * @param {!o3djs.flat_math.Matrix4} m The matrix.
- * @return {number} The determinant of m.
- */
-o3djs.flat_math.det4 = function(m) {
- var t01 = m[0] * m[5] - m[1] * m[4];
- var t02 = m[0] * m[6] - m[2] * m[4];
- var t03 = m[0] * m[7] - m[3] * m[4];
- var t12 = m[1] * m[6] - m[2] * m[5];
- var t13 = m[1] * m[7] - m[3] * m[5];
- var t23 = m[2] * m[7] - m[3] * m[6];
- return m[15] * (m[10] * t01 - m[9] * t02 + m[8] * t12) -
- m[14] * (m[11] * t01 - m[9] * t03 + m[8] * t13) +
- m[13] * (m[11] * t02 - m[10] * t03 + m[8] * t23) -
- m[12] * (m[11] * t12 - m[10] * t13 + m[9] * t23);
-};
-
-/**
- * Computes the inverse of a 1-by-1 matrix.
- * @param {!o3djs.flat_math.Matrix1} m The matrix.
- * @return {!o3djs.flat_math.Matrix1} The inverse of m.
- */
-o3djs.flat_math.inverse1 = function(m) {
- var retval = new o3djs.flat_math.Matrix(1);
- retval[0] = 1.0 / m[0];
- return retval;
-};
-
-/**
- * Computes the inverse of a 2-by-2 matrix.
- * @param {!o3djs.flat_math.Matrix2} m The matrix.
- * @return {!o3djs.flat_math.Matrix2} The inverse of m.
- */
-o3djs.flat_math.inverse2 = function(m) {
- var d = 1.0 / (m[0] * m[3] - m[1] * m[2]);
- return o3djs.flat_math.makeMatrix2(d * m[3], -d * m[1],
- -d * m[2], d * m[0]);
-};
-
-/**
- * Computes the inverse of a 3-by-3 matrix.
- * @param {!o3djs.flat_math.Matrix3} m The matrix.
- * @return {!o3djs.flat_math.Matrix3} The inverse of m.
- */
-o3djs.flat_math.inverse3 = function(m) {
- var t00 = m[4] * m[8] - m[5] * m[7];
- var t10 = m[1] * m[8] - m[2] * m[7];
- var t20 = m[1] * m[5] - m[2] * m[4];
- var d = 1.0 / (m[0] * t00 - m[3] * t10 + m[6] * t20);
- return o3djs.flat_math.makeMatrix3(d * t00, -d * t10, d * t20,
- -d * (m[3] * m[8] - m[5] * m[6]),
- d * (m[0] * m[8] - m[2] * m[6]),
- -d * (m[0] * m[5] - m[2] * m[3]),
- d * (m[3] * m[7] - m[4] * m[6]),
- -d * (m[0] * m[7] - m[1] * m[6]),
- d * (m[0] * m[4] - m[1] * m[3]));
-};
-
-/**
- * Computes the inverse of a 4-by-4 matrix.
- * @param {!o3djs.flat_math.Matrix4} m The matrix.
- * @return {!o3djs.flat_math.Matrix4} The inverse of m.
- */
-o3djs.flat_math.inverse4 = function(m) {
- var tmp_0 = m[10] * m[15];
- var tmp_1 = m[14] * m[11];
- var tmp_2 = m[6] * m[15];
- var tmp_3 = m[14] * m[7];
- var tmp_4 = m[6] * m[11];
- var tmp_5 = m[10] * m[7];
- var tmp_6 = m[2] * m[15];
- var tmp_7 = m[14] * m[3];
- var tmp_8 = m[2] * m[11];
- var tmp_9 = m[10] * m[3];
- var tmp_10 = m[2] * m[7];
- var tmp_11 = m[6] * m[3];
- var tmp_12 = m[8] * m[13];
- var tmp_13 = m[12] * m[9];
- var tmp_14 = m[4] * m[13];
- var tmp_15 = m[12] * m[5];
- var tmp_16 = m[4] * m[9];
- var tmp_17 = m[8] * m[5];
- var tmp_18 = m[0] * m[13];
- var tmp_19 = m[12] * m[1];
- var tmp_20 = m[0] * m[9];
- var tmp_21 = m[8] * m[1];
- var tmp_22 = m[0] * m[5];
- var tmp_23 = m[4] * m[1];
-
- var t0 = tmp_0 * m[5] + tmp_3 * m[9] + tmp_4 * m[13] -
- (tmp_1 * m[5] + tmp_2 * m[9] + tmp_5 * m[13]);
- var t1 = tmp_1 * m[1] + tmp_6 * m[9] + tmp_9 * m[13] -
- (tmp_0 * m[1] + tmp_7 * m[9] + tmp_8 * m[13]);
- var t2 = tmp_2 * m[1] + tmp_7 * m[5] + tmp_10 * m[13] -
- (tmp_3 * m[1] + tmp_6 * m[5] + tmp_11 * m[13]);
- var t3 = (tmp_5 * m[1] + tmp_8 * m[5] + tmp_11 * m[9]) -
- (tmp_4 * m[1] + tmp_9 * m[5] + tmp_10 * m[9]);
-
- var d = 1.0 / (m[0] * t0 + m[1 * 4] * t1 + m[8] * t2 + m[12] * t3);
-
- return o3djs.flat_math.makeMatrix4(d * t0, d * t1, d * t2, d * t3,
- d * ((tmp_1 * m[1 * 4] + tmp_2 * m[8] + tmp_5 * m[12]) -
- (tmp_0 * m[1 * 4] + tmp_3 * m[8] + tmp_4 * m[12])),
- d * ((tmp_0 * m[0 * 4] + tmp_7 * m[8] + tmp_8 * m[12]) -
- (tmp_1 * m[0 * 4] + tmp_6 * m[8] + tmp_9 * m[12])),
- d * ((tmp_3 * m[0 * 4] + tmp_6 * m[1 * 4] + tmp_11 * m[12]) -
- (tmp_2 * m[0 * 4] + tmp_7 * m[1 * 4] + tmp_10 * m[12])),
- d * ((tmp_4 * m[0 * 4] + tmp_9 * m[1 * 4] + tmp_10 * m[8]) -
- (tmp_5 * m[0 * 4] + tmp_8 * m[1 * 4] + tmp_11 * m[8])),
- d * ((tmp_12 * m[4 + 3] + tmp_15 * m[11] + tmp_16 * m[15]) -
- (tmp_13 * m[4 + 3] + tmp_14 * m[11] + tmp_17 * m[15])),
- d * ((tmp_13 * m[3] + tmp_18 * m[11] + tmp_21 * m[15]) -
- (tmp_12 * m[3] + tmp_19 * m[11] + tmp_20 * m[15])),
- d * ((tmp_14 * m[3] + tmp_19 * m[7] + tmp_22 * m[15]) -
- (tmp_15 * m[3] + tmp_18 * m[7] + tmp_23 * m[15])),
- d * ((tmp_17 * m[3] + tmp_20 * m[7] + tmp_23 * m[11]) -
- (tmp_16 * m[3] + tmp_21 * m[7] + tmp_22 * m[11])),
- d * ((tmp_14 * m[10] + tmp_17 * m[14] + tmp_13 * m[4 + 2]) -
- (tmp_16 * m[14] + tmp_12 * m[4 + 2] + tmp_15 * m[10])),
- d * ((tmp_20 * m[14] + tmp_12 * m[2] + tmp_19 * m[10]) -
- (tmp_18 * m[10] + tmp_21 * m[14] + tmp_13 * m[2])),
- d * ((tmp_18 * m[6] + tmp_23 * m[14] + tmp_15 * m[2]) -
- (tmp_22 * m[14] + tmp_14 * m[2] + tmp_19 * m[6])),
- d * ((tmp_22 * m[10] + tmp_16 * m[2] + tmp_21 * m[6]) -
- (tmp_20 * m[6] + tmp_23 * m[10] + tmp_17 * m[2])));
-};
-
-/**
- * Computes the determinant of the cofactor matrix obtained by removal
- * of a specified row and column. This is a helper function for the general
- * determinant and matrix inversion functions.
- * @param {!o3djs.flat_math.Matrix} a The original matrix.
- * @param {number} x The row to be removed.
- * @param {number} y The column to be removed.
- * @return {number} The determinant of the matrix obtained by removing
- * row x and column y from a.
- */
-o3djs.flat_math.codet = function(a, x, y) {
- var aLength = a.length;
- var size;
- switch (aLength) {
- case 4:
- size = 2;
- break;
- case 9:
- size = 3;
- break;
- case 16:
- size = 4;
- break;
- default:
- size=Math.sqrt(aLength);
- if (Math.round(size) * Math.round(size) != aLength) {
- throw "Calling codet on nonsquare matrix";
- }
- }
- var b = new o3djs.flat_math.Matrix(aLength);
- var ai = 0;
- for (var bi = 0; bi < size - 1; ++bi) {
- if (ai == x)
- ai++;
- var aj = 0;
- for (var bj = 0; bj < size - 1; ++bj) {
- if (aj == y)
- aj++;
- b[bi*size+bj] = a[ai*size+aj];
- aj++;
- }
- ai++;
- }
- return o3djs.flat_math.det(b);
-};
-
-/**
- * Computes the determinant of an arbitrary square matrix.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @return {number} the determinant of m.
- */
-o3djs.flat_math.det = function(m) {
- var d = m.length;
- switch (d) {
- case 4:
- return o3djs.flat_math.det2(m);
- case 9:
- return o3djs.flat_math.det3(m);
- case 16:
- return o3djs.flat_math.det4(m);
- default:
- d = Math.sqrt(d);
- if (Math.round(d) * Math.round(d) != m.length) {
- throw "Calling det on nonsquare matrix";
- }
- break;
- }
- var r = 0.0;
- var sign = 1;
- var row = m;
- var mLength = m.length;
- for (var y = 0; y < mLength; y++) {
- r += sign * m[0] * o3djs.flat_math.codet(m, 0, y);
- sign *= -1;
- }
- return r;
-};
-
-/**
- * Computes the inverse of an arbitrary square matrix.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @return {!o3djs.flat_math.Matrix} The inverse of m.
- */
-o3djs.flat_math.inverse = function(m) {
- var d = m.length;
- switch (d) {
- case 4:
- return o3djs.flat_math.inverse2(m);
- case 9:
- return o3djs.flat_math.inverse3(m);
- case 16:
- return o3djs.flat_math.inverse4(m);
- default:
- d = Math.sqrt(d);
- if (Math.round(d) * Math.round(d) != m.length) {
- throw "Calling inverse on nonsquare matrix";
- }
- break;
- }
- var r = new o3djs.flat_math.Matrix(m.length);
- var size = m.length;
- var det = o3djs.flat_math.det(m);
- for (var j = 0; j < size; ++j) {
- for (var i = 0; i < size; ++i)
- r[j * d + i] =
- ((i + j) % 2 ? -1 : 1) * o3djs.flat_math.codet(m, i, j) / det;
- }
- return r;
-};
-
-/**
- * Performs Graham-Schmidt orthogonalization on the vectors which make up the
- * given matrix and returns the result in the rows of a new matrix. When
- * multiplying many orthogonal matrices together, errors can accumulate causing
- * the product to fail to be orthogonal. This function can be used to correct
- * that.
- * @param {!o3djs.flat_math.Matrix} m The matrix.
- * @return {!o3djs.flat_math.Matrix} A matrix whose rows are obtained from the
- * rows of m by the Graham-Schmidt process.
- */
-o3djs.flat_math.orthonormalize = function(m) {
- var d = m.length;
- var r = new o3djs.flat_math.Matrix(d);
- switch (d) {
- case 4:
- d = 2; break;
- case 9:
- d = 3; break;
- case 16:
- d = 4; break;
- default:
- d = Math.sqrt(d);
- if (Math.round(d) * Math.round(d) != m.length) {
- throw "Calling orthonormalize on nonsquare matrix";
- }
- break;
- }
- for (var i = 0; i < d; ++i) {
- var v = m.slice(i*d,i*d+d);
- for (var j = 0; j < i; ++j) {
- v = o3djs.flat_math.subVector(v, o3djs.flat_math.mulScalarVector(
- o3djs.flat_math.dot(r[j], v), r[j]));
- }
- var ri = o3djs.flat_math.normalize(v);
- for (var k = 0; k < d; ++ k) {
- r[i * d +k ] = ri[k];
- }
- }
- return r;
-};
-
-/**
- * Computes the inverse of a 4-by-4 matrix.
- * Note: It is faster to call this than o3djs.flat_math.inverse.
- * @param {!o3djs.flat_math.Matrix4} m The matrix.
- * @return {!o3djs.flat_math.Matrix4} The inverse of m.
- */
-o3djs.flat_math.matrix4.inverse = function(m) {
- return o3djs.flat_math.inverse4(m);
-};
-
-/**
- * Multiplies two 4-by-4 matrices; assumes that the given matrices are 4-by-4.
- * Note: It is faster to call this than o3djs.flat_math.mul.
- * @param {!o3djs.flat_math.Matrix4} a The matrix on the left.
- * @param {!o3djs.flat_math.Matrix4} b The matrix on the right.
- * @return {!o3djs.flat_math.Matrix4} The matrix product of a and b.
- */
-o3djs.flat_math.matrix4.mul = function(a, b) {
- return o3djs.flat_math.mulMatrixMatrix4(a, b);
-};
-
-/**
- * Computes the determinant of a 4-by-4 matrix.
- * Note: It is faster to call this than o3djs.flat_math.det.
- * @param {!o3djs.flat_math.Matrix4} m The matrix.
- * @return {number} The determinant of m.
- */
-o3djs.flat_math.matrix4.det = function(m) {
- return o3djs.flat_math.det4(m);
-};
-
-/**
- * Copies a Matrix4.
- * Note: It is faster to call this than o3djs.flat_math.copy.
- * @param {!o3djs.flat_math.Matrix4} m The matrix.
- * @return {!o3djs.flat_math.Matrix4} A copy of m.
- */
-o3djs.flat_math.matrix4.copy = function(m) {
- return o3djs.flat_math.copyMatrix(m);
-};
-
-/**
- * Sets the upper 3-by-3 block of matrix a to the upper 3-by-3 block of matrix
- * b; assumes that a and b are big enough to contain an upper 3-by-3 block.
- * @param {!o3djs.flat_math.Matrix4} a A matrix.
- * @param {!o3djs.flat_math.Matrix3} b A 3-by-3 matrix.
- * @return {!o3djs.flat_math.Matrix4} a once modified.
- */
-o3djs.flat_math.matrix4.setUpper3x3 = function(a, b) {
- a[0] = b[0];
- a[1] = b[1];
- a[2] = b[2];
- a[4] = b[4];
- a[5] = b[5];
- a[6] = b[6];
- a[8] = b[8];
- a[9] = b[9];
- a[10] = b[10];
-
- return a;
-};
-
-/**
- * Returns a 3-by-3 matrix mimicking the upper 3-by-3 block of m; assumes m
- * is big enough to contain an upper 3-by-3 block.
- * @param {!o3djs.flat_math.Matrix4} m The matrix.
- * @return {!o3djs.flat_math.Matrix3} The upper 3-by-3 block of m.
- */
-o3djs.flat_math.matrix4.getUpper3x3 = function(m) {
- return o3djs.flat_math.makeMatrix3(
- m[0], m[1], m[2],
- m[4], m[5], m[6],
- m[8], m[9], m[10]);
-};
-
-/**
- * Sets the translation component of a 4-by-4 matrix to the given
- * vector.
- * @param {!o3djs.flat_math.Matrix4} a The matrix.
- * @param {(!o3djs.flat_math.Vector3|!o3djs.flat_math.Vector4)} v The vector.
- * @return {!o3djs.flat_math.Matrix4} a once modified.
- */
-o3djs.flat_math.matrix4.setTranslation = function(a, v) {
- a[12] = v[0];
- a[13] = v[1];
- a[14] = v[2];
- return a;
-};
-
-/**
- * Returns the translation component of a 4-by-4 matrix as a vector with 3
- * entries.
- * @param {!o3djs.flat_math.Matrix4} m The matrix.
- * @return {!o3djs.flat_math.Vector3} The translation component of m.
- */
-o3djs.flat_math.matrix4.getTranslation = function(m) {
- var retval =new o3djs.flat_math.Vector(3);
- retval[0] = m[12];
- retval[1] = m[13];
- retval[2] = m[14];
- return retval;
-};
-
-/**
- * Takes a 4-by-4 matrix and a vector with 3 entries,
- * interprets the vector as a point, transforms that point by the matrix, and
- * returns the result as a vector with 3 entries.
- * @param {!o3djs.flat_math.Matrix4} m The matrix.
- * @param {!o3djs.flat_math.Vector3} v The point.
- * @return {!o3djs.flat_math.Vector3} The transformed point.
- */
-o3djs.flat_math.matrix4.transformPoint = function(m, v) {
- var v0 = v[0];
- var v1 = v[1];
- var v2 = v[2];
-
- var d = v0 * m[3] +
- v1 * m[7] +
- v2 * m[11] +
- m[15];
- var retval = new o3djs.flat_math.Vector(3);
- retval[0] = (v0 * m[0] +
- v1 * m[4] +
- v2 * m[8] +
- m[12]) / d;
- retval[1] = (v0 * m[1] +
- v1 * m[5] +
- v2 * m[9] +
- m[13]) / d;
- retval[2] = (v0 * m[2] +
- v1 * m[6] +
- v2 * m[10] +
- m[14]) / d;
- return retval;
-};
-
-/**
- * Takes a 4-by-4 matrix and a vector with 4 entries, transforms that vector by
- * the matrix, and returns the result as a vector with 4 entries.
- * @param {!o3djs.flat_math.Matrix4} m The matrix.
- * @param {!o3djs.flat_math.Vector4} v The point in homogenous coordinates.
- * @return {!o3djs.flat_math.Vector4} The transformed point in homogenous
- * coordinates.
- */
-o3djs.flat_math.matrix4.transformVector4 = function(m, v) {
- var v0 = v[0];
- var v1 = v[1];
- var v2 = v[2];
- var v3 = v[3];
-
- return [v0 * m[0] +
- v1 * m[4] +
- v2 * m[8] +
- v3 * m[12],
- v0 * m[1] +
- v1 * m[5] +
- v2 * m[9] +
- v3 * m[13],
- v0 * m[2] +
- v1 * m[6] +
- v2 * m[10] +
- v3 * m[14],
- v0 * m[3] +
- v1 * m[7] +
- v2 * m[11] +
- v3 * m[15]];
-};
-
-/**
- * Takes a 4-by-4 matrix and a vector with 3 entries, interprets the vector as a
- * direction, transforms that direction by the matrix, and returns the result;
- * assumes the transformation of 3-dimensional space represented by the matrix
- * is parallel-preserving, i.e. any combination of rotation, scaling and
- * translation, but not a perspective distortion. Returns a vector with 3
- * entries.
- * @param {!o3djs.flat_math.Matrix4} m The matrix.
- * @param {!o3djs.flat_math.Vector3} v The direction.
- * @return {!o3djs.flat_math.Vector3} The transformed direction.
- */
-o3djs.flat_math.matrix4.transformDirection = function(m, v) {
- var v0 = v[0];
- var v1 = v[1];
- var v2 = v[2];
-
- return [v0 * m[0] +
- v1 * m[4] +
- v2 * m[8],
- v0 * m[1] +
- v1 * m[5] +
- v2 * m[9],
- v0 * m[2] +
- v1 * m[6] +
- v2 * m[10]];
-};
-
-/**
- * Takes a 4-by-4 matrix m and a vector v with 3 entries, interprets the vector
- * as a normal to a surface, and computes a vector which is normal upon
- * transforming that surface by the matrix. The effect of this function is the
- * same as transforming v (as a direction) by the inverse-transpose of m. This
- * function assumes the transformation of 3-dimensional space represented by the
- * matrix is parallel-preserving, i.e. any combination of rotation, scaling and
- * translation, but not a perspective distortion. Returns a vector with 3
- * entries.
- * @param {!o3djs.flat_math.Matrix4} m The matrix.
- * @param {!o3djs.flat_math.Vector3} v The normal.
- * @return {!o3djs.flat_math.Vector3} The transformed normal.
- */
-o3djs.flat_math.matrix4.transformNormal = function(m, v) {
- var mInverse = o3djs.flat_math.inverse4(m);
- var v0 = v[0];
- var v1 = v[1];
- var v2 = v[2];
-
- return [v0 * mInverse[0] + v1 * mInverse[1] + v2 * mInverse[2],
- v0 * mInverse[4] +
- v1 * mInverse[5] +
- v2 * mInverse[6],
- v0 * mInverse[8] +
- v1 * mInverse[9] +
- v2 * mInverse[10]];
-};
-
-/**
- * Creates a 4-by-4 identity matrix.
- * @return {!o3djs.flat_math.Matrix4} The 4-by-4 identity.
- */
-o3djs.flat_math.matrix4.identity = function() {
- return o3djs.flat_math.makeMatrix4(
- 1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1);
-};
-
-/**
- * Sets the given 4-by-4 matrix to the identity matrix.
- * @param {!o3djs.flat_math.Matrix4} m The matrix to set to identity.
- * @return {!o3djs.flat_math.Matrix4} m once modified.
- */
-o3djs.flat_math.matrix4.setIdentity = function(m) {
- for (var i = 0; i < 4; i++) {
- for (var j = 0; j < 4; j++) {
- if (i == j) {
- m[i * 4 + j] = 1;
- } else {
- m[i * 4 + j] = 0;
- }
- }
- }
- return m;
-};
-
-/**
- * Computes a 4-by-4 perspective transformation matrix given the angular height
- * of the frustum, the aspect ratio, and the near and far clipping planes. The
- * arguments define a frustum extending in the negative z direction. The given
- * angle is the vertical angle of the frustum, and the horizontal angle is
- * determined to produce the given aspect ratio. The arguments near and far are
- * the distances to the near and far clipping planes. Note that near and far
- * are not z coordinates, but rather they are distances along the negative
- * z-axis. The matrix generated sends the viewing frustum to the unit box.
- * We assume a unit box extending from -1 to 1 in the x and y dimensions and
- * from 0 to 1 in the z dimension.
- * @param {number} angle The camera angle from top to bottom (in radians).
- * @param {number} aspect The aspect ratio width / height.
- * @param {number} near The depth (negative z coordinate)
- * of the near clipping plane.
- * @param {number} far The depth (negative z coordinate)
- * of the far clipping plane.
- * @return {!o3djs.flat_math.Matrix4} The perspective matrix.
- */
-o3djs.flat_math.matrix4.perspective = function(angle, aspect, near, far) {
- var f = Math.tan(0.5 * (Math.PI - angle));
- var range = near - far;
-
- return o3djs.flat_math.makeMatrix4 (
- f / aspect, 0, 0, 0,
- 0, f, 0, 0,
- 0, 0, 2 * far / range + 1, -1,
- 0, 0, 2 * near * far / range, 0
- );
-};
-
-/**
- * Computes a 4-by-4 orthographic projection matrix given the coordinates of the
- * planes defining the axis-aligned, box-shaped viewing volume. The matrix
- * generated sends that box to the unit box. Note that although left and right
- * are x coordinates and bottom and top are y coordinates, near and far
- * are not z coordinates, but rather they are distances along the negative
- * z-axis. We assume a unit box extending from -1 to 1 in the x and y
- * dimensions and from 0 to 1 in the z dimension.
- * @param {number} left The x coordinate of the left plane of the box.
- * @param {number} right The x coordinate of the right plane of the box.
- * @param {number} bottom The y coordinate of the bottom plane of the box.
- * @param {number} top The y coordinate of the right plane of the box.
- * @param {number} near The negative z coordinate of the near plane of the box.
- * @param {number} far The negative z coordinate of the far plane of the box.
- * @return {!o3djs.flat_math.Matrix4} The orthographic projection matrix.
- */
-o3djs.flat_math.matrix4.orthographic =
- function(left, right, bottom, top, near, far) {
- return o3djs.flat_math.makeMatrix4 (
- 2 / (right - left), 0, 0, 0,
- 0, 2 / (top - bottom), 0, 0,
- 0, 0, 2 / (near - far), 0,
- (left + right) / (left - right),
- (bottom + top) / (bottom - top),
- (near + far) / (near - far), 1);
-};
-
-/**
- * Computes a 4-by-4 perspective transformation matrix given the left, right,
- * top, bottom, near and far clipping planes. The arguments define a frustum
- * extending in the negative z direction. The arguments near and far are the
- * distances to the near and far clipping planes. Note that near and far are not
- * z coordinates, but rather they are distances along the negative z-axis. The
- * matrix generated sends the viewing frustum to the unit box. We assume a unit
- * box extending from -1 to 1 in the x and y dimensions and from 0 to 1 in the z
- * dimension.
- * @param {number} left The x coordinate of the left plane of the box.
- * @param {number} right The x coordinate of the right plane of the box.
- * @param {number} bottom The y coordinate of the bottom plane of the box.
- * @param {number} top The y coordinate of the right plane of the box.
- * @param {number} near The negative z coordinate of the near plane of the box.
- * @param {number} far The negative z coordinate of the far plane of the box.
- * @return {!o3djs.flat_math.Matrix4} The perspective projection matrix.
- */
-o3djs.flat_math.matrix4.frustum = function(left, right, bottom, top, near, far) {
- var dx = (right - left);
- var dy = (top - bottom);
- var dz = (near - far);
- return o3djs.flat_math.makeMatrix4(
- 2 * near / dx, 0, 0, 0,
- 0, 2 * near / dy, 0, 0,
- (left + right) / dx, (top + bottom) / dy, far / dz, -1,
- 0, 0, near * far / dz, 0);
-};
-
-/**
- * Computes a 4-by-4 look-at transformation. The transformation generated is
- * an orthogonal rotation matrix with translation component. The translation
- * component sends the eye to the origin. The rotation component sends the
- * vector pointing from the eye to the target to a vector pointing in the
- * negative z direction, and also sends the up vector into the upper half of
- * the yz plane.
- * @param {(!o3djs.flat_math.Vector3|!o3djs.flat_math.Vector4)} eye The position
- * of the eye.
- * @param {(!o3djs.flat_math.Vector3|!o3djs.flat_math.Vector4)} target The
- * position meant to be viewed.
- * @param {(!o3djs.flat_math.Vector3|!o3djs.flat_math.Vector4)} up A vector
- * pointing up.
- * @return {!o3djs.flat_math.Matrix4} The look-at matrix.
- */
-o3djs.flat_math.matrix4.lookAt = function(eye, target, up) {
- var vz = o3djs.flat_math.normalize(
- o3djs.flat_math.subVector(eye, target).slice(0, 3));
- var vx = o3djs.flat_math.normalize(
- o3djs.flat_math.cross(up, vz));
- var vy = o3djs.flat_math.cross(vz, vx);
- return o3djs.flat_math.inverse4(o3djs.flat_math.makeMatrix4(
- vx[0], vx[1], vx[2], 0,
- vy[0], vy[1], vy[2], 0,
- vz[0], vz[1], vz[2], 0,
- eye[0], eye[1], eye[2], 1));
-};
-
-/**
- * Takes two 4-by-4 matrices, a and b, and computes the product in the order
- * that pre-composes b with a. In other words, the matrix returned will
- * transform by b first and then a. Note this is subtly different from just
- * multiplying the matrices together. For given a and b, this function returns
- * the same object in both row-major and column-major mode.
- * @param {!o3djs.flat_math.Matrix4} a A 4-by-4 matrix.
- * @param {!o3djs.flat_math.Matrix4} b A 4-by-4 matrix.
- * @return {!o3djs.flat_math.Matrix4} the composition of a and b, b first then a.
- */
-o3djs.flat_math.matrix4.composition = function(a, b) {
- var a00 = a[0];
- var a01 = a[1];
- var a02 = a[2];
- var a03 = a[3];
- var a10 = a[4];
- var a11 = a[5];
- var a12 = a[6];
- var a13 = a[7];
- var a20 = a[8];
- var a21 = a[9];
- var a22 = a[10];
- var a23 = a[11];
- var a30 = a[12];
- var a31 = a[13];
- var a32 = a[14];
- var a33 = a[15];
- var b00 = b[0];
- var b01 = b[1];
- var b02 = b[2];
- var b03 = b[3];
- var b10 = b[4];
- var b11 = b[5];
- var b12 = b[6];
- var b13 = b[7];
- var b20 = b[8];
- var b21 = b[9];
- var b22 = b[10];
- var b23 = b[11];
- var b30 = b[12];
- var b31 = b[13];
- var b32 = b[14];
- var b33 = b[15];
- return o3djs.flat_math.makeMatrix(
- a00 * b00 + a10 * b01 + a20 * b02 + a30 * b03,
- a01 * b00 + a11 * b01 + a21 * b02 + a31 * b03,
- a02 * b00 + a12 * b01 + a22 * b02 + a32 * b03,
- a03 * b00 + a13 * b01 + a23 * b02 + a33 * b03,
- a00 * b10 + a10 * b11 + a20 * b12 + a30 * b13,
- a01 * b10 + a11 * b11 + a21 * b12 + a31 * b13,
- a02 * b10 + a12 * b11 + a22 * b12 + a32 * b13,
- a03 * b10 + a13 * b11 + a23 * b12 + a33 * b13,
- a00 * b20 + a10 * b21 + a20 * b22 + a30 * b23,
- a01 * b20 + a11 * b21 + a21 * b22 + a31 * b23,
- a02 * b20 + a12 * b21 + a22 * b22 + a32 * b23,
- a03 * b20 + a13 * b21 + a23 * b22 + a33 * b23,
- a00 * b30 + a10 * b31 + a20 * b32 + a30 * b33,
- a01 * b30 + a11 * b31 + a21 * b32 + a31 * b33,
- a02 * b30 + a12 * b31 + a22 * b32 + a32 * b33,
- a03 * b30 + a13 * b31 + a23 * b32 + a33 * b33);
-};
-
-/**
- * Takes two 4-by-4 matrices, a and b, and modifies a to be the product in the
- * order that pre-composes b with a. The matrix a, upon modification will
- * transform by b first and then a. Note this is subtly different from just
- * multiplying the matrices together. For given a and b, a, upon modification,
- * will be the same object in both row-major and column-major mode.
- * @param {!o3djs.flat_math.Matrix4} a A 4-by-4 matrix.
- * @param {!o3djs.flat_math.Matrix4} b A 4-by-4 matrix.
- * @return {!o3djs.flat_math.Matrix4} a once modified.
- */
-o3djs.flat_math.matrix4.compose = function(a, b) {
- var a00 = a[0];
- var a01 = a[1];
- var a02 = a[2];
- var a03 = a[3];
- var a10 = a[4];
- var a11 = a[5];
- var a12 = a[6];
- var a13 = a[7];
- var a20 = a[8];
- var a21 = a[9];
- var a22 = a[10];
- var a23 = a[11];
- var a30 = a[12];
- var a31 = a[13];
- var a32 = a[14];
- var a33 = a[15];
- var b00 = b[0];
- var b01 = b[1];
- var b02 = b[2];
- var b03 = b[3];
- var b10 = b[4];
- var b11 = b[5];
- var b12 = b[6];
- var b13 = b[7];
- var b20 = b[8];
- var b21 = b[9];
- var b22 = b[10];
- var b23 = b[11];
- var b30 = b[12];
- var b31 = b[13];
- var b32 = b[14];
- var b33 = b[15];
- a[0] = a00 * b00 + a10 * b01 + a20 * b02 + a30 * b03;
- a[1] = a01 * b00 + a11 * b01 + a21 * b02 + a31 * b03;
- a[2] = a02 * b00 + a12 * b01 + a22 * b02 + a32 * b03;
- a[3] = a03 * b00 + a13 * b01 + a23 * b02 + a33 * b03;
- a[4] = a00 * b10 + a10 * b11 + a20 * b12 + a30 * b13;
- a[5] = a01 * b10 + a11 * b11 + a21 * b12 + a31 * b13;
- a[6] = a02 * b10 + a12 * b11 + a22 * b12 + a32 * b13;
- a[7] = a03 * b10 + a13 * b11 + a23 * b12 + a33 * b13;
- a[8] = a00 * b20 + a10 * b21 + a20 * b22 + a30 * b23;
- a[9] = a01 * b20 + a11 * b21 + a21 * b22 + a31 * b23;
- a[10] = a02 * b20 + a12 * b21 + a22 * b22 + a32 * b23;
- a[11] = a03 * b20 + a13 * b21 + a23 * b22 + a33 * b23;
- a[12] = a00 * b30 + a10 * b31 + a20 * b32 + a30 * b33;
- a[13] = a01 * b30 + a11 * b31 + a21 * b32 + a31 * b33;
- a[14] = a02 * b30 + a12 * b31 + a22 * b32 + a32 * b33;
- a[15] = a03 * b30 + a13 * b31 + a23 * b32 + a33 * b33;
- return a;
-};
-
-/**
- * Creates a 4-by-4 matrix which translates by the given vector v.
- * @param {(!o3djs.flat_math.Vector3|!o3djs.flat_math.Vector4)} v The vector by
- * which to translate.
- * @return {!o3djs.flat_math.Matrix4} The translation matrix.
- */
-o3djs.flat_math.matrix4.translation = function(v) {
- return o3djs.flat_math.makeMatrix4(
- 1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- v[0], v[1], v[2], 1);
-};
-
-/**
- * Modifies the given 4-by-4 matrix by translation by the given vector v.
- * @param {!o3djs.flat_math.Matrix4} m The matrix.
- * @param {(!o3djs.flat_math.Vector3|!o3djs.flat_math.Vector4)} v The vector by
- * which to translate.
- * @return {!o3djs.flat_math.Matrix4} m once modified.
- */
-o3djs.flat_math.matrix4.translate = function(m, v) {
- var m00 = m[0];
- var m01 = m[1];
- var m02 = m[2];
- var m03 = m[3];
- var m10 = m[4];
- var m11 = m[5];
- var m12 = m[6];
- var m13 = m[7];
- var m20 = m[8];
- var m21 = m[9];
- var m22 = m[10];
- var m23 = m[11];
- var m30 = m[12];
- var m31 = m[13];
- var m32 = m[14];
- var m33 = m[15];
-
- var v0 = v[0];
- var v1 = v[1];
- var v2 = v[2];
- var v3 = v[3];
-
- m[12] = m00 * v0 + m10 * v1 + m20 * v2 + m30;
- m[13] = m01 * v0 + m11 * v1 + m21 * v2 + m31;
- m[14] = m02 * v0 + m12 * v1 + m22 * v2 + m32;
- m[15] = m03 * v0 + m13 * v1 + m23 * v2 + m33;
-
- return m;
-};
-
-/**
- * Creates a 4-by-4 matrix which scales in each dimension by an amount given by
- * the corresponding entry in the given vector; assumes the vector has three
- * entries.
- * @param {!o3djs.flat_math.Vector3} v A vector of
- * three entries specifying the factor by which to scale in each dimension.
- * @return {!o3djs.flat_math.Matrix4} The scaling matrix.
- */
-o3djs.flat_math.matrix4.scaling = function(v) {
- return o3djs.flat_math.makeMatrix(
- v[0], 0, 0, 0,
- 0, v[1], 0, 0,
- 0, 0, v[2], 0,
- 0, 0, 0, 1
- );
-};
-
-/**
- * Modifies the given 4-by-4 matrix, scaling in each dimension by an amount
- * given by the corresponding entry in the given vector; assumes the vector has
- * three entries.
- * @param {!o3djs.flat_math.Matrix4} m The matrix to be modified.
- * @param {!o3djs.flat_math.Vector3} v A vector of three entries specifying the
- * factor by which to scale in each dimension.
- * @return {!o3djs.flat_math.Matrix4} m once modified.
- */
-o3djs.flat_math.matrix4.scale = function(m, v) {
- var v0 = v[0];
- var v1 = v[1];
- var v2 = v[2];
-
- for (var i = 0; i < 4; ++i) {
- m[i] *= v0;
- m[4 + i] *= v1;
- m[8 + i] *= v2;
- }
-
- return m;
-};
-
-/**
- * Creates a 4-by-4 matrix which rotates around the x-axis by the given angle.
- * @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.flat_math.Matrix4} The rotation matrix.
- */
-o3djs.flat_math.matrix4.rotationX = function(angle) {
- var c = Math.cos(angle);
- var s = Math.sin(angle);
-
- return o3djs.flat_math.makeMatrix(
- 1, 0, 0, 0,
- 0, c, s, 0,
- 0, -s, c, 0,
- 0, 0, 0, 1);
-};
-
-/**
- * Modifies the given 4-by-4 matrix by a rotation around the x-axis by the given
- * angle.
- * @param {!o3djs.flat_math.Matrix4} m The matrix.
- * @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.flat_math.Matrix4} m once modified.
- */
-o3djs.flat_math.matrix4.rotateX = function(m, angle) {
- var m10 = m[4];
- var m11 = m[5];
- var m12 = m[6];
- var m13 = m[7];
- var m20 = m[8];
- var m21 = m[9];
- var m22 = m[10];
- var m23 = m[11];
- var c = Math.cos(angle);
- var s = Math.sin(angle);
-
- m[4] = c * m10 + s * m20;
- m[5] = c * m11 + s * m21;
- m[6] = c * m12 + s * m22;
- m[7] = c * m13 + s * m23;
- m[8] = c * m20 - s * m10;
- m[9] = c * m21 - s * m11;
- m[10] = c * m22 - s * m12;
- m[11] = c * m23 - s * m13;
-
- return m;
-};
-
-/**
- * Creates a 4-by-4 matrix which rotates around the y-axis by the given angle.
- * @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.flat_math.Matrix4} The rotation matrix.
- */
-o3djs.flat_math.matrix4.rotationY = function(angle) {
- var c = Math.cos(angle);
- var s = Math.sin(angle);
-
- return o3djs.flat_math.makeMatrix(
- c, 0, -s, 0,
- 0, 1, 0, 0,
- s, 0, c, 0,
- 0, 0, 0, 1);
-};
-
-/**
- * Modifies the given 4-by-4 matrix by a rotation around the y-axis by the given
- * angle.
- * @param {!o3djs.flat_math.Matrix4} m The matrix.
- * @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.flat_math.Matrix4} m once modified.
- */
-o3djs.flat_math.matrix4.rotateY = function(m, angle) {
- var m00 = m[0];
- var m01 = m[1];
- var m02 = m[2];
- var m03 = m[3];
- var m20 = m[8];
- var m21 = m[9];
- var m22 = m[10];
- var m23 = m[11];
- var c = Math.cos(angle);
- var s = Math.sin(angle);
-
- m[0] = c * m00 - s * m20;
- m[1] = c * m01 - s * m21;
- m[2] = c * m02 - s * m22;
- m[3] = c * m03 - s * m23;
- m[8] = c * m20 + s * m00;
- m[9] = c * m21 + s * m01;
- m[10] = c * m22 + s * m02;
- m[11] = c * m23 + s * m03;
-
- return m;
-};
-
-/**
- * Creates a 4-by-4 matrix which rotates around the z-axis by the given angle.
- * @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.flat_math.Matrix4} The rotation matrix.
- */
-o3djs.flat_math.matrix4.rotationZ = function(angle) {
- var c = Math.cos(angle);
- var s = Math.sin(angle);
-
- return o3djs.flat_math.makeMatrix(
- c, s, 0, 0,
- -s, c, 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1);
-};
-
-/**
- * Modifies the given 4-by-4 matrix by a rotation around the z-axis by the given
- * angle.
- * @param {!o3djs.flat_math.Matrix4} m The matrix.
- * @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.flat_math.Matrix4} m once modified.
- */
-o3djs.flat_math.matrix4.rotateZ = function(m, angle) {
- var m00 = m[0];
- var m01 = m[1];
- var m02 = m[2];
- var m03 = m[3];
- var m10 = m[4];
- var m11 = m[5];
- var m12 = m[6];
- var m13 = m[7];
- var c = Math.cos(angle);
- var s = Math.sin(angle);
-
- m[0] = c * m00 + s * m10;
- m[1] = c * m01 + s * m11;
- m[2] = c * m02 + s * m12;
- m[3] = c * m03 + s * m13;
- m[4] = c * m10 - s * m00;
- m[5] = c * m11 - s * m01;
- m[6] = c * m12 - s * m02;
- m[7] = c * m13 - s * m03;
-
- return m;
-};
-
-/**
- * Creates a 4-by-4 rotation matrix. Interprets the entries of the given
- * vector as angles by which to rotate around the x, y and z axes, returns a
- * a matrix which rotates around the x-axis first, then the y-axis, then the
- * z-axis.
- * @param {!o3djs.flat_math.Vector3} v A vector of angles (in radians).
- * @return {!o3djs.flat_math.Matrix4} The rotation matrix.
- */
-o3djs.flat_math.matrix4.rotationZYX = function(v) {
- var sinx = Math.sin(v[0]);
- var cosx = Math.cos(v[0]);
- var siny = Math.sin(v[1]);
- var cosy = Math.cos(v[1]);
- var sinz = Math.sin(v[2]);
- var cosz = Math.cos(v[2]);
-
- var coszsiny = cosz * siny;
- var sinzsiny = sinz * siny;
-
- return o3djs.flat_math.makeMatrix(
- cosz * cosy, sinz * cosy, -siny, 0, coszsiny * sinx - sinz * cosx,
- sinzsiny * sinx + cosz * cosx, cosy * sinx, 0,
- coszsiny * cosx + sinz * sinx, sinzsiny * cosx - cosz * sinx, cosy * cosx,
- 0, 0, 0, 0, 1);
-};
-
-/**
- * Modifies a 4-by-4 matrix by a rotation. Interprets the coordinates of the
- * given vector as angles by which to rotate around the x, y and z axes, rotates
- * around the x-axis first, then the y-axis, then the z-axis.
- * @param {!o3djs.flat_math.Matrix4} m The matrix.
- * @param {!o3djs.flat_math.Vector3} v A vector of angles (in radians).
- * @return {!o3djs.flat_math.Matrix4} m once modified.
- */
-o3djs.flat_math.matrix4.rotateZYX = function(m, v) {
- var sinX = Math.sin(v[0]);
- var cosX = Math.cos(v[0]);
- var sinY = Math.sin(v[1]);
- var cosY = Math.cos(v[1]);
- var sinZ = Math.sin(v[2]);
- var cosZ = Math.cos(v[2]);
-
- var cosZSinY = cosZ * sinY;
- var sinZSinY = sinZ * sinY;
-
- var r00 = cosZ * cosY;
- var r01 = sinZ * cosY;
- var r02 = -sinY;
- var r10 = cosZSinY * sinX - sinZ * cosX;
- var r11 = sinZSinY * sinX + cosZ * cosX;
- var r12 = cosY * sinX;
- var r20 = cosZSinY * cosX + sinZ * sinX;
- var r21 = sinZSinY * cosX - cosZ * sinX;
- var r22 = cosY * cosX;
-
- var m00 = m[0];
- var m01 = m[1];
- var m02 = m[2];
- var m03 = m[3];
- var m10 = m[4];
- var m11 = m[5];
- var m12 = m[6];
- var m13 = m[7];
- var m20 = m[8];
- var m21 = m[9];
- var m22 = m[10];
- var m23 = m[11];
- var m30 = m[12];
- var m31 = m[13];
- var m32 = m[14];
- var m33 = m[15];
-
- m[0] = r00 * m00 + r01 * m10 + r02 * m20;
- m[1] = r00 * m01 + r01 * m11 + r02 * m21;
- m[2] = r00 * m02 + r01 * m12 + r02 * m22;
- m[3] = r00 * m03 + r01 * m13 + r02 * m23;
-
- m[4] = r10 * m00 + r11 * m10 + r12 * m20;
- m[5] = r10 * m01 + r11 * m11 + r12 * m21;
- m[6] = r10 * m02 + r11 * m12 + r12 * m22;
- m[7] = r10 * m03 + r11 * m13 + r12 * m23;
-
- m[8] = r20 * m00 + r21 * m10 + r22 * m20;
- m[9] = r20 * m01 + r21 * m11 + r22 * m21;
- m[10] = r20 * m02 + r21 * m12 + r22 * m22;
- m[11] = r20 * m03 + r21 * m13 + r22 * m23;
-
- return m;
-};
-
-/**
- * Creates a 4-by-4 matrix which rotates around the given axis by the given
- * angle.
- * @param {(!o3djs.flat_math.Vector3|!o3djs.flat_math.Vector4)} axis The axis
- * about which to rotate.
- * @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.flat_math.Matrix4} A matrix which rotates angle radians
- * around the axis.
- */
-o3djs.flat_math.matrix4.axisRotation = function(axis, angle) {
- var x = axis[0];
- var y = axis[1];
- var z = axis[2];
- var n = Math.sqrt(x * x + y * y + z * z);
- x /= n;
- y /= n;
- z /= n;
- var xx = x * x;
- var yy = y * y;
- var zz = z * z;
- var c = Math.cos(angle);
- var s = Math.sin(angle);
- var oneMinusCosine = 1 - c;
-
- return o3djs.flat_math.makeMatrix(
- xx + (1 - xx) * c,
- x * y * oneMinusCosine + z * s,
- x * z * oneMinusCosine - y * s,
- 0,
- x * y * oneMinusCosine - z * s,
- yy + (1 - yy) * c,
- y * z * oneMinusCosine + x * s,
- 0,
- x * z * oneMinusCosine + y * s,
- y * z * oneMinusCosine - x * s,
- zz + (1 - zz) * c,
- 0,
- 0, 0, 0, 1
- );
-};
-
-/**
- * Modifies the given 4-by-4 matrix by rotation around the given axis by the
- * given angle.
- * @param {!o3djs.flat_math.Matrix4} m The matrix.
- * @param {(!o3djs.flat_math.Vector3|!o3djs.flat_math.Vector4)} axis The axis
- * about which to rotate.
- * @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.flat_math.Matrix4} m once modified.
- */
-o3djs.flat_math.matrix4.axisRotate = function(m, axis, angle) {
- var x = axis[0];
- var y = axis[1];
- var z = axis[2];
- var n = Math.sqrt(x * x + y * y + z * z);
- x /= n;
- y /= n;
- z /= n;
- var xx = x * x;
- var yy = y * y;
- var zz = z * z;
- var c = Math.cos(angle);
- var s = Math.sin(angle);
- var oneMinusCosine = 1 - c;
-
- var r00 = xx + (1 - xx) * c;
- var r01 = x * y * oneMinusCosine + z * s;
- var r02 = x * z * oneMinusCosine - y * s;
- var r10 = x * y * oneMinusCosine - z * s;
- var r11 = yy + (1 - yy) * c;
- var r12 = y * z * oneMinusCosine + x * s;
- var r20 = x * z * oneMinusCosine + y * s;
- var r21 = y * z * oneMinusCosine - x * s;
- var r22 = zz + (1 - zz) * c;
-
- var m00 = m[0];
- var m01 = m[1];
- var m02 = m[2];
- var m03 = m[3];
- var m10 = m[4];
- var m11 = m[5];
- var m12 = m[6];
- var m13 = m[7];
- var m20 = m[8];
- var m21 = m[9];
- var m22 = m[10];
- var m23 = m[11];
- var m30 = m[12];
- var m31 = m[13];
- var m32 = m[14];
- var m33 = m[15];
-
- m[0] = r00 * m00 + r01 * m10 + r02 * m20;
- m[1] = r00 * m01 + r01 * m11 + r02 * m21;
- m[2] = r00 * m02 + r01 * m12 + r02 * m22;
- m[3] = r00 * m03 + r01 * m13 + r02 * m23;
-
- m[4] = r10 * m00 + r11 * m10 + r12 * m20;
- m[5] = r10 * m01 + r11 * m11 + r12 * m21;
- m[6] = r10 * m02 + r11 * m12 + r12 * m22;
- m[7] = r10 * m03 + r11 * m13 + r12 * m23;
-
- m[8] = r20 * m00 + r21 * m10 + r22 * m20;
- m[9] = r20 * m01 + r21 * m11 + r22 * m21;
- m[10] = r20 * m02 + r21 * m12 + r22 * m22;
- m[11] = r20 * m03 + r21 * m13 + r22 * m23;
-
- return m;
-};
-
-/**
- * Sets each function in the namespace o3djs.flat_math to the row major
- * version in o3djs.flat_math.rowMajor (provided such a function exists in
- * o3djs.flat_math.rowMajor). Call this function to establish the row major
- * convention.
- */
-o3djs.flat_math.installRowMajorFunctions = function() {
- for (var f in o3djs.flat_math.rowMajor) {
- o3djs.flat_math[f] = o3djs.flat_math.rowMajor[f];
- }
-};
-
-/**
- * Sets each function in the namespace o3djs.flat_math to the column major
- * version in o3djs.flat_math.columnMajor (provided such a function exists in
- * o3djs.flat_math.columnMajor). Call this function to establish the column
- * major convention.
- */
-o3djs.flat_math.installColumnMajorFunctions = function() {
- for (var f in o3djs.flat_math.columnMajor) {
- o3djs.flat_math[f] = o3djs.flat_math.columnMajor[f];
- }
-};
-
-/**
- * Sets each function in the namespace o3djs.flat_math to the error checking
- * version in o3djs.flat_math.errorCheck (provided such a function exists in
- * o3djs.flat_math.errorCheck).
- */
-o3djs.flat_math.installErrorCheckFunctions = function() {
- for (var f in o3djs.flat_math.errorCheck) {
- o3djs.flat_math[f] = o3djs.flat_math.errorCheck[f];
- }
-};
-
-/**
- * Sets each function in the namespace o3djs.flat_math to the error checking free
- * version in o3djs.flat_math.errorCheckFree (provided such a function exists in
- * o3djs.flat_math.errorCheckFree).
- */
-o3djs.flat_math.installErrorCheckFreeFunctions = function() {
- for (var f in o3djs.flat_math.errorCheckFree) {
- o3djs.flat_math[f] = o3djs.flat_math.errorCheckFree[f];
- }
-};
-
-// By default, install the row-major functions.
-o3djs.flat_math.installRowMajorFunctions();
-
-// By default, install prechecking.
-o3djs.flat_math.installErrorCheckFunctions();
-
-if (!use_plugin_math) {
- for (var f in o3djs.flat_math) {
- o3djs.math[f] = o3djs.flat_math[f];
- }
-
- /**
- * True if we are using the plugin math library in which matrices are
- * represented by 2-dimensional arrays.
- * @type {boolean}
- * @private
- */
- o3djs.math.usePluginMath_ = false;
-}
-
-
diff --git a/o3d/samples/o3djs/pack.js b/o3d/samples/o3djs/pack.js
deleted file mode 100644
index 183b315..0000000
--- a/o3d/samples/o3djs/pack.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains various functions for helping setup
- * packs for o3d. It puts them in the "pack" module on the o3djs
- * object.
- *
- * Note: This library is only a sample. It is not meant to be some official
- * library. It is provided only as example code.
- *
- */
-
-o3djs.provide('o3djs.pack');
-
-o3djs.require('o3djs.material');
-o3djs.require('o3djs.shape');
-
-/**
- * A Module with utilities for dealing with packs..
- * @namespace
- */
-o3djs.pack = o3djs.pack || {};
-
-/**
- * Prepares a pack for rendering.
- *
- * @param {!o3d.Pack} pack Pack to prepare.
- * @param {!o3djs.rendergraph.ViewInfo} viewInfo as returned from
- * o3djs.rendergraph.createView.
- * @param {!o3d.Pack} opt_effectPack Pack to create effects in. If this is
- * not specifed the pack to prepare above will be used.
- * @param {Object} opt_options Extra options for effect.getStandardShader
- *
- * @see o3djs.material.prepareMaterials
- * @see o3djs.shape.prepareShapes
- */
-o3djs.pack.preparePack = function(pack, viewInfo, opt_effectPack, opt_options) {
- o3djs.material.prepareMaterials(pack, viewInfo, opt_effectPack, opt_options);
- o3djs.shape.prepareShapes(pack);
-};
-
diff --git a/o3d/samples/o3djs/particles.js b/o3d/samples/o3djs/particles.js
deleted file mode 100644
index 3874e30..0000000
--- a/o3d/samples/o3djs/particles.js
+++ /dev/null
@@ -1,1510 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains various functions and classes for rendering
- * gpu based particles.
- *
- * TODO: Add 3d oriented particles.
- */
-
-o3djs.provide('o3djs.particles');
-
-o3djs.require('o3djs.effect');
-o3djs.require('o3djs.math');
-
-/**
- * A Module with various GPU particle functions and classes.
- * Note: GPU particles have the issue that they are not sorted per particle
- * but rather per emitter.
- * @namespace
- */
-o3djs.particles = o3djs.particles || {};
-
-/**
- * Enum for pre-made particle states.
- * @enum
- */
-o3djs.particles.ParticleStateIds = {
- BLEND: 0,
- ADD: 1,
- BLEND_PREMULTIPLY: 2,
- BLEND_NO_ALPHA: 3,
- SUBTRACT: 4,
- INVERSE: 5};
-
-/**
- * Particle Effect strings
- * @type {!Array.<{name: string, fxString: string}>}
- */
-o3djs.particles.FX_STRINGS_CG = [
- { name: 'particle3d', fxString: '' +
- 'float4x4 worldViewProjection : WORLDVIEWPROJECTION;\n' +
- 'float4x4 world : WORLD;\n' +
- 'float3 worldVelocity;\n' +
- 'float3 worldAcceleration;\n' +
- 'float timeRange;\n' +
- 'float time;\n' +
- 'float timeOffset;\n' +
- 'float frameDuration;\n' +
- 'float numFrames;\n' +
- '\n' +
- '// We need to implement 1D!\n' +
- 'sampler rampSampler;\n' +
- 'sampler colorSampler;\n' +
- '\n' +
- 'struct VertexShaderInput {\n' +
- ' float4 uvLifeTimeFrameStart : POSITION; // uv, lifeTime, frameStart\n' +
- ' float4 positionStartTime : TEXCOORD0; // position.xyz, startTime\n' +
- ' float4 velocityStartSize : TEXCOORD1; // velocity.xyz, startSize\n' +
- ' float4 accelerationEndSize : TEXCOORD2; // acceleration.xyz, endSize\n' +
- ' float4 spinStartSpinSpeed : TEXCOORD3; // spinStart.x, spinSpeed.y\n' +
- ' float4 orientation : TEXCOORD4; // orientation\n' +
- ' float4 colorMult : COLOR; //\n' +
- '};\n' +
- '\n' +
- 'struct PixelShaderInput {\n' +
- ' float4 position : POSITION;\n' +
- ' float2 texcoord : TEXCOORD0;\n' +
- ' float1 percentLife : TEXCOORD1;\n' +
- ' float4 colorMult: TEXCOORD2;\n' +
- '};\n' +
- '\n' +
- 'PixelShaderInput vertexShaderFunction(VertexShaderInput input) {\n' +
- ' PixelShaderInput output;\n' +
- '\n' +
- ' float2 uv = input.uvLifeTimeFrameStart.xy;\n' +
- ' float lifeTime = input.uvLifeTimeFrameStart.z;\n' +
- ' float frameStart = input.uvLifeTimeFrameStart.w;\n' +
- ' float3 position = input.positionStartTime.xyz;\n' +
- ' float startTime = input.positionStartTime.w;\n' +
- ' float3 velocity = mul(float4(input.velocityStartSize.xyz, 0),\n' +
- ' world).xyz + worldVelocity;\n' +
- ' float startSize = input.velocityStartSize.w;\n' +
- ' float3 acceleration = mul(float4(input.accelerationEndSize.xyz, 0),\n' +
- ' world).xyz + worldAcceleration;\n' +
- ' float endSize = input.accelerationEndSize.w;\n' +
- ' float spinStart = input.spinStartSpinSpeed.x;\n' +
- ' float spinSpeed = input.spinStartSpinSpeed.y;\n' +
- '\n' +
- ' float localTime = fmod((time - timeOffset - startTime), timeRange);\n' +
- ' float percentLife = localTime / lifeTime;\n' +
- '\n' +
- ' float frame = fmod(floor(localTime / frameDuration + frameStart),\n' +
- ' numFrames);\n' +
- ' float uOffset = frame / numFrames;\n' +
- ' float u = uOffset + (uv.x + 0.5) * (1 / numFrames);\n' +
- '\n' +
- ' output.texcoord = float2(u, uv.y + 0.5);\n' +
- ' 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' +
- ' float4 rotatedPoint = float4((uv.x * c + uv.y * s) * size, 0,\n' +
- ' (uv.x * s - uv.y * c) * size, 1);\n' +
- ' float3 center = velocity * localTime +\n' +
- ' acceleration * localTime * localTime + \n' +
- ' position;\n' +
- ' \n' +
- ' float4 q2 = input.orientation + input.orientation;\n' +
- ' float4 qx = input.orientation.xxxw * q2.xyzx;\n' +
- ' float4 qy = input.orientation.xyyw * q2.xyzy;\n' +
- ' float4 qz = input.orientation.xxzw * q2.xxzz;\n' +
- ' \n' +
- ' float4x4 localMatrix = float4x4(\n' +
- ' (1.0f - qy.y) - qz.z, \n' +
- ' qx.y + qz.w, \n' +
- ' qx.z - qy.w,\n' +
- ' 0,\n' +
- ' \n' +
- ' qx.y - qz.w, \n' +
- ' (1.0f - qx.x) - qz.z, \n' +
- ' qy.z + qx.w,\n' +
- ' 0,\n' +
- ' \n' +
- ' qx.z + qy.w, \n' +
- ' qy.z - qx.w, \n' +
- ' (1.0f - qx.x) - qy.y,\n' +
- ' 0,\n' +
- ' \n' +
- ' center.x, center.y, center.z, 1);\n' +
- ' rotatedPoint = mul(rotatedPoint, localMatrix);\n' +
- ' output.position = mul(rotatedPoint, worldViewProjection);\n' +
- ' output.percentLife = percentLife;\n' +
- ' return output;\n' +
- '}\n' +
- '\n' +
- 'float4 pixelShaderFunction(PixelShaderInput input): COLOR {\n' +
- ' float4 colorMult = tex2D(rampSampler, \n' +
- ' float2(input.percentLife, 0.5)) *\n' +
- ' input.colorMult;\n' +
- ' float4 color = tex2D(colorSampler, input.texcoord) * colorMult;\n' +
- ' return color;\n' +
- '}\n' +
- '\n' +
- '// #o3d VertexShaderEntryPoint vertexShaderFunction\n' +
- '// #o3d PixelShaderEntryPoint pixelShaderFunction\n' +
- '// #o3d MatrixLoadOrder RowMajor\n'},
- { name: 'particle2d', fxString: '' +
- 'float4x4 viewProjection : VIEWPROJECTION;\n' +
- 'float4x4 world : WORLD;\n' +
- 'float4x4 viewInverse : VIEWINVERSE;\n' +
- 'float3 worldVelocity;\n' +
- 'float3 worldAcceleration;\n' +
- 'float timeRange;\n' +
- 'float time;\n' +
- 'float timeOffset;\n' +
- 'float frameDuration;\n' +
- 'float numFrames;\n' +
- '\n' +
- '// We need to implement 1D!\n' +
- 'sampler rampSampler;\n' +
- 'sampler colorSampler;\n' +
- '\n' +
- 'struct VertexShaderInput {\n' +
- ' float4 uvLifeTimeFrameStart : POSITION; // uv, lifeTime, frameStart\n' +
- ' float4 positionStartTime : TEXCOORD0; // position.xyz, startTime\n' +
- ' float4 velocityStartSize : TEXCOORD1; // velocity.xyz, startSize\n' +
- ' float4 accelerationEndSize : TEXCOORD2; // acceleration.xyz, endSize\n' +
- ' float4 spinStartSpinSpeed : TEXCOORD3; // spinStart.x, spinSpeed.y\n' +
- ' float4 colorMult : COLOR; //\n' +
- '};\n' +
- '\n' +
- 'struct PixelShaderInput {\n' +
- ' float4 position : POSITION;\n' +
- ' float2 texcoord : TEXCOORD0;\n' +
- ' float1 percentLife : TEXCOORD1;\n' +
- ' float4 colorMult: TEXCOORD2;\n' +
- '};\n' +
- '\n' +
- 'PixelShaderInput vertexShaderFunction(VertexShaderInput input) {\n' +
- ' PixelShaderInput output;\n' +
- '\n' +
- ' float2 uv = input.uvLifeTimeFrameStart.xy;\n' +
- ' float lifeTime = input.uvLifeTimeFrameStart.z;\n' +
- ' float frameStart = input.uvLifeTimeFrameStart.w;\n' +
- ' float3 position = mul(float4(input.positionStartTime.xyz, 1),\n' +
- ' world).xyz;\n' +
- ' float startTime = input.positionStartTime.w;\n' +
- ' float3 velocity = mul(float4(input.velocityStartSize.xyz, 0),\n' +
- ' world).xyz + worldVelocity;\n' +
- ' float startSize = input.velocityStartSize.w;\n' +
- ' float3 acceleration = mul(float4(input.accelerationEndSize.xyz, 0),\n' +
- ' world).xyz + worldAcceleration;\n' +
- ' float endSize = input.accelerationEndSize.w;\n' +
- ' float spinStart = input.spinStartSpinSpeed.x;\n' +
- ' float spinSpeed = input.spinStartSpinSpeed.y;\n' +
- '\n' +
- ' float localTime = fmod((time - timeOffset - startTime), timeRange);\n' +
- ' float percentLife = localTime / lifeTime;\n' +
- '\n' +
- ' float frame = fmod(floor(localTime / frameDuration + frameStart),\n' +
- ' numFrames);\n' +
- ' float uOffset = frame / numFrames;\n' +
- ' float u = uOffset + (uv.x + 0.5) * (1 / numFrames);\n' +
- '\n' +
- ' output.texcoord = float2(u, uv.y + 0.5);\n' +
- ' output.colorMult = input.colorMult;\n' +
- '\n' +
- ' float3 basisX = viewInverse[0].xyz;\n' +
- ' 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' +
- ' float2 rotatedPoint = float2(uv.x * c + uv.y * s, \n' +
- ' -uv.x * s + uv.y * c);\n' +
- ' float3 localPosition = float3(basisX * rotatedPoint.x +\n' +
- ' basisZ * rotatedPoint.y) * size +\n' +
- ' velocity * localTime +\n' +
- ' acceleration * localTime * localTime + \n' +
- ' position;\n' +
- '\n' +
- ' output.position = mul(float4(localPosition, 1), \n' +
- ' viewProjection);\n' +
- ' output.percentLife = percentLife;\n' +
- ' return output;\n' +
- '}\n' +
- '\n' +
- 'float4 pixelShaderFunction(PixelShaderInput input): COLOR {\n' +
- ' float4 colorMult = tex2D(rampSampler, \n' +
- ' float2(input.percentLife, 0.5)) *\n' +
- ' input.colorMult;\n' +
- ' float4 color = tex2D(colorSampler, input.texcoord) * colorMult;\n' +
- ' return color;\n' +
- '}\n' +
- '\n' +
- '// #o3d VertexShaderEntryPoint vertexShaderFunction\n' +
- '// #o3d PixelShaderEntryPoint pixelShaderFunction\n' +
- '// #o3d MatrixLoadOrder RowMajor\n'}];
-
-o3djs.particles.FX_STRINGS_GLSL = [
- { name: 'particle3d', fxString: '' +
- 'uniform mat4 world;\n' +
- 'uniform mat4 worldViewProjection;\n' +
- 'uniform vec3 worldVelocity;\n' +
- 'uniform vec3 worldAcceleration;\n' +
- 'uniform float timeRange;\n' +
- 'uniform float time;\n' +
- 'uniform float timeOffset;\n' +
- 'uniform float frameDuration;\n' +
- 'uniform float numFrames;\n' +
- '\n' +
- 'attribute vec4 position; // uv, lifeTime, frameStart\n' +
- 'attribute vec4 texCoord0; // position.xyz, startTime\n' +
- 'attribute vec4 texCoord1; // velocity.xyz, startSize\n' +
- 'attribute vec4 texCoord2; // acceleration.xyz, endSize\n' +
- 'attribute vec4 texCoord3; // spinStart.x, spinSpeed.y\n' +
- 'attribute vec4 texCoord4; // orientation\n' +
- 'attribute vec4 color; //\n' +
- '\n' +
- 'varying vec4 v_position;\n' +
- 'varying vec2 v_texcoord;\n' +
- 'varying float v_percentLife;\n' +
- 'varying vec4 v_colorMult;\n' +
- '\n' +
- 'void main() {\n' +
- ' vec4 uvLifeTimeFrameStart = position;\n' +
- ' vec4 positionStartTime = texCoord0;\n' +
- ' vec4 velocityStartSize = texCoord1;\n' +
- ' vec4 accelerationEndSize = texCoord2;\n' +
- ' vec4 spinStartSpinSpeed = texCoord3;\n' +
- ' vec4 orientation = texCoord4;\n' +
- ' vec4 colorMult = color;\n' +
- ' vec2 uv = uvLifeTimeFrameStart.xy;\n' +
- ' float lifeTime = uvLifeTimeFrameStart.z;\n' +
- ' float frameStart = uvLifeTimeFrameStart.w;\n' +
- ' vec3 position = positionStartTime.xyz;\n' +
- ' float startTime = positionStartTime.w;\n' +
- ' vec3 velocity = (world * vec4(velocityStartSize.xyz, 0)).xyz\n' +
- ' + worldVelocity;\n' +
- ' float startSize = velocityStartSize.w;\n' +
- ' vec3 acceleration = (world *\n' +
- ' vec4(accelerationEndSize.xyz, 0)).xyz + worldAcceleration;\n' +
- ' float endSize = accelerationEndSize.w;\n' +
- ' float spinStart = spinStartSpinSpeed.x;\n' +
- ' float spinSpeed = spinStartSpinSpeed.y;\n' +
- '\n' +
- ' float localTime = mod((time - timeOffset - startTime),\n' +
- ' timeRange);\n' +
- ' float percentLife = localTime / lifeTime;\n' +
- '\n' +
- ' float frame = mod(floor(localTime / frameDuration + frameStart),\n' +
- ' numFrames);\n' +
- ' float uOffset = frame / numFrames;\n' +
- ' float u = uOffset + (uv.x + 0.5) * (1.0 / numFrames);\n' +
- '\n' +
- ' v_texcoord = vec2(u, uv.y + 0.5);\n' +
- ' v_colorMult = colorMult;\n' +
- '\n' +
- ' float size = mix(startSize, endSize, percentLife);\n' +
- ' size = (percentLife < 0.0 || percentLife > 1.0) ? 0.0 : size;\n' +
- ' float s = sin(spinStart + spinSpeed * localTime);\n' +
- ' float c = cos(spinStart + spinSpeed * localTime);\n' +
- '\n' +
- ' vec4 rotatedPoint = vec4((uv.x * c + uv.y * s) * size, 0.0,\n' +
- ' (uv.x * s - uv.y * c) * size, 1.0);\n' +
- ' vec3 center = velocity * localTime +\n' +
- ' acceleration * localTime * localTime + \n' +
- ' position;\n' +
- ' \n' +
- ' vec4 q2 = orientation + orientation;\n' +
- ' vec4 qx = orientation.xxxw * q2.xyzx;\n' +
- ' vec4 qy = orientation.xyyw * q2.xyzy;\n' +
- ' vec4 qz = orientation.xxzw * q2.xxzz;\n' +
- ' \n' +
- ' mat4 localMatrix = mat4(\n' +
- ' (1.0 - qy.y) - qz.z, \n' +
- ' qx.y + qz.w, \n' +
- ' qx.z - qy.w,\n' +
- ' 0,\n' +
- ' \n' +
- ' qx.y - qz.w, \n' +
- ' (1.0 - qx.x) - qz.z, \n' +
- ' qy.z + qx.w,\n' +
- ' 0,\n' +
- ' \n' +
- ' qx.z + qy.w, \n' +
- ' qy.z - qx.w, \n' +
- ' (1.0 - qx.x) - qy.y,\n' +
- ' 0,\n' +
- ' \n' +
- ' center.x, center.y, center.z, 1.0);\n' +
- ' rotatedPoint = localMatrix * rotatedPoint;\n' +
- ' gl_Position = worldViewProjection * rotatedPoint;\n' +
- ' v_percentLife = percentLife;\n' +
- '}\n' +
- '\n' +
- '// #o3d SplitMarker\n' +
- '\n' +
- 'varying vec4 v_position;\n' +
- 'varying vec2 v_texcoord;\n' +
- 'varying float v_percentLife;\n' +
- 'varying vec4 v_colorMult;\n' +
- '\n' +
- '// We need to implement 1D!\n' +
- 'uniform sampler2D rampSampler;\n' +
- 'uniform sampler2D colorSampler;\n' +
- '\n' +
- 'void main() {\n' +
- ' vec4 colorMult = texture2D(rampSampler, \n' +
- ' vec2(v_percentLife, 0.5)) * v_colorMult;\n' +
- ' vec4 color = texture2D(colorSampler, v_texcoord) * colorMult;\n' +
- ' gl_FragColor = color;\n' +
- '}\n' +
- '\n' +
- '// #o3d MatrixLoadOrder RowMajor\n'},
- { name: 'particle2d', fxString: '' +
- 'uniform mat4 viewProjection;\n' +
- 'uniform mat4 world;\n' +
- 'uniform mat4 viewInverse;\n' +
- 'uniform vec3 worldVelocity;\n' +
- 'uniform vec3 worldAcceleration;\n' +
- 'uniform float timeRange;\n' +
- 'uniform float time;\n' +
- 'uniform float timeOffset;\n' +
- 'uniform float frameDuration;\n' +
- 'uniform float numFrames;\n' +
- '\n' +
- 'attribute vec4 position; // uv, lifeTime, frameStart\n' +
- 'attribute vec4 texCoord0; // position.xyz, startTime\n' +
- 'attribute vec4 texCoord1; // velocity.xyz, startSize\n' +
- 'attribute vec4 texCoord2; // acceleration.xyz, endSize\n' +
- 'attribute vec4 texCoord3; // spinStart.x, spinSpeed.y\n' +
- 'attribute vec4 color; //\n' +
- '\n' +
- 'varying vec4 v_position;\n' +
- 'varying vec2 v_texcoord;\n' +
- 'varying float v_percentLife;\n' +
- 'varying vec4 v_colorMult;\n' +
- '\n' +
- 'void main() {\n' +
- ' vec4 uvLifeTimeFrameStart = position;\n' +
- ' vec4 positionStartTime = texCoord0;\n' +
- ' vec4 velocityStartSize = texCoord1;\n' +
- ' vec4 accelerationEndSize = texCoord2;\n' +
- ' vec4 spinStartSpinSpeed = texCoord3;\n' +
- ' vec4 colorMult = color;\n' +
- ' vec2 uv = uvLifeTimeFrameStart.xy;\n' +
- ' float lifeTime = uvLifeTimeFrameStart.z;\n' +
- ' float frameStart = uvLifeTimeFrameStart.w;\n' +
- ' vec3 position = (world * vec4(positionStartTime.xyz, 1.0)).xyz;\n' +
- ' float startTime = positionStartTime.w;\n' +
- ' vec3 velocity = (world * vec4(velocityStartSize.xyz, 0)).xyz \n' +
- ' + worldVelocity;\n' +
- ' float startSize = velocityStartSize.w;\n' +
- ' vec3 acceleration = (world *\n' +
- ' vec4(accelerationEndSize.xyz, 0)).xyz + worldAcceleration;\n' +
- ' float endSize = accelerationEndSize.w;\n' +
- ' float spinStart = spinStartSpinSpeed.x;\n' +
- ' float spinSpeed = spinStartSpinSpeed.y;\n' +
- '\n' +
- ' float localTime = mod((time - timeOffset - startTime),\n' +
- ' timeRange);\n' +
- ' float percentLife = localTime / lifeTime;\n' +
- '\n' +
- ' float frame = mod(floor(localTime / frameDuration + frameStart),\n' +
- ' numFrames);\n' +
- ' float uOffset = frame / numFrames;\n' +
- ' float u = uOffset + (uv.x + 0.5) * (1.0 / numFrames);\n' +
- '\n' +
- ' v_texcoord = vec2(u, uv.y + 0.5);\n' +
- ' v_colorMult = colorMult;\n' +
- '\n' +
- ' vec3 basisX = viewInverse[0].xyz;\n' +
- ' vec3 basisZ = viewInverse[1].xyz;\n' +
- '\n' +
- ' float size = mix(startSize, endSize, percentLife);\n' +
- ' size = (percentLife < 0.0 || percentLife > 1.0) ? 0.0 : size;\n' +
- ' float s = sin(spinStart + spinSpeed * localTime);\n' +
- ' float c = cos(spinStart + spinSpeed * localTime);\n' +
- '\n' +
- ' vec2 rotatedPoint = vec2(uv.x * c + uv.y * s, \n' +
- ' -uv.x * s + uv.y * c);\n' +
- ' vec3 localPosition = vec3(basisX * rotatedPoint.x +\n' +
- ' basisZ * rotatedPoint.y) * size +\n' +
- ' velocity * localTime +\n' +
- ' acceleration * localTime * localTime + \n' +
- ' position;\n' +
- '\n' +
- ' gl_Position = (viewProjection * vec4(localPosition, 1.0));\n' +
- ' v_percentLife = percentLife;\n' +
- '}\n' +
- '\n' +
- '// #o3d SplitMarker\n' +
- '\n' +
- 'varying vec4 v_position;\n' +
- 'varying vec2 v_texcoord;\n' +
- 'varying float v_percentLife;\n' +
- 'varying vec4 v_colorMult;\n' +
- '\n' +
- '// We need to implement 1D!\n' +
- 'uniform sampler2D rampSampler;\n' +
- 'uniform sampler2D colorSampler;\n' +
- '\n' +
- 'void main() {\n' +
- ' vec4 colorMult = texture2D(rampSampler, \n' +
- ' vec2(v_percentLife, 0.5)) * v_colorMult;\n' +
- ' vec4 color = texture2D(colorSampler, v_texcoord) * colorMult;\n' +
- ' gl_FragColor = color;\n' +
- '}\n' +
- '\n' +
- '// #o3d MatrixLoadOrder RowMajor\n'}];
-
-
-/**
- * Sets the current shaders language to be in accordance with effect.js.
- */
-o3djs.particles.useCorrectShaders_ = function() {
- o3djs.particles.FX_STRINGS = o3djs.particles.FX_STRINGS_CG;
- if (o3djs.effect.LANGUAGE == 'glsl') {
- o3djs.particles.FX_STRINGS = o3djs.particles.FX_STRINGS_GLSL;
- }
-};
-
-
-/**
- * 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.
- * @param {!o3d.Pack} pack The pack for the particle system to manage resources.
- * @param {!o3djs.rendergraph.ViewInfo} viewInfo A viewInfo so the particle
- * system can do the default setup. The only thing used from viewInfo
- * is the zOrderedDrawList. If that is not where you want your particles,
- * after you create the particleEmitter use
- * particleEmitter.material.drawList = myDrawList to set it to something
- * else.
- * @param {!o3d.ParamFloat} opt_clockParam A ParamFloat to be the default
- * clock for emitters of this particle system.
- * @param {!function(): number} opt_randomFunction A function that returns
- * a random number between 0.0 and 1.0. This allows you to pass in a
- * pseudo random function if you need particles that are reproducable.
- * @return {!o3djs.particles.ParticleSystem} The created particle system.
- */
-o3djs.particles.createParticleSystem = function(pack,
- viewInfo,
- opt_clockParam,
- opt_randomFunction) {
- return new o3djs.particles.ParticleSystem(pack,
- viewInfo,
- opt_clockParam,
- opt_randomFunction);
-};
-
-/**
- * An Object to manage Particles.
- * @constructor
- * @param {!o3d.Pack} pack The pack for the particle system to manage resources.
- * @param {!o3djs.rendergraph.ViewInfo} viewInfo A viewInfo so the particle
- * system can do the default setup. The only thing used from viewInfo
- * is the zOrderedDrawList. If that is not where you want your particles,
- * after you create the particleEmitter use
- * particleEmitter.material.drawList = myDrawList to set it to something
- * else.
- * @param {!o3d.ParamFloat} opt_clockParam A ParamFloat to be the default
- * clock for emitters of this particle system.
- * @param {!function(): number} opt_randomFunction A function that returns
- * a random number between 0.0 and 1.0. This allows you to pass in a
- * pseudo random function if you need particles that are reproducable.
- */
-o3djs.particles.ParticleSystem = function(pack,
- viewInfo,
- opt_clockParam,
- opt_randomFunction) {
- var o3d = o3djs.base.o3d;
- var particleStates = [];
- var effects = [];
- o3djs.particles.useCorrectShaders_();
- for (var ee = 0; ee < o3djs.particles.FX_STRINGS.length; ++ee) {
- var info = o3djs.particles.FX_STRINGS[ee];
- var effect = pack.createObject('Effect');
- effect.name = info.name;
- effect.loadFromFXString(info.fxString);
- effects.push(effect);
- }
-
- var stateInfos = {};
- stateInfos[o3djs.particles.ParticleStateIds.BLEND] = {
- 'SourceBlendFunction':
- o3djs.base.o3d.State.BLENDFUNC_SOURCE_ALPHA,
- 'DestinationBlendFunction':
- o3djs.base.o3d.State.BLENDFUNC_INVERSE_SOURCE_ALPHA};
-
- stateInfos[o3djs.particles.ParticleStateIds.ADD] = {
- 'SourceBlendFunction':
- o3djs.base.o3d.State.BLENDFUNC_SOURCE_ALPHA,
- 'DestinationBlendFunction':
- o3djs.base.o3d.State.BLENDFUNC_ONE};
-
- stateInfos[o3djs.particles.ParticleStateIds.BLEND_PREMULTIPLY] = {
- 'SourceBlendFunction':
- o3djs.base.o3d.State.BLENDFUNC_ONE,
- 'DestinationBlendFunction':
- o3djs.base.o3d.State.BLENDFUNC_INVERSE_SOURCE_ALPHA};
-
- stateInfos[o3djs.particles.ParticleStateIds.BLEND_NO_ALPHA] = {
- 'SourceBlendFunction':
- o3djs.base.o3d.State.BLENDFUNC_SOURCE_COLOR,
- 'DestinationBlendFunction':
- o3djs.base.o3d.State.BLENDFUNC_INVERSE_SOURCE_COLOR};
-
- stateInfos[o3djs.particles.ParticleStateIds.SUBTRACT] = {
- 'SourceBlendFunction':
- o3djs.base.o3d.State.BLENDFUNC_SOURCE_ALPHA,
- 'DestinationBlendFunction':
- o3djs.base.o3d.State.BLENDFUNC_INVERSE_SOURCE_ALPHA,
- 'BlendEquation':
- o3djs.base.o3d.State.BLEND_REVERSE_SUBTRACT};
-
- stateInfos[o3djs.particles.ParticleStateIds.INVERSE] = {
- 'SourceBlendFunction':
- o3djs.base.o3d.State.BLENDFUNC_INVERSE_DESTINATION_COLOR,
- 'DestinationBlendFunction':
- o3djs.base.o3d.State.BLENDFUNC_INVERSE_SOURCE_COLOR};
-
- for (var key in o3djs.particles.ParticleStateIds) {
- var state = pack.createObject('State');
- var id = o3djs.particles.ParticleStateIds[key];
- particleStates[id] = state;
- state.getStateParam('ZWriteEnable').value = false;
- state.getStateParam('CullMode').value = o3d.State.CULL_NONE;
-
- var info = stateInfos[id];
- for (var stateName in info) {
- state.getStateParam(stateName).value = info[stateName];
- }
- }
-
- var colorTexture = pack.createTexture2D(8, 8, o3d.Texture.ARGB8, 1, false);
- var pixelBase = [0, 0.20, 0.70, 1, 0.70, 0.20, 0, 0];
- var pixels = [];
- for (var yy = 0; yy < 8; ++yy) {
- for (var xx = 0; xx < 8; ++xx) {
- var pixel = pixelBase[xx] * pixelBase[yy];
- pixels.push(pixel, pixel, pixel, pixel);
- }
- }
- colorTexture.set(0, pixels);
- var rampTexture = pack.createTexture2D(3, 1, o3d.Texture.ARGB8, 1, false);
- rampTexture.set(0, [1, 1, 1, 1,
- 1, 1, 1, 0.5,
- 1, 1, 1, 0]);
-
- if (!opt_clockParam) {
- this.counter_ = pack.createObject('SecondCounter');
- opt_clockParam = this.counter_.getParam('count');
- }
-
- this.randomFunction_ = opt_randomFunction || function() {
- return Math.random();
- };
-
- /**
- * The states for the various blend modes.
- * @type {!Array.<!o3d.State>}
- */
- this.particleStates = particleStates;
-
- /**
- * The default ParamFloat to use as the clock for emitters created by
- * this system.
- * @type {!o3d.ParamFloat}
- */
- this.clockParam = opt_clockParam;
-
- /**
- * The pack used to manage particle system resources.
- * @type {!o3d.Pack}
- */
- this.pack = pack;
-
- /**
- * The viewInfo that is used to get drawLists.
- * @type {!o3djs.rendergraph.ViewInfo}
- */
- this.viewInfo = viewInfo;
-
- /**
- * The effects for particles.
- * @type {!Array.<!o3d.Effect>}
- */
- this.effects = effects;
-
-
- /**
- * The default color texture for particles.
- * @type {!o3d.Texture2D}
- */
- this.defaultColorTexture = colorTexture;
-
-
- /**
- * The default ramp texture for particles.
- * @type {!o3d.Texture2D}
- */
- this.defaultRampTexture = rampTexture;
-};
-
-/**
- * A ParticleSpec specifies how to emit particles.
- *
- * NOTE: For all particle functions you can specific a ParticleSpec as a
- * Javascript object, only specifying the fields that you care about.
- *
- * <pre>
- * emitter.setParameters({
- * numParticles: 40,
- * lifeTime: 2,
- * timeRange: 2,
- * startSize: 50,
- * endSize: 90,
- * positionRange: [10, 10, 10],
- * velocity:[0, 0, 60], velocityRange: [15, 15, 15],
- * acceleration: [0, 0, -20],
- * spinSpeedRange: 4}
- * );
- * </pre>
- *
- * Many of these parameters are in pairs. For paired paramters each particle
- * 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)
- *
- * @constructor
- */
-o3djs.particles.ParticleSpec = function() {
- /**
- * The number of particles to emit.
- * @type {number}
- */
- this.numParticles = 1;
-
- /**
- * The number of frames in the particle texture.
- * @type {number}
- */
- this.numFrames = 1;
-
- /**
- * The frame duration at which to animate the particle texture in seconds per
- * frame.
- * @type {number}
- */
- this.frameDuration = 1;
-
- /**
- * The initial frame to display for a particular particle.
- * @type {number}
- */
- this.frameStart = 0;
-
- /**
- * The frame start range.
- * @type {number}
- */
- this.frameStartRange = 0;
-
- /**
- * The life time of the entire particle system.
- * To make a particle system be continuous set this to match the lifeTime.
- * @type {number}
- */
- this.timeRange = 99999999;
-
- /**
- * The startTime of a particle.
- * @type {?number}
- */
- this.startTime = null;
- // TODO: Describe what happens if this is not set. I still have some
- // work to do there.
-
- /**
- * The lifeTime of a particle.
- * @type {number}
- */
- this.lifeTime = 1;
-
- /**
- * The lifeTime range.
- * @type {number}
- */
- this.lifeTimeRange = 0;
-
- /**
- * The starting size of a particle.
- * @type {number}
- */
- this.startSize = 1;
-
- /**
- * The starting size range.
- * @type {number}
- */
- this.startSizeRange = 0;
-
- /**
- * The ending size of a particle.
- * @type {number}
- */
- this.endSize = 1;
-
- /**
- * The ending size range.
- * @type {number}
- */
- this.endSizeRange = 0;
-
- /**
- * The starting position of a particle in local space.
- * @type {!o3djs.math.Vector3}
- */
- this.position = [0, 0, 0];
-
- /**
- * The starting position range.
- * @type {!o3djs.math.Vector3}
- */
- this.positionRange = [0, 0, 0];
-
- /**
- * The velocity of a paritcle in local space.
- * @type {!o3djs.math.Vector3}
- */
- this.velocity = [0, 0, 0];
-
- /**
- * The velocity range.
- * @type {!o3djs.math.Vector3}
- */
- this.velocityRange = [0, 0, 0];
-
- /**
- * The acceleration of a particle in local space.
- * @type {!o3djs.math.Vector3}
- */
- this.acceleration = [0, 0, 0];
-
- /**
- * The accleration range.
- * @type {!o3djs.math.Vector3}
- */
- this.accelerationRange = [0, 0, 0];
-
- /**
- * The starting spin value for a particle in radians.
- * @type {number}
- */
- this.spinStart = 0;
-
- /**
- * The spin start range.
- * @type {number}
- */
- this.spinStartRange = 0;
-
- /**
- * The spin speed of a particle in radians.
- * @type {number}
- */
- this.spinSpeed = 0;
-
- /**
- * The spin speed range.
- * @type {number}
- */
- this.spinSpeedRange = 0;
-
- /**
- * The color multiplier of a particle.
- * @type {!o3djs.math.Vector4}
- */
- this.colorMult = [1, 1, 1, 1];
-
- /**
- * The color multiplier range.
- * @type {!o3djs.math.Vector4}
- */
- this.colorMultRange = [0, 0, 0, 0];
-
- /**
- * The velocity of all paritcles in world space.
- * @type {!o3djs.math.Vector3}
- */
- this.worldVelocity = [0, 0, 0];
-
- /**
- * The acceleration of all paritcles in world space.
- * @type {!o3djs.math.Vector3}
- */
- this.worldAcceleration = [0, 0, 0];
-
- /**
- * Whether these particles are oriented in 2d or 3d. true = 2d, false = 3d.
- * @type {boolean}
- */
- this.billboard = true;
-
- /**
- * The orientation of a particle. This is only used if billboard is false.
- * @type {!o3djs.quaternions.Quaternion}
- */
- this.orientation = [0, 0, 0, 1];
-};
-
-/**
- * Creates a particle emitter.
- * @param {!o3d.Texture} opt_texture The texture to use for the particles.
- * If you don't supply a texture a default is provided.
- * @param {!o3d.ParamFloat} opt_clockParam A ParamFloat to be the clock for
- * the emitter.
- * @return {!o3djs.particles.ParticleEmitter} The new emitter.
- */
-o3djs.particles.ParticleSystem.prototype.createParticleEmitter =
- function(opt_texture, opt_clockParam) {
- return new o3djs.particles.ParticleEmitter(this, opt_texture, opt_clockParam);
-};
-
-/**
- * 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
- * to manage this emitter.
- * @param {!o3d.Texture} opt_texture The texture to use for the particles.
- * If you don't supply a texture a default is provided.
- * @param {!o3d.ParamFloat} opt_clockParam A ParamFloat to be the clock for
- * the emitter.
- */
-o3djs.particles.ParticleEmitter = function(particleSystem,
- opt_texture,
- opt_clockParam) {
- opt_clockParam = opt_clockParam || particleSystem.clockParam;
-
- var o3d = o3djs.base.o3d;
- var pack = particleSystem.pack;
- var viewInfo = particleSystem.viewInfo;
- var material = pack.createObject('Material');
- material.name = 'particles';
- material.drawList = viewInfo.zOrderedDrawList;
- material.effect = particleSystem.effects[1];
- particleSystem.effects[1].createUniformParameters(material);
- material.getParam('time').bind(opt_clockParam);
-
- var rampSampler = pack.createObject('Sampler');
- rampSampler.texture = particleSystem.defaultRampTexture;
- rampSampler.addressModeU = o3d.Sampler.CLAMP;
-
- var colorSampler = pack.createObject('Sampler');
- colorSampler.texture = opt_texture || particleSystem.defaultColorTexture;
- colorSampler.addressModeU = o3d.Sampler.CLAMP;
- colorSampler.addressModeV = o3d.Sampler.CLAMP;
-
- material.getParam('rampSampler').value = rampSampler;
- material.getParam('colorSampler').value = colorSampler;
-
- var vertexBuffer = pack.createObject('VertexBuffer');
- var uvLifeTimeFrameStartField = vertexBuffer.createField('FloatField', 4);
- var positionStartTimeField = vertexBuffer.createField('FloatField', 4);
- var velocityStartSizeField = vertexBuffer.createField('FloatField', 4);
- var accelerationEndSizeField = vertexBuffer.createField('FloatField', 4);
- var spinStartSpinSpeedField = vertexBuffer.createField('FloatField', 4);
- var orientationField = vertexBuffer.createField('FloatField', 4);
- var colorMultField = vertexBuffer.createField('FloatField', 4);
-
- var indexBuffer = pack.createObject('IndexBuffer');
-
- var streamBank = pack.createObject('StreamBank');
- streamBank.setVertexStream(o3d.Stream.POSITION, 0,
- uvLifeTimeFrameStartField, 0);
- streamBank.setVertexStream(o3d.Stream.TEXCOORD, 0,
- positionStartTimeField, 0);
- streamBank.setVertexStream(o3d.Stream.TEXCOORD, 1,
- velocityStartSizeField, 0);
- streamBank.setVertexStream(o3d.Stream.TEXCOORD, 2,
- accelerationEndSizeField, 0);
- streamBank.setVertexStream(o3d.Stream.TEXCOORD, 3,
- spinStartSpinSpeedField, 0);
- streamBank.setVertexStream(o3d.Stream.TEXCOORD, 4,
- orientationField, 0);
- streamBank.setVertexStream(o3d.Stream.COLOR, 0,
- colorMultField, 0);
-
- var shape = pack.createObject('Shape');
- var primitive = pack.createObject('Primitive');
- primitive.material = material;
- primitive.owner = shape;
- primitive.streamBank = streamBank;
- primitive.indexBuffer = indexBuffer;
- primitive.primitiveType = o3d.Primitive.TRIANGLELIST;
- primitive.createDrawElement(pack, null);
-
- this.vertexBuffer_ = vertexBuffer;
- this.uvLifeTimeFrameStartField_ = uvLifeTimeFrameStartField;
- this.positionStartTimeField_ = positionStartTimeField;
- this.velocityStartSizeField_ = velocityStartSizeField;
- this.accelerationEndSizeField_ = accelerationEndSizeField;
- this.spinStartSpinSpeedField_ = spinStartSpinSpeedField;
- this.orientationField_ = orientationField;
- this.colorMultField_ = colorMultField;
- this.indexBuffer_ = indexBuffer;
- this.streamBank_ = streamBank;
- this.primitive_ = primitive;
- this.rampSampler_ = rampSampler;
- this.rampTexture_ = particleSystem.defaultRampTexture;
- this.colorSampler_ = colorSampler;
-
- /**
- * The particle system managing this emitter.
- * @type {!o3djs.particles.ParticleSystem}
- */
- this.particleSystem = particleSystem;
-
- /**
- * The Shape used to render these particles.
- * @type {!o3d.Shape}
- */
- this.shape = shape;
-
- /**
- * The material used by this emitter.
- * @type {!o3d.Material}
- */
- this.material = material;
-
- /**
- * The param that is the source for the time for this emitter.
- * @type {!o3d.ParamFloat}
- */
- this.clockParam = opt_clockParam;
-};
-
-/**
- * Sets the blend state for the particles.
- * You can use this to set the emitter to draw with BLEND, ADD, SUBTRACT, etc.
- * @param {o3djs.particles.ParticleStateIds} stateId The state you want.
- */
-o3djs.particles.ParticleEmitter.prototype.setState = function(stateId) {
- this.material.state = this.particleSystem.particleStates[stateId];
-};
-
-/**
- * Sets the colorRamp for the particles.
- * The colorRamp is used as a multiplier for the texture. When a particle
- * starts it is multiplied by the first color, as it ages to progressed
- * through the colors in the ramp.
- *
- * <pre>
- * particleEmitter.setColorRamp([
- * 1, 0, 0, 1, // red
- * 0, 1, 0, 1, // green
- * 1, 0, 1, 0]); // purple but with zero alpha
- * </pre>
- *
- * The code above sets the particle to start red, change to green then
- * fade out while changing to purple.
- *
- * @param {!Array.<number>} colorRamp An array of color values in
- * the form RGBA.
- */
-o3djs.particles.ParticleEmitter.prototype.setColorRamp = function(colorRamp) {
- var width = colorRamp.length / 4;
- if (width % 1 != 0) {
- throw 'colorRamp must have multiple of 4 entries';
- }
-
- if (this.rampTexture_ == this.particleSystem.defaultRampTexture) {
- this.rampTexture_ = null;
- }
-
- if (this.rampTexture_ && this.rampTexture_.width != width) {
- this.particleSystem.pack.removeObject(this.rampTexture_);
- this.rampTexture_ = null;
- }
-
- if (!this.rampTexture_) {
- this.rampTexture_ = this.particleSystem.pack.createTexture2D(
- width, 1, o3djs.base.o3d.Texture.ARGB8, 1, false);
- }
-
- this.rampTexture_.set(0, colorRamp);
- this.rampSampler_.texture = this.rampTexture_;
-};
-
-/**
- * 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}
- * 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.createParticles_ = function(
- firstParticleIndex,
- numParticles,
- parameters,
- opt_perParticleParamSetter) {
- 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[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 =
- parameters.worldAcceleration;
-
- var random = this.particleSystem.randomFunction_;
-
- var plusMinus = function(range) {
- 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) {
- v.push(plusMinus(range[ii]));
- }
- return v;
- };
-
- for (var ii = 0; ii < numParticles; ++ii) {
- if (opt_perParticleParamSetter) {
- opt_perParticleParamSetter(ii, parameters);
- }
- 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(
- parameters.position, plusMinusVector(parameters.positionRange));
- var pVelocity = o3djs.math.addVector(
- parameters.velocity, plusMinusVector(parameters.velocityRange));
- var pAcceleration = o3djs.math.addVector(
- parameters.acceleration,
- plusMinusVector(parameters.accelerationRange));
- var pColorMult = o3djs.math.addVector(
- 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) {
- 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);
-
- var indices = [];
- for (var ii = 0; ii < numParticles; ++ii) {
- // Make 2 triangles for the quad.
- var startIndex = ii * 4
- indices.push(startIndex + 0, startIndex + 1, startIndex + 2);
- indices.push(startIndex + 0, startIndex + 2, startIndex + 3);
- }
- this.indexBuffer_.set(indices);
-
- // 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.
- * @return {!o3djs.particles.OneShot} A OneShot object.
- */
-o3djs.particles.ParticleEmitter.prototype.createOneShot = function(opt_parent) {
- return new o3djs.particles.OneShot(this, opt_parent);
-};
-
-/**
- * An object to manage a particle emitter instance as a one shot. Examples of
- * one shot effects are things like an explosion, some fireworks.
- * @constructor
- * @param {!o3djs.particles.ParticleEmitter} emitter The emitter to use for the
- * one shot.
- * @param {!o3d.Transform} opt_parent The parent for this one shot.
- */
-o3djs.particles.OneShot = function(emitter, opt_parent) {
- var pack = emitter.particleSystem.pack;
- this.emitter_ = emitter;
-
- /**
- * Transform for OneShot.
- * @type {!o3d.Transform}
- */
- this.transform = pack.createObject('Transform');
- this.transform.visible = false;
- this.transform.addShape(emitter.shape);
- this.timeOffsetParam_ =
- this.transform.createParam('timeOffset', 'ParamFloat');
- if (opt_parent) {
- this.setParent(opt_parent);
- }
-};
-
-/**
- * Sets the parent transform for this OneShot.
- * @param {!o3d.Transform} parent The parent for this one shot.
- */
-o3djs.particles.OneShot.prototype.setParent = function(parent) {
- this.transform.parent = parent;
-};
-
-/**
- * Triggers the oneshot.
- *
- * Note: You must have set the parent either at creation, with setParent, or by
- * passing in a parent here.
- *
- * @param {!o3djs.math.Vector3} opt_position The position of the one shot
- * relative to its parent.
- * @param {!o3d.Transform} opt_parent The parent for this one shot.
- */
-o3djs.particles.OneShot.prototype.trigger = function(opt_position, opt_parent) {
- if (opt_parent) {
- this.setParent(opt_parent);
- }
- if (opt_position) {
- this.transform.identity();
- this.transform.translate(opt_position);
- }
- this.transform.visible = true;
- this.timeOffsetParam_.value = this.emitter_.clockParam.value;
-};
-
-/**
- * A type of emitter to use for particle effects that leave trails like exhaust.
- * @constructor
- * @extends {o3djs.particles.ParticleEmitter}
- * @param {!o3djs.particles.ParticleSystem} particleSystem The particle system
- * to manage this emitter.
- * @param {!o3d.Transform} parent Transform to put emitter on.
- * @param {number} maxParticles Maximum number of particles to appear at once.
- * @param {!o3djs.particles.ParticleSpec} parameters The parameters used to
- * generate particles.
- * @param {!o3d.Texture} opt_texture The texture to use for the particles.
- * If you don't supply a texture a default is provided.
- * @param {!function(number, !o3djs.particles.ParticleSpec): void}
- * opt_perParticleParamSetter A function that is called for each particle to
- * allow it's parameters to be adjusted per particle. The number is the
- * index of the particle being created, in other words, if numParticles is
- * 20 this value will be 0 to 19. The ParticleSpec is a spec for this
- * particular particle. You can set any per particle value before returning.
- * @param {!o3d.ParamFloat} opt_clockParam A ParamFloat to be the clock for
- * the emitter.
- */
-o3djs.particles.Trail = function(
- particleSystem,
- parent,
- maxParticles,
- parameters,
- opt_texture,
- opt_perParticleParamSetter,
- opt_clockParam) {
- o3djs.particles.ParticleEmitter.call(
- this, particleSystem, opt_texture, opt_clockParam);
-
- var pack = particleSystem.pack;
-
- this.allocateParticles_(maxParticles);
- this.validateParameters(parameters);
-
- this.parameters = parameters;
- this.perParticleParamSetter = opt_perParticleParamSetter;
- this.birthIndex_ = 0;
- this.maxParticles_ = maxParticles;
-
- /**
- * Transform for OneShot.
- * @type {!o3d.Transform}
- */
- this.transform = pack.createObject('Transform');
- this.transform.addShape(this.shape);
-
- this.transform.parent = parent;
-};
-
-o3djs.base.inherit(o3djs.particles.Trail, o3djs.particles.ParticleEmitter);
-
-/**
- * Births particles from this Trail.
- * @param {!o3djs.math.Vector3} position Position to birth particles at.
- */
-o3djs.particles.Trail.prototype.birthParticles = function(position) {
- var numParticles = this.parameters.numParticles;
- this.parameters.startTime = this.clockParam.value;
- this.parameters.position = position;
- while (this.birthIndex_ + numParticles >= this.maxParticles_) {
- var numParticlesToEnd = this.maxParticles_ - this.birthIndex_;
- this.createParticles_(this.birthIndex_,
- numParticlesToEnd,
- this.parameters,
- this.perParticleParamSetter);
- numParticles -= numParticlesToEnd;
- this.birthIndex_ = 0;
- }
- this.createParticles_(this.birthIndex_,
- numParticles,
- this.parameters,
- this.perParticleParamSetter);
- this.birthIndex_ += numParticles;
-};
-
-
diff --git a/o3d/samples/o3djs/performance.js b/o3d/samples/o3djs/performance.js
deleted file mode 100644
index c5faeaa..0000000
--- a/o3d/samples/o3djs/performance.js
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains a utility that helps adjust rendering
- * quality [or any other setting, really] based on rendering performance.
- *
- */
-
-o3djs.provide('o3djs.performance');
-
-/**
- * A Module to help with adjusting performance.
- * @namespace
- */
-o3djs.performance = o3djs.performance || {};
-
-/**
- * Creates a utility that monitors performance [in terms of FPS] and helps to
- * adjust the rendered scene accordingly.
- * @param {number} targetFPSMin the minimum acceptable frame rate; if we're
- * under this, try to decrease quality to improve performance.
- * @param {number} targetFPSMax if we're over this, try to increase quality.
- * @param {!function(): void} increaseQuality a function to increase
- * quality because we're rendering at high-enough FPS to afford it.
- * @param {!function(): void} decreaseQuality a function to decrease
- * quality to try to raise our rendering speed.
- * @param {!o3djs.performance.PerformanceMonitor.Options} opt_options Options.
- * @return {!o3djs.performance.PerformanceMonitor} The created
- * PerformanceMonitor.
- */
-o3djs.performance.createPerformanceMonitor = function(
- targetFPSMin, targetFPSMax, increaseQuality, decreaseQuality, opt_options) {
- return new o3djs.performance.PerformanceMonitor(targetFPSMin, targetFPSMax,
- increaseQuality, decreaseQuality, opt_options);
-};
-
-/**
- * A class that monitors performance [in terms of FPS] and helps to adjust the
- * rendered scene accordingly.
- * @constructor
- * @param {number} targetFPSMin the minimum acceptable frame rate; if we're
- * under this, try to decrease quality to improve performance.
- * @param {number} targetFPSMax if we're over this, try to increase quality.
- * @param {function(): void} increaseQuality a function to increase
- * quality/lower FPS.
- * @param {function(): void} decreaseQuality a function to decrease
- * quality/raise FPS.
- * @param {!o3djs.performance.PerformanceMonitor.Options} opt_options Options.
- */
-o3djs.performance.PerformanceMonitor = function(
- targetFPSMin, targetFPSMax, increaseQuality, decreaseQuality, opt_options) {
- opt_options = opt_options || {};
-
- /**
- * A function to increase quality/lower FPS.
- * @type {function(): void}
- */
- this.increaseQuality = increaseQuality;
-
- /**
- * A function to decrease quality/raise FPS.
- * @type {function(): void}
- */
- this.decreaseQuality = decreaseQuality;
-
- /**
- * The mean time taken per frame so far, in seconds. This is only valid once
- * we've collected at least minSamples samples.
- * @type {number}
- */
- this.meanFrameTime = 0;
-
- /**
- * The number of samples we've collected so far, when that number is less than
- * or equal to this.damping. After that point, we no longer update
- * this.sampleCount, so it will clip at this.damping.
- *
- * @type {number}
- */
- this.sampleCount = 0;
-
- /**
- * The minimum number of samples to collect before trying to adjust quality.
- *
- * @type {number}
- */
- this.minSamples = opt_options.opt_minSamples || 60;
-
- /**
- * A number that controls the rate at which the effects of any given sample
- * fade away. Higher is slower, but also means that each individual sample
- * counts for less at its most-influential. Damping defaults to 120; anywhere
- * between 60 and 600 are probably reasonable values, depending on your needs,
- * but the number must be no less than minSamples.
- *
- * @type {number}
- */
- this.damping = opt_options.opt_damping || 120;
-
- /**
- * The minimum number of samples to take in between adjustments, to cut down
- * on overshoot. It defaults to 2 * minSamples.
- *
- * @type {number}
- */
- this.delayCycles = opt_options.opt_delayCycles || 2 * this.minSamples;
-
- this.targetFrameTimeMax_ = 1 / targetFPSMin;
- this.targetFrameTimeMin_ = 1 / targetFPSMax;
- this.scaleInput_ = 1 / this.minSamples;
- this.scaleMean_ = 1;
- this.delayCyclesLeft_ = 0;
- if (this.damping < this.minSamples) {
- throw Error('Damping must be at least minSamples.');
- }
-};
-
-/**
- * Options for the PerformanceMonitor.
- *
- * opt_minSamples is the minimum number of samples to take before making any
- * performance adjustments.
- * opt_damping is a number that controls the rate at which the effects of any
- * given sample fade away. Higher is slower, but also means that each
- * individual sample counts for less at its most-influential. Damping
- * defaults to 120; anywhere between 60 and 600 are probably reasonable values,
- * depending on your needs, but the number must be no less than minSamples.
- * opt_delayCycles is the minimum number of samples to take in between
- * adjustments, to cut down on overshoot. It defaults to 2 * opt_minSamples.
- *
- * @type {{
- * opt_minSamples: number,
- * opt_damping: number,
- * opt_delayCycles: number
- * }}
- */
-o3djs.performance.PerformanceMonitor.Options = goog.typedef;
-
-/**
- * Call this once per frame with the elapsed time since the last call, and it
- * will attempt to adjust your rendering quality as needed.
- *
- * @param {number} seconds the elapsed time since the last frame was rendered,
- * in seconds.
- */
-o3djs.performance.PerformanceMonitor.prototype.onRender = function(seconds) {
- var test = true;
- if (this.sampleCount < this.damping) {
- if (this.sampleCount >= this.minSamples) {
- this.scaleInput_ = 1 / (this.sampleCount + 1);
- this.scaleMean_ = this.sampleCount * this.scaleInput_;
- } else {
- test = false;
- }
- this.sampleCount += 1;
- }
- this.meanFrameTime = this.meanFrameTime * this.scaleMean_ +
- seconds * this.scaleInput_;
- if (this.delayCyclesLeft_ > 0) {
- this.delayCyclesLeft_ -= 1;
- } else if (test) {
- if (this.meanFrameTime < this.targetFrameTimeMin_) {
- this.increaseQuality();
- this.delayCyclesLeft_ = this.delayCycles;
- } else if (this.meanFrameTime > this.targetFrameTimeMax_) {
- this.decreaseQuality();
- this.delayCyclesLeft_ = this.delayCycles;
- }
- }
-};
-
-
diff --git a/o3d/samples/o3djs/picking.js b/o3d/samples/o3djs/picking.js
deleted file mode 100644
index a67de17..0000000
--- a/o3d/samples/o3djs/picking.js
+++ /dev/null
@@ -1,742 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains functions for implementing picking.
- * It puts them in the "picking" module on the o3djs object.
- *
- *
- * This example shows one way to implement picking. Because O3D is shader
- * agnostic we can't handle picking automatically since we have no way of
- * knowing what the developer is going to do with their shaders. On the other
- * hand, we can provide various functions that make it possible to do your own
- * picking. Only you know which objects are pickable and which are not. For
- * example if you are making an RTS game, only you would know that units are
- * pickable but ground and explosions are not and that neither is your HUD.
- * Similarly, only you would know how your shaders manipulate the vertices
- * passed to them.
- *
- * It's possible that someone, maybe us, will create an engine to use o3d
- * that given a bunch of restrictions and flags on the data it accepts can
- * do picking in a more automatic way but that is not the goal of the o3d
- * api. Its goal is to provide a LOW-LEVEL shader agnostic API.
- */
-
-o3djs.provide('o3djs.picking');
-
-o3djs.require('o3djs.math');
-o3djs.require('o3djs.dump');
-
-/**
- * A Module for picking.
- * @namespace
- */
-o3djs.picking = o3djs.picking || {};
-
-/**
- * A ray.
- * @type {{near: !o3djs.math.Vector3, far: !o3djs.math.Vector3}}
- */
-o3djs.picking.Ray = goog.typedef;
-
-/**
- * Creates a new PickInfo.
- * @param {!o3d.Element} element The Element that was picked.
- * @param {!o3djs.picking.ShapeInfo} shapeInfo The ShapeInfo that was picked.
- * @param {!o3d.RayIntersectionInfo} rayIntersectionInfo Information about the
- * pick.
- * @param {!o3djs.math.Vector3} worldIntersectionPosition world position of
- * intersection.
- * @return {!o3djs.picking.PickInfo} The new PickInfo.
- */
-o3djs.picking.createPickInfo = function(element,
- shapeInfo,
- rayIntersectionInfo,
- worldIntersectionPosition) {
- return new o3djs.picking.PickInfo(element,
- shapeInfo,
- rayIntersectionInfo,
- worldIntersectionPosition);
-};
-
-/**
- * Convert a pixel position relative to the top left corner of the client area
- * into the corresponding ray through the frustum in world space.
- * @param {number} clientXPosition x position relative to client area.
- * @param {number} clientYPosition y position relative to client area.
- * @param {!o3djs.math.Matrix4} view View matrix to transform with.
- * @param {!o3djs.math.Matrix4} projection Projection matrix to transform
- * with.
- * @param {number} clientWidth width of client area.
- * @param {number} clientHeight height of client area.
- * @return {!o3djs.picking.Ray} ray in world space.
- */
-o3djs.picking.clientPositionToWorldRayEx = function(clientXPosition,
- clientYPosition,
- view,
- projection,
- clientWidth,
- clientHeight) {
- // compute the world position of a ray going through the view frustum
- var inverseViewProjectionMatrix = o3djs.math.inverse(
- o3djs.math.matrix4.composition(projection, view));
- // normScreenX, normScreenY are in frustum coordinates.
- var normScreenX = clientXPosition / (clientWidth * 0.5) - 1;
- var normScreenY = -(clientYPosition / (clientHeight * 0.5) - 1);
-
- // Apply inverse view-projection matrix to get the ray in world coordinates.
- return {
- near: o3djs.math.matrix4.transformPoint(
- inverseViewProjectionMatrix, [normScreenX, normScreenY, 0]),
- far: o3djs.math.matrix4.transformPoint(
- inverseViewProjectionMatrix, [normScreenX, normScreenY, 1])
- };
-};
-
-/**
- * Convert a pixel position relative to the top left corner of the client area
- * into the corresponding ray through the frustum in world space.
- * @param {number} clientXPosition x position relative to client area.
- * @param {number} clientYPosition y position relative to client area.
- * @param {!o3d.DrawContext} drawContext DrawContext to get view and
- * projection matrices from.
- * @param {number} clientWidth width of client area.
- * @param {number} clientHeight height of client area.
- * @return {!o3djs.picking.Ray} ray in world space.
- */
-o3djs.picking.clientPositionToWorldRay = function(clientXPosition,
- clientYPosition,
- drawContext,
- clientWidth,
- clientHeight) {
- return o3djs.picking.clientPositionToWorldRayEx(
- clientXPosition,
- clientYPosition,
- drawContext.view,
- drawContext.projection,
- clientWidth,
- clientHeight);
-};
-
-/**
- * A local dump function so we can easily comment it out.
- * @param {string} msg Message to dump.
- */
-o3djs.picking.dprint = function(msg) {
- //o3djs.dump.dump(msg);
-};
-
-/**
- * A local dump function so we can easily comment it out.
- * @param {string} label Label to print before value.
- * @param {!o3djs.math.Vector3} float3 Value to print.
- * @param {string} prefix optional prefix for indenting.
- */
-o3djs.picking.dprintPoint3 = function(label, float3, prefix) {
- //o3djs.dump.dumpPoint3(label, float3, prefix);
-};
-
-/**
- * A local dump function so we can easily comment it out.
- * @param {string} label Label to put in front of dump.
- * @param {!o3d.BoundingBox} boundingBox BoundingBox to dump.
- * @param {string} opt_prefix optional prefix for indenting.
- */
-o3djs.picking.dprintBoundingBox = function(label,
- boundingBox,
- opt_prefix) {
- //o3djs.dump.dumpBoundingBox(label, boundingBox, opt_prefix);
-};
-
-/**
- * A local dump function so we can easily comment it out.
- * @param {string} label Label to print before value.
- * @param {!o3d.RayIntersectionInfo} rayIntersectionInfo Value to print.
- */
-o3djs.picking.dumpRayIntersectionInfo = function(label,
- rayIntersectionInfo) {
- o3djs.picking.dprint(
- label + ' : valid = ' +
- rayIntersectionInfo.valid + ' : intersected = ' +
- rayIntersectionInfo.intersected);
- if (rayIntersectionInfo.intersected) {
- o3djs.picking.dprint(
- ' : pos: ' +
- rayIntersectionInfo.position[0] + ', ' +
- rayIntersectionInfo.position[1] + ', ' +
- rayIntersectionInfo.position[2] + ', ');
- }
- o3djs.picking.dprint('\n');
-};
-
-/**
- * Creates a new PickInfo. Used to return picking information.
- * @constructor
- * @param {!o3d.Element} element The Element that was picked.
- * @param {!o3djs.picking.ShapeInfo} shapeInfo The ShapeInfo that was picked.
- * @param {!o3d.RayIntersectionInfo} rayIntersectionInfo Information about the
- * pick.
- * @param {!o3djs.math.Vector3} worldIntersectionPosition world position of
- * intersection.
- */
-o3djs.picking.PickInfo = function(element,
- shapeInfo,
- rayIntersectionInfo,
- worldIntersectionPosition) {
- /**
- * The Element that was picked (Primitive).
- * @type {!o3d.Element}
- */
- this.element = element;
-
- /**
- * The ShapeInfo that was picked.
- * @type {!o3djs.picking.ShapeInfo}
- */
- this.shapeInfo = shapeInfo;
-
- /**
- * Information about the pick.
- * @type {!o3d.RayIntersectionInfo}
- */
- this.rayIntersectionInfo = rayIntersectionInfo;
-
- /**
- * The worldIntersectionPosition world position of intersection.
- * @type {!o3djs.math.Vector3}
- */
- this.worldIntersectionPosition = worldIntersectionPosition
-};
-
-/**
- * Creates a new ShapeInfo. Used to store information about Shapes. Note, even
- * though Shapes can be instanced, ShapeInfos can not so if a Shape is instanced
- * there will be more than one ShapeInfo for it.
- * @constructor
- * @param {!o3d.Shape} shape Shape to keep info about.
- * @param {!o3djs.picking.TransformInfo} parent Parent transform of the shape.
- * @param {!o3djs.picking.PickManager} pickManager The PickManager this
- * ShapeInfo belongs to.
- */
-o3djs.picking.ShapeInfo = function(shape, parent, pickManager) {
- /**
- * The Shape for this ShapeInfo
- * @type {!o3d.Shape}
- */
- this.shape = shape;
-
- /**
- * The parent TransformInfo of this Shape.
- * @type {!o3djs.picking.TransformInfo}
- */
- this.parent = parent;
-
- /**
- * The bounding box for this Shape
- * @type {o3d.BoundingBox}
- */
- this.boundingBox = null;
-
- /**
- * The PickManager this ShapeInfo belongs to.
- * @type {!o3djs.picking.PickManager}
- */
- this.pickManager = pickManager;
-
- this.update();
-};
-
-/**
- * Returns whether or not this ShapeInfo is pickable.
- * @return {boolean} Whether or not this ShapeInfo is pickable.
- */
-o3djs.picking.ShapeInfo.prototype.isPickable = function() {
- return true;
-}
-
-/**
- * Gets the BoundingBox of the Shape in this ShapeInfo.
- * @return {o3d.BoundingBox} The Shape's BoundingBox.
- */
-o3djs.picking.ShapeInfo.prototype.getBoundingBox = function() {
- return this.boundingBox;
-};
-
-/**
- * Updates the BoundingBox of the Shape in this ShapeInfo.
- */
-o3djs.picking.ShapeInfo.prototype.update = function() {
- var elements = this.shape.elements;
- if (elements.length > 0) {
- this.boundingBox = elements[0].getBoundingBox(0);
- for (var ee = 1; ee < elements.length; ee++) {
- this.boundingBox = this.boundingBox.add(elements[ee].getBoundingBox(0));
- }
- }
-};
-
-/**
- * Attempts to "pick" this Shape by checking for the intersection of a ray
- * in world space to the triangles this shape uses.
- * @param {!o3djs.picking.Ray} worldRay A ray in world space to pick against.
- * @return {o3djs.picking.PickInfo} Information about the picking.
- * null if the ray did not intersect any triangles.
- */
-o3djs.picking.ShapeInfo.prototype.pick = function(worldRay) {
- if (this.isPickable()) {
- var worldMatrix = this.parent.transform.getUpdatedWorldMatrix()
- var inverseWorldMatrix = o3djs.math.inverse(worldMatrix);
- var relativeNear = o3djs.math.matrix4.transformPoint(
- inverseWorldMatrix, worldRay.near);
- var relativeFar = o3djs.math.matrix4.transformPoint(
- inverseWorldMatrix, worldRay.far);
- var rayIntersectionInfo =
- this.boundingBox.intersectRay(relativeNear,
- relativeFar);
-
- o3djs.picking.dumpRayIntersectionInfo('SHAPE(box): ' + this.shape.name,
- rayIntersectionInfo);
-
- if (rayIntersectionInfo.intersected) {
- var elements = this.shape.elements;
- for (var e = 0; e < elements.length; e++) {
- var element = elements[e];
- rayIntersectionInfo = element.intersectRay(
- 0,
- o3djs.base.o3d.State.CULL_CCW,
- relativeNear,
- relativeFar);
- o3djs.picking.dumpRayIntersectionInfo(
- 'SHAPE(tris): ' + this.shape.name + ' : element ' + element.name,
- rayIntersectionInfo);
-
- // TODO: get closest element not just first element.
- if (rayIntersectionInfo.intersected) {
- var worldIntersectionPosition = o3djs.math.matrix4.transformPoint(
- worldMatrix, rayIntersectionInfo.position);
- return o3djs.picking.createPickInfo(element,
- this,
- rayIntersectionInfo,
- worldIntersectionPosition);
- }
- }
- }
- }
- return null;
-};
-
-/**
- * Dumps info about a ShapeInfo
- * @param {string} opt_prefix optional prefix for indenting.
- */
-o3djs.picking.ShapeInfo.prototype.dump = function(opt_prefix) {
- var prefix = opt_prefix || '';
- o3djs.picking.dprint(prefix + 'SHAPE: ' + this.shape.name + '\n');
- o3djs.picking.dprintPoint3('bb min',
- this.boundingBox.minExtent,
- prefix + ' ');
- o3djs.picking.dprintPoint3('bb max',
- this.boundingBox.maxExtent,
- prefix + ' ');
-};
-
-/**
- * Creates a new TransformInfo. Used to store information about Transforms.
- * @constructor
- * @param {!o3d.Transform} transform Transform to keep info about.
- * @param {o3djs.picking.TransformInfo} parent Parent transformInfo of the
- * transform. Can be null.
- * @param {!o3djs.picking.PickManager} pickManager The PickManager this
- * ShapeInfo belongs to.
- */
-o3djs.picking.TransformInfo = function(transform, parent, pickManager) {
- /**
- * TransformInfos for children by client id.
- * @type {!Object.<number, !o3djs.picking.TransformInfo>}
- */
- this.childTransformInfos = {};
-
- /**
- * ShapeInfos for shape of this transform by client id.
- * @type {!Object.<number, !o3djs.picking.ShapeInfo>}
- */
- this.shapeInfos = {};
-
- /**
- * The transform of this transform info.
- * @type {!o3d.Transform}
- */
- this.transform = transform;
-
- /**
- * The parent of this transform info.
- * @type {o3djs.picking.TransformInfo}
- */
- this.parent = parent;
-
- /**
- * The bounding box of this transform info.
- * @type {o3d.BoundingBox}
- */
- this.boundingBox = null;
-
- /**
- * The PickManager this TransformInfo belongs to.
- * @type {!o3djs.picking.PickManager}
- */
- this.pickManager = pickManager;
-
- /**
- * Whether or not this object is pickable when invisible.
- * This is useful for collision geometry that is not visible.
- * Of course it might argubly be better to store collision geometry
- * in a separate graph from visible geometry but sometimes it's useful
- * to have them in the same graph.
- * @type {boolean}
- */
- this.pickableEvenIfInvisible = false;
-};
-
-/**
- * Gets the BoundingBox of the Transform in this TransformInfo.
- * @return {o3d.BoundingBox} The Transform's BoundingBox.
- */
-o3djs.picking.TransformInfo.prototype.getBoundingBox = function() {
- return this.boundingBox;
-};
-
-/**
- * Returns whether or not this TransformInfo is pickable.
- *
- * If this TransformInfo is not pickable then all child shapes and
- * TransformInfos will be skipped during the picking process.
- *
- * @return {boolean} Whether or not this TransformInfo is pickable.
- */
-o3djs.picking.TransformInfo.prototype.isPickable = function() {
- return this.transform.visible || this.pickableEvenIfInvisible;
-};
-
-/**
- * Updates the shape and child lists for this TransformInfo and recomputes its
- * BoundingBox.
- */
-o3djs.picking.TransformInfo.prototype.update = function() {
- var newChildTransformInfos = {};
- var newShapeInfos = {};
- // We need to add new children and remove old ones so we walk the children
- // and for each one we find, if it already has a TransformInfo or ShapeInfo we
- // add it to our new lists, if not we create one and add it to our new lists.
- var children = this.transform.children;
- for (var c = 0; c < children.length; c++) {
- var child = children[c];
- var transformInfo = this.childTransformInfos[child.clientId];
- if (!transformInfo) {
- transformInfo = this.pickManager.createTransformInfo(child, this);
- } else {
- // clear the boundingBox so we'll regenerate it.
- transformInfo.boundingBox = null;
- }
- transformInfo.update();
- newChildTransformInfos[child.clientId] = transformInfo;
- }
- var shapes = this.transform.shapes;
- for (var s = 0; s < shapes.length; s++) {
- var shape = shapes[s];
- var shapeInfo = this.shapeInfos[shape.clientId];
- if (!shapeInfo) {
- shapeInfo = this.pickManager.createShapeInfo(shape, this);
- } else {
- // unless the vertices or elements change there is no need to
- // recompute this.
- // shapeInfo.update();
- }
- newShapeInfos[shape.clientId] = shapeInfo;
- }
-
- // o3djs.picking.dprint(
- // 'num Children: ' + children.length + '\n');
- // o3djs.picking.dprint(
- // 'num Shapes: ' + shapes.length + '\n');
-
- // Now our new lists have the correct children so replace the old lists.
- // and remove any old children from the PickManager.
- for (var skey in this.childTransformInfos) {
- var key = /** @type {number} */ (skey);
- if (!newChildTransformInfos[key]) {
- this.pickManager.removeTransformInfo(this.childTransformInfos[key]);
- }
- }
-
- this.childTransformInfos = newChildTransformInfos;
- this.shapeInfos = newShapeInfos;
-
- var boundingBox = null;
- for (var key in newShapeInfos) {
- var shapeInfo = newShapeInfos[key];
- if (shapeInfo.isPickable()) {
- var box = shapeInfo.getBoundingBox().mul(this.transform.localMatrix);
- if (!boundingBox) {
- boundingBox = box;
- } else if (box) {
- boundingBox = boundingBox.add(box);
- }
- }
- }
-
- for (var key in newChildTransformInfos) {
- var transformInfo = newChildTransformInfos[key];
- if (transformInfo.isPickable()) {
- // Note: If there is no shape at the leaf on this branch
- // there will be no bounding box.
- var box = transformInfo.getBoundingBox();
- if (box) {
- if (!boundingBox) {
- boundingBox = box.mul(this.transform.localMatrix);
- } else {
- boundingBox = boundingBox.add(box.mul(this.transform.localMatrix));
- }
- }
- }
- }
-
- this.boundingBox = boundingBox;
-};
-
-/**
- * Attempts to "pick" this TransformInfo by checking for the intersection of a
- * ray in world space to the boundingbox of the TransformInfo. If intesection
- * is succesful recursively calls its children and shapes to try to find
- * a single Shape that is hit by the ray.
- * @param {!o3djs.picking.Ray} worldRay A ray in world space to pick against.
- * @return {o3djs.picking.PickInfo} Information about the picking.
- * null if the ray did not intersect any triangles.
- */
-o3djs.picking.TransformInfo.prototype.pick = function(worldRay) {
- if (this.isPickable() && this.boundingBox) {
- var inverseWorldMatrix = o3djs.math.matrix4.identity();
- if (this.parent) {
- inverseWorldMatrix = o3djs.math.inverse(
- this.parent.transform.getUpdatedWorldMatrix());
- }
- var relativeNear =
- o3djs.math.matrix4.transformPoint(inverseWorldMatrix, worldRay.near);
- var relativeFar =
- o3djs.math.matrix4.transformPoint(inverseWorldMatrix, worldRay.far);
- var rayIntersectionInfo =
- this.boundingBox.intersectRay(relativeNear, relativeFar);
- o3djs.picking.dumpRayIntersectionInfo(
- 'TRANSFORM(box): ' + this.transform.name, rayIntersectionInfo);
-
- if (rayIntersectionInfo.intersected) {
- var closestPickInfo = null;
- var minDistance = -1;
- for (var skey in this.childTransformInfos) {
- var key = /** @type {number} */ (skey);
- var transformInfo = this.childTransformInfos[key];
- var pickInfo = transformInfo.pick(worldRay);
- if (pickInfo) {
- // is this closer than the last one?
- var distance = o3djs.math.lengthSquared(
- o3djs.math.subVector(worldRay.near,
- pickInfo.worldIntersectionPosition));
- if (!closestPickInfo || distance < minDistance) {
- minDistance = distance;
- closestPickInfo = pickInfo;
- }
- }
- }
-
- for (var skey in this.shapeInfos) {
- var key = /** @type {number} */ (skey);
- var shapeInfo = this.shapeInfos[key];
- var pickInfo = shapeInfo.pick(worldRay);
- if (pickInfo) {
- // is this closer than the last one?
- var distance = o3djs.math.lengthSquared(
- o3djs.math.subVector(worldRay.near,
- pickInfo.worldIntersectionPosition));
- if (!closestPickInfo || distance < minDistance) {
- minDistance = distance;
- closestPickInfo = pickInfo;
- }
- }
- }
- return closestPickInfo;
- }
- }
- return null;
-};
-
-/**
- * Dumps info about a TransformInfo
- * @param {string} opt_prefix optional prefix for indenting.
- */
-o3djs.picking.TransformInfo.prototype.dump = function(opt_prefix) {
- var prefix = opt_prefix || '';
-
- o3djs.picking.dprint(prefix + 'TRANSFORM: ' + this.transform.name +
- '\n');
-
- if (this.boundingBox) {
- o3djs.picking.dprintPoint3('bb min',
- this.boundingBox.minExtent,
- prefix + ' ');
- o3djs.picking.dprintPoint3('bb max',
- this.boundingBox.maxExtent,
- prefix + ' ');
- } else {
- o3djs.picking.dprint(prefix + ' bb *NA*\n');
- }
-
- o3djs.picking.dprint(prefix + '--Shapes--\n');
- for (var skey in this.shapeInfos) {
- var key = /** @type {number} */ (skey);
- var shapeInfo = this.shapeInfos[key];
- shapeInfo.dump(prefix + ' ');
- }
-
- o3djs.picking.dprint(prefix + '--Children--\n');
- for (var skey in this.childTransformInfos) {
- var key = /** @type {number} */ (skey);
- var transformInfo = this.childTransformInfos[key];
- transformInfo.dump(prefix + ' ');
- }
-};
-
-/**
- * A PickManager manages picking of primitives from a transform graph.
- * @constructor
- * @param {!o3d.Transform} rootTransform The root of the transform graph this
- * PickManager should manage.
- */
-o3djs.picking.PickManager = function(rootTransform) {
- /**
- * TransformInfos for transforms of this PickManager by client id.
- * @type {!Object.<number, !o3djs.picking.TransformInfo>}
- */
- this.transformInfosByClientId = {};
-
- /**
- * The root transform for this PickManager.
- * @type {!o3djs.picking.TransformInfo}
- */
- this.rootTransformInfo = this.createTransformInfo(rootTransform, null);
-};
-
-/**
- * Creates a new ShapeInfo.
- * @param {!o3d.Shape} shape Shape to keep info about.
- * @param {!o3djs.picking.TransformInfo} parent Parent transform of the shape.
- * @return {!o3djs.picking.ShapeInfo} The new ShapeInfo.
- */
-o3djs.picking.PickManager.prototype.createShapeInfo = function(shape, parent) {
- return new o3djs.picking.ShapeInfo(shape, parent, this);
-};
-
-/**
- * Creates a new TransformInfo.
- * @param {!o3d.Transform} transform Transform to keep info about.
- * @param {o3djs.picking.TransformInfo} parent Parent transform of the
- * transform. Can be null.
- * @return {!o3djs.picking.TransformInfo} The new TransformInfo.
- */
-o3djs.picking.PickManager.prototype.createTransformInfo =
- function(transform, parent) {
- var info = new o3djs.picking.TransformInfo(transform, parent, this);
- this.addTransformInfo(info);
- return info;
-};
-
-/**
- * Adds a transform info to this PickManager.
- * @param {!o3djs.picking.TransformInfo} transformInfo The TransformInfo to add.
- */
-o3djs.picking.PickManager.prototype.addTransformInfo = function(transformInfo) {
- this.transformInfosByClientId[transformInfo.transform.clientId] =
- transformInfo;
-};
-
-/**
- * Removes a transform info from this PickManager.
- * @param {!o3djs.picking.TransformInfo} transformInfo The TransformInfo to
- * remove.
- */
-o3djs.picking.PickManager.prototype.removeTransformInfo =
- function(transformInfo) {
- delete this.transformInfosByClientId[transformInfo.transform.clientId];
-};
-
-/**
- * Gets a transform info from this PickManager by transform.
- * @param {!o3d.Transform} transform The Transform to get a TransformInfo for.
- * @return {o3djs.picking.TransformInfo} The TransformInfo for the transform or
- * null if there isn't one.
- */
-o3djs.picking.PickManager.prototype.getTransformInfo = function(transform) {
- return this.transformInfosByClientId[transform.clientId];
-};
-
-/**
- * Updates the picking info to match the transform graph in its current state.
- */
-o3djs.picking.PickManager.prototype.update = function() {
- this.rootTransformInfo.update();
-};
-
-/**
- * Dumps info about a PickManager
- */
-o3djs.picking.PickManager.prototype.dump = function() {
- this.rootTransformInfo.dump();
-};
-
-/**
- * Attempts to "pick" objects managed by this PickManager.
- * @param {!o3djs.picking.Ray} worldRay A ray in world space to pick against.
- * @return {o3djs.picking.PickInfo} Information about the picking.
- * null if the ray did not intersect any triangles.
- */
-o3djs.picking.PickManager.prototype.pick = function(worldRay) {
- return this.rootTransformInfo.pick(worldRay);
-};
-
-/**
- * Creates a PickManager.
- * @param {!o3d.Transform} rootTransform The root of the transform graph this
- * PickManager should manage.
- * @return {!o3djs.picking.PickManager} The created PickManager.
- */
-o3djs.picking.createPickManager = function(rootTransform) {
- return new o3djs.picking.PickManager(rootTransform);
-};
-
diff --git a/o3d/samples/o3djs/plugin_math.js b/o3d/samples/o3djs/plugin_math.js
deleted file mode 100644
index 25ce285..0000000
--- a/o3d/samples/o3djs/plugin_math.js
+++ /dev/null
@@ -1,2536 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains matrix/vector math functions.
- * It adds them to the "math" module on the o3djs object.
- *
- * o3djs.math supports a row-major and a column-major mode. In both
- * modes, vectors are stored as arrays of numbers, and matrices are stored as
- * arrays of arrays of numbers.
- *
- * In row-major mode:
- *
- * - Rows of a matrix are sub-arrays.
- * - Individual entries of a matrix M get accessed in M[row][column] fashion.
- * - Tuples of coordinates are interpreted as row-vectors.
- * - A vector v gets transformed by a matrix M by multiplying in the order v*M.
- *
- * In column-major mode:
- *
- * - Columns of a matrix are sub-arrays.
- * - Individual entries of a matrix M get accessed in M[column][row] fashion.
- * - Tuples of coordinates are interpreted as column-vectors.
- * - A matrix M transforms a vector v by multiplying in the order M*v.
- *
- * When a function in o3djs.math requires separate row-major and
- * column-major versions, a function with the same name gets added to each of
- * the namespaces o3djs.math.rowMajor and o3djs.math.columnMajor. The
- * function installRowMajorFunctions() or the function
- * installColumnMajorFunctions() should get called during initialization to
- * establish the mode. installRowMajorFunctions() works by iterating through
- * the o3djs.math.rowMajor namespace and for each function foo, setting
- * o3djs.math.foo equal to o3djs.math.rowMajor.foo.
- * installRowMajorFunctions() works the same way, iterating over the columnMajor
- * namespace. At the end of this file, we call installRowMajorFunctions().
- *
- * Switching modes changes two things. It changes how a matrix is encoded as an
- * array, and it changes how the entries of a matrix get interpreted. Because
- * those two things change together, the matrix representing a given
- * transformation of space is the same JavaScript object in either mode.
- * One consequence of this is that very few functions require separate row-major
- * and column-major versions. Typically, a function requires separate versions
- * only if it makes matrix multiplication order explicit, like
- * mulMatrixMatrix(), mulMatrixVector(), or mulVectorMatrix(). Functions which
- * create a new matrix, like scaling(), rotationZYX(), and translation() return
- * the same JavaScript object in either mode, and functions which implicitly
- * multiply like scale(), rotateZYX() and translate() modify the matrix in the
- * same way in either mode.
- *
- * The convention choice made for math functions in this library is independent
- * of the convention choice for how matrices get loaded into shaders. That
- * convention is determined on a per-shader basis.
- *
- * Other utilities in o3djs should avoid making calls to functions that make
- * multiplication order explicit. Instead they should appeal to functions like:
- *
- * o3djs.math.matrix4.transformPoint
- * o3djs.math.matrix4.transformDirection
- * o3djs.math.matrix4.transformNormal
- * o3djs.math.matrix4.transformVector4
- * o3djs.math.matrix4.composition
- * o3djs.math.matrix4.compose
- *
- * These functions multiply matrices implicitly and internally choose the
- * multiplication order to get the right result. That way, utilities which use
- * o3djs.math work in either major mode. Note that this does not necessarily
- * mean all sample code will work even if a line is added which switches major
- * modes, but it does mean that calls to o3djs still do what they are supposed
- * to.
- *
- */
-
-o3djs.provide('o3djs.math', true);
-
-
-/**
- * A module for math for o3djs.math.
- * @namespace
- */
-o3djs.math = o3djs.math || {};
-
-/**
- * A random seed for the pseudoRandom function.
- * @private
- * @type {number}
- */
-o3djs.math.randomSeed_ = 0;
-
-/**
- * A constant for the pseudoRandom function
- * @private
- * @type {number}
- */
-o3djs.math.RANDOM_RANGE_ = Math.pow(2, 32);
-
-
-o3djs.math.makeMatrix = function(a,b,c,d,
- e,f,g,h,
- i,j,k,l,
- m,n,o,p) {
- if (p===undefined) {
- if (i===undefined) {
- return [[a,b],
- [c,d]];
- }
- return [[a,b,c],
- [d,e,f],
- [g,h,i]];
- }
- return [[a,b,c,d],
- [e,f,g,h],
- [i,j,k,l],
- [m,n,o,p]];
-};
-
-o3djs.math.makeMatrix2 = function(a,b,
- c,d) {
- return [[a,b],
- [c,d]];
-};
-o3djs.math.makeMatrix3 = function(a,b,c,
- d,e,f,
- g,h,i) {
- return [[a,b,c],
- [d,e,f],
- [g,h,i]];
-};
-o3djs.math.makeMatrix4 = function(a,b,c,d,
- e,f,g,h,
- i,j,k,l,
- m,n,o,p) {
- return [[a,b,c,d],
- [e,f,g,h],
- [i,j,k,l],
- [m,n,o,p]];
-};
-
-
-
-/**
- * Returns a deterministic pseudorandom number between 0 and 1
- * @return {number} a random number between 0 and 1
- */
-o3djs.math.pseudoRandom = function() {
- var math = o3djs.math;
- return (math.randomSeed_ =
- (134775813 * math.randomSeed_ + 1) %
- math.RANDOM_RANGE_) / math.RANDOM_RANGE_;
-};
-
-/**
- * Resets the pseudoRandom function sequence.
- */
-o3djs.math.resetPseudoRandom = function() {
- o3djs.math.randomSeed_ = 0;
-};
-
-/**
- * Converts degrees to radians.
- * @param {number} degrees A value in degrees.
- * @return {number} the value in radians.
- */
-o3djs.math.degToRad = function(degrees) {
- return degrees * Math.PI / 180;
-};
-
-/**
- * Converts radians to degrees.
- * @param {number} radians A value in radians.
- * @return {number} the value in degrees.
- */
-o3djs.math.radToDeg = function(radians) {
- return radians * 180 / Math.PI;
-};
-
-/**
- * Performs linear interpolation on two scalars.
- * Given scalars a and b and interpolation coefficient t, returns
- * (1 - t) * a + t * b.
- * @param {number} a Operand scalar.
- * @param {number} b Operand scalar.
- * @param {number} t Interpolation coefficient.
- * @return {number} The weighted sum of a and b.
- */
-o3djs.math.lerpScalar = function(a, b, t) {
- return (1 - t) * a + t * b;
-};
-
-/**
- * Adds two vectors; assumes a and b have the same dimension.
- * @param {!o3djs.math.Vector} a Operand vector.
- * @param {!o3djs.math.Vector} b Operand vector.
- * @return {!o3djs.math.Vector} The sum of a and b.
- */
-o3djs.math.addVector = function(a, b) {
- var r = [];
- var aLength = a.length;
- for (var i = 0; i < aLength; ++i)
- r[i] = a[i] + b[i];
- return r;
-};
-
-/**
- * Subtracts two vectors.
- * @param {!o3djs.math.Vector} a Operand vector.
- * @param {!o3djs.math.Vector} b Operand vector.
- * @return {!o3djs.math.Vector} The difference of a and b.
- */
-o3djs.math.subVector = function(a, b) {
- var r = [];
- var aLength = a.length;
- for (var i = 0; i < aLength; ++i)
- r[i] = a[i] - b[i];
- return r;
-};
-
-/**
- * Performs linear interpolation on two vectors.
- * Given vectors a and b and interpolation coefficient t, returns
- * (1 - t) * a + t * b.
- * @param {!o3djs.math.Vector} a Operand vector.
- * @param {!o3djs.math.Vector} b Operand vector.
- * @param {number} t Interpolation coefficient.
- * @return {!o3djs.math.Vector} The weighted sum of a and b.
- */
-o3djs.math.lerpVector = function(a, b, t) {
- var r = [];
- var aLength = a.length;
- for (var i = 0; i < aLength; ++i)
- r[i] = (1 - t) * a[i] + t * b[i];
- return r;
-};
-
-/**
- * Clamps a value between 0 and range using a modulo.
- * @param {number} v Value to clamp mod.
- * @param {number} range Range to clamp to.
- * @param {number} opt_rangeStart start of range. Default = 0.
- * @return {number} Clamp modded value.
- */
-o3djs.math.modClamp = function(v, range, opt_rangeStart) {
- var start = opt_rangeStart || 0;
- if (range < 0.00001) {
- return start;
- }
- v -= start;
- if (v < 0) {
- v -= Math.floor(v / range) * range;
- } else {
- v = v % range;
- }
- return v + start;
-};
-
-/**
- * Lerps in a circle.
- * Does a lerp between a and b but inside range so for example if
- * range is 100, a is 95 and b is 5 lerping will go in the positive direction.
- * @param {number} a Start value.
- * @param {number} b Target value.
- * @param {number} t Amount to lerp (0 to 1).
- * @param {number} range Range of circle.
- * @return {number} lerped result.
- */
-o3djs.math.lerpCircular = function(a, b, t, range) {
- a = o3djs.math.modClamp(a, range);
- b = o3djs.math.modClamp(b, range);
- var delta = b - a;
- if (Math.abs(delta) > range * 0.5) {
- if (delta > 0) {
- b -= range;
- } else {
- b += range;
- }
- }
- return o3djs.math.modClamp(o3djs.math.lerpScalar(a, b, t), range);
-};
-
-/**
- * Lerps radians.
- * @param {number} a Start value.
- * @param {number} b Target value.
- * @param {number} t Amount to lerp (0 to 1).
- * @return {number} lerped result.
- */
-o3djs.math.lerpRadian = function(a, b, t) {
- return o3djs.math.lerpCircular(a, b, t, Math.PI * 2);
-};
-
-/**
- * Divides a vector by a scalar.
- * @param {!o3djs.math.Vector} v The vector.
- * @param {number} k The scalar.
- * @return {!o3djs.math.Vector} v The vector v divided by k.
- */
-o3djs.math.divVectorScalar = function(v, k) {
- var r = [];
- var vLength = v.length;
- for (var i = 0; i < vLength; ++i)
- r[i] = v[i] / k;
- return r;
-};
-
-/**
- * Computes the dot product of two vectors; assumes that a and b have
- * the same dimension.
- * @param {!o3djs.math.Vector} a Operand vector.
- * @param {!o3djs.math.Vector} b Operand vector.
- * @return {number} The dot product of a and b.
- */
-o3djs.math.dot = function(a, b) {
- var r = 0.0;
- var aLength = a.length;
- for (var i = 0; i < aLength; ++i)
- r += a[i] * b[i];
- return r;
-};
-
-/**
- * Computes the cross product of two vectors; assumes both vectors have
- * three entries.
- * @param {!o3djs.math.Vector} a Operand vector.
- * @param {!o3djs.math.Vector} b Operand vector.
- * @return {!o3djs.math.Vector} The vector a cross b.
- */
-o3djs.math.cross = function(a, b) {
- return [a[1] * b[2] - a[2] * b[1],
- a[2] * b[0] - a[0] * b[2],
- a[0] * b[1] - a[1] * b[0]];
-};
-
-/**
- * Computes the Euclidean length of a vector, i.e. the square root of the
- * sum of the squares of the entries.
- * @param {!o3djs.math.Vector} a The vector.
- * @return {number} The length of a.
- */
-o3djs.math.length = function(a) {
- var r = 0.0;
- var aLength = a.length;
- for (var i = 0; i < aLength; ++i)
- r += a[i] * a[i];
- return Math.sqrt(r);
-};
-
-/**
- * Computes the square of the Euclidean length of a vector, i.e. the sum
- * of the squares of the entries.
- * @param {!o3djs.math.Vector} a The vector.
- * @return {number} The square of the length of a.
- */
-o3djs.math.lengthSquared = function(a) {
- var r = 0.0;
- var aLength = a.length;
- for (var i = 0; i < aLength; ++i)
- r += a[i] * a[i];
- return r;
-};
-
-/**
- * Computes the Euclidean distance between two vectors.
- * @param {!o3djs.math.Vector} a A vector.
- * @param {!o3djs.math.Vector} b A vector.
- * @return {number} The distance between a and b.
- */
-o3djs.math.distance = function(a, b) {
- var r = 0.0;
- var aLength = a.length;
- for (var i = 0; i < aLength; ++i) {
- var t = a[i] - b[i];
- r += t * t;
- }
- return Math.sqrt(r);
-};
-
-/**
- * Computes the square of the Euclidean distance between two vectors.
- * @param {!o3djs.math.Vector} a A vector.
- * @param {!o3djs.math.Vector} b A vector.
- * @return {number} The distance between a and b.
- */
-o3djs.math.distanceSquared = function(a, b) {
- var r = 0.0;
- var aLength = a.length;
- for (var i = 0; i < aLength; ++i) {
- var t = a[i] - b[i];
- r += t * t;
- }
- return r;
-};
-
-/**
- * Divides a vector by its Euclidean length and returns the quotient.
- * @param {!o3djs.math.Vector} a The vector.
- * @return {!o3djs.math.Vector} The normalized vector.
- */
-o3djs.math.normalize = function(a) {
- var r = [];
- var n = 0.0;
- var aLength = a.length;
- for (var i = 0; i < aLength; ++i)
- n += a[i] * a[i];
- n = Math.sqrt(n);
- for (var i = 0; i < aLength; ++i)
- r[i] = a[i] / n;
- return r;
-};
-
-/**
- * Adds two matrices; assumes a and b are the same size.
- * @param {!o3djs.math.Matrix} a Operand matrix.
- * @param {!o3djs.math.Matrix} b Operand matrix.
- * @return {!o3djs.math.Matrix} The sum of a and b.
- */
-o3djs.math.addMatrix = function(a, b) {
- var r = [];
- var aLength = a.length;
- var a0Length = a[0].length;
- for (var i = 0; i < aLength; ++i) {
- var row = [];
- var ai = a[i];
- var bi = b[i];
- for (var j = 0; j < a0Length; ++j)
- row[j] = ai[j] + bi[j];
- r[i] = row;
- }
- return r;
-};
-
-/**
- * Subtracts two matrices; assumes a and b are the same size.
- * @param {!o3djs.math.Matrix} a Operand matrix.
- * @param {!o3djs.math.Matrix} b Operand matrix.
- * @return {!o3djs.math.Matrix} The sum of a and b.
- */
-o3djs.math.subMatrix = function(a, b) {
- var r = [];
- var aLength = a.length;
- var a0Length = a[0].length;
- for (var i = 0; i < aLength; ++i) {
- var row = [];
- var ai = a[i];
- var bi = b[i];
- for (var j = 0; j < a0Length; ++j)
- row[j] = ai[j] - bi[j];
- r[i] = row;
- }
- return r;
-};
-
-/**
- * Performs linear interpolation on two matrices.
- * Given matrices a and b and interpolation coefficient t, returns
- * (1 - t) * a + t * b.
- * @param {!o3djs.math.Matrix} a Operand matrix.
- * @param {!o3djs.math.Matrix} b Operand matrix.
- * @param {number} t Interpolation coefficient.
- * @return {!o3djs.math.Matrix} The weighted of a and b.
- */
-o3djs.math.lerpMatrix = function(a, b, t) {
- var r = [];
- var aLength = a.length;
- var a0Length = a[0].length;
- for (var i = 0; i < aLength; ++i) {
- var row = [];
- var ai = a[i];
- var bi = b[i];
- for (var j = 0; j < a0Length; ++j)
- row[j] = (1 - t) * ai[j] + t * bi[j];
- r[i] = row;
- }
- return r;
-};
-
-/**
- * Divides a matrix by a scalar.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @param {number} k The scalar.
- * @return {!o3djs.math.Matrix} The matrix m divided by k.
- */
-o3djs.math.divMatrixScalar = function(m, k) {
- var r = [];
- var mLength = m.length;
- var m0Length = m[0].length;
- for (var i = 0; i < mLength; ++i) {
- r[i] = [];
- for (var j = 0; j < m0Length; ++j)
- r[i][j] = m[i][j] / k;
- }
- return r;
-};
-
-/**
- * Negates a scalar.
- * @param {number} a The scalar.
- * @return {number} -a.
- */
-o3djs.math.negativeScalar = function(a) {
- return -a;
-};
-
-/**
- * Negates a vector.
- * @param {!o3djs.math.Vector} v The vector.
- * @return {!o3djs.math.Vector} -v.
- */
-o3djs.math.negativeVector = function(v) {
- var r = [];
- var vLength = v.length;
- for (var i = 0; i < vLength; ++i) {
- r[i] = -v[i];
- }
- return r;
-};
-
-/**
- * Negates a matrix.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @return {!o3djs.math.Matrix} -m.
- */
-o3djs.math.negativeMatrix = function(m) {
- var r = [];
- var mLength = m.length;
- var m0Length = m[0].length;
- for (var i = 0; i < mLength; ++i) {
- r[i] = [];
- for (var j = 0; j < m0Length; ++j)
- r[i][j] = -m[i][j];
- }
- return r;
-};
-
-/**
- * Copies a scalar.
- * @param {number} a The scalar.
- * @return {number} a.
- */
-o3djs.math.copyScalar = function(a) {
- return a;
-};
-
-/**
- * Copies a vector.
- * @param {!o3djs.math.Vector} v The vector.
- * @return {!o3djs.math.Vector} A copy of v.
- */
-o3djs.math.copyVector = function(v) {
- var r = [];
- for (var i = 0; i < v.length; i++)
- r[i] = v[i];
- return r;
-};
-
-/**
- * Copies a matrix.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @return {!o3djs.math.Matrix} A copy of m.
- */
-o3djs.math.copyMatrix = function(m) {
- var r = [];
- var mLength = m.length;
- for (var i = 0; i < mLength; ++i) {
- r[i] = [];
- for (var j = 0; j < m[i].length; j++) {
- r[i][j] = m[i][j];
- }
- }
- return r;
-};
-
-/**
- * Returns the elements of a matrix as a one-dimensional array. The
- * rows or columns (depending on whether the matrix is row-major or
- * column-major) are concatenated.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @return {!Array.<number>} The matrix's elements as a one-dimensional array.
- */
-o3djs.math.getMatrixElements = function(m) {
- var r = [];
- var mLength = m.length;
- var k = 0;
- for (var i = 0; i < mLength; i++) {
- for (var j = 0; j < m[i].length; j++) {
- r[k++] = m[i][j];
- }
- }
- return r;
-};
-
-/**
- * Multiplies two scalars.
- * @param {number} a Operand scalar.
- * @param {number} b Operand scalar.
- * @return {number} The product of a and b.
- */
-o3djs.math.mulScalarScalar = function(a, b) {
- return a * b;
-};
-
-/**
- * Multiplies a scalar by a vector.
- * @param {number} k The scalar.
- * @param {!o3djs.math.Vector} v The vector.
- * @return {!o3djs.math.Vector} The product of k and v.
- */
-o3djs.math.mulScalarVector = function(k, v) {
- var r = [];
- var vLength = v.length;
- for (var i = 0; i < vLength; ++i) {
- r[i] = k * v[i];
- }
- return r;
-};
-
-/**
- * Multiplies a vector by a scalar.
- * @param {!o3djs.math.Vector} v The vector.
- * @param {number} k The scalar.
- * @return {!o3djs.math.Vector} The product of k and v.
- */
-o3djs.math.mulVectorScalar = function(v, k) {
- return o3djs.math.mulScalarVector(k, v);
-};
-
-/**
- * Multiplies a scalar by a matrix.
- * @param {number} k The scalar.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @return {!o3djs.math.Matrix} The product of m and k.
- */
-o3djs.math.mulScalarMatrix = function(k, m) {
- var r = [];
- var mLength = m.length;
- var m0Length = m[0].length;
- for (var i = 0; i < mLength; ++i) {
- r[i] = [];
- for (var j = 0; j < m0Length; ++j)
- r[i][j] = k * m[i][j];
- }
- return r;
-};
-
-/**
- * Multiplies a matrix by a scalar.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @param {number} k The scalar.
- * @return {!o3djs.math.Matrix} The product of m and k.
- */
-o3djs.math.mulMatrixScalar = function(m, k) {
- return o3djs.math.mulScalarMatrix(k, m);
-};
-
-/**
- * Multiplies a vector by another vector (component-wise); assumes a and
- * b have the same length.
- * @param {!o3djs.math.Vector} a Operand vector.
- * @param {!o3djs.math.Vector} b Operand vector.
- * @return {!o3djs.math.Vector} The vector of products of entries of a and
- * b.
- */
-o3djs.math.mulVectorVector = function(a, b) {
- var r = [];
- var aLength = a.length;
- for (var i = 0; i < aLength; ++i)
- r[i] = a[i] * b[i];
- return r;
-};
-
-/**
- * Divides a vector by another vector (component-wise); assumes a and
- * b have the same length.
- * @param {!o3djs.math.Vector} a Operand vector.
- * @param {!o3djs.math.Vector} b Operand vector.
- * @return {!o3djs.math.Vector} The vector of quotients of entries of a and
- * b.
- */
-o3djs.math.divVectorVector = function(a, b) {
- var r = [];
- var aLength = a.length;
- for (var i = 0; i < aLength; ++i)
- r[i] = a[i] / b[i];
- return r;
-};
-
-/**
- * Multiplies a vector by a matrix; treats the vector as a row vector; assumes
- * matrix entries are accessed in [row][column] fashion.
- * @param {!o3djs.math.Vector} v The vector.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @return {!o3djs.math.Vector} The product of v and m as a row vector.
- */
-o3djs.math.rowMajor.mulVectorMatrix = function(v, m) {
- var r = [];
- var m0Length = m[0].length;
- var vLength = v.length;
- for (var i = 0; i < m0Length; ++i) {
- r[i] = 0.0;
- for (var j = 0; j < vLength; ++j)
- r[i] += v[j] * m[j][i];
- }
- return r;
-};
-
-/**
- * Multiplies a vector by a matrix; treats the vector as a row vector; assumes
- * matrix entries are accessed in [column][row] fashion.
- * @param {!o3djs.math.Vector} v The vector.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @return {!o3djs.math.Vector} The product of v and m as a row vector.
- */
-o3djs.math.columnMajor.mulVectorMatrix = function(v, m) {
- var r = [];
- var mLength = m.length;
- var vLength = v.length;
- for (var i = 0; i < mLength; ++i) {
- r[i] = 0.0;
- var column = m[i];
- for (var j = 0; j < vLength; ++j)
- r[i] += v[j] * column[j];
- }
- return r;
-};
-
-/**
- * Multiplies a vector by a matrix; treats the vector as a row vector.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @param {!o3djs.math.Vector} v The vector.
- * @return {!o3djs.math.Vector} The product of m and v as a row vector.
- */
-o3djs.math.mulVectorMatrix = null;
-
-/**
- * Multiplies a matrix by a vector; treats the vector as a column vector.
- * assumes matrix entries are accessed in [row][column] fashion.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @param {!o3djs.math.Vector} v The vector.
- * @return {!o3djs.math.Vector} The product of m and v as a column vector.
- */
-o3djs.math.rowMajor.mulMatrixVector = function(m, v) {
- var r = [];
- var mLength = m.length;
- var m0Length = m[0].length;
- for (var i = 0; i < mLength; ++i) {
- r[i] = 0.0;
- var row = m[i];
- for (var j = 0; j < m0Length; ++j)
- r[i] += row[j] * v[j];
- }
- return r;
-};
-
-/**
- * Multiplies a matrix by a vector; treats the vector as a column vector;
- * assumes matrix entries are accessed in [column][row] fashion.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @param {!o3djs.math.Vector} v The vector.
- * @return {!o3djs.math.Vector} The product of m and v as a column vector.
- */
-o3djs.math.columnMajor.mulMatrixVector = function(m, v) {
- var r = [];
- var m0Length = m[0].length;
- var vLength = v.length;
- for (var i = 0; i < m0Length; ++i) {
- r[i] = 0.0;
- for (var j = 0; j < vLength; ++j)
- r[i] += v[j] * m[j][i];
- }
- return r;
-};
-
-/**
- * Multiplies a matrix by a vector; treats the vector as a column vector.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @param {!o3djs.math.Vector} v The vector.
- * @return {!o3djs.math.Vector} The product of m and v as a column vector.
- */
-o3djs.math.mulMatrixVector = null;
-
-/**
- * Multiplies two 2-by-2 matrices; assumes that the given matrices are 2-by-2;
- * assumes matrix entries are accessed in [row][column] fashion.
- * @param {!o3djs.math.Matrix2} a The matrix on the left.
- * @param {!o3djs.math.Matrix2} b The matrix on the right.
- * @return {!o3djs.math.Matrix2} The matrix product of a and b.
- */
-o3djs.math.rowMajor.mulMatrixMatrix2 = function(a, b) {
- var a0 = a[0];
- var a1 = a[1];
- var b0 = b[0];
- var b1 = b[1];
- var a00 = a0[0];
- var a01 = a0[1];
- var a10 = a1[0];
- var a11 = a1[1];
- var b00 = b0[0];
- var b01 = b0[1];
- var b10 = b1[0];
- var b11 = b1[1];
- return [[a00 * b00 + a01 * b10, a00 * b01 + a01 * b11],
- [a10 * b00 + a11 * b10, a10 * b01 + a11 * b11]];
-};
-
-/**
- * Multiplies two 2-by-2 matrices; assumes that the given matrices are 2-by-2;
- * assumes matrix entries are accessed in [column][row] fashion.
- * @param {!o3djs.math.Matrix2} a The matrix on the left.
- * @param {!o3djs.math.Matrix2} b The matrix on the right.
- * @return {!o3djs.math.Matrix2} The matrix product of a and b.
- */
-o3djs.math.columnMajor.mulMatrixMatrix2 = function(a, b) {
- var a0 = a[0];
- var a1 = a[1];
- var b0 = b[0];
- var b1 = b[1];
- var a00 = a0[0];
- var a01 = a0[1];
- var a10 = a1[0];
- var a11 = a1[1];
- var b00 = b0[0];
- var b01 = b0[1];
- var b10 = b1[0];
- var b11 = b1[1];
- return [[a00 * b00 + a10 * b01, a01 * b00 + a11 * b01],
- [a00 * b10 + a10 * b11, a01 * b10 + a11 * b11]];
-};
-
-/**
- * Multiplies two 2-by-2 matrices.
- * @param {!o3djs.math.Matrix2} a The matrix on the left.
- * @param {!o3djs.math.Matrix2} b The matrix on the right.
- * @return {!o3djs.math.Matrix2} The matrix product of a and b.
- */
-o3djs.math.mulMatrixMatrix2 = null;
-
-
-/**
- * Multiplies two 3-by-3 matrices; assumes that the given matrices are 3-by-3;
- * assumes matrix entries are accessed in [row][column] fashion.
- * @param {!o3djs.math.Matrix3} a The matrix on the left.
- * @param {!o3djs.math.Matrix3} b The matrix on the right.
- * @return {!o3djs.math.Matrix3} The matrix product of a and b.
- */
-o3djs.math.rowMajor.mulMatrixMatrix3 = function(a, b) {
- var a0 = a[0];
- var a1 = a[1];
- var a2 = a[2];
- var b0 = b[0];
- var b1 = b[1];
- var b2 = b[2];
- var a00 = a0[0];
- var a01 = a0[1];
- var a02 = a0[2];
- var a10 = a1[0];
- var a11 = a1[1];
- var a12 = a1[2];
- var a20 = a2[0];
- var a21 = a2[1];
- var a22 = a2[2];
- var b00 = b0[0];
- var b01 = b0[1];
- var b02 = b0[2];
- var b10 = b1[0];
- var b11 = b1[1];
- var b12 = b1[2];
- var b20 = b2[0];
- var b21 = b2[1];
- var b22 = b2[2];
- return [[a00 * b00 + a01 * b10 + a02 * b20,
- a00 * b01 + a01 * b11 + a02 * b21,
- a00 * b02 + a01 * b12 + a02 * b22],
- [a10 * b00 + a11 * b10 + a12 * b20,
- a10 * b01 + a11 * b11 + a12 * b21,
- a10 * b02 + a11 * b12 + a12 * b22],
- [a20 * b00 + a21 * b10 + a22 * b20,
- a20 * b01 + a21 * b11 + a22 * b21,
- a20 * b02 + a21 * b12 + a22 * b22]];
-};
-
-/**
- * Multiplies two 3-by-3 matrices; assumes that the given matrices are 3-by-3;
- * assumes matrix entries are accessed in [column][row] fashion.
- * @param {!o3djs.math.Matrix3} a The matrix on the left.
- * @param {!o3djs.math.Matrix3} b The matrix on the right.
- * @return {!o3djs.math.Matrix3} The matrix product of a and b.
- */
-o3djs.math.columnMajor.mulMatrixMatrix3 = function(a, b) {
- var a0 = a[0];
- var a1 = a[1];
- var a2 = a[2];
- var b0 = b[0];
- var b1 = b[1];
- var b2 = b[2];
- var a00 = a0[0];
- var a01 = a0[1];
- var a02 = a0[2];
- var a10 = a1[0];
- var a11 = a1[1];
- var a12 = a1[2];
- var a20 = a2[0];
- var a21 = a2[1];
- var a22 = a2[2];
- var b00 = b0[0];
- var b01 = b0[1];
- var b02 = b0[2];
- var b10 = b1[0];
- var b11 = b1[1];
- var b12 = b1[2];
- var b20 = b2[0];
- var b21 = b2[1];
- var b22 = b2[2];
- return [[a00 * b00 + a10 * b01 + a20 * b02,
- a01 * b00 + a11 * b01 + a21 * b02,
- a02 * b00 + a12 * b01 + a22 * b02],
- [a00 * b10 + a10 * b11 + a20 * b12,
- a01 * b10 + a11 * b11 + a21 * b12,
- a02 * b10 + a12 * b11 + a22 * b12],
- [a00 * b20 + a10 * b21 + a20 * b22,
- a01 * b20 + a11 * b21 + a21 * b22,
- a02 * b20 + a12 * b21 + a22 * b22]];
-};
-
-/**
- * Multiplies two 3-by-3 matrices; assumes that the given matrices are 3-by-3.
- * @param {!o3djs.math.Matrix3} a The matrix on the left.
- * @param {!o3djs.math.Matrix3} b The matrix on the right.
- * @return {!o3djs.math.Matrix3} The matrix product of a and b.
- */
-o3djs.math.mulMatrixMatrix3 = null;
-
-/**
- * Multiplies two 4-by-4 matrices; assumes that the given matrices are 4-by-4;
- * assumes matrix entries are accessed in [row][column] fashion.
- * @param {!o3djs.math.Matrix4} a The matrix on the left.
- * @param {!o3djs.math.Matrix4} b The matrix on the right.
- * @return {!o3djs.math.Matrix4} The matrix product of a and b.
- */
-o3djs.math.rowMajor.mulMatrixMatrix4 = function(a, b) {
- var a0 = a[0];
- var a1 = a[1];
- var a2 = a[2];
- var a3 = a[3];
- var b0 = b[0];
- var b1 = b[1];
- var b2 = b[2];
- var b3 = b[3];
- var a00 = a0[0];
- var a01 = a0[1];
- var a02 = a0[2];
- var a03 = a0[3];
- var a10 = a1[0];
- var a11 = a1[1];
- var a12 = a1[2];
- var a13 = a1[3];
- var a20 = a2[0];
- var a21 = a2[1];
- var a22 = a2[2];
- var a23 = a2[3];
- var a30 = a3[0];
- var a31 = a3[1];
- var a32 = a3[2];
- var a33 = a3[3];
- var b00 = b0[0];
- var b01 = b0[1];
- var b02 = b0[2];
- var b03 = b0[3];
- var b10 = b1[0];
- var b11 = b1[1];
- var b12 = b1[2];
- var b13 = b1[3];
- var b20 = b2[0];
- var b21 = b2[1];
- var b22 = b2[2];
- var b23 = b2[3];
- var b30 = b3[0];
- var b31 = b3[1];
- var b32 = b3[2];
- var b33 = b3[3];
- return [[a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30,
- a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31,
- a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32,
- a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33],
- [a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30,
- a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31,
- a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32,
- a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33],
- [a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30,
- a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31,
- a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32,
- a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33],
- [a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30,
- a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31,
- a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32,
- a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33]];
-};
-
-/**
- * Multiplies two 4-by-4 matrices; assumes that the given matrices are 4-by-4;
- * assumes matrix entries are accessed in [column][row] fashion.
- * @param {!o3djs.math.Matrix4} a The matrix on the left.
- * @param {!o3djs.math.Matrix4} b The matrix on the right.
- * @return {!o3djs.math.Matrix4} The matrix product of a and b.
- */
-o3djs.math.columnMajor.mulMatrixMatrix4 = function(a, b) {
- var a0 = a[0];
- var a1 = a[1];
- var a2 = a[2];
- var a3 = a[3];
- var b0 = b[0];
- var b1 = b[1];
- var b2 = b[2];
- var b3 = b[3];
- var a00 = a0[0];
- var a01 = a0[1];
- var a02 = a0[2];
- var a03 = a0[3];
- var a10 = a1[0];
- var a11 = a1[1];
- var a12 = a1[2];
- var a13 = a1[3];
- var a20 = a2[0];
- var a21 = a2[1];
- var a22 = a2[2];
- var a23 = a2[3];
- var a30 = a3[0];
- var a31 = a3[1];
- var a32 = a3[2];
- var a33 = a3[3];
- var b00 = b0[0];
- var b01 = b0[1];
- var b02 = b0[2];
- var b03 = b0[3];
- var b10 = b1[0];
- var b11 = b1[1];
- var b12 = b1[2];
- var b13 = b1[3];
- var b20 = b2[0];
- var b21 = b2[1];
- var b22 = b2[2];
- var b23 = b2[3];
- var b30 = b3[0];
- var b31 = b3[1];
- var b32 = b3[2];
- var b33 = b3[3];
- return [[a00 * b00 + a10 * b01 + a20 * b02 + a30 * b03,
- a01 * b00 + a11 * b01 + a21 * b02 + a31 * b03,
- a02 * b00 + a12 * b01 + a22 * b02 + a32 * b03,
- a03 * b00 + a13 * b01 + a23 * b02 + a33 * b03],
- [a00 * b10 + a10 * b11 + a20 * b12 + a30 * b13,
- a01 * b10 + a11 * b11 + a21 * b12 + a31 * b13,
- a02 * b10 + a12 * b11 + a22 * b12 + a32 * b13,
- a03 * b10 + a13 * b11 + a23 * b12 + a33 * b13],
- [a00 * b20 + a10 * b21 + a20 * b22 + a30 * b23,
- a01 * b20 + a11 * b21 + a21 * b22 + a31 * b23,
- a02 * b20 + a12 * b21 + a22 * b22 + a32 * b23,
- a03 * b20 + a13 * b21 + a23 * b22 + a33 * b23],
- [a00 * b30 + a10 * b31 + a20 * b32 + a30 * b33,
- a01 * b30 + a11 * b31 + a21 * b32 + a31 * b33,
- a02 * b30 + a12 * b31 + a22 * b32 + a32 * b33,
- a03 * b30 + a13 * b31 + a23 * b32 + a33 * b33]];
-};
-
-/**
- * Multiplies two 4-by-4 matrices; assumes that the given matrices are 4-by-4.
- * @param {!o3djs.math.Matrix4} a The matrix on the left.
- * @param {!o3djs.math.Matrix4} b The matrix on the right.
- * @return {!o3djs.math.Matrix4} The matrix product of a and b.
- */
-o3djs.math.mulMatrixMatrix4 = null;
-
-/**
- * Multiplies two matrices; assumes that the sizes of the matrices are
- * appropriately compatible; assumes matrix entries are accessed in
- * [row][column] fashion.
- * @param {!o3djs.math.Matrix} a The matrix on the left.
- * @param {!o3djs.math.Matrix} b The matrix on the right.
- * @return {!o3djs.math.Matrix} The matrix product of a and b.
- */
-o3djs.math.rowMajor.mulMatrixMatrix = function(a, b) {
- var r = [];
- var aRows = a.length;
- var bColumns = b[0].length;
- var bRows = b.length;
- for (var i = 0; i < aRows; ++i) {
- var v = []; // v becomes a row of the answer.
- var ai = a[i]; // ith row of a.
- for (var j = 0; j < bColumns; ++j) {
- v[j] = 0.0;
- for (var k = 0; k < bRows; ++k)
- v[j] += ai[k] * b[k][j]; // kth row, jth column.
- }
- r[i] = v;
- }
- return r;
-};
-
-/**
- * Multiplies two matrices; assumes that the sizes of the matrices are
- * appropriately compatible; assumes matrix entries are accessed in
- * [row][column] fashion.
- * @param {!o3djs.math.Matrix} a The matrix on the left.
- * @param {!o3djs.math.Matrix} b The matrix on the right.
- * @return {!o3djs.math.Matrix} The matrix product of a and b.
- */
-o3djs.math.columnMajor.mulMatrixMatrix = function(a, b) {
- var r = [];
- var bColumns = b.length;
- var aRows = a[0].length;
- var aColumns = a.length;
- for (var i = 0; i < bColumns; ++i) {
- var v = []; // v becomes a column of the answer.
- var bi = b[i]; // ith column of b.
- for (var j = 0; j < aRows; ++j) {
- v[j] = 0.0;
- for (var k = 0; k < aColumns; ++k)
- v[j] += bi[k] * a[k][j]; // kth column, jth row.
- }
- r[i] = v;
- }
- return r;
-};
-
-/**
- * Multiplies two matrices; assumes that the sizes of the matrices are
- * appropriately compatible.
- * @param {!o3djs.math.Matrix} a The matrix on the left.
- * @param {!o3djs.math.Matrix} b The matrix on the right.
- * @return {!o3djs.math.Matrix} The matrix product of a and b.
- */
-o3djs.math.mulMatrixMatrix = null;
-
-/**
- * Gets the jth column of the given matrix m; assumes matrix entries are
- * accessed in [row][column] fashion.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @param {number} j The index of the desired column.
- * @return {!o3djs.math.Vector} The jth column of m as a vector.
- */
-o3djs.math.rowMajor.column = function(m, j) {
- var r = [];
- var mLength = m.length;
- for (var i = 0; i < mLength; ++i) {
- r[i] = m[i][j];
- }
- return r;
-};
-
-/**
- * Gets the jth column of the given matrix m; assumes matrix entries are
- * accessed in [column][row] fashion.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @param {number} j The index of the desired column.
- * @return {!o3djs.math.Vector} The jth column of m as a vector.
- */
-o3djs.math.columnMajor.column = function(m, j) {
- return m[j].slice();
-};
-
-/**
- * Gets the jth column of the given matrix m.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @param {number} j The index of the desired column.
- * @return {!o3djs.math.Vector} The jth column of m as a vector.
- */
-o3djs.math.column = null;
-
-/**
- * Gets the ith row of the given matrix m; assumes matrix entries are
- * accessed in [row][column] fashion.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @param {number} i The index of the desired row.
- * @return {!o3djs.math.Vector} The ith row of m.
- */
-o3djs.math.rowMajor.row = function(m, i) {
- return m[i].slice();
-};
-
-/**
- * Gets the ith row of the given matrix m; assumes matrix entries are
- * accessed in [column][row] fashion.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @param {number} i The index of the desired row.
- * @return {!o3djs.math.Vector} The ith row of m.
- */
-o3djs.math.columnMajor.row = function(m, i) {
- var r = [];
- var mLength = m.length;
- for (var j = 0; j < mLength; ++j) {
- r[j] = m[j][i];
- }
- return r;
-};
-
-/**
- * Gets the ith row of the given matrix m.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @param {number} i The index of the desired row.
- * @return {!o3djs.math.Vector} The ith row of m.
- */
-o3djs.math.row = null;
-
-/**
- * Creates an n-by-n identity matrix.
- * @param {number} n The dimension of the identity matrix required.
- * @return {!o3djs.math.Matrix} An n-by-n identity matrix.
- */
-o3djs.math.identity = function(n) {
- var r = [];
- for (var j = 0; j < n; ++j) {
- r[j] = [];
- for (var i = 0; i < n; ++i)
- r[j][i] = (i == j) ? 1 : 0;
- }
- return r;
-};
-
-/**
- * Takes the transpose of a matrix.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @return {!o3djs.math.Matrix} The transpose of m.
- */
-o3djs.math.transpose = function(m) {
- var r = [];
- var m0Length = m[0].length;
- var mLength = m.length;
- for (var j = 0; j < m0Length; ++j) {
- r[j] = [];
- for (var i = 0; i < mLength; ++i)
- r[j][i] = m[i][j];
- }
- return r;
-};
-
-/**
- * Computes the trace (sum of the diagonal entries) of a square matrix;
- * assumes m is square.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @return {number} The trace of m.
- */
-o3djs.math.trace = function(m) {
- var r = 0.0;
- var mLength = m.length;
- for (var i = 0; i < mLength; ++i)
- r += m[i][i];
- return r;
-};
-
-/**
- * Computes the determinant of a 1-by-1 matrix.
- * @param {!o3djs.math.Matrix1} m The matrix.
- * @return {number} The determinant of m.
- */
-o3djs.math.det1 = function(m) {
- return m[0][0];
-};
-
-/**
- * Computes the determinant of a 2-by-2 matrix.
- * @param {!o3djs.math.Matrix2} m The matrix.
- * @return {number} The determinant of m.
- */
-o3djs.math.det2 = function(m) {
- return m[0][0] * m[1][1] - m[0][1] * m[1][0];
-};
-
-/**
- * Computes the determinant of a 3-by-3 matrix.
- * @param {!o3djs.math.Matrix3} m The matrix.
- * @return {number} The determinant of m.
- */
-o3djs.math.det3 = function(m) {
- return m[2][2] * (m[0][0] * m[1][1] - m[0][1] * m[1][0]) -
- m[2][1] * (m[0][0] * m[1][2] - m[0][2] * m[1][0]) +
- m[2][0] * (m[0][1] * m[1][2] - m[0][2] * m[1][1]);
-};
-
-/**
- * Computes the determinant of a 4-by-4 matrix.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @return {number} The determinant of m.
- */
-o3djs.math.det4 = function(m) {
- var t01 = m[0][0] * m[1][1] - m[0][1] * m[1][0];
- var t02 = m[0][0] * m[1][2] - m[0][2] * m[1][0];
- var t03 = m[0][0] * m[1][3] - m[0][3] * m[1][0];
- var t12 = m[0][1] * m[1][2] - m[0][2] * m[1][1];
- var t13 = m[0][1] * m[1][3] - m[0][3] * m[1][1];
- var t23 = m[0][2] * m[1][3] - m[0][3] * m[1][2];
- return m[3][3] * (m[2][2] * t01 - m[2][1] * t02 + m[2][0] * t12) -
- m[3][2] * (m[2][3] * t01 - m[2][1] * t03 + m[2][0] * t13) +
- m[3][1] * (m[2][3] * t02 - m[2][2] * t03 + m[2][0] * t23) -
- m[3][0] * (m[2][3] * t12 - m[2][2] * t13 + m[2][1] * t23);
-};
-
-/**
- * Computes the inverse of a 1-by-1 matrix.
- * @param {!o3djs.math.Matrix1} m The matrix.
- * @return {!o3djs.math.Matrix1} The inverse of m.
- */
-o3djs.math.inverse1 = function(m) {
- return [[1.0 / m[0][0]]];
-};
-
-/**
- * Computes the inverse of a 2-by-2 matrix.
- * @param {!o3djs.math.Matrix2} m The matrix.
- * @return {!o3djs.math.Matrix2} The inverse of m.
- */
-o3djs.math.inverse2 = function(m) {
- var d = 1.0 / (m[0][0] * m[1][1] - m[0][1] * m[1][0]);
- return [[d * m[1][1], -d * m[0][1]], [-d * m[1][0], d * m[0][0]]];
-};
-
-/**
- * Computes the inverse of a 3-by-3 matrix.
- * @param {!o3djs.math.Matrix3} m The matrix.
- * @return {!o3djs.math.Matrix3} The inverse of m.
- */
-o3djs.math.inverse3 = function(m) {
- var t00 = m[1][1] * m[2][2] - m[1][2] * m[2][1];
- var t10 = m[0][1] * m[2][2] - m[0][2] * m[2][1];
- var t20 = m[0][1] * m[1][2] - m[0][2] * m[1][1];
- var d = 1.0 / (m[0][0] * t00 - m[1][0] * t10 + m[2][0] * t20);
- return [[d * t00, -d * t10, d * t20],
- [-d * (m[1][0] * m[2][2] - m[1][2] * m[2][0]),
- d * (m[0][0] * m[2][2] - m[0][2] * m[2][0]),
- -d * (m[0][0] * m[1][2] - m[0][2] * m[1][0])],
- [d * (m[1][0] * m[2][1] - m[1][1] * m[2][0]),
- -d * (m[0][0] * m[2][1] - m[0][1] * m[2][0]),
- d * (m[0][0] * m[1][1] - m[0][1] * m[1][0])]];
-};
-
-/**
- * Computes the inverse of a 4-by-4 matrix.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @return {!o3djs.math.Matrix4} The inverse of m.
- */
-o3djs.math.inverse4 = function(m) {
- var tmp_0 = m[2][2] * m[3][3];
- var tmp_1 = m[3][2] * m[2][3];
- var tmp_2 = m[1][2] * m[3][3];
- var tmp_3 = m[3][2] * m[1][3];
- var tmp_4 = m[1][2] * m[2][3];
- var tmp_5 = m[2][2] * m[1][3];
- var tmp_6 = m[0][2] * m[3][3];
- var tmp_7 = m[3][2] * m[0][3];
- var tmp_8 = m[0][2] * m[2][3];
- var tmp_9 = m[2][2] * m[0][3];
- var tmp_10 = m[0][2] * m[1][3];
- var tmp_11 = m[1][2] * m[0][3];
- var tmp_12 = m[2][0] * m[3][1];
- var tmp_13 = m[3][0] * m[2][1];
- var tmp_14 = m[1][0] * m[3][1];
- var tmp_15 = m[3][0] * m[1][1];
- var tmp_16 = m[1][0] * m[2][1];
- var tmp_17 = m[2][0] * m[1][1];
- var tmp_18 = m[0][0] * m[3][1];
- var tmp_19 = m[3][0] * m[0][1];
- var tmp_20 = m[0][0] * m[2][1];
- var tmp_21 = m[2][0] * m[0][1];
- var tmp_22 = m[0][0] * m[1][1];
- var tmp_23 = m[1][0] * m[0][1];
-
- var t0 = (tmp_0 * m[1][1] + tmp_3 * m[2][1] + tmp_4 * m[3][1]) -
- (tmp_1 * m[1][1] + tmp_2 * m[2][1] + tmp_5 * m[3][1]);
- var t1 = (tmp_1 * m[0][1] + tmp_6 * m[2][1] + tmp_9 * m[3][1]) -
- (tmp_0 * m[0][1] + tmp_7 * m[2][1] + tmp_8 * m[3][1]);
- var t2 = (tmp_2 * m[0][1] + tmp_7 * m[1][1] + tmp_10 * m[3][1]) -
- (tmp_3 * m[0][1] + tmp_6 * m[1][1] + tmp_11 * m[3][1]);
- var t3 = (tmp_5 * m[0][1] + tmp_8 * m[1][1] + tmp_11 * m[2][1]) -
- (tmp_4 * m[0][1] + tmp_9 * m[1][1] + tmp_10 * m[2][1]);
-
- var d = 1.0 / (m[0][0] * t0 + m[1][0] * t1 + m[2][0] * t2 + m[3][0] * t3);
-
- var row0 = [d * t0, d * t1, d * t2, d * t3];
- var row1 = [d * ((tmp_1 * m[1][0] + tmp_2 * m[2][0] + tmp_5 * m[3][0]) -
- (tmp_0 * m[1][0] + tmp_3 * m[2][0] + tmp_4 * m[3][0])),
- d * ((tmp_0 * m[0][0] + tmp_7 * m[2][0] + tmp_8 * m[3][0]) -
- (tmp_1 * m[0][0] + tmp_6 * m[2][0] + tmp_9 * m[3][0])),
- d * ((tmp_3 * m[0][0] + tmp_6 * m[1][0] + tmp_11 * m[3][0]) -
- (tmp_2 * m[0][0] + tmp_7 * m[1][0] + tmp_10 * m[3][0])),
- d * ((tmp_4 * m[0][0] + tmp_9 * m[1][0] + tmp_10 * m[2][0]) -
- (tmp_5 * m[0][0] + tmp_8 * m[1][0] + tmp_11 * m[2][0]))];
- var row2 =[d * ((tmp_12 * m[1][3] + tmp_15 * m[2][3] + tmp_16 * m[3][3]) -
- (tmp_13 * m[1][3] + tmp_14 * m[2][3] + tmp_17 * m[3][3])),
- d * ((tmp_13 * m[0][3] + tmp_18 * m[2][3] + tmp_21 * m[3][3]) -
- (tmp_12 * m[0][3] + tmp_19 * m[2][3] + tmp_20 * m[3][3])),
- d * ((tmp_14 * m[0][3] + tmp_19 * m[1][3] + tmp_22 * m[3][3]) -
- (tmp_15 * m[0][3] + tmp_18 * m[1][3] + tmp_23 * m[3][3])),
- d * ((tmp_17 * m[0][3] + tmp_20 * m[1][3] + tmp_23 * m[2][3]) -
- (tmp_16 * m[0][3] + tmp_21 * m[1][3] + tmp_22 * m[2][3]))];
- var row3 = [d * ((tmp_14 * m[2][2] + tmp_17 * m[3][2] + tmp_13 * m[1][2]) -
- (tmp_16 * m[3][2] + tmp_12 * m[1][2] + tmp_15 * m[2][2])),
- d * ((tmp_20 * m[3][2] + tmp_12 * m[0][2] + tmp_19 * m[2][2]) -
- (tmp_18 * m[2][2] + tmp_21 * m[3][2] + tmp_13 * m[0][2])),
- d * ((tmp_18 * m[1][2] + tmp_23 * m[3][2] + tmp_15 * m[0][2]) -
- (tmp_22 * m[3][2] + tmp_14 * m[0][2] + tmp_19 * m[1][2])),
- d * ((tmp_22 * m[2][2] + tmp_16 * m[0][2] + tmp_21 * m[1][2]) -
- (tmp_20 * m[1][2] + tmp_23 * m[2][2] + tmp_17 * m[0][2]))];
- return [row0, row1, row2, row3];
-};
-
-/**
- * Computes the determinant of the cofactor matrix obtained by removal
- * of a specified row and column. This is a helper function for the general
- * determinant and matrix inversion functions.
- * @param {!o3djs.math.Matrix} a The original matrix.
- * @param {number} x The row to be removed.
- * @param {number} y The column to be removed.
- * @return {number} The determinant of the matrix obtained by removing
- * row x and column y from a.
- */
-o3djs.math.codet = function(a, x, y) {
- var size = a.length;
- var b = [];
- var ai = 0;
- for (var bi = 0; bi < size - 1; ++bi) {
- if (ai == x)
- ai++;
- b[bi] = [];
- var aj = 0;
- for (var bj = 0; bj < size - 1; ++bj) {
- if (aj == y)
- aj++;
- b[bi][bj] = a[ai][aj];
- aj++;
- }
- ai++;
- }
- return o3djs.math.det(b);
-};
-
-/**
- * Computes the determinant of an arbitrary square matrix.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @return {number} the determinant of m.
- */
-o3djs.math.det = function(m) {
- var d = m.length;
- if (d <= 4) {
- return o3djs.math['det' + d](m);
- }
- var r = 0.0;
- var sign = 1;
- var row = m[0];
- var mLength = m.length;
- for (var y = 0; y < mLength; y++) {
- r += sign * row[y] * o3djs.math.codet(m, 0, y);
- sign *= -1;
- }
- return r;
-};
-
-/**
- * Computes the inverse of an arbitrary square matrix.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @return {!o3djs.math.Matrix} The inverse of m.
- */
-o3djs.math.inverse = function(m) {
- var d = m.length;
- if (d <= 4) {
- return o3djs.math['inverse' + d](m);
- }
- var r = [];
- var size = m.length;
- for (var j = 0; j < size; ++j) {
- r[j] = [];
- for (var i = 0; i < size; ++i)
- r[j][i] = ((i + j) % 2 ? -1 : 1) * o3djs.math.codet(m, i, j);
- }
- return o3djs.math.divMatrixScalar(r, o3djs.math.det(m));
-};
-
-/**
- * Performs Graham-Schmidt orthogonalization on the vectors which make up the
- * given matrix and returns the result in the rows of a new matrix. When
- * multiplying many orthogonal matrices together, errors can accumulate causing
- * the product to fail to be orthogonal. This function can be used to correct
- * that.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @return {!o3djs.math.Matrix} A matrix whose rows are obtained from the
- * rows of m by the Graham-Schmidt process.
- */
-o3djs.math.orthonormalize = function(m) {
- var r = [];
- var mLength = m.length;
- for (var i = 0; i < mLength; ++i) {
- var v = m[i];
- for (var j = 0; j < i; ++j) {
- v = o3djs.math.subVector(v, o3djs.math.mulScalarVector(
- o3djs.math.dot(r[j], m[i]), r[j]));
- }
- r[i] = o3djs.math.normalize(v);
- }
- return r;
-};
-
-/**
- * Computes the inverse of a 4-by-4 matrix.
- * Note: It is faster to call this than o3djs.math.inverse.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @return {!o3djs.math.Matrix4} The inverse of m.
- */
-o3djs.math.matrix4.inverse = function(m) {
- return o3djs.math.inverse4(m);
-};
-
-/**
- * Multiplies two 4-by-4 matrices; assumes that the given matrices are 4-by-4.
- * Note: It is faster to call this than o3djs.math.mul.
- * @param {!o3djs.math.Matrix4} a The matrix on the left.
- * @param {!o3djs.math.Matrix4} b The matrix on the right.
- * @return {!o3djs.math.Matrix4} The matrix product of a and b.
- */
-o3djs.math.matrix4.mul = function(a, b) {
- return o3djs.math.mulMatrixMatrix4(a, b);
-};
-
-/**
- * Computes the determinant of a 4-by-4 matrix.
- * Note: It is faster to call this than o3djs.math.det.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @return {number} The determinant of m.
- */
-o3djs.math.matrix4.det = function(m) {
- return o3djs.math.det4(m);
-};
-
-/**
- * Copies a Matrix4.
- * Note: It is faster to call this than o3djs.math.copy.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @return {!o3djs.math.Matrix4} A copy of m.
- */
-o3djs.math.matrix4.copy = function(m) {
- return o3djs.math.copyMatrix(m);
-};
-
-/**
- * Sets the upper 3-by-3 block of matrix a to the upper 3-by-3 block of matrix
- * b; assumes that a and b are big enough to contain an upper 3-by-3 block.
- * @param {!o3djs.math.Matrix4} a A matrix.
- * @param {!o3djs.math.Matrix3} b A 3-by-3 matrix.
- * @return {!o3djs.math.Matrix4} a once modified.
- */
-o3djs.math.matrix4.setUpper3x3 = function(a, b) {
- var b0 = b[0];
- var b1 = b[1];
- var b2 = b[2];
-
- a[0].splice(0, 3, b0[0], b0[1], b0[2]);
- a[1].splice(0, 3, b1[0], b1[1], b1[2]);
- a[2].splice(0, 3, b2[0], b2[1], b2[2]);
-
- return a;
-};
-
-/**
- * Returns a 3-by-3 matrix mimicking the upper 3-by-3 block of m; assumes m
- * is big enough to contain an upper 3-by-3 block.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @return {!o3djs.math.Matrix3} The upper 3-by-3 block of m.
- */
-o3djs.math.matrix4.getUpper3x3 = function(m) {
- return [m[0].slice(0, 3), m[1].slice(0, 3), m[2].slice(0, 3)];
-};
-
-/**
- * Sets the translation component of a 4-by-4 matrix to the given
- * vector.
- * @param {!o3djs.math.Matrix4} a The matrix.
- * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} v The vector.
- * @return {!o3djs.math.Matrix4} a once modified.
- */
-o3djs.math.matrix4.setTranslation = function(a, v) {
- a[3].splice(0, 4, v[0], v[1], v[2], 1);
- return a;
-};
-
-/**
- * Returns the translation component of a 4-by-4 matrix as a vector with 3
- * entries.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @return {!o3djs.math.Vector3} The translation component of m.
- */
-o3djs.math.matrix4.getTranslation = function(m) {
- return m[3].slice(0, 3);
-};
-
-/**
- * Takes a 4-by-4 matrix and a vector with 3 entries,
- * interprets the vector as a point, transforms that point by the matrix, and
- * returns the result as a vector with 3 entries.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @param {!o3djs.math.Vector3} v The point.
- * @return {!o3djs.math.Vector3} The transformed point.
- */
-o3djs.math.matrix4.transformPoint = function(m, v) {
- var v0 = v[0];
- var v1 = v[1];
- var v2 = v[2];
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
-
- var d = v0 * m0[3] + v1 * m1[3] + v2 * m2[3] + m3[3];
- return [(v0 * m0[0] + v1 * m1[0] + v2 * m2[0] + m3[0]) / d,
- (v0 * m0[1] + v1 * m1[1] + v2 * m2[1] + m3[1]) / d,
- (v0 * m0[2] + v1 * m1[2] + v2 * m2[2] + m3[2]) / d];
-};
-
-/**
- * Takes a 4-by-4 matrix and a vector with 4 entries, transforms that vector by
- * the matrix, and returns the result as a vector with 4 entries.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @param {!o3djs.math.Vector4} v The point in homogenous coordinates.
- * @return {!o3djs.math.Vector4} The transformed point in homogenous
- * coordinates.
- */
-o3djs.math.matrix4.transformVector4 = function(m, v) {
- var v0 = v[0];
- var v1 = v[1];
- var v2 = v[2];
- var v3 = v[3];
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
-
- return [v0 * m0[0] + v1 * m1[0] + v2 * m2[0] + v3 * m3[0],
- v0 * m0[1] + v1 * m1[1] + v2 * m2[1] + v3 * m3[1],
- v0 * m0[2] + v1 * m1[2] + v2 * m2[2] + v3 * m3[2],
- v0 * m0[3] + v1 * m1[3] + v2 * m2[3] + v3 * m3[3]];
-};
-
-/**
- * Takes a 4-by-4 matrix and a vector with 3 entries, interprets the vector as a
- * direction, transforms that direction by the matrix, and returns the result;
- * assumes the transformation of 3-dimensional space represented by the matrix
- * is parallel-preserving, i.e. any combination of rotation, scaling and
- * translation, but not a perspective distortion. Returns a vector with 3
- * entries.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @param {!o3djs.math.Vector3} v The direction.
- * @return {!o3djs.math.Vector3} The transformed direction.
- */
-o3djs.math.matrix4.transformDirection = function(m, v) {
- var v0 = v[0];
- var v1 = v[1];
- var v2 = v[2];
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
-
- return [v0 * m0[0] + v1 * m1[0] + v2 * m2[0],
- v0 * m0[1] + v1 * m1[1] + v2 * m2[1],
- v0 * m0[2] + v1 * m1[2] + v2 * m2[2]];
-};
-
-/**
- * Takes a 4-by-4 matrix m and a vector v with 3 entries, interprets the vector
- * as a normal to a surface, and computes a vector which is normal upon
- * transforming that surface by the matrix. The effect of this function is the
- * same as transforming v (as a direction) by the inverse-transpose of m. This
- * function assumes the transformation of 3-dimensional space represented by the
- * matrix is parallel-preserving, i.e. any combination of rotation, scaling and
- * translation, but not a perspective distortion. Returns a vector with 3
- * entries.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @param {!o3djs.math.Vector3} v The normal.
- * @return {!o3djs.math.Vector3} The transformed normal.
- */
-o3djs.math.matrix4.transformNormal = function(m, v) {
- var mInverse = o3djs.math.inverse4(m);
- var v0 = v[0];
- var v1 = v[1];
- var v2 = v[2];
- var mi0 = mInverse[0];
- var mi1 = mInverse[1];
- var mi2 = mInverse[2];
- var mi3 = mInverse[3];
-
- return [v0 * mi0[0] + v1 * mi0[1] + v2 * mi0[2],
- v0 * mi1[0] + v1 * mi1[1] + v2 * mi1[2],
- v0 * mi2[0] + v1 * mi2[1] + v2 * mi2[2]];
-};
-
-/**
- * Creates a 4-by-4 identity matrix.
- * @return {!o3djs.math.Matrix4} The 4-by-4 identity.
- */
-o3djs.math.matrix4.identity = function() {
- return [
- [1, 0, 0, 0],
- [0, 1, 0, 0],
- [0, 0, 1, 0],
- [0, 0, 0, 1]
- ];
-};
-
-/**
- * Sets the given 4-by-4 matrix to the identity matrix.
- * @param {!o3djs.math.Matrix4} m The matrix to set to identity.
- * @return {!o3djs.math.Matrix4} m once modified.
- */
-o3djs.math.matrix4.setIdentity = function(m) {
- for (var i = 0; i < 4; i++) {
- for (var j = 0; j < 4; j++) {
- if (i == j) {
- m[i][j] = 1;
- } else {
- m[i][j] = 0;
- }
- }
- }
- return m;
-};
-
-/**
- * Computes a 4-by-4 perspective transformation matrix given the angular height
- * of the frustum, the aspect ratio, and the near and far clipping planes. The
- * arguments define a frustum extending in the negative z direction. The given
- * angle is the vertical angle of the frustum, and the horizontal angle is
- * determined to produce the given aspect ratio. The arguments near and far are
- * the distances to the near and far clipping planes. Note that near and far
- * are not z coordinates, but rather they are distances along the negative
- * z-axis. The matrix generated sends the viewing frustum to the unit box.
- * We assume a unit box extending from -1 to 1 in the x and y dimensions and
- * from 0 to 1 in the z dimension.
- * @param {number} angle The camera angle from top to bottom (in radians).
- * @param {number} aspect The aspect ratio width / height.
- * @param {number} near The depth (negative z coordinate)
- * of the near clipping plane.
- * @param {number} far The depth (negative z coordinate)
- * of the far clipping plane.
- * @return {!o3djs.math.Matrix4} The perspective matrix.
- */
-o3djs.math.matrix4.perspective = function(angle, aspect, near, far) {
- var f = Math.tan(0.5 * (Math.PI - angle));
- var range = near - far;
-
- return [
- [f / aspect, 0, 0, 0],
- [0, f, 0, 0],
- [0, 0, far / range, -1],
- [0, 0, near * far / range, 0]
- ];
-};
-
-/**
- * Computes a 4-by-4 orthographic projection matrix given the coordinates of the
- * planes defining the axis-aligned, box-shaped viewing volume. The matrix
- * generated sends that box to the unit box. Note that although left and right
- * are x coordinates and bottom and top are y coordinates, near and far
- * are not z coordinates, but rather they are distances along the negative
- * z-axis. We assume a unit box extending from -1 to 1 in the x and y
- * dimensions and from 0 to 1 in the z dimension.
- * @param {number} left The x coordinate of the left plane of the box.
- * @param {number} right The x coordinate of the right plane of the box.
- * @param {number} bottom The y coordinate of the bottom plane of the box.
- * @param {number} top The y coordinate of the right plane of the box.
- * @param {number} near The negative z coordinate of the near plane of the box.
- * @param {number} far The negative z coordinate of the far plane of the box.
- * @return {!o3djs.math.Matrix4} The orthographic projection matrix.
- */
-o3djs.math.matrix4.orthographic =
- function(left, right, bottom, top, near, far) {
- return [
- [2 / (right - left), 0, 0, 0],
- [0, 2 / (top - bottom), 0, 0],
- [0, 0, 1 / (near - far), 0],
- [(left + right) / (left - right),
- (bottom + top) / (bottom - top),
- near / (near - far), 1]
- ];
-};
-
-/**
- * Computes a 4-by-4 perspective transformation matrix given the left, right,
- * top, bottom, near and far clipping planes. The arguments define a frustum
- * extending in the negative z direction. The arguments near and far are the
- * distances to the near and far clipping planes. Note that near and far are not
- * z coordinates, but rather they are distances along the negative z-axis. The
- * matrix generated sends the viewing frustum to the unit box. We assume a unit
- * box extending from -1 to 1 in the x and y dimensions and from 0 to 1 in the z
- * dimension.
- * @param {number} left The x coordinate of the left plane of the box.
- * @param {number} right The x coordinate of the right plane of the box.
- * @param {number} bottom The y coordinate of the bottom plane of the box.
- * @param {number} top The y coordinate of the right plane of the box.
- * @param {number} near The negative z coordinate of the near plane of the box.
- * @param {number} far The negative z coordinate of the far plane of the box.
- * @return {!o3djs.math.Matrix4} The perspective projection matrix.
- */
-o3djs.math.matrix4.frustum = function(left, right, bottom, top, near, far) {
- var dx = (right - left);
- var dy = (top - bottom);
- var dz = (near - far);
- return [
- [2 * near / dx, 0, 0, 0],
- [0, 2 * near / dy, 0, 0],
- [(left + right) / dx, (top + bottom) / dy, far / dz, -1],
- [0, 0, near * far / dz, 0]];
-};
-
-/**
- * Computes a 4-by-4 look-at transformation. The transformation generated is
- * an orthogonal rotation matrix with translation component. The translation
- * component sends the eye to the origin. The rotation component sends the
- * vector pointing from the eye to the target to a vector pointing in the
- * negative z direction, and also sends the up vector into the upper half of
- * the yz plane.
- * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} eye The position
- * of the eye.
- * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} target The
- * position meant to be viewed.
- * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} up A vector
- * pointing up.
- * @return {!o3djs.math.Matrix4} The look-at matrix.
- */
-o3djs.math.matrix4.lookAt = function(eye, target, up) {
- var vz = o3djs.math.normalize(
- o3djs.math.subVector(eye, target).slice(0, 3)).concat(0);
- var vx = o3djs.math.normalize(
- o3djs.math.cross(up, vz)).concat(0);
- var vy = o3djs.math.cross(vz, vx).concat(0);
-
- return o3djs.math.inverse([vx, vy, vz, eye.concat(1)]);
-};
-
-/**
- * Takes two 4-by-4 matrices, a and b, and computes the product in the order
- * that pre-composes b with a. In other words, the matrix returned will
- * transform by b first and then a. Note this is subtly different from just
- * multiplying the matrices together. For given a and b, this function returns
- * the same object in both row-major and column-major mode.
- * @param {!o3djs.math.Matrix4} a A 4-by-4 matrix.
- * @param {!o3djs.math.Matrix4} b A 4-by-4 matrix.
- * @return {!o3djs.math.Matrix4} the composition of a and b, b first then a.
- */
-o3djs.math.matrix4.composition = function(a, b) {
- var a0 = a[0];
- var a1 = a[1];
- var a2 = a[2];
- var a3 = a[3];
- var b0 = b[0];
- var b1 = b[1];
- var b2 = b[2];
- var b3 = b[3];
- var a00 = a0[0];
- var a01 = a0[1];
- var a02 = a0[2];
- var a03 = a0[3];
- var a10 = a1[0];
- var a11 = a1[1];
- var a12 = a1[2];
- var a13 = a1[3];
- var a20 = a2[0];
- var a21 = a2[1];
- var a22 = a2[2];
- var a23 = a2[3];
- var a30 = a3[0];
- var a31 = a3[1];
- var a32 = a3[2];
- var a33 = a3[3];
- var b00 = b0[0];
- var b01 = b0[1];
- var b02 = b0[2];
- var b03 = b0[3];
- var b10 = b1[0];
- var b11 = b1[1];
- var b12 = b1[2];
- var b13 = b1[3];
- var b20 = b2[0];
- var b21 = b2[1];
- var b22 = b2[2];
- var b23 = b2[3];
- var b30 = b3[0];
- var b31 = b3[1];
- var b32 = b3[2];
- var b33 = b3[3];
- return [[a00 * b00 + a10 * b01 + a20 * b02 + a30 * b03,
- a01 * b00 + a11 * b01 + a21 * b02 + a31 * b03,
- a02 * b00 + a12 * b01 + a22 * b02 + a32 * b03,
- a03 * b00 + a13 * b01 + a23 * b02 + a33 * b03],
- [a00 * b10 + a10 * b11 + a20 * b12 + a30 * b13,
- a01 * b10 + a11 * b11 + a21 * b12 + a31 * b13,
- a02 * b10 + a12 * b11 + a22 * b12 + a32 * b13,
- a03 * b10 + a13 * b11 + a23 * b12 + a33 * b13],
- [a00 * b20 + a10 * b21 + a20 * b22 + a30 * b23,
- a01 * b20 + a11 * b21 + a21 * b22 + a31 * b23,
- a02 * b20 + a12 * b21 + a22 * b22 + a32 * b23,
- a03 * b20 + a13 * b21 + a23 * b22 + a33 * b23],
- [a00 * b30 + a10 * b31 + a20 * b32 + a30 * b33,
- a01 * b30 + a11 * b31 + a21 * b32 + a31 * b33,
- a02 * b30 + a12 * b31 + a22 * b32 + a32 * b33,
- a03 * b30 + a13 * b31 + a23 * b32 + a33 * b33]];
-};
-
-/**
- * Takes two 4-by-4 matrices, a and b, and modifies a to be the product in the
- * order that pre-composes b with a. The matrix a, upon modification will
- * transform by b first and then a. Note this is subtly different from just
- * multiplying the matrices together. For given a and b, a, upon modification,
- * will be the same object in both row-major and column-major mode.
- * @param {!o3djs.math.Matrix4} a A 4-by-4 matrix.
- * @param {!o3djs.math.Matrix4} b A 4-by-4 matrix.
- * @return {!o3djs.math.Matrix4} a once modified.
- */
-o3djs.math.matrix4.compose = function(a, b) {
- var a0 = a[0];
- var a1 = a[1];
- var a2 = a[2];
- var a3 = a[3];
- var b0 = b[0];
- var b1 = b[1];
- var b2 = b[2];
- var b3 = b[3];
- var a00 = a0[0];
- var a01 = a0[1];
- var a02 = a0[2];
- var a03 = a0[3];
- var a10 = a1[0];
- var a11 = a1[1];
- var a12 = a1[2];
- var a13 = a1[3];
- var a20 = a2[0];
- var a21 = a2[1];
- var a22 = a2[2];
- var a23 = a2[3];
- var a30 = a3[0];
- var a31 = a3[1];
- var a32 = a3[2];
- var a33 = a3[3];
- var b00 = b0[0];
- var b01 = b0[1];
- var b02 = b0[2];
- var b03 = b0[3];
- var b10 = b1[0];
- var b11 = b1[1];
- var b12 = b1[2];
- var b13 = b1[3];
- var b20 = b2[0];
- var b21 = b2[1];
- var b22 = b2[2];
- var b23 = b2[3];
- var b30 = b3[0];
- var b31 = b3[1];
- var b32 = b3[2];
- var b33 = b3[3];
- a[0].splice(0, 4, a00 * b00 + a10 * b01 + a20 * b02 + a30 * b03,
- a01 * b00 + a11 * b01 + a21 * b02 + a31 * b03,
- a02 * b00 + a12 * b01 + a22 * b02 + a32 * b03,
- a03 * b00 + a13 * b01 + a23 * b02 + a33 * b03);
- a[1].splice(0, 4, a00 * b10 + a10 * b11 + a20 * b12 + a30 * b13,
- a01 * b10 + a11 * b11 + a21 * b12 + a31 * b13,
- a02 * b10 + a12 * b11 + a22 * b12 + a32 * b13,
- a03 * b10 + a13 * b11 + a23 * b12 + a33 * b13);
- a[2].splice(0, 4, a00 * b20 + a10 * b21 + a20 * b22 + a30 * b23,
- a01 * b20 + a11 * b21 + a21 * b22 + a31 * b23,
- a02 * b20 + a12 * b21 + a22 * b22 + a32 * b23,
- a03 * b20 + a13 * b21 + a23 * b22 + a33 * b23),
- a[3].splice(0, 4, a00 * b30 + a10 * b31 + a20 * b32 + a30 * b33,
- a01 * b30 + a11 * b31 + a21 * b32 + a31 * b33,
- a02 * b30 + a12 * b31 + a22 * b32 + a32 * b33,
- a03 * b30 + a13 * b31 + a23 * b32 + a33 * b33);
- return a;
-};
-
-/**
- * Creates a 4-by-4 matrix which translates by the given vector v.
- * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} v The vector by
- * which to translate.
- * @return {!o3djs.math.Matrix4} The translation matrix.
- */
-o3djs.math.matrix4.translation = function(v) {
- return [
- [1, 0, 0, 0],
- [0, 1, 0, 0],
- [0, 0, 1, 0],
- [v[0], v[1], v[2], 1]
- ];
-};
-
-/**
- * Modifies the given 4-by-4 matrix by translation by the given vector v.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} v The vector by
- * which to translate.
- * @return {!o3djs.math.Matrix4} m once modified.
- */
-o3djs.math.matrix4.translate = function(m, v) {
- var v0 = v[0];
- var v1 = v[1];
- var v2 = v[2];
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
- var m00 = m0[0];
- var m01 = m0[1];
- var m02 = m0[2];
- var m03 = m0[3];
- var m10 = m1[0];
- var m11 = m1[1];
- var m12 = m1[2];
- var m13 = m1[3];
- var m20 = m2[0];
- var m21 = m2[1];
- var m22 = m2[2];
- var m23 = m2[3];
- var m30 = m3[0];
- var m31 = m3[1];
- var m32 = m3[2];
- var m33 = m3[3];
-
- m3.splice(0, 4, m00 * v0 + m10 * v1 + m20 * v2 + m30,
- m01 * v0 + m11 * v1 + m21 * v2 + m31,
- m02 * v0 + m12 * v1 + m22 * v2 + m32,
- m03 * v0 + m13 * v1 + m23 * v2 + m33);
-
- return m;
-};
-
-/**
- * Creates a 4-by-4 matrix which scales in each dimension by an amount given by
- * the corresponding entry in the given vector; assumes the vector has three
- * entries.
- * @param {!o3djs.math.Vector3} v A vector of
- * three entries specifying the factor by which to scale in each dimension.
- * @return {!o3djs.math.Matrix4} The scaling matrix.
- */
-o3djs.math.matrix4.scaling = function(v) {
- return [
- [v[0], 0, 0, 0],
- [0, v[1], 0, 0],
- [0, 0, v[2], 0],
- [0, 0, 0, 1]
- ];
-};
-
-/**
- * Modifies the given 4-by-4 matrix, scaling in each dimension by an amount
- * given by the corresponding entry in the given vector; assumes the vector has
- * three entries.
- * @param {!o3djs.math.Matrix4} m The matrix to be modified.
- * @param {!o3djs.math.Vector3} v A vector of three entries specifying the
- * factor by which to scale in each dimension.
- * @return {!o3djs.math.Matrix4} m once modified.
- */
-o3djs.math.matrix4.scale = function(m, v) {
- var v0 = v[0];
- var v1 = v[1];
- var v2 = v[2];
-
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
-
- m0.splice(0, 4, v0 * m0[0], v0 * m0[1], v0 * m0[2], v0 * m0[3]);
- m1.splice(0, 4, v1 * m1[0], v1 * m1[1], v1 * m1[2], v1 * m1[3]);
- m2.splice(0, 4, v2 * m2[0], v2 * m2[1], v2 * m2[2], v2 * m2[3]);
-
- return m;
-};
-
-/**
- * Creates a 4-by-4 matrix which rotates around the x-axis by the given angle.
- * @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.math.Matrix4} The rotation matrix.
- */
-o3djs.math.matrix4.rotationX = function(angle) {
- var c = Math.cos(angle);
- var s = Math.sin(angle);
-
- return [
- [1, 0, 0, 0],
- [0, c, s, 0],
- [0, -s, c, 0],
- [0, 0, 0, 1]
- ];
-};
-
-/**
- * Modifies the given 4-by-4 matrix by a rotation around the x-axis by the given
- * angle.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.math.Matrix4} m once modified.
- */
-o3djs.math.matrix4.rotateX = function(m, angle) {
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
- var m10 = m1[0];
- var m11 = m1[1];
- var m12 = m1[2];
- var m13 = m1[3];
- var m20 = m2[0];
- var m21 = m2[1];
- var m22 = m2[2];
- var m23 = m2[3];
- var c = Math.cos(angle);
- var s = Math.sin(angle);
-
- m1.splice(0, 4, c * m10 + s * m20,
- c * m11 + s * m21,
- c * m12 + s * m22,
- c * m13 + s * m23);
- m2.splice(0, 4, c * m20 - s * m10,
- c * m21 - s * m11,
- c * m22 - s * m12,
- c * m23 - s * m13);
-
- return m;
-};
-
-/**
- * Creates a 4-by-4 matrix which rotates around the y-axis by the given angle.
- * @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.math.Matrix4} The rotation matrix.
- */
-o3djs.math.matrix4.rotationY = function(angle) {
- var c = Math.cos(angle);
- var s = Math.sin(angle);
-
- return [
- [c, 0, -s, 0],
- [0, 1, 0, 0],
- [s, 0, c, 0],
- [0, 0, 0, 1]
- ];
-};
-
-/**
- * Modifies the given 4-by-4 matrix by a rotation around the y-axis by the given
- * angle.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.math.Matrix4} m once modified.
- */
-o3djs.math.matrix4.rotateY = function(m, angle) {
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
- var m00 = m0[0];
- var m01 = m0[1];
- var m02 = m0[2];
- var m03 = m0[3];
- var m20 = m2[0];
- var m21 = m2[1];
- var m22 = m2[2];
- var m23 = m2[3];
- var c = Math.cos(angle);
- var s = Math.sin(angle);
-
- m0.splice(0, 4, c * m00 - s * m20,
- c * m01 - s * m21,
- c * m02 - s * m22,
- c * m03 - s * m23);
- m2.splice(0, 4, c * m20 + s * m00,
- c * m21 + s * m01,
- c * m22 + s * m02,
- c * m23 + s * m03);
-
- return m;
-};
-
-/**
- * Creates a 4-by-4 matrix which rotates around the z-axis by the given angle.
- * @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.math.Matrix4} The rotation matrix.
- */
-o3djs.math.matrix4.rotationZ = function(angle) {
- var c = Math.cos(angle);
- var s = Math.sin(angle);
-
- return [
- [c, s, 0, 0],
- [-s, c, 0, 0],
- [0, 0, 1, 0],
- [0, 0, 0, 1]
- ];
-};
-
-/**
- * Modifies the given 4-by-4 matrix by a rotation around the z-axis by the given
- * angle.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.math.Matrix4} m once modified.
- */
-o3djs.math.matrix4.rotateZ = function(m, angle) {
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
- var m00 = m0[0];
- var m01 = m0[1];
- var m02 = m0[2];
- var m03 = m0[3];
- var m10 = m1[0];
- var m11 = m1[1];
- var m12 = m1[2];
- var m13 = m1[3];
- var c = Math.cos(angle);
- var s = Math.sin(angle);
-
- m0.splice(0, 4, c * m00 + s * m10,
- c * m01 + s * m11,
- c * m02 + s * m12,
- c * m03 + s * m13);
- m1.splice(0, 4, c * m10 - s * m00,
- c * m11 - s * m01,
- c * m12 - s * m02,
- c * m13 - s * m03);
-
- return m;
-};
-
-/**
- * Creates a 4-by-4 rotation matrix. Interprets the entries of the given
- * vector as angles by which to rotate around the x, y and z axes, returns a
- * a matrix which rotates around the x-axis first, then the y-axis, then the
- * z-axis.
- * @param {!o3djs.math.Vector3} v A vector of angles (in radians).
- * @return {!o3djs.math.Matrix4} The rotation matrix.
- */
-o3djs.math.matrix4.rotationZYX = function(v) {
- var sinx = Math.sin(v[0]);
- var cosx = Math.cos(v[0]);
- var siny = Math.sin(v[1]);
- var cosy = Math.cos(v[1]);
- var sinz = Math.sin(v[2]);
- var cosz = Math.cos(v[2]);
-
- var coszsiny = cosz * siny;
- var sinzsiny = sinz * siny;
-
- return [
- [cosz * cosy, sinz * cosy, -siny, 0],
- [coszsiny * sinx - sinz * cosx,
- sinzsiny * sinx + cosz * cosx,
- cosy * sinx,
- 0],
- [coszsiny * cosx + sinz * sinx,
- sinzsiny * cosx - cosz * sinx,
- cosy * cosx,
- 0],
- [0, 0, 0, 1]
- ];
-};
-
-/**
- * Modifies a 4-by-4 matrix by a rotation. Interprets the coordinates of the
- * given vector as angles by which to rotate around the x, y and z axes, rotates
- * around the x-axis first, then the y-axis, then the z-axis.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @param {!o3djs.math.Vector3} v A vector of angles (in radians).
- * @return {!o3djs.math.Matrix4} m once modified.
- */
-o3djs.math.matrix4.rotateZYX = function(m, v) {
- var sinX = Math.sin(v[0]);
- var cosX = Math.cos(v[0]);
- var sinY = Math.sin(v[1]);
- var cosY = Math.cos(v[1]);
- var sinZ = Math.sin(v[2]);
- var cosZ = Math.cos(v[2]);
-
- var cosZSinY = cosZ * sinY;
- var sinZSinY = sinZ * sinY;
-
- var r00 = cosZ * cosY;
- var r01 = sinZ * cosY;
- var r02 = -sinY;
- var r10 = cosZSinY * sinX - sinZ * cosX;
- var r11 = sinZSinY * sinX + cosZ * cosX;
- var r12 = cosY * sinX;
- var r20 = cosZSinY * cosX + sinZ * sinX;
- var r21 = sinZSinY * cosX - cosZ * sinX;
- var r22 = cosY * cosX;
-
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
-
- var m00 = m0[0];
- var m01 = m0[1];
- var m02 = m0[2];
- var m03 = m0[3];
- var m10 = m1[0];
- var m11 = m1[1];
- var m12 = m1[2];
- var m13 = m1[3];
- var m20 = m2[0];
- var m21 = m2[1];
- var m22 = m2[2];
- var m23 = m2[3];
- var m30 = m3[0];
- var m31 = m3[1];
- var m32 = m3[2];
- var m33 = m3[3];
-
- m0.splice(0, 4,
- r00 * m00 + r01 * m10 + r02 * m20,
- r00 * m01 + r01 * m11 + r02 * m21,
- r00 * m02 + r01 * m12 + r02 * m22,
- r00 * m03 + r01 * m13 + r02 * m23);
-
- m1.splice(0, 4,
- r10 * m00 + r11 * m10 + r12 * m20,
- r10 * m01 + r11 * m11 + r12 * m21,
- r10 * m02 + r11 * m12 + r12 * m22,
- r10 * m03 + r11 * m13 + r12 * m23);
-
- m2.splice(0, 4,
- r20 * m00 + r21 * m10 + r22 * m20,
- r20 * m01 + r21 * m11 + r22 * m21,
- r20 * m02 + r21 * m12 + r22 * m22,
- r20 * m03 + r21 * m13 + r22 * m23);
-
- return m;
-};
-
-/**
- * Creates a 4-by-4 matrix which rotates around the given axis by the given
- * angle.
- * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} axis The axis
- * about which to rotate.
- * @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.math.Matrix4} A matrix which rotates angle radians
- * around the axis.
- */
-o3djs.math.matrix4.axisRotation = function(axis, angle) {
- var x = axis[0];
- var y = axis[1];
- var z = axis[2];
- var n = Math.sqrt(x * x + y * y + z * z);
- x /= n;
- y /= n;
- z /= n;
- var xx = x * x;
- var yy = y * y;
- var zz = z * z;
- var c = Math.cos(angle);
- var s = Math.sin(angle);
- var oneMinusCosine = 1 - c;
-
- return [
- [xx + (1 - xx) * c,
- x * y * oneMinusCosine + z * s,
- x * z * oneMinusCosine - y * s,
- 0],
- [x * y * oneMinusCosine - z * s,
- yy + (1 - yy) * c,
- y * z * oneMinusCosine + x * s,
- 0],
- [x * z * oneMinusCosine + y * s,
- y * z * oneMinusCosine - x * s,
- zz + (1 - zz) * c,
- 0],
- [0, 0, 0, 1]
- ];
-};
-
-/**
- * Modifies the given 4-by-4 matrix by rotation around the given axis by the
- * given angle.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} axis The axis
- * about which to rotate.
- * @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.math.Matrix4} m once modified.
- */
-o3djs.math.matrix4.axisRotate = function(m, axis, angle) {
- var x = axis[0];
- var y = axis[1];
- var z = axis[2];
- var n = Math.sqrt(x * x + y * y + z * z);
- x /= n;
- y /= n;
- z /= n;
- var xx = x * x;
- var yy = y * y;
- var zz = z * z;
- var c = Math.cos(angle);
- var s = Math.sin(angle);
- var oneMinusCosine = 1 - c;
-
- var r00 = xx + (1 - xx) * c;
- var r01 = x * y * oneMinusCosine + z * s;
- var r02 = x * z * oneMinusCosine - y * s;
- var r10 = x * y * oneMinusCosine - z * s;
- var r11 = yy + (1 - yy) * c;
- var r12 = y * z * oneMinusCosine + x * s;
- var r20 = x * z * oneMinusCosine + y * s;
- var r21 = y * z * oneMinusCosine - x * s;
- var r22 = zz + (1 - zz) * c;
-
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
-
- var m00 = m0[0];
- var m01 = m0[1];
- var m02 = m0[2];
- var m03 = m0[3];
- var m10 = m1[0];
- var m11 = m1[1];
- var m12 = m1[2];
- var m13 = m1[3];
- var m20 = m2[0];
- var m21 = m2[1];
- var m22 = m2[2];
- var m23 = m2[3];
- var m30 = m3[0];
- var m31 = m3[1];
- var m32 = m3[2];
- var m33 = m3[3];
-
- m0.splice(0, 4,
- r00 * m00 + r01 * m10 + r02 * m20,
- r00 * m01 + r01 * m11 + r02 * m21,
- r00 * m02 + r01 * m12 + r02 * m22,
- r00 * m03 + r01 * m13 + r02 * m23);
-
- m1.splice(0, 4,
- r10 * m00 + r11 * m10 + r12 * m20,
- r10 * m01 + r11 * m11 + r12 * m21,
- r10 * m02 + r11 * m12 + r12 * m22,
- r10 * m03 + r11 * m13 + r12 * m23);
-
- m2.splice(0, 4,
- r20 * m00 + r21 * m10 + r22 * m20,
- r20 * m01 + r21 * m11 + r22 * m21,
- r20 * m02 + r21 * m12 + r22 * m22,
- r20 * m03 + r21 * m13 + r22 * m23);
-
- return m;
-};
-
-/**
- * Sets each function in the namespace o3djs.math to the row major
- * version in o3djs.math.rowMajor (provided such a function exists in
- * o3djs.math.rowMajor). Call this function to establish the row major
- * convention.
- */
-o3djs.math.installRowMajorFunctions = function() {
- for (var f in o3djs.math.rowMajor) {
- o3djs.math[f] = o3djs.math.rowMajor[f];
- }
-};
-
-/**
- * Sets each function in the namespace o3djs.math to the column major
- * version in o3djs.math.columnMajor (provided such a function exists in
- * o3djs.math.columnMajor). Call this function to establish the column
- * major convention.
- */
-o3djs.math.installColumnMajorFunctions = function() {
- for (var f in o3djs.math.columnMajor) {
- o3djs.math[f] = o3djs.math.columnMajor[f];
- }
-};
-
-/**
- * Sets each function in the namespace o3djs.math to the error checking
- * version in o3djs.math.errorCheck (provided such a function exists in
- * o3djs.math.errorCheck).
- */
-o3djs.math.installErrorCheckFunctions = function() {
- for (var f in o3djs.math.errorCheck) {
- o3djs.math[f] = o3djs.math.errorCheck[f];
- }
-};
-
-/**
- * Sets each function in the namespace o3djs.math to the error checking free
- * version in o3djs.math.errorCheckFree (provided such a function exists in
- * o3djs.math.errorCheckFree).
- */
-o3djs.math.installErrorCheckFreeFunctions = function() {
- for (var f in o3djs.math.errorCheckFree) {
- o3djs.math[f] = o3djs.math.errorCheckFree[f];
- }
-}
-
-// By default, install the row-major functions.
-o3djs.math.installRowMajorFunctions();
-
-// By default, install prechecking.
-o3djs.math.installErrorCheckFunctions();
-
-
-/**
- * True if we are using the plugin math library in which matrices are
- * represented by 2-dimensional arrays.
- * @type {boolean}
- * @private
- */
-o3djs.math.usePluginMath_ = true;
diff --git a/o3d/samples/o3djs/primitives.js b/o3d/samples/o3djs/primitives.js
deleted file mode 100644
index 34d058d..0000000
--- a/o3d/samples/o3djs/primitives.js
+++ /dev/null
@@ -1,2016 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains functions to create geometric primitives for
- * o3d. It puts them in the "primitives" module on the o3djs object.
- *
- * For more information about o3d see http://code.google.com/p/o3d
- *
- *
- * Requires base.js
- */
-
-o3djs.provide('o3djs.primitives');
-
-o3djs.require('o3djs.math');
-
-/**
- * A Module for creating primitives.
- * @namespace
- */
-o3djs.primitives = o3djs.primitives || {};
-
-
-/**
- * Sets the bounding box and zSortPoint for a primitive based on its vertices
- *
- * @param {!o3d.Primitive} primitive Primitive to set culling info for.
- */
-o3djs.primitives.setCullingInfo = function(primitive) {
- var box = primitive.getBoundingBox(0);
- primitive.boundingBox = box;
- var minExtent = box.minExtent;
- var maxExtent = box.maxExtent;
- primitive.zSortPoint = o3djs.math.divVectorScalar(
- o3djs.math.addVector(minExtent, maxExtent), 2);
-};
-
-/**
- * Used to store the elements of a stream.
- * @param {number} numComponents The number of numerical components per
- * element.
- * @param {!o3d.Stream.Semantic} semantic The semantic of the stream.
- * @param {number} opt_semanticIndex The semantic index of the stream.
- * Defaults to zero.
- * @constructor
- */
-o3djs.primitives.VertexStreamInfo = function(numComponents,
- semantic,
- opt_semanticIndex) {
- /**
- * The number of numerical components per element.
- * @type {number}
- */
- this.numComponents = numComponents;
-
- /**
- * The semantic of the stream.
- * @type {!o3d.Stream.Semantic}
- */
- this.semantic = semantic;
-
- /**
- * The semantic index of the stream.
- * @type {number}
- */
- this.semanticIndex = opt_semanticIndex || 0;
-
- /**
- * The elements of the stream.
- * @type {!Array.<number>}
- */
- this.elements = [];
-
- /**
- * Adds an element to this VertexStreamInfo. The number of values passed must
- * match the number of components for this VertexStreamInfo.
- * @param {number} value1 First value.
- * @param {number} opt_value2 Second value.
- * @param {number} opt_value3 Third value.
- * @param {number} opt_value4 Fourth value.
- */
- this.addElement = function(value1, opt_value2, opt_value3, opt_value4) { };
-
- /**
- * Sets an element on this VertexStreamInfo. The number of values passed must
- * match the number of components for this VertexStreamInfo.
- * @param {number} index Index of element to set.
- * @param {number} value1 First value.
- * @param {number} opt_value2 Second value.
- * @param {number} opt_value3 Third value.
- * @param {number} opt_value4 Fourth value.
- */
- this.setElement = function(
- index, value1, opt_value2, opt_value3, opt_value4) { };
-
- /**
- * Adds an element to this VertexStreamInfo. The number of values in the
- * vector must match the number of components for this VertexStreamInfo.
- * @param {!Array.<number>} vector Array of values for element.
- */
- this.addElementVector = function(vector) { }; // replaced below.
-
- /**
- * Sets an element on this VertexStreamInfo. The number of values in the
- * vector must match the number of components for this VertexStreamInfo.
- * @param {number} index Index of element to set.
- * @param {!Array.<number>} vector Array of values for element.
- */
- this.setElementVector = function(index, vector) { }; // replaced below.
-
- /**
- * Sets an element on this VertexStreamInfo. The number of values in the
- * vector will match the number of components for this VertexStreamInfo.
- * @param {number} index Index of element to set.
- * @return {!Array.<number>} Array of values for element.
- */
- this.getElementVector = function(index) { return []; }; // replaced below.
-
- switch (numComponents) {
- case 1:
- this.addElement = function(value) {
- this.elements.push(value);
- }
- this.getElement = function(index) {
- return this.elements[index];
- }
- this.setElement = function(index, value) {
- this.elements[index] = value;
- }
- break;
- case 2:
- this.addElement = function(value0, value1) {
- this.elements.push(value0, value1);
- }
- this.addElementVector = function(vector) {
- this.elements.push(vector[0], vector[1]);
- }
- this.getElementVector = function(index) {
- return this.elements.slice(index * numComponents,
- (index + 1) * numComponents);
- }
- this.setElement = function(index, value0, value1) {
- this.elements[index * numComponents + 0] = value0;
- this.elements[index * numComponents + 1] = value1;
- }
- this.setElementVector = function(index, vector) {
- this.elements[index * numComponents + 0] = vector[0];
- this.elements[index * numComponents + 1] = vector[1];
- }
- break;
- case 3:
- this.addElement = function(value0, value1, value2) {
- this.elements.push(value0, value1, value2);
- }
- this.addElementVector = function(vector) {
- this.elements.push(vector[0], vector[1], vector[2]);
- }
- this.getElementVector = function(index) {
- return this.elements.slice(index * numComponents,
- (index + 1) * numComponents);
- }
- this.setElement = function(index, value0, value1, value2) {
- this.elements[index * numComponents + 0] = value0;
- this.elements[index * numComponents + 1] = value1;
- this.elements[index * numComponents + 2] = value2;
- }
- this.setElementVector = function(index, vector) {
- this.elements[index * numComponents + 0] = vector[0];
- this.elements[index * numComponents + 1] = vector[1];
- this.elements[index * numComponents + 2] = vector[2];
- }
- break;
- case 4:
- this.addElement = function(value0, value1, value2, value3) {
- this.elements.push(value0, value1, value2, value3);
- }
- this.addElementVector = function(vector) {
- this.elements.push(vector[0], vector[1], vector[2], vector[3]);
- }
- this.getElementVector = function(index) {
- return this.elements.slice(index * numComponents,
- (index + 1) * numComponents);
- }
- this.setElement = function(index, value0, value1, value2, value3) {
- this.elements[index * numComponents + 0] = value0;
- this.elements[index * numComponents + 1] = value1;
- this.elements[index * numComponents + 2] = value2;
- this.elements[index * numComponents + 3] = value3;
- }
- this.setElementVector = function(index, vector) {
- this.elements[index * numComponents + 0] = vector[0];
- this.elements[index * numComponents + 1] = vector[1];
- this.elements[index * numComponents + 2] = vector[2];
- this.elements[index * numComponents + 3] = vector[3];
- }
- break;
- default:
- throw 'A stream must contain between 1 and 4 components';
- }
-};
-
-/**
- * Get the number of elements in the stream.
- * @return {number} The number of elements in the stream.
- */
-o3djs.primitives.VertexStreamInfo.prototype.numElements = function() {
- return this.elements.length / this.numComponents;
-};
-
-/**
- * Create a VertexStreamInfo.
- * @param {number} numComponents The number of numerical components per
- * element.
- * @param {!o3d.Stream.Semantic} semantic The semantic of the stream.
- * @param {number} opt_semanticIndex The semantic index of the stream.
- * Defaults to zero.
- * @return {!o3djs.primitives.VertexStreamInfo} The new stream.
- */
-o3djs.primitives.createVertexStreamInfo = function(numComponents,
- semantic,
- opt_semanticIndex) {
- return new o3djs.primitives.VertexStreamInfo(numComponents,
- semantic,
- opt_semanticIndex);
-};
-
-/**
- * VertexInfoBase. Used to store vertices and indices.
- * @constructor
- */
-o3djs.primitives.VertexInfoBase = function() {
- this.streams = [];
- this.indices = [];
-};
-
-/**
- * Add a new stream to the VertexInfo, replacing it with a new empty one
- * if it already exists.
- * @param {number} numComponents The number of components per vector.
- * @param {!o3d.Stream.Semantic} semantic The semantic of the stream.
- * @param {number} opt_semanticIndex The semantic index of the stream.
- * Defaults to zero.
- * @return {!o3djs.primitives.VertexStreamInfo} The new stream.
- */
-o3djs.primitives.VertexInfoBase.prototype.addStream = function(
- numComponents,
- semantic,
- opt_semanticIndex) {
- this.removeStream(semantic, opt_semanticIndex);
- var stream = o3djs.primitives.createVertexStreamInfo(
- numComponents,
- semantic,
- opt_semanticIndex);
- this.streams.push(stream);
- return stream;
-};
-
-/**
- * Find a stream in the VertexInfo.
- * @param {!o3d.Stream.Semantic} semantic The semantic of the stream.
- * @param {number} opt_semanticIndex The semantic index of the stream.
- * Defaults to zero.
- * @return {o3djs.primitives.VertexStreamInfo} The stream or null if it
- * is not present.
- */
-o3djs.primitives.VertexInfoBase.prototype.findStream = function(
- semantic,
- opt_semanticIndex) {
- opt_semanticIndex = opt_semanticIndex || 0;
- for (var i = 0; i < this.streams.length; ++i) {
- if (this.streams[i].semantic === semantic &&
- this.streams[i].semanticIndex == opt_semanticIndex) {
- return this.streams[i];
- }
- }
- return null;
-};
-
-/**
- * Remove a stream from the VertexInfo. Does nothing if a matching stream
- * does not exist.
- * @param {!o3d.Stream.Semantic} semantic The semantic of the stream.
- * @param {number} opt_semanticIndex The semantic index of the stream.
- * Defaults to zero.
- */
-o3djs.primitives.VertexInfoBase.prototype.removeStream = function(
- semantic,
- opt_semanticIndex) {
- opt_semanticIndex = opt_semanticIndex || 0;
- for (var i = 0; i < this.streams.length; ++i) {
- if (this.streams[i].semantic === semantic &&
- this.streams[i].semanticIndex == opt_semanticIndex) {
- this.streams.splice(i, 1);
- return;
- }
- }
-};
-
-/**
- * Appends all of the information in the passed VertexInfo on to the
- * end of this one. This is useful for putting multiple primitives'
- * vertices, appropriately transformed, into a single Shape. Both
- * VertexInfo objects must contain the same number of streams, with
- * the same semantics and number of components.
- * @param {!o3djs.primitives.VertexInfoBase} info The VertexInfo whose
- * information should be appended to this one.
- */
-o3djs.primitives.VertexInfoBase.prototype.append = function(info) {
- if (this.streams.length == 0 && info.streams.length != 0) {
- // Special case
- for (var i = 0; i < info.streams.length; i++) {
- var srcStream = info.streams[i];
- var stream = this.addStream(srcStream.numComponents,
- srcStream.semantic,
- srcStream.semanticIndex);
- stream.elements = stream.elements.concat(srcStream.elements);
- }
- this.indices = this.indices.concat(info.indices);
- return;
- }
-
- // First verify that both have the same streams
- if (this.streams.length != info.streams.length) {
- throw 'Number of VertexInfoStreams did not match';
- }
- for (var i = 0; i < this.streams.length; i++) {
- var found = false;
- var semantic = this.streams[i].semantic;
- var numComponents = this.streams[i].numComponents;
- var semanticIndex = this.streams[i].semanticIndex;
- for (var j = 0; j < info.streams.length; j++) {
- var otherStream = info.streams[j];
- if (otherStream.semantic === semantic &&
- otherStream.numComponents == numComponents &&
- otherStream.semanticIndex == semanticIndex) {
- found = true;
- break;
- }
- }
- if (!found) {
- throw 'Did not find stream with semantic=' + semantic +
- ', numComponents=' + numComponents +
- ', and semantic index=' + semanticIndex +
- ' in given VertexInfo';
- }
- }
-
- // Compute the number of vertices currently in the shape
- var positionStream = this.findStream(o3djs.base.o3d.Stream.POSITION);
- if (!positionStream)
- throw 'POSITION stream is missing';
- var numVertices = positionStream.numElements();
-
- // Concatenate all VertexStreamInfos' data
- for (var i = 0; i < this.streams.length; i++) {
- var stream = this.streams[i];
- var srcStream = info.findStream(stream.semantic, stream.semanticIndex);
- stream.elements = stream.elements.concat(srcStream.elements);
- }
-
- // Concatenate and adjust indices
- for (var i = 0; i < info.indices.length; i++) {
- this.indices.push(info.indices[i] + numVertices);
- }
-};
-
-/**
- * Validates that all the streams contain the same number of elements, that
- * all the indices are within range and that a position stream is present.
- */
-o3djs.primitives.VertexInfoBase.prototype.validate = function() {
- // Check the position stream is present.
- var positionStream = this.findStream(o3djs.base.o3d.Stream.POSITION);
- if (!positionStream)
- throw 'POSITION stream is missing';
-
- // Check all the streams have the same number of elements.
- var numElements = positionStream.numElements();
- for (var s = 0; s < this.streams.length; ++s) {
- if (this.streams[s].numElements() !== numElements) {
- throw 'Stream ' + s + ' contains ' + this.streams[s].numElements() +
- ' elements whereas the POSITION stream contains ' + numElements;
- }
- }
-
- // Check all the indices are in range.
- for (var i = 0; i < this.indices.length; ++i) {
- if (this.indices[i] < 0 || this.indices[i] >= numElements) {
- throw 'The index ' + this.indices[i] + ' is out of range [0, ' +
- numElements + ']';
- }
- }
-};
-
-/**
- * Reorients the vertices, positions and normals, of this vertexInfo by the
- * given matrix. In other words, it multiplies each vertex by the given matrix
- * and each normal by the inverse-transpose of the given matrix.
- * @param {!o3djs.math.Matrix4} matrix Matrix by which to multiply.
- */
-o3djs.primitives.VertexInfoBase.prototype.reorient = function(matrix) {
- var math = o3djs.math;
- var matrixInverse = math.inverse(math.matrix4.getUpper3x3(matrix));
-
- for (var s = 0; s < this.streams.length; ++s) {
- var stream = this.streams[s];
- if (stream.numComponents == 3) {
- var numElements = stream.numElements();
- switch (stream.semantic) {
- case o3djs.base.o3d.Stream.POSITION:
- for (var i = 0; i < numElements; ++i) {
- stream.setElementVector(i,
- math.matrix4.transformPoint(matrix,
- stream.getElementVector(i)));
- }
- break;
- case o3djs.base.o3d.Stream.NORMAL:
- for (var i = 0; i < numElements; ++i) {
- stream.setElementVector(i,
- math.matrix4.transformNormal(matrix,
- stream.getElementVector(i)));
- }
- break;
- case o3djs.base.o3d.Stream.TANGENT:
- case o3djs.base.o3d.Stream.BINORMAL:
- for (var i = 0; i < numElements; ++i) {
- stream.setElementVector(i,
- math.matrix4.transformDirection(matrix,
- stream.getElementVector(i)));
- }
- break;
- }
- }
- }
-};
-
-/**
- * Creates a shape from a VertexInfoBase
- * @param {!o3d.Pack} pack Pack to create objects in.
- * @param {!o3d.Material} material to use.
- * @param {!o3d.Primitive.PrimitiveType} primitiveType The type of primitive.
- * @return {!o3d.Shape} The created shape.
- */
-o3djs.primitives.VertexInfoBase.prototype.createShapeByType = function(
- pack,
- material,
- primitiveType) {
- this.validate();
-
- var numIndices = this.indices.length;
- var numPrimitives;
- switch (primitiveType) {
- case o3djs.base.o3d.Primitive.POINTLIST:
- numPrimitives = numIndices / 1;
- break;
- case o3djs.base.o3d.Primitive.LINELIST:
- numPrimitives = numIndices / 2;
- break;
- case o3djs.base.o3d.Primitive.LINESTRIP:
- numPrimitives = numIndices - 1;
- break;
- case o3djs.base.o3d.Primitive.TRIANGLELIST:
- numPrimitives = numIndices / 3;
- break;
- case o3djs.base.o3d.Primitive.TRIANGLESTRIP:
- case o3djs.base.o3d.Primitive.TRIANGLEFAN:
- numPrimitives = numIndices - 2;
- break;
- default:
- throw 'unknown primitive type';
- }
-
- var positionStream = this.findStream(o3djs.base.o3d.Stream.POSITION);
- var numVertices = positionStream.numElements();
-
- // create a shape and primitive for the vertices.
- var shape = pack.createObject('Shape');
- var primitive = pack.createObject('Primitive');
- var streamBank = pack.createObject('StreamBank');
- primitive.owner = shape;
- primitive.streamBank = streamBank;
- primitive.material = material;
- primitive.numberPrimitives = numPrimitives;
- primitive.primitiveType = primitiveType;
- primitive.numberVertices = numVertices;
- primitive.createDrawElement(pack, null);
-
- // Calculate the tangent and binormal or provide defaults or fail if the
- // effect requires either and they are not present.
- var streamInfos = material.effect.getStreamInfo();
- for (var s = 0; s < streamInfos.length; ++s) {
- var semantic = streamInfos[s].semantic;
- var semanticIndex = streamInfos[s].semanticIndex;
-
- var requiredStream = this.findStream(semantic, semanticIndex);
- if (!requiredStream) {
- switch (semantic) {
- case o3djs.base.o3d.Stream.TANGENT:
- case o3djs.base.o3d.Stream.BINORMAL:
- if (primitiveType == o3djs.base.o3d.Primitive.TRIANGLELIST) {
- this.addTangentStreams(semanticIndex);
- } else {
- throw 'Can not create tangents and binormals for primitive type' +
- primitiveType;
- }
- break;
- case o3djs.base.o3d.Stream.COLOR:
- requiredStream = this.addStream(4, semantic, semanticIndex);
- for (var i = 0; i < numVertices; ++i) {
- requiredStream.addElement(1, 1, 1, 1);
- }
- break;
- case o3djs.base.o3d.Stream.INFLUENCE_WEIGHTS:
- case o3djs.base.o3d.Stream.INFLUENCE_INDICES:
- break;
- default:
- throw 'Missing stream for semantic ' + semantic +
- ' with semantic index ' + semanticIndex;
- }
- }
- }
-
- // These next few lines take our javascript streams and load them into a
- // 'buffer' where the 3D hardware can find them. We have to do this
- // because the 3D hardware can't 'see' javascript data until we copy it to
- // a buffer.
- var vertexBuffer = pack.createObject('VertexBuffer');
- var fields = [];
- for (var s = 0; s < this.streams.length; ++s) {
- var stream = this.streams[s];
- var fieldType = (stream.semantic == o3djs.base.o3d.Stream.COLOR &&
- stream.numComponents == 4) ? 'UByteNField' : 'FloatField';
- fields[s] = vertexBuffer.createField(fieldType, stream.numComponents);
- streamBank.setVertexStream(stream.semantic,
- stream.semanticIndex,
- fields[s],
- 0);
- }
- vertexBuffer.allocateElements(numVertices);
- for (var s = 0; s < this.streams.length; ++s) {
- fields[s].setAt(0, this.streams[s].elements);
- }
-
- var indexBuffer = pack.createObject('IndexBuffer');
- indexBuffer.set(this.indices);
- primitive.indexBuffer = indexBuffer;
- o3djs.primitives.setCullingInfo(primitive);
- return shape;
-};
-
-/**
- * A VertexInfo is a specialization of VertexInfoBase for triangle based
- * geometry.
- * @constructor
- * @extends {o3djs.primitives.VertexInfoBase}
- */
-o3djs.primitives.VertexInfo = function() {
- o3djs.primitives.VertexInfoBase.call(this);
-}
-
-o3djs.base.inherit(o3djs.primitives.VertexInfo,
- o3djs.primitives.VertexInfoBase);
-
-/**
- * Returns the number of triangles represented by the VertexInfo.
- * @return {number} The number of triangles represented by VertexInfo.
- */
-o3djs.primitives.VertexInfo.prototype.numTriangles = function() {
- return this.indices.length / 3;
-};
-
-/**
- * Adds a triangle.
- * @param {number} index1 The index of the first vertex of the triangle.
- * @param {number} index2 The index of the second vertex of the triangle.
- * @param {number} index3 The index of the third vertex of the triangle.
- */
-o3djs.primitives.VertexInfo.prototype.addTriangle = function(
- index1, index2, index3) {
- this.indices.push(index1, index2, index3);
-};
-
-/**
- * Gets the vertex indices of the triangle at the given triangle index.
- * @param {number} triangleIndex The index of the triangle.
- * @return {!Array.<number>} An array of three triangle indices.
- */
-o3djs.primitives.VertexInfo.prototype.getTriangle = function(
- triangleIndex) {
- var indexIndex = triangleIndex * 3;
- return [this.indices[indexIndex + 0],
- this.indices[indexIndex + 1],
- this.indices[indexIndex + 2]];
-};
-
-/**
- * Sets the vertex indices of the triangle at the given triangle index.
- * @param {number} triangleIndex The index of the triangle.
- * @param {number} index1 The index of the first vertex of the triangle.
- * @param {number} index2 The index of the second vertex of the triangle.
- * @param {number} index3 The index of the third vertex of the triangle.
- */
-o3djs.primitives.VertexInfo.prototype.setTriangle = function(
- triangleIndex, index1, index2, index3) {
- var indexIndex = triangleIndex * 3;
- this.indices[indexIndex + 0] = index1;
- this.indices[indexIndex + 1] = index2;
- this.indices[indexIndex + 2] = index3;
-};
-
-/**
- * Creates a shape from a VertexInfo
- * @param {!o3d.Pack} pack Pack to create objects in.
- * @param {!o3d.Material} material to use.
- * @return {!o3d.Shape} The created shape.
- */
-o3djs.primitives.VertexInfo.prototype.createShape = function(
- pack,
- material) {
- return this.createShapeByType(
- pack, material, o3djs.base.o3d.Primitive.TRIANGLELIST);
-};
-
-/**
- * Calculate tangents and binormals based on the positions, normals and
- * texture coordinates found in existing streams.
- * @param {number} opt_semanticIndex The semantic index of the texture
- * coordinate to use and the tangent and binormal streams to add. Defaults
- * to zero.
- */
-o3djs.primitives.VertexInfo.prototype.addTangentStreams =
- function(opt_semanticIndex) {
- opt_semanticIndex = opt_semanticIndex || 0;
- var math = o3djs.math;
-
- this.validate();
-
- // Find and validate the position, normal and texture coordinate frames.
- var positionStream = this.findStream(o3djs.base.o3d.Stream.POSITION);
- if (!positionStream)
- throw 'Cannot calculate tangent frame because POSITION stream is missing';
- if (positionStream.numComponents != 3)
- throw 'Cannot calculate tangent frame because POSITION stream is not 3D';
-
- var normalStream = this.findStream(o3djs.base.o3d.Stream.NORMAL);
- if (!normalStream)
- throw 'Cannot calculate tangent frame because NORMAL stream is missing';
- if (normalStream.numComponents != 3)
- throw 'Cannot calculate tangent frame because NORMAL stream is not 3D';
-
- var texCoordStream = this.findStream(o3djs.base.o3d.Stream.TEXCOORD,
- opt_semanticIndex);
- if (!texCoordStream)
- throw 'Cannot calculate tangent frame because TEXCOORD stream ' +
- opt_semanticIndex + ' is missing';
-
- // Maps from position, normal key to tangent and binormal matrix.
- var tangentFrames = {};
-
- // Rounds a vector to integer components.
- function roundVector(v) {
- return [Math.round(v[0]), Math.round(v[1]), Math.round(v[2])];
- }
-
- // Generates a key for the tangentFrames map from a position and normal
- // vector. Rounds position and normal to allow some tolerance.
- function tangentFrameKey(position, normal) {
- return roundVector(math.mulVectorScalar(position, 100)) + ',' +
- roundVector(math.mulVectorScalar(normal, 100));
- }
-
- // Accumulates into the tangent and binormal matrix at the approximate
- // position and normal.
- function addTangentFrame(position, normal, tangent, binormal) {
- var key = tangentFrameKey(position, normal);
- var frame = tangentFrames[key];
- if (!frame) {
- frame = [[0, 0, 0], [0, 0, 0]];
- }
- math.addVector3To(frame[0], tangent, frame[0]);
- math.addVector3To(frame[1], binormal, frame[1]);
- tangentFrames[key] = frame;
- }
-
- // Get the tangent and binormal matrix at the approximate position and
- // normal.
- function getTangentFrame(position, normal) {
- var key = tangentFrameKey(position, normal);
- return tangentFrames[key];
- }
-
- var numTriangles = this.numTriangles();
- for (var triangleIndex = 0; triangleIndex < numTriangles; ++triangleIndex) {
- // Get the vertex indices, uvs and positions for the triangle.
- var vertexIndices = this.getTriangle(triangleIndex);
- var uvs = [];
- var positions = [];
- var normals = [];
- for (var i = 0; i < 3; ++i) {
- var vertexIndex = vertexIndices[i];
- uvs[i] = texCoordStream.getElementVector(vertexIndex);
- positions[i] = positionStream.getElementVector(vertexIndex);
- normals[i] = normalStream.getElementVector(vertexIndex);
- }
-
- // Calculate the tangent and binormal for the triangle using method
- // described in Maya documentation appendix A: tangent and binormal
- // vectors.
- var tangent = [0, 0, 0];
- var binormal = [0, 0, 0];
- for (var axis = 0; axis < 3; ++axis) {
- var edge1 = [positions[1][axis] - positions[0][axis],
- uvs[1][0] - uvs[0][0], uvs[1][1] - uvs[0][1]];
- var edge2 = [positions[2][axis] - positions[0][axis],
- uvs[2][0] - uvs[0][0], uvs[2][1] - uvs[0][1]];
- var edgeCross = math.normalize(math.cross(edge1, edge2));
- if (edgeCross[0] == 0) {
- edgeCross[0] = 1;
- }
- tangent[axis] = -edgeCross[1] / edgeCross[0];
- binormal[axis] = -edgeCross[2] / edgeCross[0];
- }
-
- // Normalize the tangent and binornmal.
- var tangentLength = math.length(tangent);
- if (tangentLength > 0.001) {
- tangent = math.mulVectorScalar(tangent, 1 / tangentLength);
- }
- var binormalLength = math.length(binormal);
- if (binormalLength > 0.001) {
- binormal = math.mulVectorScalar(binormal, 1 / binormalLength);
- }
-
- // Accumulate the tangent and binormal into the tangent frame map.
- for (var i = 0; i < 3; ++i) {
- addTangentFrame(positions[i], normals[i], tangent, binormal);
- }
- }
-
- // Add the tangent and binormal streams.
- var tangentStream = this.addStream(3,
- o3djs.base.o3d.Stream.TANGENT,
- opt_semanticIndex);
- var binormalStream = this.addStream(3,
- o3djs.base.o3d.Stream.BINORMAL,
- opt_semanticIndex);
-
- // Extract the tangent and binormal for each vertex.
- var numVertices = positionStream.numElements();
- for (var vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex) {
- var position = positionStream.getElementVector(vertexIndex);
- var normal = normalStream.getElementVector(vertexIndex);
- var frame = getTangentFrame(position, normal);
-
- // Orthonormalize the tangent with respect to the normal.
- var tangent = frame[0];
- tangent = math.subVector(
- tangent, math.mulVectorScalar(normal, math.dot(normal, tangent)));
- var tangentLength = math.length(tangent);
- if (tangentLength > 0.001) {
- tangent = math.mulVectorScalar(tangent, 1 / tangentLength);
- }
-
- // Orthonormalize the binormal with respect to the normal and the tangent.
- var binormal = frame[1];
- binormal = math.subVector(
- binormal, math.mulVectorScalar(tangent, math.dot(tangent, binormal)));
- binormal = math.subVector(
- binormal, math.mulVectorScalar(normal, math.dot(normal, binormal)));
- var binormalLength = math.length(binormal);
- if (binormalLength > 0.001) {
- binormal = math.mulVectorScalar(binormal, 1 / binormalLength);
- }
-
- tangentStream.setElementVector(vertexIndex, tangent);
- binormalStream.setElementVector(vertexIndex, binormal);
- }
-};
-
-/**
- * Creates a new VertexInfo.
- * @return {!o3djs.primitives.VertexInfo} The new VertexInfo.
- */
-o3djs.primitives.createVertexInfo = function() {
- return new o3djs.primitives.VertexInfo();
-};
-
-/**
- * Creates sphere vertices.
- * The created sphere has position, normal and uv streams.
- *
- * @param {number} radius radius of the sphere.
- * @param {number} subdivisionsAxis number of steps around the sphere.
- * @param {number} subdivisionsHeight number of vertically on the sphere.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply
- * all the vertices.
- * @return {!o3djs.primitives.VertexInfo} The created sphere vertices.
- */
-o3djs.primitives.createSphereVertices = function(radius,
- subdivisionsAxis,
- subdivisionsHeight,
- opt_matrix) {
- if (subdivisionsAxis <= 0 || subdivisionsHeight <= 0) {
- throw Error('subdivisionAxis and subdivisionHeight must be > 0');
- }
-
- // We are going to generate our sphere by iterating through its
- // spherical coordinates and generating 2 triangles for each quad on a
- // ring of the sphere.
-
- var vertexInfo = o3djs.primitives.createVertexInfo();
- var positionStream = vertexInfo.addStream(
- 3, o3djs.base.o3d.Stream.POSITION);
- var normalStream = vertexInfo.addStream(
- 3, o3djs.base.o3d.Stream.NORMAL);
- var texCoordStream = vertexInfo.addStream(
- 2, o3djs.base.o3d.Stream.TEXCOORD, 0);
-
- // Generate the individual vertices in our vertex buffer.
- for (var y = 0; y <= subdivisionsHeight; y++) {
- for (var x = 0; x <= subdivisionsAxis; x++) {
- // Generate a vertex based on its spherical coordinates
- var u = x / subdivisionsAxis;
- var v = y / subdivisionsHeight;
- var theta = 2 * Math.PI * u;
- var phi = Math.PI * v;
- var sinTheta = Math.sin(theta);
- var cosTheta = Math.cos(theta);
- var sinPhi = Math.sin(phi);
- var cosPhi = Math.cos(phi);
- var ux = cosTheta * sinPhi;
- var uy = cosPhi;
- var uz = sinTheta * sinPhi;
- positionStream.addElement(radius * ux, radius * uy, radius * uz);
- normalStream.addElement(ux, uy, uz);
- texCoordStream.addElement(1 - u, 1 - v);
- }
- }
- var numVertsAround = subdivisionsAxis + 1;
-
- for (var x = 0; x < subdivisionsAxis; x++) {
- for (var y = 0; y < subdivisionsHeight; y++) {
- // Make triangle 1 of quad.
- vertexInfo.addTriangle(
- (y + 0) * numVertsAround + x,
- (y + 0) * numVertsAround + x + 1,
- (y + 1) * numVertsAround + x);
-
- // Make triangle 2 of quad.
- vertexInfo.addTriangle(
- (y + 1) * numVertsAround + x,
- (y + 0) * numVertsAround + x + 1,
- (y + 1) * numVertsAround + x + 1);
- }
- }
-
- if (opt_matrix) {
- vertexInfo.reorient(opt_matrix);
- }
- return vertexInfo;
-};
-
-/**
- * Creates a sphere.
- * The created sphere has position, normal and uv streams.
- *
- * @param {!o3d.Pack} pack Pack to create sphere elements in.
- * @param {!o3d.Material} material to use.
- * @param {number} radius radius of the sphere.
- * @param {number} subdivisionsAxis number of steps around the sphere.
- * @param {number} subdivisionsHeight number of vertically on the sphere.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply
- * all the vertices.
- * @return {!o3d.Shape} The created sphere.
- *
- * @see o3d.Pack
- * @see o3d.Shape
- */
-o3djs.primitives.createSphere = function(pack,
- material,
- radius,
- subdivisionsAxis,
- subdivisionsHeight,
- opt_matrix) {
- var vertexInfo = o3djs.primitives.createSphereVertices(
- radius,
- subdivisionsAxis,
- subdivisionsHeight,
- opt_matrix);
-
- return vertexInfo.createShape(pack, material);
-};
-
-/**
- * Array of the indices of corners of each face of a cube.
- * @private
- * @type {!Array.<!Array.<number>>}
- */
-o3djs.primitives.CUBE_FACE_INDICES_ = [
- [3, 7, 5, 1],
- [0, 4, 6, 2],
- [6, 7, 3, 2],
- [0, 1, 5, 4],
- [5, 7, 6, 4],
- [2, 3, 1, 0]
-];
-
-/**
- * Creates the vertices and indices for a cube. The
- * cube will be created around the origin. (-size / 2, size / 2)
- * The created cube has position, normal and uv streams.
- *
- * @param {number} size Width, height and depth of the cube.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply
- * all the vertices.
- * @return {!o3djs.primitives.VertexInfo} The created cube vertices.
- */
-o3djs.primitives.createCubeVertices = function(size, opt_matrix) {
- var k = size / 2;
-
- var cornerVertices = [
- [-k, -k, -k],
- [+k, -k, -k],
- [-k, +k, -k],
- [+k, +k, -k],
- [-k, -k, +k],
- [+k, -k, +k],
- [-k, +k, +k],
- [+k, +k, +k]
- ];
-
- var faceNormals = [
- [+1, +0, +0],
- [-1, +0, +0],
- [+0, +1, +0],
- [+0, -1, +0],
- [+0, +0, +1],
- [+0, +0, -1]
- ];
-
- var uvCoords = [
- [0, 0],
- [1, 0],
- [1, 1],
- [0, 1]
- ];
-
- var vertexInfo = o3djs.primitives.createVertexInfo();
- var positionStream = vertexInfo.addStream(
- 3, o3djs.base.o3d.Stream.POSITION);
- var normalStream = vertexInfo.addStream(
- 3, o3djs.base.o3d.Stream.NORMAL);
- var texCoordStream = vertexInfo.addStream(
- 2, o3djs.base.o3d.Stream.TEXCOORD, 0);
-
- for (var f = 0; f < 6; ++f) {
- var faceIndices = o3djs.primitives.CUBE_FACE_INDICES_[f];
- for (var v = 0; v < 4; ++v) {
- var position = cornerVertices[faceIndices[v]];
- var normal = faceNormals[f];
- var uv = uvCoords[v];
-
- // Each face needs all four vertices because the normals and texture
- // coordinates are not all the same.
- positionStream.addElementVector(position);
- normalStream.addElementVector(normal);
- texCoordStream.addElementVector(uv);
-
- // Two triangles make a square face.
- var offset = 4 * f;
- vertexInfo.addTriangle(offset + 0, offset + 1, offset + 2);
- vertexInfo.addTriangle(offset + 0, offset + 2, offset + 3);
- }
- }
-
- if (opt_matrix) {
- vertexInfo.reorient(opt_matrix);
- }
- return vertexInfo;
-};
-
-/**
- * Creates a cube.
- * The cube will be created around the origin. (-size / 2, size / 2)
- * The created cube has position, normal and uv streams.
- *
- * @param {!o3d.Pack} pack Pack to create cube elements in.
- * @param {!o3d.Material} material to use.
- * @param {number} size Width, height and depth of the cube.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply
- * all the vertices.
- * @return {!o3d.Shape} The created cube.
- *
- * @see o3d.Pack
- * @see o3d.Shape
- */
-o3djs.primitives.createCube = function(pack,
- material,
- size,
- opt_matrix) {
- var vertexInfo = o3djs.primitives.createCubeVertices(size, opt_matrix);
- return vertexInfo.createShape(pack, material);
-};
-
-/**
- * Creates a box. The box will be created around the origin.
- * The created box has position, normal and uv streams.
- *
- * @param {!o3d.Pack} pack Pack to create Box elements in.
- * @param {!o3d.Material} material to use.
- * @param {number} width Width of the box.
- * @param {number} height Height of the box.
- * @param {number} depth Depth of the box.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply
- * all the vertices.
- * @return {!o3d.Shape} The created Box.
- *
- * @see o3d.Pack
- * @see o3d.Shape
- */
-o3djs.primitives.createBox = function(pack,
- material,
- width,
- height,
- depth,
- opt_matrix) {
- var vertexInfo = o3djs.primitives.createCubeVertices(1);
- vertexInfo.reorient(o3djs.math.makeMatrix4(width, 0, 0, 0,
- 0, height, 0, 0,
- 0, 0, depth, 0,
- 0, 0, 0, 1));
-
- if (opt_matrix) {
- vertexInfo.reorient(opt_matrix);
- }
- return vertexInfo.createShape(pack, material);
-};
-
-/**
- * Creates a cube with varying vertex colors. The cube will be created
- * around the origin. (-size / 2, size / 2)
- *
- * @param {!o3d.Pack} pack Pack to create cube elements in.
- * @param {!o3d.Material} material to use.
- * @param {number} size Width, height and depth of the cube.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply
- * all the vertices.
- * @return {!o3d.Shape} The created cube.
- *
- * @see o3d.Pack
- * @see o3d.Shape
- */
-o3djs.primitives.createRainbowCube = function(pack,
- material,
- size,
- opt_matrix) {
- var vertexInfo = o3djs.primitives.createCubeVertices(size, opt_matrix);
- var colorStream = vertexInfo.addStream(
- 4, o3djs.base.o3d.Stream.COLOR);
-
- var colors = [
- [1, 0, 0, 1],
- [0, 1, 0, 1],
- [0, 0, 1, 1],
- [1, 1, 0, 1],
- [0, 1, 1, 1],
- [1, 0, 1, 1],
- [0, .5, .3, 1],
- [.3, 0, .5, 1]
- ];
-
- var vertices = vertexInfo.vertices;
- for (var f = 0; f < 6; ++f) {
- var faceIndices = o3djs.primitives.CUBE_FACE_INDICES_[f];
- for (var v = 0; v < 4; ++v) {
- var color = colors[faceIndices[v]];
- colorStream.addElementVector(color);
- }
- }
-
- return vertexInfo.createShape(pack, material);
-};
-
-/**
- * Creates disc vertices. The disc will be in the xz plane, centered
- * at the origin. When creating, at least 3 divisions, or pie pieces, need
- * to be specified, otherwise the triangles making up the disc will be
- * degenerate. You can also specify the number of radial pieces (opt_stacks).
- * A value of 1 for opt_stacks will give you a simple disc of pie pieces. If
- * you want to create an annulus by omitting some of the center stacks, you
- * can specify the stack at which to start creating triangles. Finally,
- * stackPower allows you to have the widths increase or decrease as you move
- * away from the center. This is particularly useful when using the disc as a
- * ground plane with a fixed camera such that you don't need the resolution of
- * small triangles near the perimeter. For example, a value of 2 will produce
- * stacks whose ouside radius increases with the square of the stack index. A
- * value of 1 will give uniform stacks.
- *
- * @param {number} radius Radius of the ground plane.
- * @param {number} divisions Number of triangles in the ground plane
- * (at least 3).
- * @param {number} opt_stacks Number of radial divisions (default=1).
- * @param {number} opt_startStack Which radial division to start dividing at.
- * @param {number} opt_stackPower Power to raise stack size to for decreasing
- * width.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply
- * all the vertices.
- * @return {!o3djs.primitives.VertexInfo} The created plane vertices.
- */
-o3djs.primitives.createDiscVertices = function(radius,
- divisions,
- opt_stacks,
- opt_startStack,
- opt_stackPower,
- opt_matrix) {
- if (divisions < 3) {
- throw Error('divisions must be at least 3');
- }
-
- var stacks = opt_stacks ? opt_stacks : 1;
- var startStack = opt_startStack ? opt_startStack : 0;
- var stackPower = opt_stackPower ? opt_stackPower : 1;
-
- var vertexInfo = o3djs.primitives.createVertexInfo();
- var positionStream = vertexInfo.addStream(
- 3, o3djs.base.o3d.Stream.POSITION);
- var normalStream = vertexInfo.addStream(
- 3, o3djs.base.o3d.Stream.NORMAL);
- var texCoordStream = vertexInfo.addStream(
- 2, o3djs.base.o3d.Stream.TEXCOORD, 0);
-
- // Initialize the center vertex.
- // x y z nx ny nz r g b a u v
- var firstIndex = 0;
-
- if (startStack == 0) {
- positionStream.addElement(0, 0, 0);
- normalStream.addElement(0, 1, 0);
- texCoordStream.addElement(0, 0);
- firstIndex++;
- }
-
- // Build the disk one stack at a time.
- for (var currentStack = Math.max(startStack, 1);
- currentStack <= stacks;
- ++currentStack) {
- var stackRadius = radius * Math.pow(currentStack / stacks, stackPower);
-
- for (var i = 0; i < divisions; ++i) {
- var theta = 2.0 * Math.PI * i / divisions;
- var x = stackRadius * Math.cos(theta);
- var z = stackRadius * Math.sin(theta);
-
- positionStream.addElement(x, 0, z);
- normalStream.addElement(0, 1, 0);
- texCoordStream.addElement(x, z);
-
- if (currentStack > startStack) {
- // a, b, c and d are the indices of the vertices of a quad. unless
- // the current stack is the one closest to the center, in which case
- // the vertices a and b connect to the center vertex.
- var a = firstIndex + (i + 1) % divisions;
- var b = firstIndex + i;
- if (currentStack > 1) {
- var c = firstIndex + i - divisions;
- var d = firstIndex + (i + 1) % divisions - divisions;
-
- // Make a quad of the vertices a, b, c, d.
- vertexInfo.addTriangle(a, b, c);
- vertexInfo.addTriangle(a, c, d);
- } else {
- // Make a single triangle of a, b and the center.
- vertexInfo.addTriangle(0, a, b);
- }
- }
- }
-
- firstIndex += divisions;
- }
-
- if (opt_matrix) {
- vertexInfo.reorient(opt_matrix);
- }
- return vertexInfo;
-};
-
-/**
- * Creates a disc shape. The disc will be in the xz plane, centered
- * at the origin. When creating, at least 3 divisions, or pie pieces, need
- * to be specified, otherwise the triangles making up the disc will be
- * degenerate. You can also specify the number of radial pieces (opt_stacks).
- * A value of 1 for opt_stacks will give you a simple disc of pie pieces. If
- * you want to create an annulus by omitting some of the center stacks, you
- * can specify the stack at which to start creating triangles. Finally,
- * stackPower allows you to have the widths increase or decrease as you move
- * away from the center. This is particularly useful when using the disc as a
- * ground plane with a fixed camera such that you don't need the resolution of
- * small triangles near the perimeter. For example, a value of 2 will produce
- * stacks whose ouside radius increases with the square of the stack index. A
- * value of 1 will give uniform stacks.
- *
- * @param {!o3d.Pack} pack Pack to create disc elements in.
- * @param {!o3d.Material} material to use.
- * @param {number} radius Radius of the disc.
- * @param {number} divisions Number of triangles in the disc (at least 3).
- * @param {number} stacks Number of radial divisions.
- * @param {number} startStack Which radial division to start dividing at.
- * @param {number} stackPower Power to raise stack size to for decreasing width.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply
- * all the vertices.
- * @return {!o3d.Shape} The created disc.
- *
- * @see o3d.Pack
- * @see o3d.Shape
- */
-o3djs.primitives.createDisc = function(pack, material,
- radius, divisions, stacks,
- startStack, stackPower,
- opt_matrix) {
- var vertexInfo = o3djs.primitives.createDiscVertices(radius, divisions,
- stacks,
- startStack,
- stackPower,
- opt_matrix);
-
- return vertexInfo.createShape(pack, material);
-};
-
-/**
- * Creates cylinder vertices. The cylinder will be created around the origin
- * along the y-axis. The created cylinder has position, normal and uv streams.
- *
- * @param {number} radius Radius of cylinder.
- * @param {number} height Height of cylinder.
- * @param {number} radialSubdivisions The number of subdivisions around the
- * cylinder.
- * @param {number} verticalSubdivisions The number of subdivisions down the
- * cylinder.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply
- * all the vertices.
- * @return {!o3djs.primitives.VertexInfo} The created cylinder vertices.
- */
-o3djs.primitives.createCylinderVertices = function(radius,
- height,
- radialSubdivisions,
- verticalSubdivisions,
- opt_matrix) {
- return o3djs.primitives.createTruncatedConeVertices(radius,
- radius,
- height,
- radialSubdivisions,
- verticalSubdivisions,
- opt_matrix);
-};
-
-/**
- * Creates a cylinder shape. The cylinder will be created around the
- * origin along the y-axis. The created cylinder has position, normal
- * and uv streams.
- *
- * @param {!o3d.Pack} pack Pack to create cylinder elements in.
- * @param {!o3d.Material} material to use.
- * @param {number} radius Radius of cylinder.
- * @param {number} height Height of cylinder.
- * @param {number} radialSubdivisions The number of subdivisions around the
- * cylinder.
- * @param {number} verticalSubdivisions The number of subdivisions down the
- * cylinder.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply
- * all the vertices.
- * @return {!o3d.Shape} The created cylinder.
- */
-o3djs.primitives.createCylinder = function(pack,
- material,
- radius,
- height,
- radialSubdivisions,
- verticalSubdivisions,
- opt_matrix) {
- var vertexInfo = o3djs.primitives.createCylinderVertices(
- radius,
- height,
- radialSubdivisions,
- verticalSubdivisions,
- opt_matrix);
- return vertexInfo.createShape(pack, material);
-};
-
-/**
- * Creates vertices for a truncated cone, which is like a cylinder
- * except that it has different top and bottom radii. A truncated cone
- * can also be used to create cylinders and regular cones. The
- * truncated cone will be created centered about the origin, with the
- * y axis as its vertical axis. The created cone has position, normal
- * and uv streams.
- *
- * @param {number} bottomRadius Bottom radius of truncated cone.
- * @param {number} topRadius Top radius of truncated cone.
- * @param {number} height Height of truncated cone.
- * @param {number} radialSubdivisions The number of subdivisions around the
- * truncated cone.
- * @param {number} verticalSubdivisions The number of subdivisions down the
- * truncated cone.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply
- * all the vertices.
- * @return {!o3djs.primitives.VertexInfo} The created truncated cone vertices.
- */
-o3djs.primitives.createTruncatedConeVertices = function(bottomRadius,
- topRadius,
- height,
- radialSubdivisions,
- verticalSubdivisions,
- opt_matrix) {
- if (radialSubdivisions < 3) {
- throw Error('radialSubdivisions must be 3 or greater');
- }
-
- if (verticalSubdivisions < 1) {
- throw Error('verticalSubdivisions must be 1 or greater');
- }
-
- var vertexInfo = o3djs.primitives.createVertexInfo();
- var positionStream = vertexInfo.addStream(
- 3, o3djs.base.o3d.Stream.POSITION);
- var normalStream = vertexInfo.addStream(
- 3, o3djs.base.o3d.Stream.NORMAL);
- var texCoordStream = vertexInfo.addStream(
- 2, o3djs.base.o3d.Stream.TEXCOORD, 0);
-
- var vertsAroundEdge = radialSubdivisions + 1;
-
- // The slant of the cone is constant across its surface
- var slant = Math.atan2(bottomRadius - topRadius, height);
- var cosSlant = Math.cos(slant);
- var sinSlant = Math.sin(slant);
-
- for (var yy = -2; yy <= verticalSubdivisions + 2; ++yy) {
- var v = yy / verticalSubdivisions
- var y = height * v;
- var ringRadius;
- if (yy < 0) {
- y = 0;
- v = 1;
- ringRadius = bottomRadius;
- } else if (yy > verticalSubdivisions) {
- y = height;
- v = 1;
- ringRadius = topRadius;
- } else {
- ringRadius = bottomRadius +
- (topRadius - bottomRadius) * (yy / verticalSubdivisions);
- }
- if (yy == -2 || yy == verticalSubdivisions + 2) {
- ringRadius = 0;
- v = 0;
- }
- y -= height / 2;
- for (var ii = 0; ii < vertsAroundEdge; ++ii) {
- var sin = Math.sin(ii * Math.PI * 2 / radialSubdivisions);
- var cos = Math.cos(ii * Math.PI * 2 / radialSubdivisions);
- positionStream.addElement(sin * ringRadius, y, cos * ringRadius);
- normalStream.addElement(
- (yy < 0 || yy > verticalSubdivisions) ? 0 : (sin * cosSlant),
- (yy < 0) ? -1 : (yy > verticalSubdivisions ? 1 : sinSlant),
- (yy < 0 || yy > verticalSubdivisions) ? 0 : (cos * cosSlant));
- texCoordStream.addElement(ii / radialSubdivisions, v);
- }
- }
-
- for (var yy = 0; yy < verticalSubdivisions + 4; ++yy) {
- for (var ii = 0; ii < radialSubdivisions; ++ii) {
- vertexInfo.addTriangle(vertsAroundEdge * (yy + 0) + 0 + ii,
- vertsAroundEdge * (yy + 0) + 1 + ii,
- vertsAroundEdge * (yy + 1) + 1 + ii);
- vertexInfo.addTriangle(vertsAroundEdge * (yy + 0) + 0 + ii,
- vertsAroundEdge * (yy + 1) + 1 + ii,
- vertsAroundEdge * (yy + 1) + 0 + ii);
- }
- }
-
- if (opt_matrix) {
- vertexInfo.reorient(opt_matrix);
- }
- return vertexInfo;
-};
-
-/**
- * Creates a truncated cone shape, which is like a cylinder except
- * that it has different top and bottom radii. A truncated cone can
- * also be used to create cylinders, by setting the bottom and top
- * radii equal, and cones, by setting either the top or bottom radius
- * to 0. The truncated cone will be created centered about the origin,
- * with the y axis as its vertical axis. The created cone has
- * position, normal and uv streams.
- *
- * @param {!o3d.Pack} pack Pack in which to create the truncated cone.
- * @param {!o3d.Material} material to use.
- * @param {number} bottomRadius Bottom radius of truncated cone.
- * @param {number} topRadius Top radius of truncated cone.
- * @param {number} height Height of truncated cone.
- * @param {number} radialSubdivisions The number of subdivisions around the
- * truncated cone.
- * @param {number} verticalSubdivisions The number of subdivisions down the
- * truncated cone.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply
- * all the vertices.
- * @return {!o3d.Shape} The created truncated cone.
- */
-o3djs.primitives.createTruncatedCone = function(pack,
- material,
- bottomRadius,
- topRadius,
- height,
- radialSubdivisions,
- verticalSubdivisions,
- opt_matrix) {
- var vertexInfo = o3djs.primitives.createTruncatedConeVertices(
- bottomRadius,
- topRadius,
- height,
- radialSubdivisions,
- verticalSubdivisions,
- opt_matrix);
- return vertexInfo.createShape(pack, material);
-};
-
-/**
- * Creates vertices for a torus. The torus will be created centered about the
- * origin, with the y axis as its vertical axis. The created torus has
- * position, normal and uv streams.
- *
- * @param {number} torusRadius Distance from the center of the tube to
- * the center of the torus.
- * @param {number} tubeRadius Radius of the tube.
- * @param {number} tubeLengthSubdivisions The number of subdivisions around the
- * vertical axis of the torus, i.e. along the length of the tube.
- * @param {number} circleSubdivisions The number of subdivisions in the circle
- * that is rotated about the vertical axis to create the torus.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply
- * all the vertices.
- * @return {!o3djs.primitives.VertexInfo} The created torus vertices.
- */
-o3djs.primitives.createTorusVertices = function(torusRadius,
- tubeRadius,
- tubeLengthSubdivisions,
- circleSubdivisions,
- opt_matrix) {
- if (tubeLengthSubdivisions < 3) {
- throw Error('tubeLengthSubdivisions must be 3 or greater');
- }
-
- if (circleSubdivisions < 3) {
- throw Error('circleSubdivisions must be 3 or greater');
- }
-
- var vertexInfo = o3djs.primitives.createVertexInfo();
- var positionStream = vertexInfo.addStream(
- 3, o3djs.base.o3d.Stream.POSITION);
- var normalStream = vertexInfo.addStream(
- 3, o3djs.base.o3d.Stream.NORMAL);
- var texCoordStream = vertexInfo.addStream(
- 2, o3djs.base.o3d.Stream.TEXCOORD, 0);
-
- for (var uu = 0; uu < tubeLengthSubdivisions; ++uu) {
- var u = (uu / tubeLengthSubdivisions) * 2 * Math.PI;
- for (var vv = 0; vv < circleSubdivisions; ++vv) {
- var v = (vv / circleSubdivisions) * 2 * Math.PI;
- var sinu = Math.sin(u);
- var cosu = Math.cos(u);
- var sinv = Math.sin(v);
- var cosv = Math.cos(v);
- positionStream.addElement((torusRadius + tubeRadius * cosv) * cosu,
- tubeRadius * sinv,
- (torusRadius + tubeRadius * cosv) * sinu);
- normalStream.addElement(cosv * cosu,
- sinv,
- cosv * sinu);
- texCoordStream.addElement(uu / tubeLengthSubdivisions,
- vv / circleSubdivisions);
- }
- }
-
- for (var uu = 0; uu < tubeLengthSubdivisions; ++uu) {
- for (var vv = 0; vv < circleSubdivisions; ++vv) {
- // We want to wrap the indices around at the seams.
- var uuPlusOne = (uu + 1) % tubeLengthSubdivisions;
- var vvPlusOne = (vv + 1) % circleSubdivisions;
- // The indices of four points forming a quad.
- var a = circleSubdivisions * uu + vv;
- var b = circleSubdivisions * uuPlusOne + vv;
- var c = circleSubdivisions * uu + vvPlusOne;
- var d = circleSubdivisions * uuPlusOne + vvPlusOne;
- vertexInfo.addTriangle(a, d, b);
- vertexInfo.addTriangle(a, c, d);
- }
- }
-
- if (opt_matrix) {
- vertexInfo.reorient(opt_matrix);
- }
- return vertexInfo;
-};
-
-/**
- * Creates a torus shape. The torus will be created centered about the
- * origin, with the y axis as its vertical axis. The created torus has
- * position, normal and uv streams.
- *
- * @param {!o3d.Pack} pack Pack in which to create the torus.
- * @param {!o3d.Material} material to use.
- * @param {number} torusRadius Distance from the center of the tube to
- * the center of the torus.
- * @param {number} tubeRadius Radius of the tube.
- * @param {number} tubeLengthSubdivisions The number of subdivisions around the
- * vertical axis of the torus, i.e. along the length of the tube.
- * @param {number} circleSubdivisions The number of subdivisions in the circle
- * that is rotated about the vertical axis to create the torus.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply
- * all the vertices.
- * @return {!o3d.Shape} The created torus.
- */
-o3djs.primitives.createTorus = function(pack,
- material,
- torusRadius,
- tubeRadius,
- tubeLengthSubdivisions,
- circleSubdivisions,
- opt_matrix) {
- var vertexInfo = o3djs.primitives.createTorusVertices(
- torusRadius,
- tubeRadius,
- tubeLengthSubdivisions,
- circleSubdivisions,
- opt_matrix);
- return vertexInfo.createShape(pack, material);
-};
-
-/**
- * Creates wedge vertices, wedge being an extruded triangle. The wedge will be
- * created around the 3 2d points passed in and extruded along the z axis. The
- * created wedge has position, normal and uv streams.
- *
- * @param {!Array.<!Array.<number>>} inPoints Array of 2d points in the format
- * [[x1, y1], [x2, y2], [x3, y3]] that describe a 2d triangle.
- * @param {number} depth The depth to extrude the triangle.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply
- * all the vertices.
- * @return {!o3djs.primitives.VertexInfo} The created wedge vertices.
- */
-o3djs.primitives.createWedgeVertices = function(inPoints, depth,
- opt_matrix) {
- var math = o3djs.math;
-
- var vertexInfo = o3djs.primitives.createVertexInfo();
- var positionStream = vertexInfo.addStream(
- 3, o3djs.base.o3d.Stream.POSITION);
- var normalStream = vertexInfo.addStream(
- 3, o3djs.base.o3d.Stream.NORMAL);
- var texCoordStream = vertexInfo.addStream(
- 2, o3djs.base.o3d.Stream.TEXCOORD, 0);
-
- var z1 = -depth * 0.5;
- var z2 = depth * 0.5;
- var face = [];
- var points = [[inPoints[0][0], inPoints[0][1]],
- [inPoints[1][0], inPoints[1][1]],
- [inPoints[2][0], inPoints[2][1]]];
-
- face[0] = math.cross(
- math.normalize([points[1][0] - points[0][0],
- points[1][1] - points[0][1],
- z1 - z1]),
- math.normalize([points[1][0] - points[1][0],
- points[1][1] - points[1][1],
- z2 - z1]));
- face[1] = math.cross(
- math.normalize([points[2][0] - points[1][0],
- points[2][1] - points[1][1],
- z1 - z1]),
- math.normalize([points[2][0] - points[2][0],
- points[2][1] - points[2][1],
- z2 - z1]));
- face[2] = math.cross(
- [points[0][0] - points[2][0], points[0][1] - points[2][1], z1 - z1],
- [points[0][0] - points[0][0], points[0][1] - points[0][1], z2 - z1]);
-
- positionStream.addElement(points[0][0], points[0][1], z1);
- normalStream.addElement(0, 0, -1);
- texCoordStream.addElement(0, 1);
- positionStream.addElement(points[1][0], points[1][1], z1);
- normalStream.addElement(0, 0, -1);
- texCoordStream.addElement(1, 0);
- positionStream.addElement(points[2][0], points[2][1], z1);
- normalStream.addElement(0, 0, -1);
- texCoordStream.addElement(0, 0);
- // back
- positionStream.addElement(points[0][0], points[0][1], z2);
- normalStream.addElement(0, 0, 1);
- texCoordStream.addElement(0, 1);
- positionStream.addElement(points[1][0], points[1][1], z2);
- normalStream.addElement(0, 0, 1);
- texCoordStream.addElement(1, 0);
- positionStream.addElement(points[2][0], points[2][1], z2);
- normalStream.addElement(0, 0, 1);
- texCoordStream.addElement(0, 0);
- // face 0
- positionStream.addElement(points[0][0], points[0][1], z1);
- normalStream.addElement(face[0][0], face[0][1], face[0][2]);
- texCoordStream.addElement(0, 1);
- positionStream.addElement(points[1][0], points[1][1], z1);
- normalStream.addElement(face[0][0], face[0][1], face[0][2]);
- texCoordStream.addElement(0, 0);
- positionStream.addElement(points[1][0], points[1][1], z2);
- normalStream.addElement(face[0][0], face[0][1], face[0][2]);
- texCoordStream.addElement(1, 0);
- positionStream.addElement(points[0][0], points[0][1], z2);
- normalStream.addElement(face[0][0], face[0][1], face[0][2]);
- texCoordStream.addElement(1, 1);
- // face 1
- positionStream.addElement(points[1][0], points[1][1], z1);
- normalStream.addElement(face[1][0], face[1][1], face[1][2]);
- texCoordStream.addElement(0, 1);
- positionStream.addElement(points[2][0], points[2][1], z1);
- normalStream.addElement(face[1][0], face[1][1], face[1][2]);
- texCoordStream.addElement(0, 0);
- positionStream.addElement(points[2][0], points[2][1], z2);
- normalStream.addElement(face[1][0], face[1][1], face[1][2]);
- texCoordStream.addElement(1, 0);
- positionStream.addElement(points[1][0], points[1][1], z2);
- normalStream.addElement(face[1][0], face[1][1], face[1][2]);
- texCoordStream.addElement(1, 1);
- // face 2
- positionStream.addElement(points[2][0], points[2][1], z1);
- normalStream.addElement(face[2][0], face[2][1], face[2][2]);
- texCoordStream.addElement(0, 1);
- positionStream.addElement(points[0][0], points[0][1], z1);
- normalStream.addElement(face[2][0], face[2][1], face[2][2]);
- texCoordStream.addElement(0, 0);
- positionStream.addElement(points[0][0], points[0][1], z2);
- normalStream.addElement(face[2][0], face[2][1], face[2][2]);
- texCoordStream.addElement(1, 0);
- positionStream.addElement(points[2][0], points[2][1], z2);
- normalStream.addElement(face[2][0], face[2][1], face[2][2]);
- texCoordStream.addElement(1, 1);
-
- vertexInfo.addTriangle(0, 2, 1);
- vertexInfo.addTriangle(3, 4, 5);
- vertexInfo.addTriangle(6, 7, 8);
- vertexInfo.addTriangle(6, 8, 9);
- vertexInfo.addTriangle(10, 11, 12);
- vertexInfo.addTriangle(10, 12, 13);
- vertexInfo.addTriangle(14, 15, 16);
- vertexInfo.addTriangle(14, 16, 17);
-
- if (opt_matrix) {
- vertexInfo.reorient(opt_matrix);
- }
- return vertexInfo;
-};
-
-/**
- * Creates a wedge shape. A wedge being an extruded triangle. The wedge will
- * be created around the 3 2d points passed in and extruded along the z-axis.
- * The created wedge has position, normal and uv streams.
- *
- * @param {!o3d.Pack} pack Pack to create wedge elements in.
- * @param {!o3d.Material} material to use.
- * @param {!Array.<!Array.<number>>} points Array of 2d points in the format
- * [[x1, y1], [x2, y2], [x3, y3]] that describe a 2d triangle.
- * @param {number} depth The depth to extrude the triangle.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply
- * all the vertices.
- * @return {!o3d.Shape} The created wedge.
- */
-o3djs.primitives.createWedge = function(pack,
- material,
- points,
- depth,
- opt_matrix) {
- var vertexInfo = o3djs.primitives.createWedgeVertices(points,
- depth,
- opt_matrix);
- return vertexInfo.createShape(pack, material);
-};
-
-/**
- * Creates prism vertices by extruding a polygon. The prism will be created
- * around the 2d points passed in and extruded along the z axis. The end caps
- * of the prism are constructed using a triangle fan originating at point 0,
- * so a non-convex polygon might not get the desired shape, but it will if it
- * is convex with respect to point 0. Texture coordinates map each face of
- * the wall exactly to the unit square. Texture coordinates on the front
- * and back faces are scaled such that the bounding rectangle of the polygon
- * is mapped to the unit square. The created prism has position, normal,
- * uv streams.
- *
- * @param {!Array.<!Array.<number>>} points Array of 2d points in the format
- * [[x1, y1], [x2, y2], [x3, y3],...] that describe a 2d polygon.
- * @param {number} depth The depth to extrude the polygon.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply
- * all the vertices.
- * @return {!o3djs.primitives.VertexInfo} The created prism vertices.
- */
-o3djs.primitives.createPrismVertices = function(points,
- depth,
- opt_matrix) {
- if (points.length < 3) {
- throw Error('there must be 3 or more points');
- }
-
- var backZ = -0.5 * depth;
- var frontZ = 0.5 * depth;
- var normals = [];
-
- var vertexInfo = o3djs.primitives.createVertexInfo();
- var positionStream = vertexInfo.addStream(
- 3, o3djs.base.o3d.Stream.POSITION);
- var normalStream = vertexInfo.addStream(
- 3, o3djs.base.o3d.Stream.NORMAL);
- var texCoordStream = vertexInfo.addStream(
- 2, o3djs.base.o3d.Stream.TEXCOORD, 0);
-
- // Normals for the wall faces.
- var n = points.length;
-
- for (var i = 0; i < n; ++i) {
- var j = (i + 1) % n;
- var x = points[j][0] - points[i][0];
- var y = points[j][1] - points[i][1];
- var length = Math.sqrt(x * x + y * y);
- normals[i] = [y / length, -x / length, 0];
- }
-
- // Compute the minimum and maxiumum x and y coordinates of points in the
- // polygon.
- var minX = points[0][0];
- var minY = points[0][1];
- var maxX = points[0][0];
- var maxY = points[0][1];
- for (var i = 1; i < n; ++i) {
- var x = points[i][0];
- var y = points[i][1];
- minX = Math.min(minX, x);
- minY = Math.min(minY, y);
- maxX = Math.max(maxX, x);
- maxY = Math.max(maxY, y);
- }
-
- // Scale the x and y coordinates of the points of the polygon to fit the
- // bounding rectangle, and use the scaled coordinates for the uv
- // of the front and back cap.
- var frontUV = [];
- var backUV = [];
- var rangeX = maxX - minX;
- var rangeY = maxY - minY;
- for (var i = 0; i < n; ++i) {
- frontUV[i] = [
- (points[i][0] - minX) / rangeX,
- (points[i][1] - minY) / rangeY
- ];
- backUV[i] = [
- (maxX - points[i][0]) / rangeX,
- (points[i][1] - minY) / rangeY
- ];
- }
-
- for (var i = 0; i < n; ++i) {
- var j = (i + 1) % n;
- // Vertex on the back face.
- positionStream.addElement(points[i][0], points[i][1], backZ);
- normalStream.addElement(0, 0, -1);
- texCoordStream.addElement(backUV[i][0], backUV[i][1]);
-
- // Vertex on the front face.
- positionStream.addElement(points[i][0], points[i][1], frontZ),
- normalStream.addElement(0, 0, 1);
- texCoordStream.addElement(frontUV[i][0], frontUV[i][1]);
-
- // Vertices for a quad on the wall.
- positionStream.addElement(points[i][0], points[i][1], backZ),
- normalStream.addElement(normals[i][0], normals[i][1], normals[i][2]);
- texCoordStream.addElement(0, 1);
-
- positionStream.addElement(points[j][0], points[j][1], backZ),
- normalStream.addElement(normals[i][0], normals[i][1], normals[i][2]);
- texCoordStream.addElement(0, 0);
-
- positionStream.addElement(points[j][0], points[j][1], frontZ),
- normalStream.addElement(normals[i][0], normals[i][1], normals[i][2]);
- texCoordStream.addElement(1, 0);
-
- positionStream.addElement(points[i][0], points[i][1], frontZ),
- normalStream.addElement(normals[i][0], normals[i][1], normals[i][2]);
- texCoordStream.addElement(1, 1);
-
- if (i > 0 && i < n - 1) {
- // Triangle for the back face.
- vertexInfo.addTriangle(0, 6 * (i + 1), 6 * i);
-
- // Triangle for the front face.
- vertexInfo.addTriangle(1, 6 * i + 1, 6 * (i + 1) + 1);
- }
-
- // Quad on the wall.
- vertexInfo.addTriangle(6 * i + 2, 6 * i + 3, 6 * i + 4);
- vertexInfo.addTriangle(6 * i + 2, 6 * i + 4, 6 * i + 5);
- }
-
- if (opt_matrix) {
- vertexInfo.reorient(opt_matrix);
- }
- return vertexInfo;
-};
-
-/**
- * Creates a prism shape by extruding a polygon. The prism will be created
- * around the 2d points passed in an array and extruded along the z-axis.
- * The end caps of the prism are constructed using a triangle fan originating
- * at the first point, so a non-convex polygon might not get the desired
- * shape, but it will if it is convex with respect to the first point.
- * Texture coordinates map each face of the wall exactly to the unit square.
- * Texture coordinates on the front and back faces are scaled such that the
- * bounding rectangle of the polygon is mapped to the unit square.
- * The created prism has position, normal and uv streams.
- *
- * @param {!o3d.Pack} pack Pack to create wedge elements in.
- * @param {!o3d.Material} material to use.
- * @param {!Array.<!Array.<number>>} points Array of 2d points in the format:
- * [[x1, y1], [x2, y2], [x3, y3],...] that describe a 2d polygon.
- * @param {number} depth The depth to extrude the polygon.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply
- * all the vertices.
- * @return {!o3d.Shape} The created prism.
- */
-o3djs.primitives.createPrism = function(pack,
- material,
- points,
- depth,
- opt_matrix) {
- var vertexInfo = o3djs.primitives.createPrismVertices(points,
- depth,
- opt_matrix);
- return vertexInfo.createShape(pack, material);
-};
-
-/**
- * Creates XZ plane vertices.
- * The created plane has position, normal and uv streams.
- *
- * @param {number} width Width of the plane.
- * @param {number} depth Depth of the plane.
- * @param {number} subdivisionsWidth Number of steps across the plane.
- * @param {number} subdivisionsDepth Number of steps down the plane.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply
- * all the vertices.
- * @return {!o3djs.primitives.VertexInfo} The created plane vertices.
- */
-o3djs.primitives.createPlaneVertices = function(width,
- depth,
- subdivisionsWidth,
- subdivisionsDepth,
- opt_matrix) {
- if (subdivisionsWidth <= 0 || subdivisionsDepth <= 0) {
- throw Error('subdivisionWidth and subdivisionDepth must be > 0');
- }
-
- var vertexInfo = o3djs.primitives.createVertexInfo();
- var positionStream = vertexInfo.addStream(
- 3, o3djs.base.o3d.Stream.POSITION);
- var normalStream = vertexInfo.addStream(
- 3, o3djs.base.o3d.Stream.NORMAL);
- var texCoordStream = vertexInfo.addStream(
- 2, o3djs.base.o3d.Stream.TEXCOORD, 0);
-
- // Generate the individual vertices in our vertex buffer.
- for (var z = 0; z <= subdivisionsDepth; z++) {
- for (var x = 0; x <= subdivisionsWidth; x++) {
- var u = x / subdivisionsWidth;
- var v = z / subdivisionsDepth;
- positionStream.addElement(width * u - width * 0.5,
- 0,
- depth * v - depth * 0.5);
- normalStream.addElement(0, 1, 0);
- texCoordStream.addElement(u, 1 - v);
- }
- }
-
- var numVertsAcross = subdivisionsWidth + 1;
-
- for (var z = 0; z < subdivisionsDepth; z++) {
- for (var x = 0; x < subdivisionsWidth; x++) {
- // triangle 1 of quad
- vertexInfo.addTriangle(
- (z + 0) * numVertsAcross + x,
- (z + 1) * numVertsAcross + x,
- (z + 0) * numVertsAcross + x + 1);
-
- // triangle 2 of quad
- vertexInfo.addTriangle(
- (z + 1) * numVertsAcross + x,
- (z + 1) * numVertsAcross + x + 1,
- (z + 0) * numVertsAcross + x + 1);
- }
- }
-
- if (opt_matrix) {
- vertexInfo.reorient(opt_matrix);
- }
- return vertexInfo;
-};
-
-/**
- * Creates an XZ plane.
- * The created plane has position, normal and uv streams.
- *
- * @param {!o3d.Pack} pack Pack to create plane elements in.
- * @param {!o3d.Material} material to use.
- * @param {number} width Width of the plane.
- * @param {number} depth Depth of the plane.
- * @param {number} subdivisionsWidth Number of steps across the plane.
- * @param {number} subdivisionsDepth Number of steps down the plane.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply
- * all the vertices.
- * @return {!o3d.Shape} The created plane.
- *
- * @see o3d.Pack
- * @see o3d.Shape
- */
-o3djs.primitives.createPlane = function(pack,
- material,
- width,
- depth,
- subdivisionsWidth,
- subdivisionsDepth,
- opt_matrix) {
- var vertexInfo = o3djs.primitives.createPlaneVertices(
- width,
- depth,
- subdivisionsWidth,
- subdivisionsDepth,
- opt_matrix);
-
- return vertexInfo.createShape(pack, material);
-};
-
-/**
- * Creates an XZ fade plane, where the alpha channel of the color stream
- * fades from 1 to 0.
- * The created plane has position, normal, uv and vertex color streams.
- *
- * @param {!o3d.Pack} pack Pack to create plane elements in.
- * @param {!o3d.Material} material to use.
- * @param {number} width Width of the plane.
- * @param {number} depth Depth of the plane.
- * @param {number} subdivisionsWidth Number of steps across the plane.
- * @param {number} subdivisionsDepth Number of steps down the plane.
- * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply
- * all the vertices.
- * @return {!o3d.Shape} The created plane.
- *
- * @see o3d.Pack
- * @see o3d.Shape
- */
-o3djs.primitives.createFadePlane = function(pack,
- material,
- width,
- depth,
- subdivisionsWidth,
- subdivisionsDepth,
- opt_matrix) {
- var vertexInfo = o3djs.primitives.createPlaneVertices(
- width,
- depth,
- subdivisionsWidth,
- subdivisionsDepth,
- opt_matrix);
- var colorStream = vertexInfo.addStream(4, o3djs.base.o3d.Stream.COLOR);
- for (var z = 0; z <= subdivisionsDepth; z++) {
- var alpha = z / subdivisionsDepth;
- for (var x = 0; x <= subdivisionsWidth; x++) {
- colorStream.addElement(1, 1, 1, alpha);
- }
- }
- return vertexInfo.createShape(pack, material);
-};
-
diff --git a/o3d/samples/o3djs/quaternions.js b/o3d/samples/o3djs/quaternions.js
deleted file mode 100644
index 24d9d65..0000000
--- a/o3d/samples/o3djs/quaternions.js
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @fileoverview This file contains various functions for quaternion arithmetic
- * and converting between rotation matrices and quaternions. It adds them to
- * the "quaternions" module on the o3djs object. Javascript arrays with
- * four entries are used to represent quaternions, and functions are provided
- * for doing operations on those.
- *
- * Operations are done assuming quaternions are of the form:
- * q[0] + q[1]i + q[2]j + q[3]k and using the hamiltonian rules for
- * multiplication as described on Brougham Bridge:
- * i^2 = j^2 = k^2 = ijk = -1.
- *
- */
-
-o3djs.provide('o3djs.quaternions');
-
-/**
- * A Module for quaternion math.
- * @namespace
- */
-o3djs.quaternions = o3djs.quaternions || {};
-
-/**
- * A Quaternion.
- * @type {!Array.<number>}
- */
-o3djs.quaternions.Quaternion = goog.typedef;
-
-/**
- * Quickly determines if the object a is a scalar or a quaternion;
- * assumes that the argument is either a number (scalar), or an array of
- * numbers.
- * @param {(number|!o3djs.quaternions.Quaternion)} a A number or array the type
- * of which is in question.
- * @return {string} Either the string 'Scalar' or 'Quaternion'.
- */
-o3djs.quaternions.mathType = function(a) {
- if (typeof(a) === 'number')
- return 'Scalar';
- return 'Quaternion';
-};
-
-/**
- * Copies a quaternion.
- * @param {!o3djs.quaternions.Quaternion} q The quaternion.
- * @return {!o3djs.quaternions.Quaternion} A new quaternion identical to q.
- */
-o3djs.quaternions.copy = function(q) {
- return q.slice();
-};
-
-/**
- * Negates a quaternion.
- * @param {!o3djs.quaternions.Quaternion} q The quaternion.
- * @return {!o3djs.quaternions.Quaternion} -q.
- */
-o3djs.quaternions.negative = function(q) {
- return [-q[0], -q[1], -q[2], -q[3]];
-};
-
-/**
- * Adds two Quaternions.
- * @param {!o3djs.quaternions.Quaternion} a Operand Quaternion.
- * @param {!o3djs.quaternions.Quaternion} b Operand Quaternion.
- * @return {!o3djs.quaternions.Quaternion} The sum of a and b.
- */
-o3djs.quaternions.addQuaternionQuaternion = function(a, b) {
- return [a[0] + b[0],
- a[1] + b[1],
- a[2] + b[2],
- a[3] + b[3]];
-};
-
-/**
- * Adds a quaternion to a scalar.
- * @param {!o3djs.quaternions.Quaternion} a Operand Quaternion.
- * @param {number} b Operand Scalar.
- * @return {!o3djs.quaternions.Quaternion} The sum of a and b.
- */
-o3djs.quaternions.addQuaternionScalar = function(a, b) {
- return a.slice(0, 3).concat(a[3] + b);
-};
-
-/**
- * Adds a scalar to a quaternion.
- * @param {number} a Operand scalar.
- * @param {!o3djs.quaternions.Quaternion} b Operand quaternion.
- * @return {!o3djs.quaternions.Quaternion} The sum of a and b.
- */
-o3djs.quaternions.addScalarQuaternion = function(a, b) {
- return b.slice(0, 3).concat(a + b[3]);
-};
-
-/**
- * Subtracts two quaternions.
- * @param {!o3djs.quaternions.Quaternion} a Operand quaternion.
- * @param {!o3djs.quaternions.Quaternion} b Operand quaternion.
- * @return {!o3djs.quaternions.Quaternion} The difference a - b.
- */
-o3djs.quaternions.subQuaternionQuaternion = function(a, b) {
- return [a[0] - b[0],
- a[1] - b[1],
- a[2] - b[2],
- a[3] - b[3]];
-};
-
-/**
- * Subtracts a scalar from a quaternion.
- * @param {!o3djs.quaternions.Quaternion} a Operand quaternion.
- * @param {number} b Operand scalar.
- * @return {!o3djs.quaternions.Quaternion} The difference a - b.
- */
-o3djs.quaternions.subQuaternionScalar = function(a, b) {
- return a.slice(0, 3).concat(a[3] - b);
-};
-
-/**
- * Subtracts a quaternion from a scalar.
- * @param {number} a Operand scalar.
- * @param {!o3djs.quaternions.Quaternion} b Operand quaternion.
- * @return {!o3djs.quaternions.Quaternion} The difference a - b.
- */
-o3djs.quaternions.subScalarQuaternion = function(a, b) {
- return [-b[0], -b[1], -b[2], a - b[3]];
-};
-
-/**
- * Multiplies a scalar by a quaternion.
- * @param {number} k The scalar.
- * @param {!o3djs.quaternions.Quaternion} q The quaternion.
- * @return {!o3djs.quaternions.Quaternion} The product of k and q.
- */
-o3djs.quaternions.mulScalarQuaternion = function(k, q) {
- return [k * q[0], k * q[1], k * q[2], k * q[3]];
-};
-
-/**
- * Multiplies a quaternion by a scalar.
- * @param {!o3djs.quaternions.Quaternion} q The Quaternion.
- * @param {number} k The scalar.
- * @return {!o3djs.quaternions.Quaternion} The product of k and v.
- */
-o3djs.quaternions.mulQuaternionScalar = function(q, k) {
- return [k * q[0], k * q[1], k * q[2], k * q[3]];
-};
-
-/**
- * Multiplies two quaternions.
- * @param {!o3djs.quaternions.Quaternion} a Operand quaternion.
- * @param {!o3djs.quaternions.Quaternion} b Operand quaternion.
- * @return {!o3djs.quaternions.Quaternion} The quaternion product a * b.
- */
-o3djs.quaternions.mulQuaternionQuaternion = function(a, b) {
- var aX = a[0];
- var aY = a[1];
- var aZ = a[2];
- var aW = a[3];
- var bX = b[0];
- var bY = b[1];
- var bZ = b[2];
- var bW = b[3];
-
- return [
- aW * bX + aX * bW + aY * bZ - aZ * bY,
- aW * bY + aY * bW + aZ * bX - aX * bZ,
- aW * bZ + aZ * bW + aX * bY - aY * bX,
- aW * bW - aX * bX - aY * bY - aZ * bZ];
-};
-
-/**
- * Divides two quaternions; assumes the convention that a/b = a*(1/b).
- * @param {!o3djs.quaternions.Quaternion} a Operand quaternion.
- * @param {!o3djs.quaternions.Quaternion} b Operand quaternion.
- * @return {!o3djs.quaternions.Quaternion} The quaternion quotient a / b.
- */
-o3djs.quaternions.divQuaternionQuaternion = function(a, b) {
- var aX = a[0];
- var aY = a[1];
- var aZ = a[2];
- var aW = a[3];
- var bX = b[0];
- var bY = b[1];
- var bZ = b[2];
- var bW = b[3];
-
- var d = 1 / (bW * bW + bX * bX + bY * bY + bZ * bZ);
- return [
- (aX * bW - aW * bX - aY * bZ + aZ * bY) * d,
- (aX * bZ - aW * bY + aY * bW - aZ * bX) * d,
- (aY * bX + aZ * bW - aW * bZ - aX * bY) * d,
- (aW * bW + aX * bX + aY * bY + aZ * bZ) * d];
-};
-
-/**
- * Divides a Quaternion by a scalar.
- * @param {!o3djs.quaternions.Quaternion} q The quaternion.
- * @param {number} k The scalar.
- * @return {!o3djs.quaternions.Quaternion} q The quaternion q divided by k.
- */
-o3djs.quaternions.divQuaternionScalar = function(q, k) {
- return [q[0] / k, q[1] / k, q[2] / k, q[3] / k];
-};
-
-/**
- * Divides a scalar by a quaternion.
- * @param {number} a Operand scalar.
- * @param {!o3djs.quaternions.Quaternion} b Operand quaternion.
- * @return {!o3djs.quaternions.Quaternion} The quaternion product.
- */
-o3djs.quaternions.divScalarQuaternion = function(a, b) {
- var b0 = b[0];
- var b1 = b[1];
- var b2 = b[2];
- var b3 = b[3];
-
- var d = 1 / (b0 * b0 + b1 * b1 + b2 * b2 + b3 * b3);
- return [-a * b0 * d, -a * b1 * d, -a * b2 * d, a * b3 * d];
-};
-
-/**
- * Computes the multiplicative inverse of a quaternion.
- * @param {!o3djs.quaternions.Quaternion} q The quaternion.
- * @return {!o3djs.quaternions.Quaternion} The multiplicative inverse of q.
- */
-o3djs.quaternions.inverse = function(q) {
- var q0 = q[0];
- var q1 = q[1];
- var q2 = q[2];
- var q3 = q[3];
-
- var d = 1 / (q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
- return [-q0 * d, -q1 * d, -q2 * d, q3 * d];
-};
-
-/**
- * Multiplies two objects which are either scalars or quaternions.
- * @param {(!o3djs.quaternions.Quaternion|number)} a Operand.
- * @param {(!o3djs.quaternions.Quaternion|number)} b Operand.
- * @return {(!o3djs.quaternions.Quaternion|number)} The product of a and b.
- */
-o3djs.quaternions.mul = function(a, b) {
- return o3djs.quaternions['mul' + o3djs.quaternions.mathType(a) +
- o3djs.quaternions.mathType(b)](a, b);
-};
-
-/**
- * Divides two objects which are either scalars or quaternions.
- * @param {(!o3djs.quaternions.Quaternion|number)} a Operand.
- * @param {(!o3djs.quaternions.Quaternion|number)} b Operand.
- * @return {(!o3djs.quaternions.Quaternion|number)} The quotient of a and b.
- */
-o3djs.quaternions.div = function(a, b) {
- return o3djs.quaternions['div' + o3djs.quaternions.mathType(a) +
- o3djs.quaternions.mathType(b)](a, b);
-};
-
-/**
- * Adds two objects which are either scalars or quaternions.
- * @param {(!o3djs.quaternions.Quaternion|number)} a Operand.
- * @param {(!o3djs.quaternions.Quaternion|number)} b Operand.
- * @return {(!o3djs.quaternions.Quaternion|number)} The sum of a and b.
- */
-o3djs.quaternions.add = function(a, b) {
- return o3djs.quaternions['add' + o3djs.quaternions.mathType(a) +
- o3djs.quaternions.mathType(b)](a, b);
-};
-
-/**
- * Subtracts two objects which are either scalars or quaternions.
- * @param {(!o3djs.quaternions.Quaternion|number)} a Operand.
- * @param {(!o3djs.quaternions.Quaternion|number)} b Operand.
- * @return {(!o3djs.quaternions.Quaternion|number)} The difference of a and b.
- */
-o3djs.quaternions.sub = function(a, b) {
- return o3djs.quaternions['sub' + o3djs.quaternions.mathType(a) +
- o3djs.quaternions.mathType(b)](a, b);
-};
-
-/**
- * Computes the length of a Quaternion, i.e. the square root of the
- * sum of the squares of the coefficients.
- * @param {!o3djs.quaternions.Quaternion} a The Quaternion.
- * @return {number} The length of a.
- */
-o3djs.quaternions.length = function(a) {
- return Math.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3]);
-};
-
-/**
- * Computes the square of the length of a quaternion, i.e. the sum of the
- * squares of the coefficients.
- * @param {!o3djs.quaternions.Quaternion} a The quaternion.
- * @return {number} The square of the length of a.
- */
-o3djs.quaternions.lengthSquared = function(a) {
- return a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3];
-};
-
-/**
- * Divides a Quaternion by its length and returns the quotient.
- * @param {!o3djs.quaternions.Quaternion} a The Quaternion.
- * @return {!o3djs.quaternions.Quaternion} A unit length quaternion pointing in
- * the same direction as a.
- */
-o3djs.quaternions.normalize = function(a) {
- var d = 1 / Math.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3]);
- return [a[0] * d, a[1] * d, a[2] * d, a[3] * d];
-};
-
-/**
- * Computes the conjugate of the given quaternion.
- * @param {!o3djs.quaternions.Quaternion} q The quaternion.
- * @return {!o3djs.quaternions.Quaternion} The conjugate of q.
- */
-o3djs.quaternions.conjugate = function(q) {
- return [-q[0], -q[1], -q[2], q[3]];
-};
-
-
-/**
- * Creates a quaternion which rotates around the x-axis by the given angle.
- * @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.quaternions.Quaternion} The quaternion.
- */
-o3djs.quaternions.rotationX = function(angle) {
- return [Math.sin(angle / 2), 0, 0, Math.cos(angle / 2)];
-};
-
-/**
- * Creates a quaternion which rotates around the y-axis by the given angle.
- * @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.quaternions.Quaternion} The quaternion.
- */
-o3djs.quaternions.rotationY = function(angle) {
- return [0, Math.sin(angle / 2), 0, Math.cos(angle / 2)];
-};
-
-/**
- * Creates a quaternion which rotates around the z-axis by the given angle.
- * @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.quaternions.Quaternion} The quaternion.
- */
-o3djs.quaternions.rotationZ = function(angle) {
- return [0, 0, Math.sin(angle / 2), Math.cos(angle / 2)];
-};
-
-/**
- * Creates a quaternion which rotates around the given axis by the given
- * angle.
- * @param {!o3djs.math.Vector3} axis The axis about which to rotate.
- * @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.quaternions.Quaternion} A quaternion which rotates angle
- * radians around the axis.
- */
-o3djs.quaternions.axisRotation = function(axis, angle) {
- var d = 1 / Math.sqrt(axis[0] * axis[0] +
- axis[1] * axis[1] +
- axis[2] * axis[2]);
- var sin = Math.sin(angle / 2);
- var cos = Math.cos(angle / 2);
- return [sin * axis[0] * d, sin * axis[1] * d, sin * axis[2] * d, cos];
-};
-
-/**
- * Computes a 4-by-4 rotation matrix (with trivial translation component)
- * given a quaternion. We assume the convention that to rotate a vector v by
- * a quaternion r means to express that vector as a quaternion q by letting
- * q = [v[0], v[1], v[2], 0] and then obtain the rotated vector by evaluating
- * the expression (r * q) / r.
- * @param {!o3djs.quaternions.Quaternion} q The quaternion.
- * @return {!o3djs.math.Matrix4} A 4-by-4 rotation matrix.
- */
-o3djs.quaternions.quaternionToRotation = function(q) {
- var qX = q[0];
- var qY = q[1];
- var qZ = q[2];
- var qW = q[3];
-
- var qWqW = qW * qW;
- var qWqX = qW * qX;
- var qWqY = qW * qY;
- var qWqZ = qW * qZ;
- var qXqW = qX * qW;
- var qXqX = qX * qX;
- var qXqY = qX * qY;
- var qXqZ = qX * qZ;
- var qYqW = qY * qW;
- var qYqX = qY * qX;
- var qYqY = qY * qY;
- var qYqZ = qY * qZ;
- var qZqW = qZ * qW;
- var qZqX = qZ * qX;
- var qZqY = qZ * qY;
- var qZqZ = qZ * qZ;
-
- var d = qWqW + qXqX + qYqY + qZqZ;
-
- return o3djs.math.makeMatrix4(
- (qWqW + qXqX - qYqY - qZqZ) / d,
- 2 * (qWqZ + qXqY) / d,
- 2 * (qXqZ - qWqY) / d, 0,
- 2 * (qXqY - qWqZ) / d,
- (qWqW - qXqX + qYqY - qZqZ) / d,
- 2 * (qWqX + qYqZ) / d, 0,
- 2 * (qWqY + qXqZ) / d,
- 2 * (qYqZ - qWqX) / d,
- (qWqW - qXqX - qYqY + qZqZ) / d, 0,
- 0, 0, 0, 1);
-};
-
-/**
- * Computes a quaternion whose rotation is equivalent to the given matrix.
- * Based on an algorithm from Shoemake SIGGRAPH 1987.
- * @param {(!o3djs.math.Matrix4|!o3djs.math.Matrix3)} m A 3-by-3 or 4-by-4
- * rotation matrix.
- * @return {!o3djs.quaternions.Quaternion} A quaternion q such that
- * quaternions.quaternionToRotation(q) is m.
- */
-o3djs.quaternions.rotationToQuaternion = function(m) {
- var u;
- var v;
- var w;
-
- var q = [];
- var m0,m1,m2;
- if (m.length==9) {
- m0 = [m[0], m[1], m[2]];
- m1 = [m[3], m[4], m[5]];
- m2 = [m[6], m[7], m[8]];
- }else {
- m0 = [m[0], m[1], m[2]];
- m1 = [m[4], m[5], m[6]];
- m2 = [m[8], m[9], m[10]];
- }
-
- var m00 = m0[0];
- var m11 = m1[1];
- var m22 = m2[2];
-
- var trace = m00 + m11 + m22;
-
- if (trace > 0) {
- var r = Math.sqrt(1 + trace);
- var k = 0.5 / r;
- return [(m1[2] - m2[1]) * k,
- (m2[0] - m0[2]) * k,
- (m0[1] - m1[0]) * k,
- 0.5 * r];
- }
-
- var mu;
- var mv;
- var mw;
-
- // Choose u, v, and w such that u is the index of the biggest diagonal entry
- // of m, and u v w is an even permutation of 0 1 and 2.
- if (m00 > m11 && m00 > m22) {
- u = 0;
- mu = m0;
- v = 1;
- mv = m1;
- w = 2;
- mw = m2;
- } else if (m11 > m00 && m11 > m22) {
- u = 1;
- mu = m1;
- v = 2;
- mv = m2;
- w = 0;
- mw = m0;
- } else {
- u = 2;
- mu = m2;
- v = 0;
- mv = m0;
- w = 1;
- mw = m1;
- }
-
- var r = Math.sqrt(1 + mu[u] - mv[v] - mw[w]);
- var k = 0.5 / r;
- q[u] = 0.5 * r;
- q[v] = (mv[u] + mu[v]) * k;
- q[w] = (mu[w] + mw[u]) * k;
- q[3] = (mv[w] - mw[v]) * k;
-
- return q;
-};
-
diff --git a/o3d/samples/o3djs/rendergraph.js b/o3d/samples/o3djs/rendergraph.js
deleted file mode 100644
index 2457004..0000000
--- a/o3d/samples/o3djs/rendergraph.js
+++ /dev/null
@@ -1,580 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains various functions for helping create
- * render graphs for o3d. It puts them in the "rendergraph" module on
- * the o3djs object.
- *
- * Note: This library is only a sample. It is not meant to be some official
- * library. It is provided only as example code.
- *
- */
-
-o3djs.provide('o3djs.rendergraph');
-
-/**
- * A Module for creating render graphs.
- * @namespace
- */
-o3djs.rendergraph = o3djs.rendergraph || {};
-
-/**
- * Creates a basic render graph setup to draw opaque and transparent
- * 3d objects.
- * @param {!o3d.Pack} pack Pack to manage created objects.
- * @param {!o3d.Transform} treeRoot root Transform of tree to render.
- * @param {!o3d.RenderNode} opt_parent RenderNode to build this view under.
- * @param {!o3djs.math.Vector4} opt_clearColor color to clear view.
- * @param {number} opt_priority Optional base priority for created objects.
- * @param {!o3djs.math.Vector4} opt_viewport viewport settings for view.
- * @param {!o3d.DrawList} opt_performanceDrawList Optional DrawList to
- * use for performanceDrawPass.
- * @param {!o3d.DrawList} opt_zOrderedDrawList Optional DrawList to
- * use for zOrderedDrawPass.
- * @param {!o3d.DrawContext} opt_drawContext Optional DrawContext to
- * use. If not passed in one is created.
- * @return {!o3djs.rendergraph.ViewInfo} A ViewInfo object with info about
- * everything created.
- */
-o3djs.rendergraph.createView = function(pack,
- treeRoot,
- opt_parent,
- opt_clearColor,
- opt_priority,
- opt_viewport,
- opt_performanceDrawList,
- opt_zOrderedDrawList,
- opt_drawContext) {
- return new o3djs.rendergraph.ViewInfo(pack,
- treeRoot,
- opt_parent,
- opt_clearColor,
- opt_priority,
- opt_viewport,
- opt_performanceDrawList,
- opt_zOrderedDrawList,
- opt_drawContext);
-};
-
-/**
- * Creates a basic render graph setup to draw opaque and transparent
- * 3d objects.
- * @param {!o3d.Pack} pack Pack to manage created objects.
- * @param {!o3d.Transform} treeRoot root Transform of tree to render.
- * @param {!o3d.RenderNode} opt_parent RenderNode to build this view under.
- * @param {!o3djs.math.Vector4} opt_clearColor color to clear view.
- * @param {number} opt_priority Optional base priority for created objects.
- * @param {!o3djs.math.Vector4} opt_viewport viewport settings for view.
- * @return {!o3djs.rendergraph.ViewInfo} A ViewInfo object with info about
- * everything created.
- */
-o3djs.rendergraph.createBasicView = function(pack,
- treeRoot,
- opt_parent,
- opt_clearColor,
- opt_priority,
- opt_viewport) {
- return o3djs.rendergraph.createView(pack,
- treeRoot,
- opt_parent,
- opt_clearColor,
- opt_priority,
- opt_viewport);
-};
-
-/**
- * Creates an extra view render graph setup to draw opaque and transparent
- * 3d objects based on a previously created view. It uses the previous view
- * to share draw lists and to set the priority.
- * @param {!o3djs.rendergraph.ViewInfo} viewInfo ViewInfo returned from
- * createBasicView.
- * @param {!o3djs.math.Vector4} opt_viewport viewport settings for view.
- * @param {!o3djs.math.Vector4} opt_clearColor color to clear view.
- * @param {number} opt_priority base priority for created objects.
- * @return {!o3djs.rendergraph.ViewInfo} A ViewInfo object with info about
- * everything created.
- */
-o3djs.rendergraph.createExtraView = function(viewInfo,
- opt_viewport,
- opt_clearColor,
- opt_priority) {
- return o3djs.rendergraph.createView(viewInfo.pack,
- viewInfo.treeRoot,
- viewInfo.renderGraphRoot,
- opt_clearColor,
- opt_priority,
- opt_viewport,
- viewInfo.performanceDrawList,
- viewInfo.zOrderedDrawList);
-};
-
-/**
- * A ViewInfo object creates the standard o3d objects needed for
- * a single 3d view. Those include a ClearBuffer followed by a TreeTraveral
- * followed by 2 DrawPasses all of which are children of a Viewport. On top of
- * those a DrawContext and optionally 2 DrawLists although you can pass in your
- * own DrawLists if there is a reason to reuse the same DrawLists such was with
- * mulitple views of the same scene.
- *
- * The render graph created is something like:
- * <pre>
- * [Viewport]
- * |
- * +------+--------+------------------+---------------------+
- * | | | |
- * [ClearBuffer] [TreeTraversal] [Performance StateSet] [ZOrdered StateSet]
- * | |
- * [Performance DrawPass] [ZOrdered DrawPass]
- * </pre>
- *
- * @constructor
- * @param {!o3d.Pack} pack Pack to manage created objects.
- * @param {!o3d.Transform} treeRoot root Transform of tree to render.
- * @param {!o3d.RenderNode} opt_parent RenderNode to build this view under.
- * @param {!o3djs.math.Vector4} opt_clearColor color to clear view.
- * @param {number} opt_priority Optional base priority for created objects.
- * @param {!o3djs.math.Vector4} opt_viewport viewport settings for view.
- * @param {!o3d.DrawList} opt_performanceDrawList DrawList to use for
- * performanceDrawPass.
- * @param {!o3d.DrawList} opt_zOrderedDrawList DrawList to use for
- * zOrderedDrawPass.
- * @param {!o3d.DrawContext} opt_drawContext Optional DrawContext to
- * use. If not passed in one is created.
- */
-o3djs.rendergraph.ViewInfo = function(pack,
- treeRoot,
- opt_parent,
- opt_clearColor,
- opt_priority,
- opt_viewport,
- opt_performanceDrawList,
- opt_zOrderedDrawList,
- opt_drawContext) {
- var that = this;
- var clearColor = opt_clearColor || [0.5, 0.5, 0.5, 1.0];
- var viewPriority = opt_priority || 0;
- var priority = 0;
-
- // Create Viewport.
- var viewport = pack.createObject('Viewport');
- if (opt_viewport) {
- viewport.viewport = opt_viewport;
- }
- viewport.priority = viewPriority;
-
- // Create a clear buffer.
- var clearBuffer = pack.createObject('ClearBuffer');
- clearBuffer.clearColor = clearColor;
- clearBuffer.priority = priority++;
- clearBuffer.parent = viewport;
-
- // Creates a TreeTraversal and parents it to the root.
- var treeTraversal = pack.createObject('TreeTraversal');
- treeTraversal.priority = priority++;
- treeTraversal.parent = viewport;
- treeTraversal.transform = treeRoot;
-
- this.drawPassInfos_ = [];
-
- /**
- * Pack that manages the objects created for this ViewInfo.
- * @type {!o3d.Pack}
- */
- this.pack = pack;
-
- /**
- * The RenderNode this ViewInfo render graph subtree is parented under.
- * @type {(!o3d.RenderNode|undefined)}
- */
- this.renderGraphRoot = opt_parent;
-
- /**
- * The root node of the transform graph this ViewInfo renders.
- * @type {!o3d.Transform}
- */
- this.treeRoot = treeRoot;
-
- /**
- * The root of the subtree of the render graph this ViewInfo is managing.
- * If you want to set the priority of a ViewInfo's rendergraph subtree use
- * <pre>
- * viewInfo.root.priority = desiredPriority;
- * </pre>
- * @type {!o3d.RenderNode}
- */
- this.root = viewport;
-
- /**
- * The Viewport RenderNode created for this ViewInfo.
- * @type {!o3d.Viewport}
- */
- this.viewport = viewport;
-
- /**
- * The ClearBuffer RenderNode created for this ViewInfo.
- * @type {!o3d.ClearBuffer}
- */
- this.clearBuffer = clearBuffer;
-
- // Create DrawContext.
- var drawContext = opt_drawContext || pack.createObject('DrawContext');
-
- /**
- * The DrawContext used by this ViewInfo.
- * @type {!o3d.DrawContext}
- */
- this.drawContext = drawContext;
-
- /**
- * The TreeTraversal used by this ViewInfo.
- * @type {!o3d.TreeTraversal}
- */
- this.treeTraversal = treeTraversal;
-
- /**
- * The highest priority used for objects under the Viewport RenderNode created
- * by this ViewInfo.
- * @type {number}
- */
- this.priority = priority;
-
- /**
- * This function is here just because the inside use case of
- * ViewInfo.createDrawPass is the less common case.
- * @param {o3d.DrawList.SortMethod} sortMethod how to sort.
- * @param {!o3d.DrawList} opt_drawList DrawList to use.
- */
- function createDrawPass(sortMethod, opt_drawList) {
- return that.createDrawPass(
- sortMethod,
- undefined,
- undefined,
- undefined,
- opt_drawList);
- }
-
- // Setup a Performance Ordered DrawPass
- var performanceDrawPassInfo = createDrawPass(
- o3djs.base.o3d.DrawList.BY_PERFORMANCE,
- opt_performanceDrawList);
-
- var performanceState = performanceDrawPassInfo.state;
-
- // Setup a z Ordered DrawPass
- var zOrderedDrawPassInfo = createDrawPass(
- o3djs.base.o3d.DrawList.BY_Z_ORDER,
- opt_zOrderedDrawList);
-
- var zOrderedState = zOrderedDrawPassInfo.state;
-
- zOrderedState.getStateParam('AlphaBlendEnable').value = true;
- zOrderedState.getStateParam('SourceBlendFunction').value =
- o3djs.base.o3d.State.BLENDFUNC_SOURCE_ALPHA;
- zOrderedState.getStateParam('DestinationBlendFunction').value =
- o3djs.base.o3d.State.BLENDFUNC_INVERSE_SOURCE_ALPHA;
- zOrderedState.getStateParam('AlphaTestEnable').value = true;
- zOrderedState.getStateParam('AlphaComparisonFunction').value =
- o3djs.base.o3d.State.CMP_GREATER;
-
- // Parent whatever the root is to the parent passed in.
- if (opt_parent) {
- this.root.parent = opt_parent;
- }
-
- /**
- * The DrawPassInfo for the performance draw pass.
- * @type {!o3djs.rendergraph.DrawPassInfo}
- */
- this.performanceDrawPassInfo = performanceDrawPassInfo;
-
- /**
- * The DrawPassInfo for the zOrdered draw pass.
- * @type {!o3djs.rendergraph.DrawPassInfo}
- */
- this.zOrderedDrawPassInfo = zOrderedDrawPassInfo;
-
- // Legacy properties
-
- /**
- * The StateSet RenderNode above the performance DrawPass in this ViewInfo
- * @type {!o3d.StateSet}
- */
- this.performanceStateSet = performanceDrawPassInfo.stateSet;
-
- /**
- * The State object used by the performanceStateSet object in this ViewInfo.
- * By default, no states are set here.
- * @type {!o3d.State}
- */
- this.performanceState = performanceState;
-
- /**
- * The DrawList used for the performance draw pass. Generally for opaque
- * materials.
- * @type {!o3d.DrawList}
- */
- this.performanceDrawList = performanceDrawPassInfo.drawList;
-
- /**
- * The StateSet RenderNode above the ZOrdered DrawPass in this ViewInfo
- * @type {!o3d.StateSet}
- */
- this.zOrderedStateSet = zOrderedDrawPassInfo.stateSet;
-
- /**
- * The State object used by the zOrderedStateSet object in this ViewInfo.
- * By default AlphaBlendEnable is set to true, SourceBlendFucntion is set to
- * State.BLENDFUNC_SOURCE_ALPHA and DestinationBlendFunction is set to
- * State.BLENDFUNC_INVERSE_SOURCE_ALPHA
- * @type {!o3d.State}
- */
- this.zOrderedState = zOrderedState;
-
- /**
- * The DrawList used for the zOrdered draw pass. Generally for transparent
- * materials.
- * @type {!o3d.DrawList}
- */
- this.zOrderedDrawList = zOrderedDrawPassInfo.drawList;
-
- /**
- * The DrawPass used with the performance DrawList created by this ViewInfo.
- * @type {!o3d.DrawPass}
- */
- this.performanceDrawPass = performanceDrawPassInfo.drawPass;
-
- /**
- * The DrawPass used with the zOrdered DrawList created by this ViewInfo.
- * @type {!o3d.DrawPass}
- */
- this.zOrderedDrawPass = zOrderedDrawPassInfo.drawPass;
-
- /**
- * A flag whether or not we created the DrawContext for this DrawPassInfo.
- * @private
- * @type {boolean}
- */
- this.ownDrawContext_ = opt_drawContext ? false : true;
-};
-
-/**
- * Destroys the various objects created for the view.
- *
- * @param {boolean} opt_destroyDrawContext True if you want view's DrawContext
- * destroyed. Default = true.
- * @param {boolean} opt_destroyDrawList True if you want view's DrawLists
- * destroyed. Default = true.
- */
-o3djs.rendergraph.ViewInfo.prototype.destroy = function(
- opt_destroyDrawContext,
- opt_destroyDrawList) {
- if (opt_destroyDrawContext === undefined) {
- opt_destroyDrawContext = true;
- }
-
- for (var ii = 0; ii < this.drawPassInfos_.length; ++ii) {
- this.drawPassInfos_[ii].destroy();
- }
-
- // Remove everything we created from the pack.
- this.pack.removeObject(this.viewport);
- this.pack.removeObject(this.clearBuffer);
- if (opt_destroyDrawContext && this.ownDrawContext_) {
- this.pack.removeObject(this.drawContext);
- }
- this.pack.removeObject(this.treeTraversal);
- // Remove our substree from its parent.
- this.viewport.parent = null;
-
- // At this point, IF nothing else is referencing any of these objects
- // they should get removed.
-};
-
-/**
- * Creates a draw pass in this ViewInfo.
- *
- * @param {o3d.DrawList.SortMethod} sortMethod How to sort this draw pass's
- * DrawElements.
- * @param {!o3d.DrawContext} opt_drawContext The DrawContext for this draw pass.
- * If not passed in the default DrawContext for this ViewInfo will be used.
- * @param {number} opt_priority The priority for this draw pass. If not passed
- * in the priority will be the next priority for this ViewInfo.
- * @param {!o3d.RenderNode} opt_parent The RenderNode to parent this draw pass
- * under. If not passed in the draw pass will be parented under the
- * ViewInfo's viewport RenderNode.
- * @param {!o3d.DrawList} opt_drawList The DrawList for this draw pass. If not
- * passed in one will be created.
- * @return {!o3djs.rendergraph.DrawPassInfo}
- */
-o3djs.rendergraph.ViewInfo.prototype.createDrawPass = function(
- sortMethod,
- opt_drawContext,
- opt_priority,
- opt_parent,
- opt_drawList) {
- opt_drawContext = opt_drawContext || this.drawContext;
- opt_parent = opt_parent || this.viewport;
- opt_priority = (typeof opt_priority !== 'undefined') ? opt_priority :
- this.priority++;
- var drawPassInfo = o3djs.rendergraph.createDrawPassInfo(
- this.pack,
- opt_drawContext,
- sortMethod,
- opt_parent,
- opt_drawList);
- drawPassInfo.root.priority = opt_priority;
- this.treeTraversal.registerDrawList(
- drawPassInfo.drawList, opt_drawContext, true);
-
- this.drawPassInfos_.push(drawPassInfo);
-
- return drawPassInfo;
-};
-
-/**
- * Creates a DrawPassInfo to manage a draw pass.
- *
- * @param {!o3d.Pack} pack Pack to manage created objects.
- * @param {!o3d.DrawContext} drawContext The DrawContext for this draw pass.
- * @param {o3d.DrawList.SortMethod} sortMethod How to sort this draw pass's
- * DrawElements.
- * @param {!o3d.DrawList} opt_drawList The DrawList for this draw pass. If not
- * passed in one will be created.
- * @param {!o3d.RenderNode} opt_parent The RenderNode to parent this draw pass
- * under. If not passed the draw pass will not be parented.
- * @return {!o3djs.rendergraph.DrawPassInfo}
- */
-o3djs.rendergraph.createDrawPassInfo = function(
- pack,
- drawContext,
- sortMethod,
- opt_parent,
- opt_drawList) {
- return new o3djs.rendergraph.DrawPassInfo(
- pack, drawContext, sortMethod, opt_parent, opt_drawList);
-};
-
-/**
- * A class to manage a draw pass.
- * @constructor
- * @param {!o3d.Pack} pack Pack to manage created objects.
- * @param {!o3d.DrawContext} drawContext The DrawContext for this draw pass.
- * @param {o3d.DrawList.SortMethod} sortMethod How to sort this draw pass's
- * DrawElements.
- * @param {!o3d.DrawList} opt_drawList The DrawList for this draw pass. If not
- * passed in one will be created.
- * @param {!o3d.RenderNode} opt_parent The RenderNode to parent this draw pass
- * under. If not passed the draw pass will not be parented.
- * @return {!o3djs.rendergraph.DrawPassInfo}
- */
-o3djs.rendergraph.DrawPassInfo = function(pack,
- drawContext,
- sortMethod,
- opt_parent,
- opt_drawList) {
- var ownDrawList = opt_drawList ? false : true;
-
- opt_parent = opt_parent || null;
- opt_drawList = opt_drawList || pack.createObject('DrawList');
-
- var stateSet = pack.createObject('StateSet');
- var state = pack.createObject('State');
- stateSet.state = state;
- stateSet.parent = opt_parent;
-
- var drawPass = pack.createObject('DrawPass');
- drawPass.drawList = opt_drawList;
- drawPass.sortMethod = sortMethod;
- drawPass.parent = stateSet;
-
- /**
- * The pack managing the objects created for this DrawPassInfo.
- * @type {!o3d.Pack}
- */
- this.pack = pack;
-
- /**
- * The State that affects all things drawn in this DrawPassInfo.
- * @type {!o3d.State}
- */
- this.state = state;
-
- /**
- * The StateSet that applies the state for this DrawPassInfo.
- * @type {!o3d.StateSet}
- */
- this.stateSet = stateSet;
-
- /**
- * The DrawPass for this DrawPassInfo.
- * @type {!o3d.DrawPass}
- */
- this.drawPass = drawPass;
-
- /**
- * The DrawList for this DrawPassInfo.
- * @type {!o3d.DrawList}
- */
- this.drawList = opt_drawList;
-
- /**
- * The root RenderNode of this DrawPassInfo. This is the RenderNdoe you should
- * use if you want to turn this draw pass off or reparent it.
- * @type {!o3d.RenderNode}
- */
- this.root = stateSet;
-
- /**
- * A flag whether or not we created the DrawList for this DrawPassInfo.
- * @private
- * @type {boolean}
- */
- this.ownDrawList_ = ownDrawList;
-};
-
-/**
- * Frees the resources created for this DrawPassInfo.
- */
-o3djs.rendergraph.DrawPassInfo.prototype.destroy = function() {
- // Remove everything we created from the pack.
- if (this.ownDrawList_) {
- this.drawPass.drawList = null;
- this.pack.removeObject(this.drawList);
- }
- this.drawPass.parent = null;
- this.stateSet.parent = null;
- this.pack.removeObject(this.drawPass);
- this.pack.removeObject(this.stateSet);
- this.pack.removeObject(this.state);
-};
-
diff --git a/o3d/samples/o3djs/scene.js b/o3d/samples/o3djs/scene.js
deleted file mode 100644
index c17b517..0000000
--- a/o3d/samples/o3djs/scene.js
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains various functions and classes for dealing
- * with 3d scenes.
- */
-
-o3djs.provide('o3djs.scene');
-
-o3djs.require('o3djs.io');
-o3djs.require('o3djs.serialization');
-
-/**
- * A Module with various scene functions and classes.
- * @namespace
- */
-o3djs.scene = o3djs.scene || {};
-
-/**
- * Loads a scene.
- * @param {!o3d.Client} client An O3D client object.
- * @param {!o3d.Pack} pack Pack to load scene into.
- * @param {!o3d.Transform} parent Transform to parent scene under.
- * @param {string} url URL of scene to load.
- * @param {!function(!o3d.Pack, !o3d.Transform, *): void} callback
- * Callback when scene is loaded. It will be passed the pack, the parent and
- * an exception which is null on success.
- * @param {!o3djs.serialization.Options} opt_options Options passed into the
- * loader.
- * @return {!o3djs.io.LoadInfo} A LoadInfo for tracking progress.
- * @see o3djs.loader.createLoader
- */
-o3djs.scene.loadScene = function(client,
- pack,
- parent,
- url,
- callback,
- opt_options) {
- // Starts the deserializer once the entire archive is available.
- function onFinished(archiveInfo, exception) {
- if (!exception) {
- var finishCallback = function(pack, parent, exception) {
- archiveInfo.destroy();
- callback(pack, parent, exception);
- };
- o3djs.serialization.deserializeArchive(archiveInfo,
- 'scene.json',
- client,
- pack,
- parent,
- finishCallback,
- opt_options);
- } else {
- archiveInfo.destroy();
- callback(pack, parent, exception);
- }
- }
- return o3djs.io.loadArchive(pack, url, onFinished);
-};
-
-
diff --git a/o3d/samples/o3djs/serialization.js b/o3d/samples/o3djs/serialization.js
deleted file mode 100644
index c02e405..0000000
--- a/o3d/samples/o3djs/serialization.js
+++ /dev/null
@@ -1,871 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file provides support for deserializing (loading)
- * transform graphs from JSON files.
- *
- */
-
-o3djs.provide('o3djs.serialization');
-
-o3djs.require('o3djs.math');
-o3djs.require('o3djs.error');
-o3djs.require('o3djs.texture');
-
-/**
- * A Module for deserializing a scene created by the sample o3dConverter.
- * @namespace
- */
-o3djs.serialization = o3djs.serialization || {};
-
-/**
- * The oldest supported version of the serializer. It isn't necessary to
- * increment this version whenever the format changes. Only change it when the
- * deserializer becomes incapable of deserializing an older version.
- * @type {number}
- */
-o3djs.serialization.supportedVersion = 5;
-
-/**
- * These are the values the sample o3dConverter uses to identify curve key
- * types.
- * @type {!Object}
- */
-o3djs.serialization.CURVE_KEY_TYPES = {
- step: 1,
- linear: 2,
- bezier: 3};
-
-/**
- * Options for deserialization.
- *
- * opt_animSource is an optional ParamFloat that will be bound as the source
- * param for all animation time params in the scene. opt_async is a bool that
- * will make the deserialization process async.
- *
- * @type {{opt_animSource: !o3d.ParamFloat, opt_async: boolean}}
- */
-o3djs.serialization.Options = goog.typedef;
-
-/**
- * A Deserializer incrementally deserializes a transform graph.
- * @constructor
- * @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) {
- /**
- * The pack to deserialize into.
- * @type {!o3d.Pack}
- */
- this.pack = pack;
-
- /**
- * An object tree conforming to the JSON rules.
- * @type {!Object}
- */
- this.json = json;
-
- /**
- * The archive from which assets referenced from JSON are retreived.
- * @type {o3djs.io.ArchiveInfo}
- */
- this.archiveInfo = null;
-
- /**
- * Deserializes a Buffer .
- * @param {!o3djs.serialization.Deserializer} deserializer The deserializer.
- * @param {!Object} json The json for this buffer.
- * @param {string} type The type of buffer to create.
- * @param {string} uri The uri of the file containing the binary data.
- */
- function deserializeBuffer(deserializer, json, type, uri) {
- var object = deserializer.pack.createObject(type);
- if ('custom' in json) {
- if ('fieldData' in json.custom) {
- var fieldDataArray = json.custom.fieldData;
- if (fieldDataArray.length > 0) {
- var fields = [];
- // First create all the fields
- for (var ii = 0; ii < fieldDataArray.length; ++ii) {
- var data = fieldDataArray[ii];
- var field = object.createField(data.type, data.numComponents);
- fields.push(field);
- deserializer.addObject(data.id, field);
- }
- var firstData = fieldDataArray[0];
- var numElements = firstData.data.length / firstData.numComponents;
- object.allocateElements(numElements);
- // Now set the data.
- for (var ii = 0; ii < fieldDataArray.length; ++ii) {
- var data = fieldDataArray[ii];
- fields[ii].setAt(0, data.data);
- }
- }
- } else {
- var rawData = deserializer.archiveInfo.getFileByURI(uri);
- object.set(rawData,
- json.custom.binaryRange[0],
- json.custom.binaryRange[1] - json.custom.binaryRange[0]);
- for (var i = 0; i < json.custom.fields.length; ++i) {
- deserializer.addObject(json.custom.fields[i], object.fields[i]);
- }
- }
- }
- return object;
- }
-
- /**
- * A map from classname to a function that will create
- * instances of objects. Add entries to support additional classes.
- * @type {!Object}
- */
- this.createCallbacks = {
- 'o3djs.DestinationBuffer': function(deserializer, json) {
- var object = deserializer.pack.createObject('o3d.VertexBuffer');
- if ('custom' in json) {
- for (var i = 0; i < json.custom.fields.length; ++i) {
- var fieldInfo = json.custom.fields[i]
- var field = object.createField(fieldInfo.type,
- fieldInfo.numComponents);
- deserializer.addObject(fieldInfo.id, field);
- }
- object.allocateElements(json.custom.numElements);
- }
- return object;
- },
-
- 'o3d.VertexBuffer': function(deserializer, json) {
- return deserializeBuffer(
- deserializer, json, 'o3d.VertexBuffer', 'vertex-buffers.bin');
- },
-
- 'o3d.SourceBuffer': function(deserializer, json) {
- return deserializeBuffer(
- deserializer, json, 'o3d.SourceBuffer', 'vertex-buffers.bin');
- },
-
- 'o3d.IndexBuffer': function(deserializer, json) {
- return deserializeBuffer(
- deserializer, json, 'o3d.IndexBuffer', 'index-buffers.bin');
- },
-
- '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';
- }
- return o3djs.texture.createTextureFromRawData(pack, rawData, true);
- } else {
- return deserializer.pack.createTexture2D(
- json.custom.width,
- json.custom.height,
- json.custom.format,
- json.custom.levels,
- json.custom.renderSurfacesEnabled);
- }
- },
-
- 'o3d.TextureCUBE': function(deserializer, json) {
- if ('o3d.negx_uri' in json.params) {
- // Cube map comprised of six separate textures.
- var param_names = [
- 'o3d.posx_uri',
- 'o3d.negx_uri',
- 'o3d.posy_uri',
- 'o3d.negy_uri',
- 'o3d.posz_uri',
- 'o3d.negz_uri'
- ];
- var rawDataArray = [];
- for (var i = 0; i < param_names.length; i++) {
- var uri = json.params[param_names[i]].value;
- var rawData = deserializer.archiveInfo.getFileByURI(uri);
- if (!rawData) {
- throw 'Could not find texture ' + uri + ' in the archive';
- }
- rawDataArray.push(rawData);
- }
- // Cube map faces should not be flipped.
- return o3djs.texture.createTextureFromRawDataArray(
- pack, rawDataArray, true, false);
- } else 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';
- }
- return o3djs.texture.createTextureFromRawData(pack, rawData, true);
- } else {
- return deserializer.pack.createTextureCUBE(
- json.custom.edgeLength,
- json.custom.format,
- json.custom.levels,
- json.custom.renderSurfacesEnabled);
- }
- }
- };
-
- /**
- * A map from classname to a function that will initialize
- * instances of the given class from JSON data. Add entries to support
- * additional classes.
- * @type {!Object}
- */
- this.initCallbacks = {
- 'o3d.Curve': function(deserializer, object, json) {
- if ('custom' in json) {
- if ('keys' in json.custom) {
- var keys = json.custom.keys;
- var stepType = o3djs.serialization.CURVE_KEY_TYPES.step;
- var linearType = o3djs.serialization.CURVE_KEY_TYPES.linear;
- var bezierType = o3djs.serialization.CURVE_KEY_TYPES.bezier;
- for (var ii = 0; ii < keys.length; ++ii) {
- var key = keys[ii];
- switch (key[0]) {
- case stepType: // Step
- object.addStepKeys(key.slice(1));
- break;
- case linearType: // Linear
- object.addLinearKeys(key.slice(1));
- break;
- case bezierType: // Bezier
- object.addBezierKeys(key.slice(1));
- break;
- }
- }
- } else {
- var rawData = deserializer.archiveInfo.getFileByURI('curve-keys.bin');
- object.set(rawData,
- json.custom.binaryRange[0],
- json.custom.binaryRange[1] - json.custom.binaryRange[0]);
- }
- }
- },
-
- 'o3d.Effect': function(deserializer, object, json) {
- var uriParam = object.getParam('o3d.uri');
- if (uriParam) {
- var rawData = deserializer.archiveInfo.getFileByURI(uriParam.value);
- if (!rawData) {
- throw 'Cannot find shader ' + uriParam.value + ' in archive.';
- }
- if (!object.loadFromFXString(rawData.stringValue)) {
- throw 'Cannot load shader ' + uriParam.value + ' in archive.';
- }
- }
- },
-
- 'o3d.Skin': function(deserializer, object, json) {
- if ('custom' in json) {
- if ('binaryRange' in json.custom) {
- var rawData = deserializer.archiveInfo.getFileByURI('skins.bin');
- object.set(rawData,
- json.custom.binaryRange[0],
- json.custom.binaryRange[1] - json.custom.binaryRange[0]);
- }
- }
- },
-
- 'o3d.SkinEval': function(deserializer, object, 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);
- object.setVertexStream(streamJson.stream.semantic,
- streamJson.stream.semanticIndex,
- field,
- streamJson.stream.startIndex);
- if ('bind' in streamJson) {
- var source = deserializer.getObjectById(streamJson.bind);
- object.bindStream(source,
- streamJson.stream.semantic,
- streamJson.stream.semanticIndex);
- }
- }
- }
- },
-
- 'o3d.StreamBank': function(deserializer, object, 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);
- object.setVertexStream(streamJson.stream.semantic,
- streamJson.stream.semanticIndex,
- field,
- streamJson.stream.startIndex);
- if ('bind' in streamJson) {
- var source = deserializer.getObjectById(streamJson.bind);
- object.bindStream(source,
- streamJson.stream.semantic,
- streamJson.stream.semanticIndex);
- }
- }
- }
- }
- };
-
- if (!('version' in json)) {
- throw 'Version in JSON file was missing.';
- }
-
- if (json.version < o3djs.serialization.supportedVersion) {
- throw 'Version in JSON file was ' + json.version +
- ' but expected at least version ' +
- o3djs.serialization.supportedVersion + '.';
- }
-
- if (!('objects' in json)) {
- throw 'Objects array in JSON file was missing.';
- }
-
- /**
- * An array of all objects deserialized so far, indexed by object id. Id zero
- * means null.
- * @type {!Array.<(Object|undefined)>}
- * @private
- */
- this.objectsById_ = [null];
-
- /**
- * An array of objects deserialized so far, indexed by position in the JSON.
- * @type {!Array.<Object>}
- * @private
- */
- this.objectsByIndex_ = [];
-
- /**
- * Array of all classes present in the JSON.
- * @type {!Array.<string>}
- * @private
- */
- this.classNames_ = [];
- for (var className in json.objects) {
- this.classNames_.push(className);
- }
-
- /**
- * The current phase_ of deserialization. In phase_ 0, objects
- * are created and their ids registered. In phase_ 1, objects are
- * initialized from JSON data.
- * @type {number}
- * @private
- */
- this.phase_ = 0;
-
- /**
- * Index of the next class to be deserialized in classNames_.
- * @type {number}
- * @private
- */
- this.nextClassIndex_ = 0;
-
- /**
- * Index of the next object of the current class to be deserialized.
- * @type {number}
- * @private
- */
- this.nextObjectIndex_ = 0;
-
- /**
- * Index of the next object to be deserialized in objectsByIndex_.
- * @type {number}
- * @private
- */
- this.globalObjectIndex_ = 0;
-};
-
-/**
- * Get the object with the given id.
- * @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];
-};
-
-/**
- * When a creation or init callback creates an object that the Deserializer
- * is not aware of, it can associate it with an id using this function, so that
- * references to the object can be resolved.
- * @param {number} id The is of the object.
- * @param {!Object} object The object to register.
- */
-o3djs.serialization.Deserializer.prototype.addObject = function(
- id, object) {
- this.objectsById_[id] = object;
-};
-
-/**
- * Deserialize a value. Identifies reference values and converts
- * their object id into an object reference. Otherwise returns the
- * value unchanged.
- * @param {*} valueJson The JSON representation of the value.
- * @return {*} The JavaScript representation of the value.
- */
-o3djs.serialization.Deserializer.prototype.deserializeValue = function(
- valueJson) {
- if (typeof(valueJson) === 'object') {
- if (valueJson === null) {
- return null;
- }
-
- var valueAsObject = /** @type {!Object} */ (valueJson);
- if ('length' in valueAsObject) {
- for (var i = 0; i != valueAsObject.length; ++i) {
- valueAsObject[i] = this.deserializeValue(valueAsObject[i]);
- }
- if (o3djs.math.usePluginMath_) {
- return valueAsObject;
- }
- return o3djs.serialization.fixMatrices(valueAsObject);
- }
-
- var refId = valueAsObject['ref'];
- if (refId !== undefined) {
- var referenced = this.objectsById_[refId];
- if (referenced === undefined) {
- throw 'Could not find object with id ' + refId + '.';
- }
- return referenced;
- }
- }
-
- return valueJson;
-};
-
-/**
- * Sets the value of a param on an object or binds a param to another.
- * @param {!Object} object The object holding the param.
- * @param {(string|number)} paramName The name of the param.
- * @param {!Object} propertyJson The JSON representation of the value.
- * @private
- */
-o3djs.serialization.Deserializer.prototype.setParamValue_ = function(
- object, paramName, propertyJson) {
- var param = object.getParam(paramName);
- if (param === null)
- return;
-
- var valueJson = propertyJson['value'];
- if (valueJson !== undefined) {
- param.value = this.deserializeValue(valueJson);
- }
-
- var bindId = propertyJson['bind'];
- if (bindId !== undefined) {
- var referenced = this.objectsById_[bindId];
- if (referenced === undefined) {
- throw 'Could not find output param with id ' + bindId + '.';
- }
- param.bind(referenced);
- }
-};
-
-/**
- * Creates a param on an object and adds it's id so that other objects can
- * reference it.
- * @param {!Object} object The object to hold the param.
- * @param {(string|number)} paramName The name of the param.
- * @param {!Object} propertyJson The JSON representation of the value.
- * @private
- */
-o3djs.serialization.Deserializer.prototype.createAndIdentifyParam_ =
- function(object, paramName, propertyJson) {
- var propertyClass = propertyJson['class'];
- var param;
- if (propertyClass !== undefined) {
- param = object.createParam(paramName, propertyClass);
- } else {
- param = object.getParam(paramName);
- }
-
- var paramId = propertyJson['id'];
- if (paramId !== undefined && param !== null) {
- this.objectsById_[paramId] = param;
- }
-};
-
-/**
- * First pass: create all objects and additional params. We need two
- * passes to support references to objects that appear later in the
- * JSON.
- * @param {number} amountOfWork The number of loop iterations to perform of
- * this phase_.
- * @private
- */
-o3djs.serialization.Deserializer.prototype.createObjectsPhase_ =
- function(amountOfWork) {
- for (; this.nextClassIndex_ < this.classNames_.length;
- ++this.nextClassIndex_) {
- var className = this.classNames_[this.nextClassIndex_];
- var classJson = this.json.objects[className];
- var numObjects = classJson.length;
- for (; this.nextObjectIndex_ < numObjects; ++this.nextObjectIndex_) {
- if (amountOfWork-- <= 0)
- return;
-
- var objectJson = classJson[this.nextObjectIndex_];
- var object = undefined;
- if ('id' in objectJson) {
- object = this.objectsById_[objectJson.id];
- }
- if (object === undefined) {
- if (className in this.createCallbacks) {
- object = this.createCallbacks[className](this, objectJson);
- } else {
- object = this.pack.createObject(className);
- }
- }
- this.objectsByIndex_[this.globalObjectIndex_++] = object;
- if ('id' in objectJson) {
- this.objectsById_[objectJson.id] = object;
- }
- if ('params' in objectJson) {
- if ('length' in objectJson.params) {
- for (var paramIndex = 0; paramIndex != objectJson.params.length;
- ++paramIndex) {
- var paramJson = objectJson.params[paramIndex];
- this.createAndIdentifyParam_(object, paramIndex,
- paramJson);
- }
- } else {
- for (var paramName in objectJson.params) {
- var paramJson = objectJson.params[paramName];
- this.createAndIdentifyParam_(object, paramName, paramJson);
- }
- }
- }
- }
- this.nextObjectIndex_ = 0;
- }
-
- if (this.nextClassIndex_ === this.classNames_.length) {
- this.nextClassIndex_ = 0;
- this.nextObjectIndex_ = 0;
- this.globalObjectIndex_ = 0;
- ++this.phase_;
- }
-};
-
-/**
- * Second pass: set property and parameter values and bind parameters.
- * @param {number} amountOfWork The number of loop iterations to perform of
- * this phase_.
- * @private
- */
-o3djs.serialization.Deserializer.prototype.setPropertiesPhase_ = function(
- amountOfWork) {
- for (; this.nextClassIndex_ < this.classNames_.length;
- ++this.nextClassIndex_) {
- var className = this.classNames_[this.nextClassIndex_];
- var classJson = this.json.objects[className];
- var numObjects = classJson.length;
- for (; this.nextObjectIndex_ < numObjects; ++this.nextObjectIndex_) {
- if (amountOfWork-- <= 0)
- return;
-
- var objectJson = classJson[this.nextObjectIndex_];
- var object = this.objectsByIndex_[this.globalObjectIndex_++];
- if ('properties' in objectJson) {
- for (var propertyName in objectJson.properties) {
- if (propertyName in object) {
- var propertyJson = objectJson.properties[propertyName];
- var propertyValue = this.deserializeValue(propertyJson);
- object[propertyName] = propertyValue;
- }
- };
- }
- if ('params' in objectJson) {
- if ('length' in objectJson.params) {
- for (var paramIndex = 0; paramIndex != objectJson.params.length;
- ++paramIndex) {
- var paramJson = objectJson.params[paramIndex];
- this.setParamValue_(/** @type {!Object} */ (object),
- paramIndex,
- paramJson);
- }
- } else {
- for (var paramName in objectJson.params) {
- var paramJson = objectJson.params[paramName];
- this.setParamValue_(/** @type {!Object} */ (object),
- paramName,
- paramJson);
- }
- }
- }
- if (className in this.initCallbacks) {
- this.initCallbacks[className](this, object, objectJson);
- }
- }
- this.nextObjectIndex_ = 0;
- }
-
- if (this.nextClassIndex_ === this.classNames_.length) {
- this.nextClassIndex_ = 0;
- this.nextObjectIndex_ = 0;
- this.globalObjectIndex_ = 0;
- ++this.phase_;
- }
-};
-
-/**
- * Perform a certain number of iterations of the deserializer. Keep calling this
- * function until it returns false.
- * @param {number} opt_amountOfWork The number of loop iterations to run. If
- * not specified, runs the deserialization to completion.
- * @return {boolean} Whether work remains to be done.
- */
-o3djs.serialization.Deserializer.prototype.run = function(
- opt_amountOfWork) {
- if (!opt_amountOfWork) {
- while (this.run(10000)) {
- }
- return false;
- } else {
- switch (this.phase_) {
- case 0:
- this.createObjectsPhase_(opt_amountOfWork);
- break;
- case 1:
- this.setPropertiesPhase_(opt_amountOfWork);
- break;
- }
- return this.phase_ < 2;
- }
-};
-
-/**
- * Deserializes (loads) a transform graph in the background. Invokes
- * a callback function on completion passing the pack and the thrown
- * exception on failure or the pack and a null exception on success.
- * @param {!o3d.Client} client An O3D client object.
- * @param {!o3d.Pack} pack The pack to create the deserialized objects
- * in.
- * @param {number} time The amount of the time (in seconds) the deserializer
- * should aim to complete in.
- * @param {!function(o3d.Pack, *): void} callback The function that
- * is called on completion. The second parameter is null on success or
- * the thrown exception on failure.
- */
-o3djs.serialization.Deserializer.prototype.runBackground = function(
- client, pack, time, callback) {
- // TODO: This seems like it needs to be more granular than the
- // top level.
- // TODO: Passing in the time you want it to take seems counter
- // intuitive. I want pass in a % of CPU so I can effectively say
- // "deserialize this in such a way so as not to affect my app's
- // performance". callbacksRequired = numObjects / amountPerCallback where
- // amountPerCallback = number I can do per frame and not affect performance
- // too much.
- var workToDo = this.json.objects.length * 2;
- var timerCallbacks = time * 60;
- var amountPerCallback = workToDo / timerCallbacks;
- var intervalId;
- var that = this;
- function deserializeMore() {
- var exception = null;
- var finished = false;
- var failed = false;
- var errorCollector = o3djs.error.createErrorCollector(client);
- try {
- finished = !that.run(amountPerCallback);
- } catch(e) {
- failed = true;
- finished = true;
- exception = e;
- }
- if (errorCollector.errors.length > 0) {
- finished = true;
- exception = errorCollector.errors.join('\n') +
- (exception ? ('\n' + exception.toString()) : '');
- }
- errorCollector.finish();
- if (finished) {
- window.clearInterval(intervalId);
- callback(pack, exception);
- }
- }
-
- intervalId = window.setInterval(deserializeMore, 1000 / 60);
-};
-
-/**
- * Creates a deserializer that will incrementally deserialize a
- * transform graph. The deserializer object has a method
- * 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 {!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);
-};
-
-/**
- * Deserializes a transform graph.
- * @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);
- deserializer.run();
-};
-
-/**
- * This function looks at a given data type, determines if it is an old style
- * matrix that is a 2d doubly nested array. If so, it flattens the matrix in
- * place so that it may be handled by the code.
- * @param {Object} parsed a potential array that will be repaired
- */
-o3djs.serialization.fixMatrices = function(parsed) {
- function isMatrix(m) {
- var len = m && m.length;
- if (len && len <= 4) {
- for (var i = 0; i < len; ++i) {
- var mi = m[i];
- var mlen = mi.length;
- if (mlen != len) {
- return false;
- }
- for(var j = 0; j < len; ++j) {
- if (Number(mi[j]) == NaN){
- return false;
- }
- }
- }
- return true;
- } else {
- return false;
- }
- }
-
- function flatten(m) {
- var len = m.length;
- var retval = new o3djs.math.makeMatrix4(len * len);
- for (var i = 0; i < len; ++i) {
- for (var j = 0; j < len; ++j) {
- retval[i * len + j] = m[i][j];
- }
- }
- return retval;
- }
- if (isMatrix(parsed)) {
- return flatten(parsed);
- }
- return parsed;
-};
-
-/**
- * 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
- * the pack, the parent transform, and an exception which will be null on
- * success.
- * @param {!o3djs.serialization.Options} opt_options Options.
- */
-o3djs.serialization.deserializeArchive = function(archiveInfo,
- sceneJsonUri,
- client,
- pack,
- parent,
- 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(pack, parsed);
-
- deserializer.addObject(parsed.o3d_rootObject_root, parent);
- deserializer.archiveInfo = archiveInfo;
-
- 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);
- }
-};
-
-
diff --git a/o3d/samples/o3djs/shape.js b/o3d/samples/o3djs/shape.js
deleted file mode 100644
index 7b36c16..0000000
--- a/o3d/samples/o3djs/shape.js
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains various functions for helping setup
- * shapes for o3d. It puts them in the "shape" module on the o3djs
- * object.
- *
- * Note: This library is only a sample. It is not meant to be some official
- * library. It is provided only as example code.
- *
- */
-
-o3djs.provide('o3djs.shape');
-
-o3djs.require('o3djs.math');
-o3djs.require('o3djs.element');
-
-/**
- * A Module for shapes.
- * @namespace
- */
-o3djs.shape = o3djs.shape || {};
-
-/**
- * Adds missing tex coord streams to a shape's elements.
- * @param {!o3d.Shape} shape Shape to add missing streams to.
- * @see o3djs.element.addMissingTexCoordStreams
- */
-o3djs.shape.addMissingTexCoordStreams = function(shape) {
- var elements = shape.elements;
- for (var ee = 0; ee < elements.length; ++ee) {
- var element = elements[ee];
- o3djs.element.addMissingTexCoordStreams(element);
- }
-};
-
-/**
- * Sets the bounding box and z sort points of a shape's elements.
- * @param {!o3d.Shape} shape Shape to set info on.
- */
-o3djs.shape.setBoundingBoxesAndZSortPoints = function(shape) {
- var elements = shape.elements;
- for (var ee = 0; ee < elements.length; ++ee) {
- var element = elements[ee];
- o3djs.element.setBoundingBoxAndZSortPoint(element);
- }
-};
-
-/**
- * Prepares a shape by setting its boundingBox, zSortPoint and creating
- * DrawElements.
- * @param {!o3d.Pack} pack Pack to manage created objects.
- * @param {!o3d.Shape} shape Shape to prepare.
- */
-o3djs.shape.prepareShape = function(pack, shape) {
- shape.createDrawElements(pack, null);
- o3djs.shape.setBoundingBoxesAndZSortPoints(shape);
- o3djs.shape.addMissingTexCoordStreams(shape);
-};
-
-/**
- * Prepares all the shapes in the given pack by setting their boundingBox,
- * zSortPoint and creating DrawElements.
- * @param {!o3d.Pack} pack Pack to manage created objects.
- */
-o3djs.shape.prepareShapes = function(pack) {
- var shapes = pack.getObjectsByClassName('o3d.Shape');
- for (var ss = 0; ss < shapes.length; ++ss) {
- o3djs.shape.prepareShape(pack, shapes[ss]);
- }
-};
-
-/**
- * Attempts to delete the parts of a shape that were created by
- * duplicateShape as well as any drawElements attached to it.
- * @param {!o3d.Shape} shape shape to delete.
- * @param {!o3d.Pack} pack Pack to release objects from.
- */
-o3djs.shape.deleteDuplicateShape = function(shape, pack) {
- var elements = shape.elements;
- for (var ee = 0; ee < elements.length; ee++) {
- var element = elements[ee];
- var drawElements = element.drawElements;
- for (var dd = 0; dd < drawElements.length; dd++) {
- var drawElement = drawElements[dd];
- pack.removeObject(drawElement);
- }
- pack.removeObject(element);
- }
- pack.removeObject(shape);
-};
-
-/**
- * Copies a shape's elements and streambank or buffers so the two will share
- * streambanks, vertex and index buffers.
- * @param {!o3d.Pack} pack Pack to manage created objects.
- * @param {!o3d.Shape} source The Shape to copy.
- * @return {!o3d.Shape} the new copy of the shape.
- */
-o3djs.shape.duplicateShape = function(pack, source) {
- var newShape = pack.createObject('Shape');
- var elements = source.elements;
- for (var ee = 0; ee < elements.length; ee++) {
- var newElement = o3djs.element.duplicateElement(pack, elements[ee]);
- newElement.owner = newShape;
- }
- newShape.createDrawElements(pack, null);
- return newShape;
-};
-
diff --git a/o3d/samples/o3djs/simple.js b/o3d/samples/o3djs/simple.js
deleted file mode 100644
index 7252b76..0000000
--- a/o3d/samples/o3djs/simple.js
+++ /dev/null
@@ -1,830 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @fileoverview This file contains functions to make it extremely simple
- * to get something on the screen in o3d. The disadvantage is it
- * is less flexible and creates inefficient assets.
- *
- * Example
- *
- * <pre>
- * &lt;html&gt;&lt;body&gt;
- * &lt;script type="text/javascript" src="o3djs/all.js"&gt;
- * &lt;/script&gt;
- * &lt;script type="text/javascript"&gt;
- * window.init = init;
- *
- * function init() {
- * o3djs.base.makeClients(initStep2);
- * }
- *
- * function initStep2(clientElements) {
- * var clientElement = clientElements[0];
- *
- * // Create an o3djs.simple object to manage things in a simple way.
- * g_simple = o3djs.simple.create(clientElement);
- *
- * // Create a cube.
- * g_cube = g_simple.createCube(50);
- *
- * // DONE!
- * }
- * &lt;/script&gt;
- * &lt;div id="o3d" style="width: 600px; height: 600px"&gt;&lt;/div&gt;
- * &lt;/body&gt;&lt;/html&gt;
- * </pre>
- *
- * Some more examples:
- *
- * g_cube.setDiffuseColor(1, 0, 0, 1); // Cube is now red.
- * g_cube.transform.translate(10, 0, 0); // Cube translates.
- * g_cube.loadTexture('http://google.com/someimage.jpg"); // Cube is textured
- *
- *
- * Note: This library is only a sample. It is not meant to be some official
- * library. It is provided only as example code.
- *
- */
-
-o3djs.provide('o3djs.simple');
-
-o3djs.require('o3djs.math');
-o3djs.require('o3djs.material');
-o3djs.require('o3djs.effect');
-o3djs.require('o3djs.shape');
-o3djs.require('o3djs.util');
-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.
- * @namespace
- */
-o3djs.simple = o3djs.simple || {};
-
-/**
- * Creates an o3djs.simple library object that helps manage o3d
- * for the extremely simple cases.
- *
- * <pre>
- * &lt;html&gt;&lt;body&gt;
- * &lt;script type="text/javascript" src="o3djs/all.js"&gt;
- * &lt;/script&gt;
- * &lt;script type="text/javascript"&gt;
- * windows.onload = init;
- *
- * function init() {
- * o3djs.base.makeClients(initStep2);
- * }
- *
- * function initStep2(clientElements) {
- * var clientElement = clientElements[0];
- *
- * // Create an o3djs.simple object to manage things in a simple way.
- * g_simple = o3djs.simple.create(clientElement);
- *
- * // Create a cube.
- * g_cube = g_simple.createCube(50);
- *
- * // DONE!
- * }
- * &lt;/script&gt;
- * &lt;div id="o3d" style="width: 600px; height: 600px"&gt;&lt;/div&gt;
- * &lt;/body&gt;&lt;/html&gt;
- * </pre>
- *
- * @param {!Element} clientObject O3D.Plugin Object.
- * @return {!o3djs.simple.SimpleInfo} Javascript object that hold info for the
- * simple library.
- *
- */
-o3djs.simple.create = function(clientObject) {
- return new o3djs.simple.SimpleInfo(clientObject);
-};
-
-/**
- * A SimpleInfo contains information for the simple library.
- * @constructor
- * @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;
-
- /**
- * 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 {!o3djs.rendergraph.ViewInfo}
- */
- this.viewInfo = o3djs.rendergraph.createBasicView(
- this.pack,
- this.root,
- this.client.renderGraphRoot);
-
- /**
- * The list of objects that need to have an update function called indexed by
- * id.
- * @private
- * @type {!Object.<number,!o3djs.simple.SimpleObject>}
- */
- this.updateObjects_ = { };
-
- /**
- * The next available id for objects.
- * @private
- * @type {number}
- */
- this.nextId_ = 1;
-
- // Create 1 non-textured material and 1 textured material.
- //
- // TODO: Refactor.
- // This is slightly backward. What we really want is to be able to request
- // an effect of a specific type from our shader builder but the current shader
- // builder expects a material to already exist. So, we create a material here
- // just to pass it to the shader builder, then we keep the effect it created
- // but throw away the material.
- //
- // TODO: Fix shader builder so it creates diffuseColorMult,
- // diffuseColorOffset and diffuseTexture so
- // diffuse = diffuseTexture * diffuseColorMult + diffuseColorOffset.
-
- var material = this.pack.createObject('Material');
-
- o3djs.effect.attachStandardShader(this.pack,
- material,
- [0, 0, 0],
- 'phong');
-
- this.nonTexturedEffect_ = material.effect;
- this.pack.removeObject(material);
-
- var material = this.pack.createObject('Material');
- var samplerParam = material.createParam('diffuseSampler', 'ParamSampler');
- o3djs.effect.attachStandardShader(this.pack,
- material,
- [0, 0, 0],
- 'phong');
-
- this.texturedEffect_ = material.effect;
- this.pack.removeObject(material);
-
- this.globalParamObject = this.pack.createObject('ParamObject');
- this.lightWorldPosParam = this.globalParamObject.createParam('lightWorldPos',
- 'ParamFloat3');
- this.lightColorParam = this.globalParamObject.createParam('lightColor',
- 'ParamFloat4');
- this.setLightColor(1, 1, 1, 1);
- this.setLightPosition(255, 150, 150); // same as camera.
-
- // Attempt to setup a resonable default perspective matrix.
- this.zNear = 0.1;
- this.zFar = 1000;
- this.fieldOfView = o3djs.math.degToRad(45);
- this.setPerspectiveMatrix_();
-
- // Attempt to setup a resonable default view.
- this.cameraPosition = [250, 150, 150];
- this.cameraTarget = [0, 0, 0];
- this.cameraUp = [0, 1, 0];
- this.setViewMatrix_();
-
- var that = this;
-
- this.client.setRenderCallback(function(renderEvent) {
- var elapsedTime = Math.min(renderEvent.elapsedTime, 0.1);
- that.onRender_(elapsedTime);
- });
-};
-
-/**
- * Gets the next available id.
- * @return {number} The next available id.
- */
-o3djs.simple.SimpleInfo.prototype.getNextId = function() {
- return this.nextId_++;
-};
-
-/**
- * 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.
- * @return {!o3djs.simple.SimpleShape} the created SimpleShape.
- */
-o3djs.simple.SimpleInfo.prototype.createSimpleShape = function(shape) {
- shape.createDrawElements(this.pack, null);
- var transform = this.pack.createObject('Transform');
- transform.parent = this.root;
- transform.addShape(shape);
- return new o3djs.simple.SimpleShape(this, transform);
-};
-
-/**
- * The on render handler for a SimpleInfo.
- * @private
- * @param {number} elapsedTime Time elapsed since last frame.
- */
-o3djs.simple.SimpleInfo.prototype.onRender_ = function(elapsedTime) {
- for (var sid in this.updateObjects_) {
- var id = /** @type {number} */ (sid);
- this.updateObjects_[id].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.id] = simpleObject;
-};
-
-/**
- * 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.id];
-};
-
-/**
- * Sets the perspective matrix.
- * @private
- */
-o3djs.simple.SimpleInfo.prototype.setPerspectiveMatrix_ = function() {
- this.viewInfo.drawContext.projection = o3djs.math.matrix4.perspective(
- this.fieldOfView,
- this.client.width / this.client.height,
- this.zNear,
- this.zFar);
-};
-
-/**
- * Sets the view matrix.
- * @private
- */
-o3djs.simple.SimpleInfo.prototype.setViewMatrix_ = function() {
- this.viewInfo.drawContext.view = o3djs.math.matrix4.lookAt(
- this.cameraPosition,
- this.cameraTarget,
- this.cameraUp);
-};
-
-/**
- * Sets the field of view
- * @param {number} fieldOfView in Radians.
- *
- * For degrees use setFieldOfView(o3djs.math.degToRad(degrees)).
- */
-o3djs.simple.SimpleInfo.prototype.setFieldOfView =
- function(fieldOfView) {
- this.fieldOfView = fieldOfView;
- this.setPerspectiveMatrix_();
-};
-
-/**
- * Sets the z clip range.
- * @param {number} zNear near z value.
- * @param {number} zFar far z value.
- */
-o3djs.simple.SimpleInfo.prototype.setZClip = function(zNear, zFar) {
- this.zNear = zNear;
- this.zFar = zFar;
- this.setPerspectiveMatrix_();
-};
-
-/**
- * Sets the light position
- * @param {number} x x position.
- * @param {number} y y position.
- * @param {number} z z position.
- */
-o3djs.simple.SimpleInfo.prototype.setLightPosition = function(x, y, z) {
- this.lightWorldPosParam.set(x, y, z);
-};
-
-/**
- * Sets the light color
- * @param {number} r red (0-1).
- * @param {number} g green (0-1).
- * @param {number} b blue (0-1).
- * @param {number} a alpha (0-1).
- */
-o3djs.simple.SimpleInfo.prototype.setLightColor = function(r, g, b, a) {
- this.lightColorParam.set(r, g, b, a);
-};
-
-/**
- * Sets the camera position
- * @param {number} x x position.
- * @param {number} y y position.
- * @param {number} z z position.
- */
-o3djs.simple.SimpleInfo.prototype.setCameraPosition = function(x, y, z) {
- this.cameraPosition = [x, y, z];
- this.setViewMatrix_();
-};
-
-/**
- * Sets the camera target
- * @param {number} x x position.
- * @param {number} y y position.
- * @param {number} z z position.
- */
-o3djs.simple.SimpleInfo.prototype.setCameraTarget = function(x, y, z) {
- this.cameraTarget = [x, y, z];
- this.setViewMatrix_();
-};
-
-/**
- * Sets the camera up
- * @param {number} x x position.
- * @param {number} y y position.
- * @param {number} z z position.
- */
-o3djs.simple.SimpleInfo.prototype.setCameraUp = function(x, y, z) {
- this.cameraUp = [x, y, z];
- this.setViewMatrix_();
-};
-
-/**
- * Create meterial from effect.
- * @param {!o3d.Effect} effect Effect to use for material.
- * @return {!o3d.Material} The created material.
- */
-o3djs.simple.SimpleInfo.prototype.createMaterialFromEffect =
- function(effect) {
- var material = this.pack.createObject('Material');
- material.drawList = this.viewInfo.performanceDrawList;
- material.effect = effect;
- effect.createUniformParameters(material);
- material.getParam('lightWorldPos').bind(this.lightWorldPosParam);
- material.getParam('lightColor').bind(this.lightColorParam);
- return material;
-};
-
-/**
- * Create a new non-textured material.
- * @param {string} type Type of material 'phong', 'lambert', 'constant'.
- * @return {!o3d.Material} The created material.
- */
-o3djs.simple.SimpleInfo.prototype.createNonTexturedMaterial =
- function(type) {
- 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);
- material.getParam('specular').set(1, 1, 1, 1);
- material.getParam('shininess').value = 20;
- return material;
-};
-
-/**
- * @param {string} type Type of material 'phong', 'lambert', 'constant'.
- * @return {!o3d.Material} The created material.
- */
-o3djs.simple.SimpleInfo.prototype.createTexturedMaterial =
- function(type) {
- var material = this.createMaterialFromEffect(this.texturedEffect_);
- var samplerParam = material.getParam('diffuseSampler');
- var sampler = this.pack.createObject('Sampler');
- samplerParam.value = sampler;
- return material;
-};
-
-/**
- * Creates a cube and adds it to the root of this SimpleInfo's transform graph.
- * @param {number} size Width, height and depth of the cube.
- * @return {!o3djs.simple.SimpleShape} A Javascript object to manage the
- * shape.
- */
-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);
-};
-
-/**
- * Creates a box and adds it to the root of this SimpleInfo's transform graph.
- * @param {number} width Width of the box.
- * @param {number} height Height of the box.
- * @param {number} depth Depth of the box.
- * @return {!o3djs.simple.SimpleShape} A Javascript object to manage the
- * shape.
- */
-o3djs.simple.SimpleInfo.prototype.createBox = function(width,
- height,
- depth) {
- var material = this.createNonTexturedMaterial('phong');
- var shape = o3djs.primitives.createBox(this.pack,
- material,
- width,
- height,
- depth);
- return this.createSimpleShape(shape);
-};
-
-/**
- * Creates a sphere and adds it to the root of this SimpleInfo's transform
- * graph.
- * @param {number} radius radius of sphere.
- * @param {number} smoothness determines the number of subdivisions.
- * @return {!o3djs.simple.SimpleShape} A Javascript object to manage the
- * shape.
- */
-o3djs.simple.SimpleInfo.prototype.createSphere = function(radius,
- smoothness) {
- var material = this.createNonTexturedMaterial('phong');
- var shape = o3djs.primitives.createSphere(this.pack,
- material,
- radius,
- smoothness * 2,
- smoothness);
- return this.createSimpleShape(shape);
-};
-
-/**
- * Loads a scene from a URL.
- * @param {string} url Url of scene to load.
- * @param {!function(o3djs.simple.SimpleScene, *): void} callback 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, 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,
- /** @type {!o3djs.serialization.Options} */
- ({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.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 = 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]]);
- this.setCameraPosition(eye[0], eye[1], eye[2]);
- this.setZClip(diag / 1000, diag * 10);
-};
-
-/**
- * An object for managing things simply.
- * @constructor
- */
-o3djs.simple.SimpleObject = function() {
-};
-
-/**
- * Initializes a SimpleObject.
- * @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 object.
- * @type {!o3djs.simple.SimpleInfo}
- */
- this.simpleInfo = simpleInfo;
-
- /**
- * The Id for this SimpleInfo.
- * @type {number}
- */
- this.id = simpleInfo.getNextId();
-
- /**
- * The Transform that orients this object.
- * @type {!o3d.Transform}
- */
- this.transform = transform;
-
- /**
- * The update callback for this object.
- * @private
- * @type {?function(number): void}
- */
- this.updateCallback_ = null;
-
- /**
- * The pick callback for this object.
- * @private
- * @type {?function(number): void}
- */
- this.pickCallback_ = null;
-};
-
-/**
- * Registers on an on picked callback.
- * @param {!function(!o3djs.simple.SimpleObject): void} onPickedCallback A
- * function called when this object is picked.
- */
-o3djs.simple.SimpleObject.prototype.onPicked = function(onPickedCallback) {
- throw 'not implemented';
-};
-
-/**
- * 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|null)} 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;
-};
-
-/**
- * Sets the material for this SimpleShape, deleting any old one.
- * @param {!o3d.Material} material new material.
- */
-o3djs.simple.SimpleShape.prototype.setMaterial = function(material) {
- var old_material = this.getMaterial();
- if (old_material != null) {
- this.simpleInfo.pack.removeObject(old_material);
- }
- this.transform.shapes[0].elements[0].material = material;
-};
-
-/**
- * Sets the diffuse color of this shape.
- * @param {number} r Red (0-1).
- * @param {number} g Green (0-1).
- * @param {number} b Blue (0-1).
- * @param {number} a Alpha (0-1).
- */
-o3djs.simple.SimpleShape.prototype.setDiffuseColor =
- function(r, g, b, a) {
- var material = this.getMaterial();
- material.getParam('diffuse').set(r, g, b, a);
- if (a < 1) {
- material.drawList = this.simpleInfo.viewInfo.zOrderedDrawList;
- } else {
- material.drawList = this.simpleInfo.viewInfo.performanceDrawList;
- }
-};
-
-/**
- * Gets the texture on this shape.
- * @return {o3d.Texture} The texture on this shape. May be null.
- */
-o3djs.simple.SimpleShape.prototype.getTexture = function() {
- var material = this.getMaterial();
- var samplerParam = material.getParam('diffuseSampler');
- if (samplerParam.className == 'o3d.ParamSampler') {
- return samplerParam.texture;
- }
- return null;
-};
-
-/**
- * Loads a texture onto the given shape. It will replace the material
- * if it needs to with one that supports a texture. Note that the texture
- * is loaded asynchronously and so the result of this call may appear several
- * seconds after it is called depending on how long it takes to download the
- * texture.
- * @param {string} url Url of texture.
- */
-o3djs.simple.SimpleShape.prototype.loadTexture = function(url) {
- var that = this;
- o3djs.io.loadTexture(
- this.simpleInfo.pack,
- url,
- function(texture, exception) {
- if (!exception) {
- // See if this is a textured material.
- 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_;
- that.setMaterial(new_material);
- material = new_material;
- }
- var samplerParam = material.getParam('diffuseSampler');
- samplerParam.value.texture = texture;
- } else {
- alert('Load texture file returned failure. \n' + exception);
- }
- });
-};
-
-/**
- * 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.ParamObject}
- */
- 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;
-};
-
-
diff --git a/o3d/samples/o3djs/test.js b/o3d/samples/o3djs/test.js
deleted file mode 100644
index 84fd88a..0000000
--- a/o3d/samples/o3djs/test.js
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This is a simple unit testing library used to test the
- * sample utilities
- *
- *
- */
-o3djs.provide('o3djs.test');
-
-/**
- * A unit testing library
- */
-o3djs.test = o3djs.test || {};
-
-/**
- * Class of errors thrown by assertions
- * @param {string} message The assertion message.
- * @this o3djs.test.AssertionError
- */
-o3djs.test.AssertionError = function(message) {
- this.message = message;
-
- /**
- * Returns the error message.
- * @return {String} The error message.
- */
- this.toString = function() {
- return message;
- };
-};
-
-/**
- * Runs all the tests found in the given suite. Every function with a
- * name beginning with 'test' is considered to be a test.
- * @param {!Object} suite The object containing the test suite.
- * @param {!Object} opt_reporter An optional object to which the results
- * of the test run are reported.
- * @return {boolean} Whether all the tests passed.
- */
-o3djs.test.runTests = function(suite, opt_reporter) {
- try {
- opt_reporter = opt_reporter || o3djs.test.documentReporter;
-
- var passCount = 0;
- var failCount = 0;
- for (var propertyName in suite) {
- if (propertyName.substring(0, 4) !== 'test')
- continue;
-
- if (typeof(suite[propertyName]) !== 'function')
- continue;
-
- try {
- suite[propertyName]();
- } catch (e) {
- ++failCount;
- opt_reporter.reportFail(propertyName, String(e));
- continue;
- }
-
- ++passCount;
- opt_reporter.reportPass(propertyName);
- }
-
- opt_reporter.reportSummary(passCount, failCount);
- return failCount == 0;
- }
- catch (e) {
- return false;
- }
-};
-
-/**
- * Converts a value to the string representation used in assertion messages.
- * @private
- * @param {*} value The value to convert.
- * @param {number} opt_depth The depth of references to follow for nested
- * objects. Defaults to 3.
- * @return {string} The string representation.
- */
-o3djs.test.valueToString_ = function(value, opt_depth) {
- if (opt_depth === undefined) {
- opt_depth = 3;
- }
- var string;
- if (typeof(value) === 'object') {
- if (value !== null) {
- if (opt_depth === 0) {
- string = '?';
- } else {
- if (o3djs.base.isArray(value)) {
- var valueAsArray = /** @type {!Array.<*>} */ (value);
- string = '[';
- var separator = '';
- for (var i = 0; i < valueAsArray.length; ++i) {
- string += separator +
- o3djs.test.valueToString_(valueAsArray[i], opt_depth - 1);
- separator = ', ';
- }
- string += ']';
- } else {
- var valueAsObject = /** @type {!Object} */ (value);
- string = '{';
- var separator = '';
- for (var propertyName in valueAsObject) {
- if (typeof(valueAsObject[propertyName]) !== 'function') {
- string += separator + propertyName + ': ' +
- o3djs.test.valueToString_(valueAsObject[propertyName],
- opt_depth - 1);
- separator = ', ';
- }
- }
- string += '}';
- }
- }
- } else {
- string = "null";
- }
- } else if (typeof(value) === 'string') {
- string = '"' + value + '"';
- } else {
- string = String(value);
- }
- return string;
-};
-
-/**
- * Asserts that a value is true from within a test
- * @param {boolean} value The value to test.
- */
-o3djs.test.assertTrue = function(value) {
- if (!value) {
- throw new o3djs.test.AssertionError(
- 'assertTrue failed for ' +
- o3djs.test.valueToString_(value));
- }
-};
-
-/**
- * Asserts that a value is false from within a test
- * @param {boolean} value The value to test.
- */
-o3djs.test.assertFalse = function(value) {
- if (value) {
- throw new o3djs.test.AssertionError(
- 'assertFalse failed for ' +
- o3djs.test.valueToString_(value));
- }
-};
-
-/**
- * Asserts that a value is null from within a test
- * @param {*} value The value to test.
- */
-o3djs.test.assertNull = function(value) {
- if (value !== null) {
- throw new o3djs.test.AssertionError(
- 'assertNull failed for ' +
- o3djs.test.valueToString_(value));
- }
-};
-
-/**
- * Asserts that an expected value is equal to an actual value.
- * @param {*} expected The expected value.
- * @param {*} actual The actual value.
- */
-o3djs.test.assertEquals = function(expected, actual) {
- if (expected !== actual) {
- throw new o3djs.test.AssertionError(
- 'assertEquals failed: expected ' +
- o3djs.test.valueToString_(expected) + ' but got ' +
- o3djs.test.valueToString_(actual));
- }
-};
-
-/**
- * Asserts that an expected value is close to an actual value
- * within a tolerance of 0.001.
- * @param {number} expected The expected value.
- * @param {number} actual The actual value.
- */
-o3djs.test.assertClose = function(expected, actual) {
- if (actual < expected - 0.001 || actual > expected + 0.001) {
- throw new o3djs.test.AssertionError(
- 'assertClose failed: expected ' +
- o3djs.test.valueToString_(expected) + ' but got ' +
- o3djs.test.valueToString_(actual));
- }
-};
-
-/**
- * Determines whether the elements of a pair of arrays are equal.
- * @private
- * @param {!Array.<*>} expected The expected array.
- * @param {!Array.<*>} actual The actual array.
- * @return {boolean} Whether the arrays are equal.
- */
-o3djs.test.compareArrays_ = function(expected, actual) {
- if (expected.length !== actual.length) {
- return false;
- }
- for (var i = 0; i != expected.length; ++i) {
- if (o3djs.base.isArray(expected[i]) && o3djs.base.isArray(actual[i])) {
- var expectedAsArray = /** @type {!Array.<*>} */ (expected[i]);
- var actualAsArray = /** @type {!Array.<*>} */ (actual[i]);
- if (!o3djs.test.compareArrays_(expectedAsArray, actualAsArray)) {
- return false;
- }
- } else if (expected[i] !== actual[i]) {
- return false;
- }
- }
- return true;
-};
-
-/**
- * Asserts that an expected array is equal to an actual array.
- * @param {!Array.<*>} expected The expected array.
- * @param {!Array.<*>} actual The actual array.
- */
-o3djs.test.assertArrayEquals = function(expected, actual) {
- if (!o3djs.base.isArray(expected)) {
- throw new o3djs.test.AssertionError(
- 'assertArrayEquals failed: expected value ' +
- o3djs.test.valueToString_(expected) +
- ' is not an array');
- }
- if (!o3djs.base.isArray(actual)) {
- throw new o3djs.test.AssertionError(
- 'assertArrayEquals failed: actual value ' +
- o3djs.test.valueToString_(actual) +
- ' is not an array');
- }
- if (!o3djs.test.compareArrays_(expected, actual)) {
- throw new o3djs.test.AssertionError(
- 'assertArrayEquals failed: expected ' +
- o3djs.test.valueToString_(expected) + ' but got ' +
- o3djs.test.valueToString_(actual));
- }
-};
-
-/**
- * Creates a DOM paragraph object for the given text and color.
- * @private
- * @param {string} text The text of the message.
- * @param {string} opt_color The optional color of the message.
- * @return {!Element} A DOM paragraph object.
- */
-o3djs.test.createReportParagraph_ = function(text, opt_color) {
- var textNode = document.createTextNode(text);
- var paragraph = document.createElement('p');
- paragraph.appendChild(textNode);
- if (opt_color !== undefined) {
- paragraph.style.color = opt_color;
- }
- return paragraph;
-};
-
-/**
- * A reporter that reports messages to the document (i.e. the DOM).
- * @type {!Object}
- */
-o3djs.test.documentReporter = {
- /**
- * A Report div.
- * @private
- * @this {Object}
- */
- getReportDiv_: function() {
- if (!this.reportDiv_) {
- this.reportDiv_ = document.createElement('div');
- document.body.appendChild(this.reportDiv_);
- }
- return this.reportDiv_;
- },
- /**
- * Reports a test passed.
- * @param {string} testName The name of the test.
- * @this {Object}
- */
- reportPass: function(testName) {
- var paragraph = o3djs.test.createReportParagraph_(
- testName + ' : PASS', 'green');
- this.getReportDiv_().appendChild(paragraph);
- },
- /**
- * Reports a test failed.
- * @param {string} testName The name of the test.
- */
- reportFail: function(testName, message) {
- var paragraph = o3djs.test.createReportParagraph_(
- testName + ' : FAIL : ' + message, 'red');
- var reportDiv = this.getReportDiv_();
- reportDiv.insertBefore(paragraph,
- reportDiv.firstChild);
- },
- /**
- * Reports a test summary.
- * @param {number} passCount The number of tests that passed.
- * @param {number} failCount The number of tests that failed.
- * @this {Object}
- */
- reportSummary: function(passCount, failCount) {
- var paragraph = o3djs.test.createReportParagraph_(
- passCount + ' passed, ' + failCount + ' failed', 'blue');
- var reportDiv = this.getReportDiv_();
- reportDiv.insertBefore(paragraph,
- reportDiv.firstChild);
- }
-};
diff --git a/o3d/samples/o3djs/texture.js b/o3d/samples/o3djs/texture.js
deleted file mode 100644
index 8bb6680..0000000
--- a/o3d/samples/o3djs/texture.js
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains functions helping to manipulate and manage
- * textures.
- */
-
-o3djs.provide('o3djs.texture');
-
-/**
- * A Module for bitmaps.
- * @namespace
- */
-o3djs.texture = o3djs.texture || {};
-
-/**
- * The maximum dimension of a texture.
- * @type {number}
- */
-o3djs.texture.MAX_TEXTURE_DIMENSION = 2048;
-
-/**
- * Computes the maximum number of levels of mips a given width and height could
- * use.
- * @param {number} width Width of texture.
- * @param {number} height Height of texture.
- * @return {number} The maximum number of levels for the given width and height.
- */
-o3djs.texture.computeNumLevels = function(width, height) {
- if (width == 0 || height == 0) {
- return 0;
- }
- var max = Math.max(width, height);
- var levels = 0;
- while (max > 0) {
- ++levels;
- max = max >> 1;
- }
- return levels;
-};
-
-/**
- * Creates a texture from a RawData object.
- * @param {!o3d.Pack} pack The pack to create the texture in.
- * @param {!o3d.RawData} rawData The raw data to create the texture from.
- * @param {boolean} opt_generateMips Whether or not to generate mips. Note, mips
- * can not be generated for DXT textures although they will be loaded if they
- * exist in the RawData.
- * @param {boolean} opt_flip Whether or not to flip the texture. Most DCC tools
- * Like Maya, Max, etc expect the textures to be flipped. Note that only
- * 2D (image) textures will be flipped. Cube textures will not be flipped.
- * Default = true.
- * @param {number} opt_maxWidth The maximum width of the texture. If the RawData
- * is larger than this size it will be scaled down to this size. Note that
- * DXT format textures can not be scaled. Default = 2048.
- * @param {number} opt_maxHeight The maximum width of the texture. If the
- * RawData is larger than this size it will be scaled down to this size. Note
- * that DXT format textures can not be scaled. Default = 2048.
- * @return {!o3d.Texture} The created texture.
- */
-o3djs.texture.createTextureFromRawData = function(
- pack,
- rawData,
- opt_generateMips,
- opt_flip,
- opt_maxWidth,
- opt_maxHeight) {
- // Make a bitmaps from the raw data.
- var bitmaps = pack.createBitmapsFromRawData(rawData);
- if (opt_flip || typeof opt_flip === 'undefined') {
- for (var ii = 0; ii < bitmaps.length; ++ii) {
- var bitmap = bitmaps[ii];
- if (bitmap.semantic == o3djs.base.o3d.Bitmap.IMAGE) {
- bitmaps[ii].flipVertically();
- }
- }
- }
-
- // Create a texture from the bitmaps.
- var texture = o3djs.texture.createTextureFromBitmaps(
- pack, bitmaps, opt_generateMips);
-
- // Delete the bitmaps.
- for (var ii = 0; ii < bitmaps.length; ++ii) {
- pack.removeObject(bitmaps[ii]);
- }
-
- return texture;
-};
-
-/**
- * Creates a texture from an array of RawData objects. This is mainly useful for
- * creating a cube map out of six separate textures.
- * @param {!o3d.Pack} pack The pack to create the texture in.
- * @param {!Array.<!o3d.RawData>} rawDataArray The array of raw data objects to
- * create the texture from. If these represent the six faces of a cube map,
- * they must be in the order FACE_POSITIVE_X, FACE_NEGATIVE_X,
- * FACE_POSITIVE_Y, FACE_NEGATIVE_Y, FACE_POSITIVE_Z, FACE_NEGATIVE_Z
- * @param {boolean} opt_generateMips Whether or not to generate mips. Note, mips
- * can not be generated for DXT textures although they will be loaded if they
- * exist in the RawData.
- * @param {boolean} opt_flip Whether or not to flip the texture. Most DCC tools
- * Like Maya, Max, etc expect the textures to be flipped. Note that only
- * 2D (image) textures will be flipped. Cube textures will not be flipped.
- * Default = true.
- * @param {number} opt_maxWidth The maximum width of the texture. If the RawData
- * is larger than this size it will be scaled down to this size. Note that
- * DXT format textures can not be scaled. Default = 2048.
- * @param {number} opt_maxHeight The maximum width of the texture. If the
- * RawData is larger than this size it will be scaled down to this size. Note
- * that DXT format textures can not be scaled. Default = 2048.
- * @return {!o3d.Texture} The created texture.
- */
-o3djs.texture.createTextureFromRawDataArray = function(
- pack,
- rawDataArray,
- opt_generateMips,
- opt_flip,
- opt_maxWidth,
- opt_maxHeight) {
- // Make bitmaps from the raw data.
- var bitmaps = [];
- for (var ii = 0; ii < rawDataArray.length; ++ii) {
- bitmaps = bitmaps.concat(pack.createBitmapsFromRawData(rawDataArray[ii]));
- }
- if (opt_flip || typeof opt_flip === 'undefined') {
- for (var ii = 0; ii < bitmaps.length; ++ii) {
- var bitmap = bitmaps[ii];
- if (bitmap.semantic == o3djs.base.o3d.Bitmap.IMAGE) {
- bitmaps[ii].flipVertically();
- }
- }
- }
-
- // Create a texture from the bitmaps.
- // TODO(kbr): use createCubeTextureFrom6Bitmaps instead; bugs in the plugin
- // currently prevent this.
- var texture = o3djs.texture.createTextureFromBitmaps(
- pack, bitmaps, opt_generateMips);
-
- // Delete the bitmaps.
- for (var ii = 0; ii < bitmaps.length; ++ii) {
- pack.removeObject(bitmaps[ii]);
- }
-
- return texture;
-};
-
-/**
- * Returns whether or not a given texture format can be scaled.
- * @param {!o3d.Texture.Format} format The format to check.
- * @return {boolean} True if you can scale and make mips for the given format.
- */
-o3djs.texture.canMakeMipsAndScale = function(format) {
- switch (format) {
- case o3djs.base.o3d.Texture.XRGB8:
- case o3djs.base.o3d.Texture.ARGB8:
- case o3djs.base.o3d.Texture.ABGR16F:
- case o3djs.base.o3d.Texture.R32F:
- case o3djs.base.o3d.Texture.ABGR32F:
- return true;
- case o3djs.base.o3d.Texture.DXT1:
- case o3djs.base.o3d.Texture.DXT3:
- case o3djs.base.o3d.Texture.DXT5:
- return false;
- }
- return false;
-};
-
-/**
- * Creates a Texture from an array of bitmaps.
- * @param {!o3d.Pack} pack The pack to create the texture in.
- * @param {!Array.<!o3d.Bitmap>} bitmaps An array of bitmaps to create the
- * texture from. For a 2D texture this would be 1 bitmap. For a cubemap this
- * would be 6 bitmaps.
- * @param {boolean} opt_generateMips Whether or not to generate mips. Note, mips
- * can not be generated for DXT textures although they will be loaded if they
- * exist in the RawData. Default = true.
- * @return {!o3d.Texture} The created texture.
- */
-o3djs.texture.createTextureFromBitmaps = function(
- pack,
- bitmaps,
- opt_generateMips) {
- if (bitmaps.length == 0) {
- throw 'no bitmaps';
- }
-
- var srcWidth = bitmaps[0].width;
- var srcHeight = bitmaps[0].height;
- var format = bitmaps[0].format;
- var mipMaps = bitmaps[0].numMipmaps;
- var maxMips = o3djs.texture.computeNumLevels(srcWidth, srcHeight);
- var targetMips = mipMaps;
- var dstWidth = srcWidth;
- var dstHeight = srcHeight;
- if ((typeof opt_generateMips === 'undefined' || opt_generateMips) &&
- o3djs.texture.canMakeMipsAndScale(format) &&
- mipMaps == 1 && maxMips > 1) {
- targetMips = maxMips;
- }
-
- // Check that all the bitmaps are the same size and make mips
- for (var ii = 0; ii < bitmaps.length; ++ii) {
- var bitmap = bitmaps[ii];
- if (bitmap.width != srcWidth ||
- bitmap.height != srcHeight ||
- bitmap.format != format ||
- bitmap.numMipmaps != mipMaps) {
- throw 'bitmaps must all be the same width, height, mips and format';
- }
- if (targetMips != mipMaps) {
- bitmap.generateMips(0, targetMips - 1);
- }
- }
-
- var levels = bitmap.numMipmaps > 1 ? bitmap.numMipmaps :
- o3djs.texture.computeNumLevels(dstWidth, dstHeight);
- var texture;
- if (bitmaps.length == 6 &&
- bitmaps[0].semantic != o3djs.base.o3d.Bitmap.SLICE) {
- if (srcWidth != srcHeight ||
- srcWidth != dstWidth ||
- srcHeight != dstHeight) {
- throw 'Cubemaps must be square';
- }
- texture = pack.createTextureCUBE(dstWidth, format, targetMips, false);
- for (var ii = 0; ii < 6; ++ii) {
- texture.setFromBitmap(
- /** @type {o3d.TextureCUBE.CubeFace} */ (ii),
- bitmaps[ii]);
- }
- } else if (bitmaps.length == 1) {
- texture = pack.createTexture2D(
- dstWidth, dstHeight, format, targetMips, false);
- texture.setFromBitmap(bitmaps[0]);
- }
-
- return /** @type{!o3d.Texture} */ (texture);
-};
-
-/**
- * Creates a TextureCUBE from 6 bitmaps. The bitmaps do not have to be the same
- * size though they do have to be the same format.
- *
- * @param {!o3d.Pack} pack The pack to create the texture in.
- * @param {number} edgeLength The size of the cubemap.
- * @param {!Array.<!o3d.Bitmap>} bitmaps An array of 6 bitmaps in the order
- * FACE_POSITIVE_X, FACE_NEGATIVE_X, FACE_POSITIVE_Y, FACE_NEGATIVE_Y,
- * FACE_POSITIVE_Z, FACE_NEGATIVE_Z.
- * @return {!o3d.Texture} The created texture.
- */
-o3djs.texture.createCubeTextureFrom6Bitmaps = function(
- pack, edgeLength, bitmaps) {
- var numMips = o3djs.texture.computeNumLevels(edgeLength, edgeLength);
- var texture = pack.createTextureCUBE(
- edgeLength, bitmaps[0].format, numMips, false);
- for (var ii = 0; ii < 6; ++ii) {
- var bitmap = bitmaps[ii];
- texture.setFromBitmap(/** @type{o3d.TextureCUBE.CubeFace} */ (ii), bitmap);
- }
- texture.generateMips(0, numMips - 1);
- return texture;
-};
-
diff --git a/o3d/samples/o3djs/util.js b/o3d/samples/o3djs/util.js
deleted file mode 100644
index 24c09d0..0000000
--- a/o3d/samples/o3djs/util.js
+++ /dev/null
@@ -1,1037 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains various utility functions for o3d. It
- * puts them in the "util" module on the o3djs object.
- *
- */
-
-o3djs.provide('o3djs.util');
-
-o3djs.require('o3djs.io');
-o3djs.require('o3djs.effect');
-o3djs.require('o3djs.event');
-o3djs.require('o3djs.error');
-
-/**
- * A Module with various utilities.
- * @namespace
- */
-o3djs.util = o3djs.util || {};
-
-/**
- * The name of the o3d plugin. Used to find the plugin when checking
- * for its version.
- * @type {string}
- */
-o3djs.util.PLUGIN_NAME = 'O3D Plugin';
-
-/**
- * The version of the plugin needed to use this version of the javascript
- * utility libraries.
- * @type {string}
- */
-o3djs.util.REQUIRED_VERSION = '0.1.42.4';
-
-/**
- * The width an O3D must be to put a failure message inside
- * @type {number}
- */
-o3djs.util.MINIMUM_WIDTH_FOR_MESSAGE = 200;
-
-/**
- * The height an O3D must be to put a failure message inside
- * @type {number}
- */
-o3djs.util.MINIMUM_HEIGHT_FOR_MESSAGE = 200;
-
-/**
- * A URL at which to download the client.
- * @type {string}
- */
-o3djs.util.PLUGIN_DOWNLOAD_URL = 'http://tools.google.com/dlpage/o3d';
-
-/**
- * The Renderer InitStatus constants so we don't need an o3d object to look
- * them up.
- * @enum {number}
- */
-o3djs.util.rendererInitStatus = {
- NO_PLUGIN: -1,
- UNINITIALIZED: 0,
- SUCCESS: 1,
- OUT_OF_RESOURCES: 2,
- GPU_NOT_UP_TO_SPEC: 3,
- INITIALIZATION_ERROR: 4
-};
-
-/**
- * This implements a JavaScript version of currying. Currying allows you to
- * take a function and fix its initial arguments, resulting in a function
- * expecting only the remaining arguments when it is invoked. For example:
- * <pre>
- * function add(a, b) {
- * return a + b;
- * }
- * var increment = o3djs.util.curry(add, 1);
- * var result = increment(10);
- * </pre>
- * Now result equals 11.
- * @param {!function(...): *} func The function to curry.
- * @return {!function(...): *} The curried function.
- */
-o3djs.util.curry = function(func) {
- var outerArgs = [];
- for (var i = 1; i < arguments.length; ++i) {
- outerArgs.push(arguments[i]);
- }
- return function() {
- var innerArgs = outerArgs.slice();
- for (var i = 0; i < arguments.length; ++i) {
- innerArgs.push(arguments[i]);
- }
- return func.apply(this, innerArgs);
- }
-}
-
-/**
- * Gets the URI in which the current page is located, omitting the file name.
- * @return {string} The base URI of the page. If the page is
- * "http://some.com/folder/somepage.html" returns
- * "http://some.com/folder/".
- */
-o3djs.util.getCurrentURI = function() {
- var path = window.location.href;
- var index = path.lastIndexOf('/');
- return path.substring(0, index + 1);
-};
-
-/**
- * Given a URI that is relative to the current page, returns the absolute
- * URI.
- * @param {string} uri URI relative to the current page.
- * @return {string} Absolute uri. If the page is
- * "http://some.com/folder/sompage.html" and you pass in
- * "images/someimage.jpg" will return
- * "http://some.com/folder/images/someimage.jpg".
- */
-o3djs.util.getAbsoluteURI = function(uri) {
- return o3djs.util.getCurrentURI() + uri;
-};
-
-/**
- * Searches an array for a specific value.
- * @param {!Array.<*>} array Array to search.
- * @param {*} value Value to search for.
- * @return {boolean} True if value is in array.
- */
-o3djs.util.arrayContains = function(array, value) {
- for (var i = 0; i < array.length; i++) {
- if (array[i] == value) {
- return true;
- }
- }
- return false;
-};
-
-/**
- * Searches for all transforms with a "o3d.tags" ParamString
- * that contains specific tag keywords assuming comma separated
- * words.
- * @param {!o3d.Transform} treeRoot Root of tree to search for tags.
- * @param {string} searchTags Tags to look for. eg "camera", "ogre,dragon".
- * @return {!Array.<!o3d.Transform>} Array of transforms.
- */
-o3djs.util.getTransformsInTreeByTags = function(treeRoot, searchTags) {
- var splitTags = searchTags.split(',');
- var transforms = treeRoot.getTransformsInTree();
- var found = [];
- for (var n = 0; n < transforms.length; n++) {
- var tagParam = transforms[n].getParam('collada.tags');
- if (tagParam) {
- var tags = tagParam.value.split(',');
- for (var t = 0; t < tags.length; t++) {
- if (o3djs.util.arrayContains(splitTags, tags[t])) {
- found[found.length] = transforms[n];
- break;
- }
- }
- }
- }
- return found;
-};
-
-/**
- * Finds transforms in the tree by prefix.
- * @param {!o3d.Transform} treeRoot Root of tree to search.
- * @param {string} prefix Prefix to look for.
- * @return {!Array.<!o3d.Transform>} Array of transforms matching prefix.
- */
-o3djs.util.getTransformsInTreeByPrefix = function(treeRoot, prefix) {
- var found = [];
- var transforms = treeRoot.getTransformsInTree();
- for (var ii = 0; ii < transforms.length; ii++) {
- var transform = transforms[ii];
- if (transform.name.indexOf(prefix) == 0) {
- found[found.length] = transform;
- }
- }
- return found;
-};
-
-/**
- * Finds the bounding box of all primitives in the tree, in the local space of
- * the tree root. This will use existing bounding boxes on transforms and
- * elements, but not create new ones.
- * @param {!o3d.Transform} treeRoot Root of tree to search.
- * @return {!o3d.BoundingBox} The boundinding box of the tree.
- */
-o3djs.util.getBoundingBoxOfTree = function(treeRoot) {
- // If we already have a bounding box, use that one.
- var box = treeRoot.boundingBox;
- if (box.valid) {
- return box;
- }
- var o3d = o3djs.base.o3d;
- // Otherwise, create it as the union of all the children bounding boxes and
- // all the shape bounding boxes.
- var transforms = treeRoot.children;
- for (var i = 0; i < transforms.length; ++i) {
- var transform = transforms[i];
- var childBox = o3djs.util.getBoundingBoxOfTree(transform);
- if (childBox.valid) {
- // transform by the child local matrix.
- childBox = childBox.mul(transform.localMatrix);
- if (box.valid) {
- box = box.add(childBox);
- } else {
- box = childBox;
- }
- }
- }
- var shapes = treeRoot.shapes;
- for (var i = 0; i < shapes.length; ++i) {
- var elements = shapes[i].elements;
- for (var j = 0; j < elements.length; ++j) {
- var elementBox = elements[j].boundingBox;
- if (!elementBox.valid) {
- elementBox = elements[j].getBoundingBox(0);
- }
- if (box.valid) {
- box = box.add(elementBox);
- } else {
- box = elementBox;
- }
- }
- }
- return box;
-};
-
-/**
- * Returns the smallest power of 2 that is larger than or equal to size.
- * @param {number} size Size to get power of 2 for.
- * @return {number} smallest power of 2 that is larger than or equal to size.
- */
-o3djs.util.getPowerOfTwoSize = function(size) {
- var powerOfTwo = 1;
- size = size - 1;
- while (size) {
- size = size >> 1;
- powerOfTwo = powerOfTwo << 1;
- }
- return powerOfTwo;
-};
-
-/**
- * Gets the version of the installed plugin.
- * @return {?string} version string in 'major.minor.revision.build' format.
- * If the plugin does not exist returns null.
- */
-o3djs.util.getPluginVersion = function() {
- var version = null;
- var description = null;
- if (navigator.plugins != null && navigator.plugins.length > 0) {
- var plugin = navigator.plugins[o3djs.util.PLUGIN_NAME];
- if (plugin) {
- description = plugin.description;
- }
- } else if (o3djs.base.IsMSIE()) {
- try {
- var activeXObject = new ActiveXObject('o3d_host.O3DHostControl');
- description = activeXObject.description;
- } catch (e) {
- // O3D plugin was not found.
- }
- }
- if (description) {
- var re = /.*version:\s*(\d+)\.(\d+)\.(\d+)\.(\d+).*/;
- // Parse the version out of the description.
- var parts = re.exec(description);
- if (parts && parts.length == 5) {
- // make sure the format is #.#.#.# no whitespace, no trailing comments
- version = '' + parseInt(parts[1], 10) + '.' +
- parseInt(parts[2], 10) + '.' +
- parseInt(parts[3], 10) + '.' +
- parseInt(parts[4], 10);
- }
- }
- return version;
-};
-
-/**
- * Checks if the required version of the plugin in available.
- * @param {string} requiredVersion version string in
- * "major.minor.revision.build" format. You can leave out any non-important
- * numbers for example "3" = require major version 3, "2.4" = require major
- * version 2, minor version 4.
- * @return {boolean} True if the required version is available.
- */
-o3djs.util.requiredVersionAvailable = function(requiredVersion) {
- var version = o3djs.util.getPluginVersion();
- if (!version) {
- return false;
- }
- var haveParts = version.split('.');
- var requiredParts = requiredVersion.split('.');
- if (requiredParts.length > 4) {
- throw Error('requiredVersion has more than 4 parts!');
- }
- for (var pp = 0; pp < requiredParts.length; ++pp) {
- var have = parseInt(haveParts[pp], 10);
- var required = parseInt(requiredParts[pp], 10);
- if (have < required) {
- return false;
- }
- if (have > required) {
- return true;
- }
- }
- return true;
-};
-
-/**
- * Gets all the elements of a certain tag that have a certain id.
- * @param {string} tag The tag to look for. (eg. 'div').
- * @param {string} id The id to look for. This can be a regular expression.
- * @return {!Array.<!Element>} An array of the elements found.
- */
-o3djs.util.getElementsByTagAndId = function(tag, id) {
- var elements = [];
- var allElements = document.getElementsByTagName(tag);
- for (var ee = 0; ee < allElements.length; ++ee) {
- var element = allElements[ee];
- if (element.id && element.id.match(id)) {
- elements.push(element);
- }
- }
- return elements;
-};
-
-/**
- * Gets all the Elements that contain or would contain O3D plugin objects.
- * @param {string} opt_id The id to look for. This can be a regular
- * expression. The default is "^o3d".
- * @param {string} opt_tag The type of tag to look for. The default is "div".
- */
-o3djs.util.getO3DContainerElements = function(opt_id, opt_tag) {
- var tag = opt_tag || 'div';
- var id = opt_id || '^o3d';
- return o3djs.util.getElementsByTagAndId(tag, id);
-}
-
-/**
- * Offers the user the option to download the plugin.
- *
- * Finds all divs with the id "^o3d" and inserts a message and link
- * inside to download the plugin. If no areas exist OR if none of them are
- * large enough for the message then displays an alert.
- *
- * @param {string} opt_id The id to look for. This can be a regular
- * expression. The default is "^o3d".
- * @param {string} opt_tag The type of tag to look for. The default is "div".
- */
-o3djs.util.offerPlugin = function(opt_id, opt_tag) {
- var havePlugin = o3djs.util.requiredVersionAvailable('');
- var elements = o3djs.util.getO3DContainerElements(opt_id, opt_tag);
- var addedMessage = false;
- // TODO: This needs to be localized OR we could insert a html like
- // <script src="http://google.com/o3d_plugin_dl"></script>
- // in which case google could serve the message localized and update the
- // link.
- var subMessage =
- (havePlugin ?
- 'This page requires a newer version of the O3D plugin.' :
- 'This page requires the O3D plugin to be installed.');
- var message =
- '<div style="background: lightblue; width: 100%; height: 100%; ' +
- 'text-align:center;">' +
- '<br/><br/>' + subMessage + '<br/>' +
- '<a href="' + o3djs.util.PLUGIN_DOWNLOAD_URL +
- '">Click here to download.</a>' +
- '</div>'
- for (var ee = 0; ee < elements.length; ++ee) {
- var element = elements[ee];
- if (element.clientWidth >= o3djs.util.MINIMUM_WIDTH_FOR_MESSAGE &&
- element.clientHeight >= o3djs.util.MINIMUM_HEIGHT_FOR_MESSAGE &&
- element.style.display.toLowerCase() != 'none' &&
- element.style.visibility.toLowerCase() != 'hidden') {
- addedMessage = true;
- element.innerHTML = message;
- }
- }
- if (!addedMessage) {
- if (confirm(subMessage + '\n\nClick OK to download.')) {
- window.location = o3djs.util.PLUGIN_DOWNLOAD_URL;
- }
- }
-};
-
-/**
- * Tells the user their graphics card is not able to run the plugin or is out
- * of resources etc.
- *
- * Finds all divs with the id "^o3d" and inserts a message. If no areas
- * exist OR if none of them are large enough for the message then displays an
- * alert.
- *
- * @param {!o3d.Renderer.InitStatus} initStatus The initializaion status of
- * the renderer.
- * @param {string} error An error message. Will be '' if there is no message.
- * @param {string} opt_id The id to look for. This can be a regular
- * expression. The default is "^o3d".
- * @param {string} opt_tag The type of tag to look for. The default is "div".
- */
-o3djs.util.informNoGraphics = function(initStatus, error, opt_id, opt_tag) {
- var elements = o3djs.util.getO3DContainerElements(opt_id, opt_tag);
- var addedMessage = false;
- var subMessage;
- var message;
- var alertMessage = '';
- var alertFunction = function() { };
-
- var moreInfo = function(error) {
- var html = '';
- if (error.length > 0) {
- html = '' +
- '<br/><br/><div>More Info:<br/>' + error + '</div>';
- }
- return html;
- };
-
- // TODO: This needs to be localized OR we could insert a html like
- // <script src="http://google.com/o3d_plugin_dl"></script>
- // in which case google could serve the message localized and update the
- // link.
- if (initStatus == o3djs.util.rendererInitStatus.GPU_NOT_UP_TO_SPEC) {
- subMessage =
- 'We are terribly sorry but it appears your graphics card is not ' +
- 'able to run o3d. We are working on a solution.';
- message =
- '<div style="background: lightgray; width: 100%; height: 100%; ' +
- 'text-align: center;">' +
- '<br/><br/>' + subMessage +
- '<br/><br/><a href="' + o3djs.util.PLUGIN_DOWNLOAD_URL +
- '">Click Here to go the O3D website</a>' +
- moreInfo(error) +
- '</div>';
- alertMessage = '\n\nClick OK to go to the o3d website.';
- alertFunction = function() {
- window.location = o3djs.util.PLUGIN_DOWNLOAD_URL;
- };
- } else if (initStatus == o3djs.util.rendererInitStatus.OUT_OF_RESOURCES) {
- subMessage =
- 'Your graphics system appears to be out of resources. Try closing ' +
- 'some applications and then refreshing this page.';
- message =
- '<div style="background: lightgray; width: 100%; height: 100%; ' +
- 'text-align: center;">' +
- '<br/><br/>' + subMessage +
- moreInfo(error) +
- '</div>';
- } else {
- subMessage =
- 'A unknown error has prevented O3D from starting. Try downloading ' +
- 'new drivers or checking for OS updates.';
- message =
- '<div style="background: lightgray; width: 100%; height: 100%; ' +
- 'text-align: center;">' +
- '<br/><br/>' + subMessage +
- moreInfo(error) +
- '</div>';
- }
- for (var ee = 0; ee < elements.length; ++ee) {
- var element = elements[ee];
- if (element.clientWidth >= o3djs.util.MINIMUM_WIDTH_FOR_MESSAGE &&
- element.clientHeight >= o3djs.util.MINIMUM_HEIGHT_FOR_MESSAGE &&
- element.style.display.toLowerCase() != 'none' &&
- element.style.visibility.toLowerCase() != 'hidden') {
- addedMessage = true;
- element.innerHTML = message;
- }
- }
- if (!addedMessage) {
- if (confirm(subMessage + alertMessage)) {
- alertFunction();
- }
- }
-};
-
-/**
- * Handles failure to create the plugin.
- *
- * @param {!o3d.Renderer.InitStatus} initStatus The initializaion status of
- * the renderer.
- * @param {string} error An error message. Will be '' if there is no message.
- * @param {string} opt_id The id to look for. This can be a regular
- * expression. The default is "^o3d".
- * @param {string} opt_tag The type of tag to look for. The default is "div".
- */
-o3djs.util.informPluginFailure = function(initStatus, error, opt_id, opt_tag) {
- if (initStatus == o3djs.util.rendererInitStatus.NO_PLUGIN) {
- o3djs.util.offerPlugin(opt_id, opt_tag);
- } else {
- o3djs.util.informNoGraphics(initStatus, error, opt_id, opt_tag);
- }
-};
-
-/**
- * Utility to get the text contents of a DOM element with a particular ID.
- * Currently only supports textarea and script nodes.
- * @param {string} id The Node id.
- * @return {string} The text content.
- */
-o3djs.util.getElementContentById = function(id) {
- // DOM manipulation is not currently supported in IE.
- o3djs.BROWSER_ONLY = true;
-
- var node = document.getElementById(id);
- if (!node) {
- throw 'getElementContentById could not find node with id ' + id;
- }
- switch (node.tagName) {
- case 'TEXTAREA':
- return node.value;
- case 'SCRIPT':
- return node.text;
- default:
- throw 'getElementContentById does not no how to get content from a ' +
- node.tagName + ' element';
- }
-};
-
-/**
- * Utility to get an element from the DOM by ID. This must be used from V8
- * in preference to document.getElementById because we do not currently
- * support invoking methods on DOM objects in IE.
- * @param {string} id The Element id.
- * @return {Element} The Element or null if not found.
- */
-o3djs.util.getElementById = function(id) {
- o3djs.BROWSER_ONLY = true;
- return document.getElementById(id);
-};
-
-/**
- * Identifies a JavaScript engine.
- * @enum {number}
- */
-o3djs.util.Engine = {
- /**
- * The JavaScript engine provided by the browser.
- */
- BROWSER: 0,
- /**
- * The V8 JavaScript engine embedded in the plugin.
- */
- V8: 1
-};
-
-/**
- * The engine selected as the main engine (the one the makeClients callback
- * will be invoked on).
- * @private
- * @type {o3djs.util.Engine}
- */
-o3djs.util.mainEngine_ = o3djs.util.Engine.BROWSER;
-
-/**
- * Checks the user agent string for substring s, returning true if it appears.
- * @return {boolean} Whether the browser's user-agent string contains string s.
- */
-function o3djs_navHas(s) {
- return navigator.userAgent.indexOf(s) != -1;
-}
-
-/**
- * Checks for V8 support. This is to cope with environments where our V8 is
- * known to be problematic, eg Safari on 10.6.
- * @return {boolean} Whether the environment supports V8.
- */
-function o3djs_isV8Supported() {
- if (o3djs_navHas('Chrome'))
- return true;
- if (!o3djs_navHas('Safari'))
- return true;
- return !o3djs_navHas('Intel Mac OS X 10_6');
-}
-
-/**
- * Select an engine to use as the main engine (the one the makeClients
- * callback will be invoked on). If an embedded engine is requested, one
- * element must be identified with the id 'o3d'. The callback will be invoked
- * in this element.
- * Ignores attempts to choose V8 if it is not supported in this host.
- * @param {o3djs.util.Engine} engine The engine.
- */
-o3djs.util.setMainEngine = function(engine) {
- if ((engine == o3djs.util.Engine.V8) && !o3djs_isV8Supported()) {
- engine = o3djs.util.Engine.BROWSER;
- }
- o3djs.util.mainEngine_ = engine;
-};
-
-/**
- * A regex used to cleanup the string representation of a function before
- * it is evaled.
- * @private
- * @type {!RegExp}
- */
-o3djs.util.fixFunctionString_ = /^\s*function\s+[^\s]+\s*\(([^)]*)\)/
-
-/**
- * Evaluate a callback function in the V8 engine.
- * @param {!Object} clientElement The plugin containing the V8 engine.
- * @param {!function(...): *} callback A function to call.
- * @param {!Object} thisArg The value to be bound to "this".
- * @param {!Array.<*>} args The arguments to pass to the callback.
- * @return {*} The result of calling the callback.
- */
-o3djs.util.callV8 = function(clientElement, callback, thisArg, args) {
- // Sometimes a function will be converted to a string like this:
- // function foo(a, b) { ... }
- // In this case, convert to this form:
- // function(a, b) { ... }
- var functionString = callback.toString();
- functionString = functionString.replace(o3djs.util.fixFunctionString_,
- 'function($1)');
-
- // Make a V8 function that will invoke the callback.
- var v8Code =
- 'function(thisArg, args) {\n' +
- ' var localArgs = [];\n' +
- ' var numArgs = args.length;\n' +
- ' for (var i = 0; i < numArgs; ++i) {\n' +
- ' localArgs.push(args[i]);\n' +
- ' }\n' +
- ' var func = ' + functionString + ';\n' +
- ' return func.apply(thisArg, localArgs);\n' +
- '}\n';
-
- // Evaluate the function in V8.
- var v8Function = clientElement.eval(v8Code);
- return v8Function(thisArg, args);
-};
-
-/**
- * A regex to remove .. from a URI.
- * @private
- * @type {!RegExp}
- */
-o3djs.util.stripDotDot_ = /\/[^\/]+\/\.\./;
-
-/**
- * Turn a URI into an absolute URI.
- * @param {string} uri The URI.
- * @return {string} The absolute URI.
- */
-o3djs.util.toAbsoluteUri = function(uri) {
- if (uri.indexOf('://') == -1) {
- var baseUri = document.location.toString();
- var lastSlash = baseUri.lastIndexOf('/');
- if (lastSlash != -1) {
- baseUri = baseUri.substring(0, lastSlash);
- }
- uri = baseUri + '/' + uri;
- }
-
- do {
- var lastUri = uri;
- uri = uri.replace(o3djs.util.stripDotDot_, '');
- } while (lastUri !== uri);
-
- return uri;
-};
-
-/**
- * The script URIs.
- * @private
- * @type {!Array.<string>}
- */
-o3djs.util.scriptUris_ = [];
-
-/**
- * Add a script URI. Scripts that are referenced from script tags that are
- * within this URI are automatically loaded into the alternative JavaScript
- * main JavaScript engine. Do not include directories of scripts that are
- * included with o3djs.require. These are always available. This mechanism
- * is not able to load scripts in a different domain from the document.
- * @param {string} uri The URI.
- */
-o3djs.util.addScriptUri = function(uri) {
- o3djs.util.scriptUris_.push(o3djs.util.toAbsoluteUri(uri));
-};
-
-/**
- * Determine whether a URI is a script URI that should be loaded into the
- * alternative main JavaScript engine.
- * @param {string} uri The URI.
- * @return {boolean} Whether it is a script URI.
- */
-o3djs.util.isScriptUri = function(uri) {
- uri = o3djs.util.toAbsoluteUri(uri);
- for (var i = 0; i < o3djs.util.scriptUris_.length; ++i) {
- var scriptUri = o3djs.util.scriptUris_[i];
- if (uri.substring(0, scriptUri.length) === scriptUri) {
- return true;
- }
- }
- return false;
-};
-
-/**
- * Returns whether or not this is a script tag we want. Currently that is
- * only script tags with an id that starts with "o3d".
- * @private
- * @param {!Element} scriptElement The script element to check.
- * @return {boolean} True if we want this script tag.
- */
-o3djs.util.isWantedScriptTag_ = function(scriptElement) {
- return scriptElement.id && scriptElement.id.match(/^o3dscript/);
-};
-
-/**
- * Concatenate the text of all the script tags in the document and invokes
- * the callback when complete. This function is asynchronous if any of the
- * script tags reference JavaScript through a URI.
- * @private
- * @return {string} The script tag text.
- */
-o3djs.util.getScriptTagText_ = function() {
- var scriptTagText = '';
- var scriptElements = document.getElementsByTagName('script');
- for (var i = 0; i < scriptElements.length; ++i) {
- var scriptElement = scriptElements[i];
- if (scriptElement.type === '' ||
- scriptElement.type === 'text/javascript') {
- if ('text' in scriptElement && scriptElement.text &&
- o3djs.util.isWantedScriptTag_(scriptElement)) {
- scriptTagText += scriptElement.text;
- }
- if ('src' in scriptElement && scriptElement.src &&
- o3djs.util.isScriptUri(scriptElement.src)) {
- // It would be better to make this an asynchronous load but the script
- // file is very likely to be in the browser cache because it should
- // have just been loaded via the browser script tag.
- scriptTagText += o3djs.io.loadTextFileSynchronous(scriptElement.src);
- }
- }
- }
- return scriptTagText;
-};
-
-/**
- * Creates a client element. In other words it creates an <OBJECT> tag for o3d.
- * <b>Note that the browser may not have initialized the plugin before
- * returning.</b>
- * @param {!Element} element The DOM element under which the client element
- * will be appended.
- * @param {string} opt_features A comma separated list of the
- * features you need for your application. The current list of features:
- * <li>FloatingPointTextures: Includes the formats R32F, ABGR16F and
- * ABGR32F</li>
- * The features are case sensitive.
- * @param {string} opt_requestVersion version string in
- * "major.minor.revision.build" format. You can leave out any non-important
- * numbers for example "3" = request major version 3, "2.4" = request major
- * version 2, minor version 4. If no string is passed in the newest version
- * of the plugin will be created.
- * @return {Element} O3D element or null if requested version is not
- * available.
- */
-o3djs.util.createClient = function(element, opt_features, opt_requestVersion) {
- opt_features = opt_features || '';
- opt_requestVersion = opt_requestVersion || o3djs.util.REQUIRED_VERSION;
- if (!o3djs.util.requiredVersionAvailable(opt_requestVersion)) {
- return null;
- }
- opt_features += (opt_features ? ',' : '') + 'APIVersion=' +
- opt_requestVersion;
- var objElem;
- // TODO: Use opt_requiredVersion to set a version so the plugin
- // can make sure it offers that version of the API.
- // Note: The IE version of the plug-in does not receive attributes during
- // construction, unless the innerHTML construction style is used.
- if (o3djs.base.IsMSIE()) {
- element.innerHTML =
- '<OBJECT ' +
- 'WIDTH="100%" HEIGHT="100%"' +
- 'CLASSID="CLSID:9666A772-407E-4F90-BC37-982E8160EB2D">' +
- '<PARAM name="o3d_features" value="' + opt_features + '"/>' +
- '</OBJECT>';
- objElem = element.childNodes[0];
- } else {
- objElem = document.createElement('object');
- objElem.type = 'application/vnd.o3d.auto';
- objElem.style.width = '100%';
- objElem.style.height = '100%';
- objElem.setAttribute('o3d_features', opt_features);
- element.appendChild(objElem);
- }
-
- if (objElem.client.clientInfo.glsl) {
- o3djs.effect.setLanguage('glsl');
- }
-
- return objElem;
-};
-
-/**
- * Finds all divs with the an id that starts with "o3d" and inserts a client
- * area inside.
- *
- * NOTE: the size of the client area is always set to 100% which means the div
- * must have its size set or managed by the browser. Examples:
- *
- * -- A div of a specific size --
- * &lt;div id="o3d" style="width:800px; height:600px">&lt;/div>
- *
- * -- A div that fills its containing element --
- * &lt;div id="o3d" style="width:100%; height:100%">&lt;/div>
- *
- * In both cases, a DOCTYPE is probably required.
- *
- * You can also request certain features by adding the attribute
- * 'o3d_features' as in
- *
- * &lt;div id="o3d" o3d_features="FloatingPointTextures">&lt;/div>
- *
- * This allows you to specify different features per area. Otherwise you can
- * request features as an argument to this function.
- *
- * Normally this function handles failure for you but if you want to handle
- * failure in your own way you can supply a failure callback. Here is an example
- * of using this function with your own failure callback.
- *
- * <pre>
- * &lt;script type="text/javascript" id="o3dscript"&gt;
- * o3djs.require('o3djs.util');
- *
- * window.onload = init;
- *
- * function init() {
- * o3djs.util.makeClients(onSuccess, '', undefined, onFailure);
- * }
- *
- * function onFailure(initStatus, error, id, tag) {
- * // Get a list of the elements that would have had an O3D plugin object
- * // inserted if it had succeed.
- * var elements = o3djs.util.getO3DContainerElements(id, tag);
- *
- * switch (initStatus) {
- * case o3djs.util.rendererInitStatus.NO_PLUGIN:
- * // Tell the user there is no plugin
- * ...
- * break;
- * case o3djs.util.rendererInitStatus.OUT_OF_RESOURCES:
- * case o3djs.util.rendererInitStatus.GPU_NOT_UP_TO_SPEC:,
- * case o3djs.util.rendererInitStatus.INITIALIZATION_ERROR:
- * default:
- * // Tell the user there are other issues
- * ...
- * break;
- * }
- * }
- *
- * function onSuccess(o3dElementsArray) {
- * // Run your app.
- * ...
- * }
- * &lt;/script&gt;
- * </pre>
- *
- * @param {!function(Array.<!Element>): void} callback Function to call when
- * client objects have been created.
- * @param {string} opt_features A comma separated list of the
- * features you need for your application. The current list of features:
- *
- * <li>FloatingPointTextures: Includes the formats R32F, ABGR16F and
- * ABGR32F</li>
- * <li>LargeGeometry: Allows buffers to have more than 65534 elements.</li>
- * <li>NotAntiAliased: Turns off anti-aliasing</li>
- * <li>InitStatus=X: Where X is a number. Allows simulatation of the plugin
- * failing</li>
- *
- * The features are case sensitive.
- * @param {string} opt_requiredVersion version string in
- * "major.minor.revision.build" format. You can leave out any
- * non-important numbers for example "3" = require major version 3,
- * "2.4" = require major version 2, minor version 4. If no string is
- * passed in the version of the needed by this version of the javascript
- * libraries will be created.
- * @param {!function(!o3d.Renderer.InitStatus, string, (string|undefined),
- * (string|undefined)): void} opt_failureCallback Function to call if the
- * plugin does not exist, if the required version is not installed, or if
- * for some other reason the plugin can not start. If this function is not
- * specified or is null the default behavior of leading the user to the
- * download page will be provided. See o3djs.util.informPluginFailure for an
- * example of this type of callback.
- * @param {string} opt_id The id to look for. This can be a regular
- * expression. The default is "^o3d".
- * @param {string} opt_tag The type of tag to look for. The default is "div".
- * @see o3djs.util.informPluginFailure
- */
-o3djs.util.makeClients = function(callback,
- opt_features,
- opt_requiredVersion,
- opt_failureCallback,
- opt_id,
- opt_tag) {
- opt_failureCallback = opt_failureCallback || o3djs.util.informPluginFailure;
- opt_requiredVersion = opt_requiredVersion || o3djs.util.REQUIRED_VERSION;
- if (!o3djs.util.requiredVersionAvailable(opt_requiredVersion)) {
- opt_failureCallback(o3djs.util.rendererInitStatus.NO_PLUGIN, '',
- opt_id, opt_tag);
- } else {
- var clientElements = [];
- var elements = o3djs.util.getO3DContainerElements(opt_id, opt_tag);
- var mainClientElement = null;
- for (var ee = 0; ee < elements.length; ++ee) {
- var element = elements[ee];
- var features = opt_features;
- if (!features) {
- var o3d_features = element.getAttribute('o3d_features');
- if (o3d_features) {
- features = o3d_features;
- } else {
- features = '';
- }
- }
-
- var objElem = o3djs.util.createClient(element, features);
- clientElements.push(objElem);
-
- // If the callback is to be invoked in an embedded JavaScript engine,
- // one element must be identified with the id 'o3d'. This callback
- // will be invoked in the element identified as such.
- if (element.id === 'o3d') {
- mainClientElement = objElem;
- }
- }
-
- // Wait for the browser to initialize the clients.
- var clearId = window.setInterval(function() {
- var initStatus = 0;
- var error = '';
- var o3d;
- for (var cc = 0; cc < clientElements.length; ++cc) {
- var element = clientElements[cc];
- o3d = element.o3d;
- var ready = o3d &&
- element.client &&
- element.client.rendererInitStatus >
- o3djs.util.rendererInitStatus.UNINITIALIZED;
- if (!ready) {
- return;
- }
- var status = clientElements[cc].client.rendererInitStatus;
- // keep the highest status. This is the worst status.
- if (status > initStatus) {
- initStatus = status;
- error = clientElements[cc].client.lastError;
- }
- }
-
- window.clearInterval(clearId);
-
- // If the plugin could not initialize the graphics delete all of
- // the plugin objects
- if (initStatus > 0 && initStatus != o3d.Renderer.SUCCESS) {
- for (var cc = 0; cc < clientElements.length; ++cc) {
- var clientElement = clientElements[cc];
- clientElement.parentNode.removeChild(clientElement);
- }
- opt_failureCallback(initStatus, error, opt_id, opt_tag);
- } else {
- o3djs.base.snapshotProvidedNamespaces();
-
- // TODO: Is this needed with the new event code?
- for (var cc = 0; cc < clientElements.length; ++cc) {
- // Based on v8 support test, not on current engine, as V8
- // still needs to be initialized even with o3djs.util.Engine.BROWSER
- // on some configs.
- if (o3djs_isV8Supported())
- o3djs.base.initV8(clientElements[cc]);
- o3djs.event.startKeyboardEventSynthesis(clientElements[cc]);
- o3djs.error.setDefaultErrorHandler(clientElements[cc].client);
- }
- o3djs.base.init(clientElements[0]);
-
- switch (o3djs.util.mainEngine_) {
- case o3djs.util.Engine.BROWSER:
- callback(clientElements);
- break;
- case o3djs.util.Engine.V8:
- if (!mainClientElement) {
- throw 'V8 engine was requested but there is no element with' +
- ' the id "o3d"';
- }
-
- // Retreive the code from the script tags and eval it in V8 to
- // duplicate the browser environment.
- var scriptTagText = o3djs.util.getScriptTagText_();
- mainClientElement.eval(scriptTagText);
-
- // Invoke the callback in V8.
- o3djs.util.callV8(mainClientElement,
- callback,
- o3djs.global,
- [clientElements]);
- break;
- default:
- throw 'Unknown engine ' + o3djs.util.mainEngine_;
- }
- }
- }, 10);
- }
-};
-
diff --git a/o3d/samples/o3djs/webgl.js b/o3d/samples/o3djs/webgl.js
deleted file mode 100644
index b7c4111..0000000
--- a/o3d/samples/o3djs/webgl.js
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains utility functions for o3d running on
- * top of webgl. The function o3djs.webgl.makeClients replaces the
- * function o3djs.util.makeClients.
- */
-
-o3djs.provide('o3djs.webgl');
-
-o3djs.require('o3djs.effect');
-o3djs.require('o3djs.util');
-
-
-/**
- * A Module with various utilities.
- * @namespace
- */
-o3djs.webgl = o3djs.webgl || {};
-
-
-/**
- * Takes a javascript object containing name-value pairs of options to
- * makeClients or createClient and adds options to the default value if they
- * aren't already there setting them to the default value.
- * @param {Object} The obejct containing options.
- */
-o3djs.webgl.setUndefinedOptionsToDefaults_ = function(options) {
- /**
- * Whether to install debugging functions, and selectable
- * @type {boolean}
- */
- options.debug = options.debug || false;
-
- /**
- * Whether to allow the canvas object created to remain selectable.
- * @type {boolean}
- */
- options.selectable = options.selectable || false;
-};
-
-
-/**
- * Finds all divs with an id that starts with "o3d" and inits a canvas
- * under them with o3d client object and the o3d namespace.
- * @param {!function(Array.<!Element>): void} callback Function to call when
- * client objects have been created.
- * @param {Object} opt_options An object mapping various options to their values
- * See comment for o3djs.webgl.setUndefinedOptionsToDefaults_ to see what
- * options there are.
- * @param {string} opt_requiredVersion Ignored in o3d-webgl.
- * @param {!function(!o3d.Renderer.InitStatus, string, (string|undefined),
- * (string|undefined)): void} opt_failureCallback Called with an error
- * string if the client fails to create.
- * @param {string} opt_id The id to look for. This can be a regular
- * expression. The default is "^o3d".
- * @param {string} opt_tag The type of tag to look for. The default is "div".
- * @see o3djs.util.informPluginFailure
- */
-o3djs.webgl.makeClients = function(callback,
- opt_options,
- opt_requiredVersion,
- opt_failureCallback,
- opt_id,
- opt_tag) {
- opt_failureCallback = opt_failureCallback || o3djs.util.informPluginFailure;
- var options = opt_options;
-
- // If opt_options is a string, we assume it's coming from formerly plugin
- // code and ignore it. If it's an object, we assume it's the name-value-pair
- // object describing the optional arguments to this function.
- if (options == undefined || typeof options == 'string') {
- options = {};
- }
- o3djs.webgl.setUndefinedOptionsToDefaults_(options);
-
- var clientElements = [];
- var elements = o3djs.util.getO3DContainerElements(opt_id, opt_tag);
-
- for (var ee = 0; ee < elements.length; ++ee) {
- var element = elements[ee];
- var objElem = o3djs.webgl.createClient(element, options, options.debug);
- if (!objElem) {
- opt_failureCallback('Failed to create o3d-webgl client object.');
- return;
- }
- clientElements.push(objElem);
- }
-
- // Wait for the client elements to be fully initialized. This
- // involves waiting for the page to fully layout and the initial
- // resize event to be processed.
- var clearId = window.setInterval(function() {
- for (var cc = 0; cc < clientElements.length; ++cc) {
- var element = clientElements[cc];
- if (!element.sizeInitialized_) {
- return;
- }
- }
- window.clearInterval(clearId);
- callback(clientElements);
- });
-};
-
-
-/**
- * Adds a wrapper object to single gl function context that checks for errors
- * before the call.
- * @param {WebGLContext} context
- * @param {string} fname The name of the function.
- * @return {}
- */
-o3djs.webgl.createGLErrorWrapper = function(context, fname) {
- return function() {
- var rv = context[fname].apply(context, arguments);
- var err = context.getError();
- if (err != 0) {
- throw "GL error " + err + " in " + fname;
- }
- return rv;
- };
-};
-
-
-/**
- * Adds a wrapper object to a webgl context that checks for errors
- * before each function call.
- */
-o3djs.webgl.addDebuggingWrapper = function(context) {
- // Thanks to Ilmari Heikkinen for the idea on how to implement this
- // so elegantly.
- var wrap = {};
- for (var i in context) {
- if (typeof context[i] == 'function') {
- wrap[i] = o3djs.webgl.createGLErrorWrapper(context, i);
- } else {
- wrap[i] = context[i];
- }
- }
- wrap.getError = function() {
- return context.getError();
- };
- return wrap;
-};
-
-
-/**
- * Inserts text indicating that a WebGL context could not be created under
- * the given node and links to the site about WebGL capable browsers.
- */
-o3djs.webgl.webGlCanvasError = function(parentNode, unavailableElement) {
- var background = document.createElement('div');
- background.style.backgroundColor = '#ccffff';
- background.style.textAlign = 'center';
- background.style.margin = '10px';
- background.style.width = '100%';
- background.style.height = '100%';
-
- var messageHTML = '<br/><br/><a href="http://get.webgl.org">' +
- 'Your browser does not appear to support WebGL.<br/><br/>' +
- 'Check that WebGL is enabled or click here to upgrade your browser:' +
- '</a><br/>';
-
- background.innerHTML = messageHTML;
-
- parentNode.appendChild(background);
-};
-
-
-/**
- * Creates a canvas under the given parent element and an o3d.Client
- * under that.
- *
- * @param {!Element} element The element under which to insert the client.
- * @param {Object} opt_options A javascript object containing
- * @param {boolean} opt_debug Whether gl debugging features should be
- * enabled.
- * @return {HTMLCanvas} The canvas element, or null if initializaton failed.
- */
-o3djs.webgl.createClient = function(element, opt_options, opt_debug) {
- var options = opt_options;
-
- // If opt_options is a string, we assume it's coming from formerly plugin
- // code and ignore it. If it's an object, we assume it's the name-value-pair
- // object describing the optional arguments to this function.
- if (opt_options == undefined || typeof opt_options == 'string') {
- options = {};
- options.debug = opt_debug;
- }
- o3djs.webgl.setUndefinedOptionsToDefaults_(options);
-
- opt_debug = opt_debug || false;
-
- // If we're creating a webgl client, the assumption is we're using webgl,
- // in which case the only acceptable shader language is glsl. So, here
- // we set the shader language to glsl.
- o3djs.effect.setLanguage('glsl');
-
- // Make the canvas automatically resize to fill the containing
- // element (div), and initialize its size correctly.
- var canvas;
- canvas = document.createElement('canvas');
-
- if (!canvas || !canvas.getContext) {
- o3djs.webgl.webGlCanvasError(element, 'HTMLCanvas');
- return null;
- }
-
- canvas.style.width = "100%";
- canvas.style.height = "100%";
-
- var client = new o3d.Client;
-
- var resizeHandler = function() {
- var width = Math.max(1, canvas.clientWidth);
- var height = Math.max(1, canvas.clientHeight);
- canvas.width = width;
- canvas.height = height;
- canvas.sizeInitialized_ = true;
- if (client.gl) {
- client.gl.displayInfo = {width: canvas.width, height: canvas.height};
- }
- };
- window.addEventListener('resize', resizeHandler, false);
- setTimeout(resizeHandler, 0);
-
- if (!client.initWithCanvas(canvas)) {
- o3djs.webgl.webGlCanvasError(element, 'WebGL context');
- return null;
- }
-
- if (!options.selectable) {
- // This keeps the cursor from changing to an I-beam when the user clicks
- // and drags. It's easier on the eyes.
- function returnFalse() {
- return false;
- }
- canvas.onselectstart = returnFalse;
- canvas.onmousedown = returnFalse;
- }
-
- canvas.client = client;
- canvas.o3d = o3d;
-
- if (options.debug) {
- client.gl = o3djs.webgl.addDebuggingWrapper(client.gl);
- }
-
- element.appendChild(canvas);
- return canvas;
-};
-
-