Non-member conversion functions; Casting different types, e.g. DirectX vector to OpenGL vector

元气小坏坏 提交于 2020-03-11 18:13:30

问题


I am currently working on a game "engine" that needs to move values between a 3D engine, a physics engine and a scripting language. Since I need to apply vectors from the physics engine to 3D objects very often and want to be able to control both the 3D, as well as the physics objects through the scripting system, I need a mechanism to convert a vector of one type (e.g. vector3d<float>) to a vector of the other type (e.g. btVector3). Unfortunately I can make no assumptions on how the classes/structs are laid out, so a simple reinterpret_cast probably won't do.

So the question is: Is there some sort of 'static'/non-member casting method to achieve basically this:

vector3d<float> operator vector3d<float>(btVector3 vector) {
    // convert and return
}

btVector3 operator btVector3(vector3d<float> vector) {
    // convert and return
}

Right now this won't compile since casting operators need to be member methods. (error C2801: 'operator foo' must be a non-static member)


回答1:


I would suggest writing them as a pair of free functions (i.e. don't worry about making them 'operators'):

vector3d<float> vector3dFromBt(const btVector3& src) {
    // convert and return
}

btVector3 btVectorFrom3d(const vector3d<float>& src) {
    // convert and return
}

void f(void)
{
  vector3d<float> one;   
// ...populate...   
  btVector3 two(btVectorFrom3d(one));    
// ...
  vector3d<float> three(vector3dFromBt(two));
}



回答2:


You could also use a templated wrapper class like:

template<class V>
class vector_cast {};

template<>
class vector_cast<vector3d> {
  const vector3d& v;

public:

  vector_cast(const vector3d& v) : v(v) {};

  operator vector3d () const {
    return vector3d(v);
  }

  operator btVector3 () const {
    // convert and return
  }
};

template<>
class vector_cast<btVector3> {
  const btVector3& v;

public:

  vector_cast(const btVector3& v) : v(v) {};

  operator btVector3 () const {
    return btVector3(v);
  }

  operator vector3d () const {
    // convert and return
  }
};

Usage:

void set_origin(btVector3 v);

// in your code:

vector3d v;
// do some fancy computations
set_origin(vector_cast(v));

// --- OR the other way round --- //

void set_velocity(vector3d v);

// in your code:

btVector3 v;
// do some other computations
set_velocity(vector_cast(v));



回答3:


Your statement in the question is correct. The type conversion operator needs to be a non-static member. If you really want conversion-type semantics, you could extend each of those classes for use in your application code:

// header:
class ConvertibleVector3d;

ConvertibleBtVector : public btVector3
{
  operator ConvertibleVector3d() const;
}

ConvertibleVector3d : public vector3d<float>
{
  operator ConvertibleBtVector() const;
}

//impl:
ConvertibleBtVector::operator ConvertibleVector3d() const
  {
    ConvertibleVector3d retVal;
// convert this into retVal...
    return retVal;
  }

ConvertibleVector3d::operator ConvertibleBtVector() const;
  {
    ConvertibleBtVector retVal;
// convert this into retVal...
    return retVal;
  }

void f(void)
{
  ConvertibleVector3d one;   
// ...populate...   
  ConvertibleBtVector two(one);    
// ...
  ConvertibleVector3d three;
  three = two;
}

The names are a bit verbose but hopefully the intent is clear.

The public inheritance means you should be able to use instances of these classes in the same way as the base class, except they will be assignable and constructable from each other. Of course this couples the two classes, but that may be acceptable since it sounds like that's what your application intends to do anyway.



来源:https://stackoverflow.com/questions/2999506/non-member-conversion-functions-casting-different-types-e-g-directx-vector-to

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!