Merge branch 'master' into master

pull/3561/head
Kim Kulling 2021-01-06 18:54:57 +01:00 committed by GitHub
commit 2ad4218d25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 3154 additions and 2033 deletions

View File

@ -55,6 +55,8 @@ namespace XmlTag {
static const std::string resources = "resources"; static const std::string resources = "resources";
static const std::string object = "object"; static const std::string object = "object";
static const std::string mesh = "mesh"; static const std::string mesh = "mesh";
static const std::string components = "components";
static const std::string component = "component";
static const std::string vertices = "vertices"; static const std::string vertices = "vertices";
static const std::string vertex = "vertex"; static const std::string vertex = "vertex";
static const std::string triangles = "triangles"; static const std::string triangles = "triangles";
@ -67,6 +69,7 @@ namespace XmlTag {
static const std::string v3 = "v3"; static const std::string v3 = "v3";
static const std::string id = "id"; static const std::string id = "id";
static const std::string pid = "pid"; static const std::string pid = "pid";
static const std::string pindex = "pindex";
static const std::string p1 = "p1"; static const std::string p1 = "p1";
static const std::string name = "name"; static const std::string name = "name";
static const std::string type = "type"; static const std::string type = "type";

View File

@ -137,7 +137,7 @@ bool D3MFExporter::exportContentTypes() {
mContentOutput << std::endl; mContentOutput << std::endl;
mContentOutput << "</Types>"; mContentOutput << "</Types>";
mContentOutput << std::endl; mContentOutput << std::endl;
exportContentTyp(XmlTag::CONTENT_TYPES_ARCHIVE); zipContentType(XmlTag::CONTENT_TYPES_ARCHIVE);
return true; return true;
} }
@ -162,7 +162,7 @@ bool D3MFExporter::exportRelations() {
mRelOutput << "</Relationships>"; mRelOutput << "</Relationships>";
mRelOutput << std::endl; mRelOutput << std::endl;
writeRelInfoToFile("_rels", ".rels"); zipRelInfo("_rels", ".rels");
mRelOutput.flush(); mRelOutput.flush();
return true; return true;
@ -196,7 +196,7 @@ bool D3MFExporter::export3DModel() {
info->type = XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE; info->type = XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE;
mRelations.push_back(info); mRelations.push_back(info);
writeModelToArchive("3D", "3DModel.model"); zipModel("3D", "3DModel.model");
mModelOutput.flush(); mModelOutput.flush();
return true; return true;
@ -357,42 +357,27 @@ void D3MFExporter::writeBuild() {
mModelOutput << std::endl; mModelOutput << std::endl;
} }
void D3MFExporter::exportContentTyp(const std::string &filename) { void D3MFExporter::zipContentType(const std::string &filename) {
if (nullptr == m_zipArchive) { addFileInZip(filename, mContentOutput.str());
throw DeadlyExportError("3MF-Export: Zip archive not valid, nullptr.");
}
const std::string entry = filename;
zip_entry_open(m_zipArchive, entry.c_str());
const std::string &exportTxt(mContentOutput.str());
zip_entry_write(m_zipArchive, exportTxt.c_str(), exportTxt.size());
zip_entry_close(m_zipArchive);
} }
void D3MFExporter::writeModelToArchive(const std::string &folder, const std::string &modelName) { void D3MFExporter::zipModel(const std::string &folder, const std::string &modelName) {
if (nullptr == m_zipArchive) {
throw DeadlyExportError("3MF-Export: Zip archive not valid, nullptr.");
}
const std::string entry = folder + "/" + modelName; const std::string entry = folder + "/" + modelName;
zip_entry_open(m_zipArchive, entry.c_str()); addFileInZip(entry, mModelOutput.str());
const std::string &exportTxt(mModelOutput.str());
zip_entry_write(m_zipArchive, exportTxt.c_str(), exportTxt.size());
zip_entry_close(m_zipArchive);
} }
void D3MFExporter::writeRelInfoToFile(const std::string &folder, const std::string &relName) { void D3MFExporter::zipRelInfo(const std::string &folder, const std::string &relName) {
const std::string entry = folder + "/" + relName;
addFileInZip(entry, mRelOutput.str());
}
void D3MFExporter::addFileInZip(const std::string& entry, const std::string& content) {
if (nullptr == m_zipArchive) { if (nullptr == m_zipArchive) {
throw DeadlyExportError("3MF-Export: Zip archive not valid, nullptr."); throw DeadlyExportError("3MF-Export: Zip archive not valid, nullptr.");
} }
const std::string entry = folder + "/" + relName;
zip_entry_open(m_zipArchive, entry.c_str()); zip_entry_open(m_zipArchive, entry.c_str());
zip_entry_write(m_zipArchive, content.c_str(), content.size());
const std::string &exportTxt(mRelOutput.str());
zip_entry_write(m_zipArchive, exportTxt.c_str(), exportTxt.size());
zip_entry_close(m_zipArchive); zip_entry_close(m_zipArchive);
} }

View File

@ -82,9 +82,12 @@ protected:
void writeVertex( const aiVector3D &pos ); void writeVertex( const aiVector3D &pos );
void writeFaces( aiMesh *mesh, unsigned int matIdx ); void writeFaces( aiMesh *mesh, unsigned int matIdx );
void writeBuild(); void writeBuild();
void exportContentTyp( const std::string &filename );
void writeModelToArchive( const std::string &folder, const std::string &modelName ); // Zip the data
void writeRelInfoToFile( const std::string &folder, const std::string &relName ); void zipContentType( const std::string &filename );
void zipModel( const std::string &folder, const std::string &modelName );
void zipRelInfo( const std::string &folder, const std::string &relName );
void addFileInZip( const std::string &entry, const std::string &content );
private: private:
std::string mArchiveName; std::string mArchiveName;

View File

@ -66,22 +66,79 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp { namespace Assimp {
namespace D3MF { namespace D3MF {
enum class ResourceType {
RT_Object,
RT_BaseMaterials,
RT_Unknown
}; // To be extended with other resource types (eg. material extension resources like Texture2d, Texture2dGroup...)
class Resource
{
public:
Resource(int id) :
mId(id) {}
virtual ~Resource() {}
int mId;
virtual ResourceType getType() {
return ResourceType::RT_Unknown;
}
};
class BaseMaterials : public Resource {
public:
BaseMaterials(int id) :
Resource(id),
mMaterials(),
mMaterialIndex() {}
std::vector<aiMaterial *> mMaterials;
std::vector<unsigned int> mMaterialIndex;
virtual ResourceType getType() {
return ResourceType::RT_BaseMaterials;
}
};
struct Component {
int mObjectId;
aiMatrix4x4 mTransformation;
};
class Object : public Resource {
public:
std::vector<aiMesh*> mMeshes;
std::vector<unsigned int> mMeshIndex;
std::vector<Component> mComponents;
std::string mName;
Object(int id) :
Resource(id),
mName (std::string("Object_") + to_string(id)){}
virtual ResourceType getType() {
return ResourceType::RT_Object;
}
};
class XmlSerializer { class XmlSerializer {
public: public:
using MatArray = std::vector<aiMaterial *>;
using MatId2MatArray = std::map<unsigned int, std::vector<unsigned int>>;
XmlSerializer(XmlParser *xmlParser) : XmlSerializer(XmlParser *xmlParser) :
mMeshes(), mResourcesDictionnary(),
mMatArray(), mMaterialCount(0),
mActiveMatGroup(99999999), mMeshCount(0),
mMatId2MatArray(),
mXmlParser(xmlParser) { mXmlParser(xmlParser) {
// empty // empty
} }
~XmlSerializer() { ~XmlSerializer() {
// empty for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); it++) {
delete it->second;
}
} }
void ImportXml(aiScene *scene) { void ImportXml(aiScene *scene) {
@ -89,10 +146,8 @@ public:
return; return;
} }
scene->mRootNode = new aiNode(); scene->mRootNode = new aiNode("3MF");
std::vector<aiNode *> children;
std::string nodeName;
XmlNode node = mXmlParser->getRootNode().child("model"); XmlNode node = mXmlParser->getRootNode().child("model");
if (node.empty()) { if (node.empty()) {
return; return;
@ -101,9 +156,7 @@ public:
for (XmlNode currentNode = resNode.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode currentNode = resNode.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
const std::string &currentNodeName = currentNode.name(); const std::string &currentNodeName = currentNode.name();
if (currentNodeName == D3MF::XmlTag::object) { if (currentNodeName == D3MF::XmlTag::object) {
children.push_back(ReadObject(currentNode, scene)); ReadObject(currentNode);;
} else if (currentNodeName == D3MF::XmlTag::build) {
//
} else if (currentNodeName == D3MF::XmlTag::basematerials) { } else if (currentNodeName == D3MF::XmlTag::basematerials) {
ReadBaseMaterials(currentNode); ReadBaseMaterials(currentNode);
} else if (currentNodeName == D3MF::XmlTag::meta) { } else if (currentNodeName == D3MF::XmlTag::meta) {
@ -111,10 +164,29 @@ public:
} }
} }
if (scene->mRootNode->mName.length == 0) { XmlNode buildNode = node.child("build");
scene->mRootNode->mName.Set("3MF"); for (XmlNode currentNode = buildNode.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
const std::string &currentNodeName = currentNode.name();
if (currentNodeName == D3MF::XmlTag::item) {
int objectId = -1;
std::string transformationMatrixStr;
aiMatrix4x4 transformationMatrix;
getNodeAttribute(currentNode, D3MF::XmlTag::objectid, objectId);
bool hasTransform = getNodeAttribute(currentNode, D3MF::XmlTag::transform, transformationMatrixStr);
auto it = mResourcesDictionnary.find(objectId);
if (it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_Object) {
Object *obj = static_cast<Object *>(it->second);
if (hasTransform) {
transformationMatrix = parseTransformMatrix(transformationMatrixStr);
} }
addObjectToNode(scene->mRootNode, obj, transformationMatrix);
}
}
}
// import the metadata // import the metadata
if (!mMetaData.empty()) { if (!mMetaData.empty()) {
const size_t numMeta(mMetaData.size()); const size_t numMeta(mMetaData.size());
@ -126,66 +198,177 @@ public:
} }
// import the meshes // import the meshes
scene->mNumMeshes = static_cast<unsigned int>(mMeshes.size()); scene->mNumMeshes = static_cast<unsigned int>(mMeshCount);
if (scene->mNumMeshes != 0) {
scene->mMeshes = new aiMesh *[scene->mNumMeshes](); scene->mMeshes = new aiMesh *[scene->mNumMeshes]();
std::copy(mMeshes.begin(), mMeshes.end(), scene->mMeshes); for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); it++) {
if (it->second->getType() == ResourceType::RT_Object) {
// import the materials Object *obj = static_cast<Object*>(it->second);
scene->mNumMaterials = static_cast<unsigned int>(mMatArray.size()); for (unsigned int i = 0; i < obj->mMeshes.size(); ++i) {
if (0 != scene->mNumMaterials) { scene->mMeshes[obj->mMeshIndex[i]] = obj->mMeshes[i];
scene->mMaterials = new aiMaterial *[scene->mNumMaterials]; }
std::copy(mMatArray.begin(), mMatArray.end(), scene->mMaterials); }
}
} }
// create the scene-graph
scene->mRootNode->mNumChildren = static_cast<unsigned int>(children.size()); // import the materials
scene->mRootNode->mChildren = new aiNode *[scene->mRootNode->mNumChildren](); scene->mNumMaterials = static_cast<unsigned int>(mMaterialCount);
std::copy(children.begin(), children.end(), scene->mRootNode->mChildren); if (scene->mNumMaterials != 0) {
scene->mMaterials = new aiMaterial *[scene->mNumMaterials];
for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); it++) {
if (it->second->getType() == ResourceType::RT_BaseMaterials) {
BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
for (unsigned int i = 0; i < baseMaterials->mMaterials.size(); ++i) {
scene->mMaterials[baseMaterials->mMaterialIndex[i]] = baseMaterials->mMaterials[i];
}
}
}
}
} }
private: private:
aiNode *ReadObject(XmlNode &node, aiScene *scene) {
std::unique_ptr<aiNode> nodePtr(new aiNode());
std::vector<unsigned long> meshIds; void addObjectToNode(aiNode* parent, Object* obj, aiMatrix4x4 nodeTransform) {
aiNode *sceneNode = new aiNode(obj->mName);
sceneNode->mNumMeshes = static_cast<unsigned int>(obj->mMeshes.size());
sceneNode->mMeshes = new unsigned int[sceneNode->mNumMeshes];
std::copy(obj->mMeshIndex.begin(), obj->mMeshIndex.end(), sceneNode->mMeshes);
std::string name, type; sceneNode->mTransformation = nodeTransform;
pugi::xml_attribute attr = node.attribute(D3MF::XmlTag::id.c_str());
if (!attr.empty()) { parent->addChildren(1, &sceneNode);
name = attr.as_string();
} for (size_t i = 0; i < obj->mComponents.size(); ++i) {
attr = node.attribute(D3MF::XmlTag::type.c_str()); Component c = obj->mComponents[i];
if (!attr.empty()) { auto it = mResourcesDictionnary.find(c.mObjectId);
type = attr.as_string(); if (it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_Object) {
addObjectToNode(sceneNode, static_cast<Object*>(it->second), c.mTransformation);
} }
nodePtr->mParent = scene->mRootNode; }
nodePtr->mName.Set(name); }
size_t meshIdx = mMeshes.size(); bool getNodeAttribute(const XmlNode& node, const std::string& attribute, std::string& value) {
pugi::xml_attribute objectAttribute = node.attribute(attribute.c_str());
if (!objectAttribute.empty()) {
value = objectAttribute.as_string();
return true;
} else {
return false;
}
}
bool getNodeAttribute(const XmlNode &node, const std::string &attribute, int &value) {
std::string strValue;
bool ret = getNodeAttribute(node, attribute, strValue);
if (ret) {
value = std::atoi(strValue.c_str());
return true;
} else {
return false;
}
}
aiMatrix4x4 parseTransformMatrix(std::string matrixStr) {
// split the string
std::vector<float> numbers;
std::string currentNumber;
for (size_t i = 0; i < matrixStr.size(); ++i) {
const char c = matrixStr[i];
if (c == ' ') {
if (currentNumber.size() > 0) {
float f = std::stof(currentNumber);
numbers.push_back(f);
currentNumber.clear();
}
} else {
currentNumber.push_back(c);
}
}
if (currentNumber.size() > 0) {
float f = std::stof(currentNumber);
numbers.push_back(f);
}
aiMatrix4x4 transformMatrix;
transformMatrix.a1 = numbers[0];
transformMatrix.b1 = numbers[1];
transformMatrix.c1 = numbers[2];
transformMatrix.d1 = 0;
transformMatrix.a2 = numbers[3];
transformMatrix.b2 = numbers[4];
transformMatrix.c2 = numbers[5];
transformMatrix.d2 = 0;
transformMatrix.a3 = numbers[6];
transformMatrix.b3 = numbers[7];
transformMatrix.c3 = numbers[8];
transformMatrix.d3 = 0;
transformMatrix.a4 = numbers[9];
transformMatrix.b4 = numbers[10];
transformMatrix.c4 = numbers[11];
transformMatrix.d4 = 1;
return transformMatrix;
}
void ReadObject(XmlNode &node) {
int id = -1, pid = -1, pindex = -1;
bool hasId = getNodeAttribute(node, D3MF::XmlTag::id, id);
//bool hasType = getNodeAttribute(node, D3MF::XmlTag::type, type); not used currently
bool hasPid = getNodeAttribute(node, D3MF::XmlTag::pid, pid);
bool hasPindex = getNodeAttribute(node, D3MF::XmlTag::pindex, pindex);
std::string idStr = to_string(id);
if (!hasId) {
return;
}
Object *obj = new Object(id);
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == D3MF::XmlTag::mesh) { if (currentName == D3MF::XmlTag::mesh) {
auto mesh = ReadMesh(currentNode); auto mesh = ReadMesh(currentNode);
mesh->mName.Set(name); mesh->mName.Set(idStr);
mMeshes.push_back(mesh);
meshIds.push_back(static_cast<unsigned long>(meshIdx)); if (hasPid) {
++meshIdx; auto it = mResourcesDictionnary.find(pid);
if (hasPindex && it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_BaseMaterials) {
BaseMaterials *materials = static_cast<BaseMaterials *>(it->second);
mesh->mMaterialIndex = materials->mMaterialIndex[pindex];
} }
} }
nodePtr->mNumMeshes = static_cast<unsigned int>(meshIds.size()); obj->mMeshes.push_back(mesh);
obj->mMeshIndex.push_back(mMeshCount);
mMeshCount++;
} else if (currentName == D3MF::XmlTag::components) {
for (XmlNode currentSubNode = currentNode.first_child(); currentSubNode; currentSubNode = currentSubNode.next_sibling()) {
if (currentSubNode.name() == D3MF::XmlTag::component) {
int objectId = -1;
std::string componentTransformStr;
aiMatrix4x4 componentTransform;
if (getNodeAttribute(currentSubNode, D3MF::XmlTag::transform, componentTransformStr)) {
componentTransform = parseTransformMatrix(componentTransformStr);
}
nodePtr->mMeshes = new unsigned int[nodePtr->mNumMeshes]; if (getNodeAttribute(currentSubNode, D3MF::XmlTag::objectid, objectId))
obj->mComponents.push_back({ objectId, componentTransform });
}
}
}
}
std::copy(meshIds.begin(), meshIds.end(), nodePtr->mMeshes); mResourcesDictionnary.insert(std::make_pair(id, obj));
return nodePtr.release();
} }
aiMesh *ReadMesh(XmlNode &node) { aiMesh *ReadMesh(XmlNode &node) {
aiMesh *mesh = new aiMesh(); aiMesh *mesh = new aiMesh();
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == D3MF::XmlTag::vertices) { if (currentName == D3MF::XmlTag::vertices) {
@ -241,11 +424,23 @@ private:
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == D3MF::XmlTag::triangle) { if (currentName == D3MF::XmlTag::triangle) {
faces.push_back(ReadTriangle(currentNode)); aiFace face = ReadTriangle(currentNode);
const char *pidToken = currentNode.attribute(D3MF::XmlTag::p1.c_str()).as_string(); faces.push_back(face);
if (nullptr != pidToken) {
int matIdx(std::atoi(pidToken)); int pid, p1;
mesh->mMaterialIndex = matIdx; bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid);
bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1);
if (hasPid && hasP1) {
auto it = mResourcesDictionnary.find(pid);
if (it != mResourcesDictionnary.end())
{
if (it->second->getType() == ResourceType::RT_BaseMaterials) {
BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1];
}
// TODO: manage the separation into several meshes if the triangles of the mesh do not all refer to the same material
}
} }
} }
} }
@ -270,26 +465,21 @@ private:
} }
void ReadBaseMaterials(XmlNode &node) { void ReadBaseMaterials(XmlNode &node) {
std::vector<unsigned int> MatIdArray; int id = -1;
const char *baseMaterialId = node.attribute(D3MF::XmlTag::basematerials_id.c_str()).as_string(); if (getNodeAttribute(node, D3MF::XmlTag::basematerials_id, id)) {
if (nullptr != baseMaterialId) { BaseMaterials* baseMaterials = new BaseMaterials(id);
unsigned int id = std::atoi(baseMaterialId);
const size_t newMatIdx(mMatArray.size()); for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling())
if (id != mActiveMatGroup) { {
mActiveMatGroup = id; if (currentNode.name() == D3MF::XmlTag::basematerials_base) {
MatId2MatArray::const_iterator it(mMatId2MatArray.find(id)); baseMaterials->mMaterialIndex.push_back(mMaterialCount);
if (mMatId2MatArray.end() == it) { baseMaterials->mMaterials.push_back(readMaterialDef(currentNode, id));
MatIdArray.clear(); mMaterialCount++;
mMatId2MatArray[id] = MatIdArray;
} else {
MatIdArray = it->second;
} }
} }
MatIdArray.push_back(static_cast<unsigned int>(newMatIdx));
mMatId2MatArray[mActiveMatGroup] = MatIdArray;
}
mMatArray.push_back(readMaterialDef(node)); mResourcesDictionnary.insert(std::make_pair(id, baseMaterials));
}
} }
bool parseColor(const char *color, aiColor4D &diffuse) { bool parseColor(const char *color, aiColor4D &diffuse) {
@ -304,37 +494,24 @@ private:
} }
const char *buf(color); const char *buf(color);
if ('#' != *buf) { if ('#' != buf[0]) {
return false; return false;
} }
++buf;
char comp[3] = { 0, 0, '\0' };
comp[0] = *buf; char r[3] = { buf[1], buf[2], '\0' };
++buf; diffuse.r = static_cast<ai_real>(strtol(r, nullptr, 16)) / ai_real(255.0);
comp[1] = *buf;
++buf;
diffuse.r = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
comp[0] = *buf; char g[3] = { buf[3], buf[4], '\0' };
++buf; diffuse.g = static_cast<ai_real>(strtol(g, nullptr, 16)) / ai_real(255.0);
comp[1] = *buf;
++buf;
diffuse.g = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
comp[0] = *buf; char b[3] = { buf[5], buf[6], '\0' };
++buf; diffuse.b = static_cast<ai_real>(strtol(b, nullptr, 16)) / ai_real(255.0);
comp[1] = *buf;
++buf;
diffuse.b = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
if (7 == len) if (7 == len)
return true; return true;
comp[0] = *buf;
++buf; char a[3] = { buf[7], buf[8], '\0' };
comp[1] = *buf; diffuse.a = static_cast<ai_real>(strtol(a, nullptr, 16)) / ai_real(255.0);
++buf;
diffuse.a = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
return true; return true;
} }
@ -347,32 +524,30 @@ private:
} }
} }
aiMaterial *readMaterialDef(XmlNode &node) { aiMaterial *readMaterialDef(XmlNode &node, unsigned int basematerialsId) {
aiMaterial *mat(nullptr); aiMaterial *material = new aiMaterial();
const char *name(nullptr); material->mNumProperties = 0;
const std::string nodeName = node.name(); std::string name;
if (nodeName == D3MF::XmlTag::basematerials_base) { bool hasName = getNodeAttribute(node, D3MF::XmlTag::basematerials_name, name);
name = node.attribute(D3MF::XmlTag::basematerials_name.c_str()).as_string();
std::string stdMatName; std::string stdMaterialName;
aiString matName; std::string strId(to_string(basematerialsId));
std::string strId(to_string(mActiveMatGroup)); stdMaterialName += "id";
stdMatName += "id"; stdMaterialName += strId;
stdMatName += strId; stdMaterialName += "_";
stdMatName += "_"; if (hasName) {
if (nullptr != name) { stdMaterialName += std::string(name);
stdMatName += std::string(name);
} else { } else {
stdMatName += "basemat"; stdMaterialName += "basemat_";
} stdMaterialName += to_string(mMaterialCount - basematerialsId);
matName.Set(stdMatName);
mat = new aiMaterial;
mat->AddProperty(&matName, AI_MATKEY_NAME);
assignDiffuseColor(node, mat);
} }
return mat; aiString assimpMaterialName(stdMaterialName);
material->AddProperty(&assimpMaterialName, AI_MATKEY_NAME);
assignDiffuseColor(node, material);
return material;
} }
private: private:
@ -381,10 +556,8 @@ private:
std::string value; std::string value;
}; };
std::vector<MetaEntry> mMetaData; std::vector<MetaEntry> mMetaData;
std::vector<aiMesh *> mMeshes; std::map<unsigned int, Resource*> mResourcesDictionnary;
MatArray mMatArray; unsigned int mMaterialCount, mMeshCount;
unsigned int mActiveMatGroup;
MatId2MatArray mMatId2MatArray;
XmlParser *mXmlParser; XmlParser *mXmlParser;
}; };

View File

@ -375,6 +375,11 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
// now come the individual properties // now come the individual properties
const char* begin_cursor = cursor; const char* begin_cursor = cursor;
if ((begin_cursor + prop_length) > end) {
TokenizeError("property length out of bounds reading length ", input, cursor);
}
for (unsigned int i = 0; i < prop_count; ++i) { for (unsigned int i = 0; i < prop_count; ++i) {
ReadData(sbeg, send, input, cursor, begin_cursor + prop_length); ReadData(sbeg, send, input, cursor, begin_cursor + prop_length);

View File

@ -40,6 +40,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <assimp/StringUtils.h> #include <assimp/StringUtils.h>
#include <assimp/MemoryIOWrapper.h>
#include <iomanip> #include <iomanip>
// Header files, Assimp // Header files, Assimp
@ -331,7 +332,10 @@ inline void Buffer::Read(Value &obj, Asset &r) {
} }
} else { // Local file } else { // Local file
if (byteLength > 0) { if (byteLength > 0) {
std::string dir = !r.mCurrentAssetDir.empty() ? (r.mCurrentAssetDir) : ""; std::string dir = !r.mCurrentAssetDir.empty() ? (
r.mCurrentAssetDir.back() == '/' ?
r.mCurrentAssetDir : r.mCurrentAssetDir + '/'
) : "";
IOStream *file = r.OpenFile(dir + uri, "rb"); IOStream *file = r.OpenFile(dir + uri, "rb");
if (file) { if (file) {
@ -1276,7 +1280,9 @@ inline void Asset::Load(const std::string &pFile, bool isBinary) {
/*int pos = std::max(int(pFile.rfind('/')), int(pFile.rfind('\\'))); /*int pos = std::max(int(pFile.rfind('/')), int(pFile.rfind('\\')));
if (pos != int(std::string::npos)) mCurrentAssetDir = pFile.substr(0, pos + 1);*/ if (pos != int(std::string::npos)) mCurrentAssetDir = pFile.substr(0, pos + 1);*/
if (0 != strncmp(pFile.c_str(), AI_MEMORYIO_MAGIC_FILENAME, AI_MEMORYIO_MAGIC_FILENAME_LENGTH)) {
mCurrentAssetDir = getCurrentAssetDir(pFile); mCurrentAssetDir = getCurrentAssetDir(pFile);
}
shared_ptr<IOStream> stream(OpenFile(pFile.c_str(), "rb", true)); shared_ptr<IOStream> stream(OpenFile(pFile.c_str(), "rb", true));
if (!stream) { if (!stream) {

View File

@ -46,6 +46,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* KHR_materials_pbrSpecularGlossiness full * KHR_materials_pbrSpecularGlossiness full
* KHR_materials_unlit full * KHR_materials_unlit full
* KHR_lights_punctual full * KHR_lights_punctual full
* KHR_materials_sheen full
* KHR_materials_clearcoat full
* KHR_materials_transmission full
*/ */
#ifndef GLTF2ASSET_H_INC #ifndef GLTF2ASSET_H_INC
#define GLTF2ASSET_H_INC #define GLTF2ASSET_H_INC
@ -677,6 +680,7 @@ const vec4 defaultBaseColor = { 1, 1, 1, 1 };
const vec3 defaultEmissiveFactor = { 0, 0, 0 }; const vec3 defaultEmissiveFactor = { 0, 0, 0 };
const vec4 defaultDiffuseFactor = { 1, 1, 1, 1 }; const vec4 defaultDiffuseFactor = { 1, 1, 1, 1 };
const vec3 defaultSpecularFactor = { 1, 1, 1 }; const vec3 defaultSpecularFactor = { 1, 1, 1 };
const vec3 defaultSheenFactor = { 0, 0, 0 };
struct TextureInfo { struct TextureInfo {
Ref<Texture> texture; Ref<Texture> texture;
@ -718,6 +722,29 @@ struct PbrSpecularGlossiness {
void SetDefaults(); void SetDefaults();
}; };
struct MaterialSheen {
vec3 sheenColorFactor;
float sheenRoughnessFactor;
TextureInfo sheenColorTexture;
TextureInfo sheenRoughnessTexture;
MaterialSheen() { SetDefaults(); }
void SetDefaults();
};
struct MaterialClearcoat {
float clearcoatFactor = 0.f;
float clearcoatRoughnessFactor = 0.f;
TextureInfo clearcoatTexture;
TextureInfo clearcoatRoughnessTexture;
NormalTextureInfo clearcoatNormalTexture;
};
struct MaterialTransmission {
TextureInfo transmissionTexture;
float transmissionFactor = 0.f;
};
//! The material appearance of a primitive. //! The material appearance of a primitive.
struct Material : public Object { struct Material : public Object {
//PBR metallic roughness properties //PBR metallic roughness properties
@ -735,6 +762,15 @@ struct Material : public Object {
//extension: KHR_materials_pbrSpecularGlossiness //extension: KHR_materials_pbrSpecularGlossiness
Nullable<PbrSpecularGlossiness> pbrSpecularGlossiness; Nullable<PbrSpecularGlossiness> pbrSpecularGlossiness;
//extension: KHR_materials_sheen
Nullable<MaterialSheen> materialSheen;
//extension: KHR_materials_clearcoat
Nullable<MaterialClearcoat> materialClearcoat;
//extension: KHR_materials_transmission
Nullable<MaterialTransmission> materialTransmission;
//extension: KHR_materials_unlit //extension: KHR_materials_unlit
bool unlit; bool unlit;
@ -1053,6 +1089,9 @@ public:
bool KHR_materials_unlit; bool KHR_materials_unlit;
bool KHR_lights_punctual; bool KHR_lights_punctual;
bool KHR_texture_transform; bool KHR_texture_transform;
bool KHR_materials_sheen;
bool KHR_materials_clearcoat;
bool KHR_materials_transmission;
} extensionsUsed; } extensionsUsed;
//! Keeps info about the required extensions //! Keeps info about the required extensions

View File

@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/StringUtils.h> #include <assimp/StringUtils.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/MemoryIOWrapper.h>
using namespace Assimp; using namespace Assimp;
@ -400,7 +401,10 @@ inline void Buffer::Read(Value &obj, Asset &r) {
} }
} else { // Local file } else { // Local file
if (byteLength > 0) { if (byteLength > 0) {
std::string dir = !r.mCurrentAssetDir.empty() ? (r.mCurrentAssetDir) : ""; std::string dir = !r.mCurrentAssetDir.empty() ? (
r.mCurrentAssetDir.back() == '/' ?
r.mCurrentAssetDir : r.mCurrentAssetDir + '/'
) : "";
IOStream *file = r.OpenFile(dir + uri, "rb"); IOStream *file = r.OpenFile(dir + uri, "rb");
if (file) { if (file) {
@ -1042,6 +1046,44 @@ inline void Material::Read(Value &material, Asset &r) {
if (r.extensionsUsed.KHR_texture_transform) { if (r.extensionsUsed.KHR_texture_transform) {
} }
if (r.extensionsUsed.KHR_materials_sheen) {
if (Value *curMaterialSheen = FindObject(*extensions, "KHR_materials_sheen")) {
MaterialSheen sheen;
ReadMember(*curMaterialSheen, "sheenColorFactor", sheen.sheenColorFactor);
ReadTextureProperty(r, *curMaterialSheen, "sheenColorTexture", sheen.sheenColorTexture);
ReadMember(*curMaterialSheen, "sheenRoughnessFactor", sheen.sheenRoughnessFactor);
ReadTextureProperty(r, *curMaterialSheen, "sheenRoughnessTexture", sheen.sheenRoughnessTexture);
this->materialSheen = Nullable<MaterialSheen>(sheen);
}
}
if (r.extensionsUsed.KHR_materials_clearcoat) {
if (Value *curMaterialClearcoat = FindObject(*extensions, "KHR_materials_clearcoat")) {
MaterialClearcoat clearcoat;
ReadMember(*curMaterialClearcoat, "clearcoatFactor", clearcoat.clearcoatFactor);
ReadTextureProperty(r, *curMaterialClearcoat, "clearcoatTexture", clearcoat.clearcoatTexture);
ReadMember(*curMaterialClearcoat, "clearcoatRoughnessFactor", clearcoat.clearcoatRoughnessFactor);
ReadTextureProperty(r, *curMaterialClearcoat, "clearcoatRoughnessTexture", clearcoat.clearcoatRoughnessTexture);
ReadTextureProperty(r, *curMaterialClearcoat, "clearcoatNormalTexture", clearcoat.clearcoatNormalTexture);
this->materialClearcoat = Nullable<MaterialClearcoat>(clearcoat);
}
}
if (r.extensionsUsed.KHR_materials_transmission) {
if (Value *curMaterialTransmission = FindObject(*extensions, "KHR_materials_transmission")) {
MaterialTransmission transmission;
ReadMember(*curMaterialTransmission, "transmissionFactor", transmission.transmissionFactor);
ReadTextureProperty(r, *curMaterialTransmission, "transmissionTexture", transmission.transmissionTexture);
this->materialTransmission = Nullable<MaterialTransmission>(transmission);
}
}
unlit = nullptr != FindObject(*extensions, "KHR_materials_unlit"); unlit = nullptr != FindObject(*extensions, "KHR_materials_unlit");
} }
} }
@ -1081,6 +1123,12 @@ inline void PbrSpecularGlossiness::SetDefaults() {
glossinessFactor = 1.0; glossinessFactor = 1.0;
} }
inline void MaterialSheen::SetDefaults() {
//KHR_materials_sheen properties
SetVector(sheenColorFactor, defaultSheenFactor);
sheenRoughnessFactor = 0.f;
}
namespace { namespace {
template <int N> template <int N>
@ -1590,7 +1638,9 @@ inline void Asset::Load(const std::string &pFile, bool isBinary) {
/*int pos = std::max(int(pFile.rfind('/')), int(pFile.rfind('\\'))); /*int pos = std::max(int(pFile.rfind('/')), int(pFile.rfind('\\')));
if (pos != int(std::string::npos)) */ if (pos != int(std::string::npos)) */
if (0 != strncmp(pFile.c_str(), AI_MEMORYIO_MAGIC_FILENAME, AI_MEMORYIO_MAGIC_FILENAME_LENGTH)) {
mCurrentAssetDir = glTFCommon::getCurrentAssetDir(pFile); mCurrentAssetDir = glTFCommon::getCurrentAssetDir(pFile);
}
shared_ptr<IOStream> stream(OpenFile(pFile.c_str(), "rb", true)); shared_ptr<IOStream> stream(OpenFile(pFile.c_str(), "rb", true));
if (!stream) { if (!stream) {
@ -1731,6 +1781,9 @@ inline void Asset::ReadExtensionsUsed(Document &doc) {
CHECK_EXT(KHR_materials_unlit); CHECK_EXT(KHR_materials_unlit);
CHECK_EXT(KHR_lights_punctual); CHECK_EXT(KHR_lights_punctual);
CHECK_EXT(KHR_texture_transform); CHECK_EXT(KHR_texture_transform);
CHECK_EXT(KHR_materials_sheen);
CHECK_EXT(KHR_materials_clearcoat);
CHECK_EXT(KHR_materials_transmission);
#undef CHECK_EXT #undef CHECK_EXT
} }

View File

@ -46,6 +46,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* glTF Extensions Support: * glTF Extensions Support:
* KHR_materials_pbrSpecularGlossiness: full * KHR_materials_pbrSpecularGlossiness: full
* KHR_materials_unlit: full * KHR_materials_unlit: full
* KHR_materials_sheen: full
* KHR_materials_clearcoat: full
* KHR_materials_transmission: full
*/ */
#ifndef GLTF2ASSETWRITER_H_INC #ifndef GLTF2ASSETWRITER_H_INC
#define GLTF2ASSETWRITER_H_INC #define GLTF2ASSETWRITER_H_INC

View File

@ -417,6 +417,63 @@ namespace glTF2 {
exts.AddMember("KHR_materials_unlit", unlit, w.mAl); exts.AddMember("KHR_materials_unlit", unlit, w.mAl);
} }
if (m.materialSheen.isPresent) {
Value materialSheen(rapidjson::Type::kObjectType);
MaterialSheen &sheen = m.materialSheen.value;
WriteVec(materialSheen, sheen.sheenColorFactor, "sheenColorFactor", defaultSheenFactor, w.mAl);
if (sheen.sheenRoughnessFactor != 0.f) {
WriteFloat(materialSheen, sheen.sheenRoughnessFactor, "sheenRoughnessFactor", w.mAl);
}
WriteTex(materialSheen, sheen.sheenColorTexture, "sheenColorTexture", w.mAl);
WriteTex(materialSheen, sheen.sheenRoughnessTexture, "sheenRoughnessTexture", w.mAl);
if (!materialSheen.ObjectEmpty()) {
exts.AddMember("KHR_materials_sheen", materialSheen, w.mAl);
}
}
if (m.materialClearcoat.isPresent) {
Value materialClearcoat(rapidjson::Type::kObjectType);
MaterialClearcoat &clearcoat = m.materialClearcoat.value;
if (clearcoat.clearcoatFactor != 0.f) {
WriteFloat(materialClearcoat, clearcoat.clearcoatFactor, "clearcoatFactor", w.mAl);
}
if (clearcoat.clearcoatRoughnessFactor != 0.f) {
WriteFloat(materialClearcoat, clearcoat.clearcoatRoughnessFactor, "clearcoatRoughnessFactor", w.mAl);
}
WriteTex(materialClearcoat, clearcoat.clearcoatTexture, "clearcoatTexture", w.mAl);
WriteTex(materialClearcoat, clearcoat.clearcoatRoughnessTexture, "clearcoatRoughnessTexture", w.mAl);
WriteTex(materialClearcoat, clearcoat.clearcoatNormalTexture, "clearcoatNormalTexture", w.mAl);
if (!materialClearcoat.ObjectEmpty()) {
exts.AddMember("KHR_materials_clearcoat", materialClearcoat, w.mAl);
}
}
if (m.materialTransmission.isPresent) {
Value materialTransmission(rapidjson::Type::kObjectType);
MaterialTransmission &transmission = m.materialTransmission.value;
if (transmission.transmissionFactor != 0.f) {
WriteFloat(materialTransmission, transmission.transmissionFactor, "transmissionFactor", w.mAl);
}
WriteTex(materialTransmission, transmission.transmissionTexture, "transmissionTexture", w.mAl);
if (!materialTransmission.ObjectEmpty()) {
exts.AddMember("KHR_materials_transmission", materialTransmission, w.mAl);
}
}
if (!exts.ObjectEmpty()) { if (!exts.ObjectEmpty()) {
obj.AddMember("extensions", exts, w.mAl); obj.AddMember("extensions", exts, w.mAl);
} }
@ -808,6 +865,18 @@ namespace glTF2 {
if (this->mAsset.extensionsUsed.KHR_materials_unlit) { if (this->mAsset.extensionsUsed.KHR_materials_unlit) {
exts.PushBack(StringRef("KHR_materials_unlit"), mAl); exts.PushBack(StringRef("KHR_materials_unlit"), mAl);
} }
if (this->mAsset.extensionsUsed.KHR_materials_sheen) {
exts.PushBack(StringRef("KHR_materials_sheen"), mAl);
}
if (this->mAsset.extensionsUsed.KHR_materials_clearcoat) {
exts.PushBack(StringRef("KHR_materials_clearcoat"), mAl);
}
if (this->mAsset.extensionsUsed.KHR_materials_transmission) {
exts.PushBack(StringRef("KHR_materials_transmission"), mAl);
}
} }
if (!exts.Empty()) if (!exts.Empty())

View File

@ -714,6 +714,53 @@ void glTF2Exporter::ExportMaterials()
mAsset->extensionsUsed.KHR_materials_unlit = true; mAsset->extensionsUsed.KHR_materials_unlit = true;
m->unlit = true; m->unlit = true;
} }
bool hasMaterialSheen = false;
mat->Get(AI_MATKEY_GLTF_MATERIAL_SHEEN, hasMaterialSheen);
if (hasMaterialSheen) {
mAsset->extensionsUsed.KHR_materials_sheen = true;
MaterialSheen sheen;
GetMatColor(mat, sheen.sheenColorFactor, AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_FACTOR);
mat->Get(AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_FACTOR, sheen.sheenRoughnessFactor);
GetMatTex(mat, sheen.sheenColorTexture, AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_TEXTURE);
GetMatTex(mat, sheen.sheenRoughnessTexture, AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_TEXTURE);
m->materialSheen = Nullable<MaterialSheen>(sheen);
}
bool hasMaterialClearcoat = false;
mat->Get(AI_MATKEY_GLTF_MATERIAL_CLEARCOAT, hasMaterialClearcoat);
if (hasMaterialClearcoat) {
mAsset->extensionsUsed.KHR_materials_clearcoat= true;
MaterialClearcoat clearcoat;
mat->Get(AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_FACTOR, clearcoat.clearcoatFactor);
mat->Get(AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_FACTOR, clearcoat.clearcoatRoughnessFactor);
GetMatTex(mat, clearcoat.clearcoatTexture, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_TEXTURE);
GetMatTex(mat, clearcoat.clearcoatRoughnessTexture, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_TEXTURE);
GetMatTex(mat, clearcoat.clearcoatNormalTexture, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_NORMAL_TEXTURE);
m->materialClearcoat = Nullable<MaterialClearcoat>(clearcoat);
}
bool hasMaterialTransmission = false;
mat->Get(AI_MATKEY_GLTF_MATERIAL_TRANSMISSION, hasMaterialTransmission);
if (hasMaterialTransmission) {
mAsset->extensionsUsed.KHR_materials_transmission = true;
MaterialTransmission transmission;
mat->Get(AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_FACTOR, transmission.transmissionFactor);
GetMatTex(mat, transmission.transmissionTexture, AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_TEXTURE);
m->materialTransmission = Nullable<MaterialTransmission>(transmission);
}
} }
} }

View File

@ -282,6 +282,38 @@ static aiMaterial *ImportMaterial(std::vector<int> &embeddedTexIdxs, Asset &r, M
aimat->AddProperty(&mat.unlit, 1, AI_MATKEY_GLTF_UNLIT); aimat->AddProperty(&mat.unlit, 1, AI_MATKEY_GLTF_UNLIT);
} }
//KHR_materials_sheen
if (mat.materialSheen.isPresent) {
MaterialSheen &sheen = mat.materialSheen.value;
aimat->AddProperty(&mat.materialSheen.isPresent, 1, AI_MATKEY_GLTF_MATERIAL_SHEEN);
SetMaterialColorProperty(r, sheen.sheenColorFactor, aimat, AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_FACTOR);
aimat->AddProperty(&sheen.sheenRoughnessFactor, 1, AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_FACTOR);
SetMaterialTextureProperty(embeddedTexIdxs, r, sheen.sheenColorTexture, aimat, AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_TEXTURE);
SetMaterialTextureProperty(embeddedTexIdxs, r, sheen.sheenRoughnessTexture, aimat, AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_TEXTURE);
}
//KHR_materials_clearcoat
if (mat.materialClearcoat.isPresent) {
MaterialClearcoat &clearcoat = mat.materialClearcoat.value;
aimat->AddProperty(&mat.materialClearcoat.isPresent, 1, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT);
aimat->AddProperty(&clearcoat.clearcoatFactor, 1, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_FACTOR);
aimat->AddProperty(&clearcoat.clearcoatRoughnessFactor, 1, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_FACTOR);
SetMaterialTextureProperty(embeddedTexIdxs, r, clearcoat.clearcoatTexture, aimat, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_TEXTURE);
SetMaterialTextureProperty(embeddedTexIdxs, r, clearcoat.clearcoatRoughnessTexture, aimat, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_TEXTURE);
SetMaterialTextureProperty(embeddedTexIdxs, r, clearcoat.clearcoatNormalTexture, aimat, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_NORMAL_TEXTURE);
}
//KHR_materials_transmission
if (mat.materialTransmission.isPresent) {
MaterialTransmission &transmission = mat.materialTransmission.value;
aimat->AddProperty(&mat.materialTransmission.isPresent, 1, AI_MATKEY_GLTF_MATERIAL_TRANSMISSION);
aimat->AddProperty(&transmission.transmissionFactor, 1, AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_FACTOR);
SetMaterialTextureProperty(embeddedTexIdxs, r, transmission.transmissionTexture, aimat, AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_TEXTURE);
}
return aimat; return aimat;
} catch (...) { } catch (...) {
delete aimat; delete aimat;

View File

@ -920,6 +920,7 @@ IF(ASSIMP_HUNTER_ENABLED)
find_package(minizip CONFIG REQUIRED) find_package(minizip CONFIG REQUIRED)
ELSE() ELSE()
SET( unzip_SRCS SET( unzip_SRCS
../contrib/unzip/crypt.c
../contrib/unzip/crypt.h ../contrib/unzip/crypt.h
../contrib/unzip/ioapi.c ../contrib/unzip/ioapi.c
../contrib/unzip/ioapi.h ../contrib/unzip/ioapi.h

View File

@ -146,7 +146,6 @@ int IOSystem2Unzip::testerror(voidpf /*opaque*/, voidpf /*stream*/) {
zlib_filefunc_def IOSystem2Unzip::get(IOSystem *pIOHandler) { zlib_filefunc_def IOSystem2Unzip::get(IOSystem *pIOHandler) {
zlib_filefunc_def mapping; zlib_filefunc_def mapping;
#if defined (ASSIMP_USE_HUNTER) || defined (__MINGW32__) // GH#3144
mapping.zopen_file = (open_file_func)open; mapping.zopen_file = (open_file_func)open;
mapping.zread_file = (read_file_func)read; mapping.zread_file = (read_file_func)read;
mapping.zwrite_file = (write_file_func)write; mapping.zwrite_file = (write_file_func)write;
@ -154,15 +153,7 @@ zlib_filefunc_def IOSystem2Unzip::get(IOSystem *pIOHandler) {
mapping.zseek_file = (seek_file_func)seek; mapping.zseek_file = (seek_file_func)seek;
mapping.zclose_file = (close_file_func)close; mapping.zclose_file = (close_file_func)close;
mapping.zerror_file = (error_file_func)testerror; mapping.zerror_file = (error_file_func)testerror;
#else
mapping.zopen_file = open;
mapping.zread_file = read;
mapping.zwrite_file = write;
mapping.ztell_file = tell;
mapping.zseek_file = seek;
mapping.zclose_file = close;
mapping.zerror_file = testerror;
#endif
mapping.opaque = reinterpret_cast<voidpf>(pIOHandler); mapping.opaque = reinterpret_cast<voidpf>(pIOHandler);
return mapping; return mapping;
@ -226,10 +217,28 @@ ZipFile *ZipFileInfo::Extract(unzFile zip_handle) const {
ZipFile *zip_file = new ZipFile(m_Size); ZipFile *zip_file = new ZipFile(m_Size);
if (unzReadCurrentFile(zip_handle, zip_file->m_Buffer.get(), static_cast<unsigned int>(m_Size)) != static_cast<int>(m_Size)) { // Unzip has a limit of UINT16_MAX bytes buffer
uint16_t unzipBufferSize = zip_file->m_Size <= UINT16_MAX ? static_cast<uint16_t>(zip_file->m_Size) : UINT16_MAX;
std::unique_ptr<uint8_t[]> unzipBuffer = std::unique_ptr<uint8_t[]>(new uint8_t[unzipBufferSize]);
size_t readCount = 0;
while (readCount < zip_file->m_Size)
{
size_t bufferSize = zip_file->m_Size - readCount;
if (bufferSize > UINT16_MAX) {
bufferSize = UINT16_MAX;
}
int ret = unzReadCurrentFile(zip_handle, unzipBuffer.get(), static_cast<unsigned int>(bufferSize));
if (ret != static_cast<int>(bufferSize))
{
// Failed, release the memory // Failed, release the memory
delete zip_file; delete zip_file;
zip_file = nullptr; zip_file = nullptr;
break;
}
std::memcpy(zip_file->m_Buffer.get() + readCount, unzipBuffer.get(), ret);
readCount += ret;
} }
ai_assert(unzCloseCurrentFile(zip_handle) == UNZ_OK); ai_assert(unzCloseCurrentFile(zip_handle) == UNZ_OK);

View File

@ -522,8 +522,7 @@ namespace o3dgc
buffer_size = max_code_bytes; // assign new memory buffer_size = max_code_bytes; // assign new memory
delete [] new_buffer; // free anything previously assigned delete [] new_buffer; // free anything previously assigned
if ((new_buffer = new unsigned char[buffer_size+16]) == 0) // 16 extra bytes new_buffer = new unsigned char[buffer_size+16]; // 16 extra bytes
AC_Error("cannot assign memory for compressed data buffer");
code_buffer = new_buffer; // set buffer for compressed data code_buffer = new_buffer; // set buffer for compressed data
} }
@ -732,7 +731,6 @@ namespace o3dgc
table_size = table_shift = 0; table_size = table_shift = 0;
distribution = new unsigned[data_symbols]; distribution = new unsigned[data_symbols];
} }
if (distribution == 0) AC_Error("cannot assign model memory");
} }
// compute cumulative distribution, decoder table // compute cumulative distribution, decoder table
unsigned s = 0; unsigned s = 0;
@ -803,7 +801,6 @@ namespace o3dgc
distribution = new unsigned[2*data_symbols]; distribution = new unsigned[2*data_symbols];
} }
symbol_count = distribution + data_symbols; symbol_count = distribution + data_symbols;
if (distribution == 0) AC_Error("cannot assign model memory");
} }
reset(); // initialize model reset(); // initialize model

View File

@ -527,10 +527,8 @@ char *OpenDDLParser::parseName(char *in, char *end, Name **name) {
in = parseIdentifier(in, end, &id); in = parseIdentifier(in, end, &id);
if (id) { if (id) {
currentName = new Name(ntype, id); currentName = new Name(ntype, id);
if (currentName) {
*name = currentName; *name = currentName;
} }
}
return in; return in;
} }

