170 lines
5.4 KiB
C
170 lines
5.4 KiB
C
|
|
#include "global.h"
|
|
|
|
static object_t *_compass_hitbox_x;
|
|
static object_t *_compass_hitbox_y;
|
|
static object_t *_compass_hitbox_z;
|
|
static object_t *_compass_hovered = NULL;
|
|
static object_t *_compass_hovered_last = NULL;
|
|
|
|
static void _compass_init_hitbox() {
|
|
if (_compass_hitbox_x != NULL) {
|
|
return;
|
|
}
|
|
|
|
gc_unroot(_compass_hitbox_x);
|
|
_compass_hitbox_x = object_create(true);
|
|
gc_root(_compass_hitbox_x);
|
|
gc_unroot(_compass_hitbox_y);
|
|
_compass_hitbox_y = object_create(true);
|
|
gc_root(_compass_hitbox_y);
|
|
gc_unroot(_compass_hitbox_z);
|
|
_compass_hitbox_z = object_create(true);
|
|
gc_root(_compass_hitbox_z);
|
|
|
|
_compass_hitbox_x->transform->scale = (vec4_t){0.15, 0.15, 0.15, 1.0};
|
|
_compass_hitbox_y->transform->scale = (vec4_t){0.15, 0.15, 0.15, 1.0};
|
|
_compass_hitbox_z->transform->scale = (vec4_t){0.15, 0.15, 0.15, 1.0};
|
|
|
|
_compass_hitbox_x->transform->loc = (vec4_t){1.5, 0, 0, 1.0};
|
|
_compass_hitbox_y->transform->loc = (vec4_t){0, 1.5, 0, 1.0};
|
|
_compass_hitbox_z->transform->loc = (vec4_t){0, 0, 1.5, 1.0};
|
|
|
|
object_t *compass = scene_get_child(".Compass");
|
|
object_set_parent(_compass_hitbox_x, compass);
|
|
object_set_parent(_compass_hitbox_y, compass);
|
|
object_set_parent(_compass_hitbox_z, compass);
|
|
}
|
|
|
|
static bool _compass_compare_quat(quat_t a, quat_t b) {
|
|
return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w;
|
|
}
|
|
|
|
void render_compass() {
|
|
if (!g_context->show_compass || g_config->workspace == WORKSPACE_PLAYER || g_context->capturing_screenshot) {
|
|
return;
|
|
}
|
|
|
|
camera_object_t *cam = scene_camera;
|
|
mesh_object_t *compass = scene_get_child(".Compass")->ext;
|
|
|
|
bool _visible = compass->base->visible;
|
|
object_t *_parent = compass->base->parent;
|
|
quat_t crot = cam->base->transform->rot;
|
|
f32 ratio = sys_w() / (float)sys_h();
|
|
mat4_t _P = cam->p;
|
|
cam->p = mat4_ortho(-8 * ratio, 8 * ratio, -8, 8, -2, 2);
|
|
compass->base->visible = true;
|
|
compass->base->parent = cam->base;
|
|
|
|
f32 compass_x = 7.4;
|
|
f32 compass_y = 7.0;
|
|
bool compass_down = false;
|
|
|
|
#ifdef IRON_IOS
|
|
if (config_is_iphone()) {
|
|
compass_down = true;
|
|
}
|
|
#endif
|
|
|
|
if (compass_down) {
|
|
compass_x = 6.0;
|
|
compass_y = -compass_y;
|
|
}
|
|
|
|
compass->base->transform->loc = (vec4_t){compass_x * ratio, compass_y, -1, 1.0};
|
|
compass->base->transform->rot = (quat_t){-crot.x, -crot.y, -crot.z, crot.w};
|
|
compass->base->transform->scale = (vec4_t){0.4, 0.4, 0.4, 1.0};
|
|
transform_build_matrix(compass->base->transform);
|
|
compass->frustum_culling = false;
|
|
mesh_object_render(compass, "overlay", NULL);
|
|
|
|
if (_compass_hovered != NULL) {
|
|
line_draw_color = _compass_hovered == _compass_hitbox_x ? 0xffff0000 : _compass_hovered == _compass_hitbox_y ? 0xff00ff00 : 0xff0000ff;
|
|
line_draw_strength = 0.1;
|
|
shape_draw_sphere(_compass_hovered->transform->world);
|
|
}
|
|
|
|
cam->p = _P;
|
|
compass->base->visible = _visible;
|
|
compass->base->parent = _parent;
|
|
}
|
|
|
|
void render_compass_update() {
|
|
if (!g_context->show_compass) {
|
|
return;
|
|
}
|
|
|
|
if (_compass_hovered_last != _compass_hovered) {
|
|
gc_unroot(_compass_hovered_last);
|
|
_compass_hovered_last = _compass_hovered;
|
|
gc_root(_compass_hovered_last);
|
|
g_context->ddirty = 2;
|
|
}
|
|
gc_unroot(_compass_hovered);
|
|
_compass_hovered = NULL;
|
|
|
|
f32 x = mouse_view_x() / (float)sys_w();
|
|
f32 y = mouse_view_y() / (float)sys_h();
|
|
bool hover = x > 0.9 && x < 1.0 && y < 0.14 && y > 0.0;
|
|
if (hover) {
|
|
|
|
_compass_init_hitbox();
|
|
|
|
f32 ratio = sys_w() / (float)sys_h();
|
|
mat4_t _P = scene_camera->p;
|
|
scene_camera->p = mat4_ortho(-8 * ratio, 8 * ratio, -8, 8, -2, 2);
|
|
|
|
transform_build_matrix(_compass_hitbox_x->transform);
|
|
transform_build_matrix(_compass_hitbox_y->transform);
|
|
transform_build_matrix(_compass_hitbox_z->transform);
|
|
|
|
transform_t_array_t *ts = any_array_create_from_raw(
|
|
(void *[]){
|
|
_compass_hitbox_x->transform,
|
|
_compass_hitbox_y->transform,
|
|
_compass_hitbox_z->transform,
|
|
},
|
|
3);
|
|
|
|
transform_t *t = raycast_closest_box_intersect(ts, mouse_view_x(), mouse_view_y(), scene_camera);
|
|
if (t != NULL) {
|
|
quat_t cq = scene_camera->base->transform->rot;
|
|
|
|
if (t == _compass_hitbox_x->transform) {
|
|
if (mouse_started("left")) {
|
|
// Flip between left / right
|
|
_compass_compare_quat(quat_from_euler(math_pi() / 2.0, 0, math_pi() / 2.0), cq)
|
|
? viewport_set_view(-1, 0, 0, math_pi() / 2.0, 0, -math_pi() / 2.0) // Left
|
|
: viewport_set_view(1, 0, 0, math_pi() / 2.0, 0, math_pi() / 2.0); // Right
|
|
}
|
|
gc_unroot(_compass_hovered);
|
|
_compass_hovered = _compass_hitbox_x;
|
|
gc_root(_compass_hovered);
|
|
}
|
|
|
|
else if (t == _compass_hitbox_y->transform) {
|
|
if (mouse_started("left")) {
|
|
_compass_compare_quat(quat_from_euler(math_pi() / 2.0, 0, math_pi()), cq)
|
|
? viewport_set_view(0, -1, 0, math_pi() / 2.0, 0, 0) // Front
|
|
: viewport_set_view(0, 1, 0, math_pi() / 2.0, 0, math_pi()); // Back
|
|
}
|
|
gc_unroot(_compass_hovered);
|
|
_compass_hovered = _compass_hitbox_y;
|
|
gc_root(_compass_hovered);
|
|
}
|
|
|
|
else {
|
|
if (mouse_started("left")) {
|
|
_compass_compare_quat(quat_from_euler(0, 0, 0), cq) ? viewport_set_view(0, 0, -1, math_pi(), 0, math_pi()) // Bottom
|
|
: viewport_set_view(0, 0, 1, 0, 0, 0); // Top
|
|
}
|
|
gc_unroot(_compass_hovered);
|
|
_compass_hovered = _compass_hitbox_z;
|
|
gc_root(_compass_hovered);
|
|
}
|
|
}
|
|
scene_camera->p = _P;
|
|
}
|
|
}
|