From ae6d34a731a5abde2b5c37f57084954d58941452 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 23 Feb 2026 01:43:53 +0100 Subject: [PATCH] Renamed some models examples for consistency --- examples/Makefile | 5 +- examples/Makefile.Web | 25 +- examples/examples_list.txt | 3 +- ...ding.c => models_animation_blend_custom.c} | 58 +- .../models/models_animation_blend_custom.png | Bin 0 -> 23976 bytes examples/models/models_animation_blending.c | 2 +- .../models/models_animation_gpu_skinning.c | 60 +- examples/models/models_animation_timming.c | 114 ++++ examples/models/models_animation_timming.png | Bin 0 -> 22154 bytes examples/models/models_bone_socket.c | 18 +- ... => models_animation_blend_custom.vcxproj} | 6 +- .../examples/models_animation_timming.vcxproj | 569 ++++++++++++++++++ projects/VS2022/raylib.sln | 31 +- tools/rexm/reports/examples_issues.md | 1 - tools/rexm/reports/examples_validation.md | 5 +- 15 files changed, 795 insertions(+), 102 deletions(-) rename examples/models/{models_animation_bone_blending.c => models_animation_blend_custom.c} (87%) create mode 100644 examples/models/models_animation_blend_custom.png create mode 100644 examples/models/models_animation_timming.c create mode 100644 examples/models/models_animation_timming.png rename projects/VS2022/examples/{models_animation_bone_blending.vcxproj => models_animation_blend_custom.vcxproj} (99%) create mode 100644 projects/VS2022/examples/models_animation_timming.vcxproj diff --git a/examples/Makefile b/examples/Makefile index b7c2cee81..fcc013876 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -657,10 +657,10 @@ TEXT = \ text/text_writing_anim MODELS = \ + models/models_animation_blend_custom \ models/models_animation_blending \ - models/models_animation_bone_blending \ models/models_animation_gpu_skinning \ - models/models_loading_iqm \ + models/models_animation_timming \ models/models_basic_voxel \ models/models_billboard_rendering \ models/models_bone_socket \ @@ -673,6 +673,7 @@ MODELS = \ models/models_heightmap_rendering \ models/models_loading \ models/models_loading_gltf \ + models/models_loading_iqm \ models/models_loading_m3d \ models/models_loading_vox \ models/models_mesh_generation \ diff --git a/examples/Makefile.Web b/examples/Makefile.Web index ce5ee4784..b355bc63e 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -642,10 +642,10 @@ TEXT = \ text/text_writing_anim MODELS = \ + models/models_animation_blend_custom \ models/models_animation_blending \ - models/models_animation_bone_blending \ models/models_animation_gpu_skinning \ - models/models_loading_iqm \ + models/models_animation_timming \ models/models_basic_voxel \ models/models_billboard_rendering \ models/models_bone_socket \ @@ -658,6 +658,7 @@ MODELS = \ models/models_heightmap_rendering \ models/models_loading \ models/models_loading_gltf \ + models/models_loading_iqm \ models/models_loading_m3d \ models/models_loading_vox \ models/models_mesh_generation \ @@ -1199,15 +1200,15 @@ text/text_writing_anim: text/text_writing_anim.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) # Compile MODELS examples -models/models_animation_blending: models/models_animation_blending.c +models/models_animation_blend_custom: models/models_animation_blend_custom.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file models/resources/models/gltf/robot.glb@resources/models/gltf/robot.glb \ + --preload-file models/resources/models/gltf/greenman.glb@resources/models/gltf/greenman.glb \ --preload-file models/resources/shaders/glsl100/skinning.vs@resources/shaders/glsl100/skinning.vs \ --preload-file models/resources/shaders/glsl100/skinning.fs@resources/shaders/glsl100/skinning.fs -models/models_animation_bone_blending: models/models_animation_bone_blending.c +models/models_animation_blending: models/models_animation_blending.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file models/resources/models/gltf/greenman.glb@resources/models/gltf/greenman.glb \ + --preload-file models/resources/models/gltf/robot.glb@resources/models/gltf/robot.glb \ --preload-file models/resources/shaders/glsl100/skinning.vs@resources/shaders/glsl100/skinning.vs \ --preload-file models/resources/shaders/glsl100/skinning.fs@resources/shaders/glsl100/skinning.fs @@ -1217,11 +1218,9 @@ models/models_animation_gpu_skinning: models/models_animation_gpu_skinning.c --preload-file models/resources/shaders/glsl100/skinning.vs@resources/shaders/glsl100/skinning.vs \ --preload-file models/resources/shaders/glsl100/skinning.fs@resources/shaders/glsl100/skinning.fs -models/models_loading_iqm: models/models_loading_iqm.c +models/models_animation_timming: models/models_animation_timming.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file models/resources/models/iqm/guy.iqm@resources/models/iqm/guy.iqm \ - --preload-file models/resources/models/iqm/guytex.png@resources/models/iqm/guytex.png \ - --preload-file models/resources/models/iqm/guyanim.iqm@resources/models/iqm/guyanim.iqm + --preload-file models/resources/models/gltf/robot.glb@resources/models/gltf/robot.glb models/models_basic_voxel: models/models_basic_voxel.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) @@ -1276,6 +1275,12 @@ models/models_loading_gltf: models/models_loading_gltf.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file models/resources/models/gltf/robot.glb@resources/models/gltf/robot.glb +models/models_loading_iqm: models/models_loading_iqm.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file models/resources/models/iqm/guy.iqm@resources/models/iqm/guy.iqm \ + --preload-file models/resources/models/iqm/guytex.png@resources/models/iqm/guytex.png \ + --preload-file models/resources/models/iqm/guyanim.iqm@resources/models/iqm/guyanim.iqm + models/models_loading_m3d: models/models_loading_m3d.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file models/resources/models/m3d/cesium_man.m3d@resources/models/m3d/cesium_man.m3d diff --git a/examples/examples_list.txt b/examples/examples_list.txt index 981636ed8..042c1aed3 100644 --- a/examples/examples_list.txt +++ b/examples/examples_list.txt @@ -171,8 +171,9 @@ models;models_basic_voxel;★★☆☆;5.5;5.5;2025;2025;"Tim Little";@timlittle models;models_rotating_cube;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe models;models_decals;★★★★;5.6-dev;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates models;models_directional_billboard;★★☆☆;5.6-dev;5.6;2025;2025;"Robin";@RobinsAviary -models;models_animation_bone_blending;★★★★;5.5;5.5;2026;2026;"dmitrii-brand";@dmitrii-brand +models;models_animation_blend_custom;★★★★;5.5;5.5;2026;2026;"dmitrii-brand";@dmitrii-brand models;models_animation_blending;☆☆☆☆;5.5;5.6-dev;2024;2024;"Kirandeep";@Kirandeep-Singh-Khehra +models;models_animation_timming;★★☆☆;5.6;5.6;2026;2026;"Ramon Santamaria";@raysan5 shaders;shaders_ascii_rendering;★★☆☆;5.5;5.6;2025;2025;"Maicon Santana";@maiconpintoabreu shaders;shaders_basic_lighting;★★★★;3.0;4.2;2019;2025;"Chris Camacho";@chriscamacho shaders;shaders_model_shader;★★☆☆;1.3;3.7;2014;2025;"Ramon Santamaria";@raysan5 diff --git a/examples/models/models_animation_bone_blending.c b/examples/models/models_animation_blend_custom.c similarity index 87% rename from examples/models/models_animation_bone_blending.c rename to examples/models/models_animation_blend_custom.c index 11e05a305..76dba6a69 100644 --- a/examples/models/models_animation_bone_blending.c +++ b/examples/models/models_animation_blend_custom.c @@ -1,6 +1,6 @@ /******************************************************************************************* * -* raylib [models] example - animation bone blending +* raylib [models] example - animation blend custom * * Example complexity rating: [★★★★] 4/4 * @@ -53,7 +53,7 @@ int main(void) const int screenWidth = 800; const int screenHeight = 450; - InitWindow(screenWidth, screenHeight, "raylib [models] example - animation bone blending"); + InitWindow(screenWidth, screenHeight, "raylib [models] example - animation blend custom"); // Define the camera to look into our 3d world Camera camera = { 0 }; @@ -80,7 +80,7 @@ int main(void) TraceLog(LOG_INFO, "Found %d animations:", animsCount); for (int i = 0; i < animsCount; i++) { - TraceLog(LOG_INFO, " Animation %d: %s (%d frames)", i, modelAnimations[i].name, modelAnimations[i].frameCount); + TraceLog(LOG_INFO, " Animation %d: %s (%d frames)", i, modelAnimations[i].name, modelAnimations[i].keyframeCount); } // Use specific indices: walk/move = 2, attack = 3 @@ -118,8 +118,8 @@ int main(void) ModelAnimation anim1 = modelAnimations[animIndex1]; ModelAnimation anim2 = modelAnimations[animIndex2]; - animCurrentFrame1 = (animCurrentFrame1 + 1)%anim1.frameCount; - animCurrentFrame2 = (animCurrentFrame2 + 1)%anim2.frameCount; + animCurrentFrame1 = (animCurrentFrame1 + 1)%anim1.keyframeCount; + animCurrentFrame2 = (animCurrentFrame2 + 1)%anim2.keyframeCount; // Blend the two animations characterModel.transform = MatrixTranslate(position.x, position.y, position.z); @@ -203,9 +203,9 @@ static void BlendModelAnimationsBones(Model *model, ModelAnimation *anim1, int f ModelAnimation *anim2, int frame2, float blendFactor, bool upperBodyBlend) { // Validate inputs - if (anim1->boneCount == 0 || anim1->framePoses == NULL || - anim2->boneCount == 0 || anim2->framePoses == NULL || - model->boneCount == 0 || model->bindPose == NULL) + if (anim1->boneCount == 0 || anim1->keyframePoses == NULL || + anim2->boneCount == 0 || anim2->keyframePoses == NULL || + model->skeleton.boneCount == 0 || model->skeleton.bindPose == NULL) { return; } @@ -214,26 +214,13 @@ static void BlendModelAnimationsBones(Model *model, ModelAnimation *anim1, int f blendFactor = fminf(1.0f, fmaxf(0.0f, blendFactor)); // Ensure frame indices are valid - if (frame1 >= anim1->frameCount) frame1 = anim1->frameCount - 1; - if (frame2 >= anim2->frameCount) frame2 = anim2->frameCount - 1; + if (frame1 >= anim1->keyframeCount) frame1 = anim1->keyframeCount - 1; + if (frame2 >= anim2->keyframeCount) frame2 = anim2->keyframeCount - 1; if (frame1 < 0) frame1 = 0; if (frame2 < 0) frame2 = 0; - // Find first mesh with bones - int firstMeshWithBones = -1; - for (int i = 0; i < model->meshCount; i++) - { - if (model->meshes[i].boneMatrices) - { - firstMeshWithBones = i; - break; - } - } - - if (firstMeshWithBones == -1) return; - // Get bone count (use minimum of all to be safe) - int boneCount = model->boneCount; + int boneCount = model->skeleton.boneCount; if (anim1->boneCount < boneCount) boneCount = anim1->boneCount; if (anim2->boneCount < boneCount) boneCount = anim2->boneCount; @@ -246,7 +233,7 @@ static void BlendModelAnimationsBones(Model *model, ModelAnimation *anim1, int f // If upper body blending is enabled, use different blend factors for upper vs lower body if (upperBodyBlend) { - const char *boneName = model->bones[boneId].name; + const char *boneName = model->skeleton.bones[boneId].name; bool isUpperBody = IsUpperBodyBone(boneName); // Upper body: use anim2 (attack), Lower body: use anim1 (walk) @@ -256,12 +243,12 @@ static void BlendModelAnimationsBones(Model *model, ModelAnimation *anim1, int f } // Get transforms from both animations - Transform *bindTransform = &model->bindPose[boneId]; - Transform *anim1Transform = &anim1->framePoses[frame1][boneId]; - Transform *anim2Transform = &anim2->framePoses[frame2][boneId]; + Transform *bindTransform = &model->skeleton.bindPose[boneId]; + Transform *anim1Transform = &anim1->keyframePoses[frame1][boneId]; + Transform *anim2Transform = &anim2->keyframePoses[frame2][boneId]; // Blend the transforms - Transform blended; + Transform blended = { 0 }; blended.translation = Vector3Lerp(anim1Transform->translation, anim2Transform->translation, boneBlendFactor); blended.rotation = QuaternionSlerp(anim1Transform->rotation, anim2Transform->rotation, boneBlendFactor); blended.scale = Vector3Lerp(anim1Transform->scale, anim2Transform->scale, boneBlendFactor); @@ -279,18 +266,7 @@ static void BlendModelAnimationsBones(Model *model, ModelAnimation *anim1, int f MatrixTranslate(blended.translation.x, blended.translation.y, blended.translation.z)); // Calculate final bone matrix (similar to UpdateModelAnimationBones) - model->meshes[firstMeshWithBones].boneMatrices[boneId] = MatrixMultiply(MatrixInvert(bindMatrix), blendedMatrix); - } - - // Copy bone matrices to remaining meshes - for (int i = firstMeshWithBones + 1; i < model->meshCount; i++) - { - if (model->meshes[i].boneMatrices) - { - memcpy(model->meshes[i].boneMatrices, - model->meshes[firstMeshWithBones].boneMatrices, - model->meshes[i].boneCount*sizeof(model->meshes[i].boneMatrices[0])); - } + model->boneMatrices[boneId] = MatrixMultiply(MatrixInvert(bindMatrix), blendedMatrix); } } diff --git a/examples/models/models_animation_blend_custom.png b/examples/models/models_animation_blend_custom.png new file mode 100644 index 0000000000000000000000000000000000000000..0f6dbca87898af2cbf5bb535fab3ba46c6ca85fe GIT binary patch literal 23976 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 literal 0 HcmV?d00001 diff --git a/examples/models/models_animation_blending.c b/examples/models/models_animation_blending.c index c9f59d9f1..39623cd28 100644 --- a/examples/models/models_animation_blending.c +++ b/examples/models/models_animation_blending.c @@ -2,7 +2,7 @@ * * raylib [models] example - animation blending * -* Example complexity rating: [★★★☆] 3/4 +* Example complexity rating: [☆☆☆☆] 0/4 * * Example originally created with raylib 5.5, last time updated with raylib 5.6-dev * diff --git a/examples/models/models_animation_gpu_skinning.c b/examples/models/models_animation_gpu_skinning.c index 337df931c..0cd890449 100644 --- a/examples/models/models_animation_gpu_skinning.c +++ b/examples/models/models_animation_gpu_skinning.c @@ -8,13 +8,15 @@ * * Example contributed by Daniel Holden (@orangeduck) and reviewed by Ramon Santamaria (@raysan5) * +* WARNING: GPU skinning must be enabled in raylib with a compilation flag, +* if not enabled, CPU skinning will be used instead +* NOTE: Due to limitations in the Apple OpenGL driver, this feature does not work on MacOS +* * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software * * Copyright (c) 2024-2025 Daniel Holden (@orangeduck) * -* Note: Due to limitations in the Apple OpenGL driver, this feature does not work on MacOS -* ********************************************************************************************/ #include "raylib.h" @@ -42,29 +44,29 @@ int main(void) // Define the camera to look into our 3d world Camera camera = { 0 }; camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position - camera.target = (Vector3){ 0.0f, 2.0f, 0.0f }; // Camera looking at point + camera.target = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera looking at point 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.projection = CAMERA_PERSPECTIVE; // Camera projection type // Load gltf model - Model characterModel = LoadModel("resources/models/gltf/greenman.glb"); // Load character model - - // Load skinning shader - Shader skinningShader = LoadShader(TextFormat("resources/shaders/glsl%i/skinning.vs", GLSL_VERSION), - TextFormat("resources/shaders/glsl%i/skinning.fs", GLSL_VERSION)); - - characterModel.materials[1].shader = skinningShader; - - // Load gltf model animations - int animsCount = 0; - unsigned int animIndex = 0; - unsigned int animCurrentFrame = 0; - ModelAnimation *modelAnimations = LoadModelAnimations("resources/models/gltf/greenman.glb", &animsCount); - + Model model = LoadModel("resources/models/gltf/greenman.glb"); // Load character model Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position - DisableCursor(); // Limit cursor to relative movement inside the window + // Load skinning shader + // WARNING: GPU skinning must be enabled in raylib with a compilation flag, + // if not enabled, CPU skinning will be used instead + Shader skinningShader = LoadShader(TextFormat("resources/shaders/glsl%i/skinning.vs", GLSL_VERSION), + TextFormat("resources/shaders/glsl%i/skinning.fs", GLSL_VERSION)); + model.materials[1].shader = skinningShader; + + // Load gltf model animations + int animCount = 0; + ModelAnimation *anims = LoadModelAnimations("resources/models/gltf/greenman.glb", &animCount); + + // Animation playing variables + unsigned int animIndex = 0; // Current animation playing + unsigned int animCurrentFrame = 0; // Current animation frame SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -74,17 +76,15 @@ int main(void) { // Update //---------------------------------------------------------------------------------- - UpdateCamera(&camera, CAMERA_THIRD_PERSON); + UpdateCamera(&camera, CAMERA_ORBITAL); // Select current animation - if (IsKeyPressed(KEY_T)) animIndex = (animIndex + 1)%animsCount; - else if (IsKeyPressed(KEY_G)) animIndex = (animIndex + animsCount - 1)%animsCount; + if (IsKeyPressed(KEY_RIGHT)) animIndex = (animIndex + 1)%animCount; + else if (IsKeyPressed(KEY_LEFT)) animIndex = (animIndex + animCount - 1)%animCount; // Update model animation - ModelAnimation anim = modelAnimations[animIndex]; - animCurrentFrame = (animCurrentFrame + 1)%anim.frameCount; - characterModel.transform = MatrixTranslate(position.x, position.y, position.z); - UpdateModelAnimationBones(characterModel, anim, animCurrentFrame); + animCurrentFrame = (animCurrentFrame + 1)%anims[animIndex].keyframeCount; + UpdateModelAnimation(model, anims[animIndex], (float)animCurrentFrame); //---------------------------------------------------------------------------------- // Draw @@ -95,14 +95,14 @@ int main(void) BeginMode3D(camera); - // Draw character mesh, pose calculation is done in shader (GPU skinning) - DrawMesh(characterModel.meshes[0], characterModel.materials[1], characterModel.transform); + DrawModel(model, position, 1.0f, WHITE); DrawGrid(10, 1.0f); EndMode3D(); - DrawText("Use the T/G to switch animation", 10, 10, 20, GRAY); + DrawText(TextFormat("Current animation: %s", anims[animIndex].name), 10, 40, 20, MAROON); + DrawText("Use the LEFT/RIGHT keys to switch animation", 10, 10, 20, GRAY); EndDrawing(); //---------------------------------------------------------------------------------- @@ -110,8 +110,8 @@ int main(void) // De-Initialization //-------------------------------------------------------------------------------------- - UnloadModelAnimations(modelAnimations, animsCount); // Unload model animation - UnloadModel(characterModel); // Unload model and meshes/material + UnloadModelAnimations(anims, animCount); // Unload model animation + UnloadModel(model); // Unload model and meshes/material UnloadShader(skinningShader); // Unload GPU skinning shader CloseWindow(); // Close window and OpenGL context diff --git a/examples/models/models_animation_timming.c b/examples/models/models_animation_timming.c new file mode 100644 index 000000000..8069537ce --- /dev/null +++ b/examples/models/models_animation_timming.c @@ -0,0 +1,114 @@ +/******************************************************************************************* +* +* raylib [models] example - animation timming +* +* Example complexity rating: [★★☆☆] 2/4 +* +* Example originally created with raylib 5.6, last time updated with raylib 5.6 +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2026 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#define RAYGUI_IMPLEMENTATION +#include "raygui.h" // Required for: UI controls + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [models] example - animation timming"); + + // Define the camera to look into our 3d world + Camera camera = { 0 }; + camera.position = (Vector3){ 6.0f, 6.0f, 6.0f }; // Camera position + camera.target = (Vector3){ 0.0f, 2.0f, 0.0f }; // Camera looking at point + 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.projection = CAMERA_PERSPECTIVE; // Camera projection type + + // Load model + Model model = LoadModel("resources/models/gltf/robot.glb"); + Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model world position + + // Load model animations + int animsCount = 0; + ModelAnimation *modelAnimations = LoadModelAnimations("resources/models/gltf/robot.glb", &animsCount); + + // Animation playing variables + unsigned int animIndex = 0; // Current animation playing + float animCurrentFrame = 0.0f; // Current animation frame (supporting interpolated frames) + float animFrameSpeed = 0.1f; // Animation play speed + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + UpdateCamera(&camera, CAMERA_ORBITAL); + + // Select current animation + if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) animIndex = (animIndex + 1)%animsCount; + else if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) animIndex = (animIndex + animsCount - 1)%animsCount; + + // Select animation playing speed + if (IsKeyPressed(KEY_RIGHT)) animFrameSpeed += 0.1f; + else if (IsKeyPressed(KEY_LEFT)) animFrameSpeed -= 0.1f; + + // Update model animation + animCurrentFrame += animFrameSpeed; + UpdateModelAnimation(model, modelAnimations[animIndex], animCurrentFrame); + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + BeginMode3D(camera); + + DrawModel(model, position, 1.0f, WHITE); + + DrawGrid(10, 1.0f); + + EndMode3D(); + + // Draw UI + //GuiDropdownBox((Rectangle){ 10, 20, 240, 30 }, "text", &animIndex, editMode); + + DrawText(TextFormat("FRAME SPEED: x%.1f", animFrameSpeed), 10, 40, 20, RED); + + DrawText("Use the LEFT/RIGHT mouse buttons to switch animation", 10, 10, 20, GRAY); + DrawText(TextFormat("Animation: %s", modelAnimations[animIndex].name), 10, GetScreenHeight() - 20, 10, DARKGRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadModel(model); // Unload model and meshes/material + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + + + diff --git a/examples/models/models_animation_timming.png b/examples/models/models_animation_timming.png new file mode 100644 index 0000000000000000000000000000000000000000..673994b7c4451ad3a8f431a9e92cf21406496fbc GIT binary patch literal 22154 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 OVDNPHb6Mw<&;$TtVr|j@ literal 0 HcmV?d00001 diff --git a/examples/models/models_bone_socket.c b/examples/models/models_bone_socket.c index 8348aa50d..37b677c4a 100644 --- a/examples/models/models_bone_socket.c +++ b/examples/models/models_bone_socket.c @@ -60,25 +60,25 @@ int main(void) unsigned int animCurrentFrame = 0; ModelAnimation *modelAnimations = LoadModelAnimations("resources/models/gltf/greenman.glb", &animsCount); - // indices of bones for sockets + // Indices of bones for sockets int boneSocketIndex[BONE_SOCKETS] = { -1, -1, -1 }; - // search bones for sockets - for (int i = 0; i < characterModel.boneCount; i++) + // Search bones for sockets + for (int i = 0; i < characterModel.skeleton.boneCount; i++) { - if (TextIsEqual(characterModel.bones[i].name, "socket_hat")) + if (TextIsEqual(characterModel.skeleton.bones[i].name, "socket_hat")) { boneSocketIndex[BONE_SOCKET_HAT] = i; continue; } - if (TextIsEqual(characterModel.bones[i].name, "socket_hand_R")) + if (TextIsEqual(characterModel.skeleton.bones[i].name, "socket_hand_R")) { boneSocketIndex[BONE_SOCKET_HAND_R] = i; continue; } - if (TextIsEqual(characterModel.bones[i].name, "socket_hand_L")) + if (TextIsEqual(characterModel.skeleton.bones[i].name, "socket_hand_L")) { boneSocketIndex[BONE_SOCKET_HAND_L] = i; continue; @@ -115,7 +115,7 @@ int main(void) // Update model animation ModelAnimation anim = modelAnimations[animIndex]; - animCurrentFrame = (animCurrentFrame + 1)%anim.frameCount; + animCurrentFrame = (animCurrentFrame + 1)%anim.keyframeCount; UpdateModelAnimation(characterModel, anim, animCurrentFrame); //---------------------------------------------------------------------------------- @@ -137,8 +137,8 @@ int main(void) { if (!showEquip[i]) continue; - Transform *transform = &anim.framePoses[animCurrentFrame][boneSocketIndex[i]]; - Quaternion inRotation = characterModel.bindPose[boneSocketIndex[i]].rotation; + Transform *transform = &anim.keyframePoses[animCurrentFrame][boneSocketIndex[i]]; + Quaternion inRotation = characterModel.skeleton.bindPose[boneSocketIndex[i]].rotation; Quaternion outRotation = transform->rotation; // Calculate socket rotation (angle between bone in initial pose and same bone in current animation frame) diff --git a/projects/VS2022/examples/models_animation_bone_blending.vcxproj b/projects/VS2022/examples/models_animation_blend_custom.vcxproj similarity index 99% rename from projects/VS2022/examples/models_animation_bone_blending.vcxproj rename to projects/VS2022/examples/models_animation_blend_custom.vcxproj index 475ad47f0..32fdf506b 100644 --- a/projects/VS2022/examples/models_animation_bone_blending.vcxproj +++ b/projects/VS2022/examples/models_animation_blend_custom.vcxproj @@ -53,9 +53,9 @@ {AC751FE1-C986-4B6A-92A8-28ED89DEE671} Win32Proj - models_animation_bone_blending + models_animation_blend_custom 10.0 - models_animation_bone_blending + models_animation_blend_custom @@ -553,7 +553,7 @@ - + diff --git a/projects/VS2022/examples/models_animation_timming.vcxproj b/projects/VS2022/examples/models_animation_timming.vcxproj new file mode 100644 index 000000000..a18123bbc --- /dev/null +++ b/projects/VS2022/examples/models_animation_timming.vcxproj @@ -0,0 +1,569 @@ + + + + + Debug.DLL + ARM64 + + + Debug.DLL + Win32 + + + Debug.DLL + x64 + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release.DLL + ARM64 + + + Release.DLL + Win32 + + + Release.DLL + x64 + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {89D5A0E9-683C-465C-BF85-A880865175C8} + Win32Proj + models_animation_timming + 10.0 + models_animation_timming + + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + + + + + + + {e89d61ac-55de-4482-afd4-df7242ebc859} + + + + + + \ No newline at end of file diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln index 938f23bf4..51268e037 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -429,12 +429,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_easings_testbed", "e EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_rlgl_compute", "examples\shaders_rlgl_compute.vcxproj", "{AEA9D0D4-B810-4624-BC75-10A291584ED6}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_animation_bone_blending", "examples\models_animation_bone_blending.vcxproj", "{AC751FE1-C986-4B6A-92A8-28ED89DEE671}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_animation_blend_custom", "examples\models_animation_blend_custom.vcxproj", "{AC751FE1-C986-4B6A-92A8-28ED89DEE671}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_animation_blending", "examples\models_animation_blending.vcxproj", "{BB9C957D-34F1-46AE-B64A-9E0499C1746D}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_window_web", "examples\core_window_web.vcxproj", "{4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_animation_timming", "examples\models_animation_timming.vcxproj", "{89D5A0E9-683C-465C-BF85-A880865175C8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug.DLL|ARM64 = Debug.DLL|ARM64 @@ -5443,6 +5445,30 @@ Global {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Release|x64.Build.0 = Release|x64 {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Release|x86.ActiveCfg = Release|Win32 {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Release|x86.Build.0 = Release|Win32 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Debug|ARM64.Build.0 = Debug|ARM64 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Debug|x64.ActiveCfg = Debug|x64 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Debug|x64.Build.0 = Debug|x64 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Debug|x86.ActiveCfg = Debug|Win32 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Debug|x86.Build.0 = Debug|Win32 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Release|ARM64.ActiveCfg = Release|ARM64 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Release|ARM64.Build.0 = Release|ARM64 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Release|x64.ActiveCfg = Release|x64 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Release|x64.Build.0 = Release|x64 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Release|x86.ActiveCfg = Release|Win32 + {89D5A0E9-683C-465C-BF85-A880865175C8}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -5605,7 +5631,7 @@ Global {C54703BF-D68A-480D-BE27-49B62E45D582} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} {9CD8BCAD-F212-4BCC-BA98-899743CE3279} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} {0981CA28-E4A5-4DF1-987F-A41D09131EFC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} {6777EC3C-077C-42FC-B4AD-B799CE55CCE4} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} {A61DAD9C-271C-4E95-81AA-DB4CD58564D4} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} @@ -5662,6 +5688,7 @@ Global {AC751FE1-C986-4B6A-92A8-28ED89DEE671} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} {BB9C957D-34F1-46AE-B64A-9E0499C1746D} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {89D5A0E9-683C-465C-BF85-A880865175C8} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} diff --git a/tools/rexm/reports/examples_issues.md b/tools/rexm/reports/examples_issues.md index 3fcc136e5..a648295cc 100644 --- a/tools/rexm/reports/examples_issues.md +++ b/tools/rexm/reports/examples_issues.md @@ -20,4 +20,3 @@ Example elements validated: ``` | **EXAMPLE NAME** | [C] | [CAT]| [INFO]|[PNG]|[WPNG]| [RES]| [MK] |[MKWEB]| [VCX]| [SOL]|[RDME]|[JS] | [WOUT]|[WMETA]| |:---------------------------------|:---:|:----:|:-----:|:---:|:----:|:----:|:----:|:-----:|:----:|:----:|:----:|:---:|:-----:|:-----:| -| models_animation_bone_blending | ✔ | ✔ | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | diff --git a/tools/rexm/reports/examples_validation.md b/tools/rexm/reports/examples_validation.md index 9c0c02956..e46b93e46 100644 --- a/tools/rexm/reports/examples_validation.md +++ b/tools/rexm/reports/examples_validation.md @@ -155,7 +155,7 @@ Example elements validated: | text_inline_styling | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_words_alignment | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_strings_management | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| models_animation_playing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| models_loading_iqm | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_billboard_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_box_collisions | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_cubicmap_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -182,8 +182,9 @@ Example elements validated: | models_rotating_cube | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_decals | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_directional_billboard | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| models_animation_bone_blending | ✔ | ✔ | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| models_animation_blend_custom | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_animation_blending | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| models_animation_timming | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_ascii_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_basic_lighting | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_model_shader | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |