atmo 29 Posted April 20, 2019 Hi all, I've made a script to check the visibility of positions on the map. An example mission is here I hope I've done this right. 1 min Video And the code is here for those interested. /* CheckVisibility.sqf Author: Atmo Date: April 2019 Version: 1.0 Params : None Description: Checks the visibility of a 2000m square around the position left clicked on in the map. It checks a position 2m off the ground to the test position. Checks 30m squares - could change the size if you want but it could get intensive... Running script toggles activation of the eventHandlers so running once turns it on, running it again stops it. Use: single left click (Default mode): - shows non-visible areas as red pressing 'alt' and left clicking: - shows visible areas in green. Some examples: 1) From an action in an players init this addAction ["Check Visibility", "fn_CheckVisibility.sqf"]; 2) compile the function from the description.ext and then call it - I'll let you do that. */ if (!hasInterface) exitWith {["fn_CheckVisibility only runs on client"] call BIS_fnc_error}; // Every time script runs toggle eventHandlers private _EHs = missionNamespace getVariable [format["BIS_stackedEventHandlers_%1", "onMapSingleClick"], []]; if (_EHs findIf {(_x select 0) isEqualTo "Atmo_CV_EH"} == -1) then { ["Atmo_CV_EH", "onMapSingleClick", { // _pos, _shift, _alt are parameters of onMapSingleClick EH private _positions = []; // Array of positions tested private _size = 30; // Size of squares (if you change this also change _size in Draw EH) // Set the drawing method for the ctrlEventHandler missionNamespace setVariable ["Atmo_CV_mode", _alt]; // Convert _pos to ASL + 2m private _origin = (ATLToASL _pos) vectorAdd [0,0, 2]; for "_i" from -1000 to 1000 step _size do { for "_j" from -1000 to 1000 step _size do { _testPos = ATLToASL (_pos VectorAdd [_i, _j, 2]); _visibility = 0; // Cast a line to the point _intersectPos = lineIntersectsSurfaces [_origin, _testpos, player, objNull, true, 1, "VIEW", "FIRE"] select 0 select 0; if (isNil "_intersectPos") then { // It didn't intersect anything = it is visible _visibility = 1; } else { // The line hit something - is thing it hit in the area we are testing? if (_intersectPos inArea [_testPos, _size, _size, 0, true, -1]) then {_visibility = 1}; }; if (_alt) then { if (_visibility == 1) then { _positions append [_testPos]; }; } else { if (_visibility == 0) then { _positions append [_testPos]; }; }; }; }; missionNamespace setVariable ["Atmo_CV_Positions", _positions]; }] call BIS_fnc_addStackedEventHandler; // Add draw EventHandler to the map display - Oooo, er, should I use displayAddEventHandler? private _map = findDisplay 12 displayCtrl 51; private _id = _map ctrlAddEventHandler ["Draw", { params ["_control"]; // Get the mode of drawing - false: 'alt' wasn't pressed show not visible in red, true: show visible in green private _mode = missionNamespace getVariable ["Atmo_CV_mode", false]; private _rgba = [[0.5,0,0,0.8], [0,0.5,0,0.8]] select _mode; private _positions = missionNamespace getVariable ["Atmo_CV_Positions", []]; private _size = 15; { _control drawRectangle [_x, _size, _size, 0, _rgba, "#(rgb,1,1,1)color(1,1,1,1)"] ; } forEach _positions; private _pos = missionNamespace getVariable ["Atmo_CV_cursorPos", [0,0]]; _control drawIcon ["#(rgb,1,1,1)color(1,1,1,1)", [0,0,1,1], _pos, 0, 0, 0, "Check Visibility (click +/- alt)"]; }]; // Save the EH id missionNamespace setVariable ["Atmo_CV_DrawEHid", _id]; _id = _map ctrlAddEventHandler ["MouseMoving", { params ["_control", "_xPos", "_yPos", "_mouseOver"]; _pos = _control posScreenToWorld [_xPos + 0.1, _yPos - 0.1]; missionNamespace setVariable ["Atmo_CV_cursorPos", _pos]; }]; // Save the EH id missionNamespace setVariable ["Atmo_CV_MouseMoveEHid", _id]; } else { // The event handler is already there - delete them all //remove onMapSingleClick private _removed = ["Atmo_CV_EH", "onMapSingleClick"] call BIS_fnc_removeStackedEventHandler; // remove Draw eventHandler on the map private _map = findDisplay 12 displayCtrl 51; _map ctrlRemoveEventHandler ["Draw", missionNamespace getVariable "Atmo_CV_DrawEHid"]; _map ctrlRemoveEventHandler ["MouseMoving", missionNamespace getVariable "Atmo_CV_MouseMoveEHid"]; missionNamespace setVariable ["Atmo_CV_Positions", []]; }; (Nice) Comments appreciated - scripters let me know if you see any glaring errors! Atmo 5 Share this post Link to post Share on other sites
sarogahtyp 1109 Posted April 21, 2019 neat and looks like it could work well. idk if lineIntersect is faster than checkVisibility. what i know is that checkVisibility is newer. You could test it against each other. Share this post Link to post Share on other sites
Tankbuster 1747 Posted April 21, 2019 1 hour ago, sarogahtyp said: neat and looks like it could work well. idk if lineIntersect is faster than checkVisibility. what i know is that checkVisibility is newer. You could test it against each other. There's not much between them in terms of pure performance. Lineintersects is limited to 1000m and doesn't work underwater and returns a bool. Checkvisibilty isn't restricted like this but is affected by smoke and rain. At longer ranges and in more complicated scenes, Checkvisibilty is slower, but the difference is around the order of 0.0x milliseconds. 1 Share this post Link to post Share on other sites
atmo 29 Posted April 21, 2019 I used lineIntersectsSurfaces because it returns a position, so if the ray hits something within the area you are testing you can say it is visible. It seems pretty fast altogether. The frame rate drop comes with more drawRectangles…. Atmo Share this post Link to post Share on other sites
phronk 898 Posted April 21, 2019 I really like it! Reminds me of the line-of-sight checks in sims like Steelbeasts or Steel Armor: Blaze of War. Share this post Link to post Share on other sites
killzone_kid 1332 Posted April 21, 2019 On 4/20/2019 at 1:59 PM, atmo said: let me know if you see any glaring errors! Just one, couldn’t find checkVisibility command anywhere in code 😉 3 Share this post Link to post Share on other sites
atmo 29 Posted April 22, 2019 Thank you @phronk. I was inspired by the Line of Sight tool in Steel Division. It's very cool. I'll keep tweaking it to see it I can come up with a faster method or visually more appealing. I would like to be able to create 'blobs' with smooth filled curves but I notice you can't fill a drawPolygon so it's triangles or similar it seems. Unless anyone has any ideas how to do that, I would be interested. Share this post Link to post Share on other sites