Removed Original mesh compiler, rewriting mesh loader to reflect ModelCompiler format
This commit is contained in:
parent
e2778da955
commit
2beae24924
|
@ -18,24 +18,32 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
struct SH_API SHMeshAssetHeader
|
struct SHMeshDataHeader
|
||||||
{
|
{
|
||||||
uint32_t vertexCount;
|
uint32_t vertexCount;
|
||||||
uint32_t indexCount;
|
uint32_t indexCount;
|
||||||
std::string name;
|
uint32_t charCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SH_API SHMeshAsset : SHAssetData
|
struct SHMeshData
|
||||||
{
|
{
|
||||||
bool compiled;
|
std::string name;
|
||||||
bool changed;
|
std::vector<SHVec3> vertexPosition;
|
||||||
|
std::vector<SHVec3> vertexTangent;
|
||||||
|
std::vector<SHVec3> vertexNormal;
|
||||||
|
std::vector<SHVec2> texCoords;
|
||||||
|
std::vector<uint32_t> indices;
|
||||||
|
};
|
||||||
|
|
||||||
SHMeshAssetHeader header;
|
struct SHMeshAssetHeader
|
||||||
|
{
|
||||||
|
size_t meshCount;
|
||||||
|
};
|
||||||
|
|
||||||
std::vector<SHVec3> vertexPosition;
|
struct SH_API SHMeshAsset : SHAssetData
|
||||||
std::vector<SHVec3> vertexTangent;
|
{
|
||||||
std::vector<SHVec3> vertexNormal;
|
SHMeshAssetHeader header;
|
||||||
std::vector<SHVec2> texCoords;
|
std::vector<SHMeshDataHeader> headers;
|
||||||
std::vector<uint32_t> indices;
|
std::vector<SHMeshData> meshes;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -16,6 +16,36 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
void SHMeshLoader::ReadHeader(std::ifstream& file, SHMeshDataHeader& header) noexcept
|
||||||
|
{
|
||||||
|
file.read(
|
||||||
|
reinterpret_cast<char*>(&header),
|
||||||
|
sizeof(SHMeshDataHeader)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHMeshLoader::ReadData(std::ifstream& file, SHMeshDataHeader const& header, SHMeshData& data) noexcept
|
||||||
|
{
|
||||||
|
|
||||||
|
auto const vertexVec3Byte{ sizeof(SHVec3) * header.vertexCount };
|
||||||
|
auto const vertexVec2Byte{ sizeof(SHVec2) * header.indexCount };
|
||||||
|
|
||||||
|
data.vertexPosition.resize(header.vertexCount);
|
||||||
|
data.vertexTangent.resize(header.vertexCount);
|
||||||
|
data.vertexNormal.resize(header.vertexCount);
|
||||||
|
data.texCoords.resize(header.vertexCount);
|
||||||
|
data.indices.resize(header.indexCount);
|
||||||
|
|
||||||
|
file.read(data.name.data(), header.charCount);
|
||||||
|
file.read(reinterpret_cast<char*>(data.vertexPosition.data()), vertexVec3Byte);
|
||||||
|
file.read(reinterpret_cast<char*>(data.vertexTangent.data()), vertexVec3Byte);
|
||||||
|
file.read(reinterpret_cast<char*>(data.vertexNormal.data()), vertexVec3Byte);
|
||||||
|
file.read(reinterpret_cast<char*>(data.texCoords.data()), vertexVec2Byte);
|
||||||
|
file.read(reinterpret_cast<char*>(data.indices.data()), sizeof(uint32_t) * header.indexCount);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void SHMeshLoader::LoadSHMesh(AssetPath path, SHMeshAsset& mesh) noexcept
|
void SHMeshLoader::LoadSHMesh(AssetPath path, SHMeshAsset& mesh) noexcept
|
||||||
{
|
{
|
||||||
std::ifstream file{ path.string(), std::ios::in | std::ios::binary };
|
std::ifstream file{ path.string(), std::ios::in | std::ios::binary };
|
||||||
|
@ -25,46 +55,21 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string name{ path.stem().string() };
|
|
||||||
|
|
||||||
file.seekg(0);
|
file.seekg(0);
|
||||||
|
|
||||||
uint32_t vertCount, indexCount;
|
file.read(
|
||||||
std::vector<SHVec3> vertPos, vertTan, vertNorm;
|
reinterpret_cast<char *>(&mesh.header),
|
||||||
std::vector<SHVec2> texCoord;
|
sizeof(SHMeshAssetHeader)
|
||||||
std::vector<uint32_t> indices;
|
);
|
||||||
|
|
||||||
file.read(reinterpret_cast<char*>(&vertCount), sizeof(uint32_t));
|
mesh.headers.resize(mesh.header.meshCount);
|
||||||
file.read(reinterpret_cast<char*>(&indexCount), sizeof(uint32_t));
|
mesh.meshes.resize(mesh.header.meshCount);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
|
for (auto i{ 0 }; i < mesh.header.meshCount; ++i)
|
||||||
|
{
|
||||||
|
ReadHeader(file, mesh.headers[i]);
|
||||||
|
ReadData(file, mesh.headers[i], mesh.meshes[i]);
|
||||||
|
}
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,52 +84,6 @@ namespace SHADE
|
||||||
|
|
||||||
void SHMeshLoader::Write(SHAssetData const* data, AssetPath path)
|
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,16 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "Assets/Asset Types/SHMeshAsset.h"
|
#include "Assets/Asset Types/SHMeshAsset.h"
|
||||||
#include "SHAssetLoader.h"
|
#include "SHAssetLoader.h"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
struct SHMeshLoader : SHAssetLoader
|
class SHMeshLoader : public SHAssetLoader
|
||||||
{
|
{
|
||||||
|
void ReadHeader(std::ifstream& file, SHMeshDataHeader& header) noexcept;
|
||||||
|
void ReadData(std::ifstream& file, SHMeshDataHeader const& header, SHMeshData& data) noexcept;
|
||||||
|
|
||||||
|
public:
|
||||||
void LoadSHMesh(AssetPath path, SHMeshAsset& meshes) noexcept;
|
void LoadSHMesh(AssetPath path, SHMeshAsset& meshes) 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;
|
||||||
|
|
Loading…
Reference in New Issue