La struttura ad albero mi sembra una vittoria. Fai solo un attraversamento approfondito della tua gerarchia e compila un array; quando riavvolgi attraverso la ricorsione puoi aggiornare il genitore con l'indice assoluto al figlio o solo il delta-da-me, e anche i figli possono memorizzare gli indici del genitore in entrambi i modi. Infatti, se si utilizzano offset relativi, non è necessario portare in giro l'indirizzo di root. Suppongo che la struttura probabilmente assomiglierebbe a qualcosa di simile
struct Transform
{
Matrix m; // whatever you like
int parent; // index or offset, you choose!
int sibling;
int firstchild;
};
... quindi avresti bisogno di nodi per sapere come arrivare anche ai fratelli poiché non puoi (facilmente) avere una struttura di dimensioni variabili. Anche se suppongo che se hai utilizzato offset di byte anziché offset di trasformazione, potresti avere un numero variabile di figli per trasformazione:
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
};
... allora devi solo assicurarti di mettere le trasformazioni successive nel posto giusto.
Ecco come creare un albero totalmente autonomo con "puntatori" figlio incorporati.
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);
}
(Se si desidera memorizzare posizioni relative, è sufficiente aggiungere - currentLocation
alle due scritture "posizione".)