rev |
line source |
nuclear@0
|
1 /*
|
nuclear@0
|
2 Open Asset Import Library (assimp)
|
nuclear@0
|
3 ----------------------------------------------------------------------
|
nuclear@0
|
4
|
nuclear@0
|
5 Copyright (c) 2006-2012, assimp team
|
nuclear@0
|
6 All rights reserved.
|
nuclear@0
|
7
|
nuclear@0
|
8 Redistribution and use of this software in source and binary forms,
|
nuclear@0
|
9 with or without modification, are permitted provided that the
|
nuclear@0
|
10 following conditions are met:
|
nuclear@0
|
11
|
nuclear@0
|
12 * Redistributions of source code must retain the above
|
nuclear@0
|
13 copyright notice, this list of conditions and the
|
nuclear@0
|
14 following disclaimer.
|
nuclear@0
|
15
|
nuclear@0
|
16 * Redistributions in binary form must reproduce the above
|
nuclear@0
|
17 copyright notice, this list of conditions and the
|
nuclear@0
|
18 following disclaimer in the documentation and/or other
|
nuclear@0
|
19 materials provided with the distribution.
|
nuclear@0
|
20
|
nuclear@0
|
21 * Neither the name of the assimp team, nor the names of its
|
nuclear@0
|
22 contributors may be used to endorse or promote products
|
nuclear@0
|
23 derived from this software without specific prior
|
nuclear@0
|
24 written permission of the assimp team.
|
nuclear@0
|
25
|
nuclear@0
|
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
nuclear@0
|
27 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
nuclear@0
|
28 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
nuclear@0
|
29 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
nuclear@0
|
30 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
nuclear@0
|
31 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
nuclear@0
|
32 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
nuclear@0
|
33 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
nuclear@0
|
34 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
nuclear@0
|
35 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
nuclear@0
|
36 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
nuclear@0
|
37
|
nuclear@0
|
38 ----------------------------------------------------------------------
|
nuclear@0
|
39 */
|
nuclear@0
|
40
|
nuclear@0
|
41 /** @file StandardShapes.cpp
|
nuclear@0
|
42 * @brief Implementation of the StandardShapes class
|
nuclear@0
|
43 *
|
nuclear@0
|
44 * The primitive geometry data comes from
|
nuclear@0
|
45 * http://geometrictools.com/Documentation/PlatonicSolids.pdf.
|
nuclear@0
|
46 */
|
nuclear@0
|
47
|
nuclear@0
|
48 #include "AssimpPCH.h"
|
nuclear@0
|
49 #include "StandardShapes.h"
|
nuclear@0
|
50
|
nuclear@0
|
51 namespace Assimp {
|
nuclear@0
|
52
|
nuclear@0
|
53
|
nuclear@0
|
54 # define ADD_TRIANGLE(n0,n1,n2) \
|
nuclear@0
|
55 positions.push_back(n0); \
|
nuclear@0
|
56 positions.push_back(n1); \
|
nuclear@0
|
57 positions.push_back(n2);
|
nuclear@0
|
58
|
nuclear@0
|
59 # define ADD_PENTAGON(n0,n1,n2,n3,n4) \
|
nuclear@0
|
60 if (polygons) \
|
nuclear@0
|
61 { \
|
nuclear@0
|
62 positions.push_back(n0); \
|
nuclear@0
|
63 positions.push_back(n1); \
|
nuclear@0
|
64 positions.push_back(n2); \
|
nuclear@0
|
65 positions.push_back(n3); \
|
nuclear@0
|
66 positions.push_back(n4); \
|
nuclear@0
|
67 } \
|
nuclear@0
|
68 else \
|
nuclear@0
|
69 { \
|
nuclear@0
|
70 ADD_TRIANGLE(n0, n1, n2) \
|
nuclear@0
|
71 ADD_TRIANGLE(n0, n2, n3) \
|
nuclear@0
|
72 ADD_TRIANGLE(n0, n3, n4) \
|
nuclear@0
|
73 }
|
nuclear@0
|
74
|
nuclear@0
|
75 # define ADD_QUAD(n0,n1,n2,n3) \
|
nuclear@0
|
76 if (polygons) \
|
nuclear@0
|
77 { \
|
nuclear@0
|
78 positions.push_back(n0); \
|
nuclear@0
|
79 positions.push_back(n1); \
|
nuclear@0
|
80 positions.push_back(n2); \
|
nuclear@0
|
81 positions.push_back(n3); \
|
nuclear@0
|
82 } \
|
nuclear@0
|
83 else \
|
nuclear@0
|
84 { \
|
nuclear@0
|
85 ADD_TRIANGLE(n0, n1, n2) \
|
nuclear@0
|
86 ADD_TRIANGLE(n0, n2, n3) \
|
nuclear@0
|
87 }
|
nuclear@0
|
88
|
nuclear@0
|
89
|
nuclear@0
|
90 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
91 // Fast subdivision for a mesh whose verts have a magnitude of 1
|
nuclear@0
|
92 void Subdivide(std::vector<aiVector3D>& positions)
|
nuclear@0
|
93 {
|
nuclear@0
|
94 // assume this to be constant - (fixme: must be 1.0? I think so)
|
nuclear@0
|
95 const float fl1 = positions[0].Length();
|
nuclear@0
|
96
|
nuclear@0
|
97 unsigned int origSize = (unsigned int)positions.size();
|
nuclear@0
|
98 for (unsigned int i = 0 ; i < origSize ; i+=3)
|
nuclear@0
|
99 {
|
nuclear@0
|
100 aiVector3D& tv0 = positions[i];
|
nuclear@0
|
101 aiVector3D& tv1 = positions[i+1];
|
nuclear@0
|
102 aiVector3D& tv2 = positions[i+2];
|
nuclear@0
|
103
|
nuclear@0
|
104 aiVector3D a = tv0, b = tv1, c = tv2;
|
nuclear@0
|
105 aiVector3D v1 = aiVector3D(a.x+b.x, a.y+b.y, a.z+b.z).Normalize()*fl1;
|
nuclear@0
|
106 aiVector3D v2 = aiVector3D(a.x+c.x, a.y+c.y, a.z+c.z).Normalize()*fl1;
|
nuclear@0
|
107 aiVector3D v3 = aiVector3D(b.x+c.x, b.y+c.y, b.z+c.z).Normalize()*fl1;
|
nuclear@0
|
108
|
nuclear@0
|
109 tv0 = v1; tv1 = v3; tv2 = v2; // overwrite the original
|
nuclear@0
|
110 ADD_TRIANGLE(v1, v2, a);
|
nuclear@0
|
111 ADD_TRIANGLE(v2, v3, c);
|
nuclear@0
|
112 ADD_TRIANGLE(v3, v1, b);
|
nuclear@0
|
113 }
|
nuclear@0
|
114 }
|
nuclear@0
|
115
|
nuclear@0
|
116 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
117 // Construct a mesh from given vertex positions
|
nuclear@0
|
118 aiMesh* StandardShapes::MakeMesh(const std::vector<aiVector3D>& positions,
|
nuclear@0
|
119 unsigned int numIndices)
|
nuclear@0
|
120 {
|
nuclear@0
|
121 if (positions.size() & numIndices || positions.empty() || !numIndices)
|
nuclear@0
|
122 return NULL;
|
nuclear@0
|
123
|
nuclear@0
|
124 // Determine which kinds of primitives the mesh consists of
|
nuclear@0
|
125 aiMesh* out = new aiMesh();
|
nuclear@0
|
126 switch (numIndices)
|
nuclear@0
|
127 {
|
nuclear@0
|
128 case 1:
|
nuclear@0
|
129 out->mPrimitiveTypes = aiPrimitiveType_POINT;
|
nuclear@0
|
130 break;
|
nuclear@0
|
131 case 2:
|
nuclear@0
|
132 out->mPrimitiveTypes = aiPrimitiveType_LINE;
|
nuclear@0
|
133 break;
|
nuclear@0
|
134 case 3:
|
nuclear@0
|
135 out->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
|
nuclear@0
|
136 break;
|
nuclear@0
|
137 default:
|
nuclear@0
|
138 out->mPrimitiveTypes = aiPrimitiveType_POLYGON;
|
nuclear@0
|
139 break;
|
nuclear@0
|
140 };
|
nuclear@0
|
141
|
nuclear@0
|
142 out->mNumFaces = (unsigned int)positions.size() / numIndices;
|
nuclear@0
|
143 out->mFaces = new aiFace[out->mNumFaces];
|
nuclear@0
|
144 for (unsigned int i = 0, a = 0; i < out->mNumFaces;++i)
|
nuclear@0
|
145 {
|
nuclear@0
|
146 aiFace& f = out->mFaces[i];
|
nuclear@0
|
147 f.mNumIndices = numIndices;
|
nuclear@0
|
148 f.mIndices = new unsigned int[numIndices];
|
nuclear@0
|
149 for (unsigned int i = 0; i < numIndices;++i,++a)
|
nuclear@0
|
150 f.mIndices[i] = a;
|
nuclear@0
|
151 }
|
nuclear@0
|
152 out->mNumVertices = (unsigned int)positions.size();
|
nuclear@0
|
153 out->mVertices = new aiVector3D[out->mNumVertices];
|
nuclear@0
|
154 ::memcpy(out->mVertices,&positions[0],out->mNumVertices*sizeof(aiVector3D));
|
nuclear@0
|
155 return out;
|
nuclear@0
|
156 }
|
nuclear@0
|
157
|
nuclear@0
|
158 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
159 // Construct a mesh with a specific shape (callback)
|
nuclear@0
|
160 aiMesh* StandardShapes::MakeMesh ( unsigned int (*GenerateFunc)(
|
nuclear@0
|
161 std::vector<aiVector3D>&))
|
nuclear@0
|
162 {
|
nuclear@0
|
163 std::vector<aiVector3D> temp;
|
nuclear@0
|
164 unsigned num = (*GenerateFunc)(temp);
|
nuclear@0
|
165 return MakeMesh(temp,num);
|
nuclear@0
|
166 }
|
nuclear@0
|
167
|
nuclear@0
|
168 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
169 // Construct a mesh with a specific shape (callback)
|
nuclear@0
|
170 aiMesh* StandardShapes::MakeMesh ( unsigned int (*GenerateFunc)(
|
nuclear@0
|
171 std::vector<aiVector3D>&, bool))
|
nuclear@0
|
172 {
|
nuclear@0
|
173 std::vector<aiVector3D> temp;
|
nuclear@0
|
174 unsigned num = (*GenerateFunc)(temp,true);
|
nuclear@0
|
175 return MakeMesh(temp,num);
|
nuclear@0
|
176 }
|
nuclear@0
|
177
|
nuclear@0
|
178 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
179 // Construct a mesh with a specific shape (callback)
|
nuclear@0
|
180 aiMesh* StandardShapes::MakeMesh (unsigned int num, void (*GenerateFunc)(
|
nuclear@0
|
181 unsigned int,std::vector<aiVector3D>&))
|
nuclear@0
|
182 {
|
nuclear@0
|
183 std::vector<aiVector3D> temp;
|
nuclear@0
|
184 (*GenerateFunc)(num,temp);
|
nuclear@0
|
185 return MakeMesh(temp,3);
|
nuclear@0
|
186 }
|
nuclear@0
|
187
|
nuclear@0
|
188 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
189 // Build an incosahedron with points.magnitude == 1
|
nuclear@0
|
190 unsigned int StandardShapes::MakeIcosahedron(std::vector<aiVector3D>& positions)
|
nuclear@0
|
191 {
|
nuclear@0
|
192 positions.reserve(positions.size()+60);
|
nuclear@0
|
193
|
nuclear@0
|
194 const float t = (1.f + 2.236067977f)/2.f;
|
nuclear@0
|
195 const float s = sqrt(1.f + t*t);
|
nuclear@0
|
196
|
nuclear@0
|
197 const aiVector3D v0 = aiVector3D(t,1.f, 0.f)/s;
|
nuclear@0
|
198 const aiVector3D v1 = aiVector3D(-t,1.f, 0.f)/s;
|
nuclear@0
|
199 const aiVector3D v2 = aiVector3D(t,-1.f, 0.f)/s;
|
nuclear@0
|
200 const aiVector3D v3 = aiVector3D(-t,-1.f, 0.f)/s;
|
nuclear@0
|
201 const aiVector3D v4 = aiVector3D(1.f, 0.f, t)/s;
|
nuclear@0
|
202 const aiVector3D v5 = aiVector3D(1.f, 0.f,-t)/s;
|
nuclear@0
|
203 const aiVector3D v6 = aiVector3D(-1.f, 0.f,t)/s;
|
nuclear@0
|
204 const aiVector3D v7 = aiVector3D(-1.f, 0.f,-t)/s;
|
nuclear@0
|
205 const aiVector3D v8 = aiVector3D(0.f, t, 1.f)/s;
|
nuclear@0
|
206 const aiVector3D v9 = aiVector3D(0.f,-t, 1.f)/s;
|
nuclear@0
|
207 const aiVector3D v10 = aiVector3D(0.f, t,-1.f)/s;
|
nuclear@0
|
208 const aiVector3D v11 = aiVector3D(0.f,-t,-1.f)/s;
|
nuclear@0
|
209
|
nuclear@0
|
210 ADD_TRIANGLE(v0,v8,v4);
|
nuclear@0
|
211 ADD_TRIANGLE(v0,v5,v10);
|
nuclear@0
|
212 ADD_TRIANGLE(v2,v4,v9);
|
nuclear@0
|
213 ADD_TRIANGLE(v2,v11,v5);
|
nuclear@0
|
214
|
nuclear@0
|
215 ADD_TRIANGLE(v1,v6,v8);
|
nuclear@0
|
216 ADD_TRIANGLE(v1,v10,v7);
|
nuclear@0
|
217 ADD_TRIANGLE(v3,v9,v6);
|
nuclear@0
|
218 ADD_TRIANGLE(v3,v7,v11);
|
nuclear@0
|
219
|
nuclear@0
|
220 ADD_TRIANGLE(v0,v10,v8);
|
nuclear@0
|
221 ADD_TRIANGLE(v1,v8,v10);
|
nuclear@0
|
222 ADD_TRIANGLE(v2,v9,v11);
|
nuclear@0
|
223 ADD_TRIANGLE(v3,v11,v9);
|
nuclear@0
|
224
|
nuclear@0
|
225 ADD_TRIANGLE(v4,v2,v0);
|
nuclear@0
|
226 ADD_TRIANGLE(v5,v0,v2);
|
nuclear@0
|
227 ADD_TRIANGLE(v6,v1,v3);
|
nuclear@0
|
228 ADD_TRIANGLE(v7,v3,v1);
|
nuclear@0
|
229
|
nuclear@0
|
230 ADD_TRIANGLE(v8,v6,v4);
|
nuclear@0
|
231 ADD_TRIANGLE(v9,v4,v6);
|
nuclear@0
|
232 ADD_TRIANGLE(v10,v5,v7);
|
nuclear@0
|
233 ADD_TRIANGLE(v11,v7,v5);
|
nuclear@0
|
234 return 3;
|
nuclear@0
|
235 }
|
nuclear@0
|
236
|
nuclear@0
|
237 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
238 // Build a dodecahedron with points.magnitude == 1
|
nuclear@0
|
239 unsigned int StandardShapes::MakeDodecahedron(std::vector<aiVector3D>& positions,
|
nuclear@0
|
240 bool polygons /*= false*/)
|
nuclear@0
|
241 {
|
nuclear@0
|
242 positions.reserve(positions.size()+108);
|
nuclear@0
|
243
|
nuclear@0
|
244 const float a = 1.f / 1.7320508f;
|
nuclear@0
|
245 const float b = sqrt((3.f-2.23606797f)/6.f);
|
nuclear@0
|
246 const float c = sqrt((3.f+2.23606797f)/6.f);
|
nuclear@0
|
247
|
nuclear@0
|
248 const aiVector3D v0 = aiVector3D(a,a,a);
|
nuclear@0
|
249 const aiVector3D v1 = aiVector3D(a,a,-a);
|
nuclear@0
|
250 const aiVector3D v2 = aiVector3D(a,-a,a);
|
nuclear@0
|
251 const aiVector3D v3 = aiVector3D(a,-a,-a);
|
nuclear@0
|
252 const aiVector3D v4 = aiVector3D(-a,a,a);
|
nuclear@0
|
253 const aiVector3D v5 = aiVector3D(-a,a,-a);
|
nuclear@0
|
254 const aiVector3D v6 = aiVector3D(-a,-a,a);
|
nuclear@0
|
255 const aiVector3D v7 = aiVector3D(-a,-a,-a);
|
nuclear@0
|
256 const aiVector3D v8 = aiVector3D(b,c,0.f);
|
nuclear@0
|
257 const aiVector3D v9 = aiVector3D(-b,c,0.f);
|
nuclear@0
|
258 const aiVector3D v10 = aiVector3D(b,-c,0.f);
|
nuclear@0
|
259 const aiVector3D v11 = aiVector3D(-b,-c,0.f);
|
nuclear@0
|
260 const aiVector3D v12 = aiVector3D(c, 0.f, b);
|
nuclear@0
|
261 const aiVector3D v13 = aiVector3D(c, 0.f, -b);
|
nuclear@0
|
262 const aiVector3D v14 = aiVector3D(-c, 0.f, b);
|
nuclear@0
|
263 const aiVector3D v15 = aiVector3D(-c, 0.f, -b);
|
nuclear@0
|
264 const aiVector3D v16 = aiVector3D(0.f, b, c);
|
nuclear@0
|
265 const aiVector3D v17 = aiVector3D(0.f, -b, c);
|
nuclear@0
|
266 const aiVector3D v18 = aiVector3D(0.f, b, -c);
|
nuclear@0
|
267 const aiVector3D v19 = aiVector3D(0.f, -b, -c);
|
nuclear@0
|
268
|
nuclear@0
|
269 ADD_PENTAGON(v0, v8, v9, v4, v16);
|
nuclear@0
|
270 ADD_PENTAGON(v0, v12, v13, v1, v8);
|
nuclear@0
|
271 ADD_PENTAGON(v0, v16, v17, v2, v12);
|
nuclear@0
|
272 ADD_PENTAGON(v8, v1, v18, v5, v9);
|
nuclear@0
|
273 ADD_PENTAGON(v12, v2, v10, v3, v13);
|
nuclear@0
|
274 ADD_PENTAGON(v16, v4, v14, v6, v17);
|
nuclear@0
|
275 ADD_PENTAGON(v9, v5, v15, v14, v4);
|
nuclear@0
|
276
|
nuclear@0
|
277 ADD_PENTAGON(v6, v11, v10, v2, v17);
|
nuclear@0
|
278 ADD_PENTAGON(v3, v19, v18, v1, v13);
|
nuclear@0
|
279 ADD_PENTAGON(v7, v15, v5, v18, v19);
|
nuclear@0
|
280 ADD_PENTAGON(v7, v11, v6, v14, v15);
|
nuclear@0
|
281 ADD_PENTAGON(v7, v19, v3, v10, v11);
|
nuclear@0
|
282 return (polygons ? 5 : 3);
|
nuclear@0
|
283 }
|
nuclear@0
|
284
|
nuclear@0
|
285 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
286 // Build an octahedron with points.magnitude == 1
|
nuclear@0
|
287 unsigned int StandardShapes::MakeOctahedron(std::vector<aiVector3D>& positions)
|
nuclear@0
|
288 {
|
nuclear@0
|
289 positions.reserve(positions.size()+24);
|
nuclear@0
|
290
|
nuclear@0
|
291 const aiVector3D v0 = aiVector3D(1.0f, 0.f, 0.f) ;
|
nuclear@0
|
292 const aiVector3D v1 = aiVector3D(-1.0f, 0.f, 0.f);
|
nuclear@0
|
293 const aiVector3D v2 = aiVector3D(0.f, 1.0f, 0.f);
|
nuclear@0
|
294 const aiVector3D v3 = aiVector3D(0.f, -1.0f, 0.f);
|
nuclear@0
|
295 const aiVector3D v4 = aiVector3D(0.f, 0.f, 1.0f);
|
nuclear@0
|
296 const aiVector3D v5 = aiVector3D(0.f, 0.f, -1.0f);
|
nuclear@0
|
297
|
nuclear@0
|
298 ADD_TRIANGLE(v4,v0,v2);
|
nuclear@0
|
299 ADD_TRIANGLE(v4,v2,v1);
|
nuclear@0
|
300 ADD_TRIANGLE(v4,v1,v3);
|
nuclear@0
|
301 ADD_TRIANGLE(v4,v3,v0);
|
nuclear@0
|
302
|
nuclear@0
|
303 ADD_TRIANGLE(v5,v2,v0);
|
nuclear@0
|
304 ADD_TRIANGLE(v5,v1,v2);
|
nuclear@0
|
305 ADD_TRIANGLE(v5,v3,v1);
|
nuclear@0
|
306 ADD_TRIANGLE(v5,v0,v3);
|
nuclear@0
|
307 return 3;
|
nuclear@0
|
308 }
|
nuclear@0
|
309
|
nuclear@0
|
310 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
311 // Build a tetrahedron with points.magnitude == 1
|
nuclear@0
|
312 unsigned int StandardShapes::MakeTetrahedron(std::vector<aiVector3D>& positions)
|
nuclear@0
|
313 {
|
nuclear@0
|
314 positions.reserve(positions.size()+9);
|
nuclear@0
|
315
|
nuclear@0
|
316 const float a = 1.41421f/3.f;
|
nuclear@0
|
317 const float b = 2.4494f/3.f;
|
nuclear@0
|
318
|
nuclear@0
|
319 const aiVector3D v0 = aiVector3D(0.f,0.f,1.f);
|
nuclear@0
|
320 const aiVector3D v1 = aiVector3D(2*a,0,-1.f/3.f);
|
nuclear@0
|
321 const aiVector3D v2 = aiVector3D(-a,b,-1.f/3.f);
|
nuclear@0
|
322 const aiVector3D v3 = aiVector3D(-a,-b,-1.f/3.f);
|
nuclear@0
|
323
|
nuclear@0
|
324 ADD_TRIANGLE(v0,v1,v2);
|
nuclear@0
|
325 ADD_TRIANGLE(v0,v2,v3);
|
nuclear@0
|
326 ADD_TRIANGLE(v0,v3,v1);
|
nuclear@0
|
327 ADD_TRIANGLE(v1,v3,v2);
|
nuclear@0
|
328 return 3;
|
nuclear@0
|
329 }
|
nuclear@0
|
330
|
nuclear@0
|
331 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
332 // Build a hexahedron with points.magnitude == 1
|
nuclear@0
|
333 unsigned int StandardShapes::MakeHexahedron(std::vector<aiVector3D>& positions,
|
nuclear@0
|
334 bool polygons /*= false*/)
|
nuclear@0
|
335 {
|
nuclear@0
|
336 positions.reserve(positions.size()+36);
|
nuclear@0
|
337 const float length = 1.f/1.73205080f;
|
nuclear@0
|
338
|
nuclear@0
|
339 const aiVector3D v0 = aiVector3D(-1.f,-1.f,-1.f)*length;
|
nuclear@0
|
340 const aiVector3D v1 = aiVector3D(1.f,-1.f,-1.f)*length;
|
nuclear@0
|
341 const aiVector3D v2 = aiVector3D(1.f,1.f,-1.f)*length;
|
nuclear@0
|
342 const aiVector3D v3 = aiVector3D(-1.f,1.f,-1.f)*length;
|
nuclear@0
|
343 const aiVector3D v4 = aiVector3D(-1.f,-1.f,1.f)*length;
|
nuclear@0
|
344 const aiVector3D v5 = aiVector3D(1.f,-1.f,1.f)*length;
|
nuclear@0
|
345 const aiVector3D v6 = aiVector3D(1.f,1.f,1.f)*length;
|
nuclear@0
|
346 const aiVector3D v7 = aiVector3D(-1.f,1.f,1.f)*length;
|
nuclear@0
|
347
|
nuclear@0
|
348 ADD_QUAD(v0,v3,v2,v1);
|
nuclear@0
|
349 ADD_QUAD(v0,v1,v5,v4);
|
nuclear@0
|
350 ADD_QUAD(v0,v4,v7,v3);
|
nuclear@0
|
351 ADD_QUAD(v6,v5,v1,v2);
|
nuclear@0
|
352 ADD_QUAD(v6,v2,v3,v7);
|
nuclear@0
|
353 ADD_QUAD(v6,v7,v4,v5);
|
nuclear@0
|
354 return (polygons ? 4 : 3);
|
nuclear@0
|
355 }
|
nuclear@0
|
356
|
nuclear@0
|
357 // Cleanup ...
|
nuclear@0
|
358 #undef ADD_TRIANGLE
|
nuclear@0
|
359 #undef ADD_QUAD
|
nuclear@0
|
360 #undef ADD_PENTAGON
|
nuclear@0
|
361
|
nuclear@0
|
362 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
363 // Create a subdivision sphere
|
nuclear@0
|
364 void StandardShapes::MakeSphere(unsigned int tess,
|
nuclear@0
|
365 std::vector<aiVector3D>& positions)
|
nuclear@0
|
366 {
|
nuclear@0
|
367 // Reserve enough storage. Every subdivision
|
nuclear@0
|
368 // splits each triangle in 4, the icosahedron consists of 60 verts
|
nuclear@0
|
369 positions.reserve(positions.size()+60 * integer_pow(4, tess));
|
nuclear@0
|
370
|
nuclear@0
|
371 // Construct an icosahedron to start with
|
nuclear@0
|
372 MakeIcosahedron(positions);
|
nuclear@0
|
373
|
nuclear@0
|
374 // ... and subdivide it until the requested output
|
nuclear@0
|
375 // tesselation is reached
|
nuclear@0
|
376 for (unsigned int i = 0; i<tess;++i)
|
nuclear@0
|
377 Subdivide(positions);
|
nuclear@0
|
378 }
|
nuclear@0
|
379
|
nuclear@0
|
380 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
381 // Build a cone
|
nuclear@0
|
382 void StandardShapes::MakeCone(float height,float radius1,
|
nuclear@0
|
383 float radius2,unsigned int tess,
|
nuclear@0
|
384 std::vector<aiVector3D>& positions,bool bOpen /*= false */)
|
nuclear@0
|
385 {
|
nuclear@0
|
386 // Sorry, a cone with less than 3 segments makes ABSOLUTELY NO SENSE
|
nuclear@0
|
387 if (tess < 3 || !height)
|
nuclear@0
|
388 return;
|
nuclear@0
|
389
|
nuclear@0
|
390 size_t old = positions.size();
|
nuclear@0
|
391
|
nuclear@0
|
392 // No negative radii
|
nuclear@0
|
393 radius1 = ::fabs(radius1);
|
nuclear@0
|
394 radius2 = ::fabs(radius2);
|
nuclear@0
|
395
|
nuclear@0
|
396 float halfHeight = height / 2;
|
nuclear@0
|
397
|
nuclear@0
|
398 // radius1 is always the smaller one
|
nuclear@0
|
399 if (radius2 > radius1)
|
nuclear@0
|
400 {
|
nuclear@0
|
401 std::swap(radius2,radius1);
|
nuclear@0
|
402 halfHeight = -halfHeight;
|
nuclear@0
|
403 }
|
nuclear@0
|
404 else old = SIZE_MAX;
|
nuclear@0
|
405
|
nuclear@0
|
406 // Use a large epsilon to check whether the cone is pointy
|
nuclear@0
|
407 if (radius1 < (radius2-radius1)*10e-3f)radius1 = 0.f;
|
nuclear@0
|
408
|
nuclear@0
|
409 // We will need 3*2 verts per segment + 3*2 verts per segment
|
nuclear@0
|
410 // if the cone is closed
|
nuclear@0
|
411 const unsigned int mem = tess*6 + (!bOpen ? tess*3 * (radius1 ? 2 : 1) : 0);
|
nuclear@0
|
412 positions.reserve(positions.size () + mem);
|
nuclear@0
|
413
|
nuclear@0
|
414 // Now construct all segments
|
nuclear@0
|
415 const float angle_delta = (float)AI_MATH_TWO_PI / tess;
|
nuclear@0
|
416 const float angle_max = (float)AI_MATH_TWO_PI;
|
nuclear@0
|
417
|
nuclear@0
|
418 float s = 1.f; // cos(angle == 0);
|
nuclear@0
|
419 float t = 0.f; // sin(angle == 0);
|
nuclear@0
|
420
|
nuclear@0
|
421 for (float angle = 0.f; angle < angle_max; )
|
nuclear@0
|
422 {
|
nuclear@0
|
423 const aiVector3D v1 = aiVector3D (s * radius1, -halfHeight, t * radius1 );
|
nuclear@0
|
424 const aiVector3D v2 = aiVector3D (s * radius2, halfHeight, t * radius2 );
|
nuclear@0
|
425
|
nuclear@0
|
426 const float next = angle + angle_delta;
|
nuclear@0
|
427 float s2 = ::cos(next);
|
nuclear@0
|
428 float t2 = ::sin(next);
|
nuclear@0
|
429
|
nuclear@0
|
430 const aiVector3D v3 = aiVector3D (s2 * radius2, halfHeight, t2 * radius2 );
|
nuclear@0
|
431 const aiVector3D v4 = aiVector3D (s2 * radius1, -halfHeight, t2 * radius1 );
|
nuclear@0
|
432
|
nuclear@0
|
433 positions.push_back(v1);
|
nuclear@0
|
434 positions.push_back(v2);
|
nuclear@0
|
435 positions.push_back(v3);
|
nuclear@0
|
436 positions.push_back(v4);
|
nuclear@0
|
437 positions.push_back(v1);
|
nuclear@0
|
438 positions.push_back(v3);
|
nuclear@0
|
439
|
nuclear@0
|
440 if (!bOpen)
|
nuclear@0
|
441 {
|
nuclear@0
|
442 // generate the end 'cap'
|
nuclear@0
|
443 positions.push_back(aiVector3D(s * radius2, halfHeight, t * radius2 ));
|
nuclear@0
|
444 positions.push_back(aiVector3D(s2 * radius2, halfHeight, t2 * radius2 ));
|
nuclear@0
|
445 positions.push_back(aiVector3D(0.f, halfHeight, 0.f));
|
nuclear@0
|
446
|
nuclear@0
|
447
|
nuclear@0
|
448 if (radius1)
|
nuclear@0
|
449 {
|
nuclear@0
|
450 // generate the other end 'cap'
|
nuclear@0
|
451 positions.push_back(aiVector3D(s * radius1, -halfHeight, t * radius1 ));
|
nuclear@0
|
452 positions.push_back(aiVector3D(s2 * radius1, -halfHeight, t2 * radius1 ));
|
nuclear@0
|
453 positions.push_back(aiVector3D(0.f, -halfHeight, 0.f));
|
nuclear@0
|
454
|
nuclear@0
|
455 }
|
nuclear@0
|
456 }
|
nuclear@0
|
457 s = s2;
|
nuclear@0
|
458 t = t2;
|
nuclear@0
|
459 angle = next;
|
nuclear@0
|
460 }
|
nuclear@0
|
461
|
nuclear@0
|
462 // Need to flip face order?
|
nuclear@0
|
463 if ( SIZE_MAX != old ) {
|
nuclear@0
|
464 for (size_t s = old; s < positions.size();s += 3) {
|
nuclear@0
|
465 std::swap(positions[s],positions[s+1]);
|
nuclear@0
|
466 }
|
nuclear@0
|
467 }
|
nuclear@0
|
468 }
|
nuclear@0
|
469
|
nuclear@0
|
470 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
471 // Build a circle
|
nuclear@0
|
472 void StandardShapes::MakeCircle(float radius, unsigned int tess,
|
nuclear@0
|
473 std::vector<aiVector3D>& positions)
|
nuclear@0
|
474 {
|
nuclear@0
|
475 // Sorry, a circle with less than 3 segments makes ABSOLUTELY NO SENSE
|
nuclear@0
|
476 if (tess < 3 || !radius)
|
nuclear@0
|
477 return;
|
nuclear@0
|
478
|
nuclear@0
|
479 radius = ::fabs(radius);
|
nuclear@0
|
480
|
nuclear@0
|
481 // We will need 3 vertices per segment
|
nuclear@0
|
482 positions.reserve(positions.size()+tess*3);
|
nuclear@0
|
483
|
nuclear@0
|
484 const float angle_delta = (float)AI_MATH_TWO_PI / tess;
|
nuclear@0
|
485 const float angle_max = (float)AI_MATH_TWO_PI;
|
nuclear@0
|
486
|
nuclear@0
|
487 float s = 1.f; // cos(angle == 0);
|
nuclear@0
|
488 float t = 0.f; // sin(angle == 0);
|
nuclear@0
|
489
|
nuclear@0
|
490 for (float angle = 0.f; angle < angle_max; )
|
nuclear@0
|
491 {
|
nuclear@0
|
492 positions.push_back(aiVector3D(s * radius,0.f,t * radius));
|
nuclear@0
|
493 angle += angle_delta;
|
nuclear@0
|
494 s = ::cos(angle);
|
nuclear@0
|
495 t = ::sin(angle);
|
nuclear@0
|
496 positions.push_back(aiVector3D(s * radius,0.f,t * radius));
|
nuclear@0
|
497
|
nuclear@0
|
498 positions.push_back(aiVector3D(0.f,0.f,0.f));
|
nuclear@0
|
499 }
|
nuclear@0
|
500 }
|
nuclear@0
|
501
|
nuclear@0
|
502 } // ! Assimp
|