|
@@ -32,20 +32,11 @@
|
|
// $Id: Cylinder.java 4131 2009-03-19 20:15:28Z blaine.dev $
|
|
// $Id: Cylinder.java 4131 2009-03-19 20:15:28Z blaine.dev $
|
|
package com.jme3.scene.debug.custom;
|
|
package com.jme3.scene.debug.custom;
|
|
|
|
|
|
-import com.jme3.export.InputCapsule;
|
|
|
|
-import com.jme3.export.JmeExporter;
|
|
|
|
-import com.jme3.export.JmeImporter;
|
|
|
|
-import com.jme3.export.OutputCapsule;
|
|
|
|
-import com.jme3.math.FastMath;
|
|
|
|
-import com.jme3.math.Vector3f;
|
|
|
|
-import com.jme3.scene.Mesh;
|
|
|
|
|
|
+import com.jme3.math.*;
|
|
import com.jme3.scene.VertexBuffer.Type;
|
|
import com.jme3.scene.VertexBuffer.Type;
|
|
-import com.jme3.scene.mesh.IndexBuffer;
|
|
|
|
|
|
+import com.jme3.scene.shape.AbstractBox;
|
|
import com.jme3.util.BufferUtils;
|
|
import com.jme3.util.BufferUtils;
|
|
|
|
|
|
-import static com.jme3.util.BufferUtils.*;
|
|
|
|
-
|
|
|
|
-import java.io.IOException;
|
|
|
|
import java.nio.FloatBuffer;
|
|
import java.nio.FloatBuffer;
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -55,362 +46,125 @@ import java.nio.FloatBuffer;
|
|
* @author Mark Powell
|
|
* @author Mark Powell
|
|
* @version $Revision: 4131 $, $Date: 2009-03-19 16:15:28 -0400 (Thu, 19 Mar 2009) $
|
|
* @version $Revision: 4131 $, $Date: 2009-03-19 16:15:28 -0400 (Thu, 19 Mar 2009) $
|
|
*/
|
|
*/
|
|
-public class BoneShape extends Mesh {
|
|
|
|
-
|
|
|
|
- private int axisSamples;
|
|
|
|
-
|
|
|
|
- private int radialSamples;
|
|
|
|
-
|
|
|
|
- private float radius;
|
|
|
|
- private float radius2;
|
|
|
|
-
|
|
|
|
- private float height;
|
|
|
|
- private boolean closed;
|
|
|
|
- private boolean inverted;
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Default constructor for serialization only. Do not use.
|
|
|
|
- */
|
|
|
|
- public BoneShape() {
|
|
|
|
|
|
+public class BoneShape extends AbstractBox {
|
|
|
|
+
|
|
|
|
+ private static Vector3f topN = new Vector3f(0, 1, 0);
|
|
|
|
+ private static Vector3f botN = new Vector3f(0, -1, 0);
|
|
|
|
+ private static Vector3f rigN = new Vector3f(1, 0, 0);
|
|
|
|
+ private static Vector3f lefN = new Vector3f(-1, 0, 0);
|
|
|
|
+
|
|
|
|
+ static {
|
|
|
|
+ Quaternion q = new Quaternion().fromAngleAxis(-FastMath.PI / 16f, Vector3f.UNIT_X);
|
|
|
|
+ q.multLocal(topN);
|
|
|
|
+ q.inverseLocal();
|
|
|
|
+ q.multLocal(botN);
|
|
|
|
+ q = new Quaternion().fromAngleAxis(FastMath.PI / 16f, Vector3f.UNIT_Y);
|
|
|
|
+ q.multLocal(rigN);
|
|
|
|
+ q.inverseLocal();
|
|
|
|
+ q.multLocal(lefN);
|
|
}
|
|
}
|
|
|
|
|
|
- /**
|
|
|
|
- * Creates a new Cylinder. By default its center is the origin. Usually, a
|
|
|
|
- * higher sample number creates a better looking cylinder, but at the cost
|
|
|
|
- * of more vertex information.
|
|
|
|
- *
|
|
|
|
- * @param axisSamples Number of triangle samples along the axis.
|
|
|
|
- * @param radialSamples Number of triangle samples along the radial.
|
|
|
|
- * @param radius The radius of the cylinder.
|
|
|
|
- * @param height The cylinder's height.
|
|
|
|
- */
|
|
|
|
- public BoneShape(int axisSamples, int radialSamples,
|
|
|
|
- float radius, float height) {
|
|
|
|
- this(axisSamples, radialSamples, radius, height, false);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Creates a new Cylinder. By default its center is the origin. Usually, a
|
|
|
|
- * higher sample number creates a better looking cylinder, but at the cost
|
|
|
|
- * of more vertex information. <br>
|
|
|
|
- * If the cylinder is closed the texture is split into axisSamples parts:
|
|
|
|
- * top most and bottom most part is used for top and bottom of the cylinder,
|
|
|
|
- * rest of the texture for the cylinder wall. The middle of the top is
|
|
|
|
- * mapped to texture coordinates (0.5, 1), bottom to (0.5, 0). Thus you need
|
|
|
|
- * a suited distorted texture.
|
|
|
|
- *
|
|
|
|
- * @param axisSamples Number of triangle samples along the axis.
|
|
|
|
- * @param radialSamples Number of triangle samples along the radial.
|
|
|
|
- * @param radius The radius of the cylinder.
|
|
|
|
- * @param height The cylinder's height.
|
|
|
|
- * @param closed true to create a cylinder with top and bottom surface
|
|
|
|
- */
|
|
|
|
- public BoneShape(int axisSamples, int radialSamples,
|
|
|
|
- float radius, float height, boolean closed) {
|
|
|
|
- this(axisSamples, radialSamples, radius, height, closed, false);
|
|
|
|
- }
|
|
|
|
|
|
+ private static final short[] GEOMETRY_INDICES_DATA = {
|
|
|
|
+ 2, 1, 0, 3, 2, 0, // back
|
|
|
|
+ 6, 5, 4, 7, 6, 4, // right
|
|
|
|
+ 10, 9, 8, 11, 10, 8, // front
|
|
|
|
+ 14, 13, 12, 15, 14, 12, // left
|
|
|
|
+ 18, 17, 16, 19, 18, 16, // top
|
|
|
|
+ 22, 21, 20, 23, 22, 20 // bottom
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ private static final float[] GEOMETRY_NORMALS_DATA = {
|
|
|
|
+ 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, // back
|
|
|
|
+ rigN.x, rigN.y, rigN.z, rigN.x, rigN.y, rigN.z, rigN.x, rigN.y, rigN.z, rigN.x, rigN.y, rigN.z, // right
|
|
|
|
+ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // front
|
|
|
|
+ lefN.x, lefN.y, lefN.z, lefN.x, lefN.y, lefN.z, lefN.x, lefN.y, lefN.z, lefN.x, lefN.y, lefN.z, // left
|
|
|
|
+ topN.x, topN.y, topN.z, topN.x, topN.y, topN.z, topN.x, topN.y, topN.z, topN.x, topN.y, topN.z, // top
|
|
|
|
+ botN.x, botN.y, botN.z, botN.x, botN.y, botN.z, botN.x, botN.y, botN.z, botN.x, botN.y, botN.z // bottom
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ private static final float[] GEOMETRY_TEXTURE_DATA = {
|
|
|
|
+ 1, 0, 0, 0, 0, 1, 1, 1, // back
|
|
|
|
+ 1, 0, 0, 0, 0, 1, 1, 1, // right
|
|
|
|
+ 1, 0, 0, 0, 0, 1, 1, 1, // front
|
|
|
|
+ 1, 0, 0, 0, 0, 1, 1, 1, // left
|
|
|
|
+ 1, 0, 0, 0, 0, 1, 1, 1, // top
|
|
|
|
+ 1, 0, 0, 0, 0, 1, 1, 1 // bottom
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ private static final float[] GEOMETRY_POSITION_DATA = {
|
|
|
|
+ -0.5f, -0.5f, 0, 0.5f, -0.5f, 0, 0.5f, 0.5f, 0, -0.5f, 0.5f, 0, //back
|
|
|
|
+ 0.5f, -0.5f, 0, 0.25f, -0.25f, 1, 0.25f, 0.25f, 1, 0.5f, 0.5f, 0, //right
|
|
|
|
+ 0.25f, -0.25f, 1, -0.25f, -0.25f, 1, -0.25f, 0.25f, 1, 0.25f, 0.25f, 1, //front
|
|
|
|
+ -0.25f, -0.25f, 1, -0.5f, -0.5f, 0, -0.5f, 0.5f, 0, -0.25f, 0.25f, 1, //left
|
|
|
|
+ 0.5f, 0.5f, 0, 0.25f, 0.25f, 1, -0.25f, 0.25f, 1, -0.5f, 0.5f, 0, // top
|
|
|
|
+ -0.5f, -0.5f, 0, -0.25f, -0.25f, 1, 0.25f, -0.25f, 1, 0.5f, -0.5f, 0 // bottom
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ //0,1,2,3
|
|
|
|
+ //1,4,6,2
|
|
|
|
+ //4,5,7,6
|
|
|
|
+ //5,0,3,7,
|
|
|
|
+ //2,6,7,3
|
|
|
|
+ //0,5,4,1
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+// v[0].x, v[0].y, v[0].z, v[1].x, v[1].y, v[1].z, v[2].x, v[2].y, v[2].z, v[3].x, v[3].y, v[3].z, // back
|
|
|
|
+// v[1].x, v[1].y, v[1].z, v[4].x, v[4].y, v[4].z, v[6].x, v[6].y, v[6].z, v[2].x, v[2].y, v[2].z, // right
|
|
|
|
+// v[4].x, v[4].y, v[4].z, v[5].x, v[5].y, v[5].z, v[7].x, v[7].y, v[7].z, v[6].x, v[6].y, v[6].z, // front
|
|
|
|
+// v[5].x, v[5].y, v[5].z, v[0].x, v[0].y, v[0].z, v[3].x, v[3].y, v[3].z, v[7].x, v[7].y, v[7].z, // left
|
|
|
|
+// v[2].x, v[2].y, v[2].z, v[6].x, v[6].y, v[6].z, v[7].x, v[7].y, v[7].z, v[3].x, v[3].y, v[3].z, // top
|
|
|
|
+// v[0].x, v[0].y, v[0].z, v[5].x, v[5].y, v[5].z, v[4].x, v[4].y, v[4].z, v[1].x, v[1].y, v[1].z // bottom
|
|
|
|
|
|
/**
|
|
/**
|
|
- * Creates a new Cylinder. By default its center is the origin. Usually, a
|
|
|
|
- * higher sample number creates a better looking cylinder, but at the cost
|
|
|
|
- * of more vertex information. <br>
|
|
|
|
- * If the cylinder is closed the texture is split into axisSamples parts:
|
|
|
|
- * top most and bottom most part is used for top and bottom of the cylinder,
|
|
|
|
- * rest of the texture for the cylinder wall. The middle of the top is
|
|
|
|
- * mapped to texture coordinates (0.5, 1), bottom to (0.5, 0). Thus you need
|
|
|
|
- * a suited distorted texture.
|
|
|
|
|
|
+ * Creates a new box.
|
|
|
|
+ * <p>
|
|
|
|
+ * The box has a center of 0,0,0 and extends in the out from the center by
|
|
|
|
+ * the given amount in <em>each</em> direction. So, for example, a box
|
|
|
|
+ * with extent of 0.5 would be the unit cube.
|
|
*
|
|
*
|
|
- * @param axisSamples Number of triangle samples along the axis.
|
|
|
|
- * @param radialSamples Number of triangle samples along the radial.
|
|
|
|
- * @param radius The radius of the cylinder.
|
|
|
|
- * @param height The cylinder's height.
|
|
|
|
- * @param closed true to create a cylinder with top and bottom surface
|
|
|
|
- * @param inverted true to create a cylinder that is meant to be viewed from the
|
|
|
|
- * interior.
|
|
|
|
|
|
+ * @param x the size of the box along the x axis, in both directions.
|
|
|
|
+ * @param y the size of the box along the y axis, in both directions.
|
|
|
|
+ * @param z the size of the box along the z axis, in both directions.
|
|
*/
|
|
*/
|
|
- public BoneShape(int axisSamples, int radialSamples,
|
|
|
|
- float radius, float height, boolean closed, boolean inverted) {
|
|
|
|
- this(axisSamples, radialSamples, radius, radius, height, closed, inverted);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public BoneShape(int axisSamples, int radialSamples,
|
|
|
|
- float radius, float radius2, float height, boolean closed, boolean inverted) {
|
|
|
|
|
|
+ public BoneShape() {
|
|
super();
|
|
super();
|
|
- updateGeometry(axisSamples, radialSamples, radius, radius2, height, closed, inverted);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * @return the number of samples along the cylinder axis
|
|
|
|
- */
|
|
|
|
- public int getAxisSamples() {
|
|
|
|
- return axisSamples;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * @return Returns the height.
|
|
|
|
- */
|
|
|
|
- public float getHeight() {
|
|
|
|
- return height;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * @return number of samples around cylinder
|
|
|
|
- */
|
|
|
|
- public int getRadialSamples() {
|
|
|
|
- return radialSamples;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * @return Returns the radius.
|
|
|
|
- */
|
|
|
|
- public float getRadius() {
|
|
|
|
- return radius;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public float getRadius2() {
|
|
|
|
- return radius2;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * @return true if end caps are used.
|
|
|
|
- */
|
|
|
|
- public boolean isClosed() {
|
|
|
|
- return closed;
|
|
|
|
|
|
+ updateGeometry();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * @return true if normals and uvs are created for interior use
|
|
|
|
|
|
+ * Creates a clone of this box.
|
|
|
|
+ * <p>
|
|
|
|
+ * The cloned box will have '_clone' appended to it's name, but all other
|
|
|
|
+ * properties will be the same as this box.
|
|
*/
|
|
*/
|
|
- public boolean isInverted() {
|
|
|
|
- return inverted;
|
|
|
|
|
|
+ @Override
|
|
|
|
+ public BoneShape clone() {
|
|
|
|
+ return new BoneShape();
|
|
}
|
|
}
|
|
|
|
|
|
- /**
|
|
|
|
- * Rebuilds the cylinder based on a new set of parameters.
|
|
|
|
- *
|
|
|
|
- * @param axisSamples the number of samples along the axis.
|
|
|
|
- * @param radialSamples the number of samples around the radial.
|
|
|
|
- * @param radius the radius of the bottom of the cylinder.
|
|
|
|
- * @param radius2 the radius of the top of the cylinder.
|
|
|
|
- * @param height the cylinder's height.
|
|
|
|
- * @param closed should the cylinder have top and bottom surfaces.
|
|
|
|
- * @param inverted is the cylinder is meant to be viewed from the inside.
|
|
|
|
- */
|
|
|
|
- public void updateGeometry(int axisSamples, int radialSamples,
|
|
|
|
- float radius, float radius2, float height, boolean closed, boolean inverted) {
|
|
|
|
- this.axisSamples = axisSamples + (closed ? 2 : 0);
|
|
|
|
- this.radialSamples = radialSamples;
|
|
|
|
- this.radius = radius;
|
|
|
|
- this.radius2 = radius2;
|
|
|
|
- this.height = height;
|
|
|
|
- this.closed = closed;
|
|
|
|
- this.inverted = inverted;
|
|
|
|
-
|
|
|
|
-// VertexBuffer pvb = getBuffer(Type.Position);
|
|
|
|
-// VertexBuffer nvb = getBuffer(Type.Normal);
|
|
|
|
-// VertexBuffer tvb = getBuffer(Type.TexCoord);
|
|
|
|
-
|
|
|
|
- // Vertices
|
|
|
|
- int vertCount = axisSamples * (radialSamples + 1) + (closed ? 2 : 0);
|
|
|
|
-
|
|
|
|
- setBuffer(Type.Position, 3, createVector3Buffer(getFloatBuffer(Type.Position), vertCount));
|
|
|
|
-
|
|
|
|
- // Normals
|
|
|
|
- setBuffer(Type.Normal, 3, createVector3Buffer(getFloatBuffer(Type.Normal), vertCount));
|
|
|
|
-
|
|
|
|
- // Texture co-ordinates
|
|
|
|
- setBuffer(Type.TexCoord, 2, createVector2Buffer(vertCount));
|
|
|
|
-
|
|
|
|
- int triCount = ((closed ? 2 : 0) + 2 * (axisSamples - 1)) * radialSamples;
|
|
|
|
-
|
|
|
|
- setBuffer(Type.Index, 3, createShortBuffer(getShortBuffer(Type.Index), 3 * triCount));
|
|
|
|
-
|
|
|
|
- //Color
|
|
|
|
- setBuffer(Type.Color, 4, createFloatBuffer(vertCount * 4));
|
|
|
|
-
|
|
|
|
- // generate geometry
|
|
|
|
- float inverseRadial = 1.0f / radialSamples;
|
|
|
|
- float inverseAxisLess = 1.0f / (closed ? axisSamples - 3 : axisSamples - 1);
|
|
|
|
- float inverseAxisLessTexture = 1.0f / (axisSamples - 1);
|
|
|
|
- float halfHeight = 0.5f * height;
|
|
|
|
-
|
|
|
|
- // Generate points on the unit circle to be used in computing the mesh
|
|
|
|
- // points on a cylinder slice.
|
|
|
|
- float[] sin = new float[radialSamples + 1];
|
|
|
|
- float[] cos = new float[radialSamples + 1];
|
|
|
|
-
|
|
|
|
- for (int radialCount = 0; radialCount < radialSamples; radialCount++) {
|
|
|
|
- float angle = FastMath.TWO_PI * inverseRadial * radialCount;
|
|
|
|
- cos[radialCount] = FastMath.cos(angle);
|
|
|
|
- sin[radialCount] = FastMath.sin(angle);
|
|
|
|
- }
|
|
|
|
- sin[radialSamples] = sin[0];
|
|
|
|
- cos[radialSamples] = cos[0];
|
|
|
|
-
|
|
|
|
- // calculate normals
|
|
|
|
- Vector3f[] vNormals = null;
|
|
|
|
- Vector3f vNormal = Vector3f.UNIT_Z;
|
|
|
|
-
|
|
|
|
- if ((height != 0.0f) && (radius != radius2)) {
|
|
|
|
- vNormals = new Vector3f[radialSamples];
|
|
|
|
- Vector3f vHeight = Vector3f.UNIT_Z.mult(height);
|
|
|
|
- Vector3f vRadial = new Vector3f();
|
|
|
|
-
|
|
|
|
- for (int radialCount = 0; radialCount < radialSamples; radialCount++) {
|
|
|
|
- vRadial.set(cos[radialCount], sin[radialCount], 0.0f);
|
|
|
|
- Vector3f vRadius = vRadial.mult(radius);
|
|
|
|
- Vector3f vRadius2 = vRadial.mult(radius2);
|
|
|
|
- Vector3f vMantle = vHeight.subtract(vRadius2.subtract(vRadius));
|
|
|
|
- Vector3f vTangent = vRadial.cross(Vector3f.UNIT_Z);
|
|
|
|
- vNormals[radialCount] = vMantle.cross(vTangent).normalize();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- FloatBuffer nb = getFloatBuffer(Type.Normal);
|
|
|
|
- FloatBuffer pb = getFloatBuffer(Type.Position);
|
|
|
|
- FloatBuffer tb = getFloatBuffer(Type.TexCoord);
|
|
|
|
- FloatBuffer cb = getFloatBuffer(Type.Color);
|
|
|
|
-
|
|
|
|
- cb.rewind();
|
|
|
|
- for (int i = 0; i < vertCount; i++) {
|
|
|
|
- cb.put(0.05f).put(0.05f).put(0.05f).put(1f);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // generate the cylinder itself
|
|
|
|
- Vector3f tempNormal = new Vector3f();
|
|
|
|
- for (int axisCount = 0, i = 0; axisCount < axisSamples; axisCount++, i++) {
|
|
|
|
- float axisFraction;
|
|
|
|
- float axisFractionTexture;
|
|
|
|
- int topBottom = 0;
|
|
|
|
- if (!closed) {
|
|
|
|
- axisFraction = axisCount * inverseAxisLess; // in [0,1]
|
|
|
|
- axisFractionTexture = axisFraction;
|
|
|
|
- } else {
|
|
|
|
- if (axisCount == 0) {
|
|
|
|
- topBottom = -1; // bottom
|
|
|
|
- axisFraction = 0;
|
|
|
|
- axisFractionTexture = inverseAxisLessTexture;
|
|
|
|
- } else if (axisCount == axisSamples - 1) {
|
|
|
|
- topBottom = 1; // top
|
|
|
|
- axisFraction = 1;
|
|
|
|
- axisFractionTexture = 1 - inverseAxisLessTexture;
|
|
|
|
- } else {
|
|
|
|
- axisFraction = (axisCount - 1) * inverseAxisLess;
|
|
|
|
- axisFractionTexture = axisCount * inverseAxisLessTexture;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // compute center of slice
|
|
|
|
- float z = height * axisFraction;
|
|
|
|
- Vector3f sliceCenter = new Vector3f(0, 0, z);
|
|
|
|
-
|
|
|
|
- // compute slice vertices with duplication at end point
|
|
|
|
- int save = i;
|
|
|
|
- for (int radialCount = 0; radialCount < radialSamples; radialCount++, i++) {
|
|
|
|
- float radialFraction = radialCount * inverseRadial; // in [0,1)
|
|
|
|
- tempNormal.set(cos[radialCount], sin[radialCount], 0.0f);
|
|
|
|
-
|
|
|
|
- if (vNormals != null) {
|
|
|
|
- vNormal = vNormals[radialCount];
|
|
|
|
- } else if (radius == radius2) {
|
|
|
|
- vNormal = tempNormal;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (topBottom == 0) {
|
|
|
|
- if (!inverted)
|
|
|
|
- nb.put(vNormal.x).put(vNormal.y).put(vNormal.z);
|
|
|
|
- else
|
|
|
|
- nb.put(-vNormal.x).put(-vNormal.y).put(-vNormal.z);
|
|
|
|
- } else {
|
|
|
|
- nb.put(0).put(0).put(topBottom * (inverted ? -1 : 1));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- tempNormal.multLocal((radius - radius2) * axisFraction + radius2)
|
|
|
|
- .addLocal(sliceCenter);
|
|
|
|
- pb.put(tempNormal.x).put(tempNormal.y).put(tempNormal.z);
|
|
|
|
-
|
|
|
|
- tb.put((inverted ? 1 - radialFraction : radialFraction))
|
|
|
|
- .put(axisFractionTexture);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- BufferUtils.copyInternalVector3(pb, save, i);
|
|
|
|
- BufferUtils.copyInternalVector3(nb, save, i);
|
|
|
|
-
|
|
|
|
- tb.put((inverted ? 0.0f : 1.0f))
|
|
|
|
- .put(axisFractionTexture);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (closed) {
|
|
|
|
- pb.put(0).put(0).put(-halfHeight); // bottom center
|
|
|
|
- nb.put(0).put(0).put(-1 * (inverted ? -1 : 1));
|
|
|
|
- tb.put(0.5f).put(0);
|
|
|
|
- pb.put(0).put(0).put(halfHeight); // top center
|
|
|
|
- nb.put(0).put(0).put(1 * (inverted ? -1 : 1));
|
|
|
|
- tb.put(0.5f).put(1);
|
|
|
|
|
|
+ protected void doUpdateGeometryIndices() {
|
|
|
|
+ if (getBuffer(Type.Index) == null) {
|
|
|
|
+ setBuffer(Type.Index, 3, BufferUtils.createShortBuffer(GEOMETRY_INDICES_DATA));
|
|
}
|
|
}
|
|
|
|
+ }
|
|
|
|
|
|
- IndexBuffer ib = getIndexBuffer();
|
|
|
|
- int index = 0;
|
|
|
|
- // Connectivity
|
|
|
|
- for (int axisCount = 0, axisStart = 0; axisCount < axisSamples - 1; axisCount++) {
|
|
|
|
- int i0 = axisStart;
|
|
|
|
- int i1 = i0 + 1;
|
|
|
|
- axisStart += radialSamples + 1;
|
|
|
|
- int i2 = axisStart;
|
|
|
|
- int i3 = i2 + 1;
|
|
|
|
- for (int i = 0; i < radialSamples; i++) {
|
|
|
|
- if (closed && axisCount == 0) {
|
|
|
|
- if (!inverted) {
|
|
|
|
- ib.put(index++, i0++);
|
|
|
|
- ib.put(index++, vertCount - 2);
|
|
|
|
- ib.put(index++, i1++);
|
|
|
|
- } else {
|
|
|
|
- ib.put(index++, i0++);
|
|
|
|
- ib.put(index++, i1++);
|
|
|
|
- ib.put(index++, vertCount - 2);
|
|
|
|
- }
|
|
|
|
- } else if (closed && axisCount == axisSamples - 2) {
|
|
|
|
- ib.put(index++, i2++);
|
|
|
|
- ib.put(index++, inverted ? vertCount - 1 : i3++);
|
|
|
|
- ib.put(index++, inverted ? i3++ : vertCount - 1);
|
|
|
|
- } else {
|
|
|
|
- ib.put(index++, i0++);
|
|
|
|
- ib.put(index++, inverted ? i2 : i1);
|
|
|
|
- ib.put(index++, inverted ? i1 : i2);
|
|
|
|
- ib.put(index++, i1++);
|
|
|
|
- ib.put(index++, inverted ? i2++ : i3++);
|
|
|
|
- ib.put(index++, inverted ? i3++ : i2++);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ protected void doUpdateGeometryNormals() {
|
|
|
|
+ if (getBuffer(Type.Normal) == null) {
|
|
|
|
+ setBuffer(Type.Normal, 3, BufferUtils.createFloatBuffer(GEOMETRY_NORMALS_DATA));
|
|
}
|
|
}
|
|
-
|
|
|
|
- updateBound();
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
|
- public void read(JmeImporter e) throws IOException {
|
|
|
|
- super.read(e);
|
|
|
|
- InputCapsule capsule = e.getCapsule(this);
|
|
|
|
- axisSamples = capsule.readInt("axisSamples", 0);
|
|
|
|
- radialSamples = capsule.readInt("radialSamples", 0);
|
|
|
|
- radius = capsule.readFloat("radius", 0);
|
|
|
|
- radius2 = capsule.readFloat("radius2", 0);
|
|
|
|
- height = capsule.readFloat("height", 0);
|
|
|
|
- closed = capsule.readBoolean("closed", false);
|
|
|
|
- inverted = capsule.readBoolean("inverted", false);
|
|
|
|
|
|
+ protected void doUpdateGeometryTextures() {
|
|
|
|
+ if (getBuffer(Type.TexCoord) == null) {
|
|
|
|
+ setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(GEOMETRY_TEXTURE_DATA));
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
|
- public void write(JmeExporter e) throws IOException {
|
|
|
|
- super.write(e);
|
|
|
|
- OutputCapsule capsule = e.getCapsule(this);
|
|
|
|
- capsule.write(axisSamples, "axisSamples", 0);
|
|
|
|
- capsule.write(radialSamples, "radialSamples", 0);
|
|
|
|
- capsule.write(radius, "radius", 0);
|
|
|
|
- capsule.write(radius2, "radius2", 0);
|
|
|
|
- capsule.write(height, "height", 0);
|
|
|
|
- capsule.write(closed, "closed", false);
|
|
|
|
- capsule.write(inverted, "inverted", false);
|
|
|
|
|
|
+ protected void doUpdateGeometryVertices() {
|
|
|
|
+ FloatBuffer fpb = BufferUtils.createVector3Buffer(24);
|
|
|
|
+ fpb.put(GEOMETRY_POSITION_DATA);
|
|
|
|
+ setBuffer(Type.Position, 3, fpb);
|
|
|
|
+ updateBound();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|