diff --git a/Assets/Shaders/Anim_VS.glsl b/Assets/Shaders/Anim_VS.glsl index c9aa64aa..b553fdf1 100644 --- a/Assets/Shaders/Anim_VS.glsl +++ b/Assets/Shaders/Anim_VS.glsl @@ -12,6 +12,7 @@ layout(location = 4) in mat4 worldTransform; layout(location = 8) in uvec2 integerData; layout(location = 9) in uvec4 aBoneIndices; layout(location = 10) in vec4 aBoneWeights; +layout(location = 11) in uint firstBoneIndex; layout(location = 0) out struct { @@ -65,10 +66,10 @@ void main() Out.normal.rgb = normalize (Out.normal.rgb); // Compute bone matrix - mat4 boneMatrix = BoneMatrices.data[aBoneIndices[0]] * aBoneWeights[0]; - boneMatrix += BoneMatrices.data[aBoneIndices[1]] * aBoneWeights[1]; - boneMatrix += BoneMatrices.data[aBoneIndices[2]] * aBoneWeights[2]; - boneMatrix += BoneMatrices.data[aBoneIndices[3]] * aBoneWeights[3]; + mat4 boneMatrix = BoneMatrices.data[firstBoneIndex + aBoneIndices[0]] * aBoneWeights[0]; + boneMatrix += BoneMatrices.data[firstBoneIndex + aBoneIndices[1]] * aBoneWeights[1]; + boneMatrix += BoneMatrices.data[firstBoneIndex + aBoneIndices[2]] * aBoneWeights[2]; + boneMatrix += BoneMatrices.data[firstBoneIndex + aBoneIndices[3]] * aBoneWeights[3]; // clip space for rendering gl_Position = cameraData.vpMat * worldTransform * boneMatrix * vec4 (aVertexPos, 1.0f); diff --git a/Assets/Shaders/Anim_VS.shshaderb b/Assets/Shaders/Anim_VS.shshaderb index c10bdc5a..0c711949 100644 Binary files a/Assets/Shaders/Anim_VS.shshaderb and b/Assets/Shaders/Anim_VS.shshaderb differ diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 80bb28ff..233ca4ed 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -34,6 +34,7 @@ #include "Physics/System/SHPhysicsDebugDrawSystem.h" #include "Scripting/SHScriptEngine.h" #include "UI/SHUISystem.h" +#include "Animation/SHAnimationSystem.h" // Components #include "Graphics/MiddleEnd/Interface/SHRenderable.h" @@ -96,6 +97,7 @@ namespace Sandbox // Link up SHDebugDraw SHSystemManager::CreateSystem(); SHDebugDraw::Init(SHSystemManager::GetSystem()); + SHSystemManager::CreateSystem(); #ifdef SHEDITOR SDL_Init(SDL_INIT_VIDEO); @@ -142,7 +144,7 @@ namespace Sandbox #ifdef SHEDITOR SHSystemManager::RegisterRoutine(); #endif - + SHSystemManager::RegisterRoutine(); SHSystemManager::RegisterRoutine(); SHSystemManager::RegisterRoutine(); diff --git a/SHADE_Engine/src/Animation/SHAnimationSystem.cpp b/SHADE_Engine/src/Animation/SHAnimationSystem.cpp index 8c514e7c..6f41e2aa 100644 --- a/SHADE_Engine/src/Animation/SHAnimationSystem.cpp +++ b/SHADE_Engine/src/Animation/SHAnimationSystem.cpp @@ -16,6 +16,7 @@ of DigiPen Institute of Technology is prohibited. // Project Includes #include "ECS_Base/Managers/SHComponentManager.h" #include "SHAnimatorComponent.h" +#include "ECS_Base/General/SHFamily.h" namespace SHADE { @@ -23,8 +24,11 @@ namespace SHADE /* System Routine Functions - UpdateRoutine */ /*-----------------------------------------------------------------------------------*/ SHAnimationSystem::UpdateRoutine::UpdateRoutine() - : SHSystemRoutine("Animation System Update", false) - {} + : SHSystemRoutine("Animation System Update", true) + { + SHFamilyID::GetID(); + } + void SHAnimationSystem::UpdateRoutine::Execute(double dt) noexcept { auto& animators = SHComponentManager::GetDense(); @@ -33,4 +37,18 @@ namespace SHADE animator.Update(dt); } } + + /*---------------------------------------------------------------------------------*/ + /* SHSystem Overrides */ + /*---------------------------------------------------------------------------------*/ + void SHAnimationSystem::Init(void) + { + + } + + void SHAnimationSystem::Exit(void) + { + + } + } diff --git a/SHADE_Engine/src/Animation/SHAnimationSystem.h b/SHADE_Engine/src/Animation/SHAnimationSystem.h index 96cd9a71..3d46edc2 100644 --- a/SHADE_Engine/src/Animation/SHAnimationSystem.h +++ b/SHADE_Engine/src/Animation/SHAnimationSystem.h @@ -18,10 +18,6 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { - /*-----------------------------------------------------------------------------------*/ - /* Forward Declarations */ - /*-----------------------------------------------------------------------------------*/ - /*-----------------------------------------------------------------------------------*/ /* Type Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -30,7 +26,7 @@ namespace SHADE /// class SH_API SHAnimationSystem : public SHSystem { - public: + public: /*---------------------------------------------------------------------------------*/ /* Type Definitions */ /*---------------------------------------------------------------------------------*/ @@ -44,5 +40,16 @@ namespace SHADE UpdateRoutine(); void Execute(double dt) noexcept override final; }; + + /*---------------------------------------------------------------------------------*/ + /* Constructors */ + /*---------------------------------------------------------------------------------*/ + SHAnimationSystem() = default; + + /*---------------------------------------------------------------------------------*/ + /* SHSystem Overrides */ + /*---------------------------------------------------------------------------------*/ + virtual void Init(void) override final; + virtual void Exit(void) override final; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.h b/SHADE_Engine/src/Animation/SHAnimatorComponent.h index 6c525be2..43a9f044 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.h +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.h @@ -128,7 +128,7 @@ namespace SHADE Handle currClip; // Playback Tracking float currPlaybackTime = 0.0f; - bool isPlaying = false; + bool isPlaying = true; // Useful Cached Data float secsPerTick = 0.0f; // Buffer diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp index 9c70d15e..d0775711 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp @@ -55,15 +55,20 @@ namespace SHADE // No keyframes at all, means no changes if (nextKeyFrame == keyframes.end()) return T(); - // At the back, so no keyframes will follow + // Out of range, clamp to the back else - return firstKeyFrame->Data; + return nextKeyFrame->Data; } // At the front, so no prior key frames else if (nextKeyFrame != keyframes.end()) { return nextKeyFrame->Data; } + // At the back, so no keyframes will follow + else + { + return firstKeyFrame->Data; + } // Get interpolated vector const float PREV_FRAME_TIME = firstKeyFrame->FrameIndex * secsPerTick; diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHModelLoader.cpp b/SHADE_Engine/src/Assets/Libraries/Loaders/SHModelLoader.cpp index 230df857..6773fb28 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHModelLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHModelLoader.cpp @@ -79,6 +79,7 @@ namespace SHADE void SHModelLoader::ReadAnimNode(FileReference file, SHAnimNodeInfo const& info, SHAnimData& data) { + data.name.resize(info.charCount); file.read( data.name.data(), info.charCount diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index d3329585..8f1cbb6d 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -607,7 +607,7 @@ namespace SHADE }, SHDragDrop::DRAG_RESOURCE); Handle const& clip = component->GetCurrentClip(); - const auto CLIP_NAME = rig ? SHResourceManager::GetAssetName(clip).value_or("") : ""; + const auto CLIP_NAME = clip ? SHResourceManager::GetAssetName(clip).value_or("") : ""; SHEditorWidgets::DragDropReadOnlyField("Clip", CLIP_NAME, [component]() { diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 48859040..fdbbad24 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -380,6 +380,38 @@ namespace SHADE } + void SHBatch::UpdateAnimationBuffer(uint32_t frameIndex) + { + // Frame Index check + if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) + { + SHLOG_WARNING("[SHBatch] Attempted to update animation buffers with an invalid frame index."); + return; + } + + // Reset Animation Matrix Data + boneMatrixData.clear(); + + // Populate on the CPU + for (auto& subBatch : subBatches) + for (auto rendId : subBatch.Renderables) + { + auto animator = SHComponentManager::GetComponent_s(rendId); + if (animator) + { + const auto& MATRICES = animator->GetBoneMatrices(); + boneMatrixData.insert(boneMatrixData.end(), MATRICES.cbegin(), MATRICES.cend()); + } + } + + // Update GPU Buffers + const uint32_t BONE_MTX_DATA_BYTES = static_cast(boneMatrixData.size() * sizeof(SHMatrix)); + if (boneMatrixBuffer[frameIndex]) + { + boneMatrixBuffer[frameIndex]->WriteToMemory(boneMatrixData.data(), BONE_MTX_DATA_BYTES, 0, 0); + } + } + void SHBatch::Build(Handle _device, Handle descPool, uint32_t frameIndex) { if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) @@ -557,6 +589,17 @@ namespace SHADE BuffUsage::eVertexBuffer, "Batch Instance Data Buffer" ); + // - Bone Matrix Indices + if (!boneMatrixIndices.empty()) + { + const uint32_t BMI_DATA_BYTES = static_cast(boneMatrixIndices.size() * sizeof(uint32_t)); + SHVkUtil::EnsureBufferAndCopyHostVisibleData + ( + device, boneMatrixFirstIndexBuffer[frameIndex], boneMatrixIndices.data(), BMI_DATA_BYTES, + BuffUsage::eVertexBuffer, + "Batch Instance Bone Matrix First Index Buffer" + ); + } // - Material and bone buffers/descriptor sets rebuildDescriptorSetBuffers(frameIndex, descPool); } @@ -590,6 +633,10 @@ namespace SHADE cmdBuffer->BindPipeline(pipeline); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0); + if (boneMatrixFirstIndexBuffer[frameIndex]) + { + cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::BONE_MATRIX_FIRST_INDEX, boneMatrixFirstIndexBuffer[frameIndex], 0); + } auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING); if (instanceDataDescSet[frameIndex]) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h index 1bdd9a59..913a7a04 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h @@ -86,6 +86,7 @@ namespace SHADE void UpdateMaterialBuffer(uint32_t frameIndex, Handle descPool); void UpdateTransformBuffer(uint32_t frameIndex); void UpdateInstancedIntegerBuffer(uint32_t frameIndex); + void UpdateAnimationBuffer(uint32_t frameIndex); void Build(Handle device, Handle descPool, uint32_t frameIndex); void Draw(Handle cmdBuffer, uint32_t frameIndex); @@ -134,6 +135,7 @@ namespace SHADE TripleBuffer instancedIntegerBuffer; TripleBuffer matPropsBuffer; TripleBuffer boneMatrixBuffer; + TripleBuffer boneMatrixFirstIndexBuffer; // Instanced buffer, indicates where the first bone matrix is TripleDescSet instanceDataDescSet; /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp index 58993026..0129c0ba 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp @@ -94,6 +94,7 @@ namespace SHADE { batch.UpdateMaterialBuffer(frameIndex, descPool); batch.UpdateTransformBuffer(frameIndex); + batch.UpdateAnimationBuffer(frameIndex); batch.UpdateInstancedIntegerBuffer(frameIndex); } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp index 0cbd6c33..09f7d19e 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp @@ -218,6 +218,7 @@ namespace SHADE defaultVertexInputState.AddBinding(true , true , { SHVertexAttribute(SHAttribFormat::UINT32_2D) }); // Instanced integer data at index 8 defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::UINT32_4D) }); // Attribute bone indices at index 9 defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_4D) }); // Attribute bone weights at index 10 + defaultVertexInputState.AddBinding(true , true , { SHVertexAttribute(SHAttribFormat::UINT32_1D) }); // Instance bone matrix first index at index 11 } void SHGraphicsPredefinedData::Init(Handle logicalDevice) noexcept diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h index e967312f..99694c11 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h @@ -234,6 +234,13 @@ namespace SHADE */ /***************************************************************************/ static constexpr uint32_t BONE_WEIGHTS = 7; + /***************************************************************************/ + /*! + \brief + Vertex buffer bindings for the bone matrix first index buffer. + */ + /***************************************************************************/ + static constexpr uint32_t BONE_MATRIX_FIRST_INDEX = 8; static constexpr uint32_t CALCULATED_GLYPH_POSITION = 0; static constexpr uint32_t GLYPH_INDEX = 1;