|
|
|
|
@ -28,13 +28,16 @@ const char* ModeStrings[] = {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef struct EditorDataStruct EditorData;
|
|
|
|
|
typedef struct ModeKeyStruct ModeKey;
|
|
|
|
|
|
|
|
|
|
typedef void(*ModeKeyCallback)(EditorData* data, ClientContext* context, int action, int mods);
|
|
|
|
|
typedef void(*ModeKeyCallback)(EditorData* data, ClientContext* context, ModeKey* binding, int action, int mods);
|
|
|
|
|
|
|
|
|
|
typedef struct ModeKeyStruct {
|
|
|
|
|
struct ModeKeyStruct {
|
|
|
|
|
int key;
|
|
|
|
|
ModeKeyCallback logic;
|
|
|
|
|
} ModeKey;
|
|
|
|
|
int axis;
|
|
|
|
|
float amount;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct EditorDataStruct {
|
|
|
|
|
EditorMode mode;
|
|
|
|
|
@ -153,86 +156,59 @@ VkResult update_mode_string(ClientContext* context, EditorData* data) {
|
|
|
|
|
return ui_lua_call(&context->ui, &context->render, container, "set_mode", ModeStrings[data->mode]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Movement/spin keys are only ever seen by editor.c when no UI element has
|
|
|
|
|
// focus (engine.c routes key events to the focused element first). If focus
|
|
|
|
|
// is gained while a key is held, its release never reaches us and the
|
|
|
|
|
// accumulator in move_cam/spin_cam is left stuck. Zeroing here every frame a
|
|
|
|
|
// UI element is focused keeps the camera from drifting forever in that case.
|
|
|
|
|
void editor_frame_callback(ClientContext* context) {
|
|
|
|
|
if(context->ui.active_container != NULL) {
|
|
|
|
|
context->velocity[0] = 0;
|
|
|
|
|
context->velocity[1] = 0;
|
|
|
|
|
context->velocity[2] = 0;
|
|
|
|
|
context->spin[0] = 0;
|
|
|
|
|
context->spin[1] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void editor_key_callback(ClientContext* context, int key, int action, int mods) {
|
|
|
|
|
EditorData* data = context->app_data;
|
|
|
|
|
for(uint32_t i = 0; i < data->mode_key_counts[data->mode]; i++) {
|
|
|
|
|
if(data->mode_keys[data->mode][i].key == key) {
|
|
|
|
|
data->mode_keys[data->mode][i].logic(data, context, action, mods);
|
|
|
|
|
data->mode_keys[data->mode][i].logic(data, context, &data->mode_keys[data->mode][i], action, mods);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(uint32_t i = 0; i < data->mode_key_counts[MODE_NONE]; i++) {
|
|
|
|
|
if(data->mode_keys[MODE_NONE][i].key == key) {
|
|
|
|
|
data->mode_keys[MODE_NONE][i].logic(data, context, action, mods);
|
|
|
|
|
data->mode_keys[MODE_NONE][i].logic(data, context, &data->mode_keys[MODE_NONE][i], action, mods);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void spin_cam(ClientContext* context, int action, int mods, unsigned int axis, float amount) {
|
|
|
|
|
(void)mods;
|
|
|
|
|
if(action == GLFW_PRESS) context->spin[axis] += amount;
|
|
|
|
|
else if(action == GLFW_RELEASE) context->spin[axis] -= amount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void spin_cam_left(EditorData* data, ClientContext* context, int action, int mods) {
|
|
|
|
|
(void)data;
|
|
|
|
|
spin_cam(context, action, mods, 0, -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void spin_cam_right(EditorData* data, ClientContext* context, int action, int mods) {
|
|
|
|
|
(void)data;
|
|
|
|
|
spin_cam(context, action, mods, 0, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void spin_cam_up(EditorData* data, ClientContext* context, int action, int mods) {
|
|
|
|
|
(void)data;
|
|
|
|
|
spin_cam(context, action, mods, 1, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void spin_cam_down(EditorData* data, ClientContext* context, int action, int mods) {
|
|
|
|
|
void spin_cam_key(EditorData* data, ClientContext* context, ModeKey* binding, int action, int mods) {
|
|
|
|
|
(void)data;
|
|
|
|
|
spin_cam(context, action, mods, 1, -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void move_cam(ClientContext* context, int action, int mods, unsigned int axis, float amount) {
|
|
|
|
|
(void)mods;
|
|
|
|
|
if(action == GLFW_PRESS) context->velocity[axis] += amount;
|
|
|
|
|
else if(action == GLFW_RELEASE) context->velocity[axis] -= amount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void move_cam_up(EditorData* data, ClientContext* context, int action, int mods) {
|
|
|
|
|
(void)data;
|
|
|
|
|
move_cam(context, action, mods, 1, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void move_cam_down(EditorData* data, ClientContext* context, int action, int mods) {
|
|
|
|
|
(void)data;
|
|
|
|
|
move_cam(context, action, mods, 1, -1);
|
|
|
|
|
if(action == GLFW_PRESS) context->spin[binding->axis] += binding->amount;
|
|
|
|
|
else if(action == GLFW_RELEASE) context->spin[binding->axis] -= binding->amount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void move_cam_left(EditorData* data, ClientContext* context, int action, int mods) {
|
|
|
|
|
void move_cam_key(EditorData* data, ClientContext* context, ModeKey* binding, int action, int mods) {
|
|
|
|
|
(void)data;
|
|
|
|
|
move_cam(context, action, mods, 0, -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void move_cam_right(EditorData* data, ClientContext* context, int action, int mods) {
|
|
|
|
|
(void)data;
|
|
|
|
|
move_cam(context, action, mods, 0, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void move_cam_forward(EditorData* data, ClientContext* context, int action, int mods) {
|
|
|
|
|
(void)data;
|
|
|
|
|
move_cam(context, action, mods, 2, 1);
|
|
|
|
|
(void)mods;
|
|
|
|
|
if(action == GLFW_PRESS) context->velocity[binding->axis] += binding->amount;
|
|
|
|
|
else if(action == GLFW_RELEASE) context->velocity[binding->axis] -= binding->amount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void move_cam_backwards(EditorData* data, ClientContext* context, int action, int mods) {
|
|
|
|
|
(void)data;
|
|
|
|
|
move_cam(context, action, mods, 2, -1);
|
|
|
|
|
void editor_scroll_callback(ClientContext* context, double x, double y) {
|
|
|
|
|
(void)x;
|
|
|
|
|
context->zoom = (int32_t)y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void clear_mode(EditorData* data, ClientContext* context, int action, int mods) {
|
|
|
|
|
void clear_mode(EditorData* data, ClientContext* context, ModeKey* binding, int action, int mods) {
|
|
|
|
|
(void)binding;
|
|
|
|
|
(void)mods;
|
|
|
|
|
if(action == GLFW_PRESS) {
|
|
|
|
|
data->mode = MODE_NONE;
|
|
|
|
|
@ -242,7 +218,8 @@ void clear_mode(EditorData* data, ClientContext* context, int action, int mods)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void enter_vertex_mode(EditorData* data, ClientContext* context, int action, int mods) {
|
|
|
|
|
void enter_vertex_mode(EditorData* data, ClientContext* context, ModeKey* binding, int action, int mods) {
|
|
|
|
|
(void)binding;
|
|
|
|
|
(void)mods;
|
|
|
|
|
if(action == GLFW_PRESS) {
|
|
|
|
|
data->mode = MODE_VERTEX;
|
|
|
|
|
@ -252,7 +229,8 @@ void enter_vertex_mode(EditorData* data, ClientContext* context, int action, int
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void enter_neighbor_mode(EditorData* data, ClientContext* context, int action, int mods) {
|
|
|
|
|
void enter_neighbor_mode(EditorData* data, ClientContext* context, ModeKey* binding, int action, int mods) {
|
|
|
|
|
(void)binding;
|
|
|
|
|
(void)mods;
|
|
|
|
|
if(action == GLFW_PRESS) {
|
|
|
|
|
data->mode = MODE_NEIGHBOR;
|
|
|
|
|
@ -262,7 +240,8 @@ void enter_neighbor_mode(EditorData* data, ClientContext* context, int action, i
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void enter_hex_mode(EditorData* data, ClientContext* context, int action, int mods) {
|
|
|
|
|
void enter_hex_mode(EditorData* data, ClientContext* context, ModeKey* binding, int action, int mods) {
|
|
|
|
|
(void)binding;
|
|
|
|
|
(void)mods;
|
|
|
|
|
if(action == GLFW_PRESS) {
|
|
|
|
|
data->mode = MODE_HEX;
|
|
|
|
|
@ -272,7 +251,8 @@ void enter_hex_mode(EditorData* data, ClientContext* context, int action, int mo
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void enter_region_mode(EditorData* data, ClientContext* context, int action, int mods) {
|
|
|
|
|
void enter_region_mode(EditorData* data, ClientContext* context, ModeKey* binding, int action, int mods) {
|
|
|
|
|
(void)binding;
|
|
|
|
|
(void)mods;
|
|
|
|
|
if(action == GLFW_PRESS) {
|
|
|
|
|
data->mode = MODE_REGION;
|
|
|
|
|
@ -325,40 +305,25 @@ int main() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Mode Switches
|
|
|
|
|
data->mode_keys[MODE_NONE][0].key = GLFW_KEY_ESCAPE;
|
|
|
|
|
data->mode_keys[MODE_NONE][0].logic = clear_mode;
|
|
|
|
|
data->mode_keys[MODE_NONE][1].key = GLFW_KEY_V;
|
|
|
|
|
data->mode_keys[MODE_NONE][1].logic = enter_vertex_mode;
|
|
|
|
|
data->mode_keys[MODE_NONE][2].key = GLFW_KEY_N;
|
|
|
|
|
data->mode_keys[MODE_NONE][2].logic = enter_neighbor_mode;
|
|
|
|
|
data->mode_keys[MODE_NONE][3].key = GLFW_KEY_H;
|
|
|
|
|
data->mode_keys[MODE_NONE][3].logic = enter_hex_mode;
|
|
|
|
|
data->mode_keys[MODE_NONE][4].key = GLFW_KEY_R;
|
|
|
|
|
data->mode_keys[MODE_NONE][4].logic = enter_region_mode;
|
|
|
|
|
|
|
|
|
|
// Camera Movement
|
|
|
|
|
data->mode_keys[MODE_NONE][5].key = GLFW_KEY_SPACE;
|
|
|
|
|
data->mode_keys[MODE_NONE][5].logic = move_cam_up;
|
|
|
|
|
data->mode_keys[MODE_NONE][6].key = GLFW_KEY_LEFT_SHIFT;
|
|
|
|
|
data->mode_keys[MODE_NONE][6].logic = move_cam_down;
|
|
|
|
|
data->mode_keys[MODE_NONE][7].key = GLFW_KEY_LEFT;
|
|
|
|
|
data->mode_keys[MODE_NONE][7].logic = move_cam_left;
|
|
|
|
|
data->mode_keys[MODE_NONE][8].key = GLFW_KEY_RIGHT;
|
|
|
|
|
data->mode_keys[MODE_NONE][8].logic = move_cam_right;
|
|
|
|
|
data->mode_keys[MODE_NONE][9].key = GLFW_KEY_UP;
|
|
|
|
|
data->mode_keys[MODE_NONE][9].logic = move_cam_forward;
|
|
|
|
|
data->mode_keys[MODE_NONE][10].key = GLFW_KEY_DOWN;
|
|
|
|
|
data->mode_keys[MODE_NONE][10].logic = move_cam_backwards;
|
|
|
|
|
|
|
|
|
|
// Camera Spin
|
|
|
|
|
data->mode_keys[MODE_NONE][11].key = GLFW_KEY_A;
|
|
|
|
|
data->mode_keys[MODE_NONE][11].logic = spin_cam_left;
|
|
|
|
|
data->mode_keys[MODE_NONE][12].key = GLFW_KEY_D;
|
|
|
|
|
data->mode_keys[MODE_NONE][12].logic = spin_cam_right;
|
|
|
|
|
data->mode_keys[MODE_NONE][13].key = GLFW_KEY_W;
|
|
|
|
|
data->mode_keys[MODE_NONE][13].logic = spin_cam_up;
|
|
|
|
|
data->mode_keys[MODE_NONE][14].key = GLFW_KEY_S;
|
|
|
|
|
data->mode_keys[MODE_NONE][14].logic = spin_cam_down;
|
|
|
|
|
|
|
|
|
|
return run_app(data, editor_startup, NULL, NULL, editor_key_callback, NULL, NULL, NULL);
|
|
|
|
|
data->mode_keys[MODE_NONE][0] = (ModeKey){GLFW_KEY_ESCAPE, clear_mode, 0, 0};
|
|
|
|
|
data->mode_keys[MODE_NONE][1] = (ModeKey){GLFW_KEY_V, enter_vertex_mode, 0, 0};
|
|
|
|
|
data->mode_keys[MODE_NONE][2] = (ModeKey){GLFW_KEY_N, enter_neighbor_mode, 0, 0};
|
|
|
|
|
data->mode_keys[MODE_NONE][3] = (ModeKey){GLFW_KEY_H, enter_hex_mode, 0, 0};
|
|
|
|
|
data->mode_keys[MODE_NONE][4] = (ModeKey){GLFW_KEY_R, enter_region_mode, 0, 0};
|
|
|
|
|
|
|
|
|
|
// Camera Movement (axis: 0 = strafe x, 1 = up/down, 2 = forward/back)
|
|
|
|
|
data->mode_keys[MODE_NONE][5] = (ModeKey){GLFW_KEY_SPACE, move_cam_key, 1, 1};
|
|
|
|
|
data->mode_keys[MODE_NONE][6] = (ModeKey){GLFW_KEY_LEFT_SHIFT, move_cam_key, 1, -1};
|
|
|
|
|
data->mode_keys[MODE_NONE][7] = (ModeKey){GLFW_KEY_LEFT, move_cam_key, 0, -1};
|
|
|
|
|
data->mode_keys[MODE_NONE][8] = (ModeKey){GLFW_KEY_RIGHT, move_cam_key, 0, 1};
|
|
|
|
|
data->mode_keys[MODE_NONE][9] = (ModeKey){GLFW_KEY_UP, move_cam_key, 2, 1};
|
|
|
|
|
data->mode_keys[MODE_NONE][10] = (ModeKey){GLFW_KEY_DOWN, move_cam_key, 2, -1};
|
|
|
|
|
|
|
|
|
|
// Camera Spin (axis: 0 = yaw, 1 = pitch)
|
|
|
|
|
data->mode_keys[MODE_NONE][11] = (ModeKey){GLFW_KEY_A, spin_cam_key, 0, -1};
|
|
|
|
|
data->mode_keys[MODE_NONE][12] = (ModeKey){GLFW_KEY_D, spin_cam_key, 0, 1};
|
|
|
|
|
data->mode_keys[MODE_NONE][13] = (ModeKey){GLFW_KEY_W, spin_cam_key, 1, 1};
|
|
|
|
|
data->mode_keys[MODE_NONE][14] = (ModeKey){GLFW_KEY_S, spin_cam_key, 1, -1};
|
|
|
|
|
|
|
|
|
|
return run_app(data, editor_startup, editor_frame_callback, NULL, editor_key_callback, NULL, editor_scroll_callback, NULL);
|
|
|
|
|
}
|
|
|
|
|
|