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(renderIcon);
PREP(renderMenu);
PREP(renderSelector);
PREP(splitPath);
GVAR(keyDown) = false;

View File

@ -12,6 +12,8 @@
*/
#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"];
_foundTarget = false;
_cursorPos1 = positionCameraToWorld [0, 0, 0];
@ -97,7 +99,11 @@ if (GVAR(keyDown)) then {
{
_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);
} forEach _classActions;
};
@ -115,14 +121,11 @@ if(GVAR(keyDown) || GVAR(keyDownSelfAction)) then {
_closestDistance = 1000000;
_closestSelection = -1;
{
_pos = _x select 1;
_sPos = worldToScreen _pos;
if(count _sPos > 0) then {
_disSq = (((_cursorScreenPos select 0) - (_sPos select 0))^2 + ((_cursorScreenPos select 1) - (_sPos select 1))^2);
if(_disSq < 0.0125 && _disSq < _closestDistance) then {
_closestDistance = _disSq;
_closestSelection = _forEachIndex;
};
_sPos = _x select 1;
_disSq = (((_cursorScreenPos select 0) - (_sPos select 0))^2 + ((_cursorScreenPos select 1) - (_sPos select 1))^2);
if(_disSq < 0.0125 && _disSq < _closestDistance) then {
_closestDistance = _disSq;
_closestSelection = _forEachIndex;
};
} forEach GVAR(currentOptions);
@ -131,15 +134,14 @@ if(GVAR(keyDown) || GVAR(keyDownSelfAction)) then {
_closest = GVAR(currentOptions) select _closestSelection;
_pos = _closest select 1;
_sPos = _closest select 1;
_cTime = diag_tickTime;
_delta = _cTime - GVAR(lastTime);
GVAR(lastTime) = _cTime;
GVAR(rotationAngle) = GVAR(rotationAngle) + (180*_delta);
if(GVAR(rotationAngle) > 360) then {
GVAR(rotationAngle) = GVAR(rotationAngle) - 360;
};
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"];
GVAR(rotationAngle) = (GVAR(rotationAngle) + (270*_delta)) mod 360;
[_sPos] call FUNC(renderSelector);
_foundTarget = true;
GVAR(actionSelected) = true;
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(iconCount) = 0;
END_COUNTER(fnc_render);

View File

@ -5,7 +5,7 @@
* Argument:
* 0: Object <OBJECT>
* 1: Action node <ARRAY>
* 2: 3D position <ARRAY> (Optional)
* 2: 3D position or 2D position <ARRAY> (Optional)
*
* Return value:
* Was the menu rendered <BOOL>
@ -14,6 +14,8 @@
*/
#include "script_component.hpp"
BEGIN_COUNTER(fnc_renderBaseMenu)
private ["_distance","_pos","_weaponDir","_ref","_cameraPos","_sPos","_activeActionTree"];
EXPLODE_2_PVT(_this,_object,_baseActionNode);
@ -41,16 +43,16 @@ if((count _this) > 2) then {
_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
if (GVAR(keyDown) &&
{(ACE_player modelToWorld (ACE_player selectionPosition "pilot")) distance _pos >= _distance}) exitWith {false};
// 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};
// 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};
BEGIN_COUNTER(fnc_collectActiveActionTree)
// Collect active tree
private "_uid";
_uid = format [QGVAR(ATCache_%1), _actionData select 0];
@ -67,6 +71,8 @@ _activeActionTree = [
_object, _uid, 1.0, "interactMenuClosed"
] call EFUNC(common,cachedCall);
END_COUNTER(fnc_collectActiveActionTree)
/*
diag_log "Printing: _activeActionTree";
_fnc_print = {
@ -84,6 +90,12 @@ if (count _activeActionTree == 0) exitWith {false};
//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

View File

@ -5,7 +5,7 @@
* Argument:
* 0: Text <STRING>
* 1: Color <STRING>
* 2: 3d position ASL <ARRAY>
* 2: 2d position <ARRAY>
* 3: ?
* 4: ?
* 5: ?
@ -18,30 +18,25 @@
*/
#include "script_component.hpp"
#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;
_color = _this select 1;
_pos = _this select 2;
_sPos = _this select 2;
_icon = _this select 6;
//systemChat format ["Icon %1 - %2,%3,%4", _text, _pos select 0, _pos select 1, _pos select 2];
_sPos = worldToScreen _pos;
if(count _sPos > 0) then {
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;
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;
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:
* 0: Parent path <ARRAY>
* 1: Action data <ARRAY>
* 2: 3D position <ARRAY>
* 2: 2D position <ARRAY>
* 3: Angle range available for rendering <ARRAY>
*
* Return value:
@ -17,12 +17,14 @@
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_2_PVT(_angles,_centerAngle,_maxAngleSpan);
_menuDepth = (count GVAR(menuDepthPath));
//BEGIN_COUNTER(constructing_paths);
// Store path to action
_path = +_parentPath;
_path pushBack [_actionData select 0,_actionObject];
@ -38,24 +40,39 @@ _menuInSelectedPath = true;
};
} forEach _path;
//END_COUNTER(constructing_paths);
//BEGIN_COUNTER(constructing_colors);
// Render icon
// ARGB Color (First Hex Pair is transparancy)
_color = "#FFFFFFFF";
if(!_menuInSelectedPath) then { //_menuDepth > 0 &&
if(!_menuInSelectedPath) then {
if (_menuDepth > 0) then {
_color = format ["#%1FFFFFF", [255 * ((((count _path) - 1)/_menuDepth) max 0.25)] call EFUNC(common,toHex)];
} else {
_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
GVAR(currentOptions) pushBack [_this, _pos, _path];
GVAR(currentOptions) pushBack [_this, _sPos, _path];
//END_COUNTER(currentOptions);
// Exit without rendering children if it isn't
if !(_menuInSelectedPath) exitWith {true};
//BEGIN_COUNTER(children);
private ["_numChildren","_angleSpan","_angle","_angleInterval","_scale","_offset"];
_numChildren = count _activeChildren;
_angleSpan = _maxAngleSpan min (55 * ((_numChildren) - 1));
@ -75,6 +92,7 @@ if (_numChildren == 1) then {
};
// 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);
// Animate menu scale
if (_menuInSelectedPath && (_menuDepth == count _path)) then {
@ -83,16 +101,17 @@ if (_menuInSelectedPath && (_menuDepth == count _path)) then {
_target = _actionObject;
_player = ACE_player;
//END_COUNTER(children);
_angle = _centerAngle - _angleSpan / 2;
{
//BEGIN_COUNTER(children);
private ["_offset","_newPos"];
_offset = ((GVAR(refSystem) select 1) vectorMultiply (-_scale * cos _angle)) vectorAdd
((GVAR(refSystem) select 2) vectorMultiply (-_scale * sin _angle));
_newPos = ((_pos call EFUNC(common,positionToASL)) vectorAdd _offset) call EFUNC(common,ASLToPosition);
_newPos = [(_sPos select 0) -_scale * cos _angle,
(_sPos select 1) +_scale * (sin _angle) * 4/3];
//drawLine3D [_pos, _newPos, [1,0,0,0.8]];
//END_COUNTER(children);
[_path, _x, _newPos, [_angle, 140]] call FUNC(renderMenu);
_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