El árbol como matriz me parece una victoria. Simplemente haga un recorrido profundo de su jerarquía y complete una matriz; al retroceder a través de la recursión, puede actualizar el elemento primario con el índice absoluto para el elemento secundario o solo el delta de mí, y los elementos secundarios también pueden almacenar los índices principales de cualquier manera. De hecho, si usa compensaciones relativas, entonces no necesita llevar la dirección raíz. Supongo que la estructura probablemente se vería algo así
struct Transform
{
Matrix m; // whatever you like
int parent; // index or offset, you choose!
int sibling;
int firstchild;
};
... por lo que necesitaría nodos para saber cómo llegar a los hermanos también, ya que no puede (fácilmente) tener una estructura de tamaño variable. Aunque supongo que si usaba desplazamientos de bytes en lugar de desplazamientos de transformación, podría tener un número variable de hijos por transformación:
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
};
... entonces solo necesita asegurarse de colocar las Transformaciones sucesivas en el lugar correcto.
Así es como se construye un árbol totalmente autónomo con "punteros" secundarios incrustados.
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 desea almacenar ubicaciones relativas, simplemente agregue - currentLocation
a las dos escrituras de "ubicación").