📄 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 + -