]> git.sesse.net Git - pistorm/blob - raylib/models.c
Add Meson build files.
[pistorm] / raylib / models.c
1 /**********************************************************************************************
2 *
3 *   raylib.models - Basic functions to deal with 3d shapes and 3d models
4 *
5 *   CONFIGURATION:
6 *
7 *   #define SUPPORT_FILEFORMAT_OBJ
8 *   #define SUPPORT_FILEFORMAT_MTL
9 *   #define SUPPORT_FILEFORMAT_IQM
10 *   #define SUPPORT_FILEFORMAT_GLTF
11 *       Selected desired fileformats to be supported for model data loading.
12 *
13 *   #define SUPPORT_MESH_GENERATION
14 *       Support procedural mesh generation functions, uses external par_shapes.h library
15 *       NOTE: Some generated meshes DO NOT include generated texture coordinates
16 *
17 *
18 *   LICENSE: zlib/libpng
19 *
20 *   Copyright (c) 2013-2021 Ramon Santamaria (@raysan5)
21 *
22 *   This software is provided "as-is", without any express or implied warranty. In no event
23 *   will the authors be held liable for any damages arising from the use of this software.
24 *
25 *   Permission is granted to anyone to use this software for any purpose, including commercial
26 *   applications, and to alter it and redistribute it freely, subject to the following restrictions:
27 *
28 *     1. The origin of this software must not be misrepresented; you must not claim that you
29 *     wrote the original software. If you use this software in a product, an acknowledgment
30 *     in the product documentation would be appreciated but is not required.
31 *
32 *     2. Altered source versions must be plainly marked as such, and must not be misrepresented
33 *     as being the original software.
34 *
35 *     3. This notice may not be removed or altered from any source distribution.
36 *
37 **********************************************************************************************/
38
39 #include "raylib.h"         // Declares module functions
40
41 // Check if config flags have been externally provided on compilation line
42 #if !defined(EXTERNAL_CONFIG_FLAGS)
43     #include "config.h"         // Defines module configuration flags
44 #endif
45
46 #include "utils.h"          // Required for: LoadFileData(), LoadFileText(), SaveFileText()
47
48 #include <stdio.h>          // Required for: sprintf()
49 #include <stdlib.h>         // Required for: malloc(), free()
50 #include <string.h>         // Required for: memcmp(), strlen()
51 #include <math.h>           // Required for: sinf(), cosf(), sqrtf(), fabsf()
52
53 #if defined(_WIN32)
54     #include <direct.h>     // Required for: _chdir() [Used in LoadOBJ()]
55     #define CHDIR _chdir
56 #else
57     #include <unistd.h>     // Required for: chdir() (POSIX) [Used in LoadOBJ()]
58     #define CHDIR chdir
59 #endif
60
61 #include "rlgl.h"           // raylib OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2
62
63 #if defined(SUPPORT_FILEFORMAT_OBJ) || defined(SUPPORT_FILEFORMAT_MTL)
64     #define TINYOBJ_MALLOC RL_MALLOC
65     #define TINYOBJ_CALLOC RL_CALLOC
66     #define TINYOBJ_REALLOC RL_REALLOC
67     #define TINYOBJ_FREE RL_FREE
68
69     #define TINYOBJ_LOADER_C_IMPLEMENTATION
70     #include "external/tinyobj_loader_c.h"      // OBJ/MTL file formats loading
71 #endif
72
73 #if defined(SUPPORT_FILEFORMAT_GLTF)
74     #define CGLTF_MALLOC RL_MALLOC
75     #define CGLTF_FREE RL_FREE
76
77     #define CGLTF_IMPLEMENTATION
78     #include "external/cgltf.h"         // glTF file format loading
79     #include "external/stb_image.h"     // glTF texture images loading
80 #endif
81
82 #if defined(SUPPORT_MESH_GENERATION)
83     #define PAR_MALLOC(T, N) ((T*)RL_MALLOC(N*sizeof(T)))
84     #define PAR_CALLOC(T, N) ((T*)RL_CALLOC(N*sizeof(T), 1))
85     #define PAR_REALLOC(T, BUF, N) ((T*)RL_REALLOC(BUF, sizeof(T)*(N)))
86     #define PAR_FREE RL_FREE
87
88     #define PAR_SHAPES_IMPLEMENTATION
89     #include "external/par_shapes.h"    // Shapes 3d parametric generation
90 #endif
91
92 //----------------------------------------------------------------------------------
93 // Defines and Macros
94 //----------------------------------------------------------------------------------
95 // ...
96
97 //----------------------------------------------------------------------------------
98 // Types and Structures Definition
99 //----------------------------------------------------------------------------------
100 // ...
101
102 //----------------------------------------------------------------------------------
103 // Global Variables Definition
104 //----------------------------------------------------------------------------------
105 // ...
106
107 //----------------------------------------------------------------------------------
108 // Module specific Functions Declaration
109 //----------------------------------------------------------------------------------
110 #if defined(SUPPORT_FILEFORMAT_OBJ)
111 static Model LoadOBJ(const char *fileName);     // Load OBJ mesh data
112 #endif
113 #if defined(SUPPORT_FILEFORMAT_IQM)
114 static Model LoadIQM(const char *fileName);     // Load IQM mesh data
115 static ModelAnimation *LoadIQMModelAnimations(const char *fileName, int *animCount);    // Load IQM animation data
116 #endif
117 #if defined(SUPPORT_FILEFORMAT_GLTF)
118 static Model LoadGLTF(const char *fileName);    // Load GLTF mesh data
119 static ModelAnimation *LoadGLTFModelAnimations(const char *fileName, int *animCount);    // Load GLTF animation data
120 static void LoadGLTFModelIndices(Model* model, cgltf_accessor* indexAccessor, int primitiveIndex);
121 static void BindGLTFPrimitiveToBones(Model* model, const cgltf_data* data, int primitiveIndex);
122 static void LoadGLTFBoneAttribute(Model* model, cgltf_accessor* jointsAccessor, const cgltf_data* data, int primitiveIndex);
123 static void LoadGLTFMaterial(Model* model, const char* fileName, const cgltf_data* data);
124 static void InitGLTFBones(Model* model, const cgltf_data* data);
125 #endif
126
127 //----------------------------------------------------------------------------------
128 // Module Functions Definition
129 //----------------------------------------------------------------------------------
130
131 // Draw a line in 3D world space
132 void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color)
133 {
134     // WARNING: Be careful with internal buffer vertex alignment
135     // when using RL_LINES or RL_TRIANGLES, data is aligned to fit
136     // lines-triangles-quads in the same indexed buffers!!!
137     rlCheckRenderBatchLimit(8);
138
139     rlBegin(RL_LINES);
140         rlColor4ub(color.r, color.g, color.b, color.a);
141         rlVertex3f(startPos.x, startPos.y, startPos.z);
142         rlVertex3f(endPos.x, endPos.y, endPos.z);
143     rlEnd();
144 }
145
146 // Draw a point in 3D space, actually a small line
147 void DrawPoint3D(Vector3 position, Color color)
148 {
149     rlCheckRenderBatchLimit(8);
150
151     rlPushMatrix();
152         rlTranslatef(position.x, position.y, position.z);
153         rlBegin(RL_LINES);
154             rlColor4ub(color.r, color.g, color.b, color.a);
155             rlVertex3f(0.0f, 0.0f, 0.0f);
156             rlVertex3f(0.0f, 0.0f, 0.1f);
157         rlEnd();
158     rlPopMatrix();
159 }
160
161 // Draw a circle in 3D world space
162 void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color)
163 {
164     rlCheckRenderBatchLimit(2*36);
165
166     rlPushMatrix();
167         rlTranslatef(center.x, center.y, center.z);
168         rlRotatef(rotationAngle, rotationAxis.x, rotationAxis.y, rotationAxis.z);
169
170         rlBegin(RL_LINES);
171             for (int i = 0; i < 360; i += 10)
172             {
173                 rlColor4ub(color.r, color.g, color.b, color.a);
174
175                 rlVertex3f(sinf(DEG2RAD*i)*radius, cosf(DEG2RAD*i)*radius, 0.0f);
176                 rlVertex3f(sinf(DEG2RAD*(i + 10))*radius, cosf(DEG2RAD*(i + 10))*radius, 0.0f);
177             }
178         rlEnd();
179     rlPopMatrix();
180 }
181
182 // Draw a color-filled triangle (vertex in counter-clockwise order!)
183 void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color)
184 {
185     rlCheckRenderBatchLimit(3);
186
187     rlBegin(RL_TRIANGLES);
188         rlColor4ub(color.r, color.g, color.b, color.a);
189         rlVertex3f(v1.x, v1.y, v1.z);
190         rlVertex3f(v2.x, v2.y, v2.z);
191         rlVertex3f(v3.x, v3.y, v3.z);
192     rlEnd();
193 }
194
195 // Draw a triangle strip defined by points
196 void DrawTriangleStrip3D(Vector3 *points, int pointsCount, Color color)
197 {
198     if (pointsCount >= 3)
199     {
200         rlCheckRenderBatchLimit(3*(pointsCount - 2));
201
202         rlBegin(RL_TRIANGLES);
203             rlColor4ub(color.r, color.g, color.b, color.a);
204
205             for (int i = 2; i < pointsCount; i++)
206             {
207                 if ((i%2) == 0)
208                 {
209                     rlVertex3f(points[i].x, points[i].y, points[i].z);
210                     rlVertex3f(points[i - 2].x, points[i - 2].y, points[i - 2].z);
211                     rlVertex3f(points[i - 1].x, points[i - 1].y, points[i - 1].z);
212                 }
213                 else
214                 {
215                     rlVertex3f(points[i].x, points[i].y, points[i].z);
216                     rlVertex3f(points[i - 1].x, points[i - 1].y, points[i - 1].z);
217                     rlVertex3f(points[i - 2].x, points[i - 2].y, points[i - 2].z);
218                 }
219             }
220         rlEnd();
221     }
222 }
223
224 // Draw cube
225 // NOTE: Cube position is the center position
226 void DrawCube(Vector3 position, float width, float height, float length, Color color)
227 {
228     float x = 0.0f;
229     float y = 0.0f;
230     float z = 0.0f;
231
232     rlCheckRenderBatchLimit(36);
233
234     rlPushMatrix();
235         // NOTE: Transformation is applied in inverse order (scale -> rotate -> translate)
236         rlTranslatef(position.x, position.y, position.z);
237         //rlRotatef(45, 0, 1, 0);
238         //rlScalef(1.0f, 1.0f, 1.0f);   // NOTE: Vertices are directly scaled on definition
239
240         rlBegin(RL_TRIANGLES);
241             rlColor4ub(color.r, color.g, color.b, color.a);
242
243             // Front face
244             rlVertex3f(x - width/2, y - height/2, z + length/2);  // Bottom Left
245             rlVertex3f(x + width/2, y - height/2, z + length/2);  // Bottom Right
246             rlVertex3f(x - width/2, y + height/2, z + length/2);  // Top Left
247
248             rlVertex3f(x + width/2, y + height/2, z + length/2);  // Top Right
249             rlVertex3f(x - width/2, y + height/2, z + length/2);  // Top Left
250             rlVertex3f(x + width/2, y - height/2, z + length/2);  // Bottom Right
251
252             // Back face
253             rlVertex3f(x - width/2, y - height/2, z - length/2);  // Bottom Left
254             rlVertex3f(x - width/2, y + height/2, z - length/2);  // Top Left
255             rlVertex3f(x + width/2, y - height/2, z - length/2);  // Bottom Right
256
257             rlVertex3f(x + width/2, y + height/2, z - length/2);  // Top Right
258             rlVertex3f(x + width/2, y - height/2, z - length/2);  // Bottom Right
259             rlVertex3f(x - width/2, y + height/2, z - length/2);  // Top Left
260
261             // Top face
262             rlVertex3f(x - width/2, y + height/2, z - length/2);  // Top Left
263             rlVertex3f(x - width/2, y + height/2, z + length/2);  // Bottom Left
264             rlVertex3f(x + width/2, y + height/2, z + length/2);  // Bottom Right
265
266             rlVertex3f(x + width/2, y + height/2, z - length/2);  // Top Right
267             rlVertex3f(x - width/2, y + height/2, z - length/2);  // Top Left
268             rlVertex3f(x + width/2, y + height/2, z + length/2);  // Bottom Right
269
270             // Bottom face
271             rlVertex3f(x - width/2, y - height/2, z - length/2);  // Top Left
272             rlVertex3f(x + width/2, y - height/2, z + length/2);  // Bottom Right
273             rlVertex3f(x - width/2, y - height/2, z + length/2);  // Bottom Left
274
275             rlVertex3f(x + width/2, y - height/2, z - length/2);  // Top Right
276             rlVertex3f(x + width/2, y - height/2, z + length/2);  // Bottom Right
277             rlVertex3f(x - width/2, y - height/2, z - length/2);  // Top Left
278
279             // Right face
280             rlVertex3f(x + width/2, y - height/2, z - length/2);  // Bottom Right
281             rlVertex3f(x + width/2, y + height/2, z - length/2);  // Top Right
282             rlVertex3f(x + width/2, y + height/2, z + length/2);  // Top Left
283
284             rlVertex3f(x + width/2, y - height/2, z + length/2);  // Bottom Left
285             rlVertex3f(x + width/2, y - height/2, z - length/2);  // Bottom Right
286             rlVertex3f(x + width/2, y + height/2, z + length/2);  // Top Left
287
288             // Left face
289             rlVertex3f(x - width/2, y - height/2, z - length/2);  // Bottom Right
290             rlVertex3f(x - width/2, y + height/2, z + length/2);  // Top Left
291             rlVertex3f(x - width/2, y + height/2, z - length/2);  // Top Right
292
293             rlVertex3f(x - width/2, y - height/2, z + length/2);  // Bottom Left
294             rlVertex3f(x - width/2, y + height/2, z + length/2);  // Top Left
295             rlVertex3f(x - width/2, y - height/2, z - length/2);  // Bottom Right
296         rlEnd();
297     rlPopMatrix();
298 }
299
300 // Draw cube (Vector version)
301 void DrawCubeV(Vector3 position, Vector3 size, Color color)
302 {
303     DrawCube(position, size.x, size.y, size.z, color);
304 }
305
306 // Draw cube wires
307 void DrawCubeWires(Vector3 position, float width, float height, float length, Color color)
308 {
309     float x = 0.0f;
310     float y = 0.0f;
311     float z = 0.0f;
312
313     rlCheckRenderBatchLimit(36);
314
315     rlPushMatrix();
316         rlTranslatef(position.x, position.y, position.z);
317
318         rlBegin(RL_LINES);
319             rlColor4ub(color.r, color.g, color.b, color.a);
320
321             // Front Face -----------------------------------------------------
322             // Bottom Line
323             rlVertex3f(x-width/2, y-height/2, z+length/2);  // Bottom Left
324             rlVertex3f(x+width/2, y-height/2, z+length/2);  // Bottom Right
325
326             // Left Line
327             rlVertex3f(x+width/2, y-height/2, z+length/2);  // Bottom Right
328             rlVertex3f(x+width/2, y+height/2, z+length/2);  // Top Right
329
330             // Top Line
331             rlVertex3f(x+width/2, y+height/2, z+length/2);  // Top Right
332             rlVertex3f(x-width/2, y+height/2, z+length/2);  // Top Left
333
334             // Right Line
335             rlVertex3f(x-width/2, y+height/2, z+length/2);  // Top Left
336             rlVertex3f(x-width/2, y-height/2, z+length/2);  // Bottom Left
337
338             // Back Face ------------------------------------------------------
339             // Bottom Line
340             rlVertex3f(x-width/2, y-height/2, z-length/2);  // Bottom Left
341             rlVertex3f(x+width/2, y-height/2, z-length/2);  // Bottom Right
342
343             // Left Line
344             rlVertex3f(x+width/2, y-height/2, z-length/2);  // Bottom Right
345             rlVertex3f(x+width/2, y+height/2, z-length/2);  // Top Right
346
347             // Top Line
348             rlVertex3f(x+width/2, y+height/2, z-length/2);  // Top Right
349             rlVertex3f(x-width/2, y+height/2, z-length/2);  // Top Left
350
351             // Right Line
352             rlVertex3f(x-width/2, y+height/2, z-length/2);  // Top Left
353             rlVertex3f(x-width/2, y-height/2, z-length/2);  // Bottom Left
354
355             // Top Face -------------------------------------------------------
356             // Left Line
357             rlVertex3f(x-width/2, y+height/2, z+length/2);  // Top Left Front
358             rlVertex3f(x-width/2, y+height/2, z-length/2);  // Top Left Back
359
360             // Right Line
361             rlVertex3f(x+width/2, y+height/2, z+length/2);  // Top Right Front
362             rlVertex3f(x+width/2, y+height/2, z-length/2);  // Top Right Back
363
364             // Bottom Face  ---------------------------------------------------
365             // Left Line
366             rlVertex3f(x-width/2, y-height/2, z+length/2);  // Top Left Front
367             rlVertex3f(x-width/2, y-height/2, z-length/2);  // Top Left Back
368
369             // Right Line
370             rlVertex3f(x+width/2, y-height/2, z+length/2);  // Top Right Front
371             rlVertex3f(x+width/2, y-height/2, z-length/2);  // Top Right Back
372         rlEnd();
373     rlPopMatrix();
374 }
375
376 // Draw cube wires (vector version)
377 void DrawCubeWiresV(Vector3 position, Vector3 size, Color color)
378 {
379     DrawCubeWires(position, size.x, size.y, size.z, color);
380 }
381
382 // Draw cube
383 // NOTE: Cube position is the center position
384 void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float length, Color color)
385 {
386     float x = position.x;
387     float y = position.y;
388     float z = position.z;
389
390     rlCheckRenderBatchLimit(36);
391
392     rlSetTexture(texture.id);
393
394     //rlPushMatrix();
395         // NOTE: Transformation is applied in inverse order (scale -> rotate -> translate)
396         //rlTranslatef(2.0f, 0.0f, 0.0f);
397         //rlRotatef(45, 0, 1, 0);
398         //rlScalef(2.0f, 2.0f, 2.0f);
399
400         rlBegin(RL_QUADS);
401             rlColor4ub(color.r, color.g, color.b, color.a);
402             // Front Face
403             rlNormal3f(0.0f, 0.0f, 1.0f);                  // Normal Pointing Towards Viewer
404             rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z + length/2);  // Bottom Left Of The Texture and Quad
405             rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z + length/2);  // Bottom Right Of The Texture and Quad
406             rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z + length/2);  // Top Right Of The Texture and Quad
407             rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z + length/2);  // Top Left Of The Texture and Quad
408             // Back Face
409             rlNormal3f(0.0f, 0.0f, - 1.0f);                  // Normal Pointing Away From Viewer
410             rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z - length/2);  // Bottom Right Of The Texture and Quad
411             rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z - length/2);  // Top Right Of The Texture and Quad
412             rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z - length/2);  // Top Left Of The Texture and Quad
413             rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z - length/2);  // Bottom Left Of The Texture and Quad
414             // Top Face
415             rlNormal3f(0.0f, 1.0f, 0.0f);                  // Normal Pointing Up
416             rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z - length/2);  // Top Left Of The Texture and Quad
417             rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - width/2, y + height/2, z + length/2);  // Bottom Left Of The Texture and Quad
418             rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + width/2, y + height/2, z + length/2);  // Bottom Right Of The Texture and Quad
419             rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z - length/2);  // Top Right Of The Texture and Quad
420             // Bottom Face
421             rlNormal3f(0.0f, - 1.0f, 0.0f);                  // Normal Pointing Down
422             rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - width/2, y - height/2, z - length/2);  // Top Right Of The Texture and Quad
423             rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + width/2, y - height/2, z - length/2);  // Top Left Of The Texture and Quad
424             rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z + length/2);  // Bottom Left Of The Texture and Quad
425             rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z + length/2);  // Bottom Right Of The Texture and Quad
426             // Right face
427             rlNormal3f(1.0f, 0.0f, 0.0f);                  // Normal Pointing Right
428             rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z - length/2);  // Bottom Right Of The Texture and Quad
429             rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z - length/2);  // Top Right Of The Texture and Quad
430             rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z + length/2);  // Top Left Of The Texture and Quad
431             rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z + length/2);  // Bottom Left Of The Texture and Quad
432             // Left Face
433             rlNormal3f( - 1.0f, 0.0f, 0.0f);                  // Normal Pointing Left
434             rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z - length/2);  // Bottom Left Of The Texture and Quad
435             rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z + length/2);  // Bottom Right Of The Texture and Quad
436             rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z + length/2);  // Top Right Of The Texture and Quad
437             rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z - length/2);  // Top Left Of The Texture and Quad
438         rlEnd();
439     //rlPopMatrix();
440
441     rlSetTexture(0);
442 }
443
444 // Draw sphere
445 void DrawSphere(Vector3 centerPos, float radius, Color color)
446 {
447     DrawSphereEx(centerPos, radius, 16, 16, color);
448 }
449
450 // Draw sphere with extended parameters
451 void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color)
452 {
453     int numVertex = (rings + 2)*slices*6;
454     rlCheckRenderBatchLimit(numVertex);
455
456     rlPushMatrix();
457         // NOTE: Transformation is applied in inverse order (scale -> translate)
458         rlTranslatef(centerPos.x, centerPos.y, centerPos.z);
459         rlScalef(radius, radius, radius);
460
461         rlBegin(RL_TRIANGLES);
462             rlColor4ub(color.r, color.g, color.b, color.a);
463
464             for (int i = 0; i < (rings + 2); i++)
465             {
466                 for (int j = 0; j < slices; j++)
467                 {
468                     rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*i))*sinf(DEG2RAD*(j*360/slices)),
469                                sinf(DEG2RAD*(270+(180/(rings + 1))*i)),
470                                cosf(DEG2RAD*(270+(180/(rings + 1))*i))*cosf(DEG2RAD*(j*360/slices)));
471                     rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360/slices)),
472                                sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
473                                cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360/slices)));
474                     rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*(j*360/slices)),
475                                sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
476                                cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*(j*360/slices)));
477
478                     rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*i))*sinf(DEG2RAD*(j*360/slices)),
479                                sinf(DEG2RAD*(270+(180/(rings + 1))*i)),
480                                cosf(DEG2RAD*(270+(180/(rings + 1))*i))*cosf(DEG2RAD*(j*360/slices)));
481                     rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i)))*sinf(DEG2RAD*((j+1)*360/slices)),
482                                sinf(DEG2RAD*(270+(180/(rings + 1))*(i))),
483                                cosf(DEG2RAD*(270+(180/(rings + 1))*(i)))*cosf(DEG2RAD*((j+1)*360/slices)));
484                     rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360/slices)),
485                                sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
486                                cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360/slices)));
487                 }
488             }
489         rlEnd();
490     rlPopMatrix();
491 }
492
493 // Draw sphere wires
494 void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color)
495 {
496     int numVertex = (rings + 2)*slices*6;
497     rlCheckRenderBatchLimit(numVertex);
498
499     rlPushMatrix();
500         // NOTE: Transformation is applied in inverse order (scale -> translate)
501         rlTranslatef(centerPos.x, centerPos.y, centerPos.z);
502         rlScalef(radius, radius, radius);
503
504         rlBegin(RL_LINES);
505             rlColor4ub(color.r, color.g, color.b, color.a);
506
507             for (int i = 0; i < (rings + 2); i++)
508             {
509                 for (int j = 0; j < slices; j++)
510                 {
511                     rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*i))*sinf(DEG2RAD*(j*360/slices)),
512                                sinf(DEG2RAD*(270+(180/(rings + 1))*i)),
513                                cosf(DEG2RAD*(270+(180/(rings + 1))*i))*cosf(DEG2RAD*(j*360/slices)));
514                     rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360/slices)),
515                                sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
516                                cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360/slices)));
517
518                     rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360/slices)),
519                                sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
520                                cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360/slices)));
521                     rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*(j*360/slices)),
522                                sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
523                                cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*(j*360/slices)));
524
525                     rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*(j*360/slices)),
526                                sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
527                                cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*(j*360/slices)));
528                     rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*i))*sinf(DEG2RAD*(j*360/slices)),
529                                sinf(DEG2RAD*(270+(180/(rings + 1))*i)),
530                                cosf(DEG2RAD*(270+(180/(rings + 1))*i))*cosf(DEG2RAD*(j*360/slices)));
531                 }
532             }
533         rlEnd();
534     rlPopMatrix();
535 }
536
537 // Draw a cylinder
538 // NOTE: It could be also used for pyramid and cone
539 void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int sides, Color color)
540 {
541     if (sides < 3) sides = 3;
542
543     int numVertex = sides*6;
544     rlCheckRenderBatchLimit(numVertex);
545
546     rlPushMatrix();
547         rlTranslatef(position.x, position.y, position.z);
548
549         rlBegin(RL_TRIANGLES);
550             rlColor4ub(color.r, color.g, color.b, color.a);
551
552             if (radiusTop > 0)
553             {
554                 // Draw Body -------------------------------------------------------------------------------------
555                 for (int i = 0; i < 360; i += 360/sides)
556                 {
557                     rlVertex3f(sinf(DEG2RAD*i)*radiusBottom, 0, cosf(DEG2RAD*i)*radiusBottom); //Bottom Left
558                     rlVertex3f(sinf(DEG2RAD*(i + 360/sides))*radiusBottom, 0, cosf(DEG2RAD*(i + 360/sides))*radiusBottom); //Bottom Right
559                     rlVertex3f(sinf(DEG2RAD*(i + 360/sides))*radiusTop, height, cosf(DEG2RAD*(i + 360/sides))*radiusTop); //Top Right
560
561                     rlVertex3f(sinf(DEG2RAD*i)*radiusTop, height, cosf(DEG2RAD*i)*radiusTop); //Top Left
562                     rlVertex3f(sinf(DEG2RAD*i)*radiusBottom, 0, cosf(DEG2RAD*i)*radiusBottom); //Bottom Left
563                     rlVertex3f(sinf(DEG2RAD*(i + 360/sides))*radiusTop, height, cosf(DEG2RAD*(i + 360/sides))*radiusTop); //Top Right
564                 }
565
566                 // Draw Cap --------------------------------------------------------------------------------------
567                 for (int i = 0; i < 360; i += 360/sides)
568                 {
569                     rlVertex3f(0, height, 0);
570                     rlVertex3f(sinf(DEG2RAD*i)*radiusTop, height, cosf(DEG2RAD*i)*radiusTop);
571                     rlVertex3f(sinf(DEG2RAD*(i + 360/sides))*radiusTop, height, cosf(DEG2RAD*(i + 360/sides))*radiusTop);
572                 }
573             }
574             else
575             {
576                 // Draw Cone -------------------------------------------------------------------------------------
577                 for (int i = 0; i < 360; i += 360/sides)
578                 {
579                     rlVertex3f(0, height, 0);
580                     rlVertex3f(sinf(DEG2RAD*i)*radiusBottom, 0, cosf(DEG2RAD*i)*radiusBottom);
581                     rlVertex3f(sinf(DEG2RAD*(i + 360/sides))*radiusBottom, 0, cosf(DEG2RAD*(i + 360/sides))*radiusBottom);
582                 }
583             }
584
585             // Draw Base -----------------------------------------------------------------------------------------
586             for (int i = 0; i < 360; i += 360/sides)
587             {
588                 rlVertex3f(0, 0, 0);
589                 rlVertex3f(sinf(DEG2RAD*(i + 360/sides))*radiusBottom, 0, cosf(DEG2RAD*(i + 360/sides))*radiusBottom);
590                 rlVertex3f(sinf(DEG2RAD*i)*radiusBottom, 0, cosf(DEG2RAD*i)*radiusBottom);
591             }
592         rlEnd();
593     rlPopMatrix();
594 }
595
596 // Draw a wired cylinder
597 // NOTE: It could be also used for pyramid and cone
598 void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int sides, Color color)
599 {
600     if (sides < 3) sides = 3;
601
602     int numVertex = sides*8;
603     rlCheckRenderBatchLimit(numVertex);
604
605     rlPushMatrix();
606         rlTranslatef(position.x, position.y, position.z);
607
608         rlBegin(RL_LINES);
609             rlColor4ub(color.r, color.g, color.b, color.a);
610
611             for (int i = 0; i < 360; i += 360/sides)
612             {
613                 rlVertex3f(sinf(DEG2RAD*i)*radiusBottom, 0, cosf(DEG2RAD*i)*radiusBottom);
614                 rlVertex3f(sinf(DEG2RAD*(i + 360/sides))*radiusBottom, 0, cosf(DEG2RAD*(i + 360/sides))*radiusBottom);
615
616                 rlVertex3f(sinf(DEG2RAD*(i + 360/sides))*radiusBottom, 0, cosf(DEG2RAD*(i + 360/sides))*radiusBottom);
617                 rlVertex3f(sinf(DEG2RAD*(i + 360/sides))*radiusTop, height, cosf(DEG2RAD*(i + 360/sides))*radiusTop);
618
619                 rlVertex3f(sinf(DEG2RAD*(i + 360/sides))*radiusTop, height, cosf(DEG2RAD*(i + 360/sides))*radiusTop);
620                 rlVertex3f(sinf(DEG2RAD*i)*radiusTop, height, cosf(DEG2RAD*i)*radiusTop);
621
622                 rlVertex3f(sinf(DEG2RAD*i)*radiusTop, height, cosf(DEG2RAD*i)*radiusTop);
623                 rlVertex3f(sinf(DEG2RAD*i)*radiusBottom, 0, cosf(DEG2RAD*i)*radiusBottom);
624             }
625         rlEnd();
626     rlPopMatrix();
627 }
628
629 // Draw a plane
630 void DrawPlane(Vector3 centerPos, Vector2 size, Color color)
631 {
632     rlCheckRenderBatchLimit(4);
633
634     // NOTE: Plane is always created on XZ ground
635     rlPushMatrix();
636         rlTranslatef(centerPos.x, centerPos.y, centerPos.z);
637         rlScalef(size.x, 1.0f, size.y);
638
639         rlBegin(RL_QUADS);
640             rlColor4ub(color.r, color.g, color.b, color.a);
641             rlNormal3f(0.0f, 1.0f, 0.0f);
642
643             rlVertex3f(-0.5f, 0.0f, -0.5f);
644             rlVertex3f(-0.5f, 0.0f, 0.5f);
645             rlVertex3f(0.5f, 0.0f, 0.5f);
646             rlVertex3f(0.5f, 0.0f, -0.5f);
647         rlEnd();
648     rlPopMatrix();
649 }
650
651 // Draw a ray line
652 void DrawRay(Ray ray, Color color)
653 {
654     float scale = 10000;
655
656     rlBegin(RL_LINES);
657         rlColor4ub(color.r, color.g, color.b, color.a);
658         rlColor4ub(color.r, color.g, color.b, color.a);
659
660         rlVertex3f(ray.position.x, ray.position.y, ray.position.z);
661         rlVertex3f(ray.position.x + ray.direction.x*scale, ray.position.y + ray.direction.y*scale, ray.position.z + ray.direction.z*scale);
662     rlEnd();
663 }
664
665 // Draw a grid centered at (0, 0, 0)
666 void DrawGrid(int slices, float spacing)
667 {
668     int halfSlices = slices/2;
669
670     rlCheckRenderBatchLimit((slices + 2)*4);
671
672     rlBegin(RL_LINES);
673         for (int i = -halfSlices; i <= halfSlices; i++)
674         {
675             if (i == 0)
676             {
677                 rlColor3f(0.5f, 0.5f, 0.5f);
678                 rlColor3f(0.5f, 0.5f, 0.5f);
679                 rlColor3f(0.5f, 0.5f, 0.5f);
680                 rlColor3f(0.5f, 0.5f, 0.5f);
681             }
682             else
683             {
684                 rlColor3f(0.75f, 0.75f, 0.75f);
685                 rlColor3f(0.75f, 0.75f, 0.75f);
686                 rlColor3f(0.75f, 0.75f, 0.75f);
687                 rlColor3f(0.75f, 0.75f, 0.75f);
688             }
689
690             rlVertex3f((float)i*spacing, 0.0f, (float)-halfSlices*spacing);
691             rlVertex3f((float)i*spacing, 0.0f, (float)halfSlices*spacing);
692
693             rlVertex3f((float)-halfSlices*spacing, 0.0f, (float)i*spacing);
694             rlVertex3f((float)halfSlices*spacing, 0.0f, (float)i*spacing);
695         }
696     rlEnd();
697 }
698
699 // Load model from files (mesh and material)
700 Model LoadModel(const char *fileName)
701 {
702     Model model = { 0 };
703
704 #if defined(SUPPORT_FILEFORMAT_OBJ)
705     if (IsFileExtension(fileName, ".obj")) model = LoadOBJ(fileName);
706 #endif
707 #if defined(SUPPORT_FILEFORMAT_IQM)
708     if (IsFileExtension(fileName, ".iqm")) model = LoadIQM(fileName);
709 #endif
710 #if defined(SUPPORT_FILEFORMAT_GLTF)
711     if (IsFileExtension(fileName, ".gltf;.glb")) model = LoadGLTF(fileName);
712 #endif
713
714     // Make sure model transform is set to identity matrix!
715     model.transform = MatrixIdentity();
716
717     if (model.meshCount == 0)
718     {
719         model.meshCount = 1;
720         model.meshes = (Mesh *)RL_CALLOC(model.meshCount, sizeof(Mesh));
721 #if defined(SUPPORT_MESH_GENERATION)
722         TRACELOG(LOG_WARNING, "MESH: [%s] Failed to load mesh data, default to cube mesh", fileName);
723         model.meshes[0] = GenMeshCube(1.0f, 1.0f, 1.0f);
724 #else
725         TRACELOG(LOG_WARNING, "MESH: [%s] Failed to load mesh data", fileName);
726 #endif
727     }
728     else
729     {
730         // Upload vertex data to GPU (static mesh)
731         for (int i = 0; i < model.meshCount; i++) UploadMesh(&model.meshes[i], false);
732     }
733
734     if (model.materialCount == 0)
735     {
736         TRACELOG(LOG_WARNING, "MATERIAL: [%s] Failed to load material data, default to white material", fileName);
737
738         model.materialCount = 1;
739         model.materials = (Material *)RL_CALLOC(model.materialCount, sizeof(Material));
740         model.materials[0] = LoadMaterialDefault();
741
742         if (model.meshMaterial == NULL) model.meshMaterial = (int *)RL_CALLOC(model.meshCount, sizeof(int));
743     }
744
745     return model;
746 }
747
748 // Load model from generated mesh
749 // WARNING: A shallow copy of mesh is generated, passed by value,
750 // as long as struct contains pointers to data and some values, we get a copy
751 // of mesh pointing to same data as original version... be careful!
752 Model LoadModelFromMesh(Mesh mesh)
753 {
754     Model model = { 0 };
755
756     model.transform = MatrixIdentity();
757
758     model.meshCount = 1;
759     model.meshes = (Mesh *)RL_CALLOC(model.meshCount, sizeof(Mesh));
760     model.meshes[0] = mesh;
761
762     model.materialCount = 1;
763     model.materials = (Material *)RL_CALLOC(model.materialCount, sizeof(Material));
764     model.materials[0] = LoadMaterialDefault();
765
766     model.meshMaterial = (int *)RL_CALLOC(model.meshCount, sizeof(int));
767     model.meshMaterial[0] = 0;  // First material index
768
769     return model;
770 }
771
772 // Unload model (meshes/materials) from memory (RAM and/or VRAM)
773 // NOTE: This function takes care of all model elements, for a detailed control
774 // over them, use UnloadMesh() and UnloadMaterial()
775 void UnloadModel(Model model)
776 {
777     // Unload meshes
778     for (int i = 0; i < model.meshCount; i++) UnloadMesh(model.meshes[i]);
779
780     // Unload materials maps
781     // NOTE: As the user could be sharing shaders and textures between models,
782     // we don't unload the material but just free it's maps,
783     // the user is responsible for freeing models shaders and textures
784     for (int i = 0; i < model.materialCount; i++) RL_FREE(model.materials[i].maps);
785
786     // Unload arrays
787     RL_FREE(model.meshes);
788     RL_FREE(model.materials);
789     RL_FREE(model.meshMaterial);
790
791     // Unload animation data
792     RL_FREE(model.bones);
793     RL_FREE(model.bindPose);
794
795     TRACELOG(LOG_INFO, "MODEL: Unloaded model (and meshes) from RAM and VRAM");
796 }
797
798 // Unload model (but not meshes) from memory (RAM and/or VRAM)
799 void UnloadModelKeepMeshes(Model model)
800 {
801     // Unload materials maps
802     // NOTE: As the user could be sharing shaders and textures between models,
803     // we don't unload the material but just free it's maps,
804     // the user is responsible for freeing models shaders and textures
805     for (int i = 0; i < model.materialCount; i++) RL_FREE(model.materials[i].maps);
806
807     // Unload arrays
808     RL_FREE(model.meshes);
809     RL_FREE(model.materials);
810     RL_FREE(model.meshMaterial);
811
812     // Unload animation data
813     RL_FREE(model.bones);
814     RL_FREE(model.bindPose);
815
816     TRACELOG(LOG_INFO, "MODEL: Unloaded model (but not meshes) from RAM and VRAM");
817 }
818
819 // Upload vertex data into a VAO (if supported) and VBO
820 void UploadMesh(Mesh *mesh, bool dynamic)
821 {
822     if (mesh->vaoId > 0)
823     {
824         // Check if mesh has already been loaded in GPU
825         TRACELOG(LOG_WARNING, "VAO: [ID %i] Trying to re-load an already loaded mesh", mesh->vaoId);
826         return;
827     }
828
829     mesh->vboId = (unsigned int *)RL_CALLOC(MAX_MESH_VERTEX_BUFFERS, sizeof(unsigned int));
830
831     mesh->vaoId = 0;        // Vertex Array Object
832     mesh->vboId[0] = 0;     // Vertex buffer: positions
833     mesh->vboId[1] = 0;     // Vertex buffer: texcoords
834     mesh->vboId[2] = 0;     // Vertex buffer: normals
835     mesh->vboId[3] = 0;     // Vertex buffer: colors
836     mesh->vboId[4] = 0;     // Vertex buffer: tangents
837     mesh->vboId[5] = 0;     // Vertex buffer: texcoords2
838     mesh->vboId[6] = 0;     // Vertex buffer: indices
839
840 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
841     mesh->vaoId = rlLoadVertexArray();
842     rlEnableVertexArray(mesh->vaoId);
843
844     // NOTE: Attributes must be uploaded considering default locations points
845
846     // Enable vertex attributes: position (shader-location = 0)
847     mesh->vboId[0] = rlLoadVertexBuffer(mesh->vertices, mesh->vertexCount*3*sizeof(float), dynamic);
848     rlSetVertexAttribute(0, 3, RL_FLOAT, 0, 0, 0);
849     rlEnableVertexAttribute(0);
850
851     // Enable vertex attributes: texcoords (shader-location = 1)
852     mesh->vboId[1] = rlLoadVertexBuffer(mesh->texcoords, mesh->vertexCount*2*sizeof(float), dynamic);
853     rlSetVertexAttribute(1, 2, RL_FLOAT, 0, 0, 0);
854     rlEnableVertexAttribute(1);
855
856     if (mesh->normals != NULL)
857     {
858         // Enable vertex attributes: normals (shader-location = 2)
859         mesh->vboId[2] = rlLoadVertexBuffer(mesh->normals, mesh->vertexCount*3*sizeof(float), dynamic);
860         rlSetVertexAttribute(2, 3, RL_FLOAT, 0, 0, 0);
861         rlEnableVertexAttribute(2);
862     }
863     else
864     {
865         // Default color vertex attribute set to WHITE
866         float value[3] = { 1.0f, 1.0f, 1.0f };
867         rlSetVertexAttributeDefault(2, value, SHADER_ATTRIB_VEC3, 3);
868         rlDisableVertexAttribute(2);
869     }
870
871     if (mesh->colors != NULL)
872     {
873         // Enable vertex attribute: color (shader-location = 3)
874         mesh->vboId[3] = rlLoadVertexBuffer(mesh->colors, mesh->vertexCount*4*sizeof(unsigned char), dynamic);
875         rlSetVertexAttribute(3, 4, RL_UNSIGNED_BYTE, 1, 0, 0);
876         rlEnableVertexAttribute(3);
877     }
878     else
879     {
880         // Default color vertex attribute set to WHITE
881         float value[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
882         rlSetVertexAttributeDefault(3, value, SHADER_ATTRIB_VEC4, 4);
883         rlDisableVertexAttribute(3);
884     }
885
886     if (mesh->tangents != NULL)
887     {
888         // Enable vertex attribute: tangent (shader-location = 4)
889         mesh->vboId[4] = rlLoadVertexBuffer(mesh->tangents, mesh->vertexCount*4*sizeof(float), dynamic);
890         rlSetVertexAttribute(4, 4, RL_FLOAT, 0, 0, 0);
891         rlEnableVertexAttribute(4);
892     }
893     else
894     {
895         // Default tangents vertex attribute
896         float value[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
897         rlSetVertexAttributeDefault(4, value, SHADER_ATTRIB_VEC4, 4);
898         rlDisableVertexAttribute(4);
899     }
900
901     if (mesh->texcoords2 != NULL)
902     {
903         // Enable vertex attribute: texcoord2 (shader-location = 5)
904         mesh->vboId[5] = rlLoadVertexBuffer(mesh->texcoords2, mesh->vertexCount*2*sizeof(float), dynamic);
905         rlSetVertexAttribute(5, 2, RL_FLOAT, 0, 0, 0);
906         rlEnableVertexAttribute(5);
907     }
908     else
909     {
910         // Default texcoord2 vertex attribute
911         float value[2] = { 0.0f, 0.0f };
912         rlSetVertexAttributeDefault(5, value, SHADER_ATTRIB_VEC2, 2);
913         rlDisableVertexAttribute(5);
914     }
915
916     if (mesh->indices != NULL)
917     {
918         mesh->vboId[6] = rlLoadVertexBufferElement(mesh->indices, mesh->triangleCount*3*sizeof(unsigned short), dynamic);
919     }
920
921     if (mesh->vaoId > 0) TRACELOG(LOG_INFO, "VAO: [ID %i] Mesh uploaded successfully to VRAM (GPU)", mesh->vaoId);
922     else TRACELOG(LOG_INFO, "VBO: Mesh uploaded successfully to VRAM (GPU)");
923
924     rlDisableVertexArray();
925 #endif
926 }
927
928 // Update mesh vertex data in GPU for a specific buffer index
929 void UpdateMeshBuffer(Mesh mesh, int index, void *data, int dataSize, int offset)
930 {
931     rlUpdateVertexBuffer(mesh.vboId[index], data, dataSize, offset);
932 }
933
934 // Draw a 3d mesh with material and transform
935 void DrawMesh(Mesh mesh, Material material, Matrix transform)
936 {
937     DrawMeshInstanced(mesh, material, &transform, 1);
938 }
939
940 // Draw multiple mesh instances with material and different transforms
941 void DrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int instances)
942 {
943 #if defined(GRAPHICS_API_OPENGL_11)
944     #define GL_VERTEX_ARRAY         0x8074
945     #define GL_NORMAL_ARRAY         0x8075
946     #define GL_COLOR_ARRAY          0x8076
947     #define GL_TEXTURE_COORD_ARRAY  0x8078
948
949     rlEnableTexture(material.maps[MATERIAL_MAP_DIFFUSE].texture.id);
950
951     rlEnableStatePointer(GL_VERTEX_ARRAY, mesh.vertices);
952     rlEnableStatePointer(GL_TEXTURE_COORD_ARRAY, mesh.texcoords);
953     rlEnableStatePointer(GL_NORMAL_ARRAY, mesh.normals);
954     rlEnableStatePointer(GL_COLOR_ARRAY, mesh.colors);
955
956     rlPushMatrix();
957         rlMultMatrixf(MatrixToFloat(transforms[0]));
958         rlColor4ub(material.maps[MATERIAL_MAP_DIFFUSE].color.r,
959                    material.maps[MATERIAL_MAP_DIFFUSE].color.g,
960                    material.maps[MATERIAL_MAP_DIFFUSE].color.b,
961                    material.maps[MATERIAL_MAP_DIFFUSE].color.a);
962
963         if (mesh.indices != NULL) rlDrawVertexArrayElements(0, mesh.triangleCount*3, mesh.indices);
964         else rlDrawVertexArray(0, mesh.vertexCount);
965     rlPopMatrix();
966
967     rlDisableStatePointer(GL_VERTEX_ARRAY);
968     rlDisableStatePointer(GL_TEXTURE_COORD_ARRAY);
969     rlDisableStatePointer(GL_NORMAL_ARRAY);
970     rlDisableStatePointer(GL_COLOR_ARRAY);
971
972     rlDisableTexture();
973 #endif
974
975 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
976     // Check instancing
977     bool instancing = false;
978     if (instances < 1) return;
979     else if (instances > 1) instancing = true;
980     float16 *instanceTransforms = NULL;
981     unsigned int instancesVboId = 0;
982
983     // Bind shader program
984     rlEnableShader(material.shader.id);
985
986     // Send required data to shader (matrices, values)
987     //-----------------------------------------------------
988     // Upload to shader material.colDiffuse
989     if (material.shader.locs[SHADER_LOC_COLOR_DIFFUSE] != -1)
990     {
991         float values[4] = {
992             (float)material.maps[MATERIAL_MAP_DIFFUSE].color.r/255.0f,
993             (float)material.maps[MATERIAL_MAP_DIFFUSE].color.g/255.0f,
994             (float)material.maps[MATERIAL_MAP_DIFFUSE].color.b/255.0f,
995             (float)material.maps[MATERIAL_MAP_DIFFUSE].color.a/255.0f
996         };
997
998         rlSetUniform(material.shader.locs[SHADER_LOC_COLOR_DIFFUSE], values, SHADER_UNIFORM_VEC4, 1);
999     }
1000
1001     // Upload to shader material.colSpecular (if location available)
1002     if (material.shader.locs[SHADER_LOC_COLOR_SPECULAR] != -1)
1003     {
1004         float values[4] = {
1005             (float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.r/255.0f,
1006             (float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.g/255.0f,
1007             (float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.b/255.0f,
1008             (float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.a/255.0f
1009         };
1010
1011         rlSetUniform(material.shader.locs[SHADER_LOC_COLOR_SPECULAR], values, SHADER_UNIFORM_VEC4, 1);
1012     }
1013
1014     // Get a copy of current matrices to work with,
1015     // just in case stereo render is required and we need to modify them
1016     // NOTE: At this point the modelview matrix just contains the view matrix (camera)
1017     // That's because BeginMode3D() sets it and there is no model-drawing function
1018     // that modifies it, all use rlPushMatrix() and rlPopMatrix()
1019     Matrix matView = rlGetMatrixModelview();
1020     Matrix matModelView = matView;
1021     Matrix matProjection = rlGetMatrixProjection();
1022
1023     // Upload view and projection matrices (if locations available)
1024     if (material.shader.locs[SHADER_LOC_MATRIX_VIEW] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_VIEW], matView);
1025     if (material.shader.locs[SHADER_LOC_MATRIX_PROJECTION] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_PROJECTION], matProjection);
1026
1027     if (instancing)
1028     {
1029         // Create instances buffer
1030         instanceTransforms = RL_MALLOC(instances*sizeof(float16));
1031
1032         // Fill buffer with instances transformations as float16 arrays
1033         for (int i = 0; i < instances; i++) instanceTransforms[i] = MatrixToFloatV(transforms[i]);
1034
1035         // Enable mesh VAO to attach new buffer
1036         rlEnableVertexArray(mesh.vaoId);
1037
1038         // This could alternatively use a static VBO and either glMapBuffer() or glBufferSubData().
1039         // It isn't clear which would be reliably faster in all cases and on all platforms,
1040         // anecdotally glMapBuffer() seems very slow (syncs) while glBufferSubData() seems
1041         // no faster, since we're transferring all the transform matrices anyway
1042         instancesVboId = rlLoadVertexBuffer(instanceTransforms, instances*sizeof(float16), false);
1043
1044         // Instances transformation matrices are send to shader attribute location: SHADER_LOC_MATRIX_MODEL
1045         for (unsigned int i = 0; i < 4; i++)
1046         {
1047             rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i);
1048             rlSetVertexAttribute(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i, 4, RL_FLOAT, 0, sizeof(Matrix), (void *)(i*sizeof(Vector4)));
1049             rlSetVertexAttributeDivisor(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i, 1);
1050         }
1051
1052         rlDisableVertexBuffer();
1053         rlDisableVertexArray();
1054
1055         // Accumulate internal matrix transform (push/pop) and view matrix
1056         // NOTE: In this case, model instance transformation must be computed in the shader
1057         matModelView = MatrixMultiply(rlGetMatrixTransform(), matView);
1058     }
1059     else
1060     {
1061         // Model transformation matrix is send to shader uniform location: SHADER_LOC_MATRIX_MODEL
1062         if (material.shader.locs[SHADER_LOC_MATRIX_MODEL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_MODEL], transforms[0]);
1063
1064         // Accumulate several transformations:
1065         //    matView: rlgl internal modelview matrix (actually, just view matrix)
1066         //    rlGetMatrixTransform(): rlgl internal transform matrix due to push/pop matrix stack
1067         //    transform: function parameter transformation
1068         matModelView = MatrixMultiply(transforms[0], MatrixMultiply(rlGetMatrixTransform(), matView));
1069     }
1070
1071     // Upload model normal matrix (if locations available)
1072     if (material.shader.locs[SHADER_LOC_MATRIX_NORMAL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_NORMAL], MatrixTranspose(MatrixInvert(matModelView)));
1073     //-----------------------------------------------------
1074
1075     // Bind active texture maps (if available)
1076     for (int i = 0; i < MAX_MATERIAL_MAPS; i++)
1077     {
1078         if (material.maps[i].texture.id > 0)
1079         {
1080             // Select current shader texture slot
1081             rlActiveTextureSlot(i);
1082
1083             // Enable texture for active slot
1084             if ((i == MATERIAL_MAP_IRRADIANCE) ||
1085                 (i == MATERIAL_MAP_PREFILTER) ||
1086                 (i == MATERIAL_MAP_CUBEMAP)) rlEnableTextureCubemap(material.maps[i].texture.id);
1087             else rlEnableTexture(material.maps[i].texture.id);
1088
1089             rlSetUniform(material.shader.locs[SHADER_LOC_MAP_DIFFUSE + i], &i, SHADER_UNIFORM_INT, 1);
1090         }
1091     }
1092
1093     // Try binding vertex array objects (VAO)
1094     // or use VBOs if not possible
1095     if (!rlEnableVertexArray(mesh.vaoId))
1096     {
1097         // Bind mesh VBO data: vertex position (shader-location = 0)
1098         rlEnableVertexBuffer(mesh.vboId[0]);
1099         rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION], 3, RL_FLOAT, 0, 0, 0);
1100         rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION]);
1101
1102         rlEnableVertexBuffer(mesh.vboId[0]);
1103         rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION], 3, RL_FLOAT, 0, 0, 0);
1104         rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION]);
1105
1106         // Bind mesh VBO data: vertex texcoords (shader-location = 1)
1107         rlEnableVertexBuffer(mesh.vboId[1]);
1108         rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01], 2, RL_FLOAT, 0, 0, 0);
1109         rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01]);
1110
1111         if (material.shader.locs[SHADER_LOC_VERTEX_NORMAL] != -1)
1112         {
1113             // Bind mesh VBO data: vertex normals (shader-location = 2)
1114             rlEnableVertexBuffer(mesh.vboId[2]);
1115             rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_NORMAL], 3, RL_FLOAT, 0, 0, 0);
1116             rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_NORMAL]);
1117         }
1118
1119         // Bind mesh VBO data: vertex colors (shader-location = 3, if available)
1120         if (material.shader.locs[SHADER_LOC_VERTEX_COLOR] != -1)
1121         {
1122             if (mesh.vboId[3] != 0)
1123             {
1124                 rlEnableVertexBuffer(mesh.vboId[3]);
1125                 rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR], 4, RL_UNSIGNED_BYTE, 1, 0, 0);
1126                 rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR]);
1127             }
1128             else
1129             {
1130                 // Set default value for unused attribute
1131                 // NOTE: Required when using default shader and no VAO support
1132                 float value[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
1133                 rlSetVertexAttributeDefault(material.shader.locs[SHADER_LOC_VERTEX_COLOR], value, SHADER_ATTRIB_VEC2, 4);
1134                 rlDisableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR]);
1135             }
1136         }
1137
1138         // Bind mesh VBO data: vertex tangents (shader-location = 4, if available)
1139         if (material.shader.locs[SHADER_LOC_VERTEX_TANGENT] != -1)
1140         {
1141             rlEnableVertexBuffer(mesh.vboId[4]);
1142             rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TANGENT], 4, RL_FLOAT, 0, 0, 0);
1143             rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TANGENT]);
1144         }
1145
1146         // Bind mesh VBO data: vertex texcoords2 (shader-location = 5, if available)
1147         if (material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02] != -1)
1148         {
1149             rlEnableVertexBuffer(mesh.vboId[5]);
1150             rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02], 2, RL_FLOAT, 0, 0, 0);
1151             rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02]);
1152         }
1153
1154         if (mesh.indices != NULL) rlEnableVertexBufferElement(mesh.vboId[6]);
1155     }
1156
1157     int eyesCount = 1;
1158     if (rlIsStereoRenderEnabled()) eyesCount = 2;
1159
1160     for (int eye = 0; eye < eyesCount; eye++)
1161     {
1162         // Calculate model-view-projection matrix (MVP)
1163         Matrix matMVP = MatrixIdentity();
1164         if (eyesCount == 1) matMVP = MatrixMultiply(matModelView, matProjection);
1165         else
1166         {
1167             // Setup current eye viewport (half screen width)
1168             rlViewport(eye*rlGetFramebufferWidth()/2, 0, rlGetFramebufferWidth()/2, rlGetFramebufferHeight());
1169             matMVP = MatrixMultiply(MatrixMultiply(matModelView, rlGetMatrixViewOffsetStereo(eye)), rlGetMatrixProjectionStereo(eye));
1170         }
1171
1172         // Send combined model-view-projection matrix to shader
1173         rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_MVP], matMVP);
1174
1175         if (instancing) // Draw mesh instanced
1176         {
1177             if (mesh.indices != NULL) rlDrawVertexArrayElementsInstanced(0, mesh.triangleCount*3, 0, instances);
1178             else rlDrawVertexArrayInstanced(0, mesh.vertexCount, instances);
1179         }
1180         else    // Draw mesh
1181         {
1182             if (mesh.indices != NULL) rlDrawVertexArrayElements(0, mesh.triangleCount*3, 0);
1183             else rlDrawVertexArray(0, mesh.vertexCount);
1184         }
1185     }
1186
1187     // Unbind all binded texture maps
1188     for (int i = 0; i < MAX_MATERIAL_MAPS; i++)
1189     {
1190         // Select current shader texture slot
1191         rlActiveTextureSlot(i);
1192
1193         // Disable texture for active slot
1194         if ((i == MATERIAL_MAP_IRRADIANCE) ||
1195             (i == MATERIAL_MAP_PREFILTER) ||
1196             (i == MATERIAL_MAP_CUBEMAP)) rlDisableTextureCubemap();
1197         else rlDisableTexture();
1198     }
1199
1200     // Disable all possible vertex array objects (or VBOs)
1201     rlDisableVertexArray();
1202     rlDisableVertexBuffer();
1203     rlDisableVertexBufferElement();
1204
1205     // Disable shader program
1206     rlDisableShader();
1207
1208     if (instancing)
1209     {
1210         // Remove instance transforms buffer
1211         rlUnloadVertexBuffer(instancesVboId);
1212         RL_FREE(instanceTransforms);
1213     }
1214     else
1215     {
1216         // Restore rlgl internal modelview and projection matrices
1217         rlSetMatrixModelview(matView);
1218         rlSetMatrixProjection(matProjection);
1219     }
1220 #endif
1221 }
1222
1223 // Unload mesh from memory (RAM and VRAM)
1224 void UnloadMesh(Mesh mesh)
1225 {
1226     // Unload rlgl mesh vboId data
1227     rlUnloadVertexArray(mesh.vaoId);
1228
1229     for (int i = 0; i < MAX_MESH_VERTEX_BUFFERS; i++) rlUnloadVertexBuffer(mesh.vboId[i]);
1230     RL_FREE(mesh.vboId);
1231
1232     RL_FREE(mesh.vertices);
1233     RL_FREE(mesh.texcoords);
1234     RL_FREE(mesh.normals);
1235     RL_FREE(mesh.colors);
1236     RL_FREE(mesh.tangents);
1237     RL_FREE(mesh.texcoords2);
1238     RL_FREE(mesh.indices);
1239
1240     RL_FREE(mesh.animVertices);
1241     RL_FREE(mesh.animNormals);
1242     RL_FREE(mesh.boneWeights);
1243     RL_FREE(mesh.boneIds);
1244 }
1245
1246 // Export mesh data to file
1247 bool ExportMesh(Mesh mesh, const char *fileName)
1248 {
1249     bool success = false;
1250
1251     if (IsFileExtension(fileName, ".obj"))
1252     {
1253         // Estimated data size, it should be enough...
1254         int dataSize = mesh.vertexCount/3* (int)strlen("v 0000.00f 0000.00f 0000.00f") +
1255                        mesh.vertexCount/2* (int)strlen("vt 0.000f 0.00f") +
1256                        mesh.vertexCount/3* (int)strlen("vn 0.000f 0.00f 0.00f") +
1257                        mesh.triangleCount/3* (int)strlen("f 00000/00000/00000 00000/00000/00000 00000/00000/00000");
1258
1259         // NOTE: Text data buffer size is estimated considering mesh data size
1260         char *txtData = (char *)RL_CALLOC(dataSize + 2000, sizeof(char));
1261
1262         int bytesCount = 0;
1263         bytesCount += sprintf(txtData + bytesCount, "# //////////////////////////////////////////////////////////////////////////////////\n");
1264         bytesCount += sprintf(txtData + bytesCount, "# //                                                                              //\n");
1265         bytesCount += sprintf(txtData + bytesCount, "# // rMeshOBJ exporter v1.0 - Mesh exported as triangle faces and not optimized   //\n");
1266         bytesCount += sprintf(txtData + bytesCount, "# //                                                                              //\n");
1267         bytesCount += sprintf(txtData + bytesCount, "# // more info and bugs-report:  github.com/raysan5/raylib                        //\n");
1268         bytesCount += sprintf(txtData + bytesCount, "# // feedback and support:       ray[at]raylib.com                                //\n");
1269         bytesCount += sprintf(txtData + bytesCount, "# //                                                                              //\n");
1270         bytesCount += sprintf(txtData + bytesCount, "# // Copyright (c) 2018 Ramon Santamaria (@raysan5)                               //\n");
1271         bytesCount += sprintf(txtData + bytesCount, "# //                                                                              //\n");
1272         bytesCount += sprintf(txtData + bytesCount, "# //////////////////////////////////////////////////////////////////////////////////\n\n");
1273         bytesCount += sprintf(txtData + bytesCount, "# Vertex Count:     %i\n", mesh.vertexCount);
1274         bytesCount += sprintf(txtData + bytesCount, "# Triangle Count:   %i\n\n", mesh.triangleCount);
1275
1276         bytesCount += sprintf(txtData + bytesCount, "g mesh\n");
1277
1278         for (int i = 0, v = 0; i < mesh.vertexCount; i++, v += 3)
1279         {
1280             bytesCount += sprintf(txtData + bytesCount, "v %.2f %.2f %.2f\n", mesh.vertices[v], mesh.vertices[v + 1], mesh.vertices[v + 2]);
1281         }
1282
1283         for (int i = 0, v = 0; i < mesh.vertexCount; i++, v += 2)
1284         {
1285             bytesCount += sprintf(txtData + bytesCount, "vt %.3f %.3f\n", mesh.texcoords[v], mesh.texcoords[v + 1]);
1286         }
1287
1288         for (int i = 0, v = 0; i < mesh.vertexCount; i++, v += 3)
1289         {
1290             bytesCount += sprintf(txtData + bytesCount, "vn %.3f %.3f %.3f\n", mesh.normals[v], mesh.normals[v + 1], mesh.normals[v + 2]);
1291         }
1292
1293         for (int i = 0; i < mesh.triangleCount; i += 3)
1294         {
1295             bytesCount += sprintf(txtData + bytesCount, "f %i/%i/%i %i/%i/%i %i/%i/%i\n", i, i, i, i + 1, i + 1, i + 1, i + 2, i + 2, i + 2);
1296         }
1297
1298         bytesCount += sprintf(txtData + bytesCount, "\n");
1299
1300         // NOTE: Text data length exported is determined by '\0' (NULL) character
1301         success = SaveFileText(fileName, txtData);
1302
1303         RL_FREE(txtData);
1304     }
1305     else if (IsFileExtension(fileName, ".raw"))
1306     {
1307         // TODO: Support additional file formats to export mesh vertex data
1308     }
1309
1310     return success;
1311 }
1312
1313
1314 // Load materials from model file
1315 Material *LoadMaterials(const char *fileName, int *materialCount)
1316 {
1317     Material *materials = NULL;
1318     unsigned int count = 0;
1319
1320     // TODO: Support IQM and GLTF for materials parsing
1321
1322 #if defined(SUPPORT_FILEFORMAT_MTL)
1323     if (IsFileExtension(fileName, ".mtl"))
1324     {
1325         tinyobj_material_t *mats = NULL;
1326
1327         int result = tinyobj_parse_mtl_file(&mats, &count, fileName);
1328         if (result != TINYOBJ_SUCCESS) TRACELOG(LOG_WARNING, "MATERIAL: [%s] Failed to parse materials file", fileName);
1329
1330         // TODO: Process materials to return
1331
1332         tinyobj_materials_free(mats, count);
1333     }
1334 #else
1335     TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to load material file", fileName);
1336 #endif
1337
1338     // Set materials shader to default (DIFFUSE, SPECULAR, NORMAL)
1339     if (materials != NULL)
1340     {
1341         for (unsigned int i = 0; i < count; i++) materials[i].shader = rlGetShaderDefault();
1342     }
1343
1344     *materialCount = count;
1345     return materials;
1346 }
1347
1348 // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
1349 Material LoadMaterialDefault(void)
1350 {
1351     Material material = { 0 };
1352     material.maps = (MaterialMap *)RL_CALLOC(MAX_MATERIAL_MAPS, sizeof(MaterialMap));
1353
1354     material.shader = rlGetShaderDefault();
1355     material.maps[MATERIAL_MAP_DIFFUSE].texture = rlGetTextureDefault();   // White texture (1x1 pixel)
1356     //material.maps[MATERIAL_MAP_NORMAL].texture;         // NOTE: By default, not set
1357     //material.maps[MATERIAL_MAP_SPECULAR].texture;       // NOTE: By default, not set
1358
1359     material.maps[MATERIAL_MAP_DIFFUSE].color = WHITE;    // Diffuse color
1360     material.maps[MATERIAL_MAP_SPECULAR].color = WHITE;   // Specular color
1361
1362     return material;
1363 }
1364
1365 // Unload material from memory
1366 void UnloadMaterial(Material material)
1367 {
1368     // Unload material shader (avoid unloading default shader, managed by raylib)
1369     if (material.shader.id != rlGetShaderDefault().id) UnloadShader(material.shader);
1370
1371     // Unload loaded texture maps (avoid unloading default texture, managed by raylib)
1372     for (int i = 0; i < MAX_MATERIAL_MAPS; i++)
1373     {
1374         if (material.maps[i].texture.id != rlGetTextureDefault().id) rlUnloadTexture(material.maps[i].texture.id);
1375     }
1376
1377     RL_FREE(material.maps);
1378 }
1379
1380 // Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...)
1381 // NOTE: Previous texture should be manually unloaded
1382 void SetMaterialTexture(Material *material, int mapType, Texture2D texture)
1383 {
1384     material->maps[mapType].texture = texture;
1385 }
1386
1387 // Set the material for a mesh
1388 void SetModelMeshMaterial(Model *model, int meshId, int materialId)
1389 {
1390     if (meshId >= model->meshCount) TRACELOG(LOG_WARNING, "MESH: Id greater than mesh count");
1391     else if (materialId >= model->materialCount) TRACELOG(LOG_WARNING, "MATERIAL: Id greater than material count");
1392     else  model->meshMaterial[meshId] = materialId;
1393 }
1394
1395 // Load model animations from file
1396 ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount)
1397 {
1398     ModelAnimation *animations = NULL;
1399
1400 #if defined(SUPPORT_FILEFORMAT_IQM)
1401     if (IsFileExtension(fileName, ".iqm")) animations = LoadIQMModelAnimations(fileName, animCount);
1402 #endif
1403 #if defined(SUPPORT_FILEFORMAT_GLTF)
1404     if (IsFileExtension(fileName, ".gltf;.glb")) animations = LoadGLTFModelAnimations(fileName, animCount);
1405 #endif
1406
1407     return animations;
1408 }
1409
1410 // Update model animated vertex data (positions and normals) for a given frame
1411 // NOTE: Updated data is uploaded to GPU
1412 void UpdateModelAnimation(Model model, ModelAnimation anim, int frame)
1413 {
1414     if ((anim.frameCount > 0) && (anim.bones != NULL) && (anim.framePoses != NULL))
1415     {
1416         if (frame >= anim.frameCount) frame = frame%anim.frameCount;
1417
1418         for (int m = 0; m < model.meshCount; m++)
1419         {
1420             Vector3 animVertex = { 0 };
1421             Vector3 animNormal = { 0 };
1422
1423             Vector3 inTranslation = { 0 };
1424             Quaternion inRotation = { 0 };
1425             //Vector3 inScale = { 0 };      // Not used...
1426
1427             Vector3 outTranslation = { 0 };
1428             Quaternion outRotation = { 0 };
1429             Vector3 outScale = { 0 };
1430
1431             int vCounter = 0;
1432             int boneCounter = 0;
1433             int boneId = 0;
1434             float boneWeight = 0.0;
1435
1436             for (int i = 0; i < model.meshes[m].vertexCount; i++)
1437             {
1438                 model.meshes[m].animVertices[vCounter]     = 0;
1439                 model.meshes[m].animVertices[vCounter + 1] = 0;
1440                 model.meshes[m].animVertices[vCounter + 2] = 0;
1441
1442                 model.meshes[m].animNormals[vCounter]     = 0;
1443                 model.meshes[m].animNormals[vCounter + 1] = 0;
1444                 model.meshes[m].animNormals[vCounter + 2] = 0;
1445
1446                 for (int j = 0; j < 4; j++)
1447                 {
1448                     boneId = model.meshes[m].boneIds[boneCounter];
1449                     boneWeight = model.meshes[m].boneWeights[boneCounter];
1450                     inTranslation = model.bindPose[boneId].translation;
1451                     inRotation = model.bindPose[boneId].rotation;
1452                     //inScale = model.bindPose[boneId].scale;
1453                     outTranslation = anim.framePoses[frame][boneId].translation;
1454                     outRotation = anim.framePoses[frame][boneId].rotation;
1455                     outScale = anim.framePoses[frame][boneId].scale;
1456
1457                     // Vertices processing
1458                     // NOTE: We use meshes.vertices (default vertex position) to calculate meshes.animVertices (animated vertex position)
1459                     animVertex = (Vector3){ model.meshes[m].vertices[vCounter], model.meshes[m].vertices[vCounter + 1], model.meshes[m].vertices[vCounter + 2] };
1460                     animVertex = Vector3Multiply(animVertex, outScale);
1461                     animVertex = Vector3Subtract(animVertex, inTranslation);
1462                     animVertex = Vector3RotateByQuaternion(animVertex, QuaternionMultiply(outRotation, QuaternionInvert(inRotation)));
1463                     animVertex = Vector3Add(animVertex, outTranslation);
1464                     model.meshes[m].animVertices[vCounter]     += animVertex.x * boneWeight;
1465                     model.meshes[m].animVertices[vCounter + 1] += animVertex.y * boneWeight;
1466                     model.meshes[m].animVertices[vCounter + 2] += animVertex.z * boneWeight;
1467
1468                     // Normals processing
1469                     // NOTE: We use meshes.baseNormals (default normal) to calculate meshes.normals (animated normals)
1470                     if (model.meshes[m].normals != NULL)
1471                     {
1472                         animNormal = (Vector3){ model.meshes[m].normals[vCounter], model.meshes[m].normals[vCounter + 1], model.meshes[m].normals[vCounter + 2] };
1473                         animNormal = Vector3RotateByQuaternion(animNormal, QuaternionMultiply(outRotation, QuaternionInvert(inRotation)));
1474                         model.meshes[m].animNormals[vCounter]     += animNormal.x * boneWeight;
1475                         model.meshes[m].animNormals[vCounter + 1] += animNormal.y * boneWeight;
1476                         model.meshes[m].animNormals[vCounter + 2] += animNormal.z * boneWeight;
1477                     }
1478                     boneCounter += 1;
1479                 }
1480                 vCounter += 3;
1481             }
1482
1483             // Upload new vertex data to GPU for model drawing
1484             rlUpdateVertexBuffer(model.meshes[m].vboId[0], model.meshes[m].animVertices, model.meshes[m].vertexCount*3*sizeof(float), 0);    // Update vertex position
1485             rlUpdateVertexBuffer(model.meshes[m].vboId[2], model.meshes[m].animNormals, model.meshes[m].vertexCount*3*sizeof(float), 0);     // Update vertex normals
1486         }
1487     }
1488 }
1489
1490 // Unload animation array data
1491 void UnloadModelAnimations(ModelAnimation* animations, unsigned int count)
1492 {
1493     for (unsigned int i = 0; i < count; i++) UnloadModelAnimation(animations[i]);
1494     RL_FREE(animations);
1495 }
1496
1497 // Unload animation data
1498 void UnloadModelAnimation(ModelAnimation anim)
1499 {
1500     for (int i = 0; i < anim.frameCount; i++) RL_FREE(anim.framePoses[i]);
1501
1502     RL_FREE(anim.bones);
1503     RL_FREE(anim.framePoses);
1504 }
1505
1506 // Check model animation skeleton match
1507 // NOTE: Only number of bones and parent connections are checked
1508 bool IsModelAnimationValid(Model model, ModelAnimation anim)
1509 {
1510     int result = true;
1511
1512     if (model.boneCount != anim.boneCount) result = false;
1513     else
1514     {
1515         for (int i = 0; i < model.boneCount; i++)
1516         {
1517             if (model.bones[i].parent != anim.bones[i].parent) { result = false; break; }
1518         }
1519     }
1520
1521     return result;
1522 }
1523
1524 #if defined(SUPPORT_MESH_GENERATION)
1525 // Generate polygonal mesh
1526 Mesh GenMeshPoly(int sides, float radius)
1527 {
1528     Mesh mesh = { 0 };
1529
1530     if (sides < 3) return mesh;
1531
1532     int vertexCount = sides*3;
1533
1534     // Vertices definition
1535     Vector3 *vertices = (Vector3 *)RL_MALLOC(vertexCount*sizeof(Vector3));
1536
1537     float d = 0.0f, dStep = 360.0f/sides;
1538     for (int v = 0; v < vertexCount; v += 3)
1539     {
1540         vertices[v] = (Vector3){ 0.0f, 0.0f, 0.0f };
1541         vertices[v + 1] = (Vector3){ sinf(DEG2RAD*d)*radius, 0.0f, cosf(DEG2RAD*d)*radius };
1542         vertices[v + 2] = (Vector3){sinf(DEG2RAD*(d+dStep))*radius, 0.0f, cosf(DEG2RAD*(d+dStep))*radius };
1543         d += dStep;
1544     }
1545
1546     // Normals definition
1547     Vector3 *normals = (Vector3 *)RL_MALLOC(vertexCount*sizeof(Vector3));
1548     for (int n = 0; n < vertexCount; n++) normals[n] = (Vector3){ 0.0f, 1.0f, 0.0f };   // Vector3.up;
1549
1550     // TexCoords definition
1551     Vector2 *texcoords = (Vector2 *)RL_MALLOC(vertexCount*sizeof(Vector2));
1552     for (int n = 0; n < vertexCount; n++) texcoords[n] = (Vector2){ 0.0f, 0.0f };
1553
1554     mesh.vertexCount = vertexCount;
1555     mesh.triangleCount = sides;
1556     mesh.vertices = (float *)RL_MALLOC(mesh.vertexCount*3*sizeof(float));
1557     mesh.texcoords = (float *)RL_MALLOC(mesh.vertexCount*2*sizeof(float));
1558     mesh.normals = (float *)RL_MALLOC(mesh.vertexCount*3*sizeof(float));
1559
1560     // Mesh vertices position array
1561     for (int i = 0; i < mesh.vertexCount; i++)
1562     {
1563         mesh.vertices[3*i] = vertices[i].x;
1564         mesh.vertices[3*i + 1] = vertices[i].y;
1565         mesh.vertices[3*i + 2] = vertices[i].z;
1566     }
1567
1568     // Mesh texcoords array
1569     for (int i = 0; i < mesh.vertexCount; i++)
1570     {
1571         mesh.texcoords[2*i] = texcoords[i].x;
1572         mesh.texcoords[2*i + 1] = texcoords[i].y;
1573     }
1574
1575     // Mesh normals array
1576     for (int i = 0; i < mesh.vertexCount; i++)
1577     {
1578         mesh.normals[3*i] = normals[i].x;
1579         mesh.normals[3*i + 1] = normals[i].y;
1580         mesh.normals[3*i + 2] = normals[i].z;
1581     }
1582
1583     RL_FREE(vertices);
1584     RL_FREE(normals);
1585     RL_FREE(texcoords);
1586
1587     // Upload vertex data to GPU (static mesh)
1588     // NOTE: mesh.vboId array is allocated inside UploadMesh()
1589     UploadMesh(&mesh, false);
1590
1591     return mesh;
1592 }
1593
1594 // Generate plane mesh (with subdivisions)
1595 Mesh GenMeshPlane(float width, float length, int resX, int resZ)
1596 {
1597     Mesh mesh = { 0 };
1598
1599 #define CUSTOM_MESH_GEN_PLANE
1600 #if defined(CUSTOM_MESH_GEN_PLANE)
1601     resX++;
1602     resZ++;
1603
1604     // Vertices definition
1605     int vertexCount = resX*resZ; // vertices get reused for the faces
1606
1607     Vector3 *vertices = (Vector3 *)RL_MALLOC(vertexCount*sizeof(Vector3));
1608     for (int z = 0; z < resZ; z++)
1609     {
1610         // [-length/2, length/2]
1611         float zPos = ((float)z/(resZ - 1) - 0.5f)*length;
1612         for (int x = 0; x < resX; x++)
1613         {
1614             // [-width/2, width/2]
1615             float xPos = ((float)x/(resX - 1) - 0.5f)*width;
1616             vertices[x + z*resX] = (Vector3){ xPos, 0.0f, zPos };
1617         }
1618     }
1619
1620     // Normals definition
1621     Vector3 *normals = (Vector3 *)RL_MALLOC(vertexCount*sizeof(Vector3));
1622     for (int n = 0; n < vertexCount; n++) normals[n] = (Vector3){ 0.0f, 1.0f, 0.0f };   // Vector3.up;
1623
1624     // TexCoords definition
1625     Vector2 *texcoords = (Vector2 *)RL_MALLOC(vertexCount*sizeof(Vector2));
1626     for (int v = 0; v < resZ; v++)
1627     {
1628         for (int u = 0; u < resX; u++)
1629         {
1630             texcoords[u + v*resX] = (Vector2){ (float)u/(resX - 1), (float)v/(resZ - 1) };
1631         }
1632     }
1633
1634     // Triangles definition (indices)
1635     int numFaces = (resX - 1)*(resZ - 1);
1636     int *triangles = (int *)RL_MALLOC(numFaces*6*sizeof(int));
1637     int t = 0;
1638     for (int face = 0; face < numFaces; face++)
1639     {
1640         // Retrieve lower left corner from face ind
1641         int i = face % (resX - 1) + (face/(resZ - 1)*resX);
1642
1643         triangles[t++] = i + resX;
1644         triangles[t++] = i + 1;
1645         triangles[t++] = i;
1646
1647         triangles[t++] = i + resX;
1648         triangles[t++] = i + resX + 1;
1649         triangles[t++] = i + 1;
1650     }
1651
1652     mesh.vertexCount = vertexCount;
1653     mesh.triangleCount = numFaces*2;
1654     mesh.vertices = (float *)RL_MALLOC(mesh.vertexCount*3*sizeof(float));
1655     mesh.texcoords = (float *)RL_MALLOC(mesh.vertexCount*2*sizeof(float));
1656     mesh.normals = (float *)RL_MALLOC(mesh.vertexCount*3*sizeof(float));
1657     mesh.indices = (unsigned short *)RL_MALLOC(mesh.triangleCount*3*sizeof(unsigned short));
1658
1659     // Mesh vertices position array
1660     for (int i = 0; i < mesh.vertexCount; i++)
1661     {
1662         mesh.vertices[3*i] = vertices[i].x;
1663         mesh.vertices[3*i + 1] = vertices[i].y;
1664         mesh.vertices[3*i + 2] = vertices[i].z;
1665     }
1666
1667     // Mesh texcoords array
1668     for (int i = 0; i < mesh.vertexCount; i++)
1669     {
1670         mesh.texcoords[2*i] = texcoords[i].x;
1671         mesh.texcoords[2*i + 1] = texcoords[i].y;
1672     }
1673
1674     // Mesh normals array
1675     for (int i = 0; i < mesh.vertexCount; i++)
1676     {
1677         mesh.normals[3*i] = normals[i].x;
1678         mesh.normals[3*i + 1] = normals[i].y;
1679         mesh.normals[3*i + 2] = normals[i].z;
1680     }
1681
1682     // Mesh indices array initialization
1683     for (int i = 0; i < mesh.triangleCount*3; i++) mesh.indices[i] = triangles[i];
1684
1685     RL_FREE(vertices);
1686     RL_FREE(normals);
1687     RL_FREE(texcoords);
1688     RL_FREE(triangles);
1689
1690 #else       // Use par_shapes library to generate plane mesh
1691
1692     par_shapes_mesh *plane = par_shapes_create_plane(resX, resZ);   // No normals/texcoords generated!!!
1693     par_shapes_scale(plane, width, length, 1.0f);
1694     par_shapes_rotate(plane, -PI/2.0f, (float[]){ 1, 0, 0 });
1695     par_shapes_translate(plane, -width/2, 0.0f, length/2);
1696
1697     mesh.vertices = (float *)RL_MALLOC(plane->ntriangles*3*3*sizeof(float));
1698     mesh.texcoords = (float *)RL_MALLOC(plane->ntriangles*3*2*sizeof(float));
1699     mesh.normals = (float *)RL_MALLOC(plane->ntriangles*3*3*sizeof(float));
1700
1701     mesh.vertexCount = plane->ntriangles*3;
1702     mesh.triangleCount = plane->ntriangles;
1703
1704     for (int k = 0; k < mesh.vertexCount; k++)
1705     {
1706         mesh.vertices[k*3] = plane->points[plane->triangles[k]*3];
1707         mesh.vertices[k*3 + 1] = plane->points[plane->triangles[k]*3 + 1];
1708         mesh.vertices[k*3 + 2] = plane->points[plane->triangles[k]*3 + 2];
1709
1710         mesh.normals[k*3] = plane->normals[plane->triangles[k]*3];
1711         mesh.normals[k*3 + 1] = plane->normals[plane->triangles[k]*3 + 1];
1712         mesh.normals[k*3 + 2] = plane->normals[plane->triangles[k]*3 + 2];
1713
1714         mesh.texcoords[k*2] = plane->tcoords[plane->triangles[k]*2];
1715         mesh.texcoords[k*2 + 1] = plane->tcoords[plane->triangles[k]*2 + 1];
1716     }
1717
1718     par_shapes_free_mesh(plane);
1719 #endif
1720
1721     // Upload vertex data to GPU (static mesh)
1722     UploadMesh(&mesh, false);
1723
1724     return mesh;
1725 }
1726
1727 // Generated cuboid mesh
1728 Mesh GenMeshCube(float width, float height, float length)
1729 {
1730     Mesh mesh = { 0 };
1731
1732 #define CUSTOM_MESH_GEN_CUBE
1733 #if defined(CUSTOM_MESH_GEN_CUBE)
1734     float vertices[] = {
1735         -width/2, -height/2, length/2,
1736         width/2, -height/2, length/2,
1737         width/2, height/2, length/2,
1738         -width/2, height/2, length/2,
1739         -width/2, -height/2, -length/2,
1740         -width/2, height/2, -length/2,
1741         width/2, height/2, -length/2,
1742         width/2, -height/2, -length/2,
1743         -width/2, height/2, -length/2,
1744         -width/2, height/2, length/2,
1745         width/2, height/2, length/2,
1746         width/2, height/2, -length/2,
1747         -width/2, -height/2, -length/2,
1748         width/2, -height/2, -length/2,
1749         width/2, -height/2, length/2,
1750         -width/2, -height/2, length/2,
1751         width/2, -height/2, -length/2,
1752         width/2, height/2, -length/2,
1753         width/2, height/2, length/2,
1754         width/2, -height/2, length/2,
1755         -width/2, -height/2, -length/2,
1756         -width/2, -height/2, length/2,
1757         -width/2, height/2, length/2,
1758         -width/2, height/2, -length/2
1759     };
1760
1761     float texcoords[] = {
1762         0.0f, 0.0f,
1763         1.0f, 0.0f,
1764         1.0f, 1.0f,
1765         0.0f, 1.0f,
1766         1.0f, 0.0f,
1767         1.0f, 1.0f,
1768         0.0f, 1.0f,
1769         0.0f, 0.0f,
1770         0.0f, 1.0f,
1771         0.0f, 0.0f,
1772         1.0f, 0.0f,
1773         1.0f, 1.0f,
1774         1.0f, 1.0f,
1775         0.0f, 1.0f,
1776         0.0f, 0.0f,
1777         1.0f, 0.0f,
1778         1.0f, 0.0f,
1779         1.0f, 1.0f,
1780         0.0f, 1.0f,
1781         0.0f, 0.0f,
1782         0.0f, 0.0f,
1783         1.0f, 0.0f,
1784         1.0f, 1.0f,
1785         0.0f, 1.0f
1786     };
1787
1788     float normals[] = {
1789         0.0f, 0.0f, 1.0f,
1790         0.0f, 0.0f, 1.0f,
1791         0.0f, 0.0f, 1.0f,
1792         0.0f, 0.0f, 1.0f,
1793         0.0f, 0.0f,-1.0f,
1794         0.0f, 0.0f,-1.0f,
1795         0.0f, 0.0f,-1.0f,
1796         0.0f, 0.0f,-1.0f,
1797         0.0f, 1.0f, 0.0f,
1798         0.0f, 1.0f, 0.0f,
1799         0.0f, 1.0f, 0.0f,
1800         0.0f, 1.0f, 0.0f,
1801         0.0f,-1.0f, 0.0f,
1802         0.0f,-1.0f, 0.0f,
1803         0.0f,-1.0f, 0.0f,
1804         0.0f,-1.0f, 0.0f,
1805         1.0f, 0.0f, 0.0f,
1806         1.0f, 0.0f, 0.0f,
1807         1.0f, 0.0f, 0.0f,
1808         1.0f, 0.0f, 0.0f,
1809         -1.0f, 0.0f, 0.0f,
1810         -1.0f, 0.0f, 0.0f,
1811         -1.0f, 0.0f, 0.0f,
1812         -1.0f, 0.0f, 0.0f
1813     };
1814
1815     mesh.vertices = (float *)RL_MALLOC(24*3*sizeof(float));
1816     memcpy(mesh.vertices, vertices, 24*3*sizeof(float));
1817
1818     mesh.texcoords = (float *)RL_MALLOC(24*2*sizeof(float));
1819     memcpy(mesh.texcoords, texcoords, 24*2*sizeof(float));
1820
1821     mesh.normals = (float *)RL_MALLOC(24*3*sizeof(float));
1822     memcpy(mesh.normals, normals, 24*3*sizeof(float));
1823
1824     mesh.indices = (unsigned short *)RL_MALLOC(36*sizeof(unsigned short));
1825
1826     int k = 0;
1827
1828     // Indices can be initialized right now
1829     for (int i = 0; i < 36; i+=6)
1830     {
1831         mesh.indices[i] = 4*k;
1832         mesh.indices[i+1] = 4*k+1;
1833         mesh.indices[i+2] = 4*k+2;
1834         mesh.indices[i+3] = 4*k;
1835         mesh.indices[i+4] = 4*k+2;
1836         mesh.indices[i+5] = 4*k+3;
1837
1838         k++;
1839     }
1840
1841     mesh.vertexCount = 24;
1842     mesh.triangleCount = 12;
1843
1844 #else               // Use par_shapes library to generate cube mesh
1845 /*
1846 // Platonic solids:
1847 par_shapes_mesh* par_shapes_create_tetrahedron();       // 4 sides polyhedron (pyramid)
1848 par_shapes_mesh* par_shapes_create_cube();              // 6 sides polyhedron (cube)
1849 par_shapes_mesh* par_shapes_create_octahedron();        // 8 sides polyhedron (dyamond)
1850 par_shapes_mesh* par_shapes_create_dodecahedron();      // 12 sides polyhedron
1851 par_shapes_mesh* par_shapes_create_icosahedron();       // 20 sides polyhedron
1852 */
1853     // Platonic solid generation: cube (6 sides)
1854     // NOTE: No normals/texcoords generated by default
1855     par_shapes_mesh *cube = par_shapes_create_cube();
1856     cube->tcoords = PAR_MALLOC(float, 2*cube->npoints);
1857     for (int i = 0; i < 2*cube->npoints; i++) cube->tcoords[i] = 0.0f;
1858     par_shapes_scale(cube, width, height, length);
1859     par_shapes_translate(cube, -width/2, 0.0f, -length/2);
1860     par_shapes_compute_normals(cube);
1861
1862     mesh.vertices = (float *)RL_MALLOC(cube->ntriangles*3*3*sizeof(float));
1863     mesh.texcoords = (float *)RL_MALLOC(cube->ntriangles*3*2*sizeof(float));
1864     mesh.normals = (float *)RL_MALLOC(cube->ntriangles*3*3*sizeof(float));
1865
1866     mesh.vertexCount = cube->ntriangles*3;
1867     mesh.triangleCount = cube->ntriangles;
1868
1869     for (int k = 0; k < mesh.vertexCount; k++)
1870     {
1871         mesh.vertices[k*3] = cube->points[cube->triangles[k]*3];
1872         mesh.vertices[k*3 + 1] = cube->points[cube->triangles[k]*3 + 1];
1873         mesh.vertices[k*3 + 2] = cube->points[cube->triangles[k]*3 + 2];
1874
1875         mesh.normals[k*3] = cube->normals[cube->triangles[k]*3];
1876         mesh.normals[k*3 + 1] = cube->normals[cube->triangles[k]*3 + 1];
1877         mesh.normals[k*3 + 2] = cube->normals[cube->triangles[k]*3 + 2];
1878
1879         mesh.texcoords[k*2] = cube->tcoords[cube->triangles[k]*2];
1880         mesh.texcoords[k*2 + 1] = cube->tcoords[cube->triangles[k]*2 + 1];
1881     }
1882
1883     par_shapes_free_mesh(cube);
1884 #endif
1885
1886     // Upload vertex data to GPU (static mesh)
1887     UploadMesh(&mesh, false);
1888
1889     return mesh;
1890 }
1891
1892 // Generate sphere mesh (standard sphere)
1893 Mesh GenMeshSphere(float radius, int rings, int slices)
1894 {
1895     Mesh mesh = { 0 };
1896
1897     if ((rings >= 3) && (slices >= 3))
1898     {
1899         par_shapes_mesh *sphere = par_shapes_create_parametric_sphere(slices, rings);
1900         par_shapes_scale(sphere, radius, radius, radius);
1901         // NOTE: Soft normals are computed internally
1902
1903         mesh.vertices = (float *)RL_MALLOC(sphere->ntriangles*3*3*sizeof(float));
1904         mesh.texcoords = (float *)RL_MALLOC(sphere->ntriangles*3*2*sizeof(float));
1905         mesh.normals = (float *)RL_MALLOC(sphere->ntriangles*3*3*sizeof(float));
1906
1907         mesh.vertexCount = sphere->ntriangles*3;
1908         mesh.triangleCount = sphere->ntriangles;
1909
1910         for (int k = 0; k < mesh.vertexCount; k++)
1911         {
1912             mesh.vertices[k*3] = sphere->points[sphere->triangles[k]*3];
1913             mesh.vertices[k*3 + 1] = sphere->points[sphere->triangles[k]*3 + 1];
1914             mesh.vertices[k*3 + 2] = sphere->points[sphere->triangles[k]*3 + 2];
1915
1916             mesh.normals[k*3] = sphere->normals[sphere->triangles[k]*3];
1917             mesh.normals[k*3 + 1] = sphere->normals[sphere->triangles[k]*3 + 1];
1918             mesh.normals[k*3 + 2] = sphere->normals[sphere->triangles[k]*3 + 2];
1919
1920             mesh.texcoords[k*2] = sphere->tcoords[sphere->triangles[k]*2];
1921             mesh.texcoords[k*2 + 1] = sphere->tcoords[sphere->triangles[k]*2 + 1];
1922         }
1923
1924         par_shapes_free_mesh(sphere);
1925
1926         // Upload vertex data to GPU (static mesh)
1927         UploadMesh(&mesh, false);
1928     }
1929     else TRACELOG(LOG_WARNING, "MESH: Failed to generate mesh: sphere");
1930
1931     return mesh;
1932 }
1933
1934 // Generate hemi-sphere mesh (half sphere, no bottom cap)
1935 Mesh GenMeshHemiSphere(float radius, int rings, int slices)
1936 {
1937     Mesh mesh = { 0 };
1938
1939     if ((rings >= 3) && (slices >= 3))
1940     {
1941         if (radius < 0.0f) radius = 0.0f;
1942
1943         par_shapes_mesh *sphere = par_shapes_create_hemisphere(slices, rings);
1944         par_shapes_scale(sphere, radius, radius, radius);
1945         // NOTE: Soft normals are computed internally
1946
1947         mesh.vertices = (float *)RL_MALLOC(sphere->ntriangles*3*3*sizeof(float));
1948         mesh.texcoords = (float *)RL_MALLOC(sphere->ntriangles*3*2*sizeof(float));
1949         mesh.normals = (float *)RL_MALLOC(sphere->ntriangles*3*3*sizeof(float));
1950
1951         mesh.vertexCount = sphere->ntriangles*3;
1952         mesh.triangleCount = sphere->ntriangles;
1953
1954         for (int k = 0; k < mesh.vertexCount; k++)
1955         {
1956             mesh.vertices[k*3] = sphere->points[sphere->triangles[k]*3];
1957             mesh.vertices[k*3 + 1] = sphere->points[sphere->triangles[k]*3 + 1];
1958             mesh.vertices[k*3 + 2] = sphere->points[sphere->triangles[k]*3 + 2];
1959
1960             mesh.normals[k*3] = sphere->normals[sphere->triangles[k]*3];
1961             mesh.normals[k*3 + 1] = sphere->normals[sphere->triangles[k]*3 + 1];
1962             mesh.normals[k*3 + 2] = sphere->normals[sphere->triangles[k]*3 + 2];
1963
1964             mesh.texcoords[k*2] = sphere->tcoords[sphere->triangles[k]*2];
1965             mesh.texcoords[k*2 + 1] = sphere->tcoords[sphere->triangles[k]*2 + 1];
1966         }
1967
1968         par_shapes_free_mesh(sphere);
1969
1970         // Upload vertex data to GPU (static mesh)
1971         UploadMesh(&mesh, false);
1972     }
1973     else TRACELOG(LOG_WARNING, "MESH: Failed to generate mesh: hemisphere");
1974
1975     return mesh;
1976 }
1977
1978 // Generate cylinder mesh
1979 Mesh GenMeshCylinder(float radius, float height, int slices)
1980 {
1981     Mesh mesh = { 0 };
1982
1983     if (slices >= 3)
1984     {
1985         // Instance a cylinder that sits on the Z=0 plane using the given tessellation
1986         // levels across the UV domain.  Think of "slices" like a number of pizza
1987         // slices, and "stacks" like a number of stacked rings.
1988         // Height and radius are both 1.0, but they can easily be changed with par_shapes_scale
1989         par_shapes_mesh *cylinder = par_shapes_create_cylinder(slices, 8);
1990         par_shapes_scale(cylinder, radius, radius, height);
1991         par_shapes_rotate(cylinder, -PI/2.0f, (float[]){ 1, 0, 0 });
1992         par_shapes_rotate(cylinder, PI/2.0f, (float[]){ 0, 1, 0 });
1993
1994         // Generate an orientable disk shape (top cap)
1995         par_shapes_mesh *capTop = par_shapes_create_disk(radius, slices, (float[]){ 0, 0, 0 }, (float[]){ 0, 0, 1 });
1996         capTop->tcoords = PAR_MALLOC(float, 2*capTop->npoints);
1997         for (int i = 0; i < 2*capTop->npoints; i++) capTop->tcoords[i] = 0.0f;
1998         par_shapes_rotate(capTop, -PI/2.0f, (float[]){ 1, 0, 0 });
1999         par_shapes_translate(capTop, 0, height, 0);
2000
2001         // Generate an orientable disk shape (bottom cap)
2002         par_shapes_mesh *capBottom = par_shapes_create_disk(radius, slices, (float[]){ 0, 0, 0 }, (float[]){ 0, 0, -1 });
2003         capBottom->tcoords = PAR_MALLOC(float, 2*capBottom->npoints);
2004         for (int i = 0; i < 2*capBottom->npoints; i++) capBottom->tcoords[i] = 0.95f;
2005         par_shapes_rotate(capBottom, PI/2.0f, (float[]){ 1, 0, 0 });
2006
2007         par_shapes_merge_and_free(cylinder, capTop);
2008         par_shapes_merge_and_free(cylinder, capBottom);
2009
2010         mesh.vertices = (float *)RL_MALLOC(cylinder->ntriangles*3*3*sizeof(float));
2011         mesh.texcoords = (float *)RL_MALLOC(cylinder->ntriangles*3*2*sizeof(float));
2012         mesh.normals = (float *)RL_MALLOC(cylinder->ntriangles*3*3*sizeof(float));
2013
2014         mesh.vertexCount = cylinder->ntriangles*3;
2015         mesh.triangleCount = cylinder->ntriangles;
2016
2017         for (int k = 0; k < mesh.vertexCount; k++)
2018         {
2019             mesh.vertices[k*3] = cylinder->points[cylinder->triangles[k]*3];
2020             mesh.vertices[k*3 + 1] = cylinder->points[cylinder->triangles[k]*3 + 1];
2021             mesh.vertices[k*3 + 2] = cylinder->points[cylinder->triangles[k]*3 + 2];
2022
2023             mesh.normals[k*3] = cylinder->normals[cylinder->triangles[k]*3];
2024             mesh.normals[k*3 + 1] = cylinder->normals[cylinder->triangles[k]*3 + 1];
2025             mesh.normals[k*3 + 2] = cylinder->normals[cylinder->triangles[k]*3 + 2];
2026
2027             mesh.texcoords[k*2] = cylinder->tcoords[cylinder->triangles[k]*2];
2028             mesh.texcoords[k*2 + 1] = cylinder->tcoords[cylinder->triangles[k]*2 + 1];
2029         }
2030
2031         par_shapes_free_mesh(cylinder);
2032
2033         // Upload vertex data to GPU (static mesh)
2034         UploadMesh(&mesh, false);
2035     }
2036     else TRACELOG(LOG_WARNING, "MESH: Failed to generate mesh: cylinder");
2037
2038     return mesh;
2039 }
2040
2041 // Generate torus mesh
2042 Mesh GenMeshTorus(float radius, float size, int radSeg, int sides)
2043 {
2044     Mesh mesh = { 0 };
2045
2046     if ((sides >= 3) && (radSeg >= 3))
2047     {
2048         if (radius > 1.0f) radius = 1.0f;
2049         else if (radius < 0.1f) radius = 0.1f;
2050
2051         // Create a donut that sits on the Z=0 plane with the specified inner radius
2052         // The outer radius can be controlled with par_shapes_scale
2053         par_shapes_mesh *torus = par_shapes_create_torus(radSeg, sides, radius);
2054         par_shapes_scale(torus, size/2, size/2, size/2);
2055
2056         mesh.vertices = (float *)RL_MALLOC(torus->ntriangles*3*3*sizeof(float));
2057         mesh.texcoords = (float *)RL_MALLOC(torus->ntriangles*3*2*sizeof(float));
2058         mesh.normals = (float *)RL_MALLOC(torus->ntriangles*3*3*sizeof(float));
2059
2060         mesh.vertexCount = torus->ntriangles*3;
2061         mesh.triangleCount = torus->ntriangles;
2062
2063         for (int k = 0; k < mesh.vertexCount; k++)
2064         {
2065             mesh.vertices[k*3] = torus->points[torus->triangles[k]*3];
2066             mesh.vertices[k*3 + 1] = torus->points[torus->triangles[k]*3 + 1];
2067             mesh.vertices[k*3 + 2] = torus->points[torus->triangles[k]*3 + 2];
2068
2069             mesh.normals[k*3] = torus->normals[torus->triangles[k]*3];
2070             mesh.normals[k*3 + 1] = torus->normals[torus->triangles[k]*3 + 1];
2071             mesh.normals[k*3 + 2] = torus->normals[torus->triangles[k]*3 + 2];
2072
2073             mesh.texcoords[k*2] = torus->tcoords[torus->triangles[k]*2];
2074             mesh.texcoords[k*2 + 1] = torus->tcoords[torus->triangles[k]*2 + 1];
2075         }
2076
2077         par_shapes_free_mesh(torus);
2078
2079         // Upload vertex data to GPU (static mesh)
2080         UploadMesh(&mesh, false);
2081     }
2082     else TRACELOG(LOG_WARNING, "MESH: Failed to generate mesh: torus");
2083
2084     return mesh;
2085 }
2086
2087 // Generate trefoil knot mesh
2088 Mesh GenMeshKnot(float radius, float size, int radSeg, int sides)
2089 {
2090     Mesh mesh = { 0 };
2091
2092     if ((sides >= 3) && (radSeg >= 3))
2093     {
2094         if (radius > 3.0f) radius = 3.0f;
2095         else if (radius < 0.5f) radius = 0.5f;
2096
2097         par_shapes_mesh *knot = par_shapes_create_trefoil_knot(radSeg, sides, radius);
2098         par_shapes_scale(knot, size, size, size);
2099
2100         mesh.vertices = (float *)RL_MALLOC(knot->ntriangles*3*3*sizeof(float));
2101         mesh.texcoords = (float *)RL_MALLOC(knot->ntriangles*3*2*sizeof(float));
2102         mesh.normals = (float *)RL_MALLOC(knot->ntriangles*3*3*sizeof(float));
2103
2104         mesh.vertexCount = knot->ntriangles*3;
2105         mesh.triangleCount = knot->ntriangles;
2106
2107         for (int k = 0; k < mesh.vertexCount; k++)
2108         {
2109             mesh.vertices[k*3] = knot->points[knot->triangles[k]*3];
2110             mesh.vertices[k*3 + 1] = knot->points[knot->triangles[k]*3 + 1];
2111             mesh.vertices[k*3 + 2] = knot->points[knot->triangles[k]*3 + 2];
2112
2113             mesh.normals[k*3] = knot->normals[knot->triangles[k]*3];
2114             mesh.normals[k*3 + 1] = knot->normals[knot->triangles[k]*3 + 1];
2115             mesh.normals[k*3 + 2] = knot->normals[knot->triangles[k]*3 + 2];
2116
2117             mesh.texcoords[k*2] = knot->tcoords[knot->triangles[k]*2];
2118             mesh.texcoords[k*2 + 1] = knot->tcoords[knot->triangles[k]*2 + 1];
2119         }
2120
2121         par_shapes_free_mesh(knot);
2122
2123         // Upload vertex data to GPU (static mesh)
2124         UploadMesh(&mesh, false);
2125     }
2126     else TRACELOG(LOG_WARNING, "MESH: Failed to generate mesh: knot");
2127
2128     return mesh;
2129 }
2130
2131 // Generate a mesh from heightmap
2132 // NOTE: Vertex data is uploaded to GPU
2133 Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
2134 {
2135     #define GRAY_VALUE(c) ((c.r+c.g+c.b)/3)
2136
2137     Mesh mesh = { 0 };
2138
2139     int mapX = heightmap.width;
2140     int mapZ = heightmap.height;
2141
2142     Color *pixels = LoadImageColors(heightmap);
2143
2144     // NOTE: One vertex per pixel
2145     mesh.triangleCount = (mapX-1)*(mapZ-1)*2;    // One quad every four pixels
2146
2147     mesh.vertexCount = mesh.triangleCount*3;
2148
2149     mesh.vertices = (float *)RL_MALLOC(mesh.vertexCount*3*sizeof(float));
2150     mesh.normals = (float *)RL_MALLOC(mesh.vertexCount*3*sizeof(float));
2151     mesh.texcoords = (float *)RL_MALLOC(mesh.vertexCount*2*sizeof(float));
2152     mesh.colors = NULL;
2153
2154     int vCounter = 0;       // Used to count vertices float by float
2155     int tcCounter = 0;      // Used to count texcoords float by float
2156     int nCounter = 0;       // Used to count normals float by float
2157
2158     int trisCounter = 0;
2159
2160     Vector3 scaleFactor = { size.x/mapX, size.y/255.0f, size.z/mapZ };
2161
2162     Vector3 vA;
2163     Vector3 vB;
2164     Vector3 vC;
2165     Vector3 vN;
2166
2167     for (int z = 0; z < mapZ-1; z++)
2168     {
2169         for (int x = 0; x < mapX-1; x++)
2170         {
2171             // Fill vertices array with data
2172             //----------------------------------------------------------
2173
2174             // one triangle - 3 vertex
2175             mesh.vertices[vCounter] = (float)x*scaleFactor.x;
2176             mesh.vertices[vCounter + 1] = (float)GRAY_VALUE(pixels[x + z*mapX])*scaleFactor.y;
2177             mesh.vertices[vCounter + 2] = (float)z*scaleFactor.z;
2178
2179             mesh.vertices[vCounter + 3] = (float)x*scaleFactor.x;
2180             mesh.vertices[vCounter + 4] = (float)GRAY_VALUE(pixels[x + (z + 1)*mapX])*scaleFactor.y;
2181             mesh.vertices[vCounter + 5] = (float)(z + 1)*scaleFactor.z;
2182
2183             mesh.vertices[vCounter + 6] = (float)(x + 1)*scaleFactor.x;
2184             mesh.vertices[vCounter + 7] = (float)GRAY_VALUE(pixels[(x + 1) + z*mapX])*scaleFactor.y;
2185             mesh.vertices[vCounter + 8] = (float)z*scaleFactor.z;
2186
2187             // another triangle - 3 vertex
2188             mesh.vertices[vCounter + 9] = mesh.vertices[vCounter + 6];
2189             mesh.vertices[vCounter + 10] = mesh.vertices[vCounter + 7];
2190             mesh.vertices[vCounter + 11] = mesh.vertices[vCounter + 8];
2191
2192             mesh.vertices[vCounter + 12] = mesh.vertices[vCounter + 3];
2193             mesh.vertices[vCounter + 13] = mesh.vertices[vCounter + 4];
2194             mesh.vertices[vCounter + 14] = mesh.vertices[vCounter + 5];
2195
2196             mesh.vertices[vCounter + 15] = (float)(x + 1)*scaleFactor.x;
2197             mesh.vertices[vCounter + 16] = (float)GRAY_VALUE(pixels[(x + 1) + (z + 1)*mapX])*scaleFactor.y;
2198             mesh.vertices[vCounter + 17] = (float)(z + 1)*scaleFactor.z;
2199             vCounter += 18;     // 6 vertex, 18 floats
2200
2201             // Fill texcoords array with data
2202             //--------------------------------------------------------------
2203             mesh.texcoords[tcCounter] = (float)x/(mapX - 1);
2204             mesh.texcoords[tcCounter + 1] = (float)z/(mapZ - 1);
2205
2206             mesh.texcoords[tcCounter + 2] = (float)x/(mapX - 1);
2207             mesh.texcoords[tcCounter + 3] = (float)(z + 1)/(mapZ - 1);
2208
2209             mesh.texcoords[tcCounter + 4] = (float)(x + 1)/(mapX - 1);
2210             mesh.texcoords[tcCounter + 5] = (float)z/(mapZ - 1);
2211
2212             mesh.texcoords[tcCounter + 6] = mesh.texcoords[tcCounter + 4];
2213             mesh.texcoords[tcCounter + 7] = mesh.texcoords[tcCounter + 5];
2214
2215             mesh.texcoords[tcCounter + 8] = mesh.texcoords[tcCounter + 2];
2216             mesh.texcoords[tcCounter + 9] = mesh.texcoords[tcCounter + 3];
2217
2218             mesh.texcoords[tcCounter + 10] = (float)(x + 1)/(mapX - 1);
2219             mesh.texcoords[tcCounter + 11] = (float)(z + 1)/(mapZ - 1);
2220             tcCounter += 12;    // 6 texcoords, 12 floats
2221
2222             // Fill normals array with data
2223             //--------------------------------------------------------------
2224             for (int i = 0; i < 18; i += 9)
2225             {
2226                 vA.x = mesh.vertices[nCounter + i];
2227                 vA.y = mesh.vertices[nCounter + i + 1];
2228                 vA.z = mesh.vertices[nCounter + i + 2];
2229
2230                 vB.x = mesh.vertices[nCounter + i + 3];
2231                 vB.y = mesh.vertices[nCounter + i + 4];
2232                 vB.z = mesh.vertices[nCounter + i + 5];
2233
2234                 vC.x = mesh.vertices[nCounter + i + 6];
2235                 vC.y = mesh.vertices[nCounter + i + 7];
2236                 vC.z = mesh.vertices[nCounter + i + 8];
2237
2238                 vN = Vector3Normalize(Vector3CrossProduct(Vector3Subtract(vB, vA), Vector3Subtract(vC, vA)));
2239
2240                 mesh.normals[nCounter + i] = vN.x;
2241                 mesh.normals[nCounter + i + 1] = vN.y;
2242                 mesh.normals[nCounter + i + 2] = vN.z;
2243
2244                 mesh.normals[nCounter + i + 3] = vN.x;
2245                 mesh.normals[nCounter + i + 4] = vN.y;
2246                 mesh.normals[nCounter + i + 5] = vN.z;
2247
2248                 mesh.normals[nCounter + i + 6] = vN.x;
2249                 mesh.normals[nCounter + i + 7] = vN.y;
2250                 mesh.normals[nCounter + i + 8] = vN.z;
2251             }
2252
2253             nCounter += 18;     // 6 vertex, 18 floats
2254             trisCounter += 2;
2255         }
2256     }
2257
2258     UnloadImageColors(pixels);  // Unload pixels color data
2259
2260     // Upload vertex data to GPU (static mesh)
2261     UploadMesh(&mesh, false);
2262
2263     return mesh;
2264 }
2265
2266 // Generate a cubes mesh from pixel data
2267 // NOTE: Vertex data is uploaded to GPU
2268 Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize)
2269 {
2270     #define COLOR_EQUAL(col1, col2) ((col1.r == col2.r)&&(col1.g == col2.g)&&(col1.b == col2.b)&&(col1.a == col2.a))
2271
2272     Mesh mesh = { 0 };
2273
2274     Color *pixels = LoadImageColors(cubicmap);
2275
2276     int mapWidth = cubicmap.width;
2277     int mapHeight = cubicmap.height;
2278
2279     // NOTE: Max possible number of triangles numCubes*(12 triangles by cube)
2280     int maxTriangles = cubicmap.width*cubicmap.height*12;
2281
2282     int vCounter = 0;       // Used to count vertices
2283     int tcCounter = 0;      // Used to count texcoords
2284     int nCounter = 0;       // Used to count normals
2285
2286     float w = cubeSize.x;
2287     float h = cubeSize.z;
2288     float h2 = cubeSize.y;
2289
2290     Vector3 *mapVertices = (Vector3 *)RL_MALLOC(maxTriangles*3*sizeof(Vector3));
2291     Vector2 *mapTexcoords = (Vector2 *)RL_MALLOC(maxTriangles*3*sizeof(Vector2));
2292     Vector3 *mapNormals = (Vector3 *)RL_MALLOC(maxTriangles*3*sizeof(Vector3));
2293
2294     // Define the 6 normals of the cube, we will combine them accordingly later...
2295     Vector3 n1 = { 1.0f, 0.0f, 0.0f };
2296     Vector3 n2 = { -1.0f, 0.0f, 0.0f };
2297     Vector3 n3 = { 0.0f, 1.0f, 0.0f };
2298     Vector3 n4 = { 0.0f, -1.0f, 0.0f };
2299     Vector3 n5 = { 0.0f, 0.0f, -1.0f };
2300     Vector3 n6 = { 0.0f, 0.0f, 1.0f };
2301
2302     // NOTE: We use texture rectangles to define different textures for top-bottom-front-back-right-left (6)
2303     typedef struct RectangleF {
2304         float x;
2305         float y;
2306         float width;
2307         float height;
2308     } RectangleF;
2309
2310     RectangleF rightTexUV = { 0.0f, 0.0f, 0.5f, 0.5f };
2311     RectangleF leftTexUV = { 0.5f, 0.0f, 0.5f, 0.5f };
2312     RectangleF frontTexUV = { 0.0f, 0.0f, 0.5f, 0.5f };
2313     RectangleF backTexUV = { 0.5f, 0.0f, 0.5f, 0.5f };
2314     RectangleF topTexUV = { 0.0f, 0.5f, 0.5f, 0.5f };
2315     RectangleF bottomTexUV = { 0.5f, 0.5f, 0.5f, 0.5f };
2316
2317     for (int z = 0; z < mapHeight; ++z)
2318     {
2319         for (int x = 0; x < mapWidth; ++x)
2320         {
2321             // Define the 8 vertex of the cube, we will combine them accordingly later...
2322             Vector3 v1 = { w*(x - 0.5f), h2, h*(z - 0.5f) };
2323             Vector3 v2 = { w*(x - 0.5f), h2, h*(z + 0.5f) };
2324             Vector3 v3 = { w*(x + 0.5f), h2, h*(z + 0.5f) };
2325             Vector3 v4 = { w*(x + 0.5f), h2, h*(z - 0.5f) };
2326             Vector3 v5 = { w*(x + 0.5f), 0, h*(z - 0.5f) };
2327             Vector3 v6 = { w*(x - 0.5f), 0, h*(z - 0.5f) };
2328             Vector3 v7 = { w*(x - 0.5f), 0, h*(z + 0.5f) };
2329             Vector3 v8 = { w*(x + 0.5f), 0, h*(z + 0.5f) };
2330
2331             // We check pixel color to be WHITE -> draw full cube
2332             if (COLOR_EQUAL(pixels[z*cubicmap.width + x], WHITE))
2333             {
2334                 // Define triangles and checking collateral cubes
2335                 //------------------------------------------------
2336
2337                 // Define top triangles (2 tris, 6 vertex --> v1-v2-v3, v1-v3-v4)
2338                 // WARNING: Not required for a WHITE cubes, created to allow seeing the map from outside
2339                 mapVertices[vCounter] = v1;
2340                 mapVertices[vCounter + 1] = v2;
2341                 mapVertices[vCounter + 2] = v3;
2342                 mapVertices[vCounter + 3] = v1;
2343                 mapVertices[vCounter + 4] = v3;
2344                 mapVertices[vCounter + 5] = v4;
2345                 vCounter += 6;
2346
2347                 mapNormals[nCounter] = n3;
2348                 mapNormals[nCounter + 1] = n3;
2349                 mapNormals[nCounter + 2] = n3;
2350                 mapNormals[nCounter + 3] = n3;
2351                 mapNormals[nCounter + 4] = n3;
2352                 mapNormals[nCounter + 5] = n3;
2353                 nCounter += 6;
2354
2355                 mapTexcoords[tcCounter] = (Vector2){ topTexUV.x, topTexUV.y };
2356                 mapTexcoords[tcCounter + 1] = (Vector2){ topTexUV.x, topTexUV.y + topTexUV.height };
2357                 mapTexcoords[tcCounter + 2] = (Vector2){ topTexUV.x + topTexUV.width, topTexUV.y + topTexUV.height };
2358                 mapTexcoords[tcCounter + 3] = (Vector2){ topTexUV.x, topTexUV.y };
2359                 mapTexcoords[tcCounter + 4] = (Vector2){ topTexUV.x + topTexUV.width, topTexUV.y + topTexUV.height };
2360                 mapTexcoords[tcCounter + 5] = (Vector2){ topTexUV.x + topTexUV.width, topTexUV.y };
2361                 tcCounter += 6;
2362
2363                 // Define bottom triangles (2 tris, 6 vertex --> v6-v8-v7, v6-v5-v8)
2364                 mapVertices[vCounter] = v6;
2365                 mapVertices[vCounter + 1] = v8;
2366                 mapVertices[vCounter + 2] = v7;
2367                 mapVertices[vCounter + 3] = v6;
2368                 mapVertices[vCounter + 4] = v5;
2369                 mapVertices[vCounter + 5] = v8;
2370                 vCounter += 6;
2371
2372                 mapNormals[nCounter] = n4;
2373                 mapNormals[nCounter + 1] = n4;
2374                 mapNormals[nCounter + 2] = n4;
2375                 mapNormals[nCounter + 3] = n4;
2376                 mapNormals[nCounter + 4] = n4;
2377                 mapNormals[nCounter + 5] = n4;
2378                 nCounter += 6;
2379
2380                 mapTexcoords[tcCounter] = (Vector2){ bottomTexUV.x + bottomTexUV.width, bottomTexUV.y };
2381                 mapTexcoords[tcCounter + 1] = (Vector2){ bottomTexUV.x, bottomTexUV.y + bottomTexUV.height };
2382                 mapTexcoords[tcCounter + 2] = (Vector2){ bottomTexUV.x + bottomTexUV.width, bottomTexUV.y + bottomTexUV.height };
2383                 mapTexcoords[tcCounter + 3] = (Vector2){ bottomTexUV.x + bottomTexUV.width, bottomTexUV.y };
2384                 mapTexcoords[tcCounter + 4] = (Vector2){ bottomTexUV.x, bottomTexUV.y };
2385                 mapTexcoords[tcCounter + 5] = (Vector2){ bottomTexUV.x, bottomTexUV.y + bottomTexUV.height };
2386                 tcCounter += 6;
2387
2388                 // Checking cube on bottom of current cube
2389                 if (((z < cubicmap.height - 1) && COLOR_EQUAL(pixels[(z + 1)*cubicmap.width + x], BLACK)) || (z == cubicmap.height - 1))
2390                 {
2391                     // Define front triangles (2 tris, 6 vertex) --> v2 v7 v3, v3 v7 v8
2392                     // NOTE: Collateral occluded faces are not generated
2393                     mapVertices[vCounter] = v2;
2394                     mapVertices[vCounter + 1] = v7;
2395                     mapVertices[vCounter + 2] = v3;
2396                     mapVertices[vCounter + 3] = v3;
2397                     mapVertices[vCounter + 4] = v7;
2398                     mapVertices[vCounter + 5] = v8;
2399                     vCounter += 6;
2400
2401                     mapNormals[nCounter] = n6;
2402                     mapNormals[nCounter + 1] = n6;
2403                     mapNormals[nCounter + 2] = n6;
2404                     mapNormals[nCounter + 3] = n6;
2405                     mapNormals[nCounter + 4] = n6;
2406                     mapNormals[nCounter + 5] = n6;
2407                     nCounter += 6;
2408
2409                     mapTexcoords[tcCounter] = (Vector2){ frontTexUV.x, frontTexUV.y };
2410                     mapTexcoords[tcCounter + 1] = (Vector2){ frontTexUV.x, frontTexUV.y + frontTexUV.height };
2411                     mapTexcoords[tcCounter + 2] = (Vector2){ frontTexUV.x + frontTexUV.width, frontTexUV.y };
2412                     mapTexcoords[tcCounter + 3] = (Vector2){ frontTexUV.x + frontTexUV.width, frontTexUV.y };
2413                     mapTexcoords[tcCounter + 4] = (Vector2){ frontTexUV.x, frontTexUV.y + frontTexUV.height };
2414                     mapTexcoords[tcCounter + 5] = (Vector2){ frontTexUV.x + frontTexUV.width, frontTexUV.y + frontTexUV.height };
2415                     tcCounter += 6;
2416                 }
2417
2418                 // Checking cube on top of current cube
2419                 if (((z > 0) && COLOR_EQUAL(pixels[(z - 1)*cubicmap.width + x], BLACK)) || (z == 0))
2420                 {
2421                     // Define back triangles (2 tris, 6 vertex) --> v1 v5 v6, v1 v4 v5
2422                     // NOTE: Collateral occluded faces are not generated
2423                     mapVertices[vCounter] = v1;
2424                     mapVertices[vCounter + 1] = v5;
2425                     mapVertices[vCounter + 2] = v6;
2426                     mapVertices[vCounter + 3] = v1;
2427                     mapVertices[vCounter + 4] = v4;
2428                     mapVertices[vCounter + 5] = v5;
2429                     vCounter += 6;
2430
2431                     mapNormals[nCounter] = n5;
2432                     mapNormals[nCounter + 1] = n5;
2433                     mapNormals[nCounter + 2] = n5;
2434                     mapNormals[nCounter + 3] = n5;
2435                     mapNormals[nCounter + 4] = n5;
2436                     mapNormals[nCounter + 5] = n5;
2437                     nCounter += 6;
2438
2439                     mapTexcoords[tcCounter] = (Vector2){ backTexUV.x + backTexUV.width, backTexUV.y };
2440                     mapTexcoords[tcCounter + 1] = (Vector2){ backTexUV.x, backTexUV.y + backTexUV.height };
2441                     mapTexcoords[tcCounter + 2] = (Vector2){ backTexUV.x + backTexUV.width, backTexUV.y + backTexUV.height };
2442                     mapTexcoords[tcCounter + 3] = (Vector2){ backTexUV.x + backTexUV.width, backTexUV.y };
2443                     mapTexcoords[tcCounter + 4] = (Vector2){ backTexUV.x, backTexUV.y };
2444                     mapTexcoords[tcCounter + 5] = (Vector2){ backTexUV.x, backTexUV.y + backTexUV.height };
2445                     tcCounter += 6;
2446                 }
2447
2448                 // Checking cube on right of current cube
2449                 if (((x < cubicmap.width - 1) && COLOR_EQUAL(pixels[z*cubicmap.width + (x + 1)], BLACK)) || (x == cubicmap.width - 1))
2450                 {
2451                     // Define right triangles (2 tris, 6 vertex) --> v3 v8 v4, v4 v8 v5
2452                     // NOTE: Collateral occluded faces are not generated
2453                     mapVertices[vCounter] = v3;
2454                     mapVertices[vCounter + 1] = v8;
2455                     mapVertices[vCounter + 2] = v4;
2456                     mapVertices[vCounter + 3] = v4;
2457                     mapVertices[vCounter + 4] = v8;
2458                     mapVertices[vCounter + 5] = v5;
2459                     vCounter += 6;
2460
2461                     mapNormals[nCounter] = n1;
2462                     mapNormals[nCounter + 1] = n1;
2463                     mapNormals[nCounter + 2] = n1;
2464                     mapNormals[nCounter + 3] = n1;
2465                     mapNormals[nCounter + 4] = n1;
2466                     mapNormals[nCounter + 5] = n1;
2467                     nCounter += 6;
2468
2469                     mapTexcoords[tcCounter] = (Vector2){ rightTexUV.x, rightTexUV.y };
2470                     mapTexcoords[tcCounter + 1] = (Vector2){ rightTexUV.x, rightTexUV.y + rightTexUV.height };
2471                     mapTexcoords[tcCounter + 2] = (Vector2){ rightTexUV.x + rightTexUV.width, rightTexUV.y };
2472                     mapTexcoords[tcCounter + 3] = (Vector2){ rightTexUV.x + rightTexUV.width, rightTexUV.y };
2473                     mapTexcoords[tcCounter + 4] = (Vector2){ rightTexUV.x, rightTexUV.y + rightTexUV.height };
2474                     mapTexcoords[tcCounter + 5] = (Vector2){ rightTexUV.x + rightTexUV.width, rightTexUV.y + rightTexUV.height };
2475                     tcCounter += 6;
2476                 }
2477
2478                 // Checking cube on left of current cube
2479                 if (((x > 0) && COLOR_EQUAL(pixels[z*cubicmap.width + (x - 1)], BLACK)) || (x == 0))
2480                 {
2481                     // Define left triangles (2 tris, 6 vertex) --> v1 v7 v2, v1 v6 v7
2482                     // NOTE: Collateral occluded faces are not generated
2483                     mapVertices[vCounter] = v1;
2484                     mapVertices[vCounter + 1] = v7;
2485                     mapVertices[vCounter + 2] = v2;
2486                     mapVertices[vCounter + 3] = v1;
2487                     mapVertices[vCounter + 4] = v6;
2488                     mapVertices[vCounter + 5] = v7;
2489                     vCounter += 6;
2490
2491                     mapNormals[nCounter] = n2;
2492                     mapNormals[nCounter + 1] = n2;
2493                     mapNormals[nCounter + 2] = n2;
2494                     mapNormals[nCounter + 3] = n2;
2495                     mapNormals[nCounter + 4] = n2;
2496                     mapNormals[nCounter + 5] = n2;
2497                     nCounter += 6;
2498
2499                     mapTexcoords[tcCounter] = (Vector2){ leftTexUV.x, leftTexUV.y };
2500                     mapTexcoords[tcCounter + 1] = (Vector2){ leftTexUV.x + leftTexUV.width, leftTexUV.y + leftTexUV.height };
2501                     mapTexcoords[tcCounter + 2] = (Vector2){ leftTexUV.x + leftTexUV.width, leftTexUV.y };
2502                     mapTexcoords[tcCounter + 3] = (Vector2){ leftTexUV.x, leftTexUV.y };
2503                     mapTexcoords[tcCounter + 4] = (Vector2){ leftTexUV.x, leftTexUV.y + leftTexUV.height };
2504                     mapTexcoords[tcCounter + 5] = (Vector2){ leftTexUV.x + leftTexUV.width, leftTexUV.y + leftTexUV.height };
2505                     tcCounter += 6;
2506                 }
2507             }
2508             // We check pixel color to be BLACK, we will only draw floor and roof
2509             else if (COLOR_EQUAL(pixels[z*cubicmap.width + x], BLACK))
2510             {
2511                 // Define top triangles (2 tris, 6 vertex --> v1-v2-v3, v1-v3-v4)
2512                 mapVertices[vCounter] = v1;
2513                 mapVertices[vCounter + 1] = v3;
2514                 mapVertices[vCounter + 2] = v2;
2515                 mapVertices[vCounter + 3] = v1;
2516                 mapVertices[vCounter + 4] = v4;
2517                 mapVertices[vCounter + 5] = v3;
2518                 vCounter += 6;
2519
2520                 mapNormals[nCounter] = n4;
2521                 mapNormals[nCounter + 1] = n4;
2522                 mapNormals[nCounter + 2] = n4;
2523                 mapNormals[nCounter + 3] = n4;
2524                 mapNormals[nCounter + 4] = n4;
2525                 mapNormals[nCounter + 5] = n4;
2526                 nCounter += 6;
2527
2528                 mapTexcoords[tcCounter] = (Vector2){ topTexUV.x, topTexUV.y };
2529                 mapTexcoords[tcCounter + 1] = (Vector2){ topTexUV.x + topTexUV.width, topTexUV.y + topTexUV.height };
2530                 mapTexcoords[tcCounter + 2] = (Vector2){ topTexUV.x, topTexUV.y + topTexUV.height };
2531                 mapTexcoords[tcCounter + 3] = (Vector2){ topTexUV.x, topTexUV.y };
2532                 mapTexcoords[tcCounter + 4] = (Vector2){ topTexUV.x + topTexUV.width, topTexUV.y };
2533                 mapTexcoords[tcCounter + 5] = (Vector2){ topTexUV.x + topTexUV.width, topTexUV.y + topTexUV.height };
2534                 tcCounter += 6;
2535
2536                 // Define bottom triangles (2 tris, 6 vertex --> v6-v8-v7, v6-v5-v8)
2537                 mapVertices[vCounter] = v6;
2538                 mapVertices[vCounter + 1] = v7;
2539                 mapVertices[vCounter + 2] = v8;
2540                 mapVertices[vCounter + 3] = v6;
2541                 mapVertices[vCounter + 4] = v8;
2542                 mapVertices[vCounter + 5] = v5;
2543                 vCounter += 6;
2544
2545                 mapNormals[nCounter] = n3;
2546                 mapNormals[nCounter + 1] = n3;
2547                 mapNormals[nCounter + 2] = n3;
2548                 mapNormals[nCounter + 3] = n3;
2549                 mapNormals[nCounter + 4] = n3;
2550                 mapNormals[nCounter + 5] = n3;
2551                 nCounter += 6;
2552
2553                 mapTexcoords[tcCounter] = (Vector2){ bottomTexUV.x + bottomTexUV.width, bottomTexUV.y };
2554                 mapTexcoords[tcCounter + 1] = (Vector2){ bottomTexUV.x + bottomTexUV.width, bottomTexUV.y + bottomTexUV.height };
2555                 mapTexcoords[tcCounter + 2] = (Vector2){ bottomTexUV.x, bottomTexUV.y + bottomTexUV.height };
2556                 mapTexcoords[tcCounter + 3] = (Vector2){ bottomTexUV.x + bottomTexUV.width, bottomTexUV.y };
2557                 mapTexcoords[tcCounter + 4] = (Vector2){ bottomTexUV.x, bottomTexUV.y + bottomTexUV.height };
2558                 mapTexcoords[tcCounter + 5] = (Vector2){ bottomTexUV.x, bottomTexUV.y };
2559                 tcCounter += 6;
2560             }
2561         }
2562     }
2563
2564     // Move data from mapVertices temp arays to vertices float array
2565     mesh.vertexCount = vCounter;
2566     mesh.triangleCount = vCounter/3;
2567
2568     mesh.vertices = (float *)RL_MALLOC(mesh.vertexCount*3*sizeof(float));
2569     mesh.normals = (float *)RL_MALLOC(mesh.vertexCount*3*sizeof(float));
2570     mesh.texcoords = (float *)RL_MALLOC(mesh.vertexCount*2*sizeof(float));
2571     mesh.colors = NULL;
2572
2573     int fCounter = 0;
2574
2575     // Move vertices data
2576     for (int i = 0; i < vCounter; i++)
2577     {
2578         mesh.vertices[fCounter] = mapVertices[i].x;
2579         mesh.vertices[fCounter + 1] = mapVertices[i].y;
2580         mesh.vertices[fCounter + 2] = mapVertices[i].z;
2581         fCounter += 3;
2582     }
2583
2584     fCounter = 0;
2585
2586     // Move normals data
2587     for (int i = 0; i < nCounter; i++)
2588     {
2589         mesh.normals[fCounter] = mapNormals[i].x;
2590         mesh.normals[fCounter + 1] = mapNormals[i].y;
2591         mesh.normals[fCounter + 2] = mapNormals[i].z;
2592         fCounter += 3;
2593     }
2594
2595     fCounter = 0;
2596
2597     // Move texcoords data
2598     for (int i = 0; i < tcCounter; i++)
2599     {
2600         mesh.texcoords[fCounter] = mapTexcoords[i].x;
2601         mesh.texcoords[fCounter + 1] = mapTexcoords[i].y;
2602         fCounter += 2;
2603     }
2604
2605     RL_FREE(mapVertices);
2606     RL_FREE(mapNormals);
2607     RL_FREE(mapTexcoords);
2608
2609     UnloadImageColors(pixels);   // Unload pixels color data
2610
2611     // Upload vertex data to GPU (static mesh)
2612     UploadMesh(&mesh, false);
2613
2614     return mesh;
2615 }
2616 #endif      // SUPPORT_MESH_GENERATION
2617
2618 // Compute mesh bounding box limits
2619 // NOTE: minVertex and maxVertex should be transformed by model transform matrix
2620 BoundingBox MeshBoundingBox(Mesh mesh)
2621 {
2622     // Get min and max vertex to construct bounds (AABB)
2623     Vector3 minVertex = { 0 };
2624     Vector3 maxVertex = { 0 };
2625
2626     if (mesh.vertices != NULL)
2627     {
2628         minVertex = (Vector3){ mesh.vertices[0], mesh.vertices[1], mesh.vertices[2] };
2629         maxVertex = (Vector3){ mesh.vertices[0], mesh.vertices[1], mesh.vertices[2] };
2630
2631         for (int i = 1; i < mesh.vertexCount; i++)
2632         {
2633             minVertex = Vector3Min(minVertex, (Vector3){ mesh.vertices[i*3], mesh.vertices[i*3 + 1], mesh.vertices[i*3 + 2] });
2634             maxVertex = Vector3Max(maxVertex, (Vector3){ mesh.vertices[i*3], mesh.vertices[i*3 + 1], mesh.vertices[i*3 + 2] });
2635         }
2636     }
2637
2638     // Create the bounding box
2639     BoundingBox box = { 0 };
2640     box.min = minVertex;
2641     box.max = maxVertex;
2642
2643     return box;
2644 }
2645
2646 // Compute mesh tangents
2647 // NOTE: To calculate mesh tangents and binormals we need mesh vertex positions and texture coordinates
2648 // Implementation base don: https://answers.unity.com/questions/7789/calculating-tangents-vector4.html
2649 void MeshTangents(Mesh *mesh)
2650 {
2651     if (mesh->tangents == NULL) mesh->tangents = (float *)RL_MALLOC(mesh->vertexCount*4*sizeof(float));
2652     else TRACELOG(LOG_WARNING, "MESH: Tangents data already available, re-writting");
2653
2654     Vector3 *tan1 = (Vector3 *)RL_MALLOC(mesh->vertexCount*sizeof(Vector3));
2655     Vector3 *tan2 = (Vector3 *)RL_MALLOC(mesh->vertexCount*sizeof(Vector3));
2656
2657     for (int i = 0; i < mesh->vertexCount; i += 3)
2658     {
2659         // Get triangle vertices
2660         Vector3 v1 = { mesh->vertices[(i + 0)*3 + 0], mesh->vertices[(i + 0)*3 + 1], mesh->vertices[(i + 0)*3 + 2] };
2661         Vector3 v2 = { mesh->vertices[(i + 1)*3 + 0], mesh->vertices[(i + 1)*3 + 1], mesh->vertices[(i + 1)*3 + 2] };
2662         Vector3 v3 = { mesh->vertices[(i + 2)*3 + 0], mesh->vertices[(i + 2)*3 + 1], mesh->vertices[(i + 2)*3 + 2] };
2663
2664         // Get triangle texcoords
2665         Vector2 uv1 = { mesh->texcoords[(i + 0)*2 + 0], mesh->texcoords[(i + 0)*2 + 1] };
2666         Vector2 uv2 = { mesh->texcoords[(i + 1)*2 + 0], mesh->texcoords[(i + 1)*2 + 1] };
2667         Vector2 uv3 = { mesh->texcoords[(i + 2)*2 + 0], mesh->texcoords[(i + 2)*2 + 1] };
2668
2669         float x1 = v2.x - v1.x;
2670         float y1 = v2.y - v1.y;
2671         float z1 = v2.z - v1.z;
2672         float x2 = v3.x - v1.x;
2673         float y2 = v3.y - v1.y;
2674         float z2 = v3.z - v1.z;
2675
2676         float s1 = uv2.x - uv1.x;
2677         float t1 = uv2.y - uv1.y;
2678         float s2 = uv3.x - uv1.x;
2679         float t2 = uv3.y - uv1.y;
2680
2681         float div = s1*t2 - s2*t1;
2682         float r = (div == 0.0f)? 0.0f : 1.0f/div;
2683
2684         Vector3 sdir = { (t2*x1 - t1*x2)*r, (t2*y1 - t1*y2)*r, (t2*z1 - t1*z2)*r };
2685         Vector3 tdir = { (s1*x2 - s2*x1)*r, (s1*y2 - s2*y1)*r, (s1*z2 - s2*z1)*r };
2686
2687         tan1[i + 0] = sdir;
2688         tan1[i + 1] = sdir;
2689         tan1[i + 2] = sdir;
2690
2691         tan2[i + 0] = tdir;
2692         tan2[i + 1] = tdir;
2693         tan2[i + 2] = tdir;
2694     }
2695
2696     // Compute tangents considering normals
2697     for (int i = 0; i < mesh->vertexCount; ++i)
2698     {
2699         Vector3 normal = { mesh->normals[i*3 + 0], mesh->normals[i*3 + 1], mesh->normals[i*3 + 2] };
2700         Vector3 tangent = tan1[i];
2701
2702         // TODO: Review, not sure if tangent computation is right, just used reference proposed maths...
2703     #if defined(COMPUTE_TANGENTS_METHOD_01)
2704         Vector3 tmp = Vector3Subtract(tangent, Vector3Scale(normal, Vector3DotProduct(normal, tangent)));
2705         tmp = Vector3Normalize(tmp);
2706         mesh->tangents[i*4 + 0] = tmp.x;
2707         mesh->tangents[i*4 + 1] = tmp.y;
2708         mesh->tangents[i*4 + 2] = tmp.z;
2709         mesh->tangents[i*4 + 3] = 1.0f;
2710     #else
2711         Vector3OrthoNormalize(&normal, &tangent);
2712         mesh->tangents[i*4 + 0] = tangent.x;
2713         mesh->tangents[i*4 + 1] = tangent.y;
2714         mesh->tangents[i*4 + 2] = tangent.z;
2715         mesh->tangents[i*4 + 3] = (Vector3DotProduct(Vector3CrossProduct(normal, tangent), tan2[i]) < 0.0f)? -1.0f : 1.0f;
2716     #endif
2717     }
2718
2719     RL_FREE(tan1);
2720     RL_FREE(tan2);
2721
2722     // Load a new tangent attributes buffer
2723     mesh->vboId[SHADER_LOC_VERTEX_TANGENT] = rlLoadVertexBuffer(mesh->tangents, mesh->vertexCount*4*sizeof(float), false);
2724
2725     TRACELOG(LOG_INFO, "MESH: Tangents data computed for provided mesh");
2726 }
2727
2728 // Compute mesh binormals (aka bitangent)
2729 void MeshBinormals(Mesh *mesh)
2730 {
2731     for (int i = 0; i < mesh->vertexCount; i++)
2732     {
2733         //Vector3 normal = { mesh->normals[i*3 + 0], mesh->normals[i*3 + 1], mesh->normals[i*3 + 2] };
2734         //Vector3 tangent = { mesh->tangents[i*4 + 0], mesh->tangents[i*4 + 1], mesh->tangents[i*4 + 2] };
2735         //Vector3 binormal = Vector3Scale(Vector3CrossProduct(normal, tangent), mesh->tangents[i*4 + 3]);
2736
2737         // TODO: Register computed binormal in mesh->binormal?
2738     }
2739 }
2740
2741 // Draw a model (with texture if set)
2742 void DrawModel(Model model, Vector3 position, float scale, Color tint)
2743 {
2744     Vector3 vScale = { scale, scale, scale };
2745     Vector3 rotationAxis = { 0.0f, 1.0f, 0.0f };
2746
2747     DrawModelEx(model, position, rotationAxis, 0.0f, vScale, tint);
2748 }
2749
2750 // Draw a model with extended parameters
2751 void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint)
2752 {
2753     // Calculate transformation matrix from function parameters
2754     // Get transform matrix (rotation -> scale -> translation)
2755     Matrix matScale = MatrixScale(scale.x, scale.y, scale.z);
2756     Matrix matRotation = MatrixRotate(rotationAxis, rotationAngle*DEG2RAD);
2757     Matrix matTranslation = MatrixTranslate(position.x, position.y, position.z);
2758
2759     Matrix matTransform = MatrixMultiply(MatrixMultiply(matScale, matRotation), matTranslation);
2760
2761     // Combine model transformation matrix (model.transform) with matrix generated by function parameters (matTransform)
2762     model.transform = MatrixMultiply(model.transform, matTransform);
2763
2764     for (int i = 0; i < model.meshCount; i++)
2765     {
2766         Color color = model.materials[model.meshMaterial[i]].maps[MATERIAL_MAP_DIFFUSE].color;
2767
2768         Color colorTint = WHITE;
2769         colorTint.r = (unsigned char)((((float)color.r/255.0)*((float)tint.r/255.0))*255.0f);
2770         colorTint.g = (unsigned char)((((float)color.g/255.0)*((float)tint.g/255.0))*255.0f);
2771         colorTint.b = (unsigned char)((((float)color.b/255.0)*((float)tint.b/255.0))*255.0f);
2772         colorTint.a = (unsigned char)((((float)color.a/255.0)*((float)tint.a/255.0))*255.0f);
2773
2774         model.materials[model.meshMaterial[i]].maps[MATERIAL_MAP_DIFFUSE].color = colorTint;
2775         DrawMesh(model.meshes[i], model.materials[model.meshMaterial[i]], model.transform);
2776         model.materials[model.meshMaterial[i]].maps[MATERIAL_MAP_DIFFUSE].color = color;
2777     }
2778 }
2779
2780 // Draw a model wires (with texture if set)
2781 void DrawModelWires(Model model, Vector3 position, float scale, Color tint)
2782 {
2783     rlEnableWireMode();
2784
2785     DrawModel(model, position, scale, tint);
2786
2787     rlDisableWireMode();
2788 }
2789
2790 // Draw a model wires (with texture if set) with extended parameters
2791 void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint)
2792 {
2793     rlEnableWireMode();
2794
2795     DrawModelEx(model, position, rotationAxis, rotationAngle, scale, tint);
2796
2797     rlDisableWireMode();
2798 }
2799
2800 // Draw a billboard
2801 void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint)
2802 {
2803     Rectangle source = { 0.0f, 0.0f, (float)texture.width, (float)texture.height };
2804
2805     DrawBillboardRec(camera, texture, source, center, size, tint);
2806 }
2807
2808 // Draw a billboard (part of a texture defined by a rectangle)
2809 void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 center, float size, Color tint)
2810 {
2811     // NOTE: Billboard size will maintain source rectangle aspect ratio, size will represent billboard width
2812     Vector2 sizeRatio = { size, size*(float)source.height/source.width };
2813
2814     Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
2815
2816     Vector3 right = { matView.m0, matView.m4, matView.m8 };
2817     //Vector3 up = { matView.m1, matView.m5, matView.m9 };
2818
2819     // NOTE: Billboard locked on axis-Y
2820     Vector3 up = { 0.0f, 1.0f, 0.0f };
2821 /*
2822     a-------b
2823     |       |
2824     |   *   |
2825     |       |
2826     d-------c
2827 */
2828     right = Vector3Scale(right, sizeRatio.x/2);
2829     up = Vector3Scale(up, sizeRatio.y/2);
2830
2831     Vector3 p1 = Vector3Add(right, up);
2832     Vector3 p2 = Vector3Subtract(right, up);
2833
2834     Vector3 a = Vector3Subtract(center, p2);
2835     Vector3 b = Vector3Add(center, p1);
2836     Vector3 c = Vector3Add(center, p2);
2837     Vector3 d = Vector3Subtract(center, p1);
2838
2839     rlCheckRenderBatchLimit(4);
2840
2841     rlSetTexture(texture.id);
2842
2843     rlBegin(RL_QUADS);
2844         rlColor4ub(tint.r, tint.g, tint.b, tint.a);
2845
2846         // Bottom-left corner for texture and quad
2847         rlTexCoord2f((float)source.x/texture.width, (float)source.y/texture.height);
2848         rlVertex3f(a.x, a.y, a.z);
2849
2850         // Top-left corner for texture and quad
2851         rlTexCoord2f((float)source.x/texture.width, (float)(source.y + source.height)/texture.height);
2852         rlVertex3f(d.x, d.y, d.z);
2853
2854         // Top-right corner for texture and quad
2855         rlTexCoord2f((float)(source.x + source.width)/texture.width, (float)(source.y + source.height)/texture.height);
2856         rlVertex3f(c.x, c.y, c.z);
2857
2858         // Bottom-right corner for texture and quad
2859         rlTexCoord2f((float)(source.x + source.width)/texture.width, (float)source.y/texture.height);
2860         rlVertex3f(b.x, b.y, b.z);
2861     rlEnd();
2862
2863     rlSetTexture(0);
2864 }
2865
2866 // Draw a bounding box with wires
2867 void DrawBoundingBox(BoundingBox box, Color color)
2868 {
2869     Vector3 size;
2870
2871     size.x = fabsf(box.max.x - box.min.x);
2872     size.y = fabsf(box.max.y - box.min.y);
2873     size.z = fabsf(box.max.z - box.min.z);
2874
2875     Vector3 center = { box.min.x + size.x/2.0f, box.min.y + size.y/2.0f, box.min.z + size.z/2.0f };
2876
2877     DrawCubeWires(center, size.x, size.y, size.z, color);
2878 }
2879
2880 // Detect collision between two spheres
2881 bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, float radius2)
2882 {
2883     bool collision = false;
2884
2885     // Simple way to check for collision, just checking distance between two points
2886     // Unfortunately, sqrtf() is a costly operation, so we avoid it with following solution
2887     /*
2888     float dx = center1.x - center2.x;      // X distance between centers
2889     float dy = center1.y - center2.y;      // Y distance between centers
2890     float dz = center1.z - center2.z;      // Z distance between centers
2891
2892     float distance = sqrtf(dx*dx + dy*dy + dz*dz);  // Distance between centers
2893
2894     if (distance <= (radius1 + radius2)) collision = true;
2895     */
2896
2897     // Check for distances squared to avoid sqrtf()
2898     if (Vector3DotProduct(Vector3Subtract(center2, center1), Vector3Subtract(center2, center1)) <= (radius1 + radius2)*(radius1 + radius2)) collision = true;
2899
2900     return collision;
2901 }
2902
2903 // Detect collision between two boxes
2904 // NOTE: Boxes are defined by two points minimum and maximum
2905 bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2)
2906 {
2907     bool collision = true;
2908
2909     if ((box1.max.x >= box2.min.x) && (box1.min.x <= box2.max.x))
2910     {
2911         if ((box1.max.y < box2.min.y) || (box1.min.y > box2.max.y)) collision = false;
2912         if ((box1.max.z < box2.min.z) || (box1.min.z > box2.max.z)) collision = false;
2913     }
2914     else collision = false;
2915
2916     return collision;
2917 }
2918
2919 // Detect collision between box and sphere
2920 bool CheckCollisionBoxSphere(BoundingBox box, Vector3 center, float radius)
2921 {
2922     bool collision = false;
2923
2924     float dmin = 0;
2925
2926     if (center.x < box.min.x) dmin += powf(center.x - box.min.x, 2);
2927     else if (center.x > box.max.x) dmin += powf(center.x - box.max.x, 2);
2928
2929     if (center.y < box.min.y) dmin += powf(center.y - box.min.y, 2);
2930     else if (center.y > box.max.y) dmin += powf(center.y - box.max.y, 2);
2931
2932     if (center.z < box.min.z) dmin += powf(center.z - box.min.z, 2);
2933     else if (center.z > box.max.z) dmin += powf(center.z - box.max.z, 2);
2934
2935     if (dmin <= (radius*radius)) collision = true;
2936
2937     return collision;
2938 }
2939
2940 // Detect collision between ray and sphere
2941 bool CheckCollisionRaySphere(Ray ray, Vector3 center, float radius)
2942 {
2943     bool collision = false;
2944
2945     Vector3 raySpherePos = Vector3Subtract(center, ray.position);
2946     float distance = Vector3Length(raySpherePos);
2947     float vector = Vector3DotProduct(raySpherePos, ray.direction);
2948     float d = radius*radius - (distance*distance - vector*vector);
2949
2950     if (d >= 0.0f) collision = true;
2951
2952     return collision;
2953 }
2954
2955 // Detect collision between ray and sphere with extended parameters and collision point detection
2956 bool CheckCollisionRaySphereEx(Ray ray, Vector3 center, float radius, Vector3 *collisionPoint)
2957 {
2958     bool collision = false;
2959
2960     Vector3 raySpherePos = Vector3Subtract(center, ray.position);
2961     float distance = Vector3Length(raySpherePos);
2962     float vector = Vector3DotProduct(raySpherePos, ray.direction);
2963     float d = radius*radius - (distance*distance - vector*vector);
2964
2965     if (d >= 0.0f) collision = true;
2966
2967     // Check if ray origin is inside the sphere to calculate the correct collision point
2968     float collisionDistance = 0;
2969
2970     if (distance < radius) collisionDistance = vector + sqrtf(d);
2971     else collisionDistance = vector - sqrtf(d);
2972
2973     // Calculate collision point
2974     Vector3 cPoint = Vector3Add(ray.position, Vector3Scale(ray.direction, collisionDistance));
2975
2976     collisionPoint->x = cPoint.x;
2977     collisionPoint->y = cPoint.y;
2978     collisionPoint->z = cPoint.z;
2979
2980     return collision;
2981 }
2982
2983 // Detect collision between ray and bounding box
2984 bool CheckCollisionRayBox(Ray ray, BoundingBox box)
2985 {
2986     bool collision = false;
2987
2988     float t[8];
2989     t[0] = (box.min.x - ray.position.x)/ray.direction.x;
2990     t[1] = (box.max.x - ray.position.x)/ray.direction.x;
2991     t[2] = (box.min.y - ray.position.y)/ray.direction.y;
2992     t[3] = (box.max.y - ray.position.y)/ray.direction.y;
2993     t[4] = (box.min.z - ray.position.z)/ray.direction.z;
2994     t[5] = (box.max.z - ray.position.z)/ray.direction.z;
2995     t[6] = (float)fmax(fmax(fmin(t[0], t[1]), fmin(t[2], t[3])), fmin(t[4], t[5]));
2996     t[7] = (float)fmin(fmin(fmax(t[0], t[1]), fmax(t[2], t[3])), fmax(t[4], t[5]));
2997
2998     collision = !(t[7] < 0 || t[6] > t[7]);
2999
3000     return collision;
3001 }
3002 // Get collision info between ray and mesh
3003 RayHitInfo GetCollisionRayMesh(Ray ray, Mesh mesh, Matrix transform)
3004 {
3005     RayHitInfo result = { 0 };
3006
3007     // Check if mesh vertex data on CPU for testing
3008     if (mesh.vertices != NULL)
3009     {
3010         int triangleCount = mesh.triangleCount;
3011
3012         // Test against all triangles in mesh
3013         for (int i = 0; i < triangleCount; i++)
3014         {
3015             Vector3 a, b, c;
3016             Vector3* vertdata = (Vector3*)mesh.vertices;
3017
3018             if (mesh.indices)
3019             {
3020                 a = vertdata[mesh.indices[i*3 + 0]];
3021                 b = vertdata[mesh.indices[i*3 + 1]];
3022                 c = vertdata[mesh.indices[i*3 + 2]];
3023             }
3024             else
3025             {
3026                 a = vertdata[i*3 + 0];
3027                 b = vertdata[i*3 + 1];
3028                 c = vertdata[i*3 + 2];
3029             }
3030
3031             a = Vector3Transform(a, transform);
3032             b = Vector3Transform(b, transform);
3033             c = Vector3Transform(c, transform);
3034
3035             RayHitInfo triHitInfo = GetCollisionRayTriangle(ray, a, b, c);
3036
3037             if (triHitInfo.hit)
3038             {
3039                 // Save the closest hit triangle
3040                 if ((!result.hit) || (result.distance > triHitInfo.distance)) result = triHitInfo;
3041             }
3042         }
3043     }
3044     return result;
3045 }
3046
3047 // Get collision info between ray and model
3048 RayHitInfo GetCollisionRayModel(Ray ray, Model model)
3049 {
3050     RayHitInfo result = { 0 };
3051
3052     for (int m = 0; m < model.meshCount; m++)
3053     {
3054         RayHitInfo meshHitInfo = GetCollisionRayMesh(ray, model.meshes[m], model.transform);
3055
3056         if (meshHitInfo.hit)
3057         {
3058             // Save the closest hit mesh
3059             if ((!result.hit) || (result.distance > meshHitInfo.distance)) result = meshHitInfo;
3060         }
3061     }
3062
3063     return result;
3064 }
3065
3066 // Get collision info between ray and triangle
3067 // NOTE: Based on https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
3068 RayHitInfo GetCollisionRayTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3)
3069 {
3070     #define EPSILON 0.000001        // A small number
3071
3072     Vector3 edge1, edge2;
3073     Vector3 p, q, tv;
3074     float det, invDet, u, v, t;
3075     RayHitInfo result = {0};
3076
3077     // Find vectors for two edges sharing V1
3078     edge1 = Vector3Subtract(p2, p1);
3079     edge2 = Vector3Subtract(p3, p1);
3080
3081     // Begin calculating determinant - also used to calculate u parameter
3082     p = Vector3CrossProduct(ray.direction, edge2);
3083
3084     // If determinant is near zero, ray lies in plane of triangle or ray is parallel to plane of triangle
3085     det = Vector3DotProduct(edge1, p);
3086
3087     // Avoid culling!
3088     if ((det > -EPSILON) && (det < EPSILON)) return result;
3089
3090     invDet = 1.0f/det;
3091
3092     // Calculate distance from V1 to ray origin
3093     tv = Vector3Subtract(ray.position, p1);
3094
3095     // Calculate u parameter and test bound
3096     u = Vector3DotProduct(tv, p)*invDet;
3097
3098     // The intersection lies outside of the triangle
3099     if ((u < 0.0f) || (u > 1.0f)) return result;
3100
3101     // Prepare to test v parameter
3102     q = Vector3CrossProduct(tv, edge1);
3103
3104     // Calculate V parameter and test bound
3105     v = Vector3DotProduct(ray.direction, q)*invDet;
3106
3107     // The intersection lies outside of the triangle
3108     if ((v < 0.0f) || ((u + v) > 1.0f)) return result;
3109
3110     t = Vector3DotProduct(edge2, q)*invDet;
3111
3112     if (t > EPSILON)
3113     {
3114         // Ray hit, get hit point and normal
3115         result.hit = true;
3116         result.distance = t;
3117         result.hit = true;
3118         result.normal = Vector3Normalize(Vector3CrossProduct(edge1, edge2));
3119         result.position = Vector3Add(ray.position, Vector3Scale(ray.direction, t));
3120     }
3121
3122     return result;
3123 }
3124
3125 // Get collision info between ray and ground plane (Y-normal plane)
3126 RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight)
3127 {
3128     #define EPSILON 0.000001        // A small number
3129
3130     RayHitInfo result = { 0 };
3131
3132     if (fabsf(ray.direction.y) > EPSILON)
3133     {
3134         float distance = (ray.position.y - groundHeight)/-ray.direction.y;
3135
3136         if (distance >= 0.0)
3137         {
3138             result.hit = true;
3139             result.distance = distance;
3140             result.normal = (Vector3){ 0.0, 1.0, 0.0 };
3141             result.position = Vector3Add(ray.position, Vector3Scale(ray.direction, distance));
3142             result.position.y = groundHeight;
3143         }
3144     }
3145
3146     return result;
3147 }
3148
3149 //----------------------------------------------------------------------------------
3150 // Module specific Functions Definition
3151 //----------------------------------------------------------------------------------
3152
3153 #if defined(SUPPORT_FILEFORMAT_OBJ)
3154 // Load OBJ mesh data
3155 static Model LoadOBJ(const char *fileName)
3156 {
3157     Model model = { 0 };
3158
3159     tinyobj_attrib_t attrib = { 0 };
3160     tinyobj_shape_t *meshes = NULL;
3161     unsigned int meshCount = 0;
3162
3163     tinyobj_material_t *materials = NULL;
3164     unsigned int materialCount = 0;
3165
3166     char *fileData = LoadFileText(fileName);
3167
3168     if (fileData != NULL)
3169     {
3170         unsigned int dataSize = (unsigned int)strlen(fileData);
3171         char currentDir[1024] = { 0 };
3172         strcpy(currentDir, GetWorkingDirectory());
3173         const char *workingDir = GetDirectoryPath(fileName);
3174         if (CHDIR(workingDir) != 0)
3175         {
3176             TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to change working directory", workingDir);
3177         }
3178
3179         unsigned int flags = TINYOBJ_FLAG_TRIANGULATE;
3180         int ret = tinyobj_parse_obj(&attrib, &meshes, &meshCount, &materials, &materialCount, fileData, dataSize, flags);
3181
3182         if (ret != TINYOBJ_SUCCESS) TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to load OBJ data", fileName);
3183         else TRACELOG(LOG_INFO, "MODEL: [%s] OBJ data loaded successfully: %i meshes / %i materials", fileName, meshCount, materialCount);
3184
3185         model.meshCount = materialCount;
3186
3187         // Init model materials array
3188         if (materialCount > 0)
3189         {
3190             model.materialCount = materialCount;
3191             model.materials = (Material *)RL_CALLOC(model.materialCount, sizeof(Material));
3192             TraceLog(LOG_INFO, "MODEL: model has %i material meshes", materialCount);
3193         }
3194         else
3195         {
3196             model.meshCount = 1;
3197             TraceLog(LOG_INFO, "MODEL: No materials, putting all meshes in a default material");
3198         }
3199
3200         model.meshes = (Mesh *)RL_CALLOC(model.meshCount, sizeof(Mesh));
3201         model.meshMaterial = (int *)RL_CALLOC(model.meshCount, sizeof(int));
3202
3203         // count the faces for each material
3204         int *matFaces = RL_CALLOC(meshCount, sizeof(int));
3205
3206         for (unsigned int mi = 0; mi < meshCount; mi++)
3207         {
3208             for (unsigned int fi = 0; fi < meshes[mi].length; fi++)
3209             {
3210                 int idx = attrib.material_ids[meshes[mi].face_offset + fi];
3211                 if (idx == -1) idx = 0; // for no material face (which could be the whole model)
3212                 matFaces[idx]++;
3213             }
3214         }
3215
3216         //--------------------------------------
3217         // create the material meshes
3218
3219         // running counts / indexes for each material mesh as we are
3220         // building them at the same time
3221         int *vCount = RL_CALLOC(model.meshCount, sizeof(int));
3222         int *vtCount = RL_CALLOC(model.meshCount, sizeof(int));
3223         int *vnCount = RL_CALLOC(model.meshCount, sizeof(int));
3224         int *faceCount = RL_CALLOC(model.meshCount, sizeof(int));
3225
3226         // allocate space for each of the material meshes
3227         for (int mi = 0; mi < model.meshCount; mi++)
3228         {
3229             model.meshes[mi].vertexCount = matFaces[mi]*3;
3230             model.meshes[mi].triangleCount = matFaces[mi];
3231             model.meshes[mi].vertices = (float *)RL_CALLOC(model.meshes[mi].vertexCount*3, sizeof(float));
3232             model.meshes[mi].texcoords = (float *)RL_CALLOC(model.meshes[mi].vertexCount*2, sizeof(float));
3233             model.meshes[mi].normals = (float *)RL_CALLOC(model.meshes[mi].vertexCount*3, sizeof(float));
3234             model.meshMaterial[mi] = mi;
3235         }
3236
3237         // scan through the combined sub meshes and pick out each material mesh
3238         for (unsigned int af = 0; af < attrib.num_faces; af++)
3239         {
3240             int mm = attrib.material_ids[af];   // mesh material for this face
3241             if (mm == -1) { mm = 0; }           // no material object..
3242
3243             // Get indices for the face
3244             tinyobj_vertex_index_t idx0 = attrib.faces[3*af + 0];
3245             tinyobj_vertex_index_t idx1 = attrib.faces[3*af + 1];
3246             tinyobj_vertex_index_t idx2 = attrib.faces[3*af + 2];
3247
3248             // Fill vertices buffer (float) using vertex index of the face
3249             for (int v = 0; v < 3; v++) { model.meshes[mm].vertices[vCount[mm] + v] = attrib.vertices[idx0.v_idx*3 + v]; } vCount[mm] +=3;
3250             for (int v = 0; v < 3; v++) { model.meshes[mm].vertices[vCount[mm] + v] = attrib.vertices[idx1.v_idx*3 + v]; } vCount[mm] +=3;
3251             for (int v = 0; v < 3; v++) { model.meshes[mm].vertices[vCount[mm] + v] = attrib.vertices[idx2.v_idx*3 + v]; } vCount[mm] +=3;
3252
3253             if (attrib.num_texcoords > 0)
3254             {
3255                 // Fill texcoords buffer (float) using vertex index of the face
3256                 // NOTE: Y-coordinate must be flipped upside-down to account for
3257                 // raylib's upside down textures...
3258                 model.meshes[mm].texcoords[vtCount[mm] + 0] = attrib.texcoords[idx0.vt_idx*2 + 0];
3259                 model.meshes[mm].texcoords[vtCount[mm] + 1] = 1.0f - attrib.texcoords[idx0.vt_idx*2 + 1]; vtCount[mm] += 2;
3260                 model.meshes[mm].texcoords[vtCount[mm] + 0] = attrib.texcoords[idx1.vt_idx*2 + 0];
3261                 model.meshes[mm].texcoords[vtCount[mm] + 1] = 1.0f - attrib.texcoords[idx1.vt_idx*2 + 1]; vtCount[mm] += 2;
3262                 model.meshes[mm].texcoords[vtCount[mm] + 0] = attrib.texcoords[idx2.vt_idx*2 + 0];
3263                 model.meshes[mm].texcoords[vtCount[mm] + 1] = 1.0f - attrib.texcoords[idx2.vt_idx*2 + 1]; vtCount[mm] += 2;
3264             }
3265
3266             if (attrib.num_normals > 0)
3267             {
3268                 // Fill normals buffer (float) using vertex index of the face
3269                 for (int v = 0; v < 3; v++) { model.meshes[mm].normals[vnCount[mm] + v] = attrib.normals[idx0.vn_idx*3 + v]; } vnCount[mm] +=3;
3270                 for (int v = 0; v < 3; v++) { model.meshes[mm].normals[vnCount[mm] + v] = attrib.normals[idx1.vn_idx*3 + v]; } vnCount[mm] +=3;
3271                 for (int v = 0; v < 3; v++) { model.meshes[mm].normals[vnCount[mm] + v] = attrib.normals[idx2.vn_idx*3 + v]; } vnCount[mm] +=3;
3272             }
3273         }
3274
3275         // Init model materials
3276         for (unsigned int m = 0; m < materialCount; m++)
3277         {
3278             // Init material to default
3279             // NOTE: Uses default shader, which only supports MATERIAL_MAP_DIFFUSE
3280             model.materials[m] = LoadMaterialDefault();
3281
3282             model.materials[m].maps[MATERIAL_MAP_DIFFUSE].texture = rlGetTextureDefault();     // Get default texture, in case no texture is defined
3283
3284             if (materials[m].diffuse_texname != NULL) model.materials[m].maps[MATERIAL_MAP_DIFFUSE].texture = LoadTexture(materials[m].diffuse_texname);  //char *diffuse_texname; // map_Kd
3285             else model.materials[m].maps[MATERIAL_MAP_DIFFUSE].texture = rlGetTextureDefault();
3286
3287             model.materials[m].maps[MATERIAL_MAP_DIFFUSE].color = (Color){ (unsigned char)(materials[m].diffuse[0]*255.0f), (unsigned char)(materials[m].diffuse[1]*255.0f), (unsigned char)(materials[m].diffuse[2]*255.0f), 255 }; //float diffuse[3];
3288             model.materials[m].maps[MATERIAL_MAP_DIFFUSE].value = 0.0f;
3289
3290             if (materials[m].specular_texname != NULL) model.materials[m].maps[MATERIAL_MAP_SPECULAR].texture = LoadTexture(materials[m].specular_texname);  //char *specular_texname; // map_Ks
3291             model.materials[m].maps[MATERIAL_MAP_SPECULAR].color = (Color){ (unsigned char)(materials[m].specular[0]*255.0f), (unsigned char)(materials[m].specular[1]*255.0f), (unsigned char)(materials[m].specular[2]*255.0f), 255 }; //float specular[3];
3292             model.materials[m].maps[MATERIAL_MAP_SPECULAR].value = 0.0f;
3293
3294             if (materials[m].bump_texname != NULL) model.materials[m].maps[MATERIAL_MAP_NORMAL].texture = LoadTexture(materials[m].bump_texname);  //char *bump_texname; // map_bump, bump
3295             model.materials[m].maps[MATERIAL_MAP_NORMAL].color = WHITE;
3296             model.materials[m].maps[MATERIAL_MAP_NORMAL].value = materials[m].shininess;
3297
3298             model.materials[m].maps[MATERIAL_MAP_EMISSION].color = (Color){ (unsigned char)(materials[m].emission[0]*255.0f), (unsigned char)(materials[m].emission[1]*255.0f), (unsigned char)(materials[m].emission[2]*255.0f), 255 }; //float emission[3];
3299
3300             if (materials[m].displacement_texname != NULL) model.materials[m].maps[MATERIAL_MAP_HEIGHT].texture = LoadTexture(materials[m].displacement_texname);  //char *displacement_texname; // disp
3301         }
3302
3303         tinyobj_attrib_free(&attrib);
3304         tinyobj_shapes_free(meshes, meshCount);
3305         tinyobj_materials_free(materials, materialCount);
3306
3307         RL_FREE(fileData);
3308         RL_FREE(matFaces);
3309
3310         RL_FREE(vCount);
3311         RL_FREE(vtCount);
3312         RL_FREE(vnCount);
3313         RL_FREE(faceCount);
3314
3315         if (CHDIR(currentDir) != 0)
3316         {
3317             TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to change working directory", currentDir);
3318         }
3319     }
3320
3321     return model;
3322 }
3323 #endif
3324
3325 #if defined(SUPPORT_FILEFORMAT_IQM)
3326 // Load IQM mesh data
3327 static Model LoadIQM(const char *fileName)
3328 {
3329     #define IQM_MAGIC     "INTERQUAKEMODEL" // IQM file magic number
3330     #define IQM_VERSION          2          // only IQM version 2 supported
3331
3332     #define BONE_NAME_LENGTH    32          // BoneInfo name string length
3333     #define MESH_NAME_LENGTH    32          // Mesh name string length
3334     #define MATERIAL_NAME_LENGTH 32         // Material name string length
3335
3336     unsigned int fileSize = 0;
3337     unsigned char *fileData = LoadFileData(fileName, &fileSize);
3338     unsigned char *fileDataPtr = fileData;
3339
3340     // IQM file structs
3341     //-----------------------------------------------------------------------------------
3342     typedef struct IQMHeader {
3343         char magic[16];
3344         unsigned int version;
3345         unsigned int filesize;
3346         unsigned int flags;
3347         unsigned int num_text, ofs_text;
3348         unsigned int num_meshes, ofs_meshes;
3349         unsigned int num_vertexarrays, num_vertexes, ofs_vertexarrays;
3350         unsigned int num_triangles, ofs_triangles, ofs_adjacency;
3351         unsigned int num_joints, ofs_joints;
3352         unsigned int num_poses, ofs_poses;
3353         unsigned int num_anims, ofs_anims;
3354         unsigned int num_frames, num_framechannels, ofs_frames, ofs_bounds;
3355         unsigned int num_comment, ofs_comment;
3356         unsigned int num_extensions, ofs_extensions;
3357     } IQMHeader;
3358
3359     typedef struct IQMMesh {
3360         unsigned int name;
3361         unsigned int material;
3362         unsigned int first_vertex, num_vertexes;
3363         unsigned int first_triangle, num_triangles;
3364     } IQMMesh;
3365
3366     typedef struct IQMTriangle {
3367         unsigned int vertex[3];
3368     } IQMTriangle;
3369
3370     typedef struct IQMJoint {
3371         unsigned int name;
3372         int parent;
3373         float translate[3], rotate[4], scale[3];
3374     } IQMJoint;
3375
3376     typedef struct IQMVertexArray {
3377         unsigned int type;
3378         unsigned int flags;
3379         unsigned int format;
3380         unsigned int size;
3381         unsigned int offset;
3382     } IQMVertexArray;
3383
3384     // NOTE: Below IQM structures are not used but listed for reference
3385     /*
3386     typedef struct IQMAdjacency {
3387         unsigned int triangle[3];
3388     } IQMAdjacency;
3389
3390     typedef struct IQMPose {
3391         int parent;
3392         unsigned int mask;
3393         float channeloffset[10];
3394         float channelscale[10];
3395     } IQMPose;
3396
3397     typedef struct IQMAnim {
3398         unsigned int name;
3399         unsigned int first_frame, num_frames;
3400         float framerate;
3401         unsigned int flags;
3402     } IQMAnim;
3403
3404     typedef struct IQMBounds {
3405         float bbmin[3], bbmax[3];
3406         float xyradius, radius;
3407     } IQMBounds;
3408     */
3409     //-----------------------------------------------------------------------------------
3410
3411     // IQM vertex data types
3412     enum {
3413         IQM_POSITION     = 0,
3414         IQM_TEXCOORD     = 1,
3415         IQM_NORMAL       = 2,
3416         IQM_TANGENT      = 3,       // NOTE: Tangents unused by default
3417         IQM_BLENDINDEXES = 4,
3418         IQM_BLENDWEIGHTS = 5,
3419         IQM_COLOR        = 6,       // NOTE: Vertex colors unused by default
3420         IQM_CUSTOM       = 0x10     // NOTE: Custom vertex values unused by default
3421     };
3422
3423     Model model = { 0 };
3424
3425     IQMMesh *imesh = NULL;
3426     IQMTriangle *tri = NULL;
3427     IQMVertexArray *va = NULL;
3428     IQMJoint *ijoint = NULL;
3429
3430     float *vertex = NULL;
3431     float *normal = NULL;
3432     float *text = NULL;
3433     char *blendi = NULL;
3434     unsigned char *blendw = NULL;
3435
3436     // In case file can not be read, return an empty model
3437     if (fileDataPtr == NULL) return model;
3438
3439     // Read IQM header
3440     IQMHeader *iqmHeader = (IQMHeader *)fileDataPtr;
3441
3442     if (memcmp(iqmHeader->magic, IQM_MAGIC, sizeof(IQM_MAGIC)) != 0)
3443     {
3444         TRACELOG(LOG_WARNING, "MODEL: [%s] IQM file is not a valid model", fileName);
3445         return model;
3446     }
3447
3448     if (iqmHeader->version != IQM_VERSION)
3449     {
3450         TRACELOG(LOG_WARNING, "MODEL: [%s] IQM file version not supported (%i)", fileName, iqmHeader->version);
3451         return model;
3452     }
3453
3454     //fileDataPtr += sizeof(IQMHeader);       // Move file data pointer
3455
3456     // Meshes data processing
3457     imesh = RL_MALLOC(sizeof(IQMMesh)*iqmHeader->num_meshes);
3458     //fseek(iqmFile, iqmHeader->ofs_meshes, SEEK_SET);
3459     //fread(imesh, sizeof(IQMMesh)*iqmHeader->num_meshes, 1, iqmFile);
3460     memcpy(imesh, fileDataPtr + iqmHeader->ofs_meshes, iqmHeader->num_meshes*sizeof(IQMMesh));
3461
3462     model.meshCount = iqmHeader->num_meshes;
3463     model.meshes = RL_CALLOC(model.meshCount, sizeof(Mesh));
3464
3465     model.materialCount = model.meshCount;
3466     model.materials = (Material *)RL_CALLOC(model.materialCount, sizeof(Material));
3467     model.meshMaterial = (int *)RL_CALLOC(model.meshCount, sizeof(int));
3468
3469     char name[MESH_NAME_LENGTH] = { 0 };
3470     char material[MATERIAL_NAME_LENGTH] = { 0 };
3471
3472     for (int i = 0; i < model.meshCount; i++)
3473     {
3474         //fseek(iqmFile, iqmHeader->ofs_text + imesh[i].name, SEEK_SET);
3475         //fread(name, sizeof(char)*MESH_NAME_LENGTH, 1, iqmFile);
3476         memcpy(name, fileDataPtr + iqmHeader->ofs_text + imesh[i].name, MESH_NAME_LENGTH*sizeof(char));
3477
3478         //fseek(iqmFile, iqmHeader->ofs_text + imesh[i].material, SEEK_SET);
3479         //fread(material, sizeof(char)*MATERIAL_NAME_LENGTH, 1, iqmFile);
3480         memcpy(material, fileDataPtr + iqmHeader->ofs_text + imesh[i].material, MATERIAL_NAME_LENGTH*sizeof(char));
3481
3482         model.materials[i] = LoadMaterialDefault();
3483
3484         TRACELOG(LOG_DEBUG, "MODEL: [%s] mesh name (%s), material (%s)", fileName, name, material);
3485
3486         model.meshes[i].vertexCount = imesh[i].num_vertexes;
3487
3488         model.meshes[i].vertices = RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float));       // Default vertex positions
3489         model.meshes[i].normals = RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float));        // Default vertex normals
3490         model.meshes[i].texcoords = RL_CALLOC(model.meshes[i].vertexCount*2, sizeof(float));      // Default vertex texcoords
3491
3492         model.meshes[i].boneIds = RL_CALLOC(model.meshes[i].vertexCount*4, sizeof(float));        // Up-to 4 bones supported!
3493         model.meshes[i].boneWeights = RL_CALLOC(model.meshes[i].vertexCount*4, sizeof(float));    // Up-to 4 bones supported!
3494
3495         model.meshes[i].triangleCount = imesh[i].num_triangles;
3496         model.meshes[i].indices = RL_CALLOC(model.meshes[i].triangleCount*3, sizeof(unsigned short));
3497
3498         // Animated verted data, what we actually process for rendering
3499         // NOTE: Animated vertex should be re-uploaded to GPU (if not using GPU skinning)
3500         model.meshes[i].animVertices = RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float));
3501         model.meshes[i].animNormals = RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float));
3502     }
3503
3504     // Triangles data processing
3505     tri = RL_MALLOC(iqmHeader->num_triangles*sizeof(IQMTriangle));
3506     //fseek(iqmFile, iqmHeader->ofs_triangles, SEEK_SET);
3507     //fread(tri, iqmHeader->num_triangles*sizeof(IQMTriangle), 1, iqmFile);
3508     memcpy(tri, fileDataPtr + iqmHeader->ofs_triangles, iqmHeader->num_triangles*sizeof(IQMTriangle));
3509
3510     for (int m = 0; m < model.meshCount; m++)
3511     {
3512         int tcounter = 0;
3513
3514         for (unsigned int i = imesh[m].first_triangle; i < (imesh[m].first_triangle + imesh[m].num_triangles); i++)
3515         {
3516             // IQM triangles indexes are stored in counter-clockwise, but raylib processes the index in linear order,
3517             // expecting they point to the counter-clockwise vertex triangle, so we need to reverse triangle indexes
3518             // NOTE: raylib renders vertex data in counter-clockwise order (standard convention) by default
3519             model.meshes[m].indices[tcounter + 2] = tri[i].vertex[0] - imesh[m].first_vertex;
3520             model.meshes[m].indices[tcounter + 1] = tri[i].vertex[1] - imesh[m].first_vertex;
3521             model.meshes[m].indices[tcounter] = tri[i].vertex[2] - imesh[m].first_vertex;
3522             tcounter += 3;
3523         }
3524     }
3525
3526     // Vertex arrays data processing
3527     va = RL_MALLOC(iqmHeader->num_vertexarrays*sizeof(IQMVertexArray));
3528     //fseek(iqmFile, iqmHeader->ofs_vertexarrays, SEEK_SET);
3529     //fread(va, iqmHeader->num_vertexarrays*sizeof(IQMVertexArray), 1, iqmFile);
3530     memcpy(va, fileDataPtr + iqmHeader->ofs_vertexarrays, iqmHeader->num_vertexarrays*sizeof(IQMVertexArray));
3531
3532     for (unsigned int i = 0; i < iqmHeader->num_vertexarrays; i++)
3533     {
3534         switch (va[i].type)
3535         {
3536             case IQM_POSITION:
3537             {
3538                 vertex = RL_MALLOC(iqmHeader->num_vertexes*3*sizeof(float));
3539                 //fseek(iqmFile, va[i].offset, SEEK_SET);
3540                 //fread(vertex, iqmHeader->num_vertexes*3*sizeof(float), 1, iqmFile);
3541                 memcpy(vertex, fileDataPtr + va[i].offset, iqmHeader->num_vertexes*3*sizeof(float));
3542
3543                 for (unsigned int m = 0; m < iqmHeader->num_meshes; m++)
3544                 {
3545                     int vCounter = 0;
3546                     for (unsigned int i = imesh[m].first_vertex*3; i < (imesh[m].first_vertex + imesh[m].num_vertexes)*3; i++)
3547                     {
3548                         model.meshes[m].vertices[vCounter] = vertex[i];
3549                         model.meshes[m].animVertices[vCounter] = vertex[i];
3550                         vCounter++;
3551                     }
3552                 }
3553             } break;
3554             case IQM_NORMAL:
3555             {
3556                 normal = RL_MALLOC(iqmHeader->num_vertexes*3*sizeof(float));
3557                 //fseek(iqmFile, va[i].offset, SEEK_SET);
3558                 //fread(normal, iqmHeader->num_vertexes*3*sizeof(float), 1, iqmFile);
3559                 memcpy(normal, fileDataPtr + va[i].offset, iqmHeader->num_vertexes*3*sizeof(float));
3560
3561                 for (unsigned int m = 0; m < iqmHeader->num_meshes; m++)
3562                 {
3563                     int vCounter = 0;
3564                     for (unsigned int i = imesh[m].first_vertex*3; i < (imesh[m].first_vertex + imesh[m].num_vertexes)*3; i++)
3565                     {
3566                         model.meshes[m].normals[vCounter] = normal[i];
3567                         model.meshes[m].animNormals[vCounter] = normal[i];
3568                         vCounter++;
3569                     }
3570                 }
3571             } break;
3572             case IQM_TEXCOORD:
3573             {
3574                 text = RL_MALLOC(iqmHeader->num_vertexes*2*sizeof(float));
3575                 //fseek(iqmFile, va[i].offset, SEEK_SET);
3576                 //fread(text, iqmHeader->num_vertexes*2*sizeof(float), 1, iqmFile);
3577                 memcpy(text, fileDataPtr + va[i].offset, iqmHeader->num_vertexes*2*sizeof(float));
3578
3579                 for (unsigned int m = 0; m < iqmHeader->num_meshes; m++)
3580                 {
3581                     int vCounter = 0;
3582                     for (unsigned int i = imesh[m].first_vertex*2; i < (imesh[m].first_vertex + imesh[m].num_vertexes)*2; i++)
3583                     {
3584                         model.meshes[m].texcoords[vCounter] = text[i];
3585                         vCounter++;
3586                     }
3587                 }
3588             } break;
3589             case IQM_BLENDINDEXES:
3590             {
3591                 blendi = RL_MALLOC(iqmHeader->num_vertexes*4*sizeof(char));
3592                 //fseek(iqmFile, va[i].offset, SEEK_SET);
3593                 //fread(blendi, iqmHeader->num_vertexes*4*sizeof(char), 1, iqmFile);
3594                 memcpy(blendi, fileDataPtr + va[i].offset, iqmHeader->num_vertexes*4*sizeof(char));
3595
3596                 for (unsigned int m = 0; m < iqmHeader->num_meshes; m++)
3597                 {
3598                     int boneCounter = 0;
3599                     for (unsigned int i = imesh[m].first_vertex*4; i < (imesh[m].first_vertex + imesh[m].num_vertexes)*4; i++)
3600                     {
3601                         model.meshes[m].boneIds[boneCounter] = blendi[i];
3602                         boneCounter++;
3603                     }
3604                 }
3605             } break;
3606             case IQM_BLENDWEIGHTS:
3607             {
3608                 blendw = RL_MALLOC(iqmHeader->num_vertexes*4*sizeof(unsigned char));
3609                 //fseek(iqmFile, va[i].offset, SEEK_SET);
3610                 //fread(blendw, iqmHeader->num_vertexes*4*sizeof(unsigned char), 1, iqmFile);
3611                 memcpy(blendw, fileDataPtr + va[i].offset, iqmHeader->num_vertexes*4*sizeof(unsigned char));
3612
3613                 for (unsigned int m = 0; m < iqmHeader->num_meshes; m++)
3614                 {
3615                     int boneCounter = 0;
3616                     for (unsigned int i = imesh[m].first_vertex*4; i < (imesh[m].first_vertex + imesh[m].num_vertexes)*4; i++)
3617                     {
3618                         model.meshes[m].boneWeights[boneCounter] = blendw[i]/255.0f;
3619                         boneCounter++;
3620                     }
3621                 }
3622             } break;
3623         }
3624     }
3625
3626     // Bones (joints) data processing
3627     ijoint = RL_MALLOC(iqmHeader->num_joints*sizeof(IQMJoint));
3628     //fseek(iqmFile, iqmHeader->ofs_joints, SEEK_SET);
3629     //fread(ijoint, iqmHeader->num_joints*sizeof(IQMJoint), 1, iqmFile);
3630     memcpy(ijoint, fileDataPtr + iqmHeader->ofs_joints, iqmHeader->num_joints*sizeof(IQMJoint));
3631
3632     model.boneCount = iqmHeader->num_joints;
3633     model.bones = RL_MALLOC(iqmHeader->num_joints*sizeof(BoneInfo));
3634     model.bindPose = RL_MALLOC(iqmHeader->num_joints*sizeof(Transform));
3635
3636     for (unsigned int i = 0; i < iqmHeader->num_joints; i++)
3637     {
3638         // Bones
3639         model.bones[i].parent = ijoint[i].parent;
3640         //fseek(iqmFile, iqmHeader->ofs_text + ijoint[i].name, SEEK_SET);
3641         //fread(model.bones[i].name, BONE_NAME_LENGTH*sizeof(char), 1, iqmFile);
3642         memcpy(model.bones[i].name, fileDataPtr + iqmHeader->ofs_text + ijoint[i].name, BONE_NAME_LENGTH*sizeof(char));
3643
3644         // Bind pose (base pose)
3645         model.bindPose[i].translation.x = ijoint[i].translate[0];
3646         model.bindPose[i].translation.y = ijoint[i].translate[1];
3647         model.bindPose[i].translation.z = ijoint[i].translate[2];
3648
3649         model.bindPose[i].rotation.x = ijoint[i].rotate[0];
3650         model.bindPose[i].rotation.y = ijoint[i].rotate[1];
3651         model.bindPose[i].rotation.z = ijoint[i].rotate[2];
3652         model.bindPose[i].rotation.w = ijoint[i].rotate[3];
3653
3654         model.bindPose[i].scale.x = ijoint[i].scale[0];
3655         model.bindPose[i].scale.y = ijoint[i].scale[1];
3656         model.bindPose[i].scale.z = ijoint[i].scale[2];
3657     }
3658
3659     // Build bind pose from parent joints
3660     for (int i = 0; i < model.boneCount; i++)
3661     {
3662         if (model.bones[i].parent >= 0)
3663         {
3664             model.bindPose[i].rotation = QuaternionMultiply(model.bindPose[model.bones[i].parent].rotation, model.bindPose[i].rotation);
3665             model.bindPose[i].translation = Vector3RotateByQuaternion(model.bindPose[i].translation, model.bindPose[model.bones[i].parent].rotation);
3666             model.bindPose[i].translation = Vector3Add(model.bindPose[i].translation, model.bindPose[model.bones[i].parent].translation);
3667             model.bindPose[i].scale = Vector3Multiply(model.bindPose[i].scale, model.bindPose[model.bones[i].parent].scale);
3668         }
3669     }
3670
3671     RL_FREE(fileData);
3672
3673     RL_FREE(imesh);
3674     RL_FREE(tri);
3675     RL_FREE(va);
3676     RL_FREE(vertex);
3677     RL_FREE(normal);
3678     RL_FREE(text);
3679     RL_FREE(blendi);
3680     RL_FREE(blendw);
3681     RL_FREE(ijoint);
3682
3683     return model;
3684 }
3685
3686 // Load IQM animation data
3687 static ModelAnimation* LoadIQMModelAnimations(const char* fileName, int* animCount)
3688 {
3689 #define IQM_MAGIC       "INTERQUAKEMODEL"   // IQM file magic number
3690 #define IQM_VERSION     2                   // only IQM version 2 supported
3691
3692     unsigned int fileSize = 0;
3693     unsigned char *fileData = LoadFileData(fileName, &fileSize);
3694     unsigned char *fileDataPtr = fileData;
3695
3696     typedef struct IQMHeader {
3697         char magic[16];
3698         unsigned int version;
3699         unsigned int filesize;
3700         unsigned int flags;
3701         unsigned int num_text, ofs_text;
3702         unsigned int num_meshes, ofs_meshes;
3703         unsigned int num_vertexarrays, num_vertexes, ofs_vertexarrays;
3704         unsigned int num_triangles, ofs_triangles, ofs_adjacency;
3705         unsigned int num_joints, ofs_joints;
3706         unsigned int num_poses, ofs_poses;
3707         unsigned int num_anims, ofs_anims;
3708         unsigned int num_frames, num_framechannels, ofs_frames, ofs_bounds;
3709         unsigned int num_comment, ofs_comment;
3710         unsigned int num_extensions, ofs_extensions;
3711     } IQMHeader;
3712
3713     typedef struct IQMPose {
3714         int parent;
3715         unsigned int mask;
3716         float channeloffset[10];
3717         float channelscale[10];
3718     } IQMPose;
3719
3720     typedef struct IQMAnim {
3721         unsigned int name;
3722         unsigned int first_frame, num_frames;
3723         float framerate;
3724         unsigned int flags;
3725     } IQMAnim;
3726
3727     // In case file can not be read, return an empty model
3728     if (fileDataPtr == NULL) return NULL;
3729
3730     // Read IQM header
3731     IQMHeader *iqmHeader = (IQMHeader *)fileDataPtr;
3732
3733     if (memcmp(iqmHeader->magic, IQM_MAGIC, sizeof(IQM_MAGIC)) != 0)
3734     {
3735         TRACELOG(LOG_WARNING, "MODEL: [%s] IQM file is not a valid model", fileName);
3736         return NULL;
3737     }
3738
3739     if (iqmHeader->version != IQM_VERSION)
3740     {
3741         TRACELOG(LOG_WARNING, "MODEL: [%s] IQM file version not supported (%i)", fileName, iqmHeader->version);
3742         return NULL;
3743     }
3744
3745     // Get bones data
3746     IQMPose *poses = RL_MALLOC(iqmHeader->num_poses*sizeof(IQMPose));
3747     //fseek(iqmFile, iqmHeader->ofs_poses, SEEK_SET);
3748     //fread(poses, iqmHeader->num_poses*sizeof(IQMPose), 1, iqmFile);
3749     memcpy(poses, fileDataPtr + iqmHeader->ofs_poses, iqmHeader->num_poses*sizeof(IQMPose));
3750
3751     // Get animations data
3752     *animCount = iqmHeader->num_anims;
3753     IQMAnim *anim = RL_MALLOC(iqmHeader->num_anims*sizeof(IQMAnim));
3754     //fseek(iqmFile, iqmHeader->ofs_anims, SEEK_SET);
3755     //fread(anim, iqmHeader->num_anims*sizeof(IQMAnim), 1, iqmFile);
3756     memcpy(anim, fileDataPtr + iqmHeader->ofs_anims, iqmHeader->num_anims*sizeof(IQMAnim));
3757
3758     ModelAnimation *animations = RL_MALLOC(iqmHeader->num_anims*sizeof(ModelAnimation));
3759
3760     // frameposes
3761     unsigned short *framedata = RL_MALLOC(iqmHeader->num_frames*iqmHeader->num_framechannels*sizeof(unsigned short));
3762     //fseek(iqmFile, iqmHeader->ofs_frames, SEEK_SET);
3763     //fread(framedata, iqmHeader->num_frames*iqmHeader->num_framechannels*sizeof(unsigned short), 1, iqmFile);
3764     memcpy(framedata, fileDataPtr + iqmHeader->ofs_frames, iqmHeader->num_frames*iqmHeader->num_framechannels*sizeof(unsigned short));
3765
3766     for (unsigned int a = 0; a < iqmHeader->num_anims; a++)
3767     {
3768         animations[a].frameCount = anim[a].num_frames;
3769         animations[a].boneCount = iqmHeader->num_poses;
3770         animations[a].bones = RL_MALLOC(iqmHeader->num_poses*sizeof(BoneInfo));
3771         animations[a].framePoses = RL_MALLOC(anim[a].num_frames*sizeof(Transform *));
3772         // animations[a].framerate = anim.framerate;     // TODO: Use framerate?
3773
3774         for (unsigned int j = 0; j < iqmHeader->num_poses; j++)
3775         {
3776             strcpy(animations[a].bones[j].name, "ANIMJOINTNAME");
3777             animations[a].bones[j].parent = poses[j].parent;
3778         }
3779
3780         for (unsigned int j = 0; j < anim[a].num_frames; j++) animations[a].framePoses[j] = RL_MALLOC(iqmHeader->num_poses*sizeof(Transform));
3781
3782         int dcounter = anim[a].first_frame*iqmHeader->num_framechannels;
3783
3784         for (unsigned int frame = 0; frame < anim[a].num_frames; frame++)
3785         {
3786             for (unsigned int i = 0; i < iqmHeader->num_poses; i++)
3787             {
3788                 animations[a].framePoses[frame][i].translation.x = poses[i].channeloffset[0];
3789
3790                 if (poses[i].mask & 0x01)
3791                 {
3792                     animations[a].framePoses[frame][i].translation.x += framedata[dcounter]*poses[i].channelscale[0];
3793                     dcounter++;
3794                 }
3795
3796                 animations[a].framePoses[frame][i].translation.y = poses[i].channeloffset[1];
3797
3798                 if (poses[i].mask & 0x02)
3799                 {
3800                     animations[a].framePoses[frame][i].translation.y += framedata[dcounter]*poses[i].channelscale[1];
3801                     dcounter++;
3802                 }
3803
3804                 animations[a].framePoses[frame][i].translation.z = poses[i].channeloffset[2];
3805
3806                 if (poses[i].mask & 0x04)
3807                 {
3808                     animations[a].framePoses[frame][i].translation.z += framedata[dcounter]*poses[i].channelscale[2];
3809                     dcounter++;
3810                 }
3811
3812                 animations[a].framePoses[frame][i].rotation.x = poses[i].channeloffset[3];
3813
3814                 if (poses[i].mask & 0x08)
3815                 {
3816                     animations[a].framePoses[frame][i].rotation.x += framedata[dcounter]*poses[i].channelscale[3];
3817                     dcounter++;
3818                 }
3819
3820                 animations[a].framePoses[frame][i].rotation.y = poses[i].channeloffset[4];
3821
3822                 if (poses[i].mask & 0x10)
3823                 {
3824                     animations[a].framePoses[frame][i].rotation.y += framedata[dcounter]*poses[i].channelscale[4];
3825                     dcounter++;
3826                 }
3827
3828                 animations[a].framePoses[frame][i].rotation.z = poses[i].channeloffset[5];
3829
3830                 if (poses[i].mask & 0x20)
3831                 {
3832                     animations[a].framePoses[frame][i].rotation.z += framedata[dcounter]*poses[i].channelscale[5];
3833                     dcounter++;
3834                 }
3835
3836                 animations[a].framePoses[frame][i].rotation.w = poses[i].channeloffset[6];
3837
3838                 if (poses[i].mask & 0x40)
3839                 {
3840                     animations[a].framePoses[frame][i].rotation.w += framedata[dcounter]*poses[i].channelscale[6];
3841                     dcounter++;
3842                 }
3843
3844                 animations[a].framePoses[frame][i].scale.x = poses[i].channeloffset[7];
3845
3846                 if (poses[i].mask & 0x80)
3847                 {
3848                     animations[a].framePoses[frame][i].scale.x += framedata[dcounter]*poses[i].channelscale[7];
3849                     dcounter++;
3850                 }
3851
3852                 animations[a].framePoses[frame][i].scale.y = poses[i].channeloffset[8];
3853
3854                 if (poses[i].mask & 0x100)
3855                 {
3856                     animations[a].framePoses[frame][i].scale.y += framedata[dcounter]*poses[i].channelscale[8];
3857                     dcounter++;
3858                 }
3859
3860                 animations[a].framePoses[frame][i].scale.z = poses[i].channeloffset[9];
3861
3862                 if (poses[i].mask & 0x200)
3863                 {
3864                     animations[a].framePoses[frame][i].scale.z += framedata[dcounter]*poses[i].channelscale[9];
3865                     dcounter++;
3866                 }
3867
3868                 animations[a].framePoses[frame][i].rotation = QuaternionNormalize(animations[a].framePoses[frame][i].rotation);
3869             }
3870         }
3871
3872         // Build frameposes
3873         for (unsigned int frame = 0; frame < anim[a].num_frames; frame++)
3874         {
3875             for (int i = 0; i < animations[a].boneCount; i++)
3876             {
3877                 if (animations[a].bones[i].parent >= 0)
3878                 {
3879                     animations[a].framePoses[frame][i].rotation = QuaternionMultiply(animations[a].framePoses[frame][animations[a].bones[i].parent].rotation, animations[a].framePoses[frame][i].rotation);
3880                     animations[a].framePoses[frame][i].translation = Vector3RotateByQuaternion(animations[a].framePoses[frame][i].translation, animations[a].framePoses[frame][animations[a].bones[i].parent].rotation);
3881                     animations[a].framePoses[frame][i].translation = Vector3Add(animations[a].framePoses[frame][i].translation, animations[a].framePoses[frame][animations[a].bones[i].parent].translation);
3882                     animations[a].framePoses[frame][i].scale = Vector3Multiply(animations[a].framePoses[frame][i].scale, animations[a].framePoses[frame][animations[a].bones[i].parent].scale);
3883                 }
3884             }
3885         }
3886     }
3887
3888     RL_FREE(fileData);
3889
3890     RL_FREE(framedata);
3891     RL_FREE(poses);
3892     RL_FREE(anim);
3893
3894     return animations;
3895 }
3896
3897 #endif
3898
3899 #if defined(SUPPORT_FILEFORMAT_GLTF)
3900
3901 static const unsigned char base64Table[] = {
3902     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3903     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3904     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3905     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3906     0, 0, 0, 62, 0, 0, 0, 63, 52, 53,
3907     54, 55, 56, 57, 58, 59, 60, 61, 0, 0,
3908     0, 0, 0, 0, 0, 0, 1, 2, 3, 4,
3909     5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
3910     15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
3911     25, 0, 0, 0, 0, 0, 0, 26, 27, 28,
3912     29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
3913     39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
3914     49, 50, 51
3915 };
3916
3917 static int GetSizeBase64(char *input)
3918 {
3919     int size = 0;
3920
3921     for (int i = 0; input[4*i] != 0; i++)
3922     {
3923         if (input[4*i + 3] == '=')
3924         {
3925             if (input[4*i + 2] == '=') size += 1;
3926             else size += 2;
3927         }
3928         else size += 3;
3929     }
3930
3931     return size;
3932 }
3933
3934 static unsigned char *DecodeBase64(char *input, int *size)
3935 {
3936     *size = GetSizeBase64(input);
3937
3938     unsigned char *buf = (unsigned char *)RL_MALLOC(*size);
3939     for (int i = 0; i < *size/3; i++)
3940     {
3941         unsigned char a = base64Table[(int)input[4*i]];
3942         unsigned char b = base64Table[(int)input[4*i + 1]];
3943         unsigned char c = base64Table[(int)input[4*i + 2]];
3944         unsigned char d = base64Table[(int)input[4*i + 3]];
3945
3946         buf[3*i] = (a << 2) | (b >> 4);
3947         buf[3*i + 1] = (b << 4) | (c >> 2);
3948         buf[3*i + 2] = (c << 6) | d;
3949     }
3950
3951     if (*size%3 == 1)
3952     {
3953         int n = *size/3;
3954         unsigned char a = base64Table[(int)input[4*n]];
3955         unsigned char b = base64Table[(int)input[4*n + 1]];
3956         buf[*size - 1] = (a << 2) | (b >> 4);
3957     }
3958     else if (*size%3 == 2)
3959     {
3960         int n = *size/3;
3961         unsigned char a = base64Table[(int)input[4*n]];
3962         unsigned char b = base64Table[(int)input[4*n + 1]];
3963         unsigned char c = base64Table[(int)input[4*n + 2]];
3964         buf[*size - 2] = (a << 2) | (b >> 4);
3965         buf[*size - 1] = (b << 4) | (c >> 2);
3966     }
3967     return buf;
3968 }
3969
3970 // Load texture from cgltf_image
3971 static Image LoadImageFromCgltfImage(cgltf_image *image, const char *texPath, Color tint)
3972 {
3973     Image rimage = { 0 };
3974
3975     if (image->uri)
3976     {
3977         if ((strlen(image->uri) > 5) &&
3978             (image->uri[0] == 'd') &&
3979             (image->uri[1] == 'a') &&
3980             (image->uri[2] == 't') &&
3981             (image->uri[3] == 'a') &&
3982             (image->uri[4] == ':'))
3983         {
3984             // Data URI
3985             // Format: data:<mediatype>;base64,<data>
3986
3987             // Find the comma
3988             int i = 0;
3989             while ((image->uri[i] != ',') && (image->uri[i] != 0)) i++;
3990
3991             if (image->uri[i] == 0) TRACELOG(LOG_WARNING, "IMAGE: glTF data URI is not a valid image");
3992             else
3993             {
3994                 int size = 0;
3995                 unsigned char *data = DecodeBase64(image->uri + i + 1, &size);
3996
3997                 int width, height;
3998                 unsigned char *raw = stbi_load_from_memory(data, size, &width, &height, NULL, 4);
3999                 RL_FREE(data);
4000
4001                 rimage.data = raw;
4002                 rimage.width = width;
4003                 rimage.height = height;
4004                 rimage.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
4005                 rimage.mipmaps = 1;
4006
4007                 // TODO: Tint shouldn't be applied here!
4008                 ImageColorTint(&rimage, tint);
4009             }
4010         }
4011         else
4012         {
4013             rimage = LoadImage(TextFormat("%s/%s", texPath, image->uri));
4014
4015             // TODO: Tint shouldn't be applied here!
4016             ImageColorTint(&rimage, tint);
4017         }
4018     }
4019     else if (image->buffer_view)
4020     {
4021         unsigned char *data = RL_MALLOC(image->buffer_view->size);
4022         int n = (int)image->buffer_view->offset;
4023         int stride = (int)image->buffer_view->stride ? (int)image->buffer_view->stride : 1;
4024
4025         for (unsigned int i = 0; i < image->buffer_view->size; i++)
4026         {
4027             data[i] = ((unsigned char *)image->buffer_view->buffer->data)[n];
4028             n += stride;
4029         }
4030
4031         int width, height;
4032         unsigned char *raw = stbi_load_from_memory(data, (int)image->buffer_view->size, &width, &height, NULL, 4);
4033         RL_FREE(data);
4034
4035         rimage.data = raw;
4036         rimage.width = width;
4037         rimage.height = height;
4038         rimage.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
4039         rimage.mipmaps = 1;
4040
4041         // TODO: Tint shouldn't be applied here!
4042         ImageColorTint(&rimage, tint);
4043     }
4044     else rimage = GenImageColor(1, 1, tint);
4045
4046     return rimage;
4047 }
4048
4049
4050 static bool GLTFReadValue(cgltf_accessor* acc, unsigned int index, void *variable, unsigned int elements, unsigned int size)
4051 {
4052     if (acc->count == 2)
4053     {
4054         if (index > 1) return false;
4055
4056         memcpy(variable, index == 0 ? acc->min : acc->max, elements*size);
4057         return true;
4058     }
4059
4060     unsigned int stride = size*elements;
4061     memset(variable, 0, stride);
4062
4063     if (acc->buffer_view == NULL || acc->buffer_view->buffer == NULL || acc->buffer_view->buffer->data == NULL) return false;
4064
4065     void* readPosition = ((char *)acc->buffer_view->buffer->data) + (index*stride) + acc->buffer_view->offset + acc->offset;
4066     memcpy(variable, readPosition, stride);
4067     return true;
4068 }
4069
4070 // LoadGLTF loads in model data from given filename, supporting both .gltf and .glb
4071 static Model LoadGLTF(const char *fileName)
4072 {
4073     /***********************************************************************************
4074
4075         Function implemented by Wilhem Barbier(@wbrbr), with modifications by Tyler Bezera(@gamerfiend) and Hristo Stamenov(@object71)
4076
4077         Features:
4078           - Supports .gltf and .glb files
4079           - Supports embedded (base64) or external textures
4080           - Loads all raylib supported material textures, values and colors
4081           - Supports multiple mesh per model and multiple primitives per model
4082
4083         Some restrictions (not exhaustive):
4084           - Triangle-only meshes
4085           - Not supported node hierarchies or transforms
4086           - Only supports unsigned short indices (no byte/unsigned int)
4087           - Only supports float for texture coordinates (no byte/unsigned short)
4088
4089     *************************************************************************************/
4090
4091     Model model = { 0 };
4092
4093     // glTF file loading
4094     unsigned int dataSize = 0;
4095     unsigned char *fileData = LoadFileData(fileName, &dataSize);
4096
4097     if (fileData == NULL) return model;
4098
4099     // glTF data loading
4100     cgltf_options options = { 0 };
4101     cgltf_data *data = NULL;
4102     cgltf_result result = cgltf_parse(&options, fileData, dataSize, &data);
4103
4104     if (result == cgltf_result_success)
4105     {
4106         TRACELOG(LOG_INFO, "MODEL: [%s] glTF meshes (%s) count: %i", fileName, (data->file_type == 2)? "glb" : "gltf", data->meshes_count);
4107         TRACELOG(LOG_INFO, "MODEL: [%s] glTF materials (%s) count: %i", fileName, (data->file_type == 2)? "glb" : "gltf", data->materials_count);
4108
4109         // Read data buffers
4110         result = cgltf_load_buffers(&options, data, fileName);
4111         if (result != cgltf_result_success) TRACELOG(LOG_INFO, "MODEL: [%s] Failed to load mesh/material buffers", fileName);
4112
4113         int primitivesCount = 0;
4114
4115         for (unsigned int i = 0; i < data->meshes_count; i++)
4116             primitivesCount += (int)data->meshes[i].primitives_count;
4117
4118         // Process glTF data and map to model
4119         model.meshCount = primitivesCount;
4120         model.meshes = RL_CALLOC(model.meshCount, sizeof(Mesh));
4121         model.materialCount = (int)data->materials_count + 1;
4122         model.materials = RL_MALLOC(model.materialCount*sizeof(Material));
4123         model.meshMaterial = RL_MALLOC(model.meshCount*sizeof(int));
4124         model.boneCount = (int)data->nodes_count;
4125         model.bones = RL_CALLOC(model.boneCount, sizeof(BoneInfo));
4126         model.bindPose = RL_CALLOC(model.boneCount, sizeof(Transform));
4127
4128         InitGLTFBones(&model, data);
4129         LoadGLTFMaterial(&model, fileName, data);
4130
4131         int primitiveIndex = 0;
4132
4133         for (unsigned int i = 0; i < data->meshes_count; i++)
4134         {
4135             for (unsigned int p = 0; p < data->meshes[i].primitives_count; p++)
4136             {
4137                 for (unsigned int j = 0; j < data->meshes[i].primitives[p].attributes_count; j++)
4138                 {
4139                     if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_position)
4140                     {
4141                         cgltf_accessor *acc = data->meshes[i].primitives[p].attributes[j].data;
4142                         model.meshes[primitiveIndex].vertexCount = (int)acc->count;
4143                         int bufferSize = model.meshes[primitiveIndex].vertexCount*3*sizeof(float);
4144                         model.meshes[primitiveIndex].vertices = RL_MALLOC(bufferSize);
4145                         model.meshes[primitiveIndex].animVertices = RL_MALLOC(bufferSize);
4146
4147                         if (acc->component_type == cgltf_component_type_r_32f)
4148                         {
4149                             for (int a = 0; a < acc->count; a++)
4150                             {
4151                                 GLTFReadValue(acc, a, model.meshes[primitiveIndex].vertices + (a*3), 3, sizeof(float));
4152                             }
4153                         }
4154                         else if (acc->component_type == cgltf_component_type_r_32u)
4155                         {
4156                             int readValue[3];
4157                             for (int a = 0; a < acc->count; a++)
4158                             {
4159                                 GLTFReadValue(acc, a, readValue, 3, sizeof(int));
4160                                 model.meshes[primitiveIndex].vertices[(a*3) + 0] = (float)readValue[0];
4161                                 model.meshes[primitiveIndex].vertices[(a*3) + 1] = (float)readValue[1];
4162                                 model.meshes[primitiveIndex].vertices[(a*3) + 2] = (float)readValue[2];
4163                             }
4164                         }
4165                         else
4166                         {
4167                             // TODO: Support normalized unsigned byte/unsigned short vertices
4168                             TRACELOG(LOG_WARNING, "MODEL: [%s] glTF vertices must be float or int", fileName);
4169                         }
4170
4171                         memcpy(model.meshes[primitiveIndex].animVertices, model.meshes[primitiveIndex].vertices, bufferSize);
4172                     }
4173                     else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_normal)
4174                     {
4175                         cgltf_accessor *acc = data->meshes[i].primitives[p].attributes[j].data;
4176
4177                         int bufferSize = (int)(acc->count*3*sizeof(float));
4178                         model.meshes[primitiveIndex].normals = RL_MALLOC(bufferSize);
4179                         model.meshes[primitiveIndex].animNormals = RL_MALLOC(bufferSize);
4180
4181                         if (acc->component_type == cgltf_component_type_r_32f)
4182                         {
4183                             for (int a = 0; a < acc->count; a++)
4184                             {
4185                                 GLTFReadValue(acc, a, model.meshes[primitiveIndex].normals + (a*3), 3, sizeof(float));
4186                             }
4187                         }
4188                         else if (acc->component_type == cgltf_component_type_r_32u)
4189                         {
4190                             int readValue[3];
4191                             for (int a = 0; a < acc->count; a++)
4192                             {
4193                                 GLTFReadValue(acc, a, readValue, 3, sizeof(int));
4194                                 model.meshes[primitiveIndex].normals[(a*3) + 0] = (float)readValue[0];
4195                                 model.meshes[primitiveIndex].normals[(a*3) + 1] = (float)readValue[1];
4196                                 model.meshes[primitiveIndex].normals[(a*3) + 2] = (float)readValue[2];
4197                             }
4198                         }
4199                         else
4200                         {
4201                             // TODO: Support normalized unsigned byte/unsigned short normals
4202                             TRACELOG(LOG_WARNING, "MODEL: [%s] glTF normals must be float or int", fileName);
4203                         }
4204
4205                         memcpy(model.meshes[primitiveIndex].animNormals, model.meshes[primitiveIndex].normals, bufferSize);
4206                     }
4207                     else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_texcoord)
4208                     {
4209                         cgltf_accessor *acc = data->meshes[i].primitives[p].attributes[j].data;
4210
4211                         if (acc->component_type == cgltf_component_type_r_32f)
4212                         {
4213                             model.meshes[primitiveIndex].texcoords = RL_MALLOC(acc->count*2*sizeof(float));
4214
4215                             for (int a = 0; a < acc->count; a++)
4216                             {
4217                                 GLTFReadValue(acc, a, model.meshes[primitiveIndex].texcoords + (a*2), 2, sizeof(float));
4218                             }
4219                         }
4220                         else
4221                         {
4222                             // TODO: Support normalized unsigned byte/unsigned short texture coordinates
4223                             TRACELOG(LOG_WARNING, "MODEL: [%s] glTF texture coordinates must be float", fileName);
4224                         }
4225                     }
4226                     else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_joints)
4227                     {
4228                         cgltf_accessor *acc = data->meshes[i].primitives[p].attributes[j].data;
4229                         LoadGLTFBoneAttribute(&model, acc, data, primitiveIndex);
4230                     }
4231                     else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_weights)
4232                     {
4233                         cgltf_accessor *acc = data->meshes[i].primitives[p].attributes[j].data;
4234
4235                         model.meshes[primitiveIndex].boneWeights = RL_MALLOC(acc->count*4*sizeof(float));
4236
4237                         if (acc->component_type == cgltf_component_type_r_32f)
4238                         {
4239                             for (int a = 0; a < acc->count; a++)
4240                             {
4241                                 GLTFReadValue(acc, a, model.meshes[primitiveIndex].boneWeights + (a*4), 4, sizeof(float));
4242                             }
4243                         }
4244                         else if (acc->component_type == cgltf_component_type_r_32u)
4245                         {
4246                             unsigned int readValue[4];
4247                             for (int a = 0; a < acc->count; a++)
4248                             {
4249                                 GLTFReadValue(acc, a, readValue, 4, sizeof(unsigned int));
4250                                 model.meshes[primitiveIndex].normals[(a*4) + 0] = (float)readValue[0];
4251                                 model.meshes[primitiveIndex].normals[(a*4) + 1] = (float)readValue[1];
4252                                 model.meshes[primitiveIndex].normals[(a*4) + 2] = (float)readValue[2];
4253                                 model.meshes[primitiveIndex].normals[(a*4) + 3] = (float)readValue[3];
4254                             }
4255                         }
4256                         else
4257                         {
4258                             // TODO: Support normalized unsigned byte/unsigned short weights
4259                             TRACELOG(LOG_WARNING, "MODEL: [%s] glTF normals must be float or int", fileName);
4260                         }
4261                     }
4262                 }
4263
4264                 cgltf_accessor *acc = data->meshes[i].primitives[p].indices;
4265                 LoadGLTFModelIndices(&model, acc, primitiveIndex);
4266
4267                 if (data->meshes[i].primitives[p].material)
4268                 {
4269                     // Compute the offset
4270                     model.meshMaterial[primitiveIndex] = (int)(data->meshes[i].primitives[p].material - data->materials);
4271                 }
4272                 else
4273                 {
4274                     model.meshMaterial[primitiveIndex] = model.materialCount - 1;
4275                 }
4276
4277                 BindGLTFPrimitiveToBones(&model, data, primitiveIndex);
4278
4279                 primitiveIndex++;
4280             }
4281
4282         }
4283
4284         cgltf_free(data);
4285     }
4286     else TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to load glTF data", fileName);
4287
4288     RL_FREE(fileData);
4289
4290     return model;
4291 }
4292
4293 static void InitGLTFBones(Model* model, const cgltf_data* data)
4294 {
4295     for (unsigned int j = 0; j < data->nodes_count; j++)
4296     {
4297         strcpy(model->bones[j].name, data->nodes[j].name == 0 ? "ANIMJOINT" : data->nodes[j].name);
4298         model->bones[j].parent = (data->nodes[j].parent != NULL) ? (int)(data->nodes[j].parent - data->nodes) : -1;
4299     }
4300
4301     for (unsigned int i = 0; i < data->nodes_count; i++)
4302     {
4303         if (data->nodes[i].has_translation) memcpy(&model->bindPose[i].translation, data->nodes[i].translation, 3*sizeof(float));
4304         else model->bindPose[i].translation = Vector3Zero();
4305
4306         if (data->nodes[i].has_rotation) memcpy(&model->bindPose[i].rotation, data->nodes[i].rotation, 4*sizeof(float));
4307         else model->bindPose[i].rotation = QuaternionIdentity();
4308
4309         model->bindPose[i].rotation = QuaternionNormalize(model->bindPose[i].rotation);
4310
4311         if (data->nodes[i].has_scale) memcpy(&model->bindPose[i].scale, data->nodes[i].scale, 3*sizeof(float));
4312         else model->bindPose[i].scale = Vector3One();
4313     }
4314
4315     {
4316         bool* completedBones = RL_CALLOC(model->boneCount, sizeof(bool));
4317         int numberCompletedBones = 0;
4318
4319         while (numberCompletedBones < model->boneCount) {
4320             for (int i = 0; i < model->boneCount; i++)
4321             {
4322                 if (completedBones[i]) continue;
4323
4324                 if (model->bones[i].parent < 0) {
4325                     completedBones[i] = true;
4326                     numberCompletedBones++;
4327                     continue;
4328                 }
4329
4330                 if (!completedBones[model->bones[i].parent]) continue;
4331
4332                 Transform* currentTransform = &model->bindPose[i];
4333                 BoneInfo* currentBone = &model->bones[i];
4334                 int root = currentBone->parent;
4335                 if (root >= model->boneCount)
4336                     root = 0;
4337                 Transform* parentTransform = &model->bindPose[root];
4338
4339                 currentTransform->rotation = QuaternionMultiply(parentTransform->rotation, currentTransform->rotation);
4340                 currentTransform->translation = Vector3RotateByQuaternion(currentTransform->translation, parentTransform->rotation);
4341                 currentTransform->translation = Vector3Add(currentTransform->translation, parentTransform->translation);
4342                 currentTransform->scale = Vector3Multiply(currentTransform->scale, parentTransform->scale);
4343                 completedBones[i] = true;
4344                 numberCompletedBones++;
4345             }
4346         }
4347
4348         RL_FREE(completedBones);
4349     }
4350 }
4351
4352 static void LoadGLTFMaterial(Model* model, const char* fileName, const cgltf_data* data)
4353 {
4354     for (int i = 0; i < model->materialCount - 1; i++)
4355     {
4356         model->materials[i] = LoadMaterialDefault();
4357         Color tint = (Color){ 255, 255, 255, 255 };
4358         const char *texPath = GetDirectoryPath(fileName);
4359
4360         // Ensure material follows raylib support for PBR (metallic/roughness flow)
4361         if (data->materials[i].has_pbr_metallic_roughness)
4362         {
4363             tint.r = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[0]*255);
4364             tint.g = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[1]*255);
4365             tint.b = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[2]*255);
4366             tint.a = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[3]*255);
4367
4368             model->materials[i].maps[MATERIAL_MAP_ALBEDO].color = tint;
4369
4370             if (data->materials[i].pbr_metallic_roughness.base_color_texture.texture)
4371             {
4372                 Image albedo = LoadImageFromCgltfImage(data->materials[i].pbr_metallic_roughness.base_color_texture.texture->image, texPath, tint);
4373                 model->materials[i].maps[MATERIAL_MAP_ALBEDO].texture = LoadTextureFromImage(albedo);
4374                 UnloadImage(albedo);
4375             }
4376
4377             tint = WHITE;   // Set tint to white after it's been used by Albedo
4378
4379             if (data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.texture)
4380             {
4381                 Image metallicRoughness = LoadImageFromCgltfImage(data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.texture->image, texPath, tint);
4382                 model->materials[i].maps[MATERIAL_MAP_ROUGHNESS].texture = LoadTextureFromImage(metallicRoughness);
4383
4384                 float roughness = data->materials[i].pbr_metallic_roughness.roughness_factor;
4385                 model->materials[i].maps[MATERIAL_MAP_ROUGHNESS].value = roughness;
4386
4387                 float metallic = data->materials[i].pbr_metallic_roughness.metallic_factor;
4388                 model->materials[i].maps[MATERIAL_MAP_METALNESS].value = metallic;
4389
4390                 UnloadImage(metallicRoughness);
4391             }
4392
4393             if (data->materials[i].normal_texture.texture)
4394             {
4395                 Image normalImage = LoadImageFromCgltfImage(data->materials[i].normal_texture.texture->image, texPath, tint);
4396                 model->materials[i].maps[MATERIAL_MAP_NORMAL].texture = LoadTextureFromImage(normalImage);
4397                 UnloadImage(normalImage);
4398             }
4399
4400             if (data->materials[i].occlusion_texture.texture)
4401             {
4402                 Image occulsionImage = LoadImageFromCgltfImage(data->materials[i].occlusion_texture.texture->image, texPath, tint);
4403                 model->materials[i].maps[MATERIAL_MAP_OCCLUSION].texture = LoadTextureFromImage(occulsionImage);
4404                 UnloadImage(occulsionImage);
4405             }
4406
4407             if (data->materials[i].emissive_texture.texture)
4408             {
4409                 Image emissiveImage = LoadImageFromCgltfImage(data->materials[i].emissive_texture.texture->image, texPath, tint);
4410                 model->materials[i].maps[MATERIAL_MAP_EMISSION].texture = LoadTextureFromImage(emissiveImage);
4411                 tint.r = (unsigned char)(data->materials[i].emissive_factor[0]*255);
4412                 tint.g = (unsigned char)(data->materials[i].emissive_factor[1]*255);
4413                 tint.b = (unsigned char)(data->materials[i].emissive_factor[2]*255);
4414                 model->materials[i].maps[MATERIAL_MAP_EMISSION].color = tint;
4415                 UnloadImage(emissiveImage);
4416             }
4417         }
4418     }
4419
4420     model->materials[model->materialCount - 1] = LoadMaterialDefault();
4421 }
4422
4423 static void LoadGLTFBoneAttribute(Model* model, cgltf_accessor* jointsAccessor, const cgltf_data* data, int primitiveIndex)
4424 {
4425     if (jointsAccessor->component_type == cgltf_component_type_r_16u)
4426     {
4427         model->meshes[primitiveIndex].boneIds = RL_MALLOC(sizeof(int)*jointsAccessor->count*4);
4428         short* bones = RL_MALLOC(sizeof(short)*jointsAccessor->count*4);
4429
4430         for (int a = 0; a < jointsAccessor->count; a++)
4431         {
4432             GLTFReadValue(jointsAccessor, a, bones + (a*4), 4, sizeof(short));
4433         }
4434
4435         for (unsigned int a = 0; a < jointsAccessor->count*4; a++)
4436         {
4437             cgltf_node* skinJoint = data->skins->joints[bones[a]];
4438
4439             for (unsigned int k = 0; k < data->nodes_count; k++)
4440             {
4441                 if (&(data->nodes[k]) == skinJoint)
4442                 {
4443                     model->meshes[primitiveIndex].boneIds[a] = k;
4444                     break;
4445                 }
4446             }
4447         }
4448         RL_FREE(bones);
4449     }
4450     else if (jointsAccessor->component_type == cgltf_component_type_r_8u)
4451     {
4452         model->meshes[primitiveIndex].boneIds = RL_MALLOC(sizeof(int)*jointsAccessor->count*4);
4453         unsigned char* bones = RL_MALLOC(sizeof(unsigned char)*jointsAccessor->count*4);
4454
4455         for (int a = 0; a < jointsAccessor->count; a++)
4456         {
4457             GLTFReadValue(jointsAccessor, a, bones + (a*4), 4, sizeof(unsigned char));
4458         }
4459
4460         for (unsigned int a = 0; a < jointsAccessor->count*4; a++)
4461         {
4462             cgltf_node* skinJoint = data->skins->joints[bones[a]];
4463
4464             for (unsigned int k = 0; k < data->nodes_count; k++)
4465             {
4466                 if (&(data->nodes[k]) == skinJoint)
4467                 {
4468                     model->meshes[primitiveIndex].boneIds[a] = k;
4469                     break;
4470                 }
4471             }
4472         }
4473         RL_FREE(bones);
4474     }
4475     else
4476     {
4477         // TODO: Support other size of bone index?
4478         TRACELOG(LOG_WARNING, "MODEL: glTF bones in unexpected format");
4479     }
4480 }
4481
4482 static void BindGLTFPrimitiveToBones(Model* model, const cgltf_data* data, int primitiveIndex)
4483 {
4484     if (model->meshes[primitiveIndex].boneIds == NULL && data->nodes_count > 0)
4485     {
4486         for (int nodeId = 0; nodeId < data->nodes_count; nodeId++)
4487         {
4488             if (data->nodes[nodeId].mesh == &(data->meshes[primitiveIndex]))
4489             {
4490                 model->meshes[primitiveIndex].boneIds = RL_CALLOC(4*model->meshes[primitiveIndex].vertexCount, sizeof(int));
4491                 model->meshes[primitiveIndex].boneWeights = RL_CALLOC(4*model->meshes[primitiveIndex].vertexCount, sizeof(float));
4492
4493                 for (int b = 0; b < 4*model->meshes[primitiveIndex].vertexCount; b++)
4494                 {
4495                     if (b%4 == 0)
4496                     {
4497                         model->meshes[primitiveIndex].boneIds[b] = nodeId;
4498                         model->meshes[primitiveIndex].boneWeights[b] = 1.0f;
4499                     }
4500                     else
4501                     {
4502                         model->meshes[primitiveIndex].boneIds[b] = 0;
4503                         model->meshes[primitiveIndex].boneWeights[b] = 0.0f;
4504                     }
4505
4506                 }
4507
4508                 Vector3 boundVertex = { 0 };
4509                 Vector3 boundNormal = { 0 };
4510
4511                 Vector3 outTranslation = { 0 };
4512                 Quaternion outRotation = { 0 };
4513                 Vector3 outScale = { 0 };
4514
4515                 int vCounter = 0;
4516                 int boneCounter = 0;
4517                 int boneId = 0;
4518
4519                 for (int i = 0; i < model->meshes[primitiveIndex].vertexCount; i++)
4520                 {
4521                     boneId = model->meshes[primitiveIndex].boneIds[boneCounter];
4522                     outTranslation = model->bindPose[boneId].translation;
4523                     outRotation = model->bindPose[boneId].rotation;
4524                     outScale = model->bindPose[boneId].scale;
4525
4526                     // Vertices processing
4527                     boundVertex = (Vector3){ model->meshes[primitiveIndex].vertices[vCounter], model->meshes[primitiveIndex].vertices[vCounter + 1], model->meshes[primitiveIndex].vertices[vCounter + 2] };
4528                     boundVertex = Vector3Multiply(boundVertex, outScale);
4529                     boundVertex = Vector3RotateByQuaternion(boundVertex, outRotation);
4530                     boundVertex = Vector3Add(boundVertex, outTranslation);
4531                     model->meshes[primitiveIndex].vertices[vCounter] = boundVertex.x;
4532                     model->meshes[primitiveIndex].vertices[vCounter + 1] = boundVertex.y;
4533                     model->meshes[primitiveIndex].vertices[vCounter + 2] = boundVertex.z;
4534
4535                     // Normals processing
4536                     if (model->meshes[primitiveIndex].normals != NULL)
4537                     {
4538                         boundNormal = (Vector3){ model->meshes[primitiveIndex].normals[vCounter], model->meshes[primitiveIndex].normals[vCounter + 1], model->meshes[primitiveIndex].normals[vCounter + 2] };
4539                         boundNormal = Vector3RotateByQuaternion(boundNormal, outRotation);
4540                         model->meshes[primitiveIndex].normals[vCounter] = boundNormal.x;
4541                         model->meshes[primitiveIndex].normals[vCounter + 1] = boundNormal.y;
4542                         model->meshes[primitiveIndex].normals[vCounter + 2] = boundNormal.z;
4543                     }
4544
4545                     vCounter += 3;
4546                     boneCounter += 4;
4547                 }
4548             }
4549         }
4550     }
4551 }
4552
4553 static void LoadGLTFModelIndices(Model* model, cgltf_accessor* indexAccessor, int primitiveIndex)
4554 {
4555     if (indexAccessor)
4556     {
4557         if (indexAccessor->component_type == cgltf_component_type_r_16u || indexAccessor->component_type == cgltf_component_type_r_16)
4558         {
4559             model->meshes[primitiveIndex].triangleCount = (int)indexAccessor->count/3;
4560             model->meshes[primitiveIndex].indices = RL_MALLOC(model->meshes[primitiveIndex].triangleCount*3*sizeof(unsigned short));
4561
4562             unsigned short readValue = 0;
4563             for (int a = 0; a < indexAccessor->count; a++)
4564             {
4565                 GLTFReadValue(indexAccessor, a, &readValue, 1, sizeof(short));
4566                 model->meshes[primitiveIndex].indices[a] = readValue;
4567             }
4568         }
4569         else if (indexAccessor->component_type == cgltf_component_type_r_8u || indexAccessor->component_type == cgltf_component_type_r_8)
4570         {
4571             model->meshes[primitiveIndex].triangleCount = (int)indexAccessor->count/3;
4572             model->meshes[primitiveIndex].indices = RL_MALLOC(model->meshes[primitiveIndex].triangleCount*3*sizeof(unsigned short));
4573
4574             unsigned char readValue = 0;
4575             for (int a = 0; a < indexAccessor->count; a++)
4576             {
4577                 GLTFReadValue(indexAccessor, a, &readValue, 1, sizeof(char));
4578                 model->meshes[primitiveIndex].indices[a] = (unsigned short)readValue;
4579             }
4580         }
4581         else if (indexAccessor->component_type == cgltf_component_type_r_32u)
4582         {
4583             model->meshes[primitiveIndex].triangleCount = (int)indexAccessor->count/3;
4584             model->meshes[primitiveIndex].indices = RL_MALLOC(model->meshes[primitiveIndex].triangleCount*3*sizeof(unsigned short));
4585
4586             unsigned int readValue;
4587             for (int a = 0; a < indexAccessor->count; a++)
4588             {
4589                 GLTFReadValue(indexAccessor, a, &readValue, 1, sizeof(unsigned int));
4590                 model->meshes[primitiveIndex].indices[a] = (unsigned short)readValue;
4591             }
4592         }
4593     }
4594     else
4595     {
4596         // Unindexed mesh
4597         model->meshes[primitiveIndex].triangleCount = model->meshes[primitiveIndex].vertexCount/3;
4598     }
4599 }
4600
4601 // LoadGLTF loads in animation data from given filename
4602 static ModelAnimation *LoadGLTFModelAnimations(const char *fileName, int *animCount)
4603 {
4604     /***********************************************************************************
4605
4606         Function implemented by Hristo Stamenov (@object71)
4607
4608         Features:
4609           - Supports .gltf and .glb files
4610
4611         Some restrictions (not exhaustive):
4612           - ...
4613
4614     *************************************************************************************/
4615
4616     // glTF file loading
4617     unsigned int dataSize = 0;
4618     unsigned char *fileData = LoadFileData(fileName, &dataSize);
4619
4620     ModelAnimation *animations = NULL;
4621
4622     if (fileData == NULL) return animations;
4623
4624     // glTF data loading
4625     cgltf_options options = { 0 };
4626     cgltf_data *data = NULL;
4627     cgltf_result result = cgltf_parse(&options, fileData, dataSize, &data);
4628
4629     if (result == cgltf_result_success)
4630     {
4631         TRACELOG(LOG_INFO, "MODEL: [%s] glTF animations (%s) count: %i", fileName, (data->file_type == 2)? "glb" :
4632         "gltf", data->animations_count);
4633
4634         result = cgltf_load_buffers(&options, data, fileName);
4635         if (result != cgltf_result_success) TRACELOG(LOG_WARNING, "MODEL: [%s] unable to load glTF animations data", fileName);
4636         animations = RL_MALLOC(data->animations_count*sizeof(ModelAnimation));
4637         *animCount = (int)data->animations_count;
4638
4639         for (unsigned int a = 0; a < data->animations_count; a++)
4640         {
4641             // gltf animation consists of the following structures:
4642             // - nodes - bones
4643             // - channels - single transformation type on a single bone
4644             //     - node - bone
4645             //     - transformation type (path) - translation, rotation, scale
4646             //     - sampler - animation samples
4647             //         - input - points in time this transformation happens
4648             //         - output - the transformation amount at the given input points in time
4649             //         - interpolation - the type of interpolation to use between the frames
4650
4651             cgltf_animation *animation = data->animations + a;
4652
4653             ModelAnimation *output = animations + a;
4654
4655             // 30 frames sampled per second
4656             const float timeStep = (1.0f/30.0f);
4657             float animationDuration = 0.0f;
4658
4659             // Getting the max animation time to consider for animation duration
4660             for (unsigned int i = 0; i < animation->channels_count; i++)
4661             {
4662                 cgltf_animation_channel* channel = animation->channels + i;
4663                 int frameCounts = (int)channel->sampler->input->count;
4664                 float lastFrameTime = 0.0f;
4665
4666                 if (GLTFReadValue(channel->sampler->input, frameCounts - 1, &lastFrameTime, 1, sizeof(float)))
4667                 {
4668                     animationDuration = fmaxf(lastFrameTime, animationDuration);
4669                 }
4670             }
4671
4672             output->frameCount = (int)(animationDuration / timeStep);
4673             output->boneCount = (int)data->nodes_count;
4674             output->bones = RL_MALLOC(output->boneCount*sizeof(BoneInfo));
4675             output->framePoses = RL_MALLOC(output->frameCount*sizeof(Transform *));
4676             // output->framerate = // TODO: Use framerate instead of const timestep
4677
4678             // Name and parent bones
4679             for (unsigned int j = 0; j < data->nodes_count; j++)
4680             {
4681                 strcpy(output->bones[j].name, data->nodes[j].name == 0 ? "ANIMJOINT" : data->nodes[j].name);
4682                 output->bones[j].parent = (data->nodes[j].parent != NULL) ? (int)(data->nodes[j].parent - data->nodes) : -1;
4683             }
4684
4685             // Allocate data for frames
4686             // Initiate with zero bone translations
4687             for (int frame = 0; frame < output->frameCount; frame++)
4688             {
4689                 output->framePoses[frame] = RL_MALLOC(output->frameCount*data->nodes_count*sizeof(Transform));
4690
4691                 for (unsigned int i = 0; i < data->nodes_count; i++)
4692                 {
4693                     output->framePoses[frame][i].translation = Vector3Zero();
4694                     output->framePoses[frame][i].rotation = QuaternionIdentity();
4695                     output->framePoses[frame][i].rotation = QuaternionNormalize(output->framePoses[frame][i].rotation);
4696                     output->framePoses[frame][i].scale = Vector3One();
4697                 }
4698             }
4699
4700             // for each single transformation type on single bone
4701             for (unsigned int channelId = 0; channelId < animation->channels_count; channelId++)
4702             {
4703                 cgltf_animation_channel* channel = animation->channels + channelId;
4704                 cgltf_animation_sampler* sampler = channel->sampler;
4705
4706                 int boneId = (int)(channel->target_node - data->nodes);
4707
4708                 for (int frame = 0; frame < output->frameCount; frame++)
4709                 {
4710                     bool shouldSkipFurtherTransformation = true;
4711                     int outputMin = 0;
4712                     int outputMax = 0;
4713                     float frameTime = frame*timeStep;
4714                     float lerpPercent = 0.0f;
4715
4716                     // For this transformation:
4717                     // getting between which input values the current frame time position
4718                     // and also what is the percent to use in the linear interpolation later
4719                     for (unsigned int j = 0; j < sampler->input->count; j++)
4720                     {
4721                         float inputFrameTime;
4722                         if (GLTFReadValue(sampler->input, j, &inputFrameTime, 1, sizeof(float)))
4723                         {
4724                             if (frameTime < inputFrameTime)
4725                             {
4726                                 shouldSkipFurtherTransformation = false;
4727                                 outputMin = (j == 0) ? 0 : j - 1;
4728                                 outputMax = j;
4729
4730                                 float previousInputTime = 0.0f;
4731                                 if (GLTFReadValue(sampler->input, outputMin, &previousInputTime, 1, sizeof(float)))
4732                                 {
4733                                     if ((inputFrameTime - previousInputTime) != 0)
4734                                     {
4735                                         lerpPercent = (frameTime - previousInputTime)/(inputFrameTime - previousInputTime);
4736                                     }
4737                                 }
4738
4739                                 break;
4740                             }
4741                         }
4742                         else break;
4743                     }
4744
4745                     // If the current transformation has no information for the current frame time point
4746                     if (shouldSkipFurtherTransformation) continue;
4747
4748                     if (channel->target_path == cgltf_animation_path_type_translation)
4749                     {
4750                         Vector3 translationStart;
4751                         Vector3 translationEnd;
4752
4753                         bool success = GLTFReadValue(sampler->output, outputMin, &translationStart, 3, sizeof(float));
4754                         success = GLTFReadValue(sampler->output, outputMax, &translationEnd, 3, sizeof(float)) || success;
4755
4756                         if (success) output->framePoses[frame][boneId].translation = Vector3Lerp(translationStart, translationEnd, lerpPercent);
4757                     }
4758                     if (channel->target_path == cgltf_animation_path_type_rotation)
4759                     {
4760                         Quaternion rotationStart;
4761                         Quaternion rotationEnd;
4762
4763                         bool success = GLTFReadValue(sampler->output, outputMin, &rotationStart, 4, sizeof(float));
4764                         success = GLTFReadValue(sampler->output, outputMax, &rotationEnd, 4, sizeof(float)) || success;
4765
4766                         if (success)
4767                         {
4768                             output->framePoses[frame][boneId].rotation = QuaternionLerp(rotationStart, rotationEnd, lerpPercent);
4769                             output->framePoses[frame][boneId].rotation = QuaternionNormalize(output->framePoses[frame][boneId].rotation);
4770                         }
4771                     }
4772                     if (channel->target_path == cgltf_animation_path_type_scale)
4773                     {
4774                         Vector3 scaleStart;
4775                         Vector3 scaleEnd;
4776
4777                         bool success = GLTFReadValue(sampler->output, outputMin, &scaleStart, 3, sizeof(float));
4778                         success = GLTFReadValue(sampler->output, outputMax, &scaleEnd, 3, sizeof(float)) || success;
4779
4780                         if (success) output->framePoses[frame][boneId].scale = Vector3Lerp(scaleStart, scaleEnd, lerpPercent);
4781                     }
4782                 }
4783             }
4784
4785             // Build frameposes
4786             for (int frame = 0; frame < output->frameCount; frame++)
4787             {
4788                 bool *completedBones = RL_CALLOC(output->boneCount, sizeof(bool));
4789                 int numberCompletedBones = 0;
4790
4791                 while (numberCompletedBones < output->boneCount)
4792                 {
4793                     for (int i = 0; i < output->boneCount; i++)
4794                     {
4795                         if (completedBones[i]) continue;
4796
4797                         if (output->bones[i].parent < 0)
4798                         {
4799                             completedBones[i] = true;
4800                             numberCompletedBones++;
4801                             continue;
4802                         }
4803
4804                         if (!completedBones[output->bones[i].parent]) continue;
4805
4806                         output->framePoses[frame][i].rotation = QuaternionMultiply(output->framePoses[frame][output->bones[i].parent].rotation, output->framePoses[frame][i].rotation);
4807                         output->framePoses[frame][i].translation = Vector3RotateByQuaternion(output->framePoses[frame][i].translation, output->framePoses[frame][output->bones[i].parent].rotation);
4808                         output->framePoses[frame][i].translation = Vector3Add(output->framePoses[frame][i].translation, output->framePoses[frame][output->bones[i].parent].translation);
4809                         output->framePoses[frame][i].scale = Vector3Multiply(output->framePoses[frame][i].scale, output->framePoses[frame][output->bones[i].parent].scale);
4810                         completedBones[i] = true;
4811                         numberCompletedBones++;
4812                     }
4813                 }
4814
4815                 RL_FREE(completedBones);
4816             }
4817
4818         }
4819
4820         cgltf_free(data);
4821     }
4822     else TRACELOG(LOG_WARNING, ": [%s] Failed to load glTF data", fileName);
4823
4824     RL_FREE(fileData);
4825
4826     return animations;
4827 }
4828
4829 #endif