Rewrote rotate tool behaviour to only show one axis at a time and fixed a renderer bug where all cameras are always rendererd

dev
Shariq Shah 6 years ago
parent 18e8b59017
commit 9ab4313db3
  1. 270
      src/game/editor.c
  2. 3
      src/game/editor.h
  3. 308
      src/game/renderer.c
  4. 10
      todo.txt

@ -55,11 +55,13 @@ enum Editor_Mode
enum Editor_Axis enum Editor_Axis
{ {
EDITOR_AXIS_XZ = 0, EDITOR_AXIS_NONE = 0,
EDITOR_AXIS_X, EDITOR_AXIS_X,
EDITOR_AXIS_Y, EDITOR_AXIS_Y,
EDITOR_AXIS_Z, EDITOR_AXIS_Z,
EDITOR_AXIS_NONE EDITOR_AXIS_XZ,
EDITOR_AXIS_XY,
EDITOR_AXIS_YZ,
}; };
static struct Debug_Variable* debug_vars_list = NULL; static struct Debug_Variable* debug_vars_list = NULL;
@ -98,6 +100,7 @@ static void editor_window_settings_editor(struct nk_context* context, struct Edi
static void editor_axis_set(struct Editor* editor, int axis); static void editor_axis_set(struct Editor* editor, int axis);
static void editor_entity_select(struct Editor* editor, struct Entity* entity); static void editor_entity_select(struct Editor* editor, struct Entity* entity);
static void editor_mode_set(struct Editor* editor, int mode); static void editor_mode_set(struct Editor* editor, int mode);
static void editor_tool_reset(struct Editor* editor);
void editor_init(struct Editor* editor) void editor_init(struct Editor* editor)
{ {
@ -125,7 +128,8 @@ void editor_init(struct Editor* editor)
editor->tool_rotate_increment = 5.f; editor->tool_rotate_increment = 5.f;
editor->tool_rotate_arc_radius = 5.f; editor->tool_rotate_arc_radius = 5.f;
editor->tool_rotate_arc_segments = 50.f; editor->tool_rotate_arc_segments = 50.f;
editor->tool_rotate_axis_selection_enabled = true; editor->tool_rotate_rotation_started = false;
editor->tool_rotate_allowed = false;
editor->axis_line_length = 500.f; editor->axis_line_length = 500.f;
editor->picking_enabled = true; editor->picking_enabled = true;
@ -359,15 +363,18 @@ void editor_update(struct Editor* editor, float dt)
} }
nk_layout_row_push(context, 0.1f); nk_layout_row_push(context, 0.1f);
static const char* editor_axes[] = { "Axis: XZ", "Axis: X", "Axis: Y", "Axis: Z", "Axis: None" }; static const char* editor_axes[] = { "Axis: None", "Axis: X", "Axis: Y", "Axis: Z", "Axis: XZ", "Axis: XY", "Axis: YZ" };
if(nk_combo_begin_label(context, editor_axes[editor->current_axis], nk_vec2(160, 125))) if(nk_combo_begin_label(context, editor_axes[editor->current_axis], nk_vec2(160, 125)))
{ {
nk_layout_row_dynamic(context, row_height, 1); nk_layout_row_dynamic(context, row_height, 1);
int axis = editor->current_axis; int axis = editor->current_axis;
axis = nk_option_label(context, "X", axis == EDITOR_AXIS_X) ? EDITOR_AXIS_X : axis; axis = nk_option_label(context, "X", axis == EDITOR_AXIS_X) ? EDITOR_AXIS_X : axis;
axis = nk_option_label(context, "Y", axis == EDITOR_AXIS_Y) ? EDITOR_AXIS_Y : axis; axis = nk_option_label(context, "Y", axis == EDITOR_AXIS_Y) ? EDITOR_AXIS_Y : axis;
axis = nk_option_label(context, "Z", axis == EDITOR_AXIS_Z) ? EDITOR_AXIS_Z : axis; axis = nk_option_label(context, "Z", axis == EDITOR_AXIS_Z) ? EDITOR_AXIS_Z : axis;
axis = nk_option_label(context, "XZ", axis == EDITOR_AXIS_XZ) ? EDITOR_AXIS_XZ : axis; axis = nk_option_label(context, "XZ", axis == EDITOR_AXIS_XZ) ? EDITOR_AXIS_XZ : axis;
axis = nk_option_label(context, "XY", axis == EDITOR_AXIS_XY) ? EDITOR_AXIS_XY : axis;
axis = nk_option_label(context, "YZ", axis == EDITOR_AXIS_YZ) ? EDITOR_AXIS_YZ : axis;
axis = nk_option_label(context, "None", axis == EDITOR_AXIS_NONE) ? EDITOR_AXIS_NONE : axis;
editor_axis_set(editor, axis); editor_axis_set(editor, axis);
nk_combo_end(context); nk_combo_end(context);
} }
@ -461,10 +468,6 @@ void editor_update(struct Editor* editor, float dt)
//Draw Axes //Draw Axes
switch(editor->current_axis) switch(editor->current_axis)
{ {
case EDITOR_AXIS_XZ:
im_line((vec3) { -editor->axis_line_length, 0.f, 0.f }, (vec3) { editor->axis_line_length, 0.f, 0.f }, editor->tool_mesh_position, rotation, scale, editor->axis_color_x, 3);
im_line((vec3) { 0.f, 0.f, -editor->axis_line_length }, (vec3) { 0.f, 0.f, editor->axis_line_length }, editor->tool_mesh_position, rotation, scale, editor->axis_color_z, 3);
break;
case EDITOR_AXIS_Y: case EDITOR_AXIS_Y:
im_line((vec3) { 0.f, -editor->axis_line_length, 0.f }, (vec3) { 0.f, editor->axis_line_length, 0.f }, editor->tool_mesh_position, rotation, scale, editor->axis_color_y, 3); im_line((vec3) { 0.f, -editor->axis_line_length, 0.f }, (vec3) { 0.f, editor->axis_line_length, 0.f }, editor->tool_mesh_position, rotation, scale, editor->axis_color_y, 3);
break; break;
@ -474,6 +477,18 @@ void editor_update(struct Editor* editor, float dt)
case EDITOR_AXIS_Z: case EDITOR_AXIS_Z:
im_line((vec3) { 0.f, 0.f, -editor->axis_line_length }, (vec3) { 0.f, 0.f, editor->axis_line_length }, editor->tool_mesh_position, rotation, scale, editor->axis_color_z, 3); im_line((vec3) { 0.f, 0.f, -editor->axis_line_length }, (vec3) { 0.f, 0.f, editor->axis_line_length }, editor->tool_mesh_position, rotation, scale, editor->axis_color_z, 3);
break; break;
case EDITOR_AXIS_XZ:
im_line((vec3) { -editor->axis_line_length, 0.f, 0.f }, (vec3) { editor->axis_line_length, 0.f, 0.f }, editor->tool_mesh_position, rotation, scale, editor->axis_color_x, 3);
im_line((vec3) { 0.f, 0.f, -editor->axis_line_length }, (vec3) { 0.f, 0.f, editor->axis_line_length }, editor->tool_mesh_position, rotation, scale, editor->axis_color_z, 3);
break;
case EDITOR_AXIS_XY:
im_line((vec3) { -editor->axis_line_length, 0.f, 0.f }, (vec3) { editor->axis_line_length, 0.f, 0.f }, editor->tool_mesh_position, rotation, scale, editor->axis_color_x, 3);
im_line((vec3) { 0.f, -editor->axis_line_length, 0.f }, (vec3) { 0.f, editor->axis_line_length, 0.f }, editor->tool_mesh_position, rotation, scale, editor->axis_color_y, 3);
break;
case EDITOR_AXIS_YZ:
im_line((vec3) { 0.f, -editor->axis_line_length, 0.f }, (vec3) { 0.f, editor->axis_line_length, 0.f }, editor->tool_mesh_position, rotation, scale, editor->axis_color_y, 3);
im_line((vec3) { 0.f, 0.f, -editor->axis_line_length }, (vec3) { 0.f, 0.f, editor->axis_line_length }, editor->tool_mesh_position, rotation, scale, editor->axis_color_z, 3);
break;
} }
} }
break; break;
@ -481,17 +496,46 @@ void editor_update(struct Editor* editor, float dt)
{ {
quat rotation = { 0.f, 0.f, 0.f, 1.f }; quat rotation = { 0.f, 0.f, 0.f, 1.f };
vec3 scale = { 1.f, 1.f, 1.f }; vec3 scale = { 1.f, 1.f, 1.f };
im_circle(editor->tool_rotate_arc_radius, editor->tool_rotate_arc_segments, false, editor->tool_mesh_position, rotation, editor->axis_color_z, 3); switch(editor->current_axis)
//im_arc(editor->tool_rotate_arc_radius, 0.f, 90.f, editor->tool_rotate_arc_segments, editor->tool_mesh_position, rotation, editor->axis_color_z, 3); {
case EDITOR_AXIS_X:
quat_axis_angle(&rotation, &UNIT_X, -90.f); 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_y, 3); im_circle(editor->tool_rotate_arc_radius, editor->tool_rotate_arc_segments, false, editor->tool_mesh_position, rotation, editor->axis_color_x, 3);
//im_arc(editor->tool_rotate_arc_radius, 90.f, 180.f, editor->tool_rotate_arc_segments, editor->tool_mesh_position, rotation, editor->axis_color_y, 3); break;
case EDITOR_AXIS_Y:
quat_identity(&rotation); quat_axis_angle(&rotation, &UNIT_X, -90.f);
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_y, 3);
im_circle(editor->tool_rotate_arc_radius, editor->tool_rotate_arc_segments, false, editor->tool_mesh_position, rotation, editor->axis_color_x, 3); break;
//im_arc(editor->tool_rotate_arc_radius, 0.f, 90.f, editor->tool_rotate_arc_segments, editor->tool_mesh_position, rotation, editor->axis_color_x, 3); case EDITOR_AXIS_Z:
im_circle(editor->tool_rotate_arc_radius, editor->tool_rotate_arc_segments, false, editor->tool_mesh_position, rotation, editor->axis_color_z, 3);
break;
case EDITOR_AXIS_XZ:
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_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);
break;
case EDITOR_AXIS_XY:
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);
quat_identity(&rotation);
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);
break;
case EDITOR_AXIS_YZ:
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);
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) if(editor->current_axis != EDITOR_AXIS_NONE)
{ {
@ -504,15 +548,17 @@ void editor_update(struct Editor* editor, float dt)
case EDITOR_AXIS_Z: vec4_assign(&arc_color, &editor->axis_color_z); break; case EDITOR_AXIS_Z: vec4_assign(&arc_color, &editor->axis_color_z); break;
} }
arc_color.w = 0.1f; if(editor->tool_rotate_allowed)
im_circle(editor->tool_rotate_arc_radius, editor->tool_rotate_arc_segments, true, editor->tool_mesh_position, rotation, arc_color, 2); {
arc_color.w = 0.1f;
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_amount != 0.f)
{ {
arc_color.w = 0.5f; 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); 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);
} }
} }
} }
break; break;
@ -575,24 +621,25 @@ void editor_on_mousebutton_release(const struct Event* event)
transform_translate(editor->selected_entity, &translation, TS_WORLD); transform_translate(editor->selected_entity, &translation, TS_WORLD);
} }
} }
else if(editor->current_mode == EDITOR_MODE_ROTATE) else if(editor->current_mode == EDITOR_MODE_ROTATE && editor->tool_rotate_rotation_started)
{ {
if(!editor->tool_rotate_axis_selection_enabled) editor->picking_enabled = true;
editor->tool_rotate_rotation_started = false;
if(editor->tool_rotate_amount != 0.f)
{ {
editor->tool_rotate_axis_selection_enabled = true; vec3 axis = { 0.f, 0.f, 0.f };
editor->picking_enabled = true; bool should_rotate = true;
if(editor->tool_rotate_amount != 0.f) switch(editor->current_axis)
{ {
vec3 axis = { 0.f, 0.f, 0.f }; case EDITOR_AXIS_X: vec3_assign(&axis, &UNIT_X); break;
switch(editor->current_axis) case EDITOR_AXIS_Y: vec3_assign(&axis, &UNIT_Y); break;
{ case EDITOR_AXIS_Z: vec3_assign(&axis, &UNIT_Z); break;
case EDITOR_AXIS_X: vec3_assign(&axis, &UNIT_X); break; default: should_rotate = false;
case EDITOR_AXIS_Y: vec3_assign(&axis, &UNIT_Y); break;
case EDITOR_AXIS_Z: vec3_assign(&axis, &UNIT_Z); break;
}
transform_rotate(editor->selected_entity, &axis, editor->tool_rotate_amount, TS_WORLD);
editor->tool_rotate_amount = 0.f;
} }
if(should_rotate)
transform_rotate(editor->selected_entity, &axis, editor->tool_rotate_amount, TS_WORLD);
editor->tool_rotate_amount = 0.f;
} }
} }
} }
@ -609,13 +656,10 @@ void editor_on_mousebutton_press(const struct Event* event)
if(event->mousebutton.button == MSB_LEFT && event->type == EVT_MOUSEBUTTON_PRESSED && editor->selected_entity) if(event->mousebutton.button == MSB_LEFT && event->type == EVT_MOUSEBUTTON_PRESSED && editor->selected_entity)
{ {
if(editor->current_mode == EDITOR_MODE_ROTATE) if(editor->current_mode == EDITOR_MODE_ROTATE && editor->tool_rotate_allowed)
{ {
if(editor->tool_rotate_axis_selection_enabled) editor->picking_enabled = false;
{ editor->tool_rotate_rotation_started = true;
editor->tool_rotate_axis_selection_enabled = false;
editor->picking_enabled = false;
}
} }
} }
} }
@ -624,6 +668,8 @@ void editor_on_mousemotion(const struct Event* event)
{ {
struct Game_State* game_state = game_state_get(); struct Game_State* game_state = game_state_get();
struct Editor* editor = game_state->editor; struct Editor* editor = game_state->editor;
struct Gui* gui = game_state->gui;
if(nk_window_is_any_hovered(&gui->context)) return;
switch(editor->current_mode) switch(editor->current_mode)
{ {
@ -677,8 +723,7 @@ void editor_on_mousemotion(const struct Event* event)
break; break;
case EDITOR_MODE_ROTATE: case EDITOR_MODE_ROTATE:
{ {
/* Select Axis to rotate on */ if(editor->selected_entity && editor->current_axis < EDITOR_AXIS_XZ)
if(editor->selected_entity && editor->tool_rotate_axis_selection_enabled)
{ {
struct Camera* editor_camera = &game_state->scene->cameras[CAM_EDITOR]; struct Camera* editor_camera = &game_state->scene->cameras[CAM_EDITOR];
vec3 position = { 0.f }; vec3 position = { 0.f };
@ -686,49 +731,62 @@ void editor_on_mousemotion(const struct Event* event)
struct Ray cam_ray; struct Ray cam_ray;
cam_ray = camera_screen_coord_to_ray(editor_camera, event->mousemotion.x, event->mousemotion.y); cam_ray = camera_screen_coord_to_ray(editor_camera, event->mousemotion.x, event->mousemotion.y);
/* Instead of using a spehre intersection, get the point where the ray intersects the plane
then check if the distance of that point from the selected entity is less than or equal to
the radius of the circle/disc, if it is, then we are inside the circle and can rotate */
struct Bounding_Sphere gizmo_sphere; struct Bounding_Sphere gizmo_sphere;
//vec3_assign(&gizmo_sphere.center, &position); //vec3_assign(&gizmo_sphere.center, &position);
gizmo_sphere.center = (vec3) { 0.f, 0.f, 0.f }; gizmo_sphere.center = (vec3) { 0.f, 0.f, 0.f };
gizmo_sphere.radius = editor->tool_rotate_arc_radius; gizmo_sphere.radius = editor->tool_rotate_arc_radius;
if(bv_intersect_sphere_ray(&gizmo_sphere, &position, &cam_ray)) if(bv_intersect_sphere_ray(&gizmo_sphere, &position, &cam_ray))
{ {
Plane ground_plane; //Plane ground_plane;
plane_init(&ground_plane, &UNIT_X, &position); //plane_init(&ground_plane, &UNIT_X, &position);
float distance_x = bv_distance_ray_plane(&cam_ray, &ground_plane); //float distance_x = bv_distance_ray_plane(&cam_ray, &ground_plane);
plane_init(&ground_plane, &UNIT_Y, &position); //plane_init(&ground_plane, &UNIT_Y, &position);
float distance_y = bv_distance_ray_plane(&cam_ray, &ground_plane); //float distance_y = bv_distance_ray_plane(&cam_ray, &ground_plane);
plane_init(&ground_plane, &UNIT_Z, &position); //plane_init(&ground_plane, &UNIT_Z, &position);
float distance_z = bv_distance_ray_plane(&cam_ray, &ground_plane); //float distance_z = bv_distance_ray_plane(&cam_ray, &ground_plane);
//Determine the closest plane ////Determine the closest plane
log_message("X: %.3f Y: %.3f Z: %.3f", distance_x, distance_y, distance_z); ////log_message("X: %.3f Y: %.3f Z: %.3f", distance_x, distance_y, distance_z);
float shortest_distance = distance_x < distance_y ? distance_x : distance_y; //float shortest_distance = distance_x < distance_y ? distance_x : distance_y;
shortest_distance = shortest_distance < distance_z ? shortest_distance : distance_z; //shortest_distance = shortest_distance < distance_z ? shortest_distance : distance_z;
if(shortest_distance == distance_x) editor->current_axis = EDITOR_AXIS_X; //if(shortest_distance == distance_x) editor->tool_rotate_axis = EDITOR_AXIS_X;
if(shortest_distance == distance_y) editor->current_axis = EDITOR_AXIS_Y; //if(shortest_distance == distance_y) editor->tool_rotate_axis = EDITOR_AXIS_Y;
if(shortest_distance == distance_z) editor->current_axis = EDITOR_AXIS_Z; //if(shortest_distance == distance_z) editor->tool_rotate_axis = EDITOR_AXIS_Z;
editor->tool_rotate_allowed = true;
} }
else else
{ {
editor->current_axis = EDITOR_AXIS_NONE; editor->tool_rotate_allowed = false;
}
//else
//{
// editor->tool_rotate_axis = EDITOR_AXIS_NONE;
//}
if(editor->current_axis != EDITOR_AXIS_NONE && editor->tool_rotate_rotation_started)
{
if(editor->tool_snap_enabled)
editor->tool_rotate_amount += editor->grid_scale * editor->tool_rotate_increment * ((float)event->mousemotion.xrel / 2.f);
else
editor->tool_rotate_amount += event->mousemotion.xrel / 2;
if(editor->tool_rotate_amount > 360.f)
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;
} }
} }
else /* Rotate on selected axis */
{
if(editor->tool_snap_enabled)
editor->tool_rotate_amount += editor->grid_scale * editor->tool_rotate_increment * ((float)event->mousemotion.xrel / 2.f);
else
editor->tool_rotate_amount += event->mousemotion.xrel / 2;
if(editor->tool_rotate_amount > 360.f)
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;
}
} }
break; break;
default: break; default: break;
@ -765,8 +823,10 @@ void editor_on_key_release(const struct Event* event)
if(event->key.key == KEY_X) selected_axis = EDITOR_AXIS_X; if(event->key.key == KEY_X) selected_axis = EDITOR_AXIS_X;
if(event->key.key == KEY_Y) selected_axis = EDITOR_AXIS_Y; if(event->key.key == KEY_Y) selected_axis = EDITOR_AXIS_Y;
if(event->key.key == KEY_Z) selected_axis = EDITOR_AXIS_Z; if(event->key.key == KEY_Z) selected_axis = EDITOR_AXIS_Z;
if(event->key.key == KEY_X && input_is_key_pressed(KEY_LSHIFT)) selected_axis = EDITOR_AXIS_YZ;
if(event->key.key == KEY_Y && input_is_key_pressed(KEY_LSHIFT)) selected_axis = EDITOR_AXIS_XZ; if(event->key.key == KEY_Y && input_is_key_pressed(KEY_LSHIFT)) selected_axis = EDITOR_AXIS_XZ;
if(event->key.key == KEY_ALT) selected_axis = editor->previous_axis; if(event->key.key == KEY_Z && input_is_key_pressed(KEY_LSHIFT)) selected_axis = EDITOR_AXIS_XY;
if(event->key.key == KEY_ALT && editor->current_mode == EDITOR_MODE_TRANSLATE) selected_axis = editor->previous_axis; // Revert to previous axis when alt is released
editor_axis_set(editor, selected_axis); editor_axis_set(editor, selected_axis);
/* Grid Scale select */ /* Grid Scale select */
@ -794,18 +854,7 @@ void editor_mode_set(struct Editor* editor, int mode)
editor->current_mode = mode; editor->current_mode = mode;
} }
if(editor->selected_entity) editor_tool_reset(editor);
transform_get_absolute_position(editor->selected_entity, &editor->tool_mesh_position);
else
vec3_fill(&editor->tool_mesh_position, 0.f, 0.f, 0.f);
editor->tool_rotate_amount = 0.f;
editor->tool_rotate_axis_selection_enabled = true;
editor->picking_enabled = true;
if(mode == EDITOR_MODE_TRANSLATE)
editor_axis_set(editor, EDITOR_AXIS_XZ);
else
editor_axis_set(editor, EDITOR_AXIS_NONE);
} }
void editor_entity_select(struct Editor* editor, struct Entity* entity) void editor_entity_select(struct Editor* editor, struct Entity* entity)
@ -814,7 +863,7 @@ void editor_entity_select(struct Editor* editor, struct Entity* entity)
{ {
editor->selected_entity->editor_selected = false; editor->selected_entity->editor_selected = false;
editor->selected_entity = NULL; editor->selected_entity = NULL;
vec3_fill(&editor->tool_mesh_position, 0.f, 0.f, 0.f); editor_tool_reset(editor);
} }
else if(entity) // Select else if(entity) // Select
{ {
@ -830,12 +879,28 @@ void editor_entity_select(struct Editor* editor, struct Entity* entity)
} }
} }
void editor_tool_reset(struct Editor* editor)
{
if(editor->selected_entity)
transform_get_absolute_position(editor->selected_entity, &editor->tool_mesh_position);
else
vec3_fill(&editor->tool_mesh_position, 0.f, 0.f, 0.f);
editor->tool_rotate_amount = 0.f;
editor->tool_rotate_allowed = false;
editor->picking_enabled = true;
if(editor->current_mode == EDITOR_MODE_TRANSLATE)
editor_axis_set(editor, EDITOR_AXIS_XZ);
else
editor_axis_set(editor, EDITOR_AXIS_NONE);
}
void editor_on_key_press(const struct Event* event) void editor_on_key_press(const struct Event* event)
{ {
struct Editor* editor = game_state_get()->editor; struct Editor* editor = game_state_get()->editor;
if(!nk_window_is_any_hovered(&game_state_get()->gui->context)) if(!nk_window_is_any_hovered(&game_state_get()->gui->context))
{ {
if(event->key.key == KEY_ALT) editor_axis_set(editor, EDITOR_AXIS_Y); if(event->key.key == KEY_ALT && editor->current_mode == EDITOR_MODE_TRANSLATE) editor_axis_set(editor, EDITOR_AXIS_Y);
} }
} }
@ -843,15 +908,24 @@ void editor_axis_set(struct Editor* editor, int axis)
{ {
if(editor->current_axis != axis) if(editor->current_axis != axis)
{ {
if(axis != editor->current_axis) editor->previous_axis = editor->current_axis;
editor->current_axis = axis;
/* Reset tool position after axis has changed */
if(editor->selected_entity)
{ {
editor->previous_axis = editor->current_axis; transform_get_absolute_position(editor->selected_entity, &editor->tool_mesh_position);
editor->current_axis = axis; }
/* Reset tool position after axis has changed */ if(editor->current_mode == EDITOR_MODE_ROTATE)
if(editor->selected_entity) {
// Assign rotation axis only if it is a single axis since we don't want to rotate on multiple axes at the same time
if(axis >= EDITOR_AXIS_XZ)
{ {
transform_get_absolute_position(editor->selected_entity, &editor->tool_mesh_position); editor->previous_axis = EDITOR_AXIS_NONE;
editor->current_axis = EDITOR_AXIS_NONE;
editor->tool_rotate_allowed = false;
editor->tool_rotate_amount = 0.f;
} }
} }
} }
@ -860,7 +934,7 @@ void editor_camera_update(struct Editor* editor, float dt)
{ {
struct Camera* editor_camera = &game_state_get()->scene->cameras[CAM_EDITOR]; struct Camera* editor_camera = &game_state_get()->scene->cameras[CAM_EDITOR];
static float total_up_down_rot = 0.f; static float total_up_down_rot = 0.f;
float move_speed = editor->camera_move_speed, turn_speed = editor->camera_turn_speed; float move_speed = editor->camera_move_speed, turn_speed = editor->camera_turn_speed;
float turn_up_down = 0.f; float turn_up_down = 0.f;
float turn_left_right = 0.f; float turn_left_right = 0.f;
float max_up_down = 60.f; float max_up_down = 60.f;

@ -36,8 +36,9 @@ struct Editor
int tool_mesh_draw_enabled; int tool_mesh_draw_enabled;
float tool_rotate_arc_radius; float tool_rotate_arc_radius;
int tool_rotate_arc_segments; int tool_rotate_arc_segments;
bool tool_rotate_axis_selection_enabled;
float tool_rotate_amount; float tool_rotate_amount;
bool tool_rotate_allowed;
bool tool_rotate_rotation_started;
float tool_rotate_increment; float tool_rotate_increment;
vec3 tool_scale_amount; vec3 tool_scale_amount;
float axis_line_length; float axis_line_length;

@ -146,185 +146,179 @@ void renderer_init(struct Renderer* renderer)
void renderer_render(struct Renderer* renderer, struct Scene* scene) void renderer_render(struct Renderer* renderer, struct Scene* scene)
{ {
/* Render each camera output into it's framebuffer or to the default framebuffer */ struct Camera* camera = &scene->cameras[scene->active_camera_index];
for(int i = 0; i < MAX_CAMERAS; i++) int fbo = camera->fbo == -1 ? renderer->def_fbo : camera->fbo;
{ framebuffer_bind(fbo);
struct Camera* camera = &scene->cameras[i]; {
if(!camera->base.active) continue; glViewport(0, 0, framebuffer_width_get(fbo), framebuffer_height_get(fbo));
glEnable(GL_DEPTH_TEST);
int fbo = camera->fbo == -1 ? renderer->def_fbo : camera->fbo; glDepthFunc(GL_LEQUAL);
framebuffer_bind(fbo); glClearColor(camera->clear_color.x,
camera->clear_color.y,
camera->clear_color.z,
camera->clear_color.w);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
static mat4 mvp;
for(int i = 0; i < MAT_MAX; i++)
{ {
glViewport(0, 0, framebuffer_width_get(fbo), framebuffer_height_get(fbo)); /* for each material, get all the registered models and render them */
glEnable(GL_DEPTH_TEST); struct Material* material = &renderer->materials[i];
glDepthFunc(GL_LEQUAL); GL_CHECK(shader_bind(material->shader));
glClearColor(camera->clear_color.x,
camera->clear_color.y,
camera->clear_color.z,
camera->clear_color.w);
glEnable(GL_CULL_FACE );
glCullFace(GL_BACK);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
static mat4 mvp;
for(int i = 0; i < MAT_MAX; i++)
{
/* for each material, get all the registered models and render them */
struct Material* material = &renderer->materials[i];
GL_CHECK(shader_bind(material->shader));
if(material->lit) /* Set light information */ if(material->lit) /* Set light information */
{
char uniform_name[MAX_UNIFORM_NAME_LEN];
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
int light_count = -1;
for(int j = 0; j < MAX_LIGHTS; j++)
{ {
char uniform_name[MAX_UNIFORM_NAME_LEN]; struct Light* light = &scene->lights[j]; /* TODO: Cull lights according to camera frustum */
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); if(!light->base.active || !light->valid) continue;
int light_count = -1; light_count++;
for(int i = 0; i < MAX_LIGHTS; i++)
vec3 light_pos = { 0, 0, 0 };
transform_get_absolute_position(&light->base, &light_pos);
if(light->type != LT_POINT)
{ {
struct Light* light = &scene->lights[i]; /* TODO: Cull lights according to camera frustum */ snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].direction", light_count);
if(!light->base.active || !light->valid) continue; vec3 light_dir = { 0.f, 0.f, 0.f };
light_count++; transform_get_absolute_lookat(&light->base, &light_dir);
vec3_norm(&light_dir, &light_dir);
vec3 light_pos = {0, 0, 0}; shader_set_uniform_vec3(material->shader, uniform_name, &light_dir);
transform_get_absolute_position(&light->base, &light_pos);
if(light->type != LT_POINT)
{
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].direction", light_count);
vec3 light_dir = {0.f, 0.f, 0.f};
transform_get_absolute_lookat(&light->base, &light_dir);
vec3_norm(&light_dir, &light_dir);
shader_set_uniform_vec3(material->shader, uniform_name, &light_dir);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
}
if(light->type != LT_DIR)
{
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].position", light_count);
shader_set_uniform_vec3(material->shader, uniform_name, &light_pos);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].outer_angle", light_count);
shader_set_uniform_float(material->shader, uniform_name, light->outer_angle);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].inner_angle", light_count);
shader_set_uniform_float(material->shader, uniform_name, light->inner_angle);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].falloff", light_count);
shader_set_uniform_float(material->shader, uniform_name, light->falloff);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].radius", light_count);
shader_set_uniform_int(material->shader, uniform_name, light->radius);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
}
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].color", light_count);
shader_set_uniform_vec3(material->shader, uniform_name, &light->color);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
}
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].intensity", light_count);
shader_set_uniform_float(material->shader, uniform_name, light->intensity); if(light->type != LT_DIR)
{
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].position", light_count);
shader_set_uniform_vec3(material->shader, uniform_name, &light_pos);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].type", light_count); snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].outer_angle", light_count);
shader_set_uniform_int(material->shader, uniform_name, light->type); shader_set_uniform_float(material->shader, uniform_name, light->outer_angle);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].inner_angle", light_count);
shader_set_uniform_float(material->shader, uniform_name, light->inner_angle);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].falloff", light_count);
shader_set_uniform_float(material->shader, uniform_name, light->falloff);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].radius", light_count);
shader_set_uniform_int(material->shader, uniform_name, light->radius);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
} }
light_count++; // this variable is going to be sent as a uniform and be used for looping an array so increase its length by one snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].color", light_count);
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_TOTAL_LIGHTS].type, material->pipeline_params[MPP_TOTAL_LIGHTS].location, &light_count)); shader_set_uniform_vec3(material->shader, uniform_name, &light->color);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].intensity", light_count);
shader_set_uniform_float(material->shader, uniform_name, light->intensity);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].type", light_count);
shader_set_uniform_int(material->shader, uniform_name, light->type);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
}
light_count++; // this variable is going to be sent as a uniform and be used for looping an array so increase its length by one
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_TOTAL_LIGHTS].type, material->pipeline_params[MPP_TOTAL_LIGHTS].location, &light_count));
vec3 camera_pos = {0, 0, 0}; vec3 camera_pos = { 0, 0, 0 };
transform_get_absolute_position(&camera->base, &camera_pos); transform_get_absolute_position(&camera->base, &camera_pos);
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_CAM_POS].type, material->pipeline_params[MPP_CAM_POS].location, &camera_pos)); GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_CAM_POS].type, material->pipeline_params[MPP_CAM_POS].location, &camera_pos));
}
/* Set material pipeline uniforms */
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_MODE].type, material->pipeline_params[MPP_FOG_MODE].location, &renderer->settings.fog.mode));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_DENSITY].type, material->pipeline_params[MPP_FOG_DENSITY].location, &renderer->settings.fog.density));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_START_DIST].type, material->pipeline_params[MPP_FOG_START_DIST].location, &renderer->settings.fog.start_dist));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_MAX_DIST].type, material->pipeline_params[MPP_FOG_MAX_DIST].location, &renderer->settings.fog.max_dist));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_COLOR].type, material->pipeline_params[MPP_FOG_COLOR].location, &renderer->settings.fog.color));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_AMBIENT_LIGHT].type, material->pipeline_params[MPP_AMBIENT_LIGHT].location, &renderer->settings.ambient_light));
if(material->lit) GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_VIEW_MAT].type, material->pipeline_params[MPP_VIEW_MAT].location, &camera->view_mat));
for(int j = 0; j < MAX_MATERIAL_REGISTERED_STATIC_MESHES; j++)
{
if(!material->registered_static_meshes[j]) continue;
/* for each registered model, set up uniforms and render */
struct Static_Mesh* mesh = material->registered_static_meshes[j];
struct Geometry* geometry = geom_get(mesh->model.geometry_index);
/* Check if model is in frustum */
vec3 abs_pos, abs_scale;
transform_get_absolute_position(&mesh->base, &abs_pos);
transform_get_absolute_scale(&mesh->base, &abs_scale);
int intersection = bv_intersect_frustum_sphere(&camera->frustum[0], &geometry->bounding_sphere, &abs_pos, &abs_scale);
if(intersection == IT_OUTSIDE)
{
renderer->num_culled++;
continue;
}
else
{
renderer->num_indices += array_len(geometry->indices);
renderer->num_rendered++;
} }
/* Set material pipeline uniforms */ /* set material params for the model */
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_MODE].type, material->pipeline_params[MPP_FOG_MODE].location, &renderer->settings.fog.mode)); for(int k = 0; k < MMP_MAX; k++)
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_DENSITY].type, material->pipeline_params[MPP_FOG_DENSITY].location, &renderer->settings.fog.density));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_START_DIST].type, material->pipeline_params[MPP_FOG_START_DIST].location, &renderer->settings.fog.start_dist));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_MAX_DIST].type, material->pipeline_params[MPP_FOG_MAX_DIST].location, &renderer->settings.fog.max_dist));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_COLOR].type, material->pipeline_params[MPP_FOG_COLOR].location, &renderer->settings.fog.color));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_AMBIENT_LIGHT].type, material->pipeline_params[MPP_AMBIENT_LIGHT].location, &renderer->settings.ambient_light));
if(material->lit) GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_VIEW_MAT].type, material->pipeline_params[MPP_VIEW_MAT].location, &camera->view_mat));
for(int j = 0; j < MAX_MATERIAL_REGISTERED_STATIC_MESHES; j++)
{ {
if(!material->registered_static_meshes[j]) continue; switch(mesh->model.material_params[k].type)
/* for each registered model, set up uniforms and render */
struct Static_Mesh* mesh = material->registered_static_meshes[j];
struct Geometry* geometry = geom_get(mesh->model.geometry_index);
/* Check if model is in frustum */
vec3 abs_pos, abs_scale;
transform_get_absolute_position(&mesh->base, &abs_pos);
transform_get_absolute_scale(&mesh->base, &abs_scale);
int intersection = bv_intersect_frustum_sphere(&camera->frustum[0], &geometry->bounding_sphere, &abs_pos, &abs_scale);
if(intersection == IT_OUTSIDE)
{
renderer->num_culled++;
continue;
}
else
{ {
renderer->num_indices += array_len(geometry->indices); case VT_INT: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_int)); break;
renderer->num_rendered++; case VT_FLOAT: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_float)); break;
case VT_VEC3: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_vec3)); break;
case VT_VEC4: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_vec4)); break;
} }
}
/* set material params for the model */ /* Set pipeline uniforms that are derived per model */
for(int k = 0; k < MMP_MAX; k++) mat4_identity(&mvp);
{ mat4_mul(&mvp, &camera->view_proj_mat, &mesh->base.transform.trans_mat);
switch(mesh->model.material_params[k].type) GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_MVP].type, material->pipeline_params[MPP_MVP].location, &mvp));
{
case VT_INT: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_int)); break;
case VT_FLOAT: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_float)); break;
case VT_VEC3: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_vec3)); break;
case VT_VEC4: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_vec4)); break;
}
}
/* Set pipeline uniforms that are derived per model */ if(material->lit)
mat4_identity(&mvp); {
mat4_mul(&mvp, &camera->view_proj_mat, &mesh->base.transform.trans_mat); GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_VIEW_MAT].type, material->pipeline_params[MPP_VIEW_MAT].location, &camera->view_mat));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_MVP].type, material->pipeline_params[MPP_MVP].location, &mvp)); GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_MODEL_MAT].type, material->pipeline_params[MPP_MODEL_MAT].location, &mesh->base.transform.trans_mat));
mat4 inv_mat;
mat4_identity(&inv_mat);
mat4_inverse(&inv_mat, &mesh->base.transform.trans_mat);
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_INV_MODEL_MAT].type, material->pipeline_params[MPP_INV_MODEL_MAT].location, &inv_mat));
}
if(material->lit) /* Render the geometry */
{ //int indices = geom_render_in_frustum(model->geometry_index, &viewer->camera.frustum[0], entity, draw_mode);
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_VIEW_MAT].type, material->pipeline_params[MPP_VIEW_MAT].location, &camera->view_mat)); //geom_render(model->geometry_index, draw_mode);
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_MODEL_MAT].type, material->pipeline_params[MPP_MODEL_MAT].location, &mesh->base.transform.trans_mat)); geom_render(mesh->model.geometry_index, GDM_TRIANGLES);
mat4 inv_mat;
mat4_identity(&inv_mat);
mat4_inverse(&inv_mat, &mesh->base.transform.trans_mat);
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_INV_MODEL_MAT].type, material->pipeline_params[MPP_INV_MODEL_MAT].location, &inv_mat));
}
/* Render the geometry */
//int indices = geom_render_in_frustum(model->geometry_index, &viewer->camera.frustum[0], entity, draw_mode);
//geom_render(model->geometry_index, draw_mode);
geom_render(mesh->model.geometry_index, GDM_TRIANGLES);
for(int k = 0; k < MMP_MAX; k++) for(int k = 0; k < MMP_MAX; k++)
{ {
/* unbind textures, if any */ /* unbind textures, if any */
if(material->model_params[k].type == UT_TEX) if(material->model_params[k].type == UT_TEX)
GL_CHECK(texture_unbind(mesh->model.material_params[k].val_int)); GL_CHECK(texture_unbind(mesh->model.material_params[k].val_int));
}
} }
shader_unbind();
} }
editor_debugvar_slot_set_int(renderer->num_rendered_slot, renderer->num_rendered); shader_unbind();
editor_debugvar_slot_set_int(renderer->num_culled_slot, renderer->num_culled);
editor_debugvar_slot_set_int(renderer->num_indices_slot, renderer->num_indices);
renderer->num_culled = renderer->num_rendered = renderer->num_indices = 0;
} }
framebuffer_unbind(); editor_debugvar_slot_set_int(renderer->num_rendered_slot, renderer->num_rendered);
glDisable(GL_DEPTH_TEST); editor_debugvar_slot_set_int(renderer->num_culled_slot, renderer->num_culled);
glDisable(GL_CULL_FACE); editor_debugvar_slot_set_int(renderer->num_indices_slot, renderer->num_indices);
}
renderer->num_culled = renderer->num_rendered = renderer->num_indices = 0;
}
framebuffer_unbind();
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
/* Final Render */ /* Final Render */
struct Camera* active_camera = &scene->cameras[scene->active_camera_index]; struct Camera* active_camera = &scene->cameras[scene->active_camera_index];

