1 | /* |
2 | --------------------------------------------------------------------------- |
3 | Open Asset Import Library (assimp) |
4 | --------------------------------------------------------------------------- |
5 | |
6 | Copyright (c) 2006-2017, assimp team |
7 | |
8 | |
9 | All rights reserved. |
10 | |
11 | Redistribution and use of this software in source and binary forms, |
12 | with or without modification, are permitted provided that the following |
13 | conditions are met: |
14 | |
15 | * Redistributions of source code must retain the above |
16 | copyright notice, this list of conditions and the |
17 | following disclaimer. |
18 | |
19 | * Redistributions in binary form must reproduce the above |
20 | copyright notice, this list of conditions and the |
21 | following disclaimer in the documentation and/or other |
22 | materials provided with the distribution. |
23 | |
24 | * Neither the name of the assimp team, nor the names of its |
25 | contributors may be used to endorse or promote products |
26 | derived from this software without specific prior |
27 | written permission of the assimp team. |
28 | |
29 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
30 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
31 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
32 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
33 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
34 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
35 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
36 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
37 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
38 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
39 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
40 | --------------------------------------------------------------------------- |
41 | */ |
42 | |
43 | /** @file types.h |
44 | * Basic data types and primitives, such as vectors or colors. |
45 | */ |
46 | #pragma once |
47 | #ifndef AI_TYPES_H_INC |
48 | #define AI_TYPES_H_INC |
49 | |
50 | // Some runtime headers |
51 | #include <sys/types.h> |
52 | #include <stddef.h> |
53 | #include <string.h> |
54 | #include <limits.h> |
55 | |
56 | // Our compile configuration |
57 | #include "defs.h" |
58 | |
59 | // Some types moved to separate header due to size of operators |
60 | #include "vector3.h" |
61 | #include "vector2.h" |
62 | #include "color4.h" |
63 | #include "matrix3x3.h" |
64 | #include "matrix4x4.h" |
65 | #include "quaternion.h" |
66 | |
67 | #ifdef __cplusplus |
68 | #include <cstring> |
69 | #include <new> // for std::nothrow_t |
70 | #include <string> // for aiString::Set(const std::string&) |
71 | |
72 | namespace Assimp { |
73 | //! @cond never |
74 | namespace Intern { |
75 | // -------------------------------------------------------------------- |
76 | /** @brief Internal helper class to utilize our internal new/delete |
77 | * routines for allocating object of this and derived classes. |
78 | * |
79 | * By doing this you can safely share class objects between Assimp |
80 | * and the application - it works even over DLL boundaries. A good |
81 | * example is the #IOSystem where the application allocates its custom |
82 | * #IOSystem, then calls #Importer::SetIOSystem(). When the Importer |
83 | * destructs, Assimp calls operator delete on the stored #IOSystem. |
84 | * If it lies on a different heap than Assimp is working with, |
85 | * the application is determined to crash. |
86 | */ |
87 | // -------------------------------------------------------------------- |
88 | #ifndef SWIG |
89 | struct ASSIMP_API AllocateFromAssimpHeap { |
90 | // http://www.gotw.ca/publications/mill15.htm |
91 | |
92 | // new/delete overload |
93 | void *operator new ( size_t num_bytes) /* throw( std::bad_alloc ) */; |
94 | void *operator new ( size_t num_bytes, const std::nothrow_t& ) throw(); |
95 | void operator delete ( void* data); |
96 | |
97 | // array new/delete overload |
98 | void *operator new[] ( size_t num_bytes) /* throw( std::bad_alloc ) */; |
99 | void *operator new[] ( size_t num_bytes, const std::nothrow_t& ) throw(); |
100 | void operator delete[] ( void* data); |
101 | |
102 | }; // struct AllocateFromAssimpHeap |
103 | #endif |
104 | } // namespace Intern |
105 | //! @endcond |
106 | } // namespace Assimp |
107 | |
108 | extern "C" { |
109 | #endif |
110 | |
111 | /** Maximum dimension for strings, ASSIMP strings are zero terminated. */ |
112 | #ifdef __cplusplus |
113 | static |
114 | const size_t MAXLEN = 1024; |
115 | #else |
116 | # define MAXLEN 1024 |
117 | #endif |
118 | |
119 | // ---------------------------------------------------------------------------------- |
120 | /** Represents a plane in a three-dimensional, euclidean space |
121 | */ |
122 | struct aiPlane |
123 | { |
124 | #ifdef __cplusplus |
125 | aiPlane () : a(0.f), b(0.f), c(0.f), d(0.f) {} |
126 | aiPlane (ai_real _a, ai_real _b, ai_real _c, ai_real _d) |
127 | : a(_a), b(_b), c(_c), d(_d) {} |
128 | |
129 | aiPlane (const aiPlane& o) : a(o.a), b(o.b), c(o.c), d(o.d) {} |
130 | |
131 | #endif // !__cplusplus |
132 | |
133 | //! Plane equation |
134 | ai_real a,b,c,d; |
135 | }; // !struct aiPlane |
136 | |
137 | // ---------------------------------------------------------------------------------- |
138 | /** Represents a ray |
139 | */ |
140 | struct aiRay |
141 | { |
142 | #ifdef __cplusplus |
143 | aiRay () {} |
144 | aiRay (const aiVector3D& _pos, const aiVector3D& _dir) |
145 | : pos(_pos), dir(_dir) {} |
146 | |
147 | aiRay (const aiRay& o) : pos (o.pos), dir (o.dir) {} |
148 | |
149 | #endif // !__cplusplus |
150 | |
151 | //! Position and direction of the ray |
152 | C_STRUCT aiVector3D pos, dir; |
153 | }; // !struct aiRay |
154 | |
155 | // ---------------------------------------------------------------------------------- |
156 | /** Represents a color in Red-Green-Blue space. |
157 | */ |
158 | struct aiColor3D |
159 | { |
160 | #ifdef __cplusplus |
161 | aiColor3D () : r(0.0f), g(0.0f), b(0.0f) {} |
162 | aiColor3D (ai_real _r, ai_real _g, ai_real _b) : r(_r), g(_g), b(_b) {} |
163 | explicit aiColor3D (ai_real _r) : r(_r), g(_r), b(_r) {} |
164 | aiColor3D (const aiColor3D& o) : r(o.r), g(o.g), b(o.b) {} |
165 | |
166 | /** Component-wise comparison */ |
167 | // TODO: add epsilon? |
168 | bool operator == (const aiColor3D& other) const |
169 | {return r == other.r && g == other.g && b == other.b;} |
170 | |
171 | /** Component-wise inverse comparison */ |
172 | // TODO: add epsilon? |
173 | bool operator != (const aiColor3D& other) const |
174 | {return r != other.r || g != other.g || b != other.b;} |
175 | |
176 | /** Component-wise comparison */ |
177 | // TODO: add epsilon? |
178 | bool operator < (const aiColor3D& other) const { |
179 | return r < other.r || ( r == other.r && (g < other.g || (g == other.g && b < other.b ) ) ); |
180 | } |
181 | |
182 | /** Component-wise addition */ |
183 | aiColor3D operator+(const aiColor3D& c) const { |
184 | return aiColor3D(r+c.r,g+c.g,b+c.b); |
185 | } |
186 | |
187 | /** Component-wise subtraction */ |
188 | aiColor3D operator-(const aiColor3D& c) const { |
189 | return aiColor3D(r-c.r,g-c.g,b-c.b); |
190 | } |
191 | |
192 | /** Component-wise multiplication */ |
193 | aiColor3D operator*(const aiColor3D& c) const { |
194 | return aiColor3D(r*c.r,g*c.g,b*c.b); |
195 | } |
196 | |
197 | /** Multiply with a scalar */ |
198 | aiColor3D operator*(ai_real f) const { |
199 | return aiColor3D(r*f,g*f,b*f); |
200 | } |
201 | |
202 | /** Access a specific color component */ |
203 | ai_real operator[](unsigned int i) const { |
204 | return *(&r + i); |
205 | } |
206 | |
207 | /** Access a specific color component */ |
208 | ai_real& operator[](unsigned int i) { |
209 | if ( 0 == i ) { |
210 | return r; |
211 | } else if ( 1 == i ) { |
212 | return g; |
213 | } else if ( 2 == i ) { |
214 | return b; |
215 | } |
216 | return r; |
217 | } |
218 | |
219 | /** Check whether a color is black */ |
220 | bool IsBlack() const { |
221 | static const ai_real epsilon = ai_real(10e-3); |
222 | return std::fabs( r ) < epsilon && std::fabs( g ) < epsilon && std::fabs( b ) < epsilon; |
223 | } |
224 | |
225 | #endif // !__cplusplus |
226 | |
227 | //! Red, green and blue color values |
228 | ai_real r, g, b; |
229 | }; // !struct aiColor3D |
230 | |
231 | // ---------------------------------------------------------------------------------- |
232 | /** Represents an UTF-8 string, zero byte terminated. |
233 | * |
234 | * The character set of an aiString is explicitly defined to be UTF-8. This Unicode |
235 | * transformation was chosen in the belief that most strings in 3d files are limited |
236 | * to ASCII, thus the character set needed to be strictly ASCII compatible. |
237 | * |
238 | * Most text file loaders provide proper Unicode input file handling, special unicode |
239 | * characters are correctly transcoded to UTF8 and are kept throughout the libraries' |
240 | * import pipeline. |
241 | * |
242 | * For most applications, it will be absolutely sufficient to interpret the |
243 | * aiString as ASCII data and work with it as one would work with a plain char*. |
244 | * Windows users in need of proper support for i.e asian characters can use the |
245 | * MultiByteToWideChar(), WideCharToMultiByte() WinAPI functionality to convert the |
246 | * UTF-8 strings to their working character set (i.e. MBCS, WideChar). |
247 | * |
248 | * We use this representation instead of std::string to be C-compatible. The |
249 | * (binary) length of such a string is limited to MAXLEN characters (including the |
250 | * the terminating zero). |
251 | */ |
252 | struct aiString |
253 | { |
254 | #ifdef __cplusplus |
255 | /** Default constructor, the string is set to have zero length */ |
256 | aiString() : |
257 | length(0) |
258 | { |
259 | data[0] = '\0'; |
260 | |
261 | #ifdef ASSIMP_BUILD_DEBUG |
262 | // Debug build: overwrite the string on its full length with ESC (27) |
263 | memset(data+1,27,MAXLEN-1); |
264 | #endif |
265 | } |
266 | |
267 | /** Copy constructor */ |
268 | aiString(const aiString& rOther) : |
269 | length(rOther.length) |
270 | { |
271 | // Crop the string to the maximum length |
272 | length = length>=MAXLEN?MAXLEN-1:length; |
273 | memcpy( data, rOther.data, length); |
274 | data[length] = '\0'; |
275 | } |
276 | |
277 | /** Constructor from std::string */ |
278 | explicit aiString(const std::string& pString) : |
279 | length(pString.length()) |
280 | { |
281 | length = length>=MAXLEN?MAXLEN-1:length; |
282 | memcpy( data, pString.c_str(), length); |
283 | data[length] = '\0'; |
284 | } |
285 | |
286 | /** Copy a std::string to the aiString */ |
287 | void Set( const std::string& pString) { |
288 | if( pString.length() > MAXLEN - 1) { |
289 | return; |
290 | } |
291 | length = pString.length(); |
292 | memcpy( data, pString.c_str(), length); |
293 | data[length] = 0; |
294 | } |
295 | |
296 | /** Copy a const char* to the aiString */ |
297 | void Set( const char* sz) { |
298 | const size_t len = ::strlen(sz); |
299 | if( len > MAXLEN - 1) { |
300 | return; |
301 | } |
302 | length = len; |
303 | memcpy( data, sz, len); |
304 | data[len] = 0; |
305 | } |
306 | |
307 | /** Assign a const char* to the string */ |
308 | aiString& operator = (const char* sz) { |
309 | Set(sz); |
310 | return *this; |
311 | } |
312 | |
313 | /** Assign a cstd::string to the string */ |
314 | aiString& operator = ( const std::string& pString) { |
315 | Set(pString); |
316 | return *this; |
317 | } |
318 | |
319 | /** Comparison operator */ |
320 | bool operator==(const aiString& other) const { |
321 | return (length == other.length && 0 == memcmp(data,other.data,length)); |
322 | } |
323 | |
324 | /** Inverse comparison operator */ |
325 | bool operator!=(const aiString& other) const { |
326 | return (length != other.length || 0 != memcmp(data,other.data,length)); |
327 | } |
328 | |
329 | /** Append a string to the string */ |
330 | void Append (const char* app) { |
331 | const size_t len = ::strlen(app); |
332 | if (!len) { |
333 | return; |
334 | } |
335 | if (length + len >= MAXLEN) { |
336 | return; |
337 | } |
338 | |
339 | memcpy(&data[length],app,len+1); |
340 | length += len; |
341 | } |
342 | |
343 | /** Clear the string - reset its length to zero */ |
344 | void Clear () { |
345 | length = 0; |
346 | data[0] = '\0'; |
347 | |
348 | #ifdef ASSIMP_BUILD_DEBUG |
349 | // Debug build: overwrite the string on its full length with ESC (27) |
350 | memset(data+1,27,MAXLEN-1); |
351 | #endif |
352 | } |
353 | |
354 | /** Returns a pointer to the underlying zero-terminated array of characters */ |
355 | const char* C_Str() const { |
356 | return data; |
357 | } |
358 | |
359 | #endif // !__cplusplus |
360 | |
361 | /** Binary length of the string excluding the terminal 0. This is NOT the |
362 | * logical length of strings containing UTF-8 multibyte sequences! It's |
363 | * the number of bytes from the beginning of the string to its end.*/ |
364 | size_t length; |
365 | |
366 | /** String buffer. Size limit is MAXLEN */ |
367 | char data[MAXLEN]; |
368 | } ; // !struct aiString |
369 | |
370 | |
371 | // ---------------------------------------------------------------------------------- |
372 | /** Standard return type for some library functions. |
373 | * Rarely used, and if, mostly in the C API. |
374 | */ |
375 | typedef enum aiReturn |
376 | { |
377 | /** Indicates that a function was successful */ |
378 | aiReturn_SUCCESS = 0x0, |
379 | |
380 | /** Indicates that a function failed */ |
381 | aiReturn_FAILURE = -0x1, |
382 | |
383 | /** Indicates that not enough memory was available |
384 | * to perform the requested operation |
385 | */ |
386 | aiReturn_OUTOFMEMORY = -0x3, |
387 | |
388 | /** @cond never |
389 | * Force 32-bit size enum |
390 | */ |
391 | _AI_ENFORCE_ENUM_SIZE = 0x7fffffff |
392 | |
393 | /// @endcond |
394 | } aiReturn; // !enum aiReturn |
395 | |
396 | // just for backwards compatibility, don't use these constants anymore |
397 | #define AI_SUCCESS aiReturn_SUCCESS |
398 | #define AI_FAILURE aiReturn_FAILURE |
399 | #define AI_OUTOFMEMORY aiReturn_OUTOFMEMORY |
400 | |
401 | // ---------------------------------------------------------------------------------- |
402 | /** Seek origins (for the virtual file system API). |
403 | * Much cooler than using SEEK_SET, SEEK_CUR or SEEK_END. |
404 | */ |
405 | enum aiOrigin |
406 | { |
407 | /** Beginning of the file */ |
408 | aiOrigin_SET = 0x0, |
409 | |
410 | /** Current position of the file pointer */ |
411 | aiOrigin_CUR = 0x1, |
412 | |
413 | /** End of the file, offsets must be negative */ |
414 | aiOrigin_END = 0x2, |
415 | |
416 | /** @cond never |
417 | * Force 32-bit size enum |
418 | */ |
419 | _AI_ORIGIN_ENFORCE_ENUM_SIZE = 0x7fffffff |
420 | |
421 | /// @endcond |
422 | }; // !enum aiOrigin |
423 | |
424 | // ---------------------------------------------------------------------------------- |
425 | /** @brief Enumerates predefined log streaming destinations. |
426 | * Logging to these streams can be enabled with a single call to |
427 | * #LogStream::createDefaultStream. |
428 | */ |
429 | enum aiDefaultLogStream |
430 | { |
431 | /** Stream the log to a file */ |
432 | aiDefaultLogStream_FILE = 0x1, |
433 | |
434 | /** Stream the log to std::cout */ |
435 | aiDefaultLogStream_STDOUT = 0x2, |
436 | |
437 | /** Stream the log to std::cerr */ |
438 | aiDefaultLogStream_STDERR = 0x4, |
439 | |
440 | /** MSVC only: Stream the log the the debugger |
441 | * (this relies on OutputDebugString from the Win32 SDK) |
442 | */ |
443 | aiDefaultLogStream_DEBUGGER = 0x8, |
444 | |
445 | /** @cond never |
446 | * Force 32-bit size enum |
447 | */ |
448 | _AI_DLS_ENFORCE_ENUM_SIZE = 0x7fffffff |
449 | /// @endcond |
450 | }; // !enum aiDefaultLogStream |
451 | |
452 | // just for backwards compatibility, don't use these constants anymore |
453 | #define DLS_FILE aiDefaultLogStream_FILE |
454 | #define DLS_STDOUT aiDefaultLogStream_STDOUT |
455 | #define DLS_STDERR aiDefaultLogStream_STDERR |
456 | #define DLS_DEBUGGER aiDefaultLogStream_DEBUGGER |
457 | |
458 | // ---------------------------------------------------------------------------------- |
459 | /** Stores the memory requirements for different components (e.g. meshes, materials, |
460 | * animations) of an import. All sizes are in bytes. |
461 | * @see Importer::GetMemoryRequirements() |
462 | */ |
463 | struct aiMemoryInfo |
464 | { |
465 | #ifdef __cplusplus |
466 | |
467 | /** Default constructor */ |
468 | aiMemoryInfo() |
469 | : textures (0) |
470 | , materials (0) |
471 | , meshes (0) |
472 | , nodes (0) |
473 | , animations (0) |
474 | , cameras (0) |
475 | , lights (0) |
476 | , total (0) |
477 | {} |
478 | |
479 | #endif |
480 | |
481 | /** Storage allocated for texture data */ |
482 | unsigned int textures; |
483 | |
484 | /** Storage allocated for material data */ |
485 | unsigned int materials; |
486 | |
487 | /** Storage allocated for mesh data */ |
488 | unsigned int meshes; |
489 | |
490 | /** Storage allocated for node data */ |
491 | unsigned int nodes; |
492 | |
493 | /** Storage allocated for animation data */ |
494 | unsigned int animations; |
495 | |
496 | /** Storage allocated for camera data */ |
497 | unsigned int cameras; |
498 | |
499 | /** Storage allocated for light data */ |
500 | unsigned int lights; |
501 | |
502 | /** Total storage allocated for the full import. */ |
503 | unsigned int total; |
504 | }; // !struct aiMemoryInfo |
505 | |
506 | #ifdef __cplusplus |
507 | } |
508 | #endif //! __cplusplus |
509 | |
510 | // Include implementation files |
511 | #include "vector2.inl" |
512 | #include "vector3.inl" |
513 | #include "color4.inl" |
514 | #include "quaternion.inl" |
515 | #include "matrix3x3.inl" |
516 | #include "matrix4x4.inl" |
517 | |
518 | #endif // AI_TYPES_H_INC |
519 | |