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
Terrn2FileFormat.cpp
Go to the documentation of this file.
1/*
2 This source file is part of Rigs of Rods
3 Copyright 2016-2017 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 "Terrn2FileFormat.h"
24
25#include "AppContext.h"
26#include "ConfigFile.h"
27#include "Console.h"
28#include "Utils.h"
29#include "SimConstants.h"
30
31#include <OgreException.h>
32
33using namespace RoR;
34using namespace Ogre;
35
36const std::string VALUE_NOT_FOUND("@@NotFound!!");
37
39{
40 RoR::ConfigFile file;
41 file.load(ds, "\t:=", true);
43
44 Terrn2DocumentPtr def = std::make_shared<Terrn2Document>();
45
46 // read in the settings
47 def->name = file.getString("Name", "General");
48 if (def->name.empty())
49 {
50 Str<500> msg; msg << "Error in file '" << ds->getName() << "': Terrain name is empty";
52 return nullptr;
53 }
54
55 def->ogre_ter_conf_filename = file.getString("GeometryConfig", "General");
56 // otc = ogre terrain config
57 if (!def->ogre_ter_conf_filename.empty() && def->ogre_ter_conf_filename.find(".otc") == String::npos)
58 {
59 Str<500> msg; msg << "Error in file '" << ds->getName() << "': Invalid geometry config file; only '.otc' is supported";
61 return nullptr;
62 }
63
64 def->ambient_color = file.getColourValue("AmbientColor", "General", ColourValue::White);
65 def->category_id = file.getInt ("CategoryID", "General", 129);
66 def->guid = file.getString ("GUID", "General");
67 def->version = file.getInt ("Version", "General", 1);
68 def->gravity = file.getFloat ("Gravity", "General", -9.81);
69 def->caelum_config = file.getString ("CaelumConfigFile", "General");
70 def->cubemap_config = file.getString ("SandStormCubeMap", "General");
71 def->caelum_fog_start = file.getInt ("CaelumFogStart", "General", -1);
72 def->caelum_fog_end = file.getInt ("CaelumFogEnd", "General", -1);
73 def->has_water = file.getBool ("Water", "General", false);
74 def->hydrax_conf_file = file.getString ("HydraxConfigFile", "General");
75 def->skyx_config = file.getString ("SkyXConfigFile", "General");
76 def->traction_map_file = file.getString ("TractionMap", "General");
77 def->water_height = file.getFloat ("WaterLine", "General");
78 def->water_bottom_height = file.getFloat ("WaterBottomLine", "General");
79 def->custom_material_name = file.getString ("CustomMaterial", "General");
80 def->start_position = file.getVector3 ("StartPosition", "General", Vector3(512.0f, 0.0f, 512.0f));
81
82 def->start_rotation_specified = file.HasSetting("General", "StartRotation");
83 def->start_rotation = Ogre::Degree(file.getFloat("StartRotation", "General"));
84
85 if (file.HasSection("Authors"))
86 {
87 for (auto& author: file.getSettings("Authors"))
88 {
89 String type = SanitizeUtf8String(author.first); // e.g. terrain
90 String name = SanitizeUtf8String(author.second); // e.g. john doe
91
92 if (!name.empty())
93 {
94 Terrn2Author author;
95 author.type = type;
96 author.name = name;
97 def->authors.push_back(author);
98 }
99 }
100 }
101
102 if (file.HasSection("Objects"))
103 {
104 for (auto& tobj: file.getSettings("Objects"))
105 {
106 Ogre::String tobj_filename = SanitizeUtf8String(tobj.first);
107 def->tobj_files.push_back(TrimStr(tobj_filename));
108 }
109 }
110
111 if (file.HasSection("Scripts"))
112 {
113 for (auto& script: file.getSettings("Scripts"))
114 {
115 Ogre::String as_filename = SanitizeUtf8String(script.first);
116 def->as_files.push_back(TrimStr(as_filename));
117 }
118 }
119
120 if (file.HasSection("AssetPacks"))
121 {
122 for (auto& assetpack: file.getSettings("AssetPacks"))
123 {
124 Ogre::String assetpack_filename = SanitizeUtf8String(assetpack.first);
125 def->assetpack_files.push_back(TrimStr(assetpack_filename));
126 }
127 }
128
129 if (file.HasSection("AI Presets"))
130 {
131 for (auto& presets: file.getSettings("AI Presets"))
132 {
133 Ogre::String presets_filename = SanitizeUtf8String(presets.first);
134 def->ai_presets_files.push_back(TrimStr(presets_filename));
135 }
136 }
137
138 this->ProcessTeleport(def, &file);
139
140 return def;
141}
142
144{
145 def->teleport_map_image = file->getString("NavigationMapImage", "Teleport");
146
147 unsigned int telepoint_number = 1;
148 for (;;)
149 {
150 char key_position [50];
151 char key_name [50];
152
153 snprintf(key_position, 50, "Telepoint%u/Position" , telepoint_number);
154 snprintf(key_name, 50, "Telepoint%u/Name" , telepoint_number);
155
156 std::string pos_str = file->getString(key_position, "Teleport", VALUE_NOT_FOUND);
157 if (pos_str == VALUE_NOT_FOUND)
158 {
159 break; // No more telepoints
160 }
161 Terrn2Telepoint t_point;
162 if (sscanf(pos_str.c_str(), "%f, %f, %f", &t_point.position.x, &t_point.position.y, &t_point.position.z) != 3)
163 {
164 char msg_buf[500];
165 snprintf(msg_buf, 500,
166 "ERROR: Field '[Teleport]/%s' ('%s') is not valid XYZ position. Skipping telepoint %u.",
167 key_position, pos_str.c_str(), telepoint_number);
170 }
171 else
172 {
173 t_point.name = file->getString(key_name, "Teleport"); // Optional field
174 def->telepoints.push_back(t_point); // Persist the entry
175 }
176
177 ++telepoint_number;
178 }
179}
System integration layer; inspired by OgreBites::ApplicationContext.
const std::string VALUE_NOT_FOUND("@@NotFound!!")
Adds direct parsing of custom types.
Definition ConfigFile.h:38
bool getBool(Ogre::String const &key, bool defaultValue=false)
Definition ConfigFile.h:57
float getFloat(Ogre::String const &key, float defaultValue=0.f)
Definition ConfigFile.h:50
bool HasSection(std::string const &name)
Ogre::String getString(Ogre::String const &key, Ogre::String const &section, Ogre::String const &defaultValue="")
Ogre::Vector3 getVector3(Ogre::String const &key, Ogre::String const &section, Ogre::Vector3 const &defaultValue=Ogre::Vector3::ZERO)
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
Ogre::ColourValue getColourValue(Ogre::String const &key, Ogre::ColourValue const &defaultValue=Ogre::ColourValue())
Definition ConfigFile.h:41
bool HasSetting(std::string const &section, std::string const &key)
@ 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
@ CONSOLE_SYSTEM_WARNING
Definition Console.h:53
Wrapper for classic c-string (local buffer) Refresher: strlen() excludes '\0' terminator; strncat() A...
Definition Str.h:36
const char * ToCStr() const
Definition Str.h:46
void ProcessTeleport(Terrn2DocumentPtr def, RoR::ConfigFile *file)
Terrn2DocumentPtr LoadTerrn2(Ogre::DataStreamPtr &ds)
Console * GetConsole()
std::shared_ptr< Terrn2Document > Terrn2DocumentPtr
std::string & TrimStr(std::string &s)
Definition Utils.h:68
std::string SanitizeUtf8String(std::string const &str_in)
Definition Utils.cpp:120
< Teleport drop location