FS2_Open
Open source remastering of the Freespace 2 engine
objectdock.cpp
Go to the documentation of this file.
1 /*
2  * Created by Ian "Goober5000" Warfield for the FreeSpace2 Source Code Project.
3  * You may not sell or otherwise commercially exploit the source or things you
4  * create based on the source.
5  */
6 
7 
8 
9 #include "math/bitarray.h"
10 #include "math/vecmat.h"
11 #include "mission/missionparse.h"
12 #include "object/object.h"
13 #include "object/objectdock.h"
14 #include "ship/ship.h"
15 
16 
17 
18 
19 // helper prototypes
20 
21 void dock_evaluate_tree(object *objp, dock_function_info *infop, void (*function)(object *, dock_function_info *), ubyte *visited_bitstring);
22 void dock_move_docked_children_tree(object *objp, object *parent_objp);
25 void dock_calc_docked_center_helper(object *objp, dock_function_info *infop);
30 void dock_find_max_speed_helper(object *objp, dock_function_info *infop);
31 void dock_find_max_fspeed_helper(object *objp, dock_function_info *infop);
32 
33 
34 // management prototypes
35 
37 object *dock_get_hub(object *objp);
38 
39 void dock_add_instance(object *objp, int dockpoint, object *other_objp);
40 void dock_remove_instance(object *objp, object *other_objp);
41 dock_instance *dock_find_instance(object *objp, object *other_objp);
42 dock_instance *dock_find_instance(object *objp, int dockpoint);
43 int dock_count_instances(object *objp);
44 
45 
46 
47 object *dock_get_first_docked_object(object *objp)
48 {
49  // are we docked?
50  if (!object_is_docked(objp))
51  return NULL;
52 
53  return objp->dock_list->docked_objp;
54 }
55 
56 bool dock_check_docked_one_on_one(object *objp)
57 {
58  // we must be docked
59  if (!object_is_docked(objp))
60  return false;
61 
62  // our dock list must contain only one object
63  if (objp->dock_list->next != NULL)
64  return false;
65 
66  // the other guy's dock list must contain only one object
67  if (dock_get_first_docked_object(objp)->dock_list->next != NULL)
68  return false;
69 
70  // debug check to make sure that we're docked to each other
71  Assert(objp == dock_get_first_docked_object(objp)->dock_list->docked_objp);
72 
73  // success
74  return true;
75 }
76 
78 {
79  return dock_count_instances(objp);
80 }
81 
83 {
85 
87 
89 }
90 
91 bool dock_check_find_direct_docked_object(object *objp, object *other_objp)
92 {
93  return (dock_find_instance(objp, other_objp) != NULL);
94 }
95 
96 bool dock_check_find_docked_object(object *objp, object *other_objp)
97 {
99  dfi.parameter_variables.objp_value = other_objp;
100 
102 
103  return dfi.maintained_variables.bool_value;
104 }
105 
106 object *dock_find_object_at_dockpoint(object *objp, int dockpoint)
107 {
108  dock_instance *result = dock_find_instance(objp, dockpoint);
109 
110  if (result == NULL)
111  return NULL;
112  else
113  return result->docked_objp;
114 }
115 
116 int dock_find_dockpoint_used_by_object(object *objp, object *other_objp)
117 {
118  dock_instance *result = dock_find_instance(objp, other_objp);
119 
120  if (result == NULL)
121  return -1;
122  else
123  return result->dockpoint_used;
124 }
125 
126 void dock_calc_docked_center(vec3d *dest, object *objp)
127 {
128  vm_vec_zero(dest);
129 
130  dock_function_info dfi;
131  dfi.maintained_variables.vecp_value = dest;
132 
134 
135  // overall center = sum of centers divided by sum of objects
136  vm_vec_scale(dest, (1.0f / (float) dfi.maintained_variables.int_value));
137 }
138 
139 void dock_calc_docked_center_of_mass(vec3d *dest, object *objp)
140 {
141  vm_vec_zero(dest);
142 
143  dock_function_info dfi;
144  dfi.maintained_variables.vecp_value = dest;
145 
147 
148  // overall center of mass = weighted sum of centers of mass divided by total mass
150 }
151 
152 float dock_calc_total_docked_mass(object *objp)
153 {
154  dock_function_info dfi;
155 
157 
159 }
160 
162 {
163  vec3d local_line_end;
164  vec3d *world_line_start, world_line_end;
165  dock_function_info dfi;
166 
167  // to calculate the cross-sectional radius, we need a line that will be perpendicular to the cross-section
168 
169  // the first endpoint is simply the position of the object
170  world_line_start = &objp->pos;
171 
172  // the second endpoint extends in the axis direction
173  vm_vec_zero(&local_line_end);
174  switch(axis)
175  {
176  case X_AXIS:
177  local_line_end.xyz.x = 1.0f;
178  break;
179 
180  case Y_AXIS:
181  local_line_end.xyz.y = 1.0f;
182  break;
183 
184  case Z_AXIS:
185  local_line_end.xyz.z = 1.0f;
186  break;
187 
188  default:
189  Int3();
190  return 0.0f;
191  }
192 
193  // rotate and move the endpoint to go through the axis of the actual object
194  vm_vec_rotate(&world_line_end, &local_line_end, &objp->orient);
195  vm_vec_add2(&world_line_end, &objp->pos);
196 
197  // now we have a unit vector starting at the object's position and pointing along the chosen axis
198  // (although the length doesn't matter, as it's calculated as an endless line)
199 
200  // now determine the cross-sectional radius
201 
202  // set parameters and call function for the radius squared
203  dfi.parameter_variables.vecp_value = world_line_start;
204  dfi.parameter_variables.vecp_value2 = &world_line_end;
206 
207  // the radius is the square root of our result
209 }
210 
212 {
213  vec3d local_line_end;
214  vec3d *world_line_start, world_line_end;
215  dock_function_info dfi;
216 
217  // to calculate the semilatus rectum, we need a directrix that will be parallel to the axis
218 
219  // the first endpoint is simply the position of the object
220  world_line_start = &objp->pos;
221 
222  // the second endpoint extends in the axis direction
223  vm_vec_zero(&local_line_end);
224  switch(axis)
225  {
226  case X_AXIS:
227  local_line_end.xyz.x = 1.0f;
228  break;
229 
230  case Y_AXIS:
231  local_line_end.xyz.y = 1.0f;
232  break;
233 
234  case Z_AXIS:
235  local_line_end.xyz.z = 1.0f;
236  break;
237 
238  default:
239  Int3();
240  return 0.0f;
241  }
242 
243  // rotate and move the endpoint to go through the axis of the actual object
244  vm_vec_rotate(&world_line_end, &local_line_end, &objp->orient);
245  vm_vec_add2(&world_line_end, &objp->pos);
246 
247  // now we have a unit vector starting at the object's position and pointing along the chosen axis
248  // (although the length doesn't matter, as it's calculated as an endless line)
249 
250  // now determine the semilatus rectum
251 
252  // set parameters and call function for the semilatus rectum squared
253  dfi.parameter_variables.vecp_value = world_line_start;
254  dfi.parameter_variables.vecp_value2 = &world_line_end;
256 
257  // the semilatus rectum is the square root of our result
259 }
260 
261 float dock_calc_docked_fspeed(object *objp)
262 {
263  // *sigh*... the docked fspeed is simply the max fspeed of all docked objects
264  dock_function_info dfi;
267 }
268 
269 float dock_calc_docked_speed(object *objp)
270 {
271  // ditto with speed
272  dock_function_info dfi;
275 }
276 
277 
278 // functions to deal with all docked ships anywhere
279 // ---------------------------------------------------------------------------------------------------------------
280 
281 // universal two functions
282 // -----------------------
283 
284 // evaluate a certain function for all docked objects
285 void dock_evaluate_all_docked_objects(object *objp, dock_function_info *infop, void (*function)(object *, dock_function_info *))
286 {
287  Assert((objp != NULL) && (infop != NULL) && (function != NULL));
288 
289  // not docked?
290  if (!object_is_docked(objp))
291  {
292  // call the function for just the one object
293  function(objp, infop);
294  return;
295  }
296 
297  // we only have two objects docked
299  {
300  // call the function for the first object, and return if instructed
301  function(objp, infop);
302  if (infop->early_return_condition) return;
303 
304  // call the function for the second object, and return if instructed
305  function(objp->dock_list->docked_objp, infop);
306  if (infop->early_return_condition) return;
307  }
308 
309  // we have multiple objects docked and we're treating them as a hub
310  else if (dock_check_assume_hub())
311  {
312  // get the hub
313  object *hub_objp = dock_get_hub(objp);
314 
315  // call the function for the hub, and return if instructed
316  function(hub_objp, infop);
317  if (infop->early_return_condition) return;
318 
319  // iterate through all docked objects
320  for (dock_instance *ptr = hub_objp->dock_list; ptr != NULL; ptr = ptr->next)
321  {
322  // call the function for this object, and return if instructed
323  function(ptr->docked_objp, infop);
324  if (infop->early_return_condition) return;
325  }
326  }
327 
328  // we have multiple objects docked and we must treat them as a tree
329  else
330  {
331  // create a bit array to mark the objects we check
332  ubyte *visited_bitstring = (ubyte *) vm_malloc(calculate_num_bytes(MAX_OBJECTS));
333 
334  // clear it
335  memset(visited_bitstring, 0, calculate_num_bytes(MAX_OBJECTS));
336 
337  // start evaluating the tree
338  dock_evaluate_tree(objp, infop, function, visited_bitstring);
339 
340  // destroy the bit array
341  vm_free(visited_bitstring);
342  visited_bitstring = NULL;
343  }
344 }
345 
346 void dock_evaluate_tree(object *objp, dock_function_info *infop, void (*function)(object *, dock_function_info *), ubyte *visited_bitstring)
347 {
348  // make sure we haven't visited this object already
349  if (get_bit(visited_bitstring, OBJ_INDEX(objp)))
350  return;
351 
352  // mark as visited
353  set_bit(visited_bitstring, OBJ_INDEX(objp));
354 
355  // call the function for this object, and return if instructed
356  function(objp, infop);
357  if (infop->early_return_condition) return;
358 
359  // iterate through all docked objects
360  for (dock_instance *ptr = objp->dock_list; ptr != NULL; ptr = ptr->next)
361  {
362  // start another tree with the docked object as the root, and return if instructed
363  dock_evaluate_tree(ptr->docked_objp, infop, function, visited_bitstring);
364  if (infop->early_return_condition) return;
365  }
366 }
367 
368 // special-case functions
369 // ----------------------
370 
371 void dock_move_docked_objects(object *objp)
372 {
373  if ((objp->type != OBJ_SHIP) && (objp->type != OBJ_START))
374  return;
375 
376  if (!object_is_docked(objp))
377  return;
378 
379  // has this object (by extension, this group of docked objects) been handled already?
380  if (objp->flags & OF_DOCKED_ALREADY_HANDLED)
381  return;
382 
383  Assert((objp->instance >= 0) && (objp->instance < MAX_SHIPS));
384 
385  dock_function_info dfi;
386  object *fastest_objp;
387 
388  // in FRED, objp is the object everyone moves with
389  if (Fred_running)
390  {
391  fastest_objp = objp;
392  }
393  else
394  {
395  // find the object with the highest max speed
397  fastest_objp = dfi.maintained_variables.objp_value;
398 
399  // if we have no max speed, just use the first one
400  if (fastest_objp == NULL)
401  fastest_objp = objp;
402  }
403 
404  // start a tree with that object as the parent... do NOT use the überfunction for this,
405  // because we must use a tree for the parent ancestry to work correctly
406 
407  // we don't need a bit array because OF_DOCKED_ALREADY_HANDLED takes care of it
408  // and must persist for the entire game frame
409 
410  // start evaluating the tree, starting with the fastest object having no parent
411  dock_move_docked_children_tree(fastest_objp, NULL);
412 }
413 
414 void dock_move_docked_children_tree(object *objp, object *parent_objp)
415 {
416  // has this object been handled already?
417  if (objp->flags & OF_DOCKED_ALREADY_HANDLED)
418  return;
419 
420  // mark as handled
422 
423  // if parent_objp exists
424  if (parent_objp != NULL)
425  {
426  // move this object to align with it
427  obj_move_one_docked_object(objp, parent_objp);
428  }
429 
430  // iterate through all docked objects
431  for (dock_instance *ptr = objp->dock_list; ptr != NULL; ptr = ptr->next)
432  {
433  // start another tree with the docked object as the root and this object as the parent
434  dock_move_docked_children_tree(ptr->docked_objp, objp);
435  }
436 }
437 
438 
439 // helper functions
440 // ----------------
441 
443 {
444  // increment count
446 }
447 
449 {
450  // if object found, set to true and break
451  if (infop->parameter_variables.objp_value == objp)
452  {
453  infop->maintained_variables.bool_value = true;
454  infop->early_return_condition = true;
455  }
456 }
457 
459 {
460  // add object position and increment count
463 }
464 
466 {
467  // add weighted object position and add mass
470 }
471 
473 {
474  // add mass
476 }
477 
478 // What we're doing here is finding the distances between each extent of the object and the line, and then taking the
479 // maximum distance as the cross-sectional radius. We're actually maintaining the square of the distance rather than
480 // the actual distance, as it's faster to calculate and it gives the same result in a greater-than or less-than
481 // comparison. When we're done calculating everything for all objects (i.e. when we return to the parent function)
482 // we take the square root of the final value.
484 {
485  vec3d world_point, local_point[6], nearest;
486  polymodel *pm;
487  int i;
488  float dist_squared;
489 
490  // line parameters
491  vec3d *line_start = infop->parameter_variables.vecp_value;
492  vec3d *line_end = infop->parameter_variables.vecp_value2;
493 
494  // We must find world coordinates for each of the six endpoints on the three axes of the object. I looked up
495  // which axis is front/back, left/right, and up/down, as well as which endpoint is which. It doesn't really
496  // matter, though, as all we need are the distances.
497 
498  // grab our model
499  Assert(objp->type == OBJ_SHIP);
500  pm = model_get(Ship_info[Ships[objp->instance].ship_info_index].model_num);
501 
502  // set up the points we want to check
503  memset(local_point, 0, sizeof(vec3d) * 6);
504  local_point[0].xyz.x = pm->maxs.xyz.x; // right point (max x)
505  local_point[1].xyz.x = pm->mins.xyz.x; // left point (min x)
506  local_point[2].xyz.y = pm->maxs.xyz.y; // top point (max y)
507  local_point[3].xyz.y = pm->mins.xyz.y; // bottom point (min y)
508  local_point[4].xyz.z = pm->maxs.xyz.z; // front point (max z)
509  local_point[5].xyz.z = pm->mins.xyz.z; // rear point (min z)
510 
511  // check points
512  for (i = 0; i < 6; i++)
513  {
514  // calculate position of point
515  vm_vec_rotate(&world_point, &local_point[i], &objp->orient);
516  vm_vec_add2(&world_point, &objp->pos);
517 
518  // calculate square of distance to line
519  vm_vec_dist_squared_to_line(&world_point, line_start, line_end, &nearest, &dist_squared);
520 
521  // update with farthest distance squared
522  if (dist_squared > infop->maintained_variables.float_value)
523  infop->maintained_variables.float_value = dist_squared;
524  }
525 }
526 
527 // What we're doing here is projecting each object extent onto the directrix, calculating the distance between the
528 // projected point and the origin, and then taking the maximum distance as the semilatus rectum. We're actually
529 // maintaining the square of the distance rather than the actual distance, as it's faster to calculate and it gives
530 // the same result in a greater-than or less-than comparison. When we're done calculating everything for all
531 // objects (i.e. when we return to the parent function) we take the square root of the final value.
533 {
534  vec3d world_point, local_point[6], nearest;
535  polymodel *pm;
536  int i;
537  float temp, dist_squared;
538 
539  // line parameters
540  vec3d *line_start = infop->parameter_variables.vecp_value;
541  vec3d *line_end = infop->parameter_variables.vecp_value2;
542 
543  // We must find world coordinates for each of the six endpoints on the three axes of the object. I looked up
544  // which axis is front/back, left/right, and up/down, as well as which endpoint is which. It doesn't really
545  // matter, though, as all we need are the distances.
546 
547  // grab our model
548  Assert(objp->type == OBJ_SHIP);
549  pm = model_get(Ship_info[Ships[objp->instance].ship_info_index].model_num);
550 
551  // set up the points we want to check
552  memset(local_point, 0, sizeof(vec3d) * 6);
553  local_point[0].xyz.x = pm->maxs.xyz.x; // right point (max x)
554  local_point[1].xyz.x = pm->mins.xyz.x; // left point (min x)
555  local_point[2].xyz.y = pm->maxs.xyz.y; // top point (max y)
556  local_point[3].xyz.y = pm->mins.xyz.y; // bottom point (min y)
557  local_point[4].xyz.z = pm->maxs.xyz.z; // front point (max z)
558  local_point[5].xyz.z = pm->mins.xyz.z; // rear point (min z)
559 
560  // check points
561  for (i = 0; i < 6; i++)
562  {
563  // calculate position of point
564  vm_vec_rotate(&world_point, &local_point[i], &objp->orient);
565  vm_vec_add2(&world_point, &objp->pos);
566 
567  // find the nearest point along the line
568  vm_vec_dist_squared_to_line(&world_point, line_start, line_end, &nearest, &temp);
569 
570  // find the distance squared between the origin of the line and the point on the line
571  dist_squared = vm_vec_dist_squared(line_start, &nearest);
572 
573  // update with farthest distance squared
574  if (dist_squared > infop->maintained_variables.float_value)
575  infop->maintained_variables.float_value = dist_squared;
576  }
577 }
578 
580 {
581  // check our fspeed against the running maximum
583  {
586  }
587 }
588 
590 {
591  // check our speed against the running maximum
592  if (objp->phys_info.speed > infop->maintained_variables.float_value)
593  {
596  }
597 }
598 // ---------------------------------------------------------------------------------------------------------------
599 // end of über code block ----------------------------------------------------------------------------------------
600 
601 // dock management functions -------------------------------------------------------------------------------------
602 void dock_dock_objects(object *objp1, int dockpoint1, object *objp2, int dockpoint2)
603 {
604 #ifndef NDEBUG
605  if ((dock_find_instance(objp1, objp2) != NULL) || (dock_find_instance(objp2, objp1) != NULL))
606  {
607  Error(LOCATION, "Trying to dock an object that's already docked!\n");
608  }
609 
610  if ((dock_find_instance(objp1, dockpoint1) != NULL) || (dock_find_instance(objp2, dockpoint2) != NULL))
611  {
612  Error(LOCATION, "Trying to dock to a dockpoint that's in use!\n");
613  }
614 #endif
615 
616  // put objects on each others' dock lists
617  dock_add_instance(objp1, dockpoint1, objp2);
618  dock_add_instance(objp2, dockpoint2, objp1);
619 }
620 
621 void dock_undock_objects(object *objp1, object *objp2)
622 {
623 #ifndef NDEBUG
624  if ((dock_find_instance(objp1, objp2) == NULL) || (dock_find_instance(objp2, objp1) == NULL))
625  {
626  Error(LOCATION, "Trying to undock an object that isn't docked!\n");
627  }
628 #endif
629 
630  // remove objects from each others' dock lists
631  dock_remove_instance(objp1, objp2);
632  dock_remove_instance(objp2, objp1);
633 }
634 
635 // dock list functions -------------------------------------------------------------------------------------------
637 {
638  // There are several ways of handling ships docking to other ships. Level 1, the simplest, is the one-docker, one-dockee
639  // model used in retail FS2. Level 2 is the hub model, where we stipulate that any given set of docked ships
640  // includes one ship to which all other ships are docked. No ship except for the hub ship can be docked to more than
641  // one ship. Level 3 is the daisy-chain model, where you can string ships along and make a rooted tree.
642  //
643  // The new code can handle level 3 ship formations, but it requires more overhead than level 2 or level 1. (Whether
644  // the additional overhead is significant or not has not been determined.) In the vast majority of cases, level 3
645  // is not needed. So this function is provided to allow the code to optimize itself for level 2, should level 1
646  // evaluation fail.
647 
648  // Assume level 2 optimization unless the mission specifies level 3.
650 }
651 
652 object *dock_get_hub(object *objp)
653 {
655 
656  // if our dock list contains only one object, it must be the hub
657  if (objp->dock_list->next == NULL)
658  {
659  return dock_get_first_docked_object(objp);
660  }
661  // otherwise we are the hub
662  else
663  {
664  return objp;
665  }
666 }
667 
668 void dock_add_instance(object *objp, int dockpoint, object *other_objp)
669 {
670  dock_instance *item;
671 
672  // create item
673  item = (dock_instance *) vm_malloc(sizeof(dock_instance));
674  item->dockpoint_used = dockpoint;
675  item->docked_objp = other_objp;
676 
677  // prepend item to existing list
678  item->next = objp->dock_list;
679  objp->dock_list = item;
680 }
681 
682 void dock_remove_instance(object *objp, object *other_objp)
683 {
684  int found = 0;
685  dock_instance *prev_ptr, *ptr;
686 
687  prev_ptr = NULL;
688  ptr = objp->dock_list;
689 
690  // iterate until item found
691  while (ptr != NULL)
692  {
693  // if found, exit loop
694  if (ptr->docked_objp == other_objp)
695  {
696  found = 1;
697  break;
698  }
699 
700  // iterate
701  prev_ptr = ptr;
702  ptr = ptr->next;
703  }
704 
705  // delete if found
706  if (found)
707  {
708  // special case... found at beginning of list
709  if (prev_ptr == NULL)
710  {
711  objp->dock_list = ptr->next;
712  }
713  // normal case
714  else
715  {
716  prev_ptr->next = ptr->next;
717  }
718 
719  // delete it
720  vm_free(ptr);
721  }
722 }
723 
724 // just free the list without worrying about undocking anything
725 void dock_free_dock_list(object *objp)
726 {
727  while (objp->dock_list != NULL)
728  {
729  dock_instance *ptr = objp->dock_list;
730  objp->dock_list = ptr->next;
731  vm_free(ptr);
732  }
733 }
734 
735 dock_instance *dock_find_instance(object *objp, object *other_objp)
736 {
737  dock_instance *ptr = objp->dock_list;
738 
739  // iterate until item found
740  while (ptr != NULL)
741  {
742  // if found, return it
743  if (ptr->docked_objp == other_objp)
744  return ptr;
745 
746  // iterate
747  ptr = ptr->next;
748  }
749 
750  // not found
751  return NULL;
752 }
753 
754 dock_instance *dock_find_instance(object *objp, int dockpoint)
755 {
756  dock_instance *ptr = objp->dock_list;
757 
758  // iterate until item found
759  while (ptr != NULL)
760  {
761  // if found, return it
762  if (ptr->dockpoint_used == dockpoint)
763  return ptr;
764 
765  // iterate
766  ptr = ptr->next;
767  }
768 
769  // not found
770  return NULL;
771 }
772 
773 int dock_count_instances(object *objp)
774 {
775  int total_count = 0;
776 
777  // count all instances in the list
778  dock_instance *ptr = objp->dock_list;
779  while (ptr != NULL)
780  {
781  // incrememnt for this object
782  total_count++;
783 
784  // iterate
785  ptr = ptr->next;
786  }
787 
788  // done
789  return total_count;
790 }
GLuint64EXT * result
Definition: Glext.h:10775
void dock_free_dock_list(object *objp)
Definition: objectdock.cpp:725
int i
Definition: multi_pxo.cpp:466
#define vm_free(ptr)
Definition: pstypes.h:548
void dock_calc_docked_center_helper(object *objp, dock_function_info *infop)
Definition: objectdock.cpp:458
float dock_calc_docked_fspeed(object *objp)
Definition: objectdock.cpp:261
vec3d mins
Definition: model.h:746
polymodel * model_get(int model_num)
Definition: modelread.cpp:3134
bool dock_check_find_docked_object(object *objp, object *other_objp)
Definition: objectdock.cpp:96
physics_info phys_info
Definition: object.h:157
int Fred_running
Definition: fred.cpp:44
#define MAX_SHIPS
Definition: globals.h:37
vec3d * vecp_value2
Definition: objectdock.h:40
void dock_calc_docked_center_of_mass_helper(object *objp, dock_function_info *infop)
Definition: objectdock.cpp:465
Assert(pm!=NULL)
Definition: pstypes.h:88
int dockpoint_used
Definition: objectdock.h:21
struct vec3d::@225::@227 xyz
GLclampf f
Definition: Glext.h:7097
object * dock_find_object_at_dockpoint(object *objp, int dockpoint)
Definition: objectdock.cpp:106
void dock_evaluate_tree(object *objp, dock_function_info *infop, void(*function)(object *, dock_function_info *), ubyte *visited_bitstring)
Definition: objectdock.cpp:346
#define MAX_OBJECTS
Definition: globals.h:83
dock_instance * next
Definition: objectdock.h:19
bool dock_check_find_direct_docked_object(object *objp, object *other_objp)
Definition: objectdock.cpp:91
vec3d * vm_vec_rotate(vec3d *dest, const vec3d *src, const matrix *m)
Definition: vecmat.cpp:933
int dock_find_dockpoint_used_by_object(object *objp, object *other_objp)
Definition: objectdock.cpp:116
#define MISSION_FLAG_ALLOW_DOCK_TREES
Definition: missionparse.h:81
vec3d maxs
Definition: model.h:746
void dock_calc_max_semilatus_rectum_squared_parallel_to_directrix_helper(object *objp, dock_function_info *infop)
Definition: objectdock.cpp:532
void vm_vec_scale_add2(vec3d *dest, const vec3d *src, float k)
Definition: vecmat.cpp:284
float dock_calc_docked_speed(object *objp)
Definition: objectdock.cpp:269
void dock_move_docked_objects(object *objp)
Definition: objectdock.cpp:371
object * objp
Definition: lua.cpp:3105
void vm_vec_dist_squared_to_line(const vec3d *p, const vec3d *l0, const vec3d *l1, vec3d *nearest, float *dist_squared)
Definition: vecmat.cpp:2543
#define Int3()
Definition: pstypes.h:292
void obj_move_one_docked_object(object *objp, object *parent_objp)
Definition: object.cpp:682
vec3d pos
Definition: object.h:152
#define calculate_num_bytes(num_bits)
Definition: bitarray.h:46
void dock_check_find_docked_object_helper(object *objp, dock_function_info *infop)
Definition: objectdock.cpp:448
#define set_bit(array, bitnum)
Definition: bitarray.h:36
#define get_bit(array, bitnum)
Definition: bitarray.h:33
void dock_count_total_docked_objects_helper(object *objp, dock_function_info *infop)
Definition: objectdock.cpp:442
int object_is_docked(object *objp)
Definition: object.cpp:2019
int instance
Definition: object.h:150
void dock_calc_docked_center(vec3d *dest, object *objp)
Definition: objectdock.cpp:126
void vm_vec_add2(vec3d *dest, const vec3d *src)
Definition: vecmat.cpp:178
#define OBJ_START
Definition: object.h:35
dock_instance * dock_list
Definition: object.h:166
bool dock_check_docked_one_on_one(object *objp)
Definition: objectdock.cpp:56
void dock_add_instance(object *objp, int dockpoint, object *other_objp)
Definition: objectdock.cpp:668
vec3d * vecp_value
Definition: objectdock.h:39
void vm_vec_scale(vec3d *dest, float s)
Definition: vecmat.cpp:248
object * dock_get_hub(object *objp)
Definition: objectdock.cpp:652
dock_instance * dock_find_instance(object *objp, object *other_objp)
Definition: objectdock.cpp:735
void dock_undock_objects(object *objp1, object *objp2)
Definition: objectdock.cpp:621
float speed
Definition: physics.h:79
void dock_remove_instance(object *objp, object *other_objp)
Definition: objectdock.cpp:682
void dock_find_max_fspeed_helper(object *objp, dock_function_info *infop)
Definition: objectdock.cpp:579
float dock_calc_max_cross_sectional_radius_perpendicular_to_axis(object *objp, axis_type axis)
Definition: objectdock.cpp:161
bool early_return_condition
Definition: objectdock.h:32
object * dock_get_first_docked_object(object *objp)
Definition: objectdock.cpp:47
int dock_count_total_docked_objects(object *objp)
Definition: objectdock.cpp:82
void dock_dock_objects(object *objp1, int dockpoint1, object *objp2, int dockpoint2)
Definition: objectdock.cpp:602
float vm_vec_dist_squared(const vec3d *v0, const vec3d *v1)
Definition: vecmat.cpp:344
float dock_calc_max_semilatus_rectum_parallel_to_axis(object *objp, axis_type axis)
Definition: objectdock.cpp:211
class object * next
Definition: object.h:144
unsigned char ubyte
Definition: pstypes.h:62
#define vm_vec_zero(v)
Definition: vecmat.h:37
#define OBJ_INDEX(objp)
Definition: object.h:235
matrix orient
Definition: object.h:153
#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
#define vm_malloc(size)
Definition: pstypes.h:547
int dock_count_direct_docked_objects(object *objp)
Definition: objectdock.cpp:77
int dock_count_instances(object *objp)
Definition: objectdock.cpp:773
float fspeed
Definition: physics.h:80
ship Ships[MAX_SHIPS]
Definition: ship.cpp:122
void dock_move_docked_children_tree(object *objp, object *parent_objp)
Definition: objectdock.cpp:414
struct dock_function_info::@258 parameter_variables
struct dock_function_info::@258 maintained_variables
object * objp_value
Definition: objectdock.h:38
void dock_find_max_speed_helper(object *objp, dock_function_info *infop)
Definition: objectdock.cpp:589
void dock_evaluate_all_docked_objects(object *objp, dock_function_info *infop, void(*function)(object *, dock_function_info *))
Definition: objectdock.cpp:285
#define fl_sqrt(fl)
Definition: floating.h:29
int ship_info_index
Definition: ship.h:539
SCP_vector< ship_info > Ship_info
Definition: ship.cpp:164
#define LOCATION
Definition: pstypes.h:245
object * docked_objp
Definition: objectdock.h:22
void dock_calc_docked_center_of_mass(vec3d *dest, object *objp)
Definition: objectdock.cpp:139
bool dock_check_assume_hub()
Definition: objectdock.cpp:636
int temp
Definition: lua.cpp:4996
polymodel * pm
Definition: lua.cpp:1598
float mass
Definition: physics.h:39
uint flags
Definition: object.h:151
mission The_mission
void dock_calc_max_cross_sectional_radius_squared_perpendicular_to_line_helper(object *objp, dock_function_info *infop)
Definition: objectdock.cpp:483
float dock_calc_total_docked_mass(object *objp)
Definition: objectdock.cpp:152
char type
Definition: object.h:146
axis_type
Definition: objectdock.h:59
#define OF_DOCKED_ALREADY_HANDLED
Definition: object.h:117
void dock_calc_total_docked_mass_helper(object *objp, dock_function_info *infop)
Definition: objectdock.cpp:472