如何使用 boost 序列化 glm::vec3

How to Serialize glm::vec3 with boost

我正在尝试在我的相机 class 中序列化一个 glm::vec3 变量。

class Camera
{
   glm::vec3 Position;
   float Yaw;

private:
    friend class boost::serialization::access;
    template<typename Archive>
    void save(Archive& ar, const unsigned int version) const {
        ar & Position & Yaw;
    }

    template<typename Archive>
    void load(Archive& ar, const unsigned int version) {
          ar & Position & Yaw;
    }
    BOOST_SERIALIZATION_SPLIT_MEMBER()
}

现在我正在创建另一个名为 BoostGlm.h 的头文件,内容如下。

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/split_free.hpp>
namespace boost
{
    namespace serialization
    {
        template<class Archive>
        void save(Archive & ar, glm::tvec3<float>& vec, const unsigned int version)
        {
            ar & boost::serialization::make_nvp("x", vec.x);
            ar & boost::serialization::make_nvp("y", vec.y);
            ar & boost::serialization::make_nvp("z", vec.z);
        }


        template<class Archive>
        void load(Archive & ar, glm::tvec3<float>& vec, const unsigned int version)
        {
            ar & boost::serialization::make_nvp("x", vec.x);
            ar & boost::serialization::make_nvp("y", vec.y);
            ar & boost::serialization::make_nvp("z", vec.z);
        }
    }
}

我现在的问题是如何让 boost 理解如何序列化 glm::vec3 ,我需要在哪里添加这个文件。

它们不是同一类型:

static_assert(not std::is_same_v<glm::tvec1<float>, glm::vec3>);

此外,您没有添加 serialize 函数(例如使用 split_freeBOOST_SERIALIZATION_SPLIT_FREE)。

所以只需添加:

namespace boost::serialization {
    template <typename Ar>
    void serialize(Ar& ar, glm::vec3& v, unsigned /*unused*/) {
        ar & make_nvp("x", v.x) & make_nvp("y", v.y) & make_nvp("z", v.z);
    }
}

序列化代码实例化之前的任何位置。

完整演示

//#include <boost/spirit/home/x3.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/nvp.hpp>
#include <glm/glm.hpp>

namespace boost::serialization {
    template <typename Ar>
    void serialize(Ar& ar, glm::vec3& v, unsigned /*unused*/) {
        ar & make_nvp("x", v.x) & make_nvp("y", v.y) & make_nvp("z", v.z);
    }
}

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <iostream>

int main()  {
    auto constexpr inf = std::numeric_limits<double>::infinity();
    auto constexpr nan = std::numeric_limits<double>::quiet_NaN();

    glm::vec3 a{1,2e8,3}, b{-inf, +inf, nan};

    {
        boost::archive::xml_oarchive oa(std::cout);
        oa << BOOST_NVP(a) << BOOST_NVP(b);
    }
    std::cout << "\n-----\n";

    {
        boost::archive::text_oarchive oa(std::cout);
        oa << a << b;
    }
}

版画

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="18">
<a class_id="0" tracking_level="0" version="0">
    <x>1.000000000e+00</x>
    <y>2.000000000e+08</y>
    <z>3.000000000e+00</z>
</a>
<b>
    <x>-inf</x>
    <y>inf</y>
    <z>nan</z>
</b>
</boost_serialization>


-----
22 serialization::archive 18 0 0 1.000000000e+00 2.000000000e+08 3.000000000e+00 -inf inf nan