mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 23:11:38 +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 {
|
typedef struct entity_s {
|
||||||
struct entity_s *next;
|
struct entity_s *next;
|
||||||
|
|
||||||
struct transform_s *transform;
|
struct transform_s *transform;
|
||||||
|
int id; ///< scene id
|
||||||
animation_t animation;
|
animation_t animation;
|
||||||
visibility_t visibility;
|
visibility_t visibility;
|
||||||
renderer_t renderer;
|
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 {
|
typedef struct scene_s {
|
||||||
struct scene_resources_s *const resources;
|
struct scene_resources_s *const resources;
|
||||||
hierarchyset_t roots;
|
xformset_t roots;
|
||||||
xformset_t transforms;
|
|
||||||
entityset_t entities;
|
|
||||||
visibilityset_t visibility;
|
|
||||||
} scene_t;
|
} scene_t;
|
||||||
|
|
||||||
scene_t *Scene_NewScene (void);
|
scene_t *Scene_NewScene (void);
|
||||||
|
void Scene_DeleteScene (scene_t *scene);
|
||||||
struct entity_s *Scene_CreateEntity (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);
|
void Scene_FreeAllEntities (scene_t *scene);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -43,10 +43,12 @@
|
||||||
|
|
||||||
typedef struct transform_s {
|
typedef struct transform_s {
|
||||||
struct hierarchy_s *hierarchy;
|
struct hierarchy_s *hierarchy;
|
||||||
uint32_t index;
|
uint32_t index; ///< index in hierarchy
|
||||||
|
int32_t id; ///< scene id
|
||||||
} transform_t;
|
} transform_t;
|
||||||
|
|
||||||
transform_t *Transform_New (transform_t *parent);
|
transform_t *Transform_New (transform_t *parent);
|
||||||
|
/* Deletes all child transforms, and transform names */
|
||||||
void Transform_Delete (transform_t *transform);
|
void Transform_Delete (transform_t *transform);
|
||||||
transform_t *Transform_NewNamed (transform_t *parent, const char *name);
|
transform_t *Transform_NewNamed (transform_t *parent, const char *name);
|
||||||
uint32_t Transform_ChildCount (const transform_t *transform) __attribute__((pure));
|
uint32_t Transform_ChildCount (const transform_t *transform) __attribute__((pure));
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "QF/progs.h" // for PR_RESMAP
|
#include "QF/progs.h" // for PR_RESMAP
|
||||||
|
#include "QF/sys.h"
|
||||||
|
|
||||||
#include "QF/scene/entity.h"
|
#include "QF/scene/entity.h"
|
||||||
#include "QF/scene/scene.h"
|
#include "QF/scene/scene.h"
|
||||||
|
@ -56,34 +57,105 @@ Scene_NewScene (void)
|
||||||
*(scene_resources_t **)&scene->resources = res;
|
*(scene_resources_t **)&scene->resources = res;
|
||||||
|
|
||||||
DARRAY_INIT (&scene->roots, 16);
|
DARRAY_INIT (&scene->roots, 16);
|
||||||
DARRAY_INIT (&scene->transforms, 16);
|
|
||||||
DARRAY_INIT (&scene->entities, 16);
|
|
||||||
DARRAY_INIT (&scene->visibility, 16);
|
|
||||||
|
|
||||||
return scene;
|
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 *
|
entity_t *
|
||||||
Scene_CreateEntity (scene_t *scene)
|
Scene_CreateEntity (scene_t *scene)
|
||||||
{
|
{
|
||||||
scene_resources_t *res = scene->resources;
|
scene_resources_t *res = scene->resources;
|
||||||
|
|
||||||
entity_t *ent = PR_RESNEW_NC (res->entities);
|
entity_t *ent = PR_RESNEW_NC (res->entities);
|
||||||
ent->transform = 0;
|
ent->transform = Transform_New (0);
|
||||||
DARRAY_APPEND (&scene->entities, ent);
|
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;
|
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
|
void
|
||||||
Scene_FreeAllEntities (scene_t *scene)
|
Scene_FreeAllEntities (scene_t *scene)
|
||||||
{
|
{
|
||||||
scene_resources_t *res = scene->resources;
|
for (size_t i = 0; i < scene->roots.size; i++) {
|
||||||
for (size_t i = 0; i < scene->entities.size; i++) {
|
hierarchy_t *h = scene->roots.a[i]->hierarchy;
|
||||||
entity_t *ent = scene->entities.a[i];
|
// deleting the root entity deletes all child entities
|
||||||
if (ent->transform) {
|
entity_t *ent = h->entity.a[0];
|
||||||
Transform_Delete (ent->transform);
|
destroy_entity (scene, ent);
|
||||||
ent->transform = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
scene_resources_t *res = scene->resources;
|
||||||
PR_RESRESET (res->entities);
|
PR_RESRESET (res->entities);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue