mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-07-12 13:35:35 -04:00
Frame interp: Stable keying for simple shadows
This commit is contained in:
@@ -34,6 +34,7 @@ void open_child(const void* key, int32_t id);
|
||||
void close_child();
|
||||
void record_camera(::camera_process_class* cam, int camera_id);
|
||||
void record_final_mtx_raw(const Mtx* dest, const Mtx src);
|
||||
void record_final_mtx_raw_tagged(const Mtx* dest, const Mtx src, uint64_t stable_tag);
|
||||
|
||||
bool lookup_replacement(const void* source, Mtx out);
|
||||
bool lookup_concat_replacement(const void* lhs, const void* rhs, Mtx out);
|
||||
@@ -41,6 +42,7 @@ bool lookup_concat_replacement(const void* lhs, const void* rhs, Mtx out);
|
||||
void camera_eye_from_view_mtx(MtxP view_mtx, cXyz* o_eye);
|
||||
bool build_star_view(Mtx o_view, Mtx o_cam_billboard_base, cXyz* o_anchor_eye, float* o_fovy);
|
||||
|
||||
uint64_t alloc_simple_shadow_pair_base();
|
||||
} // namespace frame_interp
|
||||
} // namespace dusk
|
||||
#endif
|
||||
|
||||
+19
-12
@@ -1,28 +1,29 @@
|
||||
#include "d/dolzel.h" // IWYU pragma: keep
|
||||
|
||||
#include <cstdio>
|
||||
#include "JSystem/J2DGraph/J2DAnimation.h"
|
||||
#include "JSystem/J2DGraph/J2DGrafContext.h"
|
||||
#include "JSystem/J2DGraph/J2DScreen.h"
|
||||
#include "JSystem/J3DGraphBase/J3DDrawBuffer.h"
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "SSystem/SComponent/c_bg_s_shdw_draw.h"
|
||||
#include "SSystem/SComponent/c_math.h"
|
||||
#include "d/d_com_inf_game.h"
|
||||
#include "d/d_drawlist.h"
|
||||
|
||||
#include <typeindex>
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "client/TracyScoped.hpp"
|
||||
#include "d/d_s_play.h"
|
||||
#include "dusk/frame_interpolation.h"
|
||||
#include "dusk/gx_helper.h"
|
||||
#include "dusk/logging.h"
|
||||
#include "m_Do/m_Do_graphic.h"
|
||||
#include "m_Do/m_Do_lib.h"
|
||||
#include "m_Do/m_Do_mtx.h"
|
||||
|
||||
#if TARGET_PC
|
||||
#include <cstdio>
|
||||
#include <typeindex>
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "client/TracyScoped.hpp"
|
||||
#include "dusk/frame_interpolation.h"
|
||||
#include "dusk/gx_helper.h"
|
||||
#include "dusk/logging.h"
|
||||
#endif
|
||||
|
||||
class dDlst_2Dm_c {
|
||||
public:
|
||||
virtual void draw();
|
||||
@@ -1432,8 +1433,14 @@ void dDlst_shadowSimple_c::set(cXyz* param_0, f32 param_1, f32 param_2, cXyz* pa
|
||||
mDoMtx_stack_c::scaleM(param_2, 1.0f, param_2 * param_5);
|
||||
cMtx_concat(j3dSys.getViewMtx(), mDoMtx_stack_c::get(), mMtx);
|
||||
#ifdef TARGET_PC
|
||||
dusk::frame_interp::record_final_mtx_raw(&mVolumeMtx, mVolumeMtx);
|
||||
dusk::frame_interp::record_final_mtx_raw(&mMtx, mMtx);
|
||||
const uint64_t shadow_tag_base = dusk::frame_interp::alloc_simple_shadow_pair_base();
|
||||
if (shadow_tag_base != 0) {
|
||||
dusk::frame_interp::record_final_mtx_raw_tagged(&mVolumeMtx, mVolumeMtx, shadow_tag_base);
|
||||
dusk::frame_interp::record_final_mtx_raw_tagged(&mMtx, mMtx, shadow_tag_base + 1u);
|
||||
} else {
|
||||
dusk::frame_interp::record_final_mtx_raw(&mVolumeMtx, mVolumeMtx);
|
||||
dusk::frame_interp::record_final_mtx_raw(&mMtx, mMtx);
|
||||
}
|
||||
#endif
|
||||
mpTexObj = param_6;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ struct Data {
|
||||
size_t child_index = 0;
|
||||
Mtx matrix{};
|
||||
const Mtx* dest = nullptr;
|
||||
uint64_t stable_tag = 0;
|
||||
};
|
||||
|
||||
struct Path;
|
||||
@@ -46,6 +47,8 @@ struct Path {
|
||||
std::vector<ChildBucket> children;
|
||||
std::vector<OpBucket> ops;
|
||||
std::vector<std::pair<Op, size_t>> items;
|
||||
Label draw_scope{};
|
||||
uint32_t simple_shadow_pair_seq = 0;
|
||||
};
|
||||
|
||||
struct Recording {
|
||||
@@ -57,6 +60,7 @@ struct MatrixValue {
|
||||
};
|
||||
|
||||
using FinalMtxLookup = std::unordered_map<const Mtx*, const Data*>;
|
||||
using FinalMtxLookupTagged = std::unordered_map<uint64_t, const Data*>;
|
||||
|
||||
bool s_initialized = false;
|
||||
|
||||
@@ -142,8 +146,9 @@ const OpBucket* find_op_bucket(const Path& path, Op op) {
|
||||
return &*it;
|
||||
}
|
||||
|
||||
void build_final_mtx_lookup(const Path& path, FinalMtxLookup& lookup) {
|
||||
lookup.clear();
|
||||
void build_final_mtx_lookups(const Path& path, FinalMtxLookup& dest_lookup, FinalMtxLookupTagged& tag_lookup) {
|
||||
dest_lookup.clear();
|
||||
tag_lookup.clear();
|
||||
|
||||
const OpBucket* bucket = find_op_bucket(path, Op::FinalMtx);
|
||||
if (bucket == nullptr) {
|
||||
@@ -151,10 +156,12 @@ void build_final_mtx_lookup(const Path& path, FinalMtxLookup& lookup) {
|
||||
}
|
||||
|
||||
for (const Data& data : bucket->values) {
|
||||
if (data.dest == nullptr) {
|
||||
continue;
|
||||
if (data.dest != nullptr) {
|
||||
dest_lookup[data.dest] = &data;
|
||||
}
|
||||
if (data.stable_tag != 0) {
|
||||
tag_lookup[data.stable_tag] = &data;
|
||||
}
|
||||
lookup[data.dest] = &data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,7 +208,8 @@ void store_replacement(const Data& old_data, const Data& new_data, float step) {
|
||||
|
||||
void interpolate_branch(const Path& old_path, const Path& new_path, float step) {
|
||||
FinalMtxLookup old_final_mtx_lookup;
|
||||
build_final_mtx_lookup(old_path, old_final_mtx_lookup);
|
||||
FinalMtxLookupTagged old_final_mtx_lookup_tagged;
|
||||
build_final_mtx_lookups(old_path, old_final_mtx_lookup, old_final_mtx_lookup_tagged);
|
||||
|
||||
for (const auto& item : new_path.items) {
|
||||
const Op op = item.first;
|
||||
@@ -230,7 +238,17 @@ void interpolate_branch(const Path& old_path, const Path& new_path, float step)
|
||||
}
|
||||
|
||||
const Data* indexed_old_data = find_matching_data(old_path, op, index);
|
||||
const Data* old_data = op == Op::FinalMtx ? find_matching_final_mtx(old_final_mtx_lookup, *new_data) : indexed_old_data;
|
||||
const Data* old_data = nullptr;
|
||||
if (op == Op::FinalMtx) {
|
||||
if (new_data->stable_tag != 0) {
|
||||
const auto it = old_final_mtx_lookup_tagged.find(new_data->stable_tag);
|
||||
old_data = it != old_final_mtx_lookup_tagged.end() ? it->second : nullptr;
|
||||
} else {
|
||||
old_data = find_matching_final_mtx(old_final_mtx_lookup, *new_data);
|
||||
}
|
||||
} else {
|
||||
old_data = indexed_old_data;
|
||||
}
|
||||
if (op == Op::FinalMtx) {
|
||||
store_replacement(old_data != nullptr ? *old_data : *new_data, *new_data, step);
|
||||
}
|
||||
@@ -370,7 +388,9 @@ void open_child(const void* key, int32_t id) {
|
||||
data.child_label = label;
|
||||
data.child_index = siblings.size();
|
||||
siblings.emplace_back(std::make_unique<Path>());
|
||||
g_current_path.push_back(siblings.back().get());
|
||||
Path* const child = siblings.back().get();
|
||||
child->draw_scope = label;
|
||||
g_current_path.push_back(child);
|
||||
}
|
||||
|
||||
void close_child() {
|
||||
@@ -388,6 +408,18 @@ void record_final_mtx_raw(const Mtx* dest, const Mtx src) {
|
||||
|
||||
Data& data = append_op(Op::FinalMtx);
|
||||
data.dest = dest;
|
||||
data.stable_tag = 0;
|
||||
copy_matrix(src, data.matrix);
|
||||
}
|
||||
|
||||
void record_final_mtx_raw_tagged(const Mtx* dest, const Mtx src, uint64_t stable_tag) {
|
||||
if (!s_initialized || !g_recording || dest == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
Data& data = append_op(Op::FinalMtx);
|
||||
data.dest = dest;
|
||||
data.stable_tag = stable_tag;
|
||||
copy_matrix(src, data.matrix);
|
||||
}
|
||||
|
||||
@@ -501,4 +533,20 @@ bool build_star_view(Mtx o_view, Mtx o_cam_billboard_base, cXyz* o_anchor_eye, f
|
||||
*o_fovy = s_star_prev.fovy + (s_star_curr.fovy - s_star_prev.fovy) * step;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t alloc_simple_shadow_pair_base() {
|
||||
if (!s_initialized || !g_recording || g_current_path.size() <= 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Path* const scope = g_current_path.back();
|
||||
const uint64_t h = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(scope->draw_scope.key));
|
||||
const uint32_t lo = scope->simple_shadow_pair_seq;
|
||||
scope->simple_shadow_pair_seq += 2;
|
||||
uint64_t tag0 = (h << 17) ^ (static_cast<uint64_t>(lo) << 1u);
|
||||
if (tag0 == 0) {
|
||||
tag0 = 2;
|
||||
}
|
||||
return tag0;
|
||||
}
|
||||
} // namespace dusk::frame_interp
|
||||
|
||||
Reference in New Issue
Block a user