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
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::OTCDocument>())
36{
37}
38
39bool 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);
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
106bool 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
189RoR::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}
Central state/object manager and communications hub.
#define PARSEINT(x)
Definition Application.h:58
#define PARSEREAL(x)
Definition Application.h:59
#define TOSTRING(x)
Definition Application.h:57
void LOG(const char *msg)
Legacy alias - formerly a macro.
Adds direct parsing of custom types.
Definition ConfigFile.h:38
bool getBool(Ogre::String const &key, bool defaultValue=false)
Definition ConfigFile.h:57
Ogre::String getString(Ogre::String const &key, Ogre::String const &section, Ogre::String const &defaultValue="")
int getInt(Ogre::String const &key, int defaultValue=0)
Definition ConfigFile.h:64
void setLoggingInfo(std::string const &filename, Console::MessageArea area)
Definition ConfigFile.h:78
@ CONSOLE_MSGTYPE_TERRN
Parsing/spawn/simulation messages for terrain.
Definition Console.h:64
bool LoadMasterConfig(Ogre::DataStreamPtr &ds, const char *filename)
bool LoadPageConfig(Ogre::DataStreamPtr &ds, OTCPage &page, const char *filename)
void HandleGenericException(const std::string &from, BitMask_t flags)
void LogFormat(const char *format,...)
Improved logging utility. Uses fixed 2Kb buffer.
std::string & TrimStr(std::string &s)
Definition Utils.h:68
std::string SanitizeUtf8String(std::string const &str_in)
Definition Utils.cpp:120
Rembember OGRE coordinates are {X = right/left, Y = up/down, Z = front/back}.
std::string normalheight_filename
std::string diffusespecular_filename
std::string blendmap_filename
OTCPage(int pos_x, int pos_z, std::string const &conf_filename, bool flipX, bool flipY, int rawsize, int rawbpp)
std::list< OTCLayer > layers
bool is_heightmap_raw
std::string heightmap_filename