vrshoot
diff libs/assimp/StandardShapes.cpp @ 0:b2f14e535253
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 01 Feb 2014 19:58:19 +0200 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libs/assimp/StandardShapes.cpp Sat Feb 01 19:58:19 2014 +0200 1.3 @@ -0,0 +1,502 @@ 1.4 +/* 1.5 +Open Asset Import Library (assimp) 1.6 +---------------------------------------------------------------------- 1.7 + 1.8 +Copyright (c) 2006-2012, assimp team 1.9 +All rights reserved. 1.10 + 1.11 +Redistribution and use of this software in source and binary forms, 1.12 +with or without modification, are permitted provided that the 1.13 +following conditions are met: 1.14 + 1.15 +* Redistributions of source code must retain the above 1.16 + copyright notice, this list of conditions and the 1.17 + following disclaimer. 1.18 + 1.19 +* Redistributions in binary form must reproduce the above 1.20 + copyright notice, this list of conditions and the 1.21 + following disclaimer in the documentation and/or other 1.22 + materials provided with the distribution. 1.23 + 1.24 +* Neither the name of the assimp team, nor the names of its 1.25 + contributors may be used to endorse or promote products 1.26 + derived from this software without specific prior 1.27 + written permission of the assimp team. 1.28 + 1.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.40 + 1.41 +---------------------------------------------------------------------- 1.42 +*/ 1.43 + 1.44 +/** @file StandardShapes.cpp 1.45 + * @brief Implementation of the StandardShapes class 1.46 + * 1.47 + * The primitive geometry data comes from 1.48 + * http://geometrictools.com/Documentation/PlatonicSolids.pdf. 1.49 + */ 1.50 + 1.51 +#include "AssimpPCH.h" 1.52 +#include "StandardShapes.h" 1.53 + 1.54 +namespace Assimp { 1.55 + 1.56 + 1.57 +# define ADD_TRIANGLE(n0,n1,n2) \ 1.58 + positions.push_back(n0); \ 1.59 + positions.push_back(n1); \ 1.60 + positions.push_back(n2); 1.61 + 1.62 +# define ADD_PENTAGON(n0,n1,n2,n3,n4) \ 1.63 + if (polygons) \ 1.64 + { \ 1.65 + positions.push_back(n0); \ 1.66 + positions.push_back(n1); \ 1.67 + positions.push_back(n2); \ 1.68 + positions.push_back(n3); \ 1.69 + positions.push_back(n4); \ 1.70 + } \ 1.71 + else \ 1.72 + { \ 1.73 + ADD_TRIANGLE(n0, n1, n2) \ 1.74 + ADD_TRIANGLE(n0, n2, n3) \ 1.75 + ADD_TRIANGLE(n0, n3, n4) \ 1.76 + } 1.77 + 1.78 +# define ADD_QUAD(n0,n1,n2,n3) \ 1.79 + if (polygons) \ 1.80 + { \ 1.81 + positions.push_back(n0); \ 1.82 + positions.push_back(n1); \ 1.83 + positions.push_back(n2); \ 1.84 + positions.push_back(n3); \ 1.85 + } \ 1.86 + else \ 1.87 + { \ 1.88 + ADD_TRIANGLE(n0, n1, n2) \ 1.89 + ADD_TRIANGLE(n0, n2, n3) \ 1.90 + } 1.91 + 1.92 + 1.93 +// ------------------------------------------------------------------------------------------------ 1.94 +// Fast subdivision for a mesh whose verts have a magnitude of 1 1.95 +void Subdivide(std::vector<aiVector3D>& positions) 1.96 +{ 1.97 + // assume this to be constant - (fixme: must be 1.0? I think so) 1.98 + const float fl1 = positions[0].Length(); 1.99 + 1.100 + unsigned int origSize = (unsigned int)positions.size(); 1.101 + for (unsigned int i = 0 ; i < origSize ; i+=3) 1.102 + { 1.103 + aiVector3D& tv0 = positions[i]; 1.104 + aiVector3D& tv1 = positions[i+1]; 1.105 + aiVector3D& tv2 = positions[i+2]; 1.106 + 1.107 + aiVector3D a = tv0, b = tv1, c = tv2; 1.108 + aiVector3D v1 = aiVector3D(a.x+b.x, a.y+b.y, a.z+b.z).Normalize()*fl1; 1.109 + aiVector3D v2 = aiVector3D(a.x+c.x, a.y+c.y, a.z+c.z).Normalize()*fl1; 1.110 + aiVector3D v3 = aiVector3D(b.x+c.x, b.y+c.y, b.z+c.z).Normalize()*fl1; 1.111 + 1.112 + tv0 = v1; tv1 = v3; tv2 = v2; // overwrite the original 1.113 + ADD_TRIANGLE(v1, v2, a); 1.114 + ADD_TRIANGLE(v2, v3, c); 1.115 + ADD_TRIANGLE(v3, v1, b); 1.116 + } 1.117 +} 1.118 + 1.119 +// ------------------------------------------------------------------------------------------------ 1.120 +// Construct a mesh from given vertex positions 1.121 +aiMesh* StandardShapes::MakeMesh(const std::vector<aiVector3D>& positions, 1.122 + unsigned int numIndices) 1.123 +{ 1.124 + if (positions.size() & numIndices || positions.empty() || !numIndices) 1.125 + return NULL; 1.126 + 1.127 + // Determine which kinds of primitives the mesh consists of 1.128 + aiMesh* out = new aiMesh(); 1.129 + switch (numIndices) 1.130 + { 1.131 + case 1: 1.132 + out->mPrimitiveTypes = aiPrimitiveType_POINT; 1.133 + break; 1.134 + case 2: 1.135 + out->mPrimitiveTypes = aiPrimitiveType_LINE; 1.136 + break; 1.137 + case 3: 1.138 + out->mPrimitiveTypes = aiPrimitiveType_TRIANGLE; 1.139 + break; 1.140 + default: 1.141 + out->mPrimitiveTypes = aiPrimitiveType_POLYGON; 1.142 + break; 1.143 + }; 1.144 + 1.145 + out->mNumFaces = (unsigned int)positions.size() / numIndices; 1.146 + out->mFaces = new aiFace[out->mNumFaces]; 1.147 + for (unsigned int i = 0, a = 0; i < out->mNumFaces;++i) 1.148 + { 1.149 + aiFace& f = out->mFaces[i]; 1.150 + f.mNumIndices = numIndices; 1.151 + f.mIndices = new unsigned int[numIndices]; 1.152 + for (unsigned int i = 0; i < numIndices;++i,++a) 1.153 + f.mIndices[i] = a; 1.154 + } 1.155 + out->mNumVertices = (unsigned int)positions.size(); 1.156 + out->mVertices = new aiVector3D[out->mNumVertices]; 1.157 + ::memcpy(out->mVertices,&positions[0],out->mNumVertices*sizeof(aiVector3D)); 1.158 + return out; 1.159 +} 1.160 + 1.161 +// ------------------------------------------------------------------------------------------------ 1.162 +// Construct a mesh with a specific shape (callback) 1.163 +aiMesh* StandardShapes::MakeMesh ( unsigned int (*GenerateFunc)( 1.164 + std::vector<aiVector3D>&)) 1.165 +{ 1.166 + std::vector<aiVector3D> temp; 1.167 + unsigned num = (*GenerateFunc)(temp); 1.168 + return MakeMesh(temp,num); 1.169 +} 1.170 + 1.171 +// ------------------------------------------------------------------------------------------------ 1.172 +// Construct a mesh with a specific shape (callback) 1.173 +aiMesh* StandardShapes::MakeMesh ( unsigned int (*GenerateFunc)( 1.174 + std::vector<aiVector3D>&, bool)) 1.175 +{ 1.176 + std::vector<aiVector3D> temp; 1.177 + unsigned num = (*GenerateFunc)(temp,true); 1.178 + return MakeMesh(temp,num); 1.179 +} 1.180 + 1.181 +// ------------------------------------------------------------------------------------------------ 1.182 +// Construct a mesh with a specific shape (callback) 1.183 +aiMesh* StandardShapes::MakeMesh (unsigned int num, void (*GenerateFunc)( 1.184 + unsigned int,std::vector<aiVector3D>&)) 1.185 +{ 1.186 + std::vector<aiVector3D> temp; 1.187 + (*GenerateFunc)(num,temp); 1.188 + return MakeMesh(temp,3); 1.189 +} 1.190 + 1.191 +// ------------------------------------------------------------------------------------------------ 1.192 +// Build an incosahedron with points.magnitude == 1 1.193 +unsigned int StandardShapes::MakeIcosahedron(std::vector<aiVector3D>& positions) 1.194 +{ 1.195 + positions.reserve(positions.size()+60); 1.196 + 1.197 + const float t = (1.f + 2.236067977f)/2.f; 1.198 + const float s = sqrt(1.f + t*t); 1.199 + 1.200 + const aiVector3D v0 = aiVector3D(t,1.f, 0.f)/s; 1.201 + const aiVector3D v1 = aiVector3D(-t,1.f, 0.f)/s; 1.202 + const aiVector3D v2 = aiVector3D(t,-1.f, 0.f)/s; 1.203 + const aiVector3D v3 = aiVector3D(-t,-1.f, 0.f)/s; 1.204 + const aiVector3D v4 = aiVector3D(1.f, 0.f, t)/s; 1.205 + const aiVector3D v5 = aiVector3D(1.f, 0.f,-t)/s; 1.206 + const aiVector3D v6 = aiVector3D(-1.f, 0.f,t)/s; 1.207 + const aiVector3D v7 = aiVector3D(-1.f, 0.f,-t)/s; 1.208 + const aiVector3D v8 = aiVector3D(0.f, t, 1.f)/s; 1.209 + const aiVector3D v9 = aiVector3D(0.f,-t, 1.f)/s; 1.210 + const aiVector3D v10 = aiVector3D(0.f, t,-1.f)/s; 1.211 + const aiVector3D v11 = aiVector3D(0.f,-t,-1.f)/s; 1.212 + 1.213 + ADD_TRIANGLE(v0,v8,v4); 1.214 + ADD_TRIANGLE(v0,v5,v10); 1.215 + ADD_TRIANGLE(v2,v4,v9); 1.216 + ADD_TRIANGLE(v2,v11,v5); 1.217 + 1.218 + ADD_TRIANGLE(v1,v6,v8); 1.219 + ADD_TRIANGLE(v1,v10,v7); 1.220 + ADD_TRIANGLE(v3,v9,v6); 1.221 + ADD_TRIANGLE(v3,v7,v11); 1.222 + 1.223 + ADD_TRIANGLE(v0,v10,v8); 1.224 + ADD_TRIANGLE(v1,v8,v10); 1.225 + ADD_TRIANGLE(v2,v9,v11); 1.226 + ADD_TRIANGLE(v3,v11,v9); 1.227 + 1.228 + ADD_TRIANGLE(v4,v2,v0); 1.229 + ADD_TRIANGLE(v5,v0,v2); 1.230 + ADD_TRIANGLE(v6,v1,v3); 1.231 + ADD_TRIANGLE(v7,v3,v1); 1.232 + 1.233 + ADD_TRIANGLE(v8,v6,v4); 1.234 + ADD_TRIANGLE(v9,v4,v6); 1.235 + ADD_TRIANGLE(v10,v5,v7); 1.236 + ADD_TRIANGLE(v11,v7,v5); 1.237 + return 3; 1.238 +} 1.239 + 1.240 +// ------------------------------------------------------------------------------------------------ 1.241 +// Build a dodecahedron with points.magnitude == 1 1.242 +unsigned int StandardShapes::MakeDodecahedron(std::vector<aiVector3D>& positions, 1.243 + bool polygons /*= false*/) 1.244 +{ 1.245 + positions.reserve(positions.size()+108); 1.246 + 1.247 + const float a = 1.f / 1.7320508f; 1.248 + const float b = sqrt((3.f-2.23606797f)/6.f); 1.249 + const float c = sqrt((3.f+2.23606797f)/6.f); 1.250 + 1.251 + const aiVector3D v0 = aiVector3D(a,a,a); 1.252 + const aiVector3D v1 = aiVector3D(a,a,-a); 1.253 + const aiVector3D v2 = aiVector3D(a,-a,a); 1.254 + const aiVector3D v3 = aiVector3D(a,-a,-a); 1.255 + const aiVector3D v4 = aiVector3D(-a,a,a); 1.256 + const aiVector3D v5 = aiVector3D(-a,a,-a); 1.257 + const aiVector3D v6 = aiVector3D(-a,-a,a); 1.258 + const aiVector3D v7 = aiVector3D(-a,-a,-a); 1.259 + const aiVector3D v8 = aiVector3D(b,c,0.f); 1.260 + const aiVector3D v9 = aiVector3D(-b,c,0.f); 1.261 + const aiVector3D v10 = aiVector3D(b,-c,0.f); 1.262 + const aiVector3D v11 = aiVector3D(-b,-c,0.f); 1.263 + const aiVector3D v12 = aiVector3D(c, 0.f, b); 1.264 + const aiVector3D v13 = aiVector3D(c, 0.f, -b); 1.265 + const aiVector3D v14 = aiVector3D(-c, 0.f, b); 1.266 + const aiVector3D v15 = aiVector3D(-c, 0.f, -b); 1.267 + const aiVector3D v16 = aiVector3D(0.f, b, c); 1.268 + const aiVector3D v17 = aiVector3D(0.f, -b, c); 1.269 + const aiVector3D v18 = aiVector3D(0.f, b, -c); 1.270 + const aiVector3D v19 = aiVector3D(0.f, -b, -c); 1.271 + 1.272 + ADD_PENTAGON(v0, v8, v9, v4, v16); 1.273 + ADD_PENTAGON(v0, v12, v13, v1, v8); 1.274 + ADD_PENTAGON(v0, v16, v17, v2, v12); 1.275 + ADD_PENTAGON(v8, v1, v18, v5, v9); 1.276 + ADD_PENTAGON(v12, v2, v10, v3, v13); 1.277 + ADD_PENTAGON(v16, v4, v14, v6, v17); 1.278 + ADD_PENTAGON(v9, v5, v15, v14, v4); 1.279 + 1.280 + ADD_PENTAGON(v6, v11, v10, v2, v17); 1.281 + ADD_PENTAGON(v3, v19, v18, v1, v13); 1.282 + ADD_PENTAGON(v7, v15, v5, v18, v19); 1.283 + ADD_PENTAGON(v7, v11, v6, v14, v15); 1.284 + ADD_PENTAGON(v7, v19, v3, v10, v11); 1.285 + return (polygons ? 5 : 3); 1.286 +} 1.287 + 1.288 +// ------------------------------------------------------------------------------------------------ 1.289 +// Build an octahedron with points.magnitude == 1 1.290 +unsigned int StandardShapes::MakeOctahedron(std::vector<aiVector3D>& positions) 1.291 +{ 1.292 + positions.reserve(positions.size()+24); 1.293 + 1.294 + const aiVector3D v0 = aiVector3D(1.0f, 0.f, 0.f) ; 1.295 + const aiVector3D v1 = aiVector3D(-1.0f, 0.f, 0.f); 1.296 + const aiVector3D v2 = aiVector3D(0.f, 1.0f, 0.f); 1.297 + const aiVector3D v3 = aiVector3D(0.f, -1.0f, 0.f); 1.298 + const aiVector3D v4 = aiVector3D(0.f, 0.f, 1.0f); 1.299 + const aiVector3D v5 = aiVector3D(0.f, 0.f, -1.0f); 1.300 + 1.301 + ADD_TRIANGLE(v4,v0,v2); 1.302 + ADD_TRIANGLE(v4,v2,v1); 1.303 + ADD_TRIANGLE(v4,v1,v3); 1.304 + ADD_TRIANGLE(v4,v3,v0); 1.305 + 1.306 + ADD_TRIANGLE(v5,v2,v0); 1.307 + ADD_TRIANGLE(v5,v1,v2); 1.308 + ADD_TRIANGLE(v5,v3,v1); 1.309 + ADD_TRIANGLE(v5,v0,v3); 1.310 + return 3; 1.311 +} 1.312 + 1.313 +// ------------------------------------------------------------------------------------------------ 1.314 +// Build a tetrahedron with points.magnitude == 1 1.315 +unsigned int StandardShapes::MakeTetrahedron(std::vector<aiVector3D>& positions) 1.316 +{ 1.317 + positions.reserve(positions.size()+9); 1.318 + 1.319 + const float a = 1.41421f/3.f; 1.320 + const float b = 2.4494f/3.f; 1.321 + 1.322 + const aiVector3D v0 = aiVector3D(0.f,0.f,1.f); 1.323 + const aiVector3D v1 = aiVector3D(2*a,0,-1.f/3.f); 1.324 + const aiVector3D v2 = aiVector3D(-a,b,-1.f/3.f); 1.325 + const aiVector3D v3 = aiVector3D(-a,-b,-1.f/3.f); 1.326 + 1.327 + ADD_TRIANGLE(v0,v1,v2); 1.328 + ADD_TRIANGLE(v0,v2,v3); 1.329 + ADD_TRIANGLE(v0,v3,v1); 1.330 + ADD_TRIANGLE(v1,v3,v2); 1.331 + return 3; 1.332 +} 1.333 + 1.334 +// ------------------------------------------------------------------------------------------------ 1.335 +// Build a hexahedron with points.magnitude == 1 1.336 +unsigned int StandardShapes::MakeHexahedron(std::vector<aiVector3D>& positions, 1.337 + bool polygons /*= false*/) 1.338 +{ 1.339 + positions.reserve(positions.size()+36); 1.340 + const float length = 1.f/1.73205080f; 1.341 + 1.342 + const aiVector3D v0 = aiVector3D(-1.f,-1.f,-1.f)*length; 1.343 + const aiVector3D v1 = aiVector3D(1.f,-1.f,-1.f)*length; 1.344 + const aiVector3D v2 = aiVector3D(1.f,1.f,-1.f)*length; 1.345 + const aiVector3D v3 = aiVector3D(-1.f,1.f,-1.f)*length; 1.346 + const aiVector3D v4 = aiVector3D(-1.f,-1.f,1.f)*length; 1.347 + const aiVector3D v5 = aiVector3D(1.f,-1.f,1.f)*length; 1.348 + const aiVector3D v6 = aiVector3D(1.f,1.f,1.f)*length; 1.349 + const aiVector3D v7 = aiVector3D(-1.f,1.f,1.f)*length; 1.350 + 1.351 + ADD_QUAD(v0,v3,v2,v1); 1.352 + ADD_QUAD(v0,v1,v5,v4); 1.353 + ADD_QUAD(v0,v4,v7,v3); 1.354 + ADD_QUAD(v6,v5,v1,v2); 1.355 + ADD_QUAD(v6,v2,v3,v7); 1.356 + ADD_QUAD(v6,v7,v4,v5); 1.357 + return (polygons ? 4 : 3); 1.358 +} 1.359 + 1.360 +// Cleanup ... 1.361 +#undef ADD_TRIANGLE 1.362 +#undef ADD_QUAD 1.363 +#undef ADD_PENTAGON 1.364 + 1.365 +// ------------------------------------------------------------------------------------------------ 1.366 +// Create a subdivision sphere 1.367 +void StandardShapes::MakeSphere(unsigned int tess, 1.368 + std::vector<aiVector3D>& positions) 1.369 +{ 1.370 + // Reserve enough storage. Every subdivision 1.371 + // splits each triangle in 4, the icosahedron consists of 60 verts 1.372 + positions.reserve(positions.size()+60 * integer_pow(4, tess)); 1.373 + 1.374 + // Construct an icosahedron to start with 1.375 + MakeIcosahedron(positions); 1.376 + 1.377 + // ... and subdivide it until the requested output 1.378 + // tesselation is reached 1.379 + for (unsigned int i = 0; i<tess;++i) 1.380 + Subdivide(positions); 1.381 +} 1.382 + 1.383 +// ------------------------------------------------------------------------------------------------ 1.384 +// Build a cone 1.385 +void StandardShapes::MakeCone(float height,float radius1, 1.386 + float radius2,unsigned int tess, 1.387 + std::vector<aiVector3D>& positions,bool bOpen /*= false */) 1.388 +{ 1.389 + // Sorry, a cone with less than 3 segments makes ABSOLUTELY NO SENSE 1.390 + if (tess < 3 || !height) 1.391 + return; 1.392 + 1.393 + size_t old = positions.size(); 1.394 + 1.395 + // No negative radii 1.396 + radius1 = ::fabs(radius1); 1.397 + radius2 = ::fabs(radius2); 1.398 + 1.399 + float halfHeight = height / 2; 1.400 + 1.401 + // radius1 is always the smaller one 1.402 + if (radius2 > radius1) 1.403 + { 1.404 + std::swap(radius2,radius1); 1.405 + halfHeight = -halfHeight; 1.406 + } 1.407 + else old = SIZE_MAX; 1.408 + 1.409 + // Use a large epsilon to check whether the cone is pointy 1.410 + if (radius1 < (radius2-radius1)*10e-3f)radius1 = 0.f; 1.411 + 1.412 + // We will need 3*2 verts per segment + 3*2 verts per segment 1.413 + // if the cone is closed 1.414 + const unsigned int mem = tess*6 + (!bOpen ? tess*3 * (radius1 ? 2 : 1) : 0); 1.415 + positions.reserve(positions.size () + mem); 1.416 + 1.417 + // Now construct all segments 1.418 + const float angle_delta = (float)AI_MATH_TWO_PI / tess; 1.419 + const float angle_max = (float)AI_MATH_TWO_PI; 1.420 + 1.421 + float s = 1.f; // cos(angle == 0); 1.422 + float t = 0.f; // sin(angle == 0); 1.423 + 1.424 + for (float angle = 0.f; angle < angle_max; ) 1.425 + { 1.426 + const aiVector3D v1 = aiVector3D (s * radius1, -halfHeight, t * radius1 ); 1.427 + const aiVector3D v2 = aiVector3D (s * radius2, halfHeight, t * radius2 ); 1.428 + 1.429 + const float next = angle + angle_delta; 1.430 + float s2 = ::cos(next); 1.431 + float t2 = ::sin(next); 1.432 + 1.433 + const aiVector3D v3 = aiVector3D (s2 * radius2, halfHeight, t2 * radius2 ); 1.434 + const aiVector3D v4 = aiVector3D (s2 * radius1, -halfHeight, t2 * radius1 ); 1.435 + 1.436 + positions.push_back(v1); 1.437 + positions.push_back(v2); 1.438 + positions.push_back(v3); 1.439 + positions.push_back(v4); 1.440 + positions.push_back(v1); 1.441 + positions.push_back(v3); 1.442 + 1.443 + if (!bOpen) 1.444 + { 1.445 + // generate the end 'cap' 1.446 + positions.push_back(aiVector3D(s * radius2, halfHeight, t * radius2 )); 1.447 + positions.push_back(aiVector3D(s2 * radius2, halfHeight, t2 * radius2 )); 1.448 + positions.push_back(aiVector3D(0.f, halfHeight, 0.f)); 1.449 + 1.450 + 1.451 + if (radius1) 1.452 + { 1.453 + // generate the other end 'cap' 1.454 + positions.push_back(aiVector3D(s * radius1, -halfHeight, t * radius1 )); 1.455 + positions.push_back(aiVector3D(s2 * radius1, -halfHeight, t2 * radius1 )); 1.456 + positions.push_back(aiVector3D(0.f, -halfHeight, 0.f)); 1.457 + 1.458 + } 1.459 + } 1.460 + s = s2; 1.461 + t = t2; 1.462 + angle = next; 1.463 + } 1.464 + 1.465 + // Need to flip face order? 1.466 + if ( SIZE_MAX != old ) { 1.467 + for (size_t s = old; s < positions.size();s += 3) { 1.468 + std::swap(positions[s],positions[s+1]); 1.469 + } 1.470 + } 1.471 +} 1.472 + 1.473 +// ------------------------------------------------------------------------------------------------ 1.474 +// Build a circle 1.475 +void StandardShapes::MakeCircle(float radius, unsigned int tess, 1.476 + std::vector<aiVector3D>& positions) 1.477 +{ 1.478 + // Sorry, a circle with less than 3 segments makes ABSOLUTELY NO SENSE 1.479 + if (tess < 3 || !radius) 1.480 + return; 1.481 + 1.482 + radius = ::fabs(radius); 1.483 + 1.484 + // We will need 3 vertices per segment 1.485 + positions.reserve(positions.size()+tess*3); 1.486 + 1.487 + const float angle_delta = (float)AI_MATH_TWO_PI / tess; 1.488 + const float angle_max = (float)AI_MATH_TWO_PI; 1.489 + 1.490 + float s = 1.f; // cos(angle == 0); 1.491 + float t = 0.f; // sin(angle == 0); 1.492 + 1.493 + for (float angle = 0.f; angle < angle_max; ) 1.494 + { 1.495 + positions.push_back(aiVector3D(s * radius,0.f,t * radius)); 1.496 + angle += angle_delta; 1.497 + s = ::cos(angle); 1.498 + t = ::sin(angle); 1.499 + positions.push_back(aiVector3D(s * radius,0.f,t * radius)); 1.500 + 1.501 + positions.push_back(aiVector3D(0.f,0.f,0.f)); 1.502 + } 1.503 +} 1.504 + 1.505 +} // ! Assimp