diff options
author | Joshua Slack <[email protected]> | 2017-09-06 13:25:50 -0500 |
---|---|---|
committer | Joshua Slack <[email protected]> | 2017-09-06 13:25:50 -0500 |
commit | 667a92257e00530c9dc85d7c737acead45169629 (patch) | |
tree | eec22131bb8e9fc84762e23e46674f5e13c69808 /ardor3d-core/src/main/java | |
parent | 276240b3c9fda93e2ec76816b6d5f4307b549790 (diff) |
Updates to Disk to allow for hole in center.
Diffstat (limited to 'ardor3d-core/src/main/java')
-rw-r--r-- | ardor3d-core/src/main/java/com/ardor3d/scenegraph/shape/Disk.java | 191 |
1 files changed, 142 insertions, 49 deletions
diff --git a/ardor3d-core/src/main/java/com/ardor3d/scenegraph/shape/Disk.java b/ardor3d-core/src/main/java/com/ardor3d/scenegraph/shape/Disk.java index 3ada7d3..9608c03 100644 --- a/ardor3d-core/src/main/java/com/ardor3d/scenegraph/shape/Disk.java +++ b/ardor3d-core/src/main/java/com/ardor3d/scenegraph/shape/Disk.java @@ -3,7 +3,7 @@ * * This file is part of Ardor3D. * - * Ardor3D is free software: you can redistribute it and/or modify it + * Ardor3D is free software: you can redistribute it and/or modify it * under the terms of its license which may be found in the accompanying * LICENSE file or at <http://www.ardor3d.com/LICENSE>. */ @@ -26,18 +26,20 @@ import com.ardor3d.util.geom.BufferUtils; */ public class Disk extends Mesh { - private int _shellSamples; + protected int _shellSamples; - private int _radialSamples; + protected int _radialSamples; - private double _radius; + protected double _radius; + + protected double _innerRadius; public Disk() {} /** * Creates a flat disk (circle) at the origin flat along the Z. Usually, a higher sample number creates a better * looking cylinder, but at the cost of more vertex information. - * + * * @param name * The name of the disk. * @param shellSamples @@ -48,90 +50,180 @@ public class Disk extends Mesh { * The radius of the disk. */ public Disk(final String name, final int shellSamples, final int radialSamples, final double radius) { + this(name, shellSamples, radialSamples, radius, 0); + } + + /** + * Creates a flat disk (circle) at the origin flat along the Z. Usually, a higher sample number creates a better + * looking cylinder, but at the cost of more vertex information. + * + * @param name + * The name of the disk. + * @param shellSamples + * The number of shell samples. + * @param radialSamples + * The number of radial samples. + * @param radius + * The radius of the disk. + * @param innerRadius + * The inner radius of the disk. If greater than 0, the center of the disk has a hole of this size. + */ + public Disk(final String name, final int shellSamples, final int radialSamples, final double radius, + final double innerRadius) { super(name); _shellSamples = shellSamples; _radialSamples = radialSamples; _radius = radius; + _innerRadius = innerRadius; - final int radialless = radialSamples - 1; final int shellLess = shellSamples - 1; // allocate vertices - final int verts = 1 + radialSamples * shellLess; + final int verts = _innerRadius <= 0 ? 1 + radialSamples * shellLess : radialSamples * shellSamples; _meshData.setVertexBuffer(BufferUtils.createVector3Buffer(verts)); _meshData.setNormalBuffer(BufferUtils.createVector3Buffer(verts)); _meshData.setTextureBuffer(BufferUtils.createVector2Buffer(verts), 0); - final int tris = radialSamples * (2 * shellLess - 1); + final int tris = radialSamples * (2 * shellLess - (_innerRadius <= 0 ? 1 : 0)); _meshData.setIndices(BufferUtils.createIndexBufferData(3 * tris, verts - 1)); - setGeometryData(shellLess); - setIndexData(radialless, shellLess); + setGeometryData(); + setIndexData(); } - private void setGeometryData(final int shellLess) { - // generate geometry - // center of disk - _meshData.getVertexBuffer().put(0).put(0).put(0); + private void setGeometryData() { - for (int x = 0; x < _meshData.getVertexCount(); x++) { + // normals + for (int x = 0, maxX = _meshData.getVertexCount(); x < maxX; x++) { _meshData.getNormalBuffer().put(0).put(0).put(1); } - _meshData.getTextureCoords(0).getBuffer().put(.5f).put(.5f); - + // generate geometry + final int shellLess = _shellSamples - 1; final double inverseShellLess = 1.0 / shellLess; final double inverseRadial = 1.0 / _radialSamples; final Vector3 radialFraction = new Vector3(); final Vector2 texCoord = new Vector2(); - for (int radialCount = 0; radialCount < _radialSamples; radialCount++) { - final double angle = MathUtils.TWO_PI * inverseRadial * radialCount; - final double cos = MathUtils.cos(angle); - final double sin = MathUtils.sin(angle); - final Vector3 radial = new Vector3(cos, sin, 0); - - for (int shellCount = 1; shellCount < _shellSamples; shellCount++) { - final double fraction = inverseShellLess * shellCount; // in (0,R] - radialFraction.set(radial).multiplyLocal(fraction); - final int i = shellCount + shellLess * radialCount; - texCoord.setX(0.5 * (1.0 + radialFraction.getX())); - texCoord.setY(0.5 * (1.0 + radialFraction.getY())); - BufferUtils.setInBuffer(texCoord, _meshData.getTextureCoords(0).getBuffer(), i); - - radialFraction.multiplyLocal(_radius); - BufferUtils.setInBuffer(radialFraction, _meshData.getVertexBuffer(), i); + + if (_innerRadius <= 0) { + // no hole! + // center of disk + _meshData.getVertexBuffer().put(0).put(0).put(0); + _meshData.getTextureCoords(0).getBuffer().put(.5f).put(.5f); + + for (int radialCount = 0; radialCount < _radialSamples; radialCount++) { + final double angle = MathUtils.TWO_PI * inverseRadial * radialCount; + final double cos = MathUtils.cos(angle); + final double sin = MathUtils.sin(angle); + final Vector3 radial = new Vector3(cos, sin, 0); + + for (int shellCount = 1; shellCount < _shellSamples; shellCount++) { + final double fraction = inverseShellLess * shellCount; // in (0,R] + radialFraction.set(radial).multiplyLocal(fraction); + final int i = shellCount + shellLess * radialCount; + texCoord.setX(0.5 * (1.0 + radialFraction.getX())); + texCoord.setY(0.5 * (1.0 + radialFraction.getY())); + BufferUtils.setInBuffer(texCoord, _meshData.getTextureCoords(0).getBuffer(), i); + + radialFraction.multiplyLocal(_radius); + BufferUtils.setInBuffer(radialFraction, _meshData.getVertexBuffer(), i); + } + } + + } else { + // we have a hole in the middle + final Vector3 radialInner = new Vector3(); + for (int radialCount = 0; radialCount < _radialSamples; radialCount++) { + final double angle = MathUtils.TWO_PI * inverseRadial * radialCount; + final double cos = MathUtils.cos(angle); + final double sin = MathUtils.sin(angle); + final Vector3 radial = new Vector3(cos, sin, 0); + radialInner.set(radial).multiplyLocal(_innerRadius); + + for (int shellCount = 0; shellCount < _shellSamples; shellCount++) { + final double fraction = inverseShellLess * shellCount; + radialFraction.set(radial).multiplyLocal(fraction); + + final int i = shellCount + _shellSamples * radialCount; + + radialFraction.multiplyLocal(_radius - _innerRadius).addLocal(radialInner); + BufferUtils.setInBuffer(radialFraction, _meshData.getVertexBuffer(), i); + + texCoord.setX(0.5 * (1.0 + radialFraction.getX() / _radius)); + texCoord.setY(0.5 * (1.0 + radialFraction.getY() / _radius)); + BufferUtils.setInBuffer(texCoord, _meshData.getTextureCoords(0).getBuffer(), i); + } } } + } - private void setIndexData(final int radialless, final int shellLess) { + private void setIndexData() { + final int shellLess = _shellSamples - 1; + // generate connectivity - for (int radialCount0 = radialless, radialCount1 = 0; radialCount1 < _radialSamples; radialCount0 = radialCount1++) { - _meshData.getIndices().put(0); - _meshData.getIndices().put(1 + shellLess * radialCount0); - _meshData.getIndices().put(1 + shellLess * radialCount1); - for (int iS = 1; iS < shellLess; iS++) { - final int i00 = iS + shellLess * radialCount0; - final int i01 = iS + shellLess * radialCount1; - final int i10 = i00 + 1; - final int i11 = i01 + 1; - _meshData.getIndices().put(i00); - _meshData.getIndices().put(i10); - _meshData.getIndices().put(i11); - _meshData.getIndices().put(i00); - _meshData.getIndices().put(i11); - _meshData.getIndices().put(i01); + if (_innerRadius <= 0) { + // no hole! + for (int radialCount0 = _radialSamples - 1, radialCount1 = 0; radialCount1 < _radialSamples; radialCount0 = radialCount1++) { + _meshData.getIndices().put(0); + _meshData.getIndices().put(1 + shellLess * radialCount0); + _meshData.getIndices().put(1 + shellLess * radialCount1); + for (int iS = 1; iS < shellLess; iS++) { + final int i00 = iS + shellLess * radialCount0; + final int i01 = iS + shellLess * radialCount1; + final int i10 = i00 + 1; + final int i11 = i01 + 1; + _meshData.getIndices().put(i00); + _meshData.getIndices().put(i10); + _meshData.getIndices().put(i11); + _meshData.getIndices().put(i00); + _meshData.getIndices().put(i11); + _meshData.getIndices().put(i01); + } + } + } else { + // generate a hole! + for (int radialCount0 = _radialSamples - 1, radialCount1 = 0; radialCount1 < _radialSamples; radialCount0 = radialCount1++) { + for (int iS = 0; iS < shellLess; iS++) { + final int i00 = iS + _shellSamples * radialCount0; + final int i01 = iS + _shellSamples * radialCount1; + final int i10 = i00 + 1; + final int i11 = i01 + 1; + _meshData.getIndices().put(i00); + _meshData.getIndices().put(i10); + _meshData.getIndices().put(i11); + _meshData.getIndices().put(i00); + _meshData.getIndices().put(i11); + _meshData.getIndices().put(i01); + } } } } + public int getRadialSamples() { + return _radialSamples; + } + + public int getShellSamples() { + return _shellSamples; + } + + public double getRadius() { + return _radius; + } + + public double getInnerRadius() { + return _innerRadius; + } + @Override public void write(final OutputCapsule capsule) throws IOException { super.write(capsule); capsule.write(_shellSamples, "shellSamples", 0); capsule.write(_radialSamples, "radialSamples", 0); capsule.write(_radius, "radius", 0); + capsule.write(_innerRadius, "innerRadius", 0); } @Override @@ -140,5 +232,6 @@ public class Disk extends Mesh { _shellSamples = capsule.readInt("shellSamples", 0); _radialSamples = capsule.readInt("radialSamples", 0); _radius = capsule.readDouble("radius", 0); + _innerRadius = capsule.readDouble("innerRadius", 0); } }
\ No newline at end of file |