mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
[scene] Add functions for scene and entity create/delete
Scene creation was already there, but now can be deleted, as can entities.
This commit is contained in:
parent
f3559cedb0
commit
f6ac614e09
4 changed files with 92 additions and 23 deletions
|
@ -172,8 +172,8 @@ typedef struct renderer_s {
|
|||
|
||||
typedef struct entity_s {
|
||||
struct entity_s *next;
|
||||
|
||||
struct transform_s *transform;
|
||||
int id; ///< scene id
|
||||
animation_t animation;
|
||||
visibility_t visibility;
|
||||
renderer_t renderer;
|
||||
|
|
|
@ -40,21 +40,16 @@
|
|||
*/
|
||||
///@{
|
||||
|
||||
typedef struct hierarchyset_s DARRAY_TYPE (struct hierarchy_s *)
|
||||
hierarchyset_t;
|
||||
typedef struct visibilityset_s DARRAY_TYPE (struct visibility_s *)
|
||||
visibilityset_t;
|
||||
|
||||
typedef struct scene_s {
|
||||
struct scene_resources_s *const resources;
|
||||
hierarchyset_t roots;
|
||||
xformset_t transforms;
|
||||
entityset_t entities;
|
||||
visibilityset_t visibility;
|
||||
xformset_t roots;
|
||||
} scene_t;
|
||||
|
||||
scene_t *Scene_NewScene (void);
|
||||
void Scene_DeleteScene (scene_t *scene);
|
||||
struct entity_s *Scene_CreateEntity (scene_t *scene);
|
||||
struct entity_s *Scene_GetEntity (scene_t *scene, int id);
|
||||
void Scene_DestroyEntity (scene_t *scene, struct entity_s *entity);
|
||||
void Scene_FreeAllEntities (scene_t *scene);
|
||||
|
||||
|
||||
|
|
|
@ -43,10 +43,12 @@
|
|||
|
||||
typedef struct transform_s {
|
||||
struct hierarchy_s *hierarchy;
|
||||
uint32_t index;
|
||||
uint32_t index; ///< index in hierarchy
|
||||
int32_t id; ///< scene id
|
||||
} transform_t;
|
||||
|
||||
transform_t *Transform_New (transform_t *parent);
|
||||
/* Deletes all child transforms, and transform names */
|
||||
void Transform_Delete (transform_t *transform);
|
||||
transform_t *Transform_NewNamed (transform_t *parent, const char *name);
|
||||
uint32_t Transform_ChildCount (const transform_t *transform) __attribute__((pure));
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#endif
|
||||
|
||||
#include "QF/progs.h" // for PR_RESMAP
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
#include "QF/scene/scene.h"
|
||||
|
@ -56,34 +57,105 @@ Scene_NewScene (void)
|
|||
*(scene_resources_t **)&scene->resources = res;
|
||||
|
||||
DARRAY_INIT (&scene->roots, 16);
|
||||
DARRAY_INIT (&scene->transforms, 16);
|
||||
DARRAY_INIT (&scene->entities, 16);
|
||||
DARRAY_INIT (&scene->visibility, 16);
|
||||
|
||||
return scene;
|
||||
}
|
||||
|
||||
void
|
||||
Scene_DeleteScene (scene_t *scene)
|
||||
{
|
||||
Scene_FreeAllEntities (scene);
|
||||
|
||||
scene_resources_t *res = scene->resources;
|
||||
for (unsigned i = 0; i < res->entities._size; i++) {
|
||||
free (res->entities._map[i]);
|
||||
}
|
||||
free (res->entities._map);
|
||||
|
||||
DARRAY_CLEAR (&scene->roots);
|
||||
|
||||
free (scene->resources);
|
||||
free (scene);
|
||||
}
|
||||
|
||||
entity_t *
|
||||
Scene_CreateEntity (scene_t *scene)
|
||||
{
|
||||
scene_resources_t *res = scene->resources;
|
||||
|
||||
entity_t *ent = PR_RESNEW_NC (res->entities);
|
||||
ent->transform = 0;
|
||||
DARRAY_APPEND (&scene->entities, ent);
|
||||
ent->transform = Transform_New (0);
|
||||
ent->id = PR_RESINDEX (res->entities, ent);
|
||||
|
||||
hierarchy_t *h = ent->transform->hierarchy;
|
||||
h->entity.a[ent->transform->index] = ent;
|
||||
|
||||
DARRAY_APPEND (&scene->roots, ent->transform);
|
||||
return ent;
|
||||
}
|
||||
|
||||
entity_t *
|
||||
Scene_GetEntity (scene_t *scene, int id)
|
||||
{
|
||||
scene_resources_t *res = scene->resources;
|
||||
return PR_RESGET (res->entities, id);
|
||||
}
|
||||
|
||||
static void
|
||||
unroot_transform (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)
|
||||
{
|
||||
scene_resources_t *res = scene->resources;
|
||||
// ent->transform will be trampled by the loop below
|
||||
transform_t *transform = ent->transform;
|
||||
|
||||
// Transform_Delete takes care of all hierarchy stuff (transforms
|
||||
// themselves, name strings, hierarchy table)
|
||||
hierarchy_t *h = transform->hierarchy;
|
||||
for (size_t i = 0; i < h->entity.size; i++) {
|
||||
entity_t *e = h->entity.a[0];
|
||||
e->transform = 0;
|
||||
PR_RESFREE (res->entities, ent);
|
||||
}
|
||||
Transform_Delete (transform);
|
||||
}
|
||||
|
||||
void
|
||||
Scene_DestroyEntity (scene_t *scene, entity_t *ent)
|
||||
{
|
||||
scene_resources_t *res = scene->resources;
|
||||
|
||||
if (PR_RESGET (res->entities, ent->id) != ent) {
|
||||
Sys_Error ("Scene_DestroyEntity: entity not owned by scene");
|
||||
}
|
||||
unroot_transform (scene, ent->transform);
|
||||
// pull the transform out of the hierarchy to make it easier to destory
|
||||
// all the child entities
|
||||
Transform_SetParent (ent->transform, 0);
|
||||
destroy_entity (scene, ent);
|
||||
}
|
||||
|
||||
void
|
||||
Scene_FreeAllEntities (scene_t *scene)
|
||||
{
|
||||
scene_resources_t *res = scene->resources;
|
||||
for (size_t i = 0; i < scene->entities.size; i++) {
|
||||
entity_t *ent = scene->entities.a[i];
|
||||
if (ent->transform) {
|
||||
Transform_Delete (ent->transform);
|
||||
ent->transform = 0;
|
||||
}
|
||||
for (size_t i = 0; i < scene->roots.size; i++) {
|
||||
hierarchy_t *h = scene->roots.a[i]->hierarchy;
|
||||
// deleting the root entity deletes all child entities
|
||||
entity_t *ent = h->entity.a[0];
|
||||
destroy_entity (scene, ent);
|
||||
}
|
||||
scene_resources_t *res = scene->resources;
|
||||
PR_RESRESET (res->entities);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue