Browse Source

Implemented latest .M3D improvements #2648

Ray 2 years ago
parent
commit
23cc39a265
3 changed files with 39 additions and 6 deletions
  1. 21 6
      examples/models/models_loading_m3d.c
  2. BIN
      examples/models/models_loading_m3d.png
  3. 18 0
      src/rmodels.c

+ 21 - 6
examples/models/models_loading_m3d.c

@@ -18,13 +18,14 @@
 #include "raylib.h"
 
 #include <stdlib.h>
+#include <stdio.h>
 
 //------------------------------------------------------------------------------------
 // Program main entry point
 //------------------------------------------------------------------------------------
 int main(int argc, char **argv)
 {
-    char *model_fn = argc > 1 ? argv[1] : "resources/models/m3d/suzanne.m3d";
+    char *model_fn = argc > 1 ? argv[1] : "resources/models/m3d/seagull.m3d";
 
     // Initialization
     //--------------------------------------------------------------------------------------
@@ -46,7 +47,7 @@ int main(int argc, char **argv)
     Model model = LoadModel(model_fn); // Load the animated model mesh and basic data
 
     // Load animation data
-    unsigned int animsCount = 0;
+    unsigned int animsCount = 0, animsSkel = 1, animsMesh = 1;
     ModelAnimation *anims = LoadModelAnimations(model_fn, &animsCount);
     int animFrameCounter = 0, animId = 0;
 
@@ -71,6 +72,15 @@ int main(int argc, char **argv)
                 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;
             }
 
             // Select animation on mouse click
@@ -92,11 +102,16 @@ int main(int argc, char **argv)
 
             BeginMode3D(camera);
 
-                DrawModel(model, position, 1.0f, WHITE);        // Draw 3d model with texture
-                if(anims)
+                if (animsMesh)
+                    DrawModel(model, position, 1.0f, WHITE);        // Draw 3d model with texture
+
+                if (anims && animsSkel)
                     for (int i = 0; i < model.boneCount; i++)
                     {
-                        DrawCube(anims[animId].framePoses[animFrameCounter][i].translation, 0.2f, 0.2f, 0.2f, RED);
+                        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
@@ -105,7 +120,7 @@ int main(int argc, char **argv)
 
             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) Suzanne 3D model by blender", screenWidth - 200, screenHeight - 20, 10, GRAY);
+            DrawText("(c) Seagull model by Scorched3D", screenWidth - 200, screenHeight - 20, 10, GRAY);
 
         EndDrawing();
         //----------------------------------------------------------------------------------

BIN
examples/models/models_loading_m3d.png


+ 18 - 0
src/rmodels.c

@@ -5371,6 +5371,15 @@ static Model LoadM3D(const char *fileName)
                 // TODO: if the orientation quaternion not normalized, then that's encoding scaling
                 model.bindPose[i].rotation = QuaternionNormalize(model.bindPose[i].rotation);
                 model.bindPose[i].scale.x = model.bindPose[i].scale.y = model.bindPose[i].scale.z = 1.0f;
+
+                // Child bones are stored in parent bone relative space, convert that into model space
+                if (model.bones[i].parent >= 0)
+                {
+                    model.bindPose[i].rotation = QuaternionMultiply(model.bindPose[model.bones[i].parent].rotation, model.bindPose[i].rotation);
+                    model.bindPose[i].translation = Vector3RotateByQuaternion(model.bindPose[i].translation, model.bindPose[model.bones[i].parent].rotation);
+                    model.bindPose[i].translation = Vector3Add(model.bindPose[i].translation, model.bindPose[model.bones[i].parent].translation);
+                    model.bindPose[i].scale = Vector3Multiply(model.bindPose[i].scale, model.bindPose[model.bones[i].parent].scale);
+                }
             }
         }
 
@@ -5463,6 +5472,15 @@ static ModelAnimation *LoadModelAnimationsM3D(const char *fileName, unsigned int
                         animations[a].framePoses[i][j].rotation.w = m3d->vertex[pose[j].ori].w;
                         animations[a].framePoses[i][j].rotation = QuaternionNormalize(animations[a].framePoses[i][j].rotation);
                         animations[a].framePoses[i][j].scale.x = animations[a].framePoses[i][j].scale.y = animations[a].framePoses[i][j].scale.z = 1.0f;
+
+						// Child bones are stored in parent bone relative space, convert that into model space
+                        if (animations[a].bones[j].parent >= 0)
+                        {
+                            animations[a].framePoses[i][j].rotation = QuaternionMultiply(animations[a].framePoses[i][animations[a].bones[j].parent].rotation, animations[a].framePoses[i][j].rotation);
+                            animations[a].framePoses[i][j].translation = Vector3RotateByQuaternion(animations[a].framePoses[i][j].translation, animations[a].framePoses[i][animations[a].bones[j].parent].rotation);
+                            animations[a].framePoses[i][j].translation = Vector3Add(animations[a].framePoses[i][j].translation, animations[a].framePoses[i][animations[a].bones[j].parent].translation);
+                            animations[a].framePoses[i][j].scale = Vector3Multiply(animations[a].framePoses[i][j].scale, animations[a].framePoses[i][animations[a].bones[j].parent].scale);
+                        }
                     }
                     RL_FREE(pose);
                 }