Fix empty mesh handling
parent
e673d1fd9e
commit
518c26ede6
|
@ -103,10 +103,6 @@ Discreet3DSImporter::Discreet3DSImporter() :
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
Discreet3DSImporter::~Discreet3DSImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool Discreet3DSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
bool Discreet3DSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
||||||
|
|
|
@ -59,7 +59,6 @@ struct aiNode;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
|
||||||
using namespace D3DS;
|
using namespace D3DS;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
|
@ -68,7 +67,7 @@ using namespace D3DS;
|
||||||
class Discreet3DSImporter : public BaseImporter {
|
class Discreet3DSImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
Discreet3DSImporter();
|
Discreet3DSImporter();
|
||||||
~Discreet3DSImporter() override;
|
~Discreet3DSImporter() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
|
|
|
@ -95,7 +95,7 @@ FBXImporter::FBXImporter() = default;
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool FBXImporter::CanRead(const std::string & pFile, IOSystem * pIOHandler, bool /*checkSig*/) const {
|
bool FBXImporter::CanRead(const std::string & pFile, IOSystem * pIOHandler, bool /*checkSig*/) const {
|
||||||
// at least ASCII-FBX files usually have a 'FBX' somewhere in their head
|
// at least ASCII-FBX files usually have a 'FBX' somewhere in their head
|
||||||
static const char *tokens[] = { "fbx" };
|
static const char *tokens[] = { " \n\r\n " };
|
||||||
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
|
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,13 +100,6 @@ bool IQMImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c
|
||||||
if (!pIOHandler) {
|
if (!pIOHandler) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* don't use CheckMagicToken because that checks with swapped bytes too, leading to false
|
|
||||||
* positives. This magic is not uint32_t, but char[4], so memcmp is the best way
|
|
||||||
|
|
||||||
const char* tokens[] = {"3DMO", "3dmo"};
|
|
||||||
return CheckMagicToken(pIOHandler,pFile,tokens,2,0,4);
|
|
||||||
*/
|
|
||||||
std::unique_ptr<IOStream> pStream(pIOHandler->Open(pFile, "rb"));
|
std::unique_ptr<IOStream> pStream(pIOHandler->Open(pFile, "rb"));
|
||||||
unsigned char data[15];
|
unsigned char data[15];
|
||||||
if (!pStream || 15 != pStream->Read(data, 1, 15)) {
|
if (!pStream || 15 != pStream->Read(data, 1, 15)) {
|
||||||
|
|
|
@ -78,7 +78,9 @@ using namespace std;
|
||||||
ObjFileImporter::ObjFileImporter() :
|
ObjFileImporter::ObjFileImporter() :
|
||||||
m_Buffer(),
|
m_Buffer(),
|
||||||
m_pRootObject(nullptr),
|
m_pRootObject(nullptr),
|
||||||
m_strAbsPath(std::string(1, DefaultIOSystem().getOsSeparator())) {}
|
m_strAbsPath(std::string(1, DefaultIOSystem().getOsSeparator())) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor.
|
// Destructor.
|
||||||
|
@ -102,7 +104,7 @@ const aiImporterDesc *ObjFileImporter::GetInfo() const {
|
||||||
// Obj-file import implementation
|
// Obj-file import implementation
|
||||||
void ObjFileImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSystem *pIOHandler) {
|
void ObjFileImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSystem *pIOHandler) {
|
||||||
// Read file into memory
|
// Read file into memory
|
||||||
static const std::string mode = "rb";
|
static constexpr char mode[] = "rb";
|
||||||
auto streamCloser = [&](IOStream *pStream) {
|
auto streamCloser = [&](IOStream *pStream) {
|
||||||
pIOHandler->Close(pStream);
|
pIOHandler->Close(pStream);
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2023, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -56,62 +56,43 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
//#include <cctype>
|
|
||||||
//#include <memory>
|
|
||||||
|
|
||||||
using namespace Assimp;
|
namespace Assimp {
|
||||||
|
|
||||||
namespace Assimp { // this has to be in here because LogFunctions is in ::Assimp
|
static constexpr uint32_t ErrorId = ~0u;
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
const char *LogFunctions<XGLImporter>::Prefix() {
|
const char *LogFunctions<XGLImporter>::Prefix() {
|
||||||
return "XGL: ";
|
return "XGL: ";
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Assimp
|
static constexpr aiImporterDesc desc = {
|
||||||
|
"XGL Importer", "", "", "",
|
||||||
static const aiImporterDesc desc = {
|
|
||||||
"XGL Importer",
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportCompressedFlavour,
|
aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportCompressedFlavour,
|
||||||
0,
|
0, 0, 0, 0, "xgl zgl"};
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
"xgl zgl"
|
|
||||||
};
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
XGLImporter::XGLImporter() : mXmlParser(nullptr), m_scene(nullptr) {
|
||||||
XGLImporter::XGLImporter() :
|
|
||||||
mXmlParser(nullptr),
|
|
||||||
m_scene(nullptr) {
|
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor, private as well
|
|
||||||
XGLImporter::~XGLImporter() {
|
XGLImporter::~XGLImporter() {
|
||||||
delete mXmlParser;
|
delete mXmlParser;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
|
||||||
bool XGLImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
bool XGLImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
||||||
static const char *tokens[] = { "<world>", "<World>", "<WORLD>" };
|
static const char *tokens[] = { "<world>", "<World>", "<WORLD>" };
|
||||||
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
|
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Get a list of all file extensions which are handled by this class
|
|
||||||
const aiImporterDesc *XGLImporter::GetInfo() const {
|
const aiImporterDesc *XGLImporter::GetInfo() const {
|
||||||
return &desc;
|
return &desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file into the given scene structure.
|
|
||||||
void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
|
void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
|
||||||
#ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL
|
#ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL
|
||||||
std::vector<char> uncompressed;
|
std::vector<char> uncompressed;
|
||||||
|
@ -159,7 +140,7 @@ void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
||||||
|
|
||||||
std::vector<aiMesh *> &meshes = scope.meshes_linear;
|
std::vector<aiMesh *> &meshes = scope.meshes_linear;
|
||||||
std::vector<aiMaterial *> &materials = scope.materials_linear;
|
std::vector<aiMaterial *> &materials = scope.materials_linear;
|
||||||
if (!meshes.size() || !materials.size()) {
|
if (meshes.empty() || materials.empty()) {
|
||||||
ThrowException("failed to extract data from XGL file, no meshes loaded");
|
ThrowException("failed to extract data from XGL file, no meshes loaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,9 +180,10 @@ void XGLImporter::ReadWorld(XmlNode &node, TempScope &scope) {
|
||||||
}
|
}
|
||||||
|
|
||||||
aiNode *const nd = ReadObject(node, scope);
|
aiNode *const nd = ReadObject(node, scope);
|
||||||
if (!nd) {
|
if (nd == nullptr) {
|
||||||
ThrowException("failure reading <world>");
|
ThrowException("failure reading <world>");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nd->mName.length == 0) {
|
if (nd->mName.length == 0) {
|
||||||
nd->mName.Set("WORLD");
|
nd->mName.Set("WORLD");
|
||||||
}
|
}
|
||||||
|
@ -254,15 +236,19 @@ aiNode *XGLImporter::ReadObject(XmlNode &node, TempScope &scope) {
|
||||||
const std::string &s = ai_stdStrToLower(child.name());
|
const std::string &s = ai_stdStrToLower(child.name());
|
||||||
if (s == "mesh") {
|
if (s == "mesh") {
|
||||||
const size_t prev = scope.meshes_linear.size();
|
const size_t prev = scope.meshes_linear.size();
|
||||||
bool empty;
|
if (ReadMesh(child, scope)) {
|
||||||
if (ReadMesh(child, scope, empty)) {
|
|
||||||
const size_t newc = scope.meshes_linear.size();
|
const size_t newc = scope.meshes_linear.size();
|
||||||
for (size_t i = 0; i < newc - prev; ++i) {
|
for (size_t i = 0; i < newc - prev; ++i) {
|
||||||
meshes.push_back(static_cast<unsigned int>(i + prev));
|
meshes.push_back(static_cast<unsigned int>(i + prev));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
printf("skipping empty mesh\n");
|
||||||
}
|
}
|
||||||
} else if (s == "mat") {
|
} else if (s == "mat") {
|
||||||
ReadMaterial(child, scope);
|
const uint32_t matId = ReadMaterial(child, scope);
|
||||||
|
if (matId == ErrorId) {
|
||||||
|
ThrowException("Invalid material id detected.");
|
||||||
|
}
|
||||||
} else if (s == "object") {
|
} else if (s == "object") {
|
||||||
children.push_back(ReadObject(child, scope));
|
children.push_back(ReadObject(child, scope));
|
||||||
} else if (s == "objectref") {
|
} else if (s == "objectref") {
|
||||||
|
@ -438,18 +424,25 @@ aiMesh *XGLImporter::ToOutputMesh(const TempMaterialMesh &m) {
|
||||||
return mesh.release();
|
return mesh.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
bool XGLImporter::ReadMesh(XmlNode &node, TempScope &scope, bool &empty) {
|
|
||||||
TempMesh t;
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
inline static unsigned int generateMeshId(unsigned int meshId, bool nor, bool uv) {
|
||||||
|
unsigned int currentMeshId = meshId | ((nor ? 1 : 0) << 31) | ((uv ? 1 : 0) << 30);
|
||||||
|
return currentMeshId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
bool XGLImporter::ReadMesh(XmlNode &node, TempScope &scope) {
|
||||||
|
TempMesh t;
|
||||||
|
uint32_t matId = 99999;
|
||||||
|
bool mesh_created = false;
|
||||||
std::map<unsigned int, TempMaterialMesh> bymat;
|
std::map<unsigned int, TempMaterialMesh> bymat;
|
||||||
const unsigned int mesh_id = ReadIDAttr(node);
|
const unsigned int mesh_id = ReadIDAttr(node);
|
||||||
bool empty_mesh = true;
|
|
||||||
for (XmlNode &child : node.children()) {
|
for (XmlNode &child : node.children()) {
|
||||||
const std::string &s = ai_stdStrToLower(child.name());
|
const std::string &s = ai_stdStrToLower(child.name());
|
||||||
|
|
||||||
if (s == "mat") {
|
if (s == "mat") {
|
||||||
ReadMaterial(child, scope);
|
matId = ReadMaterial(child, scope);
|
||||||
} else if (s == "p") {
|
} else if (s == "p") {
|
||||||
pugi::xml_attribute attr = child.attribute("ID");
|
pugi::xml_attribute attr = child.attribute("ID");
|
||||||
if (attr.empty()) {
|
if (attr.empty()) {
|
||||||
|
@ -477,9 +470,79 @@ bool XGLImporter::ReadMesh(XmlNode &node, TempScope &scope, bool &empty) {
|
||||||
} else if (s == "f" || s == "l" || s == "p") {
|
} else if (s == "f" || s == "l" || s == "p") {
|
||||||
const unsigned int vcount = s == "f" ? 3 : (s == "l" ? 2 : 1);
|
const unsigned int vcount = s == "f" ? 3 : (s == "l" ? 2 : 1);
|
||||||
|
|
||||||
unsigned int mid = ~0u;
|
unsigned int meshId = ErrorId;
|
||||||
TempFace tf[3];
|
TempFace tempFace[3] = {};
|
||||||
bool has[3] = { false };
|
bool has[3] = { false };
|
||||||
|
meshId = ReadVertices(child, t, tempFace, has, meshId, scope);
|
||||||
|
if (meshId == ErrorId) {
|
||||||
|
ThrowException("missing material index");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nor = false, uv = false;
|
||||||
|
for (unsigned int i = 0; i < vcount; ++i) {
|
||||||
|
if (!has[i]) {
|
||||||
|
ThrowException("missing face vertex data");
|
||||||
|
}
|
||||||
|
|
||||||
|
nor = nor || tempFace[i].has_normal;
|
||||||
|
uv = uv || tempFace[i].has_uv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (meshId >= (1 << 30)) {
|
||||||
|
LogWarn("material indices exhausted, this may cause errors in the output");
|
||||||
|
}
|
||||||
|
const unsigned int currentMeshId = generateMeshId(meshId, nor, uv);
|
||||||
|
|
||||||
|
// Generate the temp mesh
|
||||||
|
TempMaterialMesh &mesh = bymat[currentMeshId];
|
||||||
|
mesh.matid = meshId;
|
||||||
|
mesh_created = true;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < vcount; ++i) {
|
||||||
|
mesh.positions.push_back(tempFace[i].pos);
|
||||||
|
if (nor) {
|
||||||
|
mesh.normals.push_back(tempFace[i].normal);
|
||||||
|
}
|
||||||
|
if (uv) {
|
||||||
|
mesh.uvs.push_back(tempFace[i].uv);
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh.pflags |= 1 << (vcount - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh.vcounts.push_back(vcount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mesh_created) {
|
||||||
|
TempMaterialMesh &mesh = bymat[mesh_id];
|
||||||
|
mesh.matid = matId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// finally extract output meshes and add them to the scope
|
||||||
|
AppendOutputMeshes(bymat, scope, mesh_id);
|
||||||
|
|
||||||
|
// no id == not a reference, insert this mesh right *here*
|
||||||
|
return mesh_id == ErrorId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------------------------
|
||||||
|
void XGLImporter::AppendOutputMeshes(std::map<unsigned int, TempMaterialMesh> bymat, TempScope &scope,
|
||||||
|
const unsigned int mesh_id) {
|
||||||
|
using pairt = std::pair<const unsigned int, TempMaterialMesh>;
|
||||||
|
for (const pairt &p : bymat) {
|
||||||
|
aiMesh *const m = ToOutputMesh(p.second);
|
||||||
|
scope.meshes_linear.push_back(m);
|
||||||
|
|
||||||
|
// if this is a definition, keep it on the stack
|
||||||
|
if (mesh_id != ErrorId) {
|
||||||
|
scope.meshes.insert(std::pair<unsigned int, aiMesh *>(mesh_id, m));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------------------------
|
||||||
|
unsigned int XGLImporter::ReadVertices(XmlNode &child, TempMesh t, TempFace *tf, bool *has, unsigned int mid, TempScope &scope) {
|
||||||
for (XmlNode &sub_child : child.children()) {
|
for (XmlNode &sub_child : child.children()) {
|
||||||
const std::string &scn = ai_stdStrToLower(sub_child.name());
|
const std::string &scn = ai_stdStrToLower(sub_child.name());
|
||||||
if (scn == "fv1" || scn == "lv1" || scn == "pv1") {
|
if (scn == "fv1" || scn == "lv1" || scn == "pv1") {
|
||||||
|
@ -492,79 +555,18 @@ bool XGLImporter::ReadMesh(XmlNode &node, TempScope &scope, bool &empty) {
|
||||||
ReadFaceVertex(sub_child, t, tf[2]);
|
ReadFaceVertex(sub_child, t, tf[2]);
|
||||||
has[2] = true;
|
has[2] = true;
|
||||||
} else if (scn == "mat") {
|
} else if (scn == "mat") {
|
||||||
if (mid != ~0u) {
|
if (mid != ErrorId) {
|
||||||
LogWarn("only one material tag allowed per <f>");
|
LogWarn("only one material tag allowed per <f>");
|
||||||
}
|
}
|
||||||
mid = ResolveMaterialRef(sub_child, scope);
|
mid = ResolveMaterialRef(sub_child, scope);
|
||||||
} else if (scn == "matref") {
|
} else if (scn == "matref") {
|
||||||
if (mid != ~0u) {
|
if (mid != ErrorId) {
|
||||||
LogWarn("only one material tag allowed per <f>");
|
LogWarn("only one material tag allowed per <f>");
|
||||||
}
|
}
|
||||||
mid = ResolveMaterialRef(sub_child, scope);
|
mid = ResolveMaterialRef(sub_child, scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (has[0] || has[1] || has[2]) {
|
return mid;
|
||||||
empty_mesh = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mid == ~0u) {
|
|
||||||
ThrowException("missing material index");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nor = false;
|
|
||||||
bool uv = false;
|
|
||||||
for (unsigned int i = 0; i < vcount; ++i) {
|
|
||||||
if (!has[i]) {
|
|
||||||
ThrowException("missing face vertex data");
|
|
||||||
}
|
|
||||||
|
|
||||||
nor = nor || tf[i].has_normal;
|
|
||||||
uv = uv || tf[i].has_uv;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mid >= (1 << 30)) {
|
|
||||||
LogWarn("material indices exhausted, this may cause errors in the output");
|
|
||||||
}
|
|
||||||
unsigned int meshId = mid | ((nor ? 1 : 0) << 31) | ((uv ? 1 : 0) << 30);
|
|
||||||
|
|
||||||
TempMaterialMesh &mesh = bymat[meshId];
|
|
||||||
mesh.matid = mid;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < vcount; ++i) {
|
|
||||||
mesh.positions.push_back(tf[i].pos);
|
|
||||||
if (nor) {
|
|
||||||
mesh.normals.push_back(tf[i].normal);
|
|
||||||
}
|
|
||||||
if (uv) {
|
|
||||||
mesh.uvs.push_back(tf[i].uv);
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh.pflags |= 1 << (vcount - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh.vcounts.push_back(vcount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// finally extract output meshes and add them to the scope
|
|
||||||
using pairt = std::pair<const unsigned int, TempMaterialMesh>;
|
|
||||||
for (const pairt &p : bymat) {
|
|
||||||
aiMesh *const m = ToOutputMesh(p.second);
|
|
||||||
scope.meshes_linear.push_back(m);
|
|
||||||
|
|
||||||
// if this is a definition, keep it on the stack
|
|
||||||
if (mesh_id != ~0u) {
|
|
||||||
scope.meshes.insert(std::pair<unsigned int, aiMesh *>(mesh_id, m));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (empty_mesh) {
|
|
||||||
LogWarn("Mesh is empty, skipping.");
|
|
||||||
empty = empty_mesh;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// no id == not a reference, insert this mesh right *here*
|
|
||||||
return mesh_id == ~0u;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------
|
||||||
|
@ -598,10 +600,10 @@ unsigned int XGLImporter::ResolveMaterialRef(XmlNode &node, TempScope &scope) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void XGLImporter::ReadMaterial(XmlNode &node, TempScope &scope) {
|
unsigned int XGLImporter::ReadMaterial(XmlNode &node, TempScope &scope) {
|
||||||
const unsigned int mat_id = ReadIDAttr(node);
|
const unsigned int mat_id = ReadIDAttr(node);
|
||||||
|
|
||||||
auto *mat(new aiMaterial);
|
auto *mat = new aiMaterial;
|
||||||
for (XmlNode &child : node.children()) {
|
for (XmlNode &child : node.children()) {
|
||||||
const std::string &s = ai_stdStrToLower(child.name());
|
const std::string &s = ai_stdStrToLower(child.name());
|
||||||
if (s == "amb") {
|
if (s == "amb") {
|
||||||
|
@ -627,6 +629,8 @@ void XGLImporter::ReadMaterial(XmlNode &node, TempScope &scope) {
|
||||||
|
|
||||||
scope.materials[mat_id] = mat;
|
scope.materials[mat_id] = mat;
|
||||||
scope.materials_linear.push_back(mat);
|
scope.materials_linear.push_back(mat);
|
||||||
|
|
||||||
|
return mat_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------
|
||||||
|
@ -683,7 +687,7 @@ unsigned int XGLImporter::ReadIDAttr(XmlNode &node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ~0u;
|
return ErrorId;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -712,14 +716,14 @@ unsigned int XGLImporter::ReadIndexFromText(XmlNode &node) {
|
||||||
const char *s = v.c_str();
|
const char *s = v.c_str();
|
||||||
if (!SkipSpaces(&s)) {
|
if (!SkipSpaces(&s)) {
|
||||||
LogError("unexpected EOL, failed to parse index element");
|
LogError("unexpected EOL, failed to parse index element");
|
||||||
return ~0u;
|
return ErrorId;
|
||||||
}
|
}
|
||||||
const char *se;
|
const char *se = nullptr;
|
||||||
const unsigned int t = strtoul10(s, &se);
|
const unsigned int t = strtoul10(s, &se);
|
||||||
|
|
||||||
if (se == s) {
|
if (se == s) {
|
||||||
LogError("failed to read index");
|
LogError("failed to read index");
|
||||||
return ~0u;
|
return ErrorId;
|
||||||
}
|
}
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
|
@ -786,4 +790,6 @@ aiColor3D XGLImporter::ReadCol3(XmlNode &node) {
|
||||||
return aiColor3D(v.x, v.y, v.z);
|
return aiColor3D(v.x, v.y, v.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Assimp
|
||||||
|
|
||||||
#endif // ASSIMP_BUILD_NO_XGL_IMPORTER
|
#endif // ASSIMP_BUILD_NO_XGL_IMPORTER
|
||||||
|
|
|
@ -69,12 +69,14 @@ namespace Assimp {
|
||||||
*/
|
*/
|
||||||
class XGLImporter : public BaseImporter, public LogFunctions<XGLImporter> {
|
class XGLImporter : public BaseImporter, public LogFunctions<XGLImporter> {
|
||||||
public:
|
public:
|
||||||
|
/// @brief The class constructor.
|
||||||
XGLImporter();
|
XGLImporter();
|
||||||
|
|
||||||
|
/// @brief The class destructor.
|
||||||
~XGLImporter() override;
|
~XGLImporter() override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
/// @brief Returns whether the class can handle the format of the given file.
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/// @see BaseImporter::CanRead() for details. */
|
||||||
* See BaseImporter::CanRead() for details. */
|
|
||||||
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
|
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
|
||||||
bool checkSig) const override;
|
bool checkSig) const override;
|
||||||
|
|
||||||
|
@ -92,10 +94,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct TempScope {
|
struct TempScope {
|
||||||
TempScope() :
|
TempScope() : light() {}
|
||||||
light() {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
~TempScope() {
|
~TempScope() {
|
||||||
for (aiMesh *m : meshes_linear) {
|
for (aiMesh *m : meshes_linear) {
|
||||||
|
@ -145,9 +144,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TempMaterialMesh {
|
struct TempMaterialMesh {
|
||||||
TempMaterialMesh() :
|
TempMaterialMesh() : pflags(), matid() {
|
||||||
pflags(),
|
|
||||||
matid() {
|
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,9 +157,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TempFace {
|
struct TempFace {
|
||||||
TempFace() :
|
TempFace() : has_uv(), has_normal() {
|
||||||
has_uv(),
|
|
||||||
has_normal() {
|
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,26 +170,25 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Cleanup();
|
void Cleanup();
|
||||||
|
|
||||||
std::string GetElementName();
|
std::string GetElementName();
|
||||||
bool ReadElement();
|
bool ReadElement();
|
||||||
bool ReadElementUpToClosing(const char *closetag);
|
bool ReadElementUpToClosing(const char *closetag);
|
||||||
bool SkipToText();
|
bool SkipToText();
|
||||||
unsigned int ReadIDAttr(XmlNode &node);
|
unsigned int ReadIDAttr(XmlNode &node);
|
||||||
|
|
||||||
void ReadWorld(XmlNode &node, TempScope &scope);
|
void ReadWorld(XmlNode &node, TempScope &scope);
|
||||||
void ReadLighting(XmlNode &node, TempScope &scope);
|
void ReadLighting(XmlNode &node, TempScope &scope);
|
||||||
aiLight *ReadDirectionalLight(XmlNode &node);
|
aiLight *ReadDirectionalLight(XmlNode &node);
|
||||||
aiNode *ReadObject(XmlNode &node, TempScope &scope);
|
aiNode *ReadObject(XmlNode &node, TempScope &scope);
|
||||||
bool ReadMesh(XmlNode &node, TempScope &scope, bool &empty);
|
bool ReadMesh(XmlNode &node, TempScope &scope);
|
||||||
void ReadMaterial(XmlNode &node, TempScope &scope);
|
void AppendOutputMeshes(std::map<unsigned int, TempMaterialMesh> bymat, TempScope &scope, const unsigned int mesh_id);
|
||||||
|
unsigned int ReadVertices(XmlNode &child, TempMesh t, TempFace *tf, bool *has, unsigned int mid, TempScope &scope);
|
||||||
|
unsigned int ReadMaterial(XmlNode &node, TempScope &scope);
|
||||||
aiVector2D ReadVec2(XmlNode &node);
|
aiVector2D ReadVec2(XmlNode &node);
|
||||||
aiVector3D ReadVec3(XmlNode &node);
|
aiVector3D ReadVec3(XmlNode &node);
|
||||||
aiColor3D ReadCol3(XmlNode &node);
|
aiColor3D ReadCol3(XmlNode &node);
|
||||||
aiMatrix4x4 ReadTrafo(XmlNode &node);
|
aiMatrix4x4 ReadTrafo(XmlNode &node);
|
||||||
unsigned int ReadIndexFromText(XmlNode &node);
|
unsigned int ReadIndexFromText(XmlNode &node);
|
||||||
float ReadFloat(XmlNode &node);
|
float ReadFloat(XmlNode &node);
|
||||||
|
|
||||||
aiMesh *ToOutputMesh(const TempMaterialMesh &m);
|
aiMesh *ToOutputMesh(const TempMaterialMesh &m);
|
||||||
void ReadFaceVertex(XmlNode &node, const TempMesh &t, TempFace &out);
|
void ReadFaceVertex(XmlNode &node, const TempMesh &t, TempFace &out);
|
||||||
unsigned int ResolveMaterialRef(XmlNode &node, TempScope &scope);
|
unsigned int ResolveMaterialRef(XmlNode &node, TempScope &scope);
|
||||||
|
|
|
@ -66,6 +66,10 @@ Compression::Compression() :
|
||||||
Compression::~Compression() {
|
Compression::~Compression() {
|
||||||
ai_assert(mImpl != nullptr);
|
ai_assert(mImpl != nullptr);
|
||||||
|
|
||||||
|
if (mImpl->mOpen) {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
delete mImpl;
|
delete mImpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +128,7 @@ static int getFlushMode(Compression::FlushMode flush) {
|
||||||
return z_flush;
|
return z_flush;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr size_t MYBLOCK = 32786;
|
static constexpr size_t MYBLOCK = 32786;
|
||||||
|
|
||||||
size_t Compression::decompress(const void *data, size_t in, std::vector<char> &uncompressed) {
|
size_t Compression::decompress(const void *data, size_t in, std::vector<char> &uncompressed) {
|
||||||
ai_assert(mImpl != nullptr);
|
ai_assert(mImpl != nullptr);
|
||||||
|
|
|
@ -40,6 +40,9 @@
|
||||||
# define crc32 z_crc32
|
# define crc32 z_crc32
|
||||||
# define crc32_combine z_crc32_combine
|
# define crc32_combine z_crc32_combine
|
||||||
# define crc32_combine64 z_crc32_combine64
|
# define crc32_combine64 z_crc32_combine64
|
||||||
|
# define crc32_combine_gen z_crc32_combine_gen
|
||||||
|
# define crc32_combine_gen64 z_crc32_combine_gen64
|
||||||
|
# define crc32_combine_op z_crc32_combine_op
|
||||||
# define crc32_z z_crc32_z
|
# define crc32_z z_crc32_z
|
||||||
# define deflate z_deflate
|
# define deflate z_deflate
|
||||||
# define deflateBound z_deflateBound
|
# define deflateBound z_deflateBound
|
||||||
|
@ -351,6 +354,9 @@
|
||||||
# ifdef FAR
|
# ifdef FAR
|
||||||
# undef FAR
|
# undef FAR
|
||||||
# endif
|
# endif
|
||||||
|
# ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
# define WIN32_LEAN_AND_MEAN
|
||||||
|
# endif
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
/* No need for _export, use ZLIB.DEF instead. */
|
/* No need for _export, use ZLIB.DEF instead. */
|
||||||
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
|
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
|
||||||
|
@ -469,11 +475,18 @@ typedef uLong FAR uLongf;
|
||||||
# undef _LARGEFILE64_SOURCE
|
# undef _LARGEFILE64_SOURCE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
|
#ifndef Z_HAVE_UNISTD_H
|
||||||
|
# ifdef __WATCOMC__
|
||||||
# define Z_HAVE_UNISTD_H
|
# define Z_HAVE_UNISTD_H
|
||||||
# endif
|
# endif
|
||||||
|
#endif
|
||||||
|
#ifndef Z_HAVE_UNISTD_H
|
||||||
|
# if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32)
|
||||||
|
# define Z_HAVE_UNISTD_H
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
#ifndef Z_SOLO
|
#ifndef Z_SOLO
|
||||||
# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
|
# if defined(Z_HAVE_UNISTD_H)
|
||||||
# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
|
# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
|
||||||
# ifdef VMS
|
# ifdef VMS
|
||||||
# include <unixio.h> /* for off_t */
|
# include <unixio.h> /* for off_t */
|
||||||
|
|
Loading…
Reference in New Issue