diff options
| author | Ray <[email protected]> | 2022-09-01 20:46:06 +0200 |
|---|---|---|
| committer | Ray <[email protected]> | 2022-09-01 20:46:06 +0200 |
| commit | fb1037a2417e516d4be02d962b113e5d55cd5855 (patch) | |
| tree | 4d09a01595f7b46f1cd996515b0407b42414cab9 /examples/models | |
| parent | 64cca24526d8d2f82e87039a1d492dcbe07b994d (diff) | |
| download | raylib-fb1037a2417e516d4be02d962b113e5d55cd5855.tar.gz raylib-fb1037a2417e516d4be02d962b113e5d55cd5855.zip | |
ADDED: Complete support for M3D animations! #2648
Diffstat (limited to 'examples/models')
| -rw-r--r-- | examples/models/models_loading_m3d.c | 137 | ||||
| -rw-r--r-- | examples/models/models_loading_m3d.png | bin | 16992 -> 23682 bytes | |||
| -rw-r--r-- | examples/models/resources/models/m3d/CesiumMan.m3d | bin | 0 -> 73844 bytes | |||
| -rw-r--r-- | examples/models/resources/models/m3d/seagull.m3d | bin | 0 -> 10263 bytes | |||
| -rw-r--r-- | examples/models/resources/models/m3d/suzanne.m3d | bin | 0 -> 11645 bytes |
5 files changed, 84 insertions, 53 deletions
diff --git a/examples/models/models_loading_m3d.c b/examples/models/models_loading_m3d.c index f67ba5e5..d11c3a00 100644 --- a/examples/models/models_loading_m3d.c +++ b/examples/models/models_loading_m3d.c @@ -1,97 +1,101 @@ /******************************************************************************************* * -* raylib [models] example - Load M3D model (with optional animations) and play them +* raylib [models] example - Load models M3D * -* Example static mesh Suzanne from Blender -* Example animated seagull model from Scorched 3D, licensed GPLv2 +* Example originally created with raylib 4.5-dev, last time updated with raylib 4.5-dev * -* Copyright (c) 2019-2022 Culacant (@culacant) and Ramon Santamaria (@raysan5) -* Copyright (c) 2022 bzt (@bztsrc) +* Example contributed by bzt (@bztsrc) and reviewed by Ramon Santamaria (@raysan5) * -******************************************************************************************** +* NOTES: +* - Model3D (M3D) fileformat specs: https://gitlab.com/bztsrc/model3d +* - Bender M3D exported: https://gitlab.com/bztsrc/model3d/-/tree/master/blender +* WARNING: Make sure to add "(action)" markers to the timeline if you want multiple animations. +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software * -* NOTE: To export a model from blender, just use https://gitlab.com/bztsrc/model3d/-/tree/master/blender -* and make sure to add "(action)" markers to the timeline if you want multiple animations. +* Copyright (c) 2022 bzt (@bztsrc) * ********************************************************************************************/ #include "raylib.h" -#include <stdlib.h> -#include <stdio.h> - //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ -int main(int argc, char **argv) +int main(void) { - char *model_fn = argc > 1 ? argv[1] : "resources/models/m3d/seagull.m3d"; - // Initialization //-------------------------------------------------------------------------------------- const int screenWidth = 800; const int screenHeight = 450; - InitWindow(screenWidth, screenHeight, "raylib [models] example - M3D model"); + InitWindow(screenWidth, screenHeight, "raylib [models] example - M3D model loading"); // Define the camera to look into our 3d world Camera camera = { 0 }; - camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position - camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point + camera.position = (Vector3){ 1.5f, 1.5f, 1.5f }; // Camera position + camera.target = (Vector3){ 0.0f, 0.4f, 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 mode type Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position + + char modelFileName[128] = "resources/models/m3d/CesiumMan.m3d"; + bool drawMesh = 1; + bool drawSkeleton = 1; + bool animPlaying = false; // Store anim state, what to draw // Load model - Model model = LoadModel(model_fn); // Load the animated model mesh and basic data + Model model = LoadModel(modelFileName); // Load the bind-pose model mesh and basic data - // Load animation data - unsigned int animsCount = 0, animsSkel = 1, animsMesh = 1; - ModelAnimation *anims = LoadModelAnimations(model_fn, &animsCount); + // Load animations + unsigned int animsCount = 0; int animFrameCounter = 0, animId = 0; + ModelAnimation *anims = LoadModelAnimations(modelFileName, &animsCount); // Load skeletal animation data - SetCameraMode(camera, CAMERA_FREE); // Set free camera mode - - SetTargetFPS(60); // Set our game to run at 60 frames-per-second + SetCameraMode(camera, CAMERA_FREE); // Set free camera mode + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key + while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- UpdateCamera(&camera); - // Play animation when spacebar is held down if (animsCount) { - if (IsKeyDown(KEY_SPACE)) + // Play animation when spacebar is held down (or step one frame with N) + if (IsKeyDown(KEY_SPACE) || IsKeyPressed(KEY_N)) { animFrameCounter++; - UpdateModelAnimation(model, anims[animId], animFrameCounter); + if (animFrameCounter >= anims[animId].frameCount) animFrameCounter = 0; - //printf("anim %u, frame %u / %u\n",animId,animFrameCounter,anims[animId].frameCount); - } - if (IsKeyDown(KEY_S)) - { - animsSkel ^= 1; - } - if (IsKeyDown(KEY_M)) - { - animsMesh ^= 1; + + UpdateModelAnimation(model, anims[animId], animFrameCounter); + animPlaying = true; } - - // Select animation on mouse click - if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) + + // Select animation by pressing A + if (IsKeyPressed(KEY_A)) { animFrameCounter = 0; animId++; + if (animId >= animsCount) animId = 0; UpdateModelAnimation(model, anims[animId], 0); + animPlaying = true; } } + + // Toggle skeleton drawing + if (IsKeyPressed(KEY_S)) drawSkeleton ^= 1; + + // Toggle mesh drawing + if (IsKeyPressed(KEY_M)) drawMesh ^= 1; //---------------------------------------------------------------------------------- // Draw @@ -102,25 +106,53 @@ int main(int argc, char **argv) BeginMode3D(camera); - if (animsMesh) - DrawModel(model, position, 1.0f, WHITE); // Draw 3d model with texture + // Draw 3d model with texture + if (drawMesh) DrawModel(model, position, 1.0f, WHITE); - if (anims && animsSkel) - for (int i = 0; i < model.boneCount; i++) + // Draw the animated skeleton + if (drawSkeleton) + { + // Loop to (boneCount - 1) because the last one is a special "no bone" bone, + // needed to workaround buggy models + // without a -1, we would always draw a cube at the origin + for (int i = 0; i < model.boneCount - 1; i++) { - DrawCube(anims[animId].framePoses[animFrameCounter][i].translation, 0.05f, 0.05f, 0.05f, RED); - if (anims[animId].bones[i].parent >= 0) - DrawLine3D(anims[animId].framePoses[animFrameCounter][i].translation, - anims[animId].framePoses[animFrameCounter][anims[animId].bones[i].parent].translation, RED); + // By default the model is loaded in bind-pose by LoadModel(). + // But if UpdateModelAnimation() has been called at least once + // then the model is already in animation pose, so we need the animated skeleton + if (!animPlaying || !animsCount) + { + // Display the bind-pose skeleton + DrawCube(model.bindPose[i].translation, 0.04f, 0.04f, 0.04f, RED); + + if (model.bones[i].parent >= 0) + { + DrawLine3D(model.bindPose[i].translation, + model.bindPose[model.bones[i].parent].translation, RED); + } + } + else + { + // Display the frame-pose skeleton + DrawCube(anims[animId].framePoses[animFrameCounter][i].translation, 0.05f, 0.05f, 0.05f, RED); + + if (anims[animId].bones[i].parent >= 0) + { + DrawLine3D(anims[animId].framePoses[animFrameCounter][i].translation, + anims[animId].framePoses[animFrameCounter][anims[animId].bones[i].parent].translation, RED); + } + } } + } DrawGrid(10, 1.0f); // Draw a grid EndMode3D(); - DrawText("PRESS SPACE to PLAY MODEL ANIMATION", 10, GetScreenHeight() - 30, 10, MAROON); - DrawText("MOUSE LEFT BUTTON to CYCLE THROUGH ANIMATIONS", 10, GetScreenHeight() - 20, 10, DARKGRAY); - DrawText("(c) Seagull model by Scorched3D", screenWidth - 200, screenHeight - 20, 10, GRAY); + DrawText("PRESS SPACE to PLAY MODEL ANIMATION", 10, GetScreenHeight() - 60, 10, MAROON); + DrawText("PRESS A to CYCLE THROUGH ANIMATIONS", 10, GetScreenHeight() - 40, 10, DARKGRAY); + DrawText("PRESS M to toggle MESH, S to toggle SKELETON DRAWING", 10, GetScreenHeight() - 20, 10, DARKGRAY); + DrawText("(c) CesiumMan model by KhronosGroup", GetScreenWidth() - 210, GetScreenHeight() - 20, 10, GRAY); EndDrawing(); //---------------------------------------------------------------------------------- @@ -130,8 +162,7 @@ int main(int argc, char **argv) //-------------------------------------------------------------------------------------- // Unload model animations data - for (unsigned int i = 0; i < animsCount; i++) UnloadModelAnimation(anims[i]); - RL_FREE(anims); + UnloadModelAnimations(anims, animsCount); UnloadModel(model); // Unload model diff --git a/examples/models/models_loading_m3d.png b/examples/models/models_loading_m3d.png Binary files differindex 80c859fe..2214b8e0 100644 --- a/examples/models/models_loading_m3d.png +++ b/examples/models/models_loading_m3d.png diff --git a/examples/models/resources/models/m3d/CesiumMan.m3d b/examples/models/resources/models/m3d/CesiumMan.m3d Binary files differnew file mode 100644 index 00000000..ddf9f509 --- /dev/null +++ b/examples/models/resources/models/m3d/CesiumMan.m3d diff --git a/examples/models/resources/models/m3d/seagull.m3d b/examples/models/resources/models/m3d/seagull.m3d Binary files differnew file mode 100644 index 00000000..82368205 --- /dev/null +++ b/examples/models/resources/models/m3d/seagull.m3d diff --git a/examples/models/resources/models/m3d/suzanne.m3d b/examples/models/resources/models/m3d/suzanne.m3d Binary files differnew file mode 100644 index 00000000..9bc64d7d --- /dev/null +++ b/examples/models/resources/models/m3d/suzanne.m3d |
