Line Of Sight

by DarkCampainger
Determine if two atoms have a clear line of sight between them [More]
To download this library for your Linux/Mac installation, enter this on your command line:

DreamDownload byond://DarkCampainger.LineOfSightLibrary##version=4

Emulator users, in the BYOND pager go to File | Open Location and enter this URL:

byond://DarkCampainger.LineOfSightLibrary##version=4

321 downloads
Version 1.3 (Reorganization)
Date added: Aug 12 2012
Last updated: Sep 25 2012
8 fans
In the above pictures, the black squares are mobs, the dark grey tiles are opaque walls, and the red areas represent the mobs' field of vision based on line-of-sight calculations. Blue areas represent overlap.


/* *********************************************************************

.__ .__ ____ _______.__ .__ __
| | |__| ___ ____ _____/ ___\ / ___/|__| ____ | |___/ |_
| | | |/ \_/ __ \ / _ \ _\ \___ \ | |/ ___\| | \ __\
| |___| | | \ ___/ ( <_> ) | / \| / /_/ > Y \ |
|_____ \__|__| /\___ > \____/|__| /_____ /|__\___ /|___| /__|
\/ \/ \/ \/ /_____/ \/

Created by David "DarkCampainger" Braun

Released under the Unlicense (see _Unlicense.dm)

Version 1.3 - September 25, 2012

Please see 'Demo/Demo.dm' for the example usage

*/
//////////////////////////////////////////////////////////////////////


## Summary
#######################

"' This library includes a InLineOfSight() process which allows you to
"' to determine if two atoms have a clear line of sight between one
"' another. It works by casting a line between the objects and
"' searching along it for opaque tiles.
"'
"' It's important to note that although the start and end points of the
"' line consider the pixel-based center of each object, the actual
"' search for opaque objects only considers full tiles.
"'
"' The library also integrates range and field-of-view limitations to
"' create more realistic sight lines.
"'

## Reference
#######################

/LineOfSight (/datum)

"' This is the container type for the library. All global procs and
"' vars are defined under it. You can access an instance of it via
"' the global variable [LOS], for example: [LOS.InLineOfSight(...)]
"'
// Variables:
"'
:: iconSizeWidth (number)
:: iconSizeHeight (number)
"' The width and height of each tile as parsed from the
"' world's icon_size variable
"'
// Procedures:
"'
:: inLineOfSight(atom/source, atom/target, \
:: sourceCenterX=null, sourceCenterY=null, \
:: targetCenterX=null, targetCenterY=null, \
:: parameter="opacity", checkContents=FALSE, \
:: range=null, fov=null, fovX=null, fovY=null, \
:: fovCos=null)
"'
"[ source: atom to calculate sight-line for (required)
"[ target: atom to test against (required)
"'
"[ sourceCenterX, Manually specify centers of atoms in pixels,
"[ sourceCenterY, as offsets from the bottom-left corner.
"[ targetCenterX, Do NOT include step_x/y in this value.
"[ targetCenterY: Example values for 32x32 icons:
"[ Bottom-left: (0,0)
"[ Top-right: (32,32)
"[ Center: (16,16)
"[
"[ If not specified, the centers will be
"[ determined from the bounding boxes.
"'
"[ parameter: Manually specify variable to test if line of
"[ sight penetrates a tile. Default is "opacity".
"[ Must be a variable that all turfs have. If
"[ 'checkContents' is true, must also be a
"[ variable that all atoms have.
"'
"[ checkContents: Set to true value to also check the contents
"[ of each turf along the line for atoms that
"[ may block it. Defaults to false, which means
"[ only the turfs parameter is checked. Note
"[ that even if this is true, contents are
"[ treated as affecting the whole tile and their
"[ step offsets and bounds are not considered.
"'
"[ range: Restrict the sight to a max range in pixels.
"'
"[ fov: Limits the distance that the target can
"[ be from the source sight vector, as it is
"[ specified by the fovX and fovY arguments.
"[ Note that this is half the size of the total
"[ viewing arc, so to be able to see in 180
"[ degrees, fov should be set to 90.
"'
"[ fovCos: As an optimization, you can precompute the
"[ cosine of the desired FOV and pass it via
"[ this argument instead of the 'fov' argument.
"'
"[ fovX / fovY: Specifies the direction of the source atom
"[ sight vector for FOV. If both fovX and
"[ fovY are null, it defaults to the source
"[ dir. If fovX is set and fovY is null, fovX
"[ is expected to be a directional flag
"[ (NORTH, SOUTH, ect). If both fovX and fovY
"[ are set, they are expected to define a
"[ vector (does not need to be normalized)
"'
"[ Returns: True if there is a clear line of sight from
"[ the source to the target. False otherwise.
"'
"' This process returns whether or not one atom has a clear
"' line of sight to another, optionally taking into account
"' the atom's field-of-view and vision range.
"'
:: getCenterPixelX(atom/A, includeStep=FALSE)
:: getCenterPixelY(atom/A, includeStep=FALSE)
"'
"[ A: The atom to calculate the center of
"'
"[ includeStep: Whether to include step_x/y in the result
"'
"[ Returns: The relative pixel offset of the center of
"[ the atom. For a 32x32 icon_size, the center
"[ will be (16,16) for a full bounding box.
"'
"' This utility process determines the relative pixel center
"' of an atom, taking into account its bounding box.
"'
:: getAbsoluteTileX(atom/A, customCenterX=null)
:: getAbsoluteTileY(atom/A, customCenterY=null)
"'
"[ A: The atom to calculate the absolute center of
"'
"[ customCenterX, Pass the center of the atom, instead of
"[ customCenterY: calculating it based on the bounding box
"'
"[ Returns: The relative pixel offset of the center of
"[ the atom. For a 32x32 icon_size, the center
"[ will be (16,16) for a full bounding box.
"'
"' This utility process determines the absolute tile position of
"' of an atom's center, taking into account its bounding box.
"'

## Version History
#######################

Version 1.3 / September 25, 2012

Library is now released under the Unlicense
Library data organized under /LineOfSight parent type
Added getCenterPixelX/Y() and getAbsoluteTileX/Y() utilities
InLineOfSight() has been renamed inLineOfSight()
inLineOfSight() now has fovCos argument
Fixed bug with fovY argument
Fixed bug with targetCenterX/Y arguments
Optimized FOV calculation (Thanks Lummox JR!)
Shortened and reformatted documentation
Improved demo

Version 1.2 / September 20, 2012

Added field of view and range constraints
Improved accuracy and handling of floating-point error
Adjusted demo so that the intended usage is more clear

Version 1.1 / August 13, 2012

Improved handling of opaque source and target tiles

Version 1.0 / August 13, 2012

Initial Release

Comments

Delta0Zero2: (Jul 25 2016, 1:42 am)
This is incredible!
-._.DreamBunny._.-: (Jul 5 2013, 7:53 pm)
I would love to use this for a game but it's too complicated you're coding can you make a simpler one or just send me one that is more simpled?
DarkCampainger: (Sep 16 2012, 8:09 am)
It's not meant to work like that. That's just a visualization included with the demo of the areas that would register as "in sight". In an actual game, that level of testing probably wouldn't perform too well. I've got an update I'll release probably later today that shows this better (it'll also have FOV and range built-in).
Bumblemore: (Sep 16 2012, 4:27 am)
can somebody edit this so the area around is dark and the line of sight is the only seeable thing?
SuperAntx: (Aug 18 2012, 5:42 pm)
Oh shit, this is cool as fuck. Nice job.