-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathCameraController.cpp
More file actions
200 lines (161 loc) · 9.52 KB
/
CameraController.cpp
File metadata and controls
200 lines (161 loc) · 9.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#include "CameraController.h"
void CameraController::ProcessCameraMatrix(float delta) {
if (settingsManager->debugMod) uevr::API::get()->log_info("ProcessCameraMatrix()");
// Update the camera position based on the head's socket location
Utilities::ParameterGetSocketLocation socketLocation_params{};
socketLocation_params.inSocketName = uevr::API::FName(L"head");
playerManager->playerHead->call_function(L"GetSocketLocation", &socketLocation_params);
Utilities::ParameterSingleVector3 forwardVector_params{};
Utilities::ParameterSingleVector3 upVector_params{};
Utilities::ParameterSingleVector3 rightVector_params{};
playerManager->playerHead->call_function(L"GetForwardVector", &forwardVector_params);
playerManager->playerHead->call_function(L"GetUpVector", &upVector_params);
playerManager->playerHead->call_function(L"GetRightVector", &rightVector_params);
// Camera Matrix rotation ---------------------------------------------------
UEVR_Vector2f rightJoystick{};
uevr::API::get()->param()->vr->get_joystick_axis(uevr::API::get()->param()->vr->get_right_joystick_source(), &rightJoystick);
// Create a rotation matrix from the head's forward, up, and right vectors
glm::mat4 headRotationMatrix = glm::mat4(1.0f);
headRotationMatrix[0] = glm::vec4(-forwardVector_params.vec3Value.x, forwardVector_params.vec3Value.y, -forwardVector_params.vec3Value.z, 0.0f);
headRotationMatrix[1] = glm::vec4(-rightVector_params.vec3Value.x, rightVector_params.vec3Value.y, -rightVector_params.vec3Value.z, 0.0f); // Right vector
headRotationMatrix[2] = glm::vec4(upVector_params.vec3Value.x, -upVector_params.vec3Value.y, upVector_params.vec3Value.z, 0.0f); // Up vector
float joystickYaw = 0.0f;
// Reset the accumulated joystick rotation when going in or out of a vehicle
if (playerManager->isInVehicle && !playerManager->wasInVehicle)
{
accumulatedJoystickRotation = glm::mat4(1.0f);
}
if ((!playerManager->isInVehicle && playerManager->wasInVehicle) || (!playerManager->isInVehicle && camResetRequested) || (previousCameraMode == Camera && currentCameraMode != Camera ))
{
accumulatedJoystickRotation = glm::mat4(1.0f);
baseHeadRotation = headRotationMatrix;
}
// Calculate the delta rotation matrix, basically the rotation of the vehicle we're driving if any.
glm::mat4 deltaRotationMatrix = playerManager->isInVehicle && currentCameraMode != AimWeaponFromCar ? glm::inverse(accumulatedJoystickRotation) * headRotationMatrix : glm::inverse(accumulatedJoystickRotation) * baseHeadRotation;
// Joystick input to adjust the camera yaw rotation
if (abs(rightJoystick.x) > settingsManager->joystickDeadzone) {
joystickYaw = -rightJoystick.x * delta * settingsManager->xAxisSensitivity;
}
// Convert joystick yaw to radians
float yawRadians = joystickYaw * (M_PI / 180.0f);
// Create rotation matrice
glm::mat4 joystickYawRotation = glm::rotate(glm::mat4(1.0f), yawRadians, glm::vec3(0.0f, 0.0f, 1.0f)); // Rotate around world Y-axis
// Combine the accumulatedJoystickRotation with the joystick rotations
accumulatedJoystickRotation = accumulatedJoystickRotation * joystickYawRotation;
// Combine the accumulatedJoystickRotation with the delta rotation so camera follows the car when driving
glm::mat4 totalDeltaRotation = accumulatedJoystickRotation * deltaRotationMatrix;
// Combine the head rotation matrix with the joystick rotations
glm::mat4 finalRotationMatrix = accumulatedJoystickRotation * totalDeltaRotation;
// Copy the modified matrix back to cameraMatrixValues
for (int i = 0; i < 16; ++i) {
cameraMatrixValues[i] = finalRotationMatrix[i / 4][i % 4];
}
//Runs if player loads a save or after a cinematic, resets the camera to the camera heading direction
if (camResetRequested) {
cameraMatrixValues[0] = -1;
cameraMatrixValues[5] = 1;
cameraMatrixValues[10] = 1;
}
// Letting the original code manage ingame camera position (not the uevr one) fixes the aim in car issue but
// also keeps the original audio listener position. Attempt to mitigate it by disabling the overwrite only when shooting in car.
if (currentCameraMode == AimWeaponFromCar || !playerManager->isInVehicle || !playerManager->shootFromCarInput)
{
glm::fvec3 offsetedPosition = Utilities::OffsetLocalPositionFromWorld(socketLocation_params.outLocation, forwardVector_params.vec3Value, upVector_params.vec3Value, rightVector_params.vec3Value, glm::fvec3(49.5, 0.0, 0.0));
cameraMatrixValues[12] = offsetedPosition.x * 0.01f;
cameraMatrixValues[13] = -offsetedPosition.y * 0.01f;
cameraMatrixValues[14] = offsetedPosition.z * 0.01f;
}
UpdateCameraMatrix();
// Update some vars. The game's source code doesn't use the Unreal Engine unit scale.
// GTA SA original unit scale = UE Scale / 100.
playerManager->actualPlayerPositionUE = socketLocation_params.outLocation;
playerManager->actualPlayerHeadPositionUE = glm::fvec3(playerManager->actualPlayerPositionUE.x,
playerManager->actualPlayerPositionUE.y,
(currentCameraMode == HelicannonFirstPerson ? *(reinterpret_cast<float*>(memoryManager->playerPositionAddresses[2])) + 0.5f : *(reinterpret_cast<float*>(memoryManager->playerHeadPositionAddresses[2]))) * 100);
cameraPositionUE = glm::fvec3(*(reinterpret_cast<float*>(memoryManager->cameraPositionAddresses[0])) * 100,
-*(reinterpret_cast<float*>(memoryManager->cameraPositionAddresses[1])) * 100,
*(reinterpret_cast<float*>(memoryManager->cameraPositionAddresses[2])) * 100);
rightVectorUE = glm::fvec3(*(reinterpret_cast<float*>(memoryManager->cameraMatrixAddresses[0])),
-*(reinterpret_cast<float*>(memoryManager->cameraMatrixAddresses[1])),
*(reinterpret_cast<float*>(memoryManager->cameraMatrixAddresses[2])));
upVectorUE = glm::fvec3(*(reinterpret_cast<float*>(memoryManager->cameraMatrixAddresses[8])),
-*(reinterpret_cast<float*>(memoryManager->cameraMatrixAddresses[9])),
*(reinterpret_cast<float*>(memoryManager->cameraMatrixAddresses[10])));
camResetRequested = false;
}
void CameraController::UpdateCameraMatrix()
{
if (settingsManager->debugMod) uevr::API::get()->log_info("UpdateCameraMatrix()");
if (currentCameraMode == Camera )
return;
// Write the modified matrix back to memory
int arrayMaxIndex = playerManager->isInVehicle ? 12 : 15; //let the game handle the ingame camera position when driving
for (int i = 0; i < arrayMaxIndex; ++i) {
*(reinterpret_cast<float*>(memoryManager->cameraMatrixAddresses[i])) = cameraMatrixValues[i];
}
}
//Handles the VR camera height. Allows it to follow the crouch animation or to be correctly positioned in different camera mods.
void CameraController::ProcessHookedHeadPosition(float delta)
{
if (settingsManager->debugMod) uevr::API::get()->log_info("ProcessHookedHeadPosition()");
if (currentCameraMode != Fixed && previousCameraMode == Fixed )
keepCameraHeight = true ;
//Workaround : Forces the VR camera height when player is in his garage.
if (playerManager->isInVehicle || currentCameraMode == Fixed || keepCameraHeight)
{
Utilities::Parameter_K2_SetWorldOrRelativeLocation setRelativeLocation_params{};
setRelativeLocation_params.bSweep = false;
setRelativeLocation_params.bTeleport = true;
// check vehicleType == 13 to offset the bikes camera position
setRelativeLocation_params.newLocation = playerManager->vehicleType == 13 && playerManager->isInVehicle ? playerManager->defaultPlayerHeadLocalPositionUE + playerManager->defaultBikeLocalOffsetUE : playerManager->defaultPlayerHeadLocalPositionUE;
playerManager->playerHead->call_function(L"K2_SetRelativeLocation", &setRelativeLocation_params);
keepCameraHeightTimer += keepCameraHeight ? delta : 0.0f;
if (keepCameraHeightTimer >= keepCameraHeightTime)
{
keepCameraHeight = false;
keepCameraHeightTimer = 0.0f;
}
return;
}
//Fixes the VR camera height when player handles the camera weapon.
if (currentCameraMode == Camera )
{
Utilities::Parameter_K2_SetWorldOrRelativeLocation setWorldLocation_params{};
setWorldLocation_params.bSweep = false;
setWorldLocation_params.bTeleport = true;
setWorldLocation_params.newLocation = cameraPositionUE;
playerManager->playerHead->call_function(L"K2_SetWorldLocation", &setWorldLocation_params);
return;
}
Utilities::Parameter_K2_SetWorldOrRelativeLocation setWorldLocation_params{};
setWorldLocation_params.bSweep = false;
setWorldLocation_params.bTeleport = true;
setWorldLocation_params.newLocation = playerManager->actualPlayerHeadPositionUE;
playerManager->playerHead->call_function(L"K2_SetWorldLocation", &setWorldLocation_params);
}
void CameraController::FixUnderwaterView(bool enableFix)
{
if (settingsManager->debugMod) uevr::API::get()->log_info("FixUnderwaterView()");
const auto underwaterMaterial = uevr::API::get()->find_uobject(L"MaterialInstanceConstant /Game/Common/Materials/VGD/Instances/MI_Underwater_VGD.MI_Underwater_VGD");
//API::get()->log_info("underwaterMaterial : %ls", underwaterMaterial->get_full_name().c_str());
underwaterMaterial->set_bool_property(L"bHasStaticPermutationResource", enableFix);
underwaterViewFixed = enableFix;
}
std::string CameraController::VehicleCameraModeToString(VehicleCameraMode cameraMode)
{
switch (cameraMode) {
case VehicleCameraMode::Road: return "Road";
case VehicleCameraMode::Close: return "FPS";
case VehicleCameraMode::Normal: return "Normal";
case VehicleCameraMode::Far: return "Far";
case VehicleCameraMode::Cinematic: return "Cinematic";
}
}
std::string CameraController::OnFootCameraModeToString(OnFootCameraMode cameraMode)
{
switch (cameraMode) {
case OnFootCameraMode::Close: return "FPS";
case OnFootCameraMode::Normal: return "Normal";
case OnFootCameraMode::Far: return "Far";
}
}