Cây như một mảng âm thanh như một chiến thắng với tôi. Chỉ cần thực hiện một giao dịch theo chiều sâu của hệ thống phân cấp của bạn và điền vào một mảng; khi tua lại qua đệ quy, bạn có thể cập nhật cha mẹ với chỉ số tuyệt đối cho con hoặc chỉ là delta-from-me, và con cái cũng có thể lưu trữ các chỉ số cha mẹ. Thật vậy, nếu bạn sử dụng offset tương đối thì bạn không cần phải mang theo địa chỉ gốc. Tôi cho rằng cấu trúc có thể sẽ trông giống như
struct Transform
{
Matrix m; // whatever you like
int parent; // index or offset, you choose!
int sibling;
int firstchild;
};
... vì vậy bạn cũng cần các nút để biết cách đến với anh chị em vì bạn không thể (dễ dàng) có cấu trúc kích thước thay đổi. Mặc dù tôi đoán rằng nếu bạn đã sử dụng offset byte thay vì offset offset, bạn có thể có số lượng con thay đổi trên mỗi biến đổi:
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
};
... Sau đó, bạn chỉ cần đảm bảo rằng bạn đặt Biến đổi liên tiếp vào đúng chỗ.
Đây là cách bạn xây dựng một cây hoàn toàn khép kín với "con trỏ" được nhúng.
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);
}
(Nếu bạn muốn lưu trữ các vị trí tương đối, chỉ cần thêm - currentLocation
vào hai "vị trí" ghi.)