I am using two math libraries in a game project. One is the GLM library and the other one is the math part of Box2D. Occasionally conversion between the two is necessary, like this:
b2Vec2 vec1(1.0f, 1.0f);
glm::vec2 vec2(vec1.x, vec1.y);
I am wondering if there is a better approach to do it more seamlessly, without editing either library?
I think that the conversion cannot be done implicitly without modifying the libraries.
However, to simplify your transformation code tou could implement simple transformation functions, something like:
inline glm::vec2 make_glmVec2(const b2Vec2 &v) {
return glm::vec2(v.x, v.y);
}
inline glm::vec3 make_glmVec3(const b2Vec3 &v) {
return glm::vec3(v.x, v.y, v.z);
}
If there is (almost) direct correspondence between types of those 2 libraries, you could even use a simpler name for all your transformation functions, like toGlm
and simple overload it for all the types you need:
inline glm::vec2 toGlm(const b2Vec2 &v) {
return glm::vec2(v.x, v.y);
}
inline glm::vec3 toGlm(const b2Vec3 &v) {
return glm::vec3(v.x, v.y, v.z);
}
Edit
I tried implementing a "proxy" class which could work as a bridge between your two classes coming from two libraries. The proxy class contains constructors and cast operators which allow you to create to and from those classes. Unfortunately, you need to call the constructor explicitly, otherwise the compiler will not even consider using this class:
//Library 1:
class Vec1 {
public:
int x;
int y;
Vec1(int _x, int _y) : x(_x), y(_y) {}
};
//Library 2:
class Vec2 {
public:
int e1;
int e2;
Vec2(int _x, int _y) : e1(_x), e2(_y) {}
};
//Your code
class VecProxy {
public:
int pxX;
int pxY;
VecProxy(const Vec1& v1) : pxX(v1.x), pxY(v1.y) {}
VecProxy(const Vec2& v2) : pxX(v2.e1), pxY(v2.e2) {}
operator Vec1() {return Vec1(pxX, pxY); }
operator Vec2() {return Vec2(pxX, pxY); }
};
int main() {
Vec1 v1(2,3);
Vec2 v2=VecProxy(v1);
Vec1 v3=VecProxy(v2);
}
Note that you can use the same name, no mater in which direction you are casting, which may be marginally better than my previous suggestion above. I don't think you can make the constructor being called implicitly.