Started adding heirarchical transformations

dev
Shariq Shah 10 years ago
parent 820fd6880e
commit c97dbf5777
  1. 10
      src/camera.c
  2. 13
      src/entity.c
  3. 4
      src/entity.h
  4. 117
      src/game.c
  5. 4
      src/linmath.h
  6. 2
      src/model.c
  7. 119
      src/scene.c
  8. 16
      src/scene.h
  9. 64
      src/transform.c
  10. 2
      src/transform.h

@ -56,7 +56,8 @@ int camera_create(int node, int width, int height)
new_camera->farz = 1000.f;
new_camera->nearz = 0.1f;
new_camera->fov = TO_RADIANS(60.f);
new_camera->aspect_ratio = ((float)width / (float)height) <= 0.f ? (4.f / 3.f) : ((float)width / (float)height);
float aspect_ratio = (float)width / (float)height;
new_camera->aspect_ratio = aspect_ratio <= 0.f ? (4.f / 3.f) : aspect_ratio;
new_camera->ortho = 0;
mat4_identity(new_camera->view_mat);
mat4_identity(new_camera->proj_mat);
@ -76,10 +77,11 @@ void camera_update_view(struct Camera* camera)
{
struct Entity* entity = entity_get(camera->node);
struct Transform* transform = entity_component_get(entity, C_TRANSFORM);
vec3 lookat = {0.f}, up = {0.f};
transform_get_lookat(transform, lookat);
vec3 lookat = {0.f}, up = {0.f}, position = {0.f};
transform_get_absolute_lookat(transform, lookat);
transform_get_up(transform, up);
mat4_look_at(camera->view_mat, transform->position, lookat, up);
transform_get_absolute_pos(transform, position);
mat4_look_at(camera->view_mat, position, lookat, up);
camera_update_view_proj(camera);
}

@ -46,6 +46,8 @@ void entity_remove(int index)
}
}
entity->node = -1;
entity->parent = -1;
array_free(entity->children);
free(entity->name);
free(entity->tag);
entity->name = entity->tag = NULL;
@ -76,6 +78,8 @@ struct Entity* entity_create(const char* name, const char* tag)
new_entity->name = name ? str_new(name) : str_new("DEFAULT_NAME");
new_entity->tag = tag ? str_new(tag) : str_new("DEFAULT_TAG");
new_entity->node = index;
new_entity->parent = -1;
new_entity->children = array_new(int);
for(int i = 0; i < MAX_COMPONENTS; i++)
new_entity->components[i] = -1;
new_entity->components[C_TRANSFORM] = transform_create(new_entity->node);
@ -88,8 +92,8 @@ struct Entity* entity_get(int index)
struct Entity* entity = NULL;
if(index >= 0 && index < array_len(entity_list))
entity = &entity_list[index];
else
log_error("entity:get", "Invalid index '%d'", index);
/* else */
/* log_error("entity:get", "Invalid index '%d'", index); */
return entity;
}
@ -224,3 +228,8 @@ void entity_sync_components(struct Entity* entity)
camera_update_view(camera);
}
}
struct Entity* entity_get_all(void)
{
return entity_list;
}

@ -2,7 +2,6 @@
#define entity_H
#include "components.h"
#include "num_types.h"
struct Entity
{
@ -10,6 +9,8 @@ struct Entity
char* name;
char* tag;
int components[MAX_COMPONENTS];
int parent;
int* children;
};
void entity_init(void);
@ -18,6 +19,7 @@ void entity_remove(int index);
struct Entity* entity_create(const char* name, const char* tag);
struct Entity* entity_get(int index);
struct Entity* entity_find(const char* name);
struct Entity* entity_get_all(void);
int entity_component_remove(struct Entity* entity, enum Component component);
void* entity_component_get(struct Entity* entity, enum Component component);
void* entity_component_add(struct Entity* entity, enum Component component, ...);

