diff --git a/orgfile.org b/orgfile.org index 5acc83f..9c6bbf5 100644 --- a/orgfile.org +++ b/orgfile.org @@ -238,6 +238,8 @@ x Font atlas proper cleanup ** DONE Array-based Hashmaps - State "DONE" from "TODO" [2017-05-07 Sun 18:42] ** TODO Sprite sheet animations +** DONE Fix bugs with heirarchical transformations +- State "DONE" from "TODO" [2017-06-01 Thu 00:20] ** TODO Replace orgfile with simple text readme and reduce duplication? ** TODO Ray picking ** TODO Remove reduntant "settings" structures and move all configuration stuff to config variables diff --git a/src/scene.c b/src/scene.c index 96f37fc..4c84c8a 100644 --- a/src/scene.c +++ b/src/scene.c @@ -24,12 +24,7 @@ struct Entity* scene_add_new(const char* name, const int type) struct Entity* scene_add_as_child(const char* name, const int type, int parent_id) { assert(parent_id > -1); - struct Entity* new_entity = NULL; - new_entity = entity_create(name, type, parent_id); - struct Entity* parent = entity_get(parent_id); - new_entity->transform.parent = parent->id; - transform_update_transmat(new_entity); - return new_entity; + return entity_create(name, type, parent_id); } void scene_remove(struct Entity* entity) diff --git a/src/transform.c b/src/transform.c index 6aacf6a..9ecf388 100644 --- a/src/transform.c +++ b/src/transform.c @@ -12,11 +12,60 @@ void transform_create(struct Entity* entity, int parent_entity) vec3_fill(&transform->scale, 1.f, 1.f, 1.f); quat_identity(&transform->rotation); mat4_identity(&transform->trans_mat); - transform->parent = parent_entity; transform->children = array_new(int); + transform->parent = -1; + if(parent_entity != -1) + transform_parent_set(entity, entity_get(parent_entity), false); transform_update_transmat(entity); } +void transform_child_add(struct Entity* parent, struct Entity* child, bool update_transmat) +{ + struct Transform* parent_transform = &parent->transform; + struct Transform* child_transform = &child->transform; + + /* Check if already added */ + for(int i = 0; i < array_len(parent_transform->children); i++) + if(parent_transform->children[i] == child->id) return; + + int* new_child_loc = array_grow(parent_transform->children, int); + *new_child_loc = child->id; + child_transform->parent = parent->id; + if(update_transmat) transform_update_transmat(child); +} + +bool transform_child_remove(struct Entity* parent, struct Entity* child) +{ + bool success = false; + struct Transform* parent_transform = &parent->transform; + for(int i = 0; i < array_len(parent_transform->children); i++) + { + if(parent_transform->children[i] == child->id) + { + array_remove_at(parent_transform, i); + child->transform.parent = -1; + success = true; + return success; + }; + } + return success; +} + +void transform_parent_set(struct Entity* child, struct Entity* parent, bool update_transmat) +{ + if(child->transform.parent == -1) + { + transform_child_add(parent, child, false); + } + else + { + transform_child_remove(parent, child); + transform_child_add(parent, child, false); + } + + if(update_transmat) transform_update_transmat(child); +} + void transform_translate(struct Entity* entity, vec3* amount, enum Transform_Space space) { struct Transform* transform = &entity->transform; diff --git a/src/transform.h b/src/transform.h index 2355073..f0994be 100644 --- a/src/transform.h +++ b/src/transform.h @@ -2,31 +2,35 @@ #define TRANSFORM_H #include "linmath.h" +#include "num_types.h" enum Transform_Space { TS_LOCAL, TS_PARENT, TS_WORLD}; struct Entity; -void transform_create(struct Entity* transform, int parent_entity); -void transform_destroy(struct Entity* transform); -void transform_translate(struct Entity* transform, vec3* amount, enum Transform_Space space); +void transform_create(struct Entity* entity, int parent_entity); +void transform_destroy(struct Entity* entity); +void transform_translate(struct Entity* entity, vec3* amount, enum Transform_Space space); void transform_rotate(struct Entity* transform, vec3* axis, float angle, enum Transform_Space space); -void transform_scale(struct Entity* transform, vec3* scale); -void transform_set_position(struct Entity* transform, vec3* new_position); -void transform_get_forward(struct Entity* transform, vec3* res); -void transform_get_lookat(struct Entity* transform, vec3* res); -void transform_get_up(struct Entity* transform, vec3* res); -void transform_get_right(struct Entity* transform, vec3* res); -void transform_update_transmat(struct Entity* transform); -void transform_get_absolute_pos(struct Entity* transform, vec3* res); -void transform_get_absolute_rot(struct Entity* transform, quat* res); -void transform_get_absolute_scale(struct Entity* transform, vec3* res); -void transform_get_absolute_lookat(struct Entity* transform, vec3* res); -void transform_get_absolute_up(struct Entity* transform, vec3* res); -void transform_get_absolute_right(struct Entity* transform, vec3* res); -void transform_get_absolute_forward(struct Entity* transform, vec3* res); +void transform_scale(struct Entity* entity, vec3* scale); +void transform_set_position(struct Entity* entity, vec3* new_position); +void transform_get_forward(struct Entity* entity, vec3* res); +void transform_get_lookat(struct Entity* entity, vec3* res); +void transform_get_up(struct Entity* entity, vec3* res); +void transform_get_right(struct Entity* entity, vec3* res); +void transform_update_transmat(struct Entity* entity); +void transform_get_absolute_pos(struct Entity* entity, vec3* res); +void transform_get_absolute_rot(struct Entity* entity, quat* res); +void transform_get_absolute_scale(struct Entity* entity, vec3* res); +void transform_get_absolute_lookat(struct Entity* entity, vec3* res); +void transform_get_absolute_up(struct Entity* entity, vec3* res); +void transform_get_absolute_right(struct Entity* entity, vec3* res); +void transform_get_absolute_forward(struct Entity* entity, vec3* res); +void transform_child_add(struct Entity* entity, struct Entity* child, bool update_transmat); +bool transform_child_remove(struct Entity* entity, struct Entity* child); +void transform_parent_set(struct Entity* entity, struct Entity* parent, bool update_transmat); #endif