00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <placement/PlacementTypeMask.h>
00022 #include <landscapemap/LandscapeMaps.h>
00023 #include <engine/ScorchedContext.h>
00024 #include <common/ProgressCounter.h>
00025 #include <common/RandomGenerator.h>
00026 #include <common/Defines.h>
00027 #include <image/ImageFactory.h>
00028 #include <XML/XMLParser.h>
00029
00030 PlacementTypeMask::PlacementTypeMask()
00031 {
00032 }
00033
00034 PlacementTypeMask::~PlacementTypeMask()
00035 {
00036 }
00037
00038 bool PlacementTypeMask::readXML(XMLNode *node)
00039 {
00040 if (!node->getNamedChild("numobjects", numobjects)) return false;
00041 if (!node->getNamedChild("mask", mask)) return false;
00042 if (!node->getNamedChild("minheight", minheight)) return false;
00043 if (!node->getNamedChild("maxheight", maxheight)) return false;
00044 if (!node->getNamedChild("mincloseness", mincloseness)) return false;
00045 if (!node->getNamedChild("minslope", minslope)) return false;
00046 if (!node->getNamedChild("xsnap", xsnap)) return false;
00047 if (!node->getNamedChild("ysnap", ysnap)) return false;
00048 return PlacementType::readXML(node);
00049 }
00050
00051 void PlacementTypeMask::getPositions(ScorchedContext &context,
00052 RandomGenerator &generator,
00053 std::list<Position> &returnPositions,
00054 ProgressCounter *counter)
00055 {
00056 int groundMapWidth = context.getLandscapeMaps().getGroundMaps().getLandscapeWidth();
00057 int groundMapHeight = context.getLandscapeMaps().getGroundMaps().getLandscapeHeight();
00058
00059 ImageHandle map = ImageFactory::loadImageHandle(S3D::getDataFile(mask.c_str()));
00060 if (!map.getBits())
00061 {
00062 S3D::dialogExit("PlacementTypeMask",
00063 S3D::formatStringBuffer("Error: failed to find mask \"%s\"",
00064 mask.c_str()));
00065 }
00066
00067 const int NoIterations = numobjects;
00068 int objectCount = 0;
00069 for (int i=0; i<NoIterations; i++)
00070 {
00071 if (i % 1000 == 0) if (counter)
00072 counter->setNewPercentage(float(i)/float(NoIterations)*100.0f);
00073
00074 fixed lx = generator.getRandFixed() * fixed(groundMapWidth);
00075 fixed ly = generator.getRandFixed() * fixed(groundMapHeight);
00076
00077 if (xsnap > 0)
00078 {
00079 lx = fixed((lx / xsnap).asInt()) * xsnap;
00080 }
00081 if (ysnap > 0)
00082 {
00083 ly = fixed((ly / ysnap).asInt()) * ysnap;
00084 }
00085 lx = MIN(MAX(fixed(0), lx), fixed(groundMapWidth));
00086 ly = MIN(MAX(fixed(0), ly), fixed(groundMapHeight));
00087
00088 fixed height =
00089 context.getLandscapeMaps().getGroundMaps().getInterpHeight(lx, ly);
00090 FixedVector normal;
00091 context.getLandscapeMaps().
00092 getGroundMaps().getInterpNormal(lx, ly, normal);
00093 if (height > minheight &&
00094 height < maxheight &&
00095 normal[2] > minslope)
00096 {
00097 int mx = (map.getWidth() * lx.asInt()) / groundMapWidth;
00098 int my = (map.getHeight() * ly.asInt()) / groundMapHeight;
00099 unsigned char *bits = map.getBits() +
00100 mx * 3 + my * map.getWidth() * 3;
00101 if (bits[0] > 127)
00102 {
00103 Position position;
00104 position.position[0] = lx;
00105 position.position[1] = ly;
00106 position.position[2] = height;
00107
00108 if (checkCloseness(position.position, context,
00109 returnPositions, mincloseness))
00110 {
00111 returnPositions.push_back(position);
00112 }
00113 }
00114 }
00115 }
00116 }