2010-06-08 24 views
10

Actualmente estoy trabajando en un "motor" de juegos que necesita mover valores entre un motor 3D, un motor de física y un lenguaje de scripting. Como necesito aplicar vectores del motor de física a objetos 3D muy a menudo y quiero controlar tanto el 3D como los objetos físicos a través del sistema de scripting, necesito un mecanismo para convertir un vector de un tipo (por ejemplo, vector3d<float>) a un vector del otro tipo (por ejemplo, btVector3). Desafortunadamente no puedo hacer suposiciones sobre cómo se estructuran las clases/estructuras, por lo que un simple reinterpret_cast probablemente no funcionará.Funciones de conversión no miembro; Casting de diferentes tipos, p. Vector DirectX para vector OpenGL

Entonces la pregunta es: ¿Hay algún tipo de 'estática' Método/no miembro de fundición para lograr básicamente esto:

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

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

En este momento esto no va a compilar ya que los operadores tienen que ser de fundición métodos miembros . (error C2801: 'operator foo' must be a non-static member)

Respuesta

5

sugeriría escribirlos como un par de funciones libres (es decir, no se preocupe por lo que los convierte 'operadores'):

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

Gracias Adam! Esto es lo que hago ahora. Me pregunto si es posible hacer que el compilador haga el trabajo. Algo así como "si quieres ir allí, ve allí primero". – sunside

+0

Entiendo. Aunque esta solución me parece más directa, agregué otra posibilidad en otra respuesta. –

+0

Ir con funciones gratuitas. Las conversiones implícitas generalmente son un mal camino, incluso cuando son posibles. – jalf

1

su declaración en la pregunta es correcta. El operador de conversión de tipo debe ser un miembro no estático. Si realmente quiere la semántica de tipo de conversión, se podría extender cada una de esas clases para su uso en el código de aplicación:

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

Los nombres son un poco prolijo, pero esperemos que la intención es clara.

La herencia pública significa que debe poder usar instancias de estas clases de la misma manera que la clase base, excepto que serán asignables y editables entre sí. Por supuesto, esto combina las dos clases, pero eso puede ser aceptable, ya que parece que eso es lo que tu aplicación intenta hacer de todos modos.

+0

Gracias de nuevo! Acepté el otro como la respuesta.Este se siente más natural, pero no siempre es posible modificar el código de la biblioteca (aunque en este caso lo es) ... y así sucesivamente. :) – sunside

2

También es posible usar una clase contenedora de plantilla como:

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

Uso:

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)); 
Cuestiones relacionadas