summaryrefslogtreecommitdiff
path: root/src/serialization-component.cpp
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-04-02 20:46:41 -0400
committerJonathan Bradley <jcb@pikum.xyz>2025-04-02 20:46:41 -0400
commita02c7589c6c9e902c59a632aa650635336fe648c (patch)
tree8ec4800ff9f9effbd9141e02131123448679bc93 /src/serialization-component.cpp
parentfad302f7db146a78900f9b21dbbcd97761093c1b (diff)
pke: checkpoint: major serialization refactor
Diffstat (limited to 'src/serialization-component.cpp')
-rw-r--r--src/serialization-component.cpp256
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;
+}