topical media & game development
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.