diff options
author | simonrad@chromium.org <simonrad@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-20 03:42:41 +0000 |
---|---|---|
committer | simonrad@chromium.org <simonrad@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-20 03:42:41 +0000 |
commit | 021c6aacd0cfc3f5f8b24af3361dac0205c6fb04 (patch) | |
tree | 0fa532e139cfce113f7c1a1ac61f4721c24dd576 /o3d/samples | |
parent | 109f7236ba8d73e42841760cefe5a3e1539bbc1e (diff) | |
download | chromium_src-021c6aacd0cfc3f5f8b24af3361dac0205c6fb04.zip chromium_src-021c6aacd0cfc3f5f8b24af3361dac0205c6fb04.tar.gz chromium_src-021c6aacd0cfc3f5f8b24af3361dac0205c6fb04.tar.bz2 |
Added torus primitive and Rotate1 manipulator.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/395012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@32596 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/samples')
-rw-r--r-- | o3d/samples/manipulators/rotate1.html | 282 | ||||
-rw-r--r-- | o3d/samples/o3djs/manipulators.js | 157 | ||||
-rw-r--r-- | o3d/samples/o3djs/primitives.js | 151 |
3 files changed, 556 insertions, 34 deletions
diff --git a/o3d/samples/manipulators/rotate1.html b/o3d/samples/manipulators/rotate1.html new file mode 100644 index 0000000..226001e --- /dev/null +++ b/o3d/samples/manipulators/rotate1.html @@ -0,0 +1,282 @@ +<!-- +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. +--> + +<!-- +Translate2 manipulator + +This sample shows how to use the o3djs.manipulators.Translate2 class +to interactively drag objects around the scene. +--> +<!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> +Translate2 Manipulator +</title> +<script type="text/javascript" src="../o3djs/base.js"></script> +<script type="text/javascript" id="o3dscript"> +o3djs.require('o3djs.util'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.quaternions'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.primitives'); +o3djs.require('o3djs.manipulators'); +o3djs.require('o3djs.effect'); + +// global variables +var g_o3dElement; +var g_client; +var g_o3d; +var g_math; +var g_pack; +var g_viewInfo; + +var g_lightPosition = [5, 5, 7]; +var g_eyePosition = [1, 5, 23]; + +var g_primitives = []; +var g_manager; + +/** + * Creates the client area. + */ +function initClient() { + window.g_finished = false; // for selenium testing. + + // Runs the sample in V8. Comment out this line to run it in the browser + // JavaScript engine, for example if you want to debug it. + // TODO(kbr): we need to investigate why turning this on is + // significantly slower than leaving it disabled. + // o3djs.util.setMainEngine(o3djs.util.Engine.V8); + + o3djs.util.makeClients(main); +} + +/** + * Initializes global variables, positions camera, draws shapes. + * @param {Array} clientElements Array of o3d object elements. + */ +function main(clientElements) { + var o3dElement = clientElements[0]; + + // Init global variables. + initGlobals(clientElements); + + // Set up the view and projection transformations. + initContext(); + + // Add the shapes to the transform heirarchy. + createShapes(); + + // Add the manipulators to the transform hierarchy. + createManipulators(); + + // Start picking; it won't do anything until the scene finishes loading. + o3djs.event.addEventListener(o3dElement, 'mousedown', onMouseDown); + o3djs.event.addEventListener(o3dElement, 'mousemove', onMouseMove); + o3djs.event.addEventListener(o3dElement, 'mouseup', onMouseUp); + + window.g_finished = true; // for selenium testing. +} + +function onMouseDown(e) { + g_manager.mousedown(e.x, e.y, + g_viewInfo.drawContext.view, + g_viewInfo.drawContext.projection, + g_client.width, + g_client.height); +} + +function onMouseMove(e) { + g_manager.mousemove(e.x, e.y, + g_viewInfo.drawContext.view, + g_viewInfo.drawContext.projection, + g_client.width, + g_client.height); + g_manager.updateInactiveManipulators(); +} + +function onMouseUp(e) { + g_manager.mouseup(); + g_manager.updateInactiveManipulators(); +} + +/** + * Initializes global variables and libraries. + */ +function initGlobals(clientElements) { + g_o3dElement = clientElements[0]; + window.g_client = g_client = g_o3dElement.client; + g_o3d = g_o3dElement.o3d; + g_math = o3djs.math; + + // Create a pack to manage the objects created. + g_pack = g_client.createPack(); + + // Create the render graph for a view. + g_viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_client.root, + g_client.renderGraphRoot); +} + +/** + * Sets up reasonable view and projection matrices. + */ +function initContext() { + // Set up a perspective transformation for the projection. + g_viewInfo.drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(30), // 30 degree frustum. + g_o3dElement.clientWidth / g_o3dElement.clientHeight, // Aspect ratio. + 1, // Near plane. + 5000); // Far plane. + + // Set up our view transformation to look towards the world origin where the + // primitives are located. + g_viewInfo.drawContext.view = g_math.matrix4.lookAt( + g_eyePosition, // eye + [0, 2, 0], // target + [0, 1, 0]); // up +} + +/** + * Creates shapes using the primitives utility library, and adds them to the + * transform graph at the root node. + */ +function createShapes() { + // Create a little tree-like hierarchy of cubes + createCubeTree(2, 1.5, [0, 0, 0], g_client.root); +} + +/** + * Creates a small tree of cubes to demonstrate interaction with a + * hierarchy of shapes. + */ +function createCubeTree(depth, edgeLength, translation, parent) { + var cur = createCube(edgeLength, translation, parent); + if (depth > 0) { + createCubeTree(depth - 1, + edgeLength / 1.5, + o3djs.math.addVector(translation, + [-1.2 * edgeLength, + 1.0 * edgeLength, + 0]), + cur); + createCubeTree(depth - 1, + edgeLength / 1.5, + o3djs.math.addVector(translation, + [1.2 * edgeLength, + 1.0 * edgeLength, + 0]), + cur); + } + return cur; +} + +/** + * Creates a cube shape using the primitives utility library, with an + * optional translation and parent. Returns the newly-created + * transform for the cube. + */ +function createCube(edgeLength, opt_translation, opt_parent) { + var cube = o3djs.primitives.createCube( + g_pack, + // A green phong-shaded material. + o3djs.material.createBasicMaterial(g_pack, + g_viewInfo, + [0, 1, 0, 1]), + edgeLength); + var transform = g_pack.createObject('Transform'); + transform.addShape(cube); + if (opt_translation) { + transform.translate(opt_translation); + } + if (opt_parent) { + transform.parent = opt_parent; + } else { + transform.parent = g_client.root; + } + g_primitives.push(transform); + return transform; +} + +/** + * Creates manipulators attached to the objects we've just created. + */ +function createManipulators() { + g_manager = o3djs.manipulators.createManager(g_pack, + g_viewInfo.performanceDrawList, + g_client.root, + null, + 0); + var jj = 2; + for (var ii = 0; ii < g_primitives.length; ii++) { + var manip1 = g_manager.createRotate1(); + var manip2 = g_manager.createRotate1(); + var manip3 = g_manager.createRotate1(); + manip1.attachTo(g_primitives[ii]); + manip2.attachTo(g_primitives[ii]); + manip3.attachTo(g_primitives[ii]); + manip1.setOffsetTranslation([0, -1.5, 0]); + manip2.setOffsetTranslation([0, -1.5, 0]); + manip3.setOffsetTranslation([0, -1.5, 0]); + manip2.setOffsetRotation(o3djs.quaternions.rotationY(Math.PI / 2)); + manip3.setOffsetRotation(o3djs.quaternions.rotationZ(Math.PI / 2)); + // Demonstrate that we can drag along arbitrary directions. + if ((++jj % 4) == 0) { + manip1.setOffsetRotation(o3djs.quaternions.rotationY(Math.PI / 4)); + manip2.setOffsetRotation(o3djs.quaternions.rotationY(Math.PI * 3.0 / 4)); + } + } +} + +/** + * Removes 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="initClient()" onunload="unload()"> +<h1>Translate2 Manipulator Sample</h1> +This example shows how to move objects around the scene using the +Translate2 manipulator. +<br/> +<!-- Start of O3D plugin --> +<div id="o3d" style="width: 600px; height: 600px;"></div> +<!-- End of O3D plugin --> +</body> +</html> diff --git a/o3d/samples/o3djs/manipulators.js b/o3d/samples/o3djs/manipulators.js index c38089c..db44344 100644 --- a/o3d/samples/o3djs/manipulators.js +++ b/o3d/samples/o3djs/manipulators.js @@ -582,6 +582,17 @@ o3djs.manipulators.Manager.prototype.createTranslate2 = function() { } /** + * Creates a new Rotate1 manipulator. A Rotate1 rotates about the + * X axis in its local coordinate system. + * @return {!o3djs.manipulators.Rotate1} A new Rotate1 manipulator. + */ +o3djs.manipulators.Manager.prototype.createRotate1 = function() { + var manip = new o3djs.manipulators.Rotate1(this); + this.add_(manip); + return manip; +} + +/** * Adds a manipulator to this manager's set. * @private * @param {!o3djs.manipulators.Manip} manip The manipulator to add. @@ -1026,17 +1037,16 @@ o3djs.manipulators.Manip.prototype.updateAttachedTransformFromLocalTransform_ = if (this.attachedTransform_ != null) { // Compute the composition of the base and local transforms. // The offset transform is skipped except for transforming the - // local matrix's translation by the rotation component of the - // offset transform. + // effect of the local matrix through the offset transform. var base = this.baseTransform_.worldMatrix; + var offset = this.offsetTransform_.localMatrix; var local = this.localTransform_.localMatrix; - var xlate = o3djs.math.matrix4.getTranslation(local); - var transformedXlate = - o3djs.math.matrix4.transformDirection( - this.offsetTransform_.localMatrix, - o3djs.math.matrix4.getTranslation(local)); - o3djs.math.matrix4.setTranslation(local, transformedXlate); - var totalMat = o3djs.math.matrix4.mul(base, local); + var offsetInv = o3djs.math.matrix4.inverse(offset); + // We want totalMat = offsetInv * local * offset * base. + var totalMat = o3djs.math.matrix4.mul(offsetInv, local); + totalMat = o3djs.math.matrix4.mul(totalMat, offset); + totalMat = o3djs.math.matrix4.mul(totalMat, base); + // Set this into the attached transform, taking into account its // parent's transform, if any. @@ -1045,11 +1055,11 @@ o3djs.manipulators.Manip.prototype.updateAttachedTransformFromLocalTransform_ = var attWorld = this.attachedTransform_.worldMatrix; var attLocal = this.attachedTransform_.localMatrix; var attParentMat = - o3djs.math.matrix4.mul(attWorld, - o3djs.math.matrix4.inverse(attLocal)); + o3djs.math.matrix4.mul(o3djs.math.matrix4.inverse(attLocal), + attWorld); // Now we can take the inverse of this matrix var attParentMatInv = o3djs.math.matrix4.inverse(attParentMat); - totalMat = o3djs.math.matrix4.mul(attParentMatInv, totalMat); + totalMat = o3djs.math.matrix4.mul(totalMat, attParentMatInv); this.attachedTransform_.localMatrix = totalMat; } } @@ -1125,6 +1135,7 @@ o3djs.manipulators.createArrowVertices_ = function(matrix) { /** * A manipulator allowing an object to be dragged along a line. + * A Translate1 moves along the X axis in its local coordinate system. * @constructor * @extends {o3djs.manipulators.Manip} * @param {!o3djs.manipulators.Manager} manager The manager for the @@ -1226,6 +1237,7 @@ o3djs.manipulators.Translate1.prototype.drag = function(startPoint, /** * A manipulator allowing an object to be dragged around a plane. + * A Translate2 moves around the XY plane in its local coordinate system. * @constructor * @extends {o3djs.manipulators.Manip} * @param {!o3djs.manipulators.Manager} manager The manager for the @@ -1327,3 +1339,124 @@ o3djs.manipulators.Translate2.prototype.drag = function(startPoint, diffVector)); this.updateAttachedTransformFromLocalTransform_(); } + + +/** + * A manipulator allowing an object to be rotated about a single axis. + * A Rotate1 rotates about the X axis in its local coordinate system. + * @constructor + * @extends {o3djs.manipulators.Manip} + * @param {!o3djs.manipulators.Manager} manager The manager for the + * new Rotate1 manipulator. + */ +o3djs.manipulators.Rotate1 = function(manager) { + o3djs.manipulators.Manip.call(this, manager); + + var pack = manager.pack; + var material = manager.defaultMaterial; + + var shape = manager.Rotate1Shape_; + if (!shape) { + // Create the geometry for the manipulator, which looks like + // a torus centered at the origin, with the X axis as its vertical axis. + var verts = o3djs.primitives.createTorusVertices( + 1.0, + 0.1, + 32, + 8, + o3djs.math.matrix4.rotationZ(Math.PI / 2)); + shape = verts.createShape(pack, material); + manager.Rotate1Shape_ = shape; + } + + this.addShapes_([ shape ]); + + this.transformInfo = o3djs.picking.createTransformInfo(this.getTransform(), + manager.transformInfo); + + /** + * A parameter added to our transform to be able to change the + * material's color for highlighting. + * @private + * @type {!o3d.ParamFloat4} + */ + this.colorParam_ = this.getTransform().createParam('diffuse', 'ParamFloat4'); + this.clearHighlight(); + + /** + * Plane around which we are dragging. + * @private + * @type {!o3djs.manipulators.Plane_} + */ + this.dragPlane_ = new o3djs.manipulators.Plane_(); +} + +o3djs.base.inherit(o3djs.manipulators.Rotate1, o3djs.manipulators.Manip); + +o3djs.manipulators.Rotate1.prototype.highlight = function(pickResult) { + // We can use instanced geometry for the entire Rotate1 since its + // entire color changes during highlighting. + // TODO(kbr): support custom user geometry and associated callbacks. + this.colorParam_.value = o3djs.manipulators.HIGHLIGHTED_COLOR; +} + +o3djs.manipulators.Rotate1.prototype.clearHighlight = function() { + this.colorParam_.value = o3djs.manipulators.DEFAULT_COLOR; +} + +o3djs.manipulators.Rotate1.prototype.makeActive = function(pickResult) { + o3djs.manipulators.Manip.prototype.makeActive.call(this, pickResult); + this.highlight(pickResult); + var worldMatrix = this.getTransform().worldMatrix; + this.dragPlane_.setNormal( + o3djs.math.matrix4.transformDirection(worldMatrix, + o3djs.manipulators.X_AXIS)); + this.dragPlane_.setPoint(pickResult.worldIntersectionPosition); +} + +o3djs.manipulators.Rotate1.prototype.makeInactive = function() { + o3djs.manipulators.Manip.prototype.makeInactive.call(this); + this.clearHighlight(); + this.updateAttachedTransformFromLocalTransform_(); + this.updateBaseTransformFromAttachedTransform_(); +} + +o3djs.manipulators.Rotate1.prototype.drag = function(startPoint, + endPoint) { + // Algorithm: Find intersection of ray with dragPlane_. Transform + // everything from world to local coordinates. Find angle of the + // initial and final plane intersection points about the rotation + // axis. Subtract these to find the rotation angle. + var worldIntersectPoint = this.dragPlane_.intersectRay(startPoint, + o3djs.math.subVector(endPoint, startPoint)); + if (worldIntersectPoint == null) { + // Drag plane is parallel to ray. Punt. + return; + } + + // We don't want the current drag state to affect our world-to-local + // transform, since we are calculating the drag from scratch. + this.getTransform().localMatrix = o3djs.math.matrix4.identity(); + + // Need to do a world-to-local transformation on all the points. + var worldToLocal = + o3djs.math.matrix4.inverse(this.getTransform().worldMatrix); + + // All of these are in local space. + var dragStart = o3djs.math.matrix4.transformPoint(worldToLocal, + this.dragPlane_.getPoint()); + var dragEnd = o3djs.math.matrix4.transformPoint(worldToLocal, + worldIntersectPoint); + // Since this should all be happening in a YZ plane, we can discard + // the X components. + dragStart[0] = 0; + dragEnd[0] = 0; + + // The point that we are rotating around is the origin (in local space). + + var diffAngle = Math.atan2(dragEnd[1], dragEnd[2]) - + Math.atan2(dragStart[1], dragStart[2]); + + this.getTransform().localMatrix = o3djs.math.matrix4.rotationX(-diffAngle); + this.updateAttachedTransformFromLocalTransform_(); +} diff --git a/o3d/samples/o3djs/primitives.js b/o3d/samples/o3djs/primitives.js index 0a062f8..e2177dc 100644 --- a/o3d/samples/o3djs/primitives.js +++ b/o3d/samples/o3djs/primitives.js @@ -1281,8 +1281,8 @@ o3djs.primitives.createTruncatedConeVertices = function(bottomRadius, radialSubdivisions, verticalSubdivisions, opt_matrix) { - if (radialSubdivisions < 1) { - throw Error('radialSubdivisions must be 1 or greater'); + if (radialSubdivisions < 3) { + throw Error('radialSubdivisions must be 3 or greater'); } if (verticalSubdivisions < 1) { @@ -1297,8 +1297,6 @@ o3djs.primitives.createTruncatedConeVertices = function(bottomRadius, var texCoordStream = vertexInfo.addStream( 2, o3djs.base.o3d.Stream.TEXCOORD, 0); - var indices = []; - var vertices = []; var vertsAroundEdge = radialSubdivisions + 1; // The slant of the cone is constant across its surface @@ -1317,7 +1315,7 @@ o3djs.primitives.createTruncatedConeVertices = function(bottomRadius, } else if (yy > verticalSubdivisions) { y = height; v = 1; - ringRadius = topRadius; + ringRadius = topRadius; } else { ringRadius = bottomRadius + (topRadius - bottomRadius) * (yy / verticalSubdivisions); @@ -1339,7 +1337,6 @@ o3djs.primitives.createTruncatedConeVertices = function(bottomRadius, } } - var trisAround = radialSubdivisions * 2; for (var yy = 0; yy < verticalSubdivisions + 4; ++yy) { for (var ii = 0; ii < radialSubdivisions; ++ii) { vertexInfo.addTriangle(vertsAroundEdge * (yy + 0) + 0 + ii, @@ -1362,8 +1359,8 @@ o3djs.primitives.createTruncatedConeVertices = function(bottomRadius, * that it has different top and bottom radii. A truncated cone can * also be used to create cylinders, by setting the bottom and top * radii equal, and cones, by setting either the top or bottom radius - * to 0. The truncated cone will be created with the bottom face in - * the xz plane, and the y axis in the center. The created cone has + * to 0. The truncated cone will be created centered about the origin, + * with the y axis as its vertical axis. The created cone has * position, normal and uv streams. * * @param {!o3d.Pack} pack Pack in which to create the truncated cone. @@ -1398,6 +1395,117 @@ o3djs.primitives.createTruncatedCone = function(pack, }; /** + * Creates vertices for a torus. The torus will be created centered about the + * origin, with the y axis as its vertical axis. The created torus has + * position, normal and uv streams. + * + * @param {number} torusRadius Distance from the center of the tube to + * the center of the torus. + * @param {number} tubeRadius Radius of the tube. + * @param {number} tubeLengthSubdivisions The number of subdivisions around the + * vertical axis of the torus, i.e. along the length of the tube. + * @param {number} circleSubdivisions The number of subdivisions in the circle + * that is rotated about the vertical axis to create the torus. + * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply + * all the vertices. + * @return {!o3djs.primitives.VertexInfo} The created torus vertices. + */ +o3djs.primitives.createTorusVertices = function(torusRadius, + tubeRadius, + tubeLengthSubdivisions, + circleSubdivisions, + opt_matrix) { + if (tubeLengthSubdivisions < 3) { + throw Error('tubeLengthSubdivisions must be 3 or greater'); + } + + if (circleSubdivisions < 3) { + throw Error('circleSubdivisions must be 3 or greater'); + } + + var vertexInfo = o3djs.primitives.createVertexInfo(); + var positionStream = vertexInfo.addStream( + 3, o3djs.base.o3d.Stream.POSITION); + var normalStream = vertexInfo.addStream( + 3, o3djs.base.o3d.Stream.NORMAL); + var texCoordStream = vertexInfo.addStream( + 2, o3djs.base.o3d.Stream.TEXCOORD, 0); + + for (var uu = 0; uu < tubeLengthSubdivisions; ++uu) { + var u = (uu / tubeLengthSubdivisions) * 2 * Math.PI; + for (var vv = 0; vv < circleSubdivisions; ++vv) { + var v = (vv / circleSubdivisions) * 2 * Math.PI; + var sinu = Math.sin(u); + var cosu = Math.cos(u); + var sinv = Math.sin(v); + var cosv = Math.cos(v); + positionStream.addElement((torusRadius + tubeRadius * cosv) * cosu, + tubeRadius * sinv, + (torusRadius + tubeRadius * cosv) * sinu); + normalStream.addElement(cosv * cosu, + sinv, + cosv * sinu); + texCoordStream.addElement(uu / tubeLengthSubdivisions, + vv / circleSubdivisions); + } + } + + for (var uu = 0; uu < tubeLengthSubdivisions; ++uu) { + for (var vv = 0; vv < circleSubdivisions; ++vv) { + // We want to wrap the indices around at the seams. + var uuPlusOne = (uu + 1) % tubeLengthSubdivisions; + var vvPlusOne = (vv + 1) % circleSubdivisions; + // The indices of four points forming a quad. + var a = circleSubdivisions * uu + vv; + var b = circleSubdivisions * uuPlusOne + vv; + var c = circleSubdivisions * uu + vvPlusOne; + var d = circleSubdivisions * uuPlusOne + vvPlusOne; + vertexInfo.addTriangle(a, d, b); + vertexInfo.addTriangle(a, c, d); + } + } + + if (opt_matrix) { + vertexInfo.reorient(opt_matrix); + } + return vertexInfo; +}; + +/** + * Creates a torus shape. The torus will be created centered about the + * origin, with the y axis as its vertical axis. The created torus has + * position, normal and uv streams. + * + * @param {!o3d.Pack} pack Pack in which to create the torus. + * @param {!o3d.Material} material to use. + * @param {number} torusRadius Distance from the center of the tube to + * the center of the torus. + * @param {number} tubeRadius Radius of the tube. + * @param {number} tubeLengthSubdivisions The number of subdivisions around the + * vertical axis of the torus, i.e. along the length of the tube. + * @param {number} circleSubdivisions The number of subdivisions in the circle + * that is rotated about the vertical axis to create the torus. + * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply + * all the vertices. + * @return {!o3d.Shape} The created torus. + */ +o3djs.primitives.createTorus = function(pack, + material, + torusRadius, + tubeRadius, + tubeLengthSubdivisions, + circleSubdivisions, + opt_matrix) { + var vertexInfo = o3djs.primitives.createTorusVertices( + torusRadius, + tubeRadius, + tubeLengthSubdivisions, + circleSubdivisions, + opt_matrix); + return vertexInfo.createShape(pack, material); +}; + +/** * Creates wedge vertices, wedge being an extruded triangle. The wedge will be * created around the 3 2d points passed in and extruded along the z axis. The * created wedge has position, normal and uv streams. @@ -1407,7 +1515,7 @@ o3djs.primitives.createTruncatedCone = function(pack, * @param {number} depth The depth to extrude the triangle. * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply * all the vertices. - * @return {!o3djs.primitives.VertexInfo} The created cylinder vertices. + * @return {!o3djs.primitives.VertexInfo} The created wedge vertices. */ o3djs.primitives.createWedgeVertices = function(inPoints, depth, opt_matrix) { @@ -1424,7 +1532,6 @@ o3djs.primitives.createWedgeVertices = function(inPoints, depth, var z1 = -depth * 0.5; var z2 = depth * 0.5; var face = []; - var indices = []; var points = [[inPoints[0][0], inPoints[0][1]], [inPoints[1][0], inPoints[1][1]], [inPoints[2][0], inPoints[2][1]]]; @@ -1506,14 +1613,14 @@ o3djs.primitives.createWedgeVertices = function(inPoints, depth, normalStream.addElement(face[2][0], face[2][1], face[2][2]); texCoordStream.addElement(1, 1); - var indices = [0, 2, 1, - 3, 4, 5, - 6, 7, 8, - 6, 8, 9, - 10, 11, 12, - 10, 12, 13, - 14, 15, 16, - 14, 16, 17]; + vertexInfo.addTriangle(0, 2, 1); + vertexInfo.addTriangle(3, 4, 5); + vertexInfo.addTriangle(6, 7, 8); + vertexInfo.addTriangle(6, 8, 9); + vertexInfo.addTriangle(10, 11, 12); + vertexInfo.addTriangle(10, 12, 13); + vertexInfo.addTriangle(14, 15, 16); + vertexInfo.addTriangle(14, 16, 17); if (opt_matrix) { vertexInfo.reorient(opt_matrix); @@ -1559,10 +1666,10 @@ o3djs.primitives.createWedge = function(pack, * * @param {!Array.<!Array.<number>>} points Array of 2d points in the format * [[x1, y1], [x2, y2], [x3, y3],...] that describe a 2d polygon. - * @param {number} depth The depth to extrude the triangle. + * @param {number} depth The depth to extrude the polygon. * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply * all the vertices. - * @return {!o3djs.primitives.VertexInfo} The created cylinder vertices. + * @return {!o3djs.primitives.VertexInfo} The created prism vertices. */ o3djs.primitives.createPrismVertices = function(points, depth, @@ -1690,10 +1797,10 @@ o3djs.primitives.createPrismVertices = function(points, * @param {!o3d.Material} material to use. * @param {!Array.<!Array.<number>>} points Array of 2d points in the format: * [[x1, y1], [x2, y2], [x3, y3],...] that describe a 2d polygon. - * @param {number} depth The depth to extrude the triangle. + * @param {number} depth The depth to extrude the polygon. * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply * all the vertices. - * @return {!o3d.Shape} The created wedge. + * @return {!o3d.Shape} The created prism. */ o3djs.primitives.createPrism = function(pack, material, |