From 1cd9b71ba73db5045a202311cfac9a764aa5116f Mon Sep 17 00:00:00 2001 From: Shariq Shah Date: Tue, 30 Apr 2019 21:13:52 +1000 Subject: [PATCH] Implemented drawing entity projection mesh which shows the effect of the curernt transformation on the entity --- src/common/linmath.c | 12 ++- src/game/editor.c | 182 +++++++++++++++++++++++++++++++++++-------- src/game/editor.h | 78 ++++++++++--------- src/game/game.c | 2 +- src/game/im_render.c | 32 ++++++-- src/game/renderer.c | 32 -------- src/game/transform.c | 14 ++++ src/game/transform.h | 1 + todo.txt | 6 +- 9 files changed, 243 insertions(+), 116 deletions(-) diff --git a/src/common/linmath.c b/src/common/linmath.c index 7253589..47661f4 100755 --- a/src/common/linmath.c +++ b/src/common/linmath.c @@ -801,20 +801,24 @@ void quat_get_right(vec3* res, const quat* q) float quat_get_pitch(const quat* q) { - float result = (float)atan2(2 * (q->y * q->z + q->w * q->x), q->w * q->w - q->x * q->x - q->y * q->y + q->z * q->z); - return result; + float check = 2.0f * (-q->y * q->z + q->w * q->x); + if(check < -0.995f || check > 0.995f) + return 0.f; + else + return TO_DEGREES(atan2f(2.f * (q->x * q->z + q->w * q->y), 1.f - 2.f * (q->x * q->x + q->y * q->y))); + //return TO_DEGREES(atan2f(2.f * (q->y * q->z + q->w * q->x), q->w * q->w - q->x * q->x - q->y * q->y + q->z * q->z)); } float quat_get_yaw(const quat* q) { float result = (float)asin(-2 * (q->x * q->z - q->w * q->y)); - return result; + return TO_DEGREES(result); } float quat_get_roll(const quat* q) { float result = atan2(2 * (q->x * q->y + q->w * q->z), q->w * q->w + q->x * q->x - q->y * q->y - q->z * q->z); - return result; + return TO_DEGREES(result); } void quat_mul_mat4(quat* res, quat* val, mat4* mat) diff --git a/src/game/editor.c b/src/game/editor.c index 25562be..e1f06bb 100755 --- a/src/game/editor.c +++ b/src/game/editor.c @@ -127,16 +127,19 @@ void editor_init(struct Editor* editor) editor->tool_rotate_amount = 0.f; editor->tool_rotate_increment = 5.f; editor->tool_rotate_arc_radius = 5.f; - editor->tool_rotate_arc_segments = 50.f; + editor->tool_rotate_arc_segments = 20.f; + editor->tool_rotate_starting_rotation = 0.f; editor->tool_rotate_rotation_started = false; editor->tool_rotate_allowed = false; editor->axis_line_length = 500.f; editor->picking_enabled = true; + editor->draw_entity_wireframe = false; + vec4_fill(&editor->projected_entity_color, 0.f, 1.f, 1.f, 1.f); vec3_fill(&editor->tool_scale_amount, 0.f, 0.f, 0.f); vec3_fill(&editor->tool_mesh_position, 0.f, 0.f, 0.f); vec4_fill(&editor->tool_mesh_color, 0.f, 1.f, 1.f, 1.f); - vec4_fill(&editor->selected_entity_colour, 0.96, 0.61, 0.17, 1.f); + vec4_fill(&editor->selected_entity_color, 0.96, 0.61, 0.17, 0.5f); vec4_fill(&editor->grid_color, 0.3f, 0.3f, 0.3f, 0.7f); vec4_fill(&editor->axis_color_x, 0.87, 0.32, 0.40, 1.f); vec4_fill(&editor->axis_color_y, 0.53, 0.67, 0.28, 1.f); @@ -150,6 +153,8 @@ void editor_init(struct Editor* editor) event_manager_subscribe(event_manager, EVT_MOUSEMOTION, &editor_on_mousemotion); event_manager_subscribe(event_manager, EVT_KEY_PRESSED, &editor_on_key_press); event_manager_subscribe(event_manager, EVT_KEY_RELEASED, &editor_on_key_release); + + editor->selected_entity_wireframe = scene_static_mesh_create(game_state_get()->scene, "EDITOR_SELECTED_ENTITY_WIREFRAME", NULL, "Sphere.pamesh", MAT_UNSHADED); } void editor_init_camera(struct Editor* editor, struct Hashmap* cvars) @@ -172,6 +177,8 @@ void editor_init_camera(struct Editor* editor, struct Hashmap* cvars) void editor_render(struct Editor* editor, struct Camera * active_camera) { + struct Game_State* game_state = game_state_get(); + struct Renderer* renderer = game_state->renderer; //Disabling this for now until better handling of bounding box and scale of the entity is implemented //Get the selected entity if any, see if it has a mesh and render it in the selected entity colour // if(editor->selected_entity) @@ -191,6 +198,67 @@ void editor_render(struct Editor* editor, struct Camera * active_camera) // } // } + if(game_state->editor->selected_entity) + { + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + /* Draw selected entity */ + if(editor->selected_entity->type == ET_STATIC_MESH) + { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + shader_bind(renderer->debug_shader); + { + static mat4 mvp; + shader_set_uniform_vec4(renderer->debug_shader, "debug_color", &editor->selected_entity_color); + struct Static_Mesh* mesh = (struct Static_Mesh*)editor->selected_entity; + struct Model* model = &mesh->model; + struct Transform* transform = &mesh->base.transform; + int geometry = model->geometry_index; + mat4_identity(&mvp); + mat4_mul(&mvp, &active_camera->view_proj_mat, &transform->trans_mat); + shader_set_uniform_mat4(renderer->debug_shader, "mvp", &mvp); + geom_render(geometry, GDM_TRIANGLES); + } + shader_unbind(); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + } + else + { + //For now just draw a placeholder sphere just to visually denote that the entity is selected + vec3 abs_pos; + quat abs_rot; + transform_get_absolute_position(editor->selected_entity, &abs_pos); + transform_get_absolute_rot(editor->selected_entity, &abs_rot); + im_sphere(1.f, abs_pos, abs_rot, editor->selected_entity_color, GDM_TRIANGLES, 1); + } + + /* Draw selected entity with projected transformation applied */ + if(editor->draw_entity_wireframe) + { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + shader_bind(renderer->debug_shader); + { + static mat4 mvp; + shader_set_uniform_vec4(renderer->debug_shader, "debug_color", &editor->projected_entity_color); + struct Static_Mesh* mesh = editor->selected_entity_wireframe; + struct Model* model = editor->selected_entity->type == ET_STATIC_MESH ? &((struct Static_Mesh*)editor->selected_entity)->model : &mesh->model; + struct Transform* transform = &mesh->base.transform; + int geometry = model->geometry_index; + mat4_identity(&mvp); + mat4_mul(&mvp, &active_camera->view_proj_mat, &transform->trans_mat); + shader_set_uniform_mat4(renderer->debug_shader, "mvp", &mvp); + geom_render(geometry, GDM_TRIANGLES); + } + shader_unbind(); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } + glDisable(GL_DEPTH_TEST); + glDisable(GL_BLEND); + } + vec3 position = { 0.f, 0.f, 0.f }; quat rotation = { 0.f, 0.f, 0.f, 1.f }; vec3 scale = { 1.f, 1.f, 1.f }; @@ -413,7 +481,7 @@ void editor_update(struct Editor* editor, float dt) nk_labelf(context, NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE, "Position at: %.1f %.1f %.1f", editor->tool_mesh_position.x, editor->tool_mesh_position.y, editor->tool_mesh_position.z); break; case EDITOR_MODE_ROTATE: - nk_labelf(context, NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE, "Rotation by: %.1f", editor->tool_rotate_amount); + nk_labelf(context, NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE, "Rotation by: %.1f", editor->tool_rotate_total_rotation); break; case EDITOR_MODE_SCALE: nk_labelf(context, NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE, "Scale to: %.1f %.1f %.1f", editor->tool_scale_amount.x, editor->tool_scale_amount.y, editor->tool_scale_amount.z); @@ -531,15 +599,6 @@ void editor_update(struct Editor* editor, float dt) break; } - //im_circle(editor->tool_rotate_arc_radius, editor->tool_rotate_arc_segments, false, editor->tool_mesh_position, rotation, editor->axis_color_z, 3); - // - //quat_axis_angle(&rotation, &UNIT_X, -90.f); - //im_circle(editor->tool_rotate_arc_radius, editor->tool_rotate_arc_segments, false, editor->tool_mesh_position, rotation, editor->axis_color_y, 3); - - //quat_identity(&rotation); - //quat_axis_angle(&rotation, &UNIT_Y, -90.f); - //im_circle(editor->tool_rotate_arc_radius, editor->tool_rotate_arc_segments, false, editor->tool_mesh_position, rotation, editor->axis_color_x, 3); - if(editor->current_axis != EDITOR_AXIS_NONE) { quat_identity(&rotation); @@ -547,8 +606,8 @@ void editor_update(struct Editor* editor, float dt) switch(editor->current_axis) { case EDITOR_AXIS_X: quat_axis_angle(&rotation, &UNIT_Y, -90.f); vec4_assign(&arc_color, &editor->axis_color_x); break; - case EDITOR_AXIS_Y: quat_axis_angle(&rotation, &UNIT_X, -90.f); vec4_assign(&arc_color, &editor->axis_color_y) ;break; - case EDITOR_AXIS_Z: vec4_assign(&arc_color, &editor->axis_color_z); break; + case EDITOR_AXIS_Y: quat_axis_angle(&rotation, &UNIT_X, 90.f); vec4_assign(&arc_color, &editor->axis_color_y); break; + case EDITOR_AXIS_Z: quat_axis_angle(&rotation, &UNIT_Y, 180.f); vec4_assign(&arc_color, &editor->axis_color_z); break; } if(editor->tool_rotate_allowed) @@ -557,10 +616,11 @@ void editor_update(struct Editor* editor, float dt) im_circle(editor->tool_rotate_arc_radius, editor->tool_rotate_arc_segments, true, editor->tool_mesh_position, rotation, arc_color, 2); } - if(editor->tool_rotate_amount != 0.f) + if(editor->tool_rotate_total_rotation != 0.f) { arc_color.w = 0.5f; - im_arc(editor->tool_rotate_arc_radius / 2.f, 0.f, editor->tool_rotate_amount, editor->tool_rotate_arc_segments, true, editor->tool_mesh_position, rotation, arc_color, 4); + log_message("Starting: %f", editor->tool_rotate_starting_rotation); + im_arc(editor->tool_rotate_arc_radius / 2.f, editor->tool_rotate_starting_rotation, editor->tool_rotate_total_rotation, editor->tool_rotate_arc_segments, true, editor->tool_mesh_position, rotation, arc_color, 4); } } } @@ -599,7 +659,14 @@ void editor_on_mousebutton_release(const struct Event* event) { //For now, just select the first entity that is intersected struct Entity* intersected_entity = ray_result.entities_intersected[0]; - editor_entity_select(editor, intersected_entity); + if(intersected_entity == editor->selected_entity_wireframe) + { + if(ray_result.num_entities_intersected > 1) + intersected_entity = ray_result.entities_intersected[1]; + else + intersected_entity = NULL; + } + if(intersected_entity) editor_entity_select(editor, intersected_entity); } else { @@ -628,21 +695,25 @@ void editor_on_mousebutton_release(const struct Event* event) { editor->picking_enabled = true; editor->tool_rotate_rotation_started = false; + transform_copy(editor->selected_entity, editor->selected_entity_wireframe, false); + editor->tool_rotate_total_rotation = 0.f; + editor->tool_rotate_starting_rotation = 0.f; + editor->draw_entity_wireframe = false; if(editor->tool_rotate_amount != 0.f) { - vec3 axis = { 0.f, 0.f, 0.f }; - bool should_rotate = true; - switch(editor->current_axis) - { - case EDITOR_AXIS_X: vec3_assign(&axis, &UNIT_X); break; - case EDITOR_AXIS_Y: vec3_assign(&axis, &UNIT_Y); break; - case EDITOR_AXIS_Z: vec3_assign(&axis, &UNIT_Z); break; - default: should_rotate = false; - } - - if(should_rotate) - transform_rotate(editor->selected_entity, &axis, editor->tool_rotate_amount, TS_WORLD); - editor->tool_rotate_amount = 0.f; + //vec3 axis = { 0.f, 0.f, 0.f }; + //bool should_rotate = true; + //switch(editor->current_axis) + //{ + //case EDITOR_AXIS_X: vec3_assign(&axis, &UNIT_X); break; + //case EDITOR_AXIS_Y: vec3_assign(&axis, &UNIT_Y); break; + //case EDITOR_AXIS_Z: vec3_assign(&axis, &UNIT_Z); break; + //default: should_rotate = false; + //} + + //if(should_rotate) + // transform_rotate(editor->selected_entity, &axis, editor->tool_rotate_amount, TS_WORLD); + //editor->tool_rotate_amount = 0.f; } } } @@ -663,6 +734,14 @@ void editor_on_mousebutton_press(const struct Event* event) { editor->picking_enabled = false; editor->tool_rotate_rotation_started = true; + editor->tool_rotate_total_rotation = 0.f; + editor->draw_entity_wireframe = true; + switch(editor->current_axis) + { + case EDITOR_AXIS_X: editor->tool_rotate_starting_rotation = roundf(quat_get_pitch(&editor->selected_entity->transform.rotation)); break; + case EDITOR_AXIS_Y: editor->tool_rotate_starting_rotation = roundf(quat_get_yaw(&editor->selected_entity->transform.rotation)); break; + case EDITOR_AXIS_Z: editor->tool_rotate_starting_rotation = roundf(quat_get_roll(&editor->selected_entity->transform.rotation)); break; + } } } @@ -724,6 +803,7 @@ void editor_on_mousemotion(const struct Event* event) editor->tool_mesh_position.x = roundf(editor->tool_mesh_position.x / editor->grid_scale) * editor->grid_scale; editor->tool_mesh_position.y = roundf(editor->tool_mesh_position.y / editor->grid_scale) * editor->grid_scale; editor->tool_mesh_position.z = roundf(editor->tool_mesh_position.z / editor->grid_scale) * editor->grid_scale; + transform_set_position(editor->selected_entity_wireframe, &editor->tool_mesh_position); } } } @@ -791,6 +871,28 @@ void editor_on_mousemotion(const struct Event* event) editor->tool_rotate_amount = editor->tool_rotate_amount - 360.f; else if(editor->tool_rotate_amount < -360.f) editor->tool_rotate_amount = editor->tool_rotate_amount + 360.f; + + if(editor->tool_rotate_amount != 0.f) + { + vec3 axis = { 0.f, 0.f, 0.f }; + bool should_rotate = true; + switch(editor->current_axis) + { + case EDITOR_AXIS_X: vec3_assign(&axis, &UNIT_X); break; + case EDITOR_AXIS_Y: vec3_assign(&axis, &UNIT_Y); break; + case EDITOR_AXIS_Z: vec3_assign(&axis, &UNIT_Z); break; + default: should_rotate = false; + } + + if(should_rotate) + transform_rotate(editor->selected_entity_wireframe, &axis, editor->tool_rotate_amount, TS_WORLD); + editor->tool_rotate_total_rotation += editor->tool_rotate_amount; + if(editor->tool_rotate_total_rotation > 360.f) + editor->tool_rotate_total_rotation = (int)editor->tool_rotate_total_rotation % 360; + else if(editor->tool_rotate_total_rotation < -360.f) + editor->tool_rotate_total_rotation = (int)editor->tool_rotate_total_rotation % -360; + editor->tool_rotate_amount = 0.f; + } } } @@ -860,7 +962,11 @@ void editor_mode_set(struct Editor* editor, int mode) { editor->current_mode = mode; } - + + if(editor->selected_entity && editor->current_mode == EDITOR_MODE_TRANSLATE) + editor->draw_entity_wireframe = true; + else + editor->draw_entity_wireframe = false; editor_tool_reset(editor); } @@ -880,20 +986,28 @@ void editor_entity_select(struct Editor* editor, struct Entity* entity) editor->selected_entity = NULL; } + if(editor->current_mode == EDITOR_MODE_TRANSLATE) editor->draw_entity_wireframe = true; entity->editor_selected = true; editor->selected_entity = entity; transform_get_absolute_position(editor->selected_entity, &editor->tool_mesh_position); + transform_copy(editor->selected_entity_wireframe, editor->selected_entity, false); } } void editor_tool_reset(struct Editor* editor) { if(editor->selected_entity) + { transform_get_absolute_position(editor->selected_entity, &editor->tool_mesh_position); + transform_copy(editor->selected_entity_wireframe, editor->selected_entity, false); + } else + { vec3_fill(&editor->tool_mesh_position, 0.f, 0.f, 0.f); + } editor->tool_rotate_amount = 0.f; + editor->tool_rotate_total_rotation = 0.f; editor->tool_rotate_allowed = false; editor->tool_rotate_rotation_started = false; editor->picking_enabled = true; @@ -1235,9 +1349,9 @@ void editor_window_property_inspector(struct nk_context* context, struct Editor* quat abs_rot = { 0.f, 0.f, 0.f, 1.f }; transform_get_absolute_rot(entity, &abs_rot); vec3 rot_angles = { 0.f, 0.f, 0.f }; - rot_angles.x = TO_DEGREES(quat_get_pitch(&abs_rot)); - rot_angles.y = TO_DEGREES(quat_get_yaw(&abs_rot)); - rot_angles.z = TO_DEGREES(quat_get_roll(&abs_rot)); + rot_angles.x = quat_get_pitch(&abs_rot); + rot_angles.y = quat_get_yaw(&abs_rot); + rot_angles.z = quat_get_roll(&abs_rot); vec3 curr_rot = { rot_angles.x, rot_angles.y, rot_angles.z }; nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, "#X", -FLT_MAX, &curr_rot.x, FLT_MAX, 5.f, 1.f); diff --git a/src/game/editor.h b/src/game/editor.h index aa71de6..6bff8f3 100755 --- a/src/game/editor.h +++ b/src/game/editor.h @@ -7,45 +7,51 @@ struct Camera; struct Entity; struct Hashmap; +struct Static_Mesh; struct Editor { - int window_settings_renderer; - int window_settings_editor; - int window_scene_heirarchy; - int window_property_inspector; - int window_debug_variables; - int camera_looking_around; - struct Entity* selected_entity; - int top_panel_height; - float camera_turn_speed; - float camera_move_speed; - float camera_sprint_multiplier; - vec4 selected_entity_colour; - int current_mode; - int current_axis; - int previous_axis; - int grid_enabled; - int grid_relative; - vec4 grid_color; - int grid_num_lines; - float grid_scale; - int tool_snap_enabled; - vec3 tool_mesh_position; - vec4 tool_mesh_color; - int tool_mesh_draw_enabled; - float tool_rotate_arc_radius; - int tool_rotate_arc_segments; - float tool_rotate_amount; - bool tool_rotate_allowed; - bool tool_rotate_rotation_started; - float tool_rotate_increment; - vec3 tool_scale_amount; - float axis_line_length; - vec4 axis_color_x; - vec4 axis_color_y; - vec4 axis_color_z; - bool picking_enabled; + int window_settings_renderer; + int window_settings_editor; + int window_scene_heirarchy; + int window_property_inspector; + int window_debug_variables; + int camera_looking_around; + struct Entity* selected_entity; + struct Static_Mesh* selected_entity_wireframe; + vec4 projected_entity_color; + bool draw_entity_wireframe; + int top_panel_height; + float camera_turn_speed; + float camera_move_speed; + float camera_sprint_multiplier; + vec4 selected_entity_color; + int current_mode; + int current_axis; + int previous_axis; + int grid_enabled; + int grid_relative; + vec4 grid_color; + int grid_num_lines; + float grid_scale; + int tool_snap_enabled; + vec3 tool_mesh_position; + vec4 tool_mesh_color; + int tool_mesh_draw_enabled; + float tool_rotate_arc_radius; + int tool_rotate_arc_segments; + float tool_rotate_amount; + bool tool_rotate_allowed; + bool tool_rotate_rotation_started; + float tool_rotate_increment; + float tool_rotate_total_rotation; + float tool_rotate_starting_rotation; + vec3 tool_scale_amount; + float axis_line_length; + vec4 axis_color_x; + vec4 axis_color_y; + vec4 axis_color_z; + bool picking_enabled; }; void editor_init(struct Editor* editor_state); diff --git a/src/game/game.c b/src/game/game.c index 128bdb6..b7c5d18 100755 --- a/src/game/game.c +++ b/src/game/game.c @@ -106,9 +106,9 @@ bool game_init(struct Window* window, struct Hashmap* cvars) physics_body_set_moved_callback(entity_rigidbody_on_move); physics_body_set_collision_callback(entity_rigidbody_on_collision); + scene_init(game_state->scene); editor_init(game_state->editor); renderer_init(game_state->renderer); - scene_init(game_state->scene); } /* Debug scene setup */ diff --git a/src/game/im_render.c b/src/game/im_render.c index df020b5..61984f3 100755 --- a/src/game/im_render.c +++ b/src/game/im_render.c @@ -168,26 +168,44 @@ void im_circle(float radius, int num_divisions, bool filled, vec3 position, quat void im_arc(float radius, float angle_start, float angle_end, int num_divisions, bool filled, vec3 position, quat rotation, vec4 color, int draw_order) { - im_begin(position, rotation, (vec3) { 1.f, 1.f, 1.f }, color, filled ? GDM_TRIANGLE_FAN : GDM_LINE_LOOP, draw_order); float arc_degrees = angle_end - angle_start; + if(fabsf(arc_degrees) < 0.01f) + return; + + im_begin(position, rotation, (vec3) { 1.f, 1.f, 1.f }, color, filled ? GDM_TRIANGLE_FAN : GDM_LINE_LOOP, draw_order); if(arc_degrees != 360) im_pos(0.f, 0.f, 0.f); if(arc_degrees > 360.f) + { arc_degrees = (int)arc_degrees % 360; - if(arc_degrees < -360.f) + angle_end = arc_degrees; + } + else if(arc_degrees < -360.f) + { arc_degrees = (int)arc_degrees % -360; - + angle_end = arc_degrees; + } + + if(fabsf(arc_degrees) < 0.01f) + arc_degrees = arc_degrees < 0.f ? -0.01f : 0.01f; float increment = arc_degrees / num_divisions; + if(fabsf(increment) < 0.01f) + increment = increment < 0.f ? -0.01f : 0.01f; + if(angle_start < angle_end) { - for(float i = angle_start; i <= arc_degrees; i += increment) - im_pos(sinf(i * M_PI / 180.f) * radius, cosf(i * M_PI / 180.f) * radius, 0.f); + int count = 0; + for(float i = angle_start; i <= angle_end; i += increment) + { + count++; + im_pos(sinf(i * M_PI / 180.f) * radius, cosf(i * M_PI / 180.f) * radius, 0.f); + } } else { - for(float i = angle_start; i >= arc_degrees; i += increment) + for(float i = angle_start; i >= angle_end; i += increment) im_pos(sinf(i * M_PI / 180.f) * radius, cosf(i * M_PI / 180.f) * radius, 0.f); } @@ -264,6 +282,8 @@ void im_render(struct Camera* active_viewer) } shader_unbind(); + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); IM_State.curr_geom = -1; IM_State.curr_vertex = 0; diff --git a/src/game/renderer.c b/src/game/renderer.c index a8574bc..a3b4b27 100755 --- a/src/game/renderer.c +++ b/src/game/renderer.c @@ -407,38 +407,6 @@ void renderer_render(struct Renderer* renderer, struct Scene* scene) if(game_state->game_mode == GAME_MODE_EDITOR) { editor_render(game_state->editor, active_camera); - if(game_state->editor->selected_entity) - { - if(game_state->editor->selected_entity->type == ET_STATIC_MESH) - { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - shader_bind(renderer->debug_shader); - { - static mat4 mvp; - shader_set_uniform_vec4(renderer->debug_shader, "debug_color", &game_state->editor->selected_entity_colour); - struct Static_Mesh* mesh = (struct Static_Mesh*)game_state->editor->selected_entity; - struct Model* model = &mesh->model; - struct Transform* transform = &mesh->base.transform; - int geometry = model->geometry_index; - mat4_identity(&mvp); - mat4_mul(&mvp, &active_camera->view_proj_mat, &transform->trans_mat); - shader_set_uniform_mat4(renderer->debug_shader, "mvp", &mvp); - geom_render(geometry, GDM_TRIANGLES); - } - shader_unbind(); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - - } - else - { - //For now just draw a placeholder sphere just to visually denote that the entity is selected - vec3 abs_pos; - quat abs_rot; - transform_get_absolute_position(game_state->editor->selected_entity, &abs_pos); - transform_get_absolute_rot(game_state->editor->selected_entity, &abs_rot); - im_sphere(1.f, abs_pos, abs_rot, game_state->editor->selected_entity_colour, GDM_TRIANGLES, 1); - } - } } //Immediate mode geometry render diff --git a/src/game/transform.c b/src/game/transform.c index 03a68c1..c5a1f44 100755 --- a/src/game/transform.c +++ b/src/game/transform.c @@ -3,7 +3,9 @@ #include "../common/array.h" #include "entity.h" #include "../common/utils.h" + #include +#include void transform_init(struct Entity* entity, struct Entity* parent) { @@ -66,6 +68,18 @@ void transform_parent_set(struct Entity* child, struct Entity* parent, bool upda if(update_transmat) transform_update_transmat(child); } +void transform_copy(struct Entity* copy_to, struct Entity* copy_from, bool copy_parent) +{ + struct Entity* current_parent = copy_to->transform.parent; + struct Entity** current_children = copy_to->transform.children; + + memcpy(©_to->transform, ©_from->transform, sizeof(struct Transform)); + if(copy_parent) + transform_parent_set(copy_to, current_parent, true); + + copy_to->transform.children = current_children; +} + void transform_translate(struct Entity* entity, vec3* amount, enum Transform_Space space) { struct Transform* transform = &entity->transform; diff --git a/src/game/transform.h b/src/game/transform.h index fc05350..8614067 100755 --- a/src/game/transform.h +++ b/src/game/transform.h @@ -32,5 +32,6 @@ 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); +void transform_copy(struct Entity* copy_to, struct Entity* copy_from, bool copy_parent); #endif diff --git a/todo.txt b/todo.txt index 9077521..d7fe822 100644 --- a/todo.txt +++ b/todo.txt @@ -1,7 +1,4 @@ Todo: - - Rotate mesh along mouse movement or show what the rotation is going to look like by using a wireframe version of mesh when rotating - - Match amount to be rotate with actual axes and the gizmo arc being drawn - - Handle all other axes combinations - Better, more accurate picking - Editor related messages/notifications in the bottom status bar - Highlight if we are about to select an entity or perform the tool action like translate when mouse is hovered and an entity can be selected at that location @@ -267,4 +264,7 @@ Done: * Remove fixed editor windows locations and bring back floating windows * Only show rotation gizmo for one axis at a time * Cancel tool action when right click is pressed in between + * Rotate mesh along mouse movement or show what the rotation is going to look like by using a wireframe version of mesh when rotating + * Match amount to be rotate with actual axes and the gizmo arc being drawn + * Handle all other axes combinations