📄 database.c
字号:
x = MIN(MAX(2., x), (float)GridDim-2.); y = MIN(MAX(2., y), (float)GridDim-2.); done = 0; yv = xv = 0.; t = 0; cut = .3; while (!done) { xi = (int) x; yi = (int) y; min = 90.; if (xi != xo || yi != yo) { cut *=.99; /* gradient */ dx = (A[(xi + 1)*GridDim + yi] - A[(xi - 1) * GridDim + yi]); dy = (A[xi * GridDim + yi + 1] - A[xi * GridDim + yi - 1]); /* find lowest neighbor */ for (ii = -1; ii <= 1; ii++) for (jj = -1; jj <= 1; jj++) if (A[(xi + ii)*GridDim + yi + jj] < min) min = A[(xi + ii)*GridDim + yi + jj]; /* evaporate drop if sitting on my old location */ if (M[xi][yi] == nm) done = 1; M[xi][yi] = nm; /* cave in neighbors by .3 */ for (ii = -1; ii <= 1; ii++) for (jj = -1; jj <= 1; jj++) { take =.3 * cut * (A[(xi + ii)*GridDim + yi + jj]-min); A[(xi + ii)*GridDim + yi + jj] -= take; } /* take away from this cell by .7 */ take = (A[xi*GridDim + yi] - min) *.7 * cut; A[xi*GridDim + yi] -= take; } xo = xi; yo = yi; /* move drop using kinematic motion*/ xv = xv - dx -.8 * xv; yv = yv - dy -.8 * yv; x += xv; y += yv; /* * make sure can't move by more that 1.0 * in any direction */ xv = MAX(xv, -1); yv = MAX(yv, -1); xv = MIN(xv, 1); yv = MIN(yv, 1); /* check to see if need a new drop */ /* ie ran of world, got stuck, or at 'sea level' */ if (x < 1.|| x > GridDim - 1.|| y < 1.|| y > GridDim - 1. || t++ > 2000 || cut <.01) done = 1; if (A[xi*GridDim + yi] < 0.0001) { A[xi*GridDim + yi] = 0.; done = 1; } } /* while (!done) with this drop */ } /* next drop */ /* * invert the pseudo hill int the pseudo canyon */ for (r = 0; r < GridDim; r++) for (c = 0; c < GridDim; c++) if(r>=GridDim/2-4 && r<=GridDim/2+4) A[r * GridDim + c] = MAX((-3.2 * A[r * GridDim + c]), -1.8);}static void color_terrain(void){ float N[3], D, alt, maxelev = -1.; int x, y; for (x = 0; x < GridDim; x++) for (y = 0; y < GridDim; y++) maxelev = MAX(maxelev, A[x * GridDim + y]); for (x = 1; x < GridDim - 1; x++) for (y = 1; y < GridDim - 1; y++) { alt = A[x * GridDim + y] * 1.5; /* randomly perterb to get a mottling effect */ alt += IRND(100) / 400. -.125; alt = MIN(alt, 1.0); if (alt < -.11) { C[x][y][0] = 0.6; /* soil/rock in canyon */ C[x][y][1] = 0.5; C[x][y][2] = 0.2; } else if (alt < .000001) { C[x][y][0] = 0.0; /* dark, jungle lowlands */ C[x][y][1] = 0.2; C[x][y][2] = 0.05; } else if (alt <.90) { C[x][y][0] = alt*.25; /* green to redish hillsides */ C[x][y][1] = (1.0 - alt) *.4 + .1; C[x][y][2] = 0.1; } else { C[x][y][0] = alt; C[x][y][1] = alt; /* incresingly white snow */ C[x][y][2] = alt; } /* compute normal to terrain */ N[0] = A[(x - 1)*GridDim + y] - A[(x + 1)*GridDim + y]; N[1] = A[x*GridDim + y - 1] - A[x*GridDim + y + 1]; N[2] = 2.0 / ScaleZ; D = 1.0 / sqrtf(N[0] * N[0] + N[1] * N[1] + N[2] * N[2]); N[0] *= D; N[1] *= D; N[2] *= D; /* perform diffuse lighting of terrain */ D = N[0] * LX + N[1] * LY + N[2] * LZ; D *= 1.2; if(!IRND(4)) D *= .5; D = MAX(D,0); /* darken terrain on shaded side */ C[x][y][0] *= D; C[x][y][1] *= D; C[x][y][2] *= D; S[x][y] = (float) (x) / (float)CellDim; T[x][y] = (float) (y) / (float)CellDim; }}/* * create perobj to hold a cell of terrain * for a 5x5 terrain cell, there will be 5 * tmeshes each with 10 triangles (12 vertexes) * this means looking past my cell to neighbors * to stitch things together. To keep data contigious, * vertexes are repeated in tmeshes, not shared. */static void init_cells(void){ int x, y, xx, yy, world_x, world_y; int pntr, index, sstart, tstart; float *D; perfobj_t *pobj; D = (float*)calloc(CellDim *(CellDim + 1) * 2 * FLOATS_PER_VERT_PAIR, sizeof(float)); pobj = &(SharedData->terrain_texture_obj); pobj->flags = SharedData->terrain_texture_flags; put_texture_bind(1, pobj); for (x = 0; x < NumCells; x++) for (y = 0; y < NumCells; y++) { index = x*NumCells+y; SharedData->terrain_cells[index].flags = SharedData->terrain_cell_flags[index]; SharedData->terrain_cells[index].vdata = (float *) SharedData->terrain_cell_verts[index]; pntr = 0; /* * Guarantee S,T to be within range 0-8 for tmesh strip using * 256x256 sized texture. This avoids texture index clipping * in pipe. */ sstart = (int)S[x*CellDim][y*CellDim]; tstart = (int)T[x*CellDim][y*CellDim]; for (xx = 0; xx < CellDim; xx++) for (yy = 0; yy < CellDim + 1; yy++) { /* init a perfobj */ world_x = MIN(x * CellDim + xx, GridDim-2); world_y = MIN(y * CellDim + yy, GridDim-2); D[pntr + 0] = S[world_x][world_y] - sstart; D[pntr + 1] = T[world_x][world_y] - tstart; D[pntr + 2] = C[world_x][world_y][0]; D[pntr + 3] = C[world_x][world_y][1]; D[pntr + 4] = C[world_x][world_y][2]; D[pntr + 5] = (float)world_x * XYScale; D[pntr + 6] = (float)world_y * XYScale; D[pntr + 7] = A[world_x*GridDim + world_y]*ScaleZ; D[pntr + 8] = S[world_x + 1][world_y] - sstart; D[pntr + 9] = T[world_x + 1][world_y] - tstart; D[pntr + 10] = C[world_x + 1][world_y][0]; D[pntr + 11] = C[world_x + 1][world_y][1]; D[pntr + 12] = C[world_x + 1][world_y][2]; D[pntr + 13] = (float)(world_x+1) * XYScale; D[pntr + 14] = (float)world_y * XYScale; D[pntr + 15] = A[(world_x+1)*GridDim + world_y] * ScaleZ; pntr += FLOATS_PER_VERT_PAIR; } /* for each cell */ put_cell(D, &(SharedData->terrain_cells[index])); } /* for all cells in world */ free(D);}static void put_cell(float *source, perfobj_t *pobj){ int i, j; perfobj_vert_t *pdataptr =(perfobj_vert_t *) pobj->vdata; unsigned int *flagsptr = pobj->flags; float *sp = source; /* For all tmesh strips in cell */ for (i = 0; i < CellDim; i++) { *flagsptr++ = PD_DRAW_TERRAIN_CELL; *flagsptr++ = (unsigned long) pdataptr; /* For all verts in tmesh strip */ for (j = 0; j < (CellDim + 1) * 2; j++) { putt2fdata(sp, pdataptr); putc3fdata(sp + 2, pdataptr); putv3fdata(sp + 5, pdataptr); sp += 8; pdataptr++; } } *flagsptr++ = PD_END;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -