Skip to content

Commit

Permalink
Change spectator external camera behaviour
Browse files Browse the repository at this point in the history
Using the "external" view is limited by the server difficulty setting. Instead the spectator external camera has been replaced with an oribtal camera as was originally planned to be added alongside the default views.
  • Loading branch information
kymckay committed Sep 11, 2015
1 parent 17f9eab commit 77c2b99
Show file tree
Hide file tree
Showing 11 changed files with 105 additions and 56 deletions.
1 change: 1 addition & 0 deletions addons/spectator/XEH_preInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ GVAR(availableSides) = [west,east,resistance,civilian];
GVAR(availableVisions) = [-2,-1,0,1];

GVAR(camAgent) = objNull;
GVAR(camDistance) = 10;
GVAR(camMode) = 0;
GVAR(camPan) = 0;
GVAR(camPos) = ATLtoASL [worldSize * 0.5, worldSize * 0.5, 20];
Expand Down
64 changes: 44 additions & 20 deletions addons/spectator/functions/fnc_handleCamera.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,53 @@
// Kill PFH when not in free cam (or display is closed)
if (isNil QGVAR(camHandler)) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; };

private ["_camera","_oldPos","_altMod","_zoomMod","_mX","_mY","_mZ","_pan","_x","_y","_z"];
private ["_camera","_pan","_tilt","_x","_y","_z"];

_camera = GVAR(camera);
_oldPos = getPosASL _camera;
_pan = (GVAR(camPan) + 360) % 360;
_tilt = GVAR(camTilt);

// Dolly/Boom amount should be influnced by zoom level (it should really be exponential)
// Dollying should also slow as the camera gets close to the ground
_zoomMod = (GVAR(camZoom) * 0.8) max 1;
_altMod = ((((getPos _camera) select 2) * 0.05) max 0.1) min 1;
if (GVAR(camMode) == 0) then {
private ["_oldPos","_altMod","_zoomMod","_mX","_mY","_mZ"];
_camera = GVAR(freeCamera);
_oldPos = GVAR(camPos);

_mX = (GVAR(camDolly) select 0) * _altMod / _zoomMod;
_mY = (GVAR(camDolly) select 1) * _altMod / _zoomMod;
_mZ = GVAR(camBoom) / _zoomMod;
// Dolly/Boom amount should be influnced by zoom level (it should really be exponential)
// Dollying should also slow as the camera gets close to the ground
_zoomMod = (GVAR(camZoom) * 0.8) max 1;
_altMod = ((((getPos _camera) select 2) * 0.05) max 0.1) min 1;

_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;
_mX = (GVAR(camDolly) select 0) * _altMod / _zoomMod;
_mY = (GVAR(camDolly) select 1) * _altMod / _zoomMod;
_mZ = GVAR(camBoom) / _zoomMod;

_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
_camera setPosASL GVAR(camPos);
_camera setDir _pan;
[_camera, _tilt, 0] call BIS_fnc_setPitchBank;
} else {
private ["_unit","_target","_distance"];
_camera = GVAR(unitCamera);

_unit = GVAR(camUnit);
_target = GVAR(targetCamera);
_distance = GVAR(camDistance);

_x = sin(_pan)*_distance*cos(_tilt);
_y = cos(_pan)*_distance*cos(_tilt);
_z = sin(_tilt) * (2 * (0.3 max _distance));

// Prevent camera going under terrain
GVAR(camPos) = [_x,_y,_z max (getTerrainHeightASL [_x,_y])];
// Update the position of the target camera (used for smooth unit tracking)
_target camSetPos ((_unit modelToWorldVisual [0,0,0]) vectorAdd [0,0,1.5]);
_target camCommit 0;

// Update camera position and rotation
_camera setPosASL GVAR(camPos);
_camera setDir GVAR(camPan);
[_camera, GVAR(camTilt), 0] call BIS_fnc_setPitchBank;
// Update the relative position of the unit camera
_camera camSetRelPos [_x, _y, _z];
_camera camCommit 0;
};
2 changes: 1 addition & 1 deletion addons/spectator/functions/fnc_handleIcons.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ if !(GVAR(showIcons)) exitWith {};
private ["_refPoint","_drawVehicles","_leader","_color","_txt","_unit"];

