package away3d.primitives { import away3d.arcane; import away3d.core.base.*; use namespace arcane; /** * Creates a 3d wire cone primitive. */ public class WireCone extends AbstractWirePrimitive { private var grid:Array; private var _radius:Number; private var _height:Number; private var _segmentsW:int; private var _segmentsH:int; private var _yUp:Boolean; private function buildWireCone(radius:Number, height:Number, segmentsW:int, segmentsH:int, yUp:Boolean):void { var i:int; var j:int; height /= 2; segmentsH += 1; grid = new Array(segmentsH + 1); var bottom:Vertex = yUp? createVertex(0, -height, 0) : createVertex(0, 0, -height); grid[0] = new Array(segmentsW); for (i = 0; i < segmentsW; i++) grid[0][i] = bottom; for (j = 1; j < segmentsH; j++) { var z:Number = -height + 2 * height * (j-1) / (segmentsH-1); grid[j] = new Array(segmentsW); for (i = 0; i < segmentsW; i++) { var verangle:Number = 2 * i / segmentsW * Math.PI; var ringradius:Number = radius * (segmentsH-j)/(segmentsH-1); var x:Number = ringradius * Math.sin(verangle); var y:Number = ringradius * Math.cos(verangle); if (yUp) grid[j][i] = createVertex(y, z, x); else grid[j][i] = createVertex(y, -x, z); } } var top:Vertex = yUp? createVertex(0, height, 0) : createVertex(0, 0, height); grid[segmentsH] = new Array(segmentsW); for (i = 0; i < segmentsW; i++) grid[segmentsH][i] = top; for (j = 1; j <= segmentsH; j++) for (i = 0; i < segmentsW; i++) { var a:Vertex = grid[j][i]; var b:Vertex = grid[j][(i-1+segmentsW) % segmentsW]; var c:Vertex = grid[j-1][(i-1+segmentsW) % segmentsW]; var d:Vertex = grid[j-1][i]; addSegment(createSegment(a, d)); addSegment(createSegment(b, c)); if (j < segmentsH) addSegment(createSegment(a, b)); } type = "WireCone"; url = "primitive"; } /** * Defines the radius of the wire cone base. Defaults to 100. */ public function get radius():Number { return _radius; } public function set radius(val:Number):void { if (_radius == val) return; _radius = val; _primitiveDirty = true; } /** * Defines the height of the wire cone. Defaults to 200. */ public function get height():Number { return _height; } public function set height(val:Number):void { if (_height == val) return; _height = val; _primitiveDirty = true; } /** * Defines the number of horizontal segments that make up the wire cone. Defaults to 8. */ public function get segmentsW():Number { return _segmentsW; } public function set segmentsW(val:Number):void { if (_segmentsW == val) return; _segmentsW = val; _primitiveDirty = true; } /** * Defines the number of vertical segments that make up the wire cone. Defaults to 1. */ public function get segmentsH():Number { return _segmentsH; } public function set segmentsH(val:Number):void { if (_segmentsH == val) return; _segmentsH = val; _primitiveDirty = true; } /** * Defines whether the coordinates of the wire cone points use a yUp orientation (true) or a zUp orientation (false). Defaults to true. */ public function get yUp():Boolean { return _yUp; } public function set yUp(val:Boolean):void { if (_yUp == val) return; _yUp = val; _primitiveDirty = true; } /** * Creates a new WireCone object. * * @param init [optional] An initialisation object for specifying default instance properties. */ public function WireCone(init:Object = null) { super(init); _radius = ini.getNumber("radius", 100, {min:0}); _height = ini.getNumber("height", 200, {min:0}); _segmentsW = ini.getInt("segmentsW", 8, {min:3}); _segmentsH = ini.getInt("segmentsH", 1, {min:1}); _yUp = ini.getBoolean("yUp", true); buildWireCone(_radius, _height, _segmentsW, _segmentsH, _yUp); type = "Cone"; url = "primitive"; } /** * @inheritDoc */ public override function buildPrimitive():void { super.buildPrimitive(); buildWireCone(_radius, _height, _segmentsW, _segmentsH, _yUp); } /** * Returns the vertex object specified by the grid position of the mesh. * * @param w The horizontal position on the primitive mesh. * @param h The vertical position on the primitive mesh. */ public function vertex(w:int, h:int):Vertex { return grid[h][w]; } } }