summaryrefslogtreecommitdiffhomepage
path: root/examples/models
diff options
context:
space:
mode:
authorRay <[email protected]>2022-09-01 20:46:06 +0200
committerRay <[email protected]>2022-09-01 20:46:06 +0200
commitfb1037a2417e516d4be02d962b113e5d55cd5855 (patch)
tree4d09a01595f7b46f1cd996515b0407b42414cab9 /examples/models
parent64cca24526d8d2f82e87039a1d492dcbe07b994d (diff)
downloadraylib-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.c137
-rw-r--r--examples/models/models_loading_m3d.pngbin16992 -> 23682 bytes
-rw-r--r--examples/models/resources/models/m3d/CesiumMan.m3dbin0 -> 73844 bytes
-rw-r--r--examples/models/resources/models/m3d/seagull.m3dbin0 -> 10263 bytes
-rw-r--r--examples/models/resources/models/m3d/suzanne.m3dbin0 -> 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
index 80c859fe..2214b8e0 100644
--- a/examples/models/models_loading_m3d.png
+++ b/examples/models/models_loading_m3d.png
Binary files differ
diff --git a/examples/models/resources/models/m3d/CesiumMan.m3d b/examples/models/resources/models/m3d/CesiumMan.m3d
new file mode 100644
index 00000000..ddf9f509
--- /dev/null
+++ b/examples/models/resources/models/m3d/CesiumMan.m3d
Binary files differ
diff --git a/examples/models/resources/models/m3d/seagull.m3d b/examples/models/resources/models/m3d/seagull.m3d
new file mode 100644
index 00000000..82368205
--- /dev/null
+++ b/examples/models/resources/models/m3d/seagull.m3d
Binary files differ
diff --git a/examples/models/resources/models/m3d/suzanne.m3d b/examples/models/resources/models/m3d/suzanne.m3d
new file mode 100644
index 00000000..9bc64d7d
--- /dev/null
+++ b/examples/models/resources/models/m3d/suzanne.m3d
Binary files differ