OLD | NEW |
(Empty) | |
| 1 <!-- |
| 2 Copyright 2009, Google Inc. |
| 3 All rights reserved. |
| 4 |
| 5 Redistribution and use in source and binary forms, with or without |
| 6 modification, are permitted provided that the following conditions are |
| 7 met: |
| 8 |
| 9 * Redistributions of source code must retain the above copyright |
| 10 notice, this list of conditions and the following disclaimer. |
| 11 * Redistributions in binary form must reproduce the above |
| 12 copyright notice, this list of conditions and the following disclaimer |
| 13 in the documentation and/or other materials provided with the |
| 14 distribution. |
| 15 * Neither the name of Google Inc. nor the names of its |
| 16 contributors may be used to endorse or promote products derived from |
| 17 this software without specific prior written permission. |
| 18 |
| 19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 20 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 23 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 24 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 25 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 26 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 27 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 29 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 --> |
| 31 |
| 32 <!-- |
| 33 O3D Culling. |
| 34 |
| 35 Make sure things off screen get culled. |
| 36 |
| 37 By default nothing is culled. If you want object to be culled you must setup |
| 38 bounding boxes in the transform graph that fit the needs of your application |
| 39 and then turn on culling for those objects you want culled. |
| 40 --> |
| 41 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" |
| 42 "http://www.w3.org/TR/html4/loose.dtd"> |
| 43 <html> |
| 44 <head> |
| 45 <meta http-equiv="content-type" content="text/html; charset=UTF-8"> |
| 46 <title> |
| 47 Culling. |
| 48 </title> |
| 49 <script type="text/javascript" src="../o3d-webgl/base.js"></script> |
| 50 <script type="text/javascript" src="../o3djs/base.js"></script> |
| 51 <script type="text/javascript" id="o3dscript"> |
| 52 o3djs.base.o3d = o3d; |
| 53 o3djs.require('o3djs.webgl'); |
| 54 o3djs.require('o3djs.util'); |
| 55 o3djs.require('o3djs.math'); |
| 56 o3djs.require('o3djs.rendergraph'); |
| 57 o3djs.require('o3djs.primitives'); |
| 58 o3djs.require('o3djs.material'); |
| 59 |
| 60 // global variables |
| 61 var g_timeMult = 1.0; |
| 62 var g_framesRendered = 0; |
| 63 var g_o3d; |
| 64 var g_math; |
| 65 var g_client; |
| 66 var g_viewInfo; |
| 67 var g_pack; |
| 68 var g_totalTransformsElement; |
| 69 var g_transformsProcessedElement; |
| 70 var g_transformsCulledElement; |
| 71 var g_totalDrawElementsElement; |
| 72 var g_totalDrawableThingsElement; |
| 73 var g_drawElementsProcessedElement; |
| 74 var g_drawElementsCulledElement; |
| 75 var g_drawElementsRenderedElement; |
| 76 var g_primitivesRenderedElement; |
| 77 var g_groupTransforms = []; |
| 78 var GROUPS_ACROSS = 2; |
| 79 var UNITS_ACROSS_GROUP = 2; |
| 80 var TOTAL_ACROSS = GROUPS_ACROSS * UNITS_ACROSS_GROUP; |
| 81 var HALF_WIDTH = TOTAL_ACROSS * 0.0; |
| 82 var UNIT_SPACING = 200; |
| 83 |
| 84 function createInstances(pack, shape) { |
| 85 // Make a grid of transforms and put a shape instance on each one. |
| 86 for (var g = 0; g < GROUPS_ACROSS; g++) { |
| 87 for (var h = 0; h < GROUPS_ACROSS; h++) { |
| 88 for (var i = 0; i < GROUPS_ACROSS; i++) { |
| 89 var groupTransform = pack.createObject('Transform'); |
| 90 g_groupTransforms[g_groupTransforms.length] = groupTransform; |
| 91 groupTransform.parent = g_client.root; |
| 92 // Turn on culling for this transform. |
| 93 groupTransform.cull = true; |
| 94 var boundingBox = new g_o3d.BoundingBox([0, 0, 0], |
| 95 [0, 0, 0]); |
| 96 groupTransform.translate( |
| 97 (g * UNITS_ACROSS_GROUP - HALF_WIDTH) * UNIT_SPACING, |
| 98 (h * UNITS_ACROSS_GROUP - HALF_WIDTH) * UNIT_SPACING, |
| 99 (i * UNITS_ACROSS_GROUP - HALF_WIDTH) * UNIT_SPACING); |
| 100 |
| 101 for (var x = 0; x < UNITS_ACROSS_GROUP; x++) { |
| 102 for (var y = 0; y < UNITS_ACROSS_GROUP; y++) { |
| 103 for (var z = 0; z < UNITS_ACROSS_GROUP; z++) { |
| 104 var transform = pack.createObject('Transform'); |
| 105 transform.parent = groupTransform; |
| 106 // Turn on culling for this transform. |
| 107 transform.cull = true; |
| 108 transform.addShape(shape); |
| 109 // Add up the bounding boxes of all the elements. |
| 110 var elements = shape.elements; |
| 111 var box = elements[0].boundingBox; |
| 112 for (var ee = 1; ee < elements.length; ee++) { |
| 113 box = box.add(elements[ee].boundingBox); |
| 114 } |
| 115 |
| 116 // Set the transform to have a bounding box that is the sum |
| 117 // of all the elements under it. |
| 118 transform.boundingBox = box; |
| 119 transform.translate( |
| 120 (x - UNITS_ACROSS_GROUP * 0.5) * UNIT_SPACING, |
| 121 (y - UNITS_ACROSS_GROUP * 0.5) * UNIT_SPACING, |
| 122 (z - UNITS_ACROSS_GROUP * 0.5) * UNIT_SPACING); |
| 123 transform.createParam('diffuse', 'ParamFloat4').value = [ |
| 124 (g * UNITS_ACROSS_GROUP + x) * (1 / TOTAL_ACROSS), |
| 125 (h * UNITS_ACROSS_GROUP + y) * (1 / TOTAL_ACROSS), |
| 126 (i * UNITS_ACROSS_GROUP + z) * (1 / TOTAL_ACROSS), |
| 127 1]; |
| 128 // Add the box for this bounding box to the box for the group. |
| 129 var box = transform.boundingBox.mul(transform.localMatrix); |
| 130 boundingBox = boundingBox.add(box); |
| 131 } |
| 132 } |
| 133 } |
| 134 // Set the bounding box for the group transform to encompass all |
| 135 // the transforms below it. |
| 136 groupTransform.boundingBox = boundingBox; |
| 137 } |
| 138 } |
| 139 } |
| 140 } |
| 141 |
| 142 /** |
| 143 * Creates the client area. |
| 144 */ |
| 145 function init() { |
| 146 // These are here so that they are visible to both the browser (so |
| 147 // selenium sees them) and the embedded V8 engine. |
| 148 window.g_clock = 0; |
| 149 window.g_finished = false; // for selenium testing. |
| 150 |
| 151 o3djs.webgl.makeClients(initStep2); |
| 152 } |
| 153 |
| 154 /** |
| 155 * Initializes O3D and creates one shape. |
| 156 * @param {Array} clientElements Array of o3d object elements. |
| 157 */ |
| 158 function initStep2(clientElements) { |
| 159 // Initializes global variables and libraries. |
| 160 var o3dElement = clientElements[0]; |
| 161 g_o3d = o3dElement.o3d; |
| 162 g_math = o3djs.math; |
| 163 |
| 164 // Set window.g_client as well. Otherwise when the sample runs in |
| 165 // V8, selenium won't be able to find this variable (it can only see |
| 166 // the browser environment). |
| 167 window.g_client = g_client = o3dElement.client; |
| 168 |
| 169 g_totalDrawableThingsElement = |
| 170 o3djs.util.getElementById('totalDrawableThings'); |
| 171 g_totalTransformsElement = |
| 172 o3djs.util.getElementById('totalTransforms'); |
| 173 g_transformsProcessedElement = |
| 174 o3djs.util.getElementById('transformsProcessed'); |
| 175 g_transformsCulledElement = |
| 176 o3djs.util.getElementById('transformsCulled'); |
| 177 g_totalDrawElementsElement = |
| 178 o3djs.util.getElementById('totalDrawElements'); |
| 179 g_drawElementsProcessedElement = |
| 180 o3djs.util.getElementById('drawElementsProcessed'); |
| 181 g_drawElementsCulledElement = |
| 182 o3djs.util.getElementById('drawElementsCulled'); |
| 183 g_drawElementsRenderedElement = |
| 184 o3djs.util.getElementById('drawElementsRendered'); |
| 185 g_primitivesRenderedElement = |
| 186 o3djs.util.getElementById('primitivesRendered'); |
| 187 |
| 188 // Creates a pack to manage our resources/assets |
| 189 g_pack = g_client.createPack(); |
| 190 |
| 191 g_viewInfo = o3djs.rendergraph.createBasicView( |
| 192 g_pack, |
| 193 g_client.root, |
| 194 g_client.renderGraphRoot); |
| 195 |
| 196 // Create our projection matrix, with a vertical field of view of 45 |
| 197 // degrees a near clipping plane of 0.1 and far clipping plane of 10000. |
| 198 g_viewInfo.drawContext.projection = g_math.matrix4.perspective( |
| 199 g_math.degToRad(45), |
| 200 g_client.width / g_client.height, |
| 201 0.1, |
| 202 10000); |
| 203 |
| 204 // Create and load the effect. |
| 205 var material = o3djs.material.createBasicMaterial( |
| 206 g_pack, |
| 207 g_viewInfo, |
| 208 [1, 1, 1, 1]); |
| 209 |
| 210 // Create 2 spheres. |
| 211 var shape1 = o3djs.primitives.createSphere( |
| 212 g_pack, |
| 213 material, |
| 214 40, |
| 215 20, |
| 216 20, |
| 217 g_math.matrix4.translation([-50, 0, 0])); |
| 218 |
| 219 var shape2 = o3djs.primitives.createSphere( |
| 220 g_pack, |
| 221 material, |
| 222 20, |
| 223 20, |
| 224 20, |
| 225 g_math.matrix4.translation([50, 0, 0])); |
| 226 |
| 227 // Create a shape and move the 2 sphere primitives to the same shape. |
| 228 // This is done to show that each of the primitives under the shape |
| 229 // will get culled separately. |
| 230 var shape = g_pack.createObject('Shape'); |
| 231 shape1.elements[0].owner = shape; |
| 232 shape2.elements[0].owner = shape; |
| 233 // delete the old shapes. |
| 234 g_pack.removeObject(shape1); |
| 235 g_pack.removeObject(shape2); |
| 236 var elements = shape.elements; |
| 237 // Turn on culling for the two sphere elements. |
| 238 elements[0].cull = true; |
| 239 elements[1].cull = true; |
| 240 |
| 241 createInstances(g_pack, shape); |
| 242 |
| 243 g_totalDrawableThingsElement.innerHTML = |
| 244 GROUPS_ACROSS * UNITS_ACROSS_GROUP * |
| 245 GROUPS_ACROSS * UNITS_ACROSS_GROUP * |
| 246 GROUPS_ACROSS * UNITS_ACROSS_GROUP; |
| 247 |
| 248 g_totalDrawElementsElement.innerHTML = g_client.getObjectsByClassName( |
| 249 'o3d.DrawElement').length; |
| 250 g_totalTransformsElement.innerHTML = g_client.getObjectsByClassName( |
| 251 'o3d.Transform').length; |
| 252 |
| 253 // Setup an onrender callback for animation. |
| 254 g_client.setRenderCallback(onrender); |
| 255 |
| 256 window.g_finished = true; // for selenium testing. |
| 257 } |
| 258 |
| 259 var g_flag = false; |
| 260 |
| 261 // spin the camera. |
| 262 function onrender(renderEvent) { |
| 263 g_framesRendered++; |
| 264 // Get the number of seconds since the last render. |
| 265 var elapsedTime = renderEvent.elapsedTime; |
| 266 |
| 267 // Update g_clock in the browser and cache a V8 copy that can be |
| 268 // accessed efficiently. g_clock must be in the browser for selenium. |
| 269 var clock = window.g_clock + elapsedTime * window.g_timeMult; |
| 270 window.g_clock = clock; |
| 271 |
| 272 var x = Math.sin(clock * 0.1) * 300; |
| 273 var z = Math.cos(clock * 0.1) * 300; |
| 274 var y = Math.sin(clock * 0.2) * 300; |
| 275 |
| 276 g_viewInfo.drawContext.view = g_math.matrix4.lookAt( |
| 277 [x, y, z], |
| 278 [0, 0, 0], |
| 279 [0, 1, 0]); |
| 280 |
| 281 g_transformsProcessedElement.innerHTML = renderEvent.transformsProcessed; |
| 282 g_transformsCulledElement.innerHTML = renderEvent.transformsCulled; |
| 283 g_drawElementsProcessedElement.innerHTML = renderEvent.drawElementsProcessed; |
| 284 g_drawElementsCulledElement.innerHTML = renderEvent.drawElementsCulled; |
| 285 g_drawElementsRenderedElement.innerHTML = renderEvent.drawElementsRendered; |
| 286 g_primitivesRenderedElement.innerHTML = renderEvent.primitivesRendered; |
| 287 } |
| 288 |
| 289 /** |
| 290 * Remove any callbacks so they don't get called after the page has unloaded. |
| 291 */ |
| 292 function unload() { |
| 293 if (g_client) { |
| 294 g_client.cleanup(); |
| 295 } |
| 296 } |
| 297 |
| 298 </script> |
| 299 </head> |
| 300 <body onload="init()" onunload="unload()"> |
| 301 <h1>Culling</h1> |
| 302 Objects off screen should get culled. |
| 303 <br/> |
| 304 <!-- Start of O3D client area --> |
| 305 <div id="o3d" style="width: 800px; height: 600px;"></div> |
| 306 <!-- End of O3D client area --> |
| 307 |
| 308 <table> |
| 309 <tr><td>Total Drawable Things:</td><td><span id="totalDrawableThings">-</span></
td></tr> |
| 310 <tr><td>Total Transforms:</td><td><span id="totalTransforms">-</span></td></tr> |
| 311 <tr><td>Transforms Processed:</td><td><span id="transformsProcessed">-</span></t
d></tr> |
| 312 <tr><td>Transforms Culled:</td><td><span id="transformsCulled">-</span></td></tr
> |
| 313 <tr><td>Total DrawElements:</td><td><span id="totalDrawElements">-</span></td></
tr> |
| 314 <tr><td>DrawElements Processed:</td><td><span id="drawElementsProcessed">-</span
></td></tr> |
| 315 <tr><td>DrawElements Culled:</td><td><span id="drawElementsCulled">-</span></td>
</tr> |
| 316 <tr><td>DrawElements Rendered:</td><td><span id="drawElementsRendered">-</span><
/td></tr> |
| 317 <tr><td>Primitives Rendered:</td><td><span id="primitivesRendered">-</span></td>
</tr> |
| 318 </table> |
| 319 </body> |
| 320 </html> |
OLD | NEW |