Merge branch 'stb-image-updated' of https://github.com/krishty/assimp into stb-image-updated
commit
ab43f3fefd
|
@ -69,7 +69,7 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() {
|
||||||
for (unsigned int i = 0; i < mScene->mMaterials.size(); ++i) {
|
for (unsigned int i = 0; i < mScene->mMaterials.size(); ++i) {
|
||||||
std::string s = mScene->mMaterials[i].mName;
|
std::string s = mScene->mMaterials[i].mName;
|
||||||
for (std::string::iterator it = s.begin(); it != s.end(); ++it) {
|
for (std::string::iterator it = s.begin(); it != s.end(); ++it) {
|
||||||
*it = static_cast<char>(::tolower(*it));
|
*it = static_cast<char>(::tolower(static_cast<unsigned char>(*it)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::string::npos == s.find("default")) continue;
|
if (std::string::npos == s.find("default")) continue;
|
||||||
|
|
|
@ -42,6 +42,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
|
||||||
|
|
||||||
#include "D3MFImporter.h"
|
#include "D3MFImporter.h"
|
||||||
|
#include "3MFXmlTags.h"
|
||||||
|
#include "D3MFOpcPackage.h"
|
||||||
|
|
||||||
#include <assimp/StringComparison.h>
|
#include <assimp/StringComparison.h>
|
||||||
#include <assimp/StringUtils.h>
|
#include <assimp/StringUtils.h>
|
||||||
|
@ -51,17 +53,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
|
#include <assimp/fast_atof.h>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "3MFXmlTags.h"
|
|
||||||
#include "D3MFOpcPackage.h"
|
|
||||||
#include <assimp/fast_atof.h>
|
|
||||||
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace D3MF {
|
namespace D3MF {
|
||||||
|
@ -163,7 +163,7 @@ public:
|
||||||
}
|
}
|
||||||
XmlNode resNode = node.child(XmlTag::resources);
|
XmlNode resNode = node.child(XmlTag::resources);
|
||||||
for (auto ¤tNode : resNode.children()) {
|
for (auto ¤tNode : resNode.children()) {
|
||||||
const std::string ¤tNodeName = currentNode.name();
|
const std::string currentNodeName = currentNode.name();
|
||||||
if (currentNodeName == XmlTag::object) {
|
if (currentNodeName == XmlTag::object) {
|
||||||
ReadObject(currentNode);
|
ReadObject(currentNode);
|
||||||
} else if (currentNodeName == XmlTag::basematerials) {
|
} else if (currentNodeName == XmlTag::basematerials) {
|
||||||
|
@ -173,8 +173,9 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto ¤tNode : resNode.children()) {
|
XmlNode buildNode = node.child(XmlTag::build);
|
||||||
const std::string ¤tNodeName = currentNode.name();
|
for (auto ¤tNode : buildNode.children()) {
|
||||||
|
const std::string currentNodeName = currentNode.name();
|
||||||
if (currentNodeName == XmlTag::item) {
|
if (currentNodeName == XmlTag::item) {
|
||||||
int objectId = -1;
|
int objectId = -1;
|
||||||
std::string transformationMatrixStr;
|
std::string transformationMatrixStr;
|
||||||
|
@ -196,7 +197,7 @@ public:
|
||||||
|
|
||||||
// import the metadata
|
// import the metadata
|
||||||
if (!mMetaData.empty()) {
|
if (!mMetaData.empty()) {
|
||||||
const size_t numMeta(mMetaData.size());
|
const size_t numMeta = mMetaData.size();
|
||||||
scene->mMetaData = aiMetadata::Alloc(static_cast<unsigned int>(numMeta));
|
scene->mMetaData = aiMetadata::Alloc(static_cast<unsigned int>(numMeta));
|
||||||
for (size_t i = 0; i < numMeta; ++i) {
|
for (size_t i = 0; i < numMeta; ++i) {
|
||||||
aiString val(mMetaData[i].value);
|
aiString val(mMetaData[i].value);
|
||||||
|
@ -211,6 +212,7 @@ public:
|
||||||
for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); ++it) {
|
for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); ++it) {
|
||||||
if (it->second->getType() == ResourceType::RT_Object) {
|
if (it->second->getType() == ResourceType::RT_Object) {
|
||||||
Object *obj = static_cast<Object *>(it->second);
|
Object *obj = static_cast<Object *>(it->second);
|
||||||
|
ai_assert(nullptr != obj);
|
||||||
for (unsigned int i = 0; i < obj->mMeshes.size(); ++i) {
|
for (unsigned int i = 0; i < obj->mMeshes.size(); ++i) {
|
||||||
scene->mMeshes[obj->mMeshIndex[i]] = obj->mMeshes[i];
|
scene->mMeshes[obj->mMeshIndex[i]] = obj->mMeshes[i];
|
||||||
}
|
}
|
||||||
|
@ -352,7 +354,8 @@ private:
|
||||||
mMeshCount++;
|
mMeshCount++;
|
||||||
} else if (currentName == D3MF::XmlTag::components) {
|
} else if (currentName == D3MF::XmlTag::components) {
|
||||||
for (XmlNode ¤tSubNode : currentNode.children()) {
|
for (XmlNode ¤tSubNode : currentNode.children()) {
|
||||||
if (currentSubNode.name() == D3MF::XmlTag::component) {
|
const std::string subNodeName = currentSubNode.name();
|
||||||
|
if (subNodeName == D3MF::XmlTag::component) {
|
||||||
int objectId = -1;
|
int objectId = -1;
|
||||||
std::string componentTransformStr;
|
std::string componentTransformStr;
|
||||||
aiMatrix4x4 componentTransform;
|
aiMatrix4x4 componentTransform;
|
||||||
|
@ -360,8 +363,9 @@ private:
|
||||||
componentTransform = parseTransformMatrix(componentTransformStr);
|
componentTransform = parseTransformMatrix(componentTransformStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getNodeAttribute(currentSubNode, D3MF::XmlTag::objectid, objectId))
|
if (getNodeAttribute(currentSubNode, D3MF::XmlTag::objectid, objectId)) {
|
||||||
obj->mComponents.push_back({ objectId, componentTransform });
|
obj->mComponents.push_back({ objectId, componentTransform });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -374,7 +378,7 @@ private:
|
||||||
aiMesh *mesh = new aiMesh();
|
aiMesh *mesh = new aiMesh();
|
||||||
|
|
||||||
for (XmlNode ¤tNode : node.children()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string currentName = currentNode.name();
|
||||||
if (currentName == XmlTag::vertices) {
|
if (currentName == XmlTag::vertices) {
|
||||||
ImportVertices(currentNode, mesh);
|
ImportVertices(currentNode, mesh);
|
||||||
} else if (currentName == XmlTag::triangles) {
|
} else if (currentName == XmlTag::triangles) {
|
||||||
|
@ -402,8 +406,8 @@ private:
|
||||||
void ImportVertices(XmlNode &node, aiMesh *mesh) {
|
void ImportVertices(XmlNode &node, aiMesh *mesh) {
|
||||||
std::vector<aiVector3D> vertices;
|
std::vector<aiVector3D> vertices;
|
||||||
for (XmlNode ¤tNode : node.children()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string currentName = currentNode.name();
|
||||||
if (currentName == D3MF::XmlTag::vertex) {
|
if (currentName == XmlTag::vertex) {
|
||||||
vertices.push_back(ReadVertex(currentNode));
|
vertices.push_back(ReadVertex(currentNode));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -415,22 +419,22 @@ private:
|
||||||
|
|
||||||
aiVector3D ReadVertex(XmlNode &node) {
|
aiVector3D ReadVertex(XmlNode &node) {
|
||||||
aiVector3D vertex;
|
aiVector3D vertex;
|
||||||
vertex.x = ai_strtof(node.attribute(D3MF::XmlTag::x).as_string(), nullptr);
|
vertex.x = ai_strtof(node.attribute(XmlTag::x).as_string(), nullptr);
|
||||||
vertex.y = ai_strtof(node.attribute(D3MF::XmlTag::y).as_string(), nullptr);
|
vertex.y = ai_strtof(node.attribute(XmlTag::y).as_string(), nullptr);
|
||||||
vertex.z = ai_strtof(node.attribute(D3MF::XmlTag::z).as_string(), nullptr);
|
vertex.z = ai_strtof(node.attribute(XmlTag::z).as_string(), nullptr);
|
||||||
|
|
||||||
return vertex;
|
return vertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportTriangles(XmlNode &node, aiMesh *mesh) {
|
void ImportTriangles(XmlNode &node, aiMesh *mesh) {
|
||||||
std::vector<aiFace> faces;
|
std::vector<aiFace> faces;
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string currentName = currentNode.name();
|
||||||
if (currentName == D3MF::XmlTag::triangle) {
|
if (currentName == XmlTag::triangle) {
|
||||||
aiFace face = ReadTriangle(currentNode);
|
aiFace face = ReadTriangle(currentNode);
|
||||||
faces.push_back(face);
|
faces.push_back(face);
|
||||||
|
|
||||||
int pid = 0, p1;
|
int pid = 0, p1 = 0;
|
||||||
bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid);
|
bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid);
|
||||||
bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1);
|
bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1);
|
||||||
|
|
||||||
|
@ -472,10 +476,11 @@ private:
|
||||||
BaseMaterials *baseMaterials = new BaseMaterials(id);
|
BaseMaterials *baseMaterials = new BaseMaterials(id);
|
||||||
|
|
||||||
for (XmlNode ¤tNode : node.children()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
if (currentNode.name() == XmlTag::basematerials_base) {
|
const std::string currentName = currentNode.name();
|
||||||
|
if (currentName == XmlTag::basematerials_base) {
|
||||||
baseMaterials->mMaterialIndex.push_back(mMaterialCount);
|
baseMaterials->mMaterialIndex.push_back(mMaterialCount);
|
||||||
baseMaterials->mMaterials.push_back(readMaterialDef(currentNode, id));
|
baseMaterials->mMaterials.push_back(readMaterialDef(currentNode, id));
|
||||||
mMaterialCount++;
|
++mMaterialCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,6 +569,8 @@ private:
|
||||||
|
|
||||||
} //namespace D3MF
|
} //namespace D3MF
|
||||||
|
|
||||||
|
using namespace D3MF;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static const aiImporterDesc desc = {
|
||||||
"3mf Importer",
|
"3mf Importer",
|
||||||
"",
|
"",
|
||||||
|
@ -597,7 +604,7 @@ bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bo
|
||||||
if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) {
|
if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
D3MF::D3MFOpcPackage opcPackage(pIOHandler, filename);
|
D3MFOpcPackage opcPackage(pIOHandler, filename);
|
||||||
return opcPackage.validate();
|
return opcPackage.validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,11 +620,11 @@ const aiImporterDesc *D3MFImporter::GetInfo() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3MFImporter::InternReadFile(const std::string &filename, aiScene *pScene, IOSystem *pIOHandler) {
|
void D3MFImporter::InternReadFile(const std::string &filename, aiScene *pScene, IOSystem *pIOHandler) {
|
||||||
D3MF::D3MFOpcPackage opcPackage(pIOHandler, filename);
|
D3MFOpcPackage opcPackage(pIOHandler, filename);
|
||||||
|
|
||||||
XmlParser xmlParser;
|
XmlParser xmlParser;
|
||||||
if (xmlParser.parse(opcPackage.RootStream())) {
|
if (xmlParser.parse(opcPackage.RootStream())) {
|
||||||
D3MF::XmlSerializer xmlSerializer(&xmlParser);
|
XmlSerializer xmlSerializer(&xmlParser);
|
||||||
xmlSerializer.ImportXml(pScene);
|
xmlSerializer.ImportXml(pScene);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,9 +47,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
/// @brief The 3MF-importer class.
|
||||||
class D3MFImporter : public BaseImporter {
|
class D3MFImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
// BaseImporter interface
|
|
||||||
D3MFImporter();
|
D3MFImporter();
|
||||||
~D3MFImporter();
|
~D3MFImporter();
|
||||||
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const;
|
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const;
|
||||||
|
|
|
@ -205,7 +205,7 @@ void AMFImporter::ParseHelper_FixTruncatedFloatString(const char *pInStr, std::s
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ParseHelper_Decode_Base64_IsBase64(const char pChar) {
|
static bool ParseHelper_Decode_Base64_IsBase64(const char pChar) {
|
||||||
return (isalnum(pChar) || (pChar == '+') || (pChar == '/'));
|
return (isalnum((unsigned char)pChar) || (pChar == '+') || (pChar == '/'));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AMFImporter::ParseHelper_Decode_Base64(const std::string &pInputBase64, std::vector<uint8_t> &pOutputData) const {
|
void AMFImporter::ParseHelper_Decode_Base64(const std::string &pInputBase64, std::vector<uint8_t> &pOutputData) const {
|
||||||
|
|
|
@ -359,7 +359,7 @@ void BVHLoader::ReadMotion(aiScene * /*pScene*/) {
|
||||||
std::string BVHLoader::GetNextToken() {
|
std::string BVHLoader::GetNextToken() {
|
||||||
// skip any preceding whitespace
|
// skip any preceding whitespace
|
||||||
while (mReader != mBuffer.end()) {
|
while (mReader != mBuffer.end()) {
|
||||||
if (!isspace(*mReader))
|
if (!isspace((unsigned char)*mReader))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// count lines
|
// count lines
|
||||||
|
@ -372,7 +372,7 @@ std::string BVHLoader::GetNextToken() {
|
||||||
// collect all chars till the next whitespace. BVH is easy in respect to that.
|
// collect all chars till the next whitespace. BVH is easy in respect to that.
|
||||||
std::string token;
|
std::string token;
|
||||||
while (mReader != mBuffer.end()) {
|
while (mReader != mBuffer.end()) {
|
||||||
if (isspace(*mReader))
|
if (isspace((unsigned char)*mReader))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
token.push_back(*mReader);
|
token.push_back(*mReader);
|
||||||
|
|
|
@ -420,9 +420,9 @@ void BlenderImporter::ResolveImage(aiMaterial *out, const Material *mat, const M
|
||||||
--s;
|
--s;
|
||||||
}
|
}
|
||||||
|
|
||||||
curTex->achFormatHint[0] = s + 1 > e ? '\0' : (char)::tolower(s[1]);
|
curTex->achFormatHint[0] = s + 1 > e ? '\0' : (char)::tolower((unsigned char)s[1]);
|
||||||
curTex->achFormatHint[1] = s + 2 > e ? '\0' : (char)::tolower(s[2]);
|
curTex->achFormatHint[1] = s + 2 > e ? '\0' : (char)::tolower((unsigned char)s[2]);
|
||||||
curTex->achFormatHint[2] = s + 3 > e ? '\0' : (char)::tolower(s[3]);
|
curTex->achFormatHint[2] = s + 3 > e ? '\0' : (char)::tolower((unsigned char)s[3]);
|
||||||
curTex->achFormatHint[3] = '\0';
|
curTex->achFormatHint[3] = '\0';
|
||||||
|
|
||||||
// tex->mHeight = 0;
|
// tex->mHeight = 0;
|
||||||
|
|
|
@ -234,7 +234,7 @@ void ColladaParser::UriDecodePath(aiString &ss) {
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') {
|
if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') {
|
||||||
#else
|
#else
|
||||||
if (ss.data[0] == '/' && isalpha(ss.data[1]) && ss.data[2] == ':') {
|
if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') {
|
||||||
#endif
|
#endif
|
||||||
--ss.length;
|
--ss.length;
|
||||||
::memmove(ss.data, ss.data + 1, ss.length);
|
::memmove(ss.data, ss.data + 1, ss.length);
|
||||||
|
|
|
@ -82,7 +82,7 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con
|
||||||
|
|
||||||
// lower-case shading because Blender (for example) writes "Phong"
|
// lower-case shading because Blender (for example) writes "Phong"
|
||||||
for (size_t i = 0; i < shading.length(); ++i) {
|
for (size_t i = 0; i < shading.length(); ++i) {
|
||||||
shading[i] = static_cast<char>(tolower(shading[i]));
|
shading[i] = static_cast<char>(tolower(static_cast<unsigned char>(shading[i])));
|
||||||
}
|
}
|
||||||
std::string templateName;
|
std::string templateName;
|
||||||
if(shading == "phong") {
|
if(shading == "phong") {
|
||||||
|
|
|
@ -115,7 +115,7 @@ static const aiImporterDesc desc = {
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
"ifc ifczip stp"
|
"ifc ifczip step stp"
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -136,7 +136,7 @@ bool M3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c
|
||||||
*/
|
*/
|
||||||
std::unique_ptr<IOStream> pStream(pIOHandler->Open(pFile, "rb"));
|
std::unique_ptr<IOStream> pStream(pIOHandler->Open(pFile, "rb"));
|
||||||
unsigned char data[4];
|
unsigned char data[4];
|
||||||
if (4 != pStream->Read(data, 1, 4)) {
|
if (!pStream || 4 != pStream->Read(data, 1, 4)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return !memcmp(data, "3DMO", 4) /* bin */
|
return !memcmp(data, "3DMO", 4) /* bin */
|
||||||
|
|
|
@ -702,7 +702,7 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
||||||
}
|
}
|
||||||
filename = mFile.substr(s), path = mFile.substr(0, s);
|
filename = mFile.substr(s), path = mFile.substr(0, s);
|
||||||
for (std::string::iterator it = filename.begin(); it != filename.end(); ++it) {
|
for (std::string::iterator it = filename.begin(); it != filename.end(); ++it) {
|
||||||
*it = static_cast<char>(tolower(*it));
|
*it = static_cast<char>(tolower(static_cast<unsigned char>(*it)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load multi-part model file, if necessary
|
// Load multi-part model file, if necessary
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -667,8 +667,8 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, std::vector<XFile::Materi
|
||||||
|
|
||||||
// convert to lower case for easier comparison
|
// convert to lower case for easier comparison
|
||||||
for ( unsigned int c = 0; c < sz.length(); ++c ) {
|
for ( unsigned int c = 0; c < sz.length(); ++c ) {
|
||||||
if ( isalpha( sz[ c ] ) ) {
|
if ( isalpha( (unsigned char) sz[ c ] ) ) {
|
||||||
sz[ c ] = (char) tolower( sz[ c ] );
|
sz[ c ] = (char) tolower( (unsigned char) sz[ c ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1245,13 +1245,13 @@ unsigned int XFileParser::ReadInt() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// at least one digit expected
|
// at least one digit expected
|
||||||
if (!isdigit(*mP))
|
if (!isdigit((unsigned char)*mP))
|
||||||
ThrowException("Number expected.");
|
ThrowException("Number expected.");
|
||||||
|
|
||||||
// read digits
|
// read digits
|
||||||
unsigned int number = 0;
|
unsigned int number = 0;
|
||||||
while (mP < mEnd) {
|
while (mP < mEnd) {
|
||||||
if (!isdigit(*mP))
|
if (!isdigit((unsigned char)*mP))
|
||||||
break;
|
break;
|
||||||
number = number * 10 + (*mP - 48);
|
number = number * 10 + (*mP - 48);
|
||||||
mP++;
|
mP++;
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -193,7 +179,7 @@ void BaseImporter::GetExtensionList(std::set<std::string> &extensions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < read; ++i) {
|
for (size_t i = 0; i < read; ++i) {
|
||||||
buffer[i] = static_cast<char>(::tolower(buffer[i]));
|
buffer[i] = static_cast<char>(::tolower((unsigned char)buffer[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// It is not a proper handling of unicode files here ...
|
// It is not a proper handling of unicode files here ...
|
||||||
|
@ -214,7 +200,7 @@ void BaseImporter::GetExtensionList(std::set<std::string> &extensions) {
|
||||||
token.clear();
|
token.clear();
|
||||||
const char *ptr(tokens[i]);
|
const char *ptr(tokens[i]);
|
||||||
for (size_t tokIdx = 0; tokIdx < len; ++tokIdx) {
|
for (size_t tokIdx = 0; tokIdx < len; ++tokIdx) {
|
||||||
token.push_back(static_cast<char>(tolower(*ptr)));
|
token.push_back(static_cast<char>(tolower(static_cast<unsigned char>(*ptr))));
|
||||||
++ptr;
|
++ptr;
|
||||||
}
|
}
|
||||||
const char *r = strstr(buffer, token.c_str());
|
const char *r = strstr(buffer, token.c_str());
|
||||||
|
@ -223,7 +209,7 @@ void BaseImporter::GetExtensionList(std::set<std::string> &extensions) {
|
||||||
}
|
}
|
||||||
// We need to make sure that we didn't accidentially identify the end of another token as our token,
|
// We need to make sure that we didn't accidentially identify the end of another token as our token,
|
||||||
// e.g. in a previous version the "gltf " present in some gltf files was detected as "f "
|
// e.g. in a previous version the "gltf " present in some gltf files was detected as "f "
|
||||||
if (noAlphaBeforeTokens && (r != buffer && isalpha(r[-1]))) {
|
if (noAlphaBeforeTokens && (r != buffer && isalpha(static_cast<unsigned char>(r[-1])))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// We got a match, either we don't care where it is, or it happens to
|
// We got a match, either we don't care where it is, or it happens to
|
||||||
|
|
|
@ -48,6 +48,7 @@ corresponding preprocessor flag to selectively disable formats.
|
||||||
|
|
||||||
#include <assimp/BaseImporter.h>
|
#include <assimp/BaseImporter.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Importers
|
// Importers
|
||||||
|
@ -204,7 +205,17 @@ corresponding preprocessor flag to selectively disable formats.
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void GetImporterInstanceList(std::vector<BaseImporter *> &out) {
|
void GetImporterInstanceList(std::vector<BaseImporter *> &out) {
|
||||||
|
|
||||||
|
// Some importers may be unimplemented or otherwise unsuitable for general use
|
||||||
|
// in their current state. Devs can set ASSIMP_ENABLE_DEV_IMPORTERS in their
|
||||||
|
// local environment to enable them, otherwise they're left out of the registry.
|
||||||
|
const char *envStr = std::getenv("ASSIMP_ENABLE_DEV_IMPORTERS");
|
||||||
|
bool devImportersEnabled = envStr && strcmp(envStr, "0");
|
||||||
|
|
||||||
|
// Ensure no unused var warnings if all uses are #ifndef'd away below:
|
||||||
|
(void)devImportersEnabled;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Add an instance of each worker class here
|
// Add an instance of each worker class here
|
||||||
// (register_new_importers_here)
|
// (register_new_importers_here)
|
||||||
|
@ -354,7 +365,9 @@ void GetImporterInstanceList(std::vector<BaseImporter *> &out) {
|
||||||
out.push_back(new D3MFImporter());
|
out.push_back(new D3MFImporter());
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
|
||||||
out.push_back(new X3DImporter());
|
if (devImportersEnabled) { // https://github.com/assimp/assimp/issues/3647
|
||||||
|
out.push_back(new X3DImporter());
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
|
||||||
out.push_back(new MMDImporter());
|
out.push_back(new MMDImporter());
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -252,7 +252,7 @@ DecoderBuffer ParseLineIntoDecoderBuffer(DecoderBuffer *buffer) {
|
||||||
|
|
||||||
std::string ToLower(const std::string &str) {
|
std::string ToLower(const std::string &str) {
|
||||||
std::string out;
|
std::string out;
|
||||||
std::transform(str.begin(), str.end(), std::back_inserter(out), tolower);
|
std::transform(str.begin(), str.end(), std::back_inserter(out), [](unsigned char c){return tolower(c);});
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -268,14 +268,14 @@ std::vector<std::string> PlyReader::SplitWords(const std::string &line) {
|
||||||
while ((end = line.find_first_of(" \t\n\v\f\r", start)) !=
|
while ((end = line.find_first_of(" \t\n\v\f\r", start)) !=
|
||||||
std::string::npos) {
|
std::string::npos) {
|
||||||
const std::string word(line.substr(start, end - start));
|
const std::string word(line.substr(start, end - start));
|
||||||
if (!std::all_of(word.begin(), word.end(), isspace)) {
|
if (!std::all_of(word.begin(), word.end(), [](unsigned char c){return isspace(c);})) {
|
||||||
output.push_back(word);
|
output.push_back(word);
|
||||||
}
|
}
|
||||||
start = end + 1;
|
start = end + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string last_word(line.substr(start));
|
const std::string last_word(line.substr(start));
|
||||||
if (!std::all_of(last_word.begin(), last_word.end(), isspace)) {
|
if (!std::all_of(last_word.begin(), last_word.end(), [](unsigned char c){return isspace(c);})) {
|
||||||
output.push_back(last_word);
|
output.push_back(last_word);
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
|
|
|
@ -644,7 +644,7 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
|
||||||
|
|
||||||
// Check for invalid characters
|
// Check for invalid characters
|
||||||
for (std::string::size_type index = 0; index < name.size(); ++index) {
|
for (std::string::size_type index = 0; index < name.size(); ++index) {
|
||||||
if (!isalnum(name[index]) && name[index] != '_')
|
if (!IsAlNum(name[index]) && name[index] != '_')
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -262,7 +262,7 @@ AI_FORCE_INLINE unsigned int tokenize(const string_type &str, std::vector<string
|
||||||
inline std::string ai_stdStrToLower(const std::string &str) {
|
inline std::string ai_stdStrToLower(const std::string &str) {
|
||||||
std::string out(str);
|
std::string out(str);
|
||||||
for (size_t i = 0; i < str.size(); ++i) {
|
for (size_t i = 0; i < str.size(); ++i) {
|
||||||
out[i] = (char) tolower(out[i]);
|
out[i] = (char) tolower((unsigned char)out[i]);
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,8 +146,8 @@ inline int ASSIMP_stricmp(const char *s1, const char *s2) {
|
||||||
#else
|
#else
|
||||||
char c1, c2;
|
char c1, c2;
|
||||||
do {
|
do {
|
||||||
c1 = tolower(*s1++);
|
c1 = tolower((unsigned char)*(s1++));
|
||||||
c2 = tolower(*s2++);
|
c2 = tolower((unsigned char)*(s2++));
|
||||||
} while (c1 && (c1 == c2));
|
} while (c1 && (c1 == c2));
|
||||||
return c1 - c2;
|
return c1 - c2;
|
||||||
#endif
|
#endif
|
||||||
|
@ -197,8 +197,8 @@ inline int ASSIMP_strincmp(const char *s1, const char *s2, unsigned int n) {
|
||||||
unsigned int p = 0;
|
unsigned int p = 0;
|
||||||
do {
|
do {
|
||||||
if (p++ >= n) return 0;
|
if (p++ >= n) return 0;
|
||||||
c1 = tolower(*s1++);
|
c1 = tolower((unsigned char)*(s1++));
|
||||||
c2 = tolower(*s2++);
|
c2 = tolower((unsigned char)*(s2++));
|
||||||
} while (c1 && (c1 == c2));
|
} while (c1 && (c1 == c2));
|
||||||
|
|
||||||
return c1 - c2;
|
return c1 - c2;
|
||||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2021, assimp team
|
Copyright (c) 2006-2021, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -55,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define AI_SIZEFMT "%Iu"
|
#define AI_SIZEFMT "%Iu"
|
||||||
|
@ -157,7 +157,7 @@ AI_FORCE_INLINE std::string ai_decimal_to_hexa(T toConvert) {
|
||||||
ss >> result;
|
ss >> result;
|
||||||
|
|
||||||
for (size_t i = 0; i < result.size(); ++i) {
|
for (size_t i = 0; i < result.size(); ++i) {
|
||||||
result[i] = (char)toupper(result[i]);
|
result[i] = (char)toupper((unsigned char)result[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -177,7 +177,7 @@ AI_FORCE_INLINE std::string ai_rgba2hex(int r, int g, int b, int a, bool with_he
|
||||||
if (with_head) {
|
if (with_head) {
|
||||||
ss << "#";
|
ss << "#";
|
||||||
}
|
}
|
||||||
ss << std::hex << (r << 24 | g << 16 | b << 8 | a);
|
ss << std::hex << std::setfill('0') << std::setw(8) << (r << 24 | g << 16 | b << 8 | a);
|
||||||
|
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
@ -249,4 +249,4 @@ AI_FORCE_INLINE std::string ai_str_toupper(const std::string &in) {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif // INCLUDED_AI_STRINGUTILS_H
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Binary file not shown.
|
@ -42,9 +42,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/StringUtils.h>
|
#include <assimp/StringUtils.h>
|
||||||
|
|
||||||
class utStringUtils : public ::testing::Test {
|
class utStringUtils : public ::testing::Test {
|
||||||
|
// empty
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F( utStringUtils, to_string_Test ) {
|
TEST_F(utStringUtils, to_string_Test ) {
|
||||||
std::string res = ai_to_string( 1 );
|
std::string res = ai_to_string( 1 );
|
||||||
EXPECT_EQ( res, "1" );
|
EXPECT_EQ( res, "1" );
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ TEST_F( utStringUtils, to_string_Test ) {
|
||||||
EXPECT_EQ( res, "1" );
|
EXPECT_EQ( res, "1" );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F( utStringUtils, ai_strtofTest ) {
|
TEST_F(utStringUtils, ai_strtofTest ) {
|
||||||
float res = ai_strtof( nullptr, nullptr );
|
float res = ai_strtof( nullptr, nullptr );
|
||||||
EXPECT_FLOAT_EQ( res, 0.0f );
|
EXPECT_FLOAT_EQ( res, 0.0f );
|
||||||
|
|
||||||
|
@ -66,3 +67,11 @@ TEST_F( utStringUtils, ai_strtofTest ) {
|
||||||
res = ai_strtof( begin, end );
|
res = ai_strtof( begin, end );
|
||||||
EXPECT_FLOAT_EQ( res, 200.0f );
|
EXPECT_FLOAT_EQ( res, 200.0f );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(utStringUtils, ai_rgba2hexTest) {
|
||||||
|
std::string result;
|
||||||
|
result = ai_rgba2hex(255, 255, 255, 255, true);
|
||||||
|
EXPECT_EQ(result, "#ffffffff");
|
||||||
|
result = ai_rgba2hex(0, 0, 0, 0, false);
|
||||||
|
EXPECT_EQ(result, "00000000");
|
||||||
|
}
|
||||||
|
|
|
@ -272,7 +272,7 @@ bool CMaterialManager::TryLongerPath(char* szTemp,aiString* p_szString)
|
||||||
szExtFound - 1 - info.cFileName);
|
szExtFound - 1 - info.cFileName);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < iSizeFound;++i)
|
for (unsigned int i = 0; i < iSizeFound;++i)
|
||||||
info.cFileName[i] = (CHAR)tolower(info.cFileName[i]);
|
info.cFileName[i] = (CHAR)tolower((unsigned char)info.cFileName[i]);
|
||||||
|
|
||||||
if (0 == memcmp(info.cFileName,szFile2, std::min(iSizeFound,iSize)))
|
if (0 == memcmp(info.cFileName,szFile2, std::min(iSizeFound,iSize)))
|
||||||
{
|
{
|
||||||
|
@ -354,7 +354,7 @@ int CMaterialManager::FindValidPath(aiString* p_szString)
|
||||||
for (unsigned int i = 0;;++i)
|
for (unsigned int i = 0;;++i)
|
||||||
{
|
{
|
||||||
if ('\0' == szTemp[i])break;
|
if ('\0' == szTemp[i])break;
|
||||||
szTemp[i] = (char)tolower(szTemp[i]);
|
szTemp[i] = (char)tolower((unsigned char)szTemp[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(TryLongerPath(szTemp,p_szString))return 1;
|
if(TryLongerPath(szTemp,p_szString))return 1;
|
||||||
|
|
Loading…
Reference in New Issue