-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGLTFParser.h
309 lines (266 loc) · 8.49 KB
/
GLTFParser.h
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
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
/*****************************************************************
* *
* Purpose: *
* Simple and efficient parser for GLTF format *
* allows you to import 3d mesh, material and scene *
* Author: *
* Anilcan Gulkaya 2023 [email protected] *
* Restrictions: *
* No extension and .glb support. *
* License: *
* No License whatsoever do Whatever you want. *
* *
*****************************************************************/
#ifndef AX_GLTF_PARSER
#define AX_GLTF_PARSER
enum AAttribType_
{
AAttribType_POSITION = 1 << 0,
AAttribType_TEXCOORD_0 = 1 << 1,
AAttribType_NORMAL = 1 << 2,
AAttribType_TANGENT = 1 << 3,
AAttribType_TEXCOORD_1 = 1 << 4,
AAttribType_JOINTS = 1 << 5,
AAttribType_WEIGHTS = 1 << 6,
AAttribType_Count = 7 ,
AAttribType_MAKE32BIT = 1 << 31
};
typedef int AAttribType;
enum AErrorType_
{
AError_NONE,
AError_UNKNOWN,
AError_UNKNOWN_ATTRIB,
AError_UNKNOWN_MATERIAL_VAR,
AError_UNKNOWN_PBR_VAR,
AError_UNKNOWN_NODE_VAR,
AError_UNKNOWN_TEXTURE_VAR,
AError_UNKNOWN_ACCESSOR_VAR,
AError_UNKNOWN_BUFFER_VIEW_VAR,
AError_UNKNOWN_MESH_VAR,
AError_UNKNOWN_CAMERA_VAR,
AError_UNKNOWN_MESH_PRIMITIVE_VAR,
AError_BUFFER_PARSE_FAIL,
AError_BIN_NOT_EXIST,
AError_FILE_NOT_FOUND,
AError_UNKNOWN_DESCRIPTOR,
AError_HASH_COLISSION,
AError_NON_UTF8,
AError_EXT_NOT_SUPPORTED, // scenes other than GLTF, OBJ or Fbx
AError_MAX
};
typedef int AErrorType;
enum AMaterialAlphaMode_
{
AMaterialAlphaMode_Opaque, AMaterialAlphaMode_Blend, AMaterialAlphaMode_Mask
};
typedef int AMaterialAlphaMode;
typedef struct AMaterial_
{
// original value multiplied by 400 to get real value: float scale = ((float)scale) / 400.0f;
typedef short float16;
struct Texture
{
float16 scale;
float16 strength;
short index; // index to texture path. -1 if is not exist
short texCoord;
} textures[3]; // normalTexture, occlusionTexture, emissiveTexture
// pbrMetallicRoughness in gltf. but baseColorFactor is below
Texture baseColorTexture;
Texture specularTexture;
Texture metallicRoughnessTexture;
float16 metallicFactor;
float16 roughnessFactor;
char* name;
float16 emissiveFactor[3];
float16 specularFactor;
unsigned diffuseColor, specularColor, baseColorFactor;
float alphaCutoff;
bool doubleSided;
AMaterialAlphaMode alphaMode;
#ifdef __cplusplus
const Texture& GetNormalTexture() const { return textures[0]; }
const Texture& GetOcclusionTexture() const { return textures[1]; }
const Texture& GetEmissiveTexture() const { return textures[2]; }
Texture& GetNormalTexture() { return textures[0]; }
Texture& GetOcclusionTexture() { return textures[1]; }
Texture& GetEmissiveTexture() { return textures[2]; }
static inline float16 MakeFloat16(float x) { return (float16)(x * 400.0f); }
#endif
} AMaterial;
typedef struct AImage_
{
char* path;
} AImage;
typedef struct ANode_
{
// Warning! order is important, we copy memory in assetmanager.cpp from fbx transform
float translation[3];
float rotation[4];
float scale[3];
int type; // 0 mesh or 1 camera
int index; // index of mesh or camera, -1 if node doesn't have mesh or camera
int skin;
int numChildren;
char* name;
int* children;
} ANode;
typedef struct APrimitive_
{
// pointers to binary file to lookup position, texture, normal..
void* indices;
void* vertices;
unsigned attributes; // AAttribType Position, Normal, TexCoord, Tangent, masks
int indexType; // GraphicType_UnsignedInt, GraphicType_UnsignedShort..
int numIndices;
int numVertices;
int indexOffset;
short jointType; // GraphicType_UnsignedInt, GraphicType_UnsignedShort..
short jointCount; // per vertex bone count (joint), 1-4
short jointStride; // lets say index data is rgba16u [r, g, b, a, .......] stride might be bigger than joint
short weightType; // GraphicType_UnsignedInt, GraphicType_UnsignedShort..
short weightStride; // lets say index data is rgba16u [r, g, b, a, .......] stride might be bigger than joint
// internal use only. after parsing this is useless
short indiceIndex; // indice index to accessor
short material; // material index
short mode; // 4 is triangle
// when we are parsing we use this as an indicator to accessor.
// after parsing, this will become vertex pointers AAttribType_Position, AAttribType_TexCoord...
// positions = (Vector3f*)vertexAttribs[0];
// texCoords = (Vector2f*)vertexAttribs[1]; // note that tangent is vec4
// ...
void* vertexAttribs[AAttribType_Count];
// AABB min and max
float min[4];
float max[4];
} APrimitive;
typedef struct AMesh_
{
char* name;
APrimitive* primitives;
int numPrimitives;
} AMesh;
typedef struct ATexture_
{
int sampler;
int source;
char* name;
} ATexture;
typedef struct ACamera_
{
union {
struct { float aspectRatio, yFov; };
struct { float xmag, ymag; };
};
float zFar, zNear;
int type; // 0 orthographic, 1 perspective
char* name;
} ACamera;
typedef struct ASampler_
{
char magFilter; // 0 = GL_NEAREST = 0x2600 = 9728, or 1 = 0x2601 = GL_LINEAR = 9729
char minFilter; // 0 or 1 like above
char wrapS; // 0 GL_REPEAT, 1 GL_CLAMP_TO_EDGE, 2 GL_CLAMP_TO_BORDER, 3 GL_MIRRORED_REPEAT
char wrapT; // 10497 33071 33069 33648
} ASampler;
static_assert(sizeof(ASampler) == sizeof(int), "size must be 4");
typedef struct AScene_
{
char* name;
int numNodes;
int* nodes;
} AScene;
typedef struct GLTFBuffer_
{
void* uri;
int byteLength;
} GLTFBuffer;
typedef struct ASkin_
{
int skeleton; // < index of the root node
int numJoints;
float *inverseBindMatrices; // matrix4x4 * numJoints
int *joints; // < indices of bone nodes
char *name;
} ASkin;
enum AAnimTargetPath_ {
AAnimTargetPath_Translation,
AAnimTargetPath_Rotation,
AAnimTargetPath_Scale
};
typedef int AAnimTargetPath;
enum ASamplerInterpolation_ {
ASamplerInterpolation_Linear,
ASamplerInterpolation_Step,
ASamplerInterpolation_CubicSpline
};
typedef int ASamplerInterpolation;
// to understand gltf animations please refer here
// https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.pdf
typedef struct AAnimChannel_
{
int sampler;
int targetNode;
AAnimTargetPath targetPath;
} AAnimChannel;
typedef struct AAnimSampler_
{
float* input;
float* output; // quaternion or vector array
int count;
int numComponent; // 3, 4 vec3 or vec4
ASamplerInterpolation interpolation;
} AAnimSampler;
typedef struct AAnimation_
{
int numSamplers;
int numChannels;
float duration; // total duration
AAnimChannel* channels;
AAnimSampler* samplers;
char* name;
} AAnimation;
// https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html
typedef struct SceneBundle_
{
short numMeshes;
short numNodes;
short numMaterials;
short numTextures;
short numImages;
short numSamplers;
short numCameras;
short numScenes;
short defaultSceneIndex;
short numBuffers;
short numAnimations;
short numSkins;
AErrorType error;
void* stringAllocator;
void* intAllocator;
void* allVertices;
void* allIndices;
int totalVertices;
int totalIndices;
float scale;
GLTFBuffer* buffers;
AMesh *meshes;
ANode *nodes;
AMaterial *materials;
ATexture *textures;
AImage *images;
ASampler *samplers;
ACamera *cameras;
AScene *scenes;
AAnimation *animations;
ASkin *skins;
} SceneBundle;
// if there is an error error will be minus GLTFErrorType
// out scene should not be null
extern int ParseGLTF(const char* path, SceneBundle* scene, float scale);
// Free
extern void FreeParsedGLTF(SceneBundle* gltf);
void FreeGLTFBuffers(SceneBundle* gltf);
extern const char* ParsedSceneGetError(AErrorType error);
#endif // AX_GLTF_PARSER