8 #include <argos3/core/simulator/simulator.h>
9 #include <argos3/core/simulator/space/space.h>
10 #include <argos3/core/simulator/loop_functions.h>
12 #ifdef ARGOS_WITH_FREEIMAGE
13 #include <FreeImagePlus.h>
21 #ifdef ARGOS_WITH_FREEIMAGE
22 class CFloorColorFromImageFile :
public CFloorEntity::CFloorColorSource {
26 CFloorColorFromImageFile(
const std::string& str_path) {
29 cArenaSize.GetX() * 0.5f,
30 cArenaSize.GetY() * 0.5f);
32 m_cArenaCenter.
Set(cArenaCenter.GetX(),
37 virtual void Reset() {
38 LoadImage(m_strImageFileName);
41 virtual CColor GetColorAtPoint(
Real f_x,
44 UInt32 x = (f_x + m_cHalfArenaSize.GetX()) * m_fArenaToImageCoordinateXFactor;
45 UInt32 y = (f_y + m_cHalfArenaSize.GetY()) * m_fArenaToImageCoordinateYFactor;
47 if(m_cImage.getBitsPerPixel() <= 8) {
48 RGBQUAD* ptColorPalette;
51 if(! m_cImage.getPixelIndex(x, y, &tPixelIndex)) {
53 "). Image size (" << m_cImage.getWidth() <<
"," <<
54 m_cImage.getHeight() <<
")");
56 ptColorPalette = m_cImage.getPalette();
57 return CColor(ptColorPalette[tPixelIndex].rgbRed,
58 ptColorPalette[tPixelIndex].rgbGreen,
59 ptColorPalette[tPixelIndex].rgbBlue);
64 if(! m_cImage.getPixelColor(x, y, &tColorPixel)) {
66 "). Image size (" << m_cImage.getWidth() <<
"," <<
67 m_cImage.getHeight() <<
")");
69 return CColor(tColorPixel.rgbRed,
75 virtual void SaveAsImage(
const std::string& str_path) {
76 m_strImageFileName = str_path;
77 m_cImage.save(str_path.c_str());
80 virtual const std::string& GetImageFileName()
const {
81 return m_strImageFileName;
86 void LoadImage(
const std::string& str_path) {
87 m_strImageFileName = str_path;
88 if(!m_cImage.load(m_strImageFileName.c_str())) {
94 m_fArenaToImageCoordinateXFactor = m_cImage.getWidth() / cArenaSize.
GetX();
95 m_fArenaToImageCoordinateYFactor = m_cImage.getHeight() / cArenaSize.GetY();
101 Real m_fArenaToImageCoordinateXFactor;
102 Real m_fArenaToImageCoordinateYFactor;
103 CVector2 m_cHalfArenaSize;
104 CVector2 m_cArenaCenter;
105 std::string m_strImageFileName;
118 m_cLoopFunctions(
CSimulator::GetInstance().GetLoopFunctions()),
119 m_unPixelsPerMeter(un_pixels_per_meter) {
121 m_cHalfArenaSize.
Set(
122 cArenaSize.
GetX() * 0.5f,
123 cArenaSize.
GetY() * 0.5f);
125 m_cArenaCenter.
Set(cArenaCenter.
GetX(),
126 cArenaCenter.
GetY());
134 #ifdef ARGOS_WITH_FREEIMAGE
135 virtual void SaveAsImage(
const std::string& str_path) {
136 fipImage cImage(FIT_BITMAP, m_unPixelsPerMeter * m_cHalfArenaSize.
GetX()*2, m_unPixelsPerMeter * m_cHalfArenaSize.
GetY()*2, 24);
137 Real fFactor = 1.0f /
static_cast<Real>(m_unPixelsPerMeter);
141 for(
UInt32 y = 0; y < cImage.getHeight(); ++y) {
142 for(
UInt32 x = 0; x < cImage.getWidth(); ++x) {
143 cFloorPos.
Set(x * fFactor, y * fFactor);
144 cFloorPos -= m_cHalfArenaSize;
145 cFloorPos += m_cArenaCenter;
147 tFIPPixel.rgbRed = cARGoSPixel.
GetRed();
148 tFIPPixel.rgbGreen = cARGoSPixel.
GetGreen();
149 tFIPPixel.rgbBlue = cARGoSPixel.
GetBlue();
150 cImage.setPixelColor(x, y, &tFIPPixel);
153 if(!cImage.save(str_path.c_str())) {
161 CLoopFunctions& m_cLoopFunctions;
162 UInt32 m_unPixelsPerMeter;
163 CVector2 m_cHalfArenaSize;
164 CVector2 m_cArenaCenter;
172 m_eColorSource(UNSET),
173 m_pcColorSource(NULL),
174 m_bHasChanged(true) {}
179 #ifdef ARGOS_WITH_FREEIMAGE
181 const std::string& str_file_name) :
183 m_eColorSource(FROM_IMAGE),
184 m_pcColorSource(NULL),
185 m_bHasChanged(true) {
186 std::string strFileName = str_file_name;
188 m_pcColorSource =
new CFloorColorFromImageFile(strFileName);
196 UInt32 un_pixels_per_meter) :
198 m_eColorSource(FROM_LOOP_FUNCTIONS),
200 m_bHasChanged(true) {}
206 if(m_pcColorSource != NULL) {
207 delete m_pcColorSource;
218 std::string strColorSource;
220 if(strColorSource ==
"loop_functions") {
226 else if(strColorSource ==
"image") {
227 #ifdef ARGOS_WITH_FREEIMAGE
232 m_pcColorSource =
new CFloorColorFromImageFile(strPath);
234 THROW_ARGOSEXCEPTION(
"ARGoS was compiled without FreeImage, this image source is unsupported for the floor entity \"" <<
242 "\" for the floor entity \"" <<
252 m_pcColorSource->
Reset();
258 #ifdef ARGOS_WITH_FREEIMAGE
259 void CFloorEntity::SaveAsImage(
const std::string& str_path) {
260 m_pcColorSource->SaveAsImage(str_path);
269 "Carlo Pinciroli [ilpincy@gmail.com]",
271 "It contains the properties of the arena floor.",
272 "The floor entity contains the properties of the arena floor. In the current\n"
273 "implementation, it contains only the color of the floor. The floor color is\n"
274 "detected by the robots' ground sensors.\n\n"
275 "REQUIRED XML CONFIGURATION\n\n"
278 " <floor id=\"floor\"\n"
279 " source=\"SOURCE\" />\n"
282 "The 'id' attribute is necessary and must be unique among the entities. If two\n"
283 "entities share the same id, initialization aborts.\n"
284 "The 'source' attribute specifies where to get the color of the floor from. Its\n"
285 "value, here denoted as SOURCE, can assume the following values:\n\n"
286 " image The color is calculated from the passed image file\n"
287 " loop_functions The color is calculated calling the loop functions\n\n"
288 "When 'source' is set to 'image', as showed in the following example, you have\n"
289 "to specify the image path in the additional attribute 'path':\n\n"
292 " <floor id=\"floor\"\n"
293 " source=\"image\"\n"
294 " path=\"/path/to/imagefile.ext\" />\n"
297 "Many image formats are available, such as PNG, JPG, BMP, GIF and many more.\n"
298 "Refer to the FreeImage webpage for a complete list of supported image formats\n"
299 "(http://freeimage.sourceforge.net/features.html).\n\n"
300 "When 'source' is set to 'loop_functions', as showed in the following example,\n"
301 "an image is implicitly created to be used as texture for graphical\n"
302 "visualizations. The algorithm that creates the texture needs to convert from\n"
303 "meters (in the arena) to pixels (of the texture). You control how many pixels\n"
304 "per meter are used with the attribute 'pixels_per_meter'. Clearly, the higher\n"
305 "value, the higher the quality, but also the slower the algorithm and the bigger\n"
306 "the texture. The algorithm is called only once at init time, so the fact that\n"
307 "it is slow is not so important. However, the image size is limited by OpenGL.\n"
308 "Every implementation has its own limit, and you should check yours if any\n"
309 "texture-related problem arises. Now for the example:\n\n"
312 " <floor id=\"floor\"\n"
313 " source=\"loop_functions\"\n"
314 " pixels_per_meter=\"100\" />\n"
317 "OPTIONAL XML CONFIGURATION\n\n"
318 "None for the time being.\n",
334 CSpaceOperationAddCFloorEntity,