Skip to content

Commit

Permalink
Merge pull request #72669 from SurFlurer/shadowcasting
Browse files Browse the repository at this point in the history
Fix shadowcasting for weather with sight_penalty != 1.0
  • Loading branch information
Maleclypse committed Mar 29, 2024
2 parents b7a21d4 + 8130295 commit 2ccd61c
Showing 1 changed file with 26 additions and 5 deletions.
31 changes: 26 additions & 5 deletions src/shadowcasting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,17 @@ template<typename T>
struct span {
span( const slope &s_major, const slope &e_major,
const slope &s_minor, const slope &e_minor,
const T &value, bool skip_first_row = false ) :
const T &value, bool skip_first_row = false, bool skip_first_column = false ) :
start_major( s_major ), end_major( e_major ), start_minor( s_minor ), end_minor( e_minor ),
cumulative_value( value ), skip_first_row( skip_first_row ) {}
cumulative_value( value ), skip_first_row( skip_first_row ),
skip_first_column( skip_first_column ) {}
slope start_major;
slope end_major;
slope start_minor;
slope end_minor;
T cumulative_value;
bool skip_first_row;
bool skip_first_column;
};

/**
Expand Down Expand Up @@ -98,35 +100,47 @@ static void split_span( cata::list<span<T>> &spans,
// If check returns false, A and B are opaque and have no spans.
if( is_transparent( current_transparency, last_intensity ) ) {
// Emit the A span if present, placing it before the current span in the list
// If the parent span is to skip the first column, inherit it.
if( trailing_edge_major > this_span->start_major ) {
spans.emplace( this_span,
this_span->start_major, trailing_edge_major,
this_span->start_minor, this_span->end_minor,
next_cumulative_transparency );
next_cumulative_transparency, false, this_span->skip_first_column );
}

// Emit the B span if present, placing it before the current span in the list
// If the parent span is to skip the first column, inherit it.
if( trailing_edge_minor > this_span->start_minor ) {
spans.emplace( this_span,
std::max( this_span->start_major, trailing_edge_major ),
std::min( this_span->end_major, leading_edge_major ),
this_span->start_minor, trailing_edge_minor,
next_cumulative_transparency );
next_cumulative_transparency, false, this_span->skip_first_column );
}

// Overwrite new_start_minor since previous tile is transparent.
new_start_minor = trailing_edge_minor;
}

// Emit the D span if present, placing it after the current span in the list
// If the parent span is to skip the first column, inherit it.
if( leading_edge_major < this_span->end_major ) {
// Pass true to the span constructor to set skip_first_row to true
// This prevents the same row we are currently checking being checked by the
// new D span
spans.emplace( std::next( this_span ),
leading_edge_major, this_span->end_major,
this_span->start_minor, this_span->end_minor,
this_span->cumulative_value, true );
this_span->cumulative_value, true, this_span->skip_first_column );
}
// If the split is due to two transparent squares with different transparency, set skip_first_column to true
// This prevents the last column of B span being checked by the new C span
if( is_transparent( current_transparency, last_intensity ) &&
is_transparent( new_transparency, last_intensity ) ) {
this_span->skip_first_column = true;
} else {
this_span->skip_first_column = false;

}

// Truncate this_span to the current block.
Expand Down Expand Up @@ -245,6 +259,13 @@ void cast_horizontal_zlight_segment(
// Current tile comes before the span we're considering, advance to the next tile.
continue;
}
if( this_span->skip_first_column && this_span->start_minor == leading_edge_minor ) {
// If the split is due to two transparent squares with different transparency,
// We want to check the blocks that are likely to cause split only in B,
// rather than in B & C, which can lead to performance hit.
continue;
}

if( this_span->end_minor < trailing_edge_minor ) {
// Current tile is after the span we're considering, continue to next row.
break;
Expand Down

0 comments on commit 2ccd61c

Please sign in to comment.