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

GIS编程

开发平台:

Visual C++

  1. /*
  2.  * database.c   $Revision: 1.2 $
  3.  */
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <math.h>
  7. #include "skyfly.h"
  8. #if defined(_WIN32)
  9. #pragma warning (disable:4244)  /* disable bogus conversion warnings */
  10. #pragma warning (disable:4305)  /* VC++ 5.0 version of above warning. */
  11. #endif
  12. #define cosf(a) cos((float)a)
  13. #define sinf(a)   sin((float)a)
  14. #define sqrtf(a)   sqrt((float)a)
  15. #define expf(a)   exp((float)a)
  16. static void create_terrain(void);
  17. static void erode_terrain(void);
  18. static void color_terrain(void);
  19. static void init_cells(void);
  20. static void put_cell(float *source, perfobj_t *pobj);
  21. static void put_paper_plane(float *source, perfobj_t *pobj);
  22. static void put_texture_bind(int bind, perfobj_t *pobj);
  23. int clouds;
  24. static float paper_plane_vertexes[] = {
  25. /*Nx  Ny  Nz   Vx     Vy    Vz */
  26. /* ----------------------------    Top view of plane, middle streached open  */
  27.  0.2, 0., .98, -.10,    0,  .02,/* vertex #'s      4 (.48,0,-.06)            */
  28.  0., 0., 1.,   -.36,  .20, -.04,/*                 .                         */
  29.  0., 0., 1.,    .36,  .01,    0,/*                ...                        */
  30.  0., 0.,-1.,   -.32,  .02,    0,/*                 .             +X          */
  31.  0., 1., 0.,    .48,    0, -.06,/*               2 . 6,8          ^          */
  32.  0., 1., 0.,   -.30,    0, -.12,/*               . . .            |          */
  33.  0.,-1., 0.,    .36, -.01,    0,/*              .. . ..           |          */
  34.  0.,-1., 0.,   -.32, -.02,    0,/*               . . .            |          */
  35.  0., 0.,-1.,    .36, -.01,    0,/*             . . . . .  +Y<-----*          */
  36.  0., 0.,-1.,   -.36, -.20, -.04,/*               . . .     for this picture  */
  37.  -0.2, 0., .98,  -.10,  0,  .02,/*            .  . . .  .  coord system rot. */
  38.  -0.2, 0., -.98, -.10,  0,  .02,/*               . . .     90 degrees        */
  39.  0., 0., -1.,  -.36,  .20, -.04,/*           .   . . .   .                   */
  40.  0., 0., -1.,   .36,  .01,    0,/*               . # .           # marks     */
  41.  0., 0., 1.,   -.32,  .02,    0,/*          .    . . .    .   (0,0) origin   */
  42.  0., -1., 0.,   .48,    0, -.06,/*               . . .         (z=0 at top   */
  43.  0., -1., 0.,  -.30,    0, -.12,/*         .     0 . 10    .    of plane)    */
  44.  0.,1., 0.,     .36, -.01,    0,/*             . . . . .                     */
  45.  0.,1., 0.,    -.32, -.02,    0,/*        .  .   . . .   .  .                */
  46.  0., 0.,1.,     .36, -.01,    0,/*         .     . . .     .                 */
  47.  0., 0.,1.,    -.36, -.20, -.04,/*       1.......3.5.7.......9               */
  48.  0.2, 0., -.98,  -.10,  0,  .02,/* (-.36,.2,-.04)                            */
  49. };
  50. #define SIZE    400
  51. float *A;
  52. void init_paper_planes(void)
  53. {
  54.     perfobj_t       *pobj;
  55.     /* 
  56.      * create various perf-objs for planes 
  57.      */
  58.     pobj = &(SharedData->paper_plane_obj);
  59.     pobj->flags = SharedData->paper_plane_flags;
  60.     pobj->vdata = (float *) SharedData->paper_plane_verts;
  61.     put_paper_plane(paper_plane_vertexes, pobj);
  62.     pobj = &(SharedData->paper_plane_start_obj);
  63.     pobj->flags = SharedData->paper_plane_start_flags;
  64.     *(pobj->flags) = PD_PAPER_PLANE_MODE;
  65.     *(pobj->flags + 1) = PLANES_START;
  66.     *(pobj->flags + 2) = PD_END;
  67.     pobj = &(SharedData->paper_plane_2ndpass_obj);
  68.     pobj->flags = SharedData->paper_plane_2ndpass_flags;
  69.     *(pobj->flags) = PD_PAPER_PLANE_MODE;
  70.     *(pobj->flags + 1) = PLANES_SECOND_PASS;
  71.     *(pobj->flags + 2) = PD_END;
  72.     pobj = &(SharedData->paper_plane_end_obj);
  73.     pobj->flags = SharedData->paper_plane_end_flags;
  74.     *(pobj->flags) = PD_PAPER_PLANE_MODE;
  75.     *(pobj->flags + 1) = PLANES_END;
  76.     *(pobj->flags + 2) = PD_END;
  77. }
  78. /*
  79.  * create perfobj from static definition of plane geometry above
  80.  */
  81. static void put_paper_plane(float *source, perfobj_t *pobj)
  82. {
  83.     int             j;
  84.     perfobj_vert_t *pdataptr =(perfobj_vert_t *) pobj->vdata;
  85.     unsigned int  *flagsptr = pobj->flags;
  86.     float          *sp = source;
  87.     *flagsptr++ = PD_DRAW_PAPER_PLANE;
  88.     for (j = 0; j < 22; j++) {
  89.         putn3fdata(sp + 0, pdataptr);
  90.         putv3fdata(sp + 3, pdataptr);
  91.         sp += 6;
  92.         pdataptr++;
  93.     }
  94.     *flagsptr++ = PD_END;
  95. }
  96. static void put_texture_bind(int bind, perfobj_t *pobj)
  97. {
  98. unsigned int  *flagsptr = pobj->flags;
  99. *flagsptr++ = PD_TEXTURE_BIND;
  100. *flagsptr++ = bind;
  101. *flagsptr++ = PD_END;
  102. }
  103. static void put_clouds_vert(float s, float t, float x, float y, float z,
  104. perfobj_vert_t *pdataptr)
  105. {
  106. float           D[5];
  107. D[0] = s;
  108. D[1] = t;
  109. D[2] = x;
  110. D[3] = y;
  111. D[4] = z;
  112. putt2fdata(D, pdataptr);
  113. putv3fdata(D + 2, pdataptr);
  114. }
  115. float S[SIZE][SIZE];
  116. float T[SIZE][SIZE];
  117. float C[SIZE][SIZE][3];
  118. int   M[SIZE][SIZE];
  119. void init_terrain(void)
  120. {
  121. GridDim = CellDim * NumCells;
  122. XYScale = (float)GRID_RANGE / (float)GridDim;
  123. CellSize = (float)GRID_RANGE / (float)NumCells;
  124. create_terrain();
  125. erode_terrain();
  126. color_terrain();
  127. init_cells();
  128. }
  129. #define SKY                             50.
  130. void init_clouds(void)
  131. {
  132.     perfobj_t *pobj;
  133.     perfobj_vert_t *pdataptr;
  134. clouds = 0;
  135.     pobj = &(SharedData->clouds_texture_obj);
  136.     pobj->flags = SharedData->clouds_texture_flags;
  137.     put_texture_bind(2,pobj);
  138.     pobj = &(SharedData->clouds_obj);
  139.     pobj->flags = SharedData->clouds_flags;
  140.     pobj->vdata = (float *)SharedData->clouds_verts;
  141.     *(pobj->flags+ 0) = PD_DRAW_CLOUDS;
  142.     *(pobj->flags+ 1) = PD_END;
  143.     pdataptr =(perfobj_vert_t *) pobj->vdata;
  144.     put_clouds_vert(0.,0., -SKY, -SKY, SKY_HIGH,pdataptr);
  145.     pdataptr++;
  146.     put_clouds_vert(24.,0.,  SKY+GRID_RANGE, -SKY, SKY_HIGH,pdataptr);
  147.     pdataptr++;
  148.     put_clouds_vert(24.,24.,  SKY+GRID_RANGE,  SKY+GRID_RANGE, SKY_HIGH,pdataptr);
  149.     pdataptr++;
  150.     put_clouds_vert(0.,24., -SKY,  SKY+GRID_RANGE, SKY_HIGH,pdataptr);
  151. }
  152. static void create_terrain(void)
  153. {
  154. int             r, c, i, x1, y1, x2, y2;
  155. int             hillsize;
  156.     hillsize = GRID_RANGE / 12;
  157.     A = (float*)calloc(GridDim * GridDim, sizeof(float));
  158.     /*
  159.      *  initialize elevation to zero, except band down middle
  160.      *  where make a maximum height 'hill' that will later be
  161.      *  inverted to make the negative elevation 'canyon'
  162.      */
  163.     for (r = 0; r < GridDim; r++)
  164.         for (c = 0; c < GridDim; c++)
  165.              if(r>=(GridDim/2-2-IRND(2)) && r<=(GridDim/2+2+IRND(2)))
  166.                 A[r * GridDim + c] = 1.0;
  167.              else
  168.                 A[r * GridDim + c] = 0.0;
  169.     /*
  170.      * create random sinusoidal hills that add on top
  171.      * of each other
  172.      */
  173.     for (i = 1; i <= 10*GridDim; i++) {
  174.         /* randomly position hill */
  175.         x1 = IRND(GridDim - hillsize);
  176.         x2 = x1 + hillsize/ 8 + IRND(hillsize-hillsize/ 8);
  177.         y1 = IRND(GridDim - hillsize);
  178.         y2 = y1 + hillsize/ 8 + IRND(hillsize-hillsize/ 8);
  179.         if((x1<=GridDim/2-4 && x2>=GridDim/2-4) || 
  180.            (x1<=GridDim/2+4 && x2>=GridDim/2+4))
  181.         {
  182.             x1 = IRND(2)-2 + GridDim/2;
  183.             x2 = x1 + IRND(GridDim/2 - x1 + 2);
  184.         }
  185.         /* make a sinusoidal hill */
  186.         for (r = x1; r < x2; r++)
  187.             for (c = y1; c < y2; c++) {
  188.                 A[r * GridDim + c] +=.35 *
  189.                     (sinf(M_PI * (float) (r - x1) / (float) (x2 - x1)) *
  190.  (sinf(M_PI * (float) (c - y1) / (float) (y2 - y1))));
  191.             }
  192.     }
  193.     /* clamp the elevation of the terrain */
  194. for (r = 1; r < GridDim; r++)
  195. for (c = 1; c < GridDim; c++) {
  196. A[r * GridDim + c] = MIN(A[r * GridDim + c], .95);
  197. A[r * GridDim + c] = MAX(A[r * GridDim + c], 0.);
  198. }
  199. }
  200. #define NUM_DROPS                       80
  201. static void erode_terrain(void)
  202. {
  203.     float           x, y, xv, yv, dx, dy;
  204.     float           cut, min, take;
  205.     int             nm;
  206.     int             t, xi, yi, xo, yo, done;
  207.     int             ii, jj, r, c;
  208.     for (nm = 1; nm < NUM_DROPS*GridDim; nm++) {
  209.         /* find a random position to start the 'rain drop' */
  210.         x = (float) (IRND(GridDim));
  211.         y = (float) (IRND(GridDim));
  212.         /* Clamp x and y to be inside grid */
  213.         x = MIN(MAX(2., x), (float)GridDim-2.);
  214.         y = MIN(MAX(2., y), (float)GridDim-2.);
  215.         
  216.         done = 0;
  217.         yv = xv = 0.;
  218.         t = 0;
  219.         cut = .3;
  220.         while (!done) {
  221.             xi = (int) x;
  222.             yi = (int) y;
  223.             min = 90.;
  224. if (xi != xo || yi != yo) {
  225.                 cut *=.99;
  226.                 /* gradient */
  227.                 dx = (A[(xi + 1)*GridDim + yi] - A[(xi - 1) * GridDim + yi]);
  228.                 dy = (A[xi * GridDim + yi + 1] - A[xi * GridDim + yi - 1]);
  229.                 /* find lowest neighbor */
  230.                 for (ii = -1; ii <= 1; ii++)
  231.                     for (jj = -1; jj <= 1; jj++)
  232.                         if (A[(xi + ii)*GridDim + yi + jj] < min)
  233.                             min = A[(xi + ii)*GridDim + yi + jj];
  234.                 /* evaporate drop if sitting on my old location */
  235.                 if (M[xi][yi] == nm)
  236. done = 1;
  237.                 M[xi][yi] = nm;
  238.                 /* cave in neighbors by .3  */
  239.                 for (ii = -1; ii <= 1; ii++)
  240.                     for (jj = -1; jj <= 1; jj++) {
  241.                         take =.3 * cut * (A[(xi + ii)*GridDim + yi + jj]-min);
  242.                         A[(xi + ii)*GridDim + yi + jj] -= take;
  243.                     }
  244.                 /* take away from this cell by .7 */
  245.                 take = (A[xi*GridDim + yi] - min) *.7 * cut;
  246.                 A[xi*GridDim + yi] -= take;
  247.             }
  248.             xo = xi;
  249.             yo = yi;
  250.             /* move drop using kinematic motion*/
  251.             xv = xv - dx -.8 * xv;
  252.             yv = yv - dy -.8 * yv;
  253.             x += xv;
  254.             y += yv;
  255.             /*
  256.              * make sure can't move by more that 1.0
  257.              * in any direction 
  258.              */
  259.             xv = MAX(xv, -1);
  260.             yv = MAX(yv, -1);
  261.             xv = MIN(xv,  1);
  262.             yv = MIN(yv,  1);
  263.             /* check to see if need a new drop */
  264.             /* ie ran of world, got stuck, or at 'sea level' */
  265.             if (x < 1.|| x > GridDim - 1.|| y < 1.|| y > GridDim - 1.
  266.                                                 || t++ > 2000
  267.                 || cut <.01)
  268.                 done = 1;
  269.             if (A[xi*GridDim + yi] < 0.0001) {
  270.                 A[xi*GridDim + yi] = 0.;
  271.                 done = 1;
  272.             }
  273. }                       /* while (!done) with this drop */
  274. }                           /* next drop */
  275. /*
  276.  *  invert the pseudo hill int the pseudo canyon
  277.  */
  278. for (r = 0; r < GridDim; r++)
  279. for (c = 0; c < GridDim; c++)
  280.  if(r>=GridDim/2-4 && r<=GridDim/2+4)
  281. A[r * GridDim + c] = MAX((-3.2 * A[r * GridDim + c]), -1.8);
  282. }
  283. static void color_terrain(void)
  284. {
  285.     float           N[3], D, alt, maxelev = -1.;
  286.     int             x, y;
  287.     for (x = 0; x < GridDim; x++)
  288.         for (y = 0; y < GridDim; y++)
  289.             maxelev = MAX(maxelev, A[x * GridDim + y]);
  290.     for (x = 1; x < GridDim - 1; x++)
  291.         for (y = 1; y < GridDim - 1; y++) {
  292.             alt = A[x * GridDim + y] * 1.5;
  293.             /* randomly perterb to get a mottling effect */
  294.             alt += IRND(100) / 400. -.125;
  295.             alt = MIN(alt, 1.0);
  296.             if (alt < -.11) {
  297.                 C[x][y][0] = 0.6;         /* soil/rock in canyon */
  298.                 C[x][y][1] = 0.5;
  299.                 C[x][y][2] = 0.2;
  300.             } else if (alt < .000001) {
  301.                 C[x][y][0] = 0.0;         /* dark, jungle lowlands */
  302.                 C[x][y][1] = 0.2;
  303.                 C[x][y][2] = 0.05;
  304.             } else if (alt <.90) {
  305.                 C[x][y][0] = alt*.25;     /* green to redish hillsides */
  306.                 C[x][y][1] = (1.0 - alt) *.4 + .1;
  307.                 C[x][y][2] = 0.1;
  308.             } else {
  309.                 C[x][y][0] = alt;
  310.                 C[x][y][1] = alt;         /* incresingly white snow */
  311.                 C[x][y][2] = alt;
  312.             }
  313.             /* compute normal to terrain */
  314.             N[0] = A[(x - 1)*GridDim + y] - A[(x + 1)*GridDim + y];
  315.             N[1] = A[x*GridDim + y - 1] - A[x*GridDim + y + 1];
  316.             N[2] = 2.0 / ScaleZ;
  317.             D = 1.0 / sqrtf(N[0] * N[0] + N[1] * N[1] + N[2] * N[2]);
  318.             N[0] *= D;
  319.             N[1] *= D;
  320.             N[2] *= D;
  321.             /* perform diffuse lighting of terrain */
  322.             D = N[0] * LX + N[1] * LY + N[2] * LZ;
  323.             D *= 1.2;
  324.             if(!IRND(4)) D *= .5;
  325.         
  326.             D = MAX(D,0);
  327.             /* darken terrain on shaded side */
  328.             C[x][y][0] *= D;
  329.             C[x][y][1] *= D;
  330.             C[x][y][2] *= D;
  331.             S[x][y] = (float) (x) / (float)CellDim;
  332.             T[x][y] = (float) (y) / (float)CellDim;
  333.         }
  334. }
  335. /*
  336.  * create perobj to hold a cell of terrain
  337.  * for a 5x5 terrain cell, there will be 5
  338.  * tmeshes each with 10 triangles (12 vertexes)
  339.  * this means looking past my cell to neighbors
  340.  * to stitch things together.  To keep data contigious,
  341.  * vertexes are repeated in tmeshes, not shared.
  342.  */
  343. static void init_cells(void)
  344. {
  345.     int             x, y, xx, yy, world_x, world_y;
  346.     int             pntr, index, sstart, tstart;
  347.     float           *D;
  348.     perfobj_t       *pobj;
  349.     D = (float*)calloc(CellDim *(CellDim + 1) * 
  350.                         2 * FLOATS_PER_VERT_PAIR, sizeof(float));
  351.     pobj = &(SharedData->terrain_texture_obj);
  352.     pobj->flags = SharedData->terrain_texture_flags;
  353.     put_texture_bind(1, pobj);
  354.     for (x = 0; x < NumCells; x++)
  355.         for (y = 0; y < NumCells; y++) {
  356. index = x*NumCells+y;
  357.             SharedData->terrain_cells[index].flags = 
  358.                 SharedData->terrain_cell_flags[index];
  359.             SharedData->terrain_cells[index].vdata =
  360.                 (float *) SharedData->terrain_cell_verts[index];
  361.             pntr = 0;
  362.             /*
  363.              * Guarantee S,T to be within range 0-8 for tmesh strip using
  364.              * 256x256 sized texture. This avoids texture index clipping
  365.              * in pipe. 
  366.             */
  367.             sstart = (int)S[x*CellDim][y*CellDim];
  368.             tstart = (int)T[x*CellDim][y*CellDim];
  369.             for (xx = 0; xx < CellDim; xx++)
  370.                 for (yy = 0; yy < CellDim + 1; yy++) {
  371.                     /* init a perfobj */
  372.                     world_x = MIN(x * CellDim + xx, GridDim-2);
  373.                     world_y = MIN(y * CellDim + yy, GridDim-2);
  374.                     D[pntr + 0] = S[world_x][world_y] - sstart;
  375.                     D[pntr + 1] = T[world_x][world_y] - tstart;
  376.                     D[pntr + 2] = C[world_x][world_y][0];
  377.                     D[pntr + 3] = C[world_x][world_y][1];
  378. D[pntr + 4] = C[world_x][world_y][2];
  379.                     D[pntr + 5] = (float)world_x * XYScale;
  380.                     D[pntr + 6] = (float)world_y * XYScale;
  381. D[pntr + 7] = A[world_x*GridDim + world_y]*ScaleZ;
  382.                     D[pntr + 8] = S[world_x + 1][world_y] - sstart;
  383.                     D[pntr + 9] = T[world_x + 1][world_y] - tstart;
  384.                     D[pntr + 10] = C[world_x + 1][world_y][0];
  385.                     D[pntr + 11] = C[world_x + 1][world_y][1];
  386.                     D[pntr + 12] = C[world_x + 1][world_y][2];
  387.                     D[pntr + 13] = (float)(world_x+1) * XYScale;
  388.                     D[pntr + 14] = (float)world_y * XYScale;
  389.                     D[pntr + 15] = A[(world_x+1)*GridDim + world_y] * ScaleZ;
  390.                     pntr += FLOATS_PER_VERT_PAIR;
  391.                 }               /* for each cell */
  392.             put_cell(D, &(SharedData->terrain_cells[index]));
  393.         }                       /* for all cells in world */
  394.         free(D);
  395. }
  396. static void put_cell(float *source, perfobj_t *pobj)
  397. {
  398. int             i, j;
  399. perfobj_vert_t *pdataptr =(perfobj_vert_t *) pobj->vdata;
  400. unsigned int  *flagsptr = pobj->flags;
  401. float          *sp = source;
  402. /* For all tmesh strips in cell */
  403. for (i = 0; i < CellDim; i++) {
  404. *flagsptr++ = PD_DRAW_TERRAIN_CELL;
  405. *flagsptr++ = (unsigned long) pdataptr;
  406. /* For all verts in tmesh strip */
  407. for (j = 0; j < (CellDim + 1) * 2; j++) {
  408. putt2fdata(sp, pdataptr);
  409. putc3fdata(sp + 2, pdataptr);
  410.             putv3fdata(sp + 5, pdataptr);
  411.             sp += 8;
  412.             pdataptr++;
  413.         }
  414.     }
  415.     *flagsptr++ = PD_END;
  416. }