mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-21 09:51:41 +00:00
[scene] Make transforms owned by the scene
This actually has at least two benefits: the transform id is managed by the scene and thus does not need separate management by the Ruamoko wrapper functions, and better memory handling of the transform objects. Another benefit that isn't realized yet is that this is a step towards breaking the renderers free of quake and quakeworld: although the clients don't actually use the scene yet, it will be a good place to store the rendering information (functions to run, etc).
This commit is contained in:
parent
f0c35e541a
commit
ba3879c6e0
9 changed files with 102 additions and 67 deletions
|
@ -70,6 +70,7 @@ EXTRA_DIST += \
|
|||
include/rua_internal.h \
|
||||
include/sbar.h \
|
||||
include/skin_stencil.h \
|
||||
include/scn_internal.h \
|
||||
include/snd_internal.h \
|
||||
include/sv_console.h \
|
||||
include/varrays.h \
|
||||
|
|
|
@ -48,7 +48,7 @@ typedef struct scene_s {
|
|||
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);
|
||||
struct entity_s *Scene_GetEntity (scene_t *scene, int id) __attribute__((pure));
|
||||
void Scene_DestroyEntity (scene_t *scene, struct entity_s *entity);
|
||||
void Scene_FreeAllEntities (scene_t *scene);
|
||||
|
||||
|
|
|
@ -43,14 +43,16 @@
|
|||
|
||||
typedef struct transform_s {
|
||||
struct hierarchy_s *hierarchy;
|
||||
struct scene_s *scene; ///< owning scene
|
||||
uint32_t index; ///< index in hierarchy
|
||||
int32_t id; ///< scene id
|
||||
} transform_t;
|
||||
|
||||
transform_t *Transform_New (transform_t *parent);
|
||||
transform_t *Transform_New (struct scene_s *scene, 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);
|
||||
transform_t *Transform_NewNamed (struct scene_s *scene, transform_t *parent,
|
||||
const char *name);
|
||||
uint32_t Transform_ChildCount (const transform_t *transform) __attribute__((pure));
|
||||
transform_t *Transform_GetChild (const transform_t *transform,
|
||||
uint32_t childIndex) __attribute__((pure));
|
||||
|
|
14
include/scn_internal.h
Normal file
14
include/scn_internal.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifndef __scn_internal_h
|
||||
#define __scn_internal_h
|
||||
|
||||
#include "QF/progs.h"
|
||||
#include "QF/scene/entity.h"
|
||||
#include "QF/scene/scene.h"
|
||||
#include "QF/scene/transform.h"
|
||||
|
||||
typedef struct scene_resources_s {
|
||||
PR_RESMAP (entity_t) entities;
|
||||
PR_RESMAP (transform_t) transforms;
|
||||
} scene_resources_t;
|
||||
|
||||
#endif//__scn_internal_h
|
|
@ -46,6 +46,7 @@
|
|||
|
||||
#include "QF/plugin/vid_render.h" //FIXME
|
||||
#include "QF/scene/entity.h"
|
||||
#include "QF/scene/scene.h"
|
||||
|
||||
#include "client/effects.h"
|
||||
#include "client/entities.h"
|
||||
|
@ -85,6 +86,7 @@ typedef struct tent_obj_s {
|
|||
|
||||
static PR_RESMAP (tent_t) temp_entities;
|
||||
static PR_RESMAP (tent_obj_t) tent_objects;
|
||||
static scene_t *scene;
|
||||
static tent_obj_t *cl_beams;
|
||||
static tent_obj_t *cl_explosions;
|
||||
|
||||
|
@ -135,6 +137,8 @@ CL_TEnts_Precache (int phase)
|
|||
void
|
||||
CL_TEnts_Init (void)
|
||||
{
|
||||
scene = Scene_NewScene ();
|
||||
|
||||
QFS_GamedirCallback (CL_TEnts_Precache);
|
||||
CL_TEnts_Precache (1);
|
||||
for (int i = 0; i < 360; i++) {
|
||||
|
@ -151,7 +155,7 @@ CL_Init_Entity (entity_t *ent)
|
|||
}
|
||||
memset (ent, 0, sizeof (*ent));
|
||||
|
||||
ent->transform = Transform_New (0);
|
||||
ent->transform = Transform_New (scene, 0);
|
||||
ent->renderer.skin = 0;
|
||||
QuatSet (1.0, 1.0, 1.0, 1.0, ent->renderer.colormod);
|
||||
ent->animation.pose1 = ent->animation.pose2 = -1;
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
#include "QF/scene/hierarchy.h"
|
||||
#include "QF/scene/transform.h"
|
||||
|
||||
#include "scn_internal.h"
|
||||
|
||||
#if defined(_WIN32) && !defined(_WIN64)
|
||||
// FIXME (maybe) this is a hack to make DARRAY arrrays 16-byte aligned on
|
||||
// 32-bit systems (in particular for this case, windows) as the vectors and
|
||||
|
@ -430,11 +432,12 @@ Hierarchy_New (size_t grow, int createRoot)
|
|||
void
|
||||
Hierarchy_Delete (hierarchy_t *hierarchy)
|
||||
{
|
||||
for (size_t i = 0; i < hierarchy->transform.size; i++) {
|
||||
free (hierarchy->transform.a[i]);
|
||||
}
|
||||
for (size_t i = 0; i < hierarchy->name.size; i++) {
|
||||
free (hierarchy->name.a[i]);
|
||||
if (hierarchy->transform.size) {
|
||||
scene_resources_t *res = hierarchy->transform.a[0]->scene->resources;
|
||||
|
||||
for (size_t i = 0; i < hierarchy->transform.size; i++) {
|
||||
PR_RESFREE (res->transforms, hierarchy->transform.a[i]);
|
||||
}
|
||||
}
|
||||
DARRAY_CLEAR (&hierarchy->transform);
|
||||
DARRAY_CLEAR (&hierarchy->entity);
|
||||
|
|
|
@ -42,9 +42,7 @@
|
|||
#include "QF/scene/scene.h"
|
||||
#include "QF/scene/transform.h"
|
||||
|
||||
typedef struct scene_resources_s {
|
||||
PR_RESMAP (entity_t) entities;
|
||||
} scene_resources_t;
|
||||
#include "scn_internal.h"
|
||||
|
||||
scene_t *
|
||||
Scene_NewScene (void)
|
||||
|
@ -84,7 +82,7 @@ Scene_CreateEntity (scene_t *scene)
|
|||
scene_resources_t *res = scene->resources;
|
||||
|
||||
entity_t *ent = PR_RESNEW_NC (res->entities);
|
||||
ent->transform = Transform_New (0);
|
||||
ent->transform = Transform_New (scene, 0);
|
||||
ent->id = PR_RESINDEX (res->entities, ent);
|
||||
|
||||
hierarchy_t *h = ent->transform->hierarchy;
|
||||
|
|
|
@ -7,8 +7,11 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include "QF/scene/hierarchy.h"
|
||||
#include "QF/scene/scene.h"
|
||||
#include "QF/scene/transform.h"
|
||||
|
||||
scene_t *scene;
|
||||
|
||||
// NOTE: these are the columns of the matrix! (not that it matters for a
|
||||
// symmetrical matrix, but...)
|
||||
mat4f_t identity = {
|
||||
|
@ -112,7 +115,7 @@ check_indices (transform_t *transform, uint32_t index, uint32_t parentIndex,
|
|||
static int
|
||||
test_single_transform (void)
|
||||
{
|
||||
transform_t *transform = Transform_New (0);
|
||||
transform_t *transform = Transform_New (scene, 0);
|
||||
hierarchy_t *h;
|
||||
|
||||
if (!transform) {
|
||||
|
@ -149,8 +152,8 @@ test_single_transform (void)
|
|||
static int
|
||||
test_parent_child_init (void)
|
||||
{
|
||||
transform_t *parent = Transform_New (0);
|
||||
transform_t *child = Transform_New (parent);
|
||||
transform_t *parent = Transform_New (scene, 0);
|
||||
transform_t *child = Transform_New (scene, parent);
|
||||
|
||||
if (parent->hierarchy != child->hierarchy) {
|
||||
printf ("parent and child transforms have separate hierarchies\n");
|
||||
|
@ -200,8 +203,8 @@ test_parent_child_init (void)
|
|||
static int
|
||||
test_parent_child_setparent (void)
|
||||
{
|
||||
transform_t *parent = Transform_New (0);
|
||||
transform_t *child = Transform_New (0);
|
||||
transform_t *parent = Transform_New (scene, 0);
|
||||
transform_t *child = Transform_New (scene, 0);
|
||||
|
||||
Transform_SetName (parent, "parent");
|
||||
Transform_SetName (child, "child");
|
||||
|
@ -267,17 +270,17 @@ test_build_hierarchy (void)
|
|||
{
|
||||
printf ("test_build_hierarchy\n");
|
||||
|
||||
transform_t *root = Transform_NewNamed (0, "root");
|
||||
transform_t *A = Transform_NewNamed (root, "A");
|
||||
transform_t *B = Transform_NewNamed (root, "B");
|
||||
transform_t *C = Transform_NewNamed (root, "C");
|
||||
transform_t *root = Transform_NewNamed (scene, 0, "root");
|
||||
transform_t *A = Transform_NewNamed (scene, root, "A");
|
||||
transform_t *B = Transform_NewNamed (scene, root, "B");
|
||||
transform_t *C = Transform_NewNamed (scene, root, "C");
|
||||
|
||||
if (!check_indices (root, 0, null_transform, 1, 3)) { return 1; }
|
||||
if (!check_indices (A, 1, 0, 4, 0)) { return 1; }
|
||||
if (!check_indices (B, 2, 0, 4, 0)) { return 1; }
|
||||
if (!check_indices (C, 3, 0, 4, 0)) { return 1; }
|
||||
|
||||
transform_t *B1 = Transform_NewNamed (B, "B1");
|
||||
transform_t *B1 = Transform_NewNamed (scene, B, "B1");
|
||||
|
||||
if (!check_indices (root, 0, null_transform, 1, 3)) { return 1; }
|
||||
if (!check_indices ( A, 1, 0, 4, 0)) { return 1; }
|
||||
|
@ -285,7 +288,7 @@ test_build_hierarchy (void)
|
|||
if (!check_indices ( C, 3, 0, 5, 0)) { return 1; }
|
||||
if (!check_indices (B1, 4, 2, 5, 0)) { return 1; }
|
||||
|
||||
transform_t *A1 = Transform_NewNamed (A, "A1");
|
||||
transform_t *A1 = Transform_NewNamed (scene, A, "A1");
|
||||
|
||||
if (!check_indices (root, 0, null_transform, 1, 3)) { return 1; }
|
||||
if (!check_indices ( A, 1, 0, 4, 1)) { return 1; }
|
||||
|
@ -293,11 +296,11 @@ test_build_hierarchy (void)
|
|||
if (!check_indices ( C, 3, 0, 6, 0)) { return 1; }
|
||||
if (!check_indices (A1, 4, 1, 6, 0)) { return 1; }
|
||||
if (!check_indices (B1, 5, 2, 6, 0)) { return 1; }
|
||||
transform_t *A1a = Transform_NewNamed (A1, "A1a");
|
||||
transform_t *B2 = Transform_NewNamed (B, "B2");
|
||||
transform_t *A2 = Transform_NewNamed (A, "A2");
|
||||
transform_t *B3 = Transform_NewNamed (B, "B3");
|
||||
transform_t *B2a = Transform_NewNamed (B2, "B2a");
|
||||
transform_t *A1a = Transform_NewNamed (scene, A1, "A1a");
|
||||
transform_t *B2 = Transform_NewNamed (scene, B, "B2");
|
||||
transform_t *A2 = Transform_NewNamed (scene, A, "A2");
|
||||
transform_t *B3 = Transform_NewNamed (scene, B, "B3");
|
||||
transform_t *B2a = Transform_NewNamed (scene, B2, "B2a");
|
||||
|
||||
if (!check_hierarchy_size (root->hierarchy, 11)) { return 1; }
|
||||
|
||||
|
@ -313,7 +316,7 @@ test_build_hierarchy (void)
|
|||
if (!check_indices (A1a, 9, 4, 11, 0)) { return 1; }
|
||||
if (!check_indices (B2a, 10, 7, 11, 0)) { return 1; }
|
||||
|
||||
transform_t *D = Transform_NewNamed (root, "D");
|
||||
transform_t *D = Transform_NewNamed (scene, root, "D");
|
||||
|
||||
if (!check_hierarchy_size (root->hierarchy, 12)) { return 1; }
|
||||
|
||||
|
@ -331,7 +334,7 @@ test_build_hierarchy (void)
|
|||
if (!check_indices (B2a, 11, 8, 12, 0)) { return 1; }
|
||||
|
||||
dump_hierarchy (root->hierarchy);
|
||||
transform_t *C1 = Transform_NewNamed (C, "C1");
|
||||
transform_t *C1 = Transform_NewNamed (scene, C, "C1");
|
||||
dump_hierarchy (root->hierarchy);
|
||||
if (!check_hierarchy_size (root->hierarchy, 13)) { return 1; }
|
||||
|
||||
|
@ -360,19 +363,19 @@ test_build_hierarchy2 (void)
|
|||
{
|
||||
printf ("test_build_hierarchy2\n");
|
||||
|
||||
transform_t *root = Transform_NewNamed (0, "root");
|
||||
transform_t *A = Transform_NewNamed (root, "A");
|
||||
transform_t *B = Transform_NewNamed (root, "B");
|
||||
transform_t *C = Transform_NewNamed (root, "C");
|
||||
transform_t *B1 = Transform_NewNamed (B, "B1");
|
||||
transform_t *A1 = Transform_NewNamed (A, "A1");
|
||||
transform_t *A1a = Transform_NewNamed (A1, "A1a");
|
||||
transform_t *B2 = Transform_NewNamed (B, "B2");
|
||||
transform_t *A2 = Transform_NewNamed (A, "A2");
|
||||
transform_t *B3 = Transform_NewNamed (B, "B3");
|
||||
transform_t *B2a = Transform_NewNamed (B2, "B2a");
|
||||
transform_t *D = Transform_NewNamed (root, "D");
|
||||
transform_t *C1 = Transform_NewNamed (C, "C1");
|
||||
transform_t *root = Transform_NewNamed (scene, 0, "root");
|
||||
transform_t *A = Transform_NewNamed (scene, root, "A");
|
||||
transform_t *B = Transform_NewNamed (scene, root, "B");
|
||||
transform_t *C = Transform_NewNamed (scene, root, "C");
|
||||
transform_t *B1 = Transform_NewNamed (scene, B, "B1");
|
||||
transform_t *A1 = Transform_NewNamed (scene, A, "A1");
|
||||
transform_t *A1a = Transform_NewNamed (scene, A1, "A1a");
|
||||
transform_t *B2 = Transform_NewNamed (scene, B, "B2");
|
||||
transform_t *A2 = Transform_NewNamed (scene, A, "A2");
|
||||
transform_t *B3 = Transform_NewNamed (scene, B, "B3");
|
||||
transform_t *B2a = Transform_NewNamed (scene, B2, "B2a");
|
||||
transform_t *D = Transform_NewNamed (scene, root, "D");
|
||||
transform_t *C1 = Transform_NewNamed (scene, C, "C1");
|
||||
|
||||
if (!check_hierarchy_size (root->hierarchy, 13)) { return 1; }
|
||||
|
||||
|
@ -390,18 +393,18 @@ test_build_hierarchy2 (void)
|
|||
if (!check_indices (A1a, 11, 5, 13, 0)) { return 1; }
|
||||
if (!check_indices (B2a, 12, 8, 13, 0)) { return 1; }
|
||||
|
||||
transform_t *T = Transform_NewNamed (0, "T");
|
||||
transform_t *X = Transform_NewNamed (T, "X");
|
||||
transform_t *Y = Transform_NewNamed (T, "Y");
|
||||
transform_t *Z = Transform_NewNamed (T, "Z");
|
||||
transform_t *Y1 = Transform_NewNamed (Y, "Y1");
|
||||
transform_t *X1 = Transform_NewNamed (X, "X1");
|
||||
transform_t *X1a = Transform_NewNamed (X1, "X1a");
|
||||
transform_t *Y2 = Transform_NewNamed (Y, "Y2");
|
||||
transform_t *X2 = Transform_NewNamed (X, "X2");
|
||||
transform_t *Y3 = Transform_NewNamed (Y, "Y3");
|
||||
transform_t *Y2a = Transform_NewNamed (Y2, "Y2a");
|
||||
transform_t *Z1 = Transform_NewNamed (Z, "Z1");
|
||||
transform_t *T = Transform_NewNamed (scene, 0, "T");
|
||||
transform_t *X = Transform_NewNamed (scene, T, "X");
|
||||
transform_t *Y = Transform_NewNamed (scene, T, "Y");
|
||||
transform_t *Z = Transform_NewNamed (scene, T, "Z");
|
||||
transform_t *Y1 = Transform_NewNamed (scene, Y, "Y1");
|
||||
transform_t *X1 = Transform_NewNamed (scene, X, "X1");
|
||||
transform_t *X1a = Transform_NewNamed (scene, X1, "X1a");
|
||||
transform_t *Y2 = Transform_NewNamed (scene, Y, "Y2");
|
||||
transform_t *X2 = Transform_NewNamed (scene, X, "X2");
|
||||
transform_t *Y3 = Transform_NewNamed (scene, Y, "Y3");
|
||||
transform_t *Y2a = Transform_NewNamed (scene, Y2, "Y2a");
|
||||
transform_t *Z1 = Transform_NewNamed (scene, Z, "Z1");
|
||||
|
||||
dump_hierarchy (T->hierarchy);
|
||||
if (!check_hierarchy_size (T->hierarchy, 12)) { return 1; }
|
||||
|
@ -510,11 +513,11 @@ check_vector (const transform_t *transform,
|
|||
static int
|
||||
test_frames (void)
|
||||
{
|
||||
transform_t *root = Transform_NewNamed (0, "root");
|
||||
transform_t *A = Transform_NewNamed (root, "A");
|
||||
transform_t *B = Transform_NewNamed (root, "B");
|
||||
transform_t *A1 = Transform_NewNamed (A, "A1");
|
||||
transform_t *B1 = Transform_NewNamed (B, "B1");
|
||||
transform_t *root = Transform_NewNamed (scene, 0, "root");
|
||||
transform_t *A = Transform_NewNamed (scene, root, "A");
|
||||
transform_t *B = Transform_NewNamed (scene, root, "B");
|
||||
transform_t *A1 = Transform_NewNamed (scene, A, "A1");
|
||||
transform_t *B1 = Transform_NewNamed (scene, B, "B1");
|
||||
|
||||
Transform_SetLocalPosition (root, (vec4f_t) { 0, 0, 1, 1 });
|
||||
Transform_SetLocalPosition (A, (vec4f_t) { 1, 0, 0, 1 });
|
||||
|
@ -699,6 +702,8 @@ test_frames (void)
|
|||
int
|
||||
main (void)
|
||||
{
|
||||
scene = Scene_NewScene ();
|
||||
|
||||
if (test_single_transform ()) { return 1; }
|
||||
if (test_parent_child_init ()) { return 1; }
|
||||
if (test_parent_child_setparent ()) { return 1; }
|
||||
|
@ -706,5 +711,7 @@ main (void)
|
|||
if (test_build_hierarchy2 ()) { return 1; }
|
||||
if (test_frames ()) { return 1; }
|
||||
|
||||
Scene_DeleteScene (scene);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -36,13 +36,19 @@
|
|||
#endif
|
||||
|
||||
#include "QF/scene/hierarchy.h"
|
||||
#include "QF/scene/scene.h"
|
||||
#include "QF/scene/transform.h"
|
||||
|
||||
transform_t *
|
||||
Transform_New (transform_t *parent)
|
||||
{
|
||||
transform_t *transform = malloc (sizeof (transform_t));
|
||||
#include "scn_internal.h"
|
||||
|
||||
transform_t *
|
||||
Transform_New (scene_t *scene, transform_t *parent)
|
||||
{
|
||||
scene_resources_t *res = scene->resources;
|
||||
transform_t *transform = PR_RESNEW_NC (res->transforms);
|
||||
|
||||
transform->scene = scene;
|
||||
transform->id = PR_RESINDEX (res->transforms, transform);
|
||||
if (parent) {
|
||||
transform->hierarchy = parent->hierarchy;
|
||||
transform->index = Hierarchy_InsertHierarchy (parent->hierarchy, 0,
|
||||
|
@ -68,9 +74,9 @@ Transform_Delete (transform_t *transform)
|
|||
}
|
||||
|
||||
transform_t *
|
||||
Transform_NewNamed (transform_t *parent, const char *name)
|
||||
Transform_NewNamed (scene_t *scene, transform_t *parent, const char *name)
|
||||
{
|
||||
transform_t *transform = Transform_New (parent);
|
||||
transform_t *transform = Transform_New (scene, parent);
|
||||
Transform_SetName (transform, name);
|
||||
return transform;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue