/src/aerys/minko/render/geometry/primitive/TorusGeometry.as
ActionScript | 124 lines | 104 code | 20 blank | 0 comment | 8 complexity | a2c234d79f764d909fe6839fb7e894c8 MD5 | raw file
1package aerys.minko.render.geometry.primitive
2{
3 import aerys.minko.render.geometry.Geometry;
4 import aerys.minko.render.geometry.stream.IVertexStream;
5 import aerys.minko.render.geometry.stream.IndexStream;
6 import aerys.minko.render.geometry.stream.StreamUsage;
7 import aerys.minko.render.geometry.stream.VertexStream;
8 import aerys.minko.render.geometry.stream.format.VertexComponent;
9 import aerys.minko.render.geometry.stream.format.VertexFormat;
10
11 import flash.utils.ByteArray;
12 import flash.utils.Endian;
13
14 public class TorusGeometry extends Geometry
15 {
16 private static const EPSILON : Number = 0.00001;
17 private static const DTOR : Number = 0.01745329252;
18
19 private var _radius : Number;
20 private var _tube : Number;
21 private var _segmentsR : uint;
22 private var _segmentsT : uint;
23 private var _arc : Number;
24
25 public function TorusGeometry(radius : Number = .375,
26 tube : Number = .125,
27 segmentsR : uint = 14,
28 segmentsT : uint = 13,
29 arc : Number = Math.PI * 2.,
30 withUVs : Boolean = true,
31 withNormals : Boolean = true,
32 vertexStreamUsage : uint = 3,
33 indexStreamUsage : uint = 3)
34 {
35 _radius = radius;
36 _tube = tube;
37 _segmentsR = segmentsR;
38 _segmentsT = segmentsT;
39 _arc = arc;
40
41 super(
42 new <IVertexStream>[buildVertexStream(vertexStreamUsage, withUVs, withNormals)],
43 buildIndexStream(indexStreamUsage)
44 );
45 }
46
47 private function buildVertexStream(usage : uint, withUVs : Boolean, withNormals : Boolean) : VertexStream
48 {
49 var vertexData : Vector.<Number> = new <Number>[];
50
51 for (var j : uint = 0; j <= _segmentsR; ++j)
52 {
53 for (var i : uint = 0; i <= _segmentsT; ++i)
54 {
55 var u : Number = i / _segmentsT * _arc;
56 var v : Number = j / _segmentsR * _arc;
57 var cosU : Number = Math.cos(u);
58 var sinU : Number = Math.sin(u);
59 var cosV : Number = Math.cos(v);
60 var x : Number = (_radius + _tube * cosV) * cosU;
61 var y : Number = (_radius + _tube * cosV) * sinU;
62 var z : Number = _tube * Math.sin(v);
63
64 vertexData.push(x, y, z);
65
66 if (withUVs)
67 vertexData.push(i / _segmentsT, 1 - j / _segmentsR);
68
69 if (withNormals)
70 {
71 var normalX : Number = x - _radius * cosU;
72 var normalY : Number = y - _radius * sinU;
73 var normalZ : Number = z;
74 var mag : Number = normalX * normalX + normalY * normalY
75 + normalZ * normalZ;
76
77 normalX /= mag;
78 normalY /= mag;
79 normalZ /= mag;
80
81 vertexData.push(normalX, normalY, normalZ);
82 }
83 }
84 }
85
86 var format : VertexFormat = new VertexFormat(VertexComponent.XYZ);
87
88 if (withUVs)
89 format.addComponent(VertexComponent.UV);
90
91 if (withNormals)
92 format.addComponent(VertexComponent.NORMAL);
93
94 return VertexStream.fromVector(usage, format, vertexData);
95 }
96
97 private function buildIndexStream(usage : uint) : IndexStream
98 {
99 var indices : ByteArray = new ByteArray();
100
101 indices.endian = Endian.LITTLE_ENDIAN;
102 for (var j : uint = 1; j <= _segmentsR; ++j)
103 {
104 for (var i : uint = 1; i <= _segmentsT; ++i)
105 {
106 var a : uint = (_segmentsT + 1) * j + i - 1;
107 var b : uint = (_segmentsT + 1) * (j - 1) + i - 1;
108 var c : uint = (_segmentsT + 1) * (j - 1) + i;
109 var d : uint = (_segmentsT + 1) * j + i;
110
111 indices.writeShort(a);
112 indices.writeShort(c);
113 indices.writeShort(b);
114 indices.writeShort(a);
115 indices.writeShort(d);
116 indices.writeShort(c);
117 }
118 }
119 indices.position = 0;
120
121 return new IndexStream(usage, indices);
122 }
123 }
124}