Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
TerrainDescriptor.cpp
Go to the documentation of this file.
2
4namespace Divide
5{
6 namespace
7 {
8 constexpr U8 g_minTerrainSideLength = 8u;
9 }
10
11void Init( TerrainDescriptor& descriptor, const std::string_view name)
12{
13 descriptor._name = name;
15 {
16 entry.fill( VECTOR2_UNIT );
17 }
18}
19
20bool LoadFromXML( TerrainDescriptor& descriptor, const boost::property_tree::ptree& pt, const std::string_view name )
21{
22 const ResourcePath terrainDescriptorPath = ResourcePath{ pt.get<string>( "descriptor", "" ) };
23
24 if ( terrainDescriptorPath.empty() )
25 {
26 return false;
27 }
28
29 AddVariable( descriptor, "terrainName", name );
30 AddVariable( descriptor, "descriptor", terrainDescriptorPath.string() );
31 AddVariable( descriptor, "waterCaustics", pt.get<string>( "waterCaustics" ) );
32 AddVariable( descriptor, "underwaterAlbedoTexture", pt.get<string>( "underwaterAlbedoTexture", "sandfloor009a.jpg" ) );
33 AddVariable( descriptor, "underwaterDetailTexture", pt.get<string>( "underwaterDetailTexture", "terrain_detail_NM.png" ) );
34 AddVariable( descriptor, "tileNoiseTexture", pt.get<string>( "tileNoiseTexture", "bruit_gaussien_2.jpg" ) );
35 AddVariableF( descriptor, "underwaterTileScale", pt.get<F32>( "underwaterTileScale", 1.0f ) );
36 ResourcePath alphaMapDescriptor;
37 {
38 boost::property_tree::ptree descTree = {};
39 XML::readXML( Paths::g_heightmapLocation / terrainDescriptorPath / "descriptor.xml", descTree );
40
41 AddVariable( descriptor, "heightfield", descTree.get<string>( "heightfield", "" ) );
42 AddVariable( descriptor, "heightfieldTex", descTree.get<string>( "heightfieldTex", "" ) );
43
44 descriptor._dimensions.set( descTree.get<U16>( "heightfieldResolution.<xmlattr>.x", 0 ),
45 descTree.get<U16>( "heightfieldResolution.<xmlattr>.y", 0 ) );
46
47 descriptor._ringCount = to_U8( std::max( descTree.get<U8>( "tileSettings.<xmlattr>.ringCount", 4u ) + 1u, 2u ) );
48 descriptor._startWidth = descTree.get<F32>( "tileSettings.<xmlattr>.startWidth", 0.25f );
49 descriptor._ringTileCount[0] = 0u;
50
51 U8 prevSize = 8u;
52 for ( U8 i = 1; i < descriptor._ringCount; ++i )
53 {
54 descriptor._ringTileCount[i] = (descTree.get<U8>( Util::StringFormat( "tileSettings.<xmlattr>.ring{}", i ).c_str(), prevSize ));
55 prevSize = descriptor._ringTileCount[i];
56 }
57 if ( descriptor._dimensions.minComponent() < g_minTerrainSideLength )
58 {
59 return false;
60 }
61 descriptor._altitudeRange.set( descTree.get<F32>( "altitudeRange.<xmlattr>.min", 0.0f ),
62 descTree.get<F32>( "altitudeRange.<xmlattr>.max", 255.0f ) );
63
64 AddVariable( descriptor, "grassMap", descTree.get<string>( "vegetation.grassMap" ) );
65 AddVariable( descriptor, "treeMap", descTree.get<string>( "vegetation.treeMap" ) );
66
67 for ( I32 j = 1; j < 5; ++j )
68 {
69 AddVariable( descriptor, Util::StringFormat( "grassBillboard{}", j ), descTree.get<string>( Util::StringFormat( "vegetation.grassBillboard{}", j ).c_str(), "" ) );
70 AddVariable( descriptor, Util::StringFormat( "treeMesh{}", j ), descTree.get<string>( Util::StringFormat( "vegetation.treeMesh{}", j ).c_str(), "" ) );
71 AddVariableF( descriptor, Util::StringFormat( "grassScale{}", j ), descTree.get<F32>( Util::StringFormat( "vegetation.grassBillboard{}.<xmlattr>.scale", j ).c_str(), 1.0f ) );
72 AddVariableF( descriptor, Util::StringFormat( "treeScale{}", j ), descTree.get<F32>( Util::StringFormat( "vegetation.treeMesh{}.<xmlattr>.scale", j ).c_str(), 1.0f ) );
73 AddVariableF( descriptor, Util::StringFormat( "treeRotationX{}", j ), descTree.get<F32>( Util::StringFormat( "vegetation.treeMesh{}.<xmlattr>.rotate_x", j ).c_str(), 0.0f ) );
74 AddVariableF( descriptor, Util::StringFormat( "treeRotationY{}", j ), descTree.get<F32>( Util::StringFormat( "vegetation.treeMesh{}.<xmlattr>.rotate_y", j ).c_str(), 0.0f ) );
75 AddVariableF( descriptor, Util::StringFormat( "treeRotationZ{}", j ), descTree.get<F32>( Util::StringFormat( "vegetation.treeMesh{}.<xmlattr>.rotate_z", j ).c_str(), 0.0f ) );
76 }
77
78 alphaMapDescriptor = ResourcePath{ descTree.get<string>( "alphaMaps.<xmlattr>.file", "" ) };
79 for ( boost::property_tree::ptree::iterator itLayerData = std::begin( descTree.get_child( "alphaMaps" ) );
80 itLayerData != std::end( descTree.get_child( "alphaMaps" ) );
81 ++itLayerData )
82 {
83 const string format( itLayerData->first );
84 if ( format.find( "<xmlcomment>" ) != string::npos || format.find( "<xmlattr>" ) != string::npos )
85 {
86 continue;
87 }
88
89 const U8 matIndex = itLayerData->second.get<U8>( "<xmlattr>.material", 0u );
90 if ( matIndex < descriptor._layerDataEntries.size() )
91 {
93
94 const U8 layerIndex = itLayerData->second.get<U8>( "<xmlattr>.channel", 0u );
95 if ( layerIndex < 4 )
96 {
97 vec2<F32>& tileFactors = entry[layerIndex];
98 tileFactors.s = CLAMPED( itLayerData->second.get( "<xmlattr>.s", 1.f ), 1.f, 255.f );
99 tileFactors.t = CLAMPED( itLayerData->second.get( "<xmlattr>.t", 1.f ), 1.f, 255.f );
100 }
101 }
102 }
103 }
104
105 if ( alphaMapDescriptor.empty() )
106 {
107 return false;
108 }
109
110 {
111 boost::property_tree::ptree alphaTree = {};
112 XML::readXML( Paths::g_heightmapLocation / terrainDescriptorPath / alphaMapDescriptor, alphaTree );
113
114 const U8 numLayers = alphaTree.get<U8>( "AlphaData.nImages" );
115 const U8 numImages = alphaTree.get<U8>( "AlphaData.nLayers" );
116 if ( numLayers == 0 || numImages == 0 )
117 {
118 return false;
119 }
120
121 descriptor._textureLayers = numLayers;
122
123 const std::string imageListNode = "AlphaData.ImageList";
124 I32 i = 0;
125 string blendMap;
126 std::array<string, 4> arrayMaterials;
127 string layerOffsetStr;
128 for ( boost::property_tree::ptree::iterator itImage = std::begin( alphaTree.get_child( imageListNode ) );
129 itImage != std::end( alphaTree.get_child( imageListNode ) );
130 ++itImage, ++i )
131 {
132 string layerName( itImage->second.data() );
133 string format( itImage->first );
134
135 if ( format.find( "<xmlcomment>" ) != string::npos || format.find( "<xmlattr>" ) != string::npos )
136 {
137 i--;
138 continue;
139 }
140
141 layerOffsetStr = Util::to_string( i );
142 AddVariable( descriptor, "blendMap" + layerOffsetStr, stripQuotes( itImage->second.get<std::string>( "FileName", "" ).c_str() ) );
143
144 for ( boost::property_tree::ptree::iterator itLayer = std::begin( itImage->second.get_child( "LayerList" ) );
145 itLayer != std::end( itImage->second.get_child( "LayerList" ) );
146 ++itLayer )
147 {
148 if ( string( itLayer->first ).find( "<xmlcomment>" ) != string::npos )
149 {
150 continue;
151 }
152
153 string layerColour = itLayer->second.get<string>( "LayerColour", "" );
154 string materialName;
155 for ( boost::property_tree::ptree::iterator itMaterial = std::begin( itLayer->second.get_child( "MtlList" ) );
156 itMaterial != std::end( itLayer->second.get_child( "MtlList" ) );
157 ++itMaterial )
158 {
159 if ( string( itMaterial->first ).find( "<xmlcomment>" ) != string::npos )
160 {
161 continue;
162 }
163
164 materialName = itMaterial->second.data();
165 // Only one material per channel!
166 break;
167 }
168
169 AddVariable( descriptor, layerColour + layerOffsetStr + "_mat", materialName );
170 }
171 }
172 }
173
174 return true;
175}
176
177void SaveToXML( const TerrainDescriptor& descriptor, boost::property_tree::ptree& pt)
178{
179 pt.put( "descriptor", GetVariable( descriptor, "descriptor" ) );
180 pt.put( "waterCaustics", GetVariable( descriptor, "waterCaustics" ) );
181 pt.put( "underwaterAlbedoTexture", GetVariable( descriptor, "underwaterAlbedoTexture" ) );
182 pt.put( "underwaterDetailTexture", GetVariable( descriptor, "underwaterDetailTexture" ) );
183 pt.put( "tileNoiseTexture", GetVariable( descriptor, "tileNoiseTexture" ) );
184 pt.put( "underwaterTileScale", GetVariableF( descriptor, "underwaterTileScale" ) );
185}
186
187void AddVariable( TerrainDescriptor& descriptor, const std::string_view name, const std::string_view value )
188{
189 descriptor._variables[_ID(name)] = value;
190}
191
192void AddVariableF( TerrainDescriptor& descriptor, const std::string_view name, const F32 value )
193{
194 descriptor._variablesf[_ID( name )] = value;
195}
196
197string GetVariable( const TerrainDescriptor& descriptor, const std::string_view name )
198{
199 auto it = descriptor._variables.find( _ID( name ) );
200 if ( it != std::end( descriptor. _variables ) )
201 {
202 return it->second;
203 }
204
205 return "";
206}
207
208 F32 GetVariableF( const TerrainDescriptor& descriptor, const std::string_view name )
209{
210 const auto it = descriptor._variablesf.find( _ID( name ) );
211 if ( it != std::end( descriptor._variablesf ) )
212 {
213 return it->second;
214 }
215 return 0.f;
216}
217
218U32 MaxNodesPerStage( const TerrainDescriptor& descriptor ) noexcept
219{
220 // Quadtree, so assume worst case scenario
221 return descriptor._dimensions.maxComponent() / 4;
222}
223
224[[nodiscard]] U8 TileRingCount( const TerrainDescriptor& descriptor, const U8 index ) noexcept
225{
226 DIVIDE_ASSERT( index < descriptor._ringCount );
227
228 return descriptor._ringTileCount[index];
229}
230
231} //namespace Divide
#define DIVIDE_ASSERT(...)
T minComponent() const noexcept
get the smallest value of X or Y
void set(const T *v) noexcept
set the 2 components of the vector manually using a source pointer to a (large enough) array
Definition: MathVectors.h:335
Str StringFormat(const char *fmt, Args &&...args)
string to_string(GET_PASS_TYPE< T > value)
void readXML(const ResourcePath &path, boost::property_tree::ptree &tree)
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
U32 MaxNodesPerStage(const TerrainDescriptor &descriptor) noexcept
static const vec2< F32 > VECTOR2_UNIT
Definition: MathVectors.h:1436
void AddVariable(TerrainDescriptor &descriptor, std::string_view name, std::string_view value)
int32_t I32
uint8_t U8
F32 GetVariableF(const TerrainDescriptor &descriptor, std::string_view name)
void SaveToXML(const TerrainDescriptor &descriptor, boost::property_tree::ptree &pt)
bool LoadFromXML(TerrainDescriptor &descriptor, const boost::property_tree::ptree &pt, std::string_view name)
uint16_t U16
constexpr U64 _ID(const char *const str, const U64 value=val_64_const) noexcept
constexpr U8 to_U8(const T value)
::value constexpr T CLAMPED(T n, T min, T max) noexcept
Definition: MathHelper.inl:126
string GetVariable(const TerrainDescriptor &descriptor, std::string_view name)
void AddVariableF(TerrainDescriptor &descriptor, std::string_view name, F32 value)
void Init(ImTextureID texture1, ImTextureID texture2, ImTextureID dockTexture)
uint32_t U32
Project const SceneEntry & entry
Definition: DefaultScene.h:41
U8 TileRingCount(const TerrainDescriptor &descriptor, const U8 index) noexcept
string stripQuotes(const std::string_view input)
std::array< vec2< F32 >, 4 > LayerDataEntry
StringReturnType< N > string() const noexcept
Definition: ResourcePath.h:64
bool empty() const noexcept