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 /** @file Defines a helper class to represent an interleaved vertex
|
nuclear@0
|
41 along with arithmetic operations to support vertex operations
|
nuclear@0
|
42 such as subdivision, smoothing etc.
|
nuclear@0
|
43
|
nuclear@0
|
44 While the code is kept as general as possible, arithmetic operations
|
nuclear@0
|
45 that are not currently well-defined (and would cause compile errors
|
nuclear@0
|
46 due to missing operators in the math library), are commented.
|
nuclear@0
|
47 */
|
nuclear@0
|
48 #ifndef AI_VERTEX_H_INC
|
nuclear@0
|
49 #define AI_VERTEX_H_INC
|
nuclear@0
|
50
|
nuclear@0
|
51 #include <functional>
|
nuclear@0
|
52
|
nuclear@0
|
53 namespace Assimp {
|
nuclear@0
|
54
|
nuclear@0
|
55 ///////////////////////////////////////////////////////////////////////////
|
nuclear@0
|
56 // std::plus-family operates on operands with identical types - we need to
|
nuclear@0
|
57 // support all the (vectype op float) combinations in vector maths.
|
nuclear@0
|
58 // Providing T(float) would open the way to endless implicit conversions.
|
nuclear@0
|
59 ///////////////////////////////////////////////////////////////////////////
|
nuclear@0
|
60 namespace Intern {
|
nuclear@0
|
61 template <typename T0, typename T1, typename TRES = T0> struct plus {
|
nuclear@0
|
62 TRES operator() (const T0& t0, const T1& t1) const {
|
nuclear@0
|
63 return t0+t1;
|
nuclear@0
|
64 }
|
nuclear@0
|
65 };
|
nuclear@0
|
66 template <typename T0, typename T1, typename TRES = T0> struct minus {
|
nuclear@0
|
67 TRES operator() (const T0& t0, const T1& t1) const {
|
nuclear@0
|
68 return t0-t1;
|
nuclear@0
|
69 }
|
nuclear@0
|
70 };
|
nuclear@0
|
71 template <typename T0, typename T1, typename TRES = T0> struct multiplies {
|
nuclear@0
|
72 TRES operator() (const T0& t0, const T1& t1) const {
|
nuclear@0
|
73 return t0*t1;
|
nuclear@0
|
74 }
|
nuclear@0
|
75 };
|
nuclear@0
|
76 template <typename T0, typename T1, typename TRES = T0> struct divides {
|
nuclear@0
|
77 TRES operator() (const T0& t0, const T1& t1) const {
|
nuclear@0
|
78 return t0/t1;
|
nuclear@0
|
79 }
|
nuclear@0
|
80 };
|
nuclear@0
|
81 }
|
nuclear@0
|
82
|
nuclear@0
|
83 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
84 /** Intermediate description a vertex with all possible components. Defines a full set of
|
nuclear@0
|
85 * operators, so you may use such a 'Vertex' in basic arithmetics. All operators are applied
|
nuclear@0
|
86 * to *all* vertex components equally. This is useful for stuff like interpolation
|
nuclear@0
|
87 * or subdivision, but won't work if special handling is required for some vertex components. */
|
nuclear@0
|
88 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
89 class Vertex
|
nuclear@0
|
90 {
|
nuclear@0
|
91 friend Vertex operator + (const Vertex&,const Vertex&);
|
nuclear@0
|
92 friend Vertex operator - (const Vertex&,const Vertex&);
|
nuclear@0
|
93
|
nuclear@0
|
94 // friend Vertex operator + (const Vertex&,float);
|
nuclear@0
|
95 // friend Vertex operator - (const Vertex&,float);
|
nuclear@0
|
96 friend Vertex operator * (const Vertex&,float);
|
nuclear@0
|
97 friend Vertex operator / (const Vertex&,float);
|
nuclear@0
|
98
|
nuclear@0
|
99 // friend Vertex operator + (float, const Vertex&);
|
nuclear@0
|
100 // friend Vertex operator - (float, const Vertex&);
|
nuclear@0
|
101 friend Vertex operator * (float, const Vertex&);
|
nuclear@0
|
102 // friend Vertex operator / (float, const Vertex&);
|
nuclear@0
|
103
|
nuclear@0
|
104 public:
|
nuclear@0
|
105
|
nuclear@0
|
106 Vertex() {}
|
nuclear@0
|
107
|
nuclear@0
|
108 // ----------------------------------------------------------------------------
|
nuclear@0
|
109 /** Extract a particular vertex from a mesh and interleave all components */
|
nuclear@0
|
110 explicit Vertex(const aiMesh* msh, unsigned int idx) {
|
nuclear@0
|
111 ai_assert(idx < msh->mNumVertices);
|
nuclear@0
|
112 position = msh->mVertices[idx];
|
nuclear@0
|
113
|
nuclear@0
|
114 if (msh->HasNormals()) {
|
nuclear@0
|
115 normal = msh->mNormals[idx];
|
nuclear@0
|
116 }
|
nuclear@0
|
117
|
nuclear@0
|
118 if (msh->HasTangentsAndBitangents()) {
|
nuclear@0
|
119 tangent = msh->mTangents[idx];
|
nuclear@0
|
120 bitangent = msh->mBitangents[idx];
|
nuclear@0
|
121 }
|
nuclear@0
|
122
|
nuclear@0
|
123 for (unsigned int i = 0; msh->HasTextureCoords(i); ++i) {
|
nuclear@0
|
124 texcoords[i] = msh->mTextureCoords[i][idx];
|
nuclear@0
|
125 }
|
nuclear@0
|
126
|
nuclear@0
|
127 for (unsigned int i = 0; msh->HasVertexColors(i); ++i) {
|
nuclear@0
|
128 colors[i] = msh->mColors[i][idx];
|
nuclear@0
|
129 }
|
nuclear@0
|
130 }
|
nuclear@0
|
131
|
nuclear@0
|
132 public:
|
nuclear@0
|
133
|
nuclear@0
|
134 Vertex& operator += (const Vertex& v) {
|
nuclear@0
|
135 *this = *this+v;
|
nuclear@0
|
136 return *this;
|
nuclear@0
|
137 }
|
nuclear@0
|
138
|
nuclear@0
|
139 Vertex& operator -= (const Vertex& v) {
|
nuclear@0
|
140 *this = *this-v;
|
nuclear@0
|
141 return *this;
|
nuclear@0
|
142 }
|
nuclear@0
|
143
|
nuclear@0
|
144
|
nuclear@0
|
145 /*
|
nuclear@0
|
146 Vertex& operator += (float v) {
|
nuclear@0
|
147 *this = *this+v;
|
nuclear@0
|
148 return *this;
|
nuclear@0
|
149 }
|
nuclear@0
|
150
|
nuclear@0
|
151 Vertex& operator -= (float v) {
|
nuclear@0
|
152 *this = *this-v;
|
nuclear@0
|
153 return *this;
|
nuclear@0
|
154 }
|
nuclear@0
|
155 */
|
nuclear@0
|
156 Vertex& operator *= (float v) {
|
nuclear@0
|
157 *this = *this*v;
|
nuclear@0
|
158 return *this;
|
nuclear@0
|
159 }
|
nuclear@0
|
160
|
nuclear@0
|
161 Vertex& operator /= (float v) {
|
nuclear@0
|
162 *this = *this/v;
|
nuclear@0
|
163 return *this;
|
nuclear@0
|
164 }
|
nuclear@0
|
165
|
nuclear@0
|
166 public:
|
nuclear@0
|
167
|
nuclear@0
|
168 // ----------------------------------------------------------------------------
|
nuclear@0
|
169 /** Convert back to non-interleaved storage */
|
nuclear@0
|
170 void SortBack(aiMesh* out, unsigned int idx) const {
|
nuclear@0
|
171
|
nuclear@0
|
172 ai_assert(idx<out->mNumVertices);
|
nuclear@0
|
173 out->mVertices[idx] = position;
|
nuclear@0
|
174
|
nuclear@0
|
175 if (out->HasNormals()) {
|
nuclear@0
|
176 out->mNormals[idx] = normal;
|
nuclear@0
|
177 }
|
nuclear@0
|
178
|
nuclear@0
|
179 if (out->HasTangentsAndBitangents()) {
|
nuclear@0
|
180 out->mTangents[idx] = tangent;
|
nuclear@0
|
181 out->mBitangents[idx] = bitangent;
|
nuclear@0
|
182 }
|
nuclear@0
|
183
|
nuclear@0
|
184 for(unsigned int i = 0; out->HasTextureCoords(i); ++i) {
|
nuclear@0
|
185 out->mTextureCoords[i][idx] = texcoords[i];
|
nuclear@0
|
186 }
|
nuclear@0
|
187
|
nuclear@0
|
188 for(unsigned int i = 0; out->HasVertexColors(i); ++i) {
|
nuclear@0
|
189 out->mColors[i][idx] = colors[i];
|
nuclear@0
|
190 }
|
nuclear@0
|
191 }
|
nuclear@0
|
192
|
nuclear@0
|
193 private:
|
nuclear@0
|
194
|
nuclear@0
|
195 // ----------------------------------------------------------------------------
|
nuclear@0
|
196 /** Construct from two operands and a binary operation to combine them */
|
nuclear@0
|
197 template <template <typename t> class op> static Vertex BinaryOp(const Vertex& v0, const Vertex& v1) {
|
nuclear@0
|
198 // this is a heavy task for the compiler to optimize ... *pray*
|
nuclear@0
|
199
|
nuclear@0
|
200 Vertex res;
|
nuclear@0
|
201 res.position = op<aiVector3D>()(v0.position,v1.position);
|
nuclear@0
|
202 res.normal = op<aiVector3D>()(v0.normal,v1.normal);
|
nuclear@0
|
203 res.tangent = op<aiVector3D>()(v0.tangent,v1.tangent);
|
nuclear@0
|
204 res.bitangent = op<aiVector3D>()(v0.bitangent,v1.bitangent);
|
nuclear@0
|
205
|
nuclear@0
|
206 for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
|
nuclear@0
|
207 res.texcoords[i] = op<aiVector3D>()(v0.texcoords[i],v1.texcoords[i]);
|
nuclear@0
|
208 }
|
nuclear@0
|
209 for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
|
nuclear@0
|
210 res.colors[i] = op<aiColor4D>()(v0.colors[i],v1.colors[i]);
|
nuclear@0
|
211 }
|
nuclear@0
|
212 return res;
|
nuclear@0
|
213 }
|
nuclear@0
|
214
|
nuclear@0
|
215 // ----------------------------------------------------------------------------
|
nuclear@0
|
216 /** This time binary arithmetics of v0 with a floating-point number */
|
nuclear@0
|
217 template <template <typename, typename, typename> class op> static Vertex BinaryOp(const Vertex& v0, float f) {
|
nuclear@0
|
218 // this is a heavy task for the compiler to optimize ... *pray*
|
nuclear@0
|
219
|
nuclear@0
|
220 Vertex res;
|
nuclear@0
|
221 res.position = op<aiVector3D,float,aiVector3D>()(v0.position,f);
|
nuclear@0
|
222 res.normal = op<aiVector3D,float,aiVector3D>()(v0.normal,f);
|
nuclear@0
|
223 res.tangent = op<aiVector3D,float,aiVector3D>()(v0.tangent,f);
|
nuclear@0
|
224 res.bitangent = op<aiVector3D,float,aiVector3D>()(v0.bitangent,f);
|
nuclear@0
|
225
|
nuclear@0
|
226 for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
|
nuclear@0
|
227 res.texcoords[i] = op<aiVector3D,float,aiVector3D>()(v0.texcoords[i],f);
|
nuclear@0
|
228 }
|
nuclear@0
|
229 for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
|
nuclear@0
|
230 res.colors[i] = op<aiColor4D,float,aiColor4D>()(v0.colors[i],f);
|
nuclear@0
|
231 }
|
nuclear@0
|
232 return res;
|
nuclear@0
|
233 }
|
nuclear@0
|
234
|
nuclear@0
|
235 // ----------------------------------------------------------------------------
|
nuclear@0
|
236 /** This time binary arithmetics of v0 with a floating-point number */
|
nuclear@0
|
237 template <template <typename, typename, typename> class op> static Vertex BinaryOp(float f, const Vertex& v0) {
|
nuclear@0
|
238 // this is a heavy task for the compiler to optimize ... *pray*
|
nuclear@0
|
239
|
nuclear@0
|
240 Vertex res;
|
nuclear@0
|
241 res.position = op<float,aiVector3D,aiVector3D>()(f,v0.position);
|
nuclear@0
|
242 res.normal = op<float,aiVector3D,aiVector3D>()(f,v0.normal);
|
nuclear@0
|
243 res.tangent = op<float,aiVector3D,aiVector3D>()(f,v0.tangent);
|
nuclear@0
|
244 res.bitangent = op<float,aiVector3D,aiVector3D>()(f,v0.bitangent);
|
nuclear@0
|
245
|
nuclear@0
|
246 for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
|
nuclear@0
|
247 res.texcoords[i] = op<float,aiVector3D,aiVector3D>()(f,v0.texcoords[i]);
|
nuclear@0
|
248 }
|
nuclear@0
|
249 for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
|
nuclear@0
|
250 res.colors[i] = op<float,aiColor4D,aiColor4D>()(f,v0.colors[i]);
|
nuclear@0
|
251 }
|
nuclear@0
|
252 return res;
|
nuclear@0
|
253 }
|
nuclear@0
|
254
|
nuclear@0
|
255 public:
|
nuclear@0
|
256
|
nuclear@0
|
257 aiVector3D position;
|
nuclear@0
|
258 aiVector3D normal;
|
nuclear@0
|
259 aiVector3D tangent, bitangent;
|
nuclear@0
|
260
|
nuclear@0
|
261 aiVector3D texcoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
|
nuclear@0
|
262 aiColor4D colors[AI_MAX_NUMBER_OF_COLOR_SETS];
|
nuclear@0
|
263 };
|
nuclear@0
|
264
|
nuclear@0
|
265
|
nuclear@0
|
266
|
nuclear@0
|
267 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
268 AI_FORCE_INLINE Vertex operator + (const Vertex& v0,const Vertex& v1) {
|
nuclear@0
|
269 return Vertex::BinaryOp<std::plus>(v0,v1);
|
nuclear@0
|
270 }
|
nuclear@0
|
271
|
nuclear@0
|
272 AI_FORCE_INLINE Vertex operator - (const Vertex& v0,const Vertex& v1) {
|
nuclear@0
|
273 return Vertex::BinaryOp<std::minus>(v0,v1);
|
nuclear@0
|
274 }
|
nuclear@0
|
275
|
nuclear@0
|
276
|
nuclear@0
|
277 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
278 /*
|
nuclear@0
|
279 AI_FORCE_INLINE Vertex operator + (const Vertex& v0,float f) {
|
nuclear@0
|
280 return Vertex::BinaryOp<Intern::plus>(v0,f);
|
nuclear@0
|
281 }
|
nuclear@0
|
282
|
nuclear@0
|
283 AI_FORCE_INLINE Vertex operator - (const Vertex& v0,float f) {
|
nuclear@0
|
284 return Vertex::BinaryOp<Intern::minus>(v0,f);
|
nuclear@0
|
285 }
|
nuclear@0
|
286
|
nuclear@0
|
287 */
|
nuclear@0
|
288
|
nuclear@0
|
289 AI_FORCE_INLINE Vertex operator * (const Vertex& v0,float f) {
|
nuclear@0
|
290 return Vertex::BinaryOp<Intern::multiplies>(v0,f);
|
nuclear@0
|
291 }
|
nuclear@0
|
292
|
nuclear@0
|
293 AI_FORCE_INLINE Vertex operator / (const Vertex& v0,float f) {
|
nuclear@0
|
294 return Vertex::BinaryOp<Intern::multiplies>(v0,1.f/f);
|
nuclear@0
|
295 }
|
nuclear@0
|
296
|
nuclear@0
|
297 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
298 /*
|
nuclear@0
|
299 AI_FORCE_INLINE Vertex operator + (float f,const Vertex& v0) {
|
nuclear@0
|
300 return Vertex::BinaryOp<Intern::plus>(f,v0);
|
nuclear@0
|
301 }
|
nuclear@0
|
302
|
nuclear@0
|
303 AI_FORCE_INLINE Vertex operator - (float f,const Vertex& v0) {
|
nuclear@0
|
304 return Vertex::BinaryOp<Intern::minus>(f,v0);
|
nuclear@0
|
305 }
|
nuclear@0
|
306 */
|
nuclear@0
|
307
|
nuclear@0
|
308 AI_FORCE_INLINE Vertex operator * (float f,const Vertex& v0) {
|
nuclear@0
|
309 return Vertex::BinaryOp<Intern::multiplies>(f,v0);
|
nuclear@0
|
310 }
|
nuclear@0
|
311
|
nuclear@0
|
312 /*
|
nuclear@0
|
313 AI_FORCE_INLINE Vertex operator / (float f,const Vertex& v0) {
|
nuclear@0
|
314 return Vertex::BinaryOp<Intern::divides>(f,v0);
|
nuclear@0
|
315 }
|
nuclear@0
|
316 */
|
nuclear@0
|
317
|
nuclear@0
|
318 }
|
nuclear@0
|
319 #endif
|