Files
fs2open.github.com/code/camera/camera.cpp
T
taylor bec567bbab fix an issue with bm_set_components()
abs is for ints fabsf is for floats (camera.cpp)
make the in-cockpit stuff OGL friendly
2005-02-10 14:38:50 +00:00

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);
}