Tutorial 5 – Skelett-Animation mithilfe von Uniform-Buffer-Objekten

Programmbeispiel 5 demonstriert die Handhabung von Skelett-Animationen mithilfe von Uniform-Buffer-Objekten.












Schritt 1 – 3D-Modell laden

SkeletalAnimatedTestModel = new CModel;
SkeletalAnimatedTestModel->Init_Model("../Models/AnimatedTestModel1", 5,
                                      true);


Schritt 2 – Animierbaren Körper sowie eine Animations-Sequenz laden

SkeletalAnimatedBody = new CSkeletalAnimatedBody;
SkeletalAnimatedBody->Init_SkeletalAnimatedBody(
            SkeletalAnimatedTestModel->ModelPart[0].AnimationSkeletonDesc);

WalkingSequence = new CSkeletalAnimationSequence;
WalkingSequence->Init_SkeletalAnimationSequence(
            "../AnimationSequences/HumanBodySkeleton/WalkingSequence1.txt",
            "../AnimationPoses/");



Schritt 3 – Instanz-Manager anlegen

// Der Instanz-Manager wird zum Update der Positionen, Orientierungen
// und Animationsposen aller darzustellenden Instanzen benötigt.
// Gespeichert werden diese Daten in drei vom Instanz-Manager verwalteten
// Uniform-Buffer-Objekten.
SkeletalAnimatedMeshInstanceManager = new CSkeletalAnimatedMeshInstanceManager;

SkeletalAnimatedMeshInstanceManager->Set_NumInstancesMax(
                                     SkeletalAnimatedNormalMappingShader,
                                     true, 64);


Schritt 4 – Shader an den Instanz-Manager binden

// Shader-Zugriff auf die in den Uniform-Buffer-Objekten gespeicherten
// Daten gewährleisten

SkeletalAnimatedMeshInstanceManager->Bind_InstanceTransformUniformBuffer(0);

SkeletalAnimatedMeshInstanceManager->Bind_AnimationDataUniformBuffer(1);

SkeletalAnimatedMeshInstanceManager->Bind_InstanceOrientationUniformBuffer(2);

SkeletalAnimatedMeshInstanceManager->Bind_InstanceTransformUniformBlock(
                                     SkeletalAnimatedNormalMappingShader);

SkeletalAnimatedMeshInstanceManager->Bind_AnimationDataUniformBlock(
                                     SkeletalAnimatedNormalMappingShader);

SkeletalAnimatedMeshInstanceManager->Bind_InstanceOrientationUniformBlock(
                                     SkeletalAnimatedNormalMappingShader);


Schritt 5 – Update der Animation

SkeletalAnimatedMeshInstanceManager->Reset_All_Instances();

// aktuelle Anumationspose aus zwei Key-Frame-Posen interpolieren:
WalkingSequence->SkeletalAnimationSequence_Interpolation();

// Orientierung aller Instanzen festlegen:
D3DXMATRIXA16 FrameRotationMatrix;
D3DXMatrixRotationY(&FrameRotationMatrix, -0.5f*g_FrameTime);

WorldSpaceOrientation[0] *= FrameRotationMatrix;
WorldSpaceOrientation[1] *= FrameRotationMatrix;


// Animationspose updaten
SkeletalAnimatedBody->Set_AnimationPose(
                      WalkingSequence->InterpolatedAnimationPose,
                      &WalkingSequence->InterpolatedBodyPosition);

SkeletalAnimatedMeshInstanceManager->Update_AnimationDataUniformBuffer(
                                     SkeletalAnimatedBody->
                                     JointTotalTransformationMatrix,
                                     SkeletalAnimatedBody->NumJoints);

D3DXVECTOR3 WorldSpacePosition;

// Position und Orientierung von Instanz 1:
WorldSpacePosition = SkeletalAnimatedTestModel_WorldSpacePos[0] +
                     WalkingSequence->InterpolatedBodyPosition;

SkeletalAnimatedMeshInstanceManager->Set_WorldSpacePos_And_Orientation(
                                     &g_CameraPosition,
                                     &WorldSpacePosition,
                                     &WorldSpaceOrientation[0]);

// Position und Orientierung von Instanz 2:
WorldSpacePosition = SkeletalAnimatedTestModel_WorldSpacePos[1] +
                     WalkingSequence->InterpolatedBodyPosition;

SkeletalAnimatedMeshInstanceManager->Set_WorldSpacePos_And_Orientation(
                                     &g_CameraPosition,
                                     &WorldSpacePosition,
                                     &WorldSpaceOrientation[1]);


SkeletalAnimatedMeshInstanceManager->Update_InstanceOrientationUniformBuffer();

SkeletalAnimatedMeshInstanceManager->Update_InstanceTransformUniformBuffer(
                                     &g_ViewProjectionMatrix);

WalkingSequence->Update_SkeletalAnimationSequence();


Schritt 6: Rendern aller Instanzen

long NumInstances = 2;
SkeletalAnimatedNormalMappingShader->Use_Shader();

Render_SkeletalAnimatedModel(SkeletalAnimatedTestModel,
                             SkeletalAnimatedNormalMappingShader,
                             g_LODStep, 1.0f, NumInstances);

SkeletalAnimatedNormalMappingShader->Stop_Using_Shader();




Hinweise zum Erstellen eines neuen Projekts:

  • Kopieren Sie den Ordner GraphicsAndPhysicsFrameworkImports ins Projektverzeichnis
  • Kopieren sie alle dll-Dateien sowie die Konfigurationsdatei ResolutionAndRendering.txt aus besagtem Ordner ins gleiche Verzeichnis, in dem sich auch die exe-Datei befindet (in unseren Programmbeispielen ist dies das Bin-Verzeichnis)
  • Binden Sie die folgenden Dateien in Ihr Projekt ein: GraphicsAndPhysics_Framework_Imports.h, GraphicsAndPhysics_Framework_Imports.lib, glew32.lib, glew32s.lib, glut32.lib. Die Glew- und Glut-Bibliotheken ermöglichen die Nutzung der aktuellen OpenGL-Spezifikationen unabhängig vom Framework.