📄 cone.java
字号:
/* * $RCSfile: Cone.java,v $ * * Copyright (c) 2007 Sun Microsystems, 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: * * - Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistribution 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 Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed, licensed or * intended for use in the design, construction, operation or * maintenance of any nuclear facility. * * $Revision: 1.6 $ * $Date: 2007/04/24 18:50:59 $ * $State: Exp $ */package com.sun.j3d.utils.geometry;import com.sun.j3d.utils.geometry.*;import java.io.*;import java.util.*;import javax.media.j3d.*;import javax.vecmath.*;/** * Cone is a geometry primitive defined with a radius and a height. * It is a capped cone centered at the origin with its central axis * aligned along the Y-axis. The center of the cone is defined to be * the center of its bounding box (rather than its centroid). * <p> * If the GENERATE_TEXTURE_COORDS flag is set, the texture coordinates * are generated such that the texture gets mapped onto the cone similarly * to how it gets mapped onto a cylinder, the difference being the top * cap is nonexistent. * <p> * By default all primitives with the same parameters share their * geometry (e.g., you can have 50 shperes in your scene, but the * geometry is stored only once). A change to one primitive will * effect all shared nodes. Another implication of this * implementation is that the capabilities of the geometry are shared, * and once one of the shared nodes is live, the capabilities cannot * be set. Use the GEOMETRY_NOT_SHARED flag if you do not wish to * share geometry among primitives with the same parameters. */public class Cone extends Primitive { float radius, height; int xdivisions, ydivisions; static final int MID_REZ_DIV_X = 15; static final int MID_REZ_DIV_Y = 1; /** * Designates the body of the cone. Used by <code>getShape</code>. * * @see Cone#getShape */ public static final int BODY = 0; /** * Designates the end-cap of the cone. Used by <code>getShape</code>. * * @see Cone#getShape */ public static final int CAP = 1; /** * Constructs a default Cone of radius of 1.0 and height * of 2.0. Resolution defaults to 15 divisions along X and axis * and 1 along the Y axis. Normals are generated, texture * coordinates are not. */ public Cone(){ this(1.0f, 2.0f, GENERATE_NORMALS, MID_REZ_DIV_X, MID_REZ_DIV_Y, null); } /** * * Constructs a default Cone of a given radius and height. Normals * are generated, texture coordinates are not. * @param radius Radius * @param height Height */ public Cone (float radius, float height) { this(radius, height, GENERATE_NORMALS, MID_REZ_DIV_X, MID_REZ_DIV_Y, null); } /** * * Constructs a default cone of a given radius, height, * and appearance. Normals are generated, texture coordinates are not. * @param radius Radius * @param height Height * @param ap Appearance * * @since Java 3D 1.2.1 */ public Cone (float radius, float height, Appearance ap) { this(radius, height, GENERATE_NORMALS, MID_REZ_DIV_X, MID_REZ_DIV_Y, ap); } /** * * Constructs a default cone of a given radius, height, * primitive flags, and appearance. * @param radius Radius * @param height Height * @param primflags Primitive flags * @param ap Appearance */ public Cone (float radius, float height, int primflags, Appearance ap) { this(radius, height, primflags, MID_REZ_DIV_X, MID_REZ_DIV_Y, ap); } /** * Obtains the Shape3D node associated with one of the parts of the * cone (the body or the cap). This allows users to modify the appearance * or geometry of individual parts. * @param partId The part to return (BODY or CAP). * @return The Shape3D object associated with the partId. If an * invalid partId is passed in, null is returned. */ public Shape3D getShape(int partId){ if (partId > CAP || partId < BODY) return null; return (Shape3D)getChild(partId); } /** * Sets appearance of the cone. This will set each part of the * cone (cap & body) to the same appearance. To set each * part's appearance separately, use getShape(partId) to get the * individual shape and call shape.setAppearance(ap). */ public void setAppearance(Appearance ap){ ((Shape3D)getChild(BODY)).setAppearance(ap); ((Shape3D)getChild(CAP)).setAppearance(ap); } /** * Gets the appearance of the specified part of the cone. * * @param partId identifier for a given subpart of the cone * * @return The appearance object associated with the partID. If an * invalid partId is passed in, null is returned. * * @since Java 3D 1.2.1 */ public Appearance getAppearance(int partId) { if (partId > CAP || partId < BODY) return null; return getShape(partId).getAppearance(); } /** * Constructs a customized Cone of a given radius, height, flags, * resolution (X and Y dimensions), and appearance. The * resolution is defined in terms of number of subdivisions * along the object's X axis (width) and Y axis (height). More divisions * lead to finer tesselated objects. * <p> * If appearance is null, the default white appearance will be used. * @param radius Radius * @param height Height * @param xdivision Number of divisions along X direction. * @param ydivision Number of divisions along the height of cone. * @param primflags flags * @param ap Appearance */ public Cone(float radius, float height, int primflags, int xdivision, int ydivision, Appearance ap) { super(); Shape3D shape[] = new Shape3D[2]; this.radius = radius; this.height = height; xdivisions = xdivision; ydivisions = ydivision; flags = primflags; boolean outside = (flags & GENERATE_NORMALS_INWARD) == 0; boolean texCoordYUp = (flags & GENERATE_TEXTURE_COORDS_Y_UP) != 0; Quadrics q = new Quadrics(); GeomBuffer gbuf = null; GeomBuffer cache = getCachedGeometry(Primitive.CONE, radius, 0.0f, height, xdivision, ydivision, primflags); if (cache != null){// System.out.println("using cached geometry"); shape[BODY] = new Shape3D(cache.getComputedGeometry()); numVerts += cache.getNumVerts(); numTris += cache.getNumTris(); } else { // the body of the cone consists of the top of the cone and if // ydivisions is greater than 1, the body of the cone. gbuf = q.coneTop((double)(height/2.0 - height/ydivisions), (double)(radius/ydivisions), height/ydivisions, xdivisions, 1.0-1.0/(double)ydivisions, outside, texCoordYUp); shape[BODY] = new Shape3D(gbuf.getGeom(flags)); numVerts += gbuf.getNumVerts(); numTris += gbuf.getNumTris(); if ((primflags & Primitive.GEOMETRY_NOT_SHARED) == 0) { cacheGeometry(Primitive.CONE, radius, 0.0f, height, xdivision, ydivision, primflags, gbuf); } } // only need to add a body if the ydivisions is greater than 1 if (ydivisions > 1) { cache = getCachedGeometry(Primitive.CONE_DIVISIONS, radius, 0.0f, height, xdivision, ydivision, primflags); if (cache != null) {// System.out.println("using cached divisions"); shape[BODY].addGeometry(cache.getComputedGeometry()); numVerts += cache.getNumVerts(); numTris += cache.getNumTris(); } else { gbuf = q.coneBody(-(double)(height/2.0), (double)(height/2.0-height/ydivisions), (double)radius, (double)(radius/ydivisions), xdivisions, ydivisions-1, 1.0/(double)ydivisions, outside, texCoordYUp); shape[BODY].addGeometry(gbuf.getGeom(flags)); numVerts += gbuf.getNumVerts(); numTris += gbuf.getNumTris(); if ((primflags & Primitive.GEOMETRY_NOT_SHARED) == 0) { cacheGeometry(Primitive.CONE_DIVISIONS, radius, 0.0f, height, xdivision, ydivision, primflags, gbuf); } } } if ((flags & ENABLE_APPEARANCE_MODIFY) != 0) { (shape[BODY]).setCapability(Shape3D.ALLOW_APPEARANCE_READ); (shape[BODY]).setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); } if ((flags & ENABLE_GEOMETRY_PICKING) != 0) { (shape[BODY]).setCapability(Shape3D.ALLOW_GEOMETRY_READ); } this.addChild(shape[BODY]); // Create bottom cap. cache = getCachedGeometry(Primitive.BOTTOM_DISK, radius, radius, -height/2.0f, xdivision, xdivision, primflags); if (cache != null) {// System.out.println("using cached bottom"); shape[CAP] = new Shape3D(cache.getComputedGeometry()); numVerts += cache.getNumVerts(); numTris += cache.getNumTris(); } else { gbuf = q.disk((double)radius, xdivision, -(double)height/2.0, !outside, texCoordYUp); shape[CAP] = new Shape3D(gbuf.getGeom(flags)); numVerts += gbuf.getNumVerts(); numTris += gbuf.getNumTris(); if ((primflags & Primitive.GEOMETRY_NOT_SHARED) == 0) { cacheGeometry(Primitive.BOTTOM_DISK, radius, radius, -height/2.0f, xdivision, xdivision, primflags, gbuf); } } if ((flags & ENABLE_APPEARANCE_MODIFY) != 0) { (shape[CAP]).setCapability(Shape3D.ALLOW_APPEARANCE_READ); (shape[CAP]).setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); } if ((flags & ENABLE_GEOMETRY_PICKING) != 0) { (shape[CAP]).setCapability(Shape3D.ALLOW_GEOMETRY_READ); }// Transform3D t2 = new Transform3D(); // Flip it to match up the texture coords./* This causes the bottom not to match up for odd xdivision values objectMat = new Matrix4d(); objectMat.setIdentity(); rotMat = new Matrix4d(); rotMat.setIdentity(); rotMat.rotZ(Math.PI); objectMat.mul(objectMat, rotMat); t2.set(objectMat);*/ this.addChild(shape[CAP]); if (ap == null){ setAppearance(); } else setAppearance(ap); } /** * Used to create a new instance of the node. This routine is called * by <code>cloneTree</code> to duplicate the current node. * <code>cloneNode</code> should be overridden by any user subclassed * objects. All subclasses must have their <code>cloneNode</code> * method consist of the following lines: * <P><blockquote><pre> * public Node cloneNode(boolean forceDuplicate) { * UserSubClass usc = new UserSubClass(); * usc.duplicateNode(this, forceDuplicate); * return usc; * } * </pre></blockquote> * @param forceDuplicate when set to <code>true</code>, causes the * <code>duplicateOnCloneTree</code> flag to be ignored. When * <code>false</code>, the value of each node's * <code>duplicateOnCloneTree</code> variable determines whether * NodeComponent data is duplicated or copied. * * @see Node#cloneTree * @see Node#duplicateNode * @see NodeComponent#setDuplicateOnCloneTree */ public Node cloneNode(boolean forceDuplicate) { Cone c = new Cone(radius, height, flags, xdivisions, ydivisions, getAppearance()); c.duplicateNode(this, forceDuplicate); return c; } /** * Copies all node information from <code>originalNode</code> into * the current node. This method is called from the * <code>cloneNode</code> method which is, in turn, called by the * <code>cloneTree</code> method. * <P> * For any <i>NodeComponent</i> objects * contained by the object being duplicated, each <i>NodeComponent</i> * object's <code>duplicateOnCloneTree</code> value is used to determine * whether the <i>NodeComponent</i> should be duplicated in the new node * or if just a reference to the current node should be placed in the * new node. This flag can be overridden by setting the * <code>forceDuplicate</code> parameter in the <code>cloneTree</code> * method to <code>true</code>. * * @param originalNode the original node to duplicate. * @param forceDuplicate when set to <code>true</code>, causes the * <code>duplicateOnCloneTree</code> flag to be ignored. When * <code>false</code>, the value of each node's * <code>duplicateOnCloneTree</code> variable determines whether * NodeComponent data is duplicated or copied. * * @see Node#cloneTree * @see Node#cloneNode * @see NodeComponent#setDuplicateOnCloneTree */ public void duplicateNode(Node originalNode, boolean forceDuplicate) { super.duplicateNode(originalNode, forceDuplicate); } /** * Returns the radius of the cone * * @since Java 3D 1.2.1 */ public float getRadius() { return radius; } /** * Returns the height of the cone * * @since Java 3D 1.2.1 */ public float getHeight() { return height; } /** * Returns the number divisions along the X direction * * @since Java 3D 1.2.1 */ public int getXdivisions() { return xdivisions; } /** * Returns the number of divisions along the height of the cone * * @since Java 3D 1.2.1 */ public int getYdivisions() { return ydivisions; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -