diff options
author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-25 03:01:40 +0000 |
---|---|---|
committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-25 03:01:40 +0000 |
commit | 0dbb54aa48df1d003c30f7d331b9afc19e106f03 (patch) | |
tree | 5e651b5c45332a6fd0e42806dc1489f366eaa04a /o3d/samples/o3djs | |
parent | 80db1e280b349b0dae96d6bdfb72ef21b31087b7 (diff) | |
download | chromium_src-0dbb54aa48df1d003c30f7d331b9afc19e106f03.zip chromium_src-0dbb54aa48df1d003c30f7d331b9afc19e106f03.tar.gz chromium_src-0dbb54aa48df1d003c30f7d331b9afc19e106f03.tar.bz2 |
Separate the line primitive stuff out of debug.js
and into lineprimitives.js.
I refactored to code to share a lot of stuff
with primitive.js.
Review URL: http://codereview.chromium.org/435039
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@33041 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/samples/o3djs')
-rw-r--r-- | o3d/samples/o3djs/debug.js | 338 | ||||
-rw-r--r-- | o3d/samples/o3djs/js_list.manifest | 1 | ||||
-rw-r--r-- | o3d/samples/o3djs/lineprimitives.js | 371 | ||||
-rw-r--r-- | o3d/samples/o3djs/primitives.js | 207 |
4 files changed, 491 insertions, 426 deletions
diff --git a/o3d/samples/o3djs/debug.js b/o3d/samples/o3djs/debug.js index 429a75f..427c286 100644 --- a/o3d/samples/o3djs/debug.js +++ b/o3d/samples/o3djs/debug.js @@ -43,6 +43,7 @@ o3djs.provide('o3djs.debug'); o3djs.require('o3djs.math'); o3djs.require('o3djs.primitives'); +o3djs.require('o3djs.lineprimitives'); var O3D_DEBUG_PREFIX = 'o3dDebug_'; var O3D_DEBUG_PREFIX_LENGTH = O3D_DEBUG_PREFIX.length; @@ -170,329 +171,6 @@ o3djs.debug.createScaleShaders_ = function(colorParamName, scaleParamName) { o3djs.debug = o3djs.debug || {}; /** - * Creates a line list shape and primitive given a material, vertex array and - * index array. - * - * @param {!o3d.Pack} pack Pack to create objects in. - * @param {!o3d.Material} material to use. - * @param {!Array.<!o3djs.math.Vector3>} vertices array of numbers in the - * format positionX, positionY, positionZ. - * @param {!Array.<number>} indices array of vertex indices, 2 per line. - * @return {!o3d.Shape} The created shape. - */ -o3djs.debug.createLineShape = function(pack, - material, - vertices, - indices) { - // create a shape and primitive for the vertices. - var shape = pack.createObject('Shape'); - var primitive = pack.createObject('Primitive'); - var streamBank = pack.createObject('StreamBank'); - primitive.owner = shape; - primitive.streamBank = streamBank; - - // Apply the material - primitive.material = material; - - primitive.numberPrimitives = indices.length / 2; - primitive.primitiveType = o3djs.base.o3d.Primitive.LINELIST; - primitive.numberVertices = vertices.length / 3; - primitive.createDrawElement(pack, null); - - var vertexBuffer = pack.createObject('VertexBuffer'); - var positionField = vertexBuffer.createField('FloatField', 3); - vertexBuffer.set(vertices); - - // Attach our buffers to our primitive. - streamBank.setVertexStream(o3djs.base.o3d.Stream.POSITION, - 0, - positionField, - 0); - - var indexBuffer = pack.createObject('IndexBuffer'); - indexBuffer.set(indices); - primitive.indexBuffer = indexBuffer; - return shape; -}; - -/** - * VertexInfo. Used to store vertices and indices. - * @constructor - * @param {!Array.<!o3djs.math.Vector3>} opt_vertices array of numbers in the - * format positionX, positionY, positionZ. - * @param {!Array.<number>} opt_indices array of indices in pairs. - */ -o3djs.debug.VertexInfo = function(opt_vertices, opt_indices) { - /** - * The vertices for this VertexInfo. - * @type {!Array.<o3djs.math.Vector3>} - */ - this.vertices = opt_vertices || []; - - /** - * The vertex indices this VertexInfo. - * @type {!Array.<number>} - */ - this.indices = opt_indices || []; -}; - -/** - * Creates a new VertexInfo. - * @param {!Array.<!o3djs.math.Vector3>} opt_vertices array of numbers in the - * format positionX, positionY, positionZ. - * @param {!Array.<number>} opt_indices array of indices, 2 per line. - * @return {!o3djs.debug.VertexInfo} The new VertexInfo. - */ -o3djs.debug.createVertexInfo = function(opt_vertices, opt_indices) { - return new o3djs.debug.VertexInfo(opt_vertices, opt_indices); -}; - -/** - * Enum for vertex component offsets. - * - * To get/set a vertex component you can do something like this. - * - * vertInfo.vertices[vertInfo.vertexIndex(index) + vertInfo.Offset.X] *= 2; - * - * @enum {number} - */ -o3djs.debug.VertexInfo.prototype.Offset = { - X: 0, - Y: 1, - Z: 2 -}; - -/** - * Computes the number of vertices in this vertex info. - * @return {number} The number of vertices. - */ -o3djs.debug.VertexInfo.prototype.numVertices = function() { - return this.vertices.length / 3; -}; - - -/** - * Given the number of a vertex returns the index in the array where - * the coordinates of that vertex vertexIndex. - * @param {number} vertexNumber The vertex number. - * @return {number} The index where that vertex begins. - */ -o3djs.debug.VertexInfo.prototype.vertexIndex = function(vertexNumber) { - return vertexNumber * 3; -} - -/** - * Adds a vertex. - * @param {number} positionX The x position of the vertex. - * @param {number} positionY The y position of the vertex. - * @param {number} positionZ The z position of the vertex. - */ -o3djs.debug.VertexInfo.prototype.addVertex = function( - positionX, positionY, positionZ) { - this.vertices.push(positionX, positionY, positionZ); -}; - -/** - * Adds a line. - * @param {number} index1 The index of the first vertex of the triangle. - * @param {number} index2 The index of the second vertex of the triangle. - */ -o3djs.debug.VertexInfo.prototype.addLine = function( - index1, index2) { - this.indices.push(index1, index2); -}; - -/** - * Creates a shape from a VertexInfo - * @param {!o3d.Pack} pack Pack to create objects in. - * @param {!o3d.Material} material to use. - * @return {!o3d.Shape} The created shape. - */ -o3djs.debug.VertexInfo.prototype.createShape = function( - pack, - material) { - return o3djs.debug.createLineShape(pack, - material, - this.vertices, - this.indices); -}; - - -/** - * Reorients the vertex positions of this vertexInfo by the - * given matrix. In other words it multiplies each vertex by the - * given matrix. - * @param {!o3djs.math.Matrix4} matrix Matrix to multiply by. - */ -o3djs.debug.VertexInfo.prototype.reorient = function(matrix) { - var math = o3djs.math; - var numVerts = this.numVertices(); - for (var v = 0; v < numVerts; ++v) { - var index = this.vertexIndex(v); - var position = [this.vertices[index + this.Offset.X], - this.vertices[index + this.Offset.Y], - this.vertices[index + this.Offset.Z], - 1]; - position = math.mulVectorMatrix(position, matrix); - this.vertices[index + this.Offset.X] = position[0]; - this.vertices[index + this.Offset.Y] = position[1]; - this.vertices[index + this.Offset.Z] = position[2]; - } -}; - -/** - * Creates the vertices and indices for a cube of lines. The - * cube will be created around the origin. (-size / 2, size / 2) - * The created cube has a position stream only and can therefore only be used - * with shaders that support those a position stream. - * - * @param {number} size Width, height and depth of the cube. - * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply all - * the vertices. - * @return {!o3djs.debug.VertexInfo} The created cube vertices. - */ -o3djs.debug.createLineCubeVertices = function(size, opt_matrix) { - var k = size / 2; - - var vertices = [ - -k, -k, -k, - +k, -k, -k, - -k, +k, -k, - +k, +k, -k, - -k, -k, +k, - +k, -k, +k, - -k, +k, +k, - +k, +k, +k - ]; - - var indices = [ - 0, 1, 1, 3, 3, 2, 2, 0, - 4, 5, 5, 7, 7, 6, 6, 4, - 0, 4, 1, 5, 2, 6, 3, 7 - ]; - - var vertexInfo = o3djs.debug.createVertexInfo(vertices, indices); - if (opt_matrix) { - vertexInfo.reorient(opt_matrix); - } - return vertexInfo; -}; - -/** - * Creates a cube of lines. - * @param {!o3d.Pack} pack Pack to create sphere elements in. - * @param {!o3d.Material} material to use. - * @param {number} size Width, height and depth of the cube. - * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply all - * the vertices. - * @return {!o3d.Shape} The created cube. - */ -o3djs.debug.createLineCube = function(pack, - material, - size, - opt_matrix) { - var vertexInfo = o3djs.debug.createLineCubeVertices(size, opt_matrix); - return vertexInfo.createShape(pack, material); -}; - -/** - * Creates sphere vertices. - * The created sphere has a position stream only and can therefore only be - * used with shaders that support those a position stream. - * - * @param {number} radius radius of the sphere. - * @param {number} subdivisionsAxis number of steps around the sphere. - * @param {number} subdivisionsHeight number of vertically on the sphere. - * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply all - * the vertices. - * @return {!o3djs.debug.VertexInfo} The created sphere vertices. - */ -o3djs.debug.createLineSphereVertices = function(radius, - subdivisionsAxis, - subdivisionsHeight, - opt_matrix) { - if (subdivisionsAxis <= 0 || subdivisionsHeight <= 0) { - throw Error('subdivisionAxis and subdivisionHeight must be > 0'); - } - - // We are going to generate our sphere by iterating through its - // spherical coordinates and generating 1 quad for each quad on a - // ring of the sphere. - - var vertexInfo = o3djs.debug.createVertexInfo(); - - // Generate the individual vertices in our vertex buffer. - for (var y = 0; y <= subdivisionsHeight; y++) { - for (var x = 0; x <= subdivisionsAxis; x++) { - // Generate a vertex based on its spherical coordinates - var u = x / subdivisionsAxis - var v = y / subdivisionsHeight; - var theta = 2 * Math.PI * u; - var phi = Math.PI * v; - var sinTheta = Math.sin(theta); - var cosTheta = Math.cos(theta); - var sinPhi = Math.sin(phi); - var cosPhi = Math.cos(phi); - var ux = cosTheta * sinPhi; - var uy = cosPhi; - var uz = sinTheta * sinPhi; - vertexInfo.addVertex(radius * ux, radius * uy, radius * uz); - } - } - var numVertsAround = subdivisionsAxis + 1; - - for (var x = 0; x < subdivisionsAxis; x++) { - for (var y = 0; y < subdivisionsHeight; y++) { - // Make 2 lines per quad. - vertexInfo.addLine( - (y + 0) * numVertsAround + x, - (y + 0) * numVertsAround + x + 1); - vertexInfo.addLine( - (y + 0) * numVertsAround + x, - (y + 1) * numVertsAround + x); - } - } - - if (opt_matrix) { - vertexInfo.reorient(opt_matrix); - } - return vertexInfo; -}; - -/** - * Creates a sphere. - * The created sphere has position, normal, uv and vertex color streams only - * and can therefore only be used with shaders that support those 4 - * streams. - * - * @param {!o3d.Pack} pack Pack to create sphere elements in. - * @param {!o3d.Material} material to use. - * @param {number} radius radius of the sphere. - * @param {number} subdivisionsAxis number of steps around the sphere. - * @param {number} subdivisionsHeight number of vertically on the sphere. - * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply all - * the vertices. - * @return {!o3d.Shape} The created sphere. - * - * @see o3d.Pack - * @see o3d.Shape - */ -o3djs.debug.createLineSphere = function(pack, - material, - radius, - subdivisionsAxis, - subdivisionsHeight, - opt_matrix) { - var vertexInfo = o3djs.debug.createLineSphereVertices( - radius, - subdivisionsAxis, - subdivisionsHeight, - opt_matrix); - - return vertexInfo.createShape(pack, material); -}; - -/** * An object to manage a single debug line. * @constructor * @param {!o3djs.debug.DebugLineGroup} debugLineGroup DebugLineGroup @@ -895,9 +573,10 @@ o3djs.debug.DebugHelper = function(pack, viewInfo) { } { - this.sphereShape_ = o3djs.debug.createLineSphere(pack, - this.axisMaterial_, - 0.5, 8, 8); + this.sphereShape_ = o3djs.lineprimitives.createLineSphere( + pack, + this.axisMaterial_, + 0.5, 8, 8); this.sphereShape_.name = O3D_DEBUG_SPHERE_SHAPE_NAME; var primitive = this.sphereShape_.elements[0]; this.sphereScaleParam_ = primitive.createParam( @@ -906,9 +585,10 @@ o3djs.debug.DebugHelper = function(pack, viewInfo) { } { - this.cubeShape_ = o3djs.debug.createLineCube(pack, - this.axisMaterial_, - 1); + this.cubeShape_ = o3djs.lineprimitives.createLineCube( + pack, + this.axisMaterial_, + 1); this.cubeShape_.name = O3D_DEBUG_CUBE_SHAPE_NAME; var primitive = this.cubeShape_.elements[0]; this.cubeScaleParam_ = primitive.createParam( diff --git a/o3d/samples/o3djs/js_list.manifest b/o3d/samples/o3djs/js_list.manifest index ba639b8..6548155 100644 --- a/o3d/samples/o3djs/js_list.manifest +++ b/o3d/samples/o3djs/js_list.manifest @@ -39,6 +39,7 @@ 'event.js', 'fps.js', 'io.js', + 'lineprimitives.js', 'loader.js', 'material.js', 'math.js', diff --git a/o3d/samples/o3djs/lineprimitives.js b/o3d/samples/o3djs/lineprimitives.js new file mode 100644 index 0000000..07ea7f8 --- /dev/null +++ b/o3d/samples/o3djs/lineprimitives.js @@ -0,0 +1,371 @@ +/* + * 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 to help + * create line primitives for o3d applications. + * + * 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.lineprimtives'); + +o3djs.require('o3djs.math'); +o3djs.require('o3djs.primitives'); + +/** + * Defines a namespace for o3djs.lineprimitives. + * @namespace + */ +o3djs.lineprimitives = o3djs.lineprimitives || {}; + +/** + * A LineVertexInfo is a specialization of VertexInfoBase for line based + * geometry. + * @constructor + * @extends {o3djs.primitives.VertexInfoBase} + */ +o3djs.lineprimitives.LineVertexInfo = function() { + o3djs.primitives.VertexInfoBase.call(this); +} + +o3djs.base.inherit(o3djs.lineprimitives.LineVertexInfo, + o3djs.primitives.VertexInfoBase); + +/** + * Returns the number of lines represented by the LineVertexInfo. + * @return {number} The number of lines represented by LineVertexInfo. + */ +o3djs.lineprimitives.LineVertexInfo.prototype.numLines = function() { + return this.indices.length / 2; +}; + +/** + * Adds a line. + * @param {number} index1 The index of the first vertex of the line. + * @param {number} index2 The index of the second vertex of the line. + */ +o3djs.lineprimitives.LineVertexInfo.prototype.addLine = function( + index1, index2) { + this.indices.push(index1, index2); +}; + +/** + * Gets the vertex indices of the triangle at the given triangle index. + * @param {number} triangleIndex The index of the triangle. + * @return {!Array.<number>} An array of three triangle indices. + */ +o3djs.lineprimitives.LineVertexInfo.prototype.getLine = function( + triangleIndex) { + var indexIndex = triangleIndex * 3; + return [this.indices[indexIndex + 0], + this.indices[indexIndex + 1], + this.indices[indexIndex + 2]]; +}; + +/** + * Sets the vertex indices of the line at the given line index. + * @param {number} lineIndex The index of the line. + * @param {number} index1 The index of the first vertex of the line. + * @param {number} index2 The index of the second vertex of the line. + */ +o3djs.lineprimitives.LineVertexInfo.prototype.setLine = function( + lineIndex, index1, index2) { + var indexIndex = lineIndex * 2; + this.indices[indexIndex + 0] = index1; + this.indices[indexIndex + 1] = index2; +}; + +/** + * Creates a shape from a LineVertexInfo + * @param {!o3d.Pack} pack Pack to create objects in. + * @param {!o3d.Material} material to use. + * @return {!o3d.Shape} The created shape. + */ +o3djs.lineprimitives.LineVertexInfo.prototype.createShape = function( + pack, + material) { + this.validate(); + + var positionStream = this.findStream(o3djs.base.o3d.Stream.POSITION); + var numVertices = positionStream.numElements(); + + // create a shape and primitive for the vertices. + var shape = pack.createObject('Shape'); + var primitive = pack.createObject('Primitive'); + var streamBank = pack.createObject('StreamBank'); + primitive.owner = shape; + primitive.streamBank = streamBank; + primitive.material = material; + primitive.numberPrimitives = this.indices.length / 2; + primitive.primitiveType = o3djs.base.o3d.Primitive.LINELIST; + primitive.numberVertices = numVertices; + primitive.createDrawElement(pack, null); + + // Provide default streams or fail if the effect requires them. + var streamInfos = material.effect.getStreamInfo(); + for (var s = 0; s < streamInfos.length; ++s) { + var semantic = streamInfos[s].semantic; + var semanticIndex = streamInfos[s].semanticIndex; + + var requiredStream = this.findStream(semantic, semanticIndex); + if (!requiredStream) { + switch (semantic) { + case o3djs.base.o3d.Stream.COLOR: + requiredStream = this.addStream(4, semantic, semanticIndex); + for (var i = 0; i < numVertices; ++i) { + requiredStream.addElement(1, 1, 1, 1); + } + break; + default: + throw 'Missing stream for semantic ' + semantic + + ' with semantic index ' + semanticIndex; + } + } + } + + // These next few lines take our javascript streams and load them into a + // 'buffer' where the 3D hardware can find them. We have to do this + // because the 3D hardware can't 'see' javascript data until we copy it to + // a buffer. + var vertexBuffer = pack.createObject('VertexBuffer'); + var fields = []; + for (var s = 0; s < this.streams.length; ++s) { + var stream = this.streams[s]; + var fieldType = (stream.semantic == o3djs.base.o3d.Stream.COLOR && + stream.numComponents == 4) ? 'UByteNField' : 'FloatField'; + fields[s] = vertexBuffer.createField(fieldType, stream.numComponents); + streamBank.setVertexStream(stream.semantic, + stream.semanticIndex, + fields[s], + 0); + } + vertexBuffer.allocateElements(numVertices); + for (var s = 0; s < this.streams.length; ++s) { + fields[s].setAt(0, this.streams[s].elements); + } + + var indexBuffer = pack.createObject('IndexBuffer'); + indexBuffer.set(this.indices); + primitive.indexBuffer = indexBuffer; + o3djs.primitives.setCullingInfo(primitive); + return shape; +}; + +/** + * Creates a new LineVertexInfo. + * @return {!o3djs.lineprimitives.LineVertexInfo} The new LineVertexInfo. + */ +o3djs.lineprimitives.createLineVertexInfo = function() { + return new o3djs.lineprimitives.LineVertexInfo(); +}; + +/** + * Creates the vertices and indices for a cube of lines. The + * cube will be created around the origin. (-size / 2, size / 2) + * The created cube has a position stream only and can therefore only be used + * with shaders that support those a position stream. + * + * @param {number} size Width, height and depth of the cube. + * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply all + * the vertices. + * @return {!o3djs.lineprimitives.LineVertexInfo} The created cube vertices. + */ +o3djs.lineprimitives.createLineCubeVertices = function(size, opt_matrix) { + var k = size / 2; + + var vertices = [ + [-k, -k, -k], + [+k, -k, -k], + [-k, +k, -k], + [+k, +k, -k], + [-k, -k, +k], + [+k, -k, +k], + [-k, +k, +k], + [+k, +k, +k] + ]; + + var indices = [ + [0, 1], + [1, 3], + [3, 2], + [2, 0], + [4, 5], + [5, 7], + [7, 6], + [6, 4], + [0, 4], + [1, 5], + [2, 6], + [3, 7] + ]; + + var vertexInfo = o3djs.lineprimitives.createLineVertexInfo(); + var positionStream = vertexInfo.addStream( + 3, o3djs.base.o3d.Stream.POSITION); + + for (var v = 0; v < vertices.length; ++v) { + positionStream.addElementVector(vertices[v]); + } + + for (var i = 0; i < indices.length; ++i) { + vertexInfo.addLine(indices[i][0], indices[i][1]); + } + + if (opt_matrix) { + vertexInfo.reorient(opt_matrix); + } + return vertexInfo; +}; + +/** + * Creates a cube of lines. + * @param {!o3d.Pack} pack Pack to create sphere elements in. + * @param {!o3d.Material} material to use. + * @param {number} size Width, height and depth of the cube. + * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply all + * the vertices. + * @return {!o3d.Shape} The created cube. + */ +o3djs.lineprimitives.createLineCube = function( + pack, + material, + size, + opt_matrix) { + var vertexInfo = + o3djs.lineprimitives.createLineCubeVertices(size, opt_matrix); + return vertexInfo.createShape(pack, material); +}; + +/** + * Creates sphere vertices. + * The created sphere has a position stream only and can therefore only be + * used with shaders that support those a position stream. + * + * @param {number} radius radius of the sphere. + * @param {number} subdivisionsAxis number of steps around the sphere. + * @param {number} subdivisionsHeight number of vertically on the sphere. + * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply all + * the vertices. + * @return {!o3djs.lineprimitives.LineVertexInfo} The created sphere vertices. + */ +o3djs.lineprimitives.createLineSphereVertices = function( + radius, + subdivisionsAxis, + subdivisionsHeight, + opt_matrix) { + if (subdivisionsAxis <= 0 || subdivisionsHeight <= 0) { + throw Error('subdivisionAxis and subdivisionHeight must be > 0'); + } + + // We are going to generate our sphere by iterating through its + // spherical coordinates and generating 1 quad for each quad on a + // ring of the sphere. + + var vertexInfo = o3djs.lineprimitives.createLineVertexInfo(); + var positionStream = vertexInfo.addStream( + 3, o3djs.base.o3d.Stream.POSITION); + + // Generate the individual vertices in our vertex buffer. + for (var y = 0; y <= subdivisionsHeight; y++) { + for (var x = 0; x <= subdivisionsAxis; x++) { + // Generate a vertex based on its spherical coordinates + var u = x / subdivisionsAxis + var v = y / subdivisionsHeight; + var theta = 2 * Math.PI * u; + var phi = Math.PI * v; + var sinTheta = Math.sin(theta); + var cosTheta = Math.cos(theta); + var sinPhi = Math.sin(phi); + var cosPhi = Math.cos(phi); + var ux = cosTheta * sinPhi; + var uy = cosPhi; + var uz = sinTheta * sinPhi; + positionStream.addElement(radius * ux, radius * uy, radius * uz); + } + } + var numVertsAround = subdivisionsAxis + 1; + + for (var x = 0; x < subdivisionsAxis; x++) { + for (var y = 0; y < subdivisionsHeight; y++) { + // Make 2 lines per quad. + vertexInfo.addLine( + (y + 0) * numVertsAround + x, + (y + 0) * numVertsAround + x + 1); + vertexInfo.addLine( + (y + 0) * numVertsAround + x, + (y + 1) * numVertsAround + x); + } + } + + if (opt_matrix) { + vertexInfo.reorient(opt_matrix); + } + return vertexInfo; +}; + +/** + * Creates a sphere. + * The created sphere has position, normal, uv and vertex color streams only + * and can therefore only be used with shaders that support those 4 + * streams. + * + * @param {!o3d.Pack} pack Pack to create sphere elements in. + * @param {!o3d.Material} material to use. + * @param {number} radius radius of the sphere. + * @param {number} subdivisionsAxis number of steps around the sphere. + * @param {number} subdivisionsHeight number of vertically on the sphere. + * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply all + * the vertices. + * @return {!o3d.Shape} The created sphere. + * + * @see o3d.Pack + * @see o3d.Shape + */ +o3djs.lineprimitives.createLineSphere = function( + pack, + material, + radius, + subdivisionsAxis, + subdivisionsHeight, + opt_matrix) { + var vertexInfo = o3djs.lineprimitives.createLineSphereVertices( + radius, + subdivisionsAxis, + subdivisionsHeight, + opt_matrix); + + return vertexInfo.createShape(pack, material); +}; + diff --git a/o3d/samples/o3djs/primitives.js b/o3d/samples/o3djs/primitives.js index e2177dc..2e057af 100644 --- a/o3d/samples/o3djs/primitives.js +++ b/o3d/samples/o3djs/primitives.js @@ -255,10 +255,10 @@ o3djs.primitives.createVertexStreamInfo = function(numComponents, }; /** - * VertexInfo. Used to store vertices and indices. + * VertexInfoBase. Used to store vertices and indices. * @constructor */ -o3djs.primitives.VertexInfo = function() { +o3djs.primitives.VertexInfoBase = function() { this.streams = []; this.indices = []; }; @@ -272,7 +272,7 @@ o3djs.primitives.VertexInfo = function() { * Defaults to zero. * @return {!o3djs.primitives.VertexStreamInfo} The new stream. */ -o3djs.primitives.VertexInfo.prototype.addStream = function( +o3djs.primitives.VertexInfoBase.prototype.addStream = function( numComponents, semantic, opt_semanticIndex) { @@ -293,7 +293,7 @@ o3djs.primitives.VertexInfo.prototype.addStream = function( * @return {o3djs.primitives.VertexStreamInfo} The stream or null if it * is not present. */ -o3djs.primitives.VertexInfo.prototype.findStream = function( +o3djs.primitives.VertexInfoBase.prototype.findStream = function( semantic, opt_semanticIndex) { opt_semanticIndex = opt_semanticIndex || 0; @@ -313,7 +313,7 @@ o3djs.primitives.VertexInfo.prototype.findStream = function( * @param {number} opt_semanticIndex The semantic index of the stream. * Defaults to zero. */ -o3djs.primitives.VertexInfo.prototype.removeStream = function( +o3djs.primitives.VertexInfoBase.prototype.removeStream = function( semantic, opt_semanticIndex) { opt_semanticIndex = opt_semanticIndex || 0; @@ -327,62 +327,15 @@ o3djs.primitives.VertexInfo.prototype.removeStream = function( }; /** - * Returns the number of triangles represented by the VertexInfo. - * @return {number} The number of triangles represented by VertexInfo. - */ -o3djs.primitives.VertexInfo.prototype.numTriangles = function() { - return this.indices.length / 3; -}; - -/** - * Adds a triangle. - * @param {number} index1 The index of the first vertex of the triangle. - * @param {number} index2 The index of the second vertex of the triangle. - * @param {number} index3 The index of the third vertex of the triangle. - */ -o3djs.primitives.VertexInfo.prototype.addTriangle = function( - index1, index2, index3) { - this.indices.push(index1, index2, index3); -}; - -/** - * Gets the vertex indices of the triangle at the given triangle index. - * @param {number} triangleIndex The index of the triangle. - * @return {!Array.<number>} An array of three triangle indices. - */ -o3djs.primitives.VertexInfo.prototype.getTriangle = function( - triangleIndex) { - var indexIndex = triangleIndex * 3; - return [this.indices[indexIndex + 0], - this.indices[indexIndex + 1], - this.indices[indexIndex + 2]]; -}; - -/** - * Sets the vertex indices of the triangle at the given triangle index. - * @param {number} triangleIndex The index of the triangle. - * @param {number} index1 The index of the first vertex of the triangle. - * @param {number} index2 The index of the second vertex of the triangle. - * @param {number} index3 The index of the third vertex of the triangle. - */ -o3djs.primitives.VertexInfo.prototype.setTriangle = function( - triangleIndex, index1, index2, index3) { - var indexIndex = triangleIndex * 3; - this.indices[indexIndex + 0] = index1; - this.indices[indexIndex + 1] = index2; - this.indices[indexIndex + 2] = index3; -}; - -/** * Appends all of the information in the passed VertexInfo on to the * end of this one. This is useful for putting multiple primitives' * vertices, appropriately transformed, into a single Shape. Both * VertexInfo objects must contain the same number of streams, with * the same semantics and number of components. - * @param {!o3djs.primitives.VertexInfo} info The VertexInfo whose + * @param {!o3djs.primitives.VertexInfoBase} info The VertexInfo whose * information should be appended to this one. */ -o3djs.primitives.VertexInfo.prototype.append = function(info) { +o3djs.primitives.VertexInfoBase.prototype.append = function(info) { if (this.streams.length == 0 && info.streams.length != 0) { // Special case for (var i = 0; i < info.streams.length; i++) { @@ -445,7 +398,7 @@ o3djs.primitives.VertexInfo.prototype.append = function(info) { * Validates that all the streams contain the same number of elements, that * all the indices are within range and that a position stream is present. */ -o3djs.primitives.VertexInfo.prototype.validate = function() { +o3djs.primitives.VertexInfoBase.prototype.validate = function() { // Check the position stream is present. var positionStream = this.findStream(o3djs.base.o3d.Stream.POSITION); if (!positionStream) @@ -470,6 +423,108 @@ o3djs.primitives.VertexInfo.prototype.validate = function() { }; /** + * Reorients the vertices, positions and normals, of this vertexInfo by the + * given matrix. In other words, it multiplies each vertex by the given matrix + * and each normal by the inverse-transpose of the given matrix. + * @param {!o3djs.math.Matrix4} matrix Matrix by which to multiply. + */ +o3djs.primitives.VertexInfoBase.prototype.reorient = function(matrix) { + var math = o3djs.math; + var matrixInverse = math.inverse(math.matrix4.getUpper3x3(matrix)); + + for (var s = 0; s < this.streams.length; ++s) { + var stream = this.streams[s]; + if (stream.numComponents == 3) { + var numElements = stream.numElements(); + switch (stream.semantic) { + case o3djs.base.o3d.Stream.POSITION: + for (var i = 0; i < numElements; ++i) { + stream.setElementVector(i, + math.matrix4.transformPoint(matrix, + stream.getElementVector(i))); + } + break; + case o3djs.base.o3d.Stream.NORMAL: + for (var i = 0; i < numElements; ++i) { + stream.setElementVector(i, + math.matrix4.transformNormal(matrix, + stream.getElementVector(i))); + } + break; + case o3djs.base.o3d.Stream.TANGENT: + case o3djs.base.o3d.Stream.BINORMAL: + for (var i = 0; i < numElements; ++i) { + stream.setElementVector(i, + math.matrix4.transformDirection(matrix, + stream.getElementVector(i))); + } + break; + } + } + } +}; + +/** + * A VertexInfo is a specialization of VertexInfoBase for triangle based + * geometry. + * @constructor + * @extends {o3djs.primitives.VertexInfoBase} + */ +o3djs.primitives.VertexInfo = function() { + o3djs.primitives.VertexInfoBase.call(this); +} + +o3djs.base.inherit(o3djs.primitives.VertexInfo, + o3djs.primitives.VertexInfoBase); + +/** + * Returns the number of triangles represented by the VertexInfo. + * @return {number} The number of triangles represented by VertexInfo. + */ +o3djs.primitives.VertexInfo.prototype.numTriangles = function() { + return this.indices.length / 3; +}; + +/** + * Adds a triangle. + * @param {number} index1 The index of the first vertex of the triangle. + * @param {number} index2 The index of the second vertex of the triangle. + * @param {number} index3 The index of the third vertex of the triangle. + */ +o3djs.primitives.VertexInfo.prototype.addTriangle = function( + index1, index2, index3) { + this.indices.push(index1, index2, index3); +}; + +/** + * Gets the vertex indices of the triangle at the given triangle index. + * @param {number} triangleIndex The index of the triangle. + * @return {!Array.<number>} An array of three triangle indices. + */ +o3djs.primitives.VertexInfo.prototype.getTriangle = function( + triangleIndex) { + var indexIndex = triangleIndex * 3; + return [this.indices[indexIndex + 0], + this.indices[indexIndex + 1], + this.indices[indexIndex + 2]]; +}; + +/** + * Sets the vertex indices of the triangle at the given triangle index. + * @param {number} triangleIndex The index of the triangle. + * @param {number} index1 The index of the first vertex of the triangle. + * @param {number} index2 The index of the second vertex of the triangle. + * @param {number} index3 The index of the third vertex of the triangle. + */ +o3djs.primitives.VertexInfo.prototype.setTriangle = function( + triangleIndex, index1, index2, index3) { + var indexIndex = triangleIndex * 3; + this.indices[indexIndex + 0] = index1; + this.indices[indexIndex + 1] = index2; + this.indices[indexIndex + 2] = index3; +}; + +/** * Creates a shape from a VertexInfo * @param {!o3d.Pack} pack Pack to create objects in. * @param {!o3d.Material} material to use. @@ -551,48 +606,6 @@ o3djs.primitives.VertexInfo.prototype.createShape = function( }; /** - * Reorients the vertices, positions and normals, of this vertexInfo by the - * given matrix. In other words, it multiplies each vertex by the given matrix - * and each normal by the inverse-transpose of the given matrix. - * @param {!o3djs.math.Matrix4} matrix Matrix by which to multiply. - */ -o3djs.primitives.VertexInfo.prototype.reorient = function(matrix) { - var math = o3djs.math; - var matrixInverse = math.inverse(math.matrix4.getUpper3x3(matrix)); - - for (var s = 0; s < this.streams.length; ++s) { - var stream = this.streams[s]; - if (stream.numComponents == 3) { - var numElements = stream.numElements(); - switch (stream.semantic) { - case o3djs.base.o3d.Stream.POSITION: - for (var i = 0; i < numElements; ++i) { - stream.setElementVector(i, - math.matrix4.transformPoint(matrix, - stream.getElementVector(i))); - } - break; - case o3djs.base.o3d.Stream.NORMAL: - for (var i = 0; i < numElements; ++i) { - stream.setElementVector(i, - math.matrix4.transformNormal(matrix, - stream.getElementVector(i))); - } - break; - case o3djs.base.o3d.Stream.TANGENT: - case o3djs.base.o3d.Stream.BINORMAL: - for (var i = 0; i < numElements; ++i) { - stream.setElementVector(i, - math.matrix4.transformDirection(matrix, - stream.getElementVector(i))); - } - break; - } - } - } -}; - -/** * Calculate tangents and binormals based on the positions, normals and * texture coordinates found in existing streams. * @param {number} opt_semanticIndex The semantic index of the texture |