00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <landscapemap/HeightMapLoader.h>
00022 #include <image/ImageFactory.h>
00023 #include <image/ImageBitmap.h>
00024 #include <common/RandomGenerator.h>
00025 #include <common/Defines.h>
00026 #include <common/Logger.h>
00027 #include <lang/LangResource.h>
00028
00029 void HeightMapLoader::loadTerrain(HeightMap &hmap,
00030 Image &bitmap,
00031 bool levelSurround,
00032 ProgressCounter *counter)
00033 {
00034 if (counter) counter->setNewOp(LANG_RESOURCE("LOADING_LANDSCAPE", "Loading Landscape"));
00035 hmap.reset();
00036
00037 fixed dhx = fixed(bitmap.getWidth()) / fixed(hmap.getMapWidth()+1);
00038 fixed dhy = fixed(bitmap.getHeight()) / fixed(hmap.getMapHeight()+1);
00039
00040 int bh = bitmap.getHeight();
00041 int bw = bitmap.getWidth();
00042
00043 fixed scale(true, 25000);
00044
00045 fixed hy = fixed(0);
00046 for (int by=0; by<=hmap.getMapHeight(); by++, hy+=dhy)
00047 {
00048 if (counter) counter->setNewPercentage((100.0f * float(by)) / float(hmap.getMapHeight()));
00049
00050 int ihy = hy.floor().asInt();
00051 int ihy2 = ihy + 1; if (ihy2 >= bh) --ihy2;
00052
00053 int offsety = ihy * bw * 3;
00054 int offsety2 = ihy2 * bw * 3;
00055 unsigned char *posYA = (unsigned char*) (bitmap.getBits() + offsety);
00056 unsigned char *posYB = (unsigned char*) (bitmap.getBits() + offsety2);
00057
00058 fixed hx = fixed(0);
00059 for (int bx=0; bx<=hmap.getMapWidth(); bx++, hx+=dhx)
00060 {
00061 int ihx = hx.floor().asInt();
00062 int ihx2 = ihx + 1; if (ihx2 >= bw) --ihx2;
00063
00064 unsigned char *posXA1 = posYA + ihx * 3;
00065 unsigned char *posXA2 = posYA + ihx2 * 3;
00066 unsigned char *posXB1 = posYB + ihx * 3;
00067 unsigned char *posXB2 = posYB + ihx2 * 3;
00068
00069 fixed heightXA1 = fixed(posXA1[0]);
00070 fixed heightXA2 = fixed(posXA2[0]);
00071 fixed heightXB1 = fixed(posXB1[0]);
00072 fixed heightXB2 = fixed(posXB2[0]);
00073
00074 fixed XA = ((heightXA2 - heightXA1) * (hx - fixed(ihx))) + heightXA1;
00075 fixed XB = ((heightXB2 - heightXB1) * (hx - fixed(ihx))) + heightXB1;
00076
00077 fixed h = ((XB - XA) * (hy - fixed(ihy))) + XA;
00078
00079 hmap.setHeight(bx, by, h / scale);
00080 }
00081 }
00082
00083 if (levelSurround) HeightMapModifier::levelSurround(hmap);
00084 }
00085
00086 bool HeightMapLoader::generateTerrain(
00087 unsigned int seed,
00088 LandscapeDefnType *defn,
00089 HeightMap &hmap,
00090 bool &levelSurround,
00091 ProgressCounter *counter)
00092 {
00093
00094 if (defn->getType() == LandscapeDefnType::eHeightMapFile)
00095 {
00096 LandscapeDefnHeightMapFile *file =
00097 (LandscapeDefnHeightMapFile *) defn;
00098
00099
00100 levelSurround = file->levelsurround;
00101
00102 std::string fileName = S3D::getDataFile(file->file.c_str());
00103 ImageHandle image = ImageFactory::loadImageHandle(fileName);
00104 if (!image.getBits())
00105 {
00106 S3D::dialogMessage("HeightMapLoader", S3D::formatStringBuffer(
00107 "Error: Unable to find landscape map \"%s\"",
00108 fileName.c_str()));
00109 return false;
00110 }
00111 else
00112 {
00113 HeightMapLoader::loadTerrain(
00114 hmap,
00115 image,
00116 file->levelsurround,
00117 counter);
00118 }
00119 }
00120 else if (defn->getType() == LandscapeDefnType::eHeightMapGenerate)
00121 {
00122 LandscapeDefnHeightMapGenerate *generate =
00123 (LandscapeDefnHeightMapGenerate *) defn;
00124
00125
00126 levelSurround = generate->levelsurround;
00127 RandomGenerator generator;
00128 RandomGenerator offsetGenerator;
00129 generator.seed(seed);
00130 offsetGenerator.seed(seed);
00131
00132 HeightMapModifier::generateTerrain(
00133 hmap,
00134 *generate,
00135 generator,
00136 offsetGenerator,
00137 counter);
00138 }
00139 else
00140 {
00141 S3D::dialogMessage("HeightMapLoader", S3D::formatStringBuffer(
00142 "Error: Unkown generate type %i",
00143 defn->getType()));
00144 return false;
00145 }
00146
00147
00148 if (counter) counter->setNewOp(LANG_RESOURCE("SETTINGS_NORMALS", "Setting Normals"));
00149 for (int y=0; y<hmap.getMapHeight(); y++)
00150 {
00151 if (counter) counter->setNewPercentage((100.0f * float(y)) / float(hmap.getMapHeight()));
00152
00153 for (int x=0; x<hmap.getMapWidth(); x++)
00154 {
00155 hmap.getNormal(x, y);
00156 }
00157 }
00158
00159 return true;
00160 }