water interpolation fix

This commit is contained in:
Jasper St. Pierre
2026-04-18 22:17:19 -07:00
parent 6dcf4942f5
commit b3f8fecfe4
10 changed files with 108 additions and 7 deletions
+2 -4
View File
@@ -4834,8 +4834,7 @@ inline void dComIfGd_drawXluListDark() {
inline void dComIfGd_drawXluListInvisible() {
ZoneScoped;
#ifdef TARGET_PC
if (dusk::getSettings().game.enableWaterRefraction &&
!dusk::getSettings().game.enableFrameInterpolation) {
if (dusk::getSettings().game.enableWaterRefraction) {
#endif
g_dComIfG_gameInfo.drawlist.drawXluListInvisible();
#ifdef TARGET_PC
@@ -4846,8 +4845,7 @@ inline void dComIfGd_drawXluListInvisible() {
inline void dComIfGd_drawOpaListInvisible() {
ZoneScoped;
#ifdef TARGET_PC
if (dusk::getSettings().game.enableWaterRefraction &&
!dusk::getSettings().game.enableFrameInterpolation) {
if (dusk::getSettings().game.enableWaterRefraction) {
#endif
g_dComIfG_gameInfo.drawlist.drawOpaListInvisible();
#ifdef TARGET_PC
+7
View File
@@ -22,6 +22,8 @@ float get_interpolation_step();
void request_presentation_sync();
bool presentation_sync_active();
bool is_enabled();
// TODO: These should be phased out as UI is progressively updated to use game_clock
void set_ui_tick_pending(bool value);
bool get_ui_tick_pending();
@@ -35,6 +37,11 @@ void record_final_mtx_raw_tagged(const Mtx* dest, const Mtx src, uint64_t stable
bool lookup_replacement(const void* source, Mtx out);
bool lookup_concat_replacement(const void* lhs, const void* rhs, Mtx out);
typedef void (*InterpolationCallBack)(void* pUserWork);
void reset_interpolation_callbacks();
// call on a sim tick, will get called during presentation
void add_interpolation_callback(InterpolationCallBack pCallBack, void* pUserWork);
void begin_presentation_camera();
void end_presentation_camera();
@@ -79,6 +79,10 @@ public:
virtual void viewCalc();
virtual ~J3DModel() {}
#if TARGET_PC
static void interp_callback(void* pUserWork);
#endif
J3DModelData* getModelData() { return mModelData; }
void onFlag(u32 flag) { mFlags |= flag; }
@@ -23,6 +23,10 @@ public:
void syncJ3DSysPointers() const;
void syncJ3DSysFlags() const;
#if TARGET_PC
bool needsInterpCallBack() const;
#endif
virtual ~J3DModelData() {}
void simpleCalcMaterial(Mtx mtx) { simpleCalcMaterial(0, mtx); }
@@ -33,6 +33,9 @@ public:
void copy(J3DMaterial*);
s32 newSharedDisplayList(u32);
s32 newSingleSharedDisplayList(u32);
#if TARGET_PC
bool needsInterpCallBack() const;
#endif
virtual void calc(f32 const (*)[4]);
virtual void calcDiffTexMtx(f32 const (*)[4]);
@@ -46,7 +49,6 @@ public:
virtual void change();
J3DMaterial() { initialize(); }
~J3DMaterial() {}
J3DMaterial* getNext() { return mNext; }
J3DShape* getShape() { return mShape; }
J3DTevBlock* getTevBlock() { return mTevBlock; }
@@ -97,6 +97,14 @@ s32 J3DModel::entryModelData(J3DModelData* pModelData, u32 mdlFlags, u32 mtxNum)
return kJ3DError_Success;
}
#if TARGET_PC
void J3DModel::interp_callback(void* pUserWork) {
J3DModel* i_this = static_cast<J3DModel*>(pUserWork);
i_this->calcMaterial();
i_this->diff();
}
#endif
s32 J3DModel::createShapePacket(J3DModelData* pModelData) {
J3D_ASSERTMSG(173, pModelData != NULL, "Error : null pointer.");
@@ -283,6 +291,11 @@ void J3DModel::calcMaterial() {
material->calc(getAnmMtx(material->getJoint()->getJntNo()));
}
#if TARGET_PC
if (mModelData->needsInterpCallBack())
dusk::frame_interp::add_interpolation_callback(&J3DModel::interp_callback, this);
#endif
}
void J3DModel::calcDiffTexMtx() {
@@ -84,6 +84,15 @@ void J3DModelData::simpleCalcMaterial(u16 idx, Mtx param_1) {
}
}
#if TARGET_PC
bool J3DModelData::needsInterpCallBack() const {
for (u16 i = 0, n = getMaterialNum(); i < n; i++)
if (getMaterialNodePointer(i)->needsInterpCallBack())
return true;
return false;
}
#endif
void J3DModelData::syncJ3DSysPointers() const {
j3dSys.setTexture(getTexture());
j3dSys.setVtxPos(getVtxPosArray(), getVtxNum());
@@ -371,6 +371,28 @@ s32 J3DMaterial::newSingleSharedDisplayList(u32 dlSize) {
return kJ3DError_Success;
}
#if TARGET_PC
bool J3DMaterial::needsInterpCallBack() const {
for (int i = 0, n = getTexGenNum(); i < n; i++) {
J3DTexMtx* pTexMtx = mTexGenBlock->getTexMtx(i);
if (pTexMtx != NULL) {
u32 texMtxMode = pTexMtx->getTexMtxInfo().mInfo & 0x3f;
// uses j3dSys.getViewMtx()
switch (texMtxMode) {
case J3DTexMtxMode_EnvmapBasic:
case J3DTexMtxMode_EnvmapOld:
case J3DTexMtxMode_Envmap:
case J3DTexMtxMode_ViewProjmap:
case J3DTexMtxMode_ViewProjmapBasic:
return true;
}
}
}
return false;
}
#endif
void J3DPatchedMaterial::initialize() {
J3DMaterial::initialize();
}
+43 -2
View File
@@ -93,6 +93,23 @@ CameraSnapshot s_cam_curr{};
view_class s_presentation_view_backup{};
int s_presentation_depth = 0;
struct InterpolationCallBackWork {
dusk::frame_interp::InterpolationCallBack pCallBack;
void* pUserWork;
};
std::vector<InterpolationCallBackWork> s_interpolationCallBackWork;
void set_enabled(bool enabled) {
if (g_enabled == enabled)
return;
g_enabled = enabled;
if (!g_enabled)
s_interpolationCallBackWork.clear();
}
void copy_view_to_snap(CameraSnapshot* dst, const view_class& v) {
dst->eye = v.lookat.eye;
dst->center = v.lookat.center;
@@ -312,10 +329,14 @@ void clear_replacements() {
namespace dusk::frame_interp {
void ensure_initialized() {
g_enabled = getSettings().game.enableFrameInterpolation;
set_enabled(getSettings().game.enableFrameInterpolation);
s_initialized = true;
}
bool is_enabled() {
return g_enabled;
}
void begin_record() {
ensure_initialized();
@@ -486,6 +507,24 @@ void record_camera(::camera_process_class* cam, int camera_id) {
#endif
}
static void run_interpolation_callbacks() {
for (size_t i = 0; i < s_interpolationCallBackWork.size(); i++) {
auto const& work = s_interpolationCallBackWork[i];
work.pCallBack(work.pUserWork);
}
}
void reset_interpolation_callbacks() {
s_interpolationCallBackWork.clear();
}
void add_interpolation_callback(InterpolationCallBack pCallBack, void* pUserWork) {
if (!is_enabled() || s_presentation_depth > 0)
return;
s_interpolationCallBackWork.emplace_back(pCallBack, pUserWork);
}
void begin_presentation_camera() {
ensure_initialized();
if (!g_enabled) {
@@ -589,12 +628,14 @@ void begin_presentation_camera() {
}
mDoLib_clipper::setup(view->fovy, view->aspect, view->near_, far_);
#if WIDESCREEN_SUPPORT
mDoGph_gInf_c::offWideZoom();
#endif
s_presentation_depth = 1;
run_interpolation_callbacks();
}
void end_presentation_camera() {
+1
View File
@@ -235,6 +235,7 @@ void main01(void) {
if (pacing.is_interpolating) {
if (pacing.do_sim_tick) {
dusk::frame_interp::reset_interpolation_callbacks();
dusk::frame_interp::set_ui_tick_pending(true);
mDoCPd_c::read();
dusk::gyro::read(pacing.sim_pace);