View File

@ -0,0 +1,167 @@
/* crypt.c -- base code for traditional PKWARE encryption
Version 1.01e, February 12th, 2005
Copyright (C) 1998-2005 Gilles Vollant
Modifications for Info-ZIP crypting
Copyright (C) 2003 Terry Thorsen
This code is a modified version of crypting code in Info-ZIP distribution
Copyright (C) 1990-2000 Info-ZIP. All rights reserved.
This program is distributed under the terms of the same license as zlib.
See the accompanying LICENSE file for the full text of the license.
This encryption code is a direct transcription of the algorithm from
Roger Schlafly, described by Phil Katz in the file appnote.txt. This
file (appnote.txt) is distributed with the PKZIP program (even in the
version without encryption capabilities).
If you don't need crypting in your application, just define symbols
NOCRYPT and NOUNCRYPT.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#ifdef _WIN32
# include <windows.h>
# include <wincrypt.h>
#else
# include <sys/stat.h>
# include <fcntl.h>
# include <unistd.h>
#endif
#include "zlib.h"
#include "crypt.h"
#ifdef _WIN32
# pragma warning(push)
# pragma warning(disable : 4244)
#endif // _WIN32
/***************************************************************************/
#define CRC32(c, b) ((*(pcrc_32_tab+(((uint32_t)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
#ifndef ZCR_SEED2
# define ZCR_SEED2 3141592654UL /* use PI as default pattern */
#endif
/***************************************************************************/
uint8_t decrypt_byte(uint32_t *pkeys)
{
unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
* unpredictable manner on 16-bit systems; not a problem
* with any known compiler so far, though */
temp = ((uint32_t)(*(pkeys+2)) & 0xffff) | 2;
return (uint8_t)(((temp * (temp ^ 1)) >> 8) & 0xff);
}
uint8_t update_keys(uint32_t *pkeys, const z_crc_t *pcrc_32_tab, int32_t c)
{
(*(pkeys+0)) = (uint32_t)CRC32((*(pkeys+0)), c);
(*(pkeys+1)) += (*(pkeys+0)) & 0xff;
(*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
{
register int32_t keyshift = (int32_t)((*(pkeys + 1)) >> 24);
(*(pkeys+2)) = (uint32_t)CRC32((*(pkeys+2)), keyshift);
}
return c;
}
void init_keys(const char *passwd, uint32_t *pkeys, const z_crc_t *pcrc_32_tab)
{
*(pkeys+0) = 305419896L;
*(pkeys+1) = 591751049L;
*(pkeys+2) = 878082192L;
while (*passwd != 0)
{
update_keys(pkeys, pcrc_32_tab, *passwd);
passwd += 1;
}
}
/***************************************************************************/
int cryptrand(unsigned char *buf, unsigned int len)
{
static unsigned calls = 0;
int rlen = 0;
#ifdef _WIN32
HCRYPTPROV provider;
unsigned __int64 pentium_tsc[1];
int result = 0;
if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
{
result = CryptGenRandom(provider, len, buf);
CryptReleaseContext(provider, 0);
if (result)
return len;
}
for (rlen = 0; rlen < (int)len; ++rlen)
{
if (rlen % 8 == 0)
QueryPerformanceCounter((LARGE_INTEGER *)pentium_tsc);
buf[rlen] = ((unsigned char*)pentium_tsc)[rlen % 8];
}
#else
int frand = open("/dev/urandom", O_RDONLY);
if (frand != -1)
{
rlen = (int)read(frand, buf, len);
close(frand);
}
#endif
if (rlen < (int)len)
{
/* Ensure different random header each time */
if (++calls == 1)
srand((unsigned)(time(NULL) ^ ZCR_SEED2));
while (rlen < (int)len)
buf[rlen++] = (rand() >> 7) & 0xff;
}
return rlen;
}
int crypthead(const char *passwd, uint8_t *buf, int buf_size, uint32_t *pkeys,
const z_crc_t *pcrc_32_tab, uint8_t verify1, uint8_t verify2)
{
uint8_t n = 0; /* index in random header */
uint8_t header[RAND_HEAD_LEN-2]; /* random header */
uint16_t t = 0; /* temporary */
if (buf_size < RAND_HEAD_LEN)
return 0;
init_keys(passwd, pkeys, pcrc_32_tab);
/* First generate RAND_HEAD_LEN-2 random bytes. */
cryptrand(header, RAND_HEAD_LEN-2);
/* Encrypt random header (last two bytes is high word of crc) */
init_keys(passwd, pkeys, pcrc_32_tab);
for (n = 0; n < RAND_HEAD_LEN-2; n++)
buf[n] = (uint8_t)zencode(pkeys, pcrc_32_tab, header[n], t);
buf[n++] = (uint8_t)zencode(pkeys, pcrc_32_tab, verify1, t);
buf[n++] = (uint8_t)zencode(pkeys, pcrc_32_tab, verify2, t);
return n;
}
#ifdef _WIN32
# pragma warning(pop)
#endif // _WIN32
/***************************************************************************/

View File

@ -1,133 +1,61 @@
/* crypt.h -- base code for crypt/uncrypt ZIPfile /* crypt.h -- base code for traditional PKWARE encryption
Version 1.01e, February 12th, 2005 Version 1.01e, February 12th, 2005
Copyright (C) 1998-2005 Gilles Vollant Copyright (C) 1998-2005 Gilles Vollant
Modifications for Info-ZIP crypting
Copyright (C) 2003 Terry Thorsen
This code is a modified version of crypting code in Infozip distribution This code is a modified version of crypting code in Info-ZIP distribution
The encryption/decryption parts of this source code (as opposed to the Copyright (C) 1990-2000 Info-ZIP. All rights reserved.
non-echoing password parts) were originally written in Europe. The
whole source package can be freely distributed, including from the USA.
(Prior to January 2000, re-export from the US was a violation of US law.)
This encryption code is a direct transcription of the algorithm from This program is distributed under the terms of the same license as zlib.
Roger Schlafly, described by Phil Katz in the file appnote.txt. This See the accompanying LICENSE file for the full text of the license.
file (appnote.txt) is distributed with the PKZIP program (even in the
version without encryption capabilities).
If you don't need crypting in your application, just define symbols
NOCRYPT and NOUNCRYPT.
This code support the "Traditional PKWARE Encryption".
The new AES encryption added on Zip format by Winzip (see the page
http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
Encryption is not supported.
*/ */
#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) #ifndef _MINICRYPT_H
#define _MINICRYPT_H
/*********************************************************************** #if ZLIB_VERNUM < 0x1270
* Return the next byte in the pseudo-random sequence typedef unsigned long z_crc_t;
*/ #endif
static int decrypt_byte(unsigned long* pkeys, const z_crc_t* t)
{
unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
* unpredictable manner on 16-bit systems; not a problem
* with any known compiler so far, though */
temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; #ifdef __cplusplus
(void)t; extern "C" {
return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); #endif
}
/***********************************************************************
* Update the encryption keys with the next byte of plain text
*/
static int update_keys(unsigned long* pkeys,const z_crc_t* pcrc_32_tab,int c)
{
(*(pkeys+0)) = CRC32((*(pkeys+0)), c);
(*(pkeys+1)) += (*(pkeys+0)) & 0xff;
(*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
{
register int keyshift = (int)((*(pkeys+1)) >> 24);
(*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
}
return c;
}
/***********************************************************************
* Initialize the encryption keys and the random header according to
* the given password.
*/
static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t* pcrc_32_tab)
{
*(pkeys+0) = 305419896L;
*(pkeys+1) = 591751049L;
*(pkeys+2) = 878082192L;
while (*passwd != '\0') {
update_keys(pkeys,pcrc_32_tab,(int)*passwd);
passwd++;
}
}
#define zdecode(pkeys,pcrc_32_tab,c) \
(update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
#define zencode(pkeys,pcrc_32_tab,c,t) \
(t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
#define RAND_HEAD_LEN 12 #define RAND_HEAD_LEN 12
/* "last resort" source for second part of crypt seed pattern */
# ifndef ZCR_SEED2 /***************************************************************************/
# define ZCR_SEED2 3141592654UL /* use PI as default pattern */
#define zdecode(pkeys,pcrc_32_tab,c) \
(update_keys(pkeys,pcrc_32_tab, c ^= decrypt_byte(pkeys)))
#define zencode(pkeys,pcrc_32_tab,c,t) \
(t = decrypt_byte(pkeys), update_keys(pkeys,pcrc_32_tab,c), t^(c))
/***************************************************************************/
/* Return the next byte in the pseudo-random sequence */
uint8_t decrypt_byte(uint32_t *pkeys);
/* Update the encryption keys with the next byte of plain text */
uint8_t update_keys(uint32_t *pkeys, const z_crc_t *pcrc_32_tab, int32_t c);
/* Initialize the encryption keys and the random header according to the given password. */
void init_keys(const char *passwd, uint32_t *pkeys, const z_crc_t *pcrc_32_tab);
/* Generate cryptographically secure random numbers */
int cryptrand(unsigned char *buf, unsigned int len);
/* Create encryption header */
int crypthead(const char *passwd, uint8_t *buf, int buf_size, uint32_t *pkeys,
const z_crc_t *pcrc_32_tab, uint8_t verify1, uint8_t verify2);
/***************************************************************************/
#ifdef __cplusplus
}
#endif #endif
static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)
const char *passwd; /* password string */
unsigned char *buf; /* where to write header */
int bufSize;
unsigned long* pkeys;
const unsigned long* pcrc_32_tab;
unsigned long crcForCrypting;
{
int n; /* index in random header */
int t; /* temporary */
int c; /* random byte */
unsigned char header[RAND_HEAD_LEN-2]; /* random header */
static unsigned calls = 0; /* ensure different random header each time */
if (bufSize<RAND_HEAD_LEN)
return 0;
/* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
* output of rand() to get less predictability, since rand() is
* often poorly implemented.
*/
if (++calls == 1)
{
srand((unsigned)(time(NULL) ^ ZCR_SEED2));
}
init_keys(passwd, pkeys, pcrc_32_tab);
for (n = 0; n < RAND_HEAD_LEN-2; n++)
{
c = (rand() >> 7) & 0xff;
header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
}
/* Encrypt random header (last two bytes is high word of crc) */
init_keys(passwd, pkeys, pcrc_32_tab);
for (n = 0; n < RAND_HEAD_LEN-2; n++)
{
buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
}
buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
return n;
}
#endif #endif

View File

@ -1,19 +1,28 @@
/* ioapi.c -- IO base function header for compress/uncompress .zip /* ioapi.c -- IO base function header for compress/uncompress .zip
files using zlib + zip or unzip API part of the MiniZip project
Version 1.01e, February 12th, 2005 Copyright (C) 1998-2010 Gilles Vollant
http://www.winimage.com/zLibDll/minizip.html
Modifications for Zip64 support
Copyright (C) 2009-2010 Mathias Svensson
http://result42.com
Copyright (C) 1998-2005 Gilles Vollant This program is distributed under the terms of the same license as zlib.
See the accompanying LICENSE file for the full text of the license.
*/ */
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "zlib.h" #if defined unix || defined __APPLE__
#include <sys/types.h>
#include <unistd.h>
#endif
#include "ioapi.h" #include "ioapi.h"
#ifdef _WIN32 #ifdef _WIN32
# define snprintf _snprintf
# pragma warning(push) # pragma warning(push)
# pragma warning(disable : 4131 4100) # pragma warning(disable : 4131 4100)
# ifdef __clang__ # ifdef __clang__
@ -22,118 +31,231 @@
# endif # endif
#endif // _WIN32 #endif // _WIN32
/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
#ifndef SEEK_CUR voidpf call_zopen64(const zlib_filefunc64_32_def *pfilefunc, const void *filename, int mode)
#define SEEK_CUR 1 {
#endif if (pfilefunc->zfile_func64.zopen64_file != NULL)
return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque, filename, mode);
return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque, (const char*)filename, mode);
}
#ifndef SEEK_END voidpf call_zopendisk64(const zlib_filefunc64_32_def *pfilefunc, voidpf filestream, uint32_t number_disk, int mode)
#define SEEK_END 2 {
#endif if (pfilefunc->zfile_func64.zopendisk64_file != NULL)
return (*(pfilefunc->zfile_func64.zopendisk64_file)) (pfilefunc->zfile_func64.opaque, filestream, number_disk, mode);
return (*(pfilefunc->zopendisk32_file))(pfilefunc->zfile_func64.opaque, filestream, number_disk, mode);
}
#ifndef SEEK_SET long call_zseek64(const zlib_filefunc64_32_def *pfilefunc, voidpf filestream, uint64_t offset, int origin)
#define SEEK_SET 0 {
#endif uint32_t offset_truncated = 0;
if (pfilefunc->zfile_func64.zseek64_file != NULL)
return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);
offset_truncated = (uint32_t)offset;
if (offset_truncated != offset)
return -1;
return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream, offset_truncated, origin);
}
voidpf ZCALLBACK fopen_file_func OF(( uint64_t call_ztell64(const zlib_filefunc64_32_def *pfilefunc, voidpf filestream)
voidpf opaque, {
const char* filename, uint64_t position;
int mode)); if (pfilefunc->zfile_func64.zseek64_file != NULL)
return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque, filestream);
position = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque, filestream);
if ((position) == UINT32_MAX)
return (uint64_t)-1;
return position;
}
uLong ZCALLBACK fread_file_func OF(( void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def *p_filefunc64_32, const zlib_filefunc_def *p_filefunc32)
voidpf opaque, {
voidpf stream, p_filefunc64_32->zfile_func64.zopen64_file = NULL;
void* buf, p_filefunc64_32->zfile_func64.zopendisk64_file = NULL;
uLong size)); p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
p_filefunc64_32->zopendisk32_file = p_filefunc32->zopendisk_file;
p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
p_filefunc64_32->zfile_func64.ztell64_file = NULL;
p_filefunc64_32->zfile_func64.zseek64_file = NULL;
p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;
p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;
p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;
p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;
}
uLong ZCALLBACK fwrite_file_func OF(( static voidpf ZCALLBACK fopen_file_func(voidpf opaque, const char *filename, int mode);
voidpf opaque, static uint32_t ZCALLBACK fread_file_func(voidpf opaque, voidpf stream, void* buf, uint32_t size);
voidpf stream, static uint32_t ZCALLBACK fwrite_file_func(voidpf opaque, voidpf stream, const void *buf, uint32_t size);
const void* buf, static uint64_t ZCALLBACK ftell64_file_func(voidpf opaque, voidpf stream);
uLong size)); static long ZCALLBACK fseek64_file_func(voidpf opaque, voidpf stream, uint64_t offset, int origin);
static int ZCALLBACK fclose_file_func(voidpf opaque, voidpf stream);
static int ZCALLBACK ferror_file_func(voidpf opaque, voidpf stream);
long ZCALLBACK ftell_file_func OF(( typedef struct
voidpf opaque, {
voidpf stream)); FILE *file;
int filenameLength;
void *filename;
} FILE_IOPOSIX;
long ZCALLBACK fseek_file_func OF(( static voidpf file_build_ioposix(FILE *file, const char *filename)
voidpf opaque, {
voidpf stream, FILE_IOPOSIX *ioposix = NULL;
uLong offset, if (file == NULL)
int origin)); return NULL;
ioposix = (FILE_IOPOSIX*)malloc(sizeof(FILE_IOPOSIX));
ioposix->file = file;
ioposix->filenameLength = (int)strlen(filename) + 1;
ioposix->filename = (char*)malloc(ioposix->filenameLength * sizeof(char));
memcpy((char*)ioposix->filename, filename, ioposix->filenameLength);
return (voidpf)ioposix;
}
int ZCALLBACK fclose_file_func OF(( static voidpf ZCALLBACK fopen_file_func(voidpf opaque, const char *filename, int mode)
voidpf opaque,
voidpf stream));
int ZCALLBACK ferror_file_func OF((
voidpf opaque,
voidpf stream));
voidpf ZCALLBACK fopen_file_func (opaque, filename, mode)
voidpf opaque;
const char* filename;
int mode;
{ {
FILE* file = NULL; FILE* file = NULL;
const char *mode_fopen = NULL; const char *mode_fopen = NULL;
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ) if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ)
mode_fopen = "rb"; mode_fopen = "rb";
else else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
mode_fopen = "r+b"; mode_fopen = "r+b";
else else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
if (mode & ZLIB_FILEFUNC_MODE_CREATE)
mode_fopen = "wb"; mode_fopen = "wb";
if ((filename != NULL) && (mode_fopen != NULL)) if ((filename != NULL) && (mode_fopen != NULL))
{
file = fopen(filename, mode_fopen); file = fopen(filename, mode_fopen);
return file_build_ioposix(file, filename);
}
return file; return file;
} }
static voidpf ZCALLBACK fopen64_file_func(voidpf opaque, const void *filename, int mode)
uLong ZCALLBACK fread_file_func (opaque, stream, buf, size)
voidpf opaque;
voidpf stream;
void* buf;
uLong size;
{ {
uLong ret; FILE* file = NULL;
ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); const char *mode_fopen = NULL;
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ)
mode_fopen = "rb";
else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
mode_fopen = "r+b";
else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
mode_fopen = "wb";
if ((filename != NULL) && (mode_fopen != NULL))
{
file = fopen64((const char*)filename, mode_fopen);
return file_build_ioposix(file, (const char*)filename);
}
return file;
}
static voidpf ZCALLBACK fopendisk64_file_func(voidpf opaque, voidpf stream, uint32_t number_disk, int mode)
{
FILE_IOPOSIX *ioposix = NULL;
char *diskFilename = NULL;
voidpf ret = NULL;
int i = 0;
if (stream == NULL)
return NULL;
ioposix = (FILE_IOPOSIX*)stream;
diskFilename = (char*)malloc(ioposix->filenameLength * sizeof(char));
strncpy(diskFilename, (const char*)ioposix->filename, ioposix->filenameLength);
for (i = ioposix->filenameLength - 1; i >= 0; i -= 1)
{
if (diskFilename[i] != '.')
continue;
snprintf(&diskFilename[i], ioposix->filenameLength - i, ".z%02u", number_disk + 1);
break;
}
if (i >= 0)
ret = fopen64_file_func(opaque, diskFilename, mode);
free(diskFilename);
return ret; return ret;
} }
static voidpf ZCALLBACK fopendisk_file_func(voidpf opaque, voidpf stream, uint32_t number_disk, int mode)
uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size)
voidpf opaque;
voidpf stream;
const void* buf;
uLong size;
{ {
uLong ret; FILE_IOPOSIX *ioposix = NULL;
ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); char *diskFilename = NULL;
voidpf ret = NULL;
int i = 0;
if (stream == NULL)
return NULL;
ioposix = (FILE_IOPOSIX*)stream;
diskFilename = (char*)malloc(ioposix->filenameLength * sizeof(char));
strncpy(diskFilename, (const char*)ioposix->filename, ioposix->filenameLength);
for (i = ioposix->filenameLength - 1; i >= 0; i -= 1)
{
if (diskFilename[i] != '.')
continue;
snprintf(&diskFilename[i], ioposix->filenameLength - i, ".z%02u", number_disk + 1);
break;
}
if (i >= 0)
ret = fopen_file_func(opaque, diskFilename, mode);
free(diskFilename);
return ret; return ret;
} }
long ZCALLBACK ftell_file_func (opaque, stream) static uint32_t ZCALLBACK fread_file_func(voidpf opaque, voidpf stream, void* buf, uint32_t size)
voidpf opaque;
voidpf stream;
{ {
long ret; FILE_IOPOSIX *ioposix = NULL;
ret = ftell((FILE *)stream); uint32_t read = (uint32_t)-1;
if (stream == NULL)
return read;
ioposix = (FILE_IOPOSIX*)stream;
read = (uint32_t)fread(buf, 1, (size_t)size, ioposix->file);
return read;
}
static uint32_t ZCALLBACK fwrite_file_func(voidpf opaque, voidpf stream, const void *buf, uint32_t size)
{
FILE_IOPOSIX *ioposix = NULL;
uint32_t written = (uint32_t)-1;
if (stream == NULL)
return written;
ioposix = (FILE_IOPOSIX*)stream;
written = (uint32_t)fwrite(buf, 1, (size_t)size, ioposix->file);
return written;
}
static long ZCALLBACK ftell_file_func(voidpf opaque, voidpf stream)
{
FILE_IOPOSIX *ioposix = NULL;
long ret = -1;
if (stream == NULL)
return ret;
ioposix = (FILE_IOPOSIX*)stream;
ret = ftell(ioposix->file);
return ret; return ret;
} }
long ZCALLBACK fseek_file_func (opaque, stream, offset, origin) static uint64_t ZCALLBACK ftell64_file_func(voidpf opaque, voidpf stream)
voidpf opaque;
voidpf stream;
uLong offset;
int origin;
{ {
FILE_IOPOSIX *ioposix = NULL;
uint64_t ret = (uint64_t)-1;
if (stream == NULL)
return ret;
ioposix = (FILE_IOPOSIX*)stream;
ret = ftello64(ioposix->file);
return ret;
}
static long ZCALLBACK fseek_file_func(voidpf opaque, voidpf stream, uint32_t offset, int origin)
{
FILE_IOPOSIX *ioposix = NULL;
int fseek_origin = 0; int fseek_origin = 0;
long ret; long ret = 0;
if (stream == NULL)
return -1;
ioposix = (FILE_IOPOSIX*)stream;
switch (origin) switch (origin)
{ {
case ZLIB_FILEFUNC_SEEK_CUR: case ZLIB_FILEFUNC_SEEK_CUR:
@ -145,35 +267,74 @@ long ZCALLBACK fseek_file_func (opaque, stream, offset, origin)
case ZLIB_FILEFUNC_SEEK_SET: case ZLIB_FILEFUNC_SEEK_SET:
fseek_origin = SEEK_SET; fseek_origin = SEEK_SET;
break; break;
default: return -1; default:
return -1;
} }
ret = 0; if (fseek(ioposix->file, offset, fseek_origin) != 0)
fseek((FILE *)stream, offset, fseek_origin); ret = -1;
return ret; return ret;
} }
int ZCALLBACK fclose_file_func (opaque, stream) static long ZCALLBACK fseek64_file_func(voidpf opaque, voidpf stream, uint64_t offset, int origin)
voidpf opaque;
voidpf stream;
{ {
int ret; FILE_IOPOSIX *ioposix = NULL;
ret = fclose((FILE *)stream); int fseek_origin = 0;
return ret; long ret = 0;
}
int ZCALLBACK ferror_file_func (opaque, stream) if (stream == NULL)
voidpf opaque; return -1;
voidpf stream; ioposix = (FILE_IOPOSIX*)stream;
switch (origin)
{ {
int ret; case ZLIB_FILEFUNC_SEEK_CUR:
ret = ferror((FILE *)stream); fseek_origin = SEEK_CUR;
break;
case ZLIB_FILEFUNC_SEEK_END:
fseek_origin = SEEK_END;
break;
case ZLIB_FILEFUNC_SEEK_SET:
fseek_origin = SEEK_SET;
break;
default:
return -1;
}
if (fseeko64(ioposix->file, offset, fseek_origin) != 0)
ret = -1;
return ret; return ret;
} }
void fill_fopen_filefunc (pzlib_filefunc_def) static int ZCALLBACK fclose_file_func(voidpf opaque, voidpf stream)
zlib_filefunc_def* pzlib_filefunc_def; {
FILE_IOPOSIX *ioposix = NULL;
int ret = -1;
if (stream == NULL)
return ret;
ioposix = (FILE_IOPOSIX*)stream;
if (ioposix->filename != NULL)
free(ioposix->filename);
ret = fclose(ioposix->file);
free(ioposix);
return ret;
}
static int ZCALLBACK ferror_file_func(voidpf opaque, voidpf stream)
{
FILE_IOPOSIX *ioposix = NULL;
int ret = -1;
if (stream == NULL)
return ret;
ioposix = (FILE_IOPOSIX*)stream;
ret = ferror(ioposix->file);
return ret;
}
void fill_fopen_filefunc(zlib_filefunc_def *pzlib_filefunc_def)
{ {
pzlib_filefunc_def->zopen_file = fopen_file_func; pzlib_filefunc_def->zopen_file = fopen_file_func;
pzlib_filefunc_def->zopendisk_file = fopendisk_file_func;
pzlib_filefunc_def->zread_file = fread_file_func; pzlib_filefunc_def->zread_file = fread_file_func;
pzlib_filefunc_def->zwrite_file = fwrite_file_func; pzlib_filefunc_def->zwrite_file = fwrite_file_func;
pzlib_filefunc_def->ztell_file = ftell_file_func; pzlib_filefunc_def->ztell_file = ftell_file_func;
@ -183,6 +344,19 @@ void fill_fopen_filefunc (pzlib_filefunc_def)
pzlib_filefunc_def->opaque = NULL; pzlib_filefunc_def->opaque = NULL;
} }
void fill_fopen64_filefunc(zlib_filefunc64_def *pzlib_filefunc_def)
{
pzlib_filefunc_def->zopen64_file = fopen64_file_func;
pzlib_filefunc_def->zopendisk64_file = fopendisk64_file_func;
pzlib_filefunc_def->zread_file = fread_file_func;
pzlib_filefunc_def->zwrite_file = fwrite_file_func;
pzlib_filefunc_def->ztell64_file = ftell64_file_func;
pzlib_filefunc_def->zseek64_file = fseek64_file_func;
pzlib_filefunc_def->zclose_file = fclose_file_func;
pzlib_filefunc_def->zerror_file = ferror_file_func;
pzlib_filefunc_def->opaque = NULL;
}
#ifdef _WIN32 #ifdef _WIN32
# pragma warning(pop) # pragma warning(pop)
# ifdef __clang__ # ifdef __clang__

