package { import org.papervision3d.core.geom.*; import org.papervision3d.core.geom.renderables.Triangle3D; import org.papervision3d.core.geom.renderables.Vertex3D; import org.papervision3d.core.math.NumberUV; import org.papervision3d.core.proto.*; /** * The RadialSegment class lets you create and display cylinders radial segments. *

* The RadialSegment is divided in horizontal mesh segments and vertical ragial segments. *

* Derivated from original Cylinder class by Daniel Sedlacek (sedlacek.daniel@gmail.com). *

* Please follow the original Papervision3D license. */ public class RadialSegment extends TriangleMesh3D { /** * Number of segments horizontally. Defaults to 8. */ public var segmentsW : Number; /** * Number of segments vertically. Defaults to 6. */ public var segmentsH : Number; /** * Default radius of Segment3D if not defined. */ static public var DEFAULT_RADIUS : Number = 100; /** * Default height if not defined. */ static public var DEFAULT_HEIGHT : Number = 50; /** * Default value of gridX if not defined. */ static public var DEFAULT_SEGMENTSW : Number = 8; /** * Default value of gridY if not defined. */ static public var DEFAULT_SEGMENTSH : Number = 2; /** * Minimum value of gridX. */ static public var MIN_SEGMENTSW : Number = 3; /** * Minimum value of gridY. */ static public var MIN_SEGMENTSH : Number = 1; /** * Create a new Cylinder object. *

* @param material [optional] - A MaterialObject3D object that contains the material properties of the object. *

* @param angle [optional] - Desired segment angle <0,1>. *

* @param radius [optional] - Desired radius. *

* @param segmentsW [optional] - Number of segments horizontally. Defaults to 8. *

* @param segmentsH [optional] - Number of segments vertically. Defaults to 6. *

* @param topRadius [optional] - An optional parameter for con- or diverging cylinders *

* @param initObject [optional] - An object that contains user defined properties with which to populate the newly created GeometryObject3D. *

* It includes x, y, z, rotationX, rotationY, rotationZ, scaleX, scaleY scaleZ and a user defined extra object. *

* If extra is not an object, it is ignored. All properties of the extra field are copied into the new instance. The properties specified with extra are publicly available. */ public function RadialSegment( material : MaterialObject3D = null, angle : Number = 0.25, radius : Number = 100, height : Number = 100, segmentsW : int = 8, segmentsH : int = 2, topRadius : Number = -1, initObject : Object = null ) { super(material, new Array(), new Array(), null, initObject); this.segmentsW = Math.max(MIN_SEGMENTSW, segmentsW || DEFAULT_SEGMENTSW); // Defaults to 8 this.segmentsH = Math.max(MIN_SEGMENTSH, segmentsH || DEFAULT_SEGMENTSH); // Defaults to 6 if (radius == 0) radius = DEFAULT_RADIUS; // Defaults to 100 if (height == 0) height = DEFAULT_HEIGHT; // Defaults to 100 if (topRadius == -1) topRadius = radius; // segment angle = angle > 1 ? 1 : angle < 0 ? 0 : angle; buildSegment(angle, radius, height, topRadius); } private function buildSegment( fAngle : Number, fRadius : Number, fHeight : Number, fTopRadius : Number ) : void { var matInstance : MaterialObject3D = material; var i : Number, j : Number; var iHor : Number = this.segmentsW + 1; var iVer : Number = this.segmentsH; var aVertice : Array = this.geometry.vertices; var aFace : Array = this.geometry.faces; var aVtc : Array = new Array(); for (j = 0;j < (iVer + 1);j++) { // vertical var fZ : Number = fHeight * (j / (iVer + 0)) - fHeight / 2; //-fRadius*Math.cos(fRad1*Math.PI); var fRds : Number = fTopRadius + (fRadius - fTopRadius) * (1 - j / (iVer)); //*Math.sin(fRad1*Math.PI); var aRow : Array = new Array(); var oVtx : Vertex3D; for (i = 0;i < iHor;i++) { // horizontal var fRad2 : Number = Number(2 * i / (iHor - 1)); var fX : Number = fRds * Math.sin(fRad2 * Math.PI * fAngle); var fY : Number = fRds * Math.cos(fRad2 * Math.PI * fAngle); oVtx = new Vertex3D(fY, fZ, fX); aVertice.push(oVtx); aRow.push(oVtx); } // special middle vertex oVtx = new Vertex3D(0, fZ, 0); aVertice.push(oVtx); aRow.push(oVtx); aVtc.push(aRow); } var iVerNum : int = aVtc.length; var aP4uv : NumberUV, aP1uv : NumberUV, aP2uv : NumberUV, aP3uv : NumberUV; var aP1 : Vertex3D, aP2 : Vertex3D, aP3 : Vertex3D, aP4 : Vertex3D; for (j = 0;j < iVerNum;j++) { var iHorNum : int = aVtc[j].length; for (i = 0;i < iHorNum;i++) { if (j > 0 && i >= 0) { // select vertices var bEnd : Boolean = i == (iHorNum - 0); aP1 = aVtc[j][bEnd ? 0 : i]; aP2 = aVtc[j][(i == 0 ? iHorNum : i) - 1]; aP3 = aVtc[j - 1][(i == 0 ? iHorNum : i) - 1]; aP4 = aVtc[j - 1][bEnd ? 0 : i]; // uv var fJ0 : Number = j / iVerNum; var fJ1 : Number = (j - 1) / iVerNum; var fI0 : Number = (i + 1) / iHorNum; var fI1 : Number = i / iHorNum; aP4uv = new NumberUV(fI0, fJ1); aP1uv = new NumberUV(fI0, fJ0); aP2uv = new NumberUV(fI1, fJ0); aP3uv = new NumberUV(fI1, fJ1); aFace.push(new Triangle3D(this, [aP1,aP2,aP3], matInstance, [aP1uv,aP2uv,aP3uv])); aFace.push(new Triangle3D(this, [aP1,aP3,aP4], matInstance, [aP1uv,aP3uv,aP4uv])); } } if (j == 0 || j == (iVerNum - 1)) { for (i = 0;i < (iHorNum - 2);i++) { // uv aP1 = aVtc[j][iHorNum - 1]; aP2 = aVtc[j][i]; aP3 = aVtc[j][i + 1]; var bTop : Boolean = j == 0; aP1uv = new NumberUV((bTop ? 1 : 0) + (bTop ? -1 : 1) * (aP1.x / fRadius / 2 + .5), aP1.z / fRadius / 2 + .5); aP2uv = new NumberUV((bTop ? 1 : 0) + (bTop ? -1 : 1) * (aP2.x / fRadius / 2 + .5), aP2.z / fRadius / 2 + .5); aP3uv = new NumberUV((bTop ? 1 : 0) + (bTop ? -1 : 1) * (aP3.x / fRadius / 2 + .5), aP3.z / fRadius / 2 + .5); // face if (j == 0) aFace.push(new Triangle3D(this, [aP1,aP3,aP2], matInstance, [aP1uv,aP3uv,aP2uv])); else aFace.push(new Triangle3D(this, [aP1,aP2,aP3], matInstance, [aP1uv,aP2uv,aP3uv])); } } } this.geometry.ready = true; } } }