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