Cylinder radial segment primitive object for Papervision3D
May 19th, 2008 at 08:59am daniel.sedlacek
If you're new here, you may want to subscribe to my RSS feed. If you like my site, consider linking back. I prefer text "Free Flash Tutorials" to http://blog.franto.com
Thanks for visiting my site! If you need anything just contacting through Contact page or Gtalk widget
For my latest project I needed to display 3D cylinder slices - Papervision was an obvious choice. Unfortunately the primitive cylinder class does not work this way, the cylinder is built as a square mesh with no option for segment slices. So I had to help myself, I started to play with the almost undocumented PV3D primitives, step by step modifying the original cylinder class and after couple hours I dig out what is what and derived my RadialSegment class. It follows the original concept with one material for whole object, supports UV mapping and inherit all other properties. Here it is, use it as you wish.

Code and live example in full article
Here is live example and source code follows:
-
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;
-
}
-
}
-
}
Entry Filed under: Library, Papervision, 3D, ActionScript, Flash
»Related posts:
- RedBull Flight Lab
- Papervision3D resources, tutorials, examples
- Flash 3d BumpMapping in realtime
- Earthmine in Papervision3D
- From 3D Max to AS3.0
- Sandy tutorial: .ASE file export
- Useful Flex tips
- New features in Maelstrom (8ball)
- Flash 8 - burned example
- Maelstrom filters: DropShadowFilter
- Maelstrom examples: Water
- Flash 8 IDE problem
- Maelstrom filters: BlurFilter
- Maelstrom examples: BitmapData - SetPixel
- Flash 8 - displacementMap on paper
- Flash 8: Help with scale9Grid
- Another Flash 3d engines
- Sudoku
- Flash 8 - bitmapFont class, part 2.
- Flash 8 - bitmapFont class





May 19th, 2008 at 9:12 am
[…] The Hen wrote an interesting post today onHere’s a quick excerptFor my latest project I needed to display 3D cylinder slices - Papervisionwas an obvious choice. Unfortunately the primitive cylinder class does not work this way, the cylinder is built as a square mesh with no option for segment slices … […]
May 19th, 2008 at 10:19 am
[…] project I needed to display 3D cylinder slices - Papervisionwas an obvious choice. Unfortunately thttp://www.franto.com/blog2/cylinder-radial-segment-primitive-object-for-papervision3dWhat’s the best flash memory flavor for your design? Electronic Engineering Times AsiaThe embedded […]
May 21st, 2008 at 4:15 am
[…] the primitivesOwn a Wordpress blog? Make monetization easier with the WP Affiliate Pro plugin. Cylinder radial segment primitive object for Paper… saved by 4 others yourmyslave bookmarked on 05/20/08 | […]