Merge remote-tracking branch 'upstream/master' into fbxBlendshapes
commit
64da2a4315
|
@ -1,2 +1 @@
|
||||||
patreon: assimp
|
|
||||||
open_collective: assimp
|
open_collective: assimp
|
||||||
|
|
|
@ -116,3 +116,6 @@ tools/assimp_qt_viewer/moc_glview.cpp_parameters
|
||||||
tools/assimp_qt_viewer/moc_mainwindow.cpp
|
tools/assimp_qt_viewer/moc_mainwindow.cpp
|
||||||
tools/assimp_qt_viewer/moc_mainwindow.cpp_parameters
|
tools/assimp_qt_viewer/moc_mainwindow.cpp_parameters
|
||||||
tools/assimp_qt_viewer/ui_mainwindow.h
|
tools/assimp_qt_viewer/ui_mainwindow.h
|
||||||
|
|
||||||
|
#Generated directory
|
||||||
|
generated/*
|
|
@ -454,7 +454,7 @@ IF(ASSIMP_HUNTER_ENABLED)
|
||||||
ELSE()
|
ELSE()
|
||||||
# If the zlib is already found outside, add an export in case assimpTargets can't find it.
|
# If the zlib is already found outside, add an export in case assimpTargets can't find it.
|
||||||
IF( ZLIB_FOUND )
|
IF( ZLIB_FOUND )
|
||||||
INSTALL( TARGETS zlib
|
INSTALL( TARGETS zlib zlibstatic
|
||||||
EXPORT "${TARGETS_EXPORT_NAME}")
|
EXPORT "${TARGETS_EXPORT_NAME}")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
|
37
INSTALL
37
INSTALL
|
@ -8,43 +8,10 @@ Getting the documentation
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
A regularly-updated copy is available at
|
A regularly-updated copy is available at
|
||||||
http://assimp.sourceforge.net/lib_html/index.html
|
https://assimp-docs.readthedocs.io/en/latest/
|
||||||
|
|
||||||
A CHM file is included in the SVN repos: ./doc/AssimpDoc_Html/AssimpDoc.chm.
|
|
||||||
To build the doxygen documentation on your own, follow these steps:
|
|
||||||
|
|
||||||
a) download & install latest doxygen
|
|
||||||
b) make sure doxygen is in the executable search path
|
|
||||||
c) navigate to ./doc
|
|
||||||
d) and run 'doxygen'
|
|
||||||
|
|
||||||
Open the generated HTML (AssimpDoc_Html/index.html) in the browser of your choice.
|
|
||||||
Windows only: To generate the CHM doc, install 'Microsoft HTML Workshop'
|
|
||||||
and configure the path to it in the DOXYFILE first.
|
|
||||||
|
|
||||||
------------------------------
|
------------------------------
|
||||||
Building Assimp
|
Building Assimp
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
More detailed build instructions can be found in the documentation,
|
Just check the build-instaructions which you can find here: https://github.com/assimp/assimp/blob/master/Build.md
|
||||||
this section is just for the inpatient among you.
|
|
||||||
|
|
||||||
CMake is the preferred build system for Assimp. The minimum required version
|
|
||||||
is 2.6. If you don't have it yet, downloads for CMake can be found on
|
|
||||||
http://www.cmake.org/.
|
|
||||||
|
|
||||||
For Unix:
|
|
||||||
|
|
||||||
1. mkdir build && cd build
|
|
||||||
2. cmake .. -G 'Unix Makefiles'
|
|
||||||
3. make -j4
|
|
||||||
|
|
||||||
For Windows:
|
|
||||||
1. Open a command prompt
|
|
||||||
2. mkdir build
|
|
||||||
3. cd build
|
|
||||||
4. cmake ..
|
|
||||||
5. cmake --build .
|
|
||||||
|
|
||||||
For iOS:
|
|
||||||
Just check the following project, which deploys a compiler toolchain for different iOS-versions: https://github.com/assimp/assimp/tree/master/port/iOS
|
|
||||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
Copyright (c) 2006-2021, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
|
10
Readme.md
10
Readme.md
|
@ -8,10 +8,10 @@ A library to import and export various 3d-model-formats including scene-post-pro
|
||||||
<img alt="Coverity Scan Build Status"
|
<img alt="Coverity Scan Build Status"
|
||||||
src="https://scan.coverity.com/projects/5607/badge.svg"/>
|
src="https://scan.coverity.com/projects/5607/badge.svg"/>
|
||||||
</a>
|
</a>
|
||||||
|
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/9973693b7bdd4543b07084d5d9cf4745)](https://www.codacy.com/gh/assimp/assimp/dashboard?utm_source=github.com&utm_medium=referral&utm_content=assimp/assimp&utm_campaign=Badge_Grade)
|
||||||
[![Coverage Status](https://coveralls.io/repos/github/assimp/assimp/badge.svg?branch=master)](https://coveralls.io/github/assimp/assimp?branch=master)
|
[![Coverage Status](https://coveralls.io/repos/github/assimp/assimp/badge.svg?branch=master)](https://coveralls.io/github/assimp/assimp?branch=master)
|
||||||
[![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue")
|
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue")
|
||||||
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/5be56faac64f46fc941ac890fb4febef)](https://www.codacy.com/app/kimkulling/assimp?utm_source=github.com&utm_medium=referral&utm_content=assimp/assimp&utm_campaign=Badge_Grade)
|
|
||||||
[![Total alerts](https://img.shields.io/lgtm/alerts/g/assimp/assimp.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/assimp/assimp/alerts/)
|
[![Total alerts](https://img.shields.io/lgtm/alerts/g/assimp/assimp.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/assimp/assimp/alerts/)
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file.
|
||||||
### Ports ###
|
### Ports ###
|
||||||
* [Android](port/AndroidJNI/README.md)
|
* [Android](port/AndroidJNI/README.md)
|
||||||
* [Python](port/PyAssimp/README.md)
|
* [Python](port/PyAssimp/README.md)
|
||||||
* [.NET](https://github.com/assimp/assimp-net)
|
* [.NET](https://bitbucket.org/Starnick/assimpnet/src/master/)
|
||||||
* [Pascal](port/AssimpPascal/Readme.md)
|
* [Pascal](port/AssimpPascal/Readme.md)
|
||||||
* [Javascript (Alpha)](https://github.com/makc/assimp2json)
|
* [Javascript (Alpha)](https://github.com/makc/assimp2json)
|
||||||
* [Unity 3d Plugin](https://www.assetstore.unity3d.com/en/#!/content/91777)
|
* [Unity 3d Plugin](https://www.assetstore.unity3d.com/en/#!/content/91777)
|
||||||
|
@ -76,9 +76,6 @@ For more information, visit [our website](http://assimp.org/). Or check out the
|
||||||
|
|
||||||
If the docs don't solve your problem, ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest). If you think you found a bug, please open an issue on Github.
|
If the docs don't solve your problem, ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest). If you think you found a bug, please open an issue on Github.
|
||||||
|
|
||||||
For development discussions, there is also a (very low-volume) mailing list, _assimp-discussions_
|
|
||||||
[(subscribe here)]( https://lists.sourceforge.net/lists/listinfo/assimp-discussions)
|
|
||||||
|
|
||||||
Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
|
Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
|
||||||
|
|
||||||
And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
|
And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
|
||||||
|
@ -103,9 +100,6 @@ Become a financial contributor and help us sustain our community. [[Contribute](
|
||||||
|
|
||||||
<a href="https://opencollective.com/assimp"><img src="https://opencollective.com/assimp/individuals.svg?width=890"></a>
|
<a href="https://opencollective.com/assimp"><img src="https://opencollective.com/assimp/individuals.svg?width=890"></a>
|
||||||
|
|
||||||
Monthly donations via Patreon:
|
|
||||||
<br>[![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/assimp)
|
|
||||||
|
|
||||||
|
|
||||||
#### Organizations
|
#### Organizations
|
||||||
|
|
||||||
|
|
|
@ -156,7 +156,7 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
|
||||||
mRootStream = mZipArchive->Open(rootFile.c_str());
|
mRootStream = mZipArchive->Open(rootFile.c_str());
|
||||||
ai_assert(mRootStream != nullptr);
|
ai_assert(mRootStream != nullptr);
|
||||||
if (nullptr == mRootStream) {
|
if (nullptr == mRootStream) {
|
||||||
throw DeadlyExportError("Cannot open root-file in archive : " + rootFile);
|
throw DeadlyImportError("Cannot open root-file in archive : " + rootFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE) {
|
} else if (file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE) {
|
||||||
|
|
|
@ -39,16 +39,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// \file AMFImporter.cpp
|
|
||||||
/// \brief AMF-format files importer for Assimp: main algorithm implementation.
|
|
||||||
/// \date 2016
|
|
||||||
/// \author smal.root@gmail.com
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
|
||||||
|
|
||||||
// Header files, Assimp.
|
// Header files, Assimp.
|
||||||
#include "AMFImporter.hpp"
|
#include "AMFImporter.hpp"
|
||||||
#include "AMFImporter_Macro.hpp"
|
|
||||||
|
|
||||||
#include <assimp/DefaultIOSystem.h>
|
#include <assimp/DefaultIOSystem.h>
|
||||||
#include <assimp/fast_atof.h>
|
#include <assimp/fast_atof.h>
|
||||||
|
@ -307,14 +301,14 @@ void AMFImporter::ParseNode_Root() {
|
||||||
throw DeadlyImportError("Root node \"amf\" not found.");
|
throw DeadlyImportError("Root node \"amf\" not found.");
|
||||||
}
|
}
|
||||||
XmlNode node = *root;
|
XmlNode node = *root;
|
||||||
mUnit = ai_str_tolower(std::string(node.attribute("unit").as_string()));
|
mUnit = ai_tolower(std::string(node.attribute("unit").as_string()));
|
||||||
|
|
||||||
mVersion = node.attribute("version").as_string();
|
mVersion = node.attribute("version").as_string();
|
||||||
|
|
||||||
// Read attributes for node <amf>.
|
// Read attributes for node <amf>.
|
||||||
// Check attributes
|
// Check attributes
|
||||||
if (!mUnit.empty()) {
|
if (!mUnit.empty()) {
|
||||||
if ((mUnit != "inch") && (mUnit != "millimeter") && (mUnit != "meter") && (mUnit != "feet") && (mUnit != "micron")) {
|
if ((mUnit != "inch") && (mUnit != "millimeters") && (mUnit != "millimeter") && (mUnit != "meter") && (mUnit != "feet") && (mUnit != "micron")) {
|
||||||
Throw_IncorrectAttrValue("unit", mUnit);
|
Throw_IncorrectAttrValue("unit", mUnit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -409,20 +403,20 @@ void AMFImporter::ParseNode_Instance(XmlNode &node) {
|
||||||
|
|
||||||
if (!node.empty()) {
|
if (!node.empty()) {
|
||||||
ParseHelper_Node_Enter(ne);
|
ParseHelper_Node_Enter(ne);
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (auto ¤tNode : node.children()) {
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == "deltax") {
|
if (currentName == "deltax") {
|
||||||
als.Delta.x = (ai_real)std::atof(currentNode.value());
|
XmlParser::getValueAsFloat(currentNode, als.Delta.x);
|
||||||
} else if (currentName == "deltay") {
|
} else if (currentName == "deltay") {
|
||||||
als.Delta.y = (ai_real)std::atof(currentNode.value());
|
XmlParser::getValueAsFloat(currentNode, als.Delta.y);
|
||||||
} else if (currentName == "deltaz") {
|
} else if (currentName == "deltaz") {
|
||||||
als.Delta.z = (ai_real)std::atof(currentNode.value());
|
XmlParser::getValueAsFloat(currentNode, als.Delta.z);
|
||||||
} else if (currentName == "rx") {
|
} else if (currentName == "rx") {
|
||||||
als.Delta.x = (ai_real)std::atof(currentNode.value());
|
XmlParser::getValueAsFloat(currentNode, als.Delta.x);
|
||||||
} else if (currentName == "ry") {
|
} else if (currentName == "ry") {
|
||||||
als.Delta.y = (ai_real)std::atof(currentNode.value());
|
XmlParser::getValueAsFloat(currentNode, als.Delta.y);
|
||||||
} else if (currentName == "rz") {
|
} else if (currentName == "rz") {
|
||||||
als.Delta.z = (ai_real)std::atof(currentNode.value());
|
XmlParser::getValueAsFloat(currentNode, als.Delta.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ParseHelper_Node_Exit();
|
ParseHelper_Node_Exit();
|
||||||
|
@ -458,7 +452,7 @@ void AMFImporter::ParseNode_Object(XmlNode &node) {
|
||||||
// Check for child nodes
|
// Check for child nodes
|
||||||
if (!node.empty()) {
|
if (!node.empty()) {
|
||||||
ParseHelper_Node_Enter(ne);
|
ParseHelper_Node_Enter(ne);
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (auto ¤tNode : node.children()) {
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == "color") {
|
if (currentName == "color") {
|
||||||
ParseNode_Color(currentNode);
|
ParseNode_Color(currentNode);
|
||||||
|
|
|
@ -39,16 +39,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// \file AMFImporter_Geometry.cpp
|
|
||||||
/// \brief Parsing data from geometry nodes.
|
|
||||||
/// \date 2016
|
|
||||||
/// \author smal.root@gmail.com
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
|
||||||
|
|
||||||
#include "AMFImporter.hpp"
|
#include "AMFImporter.hpp"
|
||||||
#include "AMFImporter_Macro.hpp"
|
|
||||||
|
|
||||||
#include <assimp/ParsingUtils.h>
|
#include <assimp/ParsingUtils.h>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
@ -103,18 +96,18 @@ void AMFImporter::ParseNode_Vertices(XmlNode &node) {
|
||||||
// create new mesh object.
|
// create new mesh object.
|
||||||
ne = new AMFVertices(mNodeElement_Cur);
|
ne = new AMFVertices(mNodeElement_Cur);
|
||||||
// Check for child nodes
|
// Check for child nodes
|
||||||
pugi::xml_node vertexNode = node.child("vertex");
|
if (node.empty()) {
|
||||||
if (!vertexNode.empty()) {
|
|
||||||
ParseHelper_Node_Enter(ne);
|
|
||||||
|
|
||||||
ParseNode_Vertex(vertexNode);
|
|
||||||
|
|
||||||
ParseHelper_Node_Exit();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
|
mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
|
||||||
} // if(!mReader->isEmptyElement()) else
|
return;
|
||||||
|
}
|
||||||
|
ParseHelper_Node_Enter(ne);
|
||||||
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
|
const std::string ¤tName = currentNode.name();
|
||||||
|
if (currentName == "vertex") {
|
||||||
|
ParseNode_Vertex(currentNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ParseHelper_Node_Exit();
|
||||||
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
|
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,27 +159,25 @@ void AMFImporter::ParseNode_Vertex(XmlNode &node) {
|
||||||
// X, Y, or Z coordinate, respectively, of a vertex position in space.
|
// X, Y, or Z coordinate, respectively, of a vertex position in space.
|
||||||
void AMFImporter::ParseNode_Coordinates(XmlNode &node) {
|
void AMFImporter::ParseNode_Coordinates(XmlNode &node) {
|
||||||
AMFNodeElementBase *ne = nullptr;
|
AMFNodeElementBase *ne = nullptr;
|
||||||
|
|
||||||
// create new color object.
|
|
||||||
ne = new AMFCoordinates(mNodeElement_Cur);
|
|
||||||
|
|
||||||
AMFCoordinates &als = *((AMFCoordinates *)ne); // alias for convenience
|
|
||||||
if (!node.empty()) {
|
if (!node.empty()) {
|
||||||
|
ne = new AMFCoordinates(mNodeElement_Cur);
|
||||||
ParseHelper_Node_Enter(ne);
|
ParseHelper_Node_Enter(ne);
|
||||||
for (XmlNode ¤tNode : node.children()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string ¤tName = currentNode.name();
|
// create new color object.
|
||||||
if (currentName == "X") {
|
AMFCoordinates &als = *((AMFCoordinates *)ne); // alias for convenience
|
||||||
|
const std::string ¤tName = ai_tolower(currentNode.name());
|
||||||
|
if (currentName == "x") {
|
||||||
XmlParser::getValueAsFloat(currentNode, als.Coordinate.x);
|
XmlParser::getValueAsFloat(currentNode, als.Coordinate.x);
|
||||||
} else if (currentName == "Y") {
|
} else if (currentName == "y") {
|
||||||
XmlParser::getValueAsFloat(currentNode, als.Coordinate.y);
|
XmlParser::getValueAsFloat(currentNode, als.Coordinate.y);
|
||||||
} else if (currentName == "Z") {
|
} else if (currentName == "z") {
|
||||||
XmlParser::getValueAsFloat(currentNode, als.Coordinate.z);
|
XmlParser::getValueAsFloat(currentNode, als.Coordinate.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseHelper_Node_Exit();
|
ParseHelper_Node_Exit();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
mNodeElement_Cur->Child.push_back(ne);
|
mNodeElement_Cur->Child.push_back(new AMFCoordinates(mNodeElement_Cur));
|
||||||
}
|
}
|
||||||
|
|
||||||
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
|
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
|
||||||
|
@ -216,7 +207,7 @@ void AMFImporter::ParseNode_Volume(XmlNode &node) {
|
||||||
bool col_read = false;
|
bool col_read = false;
|
||||||
if (!node.empty()) {
|
if (!node.empty()) {
|
||||||
ParseHelper_Node_Enter(ne);
|
ParseHelper_Node_Enter(ne);
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (auto ¤tNode : node.children()) {
|
||||||
const std::string currentName = currentNode.name();
|
const std::string currentName = currentNode.name();
|
||||||
if (currentName == "color") {
|
if (currentName == "color") {
|
||||||
if (col_read) Throw_MoreThanOnceDefined(currentName, "color", "Only one color can be defined for <volume>.");
|
if (col_read) Throw_MoreThanOnceDefined(currentName, "color", "Only one color can be defined for <volume>.");
|
||||||
|
@ -258,7 +249,8 @@ void AMFImporter::ParseNode_Triangle(XmlNode &node) {
|
||||||
bool col_read = false;
|
bool col_read = false;
|
||||||
if (!node.empty()) {
|
if (!node.empty()) {
|
||||||
ParseHelper_Node_Enter(ne);
|
ParseHelper_Node_Enter(ne);
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
std::string v;
|
||||||
|
for (auto ¤tNode : node.children()) {
|
||||||
const std::string currentName = currentNode.name();
|
const std::string currentName = currentNode.name();
|
||||||
if (currentName == "color") {
|
if (currentName == "color") {
|
||||||
if (col_read) Throw_MoreThanOnceDefined(currentName, "color", "Only one color can be defined for <triangle>.");
|
if (col_read) Throw_MoreThanOnceDefined(currentName, "color", "Only one color can be defined for <triangle>.");
|
||||||
|
@ -269,11 +261,14 @@ void AMFImporter::ParseNode_Triangle(XmlNode &node) {
|
||||||
} else if (currentName == "map") {
|
} else if (currentName == "map") {
|
||||||
ParseNode_TexMap(currentNode, true);
|
ParseNode_TexMap(currentNode, true);
|
||||||
} else if (currentName == "v1") {
|
} else if (currentName == "v1") {
|
||||||
als.V[0] = std::atoi(currentNode.value());
|
XmlParser::getValueAsString(currentNode, v);
|
||||||
|
als.V[0] = std::atoi(v.c_str());
|
||||||
} else if (currentName == "v2") {
|
} else if (currentName == "v2") {
|
||||||
als.V[1] = std::atoi(currentNode.value());
|
XmlParser::getValueAsString(currentNode, v);
|
||||||
|
als.V[1] = std::atoi(v.c_str());
|
||||||
} else if (currentName == "v3") {
|
} else if (currentName == "v3") {
|
||||||
als.V[2] = std::atoi(currentNode.value());
|
XmlParser::getValueAsString(currentNode, v);
|
||||||
|
als.V[2] = std::atoi(v.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ParseHelper_Node_Exit();
|
ParseHelper_Node_Exit();
|
||||||
|
|
|
@ -1,164 +0,0 @@
|
||||||
/*
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
Open Asset Import Library (assimp)
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2006-2021, assimp team
|
|
||||||
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
|
||||||
with or without modification, are permitted provided that the following
|
|
||||||
conditions are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above
|
|
||||||
copyright notice, this list of conditions and the
|
|
||||||
following disclaimer.
|
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the
|
|
||||||
following disclaimer in the documentation and/or other
|
|
||||||
materials provided with the distribution.
|
|
||||||
|
|
||||||
* Neither the name of the assimp team, nor the names of its
|
|
||||||
contributors may be used to endorse or promote products
|
|
||||||
derived from this software without specific prior
|
|
||||||
written permission of the assimp team.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/// \file AMFImporter_Macro.hpp
|
|
||||||
/// \brief Useful macrodefines.
|
|
||||||
/// \date 2016
|
|
||||||
/// \author smal.root@gmail.com
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef AMFIMPORTER_MACRO_HPP_INCLUDED
|
|
||||||
#define AMFIMPORTER_MACRO_HPP_INCLUDED
|
|
||||||
|
|
||||||
/// \def MACRO_ATTRREAD_LOOPBEG
|
|
||||||
/// Begin of loop that read attributes values.
|
|
||||||
#define MACRO_ATTRREAD_LOOPBEG \
|
|
||||||
for(int idx = 0, idx_end = mReader->getAttributeCount(); idx < idx_end; idx++) \
|
|
||||||
{ \
|
|
||||||
std::string an(mReader->getAttributeName(idx));
|
|
||||||
|
|
||||||
/// \def MACRO_ATTRREAD_LOOPEND
|
|
||||||
/// End of loop that read attributes values.
|
|
||||||
#define MACRO_ATTRREAD_LOOPEND \
|
|
||||||
Throw_IncorrectAttr(an); \
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \def MACRO_ATTRREAD_LOOPEND_WSKIP
|
|
||||||
/// End of loop that read attributes values. Difference from \ref MACRO_ATTRREAD_LOOPEND in that: current macro skip unknown attributes, but
|
|
||||||
/// \ref MACRO_ATTRREAD_LOOPEND throw an exception.
|
|
||||||
#define MACRO_ATTRREAD_LOOPEND_WSKIP \
|
|
||||||
continue; \
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \def MACRO_ATTRREAD_CHECK_REF
|
|
||||||
/// Check current attribute name and if it equal to requested then read value. Result write to output variable by reference. If result was read then
|
|
||||||
/// "continue" will called.
|
|
||||||
/// \param [in] pAttrName - attribute name.
|
|
||||||
/// \param [out] pVarName - output variable name.
|
|
||||||
/// \param [in] pFunction - function which read attribute value and write it to pVarName.
|
|
||||||
#define MACRO_ATTRREAD_CHECK_REF(pAttrName, pVarName, pFunction) \
|
|
||||||
if(an == pAttrName) \
|
|
||||||
{ \
|
|
||||||
pFunction(idx, pVarName); \
|
|
||||||
continue; \
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \def MACRO_ATTRREAD_CHECK_RET
|
|
||||||
/// Check current attribute name and if it equal to requested then read value. Result write to output variable using return value of \ref pFunction.
|
|
||||||
/// If result was read then "continue" will called.
|
|
||||||
/// \param [in] pAttrName - attribute name.
|
|
||||||
/// \param [out] pVarName - output variable name.
|
|
||||||
/// \param [in] pFunction - function which read attribute value and write it to pVarName.
|
|
||||||
#define MACRO_ATTRREAD_CHECK_RET(pAttrName, pVarName, pFunction) \
|
|
||||||
if(an == pAttrName) \
|
|
||||||
{ \
|
|
||||||
pVarName = pFunction(idx); \
|
|
||||||
continue; \
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \def MACRO_NODECHECK_LOOPBEGIN(pNodeName)
|
|
||||||
/// Begin of loop of parsing child nodes. Do not add ';' at end.
|
|
||||||
/// \param [in] pNodeName - current node name.
|
|
||||||
#define MACRO_NODECHECK_LOOPBEGIN(pNodeName) \
|
|
||||||
do { \
|
|
||||||
bool close_found = false; \
|
|
||||||
\
|
|
||||||
while(mReader->read()) \
|
|
||||||
{ \
|
|
||||||
if(mReader->getNodeType() == irr::io::EXN_ELEMENT) \
|
|
||||||
{
|
|
||||||
|
|
||||||
/// \def MACRO_NODECHECK_LOOPEND(pNodeName)
|
|
||||||
/// End of loop of parsing child nodes.
|
|
||||||
/// \param [in] pNodeName - current node name.
|
|
||||||
#define MACRO_NODECHECK_LOOPEND(pNodeName) \
|
|
||||||
XML_CheckNode_SkipUnsupported(pNodeName); \
|
|
||||||
}/* if(mReader->getNodeType() == irr::io::EXN_ELEMENT) */ \
|
|
||||||
else if(mReader->getNodeType() == irr::io::EXN_ELEMENT_END) \
|
|
||||||
{ \
|
|
||||||
if(XML_CheckNode_NameEqual(pNodeName)) \
|
|
||||||
{ \
|
|
||||||
close_found = true; \
|
|
||||||
\
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
}/* else if(mReader->getNodeType() == irr::io::EXN_ELEMENT_END) */ \
|
|
||||||
}/* while(mReader->read()) */ \
|
|
||||||
\
|
|
||||||
if(!close_found) Throw_CloseNotFound(pNodeName); \
|
|
||||||
\
|
|
||||||
} while(false)
|
|
||||||
|
|
||||||
/// \def MACRO_NODECHECK_READCOMP_F
|
|
||||||
/// Check current node name and if it equal to requested then read value. Result write to output variable of type "float".
|
|
||||||
/// If result was read then "continue" will called. Also check if node data already read then raise exception.
|
|
||||||
/// \param [in] pNodeName - node name.
|
|
||||||
/// \param [in, out] pReadFlag - read flag.
|
|
||||||
/// \param [out] pVarName - output variable name.
|
|
||||||
#define MACRO_NODECHECK_READCOMP_F(pNodeName, pReadFlag, pVarName) \
|
|
||||||
if(XML_CheckNode_NameEqual(pNodeName)) \
|
|
||||||
{ \
|
|
||||||
/* Check if field already read before. */ \
|
|
||||||
if(pReadFlag) Throw_MoreThanOnceDefined(pNodeName, "Only one component can be defined."); \
|
|
||||||
/* Read color component and assign it to object. */ \
|
|
||||||
pVarName = XML_ReadNode_GetVal_AsFloat(); \
|
|
||||||
pReadFlag = true; \
|
|
||||||
continue; \
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \def MACRO_NODECHECK_READCOMP_U32
|
|
||||||
/// Check current node name and if it equal to requested then read value. Result write to output variable of type "uint32_t".
|
|
||||||
/// If result was read then "continue" will called. Also check if node data already read then raise exception.
|
|
||||||
/// \param [in] pNodeName - node name.
|
|
||||||
/// \param [in, out] pReadFlag - read flag.
|
|
||||||
/// \param [out] pVarName - output variable name.
|
|
||||||
#define MACRO_NODECHECK_READCOMP_U32(pNodeName, pReadFlag, pVarName) \
|
|
||||||
if(XML_CheckNode_NameEqual(pNodeName)) \
|
|
||||||
{ \
|
|
||||||
/* Check if field already read before. */ \
|
|
||||||
if(pReadFlag) Throw_MoreThanOnceDefined(pNodeName, "Only one component can be defined."); \
|
|
||||||
/* Read color component and assign it to object. */ \
|
|
||||||
pVarName = XML_ReadNode_GetVal_AsU32(); \
|
|
||||||
pReadFlag = true; \
|
|
||||||
continue; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // AMFIMPORTER_MACRO_HPP_INCLUDED
|
|
|
@ -65,48 +65,45 @@ namespace Assimp {
|
||||||
// Red, Greed, Blue and Alpha (transparency) component of a color in sRGB space, values ranging from 0 to 1. The
|
// Red, Greed, Blue and Alpha (transparency) component of a color in sRGB space, values ranging from 0 to 1. The
|
||||||
// values can be specified as constants, or as a formula depending on the coordinates.
|
// values can be specified as constants, or as a formula depending on the coordinates.
|
||||||
void AMFImporter::ParseNode_Color(XmlNode &node) {
|
void AMFImporter::ParseNode_Color(XmlNode &node) {
|
||||||
std::string profile = node.attribute("profile").as_string();
|
if (node.empty()) {
|
||||||
|
return;
|
||||||
// create new color object.
|
}
|
||||||
AMFNodeElementBase *ne = new AMFColor(mNodeElement_Cur);
|
|
||||||
AMFColor& als = *((AMFColor*)ne);// alias for convenience
|
|
||||||
|
|
||||||
als.Profile = profile;
|
const std::string &profile = node.attribute("profile").as_string();
|
||||||
if (!node.empty()) {
|
bool read_flag[4] = { false, false, false, false };
|
||||||
ParseHelper_Node_Enter(ne);
|
AMFNodeElementBase *ne = new AMFColor(mNodeElement_Cur);
|
||||||
bool read_flag[4] = { false, false, false, false };
|
AMFColor &als = *((AMFColor *)ne); // alias for convenience
|
||||||
for (pugi::xml_node &child : node.children()) {
|
ParseHelper_Node_Enter(ne);
|
||||||
std::string name = child.name();
|
for (pugi::xml_node &child : node.children()) {
|
||||||
if ( name == "r") {
|
// create new color object.
|
||||||
read_flag[0] = true;
|
als.Profile = profile;
|
||||||
XmlParser::getValueAsFloat(child, als.Color.r);
|
|
||||||
} else if (name == "g") {
|
const std::string &name = child.name();
|
||||||
read_flag[1] = true;
|
if ( name == "r") {
|
||||||
XmlParser::getValueAsFloat(child, als.Color.g);
|
read_flag[0] = true;
|
||||||
} else if (name == "b") {
|
XmlParser::getValueAsFloat(child, als.Color.r);
|
||||||
read_flag[2] = true;
|
} else if (name == "g") {
|
||||||
XmlParser::getValueAsFloat(child, als.Color.b);
|
read_flag[1] = true;
|
||||||
} else if (name == "a") {
|
XmlParser::getValueAsFloat(child, als.Color.g);
|
||||||
read_flag[3] = true;
|
} else if (name == "b") {
|
||||||
XmlParser::getValueAsFloat(child, als.Color.a);
|
read_flag[2] = true;
|
||||||
}
|
XmlParser::getValueAsFloat(child, als.Color.b);
|
||||||
ParseHelper_Node_Exit();
|
} else if (name == "a") {
|
||||||
|
read_flag[3] = true;
|
||||||
|
XmlParser::getValueAsFloat(child, als.Color.a);
|
||||||
}
|
}
|
||||||
// check that all components was defined
|
// check if <a> is absent. Then manually add "a == 1".
|
||||||
if (!(read_flag[0] && read_flag[1] && read_flag[2])) {
|
if (!read_flag[3]) {
|
||||||
throw DeadlyImportError("Not all color components are defined.");
|
als.Color.a = 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// check if <a> is absent. Then manually add "a == 1".
|
als.Composed = false;
|
||||||
if (!read_flag[3]) {
|
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
|
||||||
als.Color.a = 1;
|
ParseHelper_Node_Exit();
|
||||||
}
|
// check that all components was defined
|
||||||
} else {
|
if (!(read_flag[0] && read_flag[1] && read_flag[2])) {
|
||||||
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
throw DeadlyImportError("Not all color components are defined.");
|
||||||
}
|
}
|
||||||
|
|
||||||
als.Composed = false;
|
|
||||||
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// <material
|
// <material
|
||||||
|
@ -158,11 +155,11 @@ void AMFImporter::ParseNode_Material(XmlNode &node) {
|
||||||
// Multi elements - Yes.
|
// Multi elements - Yes.
|
||||||
// Parent element - <amf>.
|
// Parent element - <amf>.
|
||||||
void AMFImporter::ParseNode_Texture(XmlNode &node) {
|
void AMFImporter::ParseNode_Texture(XmlNode &node) {
|
||||||
std::string id = node.attribute("id").as_string();
|
const std::string id = node.attribute("id").as_string();
|
||||||
uint32_t width = node.attribute("width").as_uint();
|
const uint32_t width = node.attribute("width").as_uint();
|
||||||
uint32_t height = node.attribute("height").as_uint();
|
const uint32_t height = node.attribute("height").as_uint();
|
||||||
uint32_t depth = node.attribute("depth").as_uint();
|
uint32_t depth = node.attribute("depth").as_uint();
|
||||||
std::string type = node.attribute("type").as_string();
|
const std::string type = node.attribute("type").as_string();
|
||||||
bool tiled = node.attribute("tiled").as_bool();
|
bool tiled = node.attribute("tiled").as_bool();
|
||||||
|
|
||||||
if (node.empty()) {
|
if (node.empty()) {
|
||||||
|
@ -174,22 +171,20 @@ void AMFImporter::ParseNode_Texture(XmlNode &node) {
|
||||||
|
|
||||||
AMFTexture& als = *((AMFTexture*)ne);// alias for convenience
|
AMFTexture& als = *((AMFTexture*)ne);// alias for convenience
|
||||||
|
|
||||||
std::string enc64_data = node.value();
|
std::string enc64_data;
|
||||||
// Check for child nodes
|
XmlParser::getValueAsString(node, enc64_data);
|
||||||
|
// Check for child nodes
|
||||||
|
|
||||||
// check that all components was defined
|
// check that all components was defined
|
||||||
if (id.empty()) {
|
if (id.empty()) {
|
||||||
throw DeadlyImportError("ID for texture must be defined.");
|
throw DeadlyImportError("ID for texture must be defined.");
|
||||||
}
|
}
|
||||||
if (width < 1) {
|
if (width < 1) {
|
||||||
throw DeadlyImportError("INvalid width for texture.");
|
throw DeadlyImportError("Invalid width for texture.");
|
||||||
}
|
}
|
||||||
if (height < 1) {
|
if (height < 1) {
|
||||||
throw DeadlyImportError("Invalid height for texture.");
|
throw DeadlyImportError("Invalid height for texture.");
|
||||||
}
|
}
|
||||||
if (depth < 1) {
|
|
||||||
throw DeadlyImportError("Invalid depth for texture.");
|
|
||||||
}
|
|
||||||
if (type != "grayscale") {
|
if (type != "grayscale") {
|
||||||
throw DeadlyImportError("Invalid type for texture.");
|
throw DeadlyImportError("Invalid type for texture.");
|
||||||
}
|
}
|
||||||
|
@ -203,7 +198,9 @@ void AMFImporter::ParseNode_Texture(XmlNode &node) {
|
||||||
als.Depth = depth;
|
als.Depth = depth;
|
||||||
als.Tiled = tiled;
|
als.Tiled = tiled;
|
||||||
ParseHelper_Decode_Base64(enc64_data, als.Data);
|
ParseHelper_Decode_Base64(enc64_data, als.Data);
|
||||||
|
if (depth == 0) {
|
||||||
|
depth = (uint32_t)(als.Data.size() / (width * height));
|
||||||
|
}
|
||||||
// check data size
|
// check data size
|
||||||
if ((width * height * depth) != als.Data.size()) {
|
if ((width * height * depth) != als.Data.size()) {
|
||||||
throw DeadlyImportError("Texture has incorrect data size.");
|
throw DeadlyImportError("Texture has incorrect data size.");
|
||||||
|
@ -233,20 +230,18 @@ void AMFImporter::ParseNode_TexMap(XmlNode &node, const bool pUseOldName) {
|
||||||
AMFTexMap &als = *((AMFTexMap *)ne); //
|
AMFTexMap &als = *((AMFTexMap *)ne); //
|
||||||
std::string rtexid, gtexid, btexid, atexid;
|
std::string rtexid, gtexid, btexid, atexid;
|
||||||
if (!node.empty()) {
|
if (!node.empty()) {
|
||||||
ParseHelper_Node_Enter(ne);
|
for (pugi::xml_attribute &attr : node.attributes()) {
|
||||||
for (XmlNode ¤tNode : node.children()) {
|
const std::string ¤tAttr = attr.name();
|
||||||
const std::string ¤tName = currentNode.name();
|
if (currentAttr == "rtexid") {
|
||||||
if (currentName == "rtexid") {
|
rtexid = attr.as_string();
|
||||||
XmlParser::getValueAsString(node, rtexid);
|
} else if (currentAttr == "gtexid") {
|
||||||
} else if (currentName == "gtexid") {
|
gtexid = attr.as_string();
|
||||||
XmlParser::getValueAsString(node, gtexid);
|
} else if (currentAttr == "btexid") {
|
||||||
} else if (currentName == "btexid") {
|
btexid = attr.as_string();
|
||||||
XmlParser::getValueAsString(node, btexid);
|
} else if (currentAttr == "atexid") {
|
||||||
} else if (currentName == "atexid") {
|
atexid = attr.as_string();
|
||||||
XmlParser::getValueAsString(node, atexid);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ParseHelper_Node_Exit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create new texture coordinates object, alias for convenience
|
// create new texture coordinates object, alias for convenience
|
||||||
|
@ -256,7 +251,6 @@ void AMFImporter::ParseNode_TexMap(XmlNode &node, const bool pUseOldName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for children nodes
|
// Check for children nodes
|
||||||
//XML_CheckNode_MustHaveChildren();
|
|
||||||
if (node.children().begin() == node.children().end()) {
|
if (node.children().begin() == node.children().end()) {
|
||||||
throw DeadlyImportError("Invalid children definition.");
|
throw DeadlyImportError("Invalid children definition.");
|
||||||
}
|
}
|
||||||
|
@ -264,28 +258,31 @@ void AMFImporter::ParseNode_TexMap(XmlNode &node, const bool pUseOldName) {
|
||||||
bool read_flag[6] = { false, false, false, false, false, false };
|
bool read_flag[6] = { false, false, false, false, false, false };
|
||||||
|
|
||||||
if (!pUseOldName) {
|
if (!pUseOldName) {
|
||||||
for (pugi::xml_attribute &attr : node.attributes()) {
|
ParseHelper_Node_Enter(ne);
|
||||||
const std::string name = attr.name();
|
for ( XmlNode ¤tNode : node.children()) {
|
||||||
|
const std::string &name = currentNode.name();
|
||||||
if (name == "utex1") {
|
if (name == "utex1") {
|
||||||
read_flag[0] = true;
|
read_flag[0] = true;
|
||||||
als.TextureCoordinate[0].x = attr.as_float();
|
XmlParser::getValueAsFloat(node, als.TextureCoordinate[0].x);
|
||||||
} else if (name == "utex2") {
|
} else if (name == "utex2") {
|
||||||
read_flag[1] = true;
|
read_flag[1] = true;
|
||||||
als.TextureCoordinate[1].x = attr.as_float();
|
XmlParser::getValueAsFloat(node, als.TextureCoordinate[1].x);
|
||||||
} else if (name == "utex3") {
|
} else if (name == "utex3") {
|
||||||
read_flag[2] = true;
|
read_flag[2] = true;
|
||||||
als.TextureCoordinate[2].x = attr.as_float();
|
XmlParser::getValueAsFloat(node, als.TextureCoordinate[2].x);
|
||||||
} else if (name == "vtex1") {
|
} else if (name == "vtex1") {
|
||||||
read_flag[3] = true;
|
read_flag[3] = true;
|
||||||
als.TextureCoordinate[0].y = attr.as_float();
|
XmlParser::getValueAsFloat(node, als.TextureCoordinate[0].y);
|
||||||
} else if (name == "vtex2") {
|
} else if (name == "vtex2") {
|
||||||
read_flag[4] = true;
|
read_flag[4] = true;
|
||||||
als.TextureCoordinate[1].y = attr.as_float();
|
XmlParser::getValueAsFloat(node, als.TextureCoordinate[1].y);
|
||||||
} else if (name == "vtex3") {
|
} else if (name == "vtex3") {
|
||||||
read_flag[5] = true;
|
read_flag[5] = true;
|
||||||
als.TextureCoordinate[0].y = attr.as_float();
|
XmlParser::getValueAsFloat(node, als.TextureCoordinate[2].y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ParseHelper_Node_Exit();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
for (pugi::xml_attribute &attr : node.attributes()) {
|
for (pugi::xml_attribute &attr : node.attributes()) {
|
||||||
const std::string name = attr.name();
|
const std::string name = attr.name();
|
||||||
|
|
|
@ -62,12 +62,14 @@ aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*
|
||||||
// Check if stored data are supported.
|
// Check if stored data are supported.
|
||||||
if (!Composition.empty()) {
|
if (!Composition.empty()) {
|
||||||
throw DeadlyImportError("IME. GetColor for composition");
|
throw DeadlyImportError("IME. GetColor for composition");
|
||||||
} else if (Color->Composed) {
|
|
||||||
throw DeadlyImportError("IME. GetColor, composed color");
|
|
||||||
} else {
|
|
||||||
tcol = Color->Color;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Color->Composed) {
|
||||||
|
throw DeadlyImportError("IME. GetColor, composed color");
|
||||||
|
}
|
||||||
|
|
||||||
|
tcol = Color->Color;
|
||||||
|
|
||||||
// Check if default color must be used
|
// Check if default color must be used
|
||||||
if ((tcol.r == 0) && (tcol.g == 0) && (tcol.b == 0) && (tcol.a == 0)) {
|
if ((tcol.r == 0) && (tcol.g == 0) && (tcol.b == 0) && (tcol.a == 0)) {
|
||||||
tcol.r = 0.5f;
|
tcol.r = 0.5f;
|
||||||
|
@ -79,13 +81,13 @@ aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*
|
||||||
return tcol;
|
return tcol;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AMFImporter::PostprocessHelper_CreateMeshDataArray(const AMFMesh &pNodeElement, std::vector<aiVector3D> &pVertexCoordinateArray,
|
void AMFImporter::PostprocessHelper_CreateMeshDataArray(const AMFMesh &nodeElement, std::vector<aiVector3D> &vertexCoordinateArray,
|
||||||
std::vector<AMFColor *> &pVertexColorArray) const {
|
std::vector<AMFColor *> &pVertexColorArray) const {
|
||||||
AMFVertices *vn = nullptr;
|
AMFVertices *vn = nullptr;
|
||||||
size_t col_idx;
|
size_t col_idx;
|
||||||
|
|
||||||
// All data stored in "vertices", search for it.
|
// All data stored in "vertices", search for it.
|
||||||
for (AMFNodeElementBase *ne_child : pNodeElement.Child) {
|
for (AMFNodeElementBase *ne_child : nodeElement.Child) {
|
||||||
if (ne_child->Type == AMFNodeElementBase::ENET_Vertices) {
|
if (ne_child->Type == AMFNodeElementBase::ENET_Vertices) {
|
||||||
vn = (AMFVertices*)ne_child;
|
vn = (AMFVertices*)ne_child;
|
||||||
}
|
}
|
||||||
|
@ -97,7 +99,7 @@ void AMFImporter::PostprocessHelper_CreateMeshDataArray(const AMFMesh &pNodeElem
|
||||||
}
|
}
|
||||||
|
|
||||||
// all coordinates stored as child and we need to reserve space for future push_back's.
|
// all coordinates stored as child and we need to reserve space for future push_back's.
|
||||||
pVertexCoordinateArray.reserve(vn->Child.size());
|
vertexCoordinateArray.reserve(vn->Child.size());
|
||||||
|
|
||||||
// colors count equal vertices count.
|
// colors count equal vertices count.
|
||||||
pVertexColorArray.resize(vn->Child.size());
|
pVertexColorArray.resize(vn->Child.size());
|
||||||
|
@ -112,7 +114,7 @@ void AMFImporter::PostprocessHelper_CreateMeshDataArray(const AMFMesh &pNodeElem
|
||||||
|
|
||||||
for (AMFNodeElementBase *vtx : vn_child->Child) {
|
for (AMFNodeElementBase *vtx : vn_child->Child) {
|
||||||
if (vtx->Type == AMFNodeElementBase::ENET_Coordinates) {
|
if (vtx->Type == AMFNodeElementBase::ENET_Coordinates) {
|
||||||
pVertexCoordinateArray.push_back(((AMFCoordinates *)vtx)->Coordinate);
|
vertexCoordinateArray.push_back(((AMFCoordinates *)vtx)->Coordinate);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,16 +62,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifdef ASSIMP_FBX_USE_UNORDERED_MULTIMAP
|
#ifdef ASSIMP_FBX_USE_UNORDERED_MULTIMAP
|
||||||
# include <unordered_map>
|
# include <unordered_map>
|
||||||
# include <unordered_set>
|
# include <unordered_set>
|
||||||
# if _MSC_VER > 1600
|
# if defined(_MSC_VER) && _MSC_VER <= 1600
|
||||||
# define fbx_unordered_map unordered_map
|
|
||||||
# define fbx_unordered_multimap unordered_multimap
|
|
||||||
# define fbx_unordered_set unordered_set
|
|
||||||
# define fbx_unordered_multiset unordered_multiset
|
|
||||||
# else
|
|
||||||
# define fbx_unordered_map tr1::unordered_map
|
# define fbx_unordered_map tr1::unordered_map
|
||||||
# define fbx_unordered_multimap tr1::unordered_multimap
|
# define fbx_unordered_multimap tr1::unordered_multimap
|
||||||
# define fbx_unordered_set tr1::unordered_set
|
# define fbx_unordered_set tr1::unordered_set
|
||||||
# define fbx_unordered_multiset tr1::unordered_multiset
|
# define fbx_unordered_multiset tr1::unordered_multiset
|
||||||
|
# else
|
||||||
|
# define fbx_unordered_map unordered_map
|
||||||
|
# define fbx_unordered_multimap unordered_multimap
|
||||||
|
# define fbx_unordered_set unordered_set
|
||||||
|
# define fbx_unordered_multiset unordered_multiset
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -508,6 +508,12 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
|
||||||
std::vector<int> uvIndices;
|
std::vector<int> uvIndices;
|
||||||
ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName));
|
ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName));
|
||||||
|
|
||||||
|
if (uvIndices.size() > vertex_count) {
|
||||||
|
FBXImporter::LogWarn(Formatter::format("trimming length of input array for ByPolygonVertex mapping: ")
|
||||||
|
<< uvIndices.size() << ", expected " << vertex_count);
|
||||||
|
uvIndices.resize(vertex_count);
|
||||||
|
}
|
||||||
|
|
||||||
if (uvIndices.size() != vertex_count) {
|
if (uvIndices.size() != vertex_count) {
|
||||||
FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygonVertex mapping: ")
|
FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygonVertex mapping: ")
|
||||||
<< uvIndices.size() << ", expected " << vertex_count);
|
<< uvIndices.size() << ", expected " << vertex_count);
|
||||||
|
|
|
@ -157,7 +157,10 @@ void HMPImporter::InternReadFile(const std::string &pFile,
|
||||||
szBuffer[2] = ((char *)&iMagic)[2];
|
szBuffer[2] = ((char *)&iMagic)[2];
|
||||||
szBuffer[3] = ((char *)&iMagic)[3];
|
szBuffer[3] = ((char *)&iMagic)[3];
|
||||||
szBuffer[4] = '\0';
|
szBuffer[4] = '\0';
|
||||||
|
|
||||||
|
delete[] mBuffer;
|
||||||
|
mBuffer = nullptr;
|
||||||
|
|
||||||
// We're definitely unable to load this file
|
// We're definitely unable to load this file
|
||||||
throw DeadlyImportError("Unknown HMP subformat ", pFile,
|
throw DeadlyImportError("Unknown HMP subformat ", pFile,
|
||||||
". Magic word (", szBuffer, ") is not known");
|
". Magic word (", szBuffer, ") is not known");
|
||||||
|
|
|
@ -250,7 +250,7 @@ void MDCImporter::InternReadFile(
|
||||||
|
|
||||||
// get the number of valid surfaces
|
// get the number of valid surfaces
|
||||||
BE_NCONST MDC::Surface *pcSurface, *pcSurface2;
|
BE_NCONST MDC::Surface *pcSurface, *pcSurface2;
|
||||||
pcSurface = pcSurface2 = new (mBuffer + pcHeader->ulOffsetSurfaces) MDC::Surface;
|
pcSurface = pcSurface2 = reinterpret_cast<BE_NCONST MDC::Surface *>(mBuffer + pcHeader->ulOffsetSurfaces);
|
||||||
unsigned int iNumShaders = 0;
|
unsigned int iNumShaders = 0;
|
||||||
for (unsigned int i = 0; i < pcHeader->ulNumSurfaces; ++i) {
|
for (unsigned int i = 0; i < pcHeader->ulNumSurfaces; ++i) {
|
||||||
// validate the surface header
|
// validate the surface header
|
||||||
|
@ -260,7 +260,7 @@ void MDCImporter::InternReadFile(
|
||||||
++pScene->mNumMeshes;
|
++pScene->mNumMeshes;
|
||||||
}
|
}
|
||||||
iNumShaders += pcSurface2->ulNumShaders;
|
iNumShaders += pcSurface2->ulNumShaders;
|
||||||
pcSurface2 = new ((int8_t *)pcSurface2 + pcSurface2->ulOffsetEnd) MDC::Surface;
|
pcSurface2 = reinterpret_cast<BE_NCONST MDC::Surface *>((BE_NCONST int8_t *)pcSurface2 + pcSurface2->ulOffsetEnd);
|
||||||
}
|
}
|
||||||
aszShaders.reserve(iNumShaders);
|
aszShaders.reserve(iNumShaders);
|
||||||
pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
|
pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
|
||||||
|
@ -405,7 +405,7 @@ void MDCImporter::InternReadFile(
|
||||||
pcFaceCur->mIndices[2] = iOutIndex + 0;
|
pcFaceCur->mIndices[2] = iOutIndex + 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcSurface = new ((int8_t *)pcSurface + pcSurface->ulOffsetEnd) MDC::Surface;
|
pcSurface = reinterpret_cast<BE_NCONST MDC::Surface *>((BE_NCONST int8_t *)pcSurface + pcSurface->ulOffsetEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a flat node graph with a root node and one child for each surface
|
// create a flat node graph with a root node and one child for each surface
|
||||||
|
|
|
@ -500,7 +500,7 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
|
||||||
throw DeadlyImportError("MS3D: Encountered invalid triangle index, file is malformed");
|
throw DeadlyImportError("MS3D: Encountered invalid triangle index, file is malformed");
|
||||||
}
|
}
|
||||||
|
|
||||||
TempTriangle& t = triangles[g.triangles[i]];
|
TempTriangle& t = triangles[g.triangles[j]];
|
||||||
f.mIndices = new unsigned int[f.mNumIndices=3];
|
f.mIndices = new unsigned int[f.mNumIndices=3];
|
||||||
|
|
||||||
for (unsigned int k = 0; k < 3; ++k,++n) {
|
for (unsigned int k = 0; k < 3; ++k,++n) {
|
||||||
|
@ -508,7 +508,7 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
|
||||||
throw DeadlyImportError("MS3D: Encountered invalid vertex index, file is malformed");
|
throw DeadlyImportError("MS3D: Encountered invalid vertex index, file is malformed");
|
||||||
}
|
}
|
||||||
|
|
||||||
const TempVertex& v = vertices[t.indices[i]];
|
const TempVertex& v = vertices[t.indices[k]];
|
||||||
for(unsigned int a = 0; a < 4; ++a) {
|
for(unsigned int a = 0; a < 4; ++a) {
|
||||||
if (v.bone_id[a] != UINT_MAX) {
|
if (v.bone_id[a] != UINT_MAX) {
|
||||||
if (v.bone_id[a] >= joints.size()) {
|
if (v.bone_id[a] >= joints.size()) {
|
||||||
|
@ -524,9 +524,9 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
|
||||||
// collect vertex components
|
// collect vertex components
|
||||||
m->mVertices[n] = v.pos;
|
m->mVertices[n] = v.pos;
|
||||||
|
|
||||||
m->mNormals[n] = t.normals[i];
|
m->mNormals[n] = t.normals[k];
|
||||||
m->mTextureCoords[0][n] = aiVector3D(t.uv[i].x,1.f-t.uv[i].y,0.0);
|
m->mTextureCoords[0][n] = aiVector3D(t.uv[k].x,1.f-t.uv[k].y,0.0);
|
||||||
f.mIndices[i] = n;
|
f.mIndices[k] = n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -181,13 +181,13 @@ Mesh *OgreBinarySerializer::ImportMesh(MemoryStreamReader *stream) {
|
||||||
|
|
||||||
uint16_t id = serializer.ReadHeader(false);
|
uint16_t id = serializer.ReadHeader(false);
|
||||||
if (id != HEADER_CHUNK_ID) {
|
if (id != HEADER_CHUNK_ID) {
|
||||||
throw DeadlyExportError("Invalid Ogre Mesh file header.");
|
throw DeadlyImportError("Invalid Ogre Mesh file header.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @todo Check what we can actually support.
|
/// @todo Check what we can actually support.
|
||||||
std::string version = serializer.ReadLine();
|
std::string version = serializer.ReadLine();
|
||||||
if (version != MESH_VERSION_1_8) {
|
if (version != MESH_VERSION_1_8) {
|
||||||
throw DeadlyExportError("Mesh version ", version, " not supported by this importer. Run OgreMeshUpgrader tool on the file and try again.",
|
throw DeadlyImportError("Mesh version ", version, " not supported by this importer. Run OgreMeshUpgrader tool on the file and try again.",
|
||||||
" Supported versions: ", MESH_VERSION_1_8);
|
" Supported versions: ", MESH_VERSION_1_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -797,13 +797,13 @@ MemoryStreamReaderPtr OgreBinarySerializer::OpenReader(Assimp::IOSystem *pIOHand
|
||||||
void OgreBinarySerializer::ReadSkeleton(Skeleton *skeleton) {
|
void OgreBinarySerializer::ReadSkeleton(Skeleton *skeleton) {
|
||||||
uint16_t id = ReadHeader(false);
|
uint16_t id = ReadHeader(false);
|
||||||
if (id != HEADER_CHUNK_ID) {
|
if (id != HEADER_CHUNK_ID) {
|
||||||
throw DeadlyExportError("Invalid Ogre Skeleton file header.");
|
throw DeadlyImportError("Invalid Ogre Skeleton file header.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// This deserialization supports both versions of the skeleton spec
|
// This deserialization supports both versions of the skeleton spec
|
||||||
std::string version = ReadLine();
|
std::string version = ReadLine();
|
||||||
if (version != SKELETON_VERSION_1_8 && version != SKELETON_VERSION_1_1) {
|
if (version != SKELETON_VERSION_1_8 && version != SKELETON_VERSION_1_1) {
|
||||||
throw DeadlyExportError("Skeleton version ", version, " not supported by this importer.",
|
throw DeadlyImportError("Skeleton version ", version, " not supported by this importer.",
|
||||||
" Supported versions: ", SKELETON_VERSION_1_8, " and ", SKELETON_VERSION_1_1);
|
" Supported versions: ", SKELETON_VERSION_1_8, " and ", SKELETON_VERSION_1_1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -419,7 +419,7 @@ bool OgreImporter::ReadTextureUnit(const std::string &textureUnitName, stringstr
|
||||||
size_t posUnderscore = textureRef.find_last_of("_");
|
size_t posUnderscore = textureRef.find_last_of("_");
|
||||||
|
|
||||||
if (posSuffix != string::npos && posUnderscore != string::npos && posSuffix > posUnderscore) {
|
if (posSuffix != string::npos && posUnderscore != string::npos && posSuffix > posUnderscore) {
|
||||||
string identifier = ai_str_tolower(textureRef.substr(posUnderscore, posSuffix - posUnderscore));
|
string identifier = ai_tolower(textureRef.substr(posUnderscore, posSuffix - posUnderscore));
|
||||||
ASSIMP_LOG_VERBOSE_DEBUG_F("Detecting texture type from filename postfix '", identifier, "'");
|
ASSIMP_LOG_VERBOSE_DEBUG_F("Detecting texture type from filename postfix '", identifier, "'");
|
||||||
|
|
||||||
if (identifier == "_n" || identifier == "_nrm" || identifier == "_nrml" || identifier == "_normal" || identifier == "_normals" || identifier == "_normalmap") {
|
if (identifier == "_n" || identifier == "_nrm" || identifier == "_nrml" || identifier == "_normal" || identifier == "_normals" || identifier == "_normalmap") {
|
||||||
|
@ -440,7 +440,7 @@ bool OgreImporter::ReadTextureUnit(const std::string &textureUnitName, stringstr
|
||||||
// Detect from texture unit name. This cannot be too broad as
|
// Detect from texture unit name. This cannot be too broad as
|
||||||
// authors might give names like "LightSaber" or "NormalNinja".
|
// authors might give names like "LightSaber" or "NormalNinja".
|
||||||
else {
|
else {
|
||||||
string unitNameLower = ai_str_tolower(textureUnitName);
|
string unitNameLower = ai_tolower(textureUnitName);
|
||||||
if (unitNameLower.find("normalmap") != string::npos) {
|
if (unitNameLower.find("normalmap") != string::npos) {
|
||||||
textureType = aiTextureType_NORMALS;
|
textureType = aiTextureType_NORMALS;
|
||||||
} else if (unitNameLower.find("specularmap") != string::npos) {
|
} else if (unitNameLower.find("specularmap") != string::npos) {
|
||||||
|
|
|
@ -64,7 +64,7 @@ static inline bool EndsWith(const std::string &s, const std::string &suffix, boo
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!caseSensitive) {
|
if (!caseSensitive) {
|
||||||
return EndsWith(ai_str_tolower(s), ai_str_tolower(suffix), true);
|
return EndsWith(ai_tolower(s), ai_tolower(suffix), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t len = suffix.length();
|
size_t len = suffix.length();
|
||||||
|
|
|
@ -120,7 +120,7 @@ std::string OgreXmlSerializer::ReadAttribute<std::string>(XmlNode &xmlNode, cons
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
bool OgreXmlSerializer::ReadAttribute<bool>(XmlNode &xmlNode, const char *name) const {
|
bool OgreXmlSerializer::ReadAttribute<bool>(XmlNode &xmlNode, const char *name) const {
|
||||||
std::string value = ai_str_tolower(ReadAttribute<std::string>(xmlNode, name));
|
std::string value = ai_tolower(ReadAttribute<std::string>(xmlNode, name));
|
||||||
if (ASSIMP_stricmp(value, "true") == 0) {
|
if (ASSIMP_stricmp(value, "true") == 0) {
|
||||||
return true;
|
return true;
|
||||||
} else if (ASSIMP_stricmp(value, "false") == 0) {
|
} else if (ASSIMP_stricmp(value, "false") == 0) {
|
||||||
|
@ -545,7 +545,7 @@ void OgreXmlSerializer::ReadSkeleton(XmlNode &node, Skeleton *skeleton) {
|
||||||
|
|
||||||
// Optional blend mode from root node
|
// Optional blend mode from root node
|
||||||
if (XmlParser::hasAttribute(node, "blendmode")) {
|
if (XmlParser::hasAttribute(node, "blendmode")) {
|
||||||
skeleton->blendMode = (ai_str_tolower(ReadAttribute<std::string>(node, "blendmode")) == "cumulative" ? Skeleton::ANIMBLEND_CUMULATIVE : Skeleton::ANIMBLEND_AVERAGE);
|
skeleton->blendMode = (ai_tolower(ReadAttribute<std::string>(node, "blendmode")) == "cumulative" ? Skeleton::ANIMBLEND_CUMULATIVE : Skeleton::ANIMBLEND_AVERAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (XmlNode ¤tNode : node.children()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
|
|
|
@ -278,7 +278,7 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
|
||||||
--ne;
|
--ne;
|
||||||
} while (IsSpace(s.at(ne)));
|
} while (IsSpace(s.at(ne)));
|
||||||
std::string type = s.substr(ns, ne - ns + 1);
|
std::string type = s.substr(ns, ne - ns + 1);
|
||||||
type = ai_str_tolower(type);
|
type = ai_tolower(type);
|
||||||
const char* sz = scheme.GetStaticStringForToken(type);
|
const char* sz = scheme.GetStaticStringForToken(type);
|
||||||
if(sz) {
|
if(sz) {
|
||||||
const std::string::size_type szLen = n2-n1+1;
|
const std::string::size_type szLen = n2-n1+1;
|
||||||
|
|
|
@ -57,7 +57,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# pragma warning(push)
|
# pragma warning(push)
|
||||||
# pragma warning(disable : 4127 4456 4245 4512 )
|
# pragma warning(disable : 4127 4456 4245 4512 )
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
//
|
//
|
||||||
#if _MSC_VER > 1500 || (defined __GNUC___)
|
#if _MSC_VER > 1500 || (defined __GNUC___)
|
||||||
|
@ -69,12 +69,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#ifdef ASSIMP_STEP_USE_UNORDERED_MULTIMAP
|
#ifdef ASSIMP_STEP_USE_UNORDERED_MULTIMAP
|
||||||
# include <unordered_map>
|
# include <unordered_map>
|
||||||
# if _MSC_VER > 1600
|
# if defined(_MSC_VER) && _MSC_VER <= 1600
|
||||||
# define step_unordered_map unordered_map
|
|
||||||
# define step_unordered_multimap unordered_multimap
|
|
||||||
# else
|
|
||||||
# define step_unordered_map tr1::unordered_map
|
# define step_unordered_map tr1::unordered_map
|
||||||
# define step_unordered_multimap tr1::unordered_multimap
|
# define step_unordered_multimap tr1::unordered_multimap
|
||||||
|
# else
|
||||||
|
# define step_unordered_map unordered_map
|
||||||
|
# define step_unordered_multimap unordered_multimap
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -75,12 +75,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#ifdef ASSIMP_STEP_USE_UNORDERED_MULTIMAP
|
#ifdef ASSIMP_STEP_USE_UNORDERED_MULTIMAP
|
||||||
# include <unordered_map>
|
# include <unordered_map>
|
||||||
# if _MSC_VER > 1600
|
# if defined(_MSC_VER) && _MSC_VER <= 1600
|
||||||
# define step_unordered_map unordered_map
|
|
||||||
# define step_unordered_multimap unordered_multimap
|
|
||||||
# else
|
|
||||||
# define step_unordered_map tr1::unordered_map
|
# define step_unordered_map tr1::unordered_map
|
||||||
# define step_unordered_multimap tr1::unordered_multimap
|
# define step_unordered_multimap tr1::unordered_multimap
|
||||||
|
# else
|
||||||
|
# define step_unordered_map unordered_map
|
||||||
|
# define step_unordered_multimap unordered_multimap
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -302,7 +302,7 @@ void StepExporter::WriteFile()
|
||||||
dv23.Normalize();
|
dv23.Normalize();
|
||||||
dv31.Normalize();
|
dv31.Normalize();
|
||||||
dv13.Normalize();
|
dv13.Normalize();
|
||||||
|
|
||||||
aiVector3D dvY = dv12;
|
aiVector3D dvY = dv12;
|
||||||
aiVector3D dvX = dvY ^ dv13;
|
aiVector3D dvX = dvY ^ dv13;
|
||||||
dvX.Normalize();
|
dvX.Normalize();
|
||||||
|
|
|
@ -92,10 +92,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#ifdef ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
|
#ifdef ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
|
||||||
# include <unordered_map>
|
# include <unordered_map>
|
||||||
# if _MSC_VER > 1600
|
# if defined(_MSC_VER) && _MSC_VER <= 1600
|
||||||
# define gltf_unordered_map unordered_map
|
|
||||||
# else
|
|
||||||
# define gltf_unordered_map tr1::unordered_map
|
# define gltf_unordered_map tr1::unordered_map
|
||||||
|
# else
|
||||||
|
# define gltf_unordered_map unordered_map
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -954,7 +954,9 @@ namespace glTF
|
||||||
virtual void AttachToDocument(Document& doc) = 0;
|
virtual void AttachToDocument(Document& doc) = 0;
|
||||||
virtual void DetachFromDocument() = 0;
|
virtual void DetachFromDocument() = 0;
|
||||||
|
|
||||||
|
#if !defined(ASSIMP_BUILD_NO_EXPORT)
|
||||||
virtual void WriteObjects(AssetWriter& writer) = 0;
|
virtual void WriteObjects(AssetWriter& writer) = 0;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -986,8 +988,10 @@ namespace glTF
|
||||||
void AttachToDocument(Document& doc);
|
void AttachToDocument(Document& doc);
|
||||||
void DetachFromDocument();
|
void DetachFromDocument();
|
||||||
|
|
||||||
|
#if !defined(ASSIMP_BUILD_NO_EXPORT)
|
||||||
void WriteObjects(AssetWriter& writer)
|
void WriteObjects(AssetWriter& writer)
|
||||||
{ WriteLazyDict<T>(*this, writer); }
|
{ WriteLazyDict<T>(*this, writer); }
|
||||||
|
#endif
|
||||||
|
|
||||||
Ref<T> Add(T* obj);
|
Ref<T> Add(T* obj);
|
||||||
|
|
||||||
|
|
|
@ -74,10 +74,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#ifdef ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
|
#ifdef ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#if _MSC_VER > 1600
|
#if defined(_MSC_VER) && _MSC_VER <= 1600
|
||||||
#define gltf_unordered_map unordered_map
|
|
||||||
#else
|
|
||||||
#define gltf_unordered_map tr1::unordered_map
|
#define gltf_unordered_map tr1::unordered_map
|
||||||
|
#else
|
||||||
|
#define gltf_unordered_map unordered_map
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "AssetLib/glTF/glTFImporter.h"
|
#include "AssetLib/glTF/glTFImporter.h"
|
||||||
#include "AssetLib/glTF/glTFAsset.h"
|
#include "AssetLib/glTF/glTFAsset.h"
|
||||||
|
#if !defined(ASSIMP_BUILD_NO_EXPORT)
|
||||||
#include "AssetLib/glTF/glTFAssetWriter.h"
|
#include "AssetLib/glTF/glTFAssetWriter.h"
|
||||||
|
#endif
|
||||||
#include "PostProcessing/MakeVerboseFormat.h"
|
#include "PostProcessing/MakeVerboseFormat.h"
|
||||||
|
|
||||||
#include <assimp/StringComparison.h>
|
#include <assimp/StringComparison.h>
|
||||||
|
|
|
@ -98,12 +98,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifdef ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
|
#ifdef ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#if _MSC_VER > 1600
|
#if defined(_MSC_VER) && _MSC_VER <= 1600
|
||||||
#define gltf_unordered_map unordered_map
|
|
||||||
#define gltf_unordered_set unordered_set
|
|
||||||
#else
|
|
||||||
#define gltf_unordered_map tr1::unordered_map
|
#define gltf_unordered_map tr1::unordered_map
|
||||||
#define gltf_unordered_set tr1::unordered_set
|
#define gltf_unordered_set tr1::unordered_set
|
||||||
|
#else
|
||||||
|
#define gltf_unordered_map unordered_map
|
||||||
|
#define gltf_unordered_set unordered_set
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -813,6 +813,11 @@ struct Mesh : public Object {
|
||||||
AccessorList position, normal, tangent;
|
AccessorList position, normal, tangent;
|
||||||
};
|
};
|
||||||
std::vector<Target> targets;
|
std::vector<Target> targets;
|
||||||
|
|
||||||
|
// extension: FB_ngon_encoding
|
||||||
|
bool ngonEncoded;
|
||||||
|
|
||||||
|
Primitive(): ngonEncoded(false) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<Primitive> primitives;
|
std::vector<Primitive> primitives;
|
||||||
|
@ -992,7 +997,9 @@ public:
|
||||||
virtual void AttachToDocument(Document &doc) = 0;
|
virtual void AttachToDocument(Document &doc) = 0;
|
||||||
virtual void DetachFromDocument() = 0;
|
virtual void DetachFromDocument() = 0;
|
||||||
|
|
||||||
|
#if !defined(ASSIMP_BUILD_NO_EXPORT)
|
||||||
virtual void WriteObjects(AssetWriter &writer) = 0;
|
virtual void WriteObjects(AssetWriter &writer) = 0;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
@ -1025,7 +1032,9 @@ class LazyDict : public LazyDictBase {
|
||||||
void AttachToDocument(Document &doc);
|
void AttachToDocument(Document &doc);
|
||||||
void DetachFromDocument();
|
void DetachFromDocument();
|
||||||
|
|
||||||
|
#if !defined(ASSIMP_BUILD_NO_EXPORT)
|
||||||
void WriteObjects(AssetWriter &writer) { WriteLazyDict<T>(*this, writer); }
|
void WriteObjects(AssetWriter &writer) { WriteLazyDict<T>(*this, writer); }
|
||||||
|
#endif
|
||||||
|
|
||||||
Ref<T> Add(T *obj);
|
Ref<T> Add(T *obj);
|
||||||
|
|
||||||
|
@ -1108,6 +1117,7 @@ public:
|
||||||
bool KHR_materials_clearcoat;
|
bool KHR_materials_clearcoat;
|
||||||
bool KHR_materials_transmission;
|
bool KHR_materials_transmission;
|
||||||
bool KHR_draco_mesh_compression;
|
bool KHR_draco_mesh_compression;
|
||||||
|
bool FB_ngon_encoding;
|
||||||
} extensionsUsed;
|
} extensionsUsed;
|
||||||
|
|
||||||
//! Keeps info about the required extensions
|
//! Keeps info about the required extensions
|
||||||
|
|
|
@ -507,6 +507,20 @@ namespace glTF2 {
|
||||||
Mesh::Primitive& p = m.primitives[i];
|
Mesh::Primitive& p = m.primitives[i];
|
||||||
Value prim;
|
Value prim;
|
||||||
prim.SetObject();
|
prim.SetObject();
|
||||||
|
|
||||||
|
// Extensions
|
||||||
|
if (p.ngonEncoded)
|
||||||
|
{
|
||||||
|
Value exts;
|
||||||
|
exts.SetObject();
|
||||||
|
|
||||||
|
Value FB_ngon_encoding;
|
||||||
|
FB_ngon_encoding.SetObject();
|
||||||
|
|
||||||
|
exts.AddMember(StringRef("FB_ngon_encoding"), FB_ngon_encoding, w.mAl);
|
||||||
|
prim.AddMember("extensions", exts, w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
prim.AddMember("mode", Value(int(p.mode)).Move(), w.mAl);
|
prim.AddMember("mode", Value(int(p.mode)).Move(), w.mAl);
|
||||||
|
|
||||||
|
@ -874,6 +888,10 @@ namespace glTF2 {
|
||||||
if (this->mAsset.extensionsUsed.KHR_materials_transmission) {
|
if (this->mAsset.extensionsUsed.KHR_materials_transmission) {
|
||||||
exts.PushBack(StringRef("KHR_materials_transmission"), mAl);
|
exts.PushBack(StringRef("KHR_materials_transmission"), mAl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->mAsset.extensionsUsed.FB_ngon_encoding) {
|
||||||
|
exts.PushBack(StringRef("FB_ngon_encoding"), mAl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!exts.Empty())
|
if (!exts.Empty())
|
||||||
|
|
|
@ -97,6 +97,9 @@ glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const ai
|
||||||
|
|
||||||
mAsset.reset( new Asset( pIOSystem ) );
|
mAsset.reset( new Asset( pIOSystem ) );
|
||||||
|
|
||||||
|
// Always on as our triangulation process is aware of this type of encoding
|
||||||
|
mAsset->extensionsUsed.FB_ngon_encoding = true;
|
||||||
|
|
||||||
if (isBinary) {
|
if (isBinary) {
|
||||||
mAsset->SetAsBinary();
|
mAsset->SetAsBinary();
|
||||||
}
|
}
|
||||||
|
@ -955,6 +958,7 @@ void glTF2Exporter::ExportMeshes()
|
||||||
m->name = name;
|
m->name = name;
|
||||||
|
|
||||||
p.material = mAsset->materials.Get(aim->mMaterialIndex);
|
p.material = mAsset->materials.Get(aim->mMaterialIndex);
|
||||||
|
p.ngonEncoded = (aim->mPrimitiveTypes & aiPrimitiveType_NGONEncodingFlag) != 0;
|
||||||
|
|
||||||
/******************* Vertices ********************/
|
/******************* Vertices ********************/
|
||||||
Ref<Accessor> v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
|
Ref<Accessor> v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
|
||||||
|
|
|
@ -44,7 +44,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "AssetLib/glTF2/glTF2Importer.h"
|
#include "AssetLib/glTF2/glTF2Importer.h"
|
||||||
#include "PostProcessing/MakeVerboseFormat.h"
|
#include "PostProcessing/MakeVerboseFormat.h"
|
||||||
#include "AssetLib/glTF2/glTF2Asset.h"
|
#include "AssetLib/glTF2/glTF2Asset.h"
|
||||||
|
#if !defined(ASSIMP_BUILD_NO_EXPORT)
|
||||||
#include "AssetLib/glTF2/glTF2AssetWriter.h"
|
#include "AssetLib/glTF2/glTF2AssetWriter.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <assimp/CreateAnimMesh.h>
|
#include <assimp/CreateAnimMesh.h>
|
||||||
#include <assimp/StringComparison.h>
|
#include <assimp/StringComparison.h>
|
||||||
|
@ -527,8 +529,8 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
std::fill(aim->mAnimMeshes, aim->mAnimMeshes + aim->mNumAnimMeshes, nullptr);
|
std::fill(aim->mAnimMeshes, aim->mAnimMeshes + aim->mNumAnimMeshes, nullptr);
|
||||||
for (size_t i = 0; i < targets.size(); i++) {
|
for (size_t i = 0; i < targets.size(); i++) {
|
||||||
bool needPositions = targets[i].position.size() > 0;
|
bool needPositions = targets[i].position.size() > 0;
|
||||||
bool needNormals = targets[i].normal.size() > 0;
|
bool needNormals = (targets[i].normal.size() > 0) && aim->HasNormals();
|
||||||
bool needTangents = targets[i].tangent.size() > 0;
|
bool needTangents = (targets[i].tangent.size() > 0) && aim->HasTangentsAndBitangents();
|
||||||
// GLTF morph does not support colors and texCoords
|
// GLTF morph does not support colors and texCoords
|
||||||
aim->mAnimMeshes[i] = aiCreateAnimMesh(aim,
|
aim->mAnimMeshes[i] = aiCreateAnimMesh(aim,
|
||||||
needPositions, needNormals, needTangents, false, false);
|
needPositions, needNormals, needTangents, false, false);
|
||||||
|
@ -536,35 +538,47 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
Mesh::Primitive::Target &target = targets[i];
|
Mesh::Primitive::Target &target = targets[i];
|
||||||
|
|
||||||
if (needPositions) {
|
if (needPositions) {
|
||||||
aiVector3D *positionDiff = nullptr;
|
if (target.position[0]->count != aim->mNumVertices) {
|
||||||
target.position[0]->ExtractData(positionDiff);
|
ASSIMP_LOG_WARN_F("Positions of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count");
|
||||||
for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) {
|
} else {
|
||||||
aiAnimMesh.mVertices[vertexId] += positionDiff[vertexId];
|
aiVector3D *positionDiff = nullptr;
|
||||||
|
target.position[0]->ExtractData(positionDiff);
|
||||||
|
for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) {
|
||||||
|
aiAnimMesh.mVertices[vertexId] += positionDiff[vertexId];
|
||||||
|
}
|
||||||
|
delete[] positionDiff;
|
||||||
}
|
}
|
||||||
delete[] positionDiff;
|
|
||||||
}
|
}
|
||||||
if (needNormals) {
|
if (needNormals) {
|
||||||
aiVector3D *normalDiff = nullptr;
|
if (target.normal[0]->count != aim->mNumVertices) {
|
||||||
target.normal[0]->ExtractData(normalDiff);
|
ASSIMP_LOG_WARN_F("Normals of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count");
|
||||||
for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) {
|
} else {
|
||||||
aiAnimMesh.mNormals[vertexId] += normalDiff[vertexId];
|
aiVector3D *normalDiff = nullptr;
|
||||||
|
target.normal[0]->ExtractData(normalDiff);
|
||||||
|
for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) {
|
||||||
|
aiAnimMesh.mNormals[vertexId] += normalDiff[vertexId];
|
||||||
|
}
|
||||||
|
delete[] normalDiff;
|
||||||
}
|
}
|
||||||
delete[] normalDiff;
|
|
||||||
}
|
}
|
||||||
if (needTangents) {
|
if (needTangents) {
|
||||||
Tangent *tangent = nullptr;
|
if (target.tangent[0]->count != aim->mNumVertices) {
|
||||||
attr.tangent[0]->ExtractData(tangent);
|
ASSIMP_LOG_WARN_F("Tangents of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count");
|
||||||
|
} else {
|
||||||
|
Tangent *tangent = nullptr;
|
||||||
|
attr.tangent[0]->ExtractData(tangent);
|
||||||
|
|
||||||
aiVector3D *tangentDiff = nullptr;
|
aiVector3D *tangentDiff = nullptr;
|
||||||
target.tangent[0]->ExtractData(tangentDiff);
|
target.tangent[0]->ExtractData(tangentDiff);
|
||||||
|
|
||||||
for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; ++vertexId) {
|
for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; ++vertexId) {
|
||||||
tangent[vertexId].xyz += tangentDiff[vertexId];
|
tangent[vertexId].xyz += tangentDiff[vertexId];
|
||||||
aiAnimMesh.mTangents[vertexId] = tangent[vertexId].xyz;
|
aiAnimMesh.mTangents[vertexId] = tangent[vertexId].xyz;
|
||||||
aiAnimMesh.mBitangents[vertexId] = (aiAnimMesh.mNormals[vertexId] ^ tangent[vertexId].xyz) * tangent[vertexId].w;
|
aiAnimMesh.mBitangents[vertexId] = (aiAnimMesh.mNormals[vertexId] ^ tangent[vertexId].xyz) * tangent[vertexId].w;
|
||||||
|
}
|
||||||
|
delete[] tangent;
|
||||||
|
delete[] tangentDiff;
|
||||||
}
|
}
|
||||||
delete[] tangent;
|
|
||||||
delete[] tangentDiff;
|
|
||||||
}
|
}
|
||||||
if (mesh.weights.size() > i) {
|
if (mesh.weights.size() > i) {
|
||||||
aiAnimMesh.mWeight = mesh.weights[i];
|
aiAnimMesh.mWeight = mesh.weights[i];
|
||||||
|
|
|
@ -298,7 +298,6 @@ SET(ASSIMP_EXPORTERS_DISABLED "") # disabled exporters list (used to print)
|
||||||
|
|
||||||
ADD_ASSIMP_IMPORTER( AMF
|
ADD_ASSIMP_IMPORTER( AMF
|
||||||
AssetLib/AMF/AMFImporter.hpp
|
AssetLib/AMF/AMFImporter.hpp
|
||||||
AssetLib/AMF/AMFImporter_Macro.hpp
|
|
||||||
AssetLib/AMF/AMFImporter_Node.hpp
|
AssetLib/AMF/AMFImporter_Node.hpp
|
||||||
AssetLib/AMF/AMFImporter.cpp
|
AssetLib/AMF/AMFImporter.cpp
|
||||||
AssetLib/AMF/AMFImporter_Geometry.cpp
|
AssetLib/AMF/AMFImporter_Geometry.cpp
|
||||||
|
|
|
@ -276,7 +276,7 @@ std::string BaseImporter::GetExtension(const std::string &file) {
|
||||||
|
|
||||||
// thanks to Andy Maloney for the hint
|
// thanks to Andy Maloney for the hint
|
||||||
std::string ret = file.substr(pos + 1);
|
std::string ret = file.substr(pos + 1);
|
||||||
ret = ai_str_tolower(ret);
|
ret = ai_tolower(ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -982,7 +982,7 @@ size_t Importer::GetImporterIndex (const char* szExtension) const {
|
||||||
if (ext.empty()) {
|
if (ext.empty()) {
|
||||||
return static_cast<size_t>(-1);
|
return static_cast<size_t>(-1);
|
||||||
}
|
}
|
||||||
ext = ai_str_tolower(ext);
|
ext = ai_tolower(ext);
|
||||||
std::set<std::string> str;
|
std::set<std::string> str;
|
||||||
for (std::vector<BaseImporter*>::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i) {
|
for (std::vector<BaseImporter*>::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i) {
|
||||||
str.clear();
|
str.clear();
|
||||||
|
|
|
@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
static const char *LEGAL_INFORMATION =
|
static const char *LEGAL_INFORMATION =
|
||||||
"Open Asset Import Library (Assimp).\n"
|
"Open Asset Import Library (Assimp).\n"
|
||||||
"A free C/C++ library to import various 3D file formats into applications\n\n"
|
"A free C/C++ library to import various 3D file formats into applications\n\n"
|
||||||
"(c) 2006-2020, assimp team\n"
|
"(c) 2006-2021, Assimp team\n"
|
||||||
"License under the terms and conditions of the 3-clause BSD license\n"
|
"License under the terms and conditions of the 3-clause BSD license\n"
|
||||||
"https://www.assimp.org\n";
|
"https://www.assimp.org\n";
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,7 @@ bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const {
|
||||||
pTexture->pcData = imageContent;
|
pTexture->pcData = imageContent;
|
||||||
|
|
||||||
auto extension = path.substr(path.find_last_of('.') + 1u);
|
auto extension = path.substr(path.find_last_of('.') + 1u);
|
||||||
extension = ai_str_tolower(extension);
|
extension = ai_tolower(extension);
|
||||||
if (extension == "jpeg") {
|
if (extension == "jpeg") {
|
||||||
extension = "jpg";
|
extension = "jpg";
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,87 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Helper struct used to simplify NGON encoding functions.
|
||||||
|
*/
|
||||||
|
struct NGONEncoder {
|
||||||
|
NGONEncoder() : mLastNGONFirstIndex((unsigned int)-1) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode the current triangle, and make sure it is recognized as a triangle.
|
||||||
|
*
|
||||||
|
* This method will rotate indices in tri if needed in order to avoid tri to be considered
|
||||||
|
* part of the previous ngon. This method is to be used whenever you want to emit a real triangle,
|
||||||
|
* and make sure it is seen as a triangle.
|
||||||
|
*
|
||||||
|
* @param tri Triangle to encode.
|
||||||
|
*/
|
||||||
|
void ngonEncodeTriangle(aiFace * tri) {
|
||||||
|
ai_assert(tri->mNumIndices == 3);
|
||||||
|
|
||||||
|
// Rotate indices in new triangle to avoid ngon encoding false ngons
|
||||||
|
// Otherwise, the new triangle would be considered part of the previous NGON.
|
||||||
|
if (isConsideredSameAsLastNgon(tri)) {
|
||||||
|
std::swap(tri->mIndices[0], tri->mIndices[2]);
|
||||||
|
std::swap(tri->mIndices[1], tri->mIndices[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
mLastNGONFirstIndex = tri->mIndices[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode a quad (2 triangles) in ngon encoding, and make sure they are seen as a single ngon.
|
||||||
|
*
|
||||||
|
* @param tri1 First quad triangle
|
||||||
|
* @param tri2 Second quad triangle
|
||||||
|
*
|
||||||
|
* @pre Triangles must be properly fanned from the most appropriate vertex.
|
||||||
|
*/
|
||||||
|
void ngonEncodeQuad(aiFace *tri1, aiFace *tri2) {
|
||||||
|
ai_assert(tri1->mNumIndices == 3);
|
||||||
|
ai_assert(tri2->mNumIndices == 3);
|
||||||
|
ai_assert(tri1->mIndices[0] == tri2->mIndices[0]);
|
||||||
|
|
||||||
|
// If the selected fanning vertex is the same as the previously
|
||||||
|
// emitted ngon, we use the opposite vertex which also happens to work
|
||||||
|
// for tri-fanning a concave quad.
|
||||||
|
// ref: https://github.com/assimp/assimp/pull/3695#issuecomment-805999760
|
||||||
|
if (isConsideredSameAsLastNgon(tri1)) {
|
||||||
|
// Right-rotate indices for tri1 (index 2 becomes the new fanning vertex)
|
||||||
|
std::swap(tri1->mIndices[0], tri1->mIndices[2]);
|
||||||
|
std::swap(tri1->mIndices[1], tri1->mIndices[2]);
|
||||||
|
|
||||||
|
// Left-rotate indices for tri2 (index 2 becomes the new fanning vertex)
|
||||||
|
std::swap(tri2->mIndices[1], tri2->mIndices[2]);
|
||||||
|
std::swap(tri2->mIndices[0], tri2->mIndices[2]);
|
||||||
|
|
||||||
|
ai_assert(tri1->mIndices[0] == tri2->mIndices[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
mLastNGONFirstIndex = tri1->mIndices[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check whether this triangle would be considered part of the lastly emitted ngon or not.
|
||||||
|
*
|
||||||
|
* @param tri Current triangle.
|
||||||
|
* @return true If used as is, this triangle will be part of last ngon.
|
||||||
|
* @return false If used as is, this triangle is not considered part of the last ngon.
|
||||||
|
*/
|
||||||
|
bool isConsideredSameAsLastNgon(const aiFace * tri) const {
|
||||||
|
ai_assert(tri->mNumIndices == 3);
|
||||||
|
return tri->mIndices[0] == mLastNGONFirstIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned int mLastNGONFirstIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
TriangulateProcess::TriangulateProcess()
|
TriangulateProcess::TriangulateProcess()
|
||||||
|
@ -175,10 +256,15 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
|
||||||
pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
|
pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
|
||||||
pMesh->mPrimitiveTypes &= ~aiPrimitiveType_POLYGON;
|
pMesh->mPrimitiveTypes &= ~aiPrimitiveType_POLYGON;
|
||||||
|
|
||||||
|
// The mesh becomes NGON encoded now, during the triangulation process.
|
||||||
|
pMesh->mPrimitiveTypes |= aiPrimitiveType_NGONEncodingFlag;
|
||||||
|
|
||||||
aiFace* out = new aiFace[numOut](), *curOut = out;
|
aiFace* out = new aiFace[numOut](), *curOut = out;
|
||||||
std::vector<aiVector3D> temp_verts3d(max_out+2); /* temporary storage for vertices */
|
std::vector<aiVector3D> temp_verts3d(max_out+2); /* temporary storage for vertices */
|
||||||
std::vector<aiVector2D> temp_verts(max_out+2);
|
std::vector<aiVector2D> temp_verts(max_out+2);
|
||||||
|
|
||||||
|
NGONEncoder ngonEncoder;
|
||||||
|
|
||||||
// Apply vertex colors to represent the face winding?
|
// Apply vertex colors to represent the face winding?
|
||||||
#ifdef AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING
|
#ifdef AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING
|
||||||
if (!pMesh->mColors[0])
|
if (!pMesh->mColors[0])
|
||||||
|
@ -220,8 +306,11 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
|
||||||
aiFace& nface = *curOut++;
|
aiFace& nface = *curOut++;
|
||||||
nface.mNumIndices = face.mNumIndices;
|
nface.mNumIndices = face.mNumIndices;
|
||||||
nface.mIndices = face.mIndices;
|
nface.mIndices = face.mIndices;
|
||||||
|
|
||||||
face.mIndices = nullptr;
|
face.mIndices = nullptr;
|
||||||
|
|
||||||
|
// points and lines don't require ngon encoding (and are not supported either!)
|
||||||
|
if (nface.mNumIndices == 3) ngonEncoder.ngonEncodeTriangle(&nface);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// optimized code for quadrilaterals
|
// optimized code for quadrilaterals
|
||||||
|
@ -274,6 +363,9 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
|
||||||
|
|
||||||
// prevent double deletion of the indices field
|
// prevent double deletion of the indices field
|
||||||
face.mIndices = nullptr;
|
face.mIndices = nullptr;
|
||||||
|
|
||||||
|
ngonEncoder.ngonEncodeQuad(&nface, &sface);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -284,11 +376,11 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
|
||||||
// modeling suite to make extensive use of highly concave, monster polygons ...
|
// modeling suite to make extensive use of highly concave, monster polygons ...
|
||||||
// so we need to apply the full 'ear cutting' algorithm to get it right.
|
// so we need to apply the full 'ear cutting' algorithm to get it right.
|
||||||
|
|
||||||
// RERQUIREMENT: polygon is expected to be simple and *nearly* planar.
|
// REQUIREMENT: polygon is expected to be simple and *nearly* planar.
|
||||||
// We project it onto a plane to get a 2d triangle.
|
// We project it onto a plane to get a 2d triangle.
|
||||||
|
|
||||||
// Collect all vertices of of the polygon.
|
// Collect all vertices of of the polygon.
|
||||||
for (tmp = 0; tmp < max; ++tmp) {
|
for (tmp = 0; tmp < max; ++tmp) {
|
||||||
temp_verts3d[tmp] = verts[idx[tmp]];
|
temp_verts3d[tmp] = verts[idx[tmp]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,6 +600,11 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
|
||||||
i[0] = idx[i[0]];
|
i[0] = idx[i[0]];
|
||||||
i[1] = idx[i[1]];
|
i[1] = idx[i[1]];
|
||||||
i[2] = idx[i[2]];
|
i[2] = idx[i[2]];
|
||||||
|
|
||||||
|
// IMPROVEMENT: Polygons are not supported yet by this ngon encoding + triangulation step.
|
||||||
|
// So we encode polygons as regular triangles. No way to reconstruct the original
|
||||||
|
// polygon in this case.
|
||||||
|
ngonEncoder.ngonEncodeTriangle(f);
|
||||||
++f;
|
++f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ inline IntegerType lcm( IntegerType a, IntegerType b ) {
|
||||||
}
|
}
|
||||||
return a / t * b;
|
return a / t * b;
|
||||||
}
|
}
|
||||||
/// @brief Will return the smallest epsilon-value for the requested type.
|
/// @brief Will return the smallest epsilon-value for the requested type.
|
||||||
/// @return The numercical limit epsilon depending on its type.
|
/// @return The numercical limit epsilon depending on its type.
|
||||||
template<class T>
|
template<class T>
|
||||||
inline T getEpsilon() {
|
inline T getEpsilon() {
|
||||||
|
@ -97,7 +97,7 @@ inline T getEpsilon() {
|
||||||
/// @brief Will return the constant PI for the requested type.
|
/// @brief Will return the constant PI for the requested type.
|
||||||
/// @return Pi
|
/// @return Pi
|
||||||
template<class T>
|
template<class T>
|
||||||
inline T PI() {
|
inline T aiPi() {
|
||||||
return static_cast<T>(3.14159265358979323846);
|
return static_cast<T>(3.14159265358979323846);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -225,7 +225,7 @@ AI_FORCE_INLINE char_t ai_tolower(char_t in) {
|
||||||
/// @param in The incoming string.
|
/// @param in The incoming string.
|
||||||
/// @return The string as lowercase.
|
/// @return The string as lowercase.
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
AI_FORCE_INLINE std::string ai_str_tolower(const std::string &in) {
|
AI_FORCE_INLINE std::string ai_tolower(const std::string &in) {
|
||||||
std::string out(in);
|
std::string out(in);
|
||||||
ai_trim_left(out);
|
ai_trim_left(out);
|
||||||
ai_trim_right(out);
|
ai_trim_right(out);
|
||||||
|
|
|
@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
/// @brief Will find a node by its name.
|
||||||
struct find_node_by_name_predicate {
|
struct find_node_by_name_predicate {
|
||||||
std::string mName;
|
std::string mName;
|
||||||
find_node_by_name_predicate(const std::string &name) :
|
find_node_by_name_predicate(const std::string &name) :
|
||||||
|
@ -88,7 +89,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
mData.resize(0);
|
if(mData.empty()) {
|
||||||
|
mDoc = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mData.clear();
|
||||||
delete mDoc;
|
delete mDoc;
|
||||||
mDoc = nullptr;
|
mDoc = nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -398,6 +398,24 @@ enum aiPrimitiveType {
|
||||||
*/
|
*/
|
||||||
aiPrimitiveType_POLYGON = 0x8,
|
aiPrimitiveType_POLYGON = 0x8,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A flag to determine whether this triangles only mesh is NGON encoded.
|
||||||
|
*
|
||||||
|
* NGON encoding is a special encoding that tells whether 2 or more consecutive triangles
|
||||||
|
* should be considered as a triangle fan. This is identified by looking at the first vertex index.
|
||||||
|
* 2 consecutive triangles with the same 1st vertex index are part of the same
|
||||||
|
* NGON.
|
||||||
|
*
|
||||||
|
* At the moment, only quads (concave or convex) are supported, meaning that polygons are 'seen' as
|
||||||
|
* triangles, as usual after a triangulation pass.
|
||||||
|
*
|
||||||
|
* To get an NGON encoded mesh, please use the aiProcess_Triangulate post process.
|
||||||
|
*
|
||||||
|
* @see aiProcess_Triangulate
|
||||||
|
* @link https://github.com/KhronosGroup/glTF/pull/1620
|
||||||
|
*/
|
||||||
|
aiPrimitiveType_NGONEncodingFlag = 0x10,
|
||||||
|
|
||||||
/** This value is not used. It is just here to force the
|
/** This value is not used. It is just here to force the
|
||||||
* compiler to map this enum to a 32 Bit integer.
|
* compiler to map this enum to a 32 Bit integer.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -22,7 +22,7 @@ BUILD_TYPE=Release
|
||||||
################################################
|
################################################
|
||||||
# Minimum iOS deployment target version
|
# Minimum iOS deployment target version
|
||||||
################################################
|
################################################
|
||||||
MIN_IOS_VERSION="6.0"
|
MIN_IOS_VERSION="10.0"
|
||||||
|
|
||||||
IOS_SDK_TARGET=$MIN_IOS_VERSION
|
IOS_SDK_TARGET=$MIN_IOS_VERSION
|
||||||
XCODE_ROOT_DIR=$(xcode-select --print-path)
|
XCODE_ROOT_DIR=$(xcode-select --print-path)
|
||||||
|
@ -60,8 +60,8 @@ build_arch()
|
||||||
|
|
||||||
unset DEVROOT SDKROOT CFLAGS LDFLAGS CPPFLAGS CXXFLAGS CMAKE_CLI_INPUT
|
unset DEVROOT SDKROOT CFLAGS LDFLAGS CPPFLAGS CXXFLAGS CMAKE_CLI_INPUT
|
||||||
|
|
||||||
#export CC="$(xcrun -sdk iphoneos -find clang)"
|
export CC="$(xcrun -sdk iphoneos -find clang)"
|
||||||
#export CPP="$CC -E"
|
export CPP="$CC -E"
|
||||||
export DEVROOT=$XCODE_ROOT_DIR/Platforms/$IOS_SDK_DEVICE.platform/Developer
|
export DEVROOT=$XCODE_ROOT_DIR/Platforms/$IOS_SDK_DEVICE.platform/Developer
|
||||||
export SDKROOT=$DEVROOT/SDKs/$IOS_SDK_DEVICE$IOS_SDK_VERSION.sdk
|
export SDKROOT=$DEVROOT/SDKs/$IOS_SDK_DEVICE$IOS_SDK_VERSION.sdk
|
||||||
export CFLAGS="-arch $1 -pipe -no-cpp-precomp -stdlib=$CPP_STD_LIB -isysroot $SDKROOT -I$SDKROOT/usr/include/ -miphoneos-version-min=$IOS_SDK_TARGET"
|
export CFLAGS="-arch $1 -pipe -no-cpp-precomp -stdlib=$CPP_STD_LIB -isysroot $SDKROOT -I$SDKROOT/usr/include/ -miphoneos-version-min=$IOS_SDK_TARGET"
|
||||||
|
|
|
@ -57,7 +57,7 @@ protected:
|
||||||
aiMatrix4x4 get_predetermined_transformation_matrix_for_decomposition() const {
|
aiMatrix4x4 get_predetermined_transformation_matrix_for_decomposition() const {
|
||||||
aiMatrix4x4 t, r;
|
aiMatrix4x4 t, r;
|
||||||
aiMatrix4x4::Translation(aiVector3D(14,-25,-8), t);
|
aiMatrix4x4::Translation(aiVector3D(14,-25,-8), t);
|
||||||
aiMatrix4x4::Rotation(Math::PI<float>() / 4.0f, aiVector3D(1).Normalize(), r);
|
aiMatrix4x4::Rotation(Math::aiPi<float>() / 4.0f, aiVector3D(1).Normalize(), r);
|
||||||
return t * r;
|
return t * r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ TEST_F(AssimpAPITest_aiQuaternion, aiCreateQuaternionFromMatrixTest) {
|
||||||
// to prevent running into division by zero.
|
// to prevent running into division by zero.
|
||||||
aiMatrix3x3 m, r;
|
aiMatrix3x3 m, r;
|
||||||
aiMatrix3x3::Translation(aiVector2D(14,-25), m);
|
aiMatrix3x3::Translation(aiVector2D(14,-25), m);
|
||||||
aiMatrix3x3::RotationZ(Math::PI<float>() / 4.0f, r);
|
aiMatrix3x3::RotationZ(Math::aiPi<float>() / 4.0f, r);
|
||||||
m = m * r;
|
m = m * r;
|
||||||
|
|
||||||
result_cpp = aiQuaternion(m);
|
result_cpp = aiQuaternion(m);
|
||||||
|
@ -127,8 +127,8 @@ TEST_F(AssimpAPITest_aiQuaternion, aiQuaternionInterpolateTest) {
|
||||||
// Use predetermined quaternions to prevent division by zero
|
// Use predetermined quaternions to prevent division by zero
|
||||||
// during slerp calculations.
|
// during slerp calculations.
|
||||||
const float INTERPOLATION(0.5f);
|
const float INTERPOLATION(0.5f);
|
||||||
const auto q1 = aiQuaternion(aiVector3D(-1,1,1).Normalize(), Math::PI<float>() / 4.0f);
|
const auto q1 = aiQuaternion(aiVector3D(-1,1,1).Normalize(), Math::aiPi<float>() / 4.0f);
|
||||||
const auto q2 = aiQuaternion(aiVector3D(1,2,1).Normalize(), Math::PI<float>() / 2.0f);
|
const auto q2 = aiQuaternion(aiVector3D(1,2,1).Normalize(), Math::aiPi<float>() / 2.0f);
|
||||||
aiQuaternion::Interpolate(result_cpp, q1, q2, INTERPOLATION);
|
aiQuaternion::Interpolate(result_cpp, q1, q2, INTERPOLATION);
|
||||||
aiQuaternionInterpolate(&result_c, &q1, &q2, INTERPOLATION);
|
aiQuaternionInterpolate(&result_c, &q1, &q2, INTERPOLATION);
|
||||||
EXPECT_EQ(result_cpp, result_c);
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
|
|
@ -51,6 +51,6 @@ const float AssimpMathTest::Epsilon = Math::getEpsilon<float>();
|
||||||
RandomUniformFloatGenerator AssimpMathTest::RandNonZero(1.0f, 100.0f);
|
RandomUniformFloatGenerator AssimpMathTest::RandNonZero(1.0f, 100.0f);
|
||||||
|
|
||||||
// Initialize with an interval of [-PI,PI] inclusively.
|
// Initialize with an interval of [-PI,PI] inclusively.
|
||||||
RandomUniformFloatGenerator AssimpMathTest::RandPI(-Math::PI<float>(), Math::PI<float>());
|
RandomUniformFloatGenerator AssimpMathTest::RandPI(-Math::aiPi<float>(), Math::aiPi<float>());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ TEST_F( utVersion, aiGetLegalStringTest ) {
|
||||||
EXPECT_NE( lv, nullptr );
|
EXPECT_NE( lv, nullptr );
|
||||||
std::string text( lv );
|
std::string text( lv );
|
||||||
|
|
||||||
size_t pos( text.find( std::string( "2020" ) ) );
|
size_t pos( text.find( std::string( "2021" ) ) );
|
||||||
EXPECT_NE( pos, std::string::npos );
|
EXPECT_NE( pos, std::string::npos );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ void CLogWindow::Init() {
|
||||||
|
|
||||||
// setup the log text
|
// setup the log text
|
||||||
this->szText = AI_VIEW_RTF_LOG_HEADER;
|
this->szText = AI_VIEW_RTF_LOG_HEADER;
|
||||||
;
|
|
||||||
this->szPlainText = "";
|
this->szPlainText = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue