mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-07-07 12:03:24 -04:00
Frame interp: Fix Epona's reins
This commit is contained in:
@@ -196,6 +196,9 @@ public:
|
||||
void copyReinPos();
|
||||
void setReinPosHandSubstance(int);
|
||||
void setReinPosNormalSubstance();
|
||||
#if TARGET_PC
|
||||
void lerpControlPoints(f32 alpha);
|
||||
#endif
|
||||
void bgCheck();
|
||||
bool checkSpecialWallHitSubstance(cXyz const&) const;
|
||||
void setServiceWaitTimer();
|
||||
|
||||
@@ -435,6 +435,10 @@ public:
|
||||
m3DLineMatSortPacket[param_1->getMaterialID()].setMatDark(param_1);
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
void refresh3DlineMats(const cXyz& eye);
|
||||
#endif
|
||||
|
||||
void peekZdata() { mPeekZ.peekData(); }
|
||||
void entryZSortListZxlu(J3DPacket* i_packet, cXyz& param_1) {
|
||||
entryZSortXluDrawList(mDrawBuffers[DB_LIST_Z_XLU], i_packet, param_1);
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct cXyz;
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace dusk {
|
||||
namespace frame_interp {
|
||||
@@ -15,6 +17,7 @@ void ensure_initialized();
|
||||
void begin_record();
|
||||
void end_record();
|
||||
void interpolate(float step);
|
||||
float get_interpolation_step();
|
||||
void notify_sim_tick_complete();
|
||||
uint32_t begin_presentation_ui_pass();
|
||||
uint32_t get_presentation_ui_advance_ticks();
|
||||
@@ -27,6 +30,8 @@ void record_final_mtx_raw(const Mtx* dest, const Mtx src);
|
||||
bool lookup_replacement(const void* source, Mtx out);
|
||||
bool lookup_concat_replacement(const void* lhs, const void* rhs, Mtx out);
|
||||
|
||||
void camera_eye_from_view_mtx(MtxP view_mtx, cXyz* o_eye);
|
||||
|
||||
} // namespace frame_interp
|
||||
} // namespace dusk
|
||||
#endif
|
||||
|
||||
@@ -541,6 +541,9 @@ public:
|
||||
virtual int getMaterialID() = 0;
|
||||
virtual void setMaterial() = 0;
|
||||
virtual void draw() = 0;
|
||||
#if TARGET_PC
|
||||
virtual void refreshGeometryForPresentationEye(const cXyz& eye) {}
|
||||
#endif
|
||||
|
||||
/* 0x4 */ mDoExt_3DlineMat_c* field_0x4;
|
||||
};
|
||||
@@ -582,11 +585,19 @@ class dKy_tevstr_c;
|
||||
class mDoExt_3DlineMat1_c : public mDoExt_3DlineMat_c {
|
||||
public:
|
||||
int init(u16, u16, ResTIMG*, int);
|
||||
#if TARGET_PC
|
||||
void update(int, GXColor&, dKy_tevstr_c*, const cXyz* presentationEye = nullptr);
|
||||
void update(int, f32, GXColor&, u16, dKy_tevstr_c*, const cXyz* presentationEye = nullptr);
|
||||
#else
|
||||
void update(int, GXColor&, dKy_tevstr_c*);
|
||||
void update(int, f32, GXColor&, u16, dKy_tevstr_c*);
|
||||
#endif
|
||||
int getMaterialID() { return 1; }
|
||||
void setMaterial();
|
||||
void draw();
|
||||
#if TARGET_PC
|
||||
void refreshGeometryForPresentationEye(const cXyz& eye) override;
|
||||
#endif
|
||||
|
||||
cXyz* getPos(int i_idx) { return mpLines[i_idx].field_0x0; }
|
||||
f32* getSize(int i_idx) { return mpLines[i_idx].field_0x4; }
|
||||
@@ -600,6 +611,11 @@ private:
|
||||
/* 0x34 */ u16 field_0x34;
|
||||
/* 0x36 */ u8 mIsDrawn;
|
||||
/* 0x38 */ mDoExt_3Dline_c* mpLines;
|
||||
#if TARGET_PC
|
||||
u8 mInterpLineKind;
|
||||
f32 mInterpLineF;
|
||||
u16 mInterpLineU16;
|
||||
#endif
|
||||
};
|
||||
|
||||
class mDoExt_3DlineMat2_c : public mDoExt_3DlineMat1_c {
|
||||
@@ -616,6 +632,9 @@ public:
|
||||
void setMatDark(mDoExt_3DlineMat_c* i_mat) { setMat(i_mat); }
|
||||
|
||||
void setMat(mDoExt_3DlineMat_c*);
|
||||
#if TARGET_PC
|
||||
mDoExt_3DlineMat_c* getFirstMat() const { return mp3DlineMat; }
|
||||
#endif
|
||||
virtual void draw();
|
||||
virtual ~mDoExt_3DlineMatSortPacket() {}
|
||||
|
||||
|
||||
@@ -20,6 +20,21 @@
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
#if TARGET_PC
|
||||
#include "dusk/dusk.h"
|
||||
|
||||
namespace {
|
||||
// FRAME INTERP NOTE: Sim tick control point snapshots for interpolation
|
||||
constexpr int kHorseReinSimMax = 75;
|
||||
cXyz s_horseReinSimPrev[kHorseReinSimMax];
|
||||
cXyz s_horseReinSimCurr[kHorseReinSimMax];
|
||||
int s_horseReinSimNumPrev;
|
||||
int s_horseReinSimNumCurr;
|
||||
bool s_horseReinSimPrevValid;
|
||||
bool s_horseReinSimCurrValid;
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
#define ANM_HS_BACK_WALK 6
|
||||
#define ANM_HS_WALK_START 7
|
||||
#define ANM_HS_EXCITEMENT 8
|
||||
@@ -3016,6 +3031,20 @@ void daHorse_c::copyReinPos() {
|
||||
for (i = rein->field_0x8[0] - 1; i >= 0; i--, pos_p++) {
|
||||
*pos_p = rein->field_0x0[0][i];
|
||||
}
|
||||
#if TARGET_PC
|
||||
if (field_0x1204 > 0) {
|
||||
if (s_horseReinSimCurrValid && s_horseReinSimNumCurr > 0) {
|
||||
memcpy(s_horseReinSimPrev, s_horseReinSimCurr, s_horseReinSimNumCurr * sizeof(cXyz));
|
||||
s_horseReinSimNumPrev = s_horseReinSimNumCurr;
|
||||
s_horseReinSimPrevValid = true;
|
||||
}
|
||||
memcpy(s_horseReinSimCurr, m_reinLine.getPos(0), field_0x1204 * sizeof(cXyz));
|
||||
s_horseReinSimNumCurr = field_0x1204;
|
||||
s_horseReinSimCurrValid = true;
|
||||
} else {
|
||||
s_horseReinSimCurrValid = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void daHorse_c::setReinPosHandSubstance(int param_0) {
|
||||
@@ -3127,6 +3156,30 @@ void daHorse_c::setReinPosNormalSubstance() {
|
||||
copyReinPos();
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
void daHorse_c::lerpControlPoints(f32 alpha) {
|
||||
// FRAME INTERP NOTE: Currently only lerping points for Epona's reins. Need a more global solution.
|
||||
if (!dusk::getSettings().game.enableFrameInterpolation || !s_horseReinSimPrevValid || !s_horseReinSimCurrValid) {
|
||||
return;
|
||||
}
|
||||
const int nCurr = s_horseReinSimNumCurr;
|
||||
const int nPrev = s_horseReinSimNumPrev;
|
||||
if (nCurr <= 0) {
|
||||
return;
|
||||
}
|
||||
int n = nPrev < nCurr ? nPrev : nCurr;
|
||||
if (n <= 0 || n > kHorseReinSimMax) {
|
||||
return;
|
||||
}
|
||||
cXyz* dst = m_reinLine.getPos(0);
|
||||
for (int i = 0; i < n; i++) {
|
||||
const cXyz& p0 = s_horseReinSimPrev[i];
|
||||
const cXyz& p1 = s_horseReinSimCurr[i];
|
||||
dst[i] = p0 + (p1 - p0) * alpha;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void daHorse_c::bgCheck() {
|
||||
if (m_procID != PROC_LARGE_DAMAGE_e) {
|
||||
static cXyz localCenterPos(0.0f, 100.0f, 0.0f);
|
||||
|
||||
@@ -2017,3 +2017,13 @@ void dDlst_list_c::calcWipe() {
|
||||
dComIfGd_set2DXlu(&mWipeDlst);
|
||||
}
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
void dDlst_list_c::refresh3DlineMats(const cXyz& eye) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (mDoExt_3DlineMat_c* mat = m3DLineMatSortPacket[i].getFirstMat(); mat != NULL; mat = mat->field_0x4) {
|
||||
mat->refreshGeometryForPresentationEye(eye);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -300,6 +300,10 @@ void interpolate(float step) {
|
||||
interpolate_branch(g_previous_recording.root, g_current_recording.root, g_step);
|
||||
}
|
||||
|
||||
float get_interpolation_step() {
|
||||
return g_step;
|
||||
}
|
||||
|
||||
void notify_sim_tick_complete() {
|
||||
ensure_initialized();
|
||||
g_pending_presentation_ui_ticks++;
|
||||
@@ -394,5 +398,12 @@ bool lookup_concat_replacement(const void* lhs, const void* rhs, Mtx out) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: Is there already a built-in function for this?
|
||||
void camera_eye_from_view_mtx(MtxP view_mtx, cXyz* o_eye) {
|
||||
o_eye->x = -(view_mtx[0][0] * view_mtx[0][3] + view_mtx[1][0] * view_mtx[1][3] + view_mtx[2][0] * view_mtx[2][3]);
|
||||
o_eye->y = -(view_mtx[0][1] * view_mtx[0][3] + view_mtx[1][1] * view_mtx[1][3] + view_mtx[2][1] * view_mtx[2][3]);
|
||||
o_eye->z = -(view_mtx[0][2] * view_mtx[0][3] + view_mtx[1][2] * view_mtx[1][3] + view_mtx[2][2] * view_mtx[2][3]);
|
||||
}
|
||||
|
||||
} // namespace frame_interp
|
||||
} // namespace dusk
|
||||
|
||||
+74
-5
@@ -2398,7 +2398,12 @@ void mDoExt_3DlineMat0_c::draw() {
|
||||
var_r28++;
|
||||
}
|
||||
|
||||
field_0x16 ^= (u8)1;
|
||||
#if TARGET_PC
|
||||
if (!dusk::getSettings().game.enableFrameInterpolation)
|
||||
#endif
|
||||
{
|
||||
field_0x16 ^= (u8)1;
|
||||
}
|
||||
}
|
||||
|
||||
void mDoExt_3DlineMat0_c::update(int param_0, f32 param_1, GXColor& param_2, u16 param_3,
|
||||
@@ -2648,6 +2653,9 @@ int mDoExt_3DlineMat1_c::init(u16 param_0, u16 param_1, ResTIMG* param_2, int pa
|
||||
|
||||
field_0x4 = 0;
|
||||
mIsDrawn = 0;
|
||||
#if TARGET_PC
|
||||
mInterpLineKind = 0;
|
||||
#endif
|
||||
|
||||
GXInitTexObj(&mTextureObject, (void*)((intptr_t)param_2 + param_2->imageOffset), param_2->width,
|
||||
param_2->height, (GXTexFmt)param_2->format, (GXTexWrapMode)param_2->wrapS,
|
||||
@@ -2720,11 +2728,19 @@ void mDoExt_3DlineMat1_c::draw() {
|
||||
lines++;
|
||||
}
|
||||
GXSetTexCoordScaleManually(GX_TEXCOORD0, 0, 0, 0);
|
||||
mIsDrawn ^= (u8)1;
|
||||
#if TARGET_PC
|
||||
if (!dusk::getSettings().game.enableFrameInterpolation)
|
||||
#endif
|
||||
{
|
||||
mIsDrawn ^= (u8)1;
|
||||
}
|
||||
}
|
||||
|
||||
void mDoExt_3DlineMat1_c::update(int param_0, f32 param_1, GXColor& param_2, u16 param_3,
|
||||
dKy_tevstr_c* param_4) {
|
||||
#if TARGET_PC
|
||||
void mDoExt_3DlineMat1_c::update(int param_0, f32 param_1, GXColor& param_2, u16 param_3, dKy_tevstr_c* param_4, const cXyz* presentationEye) {
|
||||
#else
|
||||
void mDoExt_3DlineMat1_c::update(int param_0, f32 param_1, GXColor& param_2, u16 param_3, dKy_tevstr_c* param_4) {
|
||||
#endif
|
||||
mColor = param_2;
|
||||
this->mpTevStr = param_4;
|
||||
if (param_0 < 0) {
|
||||
@@ -2734,6 +2750,13 @@ void mDoExt_3DlineMat1_c::update(int param_0, f32 param_1, GXColor& param_2, u16
|
||||
} else {
|
||||
field_0x34 = param_0;
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
mInterpLineKind = 1;
|
||||
mInterpLineF = param_1;
|
||||
mInterpLineU16 = param_3;
|
||||
#endif
|
||||
|
||||
view_class* sp_3c = dComIfGd_getView();
|
||||
mDoExt_3Dline_c* sp_38 = mpLines;
|
||||
f32 local_f27 = param_3 != 0 ? param_1 / param_3 : 0.0f;
|
||||
@@ -2787,7 +2810,12 @@ void mDoExt_3DlineMat1_c::update(int param_0, f32 param_1, GXColor& param_2, u16
|
||||
local_f31 += local_f30 * 0.02f * (8.0f / param_1);
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
const cXyz& lineEye = (presentationEye != nullptr && dusk::getSettings().game.enableFrameInterpolation) ? *presentationEye : sp_3c->lookat.eye;
|
||||
sp_13c = *local_r27 - lineEye;
|
||||
#else
|
||||
sp_13c = *local_r27 - sp_3c->lookat.eye;
|
||||
#endif
|
||||
sp_130 = sp_130.outprod(sp_13c);
|
||||
sp_130.normalizeZP();
|
||||
|
||||
@@ -2822,7 +2850,11 @@ void mDoExt_3DlineMat1_c::update(int param_0, f32 param_1, GXColor& param_2, u16
|
||||
local_f31 += local_f30 * 0.02f * (8.0f / param_1);
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
sp_13c = local_r27[0] - lineEye;
|
||||
#else
|
||||
sp_13c = local_r27[0] - sp_3c->lookat.eye;
|
||||
#endif
|
||||
sp_130 = sp_130.outprod(sp_13c);
|
||||
sp_130.normalizeZP();
|
||||
|
||||
@@ -2894,7 +2926,11 @@ void mDoExt_3DlineMat2_c::setMaterial() {
|
||||
GXLoadNrmMtxImm(cMtx_getIdentity(), 0);
|
||||
}
|
||||
|
||||
void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* param_4) {
|
||||
#if TARGET_PC
|
||||
void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* param_4, const cXyz* presentationEye) {
|
||||
#else
|
||||
void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* param_4
|
||||
#endif
|
||||
mColor = param_2;
|
||||
this->mpTevStr = param_4;
|
||||
if (param_0 < 0) {
|
||||
@@ -2904,6 +2940,11 @@ void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* pa
|
||||
} else {
|
||||
field_0x34 = param_0;
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
mInterpLineKind = 2;
|
||||
#endif
|
||||
|
||||
view_class* stack_3c = dComIfGd_getView();
|
||||
mDoExt_3Dline_c* sp_38 = mpLines;
|
||||
f32 local_f30;
|
||||
@@ -2929,6 +2970,12 @@ void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* pa
|
||||
for (s32 sp_14 = 0; sp_14 < mNumLines; sp_14++) {
|
||||
local_r27 = sp_38[0].field_0x0;
|
||||
size_p = sp_38->field_0x4;
|
||||
#if TARGET_PC
|
||||
if (presentationEye != nullptr && dusk::getSettings().game.enableFrameInterpolation && size_p == NULL) {
|
||||
sp_38 += 1;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
JUT_ASSERT(5875, size_p != NULL);
|
||||
sp_24 = sp_38->field_0x8[mIsDrawn];
|
||||
sp_28 = sp_24;
|
||||
@@ -2942,7 +2989,12 @@ void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* pa
|
||||
sp_130 = local_r27[1] - local_r27[0];
|
||||
local_f30 = sp_130.abs();
|
||||
local_f31 += local_f30 * 0.1f;
|
||||
#if TARGET_PC
|
||||
const cXyz& lineEye = (presentationEye != nullptr && dusk::getSettings().game.enableFrameInterpolation) ? *presentationEye : stack_3c->lookat.eye;
|
||||
sp_13c = local_r27[0] - lineEye;
|
||||
#else
|
||||
sp_13c = local_r27[0] - stack_3c->lookat.eye;
|
||||
#endif
|
||||
sp_130 = sp_130.outprod(sp_13c);
|
||||
sp_130.normalizeZP();
|
||||
local_r30->x = sp_130.x * 64.0f;
|
||||
@@ -2964,7 +3016,11 @@ void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* pa
|
||||
sp_130 = local_r27[1] - local_r27[0];
|
||||
local_f30 = sp_130.abs();
|
||||
local_f31 += local_f30 * 0.1f;
|
||||
#if TARGET_PC
|
||||
sp_13c = local_r27[0] - lineEye;
|
||||
#else
|
||||
sp_13c = local_r27[0] - stack_3c->lookat.eye;
|
||||
#endif
|
||||
sp_130 = sp_130.outprod(sp_13c);
|
||||
sp_130.normalizeZP();
|
||||
local_r30 += 2;
|
||||
@@ -3008,6 +3064,19 @@ void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* pa
|
||||
}
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
void mDoExt_3DlineMat1_c::refreshGeometryForPresentationEye(const cXyz& eye) {
|
||||
if (!dusk::getSettings().game.enableFrameInterpolation) {
|
||||
return;
|
||||
}
|
||||
if (mInterpLineKind == 1) {
|
||||
update(field_0x34, mInterpLineF, mColor, mInterpLineU16, mpTevStr, &eye);
|
||||
} else if (mInterpLineKind == 2) {
|
||||
update(field_0x34, mColor, mpTevStr, &eye);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void mDoExt_3DlineMatSortPacket::setMat(mDoExt_3DlineMat_c* i_3DlineMat) {
|
||||
if (mp3DlineMat == NULL) {
|
||||
dComIfGd_getListPacket()->entryImm(this, 0);
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#endif
|
||||
|
||||
#if TARGET_PC
|
||||
#include "d/actor/d_a_horse.h"
|
||||
#include "dusk/imgui/ImGuiConsole.hpp"
|
||||
#include "dusk/dusk.h"
|
||||
#endif
|
||||
@@ -1952,6 +1953,18 @@ int mDoGph_Painter() {
|
||||
GX_DEBUG_GROUP(dComIfGd_drawOpaListDark);
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableFrameInterpolation) {
|
||||
cXyz pres_eye;
|
||||
dusk::frame_interp::camera_eye_from_view_mtx(j3dSys.getViewMtx(), &pres_eye);
|
||||
// FRAME INTERP NOTE: Currently only recalculating points for Epona's reins. Need a more global solution.
|
||||
if (daHorse_c* horse = dComIfGp_getHorseActor()) {
|
||||
horse->lerpControlPoints(dusk::frame_interp::get_interpolation_step());
|
||||
}
|
||||
g_dComIfG_gameInfo.drawlist.refresh3DlineMats(pres_eye);
|
||||
}
|
||||
#endif
|
||||
|
||||
GX_DEBUG_GROUP(dComIfGd_drawOpaListPacket);
|
||||
|
||||
#if DEBUG
|
||||
|
||||
Reference in New Issue
Block a user