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.

papervision3d cylinder radial segment

Code and live example in full article

Here is live example and source code follows:

Actionscript:
  1. package {
  2. import org.papervision3d.core.geom.*;
  3. import org.papervision3d.core.geom.renderables.Triangle3D;
  4. import org.papervision3d.core.geom.renderables.Vertex3D;
  5. import org.papervision3d.core.math.NumberUV;
  6. import org.papervision3d.core.proto.*;
  7.  
  8. /**
  9. * The RadialSegment class lets you create and display cylinders radial segments.
  10. *
  11. * The RadialSegment is divided in horizontal mesh segments and vertical ragial segments.
  12. *    * Derivated from original Cylinder class by Daniel Sedlacek (sedlacek.daniel@gmail.com).
  13. *    * Please follow the original Papervision3D license.
  14. */
  15. public class RadialSegment extends TriangleMesh3D {
  16. /**
  17. * Number of segments horizontally. Defaults to 8.
  18. */
  19. public var segmentsW : Number;    /**
  20. * Number of segments vertically. Defaults to 6.
  21. */
  22. public var segmentsH : Number;
  23.  
  24. /**
  25. * Default radius of Segment3D if not defined.
  26. */
  27. static public var DEFAULT_RADIUS : Number = 100;
  28.  
  29. /**
  30. * Default height if not defined.
  31. */
  32. static public var DEFAULT_HEIGHT : Number = 50;
  33.  
  34. /**
  35. * Default value of gridX if not defined.
  36. */
  37. static public var DEFAULT_SEGMENTSW : Number = 8;
  38.  
  39. /**
  40. * Default value of gridY if not defined.
  41. */
  42. static public var DEFAULT_SEGMENTSH : Number = 2;
  43.  
  44. /**
  45. * Minimum value of gridX.
  46. */
  47. static public var MIN_SEGMENTSW : Number = 3;
  48.  
  49. /**
  50. * Minimum value of gridY.
  51. */
  52. static public var MIN_SEGMENTSH : Number = 1;
  53.  
  54. /**
  55. * Create a new Cylinder object.
  56. *
  57. * @param    material    [optional] - A MaterialObject3D object that contains the material properties of the object.
  58. *     * @param    angle      [optional] - Desired segment angle <0,1>.
  59. *     * @param    radius    [optional] - Desired radius.
  60. *     * @param    segmentsW   [optional] - Number of segments horizontally. Defaults to 8.
  61. *     * @param    segmentsH   [optional] - Number of segments vertically. Defaults to 6.
  62. *     * @param    topRadius   [optional] - An optional parameter for con- or diverging cylinders
  63. *     * @param    initObject  [optional] - An object that contains user defined properties with which to populate the newly created GeometryObject3D.
  64. *     * It includes x, y, z, rotationX, rotationY, rotationZ, scaleX, scaleY scaleZ and a user defined extra object.
  65. *     * 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.
  66. */
  67. 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 ) {
  68. super(material, new Array(), new Array(), null, initObject);            this.segmentsW = Math.max(MIN_SEGMENTSW, segmentsW || DEFAULT_SEGMENTSW);
  69. // Defaults to 8
  70. this.segmentsH = Math.max(MIN_SEGMENTSH, segmentsH || DEFAULT_SEGMENTSH);
  71. // Defaults to 6
  72. if (radius == 0) radius = DEFAULT_RADIUS;
  73. // Defaults to 100
  74. if (height == 0) height = DEFAULT_HEIGHT;
  75. // Defaults to 100
  76. if (topRadius == -1) topRadius = radius;
  77. // segment
  78. angle = angle> 1 ? 1 : angle <0 ? 0 : angle;
  79.  
  80. buildSegment(angle, radius, height, topRadius);
  81. }
  82.  
  83. private function buildSegment( fAngle : Number, fRadius : Number, fHeight : Number,  fTopRadius : Number ) : void {
  84. var matInstance : MaterialObject3D = material;
  85.  
  86. var i : Number, j : Number;
  87.  
  88. var iHor : Number = this.segmentsW + 1;
  89. var iVer : Number = this.segmentsH;
  90. var aVertice : Array = this.geometry.vertices;
  91. var aFace : Array = this.geometry.faces;
  92. var aVtc : Array = new Array();
  93.  
  94. for (j = 0;j <(iVer + 1);j++) {
  95. // vertical
  96. var fZ : Number = fHeight * (j / (iVer + 0)) - fHeight / 2;
  97. //-fRadius*Math.cos(fRad1*Math.PI);
  98. var fRds : Number = fTopRadius + (fRadius - fTopRadius) * (1 - j / (iVer));
  99. //*Math.sin(fRad1*Math.PI);
  100. var aRow : Array = new Array();
  101. var oVtx : Vertex3D;
  102.  
  103. for (i = 0;i <iHor;i++) {
  104. // horizontal
  105. var fRad2 : Number = Number(2 * i / (iHor - 1));
  106. var fX : Number = fRds * Math.sin(fRad2 * Math.PI * fAngle);
  107. var fY : Number = fRds * Math.cos(fRad2 * Math.PI * fAngle);
  108. oVtx = new Vertex3D(fY, fZ, fX);
  109.  
  110. aVertice.push(oVtx);
  111. aRow.push(oVtx);
  112. }
  113.  
  114. // special middle vertex
  115. oVtx = new Vertex3D(0, fZ, 0);
  116. aVertice.push(oVtx);
  117. aRow.push(oVtx);
  118.  
  119. aVtc.push(aRow);
  120. }
  121. var iVerNum : int = aVtc.length;
  122.  
  123. var aP4uv : NumberUV, aP1uv : NumberUV, aP2uv : NumberUV, aP3uv : NumberUV;
  124. var aP1 : Vertex3D, aP2 : Vertex3D, aP3 : Vertex3D, aP4 : Vertex3D;
  125.  
  126. for (j = 0;j <iVerNum;j++) {
  127. var iHorNum : int = aVtc[j].length;
  128. for (i = 0;i <iHorNum;i++) {
  129. if (j> 0 && i>= 0) {
  130. // select vertices
  131. var bEnd : Boolean = i == (iHorNum - 0);
  132. aP1 = aVtc[j][bEnd ? 0 : i];
  133. aP2 = aVtc[j][(i == 0 ? iHorNum : i) - 1];
  134. aP3 = aVtc[j - 1][(i == 0 ? iHorNum : i) - 1];
  135. aP4 = aVtc[j - 1][bEnd ? 0 : i];
  136. // uv
  137. var fJ0 : Number = j / iVerNum;
  138. var fJ1 : Number = (j - 1) / iVerNum;
  139. var fI0 : Number = (i + 1) / iHorNum;
  140. var fI1 : Number = i / iHorNum;
  141. aP4uv = new NumberUV(fI0, fJ1);
  142. aP1uv = new NumberUV(fI0, fJ0);
  143. aP2uv = new NumberUV(fI1, fJ0);
  144. aP3uv = new NumberUV(fI1, fJ1);
  145.  
  146. aFace.push(new Triangle3D(this, [aP1,aP2,aP3], matInstance, [aP1uv,aP2uv,aP3uv]));
  147. aFace.push(new Triangle3D(this, [aP1,aP3,aP4], matInstance, [aP1uv,aP3uv,aP4uv]));
  148. }
  149. }
  150. if (j == 0 || j == (iVerNum - 1)) {
  151. for (i = 0;i <(iHorNum - 2);i++) {
  152. // uv
  153.  
  154. aP1 = aVtc[j][iHorNum - 1];
  155. aP2 = aVtc[j][i];
  156. aP3 = aVtc[j][i + 1];
  157.  
  158. var bTop : Boolean = j == 0;
  159. aP1uv = new NumberUV((bTop ? 1 : 0) + (bTop ? -1 : 1) * (aP1.x / fRadius / 2 + .5), aP1.z / fRadius / 2 + .5);
  160. aP2uv = new NumberUV((bTop ? 1 : 0) + (bTop ? -1 : 1) * (aP2.x / fRadius / 2 + .5), aP2.z / fRadius / 2 + .5);
  161. aP3uv = new NumberUV((bTop ? 1 : 0) + (bTop ? -1 : 1) * (aP3.x / fRadius / 2 + .5), aP3.z / fRadius / 2 + .5);
  162.  
  163. // face
  164. if (j == 0) aFace.push(new Triangle3D(this, [aP1,aP3,aP2], matInstance, [aP1uv,aP3uv,aP2uv]));
  165. else        aFace.push(new Triangle3D(this, [aP1,aP2,aP3], matInstance, [aP1uv,aP2uv,aP3uv]));
  166. }
  167. }
  168. }
  169. this.geometry.ready = true;
  170. }
  171. }
  172. }

, , , ,
AddThis Feed Button

Entry Filed under: Library, Papervision, 3D, ActionScript, Flash


Do you want to receive fresh news from my site?
Subscribe to my RSS

»Related posts:



3 Responses to “Cylinder radial segment primitive object for Papervision3D”

  1. 1
    Cylinder radial segment primitive object for Papervision3D Says:

    […] 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 … […]

  2. 2
    flash your Says:

    […] 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 […]

  3. 3
    Pages tagged "the primitives" Says:

    […] 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 | […]

Leave a Reply