How to Serialize glm::vec3 with boost

Viewed 229

I am trying to serialize a glm::vec3 variable in my Camera class.

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()
}

Now i am creating another header file with the name of BoostGlm.h with the following content.

#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);
        }
    }
}

My question is now how do i make boost understand how to serialize glm::vec3 , where do i need to add this file.

1 Answers

Those are not the same types:

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

Also, you didn't add a serialize function (e.g. using split_free or BOOST_SERIALIZATION_SPLIT_FREE).

So simply add:

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);
    }
}

Anywhere before the instantiation of the serializing code.

Full Demo

//#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;
    }
}

Prints

<?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
Related