Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 3D and map plotting tools #800

Draft
wants to merge 22 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions addons/plotting/$PBOPREFIX$
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x\zen\addons\plotting
39 changes: 39 additions & 0 deletions addons/plotting/CfgContext.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
class EGVAR(context_menu,actions) {
class Plots {
displayName = CSTRING(DisplayName);
icon = QPATHTOF(ui\ruler.paa);
statement = QUOTE(call FUNC(selectPosition));
args = "LINE";
priority = 15;

class MeasureDistance {
displayName = CSTRING(MeasureDistance);
icon = QPATHTOF(ui\ruler.paa);
statement = QUOTE(call FUNC(selectPosition));
args = "LINE";
};
class MeasureDistanceFromCamera {
displayName = CSTRING(MeasureDistanceFromCamera);
icon = QPATHTOF(ui\ruler.paa);
statement = QUOTE([ARR_2(_args,curatorCamera)] call FUNC(setActivePlot));
args = "LINE";
};
class MeasureRadius {
displayName = CSTRING(MeasureRadius);
icon = QPATHTOF(ui\radius.paa);
statement = QUOTE(call FUNC(selectPosition));
args = "RADIUS";
};
class MeasureOffset {
displayName = CSTRING(MeasureOffset);
icon = QPATHTOF(ui\cuboid.paa);
statement = QUOTE(call FUNC(selectPosition));
args = "RECTANGLE";
};
class ClearPlots {
displayName = CSTRING(ClearPlots);
icon = "A3\3den\Data\Displays\Display3DEN\PanelLeft\entityList_delete_ca.paa";
statement = QUOTE(call FUNC(clearPlots));
};
};
};
17 changes: 17 additions & 0 deletions addons/plotting/CfgEventHandlers.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class Extended_PreStart_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_preStart));
};
};

class Extended_PreInit_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_preInit));
};
};

class Extended_PostInit_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_postInit));
};
};
30 changes: 30 additions & 0 deletions addons/plotting/CfgFormatters.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
class GVAR(formatters) {
class Distance {
class Meter {
formatter = QUOTE(format [ARR_2('%1 m',_value toFixed 1)]);
priority = 100;
};
class Feet {
formatter = QUOTE(format [ARR_2('%1 ft',(_value * 3.281) toFixed 1)]);
priority = 90;
};
class Yards {
formatter = QUOTE(format [ARR_2('%1 yd',(_value * 1.094) toFixed 1)]);
priority = 80;
};
class Mile {
formatter = QUOTE(format [ARR_2('%1 mi',(_value / 1609.344) toFixed 2)]);
priority = 70;
};
Comment on lines +3 to +18
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these could be made more complex. For example, I don't think the decimal point is needed after 100 m and for any moving object it just flickers. Essentially, increase precision for small values, decrease for large ones.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea

};
class Azimuth {
class Degree {
formatter = QUOTE(format [ARR_2('%1°',_value toFixed 1)]);
priority = 100;
};
class NATOMil {
formatter = QUOTE(format [ARR_2('%1 mil',(_value * 17.7778) toFixed 0)]);
priority = 90;
};
};
};
16 changes: 16 additions & 0 deletions addons/plotting/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
PREP(addPlot);
PREP(clearPlots);
PREP(compileFormatters);
PREP(drawLine);
PREP(drawPlots);
PREP(drawRadius);
PREP(drawRectangle);
PREP(isPosInCylinder);
PREP(onDraw);
PREP(onDraw3D);
PREP(onKeyDown);
PREP(onLoad);
PREP(onMouseButtonDown);
PREP(onUnload);
PREP(selectPosition);
PREP(setActivePlot);
12 changes: 12 additions & 0 deletions addons/plotting/XEH_postInit.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include "script_component.hpp"

if (hasInterface) then {
// All plots ordered by creation time, last is newest
GVAR(plots) = [];

["zen_curatorDisplayLoaded", LINKFUNC(onLoad)] call CBA_fnc_addEventHandler;
["zen_curatorDisplayUnloaded", LINKFUNC(onUnload)] call CBA_fnc_addEventHandler;

[QGVAR(plotAdded), LINKFUNC(addPlot)] call CBA_fnc_addEventHandler;
[QGVAR(plotsCleared), LINKFUNC(clearPlots)] call CBA_fnc_addEventHandler;
};
28 changes: 28 additions & 0 deletions addons/plotting/XEH_preInit.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "script_component.hpp"

