-
-
Notifications
You must be signed in to change notification settings - Fork 648
Expand file tree
/
Copy pathtiny_obj_c.h
More file actions
288 lines (251 loc) · 10.6 KB
/
Copy pathtiny_obj_c.h
File metadata and controls
288 lines (251 loc) · 10.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
/*
* tiny_obj_c.h -- Pure C11 Wavefront .obj / .mtl loader.
*
* A from-scratch C11 reimplementation of tinyobjloader. NOT header-only:
* compile tiny_obj_c.c (and tobj_tess.c) and link against this header.
*
* Design goals: secure, portable, freestanding-capable, dependency-free,
* fast, robust. Multithreading / SIMD / mmap / file I/O are opt-in behind
* macros; the default build is scalar, single-threaded and libc-backed.
*
* Two precision families coexist in one build:
* - "_f" suffix : float positions/normals/texcoords/materials
* - "_d" suffix : double ditto
* Pick whichever you need at the call site, or define TOBJ_DEFAULT_DOUBLE to
* make the unsuffixed convenience aliases map to the double family.
*
* SPDX-License-Identifier: MIT
*/
#ifndef TINY_OBJ_C_H_
#define TINY_OBJ_C_H_
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
/* ------------------------------------------------------------------------- */
/* Configuration macros (see plan / README): */
/* */
/* TOBJ_NO_LIBC / TOBJ_FREESTANDING : forbid libc; caller must supply an */
/* allocator; no default file I/O. */
/* TOBJ_ENABLE_FILE_IO : tobj_load_obj_from_file_* helpers. */
/* TOBJ_ENABLE_MMAP : use mmap / MapViewOfFile in file I/O. */
/* TOBJ_ENABLE_MULTITHREADING : parallel chunked parse. */
/* TOBJ_ENABLE_SIMD : SIMD newline scan. */
/* TOBJ_DISABLE_FAST_FLOAT : scalar fallback float parser. */
/* TOBJ_DEFAULT_DOUBLE : unsuffixed aliases -> double family. */
/* ------------------------------------------------------------------------- */
#if defined(TOBJ_FREESTANDING) && !defined(TOBJ_NO_LIBC)
#define TOBJ_NO_LIBC 1
#endif
#if defined(TOBJ_NO_LIBC) && (defined(TOBJ_ENABLE_FILE_IO) || defined(TOBJ_ENABLE_MMAP))
#error "TOBJ_NO_LIBC is incompatible with TOBJ_ENABLE_FILE_IO / TOBJ_ENABLE_MMAP"
#endif
#ifndef TOBJ_API
#define TOBJ_API extern
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* ======================================================================= */
/* Precision-independent types */
/* ======================================================================= */
/* Result / status codes. TOBJ_OK is returned even when non-fatal warnings
* were produced (parity with the C++ loader returning `true` plus a warn
* string). Any non-zero code is a hard failure; the output object is zeroed. */
typedef enum tobj_result {
TOBJ_OK = 0,
TOBJ_ERR_INVALID_ARG,
TOBJ_ERR_ALLOC,
TOBJ_ERR_OVERFLOW,
TOBJ_ERR_PARSE,
TOBJ_ERR_IO,
TOBJ_ERR_NOT_FOUND,
TOBJ_ERR_LIMIT_EXCEEDED,
TOBJ_ERR_UNSUPPORTED
} tobj_result;
typedef enum tobj_severity {
TOBJ_SEV_WARNING = 0,
TOBJ_SEV_ERROR = 1
} tobj_severity;
/* Injectable allocator. If a config's allocator.alloc is NULL the default
* libc allocator is used (only available when !TOBJ_NO_LIBC). `align` is a
* power of two. calloc/realloc are optional; alloc and free are required for
* custom allocators. max_alloc_size == 0 means "unbounded". */
typedef struct tobj_allocator {
void *(*alloc)(void *ud, size_t size, size_t align);
void *(*calloc)(void *ud, size_t count, size_t size, size_t align);
void *(*realloc)(void *ud, void *ptr, size_t old_size, size_t new_size,
size_t align);
void (*free)(void *ud, void *ptr, size_t size);
size_t max_alloc_size;
void *user_data;
} tobj_allocator;
#ifndef TOBJ_NO_LIBC
TOBJ_API tobj_allocator tobj_default_allocator(void);
#endif
/* Diagnostics sink. If on_message is non-NULL it is invoked per message and
* nothing is aggregated. Otherwise messages are appended to the `warn`/`err`
* buffers (allocated via the load config's allocator); free with
* tobj_diag_free. A NULL tobj_diag* passed to a loader silences diagnostics. */
typedef struct tobj_diag {
void (*on_message)(void *ud, tobj_severity sev, size_t line_no,
const char *msg, size_t msg_len);
void *user_data;
char *warn;
size_t warn_len;
char *err;
size_t err_len;
} tobj_diag;
TOBJ_API void tobj_diag_free(tobj_diag *diag, const tobj_allocator *alloc);
/* Per-corner index triple. -1 means "not present". Precision-independent. */
typedef struct tobj_index {
int vertex_index;
int normal_index;
int texcoord_index;
} tobj_index;
/* Key/value pair for material unknown_parameter maps (interned strings). */
typedef struct tobj_kv {
const char *key;
const char *value;
} tobj_kv;
typedef enum tobj_texture_type {
TOBJ_TEXTURE_TYPE_NONE = 0,
TOBJ_TEXTURE_TYPE_SPHERE,
TOBJ_TEXTURE_TYPE_CUBE_TOP,
TOBJ_TEXTURE_TYPE_CUBE_BOTTOM,
TOBJ_TEXTURE_TYPE_CUBE_FRONT,
TOBJ_TEXTURE_TYPE_CUBE_BACK,
TOBJ_TEXTURE_TYPE_CUBE_LEFT,
TOBJ_TEXTURE_TYPE_CUBE_RIGHT
} tobj_texture_type;
/* Free-form curve/surface type (cstype). */
typedef enum tobj_cstype {
TOBJ_CSTYPE_NONE = 0,
TOBJ_CSTYPE_BMATRIX,
TOBJ_CSTYPE_BEZIER,
TOBJ_CSTYPE_BSPLINE,
TOBJ_CSTYPE_CARDINAL,
TOBJ_CSTYPE_TAYLOR
} tobj_cstype;
/* Raw bytes for one .mtl source, produced by a material resolver. If
* `release` is set the loader calls it once it is done with the bytes. */
typedef struct tobj_mtl_source {
const uint8_t *data;
size_t len;
void (*release)(void *ud, const uint8_t *data, size_t len);
void *release_ud;
} tobj_mtl_source;
/* Resolve a `mtllib` name to bytes. Return TOBJ_OK and fill *out, or
* TOBJ_ERR_NOT_FOUND (treated as a warning by the loader). Called once per
* distinct name encountered. Replaces the C++ virtual MaterialReader. */
typedef tobj_result (*tobj_material_resolver)(void *ud, const char *mtllib_name,
tobj_mtl_source *out);
/* Pull-style byte input. read returns TOBJ_OK and writes 0 bytes at EOF. The
* loader owns neither callbacks nor user_data, but calls close when non-NULL. */
typedef struct tobj_io_callbacks {
tobj_result (*read)(void *ud, uint8_t *dst, size_t dst_size,
size_t *bytes_read);
void (*close)(void *ud);
void *user_data;
} tobj_io_callbacks;
/* Load configuration (precision-independent: it has no real fields). */
typedef struct tobj_load_config {
tobj_allocator allocator; /* {0} -> default libc allocator */
bool triangulate; /* default true */
bool store_vertex_colors; /* default true */
bool vertex_color_fallback; /* fill missing colors with white; default true */
bool parse_freeform; /* parse cstype/curv/surf/...; default false */
bool use_arena; /* bulk-arena output; default false */
int num_threads; /* -1 auto, 0/1 single-threaded (MT builds) */
/* Hard caps; 0 selects a built-in default. Exceeding -> LIMIT_EXCEEDED. */
size_t max_vertices;
size_t max_indices;
size_t max_faces;
size_t max_face_arity;
size_t max_materials;
size_t max_shapes;
size_t max_line_bytes;
size_t max_input_bytes;
tobj_material_resolver mtl_resolver;
void *mtl_resolver_user_data;
} tobj_load_config;
TOBJ_API tobj_load_config tobj_default_config(void);
/* ======================================================================= */
/* Per-precision types and API (generated for _f and _d) */
/* ======================================================================= */
#define TOBJ_CAT_(a, b) a##b
#define TOBJ_CAT(a, b) TOBJ_CAT_(a, b)
/* Paste the active precision suffix (TOBJ_SUF) onto an identifier. */
#define TOBJ_T(name) TOBJ_CAT(name, TOBJ_SUF)
/* float family */
#define TOBJ_REAL float
#define TOBJ_SUF _f
#include "tiny_obj_c_pub.inc"
#undef TOBJ_REAL
#undef TOBJ_SUF
/* double family */
#define TOBJ_REAL double
#define TOBJ_SUF _d
#include "tiny_obj_c_pub.inc"
#undef TOBJ_REAL
#undef TOBJ_SUF
/* Convenience aliases for the default precision.
*
* IMPORTANT: type aliases are typedefs and function aliases are *function-like*
* macros. Object-like macros sharing these base names would be expanded inside
* TOBJ_T()/TOBJ_CAT() token-pasting (which fully expands its arguments) and
* corrupt the suffixed identifiers in the implementation. Typedef names and
* unparenthesized function-like macro names are not expanded there, so both
* forms are safe. */
#ifdef TOBJ_DEFAULT_DOUBLE
typedef double tobj_real;
typedef tobj_real_buf_d tobj_real_buf;
typedef tobj_texture_option_d tobj_texture_option;
typedef tobj_material_d tobj_material;
typedef tobj_attrib_d tobj_attrib;
typedef tobj_mesh_d tobj_mesh;
typedef tobj_lines_d tobj_lines;
typedef tobj_points_d tobj_points;
typedef tobj_shape_d tobj_shape;
typedef tobj_scene_d tobj_scene;
typedef tobj_callbacks_d tobj_callbacks;
typedef tobj_material_list_d tobj_material_list;
#define tobj_load_obj_from_memory(...) tobj_load_obj_from_memory_d(__VA_ARGS__)
#define tobj_load_obj_from_file(...) tobj_load_obj_from_file_d(__VA_ARGS__)
#define tobj_load_obj_with_callbacks(...) \
tobj_load_obj_with_callbacks_d(__VA_ARGS__)
#define tobj_load_obj_from_io(...) tobj_load_obj_from_io_d(__VA_ARGS__)
#define tobj_scene_free(...) tobj_scene_free_d(__VA_ARGS__)
#define tobj_parse_mtl_from_memory(...) tobj_parse_mtl_from_memory_d(__VA_ARGS__)
#define tobj_material_list_free(...) tobj_material_list_free_d(__VA_ARGS__)
#define tobj_material_get_param(...) tobj_material_get_param_d(__VA_ARGS__)
#else
typedef float tobj_real;
typedef tobj_real_buf_f tobj_real_buf;
typedef tobj_texture_option_f tobj_texture_option;
typedef tobj_material_f tobj_material;
typedef tobj_attrib_f tobj_attrib;
typedef tobj_mesh_f tobj_mesh;
typedef tobj_lines_f tobj_lines;
typedef tobj_points_f tobj_points;
typedef tobj_shape_f tobj_shape;
typedef tobj_scene_f tobj_scene;
typedef tobj_callbacks_f tobj_callbacks;
typedef tobj_material_list_f tobj_material_list;
#define tobj_load_obj_from_memory(...) tobj_load_obj_from_memory_f(__VA_ARGS__)
#define tobj_load_obj_from_file(...) tobj_load_obj_from_file_f(__VA_ARGS__)
#define tobj_load_obj_with_callbacks(...) \
tobj_load_obj_with_callbacks_f(__VA_ARGS__)
#define tobj_load_obj_from_io(...) tobj_load_obj_from_io_f(__VA_ARGS__)
#define tobj_scene_free(...) tobj_scene_free_f(__VA_ARGS__)
#define tobj_parse_mtl_from_memory(...) tobj_parse_mtl_from_memory_f(__VA_ARGS__)
#define tobj_material_list_free(...) tobj_material_list_free_f(__VA_ARGS__)
#define tobj_material_get_param(...) tobj_material_get_param_f(__VA_ARGS__)
#endif
/* Single fuzz entry (uses the float family internally). */
TOBJ_API int tobj_fuzz_one(const uint8_t *data, size_t size);
/* Human-readable name for a result code (static storage). */
TOBJ_API const char *tobj_result_string(tobj_result r);
#ifdef __cplusplus
}
#endif
#endif /* TINY_OBJ_C_H_ */