summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorraysan5 <[email protected]>2021-10-18 14:11:56 +0200
committerraysan5 <[email protected]>2021-10-18 14:11:56 +0200
commit6ac3043e881dc8e2ea80792903871f87e73faca3 (patch)
tree55cb5abfbd65fcd46c3514bf9d46c357fd171238
parent2ec8ce649ad0c33e71e084d17b5ddea72d58ca40 (diff)
downloadraylib-6ac3043e881dc8e2ea80792903871f87e73faca3.tar.gz
raylib-6ac3043e881dc8e2ea80792903871f87e73faca3.zip
WARNING: REMOVED: glTF loading
Actually, it was broken and it that code has no maintainer.
-rw-r--r--src/rmodels.c1202
1 files changed, 6 insertions, 1196 deletions
diff --git a/src/rmodels.c b/src/rmodels.c
index 2042195f..bb07412c 100644
--- a/src/rmodels.c
+++ b/src/rmodels.c
@@ -132,16 +132,7 @@ static ModelAnimation *LoadModelAnimationsIQM(const char *fileName, unsigned int
#endif
#if defined(SUPPORT_FILEFORMAT_GLTF)
static Model LoadGLTF(const char *fileName); // Load GLTF mesh data
-static ModelAnimation *LoadGLTFModelAnimations(const char *fileName, unsigned int *animCount); // Load GLTF animation data
-static void LoadGLTFMaterial(Model *model, const char *fileName, const cgltf_data *data);
-static void LoadGLTFMesh(cgltf_data *data, cgltf_node *node, Model *outModel, Matrix currentTransform, int *primitiveIndex, const char *fileName);
-static void LoadGLTFNode(cgltf_data *data, cgltf_node *node, Model *outModel, Matrix currentTransform, int *primitiveIndex, const char *fileName);
-static void InitGLTFBones(Model *model, const cgltf_data *data);
-static void BindGLTFPrimitiveToBones(Model *model, cgltf_node *node, const cgltf_data *data, int primitiveIndex);
-static void GetGLTFPrimitiveCount(cgltf_node *node, int *outCount);
-static bool ReadGLTFValue(cgltf_accessor *acc, unsigned int index, void *variable);
-static void *ReadGLTFValuesAs(cgltf_accessor *acc, cgltf_component_type type, bool adjustOnDownCasting);
-static Matrix GetNodeTransformationMatrix(cgltf_node *node, Matrix current);
+//static ModelAnimation *LoadModelAnimationGLTF(const char *fileName, unsigned int *animCount); // Load GLTF animation data
#endif
#if defined(SUPPORT_FILEFORMAT_VOX)
static Model LoadVOX(const char *filename); // Load VOX mesh data
@@ -1812,7 +1803,7 @@ ModelAnimation *LoadModelAnimations(const char *fileName, unsigned int *animCoun
if (IsFileExtension(fileName, ".iqm")) animations = LoadModelAnimationsIQM(fileName, animCount);
#endif
#if defined(SUPPORT_FILEFORMAT_GLTF)
- if (IsFileExtension(fileName, ".gltf;.glb")) animations = LoadGLTFModelAnimations(fileName, animCount);
+ //if (IsFileExtension(fileName, ".gltf;.glb")) animations = LoadModelAnimationGLTF(fileName, animCount);
#endif
return animations;
@@ -4503,573 +4494,6 @@ static ModelAnimation* LoadModelAnimationsIQM(const char *fileName, unsigned int
#endif
#if defined(SUPPORT_FILEFORMAT_GLTF)
-// Encode data to Base64 string
-char *EncodeBase64(const unsigned char *data, int inputLength, int *outputLength)
-{
- static const unsigned char base64encodeTable[] = {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
- 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
- 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
- };
-
- static const int modTable[] = { 0, 2, 1 };
-
- *outputLength = 4*((inputLength + 2)/3);
-
- char *encodedData = RL_MALLOC(*outputLength);
-
- if (encodedData == NULL) return NULL;
-
- for (int i = 0, j = 0; i < inputLength;)
- {
- unsigned int octetA = (i < inputLength)? (unsigned char)data[i++] : 0;
- unsigned int octetB = (i < inputLength)? (unsigned char)data[i++] : 0;
- unsigned int octetC = (i < inputLength)? (unsigned char)data[i++] : 0;
-
- unsigned int triple = (octetA << 0x10) + (octetB << 0x08) + octetC;
-
- encodedData[j++] = base64encodeTable[(triple >> 3*6) & 0x3F];
- encodedData[j++] = base64encodeTable[(triple >> 2*6) & 0x3F];
- encodedData[j++] = base64encodeTable[(triple >> 1*6) & 0x3F];
- encodedData[j++] = base64encodeTable[(triple >> 0*6) & 0x3F];
- }
-
- for (int i = 0; i < modTable[inputLength%3]; i++) encodedData[*outputLength - 1 - i] = '=';
-
- return encodedData;
-}
-
-// Decode Base64 string data
-static unsigned char *DecodeBase64(char *data, int *outputLength)
-{
- static const unsigned char base64decodeTable[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
- 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
- 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
- };
-
- // Get output size of Base64 input data
- int outLength = 0;
- for (int i = 0; data[4*i] != 0; i++)
- {
- if (data[4*i + 3] == '=')
- {
- if (data[4*i + 2] == '=') outLength += 1;
- else outLength += 2;
- }
- else outLength += 3;
- }
-
- // Allocate memory to store decoded Base64 data
- unsigned char *decodedData = (unsigned char *)RL_MALLOC(outLength);
-
- for (int i = 0; i < outLength/3; i++)
- {
- unsigned char a = base64decodeTable[(int)data[4*i]];
- unsigned char b = base64decodeTable[(int)data[4*i + 1]];
- unsigned char c = base64decodeTable[(int)data[4*i + 2]];
- unsigned char d = base64decodeTable[(int)data[4*i + 3]];
-
- decodedData[3*i] = (a << 2) | (b >> 4);
- decodedData[3*i + 1] = (b << 4) | (c >> 2);
- decodedData[3*i + 2] = (c << 6) | d;
- }
-
- if (outLength%3 == 1)
- {
- int n = outLength/3;
- unsigned char a = base64decodeTable[(int)data[4*n]];
- unsigned char b = base64decodeTable[(int)data[4*n + 1]];
- decodedData[outLength - 1] = (a << 2) | (b >> 4);
- }
- else if (outLength%3 == 2)
- {
- int n = outLength/3;
- unsigned char a = base64decodeTable[(int)data[4*n]];
- unsigned char b = base64decodeTable[(int)data[4*n + 1]];
- unsigned char c = base64decodeTable[(int)data[4*n + 2]];
- decodedData[outLength - 2] = (a << 2) | (b >> 4);
- decodedData[outLength - 1] = (b << 4) | (c >> 2);
- }
-
- *outputLength = outLength;
- return decodedData;
-}
-
-// Load texture from cgltf_image
-static Image LoadImageFromCgltfImage(cgltf_image *image, const char *texPath, Color tint)
-{
- Image rimage = { 0 };
-
- if (image->uri)
- {
- if ((strlen(image->uri) > 5) &&
- (image->uri[0] == 'd') &&
- (image->uri[1] == 'a') &&
- (image->uri[2] == 't') &&
- (image->uri[3] == 'a') &&
- (image->uri[4] == ':'))
- {
- // Data URI
- // Format: data:<mediatype>;base64,<data>
-
- // Find the comma
- int i = 0;
- while ((image->uri[i] != ',') && (image->uri[i] != 0)) i++;
-
- if (image->uri[i] == 0) TRACELOG(LOG_WARNING, "IMAGE: glTF data URI is not a valid image");
- else
- {
- //cgltf_result cgltf_load_buffer_base64(const cgltf_options* options, cgltf_size size, const char* base64, void** out_data)
-
- int size = 0;
- unsigned char *data = DecodeBase64(image->uri + i + 1, &size); // TODO: Use cgltf_load_buffer_base64()
-
- rimage = LoadImageFromMemory(".png", data, size);
- RL_FREE(data);
-
- // TODO: Tint shouldn't be applied here!
- ImageColorTint(&rimage, tint);
- }
- }
- else
- {
- rimage = LoadImage(TextFormat("%s/%s", texPath, image->uri));
-
- // TODO: Tint shouldn't be applied here!
- ImageColorTint(&rimage, tint);
- }
- }
- else if (image->buffer_view)
- {
- unsigned char *data = RL_MALLOC(image->buffer_view->size);
- int n = (int)image->buffer_view->offset;
- int stride = (int)image->buffer_view->stride ? (int)image->buffer_view->stride : 1;
-
- for (unsigned int i = 0; i < image->buffer_view->size; i++)
- {
- data[i] = ((unsigned char *)image->buffer_view->buffer->data)[n];
- n += stride;
- }
-
- rimage = LoadImageFromMemory(".png", data, (int)image->buffer_view->size);
- RL_FREE(data);
-
- // TODO: Tint shouldn't be applied here!
- ImageColorTint(&rimage, tint);
- }
- else rimage = GenImageColor(1, 1, tint);
-
- return rimage;
-}
-
-//
-static bool ReadGLTFValue(cgltf_accessor *acc, unsigned int index, void *variable)
-{
- unsigned int typeElements = 0;
-
- switch (acc->type)
- {
- case cgltf_type_scalar: typeElements = 1; break;
- case cgltf_type_vec2: typeElements = 2; break;
- case cgltf_type_vec3: typeElements = 3; break;
- case cgltf_type_vec4:
- case cgltf_type_mat2: typeElements = 4; break;
- case cgltf_type_mat3: typeElements = 9; break;
- case cgltf_type_mat4: typeElements = 16; break;
- case cgltf_type_invalid: typeElements = 0; break;
- default: break;
- }
-
- unsigned int typeSize = 0;
-
- switch (acc->component_type)
- {
- case cgltf_component_type_r_8u:
- case cgltf_component_type_r_8: typeSize = 1; break;
- case cgltf_component_type_r_16u:
- case cgltf_component_type_r_16: typeSize = 2; break;
- case cgltf_component_type_r_32f:
- case cgltf_component_type_r_32u: typeSize = 4; break;
- case cgltf_component_type_invalid: typeSize = 0; break;
- default: break;
- }
-
- unsigned int singleElementSize = typeSize*typeElements;
-
- if (acc->count == 2)
- {
- if (index > 1) return false;
-
- memcpy(variable, index == 0 ? acc->min : acc->max, singleElementSize);
- return true;
- }
-
- memset(variable, 0, singleElementSize);
-
- if (acc->buffer_view == NULL || acc->buffer_view->buffer == NULL || acc->buffer_view->buffer->data == NULL) return false;
-
- if (!acc->buffer_view->stride)
- {
- void *readPosition = ((char *)acc->buffer_view->buffer->data) + (index*singleElementSize) + acc->buffer_view->offset + acc->offset;
- memcpy(variable, readPosition, singleElementSize);
- }
- else
- {
- void *readPosition = ((char *)acc->buffer_view->buffer->data) + (index*acc->buffer_view->stride) + acc->buffer_view->offset + acc->offset;
- memcpy(variable, readPosition, singleElementSize);
- }
-
- return true;
-}
-
-static void *ReadGLTFValuesAs(cgltf_accessor *acc, cgltf_component_type type, bool adjustOnDownCasting)
-{
- unsigned int count = acc->count;
- unsigned int typeSize = 0;
- switch (type)
- {
- case cgltf_component_type_r_8u:
- case cgltf_component_type_r_8: typeSize = 1; break;
- case cgltf_component_type_r_16u:
- case cgltf_component_type_r_16: typeSize = 2; break;
- case cgltf_component_type_r_32f:
- case cgltf_component_type_r_32u: typeSize = 4; break;
- case cgltf_component_type_invalid: typeSize = 0; break;
- default: break;
- }
-
- unsigned int typeElements = 0;
- switch (acc->type)
- {
- case cgltf_type_scalar: typeElements = 1; break;
- case cgltf_type_vec2: typeElements = 2; break;
- case cgltf_type_vec3: typeElements = 3; break;
- case cgltf_type_vec4:
- case cgltf_type_mat2: typeElements = 4; break;
- case cgltf_type_mat3: typeElements = 9; break;
- case cgltf_type_mat4: typeElements = 16; break;
- case cgltf_type_invalid: typeElements = 0; break;
- default: break;
- }
-
- if (acc->component_type == type)
- {
- void *array = RL_MALLOC(count*typeElements*typeSize);
-
- for (unsigned int i = 0; i < count; i++) ReadGLTFValue(acc, i, (char *)array + i*typeElements*typeSize);
-
- return array;
-
- }
- else
- {
- unsigned int accTypeSize = 0;
- switch (acc->component_type)
- {
- case cgltf_component_type_r_8u:
- case cgltf_component_type_r_8: accTypeSize = 1; break;
- case cgltf_component_type_r_16u:
- case cgltf_component_type_r_16: accTypeSize = 2; break;
- case cgltf_component_type_r_32f:
- case cgltf_component_type_r_32u: accTypeSize = 4; break;
- case cgltf_component_type_invalid: accTypeSize = 0; break;
- default: break;
- }
-
- void *array = RL_MALLOC(count*typeElements*typeSize);
- void *additionalArray = RL_MALLOC(count*typeElements*accTypeSize);
-
- for (unsigned int i = 0; i < count; i++)
- {
- ReadGLTFValue(acc, i, (char *)additionalArray + i*typeElements*accTypeSize);
- }
-
- switch (acc->component_type)
- {
- case cgltf_component_type_r_8u:
- {
- unsigned char *typedAdditionalArray = (unsigned char *)additionalArray;
- switch (type)
- {
- case cgltf_component_type_r_8:
- {
- char *typedArray = (char *)array;
- for (unsigned int i = 0; i < count*typeElements; i++)
- {
- if (adjustOnDownCasting) typedArray[i] = (char)(typedAdditionalArray[i]/(UCHAR_MAX/CHAR_MAX));
- else typedArray[i] = (char)typedAdditionalArray[i];
- }
-
- } break;
- case cgltf_component_type_r_16u:
- {
- unsigned short *typedArray = (unsigned short *)array;
- for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (unsigned short)typedAdditionalArray[i];
- } break;
- case cgltf_component_type_r_16:
- {
- short *typedArray = (short *)array;
- for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (short)typedAdditionalArray[i];
- } break;
- case cgltf_component_type_r_32f:
- {
- float *typedArray = (float *)array;
- for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (float)typedAdditionalArray[i];
- } break;
- case cgltf_component_type_r_32u:
- {
- unsigned int *typedArray = (unsigned int *)array;
- for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (unsigned int)typedAdditionalArray[i];
- } break;
- default:
- {
- RL_FREE(array);
- RL_FREE(additionalArray);
- return NULL;
- } break;
- }
- } break;
- case cgltf_component_type_r_8:
- {
- char *typedAdditionalArray = (char *)additionalArray;
- switch (type)
- {
- case cgltf_component_type_r_8u:
- {
- unsigned char *typedArray = (unsigned char *)array;
- for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (unsigned char)typedAdditionalArray[i];
- } break;
- case cgltf_component_type_r_16u:
- {
- unsigned short *typedArray = (unsigned short *)array;
- for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (unsigned short)typedAdditionalArray[i];
- } break;
- case cgltf_component_type_r_16:
- {
- short *typedArray = (short *)array;
- for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (short)typedAdditionalArray[i];
- } break;
- case cgltf_component_type_r_32f:
- {
- float *typedArray = (float *)array;
- for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (float)typedAdditionalArray[i];
- } break;
- case cgltf_component_type_r_32u:
- {
- unsigned int *typedArray = (unsigned int *)array;
- for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (unsigned int)typedAdditionalArray[i];
- } break;
- default:
- {
- RL_FREE(array);
- RL_FREE(additionalArray);
- return NULL;
- } break;
- }
- } break;
- case cgltf_component_type_r_16u:
- {
- unsigned short *typedAdditionalArray = (unsigned short *)additionalArray;
- switch (type)
- {
- case cgltf_component_type_r_8u:
- {
- unsigned char *typedArray = (unsigned char *)array;
- for (unsigned int i = 0; i < count*typeElements; i++)
- {
- if (adjustOnDownCasting) typedArray[i] = (unsigned char)(typedAdditionalArray[i]/(USHRT_MAX/UCHAR_MAX));
- else typedArray[i] = (unsigned char)typedAdditionalArray[i];
- }
- } break;
- case cgltf_component_type_r_8:
- {
- char *typedArray = (char *) array;
- for (unsigned int i = 0; i < count*typeElements; i++)
- {
- if (adjustOnDownCasting) typedArray[i] = (char)(typedAdditionalArray[i]/(USHRT_MAX/CHAR_MAX));
- else typedArray[i] = (char)typedAdditionalArray[i];
- }
- } break;
- case cgltf_component_type_r_16:
- {
- short *typedArray = (short *)array;
- for (unsigned int i = 0; i < count*typeElements; i++)
- {
- if (adjustOnDownCasting) typedArray[i] = (short)(typedAdditionalArray[i]/(USHRT_MAX/SHRT_MAX));
- else typedArray[i] = (short)typedAdditionalArray[i];
- }
- } break;
- case cgltf_component_type_r_32f:
- {
- float *typedArray = (float *)array;
- for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (float)typedAdditionalArray[i];
- } break;
- case cgltf_component_type_r_32u:
- {
- unsigned int *typedArray = (unsigned int *)array;
- for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (unsigned int)typedAdditionalArray[i];
- } break;
- default:
- {
- RL_FREE(array);
- RL_FREE(additionalArray);
- return NULL;
- } break;
- }
- } break;
- case cgltf_component_type_r_16:
- {
- short *typedAdditionalArray = (short *)additionalArray;
- switch (type)
- {
- case cgltf_component_type_r_8u:
- {
- unsigned char *typedArray = (unsigned char *)array;
- for (unsigned int i = 0; i < count*typeElements; i++)
- {
- if (adjustOnDownCasting) typedArray[i] = (unsigned char)(typedAdditionalArray[i]/(SHRT_MAX/UCHAR_MAX));
- else typedArray[i] = (unsigned char)typedAdditionalArray[i];
- }
- } break;
- case cgltf_component_type_r_8:
- {
- char *typedArray = (char *)array;
- for (unsigned int i = 0; i < count*typeElements; i++)
- {
- if (adjustOnDownCasting) typedArray[i] = (char)(typedAdditionalArray[i]/(SHRT_MAX/CHAR_MAX));
- else typedArray[i] = (char)typedAdditionalArray[i];
- }
- } break;
- case cgltf_component_type_r_16u:
- {
- unsigned short *typedArray = (unsigned short *)array;
- for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (unsigned short)typedAdditionalArray[i];
- } break;
- case cgltf_component_type_r_32f:
- {
- float *typedArray = (float *)array;
- for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (float)typedAdditionalArray[i];
- } break;
- case cgltf_component_type_r_32u:
- {
- unsigned int *typedArray = (unsigned int *)array;
- for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (unsigned int)typedAdditionalArray[i];
- } break;
- default:
- {
- RL_FREE(array);
- RL_FREE(additionalArray);
- return NULL;
- } break;
- }
- } break;
- case cgltf_component_type_r_32f:
- {
- float *typedAdditionalArray = (float *)additionalArray;
- switch (type)
- {
- case cgltf_component_type_r_8u:
- {
- unsigned char *typedArray = (unsigned char *)array;
- for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (unsigned char)typedAdditionalArray[i];
- } break;
- case cgltf_component_type_r_8:
- {
- char *typedArray = (char *)array;
- for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (char)typedAdditionalArray[i];
- } break;
- case cgltf_component_type_r_16u:
- {
- unsigned short *typedArray = (unsigned short *)array;
- for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (unsigned short)typedAdditionalArray[i];
- } break;
- case cgltf_component_type_r_16:
- {
- short *typedArray = (short *)array;
- for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (short)typedAdditionalArray[i];
- } break;
- case cgltf_component_type_r_32u:
- {
- unsigned int *typedArray = (unsigned int *)array;
- for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (unsigned int)typedAdditionalArray[i];
- } break;
- default:
- {
- RL_FREE(array);
- RL_FREE(additionalArray);
- return NULL;
- } break;
- }
- } break;
- case cgltf_component_type_r_32u:
- {
- unsigned int *typedAdditionalArray = (unsigned int *)additionalArray;
- switch (type)
- {
- case cgltf_component_type_r_8u:
- {
- unsigned char *typedArray = (unsigned char *)array;
- for (unsigned int i = 0; i < count*typeElements; i++)
- {
- if (adjustOnDownCasting) typedArray[i] = (unsigned char)(typedAdditionalArray[i]/(UINT_MAX/UCHAR_MAX));
- else typedArray[i] = (unsigned char)typedAdditionalArray[i];
- }
- } break;
- case cgltf_component_type_r_8:
- {
- char *typedArray = (char *)array;
- for (unsigned int i = 0; i < count*typeElements; i++)
- {
- if (adjustOnDownCasting) typedArray[i] = (char)(typedAdditionalArray[i]/(UINT_MAX/CHAR_MAX));
- else typedArray[i] = (char)typedAdditionalArray[i];
- }
- } break;
- case cgltf_component_type_r_16u:
- {
- unsigned short *typedArray = (unsigned short *)array;
- for (unsigned int i = 0; i < count*typeElements; i++)
- {
- if (adjustOnDownCasting) typedArray[i] = (unsigned short)(typedAdditionalArray[i]/(UINT_MAX/USHRT_MAX));
- else typedArray[i] = (unsigned short)typedAdditionalArray[i];
- }
- } break;
- case cgltf_component_type_r_16:
- {
- short *typedArray = (short *)array;
- for (unsigned int i = 0; i < count*typeElements; i++)
- {
- if (adjustOnDownCasting) typedArray[i] = (short)(typedAdditionalArray[i]/(UINT_MAX/SHRT_MAX));
- else typedArray[i] = (short)typedAdditionalArray[i];
- }
- } break;
- case cgltf_component_type_r_32f:
- {
- float *typedArray = (float *)array;
- for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (float)typedAdditionalArray[i];
- } break;
- default:
- {
- RL_FREE(array);
- RL_FREE(additionalArray);
- return NULL;
- } break;
- }
- } break;
- default:
- {
- RL_FREE(array);
- RL_FREE(additionalArray);
- return NULL;
- } break;
- }
-
- RL_FREE(additionalArray);
- return array;
- }
-}
-
// LoadGLTF loads in model data from given filename, supporting both .gltf and .glb
static Model LoadGLTF(const char *fileName)
{
@@ -5118,7 +4542,7 @@ static Model LoadGLTF(const char *fileName)
int primitiveCount = 0;
for (unsigned int i = 0; i < gltfData->scene->nodes_count; i++)
{
- GetGLTFPrimitiveCount(gltfData->scene->nodes[i], &primitiveCount); // TODO: Recursive function, really needed?
+ //GetGLTFPrimitiveCount(gltfData->scene->nodes[i], &primitiveCount); // TODO: Recursive function, really needed?
}
// Process glTF data and map to model
@@ -5131,14 +4555,14 @@ static Model LoadGLTF(const char *fileName)
model.bones = RL_CALLOC(model.boneCount, sizeof(BoneInfo));
model.bindPose = RL_CALLOC(model.boneCount, sizeof(Transform));
- InitGLTFBones(&model, gltfData);
- LoadGLTFMaterial(&model, fileName, gltfData);
+ //InitGLTFBones(&model, gltfData);
+ //LoadGLTFMaterial(&model, fileName, gltfData);
int primitiveIndex = 0;
for (unsigned int i = 0; i < gltfData->scene->nodes_count; i++)
{
Matrix staticTransform = MatrixIdentity();
- LoadGLTFNode(gltfData, gltfData->scene->nodes[i], &model, staticTransform, &primitiveIndex, fileName); // TODO: Recursive function, really needed?
+ //LoadGLTFNode(gltfData, gltfData->scene->nodes[i], &model, staticTransform, &primitiveIndex, fileName); // TODO: Recursive function, really needed?
}
cgltf_free(gltfData);
@@ -5149,620 +4573,6 @@ static Model LoadGLTF(const char *fileName)
return model;
}
-
-static void InitGLTFBones(Model *model, const cgltf_data *data)
-{
- for (unsigned int j = 0; j < data->nodes_count; j++)
- {
- strcpy(model->bones[j].name, data->nodes[j].name == 0 ? "ANIMJOINT" : data->nodes[j].name);
- model->bones[j].parent = (data->nodes[j].parent != NULL) ? (int)(data->nodes[j].parent - data->nodes) : -1;
- }
-
- for (unsigned int i = 0; i < data->nodes_count; i++)
- {
- if (data->nodes[i].has_translation) memcpy(&model->bindPose[i].translation, data->nodes[i].translation, 3*sizeof(float));
- else model->bindPose[i].translation = Vector3Zero();
-
- if (data->nodes[i].has_rotation) memcpy(&model->bindPose[i].rotation, data->nodes[i].rotation, 4*sizeof(float));
- else model->bindPose[i].rotation = QuaternionIdentity();
-
- model->bindPose[i].rotation = QuaternionNormalize(model->bindPose[i].rotation);
-
- if (data->nodes[i].has_scale) memcpy(&model->bindPose[i].scale, data->nodes[i].scale, 3*sizeof(float));
- else model->bindPose[i].scale = Vector3One();
- }
-
- {
- bool *completedBones = RL_CALLOC(model->boneCount, sizeof(bool));
- int numberCompletedBones = 0;
-
- while (numberCompletedBones < model->boneCount)
- {
- for (int i = 0; i < model->boneCount; i++)
- {
- if (completedBones[i]) continue;
-
- if (model->bones[i].parent < 0)
- {
- completedBones[i] = true;
- numberCompletedBones++;
- continue;
- }
-
- if (!completedBones[model->bones[i].parent]) continue;
-
- Transform* currentTransform = &model->bindPose[i];
- BoneInfo* currentBone = &model->bones[i];
- int root = currentBone->parent;
- if (root >= model->boneCount) root = 0;
- Transform* parentTransform = &model->bindPose[root];
-
- currentTransform->rotation = QuaternionMultiply(parentTransform->rotation, currentTransform->rotation);
- currentTransform->translation = Vector3RotateByQuaternion(currentTransform->translation, parentTransform->rotation);
- currentTransform->translation = Vector3Add(currentTransform->translation, parentTransform->translation);
- currentTransform->scale = Vector3Multiply(currentTransform->scale, parentTransform->scale);
- completedBones[i] = true;
- numberCompletedBones++;
- }
- }
-
- RL_FREE(completedBones);
- }
-}
-
-static void LoadGLTFMaterial(Model *model, const char *fileName, const cgltf_data *data)
-{
- for (int i = 0; i < model->materialCount - 1; i++)
- {
- model->materials[i] = LoadMaterialDefault();
- Color tint = (Color){ 255, 255, 255, 255 };
- const char *texPath = GetDirectoryPath(fileName);
-
- // Ensure material follows raylib support for PBR (metallic/roughness flow)
- if (data->materials[i].has_pbr_metallic_roughness)
- {
- tint.r = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[0]*255);
- tint.g = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[1]*255);
- tint.b = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[2]*255);
- tint.a = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[3]*255);
-
- model->materials[i].maps[MATERIAL_MAP_ALBEDO].color = tint;
-
- if (data->materials[i].pbr_metallic_roughness.base_color_texture.texture)
- {
- Image albedo = LoadImageFromCgltfImage(data->materials[i].pbr_metallic_roughness.base_color_texture.texture->image, texPath, tint);
- model->materials[i].maps[MATERIAL_MAP_ALBEDO].texture = LoadTextureFromImage(albedo);
- UnloadImage(albedo);
- }
-
- tint = WHITE; // Set tint to white after it's been used by Albedo
-
- if (data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.texture)
- {
- Image metallicRoughness = LoadImageFromCgltfImage(data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.texture->image, texPath, tint);
- model->materials[i].maps[MATERIAL_MAP_ROUGHNESS].texture = LoadTextureFromImage(metallicRoughness);
-
- float roughness = data->materials[i].pbr_metallic_roughness.roughness_factor;
- model->materials[i].maps[MATERIAL_MAP_ROUGHNESS].value = roughness;
-
- float metallic = data->materials[i].pbr_metallic_roughness.metallic_factor;
- model->materials[i].maps[MATERIAL_MAP_METALNESS].value = metallic;
-
- UnloadImage(metallicRoughness);
- }
-
- if (data->materials[i].normal_texture.texture)
- {
- Image normalImage = LoadImageFromCgltfImage(data->materials[i].normal_texture.texture->image, texPath, tint);
- model->materials[i].maps[MATERIAL_MAP_NORMAL].texture = LoadTextureFromImage(normalImage);
- UnloadImage(normalImage);
- }
-
- if (data->materials[i].occlusion_texture.texture)
- {
- Image occulsionImage = LoadImageFromCgltfImage(data->materials[i].occlusion_texture.texture->image, texPath, tint);
- model->materials[i].maps[MATERIAL_MAP_OCCLUSION].texture = LoadTextureFromImage(occulsionImage);
- UnloadImage(occulsionImage);
- }
-
- if (data->materials[i].emissive_texture.texture)
- {
- Image emissiveImage = LoadImageFromCgltfImage(data->materials[i].emissive_texture.texture->image, texPath, tint);
- model->materials[i].maps[MATERIAL_MAP_EMISSION].texture = LoadTextureFromImage(emissiveImage);
- tint.r = (unsigned char)(data->materials[i].emissive_factor[0]*255);
- tint.g = (unsigned char)(data->materials[i].emissive_factor[1]*255);
- tint.b = (unsigned char)(data->materials[i].emissive_factor[2]*255);
- model->materials[i].maps[MATERIAL_MAP_EMISSION].color = tint;
- UnloadImage(emissiveImage);
- }
- }
- }
-
- model->materials[model->materialCount - 1] = LoadMaterialDefault();
-}
-
-static void BindGLTFPrimitiveToBones(Model *model, cgltf_node *node, const cgltf_data *data, int primitiveIndex)
-{
- int nodeId = node - data->nodes;
-
- if (model->meshes[primitiveIndex].boneIds == NULL)
- {
- model->meshes[primitiveIndex].boneIds = RL_CALLOC(model->meshes[primitiveIndex].vertexCount*4, sizeof(int));
- model->meshes[primitiveIndex].boneWeights = RL_CALLOC(model->meshes[primitiveIndex].vertexCount*4, sizeof(float));
-
- for (int b = 0; b < model->meshes[primitiveIndex].vertexCount*4; b++)
- {
- if (b%4 == 0)
- {
- model->meshes[primitiveIndex].boneIds[b] = nodeId;
- model->meshes[primitiveIndex].boneWeights[b] = 1.0f;
- }
- else
- {
- model->meshes[primitiveIndex].boneIds[b] = 0;
- model->meshes[primitiveIndex].boneWeights[b] = 0.0f;
- }
- }
- }
-}
-
-// LoadGLTF loads in animation data from given filename
-static ModelAnimation *LoadGLTFModelAnimations(const char *fileName, unsigned int *animCount)
-{
- /***********************************************************************************
-
- Function implemented by Hristo Stamenov (@object71)
-
- Features:
- - Supports .gltf and .glb files
-
- Some restrictions (not exhaustive):
- - ...
-
- *************************************************************************************/
-
- // glTF file loading
- unsigned int dataSize = 0;
- unsigned char *fileData = LoadFileData(fileName, &dataSize);
-
- ModelAnimation *animations = NULL;
-
- if (fileData == NULL) return animations;
-
- // glTF data loading
- cgltf_options options = { 0 };
- cgltf_data *data = NULL;
- cgltf_result result = cgltf_parse(&options, fileData, dataSize, &data);
-
- if (result == cgltf_result_success)
- {
- TRACELOG(LOG_INFO, "MODEL: [%s] glTF animations (%s) count: %i", fileName, (data->file_type == 2)? "glb" :
- "gltf", data->animations_count);
-
- result = cgltf_load_buffers(&options, data, fileName);
- if (result != cgltf_result_success) TRACELOG(LOG_WARNING, "MODEL: [%s] unable to load glTF animations data", fileName);
- animations = RL_MALLOC(data->animations_count*sizeof(ModelAnimation));
- *animCount = (unsigned int)data->animations_count;
-
- for (unsigned int a = 0; a < data->animations_count; a++)
- {
- // gltf animation consists of the following structures:
- // - nodes - bones are part of the node system (the whole node system is animatable)
- // - channels - single transformation type on a single bone
- // - node - animatable node
- // - transformation type (path) - translation, rotation, scale
- // - sampler - animation samples
- // - input - points in time this transformation happens
- // - output - the transformation amount at the given input points in time
- // - interpolation - the type of interpolation to use between the frames
-
- cgltf_animation *animation = data->animations + a;
-
- ModelAnimation *output = animations + a;
-
- // 30 frames sampled per second
- const float timeStep = (1.0f/60.0f);
- float animationDuration = 0.0f;
-
- // Getting the max animation time to consider for animation duration
- for (unsigned int i = 0; i < animation->channels_count; i++)
- {
- cgltf_animation_channel *channel = animation->channels + i;
- int frameCounts = (int)channel->sampler->input->count;
- float lastFrameTime = 0.0f;
-
- if (ReadGLTFValue(channel->sampler->input, frameCounts - 1, &lastFrameTime))
- {
- animationDuration = fmaxf(lastFrameTime, animationDuration);
- }
- }
-
- output->frameCount = (int)(animationDuration/timeStep);
- output->boneCount = (int)data->nodes_count;
- output->bones = RL_MALLOC(output->boneCount*sizeof(BoneInfo));
- output->framePoses = RL_MALLOC(output->frameCount*sizeof(Transform *));
- // output->framerate = // TODO: Use framerate instead of const timestep
-
- // Name and parent bones
- for (int j = 0; j < output->boneCount; j++)
- {
- strcpy(output->bones[j].name, data->nodes[j].name == 0 ? "ANIMJOINT" : data->nodes[j].name);
- output->bones[j].parent = (data->nodes[j].parent != NULL) ? (int)(data->nodes[j].parent - data->nodes) : -1;
- }
-
- // Allocate data for frames
- // Initiate with zero bone translations
- for (int frame = 0; frame < output->frameCount; frame++)
- {
- output->framePoses[frame] = RL_MALLOC(output->boneCount*sizeof(Transform));
-
- for (int i = 0; i < output->boneCount; i++)
- {
- if (data->nodes[i].has_translation) memcpy(&output->framePoses[frame][i].translation, data->nodes[i].translation, 3*sizeof(float));
- else output->framePoses[frame][i].translation = Vector3Zero();
-
- if (data->nodes[i].has_rotation) memcpy(&output->framePoses[frame][i], data->nodes[i].rotation, 4*sizeof(float));
- else output->framePoses[frame][i].rotation = QuaternionIdentity();
-
- output->framePoses[frame][i].rotation = QuaternionNormalize(output->framePoses[frame][i].rotation);
-
- if (data->nodes[i].has_scale) memcpy(&output->framePoses[frame][i].scale, data->nodes[i].scale, 3*sizeof(float));
- else output->framePoses[frame][i].scale = Vector3One();
- }
- }
-
- // for each single transformation type on single bone
- for (unsigned int channelId = 0; channelId < animation->channels_count; channelId++)
- {
- cgltf_animation_channel *channel = animation->channels + channelId;
- cgltf_animation_sampler *sampler = channel->sampler;
-
- int boneId = (int)(channel->target_node - data->nodes);
-
- for (int frame = 0; frame < output->frameCount; frame++)
- {
- bool shouldSkipFurtherTransformation = true;
- int outputMin = 0;
- int outputMax = 0;
- float frameTime = frame*timeStep;
- float lerpPercent = 0.0f;
-
- // For this transformation:
- // getting between which input values the current frame time position
- // and also what is the percent to use in the linear interpolation later
- for (unsigned int j = 0; j < sampler->input->count; j++)
- {
- float inputFrameTime;
- if (ReadGLTFValue(sampler->input, j, &inputFrameTime))
- {
- if (frameTime < inputFrameTime)
- {
- shouldSkipFurtherTransformation = false;
- outputMin = (j == 0) ? 0 : j - 1;
- outputMax = j;
-
- float previousInputTime = 0.0f;
- if (ReadGLTFValue(sampler->input, outputMin, &previousInputTime))
- {
- if ((inputFrameTime - previousInputTime) != 0)
- {
- lerpPercent = (frameTime - previousInputTime)/(inputFrameTime - previousInputTime);
- }
- }
-
- break;
- }
- }
- else break;
- }
-
- // If the current transformation has no information for the current frame time point
- if (shouldSkipFurtherTransformation) continue;
-
- if (channel->target_path == cgltf_animation_path_type_translation)
- {
- Vector3 translationStart;
- Vector3 translationEnd;
-
- float values[3];
-
- bool success = ReadGLTFValue(sampler->output, outputMin, values);
-
- translationStart.x = values[0];
- translationStart.y = values[1];
- translationStart.z = values[2];
-
- success = ReadGLTFValue(sampler->output, outputMax, values) && success;
-
- translationEnd.x = values[0];
- translationEnd.y = values[1];
- translationEnd.z = values[2];
-
- if (success)
- {
- output->framePoses[frame][boneId].translation = Vector3Lerp(translationStart, translationEnd, lerpPercent);
- }
- }
- if (channel->target_path == cgltf_animation_path_type_rotation)
- {
- Vector4 rotationStart;
- Vector4 rotationEnd;
-
- float values[4];
-
- bool success = ReadGLTFValue(sampler->output, outputMin, &values);
-
- rotationStart.x = values[0];
- rotationStart.y = values[1];
- rotationStart.z = values[2];
- rotationStart.w = values[3];
-
- success = ReadGLTFValue(sampler->output, outputMax, &values) && success;
-
- rotationEnd.x = values[0];
- rotationEnd.y = values[1];
- rotationEnd.z = values[2];
- rotationEnd.w = values[3];
-
- if (success)
- {
- output->framePoses[frame][boneId].rotation = QuaternionNlerp(rotationStart, rotationEnd, lerpPercent);
- }
- }
- if (channel->target_path == cgltf_animation_path_type_scale)
- {
- Vector3 scaleStart;
- Vector3 scaleEnd;
-
- float values[3];
-
- bool success = ReadGLTFValue(sampler->output, outputMin, &values);
-
- scaleStart.x = values[0];
- scaleStart.y = values[1];
- scaleStart.z = values[2];
-
- success = ReadGLTFValue(sampler->output, outputMax, &values) && success;
-
- scaleEnd.x = values[0];
- scaleEnd.y = values[1];
- scaleEnd.z = values[2];
-
- if (success)
- {
- output->framePoses[frame][boneId].scale = Vector3Lerp(scaleStart, scaleEnd, lerpPercent);
- }
- }
- }
- }
-
- // Build frameposes
- for (int frame = 0; frame < output->frameCount; frame++)
- {
- bool *completedBones = RL_CALLOC(output->boneCount, sizeof(bool));
- int numberCompletedBones = 0;
-
- while (numberCompletedBones < output->boneCount)
- {
- for (int i = 0; i < output->boneCount; i++)
- {
- if (completedBones[i])
- {
- continue;
- }
-
- if (output->bones[i].parent < 0)
- {
- completedBones[i] = true;
- numberCompletedBones++;
- continue;
- }
-
- if (!completedBones[output->bones[i].parent])
- {
- continue;
- }
-
- output->framePoses[frame][i].rotation = QuaternionMultiply(output->framePoses[frame][output->bones[i].parent].rotation, output->framePoses[frame][i].rotation);
- output->framePoses[frame][i].translation = Vector3RotateByQuaternion(output->framePoses[frame][i].translation, output->framePoses[frame][output->bones[i].parent].rotation);
- output->framePoses[frame][i].translation = Vector3Add(output->framePoses[frame][i].translation, output->framePoses[frame][output->bones[i].parent].translation);
- output->framePoses[frame][i].scale = Vector3Multiply(output->framePoses[frame][i].scale, output->framePoses[frame][output->bones[i].parent].scale);
- completedBones[i] = true;
- numberCompletedBones++;
- }
- }
- RL_FREE(completedBones);
- }
- }
-
- cgltf_free(data);
- }
- else TRACELOG(LOG_WARNING, ": [%s] Failed to load glTF data", fileName);
-
- RL_FREE(fileData);
-
- return animations;
-}
-
-void LoadGLTFMesh(cgltf_data *data, cgltf_node *node, Model *outModel, Matrix currentTransform, int *primitiveIndex, const char *fileName)
-{
- cgltf_mesh *mesh = node->mesh;
-
- for (unsigned int p = 0; p < mesh->primitives_count; p++)
- {
- for (unsigned int j = 0; j < mesh->primitives[p].attributes_count; j++)
- {
- if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_position)
- {
- cgltf_accessor *acc = mesh->primitives[p].attributes[j].data;
- outModel->meshes[(*primitiveIndex)].vertexCount = (int)acc->count;
-
- int bufferSize = outModel->meshes[(*primitiveIndex)].vertexCount*3*sizeof(float);
- outModel->meshes[(*primitiveIndex)].animVertices = RL_MALLOC(bufferSize);
-
- outModel->meshes[(*primitiveIndex)].vertices = ReadGLTFValuesAs(acc, cgltf_component_type_r_32f, false);
-
- // Transform using the nodes matrix attributes
- for (int v = 0; v < outModel->meshes[(*primitiveIndex)].vertexCount; v++)
- {
- Vector3 vertex = {
- outModel->meshes[(*primitiveIndex)].vertices[(v*3 + 0)],
- outModel->meshes[(*primitiveIndex)].vertices[(v*3 + 1)],
- outModel->meshes[(*primitiveIndex)].vertices[(v*3 + 2)] };
-
- vertex = Vector3Transform(vertex, currentTransform);
-
- outModel->meshes[(*primitiveIndex)].vertices[(v*3 + 0)] = vertex.x;
- outModel->meshes[(*primitiveIndex)].vertices[(v*3 + 1)] = vertex.y;
- outModel->meshes[(*primitiveIndex)].vertices[(v*3 + 2)] = vertex.z;
- }
-
- memcpy(outModel->meshes[(*primitiveIndex)].animVertices, outModel->meshes[(*primitiveIndex)].vertices, bufferSize);
- }
- else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_normal)
- {
- cgltf_accessor *acc = mesh->primitives[p].attributes[j].data;
-
- int bufferSize = (int)(acc->count*3*sizeof(float));
- outModel->meshes[(*primitiveIndex)].animNormals = RL_MALLOC(bufferSize);
-
- outModel->meshes[(*primitiveIndex)].normals = ReadGLTFValuesAs(acc, cgltf_component_type_r_32f, false);
-
- // Transform using the nodes matrix attributes
- for (int v = 0; v < outModel->meshes[(*primitiveIndex)].vertexCount; v++)
- {
- Vector3 normal = {
- outModel->meshes[(*primitiveIndex)].normals[(v*3 + 0)],
- outModel->meshes[(*primitiveIndex)].normals[(v*3 + 1)],
- outModel->meshes[(*primitiveIndex)].normals[(v*3 + 2)] };
-
- normal = Vector3Transform(normal, currentTransform);
-
- outModel->meshes[(*primitiveIndex)].normals[(v*3 + 0)] = normal.x;
- outModel->meshes[(*primitiveIndex)].normals[(v*3 + 1)] = normal.y;
- outModel->meshes[(*primitiveIndex)].normals[(v*3 + 2)] = normal.z;
- }
-
- memcpy(outModel->meshes[(*primitiveIndex)].animNormals, outModel->meshes[(*primitiveIndex)].normals, bufferSize);
- }
- else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_texcoord)
- {
- cgltf_accessor *acc = mesh->primitives[p].attributes[j].data;
- outModel->meshes[(*primitiveIndex)].texcoords = ReadGLTFValuesAs(acc, cgltf_component_type_r_32f, false);
- }
- else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_joints)
- {
- cgltf_accessor *acc = mesh->primitives[p].attributes[j].data;
- unsigned int boneCount = acc->count;
- unsigned int totalBoneWeights = boneCount*4;
- outModel->meshes[(*primitiveIndex)].boneIds = RL_MALLOC(totalBoneWeights*sizeof(int));
- short *bones = ReadGLTFValuesAs(acc, cgltf_component_type_r_16, false);
-
- // Find skin joint
- for (unsigned int a = 0; a < totalBoneWeights; a++)
- {
- outModel->meshes[(*primitiveIndex)].boneIds[a] = 0;
- if (bones[a] < 0) continue;
- cgltf_node* skinJoint = node->skin->joints[bones[a]];
- unsigned int skinJointId = skinJoint - data->nodes;
- outModel->meshes[(*primitiveIndex)].boneIds[a] = skinJointId;
- }
-
- RL_FREE(bones);
- }
- else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_weights)
- {
- cgltf_accessor *acc = mesh->primitives[p].attributes[j].data;
- outModel->meshes[(*primitiveIndex)].boneWeights = ReadGLTFValuesAs(acc, cgltf_component_type_r_32f, false);
- }
- else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_color)
- {
- cgltf_accessor *acc = mesh->primitives[p].attributes[j].data;
- outModel->meshes[(*primitiveIndex)].colors = ReadGLTFValuesAs(acc, cgltf_component_type_r_8u, true);
- }
- }
-
- cgltf_accessor *acc = mesh->primitives[p].indices;
- if (acc)
- {
- outModel->meshes[(*primitiveIndex)].triangleCount = acc->count/3;
- outModel->meshes[(*primitiveIndex)].indices = ReadGLTFValuesAs(acc, cgltf_component_type_r_16u, false);
- }
- else
- {
- // Unindexed mesh
- outModel->meshes[(*primitiveIndex)].triangleCount = outModel->meshes[(*primitiveIndex)].vertexCount/3;
- }
-
- if (mesh->primitives[p].material)
- {
- // Compute the offset
- outModel->meshMaterial[(*primitiveIndex)] = (int)(mesh->primitives[p].material - data->materials);
- }
- else outModel->meshMaterial[(*primitiveIndex)] = outModel->materialCount - 1;
-
- BindGLTFPrimitiveToBones(outModel, node, data, *primitiveIndex);
-
- (*primitiveIndex) = (*primitiveIndex) + 1;
- }
-}
-
-static Matrix GetNodeTransformationMatrix(cgltf_node *node, Matrix current)
-{
- if (node->has_matrix)
- {
- Matrix nodeTransform = {
- node->matrix[0], node->matrix[4], node->matrix[8], node->matrix[12],
- node->matrix[1], node->matrix[5], node->matrix[9], node->matrix[13],
- node->matrix[2], node->matrix[6], node->matrix[10], node->matrix[14],
- node->matrix[3], node->matrix[7], node->matrix[11], node->matrix[15] };
- current= MatrixMultiply(nodeTransform, current);
- }
- if (node->has_translation)
- {
- Matrix tl = MatrixTranslate(node->translation[0],node->translation[1],node->translation[2]);
- current = MatrixMultiply(tl, current);
- }
- if (node->has_rotation)
- {
- Matrix rot = QuaternionToMatrix((Quaternion){node->rotation[0],node->rotation[1],node->rotation[2],node->rotation[3]});
- current = MatrixMultiply(rot, current);
- }
- if (node->has_scale)
- {
- Matrix scale = MatrixScale(node->scale[0],node->scale[1],node->scale[2]);
- current = MatrixMultiply(scale, current);
- }
- return current;
-}
-
-void LoadGLTFNode(cgltf_data *data, cgltf_node *node, Model *outModel, Matrix currentTransform, int *primitiveIndex, const char *fileName)
-{
- // Apply the transforms if they exist (Will still be applied even if no mesh is present to support emptys and bone structures)
- Matrix localTransform = GetNodeTransformationMatrix(node, MatrixIdentity());
- currentTransform = MatrixMultiply(localTransform, currentTransform);
- // Load mesh if it exists
- if (node->mesh != NULL)
- {
- // Check if skinning is enabled and load Mesh accordingly
- Matrix vertexTransform = currentTransform;
- if ((node->skin != NULL) && (node->parent != NULL))
- {
- vertexTransform = localTransform;
- TRACELOG(LOG_WARNING,"MODEL: GLTF Node %s is skinned but not root node! Parent transformations will be ignored (NODE_SKINNED_MESH_NON_ROOT)",node->name);
- }
- LoadGLTFMesh(data, node, outModel, vertexTransform, primitiveIndex, fileName);
- }
- for (unsigned int i = 0; i < node->children_count; i++) LoadGLTFNode(data, node->children[i], outModel, currentTransform, primitiveIndex, fileName);
-}
-
-static void GetGLTFPrimitiveCount(cgltf_node *node, int *outCount)
-{
- if (node->mesh != NULL) *outCount += node->mesh->primitives_count;
-
- for (unsigned int i = 0; i < node->children_count; i++) GetGLTFPrimitiveCount(node->children[i], outCount);
-}
-
#endif
#if defined(SUPPORT_FILEFORMAT_VOX)