mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
[scene] Track hierarchies instead of root transforms
The root transform of each hierarchy can be extracted from the first transform of the list in the hierarchy, so no information is lost. The main reason for the change is I discovered (obvious in hindsight) that deleting root transforms was O(n) due to keeping them in an array, thus the use of a linked list (I don't expect a hierarchy to be in more than one such list), and I didn't want the transforms to be in a linked list.
This commit is contained in:
parent
7906db5a37
commit
6ec8e29429
6 changed files with 18 additions and 36 deletions
|
@ -45,6 +45,9 @@
|
|||
#define null_transform (~0u)
|
||||
|
||||
typedef struct hierarchy_s {
|
||||
struct hierarchy_s *next;
|
||||
struct hierarchy_s **prev;
|
||||
struct scene_s *scene;
|
||||
xformset_t transform;
|
||||
entityset_t entity;
|
||||
uint32set_t childCount;
|
||||
|
@ -61,7 +64,6 @@ typedef struct hierarchy_s {
|
|||
vec4fset_t localScale;
|
||||
vec4fset_t worldRotation;
|
||||
vec4fset_t worldScale;
|
||||
struct scene_s *scene;
|
||||
} hierarchy_t;
|
||||
|
||||
hierarchy_t *Hierarchy_New (struct scene_s *scene, int createRoot);
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
typedef struct scene_s {
|
||||
struct scene_resources_s *const resources;
|
||||
xformset_t roots;
|
||||
struct hierarchy_s *hierarchies;
|
||||
} scene_t;
|
||||
|
||||
scene_t *Scene_NewScene (void);
|
||||
|
|
|
@ -13,7 +13,4 @@ typedef struct scene_resources_s {
|
|||
PR_RESMAP (transform_t) transforms;
|
||||
} scene_resources_t;
|
||||
|
||||
void scene_add_root (scene_t *scene, transform_t *transform);
|
||||
void scene_del_root (scene_t *scene, transform_t *transform);
|
||||
|
||||
#endif//__scn_internal_h
|
||||
|
|
|
@ -403,6 +403,13 @@ Hierarchy_New (scene_t *scene, int createRoot)
|
|||
hierarchy_t *hierarchy = PR_RESNEW_NC (res->hierarchies);
|
||||
hierarchy->scene = scene;
|
||||
|
||||
hierarchy->prev = &scene->hierarchies;
|
||||
hierarchy->next = scene->hierarchies;
|
||||
if (scene->hierarchies) {
|
||||
scene->hierarchies->prev = &hierarchy->next;
|
||||
}
|
||||
scene->hierarchies = hierarchy;
|
||||
|
||||
size_t grow = 16;
|
||||
DARRAY_INIT (&hierarchy->transform, grow);
|
||||
DARRAY_INIT (&hierarchy->entity, grow);
|
||||
|
@ -432,6 +439,11 @@ Hierarchy_New (scene_t *scene, int createRoot)
|
|||
void
|
||||
Hierarchy_Delete (hierarchy_t *hierarchy)
|
||||
{
|
||||
if (hierarchy->next) {
|
||||
hierarchy->next->prev = hierarchy->prev;
|
||||
}
|
||||
*hierarchy->prev = hierarchy->next;
|
||||
|
||||
scene_resources_t *res = hierarchy->scene->resources;
|
||||
for (size_t i = 0; i < hierarchy->transform.size; i++) {
|
||||
PR_RESFREE (res->transforms, hierarchy->transform.a[i]);
|
||||
|
|
|
@ -54,8 +54,6 @@ Scene_NewScene (void)
|
|||
res = calloc (1, sizeof (scene_resources_t));
|
||||
*(scene_resources_t **)&scene->resources = res;
|
||||
|
||||
DARRAY_INIT (&scene->roots, 16);
|
||||
|
||||
return scene;
|
||||
}
|
||||
|
||||
|
@ -70,8 +68,6 @@ Scene_DeleteScene (scene_t *scene)
|
|||
}
|
||||
free (res->entities._map);
|
||||
|
||||
DARRAY_CLEAR (&scene->roots);
|
||||
|
||||
free (scene->resources);
|
||||
free (scene);
|
||||
}
|
||||
|
@ -98,27 +94,6 @@ Scene_GetEntity (scene_t *scene, int id)
|
|||
return PR_RESGET (res->entities, id);
|
||||
}
|
||||
|
||||
void
|
||||
scene_add_root (scene_t *scene, transform_t *transform)
|
||||
{
|
||||
if (!Transform_GetParent (transform)) {
|
||||
DARRAY_APPEND (&scene->roots, transform);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
scene_del_root (scene_t *scene, transform_t *transform)
|
||||
{
|
||||
if (!Transform_GetParent (transform)) {
|
||||
for (size_t i = 0; i < scene->roots.size; i++) {
|
||||
if (scene->roots.a[i] == transform) {
|
||||
DARRAY_REMOVE_AT (&scene->roots, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_entity (scene_t *scene, entity_t *ent)
|
||||
{
|
||||
|
@ -154,8 +129,8 @@ Scene_DestroyEntity (scene_t *scene, entity_t *ent)
|
|||
void
|
||||
Scene_FreeAllEntities (scene_t *scene)
|
||||
{
|
||||
for (size_t i = 0; i < scene->roots.size; i++) {
|
||||
hierarchy_t *h = scene->roots.a[i]->hierarchy;
|
||||
while (scene->hierarchies) {
|
||||
hierarchy_t *h = scene->hierarchies;
|
||||
// deleting the root entity deletes all child entities
|
||||
entity_t *ent = h->entity.a[0];
|
||||
destroy_entity (scene, ent);
|
||||
|
|
|
@ -58,7 +58,6 @@ Transform_New (scene_t *scene, transform_t *parent)
|
|||
} else {
|
||||
transform->hierarchy = Hierarchy_New (scene, 1);
|
||||
transform->index = 0;
|
||||
scene_add_root (scene, transform);
|
||||
}
|
||||
transform->hierarchy->transform.a[transform->index] = transform;
|
||||
Hierarchy_UpdateMatrices (transform->hierarchy);
|
||||
|
@ -73,7 +72,6 @@ Transform_Delete (transform_t *transform)
|
|||
// hierarchy so deleting it is easier
|
||||
Transform_SetParent (transform, 0);
|
||||
}
|
||||
scene_del_root (transform->scene, transform);
|
||||
// Takes care of freeing the transforms
|
||||
Hierarchy_Delete (transform->hierarchy);
|
||||
}
|
||||
|
@ -90,7 +88,6 @@ void
|
|||
Transform_SetParent (transform_t *transform, transform_t *parent)
|
||||
{
|
||||
if (parent) {
|
||||
scene_del_root (transform->scene, transform);
|
||||
hierarchy_t *hierarchy = transform->hierarchy;
|
||||
uint32_t index = transform->index;
|
||||
Hierarchy_InsertHierarchy (parent->hierarchy, hierarchy,
|
||||
|
@ -112,7 +109,6 @@ Transform_SetParent (transform_t *transform, transform_t *parent)
|
|||
Hierarchy_InsertHierarchy (new_hierarchy, hierarchy, null_transform,
|
||||
index);
|
||||
Hierarchy_RemoveHierarchy (hierarchy, index);
|
||||
scene_add_root (transform->scene, transform);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue