home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / main / morph.c < prev    next >
Text File  |  1998-06-08  |  14KB  |  574 lines

  1. /*
  2. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  3. SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  4. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  5. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  6. IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  7. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  8. FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  9. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  10. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
  11. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  12. */
  13. /*
  14.  * $Source: f:/miner/source/main/rcs/morph.c $
  15.  * $Revision: 2.1 $
  16.  * $Author: john $
  17.  * $Date: 1995/02/27 18:26:33 $
  18.  * 
  19.  * Morphing code
  20.  * 
  21.  * $Log: morph.c $
  22.  * Revision 2.1  1995/02/27  18:26:33  john
  23.  * Fixed bug that was caused by externing Polygon_models, and I had
  24.  * changed the type of it in polyobj.c, thus causing page faults.
  25.  * 
  26.  * Revision 2.0  1995/02/27  11:27:44  john
  27.  * New version 2.0, which has no anonymous unions, builds with
  28.  * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
  29.  * 
  30.  * Revision 1.35  1995/02/22  14:45:37  allender
  31.  * remove anonymous unions from object structure
  32.  * 
  33.  * Revision 1.34  1995/01/14  19:16:52  john
  34.  * First version of new bitmap paging code.
  35.  * 
  36.  * Revision 1.33  1995/01/03  20:38:36  john
  37.  * Externed MAX_MORPH_OBJECTS
  38.  * 
  39.  * Revision 1.32  1994/11/17  15:34:04  matt
  40.  * Attempt #4 to fix morph bug
  41.  * 
  42.  * Revision 1.31  1994/11/15  10:57:14  matt
  43.  * Tried again to fix morph
  44.  * 
  45.  * Revision 1.30  1994/11/14  14:06:45  matt
  46.  * Fixed stupid bug
  47.  * 
  48.  * Revision 1.29  1994/11/14  11:55:13  matt
  49.  * Added divide overflow check
  50.  * 
  51.  * Revision 1.28  1994/09/26  17:28:14  matt
  52.  * Made new multiple-object morph code work with the demo system
  53.  * 
  54.  * Revision 1.27  1994/09/26  15:39:56  matt
  55.  * Allow multiple simultaneous morphing objects
  56.  * 
  57.  * Revision 1.26  1994/09/11  22:44:59  mike
  58.  * quick on vecmat function.
  59.  * 
  60.  * Revision 1.25  1994/08/26  15:36:00  matt
  61.  * Made eclips usable on more than one object at a time
  62.  * 
  63.  * Revision 1.24  1994/07/25  00:02:46  matt
  64.  * Various changes to accomodate new 3d, which no longer takes point numbers
  65.  * as parms, and now only takes pointers to points.
  66.  * 
  67.  * Revision 1.23  1994/07/12  12:39:58  matt
  68.  * Revamped physics system
  69.  * 
  70.  * Revision 1.22  1994/06/28  11:54:51  john
  71.  * Made newdemo system record/play directly to/from disk, so
  72.  * we don't need the 4 MB buffer anymore.
  73.  * 
  74.  * Revision 1.21  1994/06/27  15:53:01  john
  75.  * #define'd out the newdemo stuff
  76.  * 
  77.  * 
  78.  * Revision 1.20  1994/06/16  14:30:19  matt
  79.  * Moved morph record data call to reder routine
  80.  * 
  81.  * Revision 1.19  1994/06/16  13:57:23  matt
  82.  * Added support for morphing objects in demos
  83.  * 
  84.  * Revision 1.18  1994/06/16  12:24:23  matt
  85.  * Made robot lighting not mess with Lighting_on so robots now night
  86.  * according to this variable.
  87.  * 
  88.  * Revision 1.17  1994/06/14  16:55:01  matt
  89.  * Got rid of physics_object speed field
  90.  * 
  91.  * Revision 1.16  1994/06/08  21:16:29  matt
  92.  * Made objects spin while morphing
  93.  * 
  94.  * Revision 1.15  1994/06/08  18:21:53  matt
  95.  * Made morphing objects light correctly
  96.  * 
  97.  * Revision 1.14  1994/06/07  16:50:49  matt
  98.  * Made object lighting work correctly; changed name of Ambient_light to
  99.  * Dynamic_light; cleaned up polygobj object rendering a little.
  100.  * 
  101.  * Revision 1.13  1994/06/01  16:33:59  yuan
  102.  * Fixed bug.
  103.  * 
  104.  * 
  105.  * Revision 1.12  1994/06/01  16:29:08  matt
  106.  * If morph_frame called on object this isn't the morph object, kill it.
  107.  * 
  108.  * Revision 1.11  1994/06/01  12:46:34  matt
  109.  * Added needed include
  110.  * 
  111.  * Revision 1.10  1994/05/31  22:12:41  matt
  112.  * Set lighting for morph objects
  113.  * Don't let another object start morph while one is morphing, unless
  114.  * that one dies.
  115.  * 
  116.  * Revision 1.9  1994/05/31  18:49:53  john
  117.  * Took out debugging printf's that Matt left in.
  118.  * 
  119.  * Revision 1.8  1994/05/30  22:50:22  matt
  120.  * Added morph effect for robots
  121.  * 
  122.  * 
  123.  * 
  124.  */
  125.  
  126.  
  127. #pragma off (unreferenced)
  128. static char rcsid[] = "$Id: morph.c 2.1 1995/02/27 18:26:33 john Exp $";
  129. #pragma on (unreferenced)
  130.  
  131. #include <stdio.h>
  132. #include <stdlib.h>
  133. #include <string.h>
  134.  
  135. #include "texmap.h"
  136. #include "error.h"
  137.  
  138. #include "inferno.h"
  139. #include "morph.h"
  140. #include "polyobj.h"
  141. #include "game.h"
  142. #include "lighting.h"
  143. #include "newdemo.h"
  144. #include "piggy.h"
  145.  
  146. #include "mono.h"
  147. #include "bm.h"
  148.  
  149. morph_data morph_objects[MAX_MORPH_OBJECTS];
  150.  
  151. //returns ptr to data for this object, or NULL if none
  152. morph_data *find_morph_data(object *obj)
  153. {
  154.     int i;
  155.  
  156.     #ifdef NEWDEMO
  157.     if (Newdemo_state == ND_STATE_PLAYBACK) {
  158.         morph_objects[0].obj = obj;
  159.         return &morph_objects[0];
  160.     }
  161.     #endif
  162.  
  163.     for (i=0;i<MAX_MORPH_OBJECTS;i++)
  164.         if (morph_objects[i].obj == obj)
  165.             return &morph_objects[i];
  166.  
  167.     return NULL;
  168. }
  169.  
  170.  
  171. //takes pm, fills in min & max
  172. find_min_max(polymodel *pm,int submodel_num,vms_vector *minv,vms_vector *maxv)
  173. {
  174.     ushort nverts;
  175.     vms_vector *vp;
  176.     ushort *data,type;
  177.  
  178.     data = (ushort *) &pm->model_data[pm->submodel_ptrs[submodel_num]];
  179.  
  180.     type = *data++;
  181.  
  182.     Assert(type == 7 || type == 1);
  183.  
  184.     nverts = *data++;
  185.  
  186.     if (type==7)
  187.         data+=2;        //skip start & pad
  188.  
  189.     vp = (vms_vector *) data;
  190.  
  191.     *minv = *maxv = *vp++; nverts--;
  192.  
  193.     while (nverts--) {
  194.         if (vp->x > maxv->x) maxv->x = vp->x;
  195.         if (vp->y > maxv->y) maxv->y = vp->y;
  196.         if (vp->z > maxv->z) maxv->z = vp->z;
  197.  
  198.         if (vp->x < minv->x) minv->x = vp->x;
  199.         if (vp->y < minv->y) minv->y = vp->y;
  200.         if (vp->z < minv->z) minv->z = vp->z;
  201.  
  202.         vp++;
  203.     }
  204.  
  205. }
  206.  
  207. #define MORPH_RATE (f1_0*3)
  208.  
  209. fix morph_rate = MORPH_RATE;
  210.  
  211. init_points(polymodel *pm,vms_vector *box_size,int submodel_num,morph_data *md)
  212. {
  213.     ushort nverts;
  214.     vms_vector *vp;
  215.     ushort *data,type;
  216.     int i;
  217.  
  218.     //printf("initing %d ",submodel_num);
  219.  
  220.     data = (ushort *) &pm->model_data[pm->submodel_ptrs[submodel_num]];
  221.  
  222.     type = *data++;
  223.  
  224.     Assert(type == 7 || type == 1);
  225.  
  226.     nverts = *data++;
  227.  
  228.     md->n_morphing_points[submodel_num] = 0;
  229.  
  230.     if (type==7) {
  231.         i = *data++;        //get start point number
  232.         data++;                //skip pad
  233.     }
  234.     else
  235.         i = 0;                //start at zero
  236.  
  237.     Assert(i+nverts < MAX_VECS);
  238.  
  239.     md->submodel_startpoints[submodel_num] = i;
  240.  
  241.     vp = (vms_vector *) data;
  242.  
  243.     while (nverts--) {
  244.         fix k,dist;
  245.  
  246.         if (box_size) {
  247.             fix t;
  248.  
  249.             k = 0x7fffffff;
  250.  
  251.             if (vp->x && f2i(box_size->x)<abs(vp->x)/2 && (t = fixdiv(box_size->x,abs(vp->x))) < k) k=t;
  252.             if (vp->y && f2i(box_size->y)<abs(vp->y)/2 && (t = fixdiv(box_size->y,abs(vp->y))) < k) k=t;
  253.             if (vp->z && f2i(box_size->z)<abs(vp->z)/2 && (t = fixdiv(box_size->z,abs(vp->z))) < k) k=t;
  254.  
  255.             if (k==0x7fffffff) k=0;
  256.  
  257.         }
  258.         else
  259.             k=0;
  260.  
  261.         vm_vec_copy_scale(&md->morph_vecs[i],vp,k);
  262.  
  263.         dist = vm_vec_normalized_dir_quick(&md->morph_deltas[i],vp,&md->morph_vecs[i]);
  264.  
  265.         md->morph_times[i] = fixdiv(dist,morph_rate);
  266.  
  267.         if (md->morph_times[i] != 0)
  268.             md->n_morphing_points[submodel_num]++;
  269.  
  270.         vm_vec_scale(&md->morph_deltas[i],morph_rate);
  271.  
  272.         vp++; i++;
  273.  
  274.     }
  275.  
  276.     //printf("npoints = %d\n",n_morphing_points[submodel_num]);
  277.  
  278. }
  279.  
  280. update_points(polymodel *pm,int submodel_num,morph_data *md)
  281. {
  282.     ushort nverts;
  283.     vms_vector *vp;
  284.     ushort *data,type;
  285.     int i;
  286.  
  287.     //printf("updating %d ",submodel_num);
  288.  
  289.     data = (ushort *) &pm->model_data[pm->submodel_ptrs[submodel_num]];
  290.  
  291.     type = *data++;
  292.  
  293.     Assert(type == 7 || type == 1);
  294.  
  295.     nverts = *data++;
  296.  
  297.     if (type==7) {
  298.         i = *data++;        //get start point number
  299.         data++;                //skip pad
  300.     }
  301.     else
  302.         i = 0;                //start at zero
  303.  
  304.     vp = (vms_vector *) data;
  305.  
  306.     while (nverts--) {
  307.  
  308.         if (md->morph_times[i])        //not done yet
  309.  
  310.             if ((md->morph_times[i] -= FrameTime) <= 0) {
  311.                 md->morph_vecs[i] = *vp;
  312.                 md->morph_times[i] = 0;
  313.                 md->n_morphing_points[submodel_num]--;
  314.             }
  315.             else
  316.                 vm_vec_scale_add2(&md->morph_vecs[i],&md->morph_deltas[i],FrameTime);
  317.  
  318.         vp++; i++;
  319.     }
  320.  
  321.     //printf("npoints = %d\n",n_morphing_points[submodel_num]);
  322. }
  323.  
  324.  
  325. //process the morphing object for one frame
  326. do_morph_frame(object *obj)
  327. {
  328.     int i;
  329.     polymodel *pm;
  330.     morph_data *md;
  331.  
  332.     md = find_morph_data(obj);
  333.  
  334.     if (md == NULL) {                    //maybe loaded half-morphed from disk
  335.         obj->flags |= OF_SHOULD_BE_DEAD;        //..so kill it
  336.         return;
  337.     }
  338.  
  339.     pm = &Polygon_models[md->obj->rtype.pobj_info.model_num];
  340.  
  341.     //printf("morph_frame active = ");
  342.     //for (i=0;i<pm->n_models;i++)
  343.     //    printf("%d ",submodel_active[i]);
  344.     //printf("\n");
  345.  
  346.  
  347.     for (i=0;i<pm->n_models;i++)
  348.         if (md->submodel_active[i]==1) {
  349.  
  350.             update_points(pm,i,md);
  351.  
  352.             if (md->n_morphing_points[i] == 0) {        //maybe start submodel
  353.                 int t;
  354.  
  355.                 md->submodel_active[i] = 2;        //not animating, just visible
  356.  
  357.                 md->n_submodels_active--;        //this one done animating
  358.  
  359.                 for (t=0;t<pm->n_models;t++)
  360.                     if (pm->submodel_parents[t] == i) {        //start this one
  361.  
  362.                         init_points(pm,NULL,t,md);
  363.                         md->n_submodels_active++;
  364.                         md->submodel_active[t] = 1;
  365.  
  366.                     }
  367.             }
  368.  
  369.         }
  370.  
  371.     if (!md->n_submodels_active) {            //done morphing!
  372.  
  373.         md->obj->control_type = md->morph_save_control_type;
  374.         md->obj->movement_type = md->morph_save_movement_type;
  375.  
  376.         md->obj->render_type = RT_POLYOBJ;
  377.  
  378.         md->obj->mtype.phys_info = md->morph_save_phys_info;
  379.  
  380.         md->obj = NULL;
  381.     }
  382.  
  383. }
  384.  
  385. vms_vector morph_rotvel = {0x4000,0x2000,0x1000};
  386.  
  387. init_morphs()
  388. {
  389.     int i;
  390.  
  391.     for (i=0;i<MAX_MORPH_OBJECTS;i++)
  392.         morph_objects[i].obj = NULL;
  393. }
  394.  
  395.  
  396. //make the object morph
  397. void morph_start(object *obj)
  398. {
  399.     polymodel *pm;
  400.     vms_vector pmmin,pmmax;
  401.     vms_vector box_size;
  402.     int i;
  403.     morph_data *md;
  404.  
  405.     for (i=0;i<MAX_MORPH_OBJECTS;i++)
  406.         if (morph_objects[i].obj == NULL || morph_objects[i].obj->type==OBJ_NONE  || morph_objects[i].obj->signature!=morph_objects[i].Morph_sig)
  407.             break;
  408.  
  409.     if (i==MAX_MORPH_OBJECTS)        //no free slots
  410.         return;
  411.  
  412.     md = &morph_objects[i];
  413.  
  414.     Assert(obj->render_type == RT_POLYOBJ);
  415.  
  416.     md->obj = obj;
  417.     md->Morph_sig = obj->signature;
  418.  
  419.     md->morph_save_control_type = obj->control_type;
  420.     md->morph_save_movement_type = obj->movement_type;
  421.     md->morph_save_phys_info = obj->mtype.phys_info;
  422.  
  423.     Assert(obj->control_type == CT_AI);        //morph objects are also AI objects
  424.  
  425.     obj->control_type = CT_MORPH;
  426.     obj->render_type = RT_MORPH;
  427.     obj->movement_type = MT_PHYSICS;        //RT_NONE;
  428.  
  429.     obj->mtype.phys_info.rotvel = morph_rotvel;
  430.  
  431.     pm = &Polygon_models[obj->rtype.pobj_info.model_num];
  432.  
  433.     find_min_max(pm,0,&pmmin,&pmmax);
  434.  
  435.     box_size.x = max(-pmmin.x,pmmax.x) / 2;
  436.     box_size.y = max(-pmmin.y,pmmax.y) / 2;
  437.     box_size.z = max(-pmmin.z,pmmax.z) / 2;
  438.  
  439.     for (i=0;i<MAX_VECS;i++)        //clear all points
  440.         md->morph_times[i] = 0;
  441.  
  442.     for (i=1;i<MAX_SUBMODELS;i++)        //clear all parts
  443.         md->submodel_active[i] = 0;
  444.  
  445.     md->submodel_active[0] = 1;        //1 means visible & animating
  446.  
  447.     md->n_submodels_active = 1;
  448.  
  449.     //now, project points onto surface of box
  450.  
  451.     init_points(pm,&box_size,0,md);
  452.  
  453. }
  454.  
  455. draw_model(polymodel *pm,int submodel_num,vms_angvec *anim_angles,fix light,morph_data *md)
  456. {
  457.     int i,mn;
  458.     int facing;
  459.     int sort_list[MAX_SUBMODELS],sort_n;
  460.  
  461.  
  462.     //first, sort the submodels
  463.  
  464.     sort_list[0] = submodel_num;
  465.     sort_n = 1;
  466.  
  467.     for (i=0;i<pm->n_models;i++)
  468.  
  469.         if (md->submodel_active[i] && pm->submodel_parents[i]==submodel_num) {
  470.  
  471.             facing = g3_check_normal_facing(&pm->submodel_pnts[i],&pm->submodel_norms[i]);
  472.  
  473.             if (!facing)
  474.  
  475.                 sort_list[sort_n++] = i;
  476.  
  477.             else {        //put at start
  478.                 int t;
  479.  
  480.                 for (t=sort_n;t>0;t--)
  481.                     sort_list[t] = sort_list[t-1];
  482.  
  483.                 sort_list[0] = i;
  484.  
  485.                 sort_n++;
  486.  
  487.  
  488.             }
  489.  
  490.         }
  491.     
  492.  
  493.     //now draw everything
  494.  
  495.     for (i=0;i<sort_n;i++) {
  496.  
  497.         mn = sort_list[i];
  498.  
  499.         if (mn == submodel_num) {
  500.              int i;
  501.  
  502.             for (i=0;i<pm->n_textures;i++)        {
  503.                 texture_list_index[i] = ObjBitmaps[ObjBitmapPtrs[pm->first_texture+i]];
  504.                 texture_list[i] = &GameBitmaps[ObjBitmaps[ObjBitmapPtrs[pm->first_texture+i]].index];
  505.             }
  506.  
  507. #ifdef PIGGY_USE_PAGING            
  508.             // Make sure the textures for this object are paged in...
  509.             piggy_page_flushed = 0;
  510.             for (i=0;i<pm->n_textures;i++)    
  511.                 PIGGY_PAGE_IN( texture_list_index[i] );
  512.             // Hmmm... cache got flushed in the middle of paging all these in,
  513.             // so we need to reread them all in.
  514.             if (piggy_page_flushed)    {
  515.                 piggy_page_flushed = 0;
  516.                 for (i=0;i<pm->n_textures;i++)    
  517.                     PIGGY_PAGE_IN( texture_list_index[i] );
  518.             }
  519.             // Make sure that they can all fit in memory.
  520.             Assert( piggy_page_flushed == 0 );
  521. #endif
  522.  
  523.  
  524.             g3_draw_morphing_model(&pm->model_data[pm->submodel_ptrs[submodel_num]],texture_list,anim_angles,light,&md->morph_vecs[md->submodel_startpoints[submodel_num]]);
  525.  
  526.         }
  527.         else {
  528.  
  529.             vms_matrix orient;
  530.  
  531.             vm_angles_2_matrix(&orient,&anim_angles[mn]);
  532.  
  533.             g3_start_instance_matrix(&pm->submodel_offsets[mn],&orient);
  534.  
  535.             draw_model(pm,mn,anim_angles,light,md);
  536.  
  537.             g3_done_instance();
  538.  
  539.         }
  540.     }
  541.  
  542. }
  543.  
  544. void draw_morph_object(object *obj)
  545. {
  546. //    int save_light;
  547.     polymodel *po;
  548.     fix light;
  549.     morph_data *md;
  550.  
  551.     md = find_morph_data(obj);
  552.     Assert(md != NULL);
  553.  
  554.     Assert(obj->rtype.pobj_info.model_num < N_polygon_models);
  555.  
  556.     po=&Polygon_models[obj->rtype.pobj_info.model_num];
  557.  
  558.     light = compute_object_light(obj,NULL);
  559.  
  560.     g3_start_instance_matrix(&obj->pos,&obj->orient);
  561.     g3_set_interp_points(robot_points);
  562.  
  563.     draw_model(po,0,obj->rtype.pobj_info.anim_angles,light,md);
  564.  
  565.     g3_done_instance();
  566.  
  567.     #ifdef NEWDEMO
  568.     if (Newdemo_state == ND_STATE_RECORDING)
  569.         newdemo_record_morph_frame(md);
  570.     #endif
  571.  
  572. }
  573. 
  574.