@ -16,14 +16,15 @@
#include "transform.h"
#include "camera.h"
#include "model.h"
#include "scene.h"
void run(void);
void update(float dt);
void render(void);
void debug(float dt);
struct Entity* entity = NULL;
struct Camera* active_camera = NULL;
int player_node = -1;
int player_pitch_node = -1;
void game_init(void)
{
@ -35,21 +36,26 @@ void game_init(void)
shader_init();
transform_init();
camera_init();
entity_init();
geom_init();
model_init();
entity_init();
scene_init();
int up_keys[2] = {'W', GLFW_KEY_UP};
int down_keys[2] = {'S', GLFW_KEY_DOWN};
int forward_keys[2] = {'W', GLFW_KEY_UP};
int backward_keys[2] = {'S', GLFW_KEY_DOWN};
int up_keys[2] = {'Q'};
int down_keys[2] = {'E'};
int left_keys[2] = {'A', GLFW_KEY_LEFT};
int right_keys[2] = {'D', GLFW_KEY_RIGHT};
int turn_right_keys[1] = {'L'};
int turn_left_keys[1] = {'J'};
int turn_up_keys[1] = {'I'};
int turn_down_keys[1] = {'K'};
input_map_create("Move_Up", up_keys, 2);
input_map_create("Move_Down", down_keys, 2);
input_map_create("Move_Forward", forward_keys, 2);
input_map_create("Move_Backward", backward_keys, 2);
input_map_create("Move_Up", up_keys, 1);
input_map_create("Move_Down", down_keys, 1);
input_map_create("Move_Left", left_keys, 2);
input_map_create("Move_Right", right_keys, 2);
input_map_create("Turn_Right", turn_right_keys, 1);
@ -58,24 +64,27 @@ void game_init(void)
input_map_create("Turn_Down", turn_down_keys, 1);
int shader = shader_create("unshaded.vert", "unshaded.frag");
entity = entity_create("Test", "None");
active_camera = entity_component_add(entity, C_CAMERA, 800, 600);
struct Entity* player = scene_add_new("player", "None");
player_node = player->node;
vec3 viewer_pos = {0, 0, 10};
struct Transform* viewer_tran = entity_component_get(entity, C_TRANSFORM);
struct Transform* viewer_tran = entity_component_get(player, C_TRANSFORM);
transform_set_position(viewer_tran, viewer_pos);
struct Entity* player_pitch = scene_add_as_child("player_pitch", NULL, player);
player_pitch_node = player_pitch->node;
entity_component_add(player_pitch, C_CAMERA, 800, 600);
struct Entity* new_ent = entity_create("Model_Entity", NULL);
struct Entity* new_ent = scene_add_new("Model_Entity", NULL);
struct Transform* tran = entity_component_get(new_ent, C_TRANSFORM);
vec3 position = {0, 0, -5};
transform_translate(tran, position, TS_WORLD);
struct Model* model = entity_component_add(new_ent, C_MODEL, "default.pamesh");
struct Transform* model_tran = entity_component_get(new_ent, C_TRANSFORM);
vec3 axis = {0.f, 1.f, 0.f};
//vec3 axis = {0.f, 1.f, 0.f};
//transform_rotate(model_tran, axis, (45.f), TS_WORLD);
vec3 scale = {1, 1, 5};
transform_scale(model_tran, scale);
struct Entity* suz = entity_create("Suzanne", NULL);
struct Entity* suz = scene_add_as_child("Suzanne", NULL, new_ent);
entity_component_add(suz, C_MODEL, "suzanne.pamesh");
struct Transform* s_tran = entity_component_get(suz, C_TRANSFORM);
vec3 s_pos = {3, 0, 0};
@ -91,14 +100,17 @@ void game_init(void)
void debug(float dt)
{
struct Entity* entity = entity_get(player_node);
struct Entity* entity_pitch = entity_get(player_pitch_node);
struct Transform* transform = entity_component_get(entity, C_TRANSFORM);
struct Transform* pitch_transform = entity_component_get(entity_pitch, C_TRANSFORM);
float move_speed = 5.f, turn_speed = 50.f;
vec3 offset = {0, 0, 0};
float turn_up_down = 0.f;
float turn_left_right = 0.f;
float max_up_down = 60.f;
static float total_up_down_rot = 0.f;
vec3 rot_axis_up_down = {-1, 0, 0};
vec3 rot_axis_up_down = {1, 0, 0};
vec3 rot_axis_left_right = {0, 1, 0};
/* Look around */
@ -107,49 +119,73 @@ void debug(float dt)
if(input_map_state_get("Turn_Right", GLFW_PRESS)) turn_left_right += turn_speed;
if(input_map_state_get("Turn_Left", GLFW_PRESS)) turn_left_right -= turn_speed;
if(turn_up_down != 0.f)
turn_up_down *= dt;
turn_left_right *= dt;
total_up_down_rot += turn_up_down;
if(total_up_down_rot >= max_up_down)
{
total_up_down_rot += turn_up_down;
if(total_up_down_rot >= max_up_down)
{
total_up_down_rot = max_up_down;
turn_left_right = 0.f;
}
else if(total_up_down_rot <= -max_up_down)
{
total_up_down_rot = -max_up_down;
turn_left_right = 0.f;
}
if(turn_up_down != 0.f)
transform_rotate(transform, rot_axis_up_down, turn_up_down * dt, TS_LOCAL);
total_up_down_rot = max_up_down;
turn_up_down = 0.f;
}
else if(total_up_down_rot <= -max_up_down)
{
total_up_down_rot = -max_up_down;
turn_up_down = 0.f;
}
if(turn_left_right != 0.f)
transform_rotate(transform, rot_axis_left_right, turn_left_right * dt, TS_WORLD);
{
transform_rotate(transform, rot_axis_left_right, -turn_left_right, TS_WORLD);
vec3 up = {0.f};
vec3 forward = {0.f};
transform_get_up(transform, up);
transform_get_forward(transform, forward);
//log_message("Up : %.3f, %.3f, %.3f", up[0], up[1], up[2]);
log_message("Forward : %.3f, %.3f, %.3f", forward[0], forward[1], forward[2]);
}
if(turn_up_down != 0.f)
{
transform_rotate(pitch_transform, rot_axis_up_down, -turn_up_down, TS_LOCAL);
vec3 up = {0.f};
vec3 forward = {0.f};
transform_get_up(transform, up);
transform_get_forward(transform, forward);
//log_message("Up : %.3f, %.3f, %.3f", up[0], up[1], up[2]);
log_message("Forward : %.3f, %.3f, %.3f", forward[0], forward[1], forward[2]);
}
/* Movement */
if(input_map_state_get("Move_Up", GLFW_PRESS)) offset[2] -= move_speed;
if(input_map_state_get("Move_Down", GLFW_PRESS)) offset[2] += move_speed;
if(input_map_state_get("Move_Forward", GLFW_PRESS)) offset[2] -= move_speed;
if(input_map_state_get("Move_Backward", GLFW_PRESS)) offset[2] += move_speed;
if(input_map_state_get("Move_Left", GLFW_PRESS)) offset[0] -= move_speed;
if(input_map_state_get("Move_Right", GLFW_PRESS)) offset[0] += move_speed;
if(input_map_state_get("Move_Up", GLFW_PRESS)) offset[1] += move_speed;
if(input_map_state_get("Move_Down", GLFW_PRESS)) offset[1] -= move_speed;
vec3_scale(offset, offset, dt);
if(offset[0] != 0 || offset[2] != 0)
if(offset[0] != 0 || offset[2] != 0 || offset[1] != 0)
{
transform_translate(transform, offset, TS_LOCAL);
log_message("Position : %.3f, %.3f, %.3f",
transform->position[0],
transform->position[1],
transform->position[2]);
/* log_message("Position : %.3f, %.3f, %.3f", */
/* transform->position[0], */
/* transform->position[1], */
/* transform->position[2]); */
}
if(input_key_state_get(GLFW_KEY_SPACE, GLFW_PRESS))
{
struct Entity* model = entity_get(1);
struct Entity* model = entity_get(3);
struct Transform* mod_tran = entity_component_get(model, C_TRANSFORM);
vec3 x_axis = {1, 0, 0};
transform_rotate(mod_tran, x_axis, 25.f * dt, TS_WORLD);
}
if(input_key_state_get(GLFW_KEY_M, GLFW_PRESS))
{
struct Entity* model = entity_get(3);
struct Transform* mod_tran = entity_component_get(model, C_TRANSFORM);
vec3 y_axis = {0, 1, 0};
transform_rotate(mod_tran, y_axis, 25.f * dt, TS_WORLD);
transform_rotate(mod_tran, y_axis, 25.f * dt, TS_LOCAL);
}
}
@ -185,6 +221,7 @@ void render(void)
void game_cleanup(void)
{
scene_cleanup();
entity_cleanup();
model_cleanup();
geom_cleanup();

@ -396,7 +396,7 @@ static inline void mat4_perspective(mat4 m, float y_fov, float aspect, float n,
m[3][2] = -((2.f * f * n) / (f - n));
m[3][3] = 0.f;
}
static inline void mat4_look_at(mat4 m, vec3 eye, vec3 center, vec3 up)
static inline void mat4_look_at(mat4 m, vec3 eye, vec3 lookat, vec3 up)
{
/* Adapted from Android's OpenGL Matrix.java. */
/* See the OpenGL GLUT documentation for gluLookAt for a description */
@ -405,7 +405,7 @@ static inline void mat4_look_at(mat4 m, vec3 eye, vec3 center, vec3 up)
/* TODO: The negation of of can be spared by swapping the order of
* operands in the following cross products in the right way. */
vec3 f;
vec3_sub(f, center, eye);
vec3_sub(f, lookat, eye);
vec3_norm(f, f);
vec3 s;

@ -99,7 +99,7 @@ void model_render_all(struct Camera* camera)
shader_bind(model->shader);
mat4_mul(mvp, camera->view_proj_mat, transform->trans_mat);
shader_set_uniform_mat4(model->shader, "mvp", mvp);
vec4 color = {1, 0, 0, 1};
vec4 color = {0.7f, 0.7f, 0.5f, 1};
shader_set_uniform_vec4(model->shader, "color", color);
geom_render(model->geometry_index);
shader_unbind();

@ -0,0 +1,119 @@
#include "scene.h"
#include "array.h"
#include "entity.h"
#include "log.h"
#include "transform.h"
#include <assert.h>
#include <string.h>
static int root_node = -1;
void scene_init(void)
{
/* Add root node to scene */
struct Entity* root = entity_create("ROOT", NULL);
root_node = root->node;
}
struct Entity* scene_add_new(const char* name, const char* tag)
{
return scene_add_as_child(name, tag, scene_get_root());
}
struct Entity* scene_add_as_child(const char* name, const char* tag, struct Entity* parent)
{
assert(parent);
struct Entity* new_entity = NULL;
new_entity = entity_create(name, tag);
new_entity->parent = parent->node;
array_push(parent->children, new_entity->node, int);
struct Transform* new_ent_tran = entity_component_get(new_entity, C_TRANSFORM);
transform_update_transmat(new_ent_tran);
return new_entity;
}
void scene_remove(struct Entity* entity)
{
assert(entity);
for(int i = 0; i < array_len(entity->children); i++)
{
struct Entity* child = entity_get(entity->children[i]);
scene_remove(child);
}
entity_remove(entity->node);
}
void scene_reset_parent(struct Entity* entity, struct Entity* new_parent)
{
assert(entity && new_parent);
struct Entity* curr_parent = entity_get(entity->parent);
if(curr_parent)
{
/* find the index that the entity is at in the cuurent parent's
children array and remove it from there. Then set the new_parent
as the entity's parent */
int index = -1;
for(int i = 0; i < array_len(curr_parent->children); i++)
{
if(curr_parent->children[i] == entity->node)
{
index = i;
break;
}
}
if(index > -1)
{
array_remove_at(curr_parent->children, index);
entity->parent = new_parent->node;
array_push(new_parent, entity->node, int);
struct Transform* entity_tran = entity_component_get(entity, C_TRANSFORM);
transform_update_transmat(entity_tran);
}
else
{
log_error("scene:reset_parent", "Entity %s not found in it's parent '%s''s children array");
}
}
else
{
log_error("scene:reset_parent", "Cannot change parent of ROOT entity");
}
}
void scene_cleanup(void)
{
struct Entity* entity_list = entity_get_all();
for(int i = 0; i < array_len(entity_list); i++)
{
if(entity_list[i].node != -1)
entity_remove(i);
}
}
struct Entity* scene_find(const char* name)
{
return entity_find(name);
}
struct Entity* scene_get_root(void)
{
return entity_get(root_node);
}
struct Entity* scene_get_child_by_name(struct Entity* parent, const char* name)
{
assert(parent);
struct Entity* child = NULL;
for(int i = 0; i < array_len(parent->children); i++)
{
struct Entity* curr_child = entity_get(parent->children[i]);
if(strcmp(curr_child->name, name) == 0)
{
child = curr_child;
break;
}
}
return child;
}

@ -0,0 +1,16 @@
#ifndef scene_H
#define scene_H
struct Entity;
void scene_init(void);
void scene_remove(struct Entity* entity);
void scene_reset_parent(struct Entity* entity, struct Entity* new_parent);
void scene_cleanup(void);
struct Entity* scene_add_new(const char* name, const char* tag); /* Add as child of Root */
struct Entity* scene_add_as_child(const char* name, const char* tag, struct Entity* parent);
struct Entity* scene_find(const char* name);
struct Entity* scene_get_root(void);
struct Entity* scene_get_child_by_name(struct Entity* parent, const char* name);
#endif

@ -59,13 +59,24 @@ void transform_rotate(struct Transform* transform,
{
mat4 new_rot;
mat4_identity(new_rot);
mat4_rotate(new_rot, new_rot, axis[0], axis[1], axis[2], TO_RADIANS(angle));
//mat4_rotate(new_rot, new_rot, axis[0], axis[1], axis[2], TO_RADIANS(angle));
if(axis[0] == 1)
mat4_rotate_X(new_rot, new_rot, TO_RADIANS(angle));
if(axis[1] == 1)
mat4_rotate_Y(new_rot, new_rot, TO_RADIANS(angle));
if(axis[2] == 1)
mat4_rotate_Z(new_rot, new_rot, TO_RADIANS(angle));
//mat4_orthonormalize(new_rot, new_rot);
//mat4_orthonormalize(new_rot, temp);
if(space == TS_LOCAL)
mat4_mul(transform->rotation, transform->rotation, new_rot);
else if(space == TS_WORLD)
mat4_mul(transform->rotation, new_rot, transform->rotation);
//mat4_orthonormalize(transform->rotation, transform->rotation);
transform_update_transmat(transform);
}
void transform_scale(struct Transform* transform, vec3 scale)
{
transform->scale[0] = scale[0];
@ -77,7 +88,7 @@ void transform_scale(struct Transform* transform, vec3 scale)
void transform_get_forward(struct Transform* transform, vec3 res)
{
res[0] = 0; res[1] = 0; res[2] = -1;
mat4_mul_vec3(res, transform->rotation, res);
mat4_mul_vec3(res, transform->trans_mat, res);
}
void transform_get_lookat(struct Transform* transform, vec3 res)
@ -86,6 +97,14 @@ void transform_get_lookat(struct Transform* transform, vec3 res)
vec3_add(res, transform->position, res);
}
void transform_get_absolute_lookat(struct Transform* transform, vec3 res)
{
vec3 abs_position = {0.f};
transform_get_absolute_pos(transform, abs_position);
transform_get_forward(transform, res);
vec3_add(res, abs_position, res);
}
void transform_get_up(struct Transform* transform, vec3 res)
{
res[0] = 0; res[1] = 1; res[2] = 0;
@ -101,18 +120,37 @@ void transform_get_right(struct Transform* transform, vec3 res)
void transform_update_transmat(struct Transform* transform)
{
static mat4 scale, tran;
static mat4 scale, translation;
mat4_identity(scale);
mat4_identity(tran);
mat4_identity(translation);
mat4_identity(transform->trans_mat);
mat4_scale_aniso(scale, scale, transform->scale[0], transform->scale[1], transform->scale[2]);
mat4_translate(tran, transform->position[0], transform->position[1], transform->position[2]);
mat4_mul(transform->trans_mat, transform->trans_mat, tran);
mat4_translate(translation, transform->position[0], transform->position[1], transform->position[2]);
mat4_mul(transform->trans_mat, transform->trans_mat, translation);
mat4_mul(transform->trans_mat, transform->trans_mat, transform->rotation);
mat4_mul(transform->trans_mat, transform->trans_mat, scale);
struct Entity* entity = entity_get(transform->node);
struct Entity* parent = entity_get(entity->parent);
if(parent)
{
struct Transform* parent_tran = entity_component_get(parent, C_TRANSFORM);
mat4_mul(transform->trans_mat, transform->trans_mat, parent_tran->trans_mat);
//mat4_mul(transform->trans_mat, parent_tran->trans_mat, transform->trans_mat);
}
/* Update all children */
if(array_len(entity->children) > 0)
{
for(int i = 0; i < array_len(entity->children); i++)
{
struct Entity* child = entity_get(entity->children[i]);
struct Transform* child_tran = entity_component_get(child, C_TRANSFORM);
transform_update_transmat(child_tran);
}
}
entity_sync_components(entity);
}
@ -135,3 +173,15 @@ void transform_set_position(struct Transform* transform, vec3 new_position)
transform->position[i] = new_position[i];
transform_update_transmat(transform);
}
void transform_get_absolute_pos(struct Transform* transform, vec3 res)
{
struct Entity* entity = entity_get(transform->node);
struct Entity* parent = entity_get(entity->parent);
if(parent)
{
struct Transform* parent_tran = entity_component_get(parent, C_TRANSFORM);
transform_get_absolute_pos(parent_tran, res);
}
vec3_add(res, res, transform->position);
}

@ -31,5 +31,7 @@ void transform_get_lookat(struct Transform* transform, vec3 res);
void transform_get_up(struct Transform* transform, vec3 res);
void transform_get_right(struct Transform* transform, vec3 res);
void transform_update_transmat(struct Transform* transform);
void transform_get_absolute_pos(struct Transform* transform, vec3 res);
void transform_get_absolute_lookat(struct Transform* transform, vec3 res);
#endif

Loading…
Cancel
Save