159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/* 259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Copyright (c) 2009-2010 jMonkeyEngine 359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * All rights reserved. 459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Redistribution and use in source and binary forms, with or without 659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * modification, are permitted provided that the following conditions are 759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * met: 859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions of source code must retain the above copyright 1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * notice, this list of conditions and the following disclaimer. 1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions in binary form must reproduce the above copyright 1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * notice, this list of conditions and the following disclaimer in the 1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * documentation and/or other materials provided with the distribution. 1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * may be used to endorse or promote products derived from this software 1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * without specific prior written permission. 1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// $Id: Cylinder.java 4131 2009-03-19 20:15:28Z blaine.dev $ 3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.scene.shape; 3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.InputCapsule; 3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.JmeExporter; 3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.JmeImporter; 3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.OutputCapsule; 4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.FastMath; 4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Vector3f; 4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Mesh; 4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.VertexBuffer.Type; 4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.mesh.IndexBuffer; 4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.BufferUtils; 4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport static com.jme3.util.BufferUtils.*; 4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.io.IOException; 4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.nio.FloatBuffer; 4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/** 5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * A simple cylinder, defined by it's height and radius. 5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (Ported to jME3) 5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Mark Powell 5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @version $Revision: 4131 $, $Date: 2009-03-19 16:15:28 -0400 (Thu, 19 Mar 2009) $ 5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class Cylinder extends Mesh { 5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private int axisSamples; 6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private int radialSamples; 6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private float radius; 6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private float radius2; 6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private float height; 6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private boolean closed; 6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private boolean inverted; 6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Default constructor for serialization only. Do not use. 7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Cylinder() { 7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Creates a new Cylinder. By default its center is the origin. Usually, a 7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * higher sample number creates a better looking cylinder, but at the cost 7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * of more vertex information. 8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param axisSamples 8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Number of triangle samples along the axis. 8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param radialSamples 8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Number of triangle samples along the radial. 8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param radius 8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * The radius of the cylinder. 8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param height 8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * The cylinder's height. 8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Cylinder(int axisSamples, int radialSamples, 9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float radius, float height) { 9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this(axisSamples, radialSamples, radius, height, false); 9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Creates a new Cylinder. By default its center is the origin. Usually, a 9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * higher sample number creates a better looking cylinder, but at the cost 9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * of more vertex information. <br> 9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * If the cylinder is closed the texture is split into axisSamples parts: 10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * top most and bottom most part is used for top and bottom of the cylinder, 10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * rest of the texture for the cylinder wall. The middle of the top is 10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * mapped to texture coordinates (0.5, 1), bottom to (0.5, 0). Thus you need 10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * a suited distorted texture. 10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param axisSamples 10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Number of triangle samples along the axis. 10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param radialSamples 10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Number of triangle samples along the radial. 10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param radius 11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * The radius of the cylinder. 11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param height 11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * The cylinder's height. 11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param closed 11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * true to create a cylinder with top and bottom surface 11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Cylinder(int axisSamples, int radialSamples, 11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float radius, float height, boolean closed) { 11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this(axisSamples, radialSamples, radius, height, closed, false); 11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Creates a new Cylinder. By default its center is the origin. Usually, a 12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * higher sample number creates a better looking cylinder, but at the cost 12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * of more vertex information. <br> 12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * If the cylinder is closed the texture is split into axisSamples parts: 12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * top most and bottom most part is used for top and bottom of the cylinder, 12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * rest of the texture for the cylinder wall. The middle of the top is 12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * mapped to texture coordinates (0.5, 1), bottom to (0.5, 0). Thus you need 12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * a suited distorted texture. 13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param axisSamples 13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Number of triangle samples along the axis. 13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param radialSamples 13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Number of triangle samples along the radial. 13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param radius 13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * The radius of the cylinder. 13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param height 13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * The cylinder's height. 13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param closed 14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * true to create a cylinder with top and bottom surface 14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param inverted 14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * true to create a cylinder that is meant to be viewed from the 14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * interior. 14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Cylinder(int axisSamples, int radialSamples, 14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float radius, float height, boolean closed, boolean inverted) { 14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this(axisSamples, radialSamples, radius, radius, height, closed, inverted); 14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Cylinder(int axisSamples, int radialSamples, 15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float radius, float radius2, float height, boolean closed, boolean inverted) { 15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super(); 15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta updateGeometry(axisSamples, radialSamples, radius, radius2, height, closed, inverted); 15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return the number of samples along the cylinder axis 15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public int getAxisSamples() { 16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return axisSamples; 16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return Returns the height. 16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public float getHeight() { 16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return height; 16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return number of samples around cylinder 17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public int getRadialSamples() { 17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return radialSamples; 17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return Returns the radius. 17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public float getRadius() { 18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return radius; 18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public float getRadius2() { 18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return radius2; 18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return true if end caps are used. 19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public boolean isClosed() { 19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return closed; 19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return true if normals and uvs are created for interior use 19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public boolean isInverted() { 19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return inverted; 20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Rebuilds the cylinder based on a new set of parameters. 20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param axisSamples the number of samples along the axis. 20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param radialSamples the number of samples around the radial. 20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param radius the radius of the bottom of the cylinder. 20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param radius2 the radius of the top of the cylinder. 20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param height the cylinder's height. 21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param closed should the cylinder have top and bottom surfaces. 21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param inverted is the cylinder is meant to be viewed from the inside. 21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void updateGeometry(int axisSamples, int radialSamples, 21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float radius, float radius2, float height, boolean closed, boolean inverted) { 21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.axisSamples = axisSamples + (closed ? 2 : 0); 21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.radialSamples = radialSamples; 21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.radius = radius; 21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.radius2 = radius2; 21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.height = height; 22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.closed = closed; 22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.inverted = inverted; 22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// VertexBuffer pvb = getBuffer(Type.Position); 22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// VertexBuffer nvb = getBuffer(Type.Normal); 22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// VertexBuffer tvb = getBuffer(Type.TexCoord); 22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // Vertices 22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int vertCount = axisSamples * (radialSamples + 1) + (closed ? 2 : 0); 22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta setBuffer(Type.Position, 3, createVector3Buffer(getFloatBuffer(Type.Position), vertCount)); 23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // Normals 23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta setBuffer(Type.Normal, 3, createVector3Buffer(getFloatBuffer(Type.Normal), vertCount)); 23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // Texture co-ordinates 23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta setBuffer(Type.TexCoord, 2, createVector2Buffer(vertCount)); 23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int triCount = ((closed ? 2 : 0) + 2 * (axisSamples - 1)) * radialSamples; 23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta setBuffer(Type.Index, 3, createShortBuffer(getShortBuffer(Type.Index), 3 * triCount)); 24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // generate geometry 24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float inverseRadial = 1.0f / radialSamples; 24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float inverseAxisLess = 1.0f / (closed ? axisSamples - 3 : axisSamples - 1); 24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float inverseAxisLessTexture = 1.0f / (axisSamples - 1); 24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float halfHeight = 0.5f * height; 24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // Generate points on the unit circle to be used in computing the mesh 24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // points on a cylinder slice. 25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float[] sin = new float[radialSamples + 1]; 25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float[] cos = new float[radialSamples + 1]; 25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int radialCount = 0; radialCount < radialSamples; radialCount++) { 25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float angle = FastMath.TWO_PI * inverseRadial * radialCount; 25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta cos[radialCount] = FastMath.cos(angle); 25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta sin[radialCount] = FastMath.sin(angle); 25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta sin[radialSamples] = sin[0]; 25959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta cos[radialSamples] = cos[0]; 26059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // calculate normals 26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f[] vNormals = null; 26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f vNormal = Vector3f.UNIT_Z; 26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 26559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if ((height != 0.0f) && (radius != radius2)) { 26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vNormals = new Vector3f[radialSamples]; 26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f vHeight = Vector3f.UNIT_Z.mult(height); 26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f vRadial = new Vector3f(); 26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int radialCount = 0; radialCount < radialSamples; radialCount++) { 27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vRadial.set(cos[radialCount], sin[radialCount], 0.0f); 27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f vRadius = vRadial.mult(radius); 27359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f vRadius2 = vRadial.mult(radius2); 27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f vMantle = vHeight.subtract(vRadius2.subtract(vRadius)); 27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f vTangent = vRadial.cross(Vector3f.UNIT_Z); 27659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vNormals[radialCount] = vMantle.cross(vTangent).normalize(); 27759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 27859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 27959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 28059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta FloatBuffer nb = getFloatBuffer(Type.Normal); 28159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta FloatBuffer pb = getFloatBuffer(Type.Position); 28259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta FloatBuffer tb = getFloatBuffer(Type.TexCoord); 28359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 28459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // generate the cylinder itself 28559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f tempNormal = new Vector3f(); 28659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int axisCount = 0, i = 0; axisCount < axisSamples; axisCount++, i++) { 28759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float axisFraction; 28859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float axisFractionTexture; 28959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int topBottom = 0; 29059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (!closed) { 29159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta axisFraction = axisCount * inverseAxisLess; // in [0,1] 29259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta axisFractionTexture = axisFraction; 29359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 29459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (axisCount == 0) { 29559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta topBottom = -1; // bottom 29659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta axisFraction = 0; 29759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta axisFractionTexture = inverseAxisLessTexture; 29859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (axisCount == axisSamples - 1) { 29959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta topBottom = 1; // top 30059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta axisFraction = 1; 30159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta axisFractionTexture = 1 - inverseAxisLessTexture; 30259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 30359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta axisFraction = (axisCount - 1) * inverseAxisLess; 30459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta axisFractionTexture = axisCount * inverseAxisLessTexture; 30559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 30659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 30759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 30859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // compute center of slice 30959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float z = -halfHeight + height * axisFraction; 31059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f sliceCenter = new Vector3f(0, 0, z); 31159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 31259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // compute slice vertices with duplication at end point 31359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int save = i; 31459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int radialCount = 0; radialCount < radialSamples; radialCount++, i++) { 31559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float radialFraction = radialCount * inverseRadial; // in [0,1) 31659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tempNormal.set(cos[radialCount], sin[radialCount], 0.0f); 31759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 31859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (vNormals != null) { 31959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vNormal = vNormals[radialCount]; 32059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (radius == radius2) { 32159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vNormal = tempNormal; 32259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 32359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 32459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (topBottom == 0) { 32559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (!inverted) 32659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta nb.put(vNormal.x).put(vNormal.y).put(vNormal.z); 32759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta else 32859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta nb.put(-vNormal.x).put(-vNormal.y).put(-vNormal.z); 32959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 33059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta nb.put(0).put(0).put(topBottom * (inverted ? -1 : 1)); 33159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 33259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 33359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tempNormal.multLocal((radius - radius2) * axisFraction + radius2) 33459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta .addLocal(sliceCenter); 33559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta pb.put(tempNormal.x).put(tempNormal.y).put(tempNormal.z); 33659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 33759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tb.put((inverted ? 1 - radialFraction : radialFraction)) 33859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta .put(axisFractionTexture); 33959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 34059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 34159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BufferUtils.copyInternalVector3(pb, save, i); 34259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BufferUtils.copyInternalVector3(nb, save, i); 34359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 34459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tb.put((inverted ? 0.0f : 1.0f)) 34559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta .put(axisFractionTexture); 34659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 34759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 34859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (closed) { 34959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta pb.put(0).put(0).put(-halfHeight); // bottom center 35059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta nb.put(0).put(0).put(-1 * (inverted ? -1 : 1)); 35159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tb.put(0.5f).put(0); 35259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta pb.put(0).put(0).put(halfHeight); // top center 35359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta nb.put(0).put(0).put(1 * (inverted ? -1 : 1)); 35459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tb.put(0.5f).put(1); 35559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 35659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 35759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta IndexBuffer ib = getIndexBuffer(); 35859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int index = 0; 35959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // Connectivity 36059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int axisCount = 0, axisStart = 0; axisCount < axisSamples - 1; axisCount++) { 36159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int i0 = axisStart; 36259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int i1 = i0 + 1; 36359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta axisStart += radialSamples + 1; 36459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int i2 = axisStart; 36559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int i3 = i2 + 1; 36659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int i = 0; i < radialSamples; i++) { 36759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (closed && axisCount == 0) { 36859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (!inverted) { 36959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ib.put(index++, i0++); 37059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ib.put(index++, vertCount - 2); 37159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ib.put(index++, i1++); 37259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 37359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ib.put(index++, i0++); 37459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ib.put(index++, i1++); 37559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ib.put(index++, vertCount - 2); 37659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 37759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (closed && axisCount == axisSamples - 2) { 37859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ib.put(index++, i2++); 37959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ib.put(index++, inverted ? vertCount - 1 : i3++); 38059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ib.put(index++, inverted ? i3++ : vertCount - 1); 38159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 38259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ib.put(index++, i0++); 38359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ib.put(index++, inverted ? i2 : i1); 38459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ib.put(index++, inverted ? i1 : i2); 38559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ib.put(index++, i1++); 38659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ib.put(index++, inverted ? i2++ : i3++); 38759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ib.put(index++, inverted ? i3++ : i2++); 38859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 38959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 39059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 39159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 39259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta updateBound(); 39359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 39459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 39559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void read(JmeImporter e) throws IOException { 39659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super.read(e); 39759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta InputCapsule capsule = e.getCapsule(this); 39859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta axisSamples = capsule.readInt("axisSamples", 0); 39959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta radialSamples = capsule.readInt("radialSamples", 0); 40059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta radius = capsule.readFloat("radius", 0); 40159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta radius2 = capsule.readFloat("radius2", 0); 40259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta height = capsule.readFloat("height", 0); 40359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta closed = capsule.readBoolean("closed", false); 40459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta inverted = capsule.readBoolean("inverted", false); 40559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 40659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 40759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void write(JmeExporter e) throws IOException { 40859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super.write(e); 40959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta OutputCapsule capsule = e.getCapsule(this); 41059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta capsule.write(axisSamples, "axisSamples", 0); 41159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta capsule.write(radialSamples, "radialSamples", 0); 41259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta capsule.write(radius, "radius", 0); 41359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta capsule.write(radius2, "radius2", 0); 41459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta capsule.write(height, "height", 0); 41559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta capsule.write(closed, "closed", false); 41659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta capsule.write(inverted, "inverted", false); 41759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 41859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 41959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 42059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta} 421