// Draw groups unless leader is within distance
_refPoint = [GVAR(camera),GVAR(camUnit)] select (GVAR(camMode) > 0);
_refPoint = [GVAR(freeCamera),GVAR(camUnit)] select (GVAR(camMode) > 0);
_drawVehicles = [];
{
_leader = leader _x;
Expand Down
13 changes: 9 additions & 4 deletions addons/spectator/functions/fnc_handleInterface.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,16 @@ switch (toLower _mode) do {
case "onmousezchanged": {
_args params ["_ctrl","_zChange"];

// Scroll to change speed, modifier for zoom
if (GVAR(ctrlKey)) then {
[nil,nil,nil,nil,nil,nil,nil, GVAR(camSpeed) + _zChange * 0.2] call FUNC(setCameraAttributes);
// Scroll to modify distance value in third person
if (GVAR(camMode) == 0) then {
// Scroll to change speed, modifier for zoom
if (GVAR(ctrlKey)) then {
[nil,nil,nil,nil,nil,nil,nil, GVAR(camSpeed) + _zChange * 0.2] call FUNC(setCameraAttributes);
} else {
[nil,nil,nil,nil,nil,nil, GVAR(camZoom) + _zChange * 0.1] call FUNC(setCameraAttributes);
};
} else {
[nil,nil,nil,nil,nil,nil, GVAR(camZoom) + _zChange * 0.1] call FUNC(setCameraAttributes);
GVAR(camDistance) = ((GVAR(camDistance) - _zChange * 2) max 5) min 50;
};
};
case "onmousemoving": {
Expand Down
2 changes: 1 addition & 1 deletion addons/spectator/functions/fnc_handleMap.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ params ["_map"];
private ["_cachedVehicles","_unit","_color","_icon","_txt"];

if (GVAR(camMode) == 0) then {
_map drawIcon ["\A3\UI_F\Data\GUI\Rsc\RscDisplayMissionEditor\iconcamera_ca.paa",[0,0,0,1],GVAR(camera),20,20,GVAR(camPan)];
_map drawIcon ["\A3\UI_F\Data\GUI\Rsc\RscDisplayMissionEditor\iconcamera_ca.paa",[0,0,0,1],GVAR(freeCamera),20,20,GVAR(camPan)];
};

_cachedVehicles = [];
Expand Down
8 changes: 4 additions & 4 deletions addons/spectator/functions/fnc_setCameraAttributes.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ GVAR(camVision) = _vision;
GVAR(camZoom) = (_zoom min 2) max 0.01;

// Apply if camera exists
if (isNil QGVAR(camera)) then {
if (GVAR(isSet)) then {
GVAR(freeCamera) setPosATL _position;
[_mode,_unit,_vision] call FUNC(transitionCamera);
} else {
GVAR(camMode) = _mode;
GVAR(camPos) = (ATLtoASL _position);
} else {
[_mode,_unit,_vision] call FUNC(transitionCamera);
GVAR(camera) setPosATL _position;
};
20 changes: 15 additions & 5 deletions addons/spectator/functions/fnc_setSpectator.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,14 @@ if (_set) then {
// Update units before opening to support pre-set camera unit
[] call FUNC(updateUnits);

// Initalize the camera view
GVAR(camera) = "Camera" camCreate (ASLtoATL GVAR(camPos));
// Initalize the camera objects
GVAR(freeCamera) = "Camera" camCreate (ASLtoATL GVAR(camPos));
GVAR(unitCamera) = "Camera" camCreate [0,0,0];
GVAR(targetCamera) = "Camera" camCreate [0,0,0];

// Initalize view
GVAR(unitCamera) camSetTarget GVAR(targetCamera);
GVAR(unitCamera) camCommit 0;
[] call FUNC(transitionCamera);

// Close map and clear radio
Expand Down Expand Up @@ -85,8 +91,10 @@ if (_set) then {
(findDisplay 12249) closeDisplay 0;

// Terminate camera
GVAR(camera) cameraEffect ["terminate", "back"];
camDestroy GVAR(camera);
GVAR(freeCamera) cameraEffect ["terminate", "back"];
camDestroy GVAR(freeCamera);
camDestroy GVAR(unitCamera);
camDestroy GVAR(targetCamera);

clearRadio;

Expand All @@ -97,10 +105,12 @@ if (_set) then {
BIS_fnc_feedback_allowPP = true;

// Cleanup camera variables
GVAR(camera) = nil;
GVAR(camBoom) = nil;
GVAR(camDolly) = nil;
GVAR(camGun) = nil;
GVAR(freeCamera) = nil;
GVAR(unitCamera) = nil;
GVAR(targetCamera) = nil;

// Cleanup display variables
GVAR(ctrlKey) = nil;
Expand Down
2 changes: 1 addition & 1 deletion addons/spectator/functions/fnc_toggleInterface.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ if (GVAR(showMap)) then {

// Centre map on camera/unit upon opening
if (_toggleMap) then {
_map ctrlMapAnimAdd [0, 0.5, [GVAR(camUnit),GVAR(camera)] select (GVAR(camMode) == 0)];
_map ctrlMapAnimAdd [0, 0.5, [GVAR(camUnit),GVAR(freeCamera)] select (GVAR(camMode) == 0)];
ctrlMapAnimCommit _map;
};
} else {
Expand Down
45 changes: 27 additions & 18 deletions addons/spectator/functions/fnc_transitionCamera.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,17 @@ if (_newMode != 1) then {
GVAR(camGun) = false;
};

private ["_camera"];
if (_newMode == 0) then { // Free
_camera = GVAR(freeCamera);

// Preserve camUnit value for consistency when manually changing view
GVAR(camera) cameraEffect ["internal", "back"];
_camera cameraEffect ["internal", "back"];
showCinemaBorder false;
cameraEffectEnableHUD true;

// Apply the camera zoom
GVAR(camera) camSetFov -(linearConversion [0.01,2,GVAR(camZoom),-2,-0.01,true]);
GVAR(camera) camCommit 0;
_camera camSetFov -(linearConversion [0.01,2,GVAR(camZoom),-2,-0.01,true]);
_camera camCommit 0;

// Agent is switched to in free cam to hide death table and prevent AI chat while allowing icons to draw (also prevents systemChat and unit HUD)
// (Why is so much stuff tied into the current camera unit BI?!)
Expand Down Expand Up @@ -79,20 +81,32 @@ if (_newMode == 0) then { // Free
// Handle camera movement
if (isNil QGVAR(camHandler)) then { GVAR(camHandler) = [FUNC(handleCamera), 0] call CBA_fnc_addPerFrameHandler; };
} else {
_camera = GVAR(unitCamera);

// When null unit is given choose random
if (isNull _newUnit) then {
_newUnit = GVAR(unitList) select floor(random(count GVAR(unitList)));
};

if (_newMode == 1) then { // Internal
// Handle gun cam
if (GVAR(camGun)) then {
_newUnit switchCamera "gunner";
} else {
_newUnit switchCamera "internal";
};
} else { // External
_newUnit switchCamera "external";
// Switch camera view to internal unit view (external uses the camera)
if (GVAR(camGun)) then {
_newUnit switchCamera "gunner";
} else {
_newUnit switchCamera "internal";
};

// Handle camera differently for internal/external view
if (_newMode == 1) then {
// Terminate camera view
_camera cameraEffect ["terminate", "back"];
GVAR(camHandler) = nil;
} else {
// Switch to the camera
_camera cameraEffect ["internal", "back"];
showCinemaBorder false;

// Handle camera orbit movement
if (isNil QGVAR(camHandler)) then { GVAR(camHandler) = [FUNC(handleCamera), 0] call CBA_fnc_addPerFrameHandler; };
};

// Clear radio if group changed
Expand All @@ -101,11 +115,6 @@ if (_newMode == 0) then { // Free
};

GVAR(camUnit) = _newUnit;

// Terminate camera view
GVAR(camera) cameraEffect ["terminate", "back"];
GVAR(camHandler) = nil;
cameraEffectEnableHUD true;
};

GVAR(camMode) = _newMode;
2 changes: 1 addition & 1 deletion addons/spectator/functions/fnc_updateCameraModes.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ if (_newModes isEqualTo []) then {
};

// Update camera in case of change
if !(isNil QGVAR(camera)) then {
if (GVAR(isSet)) then {
[] call FUNC(transitionCamera);
};

Expand Down
2 changes: 1 addition & 1 deletion addons/spectator/functions/fnc_updateVisionModes.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ if (_newModes isEqualTo []) then {
};

// Update camera in case of change
if !(isNil QGVAR(camera)) then {
if (GVAR(isSet)) then {
[] call FUNC(transitionCamera);
};

Expand Down

0 comments on commit 77c2b99

Please sign in to comment.