L'arbre comme un tableau me semble être une victoire. Faites simplement une analyse en profondeur de votre hiérarchie et remplissez un tableau; lors du rembobinage de la récursivité, vous pouvez mettre à jour le parent avec l'index absolu vers l'enfant ou simplement le delta-from-me, et les enfants peuvent également stocker les index parents dans les deux cas. En effet, si vous utilisez des décalages relatifs, vous n'avez pas besoin de transporter l'adresse racine. Je suppose que la structure ressemblerait probablement à quelque chose comme
struct Transform
{
Matrix m; // whatever you like
int parent; // index or offset, you choose!
int sibling;
int firstchild;
};
... vous auriez donc besoin de nœuds pour savoir comment vous rendre chez vos frères et sœurs, car vous ne pouvez pas (facilement) avoir une structure de taille variable. Bien que je suppose que si vous avez utilisé des décalages d'octets au lieu de décalages de transformation, vous pouvez avoir un nombre variable d'enfants par transformation:
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
};
... alors il vous suffit de vous assurer que vous placez les Transformations successives au bon endroit.
Voici comment vous créez une arborescence totalement autonome avec des "pointeurs" enfants intégrés.
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);
}
(Si vous souhaitez stocker des emplacements relatifs, ajoutez simplement - currentLocation
les deux écritures "emplacement".)