Merge branch 'main' into SP3-305-configurationsMerge

This commit is contained in:
Sri Sham Haran 2022-11-04 18:37:19 +08:00
commit b86f092f52
38 changed files with 5534 additions and 580 deletions

Binary file not shown.

View File

@ -1,3 +0,0 @@
Name: Cube.003
ID: 71245919
Type: 4

View File

@ -1,3 +0,0 @@
Name: Cube.012
ID: 80365422
Type: 4

BIN
Assets/Models/racoon.fbx Normal file

Binary file not shown.

4993
Assets/Models/racoon.gltf Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,10 @@
Name: racoon
ID: 77816045
Type: 4
Sub Assets:
Name: Bag
ID: 144838771
Type: 8
Name: Raccoon
ID: 149697411
Type: 8

View File

@ -43,7 +43,7 @@ void main()
{ {
position = In.vertPos; position = In.vertPos;
normals = In.normal; normals = In.normal;
albedo = texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv) + MatProp.data[In2.materialIndex].color; albedo = texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv) * MatProp.data[In2.materialIndex].color;
outEntityID = In2.eid; outEntityID = In2.eid;
lightLayerIndices = In2.lightLayerIndex; lightLayerIndices = In2.lightLayerIndex;

Binary file not shown.

View File

@ -7,7 +7,7 @@ echo "SHADE DEPENDENCIES (Default - All in 10 Seconds)"
echo "A - All" echo "A - All"
echo "B - VMA" echo "B - VMA"
echo "C - msdf" echo "C - msdf"
echo "D - assimp" echo "D - ModelCompiler"
echo "E - spdlog" echo "E - spdlog"
echo "F - reactphysics3d" echo "F - reactphysics3d"
echo "G - imgui" echo "G - imgui"
@ -29,7 +29,7 @@ set _e=%ERRORLEVEL%
if %_e%==1 goto VMA if %_e%==1 goto VMA
if %_e%==2 goto VMA if %_e%==2 goto VMA
if %_e%==3 goto MSDF if %_e%==3 goto MSDF
if %_e%==4 goto assimp if %_e%==4 goto ModelCompiler
if %_e%==5 goto spdlog if %_e%==5 goto spdlog
if %_e%==6 goto reactphysics3d if %_e%==6 goto reactphysics3d
if %_e%==7 goto imgui if %_e%==7 goto imgui
@ -53,12 +53,13 @@ if %_e%==2 (goto :done) else (goto :MSDF)
echo -----------------------MSDF---------------------------- echo -----------------------MSDF----------------------------
rmdir "Dependencies/msdf" /S /Q rmdir "Dependencies/msdf" /S /Q
git clone --recurse-submodules https://github.com/SHADE-DP/msdf-atlas-gen.git "Dependencies/msdf" git clone --recurse-submodules https://github.com/SHADE-DP/msdf-atlas-gen.git "Dependencies/msdf"
if %_e%==3 (goto :done) else (goto :assimp) if %_e%==3 (goto :done) else (goto :ModelCompiler)
:assimp :ModelCompiler
echo -----------------------assimp---------------------------- echo -----------------------ModelCompiler----------------------------
rmdir "Dependencies/assimp" /S /Q rmdir "Dependencies/ModelCompiler" /S /Q
git clone https://github.com/SHADE-DP/assimp.git "Dependencies/assimp" git clone https://github.com/SHADE-DP/ModelCompiler.git "Dependencies/ModelCompiler"
Dependencies/ModelCompiler/Dependencies.bat
if %_e%==4 (goto :done) else (goto :spdlog) if %_e%==4 (goto :done) else (goto :spdlog)
@REM :ktx @REM :ktx

View File

@ -1,5 +1,5 @@
IncludeDir = {} IncludeDir = {}
IncludeDir["assimp"] = "%{wks.location}\\Dependencies\\assimp" IncludeDir["ModelCompiler"] = "%{wks.location}\\Dependencies\\ModelCompiler"
IncludeDir["imgui"] = "%{wks.location}\\Dependencies\\imgui" IncludeDir["imgui"] = "%{wks.location}\\Dependencies\\imgui"
IncludeDir["imguizmo"] = "%{wks.location}\\Dependencies\\imguizmo" IncludeDir["imguizmo"] = "%{wks.location}\\Dependencies\\imguizmo"
IncludeDir["imnodes"] = "%{wks.location}\\Dependencies\\imnodes" IncludeDir["imnodes"] = "%{wks.location}\\Dependencies\\imnodes"

View File

@ -53,7 +53,7 @@ namespace Sandbox
switch (asset.type) switch (asset.type)
{ {
case AssetType::MESH: case AssetType::MESH:
if (asset.name == "Cube.012") if (asset.name == "Raccoon")
handles.emplace_back(SHResourceManager::LoadOrGet<SHMesh>(asset.id)); handles.emplace_back(SHResourceManager::LoadOrGet<SHMesh>(asset.id));
break; break;
case AssetType::TEXTURE: case AssetType::TEXTURE:
@ -67,7 +67,7 @@ namespace Sandbox
// Create Materials // Create Materials
auto baseRaccoonMat = graphicsSystem->AddOrGetBaseMaterialInstance(); auto baseRaccoonMat = graphicsSystem->AddOrGetBaseMaterialInstance();
auto baseRaccoonMatInstant = graphicsSystem->AddMaterialInstanceCopy(baseRaccoonMat); auto baseRaccoonMatInstant = graphicsSystem->AddMaterialInstanceCopy(baseRaccoonMat);
baseRaccoonMatInstant->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 1.0f)); baseRaccoonMatInstant->SetProperty("data.color", SHVec4(1.0f, 1.0f, 1.0f, 1.0f));
baseRaccoonMatInstant->SetProperty("data.textureIndex", 0); baseRaccoonMatInstant->SetProperty("data.textureIndex", 0);
baseRaccoonMatInstant->SetProperty("data.alpha", 0.1f); baseRaccoonMatInstant->SetProperty("data.alpha", 0.1f);
@ -182,6 +182,7 @@ namespace Sandbox
scriptEngine->AddScript(racoon, "PickAndThrow"); scriptEngine->AddScript(racoon, "PickAndThrow");
scriptEngine->AddScript(racoonCamera, "ThirdPersonCamera"); scriptEngine->AddScript(racoonCamera, "ThirdPersonCamera");
scriptEngine->AddScript(AI, "AIPrototype"); scriptEngine->AddScript(AI, "AIPrototype");
scriptEngine->AddScript(item, "Item");
auto raccoonShowcase = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>(); auto raccoonShowcase = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
auto& renderableShowcase = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonShowcase); auto& renderableShowcase = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonShowcase);
@ -189,7 +190,7 @@ namespace Sandbox
renderableShowcase.SetMesh(handles.front()); renderableShowcase.SetMesh(handles.front());
renderableShowcase.SetMaterial(baseRaccoonMatInstant); renderableShowcase.SetMaterial(baseRaccoonMatInstant);
renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f)); renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 1.0f, 1.0f, 1.0f));
renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f); renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
renderableShowcase.GetModifiableMaterial()->SetProperty("data.textureIndex", 0); renderableShowcase.GetModifiableMaterial()->SetProperty("data.textureIndex", 0);

View File

