Skip to content

Commit

Permalink
Added Runtime and Working on Asset Packing
Browse files Browse the repository at this point in the history
  • Loading branch information
tomheeleynz committed Aug 15, 2023
1 parent 7002d14 commit cbc9b20
Show file tree
Hide file tree
Showing 35 changed files with 787 additions and 122 deletions.
1 change: 1 addition & 0 deletions Arcane/src/Arcane.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "Arcane/Scene/Scene.h"
#include "Arcane/Scene/SceneDeserializer.h"
#include "Arcane/Scene/SceneSerializer.h"
#include "Arcane/Scene/SceneManager.h"

/////////////////////////////////////////////////////
////////// Utils
Expand Down
9 changes: 8 additions & 1 deletion Arcane/src/Arcane/Assets/Asset.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

#include <string>
#include <filesystem>
#include <fstream>
#include <nlohmann/json.hpp>
#include <map>

#include "Arcane/Core/UUID.h"

Expand Down Expand Up @@ -35,7 +38,11 @@ namespace Arcane

std::filesystem::path GetPath() { return m_Path; }
void SetPath(std::filesystem::path path) { m_Path = path; }
private:

// Virtual Methods
virtual void PackAsset(std::ofstream& o) {}
virtual std::pair<uint64_t, Asset*> UnpackAsset(std::ofstream& o) { return std::pair<uint64_t, Asset*>(); };
private:
Core::UUID m_UUID;
AssetType m_Type;
std::string m_Name;
Expand Down
9 changes: 8 additions & 1 deletion Arcane/src/Arcane/Assets/AssetDatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "Arcane/Scene/SceneDeserializer.h"
#include "Arcane/Animation/AnimationSerializer.h"
#include "Arcane/Animation/AnimationControllerSerializer.h"
#include "Arcane/Scene/SceneManager.h"

