home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / main / objfly.c < prev    next >
C/C++ Source or Header  |  1998-06-08  |  6KB  |  183 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/objfly.c $
  15.  * $Revision: 2.0 $
  16.  * $Author: john $
  17.  * $Date: 1995/02/27 11:31:00 $
  18.  * 
  19.  * Code for making objects do a flythrough.
  20.  * 
  21.  * $Log: objfly.c $
  22.  * Revision 2.0  1995/02/27  11:31:00  john
  23.  * New version 2.0, which has no anonymous unions, builds with
  24.  * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
  25.  * 
  26.  * Revision 1.4  1994/11/17  14:58:11  mike
  27.  * moved segment validation functions from editor to main.
  28.  * 
  29.  * Revision 1.3  1994/02/17  11:32:36  matt
  30.  * Changes in object system
  31.  * 
  32.  * Revision 1.2  1994/01/27  18:46:28  john
  33.  * Initial version
  34.  * 
  35.  * Revision 1.1  1994/01/27  15:11:07  john
  36.  * Initial revision
  37.  * 
  38.  * 
  39.  */
  40.  
  41.  
  42. #pragma off (unreferenced)
  43. static char rcsid[] = "$Id: objfly.c 2.0 1995/02/27 11:31:00 john Exp $";
  44. #pragma on (unreferenced)
  45.  
  46. #include <stdlib.h>
  47.  
  48. #include "inferno.h"
  49. #include "game.h"
  50. #include "editor\editor.h"
  51. #include "error.h"
  52.  
  53. #define MIN_D 0x100
  54.  
  55. // In flyby.c
  56. extern int matt_find_connect_side(int seg0,int seg1);
  57. extern vms_angvec *angvec_add2_scale(vms_angvec *dest,vms_angvec *src,fix s);
  58. extern angles_from_vector(vms_angvec *dest,vms_vector *vec);
  59. extern fixang delta_ang(fixang a,fixang b);
  60.  
  61. // In physics.c
  62. int check_object_seg(object * obj );
  63.  
  64.  
  65. void objfly_move_to_new_segment( object * obj, short newseg, int first_time )
  66. {
  67.     segment *pseg;
  68.     int old_object_seg = obj->segnum;
  69.  
  70.     if ( newseg != obj->segnum )
  71.         obj_relink(obj-Objects, newseg );
  72.  
  73.     pseg = &Segments[obj->segnum];
  74.  
  75.     if ( first_time || obj->segnum != old_object_seg) {        //moved into new seg
  76.         vms_vector curcenter,nextcenter;
  77.         fix step_size,seg_time;
  78.         short entry_side,exit_side;    //what sides we entry and leave through
  79.         vms_vector dest_point;        //where we are heading (center of exit_side)
  80.         vms_angvec dest_angles;        //where we want to be pointing
  81.  
  82.         //find new exit side
  83.  
  84.         if ( !first_time ) {
  85.  
  86.             entry_side = matt_find_connect_side(obj->segnum,old_object_seg);
  87.             exit_side = Side_opposite[entry_side];
  88.         }
  89.  
  90.         //if (first_time) obj->fly_info.ft_mode = FP_FORWARD;
  91.  
  92.         if (first_time || entry_side==-1 || (pseg->children[exit_side]==-1) || (obj->fly_info.ft_mode!=FP_FORWARD) ) {
  93.             int i;
  94.             vms_vector prefvec,segcenter,sidevec;
  95.             fix best_val=-f2_0;
  96.             int best_side;
  97.  
  98.             //find exit side
  99.  
  100.             if (obj->fly_info.ft_mode == FP_FORWARD) {
  101.                 if (first_time) 
  102.                     prefvec = obj->orient.fvec;
  103.                 else
  104.                     prefvec = obj->fly_info.heading;
  105.                 vm_vec_normalize(&prefvec);
  106.             }
  107.             else
  108.                 prefvec = obj->orient.vecs[obj->fly_info.ft_mode%3];
  109.  
  110.             if (obj->fly_info.ft_mode >= 3) {prefvec.x = -prefvec.x; prefvec.y = -prefvec.y; prefvec.z = -prefvec.z;}
  111.  
  112.             compute_segment_center(&segcenter,pseg);
  113.  
  114.             best_side=-1;
  115.             for (i=MAX_SIDES_PER_SEGMENT;--i >= 0;) {
  116.                 fix d;
  117.  
  118.                 if (pseg->children[i]!=-1) {
  119.  
  120.                     compute_center_point_on_side(&sidevec,pseg,i);
  121.                     vm_vec_sub2(&sidevec,&segcenter);
  122.                     vm_vec_normalize(&sidevec);
  123.                     d = vm_vec_dotprod(&sidevec,&prefvec);
  124.  
  125.                     if (labs(d) < MIN_D) d=0;
  126.  
  127.                     if (d > best_val || (d==best_val && i==exit_side)) {best_val=d; best_side=i;}
  128.  
  129.                 }
  130.             }
  131.  
  132.             if (best_val > 0) obj->fly_info.ft_mode = FP_FORWARD;
  133.  
  134.             Assert(best_side!=-1);
  135.  
  136.             exit_side = best_side;
  137.         }
  138.  
  139.         //update target point & angles
  140.  
  141.         compute_center_point_on_side(&dest_point,pseg,exit_side);
  142.  
  143.         //update target point and movement points
  144.  
  145.         vm_vec_sub(&obj->phys_info.velocity,&dest_point,&obj->pos);
  146.         step_size = vm_vec_normalize(&obj->phys_info.velocity);
  147.         vm_vec_scale(&obj->phys_info.velocity, obj->phys_info.speed);
  148.  
  149.         compute_segment_center(&curcenter,pseg);
  150.         compute_segment_center(&nextcenter,&Segments[pseg->children[exit_side]]);
  151.         vm_vec_sub(&obj->fly_info.heading,&nextcenter,&curcenter);
  152.  
  153.         angles_from_vector(&dest_angles,&obj->fly_info.heading);    //extract angles
  154.  
  155.         if (first_time) 
  156.             angles_from_vector(&obj->phys_info.rotvel,&obj->orient.fvec);
  157.  
  158.         seg_time = fixdiv(step_size,obj->phys_info.speed);    //how long through seg
  159.  
  160.         if (seg_time) {
  161.             obj->fly_info.angle_step.p = fixdiv(delta_ang(obj->phys_info.rotvel.p,dest_angles.p),seg_time);
  162.             obj->fly_info.angle_step.b = fixdiv(delta_ang(obj->phys_info.rotvel.b,dest_angles.b),seg_time);
  163.             obj->fly_info.angle_step.h = fixdiv(delta_ang(obj->phys_info.rotvel.h,dest_angles.h),seg_time);
  164.         }
  165.         else {
  166.             obj->phys_info.rotvel = dest_angles;
  167.             obj->fly_info.angle_step.p = obj->fly_info.angle_step.b = obj->fly_info.angle_step.h = 0;
  168.         }
  169.     }
  170. }
  171.  
  172. void do_object_flythrough(object * obj )        //set true if init
  173. {
  174.     if ( obj->fly_info.ft_mode == FP_FIRST_TIME )    {
  175.          obj->fly_info.ft_mode = FP_FORWARD;
  176.         objfly_move_to_new_segment( obj, obj->segnum, 1 );
  177.     } else {
  178.         //move the object for this frame
  179.         angvec_add2_scale(&obj->phys_info.rotvel,&obj->fly_info.angle_step,FrameTime);
  180.         vm_angles_2_matrix(&obj->orient,&obj->phys_info.rotvel);
  181.     }
  182. }
  183.