Merge pull request #1732 from turol/threadsafe

Fix thread-safety issue in 3DS and ASE loaders
pull/1734/head
turol 2018-01-24 13:07:09 +02:00 committed by GitHub
commit 1b1d1e7376
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 133 additions and 30 deletions

View File

@ -127,9 +127,8 @@ void Discreet3DSImporter::ReplaceDefaultMaterial()
if (cnt && idx == mScene->mMaterials.size()) if (cnt && idx == mScene->mMaterials.size())
{ {
// We need to create our own default material // We need to create our own default material
D3DS::Material sMat; D3DS::Material sMat("%%%DEFAULT");
sMat.mDiffuse = aiColor3D(0.3f,0.3f,0.3f); sMat.mDiffuse = aiColor3D(0.3f,0.3f,0.3f);
sMat.mName = "%%%DEFAULT";
mScene->mMaterials.push_back(sMat); mScene->mMaterials.push_back(sMat);
DefaultLogger::get()->info("3DS: Generating default material"); DefaultLogger::get()->info("3DS: Generating default material");

View File

@ -370,9 +370,14 @@ struct Texture
/** Helper structure representing a 3ds material */ /** Helper structure representing a 3ds material */
struct Material struct Material
{ {
//! Default constructor. Builds a default name for the material //! Default constructor has been deleted
Material() Material() = delete;
: mDiffuse ( ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 0.6 ) ) // FIX ... we won't want object to be black
//! Constructor with explicit name
explicit Material(const std::string &name)
: mName(name)
, mDiffuse ( ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 0.6 ) ) // FIX ... we won't want object to be black
, mSpecularExponent ( ai_real( 0.0 ) ) , mSpecularExponent ( ai_real( 0.0 ) )
, mShininessStrength ( ai_real( 1.0 ) ) , mShininessStrength ( ai_real( 1.0 ) )
, mShading(Discreet3DS::Gouraud) , mShading(Discreet3DS::Gouraud)
@ -380,13 +385,70 @@ struct Material
, mBumpHeight ( ai_real( 1.0 ) ) , mBumpHeight ( ai_real( 1.0 ) )
, mTwoSided (false) , mTwoSided (false)
{ {
static int iCnt = 0;
char szTemp[128];
ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
mName = szTemp;
} }
Material(const Material &other) = default;
Material &operator=(const Material &other) = default;
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
Material(Material &&other)
: mName(std::move(other.mName))
, mDiffuse(std::move(other.mDiffuse))
, mSpecularExponent(std::move(other.mSpecularExponent))
, mShininessStrength(std::move(other.mShininessStrength))
, mSpecular(std::move(other.mSpecular))
, mAmbient(std::move(other.mAmbient))
, mShading(std::move(other.mShading))
, mTransparency(std::move(other.mTransparency))
, sTexDiffuse(std::move(other.sTexDiffuse))
, sTexOpacity(std::move(other.sTexOpacity))
, sTexSpecular(std::move(other.sTexSpecular))
, sTexReflective(std::move(other.sTexReflective))
, sTexBump(std::move(other.sTexBump))
, sTexEmissive(std::move(other.sTexEmissive))
, sTexShininess(std::move(other.sTexShininess))
, mBumpHeight(std::move(other.mBumpHeight))
, mEmissive(std::move(other.mEmissive))
, sTexAmbient(std::move(other.sTexAmbient))
, mTwoSided(std::move(other.mTwoSided))
{
}
Material &operator=(Material &&other) {
if (this == &other) {
return *this;
}
mName = std::move(other.mName);
mDiffuse = std::move(other.mDiffuse);
mSpecularExponent = std::move(other.mSpecularExponent);
mShininessStrength = std::move(other.mShininessStrength),
mSpecular = std::move(other.mSpecular);
mAmbient = std::move(other.mAmbient);
mShading = std::move(other.mShading);
mTransparency = std::move(other.mTransparency);
sTexDiffuse = std::move(other.sTexDiffuse);
sTexOpacity = std::move(other.sTexOpacity);
sTexSpecular = std::move(other.sTexSpecular);
sTexReflective = std::move(other.sTexReflective);
sTexBump = std::move(other.sTexBump);
sTexEmissive = std::move(other.sTexEmissive);
sTexShininess = std::move(other.sTexShininess);
mBumpHeight = std::move(other.mBumpHeight);
mEmissive = std::move(other.mEmissive);
sTexAmbient = std::move(other.sTexAmbient);
mTwoSided = std::move(other.mTwoSided);
return *this;
}
~Material() {}
//! Name of the material //! Name of the material
std::string mName; std::string mName;
//! Diffuse color of the material //! Diffuse color of the material

View File

@ -105,14 +105,14 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
Discreet3DSImporter::Discreet3DSImporter() Discreet3DSImporter::Discreet3DSImporter()
: stream(), : stream()
mLastNodeIndex(), , mLastNodeIndex()
mCurrentNode(), , mCurrentNode()
mRootNode(), , mRootNode()
mScene(), , mScene()
mMasterScale(), , mMasterScale()
bHasBG(), , bHasBG()
bIsPrj() , bIsPrj()
{} {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -346,7 +346,7 @@ void Discreet3DSImporter::ParseObjectChunk()
case Discreet3DS::CHUNK_MAT_MATERIAL: case Discreet3DS::CHUNK_MAT_MATERIAL:
// Add a new material to the list // Add a new material to the list
mScene->mMaterials.push_back(D3DS::Material()); mScene->mMaterials.push_back(D3DS::Material(std::string("UNNAMED_" + std::to_string(mScene->mMaterials.size()))));
ParseMaterialChunk(); ParseMaterialChunk();
break; break;

View File

@ -83,11 +83,11 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
ASEImporter::ASEImporter() ASEImporter::ASEImporter()
: mParser(), : mParser()
mBuffer(), , mBuffer()
pcScene(), , pcScene()
configRecomputeNormals(), , configRecomputeNormals()
noSkeletonMesh() , noSkeletonMesh()
{} {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -276,14 +276,13 @@ void ASEImporter::GenerateDefaultMaterial()
} }
if (bHas || mParser->m_vMaterials.empty()) { if (bHas || mParser->m_vMaterials.empty()) {
// add a simple material without submaterials to the parser's list // add a simple material without submaterials to the parser's list
mParser->m_vMaterials.push_back ( ASE::Material() ); mParser->m_vMaterials.push_back ( ASE::Material(AI_DEFAULT_MATERIAL_NAME) );
ASE::Material& mat = mParser->m_vMaterials.back(); ASE::Material& mat = mParser->m_vMaterials.back();
mat.mDiffuse = aiColor3D(0.6f,0.6f,0.6f); mat.mDiffuse = aiColor3D(0.6f,0.6f,0.6f);
mat.mSpecular = aiColor3D(1.0f,1.0f,1.0f); mat.mSpecular = aiColor3D(1.0f,1.0f,1.0f);
mat.mAmbient = aiColor3D(0.05f,0.05f,0.05f); mat.mAmbient = aiColor3D(0.05f,0.05f,0.05f);
mat.mShading = Discreet3DS::Gouraud; mat.mShading = Discreet3DS::Gouraud;
mat.mName = AI_DEFAULT_MATERIAL_NAME;
} }
} }