ADDON = false;

PREP_RECOMPILE_START;
#include "XEH_PREP.hpp"
PREP_RECOMPILE_END;

if (hasInterface) then {
GVAR(activePlot) = [];
GVAR(draw3DAdded) = false;

GVAR(plotTypes) = createHashMapFromArray [
["LINE", LINKFUNC(drawLine)],
["RADIUS", LINKFUNC(drawRadius)],
["RECTANGLE", LINKFUNC(drawRectangle)]
];

GVAR(currentDistanceFormatter) = 0;
GVAR(currentAzimuthFormatter) = 0;
};

call FUNC(compileFormatters);

#include "initSettings.inc.sqf"
#include "initKeybinds.inc.sqf"

ADDON = true;
3 changes: 3 additions & 0 deletions addons/plotting/XEH_preStart.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "script_component.hpp"

#include "XEH_PREP.hpp"
21 changes: 21 additions & 0 deletions addons/plotting/config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include "script_component.hpp"

class CfgPatches {
class ADDON {
name = COMPONENT_NAME;
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"zen_common", "zen_context_menu"};
author = ECSTRING(main,Author);
authors[] = {"Timi007"};
url = ECSTRING(main,URL);
VERSION_CONFIG;
};
};

PRELOAD_ADDONS;

#include "CfgEventHandlers.hpp"
#include "CfgContext.hpp"
#include "CfgFormatters.hpp"
28 changes: 28 additions & 0 deletions addons/plotting/functions/fnc_addPlot.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "script_component.hpp"
/*
* Authors: Timi007
* Adds a new plot to be drawn.
*
* Arguments:
* 0: Type of plot <STRING>
* 1: Start position ASL or attached object <ARRAY or OBJECT>
* 2: End position ASL or attached object <ARRAY or OBJECT>
*
* Return Value:
* Index of new plot <NUMBER>
*
* Example:
* ["RADIUS", player, [100, 100, 10]] call zen_plotting_fnc_addPlot
*
* Public: No
*/

params [
["_type", "LINE", [""]],
["_startPos", [0, 0, 0], [[], objNull], [3]],
["_endPos", [0, 0, 0], [[], objNull], [3]]
];

if !(_type in GVAR(plotTypes)) exitWith {-1};

GVAR(plots) pushBack [_type, _startPos, _endPos]
18 changes: 18 additions & 0 deletions addons/plotting/functions/fnc_clearPlots.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "script_component.hpp"
/*
* Authors: Timi007
* Clears of plots.
*
* Arguments:
* None
*
* Return Value:
* None
*
* Example:
* [] call zen_plotting_fnc_clearPlots
*
* Public: No
*/

GVAR(plots) = [];
52 changes: 52 additions & 0 deletions addons/plotting/functions/fnc_compileFormatters.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include "script_component.hpp"
/*
* Authors: Timi007
* Compiles formatters from config and saves them in missionNamespace.
*
* Arguments:
* None
*
* Return Value:
* None
*
* Example:
* [] call zen_plotting_fnc_compileFormatters
*
* Public: No
*/

private _fnc_getFormatters = {
params ["_cfgFormatters"];

private _formatters = [];
{
private _entryConfig = _x;

private _formatterName = configName _entryConfig;

private _formatterString = getText (_entryConfig >> "formatter");
if (_formatterString isNotEqualTo "") then {
_formatterString = "params ['_value']; " + _formatterString;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary, just pass the value in _this and then, format ["%1 m", _this] for example.

};
private _formatter = compile _formatterString;

private _priority = getNumber (_entryConfig >> "priority");

private _formatterEntry = [
_formatterName,
_formatter,
_priority
];

_formatters pushBack _formatterEntry;
} forEach configProperties [_cfgFormatters, "isClass _x", true];

[_formatters, 3, false] call CBA_fnc_sortNestedArray
};

