Rewrote comping to write all meshes into one file instead of multiple files for meshes
This commit is contained in:
parent
d194ca68fe
commit
48c3ed823b
|
@ -356,3 +356,5 @@ MigrationBackup/
|
||||||
Premake/
|
Premake/
|
||||||
|
|
||||||
*.sln
|
*.sln
|
||||||
|
|
||||||
|
Dependencies/
|
||||||
|
|
|
@ -9,13 +9,6 @@ project "ModelCompileLibrary"
|
||||||
systemversion "latest"
|
systemversion "latest"
|
||||||
|
|
||||||
|
|
||||||
configurations
|
|
||||||
{
|
|
||||||
"Debug",
|
|
||||||
"Release",
|
|
||||||
"Publish"
|
|
||||||
}
|
|
||||||
|
|
||||||
files
|
files
|
||||||
{
|
{
|
||||||
"%{prj.location}/src/**.h",
|
"%{prj.location}/src/**.h",
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/*************************************************************************//**
|
/*************************************************************************//**
|
||||||
* \file SHMeshCompiler.cpp
|
* \file MeshCompiler.cpp
|
||||||
* \author Loh Xiao Qi
|
* \author Loh Xiao Qi
|
||||||
* \date 30 September 2022
|
* \date 30 September 2022
|
||||||
* \brief Library to write data in SHMeshAsset into binary file for faster
|
* \brief Library to write data in MeshAsset into binary file for faster
|
||||||
* loading in the future
|
* loading in the future
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
@ -10,23 +10,24 @@
|
||||||
* disclosure of this file or its contents without the prior written consent
|
* disclosure of this file or its contents without the prior written consent
|
||||||
* of DigiPen Institute of Technology is prohibited.
|
* of DigiPen Institute of Technology is prohibited.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
#include "SHMeshCompiler.h"
|
#include "MeshCompiler.h"
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
namespace SHADE
|
namespace SH_COMP
|
||||||
{
|
{
|
||||||
|
|
||||||
Assimp::Importer SHMeshCompiler::aiImporter;
|
Assimp::Importer MeshCompiler::aiImporter;
|
||||||
|
|
||||||
void SHMeshCompiler::ProcessNode(aiNode const& node, aiScene const& scene, MeshVectorRef meshes) noexcept
|
void MeshCompiler::ProcessNode(aiNode const& node, aiScene const& scene, MeshVectorRef meshes) noexcept
|
||||||
{
|
{
|
||||||
for (size_t i{ 0 }; i < node.mNumMeshes; ++i)
|
for (size_t i{ 0 }; i < node.mNumMeshes; ++i)
|
||||||
{
|
{
|
||||||
aiMesh* mesh = scene.mMeshes[node.mMeshes[i]];
|
aiMesh* mesh = scene.mMeshes[node.mMeshes[i]];
|
||||||
meshes.push_back(ProcessMesh(*mesh));
|
meshes.emplace_back();
|
||||||
|
GetMesh(*mesh, meshes.back());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i{ 0 }; i < node.mNumChildren; ++i)
|
for (size_t i{ 0 }; i < node.mNumChildren; ++i)
|
||||||
|
@ -35,11 +36,11 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHMeshCompiler::ExtractAnimations(aiScene const& scene, AnimVectorRef anims) noexcept
|
void MeshCompiler::ExtractAnimations(aiScene const& scene, AnimVectorRef anims) noexcept
|
||||||
{
|
{
|
||||||
if (scene.HasAnimations())
|
if (scene.HasAnimations())
|
||||||
{
|
{
|
||||||
std::vector<SHAnimationAsset> anims(scene.mNumAnimations);
|
std::vector<AnimationAsset> anims(scene.mNumAnimations);
|
||||||
for (auto i{ 0 }; i < scene.mNumAnimations; ++i)
|
for (auto i{ 0 }; i < scene.mNumAnimations; ++i)
|
||||||
{
|
{
|
||||||
auto const& anim{ *scene.mAnimations[i] };
|
auto const& anim{ *scene.mAnimations[i] };
|
||||||
|
@ -56,11 +57,12 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SHMeshAsset* SHMeshCompiler::ProcessMesh(aiMesh const& mesh) noexcept
|
void MeshCompiler::GetMesh(aiMesh const& mesh, MeshData& meshData) noexcept
|
||||||
{
|
{
|
||||||
SHMeshAsset* result = new SHMeshAsset();
|
meshData.vertexPosition.reserve(mesh.mNumVertices);
|
||||||
result->compiled = false;
|
meshData.vertexNormal.reserve(mesh.mNumVertices);
|
||||||
result->changed = false;
|
meshData.vertexTangent.reserve(mesh.mNumVertices);
|
||||||
|
meshData.texCoords.reserve(mesh.mNumVertices);
|
||||||
|
|
||||||
for (size_t i{ 0 }; i < mesh.mNumVertices; ++i)
|
for (size_t i{ 0 }; i < mesh.mNumVertices; ++i)
|
||||||
{
|
{
|
||||||
|
@ -69,7 +71,7 @@ namespace SHADE
|
||||||
vertex.x = mesh.mVertices[i].x;
|
vertex.x = mesh.mVertices[i].x;
|
||||||
vertex.y = mesh.mVertices[i].y;
|
vertex.y = mesh.mVertices[i].y;
|
||||||
vertex.z = mesh.mVertices[i].z;
|
vertex.z = mesh.mVertices[i].z;
|
||||||
result->vertexPosition.push_back(vertex);
|
meshData.vertexPosition.push_back(vertex);
|
||||||
|
|
||||||
// Tex coords
|
// Tex coords
|
||||||
SHVec2 texCoord{ 0.f, 0.f };
|
SHVec2 texCoord{ 0.f, 0.f };
|
||||||
|
@ -78,7 +80,7 @@ namespace SHADE
|
||||||
texCoord.x = mesh.mTextureCoords[0][i].x;
|
texCoord.x = mesh.mTextureCoords[0][i].x;
|
||||||
texCoord.y = mesh.mTextureCoords[0][i].y;
|
texCoord.y = mesh.mTextureCoords[0][i].y;
|
||||||
}
|
}
|
||||||
result->texCoords.push_back(texCoord);
|
meshData.texCoords.push_back(texCoord);
|
||||||
|
|
||||||
// Normals
|
// Normals
|
||||||
SHVec3 normal{ 0.f, 0.f, 0.f };
|
SHVec3 normal{ 0.f, 0.f, 0.f };
|
||||||
|
@ -88,7 +90,7 @@ namespace SHADE
|
||||||
normal.y = mesh.mNormals[i].y;
|
normal.y = mesh.mNormals[i].y;
|
||||||
normal.z = mesh.mNormals[i].z;
|
normal.z = mesh.mNormals[i].z;
|
||||||
}
|
}
|
||||||
result->vertexNormal.push_back(normal);
|
meshData.vertexNormal.push_back(normal);
|
||||||
|
|
||||||
// Tangent
|
// Tangent
|
||||||
SHVec3 tangent{ 0.f, 0.f, 0.f };
|
SHVec3 tangent{ 0.f, 0.f, 0.f };
|
||||||
|
@ -98,7 +100,7 @@ namespace SHADE
|
||||||
tangent.y = mesh.mTangents[i].y;
|
tangent.y = mesh.mTangents[i].y;
|
||||||
tangent.z = mesh.mTangents[i].z;
|
tangent.z = mesh.mTangents[i].z;
|
||||||
}
|
}
|
||||||
result->vertexTangent.push_back(tangent);
|
meshData.vertexTangent.push_back(tangent);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i{ 0 }; i < mesh.mNumFaces; ++i)
|
for (size_t i{ 0 }; i < mesh.mNumFaces; ++i)
|
||||||
|
@ -106,68 +108,46 @@ namespace SHADE
|
||||||
aiFace face = mesh.mFaces[i];
|
aiFace face = mesh.mFaces[i];
|
||||||
for (size_t j{ 0 }; j < face.mNumIndices; ++j)
|
for (size_t j{ 0 }; j < face.mNumIndices; ++j)
|
||||||
{
|
{
|
||||||
result->indices.push_back(face.mIndices[j]);
|
meshData.indices.push_back(face.mIndices[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result->header.vertexCount = static_cast<uint32_t>(result->vertexPosition.size());
|
meshData.name = mesh.mName.C_Str();
|
||||||
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
|
void MeshCompiler::BuildHeaders(MeshAsset& asset) noexcept
|
||||||
{
|
{
|
||||||
const aiScene* scene = aiImporter.ReadFile(path.string().c_str(),
|
for (auto const& mesh : asset.meshes)
|
||||||
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())
|
|
||||||
{
|
{
|
||||||
std::cout << "ERROR in GLTF::ASSIMP: " << aiImporter.GetErrorString() << "\nFile: " << path.string() << std::endl;
|
asset.headers.emplace_back();
|
||||||
return;
|
auto& head = asset.headers.back();
|
||||||
|
|
||||||
|
head.charCount = mesh.name.size();
|
||||||
|
head.indexCount = mesh.indices.size();
|
||||||
|
head.vertexCount = mesh.vertexPosition.size();
|
||||||
|
|
||||||
|
asset.header.meshCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//ExtractAnimations(*scene, anims);
|
|
||||||
|
|
||||||
ProcessNode(*scene->mRootNode, *scene, meshes);
|
|
||||||
|
|
||||||
aiImporter.FreeScene();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<AssetPath> SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept
|
void MeshCompiler::WriteMeshHeader(std::ofstream& file, MeshDataHeader const& header)
|
||||||
{
|
{
|
||||||
std::string newPath{ path.string() + asset.header.name + MESH_EXTENSION.data() };
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(&header),
|
||||||
|
sizeof(MeshDataHeader)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
std::ofstream file{ newPath, std::ios::out | std::ios::binary | std::ios::trunc };
|
void MeshCompiler::WriteMeshData(std::ofstream& file, MeshDataHeader const& header, MeshData const& asset)
|
||||||
if (!file.is_open())
|
{
|
||||||
{
|
auto const vertexVec3Byte{ sizeof(SHVec3) * header.vertexCount };
|
||||||
std::cout << "Unable to open file for write: " << newPath << std::endl;
|
auto const vertexVec2Byte{ sizeof(SHVec2) * header.vertexCount };
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
file.write(
|
file.write(
|
||||||
reinterpret_cast<char const*>(&(asset.header.vertexCount)),
|
asset.name.c_str(),
|
||||||
sizeof(uint32_t)
|
header.charCount
|
||||||
);
|
);
|
||||||
|
|
||||||
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(
|
file.write(
|
||||||
reinterpret_cast<char const*>(asset.vertexPosition.data()),
|
reinterpret_cast<char const*>(asset.vertexPosition.data()),
|
||||||
vertexVec3Byte
|
vertexVec3Byte
|
||||||
|
@ -190,24 +170,71 @@ namespace SHADE
|
||||||
|
|
||||||
file.write(
|
file.write(
|
||||||
reinterpret_cast<char const*>(asset.indices.data()),
|
reinterpret_cast<char const*>(asset.indices.data()),
|
||||||
sizeof(uint32_t) * asset.header.indexCount
|
sizeof(uint32_t) * header.indexCount
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MeshCompiler::LoadFromFile(AssetPath path, MeshAsset& asset) 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
|
||||||
);
|
);
|
||||||
|
|
||||||
file.close();
|
if (!scene || !scene->HasMeshes())
|
||||||
|
{
|
||||||
|
std::cout << "ERROR in GLTF::ASSIMP: " << aiImporter.GetErrorString() << "\nFile: " << path.string() << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
return newPath;
|
//ExtractAnimations(*scene, anims);
|
||||||
|
|
||||||
|
ProcessNode(*scene->mRootNode, *scene, asset.meshes);
|
||||||
|
|
||||||
|
aiImporter.FreeScene();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHMeshCompiler::LoadAndCompile(AssetPath path) noexcept
|
void MeshCompiler::CompileMeshBinary(AssetPath path, MeshAsset const& asset) noexcept
|
||||||
{
|
{
|
||||||
std::vector<SHMeshAsset*> meshes;
|
std::string newPath{ path.string().substr(0, path.string().find_last_of('.')) };
|
||||||
std::vector<SHAnimationAsset*> anims;
|
newPath += MESH_EXTENSION;
|
||||||
|
|
||||||
LoadFromFile(path, meshes, anims);
|
std::ofstream file{ newPath, std::ios::out | std::ios::binary | std::ios::trunc };
|
||||||
|
if (!file.is_open())
|
||||||
for (auto const& mesh : meshes)
|
|
||||||
{
|
{
|
||||||
CompileMeshBinary(*mesh, path.parent_path().string() + '/');
|
std::cout << "Unable to open file for write: " << newPath << std::endl;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(&asset.header),
|
||||||
|
sizeof(asset.header)
|
||||||
|
);
|
||||||
|
|
||||||
|
for (auto i {0}; i < asset.headers.size(); ++i)
|
||||||
|
{
|
||||||
|
WriteMeshHeader(file, asset.headers[i]);
|
||||||
|
WriteMeshData(file, asset.headers[i], asset.meshes[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MeshCompiler::LoadAndCompile(AssetPath path) noexcept
|
||||||
|
{
|
||||||
|
auto const asset = new MeshAsset();
|
||||||
|
|
||||||
|
LoadFromFile(path, *asset);
|
||||||
|
BuildHeaders(*asset);
|
||||||
|
CompileMeshBinary(path, *asset);
|
||||||
|
|
||||||
|
delete asset;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
* \file SHMeshCompiler.h
|
* \file SHMeshCompiler.h
|
||||||
* \author Loh Xiao Qi
|
* \author Loh Xiao Qi
|
||||||
* \date 30 September 2022
|
* \date 30 September 2022
|
||||||
* \brief Library to write data in SHMeshAsset into binary file for faster
|
* \brief Library to write data in MeshAsset into binary file for faster
|
||||||
* loading in the future
|
* loading in the future
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
@ -16,24 +16,30 @@
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Types/SHAnimationAsset.h"
|
#include "Types/AnimationAsset.h"
|
||||||
#include "Types/SHMeshAsset.h"
|
#include "Types/MeshAsset.h"
|
||||||
#include "SHAssetMacros.h"
|
#include "AssetMacros.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SH_COMP
|
||||||
{
|
{
|
||||||
class SHMeshCompiler
|
class MeshCompiler
|
||||||
{
|
{
|
||||||
|
|
||||||
using MeshVectorRef = std::vector<SHMeshAsset*>&;
|
using MeshVectorRef = std::vector<MeshData>&;
|
||||||
using AnimVectorRef = std::vector<SHAnimationAsset*>&;
|
using AnimVectorRef = std::vector<AnimationAsset>&;
|
||||||
|
|
||||||
static Assimp::Importer aiImporter;
|
static Assimp::Importer aiImporter;
|
||||||
|
|
||||||
static void ProcessNode(aiNode const& node, aiScene const& scene, MeshVectorRef meshes) noexcept;
|
static void ProcessNode(aiNode const& node, aiScene const& scene, MeshVectorRef meshes) noexcept;
|
||||||
static void ExtractAnimations(aiScene const& scene, AnimVectorRef anims) noexcept;
|
static void ExtractAnimations(aiScene const& scene, AnimVectorRef anims) noexcept;
|
||||||
static SHMeshAsset* ProcessMesh(aiMesh const& mesh) noexcept;
|
static void GetMesh(aiMesh const& mesh, MeshData& meshData) noexcept;
|
||||||
static void LoadFromFile(AssetPath path, MeshVectorRef meshes, AnimVectorRef anims) noexcept;
|
static void BuildHeaders(MeshAsset& asset) noexcept;
|
||||||
static std::optional<AssetPath> CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept;
|
|
||||||
|
static void WriteMeshHeader(std::ofstream& file, MeshDataHeader const& header);
|
||||||
|
static void WriteMeshData(std::ofstream& file, MeshDataHeader const& header, MeshData const& data);
|
||||||
|
|
||||||
|
static void LoadFromFile(AssetPath path, MeshAsset& asset) noexcept;
|
||||||
|
static void CompileMeshBinary(AssetPath path, MeshAsset const& asset) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void LoadAndCompile(AssetPath path) noexcept;
|
static void LoadAndCompile(AssetPath path) noexcept;
|
|
@ -13,9 +13,9 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <assimp/anim.h>
|
#include <assimp/anim.h>
|
||||||
|
|
||||||
namespace SHADE
|
namespace SH_COMP
|
||||||
{
|
{
|
||||||
struct SHAnimationAsset
|
struct AnimationAsset
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
|
@ -13,8 +13,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace SHADE
|
namespace SH_COMP
|
||||||
{
|
{
|
||||||
|
|
||||||
struct SHVec2
|
struct SHVec2
|
||||||
|
@ -27,24 +28,32 @@ namespace SHADE
|
||||||
float x, y, z;
|
float x, y, z;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SHMeshAssetHeader
|
struct MeshDataHeader
|
||||||
{
|
{
|
||||||
uint32_t vertexCount;
|
uint32_t vertexCount;
|
||||||
uint32_t indexCount;
|
uint32_t indexCount;
|
||||||
std::string name;
|
uint32_t charCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SHMeshAsset
|
struct MeshData
|
||||||
{
|
{
|
||||||
bool compiled;
|
std::string name;
|
||||||
bool changed;
|
|
||||||
|
|
||||||
SHMeshAssetHeader header;
|
|
||||||
|
|
||||||
std::vector<SHVec3> vertexPosition;
|
std::vector<SHVec3> vertexPosition;
|
||||||
std::vector<SHVec3> vertexTangent;
|
std::vector<SHVec3> vertexTangent;
|
||||||
std::vector<SHVec3> vertexNormal;
|
std::vector<SHVec3> vertexNormal;
|
||||||
std::vector<SHVec2> texCoords;
|
std::vector<SHVec2> texCoords;
|
||||||
std::vector<uint32_t> indices;
|
std::vector<uint32_t> indices;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MeshAssetHeader
|
||||||
|
{
|
||||||
|
size_t meshCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MeshAsset
|
||||||
|
{
|
||||||
|
MeshAssetHeader header;
|
||||||
|
std::vector<MeshDataHeader> headers;
|
||||||
|
std::vector<MeshData> meshes;
|
||||||
|
};
|
||||||
}
|
}
|
|
@ -8,7 +8,7 @@
|
||||||
* or disclosure of this file or its contents without the prior
|
* or disclosure of this file or its contents without the prior
|
||||||
* written consent of Digipen Institute of Technology is prohibited.
|
* written consent of Digipen Institute of Technology is prohibited.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#include "Libraries/SHMeshCompiler.h"
|
#include "Libraries/MeshCompiler.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
Loading…
Reference in New Issue