FS2_Open
Open source remastering of the Freespace 2 engine
camera.cpp
Go to the documentation of this file.
1 #include "camera/camera.h"
3 #include "globalincs/linklist.h"
4 #include "globalincs/systemvars.h" //VM_FREECAMERA etc
5 #include "graphics/font.h"
6 #include "hud/hud.h" //hud_get_draw
7 #include "math/vecmat.h"
8 #include "mod_table/mod_table.h"
9 #include "model/model.h" //polymodel, model_get
10 #include "parse/parselo.h"
11 #include "playerman/player.h" //player_get_padlock_orient
12 #include "ship/ship.h" //compute_slew_matrix
13 
14 //*************************IMPORTANT GLOBALS*************************
15 float VIEWER_ZOOM_DEFAULT = 0.75f; // Default viewer zoom, 0.625 as per multi-lateral agreement on 3/24/97
16 float Sexp_fov = 0.0f;
18 
19 //*************************OTHER STUFF*************************
20 //Some global vars
23 //Preset cameras
26 
27 //*************************CLASS: camera*************************
28 //This is where the camera class beings! :D
29 camera::camera(char *in_name, int in_signature)
30 {
31  set_name(in_name);
32  sig = in_signature;
33 
34  reset();
35 }
36 
38 {
39  //Check if this is in use
40  if(Current_camera.getSignature() == this->sig)
41  {
42  Current_camera = camid();
43  }
44 }
45 
47 {
48  strcpy_s(name, "");
49  sig = -1;
50  reset();
51 }
52 
54 {
56 
59 
63 
64  func_custom_position = NULL;
66 
67  fov.clear();
69 
70  pos_x.clear();
71  pos_y.clear();
72  pos_z.clear();
73 
74  for(int i = 0; i < 9; i++)
75  {
76  ori[i].clear();
78  }
79 }
80 
81 void camera::set_name(char *in_name)
82 {
83  if(in_name != NULL)
84  strncpy(name, in_name, NAME_LENGTH-1);
85 }
86 
87 void camera::set_fov(float in_fov, float in_fov_time, float in_fov_acceleration_time, float in_fov_deceleration_time)
88 {
89  if(in_fov_time == 0.0f && in_fov_acceleration_time == 0.0f && in_fov_deceleration_time == 0.0f)
90  {
92  c_fov = in_fov;
93  return;
94  }
95 
97  if(in_fov <= 0.0f)
98  {
99  fov.setVD(in_fov_time, in_fov_acceleration_time, 0.0f);
100  }
101 
102  fov.setAVD(in_fov, in_fov_time, in_fov_acceleration_time, in_fov_deceleration_time, 0.0f);
103 }
104 
105 void camera::set_object_host(object *objp, int n_object_host_submodel)
106 {
107  if(objp == NULL)
108  object_host = object_h();
109 
110  object_host = object_h(objp);
111  object_host_submodel = n_object_host_submodel;
114  if(n_object_host_submodel > 0)
115  {
116  if(objp->type == OBJ_SHIP)
117  {
119  while ( ssp != END_OF_LIST( &Ships[objp->instance].subsys_list ) )
120  {
121  if(ssp->system_info->subobj_num == n_object_host_submodel)
122  {
123  if(ssp->system_info->type == SUBSYSTEM_TURRET)
124  {
127  }
128  }
129  ssp = GET_NEXT( ssp );
130  }
131  }
132  }
133 }
134 
135 void camera::set_object_target(object *objp, int n_object_target_submodel)
136 {
137  if(objp == NULL)
139 
140  object_target = object_h(objp);
141  object_target_submodel = n_object_target_submodel;
142 }
143 
148 void camera::set_custom_position_function(void (*n_func_custom_position)(camera *cam, vec3d *camera_pos))
149 {
150  func_custom_position = n_func_custom_position;
151 }
152 
157 void camera::set_custom_orientation_function(void (*n_func_custom_orientation)(camera *cam, matrix *camera_ori))
158 {
159  func_custom_orientation = n_func_custom_orientation;
160 }
161 
162 void camera::set_position(vec3d *in_position, float in_translation_time, float in_translation_acceleration_time, float in_translation_deceleration_time, float in_end_velocity)
163 {
164  if(in_position != NULL && in_translation_time == 0.0f && in_translation_acceleration_time == 0.0f && in_translation_deceleration_time == 0.0f)
165  {
166  c_pos = *in_position;
167  pos_x.set(c_pos.xyz.x);
168  pos_y.set(c_pos.xyz.y);
169  pos_z.set(c_pos.xyz.z);
171  return;
172  }
173 
175  if(in_position == NULL)
176  {
177  pos_x.setVD(in_translation_time, in_translation_acceleration_time, in_end_velocity);
178  pos_y.setVD(in_translation_time, in_translation_acceleration_time, in_end_velocity);
179  pos_z.setVD(in_translation_time, in_translation_acceleration_time, in_end_velocity);
180  return;
181  }
182 
183  pos_x.setAVD(in_position->xyz.x, in_translation_time, in_translation_acceleration_time, in_translation_deceleration_time, in_end_velocity);
184  pos_y.setAVD(in_position->xyz.y, in_translation_time, in_translation_acceleration_time, in_translation_deceleration_time, in_end_velocity);
185  pos_z.setAVD(in_position->xyz.z, in_translation_time, in_translation_acceleration_time, in_translation_deceleration_time, in_end_velocity);
186 }
187 
188 void camera::set_translation_velocity(vec3d *in_velocity, float in_acceleration_time)
189 {
190  pos_x.setVD(in_acceleration_time, in_acceleration_time, in_velocity->xyz.x);
191  pos_y.setVD(in_acceleration_time, in_acceleration_time, in_velocity->xyz.y);
192  pos_z.setVD(in_acceleration_time, in_acceleration_time, in_velocity->xyz.z);
193 }
194 
195 void camera::set_rotation(matrix *in_orientation, float in_rotation_time, float in_rotation_acceleration_time, float in_rotation_deceleration_time)
196 {
197  if(in_orientation != NULL && in_rotation_time == 0.0f && in_rotation_acceleration_time == 0.0f && in_rotation_deceleration_time == 0.0f)
198  {
199  c_ori = *in_orientation;
200  for(int i = 0; i < 9; i++)
201  ori[i].set(in_orientation->a1d[i]);
203  return;
204  }
205 
207  if(in_orientation == NULL)
208  {
209  for(int i = 0; i < 9; i++)
210  ori[i].setVD(in_rotation_time, in_rotation_acceleration_time, 0.0f);
211  return;
212  }
213 
214  for(int i = 0; i < 9; i++)
215  ori[i].setAVD(in_orientation->a1d[i], in_rotation_time, in_rotation_acceleration_time, in_rotation_deceleration_time, 0.0f);
216 }
217 
218 void camera::set_rotation(angles *in_angles, float in_rotation_time, float in_rotation_acceleration_time, float in_rotation_deceleration_time)
219 {
220  matrix mtx = IDENTITY_MATRIX;
221  vm_rotate_matrix_by_angles(&mtx, in_angles);
222  this->set_rotation(&mtx, in_rotation_time, in_rotation_acceleration_time, in_rotation_deceleration_time);
223 }
224 
225 void camera::set_rotation_facing(vec3d *in_target, float in_rotation_time, float in_rotation_acceleration_time, float in_rotation_deceleration_time)
226 {
227  matrix temp_matrix = IDENTITY_MATRIX;
228 
229  if(in_target != NULL)
230  {
231  vec3d position = vmd_zero_vector;
232  this->get_info(&position, NULL);
233 
234  if(in_target->xyz.x == position.xyz.x && in_target->xyz.y == position.xyz.y && in_target->xyz.z == position.xyz.z)
235  {
236  Warning(LOCATION, "Camera tried to point to self");
237  return;
238  }
239 
240  vec3d targetvec;
241  vm_vec_normalized_dir(&targetvec, in_target, &position);
242  vm_vector_2_matrix(&temp_matrix, &targetvec, NULL, NULL);
243  }
244 
245  set_rotation(&temp_matrix, in_rotation_time, in_rotation_acceleration_time, in_rotation_deceleration_time);
246 }
247 
248 void camera::set_rotation_velocity(angles *in_rotation_rate, float in_acceleration_time)
249 {
250  Error(LOCATION, "This function is disabled until further notice.");
251 }
252 
253 void camera::do_frame(float in_frametime)
254 {
255 
256 }
257 
259 {
260  if(object_host.IsValid())
261  return object_host.objp;
262  else
263  return NULL;
264 }
265 
267 {
268  return object_host_submodel;
269 }
270 
272 {
273  if(object_target.IsValid())
274  return object_target.objp;
275  else
276  return NULL;
277 }
278 
280 {
281  return object_target_submodel;
282 }
283 
285 {
286  if(!(flags & CAM_STATIONARY_FOV))
287  {
288  fov.get(&c_fov, NULL);
289  }
290 
291  return c_fov;
292 }
293 
295 void camera::get_info(vec3d *position, matrix *orientation)
296 {
297  if(position == NULL && orientation == NULL)
298  return;
299 
300  eye* eyep = NULL;
301  vec3d host_normal;
302  //POSITION
304  {
306 
307  vec3d pt;
308  pos_x.get(&pt.xyz.x, NULL);
309  pos_y.get(&pt.xyz.y, NULL);
310  pos_z.get(&pt.xyz.z, NULL);
311 
312  if(object_host.IsValid())
313  {
314  object *objp = object_host.objp;
315  int model_num = object_get_model(objp);
316  polymodel *pm = NULL;
317 
318  if(model_num > -1)
319  {
320  pm = model_get(model_num);
321  }
322 
323  if(object_host_submodel < 0 || pm == NULL)
324  {
327  }
328  else
329  {
331  if(eyep)
332  {
333  Assertion(objp->type == OBJ_SHIP, "This part of the code expects the object to be a ship");
334 
335  vec3d c_pos_in;
336  find_submodel_instance_point_normal(&c_pos_in, &host_normal, Ships[objp->instance].model_instance_num, eyep->parent, &eyep->pnt, &eyep->norm);
337  vm_vec_unrotate(&c_pos, &c_pos_in, &objp->orient);
338  vm_vec_add2(&c_pos, &objp->pos);
339  }
340  else
341  {
342  model_find_world_point( &c_pos, &pt, pm->id, object_host_submodel, &objp->orient, &objp->pos );
343  }
344  }
345  }
346  else
347  {
348  c_pos = pt;
349  }
350 
351  //Do custom position stuff, if needed
352  if(func_custom_position != NULL && !eyep)
353  {
354  func_custom_position(this, &c_pos);
355  }
356  }
357 
358  if(position != NULL)
359  *position = c_pos;
360 
361  //ORIENTATION
362  if(orientation != NULL)
363  {
364  bool target_set = false;
366  {
367  if(object_target.IsValid())
368  {
369  object *objp = object_target.objp;
370  int model_num = object_get_model(objp);
371  polymodel *pm = NULL;
372  vec3d target_pos = vmd_zero_vector;
373 
374  //See if we can get the model
375  if(model_num > -1)
376  {
377  pm = model_get(model_num);
378  }
379 
380  //If we don't have a submodel or don't have the model use object pos
381  //Otherwise, find the submodel pos as it is rotated
382  if(object_target_submodel < 0 || pm == NULL)
383  {
384  target_pos = objp->pos;
385  }
386  else
387  {
388  model_find_world_point( &target_pos, &vmd_zero_vector, pm->id, object_target_submodel, &objp->orient, &objp->pos );
389  }
390 
391  vec3d targetvec;
392  vm_vec_normalized_dir(&targetvec, &target_pos, &c_pos);
393  vm_vector_2_matrix(&c_ori, &targetvec, NULL, NULL);
394  target_set = true;
395  }
396  else if(object_host.IsValid())
397  {
398  if(eyep)
399  {
400  vm_vector_2_matrix(&c_ori, &host_normal, vm_vec_same(&host_normal, &object_host.objp->orient.vec.uvec)?NULL:&object_host.objp->orient.vec.uvec, NULL);
401  target_set = true;
402  }
403  else
404  {
406  }
407  }
408  else
409  {
411  }
412 
413  matrix mtxA = c_ori;
414  matrix mtxB = IDENTITY_MATRIX;
415  float pos = 0.0f;
416  for(int i = 0; i < 9; i++)
417  {
418  ori[i].get(&pos, NULL);
419  mtxB.a1d[i] = pos;
420  }
421  vm_matrix_x_matrix(&c_ori, &mtxA, &mtxB);
422 
424  }
425  //Do custom orientation stuff, if needed
426  if(func_custom_orientation != NULL && !target_set)
427  {
429  }
430  *orientation = c_ori;
431  }
432 }
433 
434 //*************************warp_camera*************************
436 {
437  this->reset();
438 }
440 {
441  this->reset();
442 
443  vec3d object_pos = objp->pos;
444  matrix tmp;
445  ship_get_eye(&object_pos, &tmp, objp);
446 
447  vm_vec_scale_add2( &object_pos, &Player_obj->orient.vec.rvec, 0.0f );
448  vm_vec_scale_add2( &object_pos, &Player_obj->orient.vec.uvec, 0.952f );
449  vm_vec_scale_add2( &object_pos, &Player_obj->orient.vec.fvec, -1.782f );
450 
451  vec3d tmp_vel = { { { 0.0f, 5.1919f, 14.7f } } };
452 
453  this->set_position( &object_pos );
454  this->set_rotation( &objp->orient );
455  this->set_velocity( &tmp_vel, true);
456 }
457 
459 {
460  c_pos = c_vel = c_desired_vel = vmd_zero_vector;
461  c_ori = vmd_identity_matrix;
462  c_damping = 1.0f;
463  c_time = 0.0f;
464 }
465 
467 {
468  c_pos = *in_pos;
469 }
470 
472 {
473  c_ori = *in_ori;
474 }
475 
476 void warp_camera::set_velocity( vec3d *in_vel, bool instantaneous )
477 {
478  c_desired_vel.xyz.x = 0.0f;
479  c_desired_vel.xyz.y = 0.0f;
480  c_desired_vel.xyz.z = 0.0f;
481 
482  vm_vec_scale_add2( &c_desired_vel, &c_ori.vec.rvec, in_vel->xyz.x );
483  vm_vec_scale_add2( &c_desired_vel, &c_ori.vec.uvec, in_vel->xyz.y );
484  vm_vec_scale_add2( &c_desired_vel, &c_ori.vec.fvec, in_vel->xyz.z );
485 
486  if ( instantaneous ) {
487  c_vel = c_desired_vel;
488  }
489 
490 }
491 
492 void warp_camera::do_frame(float in_frametime)
493 {
494  vec3d new_vel, delta_pos;
495 
496  apply_physics( c_damping, c_desired_vel.xyz.x, c_vel.xyz.x, in_frametime, &new_vel.xyz.x, &delta_pos.xyz.x );
497  apply_physics( c_damping, c_desired_vel.xyz.y, c_vel.xyz.y, in_frametime, &new_vel.xyz.y, &delta_pos.xyz.y );
498  apply_physics( c_damping, c_desired_vel.xyz.z, c_vel.xyz.z, in_frametime, &new_vel.xyz.z, &delta_pos.xyz.z );
499 
500  c_vel = new_vel;
501 
502  vm_vec_add2( &c_pos, &delta_pos );
503 
504  float ot = c_time+0.0f;
505 
506  c_time += in_frametime;
507 
508  if ( (ot < 0.667f) && ( c_time >= 0.667f ) ) {
509  vec3d tmp;
510 
511  tmp.xyz.z = 4.739f; // always go this fast forward.
512 
513  // pick x and y velocities so they are always on a
514  // circle with a 25 m radius.
515 
516  float tmp_angle = frand()*PI2;
517 
518  tmp.xyz.x = 22.0f * sinf(tmp_angle);
519  tmp.xyz.y = -22.0f * cosf(tmp_angle);
520 
521  this->set_velocity( &tmp, 0 );
522  }
523 
524  if ( (ot < 3.0f ) && ( c_time >= 3.0f ) ) {
525  vec3d tmp = ZERO_VECTOR;
526  this->set_velocity( &tmp, 0 );
527  }
528 
529 }
530 
531 void warp_camera::get_info(vec3d *position, matrix *orientation)
532 {
533  if(position != NULL)
534  *position = c_pos;
535 
536  if(orientation != NULL)
537  *orientation = c_ori;
538 }
539 
540 //*************************subtitle*************************
541 
542 #define MAX_SUBTITLE_LINES 64
543 subtitle::subtitle(int in_x_pos, int in_y_pos, const char* in_text, const char* in_imageanim, float in_display_time,
544  float in_fade_time, const color *in_text_color, int in_text_fontnum, bool center_x, bool center_y, int in_width,
545  int in_height, bool in_post_shaded)
546  :display_time(-1.0f), fade_time(-1.0f), text_fontnum(-1), time_displayed(-1.0f), time_displayed_end(-1.0f),
547  post_shaded(false)
548 {
549  // Initialize color
550  gr_init_color(&text_color, 0, 0, 0);
551 
552  SCP_string text_buf;
553 
554  // basic init, this always has to be done
555  memset( imageanim, 0, sizeof(imageanim) );
556  memset( &text_pos, 0, 2*sizeof(int) );
557  memset( &image_pos, 0, 4*sizeof(int) );
558  image_id = -1;
559 
560  if ( ((in_text != NULL) && (strlen(in_text) <= 0)) && ((in_imageanim != NULL) && (strlen(in_imageanim) <= 0)) )
561  return;
562 
563  if (in_text != NULL && in_text[0] != '\0')
564  {
565  text_buf = in_text;
567  in_text = text_buf.c_str();
568  }
569 
570 
571  int num_text_lines = 0;
572  const char *text_line_ptrs[MAX_SUBTITLE_LINES];
573  int text_line_lens[MAX_SUBTITLE_LINES];
574 
575  //Setup text
576  if ( (in_text != NULL) && (in_text[0] != '\0') ) {
577  int split_width = (in_width > 0) ? in_width : 200;
578 
579  num_text_lines = split_str(in_text, split_width, text_line_lens, text_line_ptrs, MAX_SUBTITLE_LINES);
580  for(int i = 0; i < num_text_lines; i++)
581  {
582  text_buf.assign(text_line_ptrs[i], text_line_lens[i]);
583  text_lines.push_back(text_buf);
584  }
585  }
586 
587  //Setup text color
588  if(in_text_color != NULL)
589  text_color = *in_text_color;
590  else
591  gr_init_alphacolor(&text_color, 255, 255, 255, 255);
592  text_fontnum = in_text_fontnum;
593 
594  //Setup display and fade time
595  display_time = fl_abs(in_display_time);
596  fade_time = fl_abs(in_fade_time);
597 
598  //Setup image
599  if ( (in_imageanim != NULL) && (in_imageanim[0] != '\0') )
600  {
601  image_id = bm_load(in_imageanim);
602 
603  if (image_id >= 0)
604  strncpy(imageanim, in_imageanim, sizeof(imageanim) - 1);
605  }
606 
607  //Setup pos
608  int w=0, h=0, tw=0, th=0;
609  if(center_x || center_y)
610  {
611  // switch font because we need to measure it
612  int old_fontnum;
613  if (text_fontnum >= 0)
614  {
615  old_fontnum = gr_get_current_fontnum();
616  gr_set_font(text_fontnum);
617  }
618  else
619  {
620  old_fontnum = -1;
621  }
622 
623  //Get text size
624  for(int i = 0; i < num_text_lines; i++)
625  {
626  gr_get_string_size(&w, &h, text_line_ptrs[i], text_line_lens[i]);
627 
628  if(w > tw)
629  tw = w;
630 
631  th += h;
632  }
633 
634  // restore old font
635  if (old_fontnum >= 0)
636  {
637  gr_set_font(old_fontnum);
638  }
639 
640  //Get image size
641  if(image_id != -1)
642  {
643  bm_get_info(image_id, &w, &h);
644  if (in_width > 0)
645  w = in_width;
646  if (in_height > 0)
647  h = in_height;
648 
649  tw += w;
650  if(h > th)
651  th = h;
652  }
653 
654  //Center it?
655  if(center_x)
656  image_pos.x = (gr_screen.center_w - tw)/2 + gr_screen.center_offset_x;
657  if(center_y)
658  image_pos.y = (gr_screen.center_h - th)/2 + gr_screen.center_offset_y;
659  }
660 
661  if(in_x_pos < 0 && !center_x)
662  image_pos.x += gr_screen.center_offset_x + gr_screen.center_w + in_x_pos;
663  else if(!center_x)
664  image_pos.x += gr_screen.center_offset_x + in_x_pos;
665 
666  if(in_y_pos < 0 && !center_y)
667  image_pos.y += gr_screen.center_offset_y + gr_screen.center_h + in_y_pos;
668  else if(!center_y)
669  image_pos.y += gr_screen.center_offset_y + in_y_pos;
670 
671  image_pos.w = in_width;
672  image_pos.h = in_height;
673 
674  if(image_id != -1)
675  text_pos.x = image_pos.x + w; //Still set from bm_get_info call
676  else
677  text_pos.x = image_pos.x;
678  text_pos.y = image_pos.y;
679 
680  time_displayed = 0.0f;
681  time_displayed_end = 2.0f*fade_time + display_time;
682 
683  post_shaded = in_post_shaded;
684 }
685 
686 void subtitle::do_frame(float frametime)
687 {
688  //Figure out how much alpha
689  if(time_displayed < fade_time)
690  {
691  text_color.alpha = (ubyte)fl2i(255.0f*(time_displayed/fade_time));
692  }
693  else if(time_displayed > time_displayed_end)
694  {
695  //We're finished
696  return;
697  }
698  else if((time_displayed - fade_time) > display_time)
699  {
700  text_color.alpha = (ubyte)fl2i(255.0f*(1-(time_displayed - fade_time - display_time)/fade_time));
701  }
702  else
703  {
704  text_color.alpha = 255;
705  }
706 
707  gr_set_color_fast(&text_color);
708 
709  // save old font and set new font
710  int old_fontnum;
711  if (text_fontnum >= 0)
712  {
713  old_fontnum = gr_get_current_fontnum();
714  gr_set_font(text_fontnum);
715  }
716  else
717  {
718  old_fontnum = -1;
719  }
720 
721  int font_height = gr_get_font_height();
722  int x = text_pos.x;
723  int y = text_pos.y;
724 
725 
726  for(SCP_vector<SCP_string>::iterator line = text_lines.begin(); line != text_lines.end(); ++line)
727  {
728  gr_string(x, y, (char*)line->c_str(), GR_RESIZE_NONE);
729  y += font_height;
730  }
731 
732  // restore old font
733  if (old_fontnum >= 0)
734  {
735  gr_set_font(old_fontnum);
736  }
737 
738  if(image_id >= 0)
739  {
740  gr_set_bitmap(image_id, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, text_color.alpha/255.0f);
741 
742  // scaling?
743  if (image_pos.w > 0 || image_pos.h > 0)
744  {
745  int orig_w, orig_h;
746  vec3d scale;
747 
748  bm_get_info(image_id, &orig_w, &orig_h);
749  scale.xyz.x = (image_pos.w > 0) ? (image_pos.w / (float) orig_w) : 1.0f;
750  scale.xyz.y = (image_pos.h > 0) ? (image_pos.h / (float) orig_h) : 1.0f;
751  scale.xyz.z = 1.0f;
752 
753  gr_push_scale_matrix(&scale);
754  gr_bitmap(fl2i(image_pos.x / scale.xyz.x), fl2i(image_pos.y / scale.xyz.y), GR_RESIZE_NONE);
756  }
757  // no scaling
758  else
759  {
760  gr_bitmap(image_pos.x, image_pos.y, GR_RESIZE_NONE);
761  }
762  }
763 
764  time_displayed += frametime;
765 }
766 
768 {
769  if (image_id != -1) {
770  if ( bm_release(image_id) ) {
771  image_id = -1;
772  }
773  }
774 }
775 
776 void subtitle::clone(const subtitle &sub)
777 {
778 
779  text_lines = sub.text_lines;
780  text_fontnum = sub.text_fontnum;
781 
782  // copy the structs
783  text_pos = sub.text_pos;
784  image_pos = sub.image_pos;
785 
786  display_time = sub.display_time;
787  fade_time = sub.fade_time;
788  memcpy( &text_color, &sub.text_color, sizeof(color) );
789 
790  if ( strlen(sub.imageanim) ) {
791  memcpy( imageanim, sub.imageanim, MAX_FILENAME_LEN );
792  // we bm_load() again here to kick the refcount up
793  image_id = bm_load(imageanim);
794  } else {
795  memset( imageanim, 0, MAX_FILENAME_LEN );
796  image_id = -1;
797  }
798 
799  time_displayed = sub.time_displayed;
800  time_displayed_end = sub.time_displayed_end;
801 
802  post_shaded = sub.post_shaded;
803 }
804 
806 {
807  if (this != &sub) {
808  if (image_id != -1) {
809  if ( bm_release(image_id) ) {
810  image_id = -1;
811  }
812  }
813 
814  clone(sub);
815  }
816 
817  return *this;
818 }
819 
820 //*************************camid*************************
822 {
823  idx = 0;
824  sig = -1;
825 }
826 
827 camid::camid(int n_idx, int n_sig)
828 {
829  idx = n_idx;
830  sig = n_sig;
831 }
832 
834 {
835  if(!isValid())
836  return NULL;
837 
838  return Cameras[idx];
839 }
840 
842 {
843  return idx;
844 }
845 
847 {
848  return sig;
849 }
850 
852 {
853  if(idx >= Cameras.size())
854  return false;
855 
856  if(Cameras[idx] == NULL)
857  return false;
858 
859  if(Cameras[idx]->get_signature() != this->sig)
860  return false;
861 
862  return true;
863 }
864 
865 //*************************camera functions*************************
866 void cam_init()
867 {
868  //Rest FOV override
869  Sexp_fov = 0.0;
870 }
871 
872 void cam_close()
873 {
874  //Set Current_camera to nothing
875  Current_camera = camid();
876  for (auto ii = Cameras.begin(); ii != Cameras.end(); ++ii) {
877  delete * ii;
878  }
879  Cameras.clear();
880 }
881 
883 {
884  static int next_sig = 0;
885  return next_sig++;
886 }
887 
888 camid cam_create(char *n_name, vec3d *n_pos, vec3d *n_norm, object *n_object, int n_object_host_submodel)
889 {
890  matrix ori;
891  vm_vector_2_matrix_norm(&ori, n_norm);
892  return cam_create(n_name, n_pos, &ori, n_object, n_object_host_submodel);
893 }
894 
895 camid cam_create(char *n_name, vec3d *n_pos, matrix *n_ori, object *n_object, int n_object_host_submodel)
896 {
897  camera *cam = NULL;
898  camid cid;
899 
900  //Get signature
901  int sig = cam_get_next_sig();
902 
903  //Get name
904  char buf[NAME_LENGTH] = {'\0'};
905  if(n_name == NULL)
906  sprintf(buf, "Camera %d", cid.getSignature());
907  else
908  strncpy(buf, n_name, NAME_LENGTH-1);
909 
910  //Find a free slot
911  cam = new camera(buf, sig);
912  cid = camid(Cameras.size(), sig);
913  Cameras.push_back(cam);
914 
915  //Set attributes
916  if(n_pos != NULL)
917  cam->set_position(n_pos);
918  if(n_ori != NULL)
919  cam->set_rotation(n_ori);
920  if(n_object != NULL)
921  cam->set_object_host(n_object, n_object_host_submodel);
922 
923  return cid;
924 }
925 
926 void cam_delete(camid cid)
927 {
928  if(cid.isValid())
929  {
930  cid.getCamera()->clear();
931  }
932 }
933 
934 void cam_do_frame(float frametime)
935 {
936  size_t i,size=Cameras.size();
937  for(i = 0; i < size; i++)
938  {
939  if(Cameras[i] != NULL)
940  Cameras[i]->do_frame(frametime);
941  }
942 }
943 
945 {
946  if(idx >= Cameras.size())
947  return camid();
948 
949  return camid(idx, Cameras[idx]->get_signature());
950 }
951 
953 {
954  return Current_camera;
955 }
956 
958 {
959  return Cameras.size();
960 }
961 
966 {
967  size_t i, size=Cameras.size();
968  for(i = 0; i < size; i++)
969  {
970  if(Cameras[i] != NULL && !stricmp(Cameras[i]->get_name(), name))
971  return camid(i, Cameras[i]->get_signature());
972  }
973 
974  return camid();
975 }
976 
977 static bool Camera_hud_draw_saved = false;
978 static int Camera_hud_draw_value = 0;
979 
981 {
982  if(!cid.isValid())
983  {
984  return false;
985  }
986 
988  Current_camera = cid;
989 
991  {
992  if(!Camera_hud_draw_saved)
993  {
994  Camera_hud_draw_value = hud_get_draw();
995  Camera_hud_draw_saved = true;
996  }
997  hud_set_draw(0);
998  }
999  return true;
1000 }
1001 
1003 {
1005 
1007  {
1008  hud_set_draw(Camera_hud_draw_value);
1009  Camera_hud_draw_saved = false;
1010  }
1011 }
1012 
1014 {
1015  Subtitles.clear();
1016 }
1017 
1018 void subtitles_do_frame(float frametime)
1019 {
1021  for(sub = Subtitles.begin(); sub != Subtitles.end(); ++sub)
1022  {
1023  if ( !sub->is_post_shaded( ) )
1024  sub->do_frame(frametime);
1025  }
1026 }
1027 
1028 void subtitles_do_frame_post_shaded(float frametime)
1029 {
1031  for(sub = Subtitles.begin(); sub != Subtitles.end(); ++sub)
1032  {
1033  if ( sub->is_post_shaded( ) )
1034  sub->do_frame(frametime);
1035  }
1036 }
1037 
1039 
1041 {
1042  object_h obj(cam->get_object_host());
1043  if(!obj.IsValid())
1044  return;
1045  ship* shipp = &Ships[cam->get_object_host()->instance];
1046  ship_subsys* ssp = GET_FIRST(&shipp->subsys_list);
1047  while ( ssp != END_OF_LIST( &shipp->subsys_list ) )
1048  {
1049  if(ssp->system_info->subobj_num == cam->get_object_host_submodel())
1050  {
1053  offset.xyz.x = 0.0001f;
1054  vm_vec_add2(pos, &offset); // prevent beam turrets from crashing with a nullvec
1055  break;
1056  }
1057  ssp = GET_NEXT( ssp );
1058  }
1059 }
1060 
1062 {
1063  object_h obj(cam->get_object_host());
1064  if(!obj.IsValid())
1065  return;
1066  vm_vector_2_matrix(ori, &normal_cache, vm_vec_same(&normal_cache, &cam->get_object_host()->orient.vec.uvec)?NULL:&cam->get_object_host()->orient.vec.uvec, NULL);
1067 }
1068 
1070 {
1071  if(pm->n_view_positions > 0)
1072  {
1073  for(int i = 0; i < pm->n_view_positions; ++i)
1074  {
1075  if(pm->view_positions[i].parent == submodel_num)
1076  {
1077  return &pm->view_positions[i];
1078  }
1079  int sm = pm->submodel[submodel_num].first_child;
1080  while(sm > 0) //look for eyepoints attached to children, important for turret arms
1081  {
1082  if(pm->view_positions[i].parent == sm)
1083  {
1084  return &pm->view_positions[i];
1085  }
1086  sm = pm->submodel[sm].next_sibling;
1087  }
1088  }
1089  }
1090  return NULL;
1091 }
SCP_vector< camera * > Cameras
Definition: camera.cpp:22
#define MAX_FILENAME_LEN
Definition: pstypes.h:324
bsp_info * submodel
Definition: model.h:764
camid cam_get_camera(uint idx)
Definition: camera.cpp:944
int gr_get_current_fontnum()
Definition: font.cpp:545
int i
Definition: multi_pxo.cpp:466
int hud_get_draw()
Definition: hud.cpp:1282
camid cam_create(char *n_name, vec3d *n_pos, vec3d *n_norm, object *n_object, int n_object_host_submodel)
Definition: camera.cpp:888
int get_object_host_submodel()
Definition: camera.cpp:266
model_subsystem * system_info
Definition: ship.h:314
matrix c_ori
Definition: camera.h:44
avd_movement fov
Definition: camera.h:35
object * objp
Definition: object.h:182
void model_find_world_point(vec3d *outpnt, vec3d *mpnt, int model_num, int submodel_num, const matrix *objorient, const vec3d *objpos)
Definition: modelread.cpp:4099
void setVD(float total_movement_time, float ending_acceleration_time, float final_velocity)
Definition: physics.cpp:1227
matrix * vm_matrix_x_matrix(matrix *dest, const matrix *src0, const matrix *src1)
Definition: vecmat.cpp:1006
~camera()
Definition: camera.cpp:37
GLfloat GLfloat GLfloat GLfloat h
Definition: Glext.h:7280
void set_object_host(object *objp, int n_object_host_submodel=-1)
Definition: camera.cpp:105
camid Main_camera
Definition: camera.cpp:25
camera(char *in_name=NULL, int in_signature=-1)
Definition: camera.cpp:29
avd_movement pos_z
Definition: camera.h:38
#define gr_pop_scale_matrix
Definition: 2d.h:898
polymodel * model_get(int model_num)
Definition: modelread.cpp:3134
void set(float position)
Definition: physics.cpp:1188
subtitle(int in_x_pos, int in_y_pos, const char *in_text=NULL, const char *in_imageanim=NULL, float in_display_time=0, float in_fade_time=0.0f, const color *in_text_color=NULL, int in_text_fontnum=-1, bool center_x=false, bool center_y=false, int in_width=0, int in_height=0, bool post_shaded=false)
Definition: camera.cpp:543
int n_view_positions
Definition: model.h:752
void vm_rotate_matrix_by_angles(matrix *orient, const angles *tangles)
Definition: vecmat.cpp:1338
int id
Definition: model.h:732
matrix * vm_vector_2_matrix_norm(matrix *m, const vec3d *fvec, const vec3d *uvec, const vec3d *rvec)
Definition: vecmat.cpp:891
int parent
Definition: model.h:595
void ship_get_global_turret_gun_info(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, int use_angles, vec3d *targetp)
Definition: aiturret.cpp:1327
int model_instance_num
Definition: ship.h:802
const subtitle & operator=(const subtitle &sub)
Definition: camera.cpp:805
void _cdecl void void _cdecl void _cdecl Warning(char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
Definition: pstypes.h:88
void gr_init_alphacolor(color *clr, int r, int g, int b, int alpha, int type)
Definition: 2d.cpp:1173
void set_position(vec3d *in_position=NULL, float in_translation_time=0.0f, float in_translation_acceleration_time=0.0f, float in_translation_deceleration_time=0.0f, float in_end_velocity=0.0f)
Definition: camera.cpp:162
__inline void gr_string(int x, int y, const char *string, int resize_mode=GR_RESIZE_FULL)
Definition: 2d.h:769
vec3d norm
Definition: model.h:597
Definition: 2d.h:95
int bm_get_info(int handle, int *w, int *h, ubyte *flags, int *nframes, int *fps)
Gets info on the bitmap indexed by handle.
Definition: bmpman.cpp:769
void get(float Time, float *Position, float *Velocity)
Definition: physics.cpp:1172
struct vec3d::@225::@227 xyz
int center_h
Definition: 2d.h:363
bool cam_set_camera(camid cid)
Definition: camera.cpp:980
#define CAM_STATIONARY_POS
Definition: camera.h:15
void set_rotation(matrix *in_ori)
Definition: camera.cpp:471
GLclampf f
Definition: Glext.h:7097
int center_offset_y
Definition: 2d.h:364
#define Assertion(expr, msg,...)
Definition: clang.h:41
object_h object_target
Definition: camera.h:29
void set_position(vec3d *in_pos)
Definition: camera.cpp:466
camid()
Definition: camera.cpp:821
int center_w
Definition: 2d.h:363
void vm_vec_scale_add2(vec3d *dest, const vec3d *src, float k)
Definition: vecmat.cpp:284
void cam_do_frame(float frametime)
Definition: camera.cpp:934
void gr_set_color_fast(color *dst)
Definition: 2d.cpp:1197
std::basic_string< char, std::char_traits< char >, std::allocator< char > > SCP_string
Definition: vmallocator.h:21
void set_fov(float in_fov, float in_fov_time=0.0f, float in_fov_acceleration_time=0.0f, float in_deceleration_time=0.0f)
Definition: camera.cpp:87
void find_submodel_instance_point_normal(vec3d *outpnt, vec3d *outnorm, int model_instance_num, int submodel_num, const vec3d *submodel_pnt, const vec3d *submodel_norm)
Definition: modelread.cpp:4302
object * objp
Definition: lua.cpp:3105
GLenum GLenum GLenum GLenum GLenum scale
Definition: Glext.h:8503
void gr_set_bitmap(int bitmap_num, int alphablend_mode, int bitblt_mode, float alpha)
Definition: 2d.cpp:2105
GLsizeiptr size
Definition: Glext.h:5496
void apply_physics(float damping, float desired_vel, float initial_vel, float t, float *new_vel, float *delta_pos)
Definition: physics.cpp:108
Definition: model.h:594
ship * shipp
Definition: lua.cpp:9162
vec3d pos
Definition: object.h:152
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: Glext.h:7308
#define GR_RESIZE_NONE
Definition: 2d.h:681
void get_info(vec3d *position, matrix *orientation)
Definition: camera.cpp:531
hull_check submodel_num
Definition: lua.cpp:5048
int bm_release(int handle, int clear_render_targets)
Frees both a bitmap's data and it's associated slot.
Definition: bmpman.cpp:2603
int object_get_model(object *objp)
Definition: object.cpp:2092
void ship_get_eye(vec3d *eye_pos, matrix *eye_orient, object *obj, bool do_slew, bool from_origin)
Definition: ship.cpp:13227
void cam_reset_camera()
Definition: camera.cpp:1002
void cam_init()
Definition: camera.cpp:866
int subobj_num
Definition: model.h:175
void get_info(vec3d *position, matrix *orientation)
Definition: camera.cpp:295
void get_turret_cam_pos(camera *cam, vec3d *pos)
Definition: camera.cpp:1040
void reset()
Definition: camera.cpp:458
~subtitle()
Definition: camera.cpp:767
object_h object_host
Definition: camera.h:26
bool isValid()
Definition: camera.cpp:851
int sig
Definition: camera.h:23
ship_subsys subsys_list
Definition: ship.h:630
vec3d pnt
Definition: model.h:596
float Sexp_fov
Definition: camera.cpp:16
#define VM_FREECAMERA
Definition: systemvars.h:44
int getSignature()
Definition: camera.cpp:846
void set_translation_velocity(vec3d *in_velocity, float in_acceleration_time=0.0f)
Definition: camera.cpp:188
void set_object_target(object *objp, int n_object_target_submodel=-1)
Definition: camera.cpp:135
int instance
Definition: object.h:150
matrix * vm_vector_2_matrix(matrix *m, const vec3d *fvec, const vec3d *uvec, const vec3d *rvec)
Definition: vecmat.cpp:850
GLintptr offset
Definition: Glext.h:5497
avd_movement ori[9]
Definition: camera.h:39
void vm_vec_add2(vec3d *dest, const vec3d *src)
Definition: vecmat.cpp:178
#define GR_ALPHABLEND_FILTER
Definition: 2d.h:349
const float PI2
Definition: pstypes.h:305
void set_custom_position_function(void(*n_func_custom_position)(camera *cam, vec3d *pos))
Definition: camera.cpp:148
struct matrix::@228::@230 vec
unsigned int uint
Definition: pstypes.h:64
#define CAM_STATIONARY_FOV
Definition: camera.h:13
#define CAM_DEFAULT_FLAGS
Definition: camera.h:16
bsp_info * sm
Definition: lua.cpp:7079
void do_frame(float frametime)
Definition: camera.cpp:686
vec3d normal_cache
Definition: camera.cpp:1038
uint getIndex()
Definition: camera.cpp:841
void vm_orthogonalize_matrix(matrix *m_src)
Definition: vecmat.cpp:1247
sprintf(buf,"(%f,%f,%f)", v3->xyz.x, v3->xyz.y, v3->xyz.z)
warp_camera Warp_camera
Definition: camera.cpp:17
int cam_get_next_sig()
Definition: camera.cpp:882
#define SUBSYSTEM_TURRET
Definition: model.h:54
void set_custom_orientation_function(void(*n_func_custom_orientation)(camera *cam, matrix *ori))
Definition: camera.cpp:157
#define fl_abs(fl)
Definition: floating.h:31
float vm_vec_normalized_dir(vec3d *dest, const vec3d *end, const vec3d *start)
Definition: vecmat.cpp:591
int split_str(const char *src, int max_pixel_w, int *n_chars, const char **p_str, int max_lines, char ignore_char)
Definition: parselo.cpp:3412
Definition: ship.h:534
int idx
Definition: multiui.cpp:761
void setAVD(float final_position, float total_movement_time, float starting_accleration_time, float ending_acceleration_time, float final_velocity)
Definition: physics.cpp:1194
vec3d * vm_vec_unrotate(vec3d *dest, const vec3d *src, const matrix *m)
Definition: vecmat.cpp:959
camid cam_get_current()
Definition: camera.cpp:952
void(* func_custom_position)(camera *cam, vec3d *pos)
Definition: camera.h:32
GLint GLint GLint GLint GLint x
Definition: Glext.h:5182
ubyte alpha
Definition: 2d.h:103
unsigned char ubyte
Definition: pstypes.h:62
void hud_set_draw(int draw)
Definition: hud.cpp:1276
#define gr_push_scale_matrix
Definition: 2d.h:897
#define ZERO_VECTOR
Definition: vecmat.h:60
matrix orient
Definition: object.h:153
int w
Definition: camera.h:130
#define OBJ_SHIP
Definition: object.h:32
void _cdecl void void _cdecl Error(const char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
GLbitfield flags
Definition: Glext.h:6722
SCP_vector< subtitle > Subtitles
Definition: camera.cpp:21
void set_rotation(matrix *in_orientation=NULL, float in_rotation_time=0.0f, float in_rotation_acceleration_time=0.0f, float in_rotation_deceleration_time=0.0f)
Definition: camera.cpp:195
avd_movement pos_x
Definition: camera.h:36
eye * get_submodel_eye(polymodel *pm, int submodel_num)
Definition: camera.cpp:1069
GLuint const GLchar * name
Definition: Glext.h:5608
float c_fov
Definition: camera.h:42
#define IDENTITY_MATRIX
Definition: vecmat.h:64
void clear()
Definition: physics.cpp:1145
int object_target_submodel
Definition: camera.h:30
bool sexp_replace_variable_names_with_values(char *text, int max_len)
Definition: sexp.cpp:29395
int bm_load(const char *real_filename)
Loads a bitmap so we can draw with it later.
Definition: bmpman.cpp:1119
ship Ships[MAX_SHIPS]
Definition: ship.cpp:122
int vm_vec_same(const vec3d *v1, const vec3d *v2)
Definition: vecmat.cpp:1526
void set_velocity(vec3d *in_vel, bool instantaneous)
Definition: camera.cpp:476
Definition: pstypes.h:606
#define NAME_LENGTH
Definition: globals.h:15
float frand()
Return random value in range 0.0..1.0- (1.0- means the closest number less than 1.0)
Definition: floating.cpp:35
GLubyte GLubyte GLubyte GLubyte w
Definition: Glext.h:5679
bool IsValid()
Definition: object.h:185
camid cam_lookup(char *name)
Definition: camera.cpp:965
#define fl2i(fl)
Definition: floating.h:33
void subtitles_do_frame(float frametime)
Definition: camera.cpp:1018
class camera * getCamera()
Definition: camera.cpp:833
screen gr_screen
Definition: 2d.cpp:46
void gr_get_string_size(int *w, int *h, const char *text, int len=9999)
Definition: font.cpp:196
uint cam_get_num()
Definition: camera.cpp:957
#define CAM_STATIONARY_ORI
Definition: camera.h:14
void clear()
Definition: camera.cpp:46
int next_sibling
Definition: model.h:362
void set_name(char *in_name)
Definition: camera.cpp:81
int get_object_target_submodel()
Definition: camera.cpp:279
int gr_get_font_height()
Definition: font.cpp:187
int center_offset_x
Definition: 2d.h:364
void reset()
Definition: camera.cpp:53
#define LOCATION
Definition: pstypes.h:245
int Viewer_mode
Definition: systemvars.cpp:28
void cam_close()
Definition: camera.cpp:872
object * get_object_host()
Definition: camera.cpp:258
hull_check pos
Definition: lua.cpp:5050
GLsizei GLsizei GLuint * obj
Definition: Glext.h:5619
float get_fov()
Definition: camera.cpp:284
float a1d[9]
Definition: pstypes.h:120
int object_host_submodel
Definition: camera.h:27
void set_rotation_velocity(angles *in_rotation_rate, float in_acceleration_time=0.0f)
Definition: camera.cpp:248
#define MAX_SUBTITLE_LINES
Definition: camera.cpp:542
void gr_bitmap(int _x, int _y, int resize_mode)
Definition: 2d.cpp:1303
#define GR_BITBLT_MODE_NORMAL
Definition: 2d.h:351
eye view_positions[MAX_EYES]
Definition: model.h:753
object * Player_obj
Definition: object.cpp:56
polymodel * pm
Definition: lua.cpp:1598
void do_frame(float in_frametime)
Definition: camera.cpp:253
camid Current_camera
Definition: camera.cpp:24
avd_movement pos_y
Definition: camera.h:37
Definition: camera.h:18
void subtitles_do_frame_post_shaded(float frametime)
Definition: camera.cpp:1028
bool Cutscene_camera_displays_hud
Definition: mod_table.cpp:22
object * get_object_target()
Definition: camera.cpp:271
false
Definition: lua.cpp:6789
void do_frame(float in_frametime)
Definition: camera.cpp:492
void gr_set_font(int fontnum)
Definition: font.cpp:566
int model_num
Definition: lua.cpp:4996
char type
Definition: object.h:146
vec3d vmd_zero_vector
Definition: vecmat.cpp:24
void(* func_custom_orientation)(camera *cam, matrix *ori)
Definition: camera.h:33
vec3d c_pos
Definition: camera.h:43
void cam_delete(camid cid)
Definition: camera.cpp:926
#define stricmp(s1, s2)
Definition: config.h:271
void gr_init_color(color *c, int r, int g, int b)
Definition: 2d.cpp:1155
matrix vmd_identity_matrix
Definition: vecmat.cpp:28
void get_turret_cam_orient(camera *cam, matrix *ori)
Definition: camera.cpp:1061
void set_rotation_facing(vec3d *in_target, float in_rotation_time=0.0f, float in_rotation_acceleration_time=0.0f, float in_rotation_deceleration_time=0.0f)
Definition: camera.cpp:225
float VIEWER_ZOOM_DEFAULT
Definition: camera.cpp:15
int h
Definition: camera.h:130
int first_child
Definition: model.h:361
GLint y
Definition: Gl.h:1505
void subtitles_close()
Definition: camera.cpp:1013
#define strcpy_s(...)
Definition: safe_strings.h:67