Merge branch 'master' into jc3-importer-open-error-handling

pull/3890/head
Jason C 2021-05-07 14:49:00 -04:00 committed by GitHub
commit 6eb15080ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 58 additions and 98 deletions

View File

@ -115,7 +115,7 @@ static const aiImporterDesc desc = {
0, 0,
0, 0,
0, 0,
"ifc ifczip stp" "ifc ifczip step stp"
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -57,6 +57,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <iomanip> #include <iomanip>
#include <sstream> #include <sstream>
#include <map>
#ifdef MDL_HALFLIFE_LOG_WARN_HEADER #ifdef MDL_HALFLIFE_LOG_WARN_HEADER
#undef MDL_HALFLIFE_LOG_WARN_HEADER #undef MDL_HALFLIFE_LOG_WARN_HEADER

View File

@ -65,20 +65,6 @@ using namespace Assimp;
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
BaseImporter::BaseImporter() AI_NO_EXCEPT BaseImporter::BaseImporter() AI_NO_EXCEPT
: m_progress() { : m_progress() {
/**
* Assimp Importer
* unit conversions available
* if you need another measurment unit add it below.
* it's currently defined in assimp that we prefer meters.
*
* NOTE: Initialised here rather than in the header file
* to workaround a VS2013 bug with brace initialisers
* */
importerUnits[ImporterUnits::M] = 1.0;
importerUnits[ImporterUnits::CM] = 0.01;
importerUnits[ImporterUnits::MM] = 0.001;
importerUnits[ImporterUnits::INCHES] = 0.0254;
importerUnits[ImporterUnits::FEET] = 0.3048;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -70,6 +70,7 @@ GenFaceNormalsProcess::~GenFaceNormalsProcess() {
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool GenFaceNormalsProcess::IsActive(unsigned int pFlags) const { bool GenFaceNormalsProcess::IsActive(unsigned int pFlags) const {
force_ = (pFlags & aiProcess_ForceGenNormals) != 0; force_ = (pFlags & aiProcess_ForceGenNormals) != 0;
flippedWindingOrder_ = (pFlags & aiProcess_FlipWindingOrder) != 0;
return (pFlags & aiProcess_GenNormals) != 0; return (pFlags & aiProcess_GenNormals) != 0;
} }
@ -134,6 +135,8 @@ bool GenFaceNormalsProcess::GenMeshFaceNormals(aiMesh *pMesh) {
const aiVector3D *pV1 = &pMesh->mVertices[face.mIndices[0]]; const aiVector3D *pV1 = &pMesh->mVertices[face.mIndices[0]];
const aiVector3D *pV2 = &pMesh->mVertices[face.mIndices[1]]; const aiVector3D *pV2 = &pMesh->mVertices[face.mIndices[1]];
const aiVector3D *pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices - 1]]; const aiVector3D *pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices - 1]];
if (flippedWindingOrder_)
std::swap( pV2, pV3 );
const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe(); const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe();
for (unsigned int i = 0; i < face.mNumIndices; ++i) { for (unsigned int i = 0; i < face.mNumIndices; ++i) {

View File

@ -80,6 +80,7 @@ public:
private: private:
bool GenMeshFaceNormals(aiMesh* pcMesh); bool GenMeshFaceNormals(aiMesh* pcMesh);
mutable bool force_ = false; mutable bool force_ = false;
mutable bool flippedWindingOrder_ = false;
}; };
} // end of namespace Assimp } // end of namespace Assimp

View File

@ -70,6 +70,7 @@ GenVertexNormalsProcess::~GenVertexNormalsProcess() {
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool GenVertexNormalsProcess::IsActive(unsigned int pFlags) const { bool GenVertexNormalsProcess::IsActive(unsigned int pFlags) const {
force_ = (pFlags & aiProcess_ForceGenNormals) != 0; force_ = (pFlags & aiProcess_ForceGenNormals) != 0;
flippedWindingOrder_ = (pFlags & aiProcess_FlipWindingOrder) != 0;
return (pFlags & aiProcess_GenSmoothNormals) != 0; return (pFlags & aiProcess_GenSmoothNormals) != 0;
} }
@ -142,6 +143,8 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals(aiMesh *pMesh, unsigned int m
const aiVector3D *pV1 = &pMesh->mVertices[face.mIndices[0]]; const aiVector3D *pV1 = &pMesh->mVertices[face.mIndices[0]];
const aiVector3D *pV2 = &pMesh->mVertices[face.mIndices[1]]; const aiVector3D *pV2 = &pMesh->mVertices[face.mIndices[1]];
const aiVector3D *pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices - 1]]; const aiVector3D *pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices - 1]];
if (flippedWindingOrder_)
std::swap( pV2, pV3 );
const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe(); const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe();
for (unsigned int i = 0; i < face.mNumIndices; ++i) { for (unsigned int i = 0; i < face.mNumIndices; ++i) {

View File

@ -104,6 +104,7 @@ private:
/** Configuration option: maximum smoothing angle, in radians*/ /** Configuration option: maximum smoothing angle, in radians*/
ai_real configMaxAngle; ai_real configMaxAngle;
mutable bool force_ = false; mutable bool force_ = false;
mutable bool flippedWindingOrder_ = false;
}; };
} // end of namespace Assimp } // end of namespace Assimp

