diff options
author | petersont@google.com <petersont@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-26 18:17:10 +0000 |
---|---|---|
committer | petersont@google.com <petersont@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-26 18:17:10 +0000 |
commit | 7a130f3789ad66ea6a3ed381c0a581ac3dab9bf3 (patch) | |
tree | cf1a017558144f55bbc8ff23d0f7e29739987e67 /o3d/samples | |
parent | 7526811eaf3754199f502c4b751a2f41ffe67272 (diff) | |
download | chromium_src-7a130f3789ad66ea6a3ed381c0a581ac3dab9bf3.zip chromium_src-7a130f3789ad66ea6a3ed381c0a581ac3dab9bf3.tar.gz chromium_src-7a130f3789ad66ea6a3ed381c0a581ac3dab9bf3.tar.bz2 |
First check in of the o3d implimentation in webgl. Classes work well enough to run the hellocube sample.
Review URL: http://codereview.chromium.org/561026
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40133 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/samples')
40 files changed, 8656 insertions, 0 deletions
diff --git a/o3d/samples/o3d-webgl-samples/hellocube.html b/o3d/samples/o3d-webgl-samples/hellocube.html new file mode 100644 index 0000000..f0db297f --- /dev/null +++ b/o3d/samples/o3d-webgl-samples/hellocube.html @@ -0,0 +1,300 @@ +<!-- +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. +--> + +<!-- +This sample shows how to place an O3D area in a page and draw simple +3D shape in it. +--> +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> +<meta http-equiv="content-type" content="text/html; charset=UTF-8"> +<title> +Hello Cube: Getting started with O3D +</title> +<script type="text/javascript" src="../o3d-webgl/base.js"></script> +<script type="text/javascript" src="../o3djs/base.js"></script> +<script type="text/javascript" id="o3dscript"> +o3djs.base.o3d = o3d; +o3djs.require('o3djs.webgl'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.rendergraph'); + +// Events +// Run the init() function once the page has finished loading. +// Run the uninit() function when the page has is unloaded. +window.onload = init; +window.onunload = uninit; + +// global variables +var g_o3d; +var g_math; +var g_client; +var g_pack; +var g_clock = 0; +var g_timeMult = 1; +var g_cubeTransform = null; +var g_finished = false; // for selenium testing + +/** + * Creates an O3D shape representing a cube. The shape consists of + * a single primitive with eight vertices and 12 triangles (two for each face + * of the cube). + * @param {o3d.Material} material the material used by the primitive. + * @return {o3d.Shape} The Shape object created. + */ +function createCube(material) { + // Create a Shape object for the mesh. + var cubeShape = g_pack.createObject('Shape'); + + // Create the Primitive that will contain the geometry data for + // the cube. + var cubePrimitive = g_pack.createObject('Primitive'); + + // Create a StreamBank to hold the streams of vertex data. + var streamBank = g_pack.createObject('StreamBank'); + + // Assign the material that was passed in to the primitive. + cubePrimitive.material = material; + + // Assign the Primitive to the Shape. + cubePrimitive.owner = cubeShape; + + // Assign the StreamBank to the Primitive. + cubePrimitive.streamBank = streamBank; + + // The cube is made of 12 triangles. There's eight vertices in total which + // are shared between the face triangles. + cubePrimitive.primitiveType = g_o3d.Primitive.TRIANGLELIST; + cubePrimitive.numberPrimitives = 12; // 12 triangles + cubePrimitive.numberVertices = 8; // 8 vertices in total + + // Generate the draw element for the cube primitive. + cubePrimitive.createDrawElement(g_pack, null); + + // Create a javascript array that stores the X, Y and Z coordinates of each + // of the 8 corners of the cube. + var positionArray = [ + -0.5, -0.5, 0.5, // vertex 0 + 0.5, -0.5, 0.5, // vertex 1 + -0.5, 0.5, 0.5, // vertex 2 + 0.5, 0.5, 0.5, // vertex 3 + -0.5, 0.5, -0.5, // vertex 4 + 0.5, 0.5, -0.5, // vertex 5 + -0.5, -0.5, -0.5, // vertex 6 + 0.5, -0.5, -0.5 // vertex 7 + ]; + + // The following array defines how vertices are to be put together to form + // the triangles that make up the cube's faces. In the index array, every + // three elements define a triangle. So for example vertices 0, 1 and 2 + // make up the first triangle, vertices 2, 1 and 3 the second one, etc. + var indicesArray = [ + 0, 1, 2, // face 1 + 2, 1, 3, + 2, 3, 4, // face 2 + 4, 3, 5, + 4, 5, 6, // face 3 + 6, 5, 7, + 6, 7, 0, // face 4 + 0, 7, 1, + 1, 7, 3, // face 5 + 3, 7, 5, + 6, 0, 4, // face 6 + 4, 0, 2 + ]; + + // Create buffers containing the vertex data. + var positionsBuffer = g_pack.createObject('VertexBuffer'); + var positionsField = positionsBuffer.createField('FloatField', 3); + positionsBuffer.set(positionArray); + + var indexBuffer = g_pack.createObject('IndexBuffer'); + indexBuffer.set(indicesArray); + + // Associate the positions Buffer with the StreamBank. + streamBank.setVertexStream( + g_o3d.Stream.POSITION, // semantic: This stream stores vertex positions + 0, // semantic index: First (and only) position stream + positionsField, // field: the field this stream uses. + 0); // start_index: How many elements to skip in the + // field. + + // Associate the triangle indices Buffer with the primitive. + cubePrimitive.indexBuffer = indexBuffer; + + return cubeShape; +} + +/** + * This method gets called every time O3D renders a frame. Here's where + * we update the cube's transform to make it spin. + * @param {o3d.RenderEvent} renderEvent The render event object that gives + * us the elapsed time since the last time a frame was rendered. + */ +function renderCallback(renderEvent) { + g_clock += renderEvent.elapsedTime * g_timeMult; + // Rotate the cube around the Y axis. + g_cubeTransform.identity(); + g_cubeTransform.rotateY(2.0 * g_clock); +} + + +/** + * Creates the client area. + */ +function init() { + o3djs.webgl.makeClients(initStep2); +} + +/** + * Initializes O3D, creates the cube and sets up the transform and + * render graphs. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + var o3dElement = clientElements[0]; + g_client = o3dElement.client; + g_o3d = o3dElement.o3d; + g_math = o3djs.math; + + // Create a pack to manage the objects created. + g_pack = g_client.createPack(); + + // Create the render graph for a view. + var viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_client.root, + g_client.renderGraphRoot); + + // Set up a perspective projection. + viewInfo.drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(30), // 30 degree fov. + g_client.width / g_client.height, + 1, // Near plane. + 5000); // Far plane. + + // Set up our view transformation to look towards the world origin where the + // cube is located. + viewInfo.drawContext.view = g_math.matrix4.lookAt([0, 1, 5], // eye + [0, 0, 0], // target + [0, 1, 0]); // up + + // Create an Effect object and initialize it using the shaders from the + // text area. + var redEffect = g_pack.createObject('Effect'); + var vertexShaderString = document.getElementById('vshader').value; + var pixelShaderString = document.getElementById('pshader').value; + redEffect.loadVertexShaderFromString(vertexShaderString); + redEffect.loadPixelShaderFromString(pixelShaderString); + + // Create a Material for the mesh. + var redMaterial = g_pack.createObject('Material'); + + // Set the material's drawList. + redMaterial.drawList = viewInfo.performanceDrawList; + + // Apply our effect to this material. The effect tells the 3D hardware + // which shaders to use. + redMaterial.effect = redEffect; + + // Create the Shape for the cube mesh and assign its material. + var cubeShape = createCube(redMaterial); + + // Create a new transform and parent the Shape under it. + g_cubeTransform = g_pack.createObject('Transform'); + g_cubeTransform.addShape(cubeShape); + + // Parent the cube's transform to the client root. + g_cubeTransform.parent = g_client.root; + + // Set our render callback for animation. + // This sets a function to be executed every time a frame is rendered. + g_client.setRenderCallback(renderCallback); + + g_finished = true; // for selenium testing. +} + +/** + * Removes any callbacks so they don't get called after the page has unloaded. + */ +function uninit() { + if (g_client) { + g_client.cleanup(); + } +} + +</script> +</head> +<body> +<h1>Hello Cube</h1> +This example shows how to display a spinning red cube in O3D. +<br/> + +<!-- Start of O3D plugin --> +<div id="o3d" width="600px" height="600px"></div> +<!-- End of O3D plugin --> + +<!-- Don't render the textarea --> +<div style="display:none"> +<!-- Start of effect --> +<textarea id="vshader"> + // World View Projection matrix that will transform the input vertices + // to screen space. + attribute vec4 position; + + uniform mat4 world; + uniform mat4 view; + uniform mat4 projection; + + /** + * The vertex shader simply transforms the input vertices to screen space. + */ + void main() { + // Multiply the vertex positions by the worldViewProjection matrix to + // transform them to screen space. + gl_Position = projection * view * world * position; + } +</textarea> +<textarea id="pshader"> + /** + * This pixel shader just returns the color red. + */ + void main() { + gl_FragColor = vec4(1, 0, 0, 1); // Red. + } +</textarea> +<!-- End of effect --> +</div> +</body> +</html> diff --git a/o3d/samples/o3d-webgl/base.js b/o3d/samples/o3d-webgl/base.js new file mode 100644 index 0000000..9863ee6 --- /dev/null +++ b/o3d/samples/o3d-webgl/base.js @@ -0,0 +1,211 @@ +/* + * 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 Base for all o3d classes implemented in javscript. + * Include just this file in a script tag and it will include all other + * source files needed by o3d. + * For more information about o3d see + * http://code.google.com/p/o3d. + */ + +/** + * A namespace for all the o3d classes. + * @namespace + */ +var o3d = o3d || {}; + +/** + * 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'. + */ +o3d.global = this; + +/** + * Path for included scripts. + * @type {string} + */ +o3d.basePath = ''; + +/** + * Tries to detect the base path of the base.js script that + * bootstraps the o3d libraries. + * @private + */ +o3d.findBasePath_ = function() { + var doc = o3d.global.document; + if (typeof doc == 'undefined') { + return; + } + if (o3d.global.BASE_PATH) { + o3d.basePath = o3d.global.BASE_PATH; + return; + } else { + // HACK to hide compiler warnings :( + o3d.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; + var s = 'o3d-webgl/base.js'; + var sl = s.length; + if (src.substr(l - sl) == s) { + o3d.basePath = src.substr(0, l - sl) + 'o3d-webgl/'; + return; + } + } +}; + +/** + * Writes a script tag for the given o3d source file name + * to the document. (Must be called at execution time.) + * @param {string} src The full path to the source file. + * @private + */ +o3d.writeScriptTag_ = function(src) { + var doc = o3d.global.document; + if (typeof doc != 'undefined') { + doc.write('<script type="text/javascript" src="' + + src + '"></' + 'script>'); + } +}; + +/** + * Includes the file indicated by the rule by adding a script tag. + * @param {string} rule Rule to include, in the form o3d.package.part. + */ +o3d.include = function(rule) { + var parts = rule.split('.'); + var path = parts[parts.length - 1] + '.js'; + o3d.writeScriptTag_(o3d.basePath + path); +}; + + +/** + * Makes one class inherit from another. Adds the member variables superClass + * and superClassName to the prototype of the sub class. + * @param {string} subClass Class that wants to inherit. + * @param {string} superClass Class to inherit from. + */ +o3d.inherit = function(subClassName, superClassName) { + var superClass = o3d.global.o3d[superClassName]; + var subClass = o3d.global.o3d[subClassName]; + + if (!superClass) + throw ('Invalid superclass: ' + superClassName); + if (!subClass) + throw ('Invalid subclass: ' + subClassName); + + subClass.prototype = new superClass; + subClass.prototype.superClassName = superClassName; + subClass.prototype.superClass = superClass; +}; + + +/** + * If an o3d function has not been implemented in javascript yet, it should + * call this function to throw an error because it's better than doing + * nothing. + */ +o3d.notImplemented = function() { + var callerName = arguments.caller.toString(); + callerName = callerName.substr('function '.length); + callerName = ownName.substr(0, ownName.indexOf('(')); + throw 'Not implemented: ' + callerName; +}; + + +// First find the path to the directory where all o3d-webgl sources live. +o3d.findBasePath_(); + + +// Unlike o3djs, we include all o3d-webgl files at once, this way, an o3d +// developer converting to use these classes only has to include this +// javascript file. +o3d.include('object_base'); +o3d.include('named_object_base'); +o3d.include('named_object'); +o3d.include('param_object'); +o3d.include('param'); +o3d.include('event'); +o3d.include('raw_data'); +o3d.include('file_request'); +o3d.include('client'); +o3d.include('render_node'); +o3d.include('clear_buffer'); +o3d.include('state_set'); +o3d.include('viewport'); +o3d.include('tree_traversal'); +o3d.include('draw_list'); +o3d.include('draw_pass'); +o3d.include('render_surface_set'); +o3d.include('render_surface'); +o3d.include('state'); +o3d.include('draw_context'); +o3d.include('texture'); +o3d.include('sampler'); +o3d.include('transform'); +o3d.include('pack'); +o3d.include('bounding_box'); +o3d.include('draw_element'); +o3d.include('element'); +o3d.include('field'); +o3d.include('buffer'); +o3d.include('stream'); +o3d.include('stream_bank'); +o3d.include('primitive'); +o3d.include('shape'); +o3d.include('effect'); +o3d.include('material'); + + diff --git a/o3d/samples/o3d-webgl/bitmap.js b/o3d/samples/o3d-webgl/bitmap.js new file mode 100644 index 0000000..6ce1df7 --- /dev/null +++ b/o3d/samples/o3d-webgl/bitmap.js @@ -0,0 +1,140 @@ +/* + * 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. + */ + + +/** + * Bitmap provides an interface for basic image operations on bitmap, + * including scale and crop. A Bitmap can be created from RawData via + * pack.createBitmapsFromRawData(), and also can be transferred to mip of a + * Texure2D or a specific face of TextureCUBE via methods in Texture. + * @constructor + */ +o3d.Bitmap = function() { + o3d.ParamObject.call(this); +}; +o3d.inherit('Bitmap', 'ParamObject'); + + +/** + * @type {number} + */ +o3d.Bitmap.Semantic = goog.typedef; + +/** + * After loading an array of Bitmaps with pack.createBitmapsFromRawData + * you can inspect their semantic to see what they were intended for. This is + * mostly to distinguish between 6 bitmaps that are faces of a cubemap and 6 + * bitmaps that are slices of a 3d texture. + * + * FACE_POSITIVE_X, 1 face of a cubemap + * FACE_NEGATIVE_X, 1 face of a cubemap + * FACE_POSITIVE_Y, 1 face of a cubemap + * FACE_NEGATIVE_Y, 1 face of a cubemap + * FACE_POSITIVE_Z, 1 face of a cubemap + * FACE_NEGATIVE_Z, 1 face of a cubemap + * IMAGE, normal 2d image + * SLICE, a slice of a 3d texture. + */ +o3d.Bitmap.FACE_POSITIVE_X = 0; +o3d.Bitmap.FACE_NEGATIVE_X = 1; +o3d.Bitmap.FACE_POSITIVE_Y = 2; +o3d.Bitmap.FACE_NEGATIVE_Y = 3; +o3d.Bitmap.FACE_POSITIVE_Z = 4; +o3d.Bitmap.FACE_NEGATIVE_Z = 5; +o3d.Bitmap.IMAGE = 6; +o3d.Bitmap.SLICE = 7; + + + +/** + * Flips a bitmap vertically in place. + * @type {boolean} + */ +o3d.Bitmap.prototype.flipVertically = false; + + + +/** + * Generates mip maps from the source level to lower levels. + * + * You can not currently generate mips for DXT textures although you can load + * them from dds files. + * + * @param {number} source_level The level to use as the source of the mips. + * @param {number} num_levels The number of levels to generate below the + * source level. + */ +o3d.Bitmap.prototype.generateMips = + function(source_level, num_levels) { + o3d.notImplemented(); +}; + + +/** + * The width of the bitmap (read only). + * @type {number} + */ +o3d.Bitmap.prototype.width = 0; + + + +/** + * The height of the bitmap (read only). + * @type {number} + */ +o3d.Bitmap.prototype.height = 0; + + + +/** + * The format of the bitmap (read only). + * @type {number} + */ +o3d.Bitmap.prototype.format = 0; + + + +/** + * Number mip-maps (read only) + * @type {number} + */ +o3d.Bitmap.prototype.numMipmaps = 1; + + + +/** + * The Semantic of the bitmap. + * @type {!o3d.Stream.Semantic} + */ +o3d.Bitmap.prototype.semantic = o3d.Stream.UNKNOWN_SEMANTIC; + + + diff --git a/o3d/samples/o3d-webgl/bounding_box.js b/o3d/samples/o3d-webgl/bounding_box.js new file mode 100644 index 0000000..506dd2c --- /dev/null +++ b/o3d/samples/o3d-webgl/bounding_box.js @@ -0,0 +1,124 @@ +/* + * 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. + */ + + +/** + * Creates BoundingBox from minExtent and maxExtent + * @param {!o3d.math.Point3} minExtent minimum extent of the box. + * @param {!o3d.math.Point3} maxExtent maximum extent of the box. + * @constructor + */ +o3d.BoundingBox = + function(minExtent, maxExtent) { + o3d.ParamObject.call(this); + this.minExtent = [minExtent[0], minExtent[1], minExtent[2]]; + this.minExtent = [maxExtent[0], maxExtent[1], maxExtent[2]]; +}; +o3d.inherit('BoundingBox', 'ParamObject'); + + +/** + * True if this boundingbox has been initialized. + * @type {boolean} + */ +o3d.BoundingBox.prototype.valid_ = false; + + +/** + * The min extent of the box. + * @type {!o3d.math.Point3} + */ +o3d.BoundingBox.prototype.minExtent = [0, 0, 0]; + + + +/** + * The max extent of the box. + * @type {!o3d.math.Point3} + */ +o3d.BoundingBox.prototype.maxExtent = [0, 0, 0]; + + + +/** + * Multiplies the bounding box by the given matrix returning a new bounding + * box. + * @param {!o3d.math.Matrix4} matrix The matrix to multiply by. + * @returns {!o3d.BoundingBox} The new bounding box. + */ +o3d.BoundingBox.prototype.mul = + function(matrix) { + o3d.notImplemented(); +}; + + +/** + * Adds a bounding box to this bounding box returning a bounding box that + * encompases both. + * @param {!o3d.BoundingBox} box BoundingBox to add to this BoundingBox. + * @returns {!o3d.BoundingBox} The new bounding box. + */ +o3d.BoundingBox.prototype.add = + function(box) { + o3d.notImplemented(); +}; + + +/** + * Checks if a ray defined in same coordinate system as this box intersects + * this bounding box. + * TODO(petersont): this can also take six coordinates as input. + * @param {!o3d.math.Point3} start position of start of ray in local space. + * @param {!o3d.math.Point3} end position of end of ray in local space. + * @returns {!o3d.RayIntersectionInfo} RayIntersectionInfo. If result.value + * is false then something was wrong like using this function with an + * uninitialized bounding box. If result.intersected is true then the ray + * intersected the box and result.position is the exact point of + * intersection. + */ +o3d.BoundingBox.prototype.intersectRay = + function(start, end) { + o3d.notImplemented(); +}; + + +/** + * Returns true if the bounding box is inside the frustum. + * @param {!o3d.math.Matrix4} matrix Matrix to transform the box from its + * local space to view frustum space. + * @returns {boolean} True if the box is in the frustum. + */ +o3d.BoundingBox.prototype.inFrustum = + function(matrix) { + o3d.notImplemented(); +}; + + diff --git a/o3d/samples/o3d-webgl/buffer.js b/o3d/samples/o3d-webgl/buffer.js new file mode 100644 index 0000000..eb4447b --- /dev/null +++ b/o3d/samples/o3d-webgl/buffer.js @@ -0,0 +1,280 @@ +/* + * 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. + */ + + +/** + * The Buffer object is a low level container for a flat list of + * floating point or integer values. These are currently used to define + * geometry. + * @constructor + */ +o3d.Buffer = function() { + this.fields_ = []; + this.array_ = null; +}; +o3d.inherit('Buffer', 'NamedObject'); + + +/** + * A private array to hold the fields. + * @type {!Array.<o3d.Field>} + */ +o3d.Buffer.prototype.fields_ = []; + + +/** + * Total number of components. + * @type {number} + */ +o3d.Buffer.prototype.totalComponents = 0; + +/** + * Index of the corresponding gl buffer object. + * @type {number} + */ +o3d.Buffer.prototype.gl_buffer_ = 0; + +/** + * Type of the array element. + * @type {!WebGLFloatArray} + */ +o3d.Buffer.prototype.ArrayType = WebGLFloatArray; + +/** + * Allocates memory for the data to be stored in the buffer based on + * the types of fields set on the buffer. + * + * @param {number} numElements Number of elements to allocate.. + * @returns {boolean} True if operation was successful. + */ +o3d.Buffer.prototype.allocateElements = + function(numElements) { + var total = 0; + for (var i = 0; i < this.fields_.length; ++i) { + this.fields_[i].offset_ = total; + total += this.fields_[i].numComponents; + } + this.totalComponents = total; + + this.resize(numElements * this.totalComponents); +}; + +/** + * Reallocate the array element to have the given number of elements. + * @param {number} numElements The new number of elements. + */ +o3d.Buffer.prototype.resize = function(numElements) { + this.gl_buffer_ = this.gl.createBuffer(); + this.array_ = new this.ArrayType(numElements); +}; + +/** + * Defines a field on this buffer. + * + * Note: Creating a field after having allocated the buffer is an expensive + * operation as the data currently in the buffer has to be shuffled around + * to make room for the new field. + * + * @param {string} field_type type of data in the field. Valid types + * are "FloatField", "UInt32Field", and "UByteNField". + * @param {number} num_components number of components in the field. + * @returns {!o3d.Field} The created field. + */ +o3d.Buffer.prototype.createField = + function(fieldType, numComponents) { + var f = new o3d.Field(); + f.buffer = this; + f.numComponents = numComponents; + f.size = numComponents * (fieldType=='UByteNField' ? 1 : 4); + this.fields_.push(f); + return f; +}; + + +/** + * Removes a field from this buffer. + * + * Note: Removing a field after having allocated the buffer is an expensive + * operation as the data currently in the buffer has to be shuffled around + * to remove the old field. + * + * @param {!o3d.Field} field field to remove. + */ +o3d.Buffer.prototype.removeField = + function(field) { + var i = 0; + for (var j = 0; j < this.fields_.length; ++j) { + if (this.fields_[i] == field) + j++; + this.fields_[j] = this.fields_[i]; + i++; + } + if (this.fields_.length > i) { + this.fields_.pop(); + } +}; + + +/** + * Prepares the buffer for read/write. + */ +o3d.Buffer.prototype.lock = function() { + // For now, this doesn't need to do anything. +}; + + +/** + * Delivers the buffer to the graphics hardware when read/write is finished. + */ +o3d.Buffer.prototype.unlock = function() { + this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.gl_buffer_); + this.gl.bufferData(this.gl.ARRAY_BUFFER, this.array_, this.gl.STATIC_DRAW); +}; + + +/** + * Sets the values in the buffer given array. + * TODO(petersont): This should take other kinds of arguments, like RawData. + * + * @param {!Array.<number>} values contains data to assign to the Buffer + * data itself. + * @returns {boolean} True if operation was successful. + */ +o3d.Buffer.prototype.set = + function(values) { + if (this.array_ == null) { + this.resize(values.length); + } + this.lock(); + for (var i = 0; i < values.length; ++i) { + this.array_[i] = values[i]; + } + this.unlock(); +}; + + +/** + * The total components in all fields in this buffer. + * @type {number} + */ +o3d.Buffer.prototype.total_components = 0; + + +/** + * VertexBufferBase is a the base class for both VertexBuffer and SourceBuffer + * @constructor + */ +o3d.VertexBufferBase = function() { + o3d.Buffer.call(this); +}; +o3d.inherit('VertexBufferBase', 'Buffer'); + + +/** + * Gets a copy of the values of the data stored in the buffer. + * Modifying this copy has no effect on the buffer. + */ +o3d.VertexBufferBase.prototype.get = function() { + o3d.notImplemented(); +}; + + +/** + * Gets a copy of a sub range of the values in the data stored in the buffer. + * Modifying this copy has no effect on the buffer. + * + * @param {number} start_index index of the element value to get. + * @param {number} numElements the number of elements to get. + * @returns {!Array.<number>} An array of values. + */ +o3d.VertexBufferBase.prototype.getAt = + function(start_index, numElements) { +}; + + +/** + * VertexBuffer is a Buffer object used for storing vertex data for geometry. + * (e.g. vertex positions, normals, colors, etc). + * A VertexBuffer can be rendered directly by the GPU. + * @constructor + */ +o3d.VertexBuffer = function() { + o3d.Buffer.call(this); +}; +o3d.inherit('VertexBuffer', 'Buffer'); + +/** + * The name of the class as a string. + * @type {string} + */ +o3d.VertexBuffer.prototype.className = "o3d.VertexBuffer"; + + +/** + * SourceBuffer is a Buffer object used for storing vertex data for + * geometry. (e.g. vertex positions, normals, colors, etc). + * + * A SourceBuffer is the source for operations like skinning and morph + * targets. It can not be directly rendered by the GPU. + * @constructor + */ +o3d.SourceBuffer = function() { + o3d.Buffer.call(this); +}; +o3d.inherit('SourceBuffer', 'Buffer'); + + +/** + * IndexBuffer is a buffer object used for storing geometry index data (e.g. + * triangle indices). + * @constructor + */ +o3d.IndexBuffer = function() { + o3d.Buffer.call(this); +}; +o3d.inherit('IndexBuffer', 'Buffer'); + + +/** + * Type of the array element. + * @type {!WebGLUnsignedShortArray} + */ +o3d.IndexBuffer.prototype.ArrayType = WebGLUnsignedShortArray; + + +/** + * Delivers the buffer to the graphics hardware when read/write is finished. + */ +o3d.IndexBuffer.prototype.unlock = function() { + this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.gl_buffer_); + this.gl.bufferData( + this.gl.ELEMENT_ARRAY_BUFFER, this.array_, this.gl.STATIC_DRAW); +}; diff --git a/o3d/samples/o3d-webgl/clear_buffer.js b/o3d/samples/o3d-webgl/clear_buffer.js new file mode 100644 index 0000000..fbc116a --- /dev/null +++ b/o3d/samples/o3d-webgl/clear_buffer.js @@ -0,0 +1,125 @@ +/* + * 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. + */ + + +/** + * A ClearBuffer is a render node that clears the color buffer, zbuffer and/or + * stencil buffer of the current render target. + * + * @constructor + */ +o3d.ClearBuffer = function() { + o3d.RenderNode.call(this); + this.clearColor = [0, 0, 0, 1]; +}; +o3d.inherit('ClearBuffer', 'RenderNode'); + + + +/** + * The color to clear the buffer in RGBA Float4 format. + * @type {!o3d.Float4} + */ +o3d.ClearBuffer.prototype.clearColor = [0, 0, 0, 1]; + + + +/** + * true clears the current render target's color buffer to the clear color. + * false does not clear the color buffer. + * @type {boolean} + */ +o3d.ClearBuffer.prototype.clearColorFlag = true; + + + +/** + * The value to clear the depth buffer (0.0 - 1.0) + * @type {number} + */ +o3d.ClearBuffer.prototype.clearDepth = 1; + + + +/** + * true clears the current render target's depth buffer to the clear depth + * value. false does not clear the depth buffer. + * @type {boolean} + */ +o3d.ClearBuffer.prototype.clearDepthFlag = true; + + + +/** + * The value to clear the stencil buffer to (0 - 255). + * @type {number} + */ +o3d.ClearBuffer.prototype.clearStencil = 0; + + + +/** + * true clears the current render target's stencil buffer to the clear stencil + * value. false does not clear the stencil buffer + * @type {boolean} + */ +o3d.ClearBuffer.prototype.clearStencilFlag = true; + + + +/** + * Function called in the render graph traversal before the children are + * rendered. + */ +o3d.ClearBuffer.prototype.before = function() { + var flags = 0; + + this.gl.clearColor( + this.clearColor[0], + this.clearColor[1], + this.clearColor[2], + this.clearColor[3]); + + this.gl.clearDepth(this.clearDepth); + this.gl.clearStencil(this.clearStencil); + + if (this.clearColorFlag) + flags = flags | this.gl.COLOR_BUFFER_BIT; + if (this.clearDepthFlag) + flags = flags | this.gl.DEPTH_BUFFER_BIT; + if (this.clearStencilFlag) + flags = flags | this.gl.STENCIL_BUFFER_BIT; + + this.gl.clear(flags); +}; + + + diff --git a/o3d/samples/o3d-webgl/client.js b/o3d/samples/o3d-webgl/client.js new file mode 100644 index 0000000..5bbb7b2 --- /dev/null +++ b/o3d/samples/o3d-webgl/client.js @@ -0,0 +1,841 @@ +/* + * 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. + */ + +/** + * A namespace to hold the list of all clients. + * @namespace + */ +o3d.Renderer = {}; + + +/** + * @type {number} + */ +o3d.Renderer.InitStatus = goog.typedef; + +/** + * The initialization status of the renderer. + * + * InitStatus, + * UNINITIALIZED, + * SUCCESS, The renderer is initialized. + * GPU_NOT_UP_TO_SPEC, The renderer determined the user's machine cannot + * run O3D. + * OUT_OF_RESOURCES, The user's machine does not have enough graphic + * resources available to start another instance of the O3D renderer. + * INITIALIZATION_ERROR, Some unknown error such as e.g. drivers not + * being installed correctly. + */ +o3d.Renderer.UNINITIALIZED = 0; +o3d.Renderer.SUCCESS = 1; +o3d.Renderer.GPU_NOT_UP_TO_SPEC = 2; +o3d.Renderer.OUT_OF_RESOURCES = 3; +o3d.Renderer.INITIALIZATION_ERROR = 4; + + +/** + * @type {number} + */ +o3d.Renderer.DisplayMode = goog.typedef; + +/** + * This is used in SetFullscreenClickRegion to request the current display + * mode, such that the change to full-screen mode won't change the screen + * resolution or refresh rate. + * + * DisplayModes, + * DISPLAY_MODE_DEFAULT + */ +o3d.Renderer.DISPLAY_MODE_DEFAULT = 0; + + +/** + * The interval timer for the render callback. + * @type {Object} + */ +o3d.Renderer.render_callback_interval_ = null; + + +/** + * Global private list of all clients to be rendered every frame. + * @type {!Array.<!o3d.Client>} + */ +o3d.Renderer.clients_ = []; + + +/** + * Renders all clients associated with this renderer. + */ +o3d.Renderer.renderClients = function() { + for (var i = 0; i < o3d.Renderer.clients_.length; ++i) { + var client = o3d.Renderer.clients_[i]; + var renderEvent = new o3d.RenderEvent; + var now = (new Date()).getTime() * 0.001; + if(client.then_ == 0.0) + renderEvent.elapsedTime = 0.0; + else + renderEvent.elapsedTime = now - client.then_; + if (client.render_callback) { + client.render_callback(renderEvent); + } + client.then_ = now; + client.renderTree(client.renderGraphRoot); + } +}; + + +/** + * Sets a timer to traverse the rendergraph every sixtieth of a second. + */ +o3d.Renderer.installRenderInterval = function() { + o3d.Renderer.render_callback_interval_ = setInterval( + "o3d.Renderer.renderClients()", 1000.0 / 60.0); +}; + + +/** + * The ClientInfo is used to get information about the client. + * @constructor + */ +o3d.ClientInfo = function() { }; + + +/** + * The number of objects the client is currently tracking. + * You can use this to check that you are correctly freeing resources. + * @type {number} + */ +o3d.ClientInfo.prototype.num_objects = 0; + + + +/** + * The amount of texture memory used. + * @type {number} + */ +o3d.ClientInfo.prototype.texture_memory_used = 0; + + + +/** + * The amount of texture memory used. + * @type {number} + */ +o3d.ClientInfo.prototype.buffer_memory_used = 0; + + + +/** + * Whether or not O3D is using the software renderer. + * + * For testing purposes you can force O3D to use the software renderer + * by setting the environment variable O3D_FORCE_SOFTWARE_RENDERER to + * anything. + * + * + * set O3D_FORCE_SOFTWARE_RENDERER=foo + * + * or + * + * export O3D_FORCE_SOFTWARE_RENDERER=foo + * + * + * You can set it at a system level if you want to set it for all + * browser instances or set it from a command line and start your + * browser from that same command line if you want to effect just + * that instance of the browser. + * + * Note that many browers require special command line options to + * run in a separate process, otherwise they default to finding + * the browser process already running and using that. For example + * firefox requires the option -no-remote. + * + * @type {boolean} + */ +o3d.ClientInfo.prototype.software_renderer = false; + + + +/** + * Whether or not the GPU supports non power of two textures. + * NOTE: O3D always allows non power of two textures. + * + * The only reason to look at this flag is for things like video that are + * updating the texture every frame. In that case, you might want to know + * that you could run faster if you used a power of 2 texture instead of + * a non power of 2 texture. + * + * @type {boolean} + */ +o3d.ClientInfo.prototype.non_power_of_two_textures = true; + + +/** + * The Client class is the main point of entry to O3D. It defines methods + * for creating and deleting packs. Each new object created by the Client is + * assigned a unique ID. + * + * The Client has a root transform for the transform graph and a root render + * node for the render graph. + * @constructor + */ +o3d.Client = function() { + this.root = new o3d.Transform; + this.renderGraphRoot = new o3d.RenderNode; + this.root = new o3d.Transform; + this.clientId = o3d.Client.nextId++; + + if (o3d.Renderer.clients_.length == 0) + o3d.Renderer.installRenderInterval(); + + o3d.Renderer.clients_.push(this); +}; +o3d.inherit('Client', 'NamedObject'); + +/** + * @type {function(!o3d.RenderEvent): void} + */ +o3d.Client.RenderCallback = goog.typedef; + +/** + * @type {function(!o3d.TickEvent): void} + */ +o3d.Client.TickCallback = goog.typedef; + +/** + * @type {function(!o3d.Event): void} + */ +o3d.Client.ErrorCallback = goog.typedef; + +/** + * The root of the render graph. + * @type {o3d.RenderNode} + */ +o3d.Client.prototype.renderGraphRoot = null; + + +/** + * Global counter to give the client a unique ID number. + * @type {number} + */ +o3d.Client.nextId = 0; + + +/** + * The time of the last render in seconds. + * @type {number} + */ +o3d.Client.prototype.then_ = 0; + + +/** + * The transform graph root. + * @type {o3d.Transform} + */ +o3d.Client.prototype.root = null; + +/** + * Function that gets called when the client encounters an error. + */ +o3d.Client.prototype.error_callback = function(error_message) {}; + + +/** + * Function that gets called right before the client renders. + */ +o3d.Client.prototype.render_callback = function(render_event) {}; + + +/** + * Function that gets called every tick. + */ +o3d.Client.prototype.tick_callback = function(tick_event) {}; + + +/** + * Call this function from window.onunload to ensure the browser does not + * continue to call callbacks (like the render callback) after the page is + * unloaded. It is possible that during unload the browser unloads all the + * javascript code, but then, after that, still asks the plugin to render. The + * browser then calls javascript functions that no longer exist which causes an + * error. To prevent that situation you need to clear all your callbacks on + * unload. cleanup handles that for you so you don't have to dispose each and + * every callback by hand. + */ +o3d.Client.prototype.cleanup = function () { + this.clearRenderCallback(); + this.clearTickCallback(); + this.clearErrorCallback(); +}; + + +/** + * Creates a pack object. + * A pack object. + * @returns {!o3d.Pack} A new pack object. + */ +o3d.Client.prototype.createPack = + function() { + var pack = new o3d.Pack; + pack.gl = this.gl; + return pack; +}; + + +/** + * Searches the Client for an object matching the given id. + * + * @param {number} id The id of the object to look for. + * @returns {o3d.ObjectBase} The object or null if a object + * with the given id is not found. + */ +o3d.Client.prototype.getObjectById = + function(id) { + o3d.notImplemented(); +}; + + +/** + * Searches the Client for objects of a particular name and type. + * @param {string} name name of object to look for. + * @param {string} class_name name of class to look for. + * @returns {!Array.<!o3d.ObjectBase>} Array of objects found. + */ +o3d.Client.prototype.getObjects = + function(name, class_name) { + o3d.notImplemented(); + return []; +}; + + +/** + * Searches the Client for objects of a particular type. + * @param {string} class_name name of class to look for. + * @returns {!Array.<!Object>} Array of objects found. + */ +o3d.Client.prototype.getObjectsByClassName = + function(class_name) { + o3d.notImplemented(); + return []; +}; + + +/** + * @type {number} + */ +o3d.Client.RenderMode = goog.typedef; + +/** + * RENDERMODE_CONTINUOUS, Draw as often as possible up to refresh rate. + * RENDERMODE_ON_DEMAND, Draw once then only when the OS requests it + * (like uncovering part of a window.) + */ +o3d.Client.RENDERMODE_CONTINUOUS = 0; +o3d.Client.RENDERMODE_ON_DEMAND = 1; + + +/** + * The current render mode. The default mode is RENDERMODE_CONTINUOUS.\n + * Valid values are: + * RENDERMODE_CONTINUOUS, Draw as often as possible up to refresh rate. + * RENDERMODE_ON_DEMAND, Draw when the OS requests it (like uncovering + * part of a window.) + * @type {o3d.Client.RenderMode} + */ +o3d.Client.prototype.renderMode = o3d.Client.RENDERMODE_CONTINUOUS; + + + +/** + * Forces a render of the current scene if the current render mode is + * RENDERMODE_ON_DEMAND. + */ +o3d.Client.prototype.render = function() { + this.renderTree(); +}; + + + +/** + * Renders a render graph. + * + * Normally the client calls this function automatically for you effectively + * doing a client.renderTree(client.renderGraphRoot) but there are cases + * where it is beneficial to be able to call this yourself and pass it + * different roots when you need to manipulate something between calls. + * + * This function can only be called from inside a render callback. If you call + * it the client will not do its default call as mentioned above. + * + * @param {!o3d.RenderNode} render_node root RenderNode to start rendering from. + */ +o3d.Client.prototype.renderTree = + function(render_node) { + render_node.render(); +}; + + +/** + * Returns an array of DisplayModes which are available for use in full-screen + * mode. + * An array of DisplayModes. + * @type {!Array.<!o3d.Client.DispalyMode>} + */ +o3d.Client.prototype.getDisplayModes = []; + + + +/** + * Makes a region of the plugin area that will invoke full-screen mode if + * clicked. The developer is responsible for communicating this to the user, + * as this region has no visible marker. The developer is also responsible for + * updating this region if the plugin gets resized, as we don't know whether or + * how to scale it. There can be only one full-screen click region at a time; + * calling this again will override any previous call. + * + * @param {number} x x position in pixels. + * @param {number} y y position in pixels. + * @param {number} width width in pixels. + * @param {number} height height in pixels. + * @param {number} mode_id Id of mode to use. + */ +o3d.Client.prototype.setFullscreenClickRegion = + function(x, y, width, height, mode_id) { + +}; + + +/** + * Deactivates the plugin click region that was previously created with + * SetFullscreenClickRegion(). + */ +o3d.Client.prototype.clearFullscreenClickRegion = function() { + o3d.notImplemented(); +}; + + + +/** + * Cancels full-screen display, reverting to displaying content only in the + * plugin region. If the plugin is already not in full-screen mode, this has + * no effect. This does not deactivate the plugin click region--if the user + * clicks there again, we'll go back to full-screen display. + */ +o3d.Client.prototype.cancelFullscreenDisplay = function() { + render_node.render(); +}; + + + +/** + * Gets info about the client. + * @type {!o3d.ClientInfo} + */ +o3d.Client.prototype.client_info = null; + + + +/** + * Whether content is displayed in full-screen mode or in a plugin window. The + * default is false [not full-screen]. + * @type {boolean} + */ +o3d.Client.prototype.fullscreen = false; + + +/** + * Returns the width of the current drawing area [plugin or full-screen] in + * pixels. + */ +o3d.Client.prototype.__defineGetter__('width', + function() { + return this.gl.canvas.width; + } +); + +o3d.Client.prototype.__defineSetter__('width', + function(x) { + this.gl.canvas.width = x; + } +); + + +/** + * Returns the height of the current drawing area [plugin or full-screen] in + * pixels. + */ +o3d.Client.prototype.__defineGetter__('height', + function() { + return this.gl.canvas.height; + } +); + +o3d.Client.prototype.__defineSetter__('height', + function(x) { + this.gl.canvas.height = x; + } +); + + +/** + * Sets the per frame render callback. + * + * Note: The callback will not be called recursively. When your callback is + * called if you somehow manage to cause the client to render more frames + * before you've returned from the callback you will not be called for those + * frames. + * + * g_client.setRenderCallback(onrender); + * + * function onrender(render_event) { + * var elapsedTime = render_event.elapsedTime; + * } + * + * @param {!o3d.RenderCallback} render_callback The callback to call + * each frame. + */ +o3d.Client.prototype.setRenderCallback = + function(render_callback) { + if (this.render_callback) { + this.clearRenderCallback(); + } + this.render_callback = render_callback; +}; + + +/** + * Clears the per frame render callback. + */ +o3d.Client.prototype.clearRenderCallback = function() { + clearInterval(this.render_callback_interval_); + this.render_callback = null; +}; + + +/** + * Sets a render callback to be called at the end of the + * rendering cycle of each frame. + * + * Note: The callback will not be called recursively. When your callback is + * called if you somehow manage to cause the client to render more frames + * before you've returned from the callback you will not be called for those + * frames. + * + * + * g_client.setPostRenderCallback(onpostrender); + * + * function onpostrender(render_event) { + * var elapsedTime = render_event.elapsedTime; + * } + * + * @param {!o3d.RenderCallback} post_render_callback The callback to call + * each frame. + */ +o3d.Client.prototype.setPostRenderCallback = + function(post_render_callback) { + this.postRenderCallback = post_render_callback; +}; + + +/** + * Clears the post render callback. + */ +o3d.Client.prototype.clearPostRenderCallback = function() { + this.postRenderCallback = null; +}; + + + +/** + * Sets the lost resources callback. + * + * The contents of certain resources, RenderSurfaces, can get discarded by the + * system under certain circumstances. If you application needs that contents + * to be in a certain state then you can set a callback giving your program the + * opportunity to restore that state if and when it is lost. + * + * @param {!o3d.LostResourcesCallback} lost_resources_callback The callback when + * resources are lost. + */ +o3d.Client.prototype.setLostResourcesCallback = + function(lost_resources_callback) { + this.lostResourcesCallback = lost_resources_callback; +}; + + +/** + * Clears the lost resources callback. + */ +o3d.Client.prototype.clearLostResourcesCallback = + function() { + this.lostResourcesCallback = null; +}; + + + +/** + * Sets a callback for a given event type. + * types. + * There can be only one callback for a given event type at a time; setting a + * new one deletes the old one. + * + * @param {string} type Type of event to set callback for. + * @param {!o3d.EventCallback} handler Function to call on event. + */ +o3d.Client.prototype.setEventCallback = + function(type, handler) { + this.eventCallbacks[type] = handler; +}; + + +/** + * Removes the previously-registered callback for an event of the given type. + * @param {string} type Type of event to clear callback for. + */ +o3d.Client.prototype.clearEventCallback = + function(type) { + this.eventCallbacks[type] = null; +}; + + +/** + * Sets the texture to use when a Texture or Sampler is missing while + * rendering. The default is a red texture with a yellow no symbol. + * <span style="color:yellow; background-color: red;">Ø. + * If you set it to null you'll get an error if you try to render something + * that is missing a needed Texture, Sampler or ParamSampler. + * + * For example if you don't care about missing textures, setting it to a black + * texture would be one option. Another example is if you want to write all + * your shaders to expect a texture then set this to a white texture. If you + * want to make sure you are not missing any textures set it null and see if + * you get any errors using Client.setErrorCallback or Client.lastError. + * + * var t = g_pack.createTexture2D('', 1, 1, g_o3d.Texture.XRGB8, 1); + * t.set(0, [0, 0, 0]); + * g_client.setErrorTexture(t); + * + * @param {o3d.Texture} texture texture to use for missing textures or null. + */ +o3d.Client.prototype.setErrorTexture = + function(texture) { + o3d.notImplemented(); +}; + + +/** + * Sets a callback for when the client ticks. The client processes some things + * like animation timers at up to 100hz. This callback will get called before + * each of those process ticks. + * + * NOTE: The client takes ownership of the TickCallback you + * pass in. It will be deleted if you call SetTickCallback a + * second time or if you call clearTickCallback. + * + * Note: The callback will not be called recursively. + * + * @param {o3d.TickCallback} tick_callback TickCallback to call when the + * Client ticks. + */ +o3d.Client.prototype.setTickCallback = + function(tick_callback) { + this.tickCallback = tick_callback; +}; + + +/** + * Clears the tick callback + * + * NOTE: The client takes ownership of the TickCallback you + * pass in. It will be deleted if you call SetTickCallback a second + * time or if you call clearTickCallback + */ +o3d.Client.prototype.clearTickCallback = function() { + this.tickCallback = null; +}; + + +/** + * Sets a callback for when the client gets an error. For example when a shader + * is compiled and there is an error or if you attempt to bind a param to a + * param of an incompatible type. + * + * NOTE: The client takes ownership of the ErrorCallback you + * pass in. It will be deleted if you call SetErrorCallback a + * second time or if you call ClearErrorCallback. + * + * NOTE: The callback will not be called recursively. If you are in a + * callback, and do something that causes another error before you have + * returned from the callback, your callback will not be called a second time. + * + * NOTE: If you put up an alert in response to an error it is best if you + * clear the error callback before you put up the alert. Otherwise you'll get + * an alert everytime the client tries to render which is every time you close + * the current alert which means you'll be in an infinite loop of alerts. + * + * @param {o3d.ErrorCallback} error_callback ErrorCallback to call when the + * Client gets an error. + */ +o3d.Client.prototype.setErrorCallback = + function(error_callback) { + this.error_callback = error_callback; +}; + + +/** + * Clears the Error callback + * + * NOTE: The client takes ownership of the ErrorCallback you + * pass in. It will be deleted if you call SetErrorCallback a second + * time or if you call ClearErrorCallback. + */ +o3d.Client.prototype.clearErrorCallback = function() { + this.error_callback = null; +}; + + + +/** + * Makes all parameters get re-evaluated. + */ +o3d.Client.prototype.invalidateAllParameters = function() { + o3d.notImplemented(); +}; + + +/** + * Gets a copy of the current backbuffer of O3D as a data: url. + * @param {string} mime_type The type of data url you want. + * Currently O3D only supports image/png. See HTML5 canvas tag + * for info about toDataURL. + * @returns {string} A Data URL for the backbuffer. + */ +o3d.Client.prototype.toDataURL = + function(opt_mime_type) { + o3d.notImplemented(); +}; + + +/** + * Returns the status of initializing the renderer so we can display the + * appropriate message. We require a certain minimum set of graphics + * capabilities. If the user's computer does not have his minimum + * set this will be GPU_NOT_UP_TO_SPEC. If the user is out of graphics + * resources this will be OUT_OF_RESOURCES. If some other error happened this + * will be INITIALIZATION_ERROR. Otherwise it will be SUCCESS. + */ +o3d.Client.prototype.renderer_init_status = 0; + + + +/** + * Gets / Sets the cursor's shape. + * + * @type {o3d.Cursor} + */ +o3d.Client.prototype.cursor = null; + + +/** + * The last error reported by the plugin. + * + * @type {string} + */ +o3d.Client.prototype.last_error_ = ''; + + + +/** + * All the objects managed by this client. + * + * Each access to this field gets the entire list so it is best to get it + * just once. For example: + * + * var objects = client.objects; + * for (var i = 0; i < objects.length; i++) { + * var object = objects[i]; + * } + * + * + * Note that modifications to this array [e.g. push()] will not affect + * the underlying Client, while modifications to the array's members + * will affect them. + * + * @type {!Array.<!o3d.ObjectBase>} + */ +o3d.Client.prototype.objects = []; + + + +/** + * Clears the error returned in lastError. + */ +o3d.Client.prototype.clearLastError = function () { + o3d.notImplemented(); +}; + + + +/** + * Resets the profiling information. + */ +o3d.Client.prototype.profileReset = function() { + o3d.notImplemented(); +}; + + + +/** + * Returns the profiling information as a string. + * The profiling info. + * @return {string} + */ +o3d.Client.prototype.profileToString = function() { + o3d.notImplemented(); +}; + + + +/** + * A unique id for this client. + * @type {number} + */ +o3d.Client.prototype.clientId = 0; + + + +/** + * The canvas associated with this client. + * @type {Element} + */ +o3d.Client.prototype.canvas = null; + + diff --git a/o3d/samples/o3d-webgl/draw_context.js b/o3d/samples/o3d-webgl/draw_context.js new file mode 100644 index 0000000..ee30d9b --- /dev/null +++ b/o3d/samples/o3d-webgl/draw_context.js @@ -0,0 +1,70 @@ +/* + * 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. + */ + + +/** + * The DrawContext defines the parameters used for a particular drawing pass. + * It contains two 4-by-4 matrix params, view and + * projection. These correspond to the viewing and projection transformation + * matrices. + * + * @param {!o3d.Matrix4} opt_view The view matrix for this DrawContext. + * @param {!o3d.Matrix4} opt_projection The projection matrix + * for this DrawContext. + * @constructor + */ +o3d.DrawContext = function(opt_view, opt_projection) { + this.view = opt_view || + [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]; + this.projection = opt_projection || + [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]; +}; +o3d.inherit('DrawContext', 'NamedObject'); + + +/** + * The view matrix represents the viewing transformation, used to take vertices + * from world space to view space. + * @type {o3d.Matrix4} + */ +o3d.DrawContext.prototype.view = []; + + + +/** + * The projection matrix represents the projection transformation, used to take + * vertices from view space to screen space. This matrix is usually an + * orthographic or perspective transformation. + * @type {o3d.Matrix4} + */ +o3d.DrawContext.prototype.projection = []; + + diff --git a/o3d/samples/o3d-webgl/draw_element.js b/o3d/samples/o3d-webgl/draw_element.js new file mode 100644 index 0000000..d4f802e --- /dev/null +++ b/o3d/samples/o3d-webgl/draw_element.js @@ -0,0 +1,69 @@ +/* + * 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. + */ + + +/** + * A DrawElement causes an Element to be Drawn with a particular material. + * You can override other Effect parameters by adding corresponding params to + * the DrawElement. + * + * @param {!o3d.Material} opt_material The material used to render this element. + * @constructor + */ +o3d.DrawElement = function(opt_material) { + o3d.ParamObject.call(this); + this.material = opt_material || null; +}; +o3d.inherit('DrawElement', 'ParamObject'); + + +/** + * The Material for this DrawElement. If it is null the material of owner will + * be used. + * @type {o3d.Material} + */ +o3d.DrawElement.prototype.material = null; + + + +/** + * The current owner of this Draw Element. Set to null to stop being owned. + * + * Note: DrawElements are referenced by the Pack they are created in and their + * owner. If the DrawElement is removed from its Pack then setting the owner + * to null will free the DrawElement. Or, visa versa, if you set the + * DrawElement's owner to null then removing it from its Pack will free the + * DrawElement. + * @type {o3d.Element} + */ +o3d.DrawElement.prototype.owner_ = null; + + diff --git a/o3d/samples/o3d-webgl/draw_list.js b/o3d/samples/o3d-webgl/draw_list.js new file mode 100644 index 0000000..537751b --- /dev/null +++ b/o3d/samples/o3d-webgl/draw_list.js @@ -0,0 +1,106 @@ +/* + * 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. + */ + + +/** + * A DrawList gets used during rendering to collect DrawElements to + * render. Each Material references a DrawList. Depending on the material, as + * DrawElements get collected they will be put on different DrawLists. + * @constructor + */ +o3d.DrawList = function() { + this.list_ = []; +}; +o3d.inherit('DrawList', 'NamedObject'); + +/** + * Private list to actually hold the DrawElements + * @type {!Array.<!Object>} + */ +this.list_ = []; + + +/** + * @type {number} + */ +o3d.DrawList.SortMethod = goog.typedef; + + +/** + * SortMethod, + * BY_PERFORMANCE + * BY_Z_ORDER + * BY_PRIORITY + * + * Method to sort DrawList by. + */ +o3d.DrawList.BY_PERFORMANCE = 0; +o3d.DrawList.BY_Z_ORDER = 1; +o3d.DrawList.BY_PRIORITY = 2; + + +/** + * Renders the draw list. + */ +o3d.DrawList.prototype.render = function() { + // TODO(petersont): Add sort. + + for (var i = 0; i < this.list_.length; ++i) { + var drawElementInfo = this.list_[i]; + var world = drawElementInfo.world; + var view = drawElementInfo.view; + var projection = drawElementInfo.projection; + var transform = drawElementInfo.transform; + var drawElement = drawElementInfo.drawElement; + var element = drawElementInfo.drawElement.owner; + var material = drawElementInfo.drawElement.material || + drawElementInfo.drawElement.owner.material; + var effect = material.effect; + + o3d.Param.SAS.setWorld(world); + o3d.Param.SAS.setView(view); + o3d.Param.SAS.setProjection(projection); + + var paramObjects = [ + transform, + drawElement, + element, + material, + effect, + o3d.Param.SAS + ]; + + material.effect.searchForParams(paramObjects); + element.render(); + } +}; + + diff --git a/o3d/samples/o3d-webgl/draw_pass.js b/o3d/samples/o3d-webgl/draw_pass.js new file mode 100644 index 0000000..f3deea8 --- /dev/null +++ b/o3d/samples/o3d-webgl/draw_pass.js @@ -0,0 +1,77 @@ +/* + * 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. + */ + + +/** + * A DrawPass renders a DrawList. + * + * @param {o3d.DrawList} drawList The DrawList used by this DrawPass. + * @param {o3d.DrawPass.SortMethod} sortMethod ParamInteger The method + * of sorting this DrawPass. + * @constructor + */ +o3d.DrawPass = function(opt_drawList, opt_sortMethod) { + this.drawList = opt_drawList; + this.sortMethod = opt_sortMethod || o3d.DrawList.BY_PERFORMANCE; +}; +o3d.inherit('DrawPass', 'RenderNode'); + + +/** + * The DrawList for this DrawPass. + * @type {o3d.DrawList} + */ +o3d.DrawPass.prototype.drawList = null; + + +/** + * @type {number} + */ +o3d.DrawPass.SortMethod = goog.typedef; + + +/** + * The sort method for this DrawPass to draw the DrawList by. + * Default = BY_PERFORMANCE. + * @type {o3d.DrawList.SortMethod} + */ +o3d.DrawPass.prototype.sortMethod = o3d.DrawList.BY_PERFORMANCE; + +/** + * Called in rendergraph traversal before children are rendered. + */ +o3d.DrawPass.prototype.before = function() { + if (this.drawList) { + this.drawList.render(); + } +}; + + diff --git a/o3d/samples/o3d-webgl/effect.js b/o3d/samples/o3d-webgl/effect.js new file mode 100644 index 0000000..53d8882 --- /dev/null +++ b/o3d/samples/o3d-webgl/effect.js @@ -0,0 +1,424 @@ +/* + * 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. + */ + + +/** + * EffectParameterInfo holds information about the Parameters an Effect needs. + * o3d.Effect.getParameterInfo + */ +o3d.EffectParameterInfo = function() { }; +o3d.inherit('EffectParameterInfo', 'NamedObject'); + + +/** + * The name of the parameter. + * @type {string} + */ +o3d.EffectParameterInfo.prototype.name = ''; + + + +/** + * The type of the parameter. + * @type {string} + */ +o3d.EffectParameterInfo.prototype.className = ''; + + + +/** + * The number of elements. Non-zero for array types, zero for non-array types. + * @type {number} + */ +o3d.EffectParameterInfo.prototype.numElements = 0; + + + +/** + * The semantic of the parameter. This is always in UPPERCASE. + * @type {o3d.Stream.Semantic} + */ +o3d.EffectParameterInfo.prototype.semantic = o3d.Stream.UNKNOWN_SEMANTIC; + + +/** + * If this is a standard parameter (SAS) this will be the name of the type + * of Param needed. Otherwise it will be the empty string. + * + * Standard Parameters are generally handled automatically by o3d but you + * can supply your own if you have a unique situation. + * + * @type {string} + */ +o3d.EffectParameterInfo.prototype.sas_class_name = ''; + + + +/** + * EffectStreamInfo holds information about the Streams an Effect needs. + * @param {o3d.Stream.Semantic} opt_semantic The semantic of the stream + * @param {number} opt_semantic_index + * @constructor + */ +o3d.EffectStreamInfo = function(opt_semantic, opt_semantic_index) { + if (!opt_semantic) { + opt_semantic = o3d.Stream.UNKNOWN_SEMANTIC; + } + if (!opt_semantic_index) { + opt_semantic_index = 0; + } + this.semantic = opt_semantic; + this.opt_semantic_index = opt_semantic_index; +}; +o3d.inherit('EffectStreamInfo', 'NamedObject'); + + +/** + * The semantic of the stream. + * @type {!o3d.Stream.Semantic} + */ +o3d.EffectStreamInfo.prototype.semantic = o3d.Stream.UNKNOWN_SEMANTIC; + + + +/** + * The semantic index of the stream. + * @type {number} + */ +o3d.EffectStreamInfo.prototype.semanticIndex = 0; + + +/** + * An Effect contains a vertex and pixel shader. + * @constructor + */ +o3d.Effect = function() { + o3d.ParamObject.call(this); + this.program_ = null; +}; +o3d.inherit('Effect', 'ParamObject'); + + +/** + * Indicates whether the vertex shader has been loaded, so we can + * postpone linking until both shaders are in. + * + * @type {boolean} + */ +o3d.Effect.prototype.vertexShaderLoaded_ = false; + + +/** + * Indicates whether the fragment shader has been loaded, so we can + * postpone linking until both shaders are in. + * + * @type {boolean} + */ +o3d.Effect.prototype.fragmentShaderLoaded_ = false; + + +/** + * Binds standard attribute locations for the shader. + */ +o3d.Effect.prototype.bindAttributesAndLinkIfReady = function() { + if (this.vertexShaderLoaded_ && this.fragmentShaderLoaded_) { + var attributes = ['position', 'normal', 'tangent', 'binormal', 'color', + 'texCoord0', 'texCoord1', 'texCoord2', 'texCoord3', + 'texCoord4', 'texCoord5', 'texCoord6', 'texCoord7']; + for (var i = 0; i < attributes.length; ++i) { + this.gl.bindAttribLocation(this.program_, i, attributes[i]); + } + this.gl.linkProgram(this.program_); + this.getAllUniforms(); + } +}; + + +/** + * Helper function for loadVertexShaderFromString and + * loadPixelShaderFromString that takes the type as an argument. + * @param {string} shaderString The shader code. + * @param {number} type The type of the shader: either + * VERTEX_SHADER or FRAGMENT_SHADER. + */ +o3d.Effect.prototype.loadShaderFromString = function(shaderString, type) { + if (!this.program_) { + this.program_ = this.gl.createProgram(); + } + var shader = this.gl.createShader(type); + this.gl.shaderSource(shader, shaderString); + this.gl.compileShader(shader); + this.gl.attachShader(this.program_, shader); +}; + + +/** + * Loads a glsl vertex shader for this effect from a string. + * @param {string} shaderString The string. + */ +o3d.Effect.prototype.loadVertexShaderFromString = + function(shaderString) { + this.loadShaderFromString(shaderString, this.gl.VERTEX_SHADER); + this.vertexShaderLoaded_ = true; + o3d.Effect.prototype.bindAttributesAndLinkIfReady(); +}; + + +/** + * Loads a glsl vertex shader for this effect from a string. + * @param {string} shaderString The string. + */ +o3d.Effect.prototype.loadPixelShaderFromString = + function(shaderString) { + this.loadShaderFromString(shaderString, this.gl.FRAGMENT_SHADER); + this.fragmentShaderLoaded_ = true; + this.bindAttributesAndLinkIfReady(); +}; + + +/** + * Iterates through the active uniforms of the program and gets the + * location of each one and stores them by name in the uniforms + * object. + */ +o3d.Effect.prototype.getAllUniforms = + function() { + this.uniforms = {}; + var numUniforms = this.gl.getProgramParameter( + this.program_, this.gl.ACTIVE_UNIFORMS); + for (var i = 0; i < numUniforms; ++i) { + var info = this.gl.getActiveUniform(this.program_, i); + this.uniforms[info.name] = {info:info, + location:this.gl.getUniformLocation(this.program_, info.name)}; + } +}; + + +/** + * For each of the effect's uniform parameters, creates corresponding + * parameters on the given ParamObject. Skips SAS Parameters. + * + * If a Param with the same name but the wrong type already exists on the + * given ParamObject createUniformParameters will attempt to replace it with + * one of the correct type. + * + * Note: The most common thing to pass to this function is a Material but + * depending on your application it may be more appropriate to pass in a + * Transform, Effect, Element or DrawElement. + * + * @param {!o3d.ParamObject} param_object The param object on which the + * new paramters will be created. + */ +o3d.Effect.prototype.createUniformParameters = + function(param_object) { + var sasNames = {'world': true, + 'view': true, + 'projection': true, + 'worldView': true, + 'worldProjection': true, + 'worldViewProjection': true, + 'worldI': true, + 'viewI': true, + 'projectionI': true, + 'worldViewI': true, + 'worldProjectionI': true, + 'worldViewProjectionI': true, + 'worldT': true, + 'viewT': true, + 'projectionT': true, + 'worldViewT': true, + 'worldProjectionT': true, + 'worldViewProjectionT': true, + 'worldIT': true, + 'viewIT': true, + 'projectionIT': true, + 'worldViewIT': true, + 'worldProjectionIT': true, + 'worldViewProjectionIT': true}; + + for (name in this.uniforms) { + var info = this.uniforms[name].info; + + if (sasNames[name]) + continue; + + var paramType = ''; + switch (info.type) { + case this.gl.FLOAT: + paramType = 'ParamFloat'; + break; + case this.gl.FLOAT_VEC2: + paramType = 'ParamFloat2'; + break; + case this.gl.FLOAT_VEC3: + paramType = 'ParamFloat3'; + break; + case this.gl.FLOAT_VEC4: + paramType = 'ParamFloat4'; + break; + case this.gl.INT: + paramType = 'ParamInteger'; + break; + case this.gl.BOOL: + paramType = 'ParamBoolean'; + break; + case this.gl.FLOAT_MAT4: + paramType = 'ParamMatrix4'; + break; + case this.gl.SAMPLER_2D: + paramType = 'ParamSampler'; + break; + case this.gl.SAMPLER_CUBE: + paramType = 'ParamSampler'; + break; + } + + param_object.createParam(info.name, paramType); + } +}; + + +/** + * For each of the effect's uniform parameters, if it is a SAS parameter + * creates corresponding StandardParamMatrix4 parameters on the given + * ParamObject. Note that SAS parameters are handled automatically by the + * rendering system. so except in some rare cases there is no reason to call + * this function. Also be aware that the StandardParamMatrix4 Paramters like + * WorldViewProjectionParamMatrix4, etc.. are only valid during rendering. + * At all other times they will not return valid values. + * + * If a Param with the same name but the wrong type already exists on the + * given ParamObject CreateSASParameters will attempt to replace it with + * one of the correct type. + * + * @param {!o3d.ParamObject} param_object The param object on which the new + * paramters will be created. + */ +o3d.Effect.prototype.createSASParameters = + function(param_object) { + o3d.notImplemented(); +}; + + +/** + * Gets info about the parameters this effect needs. + * @returns {!Array.<!o3d.EffectParameterInfo>} an array of + * EffectParameterInfo objects. + */ +o3d.Effect.prototype.getParameterInfo = function() { + o3d.notImplemented(); + return []; +}; + + +/** + * Gets info about the streams this effect needs. + * @returns {!Array.<!o3d.EffectStreamInfo>} an array of + * EffectStreamInfo objects. + */ +o3d.Effect.prototype.getStreamInfo = function() { + var r = []; + // TODO(petersont): This is a stub, will remove later and replace with + // something that actually gets its streams from the shader. + var standard_semantic_index_pairs = [ + {semantic: o3d.Stream.POSITION, index: 0}, + {semantic: o3d.Stream.NORMAL, index: 0}, + {semantic: o3d.Stream.COLOR, index: 0}, + {semantic: o3d.Stream.TEXCOORD, index: 0} + ]; + + for (var i = 0; i < standard_semantic_index_pairs.length; ++i) { + var p = standard_semantic_index_pairs[i]; + r.push(new o3d.EffectStreamInfo(p.semantic, p.index)); + } + return r; +}; + + +/** + * Searches the objects in the given list for parameters to apply to the + * uniforms defined on this effects program, and applies them, favoring + * the objects nearer the begining of the list. + * + * @param {!Array.<!o3d.ParamObject>} object_list The param objects to search. + */ +o3d.Effect.prototype.searchForParams = function(object_list) { + var filled_map = {}; + for (name in this.uniforms) { + filled_map[name] = false; + } + this.gl.useProgram(this.program_); + for (var i = 0; i < object_list.length; ++i) { + var obj = object_list[i]; + for (name in this.uniforms) { + var uniformInfo = this.uniforms[name]; + if (filled_map[name]) { + continue; + } + var param = obj.getParam(name); + if (param) { + param.applyToLocation(this.gl, uniformInfo.location); + filled_map[name] = true; + } + } + } +}; + + +/** + * @type {number} + */ +o3d.Effect.MatrixLoadOrder = goog.typedef; + +/** + * MatrixLoadOrder, + * ROW_MAJOR, Matrix parameters are loaded in row-major order (DX-style). + * COLUMN_MAJOR, Matrix parameters are loaded in column-major order + * (OpenGL-style). + */ +o3d.Effect.ROW_MAJOR = 0; +o3d.Effect.COLUMN_MAJOR = 1; + + +/** + * The order in which matrix data is loaded to the GPU. + * @type {o3d.Effect.MatrixLoadOrder} + */ +o3d.Effect.prototype.matrix_load_order_ = o3d.Effect.ROW_MAJOR; + + +/** + * The source for the shaders on this Effect. + * @type {string} + */ +o3d.Effect.prototype.source_ = ''; + + diff --git a/o3d/samples/o3d-webgl/element.js b/o3d/samples/o3d-webgl/element.js new file mode 100644 index 0000000..8a953a8 --- /dev/null +++ b/o3d/samples/o3d-webgl/element.js @@ -0,0 +1,214 @@ +/* + * 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. + */ + + +/** + * An Element manages DrawElements for classes inherited from Element. + * + * @param {!o3d.Material} opt_material The Material used by this Element. + * @param {!o3d.BoundingBox} opt_boundingBox The BoundingBox used by this + * Element for culling. + * @param {!o3d.Point3} opt_zSortPoint The point to sort by when rendering + * this Element in a z ordered DrawPass. + * @param {boolean} opt_cull Whether or not to attempt to cull this + * Element based on whether or not its bounding box is in the view + * frustum. + * @constructor + */ +o3d.Element = + function(opt_material, opt_boundingBox, opt_zSortPoint, opt_cull) { + o3d.ParamObject.call(this); + this.material = opt_material; + this.boundingBox = opt_boundingBox || + new o3d.BoundingBox([-1, -1, -1], [1, 1, 1]); + this.zSortPoint = opt_zSortPoint || [0, 0, 0]; + this.cull = opt_cull || false; + this.drawElements = []; +}; +o3d.inherit('Element', 'ParamObject'); + + +/** + * The Material for this element. + * @type {o3d.Material} + */ +o3d.Element.prototype.material = null; + + + +/** + * The BoundingBox for this element. If culling is on this bounding box will be + * tested against the view frustum of any draw context used to render this + * Element. + * @type {o3d.BoundingBox} + */ +o3d.Element.prototype.boundingBox = null; + + + +/** + * The z sort point for this element. If this Element is drawn by a DrawPass + * that is set to sort by z order this value will be multiplied by the + * worldViewProjection matrix to compute a z value to sort by. + * @type {o3d.Point3} + */ +o3d.Element.prototype.zSortPoint = [0, 0, 0]; + + + +/** + * The priority for this element. Used to sort if this Element is drawn by a + * DrawPass that is set to sort by priority. + * @type {number} + */ +o3d.Element.prototype.priority = 0; + + + +/** + * The cull settings for this element. If true this Element will be culled + * by the bounding box above compared to the view frustum it is being rendered + * with. + * + * @type {boolean} + */ +o3d.Element.prototype.cull = false; + + + +/** + * The current owner of this Draw Element. Pass in null to stop being owned. + * + * Note: Elements are referenced by the Pack they are created in and their + * owner. If the Element is removed from its Pack, then setting the owner + * to null will free the Element. Or, visa versa, if you set the + * Element's owner to null then removing it from its Pack will free the + * Element. + * + * @type {o3d.Element} + */ +o3d.Element.prototype.owner_ = null; + +o3d.Element.prototype.__defineSetter__('owner', + function(o) { + this.owner_ = o; + o.addElement(this); + } +); + +o3d.Element.prototype.__defineGetter__('owner', + function(o) { + return this.owner_; + } +); + + + +/** + * Gets all the DrawElements under this Element. + * + * Each access to this field gets the entire list so it is best to get it + * just once. For example: + * + * var drawElements = element.drawElements; + * for (var i = 0; i < drawElements.length; i++) { + * var drawElement = drawElements[i]; + * } + * + * + * Note that modifications to this array [e.g. push()] will not affect + * the underlying Element, while modifications to the members of the array. + * will affect them. + * + * @type {!Array.<!o3d.DrawElement>} + */ +o3d.Element.prototype.drawElements = []; + + + +/** + * Creates a DrawElement for this Element. Note that unlike + * Shape.createDrawElements and Transform.createDrawElements this one will + * create more than one element for the same material. + * + * @param {!o3d.Pack} pack pack used to manage created DrawElement. + * @param {!o3d.Material} material material to use for DrawElement. If you + * pass null it will use the material on this Element. This allows you + * to easily setup the default (just draw as is) by passing null or + * setup a shadow pass by passing in a shadow material. + * @returns {!o3d.DrawElement} The created draw element. + */ +o3d.Element.prototype.createDrawElement = + function(pack, material) { + drawElement = new o3d.DrawElement(); + drawElement.owner = this; + drawElement.material = material || this.material; + this.drawElements.push(drawElement); + return drawElement; +}; + + +/** + * Computes the intersection of a ray in the same coordinate system as + * the specified POSITION stream. + * @param {number} position_stream_index Index of POSITION stream. + * @param {o3d.Cull} cull which side of the triangles to ignore. + * @param {!o3d.math.Point3} start position of start of ray in local space. + * @param {!o3d.math.Point3} end position of end of ray. in local space. + * @returns {!o3d.RayIntersectionInfo} RayIntersectionInfo class. If valid() + * is false then something was wrong, Check GetLastError(). If + * intersected() is true then the ray intersected a something. position() + * is the exact point of intersection. + */ +o3d.Element.prototype.intersectRay = + function(position_stream_index, cull, start, end) { + o3d.notImplemented(); +}; + + +/** + * Computes the bounding box in same coordinate system as the specified + * POSITION stream. + * @param {number} position_stream_index Index of POSITION stream. + * @returns {!o3d.BoundingBox} The boundingbox for this element in local space. + */ +o3d.Element.prototype.getBoundingBox = + function(position_stream_index) { + return this.boundingBox; +}; + + +/** + * Virtual function that renders the element. + */ +o3d.Element.prototype.render = function() { }; + + diff --git a/o3d/samples/o3d-webgl/event.js b/o3d/samples/o3d-webgl/event.js new file mode 100644 index 0000000..91bfcbd --- /dev/null +++ b/o3d/samples/o3d-webgl/event.js @@ -0,0 +1,260 @@ +/* + * 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. + */ + + +/** + * An Event object contains information describing a JavaScript event; it's used + * as an argument to event handlers triggered by the plugin. + * @constructor + */ +o3d.Event = function() { }; +o3d.inherit('Event', 'ObjectBase'); + + +/** + * @type {number} + */ +o3d.Event.Type = goog.typedef; + +/** + * String identifiers for JavaScript events. + * type + * invalid + * click + * dblclick + * mousedown + * mousemove + * mouseup + * wheel + * keydown + * keypress + * keyup + * resize + */ +o3d.Event.TYPE_INVALID = 0; +o3d.Event.TYPE_CLICK = 1; +o3d.Event.TYPE_DBLCLICK = 2; +o3d.Event.TYPE_MOUSEDOWN = 3; +o3d.Event.TYPE_MOUSEMOVE = 4; +o3d.Event.TYPE_MOUSEUP = 5; +o3d.Event.TYPE_WHEEL = 6; +o3d.Event.TYPE_KEYDOWN = 7; +o3d.Event.TYPE_KEYPRESS = 8; +o3d.Event.TYPE_KEYUP = 9; +o3d.Event.TYPE_RESIZE = 10; + +/** + * The type of event this object represents. + * @type {o3d.Event.Type} + */ +o3d.Event.prototype.type = o3d.Event.TYPE_INVALID; + + +/** + * @type {number} + */ +o3d.Event.Button = goog.typedef; + +/** + * Constants used to identify mouse buttons. + */ +o3d.Event.BUTTON_LEFT = 0; +o3d.Event.BUTTON_MIDDLE = 1; +o3d.Event.BUTTON_RIGHT = 2; +o3d.Event.BUTTON_4 = 3; +o3d.Event.BUTTON_5 = 4; + + + +/** + * Which mouse button caused the event, in the case of mousedown, mouseup, + * click, and dblclick events. This uses the values in enum Button. + */ +o3d.Event.prototype.button = o3d.Event.BUTTON_LEFT; + + + +/** + * Whether the ctrl key was pressed at the time of the event. + * @type {boolean} + */ +o3d.Event.prototype.ctrl_key = false; + + + +/** + * Whether the alt [option, on OSX] key was pressed at the time of the event. + * @type {boolean} + */ +o3d.Event.prototype.alt_key = false; + + + +/** + * Whether the shift key was pressed at the time of the event. + * @type {boolean} + */ +o3d.Event.prototype.shift_key = false; + + + +/** + * Whether the meta [command, on OSX] key was pressed at the time of the event. + * @type {boolean} + */ +o3d.Event.prototype.meta_key = false; + + + +/** + * The key code of the key pressed or released. + * @type {number} + */ +o3d.Event.prototype.key_code = 0; + + + +/** + * The character created by a keypress event. + * @type {number} + */ +o3d.Event.prototype.char_code = 0; + + + +/** + * The x-coordinate in pixels from the left side of the plugin or fullscreen + * display region. + * @type {number} + */ +o3d.Event.prototype.x = 0; + + + +/** + * The y-coordinate in pixels from the top of the plugin or fullscreen + * display region. + * @type {number} + */ +o3d.Event.prototype.y = 0; + + + +/** + * The x-coordinate in pixels from the left side of the screen. + * @type {number} + */ +o3d.Event.prototype.screenX = 0; + + + +/** + * The y-coordinate in pixels from the top of the screen. + * @type {number} + */ +o3d.Event.prototype.screenY = 0; + + + +/** + * The horizontal scroll offset for wheel events, in arbitrary units. + * Positive values mean right; negative mean left. + * @type {number} + */ +o3d.Event.prototype.deltaX = 0; + + + +/** + * The vertical scroll offset for wheel events, in arbitrary units. + * Positive values mean up or away from the user; negative mean down or toward + * the user. + * @type {number} + */ +o3d.Event.prototype.deltaY = 0; + + + +/** + * The width in pixels of the plugin or fullscreen display region as a result + * of this event. + * @type {number} + */ +o3d.Event.prototype.width = 0; + + + +/** + * The height in pixels of the plugin or fullscreen display region as a result + * of this event. + * @type {number} + */ +o3d.Event.prototype.height = 0; + + + +/** + * Whether we're currently displaying in fullscreen mode. + * @type {boolean} + */ +o3d.Event.prototype.fullscreen = false; + + + +/** + * An Event that gets sent to the render callback. + * @constructor + */ +o3d.RenderEvent = function() {}; +o3d.inherit('RenderEvent', 'Event'); + + +/** + * Time in seconds since the last time the client rendered. + * @type {number} + */ +o3d.RenderEvent.prototype.elapsedTime = 0; + + +/** + * An Event that gets sent to the render callback. + * @constructor + */ +o3d.TickEvent = function() {}; +o3d.inherit('RenderEvent', 'Event'); + + +/** + * Time in seconds since the last time the client rendered. + * @type {number} + */ +o3d.TickEvent.prototype.elapsedTime = 0; + diff --git a/o3d/samples/o3d-webgl/field.js b/o3d/samples/o3d-webgl/field.js new file mode 100644 index 0000000..5f82237 --- /dev/null +++ b/o3d/samples/o3d-webgl/field.js @@ -0,0 +1,134 @@ +/* + * 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. + */ + + +/** + * A Field is a base class that manages a set of components in a + * Buffer of a specific type. Fields are managed by Buffers and can not be + * directly created. When a Buffer is destroyed or if a Field is removed from a + * Buffer the Field's buffer property will be set to null. + * @constructor + */ +o3d.Field = function() { }; +o3d.inherit('Field', 'NamedObject'); + +/** + * The number of components in this field. + * @type {number} + */ +o3d.Field.prototype.numComponents = 0; + + +/** + * The Buffer the field belongs to. + * @type {o3d.Buffer} + */ +o3d.Field.prototype.buffer = null; + + +/** + * The offset of this field in the Buffer. + * @type {number} + */ +o3d.Field.prototype.offset_ = 0; + + +/** + * The size of one element of this field. + * @type {number} + */ +o3d.Field.prototype.size = 0; + + +/** + * Sets the values of the data stored in the field. + * + * The buffer for the field must have already been created either through + * buffer.set or through buffer.allocateElements. + * + * The number of values passed in must be a multiple of the number of + * components needed for the field. + * + * @param {number} start_index index of first value to set. + * @param {number} values Values to be stored in the buffer starting at index. + */ +o3d.Field.prototype.setAt = + function(start_index, values) { + this.buffer.lock(); + var l = values.length / this.numComponents; + for (var i = 0; i < l; i++) { + for (var c = 0; c < this.numComponents; ++c) { + this.buffer.array_[ + (start_index + i) * this.buffer.totalComponents + this.offset_ + c] = + values[this.numComponents * i + c]; + } + } + this.buffer.unlock(); + return true; +}; + + +/** + * Gets the values stored in the field. + * + * @param {number} start_index index of the first value to get. + * @param {number} num_elements number of elements to read from field. + * @returns {number} The values of the field. + */ +o3d.Field.prototype.getAt = + function(start_index, num_elements) { + o3d.notImplemented(); +}; + + + +/** + * A field that contains floating point numbers. + * @constructor + */ +o3d.FloatField = function() { }; +o3d.inherit('FloatField', 'Field'); + +/** + * A field that contains unsigned integers. + * @constructor + */ +o3d.UInt32Field = function() { }; +o3d.inherit('UInt32Field', 'Field'); + +/** + * A field that contains unsigned bytes. + * @constructor + */ +o3d.UByteNField = function() { }; +o3d.inherit('UByteNField', 'Field'); + + diff --git a/o3d/samples/o3d-webgl/file_request.js b/o3d/samples/o3d-webgl/file_request.js new file mode 100644 index 0000000..122364a --- /dev/null +++ b/o3d/samples/o3d-webgl/file_request.js @@ -0,0 +1,170 @@ +/* + * 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. + */ + + +/** + * A FileRequest is used to carry out an asynchronous request for a file + * to be loaded. Its use parallels that of XMLHttpRequest; you create one, call + * open, set the onreadystatechange callback, and call send. + * Note that unlike XMLHttpRequests, FileRequests cannot be reused. + * + * For RawData loads, on success the RawData will be stored in the data field + * on the FileRequest itself. It is only valid until the FileRequest is freed by + * calling pack.removeObject(request). + * + * var request = pack.createFileRequest("RAWDATA"); + * request.open("GET", url, true); + * request.onreadystatechange = function() { + * if (request.done) { + * if (request.success) { + * var rawData = request.data; + * + * ... + * } else { + * dump('Load of rawdata returned failure.'); + * } + * + * pack.removeObject(request); + * } + * }; + * request.send(); + */ +o3d.FileRequest = function() { + this.request_ = new XMLHttpRequest(); + var fileRequest = this; + this.request_.onreadystatechange = function() { + fileRequest.readyState = this.readyState; + fileRequest.done = fileRequest.done || this.done; + if (this.readyState == 4) { + if (this.responseText) { + fileRequest.success = true; + } + fileRequest.done = true; + } + fileRequest.data = this.responseText; + if (fileRequest.onreadystatechange) + fileRequest.onreadystatechange.apply(fileRequest, arguments); + } +}; +o3d.inherit('FileRequest', 'NamedObject'); + + +/** + * A callback to call whenever the ready state of the request changes. + * @type {Object} + */ +o3d.FileRequest.prototype.onreadystatechange = null; + + + +/** + * The URI this request is for. + * @type {string} + */ +o3d.FileRequest.prototype.uri = ''; + + + +/** + * On completion of successful RawData file loads, this holds the loaded + * RawData. + * @type {o3d.RawData} + */ +o3d.FileRequest.prototype.data = null; + + + +/** + * This holds the same values as in XMLHttpRequest: + * 0 = uninitialized + * 1 = opened + * 2 = sent + * 3 = receiving + * 4 = loaded (the file has been downloaded, but may or may not have been + * parsed yet) + * @type {number} + */ +o3d.FileRequest.prototype.readyState = 0; + + + +/** + * This indicates whether any further processing will be done on this + * FileRequest. + * @type {boolean} + */ +o3d.FileRequest.prototype.done = false; + + + +/** + * This field is only valid if done is true. It indicates whether or not the + * request succeeded. If it failed error holds an error message. + * @type {boolean} + */ +o3d.FileRequest.prototype.success = false; + + + +/** + * An error message. + * If done is true and success is false this will be an error message + * describing what went wrong. + * @type {string} + */ +o3d.FileRequest.prototype.error = ''; + + + +/** + * Set up several of the request fields. + * @param {string} method "GET" is the only supported method at this time + * @param {string} uri the location of the file to fetch + * @param {boolean} async true is the only legal value at this time + */ +o3d.FileRequest.prototype.open = + function(method, uri, async) { + this.uri = uri; + this.request_.open(method, uri, async); +}; + + +/** + * Send the request. + * Unlike XMLHttpRequest the onreadystatechange callback will be called no + * matter what, with success or failure. + */ +o3d.FileRequest.prototype.send = function() { + this.request_.send(); +}; + + + diff --git a/o3d/samples/o3d-webgl/material.js b/o3d/samples/o3d-webgl/material.js new file mode 100644 index 0000000..a7d6d3f --- /dev/null +++ b/o3d/samples/o3d-webgl/material.js @@ -0,0 +1,77 @@ +/* + * 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. + */ + + +/** + * A Material holds the various uniform parameters an Effect needs to render. + * For example a Lambert effect might need "diffuse", "ambient", "emissive". + * The parameters needed on a Material will vary depending its Effect. + * Note that a material MUST have its drawList set in order for objects using it + * to render. + * + * @param {!o3d.State} opt_state The State used by this material. + * @param {!o3d.Effect} opt_effect The Effect used by this material. + * @param {!o3d.DrawList} opt_draw_list The the DrawList used by this material. + * @constructor + */ +o3d.Material = function(opt_state, opt_effect, opt_draw_list) { + o3d.ParamObject.call(this); + this.state = opt_state; + this.effect = opt_effect; + this.drawList = opt_draw_list; +}; +o3d.inherit('Material', 'ParamObject'); + + +/** + * The Effect for this material. + * @type {o3d.Effect} + */ +o3d.Material.prototype.effect = null; + + + +/** + * The State for this material. + * @type {o3d.State} + */ +o3d.Material.prototype.state = null; + + + +/** + * The DrawList this material will render on. + * @type {o3d.DrawList} + */ +o3d.Material.prototype.drawList = null; + + + diff --git a/o3d/samples/o3d-webgl/named_object.js b/o3d/samples/o3d-webgl/named_object.js new file mode 100644 index 0000000..ce6c871 --- /dev/null +++ b/o3d/samples/o3d-webgl/named_object.js @@ -0,0 +1,72 @@ +/* + * 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. + */ + + +/** + * Takes the name of a class as an argument, and returns true if this object is + * either an instance of that class or derives from that class. + * + * var t = pack.createObject('o3d.Transform'); + * t.isAClassName('o3d.Transform'); + * t.isAClassName('o3d.ParamObject'); + * t.isAClassName('o3d.Shape'); + * + * @param {o3d.String} class_name Name of class to check for. + * @returns {o3d.bool} true if this object is a or is derived from the given + * class name. + */ +o3d.ObjectBase.prototype.isAClassName = + function(class_name) { + o3d.notImplemented(); +}; + + +/** + * Base class for all objects that can have their name set. + * @constructor + */ +o3d.NamedObject = function() { }; +o3d.inherit('NamedObject', 'NamedObjectBase'); + + +/** + * The object's name. + * + * Setting this has no meaning to O3D, but is useful for debugging and for + * the functions Client.getObjects, Pack.getObject, + * RenderNode.getRenderNodesByNameInTree and + * RenderNode.getTransformsByNameInTree + * which search for objects by name. + * @type {string} + */ +o3d.NamedObject.prototype.name = ''; + + diff --git a/o3d/samples/o3d-webgl/named_object_base.js b/o3d/samples/o3d-webgl/named_object_base.js new file mode 100644 index 0000000..5176426 --- /dev/null +++ b/o3d/samples/o3d-webgl/named_object_base.js @@ -0,0 +1,47 @@ +/* + * 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. + */ + + +/** + * Base class for all objects that are identifiable by a name. + * @constructor + */ +o3d.NamedObjectBase = function() { }; +o3d.inherit('NamedObjectBase', 'ObjectBase'); + + +/** + * The object's name. + * @type {string} + */ +o3d.NamedObjectBase.prototype.name = ""; + + diff --git a/o3d/samples/o3d-webgl/object_base.js b/o3d/samples/o3d-webgl/object_base.js new file mode 100644 index 0000000..42931eb --- /dev/null +++ b/o3d/samples/o3d-webgl/object_base.js @@ -0,0 +1,69 @@ +/* + * 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. + */ + + +/** + * A ObjectBase is a base class that manages a set of components in a + * Buffer of a specific type. ObjectBases are managed by Buffers and can + * not be directly created. When a Buffer is destroyed or if a ObjectBase + * is removed from a Buffer the ObjectBase's buffer property will be set + * to null. + */ +o3d.ObjectBase = function() { }; + + +/** + * Used by isAClassName. + * @type {string} + */ +o3d.ObjectBase.prototype.className = 'o3d.ObjectBase'; + +/** + * @type {o3d.ObjectBase} + */ +o3d.ObjectBase.prototype.superClass = null; + +/** + * Traverses the current object's class and all its superclasses and + * determines if any of them are of the given name. + * returns {bool} + */ +o3d.ObjectBase.isAClassName = function(o, className) { + while (o != undefined) { + if (o.className == 'className') { + return true; + } + o = o.superClass.prototype; + } + return false; +}; + + diff --git a/o3d/samples/o3d-webgl/pack.js b/o3d/samples/o3d-webgl/pack.js new file mode 100644 index 0000000..fc10e49 --- /dev/null +++ b/o3d/samples/o3d-webgl/pack.js @@ -0,0 +1,348 @@ +/* + * 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. + */ + + +/** + * A Pack object functions as a container for O3D objects. The Pack + * is used to control the lifetime scope of a collection of objects in bulk. The + * Pack object achieves this by simply storing a set of references to its + * contained objects, which ensures that the ref-counts for those objects never + * reach zero while the pack is alive. + * @constructor + */ +o3d.Pack = function() { + this.objects_ = []; +}; +o3d.inherit('Pack', 'NamedObject'); + + +/** + * Removes all internal references to the Pack from the client. + * The pack, and all objects contained in it are permitted to be destroyed + * after the pack's destruction. Objects will only be destroyed after all + * references to them have been removed. + * + * NOTE: Calling pack.destroy does NOT free your resources. It justs releases + * the pack's reference to those resources. An example should hopefully make + * it clearer. + * + * pack.destroy() is effectively almost the same as this. + * + * var objectsInPack = pack.getObjectsByClassName('o3d.ObjectBase'); + * for (var ii = 0; ii < objectsInPack.length; ++ii) { + * pack.removeObject(objectsInPack[ii]); + * } + * + * The only difference is that after all the objects are removed the pack + * itself will be released from the client. See documentation on + * pack.removeObject for why this is important. + * + * It's important to note that many objects are only referenced by the pack. + * Textures, Effects, Materials, for example. That means the moment you call + * pack.destroy() those objects will be freed. If the client then tries to + * render and some objects are missing you'll immediately get an error. + */ +o3d.Pack.prototype.destroy = function() { + this.objects_ = []; +}; + + + +/** + * Removes a pack's reference to an object. Any object created from + * pack.create___ function can be removed. This releases the pack's reference + * to that object so if nothing else is referencing that object it will be + * deleted. + * + * NOTE: Calling pack.removeObject does NOT automatically free your resource. + * It just releases the pack's reference to that resource. An example should + * hopefully make it clearer. + * + * Suppose you make a transform like this: + * + * + * var myTransform = pack.createObject('Transform'); + * myTransform.parent = g_client.root; + * pack.removeObject(myTransform); + * + * + * In the code above, myTransform is referenced twice. Once by the pack, and + * again by g_client.root So in this case, calling pack.removeObject() + * only releases the pack's reference leaving the reference by g_client.root. + * + * + * myTransform.parent = null; + * + * + * Now the last reference has been removed and myTransform will be freed. + * + * @param {o3d.ObjectBase} object Object to remove. + * @returns {boolean} True if the object was successfully removed. + * False if the object is not part of this pack. + */ +o3d.Pack.prototype.removeObject = + function(object) { + var i = 0; + for (var j = 0; j < this.objects_.length; ++j) { + if (this.objects_[i] == object) { + j++; + } + this.objects_[j] = this.objects_[i]; + i++; + } + if (this.objects_.length > i) { + this.objects_.pop(); + } +}; + + +/** + * Creates an Object by Class name. + * + * Note: You may omit the 'o3d.'. + * + * @param {string} type_name name of Class to create. Valid type names are: + * Bitmap + * Canvas + * CanvasLinearGradient + * CanvasPaint + * ClearBuffer + * Counter + * Curve + * DrawContext + * DrawElement + * DrawList + * DrawPass + * Effect + * FunctionEval + * IndexBuffer + * Material + * ParamArray + * ParamObject + * Primitive + * RenderFrameCounter + * RenderNode + * RenderSurfaceSet + * Sampler + * SecondCounter + * Shape + * Skin + * SkinEval + * SourceBuffer + * State + * StateSet + * StreamBank + * Texture2D + * TextureCUBE + * TickCounter + * Transform + * TreeTraversal + * VertexBuffer + * Viewport + * Matrix4AxisRotation + * Matrix4Composition + * Matrix4Scale + * Matrix4Translation + * ParamOp2FloatsToFloat2 + * ParamOp3FloatsToFloat3 + * ParamOp4FloatsToFloat4 + * ParamOp16FloatsToMatrix4 + * TRSToMatrix4 + * @returns {o3d.ObjectBase} The created object. + */ +o3d.Pack.prototype.createObject = + function(type_name) { + var foo = o3d.global.o3d[type_name]; + if (typeof foo != 'function') { + throw 'cannot find type in o3d namespace: ' + type_name + } + var object = new foo(); + object.gl = this.gl; + return object; +}; + + +/** + * Creates a new Texture2D object of the specified size and format and + * reserves the necessary resources for it. + * + * Note: If enable_render_surfaces is true, then the dimensions must be a + * power of two. + * + * @param {number} width The width of the texture area in texels (max = 2048) + * @param {number} height The height of the texture area in texels (max = 2048) + * @param {o3d.Texture.Format} format The memory format of each texel + * @param {number} levels The number of mipmap levels. Use zero to create the + * compelete mipmap chain. + * @param {boolean} enable_render_surfaces If true, the texture object will + * expose RenderSurface objects through GetRenderSurface(...). + * @returns {!o3d.Texture2D} The Texture2D object. + */ +o3d.Pack.prototype.createTexture2D = + function(width, height, format, levels, enable_render_surfaces) { + o3d.notImplemented(); +}; + + +/** + * Creates a new TextureCUBE object of the specified size and format and + * reserves the necessary resources for it. + * Note: If enable_render_surfaces is true, then the dimensions must be a + * power of two. + * + * @param {number} edge_length The edge of the texture area in texels + * (max = 2048) + * @param {o3d.Texture.Format} format The memory format of each texel. + * @param {number} levels The number of mipmap levels. Use zero to create + * the compelete mipmap chain. + * @param {boolean} enable_render_surfaces If true, the texture object + * will expose RenderSurface objects through GetRenderSurface(...). + * @returns {!o3d.TextureCUBE} The TextureCUBE object. + */ +o3d.Pack.prototype.createTextureCUBE = + function(edge_length, format, levels, enable_render_surfaces) { + o3d.notImplemented(); +}; + + +/** + * Creates a new RenderDepthStencilSurface object of a format suitable for use + * as a depth-stencil render target. + * Note: The dimensions of the RenderDepthStencilSurface must be a power of + * two. + * + * @param {number} width The width of the RenderSurface in pixels + * @param {number} height The height of the RenderSurface in pixels + * @returns {!o3d.RenderDepthStencilSurface} The RenderSurface object. + */ +o3d.Pack.prototype.createDepthStencilSurface = + function(width, height) { + o3d.notImplemented(); +}; + + +/** + * Search the pack for all objects of a certain class with a certain name. + * + * Note that modifications to this array [e.g. push()] will not affect + * the underlying Pack, while modifications to the array's members + * will affect them. + * + * @param {string} name Name to look for + * @param {string} class_type_name the Class of the object. It is okay + * to pass base types for example "o3d.RenderNode" will return + * ClearBuffers, DrawPasses, etc... + * @returns {!Array.<!o3d.ObjectBase>} Array of Objects. + */ +o3d.Pack.prototype.getObjects = + function(name, class_type_name) { + o3d.notImplemented(); +}; + + +/** + * Search the pack for all objects of a certain class + * + * Note that modifications to this array [e.g. push()] will not affect + * the underlying Pack, while modifications to the array's members + * will affect them. + * + * @param {string} class_type_name the Class of the object. It is + * okay to pass base types for example "o3d.RenderNode" will return + * ClearBuffers, DrawPasses, etc... + * @returns {!Array.<!o3d.ObjectBase>} Array of Objects. + */ +o3d.Pack.prototype.getObjectsByClassName = + function(class_type_name) { + o3d.notImplemented(); +}; + + +/** + * All the objects managed by this pack. + * + * Each access to this field gets the entire list so it is best to get it + * just once. For example: + * + * var objects = pack.objects; + * for (var i = 0; i < objects.length; i++) { + * var object = objects[i]; + * } + * + * + * Note that modifications to this array [e.g. push()] will not affect + * the underlying Pack, while modifications to the array's members + * will affect them. + */ +o3d.Pack.prototype.objects_ = []; + + +/** + * Creates a FileRequest to be used to asynchronously load a Texture or + * RawData. Note: Loading a "TEXTURE" is deprecated. The recommended way to + * load a texture is to load a RawData, use that to create Bitmap, Massage + * the Bitmap to your liking the use that to create a Texture. + * @param {string} type Must be "TEXTURE" or "RAWDATA" + * @returns {!o3d.FileRequest} a FileRequest + */ +o3d.Pack.prototype.createFileRequest = + function(type) { + return this.createObject('FileRequest'); +}; + + +/** + * Create Bitmaps from RawData. + * + * If you load a cube map you'll get an array of 6 Bitmaps. + * If you load a volume map you'll get an array of n Bitmaps. + * If there is an error you'll get an empty array. + * + * @param {!o3d.RawData} raw_data contains the bitmap data in a supported + * format. + * @returns {!o3d.Bitmap} An Array of Bitmaps object. + */ +o3d.Pack.prototype.createBitmapsFromRawData = + function(raw_data) { + o3d.notImplemented(); +}; + + +/** + * Create RawData given a data URL. + * @param {string} data_url The data URL from which to create the RawData. + * @returns {!o3d.RawData} The RawData. + */ +o3d.Pack.prototype.createRawDataFromDataURL = + function(data_url) { + o3d.notImplemented(); +}; + diff --git a/o3d/samples/o3d-webgl/param.js b/o3d/samples/o3d-webgl/param.js new file mode 100644 index 0000000..0bb28fe --- /dev/null +++ b/o3d/samples/o3d-webgl/param.js @@ -0,0 +1,829 @@ +/* + * Copyright 2010, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +/** + * Params store data defined name/value pairs on ParamObjects. + * Each Param has a name, a type and a value that can be set and queried. + * One of their uses is to hold "uniform constants" used to parameterize + * shaders. Params can be connected in a source/destination fashion such + * that a target Param gets its value from the source param. + * @constructor + */ +o3d.Param = function(param_type_name) { + o3d.Param.prototype.output_connections = []; + this.outputConnections = []; +} +o3d.inherit('Param', 'NamedObject'); + + +/** + * If true, this param will make sure its input param is up to date when + * using it as a source. Default = true. + * + * This is for helping with Param cycles. + * + * If paramA gets its value from paramB and paramB gets its value from + * paramA: + * If you go paramA.value, paramB will evaluate then copy to paramA. + * If you go paramB.value, paramA will evaluate then copy to paramB. + * If you set paramB.updateInput = false, then: + * If you go paramA.value, paramB will evaluate then copy to paramA. + * If you go paramB.value, paramB just copy paramA. paramA will NOT evaluate + * when paramB asks for its value. + */ +o3d.Param.prototype.update_input = true; + +/** + * @type {o3d.Param} + */ +o3d.Param.prototype.inputConnection = null; + +/** + * @type {Array.<!o3d.Param>} + */ +o3d.Param.prototype.outputConnections = []; + + +/** + * @type {o3d.ParamObject} + */ +o3d.Param.prototype.owner_ = null; + +/** + * Directly binds two Param elements such that this parameter gets its value + * from the source parameter. The source must be compatible with this + * parameter. + * + * @param {o3d.Param} source_param The parameter that the value originates + * from. Passing in null will unbind any parameter currently bound. + * @returns {boolean} True if the bind succeeded. + */ +o3d.Param.prototype.bind = + function(source_param) { + source_param.outputConnections.push(this); + this.inputConnection = source_param; +}; + + +/** + * Breaks any input connection coming into the Param. + */ +o3d.Param.prototype.unbindInput = + function() { + o3d.notImplemented(); +}; + + +/** + * Breaks a specific param-bind output connection on this param. + * + * @param {o3d.Param} destination_param param to unbind. + */ +o3d.Param.prototype.unbindOutput = + function(destination_param) { + o3d.notImplemented(); +}; + + +/** + * Breaks all param-bind output connections on this param. + */ +o3d.Param.prototype.unbindOutputs = function() { + o3d.notImplemented(); +}; + + + +/** + * If true the param is read only. Its value can not be set nor can it be used + * as the destination in a ParamBind. + */ +o3d.Param.prototype.read_only_ = false; + + + +/** + * The input connection for this param. + */ +o3d.Param.prototype.input_connection = null; + + + +/** + * The output connections for this param. + */ +o3d.Param.prototype.output_connections = []; + + +/** + * @constructor + */ +o3d.ParamBoolean = function() { + o3d.Param.call(this); + this.value = false; +}; +o3d.inherit('ParamBoolean', 'Param'); + + +/** + * @constructor + */ +o3d.ParamBoundingBox = function() { + o3d.Param.call(this); + this.value = null; +}; +o3d.inherit('ParamBoundingBox', 'Param'); + + +/** + * @constructor + */ +o3d.ParamDrawContext = function() { + o3d.Param.call(this); + this.value = null; +}; +o3d.inherit('ParamDrawContext', 'Param'); + + +/** + * @constructor + */ +o3d.ParamDrawList = function() { + o3d.Param.call(this); + this.value = null; +}; +o3d.inherit('ParamDrawList', 'Param'); + + +/** + * @constructor + */ +o3d.ParamEffect = function() { + o3d.Param.call(this); + this.value = null; +}; +o3d.inherit('ParamEffect', 'Param'); + + +/** + * @constructor + */ +o3d.ParamFloat = function() { + o3d.Param.call(this); + this.value = 0.0; +}; +o3d.inherit('ParamFloat', 'Param'); + + +/** + * @constructor + */ +o3d.ParamFloat2 = function() { + o3d.Param.call(this); + this.value = [0.0, 0.0]; +}; +o3d.inherit('ParamFloat2', 'Param'); + + +/** + * @constructor + */ +o3d.ParamFloat3 = function() { + o3d.Param.call(this); + this.value = [0.0, 0.0, 0.0]; +}; +o3d.inherit('ParamFloat3', 'Param'); + + +/** + * @constructor + */ +o3d.ParamFloat4 = function() { + o3d.Param.call(this); + this.value = [0.0, 0.0, 0.0, 0.0]; +}; +o3d.inherit('ParamFloat4', 'Param'); + + +/** + * @constructor + */ +o3d.ParamFunction = function() { + o3d.Param.call(this); + this.value = null; +}; +o3d.inherit('ParamFunction', 'Param'); + + +/** + * @constructor + */ +o3d.ParamInteger = function() { + o3d.Param.call(this); + this.value = 0; +}; +o3d.inherit('ParamInteger', 'Param'); + + +/** + * @constructor + */ +o3d.ParamMaterial = function() { + o3d.Param.call(this); + this.value = null; +}; +o3d.inherit('ParamMaterial', 'Param'); + + +/** + * @constructor + */ +o3d.ParamMatrix4 = function() { + o3d.Param.call(this); + this.value = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]; +}; +o3d.inherit('ParamMatrix4', 'Param'); + + +/** + * @constructor + */ +o3d.ParamParamArray = function() { + o3d.Param.call(this); + this.value = []; +}; +o3d.inherit('ParamParamArray', 'Param'); + + +/** + * @constructor + */ +o3d.ParamRenderSurface = function() { + o3d.Param.call(this); + this.value = null; +}; +o3d.inherit('ParamRenderSurface', 'Param'); + + +/** + * @constructor + */ +o3d.ParamRenderDepthStencilSurface = function() { + o3d.Param.call(this); + this.value = null; +}; +o3d.inherit('ParamRenderDepthStencilSurface', 'Param'); + + +/** + * @constructor + */ +o3d.ParamSampler = function() { + o3d.Param.call(this); + this.value = null; +}; +o3d.inherit('ParamSampler', 'Param'); + + +/** + * @constructor + */ +o3d.ParamSkin = function() { + o3d.Param.call(this); + this.value = null; +}; +o3d.inherit('ParamSkin', 'Param'); + + +/** + * @constructor + */ +o3d.ParamSteamBank = function() { + o3d.Param.call(this); + this.value = null; +}; +o3d.inherit('ParamSteamBank', 'Param'); + + +/** + * @constructor + */ +o3d.ParamState = function() { + o3d.Param.call(this); + this.value = null; +}; +o3d.inherit('ParamState', 'Param'); + + +/** + * @constructor + */ +o3d.ParamString = function() { + o3d.Param.call(this); + this.value = null; +}; +o3d.inherit('ParamString', 'Param'); + + +/** + * @constructor + */ +o3d.ParamTexture = function() { + o3d.Param.call(this); + this.value = null; +}; +o3d.inherit('ParamTexture', 'Param'); + + +/** + * @constructor + */ +o3d.ParamTransform = function() { + o3d.Param.call(this); + this.value = null; +}; +o3d.inherit('ParamTransform', 'Param'); + + +/** + * Base class for the types of matrix4 params that compute their own + * value when asked (ProjectionParamMatrix4 etc). + * @constructor + */ +o3d.CompositionParamMatrix4 = function() { + o3d.ParamMatrix4.call(this); + this.matrix_names_ = []; +}; +o3d.inherit('CompositionParamMatrix4', 'ParamMatrix4'); + +/** + * The array of names of matrix params for the matrices that are to be + * composed to get the value. + * @type {Array.<o3d.ParamMatrix4>} + */ +o3d.CompositionParamMatrix4.prototype.matrix_names_ = []; + +/** + * Whether the inverse is taken right before returning the value. + * @type {Array.<o3d.ParamMatrix4>} + */ +o3d.CompositionParamMatrix4.prototype.inverse_ = false; + + +/** + * Whether the inverse is taken right before returning the value. + * @type {Array.<o3d.ParamMatrix4>} + */ +o3d.CompositionParamMatrix4.prototype.transpose_ = false; + +o3d.CompositionParamMatrix4.prototype.__defineGetter__('value', + // TODO(petersont): Cache the result if it hasn't changed. + function() { + var product = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]; + for (var i = 0; i < this.matrix_names_.length; ++i) { + o3d.Transform.compose(product, o3d.Param.SAS[this.matrix_names_[i]]); + } + if (this.inverse_) { + o3d.Transform.inverse(product); + } + if (this.transpose_) { + o3d.Transform.transpose(product); + } + return product; + } +); + +o3d.CompositionParamMatrix4.prototype.__defineSetter__('value', + function(value) { } +); + + +/** + * @constructor + */ +o3d.ProjectionParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['projection']; +}; +o3d.inherit('ProjectionParamMatrix4', 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.ProjectionInverseParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['projection']; + this.inverse_ = true; +}; +o3d.inherit('ProjectionInverseParamMatrix4', 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.ProjectionTransposeParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['projection']; + this.transpose_ = true; +}; +o3d.inherit('ProjectionTransposeParamMatrix4', 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.ProjectionInverseTransposeParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['projection']; + this.inverse_ = true; + this.transpose_ = true; +}; +o3d.inherit('ProjectionInverseTransposeParamMatrix4', + 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.ViewParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['view']; +}; +o3d.inherit('ViewParamMatrix4', 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.ViewInverseParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['view']; + this.inverse_ = true; +}; +o3d.inherit('ViewInverseParamMatrix4', 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.ViewTransposeParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['view']; + this.transpose_ = true; +}; +o3d.inherit('ViewTransposeParamMatrix4', 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.ViewInverseTransposeParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['view']; + this.inverse_ = true; + this.transpose_ = true; +}; +o3d.inherit('ViewInverseTransposeParamMatrix4', 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.ViewProjectionParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['projection', 'view']; +}; +o3d.inherit('ViewProjectionParamMatrix4', 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.ViewProjectionInverseParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['projection', 'view']; + this.inverse_ = true; +}; +o3d.inherit('ViewProjectionInverseParamMatrix4', 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.ViewProjectionTransposeParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['projection', 'view']; + this.transpose_ = true; +}; +o3d.inherit('ViewProjectionTransposeParamMatrix4', 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.ViewProjectionInverseTransposeParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['projection', 'view']; + this.inverse_ = true; + this.transpose_ = true; +}; +o3d.inherit('ViewProjectionInverseTransposeParamMatrix4', + 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.WorldParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['world']; +}; +o3d.inherit('WorldParamMatrix4', 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.WorldInverseParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['world']; + this.inverse_ = true; +}; +o3d.inherit('WorldInverseParamMatrix4', 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.WorldTransposeParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['world']; + this.transpose_ = true; +}; +o3d.inherit('WorldTransposeParamMatrix4', 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.WorldInverseTransposeParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['world']; + this.inverse_ = true; + this.transpose_ = true; +}; +o3d.inherit('WorldInverseTransposeParamMatrix4', 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.WorldViewParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['view', 'world']; +}; +o3d.inherit('WorldViewParamMatrix4', 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.WorldViewInverseParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['view', 'world']; + this.inverse_ = true; +}; +o3d.inherit('WorldViewInverseParamMatrix4', + 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.WorldViewTransposeParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['view', 'world']; + this.transpose_ = true; +}; +o3d.inherit('WorldViewTransposeParamMatrix4', + 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.WorldViewInverseTransposeParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['view', 'world']; + this.inverse_ = true; + this.transpose_ = true; +}; +o3d.inherit('WorldViewInverseTransposeParamMatrix4', + 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.WorldViewProjectionParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['projection', 'view', 'world']; +}; +o3d.inherit('WorldViewProjectionParamMatrix4', + 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.WorldViewProjectionInverseParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['projection', 'view', 'world']; + this.inverse_ = true; +}; +o3d.inherit('WorldViewProjectionInverseParamMatrix4', + 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.WorldViewProjectionTransposeParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['projection', 'view', 'world']; + this.transpose_ = true; +}; +o3d.inherit('WorldViewProjectionTransposeParamMatrix4', + 'CompositionParamMatrix4'); + + +/** + * @constructor + */ +o3d.WorldViewProjectionInverseTransposeParamMatrix4 = function() { + o3d.CompositionParamMatrix4.call(this); + this.matrix_names_ = ['projection', 'view', 'world']; + this.inverse_ = true; + this.transpose_ = true; +}; +o3d.inherit('WorldViewProjectionInverseTransposeParamMatrix4', + 'CompositionParamMatrix4'); + +/** + * Called to specify the value of a uniform variable. + */ +o3d.ParamFloat.prototype.applyToLocation = function(gl, location) { + gl.uniform4fv(location, this.value); +}; + +/** + * Called to specify the value of a uniform variable. + */ +o3d.ParamFloat2.prototype.applyToLocation = function(gl, location) { + gl.uniform2fv(location, this.value); +}; + +/** + * Called to specify the value of a uniform variable. + */ +o3d.ParamFloat3.prototype.applyToLocation = function(gl, location) { + gl.uniform3fv(location, this.value); +}; + +/** + * Called to specify the value of a uniform variable. + */ +o3d.ParamFloat4.prototype.applyToLocation = function(gl, location) { + gl.uniform4fv(location, this.value); +}; + +/** + * Called to specify the value of a uniform variable. + */ +o3d.ParamMatrix4.prototype.applyToLocation = function(gl, location) { + gl.uniformMatrix4fv(location, + false, + o3d.Transform.flattenMatrix4(this.value)); +}; + + + +/** + * Object to compute all combinations of world/view/projection + * inverse/transpose matrices and provide them as parameters. + * + * @type {o3d.ParamObject} + */ +o3d.Param.SAS = new o3d.ParamObject; + +o3d.Param.SAS.createParam('world', + 'WorldParamMatrix4'); +o3d.Param.SAS.createParam('view', + 'ViewParamMatrix4'); +o3d.Param.SAS.createParam('projection', + 'ProjectionParamMatrix4'); +o3d.Param.SAS.createParam('worldView', + 'WorldViewParamMatrix4'); +o3d.Param.SAS.createParam('viewProjection', + 'ViewProjectionParamMatrix4'); +o3d.Param.SAS.createParam('worldViewProjection', + 'WorldViewProjectionParamMatrix4'); + +o3d.Param.SAS.createParam('worldI', + 'WorldInverseParamMatrix4'); +o3d.Param.SAS.createParam('viewI', + 'ViewInverseParamMatrix4'); +o3d.Param.SAS.createParam('projectionI', + 'ProjectionInverseParamMatrix4'); +o3d.Param.SAS.createParam('worldViewI', + 'WorldViewInverseParamMatrix4'); +o3d.Param.SAS.createParam('viewProjectionI', + 'ViewProjectionInverseParamMatrix4'); +o3d.Param.SAS.createParam('worldViewProjectionI', + 'WorldViewProjectionInverseParamMatrix4'); + +o3d.Param.SAS.createParam('worldT', + 'WorldInverseParamMatrix4'); +o3d.Param.SAS.createParam('viewT', + 'ViewTransposeParamMatrix4'); +o3d.Param.SAS.createParam('projectionT', + 'ProjectionTransposeParamMatrix4'); +o3d.Param.SAS.createParam('worldViewT', + 'WorldViewTransposeParamMatrix4'); +o3d.Param.SAS.createParam('viewProjectionT', + 'ViewProjectionTransposeParamMatrix4'); +o3d.Param.SAS.createParam('worldViewProjectionT', + 'WorldViewProjectionTransposeParamMatrix4'); + +o3d.Param.SAS.createParam('worldIT', + 'WorldInverseTransposeParamMatrix4'); +o3d.Param.SAS.createParam('viewIT', + 'ViewInverseTransposeParamMatrix4'); +o3d.Param.SAS.createParam('projectionIT', + 'ProjectionInverseTransposeParamMatrix4'); +o3d.Param.SAS.createParam('worldViewIT', + 'WorldViewInverseTransposeParamMatrix4'); +o3d.Param.SAS.createParam('viewProjectionIT', + 'ViewProjectionInverseTransposeParamMatrix4'); +o3d.Param.SAS.createParam('worldViewProjectionIT', + 'WorldViewProjectionInverseTransposeParamMatrix4'); + +/** + * Sets the base world matrix that gets use to compute all other products for + * SAS parameters. + */ +o3d.Param.SAS.setWorld = function(world) { + this['world'] = world; +}; + +/** + * Sets the base world matrix that gets use to compute all other products for + * SAS parameters. + */ +o3d.Param.SAS.setView = function(view) { + this['view'] = view; +}; + +/** + * Sets the base world matrix that gets use to compute all other products for + * SAS parameters. + */ +o3d.Param.SAS.setProjection = function(projection) { + var adjustedProjection = + [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 2, 0], [0, 0, -1, 1]]; + o3d.Transform.compose( + adjustedProjection, projection, adjustedProjection); + this['projection'] = projection; +}; + + diff --git a/o3d/samples/o3d-webgl/param_object.js b/o3d/samples/o3d-webgl/param_object.js new file mode 100644 index 0000000..625f876 --- /dev/null +++ b/o3d/samples/o3d-webgl/param_object.js @@ -0,0 +1,169 @@ +/* + * 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. + */ + + +/** + * A ParamObject is the base class for all objects that can have Params. + * Defines methods to add and remove params, search for params, etc. + * @constructor + */ +o3d.ParamObject = function() { + this.params_ = {}; +}; +o3d.inherit('ParamObject', 'NamedObject'); + + +/** + * Creates a Param with the given name and type on the ParamObject. + * Will fail if a param with the same name already exists. + * + * @param {string} param_name The name of the Param to be created. + * @param {string} param_type_name The type of Param to create. + * Valid types are + * 'ParamBoolean' + * 'ParamBoundingBox' + * 'ParamDrawContext' + * 'ParamDrawList' + * 'ParamEffect' + * 'ParamFloat' + * 'ParamFloat2' + * 'ParamFloat3' + * 'ParamFloat4' + * 'ParamFunction' + * 'ParamInteger' + * 'ParamMaterial' + * 'ParamMatrix4' + * 'ParamParamArray' + * 'ParamRenderSurface' + * 'ParamRenderDepthStencilSurface' + * 'ParamSampler' + * 'ParamSkin' + * 'ParamSteamBank' + * 'ParamState' + * 'ParamString' + * 'ParamTexture' + * 'ParamTransform' + * 'ProjectionParamMatrix4' + * 'ProjectionInverseParamMatrix4' + * 'ProjectionTransposeParamMatrix4' + * 'ProjectionInverseTransposeParamMatrix4' + * 'ViewParamMatrix4' + * 'ViewInverseParamMatrix4' + * 'ViewTransposeParamMatrix4' + * 'ViewInverseTransposeParamMatrix4' + * 'ViewProjectionParamMatrix4' + * 'ViewProjectionInverseParamMatrix4' + * 'ViewProjectionTransposeParamMatrix4' + * 'ViewProjectionInverseTransposeParamMatrix4' + * 'WorldParamMatrix4' + * 'WorldInverseParamMatrix4' + * 'WorldTransposeParamMatrix4' + * 'WorldInverseTransposeParamMatrix4' + * 'WorldViewParamMatrix4' + * 'WorldViewInverseParamMatrix4' + * 'WorldViewTransposeParamMatrix4' + * 'WorldViewInverseTransposeParamMatrix4' + * 'WorldViewProjectionParamMatrix4' + * 'WorldViewProjectionInverseParamMatrix4' + * 'WorldViewProjectionTransposeParamMatrix4' + * 'WorldViewProjectionInverseTransposeParamMatrix4' + * @returns {!o3d.Param} The newly created Param or null on failure. + */ +o3d.ParamObject.prototype.createParam = + function(param_name, param_type_name) { + if (!o3d.global.o3d[param_type_name]) + throw ('Invalid param type name: ' + param_type_name); + var param = new o3d.global.o3d[param_type_name]; + param.gl = this.gl; + param.owner_ = this; + this.params_[param_name] = param; + return this.params_[param_name]; +}; + + +/** + * Searches by name for a Param defined in the object. + * + * @param {string} param_name Name to search for. + * @returns {!o3d.Param} The Param with the given name, or null otherwise. + */ +o3d.ParamObject.prototype.getParam = + function(param_name) { + return this.params_[param_name]; +}; + + +/** + * Removes a Param from a ParamObject. + * + * This function will fail if the param does not exist on this ParamObject + * or if the param is unremovable. + * + * @param {!o3d.Param} param param to remove. + * @returns {boolean} True if the param was removed. + */ +o3d.ParamObject.prototype.removeParam = + function(param) { + o3d.notImplemented(); +}; + + +/** + * Gets all the param on this param object. + * + * Each access to this field gets the entire list, so it is best to get it + * just once. For example: + * + * var params = paramObject.params; + * for (var i = 0; i < params.length; i++) { + * var param = params[i]; + * } + * + * Note that modifications to this array [e.g. push()] will not affect + * the underlying ParamObject, while modifications to the array's members + * will affect them. + */ +o3d.ParamObject.prototype.params_ = {}; + + +/** + * Copies all the params from a the given source_param_object to this param + * object. Does not replace any currently existing params with the same name. + * + * @param {o3d.ParamObject} source_param_object param object to copy params + * from. + */ +o3d.ParamObject.prototype.copyParams = + function(source_param_object) { + o3d.notImplemented(); +}; + + diff --git a/o3d/samples/o3d-webgl/primitive.js b/o3d/samples/o3d-webgl/primitive.js new file mode 100644 index 0000000..ed45a65 --- /dev/null +++ b/o3d/samples/o3d-webgl/primitive.js @@ -0,0 +1,157 @@ +/* + * 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. + */ + + +/** + * A Primitive is a type of Element that is made from a list of points, + * lines or triangles that use a single material. + * + * @param opt_streamBank o3d.StreamBank The StreamBank used by this + * Primitive. + * @constructor + */ +o3d.Primitive = function(opt_streamBank) { + o3d.Element.call(this); + this.streamBank = opt_streamBank; +}; +o3d.inherit('Primitive', 'Element'); + + +/** + * @type {number} + */ +o3d.Primitive.Type = goog.typedef; + +/** + * Type of geometric primitives used by the Primitive. + */ +o3d.Primitive.POINTLIST = 1; +o3d.Primitive.LINELIST = 2; +o3d.Primitive.LINESTRIP = 3; +o3d.Primitive.TRIANGLELIST = 4; +o3d.Primitive.TRIANGLESTRIP = 5; +o3d.Primitive.TRIANGLEFAN = 6; + + + +/** + * The type of primitive the primitive is (i.e., POINTLIST, LINELIST, + * TRIANGLELIST, etc.) + * + * @type {o3d.Primitive.Type} + */ +o3d.Primitive.prototype.primitiveType = o3d.Primitive.TRIANGLELIST; + + + +/** + * The number of vertices the primitive has. + * + * @type {number} + */ +o3d.Primitive.prototype.numberVertices = 0; + + + +/** + * The number of rendering primitives (i.e., triangles, points, lines) the + * primitive has. + * + * @type {number} + */ +o3d.Primitive.prototype.numberPrimitives = 0; + + + +/** + * The index of the first vertex to render. + * Default = 0. + * + * @type {number} + */ +o3d.Primitive.prototype.startIndex = 0; + + + +/** + * The stream bank this primitive uses for vertices. + * @type {o3d.StreamBank} + */ +o3d.Primitive.prototype.streamBank = null; + + + +/** + * The index buffer for the primitive. If null the primitive is non-indexed. + * @type {number} + */ +o3d.Primitive.prototype.indexBuffer = null; + + + +/** + * Binds the vertex and index streams required to draw the shape. + */ +o3d.Primitive.prototype.render = function() { + var streamBank = this.streamBank; + var indexBuffer = this.indexBuffer; + + for (var semantic = 0; + semantic < streamBank.vertexStreams.length; + ++semantic) { + var streams = streamBank.vertexStreams[semantic]; + if (streams && streams.length) { + for (var semantic_index = 0; + semantic_index < streams.length; + ++semantic_index) { + var gl_index = semantic + semantic_index - 1; + var stream = streams[semantic_index]; + var field = stream.field; + var buffer = field.buffer; + + this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer.gl_buffer_); + this.gl.enableVertexAttribArray(gl_index); + + // TODO(petersont): Change that hard-coded 4 down there. + this.gl.vertexAttribPointer( + gl_index, field.numComponents, this.gl.FLOAT, false, + buffer.totalComponents * 4, field.offset_ * 4); + } + } + } + + // TODO(petersont): Change the hard-coded 3 and triangles too. + this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, indexBuffer.gl_buffer_); + this.gl.drawElements(this.gl.TRIANGLES, + this.numberPrimitives * 3, + this.gl.UNSIGNED_SHORT, + 0); +}; diff --git a/o3d/samples/o3d-webgl/raw_data.js b/o3d/samples/o3d-webgl/raw_data.js new file mode 100644 index 0000000..ab3c0f4 --- /dev/null +++ b/o3d/samples/o3d-webgl/raw_data.js @@ -0,0 +1,94 @@ +/* + * 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. + */ + + +/** + * A RawData object contains raw binary data which could contain + * image, audio, text, or other information. + * + * var request = g_pack.createArchiveRequest(); + * + * request.onfileavailable = function(rawData) { + * var texture = g_pack.createTextureFromRawData(rawData, true); + * ... + * }; + * + * request.send(); + * @constructor + */ +o3d.RawData = function() { }; +o3d.inherit('RawData', 'NamedObject'); + + +/** + * Returns the raw data as a string. The data must be a valid utf-8 string + * and the uri must end in .json, .txt, .xml, .ini or .csv + * @type {string} + */ +o3d.RawData.prototype.string_value = ''; + + + +/** + * The uri of the RawData. + * @type {string} + */ +o3d.RawData.prototype.uri = ''; + + + +/** + * The length in bytes of the RawData. + * @type {number} + */ +o3d.RawData.prototype.length = 0; + + + +/** + * Discards all the resources associated with this data object. + */ +o3d.RawData.prototype.discard = function() { + o3d.notImplemented(); +}; + + + +/** + * Flushes the memory resources associated with this data object, + * but keeps a cache in case the data object is used later. + */ +o3d.RawData.prototype.flush = function() { + o3d.notImplemented(); +}; + + + diff --git a/o3d/samples/o3d-webgl/ray_intersection_info.js b/o3d/samples/o3d-webgl/ray_intersection_info.js new file mode 100644 index 0000000..ab317b4 --- /dev/null +++ b/o3d/samples/o3d-webgl/ray_intersection_info.js @@ -0,0 +1,77 @@ +/* + * 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. + */ + + +/** + * A RayIntersectionInfo is used to return the results of ray intersection + * tests. + * @constructor + */ +o3d.RayIntersectionInfo = function() { + o3d.RayIntersectionInfo.prototype.position = [0, 0, 0]; +}; +o3d.inherit('RayIntersectionInfo', 'NamedObject'); + + +/** + * True if this ray intersection info is valid. For example if you call + * element.intersectRay on an element that has no vertex buffers the result + * will be invalid. + * @type {boolean} + */ +o3d.RayIntersectionInfo.prototype.valid = false; + + + +/** + * True if this ray intersection intersected something. + * @type {boolean} + */ +o3d.RayIntersectionInfo.prototype.intersected = false; + + + +/** + * The position the ray intersected something. + * type {!o3d.Point3} + */ +o3d.RayIntersectionInfo.prototype.position = [0, 0, 0]; + + + +/** + * The index of the primitive that was intersected. + * @type {number} + */ +o3d.RayIntersectionInfo.prototype.primitiveIndex = -1; + + + diff --git a/o3d/samples/o3d-webgl/render_node.js b/o3d/samples/o3d-webgl/render_node.js new file mode 100644 index 0000000..d97b2e9 --- /dev/null +++ b/o3d/samples/o3d-webgl/render_node.js @@ -0,0 +1,205 @@ +/* + * 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. + */ + + +/** + * RenderNode is the base of all RenderNodes in the render graph. + * RenderNodes are rendered in order of priority. + * + * @param {number} opt_priority The priority of this render node. Lower + * priorities are rendered first. + * @param {boolean} opt_active If true this node is processed. If false + * it is not. + * @constructor + */ +o3d.RenderNode = function(opt_priority, opt_active) { + this.priority = opt_priority; + this.children = []; +}; +o3d.inherit('RenderNode','ParamObject'); + + +/** + * Sets the priority of this render node. lower priorities are rendered first. + * + * @type {number} + */ +o3d.RenderNode.prototype.priority = 0; + + + +/** + * Setting false skips this render node. Setting true processes this render + * node. (ie, renders whatever it's supposed to render) + * + * @type {boolean} + */ +o3d.RenderNode.prototype.active = true; + + + +/** + * Sets the parent of the node by re-parenting the node under parent_node. + * Setting parent_node to null removes the node and the entire subtree below + * it from the render graph. + * + * @type {o3d.RenderNode} + */ +o3d.RenderNode.prototype.parent = null; + +o3d.RenderNode.prototype.__defineSetter__('parent', + function(p) { + this.parent_ = p; + p.addChild(this); + } +); + +o3d.RenderNode.prototype.__defineGetter__('parent', + function(p) { + return this.parent_; + } +); + +/** + * Adds a child node. + * @param {o3d.RenderNode} child The child to add. + */ +o3d.RenderNode.prototype.addChild = function(child) { + this.children.push(child); +}; + + + +/** + * The immediate children of this RenderNode. + * + * Each access to this field gets the entire list so it is best to get it + * just once. For example: + * + * var children = renderNode.children; + * for (var i = 0; i < children.length; i++) { + * var child = children[i]; + * } + * + * Note that modifications to this array [e.g. push()] will not affect + * the underlying RenderNode, while modifications to the array's members + * will affect them. + * + * @type {!Array.<o3d.RenderNode>} + */ +o3d.RenderNode.prototype.children = []; + + + +/** + * Returns this render node and all its descendants. Note that this render node + * might not be in the render graph. + * + * Note that modifications to this array [e.g. push()] will not affect + * the underlying RenderNode, while modifications to the array's members + * will affect them. + * + * An array containing all render nodes of the subtree. + */ +o3d.RenderNode.prototype.getRenderNodesInTree = + function() { + o3d.notImplemented(); +}; + + + +/** + * Searches for render nodes that match the given name in the hierarchy under + * and including this render node. Since there can be several render nodes + * with a given name the results are returned in an array. + * + * Note that modifications to this array [e.g. push()] will not affect + * the underlying RenderNode, while modifications to the array's members + * will affect them. + * + * @param {string} name Rendernode name to look for. + * @returns {Array.<!o3d.RenderNode>} An array containing all nodes among + * this node and its decendants that have the given name. + */ +o3d.RenderNode.prototype.getRenderNodesByNameInTree = + function(name) { + o3d.notImplemented(); +}; + + +/** + * Searches for render nodes that match the given class name in the hierarchy + * under and including this render node. + * + * Note that modifications to this array [e.g. push()] will not affect + * the underlying RenderNode, while modifications to the array's members + * will affect them. + * + * @param {string} class_name class name to look for. + * @returns {Array.<!o3d.RenderNode>} An array containing all nodes among + * this node and its decendants whose type is class_name. + */ +o3d.RenderNode.prototype.getRenderNodesByClassNameInTree = + function(class_name) { + o3d.notImplemented(); +}; + + +/** + * Recursively traverses the render graph starting at this node. + */ +o3d.RenderNode.prototype.render = function() { + function compare(a, b) { + return a.priority - b.priority; + } + this.children.sort(compare); + var children = this.children; + + this.before(); + for (var i = 0; i < children.length; ++i) { + children[i].render(); + } + this.after(); +}; + + +/** + * Called during the rendergraph traversal before the children are rendered. + */ +o3d.RenderNode.prototype.before = function() { }; + + +/** + * Called during the rendergraph traversal after the children are rendered. + */ +o3d.RenderNode.prototype.after = function() { }; + + diff --git a/o3d/samples/o3d-webgl/render_surface.js b/o3d/samples/o3d-webgl/render_surface.js new file mode 100644 index 0000000..d3b3877 --- /dev/null +++ b/o3d/samples/o3d-webgl/render_surface.js @@ -0,0 +1,89 @@ +/* + * 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. + */ + + +/** + * A RenderSurfaceBase is the base for RenderSurface and + * RenderDepthStencilSurface. + * + * @param {number} width The width of this RenderSurface. + * @param {number} height The height of this RenderSurface. + * @param {o3d.Texture} texture The texture of this RenderSurface. + * @constructor + */ +o3d.RenderSurfaceBase = function(width, height, texture) { + o3d.ParamObject.call(this); +}; +o3d.inherit('RenderSurfaceBase', 'ParamObject'); + + +/** + * The width of the surface, in pixels. + * @type {number} + */ +o3d.RenderSurfaceBase.prototype.width = 0; + + + +/** + * The height of the surface, in pixels. + * @type {number} + */ +o3d.RenderSurfaceBase.prototype.height = 0; + + + +/** + * A RenderSurface encapsulates the notion of a renderable surface. + * When used in conjunction with a RenderSurfaceSet node in the render graph, + * the API allows for rendering of primitives to the given surface. + * RenderSurface objects are not constructable through the Pack API, they may + * only be accessed through the texture getRenderSurface(...) interfaces. + * @constructor + */ +o3d.RenderSurface = function() { }; +o3d.inherit('RenderSurface', 'RenderSurfaceBase'); + + +/** + * The texture in which this surface is contained. + */ +o3d.RenderSurface.prototype.texture = null; + + +/** + * A RenderDepthStencilSurface represents a depth stencil render surface. + * @constructor + */ +o3d.RenderDepthStencilSurface = function() { }; +o3d.inherit('RenderDepthStencilSurface', 'RenderSurfaceBase'); + + diff --git a/o3d/samples/o3d-webgl/render_surface_set.js b/o3d/samples/o3d-webgl/render_surface_set.js new file mode 100644 index 0000000..dfcd901 --- /dev/null +++ b/o3d/samples/o3d-webgl/render_surface_set.js @@ -0,0 +1,74 @@ +/* + * 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. + */ + + +/** + * A RenderSurfaceSet node will bind depth and color RenderSurface nodes + * to the current rendering context. All RenderNodes descending + * from the given RenderSurfaceSet node will operate on the contents of + * the bound depth and color buffers. + * Note the following usage constraints of this node: + * 1) If both a color and depth surface is bound, then they must be of matching + * dimensions. + * 2) At least one of render_surface and render_depth_surface must non-null. + * + * @param {o3d.RenderSurface} opt_renderSurface The render surface to set. + * @param {o3d.RenderDepthStencilSurface} opt_renderDepthStencilSurface The + * depth stencil render surface to set. + * @constructor + */ +o3d.RenderSurfaceSet = function() { + o3d.RenderSurfaceSet.prototype.renderSurface = + opt_renderSurface; + o3d.RenderSurfaceSet.prototype.renderDepthStencilSurface = + opt_renderDepthStencilSurface; +}; +o3d.inherit('RenderSurfaceSet', 'RenderNode'); + + +/** + * The render surface to which the color contents of all RenderNode children + * should be drawn. + * @type {o3d.RenderSurface} + */ +o3d.RenderSurfaceSet.prototype.renderSurface = null; + + + +/** + * The render depth stencil surface to which the depth contents of all + * RenderNode children should be drawn. + * @type {o3d.RenderDepthStencilSurface} + */ +o3d.RenderSurfaceSet.prototype.renderDepthStencilSurface = null; + + + diff --git a/o3d/samples/o3d-webgl/shape.js b/o3d/samples/o3d-webgl/shape.js new file mode 100644 index 0000000..4754869 --- /dev/null +++ b/o3d/samples/o3d-webgl/shape.js @@ -0,0 +1,128 @@ +/* + * 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. + */ + + +/** + * The Shape represents a collection of Elements. The typical example is a + * cube with 6 faces where each face uses a different material would be + * represented as 1 Shape with 6 Elements, one for each material. + * @constructor + */ +o3d.Shape = function() { + this.elements = []; +}; +o3d.inherit('Shape', 'ParamObject'); + + +/** + * The elements owned by this shape. + * + * Each access to this field gets the entire list so it is best to get it + * just once. For example: + * + * var elements = renderNode.elements; + * for (var i = 0; i < elements.length; i++) { + * var element = elements[i]; + * } + * + * Note that modifications to this array [e.g. push()] will not affect + * the underlying Shape, while modifications to the array's members + * will affect them. + */ +o3d.Shape.prototype.elements = []; + + +/** + * Creates a DrawElement for each Element owned by this Shape. + * If an Element already has a DrawElement that uses \a material a new + * DrawElement will not be created. + * @param {o3d.Pack} pack pack used to manage created DrawElements. + * @param {o3d.Material} material material to use for each DrawElement. + * If you pass null it will use the material on the corresponding Element. + * This allows you to easily setup the default (just draw as is) by + * passing null or setup a shadow pass by passing in a shadow material. + */ +o3d.Shape.prototype.createDrawElements = + function(pack, material) { + o3d.notImplemented(); +}; + + +/** + * Adds and element to the list of elements for this shape. + * @param {o3d.Element} element The element to add. + */ +o3d.Shape.prototype.addElement = function(element) { + this.elements.push(element); +}; + + +/** + * Removes and element to the list of elements for this shape. + * @param {o3d.Element} element The element to add. + */ +o3d.Shape.prototype.removeElement = function(element) { + +}; + + +/** + * Called when the tree traversal finds this shape in the transform tree. + * Adds objects to the given drawlists if the drawlist of the material matches. + * @param {Array.<Object>} drawListInfos A list of objects containing + * drawlists and matrix info. + * @param {o3d.math.Matrix4} world The world matrix. + */ +o3d.Shape.prototype.writeToDrawLists = + function(drawListInfos, world, transform) { + var elements = this.elements; + for (var i = 0; i < elements.length; ++i) { + var element = elements[i]; + for (var j = 0; j < element.drawElements.length; ++j) { + var drawElement = element.drawElements[j]; + var materialDrawList = drawElement.material.drawList; + for (var k = 0; k < drawListInfos.length; ++k) { + var drawListInfo = drawListInfos[k]; + var list = drawListInfo.list; + var context = drawListInfo.context; + if (materialDrawList == list) { + list.list_.push({ + view: context.view, + projection: context.projection, + world: world, + transform: transform, + drawElement: drawElement + }); + } + } + } + } +}; diff --git a/o3d/samples/o3d-webgl/state.js b/o3d/samples/o3d-webgl/state.js new file mode 100644 index 0000000..cf5fea7 --- /dev/null +++ b/o3d/samples/o3d-webgl/state.js @@ -0,0 +1,567 @@ +/* + * 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. + */ + + +/** + * A State object sets the RenderStates for a particular material or StateSet. + * @constructor + */ +o3d.State = function() { + o3d.ParamObject.call(this); + + // TODO(petersont): Only some of these have been implemented. + var stateInfos = [ + {name: 'AlphaBlendEnable', paramType: 'ParamBoolean', + defaultValue: false}, + {name: 'AlphaComparisonFunction', paramType: 'ParamInteger', + defaultValue: o3d.State.CMP_ALWAYS}, + {name: 'AlphaReference', paramType: 'ParamFloat', + defaultValue: 0}, + {name: 'AlphaTestEnable', paramType: 'ParamBoolean', + defaultValue: false}, + {name: 'BlendAlphaEquation', paramType: 'ParamInteger', + defaultValue: o3d.State.BLEND_ADD}, + {name: 'BlendEquation', paramType: 'ParamInteger', + defaultValue: o3d.State.BLEND_ADD}, + {name: 'CCWStencilComparisonFunction', paramType: 'ParamInteger', + defaultValue: o3d.State.CMP_ALWAYS}, + {name: 'CCWStencilFailOperation', paramType: 'ParamInteger', + defaultValue: o3d.State.STENCIL_KEEP}, + {name: 'CCWStencilPassOperation', paramType: 'ParamInteger', + defaultValue: o3d.State.STENCIL_KEEP}, + {name: 'CCWStencilZFailOperation', paramType: 'ParamInteger', + defaultValue: o3d.State.STENCIL_KEEP}, + {name: 'ColorWriteEnable', paramType: 'ParamInteger', + defaultValue: 15}, + {name: 'CullMode', paramType: 'ParamInteger', + defaultValue: o3d.State.CULL_CW}, + {name: 'DestinationBlendAlphaFunction', paramType: 'ParamInteger', + defaultValue: o3d.State.BLENDFUNC_ZERO}, + {name: 'DestinationBlendFunction', paramType: 'ParamInteger', + defaultValue: o3d.State.BLENDFUNC_ZERO}, + {name: 'DitherEnable', paramType: 'ParamBoolean', + defaultValue: false}, + {name: 'FillMode', paramType: 'ParamInteger', + defaultValue: o3d.State.SOLID}, + {name: 'LineSmoothEnable', paramType: 'ParamBoolean', + defaultValue: false}, + {name: 'PointSize', paramType: 'ParamFloat', + defaultValue: 0}, + {name: 'PointSpriteEnable', paramType: 'ParamBoolean', + defaultValue: false}, + {name: 'PolygonOffset1', paramType: 'ParamFloat', + defaultValue: 0}, + {name: 'PolygonOffset2', paramType: 'ParamFloat', + defaultValue: 0}, + {name: 'SeparateAlphaBlendEnable', paramType: 'ParamBoolean', + defaultValue: false}, + {name: 'SourceBlendAlphaFunction', paramType: 'ParamInteger', + defaultValue: o3d.State.BLENDFUNC_ONE}, + {name: 'SourceBlendFunction', paramType: 'ParamInteger', + defaultValue: o3d.State.BLENDFUNC_ONE}, + {name: 'StencilComparisonFunction', paramType: 'ParamInteger', + defaultValue: o3d.State.CMP_ALWAYS}, + {name: 'StencilEnable', paramType: 'ParamBoolean', + defaultValue: false}, + {name: 'StencilFailOperation', paramType: 'ParamInteger', + defaultValue: o3d.State.STENCIL_KEEP}, + {name: 'StencilMask', paramType: 'ParamInteger', + defaultValue: 255}, + {name: 'StencilPassOperation', paramType: 'ParamInteger', + defaultValue: o3d.State.STENCIL_KEEP}, + {name: 'StencilReference', paramType: 'ParamInteger', + defaultValue: 0}, + {name: 'StencilWriteMask', paramType: 'ParamInteger', + defaultValue: 255}, + {name: 'StencilZFailOperation', paramType: 'ParamInteger', + defaultValue: o3d.State.STENCIL_KEEP}, + {name: 'TwoSidedStencilEnable', paramType: 'ParamBoolean', + defaultValue: false}, + {name: 'ZComparisonFunction', paramType: 'ParamInteger', + defaultValue: o3d.State.CMP_LESS}, + {name: 'ZEnable', paramType: 'ParamBoolean', + defaultValue: true}, + {name: 'ZWriteEnable', paramType: 'ParamBoolean', + defaultValue: true} + ]; + + this.state_params_ = {}; + + for (var i = 0; i < stateInfos.length; ++i) { + var info = stateInfos[i]; + var param = new o3d.global.o3d[info.paramType]; + param.value = info.defaultValue; + this.state_params_[info.name] = param; + } +}; +o3d.inherit('State', 'ParamObject'); + +/** + * A private object containing the the state params by name. + */ +o3d.State.prototype.state_params_ = { }; + + +/** + * Comparison + * CMP_NEVER (Never) + * CMP_LESS (Less Than) + * CMP_EQUAL (Equal To) + * CMP_LEQUAL (Less Than or Equal To) + * CMP_GREATER (Greater Than) + * CMP_NOTEQUAL (Not Equal To) + * CMP_GEQUAL (Greater Than or Equal To) + * CMP_ALWAYS (Always) + */ +o3d.State.CMP_NEVER = 0; +o3d.State.CMP_LESS = 1; +o3d.State.CMP_EQUAL = 2; +o3d.State.CMP_LEQUAL = 3; +o3d.State.CMP_GREATER = 4; +o3d.State.CMP_NOTEQUAL = 5; +o3d.State.CMP_GEQUAL = 6; +o3d.State.CMP_ALWAYS = 7; + + + +/** + * type {number} + */ +o3d.Cull = goog.typedef; + +/** + * Cull + * CULL_NONE Don't Cull by face + * CULL_CW Cull clock-wise faces + * CULL_CCW Cull counter clock-wise faces + */ +o3d.State.CULL_NONE = 0; +o3d.State.CULL_CW = 1; +o3d.State.CULL_CCW = 2; + + + + +/** + * Fill + * POINT + * WIREFRAME + * SOLID + */ +o3d.State.POINT = 0; +o3d.State.WIREFRAME = 1; +o3d.State.SOLID = 2; + + + +/** + * BlendingFunction + * BLENDFUNC_ZERO + * BLENDFUNC_ONE + * BLENDFUNC_SOURCE_COLOR + * BLENDFUNC_INVERSE_SOURCE_COLOR + * BLENDFUNC_SOURCE_ALPHA + * BLENDFUNC_INVERSE_SOURCE_ALPHA + * BLENDFUNC_DESTINATION_ALPHA + * BLENDFUNC_INVERSE_DESTINATION_ALPHA + * BLENDFUNC_DESTINATION_COLOR + * BLENDFUNC_INVERSE_DESTINATION_COLOR + * BLENDFUNC_SOURCE_ALPHA_SATUTRATE + */ +o3d.State.BLENDFUNC_ZERO = 0; +o3d.State.BLENDFUNC_ONE = 1; +o3d.State.BLENDFUNC_SOURCE_COLOR = 2; +o3d.State.BLENDFUNC_INVERSE_SOURCE_COLOR = 3; +o3d.State.BLENDFUNC_SOURCE_ALPHA = 4; +o3d.State.BLENDFUNC_INVERSE_SOURCE_ALPHA = 5; +o3d.State.BLENDFUNC_DESTINATION_ALPHA = 6; +o3d.State.BLENDFUNC_INVERSE_DESTINATION_ALPHA = 7; +o3d.State.BLENDFUNC_DESTINATION_COLOR = 8; +o3d.State.BLENDFUNC_INVERSE_DESTINATION_COLOR = 9; +o3d.State.BLENDFUNC_SOURCE_ALPHA_SATUTRATE = 10; + + + +/** + * BlendingEquation + * BLEND_ADD + * BLEND_SUBTRACT + * BLEND_REVERSE_SUBTRACT + * BLEND_MIN + * BLEND_MAX + */ +o3d.State.BLEND_ADD = 0; +o3d.State.BLEND_SUBTRACT = 1; +o3d.State.BLEND_REVERSE_SUBTRACT = 2; +o3d.State.BLEND_MIN = 3; +o3d.State.BLEND_MAX = 4; + + + +/** + * StencilOperation + * STENCIL_KEEP + * STENCIL_ZERO + * STENCIL_REPLACE + * STENCIL_INCREMENT_SATURATE + * STENCIL_DECREMENT_SATURATE + * STENCIL_INVERT + * STENCIL_INCREMENT + * STENCIL_DECREMENT + */ +o3d.State.STENCIL_KEEP = 0; +o3d.State.STENCIL_ZERO = 1; +o3d.State.STENCIL_REPLACE = 2; +o3d.State.STENCIL_INCREMENT_SATURATE = 3; +o3d.State.STENCIL_DECREMENT_SATURATE = 4; +o3d.State.STENCIL_INVERT = 5; +o3d.State.STENCIL_INCREMENT = 6; +o3d.State.STENCIL_DECREMENT = 7; + + + +/** + * Returns a Param for a given state. If the param does not already exist it + * will be created. If the state_name is invalid it will return null. + * @param {string} state_name name of the state + * @returns {o3d.Param} param or null if no matching state. + * + * Example: + * + * + * g_o3d = document.o3d.o3d; + * ... + * + * var state = my_pack.createState("my_state"); + * + * + * state.getStateParam('StencilEnable').value = true; + * state.getStateParam('StencilReference').value = 25; + * state.getStateParam('StencilPassOperation').value = + * g_o3d.State.STENCIL_REPLACE; + * state.getStateParam('StencilComparisonFunction').value = + * g_o3d.State.CMP_ALWAYS; + * state.getStateParam('ZEnable').value = false; + * state.getStateParam('ZWriteEnable').value = false; + * state.getStateParam('ColorWriteEnable').value = 0; + * + * Valid states: + * + * State NameTypeDefault Value + * o3d.AlphaBlendEnableParamBoolean + * default = false + * o3d.AlphaComparisonFunctionParamInteger, + * State.Comparisondefault = State.CMP_ALWAYS + * o3d.AlphaReferenceParamFloat 0-1 + * default = 0 + * o3d.AlphaTestEnableParamBoolean + * default = false + * o3d.BlendAlphaEquation + * ParamInteger, State.BlendingEquation + * default = State.BLEND_ADD + * o3d.BlendEquation + * ParamInteger, State.BlendingEquation + * default = State.BLEND_ADD + * o3d.CCWStencilComparisonFunction + * ParamInteger, State.Comparison + * default = State.CMP_ALWAYS + * o3d.CCWStencilFailOperation + * ParamInteger, State.StencilOperation + * default = State.STENCIL_KEEP + * o3d.CCWStencilPassOperation + * ParamInteger, State.StencilOperation + * default = State.STENCIL_KEEP + * o3d.CCWStencilZFailOperation + * ParamInteger, State.StencilOperation + * default = State.STENCIL_KEEP + * o3d.ColorWriteEnable + * ParamInteger 0-15 bit 0 = red, bit 1 = green, + * bit 2 = blue, bit 3 = alphadefault = 15 + * o3d.CullModeParamInteger, State.Cull + * default = State.CULL_CW + * o3d.DestinationBlendAlphaFunction + * ParamInteger, State.BlendingFunction + * default = State.BLENDFUNC_ZERO + * o3d.DestinationBlendFunction + * ParamInteger, State.BlendingFunction + * default = State.BLENDFUNC_ZERO + * o3d.DitherEnableParamBoolean + * default = false + * o3d.FillModeParamInteger, State.Fill + * default = State.SOLID + * o3d.LineSmoothEnableParamBoolean + * default = false + * o3d.PointSizeParamFloatTBD + * o3d.PointSpriteEnableParamBoolean + * default = false + * o3d.PolygonOffset1 + * ParamFloat, polygon offset slope factor0 + * o3d.PolygonOffset2ParamFloat, polygon offset bias (in + * resolvable units)0 + * o3d.SeparateAlphaBlendEnableParamBoolean + * default = false + * o3d.SourceBlendAlphaFunction + * ParamInteger, State.BlendingFunction + * default = State.BLENDFUNC_ONE + * o3d.SourceBlendFunction + * ParamInteger, State.BlendingFunction + * default = State.BLENDFUNC_ONE + * o3d.StencilComparisonFunction + * ParamInteger, State.Comparison + * default = State.CMP_ALWAYS + * o3d.StencilEnableParamBoolean + * default = false + * o3d.StencilFailOperation + * ParamInteger, State.StencilOperation + * default = State.STENCIL_KEEP + * o3d.StencilMaskParamInteger 0-255 + * default = 255 + * o3d.StencilPassOperation + * ParamInteger, State.StencilOperation + * default = State.STENCIL_KEEP + * o3d.StencilReferenceParamInteger 0-255 + * default = 0 + * o3d.StencilWriteMaskParamInteger 0-255 + * default = 255 + * o3d.StencilZFailOperation + * ParamInteger, State.StencilOperation + * default = State.STENCIL_KEEP + * o3d.TwoSidedStencilEnableParamBoolean + * default = false + * o3d.ZComparisonFunction + * ParamInteger, State.Comparison + * default = State.CMP_LESS + * o3d.ZEnableParamBoolean + * default = true + * o3d.ZWriteEnableParamBoolean + * default = true + * + * + * Note: Polygon offset is computed with the following formula: + * + * totalOffset = PolygonOffset1 * slope + PolygonOffset2 * r + * + * Slope is the maximum difference in depth between 2 adjacent pixels of the + * polygon. r is the smallest value that would fail the NOTEQUAL test against + * 0. + * Typical useful values to layer a polygon on top of another one are -1.0 for + * each of PolygonOffset1 and PolygonOffset2. + */ +o3d.State.prototype.getStateParam = + function(state_name) { + return this.state_params_[state_name]; +}; + + + +o3d.State.prototype.convertCmpFunc = function(cmp) { + switch(cmp) { + case o3d.State.CMP_ALWAYS: + return this.gl.ALWAYS; + case o3d.State.CMP_NEVER: + return this.gl.NEVER; + case o3d.State.CMP_LESS: + return this.gl.LESS; + case o3d.State.CMP_GREATER: + return this.gl.GREATER; + case o3d.State.CMP_LEQUAL: + return this.gl.LEQUAL; + case o3d.State.CMP_GEQUAL: + return this.gl.GEQUAL; + case o3d.State.CMP_EQUAL: + return this.gl.EQUAL; + case o3d.State.CMP_NOTEQUAL: + return this.gl.NOTEQUAL; + default: + break; + } + return this.gl.ALWAYS; +}; + + +o3d.State.prototype.convertFillMode = function(mode) { + switch (mode) { + case o3d.State.POINT: + return this.gl.POINT; + case o3d.State.WIREFRAME: + return this.gl.LINE; + case o3d.State.SOLID: + return this.gl.FILL; + default: + break; + } + return this.gl.FILL; +}; + + +o3d.State.prototype.convertBlendFunc = function(blend_func) { + switch (blend_func) { + case o3d.State.BLENDFUNC_ZERO: + return this.gl.ZERO; + case o3d.State.BLENDFUNC_ONE: + return this.gl.ONE; + case o3d.State.BLENDFUNC_SOURCE_COLOR: + return this.gl.SRC_COLOR; + case o3d.State.BLENDFUNC_INVERSE_SOURCE_COLOR: + return this.gl.ONE_MINUS_SRC_COLOR; + case o3d.State.BLENDFUNC_SOURCE_ALPHA: + return this.gl.SRC_ALPHA; + case o3d.State.BLENDFUNC_INVERSE_SOURCE_ALPHA: + return this.gl.ONE_MINUS_SRC_ALPHA; + case o3d.State.BLENDFUNC_DESTINATION_ALPHA: + return this.gl.DST_ALPHA; + case o3d.State.BLENDFUNC_INVERSE_DESTINATION_ALPHA: + return this.gl.ONE_MINUS_DST_ALPHA; + case o3d.State.BLENDFUNC_DESTINATION_COLOR: + return this.gl.DST_COLOR; + case o3d.State.BLENDFUNC_INVERSE_DESTINATION_COLOR: + return this.gl.ONE_MINUS_DST_COLOR; + case o3d.State.BLENDFUNC_SOURCE_ALPHA_SATUTRATE: + return this.gl.SRC_ALPHA_SATURATE; + default: + break; + } + return this.gl.ONE; +}; + + +o3d.State.prototype.convertBlendEquation = function(blend_equation) { + switch (blend_equation) { + case o3d.State.BLEND_ADD: + return this.gl.FUNC_ADD; + case o3d.State.BLEND_SUBTRACT: + return this.gl.FUNC_SUBTRACT; + case o3d.State.BLEND_REVERSE_SUBTRACT: + return this.gl.FUNC_REVERSE_SUBTRACT; + case o3d.State.BLEND_MIN: + return this.gl.MIN; + case o3d.State.BLEND_MAX: + return this.gl.MAX; + default: + break; + } + return this.gl.FUNC_ADD; +}; + + +o3d.State.prototype.convertStencilOp = function(stencil_func) { + switch (stencil_func) { + case o3d.State.STENCIL_KEEP: + return this.gl.KEEP; + case o3d.State.STENCIL_ZERO: + return this.gl.ZERO; + case o3d.State.STENCIL_REPLACE: + return this.gl.REPLACE; + case o3d.State.STENCIL_INCREMENT_SATURATE: + return this.gl.INCR; + case o3d.State.STENCIL_DECREMENT_SATURATE: + return this.gl.DECR; + case o3d.State.STENCIL_INVERT: + return this.gl.INVERT; + case o3d.State.STENCIL_INCREMENT: + return this.gl.INCR_WRAP; + case o3d.State.STENCIL_DECREMENT: + return this.gl.DECR_WRAP; + default: + break; + } + return this.gl.KEEP; +}; + + +o3d.State.prototype.set = function() { + var stateParams = this.state_params_; + + if (stateParams['AlphaBlendEnable'].value) { + this.gl.enable(this.gl.ALPHA); + } else { + this.gl.disable(this.gl.ALPHA); + } + + if (stateParams['SeparateAlphaBlendEnable'].value) { + this.gl.blendFuncSeparate( + this.convertBlendFunc(stateParams['SourceBlendFunction'].value), + this.convertBlendFunc(stateParams['DestinationBlendFunction'].value), + this.convertBlendFunc(stateParams['SourceBlendAlphaFunction'].value), + this.convertBlendFunc( + stateParams['DestinationBlendAlphaFunction'].value)); + } else { + this.gl.blendFuncSeparate( + this.convertBlendFunc(stateParams['SourceBlendFunction'].value), + this.convertBlendFunc(stateParams['DestinationBlendFunction'].value)); + } + + switch (stateParams['CullMode'].value) { + case o3d.State.CULL_CW: + this.gl.enable(this.gl.CULL_FACE); + this.gl.cullFace(this.gl.BACK); + break; + case o3d.State.CULL_CCW: + this.gl.enable(this.gl.CULL_FACE); + this.gl.cullFace(this.gl.FRONT); + break; + default: + this.gl.disable(this.gl.CULL_FACE); + break; + } + + if (stateParams['SeparateAlphaBlendEnable'].value) { + this.gl.blendEquationSeparate( + this.convertBlendEquation(stateParams['BlendEquation'].value), + this.convertBlendEquation(stateParams['BlendAlphaEquation'].value)); + } else { + this.gl.blendEquation( + this.convertBlendEquation(stateParams['BlendEquation'].value)); + } + + if (stateParams['DitherEnable'].value) { + this.gl.enable(this.gl.DITHER); + } else { + this.gl.disable(this.gl.DITHER); + } + + if (stateParams['ZEnable'].value) { + this.gl.enable(this.gl.DEPTH_TEST); + this.gl.depthFunc( + this.convertCmpFunc(stateParams['ZComparisonFunction'].value)); + } else { + this.gl.disable(this.gl.DEPTH_TEST); + } + + if (stateParams['StencilEnable'].value) { + this.gl.enable(this.gl.STENCIL_TEST); + this.gl.stencilFunc( + this.convertCmpFunc(stateParams['StencilComparisonFunction'].value)); + } else { + this.gl.disable(this.gl.STENCIL_TEST); + } +}; + diff --git a/o3d/samples/o3d-webgl/state_set.js b/o3d/samples/o3d-webgl/state_set.js new file mode 100644 index 0000000..8fe1881 --- /dev/null +++ b/o3d/samples/o3d-webgl/state_set.js @@ -0,0 +1,62 @@ +/* + * 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. + */ + + +/** + * A StateSet is a render node that sets render states of all of its + * children. You can make this a parent of a part of the render graph to set + * render states in a more global way. + * + * @param {o3d.State} opt_state The State the defines what states to set. + * @constructor + */ +o3d.StateSet = function(opt_state) { + o3d.ParamObject.call(this); + this.state = opt_state || null; +}; +o3d.inherit('StateSet', 'RenderNode'); + + +/** + * The State for this StateSet. + */ +o3d.StateSet.prototype.state = null; + + +/** + * Sets the current state to the member state. + */ +o3d.StateSet.prototype.before = function() { + if (this.state) + this.state.set(); +}; + + diff --git a/o3d/samples/o3d-webgl/stream.js b/o3d/samples/o3d-webgl/stream.js new file mode 100644 index 0000000..0a3cf19 --- /dev/null +++ b/o3d/samples/o3d-webgl/stream.js @@ -0,0 +1,101 @@ +/* + * 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. + */ + + +/** + * Namespace o3d + * @constructor + */ +o3d.Stream = function(semantic, semantic_index, field, start_index) { + this.semantic = semantic; + this.semanticIndex = semantic_index; + this.field = field; + this.startIndex = start_index; +}; +o3d.inherit('Stream', 'NamedObject') + +/** + * @type {number} + */ +o3d.Stream.Semantic = goog.typedef; + +/** + * Semantic, + * UNKNOWN_SEMANTIC = 0, + * POSITION, + * NORMAL, + * TANGENT, + * BINORMAL, + * COLOR, + * TEXCOORD + * + * Semantics used when binding buffers to the streambank. They determine how + * the Stream links up to the shader inputs. + */ +o3d.Stream.UNKNOWN_SEMANTIC = 0; +o3d.Stream.POSITION = 1; +o3d.Stream.NORMAL = 2; +o3d.Stream.TANGENT = 3; +o3d.Stream.BINORMAL = 4; +o3d.Stream.COLOR = 5; +o3d.Stream.TEXCOORD = 6; + + + +/** + * The associated Field. + */ +o3d.Stream.prototype.field = null; + + + +/** + * The semantic specified for the Stream. + */ +o3d.Stream.prototype.semantic = o3d.Stream.UNKNOWN_SEMANTIC; + + + +/** + * The semantic index specified for the Stream + * (eg., TEXCOORD1 = 1, BINORMAL7 = 7, etc). + */ +o3d.Stream.prototype.semanticIndex = 0; + + + +/** + * The start index for the Stream. + */ +o3d.Stream.prototype.startIndex = 0; + + + diff --git a/o3d/samples/o3d-webgl/stream_bank.js b/o3d/samples/o3d-webgl/stream_bank.js new file mode 100644 index 0000000..b6c032a --- /dev/null +++ b/o3d/samples/o3d-webgl/stream_bank.js @@ -0,0 +1,101 @@ +/* + * 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. + */ + + +/** + * The StreamBank a collection of streams that hold vertices. + * @constructor + */ +o3d.StreamBank = function() { + this.vertexStreams = []; +}; +o3d.inherit('StreamBank', 'NamedObject'); + +/** + * Array of streams. + */ +o3d.StreamBank.prototype.vertexStreams = []; + + +/** + * Binds a VertexBuffer field to the StreamBank and defines how the data in + * the buffer should be interpreted. The field's buffer must be of a + * compatible type otherwise the binding fails and the function returns false. + * @param {o3d.Stream.Semantic} semantic The particular use of this stream. + * @param {number} semantic_index Which index of a particular semantic to use. + * @param {o3d.Field} field The field containing information for this stream. + * @param {number} start_index The first element to use. + * @returns {boolean} True if successful. + */ +o3d.StreamBank.prototype.setVertexStream = + function(semantic, semantic_index, field, start_index) { + if (this.vertexStreams[semantic] == undefined) { + this.vertexStreams[semantic] = []; + } + this.vertexStreams[semantic][semantic_index] = new o3d.Stream( + semantic, semantic_index, field, start_index); +}; + + +/** + * Searches the vertex streams bound to the StreamBank for one with the given + * stream semantic. If a stream is not found then it returns null. + * @param {o3d.Stream.Semantic} semantic The particular use of this stream. + * @param {o3d.Stream.Semantic} semantic_index Which index of a particular + * semantic to use. + * @returns {o3d.Stream} The found stream or null if it does not exist. + */ +o3d.StreamBank.prototype.getVertexStream = + function(semantic, semantic_index) { + if (this.vertexStreams[semantic] == undefined) { + return; + } + return this.vertexStreams[semantic][semantic_index]; +}; + + +/** + * Removes a vertex stream from this StreamBank. + * @param {o3d.Stream.Semantic} semantic The particular use of this stream. + * @param {o3d.Stream.Semantic} semantic_index Which index of a particular + * semantic to use. + * @returns {boolean} true if the specified stream existed. + */ +o3d.StreamBank.prototype.removeVertexStream = + function(semantic, semantic_index) { + if (this.vertexStreams[semantic] == undefined) { + return false; + } + this.vertexStreams[semantic][semantic_index] = null; + return true; +}; + + diff --git a/o3d/samples/o3d-webgl/texture.js b/o3d/samples/o3d-webgl/texture.js new file mode 100644 index 0000000..767e608 --- /dev/null +++ b/o3d/samples/o3d-webgl/texture.js @@ -0,0 +1,463 @@ +/* + * 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. + */ + + +/** + * The Texture class is a base class for image data used in texture mapping. + * @constructor + */ +o3d.Texture = function() { + o3d.ParamObject.call(this); +}; +o3d.inherit('Texture', 'ParamObject'); + + +/** + * @type {number} + */ +o3d.Texture.Format = goog.typedef; + +/** + * Format, + * UNKNOWN_FORMAT + * XRGB8 + * ARGB8 + * ABGR16F + * R32F + * ABGR32F + * DXT1 + * DXT3 + * DXT5 + * + * The in-memory format of the texture bitmap. + * + * NOTE: The R32F format is different on GL vs D3D. If you use it in a shader + * you must only use the red channel. The green, blue and alpha channels are + * undefined. + * + * For example: + * + * ... + * + * sampler texSampler0; + * + * ... + * + * struct PixelShaderInput { + * float4 position : POSITION; + * float2 texcoord : TEXCOORD0; + * }; + * + * float4 pixelShaderFunction(PixelShaderInput input): COLOR { + * return tex2D(texSampler0, input.texcoord).rrrr; + * } + * + * @param {number} levels The number of mip levels in this texture. + */ +o3d.Texture.UNKNOWN_FORMAT = 0; +o3d.Texture.XRGB8 = 1; +o3d.Texture.ARGB8 = 2; +o3d.Texture.ABGR16F = 3; +o3d.Texture.R32F = 4; +o3d.Texture.ABGR32F = 5; +o3d.Texture.DXT1 = 6; +o3d.Texture.DXT3 = 7; +o3d.Texture.DXT5 = 8; + + + +/** + * The memory format used for storing the bitmap associated with the texture + * object. + * @type {o3d.Texture.Format} + */ +o3d.Texture.prototype.format = o3d.Texture.UNKNOWN_FORMAT; + + + +/** + * The number of mipmap levels used by the texture. + * type {number} + */ +o3d.Texture.prototype.levels = 1; + + + +/** + * True if all the alpha values in the texture are 1.0 + * type {boolean} + */ +o3d.Texture.prototype.alphaIsOne = true; + + + +/** + * Generates Mips. + * @param {number} source_level the mip to use as the source. + * @param {number} num_levels the number of mips from the source to generate. + */ +o3d.Texture.prototype.generateMips = + function(source_level, num_levels) { + o3d.notImplemented(); +}; + + +/** + * A class for 2D textures that defines the interface for getting + * the dimensions of the texture, its memory format and number of mipmap levels. + * + * @param {number} opt_width The width of this texture in pixels. + * @param {number} opt_height The height of this texture in pixels. + * @constructor + */ +o3d.Texture2D = function() { + this.width = opt_width || 0; + this.height = opt_height || 0; +}; +o3d.inherit('Texture2D', 'Texture'); + + +/** + * The width of the texture, in texels. + * @type {number} + */ +o3d.Texture2D.prototype.width = 0; + + + +/** + * The height of the texture, in texels. + * @type {number} + */ +o3d.Texture2D.prototype.height = 0; + + + +/** + * Returns a RenderSurface object associated with a mip_level of a texture. + * + * @param {number} mip_level The mip-level of the surface to be returned. + * @param {number} opt_pack pack This parameter is no longer used. + * The surface exists as long as the texture it came from exists. + * @returns {o3d.RenderSurface} The RenderSurface object. + */ +o3d.Texture2D.prototype.getRenderSurface = + function(mip_level, opt_pack) { + o3d.notImplemented(); +}; + + +/** + * Sets the values of the data stored in the texture. + * + * It is not recommend that you call this for large textures but it is useful + * for making simple ramps or noise textures for shaders. + * + * NOTE: the number of values must equal the size of the texture * the number + * of elements. In other words, for a XRGB8 texture there must be + * width * height * 3 values. For an ARGB8, ABGR16F or ABGR32F texture there + * must be width * height * 4 values. For an R32F texture there must be + * width * height values. + * + * NOTE: the order of channels is R G B for XRGB8 textures and R G B A + * for ARGB8, ABGR16F and ABGR32F textures so for example for XRGB8 textures\n + * \n + * [1, 0, 0] = a red pixel\n + * [0, 0, 1] = a blue pixel\n + * \n + * For ARGB8, ABGR16F, ABGR32F textures\n + * \n + * [1, 0, 0, 0] = a red pixel with zero alpha\n + * [1, 0, 0, 1] = a red pixel with one alpha\n + * [0, 0, 1, 1] = a blue pixel with one alpha\n + * + * @param {number} level the mip level to update. + * @param {number} values Values to be stored in the buffer. + */ +o3d.Texture2D.prototype.set = + function(level, values) { + o3d.notImplemented(); +}; + + +/** + * Sets a rectangular area of values in a texture. + * + * Does clipping. In other words if you pass in a 10x10 pixel array + * and give it destination of (-5, -5) it will only use the bottom 5x5 + * pixels of the array you passed in to set the top 5x5 pixels of the + * texture. + * + * See o3d.Texture2D.set for details on formats. + * + * @param {number} level the mip level to update. + * @param {number} destination_x The x coordinate of the area in the texture + * to affect. + * @param {number} destination_y The y coordinate of the area in the texture + * to affect. + * @param {number} source_width The width of the area to effect. The height is + * determined by the size of the array passed in. + * @param {number} values Values to be stored in the buffer. + */ +o3d.Texture2D.prototype.setRect = + function(level, destination_x, destination_y, source_width, values) { + o3d.notImplemented(); +}; + + +/** + * Gets a rectangular area of values from a texture. + * + * See o3d.Texture2D.set for details on formats. + * Can not be used for compressed textures. + * + * @param {number} level the mip level to get. + * @param {number} x The x coordinate of the area in the texture to retrieve. + * @param {number} y The y coordinate of the area in the texture to retrieve. + * @param {number} width The width of the area to retrieve. + * @param {number} height The height of the area to retrieve. + * @returns {number} Array of pixel values. + */ +o3d.Texture2D.prototype.getRect = + function(level, x, y, width, height) { + o3d.notImplemented(); +}; + + +/** + * Sets the content of the texture to the content of the bitmap. The texture + * and the bitmap must be the same dimensions and the same format. + * + * @param {o3d.Bitmap} bitmap The bitmap to copy data from. + */ +o3d.Texture2D.prototype.setFromBitmap = + function(bitmap) { + o3d.notImplemented(); +}; + + +/** + * Copy pixels from source bitmap to certain mip level. + * Scales if the width and height of source and dest do not match. + * TODO(petersont): Takes optional arguments. + * + * @param {o3d.Bitmap} source_img The source bitmap. + * @param {number} source_mip which mip from the source to copy from. + * @param {number} source_x x-coordinate of the starting pixel in the + * source image. + * @param {number} source_y y-coordinate of the starting pixel in the + * source image. + * @param {number} source_width width of the source image to draw. + * @param {number} source_height Height of the source image to draw. + * @param {number} dest_mip on which mip level to draw to. + * @param {number} dest_x x-coordinate of the starting pixel in the + * destination texture. + * @param {number} dest_y y-coordinate of the starting pixel in the + * destination texture. + * @param {number} dest_width width of the dest image. + * @param {number} dest_height height of the dest image. + */ +o3d.Texture2D.prototype.drawImage = + function(source_img, source_mip, source_x, source_y, source_width, + source_height, dest_mip, dest_x, dest_y, dest_width, + dest_height) { + o3d.notImplemented(); +}; + + +/** + * TextureCUBE is a class for textures used for cube mapping. A cube texture + * stores bitmaps for the 6 faces of a cube and is addressed via three texture + * coordinates. + * + * @param {number} edgeLength The length of any edge of this texture + * @constructor + */ +o3d.TextureCUBE = function() { }; +o3d.inherit('TextureCUBE', 'Texture'); + + +/** + * @type {number} + */ +o3d.TextureCUBE.CubeFace = goog.typedef; + + +/** + * CubeFace, + * FACE_POSITIVE_X + * FACE_NEGATIVE_X + * FACE_POSITIVE_Y + * FACE_NEGATIVE_Y + * FACE_POSITIVE_Z + * FACE_NEGATIVE_Z + * + * The names of each of the six faces of a cube map texture. + */ +o3d.TextureCUBE.FACE_POSITIVE_X = 0; +o3d.TextureCUBE.FACE_NEGATIVE_X = 1; +o3d.TextureCUBE.FACE_POSITIVE_Y = 2; +o3d.TextureCUBE.FACE_NEGATIVE_Y = 3; +o3d.TextureCUBE.FACE_POSITIVE_Z = 4; +o3d.TextureCUBE.FACE_NEGATIVE_Z = 5; + + +/** + * The length of each edge of the cube, in texels. + * @type {number} + */ +o3d.TextureCUBE.prototype.edge_length = 0; + + +/** + * Returns a RenderSurface object associated with a given cube face and + * mip_level of a texture. + * + * @param {o3d.TextureCUBE.CubeFace} face The cube face from which to extract + * the surface. + * @param {o3d.Pack} pack This parameter is no longer used. The surface exists + * as long as the texture it came from exists. + * @param {number} mip_level The mip-level of the surface to be returned. + * @returns {o3d.RenderSurface} The RenderSurface object. + */ +o3d.TextureCUBE.prototype.getRenderSurface = + function(face, mip_level, opt_pack) { + o3d.notImplemented(); +}; + + +/** + * Sets the values of the data stored in the texture. + * + * It is not recommend that you call this for large textures but it is useful + * for making simple ramps or noise textures for shaders. + * + * See o3d.Texture2D.set for details on formats. + * + * @param {o3d.TextureCUBE.CubeFace} face the face to update. + * @param {number} level the mip level to update. + * @param {number} values Values to be stored in the buffer. + */ +o3d.TextureCUBE.prototype.set = + function(face, level, values) { + o3d.notImplemented(); +}; + + +/** + * Sets a rectangular area of values in a texture. + * + * Does clipping. In other words if you pass in a 10x10 pixel array + * and give it destination of (-5, -5) it will only use the bottom 5x5 + * pixels of the array you passed in to set the top 5x5 pixels of the + * texture. + * + * See o3d.Texture2D.set for details on formats. + * + * @param {o3d.TextureCUBE.CubeFace} face the face to update. + * @param {number} level the mip level to update. + * @param {number} destination_x The x coordinate of the area in the texture + * to affect. + * @param {number} destination_y The y coordinate of the area in the texture + * to affect. + * @param {number} source_width The width of the area to effect. The height is + * determined by the size of the array passed in. + * @param {number} values Values to be stored in the buffer. + */ +o3d.TextureCUBE.prototype.setRect = + function(face, level, destination_x, destination_y, source_width, values) { + o3d.notImplemented(); +}; + + +/** + * Gets a rectangular area of values from a texture. + * + * See o3d.Texture2D.set for details on formats. + * Can not be used for compressed textures. + * + * @param {o3d.TextureCUBE.CubeFace} face the face to get. + * @param {number} level the mip level to get. + * @param {number} x The x coordinate of the area in the texture to retrieve. + * @param {number} y The y coordinate of the area in the texture to retrieve. + * @param {number} width The width of the area to retrieve. + * @param {number} height The height of the area to retrieve. + * @returns {number} Array of pixel values. + */ +o3d.TextureCUBE.prototype.getRect = + function(face, level, x, y, width, height) { + o3d.notImplemented(); +}; + + +/** + * Sets the content of a face of the texture to the content of the bitmap. The + * texture and the bitmap must be the same dimensions and the same format. + * + * @param {o3d.TextureCUBE.CubeFace} face The face to set. + * @param {o3d.Bitmap} bitmap The bitmap to copy data from. + */ +o3d.TextureCUBE.prototype.setFromBitmap = + function(face, bitmap) { + o3d.notImplemented(); +}; + + +/** + * Copy pixels from source bitmap to certain face and mip level. + * Scales if the width and height of source and dest do not match. + * TODO(petersont): Should take optional arguments. + * + * @param {o3d.Bitmap} source_img The source bitmap. + * @param {number} source_mip which mip of the source to copy from. + * @param {number} source_x x-coordinate of the starting pixel in the + * source image. + * @param {number} source_y y-coordinate of the starting pixel in the + * source image. + * @param {number} source_width width of the source image to draw. + * @param {number} source_height Height of the source image to draw. + * @param {o3d.TextureCUBE.CubeFace} face on which face to draw on. + * @param {number} dest_mip on which mip level to draw on. + * @param {number} dest_x x-coordinate of the starting pixel in the + * destination texture. + * @param {number} dest_y y-coordinate of the starting pixel in the + * destination texture. + * @param {number} dest_width width of the destination image. + * @param {number} dest_height height of the destination image. + */ +o3d.TextureCUBE.prototype.drawImage = + function(source_img, source_mip, source_x, source_y, source_width, + source_height, face, dest_mip, dest_x, dest_y, dest_width, + dest_height) { + o3d.notImplemented(); +}; + + diff --git a/o3d/samples/o3d-webgl/transform.js b/o3d/samples/o3d-webgl/transform.js new file mode 100644 index 0000000..2ef5d21 --- /dev/null +++ b/o3d/samples/o3d-webgl/transform.js @@ -0,0 +1,942 @@ +/* + * 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. + */ + + +/** + * The Transform defines parent child relationship and a localMatrix.. + * A Transform can have one or no parents and + * an arbitrary number of children. + * + * @param {o3d.math.Matrix4} opt_localMatrix The local matrix for this + * transform. + * @param {o3d.math.Matrix4} opt_worldMatrix ParamMatrix4 The world matrix of + * this transform. + * @param {boolean} opt_visible Whether or not this transform and all its + * children are visible. + * @param {o3d.BoundingBox} opt_boundingBox ParamBoundingBox The bounding box + * for this transform and all its children. + * @param {boolean} opt_cull ParamBoolean Whether or not to attempt to + * cull this transform and all its children based on whether or not its + * bounding box is in the view frustum. + * @constructor + */ +o3d.Transform = + function(opt_localMatrix, opt_worldMatrix, opt_visible, opt_boundingBox, + opt_cull) { + this.localMatrix = opt_localMatrix || + [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]; + this.worldMatrix = opt_worldMatrix || + [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]; + this.visible = opt_visible || true; + this.boundingBox = opt_boundingBox || + new o3d.BoundingBox([-1, -1, -1], [1, 1, 1]); + this.cull = opt_cull || false; + + this.children = []; + this.shapes = []; +}; +o3d.inherit('Transform', 'ParamObject'); + + +/** + * The Visibility for this transform. + * Default = true. + */ +o3d.Transform.prototype.visible = true; + + + +/** + * Sets the parent of the transform by re-parenting the transform under + * parent. Setting parent to null removes the transform and the + * entire subtree below it from the transform graph. + * If the operation would create a cycle it fails. + */ +o3d.Transform.prototype.parent = null; + +o3d.Transform.prototype.__defineSetter__('parent', + function(p) { + this.parent_ = p; + p.addChild(this); + } +); + +o3d.Transform.prototype.__defineGetter__('parent', + function(p) { + return this.parent_; + } +); + + +/** + * The immediate children of this Transform. + * + * Each access to this field gets the entire list, so it is best to get it + * just once. For example: + * + * var children = transform.children; + * for (var i = 0; i < children.length; i++) { + * var child = children[i]; + * } + * + * Note that modifications to this array [e.g. additions to it] will not affect + * the underlying Transform, while modifications to the members of the array + * will affect them. + */ +o3d.Transform.prototype.children = []; + + +/** + * Adds a child transform. + * @param {o3d.Transform} The new child. + */ +o3d.Transform.prototype.addChild = function(child) { + this.children.push(child); +}; + + +/** + * Returns all the transforms under this transform including this one. + * + * Note that modifications to this array [e.g. additions to it] will not affect + * the underlying Transform, while modifications to the members of the array + * will affect them. + * + * An array containing the transforms of the subtree. + */ +o3d.Transform.prototype.getTransformsInTree = + function() { + +}; + + + +/** + * Searches for transforms that match the given name in the hierarchy under and + * including this transform. Since there can be more than one transform with a + * given name, results are returned in an array. + * + * Note that modifications to this array [e.g. additions to it] will not affect + * the underlying Transform, while modifications to the members of the array + * will affect them. + * + * @param {string} name Transform name to look for. + * @returns {Array.<o3d.Transform>} An array containing the transforms of the + * under and including this transform matching the given name. + */ +o3d.Transform.prototype.getTransformsByNameInTree = + function(name) { + +}; + + +/** + * Evaluates and returns the current world matrix. + * + * The updated world matrix. + */ +o3d.Transform.prototype.getUpdatedWorldMatrix = + function() { + +}; + + +/** + * Adds a shape do this transform. + * @param {o3d.Shape} shape Shape to add. + */ +o3d.Transform.prototype.addShape = + function(shape) { + this.shapes.push(shape); +}; + + +/** + * Removes a shape from this transform. + * @param {o3d.Shape} shape Shape to remove. + * @returns {boolean} true if successful, false if shape was not in + * this transform. + */ +o3d.Transform.prototype.removeShape = + function(shape) { + +}; + + +/** + * Gets the shapes owned by this transform. + * + * Each access to this field gets the entire list so it is best to get it + * just once. For example: + * + * var shapes = transform.shapes; + * for (var i = 0; i < shapes.length; i++) { + * var shape = shapes[i]; + * } + * + * + * Note that modifications to this array [e.g. additions to it] will not affect + * the underlying Transform, while modifications to the members of the array + * will affect them. + */ +o3d.Transform.prototype.shapes = []; + + + +/** + * Walks the tree of transforms starting with this transform and creates + * draw elements. If an Element already has a DrawElement that uses material a + * new DrawElement will not be created. + * @param {o3d.Pack} pack Pack used to manage created elements. + * @param {o3d.Material} material Material to use for each element. If you + * pass null, it will use the material on the element to which a draw + * element is being added. In other words, a DrawElement will use the + * material of the corresponding Element if material is null. This allows + * you to easily setup the default (just draw as is) by passing null or + * setup a shadow pass by passing in a shadow material. + */ +o3d.Transform.prototype.createDrawElements = + function(pack, material) { + o3d.notImplemented(); +}; + + +/** + * World (model) matrix as it was last computed. + */ +o3d.Transform.prototype.worldMatrix = []; + + + +/** + * Local transformation matrix. + * Default = Identity. + */ +o3d.Transform.prototype.local_matrix = []; + + + +/** + * The cull setting for this transform. If true this Transform will be culled + * by having its bounding box compared to the view frustum of any draw context + * it is used with. + * Default = false. + */ +o3d.Transform.prototype.cull_ = false; + + + +/** + * The BoundingBox for this Transform. If culling is on this bounding box will + * be tested against the view frustum of any draw context used to with this + * Transform. + */ +o3d.Transform.prototype.boundingBox = null; + + + +/** + * Sets the local matrix of this transform to the identity matrix. + */ +o3d.Transform.prototype.identity = function() { + var m = this.localMatrix; + for (var i = 0; i < 4; ++i) { + for (var j = 0; j < 4; ++j) { + m[i][j] = i==j ? 1 : 0; + } + } +}; + + +/* + * Utility function to copose a matrix with another matrix. + * Precomposes b with a, changing a, or if the target matrix if + * one is provided. + * + * @param {!Array.<!Array.<number>>} a + * @param {!Array.<!Array.<number>>} b + * @param {!Array.<!Array.<number>>} opt_target + */ +o3d.Transform.compose = function(a, b, opt_target) { + var t = opt_target || a; + 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]; + t[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); + t[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); + t[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); + t[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); +}; + + +/** + * Tests whether two matrices are either equal in the sense that they + * refer to the same memory, or equal in the sense that they have equal + * entries. + * + * @param {!Array.<!Array.<number>>} a A matrix. + * @param {!Array.<!Array.<number>>} b Another matrix. + * @returns {boolean} Whether they are equal. + */ +o3d.Transform.matricesEqual = function(a, b) { + if (a==b) { + return true; + } + for (var i = 0; i < 4; ++i) { + for (var j = 0; j < 4; ++j) { + if (a[i][j] != b[i][j]) { + return false; + } + } + } + return true; +}; + + +/** + * Computes the transpose of the matrix a in place if no target is provided. + * Or if a target is provided, turns the target into the transpose of a. + * + * @param {!Array.<!Array.<number>>} m A matrix. + * @param {Array.<!Array.<number>>} opt_target + * The matrix to become the transpose of m. + */ +o3d.Transform.transpose = function(m, opt_target) { + var t = opt_target || m; + 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]; + t[0].splice(0, 4, m00, m10, m20, m30); + t[1].splice(0, 4, m01, m11, m21, m31); + t[2].splice(0, 4, m02, m12, m22, m32); + t[3].splice(0, 4, m03, m13, m23, m33); +}; + + +/** + * Computes the inverse of the matrix a in place if no target is provided. + * Or if a target is provided, turns the target into the transpose of a. + * + * @param {!Array.<!Array.<number>>} m A matrix. + * @param {Array.<!Array.<number>>} opt_target The matrix to become the + * inverse of a. + */ +o3d.Transform.inverse = function(m, opt_target) { + var t = opt_target || a; + 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]; + + var tmp_0 = m22 * m33; + var tmp_1 = m32 * m23; + var tmp_2 = m12 * m33; + var tmp_3 = m32 * m13; + var tmp_4 = m12 * m23; + var tmp_5 = m22 * m13; + var tmp_6 = m02 * m33; + var tmp_7 = m32 * m03; + var tmp_8 = m02 * m23; + var tmp_9 = m22 * m03; + var tmp_10 = m02 * m13; + var tmp_11 = m12 * m03; + var tmp_12 = m20 * m31; + var tmp_13 = m30 * m21; + var tmp_14 = m10 * m31; + var tmp_15 = m30 * m11; + var tmp_16 = m10 * m21; + var tmp_17 = m20 * m11; + var tmp_18 = m00 * m31; + var tmp_19 = m30 * m01; + var tmp_20 = m00 * m21; + var tmp_21 = m20 * m01; + var tmp_22 = m00 * m11; + var tmp_23 = m10 * m01; + + var t0 = (tmp_0 * m11 + tmp_3 * m21 + tmp_4 * m31) - + (tmp_1 * m11 + tmp_2 * m21 + tmp_5 * m31); + var t1 = (tmp_1 * m01 + tmp_6 * m21 + tmp_9 * m31) - + (tmp_0 * m01 + tmp_7 * m21 + tmp_8 * m31); + var t2 = (tmp_2 * m01 + tmp_7 * m11 + tmp_10 * m31) - + (tmp_3 * m01 + tmp_6 * m11 + tmp_11 * m31); + var t3 = (tmp_5 * m01 + tmp_8 * m11 + tmp_11 * m21) - + (tmp_4 * m01 + tmp_9 * m11 + tmp_10 * m21); + + var d = 1.0 / (m00 * t0 + m10 * t1 + m20 * t2 + m30 * t3); + + t[0].splice(0, 4, d * t0, d * t1, d * t2, d * t3); + t[1].splice(0, 4, d * ((tmp_1 * m10 + tmp_2 * m20 + tmp_5 * m30) - + (tmp_0 * m10 + tmp_3 * m20 + tmp_4 * m30)), + d * ((tmp_0 * m00 + tmp_7 * m20 + tmp_8 * m30) - + (tmp_1 * m00 + tmp_6 * m20 + tmp_9 * m30)), + d * ((tmp_3 * m00 + tmp_6 * m10 + tmp_11 * m30) - + (tmp_2 * m00 + tmp_7 * m10 + tmp_10 * m30)), + d * ((tmp_4 * m00 + tmp_9 * m10 + tmp_10 * m20) - + (tmp_5 * m00 + tmp_8 * m10 + tmp_11 * m20))); + t[2].splice(0, 4, d * ((tmp_12 * m13 + tmp_15 * m23 + tmp_16 * m33) - + (tmp_13 * m13 + tmp_14 * m23 + tmp_17 * m33)), + d * ((tmp_13 * m03 + tmp_18 * m23 + tmp_21 * m33) - + (tmp_12 * m03 + tmp_19 * m23 + tmp_20 * m33)), + d * ((tmp_14 * m03 + tmp_19 * m13 + tmp_22 * m33) - + (tmp_15 * m03 + tmp_18 * m13 + tmp_23 * m33)), + d * ((tmp_17 * m03 + tmp_20 * m13 + tmp_23 * m23) - + (tmp_16 * m03 + tmp_21 * m13 + tmp_22 * m23))); + t[3].splice(0, 4, d * ((tmp_14 * m22 + tmp_17 * m32 + tmp_13 * m12) - + (tmp_16 * m32 + tmp_12 * m12 + tmp_15 * m22)), + d * ((tmp_20 * m32 + tmp_12 * m02 + tmp_19 * m22) - + (tmp_18 * m22 + tmp_21 * m32 + tmp_13 * m02)), + d * ((tmp_18 * m12 + tmp_23 * m32 + tmp_15 * m02) - + (tmp_22 * m32 + tmp_14 * m02 + tmp_19 * m12)), + d * ((tmp_22 * m22 + tmp_16 * m02 + tmp_21 * m12) - + (tmp_20 * m12 + tmp_23 * m22 + tmp_17 * m02))); +}; + + +/** + * Pre-composes the local matrix of this Transform with a translation. For + * example, if the local matrix is a rotation then new local matrix will + * translate by the given vector and then rotated. + */ +o3d.Transform.prototype.translate = + function() { + var v; + if (arguments.length == 3) { + v = arguments; + } else { + v = arguments[0]; + } + var m = this.localMatrix; + + 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); +}; + + +/** + * Pre-composes the local matrix of this Transform with a rotation about the + * x-axis. For example, if the local matrix is a tranlsation, the new local + * matrix will rotate around the x-axis and then translate. + * + * @param {number} radians The number of radians to rotate around x-axis. + */ +o3d.Transform.prototype.rotateX = + function(angle) { + var m = this.localMatrix; + + 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); +}; + + +/** + * Pre-composes the local matrix of this Transform with a rotation about the + * y-axis. For example, if the local matrix is a translation, the new local + * matrix will rotate around the y-axis and then translate. + * + * @param {number} radians The number of radians to rotate around y-axis. + */ +o3d.Transform.prototype.rotateY = + function(angle) { + var m = this.localMatrix; + + 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); +}; + + +/** + * Pre-composes the local matrix of this Transform with a rotation about the + * z-axis. For example, if the local matrix is a translation, the new local + * matrix will rotate around the z-axis and then translate. + * + * @param {number} radians The number of radians to rotate around z-axis. + */ +o3d.Transform.prototype.rotateZ = + function(angle) { + var m = this.localMatrix; + + 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); +}; + + +/** + * Pre-composes the local matrix of this Transform with a rotation. + * Interprets the three entries 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 {!o3d.math.Vector3} v A vector of angles (in radians) by which + * to rotate around the x, y and z axes. + */ +o3d.Transform.prototype.rotateZYX = + function(v) { + var m = this.localMatrix; + + 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); +}; + + +/** + * Pre-composes the local matrix of this Transform with a rotation around the + * given axis. For example, if the local matrix is a translation, the new + * local matrix will rotate around the given axis and then translate. + * + * @param {number} angle The number of radians to rotate. + * @param {!o3d.math.Vector3} axis a non-zero vector representing the axis + * around which to rotate. + */ +o3d.Transform.prototype.axisRotate = + function(axis, angle) { + var m = this.localMatrix; + + 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); +}; + + +/** + * Pre-composes the local matrix of this Transform with a rotation defined by + * the given quaternion. + * + * @param {o3d.math.Quat} q A non-zero quaternion to be interpreted as a + * rotation. + */ +o3d.Transform.prototype.quaternionRotate = + function(q) { + var m = this.localMatrix; + + 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; + + o3d.Transform.compose(this.localMatrix, [ + [(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]]); +}; + + +/** + * Pre-composes the local matrix of this transform by a scaling transformation. + * For example, if the local matrix is a rotation, the new local matrix will + * scale and then rotate. + */ +o3d.Transform.prototype.scale = + function() { + var v; + if (arguments.length == 3) { + v = arguments; + } else { + v = arguments[0]; + } + + var m = this.localMatrix; + + 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]); +}; + + +/** + * Utility function to flatten an o3djs-style matrix + * (which is an array of arrays) into one array of entries. + * @param {Array.<Array.<number> >} m The o3djs-style matrix. + * @returns {Array.<number>} The flattened matrix. + */ +o3d.Transform.flattenMatrix4 = function(m) { + var m0 = m[0]; + var m1 = m[1]; + var m2 = m[2]; + var m3 = m[3]; + return [m0[0], m0[1], m0[2], m0[3], + m1[0], m1[1], m1[2], m1[3], + m2[0], m2[1], m2[2], m2[3], + m3[0], m3[1], m3[2], m3[3]]; +}; + + +/** + * Traverses the transform tree starting at this node and adds DrawElements + * for each shape to DrawList. + * @param {Array.<Object>} drawListInfos A list of objects containing a draw + * list and matrix information. + * @param {o3d.math.Matrix4} opt_parentWorldMatrix + */ +o3d.Transform.prototype.traverse = + function(drawListInfos, opt_parentWorldMatrix) { + opt_parentWorldMatrix = + opt_parentWorldMatrix || + [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]; + + o3d.Transform.compose( + opt_parentWorldMatrix, this.localMatrix, this.worldMatrix); + + var children = this.children; + var shapes = this.shapes; + + for (var i = 0; i < shapes.length; ++i) { + shapes[i].writeToDrawLists(drawListInfos, this.worldMatrix, this); + } + + for (var i = 0; i < children.length; ++i) { + children[i].traverse(drawListInfos, this.worldMatrix); + } +}; + + diff --git a/o3d/samples/o3d-webgl/tree_traversal.js b/o3d/samples/o3d-webgl/tree_traversal.js new file mode 100644 index 0000000..5a5dbb6 --- /dev/null +++ b/o3d/samples/o3d-webgl/tree_traversal.js @@ -0,0 +1,111 @@ +/* + * 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. + */ + + +/** + * A TreeTraversal has multiple DrawLists registered with it. Each DrawList has + * a DrawContext registered with it. At render time the TreeTraversal walks the + * transform graph from the transform it's pointing at and for each DrawElement + * it finds who's matertial matches one of its registered DrawLists it adds that + * DrawElement to that DrawList. + * + * @param {o3d.Transform} opt_transform The root transform to start traversing + * by this TreeTraveral. + * @constructor + */ +o3d.TreeTraversal = function(opt_transform) { + this.transform = opt_transform; + this.drawLists = []; + this.drawListsToReset_ = []; +}; +o3d.inherit('TreeTraversal', 'RenderNode'); + + +/** + * The root Transform this TreeTraversal will start traversing from. + */ +o3d.TreeTraversal.prototype.transform = null; + + +/** + * Private list of registered drawlists. + */ +o3d.TreeTraversal.prototype.drawLists_ = []; + +/** + * Private list of drawlists to reset at render-time before traversal. + */ +o3d.TreeTraversal.prototype.drawListsToReset_ = []; + +/** + * Registers a DrawList with this TreeTraversal so that when this + * TreeTraversal traverses its tree, DrawElements using materials that use + * this DrawList will be added though possibly culled by the view frustum of + * the DrawContext. Note: passing in the same DrawList more than once will + * override the previous settings for that DrawList. + * @param {o3d.DrawList} draw_list DrawList to register. + * @param {o3d.DrawContext} draw_context DrawContext to use with the DrawList. + * @param {boolean} reset true if you want the DrawList reset before + * traversing. + */ +o3d.TreeTraversal.prototype.registerDrawList = + function(draw_list, draw_context, reset) { + if (reset) { + this.drawListsToReset_.push(draw_list); + } + this.drawLists_.push({ + list:draw_list, + context:draw_context}); +}; + + +/** + * Unregisters a DrawList with this TreeTraversal. + * @param {o3d.DrawList} draw_list DrawList to unregister. + * @returns {boolean} true if unregistered. false if this draw_list was + * not registered. + */ +o3d.TreeTraversal.prototype.unregisterDrawList = + function(draw_list) { + o3d.notImplemented(); +}; + + +/** + * Called in the render graph traversal before the children are rendered. + */ +o3d.TreeTraversal.prototype.before = + function() { + for(var i = 0; i < this.drawListsToReset_.length; ++i) { + this.drawListsToReset_[i].list_ = []; + } + this.transform.traverse(this.drawLists_); +}; diff --git a/o3d/samples/o3d-webgl/types.js b/o3d/samples/o3d-webgl/types.js new file mode 100644 index 0000000..1207059 --- /dev/null +++ b/o3d/samples/o3d-webgl/types.js @@ -0,0 +1,119 @@ +/* + * 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. + */ + + +/** + * Namespace for math types. + */ +o3d.math = {} + + +/** + * An Array of 3 numbers. + * @type {!Array.<number>} + */ +o3d.math.Point3 = goog.typedef; + + +/** + * An Array of 3 numbers. + * @type {!Array.<number>} + */ +o3d.math.Vector3 = goog.typedef; + + +/** + * An Array of 2 numbers. + * @type {!Array.<number>} + */ +o3d.Float2 = goog.typedef; + + +/** + * An Array of 3 numbers. + * @type {!Array.<number>} + */ +o3d.Float3 = goog.typedef; + + +/** + * An Array of 4 numbers. + * @type {!Array.<number>} + */ +o3d.Float4 = goog.typedef; + + +/** + * A 4x4 Matrix of numbers. + * @type {!Array.<!Array.<number>>} + */ +o3d.math.Matrix4 = goog.typedef; + +/** + * An array of 4 numbers. + * @type {!Array.<number>} + */ +o3d.math.Quat = goog.typedef; + + +/** + * A function. + * @type {Object} + */ +o3d.ErrorCallback = goog.typedef; + + +/** + * A function. + * @type {Object} + */ +o3d.TickCallback = goog.typedef; + + +/** + * A function. + * @type {Object} + */ +o3d.RenderCallback = goog.typedef; + + +/** + * A function. + * @type {Object} + */ +o3d.LostResourcesCallback = goog.typedef; + + +/** + * A function. + * @type {Object} + */ +o3d.EventCallback = goog.typedef; diff --git a/o3d/samples/o3d-webgl/viewport.js b/o3d/samples/o3d-webgl/viewport.js new file mode 100644 index 0000000..6c082c0 --- /dev/null +++ b/o3d/samples/o3d-webgl/viewport.js @@ -0,0 +1,96 @@ +/* + * 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. + */ + + +/** + * A Viewport is a render node that sets the render viewport and depth range + * for its children. It uses an array in the format [left, top, width, height] + * where left, top, width and height are in a 0.0 to 1.0 range that represent + * positions and dimensions relative to the size of the client's rendering + * area. The depth range is represented by an array in the format + * [min Z, max Z]. The depth range provides the mapping of the clip space + * coordinates into normalized z buffer coordinates. + * + * @param {o3d.math.Float4} viewport The viewport setting. + * @param {o3d.math.Float2} depthRange ParamFloat2 The depth range setting. + * @constructor + */ +o3d.Viewport = function(opt_viewport, opt_depthRange) { + this.viewport = opt_viewport || [0.0, 0.0, 1.0, 1.0]; + this.depthRange = opt_depthRange || [0.0, 1.0]; +}; +o3d.inherit('Viewport', 'RenderNode'); + + +/** + * The position and size to set the viewport in + * [left, top, width, height] format. + * + * Note: These values must describe a rectangle that is 100% inside the client + * area. In other words, [0.5, 0.0, 1.0, 1.0] would describe an area that is + * 1/2 off right side of the screen. That is an invalid value and will be + * clipped to [0.5, 0.0, 0.5, 1.0]. + * + * Default = [0.0, 0.0, 1.0, 1.0]. In other words, the full area. + * + * @type {!Array.<number>} + */ +o3d.Viewport.prototype.viewport = [0.0, 0.0, 1.0, 1.0]; + + + +/** + * The min Z and max Z depth range in [min Z, max Z] format. + * Default = [0.0, 1.0]. + * + * @type {!Array.<number>} + */ +o3d.Viewport.prototype.depthRange = [0.0, 1.0]; + + +/** + * Called before the children are rendered. Sets up a viewport and + * scissor region in gl. + */ +o3d.Viewport.prototype.before = function() { + var x = this.viewport[0] * this.gl.canvas.width; + var y = this.viewport[1] * this.gl.canvas.height; + var width = this.viewport[2] * this.gl.canvas.width; + var height = this.viewport[3] * this.gl.canvas.height; + this.gl.viewport(x, y, width, height); + if (x != 0 || y != 0 || this.viewport[2] != 1 || this.viewport[3] != 1) { + this.gl.enable(this.gl.SCISSOR_TEST); + this.gl.scissor(x, y, width, height); + } else { + + } +}; + diff --git a/o3d/samples/o3djs/webgl.js b/o3d/samples/o3djs/webgl.js new file mode 100644 index 0000000..6940660 --- /dev/null +++ b/o3d/samples/o3djs/webgl.js @@ -0,0 +1,114 @@ +/* + * 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.util'); + +/** + * A Module with various utilities. + * @namespace + */ +o3djs.webgl = o3djs.webgl || {}; + + +/** + * Finds all divs with an id that starts with "o3d" and inits a canvas + * under them with o3d client object and the o3d namespace. + */ +o3djs.webgl.makeClients = function(callback, + opt_features, + opt_requiredVersion, + opt_failureCallback, + opt_id, + opt_tag) { + opt_failureCallback = opt_failureCallback || o3djs.webgl.informPluginFailure; + + var clientElements = []; + var elements = o3djs.util.getO3DContainerElements(opt_id, opt_tag); + + 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.webgl.createClient(element, features); + clientElements.push(objElem); + } + + callback(clientElements); +}; + + +/** + * Creates a canvas under the given parent element and an o3d.Client + * under that. + */ +o3djs.webgl.createClient = function(element, opt_features) { + opt_features = opt_features || ''; + + // TODO(petersont): Not sure what to do with the features object. + var canvas; + canvas = document.createElement('canvas'); + canvas.setAttribute('width', element.getAttribute('width')); + canvas.setAttribute('height', element.getAttribute('height')); + canvas.client = new o3d.Client; + canvas.o3d = o3d; + + var gl; + try {gl = canvas.getContext("experimental-webgl") } catch(e) { } + if (!gl) + try {gl = canvas.getContext("moz-webgl") } catch(e) { } + if (!gl) { + alert("No WebGL context found"); + return null; + } + + canvas.client.gl = gl; + + element.appendChild(canvas); + return canvas; +}; + + |