RigsofRods
Soft-body Physics Simulation
OTCFileFormat.cpp
Go to the documentation of this file.
1 /*
2  This source file is part of Rigs of Rods
3  Copyright 2016-2020 Petr Ohlidal
4 
5  For more information, see http://www.rigsofrods.org/
6 
7  Rigs of Rods is free software: you can redistribute it and/or modify
8  it under the terms of the GNU General Public License version 3, as
9  published by the Free Software Foundation.
10 
11  Rigs of Rods is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
22 
23 #include "OTCFileFormat.h"
24 
25 #include "Application.h"
26 #include "Console.h"
27 #include "SimConstants.h"
28 #include "ConfigFile.h"
29 #include "Utils.h"
30 
31 #include <algorithm>
32 #include <OgreException.h>
33 
35  m_def(std::make_shared<RoR::OTCFile>())
36 {
37 }
38 
39 bool RoR::OTCParser::LoadMasterConfig(Ogre::DataStreamPtr &ds, const char* filename)
40 {
41  std::string file_basename, file_ext;
42  Ogre::StringUtil::splitBaseFilename(filename, file_basename, file_ext);
43  RoR::ConfigFile cfg;
44  try
45  {
46  cfg.load(ds, "\t:=", false);
48 
49  m_def->disable_cache = cfg.getBool ("disableCaching", false);
50  m_def->world_size_x = cfg.getInt ("WorldSizeX", 1024);
51  m_def->world_size_y = cfg.getInt ("WorldSizeY", 50);
52  m_def->world_size_z = cfg.getInt ("WorldSizeZ", 1024);
53  m_def->page_size = cfg.getInt ("PageSize", 1025);
54  m_def->pages_max_x = cfg.getInt ("PagesX", 0);
55  m_def->pages_max_z = cfg.getInt ("PagesZ", 0);
56  m_def->page_filename_format = cfg.getString("PageFileFormat", /*section:*/Ogre::BLANKSTRING, /*defaultValue:*/file_basename + "-page-{X}-{Z}.otc");
57  m_def->is_flat = cfg.getBool ("Flat", false);
58  m_def->max_pixel_error = cfg.getInt ("MaxPixelError", 5);
59  m_def->batch_size_min = cfg.getInt ("minBatchSize", 33);
60  m_def->batch_size_max = cfg.getInt ("maxBatchSize", 65);
61  m_def->lightmap_enabled = cfg.getBool ("LightmapEnabled", false);
62  m_def->norm_map_enabled = cfg.getBool ("NormalMappingEnabled", false);
63  m_def->spec_map_enabled = cfg.getBool ("SpecularMappingEnabled", false);
64  m_def->parallax_enabled = cfg.getBool ("ParallaxMappingEnabled", false);
65  m_def->blendmap_dbg_enabled = cfg.getBool ("DebugBlendMaps", false);
66  m_def->global_colormap_enabled = cfg.getBool ("GlobalColourMapEnabled", false);
67  m_def->recv_dyn_shadows_depth = cfg.getBool ("ReceiveDynamicShadowsDepth", false);
68  m_def->composite_map_distance = cfg.getInt ("CompositeMapDistance", 4000);
69  m_def->layer_blendmap_size = cfg.getInt ("LayerBlendMapSize", 1024);
70  m_def->composite_map_size = cfg.getInt ("CompositeMapSize", 1024);
71  m_def->lightmap_size = cfg.getInt ("LightMapSize", 1024);
72  m_def->skirt_size = cfg.getInt ("SkirtSize", 30);
73 
74  m_def->world_size = std::max(m_def->world_size_x, m_def->world_size_z);
75  m_def->origin_pos = Ogre::Vector3(m_def->world_size_x / 2.0f, 0.0f, m_def->world_size_z / 2.0f);
76  m_def->cache_filename_base = file_basename;
77 
78  for (int x = 0; x <= m_def->pages_max_x; ++x)
79  {
80  for (int z = 0; z <= m_def->pages_max_z; ++z)
81  {
82  std::string filename = m_def->page_filename_format;
83  filename = Ogre::StringUtil::replaceAll(filename, "{X}", TOSTRING(x));
84  filename = Ogre::StringUtil::replaceAll(filename, "{Z}", TOSTRING(z));
85 
86  char base[50], key[75];
87  snprintf(base, 50, "Heightmap.%d.%d", x, z);
88 
89  snprintf(key, 75, "%s.raw.size", base); int raw_size = cfg.getInt(key, 1025);
90  snprintf(key, 75, "%s.raw.bpp", base); int raw_bpp = cfg.getInt(key, 2);
91  snprintf(key, 75, "%s.flipX", base); bool flip_x = cfg.getBool(key, false);
92  snprintf(key, 75, "%s.flipY", base); bool flip_y = cfg.getBool(key, false);
93 
94  m_def->pages.emplace_back(x, z, filename, flip_x, flip_y, raw_size, raw_bpp);
95  }
96  }
97  }
98  catch (...)
99  {
100  RoR::HandleGenericException(fmt::format("OTCParser::LoadMasterConfig({})", filename));
101  return false;
102  }
103  return true;
104 }
105 
106 bool RoR::OTCParser::LoadPageConfig(Ogre::DataStreamPtr &ds, RoR::OTCPage& page, const char* filename)
107 {
108  try
109  {
110  // NOTE: ds->getLine() trims the string on both sides.
111  page.heightmap_filename = SanitizeUtf8String(ds->getLine());
112 
113  page.num_layers = PARSEINT(ds->getLine());
114 
115  while (!ds->eof())
116  {
117  std::string line_sane = SanitizeUtf8String(ds->getLine());
118  if (line_sane.empty() || line_sane[0] == ';' || line_sane[0] == '/')
119  {
120  continue;
121  }
122 
123  Ogre::StringVector args = Ogre::StringUtil::split(line_sane, ",");
124  if (args.size() < 1)
125  {
126  LOG(std::string("[RoR|Terrain] Invalid OTC page config: [") + filename + "]");
127  return false;
128  }
129 
130  OTCLayer layer;
131  layer.world_size = PARSEREAL(args[0]);
132  if (args.size() > 1)
133  {
134  layer.diffusespecular_filename = TrimStr(args[1]);
135  }
136  if (args.size() > 2)
137  {
138  layer.normalheight_filename = TrimStr(args[2]);
139  }
140  if (args.size() > 3)
141  {
142  layer.blendmap_filename = TrimStr(args[3]);
143  }
144  if (args.size() > 4)
145  {
146  layer.blend_mode = TrimStr(args[4])[0];
147  }
148  if (args.size() > 5)
149  {
150  layer.alpha = PARSEREAL(args[5]);
151  }
152 
153  page.layers.push_back(layer);
154  }
155 
156  if (page.heightmap_filename.find(".raw") != std::string::npos)
157  {
158  page.is_heightmap_raw = true;
159  }
160 
161  int actual_num_layers = static_cast<int>(page.layers.size());
162  if (page.num_layers != actual_num_layers)
163  {
164  LogFormat("[RoR|Terrain] Warning: File \"%s\" declares %d layers but defines %d. Correcting declared layer count to %d",
165  filename, page.num_layers, actual_num_layers, actual_num_layers);
166  page.num_layers = actual_num_layers;
167  }
168  }
169  catch (...)
170  {
171  RoR::HandleGenericException(fmt::format("OTCParser::LoadPageConfig({})", filename));
172  return false;
173  }
174  return true;
175 }
176 
178  world_size_x(0), world_size_y(0), world_size_z(0), world_size(0),
179  page_size(0), pages_max_x(0), pages_max_z(0),
180  origin_pos(Ogre::Vector3::ZERO),
181  batch_size_min(0), batch_size_max(0),
182  layer_blendmap_size(0), max_pixel_error(0), composite_map_size(0), composite_map_distance(0),
183  skirt_size(0), lightmap_size(0),
184  lightmap_enabled(false), norm_map_enabled(false), spec_map_enabled(false), parallax_enabled(false),
185  global_colormap_enabled(false), recv_dyn_shadows_depth(false), disable_cache(false), is_flat(true)
186 {
187 }
188 
189 RoR::OTCPage::OTCPage(int x_pos, int z_pos, std::string const & conf_filename, bool flipX, bool flipY, int rawsize, int rawbpp):
190  pageconf_filename(conf_filename),
191  pos_x(x_pos), pos_z(z_pos),
192  is_heightmap_raw(false), raw_flip_x(flipX), raw_flip_y(flipY),
193  raw_size(rawsize), raw_bpp(rawbpp),
194  num_layers(0)
195 {}
196 
198  blend_mode('R'),
199  alpha(static_cast<float>('R')) // Backwards compatibility, probably old typo
200 {
201 }
RoR::OTCLayer::world_size
float world_size
Definition: OTCFileFormat.h:44
RoR::ConfigFile::getInt
int getInt(Ogre::String const &key, int defaultValue=0)
Definition: ConfigFile.h:64
RoR::OTCLayer::diffusespecular_filename
std::string diffusespecular_filename
Definition: OTCFileFormat.h:40
PARSEREAL
#define PARSEREAL(x)
Definition: Application.h:58
RoR::Console::CONSOLE_MSGTYPE_TERRN
@ CONSOLE_MSGTYPE_TERRN
Parsing/spawn/simulation messages for terrain.
Definition: Console.h:64
RoR::OTCLayer
Definition: OTCFileFormat.h:35
OTCFileFormat.h
z
float z
Definition: (ValueTypes) quaternion.h:7
format
Truck file format(technical spec)
RoR::OTCPage::num_layers
int num_layers
Definition: OTCFileFormat.h:53
RoR::HandleGenericException
void HandleGenericException(const std::string &from, BitMask_t flags)
Definition: Application.cpp:369
RoR::SanitizeUtf8String
std::string SanitizeUtf8String(std::string const &str_in)
Definition: Utils.cpp:117
SimConstants.h
RoR::LogFormat
void LogFormat(const char *format,...)
Improved logging utility. Uses fixed 2Kb buffer.
Definition: Application.cpp:424
RoR::OTCPage::heightmap_filename
std::string heightmap_filename
Definition: OTCFileFormat.h:52
Console.h
RoR::OTCLayer::blendmap_filename
std::string blendmap_filename
Definition: OTCFileFormat.h:39
RoR::ConfigFile::getString
Ogre::String getString(Ogre::String const &key, Ogre::String const &section, Ogre::String const &defaultValue="")
Definition: ConfigFile.cpp:89
RoR::OTCLayer::OTCLayer
OTCLayer()
Definition: OTCFileFormat.cpp:197
Utils.h
RoR::OTCLayer::alpha
float alpha
Definition: OTCFileFormat.h:43
RoR::TrimStr
std::string & TrimStr(std::string &s)
Definition: Utils.h:67
RoR::OTCLayer::blend_mode
char blend_mode
Definition: OTCFileFormat.h:42
RoR::OTCPage::OTCPage
OTCPage(int pos_x, int pos_z, std::string const &conf_filename, bool flipX, bool flipY, int rawsize, int rawbpp)
Definition: OTCFileFormat.cpp:189
TOSTRING
#define TOSTRING(x)
Definition: Application.h:56
PARSEINT
#define PARSEINT(x)
Definition: Application.h:57
RoR::ConfigFile::getBool
bool getBool(Ogre::String const &key, bool defaultValue=false)
Definition: ConfigFile.h:57
RoR::OTCParser::LoadPageConfig
bool LoadPageConfig(Ogre::DataStreamPtr &ds, OTCPage &page, const char *filename)
Definition: OTCFileFormat.cpp:106
RoR::OTCPage
Definition: OTCFileFormat.h:47
Application.h
Central state/object manager and communications hub.
RoR::OTCLayer::normalheight_filename
std::string normalheight_filename
Definition: OTCFileFormat.h:41
RoR::OTCPage::is_heightmap_raw
bool is_heightmap_raw
Definition: OTCFileFormat.h:55
RoR::OTCFile::OTCFile
OTCFile()
Definition: OTCFileFormat.cpp:177
RoR::OTCParser::LoadMasterConfig
bool LoadMasterConfig(Ogre::DataStreamPtr &ds, const char *filename)
Definition: OTCFileFormat.cpp:39
RoR::OTCParser::OTCParser
OTCParser()
Definition: OTCFileFormat.cpp:34
Ogre
Definition: ExtinguishableFireAffector.cpp:35
RoR::ConfigFile
Adds direct parsing of custom types.
Definition: ConfigFile.h:37
RoR::OTCFile
Rembember OGRE coordinates are {X = right/left, Y = up/down, Z = front/back}.
Definition: OTCFileFormat.h:62
ConfigFile.h
RoR::OTCPage::layers
std::list< OTCLayer > layers
Definition: OTCFileFormat.h:58
RoR
Definition: AppContext.h:36
x
float x
Definition: (ValueTypes) quaternion.h:5
RoR::ConfigFile::setLoggingInfo
void setLoggingInfo(std::string const &filename, Console::MessageArea area)
Definition: ConfigFile.h:77