summaryrefslogtreecommitdiff
path: root/src/enhancements/freecam/freecam_engine.c
blob: 02501ba1fb11af2c64381c54cb0664003fe7de24 (plain)
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
#include <libultraship.h>
#include <macros.h>
#include <defines.h>
#include <common_structs.h>
#include "player_controller.h"
#include "code_80057C60.h"
#include "code_800029B0.h"
#include "code_80005FD0.h"
#include "racing/collision.h"
#include "main.h"
#include <camera.h>
#include "freecam_engine.h"

FreeCam freeCam;

#include <math.h>

f32 gDampValue = 0.99f;

void freecam_tick(Camera* camera, Vec3f forwardVector) {
    // Update FreeCam state
    camera->pos[0] += freeCam.velocity[0] * gDeltaTime;
    camera->pos[1] += freeCam.velocity[1] * gDeltaTime;
    camera->pos[2] += freeCam.velocity[2] * gDeltaTime;

    // Apply damping to velocity
    freeCam.velocity[0] *= gDampValue;
    freeCam.velocity[1] *= gDampValue;
    freeCam.velocity[2] *= gDampValue;

    camera->lookAt[0] = camera->pos[0] + forwardVector[0];
    camera->lookAt[1] = camera->pos[1] + forwardVector[1];
    camera->lookAt[2] = camera->pos[2] + forwardVector[2];
}

void freecam_calculate_forward_vector_allow_rotation(Camera* camera, Vec3f forwardVector) {
    // Convert yaw from 0-65535 to degrees
    f32 pitch = (camera->rot[2] / 65535.0f) * 360.0f;
    f32 yaw = (camera->rot[1] / 65535.0f) * 360.0f;

    // Convert degrees to radians
    pitch = pitch * M_PI / 180.0f;
    yaw = yaw * M_PI / 180.0f;

    // Calculate the forward vector based on yaw, ignoring pitch to keep height unchanged
    forwardVector[0] = -sinf(yaw);
    forwardVector[1] = -sinf(pitch); // Keep the height unchanged
    forwardVector[2] = cosf(yaw);
}

f32 gFreecamFollowFactor = 0.7;

void freecam_target_player(Camera* camera, Vec3f forwardVector) {
    // Apply damping to velocity
    freeCam.velocity[0] *= gDampValue;
    freeCam.velocity[1] *= gDampValue;
    freeCam.velocity[2] *= gDampValue;

    // Calculate the direction from the player to the camera
    f32 dirX = gPlayers[fRankIndex].pos[0] - camera->pos[0];
    f32 dirY = gPlayers[fRankIndex].pos[1] - camera->pos[1];
    f32 dirZ = gPlayers[fRankIndex].pos[2] - camera->pos[2];

    // Normalize the direction vector (if needed)
    f32 length = sqrtf(dirX * dirX + dirY * dirY + dirZ * dirZ);
    if (length > 0) {
        dirX /= length;
        dirY /= length;
        dirZ /= length;
    }

    // Update the camera's look-at direction
    camera->lookAt[0] = camera->pos[0] + dirX;
    camera->lookAt[1] = camera->pos[1] + dirY;
    camera->lookAt[2] = camera->pos[2] + dirZ;

    // Calculate the forward vector based on the updated look-at direction
    forwardVector[0] = camera->lookAt[0] - camera->pos[0];
    forwardVector[1] = camera->lookAt[1] - camera->pos[1];
    forwardVector[2] = camera->lookAt[2] - camera->pos[2];

    // Normalize the forward vector
    f32 forwardLength = sqrtf(forwardVector[0] * forwardVector[0] + forwardVector[1] * forwardVector[1] +
                              forwardVector[2] * forwardVector[2]);
    if (forwardLength > 0.0f) {
        forwardVector[0] /= forwardLength;
        forwardVector[1] /= forwardLength;
        forwardVector[2] /= forwardLength;
    }

    // Store or return the forward vector as needed for subsequent movement calculations
    freeCam.forwardVector[0] = forwardVector[0];
    freeCam.forwardVector[1] = forwardVector[1];
    freeCam.forwardVector[2] = forwardVector[2];

    // Movement
    freeCam.velocity[0] += gPlayers[fRankIndex].velocity[0] * gFreecamFollowFactor;
    freeCam.velocity[1] += gPlayers[fRankIndex].velocity[1] * gFreecamFollowFactor;
    freeCam.velocity[2] += gPlayers[fRankIndex].velocity[2] * gFreecamFollowFactor;
}

void freecam_get_player_from_character(s32 characterId) {
    for (size_t i = 0; i < NUM_PLAYERS; i++) {
        if (gPlayers[i].characterId == characterId) {
            fRankIndex = i;
        }
    }
}