fly.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:7k
源码类别:

GIS编程

开发平台:

Visual C++

  1. /*
  2.  * fly.c        $Revision: 1.2 $
  3.  */
  4. #include "stdio.h"
  5. #include "math.h"
  6. #include "skyfly.h"
  7. #if defined(_WIN32)
  8. #pragma warning (disable:4244)  /* disable bogus conversion warnings */
  9. #pragma warning (disable:4305)  /* VC++ 5.0 version of above warning. */
  10. #endif
  11. #define cosf(a)   cos((float)a)
  12. #define sinf(a)   sin((float)a)
  13. #define sqrtf(a)   sqrt((float)a)
  14. #define expf(a)   exp((float)a)
  15. typedef struct paper_plane_struct {
  16.     float           Pturn_rate;
  17.     float           PX, PY, PZ, PZv;
  18.     float           Pazimuth;
  19.     float           Proll;
  20.     int             Pcount, Pdirection;
  21. } paper_plane;
  22. static paper_plane  flock[NUM_PLANES];
  23. static float  X, Y, Z, Azimuth, Speed;
  24. static int Keyboard_mode;
  25. extern float *A;
  26. extern int Wxorg, Wyorg;
  27. static float terrain_height(float x, float y);
  28. int Xgetbutton(int b);
  29. int Xgetvaluator(int v);
  30. void init_positions(void)
  31. {
  32.     int             i;
  33.     X = GRID_RANGE / 2.;
  34.     Y = GRID_RANGE / 2.;
  35.     Z = 1.5;
  36.     /*
  37.      * randomly position the planes near center of world
  38.      * take MAX of height above terrain and 0, so planes
  39.      * don't fall into canyon.  Canyon has negative elevation
  40.      */
  41.     for (i = 0; i < NUM_PLANES; i++) {
  42.         flock[i].PX = (float) IRND(20) + GRID_RANGE / 2 - 10;
  43.         flock[i].PY = (float) IRND(20) + GRID_RANGE / 2 - 10;
  44.         flock[i].PZ = MAX(terrain_height(flock[i].PX, flock[i].PY),0.) +
  45.                 2.*(float)i/NUM_PLANES+.3;
  46.         flock[i].Pazimuth = ((float)IRND(256) / 128.) * M_PI;
  47.     }
  48. Speed = 0.1f;
  49. Azimuth = M_PI / 2.;
  50. #if 0
  51. // if (Init_pos) {
  52. // X = Init_x;
  53. // Y = Init_y;
  54. // Z = Init_z;
  55. // Azimuth = Init_azimuth;
  56. // Keyboard_mode = 1;
  57. //    }
  58. #endif
  59. }
  60. int _frame = 0;
  61. void fly(perfobj_t *viewer_pos)
  62. {
  63. float       terrain_z, xpos, ypos, xcntr, ycntr;
  64. float       delta_speed = .003;
  65. /* if (++_frame == 1000) {
  66. _frame = 0;
  67. init_positions();
  68. }*/
  69.     xcntr = Wxsize / 2;
  70.     ycntr = Wysize / 2;
  71.     if (Xgetbutton(RKEY))
  72.         init_positions();
  73.     if (Xgetbutton(SPACEKEY)) {
  74.         Keyboard_mode = !Keyboard_mode;
  75.     }
  76. if (Keyboard_mode) {
  77.         /*
  78.          * step-at-a-time debugging mode
  79.          */
  80.         if (Keyboard_mode && Xgetbutton(LEFTARROWKEY)) {
  81. Azimuth -= 0.025;
  82. }
  83. if (Keyboard_mode && Xgetbutton(RIGHTARROWKEY)) {
  84. Azimuth += 0.025;
  85. }
  86. if (Keyboard_mode && Xgetbutton(UPARROWKEY)) {
  87. X += cosf(-Azimuth + M_PI / 2.) * 0.025;
  88. Y += sinf(-Azimuth + M_PI / 2.) * 0.025;
  89. }
  90. if (Keyboard_mode && Xgetbutton(DOWNARROWKEY)) {
  91. X -= cosf(-Azimuth + M_PI / 2.) * 0.025;
  92. Y -= sinf(-Azimuth + M_PI / 2.) * 0.025;
  93. }
  94. if (Keyboard_mode && Xgetbutton(PAGEUPKEY)) {
  95. Z += 0.025;
  96.         }
  97.         if (Keyboard_mode && Xgetbutton(PAGEDOWNKEY)) {
  98.             Z -= 0.025;
  99.         }
  100.     } else {
  101.         /*
  102.          * simple, mouse-driven flight model
  103.          */
  104.         if (Xgetbutton(LEFTMOUSE) && Speed < .3)
  105.             Speed += delta_speed;
  106.         if (Xgetbutton(RIGHTMOUSE) && Speed > -.3)
  107.             Speed -= delta_speed;
  108.         if (Xgetbutton(MIDDLEMOUSE))
  109.             Speed = Speed*.8;
  110.         xpos = (Xgetvaluator(MOUSEX)-xcntr) / ((float)Wxsize*14.);
  111.         ypos = (Xgetvaluator(MOUSEY)-ycntr) / ((float)Wysize*.5);
  112.         /*
  113.          * move in direction of view
  114.          */
  115.         Azimuth += xpos;
  116.         X += cosf(-Azimuth + M_PI / 2.) * Speed;
  117.         Y += sinf(-Azimuth + M_PI / 2.) * Speed;
  118.         Z -= ypos * Speed;
  119.     }
  120.     /*
  121.      * keep from getting too close to terrain
  122.      */
  123.     terrain_z = terrain_height(X, Y);
  124.     if (Z < terrain_z +.4)
  125.         Z = terrain_z +.4;
  126.     X = MAX(X, 1.);
  127.     X = MIN(X, GRID_RANGE);
  128.     Y = MAX(Y, 1.);
  129.     Y = MIN(Y, GRID_RANGE);
  130.     Z = MIN(Z, 20.);
  131.     *((float *) viewer_pos->vdata + 0) = X;
  132.     *((float *) viewer_pos->vdata + 1) = Y;
  133.     *((float *) viewer_pos->vdata + 2) = Z;
  134.     *((float *) viewer_pos->vdata + 3) = Azimuth;
  135. }
  136. void fly_paper_planes(perfobj_t *paper_plane_pos)
  137. {
  138. int                 i;
  139. float               speed = .08;
  140. float               terrain_z;
  141. /*
  142.  * slow planes down in cyclops mode since
  143.      * frame rate is doubled 
  144.      */
  145.     for (i = 0; i < NUM_PLANES; i++) {
  146.         /*
  147.          * If plane is not turning, one chance in 50 of
  148.          * starting a turn
  149.          */
  150.         if (flock[i].Pcount == 0 && IRND(50) == 1) {
  151.             /* initiate a roll */
  152.             /* roll for a random period */
  153.             flock[i].Pcount = IRND(100);
  154.             /* random turn rate */
  155.             flock[i].Pturn_rate = IRND(100) / 10000.;
  156.             flock[i].Pdirection = IRND(3) - 1;
  157.         }
  158.         if (flock[i].Pcount > 0) {
  159.             /* continue rolling */
  160.             flock[i].Proll += flock[i].Pdirection * flock[i].Pturn_rate;
  161.             flock[i].Pcount--;
  162.         } else
  163.             /* damp amount of roll when turn complete */
  164.             flock[i].Proll *=.95;
  165.         /* turn as a function of roll */
  166.         flock[i].Pazimuth -= flock[i].Proll *.05;
  167.         /* follow terrain elevation */
  168.         terrain_z=terrain_height(flock[i].PX,flock[i].PY);
  169.         /* use a "spring-mass-damp" system of terrain follow */
  170.         flock[i].PZv = flock[i].PZv - 
  171.             .01 * (flock[i].PZ - (MAX(terrain_z,0.) +
  172.                          2.*(float)i/NUM_PLANES+.3)) - flock[i].PZv *.04;
  173.         /* U-turn if fly off world!! */
  174.         if (flock[i].PX < 1 || flock[i].PX > GRID_RANGE - 2 || flock[i].PY < 1 || flock[i].PY > GRID_RANGE - 2)
  175.             flock[i].Pazimuth += M_PI;
  176.         /* move planes */
  177.         flock[i].PX += cosf(flock[i].Pazimuth) * speed;
  178.         flock[i].PY += sinf(flock[i].Pazimuth) * speed;
  179.         flock[i].PZ += flock[i].PZv;
  180.     }
  181. for (i = 0; i < NUM_PLANES; i++) {
  182. *((float *) paper_plane_pos[i].vdata + 0) = flock[i].PX;
  183. *((float *) paper_plane_pos[i].vdata + 1) = flock[i].PY;
  184. *((float *) paper_plane_pos[i].vdata + 2) = flock[i].PZ;
  185. *((float *) paper_plane_pos[i].vdata + 3) = flock[i].Pazimuth * RAD_TO_DEG;
  186. *((float *) paper_plane_pos[i].vdata + 4) = flock[i].PZv * (-500.);
  187. *((float *) paper_plane_pos[i].vdata + 5) = flock[i].Proll *RAD_TO_DEG;
  188. }
  189. }
  190. /* compute height above terrain */
  191. static float terrain_height(float x, float y)
  192. {
  193.     float           dx, dy;
  194.     float           z00, z01, z10, z11;
  195.     float           dzx1, dzx2, z1, z2;
  196.     int             xi, yi;
  197.     x /= XYScale;
  198.     y /= XYScale;
  199.     xi = MIN((int)x, GridDim-2);
  200.     yi = MIN((int)y, GridDim-2);
  201.     dx = x - xi;
  202.     dy = y - yi;
  203.     /*
  204.                 View looking straight down onto terrain
  205.                         <--dx-->
  206.                         z00----z1-------z10  (terrain elevations)
  207.                          |     |         |   
  208.                       ^  |     Z at(x,y) |   
  209.                       |  |     |         |   
  210.  dy  |     |         |
  211.                       |  |     |         |   
  212.   |  |     |         |
  213.                       V z00----z2-------z10
  214.                       (xi,yi)
  215.                         Z= height returned
  216.                         
  217.     */
  218.     z00 = A[xi * GridDim + yi];
  219.     z10 = A[(xi + 1) * GridDim + yi];
  220.     z01 = A[xi * GridDim + yi + 1];
  221.     z11 = A[(xi + 1) * GridDim + yi + 1];
  222.     dzx1 = z10 - z00;
  223.     dzx2 = z11 - z01;
  224.     z1 = z00 + dzx1 * dx;
  225.     z2 = z01 + dzx2 * dx;
  226.     return (ScaleZ*((1.0 - dy) * z1 + dy * z2));
  227. }