Make interac_menu work in real 2D:

- Children positions are calculated directly on screen space
- Saves a lot of worldToScreen, ATLtoASL, etc calls
- Selector is now a control instead of a 3D icon
This commit is contained in:
Nicolás Badano 2015-03-23 18:08:31 -03:00
parent 20362e8dc9
commit eb557bf777
36 changed files with 113 additions and 53 deletions

View File

@ -20,6 +20,7 @@ PREP(render);
PREP(renderBaseMenu); PREP(renderBaseMenu);
PREP(renderIcon); PREP(renderIcon);
PREP(renderMenu); PREP(renderMenu);
PREP(renderSelector);
PREP(splitPath); PREP(splitPath);
GVAR(keyDown) = false; GVAR(keyDown) = false;

View File

@ -12,6 +12,8 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
BEGIN_COUNTER(fnc_render);
private ["_cursorPos1", "_cursorPos2", "_cursorVec", "_p1", "_p2", "_p", "_v", "_cp", "_forEachIndex", "_renderTargets", "_x", "_cursorScreenPos", "_closestDistance", "_closestSelection", "_pos", "_sPos", "_disSq", "_closest", "_cTime", "_delta", "_foundTarget", "_misMatch", "_hoverPath", "_i"]; private ["_cursorPos1", "_cursorPos2", "_cursorVec", "_p1", "_p2", "_p", "_v", "_cp", "_forEachIndex", "_renderTargets", "_x", "_cursorScreenPos", "_closestDistance", "_closestSelection", "_pos", "_sPos", "_disSq", "_closest", "_cTime", "_delta", "_foundTarget", "_misMatch", "_hoverPath", "_i"];
_foundTarget = false; _foundTarget = false;
_cursorPos1 = positionCameraToWorld [0, 0, 0]; _cursorPos1 = positionCameraToWorld [0, 0, 0];
@ -97,7 +99,11 @@ if (GVAR(keyDown)) then {
{ {
_action = _x; _action = _x;
_pos = (((positionCameraToWorld [0, 0, 0]) call EFUNC(common,positionToASL)) vectorAdd GVAR(selfMenuOffset)) call EFUNC(common,ASLToPosition); _pos = if !(visibleMap) then {
(((positionCameraToWorld [0, 0, 0]) call EFUNC(common,positionToASL)) vectorAdd GVAR(selfMenuOffset)) call EFUNC(common,ASLToPosition)
} else {
[0.5, 0.5]
};
[_target, _action, _pos] call FUNC(renderBaseMenu); [_target, _action, _pos] call FUNC(renderBaseMenu);
} forEach _classActions; } forEach _classActions;
}; };
@ -115,14 +121,11 @@ if(GVAR(keyDown) || GVAR(keyDownSelfAction)) then {
_closestDistance = 1000000; _closestDistance = 1000000;
_closestSelection = -1; _closestSelection = -1;
{ {
_pos = _x select 1; _sPos = _x select 1;
_sPos = worldToScreen _pos; _disSq = (((_cursorScreenPos select 0) - (_sPos select 0))^2 + ((_cursorScreenPos select 1) - (_sPos select 1))^2);
if(count _sPos > 0) then { if(_disSq < 0.0125 && _disSq < _closestDistance) then {
_disSq = (((_cursorScreenPos select 0) - (_sPos select 0))^2 + ((_cursorScreenPos select 1) - (_sPos select 1))^2); _closestDistance = _disSq;
if(_disSq < 0.0125 && _disSq < _closestDistance) then { _closestSelection = _forEachIndex;
_closestDistance = _disSq;
_closestSelection = _forEachIndex;
};
}; };
} forEach GVAR(currentOptions); } forEach GVAR(currentOptions);
@ -131,15 +134,14 @@ if(GVAR(keyDown) || GVAR(keyDownSelfAction)) then {
_closest = GVAR(currentOptions) select _closestSelection; _closest = GVAR(currentOptions) select _closestSelection;
_pos = _closest select 1; _sPos = _closest select 1;
_cTime = diag_tickTime; _cTime = diag_tickTime;
_delta = _cTime - GVAR(lastTime); _delta = _cTime - GVAR(lastTime);
GVAR(lastTime) = _cTime; GVAR(lastTime) = _cTime;
GVAR(rotationAngle) = GVAR(rotationAngle) + (180*_delta);
if(GVAR(rotationAngle) > 360) then { GVAR(rotationAngle) = (GVAR(rotationAngle) + (270*_delta)) mod 360;
GVAR(rotationAngle) = GVAR(rotationAngle) - 360; [_sPos] call FUNC(renderSelector);
};
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,.75], _pos, 0.6*SafeZoneW, 0.6*SafeZoneW, GVAR(rotationAngle), "", 0.5, 0.025, "TahomaB"];
_foundTarget = true; _foundTarget = true;
GVAR(actionSelected) = true; GVAR(actionSelected) = true;
GVAR(selectedAction) = (_closest select 0) select 1; GVAR(selectedAction) = (_closest select 0) select 1;
@ -207,3 +209,5 @@ for "_i" from GVAR(iconCount) to (count GVAR(iconCtrls))-1 do {
}; };
GVAR(iconCtrls) resize GVAR(iconCount); GVAR(iconCtrls) resize GVAR(iconCount);
GVAR(iconCount) = 0; GVAR(iconCount) = 0;
END_COUNTER(fnc_render);

