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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 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 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |