RigsofRods
Soft-body Physics Simulation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
TObjFileFormat.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 
20 #include "TObjFileFormat.h"
21 
22 #include "Actor.h"
23 #include "ProceduralRoad.h"
24 
25 #define LOGSTREAM Ogre::LogManager::getSingleton().stream() << "[RoR|TObj fileformat] "
26 
27 using namespace RoR;
28 using namespace Ogre;
29 
30 // --------------------------------
31 // TObjEntry
32 
33 TObjEntry::TObjEntry(Ogre::Vector3 pos, Ogre::Vector3 rot, const char* odef, TObjSpecialObject spc, const char* ty, const char* nam):
34  position(pos),
35  rotation(rot),
36  special(spc)
37 {
38  strcpy(type, ty);
39  strcpy(instance_name, nam);
40  strcpy(odef_name, odef);
41 }
42 
43 bool TObjEntry::IsRoad() const
44 {
46 }
47 
48 bool TObjEntry::IsActor() const
49 {
53 }
54 
55 // --------------------------------
56 // Parser
57 
59 {
60  m_cur_line = nullptr;
61  m_line_number = 0;
62  m_in_procedural_road = false;
67  m_rot_yxz = false;
68 
70 }
71 
72 bool TObjParser::ProcessLine(const char* line)
73 {
74  bool result = true;
75  if ((line != nullptr) && (line[0] != 0))
76  {
77  bool is_comment = (line[0] == '/') || (line[0] == ';');
78  if (is_comment)
79  {
80  int text_start = 1;
81  while (line[text_start] == '/')
82  {
83  text_start++;
84  }
85  m_preceding_line_comments += std::string(line + text_start) + "\n";
86  }
87  else
88  {
89  m_cur_line = line; // No trimming by design.
90  m_cur_line_trimmed = line;
91  while (m_cur_line_trimmed[0] == ' ' || m_cur_line_trimmed[0] == '\t')
92  {
94  }
95  result = this->ProcessCurrentLine();
97  }
98  }
99  m_line_number++;
100  return result;
101 }
102 
103 // retval true = continue processing (false = stop)
105 {
106  // ** Process keywords
107 
108  if (!strcmp(m_cur_line, "end"))
109  {
110  return false;
111  }
112  if (strncmp(m_cur_line, "collision-tris", 14) == 0)
113  {
114  return true; // Obsolete - ignore it.
115  }
116  if (strncmp(m_cur_line, "grid", 4) == 0)
117  {
118  this->ProcessGridLine();
119  return true;
120  }
121  if (strncmp(m_cur_line, "trees", 5) == 0)
122  {
123  this->ProcessTreesLine();
124  return true;
125  }
126  if (strncmp(m_cur_line, "grass", 5) == 0)
127  {
128  this->ProcessGrassLine();
129  return true;
130  }
131  if (strncmp(m_cur_line, "set_default_rendering_distance", 30) == 0)
132  {
133  const int result = sscanf(m_cur_line, "set_default_rendering_distance %f", &m_default_rendering_distance);
134  if (result != 1)
135  {
136  LOG(fmt::format("too few parameters on line: '{}' ({}, line {})", m_cur_line, m_filename, m_line_number));
137  }
138  return true;
139  }
140  if (strncmp(m_cur_line, "rot_yxz", 7) == 0)
141  {
142  m_rot_yxz = true;
143  return true;
144  }
145  if (strncmp("begin_procedural_roads", m_cur_line, 22) == 0)
146  {
147  m_cur_procedural_obj = new ProceduralObject(); // Hard reset, discarding last "non-procedural" road strip. For backwards compatibility. ~ Petr Ohlidal, 08/2020
148  m_in_procedural_road = true;
150  return true;
151  }
152  if (strncmp("end_procedural_roads", m_cur_line, 20) == 0)
153  {
155  {
156  this->FlushProceduralObject();
157  }
158  m_in_procedural_road = false;
159  return true;
160  }
161  if (strncmp("smoothing_num_splits", m_cur_line_trimmed, 20) == 0)
162  {
164  {
165  int result = sscanf(m_cur_line_trimmed, "smoothing_num_splits %d", &m_cur_procedural_obj->smoothing_num_splits);
166  if (result != 1)
167  {
168  LOG(fmt::format("[RoR|TObj] not enough parameters at line '{}' ({}, line {})", m_cur_line, m_filename, m_line_number));
169  }
170  }
171  return true;
172  }
173  if (strncmp("collision_enabled", m_cur_line_trimmed, 17) == 0)
174  {
176  {
177  const char* value = m_cur_line_trimmed + 17; // C pointer arithmetic
178  m_cur_procedural_obj->collision_enabled = Ogre::StringConverter::parseBool(value, false);
179  }
180  return true;
181  }
182 
183  // ** Process entries (ODEF or special objects)
184 
186  {
187  this->ProcessProceduralLine();
188  }
189  else
190  {
191  TObjEntry object;
192  if (this->ParseObjectLine(object))
193  {
194  if (object.IsActor())
195  {
196  this->ProcessActorObject(object);
197  }
198  else if (object.IsRoad())
199  {
200  this->ProcessRoadObject(object);
201  }
202  else
203  {
204  m_def->objects.push_back(object);
205  }
206  }
207  }
208  return true;
209 }
210 
212 {
213  // finish the last road
214  if (m_road2_num_blocks > 0)
215  {
216  Vector3 pp_pos = m_road2_last_pos + m_road2_last_rot * Vector3(10.0f, 0.0f, 0.9f);
218 
219  this->FlushProceduralObject();
220  }
221 
222  m_def->document_name = m_filename;
223  m_def->rot_yxz = m_rot_yxz;
224  m_filename = "";
225 
226  TObjDocumentPtr tmp_def = m_def;
227  m_def.reset();
228  return tmp_def; // Pass ownership
229 }
230 
231 void TObjParser::ProcessOgreStream(Ogre::DataStream* stream)
232 {
233  m_filename = stream->getName();
234  char raw_line_buf[TObj::LINE_BUF_LEN];
235  bool keep_reading = true;
236  while (keep_reading && !stream->eof())
237  {
238  stream->readLine(raw_line_buf, TObj::LINE_BUF_LEN);
239  keep_reading = this->ProcessLine(raw_line_buf);
240  }
241 }
242 
243 // --------------------------------
244 // Processing
245 
247 {
248  ProceduralPoint point;
249  Str<300> obj_name;
250  Ogre::Vector3 rot = Ogre::Vector3::ZERO;
251  sscanf(m_cur_line, "%f, %f, %f, %f, %f, %f, %f, %f, %f, %s",
252  &point.position.x, &point.position.y, &point.position.z,
253  &rot.x, &rot.y, &rot.z,
254  &point.width, &point.bwidth, &point.bheight, obj_name.GetBuffer());
255 
256  point.rotation = this->CalcRotation(rot, m_rot_yxz);
257 
258  if (obj_name == "flat" ) { point.type = RoadType::ROAD_FLAT; }
259  else if (obj_name == "left" ) { point.type = RoadType::ROAD_LEFT; }
260  else if (obj_name == "right" ) { point.type = RoadType::ROAD_RIGHT; }
261  else if (obj_name == "both" ) { point.type = RoadType::ROAD_BOTH; }
262  else if (obj_name == "bridge" ) { point.type = RoadType::ROAD_BRIDGE; point.pillartype = 1; }
263  else if (obj_name == "monorail" ) { point.type = RoadType::ROAD_MONORAIL; point.pillartype = 2; }
264  else if (obj_name == "monorail2" ) { point.type = RoadType::ROAD_MONORAIL; point.pillartype = 0; }
265  else if (obj_name == "bridge_no_pillars") { point.type = RoadType::ROAD_BRIDGE; point.pillartype = 0; }
266  else { point.type = RoadType::ROAD_AUTOMATIC; point.pillartype = 1; }
267 
268  // Attach comments
270 
271  m_cur_procedural_obj->points.push_back(new ProceduralPoint(point));
272 }
273 
275 {
276  Ogre::Vector3 & pos = m_def->grid_position;
277  sscanf(m_cur_line, "grid %f, %f, %f", &pos.x, &pos.y, &pos.z); // No error check by design
278  m_def->grid_enabled = true;
279 }
280 
282 {
283  TObjTree tree;
284  sscanf(m_cur_line, "trees %f, %f, %f, %f, %f, %f, %f, %s %s %s %f %s",
285  &tree.yaw_from, &tree.yaw_to,
286  &tree.scale_from, &tree.scale_to,
287  &tree.high_density,
288  &tree.min_distance, &tree.max_distance,
289  tree.tree_mesh, tree.color_map, tree.density_map,
290  &tree.grid_spacing, tree.collision_mesh);
291 
292  m_def->trees.push_back(tree);
293 }
294 
296 {
297  TObjGrass grass;
298  if (strncmp(m_cur_line, "grass2", 6) == 0)
299  {
300  sscanf(m_cur_line, "grass2 %d, %f, %f, %f, %f, %f, %f, %f, %f, %d, %f, %f, %d, %s %s %s",
301  &grass.range,
302  &grass.sway_speed, &grass.sway_length, &grass.sway_distrib, &grass.density,
303  &grass.min_x, &grass.min_y, &grass.max_x, &grass.max_y,
304  &grass.grow_techniq, &grass.min_h, &grass.max_h, &grass.technique,
305  grass.material_name,
306  grass.color_map_filename,
307  grass.density_map_filename);
308  }
309  else
310  {
311  // Same as 'grass2', except without 'technique' parameter
312  sscanf(m_cur_line, "grass %d, %f, %f, %f, %f, %f, %f, %f, %f, %d, %f, %f, %s %s %s",
313  &grass.range,
314  &grass.sway_speed, &grass.sway_length, &grass.sway_distrib, &grass.density,
315  &grass.min_x, &grass.min_y, &grass.max_x, &grass.max_y,
316  &grass.grow_techniq, &grass.min_h, &grass.max_h,
317  grass.material_name,
318  grass.color_map_filename,
319  grass.density_map_filename);
320  }
321 
322  // 0: GRASSTECH_QUAD; // Grass constructed of randomly placed and rotated quads
323  // 1: GRASSTECH_CROSSQUADS; // Grass constructed of two quads forming a "X" cross shape
324  // 2: GRASSTECH_SPRITE; // Grass constructed of camera-facing billboard quads
325  if ((grass.technique < 0) || (grass.technique > 2))
326  {
327  LOGSTREAM << "Invalid parameter 'technique': '" << grass.technique << "', falling back to default '1: GRASSTECH_CROSSQUADS'";
328  grass.technique = 1;
329  }
330 
331  m_def->grass.push_back(grass);
332 }
333 
335 {
336  TObjVehicle v;
337  v.position = object.position;
338  v.tobj_rotation = object.rotation;
339  v.rotation = this->CalcRotation(object.rotation, m_rot_yxz);
340  v.type = object.special;
341  strcpy(v.name, object.type);
342 
343  m_def->vehicles.push_back(v);
344 }
345 
347 {
348  // ** Import road objects as procedural road
349 
350  if (object.position.distance(m_road2_last_pos) > 20.0f)
351  {
352  // break the road
353  if (m_road2_num_blocks > 0)
354  {
355  Vector3 pp_pos = m_road2_last_pos + this->CalcRotation(m_road2_last_rot, m_rot_yxz) * Vector3(10.0f, 0.0f, 0.9f);
356  this->ImportProceduralPoint(pp_pos, m_road2_last_rot, object.special);
357  this->FlushProceduralObject();
358  }
360 
361  // beginning of new
362  this->ImportProceduralPoint(object.position, object.rotation, object.special);
363  }
364  else
365  {
366  this->ImportProceduralPoint(object.position, object.rotation, object.special);
367  }
368  m_road2_last_pos=object.position;
369  m_road2_last_rot=object.rotation;
370 }
371 
372 // --------------------------------
373 // Helpers
374 
375 void TObjParser::ImportProceduralPoint(Ogre::Vector3 const& pos, Ogre::Vector3 const& rot, TObjSpecialObject special)
376 {
377  ProceduralPoint pp;
378  pp.bheight = 0.2;
379  pp.bwidth = 1.4;
381  pp.position = pos;
382  pp.rotation = CalcRotation(rot, m_rot_yxz);
384  pp.width = 8;
385 
386  // Attach comments
388 
389  m_cur_procedural_obj->points.push_back(new ProceduralPoint(pp));
391  {
393  }
394 }
395 
396 Ogre::Quaternion TObjParser::CalcRotation(Ogre::Vector3 const& rot, bool rot_yxz)
397 {
398  if (rot_yxz)
399  {
400  return Quaternion(Degree(rot.y), Vector3::UNIT_Y) * // y global
401  Quaternion(Degree(rot.x), Vector3::UNIT_X) * // x local
402  Quaternion(Degree(rot.z), Vector3::UNIT_Z); // z local
403  }
404  else
405  {
406  return Quaternion(Degree(rot.x), Vector3::UNIT_X) *
407  Quaternion(Degree(rot.y), Vector3::UNIT_Y) *
408  Quaternion(Degree(rot.z), Vector3::UNIT_Z);
409  }
410 }
411 
413 {
414  Str<TObj::STR_LEN> odef("generic");
415  Str<TObj::STR_LEN> type("");
416  Str<TObj::STR_LEN> instance_name("");
417  Ogre::Vector3 pos(Ogre::Vector3::ZERO);
418  Ogre::Vector3 rot(Ogre::Vector3::ZERO);
419  int r = sscanf(m_cur_line, "%f, %f, %f, %f, %f, %f, %s %s %s",
420  &pos.x, &pos.y, &pos.z, &rot.x, &rot.y, &rot.z, odef.GetBuffer(), type.GetBuffer(), instance_name.GetBuffer());
421  if (r < 6)
422  {
423  return false;
424  }
425 
427  if (odef == "truck" ) { special = TObjSpecialObject::TRUCK ; }
428  else if (odef == "load" ) { special = TObjSpecialObject::LOAD ; }
429  else if (odef == "machine" ) { special = TObjSpecialObject::MACHINE ; }
430  else if (odef == "boat" ) { special = TObjSpecialObject::BOAT ; }
431  else if (odef == "truck2" ) { special = TObjSpecialObject::TRUCK2 ; }
432  else if (odef == "grid" ) { special = TObjSpecialObject::GRID ; }
433  else if (odef == "road" ) { special = TObjSpecialObject::ROAD ; }
434  else if (odef == "roadborderleft" ) { special = TObjSpecialObject::ROAD_BORDER_LEFT ; }
435  else if (odef == "roadborderright" ) { special = TObjSpecialObject::ROAD_BORDER_RIGHT ; }
436  else if (odef == "roadborderboth" ) { special = TObjSpecialObject::ROAD_BORDER_BOTH ; }
437  else if (odef == "roadbridgenopillar") { special = TObjSpecialObject::ROAD_BRIDGE_NO_PILLARS; }
438  else if (odef == "roadbridge" ) { special = TObjSpecialObject::ROAD_BRIDGE ; }
439 
440  // If no instance name given, generate one, so that scripts can use `game.destroyObject(instanceName)` even for pre-placed objects.
441  // Don't use spaces because TOBJ parser doesn't support "" yet (game tries to strip the 'auto^' instancenames on save, but someone could export via custom script).
442  if (instance_name == "")
443  {
444  instance_name << "auto^" << m_filename << "(line:" << m_line_number << ")";
445  }
446 
447  object = TObjEntry(pos, rot, odef.ToCStr(), special, type, instance_name);
448  object.rendering_distance = m_default_rendering_distance;
449 
450  // Attach comments
451  object.comments = m_preceding_line_comments;
452 
453  return true;
454 }
455 
457 {
458  // finish it and start new object
460  m_def->proc_objects.push_back(m_cur_procedural_obj);
463  m_road2_num_blocks = 0;
464 }
465 
466 void WriteTObjDelimiter(Ogre::DataStreamPtr& stream, const std::string& title, size_t count)
467 {
468  if (count > 0)
469  {
470  std::string line = fmt::format("\n\n// ~~~~~~~~~~ {} ({}) ~~~~~~~~~~\n\n", title, count);
471  stream->write(line.c_str(), line.length());
472  }
473 }
474 
475 void TObj::WriteToStream(TObjDocumentPtr doc, Ogre::DataStreamPtr stream)
476 {
477  // assert on Debug, play safe on Release
478  ROR_ASSERT(doc);
479  ROR_ASSERT(stream);
480  if (!doc || !stream)
481  {
482  return;
483  }
484 
485  // 'grid'
486  WriteTObjDelimiter(stream, "grid", (int)doc->grid_enabled);
487  if (doc->grid_enabled)
488  {
489  std::string line = fmt::format("grid {}, {}, {}\n");
490  stream->write(line.c_str(), line.length());
491  }
492 
493  // 'trees'
494  WriteTObjDelimiter(stream, "trees", doc->trees.size());
495  for (TObjTree& tree : doc->trees)
496  {
497  std::string line = fmt::format("trees {:9f}, {:9f}, {:9f}, {:9f}, {:9f}, {:9f}, {:9f}, {} {} {} {:9f} {}\n",
498  tree.yaw_from, tree.yaw_to,
499  tree.scale_from, tree.scale_to,
500  tree.high_density,
501  tree.min_distance, tree.max_distance,
502  tree.tree_mesh, tree.color_map, tree.density_map,
503  tree.grid_spacing, tree.collision_mesh);
504  stream->write(line.c_str(), line.length());
505  }
506 
507  // 'grass2' (incudes 'grass' elements)
508  WriteTObjDelimiter(stream, "grass", doc->grass.size());
509  for (TObjGrass& grass : doc->grass)
510  {
511  std::string line = fmt::format("grass2 {}, {:9f}, {:9f}, {:9f}, {:9f}, {:9f}, {:9f}, {:9f}, {:9f}, {}, {:9f}, {:9f}, {}, {} {} {}\n",
512  grass.range,
513  grass.sway_speed, grass.sway_length, grass.sway_distrib, grass.density,
514  grass.min_x, grass.min_y, grass.max_x, grass.max_y,
515  grass.grow_techniq, grass.min_h, grass.max_h, grass.technique,
516  grass.material_name,
517  grass.color_map_filename,
518  grass.density_map_filename);
519  stream->write(line.c_str(), line.length());
520  }
521 
522  // vehicles ('truck', 'truck2', 'boat', 'load', 'machine')
523  WriteTObjDelimiter(stream, "vehicles/loads/machines", doc->vehicles.size());
524  for (TObjVehicle& vehicle : doc->vehicles)
525  {
526  // Handle preceding comments
527  if (vehicle.comments != "")
528  {
529  for (Ogre::String& commenttext : Ogre::StringUtil::split(vehicle.comments, "\n"))
530  {
531  std::string commentline = fmt::format("// {}\n", commenttext);
532  stream->write(commentline.c_str(), commentline.length());
533  }
534  }
535 
536  std::string line = fmt::format("{:9f}, {:9f}, {:9f}, {:9f}, {:9f}, {:9f}, {} {}\n",
537  vehicle.position.x, vehicle.position.y, vehicle.position.z,
538  vehicle.tobj_rotation.x, vehicle.tobj_rotation.y, vehicle.tobj_rotation.z,
539  TObjSpecialObjectToString(vehicle.type), (const char*)vehicle.name);
540  stream->write(line.c_str(), line.length());
541  }
542 
543  // procedural objects
544  WriteTObjDelimiter(stream, "roads", doc->proc_objects.size());
545  for (ProceduralObjectPtr& procobj : doc->proc_objects)
546  {
547  std::string bline = "begin_procedural_roads\n";
548  stream->write(bline.c_str(), bline.length());
549 
550  std::string sline = fmt::format(" smoothing_num_splits {}\n", procobj->smoothing_num_splits);
551  stream->write(sline.c_str(), sline.length());
552 
553  std::string cline = fmt::format(" collision_enabled {}\n", procobj->collision_enabled);
554  stream->write(cline.c_str(), cline.length());
555 
556  for (ProceduralPointPtr& point : procobj->points)
557  {
558  std::string type_str;
559  switch (point->type)
560  {
561  case RoadType::ROAD_AUTOMATIC: type_str = "auto"; break;
562  case RoadType::ROAD_FLAT: type_str = "flat"; break;
563  case RoadType::ROAD_LEFT: type_str = "left"; break;
564  case RoadType::ROAD_RIGHT: type_str = "right"; break;
565  case RoadType::ROAD_BOTH: type_str = "both"; break;
566  case RoadType::ROAD_BRIDGE: type_str = (point->pillartype == 1) ? "bridge" : "bridge_no_pillars"; break;
567  case RoadType::ROAD_MONORAIL: type_str = (point->pillartype == 2) ? "monorail" : "monorail2"; break;
568  }
569 
570  // Handle preceding comments
571  if (point->comments != "")
572  {
573  for (Ogre::String& commenttext : Ogre::StringUtil::split(point->comments, "\n"))
574  {
575  std::string commentline = fmt::format("// {}\n", commenttext);
576  stream->write(commentline.c_str(), commentline.length());
577  }
578  }
579 
580  std::string line = fmt::format(
581  "\t{:13f}, {:13f}, {:13f}, 0, {:13f}, 0, {:13f}, {:13f}, {:13f}, {}\n",
582  point->position.x, point->position.y, point->position.z,
583  point->rotation.getYaw(false).valueDegrees(),
584  point->width, point->bwidth, point->bheight, type_str);
585  stream->write(line.c_str(), line.length());
586  }
587 
588  std::string eline = "end_procedural_roads\n";
589  stream->write(eline.c_str(), eline.length());
590  }
591 
592  // static objects
593  WriteTObjDelimiter(stream, "static objects", doc->objects.size());
594  for (TObjEntry& entry : doc->objects)
595  {
596  // Handle preceding comments
597  if (entry.comments != "")
598  {
599  for (Ogre::String& commenttext : Ogre::StringUtil::split(entry.comments, "\n"))
600  {
601  std::string commentline = fmt::format("// {}\n", commenttext);
602  stream->write(commentline.c_str(), commentline.length());
603  }
604  }
605 
606  // Don't save autogenerated instance names
607  std::string valid_instance_name;
608  if (strncmp(entry.instance_name, "auto^", 5) != 0)
609  {
610  valid_instance_name = entry.instance_name;
611  }
612 
613  std::string line = fmt::format("{:8.3f}, {:8.3f}, {:8.3f}, {:9f}, {:9f}, {:9f}, {} {} {}\n",
614  entry.position.x, entry.position.y, entry.position.z,
615  entry.rotation.x, entry.rotation.y, entry.rotation.z,
616  entry.odef_name, entry.type, valid_instance_name);
617  stream->write(line.c_str(), line.length());
618  }
619 }
620 
ROR_ASSERT
#define ROR_ASSERT(_EXPR)
Definition: Application.h:40
RoR::TObjParser::ProcessLine
bool ProcessLine(const char *line)
Definition: TObjFileFormat.cpp:72
RoR::TObjVehicle::type
TObjSpecialObject type
Definition: TObjFileFormat.h:115
RoR::RoadType::ROAD_BOTH
@ ROAD_BOTH
RoR::ProceduralPoint::type
RoadType type
Definition: ProceduralManager.h:53
RoR::TObjParser::m_preceding_line_comments
std::string m_preceding_line_comments
Definition: TObjFileFormat.h:191
RoR::TObjParser::ProcessProceduralLine
void ProcessProceduralLine()
Definition: TObjFileFormat.cpp:246
RoR::TObjGrass::density
float density
Definition: TObjFileFormat.h:98
RoR::MACHINE
@ MACHINE
its a machine
Definition: SimData.h:88
LOGSTREAM
#define LOGSTREAM
Definition: TObjFileFormat.cpp:25
RoR::TRUCK
@ TRUCK
its a truck (or other land vehicle)
Definition: SimData.h:85
RoR::TObjParser::ProcessActorObject
void ProcessActorObject(const TObjEntry &object)
Definition: TObjFileFormat.cpp:334
RoR::ProceduralObject::points
std::vector< ProceduralPointPtr > points
Definition: ProceduralManager.h:76
RoR::TObjGrass::min_y
float min_y
Definition: TObjFileFormat.h:100
RoR::TObjGrass::range
int range
Definition: TObjFileFormat.h:92
RoR::Str::GetBuffer
char * GetBuffer()
Definition: Str.h:48
RoR::ProceduralPoint::bwidth
float bwidth
Definition: ProceduralManager.h:55
RoR::ProceduralPoint::comments
std::string comments
Comment line(s) preceding the point-line in the .TOBJ file.
Definition: ProceduralManager.h:58
RoR::TObjEntry::IsActor
bool IsActor() const
Definition: TObjFileFormat.cpp:48
RoR::TObjEntry::comments
std::string comments
Comment line(s) preceding the object-line in the .TOBJ file.
Definition: TObjFileFormat.h:137
RoR::RoadType::ROAD_AUTOMATIC
@ ROAD_AUTOMATIC
RoR::TObjGrass::max_y
float max_y
Definition: TObjFileFormat.h:101
RoR::ProceduralPoint::position
Ogre::Vector3 position
Definition: ProceduralManager.h:51
RoR::TObjParser::m_filename
std::string m_filename
Definition: TObjFileFormat.h:186
RoR::TObjVehicle::rotation
Ogre::Quaternion rotation
Definition: TObjFileFormat.h:112
RoR::TObjGrass::sway_distrib
float sway_distrib
Definition: TObjFileFormat.h:97
RoR::TObjParser::Prepare
void Prepare()
Definition: TObjFileFormat.cpp:58
RoR::TObjTree::yaw_to
float yaw_to
Definition: TObjFileFormat.h:60
format
Truck file format(technical spec)
RoR::TObjGrass::min_x
float min_x
Definition: TObjFileFormat.h:100
RoR::TObjSpecialObject
TObjSpecialObject
Definition: Application.h:568
TObjFileFormat.h
Parser and data structures for TOBJ (Terrain Objects) file format.
RoR::ProceduralPoint::bheight
float bheight
Definition: ProceduralManager.h:56
RoR::TObjEntry::instance_name
char instance_name[TObj::STR_LEN]
Definition: TObjFileFormat.h:134
RoR::ProceduralPoint::rotation
Ogre::Quaternion rotation
Definition: ProceduralManager.h:52
RoR::TObjParser::m_in_procedural_road
bool m_in_procedural_road
Definition: TObjFileFormat.h:194
RoR::TObjTree::min_distance
float min_distance
Definition: TObjFileFormat.h:62
RoR::TObjEntry::odef_name
char odef_name[TObj::STR_LEN]
Definition: TObjFileFormat.h:135
RoR::TObjGrass::material_name
char material_name[TObj::STR_LEN]
Definition: TObjFileFormat.h:103
RoR::TObj::LINE_BUF_LEN
const int LINE_BUF_LEN
Definition: TObjFileFormat.h:38
RefCountingObjectPtr< ProceduralObject >
Actor.h
RoR::TObjParser::ProcessCurrentLine
bool ProcessCurrentLine()
Definition: TObjFileFormat.cpp:104
RoR::TObjGrass::max_h
float max_h
Definition: TObjFileFormat.h:101
RoR::TObjSpecialObject::GRID
@ GRID
RoR::TObjParser::Finalize
TObjDocumentPtr Finalize()
Passes ownership.
Definition: TObjFileFormat.cpp:211
RoR::TObjEntry::special
TObjSpecialObject special
Definition: TObjFileFormat.h:132
RoR::TObjParser::m_cur_procedural_obj_start_line
int m_cur_procedural_obj_start_line
Definition: TObjFileFormat.h:196
RoR::TObjTree::density_map
char density_map[TObj::STR_LEN]
Definition: TObjFileFormat.h:68
RoR::TObjParser::ProcessGridLine
void ProcessGridLine()
Definition: TObjFileFormat.cpp:274
RoR::TObjEntry
Definition: TObjFileFormat.h:120
ProceduralRoad.h
RoR::TObjGrass::sway_length
float sway_length
Definition: TObjFileFormat.h:96
RoR::ProceduralObject
Definition: ProceduralManager.h:61
RoR::TObjEntry::rotation
Ogre::Vector3 rotation
Definition: TObjFileFormat.h:131
RoR::TObjParser::m_line_number
int m_line_number
Definition: TObjFileFormat.h:187
RoR::TObjParser::ParseObjectLine
bool ParseObjectLine(TObjEntry &object)
Definition: TObjFileFormat.cpp:412
RoR::Str
Wrapper for classic c-string (local buffer) Refresher: strlen() excludes '\0' terminator; strncat() A...
Definition: Str.h:35
RoR::TObjDocumentPtr
std::shared_ptr< TObjDocument > TObjDocumentPtr
Definition: ForwardDeclarations.h:225
RoR::TObjParser::ImportProceduralPoint
void ImportProceduralPoint(Ogre::Vector3 const &pos, Ogre::Vector3 const &rot, TObjSpecialObject special)
Definition: TObjFileFormat.cpp:375
RoR::TObjVehicle::tobj_rotation
Ogre::Vector3 tobj_rotation
Original rotation specified in .TOBJ file.
Definition: TObjFileFormat.h:113
RoR::TObjGrass::technique
int technique
Definition: TObjFileFormat.h:93
RoR::TObjGrass::density_map_filename
char density_map_filename[TObj::STR_LEN]
Definition: TObjFileFormat.h:105
RoR::RoadType::ROAD_BRIDGE
@ ROAD_BRIDGE
RoR::Str::ToCStr
const char * ToCStr() const
Definition: Str.h:46
RoR::ProceduralPoint::width
float width
Definition: ProceduralManager.h:54
RoR::TObjParser::m_road2_num_blocks
int m_road2_num_blocks
Definition: TObjFileFormat.h:201
RoR::TObjParser::m_road2_last_rot
Ogre::Vector3 m_road2_last_rot
Definition: TObjFileFormat.h:200
RoR::TObjVehicle::position
Ogre::Vector3 position
Definition: TObjFileFormat.h:111
RoR::ProceduralObject::smoothing_num_splits
int smoothing_num_splits
Definition: ProceduralManager.h:78
RoR::TObjSpecialObject::ROAD_BORDER_BOTH
@ ROAD_BORDER_BOTH
RoR::TObjVehicle::comments
std::string comments
Comment line(s) preceding the vehicle-line in the .TOBJ file.
Definition: TObjFileFormat.h:116
RoR::TObjSpecialObject::ROAD_BORDER_RIGHT
@ ROAD_BORDER_RIGHT
RoR::ProceduralObject::collision_enabled
bool collision_enabled
Generate collision triangles?
Definition: ProceduralManager.h:79
RoR::TObjTree::tree_mesh
char tree_mesh[TObj::STR_LEN]
Definition: TObjFileFormat.h:66
RoR::TObjGrass::sway_speed
float sway_speed
Definition: TObjFileFormat.h:95
RoR::TObjEntry::type
char type[TObj::STR_LEN]
Definition: TObjFileFormat.h:133
RoR::TObjDocument
Definition: TObjFileFormat.h:141
RoR::TObjEntry::IsRoad
bool IsRoad() const
Definition: TObjFileFormat.cpp:43
RoR::RoadType::ROAD_FLAT
@ ROAD_FLAT
RoR::TObjTree::scale_from
float scale_from
Definition: TObjFileFormat.h:61
RoR::TObjParser::m_def
TObjDocumentPtr m_def
Definition: TObjFileFormat.h:185
RoR::TObjParser::m_cur_procedural_obj
ProceduralObjectPtr m_cur_procedural_obj
Definition: TObjFileFormat.h:195
RoR::TObjTree::max_distance
float max_distance
Definition: TObjFileFormat.h:62
RoR::RoadType::ROAD_MONORAIL
@ ROAD_MONORAIL
RoR::RoadType::ROAD_RIGHT
@ ROAD_RIGHT
RoR::TObjParser::ProcessRoadObject
void ProcessRoadObject(const TObjEntry &object)
Definition: TObjFileFormat.cpp:346
RoR::TObjSpecialObject::ROAD_BORDER_LEFT
@ ROAD_BORDER_LEFT
RoR::TObjParser::CalcRotation
static Ogre::Quaternion CalcRotation(Ogre::Vector3 const &rot, bool rot_yxz)
Definition: TObjFileFormat.cpp:396
RoR::TObjParser::m_rot_yxz
bool m_rot_yxz
Definition: TObjFileFormat.h:203
RoR::TObjEntry::TObjEntry
TObjEntry()
Definition: TObjFileFormat.h:122
RoR::TObjParser::ProcessOgreStream
void ProcessOgreStream(Ogre::DataStream *stream)
Definition: TObjFileFormat.cpp:231
RoR::TObjTree::grid_spacing
float grid_spacing
Definition: TObjFileFormat.h:64
RoR::TObjSpecialObject::ROAD_BRIDGE
@ ROAD_BRIDGE
RoR::TObjSpecialObject::ROAD
@ ROAD
RoR::TObjParser::m_road2_last_pos
Ogre::Vector3 m_road2_last_pos
Definition: TObjFileFormat.h:199
RoR::TObjParser::m_cur_line
const char * m_cur_line
Definition: TObjFileFormat.h:188
RoR::TObj::WriteToStream
void WriteToStream(TObjDocumentPtr doc, Ogre::DataStreamPtr stream)
Definition: TObjFileFormat.cpp:475
RoR::TObjGrass::color_map_filename
char color_map_filename[TObj::STR_LEN]
Definition: TObjFileFormat.h:104
RoR::TObjTree::high_density
float high_density
Definition: TObjFileFormat.h:63
RoR::TObjVehicle::name
char name[TObj::STR_LEN]
Definition: TObjFileFormat.h:114
RoR::TObjSpecialObject::ROAD_BRIDGE_NO_PILLARS
@ ROAD_BRIDGE_NO_PILLARS
RoR::RoadType::ROAD_LEFT
@ ROAD_LEFT
RoR::TObjGrass::max_x
float max_x
Definition: TObjFileFormat.h:101
RoR::TObjGrass
Unified 'grass' and 'grass2'.
Definition: TObjFileFormat.h:74
RoR::ProceduralPoint
Definition: ProceduralManager.h:34
RoR::TObjParser::m_default_rendering_distance
float m_default_rendering_distance
Definition: TObjFileFormat.h:190
RoR::TObjGrass::grow_techniq
int grow_techniq
Definition: TObjFileFormat.h:94
RoR::TObjTree::color_map
char color_map[TObj::STR_LEN]
Definition: TObjFileFormat.h:67
RoR::TObjTree
Definition: TObjFileFormat.h:45
RoR::ProceduralObject::name
std::string name
Definition: ProceduralManager.h:75
RoR::TObjSpecialObject::LOAD
@ LOAD
Ogre
Definition: ExtinguishableFireAffector.cpp:35
RoR::TObjTree::scale_to
float scale_to
Definition: TObjFileFormat.h:61
RoR::TObjSpecialObject::NONE
@ NONE
RoR::TObjEntry::position
Ogre::Vector3 position
Definition: TObjFileFormat.h:130
RoR::TObjVehicle
Definition: TObjFileFormat.h:109
RoR::TObjParser::ProcessTreesLine
void ProcessTreesLine()
Definition: TObjFileFormat.cpp:281
RoR::BOAT
@ BOAT
its a boat
Definition: SimData.h:87
RoR::ProceduralPoint::pillartype
int pillartype
Definition: ProceduralManager.h:57
RoR::TObjParser::FlushProceduralObject
void FlushProceduralObject()
Definition: TObjFileFormat.cpp:456
RoR::TObjGrass::min_h
float min_h
Definition: TObjFileFormat.h:100
RoR
Definition: AppContext.h:36
RoR::TObjSpecialObject::TRUCK2
@ TRUCK2
Free position (not auto-adjusted to fit terrain or water surface)
RoR::TObjSpecialObjectToString
const char * TObjSpecialObjectToString(TObjSpecialObject val)
Definition: Application.cpp:680
RoR::TObjParser::m_cur_line_trimmed
const char * m_cur_line_trimmed
Definition: TObjFileFormat.h:189
RoR::TObjTree::collision_mesh
char collision_mesh[TObj::STR_LEN]
Definition: TObjFileFormat.h:69
RoR::TObjTree::yaw_from
float yaw_from
Definition: TObjFileFormat.h:60
RoR::TObjParser::ProcessGrassLine
void ProcessGrassLine()
Definition: TObjFileFormat.cpp:295
WriteTObjDelimiter
void WriteTObjDelimiter(Ogre::DataStreamPtr &stream, const std::string &title, size_t count)
Definition: TObjFileFormat.cpp:466