int terrainScaleHeights(float min,float max) { float amp,aux,min1,max1,height; int total,i; if (terrainHeights == NULL) return(TERRAIN_ERROR_NOT_INITIALISED); if (min > max) { aux = min; min = max; max = aux; } amp = max - min; total = terrainGridWidth * terrainGridLength; min1 = terrainHeights[0]; max1 = terrainHeights[0]; for(i=1;i < total ; i++) { if (terrainHeights[i] > max1) max1 = terrainHeights[i]; if (terrainHeights[i] < min1) min1 = terrainHeights[i]; } if (min1 != max1) { for(i=0;i < total;i++) { height = (terrainHeights[i] - min1) / (max1-min1); terrainHeights[i] = height * amp + min; } if (terrainNormals != NULL) terrainComputeNormals(); } return(TERRAIN_OK); }
void terrainSmooth(float k) { int i,j; for(i=0;i<terrainGridLength;i++) for(j=1;j<terrainGridWidth;j++) terrainHeights[i*terrainGridWidth + j] = terrainHeights[i*terrainGridWidth + j] * (1-k) + terrainHeights[i*terrainGridWidth + j-1] * k; for(i=1;i<terrainGridLength;i++) for(j=0;j<terrainGridWidth;j++) terrainHeights[i*terrainGridWidth + j] = terrainHeights[i*terrainGridWidth + j] * (1-k) + terrainHeights[(i-1)*terrainGridWidth + j] * k; for(i=0; i<terrainGridLength; i++) for(j=terrainGridWidth-1;j>-1;j--) terrainHeights[i*terrainGridWidth + j] = terrainHeights[i*terrainGridWidth + j] * (1-k) + terrainHeights[i*terrainGridWidth + j+1] * k; for(i=terrainGridLength-2;i<-1;i--) for(j=0;j<terrainGridWidth;j++) terrainHeights[i*terrainGridWidth + j] = terrainHeights[i*terrainGridWidth + j] * (1-k) + terrainHeights[(i+1)*terrainGridWidth + j] * k; if (terrainNormals != NULL) terrainComputeNormals(); }
void terrainSetNormals(int normals) { if (normals) { terrainNormals = (float *)malloc(terrainGridWidth * terrainGridLength * sizeof(float)*3); terrainComputeNormals(); } else if (terrainNormals != NULL){ free(terrainNormals); terrainNormals = NULL; } }
int terrainIterateFault(int numIterations) { float dispAux,pd; int i,j,k,halfX,halfZ; float a,b,c,w,d; if (terrainHeights == NULL) return(TERRAIN_ERROR_NOT_INITIALISED); halfX = terrainGridWidth / 2; halfZ = terrainGridLength / 2; for (k = 0; k < numIterations;k++) { d = sqrt(halfX * halfX + halfZ * halfZ); w = rand(); a = cos(w); b = sin(w); c = ((float)rand() / RAND_MAX) * 2*d - d; iterationsDone++; if (iterationsDone < itMinDisp) disp = maxDisp + (iterationsDone/(itMinDisp+0.0))* (minDisp - maxDisp); else disp = minDisp; for (i = 0;i < terrainGridLength; i++) for(j = 0; j < terrainGridWidth; j++) { switch(terrainFunction){ case STEP: if ((i-halfZ) * a + (j-halfX) * b + c > 0) dispAux = disp; else dispAux = -disp; break; case SIN: pd = ((i-halfZ) * a + (j-halfX) * b + c)/terrainWaveSize; if (pd > 1.57) pd = 1.57; else if (pd < 0) pd = 0; dispAux = -disp/2 + sin(pd)*disp; break; case COS: pd = ((i-halfZ) * a + (j-halfX) * b + c)/terrainWaveSize; if (pd > 3.14) pd = 3.14; else if (pd < -3.14) pd = -3.14; dispAux = disp-(terrainWaveSize/(terrainGridWidth+0.0)) + cos(pd)*disp; break; } terrainHeights[i*terrainGridWidth + j] += dispAux; } } if (terrainNormals != NULL) terrainComputeNormals(); return(TERRAIN_OK); }
int terrainDim(float stepWidth, float stepLength) { if (stepWidth > 0 && stepLength > 0) { terrainStepWidth = stepWidth; terrainStepLength = stepLength; if (terrainNormals != NULL) terrainComputeNormals(); return(TERRAIN_OK); } else return(TERRAIN_ERROR_INVALID_PARAM); }
int terrainSimulateLighting(int sim) { terrainSimLight = sim; /* just in case we don't have normals already */ if (terrainNormals == NULL) { terrainNormals = (float *)malloc(terrainGridWidth * terrainGridLength * sizeof(float) * 3); terrainComputeNormals(); } if (terrainNormals == NULL) return(TERRAIN_ERROR_MEMORY_PROBLEM); else return(TERRAIN_OK); }
int terrainIterateCircles(int numIterations) { float dispAux; int i,j,k,halfX,halfZ,dispSign; float x,z,r,pd; if (terrainHeights == NULL) return(TERRAIN_ERROR_NOT_INITIALISED); halfX = terrainGridWidth / 2; halfZ = terrainGridLength / 2; for (k = 0; k < numIterations;k++) { z = ((float)rand() / RAND_MAX) * terrainGridWidth; x = ((float)rand() / RAND_MAX) * terrainGridLength; iterationsDone++; if (iterationsDone < itMinDisp) disp = maxDisp + (iterationsDone/(itMinDisp+0.0))* (minDisp - maxDisp); else disp = minDisp; r = ((float)rand() / RAND_MAX); if (r > 0.5) dispSign = 1; else dispSign = -1; for (i = 0;i < terrainGridLength; i++) for(j = 0; j < terrainGridWidth; j++) { pd = sqrt(((i-x)*(i-x) + (j-z)*(j-z)) / terrainCircleSize)*2; if (pd > 1) dispAux = 0.0; else if (pd < -1) dispAux = 0.0; else dispAux = disp/2*dispSign + cos(pd*3.14)*disp/2 * dispSign; terrainHeights[i*terrainGridWidth + j] += dispAux; } } if (terrainNormals != NULL) terrainComputeNormals(); return(TERRAIN_OK); }
int terrainApplyFilter() { int i,j,k1,k2,h1,h2,k,h; float aux,*terrainAux,filterSum;; terrainAux = (float *)malloc(sizeof(float)* terrainGridWidth * terrainGridLength); if (terrainAux == NULL) return TERRAIN_ERROR_MEMORY_PROBLEM; for(i=0;i < terrainGridLength;i++) for(j=0;j < terrainGridWidth; j++) { aux = 0.0; filterSum = 0.0; k1 = max(0,i-2); k2 = min(i+3, terrainGridLength); for (k = k1; k < k2; k++) { h1 = max(0,j-2); h2 = min(j+3, terrainGridWidth); for (h = h1;h < h2; h++) { aux += (terrainHeights[(k)*terrainGridWidth + (h)] * terrainFilter[(k-i+2)*5 + (h-j+2)]); filterSum += terrainFilter[(k-i+2)*5 + (h-j+2)]; } } terrainAux[i*terrainGridWidth + j] = aux / filterSum; } memcpy(terrainHeights,terrainAux,sizeof(float)* terrainGridWidth * terrainGridLength); free(terrainAux); if (terrainNormals != NULL) terrainComputeNormals(); return(TERRAIN_OK); }
int terrainLoadFromImage(char *filename, int normals) { tgaInfo *info; int mode; float pointHeight; /* if a terrain already exists, destroy it. */ if (terrainHeights != NULL) terrainDestroy(); /* load the image, using the tgalib */ info = tgaLoad(filename); /* check to see if the image was properly loaded remember: only greyscale, RGB or RGBA noncompressed images */ if (info->status != TGA_OK) return(TERRAIN_ERROR_LOADING_IMAGE); /* if the image is RGB, convert it to greyscale mode will store the image's number of components */ mode = info->pixelDepth / 8; if (mode == 3) { tgaRGBtoGreyscale(info); mode = 1; } /* set the width and height of the terrain */ terrainGridWidth = info->width; terrainGridLength = info->height; /* alocate memory for the terrain, and check for errors */ terrainHeights = (float *)malloc(terrainGridWidth * terrainGridLength * sizeof(float)); if (terrainHeights == NULL) return(TERRAIN_ERROR_MEMORY_PROBLEM); /* allocate memory for the normals, and check for errors */ if (normals) { terrainNormals = (float *)malloc(terrainGridWidth * terrainGridLength * sizeof(float) * 3); if (terrainNormals == NULL) return(TERRAIN_ERROR_MEMORY_PROBLEM); } else terrainNormals = NULL; /* if mode = RGBA then allocate memory for colors, and check for errors */ if (mode == 4) { terrainColors = (float *)malloc(terrainGridWidth * terrainGridLength * sizeof(float)*3); if (terrainColors == NULL) return(TERRAIN_ERROR_MEMORY_PROBLEM); } else terrainColors = NULL; /* fill arrays */ for (int i = 0 ; i < terrainGridLength; i++) for (int j = 0;j < terrainGridWidth; j++) { /* compute the height as a value between 0.0 and 1.0 */ pointHeight = info->imageData[mode*(i*terrainGridWidth + j)+(mode-1)] / 255.0; terrainHeights[i*terrainGridWidth + j] = pointHeight; /* if mode = RGBA then fill the colors array as well */ if (mode==4) { terrainColors[3*(i*terrainGridWidth + j)] = (info->imageData[mode*(i*terrainGridWidth + j)])/255.0; terrainColors[3*(i*terrainGridWidth + j)+1] = (info->imageData[mode*(i*terrainGridWidth + j)+1])/255.0; terrainColors[3*(i*terrainGridWidth + j)+2] = (info->imageData[mode*(i*terrainGridWidth + j)+2])/255.0; } } /* if we want normals then compute them */ if (normals) terrainComputeNormals(); /* free the image's memory */ tgaDestroy(info); return(TERRAIN_OK); }