private _cfgFormatters = configFile >> QGVAR(formatters);
private _distanceFormatters = [_cfgFormatters >> "Distance"] call _fnc_getFormatters;
private _azimuthFormatters = [_cfgFormatters >> "Azimuth"] call _fnc_getFormatters;

missionNamespace setVariable [QGVAR(distanceFormatters), _distanceFormatters];
missionNamespace setVariable [QGVAR(azimuthFormatters), _azimuthFormatters];
63 changes: 63 additions & 0 deletions addons/plotting/functions/fnc_drawLine.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#include "script_component.hpp"
/*
* Authors: Timi007
* Draws a line plot in 3D or on the map. Must be called every frame.
*
* Arguments:
* 0: Start position ASL <ARRAY>
* 1: End position ASL <ARRAY>
* 2: Visual properties <ARRAY>
* 0: Icon <STRING>
* 1: Color RGBA <ARRAY>
* 2: Scale <NUMBER>
* 3: Angle <NUMBER>
* 4: Line width <NUMBER>
* 3: Formatters <ARRAY>
* 0: Distance formatter <CODE>
* 1: Azimuth formatter <CODE>
* 4: Camera position ASL <ARRAY> (default: Don't check render distance)
* 5: Map control <CONTROL> (default: Draw in 3D)
*
* Return Value:
* None
*
* Example:
* [[0, 0, 0], [100, 100, 0], ["", [1, 0, 0, 1], 1, 0, 5], [{_this toFixed 0}, {_this toFixed 1}]] call zen_plotting_fnc_drawLine
*
* Public: No
*/

params ["_startPos", "_endPos", "_visualProperties", "_formatters", ["_ctrlMap", controlNull, [controlNull]]];
_visualProperties params ["_icon", "_color", "_scale", "_angle", "_lineWidth"];

private _distance = _startPos vectorDistance _endPos;

private _azimuthToStart = _endPos getDir _startPos;
private _azimuthToEnd = _startPos getDir _endPos;
Comment on lines +35 to +36
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be the relative direction?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the direction from start to end pos and end to start. Both _startPos and _endPos are PosASL. I don't understand the relative part in your question.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, when attached to objects the direction value being displayed did not seem intuitive. If that makes sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to check what you mean. It should show the same value as the unit just opening their compass.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it just comes to whether we want to know that the position is 90 degrees relative to the vehicle or just the difference in their bearings. The former what what I assumed the value was.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What purpose does relative bearing w.r.t. the attached unit have to the Zeus or any unit on the ground? I understand if you want the direction as a relative clock, but I have never given or received relative bearing. For artillery corrections, you also don't use relative directions.


private _fnc_format = {
params ["_distance", "_azimuth", "_formatters"];
_formatters params ["_fnc_distanceFormatter", "_fnc_azimuthFormatter"];

format ["%1 - %2", _distance call _fnc_distanceFormatter, _azimuth call _fnc_azimuthFormatter]
};

if (isNull _ctrlMap) then { // 3D
private _camPos = getPosASL curatorCamera;

if (CAN_RENDER_ICON(_camPos,_startPos)) then {
drawIcon3D [_icon, _color, ASLToAGL _startPos, _scale, _scale, _angle, [_distance, _azimuthToStart, _formatters] call _fnc_format];
};

if (CAN_RENDER_LINE(_camPos,_startPos,_endPos)) then {
drawLine3D [ASLToAGL _startPos, ASLToAGL _endPos, _color, _lineWidth];
};

if (CAN_RENDER_ICON(_camPos,_endPos)) then {
drawIcon3D [_icon, _color, ASLToAGL _endPos, _scale, _scale, _angle, [_distance, _azimuthToEnd, _formatters] call _fnc_format];
};
} else { // Map
_ctrlMap drawIcon [_icon, _color, _startPos, _scale, _scale, _angle, [_distance, _azimuthToStart, _formatters] call _fnc_format];
_ctrlMap drawLine [_startPos, _endPos, _color];
_ctrlMap drawIcon [_icon, _color, _endPos, _scale, _scale, _angle, [_distance, _azimuthToEnd, _formatters] call _fnc_format];
};
Loading