|
|
|
@@ -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 = (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 = (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 = (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 = (float *)RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float)); // Default vertex positions
|
|
|
|
|
model.meshes[i].normals = (float *)RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float)); // Default vertex normals
|
|
|
|
|
model.meshes[i].texcoords = (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 = (unsigned char *)RL_CALLOC(model.meshes[i].vertexCount*4, sizeof(unsigned char)); // Up-to 4 bones supported!
|
|
|
|
|
model.meshes[i].boneWeights = (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 = (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 = (float *)RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float));
|
|
|
|
|
model.meshes[i].animNormals = (float *)RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Triangles data processing
|
|
|
|
|
tri = RL_MALLOC(iqmHeader->num_triangles*sizeof(IQMTriangle));
|
|
|
|
|
tri = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (BoneInfo *)RL_MALLOC(iqmHeader->num_joints*sizeof(BoneInfo));
|
|
|
|
|
model.bindPose = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (BoneInfo *)RL_MALLOC(iqmHeader->num_poses*sizeof(BoneInfo));
|
|
|
|
|
animations[a].framePoses = (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] = (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 = (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 = RL_MALLOC(skin.joints_count*sizeof(BoneInfo));
|
|
|
|
|
BoneInfo *bones = (BoneInfo *)RL_CALLOC(skin.joints_count, 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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (unsigned char *)RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(unsigned char));
|
|
|
|
|
model.meshes[meshIndex].boneWeights = (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 = (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 = (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 = (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 = RL_MALLOC(data->animations_count*sizeof(ModelAnimation));
|
|
|
|
|
animations = (ModelAnimation *)RL_CALLOC(data->animations_count, 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 = (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] = (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 = (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 = (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 = (BoneInfo *)RL_CALLOC(model.boneCount, sizeof(BoneInfo));
|
|
|
|
|
model.bindPose = (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 = (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 = RL_MALLOC(m3d->numaction*sizeof(ModelAnimation));
|
|
|
|
|
animations = (ModelAnimation *)RL_CALLOC(m3d->numaction, 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] = (Transform *)RL_MALLOC((m3d->numbone + 1)*sizeof(Transform));
|
|
|
|
|
|
|
|
|
|
m3db_t *pose = m3d_pose(m3d, a, i*M3D_ANIMDELAY);
|
|
|
|
|
|
|
|
|
|