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
This commit is contained in:
Cooliokid956 2024-07-21 17:58:38 -05:00 committed by GitHub
parent 1ac9ce8e4c
commit c509dab0cf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 115 additions and 6 deletions

View File

@ -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

View File

@ -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

View File

@ -2594,6 +2594,31 @@
<br />
## [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:](#)
<br />
## [djui_hud_world_pos_to_screen_pos](#djui_hud_world_pos_to_screen_pos)
### Lua Example

View File

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

View File

@ -1158,7 +1158,10 @@
| ----- | ---- | ------ |
| pivotX | `number` | |
| pivotY | `number` | |
| prevPivotX | `number` | |
| prevPivotY | `number` | |
| rotation | `number` | |
| rotationDiff | `number` | |
[:arrow_up_small:](#)

View File

@ -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) {

View File

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

View File

@ -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

View File

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