RigsofRods
Soft-body Physics Simulation
TerrainGeometryManager.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  Copyright 2013-2020 Petr Ohlidal
6 
7  For more information, see http://www.rigsofrods.org/
8 
9  Rigs of Rods is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License version 3, as
11  published by the Free Software Foundation.
12 
13  Rigs of Rods is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
20 */
21 
22 #include "TerrainGeometryManager.h"
23 
24 #include "Actor.h"
25 #include "Application.h"
26 #include "ContentManager.h"
27 #include "Language.h"
28 #include "GfxScene.h"
29 #include "GUIManager.h"
30 #include "GUI_LoadingWindow.h"
31 #include "Terrain.h"
32 #include "ShadowManager.h"
34 #include "OTCFileFormat.h"
35 
36 #include <OgreLight.h>
37 #include <Terrain/OgreTerrainGroup.h>
38 
39 using namespace Ogre;
40 using namespace RoR;
41 
42 #define CUSTOM_MAT_PROFILE_NAME "Terrn2CustomMat"
43 
45 class Terrn2CustomMaterial : public Ogre::TerrainMaterialGenerator
46 {
47 public:
48 
49  Terrn2CustomMaterial(Ogre::String materialName, bool addNormalmap, bool cloneMaterial)
50  : m_material_name(materialName), m_add_normal_map(addNormalmap), m_clone_material(cloneMaterial)
51  {
52  mProfiles.push_back(OGRE_NEW Profile(this, CUSTOM_MAT_PROFILE_NAME, "Renders RoR terrn2 with custom material"));
53  this->setActiveProfile(CUSTOM_MAT_PROFILE_NAME);
54  }
55 
56  void setMaterialByName(const Ogre::String materialName)
57  {
58  m_material_name = materialName;
59  this->_markChanged();
60  };
61 
62  class Profile : public Ogre::TerrainMaterialGenerator::Profile
63  {
64  public:
65  Profile(Ogre::TerrainMaterialGenerator* parent, const Ogre::String& name, const Ogre::String& desc)
66  : Ogre::TerrainMaterialGenerator::Profile(parent, name, desc)
67  {
68  };
69  ~Profile() override {};
70 
71  bool isVertexCompressionSupported () const { return false; }
72  void setLightmapEnabled (bool set) /*override*/ {} // OGRE 1.8 doesn't have this method
73  Ogre::MaterialPtr generate (const Ogre::Terrain* terrain) override;
74  Ogre::uint8 getMaxLayers (const Ogre::Terrain* terrain) const override { return 0; };
75  void updateParams (const Ogre::MaterialPtr& mat, const Ogre::Terrain* terrain) override {};
76  void updateParamsForCompositeMap (const Ogre::MaterialPtr& mat, const Ogre::Terrain* terrain) override {};
77 
78  Ogre::MaterialPtr generateForCompositeMap(const Ogre::Terrain* terrain) override
79  {
80  return terrain->_getCompositeMapMaterial();
81  };
82 
83  void requestOptions(Ogre::Terrain* terrain) override
84  {
85  terrain->_setMorphRequired(false);
86  terrain->_setNormalMapRequired(true); // enable global normal map
87  terrain->_setLightMapRequired(false);
88  terrain->_setCompositeMapRequired(false);
89  };
90  };
91 
92 protected:
93  Ogre::String m_material_name;
96 };
97 
98 Ogre::MaterialPtr Terrn2CustomMaterial::Profile::generate(const Ogre::Terrain* terrain)
99 {
100  const Ogre::String& matName = terrain->getMaterialName();
101 
102  Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().getByName(matName);
103  if (!mat.isNull())
104  Ogre::MaterialManager::getSingleton().remove(matName);
105 
106  Terrn2CustomMaterial* parent = static_cast<Terrn2CustomMaterial*>(this->getParent());
107 
108  // Set Ogre material
109  mat = Ogre::MaterialManager::getSingleton().getByName(parent->m_material_name);
110 
111  // Clone material
112  if(parent->m_clone_material)
113  {
114  mat = mat->clone(matName);
115  parent->m_material_name = matName;
116  }
117 
118  // Add normalmap
119  if(parent->m_add_normal_map)
120  {
121  // Get default pass
122  Ogre::Pass *p = mat->getTechnique(0)->getPass(0);
123 
124  // Add terrain's global normalmap to renderpass so the fragment program can find it.
125  Ogre::TextureUnitState *tu = p->createTextureUnitState(matName+"/nm");
126 
127  Ogre::TexturePtr nmtx = terrain->getTerrainNormalMap();
128  tu->_setTexturePtr(nmtx);
129  }
130 
131  return mat;
132 };
133 
134 // ----------------------------------------------------------------------------
135 
136 #define XZSTR(X,Z) String("[") + TOSTRING(X) + String(",") + TOSTRING(Z) + String("]")
137 
138 TerrainGeometryManager::TerrainGeometryManager(Terrain* terrainManager)
139  : mHeightData(nullptr)
140  , mIsFlat(false)
141  , mMinHeight(0.0f)
142  , mMaxHeight(std::numeric_limits<float>::min())
143  , m_was_new_geometry_generated(false)
144  , terrainManager(terrainManager)
145  , m_ogre_terrain_group(nullptr)
146 {
147 }
148 
150 {
151  if (m_ogre_terrain_group != nullptr)
152  {
153  m_ogre_terrain_group->removeAllTerrains();
154  }
155 }
156 
159 {
160  // get left / bottom points (rounded down)
161  Real factor = (Real)mSize - 1.0f;
162  Real invFactor = 1.0f / factor;
163 
164  long startX = static_cast<long>(x * factor);
165  long startY = static_cast<long>(y * factor);
166  long endX = startX + 1;
167  long endY = startY + 1;
168 
169  // now get points in terrain space (effectively rounding them to boundaries)
170  // note that we do not clamp! We need a valid plane
171  Real startXTS = startX * invFactor;
172  Real startYTS = startY * invFactor;
173  Real endXTS = endX * invFactor;
174  Real endYTS = endY * invFactor;
175 
176  // get parametric from start coord to next point
177  Real xParam = (x * factor - startX);
178  Real yParam = (y * factor - startY);
179 
180  /* For even / odd tri strip rows, triangles are this shape:
181  even odd
182  3---2 3---2
183  | / | | \ |
184  0---1 0---1
185  */
186 
187  // Build all 4 positions in terrain space, using point-sampled height
188  Vector3 v0(startXTS, startYTS, mHeightData[startY * mSize + startX]);
189  Vector3 v1(endXTS , startYTS, mHeightData[startY * mSize + endX]);
190  Vector3 v2(endXTS , endYTS , mHeightData[endY * mSize + endX]);
191  Vector3 v3(startXTS, endYTS , mHeightData[endY * mSize + startX]);
192 
193  // define this plane in terrain space
194  Vector3 normal;
195  Real d;
196  if (startY % 2)
197  {
198  // odd row
199  bool secondTri = ((1.0 - yParam) > xParam);
200  if (secondTri)
201  {
202  normal = (v1 - v0).crossProduct(v3 - v0);
203  d = -normal.dotProduct(v0);
204  }
205  else
206  {
207  normal = (v2 - v1).crossProduct(v3 - v1);
208  d = -normal.dotProduct(v1);
209  }
210  }
211  else
212  {
213  // even row
214  bool secondTri = (yParam > xParam);
215  if (secondTri)
216  {
217  normal = (v2 - v0).crossProduct(v3 - v0);
218  d = -normal.dotProduct(v0);
219  }
220  else
221  {
222  normal = (v1 - v0).crossProduct(v2 - v0);
223  d = -normal.dotProduct(v0);
224  }
225  }
226 
227  // Solve plane equation for z
228  return (-normal.x * x - normal.y * y - d) / normal.z;
229 }
230 
232 {
233  if (m_spec->is_flat)
234  return 0.0f;
235 
236  float tx = (x - mBase - mPos.x) / ((mSize - 1) * mScale);
237  float ty = (z + mBase - mPos.z) / ((mSize - 1) * -mScale);
238 
239  if (tx <= 0.0f || ty <= 0.0f || tx >= 1.0f || ty >= 1.0f)
241  else if (mIsFlat)
242  return mMinHeight;
243 
244  return getHeightAtTerrainPosition(tx, ty);
245 }
246 
247 Ogre::Vector3 TerrainGeometryManager::getNormalAt(float x, float y, float z)
248 {
249  const float precision = 0.1f;
250  Vector3 normal(getHeightAt(x - precision, z) - y, precision, y - getHeightAt(x, z + precision));
251  normal.normalise();
252  return normal;
253 }
254 
255 bool TerrainGeometryManager::InitTerrain(std::string otc_filename)
256 {
257  OTCParser otc_parser;
258 
259  // Load main *.otc file
260  try
261  {
262  DataStreamPtr ds_config = ResourceGroupManager::getSingleton().openResource(otc_filename);
263  if (ds_config.isNull() || !ds_config->isReadable())
264  {
265  RoR::LogFormat("[RoR|Terrain] Cannot read main *.otc file [%s].", otc_filename.c_str());
266  return false;
267  }
268  if (!otc_parser.LoadMasterConfig(ds_config, otc_filename.c_str()))
269  {
270  return false; // Error already reported
271  }
272  }
273  catch (...)
274  {
275  RoR::HandleGenericException(fmt::format("TerrainGeometryManager::InitTerrain({})", otc_filename));
276  // If we stop parsing we might break some legacy maps
277  //return false;
278  }
279 
280  // Load *.otc files for pages
281  for (OTCPage& page : otc_parser.GetDefinition()->pages)
282  {
283  if (page.pageconf_filename.empty())
284  {
285  continue; // For backwards compatibility.
286  }
287 
288  try
289  {
290  DataStreamPtr ds_page = ResourceGroupManager::getSingleton().openResource(page.pageconf_filename);
291  if (ds_page.isNull() || !ds_page->isReadable())
292  {
293  RoR::LogFormat("[RoR|Terrain] Cannot read file [%s].", page.pageconf_filename.c_str());
294  return false;
295  }
296 
297  // NOTE: Empty file is accepted (leaving all values to defaults) for backwards compatibility.
298  if (!otc_parser.LoadPageConfig(ds_page, page, page.pageconf_filename.c_str()))
299  {
300  return false; // Error already logged
301  }
302  }
303  catch (...)
304  {
305  RoR::HandleGenericException(fmt::format("TerrainGeometryManager::InitTerrain({})", page.pageconf_filename));
306  // If we stop parsing we might break some legacy maps
307  // return false;
308  }
309  }
310 
311  m_spec = otc_parser.GetDefinition();
312 
313  const std::string cache_filename_format = m_spec->cache_filename_base + "_OGRE_" + TOSTRING(OGRE_VERSION) + "_";
314 
315  m_ogre_terrain_group = OGRE_NEW TerrainGroup(App::GetGfxScene()->GetSceneManager(), Ogre::Terrain::ALIGN_X_Z, m_spec->page_size, m_spec->world_size);
316  m_ogre_terrain_group->setFilenameConvention(cache_filename_format, "mapbin");
317  m_ogre_terrain_group->setOrigin(m_spec->origin_pos);
318  m_ogre_terrain_group->setResourceGroup(RGN_CACHE);
319 
321 
322  for (OTCPage& page : m_spec->pages)
323  {
324  this->SetupGeometry(page, m_spec->is_flat);
325  }
326 
327  // sync load since we want everything in place when we start
328  App::GetGuiManager()->LoadingWindow.SetProgress(44, _L("Loading terrain pages ..."));
329  m_ogre_terrain_group->loadAllTerrains(true);
330 
331  Ogre::Terrain* terrain = m_ogre_terrain_group->getTerrain(0, 0);
332 
333  if (terrain == nullptr)
334  return true;
335 
336  mHeightData = terrain->getHeightData();
337  mSize = terrain->getSize();
338  const float world_size = terrain->getWorldSize();
339  mBase = -world_size * 0.5f;
340  mScale = world_size / (Real)(mSize - 1);
341  mPos = terrain->getPosition();
342 
343  // terrain->getMinHeight() / terrain->getMaxHeight() seem to be unreliable ~ ulteq 12/18
344  for (int x = 0; x < mSize; x++)
345  {
346  for (int y = 0; y < mSize; y++)
347  {
348  float h = mHeightData[y * mSize + x];
349  mMinHeight = std::min(h, mMinHeight);
350  mMaxHeight = std::max(mMaxHeight, h);
351  }
352  }
353  mIsFlat = std::abs(mMaxHeight - mMinHeight) < std::numeric_limits<float>::epsilon();
354 
356  {
357  // update the blend maps
359  {
360  for (OTCPage& page : m_spec->pages)
361  {
362  Ogre::Terrain* terrain = m_ogre_terrain_group->getTerrain(page.pos_x, page.pos_z);
363 
364  if (terrain != nullptr)
365  {
366  this->SetupLayers(page, terrain);
367  this->SetupBlendMaps(page, terrain);
368  }
369  }
370  }
371 
372  // always save the results when it was imported
373  if (!m_spec->disable_cache)
374  {
375  App::GetGuiManager()->LoadingWindow.SetProgress(50, _L("Saving all terrain pages ..."));
376  m_ogre_terrain_group->saveAllTerrains(false);
377  }
378  }
379  else
380  {
381  LOG(" *** Terrain loaded from cache ***");
382  }
383 
384  m_ogre_terrain_group->freeTemporaryResources();
385  return true;
386 }
387 
389 {
390  TerrainGroup::TerrainIterator ti = m_ogre_terrain_group->getTerrainIterator();
391 
392  while (ti.hasMoreElements())
393  {
394  Ogre::Terrain* terrain = ti.getNext()->instance;
395  if (!terrain)
396  continue;
397 
398  if (!terrain->isDerivedDataUpdateInProgress())
399  {
400  terrain->dirtyLightmap();
401  terrain->updateDerivedData();
402  }
403  }
404 }
405 
407 {
408  Light* light = terrainManager->getMainLight();
409  TerrainGlobalOptions* terrainOptions = TerrainGlobalOptions::getSingletonPtr();
410  if (light)
411  {
412  terrainOptions->setLightMapDirection(light->getDerivedDirection());
413  terrainOptions->setCompositeMapDiffuse(light->getDiffuseColour());
414  }
415  terrainOptions->setCompositeMapAmbient(App::GetGfxScene()->GetSceneManager()->getAmbientLight());
416 
417  m_ogre_terrain_group->update();
418 }
419 
421 {
422  if (!TerrainGlobalOptions::getSingletonPtr())
423  {
424  OGRE_NEW TerrainGlobalOptions();
425  }
426 
427  TerrainGlobalOptions* terrainOptions = TerrainGlobalOptions::getSingletonPtr();
428  std::string const & custom_mat = terrainManager->GetDef().custom_material_name;
429  if (!custom_mat.empty())
430  {
431  terrainOptions->setDefaultMaterialGenerator(
432  Ogre::TerrainMaterialGeneratorPtr(new Terrn2CustomMaterial(custom_mat, false, true)));
433  }
434  else
435  {
436  terrainOptions->setDefaultMaterialGenerator(
437  Ogre::TerrainMaterialGeneratorPtr(new Ogre::TerrainPSSMMaterialGenerator()));
438  }
439  // Configure global
440  terrainOptions->setMaxPixelError(m_spec->max_pixel_error);
441 
442  // Important to set these so that the terrain knows what to use for derived (non-realtime) data
443  Light* light = terrainManager->getMainLight();
444  if (light)
445  {
446  terrainOptions->setLightMapDirection(light->getDerivedDirection());
447  if (custom_mat.empty())
448  {
449  terrainOptions->setCompositeMapDiffuse(light->getDiffuseColour());
450  }
451  }
452  terrainOptions->setCompositeMapAmbient(App::GetGfxScene()->GetSceneManager()->getAmbientLight());
453 
454  // Configure default import settings for if we use imported image
455  Ogre::Terrain::ImportData& defaultimp = m_ogre_terrain_group->getDefaultImportSettings();
456  defaultimp.terrainSize = m_spec->page_size; // the heightmap size
457  defaultimp.worldSize = m_spec->world_size; // this is the scaled up size, like 12km
458  defaultimp.inputScale = m_spec->world_size_y;
459  defaultimp.minBatchSize = m_spec->batch_size_min;
460  defaultimp.maxBatchSize = m_spec->batch_size_max;
461 
462  // optimizations
463  TerrainPSSMMaterialGenerator::SM2Profile* matProfile = nullptr;
464  if (custom_mat.empty())
465  {
466  matProfile = static_cast<TerrainPSSMMaterialGenerator::SM2Profile*>(terrainOptions->getDefaultMaterialGenerator()->getActiveProfile());
467  if (matProfile)
468  {
469  matProfile->setLightmapEnabled(m_spec->lightmap_enabled);
470  // Fix for OpenGL, otherwise terrains are black
471  if (Root::getSingleton().getRenderSystem()->getName() == "OpenGL Rendering Subsystem")
472  {
473  matProfile->setLayerNormalMappingEnabled(true);
474  matProfile->setLayerSpecularMappingEnabled(true);
475  }
476  else
477  {
478  matProfile->setLayerNormalMappingEnabled(m_spec->norm_map_enabled);
479  matProfile->setLayerSpecularMappingEnabled(m_spec->spec_map_enabled);
480  }
481  matProfile->setLayerParallaxMappingEnabled(m_spec->parallax_enabled);
482  matProfile->setGlobalColourMapEnabled(m_spec->global_colormap_enabled);
483  matProfile->setReceiveDynamicShadowsDepth(m_spec->recv_dyn_shadows_depth);
484 
486  }
487  }
488 
489  terrainOptions->setLayerBlendMapSize (m_spec->layer_blendmap_size);
490  terrainOptions->setCompositeMapSize (m_spec->composite_map_size);
491  terrainOptions->setCompositeMapDistance(m_spec->composite_map_distance);
492  terrainOptions->setSkirtSize (m_spec->skirt_size);
493  terrainOptions->setLightMapSize (m_spec->lightmap_size);
494 
495  if (custom_mat.empty())
496  {
497  if (matProfile->getReceiveDynamicShadowsPSSM())
498  {
499  terrainOptions->setCastsDynamicShadows(true);
500  }
501  }
502 
503  terrainOptions->setUseRayBoxDistanceCalculation(false);
504 
505  //TODO: Make this only when hydrax is enabled.
506  terrainOptions->setUseVertexCompressionWhenAvailable(false);
507 
508  // HACK: Load the single page config now
509  // This is how it "worked before" ~ only_a_ptr, 04/2017
510  if (!m_spec->pages.empty())
511  {
512  this->SetupLayers(*m_spec->pages.begin(), nullptr);
513  }
514 }
515 
516 // if terrain is set, we operate on the already loaded terrain
517 void TerrainGeometryManager::SetupLayers(RoR::OTCPage& page, Ogre::Terrain *terrain)
518 {
519  if (page.num_layers == 0)
520  return;
521 
522  Ogre::Terrain::ImportData& defaultimp = m_ogre_terrain_group->getDefaultImportSettings();
523 
524  if (!terrain)
525  defaultimp.layerList.resize(page.num_layers);
526 
527  int layer_idx = 0;
528 
529  for (OTCLayer& layer : page.layers)
530  {
531  if (!terrain)
532  {
533  defaultimp.layerList[layer_idx].worldSize = layer.world_size;
534  defaultimp.layerList[layer_idx].textureNames.push_back(layer.diffusespecular_filename);
535  defaultimp.layerList[layer_idx].textureNames.push_back(layer.normalheight_filename);
536  }
537  else
538  {
539  terrain->setLayerWorldSize(layer_idx, layer.world_size);
540  terrain->setLayerTextureName(layer_idx, 0, layer.diffusespecular_filename);
541  terrain->setLayerTextureName(layer_idx, 1, layer.normalheight_filename);
542  }
543 
544  layer_idx++;
545  }
546  LOG("done loading page: loaded " + TOSTRING(layer_idx) + " layers");
547 }
548 
549 void TerrainGeometryManager::SetupBlendMaps(OTCPage& page, Ogre::Terrain* terrain )
550 {
551  const int layerCount = terrain->getLayerCount();
552  auto layer_def_itor = page.layers.begin();
553 
554  if (page.layers.size() < 2)
555  {
556  LOG(fmt::format("[RoR|Terrain] Page {}-{} has no blend layers defined, blendmap will not be set up.", page.pos_x, page.pos_z));
557  return;
558  }
559 
560  ++layer_def_itor;
561  for (int i = 1; i < layerCount; i++)
562  {
563  if (layer_def_itor->blendmap_filename.empty())
564  continue;
565 
566  Ogre::Image img;
567  try
568  {
569  img.load(layer_def_itor->blendmap_filename, ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME);
570  }
571  catch (Exception& e)
572  {
573  LOG("Error loading blendmap: " + layer_def_itor->blendmap_filename + " : " + e.getFullDescription());
574  continue;
575  }
576 
577  TerrainLayerBlendMap* blendmap = terrain->getLayerBlendMap(i);
578 
579  // resize that blending map so it will fit
580  const Ogre::uint32 blendmapSize = terrain->getLayerBlendMapSize();
581  if (img.getWidth() != blendmapSize)
582  img.resize(blendmapSize, blendmapSize);
583 
584  // now to the ugly part
585  float* ptr = blendmap->getBlendPointer();
586  for (Ogre::uint32 z = 0; z != blendmapSize; z++)
587  {
588  for (Ogre::uint32 x = 0; x != blendmapSize; x++)
589  {
590  Ogre::ColourValue c = img.getColourAt(x, z, 0);
591  const float alpha = layer_def_itor->alpha;
592  if (layer_def_itor->blend_mode == 'R')
593  *ptr++ = c.r * alpha;
594  else if (layer_def_itor->blend_mode == 'G')
595  *ptr++ = c.g * alpha;
596  else if (layer_def_itor->blend_mode == 'B')
597  *ptr++ = c.b * alpha;
598  else if (layer_def_itor->blend_mode == 'A')
599  *ptr++ = c.a * alpha;
600  }
601  }
602  blendmap->dirty();
603  blendmap->update();
604  ++layer_def_itor;
605  }
606 
607  if (m_spec->blendmap_dbg_enabled)
608  {
609  for (int i = 1; i < layerCount; i++)
610  {
611  Ogre::TerrainLayerBlendMap* blendMap = terrain->getLayerBlendMap(i);
612  Ogre::uint32 blendmapSize = terrain->getLayerBlendMapSize();
613  Ogre::Image img;
614  unsigned short* idata = OGRE_ALLOC_T(unsigned short, blendmapSize * blendmapSize, Ogre::MEMCATEGORY_RESOURCE);
615  float scale = 65535.0f;
616  for (unsigned int x = 0; x < blendmapSize; x++)
617  for (unsigned int z = 0; z < blendmapSize; z++)
618  idata[x + z * blendmapSize] = (unsigned short)(blendMap->getBlendValue(x, blendmapSize - z) * scale);
619  img.loadDynamicImage((Ogre::uchar*)(idata), blendmapSize, blendmapSize, Ogre::PF_L16);
620  std::string fileName = "blendmap_layer_" + Ogre::StringConverter::toString(i) + ".png";
621  img.save(fileName);
622  OGRE_FREE(idata, Ogre::MEMCATEGORY_RESOURCE);
623  }
624  }
625 }
626 
627 // Internal helper
628 bool LoadHeightmap(OTCPage& page, Image& img)
629 {
630  if (page.heightmap_filename.empty())
631  {
632  LOG("[RoR|Terrain] Empty Heightmap provided in OTC, please use 'Flat=1' instead");
633  return false;
634  }
635 
636  if (page.heightmap_filename.find(".raw") != String::npos)
637  {
638  // load raw data
639  DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource(page.heightmap_filename);
640  LOG("[RoR|Terrain] loading RAW image: " + TOSTRING(stream->size()) + " / " + TOSTRING(page.raw_size*page.raw_size*page.raw_bpp));
641  PixelFormat pix_format = (page.raw_bpp == 2) ? PF_L16 : PF_L8;
642  img.loadRawData(stream, page.raw_size, page.raw_size, 1, pix_format);
643  }
644  else
645  {
646  img.load(page.heightmap_filename, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
647  }
648 
649  if (page.raw_flip_x)
650  img.flipAroundX();
651  if (page.raw_flip_y)
652  img.flipAroundY();
653 
654  return true;
655 }
656 
658 {
659  if (flat)
660  {
661  // very simple, no height data to load at all
662  m_ogre_terrain_group->defineTerrain(page.pos_x, page.pos_z, 0.0f);
663  return;
664  }
665 
666  const std::string page_cache_filename = m_ogre_terrain_group->generateFilename(page.pos_x, page.pos_z);
667  const std::string res_group = m_ogre_terrain_group->getResourceGroup();
668  if (!m_spec->disable_cache && ResourceGroupManager::getSingleton().resourceExists(res_group, page_cache_filename))
669  {
670  // load from cache
671  m_ogre_terrain_group->defineTerrain(page.pos_x, page.pos_z);
672  }
673  else
674  {
675  Image img;
676  if (LoadHeightmap(page, img))
677  {
678  m_ogre_terrain_group->defineTerrain(page.pos_x, page.pos_z, &img);
680  }
681  else
682  {
683  // fall back to no heightmap
684  m_ogre_terrain_group->defineTerrain(page.pos_x, page.pos_z, 0.0f);
685  }
686  }
687 }
688 
690 {
691  return Vector3(m_spec->world_size_x, mMaxHeight, m_spec->world_size_z);
692 }
693 
Terrn2CustomMaterial::Profile::Profile
Profile(Ogre::TerrainMaterialGenerator *parent, const Ogre::String &name, const Ogre::String &desc)
Definition: TerrainGeometryManager.cpp:65
set
set(SOURCE_FILES main.cpp Application.{h, cpp} ForwardDeclarations.h AppContext.{h, cpp} GameContext.{h, cpp} audio/MumbleIntegration.{h, cpp} audio/Sound.{h, cpp} audio/SoundManager.{h, cpp} audio/SoundScriptManager.{h, cpp} gameplay/AutoPilot.{h, cpp} gameplay/Character.{h, cpp} gameplay/CharacterFactory.{h, cpp} gameplay/ChatSystem.{h, cpp} gameplay/CruiseControl.cpp gameplay/EngineSim.{h, cpp} gameplay/Landusemap.{h, cpp} gameplay/RaceSystem.{h, cpp} gameplay/RepairMode.{h, cpp} gameplay/Replay.{h, cpp} gameplay/SceneMouse.{h, cpp} gameplay/ScriptEvents.h gameplay/TorqueCurve.{h, cpp} gameplay/TyrePressure.{h, cpp} gameplay/VehicleAI.{h, cpp} gfx/AdvancedScreen.h gfx/ColoredTextAreaOverlayElement.{h, cpp} gfx/ColoredTextAreaOverlayElementFactory.h gfx/DustPool.{h, cpp} gfx/EnvironmentMap.{h, cpp} gfx/GfxActor.{h, cpp} gfx/GfxData.{h, cpp} gfx/GfxScene.{h, cpp} gfx/HydraxWater.{h, cpp} gfx/IWater.h gfx/MovableText.{h, cpp} gfx/Renderdash.{h, cpp} gfx/ShadowManager.{h, cpp} gfx/SimBuffers.{h, cpp} gfx/Skidmark.{h, cpp} gfx/SkyManager.{h, cpp} gfx/SkyXManager.{h, cpp} gfx/SurveyMapTextureCreator.{h, cpp} gfx/Water.{h, cpp} gfx/camera/CameraManager.{h, cpp} gfx/camera/PerVehicleCameraContext.h gfx/hydrax/CfgFileManager.{h, cpp} gfx/hydrax/DecalsManager.{h, cpp} gfx/hydrax/Enums.{h, cpp} gfx/hydrax/FFT.{h, cpp} gfx/hydrax/GodRaysManager.{h, cpp} gfx/hydrax/GPUNormalMapManager.{h, cpp} gfx/hydrax/Help.{h, cpp} gfx/hydrax/Hydrax.{h, cpp} gfx/hydrax/Image.{h, cpp} gfx/hydrax/MaterialManager.{h, cpp} gfx/hydrax/Mesh.{h, cpp} gfx/hydrax/Module.{h, cpp} gfx/hydrax/Noise.{h, cpp} gfx/hydrax/Perlin.{h, cpp} gfx/hydrax/Prerequisites.{h, cpp} gfx/hydrax/PressurePoint.{h, cpp} gfx/hydrax/ProjectedGrid.{h, cpp} gfx/hydrax/RadialGrid.{h, cpp} gfx/hydrax/Real.{h, cpp} gfx/hydrax/RttManager.{h, cpp} gfx/hydrax/SimpleGrid.{h, cpp} gfx/hydrax/TextureManager.{h, cpp} gfx/hydrax/Wave.{h, cpp} gfx/particle/ExtinguishableFireAffector.{h, cpp} gfx/particle/ExtinguishableFireAffectorFactory.h gfx/particle/FireExtinguisherAffector.{h, cpp} gfx/particle/FireExtinguisherAffectorFactory.h gfx/particle/OgreParticleCustomParam.h gfx/particle/OgreShaderParticleRenderer.{h, cpp} gfx/skyx/AtmosphereManager.{h, cpp} gfx/skyx/BasicController.{h, cpp} gfx/skyx/CloudsManager.{h, cpp} gfx/skyx/ColorGradient.{h, cpp} gfx/skyx/Controller.h gfx/skyx/GPUManager.{h, cpp} gfx/skyx/MeshManager.{h, cpp} gfx/skyx/MoonManager.{h, cpp} gfx/skyx/Prerequisites.{h, cpp} gfx/skyx/SCfgFileManager.{h, cpp} gfx/skyx/SkyX.{h, cpp} gfx/skyx/VCloudsManager.{h, cpp} gfx/skyx/VClouds/DataManager.{h, cpp} gfx/skyx/VClouds/Ellipsoid.{h, cpp} gfx/skyx/VClouds/FastFakeRandom.{h, cpp} gfx/skyx/VClouds/GeometryBlock.{h, cpp} gfx/skyx/VClouds/GeometryManager.{h, cpp} gfx/skyx/VClouds/Lightning.{h, cpp} gfx/skyx/VClouds/LightningManager.{h, cpp} gfx/skyx/VClouds/VClouds.{h, cpp} gui/DashBoardManager.{h, cpp} gui/GUIManager.{h, cpp} gui/GUIUtils.{h, cpp} gui/OverlayWrapper.{h, cpp} gui/RTTLayer.{h, cpp} gui/imgui/imgui.{h, cpp} gui/imgui/imgui_demo.cpp gui/imgui/imgui_draw.cpp gui/imgui/imgui_widgets.cpp gui/imgui/OgreImGuiOverlay.{h, cpp} gui/imgui/OgreImGui.{h, cpp} gui/imgui/imconfig.h gui/imgui/imgui_internal.h gui/imgui/imstb_rectpack.h gui/imgui/imstb_textedit.h gui/imgui/imstb_truetype.h gui/panels/GUI_AngelScriptExamples.{h, cpp} gui/panels/GUI_CollisionsDebug.{h, cpp} gui/panels/GUI_ConsoleView.{h, cpp} gui/panels/GUI_ConsoleWindow.{h, cpp} gui/panels/GUI_DirectionArrow.{h, cpp} gui/panels/GUI_LoadingWindow.{h, cpp} gui/panels/GUI_FlexbodyDebug.{h, cpp} gui/panels/GUI_FrictionSettings.{h, cpp} gui/panels/GUI_TopMenubar.{h, cpp} gui/panels/GUI_TextureToolWindow.{h, cpp} gui/panels/GUI_RepositorySelector.{h, cpp} gui/panels/GUI_GameControls.{h, cpp} gui/panels/GUI_GameAbout.{h, cpp} gui/panels/GUI_GameChatBox.{h, cpp} gui/panels/GUI_GameMainMenu.{h, cpp} gui/panels/GUI_GameSettings.{h, cpp} gui/panels/GUI_MainSelector.{h, cpp} gui/panels/GUI_MessageBox.{h, cpp} gui/panels/GUI_MultiplayerSelector.{h, cpp} gui/panels/GUI_MultiplayerClientList.{h, cpp} gui/panels/GUI_NodeBeamUtils.{h, cpp} gui/panels/GUI_VehicleInfoTPanel.{h, cpp} gui/panels/GUI_ScriptMonitor.{h, cpp} gui/panels/GUI_SimPerfStats.{h, cpp} gui/panels/GUI_SurveyMap.{h, cpp} network/CurlHelpers.{h, cpp} network/DiscordRpc.{h, cpp} network/Network.{h, cpp} network/OutGauge.{h, cpp} network/RoRnet.h physics/Actor.{h, cpp} physics/ApproxMath.h physics/ActorForcesEuler.cpp physics/ActorManager.{h, cpp} physics/ActorSlideNode.cpp physics/ActorSpawner.{h, cpp} physics/ActorSpawnerFlow.cpp physics/CmdKeyInertia.{h, cpp} physics/Differentials.{h, cpp} physics/Savegame.cpp physics/SimConstants.h physics/SimData.{h, cpp} physics/SlideNode.{h, cpp} physics/air/AeroEngine.h physics/air/AirBrake.{h, cpp} physics/air/Airfoil.{h, cpp} physics/air/TurboJet.{h, cpp} physics/air/TurboProp.{h, cpp} physics/collision/CartesianToTriangleTransform.h physics/collision/Collisions.{h, cpp} physics/collision/DynamicCollisions.{h, cpp} physics/collision/PointColDetector.{h, cpp} physics/collision/Triangle.h physics/flex/Flexable.h physics/flex/FlexAirfoil.{h, cpp} physics/flex/FlexBody.{h, cpp} physics/flex/FlexFactory.{h, cpp} physics/flex/FlexMesh.{h, cpp} physics/flex/FlexMeshWheel.{h, cpp} physics/flex/FlexObj.{h, cpp} physics/flex/Locator_t.h physics/water/Buoyance.{h, cpp} physics/water/ScrewProp.{h, cpp} resources/CacheSystem.{h, cpp} resources/ContentManager.{h, cpp} resources/addonpart_fileformat/AddonPartFileFormat.{h, cpp} resources/otc_fileformat/OTCFileFormat.{h, cpp} resources/odef_fileformat/ODefFileFormat.{h, cpp} resources/rig_def_fileformat/RigDef_File.{h, cpp} resources/rig_def_fileformat/RigDef_Node.{h, cpp} resources/rig_def_fileformat/RigDef_Parser.{h, cpp} resources/rig_def_fileformat/RigDef_Prerequisites.h resources/rig_def_fileformat/RigDef_Regexes.h resources/rig_def_fileformat/RigDef_SequentialImporter.{h, cpp} resources/rig_def_fileformat/RigDef_Serializer.{h, cpp} resources/rig_def_fileformat/RigDef_Validator.{h, cpp} resources/skin_fileformat/SkinFileFormat.{h, cpp} resources/terrn2_fileformat/Terrn2FileFormat.{h, cpp} resources/tobj_fileformat/TObjFileFormat.{h, cpp} resources/tuneup_fileformat/TuneupFileFormat.{h, cpp} system/AppCommandLine.cpp system/AppConfig.cpp system/Console.{h, cpp} system/ConsoleCmd.{h, cpp} system/CVar.{h, cpp} terrain/OgreTerrainPSSMMaterialGenerator.{h, cpp} terrain/ProceduralManager.{h, cpp} terrain/ProceduralRoad.{h, cpp} terrain/SurveyMapEntity.h terrain/TerrainEditor.{h, cpp} terrain/TerrainGeometryManager.{h, cpp} terrain/Terrain.{h, cpp} terrain/TerrainObjectManager.{h, cpp} threadpool/ThreadPool.h utils/ConfigFile.{h, cpp} utils/ErrorUtils.{h, cpp} utils/ForceFeedback.{h, cpp} utils/GenericFileFormat.{h, cpp} utils/ImprovedConfigFile.h utils/InputEngine.{h, cpp} utils/InterThreadStoreVector.h utils/Language.{h, cpp} utils/MeshObject.{h, cpp} utils/PlatformUtils.{h, cpp} utils/SHA1.{h, cpp} utils/Utils.{h, cpp} utils/WriteTextToTexture.{h, cpp} utils/memory/RefCountingObject.h utils/memory/RefCountingObjectPtr.h) if(ROR_USE_ANGELSCRIPT) list(APPEND SOURCE_FILES scripting/GameScript.
Definition: CMakeLists.txt:5
RoR::TerrainGeometryManager::mScale
Ogre::Real mScale
Definition: TerrainGeometryManager.h:80
RoR::OTCLayer::world_size
float world_size
Definition: OTCFileFormat.h:44
RGN_CACHE
#define RGN_CACHE
Definition: Application.h:46
Terrn2CustomMaterial
Definition: TerrainGeometryManager.cpp:45
y
float y
Definition: (ValueTypes) quaternion.h:6
RoR::OTCLayer::diffusespecular_filename
std::string diffusespecular_filename
Definition: OTCFileFormat.h:40
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::setLayerNormalMappingEnabled
void setLayerNormalMappingEnabled(bool enabled)
Whether to support normal mapping per layer in the shader (default true).
Definition: OgreTerrainPSSMMaterialGenerator.cpp:111
RoR::TerrainGeometryManager::mBase
Ogre::Real mBase
Definition: TerrainGeometryManager.h:79
RoR::OTCLayer
Definition: OTCFileFormat.h:35
RoR::App::GetGuiManager
GUIManager * GetGuiManager()
Definition: Application.cpp:269
OTCFileFormat.h
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::setGlobalColourMapEnabled
void setGlobalColourMapEnabled(bool enabled)
Whether to support a global colour map over the terrain in the shader, if it's present (default true)...
Definition: OgreTerrainPSSMMaterialGenerator.cpp:141
z
float z
Definition: (ValueTypes) quaternion.h:7
RoR::OTCPage::pos_z
int pos_z
Definition: OTCFileFormat.h:54
ContentManager.h
RoR::OTCPage::raw_size
int raw_size
Definition: OTCFileFormat.h:56
RoR::Terrn2Def::custom_material_name
std::string custom_material_name
Definition: Terrn2FileFormat.h:76
RoR::Terrain::getShadowManager
ShadowManager * getShadowManager()
Definition: Terrain.h:81
RoR::TerrainGeometryManager::getNormalAt
Ogre::Vector3 getNormalAt(float x, float y, float z)
Definition: TerrainGeometryManager.cpp:247
format
Truck file format(technical spec)
RoR::OTCPage::num_layers
int num_layers
Definition: OTCFileFormat.h:53
RoR::OTCParser
Definition: OTCFileFormat.h:93
RoR::HandleGenericException
void HandleGenericException(const std::string &from, BitMask_t flags)
Definition: Application.cpp:369
RoR::TerrainGeometryManager::~TerrainGeometryManager
~TerrainGeometryManager()
Definition: TerrainGeometryManager.cpp:149
TerrainGeometryManager.h
Terrn2CustomMaterial::setMaterialByName
void setMaterialByName(const Ogre::String materialName)
Definition: TerrainGeometryManager.cpp:56
RoR::Terrain::GetDef
Terrn2Def & GetDef()
Definition: Terrain.h:63
RoR::LogFormat
void LogFormat(const char *format,...)
Improved logging utility. Uses fixed 2Kb buffer.
Definition: Application.cpp:424
RoR::TerrainGeometryManager::getHeightAt
float getHeightAt(float x, float z)
Definition: TerrainGeometryManager.cpp:231
Terrn2CustomMaterial::Profile::~Profile
~Profile() override
Definition: TerrainGeometryManager.cpp:69
RoR::OTCPage::heightmap_filename
std::string heightmap_filename
Definition: OTCFileFormat.h:52
OgreTerrainPSSMMaterialGenerator.h
RoR::TerrainGeometryManager::mMinHeight
float mMinHeight
Definition: TerrainGeometryManager.h:85
Terrn2CustomMaterial::Profile::updateParamsForCompositeMap
void updateParamsForCompositeMap(const Ogre::MaterialPtr &mat, const Ogre::Terrain *terrain) override
Definition: TerrainGeometryManager.cpp:76
RoR::TerrainGeometryManager::terrainManager
RoR::Terrain * terrainManager
Definition: TerrainGeometryManager.h:73
RoR::TerrainGeometryManager::getHeightAtTerrainPosition
float getHeightAtTerrainPosition(float x, float z)
Definition: TerrainGeometryManager.cpp:158
Terrn2CustomMaterial::Profile::getMaxLayers
Ogre::uint8 getMaxLayers(const Ogre::Terrain *terrain) const override
Definition: TerrainGeometryManager.cpp:74
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::setLightmapEnabled
void setLightmapEnabled(bool enabled)
Whether to support a light map over the terrain in the shader, if it's present (default true).
Definition: OgreTerrainPSSMMaterialGenerator.cpp:151
RoR::TerrainGeometryManager::SetupGeometry
void SetupGeometry(RoR::OTCPage &page, bool flat=false)
Definition: TerrainGeometryManager.cpp:657
Language.h
RoR::TerrainGeometryManager::updateLightMap
void updateLightMap()
Definition: TerrainGeometryManager.cpp:388
GUIManager.h
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::getReceiveDynamicShadowsPSSM
PSSMShadowCameraSetup * getReceiveDynamicShadowsPSSM() const
Whether to use PSSM support dynamic texture shadows, and if so the settings to use (default 0).
Definition: OgreTerrainPSSMMaterialGenerator.h:130
RoR::TerrainGeometryManager::configureTerrainDefaults
void configureTerrainDefaults()
Definition: TerrainGeometryManager.cpp:420
Actor.h
RoR::ShadowManager::updateTerrainMaterial
void updateTerrainMaterial(Ogre::TerrainPSSMMaterialGenerator::SM2Profile *matProfile)
Definition: ShadowManager.cpp:165
RoR::GUIManager::LoadingWindow
GUI::LoadingWindow LoadingWindow
Definition: GUIManager.h:119
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::setLayerParallaxMappingEnabled
void setLayerParallaxMappingEnabled(bool enabled)
Whether to support parallax mapping per layer in the shader (default true).
Definition: OgreTerrainPSSMMaterialGenerator.cpp:121
Terrn2CustomMaterial::Profile::setLightmapEnabled
void setLightmapEnabled(bool set)
Definition: TerrainGeometryManager.cpp:72
RoR::TerrainGeometryManager::mIsFlat
bool mIsFlat
Definition: TerrainGeometryManager.h:84
TOSTRING
#define TOSTRING(x)
Definition: Application.h:56
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::setReceiveDynamicShadowsDepth
void setReceiveDynamicShadowsDepth(bool enabled)
Whether to use depth shadows (default false).
Definition: OgreTerrainPSSMMaterialGenerator.cpp:191
RoR::TerrainGeometryManager::getMaxTerrainSize
Ogre::Vector3 getMaxTerrainSize()
Definition: TerrainGeometryManager.cpp:689
Terrn2CustomMaterial::m_clone_material
bool m_clone_material
Definition: TerrainGeometryManager.cpp:94
Terrn2CustomMaterial::Terrn2CustomMaterial
Terrn2CustomMaterial(Ogre::String materialName, bool addNormalmap, bool cloneMaterial)
Definition: TerrainGeometryManager.cpp:49
GUI_LoadingWindow.h
Ogre::TerrainPSSMMaterialGenerator::SM2Profile::setLayerSpecularMappingEnabled
void setLayerSpecularMappingEnabled(bool enabled)
Whether to support specular mapping per layer in the shader (default true).
Definition: OgreTerrainPSSMMaterialGenerator.cpp:131
RoR::OTCParser::LoadPageConfig
bool LoadPageConfig(Ogre::DataStreamPtr &ds, OTCPage &page, const char *filename)
Definition: OTCFileFormat.cpp:106
LoadHeightmap
bool LoadHeightmap(OTCPage &page, Image &img)
Definition: TerrainGeometryManager.cpp:628
RoR::OTCPage
Definition: OTCFileFormat.h:47
RoR::TerrainGeometryManager::InitTerrain
bool InitTerrain(std::string otc_filename)
Definition: TerrainGeometryManager.cpp:255
RoR::TerrainGeometryManager::UpdateMainLightPosition
void UpdateMainLightPosition()
Definition: TerrainGeometryManager.cpp:406
RoR::GUI::LoadingWindow::SetProgress
void SetProgress(int _percent, const std::string &_text="", bool render_frame=true)
Definition: GUI_LoadingWindow.cpp:33
GfxScene.h
Application.h
Central state/object manager and communications hub.
RoR::OTCLayer::normalheight_filename
std::string normalheight_filename
Definition: OTCFileFormat.h:41
Terrn2CustomMaterial::Profile::isVertexCompressionSupported
bool isVertexCompressionSupported() const
Definition: TerrainGeometryManager.cpp:71
RoR::OTCParser::LoadMasterConfig
bool LoadMasterConfig(Ogre::DataStreamPtr &ds, const char *filename)
Definition: OTCFileFormat.cpp:39
RoR::TerrainGeometryManager::m_was_new_geometry_generated
bool m_was_new_geometry_generated
Definition: TerrainGeometryManager.h:75
RoR::TerrainGeometryManager::m_spec
std::shared_ptr< RoR::OTCFile > m_spec
Definition: TerrainGeometryManager.h:72
Terrn2CustomMaterial::Profile::generate
Ogre::MaterialPtr generate(const Ogre::Terrain *terrain) override
Definition: TerrainGeometryManager.cpp:98
Terrn2CustomMaterial::Profile::generateForCompositeMap
Ogre::MaterialPtr generateForCompositeMap(const Ogre::Terrain *terrain) override
Definition: TerrainGeometryManager.cpp:78
Terrn2CustomMaterial::Profile
Definition: TerrainGeometryManager.cpp:62
RoR::TerrainGeometryManager::m_ogre_terrain_group
Ogre::TerrainGroup * m_ogre_terrain_group
Definition: TerrainGeometryManager.h:74
Terrn2CustomMaterial::Profile::updateParams
void updateParams(const Ogre::MaterialPtr &mat, const Ogre::Terrain *terrain) override
Definition: TerrainGeometryManager.cpp:75
RoR::OTCPage::raw_flip_y
bool raw_flip_y
Definition: OTCFileFormat.h:55
Terrn2CustomMaterial::m_material_name
Ogre::String m_material_name
Definition: TerrainGeometryManager.cpp:93
ShadowManager.h
RoR::Terrn2Def::water_bottom_height
float water_bottom_height
Definition: Terrn2FileFormat.h:61
RoR::OTCPage::raw_flip_x
bool raw_flip_x
Definition: OTCFileFormat.h:55
RoR::Terrain
Definition: Terrain.h:40
RoR::OTCParser::GetDefinition
std::shared_ptr< OTCFile > GetDefinition()
Definition: OTCFileFormat.h:100
RoR::TerrainGeometryManager::mSize
Ogre::uint16 mSize
Definition: TerrainGeometryManager.h:81
_L
#define _L
Definition: ErrorUtils.cpp:34
RoR::TerrainGeometryManager::mPos
Ogre::Vector3 mPos
Definition: TerrainGeometryManager.h:78
RoR::TerrainGeometryManager::mHeightData
float * mHeightData
Definition: TerrainGeometryManager.h:82
RoR::TerrainGeometryManager::mMaxHeight
float mMaxHeight
Definition: TerrainGeometryManager.h:86
Terrain.h
Ogre
Definition: ExtinguishableFireAffector.cpp:35
RoR::Terrain::getMainLight
Ogre::Light * getMainLight()
Definition: Terrain.h:89
Terrn2CustomMaterial::m_add_normal_map
bool m_add_normal_map
Definition: TerrainGeometryManager.cpp:95
Ogre::TerrainPSSMMaterialGenerator
A TerrainMaterialGenerator which can cope with normal mapped, specular mapped terrain.
Definition: OgreTerrainPSSMMaterialGenerator.h:44
Ogre::TerrainPSSMMaterialGenerator::SM2Profile
Shader model 2 profile target.
Definition: OgreTerrainPSSMMaterialGenerator.h:52
RoR::TerrainGeometryManager::SetupBlendMaps
void SetupBlendMaps(RoR::OTCPage &page, Ogre::Terrain *t)
Definition: TerrainGeometryManager.cpp:549
RoR::OTCPage::raw_bpp
int raw_bpp
Definition: OTCFileFormat.h:56
Terrn2CustomMaterial::Profile::requestOptions
void requestOptions(Ogre::Terrain *terrain) override
Definition: TerrainGeometryManager.cpp:83
CUSTOM_MAT_PROFILE_NAME
#define CUSTOM_MAT_PROFILE_NAME
Definition: TerrainGeometryManager.cpp:42
RoR::OTCPage::pos_x
int pos_x
Definition: OTCFileFormat.h:54
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::TerrainGeometryManager::SetupLayers
void SetupLayers(RoR::OTCPage &page, Ogre::Terrain *terrain)
Definition: TerrainGeometryManager.cpp:517
RoR::App::GetGfxScene
GfxScene * GetGfxScene()
Definition: Application.cpp:276