namespace Arcane
{
Expand All @@ -33,7 +34,7 @@ namespace Arcane

bool AssetDatabase::GenerateDatabase()
{
GenerateDefaultAssets();
// GenerateDefaultAssets();
for (auto& dirEntry : std::filesystem::recursive_directory_iterator(m_AssetDirPath)) {
if (dirEntry.is_regular_file()) {
std::filesystem::path file = dirEntry.path();
Expand Down Expand Up @@ -172,6 +173,7 @@ namespace Arcane
scene->SetName(name);
scene->SetPath(currentAssetPath);
m_Assets[assetID] = scene;
SceneManager::AddScene(scene);
}
}
else if (currentAssetPath.extension() == ".arcaneanim")
Expand Down Expand Up @@ -208,6 +210,11 @@ namespace Arcane
return true;
}

void AssetDatabase::AddAsset(uint64_t id, Asset* asset)
{
m_Assets[id] = asset;
}

bool AssetDatabase::CheckMetaInfo(std::filesystem::path currentMetaPath)
{
return std::filesystem::exists(currentMetaPath);
Expand Down
4 changes: 4 additions & 0 deletions Arcane/src/Arcane/Assets/AssetDatabase.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#include "Asset.h"
#include "Arcane/Renderer/Texture.h"


namespace Arcane
{
class AssetDatabase
Expand All @@ -31,6 +33,8 @@ namespace Arcane
void GenerateMetaFile(std::filesystem::path metaPath, uint64_t newID);

uint64_t GetMetaID(std::filesystem::path metaPath);

void AddAsset(uint64_t id, Asset* asset);
private:
bool GenerateDefaultAssets();
void ParseTextureMetafile(Texture* texture, std::filesystem::path metaPath);
Expand Down
152 changes: 99 additions & 53 deletions Arcane/src/Arcane/Assets/AssetPack.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
#include <vector>

#include "AssetPack.h"
#include "Arcane/Scene/SceneManager.h"
#include "Arcane/ECS/Entity.h"
#include "Arcane/Scene/Scene.h"
#include "Arcane/Scene/SceneDeserializer.h"

namespace Arcane
{
Expand All @@ -9,82 +15,122 @@ namespace Arcane

void AssetPack::Serialize()
{
// Get Asset Database
AssetDatabase& database = Application::Get().GetAssetDatabase();

// Asset Pack File Struct
AssetPackFile newFile;

// Create header for the struct
AssetPackHeader newHeader;
newHeader.signature = 115;
newHeader.version = 0x01;

// Write header to file
// Serialize ScenesPack
std::ofstream o(m_Path, std::ios::out | std::ios::binary);
AssetDatabase& database = Application::Get().GetAssetDatabase();

uint16_t textureCount = 0;
std::vector<AssetPackTexture> assetPackTextures;
nlohmann::json sceneJson;
sceneJson["Scenes"] = nlohmann::json::array();

for (const auto& [key, val] : database.GetAssetMap())
for (auto& [id, asset] : database.GetAssetMap())
{
if (val->GetAssetType() == AssetType::TEXTURE) {
textureCount += 1;
if (asset->GetAssetType() == AssetType::SCENE)
{
nlohmann::json jsonObject;
std::ifstream i(asset->GetPath());
i >> jsonObject;

sceneJson["Scenes"].push_back(jsonObject);
}
}

int savedTextures = 0;
newFile.textures.resize(textureCount);
for (const auto& [key, val] : database.GetAssetMap())
{
if (val->GetAssetType() == AssetType::TEXTURE)
{
Texture* texture = static_cast<Texture*>(val);
std::string jsonString = sceneJson.dump();
uint32_t jsonLength = jsonString.length();

newFile.textures[savedTextures].height = texture->GetTextureSpecs().height;
newFile.textures[savedTextures].width = texture->GetTextureSpecs().width;
newFile.textures[savedTextures].id = key;

TextureRuntimeData runtimeData = texture->GetRuntimeData();
newFile.textures[savedTextures].textureDataCount = runtimeData.size;
o.write((const char*)&jsonLength, sizeof(uint32_t));
o.write(jsonString.data(), jsonLength);

for (int i = 0; i < runtimeData.size; i++) {
newFile.textures[savedTextures].textureData.push_back(runtimeData.data[i]);
}

savedTextures++;
for (auto& [id, asset] : database.GetAssetMap())
{
if (asset->GetAssetType() == AssetType::TEXTURE)
{
asset->PackAsset(o);
break;
}
}

newFile.assetPackHeader = newHeader;
newFile.textureCount = textureCount;

o.write((char*)&newHeader, sizeof(AssetPackHeader));
o.write((char*)&textureCount, sizeof(uint16_t));
o.write((char*)&newFile.textures[0], sizeof(assetPackTextures) * textureCount);

o.close();
}

void AssetPack::Deserialize()
{
std::ifstream i(m_Path, std::ios::out | std::ios::binary);
AssetDatabase& database = Application::Get().GetAssetDatabase();

uint32_t sceneJsonStringLength = 0;
i.read((char*)&sceneJsonStringLength, sizeof(uint32_t));

std::string sceneJsonString;
sceneJsonString.resize(sceneJsonStringLength);
i.read((char*)sceneJsonString.data(), sceneJsonStringLength);

SceneDeserializer deserializer = SceneDeserializer();
nlohmann::json scenesJson = nlohmann::json::parse(sceneJsonString);

for (auto& element : scenesJson["Scenes"])
{
deserializer.Deserialize(element);
}

while (true)
{
if (i.eof()) break;

int type = 0;
i.read((char*)&type, sizeof(int));

AssetPackHeader newHeader;
uint16_t textureCount;
std::vector<AssetPackTexture> textures;
if ((AssetType)type == AssetType::TEXTURE)
{
std::pair<uint64_t, Asset*> unpackedAsset = UnpackAsset(AssetType::TEXTURE, i);
database.AddAsset(unpackedAsset.first, unpackedAsset.second);
}

// Get Header
i.read((char*)&newHeader, sizeof(AssetPackHeader));

// Get Texture Count
i.read((char*)&textureCount, sizeof(uint16_t));

// Get Textures
textures.resize(textureCount);
i.read((char*)&textures[0], textureCount * sizeof(AssetPackTexture));
}


i.close();
}

std::pair<uint64_t, Asset*> AssetPack::UnpackAsset(AssetType type, std::ifstream& i)
{
std::pair<uint64_t, Asset*> newAsset = std::pair<uint64_t, Asset*>();

if (type == AssetType::TEXTURE)
{
uint64_t id = 0;
i.read((char*)&id, sizeof(uint64_t));

newAsset.first = id;
newAsset.second = UnpackTexture(i);
}

return newAsset;
}


Asset* AssetPack::UnpackTexture(std::ifstream& i)
{
uint32_t totalLength = 0;
i.read((char*)&totalLength, sizeof(uint32_t));

uint32_t jsonLength = 0;
i.read((char*)&jsonLength, sizeof(uint32_t));

uint32_t blobLength = 0;
i.read((char*)&blobLength, sizeof(uint32_t));

// Get Texture Metadata
std::string jsonString;
jsonString.resize(jsonLength);
i.read((char*)jsonString.data(), jsonLength);
nlohmann::json textureMetadata = nlohmann::json::parse(jsonString);

// Get Binary Data
std::vector<char> blob;
blob.resize(blobLength);
i.read((char*)blob.data(), blobLength);

return Texture::Create(blob.data(), blob.size(), textureMetadata["width"], textureMetadata["height"]);
}
}
29 changes: 10 additions & 19 deletions Arcane/src/Arcane/Assets/AssetPack.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,17 @@

#include <filesystem>
#include <fstream>
#include <vector>
#include <map>

#include "Arcane/Core/Application.h"

namespace Arcane
{
struct AssetPackTexture
struct AssetPackAsset
{
uint64_t id;
uint32_t width;
uint32_t height;
uint32_t textureDataCount;
std::vector<unsigned char> textureData;
};

struct AssetPackHeader
{
uint32_t signature;
uint8_t version;
};

struct AssetPackFile
{
AssetPackHeader assetPackHeader;
uint16_t textureCount;
std::vector<AssetPackTexture> textures;
std::vector<char> binaryBlob;
std::string json;
};

class AssetPack
Expand All @@ -36,6 +22,11 @@ namespace Arcane

void Serialize();
void Deserialize();

std::pair<uint64_t, Asset*> UnpackAsset(AssetType type, std::ifstream& i);
private:
Asset* UnpackTexture(std::ifstream& i);

private:
std::filesystem::path m_Path;
};
Expand Down
20 changes: 16 additions & 4 deletions Arcane/src/Arcane/Core/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "Arcane/Renderer/Pipeline.h"
#include "Arcane/Renderer/RenderPass.h"
#include "Arcane/Scripting/ScriptingEngine.h"
#include "Arcane/Scene/SceneManager.h"


namespace Arcane {
Expand Down Expand Up @@ -36,16 +37,27 @@ namespace Arcane {
m_Clock = new CClock();

// Init Project
ProjectDeserializer deserializer(std::filesystem::path(specifications.ProjectFilePath));
m_Project = deserializer.Deserialize();
if (!specifications.RuntimeLayer) {
ProjectDeserializer deserializer(std::filesystem::path(specifications.ProjectFilePath));
m_Project = deserializer.Deserialize();
}

// Init Scripting Engine
ScriptingEngine::Init();

// Init Scene Manager
SceneManager::Init();

// Generate Asset Database on application startup
m_AssetDatabase = new AssetDatabase(m_Project->GetWorkingPath().string());
bool assetDatabaseGenerated = m_AssetDatabase->GenerateDatabase();
std::filesystem::path assetPath;

if (specifications.RuntimeLayer)
assetPath = std::filesystem::path(specifications.RuntimePath);
else
assetPath = m_Project->GetWorkingPath();

m_AssetDatabase = new AssetDatabase(assetPath);
bool assetDatabaseGenerated = m_AssetDatabase->GenerateDatabase();
if (!assetDatabaseGenerated) {
std::cout << "Asset Database Not Created\n";
}
Expand Down
5 changes: 5 additions & 0 deletions Arcane/src/Arcane/Core/Application.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,21 @@
#include "Arcane/Assets/AssetDatabase.h"
#include "Arcane/Project/ProjectDeserializer.h"


namespace Arcane
{
struct ApplicationSpecifications
{
std::string Name;
uint32_t WindowWidth;
uint32_t WindowHeight;

bool PushImguiLayer = false;
bool RuntimeLayer = false;

const char* ProjectFilePath;
const char* EditorAssetPath;
const char* RuntimePath;
};

class Application
Expand Down
6 changes: 3 additions & 3 deletions Arcane/src/Arcane/ECS/Component.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ namespace Arcane
struct CameraComponent
{
bool isPrimary = false;
OrthoCamera* orthoCamera;
PerspectiveCamera* perspectiveCamera;
CameraType type = CameraType::Perspective;
OrthoCamera* orthoCamera = nullptr;
PerspectiveCamera* perspectiveCamera = nullptr;
CameraType type = CameraType::Orthographic;
};

struct TransformComponent
Expand Down

0 comments on commit cbc9b20

Please sign in to comment.