View File

@ -429,7 +429,7 @@ void PretransformVertices::Execute(aiScene *pScene) {
const unsigned int iOldNodes = CountNodes(pScene->mRootNode); const unsigned int iOldNodes = CountNodes(pScene->mRootNode);
if (configTransform) { if (configTransform) {
pScene->mRootNode->mTransformation = configTransformation; pScene->mRootNode->mTransformation = configTransformation * pScene->mRootNode->mTransformation;
} }
// first compute absolute transformation matrices for all nodes // first compute absolute transformation matrices for all nodes

View File

@ -51,10 +51,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Exceptional.h" #include "Exceptional.h"
#include <assimp/ai_assert.h>
#include <assimp/types.h> #include <assimp/types.h>
#include <assimp/ProgressHandler.hpp> #include <assimp/ProgressHandler.hpp>
#include <map>
#include <set> #include <set>
#include <vector> #include <vector>
#include <memory> #include <memory>
@ -179,42 +177,10 @@ public:
/** /**
* Will be called only by scale process when scaling is requested. * Will be called only by scale process when scaling is requested.
*/ */
virtual void SetFileScale(double scale) { void SetFileScale(double scale) {
fileScale = scale; fileScale = scale;
} }
virtual double GetFileScale() const {
return fileScale;
}
enum ImporterUnits {
M,
MM,
CM,
INCHES,
FEET
};
/**
* Assimp Importer
* unit conversions available
* NOTE: Valid options are initialised in the
* constructor in the implementation file to
* work around a VS2013 compiler bug if support
* for that compiler is dropped in the future
* initialisation can be moved back here
* */
std::map<ImporterUnits, double> importerUnits;
virtual void SetApplicationUnits(const ImporterUnits &unit) {
importerScale = importerUnits[unit];
applicationUnits = unit;
}
virtual const ImporterUnits &GetApplicationUnits() {
return applicationUnits;
}
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Called by #Importer::GetExtensionList for each loaded importer. /** Called by #Importer::GetExtensionList for each loaded importer.
* Take the extension list contained in the structure returned by * Take the extension list contained in the structure returned by
@ -223,7 +189,6 @@ public:
void GetExtensionList(std::set<std::string> &extensions); void GetExtensionList(std::set<std::string> &extensions);
protected: protected:
ImporterUnits applicationUnits = ImporterUnits::M;
double importerScale = 1.0; double importerScale = 1.0;
double fileScale = 1.0; double fileScale = 1.0;
@ -420,7 +385,7 @@ public: // static utilities
private: private:
/* Pushes state into importer for the importer scale */ /* Pushes state into importer for the importer scale */
virtual void UpdateImporterScale(Importer *pImp); void UpdateImporterScale(Importer *pImp);
protected: protected:
/// Error description in case there was one. /// Error description in case there was one.

View File

@ -43,8 +43,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define INCLUDED_AI_IRRXML_WRAPPER #define INCLUDED_AI_IRRXML_WRAPPER
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/ai_assert.h>
#include "BaseImporter.h" #include "BaseImporter.h"
#include "IOStream.hpp" #include "IOStream.hpp"
#include <pugixml.hpp> #include <pugixml.hpp>
#include <vector> #include <vector>

View File

@ -42,22 +42,12 @@ void ModelLoader::Draw(ID3D11DeviceContext * devcon) {
} }
} }
std::string textype;
Mesh ModelLoader::processMesh(aiMesh * mesh, const aiScene * scene) { Mesh ModelLoader::processMesh(aiMesh * mesh, const aiScene * scene) {
// Data to fill // Data to fill
std::vector<VERTEX> vertices; std::vector<VERTEX> vertices;
std::vector<UINT> indices; std::vector<UINT> indices;
std::vector<Texture> textures; std::vector<Texture> textures;
if (mesh->mMaterialIndex >= 0) {
aiMaterial* mat = scene->mMaterials[mesh->mMaterialIndex];
if (textype.empty()) {
textype = determineTextureType(scene, mat);
}
}
// Walk through each of the mesh's vertices // Walk through each of the mesh's vertices
for (UINT i = 0; i < mesh->mNumVertices; i++) { for (UINT i = 0; i < mesh->mNumVertices; i++) {
VERTEX vertex; VERTEX vertex;
@ -108,9 +98,10 @@ std::vector<Texture> ModelLoader::loadMaterialTextures(aiMaterial * mat, aiTextu
if (!skip) { // If texture hasn't been loaded already, load it if (!skip) { // If texture hasn't been loaded already, load it
HRESULT hr; HRESULT hr;
Texture texture; Texture texture;
if (textype == "embedded compressed texture") {
int textureindex = getTextureIndex(&str); const aiTexture* embeddedTexture = scene->GetEmbeddedTexture(str.C_Str());
texture.texture = getTextureFromModel(scene, textureindex); if (embeddedTexture != nullptr) {
texture.texture = loadEmbeddedTexture(embeddedTexture);
} else { } else {
std::string filename = std::string(str.C_Str()); std::string filename = std::string(str.C_Str());
filename = directory_ + '/' + filename; filename = directory_ + '/' + filename;
@ -148,38 +139,46 @@ void ModelLoader::processNode(aiNode * node, const aiScene * scene) {
} }
} }
std::string ModelLoader::determineTextureType(const aiScene * scene, aiMaterial * mat) { ID3D11ShaderResourceView * ModelLoader::loadEmbeddedTexture(const aiTexture* embeddedTexture) {
aiString textypeStr;
mat->GetTexture(aiTextureType_DIFFUSE, 0, &textypeStr);
std::string textypeteststr = textypeStr.C_Str();
if (textypeteststr == "*0" || textypeteststr == "*1" || textypeteststr == "*2" || textypeteststr == "*3" || textypeteststr == "*4" || textypeteststr == "*5") {
if (scene->mTextures[0]->mHeight == 0) {
return "embedded compressed texture";
} else {
return "embedded non-compressed texture";
}
}
if (textypeteststr.find('.') != std::string::npos) {
return "textures are on disk";
}
return ".";
}
int ModelLoader::getTextureIndex(aiString * str) {
std::string tistr;
tistr = str->C_Str();
tistr = tistr.substr(1);
return stoi(tistr);
}
ID3D11ShaderResourceView * ModelLoader::getTextureFromModel(const aiScene * scene, int textureindex) {
HRESULT hr; HRESULT hr;
ID3D11ShaderResourceView *texture; ID3D11ShaderResourceView *texture = nullptr;
int* size = reinterpret_cast<int*>(&scene->mTextures[textureindex]->mWidth); if (embeddedTexture->mHeight != 0) {
// Load an uncompressed ARGB8888 embedded texture
D3D11_TEXTURE2D_DESC desc;
desc.Width = embeddedTexture->mWidth;
desc.Height = embeddedTexture->mHeight;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
hr = CreateWICTextureFromMemory(dev_, devcon_, reinterpret_cast<unsigned char*>(scene->mTextures[textureindex]->pcData), *size, nullptr, &texture); D3D11_SUBRESOURCE_DATA subresourceData;
subresourceData.pSysMem = embeddedTexture->pcData;
subresourceData.SysMemPitch = embeddedTexture->mWidth * 4;
subresourceData.SysMemSlicePitch = embeddedTexture->mWidth * embeddedTexture->mHeight * 4;
ID3D11Texture2D *texture2D = nullptr;
hr = dev_->CreateTexture2D(&desc, &subresourceData, &texture2D);
if (FAILED(hr))
MessageBox(hwnd_, "CreateTexture2D failed!", "Error!", MB_ICONERROR | MB_OK);
hr = dev_->CreateShaderResourceView(texture2D, nullptr, &texture);
if (FAILED(hr))
MessageBox(hwnd_, "CreateShaderResourceView failed!", "Error!", MB_ICONERROR | MB_OK);
return texture;
}
// mHeight is 0, so try to load a compressed texture of mWidth bytes
const size_t size = embeddedTexture->mWidth;
hr = CreateWICTextureFromMemory(dev_, devcon_, reinterpret_cast<const unsigned char*>(embeddedTexture->pcData), size, nullptr, &texture);
if (FAILED(hr)) if (FAILED(hr))
MessageBox(hwnd_, "Texture couldn't be created from memory!", "Error!", MB_ICONERROR | MB_OK); MessageBox(hwnd_, "Texture couldn't be created from memory!", "Error!", MB_ICONERROR | MB_OK);

View File

@ -35,9 +35,7 @@ private:
void processNode(aiNode* node, const aiScene* scene); void processNode(aiNode* node, const aiScene* scene);
Mesh processMesh(aiMesh* mesh, const aiScene* scene); Mesh processMesh(aiMesh* mesh, const aiScene* scene);
std::vector<Texture> loadMaterialTextures(aiMaterial* mat, aiTextureType type, std::string typeName, const aiScene* scene); std::vector<Texture> loadMaterialTextures(aiMaterial* mat, aiTextureType type, std::string typeName, const aiScene* scene);
std::string determineTextureType(const aiScene* scene, aiMaterial* mat); ID3D11ShaderResourceView* loadEmbeddedTexture(const aiTexture* embeddedTexture);
int getTextureIndex(aiString* str);
ID3D11ShaderResourceView* getTextureFromModel(const aiScene* scene, int textureindex);
}; };
#endif // !MODEL_LOADER_H #endif // !MODEL_LOADER_H