@ -26,7 +26,6 @@ project "SHADE_Engine"
externalincludedirs externalincludedirs
{ {
"%{IncludeDir.assimp}\\include",
"%{IncludeDir.imgui}", "%{IncludeDir.imgui}",
"%{IncludeDir.imguizmo}", "%{IncludeDir.imguizmo}",
"%{IncludeDir.imnodes}", "%{IncludeDir.imnodes}",
@ -52,8 +51,6 @@ project "SHADE_Engine"
{ {
"%{prj.location}/libs", "%{prj.location}/libs",
"%{IncludeDir.VULKAN}/Lib", "%{IncludeDir.VULKAN}/Lib",
"%{IncludeDir.assimp}/lib/Debug",
"%{IncludeDir.assimp}/lib/Release",
"%{IncludeDir.RTTR}/lib", "%{IncludeDir.RTTR}/lib",
"%{IncludeDir.SDL}/lib", "%{IncludeDir.SDL}/lib",
"%{IncludeDir.spdlog}/lib", "%{IncludeDir.spdlog}/lib",
@ -119,7 +116,8 @@ project "SHADE_Engine"
filter "configurations:Debug" filter "configurations:Debug"
postbuildcommands postbuildcommands
{ {
"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Debug\\assimp-vc142-mtd.dll\" \"$(OutDir)\"", "xcopy /r /y /q \"%{IncludeDir.ModelCompiler}\\bin\\Debug\\assimp-vc142-mtd.dll\" \"$(OutDir)\"",
"xcopy /r /y /q \"%{IncludeDir.ModelCompiler}\\bin\\Debug\\ModelCompiler.exe\" \"$(OutDir)\"",
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodL.dll\" \"$(OutDir)\"", "xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodL.dll\" \"$(OutDir)\"",
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudioL.dll\" \"$(OutDir)\"" "xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudioL.dll\" \"$(OutDir)\""
} }
@ -127,7 +125,8 @@ project "SHADE_Engine"
filter "configurations:Release" filter "configurations:Release"
postbuildcommands postbuildcommands
{ {
"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\"", "xcopy /r /y /q \"%{IncludeDir.ModelCompiler}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\"",
"xcopy /r /y /q \"%{IncludeDir.ModelCompiler}\\bin\\Release\\ModelCompiler.exe\" \"$(OutDir)\"",
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmod.dll\" \"$(OutDir)\"", "xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmod.dll\" \"$(OutDir)\"",
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudio.dll\" \"$(OutDir)\"" "xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudio.dll\" \"$(OutDir)\""
} }
@ -135,32 +134,35 @@ project "SHADE_Engine"
filter "configurations:Publish" filter "configurations:Publish"
postbuildcommands postbuildcommands
{ {
"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\"", --"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\"",
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmod.dll\" \"$(OutDir)\"", "xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmod.dll\" \"$(OutDir)\"",
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudio.dll\" \"$(OutDir)\"" "xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudio.dll\" \"$(OutDir)\""
} }
filter "configurations:Publish" filter "configurations:Publish"
postbuildcommands {"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\""} postbuildcommands
{
--"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\""
}
warnings 'Extra' warnings 'Extra'
filter "configurations:Debug" filter "configurations:Debug"
symbols "On" symbols "On"
defines {"_DEBUG", "SHEDITOR"} defines {"_DEBUG", "SHEDITOR"}
links{"assimp-vc142-mtd.lib", "librttr_core_d.lib", "spdlogd.lib"} links{"librttr_core_d.lib", "spdlogd.lib"}
links{"fmodstudioL_vc.lib", "fmodL_vc.lib"} links{"fmodstudioL_vc.lib", "fmodL_vc.lib"}
filter "configurations:Release" filter "configurations:Release"
optimize "On" optimize "On"
defines{"_RELEASE", "SHEDITOR"} defines{"_RELEASE", "SHEDITOR"}
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"} links{"librttr_core.lib", "spdlog.lib"}
links{"fmodstudio_vc.lib", "fmod_vc.lib"} links{"fmodstudio_vc.lib", "fmod_vc.lib"}
filter "configurations:Publish" filter "configurations:Publish"
optimize "On" optimize "On"
defines{"_RELEASE", "_PUBLISH"} defines{"_RELEASE", "_PUBLISH"}
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"} links{"librttr_core.lib", "spdlog.lib"}
excludes excludes
{ {
-- "%{prj.location}/src/Editor/**.cpp", -- "%{prj.location}/src/Editor/**.cpp",

View File

@ -1,4 +1,4 @@
#pragma once #pragma once
#include "SHMeshAsset.h" #include "SHModelAsset.h"
#include "SHTextureAsset.h" #include "SHTextureAsset.h"

View File

@ -18,24 +18,31 @@
namespace SHADE namespace SHADE
{ {
struct SH_API SHMeshAssetHeader struct SHMeshAssetHeader
{ {
uint32_t vertexCount; uint32_t vertexCount;
uint32_t indexCount; uint32_t indexCount;
std::string name; std::string name;
}; };
struct SH_API SHMeshAsset : SHAssetData struct SHModelAssetHeader
{ {
bool compiled; size_t meshCount;
bool changed; };
struct SH_API SHMeshData : SHAssetData
{
SHMeshAssetHeader header; SHMeshAssetHeader header;
std::vector<SHVec3> VertexPositions;
std::vector<SHVec3> VertexTangents;
std::vector<SHVec3> VertexNormals;
std::vector<SHVec2> VertexTexCoords;
std::vector<uint32_t> Indices;
};
std::vector<SHVec3> vertexPosition; struct SH_API SHModelAsset : SHAssetData
std::vector<SHVec3> vertexTangent; {
std::vector<SHVec3> vertexNormal; SHModelAssetHeader header;
std::vector<SHVec2> texCoords; std::vector<SHMeshData*> subMeshes;
std::vector<uint32_t> indices;
}; };
} }

View File

@ -1,201 +0,0 @@
/*************************************************************************//**
* \file SHMeshCompiler.cpp
* \author Loh Xiao Qi
* \date 30 September 2022
* \brief Library to write data in SHMeshAsset into binary file for faster
* loading in the future
*
*
* Copyright (C) 2022 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.
*****************************************************************************/
#include "SHpch.h"
#include "SHMeshCompiler.h"
#include "Graphics/MiddleEnd/Meshes/SHMeshData.h"
#include <assimp/postprocess.h>
#include <fstream>
namespace SHADE
{
Assimp::Importer SHMeshCompiler::aiImporter;
void SHMeshCompiler::ProcessNode(aiNode const& node, aiScene const& scene, MeshVectorRef meshes) noexcept
{
for (size_t i{ 0 }; i < node.mNumMeshes; ++i)
{
aiMesh* mesh = scene.mMeshes[node.mMeshes[i]];
meshes.push_back(ProcessMesh(*mesh));
}
for (size_t i{ 0 }; i < node.mNumChildren; ++i)
{
ProcessNode(*node.mChildren[i], scene, meshes);
}
}
void SHMeshCompiler::ExtractAnimations(aiScene const& scene, AnimVectorRef anims) noexcept
{
if (scene.HasAnimations())
{
std::vector<SHAnimationAsset> anims(scene.mNumAnimations);
for (auto i{ 0 }; i < scene.mNumAnimations; ++i)
{
auto const& anim{ *scene.mAnimations[i] };
anims[i].name = anim.mName.C_Str();
anims[i].duration = anim.mDuration;
anims[i].ticksPerSecond = anim.mTicksPerSecond;
std::copy_n(anim.mChannels, anim.mNumChannels, anims[i].nodeChannels.data());
std::copy_n(anim.mMeshChannels, anim.mNumMeshChannels, anims[i].meshChannels.data());
std::copy_n(anim.mMorphMeshChannels, anim.mNumMorphMeshChannels, anims[i].morphMeshChannels.data());
}
}
}
SHMeshAsset* SHMeshCompiler::ProcessMesh(aiMesh const& mesh) noexcept
{
SHMeshAsset* result = new SHMeshAsset();
result->compiled = false;
result->changed = false;
for (size_t i{ 0 }; i < mesh.mNumVertices; ++i)
{
// Vertex position
SHVec3 vertex;
vertex.x = mesh.mVertices[i].x;
vertex.y = mesh.mVertices[i].y;
vertex.z = mesh.mVertices[i].z;
result->vertexPosition.push_back(vertex);
// Tex coords
SHVec2 texCoord{ 0.f, 0.f };
if (mesh.mTextureCoords[0])
{
texCoord.x = mesh.mTextureCoords[0][i].x;
texCoord.y = mesh.mTextureCoords[0][i].y;
}
result->texCoords.push_back(texCoord);
// Normals
SHVec3 normal{ 0.f, 0.f, 0.f };
if (mesh.mNormals)
{
normal.x = mesh.mNormals[i].x;
normal.y = mesh.mNormals[i].y;
normal.z = mesh.mNormals[i].z;
}
result->vertexNormal.push_back(normal);
// Tangent
SHVec3 tangent{ 0.f, 0.f, 0.f };
if (mesh.mTangents)
{
tangent.x = mesh.mTangents[i].x;
tangent.y = mesh.mTangents[i].y;
tangent.z = mesh.mTangents[i].z;
}
result->vertexTangent.push_back(tangent);
}
for (size_t i{ 0 }; i < mesh.mNumFaces; ++i)
{
aiFace face = mesh.mFaces[i];
for (size_t j{ 0 }; j < face.mNumIndices; ++j)
{
result->indices.push_back(face.mIndices[j]);
}
}
result->header.vertexCount = static_cast<uint32_t>(result->vertexPosition.size());
result->header.indexCount = static_cast<uint32_t>(result->indices.size());
result->header.name = mesh.mName.C_Str();
return result;
}
void SHMeshCompiler::LoadFromFile(AssetPath path, MeshVectorRef meshes, AnimVectorRef anims) noexcept
{
const aiScene* scene = aiImporter.ReadFile(path.string().c_str(),
aiProcess_Triangulate // Make sure we get triangles rather than nvert polygons
| aiProcess_GenUVCoords // Convert any type of mapping to uv mapping
| aiProcess_TransformUVCoords // preprocess UV transformations (scaling, translation ...)
| aiProcess_FindInstances // search for instanced meshes and remove them by references to one master
| aiProcess_CalcTangentSpace // calculate tangents and bitangents if possible
| aiProcess_JoinIdenticalVertices // join identical vertices/ optimize indexing
| aiProcess_RemoveRedundantMaterials // remove redundant materials
| aiProcess_FindInvalidData // detect invalid model data, such as invalid normal vectors
| aiProcess_FlipUVs // flip the V to match the Vulkans way of doing UVs
);
if (!scene || !scene->HasMeshes())
{
SHLOG_ERROR("ERROR in GLTF::ASSIMP: {}\nFile: {}", aiImporter.GetErrorString(), path.string());
return;
}
//ExtractAnimations(*scene, anims);
ProcessNode(*scene->mRootNode, *scene, meshes);
aiImporter.FreeScene();
}
std::optional<AssetPath> SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept
{
std::string newPath{ path.parent_path().string() + '/' };
newPath += asset.header.name + MESH_EXTENSION.data();
std::ofstream file{ newPath, std::ios::out | std::ios::binary | std::ios::trunc };
if (!file.is_open())
{
SHLOG_ERROR("Unable to open file for writing mesh file: {}", path.string());
}
file.write(
reinterpret_cast<char const*>(&(asset.header.vertexCount)),
sizeof(uint32_t)
);
file.write(
reinterpret_cast<const char*>(&(asset.header.indexCount)),
sizeof(uint32_t)
);
auto const vertexVec3Byte{ sizeof(SHVec3) * asset.header.vertexCount };
auto const vertexVec2Byte{ sizeof(SHVec2) * asset.header.vertexCount };
file.write(
reinterpret_cast<char const*>(asset.vertexPosition.data()),
vertexVec3Byte
);
file.write(
reinterpret_cast<char const*>(asset.vertexTangent.data()),
vertexVec3Byte
);
file.write(
reinterpret_cast<char const*>(asset.vertexNormal.data()),
vertexVec3Byte
);
file.write(
reinterpret_cast<char const*>(asset.texCoords.data()),
vertexVec2Byte
);
file.write(
reinterpret_cast<char const*>(asset.indices.data()),
sizeof(uint32_t) * asset.header.indexCount
);
file.close();
return newPath;
}
}

View File

@ -1,40 +0,0 @@
/*************************************************************************//**
* \file SHMeshCompiler.h
* \author Loh Xiao Qi
* \date 30 September 2022
* \brief Library to write data in SHMeshAsset into binary file for faster
* loading in the future
*
*
* Copyright (C) 2022 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.
*****************************************************************************/
#pragma once
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <vector>
#include "Assets/Asset Types/SHAnimationAsset.h"
#include "Assets/Asset Types/SHMeshAsset.h"
#include "Assets/SHAssetMacros.h"
namespace SHADE
{
class SHMeshCompiler
{
using MeshVectorRef = std::vector<SHMeshAsset*>&;
using AnimVectorRef = std::vector<SHAnimationAsset*>&;
static Assimp::Importer aiImporter;
static void ProcessNode(aiNode const& node, aiScene const& scene, MeshVectorRef meshes) noexcept;
static void ExtractAnimations(aiScene const& scene, AnimVectorRef anims) noexcept;
static SHMeshAsset* ProcessMesh(aiMesh const& mesh) noexcept;
public:
static void LoadFromFile(AssetPath path, MeshVectorRef meshes, AnimVectorRef anims) noexcept;
static std::optional<AssetPath> CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept;
};
}

View File

@ -1,130 +0,0 @@
/*************************************************************************//**
* \file SHMeshLoader.cpp
* \author Loh Xiao Qi
* \date 30 September 2022
* \brief Implementation for Mesh loader. Accounts for custom binary format
* as well as GLTF file format.
*
*
* Copyright (C) 2022 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.
*****************************************************************************/
#include "SHpch.h"
#include "SHMeshLoader.h"
#include <fstream>
namespace SHADE
{
void SHMeshLoader::LoadSHMesh(AssetPath path, SHMeshAsset& mesh) noexcept
{
std::ifstream file{ path.string(), std::ios::in | std::ios::binary };
if (!file.is_open())
{
SHLOG_ERROR("Unable to open SHMesh File: {}", path.string());
return;
}
const std::string name{ path.stem().string() };
file.seekg(0);
uint32_t vertCount, indexCount;
std::vector<SHVec3> vertPos, vertTan, vertNorm;
std::vector<SHVec2> texCoord;
std::vector<uint32_t> indices;
file.read(reinterpret_cast<char*>(&vertCount), sizeof(uint32_t));
file.read(reinterpret_cast<char*>(&indexCount), sizeof(uint32_t));
auto const vertexVec3Byte{ sizeof(SHVec3) * vertCount };
auto const vertexVec2Byte{ sizeof(SHVec2) * vertCount };
vertPos.resize(vertCount);
vertTan.resize(vertCount);
vertNorm.resize(vertCount);
texCoord.resize(vertCount);
indices.resize(indexCount);
file.read(reinterpret_cast<char *>(vertPos.data()), vertexVec3Byte);
file.read(reinterpret_cast<char *>(vertTan.data()), vertexVec3Byte);
file.read(reinterpret_cast<char *>(vertNorm.data()), vertexVec3Byte);
file.read(reinterpret_cast<char *>(texCoord.data()), vertexVec2Byte);
file.read(reinterpret_cast<char *>(indices.data()), sizeof(uint32_t) * indexCount);
mesh.compiled = true;
mesh.changed = false;
mesh.header.indexCount = indexCount;
mesh.header.vertexCount = vertCount;
mesh.header.name = name;
mesh.vertexPosition = std::move(vertPos);
mesh.vertexTangent = std::move(vertTan);
mesh.vertexNormal = std::move(vertNorm);
mesh.texCoords = std::move(texCoord);
mesh.indices = std::move(indices);
file.close();
}
SHAssetData* SHMeshLoader::Load(AssetPath path)
{
auto result = new SHMeshAsset();
LoadSHMesh(path, *result);
return result;
}
void SHMeshLoader::Write(SHAssetData const* data, AssetPath path)
{
std::ofstream file{ path, std::ios::out | std::ios::binary | std::ios::trunc };
if (!file.is_open())
{
SHLOG_ERROR("Unable to open file for writing mesh file: {}", path.string());
}
auto asset = *dynamic_cast<SHMeshAsset const*>(data);
file.write(
reinterpret_cast<char const*>(&(asset.header.vertexCount)),
sizeof(uint32_t)
);
file.write(
reinterpret_cast<const char*>(&(asset.header.indexCount)),
sizeof(uint32_t)
);
auto const vertexVec3Byte{ sizeof(SHVec3) * asset.header.vertexCount };
auto const vertexVec2Byte{ sizeof(SHVec2) * asset.header.vertexCount };
file.write(
reinterpret_cast<char const*>(asset.vertexPosition.data()),
vertexVec3Byte
);
file.write(
reinterpret_cast<char const*>(asset.vertexTangent.data()),
vertexVec3Byte
);
file.write(
reinterpret_cast<char const*>(asset.vertexNormal.data()),
vertexVec3Byte
);
file.write(
reinterpret_cast<char const*>(asset.texCoords.data()),
vertexVec2Byte
);
file.write(
reinterpret_cast<char const*>(asset.indices.data()),
sizeof(uint32_t) * asset.header.indexCount
);
file.close();
}
}

View File

@ -0,0 +1,91 @@
/*************************************************************************//**
* \file SHModelLoader.cpp
* \author Loh Xiao Qi
* \date 30 September 2022
* \brief Implementation for Mesh loader. Accounts for custom binary format
* as well as GLTF file format.
*
*
* Copyright (C) 2022 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.
*****************************************************************************/
#include "SHpch.h"
#include "SHModelLoader.h"
#include <fstream>
namespace SHADE
{
void SHModelLoader::ReadHeader(std::ifstream& file, SHMeshLoaderHeader& header) noexcept
{
file.read(
reinterpret_cast<char*>(&header),
sizeof(SHMeshLoaderHeader)
);
}
void SHModelLoader::ReadData(std::ifstream& file, SHMeshLoaderHeader const& header, SHMeshData& data) noexcept
{
auto const vertexVec3Byte{ sizeof(SHVec3) * header.vertexCount };
auto const vertexVec2Byte{ sizeof(SHVec2) * header.vertexCount };
data.VertexPositions.resize(header.vertexCount);
data.VertexTangents.resize(header.vertexCount);
data.VertexNormals.resize(header.vertexCount);
data.VertexTexCoords.resize(header.vertexCount);
data.Indices.resize(header.indexCount);
data.header.name.resize(header.charCount);
file.read(data.header.name.data(), header.charCount);
file.read(reinterpret_cast<char*>(data.VertexPositions.data()), vertexVec3Byte);
file.read(reinterpret_cast<char*>(data.VertexTangents.data()), vertexVec3Byte);
file.read(reinterpret_cast<char*>(data.VertexNormals.data()), vertexVec3Byte);
file.read(reinterpret_cast<char*>(data.VertexTexCoords.data()), vertexVec2Byte);
file.read(reinterpret_cast<char*>(data.Indices.data()), sizeof(uint32_t) * header.indexCount);
data.header.vertexCount = header.vertexCount;
data.header.indexCount = header.indexCount;
}
void SHModelLoader::LoadSHMesh(AssetPath path, SHModelAsset& model) noexcept
{
std::ifstream file{ path.string(), std::ios::in | std::ios::binary };
if (!file.is_open())
{
SHLOG_ERROR("Unable to open SHMesh File: {}", path.string());
return;
}
file.seekg(0);
file.read(
reinterpret_cast<char*>(&model.header),
sizeof(SHModelAssetHeader)
);
std::vector<SHMeshLoaderHeader> headers(model.header.meshCount);
model.subMeshes.resize(model.header.meshCount);
for (auto i{ 0 }; i < model.header.meshCount; ++i)
{
model.subMeshes[i] = new SHMeshData();
ReadHeader(file, headers[i]);
ReadData(file, headers[i], *model.subMeshes[i]);
}
file.close();
}
SHAssetData* SHModelLoader::Load(AssetPath path)
{
auto result = new SHModelAsset();
LoadSHMesh(path, *result);
return result;
}
void SHModelLoader::Write(SHAssetData const* data, AssetPath path)
{
}
}

View File

@ -1,5 +1,5 @@
/*************************************************************************//** /*************************************************************************//**
* \file SHMeshLoader.h * \file SHModelLoader.h
* \author Loh Xiao Qi * \author Loh Xiao Qi
* \date 30 September 2022 * \date 30 September 2022
* \brief Library to load gltf mesh files and custom binary format * \brief Library to load gltf mesh files and custom binary format
@ -10,14 +10,27 @@
* of DigiPen Institute of Technology is prohibited. * of DigiPen Institute of Technology is prohibited.
*****************************************************************************/ *****************************************************************************/
#pragma once #pragma once
#include "Assets/Asset Types/SHMeshAsset.h" #include "Assets/Asset Types/SHModelAsset.h"
#include "SHAssetLoader.h" #include "SHAssetLoader.h"
#include <fstream>
namespace SHADE namespace SHADE
{ {
struct SHMeshLoader : SHAssetLoader class SHModelLoader : public SHAssetLoader
{ {
void LoadSHMesh(AssetPath path, SHMeshAsset& meshes) noexcept; struct SHMeshLoaderHeader
{
uint32_t vertexCount;
uint32_t indexCount;
uint32_t charCount;
};
void ReadHeader(std::ifstream& file, SHMeshLoaderHeader& header) noexcept;
void ReadData(std::ifstream& file, SHMeshLoaderHeader const& header, SHMeshData& data) noexcept;
public:
void LoadSHMesh(AssetPath path, SHModelAsset& model) noexcept;
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;
}; };

View File

@ -22,5 +22,10 @@ namespace SHADE
AssetID id; AssetID id;
AssetType type; AssetType type;
AssetPath path; AssetPath path;
bool isSubAsset;
std::vector<SHAsset*> subAssets;
AssetID parent;
}; };
} }

View File

@ -47,10 +47,11 @@ enum class AssetType : AssetTypeMeta
SHADER, SHADER,
SHADER_BUILT_IN, SHADER_BUILT_IN,
TEXTURE, TEXTURE,
MESH, MODEL,
SCENE, SCENE,
PREFAB, PREFAB,
MATERIAL, MATERIAL,
MESH,
MAX_COUNT MAX_COUNT
}; };
constexpr size_t TYPE_COUNT{ static_cast<size_t>(AssetType::MAX_COUNT) }; constexpr size_t TYPE_COUNT{ static_cast<size_t>(AssetType::MAX_COUNT) };
@ -64,6 +65,9 @@ constexpr std::string_view ASSET_ROOT {"../../Assets"};
constexpr std::string_view BUILT_IN_ASSET_ROOT{ "../../Built_In" }; constexpr std::string_view BUILT_IN_ASSET_ROOT{ "../../Built_In" };
#endif #endif
// COMPILER PATHS
constexpr std::string_view MODEL_COMPILER_EXE{ "ModelCompiler.exe" };
// INTERNAL ASSET PATHS // INTERNAL ASSET PATHS
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/" };
@ -81,7 +85,7 @@ constexpr std::string_view SCENE_EXTENSION {".shade"};
constexpr std::string_view PREFAB_EXTENSION {".shprefab"}; 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 MESH_EXTENSION {".shmesh"}; constexpr std::string_view MODEL_EXTENSION {".shmodel"};
constexpr std::string_view EXTENSIONS[] = { constexpr std::string_view EXTENSIONS[] = {
AUDIO_EXTENSION, AUDIO_EXTENSION,
@ -89,7 +93,7 @@ constexpr std::string_view EXTENSIONS[] = {
SHADER_BUILT_IN_EXTENSION, SHADER_BUILT_IN_EXTENSION,
MATERIAL_EXTENSION, MATERIAL_EXTENSION,
TEXTURE_EXTENSION, TEXTURE_EXTENSION,
MESH_EXTENSION, MODEL_EXTENSION,
SCRIPT_EXTENSION, SCRIPT_EXTENSION,
SCENE_EXTENSION, SCENE_EXTENSION,
PREFAB_EXTENSION, PREFAB_EXTENSION,

View File

@ -11,15 +11,17 @@
#include <random> #include <random>
#include <chrono> #include <chrono>
#include <ranges> #include <ranges>
#include <cstdlib>
#include "SHAssetManager.h" #include "SHAssetManager.h"
#include "SHAssetMetaHandler.h" #include "SHAssetMetaHandler.h"
#include "Libraries/Loaders/SHMeshLoader.h" #include "Libraries/Loaders/SHModelLoader.h"
#include "Libraries/Loaders/SHTextureLoader.h" #include "Libraries/Loaders/SHTextureLoader.h"
#include "Libraries/Loaders/SHShaderSourceLoader.h" #include "Libraries/Loaders/SHShaderSourceLoader.h"
#include "Libraries/Loaders/SHTextBasedLoader.h" #include "Libraries/Loaders/SHTextBasedLoader.h"
#include "Libraries/Compilers/SHMeshCompiler.h" //#include "Libraries/Compilers/SHMeshCompiler.h"
#include "Libraries/Compilers/SHTextureCompiler.h" #include "Libraries/Compilers/SHTextureCompiler.h"
#include "Libraries/Compilers/SHShaderSourceCompiler.h" #include "Libraries/Compilers/SHShaderSourceCompiler.h"
@ -186,7 +188,8 @@ namespace SHADE
name, name,
id, id,
type, type,
newPath newPath,
false
}; };
assetCollection.insert({ assetCollection.insert({
@ -195,7 +198,8 @@ namespace SHADE
name, name,
id, id,
type, type,
newPath newPath,
false
) )
}); });
@ -334,25 +338,32 @@ namespace SHADE
return result; return result;
} }
AssetID SHAssetManager::CompileAsset(AssetPath const& path) noexcept void SHAssetManager::CompileAsset(AssetPath const& path) noexcept
{ {
SHAsset newAsset if (!std::filesystem::exists(path))
{ {
.name = path.stem().string() SHLOG_ERROR("Path provided does not point to a file: {}", path.string());
}; return;
}
AssetPath newPath;
auto const ext{ path.extension().string() }; auto const ext{ path.extension().string() };
if (ext == GLSL_EXTENSION.data()) if (ext == GLSL_EXTENSION.data())
{ {
newAsset.path = SHShaderSourceCompiler::LoadAndCompileShader(path).value(); newPath = SHShaderSourceCompiler::LoadAndCompileShader(path).value();
newAsset.id = GenerateAssetID(AssetType::SHADER_BUILT_IN); }
newAsset.type = AssetType::SHADER_BUILT_IN; else if (ext == GLTF_EXTENSION.data() || ext == FBX_EXTENSION.data())
{
std::string command = MODEL_COMPILER_EXE.data();
command += " " + path.string();
std::system(command.c_str());
std::string modelPath = path.string().substr(0, path.string().find_last_of('.'));
modelPath += MODEL_EXTENSION;
newPath = modelPath;
GenerateNewMeta(newPath);
} }
assetCollection.insert({ newAsset.id, newAsset });
SHAssetMetaHandler::WriteMetaData(newAsset);
return newAsset.id;
} }
FolderPointer SHAssetManager::GetRootFolder() noexcept FolderPointer SHAssetManager::GetRootFolder() noexcept
@ -405,46 +416,28 @@ namespace SHADE
for (auto const& path : paths) for (auto const& path : paths)
{ {
SHAsset newAsset AssetPath newPath;
{
.name = path.stem().string()
};
auto const ext{ path.extension().string() }; auto const ext{ path.extension().string() };
if (ext == GLSL_EXTENSION.data()) if (ext == GLSL_EXTENSION.data())
{ {
newAsset.path = SHShaderSourceCompiler::LoadAndCompileShader(path).value(); newPath = SHShaderSourceCompiler::LoadAndCompileShader(path).value();
newAsset.id = GenerateAssetID(AssetType::SHADER_BUILT_IN);
newAsset.type = AssetType::SHADER_BUILT_IN;
} }
else if (ext == DDS_EXTENSION.data()) else if (ext == DDS_EXTENSION.data())
{ {
newAsset.path = SHTextureCompiler::CompileTextureAsset(path).value(); newPath = SHTextureCompiler::CompileTextureAsset(path).value();
newAsset.id = GenerateAssetID(AssetType::TEXTURE);
newAsset.type = AssetType::TEXTURE;
} }
else if (ext == GLTF_EXTENSION.data() || ext == FBX_EXTENSION.data()) else if (ext == GLTF_EXTENSION.data() || ext == FBX_EXTENSION.data())
{ {
std::vector<SHMeshAsset*> meshes; std::string command = MODEL_COMPILER_EXE.data();
std::vector<SHAnimationAsset*> anims; command += " " + path.string();
SHMeshCompiler::LoadFromFile(path, meshes, anims); std::system(command.c_str());
for (auto const& mesh : meshes) std::string modelPath = path.string().substr(0, path.string().find_last_of('.'));
{ modelPath += MODEL_EXTENSION;
SHAsset meshAsset{ newPath = modelPath;
.name = mesh->header.name
};
meshAsset.path = SHMeshCompiler::CompileMeshBinary(*mesh, path).value();
meshAsset.id = GenerateAssetID(AssetType::MESH);
meshAsset.type = AssetType::MESH;
assetCollection.insert({ meshAsset.id, meshAsset });
SHAssetMetaHandler::WriteMetaData(meshAsset);
}
continue;
} }
assetCollection.insert({ newAsset.id, newAsset }); GenerateNewMeta(newPath);
SHAssetMetaHandler::WriteMetaData(newAsset);
} }
} }
@ -459,10 +452,11 @@ namespace SHADE
loaders[static_cast<size_t>(AssetType::SHADER)] = dynamic_cast<SHAssetLoader*>(new SHShaderSourceLoader()); loaders[static_cast<size_t>(AssetType::SHADER)] = dynamic_cast<SHAssetLoader*>(new SHShaderSourceLoader());
loaders[static_cast<size_t>(AssetType::SHADER_BUILT_IN)] = loaders[static_cast<size_t>(AssetType::SHADER)]; loaders[static_cast<size_t>(AssetType::SHADER_BUILT_IN)] = loaders[static_cast<size_t>(AssetType::SHADER)];
loaders[static_cast<size_t>(AssetType::TEXTURE)] = dynamic_cast<SHAssetLoader*>(new SHTextureLoader()); loaders[static_cast<size_t>(AssetType::TEXTURE)] = dynamic_cast<SHAssetLoader*>(new SHTextureLoader());
loaders[static_cast<size_t>(AssetType::MESH)] = dynamic_cast<SHAssetLoader*>(new SHMeshLoader()); loaders[static_cast<size_t>(AssetType::MODEL)] = dynamic_cast<SHAssetLoader*>(new SHModelLoader());
loaders[static_cast<size_t>(AssetType::SCENE)] = dynamic_cast<SHAssetLoader*>(new SHTextBasedLoader()); loaders[static_cast<size_t>(AssetType::SCENE)] = dynamic_cast<SHAssetLoader*>(new SHTextBasedLoader());
loaders[static_cast<size_t>(AssetType::PREFAB)] = loaders[static_cast<size_t>(AssetType::SCENE)]; loaders[static_cast<size_t>(AssetType::PREFAB)] = loaders[static_cast<size_t>(AssetType::SCENE)];
loaders[static_cast<size_t>(AssetType::MATERIAL)] = loaders[static_cast<size_t>(AssetType::SCENE)]; loaders[static_cast<size_t>(AssetType::MATERIAL)] = loaders[static_cast<size_t>(AssetType::SCENE)];
loaders[static_cast<size_t>(AssetType::MESH)] = nullptr;
} }
/**************************************************************************** /****************************************************************************
@ -470,9 +464,9 @@ namespace SHADE
****************************************************************************/ ****************************************************************************/
void SHAssetManager::Load() noexcept void SHAssetManager::Load() noexcept
{ {
//CompileAll();
BuildAssetCollection(); BuildAssetCollection();
InitLoaders(); InitLoaders();
//CompileAll();
//LoadAllData(); //LoadAllData();
} }
@ -490,8 +484,12 @@ namespace SHADE
SHAssetData* SHAssetManager::LoadData(SHAsset const& asset) noexcept SHAssetData* SHAssetManager::LoadData(SHAsset const& asset) noexcept
{ {
SHAssetData* data = loaders[static_cast<size_t>(asset.type)]->Load(asset.path); if (asset.isSubAsset)
{
return LoadSubData(asset);
}
SHAssetData* data = loaders[static_cast<size_t>(asset.type)]->Load(asset.path);
if (data == nullptr) if (data == nullptr)
{ {
SHLOG_ERROR("Unable to load asset into memory: {}\n", asset.path.string()); SHLOG_ERROR("Unable to load asset into memory: {}\n", asset.path.string());
@ -504,8 +502,120 @@ namespace SHADE
return data; return data;
} }
SHAssetData* SHAssetManager::LoadSubData(SHAsset const& asset) noexcept
{
auto const& parent = assetCollection[asset.parent];
auto parentData = loaders[static_cast<size_t>(parent.type)]->Load(parent.path);
if (parentData == nullptr)
{
SHLOG_ERROR("Unable to load asset into memory: {}\n", parent.path.string());
}
else
{
assetData.emplace(parent.id, parentData);
if (parent.type == AssetType::MODEL)
{
auto parentModel = reinterpret_cast<SHModelAsset*>(parentData);
for (auto i {0}; i < parent.subAssets.size(); ++i)
{
assetData.emplace(
parent.subAssets[i]->id,
parentModel->subMeshes[i]
);
}
}
return assetData[asset.id];
}
return parentData;
}
void SHAssetManager::LoadNewData(AssetPath path) noexcept
{
}
void SHAssetManager::GenerateNewMeta(AssetPath path) noexcept
{
auto const ext = path.extension().string();
if (ext == SHADER_BUILT_IN_EXTENSION.data())
{
SHAsset newAsset{
path.stem().string(),
GenerateAssetID(AssetType::SHADER_BUILT_IN),
AssetType::SHADER_BUILT_IN,
path,
false
};
assetCollection.emplace(newAsset.id, newAsset);
SHAssetMetaHandler::WriteMetaData(newAsset);
}
else if (ext == TEXTURE_EXTENSION.data())
{
SHAsset newAsset{
path.stem().string(),
GenerateAssetID(AssetType::SHADER_BUILT_IN),
AssetType::SHADER_BUILT_IN,
path,
false
};
assetCollection.emplace(newAsset.id, newAsset);
SHAssetMetaHandler::WriteMetaData(newAsset);
}
else if (ext == MODEL_EXTENSION)
{
SHAsset newAsset{
path.stem().string(),
GenerateAssetID(AssetType::MODEL),
AssetType::MODEL,
path,
false
};
assetCollection.emplace(newAsset.id, newAsset);
SHModelAsset* const data = reinterpret_cast<SHModelAsset*>(LoadData(newAsset));
assetData.emplace(newAsset.id, data);
for(auto const& subMesh : data->subMeshes)
{
SHAsset subAsset{
.name = subMesh->header.name,
.id = GenerateAssetID(AssetType::MESH),
.type = AssetType::MESH,
.isSubAsset = true,
.parent = newAsset.id
};
assetCollection.emplace(subAsset.id, subAsset);
assetCollection[newAsset.id].subAssets.push_back(&assetCollection[subAsset.id]);
assetData.emplace(subAsset.id, subMesh);
}
SHAssetMetaHandler::WriteMetaData(assetCollection[newAsset.id]);
}
}
void SHAssetManager::BuildAssetCollection() noexcept void SHAssetManager::BuildAssetCollection() noexcept
{ {
SHFileSystem::BuildDirectory(ASSET_ROOT.data(), folderRoot, assetCollection); SHFileSystem::BuildDirectory(ASSET_ROOT.data(), folderRoot, assetCollection);
for (auto& asset : std::ranges::views::values(assetCollection))
{
if (!asset.subAssets.empty())
{
// Add subasset data into map, replace pointer and free heap memory
for (auto i{ 0 }; i < asset.subAssets.size(); ++i)
{
auto const id = asset.subAssets[i]->id;
assetCollection[id] = *asset.subAssets[i];
delete asset.subAssets[i];
asset.subAssets[i] = &assetCollection[id];
}
}
}
} }
} }