View File

@ -5,7 +5,7 @@
* Argument: * Argument:
* 0: Object <OBJECT> * 0: Object <OBJECT>
* 1: Action node <ARRAY> * 1: Action node <ARRAY>
* 2: 3D position <ARRAY> (Optional) * 2: 3D position or 2D position <ARRAY> (Optional)
* *
* Return value: * Return value:
* Was the menu rendered <BOOL> * Was the menu rendered <BOOL>
@ -14,6 +14,8 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
BEGIN_COUNTER(fnc_renderBaseMenu)
private ["_distance","_pos","_weaponDir","_ref","_cameraPos","_sPos","_activeActionTree"]; private ["_distance","_pos","_weaponDir","_ref","_cameraPos","_sPos","_activeActionTree"];
EXPLODE_2_PVT(_this,_object,_baseActionNode); EXPLODE_2_PVT(_this,_object,_baseActionNode);
@ -41,16 +43,16 @@ if((count _this) > 2) then {
_pos = _pos vectorAdd ((visiblePositionASL _object) vectorDiff (getPosASL _object)); _pos = _pos vectorAdd ((visiblePositionASL _object) vectorDiff (getPosASL _object));
}; };
_cameraToActionVec = (_pos call EFUNC(common,positionToASL)) vectorDiff ((positionCameraToWorld [0,0,0]) call EFUNC(common,positionToASL));
GVAR(refSystem) = _cameraToActionVec call EFUNC(common,createOrthonormalReference);
GVAR(menuScale) = (0.15 max (0.15 * ((positionCameraToWorld [0, 0, 0]) distance _pos))) / GVAR(selfMenuScale);
// For non-self actions, exit if the action is too far away // For non-self actions, exit if the action is too far away
if (GVAR(keyDown) && if (GVAR(keyDown) &&
{(ACE_player modelToWorld (ACE_player selectionPosition "pilot")) distance _pos >= _distance}) exitWith {false}; {(ACE_player modelToWorld (ACE_player selectionPosition "pilot")) distance _pos >= _distance}) exitWith {false};
// Exit if the action is behind you // Exit if the action is behind you
_sPos = worldToScreen _pos; _sPos = if (count _pos != 2) then {
worldToScreen _pos
} else {
pos
};
if(count _sPos == 0) exitWith {false}; if(count _sPos == 0) exitWith {false};
// Exit if the action is off screen // Exit if the action is off screen
@ -58,6 +60,8 @@ if ((_sPos select 0) < safeZoneXAbs || (_sPos select 0) > safeZoneXAbs + safeZon
if ((_sPos select 1) < safeZoneY || (_sPos select 1) > safeZoneY + safeZoneH) exitWith {false}; if ((_sPos select 1) < safeZoneY || (_sPos select 1) > safeZoneY + safeZoneH) exitWith {false};
BEGIN_COUNTER(fnc_collectActiveActionTree)
// Collect active tree // Collect active tree
private "_uid"; private "_uid";
_uid = format [QGVAR(ATCache_%1), _actionData select 0]; _uid = format [QGVAR(ATCache_%1), _actionData select 0];
@ -67,6 +71,8 @@ _activeActionTree = [
_object, _uid, 1.0, "interactMenuClosed" _object, _uid, 1.0, "interactMenuClosed"
] call EFUNC(common,cachedCall); ] call EFUNC(common,cachedCall);
END_COUNTER(fnc_collectActiveActionTree)
/* /*
diag_log "Printing: _activeActionTree"; diag_log "Printing: _activeActionTree";
_fnc_print = { _fnc_print = {
@ -84,6 +90,12 @@ if (count _activeActionTree == 0) exitWith {false};
//EXPLODE_2_PVT(_activeActionTree,_actionData,_actionChildren); //EXPLODE_2_PVT(_activeActionTree,_actionData,_actionChildren);
[[], _activeActionTree, _pos, [180,360]] call FUNC(renderMenu); BEGIN_COUNTER(fnc_renderMenus);
[[], _activeActionTree, _sPos, [180,360]] call FUNC(renderMenu);
END_COUNTER(fnc_renderMenus);
END_COUNTER(fnc_renderBaseMenu)
true true

View File

@ -5,7 +5,7 @@
* Argument: * Argument:
* 0: Text <STRING> * 0: Text <STRING>
* 1: Color <STRING> * 1: Color <STRING>
* 2: 3d position ASL <ARRAY> * 2: 2d position <ARRAY>
* 3: ? * 3: ?
* 4: ? * 4: ?
* 5: ? * 5: ?
@ -18,30 +18,25 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
#define DEFAULT_ICON QUOTE(\z\ace\addons\interaction\ui\dot_ca.paa) #define DEFAULT_ICON QUOTE(\z\ace\addons\interaction\ui\dot_ca.paa)
private ["_color", "_pos", "_sPos", "_ctrl", "_icon"]; private ["_color", "_sPos", "_ctrl", "_icon"];
_text = _this select 0; _text = _this select 0;
_color = _this select 1; _color = _this select 1;
_pos = _this select 2; _sPos = _this select 2;
_icon = _this select 6; _icon = _this select 6;
//systemChat format ["Icon %1 - %2,%3,%4", _text, _pos select 0, _pos select 1, _pos select 2]; //systemChat format ["Icon %1 - %2,%3,%4", _text, _pos select 0, _pos select 1, _pos select 2];
_sPos = worldToScreen _pos; if(GVAR(iconCount) > (count GVAR(iconCtrls))-1) then {
if(count _sPos > 0) then { _displayNum = [46,91919] select (uiNamespace getVariable [QGVAR(cursorMenuOpened),false]);
GVAR(iconCtrls) pushBack ((findDisplay _displayNum) ctrlCreate ["RscStructuredText", 54021+GVAR(iconCount)]);
if(GVAR(iconCount) > (count GVAR(iconCtrls))-1) then {
_displayNum = [46,91919] select (uiNamespace getVariable [QGVAR(cursorMenuOpened),false]);
//systemChat format ["Displaynum: %1", _displayNum];
GVAR(iconCtrls) pushBack ((findDisplay _displayNum) ctrlCreate ["RscStructuredText", 54021+GVAR(iconCount)]);
};
_ctrl = GVAR(iconCtrls) select GVAR(iconCount);
GVAR(iconCount) = GVAR(iconCount) + 1;
if(_icon == "") then {
_icon = DEFAULT_ICON;
};
_text = format ["<img image='%1' color='%2' align='center'/><br/><t color ='%3' size='0.75' align='center'>%4</t>", _icon, _color, _color, _text];
_ctrl ctrlSetStructuredText (parseText _text);
_ctrl ctrlSetPosition [(_sPos select 0)-(0.2*SafeZoneW), (_sPos select 1)-(0.0095*SafeZoneW), 0.4*SafeZoneW, 0.035*SafeZoneW];
//_ctrl ctrlSetBackgroundColor [1, 0, 0, 0.1];
_ctrl ctrlCommit 0;
}; };
_ctrl = GVAR(iconCtrls) select GVAR(iconCount);
GVAR(iconCount) = GVAR(iconCount) + 1;
if(_icon == "") then {
_icon = DEFAULT_ICON;
};
_text = format ["<img image='%1' color='%2' align='center'/><br/><t color ='%3' size='0.75' align='center'>%4</t>", _icon, _color, _color, _text];
_ctrl ctrlSetStructuredText (parseText _text);
_ctrl ctrlSetPosition [(_sPos select 0)-(0.2*SafeZoneW), (_sPos select 1)-(0.0095*SafeZoneW), 0.4*SafeZoneW, 0.035*SafeZoneW];
//_ctrl ctrlSetBackgroundColor [1, 0, 0, 0.1];
_ctrl ctrlCommit 0;

View File

@ -5,7 +5,7 @@
* Argument: * Argument:
* 0: Parent path <ARRAY> * 0: Parent path <ARRAY>
* 1: Action data <ARRAY> * 1: Action data <ARRAY>
* 2: 3D position <ARRAY> * 2: 2D position <ARRAY>
* 3: Angle range available for rendering <ARRAY> * 3: Angle range available for rendering <ARRAY>
* *
* Return value: * Return value:
@ -17,12 +17,14 @@
private ["_menuInSelectedPath", "_path", "_menuDepth", "_currentRenderDepth", "_x", "_offset", "_newPos", "_forEachIndex"]; private ["_menuInSelectedPath", "_path", "_menuDepth", "_currentRenderDepth", "_x", "_offset", "_newPos", "_forEachIndex"];
EXPLODE_4_PVT(_this,_parentPath,_action,_pos,_angles); EXPLODE_4_PVT(_this,_parentPath,_action,_sPos,_angles);
EXPLODE_3_PVT(_action,_actionData,_activeChildren,_actionObject); EXPLODE_3_PVT(_action,_actionData,_activeChildren,_actionObject);
EXPLODE_2_PVT(_angles,_centerAngle,_maxAngleSpan); EXPLODE_2_PVT(_angles,_centerAngle,_maxAngleSpan);
_menuDepth = (count GVAR(menuDepthPath)); _menuDepth = (count GVAR(menuDepthPath));
//BEGIN_COUNTER(constructing_paths);
// Store path to action // Store path to action
_path = +_parentPath; _path = +_parentPath;
_path pushBack [_actionData select 0,_actionObject]; _path pushBack [_actionData select 0,_actionObject];
@ -38,24 +40,39 @@ _menuInSelectedPath = true;
}; };
} forEach _path; } forEach _path;
//END_COUNTER(constructing_paths);
//BEGIN_COUNTER(constructing_colors);
// Render icon // Render icon
// ARGB Color (First Hex Pair is transparancy) // ARGB Color (First Hex Pair is transparancy)
_color = "#FFFFFFFF"; _color = "#FFFFFFFF";
if(!_menuInSelectedPath) then { //_menuDepth > 0 && if(!_menuInSelectedPath) then {
if (_menuDepth > 0) then { if (_menuDepth > 0) then {
_color = format ["#%1FFFFFF", [255 * ((((count _path) - 1)/_menuDepth) max 0.25)] call EFUNC(common,toHex)]; _color = format ["#%1FFFFFF", [255 * ((((count _path) - 1)/_menuDepth) max 0.25)] call EFUNC(common,toHex)];
} else { } else {
_color = format ["#%1FFFFFF", [255 * 0.75] call EFUNC(common,toHex)]; _color = format ["#%1FFFFFF", [255 * 0.75] call EFUNC(common,toHex)];
}; };
}; };
[_actionData select 1, _color, _pos, 1, 1, 0, _actionData select 2, 0.5, 0.025, "TahomaB"] call FUNC(renderIcon);
//END_COUNTER(constructing_colors);
//BEGIN_COUNTER(fnc_renderIcons);
[_actionData select 1, _color, _sPos, 1, 1, 0, _actionData select 2, 0.5, 0.025, "TahomaB"] call FUNC(renderIcon);
//END_COUNTER(fnc_renderIcons);
//BEGIN_COUNTER(currentOptions);
// Add the action to current options // Add the action to current options
GVAR(currentOptions) pushBack [_this, _pos, _path]; GVAR(currentOptions) pushBack [_this, _sPos, _path];
//END_COUNTER(currentOptions);
// Exit without rendering children if it isn't // Exit without rendering children if it isn't
if !(_menuInSelectedPath) exitWith {true}; if !(_menuInSelectedPath) exitWith {true};
//BEGIN_COUNTER(children);
private ["_numChildren","_angleSpan","_angle","_angleInterval","_scale","_offset"]; private ["_numChildren","_angleSpan","_angle","_angleInterval","_scale","_offset"];
_numChildren = count _activeChildren; _numChildren = count _activeChildren;
_angleSpan = _maxAngleSpan min (55 * ((_numChildren) - 1)); _angleSpan = _maxAngleSpan min (55 * ((_numChildren) - 1));
@ -75,6 +92,7 @@ if (_numChildren == 1) then {
}; };
// Scale menu based on the amount of children // Scale menu based on the amount of children
GVAR(menuScale) = 0.15;
_scale = GVAR(menuScale) * (((0.8 * (0.46 / sin (0.5 * _angleInterval))) min 1.4) max 0.5); _scale = GVAR(menuScale) * (((0.8 * (0.46 / sin (0.5 * _angleInterval))) min 1.4) max 0.5);
// Animate menu scale // Animate menu scale
if (_menuInSelectedPath && (_menuDepth == count _path)) then { if (_menuInSelectedPath && (_menuDepth == count _path)) then {
@ -83,16 +101,17 @@ if (_menuInSelectedPath && (_menuDepth == count _path)) then {
_target = _actionObject; _target = _actionObject;
_player = ACE_player; _player = ACE_player;
//END_COUNTER(children);
_angle = _centerAngle - _angleSpan / 2; _angle = _centerAngle - _angleSpan / 2;
{ {
//BEGIN_COUNTER(children);
private ["_offset","_newPos"]; private ["_offset","_newPos"];
_offset = ((GVAR(refSystem) select 1) vectorMultiply (-_scale * cos _angle)) vectorAdd _newPos = [(_sPos select 0) -_scale * cos _angle,
((GVAR(refSystem) select 2) vectorMultiply (-_scale * sin _angle)); (_sPos select 1) +_scale * (sin _angle) * 4/3];
_newPos = ((_pos call EFUNC(common,positionToASL)) vectorAdd _offset) call EFUNC(common,ASLToPosition);
//drawLine3D [_pos, _newPos, [1,0,0,0.8]]; //drawLine3D [_pos, _newPos, [1,0,0,0.8]];
//END_COUNTER(children);
[_path, _x, _newPos, [_angle, 140]] call FUNC(renderMenu); [_path, _x, _newPos, [_angle, 140]] call FUNC(renderMenu);
_angle = _angle + _angleInterval; _angle = _angle + _angleInterval;

View File

@ -0,0 +1,29 @@
/*
* Author: CAA-Picard
* Render a single interaction icon
*
* Argument:
* 0: 2d position <ARRAY>
*
* Return value:
* None
*
* Public: No
*/
#include "script_component.hpp"
#define DEFAULT_ICON QUOTE(\z\ace\addons\interaction\ui\dot_ca.paa)
private ["_color", "_sPos", "_ctrl", "_icon"];
_sPos = _this select 0;
if(GVAR(iconCount) > (count GVAR(iconCtrls))-1) then {
_displayNum = [46,91919] select (uiNamespace getVariable [QGVAR(cursorMenuOpened),false]);
GVAR(iconCtrls) pushBack ((findDisplay _displayNum) ctrlCreate ["RscStructuredText", 54021+GVAR(iconCount)]);
};
_ctrl = GVAR(iconCtrls) select GVAR(iconCount);
GVAR(iconCount) = GVAR(iconCount) + 1;
_text = format ["<img image='%1' color='#FF0000' size='1.5' align='center'/>", format [QUOTE(PATHTOF(ui\selector%1.paa)), floor (((abs GVAR(rotationAngle)) mod 90) / 6)]];
_ctrl ctrlSetStructuredText (parseText _text);
_ctrl ctrlSetPosition [(_sPos select 0)-(0.2*SafeZoneW), (_sPos select 1)-(0.012*SafeZoneW), 0.4*SafeZoneW, 0.035*SafeZoneW];
//_ctrl ctrlSetBackgroundColor [1, 0, 0, 0.1];
_ctrl ctrlCommit 0;

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB