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