Merge branch 'SP3-17-animation-system' into SP3-17-animation-viewer
# Conflicts: # SHADE_Engine/src/Animation/SHAnimationClip.h
This commit is contained in:
commit
3b5d1ef6d5
|
@ -0,0 +1,8 @@
|
||||||
|
- VertexShader: 47911992
|
||||||
|
FragmentShader: 46377769
|
||||||
|
SubPass: G-Buffer Write
|
||||||
|
Properties:
|
||||||
|
data.color: {x: 1, y: 1, z: 1, w: 1}
|
||||||
|
data.textureIndex: 64651793
|
||||||
|
data.alpha: 0
|
||||||
|
data.beta: {x: 1, y: 1, z: 1}
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: AnimatedRaccoon
|
||||||
|
ID: 128805346
|
||||||
|
Type: 7
|
Binary file not shown.
Binary file not shown.
|
@ -1,65 +0,0 @@
|
||||||
#version 450
|
|
||||||
#extension GL_KHR_vulkan_glsl : enable
|
|
||||||
|
|
||||||
//#include "ShaderDescriptorDefinitions.glsl"
|
|
||||||
|
|
||||||
|
|
||||||
layout(location = 0) in vec3 aVertexPos;
|
|
||||||
layout(location = 1) in vec2 aUV;
|
|
||||||
layout(location = 2) in vec3 aNormal;
|
|
||||||
layout(location = 3) in vec3 aTangent;
|
|
||||||
layout(location = 4) in mat4 worldTransform;
|
|
||||||
layout(location = 5) in ivec4 aBoneIndices;
|
|
||||||
layout(location = 6) in vec4 aBoneWeights;
|
|
||||||
layout(location = 8) in uvec2 integerData;
|
|
||||||
|
|
||||||
|
|
||||||
layout(location = 0) out struct
|
|
||||||
{
|
|
||||||
vec4 vertPos; // location 0
|
|
||||||
vec2 uv; // location = 1
|
|
||||||
vec4 normal; // location = 2
|
|
||||||
|
|
||||||
} Out;
|
|
||||||
|
|
||||||
// material stuff
|
|
||||||
layout(location = 3) out struct
|
|
||||||
{
|
|
||||||
int materialIndex;
|
|
||||||
uint eid;
|
|
||||||
uint lightLayerIndex;
|
|
||||||
|
|
||||||
} Out2;
|
|
||||||
|
|
||||||
layout(set = 2, binding = 0) uniform CameraData
|
|
||||||
{
|
|
||||||
vec4 position;
|
|
||||||
mat4 vpMat;
|
|
||||||
mat4 viewMat;
|
|
||||||
mat4 projMat;
|
|
||||||
} cameraData;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
Out2.materialIndex = gl_InstanceIndex;
|
|
||||||
Out2.eid = integerData[0];
|
|
||||||
Out2.lightLayerIndex = integerData[1];
|
|
||||||
|
|
||||||
// for transforming gBuffer position and normal data
|
|
||||||
mat4 modelViewMat = cameraData.viewMat * worldTransform;
|
|
||||||
|
|
||||||
// gBuffer position will be in view space
|
|
||||||
Out.vertPos = modelViewMat * vec4(aVertexPos, 1.0f);
|
|
||||||
|
|
||||||
// uvs for texturing in fragment shader
|
|
||||||
Out.uv = aUV;
|
|
||||||
|
|
||||||
mat3 transposeInv = mat3 (transpose(inverse(modelViewMat)));
|
|
||||||
|
|
||||||
// normals are also in view space
|
|
||||||
Out.normal.rgb = transposeInv * aNormal.rgb;
|
|
||||||
Out.normal.rgb = normalize (Out.normal.rgb);
|
|
||||||
|
|
||||||
// clip space for rendering
|
|
||||||
gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f);
|
|
||||||
}
|
|
|
@ -47,6 +47,7 @@
|
||||||
|
|
||||||
#include "Tools/Logger/SHLogger.h"
|
#include "Tools/Logger/SHLogger.h"
|
||||||
#include "Tools/SHDebugDraw.h"
|
#include "Tools/SHDebugDraw.h"
|
||||||
|
#include "Resource/SHResourceManager.h"
|
||||||
|
|
||||||
using namespace SHADE;
|
using namespace SHADE;
|
||||||
|
|
||||||
|
@ -170,6 +171,10 @@ namespace Sandbox
|
||||||
|
|
||||||
// Link up SHDebugDraw
|
// Link up SHDebugDraw
|
||||||
SHDebugDraw::Init(SHSystemManager::GetSystem<SHDebugDrawSystem>());
|
SHDebugDraw::Init(SHSystemManager::GetSystem<SHDebugDrawSystem>());
|
||||||
|
|
||||||
|
auto clip = SHResourceManager::LoadOrGet<SHAnimationClip>(77816045);
|
||||||
|
auto rig = SHResourceManager::LoadOrGet<SHRig>(77816045);
|
||||||
|
int i = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SBApplication::Update(void)
|
void SBApplication::Update(void)
|
||||||
|
|
|
@ -20,10 +20,39 @@ namespace SHADE
|
||||||
/* Constructors */
|
/* Constructors */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
SHAnimationClip::SHAnimationClip(const SHAnimAsset& asset)
|
SHAnimationClip::SHAnimationClip(const SHAnimAsset& asset)
|
||||||
|
: ticksPerSecond { static_cast<int>(asset.ticksPerSecond) }
|
||||||
|
, totalTime { static_cast<float>(asset.duration) }
|
||||||
{
|
{
|
||||||
|
// Populate keyframes
|
||||||
|
for (const auto& channel : asset.nodeChannels)
|
||||||
|
{
|
||||||
|
// Create a channel
|
||||||
|
Channel newChannel;
|
||||||
|
newChannel.Name = std::string(channel.name);
|
||||||
|
newChannel.PositionKeyFrames.reserve(channel.positionKeys.size());
|
||||||
|
newChannel.RotationKeyFrames.reserve(channel.rotationKeys.size());
|
||||||
|
newChannel.ScaleKeyFrames.reserve(channel.scaleKeys.size());
|
||||||
|
|
||||||
|
// Populate Keyframes
|
||||||
|
for (const auto& posKey : channel.positionKeys)
|
||||||
|
{
|
||||||
|
newChannel.PositionKeyFrames.emplace_back(SHAnimationKeyFrame<SHVec3>{ static_cast<int>(posKey.time), posKey.value});
|
||||||
|
}
|
||||||
|
for (const auto& rotKey : channel.rotationKeys)
|
||||||
|
{
|
||||||
|
newChannel.RotationKeyFrames.emplace_back(SHAnimationKeyFrame<SHQuaternion>{ static_cast<int>(rotKey.time), rotKey.value});
|
||||||
|
}
|
||||||
|
for (const auto& scaleKey : channel.scaleKeys)
|
||||||
|
{
|
||||||
|
newChannel.ScaleKeyFrames.emplace_back(SHAnimationKeyFrame<SHVec3>{ static_cast<int>(scaleKey.time), scaleKey.value});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newChannel.MaxFrames = std::max({ newChannel.PositionKeyFrames.size(), newChannel.RotationKeyFrames.size(), newChannel.ScaleKeyFrames.size() });
|
||||||
|
|
||||||
|
// Insert the channel
|
||||||
|
channels.emplace_back(std::move(newChannel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Usage Functions */
|
/* Usage Functions */
|
||||||
|
|
|
@ -11,9 +11,8 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
*//*************************************************************************************/
|
*//*************************************************************************************/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// STL Includes
|
|
||||||
|
|
||||||
// Project Includes
|
// Project Includes
|
||||||
|
#include "SH_API.h"
|
||||||
#include "Math/SHMatrix.h"
|
#include "Math/SHMatrix.h"
|
||||||
#include "Assets/Asset Types/Models/SHAnimationAsset.h"
|
#include "Assets/Asset Types/Models/SHAnimationAsset.h"
|
||||||
|
|
||||||
|
@ -23,22 +22,20 @@ namespace SHADE
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines a single key frame in an animation.
|
/// Defines a single key frame in an animation for a specific type of data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
template<typename T>
|
||||||
struct SHAnimationKeyFrame
|
struct SHAnimationKeyFrame
|
||||||
{
|
{
|
||||||
float TimeStamp;
|
int FrameIndex;
|
||||||
SHVec3 Position;
|
T Data;
|
||||||
SHQuaternion Orientation;
|
|
||||||
SHVec3 Scale;
|
|
||||||
SHMatrix TransformationMatrix;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a animation clip of a 3D animation that is made for a specific model
|
/// Represents a animation clip of a 3D animation that is made for a specific model
|
||||||
/// rig.
|
/// rig.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class SHAnimationClip
|
class SH_API SHAnimationClip
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -50,19 +47,26 @@ namespace SHADE
|
||||||
struct Channel
|
struct Channel
|
||||||
{
|
{
|
||||||
std::string Name;
|
std::string Name;
|
||||||
std::vector<SHAnimationKeyFrame> KeyFrames;
|
std::vector<SHAnimationKeyFrame<SHVec3>> PositionKeyFrames;
|
||||||
|
std::vector<SHAnimationKeyFrame<SHQuaternion>> RotationKeyFrames;
|
||||||
|
std::vector<SHAnimationKeyFrame<SHVec3>> ScaleKeyFrames;
|
||||||
|
int MaxFrames;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Constructors */
|
/* Constructors */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
SHAnimationClip() = default;
|
/// <summary>
|
||||||
|
/// Constructs an SHAnimation Clip from a specified SHAnimAsset.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="asset">Animation asset to load.</param>
|
||||||
explicit SHAnimationClip(const SHAnimAsset& asset);
|
explicit SHAnimationClip(const SHAnimAsset& asset);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
const std::vector<Channel>& GetChannels() const noexcept { return channels; }
|
const std::vector<Channel>& GetChannels() const noexcept { return channels; }
|
||||||
|
int GetTicksPerSecond() const noexcept { return ticksPerSecond; }
|
||||||
float GetTotalTime() const noexcept { return totalTime; }
|
float GetTotalTime() const noexcept { return totalTime; }
|
||||||
|
|
||||||
//private:
|
//private:
|
||||||
|
@ -70,6 +74,7 @@ namespace SHADE
|
||||||
/* Data Members */
|
/* Data Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
std::vector<Channel> channels;
|
std::vector<Channel> channels;
|
||||||
|
int ticksPerSecond;
|
||||||
float totalTime;
|
float totalTime;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
\par email: kahwei.tng\@digipen.edu
|
\par email: kahwei.tng\@digipen.edu
|
||||||
\date Nov 20, 2022
|
\date Nov 20, 2022
|
||||||
\brief Contains the definition of functions of the SHRenderable Component class.
|
\brief Contains the definition of functions of the SHAnimatorComponent Component
|
||||||
|
class.
|
||||||
|
|
||||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
@ -83,8 +84,13 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
|
|
||||||
currClip = newClip;
|
currClip = newClip;
|
||||||
|
secsPerTick = 1.0f / currClip->GetTicksPerSecond();
|
||||||
|
|
||||||
|
if (rig)
|
||||||
|
{
|
||||||
updatePoseWithClip(0.0f);
|
updatePoseWithClip(0.0f);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Update Functions */
|
/* Update Functions */
|
||||||
|
@ -92,7 +98,7 @@ namespace SHADE
|
||||||
void SHAnimatorComponent::Update(float dt)
|
void SHAnimatorComponent::Update(float dt)
|
||||||
{
|
{
|
||||||
// Nothing to animate
|
// Nothing to animate
|
||||||
if (!currClip || !isPlaying)
|
if (!currClip || !isPlaying || !rig)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update time on the playback
|
// Update time on the playback
|
||||||
|
@ -135,36 +141,20 @@ namespace SHADE
|
||||||
bones.push(child);
|
bones.push(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get interpolated frame
|
// Get closest frame index
|
||||||
auto firstKeyFrame = channel.KeyFrames.end();
|
const int CLOSEST_FRAME_IDX = static_cast<int>(std::floorf(poseTime * currClip->GetTicksPerSecond()));
|
||||||
auto nextKeyFrame = channel.KeyFrames.end();
|
|
||||||
for (auto iter = channel.KeyFrames.begin(); iter != channel.KeyFrames.end(); ++iter)
|
|
||||||
{
|
|
||||||
const auto& KEYFRAME = *iter;
|
|
||||||
|
|
||||||
if(KEYFRAME.TimeStamp <= poseTime)
|
// Calculate the matrix from interpolated values
|
||||||
{
|
|
||||||
firstKeyFrame = iter;
|
|
||||||
}
|
|
||||||
else if (KEYFRAME.TimeStamp > poseTime)
|
|
||||||
{
|
|
||||||
nextKeyFrame = iter;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Calculate the matrix
|
|
||||||
const int BONE_MTX_IDX = rig->GetNodeIndex(bone);
|
const int BONE_MTX_IDX = rig->GetNodeIndex(bone);
|
||||||
const float T = (poseTime - firstKeyFrame->TimeStamp) / (nextKeyFrame->TimeStamp - firstKeyFrame->TimeStamp);
|
|
||||||
boneMatrices[BONE_MTX_IDX] = boneMatrices[BONE_MTX_IDX] * SHMatrix::Transform
|
boneMatrices[BONE_MTX_IDX] = boneMatrices[BONE_MTX_IDX] * SHMatrix::Transform
|
||||||
(
|
(
|
||||||
SHVec3::Lerp(firstKeyFrame->Position, nextKeyFrame->Position, T),
|
getInterpolatedValue(channel.PositionKeyFrames, CLOSEST_FRAME_IDX, poseTime),
|
||||||
SHQuaternion::Slerp(firstKeyFrame->Orientation, nextKeyFrame->Orientation, T),
|
getInterpolatedValue(channel.RotationKeyFrames, CLOSEST_FRAME_IDX, poseTime),
|
||||||
SHVec3::Lerp(firstKeyFrame->Scale, nextKeyFrame->Scale, T)
|
getInterpolatedValue(channel.ScaleKeyFrames , CLOSEST_FRAME_IDX, poseTime)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
\par email: kahwei.tng\@digipen.edu
|
\par email: kahwei.tng\@digipen.edu
|
||||||
\date Nov 20, 2022
|
\date Nov 20, 2022
|
||||||
\brief Contains the definition of the SHAnimationSystem class and related types.
|
\brief Contains the definition of the SHAnimatorComponent class and related
|
||||||
|
types.
|
||||||
|
|
||||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
@ -19,6 +20,9 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "ECS_Base/Components/SHComponent.h"
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
#include "Resource/SHHandle.h"
|
#include "Resource/SHHandle.h"
|
||||||
#include "Math/SHMatrix.h"
|
#include "Math/SHMatrix.h"
|
||||||
|
#include "Math/Vector/SHVec3.h"
|
||||||
|
#include "Math/SHQuaternion.h"
|
||||||
|
#include "SHAnimationClip.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -89,6 +93,12 @@ namespace SHADE
|
||||||
/// <returns>Reference to a vector of the bone matrices.</returns>
|
/// <returns>Reference to a vector of the bone matrices.</returns>
|
||||||
const std::vector<SHMatrix>& GetBoneMatrices() const noexcept { return boneMatrices; }
|
const std::vector<SHMatrix>& GetBoneMatrices() const noexcept { return boneMatrices; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Retrieve the currently set model rig.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Handle to the currently set rig.</returns>
|
||||||
|
Handle<SHRig> GetRig() const noexcept { return rig; }
|
||||||
|
/// <summary>
|
||||||
|
/// <summary>
|
||||||
/// Retrieve the currently set animation clip.
|
/// Retrieve the currently set animation clip.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Handle to the currently set animation clip.</returns>
|
/// <returns>Handle to the currently set animation clip.</returns>
|
||||||
|
@ -119,6 +129,8 @@ namespace SHADE
|
||||||
// Playback Tracking
|
// Playback Tracking
|
||||||
float currPlaybackTime = 0.0f;
|
float currPlaybackTime = 0.0f;
|
||||||
bool isPlaying = false;
|
bool isPlaying = false;
|
||||||
|
// Useful Cached Data
|
||||||
|
float secsPerTick = 0.0f;
|
||||||
// Buffer
|
// Buffer
|
||||||
std::vector<SHMatrix> boneMatrices;
|
std::vector<SHMatrix> boneMatrices;
|
||||||
|
|
||||||
|
@ -126,6 +138,8 @@ namespace SHADE
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
void updatePoseWithClip(float poseTime);
|
void updatePoseWithClip(float poseTime);
|
||||||
|
template<typename T>
|
||||||
|
T getInterpolatedValue(const std::vector<SHAnimationKeyFrame<T>>& keyframes, int closestFrameIndex, float poseTime);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* RTTR */
|
/* RTTR */
|
||||||
|
@ -133,3 +147,5 @@ namespace SHADE
|
||||||
RTTR_ENABLE()
|
RTTR_ENABLE()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "SHAnimatorComponent.hpp"
|
|
@ -0,0 +1,82 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHAnimatorComponent.hpp
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Jan 10, 2023
|
||||||
|
\brief Contains the definition of function templates of the SHAnimatorComponent
|
||||||
|
Component class.
|
||||||
|
|
||||||
|
Copyright (C) 2023 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
// Primary Include
|
||||||
|
#include "SHAnimatorComponent.h"
|
||||||
|
// Project Includes
|
||||||
|
#include "SHRig.h"
|
||||||
|
#include "Math/SHMatrix.h"
|
||||||
|
#include "SHAnimationClip.h"
|
||||||
|
#include "Graphics/SHVkUtil.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Helper Functions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
template<typename T>
|
||||||
|
T SHAnimatorComponent::getInterpolatedValue(const std::vector<SHAnimationKeyFrame<T>>& keyframes, int closestFrameIndex, float poseTime)
|
||||||
|
{
|
||||||
|
// Only allow SHVec3 and SHQuaternion
|
||||||
|
static_assert(std::is_same_v<T, SHVec3> || std::is_same_v<T, SHQuaternion>, "Only interpolation for SHVec3 and SHQuaternion is allowed.");
|
||||||
|
|
||||||
|
// Find the key frames that surround the current frame index
|
||||||
|
auto firstKeyFrame = keyframes.end();
|
||||||
|
auto nextKeyFrame = keyframes.end();
|
||||||
|
for (auto iter = keyframes.begin(); iter != keyframes.end(); ++iter)
|
||||||
|
{
|
||||||
|
const auto& KEYFRAME = *iter;
|
||||||
|
|
||||||
|
if (KEYFRAME.FrameIndex <= closestFrameIndex)
|
||||||
|
{
|
||||||
|
firstKeyFrame = iter;
|
||||||
|
}
|
||||||
|
else if (KEYFRAME.FrameIndex > closestFrameIndex)
|
||||||
|
{
|
||||||
|
nextKeyFrame = iter;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Edge Cases
|
||||||
|
if (firstKeyFrame == keyframes.end())
|
||||||
|
{
|
||||||
|
// No keyframes at all, means no changes
|
||||||
|
if (nextKeyFrame == keyframes.end())
|
||||||
|
return T();
|
||||||
|
// At the back, so no keyframes will follow
|
||||||
|
else
|
||||||
|
return firstKeyFrame->Data;
|
||||||
|
}
|
||||||
|
// At the front, so no prior key frames
|
||||||
|
else if (nextKeyFrame != keyframes.end())
|
||||||
|
{
|
||||||
|
return nextKeyFrame->Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get interpolated vector
|
||||||
|
const float PREV_FRAME_TIME = firstKeyFrame->FrameIndex * secsPerTick;
|
||||||
|
const float NEXT_FRAME_TIME = nextKeyFrame->FrameIndex * secsPerTick;
|
||||||
|
const float NORMALISED_TIME = (poseTime - PREV_FRAME_TIME) / (NEXT_FRAME_TIME - PREV_FRAME_TIME);
|
||||||
|
|
||||||
|
if constexpr (std::is_same_v<T, SHQuaternion>)
|
||||||
|
{
|
||||||
|
return SHQuaternion::Slerp(firstKeyFrame->Data, nextKeyFrame->Data, NORMALISED_TIME);
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, SHVec3>)
|
||||||
|
{
|
||||||
|
return SHVec3::Lerp(firstKeyFrame->Data, nextKeyFrame->Data, NORMALISED_TIME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,7 +27,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
// Don't bother if empty
|
// Don't bother if empty
|
||||||
if (asset.root == nullptr)
|
if (asset.root == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("[SHRig] Attempted to load an invalid rig with no root.");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Do a recursive depth first traversal to populate the rig
|
// Do a recursive depth first traversal to populate the rig
|
||||||
nodeCount = 0;
|
nodeCount = 0;
|
||||||
|
@ -100,7 +103,8 @@ namespace SHADE
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Recursively create children
|
// Recursively create children
|
||||||
newNode->Children.emplace_back(recurseCreateNode(asset, child));
|
auto childNode = recurseCreateNode(asset, child); // Not sure why this works but it is required for
|
||||||
|
newNode->Children.emplace_back(childNode); // the emplace_back operation to not crash
|
||||||
}
|
}
|
||||||
|
|
||||||
return newNode;
|
return newNode;
|
||||||
|
|
|
@ -17,6 +17,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
// Project Includes
|
// Project Includes
|
||||||
|
#include "SH_API.h"
|
||||||
#include "Math/SHMatrix.h"
|
#include "Math/SHMatrix.h"
|
||||||
#include "Resource/SHHandle.h"
|
#include "Resource/SHHandle.h"
|
||||||
#include "Resource/SHResourceLibrary.h"
|
#include "Resource/SHResourceLibrary.h"
|
||||||
|
@ -32,7 +33,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
class SHRig
|
class SH_API SHRig
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -153,7 +153,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHModelLoader::ReadRigTree(FileReference file, SHRigDataHeader const& header, SHRigNode* root)
|
void SHModelLoader::ReadRigTree(FileReference file, SHRigDataHeader const& header, SHRigNode*& root)
|
||||||
{
|
{
|
||||||
// Read All nodes into one contiguous data block
|
// Read All nodes into one contiguous data block
|
||||||
struct NodeTemp
|
struct NodeTemp
|
||||||
|
@ -193,6 +193,8 @@ namespace SHADE
|
||||||
nodeQueue.emplace(depthPtr++, depthTempPtr++);
|
nodeQueue.emplace(depthPtr++, depthTempPtr++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete[] dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHModelLoader::ReadMeshData(FileReference file, std::vector<SHMeshDataHeader> const& headers,
|
void SHModelLoader::ReadMeshData(FileReference file, std::vector<SHMeshDataHeader> const& headers,
|
||||||
|
@ -221,6 +223,34 @@ namespace SHADE
|
||||||
file.read(reinterpret_cast<char*>(data.VertexTexCoords.data()), vertexVec2Byte);
|
file.read(reinterpret_cast<char*>(data.VertexTexCoords.data()), vertexVec2Byte);
|
||||||
file.read(reinterpret_cast<char*>(data.Indices.data()), sizeof(uint32_t) * header.indexCount);
|
file.read(reinterpret_cast<char*>(data.Indices.data()), sizeof(uint32_t) * header.indexCount);
|
||||||
|
|
||||||
|
std::vector<MeshBoneInfo> boneInfos(header.boneCount);
|
||||||
|
std::vector<MeshBone> bones(header.boneCount);
|
||||||
|
|
||||||
|
file.read(reinterpret_cast<char*>(boneInfos.data()), sizeof(MeshBoneInfo) * header.boneCount);
|
||||||
|
|
||||||
|
for (auto i{ 0 }; i < header.boneCount; ++i)
|
||||||
|
{
|
||||||
|
auto& bone = bones[i];
|
||||||
|
auto const& info = boneInfos[i];
|
||||||
|
|
||||||
|
bone.name.resize(info.charCount);
|
||||||
|
file.read(bone.name.data(), info.charCount);
|
||||||
|
file.read(reinterpret_cast<char*>(&bone.offset), sizeof(SHMatrix));
|
||||||
|
|
||||||
|
uint32_t weightCount;
|
||||||
|
file.read(reinterpret_cast<char*>(&weightCount), sizeof(uint32_t));
|
||||||
|
bone.weights.resize(weightCount);
|
||||||
|
file.read(reinterpret_cast<char*>(bone.weights.data()), sizeof(BoneWeight) * weightCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
data.VertexBoneIndices.resize(header.vertexCount);
|
||||||
|
data.VertexBoneWeights.resize(header.vertexCount);
|
||||||
|
|
||||||
|
for (auto const& bone : bones)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
meshes[i] = &data;
|
meshes[i] = &data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace SHADE
|
||||||
|
|
||||||
void ReadRigHeader(FileReference file, SHRigDataHeader& header);
|
void ReadRigHeader(FileReference file, SHRigDataHeader& header);
|
||||||
void ReadRigData(FileReference file, SHRigDataHeader const& header, std::vector<SHRigNodeData>& data);
|
void ReadRigData(FileReference file, SHRigDataHeader const& header, std::vector<SHRigNodeData>& data);
|
||||||
void ReadRigTree(FileReference file, SHRigDataHeader const& header, SHRigNode* root);
|
void ReadRigTree(FileReference file, SHRigDataHeader const& header, SHRigNode*& root);
|
||||||
|
|
||||||
void ReadMeshData(FileReference file, std::vector<SHMeshDataHeader> const& headers, std::vector<SHMeshAsset*>& meshes);
|
void ReadMeshData(FileReference file, std::vector<SHMeshDataHeader> const& headers, std::vector<SHMeshAsset*>& meshes);
|
||||||
void ReadAnimData(FileReference file, std::vector<SHAnimDataHeader> const& headers, std::vector<SHAnimAsset*>& anims);
|
void ReadAnimData(FileReference file, std::vector<SHAnimDataHeader> const& headers, std::vector<SHAnimAsset*>& anims);
|
||||||
|
|
|
@ -437,7 +437,7 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (true)
|
if (genMeta)
|
||||||
{
|
{
|
||||||
GenerateNewMeta(newPath);
|
GenerateNewMeta(newPath);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "Serialization/SHSerializationHelper.hpp"
|
#include "Serialization/SHSerializationHelper.hpp"
|
||||||
#include "Tools/Utilities/SHClipboardUtilities.h"
|
#include "Tools/Utilities/SHClipboardUtilities.h"
|
||||||
#include "SHInspectorCommands.h"
|
#include "SHInspectorCommands.h"
|
||||||
|
#include "Animation/SHAnimatorComponent.h"
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -574,4 +575,60 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
static void DrawComponent(SHAnimatorComponent* component)
|
||||||
|
{
|
||||||
|
if (!component)
|
||||||
|
return;
|
||||||
|
ImGui::PushID(SHFamilyID<SHComponent>::GetID<SHAnimatorComponent>());
|
||||||
|
const auto componentType = rttr::type::get(*component);
|
||||||
|
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
||||||
|
{
|
||||||
|
DrawContextMenu(component);
|
||||||
|
Handle<SHRig> const& rig = component->GetRig();
|
||||||
|
const auto RIG_NAME = rig ? SHResourceManager::GetAssetName<SHRig>(rig).value_or("") : "";
|
||||||
|
SHEditorWidgets::DragDropReadOnlyField<AssetID>("Rig", RIG_NAME, [component]()
|
||||||
|
{
|
||||||
|
Handle<SHRig> const& rig = component->GetRig();
|
||||||
|
return SHResourceManager::GetAssetID<SHRig>(rig).value_or(0);
|
||||||
|
},
|
||||||
|
[component](AssetID const& id)
|
||||||
|
{
|
||||||
|
if (SHAssetManager::GetType(id) != AssetType::MODEL)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Attempted to assign non mesh asset to Renderable Mesh property!")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
component->SetRig(SHResourceManager::LoadOrGet<SHRig>(id));
|
||||||
|
SHResourceManager::FinaliseChanges();
|
||||||
|
}, SHDragDrop::DRAG_RESOURCE);
|
||||||
|
|
||||||
|
Handle<SHAnimationClip> const& clip = component->GetCurrentClip();
|
||||||
|
const auto CLIP_NAME = rig ? SHResourceManager::GetAssetName<SHAnimationClip>(clip).value_or("") : "";
|
||||||
|
SHEditorWidgets::DragDropReadOnlyField<AssetID>("Clip", CLIP_NAME,
|
||||||
|
[component]()
|
||||||
|
{
|
||||||
|
Handle<SHAnimationClip> const& clip = component->GetCurrentClip();
|
||||||
|
return SHResourceManager::GetAssetID<SHAnimationClip>(clip).value_or(0);
|
||||||
|
},
|
||||||
|
[component](AssetID const& id)
|
||||||
|
{
|
||||||
|
if (SHAssetManager::GetType(id) != AssetType::MODEL)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Attempted to assign non mesh asset to Renderable Mesh property!")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
component->SetClip(SHResourceManager::LoadOrGet<SHAnimationClip>(id));
|
||||||
|
}, SHDragDrop::DRAG_RESOURCE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DrawContextMenu(component);
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,13 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
template<typename Component>
|
||||||
|
void EnsureComponent(EntityID eid)
|
||||||
|
{
|
||||||
|
if(SHComponentManager::GetComponent_s<Component>(eid) == nullptr)
|
||||||
|
SHComponentManager::AddComponent<Component>(eid);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
bool DrawAddComponentButton(EntityID const& eid)
|
bool DrawAddComponentButton(EntityID const& eid)
|
||||||
{
|
{
|
||||||
|
@ -48,9 +55,13 @@ namespace SHADE
|
||||||
return selected;
|
return selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ComponentType, typename EnforcedComponent, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true, std::enable_if_t<std::is_base_of_v<SHComponent, EnforcedComponent>, bool> = true>
|
template <typename ComponentType, typename ... EnforcedComponents>
|
||||||
bool DrawAddComponentWithEnforcedComponentButton(EntityID const& eid)
|
bool DrawAddComponentWithEnforcedComponentButton(EntityID const& eid)
|
||||||
{
|
{
|
||||||
|
// Only make sure components are passed here
|
||||||
|
static_assert(std::is_base_of_v<SHComponent, ComponentType>, "");
|
||||||
|
//(static_assert(std::is_base_of_v<SHComponent, EnforcedComponents>, ""), ...);
|
||||||
|
|
||||||
bool selected = false;
|
bool selected = false;
|
||||||
if (!SHComponentManager::HasComponent<ComponentType>(eid))
|
if (!SHComponentManager::HasComponent<ComponentType>(eid))
|
||||||
{
|
{
|
||||||
|
@ -58,9 +69,8 @@ namespace SHADE
|
||||||
|
|
||||||
if(selected = ImGui::Selectable(std::format("Add {}", componentName).data()); selected)
|
if(selected = ImGui::Selectable(std::format("Add {}", componentName).data()); selected)
|
||||||
{
|
{
|
||||||
if(SHComponentManager::GetComponent_s<EnforcedComponent>(eid) == nullptr)
|
// Ensure that all required components are present
|
||||||
SHComponentManager::AddComponent<EnforcedComponent>(eid);
|
(EnsureComponent<EnforcedComponents>(eid), ...);
|
||||||
|
|
||||||
SHComponentManager::AddComponent<ComponentType>(eid);
|
SHComponentManager::AddComponent<ComponentType>(eid);
|
||||||
}
|
}
|
||||||
if(ImGui::IsItemHovered())
|
if(ImGui::IsItemHovered())
|
||||||
|
@ -69,9 +79,8 @@ namespace SHADE
|
||||||
ImGui::Text("Adds", componentName); ImGui::SameLine();
|
ImGui::Text("Adds", componentName); ImGui::SameLine();
|
||||||
ImGui::TextColored(ImGuiColors::green, "%s", componentName); ImGui::SameLine();
|
ImGui::TextColored(ImGuiColors::green, "%s", componentName); ImGui::SameLine();
|
||||||
ImGui::Text("to this entity", componentName);
|
ImGui::Text("to this entity", componentName);
|
||||||
ImGui::Text("Adds"); ImGui::SameLine();
|
ImGui::Text("Adds the following components if the entity does not already have it: ");
|
||||||
ImGui::TextColored(ImGuiColors::red, "%s", rttr::type::get<EnforcedComponent>().get_name().data()); ImGui::SameLine();
|
(ImGui::TextColored(ImGuiColors::red, "%s", rttr::type::get<EnforcedComponents>().get_name().data()), ...);
|
||||||
ImGui::Text("if the entity does not already have it");
|
|
||||||
ImGui::EndTooltip();
|
ImGui::EndTooltip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,6 +127,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
DrawComponent(renderableComponent);
|
DrawComponent(renderableComponent);
|
||||||
}
|
}
|
||||||
|
if (auto animatorComponent = SHComponentManager::GetComponent_s<SHAnimatorComponent>(eid))
|
||||||
|
{
|
||||||
|
DrawComponent(animatorComponent);
|
||||||
|
}
|
||||||
if(auto colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(eid))
|
if(auto colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(eid))
|
||||||
{
|
{
|
||||||
DrawComponent(colliderComponent);
|
DrawComponent(colliderComponent);
|
||||||
|
@ -174,6 +187,7 @@ namespace SHADE
|
||||||
DrawAddComponentWithEnforcedComponentButton<SHRigidBodyComponent, SHTransformComponent>(eid);
|
DrawAddComponentWithEnforcedComponentButton<SHRigidBodyComponent, SHTransformComponent>(eid);
|
||||||
DrawAddComponentWithEnforcedComponentButton<SHColliderComponent, SHTransformComponent>(eid);
|
DrawAddComponentWithEnforcedComponentButton<SHColliderComponent, SHTransformComponent>(eid);
|
||||||
DrawAddComponentWithEnforcedComponentButton<SHTextRenderableComponent, SHTransformComponent>(eid);
|
DrawAddComponentWithEnforcedComponentButton<SHTextRenderableComponent, SHTransformComponent>(eid);
|
||||||
|
DrawAddComponentWithEnforcedComponentButton<SHAnimatorComponent, SHTransformComponent, SHRenderable>(eid);
|
||||||
|
|
||||||
|
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
|
|
|
@ -581,7 +581,11 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Bind all required objects before drawing
|
// Bind all required objects before drawing
|
||||||
static std::array dynamicOffset{ 0U, static_cast<uint32_t>(boneMatrixData.size() * sizeof(SHMatrix)) };
|
std::vector<uint32_t> dynamicOffset{ 0 };
|
||||||
|
if (!boneMatrixData.empty())
|
||||||
|
{
|
||||||
|
dynamicOffset.emplace_back(0);
|
||||||
|
}
|
||||||
cmdBuffer->BeginLabeledSegment("SHBatch for Pipeline #" + std::to_string(pipeline.GetId().Data.Index));
|
cmdBuffer->BeginLabeledSegment("SHBatch for Pipeline #" + std::to_string(pipeline.GetId().Data.Index));
|
||||||
cmdBuffer->BindPipeline(pipeline);
|
cmdBuffer->BindPipeline(pipeline);
|
||||||
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
|
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
|
||||||
|
@ -598,10 +602,6 @@ namespace SHADE
|
||||||
dynamicOffset
|
dynamicOffset
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (boneMatrixBuffer[frameIndex] && boneFirstIndexBuffer[frameIndex])
|
|
||||||
{
|
|
||||||
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::BONE_INDICES, boneFirstIndexBuffer[frameIndex], 0);
|
|
||||||
}
|
|
||||||
cmdBuffer->DrawMultiIndirect(drawDataBuffer[frameIndex], static_cast<uint32_t>(drawData.size()));
|
cmdBuffer->DrawMultiIndirect(drawDataBuffer[frameIndex], static_cast<uint32_t>(drawData.size()));
|
||||||
cmdBuffer->EndLabeledSegment();
|
cmdBuffer->EndLabeledSegment();
|
||||||
}
|
}
|
||||||
|
@ -648,15 +648,16 @@ namespace SHADE
|
||||||
using PreDefDescLayoutType = SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes;
|
using PreDefDescLayoutType = SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes;
|
||||||
static constexpr uint32_t MATERIAL_DESC_SET_INDEX = 0;
|
static constexpr uint32_t MATERIAL_DESC_SET_INDEX = 0;
|
||||||
|
|
||||||
// Flags
|
|
||||||
bool descSetUpdateRequired = false;
|
|
||||||
|
|
||||||
/* Create Descriptor Sets if Needed */
|
/* Create Descriptor Sets if Needed */
|
||||||
PreDefDescLayoutType layoutTypes = {};
|
PreDefDescLayoutType layoutTypes = {};
|
||||||
if (matPropsData)
|
if (matPropsData)
|
||||||
layoutTypes |= PreDefDescLayoutType::MATERIALS;
|
{
|
||||||
|
layoutTypes = PreDefDescLayoutType::MATERIALS;
|
||||||
|
}
|
||||||
if (!boneMatrixData.empty())
|
if (!boneMatrixData.empty())
|
||||||
layoutTypes |= PreDefDescLayoutType::BONES;
|
{
|
||||||
|
layoutTypes = PreDefDescLayoutType::MATERIAL_AND_BONES;
|
||||||
|
}
|
||||||
|
|
||||||
if (matPropsData || !boneMatrixData.empty())
|
if (matPropsData || !boneMatrixData.empty())
|
||||||
{
|
{
|
||||||
|
@ -699,21 +700,19 @@ namespace SHADE
|
||||||
0, static_cast<uint32_t>(matPropsDataSize)
|
0, static_cast<uint32_t>(matPropsDataSize)
|
||||||
);
|
);
|
||||||
|
|
||||||
descSetUpdateRequired = true;
|
// Update the descriptor set buffer
|
||||||
|
instanceDataDescSet[frameIndex]->UpdateDescriptorSetBuffer
|
||||||
|
(
|
||||||
|
MATERIAL_DESC_SET_INDEX,
|
||||||
|
SHGraphicsConstants::DescriptorSetBindings::PER_INST_MATERIAL_DATA
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Animation Bone Data */
|
/* Animation Bone Data */
|
||||||
if (!boneMatrixData.empty())
|
if (!boneMatrixData.empty())
|
||||||
{
|
{
|
||||||
// Update GPU Buffers
|
// Update GPU Buffers
|
||||||
const uint32_t BONE_IDX_DATA_BYTES = static_cast<uint32_t>(boneMatrixIndices.size() * sizeof(uint32_t));
|
const uint32_t BONE_MTX_DATA_BYTES = static_cast<uint32_t>(boneMatrixData.size() * sizeof(SHMatrix));
|
||||||
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
|
||||||
(
|
|
||||||
device, boneFirstIndexBuffer[frameIndex], boneMatrixIndices.data(), BONE_IDX_DATA_BYTES,
|
|
||||||
BuffUsage::eVertexBuffer,
|
|
||||||
"Batch Bone Indices Buffer"
|
|
||||||
);
|
|
||||||
const uint32_t BONE_MTX_DATA_BYTES = static_cast<uint32_t>(boneMatrixData.size() * sizeof(uint32_t));
|
|
||||||
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
||||||
(
|
(
|
||||||
device, boneMatrixBuffer[frameIndex], boneMatrixData.data(), BONE_MTX_DATA_BYTES,
|
device, boneMatrixBuffer[frameIndex], boneMatrixData.data(), BONE_MTX_DATA_BYTES,
|
||||||
|
@ -728,21 +727,15 @@ namespace SHADE
|
||||||
MATERIAL_DESC_SET_INDEX,
|
MATERIAL_DESC_SET_INDEX,
|
||||||
SHGraphicsConstants::DescriptorSetBindings::PER_INST_BONE_DATA,
|
SHGraphicsConstants::DescriptorSetBindings::PER_INST_BONE_DATA,
|
||||||
bufferList,
|
bufferList,
|
||||||
static_cast<uint32_t>(matPropsDataSize),
|
0,
|
||||||
static_cast<uint32_t>(boneMatrixData.size() * sizeof(SHMatrix))
|
static_cast<uint32_t>(boneMatrixData.size() * sizeof(SHMatrix))
|
||||||
);
|
);
|
||||||
|
|
||||||
descSetUpdateRequired = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build and prepare the descriptor set if necessary
|
|
||||||
if (descSetUpdateRequired)
|
|
||||||
{
|
|
||||||
// Update the descriptor set buffer
|
// Update the descriptor set buffer
|
||||||
instanceDataDescSet[frameIndex]->UpdateDescriptorSetBuffer
|
instanceDataDescSet[frameIndex]->UpdateDescriptorSetBuffer
|
||||||
(
|
(
|
||||||
MATERIAL_DESC_SET_INDEX,
|
MATERIAL_DESC_SET_INDEX,
|
||||||
SHGraphicsConstants::DescriptorSetBindings::PER_INST_MATERIAL_DATA
|
SHGraphicsConstants::DescriptorSetBindings::PER_INST_BONE_DATA
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,7 +134,6 @@ namespace SHADE
|
||||||
TripleBuffer instancedIntegerBuffer;
|
TripleBuffer instancedIntegerBuffer;
|
||||||
TripleBuffer matPropsBuffer;
|
TripleBuffer matPropsBuffer;
|
||||||
TripleBuffer boneMatrixBuffer;
|
TripleBuffer boneMatrixBuffer;
|
||||||
TripleBuffer boneFirstIndexBuffer;
|
|
||||||
TripleDescSet instanceDataDescSet;
|
TripleDescSet instanceDataDescSet;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -28,6 +28,13 @@ namespace SHADE
|
||||||
{SHPredefinedDescriptorTypes::PER_INSTANCE_BATCH, 2},
|
{SHPredefinedDescriptorTypes::PER_INSTANCE_BATCH, 2},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING_ANIM)].descMappings.AddMappings
|
||||||
|
({
|
||||||
|
{SHPredefinedDescriptorTypes::STATIC_DATA, 0},
|
||||||
|
{SHPredefinedDescriptorTypes::CAMERA, 1},
|
||||||
|
{SHPredefinedDescriptorTypes::PER_INSTANCE_ANIM_BATCH, 2},
|
||||||
|
});
|
||||||
|
|
||||||
perSystemData[SHUtilities::ConvertEnum(SystemType::TEXT_RENDERING)].descMappings.AddMappings
|
perSystemData[SHUtilities::ConvertEnum(SystemType::TEXT_RENDERING)].descMappings.AddMappings
|
||||||
({
|
({
|
||||||
{SHPredefinedDescriptorTypes::STATIC_DATA, 0},
|
{SHPredefinedDescriptorTypes::STATIC_DATA, 0},
|
||||||
|
@ -129,14 +136,7 @@ namespace SHADE
|
||||||
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::PER_INST_MATERIAL_DATA,
|
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::PER_INST_MATERIAL_DATA,
|
||||||
.DescriptorCount = 1,
|
.DescriptorCount = 1,
|
||||||
};
|
};
|
||||||
SHVkDescriptorSetLayout::Binding boneDataBinding
|
Handle<SHVkDescriptorSetLayout> materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout({ materialDataBinding });
|
||||||
{
|
|
||||||
.Type = vk::DescriptorType::eStorageBufferDynamic,
|
|
||||||
.Stage = vk::ShaderStageFlagBits::eVertex,
|
|
||||||
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::PER_INST_BONE_DATA,
|
|
||||||
.DescriptorCount = 1,
|
|
||||||
};
|
|
||||||
Handle<SHVkDescriptorSetLayout> materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout({ materialDataBinding, boneDataBinding });
|
|
||||||
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, materialDataPerInstanceLayout->GetVkHandle(), "[Descriptor Set Layout] Material Globals");
|
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, materialDataPerInstanceLayout->GetVkHandle(), "[Descriptor Set Layout] Material Globals");
|
||||||
|
|
||||||
// font bitmap data (texture)
|
// font bitmap data (texture)
|
||||||
|
@ -160,17 +160,16 @@ namespace SHADE
|
||||||
Handle<SHVkDescriptorSetLayout> fontDataDescSetLayout = logicalDevice->CreateDescriptorSetLayout({ fontBitmapBinding, fontMatrixBinding });
|
Handle<SHVkDescriptorSetLayout> fontDataDescSetLayout = logicalDevice->CreateDescriptorSetLayout({ fontBitmapBinding, fontMatrixBinding });
|
||||||
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, fontDataDescSetLayout->GetVkHandle(), "[Descriptor Set Layout] Font Data");
|
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, fontDataDescSetLayout->GetVkHandle(), "[Descriptor Set Layout] Font Data");
|
||||||
|
|
||||||
// Bone matrix data
|
// For per instance data (transforms, materials, etc.)
|
||||||
SHVkDescriptorSetLayout::Binding boneMatrixBinding
|
SHVkDescriptorSetLayout::Binding boneDataBinding
|
||||||
{
|
{
|
||||||
.Type = vk::DescriptorType::eStorageBuffer,
|
.Type = vk::DescriptorType::eStorageBufferDynamic,
|
||||||
.Stage = vk::ShaderStageFlagBits::eVertex,
|
.Stage = vk::ShaderStageFlagBits::eVertex,
|
||||||
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::BONE_MATRIX_DATA,
|
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::PER_INST_BONE_DATA,
|
||||||
.DescriptorCount = 1,
|
.DescriptorCount = 1,
|
||||||
};
|
};
|
||||||
|
Handle<SHVkDescriptorSetLayout> materialBoneDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout({ materialDataBinding, boneDataBinding });
|
||||||
Handle<SHVkDescriptorSetLayout> boneMatricesDescSetLayout = logicalDevice->CreateDescriptorSetLayout({ boneMatrixBinding });
|
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, materialBoneDataPerInstanceLayout->GetVkHandle(), "[Descriptor Set Layout] Material and Bone Globals");
|
||||||
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, boneMatricesDescSetLayout->GetVkHandle(), "[Descriptor Set Layout] Bone Matrix Data");
|
|
||||||
|
|
||||||
predefinedLayouts.push_back(staticGlobalLayout);
|
predefinedLayouts.push_back(staticGlobalLayout);
|
||||||
predefinedLayouts.push_back(lightDataDescSetLayout);
|
predefinedLayouts.push_back(lightDataDescSetLayout);
|
||||||
|
@ -178,7 +177,7 @@ namespace SHADE
|
||||||
predefinedLayouts.push_back(materialDataPerInstanceLayout);
|
predefinedLayouts.push_back(materialDataPerInstanceLayout);
|
||||||
predefinedLayouts.push_back(fontDataDescSetLayout);
|
predefinedLayouts.push_back(fontDataDescSetLayout);
|
||||||
predefinedLayouts.push_back({});
|
predefinedLayouts.push_back({});
|
||||||
predefinedLayouts.push_back(boneMatricesDescSetLayout);
|
predefinedLayouts.push_back(materialBoneDataPerInstanceLayout);
|
||||||
|
|
||||||
perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].descSetLayouts = GetPredefinedDescSetLayouts
|
perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].descSetLayouts = GetPredefinedDescSetLayouts
|
||||||
(
|
(
|
||||||
|
@ -187,6 +186,13 @@ namespace SHADE
|
||||||
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::MATERIALS
|
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::MATERIALS
|
||||||
);
|
);
|
||||||
|
|
||||||
|
perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING_ANIM)].descSetLayouts = GetPredefinedDescSetLayouts
|
||||||
|
(
|
||||||
|
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::STATIC_DATA |
|
||||||
|
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::CAMERA |
|
||||||
|
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::MATERIAL_AND_BONES
|
||||||
|
);
|
||||||
|
|
||||||
perSystemData[SHUtilities::ConvertEnum(SystemType::TEXT_RENDERING)].descSetLayouts = GetPredefinedDescSetLayouts
|
perSystemData[SHUtilities::ConvertEnum(SystemType::TEXT_RENDERING)].descSetLayouts = GetPredefinedDescSetLayouts
|
||||||
(
|
(
|
||||||
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::STATIC_DATA |
|
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::STATIC_DATA |
|
||||||
|
|
|
@ -23,18 +23,19 @@ namespace SHADE
|
||||||
// This enum is mainly to initialize a bit field to retrieve bit fields from SHPRedefinedData
|
// This enum is mainly to initialize a bit field to retrieve bit fields from SHPRedefinedData
|
||||||
enum class PredefinedDescSetLayoutTypes : uint64_t
|
enum class PredefinedDescSetLayoutTypes : uint64_t
|
||||||
{
|
{
|
||||||
STATIC_DATA = 0b0000001,
|
STATIC_DATA = 0b00000001,
|
||||||
LIGHTS = 0b0000010,
|
LIGHTS = 0b00000010,
|
||||||
CAMERA = 0b0000100,
|
CAMERA = 0b00000100,
|
||||||
MATERIALS = 0b0001000,
|
MATERIALS = 0b00001000,
|
||||||
FONT = 0b0010000,
|
FONT = 0b00010000,
|
||||||
SHADOW = 0b0100000,
|
SHADOW = 0b00100000,
|
||||||
BONES = 0b1000000,
|
MATERIAL_AND_BONES = 0b01000000
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SystemType
|
enum class SystemType
|
||||||
{
|
{
|
||||||
BATCHING = 0,
|
BATCHING = 0,
|
||||||
|
BATCHING_ANIM,
|
||||||
TEXT_RENDERING,
|
TEXT_RENDERING,
|
||||||
RENDER_GRAPH_NODE_COMPUTE,
|
RENDER_GRAPH_NODE_COMPUTE,
|
||||||
NUM_TYPES
|
NUM_TYPES
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace SHADE
|
||||||
LIGHTS,
|
LIGHTS,
|
||||||
CAMERA,
|
CAMERA,
|
||||||
PER_INSTANCE_BATCH,
|
PER_INSTANCE_BATCH,
|
||||||
BONES,
|
PER_INSTANCE_ANIM_BATCH,
|
||||||
FONT,
|
FONT,
|
||||||
RENDER_GRAPH_RESOURCE,
|
RENDER_GRAPH_RESOURCE,
|
||||||
RENDER_GRAPH_NODE_COMPUTE_RESOURCE,
|
RENDER_GRAPH_NODE_COMPUTE_RESOURCE,
|
||||||
|
|
|
@ -173,7 +173,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
static constexpr uint32_t BONE_MATRIX_DATA = 0;
|
static constexpr uint32_t BONE_MATRIX_DATA = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VertexBufferBindings
|
struct VertexBufferBindings
|
||||||
|
|
|
@ -185,7 +185,9 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
const auto OG_SIZE = vertBoneWeightStorage.size();
|
||||||
vertBoneWeightStorage.resize(vertBoneWeightStorage.size() + addJob.VertexCount);
|
vertBoneWeightStorage.resize(vertBoneWeightStorage.size() + addJob.VertexCount);
|
||||||
|
std::fill_n(vertBoneWeightStorage.begin() + OG_SIZE, addJob.VertexCount, SHVec4(1.0f, 0.0f, 0.0f, 0.0f));
|
||||||
}
|
}
|
||||||
indexStorage.insert
|
indexStorage.insert
|
||||||
(
|
(
|
||||||
|
|
|
@ -8,12 +8,12 @@
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
Handle<SHVkPipeline> SHPipelineLibrary::CreateGraphicsPipelines(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHVkRenderpass> renderpass, Handle<SHSubpass> subpass) noexcept
|
Handle<SHVkPipeline> SHPipelineLibrary::CreateGraphicsPipelines(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHVkRenderpass> renderpass, Handle<SHSubpass> subpass, SHGraphicsPredefinedData::SystemType systemType) noexcept
|
||||||
{
|
{
|
||||||
SHPipelineLayoutParams params
|
SHPipelineLayoutParams params
|
||||||
{
|
{
|
||||||
.shaderModules = {vsFsPair.first, vsFsPair.second},
|
.shaderModules = {vsFsPair.first, vsFsPair.second},
|
||||||
.predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING).descSetLayouts
|
.predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(systemType).descSetLayouts
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create the pipeline layout
|
// Create the pipeline layout
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "Graphics/Shaders/SHVkShaderModule.h"
|
#include "Graphics/Shaders/SHVkShaderModule.h"
|
||||||
#include "Graphics/Pipeline/SHVkPipeline.h"
|
#include "Graphics/Pipeline/SHVkPipeline.h"
|
||||||
|
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -32,7 +33,8 @@ namespace SHADE
|
||||||
Handle<SHVkPipeline> CreateGraphicsPipelines (
|
Handle<SHVkPipeline> CreateGraphicsPipelines (
|
||||||
std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair,
|
std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair,
|
||||||
Handle<SHVkRenderpass> renderpass,
|
Handle<SHVkRenderpass> renderpass,
|
||||||
Handle<SHSubpass> subpass
|
Handle<SHSubpass> subpass,
|
||||||
|
SHGraphicsPredefinedData::SystemType systemType
|
||||||
) noexcept;
|
) noexcept;
|
||||||
Handle<SHVkPipeline> GetGraphicsPipeline (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
|
Handle<SHVkPipeline> GetGraphicsPipeline (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
|
||||||
bool CheckGraphicsPipelineExistence (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
|
bool CheckGraphicsPipelineExistence (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
|
||||||
|
|
|
@ -583,11 +583,37 @@ namespace SHADE
|
||||||
Handle<SHVkPipeline> pipeline = pipelineLibrary.GetGraphicsPipeline(vsFsPair);
|
Handle<SHVkPipeline> pipeline = pipelineLibrary.GetGraphicsPipeline(vsFsPair);
|
||||||
if (!pipeline)
|
if (!pipeline)
|
||||||
{
|
{
|
||||||
|
// default to batching system type
|
||||||
|
SHGraphicsPredefinedData::SystemType systemType{ SHGraphicsPredefinedData::SystemType::BATCHING };
|
||||||
|
auto const& REFLECTED_SETS = vsFsPair.first->GetReflectedData().GetDescriptorBindingInfo().GetReflectedSets();
|
||||||
|
|
||||||
|
// look for animation set binding in the shader (set 2 binding 1)
|
||||||
|
for (auto const& set : REFLECTED_SETS)
|
||||||
|
{
|
||||||
|
auto const mappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING_ANIM);
|
||||||
|
|
||||||
|
// Look for set 2
|
||||||
|
if (set->set == mappings.at(SHPredefinedDescriptorTypes::PER_INSTANCE_ANIM_BATCH))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < set->binding_count; i++)
|
||||||
|
{
|
||||||
|
// look for binding 1. if found use BATCHING_ANIM system type
|
||||||
|
if (set->bindings[i]->binding == SHGraphicsConstants::DescriptorSetBindings::BONE_MATRIX_DATA)
|
||||||
|
{
|
||||||
|
systemType = SHGraphicsPredefinedData::SystemType::BATCHING_ANIM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pipeline = pipelineLibrary.CreateGraphicsPipelines
|
pipeline = pipelineLibrary.CreateGraphicsPipelines
|
||||||
(
|
(
|
||||||
vsFsPair,
|
vsFsPair,
|
||||||
renderpass,
|
renderpass,
|
||||||
subpass
|
subpass,
|
||||||
|
systemType
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,8 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||||
#include "Assets/Asset Types/SHMaterialAsset.h"
|
#include "Assets/Asset Types/SHMaterialAsset.h"
|
||||||
#include "Graphics/MiddleEnd/TextRendering/SHFont.h"
|
#include "Graphics/MiddleEnd/TextRendering/SHFont.h"
|
||||||
|
#include "Animation/SHAnimationClip.h"
|
||||||
|
#include "Animation/SHRig.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -49,6 +51,8 @@ namespace SHADE
|
||||||
template<> struct SHResourceLoader<SHMaterialSpec> { using AssetType = SHMaterialAsset; };
|
template<> struct SHResourceLoader<SHMaterialSpec> { using AssetType = SHMaterialAsset; };
|
||||||
template<> struct SHResourceLoader<SHMaterial> { using AssetType = SHMaterialSpec; };
|
template<> struct SHResourceLoader<SHMaterial> { using AssetType = SHMaterialSpec; };
|
||||||
template<> struct SHResourceLoader<SHFont> { using AssetType = SHFontAsset; };
|
template<> struct SHResourceLoader<SHFont> { using AssetType = SHFontAsset; };
|
||||||
|
template<> struct SHResourceLoader<SHAnimationClip> { using AssetType = SHModelAsset; };
|
||||||
|
template<> struct SHResourceLoader<SHRig> { using AssetType = SHModelAsset; };
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Static class responsible for loading and caching runtime resources from their
|
/// Static class responsible for loading and caching runtime resources from their
|
||||||
|
|
|
@ -40,7 +40,9 @@ namespace SHADE
|
||||||
!std::is_same_v<ResourceType, SHVkShaderModule> &&
|
!std::is_same_v<ResourceType, SHVkShaderModule> &&
|
||||||
!std::is_same_v<ResourceType, SHMaterialSpec> &&
|
!std::is_same_v<ResourceType, SHMaterialSpec> &&
|
||||||
!std::is_same_v<ResourceType, SHFont> &&
|
!std::is_same_v<ResourceType, SHFont> &&
|
||||||
!std::is_same_v<ResourceType, SHMaterial>
|
!std::is_same_v<ResourceType, SHMaterial> &&
|
||||||
|
!std::is_same_v<ResourceType, SHAnimationClip> &&
|
||||||
|
!std::is_same_v<ResourceType, SHRig>
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
static_assert(true, "Unsupported Resource Type specified for SHResourceManager.");
|
static_assert(true, "Unsupported Resource Type specified for SHResourceManager.");
|
||||||
|
@ -209,7 +211,9 @@ namespace SHADE
|
||||||
assetData.VertexTangents.data(),
|
assetData.VertexTangents.data(),
|
||||||
assetData.VertexNormals.data(),
|
assetData.VertexNormals.data(),
|
||||||
assetData.Indices.size(),
|
assetData.Indices.size(),
|
||||||
assetData.Indices.data()
|
assetData.Indices.data(),
|
||||||
|
assetData.VertexBoneIndices.empty() ? nullptr : assetData.VertexBoneIndices.data(),
|
||||||
|
assetData.VertexBoneWeights.empty() ? nullptr : assetData.VertexBoneWeights.data()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// Textures
|
// Textures
|
||||||
|
@ -345,5 +349,16 @@ namespace SHADE
|
||||||
|
|
||||||
return gfxSystem->AddFont(assetData);
|
return gfxSystem->AddFont(assetData);
|
||||||
}
|
}
|
||||||
|
// Animation Clip and Rig
|
||||||
|
else if constexpr (std::is_same_v<ResourceType, SHRig>)
|
||||||
|
{
|
||||||
|
loadedAssetData.emplace_back(assetId);
|
||||||
|
return resourceHub.Create<ResourceType>(assetData.rig);
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<ResourceType, SHAnimationClip>)
|
||||||
|
{
|
||||||
|
loadedAssetData.emplace_back(assetId);
|
||||||
|
return resourceHub.Create<ResourceType>(*assetData.anims[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue