Merge pull request #569 from culacant/master

fixed so it breaks
This commit is contained in:
Ray 2018-07-05 23:47:14 +02:00 committed by GitHub
commit 4ec4481eca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 130 additions and 112 deletions

View File

@ -12,6 +12,7 @@
#include "raylib.h" #include "raylib.h"
#define RIQM_IMPLEMENTATION #define RIQM_IMPLEMENTATION
#define RAYMATH_IMPLEMENTATION
#include "riqm.h" #include "riqm.h"
int main() int main()
@ -30,18 +31,18 @@ int main()
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
camera.fovy = 45.0f; // Camera field-of-view Y camera.fovy = 45.0f; // Camera field-of-view Y
camera.type = CAMERA_PERSPECTIVE; // Camera mode type camera.type = CAMERA_PERSPECTIVE; // Camera mode type
// Load the animated model mesh and basic data // Load the animated model mesh and basic data
AnimatedModel model = LoadAnimatedModel("resources/guy.iqm"); AnimatedModel model = LoadAnimatedModel("resources/guy.iqm");
printf("VER %i\n",rlGetVersion());
// Load model texture and set material // Load model texture and set material
// NOTE: There is only 1 mesh and 1 material (both at index 0), thats what the 2 0's are // NOTE: There is only 1 mesh and 1 material (both at index 0), thats what the 2 0's are
model = AnimatedModelAddTexture(model, "resources/guytex.png"); // REPLACE! model = AnimatedModelAddTexture(model, "resources/guytex.png"); // REPLACE!
model = SetMeshMaterial(model, 0, 0); // REPLACE! model = SetMeshMaterial(model, 0, 0); // REPLACE!
// Load animation data // Load animation data
Animation anim = LoadAnimationFromIQM("resources/guyanim.iqm"); Animation anim = LoadAnimationFromIQM("resources/guyanim.iqm");
int animFrameCounter = 0; int animFrameCounter = 0;
SetCameraMode(camera, CAMERA_FREE); // Set free camera mode SetCameraMode(camera, CAMERA_FREE); // Set free camera mode
@ -55,7 +56,7 @@ int main()
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
UpdateCamera(&camera); UpdateCamera(&camera);
// Play animation when spacebar is held down // Play animation when spacebar is held down
if (IsKeyDown(KEY_SPACE)) if (IsKeyDown(KEY_SPACE))
{ {
@ -67,17 +68,17 @@ int main()
// Draw // Draw
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
BeginDrawing(); BeginDrawing();
ClearBackground(RAYWHITE); ClearBackground(RAYWHITE);
BeginMode3D(camera); BeginMode3D(camera);
DrawAnimatedModel(model, Vector3Zero(), 1.0f, WHITE); // Draw animated model DrawAnimatedModel(model, Vector3Zero(), 1.0f, WHITE); // Draw animated model
DrawGrid(10, 1.0f); // Draw a grid DrawGrid(10, 1.0f); // Draw a grid
EndMode3D(); EndMode3D();
DrawText("(c) Guy IQM 3D model by -------", screenWidth - 200, screenHeight - 20, 10, GRAY); DrawText("(c) Guy IQM 3D model by -------", screenWidth - 200, screenHeight - 20, 10, GRAY);
DrawFPS(10, 10); DrawFPS(10, 10);

View File

@ -34,6 +34,11 @@
#ifndef RIQM_H #ifndef RIQM_H
#define RIQM_H #define RIQM_H
// TODO dont break everything
static bool vaoSupported = false;
static Matrix modelview;
static Matrix projection;
#include <stdio.h> // Required for: FILE #include <stdio.h> // Required for: FILE
//#define RIQM_STATIC //#define RIQM_STATIC
@ -68,26 +73,26 @@ typedef struct Pose {
typedef struct Animation { typedef struct Animation {
int jointCount; int jointCount;
Joint *joints; // NOTE: Joints in anims do not have names Joint *joints; // NOTE: Joints in anims do not have names
int frameCount; int frameCount;
float framerate; float framerate;
Pose **framepose; Pose **framepose;
} Animation; } Animation;
typedef struct AnimatedMesh { typedef struct AnimatedMesh {
char name[MESH_NAME_LENGTH]; char name[MESH_NAME_LENGTH];
int vertexCount; int vertexCount;
int triangleCount; int triangleCount;
float *vertices; float *vertices;
float *normals; float *normals;
float *texcoords; float *texcoords;
float *animVertices; float *animVertices;
float *animNormals; float *animNormals;
unsigned short *triangles; unsigned short *triangles;
int *weightId; int *weightId;
float *weightBias; float *weightBias;
@ -98,14 +103,14 @@ typedef struct AnimatedMesh {
typedef struct AnimatedModel { typedef struct AnimatedModel {
int meshCount; int meshCount;
AnimatedMesh *mesh; AnimatedMesh *mesh;
int materialCount; int materialCount;
int *meshMaterialId; int *meshMaterialId;
Material *materials; Material *materials;
int jointCount; int jointCount;
Joint *joints; Joint *joints;
Pose *basepose; Pose *basepose;
Matrix transform; Matrix transform;
} AnimatedModel; } AnimatedModel;
@ -268,6 +273,18 @@ void rlLoadAnimatedMesh(AnimatedMesh *amesh, bool dynamic)
amesh->vboId[5] = 0; // Vertex texcoords2 VBO UNUSED amesh->vboId[5] = 0; // Vertex texcoords2 VBO UNUSED
amesh->vboId[6] = 0; // Vertex indices VBO amesh->vboId[6] = 0; // Vertex indices VBO
#if defined(GRAPHICS_API_OPENGL_11)
TraceLog(LOG_WARNING, "OGL 11");
#endif
#if defined(GRAPHICS_API_OPENGL_21)
TraceLog(LOG_WARNING, "OGL 21");
#endif
#if defined(GRAPHICS_API_OPENGL_33)
TraceLog(LOG_WARNING, "OGL 33");
#endif
#if defined(GRAPHICS_API_OPENGL_ES2)
TraceLog(LOG_WARNING, "OGL ES2");
#endif
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
int drawHint = GL_STATIC_DRAW; int drawHint = GL_STATIC_DRAW;
if (dynamic) drawHint = GL_DYNAMIC_DRAW; if (dynamic) drawHint = GL_DYNAMIC_DRAW;
@ -467,7 +484,7 @@ void rlDrawAnimatedMesh(AnimatedMesh amesh, Material material, Matrix transform)
rlPushMatrix(); rlPushMatrix();
rlMultMatrixf(MatrixToFloat(transform)); rlMultMatrixf(MatrixToFloat(transform));
rlColor4ub(material.maps[MAP_DIFFUSE].color.rotation, material.maps[MAP_DIFFUSE].color.g, material.maps[MAP_DIFFUSE].color.b, material.maps[MAP_DIFFUSE].color.a); rlColor4ub(material.maps[MAP_DIFFUSE].color.r, material.maps[MAP_DIFFUSE].color.g, material.maps[MAP_DIFFUSE].color.b, material.maps[MAP_DIFFUSE].color.a);
if (amesh.triangles != NULL) glDrawElements(GL_TRIANGLES, amesh.triangleCount*3, GL_UNSIGNED_SHORT, amesh.triangles); if (amesh.triangles != NULL) glDrawElements(GL_TRIANGLES, amesh.triangleCount*3, GL_UNSIGNED_SHORT, amesh.triangles);
else glDrawArrays(GL_TRIANGLES, 0, amesh.vertexCount); else glDrawArrays(GL_TRIANGLES, 0, amesh.vertexCount);
@ -485,29 +502,29 @@ void rlDrawAnimatedMesh(AnimatedMesh amesh, Material material, Matrix transform)
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Bind shader program // Bind shader program
glUseProgram(material.scalehader.id); glUseProgram(material.shader.id);
// Matrices and other values required by shader // Matrices and other values required by shader
//----------------------------------------------------- //-----------------------------------------------------
// Calculate and send to shader model matrix (used by PBR shader) // Calculate and send to shader model matrix (used by PBR shader)
if (material.scalehader.locs[LOC_MATRIX_MODEL] != -1) SetShaderValueMatrix(material.scalehader, material.scalehader.locs[LOC_MATRIX_MODEL], transform); if (material.shader.locs[LOC_MATRIX_MODEL] != -1) SetShaderValueMatrix(material.shader, material.shader.locs[LOC_MATRIX_MODEL], transform);
// Upload to shader material.colDiffuse // Upload to shader material.colDiffuse
if (material.scalehader.locs[LOC_COLOR_DIFFUSE] != -1) if (material.shader.locs[LOC_COLOR_DIFFUSE] != -1)
glUniform4f(material.scalehader.locs[LOC_COLOR_DIFFUSE], (float)material.maps[MAP_DIFFUSE].color.rotation/255.0f, glUniform4f(material.shader.locs[LOC_COLOR_DIFFUSE], (float)material.maps[MAP_DIFFUSE].color.r/255.0f,
(float)material.maps[MAP_DIFFUSE].color.g/255.0f, (float)material.maps[MAP_DIFFUSE].color.g/255.0f,
(float)material.maps[MAP_DIFFUSE].color.b/255.0f, (float)material.maps[MAP_DIFFUSE].color.b/255.0f,
(float)material.maps[MAP_DIFFUSE].color.a/255.0f); (float)material.maps[MAP_DIFFUSE].color.a/255.0f);
// Upload to shader material.colSpecular (if available) // Upload to shader material.colSpecular (if available)
if (material.scalehader.locs[LOC_COLOR_SPECULAR] != -1) if (material.shader.locs[LOC_COLOR_SPECULAR] != -1)
glUniform4f(material.scalehader.locs[LOC_COLOR_SPECULAR], (float)material.maps[MAP_SPECULAR].color.rotation/255.0f, glUniform4f(material.shader.locs[LOC_COLOR_SPECULAR], (float)material.maps[MAP_SPECULAR].color.r/255.0f,
(float)material.maps[MAP_SPECULAR].color.g/255.0f, (float)material.maps[MAP_SPECULAR].color.g/255.0f,
(float)material.maps[MAP_SPECULAR].color.b/255.0f, (float)material.maps[MAP_SPECULAR].color.b/255.0f,
(float)material.maps[MAP_SPECULAR].color.a/255.0f); (float)material.maps[MAP_SPECULAR].color.a/255.0f);
if (material.scalehader.locs[LOC_MATRIX_VIEW] != -1) SetShaderValueMatrix(material.scalehader, material.scalehader.locs[LOC_MATRIX_VIEW], modelview); if (material.shader.locs[LOC_MATRIX_VIEW] != -1) SetShaderValueMatrix(material.shader, material.shader.locs[LOC_MATRIX_VIEW], modelview);
if (material.scalehader.locs[LOC_MATRIX_PROJECTION] != -1) SetShaderValueMatrix(material.scalehader, material.scalehader.locs[LOC_MATRIX_PROJECTION], projection); if (material.shader.locs[LOC_MATRIX_PROJECTION] != -1) SetShaderValueMatrix(material.shader, material.shader.locs[LOC_MATRIX_PROJECTION], projection);
// At this point the modelview matrix just contains the view matrix (camera) // At this point the modelview matrix just contains the view matrix (camera)
// That's because BeginMode3D() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix() // That's because BeginMode3D() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix()
@ -527,7 +544,7 @@ void rlDrawAnimatedMesh(AnimatedMesh amesh, Material material, Matrix transform)
if ((i == MAP_IRRADIANCE) || (i == MAP_PREFILTER) || (i == MAP_CUBEMAP)) glBindTexture(GL_TEXTURE_CUBE_MAP, material.maps[i].texture.id); if ((i == MAP_IRRADIANCE) || (i == MAP_PREFILTER) || (i == MAP_CUBEMAP)) glBindTexture(GL_TEXTURE_CUBE_MAP, material.maps[i].texture.id);
else glBindTexture(GL_TEXTURE_2D, material.maps[i].texture.id); else glBindTexture(GL_TEXTURE_2D, material.maps[i].texture.id);
glUniform1i(material.scalehader.locs[LOC_MAP_DIFFUSE + i], i); glUniform1i(material.shader.locs[LOC_MAP_DIFFUSE + i], i);
} }
} }
@ -539,54 +556,54 @@ void rlDrawAnimatedMesh(AnimatedMesh amesh, Material material, Matrix transform)
// Bind mesh VBO data: vertex position (shader-location = 0) // Bind mesh VBO data: vertex position (shader-location = 0)
glBindBuffer(GL_ARRAY_BUFFER, amesh.vboId[0]); glBindBuffer(GL_ARRAY_BUFFER, amesh.vboId[0]);
glVertexAttribPointer(material.scalehader.locs[LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(material.shader.locs[LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(material.scalehader.locs[LOC_VERTEX_POSITION]); glEnableVertexAttribArray(material.shader.locs[LOC_VERTEX_POSITION]);
// Bind mesh VBO data: vertex texcoords (shader-location = 1) // Bind mesh VBO data: vertex texcoords (shader-location = 1)
glBindBuffer(GL_ARRAY_BUFFER, amesh.vboId[1]); glBindBuffer(GL_ARRAY_BUFFER, amesh.vboId[1]);
glVertexAttribPointer(material.scalehader.locs[LOC_VERTEX_TEXCOORD01], 2, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(material.shader.locs[LOC_VERTEX_TEXCOORD01], 2, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(material.scalehader.locs[LOC_VERTEX_TEXCOORD01]); glEnableVertexAttribArray(material.shader.locs[LOC_VERTEX_TEXCOORD01]);
// Bind mesh VBO data: vertex normals (shader-location = 2, if available) // Bind mesh VBO data: vertex normals (shader-location = 2, if available)
if (material.scalehader.locs[LOC_VERTEX_NORMAL] != -1) if (material.shader.locs[LOC_VERTEX_NORMAL] != -1)
{ {
glBindBuffer(GL_ARRAY_BUFFER, amesh.vboId[2]); glBindBuffer(GL_ARRAY_BUFFER, amesh.vboId[2]);
glVertexAttribPointer(material.scalehader.locs[LOC_VERTEX_NORMAL], 3, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(material.shader.locs[LOC_VERTEX_NORMAL], 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(material.scalehader.locs[LOC_VERTEX_NORMAL]); glEnableVertexAttribArray(material.shader.locs[LOC_VERTEX_NORMAL]);
} }
// Bind mesh VBO data: vertex colors (shader-location = 3, if available) // Bind mesh VBO data: vertex colors (shader-location = 3, if available)
if (material.scalehader.locs[LOC_VERTEX_COLOR] != -1) if (material.shader.locs[LOC_VERTEX_COLOR] != -1)
{ {
if (amesh.vboId[3] != 0) if (amesh.vboId[3] != 0)
{ {
glBindBuffer(GL_ARRAY_BUFFER, amesh.vboId[3]); glBindBuffer(GL_ARRAY_BUFFER, amesh.vboId[3]);
glVertexAttribPointer(material.scalehader.locs[LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); glVertexAttribPointer(material.shader.locs[LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
glEnableVertexAttribArray(material.scalehader.locs[LOC_VERTEX_COLOR]); glEnableVertexAttribArray(material.shader.locs[LOC_VERTEX_COLOR]);
} }
else else
{ {
// Set default value for unused attribute // Set default value for unused attribute
// NOTE: Required when using default shader and no VAO support // NOTE: Required when using default shader and no VAO support
glVertexAttrib4f(material.scalehader.locs[LOC_VERTEX_COLOR], 1.0f, 1.0f, 1.0f, 1.0f); glVertexAttrib4f(material.shader.locs[LOC_VERTEX_COLOR], 1.0f, 1.0f, 1.0f, 1.0f);
glDisableVertexAttribArray(material.scalehader.locs[LOC_VERTEX_COLOR]); glDisableVertexAttribArray(material.shader.locs[LOC_VERTEX_COLOR]);
} }
} }
// Bind mesh VBO data: vertex tangents (shader-location = 4, if available) // Bind mesh VBO data: vertex tangents (shader-location = 4, if available)
if (material.scalehader.locs[LOC_VERTEX_TANGENT] != -1) if (material.shader.locs[LOC_VERTEX_TANGENT] != -1)
{ {
glBindBuffer(GL_ARRAY_BUFFER, amesh.vboId[4]); glBindBuffer(GL_ARRAY_BUFFER, amesh.vboId[4]);
glVertexAttribPointer(material.scalehader.locs[LOC_VERTEX_TANGENT], 4, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(material.shader.locs[LOC_VERTEX_TANGENT], 4, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(material.scalehader.locs[LOC_VERTEX_TANGENT]); glEnableVertexAttribArray(material.shader.locs[LOC_VERTEX_TANGENT]);
} }
// Bind mesh VBO data: vertex texcoords2 (shader-location = 5, if available) // Bind mesh VBO data: vertex texcoords2 (shader-location = 5, if available)
if (material.scalehader.locs[LOC_VERTEX_TEXCOORD02] != -1) if (material.shader.locs[LOC_VERTEX_TEXCOORD02] != -1)
{ {
glBindBuffer(GL_ARRAY_BUFFER, amesh.vboId[5]); glBindBuffer(GL_ARRAY_BUFFER, amesh.vboId[5]);
glVertexAttribPointer(material.scalehader.locs[LOC_VERTEX_TEXCOORD02], 2, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(material.shader.locs[LOC_VERTEX_TEXCOORD02], 2, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(material.scalehader.locs[LOC_VERTEX_TEXCOORD02]); glEnableVertexAttribArray(material.shader.locs[LOC_VERTEX_TEXCOORD02]);
} }
if (amesh.triangles != NULL) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, amesh.vboId[6]); if (amesh.triangles != NULL) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, amesh.vboId[6]);
@ -608,7 +625,7 @@ void rlDrawAnimatedMesh(AnimatedMesh amesh, Material material, Matrix transform)
Matrix matMVP = MatrixMultiply(modelview, projection); // Transform to screen-space coordinates Matrix matMVP = MatrixMultiply(modelview, projection); // Transform to screen-space coordinates
// Send combined model-view-projection matrix to shader // Send combined model-view-projection matrix to shader
glUniformMatrix4fv(material.scalehader.locs[LOC_MATRIX_MVP], 1, false, MatrixToFloat(matMVP)); glUniformMatrix4fv(material.shader.locs[LOC_MATRIX_MVP], 1, false, MatrixToFloat(matMVP));
// Draw call! // Draw call!
if (amesh.triangles != NULL) glDrawElements(GL_TRIANGLES, amesh.triangleCount*3, GL_UNSIGNED_SHORT, 0); // Indexed vertices draw if (amesh.triangles != NULL) glDrawElements(GL_TRIANGLES, amesh.triangleCount*3, GL_UNSIGNED_SHORT, 0); // Indexed vertices draw
@ -649,14 +666,14 @@ extern "C" { // Prevents name mangling of functions
AnimatedModel LoadAnimatedModel(const char *filename) AnimatedModel LoadAnimatedModel(const char *filename)
{ {
AnimatedModel out = LoadIQM(filename); AnimatedModel out = LoadIQM(filename);
for (int i = 0; i < out.meshCount; i++) rlLoadAnimatedMesh(&out.mesh[i], false); for (int i = 0; i < out.meshCount; i++) rlLoadAnimatedMesh(&out.mesh[i], false);
out.transform = MatrixIdentity(); out.transform = MatrixIdentity();
out.meshMaterialId = malloc(sizeof(int)*out.meshCount); out.meshMaterialId = malloc(sizeof(int)*out.meshCount);
out.materials = NULL; out.materials = NULL;
out.materialCount = 0; out.materialCount = 0;
for (int i = 0; i < out.meshCount; i++) out.meshMaterialId[i] = -1; for (int i = 0; i < out.meshCount; i++) out.meshMaterialId[i] = -1;
return out; return out;
@ -666,32 +683,32 @@ AnimatedModel LoadAnimatedModel(const char *filename)
AnimatedModel AnimatedModelAddTexture(AnimatedModel model, const char *filename) AnimatedModel AnimatedModelAddTexture(AnimatedModel model, const char *filename)
{ {
Texture2D texture = LoadTexture(filename); Texture2D texture = LoadTexture(filename);
model.materials = realloc(model.materials, sizeof(Material)*(model.materialCount + 1)); model.materials = realloc(model.materials, sizeof(Material)*(model.materialCount + 1));
model.materials[model.materialCount] = LoadMaterialDefault(); model.materials[model.materialCount] = LoadMaterialDefault();
model.materials[model.materialCount].maps[MAP_DIFFUSE].texture = texture; model.materials[model.materialCount].maps[MAP_DIFFUSE].texture = texture;
model.materialCount++; model.materialCount++;
return model; return model;
} }
// Set the material for a mesh // Set the material for a mesh
AnimatedModel SetMeshMaterial(AnimatedModel model, int meshid, int textureid) AnimatedModel SetMeshMaterial(AnimatedModel model, int meshid, int textureid)
{ {
if (meshid > model.meshCount) if (meshid > model.meshCount)
{ {
TraceLog(LOG_WARNING, "MeshId greater than meshCount\n"); TraceLog(LOG_WARNING, "MeshId greater than meshCount\n");
return model; return model;
} }
if (textureid > model.materialCount) if (textureid > model.materialCount)
{ {
TraceLog(LOG_WARNING,"textureid greater than materialCount\n"); TraceLog(LOG_WARNING,"textureid greater than materialCount\n");
return model; return model;
} }
model.meshMaterialId[meshid] = textureid; model.meshMaterialId[meshid] = textureid;
return model; return model;
} }
@ -699,18 +716,18 @@ AnimatedModel SetMeshMaterial(AnimatedModel model, int meshid, int textureid)
Animation LoadAnimationFromIQM(const char *filename) Animation LoadAnimationFromIQM(const char *filename)
{ {
Animation animation = { 0 }; Animation animation = { 0 };
FILE *iqmFile; FILE *iqmFile;
IQMHeader iqm; IQMHeader iqm;
iqmFile = fopen(filename,"rb"); iqmFile = fopen(filename,"rb");
if (!iqmFile) if (!iqmFile)
{ {
TraceLog(LOG_ERROR, "[%s] Unable to open file", filename); TraceLog(LOG_ERROR, "[%s] Unable to open file", filename);
return animation; return animation;
} }
// header // header
fread(&iqm, sizeof(IQMHeader), 1, iqmFile); fread(&iqm, sizeof(IQMHeader), 1, iqmFile);
@ -720,17 +737,17 @@ Animation LoadAnimationFromIQM(const char *filename)
fclose(iqmFile); fclose(iqmFile);
return animation; return animation;
} }
if (iqm.version != IQM_VERSION) if (iqm.version != IQM_VERSION)
{ {
TraceLog(LOG_ERROR, "IQM version %i is incorrect.", iqm.version); TraceLog(LOG_ERROR, "IQM version %i is incorrect.", iqm.version);
fclose(iqmFile); fclose(iqmFile);
return animation; return animation;
} }
// header // header
if (iqm.num_anims > 1) TraceLog(LOG_WARNING, "More than 1 animation in file, only the first one will get loaded"); if (iqm.num_anims > 1) TraceLog(LOG_WARNING, "More than 1 animation in file, only the first one will get loaded");
// joints // joints
IQMPose *poses; IQMPose *poses;
poses = malloc(sizeof(IQMPose)*iqm.num_poses); poses = malloc(sizeof(IQMPose)*iqm.num_poses);
@ -739,7 +756,7 @@ Animation LoadAnimationFromIQM(const char *filename)
animation.jointCount = iqm.num_poses; animation.jointCount = iqm.num_poses;
animation.joints = malloc(sizeof(Joint)*iqm.num_poses); animation.joints = malloc(sizeof(Joint)*iqm.num_poses);
for (int j = 0; j < iqm.num_poses; j++) for (int j = 0; j < iqm.num_poses; j++)
{ {
strcpy(animation.joints[j].name, ANIMJOINTNAME); strcpy(animation.joints[j].name, ANIMJOINTNAME);
@ -763,91 +780,91 @@ Animation LoadAnimationFromIQM(const char *filename)
for (int j = 0; j < anim.num_frames; j++) animation.framepose[j] = malloc(sizeof(Pose)*iqm.num_poses); for (int j = 0; j < anim.num_frames; j++) animation.framepose[j] = malloc(sizeof(Pose)*iqm.num_poses);
int dcounter = anim.first_frame*iqm.num_framechannels; int dcounter = anim.first_frame*iqm.num_framechannels;
for (int frame = 0; frame < anim.num_frames; frame++) for (int frame = 0; frame < anim.num_frames; frame++)
{ {
for (int i = 0; i < iqm.num_poses; i++) for (int i = 0; i < iqm.num_poses; i++)
{ {
animation.framepose[frame][i].translation.x = poses[i].channeloffset[0]; animation.framepose[frame][i].translation.x = poses[i].channeloffset[0];
if (poses[i].mask & 0x01) if (poses[i].mask & 0x01)
{ {
animation.framepose[frame][i].translation.x += framedata[dcounter]*poses[i].channelscale[0]; animation.framepose[frame][i].translation.x += framedata[dcounter]*poses[i].channelscale[0];
dcounter++; dcounter++;
} }
animation.framepose[frame][i].translation.y = poses[i].channeloffset[1]; animation.framepose[frame][i].translation.y = poses[i].channeloffset[1];
if (poses[i].mask & 0x02) if (poses[i].mask & 0x02)
{ {
animation.framepose[frame][i].translation.y += framedata[dcounter]*poses[i].channelscale[1]; animation.framepose[frame][i].translation.y += framedata[dcounter]*poses[i].channelscale[1];
dcounter++; dcounter++;
} }
animation.framepose[frame][i].translation.z = poses[i].channeloffset[2]; animation.framepose[frame][i].translation.z = poses[i].channeloffset[2];
if (poses[i].mask & 0x04) if (poses[i].mask & 0x04)
{ {
animation.framepose[frame][i].translation.z += framedata[dcounter]*poses[i].channelscale[2]; animation.framepose[frame][i].translation.z += framedata[dcounter]*poses[i].channelscale[2];
dcounter++; dcounter++;
} }
animation.framepose[frame][i].rotation.x = poses[i].channeloffset[3]; animation.framepose[frame][i].rotation.x = poses[i].channeloffset[3];
if (poses[i].mask & 0x08) if (poses[i].mask & 0x08)
{ {
animation.framepose[frame][i].rotation.x += framedata[dcounter]*poses[i].channelscale[3]; animation.framepose[frame][i].rotation.x += framedata[dcounter]*poses[i].channelscale[3];
dcounter++; dcounter++;
} }
animation.framepose[frame][i].rotation.y = poses[i].channeloffset[4]; animation.framepose[frame][i].rotation.y = poses[i].channeloffset[4];
if (poses[i].mask & 0x10) if (poses[i].mask & 0x10)
{ {
animation.framepose[frame][i].rotation.y += framedata[dcounter]*poses[i].channelscale[4]; animation.framepose[frame][i].rotation.y += framedata[dcounter]*poses[i].channelscale[4];
dcounter++; dcounter++;
} }
animation.framepose[frame][i].rotation.z = poses[i].channeloffset[5]; animation.framepose[frame][i].rotation.z = poses[i].channeloffset[5];
if (poses[i].mask & 0x20) if (poses[i].mask & 0x20)
{ {
animation.framepose[frame][i].rotation.z += framedata[dcounter]*poses[i].channelscale[5]; animation.framepose[frame][i].rotation.z += framedata[dcounter]*poses[i].channelscale[5];
dcounter++; dcounter++;
} }
animation.framepose[frame][i].rotation.w = poses[i].channeloffset[6]; animation.framepose[frame][i].rotation.w = poses[i].channeloffset[6];
if (poses[i].mask & 0x40) if (poses[i].mask & 0x40)
{ {
animation.framepose[frame][i].rotation.w += framedata[dcounter]*poses[i].channelscale[6]; animation.framepose[frame][i].rotation.w += framedata[dcounter]*poses[i].channelscale[6];
dcounter++; dcounter++;
} }
animation.framepose[frame][i].scale.x = poses[i].channeloffset[7]; animation.framepose[frame][i].scale.x = poses[i].channeloffset[7];
if (poses[i].mask & 0x80) if (poses[i].mask & 0x80)
{ {
animation.framepose[frame][i].scale.x += framedata[dcounter]*poses[i].channelscale[7]; animation.framepose[frame][i].scale.x += framedata[dcounter]*poses[i].channelscale[7];
dcounter++; dcounter++;
} }
animation.framepose[frame][i].scale.y = poses[i].channeloffset[8]; animation.framepose[frame][i].scale.y = poses[i].channeloffset[8];
if (poses[i].mask & 0x100) if (poses[i].mask & 0x100)
{ {
animation.framepose[frame][i].scale.y += framedata[dcounter]*poses[i].channelscale[8]; animation.framepose[frame][i].scale.y += framedata[dcounter]*poses[i].channelscale[8];
dcounter++; dcounter++;
} }
animation.framepose[frame][i].scale.z = poses[i].channeloffset[9]; animation.framepose[frame][i].scale.z = poses[i].channeloffset[9];
if (poses[i].mask & 0x200) if (poses[i].mask & 0x200)
{ {
animation.framepose[frame][i].scale.z += framedata[dcounter]*poses[i].channelscale[9]; animation.framepose[frame][i].scale.z += framedata[dcounter]*poses[i].channelscale[9];
dcounter++; dcounter++;
} }
animation.framepose[frame][i].rotation = QuaternionNormalize(animation.framepose[frame][i].rotation); animation.framepose[frame][i].rotation = QuaternionNormalize(animation.framepose[frame][i].rotation);
} }
} }
@ -869,7 +886,7 @@ Animation LoadAnimationFromIQM(const char *filename)
free(framedata); free(framedata);
free(poses); free(poses);
fclose(iqmFile); fclose(iqmFile);
return animation; return animation;
@ -882,7 +899,7 @@ void UnloadAnimatedModel(AnimatedModel model)
free(model.meshMaterialId); free(model.meshMaterialId);
free(model.joints); free(model.joints);
free(model.basepose); free(model.basepose);
for (int i = 0; i < model.meshCount; i++) rlUnloadAnimatedMesh(&model.mesh[i]); for (int i = 0; i < model.meshCount; i++) rlUnloadAnimatedMesh(&model.mesh[i]);
free(model.mesh); free(model.mesh);
@ -893,7 +910,7 @@ void UnloadAnimation(Animation anim)
{ {
free(anim.joints); free(anim.joints);
free(anim.framepose); free(anim.framepose);
for (int i = 0; i < anim.frameCount; i++) free(anim.framepose[i]); for (int i = 0; i < anim.frameCount; i++) free(anim.framepose[i]);
} }
@ -901,12 +918,12 @@ void UnloadAnimation(Animation anim)
bool CheckSkeletonsMatch(AnimatedModel model, Animation anim) bool CheckSkeletonsMatch(AnimatedModel model, Animation anim)
{ {
if (model.jointCount != anim.jointCount) return 0; if (model.jointCount != anim.jointCount) return 0;
for (int i = 0; i < model.jointCount; i++) for (int i = 0; i < model.jointCount; i++)
{ {
if (model.joints[i].parent != anim.joints[i].parent) return 0; if (model.joints[i].parent != anim.joints[i].parent) return 0;
} }
return 1; return 1;
} }
@ -931,7 +948,7 @@ void AnimateModel(AnimatedModel model, Animation anim, int frame)
int vcounter = 0; int vcounter = 0;
int wcounter = 0; int wcounter = 0;
int weightId = 0; int weightId = 0;
for (int i = 0; i < model.mesh[m].vertexCount; i++) for (int i = 0; i < model.mesh[m].vertexCount; i++)
{ {
weightId = model.mesh[m].weightId[wcounter]; weightId = model.mesh[m].weightId[wcounter];
@ -941,7 +958,7 @@ void AnimateModel(AnimatedModel model, Animation anim, int frame)
outt = anim.framepose[frame][weightId].translation; outt = anim.framepose[frame][weightId].translation;
outr = anim.framepose[frame][weightId].rotation; outr = anim.framepose[frame][weightId].rotation;
outs = anim.framepose[frame][weightId].scale; outs = anim.framepose[frame][weightId].scale;
// vertices // vertices
outv = (Vector3){model.mesh[m].vertices[vcounter],model.mesh[m].vertices[vcounter + 1],model.mesh[m].vertices[vcounter + 2]}; outv = (Vector3){model.mesh[m].vertices[vcounter],model.mesh[m].vertices[vcounter + 1],model.mesh[m].vertices[vcounter + 2]};
outv = Vector3MultiplyV(outv,outs); outv = Vector3MultiplyV(outv,outs);
@ -951,7 +968,7 @@ void AnimateModel(AnimatedModel model, Animation anim, int frame)
model.mesh[m].animVertices[vcounter] = outv.x; model.mesh[m].animVertices[vcounter] = outv.x;
model.mesh[m].animVertices[vcounter + 1] = outv.y; model.mesh[m].animVertices[vcounter + 1] = outv.y;
model.mesh[m].animVertices[vcounter + 2] = outv.z; model.mesh[m].animVertices[vcounter + 2] = outv.z;
// normals // normals
outn = (Vector3){model.mesh[m].normals[vcounter],model.mesh[m].normals[vcounter + 1],model.mesh[m].normals[vcounter + 2]}; outn = (Vector3){model.mesh[m].normals[vcounter],model.mesh[m].normals[vcounter + 1],model.mesh[m].normals[vcounter + 2]};
outn = Vector3RotateByQuaternion(outn,QuaternionMultiply(outr,QuaternionInvert(baser))); outn = Vector3RotateByQuaternion(outn,QuaternionMultiply(outr,QuaternionInvert(baser)));
@ -969,7 +986,7 @@ void DrawAnimatedModel(AnimatedModel model,Vector3 position,float scale,Color ti
{ {
Vector3 vScale = { scale, scale, scale }; Vector3 vScale = { scale, scale, scale };
Vector3 rotationAxis = { 0.0f,0.0f,0.0f }; Vector3 rotationAxis = { 0.0f,0.0f,0.0f };
DrawAnimatedModelEx(model, position, rotationAxis, 0.0f, vScale, tint); DrawAnimatedModelEx(model, position, rotationAxis, 0.0f, vScale, tint);
} }
@ -981,14 +998,14 @@ void DrawAnimatedModelEx(AnimatedModel model,Vector3 position,Vector3 rotationAx
TraceLog(LOG_WARNING,"No materials set, can't draw animated mesh\n"); TraceLog(LOG_WARNING,"No materials set, can't draw animated mesh\n");
return; return;
} }
Matrix matScale = MatrixScale(scale.x,scale.y,scale.z); Matrix matScale = MatrixScale(scale.x,scale.y,scale.z);
Matrix matRotation = MatrixRotate(rotationAxis,rotationAngle*DEG2RAD); Matrix matRotation = MatrixRotate(rotationAxis,rotationAngle*DEG2RAD);
Matrix matTranslation = MatrixTranslate(position.x,position.y,position.z); Matrix matTranslation = MatrixTranslate(position.x,position.y,position.z);
Matrix matTransform = MatrixMultiply(MatrixMultiply(matScale,matRotation),matTranslation); Matrix matTransform = MatrixMultiply(MatrixMultiply(matScale,matRotation),matTranslation);
model.transform = MatrixMultiply(model.transform,matTransform); model.transform = MatrixMultiply(model.transform,matTransform);
for (int i = 0; i < model.meshCount; i++) for (int i = 0; i < model.meshCount; i++)
{ {
rlUpdateAnimatedMesh(&model.mesh[i]); rlUpdateAnimatedMesh(&model.mesh[i]);
@ -1005,7 +1022,7 @@ void DrawAnimatedModelEx(AnimatedModel model,Vector3 position,Vector3 rotationAx
static AnimatedModel LoadIQM(const char *filename) static AnimatedModel LoadIQM(const char *filename)
{ {
AnimatedModel model = { 0 }; AnimatedModel model = { 0 };
FILE *iqmFile; FILE *iqmFile;
IQMHeader iqm; IQMHeader iqm;
@ -1013,7 +1030,7 @@ static AnimatedModel LoadIQM(const char *filename)
IQMTriangle *tri; IQMTriangle *tri;
IQMVertexArray *va; IQMVertexArray *va;
IQMJoint *ijoint; IQMJoint *ijoint;
float *vertex; float *vertex;
float *normal; float *normal;
float *text; float *text;
@ -1021,13 +1038,13 @@ static AnimatedModel LoadIQM(const char *filename)
unsigned char *blendw; unsigned char *blendw;
iqmFile = fopen(filename, "rb"); iqmFile = fopen(filename, "rb");
if (!iqmFile) if (!iqmFile)
{ {
TraceLog(LOG_ERROR, "[%s] Unable to open file", filename); TraceLog(LOG_ERROR, "[%s] Unable to open file", filename);
return model; return model;
} }
// header // header
fread(&iqm,sizeof(IQMHeader), 1, iqmFile); fread(&iqm,sizeof(IQMHeader), 1, iqmFile);
@ -1037,14 +1054,14 @@ static AnimatedModel LoadIQM(const char *filename)
fclose(iqmFile); fclose(iqmFile);
return model; return model;
} }
if(iqm.version != IQM_VERSION) if(iqm.version != IQM_VERSION)
{ {
TraceLog(LOG_ERROR, "IQM version %i is incorrect.", iqm.version); TraceLog(LOG_ERROR, "IQM version %i is incorrect.", iqm.version);
fclose(iqmFile); fclose(iqmFile);
return model; return model;
} }
// meshes // meshes
imesh = malloc(sizeof(IQMMesh)*iqm.num_meshes); imesh = malloc(sizeof(IQMMesh)*iqm.num_meshes);
fseek(iqmFile, iqm.ofs_meshes, SEEK_SET); fseek(iqmFile, iqm.ofs_meshes, SEEK_SET);
@ -1052,7 +1069,7 @@ static AnimatedModel LoadIQM(const char *filename)
model.meshCount = iqm.num_meshes; model.meshCount = iqm.num_meshes;
model.mesh = malloc(sizeof(AnimatedMesh)*iqm.num_meshes); model.mesh = malloc(sizeof(AnimatedMesh)*iqm.num_meshes);
for (int i = 0; i < iqm.num_meshes; i++) for (int i = 0; i < iqm.num_meshes; i++)
{ {
fseek(iqmFile,iqm.ofs_text+imesh[i].name,SEEK_SET); fseek(iqmFile,iqm.ofs_text+imesh[i].name,SEEK_SET);
@ -1068,7 +1085,7 @@ static AnimatedModel LoadIQM(const char *filename)
model.mesh[i].animVertices = malloc(sizeof(float)*imesh[i].num_vertexes*3); model.mesh[i].animVertices = malloc(sizeof(float)*imesh[i].num_vertexes*3);
model.mesh[i].animNormals = malloc(sizeof(float)*imesh[i].num_vertexes*3); model.mesh[i].animNormals = malloc(sizeof(float)*imesh[i].num_vertexes*3);
} }
// tris // tris
tri = malloc(sizeof(IQMTriangle)*iqm.num_triangles); tri = malloc(sizeof(IQMTriangle)*iqm.num_triangles);
fseek(iqmFile, iqm.ofs_triangles, SEEK_SET); fseek(iqmFile, iqm.ofs_triangles, SEEK_SET);
@ -1077,7 +1094,7 @@ static AnimatedModel LoadIQM(const char *filename)
for (int m = 0; m < iqm.num_meshes; m++) for (int m = 0; m < iqm.num_meshes; m++)
{ {
int tcounter = 0; int tcounter = 0;
for (int i=imesh[m].first_triangle; i < imesh[m].first_triangle+imesh[m].num_triangles; i++) for (int i=imesh[m].first_triangle; i < imesh[m].first_triangle+imesh[m].num_triangles; i++)
{ {
// IQM triangles are stored counter clockwise, but raylib sets opengl to clockwise drawing, so we swap them around // IQM triangles are stored counter clockwise, but raylib sets opengl to clockwise drawing, so we swap them around
@ -1087,7 +1104,7 @@ static AnimatedModel LoadIQM(const char *filename)
tcounter += 3; tcounter += 3;
} }
} }
// vertarrays // vertarrays
va = malloc(sizeof(IQMVertexArray)*iqm.num_vertexarrays); va = malloc(sizeof(IQMVertexArray)*iqm.num_vertexarrays);
fseek(iqmFile, iqm.ofs_vertexarrays, SEEK_SET); fseek(iqmFile, iqm.ofs_vertexarrays, SEEK_SET);
@ -1102,7 +1119,7 @@ static AnimatedModel LoadIQM(const char *filename)
vertex = malloc(sizeof(float)*iqm.num_vertexes*3); vertex = malloc(sizeof(float)*iqm.num_vertexes*3);
fseek(iqmFile, va[i].offset, SEEK_SET); fseek(iqmFile, va[i].offset, SEEK_SET);
fread(vertex, sizeof(float)*iqm.num_vertexes*3, 1, iqmFile); fread(vertex, sizeof(float)*iqm.num_vertexes*3, 1, iqmFile);
for (int m = 0; m < iqm.num_meshes; m++) for (int m = 0; m < iqm.num_meshes; m++)
{ {
int vcounter = 0; int vcounter = 0;
@ -1119,7 +1136,7 @@ static AnimatedModel LoadIQM(const char *filename)
normal = malloc(sizeof(float)*iqm.num_vertexes*3); normal = malloc(sizeof(float)*iqm.num_vertexes*3);
fseek(iqmFile, va[i].offset, SEEK_SET); fseek(iqmFile, va[i].offset, SEEK_SET);
fread(normal, sizeof(float)*iqm.num_vertexes*3, 1, iqmFile); fread(normal, sizeof(float)*iqm.num_vertexes*3, 1, iqmFile);
for (int m = 0; m < iqm.num_meshes; m++) for (int m = 0; m < iqm.num_meshes; m++)
{ {
int vcounter = 0; int vcounter = 0;
@ -1136,7 +1153,7 @@ static AnimatedModel LoadIQM(const char *filename)
text = malloc(sizeof(float)*iqm.num_vertexes*2); text = malloc(sizeof(float)*iqm.num_vertexes*2);
fseek(iqmFile, va[i].offset, SEEK_SET); fseek(iqmFile, va[i].offset, SEEK_SET);
fread(text, sizeof(float)*iqm.num_vertexes*2, 1, iqmFile); fread(text, sizeof(float)*iqm.num_vertexes*2, 1, iqmFile);
for (int m = 0; m < iqm.num_meshes; m++) for (int m = 0; m < iqm.num_meshes; m++)
{ {
int vcounter = 0; int vcounter = 0;
@ -1181,7 +1198,7 @@ static AnimatedModel LoadIQM(const char *filename)
} break; } break;
} }
} }
// joints, include base poses // joints, include base poses
ijoint = malloc(sizeof(IQMJoint)*iqm.num_joints); ijoint = malloc(sizeof(IQMJoint)*iqm.num_joints);
fseek(iqmFile, iqm.ofs_joints, SEEK_SET); fseek(iqmFile, iqm.ofs_joints, SEEK_SET);
@ -1190,14 +1207,14 @@ static AnimatedModel LoadIQM(const char *filename)
model.jointCount = iqm.num_joints; model.jointCount = iqm.num_joints;
model.joints = malloc(sizeof(Joint)*iqm.num_joints); model.joints = malloc(sizeof(Joint)*iqm.num_joints);
model.basepose = malloc(sizeof(Pose)*iqm.num_joints); model.basepose = malloc(sizeof(Pose)*iqm.num_joints);
for (int i = 0; i < iqm.num_joints; i++) for (int i = 0; i < iqm.num_joints; i++)
{ {
// joints // joints
model.joints[i].parent = ijoint[i].parent; model.joints[i].parent = ijoint[i].parent;
fseek(iqmFile, iqm.ofs_text + ijoint[i].name, SEEK_SET); fseek(iqmFile, iqm.ofs_text + ijoint[i].name, SEEK_SET);
fread(model.joints[i].name,sizeof(char)*JOINT_NAME_LENGTH, 1, iqmFile); fread(model.joints[i].name,sizeof(char)*JOINT_NAME_LENGTH, 1, iqmFile);
// basepose // basepose
model.basepose[i].translation.x = ijoint[i].translate[0]; model.basepose[i].translation.x = ijoint[i].translate[0];
model.basepose[i].translation.y = ijoint[i].translate[1]; model.basepose[i].translation.y = ijoint[i].translate[1];
@ -1212,7 +1229,7 @@ static AnimatedModel LoadIQM(const char *filename)
model.basepose[i].scale.y = ijoint[i].scale[1]; model.basepose[i].scale.y = ijoint[i].scale[1];
model.basepose[i].scale.z = ijoint[i].scale[2]; model.basepose[i].scale.z = ijoint[i].scale[2];
} }
// build base pose // build base pose
for (int i = 0; i < model.jointCount; i++) for (int i = 0; i < model.jointCount; i++)
{ {
@ -1224,7 +1241,7 @@ static AnimatedModel LoadIQM(const char *filename)
model.basepose[i].scale = Vector3MultiplyV(model.basepose[i].scale, model.basepose[model.joints[i].parent].scale); model.basepose[i].scale = Vector3MultiplyV(model.basepose[i].scale, model.basepose[model.joints[i].parent].scale);
} }
} }
fclose(iqmFile); fclose(iqmFile);
free(imesh); free(imesh);
free(tri); free(tri);
@ -1235,8 +1252,8 @@ static AnimatedModel LoadIQM(const char *filename)
free(blendi); free(blendi);
free(blendw); free(blendw);
free(ijoint); free(ijoint);
return model; return model;
} }
#endif #endif

View File

@ -69,7 +69,7 @@
// Security check in case no GRAPHICS_API_OPENGL_* defined // Security check in case no GRAPHICS_API_OPENGL_* defined
#if !defined(GRAPHICS_API_OPENGL_11) && !defined(GRAPHICS_API_OPENGL_21) && !defined(GRAPHICS_API_OPENGL_33) && !defined(GRAPHICS_API_OPENGL_ES2) #if !defined(GRAPHICS_API_OPENGL_11) && !defined(GRAPHICS_API_OPENGL_21) && !defined(GRAPHICS_API_OPENGL_33) && !defined(GRAPHICS_API_OPENGL_ES2)
#define GRAPHICS_API_OPENGL_11 #define GRAPHICS_API_OPENGL_33
#endif #endif
// Security check in case multiple GRAPHICS_API_OPENGL_* defined // Security check in case multiple GRAPHICS_API_OPENGL_* defined