precomputed shade wall lighting

This commit is contained in:
anton.gurov
2019-10-31 16:30:12 +03:00
parent 1c44dd0885
commit cddc5fa70f
3 changed files with 58 additions and 83 deletions

View File

@ -9,56 +9,7 @@ import (
"sort"
)
/*
Why am I here? Well, I just don't know what to call it - I'm sure it's an established method, and I'm aware there are probably optimisations to be had. I thought if I roughed out the algorithm here, the r/roguelikedev community would surely be able to help! I haven't included optimisations here, but if anyone wants them I got 'em :)
Method
Beforehand
List the cells in your largest-possible FOV, storing X and Y values relative to the center.
Store the distance from the center for each cell, and sort the list by this in ascending order.
Store the range of angles occluded by each cell in this list, in clockwise order as absolute integers only.
Create a 360-char string of 0s called EmptyShade, and a 360-char string of 1s called FullShade
Runtime
Store two strings CurrentShade and NextShade
Set CurrentShade to EmptyShade to start.
While CurrentShade =/= FullShade: step through the Cell List:
If the distance to the current cell is not equal to the previous distance checked then replace the contents of the CurrentShade variable with the contents of the NextShade variable.
If the tested cell is opaque for each angle in the range occluded by the cell, place a 1 at the position determined by angle%360 in the NextShade string.
For each angle in the range occluded by the cell, add 1 to the shade value for that cell for each 0 encountered at the position determined by angle%360 in the CurrentShade string.
Notes
Benefits
No messing around with octants
Highly efficient - each cell is only visited once, and checks within that cell are rare. It performs as fast as any other LOS I've tried but with more options
Human-readable - code and output are highly legible, making it very easy to work with
Flexible - I'm using it for FOV, LOS, renderer, and lighting. Each process is calling the same function, within which flags control how much data is evaluated and output. It only uses the data it needs to in the context where its needed so monsters that need a list of things they can see only check if a cell is visible or not, and dont bother calculating how much visibility they have there. This cuts processing dramatically.
Other links
cfov by Konstantin Stupnik on RogueTemple
Pre-Computed Visiblity Trees on RogueBasin
/r/roguelikedev FAQ Friday on FOV which kicked off this train of thought
/u/pnjeffries on his FOV algorithm which inspired this one
Adam Milazzo's FOV Method Roundup where a similar method described as 'permissive' is detailed
*/
//Incomplete implementation of permissive algo with precomputation
var NotFoundCell = errors.New("Cell not found")