Make character run
- new, less blocky character model with a run animation - remove .obj support in favor of .glb/.gltf - character faces camera direction and turns head - press Tab to rotate camera freely around the character
This commit is contained in:
65
src/render.c
65
src/render.c
@@ -334,18 +334,39 @@ static void Transform(ShapeInstance *instance, mat4 *matrix)
|
||||
|
||||
static void DrawModel(GameState *gs)
|
||||
{
|
||||
Model model = gs->testModel;
|
||||
ShapeInstance instance = model.instance;
|
||||
cgltf_data *data = model.data;
|
||||
cgltf_skin *skin = model.skin;
|
||||
Model *model = &gs->testModel;
|
||||
ShapeInstance instance = model->instance;
|
||||
cgltf_data *data = model->data;
|
||||
cgltf_skin *skin = model->skin;
|
||||
cgltf_animation *anim = data->animations;
|
||||
mat4 modelMatrix;
|
||||
glm_mat4_identity(modelMatrix);
|
||||
Transform(&model.instance, &modelMatrix);
|
||||
|
||||
uint64_t ticks = SDL_GetTicks();
|
||||
if (!gs->input.freeLook)
|
||||
{
|
||||
// rotate the whole model to stay within this angle relative to the camera yaw
|
||||
const float turnThreshold = 1.047197f; // 60 degrees
|
||||
const float deg180 = 3.14159f;
|
||||
const float deg360 = 6.28318f;
|
||||
// convert camera yaw (rotation around Y axis) to radians and add 90 degrees so it aligns with the gltf model
|
||||
float camYawRadsGltf = (gs->camera.rotation[0] / -57.295828f) + 1.570795f;
|
||||
if (camYawRadsGltf > deg180) camYawRadsGltf = camYawRadsGltf - deg360;
|
||||
float *modelYaw = model->instance.rotation + 1;
|
||||
float diff = camYawRadsGltf - *modelYaw;
|
||||
if (diff > deg180) diff -= deg360;
|
||||
else if (diff < -deg180) diff += deg360;
|
||||
|
||||
if (turnThreshold < diff)
|
||||
*modelYaw = camYawRadsGltf - turnThreshold;
|
||||
else if (diff < -turnThreshold)
|
||||
*modelYaw = camYawRadsGltf + turnThreshold;
|
||||
}
|
||||
|
||||
Transform(&model->instance, &modelMatrix);
|
||||
|
||||
uint64_t ticks = SDL_GetTicks64();
|
||||
float t = ticks / 1000.0f;
|
||||
while (t > 2.0f) t -= 2.0f;
|
||||
while (t > 1.0f) t -= 1.0f;
|
||||
|
||||
// apply local transformations for each bone for the current animation frame
|
||||
for (int i = 0; i < anim->channels_count; i++)
|
||||
@@ -415,14 +436,34 @@ static void DrawModel(GameState *gs)
|
||||
}
|
||||
}
|
||||
|
||||
if (!gs->input.freeLook)
|
||||
{
|
||||
// make head look where camera is looking
|
||||
cgltf_node *head = model->head;
|
||||
vec3 a, b, yAxis;
|
||||
glm_vec3_zero(a);
|
||||
glm_vec3_zero(b);
|
||||
glm_vec3_zero(yAxis);
|
||||
yAxis[1] = 1.0f;
|
||||
a[2] = 1.0f;
|
||||
glm_vec3_rotate(a, model->instance.rotation[1], yAxis);
|
||||
b[0] = gs->camera.front[0];
|
||||
b[2] = gs->camera.front[2];
|
||||
versor desiredRotation, temp;
|
||||
glm_quat_from_vecs(a, b, desiredRotation);
|
||||
for (int i = 0; i < 4; i++) temp[i] = head->rotation[i];
|
||||
glm_quat_mul(temp, desiredRotation, temp);
|
||||
for (int i = 0; i < 4; i++) head->rotation[i] = temp[i];
|
||||
}
|
||||
|
||||
// recalculate the joint matrices
|
||||
for (int i = 0; i < skin->joints_count; i++)
|
||||
{
|
||||
cgltf_node *joint = skin->joints[i];
|
||||
cgltf_node_transform_world(joint, (float*)model.jointMatrices[i]);
|
||||
cgltf_node_transform_world(joint, (float*)model->jointMatrices[i]);
|
||||
mat4 inverseBind;
|
||||
cgltf_accessor_read_float(skin->inverse_bind_matrices, i, (float*)inverseBind, 16);
|
||||
glm_mat4_mul(model.jointMatrices[i], inverseBind, model.jointMatrices[i]);
|
||||
glm_mat4_mul(model->jointMatrices[i], inverseBind, model->jointMatrices[i]);
|
||||
}
|
||||
|
||||
int shaderId = gs->modelShaderProgramId;
|
||||
@@ -430,12 +471,12 @@ static void DrawModel(GameState *gs)
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderId, "theModelMatrix"), 1, GL_FALSE, (void*)(modelMatrix));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderId, "theViewMatrix"), 1, GL_FALSE, (void*)(gs->viewMatrix));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderId, "theProjMatrix"), 1, GL_FALSE, (void*)(gs->projMatrix));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderId, "theJointMatrices"), 64, GL_FALSE, (void*)(model.jointMatrices));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderId, "theJointMatrices"), 64, GL_FALSE, (void*)(model->jointMatrices));
|
||||
glUniform1f(glGetUniformLocation(shaderId, "texIndex"), 6.0f);
|
||||
glBindTexture(GL_TEXTURE_2D, gs->textureId);
|
||||
|
||||
glBindVertexArray(model.vao);
|
||||
glDrawElements(GL_TRIANGLES, model.indexCount, GL_UNSIGNED_SHORT, 0);
|
||||
glBindVertexArray(model->vao);
|
||||
glDrawElements(GL_TRIANGLES, model->indexCount, GL_UNSIGNED_SHORT, 0);
|
||||
}
|
||||
|
||||
void Render_Draw(GameState *gs)
|
||||
|
||||
Reference in New Issue
Block a user