Implemented Animation Clip asset and animation controller #410
|
@ -82,7 +82,5 @@ namespace SHADE
|
||||||
double ticksPerSecond;
|
double ticksPerSecond;
|
||||||
|
|
||||||
std::vector<SHAnimData> nodeChannels;
|
std::vector<SHAnimData> nodeChannels;
|
||||||
//std::vector<aiMeshAnim*> meshChannels;
|
|
||||||
//std::vector<aiMeshMorphAnim*> morphMeshChannels;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -12,17 +12,24 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
#include "SHAssetData.h"
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "Assets/SHAssetMacros.h"
|
||||||
|
#include "SHAssetData.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
struct SH_API SHAnimClipAsset : SHAssetData
|
struct SHAnimClipAsset : SHAssetData
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
AssetID animRawDataAssetId;
|
|
||||||
uint32_t firstIndex;
|
uint32_t firstIndex;
|
||||||
uint32_t lastIndex;
|
uint32_t lastIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SH_API SHAnimClipContainerAsset final : SHAssetData
|
||||||
|
{
|
||||||
|
AssetID animRawDataAssetId;
|
||||||
|
std::vector<SHAnimClipAsset> clips;
|
||||||
|
};
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
#include "SHBinaryLoader.h"
|
#include "SHBinaryLoader.h"
|
||||||
|
|
||||||
#include "Assets/Asset Types/SHAnimClipAsset.h"
|
#include "Assets/Asset Types/SHAnimClipContainerAsset.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
@ -19,15 +19,9 @@ namespace SHADE
|
||||||
auto const extension = path.extension().string();
|
auto const extension = path.extension().string();
|
||||||
SHAssetData* result{nullptr};
|
SHAssetData* result{nullptr};
|
||||||
|
|
||||||
if (extension == ANIM_CLIP_EXTENSION)
|
if (extension == ANIM_CONTAINER_EXTENSION)
|
||||||
{
|
{
|
||||||
const auto data = new SHAnimClipAsset();
|
LoadAnimClipContainer(file, result, path);
|
||||||
file.read(
|
|
||||||
reinterpret_cast<char*>(&data->animRawDataAssetId),
|
|
||||||
sizeof(uint32_t) * 3
|
|
||||||
);
|
|
||||||
data->name = path.stem().string();
|
|
||||||
result = data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
|
@ -47,15 +41,84 @@ namespace SHADE
|
||||||
|
|
||||||
auto const extension = path.extension().string();
|
auto const extension = path.extension().string();
|
||||||
|
|
||||||
if (extension == ANIM_CLIP_EXTENSION)
|
if (extension == ANIM_CONTAINER_EXTENSION)
|
||||||
{
|
{
|
||||||
auto animClip = dynamic_cast<SHAnimClipAsset const*>(data);
|
WriteAnimClipContainer(file, data, path);
|
||||||
file.write(
|
|
||||||
reinterpret_cast<char const*>(&animClip->animRawDataAssetId),
|
|
||||||
sizeof(uint32_t) * 3
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHBinaryLoader::WriteAnimClipContainer(std::ofstream& file, SHAssetData const* data, AssetPath path)
|
||||||
|
{
|
||||||
|
auto const& anim = *dynamic_cast<SHAnimClipContainerAsset const*>(data);
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(&anim.animRawDataAssetId),
|
||||||
|
sizeof(uint32_t)
|
||||||
|
);
|
||||||
|
|
||||||
|
uint32_t const size {static_cast<uint32_t>(anim.clips.size())};
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(&size),
|
||||||
|
sizeof(uint32_t)
|
||||||
|
);
|
||||||
|
|
||||||
|
for (auto const& clip : anim.clips)
|
||||||
|
{
|
||||||
|
uint32_t charCount {static_cast<uint32_t>(clip.name.size())};
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(&charCount),
|
||||||
|
sizeof(uint32_t)
|
||||||
|
);
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
clip.name.data(),
|
||||||
|
charCount
|
||||||
|
);
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(&clip.firstIndex),
|
||||||
|
sizeof(uint32_t) * 2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHBinaryLoader::LoadAnimClipContainer(std::ifstream& file, SHAssetData* result, AssetPath path)
|
||||||
|
{
|
||||||
|
auto const data = new SHAnimClipContainerAsset();
|
||||||
|
|
||||||
|
file.read(
|
||||||
|
reinterpret_cast<char*>(&data->animRawDataAssetId),
|
||||||
|
sizeof(uint32_t)
|
||||||
|
);
|
||||||
|
|
||||||
|
uint32_t size;
|
||||||
|
|
||||||
|
file.read(
|
||||||
|
reinterpret_cast<char*>(&size),
|
||||||
|
sizeof(uint32_t)
|
||||||
|
);
|
||||||
|
|
||||||
|
for (auto i{0}; i < size; ++i)
|
||||||
|
{
|
||||||
|
auto& clip {data->clips.emplace_back()};
|
||||||
|
uint32_t charCount;
|
||||||
|
file.read(
|
||||||
|
reinterpret_cast<char*>(&charCount),
|
||||||
|
sizeof(uint32_t)
|
||||||
|
);
|
||||||
|
|
||||||
|
clip.name.resize(charCount);
|
||||||
|
file.read(
|
||||||
|
clip.name.data(),
|
||||||
|
charCount
|
||||||
|
);
|
||||||
|
|
||||||
|
file.read(
|
||||||
|
reinterpret_cast<char*>(&clip.firstIndex),
|
||||||
|
sizeof(uint32_t) * 2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,5 +8,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHAssetData* Load(AssetPath path) override;
|
SHAssetData* Load(AssetPath path) override;
|
||||||
void Write(SHAssetData const* data, AssetPath path) override;
|
void Write(SHAssetData const* data, AssetPath path) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
//Individual functions to write files
|
||||||
|
void WriteAnimClipContainer(std::ofstream& file,SHAssetData const* data, AssetPath path);
|
||||||
|
void LoadAnimClipContainer(std::ifstream& file,SHAssetData* result, AssetPath path);
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -57,6 +57,7 @@ enum class AssetType : AssetTypeMeta
|
||||||
MESH,
|
MESH,
|
||||||
SCRIPT,
|
SCRIPT,
|
||||||
FONT,
|
FONT,
|
||||||
|
ANIM_CONTAINER,
|
||||||
ANIM_CLIP,
|
ANIM_CLIP,
|
||||||
MAX_COUNT
|
MAX_COUNT
|
||||||
};
|
};
|
||||||
|
@ -79,7 +80,7 @@ constexpr std::string_view FONT_COMPILER_EXE{ "FontCompiler.exe" };
|
||||||
constexpr std::string_view SCENE_FOLDER{ "/Scenes/" };
|
constexpr std::string_view SCENE_FOLDER{ "/Scenes/" };
|
||||||
constexpr std::string_view PREFAB_FOLDER{ "/Prefabs/" };
|
constexpr std::string_view PREFAB_FOLDER{ "/Prefabs/" };
|
||||||
constexpr std::string_view MATERIAL_FOLDER{ "/Materials/" };
|
constexpr std::string_view MATERIAL_FOLDER{ "/Materials/" };
|
||||||
constexpr std::string_view ANIM_CLIP_FOLDER{ "/Animation Clips/" };
|
constexpr std::string_view ANIM_CLIP_FOLDER{ "/Animations/" };
|
||||||
|
|
||||||
|
|
||||||
// ASSET EXTENSIONS
|
// ASSET EXTENSIONS
|
||||||
|
@ -95,7 +96,8 @@ constexpr std::string_view PREFAB_EXTENSION {".shprefab"};
|
||||||
constexpr std::string_view MATERIAL_EXTENSION {".shmat"};
|
constexpr std::string_view MATERIAL_EXTENSION {".shmat"};
|
||||||
constexpr std::string_view TEXTURE_EXTENSION {".shtex"};
|
constexpr std::string_view TEXTURE_EXTENSION {".shtex"};
|
||||||
constexpr std::string_view MODEL_EXTENSION{ ".shmodel" };
|
constexpr std::string_view MODEL_EXTENSION{ ".shmodel" };
|
||||||
constexpr std::string_view ANIM_CLIP_EXTENSION{ ".shanimclip" };
|
constexpr std::string_view ANIM_CONTAINER_EXTENSION{ ".shanimcontainer" };
|
||||||
|
constexpr std::string_view FILLER_EXTENSION{"dummy"};
|
||||||
|
|
||||||
constexpr std::string_view EXTENSIONS[] = {
|
constexpr std::string_view EXTENSIONS[] = {
|
||||||
AUDIO_EXTENSION,
|
AUDIO_EXTENSION,
|
||||||
|
@ -106,14 +108,15 @@ constexpr std::string_view EXTENSIONS[] = {
|
||||||
SCENE_EXTENSION,
|
SCENE_EXTENSION,
|
||||||
PREFAB_EXTENSION,
|
PREFAB_EXTENSION,
|
||||||
MATERIAL_EXTENSION,
|
MATERIAL_EXTENSION,
|
||||||
"dummy",
|
FILLER_EXTENSION,
|
||||||
SCRIPT_EXTENSION,
|
SCRIPT_EXTENSION,
|
||||||
FONT_EXTENSION,
|
FONT_EXTENSION,
|
||||||
AUDIO_WAV_EXTENSION,
|
AUDIO_WAV_EXTENSION,
|
||||||
ANIM_CLIP_EXTENSION
|
ANIM_CONTAINER_EXTENSION,
|
||||||
|
FILLER_EXTENSION
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr size_t EXTENSIONS_COUNT{ 11 };
|
constexpr size_t EXTENSIONS_COUNT{ static_cast<size_t>(AssetType::MAX_COUNT) };
|
||||||
|
|
||||||
// EXTERNAL EXTENSIONS
|
// EXTERNAL EXTENSIONS
|
||||||
constexpr std::string_view GLSL_EXTENSION{ ".glsl" };
|
constexpr std::string_view GLSL_EXTENSION{ ".glsl" };
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include "Asset Types/SHPrefabAsset.h"
|
#include "Asset Types/SHPrefabAsset.h"
|
||||||
#include "Asset Types/SHMaterialAsset.h"
|
#include "Asset Types/SHMaterialAsset.h"
|
||||||
#include "Asset Types/SHSceneAsset.h"
|
#include "Asset Types/SHSceneAsset.h"
|
||||||
#include "Asset Types/SHAnimClipAsset.h"
|
#include "Asset Types/SHAnimClipContainerAsset.h"
|
||||||
|
|
||||||
#include "Libraries/Compilers/SHTextureCompiler.h"
|
#include "Libraries/Compilers/SHTextureCompiler.h"
|
||||||
#include "Libraries/Compilers/SHShaderSourceCompiler.h"
|
#include "Libraries/Compilers/SHShaderSourceCompiler.h"
|
||||||
|
@ -238,10 +238,10 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AssetType::ANIM_CLIP:
|
case AssetType::ANIM_CONTAINER:
|
||||||
newPath += ANIM_CLIP_FOLDER;
|
newPath += ANIM_CLIP_FOLDER;
|
||||||
newPath += name;
|
newPath += name;
|
||||||
newPath += ANIM_CLIP_EXTENSION;
|
newPath += ANIM_CONTAINER_EXTENSION;
|
||||||
|
|
||||||
{
|
{
|
||||||
auto animClip = new SHAnimClipAsset();
|
auto animClip = new SHAnimClipAsset();
|
||||||
|
@ -252,7 +252,7 @@ namespace SHADE
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
SHLOG_ERROR("[Asset Manager] Asset type of {} not an internal asset type, cannot be created", name);
|
SHLOG_ERROR("[Asset Manager] Asset type of {} not an internal parent asset type, cannot be created", name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,6 +284,40 @@ namespace SHADE
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AssetID SHAssetManager::CreateNewSubAsset(AssetType type, AssetName name, AssetID parent)
|
||||||
|
{
|
||||||
|
if (!assetData.contains(parent))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("[Asset Manager] Failed to create new sub asset, parent does not exist: {}", name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case AssetType::ANIM_CLIP:
|
||||||
|
{
|
||||||
|
auto const animContainer {dynamic_cast<SHAnimClipContainerAsset*>(assetData[parent])};
|
||||||
|
auto id = GenerateAssetID(type);
|
||||||
|
SHAsset asset{
|
||||||
|
.name = name,
|
||||||
|
.id = id,
|
||||||
|
.type = type,
|
||||||
|
.isSubAsset = true,
|
||||||
|
.parent = parent
|
||||||
|
};
|
||||||
|
auto& newClip {animContainer->clips.emplace_back()};
|
||||||
|
newClip.name = name;
|
||||||
|
assetCollection.emplace(id, asset);
|
||||||
|
assetData.emplace(id, &newClip);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
SHLOG_ERROR("[Asset Manager] Asset type of {} not an internal sub asset type, cannot be created", name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool SHAssetManager::SaveAsset(AssetID id) noexcept
|
bool SHAssetManager::SaveAsset(AssetID id) noexcept
|
||||||
{
|
{
|
||||||
if (assetCollection.contains(id))
|
if (assetCollection.contains(id))
|
||||||
|
@ -547,7 +581,8 @@ namespace SHADE
|
||||||
loaders[static_cast<size_t>(AssetType::MESH)] = nullptr;
|
loaders[static_cast<size_t>(AssetType::MESH)] = nullptr;
|
||||||
loaders[static_cast<size_t>(AssetType::SCRIPT)] = nullptr;
|
loaders[static_cast<size_t>(AssetType::SCRIPT)] = nullptr;
|
||||||
loaders[static_cast<size_t>(AssetType::FONT)] = dynamic_cast<SHAssetLoader*>(new SHFontLoader());
|
loaders[static_cast<size_t>(AssetType::FONT)] = dynamic_cast<SHAssetLoader*>(new SHFontLoader());
|
||||||
loaders[static_cast<size_t>(AssetType::ANIM_CLIP)] = dynamic_cast<SHAssetLoader*>(new SHBinaryLoader());
|
loaders[static_cast<size_t>(AssetType::ANIM_CONTAINER)] = dynamic_cast<SHAssetLoader*>(new SHBinaryLoader());
|
||||||
|
loaders[static_cast<size_t>(AssetType::ANIM_CLIP)] = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -758,6 +793,38 @@ namespace SHADE
|
||||||
|
|
||||||
return newAsset.id;
|
return newAsset.id;
|
||||||
}
|
}
|
||||||
|
else if(ext==ANIM_CONTAINER_EXTENSION)
|
||||||
|
{
|
||||||
|
SHAsset newAsset{
|
||||||
|
path.stem().string(),
|
||||||
|
GenerateAssetID(AssetType::ANIM_CONTAINER),
|
||||||
|
AssetType::ANIM_CONTAINER,
|
||||||
|
path,
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
|
assetCollection.emplace(newAsset.id, newAsset);
|
||||||
|
|
||||||
|
SHAnimClipContainerAsset* const data = reinterpret_cast<SHAnimClipContainerAsset*>(LoadData(newAsset));
|
||||||
|
assetData.emplace(newAsset.id, data);
|
||||||
|
for(auto& clip : data->clips)
|
||||||
|
{
|
||||||
|
SHAsset subAsset{
|
||||||
|
.name = clip.name,
|
||||||
|
.id = GenerateAssetID(AssetType::ANIM_CLIP),
|
||||||
|
.type = AssetType::ANIM_CLIP,
|
||||||
|
.isSubAsset = true,
|
||||||
|
.parent = newAsset.id
|
||||||
|
};
|
||||||
|
|
||||||
|
assetCollection.emplace(subAsset.id, subAsset);
|
||||||
|
assetCollection[newAsset.id].subAssets.push_back(&assetCollection[subAsset.id]);
|
||||||
|
|
||||||
|
assetData.emplace(subAsset.id, &clip);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHAssetMetaHandler::WriteMetaData(assetCollection[newAsset.id]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAssetManager::BuildAssetCollection() noexcept
|
void SHAssetManager::BuildAssetCollection() noexcept
|
||||||
|
@ -814,7 +881,9 @@ namespace rttr
|
||||||
value("Material", AssetType::MATERIAL),
|
value("Material", AssetType::MATERIAL),
|
||||||
value("Mesh", AssetType::MESH),
|
value("Mesh", AssetType::MESH),
|
||||||
value("Script", AssetType::SCRIPT),
|
value("Script", AssetType::SCRIPT),
|
||||||
value("Font", AssetType::FONT)
|
value("Font", AssetType::FONT),
|
||||||
|
value("Animation Container", AssetType::ANIM_CONTAINER),
|
||||||
|
value("Animation Clip", AssetType::ANIM_CLIP)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,7 @@ namespace SHADE
|
||||||
* \return resource id generated for new asset
|
* \return resource id generated for new asset
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static AssetID CreateNewAsset(AssetType type, AssetName name) noexcept;
|
static AssetID CreateNewAsset(AssetType type, AssetName name) noexcept;
|
||||||
|
static AssetID CreateNewSubAsset(AssetType type, AssetName name, AssetID parent);
|
||||||
static bool SaveAsset(AssetID id) noexcept;
|
static bool SaveAsset(AssetID id) noexcept;
|
||||||
static bool DeleteAsset(AssetID id) noexcept;
|
static bool DeleteAsset(AssetID id) noexcept;
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Assets/Asset Types/Models/SHModelAsset.h"
|
#include "Assets/Asset Types/Models/SHModelAsset.h"
|
||||||
#include "Assets/Asset Types/SHTextureAsset.h"
|
#include "Assets/Asset Types/SHTextureAsset.h"
|
||||||
#include "Assets/Asset Types/SHShaderAsset.h"
|
#include "Assets/Asset Types/SHShaderAsset.h"
|
||||||
#include "Assets/Asset Types/SHAnimClipAsset.h"
|
#include "Assets/Asset Types/SHAnimClipContainerAsset.h"
|
||||||
#include "Assets/Asset Types/SHAnimControllerAsset.h"
|
#include "Assets/Asset Types/SHAnimControllerAsset.h"
|
||||||
#include "Graphics/Shaders/SHVkShaderModule.h"
|
#include "Graphics/Shaders/SHVkShaderModule.h"
|
||||||
#include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h"
|
#include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h"
|
||||||
|
|
Loading…
Reference in New Issue