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