// .mdatr —— Metin2 AttributeData 静态碰撞 / 高度网格资源。 // // The legacy client reads this file as a packed little-endian stream. Keep the // format layer independent from Godot so it can be used by the world loader and // by host-side validation tests alike. #pragma once #include #include #include #include namespace fmt { enum class AttributeCollisionType : std::uint32_t { Plane = 0, Box = 1, Sphere = 2, Cylinder = 3, Aabb = 4, Obb = 5, }; struct AttributeCollision { std::uint32_t type = 0; std::string name; std::array position = {0.0f, 0.0f, 0.0f}; // Plane/Cylinder use dimensions[0..1], the other supported primitives use // dimensions[0..2]. Values retain the source units (centimetres). std::array dimensions = {0.0f, 0.0f, 0.0f}; // x, y, z, w in the same order as the D3DXQUATERNION on disk. std::array quaternion = {0.0f, 0.0f, 0.0f, 1.0f}; }; struct AttributeHeight { std::string name; // The legacy file calls these vertices "primitives". They are a flat // triangle list: every consecutive three vertices form one triangle. std::vector> vertices; }; struct AttributeData { std::vector collisions; std::vector heights; }; // Parse the complete byte buffer. The parser rejects truncated data, unknown // primitive types and unreasonable counts rather than accepting a partial // collision resource. bool parse_attribute_data(const std::uint8_t *data, std::size_t size, AttributeData &out, std::string *err = nullptr); bool parse_attribute_data_file(const std::string &path, AttributeData &out, std::string *err = nullptr); } // namespace fmt