diff --git a/server/gameserver/mapcollider.cc b/server/gameserver/mapcollider.cc index 90bf5aac..e15b037b 100644 --- a/server/gameserver/mapcollider.cc +++ b/server/gameserver/mapcollider.cc @@ -5,9 +5,113 @@ namespace mc { + static void Vec3_Read(glm::vec3& v, std::shared_ptr xobj) + { + v.x = xobj->At("x")->AsXValue().GetDouble(); + v.y = xobj->At("y")->AsXValue().GetDouble(); + v.z = xobj->At("z")->AsXValue().GetDouble(); + } + + static void Quat_Read(glm::quat& v, std::shared_ptr xobj) + { + v.x = xobj->At("x")->AsXValue().GetDouble(); + v.y = xobj->At("y")->AsXValue().GetDouble(); + v.z = xobj->At("z")->AsXValue().GetDouble(); + v.w = xobj->At("w")->AsXValue().GetDouble(); + } + + static void Bounds_Read(Bounds& v, std::shared_ptr xobj) + { + Vec3_Read(v.center, xobj->At("center")); + Vec3_Read(v.size, xobj->At("size")); + } + + void Transform::Read(std::shared_ptr xobj) + { + Vec3_Read(local_position, xobj->At("local_position")); + Quat_Read(local_rotation, xobj->At("local_rotation")); + Vec3_Read(local_scale, xobj->At("local_scale")); + } + + void Collider::Read(std::shared_ptr xobj) + { + enabled = xobj->At("enabled")->AsXValue(); + is_trigge = xobj->At("is_trigge")->AsXValue(); + Bounds_Read(bounds, xobj->At("bounds")); + } + + void BoxCollider::Read(std::shared_ptr xobj) + { + Collider::Read(xobj); + auto box_xobj = xobj->At("box"); + Vec3_Read(center, box_xobj->At("center")); + Vec3_Read(size, box_xobj->At("size")); + } + + void MeshCollider::Read(std::shared_ptr xobj) + { + Collider::Read(xobj); + auto mesh_xobj = xobj->At("mesh"); + { + auto verts_xobj = mesh_xobj->At("vertices"); + for (int i = 0; i < verts_xobj->Size(); ++i) { + glm::vec3 v; + Vec3_Read(v, verts_xobj->At(i)); + mesh.vertices.push_back(v); + } + } + { + auto trig_xobj = mesh_xobj->At("triangles"); + for (int i = 0; i < trig_xobj->Size(); ++i) { + mesh.triangles.push_back(trig_xobj->At(i)->AsXValue().GetDouble()); + } + } + Bounds_Read(mesh.bounds, mesh_xobj->At("mesh")->At("bounds")); + } + void ColliderNode::Read(std::shared_ptr xobj) { name = xobj->At("name")->AsXValue().GetString(); + transform.Read(xobj->At("transform")); + { + auto colliders_arr = xobj->At("colliders"); + for (int i = 0; i < colliders_arr->Size(); ++i) { + auto collider_union_xobj = colliders_arr->At(i); + switch (collider_union_xobj->At("type")->AsXValue().GetInt()) { + case kBoxCollider: + { + Collider* c = new BoxCollider(); + c->Read(collider_union_xobj); + colliders.push_back(c); + } + break; + case kMeshCollider: + { + Collider* c = new MeshCollider(); + c->Read(collider_union_xobj); + colliders.push_back(c); + } + break; + default: + { + A8_ABORT(); + break; + } + } + } + } + { + auto childs_arr = xobj->At("childs"); + for (int i = 0; i < childs_arr->Size(); ++i) { + ColliderNode* node = new ColliderNode(); + node->parent = this; + node->Read(childs_arr->At(i)); + if (childs.find(node->name) != childs.end()) { + A8_ABORT(); + } + childs[node->name] = node; + } + } } } diff --git a/server/gameserver/mapcollider.h b/server/gameserver/mapcollider.h index 29cec972..5fb06f1d 100644 --- a/server/gameserver/mapcollider.h +++ b/server/gameserver/mapcollider.h @@ -5,6 +5,14 @@ namespace mc { + + enum ColliderType_e + { + kNoneCollider = 0, + kBoxCollider = 1, + kMeshCollider = 2 + }; + struct Bounds { glm::vec3 center = glm::vec3(0.0f, 0.0f, 0.0f); @@ -16,6 +24,7 @@ namespace mc glm::vec3 local_position = glm::vec3(0.0f, 0.0f, 0.0f); glm::quat local_rotation = glm::quat(0.0f, 0.0f, 0.0f, 0.0f); glm::vec3 local_scale = glm::vec3(0.0f, 0.0f, 0.0f); + void Read(std::shared_ptr xobj); }; struct Mesh @@ -27,26 +36,32 @@ namespace mc struct Collider { + int type = kNoneCollider; bool enabled = false; bool is_trigge = false; Bounds bounds; + + virtual void Read(std::shared_ptr xobj); }; struct MeshCollider : public Collider { Mesh mesh; + virtual void Read(std::shared_ptr xobj) override; }; struct BoxCollider : public Collider { glm::vec3 center = glm::vec3(0.0f, 0.0f, 0.0f); glm::vec3 size = glm::vec3(0.0f, 0.0f, 0.0f); + virtual void Read(std::shared_ptr xobj) override; }; struct ColliderNode { ColliderNode* parent = nullptr; std::string name; + Transform transform; std::vector colliders; std::map childs;