RigsofRods
Soft-body Physics Simulation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 "Terrn2FileFormat.h"
33 #include "ShadowManager.h"
35 #include "OTCFileFormat.h"
36 
37 #include <OgreLight.h>
38 #include <Terrain/OgreTerrainGroup.h>
39 
40 using namespace Ogre;
41 using namespace RoR;
42 
43 #define CUSTOM_MAT_PROFILE_NAME "Terrn2CustomMat"
44 
46 class Terrn2CustomMaterial : public Ogre::TerrainMaterialGenerator
47 {
48 public:
49 
50  Terrn2CustomMaterial(Ogre::String materialName, bool addNormalmap, bool cloneMaterial)
51  : m_material_name(materialName), m_add_normal_map(addNormalmap), m_clone_material(cloneMaterial)
52  {
53  mProfiles.push_back(OGRE_NEW Profile(this, CUSTOM_MAT_PROFILE_NAME, "Renders RoR terrn2 with custom material"));
54  this->setActiveProfile(CUSTOM_MAT_PROFILE_NAME);
55  }
56 
57  void setMaterialByName(const Ogre::String materialName)
58  {
59  m_material_name = materialName;
60  this->_markChanged();
61  };
62 
63  class Profile : public Ogre::TerrainMaterialGenerator::Profile
64  {
65  public:
66  Profile(Ogre::TerrainMaterialGenerator* parent, const Ogre::String& name, const Ogre::String& desc)
67  : Ogre::TerrainMaterialGenerator::Profile(parent, name, desc)
68  {
69  };
70  ~Profile() override {};
71 
72  bool isVertexCompressionSupported () const { return false; }
73  void setLightmapEnabled (bool set) /*override*/ {} // OGRE 1.8 doesn't have this method
74  Ogre::MaterialPtr generate (const Ogre::Terrain* terrain) override;
75  Ogre::uint8 getMaxLayers (const Ogre::Terrain* terrain) const override { return 0; };
76  void updateParams (const Ogre::MaterialPtr& mat, const Ogre::Terrain* terrain) override {};
77  void updateParamsForCompositeMap (const Ogre::MaterialPtr& mat, const Ogre::Terrain* terrain) override {};
78 
79  Ogre::MaterialPtr generateForCompositeMap(const Ogre::Terrain* terrain) override
80  {
81  return terrain->_getCompositeMapMaterial();
82  };
83 
84  void requestOptions(Ogre::Terrain* terrain) override
85  {
86  terrain->_setMorphRequired(false);
87  terrain->_setNormalMapRequired(true); // enable global normal map
88  terrain->_setLightMapRequired(false);
89  terrain->_setCompositeMapRequired(false);
90  };
91  };
92 
93 protected:
94  Ogre::String m_material_name;
97 };
98 
99 Ogre::MaterialPtr Terrn2CustomMaterial::Profile::generate(const Ogre::Terrain* terrain)
100 {
101  const Ogre::String& matName = terrain->getMaterialName();
102 
103  Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().getByName(matName);
104  if (!mat.isNull())
105  Ogre::MaterialManager::getSingleton().remove(matName);
106 
107  Terrn2CustomMaterial* parent = static_cast<Terrn2CustomMaterial*>(this->getParent());
108 
109  // Set Ogre material
110  mat = Ogre::MaterialManager::getSingleton().getByName(parent->m_material_name);
111 
112  // Clone material
113  if(parent->m_clone_material)
114  {
115  mat = mat->clone(matName);
116  parent->m_material_name = matName;
117  }
118 
119  // Add normalmap
120  if(parent->m_add_normal_map)
121  {
122  // Get default pass
123  Ogre::Pass *p = mat->getTechnique(0)->getPass(0);
124 
125  // Add terrain's global normalmap to renderpass so the fragment program can find it.
126  Ogre::TextureUnitState *tu = p->createTextureUnitState(matName+"/nm");
127 
128  Ogre::TexturePtr nmtx = terrain->getTerrainNormalMap();
129  tu->_setTexturePtr(nmtx);
130  }
131 
132  return mat;
133 };
134 
135 // ----------------------------------------------------------------------------
136 
137 #define XZSTR(X,Z) String("[") + TOSTRING(X) + String(",") + TOSTRING(Z) + String("]")
138 
139 TerrainGeometryManager::TerrainGeometryManager(Terrain* terrainManager)
140  : mHeightData(nullptr)
141  , mIsFlat(false)
142  , mMinHeight(0.0f)
143  , mMaxHeight(std::numeric_limits<float>::min())
144  , m_was_new_geometry_generated(false)
145  , terrainManager(terrainManager)
146  , m_ogre_terrain_group(nullptr)
147 {
148 }
149 
151 {
152  if (m_ogre_terrain_group != nullptr)
153  {
154  m_ogre_terrain_group->removeAllTerrains();
155  }
156 }
157 
160 {
161  // get left / bottom points (rounded down)
162  Real factor = (Real)mSize - 1.0f;
163  Real invFactor = 1.0f / factor;
164 
165  long startX = static_cast<long>(x * factor);
166  long startY = static_cast<long>(y * factor);
167  long endX = startX + 1;
168  long endY = startY + 1;
169 
170  // now get points in terrain space (effectively rounding them to boundaries)
171  // note that we do not clamp! We need a valid plane
172  Real startXTS = startX * invFactor;
173  Real startYTS = startY * invFactor;
174  Real endXTS = endX * invFactor;
175  Real endYTS = endY * invFactor;
176 
177  // get parametric from start coord to next point
178  Real xParam = (x * factor - startX);
179  Real yParam = (y * factor - startY);
180 
181  /* For even / odd tri strip rows, triangles are this shape:
182  even odd
183  3---2 3---2
184  | / | | \ |
185  0---1 0---1
186  */
187 
188  // Build all 4 positions in terrain space, using point-sampled height
189  Vector3 v0(startXTS, startYTS, mHeightData[startY * mSize + startX]);
190  Vector3 v1(endXTS , startYTS, mHeightData[startY * mSize + endX]);
191  Vector3 v2(endXTS , endYTS , mHeightData[endY * mSize + endX]);
192  Vector3 v3(startXTS, endYTS , mHeightData[endY * mSize + startX]);
193 
194  // define this plane in terrain space
195  Vector3 normal;
196  Real d;
197  if (startY % 2)
198  {
199  // odd row
200  bool secondTri = ((1.0 - yParam) > xParam);
201  if (secondTri)
202  {
203  normal = (v1 - v0).crossProduct(v3 - v0);
204  d = -normal.dotProduct(v0);
205  }
206  else
207  {
208  normal = (v2 - v1).crossProduct(v3 - v1);
209  d = -normal.dotProduct(v1);
210  }
211  }
212  else
213  {
214  // even row
215  bool secondTri = (yParam > xParam);
216  if (secondTri)
217  {
218  normal = (v2 - v0).crossProduct(v3 - v0);
219  d = -normal.dotProduct(v0);
220  }
221  else
222  {
223  normal = (v1 - v0).crossProduct(v2 - v0);
224  d = -normal.dotProduct(v0);
225  }
226  }
227 
228  // Solve plane equation for z
229  return (-normal.x * x - normal.y * y - d) / normal.z;
230 }
231 
233 {
234  if (m_spec->is_flat)
235  return 0.0f;
236 
237  float tx = (x - mBase - mPos.x) / ((mSize - 1) * mScale);
238  float ty = (z + mBase - mPos.z) / ((mSize - 1) * -mScale);
239 
240  if (tx <= 0.0f || ty <= 0.0f || tx >= 1.0f || ty >= 1.0f)
241  return terrainManager->GetDef()->water_bottom_height;
242  else if (mIsFlat)
243  return mMinHeight;
244 
245  return getHeightAtTerrainPosition(tx, ty);
246 }
247 
248 Ogre::Vector3 TerrainGeometryManager::getNormalAt(float x, float y, float z)
249 {
250  const float precision = 0.1f;
251  Vector3 normal(getHeightAt(x - precision, z) - y, precision, y - getHeightAt(x, z + precision));
252  normal.normalise();
253  return normal;
254 }
255 
256 bool TerrainGeometryManager::InitTerrain(std::string otc_filename)
257 {
258  OTCParser otc_parser;
259 
260  // Load main *.otc file
261  try
262  {
263  DataStreamPtr ds_config = ResourceGroupManager::getSingleton().openResource(otc_filename);
264  if (ds_config.isNull() || !ds_config->isReadable())
265  {
266  RoR::LogFormat("[RoR|Terrain] Cannot read main *.otc file [%s].", otc_filename.c_str());
267  return false;
268  }
269  if (!otc_parser.LoadMasterConfig(ds_config, otc_filename.c_str()))
270  {
271  return false; // Error already reported
272  }
273  }
274  catch (...)
275  {
276  RoR::HandleGenericException(fmt::format("TerrainGeometryManager::InitTerrain({})", otc_filename));
277  // If we stop parsing we might break some legacy maps
278  //return false;
279  }
280 
281  // Load *.otc files for pages
282  for (OTCPage& page : otc_parser.GetDefinition()->pages)
283  {
284  if (page.pageconf_filename.empty())
285  {
286  continue; // For backwards compatibility.
287  }
288 
289  try
290  {
291  DataStreamPtr ds_page = ResourceGroupManager::getSingleton().openResource(page.pageconf_filename);
292  if (ds_page.isNull() || !ds_page->isReadable())
293  {
294  RoR::LogFormat("[RoR|Terrain] Cannot read file [%s].", page.pageconf_filename.c_str());
295  return false;
296  }
297 
298  // NOTE: Empty file is accepted (leaving all values to defaults) for backwards compatibility.
299  if (!otc_parser.LoadPageConfig(ds_page, page, page.pageconf_filename.c_str()))
300  {
301  return false; // Error already logged
302  }
303  }
304  catch (...)
305  {
306  RoR::HandleGenericException(fmt::format("TerrainGeometryManager::InitTerrain({})", page.pageconf_filename));
307  // If we stop parsing we might break some legacy maps
308  // return false;
309  }
310  }
311 
312  m_spec = otc_parser.GetDefinition();
313 
314  const std::string cache_filename_format = m_spec->cache_filename_base + "_OGRE_" + TOSTRING(OGRE_VERSION) + "_";
315 
316  m_ogre_terrain_group = OGRE_NEW TerrainGroup(App::GetGfxScene()->GetSceneManager(), Ogre::Terrain::ALIGN_X_Z, m_spec->page_size, m_spec->world_size);
317  m_ogre_terrain_group->setFilenameConvention(cache_filename_format, "mapbin");
318  m_ogre_terrain_group->setOrigin(m_spec->origin_pos);
319  m_ogre_terrain_group->setResourceGroup(RGN_CACHE);
320 
322 
323  for (OTCPage& page : m_spec->pages)
324  {
325  this->SetupGeometry(page, m_spec->is_flat);
326  }
327 
328  // sync load since we want everything in place when we start
329  App::GetGuiManager()->LoadingWindow.SetProgress(44, _L("Loading terrain pages ..."));
330  m_ogre_terrain_group->loadAllTerrains(true);
331 
332  Ogre::Terrain* terrain = m_ogre_terrain_group->getTerrain(0, 0);
333 
334  if (terrain == nullptr)
335  return true;
336 
337  mHeightData = terrain->getHeightData();
338  mSize = terrain->getSize();
339  const float world_size = terrain->getWorldSize();
340  mBase = -world_size * 0.5f;
341  mScale = world_size / (Real)(mSize - 1);
342  mPos = terrain->getPosition();
343 
344  // terrain->getMinHeight() / terrain->getMaxHeight() seem to be unreliable ~ ulteq 12/18
345  for (int x = 0; x < mSize; x++)
346  {
347  for (int y = 0; y < mSize; y++)
348  {
349  float h = mHeightData[y * mSize + x];
350  mMinHeight = std::min(h, mMinHeight);
351  mMaxHeight = std::max(mMaxHeight, h);
352  }
353  }
354  mIsFlat = std::abs(mMaxHeight - mMinHeight) < std::numeric_limits<float>::epsilon();
355 
357  {
358  // update the blend maps
359  if (terrainManager->GetDef()->custom_material_name.empty())
360  {
361  for (OTCPage& page : m_spec->pages)
362  {
363  Ogre::Terrain* terrain = m_ogre_terrain_group->getTerrain(page.pos_x, page.pos_z);
364 
365  if (terrain != nullptr)
366  {
367  this->SetupLayers(page, terrain);
368  this->SetupBlendMaps(page, terrain);
369  }
370  }
371  }
372 
373  // always save the results when it was imported
374  if (!m_spec->disable_cache)
375  {
376  App::GetGuiManager()->LoadingWindow.SetProgress(50, _L("Saving all terrain pages ..."));
377  m_ogre_terrain_group->saveAllTerrains(false);
378  }
379  }
380  else
381  {
382  LOG(" *** Terrain loaded from cache ***");
383  }
384 
385  m_ogre_terrain_group->freeTemporaryResources();
386  return true;
387 }
388 
390 {
391  TerrainGroup::TerrainIterator ti = m_ogre_terrain_group->getTerrainIterator();
392 
393  while (ti.hasMoreElements())
394  {
395  Ogre::Terrain* terrain = ti.getNext()->instance;
396  if (!terrain)
397  continue;
398 
399  if (!terrain->isDerivedDataUpdateInProgress())
400  {
401  terrain->dirtyLightmap();
402  terrain->updateDerivedData();
403  }
404  }
405 }
406 
408 {
409  Light* light = terrainManager->getMainLight();
410  TerrainGlobalOptions* terrainOptions = TerrainGlobalOptions::getSingletonPtr();
411  if (light)
412  {
413  terrainOptions->setLightMapDirection(light->getDerivedDirection());
414  terrainOptions->setCompositeMapDiffuse(light->getDiffuseColour());
415  }
416  terrainOptions->setCompositeMapAmbient(App::GetGfxScene()->GetSceneManager()->getAmbientLight());
417 
418  m_ogre_terrain_group->update();
419 }
420 
422 {
423  if (!TerrainGlobalOptions::getSingletonPtr())
424  {
425  OGRE_NEW TerrainGlobalOptions();
426  }
427 
428  TerrainGlobalOptions* terrainOptions = TerrainGlobalOptions::getSingletonPtr();
429  std::string const & custom_mat = terrainManager->GetDef()->custom_material_name;
430  if (!custom_mat.empty())
431  {
432  terrainOptions->setDefaultMaterialGenerator(
433  Ogre::TerrainMaterialGeneratorPtr(new Terrn2CustomMaterial(custom_mat, false, true)));
434  }
435  else
436  {
437  terrainOptions->setDefaultMaterialGenerator(
438  Ogre::TerrainMaterialGeneratorPtr(new Ogre::TerrainPSSMMaterialGenerator()));
439  }
440  // Configure global
441  terrainOptions->setMaxPixelError(m_spec->max_pixel_error);
442 
443  // Important to set these so that the terrain knows what to use for derived (non-realtime) data
444  Light* light = terrainManager->getMainLight();
445  if (light)
446  {
447  terrainOptions->setLightMapDirection(light->getDerivedDirection());
448  if (custom_mat.empty())
449  {
450  terrainOptions->setCompositeMapDiffuse(light->getDiffuseColour());
451  }
452  }
453  terrainOptions->setCompositeMapAmbient(App::GetGfxScene()->GetSceneManager()->getAmbientLight());
454 
455  // Configure default import settings for if we use imported image
456  Ogre::Terrain::ImportData& defaultimp = m_ogre_terrain_group->getDefaultImportSettings();
457  defaultimp.terrainSize = m_spec->page_size; // the heightmap size
458  defaultimp.worldSize = m_spec->world_size; // this is the scaled up size, like 12km
459  defaultimp.inputScale = m_spec->world_size_y;
460  defaultimp.minBatchSize = m_spec->batch_size_min;
461  defaultimp.maxBatchSize = m_spec->batch_size_max;
462 
463  // optimizations
464  TerrainPSSMMaterialGenerator::SM2Profile* matProfile = nullptr;
465  if (custom_mat.empty())
466  {
467  matProfile = static_cast<TerrainPSSMMaterialGenerator::SM2Profile*>(terrainOptions->getDefaultMaterialGenerator()->getActiveProfile());
468  if (matProfile)
469  {
470  matProfile->setLightmapEnabled(m_spec->lightmap_enabled);
471  // Fix for OpenGL, otherwise terrains are black
472  if (Root::getSingleton().getRenderSystem()->getName() == "OpenGL Rendering Subsystem")
473  {
474  matProfile->setLayerNormalMappingEnabled(true);
475  matProfile->setLayerSpecularMappingEnabled(true);
476  }
477  else
478  {
479  matProfile->setLayerNormalMappingEnabled(m_spec->norm_map_enabled);
480  matProfile->setLayerSpecularMappingEnabled(m_spec->spec_map_enabled);
481  }
482  matProfile->setLayerParallaxMappingEnabled(m_spec->parallax_enabled);
483  matProfile->setGlobalColourMapEnabled(m_spec->global_colormap_enabled);
484  matProfile->setReceiveDynamicShadowsDepth(m_spec->recv_dyn_shadows_depth);
485 
487  }
488  }
489 
490  terrainOptions->setLayerBlendMapSize (m_spec->layer_blendmap_size);
491  terrainOptions->setCompositeMapSize (m_spec->composite_map_size);
492  terrainOptions->setCompositeMapDistance(m_spec->composite_map_distance);
493  terrainOptions->setSkirtSize (m_spec->skirt_size);
494  terrainOptions->setLightMapSize (m_spec->lightmap_size);
495 
496  if (custom_mat.empty())
497  {
498  if (matProfile->getReceiveDynamicShadowsPSSM())
499  {
500  terrainOptions->setCastsDynamicShadows(true);
501  }
502  }
503 
504  terrainOptions->setUseRayBoxDistanceCalculation(false);
505 
506  //TODO: Make this only when hydrax is enabled.
507  terrainOptions->setUseVertexCompressionWhenAvailable(false);
508 
509  // HACK: Load the single page config now
510  // This is how it "worked before" ~ only_a_ptr, 04/2017
511  if (!m_spec->pages.empty())
512  {
513  this->SetupLayers(*m_spec->pages.begin(), nullptr);
514  }
515 }
516 
517 // if terrain is set, we operate on the already loaded terrain
518 void TerrainGeometryManager::SetupLayers(RoR::OTCPage& page, Ogre::Terrain *terrain)
519 {
520  if (page.num_layers == 0)
521  return;
522 
523  Ogre::Terrain::ImportData& defaultimp = m_ogre_terrain_group->getDefaultImportSettings();
524 
525  if (!terrain)
526  defaultimp.layerList.resize(page.num_layers);
527 
528  int layer_idx = 0;
529 
530  for (OTCLayer& layer : page.layers)
531  {
532  if (!terrain)
533  {
534  defaultimp.layerList[layer_idx].worldSize = layer.world_size;
535  defaultimp.layerList[layer_idx].textureNames.push_back(layer.diffusespecular_filename);
536  defaultimp.layerList[layer_idx].textureNames.push_back(layer.normalheight_filename);
537  }
538  else
539  {
540  terrain->setLayerWorldSize(layer_idx, layer.world_size);
541  terrain->setLayerTextureName(layer_idx, 0, layer.diffusespecular_filename);
542  terrain->setLayerTextureName(layer_idx, 1, layer.normalheight_filename);
543  }
544 
545  layer_idx++;
546  }
547  LOG("done loading page: loaded " + TOSTRING(layer_idx) + " layers");
548 }
549 
550 void TerrainGeometryManager::SetupBlendMaps(OTCPage& page, Ogre::Terrain* terrain )
551 {
552  const int layerCount = terrain->getLayerCount();
553  auto layer_def_itor = page.layers.begin();
554 
555  if (page.layers.size() < 2)
556  {
557  LOG(fmt::format("[RoR|Terrain] Page {}-{} has no blend layers defined, blendmap will not be set up.", page.pos_x, page.pos_z));
558  return;
559  }
560 
561  ++layer_def_itor;
562  for (int i = 1; i < layerCount; i++)
563  {
564  if (layer_def_itor->blendmap_filename.empty())
565  continue;
566 
567  Ogre::Image img;
568  try
569  {
570  img.load(layer_def_itor->blendmap_filename, ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME);
571  }
572  catch (Exception& e)
573  {
574  LOG("Error loading blendmap: " + layer_def_itor->blendmap_filename + " : " + e.getFullDescription());
575  continue;
576  }
577 
578  TerrainLayerBlendMap* blendmap = terrain->getLayerBlendMap(i);
579 
580  // resize that blending map so it will fit
581  const Ogre::uint32 blendmapSize = terrain->getLayerBlendMapSize();
582  if (img.getWidth() != blendmapSize)
583  img.resize(blendmapSize, blendmapSize);
584 
585  // now to the ugly part
586  float* ptr = blendmap->getBlendPointer();
587  for (Ogre::uint32 z = 0; z != blendmapSize; z++)
588  {
589  for (Ogre::uint32 x = 0; x != blendmapSize; x++)
590  {
591  Ogre::ColourValue c = img.getColourAt(x, z, 0);
592  const float alpha = layer_def_itor->alpha;
593  if (layer_def_itor->blend_mode == 'R')
594  *ptr++ = c.r * alpha;
595  else if (layer_def_itor->blend_mode == 'G')
596  *ptr++ = c.g * alpha;
597  else if (layer_def_itor->blend_mode == 'B')
598  *ptr++ = c.b * alpha;
599  else if (layer_def_itor->blend_mode == 'A')
600  *ptr++ = c.a * alpha;
601  }
602  }
603  blendmap->dirty();
604  blendmap->update();
605  ++layer_def_itor;
606  }
607 
608  if (m_spec->blendmap_dbg_enabled)
609  {
610  for (int i = 1; i < layerCount; i++)
611  {
612  Ogre::TerrainLayerBlendMap* blendMap = terrain->getLayerBlendMap(i);
613  Ogre::uint32 blendmapSize = terrain->getLayerBlendMapSize();
614  Ogre::Image img;
615  unsigned short* idata = OGRE_ALLOC_T(unsigned short, blendmapSize * blendmapSize, Ogre::MEMCATEGORY_RESOURCE);
616  float scale = 65535.0f;
617  for (unsigned int x = 0; x < blendmapSize; x++)
618  for (unsigned int z = 0; z < blendmapSize; z++)
619  idata[x + z * blendmapSize] = (unsigned short)(blendMap->getBlendValue(x, blendmapSize - z) * scale);
620  img.loadDynamicImage((Ogre::uchar*)(idata), blendmapSize, blendmapSize, Ogre::PF_L16);
621  std::string fileName = "blendmap_layer_" + Ogre::StringConverter::toString(i) + ".png";
622  img.save(fileName);
623  OGRE_FREE(idata, Ogre::MEMCATEGORY_RESOURCE);
624  }
625  }
626 }
627 
628 // Internal helper
629 bool LoadHeightmap(OTCPage& page, Image& img)
630 {
631  if (page.heightmap_filename.empty())
632  {
633  LOG("[RoR|Terrain] Empty Heightmap provided in OTC, please use 'Flat=1' instead");
634  return false;
635  }
636 
637  if (page.heightmap_filename.find(".raw") != String::npos)
638  {
639  // load raw data
640  DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource(page.heightmap_filename);
641  LOG("[RoR|Terrain] loading RAW image: " + TOSTRING(stream->size()) + " / " + TOSTRING(page.raw_size*page.raw_size*page.raw_bpp));
642  PixelFormat pix_format = (page.raw_bpp == 2) ? PF_L16 : PF_L8;
643  img.loadRawData(stream, page.raw_size, page.raw_size, 1, pix_format);
644  }
645  else
646  {
647  img.load(page.heightmap_filename, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
648  }
649 
650  if (page.raw_flip_x)
651  img.flipAroundX();
652  if (page.raw_flip_y)
653  img.flipAroundY();
654 
655  return true;
656 }
657 
659 {
660  if (flat)
661  {
662  // very simple, no height data to load at all
663  m_ogre_terrain_group->defineTerrain(page.pos_x, page.pos_z, 0.0f);
664  return;
665  }
666 
667  const std::string page_cache_filename = m_ogre_terrain_group->generateFilename(page.pos_x, page.pos_z);
668  const std::string res_group = m_ogre_terrain_group->getResourceGroup();
669  if (!m_spec->disable_cache && ResourceGroupManager::getSingleton().resourceExists(res_group, page_cache_filename))
670  {
671  // load from cache
672  m_ogre_terrain_group->defineTerrain(page.pos_x, page.pos_z);
673  }
674  else
675  {
676  Image img;
677  if (LoadHeightmap(page, img))
678  {
679  m_ogre_terrain_group->defineTerrain(page.pos_x, page.pos_z, &img);
681  }
682  else
683  {
684  // fall back to no heightmap
685  m_ogre_terrain_group->defineTerrain(page.pos_x, page.pos_z, 0.0f);
686  }
687  }
688 }
689 
691 {
692  return Vector3(m_spec->world_size_x, mMaxHeight, m_spec->world_size_z);
693 }
694 
Terrn2CustomMaterial::Profile::Profile
Profile(Ogre::TerrainMaterialGenerator *parent, const Ogre::String &name, const Ogre::String &desc)
Definition: TerrainGeometryManager.cpp:66
RoR::Terrain::GetDef
Terrn2DocumentPtr GetDef()
Definition: Terrain.cpp:578
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:46
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:272
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::Terrain::getShadowManager
ShadowManager * getShadowManager()
Definition: Terrain.h:80
RoR::TerrainGeometryManager::getNormalAt
Ogre::Vector3 getNormalAt(float x, float y, float z)
Definition: TerrainGeometryManager.cpp:248
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:372
RoR::TerrainGeometryManager::~TerrainGeometryManager
~TerrainGeometryManager()
Definition: TerrainGeometryManager.cpp:150
TerrainGeometryManager.h
Terrn2FileFormat.h
Terrn2CustomMaterial::setMaterialByName
void setMaterialByName(const Ogre::String materialName)
Definition: TerrainGeometryManager.cpp:57
RoR::LogFormat
void LogFormat(const char *format,...)
Improved logging utility. Uses fixed 2Kb buffer.
Definition: Application.cpp:427
RoR::TerrainGeometryManager::getHeightAt
float getHeightAt(float x, float z)
Definition: TerrainGeometryManager.cpp:232
Terrn2CustomMaterial::Profile::~Profile
~Profile() override
Definition: TerrainGeometryManager.cpp:70
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:77
RoR::TerrainGeometryManager::terrainManager
RoR::Terrain * terrainManager
Definition: TerrainGeometryManager.h:73
RoR::TerrainGeometryManager::getHeightAtTerrainPosition
float getHeightAtTerrainPosition(float x, float z)
Definition: TerrainGeometryManager.cpp:159
Terrn2CustomMaterial::Profile::getMaxLayers
Ogre::uint8 getMaxLayers(const Ogre::Terrain *terrain) const override
Definition: TerrainGeometryManager.cpp:75
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:658
Language.h
RoR::TerrainGeometryManager::updateLightMap
void updateLightMap()
Definition: TerrainGeometryManager.cpp:389
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:421
Actor.h
RoR::ShadowManager::updateTerrainMaterial
void updateTerrainMaterial(Ogre::TerrainPSSMMaterialGenerator::SM2Profile *matProfile)
Definition: ShadowManager.cpp:165
RoR::GUIManager::LoadingWindow
GUI::LoadingWindow LoadingWindow
Definition: GUIManager.h:130
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:73
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:690
Terrn2CustomMaterial::m_clone_material
bool m_clone_material
Definition: TerrainGeometryManager.cpp:95
Terrn2CustomMaterial::Terrn2CustomMaterial
Terrn2CustomMaterial(Ogre::String materialName, bool addNormalmap, bool cloneMaterial)
Definition: TerrainGeometryManager.cpp:50
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:629
RoR::OTCPage
Definition: OTCFileFormat.h:47
RoR::TerrainGeometryManager::InitTerrain
bool InitTerrain(std::string otc_filename)
Definition: TerrainGeometryManager.cpp:256
RoR::TerrainGeometryManager::UpdateMainLightPosition
void UpdateMainLightPosition()
Definition: TerrainGeometryManager.cpp:407
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:72
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
Terrn2CustomMaterial::Profile::generate
Ogre::MaterialPtr generate(const Ogre::Terrain *terrain) override
Definition: TerrainGeometryManager.cpp:99
Terrn2CustomMaterial::Profile::generateForCompositeMap
Ogre::MaterialPtr generateForCompositeMap(const Ogre::Terrain *terrain) override
Definition: TerrainGeometryManager.cpp:79
Terrn2CustomMaterial::Profile
Definition: TerrainGeometryManager.cpp:63
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:76
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:94
ShadowManager.h
RoR::OTCPage::raw_flip_x
bool raw_flip_x
Definition: OTCFileFormat.h:55
RoR::Terrain
Definition: Terrain.h:39
RoR::TerrainGeometryManager::m_spec
std::shared_ptr< RoR::OTCDocument > m_spec
Definition: TerrainGeometryManager.h:72
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
RoR::OTCParser::GetDefinition
OTCDocumentPtr GetDefinition()
Definition: OTCFileFormat.h:100
Terrain.h
Ogre
Definition: ExtinguishableFireAffector.cpp:35
RoR::Terrain::getMainLight
Ogre::Light * getMainLight()
Definition: Terrain.h:88
Terrn2CustomMaterial::m_add_normal_map
bool m_add_normal_map
Definition: TerrainGeometryManager.cpp:96
Ogre::TerrainPSSMMaterialGenerator
A TerrainMaterialGenerator which can cope with normal mapped, specular mapped terrain.
Definition: OgreTerrainPSSMMaterialGenerator.h:44
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/Engine.{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
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:550
RoR::OTCPage::raw_bpp
int raw_bpp
Definition: OTCFileFormat.h:56
Terrn2CustomMaterial::Profile::requestOptions
void requestOptions(Ogre::Terrain *terrain) override
Definition: TerrainGeometryManager.cpp:84
CUSTOM_MAT_PROFILE_NAME
#define CUSTOM_MAT_PROFILE_NAME
Definition: TerrainGeometryManager.cpp:43
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:518
RoR::App::GetGfxScene
GfxScene * GetGfxScene()
Definition: Application.cpp:279