Speicherposition in vector: Unveränderbarkeit garantieren?



  • Hi,

    Ich bastel wieder Mal.

    Also ich habe einen vector von Matrizen (eigene Klasse). Die Manipulation der Matrizen geschieht allerdings durch eine andere Klasse Bone. Die Manipulation geschieht dadurch, dass der Bone durch einen Zeiger die jeweilige Matrix kennt. Problem: vector braucht nach einem push_back mehr Speicher und organisiert daher u.U. auch die Speicheradressen um, um die Datenlinearität zu gewährleisten (ich schätze Mal, dass das der Grund ist).

    Wenn ich vor der Zuweisung der Adressen der Matrizen (die im vector liegen) ein reserve auf den vector mache, kann ich dann davon ausgehen, dass sich die Speicheradressen nicht ändern? Ein resize ginge notfalls auch. Oder kann der vector trotzdem noch was umkloppen?

    Ich hoffe, mein Problem ist verständlich geworden, sonst gibt's etwas Code. 🙂

    Viele Grüße und danke wieder Mal im Voraus!

    PS: Ist hier ein Kritiker meines Mappings? Es geht um Performanceoptimierung, ich bräuchte sonst viele Kopien. Wenn jemand weiß, wie das hübscher geht, und das auch noch hier mitteilt, freue ich mich. 😉



  • std::vector<EigenMatrix> -> du hast ein Problem
    std::vector<EigenMatrix*> -> kein Problem
    std::vector<EigenMatrix> alle(500); -> jetzt haste schon 500 drin (default konstruiert) ,da könntest du Probleme bekommen wenn du jetzt was push_back()'st, wenn du da aber mit alle[0..499] arbeitest, eher kein Problem ... usw.
    std::vector<EigenMatrix> alle; alle.reserve(500); -> bis 500 dürftest du kein Problem bekommen, danach wird umkopiert und du kriegst welche ...
    std::vector<EigenMatrix> alle; alle.resize(500); -> jetzt haste schon 500 drin (default konstruiert) ,da könntest du Probleme bekommen wenn du jetzt was push_back()'st, wenn du da aber mit alle[0..499] arbeitest, eher kein Problem ... usw.



  • An Masse hat das meine Frage mehr als beantwortet. An Sicherheit... "dürfte keine Probleme bekommen"? Ist das sicher gestellt oder nicht? 😉

    Übrigens habe ich keinen Zeiger drin, sonst wär das Problem ja kein Problem.



  • Dann gib dem Bone nur den Index und nicht die Speicheradresse.



  • Dann hat der Bone aber ne Abhängigkeit von dem vector, der in einer anderen Klasse liegt und somit eine Abhängigkeit zu dieser. Zirkuläre Abhängigkeiten sind ja auch nicht wirklich schön und so funktioniert mein Ansatz immerhin.

    Oder ist es nicht sicher gestellt?



  • Eisflamme schrieb:

    Dann hat der Bone aber ne Abhängigkeit von dem vector, der in einer anderen Klasse liegt und somit eine Abhängigkeit zu dieser.

    Und wenn der Bone einen Zeiger auf ein Element in diesem vector hat dann ist er nicht von selbigem abhängig? Und noch ne ganz andre Frage: Warum hat ein Bone überhaupt einen Zeiger auf eine Matrix? Was repräsentiert diese Matrix genau und inwiefern optimierst du damit die Performance!?



  • Ich habe eine Speicherabhängigkeit, aber meine Boneklasse muss meine Meshklasse (die aggregiert Bones) nicht kennen, das ist ja nochmal ein Unterschied.

    Mein VertexShader benötigt zum VertexSkinning ein Array von float*, welche je 12 Einheiten eine Matrix repräsentieren. Diese Matrizen ändert sich in jedem Keyframe, sodass die Animation anders aussieht.

    Jetzt gehört zu einem Bone eine Offsetmatrix, die vom Mesh- ins Bone-Koordinatensystem übeträgt, und ein paar andere Eigenschaften. Daraus kann die Boneinstanz eine resultierende Matrix errechnen, welche dann schlussendlich für meinen Vertexshader relevant ist. Ich kann die Informationen aber nicht einfach nur in der Boneklasse speichern, weil diese natürlich noch mehr Informationen hat.

    Mein Mesh aggregiert jetzt verschiedene Bones. Das Mesh ist auch dafür zuständig, das float* Array an meinen Vertexshader zu übergeben.

    Die inperformante Variante liegt darin, über alle Bones zu gehen, die jeweilige resultierende Matrix zu extrahieren und die 12 Elemente in ein Array zu schreiben, sodass ich am Ende das Array habe.

    Die performante Variante liegt darin, dass die einzelnen Bones das Resultat einfach direkt an die Speicherposition schreiben, sodass das zusammenhängende Array ohne zusätzliche Kopie besteht -> kein unnötiger Kopiervorgang.



  • Also bei mir funktioniert das normalerweise so in der Art: Es gibt ein AnimatedModel das ein lineares Array aus Joints hat in denen eben die Strukur des Skelettes (Parent<->Child Relationships etc.) gespeichert ist. Dann gibt es eine beliebige Anzahl von Animation Objekten die eben eine Animation repräsentieren und die entsprechenden Daten (Keyframes, etc.) speichern. Dann gibt es AnimationInstance Objekte die eine laufende Animation darstellen und dabei eben die Daten (Keyframes) einer Animation verwenden. Eine AnimationInstance schreibt mir für einen Zeitpunkt die interpolierten Matritzen aller Joints in ein Array das ich ihr geb und sorgt dafür dass das AnimatedModel mit seinen Joints drüberlauft und eben entsprechend der Hierarchie die Matritzen updated. Raus kommt ein Array mit den Matritzen für alle Joints, kann man natürlich als AnimationState kapseln oder was weiß ich. Dem AnimatedModel wird beim Rendern einfach ein solches Array mit den Matritzen für alle Joints übergeben welches selbiges einfach 1:1 an den VertexShader weiterreichen kann. Das funktioniert so eigentlich ganz gut und ganz ohne dass irgendwo was unnötig kopiert wird...



  • Nagut. Nur wenn bei mir das alles funktioniert und sicher gestellt ist, dass vector nicht ohne push_back über reserve-Grenzen hinaus was verschiebt, klappt das ja auch ganz gut. Ich könnt jetzt alles komplett ummodellieren, aber ohne Mehrwert wäre das höchst unökonomisch. 🙂



  • Dann würd ich wie schon vorgeschlagen wurde einfach Indices statt Pointer verwenden und das Problem verschwindet. Die Abhängigkeit der beiden Klassen hast du so oder so, auch wenn sichs bei der Pointer Variante vielleicht nicht ganz direkt im Code widerpiegelt...


Anmelden zum Antworten