38#include <Terrain/OgreTerrainGroup.h>
43#define CUSTOM_MAT_PROFILE_NAME "Terrn2CustomMat"
63 class Profile :
public Ogre::TerrainMaterialGenerator::Profile
66 Profile(Ogre::TerrainMaterialGenerator* parent,
const Ogre::String& name,
const Ogre::String& desc)
67 :
Ogre::TerrainMaterialGenerator::
Profile(parent, name, desc)
66 Profile(Ogre::TerrainMaterialGenerator* parent,
const Ogre::String& name,
const Ogre::String& desc) {
…}
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 {};
81 return terrain->_getCompositeMapMaterial();
86 terrain->_setMorphRequired(
false);
87 terrain->_setNormalMapRequired(
true);
88 terrain->_setLightMapRequired(
false);
89 terrain->_setCompositeMapRequired(
false);
63 class Profile :
public Ogre::TerrainMaterialGenerator::Profile {
…};
101 const Ogre::String& matName = terrain->getMaterialName();
103 Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().getByName(matName);
105 Ogre::MaterialManager::getSingleton().remove(matName);
110 mat = Ogre::MaterialManager::getSingleton().getByName(parent->
m_material_name);
115 mat = mat->clone(matName);
123 Ogre::Pass *p = mat->getTechnique(0)->getPass(0);
126 Ogre::TextureUnitState *tu = p->createTextureUnitState(matName+
"/nm");
128 Ogre::TexturePtr nmtx = terrain->getTerrainNormalMap();
129 tu->_setTexturePtr(nmtx);
137#define XZSTR(X,Z) String("[") + TOSTRING(X) + String(",") + TOSTRING(Z) + String("]")
140 : mHeightData(nullptr)
143 , mMaxHeight(std::numeric_limits<float>::min())
144 , m_was_new_geometry_generated(false)
145 , terrainManager(terrainManager)
146 , m_ogre_terrain_group(nullptr)
162 Real factor = (Real)
mSize - 1.0f;
163 Real invFactor = 1.0f / factor;
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;
172 Real startXTS = startX * invFactor;
173 Real startYTS = startY * invFactor;
174 Real endXTS = endX * invFactor;
175 Real endYTS = endY * invFactor;
178 Real xParam = (
x * factor - startX);
179 Real yParam = (
y * factor - startY);
200 bool secondTri = ((1.0 - yParam) > xParam);
203 normal = (v1 - v0).crossProduct(v3 - v0);
204 d = -normal.dotProduct(v0);
208 normal = (v2 - v1).crossProduct(v3 - v1);
209 d = -normal.dotProduct(v1);
215 bool secondTri = (yParam > xParam);
218 normal = (v2 - v0).crossProduct(v3 - v0);
219 d = -normal.dotProduct(v0);
223 normal = (v1 - v0).crossProduct(v2 - v0);
224 d = -normal.dotProduct(v0);
229 return (-normal.x *
x - normal.y *
y - d) / normal.z;
240 if (tx <= 0.0f || ty <= 0.0f || tx >= 1.0f || ty >= 1.0f)
250 const float precision = 0.1f;
263 DataStreamPtr ds_config = ResourceGroupManager::getSingleton().openResource(otc_filename);
264 if (!ds_config || !ds_config->isReadable())
266 RoR::LogFormat(
"[RoR|Terrain] Cannot read main *.otc file [%s].", otc_filename.c_str());
284 if (page.pageconf_filename.empty())
291 DataStreamPtr ds_page = ResourceGroupManager::getSingleton().openResource(page.pageconf_filename);
292 if (!ds_page || !ds_page->isReadable())
294 RoR::LogFormat(
"[RoR|Terrain] Cannot read file [%s].", page.pageconf_filename.c_str());
299 if (!otc_parser.
LoadPageConfig(ds_page, page, page.pageconf_filename.c_str()))
314 const std::string cache_filename_format =
m_spec->cache_filename_base +
"_OGRE_" +
TOSTRING(OGRE_VERSION) +
"_";
334 if (terrain ==
nullptr)
338 mSize = terrain->getSize();
339 const float world_size = terrain->getWorldSize();
340 mBase = -world_size * 0.5f;
342 mPos = terrain->getPosition();
365 if (terrain !=
nullptr)
374 if (!
m_spec->disable_cache)
382 LOG(
" *** Terrain loaded from cache ***");
393 while (ti.hasMoreElements())
395 Ogre::Terrain* terrain = ti.getNext()->instance;
399 if (!terrain->isDerivedDataUpdateInProgress())
401 terrain->dirtyLightmap();
402 terrain->updateDerivedData();
410 TerrainGlobalOptions* terrainOptions = TerrainGlobalOptions::getSingletonPtr();
413 terrainOptions->setLightMapDirection(light->getDerivedDirection());
414 terrainOptions->setCompositeMapDiffuse(light->getDiffuseColour());
416 terrainOptions->setCompositeMapAmbient(
App::GetGfxScene()->GetSceneManager()->getAmbientLight());
423 if (!TerrainGlobalOptions::getSingletonPtr())
425 OGRE_NEW TerrainGlobalOptions();
428 TerrainGlobalOptions* terrainOptions = TerrainGlobalOptions::getSingletonPtr();
430 if (!custom_mat.empty())
432 terrainOptions->setDefaultMaterialGenerator(
437 terrainOptions->setDefaultMaterialGenerator(
441 terrainOptions->setMaxPixelError(
m_spec->max_pixel_error);
447 terrainOptions->setLightMapDirection(light->getDerivedDirection());
448 if (custom_mat.empty())
450 terrainOptions->setCompositeMapDiffuse(light->getDiffuseColour());
453 terrainOptions->setCompositeMapAmbient(
App::GetGfxScene()->GetSceneManager()->getAmbientLight());
457 defaultimp.terrainSize =
m_spec->page_size;
458 defaultimp.worldSize =
m_spec->world_size;
459 defaultimp.inputScale =
m_spec->world_size_y;
460 defaultimp.minBatchSize =
m_spec->batch_size_min;
461 defaultimp.maxBatchSize =
m_spec->batch_size_max;
465 if (custom_mat.empty())
472 if (Root::getSingleton().getRenderSystem()->getName() ==
"OpenGL Rendering Subsystem")
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);
496 if (custom_mat.empty())
500 terrainOptions->setCastsDynamicShadows(
true);
504 terrainOptions->setUseRayBoxDistanceCalculation(
false);
507 terrainOptions->setUseVertexCompressionWhenAvailable(
false);
511 if (!
m_spec->pages.empty())
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);
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);
547 LOG(
"done loading page: loaded " +
TOSTRING(layer_idx) +
" layers");
552 const int layerCount = terrain->getLayerCount();
553 auto layer_def_itor = page.
layers.begin();
555 if (page.
layers.size() < 2)
557 LOG(fmt::format(
"[RoR|Terrain] Page {}-{} has no blend layers defined, blendmap will not be set up.", page.
pos_x, page.
pos_z));
562 for (
int i = 1; i < layerCount; i++)
564 if (layer_def_itor->blendmap_filename.empty())
570 img.load(layer_def_itor->blendmap_filename, ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME);
574 LOG(
"Error loading blendmap: " + layer_def_itor->blendmap_filename +
" : " + e.getFullDescription());
578 TerrainLayerBlendMap* blendmap = terrain->getLayerBlendMap(i);
581 const Ogre::uint32 blendmapSize = terrain->getLayerBlendMapSize();
582 if (img.getWidth() != blendmapSize)
583 img.resize(blendmapSize, blendmapSize);
586 float* ptr = blendmap->getBlendPointer();
587 for (Ogre::uint32
z = 0;
z != blendmapSize;
z++)
589 for (Ogre::uint32
x = 0;
x != blendmapSize;
x++)
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;
608 if (
m_spec->blendmap_dbg_enabled)
610 for (
int i = 1; i < layerCount; i++)
612 Ogre::TerrainLayerBlendMap* blendMap = terrain->getLayerBlendMap(i);
613 Ogre::uint32 blendmapSize = terrain->getLayerBlendMapSize();
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";
623 OGRE_FREE(idata, Ogre::MEMCATEGORY_RESOURCE);
633 LOG(
"[RoR|Terrain] Empty Heightmap provided in OTC, please use 'Flat=1' instead");
640 DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource(page.
heightmap_filename);
642 PixelFormat pix_format = (page.
raw_bpp == 2) ? PF_L16 : PF_L8;
669 if (!
m_spec->disable_cache && ResourceGroupManager::getSingleton().resourceExists(res_group, page_cache_filename))
Central state/object manager and communications hub.
void LOG(const char *msg)
Legacy alias - formerly a macro.
#define CUSTOM_MAT_PROFILE_NAME
bool LoadHeightmap(OTCPage &page, Image &img)
Shader model 2 profile target.
void setReceiveDynamicShadowsDepth(bool enabled)
Whether to use depth shadows (default false).
void setLayerNormalMappingEnabled(bool enabled)
Whether to support normal mapping per layer in the shader (default true).
PSSMShadowCameraSetup * getReceiveDynamicShadowsPSSM() const
Whether to use PSSM support dynamic texture shadows, and if so the settings to use (default 0).
void setLightmapEnabled(bool enabled)
Whether to support a light map over the terrain in the shader, if it's present (default true).
void setLayerSpecularMappingEnabled(bool enabled)
Whether to support specular mapping per layer in the shader (default true).
void setGlobalColourMapEnabled(bool enabled)
Whether to support a global colour map over the terrain in the shader, if it's present (default true)...
void setLayerParallaxMappingEnabled(bool enabled)
Whether to support parallax mapping per layer in the shader (default true).
A TerrainMaterialGenerator which can cope with normal mapped, specular mapped terrain.
void SetProgress(int _percent, const std::string &_text="", bool render_frame=true)
GUI::LoadingWindow LoadingWindow
OTCDocumentPtr GetDefinition()
bool LoadMasterConfig(Ogre::DataStreamPtr &ds, const char *filename)
bool LoadPageConfig(Ogre::DataStreamPtr &ds, OTCPage &page, const char *filename)
void updateTerrainMaterial(Ogre::TerrainPSSMMaterialGenerator::SM2Profile *matProfile)
bool InitTerrain(std::string otc_filename)
void configureTerrainDefaults()
void SetupLayers(RoR::OTCPage &page, Ogre::Terrain *terrain)
~TerrainGeometryManager()
float getHeightAt(float x, float z)
Ogre::TerrainGroup * m_ogre_terrain_group
float getHeightAtTerrainPosition(float x, float z)
TerrainGeometryManager(Terrain *terrainManager)
void UpdateMainLightPosition()
RoR::Terrain * terrainManager
Ogre::Vector3 getNormalAt(float x, float y, float z)
bool m_was_new_geometry_generated
void SetupBlendMaps(RoR::OTCPage &page, Ogre::Terrain *t)
void SetupGeometry(RoR::OTCPage &page, bool flat=false)
std::shared_ptr< RoR::OTCDocument > m_spec
Ogre::Vector3 getMaxTerrainSize()
Ogre::Light * getMainLight()
ShadowManager * getShadowManager()
Terrn2DocumentPtr GetDef()
void requestOptions(Ogre::Terrain *terrain) override
void updateParamsForCompositeMap(const Ogre::MaterialPtr &mat, const Ogre::Terrain *terrain) override
Profile(Ogre::TerrainMaterialGenerator *parent, const Ogre::String &name, const Ogre::String &desc)
Ogre::MaterialPtr generate(const Ogre::Terrain *terrain) override
bool isVertexCompressionSupported() const
void setLightmapEnabled(bool set)
Ogre::uint8 getMaxLayers(const Ogre::Terrain *terrain) const override
void updateParams(const Ogre::MaterialPtr &mat, const Ogre::Terrain *terrain) override
Ogre::MaterialPtr generateForCompositeMap(const Ogre::Terrain *terrain) override
Ogre::String m_material_name
void setMaterialByName(const Ogre::String materialName)
Terrn2CustomMaterial(Ogre::String materialName, bool addNormalmap, bool cloneMaterial)
GUIManager * GetGuiManager()
void HandleGenericException(const std::string &from, BitMask_t flags)
void LogFormat(const char *format,...)
Improved logging utility. Uses fixed 2Kb buffer.
std::list< OTCLayer > layers
std::string heightmap_filename