From d2345a398a853d6bd7200972371f869624ca6d08 Mon Sep 17 00:00:00 2001 From: SilentSpike Date: Wed, 15 Jul 2015 12:11:19 +0100 Subject: [PATCH] Handle free cam movement --- addons/spectator/UI/interface.hpp | 15 ++- addons/spectator/XEH_preInit.sqf | 2 + .../spectator/functions/fnc_handleCamera.sqf | 52 +++++++++ .../functions/fnc_handleInterface.sqf | 105 +++++++++++++++++- .../spectator/functions/fnc_handleMouse.sqf | 23 ++++ 5 files changed, 195 insertions(+), 2 deletions(-) create mode 100644 addons/spectator/functions/fnc_handleCamera.sqf create mode 100644 addons/spectator/functions/fnc_handleMouse.sqf diff --git a/addons/spectator/UI/interface.hpp b/addons/spectator/UI/interface.hpp index d1eff61e5d..5e57f51b36 100644 --- a/addons/spectator/UI/interface.hpp +++ b/addons/spectator/UI/interface.hpp @@ -13,7 +13,7 @@ class GVAR(overlay) { onUnload = QUOTE([ARR_2('onUnload',_this)] call FUNC(handleInterface)); onKeyDown = QUOTE([ARR_2('onKeyDown',_this)] call FUNC(handleInterface)); onKeyUp = QUOTE([ARR_2('onKeyUp',_this)] call FUNC(handleInterface)); - class controls { + class controlsBackground { class crosshair: RscActivePicture { idc = 52; x = 0.5 - W_PART(2); @@ -24,6 +24,19 @@ class GVAR(overlay) { fixedWidth = 0; shadow = 0; }; + class mouseHandler: RscControlsGroup { + x = safeZoneXAbs; + y = safeZoneY; + w = safeZoneWAbs; + h = safeZoneH; + colorBackground[] = {0,0,0,0}; + onMouseButtonDown = QUOTE([ARR_2('onMouseButtonDown',_this)] call FUNC(handleInterface)); + onMouseButtonUp = QUOTE([ARR_2('onMouseButtonUp',_this)] call FUNC(handleInterface)); + onMouseZChanged = QUOTE([ARR_2('onMouseZChanged',_this)] call FUNC(handleInterface)); + onMouseMoving = QUOTE([ARR_2('onMouseMoving',_this)] call FUNC(handleInterface)); + }; + }; + class controls { class compassBack: RscText { idc = -1; x = COMPASS_X; diff --git a/addons/spectator/XEH_preInit.sqf b/addons/spectator/XEH_preInit.sqf index 19a8427507..e15e24aa67 100644 --- a/addons/spectator/XEH_preInit.sqf +++ b/addons/spectator/XEH_preInit.sqf @@ -2,8 +2,10 @@ ADDON = false; +PREP(handleCamera); PREP(handleInterface); PREP(handleKilled); +PREP(handleMouse); PREP(handleRespawn); PREP(moduleSpectator); PREP(setSpectator); diff --git a/addons/spectator/functions/fnc_handleCamera.sqf b/addons/spectator/functions/fnc_handleCamera.sqf new file mode 100644 index 0000000000..e0dd7b8351 --- /dev/null +++ b/addons/spectator/functions/fnc_handleCamera.sqf @@ -0,0 +1,52 @@ +#include "script_component.hpp" + +// Don't recreate the PFH +if !(isNil QGVAR(camPFH)) exitWith {}; + +// Constantly handle camera manipulation +GVAR(camPFH) = [ +{ + // Kill PFH when display is closed + if (isNull (GETUVAR(GVAR(display),displayNull))) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; GVAR(camPFH) = nil; }; + + // Different behaviour based on camera mode + switch (GVAR(camMode)) do { + case 0: { // Free + _oldPos = getPosASL GVAR(camera); + _mX = 0; + _mY = 0; + _mZ = 0; + if (GVAR(camDolly) select 0) then { // Forward + _mY = _mY + GVAR(camSpeed); + }; + if (GVAR(camDolly) select 1) then { // Backward + _mY = _mY - GVAR(camSpeed); + }; + if (GVAR(camDolly) select 2) then { // Left + _mX = _mX - GVAR(camSpeed); + }; + if (GVAR(camDolly) select 3) then { // Right + _mX = _mX + GVAR(camSpeed); + }; + if (GVAR(camBoom) select 0) then { // Up + _mZ = _mZ + 0.5; + }; + if (GVAR(camBoom) select 1) then { // Down + _mZ = _mZ - 0.5; + }; + + _pan = (GVAR(camPan) + 360) % 360; + _x = (_oldPos select 0) + (_mX * cos(_pan)) + (_mY * sin(_pan)); + _y = (_oldPos select 1) - (_mX * sin(_pan)) + (_mY * cos(_pan)); + _z = (_oldPos select 2) + _mZ; + + // Prevent camera going under terrain + GVAR(camPos) = [_x,_y,_z max (getTerrainHeightASL [_x,_y])]; + + // Update camera position and rotation + GVAR(camera) setPosASL GVAR(camPos); + GVAR(camera) setDir GVAR(camPan); + [GVAR(camera), GVAR(camTilt), GVAR(camBank)] call BIS_fnc_setPitchBank; + }; + }; +}, 0] call CBA_fnc_addPerFrameHandler; diff --git a/addons/spectator/functions/fnc_handleInterface.sqf b/addons/spectator/functions/fnc_handleInterface.sqf index 04061a843b..bf3f7d0590 100644 --- a/addons/spectator/functions/fnc_handleInterface.sqf +++ b/addons/spectator/functions/fnc_handleInterface.sqf @@ -29,13 +29,33 @@ switch (toLower _mode) do { if !(isNull (GETUVAR(GVAR(display),displayNull))) exitWith {}; // Initalize preserved variables + if (isNil QGVAR(camMode)) then { GVAR(camMode) = 0; }; + if (isNil QGVAR(camPan)) then { GVAR(camPan) = 0; }; + if (isNil QGVAR(camPos)) then { GVAR(camPos) = getPos cameraOn; }; + if (isNil QGVAR(savedSpots)) then { GVAR(savedSpots) = []; }; if (isNil QGVAR(savedUnits)) then { GVAR(savedUnits) = []; }; + // Initalize camera variables + GVAR(camBank) = 0; + GVAR(camBoom) = [false,false]; + GVAR(camDolly) = [false,false,false,false]; + GVAR(camFocus) = [-1,-1]; + GVAR(camSpeed) = 0.8; + GVAR(camTilt) = -60; + + // Initalize display variables + GVAR(ctrlKey) = false; + GVAR(mouse) = [false,false]; + GVAR(mouseDelta) = [0.5,0.5]; + GVAR(mousePos) = [0.5,0.5]; + GVAR(mousePosOld) = [0.5,0.5]; + // Initalize the camera view GVAR(camera) = "Camera" camCreate GVAR(camPos); - GVAR(camera) setDir GVAR(camDir); + GVAR(camera) setDir GVAR(camPan); GVAR(camera) cameraEffect ["internal", "back"]; + call FUNC(handleCamera); // Create the dialog createDialog QGVAR(overlay); @@ -61,6 +81,21 @@ switch (toLower _mode) do { // Return to player view ACE_Player switchCamera "internal"; + // Cleanup camera variables + GVAR(camera) = nil; + GVAR(camBank) = nil; + GVAR(camBoom) = nil; + GVAR(camDolly) = nil; + GVAR(camFocus) = nil; + GVAR(camSpeed) = nil; + GVAR(camTilt) = nil; + + // Cleanup display variables + GVAR(mouse) = nil; + GVAR(mouseDelta) = nil; + GVAR(mousePos) = nil; + GVAR(mousePosOld) = nil; + // Reset nametag settings if (["ace_nametags"] call EFUNC(common,isModLoaded)) then { EGVAR(nametags,showPlayerNames) = GVAR(nametagSettingCache) select 0; @@ -81,6 +116,9 @@ switch (toLower _mode) do { (_display displayCtrl IDC_MAP) ctrlShow false; (_display displayCtrl IDC_MAP) mapCenterOnCamera false; + // Set text values + (_display displayCtrl IDC_VIEW) ctrlSetText (["FREE","FIRST","THIRD"] select GVAR(camMode)); + // Populate unit tree //["onload",_display displayCtrl IDC_TREE] call FUNC(handleTree); @@ -93,6 +131,29 @@ switch (toLower _mode) do { GVAR(display) = nil; }; }; + // Mouse events + case "onmousebuttondown": { + private ["_button"]; + _button = _args select 1; + GVAR(mouse) set [_button,true]; + }; + case "onmousebuttonup": { + private ["_button"]; + _button = _args select 1; + GVAR(mouse) set [_button,false]; + }; + case "onmousezchanged": { + private ["_zChange"]; + _zChange = _args select 1; + }; + case "onmousemoving": { + private ["_x","_y"]; + _x = _args select 1; + _y = _args select 2; + + GVAR(mousePos) = [_x,_y]; + call FUNC(handleMouse); + }; // Keyboard events case "onkeydown": { private ["_display","_dik","_shift","_ctrl","_alt"]; @@ -113,6 +174,27 @@ switch (toLower _mode) do { _tree ctrlShow _show; }; + case 16: { // Q + GVAR(camBoom) set [0,true]; + }; + case 17: { // W + GVAR(camDolly) set [0,true]; + }; + case 29: { // Ctrl + GVAR(ctrlKey) = true; + }; + case 30: { // A + GVAR(camDolly) set [2,true]; + }; + case 31: { // S + GVAR(camDolly) set [1,true]; + }; + case 32: { // D + GVAR(camDolly) set [3,true]; + }; + case 44: { // Z + GVAR(camBoom) set [1,true]; + }; case 50: { // M private ["_map","_show"]; _map = _display displayCtrl IDC_MAP; @@ -134,6 +216,27 @@ switch (toLower _mode) do { _alt = _args select 4; switch (_dik) do { + case 16: { // Q + GVAR(camBoom) set [0,false]; + }; + case 17: { // W + GVAR(camDolly) set [0,false]; + }; + case 29: { // Ctrl + GVAR(ctrlKey) = false; + }; + case 30: { // A + GVAR(camDolly) set [2,false]; + }; + case 31: { // S + GVAR(camDolly) set [1,false]; + }; + case 32: { // D + GVAR(camDolly) set [3,false]; + }; + case 44: { // Z + GVAR(camBoom) set [1,false]; + }; }; true diff --git a/addons/spectator/functions/fnc_handleMouse.sqf b/addons/spectator/functions/fnc_handleMouse.sqf new file mode 100644 index 0000000000..a44dccd737 --- /dev/null +++ b/addons/spectator/functions/fnc_handleMouse.sqf @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +private ["_x","_y","_leftButton","_rightButton","_oldX","_oldY","_deltaX","_deltaY","_angleY","_angleX"]; + +_x = GVAR(mousePos) select 0; +_y = GVAR(mousePos) select 1; +_leftButton = GVAR(mouse) select 0; +_rightButton = GVAR(mouse) select 1; + +_oldX = GVAR(mousePosOld) select 0; +_oldY = GVAR(mousePosOld) select 1; + +// Get change in pos +_deltaX = _oldX - _x; +_deltaY = _oldY - _y; +GVAR(mouseDelta) = [_deltaX, _deltaY]; + +if (_rightButton && !_leftButton) then { + GVAR(camPan) = GVAR(camPan) - (_deltaX * 360); + GVAR(camTilt) = ((GVAR(camTilt) + (_deltaY * 180)) min 89) max -89; +}; + +GVAR(mousePosOld) = [_x,_y];