summaryrefslogtreecommitdiffstats
path: root/o3d
diff options
context:
space:
mode:
authorpetersont@google.com <petersont@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-29 22:17:57 +0000
committerpetersont@google.com <petersont@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-29 22:17:57 +0000
commit8258a86b378bc6a41fa8947aee92375ec8ff615c (patch)
treed5c8cddbbaa23500f951c09cf4f89957459efdc1 /o3d
parent0380c12a8f7fde532f95da39f48376d256367f9b (diff)
downloadchromium_src-8258a86b378bc6a41fa8947aee92375ec8ff615c.zip
chromium_src-8258a86b378bc6a41fa8947aee92375ec8ff615c.tar.gz
chromium_src-8258a86b378bc6a41fa8947aee92375ec8ff615c.tar.bz2
Added culling sample.
Review URL: http://codereview.chromium.org/1703014 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45993 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d')
-rw-r--r--o3d/samples/o3d-webgl-samples/culling.html320
-rw-r--r--o3d/samples/o3d-webgl/bitmap.js1
-rw-r--r--o3d/samples/o3d-webgl/bounding_box.js181
-rw-r--r--o3d/samples/o3d-webgl/client.js115
-rw-r--r--o3d/samples/o3d-webgl/draw_list.js6
-rw-r--r--o3d/samples/o3d-webgl/element.js6
-rw-r--r--o3d/samples/o3d-webgl/field.js24
-rw-r--r--o3d/samples/o3d-webgl/pack.js1
-rw-r--r--o3d/samples/o3d-webgl/param.js37
-rw-r--r--o3d/samples/o3d-webgl/primitive.js40
-rw-r--r--o3d/samples/o3d-webgl/ray_intersection_info.js6
-rw-r--r--o3d/samples/o3d-webgl/shape.js31
-rw-r--r--o3d/samples/o3d-webgl/transform.js76
-rw-r--r--o3d/samples/o3djs/webgl.js7
14 files changed, 772 insertions, 79 deletions
diff --git a/o3d/samples/o3d-webgl-samples/culling.html b/o3d/samples/o3d-webgl-samples/culling.html
new file mode 100644
index 0000000..af1031c
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/culling.html
@@ -0,0 +1,320 @@
+<!--
+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.
+-->
+
+<!--
+O3D Culling.
+
+Make sure things off screen get culled.
+
+By default nothing is culled. If you want object to be culled you must setup
+bounding boxes in the transform graph that fit the needs of your application
+and then turn on culling for those objects you want culled.
+-->
+<!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>
+Culling.
+</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.util');
+o3djs.require('o3djs.math');
+o3djs.require('o3djs.rendergraph');
+o3djs.require('o3djs.primitives');
+o3djs.require('o3djs.material');
+
+// global variables
+var g_timeMult = 1.0;
+var g_framesRendered = 0;
+var g_o3d;
+var g_math;
+var g_client;
+var g_viewInfo;
+var g_pack;
+var g_totalTransformsElement;
+var g_transformsProcessedElement;
+var g_transformsCulledElement;
+var g_totalDrawElementsElement;
+var g_totalDrawableThingsElement;
+var g_drawElementsProcessedElement;
+var g_drawElementsCulledElement;
+var g_drawElementsRenderedElement;
+var g_primitivesRenderedElement;
+var g_groupTransforms = [];
+var GROUPS_ACROSS = 2;
+var UNITS_ACROSS_GROUP = 2;
+var TOTAL_ACROSS = GROUPS_ACROSS * UNITS_ACROSS_GROUP;
+var HALF_WIDTH = TOTAL_ACROSS * 0.0;
+var UNIT_SPACING = 200;
+
+function createInstances(pack, shape) {
+ // Make a grid of transforms and put a shape instance on each one.
+ for (var g = 0; g < GROUPS_ACROSS; g++) {
+ for (var h = 0; h < GROUPS_ACROSS; h++) {
+ for (var i = 0; i < GROUPS_ACROSS; i++) {
+ var groupTransform = pack.createObject('Transform');
+ g_groupTransforms[g_groupTransforms.length] = groupTransform;
+ groupTransform.parent = g_client.root;
+ // Turn on culling for this transform.
+ groupTransform.cull = true;
+ var boundingBox = new g_o3d.BoundingBox([0, 0, 0],
+ [0, 0, 0]);
+ groupTransform.translate(
+ (g * UNITS_ACROSS_GROUP - HALF_WIDTH) * UNIT_SPACING,
+ (h * UNITS_ACROSS_GROUP - HALF_WIDTH) * UNIT_SPACING,
+ (i * UNITS_ACROSS_GROUP - HALF_WIDTH) * UNIT_SPACING);
+
+ for (var x = 0; x < UNITS_ACROSS_GROUP; x++) {
+ for (var y = 0; y < UNITS_ACROSS_GROUP; y++) {
+ for (var z = 0; z < UNITS_ACROSS_GROUP; z++) {
+ var transform = pack.createObject('Transform');
+ transform.parent = groupTransform;
+ // Turn on culling for this transform.
+ transform.cull = true;
+ transform.addShape(shape);
+ // Add up the bounding boxes of all the elements.
+ var elements = shape.elements;
+ var box = elements[0].boundingBox;
+ for (var ee = 1; ee < elements.length; ee++) {
+ box = box.add(elements[ee].boundingBox);
+ }
+
+ // Set the transform to have a bounding box that is the sum
+ // of all the elements under it.
+ transform.boundingBox = box;
+ transform.translate(
+ (x - UNITS_ACROSS_GROUP * 0.5) * UNIT_SPACING,
+ (y - UNITS_ACROSS_GROUP * 0.5) * UNIT_SPACING,
+ (z - UNITS_ACROSS_GROUP * 0.5) * UNIT_SPACING);
+ transform.createParam('diffuse', 'ParamFloat4').value = [
+ (g * UNITS_ACROSS_GROUP + x) * (1 / TOTAL_ACROSS),
+ (h * UNITS_ACROSS_GROUP + y) * (1 / TOTAL_ACROSS),
+ (i * UNITS_ACROSS_GROUP + z) * (1 / TOTAL_ACROSS),
+ 1];
+ // Add the box for this bounding box to the box for the group.
+ var box = transform.boundingBox.mul(transform.localMatrix);
+ boundingBox = boundingBox.add(box);
+ }
+ }
+ }
+ // Set the bounding box for the group transform to encompass all
+ // the transforms below it.
+ groupTransform.boundingBox = boundingBox;
+ }
+ }
+ }
+}
+
+/**
+ * Creates the client area.
+ */
+function init() {
+ // These are here so that they are visible to both the browser (so
+ // selenium sees them) and the embedded V8 engine.
+ window.g_clock = 0;
+ window.g_finished = false; // for selenium testing.
+
+ o3djs.webgl.makeClients(initStep2);
+}
+
+/**
+ * Initializes O3D and creates one shape.
+ * @param {Array} clientElements Array of o3d object elements.
+ */
+function initStep2(clientElements) {
+ // Initializes global variables and libraries.
+ var o3dElement = clientElements[0];
+ g_o3d = o3dElement.o3d;
+ g_math = o3djs.math;
+
+ // Set window.g_client as well. Otherwise when the sample runs in
+ // V8, selenium won't be able to find this variable (it can only see
+ // the browser environment).
+ window.g_client = g_client = o3dElement.client;
+
+ g_totalDrawableThingsElement =
+ o3djs.util.getElementById('totalDrawableThings');
+ g_totalTransformsElement =
+ o3djs.util.getElementById('totalTransforms');
+ g_transformsProcessedElement =
+ o3djs.util.getElementById('transformsProcessed');
+ g_transformsCulledElement =
+ o3djs.util.getElementById('transformsCulled');
+ g_totalDrawElementsElement =
+ o3djs.util.getElementById('totalDrawElements');
+ g_drawElementsProcessedElement =
+ o3djs.util.getElementById('drawElementsProcessed');
+ g_drawElementsCulledElement =
+ o3djs.util.getElementById('drawElementsCulled');
+ g_drawElementsRenderedElement =
+ o3djs.util.getElementById('drawElementsRendered');
+ g_primitivesRenderedElement =
+ o3djs.util.getElementById('primitivesRendered');
+
+ // Creates a pack to manage our resources/assets
+ g_pack = g_client.createPack();
+
+ g_viewInfo = o3djs.rendergraph.createBasicView(
+ g_pack,
+ g_client.root,
+ g_client.renderGraphRoot);
+
+ // Create our projection matrix, with a vertical field of view of 45
+ // degrees a near clipping plane of 0.1 and far clipping plane of 10000.
+ g_viewInfo.drawContext.projection = g_math.matrix4.perspective(
+ g_math.degToRad(45),
+ g_client.width / g_client.height,
+ 0.1,
+ 10000);
+
+ // Create and load the effect.
+ var material = o3djs.material.createBasicMaterial(
+ g_pack,
+ g_viewInfo,
+ [1, 1, 1, 1]);
+
+ // Create 2 spheres.
+ var shape1 = o3djs.primitives.createSphere(
+ g_pack,
+ material,
+ 40,
+ 20,
+ 20,
+ g_math.matrix4.translation([-50, 0, 0]));
+
+ var shape2 = o3djs.primitives.createSphere(
+ g_pack,
+ material,
+ 20,
+ 20,
+ 20,
+ g_math.matrix4.translation([50, 0, 0]));
+
+ // Create a shape and move the 2 sphere primitives to the same shape.
+ // This is done to show that each of the primitives under the shape
+ // will get culled separately.
+ var shape = g_pack.createObject('Shape');
+ shape1.elements[0].owner = shape;
+ shape2.elements[0].owner = shape;
+ // delete the old shapes.
+ g_pack.removeObject(shape1);
+ g_pack.removeObject(shape2);
+ var elements = shape.elements;
+ // Turn on culling for the two sphere elements.
+ elements[0].cull = true;
+ elements[1].cull = true;
+
+ createInstances(g_pack, shape);
+
+ g_totalDrawableThingsElement.innerHTML =
+ GROUPS_ACROSS * UNITS_ACROSS_GROUP *
+ GROUPS_ACROSS * UNITS_ACROSS_GROUP *
+ GROUPS_ACROSS * UNITS_ACROSS_GROUP;
+
+ g_totalDrawElementsElement.innerHTML = g_client.getObjectsByClassName(
+ 'o3d.DrawElement').length;
+ g_totalTransformsElement.innerHTML = g_client.getObjectsByClassName(
+ 'o3d.Transform').length;
+
+ // Setup an onrender callback for animation.
+ g_client.setRenderCallback(onrender);
+
+ window.g_finished = true; // for selenium testing.
+}
+
+var g_flag = false;
+
+// spin the camera.
+function onrender(renderEvent) {
+ g_framesRendered++;
+ // Get the number of seconds since the last render.
+ var elapsedTime = renderEvent.elapsedTime;
+
+ // Update g_clock in the browser and cache a V8 copy that can be
+ // accessed efficiently. g_clock must be in the browser for selenium.
+ var clock = window.g_clock + elapsedTime * window.g_timeMult;
+ window.g_clock = clock;
+
+ var x = Math.sin(clock * 0.1) * 300;
+ var z = Math.cos(clock * 0.1) * 300;
+ var y = Math.sin(clock * 0.2) * 300;
+
+ g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
+ [x, y, z],
+ [0, 0, 0],
+ [0, 1, 0]);
+
+ g_transformsProcessedElement.innerHTML = renderEvent.transformsProcessed;
+ g_transformsCulledElement.innerHTML = renderEvent.transformsCulled;
+ g_drawElementsProcessedElement.innerHTML = renderEvent.drawElementsProcessed;
+ g_drawElementsCulledElement.innerHTML = renderEvent.drawElementsCulled;
+ g_drawElementsRenderedElement.innerHTML = renderEvent.drawElementsRendered;
+ g_primitivesRenderedElement.innerHTML = renderEvent.primitivesRendered;
+}
+
+/**
+ * Remove any callbacks so they don't get called after the page has unloaded.
+ */
+function unload() {
+ if (g_client) {
+ g_client.cleanup();
+ }
+}
+
+</script>
+</head>
+<body onload="init()" onunload="unload()">
+<h1>Culling</h1>
+Objects off screen should get culled.
+<br/>
+<!-- Start of O3D client area -->
+<div id="o3d" style="width: 800px; height: 600px;"></div>
+<!-- End of O3D client area -->
+
+<table>
+<tr><td>Total Drawable Things:</td><td><span id="totalDrawableThings">-</span></td></tr>
+<tr><td>Total Transforms:</td><td><span id="totalTransforms">-</span></td></tr>
+<tr><td>Transforms Processed:</td><td><span id="transformsProcessed">-</span></td></tr>
+<tr><td>Transforms Culled:</td><td><span id="transformsCulled">-</span></td></tr>
+<tr><td>Total DrawElements:</td><td><span id="totalDrawElements">-</span></td></tr>
+<tr><td>DrawElements Processed:</td><td><span id="drawElementsProcessed">-</span></td></tr>
+<tr><td>DrawElements Culled:</td><td><span id="drawElementsCulled">-</span></td></tr>
+<tr><td>DrawElements Rendered:</td><td><span id="drawElementsRendered">-</span></td></tr>
+<tr><td>Primitives Rendered:</td><td><span id="primitivesRendered">-</span></td></tr>
+</table>
+</body>
+</html>
diff --git a/o3d/samples/o3d-webgl/bitmap.js b/o3d/samples/o3d-webgl/bitmap.js
index 94e90f8..444fc0c 100644
--- a/o3d/samples/o3d-webgl/bitmap.js
+++ b/o3d/samples/o3d-webgl/bitmap.js
@@ -82,6 +82,7 @@ o3d.Bitmap.scratch_canvas_ = null;
/**
* Gets a canvas to use for scratch work.
+ * @return {Canvas} The canvas.
* @private
*/
o3d.Bitmap.getScratchCanvas_ = function() {
diff --git a/o3d/samples/o3d-webgl/bounding_box.js b/o3d/samples/o3d-webgl/bounding_box.js
index 3492868d..b585c31 100644
--- a/o3d/samples/o3d-webgl/bounding_box.js
+++ b/o3d/samples/o3d-webgl/bounding_box.js
@@ -52,10 +52,52 @@ o3d.inherit('BoundingBox', 'ParamObject');
/**
+ * Computes a list of 8 3-dimensional vectors for the corners of the box.
+ * @return {!Array.<Array<numbers>>} The list of corners.
+ */
+o3d.BoundingBox.prototype.corners_ = function() {
+ var result = [];
+ var m = [this.minExtent, this.maxExtent];
+ for (var i = 0; i < 2; ++i) {
+ for (var j = 0; j < 2; ++j) {
+ for (var k = 0; k < 2; ++k) {
+ result.push([m[i][0], m[j][1], m[k][2]]);
+ }
+ }
+ }
+
+ return result;
+};
+
+
+/**
+ * Computes the smallest bounding box containing all the points in the given
+ * list, and either modifies the optional box passed in to match, or returns
+ * that box as a new box.
+ * @param {!Array.<Array<numbers>>} points A non-empty list of points.
+ * @param {o3d.BoundingBox} opt_targetBox Optional box to modify instead of
+ * returning a new box.
+ * @private
+ */
+o3d.BoundingBox.fitBoxToPoints_ = function(points, opt_targetBox) {
+ var target = opt_targetBox || new o3d.BoundingBox();
+ for (var index = 0; index < 3; ++index) {
+ target.maxExtent[index] = target.minExtent[index] = points[0][index];
+ for (var i = 1; i < points.length; ++i) {
+ var point = points[i];
+ target.minExtent[index] = Math.min(target.minExtent[index], point[index]);
+ target.maxExtent[index] = Math.max(target.maxExtent[index], point[index]);
+ }
+ }
+ return target;
+};
+
+
+/**
* True if this boundingbox has been initialized.
* @type {boolean}
*/
-o3d.BoundingBox.prototype.valid_ = false;
+o3d.BoundingBox.prototype.valid = false;
/**
@@ -65,7 +107,6 @@ o3d.BoundingBox.prototype.valid_ = false;
o3d.BoundingBox.prototype.minExtent = [0, 0, 0];
-
/**
* The max extent of the box.
* @type {!o3d.math.Point3}
@@ -73,7 +114,6 @@ o3d.BoundingBox.prototype.minExtent = [0, 0, 0];
o3d.BoundingBox.prototype.maxExtent = [0, 0, 0];
-
/**
* Multiplies the bounding box by the given matrix returning a new bounding
* box.
@@ -82,7 +122,14 @@ o3d.BoundingBox.prototype.maxExtent = [0, 0, 0];
*/
o3d.BoundingBox.prototype.mul =
function(matrix) {
- o3d.notImplemented();
+ var corners = this.corners_();
+ var new_corners = [];
+
+ for (var i = 0; i < corners.length; ++i) {
+ new_corners.push(o3d.Transform.transformPoint(matrix, corners[i]));
+ }
+
+ return o3d.BoundingBox.fitBoxToPoints_(new_corners);
};
@@ -94,7 +141,13 @@ o3d.BoundingBox.prototype.mul =
*/
o3d.BoundingBox.prototype.add =
function(box) {
- o3d.notImplemented();
+ return new o3d.BoundingBox(
+ [Math.min(box.minExtent[0], this.minExtent[0]),
+ Math.min(box.minExtent[1], this.minExtent[1]),
+ Math.min(box.minExtent[2], this.minExtent[2])],
+ [Math.max(box.maxExtent[0], this.maxExtent[0]),
+ Math.max(box.maxExtent[1], this.maxExtent[1]),
+ Math.max(box.maxExtent[2], this.maxExtent[2])]);
};
@@ -112,19 +165,129 @@ o3d.BoundingBox.prototype.add =
*/
o3d.BoundingBox.prototype.intersectRay =
function(start, end) {
- o3d.notImplemented();
+ var result = new RayIntersectionInfo;
+
+ if (this.valid) {
+ result.valid = true;
+ result.intersected = true; // True until proven false.
+
+ var kNumberOfDimensions = 3;
+ var kRight = 0;
+ var kLeft = 1;
+ var kMiddle = 2;
+
+ var dir = [end[0] - start[0], end[1] - start[1], end[2] - start[2]];
+ var coord = [0, 0, 0];
+ var inside = true;
+
+ var quadrant = [];
+ var max_t = [];
+ var candidate_plane = [];
+
+ for (var i = 0; i < kNumberOfDimensions; ++i) {
+ quadrant.push(0.0);
+ max_t.push(0.0);
+ candidate_plane.push(0,0);
+ }
+
+ var which_plane;
+
+ // Find candidate planes; this loop can be avoided if rays cast all from
+ // the eye (assumes perpsective view).
+ for (var i = 0; i < kNumberOfDimensions; ++i) {
+ if (start[i] < min_extent_[i]) {
+ quadrant[i] = kLeft;
+ candidate_plane[i] = min_extent_[i];
+ inside = false;
+ } else if (start[i] > max_extent_[i]) {
+ quadrant[i] = kRight;
+ candidate_plane[i] = max_extent_[i];
+ inside = false;
+ } else {
+ quadrant[i] = kMiddle;
+ }
+ }
+
+ // Ray origin inside bounding box.
+ if (inside) {
+ result.position = start;
+ result.inside = true;
+ } else {
+ // Calculate T distances to candidate planes.
+ for (var i = 0; i < kNumberOfDimensions; ++i) {
+ if (quadrant[i] != kMiddle && dir[i] != 0.0) {
+ max_t[i] = (candidate_plane[i] - start[i]) / dir[i];
+ } else {
+ max_t[i] = -1.0;
+ }
+ }
+
+ // Get largest of the max_t's for final choice of intersection.
+ which_plane = 0;
+ for (var i = 1; i < kNumberOfDimensions; ++i) {
+ if (max_t[which_plane] < max_t[i]) {
+ which_plane = i;
+ }
+ }
+
+ // Check final candidate actually inside box.
+ if (max_t[which_plane] < 0.0) {
+ result.intersected = false;
+ } else {
+ for (var i = 0; i < kNumberOfDimensions; ++i) {
+ if (which_plane != i) {
+ coord[i] = start[i] + max_t[which_plane] * dir[i];
+ if (coord[i] < min_extent_[i] || coord[i] > max_extent_[i]) {
+ result.intersected = false;
+ break;
+ }
+ } else {
+ coord[i] = candidate_plane[i];
+ }
+ }
+
+ // Ray hits box.
+ result.position = coord;
+ }
+ }
+ }
+
+ return result;
};
/**
- * Returns true if the bounding box is inside the frustum.
+ * Returns true if the bounding box is inside the frustum matrix.
+ * It checks all 8 corners of the bounding box against the 6 frustum planes
+ * and determines whether there's at least one plane for which all 6 points lie
+ * on the outside side of it. In that case it reports that the bounding box
+ * is outside the frustum. Note that this is a conservative check in that
+ * it in certain cases it will report that a box is in the frustum even if it
+ * really isn't. However if it reports that the box is outside then it's
+ * guaranteed to be outside.
* @param {!o3d.math.Matrix4} matrix Matrix to transform the box from its
* local space to view frustum space.
- * @return {boolean} True if the box is in the frustum.
+ * @return {boolean} True if the box is in the frustum.
*/
o3d.BoundingBox.prototype.inFrustum =
function(matrix) {
- o3d.notImplemented();
+ var corners = this.corners_();
+ var bb_test = 0x3f;
+ for (var i = 0; i < corners.length; ++i) {
+ var corner = corners[i];
+ var p = o3d.Transform.transformPoint(matrix, corner);
+ bb_test &= (((p[0] > 1.0) << 0) |
+ ((p[0] < -1.0) << 1) |
+ ((p[1] > 1.0) << 2) |
+ ((p[1] < -1.0) << 3) |
+ ((p[2] > 1.0) << 4) |
+ ((p[2] < 0.0) << 5));
+ if (bb_test == 0) {
+ return true;
+ }
+ }
+
+ return (bb_test == 0);
};
diff --git a/o3d/samples/o3d-webgl/client.js b/o3d/samples/o3d-webgl/client.js
index 5d91416..62ec060 100644
--- a/o3d/samples/o3d-webgl/client.js
+++ b/o3d/samples/o3d-webgl/client.js
@@ -97,18 +97,8 @@ o3d.Renderer.clients_ = [];
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_;
- client.updateDisplayInfo_();
- if (client.render_callback) {
- client.render_callback(renderEvent);
- }
- client.then_ = now;
- client.renderTree(client.renderGraphRoot);
+
+ client.render();
}
};
@@ -213,10 +203,12 @@ o3d.ClientInfo.prototype.non_power_of_two_textures = true;
*/
o3d.Client = function() {
o3d.NamedObject.call(this);
- this.root = new o3d.Transform;
- this.renderGraphRoot = new o3d.RenderNode;
- this.root = new o3d.Transform;
+
+ var tempPack = this.createPack();
+ this.root = tempPack.createObject('Transform');
+ this.renderGraphRoot = tempPack.createObject('RenderNode');
this.clientId = o3d.Client.nextId++;
+ this.packs_ = [tempPack];
if (o3d.Renderer.clients_.length == 0)
o3d.Renderer.installRenderInterval();
@@ -269,6 +261,13 @@ o3d.Client.prototype.root = null;
/**
+ * A list of all packs for this client.
+ * @type {!Array.<!o3d.Pack>}
+ */
+o3d.Client.prototype.packs_ = [];
+
+
+/**
* Function that gets called when the client encounters an error.
*/
o3d.Client.prototype.error_callback = function(error_message) {
@@ -313,12 +312,26 @@ o3d.Client.prototype.cleanup = function () {
o3d.Client.prototype.createPack =
function() {
var pack = new o3d.Pack;
+ pack.client = this;
pack.gl = this.gl;
+ this.packs_.push(pack);
return pack;
};
/**
+ * Creates a pack object.
+ * A pack object.
+ * @param {!o3d.Pack} pack The pack to remove.
+ */
+o3d.Client.prototype.destroyPack =
+ function(pack) {
+ o3d.removeFromArray(this.packs_, pack);
+};
+
+
+
+/**
* Searches the Client for an object matching the given id.
*
* @param {number} id The id of the object to look for.
@@ -339,8 +352,14 @@ o3d.Client.prototype.getObjectById =
*/
o3d.Client.prototype.getObjects =
function(name, class_name) {
- o3d.notImplemented();
- return [];
+ var objects = [];
+
+ for (var i = 0; i < this.packs_.length; ++i) {
+ var pack = this.packs_[i];
+ objects = objects.concat(pack.getObjects(name, class_name));
+ }
+
+ return objects;
};
@@ -351,8 +370,14 @@ o3d.Client.prototype.getObjects =
*/
o3d.Client.prototype.getObjectsByClassName =
function(class_name) {
- o3d.notImplemented();
- return [];
+ var objects = [];
+
+ for (var i = 0; i < this.packs_.length; ++i) {
+ var pack = this.packs_[i];
+ objects = objects.concat(pack.getObjectsByClassName(class_name));
+ }
+
+ return objects;
};
@@ -387,10 +412,34 @@ o3d.Client.prototype.renderMode = o3d.Client.RENDERMODE_CONTINUOUS;
* RENDERMODE_ON_DEMAND.
*/
o3d.Client.prototype.render = function() {
- this.renderTree();
+ // Synthesize a render event.
+ var render_event = new o3d.RenderEvent;
+
+ var now = (new Date()).getTime() * 0.001;
+ if(this.then_ == 0.0)
+ render_event.elapsedTime = 0.0;
+ else
+ render_event.elapsedTime = now - this.then_;
+
+ if (this.render_callback) {
+ for (var stat in this.render_stats_) {
+ render_event[stat] = this.render_stats_[stat];
+ }
+ this.render_callback(render_event);
+ }
+ this.then_ = now;
+ this.renderTree(this.renderGraphRoot);
};
+/**
+ * An object for various statistics that are gather during the render tree
+ * tranversal.
+ *
+ * @type {Object}
+ */
+o3d.Client.prototype.render_stats = {}
+
/**
* Renders a render graph.
@@ -407,6 +456,16 @@ o3d.Client.prototype.render = function() {
*/
o3d.Client.prototype.renderTree =
function(render_node) {
+
+ this.render_stats_ = {
+ drawElementsCulled: 0,
+ drawElementsProcessed: 0,
+ drawElementsRendered: 0,
+ primitivesRendered: 0,
+ transformsCulled: 0,
+ transformsProcessed: 0
+ };
+
render_node.render();
};
@@ -420,7 +479,6 @@ o3d.Client.prototype.renderTree =
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,
@@ -437,7 +495,7 @@ o3d.Client.prototype.getDisplayModes = [];
*/
o3d.Client.prototype.setFullscreenClickRegion =
function(x, y, width, height, mode_id) {
-
+ o3d.notImplemented();
};
@@ -537,9 +595,12 @@ o3d.Client.prototype.initWithCanvas = function(canvas) {
}
this.gl = gl;
+ this.root.gl = gl;
+ this.renderGraphRoot.gl = gl;
gl.client = this;
- this.updateDisplayInfo_();
+ gl.displayInfo = {width: canvas.width,
+ height: canvas.height};
};
@@ -890,11 +951,3 @@ o3d.Client.prototype.clientId = 0;
o3d.Client.prototype.canvas = null;
-/**
- * Updates the display information attached to the GL.
- * @private
- */
-o3d.Client.prototype.updateDisplayInfo_ = function() {
- this.gl.displayInfo = {width: this.width,
- height: this.height};
-};
diff --git a/o3d/samples/o3d-webgl/draw_list.js b/o3d/samples/o3d-webgl/draw_list.js
index 46ea458..875f237 100644
--- a/o3d/samples/o3d-webgl/draw_list.js
+++ b/o3d/samples/o3d-webgl/draw_list.js
@@ -60,7 +60,7 @@ o3d.DrawList.SortMethod = goog.typedef;
* BY_PERFORMANCE
* BY_Z_ORDER
* BY_PRIORITY
- *
+ *
* Method to sort DrawList by.
*/
o3d.DrawList.BY_PERFORMANCE = 0;
@@ -77,6 +77,8 @@ o3d.DrawList.prototype.render = function() {
var drawElementInfo = this.list_[i];
var world = drawElementInfo.world;
var view = drawElementInfo.view;
+ var viewProjection = drawElementInfo.viewProjection;
+ var worldViewProjection = drawElementInfo.worldViewProjection;
var projection = drawElementInfo.projection;
var transform = drawElementInfo.transform;
var drawElement = drawElementInfo.drawElement;
@@ -88,6 +90,8 @@ o3d.DrawList.prototype.render = function() {
o3d.Param.SAS.setWorld(world);
o3d.Param.SAS.setView(view);
o3d.Param.SAS.setProjection(projection);
+ o3d.Param.SAS.setViewProjection(viewProjection);
+ o3d.Param.SAS.setWorldViewProjection(worldViewProjection);
var paramObjects = [
transform,
diff --git a/o3d/samples/o3d-webgl/element.js b/o3d/samples/o3d-webgl/element.js
index 92558b4..d190780 100644
--- a/o3d/samples/o3d-webgl/element.js
+++ b/o3d/samples/o3d-webgl/element.js
@@ -32,7 +32,7 @@
/**
* 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.
@@ -145,7 +145,7 @@ o3d.Element.prototype.__defineGetter__('owner',
* 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
@@ -155,7 +155,7 @@ o3d.Element.prototype.__defineGetter__('owner',
*/
o3d.Element.prototype.createDrawElement =
function(pack, material) {
- drawElement = new o3d.DrawElement();
+ drawElement = pack.createObject('DrawElement');
drawElement.owner = this;
drawElement.material = material || this.material;
this.drawElements.push(drawElement);
diff --git a/o3d/samples/o3d-webgl/field.js b/o3d/samples/o3d-webgl/field.js
index 23058bf..1ae89e4 100644
--- a/o3d/samples/o3d-webgl/field.js
+++ b/o3d/samples/o3d-webgl/field.js
@@ -72,21 +72,22 @@ 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.
+ * @param {!Array.<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 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] =
@@ -100,14 +101,21 @@ o3d.Field.prototype.setAt =
/**
* 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.
- * @return {number} The values of the field.
+ * @return {!Array.<number>} The values of the field.
*/
o3d.Field.prototype.getAt =
function(start_index, num_elements) {
- o3d.notImplemented();
+ var values = [];
+ for (var i = 0; i < num_elements; ++i) {
+ for (var c = 0; c < this.numComponents; ++c) {
+ values.push(this.buffer.array_[(start_index + i) *
+ this.buffer.totalComponents + this.offset_ + c]);
+ }
+ }
+ return values;
};
diff --git a/o3d/samples/o3d-webgl/pack.js b/o3d/samples/o3d-webgl/pack.js
index 1c211ad..a5336ea 100644
--- a/o3d/samples/o3d-webgl/pack.js
+++ b/o3d/samples/o3d-webgl/pack.js
@@ -73,6 +73,7 @@ o3d.inherit('Pack', 'NamedObject');
*/
o3d.Pack.prototype.destroy = function() {
this.objects_ = [];
+ this.client.removePack(this);
};
diff --git a/o3d/samples/o3d-webgl/param.js b/o3d/samples/o3d-webgl/param.js
index 4a5ec63..1792eb8 100644
--- a/o3d/samples/o3d-webgl/param.js
+++ b/o3d/samples/o3d-webgl/param.js
@@ -589,7 +589,7 @@ o3d.inherit('ViewInverseTransposeParamMatrix4', 'CompositionParamMatrix4');
*/
o3d.ViewProjectionParamMatrix4 = function() {
o3d.CompositionParamMatrix4.call(this);
- this.matrix_names_ = ['projection', 'view'];
+ this.matrix_names_ = ['viewProjection'];
};
o3d.inherit('ViewProjectionParamMatrix4', 'CompositionParamMatrix4');
@@ -599,7 +599,7 @@ o3d.inherit('ViewProjectionParamMatrix4', 'CompositionParamMatrix4');
*/
o3d.ViewProjectionInverseParamMatrix4 = function() {
o3d.CompositionParamMatrix4.call(this);
- this.matrix_names_ = ['projection', 'view'];
+ this.matrix_names_ = ['viewProjection'];
this.inverse_ = true;
};
o3d.inherit('ViewProjectionInverseParamMatrix4', 'CompositionParamMatrix4');
@@ -610,7 +610,7 @@ o3d.inherit('ViewProjectionInverseParamMatrix4', 'CompositionParamMatrix4');
*/
o3d.ViewProjectionTransposeParamMatrix4 = function() {
o3d.CompositionParamMatrix4.call(this);
- this.matrix_names_ = ['projection', 'view'];
+ this.matrix_names_ = ['viewProjection'];
this.transpose_ = true;
};
o3d.inherit('ViewProjectionTransposeParamMatrix4', 'CompositionParamMatrix4');
@@ -621,7 +621,7 @@ o3d.inherit('ViewProjectionTransposeParamMatrix4', 'CompositionParamMatrix4');
*/
o3d.ViewProjectionInverseTransposeParamMatrix4 = function() {
o3d.CompositionParamMatrix4.call(this);
- this.matrix_names_ = ['projection', 'view'];
+ this.matrix_names_ = ['viewProjection'];
this.inverse_ = true;
this.transpose_ = true;
};
@@ -725,7 +725,7 @@ o3d.inherit('WorldViewInverseTransposeParamMatrix4',
*/
o3d.WorldViewProjectionParamMatrix4 = function() {
o3d.CompositionParamMatrix4.call(this);
- this.matrix_names_ = ['projection', 'view', 'world'];
+ this.matrix_names_ = ['worldViewProjection'];
};
o3d.inherit('WorldViewProjectionParamMatrix4',
'CompositionParamMatrix4');
@@ -736,7 +736,7 @@ o3d.inherit('WorldViewProjectionParamMatrix4',
*/
o3d.WorldViewProjectionInverseParamMatrix4 = function() {
o3d.CompositionParamMatrix4.call(this);
- this.matrix_names_ = ['projection', 'view', 'world'];
+ this.matrix_names_ = ['worldViewProjection'];
this.inverse_ = true;
};
o3d.inherit('WorldViewProjectionInverseParamMatrix4',
@@ -748,7 +748,7 @@ o3d.inherit('WorldViewProjectionInverseParamMatrix4',
*/
o3d.WorldViewProjectionTransposeParamMatrix4 = function() {
o3d.CompositionParamMatrix4.call(this);
- this.matrix_names_ = ['projection', 'view', 'world'];
+ this.matrix_names_ = ['worldViewProjection'];
this.transpose_ = true;
};
o3d.inherit('WorldViewProjectionTransposeParamMatrix4',
@@ -760,7 +760,7 @@ o3d.inherit('WorldViewProjectionTransposeParamMatrix4',
*/
o3d.WorldViewProjectionInverseTransposeParamMatrix4 = function() {
o3d.CompositionParamMatrix4.call(this);
- this.matrix_names_ = ['projection', 'view', 'world'];
+ this.matrix_names_ = ['worldViewProjection'];
this.inverse_ = true;
this.transpose_ = true;
};
@@ -911,16 +911,19 @@ o3d.Param.SAS.setView = function(view) {
* SAS parameters.
*/
o3d.Param.SAS.setProjection = function(projection) {
- // TODO(petersont): this wasn't being used. Need to adjust all of
- // the handwritten GLSL shaders to incorporate the modification of
- // gl_Position based on dx_clipping.
- /*
- 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;
};
+/**
+ * Sets the viewProjection matrix.
+ */
+o3d.Param.SAS.setViewProjection = function(viewProjection) {
+ this['viewProjection'] = viewProjection;
+};
+/**
+ * Sets the worldViewProjection matrix.
+ */
+o3d.Param.SAS.setWorldViewProjection = function(worldViewProjection) {
+ this['worldViewProjection'] = worldViewProjection;
+};
diff --git a/o3d/samples/o3d-webgl/primitive.js b/o3d/samples/o3d-webgl/primitive.js
index 5d60f4b..fe31ecb 100644
--- a/o3d/samples/o3d-webgl/primitive.js
+++ b/o3d/samples/o3d-webgl/primitive.js
@@ -33,7 +33,7 @@
/**
* 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
@@ -138,6 +138,8 @@ o3d.Primitive.prototype.render = function() {
}
}
+ this.gl.client.render_stats_['primitivesRendered'] += this.numberPrimitives;
+
// 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,
@@ -149,3 +151,39 @@ o3d.Primitive.prototype.render = function() {
this.gl.disableVertexAttribArray(enabled_attribs[i]);
}
};
+
+
+/**
+ * Computes the bounding box in same coordinate system as the specified
+ * POSITION stream.
+ * @param {number} position_stream_index Index of POSITION stream.
+ * @return {!o3d.BoundingBox} The boundingbox for this element in local space.
+ */
+o3d.Primitive.prototype.getBoundingBox =
+ function(position_stream_index) {
+ var streamBank = this.streamBank;
+ var indexBuffer = this.indexBuffer;
+ var stream =
+ this.streamBank.vertexStreams[o3d.Stream.POSITION][position_stream_index];
+
+ var points = [];
+ var field = stream.field;
+ var buffer = field.buffer;
+ var numPoints = buffer.array_.length / buffer.totalComponents;
+
+ var elements = field.getAt(0, numPoints);
+
+ for (var index = 0; index < numPoints; ++index) {
+ var p = [0, 0, 0];
+ for (var i = 0; i < field.numComponents; ++i) {
+ p[i] = elements[field.numComponents * index + i];
+ }
+ points.push(p);
+ }
+
+ o3d.BoundingBox.fitBoxToPoints_(points, this.boundingBox);
+ return this.boundingBox;
+};
+
+
+
diff --git a/o3d/samples/o3d-webgl/ray_intersection_info.js b/o3d/samples/o3d-webgl/ray_intersection_info.js
index db37c4d..ae9f22e 100644
--- a/o3d/samples/o3d-webgl/ray_intersection_info.js
+++ b/o3d/samples/o3d-webgl/ray_intersection_info.js
@@ -51,6 +51,12 @@ o3d.inherit('RayIntersectionInfo', 'NamedObject');
o3d.RayIntersectionInfo.prototype.valid = false;
+/**
+ * True if the origin of the ray is found to be inside the box.
+ * @type {boolean}
+ */
+o3d.RayIntersectionInfo.prototype.inside = false;
+
/**
* True if this ray intersection intersected something.
diff --git a/o3d/samples/o3d-webgl/shape.js b/o3d/samples/o3d-webgl/shape.js
index caf8cf6..e58f1f4 100644
--- a/o3d/samples/o3d-webgl/shape.js
+++ b/o3d/samples/o3d-webgl/shape.js
@@ -115,28 +115,53 @@ o3d.Shape.prototype.writeToDrawLists =
// For each element look at the DrawElements for that element.
for (var j = 0; j < element.drawElements.length; ++j) {
+ this.gl.client.render_stats_['drawElementsProcessed']++;
var drawElement = element.drawElements[j];
var material = drawElement.material || drawElement.owner.material;
var materialDrawList = material.drawList;
+ var rendered = false;
// Iterate through the drawlists we might write to.
for (var k = 0; k < drawListInfos.length; ++k) {
var drawListInfo = drawListInfos[k];
var list = drawListInfo.list;
- var context = drawListInfo.context;
// If any of those drawlists matches the material on the drawElement,
// add the drawElement to the list.
if (materialDrawList == list) {
+ var context = drawListInfo.context;
+ var view = context.view;
+ var projection = context.projection;
+
+ var worldViewProjection = [[], [], [], []];
+ var viewProjection = [[], [], [], []];
+ o3d.Transform.compose(projection, view, viewProjection);
+ o3d.Transform.compose(viewProjection, world, worldViewProjection);
+
+ if (element.cull && element.boundingBox) {
+ if (!element.boundingBox.inFrustum(worldViewProjection)) {
+ continue;
+ }
+ }
+
+ rendered = true;
list.list_.push({
- view: context.view,
- projection: context.projection,
+ view: view,
+ projection: projection,
world: world,
+ viewProjection: viewProjection,
+ worldViewProjection: worldViewProjection,
transform: transform,
drawElement: drawElement
});
}
}
+
+ if (rendered) {
+ this.gl.client.render_stats_['drawElementsRendered']++;
+ } else {
+ this.gl.client.render_stats_['drawElementsCulled']++;
+ }
}
}
};
diff --git a/o3d/samples/o3d-webgl/transform.js b/o3d/samples/o3d-webgl/transform.js
index 1873c5d..929abfd 100644
--- a/o3d/samples/o3d-webgl/transform.js
+++ b/o3d/samples/o3d-webgl/transform.js
@@ -225,7 +225,15 @@ o3d.Transform.prototype.getTransformsByNameInTree =
*/
o3d.Transform.prototype.getUpdatedWorldMatrix =
function() {
- o3d.notImplemented();
+ var parentWorldMatrix;
+ if (!this.parent) {
+ parentWorldMatrix =
+ [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]];
+ } else {
+ parentWorldMatrix = this.parent.getUpdatedWorldMatrix();
+ }
+ o3d.Transform.compose(parentWorldMatrix, this.localMatrix, this.worldMatrix);
+ return this.worldMatrix;
};
@@ -591,6 +599,37 @@ o3d.Transform.prototype.rotateX =
};
+
+/**
+ * Takes a 4-by-4 matrix and a vector with 3 entries,
+ * interprets the vector as a point, transforms that point by the matrix, and
+ * returns the result as a vector with 3 entries.
+ * @param {!o3djs.math.Matrix4} m The matrix.
+ * @param {!o3djs.math.Vector3} v The point.
+ * @return {!o3djs.math.Vector3} The transformed point.
+ */
+o3d.Transform.transformPoint = function(m, v) {
+ var v0 = v[0];
+ var v1 = v[1];
+ var v2 = v[2];
+
+ if (!m) {
+ debugger;
+ }
+
+ var m0 = m[0];
+ var m1 = m[1];
+ var m2 = m[2];
+ var m3 = m[3];
+
+ var d = v0 * m0[3] + v1 * m1[3] + v2 * m2[3] + m3[3];
+ return [(v0 * m0[0] + v1 * m1[0] + v2 * m2[0] + m3[0]) / d,
+ (v0 * m0[1] + v1 * m1[1] + v2 * m2[1] + m3[1]) / d,
+ (v0 * m0[2] + v1 * m1[2] + v2 * m2[2] + m3[2]) / d];
+};
+
+
+
/**
* 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
@@ -926,7 +965,9 @@ o3d.Transform.flattenMatrix4 = function(m) {
*/
o3d.Transform.prototype.traverse =
function(drawListInfos, opt_parentWorldMatrix) {
- if (!this.visible) {
+
+ this.gl.client.render_stats_['transformsProcessed']++;
+ if (drawListInfos.length == 0 || !this.visible) {
return;
}
opt_parentWorldMatrix =
@@ -936,15 +977,42 @@ o3d.Transform.prototype.traverse =
o3d.Transform.compose(
opt_parentWorldMatrix, this.localMatrix, this.worldMatrix);
+ var remainingDrawListInfos = [];
+
+ if (this.cull) {
+ if (this.boundingBox) {
+ for (var i = 0; i < drawListInfos.length; ++i) {
+ var drawListInfo = drawListInfos[i];
+
+ var worldViewProjection = [[], [], [], []];
+ o3d.Transform.compose(drawListInfo.context.view,
+ this.worldMatrix, worldViewProjection);
+ o3d.Transform.compose(drawListInfo.context.projection,
+ worldViewProjection, worldViewProjection);
+
+ if (this.boundingBox.inFrustum(worldViewProjection)) {
+ remainingDrawListInfos.push(drawListInfo);
+ }
+ }
+ }
+ } else {
+ remainingDrawListInfos = drawListInfos;
+ }
+
+ if (remainingDrawListInfos.length == 0) {
+ this.gl.client.render_stats_['transformsCulled']++;
+ return;
+ }
+
var children = this.children;
var shapes = this.shapes;
for (var i = 0; i < shapes.length; ++i) {
- shapes[i].writeToDrawLists(drawListInfos, this.worldMatrix, this);
+ shapes[i].writeToDrawLists(remainingDrawListInfos, this.worldMatrix, this);
}
for (var i = 0; i < children.length; ++i) {
- children[i].traverse(drawListInfos, this.worldMatrix);
+ children[i].traverse(remainingDrawListInfos, this.worldMatrix);
}
};
diff --git a/o3d/samples/o3djs/webgl.js b/o3d/samples/o3djs/webgl.js
index d9c53f3..c0594af 100644
--- a/o3d/samples/o3djs/webgl.js
+++ b/o3d/samples/o3djs/webgl.js
@@ -140,7 +140,7 @@ o3djs.webgl.addDebuggingWrapper = function(context) {
/**
* Creates a canvas under the given parent element and an o3d.Client
* under that.
- *
+ *
* @ param {!Element} element The element under which to insert the client.
* @ param {string} opt_features Features to turn on.
* @ param {boolean} opt_debug Whether gl debugging features should be
@@ -161,17 +161,20 @@ o3djs.webgl.createClient = function(element, opt_features, opt_debug) {
canvas = document.createElement('canvas');
canvas.style.width = "100%";
canvas.style.height = "100%";
+
+ var client = new o3d.Client;
+
var resizeHandler = function() {
var width = Math.max(1, canvas.clientWidth);
var height = Math.max(1, canvas.clientHeight);
canvas.width = width;
canvas.height = height;
canvas.sizeInitialized_ = true;
+ client.gl.displayInfo = {width: canvas.width, height: canvas.height};
};
window.addEventListener('resize', resizeHandler, false);
setTimeout(resizeHandler, 0);
- var client = new o3d.Client;
client.initWithCanvas(canvas);
canvas.client = client;
canvas.o3d = o3d;