@ -1,5 +1,5 @@
Todo: Todo:
- 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 - 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 - Match amount to be rotate with actual axes and the gizmo arc being drawn
- Handle all other axes combinations - Handle all other axes combinations
@ -83,16 +83,15 @@ Todo:
Improvements: Improvements:
- Better naming semantics for example, init/deinit for initialization and cleanup and create/destroy when memory is allocated or deallocated - Better naming semantics for example, init/deinit for initialization and cleanup and create/destroy when memory is allocated or deallocated
- Reset mouse cursor position to the center of the screen in editor mode after the right click is released
- Categorized entity list in editor for example different subtree for lights and static meshes - Categorized entity list in editor for example different subtree for lights and static meshes
- Depth testing for editor grid - Depth testing for editor grid
- Remove fixed editor windows locations and bring back floating windows - Improve picking and automatically improve everything in editor
- Improve culling
Bugs: Bugs:
- Better handling of wav format checking at load time - Better handling of wav format checking at load time
- Fix light rotation/direction bugs - Fix light rotation/direction bugs
- Fix lights type not being correctly saved/loaded from file - Fix lights type not being correctly saved/loaded from file
- Fix culling
- Fix bounding boxes not aligning in editor - Fix bounding boxes not aligning in editor
- Investigate memory usage increase when window is minimized - Investigate memory usage increase when window is minimized
- Fix hang on fullscreen toggle - Fix hang on fullscreen toggle
@ -264,4 +263,7 @@ Done:
* Complete rotate mode * Complete rotate mode
* Implement arc values greater than 360 or -360 * Implement arc values greater than 360 or -360
* Rotation degree snapping * Rotation degree snapping
* Reset mouse cursor position to the center of the screen in editor mode after the right click is released
* Remove fixed editor windows locations and bring back floating windows
* Only show rotation gizmo for one axis at a time

Loading…
Cancel
Save