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);