Der Tree-as-Array klingt für mich wie ein Gewinn. Führen Sie einfach eine Tiefenüberquerung Ihrer Hierarchie durch und füllen Sie ein Array aus. Beim Zurückspulen durch die Rekursion können Sie entweder das übergeordnete Element mit dem absoluten Index für das untergeordnete Element oder nur das Delta von mir aktualisieren, und die untergeordneten Indizes können die übergeordneten Indizes auch in beiden Richtungen speichern. Wenn Sie relative Offsets verwenden, müssen Sie die Stammadresse nicht mit sich herumtragen. Ich nehme an, dass die Struktur wahrscheinlich so aussehen würde
struct Transform
{
Matrix m; // whatever you like
int parent; // index or offset, you choose!
int sibling;
int firstchild;
};
... Sie benötigen also Knoten, um zu wissen, wie Sie auch zu Geschwistern gelangen, da Sie (einfach) keine Struktur mit variabler Größe haben können. Obwohl ich denke, wenn Sie Byte-Offsets anstelle von Transformations-Offsets verwenden, können Sie eine variable Anzahl von untergeordneten Elementen pro Transformation haben:
struct Transform
{
Matrix m; // whatever you like
int parent; // negative byte offest
int numchildren;
int child[0]; // can't remember if you put a 0 there or leave it empty;
// but it's an array of positive byte offsets
};
... dann müssen Sie nur noch sicherstellen, dass Sie aufeinanderfolgende Transformationen an der richtigen Stelle platzieren.
Hier erfahren Sie, wie Sie einen völlig eigenständigen Baum mit eingebetteten untergeordneten "Zeigern" erstellen.
int BuildTransforms(Entity* e, OutputStream& os, int parentLocation)
{
int currentLocation = os.Tell();
os.Write(e->localMatrix);
os.Write(parentLocation);
int numChildren = e->GetNumChildren();
os.Write(numChildren);
int childArray = os.Tell();
os.Skip(numChildren * sizeof(int));
os.AlignAsNecessary(); // if you need to align transforms
childLocation = os.Tell();
for (int i = 0; i < numChildren; ++i) {
os.Seek(childArray + (i * sizeof(int)));
os.Write(childLocation);
os.Seek(childLocation);
childLocation = BuildTransforms(e->GetChild(i), os, currentLocation);
}
return os.Tell();
}
void BuildTransforms(Entity* root)
{
OutputStream os;
BuildTransforms(root, os, -1, 0);
}
(Wenn Sie relative Speicherorte speichern möchten, fügen Sie einfach - currentLocation
die beiden "Standort" -Schreibvorgänge hinzu.)