Optymalizacja klasy przechowującej transformacje trójwymiarowego obiektu

0

Napisałem prostą klasę przechowującą transformacje trójwymiarowego obiektu, ale nie jestem pewien co do jej szybkości działania.
Chciałbym znaleźć najlepszy sposób na przechowywanie transformacji (rotacja mnie irytuje najbardziej) i nie chcę odświeżać macierzy transformacji co każdą klatkę obrazu.
Na razie przechowuję rotację w formacie ZXY Euler i obliczam transformację obiektu za każdym jej pobraniem przez jednostkę zewnętrzną, co może znacznie obniżyć efektywność programu przy wyświetlaniu statycznej sceny 3D.

Naprawdę proszę o pomoc w optymalizacji, bo nie chcę tracić czasu na nieudane pomysły...

Node.h:

#ifndef NODE_H
#define NODE_H

/**
class Node - Stores node's 3D transformation and it's family informations
Rotation is stored as ZXY Euler angles set.
**/

class Node {
private:
    Node* parent;
    std::list<Node*> children;

    glm::mat4 transform;
    glm::vec3 translation;
    glm::vec3 rotation;
    glm::vec3 scale;
    bool visible;
public:
    Node() {
        parent = nullptr;
        children.clear();
        transform = glm::mat4(1.0f);
        translation = glm::vec3(0.0f);
        rotation = glm::vec3(0.0f);
        scale = glm::vec3(0.0f);
        visible = true;
    }
    void setParent(Node* parent) {
        this->parent = parent;
        parent->children.push_back(this);
    }
    Node* getParent() {
        return parent;
    }
    void addChild(Node* child) {
	    children.push_back(child);
		child->parent = this;
    }
    std::list<Node*> getChildren() {
        return children;
    }
    void updateTransform() {
        transform =
        glm::translate(
            glm::rotate(
                glm::rotate(
                    glm::rotate(
                        glm::scale(
                            glm::mat4(1.0), scale
                        ), rotation.z, glm::vec3(0,0,1)
                    ), rotation.x, glm::vec3(1,0,0)
                ), rotation.y, glm::vec3(0,1,0)
            ), translation
        );
    }
    void setTransform(glm::mat4 transform) {
        this->transform = transform;
    }
    glm::mat4 getTransform() {
        updateTransform();
        return transform;
    }
    glm::mat4 getGlobalTransform() {
        updateTransform();
        if(parent)
            return parent->getGlobalTransform() * transform;
        return transform;
    }
    void setTranslation(glm::vec3 translation) {
        this->translation = translation;
    }
    glm::vec3 getTranslation() {
        return translation;
    }
    void setRotation(glm::vec3 rotation) {
        this->rotation = rotation;
    }
    glm::vec3 getRotation() {
        return rotation;
    }
    void setScale(glm::vec3 scale) {
        this->scale = scale;
    }
    glm::vec3 getScale() {
        return scale;
    }
    void setVisible(bool visible) {
        if(parent && !parent->visible)
            return;
        this->visible = visible;
        for(Node* child:children)
            child->visible = visible;
    }
    bool getVisible() {
        return visible;
    }
};

#endif
0

glm::mat4 już w sobie zawiera wszystkie możliwe transformacje liniowe, więc po kiego grzyba ci pola glm::vec3: translation, rotation, scale?

0

Wiem to, ale (1) nie wiem jak "wyciągnąć" dane transformacji, aby zwrócić je jako 3-wymiarowe wektory i (2) jak ustawić np. skalę po nadaniu rotacji bez budowania macierzy od nowa.

0

translation wyciągasz bez problemu, bo to są po prostu elementy macierzy 4x4
rotację i skalę można odzyskać licząc wartości własne macierzy 3x3.

0

A w jaki sposób ustawisz rotację po skalowaniu / skalę po obróceniu? Bez budowy macierzy od nowa oczywiście.

1 użytkowników online, w tym zalogowanych: 0, gości: 1