Skip to content

Commit b179235

Browse files
feat: animations (#45)
* Add animation system with skeleton and bone support - Implemented Animation, Animator, Bone, and Skeleton classes to handle skeletal animations. - Added AnimationComponent to manage animations within entities. - Integrated animation loading in the Model class, supporting multiple animations. - Created AnimationSystem to update animations based on input and delta time. - Enhanced ForwardRenderer to support animated meshes with bone transformations. - Introduced UniformBuffer class for efficient bone matrix handling in shaders. - Updated MeshRendererComponent to indicate if a mesh uses bones for skinning. - Added deserialization for AnimationComponent to load animation data from JSON. * fix(animation): fix inlcudes * feat(animation): implement skinned animation support in vertex shader * refactor(animation): update animation system and remove skeleton.cpp * feat(animation): enhance animation system with node animation support and refactor bone handling * refactor(animation): update processNode to use pointer for skeleton nodes * fix(animation): correct isFinished logic to account for looping animations * feat(animation): enhance animation system with clip management and speed control * refactor(animation): clean up bones uniform buffer management and remove commented code * fix(animation): optimize bone transformation calculation by reusing global inverse matrix * perf(model): add optimize graph flag * fix(animation): handle left-handed axis Y up models * fix(c_cpp_properties): add include paths for animator.hpp bug * feat(animation): add new enemy model and animations for 'mundo' * feat(animation): add new enemy models and animations for 'shaco' and 'yummi' * refactor(animation): simplify BoneAnimation constructor by removing BoneID parameter * feat(animation): enhance model loading to support animations and update asset paths * chore: fix compilation error * feat(animation): add playDuration method to AnimationComponent for timed playback of animations * refactor(animation): remove unused includes from animation-system.hpp * refactor(model): remove unused scene parameter from processVertexBoneData methods * refactor(uniform-buffer): disable copying of UniformBuffer class * refactor(uniform-buffer): add assertions for input validation in UniformBuffer constructor and update method * refactor(animation): clear ununsed enemy definitions in playground configurations * fix(model): set global inverse transform for skeleton when animations are present * fix(animator): include cmath for std::fmod usage * fix(animator): update MAX_BONES definition to modern c++ and change to 128 * fix(animation): enhance key interpolation to handle empty vectors and avoid division by zero * feat(shader): add getUniformBlockBinding caching * fix(animation): initialize model and defaultClip to avoid uninitialized usage * feat(renderer): optimize bone matrix updates by caching last uploaded animator * feat(animation): enhance play method to support force restart and improve isFinished logic * fix(animation): ensure animator updates before checking if animation is finished * fix(animation): correct isFinished logic to account for looping animations * fix(animation): use findBone instead of manual reading from animation channels * fix(model): fix cache key for model texture
1 parent 221ce6f commit b179235

28 files changed

Lines changed: 2284 additions & 42 deletions

.vscode/c_cpp_properties.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,18 @@
77
"browse": {
88
"path": ["${workspaceFolder}/src", "${workspaceFolder}/vendor"]
99
},
10-
"defines": ["COLLISION_DEBUG_DRAW"]
10+
"defines": ["COLLISION_DEBUG_DRAW"],
11+
"includePath": [
12+
"src/common",
13+
"src/game",
14+
"src/states",
15+
"vendor/bullet3/src",
16+
"vendor/imgui",
17+
"vendor/imgui/imgui_impl",
18+
"vendor/glad/include",
19+
"vendor/glm",
20+
"vendor/utils"
21+
]
1122
}
1223
],
1324
"version": 4

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ add_executable(${PROJECT_NAME}
257257
src/common/components/free-camera-controller.cpp
258258
src/common/components/movement.cpp
259259
src/common/components/light.cpp
260+
src/common/components/animation.cpp
260261

261262
src/game/components/collider.cpp
262263
src/game/components/enemy.cpp
@@ -272,6 +273,7 @@ add_executable(${PROJECT_NAME}
272273

273274
src/common/systems/forward-renderer.cpp
274275
src/common/systems/audio-system.cpp
276+
src/common/systems/animation-system.cpp
275277

276278
src/common/audio/audio-utils.cpp
277279
src/common/components/audio-source.cpp

assets/gltf/enemies/mundo.glb

14.6 MB
Binary file not shown.

assets/gltf/enemies/shaco.glb

3.42 MB
Binary file not shown.

assets/gltf/enemies/yummi.glb

15.9 MB
Binary file not shown.

assets/shaders/lit.vert

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,54 @@ out Varyings {
1616
mat3 TBN;
1717
} vs_out;
1818

19+
#define MAX_BONES 128
1920
uniform mat4 transform;
2021
uniform mat4 model;
22+
layout(std140) uniform Bones {
23+
mat4 bones[MAX_BONES];
24+
};
25+
uniform bool hasBones;
2126

2227
void main() {
23-
gl_Position = transform * vec4(position, 1.0);
28+
vec4 skinnedPosition = vec4(0.0);
29+
vec3 skinnedNormal = vec3(0.0);
30+
vec3 skinnedTangent = vec3(0.0);
31+
float totalWeight = 0.0;
2432

33+
if(hasBones) {
34+
for(int i = 0; i < 4; i++) {
35+
if (bone_ids[i] < 0 || bone_ids[i] >= MAX_BONES)
36+
continue;
37+
mat4 boneMatrix = bones[bone_ids[i]];
38+
float weight = weights[i];
39+
totalWeight += weight;
40+
41+
skinnedPosition += weight * (boneMatrix * vec4(position, 1.0));
42+
skinnedNormal += weight * (mat3(boneMatrix) * normal);
43+
skinnedTangent += weight * (mat3(boneMatrix) * tangent.xyz);
44+
}
45+
if (totalWeight <= 0.0) {
46+
skinnedPosition = vec4(position, 1.0);
47+
skinnedNormal = normal;
48+
skinnedTangent = tangent.xyz;
49+
}
50+
} else {
51+
skinnedPosition = vec4(position, 1.0);
52+
skinnedNormal = normal;
53+
skinnedTangent = tangent.xyz;
54+
}
55+
56+
gl_Position = transform * skinnedPosition;
57+
vs_out.worldPos = vec3(model * skinnedPosition);
2558
vs_out.color = color;
2659
vs_out.tex_coord = tex_coord;
27-
vs_out.worldPos = vec3(model * vec4(position, 1.0));
2860

29-
// normal matrix — handles non-uniform scaling correctly
3061
mat3 normalMatrix = transpose(inverse(mat3(model)));
31-
vec3 N = normalize(normalMatrix * normal);
62+
vec3 N = normalize(normalMatrix * skinnedNormal);
3263
vs_out.worldNormal = N;
3364

34-
// TBN matrix for normal mapping
35-
vec3 T = normalize(normalMatrix * tangent.xyz);
36-
T = normalize(T - dot(T, N) * N); // re-orthogonalize
37-
vec3 B = cross(N, T) * tangent.w; // bitangent with handedness
65+
vec3 T = normalize(normalMatrix * skinnedTangent);
66+
T = normalize(T - dot(T, N) * N);
67+
vec3 B = cross(N, T) * tangent.w;
3868
vs_out.TBN = mat3(T, B, N);
3969
}

0 commit comments

Comments
 (0)