View File

@ -528,7 +528,7 @@ void Parser::ParseLV1MaterialListBlock()
ParseLV4MeshLong(iMaterialCount); ParseLV4MeshLong(iMaterialCount);
// now allocate enough storage to hold all materials // now allocate enough storage to hold all materials
m_vMaterials.resize(iOldMaterialCount+iMaterialCount); m_vMaterials.resize(iOldMaterialCount+iMaterialCount, Material("INVALID"));
continue; continue;
} }
if (TokenMatch(filePtr,"MATERIAL",8)) if (TokenMatch(filePtr,"MATERIAL",8))
@ -706,7 +706,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
ParseLV4MeshLong(iNumSubMaterials); ParseLV4MeshLong(iNumSubMaterials);
// allocate enough storage // allocate enough storage
mat.avSubMaterials.resize(iNumSubMaterials); mat.avSubMaterials.resize(iNumSubMaterials, Material("INVALID SUBMATERIAL"));
} }
// submaterial chunks // submaterial chunks
if (TokenMatch(filePtr,"SUBMATERIAL",11)) if (TokenMatch(filePtr,"SUBMATERIAL",11))

View File

@ -67,10 +67,53 @@ using namespace D3DS;
/** Helper structure representing an ASE material */ /** Helper structure representing an ASE material */
struct Material : public D3DS::Material struct Material : public D3DS::Material
{ {
//! Default constructor //! Default constructor has been deleted
Material() : pcInstance(NULL), bNeed (false) Material() = delete;
//! Constructor with explicit name
explicit Material(const std::string &name)
: D3DS::Material(name)
, pcInstance(NULL)
, bNeed (false)
{} {}
Material(const Material &other) = default;
Material &operator=(const Material &other) = default;
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
Material(Material &&other)
: D3DS::Material(std::move(other))
, avSubMaterials(std::move(other.avSubMaterials))
, pcInstance(std::move(other.pcInstance))
, bNeed(std::move(other.bNeed))
{
other.pcInstance = nullptr;
}
Material &operator=(Material &&other) {
if (this == &other) {
return *this;
}
D3DS::Material::operator=(std::move(other));
avSubMaterials = std::move(other.avSubMaterials);
pcInstance = std::move(other.pcInstance);
bNeed = std::move(other.bNeed);
other.pcInstance = nullptr;
return *this;
}
~Material() {}
//! Contains all sub materials of this material //! Contains all sub materials of this material
std::vector<Material> avSubMaterials; std::vector<Material> avSubMaterials;