mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-10 04:31:34 -10:00
abs is for ints fabsf is for floats (camera.cpp) make the in-cockpit stuff OGL friendly
289 lines
9.1 KiB
C++
289 lines
9.1 KiB
C++
#include "camera/camera.h"
|
|
#include "math/vecmat.h"
|
|
#include "graphics/2d.h"
|
|
#include "globalincs/alphacolors.h"
|
|
|
|
//Some global cameras
|
|
camera free_camera;
|
|
|
|
//This is where the camera class beings! :D
|
|
camera::camera()
|
|
{
|
|
//These are our two pointers, new'd and delete'd only by this class
|
|
desired_position = NULL;
|
|
desired_orientation = NULL;
|
|
|
|
reset();
|
|
}
|
|
|
|
camera::~camera()
|
|
{
|
|
//Cleanup
|
|
if(desired_position != NULL)
|
|
delete desired_position;
|
|
|
|
if(desired_orientation != NULL)
|
|
delete desired_orientation;
|
|
}
|
|
|
|
void camera::reset()
|
|
{
|
|
memset(&position, 0, sizeof(position));
|
|
if(desired_position != NULL)
|
|
{
|
|
delete desired_position;
|
|
desired_position = NULL;
|
|
}
|
|
translation_velocity = translation_vel_limit = translation_acc_limit = vmd_zero_vector;
|
|
|
|
vm_set_identity(&orientation);
|
|
if(desired_orientation != NULL)
|
|
{
|
|
delete desired_orientation;
|
|
desired_orientation = NULL;
|
|
}
|
|
rotation_rate = rotation_vel_limit = rotation_acc_limit = vmd_zero_vector;
|
|
}
|
|
|
|
void camera::set_position(vector *in_position, float in_translation_time, float in_translation_acceleration_time)
|
|
{
|
|
position = *in_position;
|
|
|
|
}
|
|
|
|
void camera::set_translation_velocity(vector *in_velocity)
|
|
{
|
|
if(in_velocity == NULL)
|
|
translation_velocity = *in_velocity;
|
|
else
|
|
vm_vec_zero(&translation_velocity);
|
|
}
|
|
|
|
#define square(a) (a*a)
|
|
void camera::set_rotation(matrix *in_orientation, float in_rotation_time, float in_rotation_acceleration_time)
|
|
{
|
|
if(in_rotation_time > 0.0f || in_rotation_acceleration_time > 0.0f)
|
|
{
|
|
//Safeties
|
|
if(in_rotation_acceleration_time <= 0.0f)
|
|
in_rotation_acceleration_time = 1.0f;
|
|
if(in_rotation_time <= 0.0f)
|
|
in_rotation_time = 3.0f;
|
|
if(in_rotation_acceleration_time*2.0f > in_rotation_time)
|
|
in_rotation_acceleration_time = in_rotation_time/2.0f;
|
|
|
|
//Get the angles in radians
|
|
angles curr_orientation, new_orientation;
|
|
vm_extract_angles_matrix(&curr_orientation, &orientation);
|
|
vm_extract_angles_matrix(&new_orientation, in_orientation);
|
|
|
|
//Find the distance
|
|
angles d;
|
|
d.p = new_orientation.p - curr_orientation.p;
|
|
d.b = new_orientation.b - curr_orientation.b;
|
|
d.h = new_orientation.h - curr_orientation.h;
|
|
/*d.p = curr_orientation.p - new_orientation.p;
|
|
d.b = curr_orientation.b - new_orientation.b;
|
|
d.h = curr_orientation.h - new_orientation.h;*/
|
|
|
|
/*ad_dist = -(V/At)square((At));
|
|
|
|
((Xf - Xo) - ad_dist)/V*/
|
|
|
|
/*v.p = (-(in_rotation_time - 2.0f*(in_rotation_acceleration_time)) + sqrt(square(in_rotation_time-2.0f*(in_rotation_acceleration_time))) + 4.0f*(curr_orientation.p - new_orientation.p))/2;
|
|
v.b = (-(in_rotation_time - 2.0f*(in_rotation_acceleration_time)) + sqrt(square(in_rotation_time-2.0f*(in_rotation_acceleration_time))) + 4.0f*(curr_orientation.b - new_orientation.b))/2;
|
|
v.h = (-(in_rotation_time - 2.0f*(in_rotation_acceleration_time)) + sqrt(square(in_rotation_time-2.0f*(in_rotation_acceleration_time))) + 4.0f*(curr_orientation.h - new_orientation.h))/2;*/
|
|
/*v.p = (new_orientation.p - curr_orientation.p)/(in_rotation_time - in_rotation_acceleration_time);
|
|
v.b = (new_orientation.p - curr_orientation.p)/(in_rotation_time - in_rotation_acceleration_time);
|
|
v.h = (new_orientation.p - curr_orientation.p)/(in_rotation_time - in_rotation_acceleration_time);*/
|
|
|
|
/*
|
|
angles *U = &rotation_rate;
|
|
|
|
float At = in_rotation_acceleration_time;
|
|
float t = in_rotation_time; //- 2.0f*At*/
|
|
/*v.p = ((d.p/At - U->p)/t);
|
|
v.b = ((d.b/At - U->b)/t);
|
|
v.h = ((d.h/At - U->h)/t);*/
|
|
/*v.p = ((d.p - U->p*At)/t);
|
|
v.b = ((d.b - U->b*At)/t);
|
|
v.h = ((d.h - U->h*At)/t);*/
|
|
|
|
//Set the desired orientation
|
|
if(desired_orientation == NULL)
|
|
desired_orientation = new matrix;
|
|
|
|
if(in_orientation != NULL)
|
|
*desired_orientation = *in_orientation;
|
|
else
|
|
vm_set_identity(desired_orientation);
|
|
|
|
//Calculate the maximum acceleration speed
|
|
rotation_acc_limit.xyz.z = fabsf(d.p / ((in_rotation_time * in_rotation_acceleration_time) - square(in_rotation_acceleration_time)));
|
|
rotation_acc_limit.xyz.x = fabsf(d.b / ((in_rotation_time * in_rotation_acceleration_time) - square(in_rotation_acceleration_time)));
|
|
rotation_acc_limit.xyz.y = fabsf(d.h / ((in_rotation_time * in_rotation_acceleration_time) - square(in_rotation_acceleration_time)));
|
|
|
|
//Calculate the maximum velocity
|
|
rotation_vel_limit.xyz.x = fabsf(rotation_acc_limit.xyz.x * in_rotation_acceleration_time);
|
|
rotation_vel_limit.xyz.y = fabsf(rotation_acc_limit.xyz.y * in_rotation_acceleration_time);
|
|
rotation_vel_limit.xyz.z = fabsf(rotation_acc_limit.xyz.z * in_rotation_acceleration_time);
|
|
|
|
//rotation_rate_delta_time = rotation_rate_delta_time_left = in_rotation_acceleration_time;
|
|
//rotation_rate_decel_time_til = in_rotation_time - in_rotation_acceleration_time;
|
|
|
|
//set_rotation_rate(&v, in_rotation_acceleration_time);
|
|
|
|
//rotation_rate_decel_time_til = in_rotation_time - in_rotation_acceleration_time;
|
|
}
|
|
else
|
|
{
|
|
if(in_orientation != NULL)
|
|
orientation = *in_orientation;
|
|
else
|
|
vm_set_identity(&orientation);
|
|
|
|
set_rotation_velocity(NULL);
|
|
}
|
|
}
|
|
|
|
void camera::set_rotation(angles *in_angles, float in_rotation_time, float in_rotation_acceleration_time)
|
|
{
|
|
matrix temp_matrix = IDENTITY_MATRIX;
|
|
|
|
if(in_angles != NULL)
|
|
vm_angles_2_matrix(&temp_matrix, in_angles);
|
|
|
|
set_rotation(&temp_matrix, in_rotation_time, in_rotation_acceleration_time);
|
|
}
|
|
|
|
void camera::set_rotation_facing(vector *in_target, float in_rotation_time, float in_rotation_acceleration_time)
|
|
{
|
|
matrix temp_matrix = IDENTITY_MATRIX;
|
|
|
|
if(in_target != NULL)
|
|
{
|
|
vector targetvec;
|
|
vm_vec_normalized_dir(&targetvec, in_target, &position);
|
|
vm_vector_2_matrix(&temp_matrix, &targetvec, NULL, NULL);
|
|
}
|
|
|
|
set_rotation(&temp_matrix, in_rotation_time, in_rotation_acceleration_time);
|
|
}
|
|
|
|
void camera::set_rotation_velocity(vector *in_rotation_rate)
|
|
{
|
|
if(in_rotation_rate == NULL)
|
|
rotation_rate = *in_rotation_rate;
|
|
else
|
|
vm_vec_zero(&rotation_rate);
|
|
|
|
/*if(in_rotation_rate == NULL)
|
|
{
|
|
rotation_rate.p = rotation_rate.b = rotation_rate.h = 0.0f;
|
|
|
|
rotation_rate_delta_time = rotation_rate_delta_time_left = in_rotation_acceleration_time = 0.0f;
|
|
rotation_rate_decel_time_til = -1.0f;
|
|
return;
|
|
}
|
|
|
|
rotation_rate_delta_time = rotation_rate_delta_time_left = in_rotation_acceleration_time;
|
|
rotation_rate_decel_time_til = -1.0f;
|
|
|
|
rotation_rate_delta.p = in_rotation_rate->p / in_rotation_acceleration_time;
|
|
rotation_rate_delta.b = in_rotation_rate->b / in_rotation_acceleration_time;
|
|
rotation_rate_delta.h = in_rotation_rate->h / in_rotation_acceleration_time;*/
|
|
}
|
|
|
|
void camera::do_movement(float in_frametime)
|
|
{
|
|
//float frametime, rot_frametime, trans_frametime;
|
|
//DO ROTATION STUFF
|
|
if(desired_orientation != NULL)
|
|
{
|
|
matrix ori_out;
|
|
vector vel_out;
|
|
|
|
vm_matrix_interpolate(desired_orientation, &orientation, &rotation_rate, in_frametime, &ori_out, &vel_out, &rotation_vel_limit, &rotation_acc_limit, 1);
|
|
orientation = ori_out;
|
|
rotation_rate = vel_out;
|
|
|
|
//TODO: Make this "if(*desired_orienation == orientation)"
|
|
if(vel_out.xyz.x == 0.0f && vel_out.xyz.y == 0.0f && vel_out.xyz.z == 0.0f)
|
|
{
|
|
delete desired_orientation;
|
|
desired_orientation = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//TODO: Make this right.
|
|
angles new_orientation;
|
|
vm_angles_2_matrix(&orientation, &new_orientation);
|
|
new_orientation.p = rotation_rate.xyz.z;
|
|
new_orientation.b = rotation_rate.xyz.x;
|
|
new_orientation.h = rotation_rate.xyz.y;
|
|
vm_angles_2_matrix(&orientation, &new_orientation);
|
|
}
|
|
|
|
/* rot_frametime = trans_frametime = in_frametime;
|
|
|
|
do
|
|
{
|
|
frametime = rot_frametime;
|
|
if(rotation_rate_delta_time_left || rotation_rate_decel_time_til > 0.0f)
|
|
{
|
|
if(frametime > rotation_rate_delta_time_left && rotation_rate_delta_time_left)
|
|
frametime = rotation_rate_delta_time_left;
|
|
if(frametime > rotation_rate_decel_time_til && rotation_rate_decel_time_til > 0.0f)
|
|
frametime = rotation_rate_decel_time_til;
|
|
|
|
if(rotation_rate_delta_time_left)
|
|
{
|
|
rotation_rate.p += (rotation_rate_delta.p) * frametime;
|
|
rotation_rate.b += (rotation_rate_delta.b) * frametime;
|
|
rotation_rate.h += (rotation_rate_delta.h) * frametime;
|
|
}
|
|
|
|
//mprintf(("DX:%f DY:%f DZ:%f",rotation_rate_delta.p,rotation_rate_delta.b,rotation_rate_delta.h));
|
|
//mprintf(( " X:%f", rotation_rate.p));
|
|
//mprintf(( " Y:%f", rotation_rate.b));
|
|
//mprintf(( " Z:%f\n", rotation_rate.h));
|
|
|
|
if(rotation_rate_delta_time_left)
|
|
{
|
|
rotation_rate_delta_time_left -= frametime;
|
|
}
|
|
if(rotation_rate_decel_time_til > 0.0f)
|
|
{
|
|
rotation_rate_decel_time_til -= frametime;
|
|
if(rotation_rate_decel_time_til == 0.0f)
|
|
{
|
|
rotation_rate_delta.p *= -1.0f;
|
|
rotation_rate_delta.b *= -1.0f;
|
|
rotation_rate_delta.h *= -1.0f;
|
|
|
|
rotation_rate_delta_time_left = rotation_rate_delta_time;
|
|
rotation_rate_decel_time_til = -1.0f;
|
|
}
|
|
}
|
|
}
|
|
rot_frametime -= frametime;
|
|
} while(rot_frametime);*/
|
|
|
|
//DO TRANSLATION STUFF
|
|
// float frametime = in_frametime;
|
|
/*if(translation_time_left)
|
|
{
|
|
if(in_frametime > translation_time_left)
|
|
frametime = translation_time_left;
|
|
else
|
|
frametime = in_frametime;
|
|
|
|
vm_vec_scale_add2(&translation_velocity, &translation_velocity_delta, frametime);
|
|
|
|
translation_time_left -= frametime;
|
|
}*/
|
|
|
|
vm_vec_scale_add2(&position, &translation_velocity, in_frametime);
|
|
}
|