View File

@ -87,7 +87,7 @@ namespace SHADE
static std::vector<SHAssetData const*> GetAllDataOfType(AssetType type) noexcept; static std::vector<SHAssetData const*> GetAllDataOfType(AssetType type) noexcept;
static std::vector<SHAsset> GetAllRecordOfType(AssetType type) noexcept; static std::vector<SHAsset> GetAllRecordOfType(AssetType type) noexcept;
static AssetID CompileAsset(AssetPath const& path) noexcept; static void CompileAsset(AssetPath const& path) noexcept;
static FolderPointer GetRootFolder() noexcept; static FolderPointer GetRootFolder() noexcept;
@ -96,6 +96,10 @@ namespace SHADE
static void InitLoaders() noexcept; static void InitLoaders() noexcept;
static void LoadAllData() noexcept; static void LoadAllData() noexcept;
static SHAssetData* LoadData(SHAsset const& asset) noexcept; static SHAssetData* LoadData(SHAsset const& asset) noexcept;
static SHAssetData* LoadSubData(SHAsset const& asset) noexcept;
static void LoadNewData(AssetPath path) noexcept;
static void GenerateNewMeta(AssetPath path) noexcept;
inline static void BuildAssetCollection() noexcept; inline static void BuildAssetCollection() noexcept;
static bool IsRecognised(char const*) noexcept; static bool IsRecognised(char const*) noexcept;

