From de786ce1973a1360b487a8308a2c5ef5435fa0ec Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 22 Oct 2022 13:04:07 +0900 Subject: [PATCH] [scene] Use hierref_t instead of transform_t in hierarchy Hierarchies are now much closer to being more general in that they are not tied to 3d transforms. This is a major step to moving the whole entity/transform system into an ECS. --- include/QF/scene/hierarchy.h | 4 +- include/QF/scene/transform.h | 109 ++++++++++++---------- include/scn_internal.h | 4 +- libs/ruamoko/rua_scene.c | 14 +-- libs/scene/camera.c | 2 +- libs/scene/hierarchy.c | 61 +++++++------ libs/scene/scene.c | 12 +-- libs/scene/test/test-hierarchy.c | 112 +++++++++++------------ libs/scene/transform.c | 149 ++++++++++++++++--------------- 9 files changed, 246 insertions(+), 221 deletions(-) diff --git a/include/QF/scene/hierarchy.h b/include/QF/scene/hierarchy.h index 47d946540..5a7d11f7e 100644 --- a/include/QF/scene/hierarchy.h +++ b/include/QF/scene/hierarchy.h @@ -49,8 +49,6 @@ typedef struct hierarchy_type_s { const struct component_s *components; } hierarchy_type_t; -#define null_transform (~0u) - typedef struct hierref_s { struct hierarchy_s *hierarchy; uint32_t index; ///< index in hierarchy @@ -63,7 +61,7 @@ typedef struct hierarchy_s { struct scene_s *scene; uint32_t num_objects; uint32_t max_objects; - struct transform_s **transform; //FIXME use hierref_t + hierref_t **ref; struct entity_s **entity; //FIXME should not exist uint32_t *childCount; uint32_t *childIndex; diff --git a/include/QF/scene/transform.h b/include/QF/scene/transform.h index 3bd933168..c448905a8 100644 --- a/include/QF/scene/transform.h +++ b/include/QF/scene/transform.h @@ -59,23 +59,21 @@ enum { }; typedef struct transform_s { - hierarchy_t *hierarchy; - struct scene_s *scene; ///< owning scene - uint32_t index; ///< index in hierarchy - int32_t id; ///< scene id + hierref_t ref; } transform_t; #define XFORMINLINE GNU89INLINE inline __attribute__((pure)) transform_t *Transform_New (struct scene_s *scene, transform_t *parent); /* Deletes all child transforms, and transform names */ -void Transform_Delete (transform_t *transform); +void Transform_Delete (struct scene_s *scene, transform_t *transform); transform_t *Transform_NewNamed (struct scene_s *scene, transform_t *parent, const char *name); XFORMINLINE uint32_t Transform_ChildCount (const transform_t *transform); XFORMINLINE transform_t *Transform_GetChild (const transform_t *transform, uint32_t childIndex); -void Transform_SetParent (transform_t *transform, transform_t *parent); +void Transform_SetParent (struct scene_s *scene, + transform_t *transform, transform_t *parent); XFORMINLINE transform_t *Transform_GetParent (const transform_t *transform); void Transform_SetName (transform_t *transform, const char *name); XFORMINLINE const char *Transform_GetName (const transform_t *transform); @@ -118,57 +116,63 @@ XFORMINLINE uint32_t Transform_ChildCount (const transform_t *transform) { - hierarchy_t *h = transform->hierarchy; - return h->childCount[transform->index]; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; + return h->childCount[ref->index]; } XFORMINLINE transform_t * Transform_GetChild (const transform_t *transform, uint32_t childIndex) { - hierarchy_t *h = transform->hierarchy; - if (childIndex >= h->childCount[transform->index]) { + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; + if (childIndex >= h->childCount[ref->index]) { return 0; } - return h->transform[h->childIndex[transform->index] + childIndex]; + return (transform_t *) h->ref[h->childIndex[ref->index] + childIndex]; } XFORMINLINE transform_t * Transform_GetParent (const transform_t *transform) { - if (transform->index == 0) { + __auto_type ref = (const hierref_t *) transform; + if (ref->index == 0) { return 0; } - hierarchy_t *h = transform->hierarchy; - return h->transform[h->parentIndex[transform->index]]; + hierarchy_t *h = ref->hierarchy; + return (transform_t *) h->ref[h->parentIndex[ref->index]]; } XFORMINLINE const char * Transform_GetName (const transform_t *transform) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; char **name = h->components[transform_type_name]; - return name[transform->index]; + return name[ref->index]; } XFORMINLINE uint32_t Transform_GetTag (const transform_t *transform) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; uint32_t *tag = h->components[transform_type_tag]; - return tag[transform->index]; + return tag[ref->index]; } XFORMINLINE void Transform_GetLocalMatrix (const transform_t *transform, mat4f_t mat) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; mat4f_t *localMatrix = h->components[transform_type_localMatrix]; - vec4f_t *src = localMatrix[transform->index]; + vec4f_t *src = localMatrix[ref->index]; mat[0] = src[0]; mat[1] = src[1]; mat[2] = src[2]; @@ -179,9 +183,10 @@ XFORMINLINE void Transform_GetLocalInverse (const transform_t *transform, mat4f_t mat) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; mat4f_t *localInverse = h->components[transform_type_localInverse]; - vec4f_t *src = localInverse[transform->index]; + vec4f_t *src = localInverse[ref->index]; mat[0] = src[0]; mat[1] = src[1]; mat[2] = src[2]; @@ -192,9 +197,10 @@ XFORMINLINE void Transform_GetWorldMatrix (const transform_t *transform, mat4f_t mat) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; mat4f_t *worldMatrix = h->components[transform_type_worldMatrix]; - vec4f_t *src = worldMatrix[transform->index]; + vec4f_t *src = worldMatrix[ref->index]; mat[0] = src[0]; mat[1] = src[1]; mat[2] = src[2]; @@ -205,18 +211,20 @@ XFORMINLINE const vec4f_t * Transform_GetWorldMatrixPtr (const transform_t *transform) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; mat4f_t *worldMatrix = h->components[transform_type_worldMatrix]; - return worldMatrix[transform->index]; + return worldMatrix[ref->index]; } XFORMINLINE void Transform_GetWorldInverse (const transform_t *transform, mat4f_t mat) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; mat4f_t *worldInverse = h->components[transform_type_worldInverse]; - vec4f_t *src = worldInverse[transform->index]; + vec4f_t *src = worldInverse[ref->index]; mat[0] = src[0]; mat[1] = src[1]; mat[2] = src[2]; @@ -227,81 +235,90 @@ XFORMINLINE vec4f_t Transform_GetLocalPosition (const transform_t *transform) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; mat4f_t *localMatrix = h->components[transform_type_localMatrix]; - return localMatrix[transform->index][3]; + return localMatrix[ref->index][3]; } XFORMINLINE vec4f_t Transform_GetLocalRotation (const transform_t *transform) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; vec4f_t *localRotation = h->components[transform_type_localRotation]; - return localRotation[transform->index]; + return localRotation[ref->index]; } XFORMINLINE vec4f_t Transform_GetLocalScale (const transform_t *transform) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; vec4f_t *localScale = h->components[transform_type_localScale]; - return localScale[transform->index]; + return localScale[ref->index]; } XFORMINLINE vec4f_t Transform_GetWorldPosition (const transform_t *transform) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; mat4f_t *worldMatrix = h->components[transform_type_worldMatrix]; - return worldMatrix[transform->index][3]; + return worldMatrix[ref->index][3]; } XFORMINLINE vec4f_t Transform_GetWorldRotation (const transform_t *transform) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; vec4f_t *worldRotation = h->components[transform_type_worldRotation]; - return worldRotation[transform->index]; + return worldRotation[ref->index]; } XFORMINLINE vec4f_t Transform_GetWorldScale (const transform_t *transform) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; vec4f_t *worldScale = h->components[transform_type_worldScale]; - return worldScale[transform->index]; + return worldScale[ref->index]; } XFORMINLINE vec4f_t Transform_Forward (const transform_t *transform) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; mat4f_t *worldMatrix = h->components[transform_type_worldMatrix]; - return worldMatrix[transform->index][0]; + return worldMatrix[ref->index][0]; } XFORMINLINE vec4f_t Transform_Right (const transform_t *transform) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; mat4f_t *worldMatrix = h->components[transform_type_worldMatrix]; - return -worldMatrix[transform->index][1]; + return -worldMatrix[ref->index][1]; } XFORMINLINE vec4f_t Transform_Up (const transform_t *transform) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; mat4f_t *worldMatrix = h->components[transform_type_worldMatrix]; - return worldMatrix[transform->index][2]; + return worldMatrix[ref->index][2]; } ///@} diff --git a/include/scn_internal.h b/include/scn_internal.h index e2afd9d6f..5247b51f5 100644 --- a/include/scn_internal.h +++ b/include/scn_internal.h @@ -10,9 +10,9 @@ typedef struct scene_resources_s { PR_RESMAP (entity_t) entities; PR_RESMAP (hierarchy_t) hierarchies; - PR_RESMAP (transform_t) transforms; + PR_RESMAP (hierref_t) transforms; } scene_resources_t; -transform_t *__transform_alloc (struct scene_s *scene); +hierref_t *__transform_alloc (struct scene_s *scene); #endif//__scn_internal_h diff --git a/libs/ruamoko/rua_scene.c b/libs/ruamoko/rua_scene.c index 09c4cc662..b19b3003c 100644 --- a/libs/ruamoko/rua_scene.c +++ b/libs/ruamoko/rua_scene.c @@ -93,9 +93,8 @@ rua__scene_get (rua_scene_resources_t *res, pr_ulong_t id, const char *name) { rua_scene_t *scene = 0; - if (id <= 0xffffffffu) { - scene = PR_RESGET (res->scene_map, (pr_int_t) id); - } + id &= 0xffffffffu; + scene = PR_RESGET (res->scene_map, (pr_int_t) id); // scene->prev will be null if the handle is unallocated if (!scene || !scene->prev) { @@ -288,7 +287,7 @@ bi_Entity_GetTransform (progs_t *pr, void *_res) entity_t *ent = rua_entity_get (res, ent_id); // ent_id contains scene id - R_ULONG (pr) = MAKE_ID (ent->transform->id, ent_id); + R_ULONG (pr) = MAKE_ID (ent->transform->ref.id, ent_id); } static void @@ -324,7 +323,7 @@ bi_Transform_GetChild (progs_t *pr, void *_res) transform_t *transform = rua_transform_get (res, P_ULONG (pr, 0)); transform_t *child = Transform_GetChild (transform, P_UINT (pr, 2)); - R_UINT (pr) = child ? child->id : 0; + R_UINT (pr) = child ? child->ref.id : 0; } static void @@ -333,8 +332,9 @@ bi_Transform_SetParent (progs_t *pr, void *_res) rua_scene_resources_t *res = _res; transform_t *transform = rua_transform_get (res, P_ULONG (pr, 0)); transform_t *parent = rua_transform_get (res, P_ULONG (pr, 1)); + rua_scene_t *scene = rua_scene_get (res, P_ULONG (pr, 1)); - Transform_SetParent (transform, parent); + Transform_SetParent (scene->scene, transform, parent); } static void @@ -346,7 +346,7 @@ bi_Transform_GetParent (progs_t *pr, void *_res) transform_t *parent = Transform_GetParent (transform); // transform_id contains scene id - R_ULONG (pr) = parent ? MAKE_ID (parent->id, transform_id) : 0; + R_ULONG (pr) = parent ? MAKE_ID (parent->ref.id, transform_id) : 0; } static void diff --git a/libs/scene/camera.c b/libs/scene/camera.c index 1526abb19..0909f66f0 100644 --- a/libs/scene/camera.c +++ b/libs/scene/camera.c @@ -41,7 +41,7 @@ void Camera_GetViewMatrix (const camera_t *camera, mat4f_t view) { scene_resources_t *res = camera->scene->resources; - transform_t *transform = PR_RESGET (res->transforms, camera->transform); + transform_t *transform = (transform_t *) PR_RESGET (res->transforms, camera->transform); vec4f_t rotation = Transform_GetWorldRotation (transform); vec4f_t position = Transform_GetWorldPosition (transform); mat4fquat (view, qconjf (rotation)); diff --git a/libs/scene/hierarchy.c b/libs/scene/hierarchy.c index 092a3bf3b..69d9acf8c 100644 --- a/libs/scene/hierarchy.c +++ b/libs/scene/hierarchy.c @@ -41,7 +41,7 @@ #include "scn_internal.h" -static component_t transform_component = { .size = sizeof (transform_t *) }; +static component_t ref_component = { .size = sizeof (hierref_t *) }; static component_t entity_component = { .size = sizeof (entity_t *) }; static component_t childCount_component = { .size = sizeof (uint32_t) }; static component_t childIndex_component = { .size = sizeof (uint32_t) }; @@ -52,8 +52,8 @@ hierarchy_UpdateTransformIndices (hierarchy_t *hierarchy, uint32_t start, int offset) { for (size_t i = start; i < hierarchy->num_objects; i++) { - if (hierarchy->transform[i]) { - hierarchy->transform[i]->index += offset; + if (hierarchy->ref[i]) { + hierarchy->ref[i]->index += offset; } } } @@ -84,8 +84,8 @@ Hierarchy_Reserve (hierarchy_t *hierarchy, uint32_t count) new_max += 15; new_max &= ~15; - Component_ResizeArray (&transform_component, - (void **) &hierarchy->transform, new_max); + Component_ResizeArray (&ref_component, + (void **) &hierarchy->ref, new_max); Component_ResizeArray (&entity_component, (void **) &hierarchy->entity, new_max); Component_ResizeArray (&childCount_component, @@ -111,8 +111,8 @@ hierarchy_open (hierarchy_t *hierarchy, uint32_t index, uint32_t count) hierarchy->num_objects += count; uint32_t dstIndex = index + count; count = hierarchy->num_objects - index - count; - Component_MoveElements (&transform_component, - hierarchy->transform, dstIndex, index, count); + Component_MoveElements (&ref_component, + hierarchy->ref, dstIndex, index, count); Component_MoveElements (&entity_component, hierarchy->entity, dstIndex, index, count); Component_MoveElements (&childCount_component, @@ -137,8 +137,8 @@ hierarchy_close (hierarchy_t *hierarchy, uint32_t index, uint32_t count) hierarchy->num_objects -= count; uint32_t srcIndex = index + count; count = hierarchy->num_objects - index; - Component_MoveElements (&transform_component, - hierarchy->transform, index, srcIndex, count); + Component_MoveElements (&ref_component, + hierarchy->ref, index, srcIndex, count); Component_MoveElements (&entity_component, hierarchy->entity, index, srcIndex, count); Component_MoveElements (&childCount_component, @@ -158,20 +158,20 @@ static void hierarchy_move (hierarchy_t *dst, const hierarchy_t *src, uint32_t dstIndex, uint32_t srcIndex, uint32_t count) { - Component_CopyElements (&transform_component, - dst->transform, dstIndex, - src->transform, srcIndex, count); + Component_CopyElements (&ref_component, + dst->ref, dstIndex, + src->ref, srcIndex, count); Component_CopyElements (&entity_component, dst->entity, dstIndex, src->entity, srcIndex, count); // Actually move (as in C++ move semantics) source hierarchy object // references so that their indices do not get updated when the objects // are removed from the source hierarcy - memset (&src->transform[srcIndex], 0, count * sizeof(dst->transform[0])); + memset (&src->ref[srcIndex], 0, count * sizeof(dst->ref[0])); for (uint32_t i = 0; i < count; i++) { - dst->transform[dstIndex + i]->hierarchy = dst; - dst->transform[dstIndex + i]->index = dstIndex + i; + dst->ref[dstIndex + i]->hierarchy = dst; + dst->ref[dstIndex + i]->index = dstIndex + i; } for (uint32_t i = 0; i < dst->type->num_components; i++) { Component_CopyElements (&dst->type->components[i], @@ -184,8 +184,7 @@ static void hierarchy_init (hierarchy_t *dst, uint32_t index, uint32_t parentIndex, uint32_t childIndex, uint32_t count) { - memset (&dst->transform[index], 0, - count * sizeof(dst->transform[0])); + memset (&dst->ref[index], 0, count * sizeof(dst->ref[0])); for (uint32_t i = 0; i < count; i++) { dst->parentIndex[index + i] = parentIndex; @@ -271,13 +270,13 @@ Hierarchy_InsertHierarchy (hierarchy_t *dst, const hierarchy_t *src, { uint32_t insertIndex; - if (dstParent == null_transform) { + if (dstParent == nullent) { if (dst->num_objects) { Sys_Error ("attempt to insert root in non-empty hierarchy"); } hierarchy_open (dst, 0, 1); hierarchy_move (dst, src, 0, srcRoot, 1); - dst->parentIndex[0] = null_transform; + dst->parentIndex[0] = nullent; dst->childIndex[0] = 1; dst->childCount[0] = 0; insertIndex = 0; @@ -300,9 +299,9 @@ hierarchy_remove_children (hierarchy_t *hierarchy, uint32_t index) uint32_t childIndex = hierarchy->childIndex[index]; uint32_t childCount = hierarchy->childCount[index]; uint32_t parentIndex = hierarchy->parentIndex[index]; - uint32_t nieceIndex = null_transform; + uint32_t nieceIndex = nullent; - if (parentIndex != null_transform) { + if (parentIndex != nullent) { uint32_t siblingIndex = hierarchy->childIndex[parentIndex]; siblingIndex += hierarchy->childCount[parentIndex] - 1; nieceIndex = hierarchy->childIndex[siblingIndex]; @@ -316,7 +315,7 @@ hierarchy_remove_children (hierarchy_t *hierarchy, uint32_t index) if (childCount) { hierarchy_UpdateTransformIndices (hierarchy, childIndex, -childCount); hierarchy_UpdateChildIndices (hierarchy, index, -childCount); - if (nieceIndex != null_transform) { + if (nieceIndex != nullent) { hierarchy_UpdateParentIndices (hierarchy, nieceIndex, -childCount); } } @@ -327,13 +326,13 @@ Hierarchy_RemoveHierarchy (hierarchy_t *hierarchy, uint32_t index) { uint32_t parentIndex = hierarchy->parentIndex[index]; uint32_t childIndex = hierarchy->childIndex[index]; - uint32_t siblingIndex = null_transform; - if (parentIndex != null_transform) { + uint32_t siblingIndex = nullent; + if (parentIndex != nullent) { siblingIndex = hierarchy->childIndex[parentIndex]; } hierarchy_remove_children (hierarchy, index); hierarchy_close (hierarchy, index, 1); - if (siblingIndex != null_transform) { + if (siblingIndex != nullent) { hierarchy_UpdateTransformIndices (hierarchy, index, -1); hierarchy_UpdateChildIndices (hierarchy, siblingIndex, -1); hierarchy_UpdateParentIndices (hierarchy, childIndex - 1, -1); @@ -360,7 +359,7 @@ Hierarchy_New (scene_t *scene, const hierarchy_type_t *type, int createRoot) if (createRoot) { hierarchy_open (hierarchy, 0, 1); - hierarchy_init (hierarchy, 0, null_transform, 1, 1); + hierarchy_init (hierarchy, 0, nullent, 1, 1); } return hierarchy; @@ -376,9 +375,9 @@ Hierarchy_Delete (hierarchy_t *hierarchy) scene_resources_t *res = hierarchy->scene->resources; for (uint32_t i = 0; i < hierarchy->num_objects; i++) { - PR_RESFREE (res->transforms, hierarchy->transform[i]); + PR_RESFREE (res->transforms, hierarchy->ref[i]); } - free (hierarchy->transform); + free (hierarchy->ref); free (hierarchy->childCount); free (hierarchy->childIndex); free (hierarchy->parentIndex); @@ -399,9 +398,9 @@ Hierarchy_Copy (scene_t *scene, const hierarchy_t *src) Hierarchy_Reserve (dst, count); for (size_t i = 0; i < count; i++) { - dst->transform[i] = __transform_alloc (scene); - dst->transform[i]->hierarchy = dst; - dst->transform[i]->index = i; + dst->ref[i] = __transform_alloc (scene); + dst->ref[i]->hierarchy = dst; + dst->ref[i]->index = i; } Component_CopyElements (&childCount_component, diff --git a/libs/scene/scene.c b/libs/scene/scene.c index 215eb7b5e..54f3f4bc9 100644 --- a/libs/scene/scene.c +++ b/libs/scene/scene.c @@ -140,8 +140,8 @@ Scene_CreateEntity (scene_t *scene) ent->transform = Transform_New (scene, 0); ent->id = PR_RESINDEX (res->entities, ent); - hierarchy_t *h = ent->transform->hierarchy; - h->entity[ent->transform->index] = ent; + hierarchy_t *h = ent->transform->ref.hierarchy; + h->entity[ent->transform->ref.index] = ent; QuatSet (1, 1, 1, 1, ent->renderer.colormod); @@ -164,13 +164,13 @@ destroy_entity (scene_t *scene, entity_t *ent) // Transform_Delete takes care of all hierarchy stuff (transforms // themselves, name strings, hierarchy table) - hierarchy_t *h = transform->hierarchy; + hierarchy_t *h = transform->ref.hierarchy; for (size_t i = 0; i < h->num_objects; i++) { entity_t *e = h->entity[0]; e->transform = 0; PR_RESFREE (res->entities, ent); } - Transform_Delete (transform); + Transform_Delete (scene, transform); } void @@ -183,7 +183,7 @@ Scene_DestroyEntity (scene_t *scene, entity_t *ent) } // pull the transform out of the hierarchy to make it easier to destory // all the child entities - Transform_SetParent (ent->transform, 0); + Transform_SetParent (scene, ent->transform, 0); destroy_entity (scene, ent); } @@ -204,5 +204,5 @@ transform_t * Scene_GetTransform (scene_t *scene, int id) { scene_resources_t *res = scene->resources; - return PR_RESGET (res->transforms, id); + return (transform_t *) PR_RESGET (res->transforms, id); } diff --git a/libs/scene/test/test-hierarchy.c b/libs/scene/test/test-hierarchy.c index 47fdf0814..b7c7a6ec3 100644 --- a/libs/scene/test/test-hierarchy.c +++ b/libs/scene/test/test-hierarchy.c @@ -6,6 +6,7 @@ #include #include +#include "QF/scene/component.h" #include "QF/scene/hierarchy.h" #include "QF/scene/scene.h" #include "QF/scene/transform.h" @@ -49,7 +50,7 @@ check_hierarchy_size (hierarchy_t *h, uint32_t size) } char **name = h->components[transform_type_name]; for (uint32_t i = 0; i < h->num_objects; i++) { - if (h->transform[i]->hierarchy != h) { + if (h->ref[i]->hierarchy != h) { printf ("transform %d (%s) does not point to hierarchy\n", i, name[i]); } @@ -63,7 +64,7 @@ dump_hierarchy (hierarchy_t *h) char **name = h->components[transform_type_name]; for (uint32_t i = 0; i < h->num_objects; i++) { printf ("%2d: %5s %2u %2u %2u %2u\n", i, name[i], - h->transform[i]->index, h->parentIndex[i], + h->ref[i]->index, h->parentIndex[i], h->childIndex[i], h->childCount[i]); } puts (""); @@ -73,12 +74,13 @@ static int check_indices (transform_t *transform, uint32_t index, uint32_t parentIndex, uint32_t childIndex, uint32_t childCount) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = &transform->ref; + hierarchy_t *h = ref->hierarchy; char **name = h->components[transform_type_name]; - if (transform->index != index) { + if (ref->index != index) { printf ("%s/%s index incorrect: expect %u got %u\n", - name[transform->index], name[index], - index, transform->index); + name[ref->index], name[index], + index, ref->index); return 0; } if (h->parentIndex[index] != parentIndex) { @@ -109,7 +111,7 @@ test_single_transform (void) printf ("Transform_New returned null\n"); return 1; } - if (!(h = transform->hierarchy)) { + if (!(h = transform->ref.hierarchy)) { printf ("New transform has no hierarchy\n"); return 1; } @@ -120,7 +122,7 @@ test_single_transform (void) vec4f_t *localRotation = h->components[transform_type_localRotation]; vec4f_t *localScale = h->components[transform_type_localScale]; if (!check_hierarchy_size (h, 1)) { return 1; } - if (!check_indices (transform, 0, null_transform, 1, 0)) { return 1; } + if (!check_indices (transform, 0, nullent, 1, 0)) { return 1; } if (!mat4_equal (localMatrix[0], identity) || !mat4_equal (localInverse[0], identity) @@ -137,7 +139,7 @@ test_single_transform (void) } // Delete the hierarchy directly as setparent isn't fully tested - Hierarchy_Delete (transform->hierarchy); + Hierarchy_Delete (transform->ref.hierarchy); return 0; } @@ -148,17 +150,17 @@ test_parent_child_init (void) transform_t *parent = Transform_New (scene, 0); transform_t *child = Transform_New (scene, parent); - if (parent->hierarchy != child->hierarchy) { + if (parent->ref.hierarchy != child->ref.hierarchy) { printf ("parent and child transforms have separate hierarchies\n"); return 1; } - if (!check_hierarchy_size (parent->hierarchy, 2)) { return 1; } + if (!check_hierarchy_size (parent->ref.hierarchy, 2)) { return 1; } - if (!check_indices (parent, 0, null_transform, 1, 1)) { return 1; } + if (!check_indices (parent, 0, nullent, 1, 1)) { return 1; } if (!check_indices (child, 1, 0, 2, 0)) { return 1; } - hierarchy_t *h = parent->hierarchy; + hierarchy_t *h = parent->ref.hierarchy; mat4f_t *localMatrix = h->components[transform_type_localMatrix]; mat4f_t *localInverse = h->components[transform_type_localInverse]; mat4f_t *worldMatrix = h->components[transform_type_worldMatrix]; @@ -194,7 +196,7 @@ test_parent_child_init (void) } // Delete the hierarchy directly as setparent isn't fully tested - Hierarchy_Delete (parent->hierarchy); + Hierarchy_Delete (parent->ref.hierarchy); return 0; } @@ -208,28 +210,28 @@ test_parent_child_setparent (void) Transform_SetName (parent, "parent"); Transform_SetName (child, "child"); - if (!check_indices (parent, 0, null_transform, 1, 0)) { return 1; } - if (!check_indices (child, 0, null_transform, 1, 0)) { return 1; } + if (!check_indices (parent, 0, nullent, 1, 0)) { return 1; } + if (!check_indices (child, 0, nullent, 1, 0)) { return 1; } - if (parent->hierarchy == child->hierarchy) { + if (parent->ref.hierarchy == child->ref.hierarchy) { printf ("parent and child transforms have same hierarchy before" " set paret\n"); return 1; } - Transform_SetParent (child, parent); + Transform_SetParent (scene,child, parent); - if (parent->hierarchy != child->hierarchy) { + if (parent->ref.hierarchy != child->ref.hierarchy) { printf ("parent and child transforms have separate hierarchies\n"); return 1; } - if (!check_hierarchy_size (parent->hierarchy, 2)) { return 1; } + if (!check_hierarchy_size (parent->ref.hierarchy, 2)) { return 1; } - if (!check_indices (parent, 0, null_transform, 1, 1)) { return 1; } + if (!check_indices (parent, 0, nullent, 1, 1)) { return 1; } if (!check_indices (child, 1, 0, 2, 0)) { return 1; } - hierarchy_t *h = parent->hierarchy; + hierarchy_t *h = parent->ref.hierarchy; mat4f_t *localMatrix = h->components[transform_type_localMatrix]; mat4f_t *localInverse = h->components[transform_type_localInverse]; mat4f_t *worldMatrix = h->components[transform_type_worldMatrix]; @@ -265,7 +267,7 @@ test_parent_child_setparent (void) } // Delete the hierarchy directly as setparent isn't fully tested - Hierarchy_Delete (parent->hierarchy); + Hierarchy_Delete (parent->ref.hierarchy); return 0; } @@ -280,14 +282,14 @@ test_build_hierarchy (void) 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 (root, 0, nullent, 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 (scene, B, "B1"); - if (!check_indices (root, 0, null_transform, 1, 3)) { return 1; } + if (!check_indices (root, 0, nullent, 1, 3)) { return 1; } if (!check_indices ( A, 1, 0, 4, 0)) { return 1; } if (!check_indices ( B, 2, 0, 4, 1)) { return 1; } if (!check_indices ( C, 3, 0, 5, 0)) { return 1; } @@ -295,7 +297,7 @@ test_build_hierarchy (void) transform_t *A1 = Transform_NewNamed (scene, A, "A1"); - if (!check_indices (root, 0, null_transform, 1, 3)) { return 1; } + if (!check_indices (root, 0, nullent, 1, 3)) { return 1; } if (!check_indices ( A, 1, 0, 4, 1)) { return 1; } if (!check_indices ( B, 2, 0, 5, 1)) { return 1; } if (!check_indices ( C, 3, 0, 6, 0)) { return 1; } @@ -307,9 +309,9 @@ test_build_hierarchy (void) 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; } + if (!check_hierarchy_size (root->ref.hierarchy, 11)) { return 1; } - if (!check_indices (root, 0, null_transform, 1, 3)) { return 1; } + if (!check_indices (root, 0, nullent, 1, 3)) { return 1; } if (!check_indices ( A, 1, 0, 4, 2)) { return 1; } if (!check_indices ( B, 2, 0, 6, 3)) { return 1; } if (!check_indices ( C, 3, 0, 9, 0)) { return 1; } @@ -323,9 +325,9 @@ test_build_hierarchy (void) transform_t *D = Transform_NewNamed (scene, root, "D"); - if (!check_hierarchy_size (root->hierarchy, 12)) { return 1; } + if (!check_hierarchy_size (root->ref.hierarchy, 12)) { return 1; } - if (!check_indices (root, 0, null_transform, 1, 4)) { return 1; } + if (!check_indices (root, 0, nullent, 1, 4)) { return 1; } if (!check_indices ( A, 1, 0, 5, 2)) { return 1; } if (!check_indices ( B, 2, 0, 7, 3)) { return 1; } if (!check_indices ( C, 3, 0, 10, 0)) { return 1; } @@ -338,12 +340,12 @@ test_build_hierarchy (void) if (!check_indices (A1a, 10, 5, 12, 0)) { return 1; } if (!check_indices (B2a, 11, 8, 12, 0)) { return 1; } - dump_hierarchy (root->hierarchy); + dump_hierarchy (root->ref.hierarchy); transform_t *C1 = Transform_NewNamed (scene, C, "C1"); - dump_hierarchy (root->hierarchy); - if (!check_hierarchy_size (root->hierarchy, 13)) { return 1; } + dump_hierarchy (root->ref.hierarchy); + if (!check_hierarchy_size (root->ref.hierarchy, 13)) { return 1; } - if (!check_indices (root, 0, null_transform, 1, 4)) { return 1; } + if (!check_indices (root, 0, nullent, 1, 4)) { return 1; } if (!check_indices ( A, 1, 0, 5, 2)) { return 1; } if (!check_indices ( B, 2, 0, 7, 3)) { return 1; } if (!check_indices ( C, 3, 0, 10, 1)) { return 1; } @@ -358,7 +360,7 @@ test_build_hierarchy (void) if (!check_indices (B2a, 12, 8, 13, 0)) { return 1; } // Delete the hierarchy directly as setparent isn't fully tested - Hierarchy_Delete (root->hierarchy); + Hierarchy_Delete (root->ref.hierarchy); return 0; } @@ -382,9 +384,9 @@ test_build_hierarchy2 (void) 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; } + if (!check_hierarchy_size (root->ref.hierarchy, 13)) { return 1; } - if (!check_indices (root, 0, null_transform, 1, 4)) { return 1; } + if (!check_indices (root, 0, nullent, 1, 4)) { return 1; } if (!check_indices ( A, 1, 0, 5, 2)) { return 1; } if (!check_indices ( B, 2, 0, 7, 3)) { return 1; } if (!check_indices ( C, 3, 0, 10, 1)) { return 1; } @@ -411,10 +413,10 @@ test_build_hierarchy2 (void) 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; } + dump_hierarchy (T->ref.hierarchy); + if (!check_hierarchy_size (T->ref.hierarchy, 12)) { return 1; } - if (!check_indices ( T, 0, null_transform, 1, 3)) { return 1; } + if (!check_indices ( T, 0, nullent, 1, 3)) { return 1; } if (!check_indices ( X, 1, 0, 4, 2)) { return 1; } if (!check_indices ( Y, 2, 0, 6, 3)) { return 1; } if (!check_indices ( Z, 3, 0, 9, 1)) { return 1; } @@ -427,13 +429,13 @@ test_build_hierarchy2 (void) if (!check_indices (X1a, 10, 4, 12, 0)) { return 1; } if (!check_indices (Y2a, 11, 7, 12, 0)) { return 1; } - Transform_SetParent (T, B); + Transform_SetParent (scene,T, B); - dump_hierarchy (root->hierarchy); + dump_hierarchy (root->ref.hierarchy); - if (!check_hierarchy_size (root->hierarchy, 25)) { return 1; } + if (!check_hierarchy_size (root->ref.hierarchy, 25)) { return 1; } - if (!check_indices (root, 0, null_transform, 1, 4)) { return 1; } + if (!check_indices (root, 0, nullent, 1, 4)) { return 1; } if (!check_indices ( A, 1, 0, 5, 2)) { return 1; } if (!check_indices ( B, 2, 0, 7, 4)) { return 1; } if (!check_indices ( C, 3, 0, 11, 1)) { return 1; } @@ -459,14 +461,14 @@ test_build_hierarchy2 (void) if (!check_indices (X1a, 23, 17, 25, 0)) { return 1; } if (!check_indices (Y2a, 24, 20, 25, 0)) { return 1; } - Transform_SetParent (Y, 0); + Transform_SetParent (scene,Y, 0); - dump_hierarchy (root->hierarchy); - dump_hierarchy (Y->hierarchy); - if (!check_hierarchy_size (root->hierarchy, 20)) { return 1; } - if (!check_hierarchy_size (Y->hierarchy, 5)) { return 1; } + dump_hierarchy (root->ref.hierarchy); + dump_hierarchy (Y->ref.hierarchy); + if (!check_hierarchy_size (root->ref.hierarchy, 20)) { return 1; } + if (!check_hierarchy_size (Y->ref.hierarchy, 5)) { return 1; } - if (!check_indices (root, 0, null_transform, 1, 4)) { return 1; } + if (!check_indices (root, 0, nullent, 1, 4)) { return 1; } if (!check_indices ( A, 1, 0, 5, 2)) { return 1; } if (!check_indices ( B, 2, 0, 7, 4)) { return 1; } if (!check_indices ( C, 3, 0, 11, 1)) { return 1; } @@ -487,15 +489,15 @@ test_build_hierarchy2 (void) if (!check_indices ( Z1, 18, 15, 20, 0)) { return 1; } if (!check_indices (X1a, 19, 16, 20, 0)) { return 1; } - if (!check_indices ( Y, 0, null_transform, 1, 3)) { return 1; } + if (!check_indices ( Y, 0, nullent, 1, 3)) { return 1; } if (!check_indices ( Y1, 1, 0, 4, 0)) { return 1; } if (!check_indices ( Y2, 2, 0, 4, 1)) { return 1; } if (!check_indices ( Y3, 3, 0, 5, 0)) { return 1; } if (!check_indices (Y2a, 4, 2, 5, 0)) { return 1; } // Delete the hierarchy directly as setparent isn't fully tested - Hierarchy_Delete (root->hierarchy); - Hierarchy_Delete (Y->hierarchy); + Hierarchy_Delete (root->ref.hierarchy); + Hierarchy_Delete (Y->ref.hierarchy); return 0; } @@ -534,7 +536,7 @@ test_frames (void) Transform_SetLocalPosition (B1, (vec4f_t) { 0, 1, 0, 1 }); Transform_SetLocalRotation (B1, (vec4f_t) { -0.5, 0.5, -0.5, 0.5 }); - hierarchy_t *h = root->hierarchy; + hierarchy_t *h = root->ref.hierarchy; mat4f_t *localMatrix = h->components[transform_type_localMatrix]; mat4f_t *localInverse = h->components[transform_type_localInverse]; mat4f_t *worldMatrix = h->components[transform_type_worldMatrix]; @@ -704,7 +706,7 @@ test_frames (void) return 1; } - Transform_Delete (root); + Transform_Delete (scene,root); return 0; } diff --git a/libs/scene/transform.c b/libs/scene/transform.c index 82ad54557..b1bef0234 100644 --- a/libs/scene/transform.c +++ b/libs/scene/transform.c @@ -133,16 +133,15 @@ static const hierarchy_type_t transform_type = { .components = transform_components, }; -transform_t * +hierref_t * __transform_alloc (scene_t *scene) { scene_resources_t *res = scene->resources; - transform_t *transform = PR_RESNEW_NC (res->transforms); - transform->scene = scene; - transform->id = PR_RESINDEX (res->transforms, transform); - transform->hierarchy = 0; - transform->index = 0; - return transform; + hierref_t *ref = PR_RESNEW_NC (res->transforms); + ref->id = PR_RESINDEX (res->transforms, ref); + ref->hierarchy = 0; + ref->index = 0; + return ref; } static void @@ -235,31 +234,32 @@ Transform_UpdateMatrices (hierarchy_t *h) transform_t * Transform_New (scene_t *scene, transform_t *parent) { - transform_t *transform = __transform_alloc (scene); + hierref_t *transform = __transform_alloc (scene); + __auto_type ref = (hierref_t *) transform; if (parent) { - transform->hierarchy = parent->hierarchy; - transform->index = Hierarchy_InsertHierarchy (parent->hierarchy, 0, - parent->index, 0); + ref->hierarchy = parent->ref.hierarchy; + ref->index = Hierarchy_InsertHierarchy (parent->ref.hierarchy, 0, + parent->ref.index, 0); } else { - transform->hierarchy = Hierarchy_New (scene, &transform_type, 1); - transform->index = 0; + ref->hierarchy = Hierarchy_New (scene, &transform_type, 1); + ref->index = 0; } - transform->hierarchy->transform[transform->index] = transform; - Transform_UpdateMatrices (transform->hierarchy); - return transform; + ref->hierarchy->ref[ref->index] = transform; + Transform_UpdateMatrices (ref->hierarchy); + return (transform_t *) transform; } void -Transform_Delete (transform_t *transform) +Transform_Delete (scene_t *scene, transform_t *transform) { - if (transform->index != 0) { + if (transform->ref.index != 0) { // The transform is not the root, so pull it out of its current // hierarchy so deleting it is easier - Transform_SetParent (transform, 0); + Transform_SetParent (scene, transform, 0); } // Takes care of freeing the transforms - Hierarchy_Delete (transform->hierarchy); + Hierarchy_Delete (transform->ref.hierarchy); } transform_t * @@ -271,118 +271,125 @@ Transform_NewNamed (scene_t *scene, transform_t *parent, const char *name) } void -Transform_SetParent (transform_t *transform, transform_t *parent) +Transform_SetParent (scene_t *scene, transform_t *transform, + transform_t *parent) { if (parent) { - hierarchy_t *hierarchy = transform->hierarchy; - uint32_t index = transform->index; - Hierarchy_InsertHierarchy (parent->hierarchy, hierarchy, - parent->index, index); + hierarchy_t *hierarchy = transform->ref.hierarchy; + uint32_t index = transform->ref.index; + Hierarchy_InsertHierarchy (parent->ref.hierarchy, hierarchy, + parent->ref.index, index); Hierarchy_RemoveHierarchy (hierarchy, index); if (!hierarchy->num_objects) { Hierarchy_Delete (hierarchy); } } else { // null parent -> make transform root - if (!transform->index) { + if (!transform->ref.index) { // already root return; } - hierarchy_t *hierarchy = transform->hierarchy; - uint32_t index = transform->index; + hierarchy_t *hierarchy = transform->ref.hierarchy; + uint32_t index = transform->ref.index; - hierarchy_t *new_hierarchy = Hierarchy_New (transform->scene, - &transform_type, 0); - Hierarchy_InsertHierarchy (new_hierarchy, hierarchy, null_transform, + hierarchy_t *new_hierarchy = Hierarchy_New (scene, &transform_type, 0); + Hierarchy_InsertHierarchy (new_hierarchy, hierarchy, nullent, index); Hierarchy_RemoveHierarchy (hierarchy, index); } - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; byte *modified = h->components[transform_type_modified]; - modified[transform->index] = 1; + modified[ref->index] = 1; Transform_UpdateMatrices (h); } void Transform_SetName (transform_t *transform, const char *_name) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; char **name = h->components[transform_type_name]; //FIXME create a string pool (similar to qfcc's, or even move that to util) - if (name[transform->index]) { - free (name[transform->index]); + if (name[ref->index]) { + free (name[ref->index]); } - name[transform->index] = strdup (_name); + name[ref->index] = strdup (_name); } void Transform_SetTag (transform_t *transform, uint32_t _tag) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; uint32_t *tag = h->components[transform_type_tag]; - tag[transform->index] = _tag; + tag[ref->index] = _tag; } void Transform_SetLocalPosition (transform_t *transform, vec4f_t position) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; mat4f_t *localMatrix = h->components[transform_type_localMatrix]; byte *modified = h->components[transform_type_modified]; - localMatrix[transform->index][3] = position; - modified[transform->index] = 1; + localMatrix[ref->index][3] = position; + modified[ref->index] = 1; Transform_UpdateMatrices (h); } void Transform_SetLocalRotation (transform_t *transform, vec4f_t rotation) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; mat4f_t *localMatrix = h->components[transform_type_localMatrix]; vec4f_t *localRotation = h->components[transform_type_localRotation]; vec4f_t *localScale = h->components[transform_type_localScale]; byte *modified = h->components[transform_type_modified]; - vec4f_t scale = localScale[transform->index]; + vec4f_t scale = localScale[ref->index]; mat4f_t mat; mat4fquat (mat, rotation); - localRotation[transform->index] = rotation; - localMatrix[transform->index][0] = mat[0] * scale[0]; - localMatrix[transform->index][1] = mat[1] * scale[1]; - localMatrix[transform->index][2] = mat[2] * scale[2]; - modified[transform->index] = 1; + localRotation[ref->index] = rotation; + localMatrix[ref->index][0] = mat[0] * scale[0]; + localMatrix[ref->index][1] = mat[1] * scale[1]; + localMatrix[ref->index][2] = mat[2] * scale[2]; + modified[ref->index] = 1; Transform_UpdateMatrices (h); } void Transform_SetLocalScale (transform_t *transform, vec4f_t scale) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; mat4f_t *localMatrix = h->components[transform_type_localMatrix]; vec4f_t *localRotation = h->components[transform_type_localRotation]; vec4f_t *localScale = h->components[transform_type_localScale]; byte *modified = h->components[transform_type_modified]; - vec4f_t rotation = localRotation[transform->index]; + vec4f_t rotation = localRotation[ref->index]; mat4f_t mat; mat4fquat (mat, rotation); - localScale[transform->index] = scale; - localMatrix[transform->index][0] = mat[0] * scale[0]; - localMatrix[transform->index][1] = mat[1] * scale[1]; - localMatrix[transform->index][2] = mat[2] * scale[2]; - modified[transform->index] = 1; + localScale[ref->index] = scale; + localMatrix[ref->index][0] = mat[0] * scale[0]; + localMatrix[ref->index][1] = mat[1] * scale[1]; + localMatrix[ref->index][2] = mat[2] * scale[2]; + modified[ref->index] = 1; Transform_UpdateMatrices (h); } void Transform_SetWorldPosition (transform_t *transform, vec4f_t position) { - if (transform->index) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + if (ref->index) { + hierarchy_t *h = ref->hierarchy; mat4f_t *worldInverse = h->components[transform_type_worldInverse]; - uint32_t parent = h->parentIndex[transform->index]; + uint32_t parent = h->parentIndex[ref->index]; position = mvmulf (worldInverse[parent], position); } Transform_SetLocalPosition (transform, position); @@ -391,10 +398,11 @@ Transform_SetWorldPosition (transform_t *transform, vec4f_t position) void Transform_SetWorldRotation (transform_t *transform, vec4f_t rotation) { - if (transform->index) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + if (ref->index) { + hierarchy_t *h = ref->hierarchy; vec4f_t *worldRotation = h->components[transform_type_worldRotation]; - uint32_t parent = h->parentIndex[transform->index]; + uint32_t parent = h->parentIndex[ref->index]; rotation = qmulf (qconjf (worldRotation[parent]), rotation); } Transform_SetLocalRotation (transform, rotation); @@ -404,7 +412,8 @@ void Transform_SetLocalTransform (transform_t *transform, vec4f_t scale, vec4f_t rotation, vec4f_t position) { - hierarchy_t *h = transform->hierarchy; + __auto_type ref = (const hierref_t *) transform; + hierarchy_t *h = ref->hierarchy; mat4f_t *localMatrix = h->components[transform_type_localMatrix]; vec4f_t *localRotation = h->components[transform_type_localRotation]; vec4f_t *localScale = h->components[transform_type_localScale]; @@ -413,12 +422,12 @@ Transform_SetLocalTransform (transform_t *transform, vec4f_t scale, mat4fquat (mat, rotation); position[3] = 1; - localRotation[transform->index] = rotation; - localScale[transform->index] = scale; - localMatrix[transform->index][0] = mat[0] * scale[0]; - localMatrix[transform->index][1] = mat[1] * scale[1]; - localMatrix[transform->index][2] = mat[2] * scale[2]; - localMatrix[transform->index][3] = position; - modified[transform->index] = 1; + localRotation[ref->index] = rotation; + localScale[ref->index] = scale; + localMatrix[ref->index][0] = mat[0] * scale[0]; + localMatrix[ref->index][1] = mat[1] * scale[1]; + localMatrix[ref->index][2] = mat[2] * scale[2]; + localMatrix[ref->index][3] = position; + modified[ref->index] = 1; Transform_UpdateMatrices (h); }