Skip to content

Commit

Permalink
Merge pull request pnill#503 from Berthalamew/interpolation_new
Browse files Browse the repository at this point in the history
rewrite player_effect_apply_camera_effect_matrix function
  • Loading branch information
Kantanomo authored Dec 27, 2023
2 parents 7f5a002 + 6f04349 commit 93b965c
Show file tree
Hide file tree
Showing 21 changed files with 1,452 additions and 53 deletions.
3 changes: 2 additions & 1 deletion xlive/Blam/Engine/effects/particle_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
#include "particle_system.h"


enum e_particle_state_flags : uint32 {
enum e_particle_state_flags : uint32
{
_particle_update_flag_0 = FLAG(0),
_particle_update_flag_1 = FLAG(1),
_particle_update_flag_2 = FLAG(2),
Expand Down
178 changes: 178 additions & 0 deletions xlive/Blam/Engine/effects/player_effects.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,186 @@
#include "stdafx.h"
#include "player_effects.h"

#include "Blam/Engine/game/game_time.h"
#include "Blam/Engine/game/player_vibration.h"
#include "Blam/Engine/main/interpolator.h"
#include "Blam/Engine/math/random_math.h"

void player_effect_apply_camera_effect_matrix_internal(real_matrix4x3* matrix, real32 a2, real32 a3);
real32 player_effect_transition_function_evaluate(e_transition_function_type function_type, real32 a2, real32 a3, real32 a4);

s_player_effect_globals* player_effect_globals_get(void)
{
return *Memory::GetAddress<s_player_effect_globals**>(0x4CE860, 0x4F504C);
}

s_player_effect_user_globals* player_effects_get_user_globals(int32 user_index)
{
return &player_effect_globals_get()->user_effects[user_index];
}

/*
void __cdecl player_effect_apply_camera_effect_matrix(int32 user_index, real_matrix4x3* matrix)
{
INVOKE(0xA432D, 0x963AA, player_effect_apply_camera_effect_matrix, user_index, matrix);
return;
}*/

void player_effect_apply_camera_effect_matrix(int32 user_index, real_matrix4x3* matrix)
{
real_matrix4x3 calculated_matrix;
if (user_index != NONE)
{
s_player_effect_globals* player_effects_globals = player_effect_globals_get();
if (player_effects_globals->flags.test(_player_effect_global_bit_0))
{
real32 vibration_intensity = player_effects_globals->max_intensity;
calculated_matrix = global_identity4x3;

if (player_effects_globals->attack_time_ticks > 0)
{
real32 attack_time = player_effects_globals->attack_time_ticks / player_effects_globals->attack_time_ticks_1;
if (!player_effects_globals->flags.test(_player_effect_global_bit_1))
{
attack_time = 1.0f - attack_time;
}

vibration_intensity *= attack_time;
}

if (vibration_intensity >= 0.0f)
{
if (vibration_intensity > 1.0f)
{
vibration_intensity = 1.0f;
}
}
else
{
vibration_intensity = 0.0f;
}

rumble_player_set_scripted_scale(vibration_intensity);

real_vector3d random_angles;
random_angles.k = _real_random_range(get_local_random_seed_address(), -1.0f, 1.0f);
random_angles.j = _real_random_range(get_local_random_seed_address(), -1.0f, 1.0f);
random_angles.i = _real_random_range(get_local_random_seed_address(), -1.0f, 1.0f);
multiply_vectors3d(&random_angles, &player_effects_globals->position.orientation, &random_angles);
scale_vector3d(&random_angles, vibration_intensity, &random_angles);

matrix4x3_rotation_from_angles(&calculated_matrix, random_angles.i, random_angles.j, random_angles.k);

random_angles.i = _real_random_range(get_local_random_seed_address(), -1.0f, 1.0f);
random_angles.j = _real_random_range(get_local_random_seed_address(), -1.0f, 1.0f);
random_angles.k = _real_random_range(get_local_random_seed_address(), -1.0f, 1.0f);

calculated_matrix.position.x = random_angles.i * player_effects_globals->position.position.y * vibration_intensity;
calculated_matrix.position.y = random_angles.j * player_effects_globals->position.position.x * vibration_intensity;
calculated_matrix.position.z = random_angles.k * player_effects_globals->position.position.z * vibration_intensity;
matrix4x3_multiply(matrix, &calculated_matrix, matrix);
}
else
{
s_player_effect_user_globals* user_effect = &player_effects_globals->user_effects[user_index];
bool bit_1_result = user_effect->flags.test(_player_effect_user_global_bit_1);
if (user_effect->field_80 > 0 || bit_1_result)
{
real32 function_result;
if (bit_1_result)
{
function_result = 1.0f;
}
else
{
real32 timing = user_effect->camera_impulse.duration - *(real32*)(&user_effect->field_80) - halo_interpolator_get_interpolation_time();
function_result = player_effect_transition_function_evaluate((e_transition_function_type)user_effect->camera_impulse.fade_function, user_effect->transition_function_scale_9C, timing, user_effect->camera_impulse.duration);
}

real_vector3d vector;
cross_product3d(&global_up3d, &user_effect->vector_0, &vector);

real32 function_result_scaled = user_effect->camera_impulse.rotation * function_result;
matrix4x3_rotation_from_axis_and_angle(&calculated_matrix, &vector, sin(function_result_scaled), cos(function_result_scaled));

real32 position_scaler = user_effect->camera_impulse.pushback * function_result;
calculated_matrix.position.x = user_effect->vector_0.i * position_scaler;
calculated_matrix.position.y = user_effect->vector_0.j * position_scaler;
calculated_matrix.position.z = user_effect->vector_0.k * position_scaler;
point_from_line3d(&calculated_matrix.position, &user_effect->vector_C, function_result, &calculated_matrix.position);
matrix4x3_multiply(matrix, &calculated_matrix, matrix);
}

bool bit_2_result = user_effect->flags.test(_player_effect_user_global_bit_2);
if (user_effect->field_82 > 0 || bit_2_result)
{
calculated_matrix = global_identity4x3;

real32 transition_function_result;
real32 field_82_real = (real32)user_effect->field_82;
real32 timing = user_effect->camera_shaking.duration - game_ticks_to_seconds(*(real32*)(&user_effect->field_82)) - halo_interpolator_get_interpolation_time();
if (bit_2_result)
{
transition_function_result = 1.0f;
}
else
{
transition_function_result = player_effect_transition_function_evaluate((e_transition_function_type)user_effect->camera_shaking.falloff_function, user_effect->transition_function_scale_98, timing, user_effect->camera_shaking.duration);
}

real32 seconds_result = timing / user_effect->camera_shaking.wobble_function_period;
real32 periodic_function_result = periodic_function_evaluate(user_effect->camera_shaking.wobble_function, seconds_result);
real32 periodic_function_result_scaled = periodic_function_result * transition_function_result * user_effect->camera_shaking.wobble_weight + transition_function_result * (1.0 - user_effect->camera_shaking.wobble_weight);

// Set v1 to 0 if v1_value is less than 0
real32 v1_value = user_effect->camera_shaking.random_translation * periodic_function_result_scaled;
real32 v1 = (v1_value <= 0.0f ? 0.0f : v1_value);

// Set v2 to 0 if v2_value is less than 0
real32 v2_value = user_effect->camera_shaking.random_rotation * periodic_function_result_scaled;
real32 v2 = (v2_value <= 0.0f ? 0.0f : v2_value);

if (user_effect->field_7C > 0)
{
real32 seconds_7C = game_ticks_to_seconds(*(real32*)(&user_effect->field_7C));
real32 seconds_7C_x2 = seconds_7C + seconds_7C;

v1 += seconds_7C_x2 * user_effect->field_74;
v2 += seconds_7C_x2 * user_effect->field_78;

rumble_player_continuous(user_index, user_effect->rumble_intensity_left, user_effect->rumble_intensity_right);
}
player_effect_apply_camera_effect_matrix_internal(&calculated_matrix, v1, v2);
matrix4x3_multiply(matrix, &calculated_matrix, matrix);
}
}
}

return;
}


void player_effect_apply_camera_effect_matrix_internal(real_matrix4x3* matrix, real32 a2, real32 a3)
{
real_vector3d vector;

if (a3 != 0.0f)
{
_random_direction3d(get_local_random_seed_address(), NULL, __FILE__, __LINE__, &vector);
matrix4x3_rotation_from_axis_and_angle(matrix, &vector, sin(a3), cos(a3));
}
if (a2 != 0.0f)
{
_random_direction3d(get_local_random_seed_address(), NULL, __FILE__, __LINE__, &vector);
matrix->position.x = vector.i * a2;
matrix->position.y = vector.j * a2;
matrix->position.z = vector.k * a2;
}
return;
}

real32 player_effect_transition_function_evaluate(e_transition_function_type function_type, real32 a2, real32 a3, real32 a4)
{
real32 function_value = 1.0f - (a3 / a4);
return transition_function_evaluate(function_type, function_value) * a2;
}
90 changes: 89 additions & 1 deletion xlive/Blam/Engine/effects/player_effects.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,92 @@
#pragma once
#include "Blam/Engine/camera/observer.h"
#include "Blam/Engine/math/matrix_math.h"
#include "Blam/Engine/math/periodic_functions.h"
#include "Blam/Engine/Networking/Session/NetworkSession.h"

void __cdecl player_effect_apply_camera_effect_matrix(int32 user_index, real_matrix4x3* matrix);
enum e_player_effect_user_global_flags : uint8
{
_player_effect_user_global_bit_0 = 0,
_player_effect_user_global_bit_1 = 1,
_player_effect_user_global_bit_2 = 2,
k_player_effect_user_global_flag_count
};

enum e_player_effect_global_flags : uint32
{
_player_effect_global_bit_0 = 0,
_player_effect_global_bit_1 = 1,
k_player_effect_global_flag_count
};

struct s_temporary_camera_impulse
{
real32 duration;
int8 fade_function; // e_transition_function_type
int8 pad;
real32 rotation;
real32 pushback;
real_bounds jitter;
};
CHECK_STRUCT_SIZE(s_temporary_camera_impulse, 24);

struct s_player_effect_camera_shaking
{
real32 duration;
int8 falloff_function; // e_transition_function_type
real32 random_translation;
real_angle random_rotation;
e_periodic_function_type wobble_function;
real32 wobble_function_period;
real32 wobble_weight;
};
CHECK_STRUCT_SIZE(s_player_effect_camera_shaking, 28);

struct s_player_effect_user_globals
{
real_vector3d vector_0;
real_vector3d vector_C;
int16 field_18;
int16 pad_1A;
real32 field_1C;
e_transition_function_type screen_flash_function;
int16 pad;
real32 field_24;
real_argb_color screen_flash_color;
s_temporary_camera_impulse camera_impulse;
s_player_effect_camera_shaking camera_shaking;
real32 rumble_intensity_left;
real32 rumble_intensity_right;
real32 field_74;
real32 field_78;
int16 field_7C;
int16 game_time;
int16 field_80;
int16 field_82;
int8 field_84[4];
c_flags<e_player_effect_user_global_flags, uint8, k_player_effect_user_global_flag_count> flags;
int8 field_89;
int16 pad_8A;
real_point3d origin;
real32 transition_function_scale_98;
real32 transition_function_scale_9C;
};
CHECK_STRUCT_SIZE(s_player_effect_user_globals, 160);

struct s_player_effect_globals
{
int32 field_0;
int16 field_4;
bool field_6;
int8 field_7;
s_observer_command_displacement position;
real32 max_intensity;
int16 attack_time_ticks;
int16 attack_time_ticks_1;
c_flags<e_player_effect_global_flags, uint32, k_player_effect_global_flag_count> flags;
uint32 current_time_ticks;
s_player_effect_user_globals user_effects[k_number_of_users];
};
CHECK_STRUCT_SIZE(s_player_effect_globals, 688);

void player_effect_apply_camera_effect_matrix(int32 user_index, real_matrix4x3* matrix);
8 changes: 7 additions & 1 deletion xlive/Blam/Engine/game/player_vibration.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
#include "stdafx.h"
#include "player_vibration.h"

void rumble_player_set_scripted_scale(real32 scale)
void __cdecl rumble_player_set_scripted_scale(real32 scale)
{
INVOKE(0x9004F, 0x8EC60, rumble_player_set_scripted_scale, scale);
return;
}

void __cdecl rumble_player_continuous(int32 user_index, real32 rumble_intensity_left, real32 rumble_intensity_right)
{
INVOKE(0x90222, 0x8EE33, rumble_player_continuous, user_index, rumble_intensity_left, rumble_intensity_right);
return;
}
4 changes: 3 additions & 1 deletion xlive/Blam/Engine/game/player_vibration.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#pragma once

void rumble_player_set_scripted_scale(real32 scale);
void __cdecl rumble_player_set_scripted_scale(real32 scale);

void __cdecl rumble_player_continuous(int32 user_index, real32 rumble_intensity_left, real32 rumble_intensity_right);
4 changes: 2 additions & 2 deletions xlive/Blam/Engine/interface/first_person_weapons.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ void __cdecl first_person_weapons_update_nodes(int32 user_index, int32 weapon_sl
// Clear weapon orientations
if (node_count > 0)
{
for (uint32 i = 0; i < weapon_data->node_orientations_count; i++)
for (int32 i = 0; i < weapon_data->node_orientations_count; i++)
{
memcpy(fp_orientations->weapon_orientations, &global_identity_orientation, sizeof(real_orientation));
}
Expand Down Expand Up @@ -585,7 +585,7 @@ void __cdecl first_person_weapon_build_model_nodes(int32 node_matrices_count,
{
if (node_matrices_count > 0)
{
for (uint32 node_index = 0; node_index < node_matrices_count; node_index++)
for (int32 node_index = 0; node_index < node_matrices_count; node_index++)
{
matrix4x3_multiply(camera_matrix, &node_matrices[node_index], &fp_model_data->nodes[node_index]);
}
Expand Down
4 changes: 2 additions & 2 deletions xlive/Blam/Engine/main/interpolator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ bool halo_interpolator_interpolate_object_node_matrices(datum object_index, real
(*node_matrices) = g_frame_data_intermediate->object_data[out_abs_object_index].node_matrices;
if (*out_node_count > 0)
{
for (uint32 node_index = 0; node_index < *out_node_count; node_index++)
for (int32 node_index = 0; node_index < *out_node_count; node_index++)
{
real_point3d* target_position = &g_target_interpolation_frame_data->object_data[out_abs_object_index].node_matrices[node_index].position;
real_point3d* previous_position = &g_previous_interpolation_frame_data->object_data[out_abs_object_index].node_matrices[node_index].position;
Expand Down Expand Up @@ -344,7 +344,7 @@ bool halo_interpolator_interpolate_weapon(datum user_index, datum animation_inde
if (target_node_count > 0 && target_node_count == previous_node_count)
{
*nodes = g_frame_data_intermediate->weapon_data[user_index][weapon_slot].nodes;
for (uint32 node_index = 0; node_index < target_node_count; node_index++)
for (int32 node_index = 0; node_index < target_node_count; node_index++)
{
matrix4x3_interpolate(&g_previous_interpolation_frame_data->weapon_data[user_index][weapon_slot].nodes[node_index],
&g_target_interpolation_frame_data->weapon_data[user_index][weapon_slot].nodes[node_index],
Expand Down
34 changes: 34 additions & 0 deletions xlive/Blam/Engine/math/matrix_math.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,40 @@ real_vector3d* matrix4x3_transform_vector(const real_matrix4x3* matrix, const re
return out;
}

real_matrix4x3* matrix4x3_rotation_from_angles(real_matrix4x3* matrix, real32 i, real32 j, real32 k)
{
matrix->scale = 1.0f;

real_vector3d cosine_vector;
cosine_vector.i = cos(i);
cosine_vector.j = cos(j);
cosine_vector.k = cos(k);

real_vector3d sine_vector;
sine_vector.i = sin(i);
sine_vector.j = sin(j);
sine_vector.k = sin(k);

matrix->vectors.forward.j = (sine_vector.i * cosine_vector.k) - ((sine_vector.j * sine_vector.k) * cosine_vector.i);
matrix->vectors.forward.i = cosine_vector.i * cosine_vector.j;
matrix->vectors.forward.k = ((sine_vector.j * cosine_vector.k) * cosine_vector.i) + (sine_vector.i * sine_vector.k);
matrix->vectors.left.i = -(cosine_vector.j * sine_vector.i);
matrix->vectors.left.j = ((sine_vector.j * sine_vector.k) * sine_vector.i) + (cosine_vector.i * cosine_vector.k);
matrix->vectors.up.i = -0.0f - sine_vector.j;
matrix->vectors.left.k = (cosine_vector.i * sine_vector.k) - ((sine_vector.j * cosine_vector.k) * sine_vector.i);
matrix->vectors.up.j = -0.0f - (cosine_vector.j * sine_vector.k);
matrix->vectors.up.k = cosine_vector.j * cosine_vector.k;
matrix->position.x = 0.0f;
matrix->position.y = 0.0f;
matrix->position.z = 0.0f;
return matrix;
}

real_matrix4x3* __cdecl matrix4x3_rotation_from_axis_and_angle(real_matrix4x3* matrix, real_vector3d* vector, real32 axis, real32 angle)
{
return INVOKE(0x775C1, 0x751B7, matrix4x3_rotation_from_axis_and_angle, matrix, vector, axis, angle);
}

void matrix4x3_interpolate(const real_matrix4x3* previous, const real_matrix4x3* target, real32 fractional_ticks, real_matrix4x3* out_mat)
{
real_quaternion q1_previous, q2_target, q3_interpolated;
Expand Down
Loading

0 comments on commit 93b965c

Please sign in to comment.