diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2023-10-04 16:01:19 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2023-10-04 16:01:19 -0400 |
| commit | 85fefd8b28a3f22f185f517cd2eb54f73ad5d05d (patch) | |
| tree | 553035bc36e4cb6d47e2d1c0a9ef397cfbe56e15 | |
| parent | 807a5db33b28b984c39364b33ec1248c38411e63 (diff) | |
checkpoint - first pass add instances to save file
| -rw-r--r-- | src/entities.cpp | 1 | ||||
| -rw-r--r-- | src/entities.hpp | 1 | ||||
| -rw-r--r-- | src/game.cpp | 172 |
3 files changed, 158 insertions, 16 deletions
diff --git a/src/entities.cpp b/src/entities.cpp index fd55970..efa22ae 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -341,6 +341,7 @@ void EntityType_Load(EntityType &et) { */ grBinds.vkPipelineLayout = vkPipelineLayout_Texture; grBinds.graphicsPipeline = vkPipelines.Texture; + et.grBindsHandle = grBinds.grBindsHandle; cgltf_options options{}; // TODO allocator diff --git a/src/entities.hpp b/src/entities.hpp index a83e0d5..07fc3b4 100644 --- a/src/entities.hpp +++ b/src/entities.hpp @@ -16,6 +16,7 @@ struct EntityType { const char *modelFile = nullptr; const char *entityTypeCode = nullptr; EntityHandle entityHandle = EntityHandle_MAX; + GrBindsHandle grBindsHandle = GrBindsHandle_MAX; VkDeviceMemory deviceMemoryVert = VK_NULL_HANDLE; VkDeviceMemory deviceMemoryInst = VK_NULL_HANDLE; VkDeviceMemory deviceMemoryTexture = VK_NULL_HANDLE; diff --git a/src/game.cpp b/src/game.cpp index 071a2b3..6ce4847 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -4,6 +4,7 @@ #include "vendor/glm_include.hpp" #include <cstring> +#include <iomanip> GameSettings pkeSettings{}; @@ -24,6 +25,7 @@ const char *PKE_FILE_END = ":PKFE:"; const char *PKE_FILE_VERSION = ":0:"; const char *PKE_FILE_OBJ_END = ""; const char *PKE_FILE_OBJ_ENTITY_TYPE = "EntityType:"; +const char *PKE_FILE_OBJ_INSTANCE = "Instance:"; const char *PKE_FILE_ENTITY_TYPE_MODELS_DIR = "ModelsDir: "; const char *PKE_FILE_ENTITY_TYPE_MODEL_FILE = "ModelFile: "; @@ -35,6 +37,12 @@ const char *PKE_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_NORMAL = "Importer const char *PKE_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_UV = "Importer_GLTF::AccessorIndexUV: "; const char *PKE_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_INDEX = "Importer_GLTF::AccessorIndexIndex: "; +const char *PKE_FILE_INSTANCE_ENTITY_HANDLE = "EntityHandle: "; +const char *PKE_FILE_INSTANCE_ENTITY_TYPE_CODE = "EntityTypeCode: "; +const char *PKE_FILE_INSTANCE_POS_POS = "InstPos::Pos: "; +const char *PKE_FILE_INSTANCE_POS_ROT = "InstPos::Rot: "; +const char *PKE_FILE_INSTANCE_POS_SCALE = "InstPos::Scale: "; + char consoleBuffer[consoleBufferCount][consoleLineLength]; long consoleBufferIndex = 0; EntityHandle selectedEntity = EntityHandle_MAX; @@ -46,23 +54,56 @@ void SerializeEntityType(std::ofstream &stream, const EntityType &et) { snprintf(handleStr, 19, "0x%016lX",static_cast<EntityHandle_T>(et.entityHandle)); EntityType e{}; if (et.modelsDir != e.modelsDir) - stream << PKE_FILE_ENTITY_TYPE_MODELS_DIR << et.modelsDir << "\n"; + stream << PKE_FILE_ENTITY_TYPE_MODELS_DIR << et.modelsDir << std::endl; if (et.modelFile != e.modelFile) - stream << PKE_FILE_ENTITY_TYPE_MODEL_FILE << et.modelFile << "\n"; + stream << PKE_FILE_ENTITY_TYPE_MODEL_FILE << et.modelFile << std::endl; if (et.entityTypeCode != e.entityTypeCode) - stream << PKE_FILE_ENTITY_TYPE_ENTITY_TYPE_CODE << et.entityTypeCode << "\n"; + stream << PKE_FILE_ENTITY_TYPE_ENTITY_TYPE_CODE << et.entityTypeCode << std::endl; if (et.entityHandle != e.entityHandle) - stream << PKE_FILE_ENTITY_TYPE_ENTITY_HANDLE << handleStr << "\n"; + stream << PKE_FILE_ENTITY_TYPE_ENTITY_HANDLE << handleStr << std::endl; if (et.startingInstanceCount != e.startingInstanceCount) - stream << PKE_FILE_ENTITY_TYPE_STARTING_INSTANCE_COUNT << et.startingInstanceCount << "\n"; + stream << PKE_FILE_ENTITY_TYPE_STARTING_INSTANCE_COUNT << et.startingInstanceCount << std::endl; if (et.Importer_GLTF.AccessorIndexVertex != e.Importer_GLTF.AccessorIndexVertex) - stream << PKE_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_VERTEX << et.Importer_GLTF.AccessorIndexVertex << "\n"; + stream << PKE_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_VERTEX << et.Importer_GLTF.AccessorIndexVertex << std::endl; if (et.Importer_GLTF.AccessorIndexNormal != e.Importer_GLTF.AccessorIndexNormal) - stream << PKE_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_NORMAL << et.Importer_GLTF.AccessorIndexNormal << "\n"; + stream << PKE_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_NORMAL << et.Importer_GLTF.AccessorIndexNormal << std::endl; if (et.Importer_GLTF.AccessorIndexUV != e.Importer_GLTF.AccessorIndexUV) - stream << PKE_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_UV << et.Importer_GLTF.AccessorIndexUV << "\n"; + stream << PKE_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_UV << et.Importer_GLTF.AccessorIndexUV << std::endl; if (et.Importer_GLTF.AccessorIndexIndex != e.Importer_GLTF.AccessorIndexIndex) - stream << PKE_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_INDEX << et.Importer_GLTF.AccessorIndexIndex << "\n"; + stream << PKE_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_INDEX << et.Importer_GLTF.AccessorIndexIndex << std::endl; +} + +void SerializeInstance(std::ofstream &stream, const CompInstance &comp) { + char handleStr[19] = { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' }; + snprintf(handleStr, 19, "0x%016lX",static_cast<EntityHandle_T>(comp.entHandle)); + EntityType *et = nullptr; + for (long i = 0; i < GlobalEntityTypes.Count(); ++i) { + if (GlobalEntityTypes[i].grBindsHandle == comp.grBindsHandle) { + et = &GlobalEntityTypes[i]; + break; + } + } + assert(et != nullptr); + CompInstance c{}; + if (comp.entHandle != c.entHandle) + stream << PKE_FILE_INSTANCE_ENTITY_HANDLE << handleStr << std::endl; + stream << PKE_FILE_INSTANCE_ENTITY_TYPE_CODE << et->entityTypeCode << std::endl; + if (comp.instPos.pos != c.instPos.pos) + stream << PKE_FILE_INSTANCE_POS_POS << "[" + << std::setw(10) << comp.instPos.pos[0] << "," + << std::setw(10) << comp.instPos.pos[1] << "," + << std::setw(10) << comp.instPos.pos[2] << "]" << std::endl; + if (comp.instPos.rot != c.instPos.rot) + stream << PKE_FILE_INSTANCE_POS_ROT << "[" + << std::setw(10) << comp.instPos.rot[0] << "," + << std::setw(10) << comp.instPos.rot[1] << "," + << std::setw(10) << comp.instPos.rot[2] << "," + << std::setw(10) << comp.instPos.rot[3] << "]" << std::endl; + if (comp.instPos.scale != c.instPos.scale) + stream << PKE_FILE_INSTANCE_POS_SCALE << "[" + << std::setw(10) << comp.instPos.scale[0] << "," + << std::setw(10) << comp.instPos.scale[1] << "," + << std::setw(10) << comp.instPos.scale[2] << "]" << std::endl; } void ParseEntityType(std::ifstream &stream) { @@ -106,7 +147,6 @@ void ParseEntityType(std::ifstream &stream) { continue; } if (strstr(readLine, PKE_FILE_ENTITY_TYPE_ENTITY_HANDLE)) { - // TODO parse from hex ? uint64_t prefixLen = strlen(PKE_FILE_ENTITY_TYPE_ENTITY_HANDLE); EntityHandle_T handle_t; STR2NUM_ERROR result = str2num(handle_t, readLine + prefixLen); @@ -147,16 +187,99 @@ void ParseEntityType(std::ifstream &stream) { } } +void ParseInstance(std::ifstream &stream) { + CompInstance comp{}; + char entTypeCode[21]; + memset(reinterpret_cast<void *>(entTypeCode), '\0', 21); + while (stream.getline(readLine, readLineLength)) { + if (strcmp(PKE_FILE_OBJ_END, readLine) == 0) { + if (entTypeCode[0] == '\0') { + printf("[Game::ParseInstance] Failed to create instance from save file. No EntTypeCode present."); + break; + } + int64_t existingEntityTypeIndex = EntityType_FindByTypeCode(entTypeCode); + if (existingEntityTypeIndex != -1) { + printf("[Game::ParseInstance] Failed to create instance from save file. Unknown EntityTypeCode: \"%s\"", entTypeCode); + break; + } + const auto &et = GlobalEntityTypes[existingEntityTypeIndex]; + auto entityHandle = ECS_CreateEntity(); + ECS_CreateInstance(entityHandle, et.entityHandle); + ECS_UpdateInstance(entityHandle, comp.instPos); + break; + } + if (strstr(readLine, PKE_FILE_INSTANCE_ENTITY_HANDLE)) { + uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_ENTITY_HANDLE); + EntityHandle_T handle_t; + STR2NUM_ERROR result = str2num(handle_t, readLine + prefixLen); + assert(result == STR2NUM_ERROR::SUCCESS); + comp.entHandle = EntityHandle{handle_t}; + continue; + } + if (strstr(readLine, PKE_FILE_INSTANCE_ENTITY_TYPE_CODE)) { + uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_ENTITY_TYPE_CODE); + uint64_t len = strlen(readLine + prefixLen); + memcpy(entTypeCode, readLine + prefixLen, len); + continue; + } + if (strstr(readLine, PKE_FILE_INSTANCE_POS_POS)) { + uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_POS_POS); + char *startingChar = strchr(readLine + prefixLen, '[') + 1; + assert(startingChar != nullptr); + char *pEnd = nullptr; + long index = 0; + do { + assert(index < 3); + STR2NUM_ERROR result = str2num(comp.instPos.scale[index], startingChar, pEnd); + assert(result == STR2NUM_ERROR::SUCCESS); + startingChar = pEnd + 1; + ++index; + } while (*pEnd != ']'); + continue; + } + if (strstr(readLine, PKE_FILE_INSTANCE_POS_ROT)) { + uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_POS_ROT); + char *startingChar = strchr(readLine + prefixLen, '[') + 1; + assert(startingChar != nullptr); + char *pEnd = nullptr; + long index = 0; + do { + assert(index < 4); + STR2NUM_ERROR result = str2num(comp.instPos.scale[index], startingChar, pEnd); + assert(result == STR2NUM_ERROR::SUCCESS); + startingChar = pEnd + 1; + ++index; + } while (*pEnd != ']'); + continue; + } + if (strstr(readLine, PKE_FILE_INSTANCE_POS_SCALE)) { + uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_POS_SCALE); + char *startingChar = strchr(readLine + prefixLen, '[') + 1; + assert(startingChar != nullptr); + char *pEnd = nullptr; + long index = 0; + do { + assert(index < 3); + STR2NUM_ERROR result = str2num(comp.instPos.scale[index], startingChar, pEnd); + assert(result == STR2NUM_ERROR::SUCCESS); + startingChar = pEnd + 1; + ++index; + } while (*pEnd != ']'); + continue; + } + } +} + void SaveSceneFile(const char *sceneFilePath) { std::ofstream f(sceneFilePath); assert(f.is_open()); - f << PKE_FILE_BEGIN << "\n"; - f << PKE_FILE_VERSION << "\n"; - f << "" << "\n"; + f << PKE_FILE_BEGIN << std::endl; + f << PKE_FILE_VERSION << std::endl; + f << "" << std::endl; for (long i = 0; i < GlobalEntityTypes.Count(); ++i) { - f << PKE_FILE_OBJ_ENTITY_TYPE << "\n"; + f << PKE_FILE_OBJ_ENTITY_TYPE << std::endl; const auto &et = GlobalEntityTypes[i]; const CompGrBinds *grBinds = ECS_GetGrBinds(et.entityHandle); // TODO ignore if no instances @@ -164,10 +287,23 @@ void SaveSceneFile(const char *sceneFilePath) { continue; } SerializeEntityType(f, et); - f << PKE_FILE_OBJ_END << "\n"; + f << PKE_FILE_OBJ_END << std::endl; + } + + int64_t instanceBucketCount = ECS_GetInstances_BucketCount(); + for (long b = 0; b < instanceBucketCount; ++b) { + uint64_t count; + auto *instances = ECS_GetInstances(b, count); + for (long i = 0; i < count; ++i) { + const auto &instance = instances[i]; + if (instance.entHandle == EntityHandle_MAX) + continue; + SerializeInstance(f, instance); + f << PKE_FILE_OBJ_END << std::endl; + } } - f << PKE_FILE_END << "\n"; + f << PKE_FILE_END << std::endl; f.flush(); f.close(); @@ -184,6 +320,10 @@ void LoadSceneFile(const char *sceneFilePath) { ParseEntityType(f); continue; } + if (strcmp(PKE_FILE_OBJ_INSTANCE, readLine) == 0) { + ParseInstance(f); + continue; + } } f.close(); |
