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