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