View File

@ -9,7 +9,6 @@
******************************************************************************/ ******************************************************************************/
#include "SHpch.h" #include "SHpch.h"
#include "SHAssetMetaHandler.h" #include "SHAssetMetaHandler.h"
#include <fstream>
#include <sstream> #include <sstream>
namespace SHADE namespace SHADE
@ -21,11 +20,15 @@ namespace SHADE
* \brief Helper function to retrieve field value from meta data file * \brief Helper function to retrieve field value from meta data file
* for processing * for processing
****************************************************************************/ ****************************************************************************/
void GetFieldValue(std::ifstream& file, std::string& line) noexcept bool GetFieldValue(std::ifstream& file, std::string& line) noexcept
{ {
line = ""; line = "";
std::getline(file, line); if (std::getline(file, line))
{
line = line.substr(line.find_last_of(':') + 2, line.length()); line = line.substr(line.find_last_of(':') + 2, line.length());
return true;
}
return false;
} }
/**************************************************************************** /****************************************************************************
@ -66,7 +69,8 @@ namespace SHADE
std::ifstream metaFile{ path.string(), std::ios_base::in }; std::ifstream metaFile{ path.string(), std::ios_base::in };
if (!metaFile.is_open()) if (!metaFile.is_open())
{ {
// Error unable to open SHLOG_ERROR("Unable to open meta file: {}", path.string());
return {};
} }
std::string line; std::string line;
@ -93,6 +97,43 @@ namespace SHADE
typeStream >> type; typeStream >> type;
meta.type = static_cast<AssetType>(type); meta.type = static_cast<AssetType>(type);
meta.isSubAsset = false;
// Burn Line
if (std::getline(metaFile, line))
{
// Name Line
while(GetFieldValue(metaFile, line))
{
auto subAsset = new SHAsset();
// Get resource name
std::stringstream nameStream{ line };
AssetName name;
nameStream >> name;
subAsset->name = name;
// Get resource id
GetFieldValue(metaFile, line);
std::stringstream idStream{ line };
AssetID id;
idStream >> id;
subAsset->id = id;
// Get resource type
GetFieldValue(metaFile, line);
std::stringstream typeStream{ line };
AssetTypeMeta type;
typeStream >> type;
subAsset->type = static_cast<AssetType>(type);
subAsset->isSubAsset = true;
subAsset->parent = meta.id;
meta.subAssets.push_back(subAsset);
}
}
metaFile.close(); metaFile.close();
meta.path = path.parent_path().string() + "/" + path.stem().string(); meta.path = path.parent_path().string() + "/" + path.stem().string();
@ -108,6 +149,12 @@ namespace SHADE
****************************************************************************/ ****************************************************************************/
void SHAssetMetaHandler::WriteMetaData(SHAsset const& meta) noexcept void SHAssetMetaHandler::WriteMetaData(SHAsset const& meta) noexcept
{ {
if (meta.isSubAsset)
{
SHLOG_WARNING("Cannot write subasset meta: {}", meta.name);
return;
}
//TODO: Write into binary eventually //TODO: Write into binary eventually
std::string path{ meta.path.string() }; std::string path{ meta.path.string() };
path.append(META_EXTENSION); path.append(META_EXTENSION);
@ -124,7 +171,23 @@ namespace SHADE
metaFile << "ID: " << meta.id << "\n"; metaFile << "ID: " << meta.id << "\n";
metaFile << "Type: " << static_cast<AssetTypeMeta>(meta.type) << std::endl; metaFile << "Type: " << static_cast<AssetTypeMeta>(meta.type) << std::endl;
if (!meta.subAssets.empty())
{
metaFile << "Sub Assets:\n";
for (auto const& subAsset : meta.subAssets)
{
WriteSubAssetMeta(metaFile, *subAsset);
}
}
metaFile.close(); metaFile.close();
} }
void SHAssetMetaHandler::WriteSubAssetMeta(std::ofstream& metaFile, SHAsset const& subAsset) noexcept
{
metaFile << "Name: " << subAsset.name << "\n";
metaFile << "ID: " << subAsset.id << "\n";
metaFile << "Type: " << static_cast<AssetTypeMeta>(subAsset.type) << std::endl;
}
} }

