From c509dab0cf838d69c31b6230d8ad17aef50e1f4f Mon Sep 17 00:00:00 2001 From: Cooliokid956 <68075390+Cooliokid956@users.noreply.github.com> Date: Sun, 21 Jul 2024 17:58:38 -0500 Subject: [PATCH] Add rotation interpolation (#208) * Interpolate rotation * Autogen'd * Resolution 1 * Resolution 2 * Resolution 3 * Resolution 4 * Fixed jitter at low angular velocities More in the comment below --- autogen/lua_definitions/functions.lua | 10 ++++++++ autogen/lua_definitions/structs.lua | 3 +++ docs/lua/functions-3.md | 25 +++++++++++++++++++ docs/lua/functions.md | 1 + docs/lua/structs.md | 3 +++ src/pc/djui/djui_hud_utils.c | 36 +++++++++++++++++++++++++-- src/pc/djui/djui_hud_utils.h | 4 +++ src/pc/lua/smlua_cobject_autogen.c | 11 +++++--- src/pc/lua/smlua_functions_autogen.c | 28 +++++++++++++++++++++ 9 files changed, 115 insertions(+), 6 deletions(-) diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index f0973dcd..29da577d 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -3199,6 +3199,16 @@ function djui_hud_set_rotation(rotation, pivotX, pivotY) -- ... end +--- @param prevRotation integer +--- @param prevPivotX number +--- @param prevPivotY number +--- @param rotation integer +--- @param pivotX number +--- @param pivotY number +function djui_hud_set_rotation_interpolated(prevRotation, prevPivotX, prevPivotY, rotation, pivotX, pivotY) + -- ... +end + --- @param pos Vec3f --- @param out Vec3f --- @return boolean diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua index 0f5c66c4..c52b81cc 100644 --- a/autogen/lua_definitions/structs.lua +++ b/autogen/lua_definitions/structs.lua @@ -838,7 +838,10 @@ --- @class HudUtilsRotation --- @field public pivotX number --- @field public pivotY number +--- @field public prevPivotX number +--- @field public prevPivotY number --- @field public rotation number +--- @field public rotationDiff number --- @class InstantWarp --- @field public area integer diff --git a/docs/lua/functions-3.md b/docs/lua/functions-3.md index 31f26e04..961ffb8e 100644 --- a/docs/lua/functions-3.md +++ b/docs/lua/functions-3.md @@ -2594,6 +2594,31 @@
+## [djui_hud_set_rotation_interpolated](#djui_hud_set_rotation_interpolated) + +### Lua Example +`djui_hud_set_rotation_interpolated(prevRotation, prevPivotX, prevPivotY, rotation, pivotX, pivotY)` + +### Parameters +| Field | Type | +| ----- | ---- | +| prevRotation | `integer` | +| prevPivotX | `number` | +| prevPivotY | `number` | +| rotation | `integer` | +| pivotX | `number` | +| pivotY | `number` | + +### Returns +- None + +### C Prototype +`void djui_hud_set_rotation_interpolated(s32 prevRotation, f32 prevPivotX, f32 prevPivotY, s32 rotation, f32 pivotX, f32 pivotY);` + +[:arrow_up_small:](#) + +
+ ## [djui_hud_world_pos_to_screen_pos](#djui_hud_world_pos_to_screen_pos) ### Lua Example diff --git a/docs/lua/functions.md b/docs/lua/functions.md index 7b12d747..51c3307e 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -769,6 +769,7 @@ - [djui_hud_set_mouse_locked](functions-3.md#djui_hud_set_mouse_locked) - [djui_hud_set_resolution](functions-3.md#djui_hud_set_resolution) - [djui_hud_set_rotation](functions-3.md#djui_hud_set_rotation) + - [djui_hud_set_rotation_interpolated](functions-3.md#djui_hud_set_rotation_interpolated) - [djui_hud_world_pos_to_screen_pos](functions-3.md#djui_hud_world_pos_to_screen_pos) - [djui_open_pause_menu](functions-3.md#djui_open_pause_menu) diff --git a/docs/lua/structs.md b/docs/lua/structs.md index 2146f235..619a95dc 100644 --- a/docs/lua/structs.md +++ b/docs/lua/structs.md @@ -1158,7 +1158,10 @@ | ----- | ---- | ------ | | pivotX | `number` | | | pivotY | `number` | | +| prevPivotX | `number` | | +| prevPivotY | `number` | | | rotation | `number` | | +| rotationDiff | `number` | | [:arrow_up_small:](#) diff --git a/src/pc/djui/djui_hud_utils.c b/src/pc/djui/djui_hud_utils.c index 1a4847bb..9fbb72ca 100644 --- a/src/pc/djui/djui_hud_utils.c +++ b/src/pc/djui/djui_hud_utils.c @@ -27,7 +27,7 @@ static enum HudUtilsResolution sResolution = RESOLUTION_DJUI; static enum HudUtilsFilter sFilter = FILTER_NEAREST; static enum DjuiFontType sFont = FONT_NORMAL; -static struct HudUtilsRotation sRotation = { 0, 0, 0 }; +static struct HudUtilsRotation sRotation = { 0, 0, 0, 0, 0, 0 }; static struct DjuiColor sColor = { 255, 255, 255, 255 }; static struct DjuiColor sRefColor = { 255, 255, 255, 255 }; static bool sLegacy = false; @@ -101,6 +101,7 @@ struct InterpHud { f32 width; f32 height; enum HudUtilsResolution resolution; + struct HudUtilsRotation rotation; }; static struct InterpHud sInterpHuds[MAX_INTERP_HUD] = { 0 }; static u16 sInterpHudCount = 0; @@ -114,6 +115,7 @@ void patch_djui_hud(f32 delta) { f32 savedZ = gDjuiHudUtilsZ; Gfx* savedHeadPos = gDisplayListHead; enum HudUtilsResolution savedResolution = sResolution; + struct HudUtilsRotation savedRotation = sRotation; for (u16 i = 0; i < sInterpHudCount; i++) { struct InterpHud* interp = &sInterpHuds[i]; f32 x = delta_interpolate_f32(interp->prevX, interp->x, delta); @@ -121,6 +123,7 @@ void patch_djui_hud(f32 delta) { f32 scaleW = delta_interpolate_f32(interp->prevScaleW, interp->scaleW, delta); f32 scaleH = delta_interpolate_f32(interp->prevScaleH, interp->scaleH, delta); sResolution = interp->resolution; + sRotation = interp->rotation; gDjuiHudUtilsZ = interp->z; gDisplayListHead = interp->headPos; @@ -131,14 +134,27 @@ void patch_djui_hud(f32 delta) { djui_hud_position_translate(&translatedX, &translatedY); create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, gDjuiHudUtilsZ); - // translate scale + // rotate f32 translatedW = scaleW; f32 translatedH = scaleH; + s32 rotation = delta_interpolate_s32(sRotation.rotation - sRotation.rotationDiff, sRotation.rotation, delta); + f32 pivotX = delta_interpolate_f32(sRotation.prevPivotX, sRotation.pivotX, delta); + f32 pivotY = delta_interpolate_f32(sRotation.prevPivotY, sRotation.pivotY, delta); djui_hud_size_translate(&translatedW); djui_hud_size_translate(&translatedH); + if (sRotation.rotationDiff != 0 || sRotation.rotation != 0) { + f32 pivotTranslationX = translatedW * pivotX; + f32 pivotTranslationY = translatedH * pivotY; + create_dl_translation_matrix(DJUI_MTX_NOPUSH, +pivotTranslationX, -pivotTranslationY, 0); + create_dl_rotation_matrix(DJUI_MTX_NOPUSH, rotation, 0, 0, 1); + create_dl_translation_matrix(DJUI_MTX_NOPUSH, -pivotTranslationX, +pivotTranslationY, 0); + } + + // scale create_dl_scale_matrix(DJUI_MTX_NOPUSH, interp->width * translatedW, interp->height * translatedH, 1.0f); } sResolution = savedResolution; + sRotation = savedRotation; gDisplayListHead = savedHeadPos; gDjuiHudUtilsZ = savedZ; } @@ -209,6 +225,18 @@ struct HudUtilsRotation* djui_hud_get_rotation(void) { } void djui_hud_set_rotation(s16 rotation, f32 pivotX, f32 pivotY) { + sRotation.rotationDiff = 0; + sRotation.prevPivotX = pivotX; + sRotation.prevPivotY = pivotY; + sRotation.rotation = (rotation * 180.f) / 0x8000; + sRotation.pivotX = pivotX; + sRotation.pivotY = pivotY; +} + +void djui_hud_set_rotation_interpolated(s32 prevRotation, f32 prevPivotX, f32 prevPivotY, s32 rotation, f32 pivotX, f32 pivotY) { + sRotation.rotationDiff = ((rotation - prevRotation) * 180.f) / 0x8000; + sRotation.prevPivotX = prevPivotX; + sRotation.prevPivotY = prevPivotY; sRotation.rotation = (rotation * 180.f) / 0x8000; sRotation.pivotX = pivotX; sRotation.pivotY = pivotY; @@ -386,6 +414,7 @@ void djui_hud_print_text_interpolated(const char* message, f32 prevX, f32 prevY, interp->height = font->defaultFontScale; interp->z = savedZ; interp->resolution = sResolution; + interp->rotation = sRotation; } static inline bool is_power_of_two(u32 n) { @@ -493,6 +522,7 @@ void djui_hud_render_texture_interpolated(struct TextureInfo* texInfo, f32 prevX interp->height = texInfo->height; interp->z = savedZ; interp->resolution = sResolution; + interp->rotation = sRotation; } void djui_hud_render_texture_tile_interpolated(struct TextureInfo* texInfo, f32 prevX, f32 prevY, f32 prevScaleW, f32 prevScaleH, f32 x, f32 y, f32 scaleW, f32 scaleH, u32 tileX, u32 tileY, u32 tileW, u32 tileH) { @@ -516,6 +546,7 @@ void djui_hud_render_texture_tile_interpolated(struct TextureInfo* texInfo, f32 interp->height = texInfo->height; interp->z = savedZ; interp->resolution = sResolution; + interp->rotation = sRotation; } void djui_hud_render_rect(f32 x, f32 y, f32 width, f32 height) { @@ -571,6 +602,7 @@ void djui_hud_render_rect_interpolated(f32 prevX, f32 prevY, f32 prevWidth, f32 interp->height = 1; interp->z = savedZ; interp->resolution = sResolution; + interp->rotation = sRotation; } static void hud_rotate_and_translate_vec3f(Vec3f vec, Mat4* mtx, Vec3f out) { diff --git a/src/pc/djui/djui_hud_utils.h b/src/pc/djui/djui_hud_utils.h index 91e8b07f..d001fbd7 100644 --- a/src/pc/djui/djui_hud_utils.h +++ b/src/pc/djui/djui_hud_utils.h @@ -25,6 +25,9 @@ enum DjuiFontType { struct HudUtilsRotation { f32 rotation; + f32 rotationDiff; + f32 prevPivotX; + f32 prevPivotY; f32 pivotX; f32 pivotY; }; @@ -61,6 +64,7 @@ void djui_hud_set_color(u8 r, u8 g, u8 b, u8 a); void djui_hud_reset_color(void); struct HudUtilsRotation* djui_hud_get_rotation(void); void djui_hud_set_rotation(s16 rotation, f32 pivotX, f32 pivotY); +void djui_hud_set_rotation_interpolated(s32 prevRotation, f32 prevPivotX, f32 prevPivotY, s32 rotation, f32 pivotX, f32 pivotY); u32 djui_hud_get_screen_width(void); u32 djui_hud_get_screen_height(void); diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c index ff46bc1f..260cab04 100644 --- a/src/pc/lua/smlua_cobject_autogen.c +++ b/src/pc/lua/smlua_cobject_autogen.c @@ -943,11 +943,14 @@ static struct LuaObjectField sHandheldShakePointFields[LUA_HANDHELD_SHAKE_POINT_ { "point", LVT_COBJECT, offsetof(struct HandheldShakePoint, point), true, LOT_VEC3S }, }; -#define LUA_HUD_UTILS_ROTATION_FIELD_COUNT 3 +#define LUA_HUD_UTILS_ROTATION_FIELD_COUNT 6 static struct LuaObjectField sHudUtilsRotationFields[LUA_HUD_UTILS_ROTATION_FIELD_COUNT] = { - { "pivotX", LVT_F32, offsetof(struct HudUtilsRotation, pivotX), false, LOT_NONE }, - { "pivotY", LVT_F32, offsetof(struct HudUtilsRotation, pivotY), false, LOT_NONE }, - { "rotation", LVT_F32, offsetof(struct HudUtilsRotation, rotation), false, LOT_NONE }, + { "pivotX", LVT_F32, offsetof(struct HudUtilsRotation, pivotX), false, LOT_NONE }, + { "pivotY", LVT_F32, offsetof(struct HudUtilsRotation, pivotY), false, LOT_NONE }, + { "prevPivotX", LVT_F32, offsetof(struct HudUtilsRotation, prevPivotX), false, LOT_NONE }, + { "prevPivotY", LVT_F32, offsetof(struct HudUtilsRotation, prevPivotY), false, LOT_NONE }, + { "rotation", LVT_F32, offsetof(struct HudUtilsRotation, rotation), false, LOT_NONE }, + { "rotationDiff", LVT_F32, offsetof(struct HudUtilsRotation, rotationDiff), false, LOT_NONE }, }; #define LUA_INSTANT_WARP_FIELD_COUNT 3 diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index 058e540e..e1f2a50a 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -12680,6 +12680,33 @@ int smlua_func_djui_hud_set_rotation(lua_State* L) { return 1; } +int smlua_func_djui_hud_set_rotation_interpolated(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 6) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "djui_hud_set_rotation_interpolated", 6, top); + return 0; + } + + s32 prevRotation = smlua_to_integer(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "djui_hud_set_rotation_interpolated"); return 0; } + f32 prevPivotX = smlua_to_number(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "djui_hud_set_rotation_interpolated"); return 0; } + f32 prevPivotY = smlua_to_number(L, 3); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "djui_hud_set_rotation_interpolated"); return 0; } + s32 rotation = smlua_to_integer(L, 4); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "djui_hud_set_rotation_interpolated"); return 0; } + f32 pivotX = smlua_to_number(L, 5); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 5, "djui_hud_set_rotation_interpolated"); return 0; } + f32 pivotY = smlua_to_number(L, 6); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 6, "djui_hud_set_rotation_interpolated"); return 0; } + + djui_hud_set_rotation_interpolated(prevRotation, prevPivotX, prevPivotY, rotation, pivotX, pivotY); + + return 1; +} + int smlua_func_djui_hud_world_pos_to_screen_pos(lua_State* L) { if (L == NULL) { return 0; } @@ -33747,6 +33774,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "djui_hud_set_mouse_locked", smlua_func_djui_hud_set_mouse_locked); smlua_bind_function(L, "djui_hud_set_resolution", smlua_func_djui_hud_set_resolution); smlua_bind_function(L, "djui_hud_set_rotation", smlua_func_djui_hud_set_rotation); + smlua_bind_function(L, "djui_hud_set_rotation_interpolated", smlua_func_djui_hud_set_rotation_interpolated); smlua_bind_function(L, "djui_hud_world_pos_to_screen_pos", smlua_func_djui_hud_world_pos_to_screen_pos); smlua_bind_function(L, "djui_open_pause_menu", smlua_func_djui_open_pause_menu);