mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 07:11:41 +00:00
[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.
This commit is contained in:
parent
ac8c6b631e
commit
de786ce197
9 changed files with 246 additions and 221 deletions
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
||||
///@}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue