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

前端 未结 3 1546
礼貌的吻别
礼貌的吻别 2020-12-20 12:33

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

相关标签:
3条回答
  • 2020-12-20 13:03

    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));
    }
    
    0 讨论(0)
  • 2020-12-20 13:04

    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.

    0 讨论(0)
  • 2020-12-20 13:21

    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));
    
    0 讨论(0)
提交回复
热议问题