Rigs of Rods 2023.09
Soft-body Physics Simulation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
Landusemap.cpp
Go to the documentation of this file.
1/*
2 This source file is part of Rigs of Rods
3 Copyright 2005-2012 Pierre-Michel Ricordel
4 Copyright 2007-2012 Thomas Fischer
5
6 For more information, see http://www.rigsofrods.org/
7
8 Rigs of Rods is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License version 3, as
10 published by the Free Software Foundation.
11
12 Rigs of Rods is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
19*/
20
21#include "Landusemap.h"
22
23#include "Actor.h"
24#include "Application.h"
25#include "Collisions.h"
26#include "Console.h"
27#include "ErrorUtils.h"
28#include "GameContext.h"
29#include "Language.h"
30#include "Terrain.h"
31#ifdef USE_PAGED
32#include "PropertyMaps.h"
33#include "PagedGeometry.h"
34#endif
35#include <OgreConfigFile.h>
36
37using namespace Ogre;
38using namespace RoR;
39
40Landusemap::Landusemap(String configFilename) :
41 data(0)
42 , default_ground_model(nullptr)
43 , mapsize(App::GetGameContext()->GetTerrain()->getMaxTerrainSize())
44{
45 loadConfig(configFilename);
46#ifndef USE_PAGED
47 LOG("RoR was not compiled with PagedGeometry support. You cannot use Landuse maps with it.");
48#endif //USE_PAGED
49}
50
52{
53 if (data != nullptr)
54 delete[] data;
55}
56
58{
59 if (!data)
60 return nullptr;
61#ifdef USE_PAGED
62 // we return the default ground model if we are not anymore in this map
63 if (x < 0 || x >= mapsize.x || z < 0 || z >= mapsize.z)
65
66 return data[x + z * (int)mapsize.x];
67#else
68 return nullptr;
69#endif // USE_PAGED
70}
71
72int Landusemap::loadConfig(const Ogre::String& filename)
73{
74 std::map<unsigned int, String> usemap;
75 String textureFilename = "";
76
77 LOG("Parsing landuse config: '"+filename+"'");
78
79 String group = "";
80 try
81 {
82 group = ResourceGroupManager::getSingleton().findGroupContainingResource(filename);
83 }
84 catch (...)
85 {
86 // we wont catch anything, since the path could be absolute as well, then the group is not found
87 }
88
89 Ogre::ConfigFile cfg;
90 try
91 {
92 // try to load directly otherwise via resource group
93 if (group == "")
94 cfg.loadDirect(filename);
95 else
96 cfg.loadFromResourceSystem(filename, group, "\x09:=", true);
97 }
98 catch (Ogre::Exception& e) // Already logged by OGRE
99 {
101 fmt::format("{}: {}", _L("Error while loading landuse config"), e.getDescription()));
102 return 1;
103 }
104
105 Ogre::ConfigFile::SectionIterator seci = cfg.getSectionIterator();
106 Ogre::String secName, kname, kvalue;
107 while (seci.hasMoreElements())
108 {
109 secName = seci.peekNextKey();
110 Ogre::ConfigFile::SettingsMultiMap* settings = seci.getNext();
111 Ogre::ConfigFile::SettingsMultiMap::iterator i;
112 for (i = settings->begin(); i != settings->end(); ++i)
113 {
114 kname = i->first;
115 kvalue = i->second;
116 // we got all the data available now, processing now
117 if (secName == "general" || secName == "config")
118 {
119 // set some class properties accoring to the information in this section
120 if (kname == "texture")
121 textureFilename = kvalue;
122 else if (kname == "frictionconfig" || kname == "loadGroundModelsConfig")
124 else if (kname == "defaultuse")
126 }
127 else if (secName == "use-map")
128 {
129 if (kname.size() != 10)
130 {
131 LOG("invalid color in landuse line in " + filename);
132 continue;
133 }
134 char* ptr; //not used
135 unsigned int color = strtoul(kname.c_str(), &ptr, 16);
136 usemap[color] = kvalue;
137 }
138 }
139 }
140#ifdef USE_PAGED
141 // process the config data and load the buffers finally
142 try
143 {
144 Forests::ColorMap* colourMap = Forests::ColorMap::load(textureFilename, Forests::CHANNEL_COLOR);
145 colourMap->setFilter(Forests::MAPFILTER_NONE);
146
147 /*
148 // debug things below
149 printf("found ground use definitions:\n");
150 for (std::map < uint32, String >::iterator it=usemap.begin(); it!=usemap.end(); it++)
151 {
152 printf(" 0x%Lx : %s\n", it->first, it->second.c_str());
153 }
154 */
155
156 bool bgr = colourMap->getPixelBox().format == PF_A8B8G8R8;
157
158 Ogre::TRect<Ogre::Real> bounds = Forests::TBounds(0, 0, mapsize.x, mapsize.z);
159
160 // now allocate the data buffer to hold pointers to ground models
161 data = new ground_model_t*[(int)(mapsize.x * mapsize.z)];
162 ground_model_t** ptr = data;
163 //std::map < String, int > counters;
164 for (int z = 0; z < mapsize.z; z++)
165 {
166 for (int x = 0; x < mapsize.x; x++)
167 {
168 unsigned int col = colourMap->getColorAt(x, z, bounds);
169 if (bgr)
170 {
171 // Swap red and blue values
172 unsigned int cols = col & 0xFF00FF00;
173 cols |= (col & 0xFF) << 16;
174 cols |= (col & 0xFF0000) >> 16;
175 col = cols;
176 }
177 String use = usemap[col];
178 //if (use!="")
179 // counters[use]++;
180
181 // store the pointer to the ground model in the data slot
183 ptr++;
184 }
185 }
186 }
187 catch (Ogre::Exception& oex)
188 {
189 LogFormat("[RoR|Physics] Landuse: failed to load texture '%s', <Ogre::Exception> message: '%s'",
190 textureFilename.c_str(), oex.getFullDescription().c_str());
191 }
192 catch (std::exception& stex)
193 {
194 LogFormat("[RoR|Physics] Landuse: failed to load texture '%s', <std::exception> message: '%s'",
195 textureFilename.c_str(), stex.what());
196 }
197 catch (...)
198 {
199 LogFormat("[RoR|Physics] Landuse: failed to load texture '%s', unknown error", textureFilename.c_str());
200 }
201#endif // USE_PAGED
202 return 0;
203}
Central state/object manager and communications hub.
void LOG(const char *msg)
Legacy alias - formerly a macro.
#define _L
Game state manager and message-queue provider.
int loadGroundModelsConfigFile(Ogre::String filename)
ground_model_t * getGroundModelByString(const Ogre::String name)
@ CONSOLE_MSGTYPE_TERRN
Parsing/spawn/simulation messages for terrain.
Definition Console.h:64
void putMessage(MessageArea area, MessageType type, std::string const &msg, std::string icon="")
Definition Console.cpp:103
@ CONSOLE_SYSTEM_ERROR
Definition Console.h:52
const TerrainPtr & GetTerrain()
ground_model_t ** data
Definition Landusemap.h:45
ground_model_t * default_ground_model
Definition Landusemap.h:46
Landusemap(Ogre::String cfgfilename)
Ogre::Vector3 mapsize
Definition Landusemap.h:48
ground_model_t * getGroundModelAt(int x, int z)
int loadConfig(const Ogre::String &filename)
Collisions * GetCollisions()
Definition Terrain.h:86
GameContext * GetGameContext()
Console * GetConsole()
void LogFormat(const char *format,...)
Improved logging utility. Uses fixed 2Kb buffer.
Surface friction properties.
Definition SimData.h:704