00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <vlGraphics/GeometryPrimitives.hpp>
00033 #include <vlGraphics/Geometry.hpp>
00034 #include <vlGraphics/DoubleVertexRemover.hpp>
00035 #include <vlGraphics/BezierSurface.hpp>
00036
00037 using namespace vl;
00038
00039
00042 ref<Geometry> vl::makeIcosphere(const vec3& pos, Real diameter, int detail, bool remove_doubles)
00043 {
00044 ref<Geometry> geom = new Geometry;
00045 geom->setObjectName("Icosphere");
00046
00047 ref<ArrayFloat3> coords = new ArrayFloat3;
00048 ref<ArrayFloat3> norms = new ArrayFloat3;
00049 ref<DrawElementsUInt> polys = new DrawElementsUInt(PT_TRIANGLES);
00050
00051 const Real X = (Real)0.525731112119133606;
00052 const Real Z = (Real)0.850650808352039932;
00053 std::vector< vec3 > verts;
00054 verts.push_back( vec3(-X, 0, Z) );
00055 verts.push_back( vec3(X, 0, Z) );
00056 verts.push_back( vec3(-X, 0, -Z) );
00057 verts.push_back( vec3(X, 0, -Z) );
00058 verts.push_back( vec3(0, Z, X) );
00059 verts.push_back( vec3(0, Z, -X) );
00060 verts.push_back( vec3(0, -Z, X) );
00061 verts.push_back( vec3(0, -Z, -X) );
00062 verts.push_back( vec3(Z, X, 0) );
00063 verts.push_back( vec3(-Z, X, 0) );
00064 verts.push_back( vec3(Z, -X, 0) );
00065 verts.push_back( vec3(-Z, -X, 0) );
00066
00067 int idxs[] = {
00068 1,4,0, 4,9,0, 4,5,9, 8,5,4, 1,8,4,
00069 1,10,8, 10,3,8, 8,3,5, 3,2,5, 3,7,2,
00070 3,10,7, 10,6,7, 6,11,7, 6,0,11, 6,1,0,
00071 10,1,6, 11,0,9, 2,11,9, 5,2,9, 11,2,7
00072 };
00073
00074 std::vector<int> indices;
00075 for(int i=0; i<4*5*3; ++i)
00076 indices.push_back(idxs[i]);
00077
00078
00079 if (detail>8)
00080 detail = 8;
00081 if (detail<0)
00082 detail = 0;
00083 for(int i=0; i<detail; ++i)
00084 {
00085 std::vector<int> indices2;
00086 std::vector< vec3 > verts2;
00087 for( int j=0, idx=0; j<(int)indices.size(); j+=3)
00088 {
00089 indices2.push_back(idx++); indices2.push_back(idx++); indices2.push_back(idx++);
00090 indices2.push_back(idx++); indices2.push_back(idx++); indices2.push_back(idx++);
00091 indices2.push_back(idx++); indices2.push_back(idx++); indices2.push_back(idx++);
00092 indices2.push_back(idx++); indices2.push_back(idx++); indices2.push_back(idx++);
00093
00094 vec3 v1 = verts[ indices[j+0] ]; v1.normalize();
00095 vec3 v2 = verts[ indices[j+1] ]; v2.normalize();
00096 vec3 v3 = verts[ indices[j+2] ]; v3.normalize();
00097 vec3 a = (v1 + v2) * 0.5f; a.normalize();
00098 vec3 b = (v2 + v3) * 0.5f; b.normalize();
00099 vec3 c = (v3 + v1) * 0.5f; c.normalize();
00100 verts2.push_back(v1); verts2.push_back( a); verts2.push_back(c);
00101 verts2.push_back( a); verts2.push_back(v2); verts2.push_back(b);
00102 verts2.push_back( a); verts2.push_back( b); verts2.push_back(c);
00103 verts2.push_back( c); verts2.push_back( b); verts2.push_back(v3);
00104 }
00105 verts = verts2;
00106 indices = indices2;
00107 }
00108
00109
00110
00111 Real radius = diameter / 2;
00112
00113 coords->resize( (int)verts.size() );
00114 norms->resize( (int)verts.size() );
00115 for( int i=0; i<(int)verts.size(); ++i )
00116 {
00117 coords->at(i) = (fvec3)(verts[i]*radius + pos);
00118 vec3 n = verts[i];
00119 n.normalize();
00120 norms->at(i) = (fvec3)n;
00121 }
00122
00123 polys->indices()->resize( (int)indices.size() );
00124 for(int i=0; i<(int)indices.size(); ++i)
00125 {
00126 VL_CHECK( indices[i] < (int)coords->size() )
00127 polys->indices()->at(i) = indices[i];
00128 }
00129
00130 geom->setVertexArray(coords.get());
00131 geom->setNormalArray(norms.get());
00132 geom->drawCalls()->push_back(polys.get());
00133
00134 if (remove_doubles)
00135 {
00136 DoubleVertexRemover dvr;
00137 dvr.removeDoubles(geom.get());
00138 }
00139
00140 return geom;
00141 }
00142
00143 ref<Geometry> vl::makeTeapot( const vec3& origin, Real diameter, int detail)
00144 {
00145
00146 static const int patch_idx[] = {
00147 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
00148 4, 17, 18, 19, 8, 20, 21, 22, 12, 23, 24, 25, 16, 26, 27, 28,
00149 19, 29, 30, 31, 22, 32, 33, 34, 25, 35, 36, 37, 28, 38, 39, 40,
00150 31, 41, 42, 1, 34, 43, 44, 5, 37, 45, 46, 9, 40, 47, 48, 13,
00151 13, 14, 15, 16, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
00152 16, 26, 27, 28, 52, 61, 62, 63, 56, 64, 65, 66, 60, 67, 68, 69,
00153 28, 38, 39, 40, 63, 70, 71, 72, 66, 73, 74, 75, 69, 76, 77, 78,
00154 40, 47, 48, 13, 72, 79, 80, 49, 75, 81, 82, 53, 78, 83, 84, 57,
00155 57, 58, 59, 60, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
00156 60, 67, 68, 69, 88, 97, 98, 99, 92, 100, 101, 102, 96, 103, 104, 105,
00157 69, 76, 77, 78, 99, 106, 107, 108, 102, 109, 110, 111, 105, 112, 113, 114,
00158 78, 83, 84, 57, 108, 115, 116, 85, 111, 117, 118, 89, 114, 119, 120, 93,
00159 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136,
00160 124, 137, 138, 121, 128, 139, 140, 125, 132, 141, 142, 129, 136, 143, 144, 133,
00161 133, 134, 135, 136, 145, 146, 147, 148, 149, 150, 151, 152, 69, 153, 154, 155,
00162 136, 143, 144, 133, 148, 156, 157, 145, 152, 158, 159, 149, 155, 160, 161, 69,
00163 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177,
00164 165, 178, 179, 162, 169, 180, 181, 166, 173, 182, 183, 170, 177, 184, 185, 174,
00165 174, 175, 176, 177, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197,
00166 177, 184, 185, 174, 189, 198, 199, 186, 193, 200, 201, 190, 197, 202, 203, 194,
00167 204, 204, 204, 204, 207, 208, 209, 210, 211, 211, 211, 211, 212, 213, 214, 215,
00168 204, 204, 204, 204, 210, 217, 218, 219, 211, 211, 211, 211, 215, 220, 221, 222,
00169 204, 204, 204, 204, 219, 224, 225, 226, 211, 211, 211, 211, 222, 227, 228, 229,
00170 204, 204, 204, 204, 226, 230, 231, 207, 211, 211, 211, 211, 229, 232, 233, 212,
00171 212, 213, 214, 215, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245,
00172 215, 220, 221, 222, 237, 246, 247, 248, 241, 249, 250, 251, 245, 252, 253, 254,
00173 222, 227, 228, 229, 248, 255, 256, 257, 251, 258, 259, 260, 254, 261, 262, 263,
00174 229, 232, 233, 212, 257, 264, 265, 234, 260, 266, 267, 238, 263, 268, 269, 242,
00175 270, 270, 270, 270, 279, 280, 281, 282, 275, 276, 277, 278, 271, 272, 273, 274,
00176 270, 270, 270, 270, 282, 289, 290, 291, 278, 286, 287, 288, 274, 283, 284, 285,
00177 270, 270, 270, 270, 291, 298, 299, 300, 288, 295, 296, 297, 285, 292, 293, 294,
00178 270, 270, 270, 270, 300, 305, 306, 279, 297, 303, 304, 275, 294, 301, 302, 271
00179 };
00180
00181
00182 static const float coords[] = {
00183 1.4f, 0.0f, 2.4f, 1.4f, -0.784f, 2.4f, 0.784f, -1.4f, 2.4f, 0.0f, -1.4f, 2.4f, 1.3375f, 0.0f, 2.53125f,
00184 1.3375f, -0.749f, 2.53125f, 0.749f, -1.3375f, 2.53125f, 0.0f, -1.3375f, 2.53125f, 1.4375f, 0.0f, 2.53125f,
00185 1.4375f, -0.805f, 2.53125f, 0.805f, -1.4375f, 2.53125f, 0.0f, -1.4375f, 2.53125f, 1.5f, 0.0f, 2.4f, 1.5f,
00186 -0.84f, 2.4f, 0.84f, -1.5f, 2.4f, 0.0f, -1.5f, 2.4f, -0.784f, -1.4f, 2.4f, -1.4f, -0.784f, 2.4f, -1.4f,
00187 0.0f, 2.4f, -0.749f, -1.3375f, 2.53125f, -1.3375f, -0.749f, 2.53125f, -1.3375f, 0.0f, 2.53125f, -0.805f,
00188 -1.4375f, 2.53125f, -1.4375f, -0.805f, 2.53125f, -1.4375f, 0.0f, 2.53125f, -0.84f, -1.5f, 2.4f, -1.5f,
00189 -0.84f, 2.4f, -1.5f, 0.0f, 2.4f, -1.4f, 0.784f, 2.4f, -0.784f, 1.4f, 2.4f, 0.0f, 1.4f, 2.4f, -1.3375f,
00190 0.749f, 2.53125f, -0.749f, 1.3375f, 2.53125f, 0.0f, 1.3375f, 2.53125f, -1.4375f, 0.805f, 2.53125f, -0.805f,
00191 1.4375f, 2.53125f, 0.0f, 1.4375f, 2.53125f, -1.5f, 0.84f, 2.4f, -0.84f, 1.5f, 2.4f, 0.0f, 1.5f, 2.4f,
00192 0.784f, 1.4f, 2.4f, 1.4f, 0.784f, 2.4f, 0.749f, 1.3375f, 2.53125f, 1.3375f, 0.749f, 2.53125f, 0.805f,
00193 1.4375f, 2.53125f, 1.4375f, 0.805f, 2.53125f, 0.84f, 1.5f, 2.4f, 1.5f, 0.84f, 2.4f, 1.75f, 0.0f, 1.875f,
00194 1.75f, -0.98f, 1.875f, 0.98f, -1.75f, 1.875f, 0.0f, -1.75f, 1.875f, 2.0f, 0.0f, 1.35f, 2.0f, -1.12f, 1.35f,
00195 1.12f, -2.0f, 1.35f, 0.0f, -2.0f, 1.35f, 2.0f, 0.0f, 0.9f, 2.0f, -1.12f, 0.9f, 1.12f, -2.0f, 0.9f, 0.0f,
00196 -2.0f, 0.9f, -0.98f, -1.75f, 1.875f, -1.75f, -0.98f, 1.875f, -1.75f, 0.0f, 1.875f, -1.12f, -2.0f, 1.35f,
00197 -2.0f, -1.12f, 1.35f, -2.0f, 0.0f, 1.35f, -1.12f, -2.0f, 0.9f, -2.0f, -1.12f, 0.9f, -2.0f, 0.0f, 0.9f,
00198 -1.75f, 0.98f, 1.875f, -0.98f, 1.75f, 1.875f, 0.0f, 1.75f, 1.875f, -2.0f, 1.12f, 1.35f, -1.12f, 2.0f,
00199 1.35f, 0.0f, 2.0f, 1.35f, -2.0f, 1.12f, 0.9f, -1.12f, 2.0f, 0.9f, 0.0f, 2.0f, 0.9f, 0.98f, 1.75f,
00200 1.875f, 1.75f, 0.98f, 1.875f, 1.12f, 2.0f, 1.35f, 2.0f, 1.12f, 1.35f, 1.12f, 2.0f, 0.9f, 2.0f, 1.12f, 0.9f,
00201 2.0f, 0.0f, 0.45f, 2.0f, -1.12f, 0.45f, 1.12f, -2.0f, 0.45f, 0.0f, -2.0f, 0.45f, 1.5f, 0.0f, 0.225f, 1.5f,
00202 -0.84f, 0.225f, 0.84f, -1.5f, 0.225f, 0.0f, -1.5f, 0.225f, 1.5f, 0.0f, 0.15f, 1.5f, -0.84f, 0.15f, 0.84f,
00203 -1.5f, 0.15f, 0.0f, -1.5f, 0.15f, -1.12f, -2.0f, 0.45f, -2.0f, -1.12f, 0.45f, -2.0f, 0.0f, 0.45f, -0.84f,
00204 -1.5f, 0.225f, -1.5f, -0.84f, 0.225f, -1.5f, 0.0f, 0.225f, -0.84f, -1.5f, 0.15f, -1.5f, -0.84f, 0.15f,
00205 -1.5f, 0.0f, 0.15f, -2.0f, 1.12f, 0.45f, -1.12f, 2.0f, 0.45f, 0.0f, 2.0f, 0.45f, -1.5f, 0.84f, 0.225f,
00206 -0.84f, 1.5f, 0.225f, 0.0f, 1.5f, 0.225f, -1.5f, 0.84f, 0.15f, -0.84f, 1.5f, 0.15f, 0.0f, 1.5f, 0.15f,
00207 1.12f, 2.0f, 0.45f, 2.0f, 1.12f, 0.45f, 0.84f, 1.5f, 0.225f, 1.5f, 0.84f, 0.225f, 0.84f, 1.5f, 0.15f, 1.5f,
00208 0.84f, 0.15f, -1.6f, 0.0f, 2.025f, -1.6f, -0.3f, 2.025f, -1.5f, -0.3f, 2.25f, -1.5f, 0.0f, 2.25f, -2.3f,
00209 0.0f, 2.025f, -2.3f, -0.3f, 2.025f, -2.5f, -0.3f, 2.25f, -2.5f, 0.0f, 2.25f, -2.7f, 0.0f, 2.025f, -2.7f,
00210 -0.3f, 2.025f, -3.0f, -0.3f, 2.25f, -3.0f, 0.0f, 2.25f, -2.7f, 0.0f, 1.8f, -2.7f, -0.3f, 1.8f, -3.0f, -0.3f,
00211 1.8f, -3.0f, 0.0f, 1.8f, -1.5f, 0.3f, 2.25f, -1.6f, 0.3f, 2.025f, -2.5f, 0.3f, 2.25f, -2.3f, 0.3f, 2.025f,
00212 -3.0f, 0.3f, 2.25f, -2.7f, 0.3f, 2.025f, -3.0f, 0.3f, 1.8f, -2.7f, 0.3f, 1.8f, -2.7f, 0.0f, 1.575f, -2.7f,
00213 -0.3f, 1.575f, -3.0f, -0.3f, 1.35f, -3.0f, 0.0f, 1.35f, -2.5f, 0.0f, 1.125f, -2.5f, -0.3f, 1.125f, -2.65f,
00214 -0.3f, 0.9375f, -2.65f, 0.0f, 0.9375f, -2.0f, -0.3f, 0.9f, -1.9f, -0.3f, 0.6f, -1.9f, 0.0f, 0.6f, -3.0f, 0.3f,
00215 1.35f, -2.7f, 0.3f, 1.575f, -2.65f, 0.3f, 0.9375f, -2.5f, 0.3f, 1.125f, -1.9f, 0.3f, 0.6f, -2.0f, 0.3f, 0.9f,
00216 1.7f, 0.0f, 1.425f, 1.7f, -0.66f, 1.425f, 1.7f, -0.66f, 0.6f, 1.7f, 0.0f, 0.6f, 2.6f, 0.0f, 1.425f, 2.6f,
00217 -0.66f, 1.425f, 3.1f, -0.66f, 0.825f, 3.1f, 0.0f, 0.825f, 2.3f, 0.0f, 2.1f, 2.3f, -0.25f, 2.1f, 2.4f, -0.25f,
00218 2.025f, 2.4f, 0.0f, 2.025f, 2.7f, 0.0f, 2.4f, 2.7f, -0.25f, 2.4f, 3.3f, -0.25f, 2.4f, 3.3f, 0.0f, 2.4f, 1.7f,
00219 0.66f, 0.6f, 1.7f, 0.66f, 1.425f, 3.1f, 0.66f, 0.825f, 2.6f, 0.66f, 1.425f, 2.4f, 0.25f, 2.025f, 2.3f, 0.25f,
00220 2.1f, 3.3f, 0.25f, 2.4f, 2.7f, 0.25f, 2.4f, 2.8f, 0.0f, 2.475f, 2.8f, -0.25f, 2.475f, 3.525f, -0.25f, 2.49375f,
00221 3.525f, 0.0f, 2.49375f, 2.9f, 0.0f, 2.475f, 2.9f, -0.15f, 2.475f, 3.45f, -0.15f, 2.5125f, 3.45f, 0.0f, 2.5125f,
00222 2.8f, 0.0f, 2.4f, 2.8f, -0.15f, 2.4f, 3.2f, -0.15f, 2.4f, 3.2f, 0.0f, 2.4f, 3.525f, 0.25f, 2.49375f, 2.8f,
00223 0.25f, 2.475f, 3.45f, 0.15f, 2.5125f, 2.9f, 0.15f, 2.475f, 3.2f, 0.15f, 2.4f, 2.8f, 0.15f, 2.4f, 0.0f, 0.0f,
00224 3.15f, 0.0f, -0.002f, 3.15f, 0.002f, 0.0f, 3.15f, 0.8f, 0.0f, 3.15f, 0.8f, -0.45f, 3.15f, 0.45f, -0.8f, 3.15f,
00225 0.0f, -0.8f, 3.15f, 0.0f, 0.0f, 2.85f, 0.2f, 0.0f, 2.7f, 0.2f, -0.112f, 2.7f, 0.112f, -0.2f, 2.7f, 0.0f, -0.2f,
00226 2.7f, -0.002f, 0.0f, 3.15f, -0.45f, -0.8f, 3.15f, -0.8f, -0.45f, 3.15f, -0.8f, 0.0f, 3.15f, -0.112f, -0.2f, 2.7f,
00227 -0.2f, -0.112f, 2.7f, -0.2f, 0.0f, 2.7f, 0.0f, 0.002f, 3.15f, -0.8f, 0.45f, 3.15f, -0.45f, 0.8f, 3.15f, 0.0f,
00228 0.8f, 3.15f, -0.2f, 0.112f, 2.7f, -0.112f, 0.2f, 2.7f, 0.0f, 0.2f, 2.7f, 0.45f, 0.8f, 3.15f, 0.8f, 0.45f, 3.15f,
00229 0.112f, 0.2f, 2.7f, 0.2f, 0.112f, 2.7f, 0.4f, 0.0f, 2.55f, 0.4f, -0.224f, 2.55f, 0.224f, -0.4f, 2.55f, 0.0f,
00230 -0.4f, 2.55f, 1.3f, 0.0f, 2.55f, 1.3f, -0.728f, 2.55f, 0.728f, -1.3f, 2.55f, 0.0f, -1.3f, 2.55f, 1.3f, 0.0f,
00231 2.4f, 1.3f, -0.728f, 2.4f, 0.728f, -1.3f, 2.4f, 0.0f, -1.3f, 2.4f, -0.224f, -0.4f, 2.55f, -0.4f, -0.224f, 2.55f,
00232 -0.4f, 0.0f, 2.55f, -0.728f, -1.3f, 2.55f, -1.3f, -0.728f, 2.55f, -1.3f, 0.0f, 2.55f, -0.728f, -1.3f, 2.4f, -1.3f,
00233 -0.728f, 2.4f, -1.3f, 0.0f, 2.4f, -0.4f, 0.224f, 2.55f, -0.224f, 0.4f, 2.55f, 0.0f, 0.4f, 2.55f, -1.3f, 0.728f,
00234 2.55f, -0.728f, 1.3f, 2.55f, 0.0f, 1.3f, 2.55f, -1.3f, 0.728f, 2.4f, -0.728f, 1.3f, 2.4f, 0.0f, 1.3f, 2.4f,
00235 0.224f, 0.4f, 2.55f, 0.4f, 0.224f, 2.55f, 0.728f, 1.3f, 2.55f, 1.3f, 0.728f, 2.55f, 0.728f, 1.3f, 2.4f, 1.3f,
00236 0.728f, 2.4f, 0.0f, 0.0f, 0.0f, 1.5f, 0.0f, 0.15f, 1.5f, 0.84f, 0.15f, 0.84f, 1.5f, 0.15f, 0.0f, 1.5f, 0.15f,
00237 1.5f, 0.0f, 0.075f, 1.5f, 0.84f, 0.075f, 0.84f, 1.5f, 0.075f, 0.0f, 1.5f, 0.075f, 1.425f, 0.0f, 0.0f, 1.425f,
00238 0.798f, 0.0f, 0.798f, 1.425f, 0.0f, 0.0f, 1.425f, 0.0f, -0.84f, 1.5f, 0.15f, -1.5f, 0.84f, 0.15f, -1.5f, 0.0f,
00239 0.15f, -0.84f, 1.5f, 0.075f, -1.5f, 0.84f, 0.075f, -1.5f, 0.0f, 0.075f, -0.798f, 1.425f, 0.0f, -1.425f, 0.798f,
00240 0.0f, -1.425f, 0.0f, 0.0f, -1.5f, -0.84f, 0.15f, -0.84f, -1.5f, 0.15f, 0.0f, -1.5f, 0.15f, -1.5f, -0.84f, 0.075f,
00241 -0.84f, -1.5f, 0.075f, 0.0f, -1.5f, 0.075f, -1.425f, -0.798f, 0.0f, -0.798f, -1.425f, 0.0f, 0.0f, -1.425f, 0.0f,
00242 0.84f, -1.5f, 0.15f, 1.5f, -0.84f, 0.15f, 0.84f, -1.5f, 0.075f, 1.5f, -0.84f, 0.075f, 0.798f, -1.425f, 0.0f, 1.425f,
00243 -0.798f, 0.0f
00244 };
00245
00246 ref<BezierSurface> teapot = new BezierSurface;
00247 const fvec3* verts = (const fvec3*)coords;
00248
00249 for(int i=0; i<32; ++i)
00250 {
00251 ref<BezierPatch> patch = new BezierPatch(4,4);
00252 for(int j=0; j<16; ++j)
00253 {
00254 int idx = patch_idx[j+16*i]-1;
00255 VL_CHECK(idx < sizeof(coords) / coords[0])
00256 patch->points()[j] = (vec3)verts[ idx ];
00257 }
00258 teapot->patches().push_back(patch.get());
00259 }
00260 teapot->setDetail(detail);
00261 teapot->updateBezierSurface(false);
00262 Real s = Real(1.0) / teapot->boundingBox().width() * diameter;
00263 mat4 m = mat4::getTranslation( origin ) *
00264 mat4::getRotation(-90, 1, 0, 0) *
00265 mat4::getScaling(s, s, s) *
00266 mat4::getTranslation(-teapot->boundingBox().center());
00267 teapot->transform( m );
00268
00269 DoubleVertexRemover dvr;
00270 dvr.removeDoubles(teapot.get());
00271
00272 return teapot;
00273 }
00274
00275 ref<Geometry> vl::makeUVSphere( const vec3& origin, Real diameter, int phi, int theta)
00276 {
00277 ref<Geometry> geom = new Geometry;
00278 geom->setObjectName("UVSphere");
00279
00280 diameter = diameter / 2.0f;
00281 ref<ArrayFloat3> vert3 = new ArrayFloat3;
00282 geom->setVertexArray(vert3.get());
00283
00284
00285 vert3->resize( theta * phi + 2 );
00286 int vert_idx=0;
00287 vert3->at(vert_idx++) = (fvec3)(vec3(0,1*diameter,0) + origin);
00288 for(int i=0; i<theta; ++i)
00289 {
00290 for(int j=0; j<phi; ++j)
00291 {
00292
00293 vec3 v(0,1*diameter,0);
00294 v = mat4::getRotation(180.0f/(theta+1)*(i+1),0,0,1) * v;
00295 v = mat4::getRotation(360.0f/phi*j,0,1,0) * v;
00296 vert3->at(vert_idx++) = (fvec3)(v+origin);
00297 }
00298 }
00299 vert3->at(vert_idx++) = (fvec3)(vec3(0,-1*diameter,0) + origin);
00300
00301
00302
00303 ref<DrawElementsUInt> quads = new DrawElementsUInt( PT_QUADS );
00304 quads->indices()->resize( (theta-1)*phi*4 );
00305 geom->drawCalls()->push_back(quads.get());
00306 int idx = 0;
00307 for(int i=0; i<theta-1; ++i)
00308 {
00309 for(int j=0; j<phi; ++j)
00310 {
00311 quads->indices()->at(idx++) = 1+phi*(i+1)+(j+0)%phi;
00312 quads->indices()->at(idx++) = 1+phi*(i+1)+(j+1)%phi;
00313 quads->indices()->at(idx++) = 1+phi*(i+0)+(j+1)%phi;
00314 quads->indices()->at(idx++) = 1+phi*(i+0)+(j+0)%phi;
00315 }
00316 }
00317
00318
00319
00320 ref<DrawElementsUInt> tris = new DrawElementsUInt( PT_TRIANGLES );
00321 tris->indices()->resize( phi*3 + phi*3 );
00322 geom->drawCalls()->push_back(tris.get());
00323 idx = 0;
00324
00325 for(int j=0; j<phi; ++j)
00326 {
00327 tris->indices()->at(idx++) = 0;
00328 tris->indices()->at(idx++) = 1+(j+0)%phi;
00329 tris->indices()->at(idx++) = 1+(j+1)%phi;
00330 }
00331
00332 for(int j=0; j<phi; ++j)
00333 {
00334 tris->indices()->at(idx++) = (int)geom->vertexArray()->size()-1;
00335 tris->indices()->at(idx++) = 1+phi*(theta-1)+(j+1)%phi;
00336 tris->indices()->at(idx++) = 1+phi*(theta-1)+(j+0)%phi;
00337 }
00338
00339 return geom;
00340 }
00341
00342 ref<Geometry> vl::makeCylinder( const vec3& origin, Real diameter, Real height, int phi, int theta, bool top, bool bottom)
00343 {
00344 ref<Geometry> geom = new Geometry;
00345 geom->setObjectName("Cylinder");
00346
00347 diameter = diameter / 2;
00348 height = height / 2;
00349 ref<ArrayFloat3> vert3 = new ArrayFloat3;
00350 geom->setVertexArray(vert3.get());
00351
00352
00353 vert3->resize( theta * phi + (top?phi+1:0) + (bottom?phi+1:0) );
00354 int vert_idx=0;
00355 for(int i=0; i<theta; ++i)
00356 {
00357 for(int j=0; j<phi; ++j)
00358 {
00359 vec3 v(1*diameter, 1*height - 2*height*((Real)i/(theta-1)), 0);
00360 v = mat4::getRotation(360.0f/phi*j,0,1,0) * v;
00361 vert3->at(vert_idx++) = (fvec3)(v + origin);
00362 }
00363 }
00364
00365
00366
00367 ref<DrawElementsUInt> quads = new DrawElementsUInt( PT_QUADS );
00368 quads->indices()->resize( (theta-1)*phi*4 );
00369 geom->drawCalls()->push_back(quads.get());
00370 int idx = 0;
00371 for(int i=0; i<theta-1; ++i)
00372 {
00373 for(int j=0; j<phi; ++j)
00374 {
00375 quads->indices()->at(idx++) = phi*(i+1)+(j+0)%phi;
00376 quads->indices()->at(idx++) = phi*(i+1)+(j+1)%phi;
00377 quads->indices()->at(idx++) = phi*(i+0)+(j+1)%phi;
00378 quads->indices()->at(idx++) = phi*(i+0)+(j+0)%phi;
00379 }
00380 }
00381
00382
00383
00384 if (top)
00385 {
00386 ref<DrawElementsUInt> tris = new DrawElementsUInt( PT_TRIANGLE_FAN );
00387 tris->indices()->resize( phi+2 );
00388 geom->drawCalls()->push_back(tris.get());
00389 idx = 0;
00390
00391 int fan_center = vert_idx;
00392 vert3->at(vert_idx++) = (fvec3)(vec3(0, height, 0) + origin);
00393 for(int j=0; j<phi; ++j)
00394 {
00395 vec3 v(1*diameter, height, 0);
00396 v = mat4::getRotation(360.0f/phi*j,0,1,0) * v;
00397 vert3->at(vert_idx++) = (fvec3)(v + origin);
00398 }
00399
00400
00401 tris->indices()->at(idx++) = fan_center;
00402 for(int j=0; j<phi+1; ++j)
00403 tris->indices()->at(idx++) = 1+fan_center+j%phi;
00404 }
00405
00406 if (bottom)
00407 {
00408 ref<DrawElementsUInt> tris = new DrawElementsUInt( PT_TRIANGLE_FAN );
00409 tris->indices()->resize( phi+2 );
00410 geom->drawCalls()->push_back(tris.get());
00411 idx = 0;
00412
00413 int fan_center = vert_idx;
00414 vert3->at(vert_idx++) = (fvec3)(vec3(0, -height, 0) + origin);
00415 for(int j=0; j<phi; ++j)
00416 {
00417 vec3 v(1*diameter, - height, 0);
00418 v = mat4::getRotation(360.0f/phi*j,0,1,0) * v;
00419 vert3->at(vert_idx++) = (fvec3)(v + origin);
00420 }
00421
00422
00423 tris->indices()->at(idx++) = fan_center;
00424 for(int j=0; j<phi+1; ++j)
00425 tris->indices()->at(idx++) = 1+fan_center+(phi -1 - j%phi);
00426 }
00427
00428 return geom;
00429 }
00430
00431 ref<Geometry> vl::makeTorus( const vec3& origin, Real diameter, Real thickness, int phi, int theta, float tex_coords )
00432 {
00433 ref<Geometry> geom = new Geometry;
00434 geom->setObjectName("Torus");
00435
00436
00437 thickness /= 2.0f;
00438 const Real radius = diameter / 2.0f - thickness;
00439
00440
00441 ref<ArrayFloat3> vert3 = new ArrayFloat3;
00442 geom->setVertexArray(vert3.get());
00443 vert3->resize( (phi+1) * (theta+1) );
00444
00445
00446 ref<ArrayFloat3> norm3 = new ArrayFloat3;
00447 geom->setNormalArray(norm3.get());
00448 norm3->resize( (phi+1) * (theta+1) );
00449
00450
00451 ref<ArrayFloat2> texc2 = new ArrayFloat2;
00452 if (tex_coords)
00453 {
00454 geom->setTexCoordArray(0,texc2.get());
00455 texc2->resize( (phi+1) * (theta+1) );
00456 }
00457
00458 int vect_idx = 0;
00459 for(int i=0; i<theta+1; ++i)
00460 {
00461 for(int j=0; j<phi+1; ++j)
00462 {
00463 vec3 v(thickness, 0, 0);
00464 vec3 o(radius, 0, 0);
00465 v = mat4::getRotation(360.0f/phi*j,0,1,0) * v;
00466 v = mat4::getRotation(360.0f/theta*i,0,0,1) * v;
00467 o = mat4::getRotation(360.0f/theta*i,0,0,1) * o;
00468
00469 if (tex_coords)
00470 texc2->at(vect_idx) = fvec2((float)i/theta,(float)j/phi) * tex_coords;
00471
00472 vert3->at(vect_idx) = (fvec3)(v + o + origin);
00473
00474 norm3->at(vect_idx) = (fvec3)v.normalize();
00475
00476 ++vect_idx;
00477 }
00478 }
00479
00480 ref<DrawElementsUInt> polys = new DrawElementsUInt( PT_QUADS );
00481 geom->drawCalls()->push_back(polys.get());
00482 int idx = 0;
00483 polys->indices()->resize( theta * phi * 4 );
00484
00485 for(int i=0; i<theta; ++i)
00486 {
00487 for(int j=0; j<phi; ++j)
00488 {
00489 int i1 = i+1;
00490 polys->indices()->at(idx++) = (phi+1)*i +(j+0);
00491 polys->indices()->at(idx++) = (phi+1)*i +(j+1);
00492 polys->indices()->at(idx++) = (phi+1)*i1+(j+1);
00493 polys->indices()->at(idx++) = (phi+1)*i1+(j+0);
00494 }
00495 }
00496
00497 return geom;
00498 }
00499
00500 ref<Geometry> vl::makeBox( const AABB& aabb, bool tex_coords )
00501 {
00502 return makeBox( aabb.minCorner(), aabb.maxCorner(), tex_coords );
00503 }
00504
00505 ref<Geometry> vl::makeBox( const vec3& min, const vec3& max, bool tex_coords )
00506 {
00507 return makeBox( (min+max)*0.5, max.x()-min.x(), max.y()-min.y(), max.z()-min.z(), tex_coords );
00508 }
00509
00510 ref<Geometry> vl::makeBox( const vec3& origin, Real xside, Real yside, Real zside, bool tex_coords)
00511 {
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521 ref<Geometry> geom = new Geometry;
00522 geom->setObjectName("Box");
00523
00524 ref<ArrayFloat3> vert3 = new ArrayFloat3;
00525 ref<ArrayFloat2> texc2 = new ArrayFloat2;
00526 geom->setVertexArray(vert3.get());
00527 geom->setTexCoordArray(0, texc2.get());
00528
00529 Real x=xside/2.0f;
00530 Real y=yside/2.0f;
00531 Real z=zside/2.0f;
00532
00533 fvec3 a0( (fvec3)(vec3(+x,+y,+z) + origin) );
00534 fvec3 a1( (fvec3)(vec3(-x,+y,+z) + origin) );
00535 fvec3 a2( (fvec3)(vec3(-x,-y,+z) + origin) );
00536 fvec3 a3( (fvec3)(vec3(+x,-y,+z) + origin) );
00537 fvec3 a4( (fvec3)(vec3(+x,+y,-z) + origin) );
00538 fvec3 a5( (fvec3)(vec3(-x,+y,-z) + origin) );
00539 fvec3 a6( (fvec3)(vec3(-x,-y,-z) + origin) );
00540 fvec3 a7( (fvec3)(vec3(+x,-y,-z) + origin) );
00541
00542 ref<DrawArrays> polys = new DrawArrays(PT_QUADS, 0, 24);
00543 geom->drawCalls()->push_back( polys.get() );
00544
00545 vert3->resize( 24 );
00546
00547 vert3->at(0) = a1; vert3->at(1) = a2; vert3->at(2) = a3; vert3->at(3) = a0;
00548 vert3->at(4) = a2; vert3->at(5) = a6; vert3->at(6) = a7; vert3->at(7) = a3;
00549 vert3->at(8) = a6; vert3->at(9) = a5; vert3->at(10) = a4; vert3->at(11) = a7;
00550 vert3->at(12) = a5; vert3->at(13) = a1; vert3->at(14) = a0; vert3->at(15) = a4;
00551 vert3->at(16) = a0; vert3->at(17) = a3; vert3->at(18) = a7; vert3->at(19) = a4;
00552 vert3->at(20) = a5; vert3->at(21) = a6; vert3->at(22) = a2; vert3->at(23) = a1;
00553
00554 texc2->resize( 24 );
00555 int idx = 0;
00556 if (tex_coords)
00557 {
00558 texc2->at(idx++) = fvec2(0,1); texc2->at(idx++) = fvec2(0,0); texc2->at(idx++) = fvec2(1,0); texc2->at(idx++) = fvec2(1,1);
00559 texc2->at(idx++) = fvec2(0,1); texc2->at(idx++) = fvec2(0,0); texc2->at(idx++) = fvec2(1,0); texc2->at(idx++) = fvec2(1,1);
00560 texc2->at(idx++) = fvec2(1,0); texc2->at(idx++) = fvec2(1,1); texc2->at(idx++) = fvec2(0,1); texc2->at(idx++) = fvec2(0,0);
00561 texc2->at(idx++) = fvec2(0,1); texc2->at(idx++) = fvec2(0,0); texc2->at(idx++) = fvec2(1,0); texc2->at(idx++) = fvec2(1,1);
00562 texc2->at(idx++) = fvec2(0,0); texc2->at(idx++) = fvec2(1,0); texc2->at(idx++) = fvec2(1,1); texc2->at(idx++) = fvec2(0,1);
00563 texc2->at(idx++) = fvec2(1,1); texc2->at(idx++) = fvec2(0,1); texc2->at(idx++) = fvec2(0,0); texc2->at(idx++) = fvec2(1,0);
00564 }
00565
00566 return geom;
00567 }
00568
00569 ref<Geometry> vl::makePyramid( const vec3& origin, Real side, Real height)
00570 {
00571 ref<Geometry> geom = new Geometry;
00572 geom->setObjectName("Pyramid");
00573
00574 ref<ArrayFloat3> vert3 = new ArrayFloat3;
00575 geom->setVertexArray(vert3.get());
00576
00577 Real x = side / 2.0f;
00578 Real y = height;
00579 Real z = side / 2.0f;
00580
00581 fvec3 a0( (fvec3)(vec3(+0,+y,+0) + origin) );
00582 fvec3 a1( (fvec3)(vec3(-x,+0,-z) + origin) );
00583 fvec3 a2( (fvec3)(vec3(-x,-0,+z) + origin) );
00584 fvec3 a3( (fvec3)(vec3(+x,-0,+z) + origin) );
00585 fvec3 a4( (fvec3)(vec3(+x,+0,-z) + origin) );
00586
00587 ref<DrawArrays> polys = new DrawArrays(PT_TRIANGLES, 0, 6*3);
00588 geom->drawCalls()->push_back( polys.get() );
00589
00590 vert3->resize(6*3);
00591
00592 vert3->at(0) = a4; vert3->at(1) = a2; vert3->at(2) = a1;
00593 vert3->at(3) = a2; vert3->at(4) = a4; vert3->at(5) = a3;
00594 vert3->at(6) = a4; vert3->at(7) = a1; vert3->at(8) = a0;
00595 vert3->at(9) = a1; vert3->at(10) = a2; vert3->at(11) = a0;
00596 vert3->at(12) = a2; vert3->at(13) = a3; vert3->at(14) = a0;
00597 vert3->at(15) = a3; vert3->at(16) = a4; vert3->at(17) = a0;
00598
00599 return geom;
00600 }
00601
00602 ref<Geometry> vl::makeCone( const vec3& origin, Real diameter, Real height, int phi, bool bottom)
00603 {
00604 ref<Geometry> geom = new Geometry;
00605 geom->setObjectName("Cone");
00606
00607 ref<ArrayFloat3> vert3 = new ArrayFloat3;
00608 geom->setVertexArray( vert3.get() );
00609
00610 diameter = diameter / 2;
00611
00612 vert3->resize( phi+1 + (bottom?phi+1:0) );
00613
00614 int vert_idx = 0;
00615 vert3->at(vert_idx++) = (fvec3)(vec3(0, height/2.0f, 0) + origin);
00616 for(int j=0; j<phi; ++j)
00617 {
00618 vec3 v(1*diameter, -height/2.0f, 0);
00619 v = mat4::getRotation(360.0f/phi*j,0,1,0) * v;
00620 vert3->at(vert_idx++) = (fvec3)(v + origin);
00621 }
00622
00623
00624 ref<DrawElementsUInt> top_fan = new DrawElementsUInt(PT_TRIANGLE_FAN);
00625 top_fan->indices()->resize(phi+2);
00626 geom->drawCalls()->push_back(top_fan.get());
00627 int idx = 0;
00628 top_fan->indices()->at(idx++) = 0;
00629 for(int j=0; j<phi+1; ++j)
00630 top_fan->indices()->at(idx++) = 1+j%phi;
00631
00632
00633 if (bottom)
00634 {
00635 int fan_center = vert_idx;
00636 vert3->at(vert_idx++) = (fvec3)(vec3(0, -height/2.0f, 0) + origin);
00637 for(int j=0; j<phi; ++j)
00638 {
00639 vec3 v(1*diameter, -height/2.0f, 0);
00640 v = mat4::getRotation(360.0f/phi*j,0,1,0) * v;
00641 vert3->at(vert_idx++) = (fvec3)(v + origin);
00642 }
00643
00644 ref<DrawElementsUInt> bottom_fan = new DrawElementsUInt(PT_TRIANGLE_FAN);
00645 bottom_fan->indices()->resize(phi+2);
00646 geom->drawCalls()->push_back(bottom_fan.get());
00647 idx = 0;
00648 bottom_fan->indices()->at(idx++) = fan_center;
00649 for(int j=0; j<phi+1; ++j)
00650 bottom_fan->indices()->at(idx++) = fan_center+1+(phi-1-j%phi);
00651 }
00652
00653 return geom;
00654 }
00655
00657 ref<Geometry> vl::makeGrid( const vec3& origin, Real xside, Real zside, int x, int z, bool gen_texcoords, fvec2 uv0, fvec2 uv1)
00658 {
00659 ref<Geometry> geom = new Geometry;
00660 geom->setObjectName("Grid");
00661
00662 ref<ArrayFloat3> vert3 = new ArrayFloat3;
00663 ref<ArrayFloat2> text2 = new ArrayFloat2;
00664 geom->setVertexArray( vert3.get() );
00665
00666 VL_CHECK(x>=2)
00667 VL_CHECK(z>=2)
00668 Real dx = xside / (x-1);
00669 Real dz = zside / (z-1);
00670 xside /= 2.0f;
00671 zside /= 2.0f;
00672
00673 vert3->resize( x * z );
00674 if (gen_texcoords)
00675 {
00676 geom->setTexCoordArray( 0, text2.get() );
00677 text2->resize( x * z );
00678 }
00679
00680
00681 int vert_idx = 0;
00682 for(int i=0; i<z; ++i)
00683 for(int j=0; j<x; ++j, ++vert_idx)
00684 {
00685 vert3->at(vert_idx) = (fvec3)(vec3(-xside+j*dx, 0, -zside+i*dz) + origin);
00686 if (gen_texcoords)
00687 {
00688 float tu = (float)j/(x-1);
00689 float tv = (float)i/(z-1);
00690 text2->at(vert_idx).s() = (1.0f-tu) * uv0.s() + tu * uv1.s();
00691 text2->at(vert_idx).t() = (1.0f-tv) * uv0.t() + tv * uv1.t();
00692 }
00693 }
00694
00695
00696 ref<DrawElementsUInt> polys = new DrawElementsUInt(PT_QUADS);
00697 geom->drawCalls()->push_back(polys.get());
00698 int idx = 0;
00699 polys->indices()->resize( (z-1)*(x-1)*4 );
00700 for(int i=0; i<z-1; ++i)
00701 {
00702 for(int j=0; j<x-1; ++j)
00703 {
00704 polys->indices()->at(idx++) = j+0 + x*(i+1);
00705 polys->indices()->at(idx++) = j+1 + x*(i+1);
00706 polys->indices()->at(idx++) = j+1 + x*(i+0);
00707 polys->indices()->at(idx++) = j+0 + x*(i+0);
00708 }
00709 }
00710
00711 return geom;
00712 }
00713
00714 ref<Geometry> vl::makePoints( const std::vector< vec3>& pos, const fvec4& color )
00715 {
00716 ref<Geometry> geom = new Geometry;
00717 geom->setObjectName("Points");
00718
00719 ref<ArrayFloat3> vert3 = new ArrayFloat3;
00720 ref<ArrayFloat4> col4 = new ArrayFloat4;
00721 geom->setVertexArray( vert3.get() );
00722 geom->setColorArray( col4.get() );
00723 vert3->resize( (int)pos.size() );
00724 col4->resize( (int)pos.size() );
00725
00726 for(unsigned i=0; i<pos.size(); ++i)
00727 {
00728 vert3->at(i) = (fvec3)pos[i];
00729 col4->at(i) = color;
00730 }
00731
00732 geom->drawCalls()->push_back( new DrawArrays(PT_POINTS, 0, vert3->size() ));
00733
00734 return geom;
00735 }
00736
00737 ref<Geometry> vl::makeIcosahedron( const vec3& origin, Real diameter )
00738 {
00739 ref<Geometry> geom = new Geometry;
00740 geom->setObjectName("Icosahedron");
00741
00742 ref<ArrayFloat3> vert3 = new ArrayFloat3;
00743 geom->setVertexArray(vert3.get());
00744
00745
00746
00747 const Real x = 0.525731112119133606f / 1.0f;
00748 const Real z = 0.850650808352039932f / 1.0f;
00749 const Real radius = diameter / 2.0f;
00750
00751 vert3->resize( 12 );
00752
00753 vert3->at(0) = (fvec3)(origin + vec3(-x, 0.0, +z)*radius);
00754 vert3->at(1) = (fvec3)(origin + vec3(+x, 0.0, +z)*radius);
00755 vert3->at(2) = (fvec3)(origin + vec3(-x, 0.0, -z)*radius);
00756 vert3->at(3) = (fvec3)(origin + vec3(+x, 0.0, -z)*radius);
00757
00758 vert3->at(4) = (fvec3)(origin + vec3(0.0, +z, +x)*radius);
00759 vert3->at(5) = (fvec3)(origin + vec3(0.0, +z, -x)*radius);
00760 vert3->at(6) = (fvec3)(origin + vec3(0.0, -z, +x)*radius);
00761 vert3->at(7) = (fvec3)(origin + vec3(0.0, -z, -x)*radius);
00762
00763 vert3->at(8) = (fvec3)(origin + vec3(+z, +x, 0.0)*radius);
00764 vert3->at(9) = (fvec3)(origin + vec3(-z, +x, 0.0)*radius);
00765 vert3->at(10) = (fvec3)(origin + vec3(+z, -x, 0.0)*radius);
00766 vert3->at(11) = (fvec3)(origin + vec3(-z, -x, 0.0)*radius);
00767
00768 int faces[20][3] =
00769 {
00770 {1,4,0}, {4,9,0}, {4,5,9}, {8,5,4}, {1,8,4},
00771 {1,10,8}, {10,3,8}, {8,3,5}, {3,2,5}, {3,7,2},
00772 {3,10,7}, {10,6,7}, {6,11,7}, {6,0,11}, {6,1,0},
00773 {10,1,6}, {11,0,9}, {2,11,9}, {5,2,9}, {11,2,7}
00774 };
00775
00776 ref<DrawElementsUInt> polys = new DrawElementsUInt;
00777 geom->drawCalls()->push_back(polys.get());
00778 polys->indices()->resize(20*3);
00779 memcpy(polys->indices()->ptr(), faces, sizeof(int)*20*3);
00780
00781 return geom;
00782 }
00783
00784 ref<Geometry> vl::makeCircle( vec3 origin, Real radius, int slices )
00785 {
00786 ref< Geometry > geom = new Geometry;
00787 geom->setObjectName("Circle");
00788
00789 ref< ArrayFloat3 > points = new ArrayFloat3;
00790 geom->setVertexArray(points.get());
00791 points->resize( slices );
00792 for(int i=0; i<slices; ++i)
00793 {
00794 Real t = 360.0f * i / slices;
00795 vec3 v = mat4::getRotation(t,0,1,0) * vec3(radius,0,0) + origin;
00796 points->at(i) = (fvec3)v;
00797 }
00798 geom->drawCalls()->push_back( new DrawArrays(PT_LINE_LOOP, 0, points->size()) );
00799
00800 return geom;
00801 }
00802
00803 ref<Geometry> vl::makeCapsule(float radius, float height, int segments, ECapsuleCap top_cap, ECapsuleCap bottom_cap, const fvec4& top_col, const fvec4& bottom_col)
00804 {
00805 float height2 = height / 2.0f;
00806
00807 ref<Geometry> geom = new Geometry;
00808 geom->setObjectName("Capsule");
00809
00810 ref<ArrayFloat3> vert_array = new ArrayFloat3;
00811 ref<ArrayFloat4> colr_array = new ArrayFloat4;
00812 geom->setVertexArray(vert_array.get());
00813 geom->setColorArray (colr_array.get());
00814 std::vector<fvec3> verts;
00815 std::vector<fvec4> cols;
00816
00817
00818 for(int i=0; i<segments; ++i)
00819 {
00820 float a = (float)i/segments*fPi*2.0f;
00821 fvec3 v(::cos(a)*radius,+height2,::sin(a)*radius);
00822 verts.push_back(v);
00823 cols.push_back(top_col);
00824 }
00825 if (top_col != bottom_col)
00826 {
00827
00828 for(int i=0; i<segments; ++i)
00829 {
00830 float a = (float)i/segments*fPi*2.0f;
00831 fvec3 v(::cos(a)*radius,0,::sin(a)*radius);
00832 verts.push_back(v);
00833 cols.push_back(top_col);
00834 }
00835
00836 for(int i=0; i<segments; ++i)
00837 {
00838 float a = (float)i/segments*fPi*2.0f;
00839 fvec3 v(::cos(a)*radius,0,::sin(a)*radius);
00840 verts.push_back(v);
00841 cols.push_back(bottom_col);
00842 }
00843 ref<DrawElementsUInt> de_up = new DrawElementsUInt(PT_QUADS);
00844 ref<DrawElementsUInt> de_lo = new DrawElementsUInt(PT_QUADS);
00845 geom->drawCalls()->push_back(de_up.get());
00846 geom->drawCalls()->push_back(de_lo.get());
00847 de_up->indices()->resize(segments*4);
00848 de_lo->indices()->resize(segments*4);
00849 int upup = segments*0;
00850 int uplo = segments*1;
00851 int loup = segments*2;
00852 int lolo = segments*3;
00853 for(int i=0; i<segments; ++i)
00854 {
00855 int i1 = (i+1) % segments;
00856 de_up->indices()->at(i*4+3) = uplo + i;
00857 de_up->indices()->at(i*4+2) = uplo + i1;
00858 de_up->indices()->at(i*4+1) = upup + i1;
00859 de_up->indices()->at(i*4+0) = upup + i;
00860
00861 de_lo->indices()->at(i*4+3) = lolo + i;
00862 de_lo->indices()->at(i*4+2) = lolo + i1;
00863 de_lo->indices()->at(i*4+1) = loup + i1;
00864 de_lo->indices()->at(i*4+0) = loup + i;
00865 }
00866 }
00867 else
00868 {
00869 ref<DrawElementsUInt> de_up = new DrawElementsUInt(PT_QUADS);
00870 geom->drawCalls()->push_back(de_up.get());
00871 de_up->indices()->resize(segments*4);
00872 int upup = segments*0;
00873 int uplo = segments*1;
00874 for(int i=0; i<segments; ++i)
00875 {
00876 int i1 = (i+1) % segments;
00877 de_up->indices()->at(i*4+3) = uplo + i;
00878 de_up->indices()->at(i*4+2) = uplo + i1;
00879 de_up->indices()->at(i*4+1) = upup + i1;
00880 de_up->indices()->at(i*4+0) = upup + i;
00881 }
00882 }
00883
00884 for(int i=0; i<segments; ++i)
00885 {
00886 float a = (float)i/segments*fPi*2.0f;
00887 fvec3 v(::cos(a)*radius,-height2,::sin(a)*radius);
00888 verts.push_back(v);
00889 cols.push_back(bottom_col);
00890 }
00891
00892 if (top_cap == CC_FlatCap)
00893 {
00894 int start = verts.size();
00895 for(int i=0; i<segments; ++i)
00896 {
00897 float a = (float)i/segments*fPi*2.0f;
00898 fvec3 v(::cos(a)*radius,+height2,::sin(a)*radius);
00899 verts.push_back(v);
00900 cols.push_back(top_col);
00901 }
00902 ref<DrawElementsUInt> de = new DrawElementsUInt(PT_TRIANGLE_FAN);
00903 geom->drawCalls()->push_back(de.get());
00904 de->indices()->resize(segments);
00905 for(int i=0,j=segments; j--; ++i)
00906 de->indices()->at(j) = start + i;
00907 }
00908 if (bottom_cap == CC_FlatCap)
00909 {
00910 int start = verts.size();
00911 for(int i=0; i<segments; ++i)
00912 {
00913 float a = (float)i/segments*fPi*2.0f;
00914 fvec3 v(::cos(a)*radius,-height2,::sin(a)*radius);
00915 verts.push_back(v);
00916 cols.push_back(bottom_col);
00917 }
00918 ref<DrawElementsUInt> de = new DrawElementsUInt(PT_TRIANGLE_FAN);
00919 geom->drawCalls()->push_back(de.get());
00920 de->indices()->resize(segments);
00921 for(int i=0; i<segments; ++i)
00922 de->indices()->at(i) = start + i;
00923 }
00924 int segments2 = segments/3; if (segments2<2) segments2=2;
00925 if (top_cap == CC_RoundedCap)
00926 {
00927 int start = verts.size();
00928 for(int j=0; j<segments2; ++j)
00929 {
00930 float aj = (float)j/segments2*fPi/2.0f;
00931 for(int i=0; i<segments; ++i)
00932 {
00933 float a = (float)i/segments*360;
00934 fvec3 v(::cos(aj)*radius,::sin(aj)*radius,0);
00935 verts.push_back(fmat4::getRotation(a,0,1,0) * v + fvec3(0,height2,0));
00936 cols.push_back(top_col);
00937 }
00938 }
00939
00940 verts.push_back(fvec3(0,+height2+radius,0));
00941 cols.push_back(top_col);
00942
00943 ref<DrawElementsUInt> de_quads = new DrawElementsUInt(PT_QUADS);
00944 geom->drawCalls()->push_back(de_quads.get());
00945 de_quads->indices()->resize(segments*(segments2-1)*4);
00946 for(int j=0,idx=0; j<segments2-1; ++j)
00947 {
00948 int uplo = start+segments*j;
00949 int upup = start+segments*(j+1);
00950 for(int i=0; i<segments; ++i)
00951 {
00952 int i1 = (i+1) % segments;
00953 de_quads->indices()->at(idx++) = uplo + i;
00954 de_quads->indices()->at(idx++) = uplo + i1;
00955 de_quads->indices()->at(idx++) = upup + i1;
00956 de_quads->indices()->at(idx++) = upup + i;
00957 }
00958 }
00959
00960 ref<DrawElementsUInt> de = new DrawElementsUInt(PT_TRIANGLE_FAN);
00961 geom->drawCalls()->push_back(de.get());
00962 de->indices()->resize(segments+2);
00963 de->indices()->at(0) = (GLuint)verts.size()-1;
00964 for(int i=0; i<segments+1; ++i)
00965 de->indices()->at(i+1) = (GLuint)verts.size()-1-segments+i%segments;
00966 }
00967 if (bottom_cap == CC_RoundedCap)
00968 {
00969 int start = verts.size();
00970 for(int j=0; j<segments2; ++j)
00971 {
00972 float aj = (float)j/segments2*fPi/2.0f;
00973 for(int i=0; i<segments; ++i)
00974 {
00975 float a = -(float)i/segments*360;
00976 fvec3 v(::cos(aj)*radius,-::sin(aj)*radius,0);
00977 verts.push_back(fmat4::getRotation(a,0,1,0) * v + fvec3(0,-height2,0));
00978 cols.push_back(bottom_col);
00979 }
00980 }
00981
00982 verts.push_back(fvec3(0,-height2-radius,0));
00983 cols.push_back(bottom_col);
00984
00985 ref<DrawElementsUInt> de_quads = new DrawElementsUInt(PT_QUADS);
00986 geom->drawCalls()->push_back(de_quads.get());
00987 de_quads->indices()->resize(segments*(segments2-1)*4);
00988 for(int j=0,idx=0; j<segments2-1; ++j)
00989 {
00990 int uplo = start+segments*j;
00991 int upup = start+segments*(j+1);
00992 for(int i=0; i<segments; ++i)
00993 {
00994 int i1 = (i+1) % segments;
00995 de_quads->indices()->at(idx++) = uplo + i;
00996 de_quads->indices()->at(idx++) = uplo + i1;
00997 de_quads->indices()->at(idx++) = upup + i1;
00998 de_quads->indices()->at(idx++) = upup + i;
00999 }
01000 }
01001
01002 ref<DrawElementsUInt> de = new DrawElementsUInt(PT_TRIANGLE_FAN);
01003 geom->drawCalls()->push_back(de.get());
01004 de->indices()->resize(segments+2);
01005 de->indices()->at(0) = (GLuint)verts.size()-1;
01006 for(int i=0; i<segments+1; ++i)
01007 de->indices()->at(i+1) = (GLuint)verts.size()-1-segments+i%segments;
01008 }
01009
01010 *vert_array = verts;
01011 *colr_array = cols;
01012
01013 return geom;
01014 }
01015