View File

@ -12,6 +12,7 @@
#include "SHAssetMacros.h" #include "SHAssetMacros.h"
#include "SHAsset.h" #include "SHAsset.h"
#include <fstream>
namespace SHADE namespace SHADE
{ {
@ -45,6 +46,8 @@ namespace SHADE
* \brief Writes meta data into text file * \brief Writes meta data into text file
****************************************************************************/ ****************************************************************************/
static void WriteMetaData(SHAsset const&) noexcept; static void WriteMetaData(SHAsset const&) noexcept;
static void WriteSubAssetMeta(std::ofstream&, SHAsset const&) noexcept;
}; };
} }

View File

@ -108,6 +108,12 @@ namespace SHADE
} }
} }
if(ImGui::IsWindowHovered() && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
{
ParentSelectedEntities(MAX_EID, draggingEntities);
draggingEntities.clear();
ImGui::ClearDragDrop();
}
ImGui::End(); ImGui::End();
} }
@ -195,7 +201,7 @@ namespace SHADE
if (SHDragDrop::BeginSource()) if (SHDragDrop::BeginSource())
{ {
std::string moveLabel = "Moving EID: "; std::string moveLabel = "Moving EID: ";
static std::vector<EntityID> draggingEntities = editor->selectedEntities; draggingEntities = editor->selectedEntities;
if (!isSelected) if (!isSelected)
{ {
draggingEntities.clear(); draggingEntities.clear();
@ -217,7 +223,8 @@ namespace SHADE
{ {
if (const std::vector<EntityID>* eidPayload = SHDragDrop::AcceptPayload<std::vector<EntityID>>(SHDragDrop::DRAG_EID)) //If payload is valid if (const std::vector<EntityID>* eidPayload = SHDragDrop::AcceptPayload<std::vector<EntityID>>(SHDragDrop::DRAG_EID)) //If payload is valid
{ {
ParentSelectedEntities(eid); ParentSelectedEntities(eid, draggingEntities);
draggingEntities.clear();
SHDragDrop::EndTarget(); SHDragDrop::EndTarget();
} }
} }
@ -255,7 +262,7 @@ namespace SHADE
if ((currentNode->GetParent() != sceneGraph.GetRoot()) && ImGui::Selectable(std::format("{} Unparent Selected", ICON_MD_NORTH_WEST).data())) if ((currentNode->GetParent() != sceneGraph.GetRoot()) && ImGui::Selectable(std::format("{} Unparent Selected", ICON_MD_NORTH_WEST).data()))
{ {
ParentSelectedEntities(MAX_EID); ParentSelectedEntities(MAX_EID, editor->selectedEntities);
} }
ImGui::EndPopup(); ImGui::EndPopup();
} }
@ -323,14 +330,16 @@ namespace SHADE
SHEntityManager::CreateEntity(MAX_EID, "DefaultChild", parentEID); SHEntityManager::CreateEntity(MAX_EID, "DefaultChild", parentEID);
} }
void SHHierarchyPanel::ParentSelectedEntities(EntityID parentEID) const noexcept void SHHierarchyPanel::ParentSelectedEntities(EntityID parentEID, std::vector<EntityID> const& entities) const noexcept
{ {
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
auto const editor = SHSystemManager::GetSystem<SHEditor>(); //auto const editor = SHSystemManager::GetSystem<SHEditor>();
SHEntityParentCommand::EntityParentData entityParentData; SHEntityParentCommand::EntityParentData entityParentData;
std::vector<EntityID> parentedEIDS; std::vector<EntityID> parentedEIDS;
for (auto const& eid : editor->selectedEntities) for (auto const& eid : entities)
{ {
if(eid == parentEID)
continue;
if (sceneGraph.GetChild(eid, parentEID) == nullptr) if (sceneGraph.GetChild(eid, parentEID) == nullptr)
{ {
parentedEIDS.push_back(eid); parentedEIDS.push_back(eid);

View File

@ -28,7 +28,7 @@ namespace SHADE
void DrawMenuBar() const noexcept; void DrawMenuBar() const noexcept;
ImRect RecursivelyDrawEntityNode(SHSceneNode* const); ImRect RecursivelyDrawEntityNode(SHSceneNode* const);
void CreateChildEntity(EntityID parentEID) const noexcept; void CreateChildEntity(EntityID parentEID) const noexcept;
void ParentSelectedEntities(EntityID parentEID) const noexcept; void ParentSelectedEntities(EntityID parentEID, std::vector<EntityID> const& entities) const noexcept;
void SelectRangeOfEntities(EntityID beginEID, EntityID EndEID); void SelectRangeOfEntities(EntityID beginEID, EntityID EndEID);
void SelectAllEntities(); void SelectAllEntities();
void CopySelectedEntities(); void CopySelectedEntities();
@ -37,6 +37,8 @@ namespace SHADE
std::string filter; std::string filter;
bool isAnyNodeSelected = false; bool isAnyNodeSelected = false;
EntityID scrollTo = MAX_EID; EntityID scrollTo = MAX_EID;
std::vector<EntityID> draggingEntities;
};//class SHHierarchyPanel };//class SHHierarchyPanel
//Might move to a different file //Might move to a different file

View File

@ -14,7 +14,7 @@ of DigiPen Institute of Technology is prohibited.
// STL Includes // STL Includes
#include <algorithm> #include <algorithm>
// Project Includes // Project Includes
#include "../Meshes/SHMeshData.h" #include "Assets/Asset Types/SHModelAsset.h"
#include "../Meshes/SHPrimitiveGenerator.h" #include "../Meshes/SHPrimitiveGenerator.h"
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
#include "SHGraphicsSystem.h" #include "SHGraphicsSystem.h"

View File

@ -1,36 +0,0 @@
/************************************************************************************//*!
\file SHPrimitiveGenerator.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Sep 18, 2022
\brief Contains the static class definition of SHPrimitiveGenerator.
Copyright (C) 2022 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.
*//*************************************************************************************/
#pragma once
// STL Includes
#include <vector>
// Project Includes
#include "Math/SHMath.h"
#include "Graphics/MiddleEnd/Interface/SHMeshLibrary.h"
namespace SHADE
{
/*************************************************************************************/
/*!
\brief
Static class that contains functions for generating 3D primitives.
*/
/*************************************************************************************/
struct SHMeshData
{
std::vector<SHMesh::VertexPosition> VertexPositions;
std::vector<SHMesh::VertexTexCoord> VertexTexCoords;
std::vector<SHMesh::VertexTangent> VertexTangents;
std::vector<SHMesh::VertexNormal> VertexNormals;
std::vector<SHMesh::Index> Indices;
};
}

View File

@ -13,7 +13,8 @@ of DigiPen Institute of Technology is prohibited.
// Project Includes // Project Includes
#include "Math/SHMath.h" #include "Math/SHMath.h"
#include "SHMeshData.h" #include "Assets/Asset Types/SHModelAsset.h"
#include "Graphics/MiddleEnd/Interface/SHMeshLibrary.h"
#include "SH_API.h" #include "SH_API.h"
namespace SHADE namespace SHADE

View File

@ -19,7 +19,7 @@ namespace SHADE { class SHMaterial; }
#include "SH_API.h" #include "SH_API.h"
#include "SHResourceLibrary.h" #include "SHResourceLibrary.h"
#include "Assets/SHAssetMacros.h" #include "Assets/SHAssetMacros.h"
#include "Assets/Asset Types/SHMeshAsset.h" #include "Assets/Asset Types/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 "Graphics/Shaders/SHVkShaderModule.h" #include "Graphics/Shaders/SHVkShaderModule.h"
@ -36,7 +36,7 @@ namespace SHADE
/// </summary> /// </summary>
template<typename T = void> template<typename T = void>
struct SHResourceLoader { using AssetType = void; }; struct SHResourceLoader { using AssetType = void; };
template<> struct SHResourceLoader<SHMesh> { using AssetType = SHMeshAsset; }; template<> struct SHResourceLoader<SHMesh> { using AssetType = SHMeshData; };
template<> struct SHResourceLoader<SHTexture> { using AssetType = SHTextureAsset; }; template<> struct SHResourceLoader<SHTexture> { using AssetType = SHTextureAsset; };
template<> struct SHResourceLoader<SHVkShaderModule> { using AssetType = SHShaderAsset; }; template<> struct SHResourceLoader<SHVkShaderModule> { using AssetType = SHShaderAsset; };
template<> struct SHResourceLoader<SHMaterialSpec> { using AssetType = SHMaterialAsset; }; template<> struct SHResourceLoader<SHMaterialSpec> { using AssetType = SHMaterialAsset; };

View File

@ -180,13 +180,13 @@ namespace SHADE
return gfxSystem->AddMesh return gfxSystem->AddMesh
( (
assetData.vertexPosition.size(), assetData.VertexPositions.size(),
assetData.vertexPosition.data(), assetData.VertexPositions.data(),
assetData.texCoords.data(), assetData.VertexTexCoords.data(),
assetData.vertexTangent.data(), assetData.VertexTangents.data(),
assetData.vertexNormal.data(), assetData.VertexNormals.data(),
assetData.indices.size(), assetData.Indices.size(),
assetData.indices.data() assetData.Indices.data()
); );
} }
// Textures // Textures

18
TempScriptsFolder/Item.cs Normal file
View File

@ -0,0 +1,18 @@
using SHADE;
using System;
public class Item : Script
{
public enum ItemCategory
{
LIGHT,
MEDIUM,
HEAVY
}
public ItemCategory currCategory;
public Item(GameObject gameObj) : base(gameObj) { }
protected override void awake()
{
}
}

View File

@ -4,9 +4,10 @@ using static PlayerController;
public class PickAndThrow : Script public class PickAndThrow : Script
{ {
private PlayerController pc; public Vector3 throwForce = new Vector3(100.0f, 200.0f, 100.0f);
public GameObject item; public GameObject item;
public Vector3 throwForce = new Vector3(200.0f, 300.0f, 200.0f); private PlayerController pc;
private Camera cam;
private Transform itemTransform; private Transform itemTransform;
private RigidBody itemRidibody; private RigidBody itemRidibody;
private Transform raccoonHoldLocation; private Transform raccoonHoldLocation;
@ -23,7 +24,22 @@ public class PickAndThrow : Script
Debug.Log("CHILD EMPTY"); Debug.Log("CHILD EMPTY");
else else
raccoonHoldLocation.LocalPosition = new Vector3(0.0f, 1.0f, 0.0f); raccoonHoldLocation.LocalPosition = new Vector3(0.0f, 1.0f, 0.0f);
}
protected override void update()
{
if (cam == null)
cam = GetComponentInChildren<Camera>();
else if (cam != null)
{
Vector3 camerAixs = cam.GetForward();
camerAixs.y = 0;
camerAixs.Normalise();
lastXDir = camerAixs.x;
lastZDir = camerAixs.z;
}
if (item.GetScript<Item>() != null && itemTransform == null && itemRidibody == null)
{
itemTransform = item.GetComponent<Transform>(); itemTransform = item.GetComponent<Transform>();
if (itemTransform == null) if (itemTransform == null)
Debug.Log("Item transform EMPTY"); Debug.Log("Item transform EMPTY");
@ -32,26 +48,6 @@ public class PickAndThrow : Script
if (itemRidibody == null) if (itemRidibody == null)
Debug.Log("Item rb EMPTY"); Debug.Log("Item rb EMPTY");
} }
protected override void update()
{
if (!pc.isMoveKeyPress)
{
if (pc.xAxisMove != 0)
{
lastXDir = pc.xAxisMove;
lastZDir = 0.0f;
}
if (pc.zAxisMove != 0)
{
lastXDir = 0.0f;
lastZDir = pc.zAxisMove;
}
}
else
{
lastXDir = pc.xAxisMove;
lastZDir = pc.zAxisMove;
}
if (pc != null && inRange && !pc.holdItem && Input.GetKey(Input.KeyCode.E)) if (pc != null && inRange && !pc.holdItem && Input.GetKey(Input.KeyCode.E))
pc.holdItem = true; pc.holdItem = true;
@ -66,13 +62,13 @@ public class PickAndThrow : Script
if (Input.GetMouseButtonDown(Input.MouseCode.LeftButton)) if (Input.GetMouseButtonDown(Input.MouseCode.LeftButton))
{ {
pc.holdItem = false; pc.holdItem = false;
inRange = false;
itemRidibody.IsGravityEnabled = true; itemRidibody.IsGravityEnabled = true;
itemRidibody.AddForce(new Vector3(throwForce.x * lastXDir, throwForce.y, throwForce.z * lastZDir)); itemRidibody.AddForce(new Vector3(throwForce.x * lastXDir, throwForce.y, throwForce.z * lastZDir));
itemRidibody.LinearVelocity += pc.rb.LinearVelocity; itemRidibody.LinearVelocity += pc.rb.LinearVelocity;
Debug.Log($"x: {itemRidibody.LinearVelocity.x} z: {itemRidibody.LinearVelocity.z}");
} }
} }
else if(!pc.holdItem) else if(!pc.holdItem && itemRidibody != null)
itemRidibody.IsGravityEnabled = true; itemRidibody.IsGravityEnabled = true;
} }
protected override void onCollisionEnter(CollisionInfo info) protected override void onCollisionEnter(CollisionInfo info)
@ -80,20 +76,21 @@ public class PickAndThrow : Script
} }
protected override void onTriggerEnter(CollisionInfo info) protected override void onTriggerEnter(CollisionInfo info)
{ {
Debug.Log("ENTER"); //Debug.Log("ENTER");
if (info.GameObject == item && !pc.holdItem) if (info.GameObject.GetScript<Item>() != null && !pc.holdItem)
{ {
item = info.GameObject;
inRange = true; inRange = true;
} }
} }
protected override void onTriggerStay(CollisionInfo info) protected override void onTriggerStay(CollisionInfo info)
{ {
Debug.Log("STAY"); //Debug.Log("STAY");
} }
protected override void onTriggerExit(CollisionInfo info) protected override void onTriggerExit(CollisionInfo info)
{ {
Debug.Log("EXIT"); //Debug.Log("EXIT");
if (info.GameObject == item && !pc.holdItem) if (info.GameObject.GetScript<Item>() != null && !pc.holdItem)
{ {
inRange = false; inRange = false;
} }

View File

@ -1,7 +1,6 @@
using SHADE; using SHADE;
using System; using System;
using static Item;
//in air controls?
public class PlayerController : Script public class PlayerController : Script
{ {
@ -19,6 +18,7 @@ public class PlayerController : Script
public RigidBody rb; public RigidBody rb;
private Transform tranform; private Transform tranform;
private Camera cam; private Camera cam;
private PickAndThrow pat;
//to be remove //to be remove
public float drag = 2.0f; public float drag = 2.0f;
@ -68,13 +68,24 @@ public class PlayerController : Script
private float gravity = -9.8f; private float gravity = -9.8f;
private float groundGravity = -0.5f; private float groundGravity = -0.5f;
//ItemMultipler==================================================================
public float lightMultiper = 0.75f;
public float mediumMultiper = 0.5f;
public float heavyMultiper = 0.25f;
public PlayerController(GameObject gameObj) : base(gameObj) { } public PlayerController(GameObject gameObj) : base(gameObj) { }
protected override void awake() protected override void awake()
{ {
//default setup
isMoveKeyPress = false; isMoveKeyPress = false;
holdItem = false; holdItem = false;
//Jump setup
float timeToApex = maxJumpTime / 2;
gravity = (-2 * maxJumpHeight) / MathF.Pow(timeToApex, 2);
initialJumpVel = (2 * maxJumpHeight) / timeToApex;
//rigidbody check //rigidbody check
rb = GetComponent<RigidBody>(); rb = GetComponent<RigidBody>();
if (rb == null) if (rb == null)
@ -94,10 +105,10 @@ public class PlayerController : Script
if(tranform == null) if(tranform == null)
Debug.LogError("tranform is NULL!"); Debug.LogError("tranform is NULL!");
//Jump setup //PickAndThrow checl
float timeToApex = maxJumpTime / 2; pat = GetScript<PickAndThrow>();
gravity = (-2 * maxJumpHeight) / MathF.Pow(timeToApex, 2); if (pat == null)
initialJumpVel = (2 * maxJumpHeight) / timeToApex; Debug.LogError("PickAndThrow is NULL!");
//toRemove //toRemove
tranform.LocalPosition = new Vector3(-3.0f, -2.0f, -5.0f); tranform.LocalPosition = new Vector3(-3.0f, -2.0f, -5.0f);
@ -116,9 +127,11 @@ public class PlayerController : Script
tranform.LocalPosition = new Vector3(-3.0f, -2.0f, -5.0f); tranform.LocalPosition = new Vector3(-3.0f, -2.0f, -5.0f);
} }
GotCaught();
MoveKey(); MoveKey();
//Debug.Log(currentState.ToString() + " x:" + rb.LinearVelocity.x.ToString() + " y:" + rb.LinearVelocity.y.ToString() + " z:" + rb.LinearVelocity.z.ToString()); //Debug.Log(currentState.ToString() + " x:" + rb.LinearVelocity.x.ToString() + " y:" + rb.LinearVelocity.y.ToString() + " z:" + rb.LinearVelocity.z.ToString());
} }
@ -202,7 +215,7 @@ public class PlayerController : Script
{ {
if (rb != null) if (rb != null)
{ {
rb.AddForce(new Vector3(moveForce * axisMove.x, 0.0f, moveForce * axisMove.y)); rb.AddForce(new Vector3(axisMove.x, 0.0f,axisMove.y) * moveForce);
if (isMoveKeyPress) if (isMoveKeyPress)
{ {
@ -259,6 +272,16 @@ public class PlayerController : Script
currentState = RaccoonStates.JUMP; currentState = RaccoonStates.JUMP;
Vector3 v = rb.LinearVelocity; Vector3 v = rb.LinearVelocity;
v.y = initialJumpVel * 0.5f; v.y = initialJumpVel * 0.5f;
if (pat != null && pat.item.GetScript<Item>() != null && holdItem)
{
Item item = pat.item.GetScript<Item>();
if (item.currCategory == ItemCategory.LIGHT)
v.y *= lightMultiper;
if (item.currCategory == ItemCategory.MEDIUM)
v.y *= mediumMultiper;
if (item.currCategory == ItemCategory.HEAVY)
v.y *= heavyMultiper;
}
rb.LinearVelocity = v; rb.LinearVelocity = v;
} }
} }
@ -319,6 +342,15 @@ public class PlayerController : Script
} }
} }
private void GotCaught()
{
if (currentState == RaccoonStates.CAUGHT && tranform != null)
{
currentState = RaccoonStates.IDILE;
tranform.LocalPosition = new Vector3(-3.0f, -2.0f, -5.0f);
}
}
protected override void onCollisionEnter(CollisionInfo info) protected override void onCollisionEnter(CollisionInfo info)
{ {
} }

View File

@ -30,4 +30,5 @@ workspace "SHADE"
--include "Dependencies/tracy" --include "Dependencies/tracy"
include "Dependencies/yamlcpp" include "Dependencies/yamlcpp"
include "Dependencies/reactphysics3d" include "Dependencies/reactphysics3d"
include "Dependencies/ModelCompiler"
group "" group ""