View File

@ -1,14 +1,49 @@
/* ioapi.h -- IO base function header for compress/uncompress .zip /* ioapi.h -- IO base function header for compress/uncompress .zip
files using zlib + zip or unzip API part of the MiniZip project
Version 1.01e, February 12th, 2005 Copyright (C) 1998-2010 Gilles Vollant
http://www.winimage.com/zLibDll/minizip.html
Modifications for Zip64 support
Copyright (C) 2009-2010 Mathias Svensson
http://result42.com
Copyright (C) 1998-2005 Gilles Vollant This program is distributed under the terms of the same license as zlib.
See the accompanying LICENSE file for the full text of the license.
*/ */
#ifndef _ZLIBIOAPI_H #ifndef _ZLIBIOAPI64_H
#define _ZLIBIOAPI_H #define _ZLIBIOAPI64_H
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "zlib.h"
#if defined(USE_FILE32API)
# define fopen64 fopen
# define ftello64 ftell
# define fseeko64 fseek
#else
#if defined(_MSC_VER)
# define fopen64 fopen
# if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
# define ftello64 _ftelli64
# define fseeko64 _fseeki64
# else /* old MSC */
# define ftello64 ftell
# define fseeko64 fseek
# endif
#else
# define fopen64 fopen
# define ftello64 ftello
# define fseeko64 fseeko
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define ZLIB_FILEFUNC_SEEK_CUR (1) #define ZLIB_FILEFUNC_SEEK_CUR (1)
#define ZLIB_FILEFUNC_SEEK_END (2) #define ZLIB_FILEFUNC_SEEK_END (2)
@ -17,59 +52,94 @@
#define ZLIB_FILEFUNC_MODE_READ (1) #define ZLIB_FILEFUNC_MODE_READ (1)
#define ZLIB_FILEFUNC_MODE_WRITE (2) #define ZLIB_FILEFUNC_MODE_WRITE (2)
#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) #define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
#define ZLIB_FILEFUNC_MODE_EXISTING (4) #define ZLIB_FILEFUNC_MODE_EXISTING (4)
#define ZLIB_FILEFUNC_MODE_CREATE (8) #define ZLIB_FILEFUNC_MODE_CREATE (8)
#ifndef ZCALLBACK #ifndef ZCALLBACK
# if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || \
#if (defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
# define ZCALLBACK CALLBACK # define ZCALLBACK CALLBACK
# else # else
# define ZCALLBACK # define ZCALLBACK
# endif # endif
#endif #endif
#ifdef __cplusplus typedef voidpf (ZCALLBACK *open_file_func) (voidpf opaque, const char *filename, int mode);
extern "C" { typedef voidpf (ZCALLBACK *opendisk_file_func) (voidpf opaque, voidpf stream, uint32_t number_disk, int mode);
#endif typedef uint32_t (ZCALLBACK *read_file_func) (voidpf opaque, voidpf stream, void* buf, uint32_t size);
typedef uint32_t (ZCALLBACK *write_file_func) (voidpf opaque, voidpf stream, const void *buf, uint32_t size);
typedef int (ZCALLBACK *close_file_func) (voidpf opaque, voidpf stream);
typedef int (ZCALLBACK *error_file_func) (voidpf opaque, voidpf stream);
typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); typedef long (ZCALLBACK *tell_file_func) (voidpf opaque, voidpf stream);
typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); typedef long (ZCALLBACK *seek_file_func) (voidpf opaque, voidpf stream, uint32_t offset, int origin);
typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
/* here is the "old" 32 bits structure structure */
typedef struct zlib_filefunc_def_s typedef struct zlib_filefunc_def_s
{ {
open_file_func zopen_file; open_file_func zopen_file;
opendisk_file_func zopendisk_file;
read_file_func zread_file; read_file_func zread_file;
write_file_func zwrite_file; write_file_func zwrite_file;
tell_file_func ztell_file; tell_file_func ztell_file;
seek_file_func zseek_file; seek_file_func zseek_file;
close_file_func zclose_file; close_file_func zclose_file;
testerror_file_func zerror_file; error_file_func zerror_file;
voidpf opaque; voidpf opaque;
} zlib_filefunc_def; } zlib_filefunc_def;
typedef uint64_t (ZCALLBACK *tell64_file_func) (voidpf opaque, voidpf stream);
typedef long (ZCALLBACK *seek64_file_func) (voidpf opaque, voidpf stream, uint64_t offset, int origin);
typedef voidpf (ZCALLBACK *open64_file_func) (voidpf opaque, const void *filename, int mode);
typedef voidpf (ZCALLBACK *opendisk64_file_func)(voidpf opaque, voidpf stream, uint32_t number_disk, int mode);
typedef struct zlib_filefunc64_def_s
{
open64_file_func zopen64_file;
opendisk64_file_func zopendisk64_file;
read_file_func zread_file;
write_file_func zwrite_file;
tell64_file_func ztell64_file;
seek64_file_func zseek64_file;
close_file_func zclose_file;
error_file_func zerror_file;
voidpf opaque;
} zlib_filefunc64_def;
void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); void fill_fopen_filefunc(zlib_filefunc_def *pzlib_filefunc_def);
void fill_fopen64_filefunc(zlib_filefunc64_def *pzlib_filefunc_def);
#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size)) /* now internal definition, only for zip.c and unzip.h */
#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size)) typedef struct zlib_filefunc64_32_def_s
#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream)) {
#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode)) zlib_filefunc64_def zfile_func64;
#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream)) open_file_func zopen32_file;
#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream)) opendisk_file_func zopendisk32_file;
tell_file_func ztell32_file;
seek_file_func zseek32_file;
} zlib_filefunc64_32_def;
#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
/*#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream))*/
/*#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode))*/
#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream))
#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream))
voidpf call_zopen64(const zlib_filefunc64_32_def *pfilefunc,const void*filename, int mode);
voidpf call_zopendisk64(const zlib_filefunc64_32_def *pfilefunc, voidpf filestream, uint32_t number_disk, int mode);
long call_zseek64(const zlib_filefunc64_32_def *pfilefunc, voidpf filestream, uint64_t offset, int origin);
uint64_t call_ztell64(const zlib_filefunc64_32_def *pfilefunc, voidpf filestream);
void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def *p_filefunc64_32, const zlib_filefunc_def *p_filefunc32);
#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode)))
#define ZOPENDISK64(filefunc,filestream,diskn,mode) (call_zopendisk64((&(filefunc)),(filestream),(diskn),(mode)))
#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream)))
#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -1,49 +1,21 @@
/* unzip.h -- IO for uncompress .zip files using zlib /* unzip.h -- IO for uncompress .zip files using zlib
Version 1.01e, February 12th, 2005 Version 1.1, February 14h, 2010
part of the MiniZip project
Copyright (C) 1998-2005 Gilles Vollant
This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
WinZip, InfoZip tools and compatible.
Multi volume ZipFile (span) are not supported.
Encryption compatible with pkzip 2.04g only supported
Old compressions used by old PKZip 1.x are not supported
I WAIT FEEDBACK at mail info@winimage.com
Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
Condition of use and distribution are the same than zlib :
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Copyright (C) 1998-2010 Gilles Vollant
http://www.winimage.com/zLibDll/minizip.html
Modifications of Unzip for Zip64
Copyright (C) 2007-2008 Even Rouault
Modifications for Zip64 support on both zip and unzip
Copyright (C) 2009-2010 Mathias Svensson
http://result42.com
This program is distributed under the terms of the same license as zlib.
See the accompanying LICENSE file for the full text of the license.
*/ */
/* for more info about .ZIP format, see #ifndef _UNZ_H
http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip #define _UNZ_H
http://www.info-zip.org/pub/infozip/doc/
PkWare has also a specification at :
ftp://ftp.pkware.com/probdesc.zip
*/
#ifndef _unz_H
#define _unz_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -57,16 +29,21 @@ extern "C" {
#include "ioapi.h" #include "ioapi.h"
#endif #endif
#ifdef HAVE_BZIP2
#include "bzlib.h"
#endif
#define Z_BZIP2ED 12
#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) #if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
/* like the STRICT of WIN32, we define a pointer that cannot be converted /* like the STRICT of WIN32, we define a pointer that cannot be converted
from (void*) without cast */ from (void*) without cast */
typedef struct TagunzFile__ { int unused; } unzFile__; typedef struct TagunzFile__ { int unused; } unz_file__;
typedef unzFile__ *unzFile; typedef unz_file__ *unzFile;
#else #else
typedef voidp unzFile; typedef voidp unzFile;
#endif #endif
#define UNZ_OK (0) #define UNZ_OK (0)
#define UNZ_END_OF_LIST_OF_FILE (-100) #define UNZ_END_OF_LIST_OF_FILE (-100)
#define UNZ_ERRNO (Z_ERRNO) #define UNZ_ERRNO (Z_ERRNO)
@ -75,280 +52,255 @@ typedef voidp unzFile;
#define UNZ_BADZIPFILE (-103) #define UNZ_BADZIPFILE (-103)
#define UNZ_INTERNALERROR (-104) #define UNZ_INTERNALERROR (-104)
#define UNZ_CRCERROR (-105) #define UNZ_CRCERROR (-105)
#define UNZ_BADPASSWORD (-106)
/* tm_unz contain date/time info */
typedef struct tm_unz_s
{
uInt tm_sec; /* seconds after the minute - [0,59] */
uInt tm_min; /* minutes after the hour - [0,59] */
uInt tm_hour; /* hours since midnight - [0,23] */
uInt tm_mday; /* day of the month - [1,31] */
uInt tm_mon; /* months since January - [0,11] */
uInt tm_year; /* years - [1980..2044] */
} tm_unz;
/* unz_global_info structure contain global data about the ZIPfile /* unz_global_info structure contain global data about the ZIPfile
These data comes from the end of central dir */ These data comes from the end of central dir */
typedef struct unz_global_info64_s
{
uint64_t number_entry; /* total number of entries in the central dir on this disk */
uint32_t number_disk_with_CD; /* number the the disk with central dir, used for spanning ZIP*/
uint16_t size_comment; /* size of the global comment of the zipfile */
} unz_global_info64;
typedef struct unz_global_info_s typedef struct unz_global_info_s
{ {
uLong number_entry; /* total number of entries in uint32_t number_entry; /* total number of entries in the central dir on this disk */
the central dir on this disk */ uint32_t number_disk_with_CD; /* number the the disk with central dir, used for spanning ZIP*/
uLong size_comment; /* size of the global comment of the zipfile */ uint16_t size_comment; /* size of the global comment of the zipfile */
} unz_global_info; } unz_global_info;
/* unz_file_info contain information about a file in the zipfile */ /* unz_file_info contain information about a file in the zipfile */
typedef struct unz_file_info64_s
{
uint16_t version; /* version made by 2 bytes */
uint16_t version_needed; /* version needed to extract 2 bytes */
uint16_t flag; /* general purpose bit flag 2 bytes */
uint16_t compression_method; /* compression method 2 bytes */
uint32_t dos_date; /* last mod file date in Dos fmt 4 bytes */
uint32_t crc; /* crc-32 4 bytes */
uint64_t compressed_size; /* compressed size 8 bytes */
uint64_t uncompressed_size; /* uncompressed size 8 bytes */
uint16_t size_filename; /* filename length 2 bytes */
uint16_t size_file_extra; /* extra field length 2 bytes */
uint16_t size_file_comment; /* file comment length 2 bytes */
uint32_t disk_num_start; /* disk number start 4 bytes */
uint16_t internal_fa; /* internal file attributes 2 bytes */
uint32_t external_fa; /* external file attributes 4 bytes */
uint64_t disk_offset;
uint16_t size_file_extra_internal;
} unz_file_info64;
typedef struct unz_file_info_s typedef struct unz_file_info_s
{ {
uLong version; /* version made by 2 bytes */ uint16_t version; /* version made by 2 bytes */
uLong version_needed; /* version needed to extract 2 bytes */ uint16_t version_needed; /* version needed to extract 2 bytes */
uLong flag; /* general purpose bit flag 2 bytes */ uint16_t flag; /* general purpose bit flag 2 bytes */
uLong compression_method; /* compression method 2 bytes */ uint16_t compression_method; /* compression method 2 bytes */
uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ uint32_t dos_date; /* last mod file date in Dos fmt 4 bytes */
uLong crc; /* crc-32 4 bytes */ uint32_t crc; /* crc-32 4 bytes */
uLong compressed_size; /* compressed size 4 bytes */ uint32_t compressed_size; /* compressed size 4 bytes */
uLong uncompressed_size; /* uncompressed size 4 bytes */ uint32_t uncompressed_size; /* uncompressed size 4 bytes */
uLong size_filename; /* filename length 2 bytes */ uint16_t size_filename; /* filename length 2 bytes */
uLong size_file_extra; /* extra field length 2 bytes */ uint16_t size_file_extra; /* extra field length 2 bytes */
uLong size_file_comment; /* file comment length 2 bytes */ uint16_t size_file_comment; /* file comment length 2 bytes */
uLong disk_num_start; /* disk number start 2 bytes */ uint16_t disk_num_start; /* disk number start 2 bytes */
uLong internal_fa; /* internal file attributes 2 bytes */ uint16_t internal_fa; /* internal file attributes 2 bytes */
uLong external_fa; /* external file attributes 4 bytes */ uint32_t external_fa; /* external file attributes 4 bytes */
tm_unz tmu_date; uint64_t disk_offset;
} unz_file_info; } unz_file_info;
extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, /***************************************************************************/
const char* fileName2, /* Opening and close a zip file */
int iCaseSensitivity));
/*
Compare two filename (fileName1,fileName2).
If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
or strcasecmp)
If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
(like 1 on Unix, 2 on Windows)
*/
extern unzFile ZEXPORT unzOpen(const char *path);
extern unzFile ZEXPORT unzOpen64(const void *path);
/* Open a Zip file.
extern unzFile ZEXPORT unzOpen OF((const char *path)); path should contain the full path (by example, on a Windows XP computer
/* "c:\\zlib\\zlib113.zip" or on an Unix computer "zlib/zlib113.zip".
Open a Zip file. path contain the full pathname (by example, return NULL if zipfile cannot be opened or doesn't exist
on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer return unzFile handle if no error
"zlib/zlib113.zip".
If the zipfile cannot be opened (file don't exist or in not valid), the
return value is NULL.
Else, the return value is a unzFile Handle, usable with other function
of this unzip package.
*/
extern unzFile ZEXPORT unzOpen2 OF((const char *path, NOTE: The "64" function take a const void *pointer, because the path is just the value passed to the
zlib_filefunc_def* pzlib_filefunc_def)); open64_file_func callback. Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path
/* is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char *does not describe the reality */
Open a Zip file, like unzOpen, but provide a set of file low level API
for read/write the zip file (see ioapi.h)
*/
extern int ZEXPORT unzClose OF((unzFile file)); extern unzFile ZEXPORT unzOpen2(const char *path, zlib_filefunc_def *pzlib_filefunc_def);
/* /* Open a Zip file, like unzOpen, but provide a set of file low level API for read/write operations */
Close a ZipFile opened with unzipOpen. extern unzFile ZEXPORT unzOpen2_64(const void *path, zlib_filefunc64_def *pzlib_filefunc_def);
If there is files inside the .Zip opened with unzOpenCurrentFile (see later), /* Open a Zip file, like unz64Open, but provide a set of file low level API for read/write 64-bit operations */
extern int ZEXPORT unzClose(unzFile file);
/* Close a ZipFile opened with unzOpen. If there is files inside the .Zip opened with unzOpenCurrentFile,
these files MUST be closed with unzipCloseCurrentFile before call unzipClose. these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
return UNZ_OK if there is no problem. */
extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, return UNZ_OK if there is no error */
unz_global_info *pglobal_info));
/*
Write info about the ZipFile in the *pglobal_info structure.
No preparation of the structure is needed
return UNZ_OK if there is no problem. */
extern int ZEXPORT unzGetGlobalInfo(unzFile file, unz_global_info *pglobal_info);
extern int ZEXPORT unzGetGlobalInfo64(unzFile file, unz_global_info64 *pglobal_info);
/* Write info about the ZipFile in the *pglobal_info structure.
return UNZ_OK if no error */
extern int ZEXPORT unzGetGlobalComment(unzFile file, char *comment, uint16_t comment_size);
/* Get the global comment string of the ZipFile, in the comment buffer.
extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
char *szComment,
uLong uSizeBuf));
/*
Get the global comment string of the ZipFile, in the szComment buffer.
uSizeBuf is the size of the szComment buffer. uSizeBuf is the size of the szComment buffer.
return the number of byte copied or an error code <0 return the number of byte copied or an error code <0 */
*/
/***************************************************************************/ /***************************************************************************/
/* Unzip package allow you browse the directory of the zipfile */ /* Reading the content of the current zipfile, you can open it, read data from it, and close it
(you can close it before reading all the file) */
extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); extern int ZEXPORT unzOpenCurrentFile(unzFile file);
/* /* Open for reading data the current file in the zipfile.
Set the current file of the zipfile to the first file.
return UNZ_OK if there is no problem
*/
extern int ZEXPORT unzGoToNextFile OF((unzFile file)); return UNZ_OK if no error */
/*
Set the current file of the zipfile to the next file.
return UNZ_OK if there is no problem
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
*/
extern int ZEXPORT unzLocateFile OF((unzFile file, extern int ZEXPORT unzOpenCurrentFilePassword(unzFile file, const char *password);
const char *szFileName, /* Open for reading data the current file in the zipfile.
int iCaseSensitivity));
/*
Try locate the file szFileName in the zipfile.
For the iCaseSensitivity signification, see unzStringFileNameCompare
return value :
UNZ_OK if the file is found. It becomes the current file.
UNZ_END_OF_LIST_OF_FILE if the file is not found
*/
/* ****************************************** */
/* Ryan supplied functions */
/* unz_file_info contain information about a file in the zipfile */
typedef struct unz_file_pos_s
{
uLong pos_in_zip_directory; /* offset in zip file directory */
uLong num_of_file; /* # of file */
} unz_file_pos;
extern int ZEXPORT unzGetFilePos(
unzFile file,
unz_file_pos* file_pos);
extern int ZEXPORT unzGoToFilePos(
unzFile file,
unz_file_pos* file_pos);
/* ****************************************** */
extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
unz_file_info *pfile_info,
char *szFileName,
uLong fileNameBufferSize,
void *extraField,
uLong extraFieldBufferSize,
char *szComment,
uLong commentBufferSize));
/*
Get Info about the current file
if pfile_info!=NULL, the *pfile_info structure will contain somes info about
the current file
if szFileName!=NULL, the filemane string will be copied in szFileName
(fileNameBufferSize is the size of the buffer)
if extraField!=NULL, the extra field information will be copied in extraField
(extraFieldBufferSize is the size of the buffer).
This is the Central-header version of the extra field
if szComment!=NULL, the comment string of the file will be copied in szComment
(commentBufferSize is the size of the buffer)
*/
/***************************************************************************/
/* for reading the content of the current zipfile, you can open it, read data
from it, and close it (you can close it before reading all the file)
*/
extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
/*
Open for reading data the current file in the zipfile.
If there is no error, the return value is UNZ_OK.
*/
extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
const char* password));
/*
Open for reading data the current file in the zipfile.
password is a crypting password password is a crypting password
If there is no error, the return value is UNZ_OK.
*/
extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, return UNZ_OK if no error */
int* method,
int* level,
int raw));
/*
Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
if raw==1
*method will receive method of compression, *level will receive level of
compression
note : you can set level parameter as NULL (if you did not want known level,
but you CANNOT set method parameter as NULL
*/
extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, extern int ZEXPORT unzOpenCurrentFile2(unzFile file, int *method, int *level, int raw);
int* method, /* Same as unzOpenCurrentFile, but open for read raw the file (not uncompress)
int* level, if raw==1 *method will receive method of compression, *level will receive level of compression
int raw,
const char* password));
/*
Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
if raw==1
*method will receive method of compression, *level will receive level of
compression
note : you can set level parameter as NULL (if you did not want known level,
but you CANNOT set method parameter as NULL
*/
NOTE: you can set level parameter as NULL (if you did not want known level,
but you CANNOT set method parameter as NULL */
extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int *method, int *level, int raw, const char *password);
/* /* Same as unzOpenCurrentFile, but takes extra parameter password for encrypted files */
Close the file in zip opened with unzOpenCurrentFile
Return UNZ_CRCERROR if all the file was read but the CRC is not good
*/
extern int ZEXPORT unzReadCurrentFile OF((unzFile file, extern int ZEXPORT unzReadCurrentFile(unzFile file, voidp buf, uint32_t len);
voidp buf, /* Read bytes from the current file (opened by unzOpenCurrentFile)
unsigned len));
/*
Read bytes from the current file (opened by unzOpenCurrentFile)
buf contain buffer where data must be copied buf contain buffer where data must be copied
len the size of buf. len the size of buf.
return the number of byte copied if somes bytes are copied return the number of byte copied if somes bytes are copied
return 0 if the end of file was reached return 0 if the end of file was reached
return <0 with error code if there is an error return <0 with error code if there is an error (UNZ_ERRNO for IO error, or zLib error for uncompress error) */
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
*/
extern z_off_t ZEXPORT unztell OF((unzFile file)); extern int ZEXPORT unzGetCurrentFileInfo(unzFile file, unz_file_info *pfile_info, char *filename,
/* uint16_t filename_size, void *extrafield, uint16_t extrafield_size, char *comment, uint16_t comment_size);
Give the current position in uncompressed data extern int ZEXPORT unzGetCurrentFileInfo64(unzFile file, unz_file_info64 *pfile_info, char *filename,
*/ uint16_t filename_size, void *extrafield, uint16_t extrafield_size, char *comment, uint16_t comment_size);
/* Get Info about the current file
extern int ZEXPORT unzeof OF((unzFile file)); pfile_info if != NULL, the *pfile_info structure will contain somes info about the current file
/* filename if != NULL, the file name string will be copied in filename
return 1 if the end of file was reached, 0 elsewhere filename_size is the size of the filename buffer
*/ extrafield if != NULL, the extra field information from the central header will be copied in to
extrafield_size is the size of the extraField buffer
comment if != NULL, the comment string of the file will be copied in to
comment_size is the size of the comment buffer */
extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, extern int ZEXPORT unzGetLocalExtrafield(unzFile file, voidp buf, uint32_t len);
voidp buf, /* Read extra field from the current file (opened by unzOpenCurrentFile)
unsigned len));
/*
Read extra field from the current file (opened by unzOpenCurrentFile)
This is the local-header version of the extra field (sometimes, there is This is the local-header version of the extra field (sometimes, there is
more info in the local-header version than in the central-header) more info in the local-header version than in the central-header)
if buf == NULL, it return the size of the local extra field if buf == NULL, it return the size of the local extra field
if buf != NULL, len is the size of the buffer, the extra header is copied in buf.
if buf!=NULL, len is the size of the buffer, the extra header is copied in return number of bytes copied in buf, or (if <0) the error code */
buf.
the return value is the number of bytes copied in buf, or (if <0) extern int ZEXPORT unzCloseCurrentFile(unzFile file);
the error code /* Close the file in zip opened with unzOpenCurrentFile
*/
return UNZ_CRCERROR if all the file was read but the CRC is not good */
/***************************************************************************/ /***************************************************************************/
/* Browse the directory of the zipfile */
typedef int (*unzFileNameComparer)(unzFile file, const char *filename1, const char *filename2);
typedef int (*unzIteratorFunction)(unzFile file);
typedef int (*unzIteratorFunction2)(unzFile file, unz_file_info64 *pfile_info, char *filename,
uint16_t filename_size, void *extrafield, uint16_t extrafield_size, char *comment, uint16_t comment_size);
extern int ZEXPORT unzGoToFirstFile(unzFile file);
/* Set the current file of the zipfile to the first file.
return UNZ_OK if no error */
extern int ZEXPORT unzGoToFirstFile2(unzFile file, unz_file_info64 *pfile_info, char *filename,
uint16_t filename_size, void *extrafield, uint16_t extrafield_size, char *comment, uint16_t comment_size);
/* Set the current file of the zipfile to the first file and retrieves the current info on success.
Not as seek intensive as unzGoToFirstFile + unzGetCurrentFileInfo.
return UNZ_OK if no error */
extern int ZEXPORT unzGoToNextFile(unzFile file);
/* Set the current file of the zipfile to the next file.
return UNZ_OK if no error
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest */
extern int ZEXPORT unzGoToNextFile2(unzFile file, unz_file_info64 *pfile_info, char *filename,
uint16_t filename_size, void *extrafield, uint16_t extrafield_size, char *comment, uint16_t comment_size);
/* Set the current file of the zipfile to the next file and retrieves the current
info on success. Does less seeking around than unzGotoNextFile + unzGetCurrentFileInfo.
return UNZ_OK if no error
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest */
extern int ZEXPORT unzLocateFile(unzFile file, const char *filename, unzFileNameComparer filename_compare_func);
/* Try locate the file szFileName in the zipfile. For custom filename comparison pass in comparison function.
return UNZ_OK if the file is found (it becomes the current file)
return UNZ_END_OF_LIST_OF_FILE if the file is not found */
/***************************************************************************/
/* Raw access to zip file */
typedef struct unz_file_pos_s
{
uint32_t pos_in_zip_directory; /* offset in zip file directory */
uint32_t num_of_file; /* # of file */
} unz_file_pos;
extern int ZEXPORT unzGetFilePos(unzFile file, unz_file_pos *file_pos);
extern int ZEXPORT unzGoToFilePos(unzFile file, unz_file_pos *file_pos);
typedef struct unz64_file_pos_s
{
uint64_t pos_in_zip_directory; /* offset in zip file directory */
uint64_t num_of_file; /* # of file */
} unz64_file_pos;
extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos *file_pos);
extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos *file_pos);
extern int32_t ZEXPORT unzGetOffset(unzFile file);
extern int64_t ZEXPORT unzGetOffset64(unzFile file);
/* Get the current file offset */ /* Get the current file offset */
extern uLong ZEXPORT unzGetOffset (unzFile file);
extern int ZEXPORT unzSetOffset(unzFile file, uint32_t pos);
extern int ZEXPORT unzSetOffset64(unzFile file, uint64_t pos);
/* Set the current file offset */ /* Set the current file offset */
extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
extern int32_t ZEXPORT unzTell(unzFile file);
extern int64_t ZEXPORT unzTell64(unzFile file);
/* return current position in uncompressed data */
extern int ZEXPORT unzSeek(unzFile file, uint32_t offset, int origin);
extern int ZEXPORT unzSeek64(unzFile file, uint64_t offset, int origin);
/* Seek within the uncompressed data if compression method is storage */
extern int ZEXPORT unzEndOfFile(unzFile file);
/* return 1 if the end of file was reached, 0 elsewhere */
/***************************************************************************/
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* _unz_H */ #endif /* _UNZ_H */

