2016-04-01 13 views
1

Im Moment konvertiere ich die vec3-vec4, multipliziere es mit der Matrix, und es dann zu vec3 zurückgeworfenMultiply vec3 mit MAT4 GLM mit

Code:

glm::vec3 transformed = glm::vec3(matrix * glm::vec4(point, 0.0)) 

Es funktioniert, aber Ich denke, es ist nicht der beste Weg, es zu berechnen. Ist es möglich, einen mat4 auf einen vec3 anzuwenden, ohne ihn auf vec4 und zurück zu werfen?

Antwort

2

Wenn mit OpenGL arbeiten, ist es sehr ratsam, mit homogeneous coordinates zu bleiben. Für 3D-Raum sind dies 4D-Vektoren, wobei normalerweise das vierte Element gleich 1 ist. Wenn Sie dies tun, sind alle Ihre Berechnungen im 4-dimensionalen Raum, so dass keine Konvertierungen benötigt werden.

Beachten Sie auch, dass Sie in Ihrem Beispiel tatsächlich jede Übersetzung verlieren, die in der Transformationsmatrix aufgezeichnet wurde. Wenn Sie dies beibehalten möchten, müssen Sie 1 für das vierte Element und nicht für 0 verwenden.

Appendix F of the Red Book beschreibt, wie und warum homogene Koordinaten in OpenGL verwendet werden.

+0

Ich sehe '0.0' und' 1.0' auch an der 4. Koordinate. Welcher ist einer richtig? Die vierte Nullkoordinate scheint die richtige zu sein, zum Beispiel wenn ich die Länge eines Vektors berechne –

+0

In diesem Fall ist 1.0 korrekt, sonst verlierst du die vierte Spalte deiner Transformationsmatrix, die normalerweise den Übersetzungsteil der Transformation enthalten würde . – wich

+0

Die Länge des Vektors ist immer korrekt, da er auf dem Vektor und nicht auf dem 3D-Raum definiert ist, den Sie darstellen möchten. Wenn Sie die Entfernung zum Ursprung eines 3D-Punktes finden wollen, müssen Sie sqrt ((x^2 + y^2 + z^2)/w^2) berechnen, wobei der 4D-Vektor [x y z w] ist. Wie Sie sehen, ist 0 hier nicht sinnvoll, da Sie eine Division durch 0 erhalten würden, daher ist [x y z 0] kein Punkt im 3D-Raum in homogenen Koordinaten. – wich

1

mat4 ist eine 4 mal 4-Matrix, Sie benötigen also einen 4-dimensionalen Vektor, um ihn zu multiplizieren.

Die vierte Dimension für 3D Mathe wirklich nützlich ist, zwischen 3D-Raum Punkten (1) und 3D-Vektoren (0)

Hier sind fehle viele Betreiber zu unterscheiden, aber ich hoffe, dass Sie die Idee.

class point3 
{ 
public: 
    vec4 p; 

public: 
    point3(); 
    point3(const point3& rhs); 
    point3(const point3& rhs); 
    point3(float x, float y, float z); 
    point3& operator=(const point3&rhs); 
    vector3 operator-(const point3&rhs); 
    point3 operator+(const vector3&rhs); 
    point3& operator+=(const vector3&rhs); 
}; 

point3::point3():p.x(0), p.y(0), p.z(0), p.w(1) 
{ 

} 
point3::point3(const point3& rhs):p(rhs.p) 
{ 

} 
point3::point3(const point3& rhs):p(rhs.p) 
{ 

} 
point3::point3(float x, float y, float z):p.x(x), p.y(y), p.z(z), p.w(1) 
{ 

} 
point3& point3::operator=(const point3&rhs) 
{ 
    return (p=rhs.p); 
} 
vector3 point3::operator-(const point3&rhs) 
{ 
    vector3 result; 
    result.p=(p-rhs.p); 
    return result; 
} 
point3 point3::operator+(const vector3&rhs) 
{ 
    point3 result; 
    result.p=(p+rhs.p); 
    return result; 
} 
point3& point3::operator+=(const vector3&rhs) 
{ 
    p=(p+rhs.p); 
    return p; 
} 

class vector3 
{ 
public: 
    vec4 p; 

public: 
    vector3(); 
    vector3(const vector3& rhs); 
    vector3(const vector3& rhs); 
    vector3(float x, float y, float z); 
    vector3& operator=(const vector3&rhs); 
    vector3 operator-(const vector3&rhs); 
    point3 operator-(const point3&rhs); 
    point3 operator+(const point3&rhs); 
    vector3 operator+(const vector3&rhs); 
    vector3& operator+=(const vector3&rhs); 
}; 
vector3::vector3():p.x(0), p.y(0), p.z(0), p.w(0) 
{ 
} 
vector3::vector3(const vector3& rhs):p(rhs.p) 
{ 
} 
vector3::vector3(const vector3& rhs):p(rhs.p) 
{ 
} 
vector3::vector3(float x, float y, float z):p.x(x), p.y(y), p.z(z), p.w(0) 
{ 
} 
vector3& vector3::operator=(const vector3&rhs) 
{ 
    p=rhs.p; 
    return p; 
} 
vector3 vector3::operator-(const vector3&rhs) 
{ 
    vector3 result; 
    result.p=(p-rhs.p); 
    return result; 
} 
point3 vector3::operator-(const point3&rhs) 
{ 
    point3 result; 
    result.p=(p-rhs.p); 
    return result; 
} 
point3 vector3::operator+(const point3&rhs) 
{ 
    point3 result; 
    result.p=(p+rhs.p); 
    return result; 
} 
vector3 vector3::operator+(const vector3&rhs) 
{ 
    vector3 result; 
    result.p=(p+rhs.p); 
    return result; 
} 
vector3& vector3::operator+=(const vector3&rhs) 
{ 
    p=(p+rhs.p); 
    return p; 
} 
+0

Also sollte ich meine 3D-Vektoren in vec4 speichern? –

+0

Normalerweise mache ich einen Wrapper, zwei Klassen, point3 und vector3, die innen vec4 sind, und dann überladen die Operatoren, um richtig für jeden zu arbeiten, es ist nicht viel Arbeit, weil Sie im Grunde haben Sie die ganze harte Arbeit von Glm, –

+0

Wie Trivia getan , dass die 4. Dimension nur dazu benutzt wird, die gesamte Transformation in eine einzige Matrix zu verketten. Auf diese Weise wirkt sich die Übersetzungsmatrix nur auf 4D-Vektoren aus, die ihre w-Koordinate mit einem 1-Wert haben. –

Verwandte Themen