@@ -42,6 +42,76 @@ std::shared_ptr<Graphics>& Graphics::get() {
42
42
return mod;
43
43
}
44
44
45
+ std::optional<std::string> Graphics::on_initialize () {
46
+ #if TDB_VER >= 69
47
+ const auto raytracing_enum = sdk::find_type_definition (" via.render.ExperimentalRayTrace.Raytracing" );
48
+
49
+ if (raytracing_enum == nullptr ) {
50
+ return Mod::on_initialize (); // OK
51
+ }
52
+
53
+ s_ray_trace_type.clear ();
54
+ s_ray_trace_type.push_back (" Disabled" );
55
+
56
+ s_ray_trace_type.resize (raytracing_enum->get_fields ().size () + 1 );
57
+
58
+ int32_t actual_size = 1 ;
59
+
60
+ for (auto f : raytracing_enum->get_fields ()) {
61
+ const auto field_flags = f->get_flags ();
62
+
63
+ if ((field_flags & (uint16_t )via::clr::FieldFlag::Static) != 0 && (field_flags & (uint16_t )via::clr::FieldFlag::Literal) != 0 ) {
64
+ auto raw_data = f->get_data_raw (nullptr , true );
65
+ int64_t enum_data = 0 ;
66
+
67
+ switch (raytracing_enum->get_valuetype_size ()) {
68
+ case 1 :
69
+ enum_data = (int64_t )*(int8_t *)raw_data;
70
+ break ;
71
+ case 2 :
72
+ enum_data = (int64_t )*(int16_t *)raw_data;
73
+ break ;
74
+ case 4 :
75
+ enum_data = (int64_t )*(int32_t *)raw_data;
76
+ break ;
77
+ case 8 :
78
+ enum_data = *(int64_t *)raw_data;
79
+ break ;
80
+ default :
81
+ spdlog::error (" Unknown enum size: {}" , raytracing_enum->get_valuetype_size ());
82
+ break ;
83
+ }
84
+
85
+ if (enum_data < 0 || enum_data + 1 >= s_ray_trace_type.size ()) {
86
+ spdlog::error (" Invalid enum data: {} {}" , f->get_name (), enum_data);
87
+ continue ;
88
+ }
89
+
90
+ auto unfriendly_name = std::string{f->get_name ()};
91
+
92
+ // Format into a friendly name (Spacing between words)
93
+ for (size_t i = 1 ; i < unfriendly_name.size (); ++i) {
94
+ if (unfriendly_name[i] >= ' A' && unfriendly_name[i] <= ' Z' ) {
95
+ unfriendly_name.insert (i, " " );
96
+ i++;
97
+ }
98
+ }
99
+
100
+ s_ray_trace_type[enum_data + 1 ] = unfriendly_name;
101
+ ++actual_size;
102
+ }
103
+ }
104
+
105
+ s_ray_trace_type.resize (actual_size);
106
+ m_ray_trace_type->recreate_options (s_ray_trace_type);
107
+ m_ray_trace_clone_type_pre->recreate_options (s_ray_trace_type);
108
+ m_ray_trace_clone_type_post->recreate_options (s_ray_trace_type);
109
+ m_ray_trace_clone_type_true->recreate_options (s_ray_trace_type);
110
+ #endif
111
+
112
+ return Mod::on_initialize (); // OK
113
+ }
114
+
45
115
void Graphics::on_config_load (const utility::Config& cfg) {
46
116
for (IModValue& option : m_options) {
47
117
option.config_load (cfg);
@@ -126,6 +196,11 @@ void Graphics::on_draw_ui() {
126
196
127
197
if (m_ray_tracing_tweaks->value ()) {
128
198
m_ray_trace_disable_raster_shadows->draw (" Disable Raster Shadows (with PT)" );
199
+ m_ray_trace_always_recreate_rt_component->draw (" Always Recreate RT Component" );
200
+ // Description of the above option
201
+ if (ImGui::IsItemHovered ()) {
202
+ ImGui::SetTooltip (" Recreates the RT component. Useful if Ray Tracing Tweaks is not working." );
203
+ }
129
204
m_ray_trace_type->draw (" Ray Trace Type" );
130
205
131
206
const auto clone_tooltip =
@@ -152,9 +227,7 @@ void Graphics::on_draw_ui() {
152
227
}
153
228
154
229
// Hybrid/pure
155
- if (m_ray_trace_type->value () == (int32_t )RayTraceType::Hybrid || m_ray_trace_type->value () == (int32_t )RayTraceType::Pure
156
- || m_ray_trace_clone_type_true->value () == (int32_t )RayTraceType::Hybrid || m_ray_trace_clone_type_true->value () == (int32_t )RayTraceType::Pure)
157
- {
230
+ if (is_pt_type (m_ray_trace_type->value ()) || is_pt_type (m_ray_trace_clone_type_true->value ())) {
158
231
m_bounce_count->draw (" Bounce Count" );
159
232
m_samples_per_pixel->draw (" Samples Per Pixel" );
160
233
}
@@ -929,11 +1002,16 @@ void Graphics::setup_rt_component() {
929
1002
auto rt_component = utility::re_component::find<REComponent>(game_object->transform , rt_t ->get_type ());
930
1003
931
1004
// Attempt to create the component if it doesn't exist
932
- if (rt_component == nullptr ) {
1005
+ if (rt_component == nullptr || (m_ray_trace_always_recreate_rt_component->value () && m_rt_recreated_component.get () != (sdk::ManagedObject*)rt_component)) {
1006
+ if (rt_component != nullptr ) {
1007
+ sdk::call_object_func_easy<void *>(rt_component, " destroy" , rt_component);
1008
+ }
1009
+
933
1010
rt_component = sdk::call_object_func_easy<REComponent*>(game_object, " createComponent(System.Type)" , rt_t ->get_runtime_type ());
934
1011
935
1012
if (rt_component != nullptr ) {
936
1013
spdlog::info (" [Graphics] Successfully created new RT component @ {:x}" , (uintptr_t )rt_component);
1014
+ m_rt_recreated_component = (sdk::ManagedObject*)rt_component;
937
1015
}
938
1016
}
939
1017
@@ -946,7 +1024,7 @@ void Graphics::setup_rt_component() {
946
1024
m_rt_component = (sdk::ManagedObject*)rt_component;
947
1025
}
948
1026
949
- if (m_rt_cloned_component.get () == nullptr && m_ray_trace_clone_type_true->value () > ( int32_t )RayTraceType::Disabled ) {
1027
+ if (m_rt_cloned_component.get () == nullptr && m_ray_trace_clone_type_true->value () > 0 ) {
950
1028
m_rt_cloned_component = (sdk::ManagedObject*)rt_t ->create_instance_full (false );
951
1029
952
1030
if (m_rt_cloned_component.get () != nullptr ) {
@@ -986,11 +1064,13 @@ void Graphics::apply_ray_tracing_tweaks() {
986
1064
return ;
987
1065
}
988
1066
989
- if (set_RaytracingMode != nullptr && rt_type > (int32_t )RayTraceType::Disabled) {
990
- any_pt = any_pt || rt_type == (int32_t )RayTraceType::Pure;
1067
+ const auto is_pure_pt = is_pure_pt_type (rt_type);
1068
+
1069
+ if (set_RaytracingMode != nullptr && rt_type > 0 ) {
1070
+ any_pt = any_pt || is_pure_pt;
991
1071
set_RaytracingMode->call <void >(context, target, rt_type - 1 );
992
1072
993
- if (rt_type == ( int32_t )RayTraceType::Pure && m_ray_trace_disable_raster_shadows->value ()) {
1073
+ if (is_pure_pt && m_ray_trace_disable_raster_shadows->value ()) {
994
1074
if (get_DynamicShadowEnable != nullptr && set_DynamicShadowEnable != nullptr ) {
995
1075
const bool is_shadow_enabled = get_DynamicShadowEnable->call <bool >(context);
996
1076
@@ -1003,7 +1083,7 @@ void Graphics::apply_ray_tracing_tweaks() {
1003
1083
}
1004
1084
}
1005
1085
1006
- if (rt_type == ( int32_t )RayTraceType::Hybrid || rt_type == ( int32_t )RayTraceType::Pure) {
1086
+ if (is_pt_type (rt_type)) { // hybrid or any pure
1007
1087
if (setBounce != nullptr ) {
1008
1088
setBounce->call <void >(context, target, m_bounce_count->value ());
1009
1089
}
@@ -1034,7 +1114,7 @@ void* Graphics::rt_draw_hook(REComponent* rt, void* draw_context, void* r8, void
1034
1114
return og (rt, draw_context, r8, r9);
1035
1115
}
1036
1116
1037
- if (graphics->m_ray_tracing_tweaks ->value () && graphics->m_ray_trace_clone_type_true ->value () > ( int32_t )RayTraceType::Disabled ) {
1117
+ if (graphics->m_ray_tracing_tweaks ->value () && graphics->m_ray_trace_clone_type_true ->value () > 0 ) {
1038
1118
static std::recursive_mutex mtx{};
1039
1119
std::scoped_lock _{mtx};
1040
1120
@@ -1086,7 +1166,7 @@ void* Graphics::rt_draw_impl_hook(void* rt_impl, void* draw_context, void* r8, v
1086
1166
.unk = unk
1087
1167
};
1088
1168
1089
- if (graphics->m_ray_tracing_tweaks ->value () && graphics->m_ray_trace_clone_type_pre ->value () > ( int32_t )RayTraceType::Disabled ) {
1169
+ if (graphics->m_ray_tracing_tweaks ->value () && graphics->m_ray_trace_clone_type_pre ->value () > 0 ) {
1090
1170
ray_tracing_mode = graphics->m_ray_trace_clone_type_pre ->value () - 1 ;
1091
1171
og (rt_impl, draw_context, r8, r9, unk);
1092
1172
ray_tracing_mode = old_mode;
@@ -1097,7 +1177,7 @@ void* Graphics::rt_draw_impl_hook(void* rt_impl, void* draw_context, void* r8, v
1097
1177
result = og(rt_impl, draw_context, r8, r9, unk);
1098
1178
}*/
1099
1179
1100
- if (graphics->m_ray_tracing_tweaks ->value () && graphics->m_ray_trace_clone_type_post ->value () > ( int32_t )RayTraceType::Disabled ) {
1180
+ if (graphics->m_ray_tracing_tweaks ->value () && graphics->m_ray_trace_clone_type_post ->value () > 0 ) {
1101
1181
ray_tracing_mode = graphics->m_ray_trace_clone_type_post ->value () - 1 ;
1102
1182
og (rt_impl, draw_context, r8, r9, unk);
1103
1183
ray_tracing_mode = old_mode;
0 commit comments