topical media & game development

talk show tell print

graphic-o3d-samples-o3djs-shape.js / js



  /*
   * Copyright 2009, Google Inc.
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions are
   * met:
   *
   *     * Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *     * Redistributions in binary form must reproduce the above
   * copyright notice, this list of conditions and the following disclaimer
   * in the documentation and/or other materials provided with the
   * distribution.
   *     * Neither the name of Google Inc. nor the names of its
   * contributors may be used to endorse or promote products derived from
   * this software without specific prior written permission.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   */
  
  
@fileoverview This file contains various functions for helping setup shapes for o3d. It puts them in the "shape" module on the o3djs object. Note: This library is only a sample. It is not meant to be some official library. It is provided only as example code.

  
  
  o3djs.provide('o3djs.shape');
  
  
A Module for shapes. @namespace

  
  o3djs.shape = o3djs.shape || {};
  
  
Prepares all the shapes in the given pack by setting their drawList, boundingBox and zSortPoint.
parameter: {!o3d.Pack} pack Pack to manage created objects.

  
  o3djs.shape.prepareShapes = function(pack) {
    var shapes = pack.getObjectsByClassName('o3d.Shape');
    for (var ss = 0; ss < shapes.length; ++ss) {
      var shape = shapes[ss];
      shape.createDrawElements(pack, null);
      var elements = shape.elements;
      for (var ee = 0; ee < elements.length; ++ee) {
        var element = elements[ee];
        var boundingBox = element.getBoundingBox(0);
        var minExtent = boundingBox.minExtent;
        var maxExtent = boundingBox.maxExtent;
        element.boundingBox = boundingBox;
        element.cull = true;
        element.zSortPoint = o3djs.math.div(
            o3djs.math.add(minExtent, maxExtent), 2);
  
        // This is very application specific but if it's a primitive
        // and if it uses a collada material the material builder
        // assumes 1 TEXCOORD stream per texture. In other words if you have
        // both a specular texture AND a diffuse texture the builder assumes
        // you have 2 TEXCOORD streams. This assumption is often false.
        //
        // To work around this we check how many streams the material
        // expects and if there are not enough UVs streams we duplicate the
        // last TEXCOORD stream until there are, making a BIG assumption that
        // that will work.
        //
        // The problem is maybe you have 4 textures and each of them share
        // texture coordinates. There is information in the collada file about
        // what stream to connect each texture to.
        //
        // TODO We should store that info. The conditioner should either
        // make streams that way or pass on the info so we can do it here.
        if (element.isAClassName('o3d.Primitive')) {
          var material = element.material;
          var streamBank = element.streamBank;
          var lightingType = o3djs.effect.getColladaLightingType(material);
          if (lightingType) {
            var numTexCoordStreamsNeeded =
                o3djs.effect.getNumTexCoordStreamsNeeded(material);
            // Count the number of TEXCOORD streams the streamBank has.
            var streams = streamBank.vertexStreams;
            var lastTexCoordStream = null;
            var numTexCoordStreams = 0;
            for (var ii = 0; ii < streams.length; ++ii) {
              var stream = streams[ii];
              if (stream.semantic == o3djs.base.o3d.Stream.TEXCOORD) {
                lastTexCoordStream = stream;
                ++numTexCoordStreams;
              }
            }
            // Add any missing TEXCOORD streams. It might be more efficient for
            // the GPU to create an effect that doesn't need the extra streams
            // but this is a more generic solution because it means we can reuse
            // the same effect.
            for (var ii = numTexCoordStreams;
                 ii < numTexCoordStreamsNeeded;
                 ++ii) {
              streamBank.setVertexStream(
                  lastTexCoordStream.semantic,
                  lastTexCoordStream.semanticIndex + ii - numTexCoordStreams + 1,
                  lastTexCoordStream.field,
                  lastTexCoordStream.startIndex);
            }
          }
        }
      }
    }
  };
  
  
Attempts to delete the parts of a shape that were created by duplicateShape as well as any drawElements attached to it.
parameter: {!o3d.Shape} shape shape to delete.
parameter: {!o3d.Pack} pack Pack to release objects from.

  
  o3djs.shape.deleteDuplicateShape = function(shape, pack) {
     var elements = shape.elements;
     for (var ee = 0; ee < elements.length; ee++) {
       var element = elements[ee];
       var drawElements = element.drawElements;
       for (var dd = 0; dd < drawElements.length; dd++) {
         var drawElement = drawElements[dd];
         pack.removeObject(drawElement);
       }
       pack.removeObject(element);
     }
     pack.removeObject(shape);
  };
  
  
Copies a shape's elements and streams but not buffers so the two will share vertex and index buffers.
parameter: {!o3d.Pack} pack Pack to manage created objects.
parameter: {!o3d.Shape} source The Shape to copy.
parameter: {string} opt_prefix optional prefix for names of new objects.
returns: {!o3d.Shape} the new copy of the shape.

  
  o3djs.shape.duplicateShape = function(pack, source, opt_prefix) {
    if (opt_prefix == null) {
      opt_prefix = '';
    }
    var newShape = pack.createObject('Shape');
    var elements = source.elements;
    for (var ee = 0; ee < elements.length; ee++) {
      var sourceElement = elements[ee];
      var newElement = pack.createObject(sourceElement.className);
      newElement.owner = newShape;
      newElement.copyParams(sourceElement);
      // TODO: If we get the chance to parameterize buffers then make
      //     we can delete this code since copyParams will handle it.
      //     For now it only handles primitives by doing it manually.
      if (sourceElement.isAClassName('o3d.Primitive')) {
        newElement.indexBuffer = sourceElement.indexBuffer;
        newElement.startIndex = sourceElement.startIndex;
        newElement.primitiveType = sourceElement.primitiveType;
        newElement.numberVertices = sourceElement.numberVertices;
        newElement.numberPrimitives = sourceElement.numberPrimitives;
      }
    }
    newShape.createDrawElements(pack, null);
    return newShape;
  };
  
  


(C) Æliens 20/2/2008

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.