diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2025-04-02 20:46:41 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2025-04-02 20:46:41 -0400 |
| commit | a02c7589c6c9e902c59a632aa650635336fe648c (patch) | |
| tree | 8ec4800ff9f9effbd9141e02131123448679bc93 /src/serialization-component.cpp | |
| parent | fad302f7db146a78900f9b21dbbcd97761093c1b (diff) | |
pke: checkpoint: major serialization refactor
Diffstat (limited to 'src/serialization-component.cpp')
| -rw-r--r-- | src/serialization-component.cpp | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/src/serialization-component.cpp b/src/serialization-component.cpp new file mode 100644 index 0000000..34eb758 --- /dev/null +++ b/src/serialization-component.cpp @@ -0,0 +1,256 @@ + +#include "serialization-component.hpp" + +#include "ecs.hpp" +#include "entities.hpp" +#include "serialization.hpp" +#include "math-helpers.hpp" + +#include "BulletCollision/CollisionShapes/btCollisionShape.h" + +#include "pk.h" + +#define SRLZTN_FLOAT_WIDTH 10 + +bool pke_serialize_inst_pos(srlztn_serialize_helper *h, const glm::vec3 pos, const glm::quat quat_rot, const glm::vec3 scale) { + if (pos != glm::vec3(0)) { + h->o << SRLZTN_POSROT_POS << "[" + << std::setw(SRLZTN_FLOAT_WIDTH) << pos[0] << "," + << std::setw(SRLZTN_FLOAT_WIDTH) << pos[1] << "," + << std::setw(SRLZTN_FLOAT_WIDTH) << pos[2] << "]" << std::endl; + } + if (quat_rot != glm::quat{}) { + h->o << SRLZTN_POSROT_ROT << "[" + << std::setw(SRLZTN_FLOAT_WIDTH) << quat_rot[0] << "," + << std::setw(SRLZTN_FLOAT_WIDTH) << quat_rot[1] << "," + << std::setw(SRLZTN_FLOAT_WIDTH) << quat_rot[2] << "," + << std::setw(SRLZTN_FLOAT_WIDTH) << quat_rot[3] << "]" << std::endl; + } + if (scale != glm::vec3(1)) { + h->o << SRLZTN_POSROT_SCALE << "[" + << std::setw(SRLZTN_FLOAT_WIDTH) << scale[0] << "," + << std::setw(SRLZTN_FLOAT_WIDTH) << scale[1] << "," + << std::setw(SRLZTN_FLOAT_WIDTH) << scale[2] << "]" << std::endl; + } + return true; +} + +bool pke_deserialize_inst_pos(srlztn_deserialize_helper *h, glm::vec3 &pos, glm::quat &quat_rot, glm::vec3 &scale) { + const char *starting_char; + uint64_t prefix_len; + PK_STN_RES stn_res; + if (strstr(h->read_line, SRLZTN_POSROT_POS)) { + prefix_len = strlen(SRLZTN_POSROT_POS); + starting_char = strchr(h->read_line + prefix_len, '[') + 1; + assert(starting_char != nullptr); + char *pEnd = nullptr; + long index = 0; + do { + assert(index < 3); + stn_res = pk_stn_float_e(&pos[index], starting_char, &pEnd); + if (stn_res != PK_STN_RES_SUCCESS) return false; + starting_char = pEnd + 1; + ++index; + } while (*pEnd != ']'); + return true; + } + if (strstr(h->read_line, SRLZTN_POSROT_ROT)) { + prefix_len = strlen(SRLZTN_POSROT_ROT); + starting_char = strchr(h->read_line + prefix_len, '[') + 1; + assert(starting_char != nullptr); + char *pEnd = nullptr; + long index = 0; + do { + assert(index < 4); + stn_res = pk_stn_float_e(&quat_rot[index], starting_char, &pEnd); + if (stn_res != PK_STN_RES_SUCCESS) return false; + starting_char = pEnd + 1; + ++index; + } while (*pEnd != ']'); + return true; + } + if (strstr(h->read_line, SRLZTN_POSROT_SCALE)) { + prefix_len = strlen(SRLZTN_POSROT_SCALE); + starting_char = strchr(h->read_line + prefix_len, '[') + 1; + assert(starting_char != nullptr); + char *pEnd = nullptr; + long index = 0; + do { + assert(index < 3); + stn_res = pk_stn_float_e(&scale[index], starting_char, &pEnd); + if (stn_res != PK_STN_RES_SUCCESS) return false; + starting_char = pEnd + 1; + ++index; + } while (*pEnd != ']'); + return true; + } + return false; +} + +bool pke_serialize_instance(srlztn_serialize_helper *h, const CompInstance *comp) { + NULL_CHAR_ARR(handle_str, 23); + + EntityType *et = nullptr; + if (comp->grBindsHandle != GrBindsHandle_MAX) { + et = EntityType_FindByEntityHandle(ECS_GetGrBinds(comp->grBindsHandle)->entHandle); + } + + CompInstance c{}; + glm::vec3 pos; + glm::quat quat_rot; + glm::vec3 scale; + float mass; + PhysicsCollision collisionLayer; + PhysicsCollision collisionMask; + + { + mass = comp->bt.rigidBody->getMass(); + collisionLayer = PhysicsCollision{static_cast<PhysicsCollision_T>(comp->bt.rigidBody->getBroadphaseProxy()->m_collisionFilterGroup)}; + collisionMask = PhysicsCollision{static_cast<PhysicsCollision_T>(comp->bt.rigidBody->getBroadphaseProxy()->m_collisionFilterMask)}; + + btTransform trans; + comp->bt.motionState->getWorldTransform(trans); + BulletToGlm(trans.getOrigin(), pos); + BulletToGlm(trans.getRotation(), quat_rot); + BulletToGlm(comp->bt.rigidBody->getCollisionShape()->getLocalScaling(), scale); + } + + if (comp->instanceHandle != InstanceHandle_MAX) { + snprintf(handle_str, 22, "0x%08X 0x%08X", comp->instanceHandle.bucketIndex, comp->instanceHandle.itemIndex); + h->o << SRLZTN_INSTANCE_COMPONENT_ENTITY_HANDLE << handle_str << std::endl; + } + if (comp->entHandle != InstanceHandle_MAX) { + snprintf(handle_str, 22, "0x%08X 0x%08X", comp->entHandle.bucketIndex, comp->entHandle.itemIndex); + h->o << SRLZTN_INSTANCE_COMPONENT_HANDLE << handle_str << std::endl; + } + if (comp->uuid != pk_uuid_zed && comp->uuid != pk_uuid_max) { + h->o << SRLZTN_INSTANCE_COMPONENT_UUID << comp->uuid << std::endl; + } + if (et != nullptr) { + h->o << SRLZTN_INSTANCE_COMPONENT_ENTITY_TYPE_CODE << et->entityTypeCode.val << std::endl; + } + + pke_serialize_inst_pos(h, pos, quat_rot, scale); + + if (mass != 1) { + h->o << SRLZTN_INSTANCE_COMPONENT_MASS << mass << std::endl; + } + if (collisionLayer != c.physicsLayer) { + h->o << SRLZTN_INSTANCE_COMPONENT_COLLISION_LAYER << static_cast<PhysicsCollision_T>(collisionLayer) << std::endl; + } + if (collisionMask != c.physicsMask) { + h->o << SRLZTN_INSTANCE_COMPONENT_COLLISION_MASK << static_cast<PhysicsCollision_T>(collisionMask) << std::endl; + } + if (comp->collisionCallback.name[0] != '\0') { + h->o << SRLZTN_INSTANCE_COMPONENT_COLLISION_CB_SIGNATURE << comp->collisionCallback.name << std::endl; + } + + return true; +} + +bool pke_deserialize_instance(srlztn_deserialize_helper *h) { + uint64_t prefix_len; + PK_STN_RES stn_res; + NULL_CHAR_ARR(handle_str, 21); + EntityType *et_ptr = nullptr; + float mass; + InstPos inst_pos; + CompInstance comp{}; + glm::vec3 pos; + glm::quat quat_rot; + glm::vec3 scale; + comp.collisionCallback.name[0] = '\0'; + while (h->i.getline(h->read_line, h->read_line_len)) { + if (strstr(SRLZTN_OBJ_END, h->read_line)) { + if (et_ptr == nullptr) { + fprintf(stdout, "[Game::DeserializeInstance] Unknown EntityTypeCode, skipping instance.\n"); + break; + } + btVector3 bt_pos; + btQuaternion bt_quat; + GlmToBullet(pos, bt_pos); + GlmToBullet(quat_rot, bt_quat); + GlmToBullet(scale, inst_pos.scale); + inst_pos.mass = mass; + inst_pos.posRot.setIdentity(); + inst_pos.posRot.setOrigin(bt_pos); + inst_pos.posRot.setRotation(bt_quat); + if (et_ptr->createInstanceCallback.func != nullptr) { + /* TODO 2025-03-27 JCB + * We have not yet defined what the appropriate callback signature + * for creating an entity instance is. + * What should be passed as arguments? What would need to be passed + * that couldn't be accessed globally? + * Consider changing this callback to trigger after creating a + * generic instance, rather than *creating* it. + * Also consider just requiring a generic instance for any given + * EntityType. + */ + // typedef Entity_Base *CreateInst(); + // entity = reinterpret_cast<CreateInst*>(et_ptr->createInstanceCallback.func)(); + fprintf(stderr, "[%s] Attempted to call EntityType::createInstanceCallback and we have not yet defined a valid function signature", __FILE__); + } else { + EntityType_CreateGenericInstance(et_ptr, h->scene, &comp, &inst_pos); + // fprintf(stdout ,"[Game::DeserializeInstance] Debug: entTypeCode '%s' does not have a registered callback func to handle instance creation.\n", entTypeCode); + } + return true; + } + if (strstr(h->read_line, SRLZTN_INSTANCE_COMPONENT_ENTITY_HANDLE)) { + prefix_len = strlen(SRLZTN_INSTANCE_COMPONENT_ENTITY_HANDLE); + sprintf(handle_str, "%.10s%c%s", h->read_line + prefix_len, '\0', h->read_line + prefix_len + 10); + stn_res = pk_stn(&comp.entHandle.bucketIndex, handle_str, 16); + if (stn_res != PK_STN_RES_SUCCESS) return false; + stn_res = pk_stn(&comp.entHandle.itemIndex, handle_str + 11, 16); + if (stn_res != PK_STN_RES_SUCCESS) return false; + continue; + } + if (strstr(h->read_line, SRLZTN_INSTANCE_COMPONENT_HANDLE)) { + prefix_len = strlen(SRLZTN_INSTANCE_COMPONENT_HANDLE); + sprintf(handle_str, "%.10s%c%s", h->read_line + prefix_len, '\0', h->read_line + prefix_len + 10); + stn_res = pk_stn(&comp.instanceHandle.bucketIndex, handle_str, 16); + if (stn_res != PK_STN_RES_SUCCESS) return false; + stn_res = pk_stn(&comp.instanceHandle.itemIndex, handle_str + 11, 16); + if (stn_res != PK_STN_RES_SUCCESS) return false; + continue; + } + if (strstr(h->read_line, SRLZTN_INSTANCE_COMPONENT_UUID)) { + prefix_len = strlen(SRLZTN_INSTANCE_COMPONENT_UUID); + (h->read_line + prefix_len) >> comp.uuid ; + continue; + } + if (strstr(h->read_line, SRLZTN_INSTANCE_COMPONENT_ENTITY_TYPE_CODE)) { + prefix_len = strlen(SRLZTN_INSTANCE_COMPONENT_ENTITY_TYPE_CODE); + if (strlen(h->read_line + prefix_len) > 1) { + et_ptr = EntityType_FindByTypeCode(h->read_line + prefix_len); + } + continue; + } + if (strstr(h->read_line, SRLZTN_INSTANCE_COMPONENT_MASS)) { + prefix_len = strlen(SRLZTN_INSTANCE_COMPONENT_MASS); + stn_res = pk_stn(&mass, h->read_line + prefix_len); + if (stn_res != PK_STN_RES_SUCCESS) return false; + continue; + } + if (strstr(h->read_line, SRLZTN_INSTANCE_COMPONENT_COLLISION_LAYER)) { + prefix_len = strlen(SRLZTN_INSTANCE_COMPONENT_COLLISION_LAYER); + stn_res = pk_stn(&comp.physicsLayer, h->read_line + prefix_len, 10); + if (stn_res != PK_STN_RES_SUCCESS) return false; + continue; + } + if (strstr(h->read_line, SRLZTN_INSTANCE_COMPONENT_COLLISION_MASK)) { + prefix_len = strlen(SRLZTN_INSTANCE_COMPONENT_COLLISION_MASK); + stn_res = pk_stn(&comp.physicsMask, h->read_line + prefix_len, 10); + if (stn_res != PK_STN_RES_SUCCESS) return false; + continue; + } + if (strstr(h->read_line, SRLZTN_INSTANCE_COMPONENT_COLLISION_CB_SIGNATURE)) { + prefix_len = strlen(SRLZTN_INSTANCE_COMPONENT_COLLISION_CB_SIGNATURE); + strncpy(comp.collisionCallback.name, h->read_line + prefix_len, 16); + continue; + } + if (pke_deserialize_inst_pos(h, pos, quat_rot, scale)) { + continue; + } + } + return false; +} |