View File

@ -254,25 +254,16 @@ bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationT
} }
} }
bool continuationFound( false );
size_t i = 0; size_t i = 0;
for( ;; ) { for( ;; ) {
if ( continuationToken == m_cache[ m_cachePos ] ) { if ( continuationToken == m_cache[ m_cachePos ] && IsLineEnd( m_cache[ m_cachePos + 1 ] ) ) {
continuationFound = true;
++m_cachePos; ++m_cachePos;
}
if ( IsLineEnd( m_cache[ m_cachePos ] ) ) {
if ( !continuationFound ) {
// the end of the data line
break;
} else {
// skip line end
while ( m_cache[ m_cachePos ] != '\n' ) { while ( m_cache[ m_cachePos ] != '\n' ) {
++m_cachePos; ++m_cachePos;
} }
++m_cachePos; ++m_cachePos;
continuationFound = false; } else if ( IsLineEnd ( m_cache[ m_cachePos ] ) ) {
} break;
} }
buffer[ i ] = m_cache[ m_cachePos ]; buffer[ i ] = m_cache[ m_cachePos ];

View File

@ -121,7 +121,6 @@ public:
return false; return false;
} }
bool result = false;
const size_t len = stream->FileSize(); const size_t len = stream->FileSize();
mData.resize(len + 1); mData.resize(len + 1);
memset(&mData[0], '\0', len + 1); memset(&mData[0], '\0', len + 1);
@ -130,11 +129,11 @@ public:
mDoc = new pugi::xml_document(); mDoc = new pugi::xml_document();
pugi::xml_parse_result parse_result = mDoc->load_string(&mData[0], pugi::parse_full); pugi::xml_parse_result parse_result = mDoc->load_string(&mData[0], pugi::parse_full);
if (parse_result.status == pugi::status_ok) { if (parse_result.status == pugi::status_ok) {
return true;
} else {
ASSIMP_LOG_DEBUG("Error while parse xml."); ASSIMP_LOG_DEBUG("Error while parse xml.");
result = true; return false;
} }
return result;
} }
pugi::xml_document *getDocument() const { pugi::xml_document *getDocument() const {

View File

@ -60,6 +60,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS "$mat.gltf.pbrSpecularGlossiness", 0, 0 #define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS "$mat.gltf.pbrSpecularGlossiness", 0, 0
#define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR "$mat.gltf.pbrMetallicRoughness.glossinessFactor", 0, 0 #define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR "$mat.gltf.pbrMetallicRoughness.glossinessFactor", 0, 0
#define AI_MATKEY_GLTF_UNLIT "$mat.gltf.unlit", 0, 0 #define AI_MATKEY_GLTF_UNLIT "$mat.gltf.unlit", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_SHEEN "$mat.gltf.materialSheen", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_FACTOR "$mat.gltf.materialSheen.sheenColorFactor", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_FACTOR "$mat.gltf.materialSheen.sheenRoughnessFactor", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_TEXTURE aiTextureType_UNKNOWN, 1
#define AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_TEXTURE aiTextureType_UNKNOWN, 2
#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT "$mat.gltf.materialClearcoat", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_FACTOR "$mat.gltf.materialClearcoat.clearcoatFactor", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_FACTOR "$mat.gltf.materialClearcoat.clearcoatRoughnessFactor", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_TEXTURE aiTextureType_UNKNOWN, 3
#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_TEXTURE aiTextureType_UNKNOWN, 4
#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_NORMAL_TEXTURE aiTextureType_NORMALS, 1
#define AI_MATKEY_GLTF_MATERIAL_TRANSMISSION "$mat.gltf.materialTransmission", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_FACTOR "$mat.gltf.materialTransmission.transmissionFactor", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_TEXTURE aiTextureType_UNKNOWN, 5
#define _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE "$tex.file.texCoord" #define _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE "$tex.file.texCoord"
#define _AI_MATKEY_GLTF_MAPPINGNAME_BASE "$tex.mappingname" #define _AI_MATKEY_GLTF_MAPPINGNAME_BASE "$tex.mappingname"

View File

@ -57,6 +57,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
template <typename TReal> class aiVector3t; template <typename TReal> class aiVector3t;
template <typename TReal> class aiMatrix3x3t; template <typename TReal> class aiMatrix3x3t;
template <typename TReal> class aiMatrix4x4t;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Represents a quaternion in a 4D vector. */ /** Represents a quaternion in a 4D vector. */
@ -88,6 +89,9 @@ public:
bool operator== (const aiQuaterniont& o) const; bool operator== (const aiQuaterniont& o) const;
bool operator!= (const aiQuaterniont& o) const; bool operator!= (const aiQuaterniont& o) const;
// transform vector by matrix
aiQuaterniont& operator *= (const aiMatrix4x4t<TReal>& mat);
bool Equal(const aiQuaterniont& o, TReal epsilon = 1e-6) const; bool Equal(const aiQuaterniont& o, TReal epsilon = 1e-6) const;
public: public:

View File

@ -57,6 +57,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cmath> #include <cmath>
// ------------------------------------------------------------------------------------------------
/** Transformation of a quaternion by a 4x4 matrix */
template <typename TReal>
AI_FORCE_INLINE
aiQuaterniont<TReal> operator * (const aiMatrix4x4t<TReal>& pMatrix, const aiQuaterniont<TReal>& pQuaternion) {
aiQuaterniont<TReal> res;
res.x = pMatrix.a1 * pQuaternion.x + pMatrix.a2 * pQuaternion.y + pMatrix.a3 * pQuaternion.z + pMatrix.a4 * pQuaternion.w;
res.y = pMatrix.b1 * pQuaternion.x + pMatrix.b2 * pQuaternion.y + pMatrix.b3 * pQuaternion.z + pMatrix.b4 * pQuaternion.w;
res.z = pMatrix.c1 * pQuaternion.x + pMatrix.c2 * pQuaternion.y + pMatrix.c3 * pQuaternion.z + pMatrix.c4 * pQuaternion.w;
res.w = pMatrix.d1 * pQuaternion.x + pMatrix.d2 * pQuaternion.y + pMatrix.d3 * pQuaternion.z + pMatrix.d4 * pQuaternion.w;
return res;
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
template<typename TReal> template<typename TReal>
bool aiQuaterniont<TReal>::operator== (const aiQuaterniont& o) const bool aiQuaterniont<TReal>::operator== (const aiQuaterniont& o) const
@ -71,6 +83,14 @@ bool aiQuaterniont<TReal>::operator!= (const aiQuaterniont& o) const
return !(*this == o); return !(*this == o);
} }
// ------------------------------------------------------------------------------------------------
template <typename TReal>
AI_FORCE_INLINE
aiQuaterniont<TReal>& aiQuaterniont<TReal>::operator *= (const aiMatrix4x4t<TReal>& mat){
return (*this = mat * (*this));
}
// ------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
template<typename TReal> template<typename TReal>
inline bool aiQuaterniont<TReal>::Equal(const aiQuaterniont& o, TReal epsilon) const { inline bool aiQuaterniont<TReal>::Equal(const aiQuaterniont& o, TReal epsilon) const {