home *** CD-ROM | disk | FTP | other *** search
/ Action Ware 10: Quake / ACWARE10.iso / acware10 / editors / mdlv14 / mdl_3d.cc < prev    next >
C/C++ Source or Header  |  1996-08-07  |  24KB  |  865 lines

  1. //
  2. // this file by brian martin 1996
  3. // brian@phyast.pitt.edu
  4. //
  5. // this is part of the source for the MedDLe quake model viewer/editor
  6. //
  7. //
  8.  
  9. #include"mdl.h"
  10. #include<grdriver.h>
  11.  
  12. // pre-calculated vertex normals needed to do shading
  13. BG_3pt vertex_normal[162]={
  14. {-0.525731,0.000000,0.850651},
  15. {-0.442863,0.238856,0.864188},
  16. {-0.295242,0.000000,0.955423},
  17. {-0.309017,0.500000,0.809017},
  18. {-0.162460,0.262866,0.951056},
  19. {0.000000,0.000000,1.000000},
  20. {0.000000,0.850651,0.525731},
  21. {-0.147621,0.716567,0.681718},
  22. {0.147621,0.716567,0.681718},
  23. {0.000000,0.525731,0.850651},
  24. {0.309017,0.500000,0.809017},
  25. {0.525731,0.000000,0.850651},
  26. {0.295242,0.000000,0.955423},
  27. {0.442863,0.238856,0.864188},
  28. {0.162460,0.262866,0.951056},
  29. {-0.681718,0.147621,0.716567},
  30. {-0.809017,0.309017,0.500000},
  31. {-0.587785,0.425325,0.688191},
  32. {-0.850651,0.525731,0.000000},
  33. {-0.864188,0.442863,0.238856},
  34. {-0.716567,0.681718,0.147621},
  35. {-0.688191,0.587785,0.425325},
  36. {-0.500000,0.809017,0.309017},
  37. {-0.238856,0.864188,0.442863},
  38. {-0.425325,0.688191,0.587785},
  39. {-0.716567,0.681718,-0.147621},
  40. {-0.500000,0.809017,-0.309017},
  41. {-0.525731,0.850651,0.000000},
  42. {0.000000,0.850651,-0.525731},
  43. {-0.238856,0.864188,-0.442863},
  44. {0.000000,0.955423,-0.295242},
  45. {-0.262866,0.951056,-0.162460},
  46. {0.000000,1.000000,0.000000},
  47. {0.000000,0.955423,0.295242},
  48. {-0.262866,0.951056,0.162460},
  49. {0.238856,0.864188,0.442863},
  50. {0.262866,0.951056,0.162460},
  51. {0.500000,0.809017,0.309017},
  52. {0.238856,0.864188,-0.442863},
  53. {0.262866,0.951056,-0.162460},
  54. {0.500000,0.809017,-0.309017},
  55. {0.850651,0.525731,0.000000},
  56. {0.716567,0.681718,0.147621},
  57. {0.716567,0.681718,-0.147621},
  58. {0.525731,0.850651,0.000000},
  59. {0.425325,0.688191,0.587785},
  60. {0.864188,0.442863,0.238856},
  61. {0.688191,0.587785,0.425325},
  62. {0.809017,0.309017,0.500000},
  63. {0.681718,0.147621,0.716567},
  64. {0.587785,0.425325,0.688191},
  65. {0.955423,0.295242,0.000000},
  66. {1.000000,0.000000,0.000000},
  67. {0.951056,0.162460,0.262866},
  68. {0.850651,-0.525731,0.000000},
  69. {0.955423,-0.295242,0.000000},
  70. {0.864188,-0.442863,0.238856},
  71. {0.951056,-0.162460,0.262866},
  72. {0.809017,-0.309017,0.500000},
  73. {0.681718,-0.147621,0.716567},
  74. {0.850651,0.000000,0.525731},
  75. {0.864188,0.442863,-0.238856},
  76. {0.809017,0.309017,-0.500000},
  77. {0.951056,0.162460,-0.262866},
  78. {0.525731,0.000000,-0.850651},
  79. {0.681718,0.147621,-0.716567},
  80. {0.681718,-0.147621,-0.716567},
  81. {0.850651,0.000000,-0.525731},
  82. {0.809017,-0.309017,-0.500000},
  83. {0.864188,-0.442863,-0.238856},
  84. {0.951056,-0.162460,-0.262866},
  85. {0.147621,0.716567,-0.681718},
  86. {0.309017,0.500000,-0.809017},
  87. {0.425325,0.688191,-0.587785},
  88. {0.442863,0.238856,-0.864188},
  89. {0.587785,0.425325,-0.688191},
  90. {0.688191,0.587785,-0.425325},
  91. {-0.147621,0.716567,-0.681718},
  92. {-0.309017,0.500000,-0.809017},
  93. {0.000000,0.525731,-0.850651},
  94. {-0.525731,0.000000,-0.850651},
  95. {-0.442863,0.238856,-0.864188},
  96. {-0.295242,0.000000,-0.955423},
  97. {-0.162460,0.262866,-0.951056},
  98. {0.000000,0.000000,-1.000000},
  99. {0.295242,0.000000,-0.955423},
  100. {0.162460,0.262866,-0.951056},
  101. {-0.442863,-0.238856,-0.864188},
  102. {-0.309017,-0.500000,-0.809017},
  103. {-0.162460,-0.262866,-0.951056},
  104. {0.000000,-0.850651,-0.525731},
  105. {-0.147621,-0.716567,-0.681718},
  106. {0.147621,-0.716567,-0.681718},
  107. {0.000000,-0.525731,-0.850651},
  108. {0.309017,-0.500000,-0.809017},
  109. {0.442863,-0.238856,-0.864188},
  110. {0.162460,-0.262866,-0.951056},
  111. {0.238856,-0.864188,-0.442863},
  112. {0.500000,-0.809017,-0.309017},
  113. {0.425325,-0.688191,-0.587785},
  114. {0.716567,-0.681718,-0.147621},
  115. {0.688191,-0.587785,-0.425325},
  116. {0.587785,-0.425325,-0.688191},
  117. {0.000000,-0.955423,-0.295242},
  118. {0.000000,-1.000000,0.000000},
  119. {0.262866,-0.951056,-0.162460},
  120. {0.000000,-0.850651,0.525731},
  121. {0.000000,-0.955423,0.295242},
  122. {0.238856,-0.864188,0.442863},
  123. {0.262866,-0.951056,0.162460},
  124. {0.500000,-0.809017,0.309017},
  125. {0.716567,-0.681718,0.147621},
  126. {0.525731,-0.850651,0.000000},
  127. {-0.238856,-0.864188,-0.442863},
  128. {-0.500000,-0.809017,-0.309017},
  129. {-0.262866,-0.951056,-0.162460},
  130. {-0.850651,-0.525731,0.000000},
  131. {-0.716567,-0.681718,-0.147621},
  132. {-0.716567,-0.681718,0.147621},
  133. {-0.525731,-0.850651,0.000000},
  134. {-0.500000,-0.809017,0.309017},
  135. {-0.238856,-0.864188,0.442863},
  136. {-0.262866,-0.951056,0.162460},
  137. {-0.864188,-0.442863,0.238856},
  138. {-0.809017,-0.309017,0.500000},
  139. {-0.688191,-0.587785,0.425325},
  140. {-0.681718,-0.147621,0.716567},
  141. {-0.442863,-0.238856,0.864188},
  142. {-0.587785,-0.425325,0.688191},
  143. {-0.309017,-0.500000,0.809017},
  144. {-0.147621,-0.716567,0.681718},
  145. {-0.425325,-0.688191,0.587785},
  146. {-0.162460,-0.262866,0.951056},
  147. {0.442863,-0.238856,0.864188},
  148. {0.162460,-0.262866,0.951056},
  149. {0.309017,-0.500000,0.809017},
  150. {0.147621,-0.716567,0.681718},
  151. {0.000000,-0.525731,0.850651},
  152. {0.425325,-0.688191,0.587785},
  153. {0.587785,-0.425325,0.688191},
  154. {0.688191,-0.587785,0.425325},
  155. {-0.955423,0.295242,0.000000},
  156. {-0.951056,0.162460,0.262866},
  157. {-1.000000,0.000000,0.000000},
  158. {-0.850651,0.000000,0.525731},
  159. {-0.955423,-0.295242,0.000000},
  160. {-0.951056,-0.162460,0.262866},
  161. {-0.864188,0.442863,-0.238856},
  162. {-0.951056,0.162460,-0.262866},
  163. {-0.809017,0.309017,-0.500000},
  164. {-0.864188,-0.442863,-0.238856},
  165. {-0.951056,-0.162460,-0.262866},
  166. {-0.809017,-0.309017,-0.500000},
  167. {-0.681718,0.147621,-0.716567},
  168. {-0.681718,-0.147621,-0.716567},
  169. {-0.850651,0.000000,-0.525731},
  170. {-0.688191,0.587785,-0.425325},
  171. {-0.587785,0.425325,-0.688191},
  172. {-0.425325,0.688191,-0.587785},
  173. {-0.425325,-0.688191,-0.587785},
  174. {-0.587785,-0.425325,-0.688191}
  175. };
  176.  
  177.  
  178. void sort(float v[], int vi[], int left, int right);
  179. void swap(float v[], int vi[], int i, int j);
  180. int frame=0;
  181. int firsttime=1;
  182. int draw_flat=0,ii=5, draw_wire=0, draw_vertices=0;
  183. int draw_gshade=0, draw_textured=0, draw_gtextured=1;
  184. int show_head=0;
  185. int back_color=0;
  186.  
  187. situation eyeball;
  188. //situation qmodel;
  189. void init_view(MDL_model *);
  190.  
  191.  
  192. BG_Polygon mdlpts;
  193. GrContext *vscreen;
  194.  
  195. int mdl_3d(MDL_model *model, MDL_window *w)
  196. {
  197.  
  198.     char str[128];
  199.     byte mainloop=1;
  200.     byte cur_key=0;
  201.  
  202.     FILE *in;
  203.  
  204.     int i,j,k,l,jj,kk,ll,iii,jjj,kkk;
  205.     int zed=0;
  206.     int dumby,draw_poly;
  207.     int num_screen_pts=0;
  208.     int oldmx, oldmy;
  209.     int y_val;
  210.     int x_val;
  211.     int max_depth=128;
  212.     int update=1;
  213.     int num_screen_sides=0;
  214.     int cycle=0;
  215.     int p1,p2,p3,p4;
  216.     word usi;
  217.     word objects, sides, osides, curblock;
  218.     word prev_y[BG_ScreenWidth];
  219.  
  220.     unsigned ui,uj,uk,ul;
  221.  
  222.     long unsigned map_max_x=1024;
  223.     long unsigned map_max_y=1024;
  224.  
  225.     double forward=0,upward=0,rightward=0;
  226.     double t0,t1,frames, fps;
  227.     double dT=.03;
  228.     double view_angle;
  229.     double u,v;
  230.     double u0,v0,w0;
  231.     double a,b,c,d;
  232.     double aa,bb,cc,dd;
  233.     double front_plane=28.0, back_plane=10000.0, plane_const;
  234.     double z_scale_factor;
  235.     double zadd=5.0;
  236.     double scale_terra=.1;
  237.     struct time t;
  238.     float ftemp;
  239.     int maxn;
  240.     int draw_2d=0;
  241.  
  242.     // to scale view
  243.     BG_Matrix scaling;
  244.     // the rotation matrices
  245.     BG_Matrix Rx,Ry,Rz;
  246.     BG_Matrix N,T,M,OTemp;
  247.     BG_Matrix M1,M2,M3;
  248.     BG_Matrix E_TM,B_TM,O_TM,Temp_TM,T_TM,TM;
  249.  
  250.     BG_3pt *framemin, *framemax;
  251.     BG_3pt eye_ptlist[5000];
  252.     float xlist[5000];
  253.     int xindexlist[5000];
  254.     BG_3pt pt1, pt2, pt3, pt4, vect1, vect2, vect3;
  255.     BG_3pt light_ray;
  256.     BG_3pt LR;     // light ray
  257.     BG_3pt MD;     // move direction
  258.     BG_3pt vn[162];
  259.  
  260.  
  261.     BG_3pt X_axis,Y_axis, Z_axis;     // move direction
  262.  
  263.     BG_ScreenCoor pt[4];
  264.  
  265.     BG_MouseRange(0,0,BG_ScreenWidth,BG_ScreenHeight);
  266.  
  267.  
  268.  
  269.     BG_ClearScreen(0);
  270.     // create a screen buffer in ram to do rendering
  271.     vscreen = GrCreateContext(BG_ScreenWidth,BG_ScreenHeight,NULL,NULL);
  272.     G_buffer = (unsigned  char *)(vscreen->gc_frame.gf_baseaddr[0]);
  273.  
  274.  
  275.     if(firsttime==1)init_view(model);
  276.     firsttime=0;
  277.  
  278.     X_axis.x=10.0;
  279.     X_axis.y=0.0;
  280.     X_axis.z=0.0;
  281.     Y_axis.x=0.0;
  282.     Y_axis.y=10.0;
  283.     Y_axis.z=0.0;
  284.     Z_axis.x=0.0;
  285.     Z_axis.y=0.0;
  286.     Z_axis.z=10.0;
  287.  
  288.     //Rotation Matrices
  289.     Rx=BG_CalcRx(0);
  290.     Ry=BG_CalcRy(0);
  291.     Rz=BG_CalcRz(0);
  292.  
  293.     //Scaling matrix
  294.     BG_IdentityMatrix( &scaling );
  295.     //focus=20.0; // ~79 degree total view
  296.     scaling.m[0][0]=focus*(double)(BG_ScreenHeight-1)/win_height;    //scale x
  297.     scaling.m[0][1]=(BG_ScreenWidth/2);
  298.     scaling.m[2][1]=(BG_ScreenHeight/2);
  299.     scaling.m[2][2]=-focus*(double)(BG_ScreenHeight-1)/win_width;    // scale y
  300.  
  301.  
  302.     plane_const=(double)USHRT_MAX/((double)back_plane-(double)front_plane);
  303.  
  304.     BG_MouseToXY(BG_ScreenWidth/2,BG_ScreenHeight/2);
  305.     BG_MouseStatus();
  306.     oldmx=BG_MouseX;
  307.     oldmy=BG_MouseY;
  308.  
  309.     // direction of light source
  310.     // like sun pointing down
  311.     light_ray.x=.0;
  312.     light_ray.y=-1.0;
  313.     light_ray.z=-1.0;
  314.  
  315.     a=cos(0);
  316.     b=sin(0);
  317.   /*
  318.    My general prescription for viewing and such:
  319.   1. Get movement of eye, ORI & POS
  320.     a. if moved, then update POS
  321.     b. if rotated, then calc the rotation matrix: Ri=CalcRi(ang)
  322.          and then rotate ORI: ORI=Ri*ORI
  323.   2. Construct a transformation matrix for the eye: E_TM=SCALE*ORI*POS
  324.   3. Rotate and Move all objects in a similar manner to form
  325.      the objects transformation matrix: O_TM=O_POS*O_ORI
  326.   4. Construct the final transformation for each object: TM=E_TM*O_TM
  327.     5. Convert Points to eye's coords
  328.     a. make vector,O_P, from origin of object to point of object
  329.     b. new pt in eye frame is P=TM*O_P (all 4 components)
  330.   6. Rotate/Calc side Normals to perform Culling
  331.     a. make side normal,N, in eye coords
  332.     b. make vector from eye origin to a point on the side,EV
  333.     c. if N(dot)EV<0 then draw side
  334.   7. Project the 3d points to the screen
  335.     a. if pt.y>0 then its in front so draw it
  336.     b. get window (screen) coords
  337.         win_x=pt.x/pt.y;
  338.         win_y=pt.z/pt.y;
  339.   8. Draw the polygon using the above points (and clip)
  340.     9. Get input, Calulate, and Repeat
  341.  
  342.     I should scale like above, but I'm doing it later so i understand the
  343.     math better.
  344.     */
  345.     int light_move=0;
  346.     update=1;
  347.     cycle=0;
  348.     // main loop
  349.     while(mainloop==1)
  350.     {
  351.  
  352.         if(kbhit())
  353.         {
  354.             if((cur_key=getch())==0x0)
  355.             { cur_key=getch();
  356.             switch(cur_key)
  357.               {
  358.                 case ARROW_DOWN:    upward=-1.0; break;
  359.                 case ARROW_UP:        upward=1.0; break;
  360.                 case ARROW_LEFT:    {frame--; if(frame<0) frame=(int)model->blocks-1;break;}
  361.                 case ARROW_RIGHT:   {frame++; if(frame>=(int)model->blocks) frame=0; break;}
  362.               }
  363.             }
  364.             else{
  365.             switch(cur_key)
  366.             {
  367.                 //case KEY_ENTER:        mainloop=0; break;
  368.                 case 27:               mainloop=0; draw_2d=0; break;
  369.                 case '1':            mainloop=0; draw_2d=2; break;
  370.                 case '2':            mainloop=0; draw_2d=1; break;
  371.                 case 'V': case 'v': if(draw_vertices==0) draw_vertices=1; else draw_vertices=0; break;
  372.                 case 'T': case 't': if(draw_wire==0) draw_wire=1; else draw_wire=0; break;
  373.                 case '\t':
  374.                     if(ii==5) {ii=2; draw_flat=1;draw_gshade=0;draw_textured=0;draw_gtextured=0;}
  375.                     else if(ii==2) { ii=3; draw_flat=0;draw_gshade=1;draw_textured=0; draw_gtextured=0;}
  376.                     else if(ii==3){ ii=4; draw_flat=0;draw_textured=1;draw_gshade=0; draw_gtextured=0;}
  377.                     else { ii=5; draw_flat=0;draw_textured=0;draw_gshade=0; draw_gtextured=1;}
  378.                    break;
  379.  
  380.                 case 'h': if(show_head==0) show_head=1; else show_head=0; break;
  381.                 case 'c': if(cycle==1) cycle=0; else cycle=1; break;
  382.                 case 'b': if(back_color==0) back_color=0x08080808;
  383.                         else if(back_color==0x08080808) back_color=0x0F0F0F0F;
  384.                          else back_color=0;
  385.                          break;
  386.           //        case 'l': if(light_move==0) light_move=1; else light_move=0; break;
  387.                 case 'r':
  388.                     BG_ZeroMatrix( &model->sit.dir_matrix );
  389.                     model->sit.dir_matrix.m[0][0]= 1.0;
  390.                     model->sit.dir_matrix.m[1][1]= 1.0;
  391.                     model->sit.dir_matrix.m[2][2]= 1.0;
  392.                     model->sit.dir_matrix.m[3][3]= 1.0;
  393.                     break;
  394.  
  395.                 case ',': case '<': if(model->cur_skin==0) model->cur_skin=model->num_skins-1;
  396.                                     else model->cur_skin-=1;
  397.                                     break;
  398.                 case '.': case '>': model->cur_skin++;
  399.                                     if(model->cur_skin==model->num_skins) model->cur_skin=0;
  400.                                     break;
  401.                 case '\"': case '\'': model->bcolor++;
  402.                             if(model->bcolor>13)model->bcolor=0;
  403.                             break;
  404.                 case ';': case ':': model->bcolor--;
  405.                             if(model->bcolor<0)model->bcolor=13;
  406.                             break;
  407.  
  408.                 case '}': case ']': model->tcolor++;
  409.                             if(model->tcolor>13)model->tcolor=0;
  410.                             break;
  411.                 case '{': case '[': model->tcolor--;
  412.                             if(model->tcolor<0) model->tcolor=13;
  413.                             break;
  414.  
  415.                 case 's': //screen shot
  416.                 {
  417.                  for(i=0;i<100; i++)
  418.                  {
  419.                     sprintf(str,"pic%d.bmp",i);
  420.                     //see if file exists
  421.                     in=fopen(str,"rb");
  422.  
  423.                     if(in==NULL)
  424.                     {
  425.                         in=fopen(str,"wb");
  426.                         BG_WriteBMP(in, pal, G_buffer, BG_ScreenWidth, BG_ScreenHeight);
  427.                         fclose(in);
  428.                         break;
  429.                     }
  430.                  }
  431.                 break;
  432.                 }
  433.             }
  434.             }
  435.             update=1;
  436.         }
  437.  
  438.         // check on mouse
  439.         BG_MouseStatus();
  440.         //if not moving light, move object
  441. //        if(light_move==0)
  442. //        {
  443.         if((BG_MouseLeft)&&(BG_MouseX!=oldmx))
  444.         {
  445.             i=(oldmx-BG_MouseX);
  446.             Rz=BG_CalcRz((byte)i);
  447.             model->sit.dir_matrix=BG_MatrixMult(&Rz,&model->sit.dir_matrix);
  448.             zed=1;
  449.             update=1;
  450.         }
  451.         if((BG_MouseRight)&&(BG_MouseY!=oldmy))
  452.         {
  453.             i=(BG_MouseY-oldmy);
  454.             forward=i;
  455.             update=1;
  456.         }
  457.         if((BG_MouseLeft)&&(BG_MouseY!=oldmy))
  458.         {
  459.             i=(oldmy-BG_MouseY);
  460.             Ry=BG_CalcRy((byte)i);
  461.             model->sit.dir_matrix=BG_MatrixMult(&Ry,&model->sit.dir_matrix);
  462.             update=1;
  463.         }
  464. //        }
  465.         // else move light source
  466. //        else
  467. //        {
  468.         if((BG_MouseX!=oldmx)&&(!BG_MouseRight)&&(!BG_MouseLeft))
  469.         {
  470.             i=(oldmx-BG_MouseX);
  471.             Rz=BG_CalcRz((byte)i);
  472.             light_ray =BG_MatrixVector3(&Rz,&light_ray);
  473.             update=1;
  474.         }
  475.         if((BG_MouseY!=oldmy)&&(!BG_MouseRight)&&(!BG_MouseLeft))
  476.         {
  477.             i=(oldmy-BG_MouseY);
  478.             Ry=BG_CalcRy((byte)i);
  479.             light_ray =BG_MatrixVector3(&Ry,&light_ray);
  480.             update=1;
  481.         }
  482.  
  483.  
  484. //        }
  485.  
  486.         if(cycle==1)
  487.         {
  488.             frame++;
  489.             update=1;
  490.             if(frame>=(int)model->blocks) frame=0;
  491.         }
  492.  
  493.         BG_MouseToXY(BG_ScreenWidth/2,BG_ScreenHeight/2);
  494.         oldmx=BG_ScreenWidth/2;//BG_MouseX;
  495.         oldmy=BG_ScreenHeight/2;//BG_MouseY;
  496.  
  497.         // if something has changed, redraw screen
  498.         if(update==1)
  499.  
  500.         {
  501.  
  502.         MD.x=rightward;
  503.         MD.y=forward;
  504.         MD.z=upward;
  505.  
  506.         MD=BG_VectorMatrix3(&MD,&eyeball.dir_matrix);
  507.  
  508.         forward=0;
  509.         upward=0;
  510.         rightward=0;
  511.  
  512.         eyeball.pos.x+=MD.x;
  513.         if(eyeball.pos.x>=(double)map_max_x) eyeball.pos.x=map_max_x-1;
  514.         if(eyeball.pos.x<0.0) eyeball.pos.x=0;
  515.  
  516.         eyeball.pos.y+=MD.y;
  517.  
  518.         if(eyeball.pos.y>=(double)map_max_y) eyeball.pos.y=map_max_y-1;
  519.         if(eyeball.pos.y<0.0) eyeball.pos.y=0;
  520.  
  521.         eyeball.ix=(unsigned)eyeball.pos.x;
  522.         eyeball.iy=(unsigned)eyeball.pos.y;
  523.  
  524.  
  525.  
  526.         eyeball.pos.z+=MD.z;
  527.  
  528.         eyeball.pos_matrix.m[0][3]=-eyeball.pos.x;
  529.         eyeball.pos_matrix.m[1][3]=-eyeball.pos.y;
  530.         eyeball.pos_matrix.m[2][3]=-eyeball.pos.z;
  531.         // eye transformation matrix
  532.         E_TM=BG_MatrixMult(&eyeball.dir_matrix,&eyeball.pos_matrix);
  533.  
  534.         // the light ray
  535.         LR=BG_MatrixVector4(&eyeball.dir_matrix,&light_ray);
  536.         BG_Normalize(&LR);
  537.  
  538.  
  539. //***************************************************************************
  540. //***************************************************************************
  541. // draw objects !!!!!!!!!!!!!!!!!!!!!!!!
  542. //***************************************************************************
  543. //***************************************************************************
  544.  
  545.         // object's transformation matrix
  546.         O_TM=BG_MatrixMult(&model->sit.pos_matrix,&model->sit.dir_matrix);
  547.         // overall transformation matrix
  548.         TM=BG_MatrixMult(&E_TM,&O_TM);
  549.         i=0;
  550.                 // put all points in eyeballs coordinates
  551.                 for(k=0; k < model->block[frame].num_pts+8; k++)
  552.                 {
  553.                     eye_ptlist[k]=BG_MatrixVector4(&TM,&model->block[frame].ptlist[k]);
  554.                 }
  555.                 // put all vertex normals in eye's coords
  556.                 for(k=0; k < 162; k++)
  557.                 {
  558.                     vn[k]=BG_MatrixVector3(&TM,&vertex_normal[k]);
  559.                 }
  560.                 // find farthest point of each poly from eye.
  561.                 for(k=0; k <model->block[frame].num_sides ; k++)
  562.                 {
  563.                     xlist[k]=-1e23;
  564.                     for(l=0; l < 3; l++)
  565.                     {
  566.                         if(eye_ptlist[model->block[frame].side[k].pt[l]].y>xlist[k])
  567.                             xlist[k]=eye_ptlist[model->block[frame].side[k].pt[l]].y;
  568.                     }
  569.                     xindexlist[k]=k;
  570.                 }
  571.                 // now sort polys by furthest point
  572.                 sort(xlist,xindexlist,0,model->block[frame].num_sides-1);
  573.  
  574.                 G_clear(back_color);
  575.                      // if show header, draw points at bounding box
  576.                      if(show_head)
  577.                      {
  578.  
  579.                             for(k=0;k<8;k++)
  580.                             {
  581.                             pt1=eye_ptlist[model->block[frame].num_pts+k];
  582.                             pt1=BG_MatrixVector4(&scaling,&pt1);
  583.                             if((pt1.y>0))//front_plane)&&(pt1.y<back_plane))
  584.                             {
  585.                                 u=pt1.x/pt1.y;
  586.                                 v=pt1.z/pt1.y;
  587.                                 mdlpts.x[0]=(int)u;
  588.                                 mdlpts.x[1]=(int)v;
  589.                                 G_dot(mdlpts.x,250);
  590.  
  591.                             }
  592.                             }
  593.  
  594.                      }
  595.  
  596.                 //do all sides
  597.                 num_screen_sides=0;
  598.                 for(k=0; k <model->block[frame].num_sides ; k++)
  599.                 {
  600.                     num_screen_pts=0;
  601.  
  602.                     // find normals for culling
  603.                     pt1=eye_ptlist[model->block[frame].side[xindexlist[k]].pt[0]];
  604.                     vect1=BG_MatrixVector3(&TM,&model->block[frame].side[xindexlist[k]].normal);
  605.  
  606.                     // dot normal with a vector which points from the eye to the side
  607.                     a = BG_DotProduct(&vect1,&pt1);
  608.  
  609.  
  610.                     // if in front of eyeball...
  611.                     if( a < 0.0 )
  612.                     {
  613.                         // see how much normal is pointing towards light for flat shading
  614.                         if((b= BG_DotProduct(&vect1,&LR)+1.) >2.) b=2.0;
  615.                         if(b < 0.) b=0.;
  616.                         draw_poly=1;
  617.                         // do each point on each side
  618.                         for(l=0; l < 3; l++)
  619.                         {
  620.                             u=0;
  621.                             v=0;
  622.                             pt1.x=eye_ptlist[model->block[frame].side[xindexlist[k]].pt[l]].x;
  623.                             pt1.y=eye_ptlist[model->block[frame].side[xindexlist[k]].pt[l]].y;
  624.                             pt1.z=eye_ptlist[model->block[frame].side[xindexlist[k]].pt[l]].z;
  625.  
  626.                             pt1=BG_MatrixVector4(&scaling,&pt1);
  627.                             num_screen_sides++;
  628.                             // front and back plane clipping
  629.                             if((pt1.y>0))//front_plane)&&(pt1.y<back_plane))
  630.                             {
  631.                                 // put points in 2d screen coords
  632.                                 u=pt1.x/pt1.y;
  633.                                 v=pt1.z/pt1.y;
  634.                                 // put data in 3dgpl style for rendering
  635.                                 mdlpts.x[l*ii]=(int)u;
  636.                                 mdlpts.x[l*ii+1]=(int)v;
  637.  
  638.                                 if(draw_gshade)
  639.                                 {
  640.                                     //see how much normal is pointed towards lighgt
  641.                                     b= 1.-BG_DotProduct(&vn[model->block[frame].nindex[model->block[frame].side[xindexlist[k]].pt[l]]],&LR);
  642.                                     b=b*.5;
  643.                                     if(b < 0) b=0;
  644.                                     // scale intesity from 0 to 15 (different from colormap)
  645.                                     mdlpts.x[l*3+2]=(int)(15.*(1.-b));//15-(int)(.5*b*15.0);
  646.                                 }
  647.  
  648.                                 if(draw_textured)
  649.                                 {
  650.                                     // get coords of texture
  651.                                     if((model->vertex[3*model->triangle[xindexlist[k]*4+l+1]]==32)
  652.                                      &&
  653.                                     (model->triangle[xindexlist[k]*4]==0))
  654.                                     {
  655.  
  656.                                         mdlpts.x[l*4+2]=model->skinw/2+model->vertex[3*model->triangle[xindexlist[k]*4+l+1]+1];
  657.                                         mdlpts.x[l*4+3]=model->vertex[3*model->triangle[xindexlist[k]*4+l+1]+2];
  658.                                     }
  659.                                     else
  660.                                     {
  661.                                         mdlpts.x[l*4+2]=model->vertex[3*model->triangle[xindexlist[k]*4+l+1]+1];
  662.                                         mdlpts.x[l*4+3]=model->vertex[3*model->triangle[xindexlist[k]*4+l+1]+2];
  663.                                     }
  664.                                 }
  665.  
  666.                                 if(draw_gtextured)
  667.                                 {
  668.                                     // get coords of texture
  669.                                     if((model->vertex[3*model->triangle[xindexlist[k]*4+l+1]]==32)
  670.                                      &&
  671.                                     (model->triangle[xindexlist[k]*4]==0))
  672.                                     {
  673.  
  674.                                         mdlpts.x[l*5+2]=model->skinw/2+model->vertex[3*model->triangle[xindexlist[k]*4+l+1]+1];
  675.                                         mdlpts.x[l*5+3]=model->vertex[3*model->triangle[xindexlist[k]*4+l+1]+2];
  676.                                     }
  677.                                     else
  678.                                     {
  679.                                         mdlpts.x[l*5+2]=model->vertex[3*model->triangle[xindexlist[k]*4+l+1]+1];
  680.                                         mdlpts.x[l*5+3]=model->vertex[3*model->triangle[xindexlist[k]*4+l+1]+2];
  681.                                     }
  682.  
  683.                                     //see how much normal is pointed towards lighgt
  684.                                     b= 1.-BG_DotProduct(&vn[model->block[frame].nindex[model->block[frame].side[xindexlist[k]].pt[l]]],&LR);
  685.                                     b=b*.5;
  686.                                     if(b < 0) b=0;
  687.                                     // scale intesity from 0 to 15
  688.                                     mdlpts.x[l*5+4]=(int)(b*15.);//15-(int)(.5*b*15.0);
  689.  
  690.  
  691.                                 }
  692.  
  693.                             }
  694.  
  695.                             else  //don't draw if not in front
  696.                             {
  697.                                 draw_poly=0;
  698.                                 num_screen_sides--;
  699.                                 break;
  700.                             }
  701.  
  702.                             num_screen_pts++;
  703.  
  704.                         }
  705.                         // now call the rendering functs
  706.                         if(draw_poly)
  707.                         {
  708.                              mdlpts.x[3*ii]=mdlpts.x[0];
  709.                              mdlpts.x[3*ii+1]=mdlpts.x[1];
  710.  
  711.                              if(draw_flat)
  712.                                 G_ambient_polygon(mdlpts.x,3,(int)(b*15.0*.5));
  713.  
  714.                              else if(draw_gtextured)
  715.                              {
  716.                                 // must set wrap around point
  717.                                  mdlpts.x[3*ii+2]=mdlpts.x[2];
  718.                                  mdlpts.x[3*ii+3]=mdlpts.x[3];
  719.                                  mdlpts.x[3*ii+4]=mdlpts.x[4];
  720.                                  G_gtex_poly(mdlpts.x,3,model->skin[model->cur_skin].bitmap,model->skinw, model);
  721.                              }
  722.                              else if(draw_gshade)
  723.                              {
  724.                                 // must set wrap around point
  725.                                  mdlpts.x[3*ii+2]=mdlpts.x[2];
  726.                                  G_shaded_polygon(mdlpts.x,3);
  727.                              }
  728.                              else if(draw_textured)
  729.                              {
  730.                                 // must set wrap around point
  731.                                  mdlpts.x[3*ii+2]=mdlpts.x[2];
  732.                                  mdlpts.x[3*ii+3]=mdlpts.x[3];
  733.                                  G_textured_polygon(mdlpts.x,3,model->skin[model->cur_skin].bitmap,model->skinw, model);
  734.                              }
  735.                              if(draw_wire)
  736.                              {
  737.                                 G_line(mdlpts.x,mdlpts.x+ii,8);
  738.                                 G_line(mdlpts.x+ii,mdlpts.x+2*ii,8);
  739.                                 G_line(mdlpts.x+2*ii,mdlpts.x,8);
  740.                              }
  741.                              if(draw_vertices)
  742.                              {
  743.                                 l=250;
  744.                                 G_dot(mdlpts.x,l);
  745.                                 G_dot(mdlpts.x+ii,l);
  746.                                 G_dot(mdlpts.x+2*ii,l);
  747.                            }
  748.  
  749.                         }
  750.                     }
  751.  
  752.                 }
  753.         // draw some text for some things
  754.         if(light_move==1)
  755.         {
  756.             sprintf(str,"move light");
  757.             MDL_Text(BG_ScreenWidth-90,2,str,253);
  758.         }
  759.         if(show_head)
  760.         {
  761.             sprintf(str,"Frame Name: %s",model->block[frame].name);
  762.             MDL_Text(5,2,str,253);
  763.             sprintf(str,"Frame #: %d",(int)frame);
  764.             MDL_Text(5,10,str,253);
  765.           /*    sprintf(str,"Bounding Box: %d %d %d : %d %d %d",
  766.             model->frame[frame].sframe.bboxmin.v[0],
  767.             model->frame[frame].sframe.bboxmin.v[1],
  768.             model->frame[frame].sframe.bboxmin.v[2],
  769.             model->frame[frame].sframe.bboxmax.v[0],
  770.             model->frame[frame].sframe.bboxmax.v[1],
  771.             model->frame[frame].sframe.bboxmax.v[2]);
  772.             MDL_Text(5,18,str,253);
  773.             */
  774.         }
  775.         // use GRX to BitBlt Ram screen buffer to current active video screen
  776.         GrBitBltNC(NULL,0,0,vscreen,0,0,BG_ScreenWidth-1,BG_ScreenHeight-1,GrWRITE);
  777.     }
  778.     update=0;
  779.  
  780.     }
  781.     // get rid of ram screen buffer
  782.     GrDestroyContext(vscreen);
  783.  
  784.   // jump to next section
  785.   if(draw_2d==1) return 1;
  786.     else if(draw_2d==2) return 2;
  787.     else return 0;
  788.  
  789.  }
  790.  
  791. // sorting routine from  some book. Not the fastest, but it works.
  792. void sort(float v[], int vi[], int left, int right)
  793. {
  794.     int i, last;
  795.  
  796.     if(left>=right) return;
  797.     swap(v,vi,left,(left+right)/2);
  798.     last=left;
  799.     for(i=left+1; i<=right; i++)
  800.         if(v[i]>v[left])
  801.             swap(v,vi,++last,i);
  802.     swap(v,vi,left,last);
  803.     sort(v,vi,left,last-1);
  804.     sort(v,vi,last+1,right);
  805.  
  806. }
  807.  
  808. void swap(float v[], int vi[], int i, int j)
  809. {
  810.     float temp;
  811.     int itemp;
  812.  
  813.     temp = v[i];
  814.     v[i]=v[j];
  815.     v[j]=temp;
  816.     itemp=vi[i];
  817.     vi[i]=vi[j];
  818.     vi[j]=itemp;
  819. }
  820.  
  821. // this routine  just sets the initial conditions
  822. void init_view(MDL_model *model)
  823. {
  824.     model->sit.pos.x=0.0;
  825.     model->sit.pos.y=0.0;
  826.     model->sit.pos.z=0.0;
  827.     eyeball.ix=(unsigned)eyeball.pos.x;
  828.     eyeball.iy=(unsigned)eyeball.pos.y;
  829.     eyeball.pos.x=175.0; eyeball.pos.y=0.0; eyeball.pos.z=12.0;
  830. //    model.pos.x=0.0;
  831. //    model.pos.y=0.0;
  832. //    model.pos.z=0.0;
  833. //    eyeball.ix=(unsigned)eyeball.pos.x;
  834. //    eyeball.iy=(unsigned)eyeball.pos.y;
  835.  
  836.     BG_IdentityMatrix( &eyeball.pos_matrix );
  837.     BG_IdentityMatrix( &model->sit.pos_matrix );
  838.     eyeball.pos_matrix.m[0][3]=eyeball.pos.x;
  839.     eyeball.pos_matrix.m[1][3]=eyeball.pos.y;
  840.     eyeball.pos_matrix.m[2][3]=eyeball.pos.z;
  841.     model->sit.pos_matrix.m[0][3]=model->sit.pos.x;
  842.     model->sit.pos_matrix.m[1][3]=model->sit.pos.y;
  843.     model->sit.pos_matrix.m[2][3]=model->sit.pos.z;
  844.     /*
  845.     Direction matrix:
  846.  
  847.      right                  1 0 0 0
  848.      looking                0 1 0 0
  849.      up                     0 0 1 0
  850.      translation            0 0 0 1
  851.     */
  852.  
  853.     BG_ZeroMatrix( &eyeball.dir_matrix );
  854.     BG_ZeroMatrix( &model->sit.dir_matrix );
  855.     eyeball.dir_matrix.m[0][1]= 1.0;
  856.     eyeball.dir_matrix.m[1][0]= -1.0;
  857.     eyeball.dir_matrix.m[2][2]= 1.0;
  858.     eyeball.dir_matrix.m[3][3]= 1.0;
  859.     model->sit.dir_matrix.m[0][0]= 1.0;
  860.     model->sit.dir_matrix.m[1][1]= 1.0;
  861.     model->sit.dir_matrix.m[2][2]= 1.0;
  862.     model->sit.dir_matrix.m[3][3]= 1.0;
  863.  
  864.  
  865. }