/*************************************************************************** file : elevation.cpp created : Mon May 20 22:31:09 CEST 2002 copyright : (C) 2001 by Eric Espie email : eric.espie@torcs.org version : $Id: elevation.cpp,v 1.9 2005/07/05 17:48:21 berniw Exp $ ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /** @file @author Eric Espie @version $Id: elevation.cpp,v 1.9 2005/07/05 17:48:21 berniw Exp $ */ #include #include #include #include #include #ifndef WIN32 #include #endif #include #include #include #include "trackgen.h" #include "util.h" #include "elevation.h" static unsigned char *ElvImage; static int ElvOk = 0; static tdble Margin; static tdble kX, kY, dX, dY; static tdble kZ, dZ; static int width, height; #define MAX_CLR 255.0 void LoadElevation(tTrack *track, void *TrackHandle, char *imgFile) { tdble zmin, zmax; tdble xmin, xmax, ymin, ymax; ElvImage = GfImgReadPng(imgFile, &width, &height, 2.0); if (!ElvImage) { return; } printf("Loading Elevation Map %s\n", imgFile); Margin = GfParmGetNum(TrackHandle, TRK_SECT_TERRAIN, TRK_ATT_BMARGIN, NULL, Margin); xmin = track->min.x - Margin; xmax = track->max.x + Margin; ymin = track->min.y - Margin; ymax = track->max.y + Margin; kX = (tdble)(width - 1) / (xmax - xmin); dX = -xmin * kX; kY = (tdble)(height - 1) / (ymax - ymin); dY = -ymin * kY; ElvOk = 1; zmin = GfParmGetNum(TrackHandle, TRK_SECT_TERRAIN, TRK_ATT_ALT_MIN, NULL, track->min.z); zmax = GfParmGetNum(TrackHandle, TRK_SECT_TERRAIN, TRK_ATT_ALT_MAX, NULL, track->max.z); dZ = zmin; kZ = (zmax - dZ) / MAX_CLR; } tdble GetElevation(tdble x, tdble y, tdble z) { int iX, iY; int clr; if (ElvOk) { iX = (int)(x * kX + dX); iY = (int)(y * kY + dY); /* RGBA */ clr = ElvImage[4 * (iY * width + iX)]; return (tdble)clr * kZ + dZ; } return z; } void SaveElevation(tTrack *track, void *TrackHandle, char *imgFile, char *meshFile, int dispf) { ssgLoaderOptionsEx options; float zmin, zmax; float xmin, xmax, ymin, ymax; float x, y, z; int clr; int i, j, k, l; ssgRoot *root; int columns; static char buf[1024]; char *s; float heightStep; s = getenv("COLUMNS"); if (s) { columns = strtol(getenv("COLUMNS"), NULL, 0); } else { columns = 80; } Margin = GfParmGetNum(TrackHandle, TRK_SECT_TERRAIN, TRK_ATT_BMARGIN, NULL, Margin); xmin = track->min.x - Margin; xmax = track->max.x + Margin; ymin = track->min.y - Margin; ymax = track->max.y + Margin; width = 1024; height = (int)((ymax - ymin) * width / (xmax - xmin)); printf("Generating Elevation Map %s (%d, %d)\n", imgFile, width, height); kX = (xmax - xmin) / width; dX = xmin; kY = (ymax - ymin) / height; dY = ymin; zmin = GfParmGetNum(TrackHandle, TRK_SECT_TERRAIN, TRK_ATT_ALT_MIN, NULL, track->min.z); zmax = GfParmGetNum(TrackHandle, TRK_SECT_TERRAIN, TRK_ATT_ALT_MAX, NULL, track->max.z); heightStep = (float)(zmax - zmin) / (float)HeightSteps; if (dispf == 2) { printf("Height of steps = %f\n", heightStep); } kZ = MAX_CLR / (zmax - zmin); dZ = - zmin * MAX_CLR / (zmax - zmin); ElvImage = (unsigned char*)calloc(width * height, 3); if (!ElvImage) { return; } ssgSetCurrentOptions(&options); sprintf(buf, "tracks/%s/%s;data/textures;data/img;.", track->category, track->internalname); ssgTexturePath(buf); sprintf(buf, ".;tracks/%s/%s", track->category, track->internalname); ssgModelPath(buf); root = (ssgRoot*)ssgLoadAC(meshFile); if (root == NULL) { printf("Could not load %s, ", meshFile); printf("please generate it with \"trackgen -c %s -n %s -a\"\n", track->category, track->internalname); return; } l = columns - 18; for (j = 0; j < height; j++) { s = buf; s += sprintf(buf, "%4d%% |", (j+1) * 100 / height); for (k = s - buf; k < s - buf + l; k++) { if ((k - (s - buf)) > (l * (j+1) / height)) { buf[k] = ' '; } else { buf[k] = '*'; } } s += l; sprintf(s, "| row %4d", j+1); printf("\r%s", buf); fflush(stdout); for (i = 0; i < width; i++) { x = i * kX + dX; y = j * kY + dY; switch (dispf) { case 0: clr = 0; break; case 1: z = getHOT(root, x, y); if (z != -1000000.0f) { clr = (int)(z * kZ + dZ); } else { clr = (int)MAX_CLR; } break; case 2: z = getHOT(root, x, y); if (z != -1000000.0f) { clr = (int)(floor((z + heightStep / 2.0) / heightStep) * heightStep * kZ + dZ); } else { clr = (int)MAX_CLR; } break; default: clr = 0; break; } ElvImage[3 * (i + width * j)] = (unsigned char)clr; ElvImage[3 * (i + width * j) + 1] = (unsigned char)clr; ElvImage[3 * (i + width * j) + 2] = (unsigned char)clr; } } printf("\n"); GfImgWritePng(ElvImage, imgFile, width, height); }