[ecs] Move parent setting logic into hierarchy

It should have always been here, but when I first created the hierarchy
and transform objects, I didn't know where things would go. Having two
chunks of code for setting an entity's parent was too already too much,
and I expect to have other hierarchy types. Doesn't fix the issues
encountered with sbar, of course.
This commit is contained in:
Bill Currie 2022-11-05 17:38:14 +09:00
parent 42963f97c0
commit 57cd30fca3
4 changed files with 59 additions and 54 deletions

View File

@ -72,6 +72,9 @@ void Hierarchy_Delete (hierarchy_t *hierarchy);
uint32_t Hierarchy_InsertHierarchy (hierarchy_t *dst, const hierarchy_t *src,
uint32_t dstParent, uint32_t srcRoot);
void Hierarchy_RemoveHierarchy (hierarchy_t *hierarchy, uint32_t index);
hierref_t Hierarchy_SetParent (hierarchy_t *dst, uint32_t dstParent,
hierarchy_t *src, uint32_t srcIndex);
///@}
#endif//__QF_ecs_hierarchy_h

View File

@ -400,7 +400,31 @@ Hierarchy_Copy (ecs_registry_t *dstReg, const hierarchy_t *src)
dst->components[i], 0,
src->components[i], 0, count);
}
// Just in case the source hierarchy has modified objects
//Hierarchy_UpdateMatrices (dst);
return dst;
}
hierref_t
Hierarchy_SetParent (hierarchy_t *dst, uint32_t dstParent,
hierarchy_t *src, uint32_t srcRoot)
{
hierref_t r = {};
if (dst && dstParent != nullent) {
if (dst->type != src->type) {
Sys_Error ("Can't set parent in hierarcy of different type");
}
} else {
if (!srcRoot) {
r.hierarchy = src;
r.index = 0;
return r;
}
dst = Hierarchy_New (src->reg, src->type, 0);
}
r.hierarchy = dst;
r.index = Hierarchy_InsertHierarchy (dst, src, dstParent, srcRoot);
Hierarchy_RemoveHierarchy (src, srcRoot);
if (!src->num_objects) {
Hierarchy_Delete (src);
}
return r;
}

View File

@ -262,34 +262,22 @@ Transform_NewNamed (ecs_registry_t *reg, transform_t parent, const char *name)
void
Transform_SetParent (transform_t transform, transform_t parent)
{
if (parent.reg && parent.id != nullent) {
__auto_type ref = Transform_GetRef (transform);
__auto_type tref = *ref;
__auto_type pref = Transform_GetRef (parent);
ref->index = Hierarchy_InsertHierarchy (pref->hierarchy,
tref.hierarchy,
pref->index, tref.index);
ref->hierarchy = pref->hierarchy;
Hierarchy_RemoveHierarchy (tref.hierarchy, tref.index);
if (!tref.hierarchy->num_objects) {
Hierarchy_Delete (tref.hierarchy);
}
} else {
__auto_type ref = Transform_GetRef (transform);
__auto_type tref = *ref;
// null parent -> make transform root
if (!tref.index) {
// already root
return;
}
ref->hierarchy = Hierarchy_New (transform.reg, &transform_type, 0);
Hierarchy_InsertHierarchy (ref->hierarchy, tref.hierarchy, nullent,
tref.index);
Hierarchy_RemoveHierarchy (tref.hierarchy, tref.index);
if (!tref.hierarchy->num_objects) {
Hierarchy_Delete (tref.hierarchy);
}
hierarchy_t *dst = 0;
uint32_t dstParent = nullent;
hierarchy_t *src = 0;
uint32_t srcIndex = 0;
if (Transform_Valid (parent)) {
__auto_type ref = Transform_GetRef (parent);
dst = ref->hierarchy;
dstParent = ref->index;
}
{
__auto_type ref = Transform_GetRef (transform);
src = ref->hierarchy;
srcIndex = ref->index;
}
Hierarchy_SetParent (dst, dstParent, src, srcIndex);
__auto_type ref = Transform_GetRef (transform);
hierarchy_t *h = ref->hierarchy;
byte *modified = h->components[transform_type_modified];

View File

@ -265,32 +265,22 @@ View_UpdateHierarchy (view_t view)
void
View_SetParent (view_t view, view_t parent)
{
if (parent.reg && parent.id != nullent) {
__auto_type ref = View_GetRef (view);
__auto_type vref = *ref;
__auto_type pref = View_GetRef (parent);
ref->index = Hierarchy_InsertHierarchy (pref->hierarchy,
vref.hierarchy,
pref->index, vref.index);
ref->hierarchy = pref->hierarchy;
Hierarchy_RemoveHierarchy (vref.hierarchy, vref.index);
if (!vref.hierarchy->num_objects) {
Hierarchy_Delete (vref.hierarchy);
}
} else {
__auto_type ref = View_GetRef (view);
__auto_type vref = *ref;
if (!vref.index) {
return;
}
ref->hierarchy = Hierarchy_New (view.reg, &view_type, 0);
Hierarchy_InsertHierarchy (ref->hierarchy, vref.hierarchy, nullent,
vref.index);
Hierarchy_RemoveHierarchy (vref.hierarchy, vref.index);
if (!vref.hierarchy->num_objects) {
Hierarchy_Delete (vref.hierarchy);
}
hierarchy_t *dst = 0;
uint32_t dstParent = nullent;
hierarchy_t *src = 0;
uint32_t srcIndex = 0;
if (View_Valid (parent)) {
__auto_type ref = View_GetRef (parent);
dst = ref->hierarchy;
dstParent = ref->index;
}
{
__auto_type ref = View_GetRef (view);
src = ref->hierarchy;
srcIndex = ref->index;
}
Hierarchy_SetParent (dst, dstParent, src, srcIndex);
__auto_type ref = View_GetRef (view);
hierarchy_t *h = ref->hierarchy;
byte *modified = h->components[view_modified];