More namespaces

parent ec56fd4e
......@@ -57,6 +57,7 @@ set( ITAGeoHeader
"include/ITAGeoBase.h"
"include/ITAGeoDefinitions.h"
"include/ITAGeoHalfedgeMeshModel.h"
"include/ITAGeoMaterialManager.h"
"include/ITAGeoModelBase.h"
"include/ITAGeoScene.h"
"include/ITAGeoUtils.h"
......@@ -67,6 +68,7 @@ set( ITAGeoSources
"src/ITAGeoHalfedgeAC3DReader.cpp"
"src/ITAGeoHalfedgeAC3DReader.h"
"src/ITAGeoHalfedgeMeshModel.cpp"
"src/ITAGeoMaterialManager.cpp"
"src/ITAGeoModelBase.cpp"
"src/ITAGeoScene.cpp"
"src/ITAGeoUtils.cpp"
......
This diff is collapsed.
......@@ -34,11 +34,13 @@
#include <string>
#include <vector>
class IITAAcousticMaterial;
class CITAMaterialManager;
namespace ITAGeo
{
class IAcousticMaterial;
class CMaterialManager;
//! A boundary/interaction point in a geometrical acoustics context
/*
* A geometrical propagation anchor defines a point in 3D space where acoustic interaction appears,
......@@ -61,7 +63,7 @@ namespace ITAGeo
} iAnchorType; //! Type of anchor
VistaVector3D v3InteractionPoint; //!< Point of geometric interaction, has to be further defined by deriving class
IITAAcousticMaterial* pAcousticMaterial; //!< Acoustic material connection, i.e. absorption coefficient
IAcousticMaterial* pAcousticMaterial; //!< Acoustic material connection, i.e. absorption coefficient
bool bProtected; //!< Protect this anchor from destruction in DeleteAnchorsAndClear function
CPropagationAnchor();
......@@ -183,7 +185,7 @@ namespace ITAGeo
inline virtual ~CMirrorImage() {};
inline void CopyFromAnchor( const ITAGeo::CPropagationAnchor& oOther, CITAMaterialManager* pManager = nullptr )
inline void CopyFromAnchor( const ITAGeo::CPropagationAnchor& oOther, ITAGeo::CMaterialManager* pManager = nullptr )
{
bProtected = oOther.bProtected;
v3InteractionPoint = oOther.v3InteractionPoint;
......
......@@ -29,7 +29,7 @@
// Forwards
struct ITA_GEO_API CITAMeshPtr;
class IITAAcousticMaterial;
class IAcousticMaterial;
namespace ITAGeo
{
......@@ -132,7 +132,7 @@ namespace ITAGeo
bool TriangulateMesh();
//! Add acoustic material to a face of mesh
bool SetFaceAcousticMaterial( int iFaceID, IITAAcousticMaterial* pMaterial );
bool SetFaceAcousticMaterial( int iFaceID, IAcousticMaterial* pMaterial );
//! Invert normal direction vector of all faces
/**
......
/*
* ----------------------------------------------------------------
*
* ITA geometrical acoustics
* (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2018
*
* ----------------------------------------------------------------
* ____ __________ _______
* // / //__ ___/ // _ |
* // / // / // /_| |
* // / // / // ___ |
* //__/ //__/ //__/ |__|
*
* ----------------------------------------------------------------
*
*/
#ifndef IW_ITA_GEO_MATERIAL_MANAGER
#define IW_ITA_GEO_MATERIAL_MANAGER
// ITAGeo includes
#include <ITAGeoDefinitions.h>
#include <ITAGeoAcousticMaterial.h>
// STL includes
#include <map>
#include <string>
#include <vector>
namespace ITAGeo
{
class IAcousticMaterial;
//! Acoustic material basic manager
class ITA_GEO_API CMaterialManager
{
public:
CMaterialManager();
virtual ~CMaterialManager();
//! Retrieve acoustic material, if available
/**
* @param[in] sMaterialIdentifier Text-based material identifier (usually the name of the material)
* @return Pointer to material or nullptr, if not available
*/
virtual const ITAGeo::IAcousticMaterial* GetMaterial( const std::string& sMaterialIdentifier ) const = 0;
//! Add a material copy, if not already existant
/**
* @return True, if possible, false if already existing or manager is read-only
*/
virtual inline bool AddMaterialCopy( ITAGeo::IAcousticMaterial* pMaterial ) { return false; };
};
//! Acoustic material manager that retrieves data from a folder (checks file endings)
class ITA_GEO_API CMaterialDirectory : public CMaterialManager
{
public:
CMaterialDirectory();
CMaterialDirectory( const std::string& sFolderPath, const bool bRecursive = true );
~CMaterialDirectory();
void AddMaterialsFromFolder( const std::string& sFolderPath, const bool bRecursive = false );
const ITAGeo::IAcousticMaterial* GetMaterial( const std::string& sMaterialIdentifier ) const;
private:
std::map< std::string, ITAGeo::IAcousticMaterial* > m_mMaterials;
};
}
#endif // IW_ITA_GEO_MATERIAL_MANAGER
......@@ -32,10 +32,10 @@
#include <string>
#include <vector>
class CITAMaterialManager;
namespace ITAGeo
{
class CMaterialManager;
//! Geometric model for acoustics
/**
......@@ -80,12 +80,12 @@ namespace ITAGeo
*
* @param[in] pMaterialManager Associated material manager (with write access)
*/
void SetAssociatedMaterialManager( CITAMaterialManager* pMaterialManager );
void SetAssociatedMaterialManager( ITAGeo::CMaterialManager* pMaterialManager );
protected:
std::string m_sModelName; //!< Model name
CITAMaterialManager* m_pAssociatedMaterialManager; //!< Associated material manager (where to add materials during load)
ITAGeo::CMaterialManager* m_pAssociatedMaterialManager; //!< Associated material manager (where to add materials during load)
/* @todo check if removal ok
//friend class ITAGeo::CSketchUpModel;
......
......@@ -156,7 +156,7 @@ bool ITAGeo::CHalfedgeMeshModel::TriangulateMesh()
return true;
}
bool ITAGeo::CHalfedgeMeshModel::SetFaceAcousticMaterial( int iFaceID, IITAAcousticMaterial* pMaterial )
bool ITAGeo::CHalfedgeMeshModel::SetFaceAcousticMaterial( int iFaceID, IAcousticMaterial* pMaterial )
{
CITAMesh* pMesh = static_cast< CITAMesh* >( m_prModelMeshData->pTopLevelMesh );
CITAMesh::FaceIter f_it = pMesh->faces_begin();
......
#include <ITAGeoMaterialManager.h>
// ITABase
#include <ITAStringUtils.h>
#include <ITAConfigUtils.h>
#include <ITAConstants.h>
// Vista
#include <VistaTools/VistaFileSystemDirectory.h>
#include <VistaTools/VistaFileSystemFile.h>
// Base
ITAGeo::CMaterialManager::CMaterialManager()
{
}
ITAGeo::CMaterialManager::~CMaterialManager()
{
}
// Material directory
struct CMATFileMaterial
{
void LoadFromFile( const std::string& sFilePath );
std::string sName;
std::string sNotes;
std::vector< float > vfAbsorptionCoefficients;
std::vector< float > vfScatteringCoefficients;
};
ITAGeo::CMaterialDirectory::CMaterialDirectory()
{
}
ITAGeo::CMaterialDirectory::CMaterialDirectory( const std::string& sFolderPath, const bool bRecursive )
{
VistaFileSystemDirectory d( sFolderPath );
if( d.Exists() && d.IsDirectory() )
AddMaterialsFromFolder( sFolderPath, bRecursive );
}
ITAGeo::CMaterialDirectory::~CMaterialDirectory()
{
for( auto m : m_mMaterials )
delete m.second;
}
void ITAGeo::CMaterialDirectory::AddMaterialsFromFolder( const std::string& sFolderPath, const bool bRecursive /*= false*/ )
{
for( auto pNode : VistaFileSystemDirectory( sFolderPath ) )
{
if( pNode->IsDirectory() && bRecursive && pNode->GetLocalName() != "." && pNode->GetLocalName() != "..")
AddMaterialsFromFolder( pNode->GetName(), bRecursive );
std::vector< std::string > vsFileNameParts = splitString( pNode->GetLocalName(), '.' );
if( vsFileNameParts.size() < 2 )
continue;
const std::string sExtension = vsFileNameParts[ vsFileNameParts.size() - 1 ];
if( sExtension == "mat" )
{
const std::string sIdentifier = *( vsFileNameParts.begin() );
CMATFileMaterial oMaterial;
oMaterial.LoadFromFile( pNode->GetName() );
CSpectrumMaterial* pMaterial = new CSpectrumMaterial();
pMaterial->sName = oMaterial.sName;
pMaterial->vdFrequencies = ITAConstants::THIRD_OCTAVE_CENTER_FREQUENCIES_ISO_D;
if( oMaterial.vfAbsorptionCoefficients.size() == pMaterial->vdFrequencies.size() )
for( size_t i = 0; i < pMaterial->GetNumBins(); i++ )
pMaterial->vcfComplexReflectionFactor.push_back( 1.0f - ( double ) oMaterial.vfAbsorptionCoefficients[ i ] );
if( oMaterial.vfScatteringCoefficients.size() == pMaterial->vdFrequencies.size() )
for( size_t i = 0; i < pMaterial->GetNumBins(); i++ )
pMaterial->vcfScatteringCoefficient.push_back( ( double ) oMaterial.vfScatteringCoefficients[ i ] );
m_mMaterials[ sIdentifier ] = pMaterial;
}
}
}
const ITAGeo::IAcousticMaterial* ITAGeo::CMaterialDirectory::GetMaterial( const std::string& sMaterialIdentifier ) const
{
if( m_mMaterials.find( sMaterialIdentifier ) == m_mMaterials.end() )
return nullptr;
else
return m_mMaterials.find( sMaterialIdentifier )->second;
}
void CMATFileMaterial::LoadFromFile( const std::string& sFilePath )
{
INIFileUseFile( sFilePath );
if( INIFileUseSectionIfExists( "Material" ) )
{
sName = INIFileReadStringExplicit( "name" );
sNotes = INIFileReadString( "notes" );
vfAbsorptionCoefficients = INIFileReadFloatList( "absorp" );
vfScatteringCoefficients = INIFileReadFloatList( "scatter" );
}
}
......@@ -9,7 +9,7 @@
#include <iomanip>
void ITAGeo::CModelBase::SetAssociatedMaterialManager( CITAMaterialManager* pMaterialManager )
void ITAGeo::CModelBase::SetAssociatedMaterialManager( CMaterialManager* pMaterialManager )
{
m_pAssociatedMaterialManager = pMaterialManager;
}
......
......@@ -4,13 +4,16 @@
// ITABase includes
#include <ITAException.h>
// Typedefs
typedef OpenMesh::PolyMesh_ArrayKernelT<> CITAMesh;
using namespace ITAGeo;
// Globals
OpenMesh::VPropHandleT< CITAAcousticVertexProperty > tAcousticVertexProp;
OpenMesh::HPropHandleT< CITAAcousticEdgeProperty > tAcousticEdgeProp;
OpenMesh::FPropHandleT< CITAAcousticFaceProperty > tAcousticFaceProp;
OpenMesh::VPropHandleT< CAcousticVertexProperty > tAcousticVertexProp;
OpenMesh::HPropHandleT< CAcousticEdgeProperty > tAcousticEdgeProp;
OpenMesh::FPropHandleT< CAcousticFaceProperty > tAcousticFaceProp;
void AddAcousticFacePropertyToMesh( CITAMesh* pMesh )
{
......@@ -18,7 +21,7 @@ void AddAcousticFacePropertyToMesh( CITAMesh* pMesh )
pMesh->add_property( tAcousticFaceProp );
}
bool AddFaceMaterial( CITAMesh* pMesh, IITAAcousticMaterial* pMaterial, CITAMesh::FaceHandle hFace )
bool AddFaceMaterial( CITAMesh* pMesh, ITAGeo::IAcousticMaterial* pMaterial, CITAMesh::FaceHandle hFace )
{
assert( pMesh );
assert( pMaterial );
......@@ -27,7 +30,7 @@ bool AddFaceMaterial( CITAMesh* pMesh, IITAAcousticMaterial* pMaterial, CITAMesh
return true;
}
bool SUColorToOneDimAcousticMaterial( CITAOneDimAcousticMaterial* pMaterial, const SUColor& tColor )
bool SUColorToOneDimAcousticMaterial( ITAGeo::COneDimAcousticMaterial* pMaterial, const SUColor& tColor )
{
assert( pMaterial );
pMaterial->cdTransmissionFactor = tColor.alpha / 255.0f; // T, complex
......@@ -36,10 +39,10 @@ bool SUColorToOneDimAcousticMaterial( CITAOneDimAcousticMaterial* pMaterial, con
return true;
}
bool AcousticMaterialToSUMaterial( CITAMesh* pMesh, CITAMesh::FaceHandle hFace, SUMaterialRef* pSUFaceMaterial, CITAMaterialManager* pManager )
bool AcousticMaterialToSUMaterial( CITAMesh* pMesh, CITAMesh::FaceHandle hFace, SUMaterialRef* pSUFaceMaterial, ITAGeo::CMaterialManager* pManager )
{
assert( pMesh );
const IITAAcousticMaterial* pMaterial = pMesh->property( tAcousticFaceProp, hFace ).GetMaterial();
const IAcousticMaterial* pMaterial = pMesh->property( tAcousticFaceProp, hFace ).GetMaterial();
if( pMaterial == nullptr )
return false;
......@@ -48,9 +51,9 @@ bool AcousticMaterialToSUMaterial( CITAMesh* pMesh, CITAMesh::FaceHandle hFace,
int iMaterialType = pMaterial->GetType();
switch( iMaterialType )
{
case IITAAcousticMaterial::ITA_MATERIAL_VISUALIZATION:
case IAcousticMaterial::ITA_MATERIAL_VISUALIZATION:
{
const CITAVisualizationMaterial* pVisMaterial = static_cast< const CITAVisualizationMaterial* >( pMaterial );
const CVisualizationMaterial* pVisMaterial = static_cast< const CVisualizationMaterial* >( pMaterial );
assert( pVisMaterial );
oSUColor.red = ( unsigned char ) ( pVisMaterial->dRed * 255.0f );
oSUColor.green = ( unsigned char ) ( pVisMaterial->dGreen * 255.0f );
......@@ -58,12 +61,12 @@ bool AcousticMaterialToSUMaterial( CITAMesh* pMesh, CITAMesh::FaceHandle hFace,
oSUColor.alpha = ( unsigned char ) ( pVisMaterial->dAlpha * 255.0f );
break;
}
case IITAAcousticMaterial::ITA_MATERIAL_NOTYPE:
case IITAAcousticMaterial::ITA_MATERIAL_ONE_DIM:
case IITAAcousticMaterial::ITA_MATERIAL_THIRD_OCTAVE:
case IITAAcousticMaterial::ITA_MATERIAL_WHOLE_OCTAVE:
case IITAAcousticMaterial::ITA_MATERIAL_SPECTRUM:
case IITAAcousticMaterial::ITA_MATERIAL_MAGNITUDE_SPECTRUM:
case IAcousticMaterial::ITA_MATERIAL_NOTYPE:
case IAcousticMaterial::ITA_MATERIAL_ONE_DIM:
case IAcousticMaterial::ITA_MATERIAL_THIRD_OCTAVE:
case IAcousticMaterial::ITA_MATERIAL_WHOLE_OCTAVE:
case IAcousticMaterial::ITA_MATERIAL_SPECTRUM:
case IAcousticMaterial::ITA_MATERIAL_MAGNITUDE_SPECTRUM:
default:
{
pSUFaceMaterial = NULL;
......@@ -77,7 +80,7 @@ bool AcousticMaterialToSUMaterial( CITAMesh* pMesh, CITAMesh::FaceHandle hFace,
return true;
}
SUResult SUMaterialToAcousticMaterial( CITAMesh* pMesh, CITAMesh::FaceHandle hFace, SUFaceRef rFace, CITAMaterialManager* pManager )
SUResult SUMaterialToAcousticMaterial( CITAMesh* pMesh, CITAMesh::FaceHandle hFace, SUFaceRef rFace, ITAGeo::CMaterialManager* pManager )
{
SUResult sur;
......@@ -109,7 +112,7 @@ SUResult SUMaterialToAcousticMaterial( CITAMesh* pMesh, CITAMesh::FaceHandle hFa
return sur; // or defaults and skip?
// Set material connection for this face
CITAOneDimAcousticMaterial* pMat = new CITAOneDimAcousticMaterial;
COneDimAcousticMaterial* pMat = new COneDimAcousticMaterial;
pMesh->property( tAcousticFaceProp, hFace ).SetMaterial( pMat );
SUColorToOneDimAcousticMaterial( pMat, tColor );
......@@ -137,7 +140,7 @@ SUResult SUMaterialToAcousticMaterial( CITAMesh* pMesh, CITAMesh::FaceHandle hFa
else
{
// Set material connection for this face
CITAOneDimAcousticMaterial* pMaterial = new CITAOneDimAcousticMaterial;
COneDimAcousticMaterial* pMaterial = new COneDimAcousticMaterial;
pMesh->property( tAcousticFaceProp, hFace ).SetMaterial( pMaterial );
SUColorToOneDimAcousticMaterial( pMaterial, tColor );
}
......
......@@ -20,6 +20,7 @@
#define INCLUDE_WATCHER_ITA_GEO_SU_MATERIALS
#include <ITAGeoAcousticMaterial.h>
#include <ITAGeoMaterialManager.h>
// Sketchup includes
#include <SketchUpAPI/model/face.h>
......@@ -42,15 +43,15 @@ typedef OpenMesh::PolyMesh_ArrayKernelT<> CITAMesh;
void AddAcousticFacePropertyToMesh( CITAMesh* pMesh );
//! Adds acoustic material to a mesh face
bool AddFaceMaterial( CITAMesh* pMesh, IITAAcousticMaterial* pMaterial, CITAMesh::FaceHandle hFace );
bool AddFaceMaterial( CITAMesh* pMesh, ITAGeo::IAcousticMaterial* pMaterial, CITAMesh::FaceHandle hFace );
//! Converts a color to a one-dimensional acoustic material
bool SUColorToOneDimAcousticMaterial( CITAOneDimAcousticMaterial* pMaterial, const SUColor& tColor );
bool SUColorToOneDimAcousticMaterial( ITAGeo::COneDimAcousticMaterial* pMaterial, const SUColor& tColor );
//! Creates SU material from acoutic material
bool AcousticMaterialToSUMaterial( CITAMesh* pMesh, CITAMesh::FaceHandle hFace, SUMaterialRef* rFaceMaterial, CITAMaterialManager* pManager );
bool AcousticMaterialToSUMaterial( CITAMesh* pMesh, CITAMesh::FaceHandle hFace, SUMaterialRef* rFaceMaterial, ITAGeo::CMaterialManager* pManager );
//! Connects an acoustic material from SU face to ITAMesh
SUResult SUMaterialToAcousticMaterial( CITAMesh* pMesh, CITAMesh::FaceHandle hFace, SUFaceRef rFace, CITAMaterialManager* pManager = NULL );
SUResult SUMaterialToAcousticMaterial( CITAMesh* pMesh, CITAMesh::FaceHandle hFace, SUFaceRef rFace, ITAGeo::CMaterialManager* pManager = NULL );
#endif // INCLUDE_WATCHER_ITA_GEO_SU_MATERIALS
......@@ -22,7 +22,7 @@
#include <SketchUpAPI/initialize.h>
#include <SketchUpAPI/transformation.h>
SUResult SUEntitiesToITAMesh( SUEntitiesRef rEntities, CITAMesh* pMesh, bool bExplodeGroups, std::vector< SUTransformation >& vtTransform, CITAMaterialManager* pMaterialManager /* = nullptr */ )
SUResult SUEntitiesToITAMesh( SUEntitiesRef rEntities, CITAMesh* pMesh, bool bExplodeGroups, std::vector< SUTransformation >& vtTransform, ITAGeo::CMaterialManager* pMaterialManager /* = nullptr */ )
{
bool bTopLevelMesh = vtTransform.empty();
......@@ -167,13 +167,13 @@ SUResult SUEntitiesToITAMesh( SUEntitiesRef rEntities, CITAMesh* pMesh, bool bEx
return SU_ERROR_NONE;
}
SUResult SUEntitiesToITAMesh( SUEntitiesRef rEntities, CITAMesh* pMesh, bool bExplodeGroups, CITAMaterialManager* pMaterialManager /* = nullptr */ )
SUResult SUEntitiesToITAMesh( SUEntitiesRef rEntities, CITAMesh* pMesh, bool bExplodeGroups, ITAGeo::CMaterialManager* pMaterialManager /* = nullptr */ )
{
std::vector< SUTransformation > vtDummy;
return SUEntitiesToITAMesh( rEntities, pMesh, bExplodeGroups, vtDummy, pMaterialManager );
}
SUResult SUComponentInstanceToITAMesh( SUComponentInstanceRef rCompInstance, CITAMesh* pMesh, CITAMaterialManager* pMaterialManager /* = nullptr */ )
SUResult SUComponentInstanceToITAMesh( SUComponentInstanceRef rCompInstance, CITAMesh* pMesh, ITAGeo::CMaterialManager* pMaterialManager /* = nullptr */ )
{
SUComponentDefinitionRef rComponentDef;
SU_RET( SUComponentInstanceGetDefinition( rCompInstance, &rComponentDef ) );
......
......@@ -19,6 +19,9 @@
#ifndef INCLUDE_WATCHER_ITA_GEO_SU_MESH_CONVERSIONS
#define INCLUDE_WATCHER_ITA_GEO_SU_MESH_CONVERSIONS
// ITAGeo includes
#include <ITAGeoMaterialManager.h>
// Sketchup includes
#include <SketchUpAPI/model/entities.h>
#include <SketchUpAPI/model/layer.h>
......@@ -36,14 +39,11 @@
// Typedefs
typedef OpenMesh::PolyMesh_ArrayKernelT<> CITAMesh;
// Forwards
class CITAMaterialManager;
//! Add entities to the mesh
SUResult SUEntitiesToITAMesh( SUEntitiesRef rEntities, CITAMesh* pMesh, bool bExplodeGroups, CITAMaterialManager* pMaterialManager = nullptr );
SUResult SUEntitiesToITAMesh( SUEntitiesRef rEntities, CITAMesh* pMesh, bool bExplodeGroups, ITAGeo::CMaterialManager* pMaterialManager = nullptr );
//! Add entities to the mesh with transformation chain
SUResult SUEntitiesToITAMesh( SUEntitiesRef rEntities, CITAMesh* pMesh, bool bExplodeGroups, std::vector< SUTransformation >& vtTransform, CITAMaterialManager* pMaterialManager = nullptr );
SUResult SUEntitiesToITAMesh( SUEntitiesRef rEntities, CITAMesh* pMesh, bool bExplodeGroups, std::vector< SUTransformation >& vtTransform, ITAGeo::CMaterialManager* pMaterialManager = nullptr );
//! Convert from ITAMesh to SketchUp entities (and add to a layer if not NULL)
SUResult ITAMeshToSUEntities( CITAMesh* pMesh, SUEntitiesRef* rEntities, SULayerRef* rLayer = NULL );
......
......@@ -55,3 +55,13 @@ vista_install( ITAGeoUtilsTest )
vista_create_default_info_file( ITAGeoUtilsTest )
set_property( TARGET ITAGeoUtilsTest PROPERTY FOLDER "ITAGeometricalAcoustics/Tests/ITAGeo" )
add_executable( MaterialManagerTest MaterialManagerTest.cpp )
target_link_libraries( MaterialManagerTest ${VISTA_USE_PACKAGE_LIBRARIES} )
vista_configure_app( MaterialManagerTest )
vista_install( MaterialManagerTest )
vista_create_default_info_file( MaterialManagerTest )
set_property( TARGET MaterialManagerTest PROPERTY FOLDER "ITAGeometricalAcoustics/Tests/ITAGeo" )
......@@ -38,9 +38,9 @@ int main( int, char** )
{
string sSKPFileName = "ExportReceiverAndSources";
string sInExtension = "ac";
CHalfedgeMeshModel oHEModel;
if (oHEModel.Load(sSKPFileName + "." + sInExtension))
if( oHEModel.Load( sSKPFileName + "." + sInExtension ) )
cout << "Sucessfully loaded '" << sSKPFileName << "' as an halfedge model" << endl;
if( oHEModel.Store( sSKPFileName + ".skp" ) )
......
#include <ITAGeoMaterialManager.h>
#include <ITAException.h>
#include <iostream>
using namespace std;
using namespace ITAGeo;
int main( int, char** )
{
CMaterialDirectory oMaterialDirectory( "./" );
const IAcousticMaterial* pMaterial = oMaterialDirectory.GetMaterial( "stonewall" );
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment