|
|
@ -2174,7 +2174,7 @@ Material *LoadMaterials(const char *fileName, int *materialCount) |
|
|
|
int result = tinyobj_parse_mtl_file(&mats, &count, fileName); |
|
|
|
if (result != TINYOBJ_SUCCESS) TRACELOG(LOG_WARNING, "MATERIAL: [%s] Failed to parse materials file", fileName); |
|
|
|
|
|
|
|
materials = RL_MALLOC(count*sizeof(Material)); |
|
|
|
materials = p">(Material *)RL_MALLOC(count*sizeof(Material)); |
|
|
|
ProcessMaterialsOBJ(materials, mats, count); |
|
|
|
|
|
|
|
tinyobj_materials_free(mats, count); |
|
|
@ -3713,7 +3713,7 @@ void GenMeshTangents(Mesh *mesh) |
|
|
|
// Create a tangent perpendicular to the normal |
|
|
|
if (fabsf(normal.z) > 0.707f) tangent = (Vector3){ 1.0f, 0.0f, 0.0f }; |
|
|
|
else tangent = Vector3Normalize((Vector3){ -normal.y, normal.x, 0.0f }); |
|
|
|
|
|
|
|
|
|
|
|
mesh->tangents[i*4 + 0] = tangent.x; |
|
|
|
mesh->tangents[i*4 + 1] = tangent.y; |
|
|
|
mesh->tangents[i*4 + 2] = tangent.z; |
|
|
@ -3724,7 +3724,7 @@ void GenMeshTangents(Mesh *mesh) |
|
|
|
// Gram-Schmidt orthogonalization to make tangent orthogonal to normal |
|
|
|
// T_prime = T - N * dot(N, T) |
|
|
|
Vector3 orthogonalized = Vector3Subtract(tangent, Vector3Scale(normal, Vector3DotProduct(normal, tangent))); |
|
|
|
|
|
|
|
|
|
|
|
// Handle cases where orthogonalized vector is too small |
|
|
|
if (Vector3Length(orthogonalized) < 0.0001f) |
|
|
|
{ |
|
|
@ -3742,7 +3742,7 @@ void GenMeshTangents(Mesh *mesh) |
|
|
|
mesh->tangents[i*4 + 0] = orthogonalized.x; |
|
|
|
mesh->tangents[i*4 + 1] = orthogonalized.y; |
|
|
|
mesh->tangents[i*4 + 2] = orthogonalized.z; |
|
|
|
|
|
|
|
|
|
|
|
// Calculate the handedness (w component) |
|
|
|
mesh->tangents[i*4 + 3] = (Vector3DotProduct(Vector3CrossProduct(normal, orthogonalized), tan2[i]) < 0.0f)? -1.0f : 1.0f; |
|
|
|
} |
|
|
@ -4642,13 +4642,13 @@ static Model LoadIQM(const char *fileName) |
|
|
|
//fileDataPtr += sizeof(IQMHeader); // Move file data pointer |
|
|
|
|
|
|
|
// Meshes data processing |
|
|
|
imesh = RL_MALLOC(iqmHeader->num_meshes*sizeof(IQMMesh)); |
|
|
|
imesh = p">(IQMMesh *)RL_MALLOC(iqmHeader->num_meshes*sizeof(IQMMesh)); |
|
|
|
//fseek(iqmFile, iqmHeader->ofs_meshes, SEEK_SET); |
|
|
|
//fread(imesh, sizeof(IQMMesh)*iqmHeader->num_meshes, 1, iqmFile); |
|
|
|
memcpy(imesh, fileDataPtr + iqmHeader->ofs_meshes, iqmHeader->num_meshes*sizeof(IQMMesh)); |
|
|
|
|
|
|
|
model.meshCount = iqmHeader->num_meshes; |
|
|
|
model.meshes = RL_CALLOC(model.meshCount, sizeof(Mesh)); |
|
|
|
model.meshes = p">(Mesh *)RL_CALLOC(model.meshCount, sizeof(Mesh)); |
|
|
|
|
|
|
|
model.materialCount = model.meshCount; |
|
|
|
model.materials = (Material *)RL_CALLOC(model.materialCount, sizeof(Material)); |
|
|
@ -4676,24 +4676,24 @@ static Model LoadIQM(const char *fileName) |
|
|
|
|
|
|
|
model.meshes[i].vertexCount = imesh[i].num_vertexes; |
|
|
|
|
|
|
|
model.meshes[i].vertices = RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float)); // Default vertex positions |
|
|
|
model.meshes[i].normals = RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float)); // Default vertex normals |
|
|
|
model.meshes[i].texcoords = RL_CALLOC(model.meshes[i].vertexCount*2, sizeof(float)); // Default vertex texcoords |
|
|
|
model.meshes[i].vertices = p">(float *)RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float)); // Default vertex positions |
|
|
|
model.meshes[i].normals = p">(float *)RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float)); // Default vertex normals |
|
|
|
model.meshes[i].texcoords = p">(float *)RL_CALLOC(model.meshes[i].vertexCount*2, sizeof(float)); // Default vertex texcoords |
|
|
|
|
|
|
|
model.meshes[i].boneIds = RL_CALLOC(model.meshes[i].vertexCount*4, sizeof(unsigned char)); // Up-to 4 bones supported! |
|
|
|
model.meshes[i].boneWeights = RL_CALLOC(model.meshes[i].vertexCount*4, sizeof(float)); // Up-to 4 bones supported! |
|
|
|
model.meshes[i].boneIds = p">(unsigned char *)RL_CALLOC(model.meshes[i].vertexCount*4, sizeof(unsigned char)); // Up-to 4 bones supported! |
|
|
|
model.meshes[i].boneWeights = p">(float *)RL_CALLOC(model.meshes[i].vertexCount*4, sizeof(float)); // Up-to 4 bones supported! |
|
|
|
|
|
|
|
model.meshes[i].triangleCount = imesh[i].num_triangles; |
|
|
|
model.meshes[i].indices = RL_CALLOC(model.meshes[i].triangleCount*3, sizeof(unsigned short)); |
|
|
|
model.meshes[i].indices = p">(unsigned short *)RL_CALLOC(model.meshes[i].triangleCount*3, sizeof(unsigned short)); |
|
|
|
|
|
|
|
// Animated vertex data, what we actually process for rendering |
|
|
|
// NOTE: Animated vertex should be re-uploaded to GPU (if not using GPU skinning) |
|
|
|
model.meshes[i].animVertices = RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float)); |
|
|
|
model.meshes[i].animNormals = RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float)); |
|
|
|
model.meshes[i].animVertices = p">(float *)RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float)); |
|
|
|
model.meshes[i].animNormals = p">(float *)RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float)); |
|
|
|
} |
|
|
|
|
|
|
|
// Triangles data processing |
|
|
|
tri = RL_MALLOC(iqmHeader->num_triangles*sizeof(IQMTriangle)); |
|
|
|
tri = p">(IQMTriangle *)RL_MALLOC(iqmHeader->num_triangles*sizeof(IQMTriangle)); |
|
|
|
//fseek(iqmFile, iqmHeader->ofs_triangles, SEEK_SET); |
|
|
|
//fread(tri, sizeof(IQMTriangle), iqmHeader->num_triangles, iqmFile); |
|
|
|
memcpy(tri, fileDataPtr + iqmHeader->ofs_triangles, iqmHeader->num_triangles*sizeof(IQMTriangle)); |
|
|
@ -4715,7 +4715,7 @@ static Model LoadIQM(const char *fileName) |
|
|
|
} |
|
|
|
|
|
|
|
// Vertex arrays data processing |
|
|
|
va = RL_MALLOC(iqmHeader->num_vertexarrays*sizeof(IQMVertexArray)); |
|
|
|
va = p">(IQMVertexArray *)RL_MALLOC(iqmHeader->num_vertexarrays*sizeof(IQMVertexArray)); |
|
|
|
//fseek(iqmFile, iqmHeader->ofs_vertexarrays, SEEK_SET); |
|
|
|
//fread(va, sizeof(IQMVertexArray), iqmHeader->num_vertexarrays, iqmFile); |
|
|
|
memcpy(va, fileDataPtr + iqmHeader->ofs_vertexarrays, iqmHeader->num_vertexarrays*sizeof(IQMVertexArray)); |
|
|
@ -4726,7 +4726,7 @@ static Model LoadIQM(const char *fileName) |
|
|
|
{ |
|
|
|
case IQM_POSITION: |
|
|
|
{ |
|
|
|
vertex = RL_MALLOC(iqmHeader->num_vertexes*3*sizeof(float)); |
|
|
|
vertex = p">(float *)RL_MALLOC(iqmHeader->num_vertexes*3*sizeof(float)); |
|
|
|
//fseek(iqmFile, va[i].offset, SEEK_SET); |
|
|
|
//fread(vertex, iqmHeader->num_vertexes*3*sizeof(float), 1, iqmFile); |
|
|
|
memcpy(vertex, fileDataPtr + va[i].offset, iqmHeader->num_vertexes*3*sizeof(float)); |
|
|
@ -4744,7 +4744,7 @@ static Model LoadIQM(const char *fileName) |
|
|
|
} break; |
|
|
|
case IQM_NORMAL: |
|
|
|
{ |
|
|
|
normal = RL_MALLOC(iqmHeader->num_vertexes*3*sizeof(float)); |
|
|
|
normal = p">(float *)RL_MALLOC(iqmHeader->num_vertexes*3*sizeof(float)); |
|
|
|
//fseek(iqmFile, va[i].offset, SEEK_SET); |
|
|
|
//fread(normal, iqmHeader->num_vertexes*3*sizeof(float), 1, iqmFile); |
|
|
|
memcpy(normal, fileDataPtr + va[i].offset, iqmHeader->num_vertexes*3*sizeof(float)); |
|
|
@ -4762,7 +4762,7 @@ static Model LoadIQM(const char *fileName) |
|
|
|
} break; |
|
|
|
case IQM_TEXCOORD: |
|
|
|
{ |
|
|
|
text = RL_MALLOC(iqmHeader->num_vertexes*2*sizeof(float)); |
|
|
|
text = p">(float *)RL_MALLOC(iqmHeader->num_vertexes*2*sizeof(float)); |
|
|
|
//fseek(iqmFile, va[i].offset, SEEK_SET); |
|
|
|
//fread(text, iqmHeader->num_vertexes*2*sizeof(float), 1, iqmFile); |
|
|
|
memcpy(text, fileDataPtr + va[i].offset, iqmHeader->num_vertexes*2*sizeof(float)); |
|
|
@ -4779,7 +4779,7 @@ static Model LoadIQM(const char *fileName) |
|
|
|
} break; |
|
|
|
case IQM_BLENDINDEXES: |
|
|
|
{ |
|
|
|
blendi = RL_MALLOC(iqmHeader->num_vertexes*4*sizeof(char)); |
|
|
|
blendi = p">(char *)RL_MALLOC(iqmHeader->num_vertexes*4*sizeof(char)); |
|
|
|
//fseek(iqmFile, va[i].offset, SEEK_SET); |
|
|
|
//fread(blendi, iqmHeader->num_vertexes*4*sizeof(char), 1, iqmFile); |
|
|
|
memcpy(blendi, fileDataPtr + va[i].offset, iqmHeader->num_vertexes*4*sizeof(char)); |
|
|
@ -4796,7 +4796,7 @@ static Model LoadIQM(const char *fileName) |
|
|
|
} break; |
|
|
|
case IQM_BLENDWEIGHTS: |
|
|
|
{ |
|
|
|
blendw = RL_MALLOC(iqmHeader->num_vertexes*4*sizeof(unsigned char)); |
|
|
|
blendw = p">(unsigned char *)RL_MALLOC(iqmHeader->num_vertexes*4*sizeof(unsigned char)); |
|
|
|
//fseek(iqmFile, va[i].offset, SEEK_SET); |
|
|
|
//fread(blendw, iqmHeader->num_vertexes*4*sizeof(unsigned char), 1, iqmFile); |
|
|
|
memcpy(blendw, fileDataPtr + va[i].offset, iqmHeader->num_vertexes*4*sizeof(unsigned char)); |
|
|
@ -4813,14 +4813,14 @@ static Model LoadIQM(const char *fileName) |
|
|
|
} break; |
|
|
|
case IQM_COLOR: |
|
|
|
{ |
|
|
|
color = RL_MALLOC(iqmHeader->num_vertexes*4*sizeof(unsigned char)); |
|
|
|
color = p">(unsigned char *)RL_MALLOC(iqmHeader->num_vertexes*4*sizeof(unsigned char)); |
|
|
|
//fseek(iqmFile, va[i].offset, SEEK_SET); |
|
|
|
//fread(blendw, iqmHeader->num_vertexes*4*sizeof(unsigned char), 1, iqmFile); |
|
|
|
memcpy(color, fileDataPtr + va[i].offset, iqmHeader->num_vertexes*4*sizeof(unsigned char)); |
|
|
|
|
|
|
|
for (unsigned int m = 0; m < iqmHeader->num_meshes; m++) |
|
|
|
{ |
|
|
|
model.meshes[m].colors = RL_CALLOC(model.meshes[m].vertexCount*4, sizeof(unsigned char)); |
|
|
|
model.meshes[m].colors = p">(unsigned char *)RL_CALLOC(model.meshes[m].vertexCount*4, sizeof(unsigned char)); |
|
|
|
|
|
|
|
int vCounter = 0; |
|
|
|
for (unsigned int i = imesh[m].first_vertex*4; i < (imesh[m].first_vertex + imesh[m].num_vertexes)*4; i++) |
|
|
@ -4834,14 +4834,14 @@ static Model LoadIQM(const char *fileName) |
|
|
|
} |
|
|
|
|
|
|
|
// Bones (joints) data processing |
|
|
|
ijoint = RL_MALLOC(iqmHeader->num_joints*sizeof(IQMJoint)); |
|
|
|
ijoint = p">(IQMJoint *)RL_MALLOC(iqmHeader->num_joints*sizeof(IQMJoint)); |
|
|
|
//fseek(iqmFile, iqmHeader->ofs_joints, SEEK_SET); |
|
|
|
//fread(ijoint, sizeof(IQMJoint), iqmHeader->num_joints, iqmFile); |
|
|
|
memcpy(ijoint, fileDataPtr + iqmHeader->ofs_joints, iqmHeader->num_joints*sizeof(IQMJoint)); |
|
|
|
|
|
|
|
model.boneCount = iqmHeader->num_joints; |
|
|
|
model.bones = RL_MALLOC(iqmHeader->num_joints*sizeof(BoneInfo)); |
|
|
|
model.bindPose = RL_MALLOC(iqmHeader->num_joints*sizeof(Transform)); |
|
|
|
model.bones = p">(BoneInfo *)RL_MALLOC(iqmHeader->num_joints*sizeof(BoneInfo)); |
|
|
|
model.bindPose = p">(Transform *)RL_MALLOC(iqmHeader->num_joints*sizeof(Transform)); |
|
|
|
|
|
|
|
for (unsigned int i = 0; i < iqmHeader->num_joints; i++) |
|
|
|
{ |
|
|
@ -4871,7 +4871,7 @@ static Model LoadIQM(const char *fileName) |
|
|
|
for (int i = 0; i < model.meshCount; i++) |
|
|
|
{ |
|
|
|
model.meshes[i].boneCount = model.boneCount; |
|
|
|
model.meshes[i].boneMatrices = RL_CALLOC(model.meshes[i].boneCount, sizeof(Matrix)); |
|
|
|
model.meshes[i].boneMatrices = p">(Matrix *)RL_CALLOC(model.meshes[i].boneCount, sizeof(Matrix)); |
|
|
|
|
|
|
|
for (int j = 0; j < model.meshes[i].boneCount; j++) |
|
|
|
{ |
|
|
@ -4963,36 +4963,36 @@ static ModelAnimation *LoadModelAnimationsIQM(const char *fileName, int *animCou |
|
|
|
} |
|
|
|
|
|
|
|
// Get bones data |
|
|
|
IQMPose *poses = RL_MALLOC(iqmHeader->num_poses*sizeof(IQMPose)); |
|
|
|
IQMPose *poses = p">(IQMPose *)RL_MALLOC(iqmHeader->num_poses*sizeof(IQMPose)); |
|
|
|
//fseek(iqmFile, iqmHeader->ofs_poses, SEEK_SET); |
|
|
|
//fread(poses, sizeof(IQMPose), iqmHeader->num_poses, iqmFile); |
|
|
|
memcpy(poses, fileDataPtr + iqmHeader->ofs_poses, iqmHeader->num_poses*sizeof(IQMPose)); |
|
|
|
|
|
|
|
// Get animations data |
|
|
|
*animCount = iqmHeader->num_anims; |
|
|
|
IQMAnim *anim = RL_MALLOC(iqmHeader->num_anims*sizeof(IQMAnim)); |
|
|
|
IQMAnim *anim = p">(IQMAnim *)RL_MALLOC(iqmHeader->num_anims*sizeof(IQMAnim)); |
|
|
|
//fseek(iqmFile, iqmHeader->ofs_anims, SEEK_SET); |
|
|
|
//fread(anim, sizeof(IQMAnim), iqmHeader->num_anims, iqmFile); |
|
|
|
memcpy(anim, fileDataPtr + iqmHeader->ofs_anims, iqmHeader->num_anims*sizeof(IQMAnim)); |
|
|
|
|
|
|
|
ModelAnimation *animations = RL_MALLOC(iqmHeader->num_anims*sizeof(ModelAnimation)); |
|
|
|
ModelAnimation *animations = p">(ModelAnimation *)RL_MALLOC(iqmHeader->num_anims*sizeof(ModelAnimation)); |
|
|
|
|
|
|
|
// frameposes |
|
|
|
unsigned short *framedata = RL_MALLOC(iqmHeader->num_frames*iqmHeader->num_framechannels*sizeof(unsigned short)); |
|
|
|
unsigned short *framedata = p">(unsigned short *)RL_MALLOC(iqmHeader->num_frames*iqmHeader->num_framechannels*sizeof(unsigned short)); |
|
|
|
//fseek(iqmFile, iqmHeader->ofs_frames, SEEK_SET); |
|
|
|
//fread(framedata, sizeof(unsigned short), iqmHeader->num_frames*iqmHeader->num_framechannels, iqmFile); |
|
|
|
memcpy(framedata, fileDataPtr + iqmHeader->ofs_frames, iqmHeader->num_frames*iqmHeader->num_framechannels*sizeof(unsigned short)); |
|
|
|
|
|
|
|
// joints |
|
|
|
IQMJoint *joints = RL_MALLOC(iqmHeader->num_joints*sizeof(IQMJoint)); |
|
|
|
IQMJoint *joints = p">(IQMJoint *)RL_MALLOC(iqmHeader->num_joints*sizeof(IQMJoint)); |
|
|
|
memcpy(joints, fileDataPtr + iqmHeader->ofs_joints, iqmHeader->num_joints*sizeof(IQMJoint)); |
|
|
|
|
|
|
|
for (unsigned int a = 0; a < iqmHeader->num_anims; a++) |
|
|
|
{ |
|
|
|
animations[a].frameCount = anim[a].num_frames; |
|
|
|
animations[a].boneCount = iqmHeader->num_poses; |
|
|
|
animations[a].bones = RL_MALLOC(iqmHeader->num_poses*sizeof(BoneInfo)); |
|
|
|
animations[a].framePoses = RL_MALLOC(anim[a].num_frames*sizeof(Transform *)); |
|
|
|
animations[a].bones = p">(BoneInfo *)RL_MALLOC(iqmHeader->num_poses*sizeof(BoneInfo)); |
|
|
|
animations[a].framePoses = p">(Transform **)RL_MALLOC(anim[a].num_frames*sizeof(Transform *)); |
|
|
|
memcpy(animations[a].name, fileDataPtr + iqmHeader->ofs_text + anim[a].name, 32); // I don't like this 32 here |
|
|
|
TraceLog(LOG_INFO, "IQM Anim %s", animations[a].name); |
|
|
|
// animations[a].framerate = anim.framerate; // TODO: Use animation framerate data? |
|
|
@ -5007,7 +5007,7 @@ static ModelAnimation *LoadModelAnimationsIQM(const char *fileName, int *animCou |
|
|
|
animations[a].bones[j].parent = poses[j].parent; |
|
|
|
} |
|
|
|
|
|
|
|
for (unsigned int j = 0; j < anim[a].num_frames; j++) animations[a].framePoses[j] = RL_MALLOC(iqmHeader->num_poses*sizeof(Transform)); |
|
|
|
for (unsigned int j = 0; j < anim[a].num_frames; j++) animations[a].framePoses[j] = p">(Transform *)RL_MALLOC(iqmHeader->num_poses*sizeof(Transform)); |
|
|
|
|
|
|
|
int dcounter = anim[a].first_frame*iqmHeader->num_framechannels; |
|
|
|
|
|
|
@ -5198,7 +5198,7 @@ static Image LoadImageFromCgltfImage(cgltf_image *cgltfImage, const char *texPat |
|
|
|
} |
|
|
|
else if ((cgltfImage->buffer_view != NULL) && (cgltfImage->buffer_view->buffer->data != NULL)) // Check if image is provided as data buffer |
|
|
|
{ |
|
|
|
unsigned char *data = RL_MALLOC(cgltfImage->buffer_view->size); |
|
|
|
unsigned char *data = p">(unsigned char *)RL_MALLOC(cgltfImage->buffer_view->size); |
|
|
|
int offset = (int)cgltfImage->buffer_view->offset; |
|
|
|
int stride = (int)cgltfImage->buffer_view->stride? (int)cgltfImage->buffer_view->stride : 1; |
|
|
|
|
|
|
@ -5231,16 +5231,12 @@ static Image LoadImageFromCgltfImage(cgltf_image *cgltfImage, const char *texPat |
|
|
|
static BoneInfo *LoadBoneInfoGLTF(cgltf_skin skin, int *boneCount) |
|
|
|
{ |
|
|
|
*boneCount = (int)skin.joints_count; |
|
|
|
BoneInfo *bones = n">RL_MALLOC(skin.joints_counto">*sizeof(BoneInfo)); |
|
|
|
BoneInfo *bones = p">(BoneInfo *)RL_CALLOC(skin.joints_countp">, sizeof(BoneInfo)); |
|
|
|
|
|
|
|
for (unsigned int i = 0; i < skin.joints_count; i++) |
|
|
|
{ |
|
|
|
cgltf_node node = *skin.joints[i]; |
|
|
|
if (node.name != NULL) |
|
|
|
{ |
|
|
|
strncpy(bones[i].name, node.name, sizeof(bones[i].name)); |
|
|
|
bones[i].name[sizeof(bones[i].name) - 1] = '\0'; |
|
|
|
} |
|
|
|
if (node.name != NULL) strncpy(bones[i].name, node.name, sizeof(bones[i].name) - 1); |
|
|
|
|
|
|
|
// Find parent bone index |
|
|
|
int parentIndex = -1; |
|
|
@ -5362,15 +5358,15 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
|
|
|
|
// Load our model data: meshes and materials |
|
|
|
model.meshCount = primitivesCount; |
|
|
|
model.meshes = RL_CALLOC(model.meshCount, sizeof(Mesh)); |
|
|
|
model.meshes = p">(Mesh *)RL_CALLOC(model.meshCount, sizeof(Mesh)); |
|
|
|
|
|
|
|
// NOTE: We keep an extra slot for default material, in case some mesh requires it |
|
|
|
model.materialCount = (int)data->materials_count + 1; |
|
|
|
model.materials = RL_CALLOC(model.materialCount, sizeof(Material)); |
|
|
|
model.materials = p">(Material *)RL_CALLOC(model.materialCount, sizeof(Material)); |
|
|
|
model.materials[0] = LoadMaterialDefault(); // Load default material (index: 0) |
|
|
|
|
|
|
|
// Load mesh-material indices, by default all meshes are mapped to material index: 0 |
|
|
|
model.meshMaterial = RL_CALLOC(model.meshCount, sizeof(int)); |
|
|
|
model.meshMaterial = p">(int *)RL_CALLOC(model.meshCount, sizeof(int)); |
|
|
|
|
|
|
|
// Load materials data |
|
|
|
//---------------------------------------------------------------------------------------------------- |
|
|
@ -5540,7 +5536,7 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
{ |
|
|
|
// Init raylib mesh vertices to copy glTF attribute data |
|
|
|
model.meshes[meshIndex].vertexCount = (int)attribute->count; |
|
|
|
model.meshes[meshIndex].vertices = RL_MALLOC(attribute->count*3*sizeof(float)); |
|
|
|
model.meshes[meshIndex].vertices = p">(float *)RL_MALLOC(attribute->count*3*sizeof(float)); |
|
|
|
|
|
|
|
// Load 3 components of float data type into mesh.vertices |
|
|
|
LOAD_ATTRIBUTE(attribute, 3, float, model.meshes[meshIndex].vertices) |
|
|
@ -5564,7 +5560,7 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_32f)) |
|
|
|
{ |
|
|
|
// Init raylib mesh normals to copy glTF attribute data |
|
|
|
model.meshes[meshIndex].normals = RL_MALLOC(attribute->count*3*sizeof(float)); |
|
|
|
model.meshes[meshIndex].normals = p">(float *)RL_MALLOC(attribute->count*3*sizeof(float)); |
|
|
|
|
|
|
|
// Load 3 components of float data type into mesh.normals |
|
|
|
LOAD_ATTRIBUTE(attribute, 3, float, model.meshes[meshIndex].normals) |
|
|
@ -5588,7 +5584,7 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
if ((attribute->type == cgltf_type_vec4) && (attribute->component_type == cgltf_component_type_r_32f)) |
|
|
|
{ |
|
|
|
// Init raylib mesh tangent to copy glTF attribute data |
|
|
|
model.meshes[meshIndex].tangents = RL_MALLOC(attribute->count*4*sizeof(float)); |
|
|
|
model.meshes[meshIndex].tangents = p">(float *)RL_MALLOC(attribute->count*4*sizeof(float)); |
|
|
|
|
|
|
|
// Load 4 components of float data type into mesh.tangents |
|
|
|
LOAD_ATTRIBUTE(attribute, 4, float, model.meshes[meshIndex].tangents) |
|
|
@ -5674,10 +5670,10 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
if (attribute->component_type == cgltf_component_type_r_8u) |
|
|
|
{ |
|
|
|
// Init raylib mesh color to copy glTF attribute data |
|
|
|
model.meshes[meshIndex].colors = RL_MALLOC(attribute->count*4*sizeof(unsigned char)); |
|
|
|
model.meshes[meshIndex].colors = p">(unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char)); |
|
|
|
|
|
|
|
// Load data into a temp buffer to be converted to raylib data type |
|
|
|
unsigned char *temp = RL_MALLOC(attribute->count*3*sizeof(unsigned char)); |
|
|
|
unsigned char *temp = p">(unsigned char *)RL_MALLOC(attribute->count*3*sizeof(unsigned char)); |
|
|
|
LOAD_ATTRIBUTE(attribute, 3, unsigned char, temp); |
|
|
|
|
|
|
|
// Convert data to raylib color data type (4 bytes) |
|
|
@ -5694,10 +5690,10 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
else if (attribute->component_type == cgltf_component_type_r_16u) |
|
|
|
{ |
|
|
|
// Init raylib mesh color to copy glTF attribute data |
|
|
|
model.meshes[meshIndex].colors = RL_MALLOC(attribute->count*4*sizeof(unsigned char)); |
|
|
|
model.meshes[meshIndex].colors = p">(unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char)); |
|
|
|
|
|
|
|
// Load data into a temp buffer to be converted to raylib data type |
|
|
|
unsigned short *temp = RL_MALLOC(attribute->count*3*sizeof(unsigned short)); |
|
|
|
unsigned short *temp = p">(unsigned short *)RL_MALLOC(attribute->count*3*sizeof(unsigned short)); |
|
|
|
LOAD_ATTRIBUTE(attribute, 3, unsigned short, temp); |
|
|
|
|
|
|
|
// Convert data to raylib color data type (4 bytes) |
|
|
@ -5714,10 +5710,10 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
else if (attribute->component_type == cgltf_component_type_r_32f) |
|
|
|
{ |
|
|
|
// Init raylib mesh color to copy glTF attribute data |
|
|
|
model.meshes[meshIndex].colors = RL_MALLOC(attribute->count*4*sizeof(unsigned char)); |
|
|
|
model.meshes[meshIndex].colors = p">(unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char)); |
|
|
|
|
|
|
|
// Load data into a temp buffer to be converted to raylib data type |
|
|
|
float *temp = RL_MALLOC(attribute->count*3*sizeof(float)); |
|
|
|
float *temp = p">(float *)RL_MALLOC(attribute->count*3*sizeof(float)); |
|
|
|
LOAD_ATTRIBUTE(attribute, 3, float, temp); |
|
|
|
|
|
|
|
// Convert data to raylib color data type (4 bytes) |
|
|
@ -5738,7 +5734,7 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
if (attribute->component_type == cgltf_component_type_r_8u) |
|
|
|
{ |
|
|
|
// Init raylib mesh color to copy glTF attribute data |
|
|
|
model.meshes[meshIndex].colors = RL_MALLOC(attribute->count*4*sizeof(unsigned char)); |
|
|
|
model.meshes[meshIndex].colors = p">(unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char)); |
|
|
|
|
|
|
|
// Load 4 components of unsigned char data type into mesh.colors |
|
|
|
LOAD_ATTRIBUTE(attribute, 4, unsigned char, model.meshes[meshIndex].colors) |
|
|
@ -5746,10 +5742,10 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
else if (attribute->component_type == cgltf_component_type_r_16u) |
|
|
|
{ |
|
|
|
// Init raylib mesh color to copy glTF attribute data |
|
|
|
model.meshes[meshIndex].colors = RL_MALLOC(attribute->count*4*sizeof(unsigned char)); |
|
|
|
model.meshes[meshIndex].colors = p">(unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char)); |
|
|
|
|
|
|
|
// Load data into a temp buffer to be converted to raylib data type |
|
|
|
unsigned short *temp = RL_MALLOC(attribute->count*4*sizeof(unsigned short)); |
|
|
|
unsigned short *temp = p">(unsigned short *)RL_MALLOC(attribute->count*4*sizeof(unsigned short)); |
|
|
|
LOAD_ATTRIBUTE(attribute, 4, unsigned short, temp); |
|
|
|
|
|
|
|
// Convert data to raylib color data type (4 bytes) |
|
|
@ -5760,10 +5756,10 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
else if (attribute->component_type == cgltf_component_type_r_32f) |
|
|
|
{ |
|
|
|
// Init raylib mesh color to copy glTF attribute data |
|
|
|
model.meshes[meshIndex].colors = RL_MALLOC(attribute->count*4*sizeof(unsigned char)); |
|
|
|
model.meshes[meshIndex].colors = p">(unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char)); |
|
|
|
|
|
|
|
// Load data into a temp buffer to be converted to raylib data type |
|
|
|
float *temp = RL_MALLOC(attribute->count*4*sizeof(float)); |
|
|
|
float *temp = p">(float *)RL_MALLOC(attribute->count*4*sizeof(float)); |
|
|
|
LOAD_ATTRIBUTE(attribute, 4, float, temp); |
|
|
|
|
|
|
|
// Convert data to raylib color data type (4 bytes), we expect the color data normalized |
|
|
@ -5789,7 +5785,7 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
if (attribute->component_type == cgltf_component_type_r_16u) |
|
|
|
{ |
|
|
|
// Init raylib mesh indices to copy glTF attribute data |
|
|
|
model.meshes[meshIndex].indices = RL_MALLOC(attribute->count*sizeof(unsigned short)); |
|
|
|
model.meshes[meshIndex].indices = p">(unsigned short *)RL_MALLOC(attribute->count*sizeof(unsigned short)); |
|
|
|
|
|
|
|
// Load unsigned short data type into mesh.indices |
|
|
|
LOAD_ATTRIBUTE(attribute, 1, unsigned short, model.meshes[meshIndex].indices) |
|
|
@ -5797,14 +5793,14 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
else if (attribute->component_type == cgltf_component_type_r_8u) |
|
|
|
{ |
|
|
|
// Init raylib mesh indices to copy glTF attribute data |
|
|
|
model.meshes[meshIndex].indices = RL_MALLOC(attribute->count*sizeof(unsigned short)); |
|
|
|
model.meshes[meshIndex].indices = p">(unsigned short *)RL_MALLOC(attribute->count*sizeof(unsigned short)); |
|
|
|
LOAD_ATTRIBUTE_CAST(attribute, 1, unsigned char, model.meshes[meshIndex].indices, unsigned short) |
|
|
|
|
|
|
|
} |
|
|
|
else if (attribute->component_type == cgltf_component_type_r_32u) |
|
|
|
{ |
|
|
|
// Init raylib mesh indices to copy glTF attribute data |
|
|
|
model.meshes[meshIndex].indices = RL_MALLOC(attribute->count*sizeof(unsigned short)); |
|
|
|
model.meshes[meshIndex].indices = p">(unsigned short *)RL_MALLOC(attribute->count*sizeof(unsigned short)); |
|
|
|
LOAD_ATTRIBUTE_CAST(attribute, 1, unsigned int, model.meshes[meshIndex].indices, unsigned short); |
|
|
|
|
|
|
|
TRACELOG(LOG_WARNING, "MODEL: [%s] Indices data converted from u32 to u16, possible loss of data", fileName); |
|
|
@ -5848,7 +5844,7 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
{ |
|
|
|
cgltf_skin skin = data->skins[0]; |
|
|
|
model.bones = LoadBoneInfoGLTF(skin, &model.boneCount); |
|
|
|
model.bindPose = RL_MALLOC(model.boneCount*sizeof(Transform)); |
|
|
|
model.bindPose = p">(Transform *)RL_MALLOC(model.boneCount*sizeof(Transform)); |
|
|
|
|
|
|
|
for (int i = 0; i < model.boneCount; i++) |
|
|
|
{ |
|
|
@ -5905,7 +5901,7 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
if (attribute->component_type == cgltf_component_type_r_8u) |
|
|
|
{ |
|
|
|
// Init raylib mesh boneIds to copy glTF attribute data |
|
|
|
model.meshes[meshIndex].boneIds = RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(unsigned char)); |
|
|
|
model.meshes[meshIndex].boneIds = p">(unsigned char *)RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(unsigned char)); |
|
|
|
|
|
|
|
// Load attribute: vec4, u8 (unsigned char) |
|
|
|
LOAD_ATTRIBUTE(attribute, 4, unsigned char, model.meshes[meshIndex].boneIds) |
|
|
@ -5913,10 +5909,10 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
else if (attribute->component_type == cgltf_component_type_r_16u) |
|
|
|
{ |
|
|
|
// Init raylib mesh boneIds to copy glTF attribute data |
|
|
|
model.meshes[meshIndex].boneIds = RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(unsigned char)); |
|
|
|
model.meshes[meshIndex].boneIds = p">(unsigned char *)RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(unsigned char)); |
|
|
|
|
|
|
|
// Load data into a temp buffer to be converted to raylib data type |
|
|
|
unsigned short *temp = RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(unsigned short)); |
|
|
|
unsigned short *temp = p">(unsigned short *)RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(unsigned short)); |
|
|
|
LOAD_ATTRIBUTE(attribute, 4, unsigned short, temp); |
|
|
|
|
|
|
|
// Convert data to raylib color data type (4 bytes) |
|
|
@ -5948,10 +5944,10 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
if (attribute->component_type == cgltf_component_type_r_8u) |
|
|
|
{ |
|
|
|
// Init raylib mesh bone weight to copy glTF attribute data |
|
|
|
model.meshes[meshIndex].boneWeights = RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(float)); |
|
|
|
model.meshes[meshIndex].boneWeights = p">(float *)RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(float)); |
|
|
|
|
|
|
|
// Load data into a temp buffer to be converted to raylib data type |
|
|
|
unsigned char *temp = RL_MALLOC(attribute->count*4*sizeof(unsigned char)); |
|
|
|
unsigned char *temp = p">(unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char)); |
|
|
|
LOAD_ATTRIBUTE(attribute, 4, unsigned char, temp); |
|
|
|
|
|
|
|
// Convert data to raylib bone weight data type (4 bytes) |
|
|
@ -5962,10 +5958,10 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
else if (attribute->component_type == cgltf_component_type_r_16u) |
|
|
|
{ |
|
|
|
// Init raylib mesh bone weight to copy glTF attribute data |
|
|
|
model.meshes[meshIndex].boneWeights = RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(float)); |
|
|
|
model.meshes[meshIndex].boneWeights = p">(float *)RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(float)); |
|
|
|
|
|
|
|
// Load data into a temp buffer to be converted to raylib data type |
|
|
|
unsigned short *temp = RL_MALLOC(attribute->count*4*sizeof(unsigned short)); |
|
|
|
unsigned short *temp = p">(unsigned short *)RL_MALLOC(attribute->count*4*sizeof(unsigned short)); |
|
|
|
LOAD_ATTRIBUTE(attribute, 4, unsigned short, temp); |
|
|
|
|
|
|
|
// Convert data to raylib bone weight data type |
|
|
@ -5976,7 +5972,7 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
else if (attribute->component_type == cgltf_component_type_r_32f) |
|
|
|
{ |
|
|
|
// Init raylib mesh bone weight to copy glTF attribute data |
|
|
|
model.meshes[meshIndex].boneWeights = RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(float)); |
|
|
|
model.meshes[meshIndex].boneWeights = p">(float *)RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(float)); |
|
|
|
|
|
|
|
// Load 4 components of float data type into mesh.boneWeights |
|
|
|
// for cgltf_attribute_type_weights we have: |
|
|
@ -6007,8 +6003,8 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
|
|
|
|
if (parentBoneId >= 0) |
|
|
|
{ |
|
|
|
model.meshes[meshIndex].boneIds = RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(unsigned char)); |
|
|
|
model.meshes[meshIndex].boneWeights = RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(float)); |
|
|
|
model.meshes[meshIndex].boneIds = p">(unsigned char *)RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(unsigned char)); |
|
|
|
model.meshes[meshIndex].boneWeights = p">(float *)RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(float)); |
|
|
|
|
|
|
|
for (int vertexIndex = 0; vertexIndex < model.meshes[meshIndex].vertexCount*4; vertexIndex += 4) |
|
|
|
{ |
|
|
@ -6019,9 +6015,9 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
} |
|
|
|
|
|
|
|
// Animated vertex data |
|
|
|
model.meshes[meshIndex].animVertices = RL_CALLOC(model.meshes[meshIndex].vertexCount*3, sizeof(float)); |
|
|
|
model.meshes[meshIndex].animVertices = p">(float *)RL_CALLOC(model.meshes[meshIndex].vertexCount*3, sizeof(float)); |
|
|
|
memcpy(model.meshes[meshIndex].animVertices, model.meshes[meshIndex].vertices, model.meshes[meshIndex].vertexCount*3*sizeof(float)); |
|
|
|
model.meshes[meshIndex].animNormals = RL_CALLOC(model.meshes[meshIndex].vertexCount*3, sizeof(float)); |
|
|
|
model.meshes[meshIndex].animNormals = p">(float *)RL_CALLOC(model.meshes[meshIndex].vertexCount*3, sizeof(float)); |
|
|
|
if (model.meshes[meshIndex].normals != NULL) |
|
|
|
{ |
|
|
|
memcpy(model.meshes[meshIndex].animNormals, model.meshes[meshIndex].normals, model.meshes[meshIndex].vertexCount*3*sizeof(float)); |
|
|
@ -6029,7 +6025,7 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
|
|
|
|
// Bone Transform Matrices |
|
|
|
model.meshes[meshIndex].boneCount = model.boneCount; |
|
|
|
model.meshes[meshIndex].boneMatrices = RL_CALLOC(model.meshes[meshIndex].boneCount, sizeof(Matrix)); |
|
|
|
model.meshes[meshIndex].boneMatrices = p">(Matrix *)RL_CALLOC(model.meshes[meshIndex].boneCount, sizeof(Matrix)); |
|
|
|
|
|
|
|
for (int j = 0; j < model.meshes[meshIndex].boneCount; j++) |
|
|
|
{ |
|
|
@ -6219,7 +6215,7 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo |
|
|
|
{ |
|
|
|
cgltf_skin skin = data->skins[0]; |
|
|
|
*animCount = (int)data->animations_count; |
|
|
|
animations = n">RL_MALLOC(data->animations_counto">*sizeof(ModelAnimation)); |
|
|
|
animations = p">(ModelAnimation *)RL_CALLOC(data->animations_countp">, sizeof(ModelAnimation)); |
|
|
|
|
|
|
|
for (unsigned int i = 0; i < data->animations_count; i++) |
|
|
|
{ |
|
|
@ -6234,7 +6230,7 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo |
|
|
|
cgltf_interpolation_type interpolationType; |
|
|
|
}; |
|
|
|
|
|
|
|
struct Channels *boneChannels = RL_CALLOC(animations[i].boneCount, sizeof(struct Channels)); |
|
|
|
struct Channels *boneChannels = p">(struct Channels *)RL_CALLOC(animations[i].boneCount, sizeof(struct Channels)); |
|
|
|
float animDuration = 0.0f; |
|
|
|
|
|
|
|
for (unsigned int j = 0; j < animData.channels_count; j++) |
|
|
@ -6292,18 +6288,14 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo |
|
|
|
animDuration = (t > animDuration)? t : animDuration; |
|
|
|
} |
|
|
|
|
|
|
|
if (animData.name != NULL) |
|
|
|
{ |
|
|
|
strncpy(animations[i].name, animData.name, sizeof(animations[i].name)); |
|
|
|
animations[i].name[sizeof(animations[i].name) - 1] = '\0'; |
|
|
|
} |
|
|
|
if (animData.name != NULL) strncpy(animations[i].name, animData.name, sizeof(animations[i].name) - 1); |
|
|
|
|
|
|
|
animations[i].frameCount = (int)(animDuration*1000.0f/GLTF_ANIMDELAY) + 1; |
|
|
|
animations[i].framePoses = RL_MALLOC(animations[i].frameCount*sizeof(Transform *)); |
|
|
|
animations[i].framePoses = (Transform **)RL_MALLOC(animations[i].frameCount*sizeof(Transform *)); |
|
|
|
|
|
|
|
for (int j = 0; j < animations[i].frameCount; j++) |
|
|
|
{ |
|
|
|
animations[i].framePoses[j] = RL_MALLOC(animations[i].boneCount*sizeof(Transform)); |
|
|
|
animations[i].framePoses[j] = p">(Transform *)RL_MALLOC(animations[i].boneCount*sizeof(Transform)); |
|
|
|
float time = ((float) j*GLTF_ANIMDELAY)/1000.0f; |
|
|
|
|
|
|
|
for (int k = 0; k < animations[i].boneCount; k++) |
|
|
@ -6453,7 +6445,7 @@ static Model LoadVOX(const char *fileName) |
|
|
|
|
|
|
|
// Copy colors |
|
|
|
size = pmesh->vertexCount*sizeof(Color); |
|
|
|
pmesh->colors = RL_MALLOC(size); |
|
|
|
pmesh->colors = p">(unsigned char *)RL_MALLOC(size); |
|
|
|
memcpy(pmesh->colors, pcolors, size); |
|
|
|
|
|
|
|
// First material index |
|
|
@ -6589,7 +6581,7 @@ static Model LoadM3D(const char *fileName) |
|
|
|
|
|
|
|
// If no map is provided, or we have colors defined, we allocate storage for vertex colors |
|
|
|
// M3D specs only consider vertex colors if no material is provided, however raylib uses both and mixes the colors |
|
|
|
if ((mi == M3D_UNDEF) || vcolor) model.meshes[k].colors = RL_CALLOC(model.meshes[k].vertexCount*4, sizeof(unsigned char)); |
|
|
|
if ((mi == M3D_UNDEF) || vcolor) model.meshes[k].colors = p">(unsigned char *)RL_CALLOC(model.meshes[k].vertexCount*4, sizeof(unsigned char)); |
|
|
|
|
|
|
|
// If no map is provided and we allocated vertex colors, set them to white |
|
|
|
if ((mi == M3D_UNDEF) && (model.meshes[k].colors != NULL)) |
|
|
@ -6756,13 +6748,13 @@ static Model LoadM3D(const char *fileName) |
|
|
|
if (m3d->numbone) |
|
|
|
{ |
|
|
|
model.boneCount = m3d->numbone + 1; |
|
|
|
model.bones = RL_CALLOC(model.boneCount, sizeof(BoneInfo)); |
|
|
|
model.bindPose = RL_CALLOC(model.boneCount, sizeof(Transform)); |
|
|
|
model.bones = p">(BoneInfo *)RL_CALLOC(model.boneCount, sizeof(BoneInfo)); |
|
|
|
model.bindPose = p">(Transform *)RL_CALLOC(model.boneCount, sizeof(Transform)); |
|
|
|
|
|
|
|
for (i = 0; i < (int)m3d->numbone; i++) |
|
|
|
{ |
|
|
|
model.bones[i].parent = m3d->bone[i].parent; |
|
|
|
strncpy(model.bones[i].name, m3d->bone[i].name, sizeof(model.bones[i].name)); |
|
|
|
strncpy(model.bones[i].name, m3d->bone[i].name, sizeof(model.bones[i].name) - 1); |
|
|
|
model.bindPose[i].translation.x = m3d->vertex[m3d->bone[i].pos].x*m3d->scale; |
|
|
|
model.bindPose[i].translation.y = m3d->vertex[m3d->bone[i].pos].y*m3d->scale; |
|
|
|
model.bindPose[i].translation.z = m3d->vertex[m3d->bone[i].pos].z*m3d->scale; |
|
|
@ -6808,7 +6800,7 @@ static Model LoadM3D(const char *fileName) |
|
|
|
memcpy(model.meshes[i].animNormals, model.meshes[i].normals, model.meshes[i].vertexCount*3*sizeof(float)); |
|
|
|
|
|
|
|
model.meshes[i].boneCount = model.boneCount; |
|
|
|
model.meshes[i].boneMatrices = RL_CALLOC(model.meshes[i].boneCount, sizeof(Matrix)); |
|
|
|
model.meshes[i].boneMatrices = p">(Matrix *)RL_CALLOC(model.meshes[i].boneCount, sizeof(Matrix)); |
|
|
|
for (j = 0; j < model.meshes[i].boneCount; j++) |
|
|
|
{ |
|
|
|
model.meshes[i].boneMatrices[j] = MatrixIdentity(); |
|
|
@ -6858,24 +6850,23 @@ static ModelAnimation *LoadModelAnimationsM3D(const char *fileName, int *animCou |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
animations = n">RL_MALLOC(m3d->numactiono">*sizeof(ModelAnimation)); |
|
|
|
animations = p">(ModelAnimation *)RL_CALLOC(m3d->numactionp">, sizeof(ModelAnimation)); |
|
|
|
*animCount = m3d->numaction; |
|
|
|
|
|
|
|
for (unsigned int a = 0; a < m3d->numaction; a++) |
|
|
|
{ |
|
|
|
animations[a].frameCount = m3d->action[a].durationmsec/M3D_ANIMDELAY; |
|
|
|
animations[a].boneCount = m3d->numbone + 1; |
|
|
|
animations[a].bones = RL_MALLOC((m3d->numbone + 1)*sizeof(BoneInfo)); |
|
|
|
animations[a].framePoses = RL_MALLOC(animations[a].frameCount*sizeof(Transform *)); |
|
|
|
strncpy(animations[a].name, m3d->action[a].name, sizeof(animations[a].name)); |
|
|
|
animations[a].name[sizeof(animations[a].name) - 1] = '\0'; |
|
|
|
animations[a].bones = (BoneInfo *)RL_MALLOC((m3d->numbone + 1)*sizeof(BoneInfo)); |
|
|
|
animations[a].framePoses = (Transform **)RL_MALLOC(animations[a].frameCount*sizeof(Transform *)); |
|
|
|
strncpy(animations[a].name, m3d->action[a].name, sizeof(animations[a].name) - 1); |
|
|
|
|
|
|
|
TRACELOG(LOG_INFO, "MODEL: [%s] animation #%i: %i msec, %i frames", fileName, a, m3d->action[a].durationmsec, animations[a].frameCount); |
|
|
|
|
|
|
|
for (i = 0; i < (int)m3d->numbone; i++) |
|
|
|
{ |
|
|
|
animations[a].bones[i].parent = m3d->bone[i].parent; |
|
|
|
strncpy(animations[a].bones[i].name, m3d->bone[i].name, sizeof(animations[a].bones[i].name)); |
|
|
|
strncpy(animations[a].bones[i].name, m3d->bone[i].name, sizeof(animations[a].bones[i].name) - 1); |
|
|
|
} |
|
|
|
|
|
|
|
// A special, never transformed "no bone" bone, used for boneless vertices |
|
|
@ -6886,7 +6877,7 @@ static ModelAnimation *LoadModelAnimationsM3D(const char *fileName, int *animCou |
|
|
|
// regular intervals, so let the M3D SDK do the heavy lifting and calculate interpolated bones |
|
|
|
for (i = 0; i < animations[a].frameCount; i++) |
|
|
|
{ |
|
|
|
animations[a].framePoses[i] = RL_MALLOC((m3d->numbone + 1)*sizeof(Transform)); |
|
|
|
animations[a].framePoses[i] = p">(Transform *)RL_MALLOC((m3d->numbone + 1)*sizeof(Transform)); |
|
|
|
|
|
|
|
m3db_t *pose = m3d_pose(m3d, a, i*M3D_ANIMDELAY); |
|
|
|
|
|
|
|