2 * $Logfile: /Freespace2/code/Model/MODEL.H $
7 * header file for information about polygon models
10 * Revision 1.1 2002/05/03 03:28:12 root
14 * 38 9/13/99 10:09a Andsager
15 * Add debug console commands to lower model render detail and fireball
16 * LOD for big ship explosiosns.
18 * 37 9/01/99 10:09a Dave
21 * 36 8/24/99 8:55p Dave
22 * Make sure nondimming pixels work properly in tech menu.
24 * 35 7/19/99 12:02p Andsager
25 * Allow AWACS on any ship subsystem. Fix sexp_set_subsystem_strength to
26 * only blow up subsystem if its strength is > 0
28 * 34 7/15/99 2:13p Dave
29 * Added 32 bit detection.
31 * 33 7/06/99 10:45a Andsager
32 * Modify engine wash to work on any ship that is not small. Add AWACS
35 * 32 6/18/99 5:16p Dave
36 * Added real beam weapon lighting. Fixed beam weapon sounds. Added MOTD
37 * dialog to PXO screen.
39 * 31 5/26/99 11:46a Dave
40 * Added ship-blasting lighting and made the randomization of lighting
41 * much more customizable.
43 * 30 5/26/99 9:09a Andsager
44 * Increase number of live debris and MAX_MODEL_TEXTURES (for rebel base)
46 * 29 5/24/99 5:45p Dave
47 * Added detail levels to the nebula, with a decent speedup. Split nebula
48 * lightning into its own section.
50 * 28 5/11/99 10:16p Andsager
51 * First pass on engine wash effect. Rotation (control input), damage,
54 * 27 4/26/99 8:49p Dave
55 * Made all pof based nebula stuff full customizable through fred.
57 * 26 4/23/99 5:53p Dave
58 * Started putting in new pof nebula support into Fred.
60 * 25 4/19/99 12:51p Andsager
61 * Add function to find the nearest point on extneded bounding box and
62 * check if inside bounding box.
64 * 24 4/06/99 9:50a Enricco
65 * Bump up max live_debris from 4 to 5
67 * 23 3/31/99 8:24p Dave
68 * Beefed up all kinds of stuff, incluging beam weapons, nebula effects
69 * and background nebulae. Added per-ship non-dimming pixel colors.
71 * 22 3/23/99 5:17p Dave
72 * Changed model file format somewhat to account for LOD's on insignias
74 * 21 3/19/99 9:51a Dave
75 * Checkin to repair massive source safe crash. Also added support for
76 * pof-style nebulae, and some new weapons code.
78 * 20 3/08/99 7:03p Dave
79 * First run of new object update system. Looks very promising.
81 * 19 3/02/99 9:25p Dave
82 * Added a bunch of model rendering debug code. Started work on fixing
83 * beam weapon wacky firing.
85 * 18 2/19/99 11:42a Dave
86 * Put in model rendering autocentering.
88 * 17 2/19/99 11:09a Jasen
89 * Upped MAX_MODEL_SUBSYSTEMS to 128 (for the souper cap
91 * 16 1/25/99 5:03a Dave
92 * First run of stealth, AWACS and TAG missile support. New mission type
95 * 15 1/14/99 6:06p Dave
96 * 100% full squad logo support for single player and multiplayer.
98 * 14 1/12/99 12:53a Dave
99 * More work on beam weapons - made collision detection very efficient -
100 * collide against all object types properly - made 3 movement types
101 * smooth. Put in test code to check for possible non-darkening pixels on
104 * 13 1/11/99 12:56p Andsager
107 * 12 1/11/99 12:42p Andsager
108 * Add live debris - debris which is created from a destroyed subsystem,
109 * when the ship is still alive
111 * 11 1/08/99 2:08p Dave
112 * Fixed software rendering for pofview. Super early support for AWACS and
115 * 10 12/23/98 2:53p Andsager
116 * Added stepped rotation support
118 * 9 12/09/98 7:34p Dave
119 * Cleanup up nebula effect. Tweaked many values.
121 * 8 12/04/98 3:34p Andsager
122 * Handle norotating submodels
124 * 7 12/03/98 3:14p Andsager
125 * Check in code that checks rotating submodel actually has ship subsystem
127 * 6 11/19/98 11:07p Andsager
128 * Check in of physics and collision detection of rotating submodels
130 * 5 11/11/98 5:37p Dave
131 * Checkin for multiplayer testing.
133 * 4 10/23/98 3:03p Andsager
134 * Initial support for changing rotation rate.
136 * 3 10/16/98 9:40a Andsager
137 * Remove ".h" files from model.h
139 * 2 10/07/98 10:53a Dave
142 * 1 10/07/98 10:50a Dave
144 * 159 8/28/98 3:29p Dave
145 * EMP effect done. AI effects may need some tweaking as required.
147 * 158 5/19/98 8:31p Andsager
148 * Added split planes (for big ship explosions)
150 * 157 5/07/98 5:39p Andsager
151 * Changes to model to hold cross section info
153 * 156 4/22/98 9:58p John
154 * Added code to view invisible faces.
156 * 155 4/22/98 9:43p John
157 * Added code to allow checking of invisible faces, flagged by any texture
158 * name with invisible in it.
160 * 154 4/01/98 5:34p John
161 * Made only the used POFs page in for a level. Reduced some interp
162 * arrays. Made custom detail level work differently.
164 * 153 3/31/98 5:18p John
165 * Removed demo/save/restore. Made NDEBUG defined compile. Removed a
166 * bunch of debug stuff out of player file. Made model code be able to
167 * unload models and malloc out only however many models are needed.
170 * 152 3/31/98 11:19a Allender
171 * upped MAX_MODEL_SUBSYSTEMS to a resonable value
173 * 151 3/31/98 11:02a Adam
174 * upped MAX_MODEL_SUBSYSTEMS to 33
176 * 150 3/25/98 11:23a Mike
177 * Fix stack overwrite due to async between MAX_SECONDARY_WEAPONS and
180 * 149 3/24/98 10:11p Sandeep
182 * 148 3/24/98 4:03p Lawrance
183 * JOHN: Fix up outline drawing code to support different colors
185 * 147 3/22/98 10:19a Adam
186 * upped subsystem & secondary weapon constants for Frank's new capital
189 * 146 3/21/98 3:33p Lawrance
190 * Allow model outline color to be set directly
192 * 145 3/19/98 5:24p John
193 * Added code to find the closest point on a model to another point. Used
194 * this for detail levels and for targetting info.
196 * 144 3/16/98 4:51p John
197 * Added low-level code to clip all polygons against an arbritary plane.
198 * Took out all old model_interp_zclip and used this new method instead.
200 * 143 3/13/98 9:06a John
201 * Made missile thrusters use a different min dist for scaling. Made
202 * missilies not use lighting.
204 * 142 3/02/98 5:42p John
205 * Removed WinAVI stuff from Freespace. Made all HUD gauges wriggle from
206 * afterburner. Made gr_set_clip work good with negative x &y. Made
207 * model_caching be on by default. Made each cached model have it's own
208 * bitmap id. Made asteroids not rotate when model_caching is on.
210 * 141 2/24/98 5:04p Allender
211 * allow different ship classes to use the same model. Lot's of subsystem
214 * 140 2/24/98 1:58p John
215 * Made asteroids use model_caching. Made asteroids darken with distance.
217 * 139 1/29/98 5:50p John
218 * Made electrical arcing on debris pieces be persistent from frame to
221 * 138 1/27/98 11:02a John
222 * Added first rev of sparks. Made all code that calls model_render call
223 * clear_instance first. Made debris pieces not render by default when
224 * clear_instance is called.
226 * 137 1/23/98 5:08p John
227 * Took L out of vertex structure used B (blue) instead. Took all small
228 * fireballs out of fireball types and used particles instead. Fixed some
229 * debris explosion things. Restructured fireball code. Restructured
230 * some lighting code. Made dynamic lighting on by default. Made groups
231 * of lasers only cast one light. Made fireballs not cast light.
233 * 136 1/15/98 3:28p John
234 * Took out the unused ptnorms array. Saved a measly 8MB of RAM, so it
235 * might not have been worth ripping out. :-)
237 * 135 1/09/98 11:25a John
238 * Took the thruster animation stuff out of the model.
240 * 134 12/31/97 2:35p John
241 * Added code for core_radius
243 * 133 12/22/97 8:55a John
244 * added parameters for checking models.
246 * 132 12/17/97 5:11p John
247 * Added brightening back into fade table. Added code for doing the fast
248 * dynamic gun flashes and thruster flashes.
250 * 131 12/17/97 9:54a John
251 * added code for precalculated weapon flash lighting.
253 * 130 12/05/97 3:46p John
254 * made ship thruster glow scale instead of being an animation.
267 #define MAX_PRIMARY_BANKS 3
268 #define MAX_SECONDARY_BANKS 4 // Lowered from 5 to 4 by MK on 3/25/98. This needs to be <= MAX_WL_SECONDARY or you'll get stack overwrites.
270 #define MAX_POLYGON_MODELS 128
271 #define MAX_DEBRIS_OBJECTS 32
272 #define MAX_MODEL_TEXTURES 64
273 #define FILENAME_LEN 64
274 #define MAX_MODEL_DETAIL_LEVELS 8
275 #define MAX_PROP_LEN 256
276 #define MAX_NAME_LEN 32
277 #define MAX_ARC_EFFECTS 8
279 #define MOVEMENT_TYPE_NONE -1
280 #define MOVEMENT_TYPE_POS 0
281 #define MOVEMENT_TYPE_ROT 1
282 #define MOVEMENT_TYPE_ROT_SPECIAL 2 // for turrets only
284 // DA 11/13/98 Reordered to account for difference between max and game
285 #define MOVEMENT_AXIS_NONE -1
286 #define MOVEMENT_AXIS_X 0
287 #define MOVEMENT_AXIS_Y 2
288 #define MOVEMENT_AXIS_Z 1
290 #define MAX_ROTATING_SUBMODELS 10
292 // defines for special objects like gun and missile points, docking point, etc
293 // Hoffoss: Please make sure that subsystem NONE is always index 0, and UNKNOWN is
294 // always the last subsystem in the list. Also, make sure that MAX is correct.
295 // Otherwise, problems will arise in Fred.
297 #define SUBSYSTEM_NONE 0
298 #define SUBSYSTEM_ENGINE 1
299 #define SUBSYSTEM_TURRET 2
300 #define SUBSYSTEM_RADAR 3
301 #define SUBSYSTEM_NAVIGATION 4
302 #define SUBSYSTEM_COMMUNICATION 5
303 #define SUBSYSTEM_WEAPONS 6
304 #define SUBSYSTEM_SENSORS 7
305 #define SUBSYSTEM_SOLAR 8
306 #define SUBSYSTEM_GAS_COLLECT 9
307 #define SUBSYSTEM_ACTIVATION 10
308 #define SUBSYSTEM_UNKNOWN 11
310 #define SUBSYSTEM_MAX 12 // maximum value for subsystem_xxx, for error checking
312 #define MAX_TFP 4 // maximum number of turret firing points
314 #define MAX_SPLIT_PLANE 3 // number of artist specified split planes (used in big ship explosions)
316 // Data specific to a particular instance of a submodel. This gets stuffed/unstuffed using
317 // the model_clear_instance, model_set_instance, model_get_instance functions.
318 typedef struct submodel_instance_info {
319 int blown_off; // If set, this subobject is blown off
320 angles angs; // The current angle this thing is turned to.
322 vector pt_on_axis; // in ship RF
324 float desired_turn_rate;
327 int step_zero_timestamp; // timestamp determines when next step is to begin (for stepped rotation)
329 } submodel_instance_info;
331 #define MAX_MODEL_SUBSYSTEMS 128 // used in ships.cpp (only place?) for local stack variable
332 // when reading in ships.tbl
334 #define MSS_FLAG_ROTATES (1<<0) // This means the object rotates automatically with "turn_rate"
335 #define MSS_FLAG_STEPPED_ROTATE (1<<1) // This means that the rotation occurs in steps
336 #define MSS_FLAG_AI_ROTATE (1<<2) // This means that the rotation is controlled by ai
337 #define MSS_FLAG_CREWPOINT (1<<3) // If set, this is a crew point.
338 #define MSS_FLAG_TURRET_MATRIX (1<<4) // If set, this has it's turret matrix created correctly.
339 #define MSS_FLAG_AWACS (1<<5) // If set, this subsystem has AWACS capability
341 // definition of stepped rotation struct
342 typedef struct stepped_rotation {
343 int num_steps; // number of steps in complete revolution
344 float fraction; // fraction of time in step spent in accel
345 float t_transit; // time spent moving from one step to next
346 float t_pause; // time at rest between steps
347 float max_turn_rate; // max turn rate going betweens steps
348 float max_turn_accel; // max accel going between steps
349 } stepped_rotation_t;
351 typedef struct ai_rotation {
358 // definition for model subsystems.
359 typedef struct model_subsystem { /* contains rotation rate info */
360 uint flags; // See MSS_FLAG_* defines above
361 char name[MAX_NAME_LEN]; // name of the subsystem. Probably displayed on HUD
362 char subobj_name[MAX_NAME_LEN]; // Temporary (hopefully) parameter used to match stuff in ships.tbl
363 int subobj_num; // subobject number (from bspgen) -- used to match subobjects of subsystems to these entries
364 int model_num; // Which model this is attached to (i.e. the polymodel[] index)
365 int type; // type. see SUBSYSTEM_* types above. A generic type thing
366 vector pnt; // center point of this subsystem
367 float radius; // the extent of the subsystem
368 float max_hits; // maximum hits of this subsystem
370 // The following items are specific to turrets and will probably be moved to
371 // a separate struct so they don't take up space for all subsystem types.
372 char crewspot[MAX_NAME_LEN]; // unique identifying name for this turret -- used to assign AI class and multiplayer people
373 int turret_weapon_type; // index in Weapon_info of weapon this fires
374 vector turret_norm; // direction this turret faces
375 matrix turret_matrix; // turret_norm converted to a matrix.
376 float turret_fov; // dot of turret_norm:vec_to_enemy > this means can see
377 int turret_num_firing_points; // number of firing points on this turret
378 vector turret_firing_point[MAX_TFP]; // in parent object's reference frame, point from which to fire.
379 int turret_gun_sobj; // Which subobject in this model the firing points are linked to.
380 float turret_turning_rate; // How fast the turret turns. Read from ships.tbl
383 char engine_wash_index; // index into Engine_wash_info
385 // Rotation specific info
386 float turn_rate; // The turning rate of this subobject, if MSS_FLAG_ROTATES is set.
387 stepped_rotation_t *stepped_rotation; // turn rotation struct
388 ai_rotation_t *ai_rotation; // ai controlled rotation struct
390 // AWACS specific information
391 float awacs_intensity; // awacs intensity of this subsystem
392 float awacs_radius; // radius of effect of the AWACS
394 int primary_banks[MAX_PRIMARY_BANKS]; // default primary weapons -hoffoss
395 int secondary_banks[MAX_SECONDARY_BANKS]; // default secondary weapons -hoffoss
396 int secondary_bank_capacity[MAX_SECONDARY_BANKS]; // capacity of a bank -hoffoss
397 int path_num; // path index into polymodel .paths array. -2 if none exists, -1 if not defined
400 typedef struct model_special {
401 struct model_special *next, *prev; // for using as a linked list
402 int bank; // used for sequencing gun/missile backs. approach/docking points
403 int slot; // location for gun or missile in this bank
404 vector pnt; // point where this special submodel thingy is at
405 vector norm; // normal for the special submodel thingy
409 #define MARC_TYPE_NORMAL 0 // standard freespace 1 blue lightning arcs
410 #define MARC_TYPE_EMP 1 // EMP blast type arcs
412 #define MAX_LIVE_DEBRIS 7
414 typedef struct bsp_info {
415 char name[MAX_NAME_LEN]; // name of the subsystem. Probably displayed on HUD
416 int movement_type; // -1 if no movement, otherwise rotational or positional movement -- subobjects only
417 int movement_axis; // which axis this subobject moves or rotates on.
419 vector offset; // 3d offset from parent object
424 vector geometric_center; // geometric center of this subobject. In the same Frame Of
425 // Reference as all other vertices in this submodel. (Relative to pivot point)
426 float rad; // radius for each submodel
428 vector min; // The min point of this object's geometry
429 vector max; // The max point of this object's geometry
430 vector bounding_box[8]; // caclulated fron min/max
432 int blown_off; // If set, this subobject is blown off. Stuffed by model_set_instance
433 int my_replacement; // If not -1 this subobject is what should get rendered instead of this one
434 int i_replace; // If this is not -1, then this subobject will replace i_replace when it is damaged
435 angles angs; // The angles from parent. Stuffed by model_set_instance
437 int is_live_debris; // whether current submodel is a live debris model
438 int num_live_debris; // num live debris models assocaiated with a submodel
439 int live_debris[MAX_LIVE_DEBRIS]; // array of live debris submodels for a submodel
441 submodel_instance_info *sii; // stuff needed for collision from rotations
447 int parent; // what is parent for each submodel, -1 if none
448 int num_children; // How many children this model has
449 int first_child; // The first_child of this model, -1 if none
450 int next_sibling; // This submodel's next sibling, -1 if none
452 int num_details; // How many submodels are lower detail "mirrors" of this submodel
453 int details[MAX_MODEL_DETAIL_LEVELS]; // A list of all the lower detail "mirrors" of this submodel
455 // Electrical Arc Effect Info
456 // Sets a spark for this submodel between vertex v1 and v2
457 int num_arcs; // See model_add_arc for more info
458 vector arc_pts[MAX_ARC_EFFECTS][2];
459 ubyte arc_type[MAX_ARC_EFFECTS]; // see MARC_TYPE_* defines
464 #define MP_TYPE_UNUSED 0
465 #define MP_TYPE_SUBSYS 1
467 typedef struct mp_vert {
468 vector pos; // xyz coordinates of vertex in object's frame of reference
469 int nturrets; // number of turrets guarding this vertex
470 int *turret_ids; // array of indices into ship_subsys linked list (can't index using [] though)
471 float radius; // How far the closest obstruction is from this vertex
474 typedef struct model_path {
475 char name[MAX_NAME_LEN]; // name of the subsystem. Probably displayed on HUD
476 char parent_name[MAX_NAME_LEN]; // parent name of submodel that path is linked to in POF
480 int goal; // Which of the verts is the one closest to the goal of this path
481 int type; // What this path takes you to... See MP_TYPE_??? defines above for details
482 int value; // This depends on the type.
483 // For MP_TYPE_UNUSED, this means nothing.
484 // For MP_TYPE_SUBSYS, this is the subsystem number this path takes you to.
487 typedef struct model_tmap_vert {
493 // info for gun and missile banks. Also used for docking points. There should always
494 // only be two slots for each docking bay
497 #define MAX_THRUSTER_SLOTS 10
499 typedef struct w_bank {
501 vector pnt[MAX_SLOTS];
502 vector norm[MAX_SLOTS];
503 float radius[MAX_SLOTS];
506 typedef struct thruster_bank {
508 vector pnt[MAX_THRUSTER_SLOTS];
509 vector norm[MAX_THRUSTER_SLOTS];
510 float radius[MAX_THRUSTER_SLOTS];
513 char wash_info_index; // index into Engine_wash_info
517 // defines for docking bay things. The types are essentially flags since docking bays can probably
518 // be used for multiple things in some cases (i.e. rearming and general docking)
520 #define DOCK_TYPE_CARGO (1<<0)
521 #define DOCK_TYPE_REARM (1<<1)
522 #define DOCK_TYPE_GENERIC (1<<2)
524 #define MAX_DOCK_SLOTS 2
526 typedef struct dock_bay {
528 int type_flags; // indicates what this docking bay can be used for (i.e. cargo/rearm, etc)
529 int num_spline_paths; // number of spline paths which lead to this docking bay
530 int *splines; // array of indices into the Spline_path array
531 char name[MAX_NAME_LEN]; // name of this docking location
532 vector pnt[MAX_DOCK_SLOTS];
533 vector norm[MAX_DOCK_SLOTS];
536 // struct that holds the indicies into path information associated with a fighter bay on a capital ship
537 // NOTE: Fighter bay paths are identified by the path_name $bayN (where N is numbered from 1).
538 // Capital ships only have ONE fighter bay on the entire ship
539 #define MAX_SHIP_BAY_PATHS 10
540 typedef struct ship_bay {
541 int num_paths; // how many paths are associated with the model's fighter bay
542 int paths[MAX_SHIP_BAY_PATHS]; // index into polymodel->paths[] array
543 int arrive_flags; // bitfield, set to 1 when that path number is reserved for an arrival
544 int depart_flags; // bitfield, set to 1 when that path number is reserved for a departure
547 // three structures now used for representing shields.
548 // shield_tri structure stores information concerning each face of the shield.
549 // verts indexes into the verts array in the higher level structure
550 // neighbors indexes into the tris array in the higher level structure
551 typedef struct shield_tri {
553 int verts[3]; // 3 indices into vertex list of the shield. list found in shield_info struct
554 int neighbors[3]; // indices into array of triangles. neighbor = shares edge. list found in shield_info struct
555 vector norm; // norm of this triangle
558 // a list of these shield_vertex structures comprimises the vertex list of the shield.
559 // The verts array in the shield_tri structure points to one of these members
560 typedef struct shield_vertex {
565 // the high level shield structure. A ship without any shield has nverts and ntris set to 0.
566 // The vertex list and the tris list are used by the shield_tri structure
567 typedef struct shield_info {
570 shield_vertex *verts;
574 #define BSP_LIGHT_TYPE_WEAPON 1
575 #define BSP_LIGHT_TYPE_THRUSTER 2
577 typedef struct bsp_light {
579 int type; // See BSP_LIGHT_TYPE_?? for values
580 float value; // How much to light up this light. 0-1.
583 // model_octant - There are 8 of these per model. They are a handy way to catagorize
584 // a lot of model properties to get some easy 8x optimizations for model stuff.
585 typedef struct model_octant {
586 vector min, max; // The bounding box that makes up this octant defined as 2 points.
587 int nverts; // how many vertices are in this octant
588 vector **verts; // The vertices in this octant in the high-res hull. A vertex can only be in one octant.
589 int nshield_tris; // how many shield triangles are in the octant
590 shield_tri **shield_tris; // the shield triangles that make up this octant. A tri could be in multiple octants.
596 int parent; // parent's subobject number
597 vector pnt; // the point for the eye
598 vector norm; // direction the eye faces. Not used with first eye since player orient is used
601 typedef struct cross_section {
606 #define MAX_MODEL_INSIGNIAS 6
607 #define MAX_INS_FACE_VECS 3
608 #define MAX_INS_VECS 20
609 #define MAX_INS_FACES 10
610 typedef struct insignia {
613 int faces[MAX_INS_FACES][MAX_INS_FACE_VECS]; // indices into the vecs array
614 float u[MAX_INS_FACES][MAX_INS_FACE_VECS]; // u tex coords on a per-face-per-vertex basis
615 float v[MAX_INS_FACES][MAX_INS_FACE_VECS]; // v tex coords on a per-face-per-vertex bases
616 vector vecs[MAX_INS_VECS]; // vertex list
617 vector offset; // global position offset for this insignia
620 #define PM_FLAG_ALLOW_TILING (1<<0) // Allow texture tiling
621 #define PM_FLAG_AUTOCEN (1<<1) // contains autocentering info
623 //used to describe a polygon model
624 typedef struct polymodel {
625 int id; // what the polygon model number is. (Index in Polygon_models)
627 char filename[FILENAME_LEN];
629 uint flags; // 1=allow tiling
631 int detail[MAX_MODEL_DETAIL_LEVELS];
632 float detail_depth[MAX_MODEL_DETAIL_LEVELS];
634 int num_debris_objects;
635 int debris_objects[MAX_DEBRIS_OBJECTS];
639 vector mins,maxs; //min,max for whole model
640 vector bounding_box[8];
642 int num_lights; // how many lights there are
643 bsp_light * lights; // array of light info
645 int n_view_positions; // number of viewing positions available on this ship
646 eye view_positions[MAX_EYES]; //viewing positions. Default to {0,0,0}. in location 0
648 float rad; // The radius of everything in the model; shields, thrusters.
649 float core_radius; // The radius to be used for collision detection in small ship vs big ships.
650 // This is equal to 1/2 of the smallest dimension of the hull's bounding box.
652 int original_textures[MAX_MODEL_TEXTURES]; // what gets read in from file
653 int textures[MAX_MODEL_TEXTURES]; // what textures you draw with. reset to original_textures by model_set_instance
655 vector autocenter; // valid only if PM_FLAG_AUTOCEN is set
657 bsp_info *submodel; // an array of size n_models of submodel info.
659 // linked lists for special polygon types on this model. Most ships I think will have most
660 // of these. (most ships however, probably won't have approach points).
661 int n_guns; // number of primary gun points (not counting turrets)
662 int n_missiles; // number of secondary missile points (not counting turrets)
663 int n_docks; // number of docking points
664 int n_thrusters; // number of thrusters on this ship.
665 w_bank *gun_banks; // array of gun banks
666 w_bank *missile_banks; // array of missile banks
667 dock_bay *docking_bays; // array of docking point pairs
668 thruster_bank *thrusters; // array of thruster objects -- likely to change in the future
669 ship_bay *ship_bay_v; // contains path indexes for ship bay approach/depart paths
671 shield_info shield; // new shield information
678 vector center_of_mass;
679 matrix moment_of_inertia;
681 model_octant octants[8];
683 int num_xc; // number of cross sections
684 cross_section* xc; // pointer to array of cross sections (used in big ship explosions)
686 int num_split_plane; // number of split planes
687 float split_plane[MAX_SPLIT_PLANE]; // actual split plane z coords (for big ship explosions)
689 insignia ins[MAX_MODEL_INSIGNIAS];
693 int ram_used; // How much RAM this model uses
700 // Call once to initialize the model system
703 // call at the beginning of a level. after the level has been loaded
704 void model_level_post_init();
706 // Call to free all existing models
707 void model_free_all();
709 // Loads a model from disk and returns the model number it loaded into.
710 int model_load(char *filename, int n_subsystems, model_subsystem *subsystems);
712 // notify the model system that a ship has died
713 void model_notify_dead_ship(int objnum);
715 // Returns a pointer to the polymodel structure for model 'n'
716 polymodel * model_get(int model_num);
718 // routine to copy susbsystems. Must be called when subsystems sets are the same -- see ship.cpp
719 void model_copy_subsystems( int n_subsystems, model_subsystem *d_sp, model_subsystem *s_sp );
721 // If MR_FLAG_OUTLINE bit set this color will be used for outlines.
722 // This defaults to black.
723 void model_set_outline_color(int r, int g, int b );
725 void model_set_outline_color_fast(void *outline_color);
727 // IF MR_LOCK_DETAIL is set, then it will always draw detail level 'n'
728 // This defaults to 0. (0=highest, larger=lower)
729 void model_set_detail_level(int n);
731 // Flags you can pass to model_render
732 #define MR_NORMAL (0) // Draw a normal object
733 #define MR_SHOW_OUTLINE (1<<0) // Draw the object in outline mode. Color specified by model_set_outline_color
734 #define MR_SHOW_PIVOTS (1<<1) // Show the pivot points
735 #define MR_SHOW_PATHS (1<<2) // Show the paths associated with a model
736 #define MR_SHOW_RADIUS (1<<3) // Show the radius around the object
737 #define MR_SHOW_DAMAGE (1<<4) // Show the "destroyed" subobjects
738 #define MR_SHOW_SHIELDS (1<<5) // Show the sheild mesh
739 #define MR_SHOW_THRUSTERS (1<<6) // Show the engine thrusters. See model_set_thrust for how long it draws.
740 #define MR_LOCK_DETAIL (1<<7) // Only draw the detail level defined in model_set_detail_level
741 #define MR_NO_POLYS (1<<8) // Don't draw the polygons.
742 #define MR_NO_LIGHTING (1<<9) // Don't perform any lighting on the model.
743 #define MR_NO_TEXTURING (1<<10) // Draw textures as flat-shaded polygons.
744 #define MR_NO_CORRECT (1<<11) // Don't to correct texture mapping
745 #define MR_NO_SMOOTHING (1<<12) // Don't perform smoothing on vertices.
746 #define MR_ALWAYS_REDRAW (1<<13) // Don't do any model caching; redraw this model each frame!
747 #define MR_IS_ASTEROID (1<<14) // When set, treat this as an asteroid.
748 #define MR_IS_MISSILE (1<<15) // When set, treat this as a missilie. No lighting, small thrusters.
749 #define MR_SHOW_OUTLINE_PRESET (1<<16) // Draw the object in outline mode. Color assumed to be set already.
750 #define MR_SHOW_INVISIBLE_FACES (1<<17) // Show invisible faces as green...
751 #define MR_AUTOCENTER (1<<18) // Always use the center of the hull bounding box as the center, instead of the pivot point
752 #define MR_BAY_PATHS (1<<19) // draw bay paths
753 #define MR_ALL_XPARENT (1<<20) // render it fully transparent
754 #define MR_NO_ZBUFFER (1<<21) // switch z-buffering off completely
755 #define MR_NO_CULL (1<<22) // don't cull backfacing poly's
756 #define MR_FORCE_TEXTURE (1<<23) // force a given texture to always be used
757 #define MR_FORCE_LOWER_DETAIL (1<<24) // force the model to draw 1 LOD lower, if possible
759 // Renders a model and all it's submodels.
760 // See MR_? defines for values for flags
761 void model_render(int model_num, matrix *orient, vector * pos, uint flags = MR_NORMAL, int objnum = -1, int lighting_skip = -1 );
763 // Renders just one particular submodel on a model.
764 // See MR_? defines for values for flags
765 void submodel_render(int model_num,int submodel_num, matrix *orient, vector * pos, uint flags=MR_NORMAL, int light_ignore_id=-1 );
768 // Returns the radius of a model
769 float model_get_radius(int modelnum);
770 float submodel_get_radius( int modelnum, int submodelnum );
772 // Returns the core radius (smallest dimension of hull's bounding box, used for collision detection with big ships only)
773 float model_get_core_radius( int modelnum );
775 // Returns zero is x1,y1,x2,y2 are valid
776 // returns 1 for invalid model, 2 for point offscreen.
777 // note that x1,y1,x2,y2 aren't clipped to 2d screen coordinates!
778 // This function just looks at the radius, and not the orientation, so the
779 // bounding box won't change depending on the obj's orient.
780 extern int model_find_2d_bound(int model_num,matrix *orient, vector * pos,int *x1, int *y1, int *x2, int *y2 );
782 // Returns zero is x1,y1,x2,y2 are valid
783 // returns 1 for invalid model, 2 for point offscreen.
784 // note that x1,y1,x2,y2 aren't clipped to 2d screen coordinates!
785 // This function looks at the object's bounding box and it's orientation,
786 // so the bounds will change as the object rotates, to give the minimum bouding
788 extern int model_find_2d_bound_min(int model_num,matrix *orient, vector * pos,int *x1, int *y1, int *x2, int *y2 );
790 // Returns zero is x1,y1,x2,y2 are valid
791 // returns 1 for invalid model, 2 for point offscreen.
792 // note that x1,y1,x2,y2 aren't clipped to 2d screen coordinates!
793 // This function looks at the object's bounding box and it's orientation,
794 // so the bounds will change as the object rotates, to give the minimum bouding
796 int submodel_find_2d_bound_min(int model_num,int submodel, matrix *orient, vector * pos,int *x1, int *y1, int *x2, int *y2 );
799 // Returns zero is x1,y1,x2,y2 are valid
800 // Returns 2 for point offscreen.
801 // note that x1,y1,x2,y2 aren't clipped to 2d screen coordinates!
802 // This function just looks at the radius, and not the orientation, so the
803 // bounding box won't change depending on the obj's orient.
804 int subobj_find_2d_bound(float radius, matrix *orient, vector * pos,int *x1, int *y1, int *x2, int *y2 );
808 extern int modelstats_num_polys;
809 extern int modelstats_num_polys_drawn;
810 extern int modelstats_num_verts;
811 extern int modelstats_num_sortnorms;
814 // Tries to move joints so that the turrent points to the point dst.
815 // turret1 is the angles of the turret, turret2 is the angles of the gun from turret
816 extern int model_rotate_gun(int model_num, model_subsystem * turret, matrix *orient, angles * turret1, angles *turret2, vector * pos, vector * dst);
818 // Rotates the angle of a submodel. Use this so the right unlocked axis
820 extern void submodel_rotate(model_subsystem *psub, submodel_instance_info * sii );
822 // Rotates the angle of a submodel. Use this so the right unlocked axis
823 // gets stuffed. Does this for stepped rotations
824 void submodel_stepped_rotate(model_subsystem *psub, submodel_instance_info *sii);
826 // Given a point (pnt) that is in sub_model_num's frame of
827 // reference, and given the object's orient and position,
828 // return the point in 3-space in outpnt.
829 extern void model_find_world_point(vector * outpnt, vector *mpnt,int model_num, int sub_model_num, matrix * objorient, vector * objpos );
831 // Given a point in the world RF, find the corresponding point in the model RF.
832 // This is special purpose code, specific for model collision.
833 // NOTE - this code ASSUMES submodel is 1 level down from hull (detail[0])
834 void world_find_model_point(vector *out, vector *world_pt, polymodel *pm, int submodel_num, matrix *orient, vector *pos);
836 // Given a polygon model index, find a list of rotating submodels to be used for collision
837 void model_get_rotating_submodel_list(int *submodel_list, int *num_rotating_submodesl, object *objp);
839 // For a rotating submodel, find a point on the axis
840 void model_init_submodel_axis_pt(submodel_instance_info *sii, int model_num, int submodel_num);
842 // Given a direction (pnt) that is in sub_model_num's frame of
843 // reference, and given the object's orient and position,
844 // return the point in 3-space in outpnt.
845 extern void model_find_world_dir(vector * out_dir, vector *in_dir,int model_num, int sub_model_num, matrix * objorient, vector * objpos );
847 // Clears all the submodel instances stored in a model to their defaults.
848 extern void model_clear_instance(int model_num);
850 // Sets rotating submodel turn info to that stored in model
851 void model_set_instance_info(submodel_instance_info *sii, float turn_rate, float turn_accel);
853 // Clears all the values in a particular instance to their defaults.
854 extern void model_clear_instance_info(submodel_instance_info * sii);
856 // Sets the submodel instance data in a submodel
857 extern void model_set_instance(int model_num, int sub_model_num, submodel_instance_info * sii );
859 // Adds an electrical arcing effect to a submodel
860 void model_add_arc(int model_num, int sub_model_num, vector *v1, vector *v2, int arc_type );
862 // Fills in an array with points from a model. Only gets up to max_num verts.
863 // Returns number of verts found
864 extern int submodel_get_points(int model_num, int submodel_num, int max_num, vector **nts );
866 // Gets two random points on the surface of a submodel
867 extern void submodel_get_two_random_points(int model_num, int submodel_num, vector *v1, vector *v2, vector *n1 = NULL, vector *n2 = NULL);
869 // gets the index into the docking_bays array of the specified type of docking point
870 // Returns the index. second functions returns the index of the docking bay with
871 // the specified name
872 extern int model_find_dock_index(int modelnum, int dock_type);
873 extern int model_find_dock_name_index( int modelnum, char *name );
875 // returns the actual name of a docking point on a model, needed by Fred.
876 char *model_get_dock_name(int modelnum, int index);
878 // Returns number of verts in a submodel;
879 int submodel_get_num_verts(int model_num, int submodel_num );
881 // Returns number of polygons in a submodel;
882 int submodel_get_num_polys(int model_num, int submodel_num );
884 // returns number of docking points for a model
885 int model_get_num_dock_points(int modelnum);
886 int model_get_dock_index_type(int modelnum, int index);
888 // get all the different docking point types on a model
889 int model_get_dock_types(int modelnum);
891 // Given a vector that is in sub_model_num's frame of
892 // reference, and given the object's orient and position,
893 // return the vector in the model's frame of reference.
894 void model_find_obj_dir(vector *w_vec, vector *m_vec, object *ship_obj, int sub_model_num);
897 // This is the interface to model_check_collision. Rather than passing all these
898 // values and returning values in globals, just fill in a temporary variable with
899 // the input values and call model_check_collision
900 typedef struct mc_info {
902 int model_num; // What model to check
903 int submodel_num; // What submodel to check if MC_SUBMODEL is set
904 matrix *orient; // The orient of the model
905 vector *pos; // The pos of the model in world coordinates
906 vector *p0; // The starting point of the ray (sphere) to check
907 vector *p1; // The ending point of the ray (sphere) to check
908 int flags; // Flags that the model_collide code looks at. See MC_??? defines
909 float radius; // If MC_CHECK_THICK is set, checks a sphere moving with the radius.
912 int num_hits; // How many collisions were found
913 float hit_dist; // The distance from p0 to hitpoint
914 vector hit_point; // Where the collision occurred at in hit_submodel's coordinate system
915 vector hit_point_world; // Where the collision occurred at in world coordinates
916 int hit_submodel; // Which submodel got hit.
917 int hit_bitmap; // Which texture got hit. -1 if not a textured poly
918 float hit_u, hit_v; // Where on hit_bitmap the ray hit. Invalid if hit_bitmap < 0
919 int shield_hit_tri; // Which triangle on the shield got hit or -1 if none
920 vector hit_normal; // Vector normal of polygon of collision. (This is in submodel RF)
921 int edge_hit; // Set if an edge got hit. Only valid if MC_CHECK_THICK is set.
922 ubyte *f_poly; // pointer to flat poly where we intersected
923 ubyte *t_poly; // pointer to tmap poly where we intersected
925 // flags can be changed for the case of sphere check finds an edge hit
930 //======== MODEL_COLLIDE ============
932 // Model Collision flags, used in model_collide()
933 #define MC_CHECK_MODEL (1<<0) // Check the polygons in the model.
934 #define MC_CHECK_SHIELD (1<<1) // check for collision against shield, if it exists.
935 #define MC_ONLY_SPHERE (1<<2) // Only check bounding sphere. Not accurate, but fast.
936 // NOTE! This doesn't set hit_point correctly with MC_CHECK_SPHERELINE
937 #define MC_ONLY_BOUND_BOX (1<<3) // Only check bounding boxes. Pretty accurate and slower than MC_ONLY_SPHERE.
938 // Checks the rotatated bounding box of each submodel.
939 // NOTE! This doesn't set hit_point correctly with MC_CHECK_SPHERELINE
940 #define MC_CHECK_RAY (1<<4) // Checks a ray from p0 *through* p1 on to infinity
941 #define MC_CHECK_SPHERELINE (1<<5) // Checks a moving sphere rather than just a ray. Radius
942 #define MC_SUBMODEL (1<<6) // If this is set, only check the submodel specified in mc->submodel_num. Use with MC_CHECK_MODEL
943 #define MC_SUBMODEL_INSTANCE (1<<7) // Check submodel and its children (of a rotating submodel)
944 #define MC_CHECK_INVISIBLE_FACES (1<<8) // Check the invisible faces.
948 Checks to see if a vector from p0 to p0 collides with a model of
949 type 'model_num' at 'orient' 'pos'.
951 Returns the number of polys that were hit. Zero is none, obviously.
952 Return true if a collision with hull (or shield, if MC_CHECK_SHIELD set),
955 If it did it one or more, then hitpt is the closest 3d point that the
956 vector hit. See the MC_? defines for flag values.
958 Model_collide can test a sphere against either (1) shield or (2) model.
960 To check a sphere, set the radius of sphere in mc_info structure and
961 set the flag MC_CHECK_SPHERE.
963 Here is a sample for how to use:
967 mc.model_num = ???; // Fill in the model to check
968 mc.orient = &obj->orient; // The object's orient
969 mc.pos = &obj->pos; // The object's position
970 mc.p0 = &p0; // Point 1 of ray to check
971 mc.p1 = &p1; // Point 2 of ray to check
972 mc.flags = MC_CHECK_MODEL; // flags
974 ** TO COLLIDE AGAINST A LINE SEGMENT
978 // We hit submodel mc.hit_submodel on texture mc.hitbitmap,
979 // at point mc.hit_point_world, with uv's of mc.hit_u, mc.hit_v.
982 ** TO COLLIDE AGAINST A SPHERE
983 mc.flags |= MC_CHECK_SPHERELINE;
986 model_collide(&mc, radius);
988 // We hit submodel mc.hit_submodel on texture mc.hitbitmap,
989 // at point mc.hit_point_world, with uv's of mc.hit_u, mc.hit_v.
990 // Check (mc.edge_hit) to see if we hit an edge
994 int model_collide(mc_info * mc_info);
996 // Sets the submodel instance data in a submodel
997 // If show_damaged is true it shows only damaged submodels.
998 // If it is false it shows only undamaged submodels.
999 void model_show_damaged(int model_num, int show_damaged );
1002 //=========================== MODEL OCTANT STUFF ================================
1004 // Models are now divided into 8 octants. Sheilds too.
1005 // This made the collision code faster. Shield is 4x and ship faces
1006 // are about 2x faster.
1008 // Before, calling model_collide with flags=0 didn't check the shield
1009 // but did check the model itself. Setting the sheild flags caused
1010 // the shield to get check along with the ship.
1011 // Now, you need to explicitly tell the model_collide code to check
1012 // the model, so you can check the model or shield or both.
1014 // If you need to check them both, do it in one call; this saves some
1015 // time. If checking the shield is sufficient for determining
1016 // something (like if it is under the hud) then use just sheild
1017 // check, it is at least 5x faster than checking the model itself.
1020 // Model octant ordering - this is a made up ordering, but it makes sense.
1021 // X Y Z index description
1022 // - - - 0 left bottom rear
1023 // - - + 1 left bottom front
1024 // - + - 2 left top rear
1025 // - + + 3 left top front
1026 // + - - 4 right bottom rear
1027 // + - + 5 right bottom front
1028 // + + - 6 right top rear
1029 // + + + 7 right top front
1031 // Returns which octant point 'pnt' is closet to. This will always return
1032 // a valid octant (0-7) since the point doesn't have to be in an octant.
1033 // If model_orient and/or model_pos are NULL, pnt is assumed to already
1034 // be rotated into the model's local coordinates.
1035 // If oct is not null, it will be filled in with a pointer to the octant
1037 int model_which_octant_distant( vector *pnt, int model_num,matrix *model_orient, vector * model_pos, model_octant **oct );
1039 // Returns which octant point 'pnt' is in. This might return
1040 // -1 if the point isn't in any octant.
1041 // If model_orient and/or model_pos are NULL, pnt is assumed to already
1042 // be rotated into the model's local coordinates.
1043 // If oct is not null, it will be filled in with a pointer to the octant
1044 // data. Or NULL if the pnt isn't in the octant.
1045 int model_which_octant( vector *pnt, int model_num,matrix *model_orient, vector * model_pos, model_octant **oct );
1047 // scale the engines thrusters by this much
1048 // Only enabled if MR_SHOW_THRUSTERS is on
1049 void model_set_thrust(int model_num, float length, int bitmapnum, int glow_bitmapnum=-1, float glow_noise=1.0f);
1051 //=========================================================
1054 // Call once to init the model caching stuff
1055 void model_cache_init();
1057 // Call before every level to clean up the model caching stuff
1058 void model_cache_reset();
1060 // If TRUE, then model caching is enabled
1061 extern int Model_caching;
1064 //=======================================================================================
1065 // Finds the closest point on a model to a point in space. Actually only finds a point
1066 // on the bounding box of the model.
1068 // model_num Which model
1069 // submodel_num Which submodel, -1 for hull
1070 // orient Orientation of the model
1071 // pos Position of the model
1072 // eye_pos Point that you want to find the closest point to
1074 // distance from eye_pos to closest_point. 0 means eye_pos is
1075 // on or inside the bounding box.
1076 // Also fills in outpnt with the actual closest point.
1077 float model_find_closest_point( vector *outpnt, int model_num, int submodel_num, matrix *orient, vector * pos, vector *eye_pos );
1079 // set the insignia bitmap to be used when rendering a ship with an insignia (-1 switches it off altogether)
1080 void model_set_insignia_bitmap(int bmap);
1082 // set model transparency for use with MR_ALL_XPARENT
1083 void model_set_alpha(float alpha);
1085 // set the forces bitmap
1086 void model_set_forced_texture(int bmap);
1088 // see if the given texture is used by the passed model. 0 if not used, 1 if used, -1 on error
1089 int model_find_texture(int model_num, int bitmap);
1091 // find closest point on extended bounding box (the bounding box plus all the planes that make it up)
1092 // returns closest distance to extended box
1093 // positive return value means start_point is outside extended box
1094 // displaces closest point an optional amount delta to the outside of the box
1095 // closest_box_point can be NULL.
1096 float get_world_closest_box_point_with_delta(vector *closest_box_point, object *box_obj, vector *start_point, int *is_inside, float delta);
1098 // given a newly loaded model, page in all textures
1099 void model_page_in_textures(int modelnum, int ship_info_index);
1101 // is the given model a pirate ship?
1102 int model_is_pirate_ship(int modelnum);