Just had a quick play. How does this one work for you - see code below.
Unfortunately I couldn't add attachment from where I am so it's a
cut-n-paste job - hope it all comes through. It's based on the
RegularPolygon primitive, is called Star and takes an 'innerRadius' init
parameter and a number of 'points' instead of the 'sides'. This can then be
extruded I presume - but I've not checked that bit. If it does the job, I'll
commit it to the trunk when I can. Haven't got access at the moment. Greg
-----------------------------------------------
package away3d.primitives
{
import away3d.arcane;
import away3d.core.base.*;
import flash.geom.*;
use namespace arcane;
/**
* Creates a star.
*/
public class Star extends AbstractPrimitive
{
private var _radius:Number;
private var _innerRadius:Number;
private var _points:Number;
private var _subdivision:Number;
private var _yUp:Boolean;
/**
* @inheritDoc
*/
protected override function buildPrimitive():void
{
super.buildPrimitive();
var tmpPoints:Array = [];
var tmpInnerPoints:Array = [];
var i:int = 0;
var j:int = 0;
var innerstep:Number = _radius/_subdivision;
var innerradstep:Number = _innerRadius/_subdivision;
var radstep:Number = 360/(_points*2);
var ang:Number = 0;
var ang_inc:Number = radstep;
var uva:UV;
var uvb:UV;
var uvc:UV;
var uvd:UV;
var facea:Vertex;
var faceb:Vertex;
var facec:Vertex;
var faced:Vertex;
for (i; i <= _subdivision; ++i) {
tmpPoints.push(new Vector3D(i*innerstep, 0, 0));
tmpInnerPoints.push(new Vector3D(i*innerradstep, 0, 0));
}
var base:Vector3D = new Vector3D(0,0,0);
var zerouv:UV = createUV(0.5, 0.5);
var rad:Vector3D = new Vector3D(0,0,0);
var rad1:Vector3D = new Vector3D(0,0,0);
var rad2:Vector3D = new Vector3D(0,0,0);
var rad3:Vector3D = new Vector3D(0,0,0);
for (i = 0; i < (_points * 2); ++i) {
for (j = 0; j <tmpPoints.length-1; ++j) {
uva = createUV( (Math.cos(-ang_inc/180*Math.PI) / ((_subdivision*2)/j) ) +
.5, (Math.sin(ang_inc/180*Math.PI) / ((_subdivision*2)/j)) +.5 );
uvb = createUV( (Math.cos(-ang/180*Math.PI) / ((_subdivision*2)/(j+1)) ) +
.5, (Math.sin(ang/180*Math.PI) / ((_subdivision*2)/(j+1)) ) + .5 );
uvc = createUV( (Math.cos(-ang_inc/180*Math.PI) / ((_subdivision*2)/(j+1)) )
+ .5, (Math.sin(ang_inc/180*Math.PI) / ((_subdivision*2)/(j+1))) + .5 );
uvd = createUV( (Math.cos(-ang/180*Math.PI) / ((_subdivision*2)/j)) + .5,
(Math.sin(ang/180*Math.PI) / ((_subdivision*2)/j) ) +.5 );
if (j == 0) {
rad = (i % 2 == 0) ? tmpInnerPoints[1] : tmpPoints[1];
rad1 = (i % 2 == 0) ? tmpPoints[1] : tmpInnerPoints[1];
if (_yUp) {
facea = createVertex(base.x, base.y, base.z);
faceb = createVertex(Math.cos(-ang/180*Math.PI) * rad.x, base.y,
Math.sin(ang/180*Math.PI) * rad.x);
facec = createVertex(Math.cos(-ang_inc/180*Math.PI) * rad1.x, base.y,
Math.sin(ang_inc/180*Math.PI) * rad1.x);
} else {
facea = createVertex(base.x, base.y, base.z);
faceb = createVertex(Math.cos(-ang/180*Math.PI) * rad1.x,
Math.sin(ang/180*Math.PI) * rad1.x, base.z);
facec = createVertex(Math.cos(-ang_inc/180*Math.PI) * rad.x,
Math.sin(ang_inc/180*Math.PI) * rad.x, base.z);
}
addFace(createFace(facea, faceb, facec, null, zerouv, uvb, uvc ) );
} else {
rad = (i % 2 == 0) ? tmpPoints[j] : tmpInnerPoints[j];
rad1 = (i % 2 == 0) ? tmpInnerPoints[j] : tmpPoints[j];
rad2 = (i % 2 == 0) ? tmpPoints[j + 1] : tmpInnerPoints[j + 1];
rad3 = (i % 2 == 0) ? tmpInnerPoints[j + 1] : tmpPoints[j + 1];
if (_yUp) {
facea = createVertex(Math.cos(-ang_inc/180*Math.PI) * rad.x, base.y,
Math.sin(ang_inc/180*Math.PI) * rad.x);
faceb = createVertex(Math.cos(-ang_inc/180*Math.PI) * rad2.x, base.y,
Math.sin(ang_inc/180*Math.PI) * rad2.x);
facec = createVertex(Math.cos(-ang/180*Math.PI) * rad3.x, base.y,
Math.sin(ang/180*Math.PI) * rad3.x);
faced = createVertex(Math.cos(-ang/180*Math.PI) * rad1.x, base.y,
Math.sin(ang/180*Math.PI) * rad1.x);
} else {
facea = createVertex(Math.cos(-ang_inc/180*Math.PI) * rad.x,
Math.sin(ang_inc/180*Math.PI) * rad.x, base.z);
faceb = createVertex(Math.cos(-ang_inc/180*Math.PI) * rad2.x,
Math.sin(ang_inc/180*Math.PI) * rad2.x, base.z);
facec = createVertex(Math.cos(-ang/180*Math.PI) * rad3.x,
Math.sin(ang/180*Math.PI) * rad3.x, base.z);
faced = createVertex(Math.cos(-ang/180*Math.PI) * rad1.x,
Math.sin(ang/180*Math.PI) * rad1.x, base.z);
}
addFace(createFace(facec, faceb, facea, null, uvb, uvc, uva ) );
addFace(createFace(facec, facea, faced, null, uvb, uva, uvd ) );
}
}
ang += radstep;
ang_inc += radstep;
}
}
/**
* Defines the radius of the polygon. 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 number of points of the polygon. Defaults to 8
(octohedron).
*/
public function get points():Number
{
return _points;
}
public function set points(val:Number):void
{
if (_points == val)
return;
_points = val;
_primitiveDirty = true;
}
/**
* Defines the subdivision of the polygon. Defaults to 1.
*/
public function get subdivision():Number
{
return _subdivision;
}
public function set subdivision(val:Number):void
{
if (_subdivision == val)
return;
_subdivision = val;
_primitiveDirty = true;
}
/**
* Defines whether the coordinates of the polygon 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 <code>Star</code> object.
*
* @param init [optional] An initialisation object for specifying default
instance properties.
*/
public function Star(init:Object = null)
{
super(init);
_radius = ini.getNumber("radius", 100, {min:0});
_innerRadius = ini.getNumber("innerRadius", 50, {min:0});
_points = ini.getInt("points", 4, {min:3});
_subdivision = ini.getInt("subdivision", 1, {min:1});
_yUp = ini.getBoolean("yUp", true);
type = "Star";
url = "primitive";
}
}
}