Merge branch 'master' into strrchr
commit
9682ab0685
107
Readme.md
107
Readme.md
|
@ -25,107 +25,12 @@ Additionally, assimp features various __mesh post processing tools__: normals an
|
||||||
|
|
||||||
This is the development repo containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [Github Assimp Releases](https://github.com/assimp/assimp/releases).
|
This is the development repo containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [Github Assimp Releases](https://github.com/assimp/assimp/releases).
|
||||||
|
|
||||||
Monthly donations via Patreon:
|
|
||||||
<br>[![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/assimp)
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
One-off donations via PayPal:
|
|
||||||
<br>[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4JRJVPXC4QJM4)
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
Please check our Wiki as well: https://github.com/assimp/assimp/wiki
|
Please check our Wiki as well: https://github.com/assimp/assimp/wiki
|
||||||
|
|
||||||
If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
|
If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
|
||||||
|
|
||||||
#### Supported file formats ####
|
#### Supported file formats ####
|
||||||
|
You can find the complete list of supported file-formats [here](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md)
|
||||||
__Importers__:
|
|
||||||
|
|
||||||
- 3D
|
|
||||||
- [3DS](https://en.wikipedia.org/wiki/.3ds)
|
|
||||||
- [3MF](https://en.wikipedia.org/wiki/3D_Manufacturing_Format)
|
|
||||||
- AC
|
|
||||||
- [AC3D](https://en.wikipedia.org/wiki/AC3D)
|
|
||||||
- ACC
|
|
||||||
- AMJ
|
|
||||||
- ASE
|
|
||||||
- ASK
|
|
||||||
- B3D
|
|
||||||
- [BLEND](https://en.wikipedia.org/wiki/.blend_(file_format))
|
|
||||||
- [BVH](https://en.wikipedia.org/wiki/Biovision_Hierarchy)
|
|
||||||
- CMS
|
|
||||||
- COB
|
|
||||||
- [DAE/Collada](https://en.wikipedia.org/wiki/COLLADA)
|
|
||||||
- [DXF](https://en.wikipedia.org/wiki/AutoCAD_DXF)
|
|
||||||
- ENFF
|
|
||||||
- [FBX](https://en.wikipedia.org/wiki/FBX)
|
|
||||||
- [glTF 1.0](https://en.wikipedia.org/wiki/GlTF#glTF_1.0) + GLB
|
|
||||||
- [glTF 2.0](https://en.wikipedia.org/wiki/GlTF#glTF_2.0):
|
|
||||||
At the moment for glTF2.0 the following extensions are supported:
|
|
||||||
+ KHR_lights_punctual ( 5.0 )
|
|
||||||
+ KHR_materials_pbrSpecularGlossiness ( 5.0 )
|
|
||||||
+ KHR_materials_unlit ( 5.0 )
|
|
||||||
+ KHR_texture_transform ( 5.1 under test )
|
|
||||||
- HMB
|
|
||||||
- IFC-STEP
|
|
||||||
- IRR / IRRMESH
|
|
||||||
- [LWO](https://en.wikipedia.org/wiki/LightWave_3D)
|
|
||||||
- LWS
|
|
||||||
- LXO
|
|
||||||
- [M3D](https://bztsrc.gitlab.io/model3d)
|
|
||||||
- MD2
|
|
||||||
- MD3
|
|
||||||
- MD5
|
|
||||||
- MDC
|
|
||||||
- MDL
|
|
||||||
- MESH / MESH.XML
|
|
||||||
- MOT
|
|
||||||
- MS3D
|
|
||||||
- NDO
|
|
||||||
- NFF
|
|
||||||
- [OBJ](https://en.wikipedia.org/wiki/Wavefront_.obj_file)
|
|
||||||
- [OFF](https://en.wikipedia.org/wiki/OFF_(file_format))
|
|
||||||
- [OGEX](https://en.wikipedia.org/wiki/Open_Game_Engine_Exchange)
|
|
||||||
- [PLY](https://en.wikipedia.org/wiki/PLY_(file_format))
|
|
||||||
- PMX
|
|
||||||
- PRJ
|
|
||||||
- Q3O
|
|
||||||
- Q3S
|
|
||||||
- RAW
|
|
||||||
- SCN
|
|
||||||
- SIB
|
|
||||||
- SMD
|
|
||||||
- [STP](https://en.wikipedia.org/wiki/ISO_10303-21)
|
|
||||||
- [STL](https://en.wikipedia.org/wiki/STL_(file_format))
|
|
||||||
- TER
|
|
||||||
- UC
|
|
||||||
- VTA
|
|
||||||
- X
|
|
||||||
- [X3D](https://en.wikipedia.org/wiki/X3D)
|
|
||||||
- XGL
|
|
||||||
- ZGL
|
|
||||||
|
|
||||||
Additionally, some formats are supported by dependency on non-free code or external SDKs (not built by default):
|
|
||||||
|
|
||||||
- [C4D](https://en.wikipedia.org/wiki/Cinema_4D) (https://github.com/assimp/assimp/wiki/Cinema4D-&-Melange) IMporting geometry + node hierarchy are currently supported
|
|
||||||
|
|
||||||
__Exporters__:
|
|
||||||
|
|
||||||
- DAE (Collada)
|
|
||||||
- STL
|
|
||||||
- OBJ
|
|
||||||
- PLY
|
|
||||||
- X
|
|
||||||
- 3DS
|
|
||||||
- JSON (for WebGl, via https://github.com/acgessler/assimp2json)
|
|
||||||
- ASSBIN
|
|
||||||
- STEP
|
|
||||||
- glTF 1.0 (partial)
|
|
||||||
- glTF 2.0 (partial)
|
|
||||||
- 3MF ( experimental )
|
|
||||||
- FBX ( experimental )
|
|
||||||
|
|
||||||
### Building ###
|
### Building ###
|
||||||
Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file. We are available in vcpkg, and our build system is CMake; if you used CMake before there is a good chance you know what to do.
|
Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file. We are available in vcpkg, and our build system is CMake; if you used CMake before there is a good chance you know what to do.
|
||||||
|
@ -196,6 +101,16 @@ 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)
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
One-off donations via PayPal:
|
||||||
|
<br>[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4JRJVPXC4QJM4)
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
#### Organizations
|
#### Organizations
|
||||||
|
|
||||||
Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/assimp/contribute)]
|
Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/assimp/contribute)]
|
||||||
|
|
|
@ -1,707 +0,0 @@
|
||||||
/*
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
Open Asset Import Library (assimp)
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2006-2020, 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.cpp
|
|
||||||
/// \brief AMF-format files importer for Assimp: main algorithm implementation.
|
|
||||||
/// \date 2016
|
|
||||||
/// \author smal.root@gmail.com
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
|
|
||||||
|
|
||||||
// Header files, Assimp.
|
|
||||||
#include "AMFImporter.hpp"
|
|
||||||
#include "AMFImporter_Macro.hpp"
|
|
||||||
|
|
||||||
#include <assimp/fast_atof.h>
|
|
||||||
#include <assimp/DefaultIOSystem.h>
|
|
||||||
|
|
||||||
// Header files, stdlib.
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace Assimp
|
|
||||||
{
|
|
||||||
|
|
||||||
/// \var aiImporterDesc AMFImporter::Description
|
|
||||||
/// Conastant which hold importer description
|
|
||||||
const aiImporterDesc AMFImporter::Description = {
|
|
||||||
"Additive manufacturing file format(AMF) Importer",
|
|
||||||
"smalcom",
|
|
||||||
"",
|
|
||||||
"See documentation in source code. Chapter: Limitations.",
|
|
||||||
aiImporterFlags_SupportTextFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
"amf"
|
|
||||||
};
|
|
||||||
|
|
||||||
void AMFImporter::Clear()
|
|
||||||
{
|
|
||||||
mNodeElement_Cur = nullptr;
|
|
||||||
mUnit.clear();
|
|
||||||
mMaterial_Converted.clear();
|
|
||||||
mTexture_Converted.clear();
|
|
||||||
// Delete all elements
|
|
||||||
if(!mNodeElement_List.empty())
|
|
||||||
{
|
|
||||||
for(CAMFImporter_NodeElement* ne: mNodeElement_List) { delete ne; }
|
|
||||||
|
|
||||||
mNodeElement_List.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AMFImporter::~AMFImporter()
|
|
||||||
{
|
|
||||||
if(mReader != nullptr) delete mReader;
|
|
||||||
// Clear() is accounting if data already is deleted. So, just check again if all data is deleted.
|
|
||||||
Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************************************************/
|
|
||||||
/************************************************************ Functions: find set ************************************************************/
|
|
||||||
/*********************************************************************************************************************************************/
|
|
||||||
|
|
||||||
bool AMFImporter::Find_NodeElement(const std::string& pID, const CAMFImporter_NodeElement::EType pType, CAMFImporter_NodeElement** pNodeElement) const
|
|
||||||
{
|
|
||||||
for(CAMFImporter_NodeElement* ne: mNodeElement_List)
|
|
||||||
{
|
|
||||||
if((ne->ID == pID) && (ne->Type == pType))
|
|
||||||
{
|
|
||||||
if(pNodeElement != nullptr) *pNodeElement = ne;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}// for(CAMFImporter_NodeElement* ne: mNodeElement_List)
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AMFImporter::Find_ConvertedNode(const std::string& pID, std::list<aiNode*>& pNodeList, aiNode** pNode) const
|
|
||||||
{
|
|
||||||
aiString node_name(pID.c_str());
|
|
||||||
|
|
||||||
for(aiNode* node: pNodeList)
|
|
||||||
{
|
|
||||||
if(node->mName == node_name)
|
|
||||||
{
|
|
||||||
if(pNode != nullptr) *pNode = node;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}// for(aiNode* node: pNodeList)
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AMFImporter::Find_ConvertedMaterial(const std::string& pID, const SPP_Material** pConvertedMaterial) const
|
|
||||||
{
|
|
||||||
for(const SPP_Material& mat: mMaterial_Converted)
|
|
||||||
{
|
|
||||||
if(mat.ID == pID)
|
|
||||||
{
|
|
||||||
if(pConvertedMaterial != nullptr) *pConvertedMaterial = &mat;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}// for(const SPP_Material& mat: mMaterial_Converted)
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************************************************/
|
|
||||||
/************************************************************ Functions: throw set ***********************************************************/
|
|
||||||
/*********************************************************************************************************************************************/
|
|
||||||
|
|
||||||
void AMFImporter::Throw_CloseNotFound(const std::string& pNode)
|
|
||||||
{
|
|
||||||
throw DeadlyImportError("Close tag for node <" + pNode + "> not found. Seems file is corrupt.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void AMFImporter::Throw_IncorrectAttr(const std::string& pAttrName)
|
|
||||||
{
|
|
||||||
throw DeadlyImportError("Node <" + std::string(mReader->getNodeName()) + "> has incorrect attribute \"" + pAttrName + "\".");
|
|
||||||
}
|
|
||||||
|
|
||||||
void AMFImporter::Throw_IncorrectAttrValue(const std::string& pAttrName)
|
|
||||||
{
|
|
||||||
throw DeadlyImportError("Attribute \"" + pAttrName + "\" in node <" + std::string(mReader->getNodeName()) + "> has incorrect value.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void AMFImporter::Throw_MoreThanOnceDefined(const std::string& pNodeType, const std::string& pDescription)
|
|
||||||
{
|
|
||||||
throw DeadlyImportError("\"" + pNodeType + "\" node can be used only once in " + mReader->getNodeName() + ". Description: " + pDescription);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AMFImporter::Throw_ID_NotFound(const std::string& pID) const
|
|
||||||
{
|
|
||||||
throw DeadlyImportError("Not found node with name \"" + pID + "\".");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************************************************/
|
|
||||||
/************************************************************* Functions: XML set ************************************************************/
|
|
||||||
/*********************************************************************************************************************************************/
|
|
||||||
|
|
||||||
void AMFImporter::XML_CheckNode_MustHaveChildren()
|
|
||||||
{
|
|
||||||
if(mReader->isEmptyElement()) throw DeadlyImportError(std::string("Node <") + mReader->getNodeName() + "> must have children.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void AMFImporter::XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName)
|
|
||||||
{
|
|
||||||
static const size_t Uns_Skip_Len = 3;
|
|
||||||
const char* Uns_Skip[Uns_Skip_Len] = { "composite", "edge", "normal" };
|
|
||||||
|
|
||||||
static bool skipped_before[Uns_Skip_Len] = { false, false, false };
|
|
||||||
|
|
||||||
std::string nn(mReader->getNodeName());
|
|
||||||
bool found = false;
|
|
||||||
bool close_found = false;
|
|
||||||
size_t sk_idx;
|
|
||||||
|
|
||||||
for(sk_idx = 0; sk_idx < Uns_Skip_Len; sk_idx++)
|
|
||||||
{
|
|
||||||
if(nn != Uns_Skip[sk_idx]) continue;
|
|
||||||
|
|
||||||
found = true;
|
|
||||||
if(mReader->isEmptyElement())
|
|
||||||
{
|
|
||||||
close_found = true;
|
|
||||||
|
|
||||||
goto casu_cres;
|
|
||||||
}
|
|
||||||
|
|
||||||
while(mReader->read())
|
|
||||||
{
|
|
||||||
if((mReader->getNodeType() == irr::io::EXN_ELEMENT_END) && (nn == mReader->getNodeName()))
|
|
||||||
{
|
|
||||||
close_found = true;
|
|
||||||
|
|
||||||
goto casu_cres;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}// for(sk_idx = 0; sk_idx < Uns_Skip_Len; sk_idx++)
|
|
||||||
|
|
||||||
casu_cres:
|
|
||||||
|
|
||||||
if(!found) throw DeadlyImportError("Unknown node \"" + nn + "\" in " + pParentNodeName + ".");
|
|
||||||
if(!close_found) Throw_CloseNotFound(nn);
|
|
||||||
|
|
||||||
if(!skipped_before[sk_idx])
|
|
||||||
{
|
|
||||||
skipped_before[sk_idx] = true;
|
|
||||||
ASSIMP_LOG_WARN_F("Skipping node \"", nn, "\" in ", pParentNodeName, ".");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AMFImporter::XML_SearchNode(const std::string& pNodeName)
|
|
||||||
{
|
|
||||||
while(mReader->read())
|
|
||||||
{
|
|
||||||
if((mReader->getNodeType() == irr::io::EXN_ELEMENT) && XML_CheckNode_NameEqual(pNodeName)) return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AMFImporter::XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx)
|
|
||||||
{
|
|
||||||
std::string val(mReader->getAttributeValue(pAttrIdx));
|
|
||||||
|
|
||||||
if((val == "false") || (val == "0"))
|
|
||||||
return false;
|
|
||||||
else if((val == "true") || (val == "1"))
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
throw DeadlyImportError("Bool attribute value can contain \"false\"/\"0\" or \"true\"/\"1\" not the \"" + val + "\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
float AMFImporter::XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx)
|
|
||||||
{
|
|
||||||
std::string val;
|
|
||||||
float tvalf;
|
|
||||||
|
|
||||||
ParseHelper_FixTruncatedFloatString(mReader->getAttributeValue(pAttrIdx), val);
|
|
||||||
fast_atoreal_move(val.c_str(), tvalf, false);
|
|
||||||
|
|
||||||
return tvalf;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t AMFImporter::XML_ReadNode_GetAttrVal_AsU32(const int pAttrIdx)
|
|
||||||
{
|
|
||||||
return strtoul10(mReader->getAttributeValue(pAttrIdx));
|
|
||||||
}
|
|
||||||
|
|
||||||
float AMFImporter::XML_ReadNode_GetVal_AsFloat()
|
|
||||||
{
|
|
||||||
std::string val;
|
|
||||||
float tvalf;
|
|
||||||
|
|
||||||
if(!mReader->read()) throw DeadlyImportError("XML_ReadNode_GetVal_AsFloat. No data, seems file is corrupt.");
|
|
||||||
if(mReader->getNodeType() != irr::io::EXN_TEXT) throw DeadlyImportError("XML_ReadNode_GetVal_AsFloat. Invalid type of XML element, seems file is corrupt.");
|
|
||||||
|
|
||||||
ParseHelper_FixTruncatedFloatString(mReader->getNodeData(), val);
|
|
||||||
fast_atoreal_move(val.c_str(), tvalf, false);
|
|
||||||
|
|
||||||
return tvalf;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t AMFImporter::XML_ReadNode_GetVal_AsU32()
|
|
||||||
{
|
|
||||||
if(!mReader->read()) throw DeadlyImportError("XML_ReadNode_GetVal_AsU32. No data, seems file is corrupt.");
|
|
||||||
if(mReader->getNodeType() != irr::io::EXN_TEXT) throw DeadlyImportError("XML_ReadNode_GetVal_AsU32. Invalid type of XML element, seems file is corrupt.");
|
|
||||||
|
|
||||||
return strtoul10(mReader->getNodeData());
|
|
||||||
}
|
|
||||||
|
|
||||||
void AMFImporter::XML_ReadNode_GetVal_AsString(std::string& pValue)
|
|
||||||
{
|
|
||||||
if(!mReader->read()) throw DeadlyImportError("XML_ReadNode_GetVal_AsString. No data, seems file is corrupt.");
|
|
||||||
if(mReader->getNodeType() != irr::io::EXN_TEXT)
|
|
||||||
throw DeadlyImportError("XML_ReadNode_GetVal_AsString. Invalid type of XML element, seems file is corrupt.");
|
|
||||||
|
|
||||||
pValue = mReader->getNodeData();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************************************************/
|
|
||||||
/************************************************************ Functions: parse set ***********************************************************/
|
|
||||||
/*********************************************************************************************************************************************/
|
|
||||||
|
|
||||||
void AMFImporter::ParseHelper_Node_Enter(CAMFImporter_NodeElement* pNode)
|
|
||||||
{
|
|
||||||
mNodeElement_Cur->Child.push_back(pNode);// add new element to current element child list.
|
|
||||||
mNodeElement_Cur = pNode;// switch current element to new one.
|
|
||||||
}
|
|
||||||
|
|
||||||
void AMFImporter::ParseHelper_Node_Exit()
|
|
||||||
{
|
|
||||||
// check if we can walk up.
|
|
||||||
if(mNodeElement_Cur != nullptr) mNodeElement_Cur = mNodeElement_Cur->Parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AMFImporter::ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString)
|
|
||||||
{
|
|
||||||
size_t instr_len;
|
|
||||||
|
|
||||||
pOutString.clear();
|
|
||||||
instr_len = strlen(pInStr);
|
|
||||||
if(!instr_len) return;
|
|
||||||
|
|
||||||
pOutString.reserve(instr_len * 3 / 2);
|
|
||||||
// check and correct floats in format ".x". Must be "x.y".
|
|
||||||
if(pInStr[0] == '.') pOutString.push_back('0');
|
|
||||||
|
|
||||||
pOutString.push_back(pInStr[0]);
|
|
||||||
for(size_t ci = 1; ci < instr_len; ci++)
|
|
||||||
{
|
|
||||||
if((pInStr[ci] == '.') && ((pInStr[ci - 1] == ' ') || (pInStr[ci - 1] == '-') || (pInStr[ci - 1] == '+') || (pInStr[ci - 1] == '\t')))
|
|
||||||
{
|
|
||||||
pOutString.push_back('0');
|
|
||||||
pOutString.push_back('.');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pOutString.push_back(pInStr[ci]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ParseHelper_Decode_Base64_IsBase64(const char pChar)
|
|
||||||
{
|
|
||||||
return (isalnum(pChar) || (pChar == '+') || (pChar == '/'));
|
|
||||||
}
|
|
||||||
|
|
||||||
void AMFImporter::ParseHelper_Decode_Base64(const std::string& pInputBase64, std::vector<uint8_t>& pOutputData) const
|
|
||||||
{
|
|
||||||
// With help from
|
|
||||||
// René Nyffenegger http://www.adp-gmbh.ch/cpp/common/base64.html
|
|
||||||
const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
||||||
|
|
||||||
uint8_t tidx = 0;
|
|
||||||
uint8_t arr4[4], arr3[3];
|
|
||||||
|
|
||||||
// check input data
|
|
||||||
if(pInputBase64.size() % 4) throw DeadlyImportError("Base64-encoded data must have size multiply of four.");
|
|
||||||
// prepare output place
|
|
||||||
pOutputData.clear();
|
|
||||||
pOutputData.reserve(pInputBase64.size() / 4 * 3);
|
|
||||||
|
|
||||||
for(size_t in_len = pInputBase64.size(), in_idx = 0; (in_len > 0) && (pInputBase64[in_idx] != '='); in_len--)
|
|
||||||
{
|
|
||||||
if(ParseHelper_Decode_Base64_IsBase64(pInputBase64[in_idx]))
|
|
||||||
{
|
|
||||||
arr4[tidx++] = pInputBase64[in_idx++];
|
|
||||||
if(tidx == 4)
|
|
||||||
{
|
|
||||||
for(tidx = 0; tidx < 4; tidx++) arr4[tidx] = (uint8_t)base64_chars.find(arr4[tidx]);
|
|
||||||
|
|
||||||
arr3[0] = (arr4[0] << 2) + ((arr4[1] & 0x30) >> 4);
|
|
||||||
arr3[1] = ((arr4[1] & 0x0F) << 4) + ((arr4[2] & 0x3C) >> 2);
|
|
||||||
arr3[2] = ((arr4[2] & 0x03) << 6) + arr4[3];
|
|
||||||
for(tidx = 0; tidx < 3; tidx++) pOutputData.push_back(arr3[tidx]);
|
|
||||||
|
|
||||||
tidx = 0;
|
|
||||||
}// if(tidx == 4)
|
|
||||||
}// if(ParseHelper_Decode_Base64_IsBase64(pInputBase64[in_idx]))
|
|
||||||
else
|
|
||||||
{
|
|
||||||
in_idx++;
|
|
||||||
}// if(ParseHelper_Decode_Base64_IsBase64(pInputBase64[in_idx])) else
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tidx)
|
|
||||||
{
|
|
||||||
for(uint8_t i = tidx; i < 4; i++) arr4[i] = 0;
|
|
||||||
for(uint8_t i = 0; i < 4; i++) arr4[i] = (uint8_t)(base64_chars.find(arr4[i]));
|
|
||||||
|
|
||||||
arr3[0] = (arr4[0] << 2) + ((arr4[1] & 0x30) >> 4);
|
|
||||||
arr3[1] = ((arr4[1] & 0x0F) << 4) + ((arr4[2] & 0x3C) >> 2);
|
|
||||||
arr3[2] = ((arr4[2] & 0x03) << 6) + arr4[3];
|
|
||||||
for(uint8_t i = 0; i < (tidx - 1); i++) pOutputData.push_back(arr3[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AMFImporter::ParseFile(const std::string& pFile, IOSystem* pIOHandler)
|
|
||||||
{
|
|
||||||
irr::io::IrrXMLReader* OldReader = mReader;// store current XMLreader.
|
|
||||||
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
|
|
||||||
|
|
||||||
// Check whether we can read from the file
|
|
||||||
if (file.get() == nullptr) {
|
|
||||||
throw DeadlyImportError("Failed to open AMF file " + pFile + ".");
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate a XML reader for it
|
|
||||||
std::unique_ptr<CIrrXML_IOStreamReader> mIOWrapper(new CIrrXML_IOStreamReader(file.get()));
|
|
||||||
mReader = irr::io::createIrrXMLReader(mIOWrapper.get());
|
|
||||||
if(!mReader) throw DeadlyImportError("Failed to create XML reader for file" + pFile + ".");
|
|
||||||
//
|
|
||||||
// start reading
|
|
||||||
// search for root tag <amf>
|
|
||||||
if(XML_SearchNode("amf"))
|
|
||||||
ParseNode_Root();
|
|
||||||
else
|
|
||||||
throw DeadlyImportError("Root node \"amf\" not found.");
|
|
||||||
|
|
||||||
delete mReader;
|
|
||||||
// restore old XMLreader
|
|
||||||
mReader = OldReader;
|
|
||||||
}
|
|
||||||
|
|
||||||
// <amf
|
|
||||||
// unit="" - The units to be used. May be "inch", "millimeter", "meter", "feet", or "micron".
|
|
||||||
// version="" - Version of file format.
|
|
||||||
// >
|
|
||||||
// </amf>
|
|
||||||
// Root XML element.
|
|
||||||
// Multi elements - No.
|
|
||||||
void AMFImporter::ParseNode_Root()
|
|
||||||
{
|
|
||||||
std::string unit, version;
|
|
||||||
CAMFImporter_NodeElement *ne( nullptr );
|
|
||||||
|
|
||||||
// Read attributes for node <amf>.
|
|
||||||
MACRO_ATTRREAD_LOOPBEG;
|
|
||||||
MACRO_ATTRREAD_CHECK_RET("unit", unit, mReader->getAttributeValue);
|
|
||||||
MACRO_ATTRREAD_CHECK_RET("version", version, mReader->getAttributeValue);
|
|
||||||
MACRO_ATTRREAD_LOOPEND_WSKIP;
|
|
||||||
|
|
||||||
// Check attributes
|
|
||||||
if(!mUnit.empty())
|
|
||||||
{
|
|
||||||
if((mUnit != "inch") && (mUnit != "millimeter") && (mUnit != "meter") && (mUnit != "feet") && (mUnit != "micron")) Throw_IncorrectAttrValue("unit");
|
|
||||||
}
|
|
||||||
|
|
||||||
// create root node element.
|
|
||||||
ne = new CAMFImporter_NodeElement_Root(nullptr);
|
|
||||||
mNodeElement_Cur = ne;// set first "current" element
|
|
||||||
// and assign attribute's values
|
|
||||||
((CAMFImporter_NodeElement_Root*)ne)->Unit = unit;
|
|
||||||
((CAMFImporter_NodeElement_Root*)ne)->Version = version;
|
|
||||||
|
|
||||||
// Check for child nodes
|
|
||||||
if(!mReader->isEmptyElement())
|
|
||||||
{
|
|
||||||
MACRO_NODECHECK_LOOPBEGIN("amf");
|
|
||||||
if(XML_CheckNode_NameEqual("object")) { ParseNode_Object(); continue; }
|
|
||||||
if(XML_CheckNode_NameEqual("material")) { ParseNode_Material(); continue; }
|
|
||||||
if(XML_CheckNode_NameEqual("texture")) { ParseNode_Texture(); continue; }
|
|
||||||
if(XML_CheckNode_NameEqual("constellation")) { ParseNode_Constellation(); continue; }
|
|
||||||
if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
|
|
||||||
MACRO_NODECHECK_LOOPEND("amf");
|
|
||||||
mNodeElement_Cur = ne;// force restore "current" element
|
|
||||||
}// if(!mReader->isEmptyElement())
|
|
||||||
|
|
||||||
mNodeElement_List.push_back(ne);// add to node element list because its a new object in graph.
|
|
||||||
}
|
|
||||||
|
|
||||||
// <constellation
|
|
||||||
// id="" - The Object ID of the new constellation being defined.
|
|
||||||
// >
|
|
||||||
// </constellation>
|
|
||||||
// A collection of objects or constellations with specific relative locations.
|
|
||||||
// Multi elements - Yes.
|
|
||||||
// Parent element - <amf>.
|
|
||||||
void AMFImporter::ParseNode_Constellation()
|
|
||||||
{
|
|
||||||
std::string id;
|
|
||||||
CAMFImporter_NodeElement* ne( nullptr );
|
|
||||||
|
|
||||||
// Read attributes for node <constellation>.
|
|
||||||
MACRO_ATTRREAD_LOOPBEG;
|
|
||||||
MACRO_ATTRREAD_CHECK_RET("id", id, mReader->getAttributeValue);
|
|
||||||
MACRO_ATTRREAD_LOOPEND;
|
|
||||||
|
|
||||||
// create and if needed - define new grouping object.
|
|
||||||
ne = new CAMFImporter_NodeElement_Constellation(mNodeElement_Cur);
|
|
||||||
|
|
||||||
CAMFImporter_NodeElement_Constellation& als = *((CAMFImporter_NodeElement_Constellation*)ne);// alias for convenience
|
|
||||||
|
|
||||||
if(!id.empty()) als.ID = id;
|
|
||||||
// Check for child nodes
|
|
||||||
if(!mReader->isEmptyElement())
|
|
||||||
{
|
|
||||||
ParseHelper_Node_Enter(ne);
|
|
||||||
MACRO_NODECHECK_LOOPBEGIN("constellation");
|
|
||||||
if(XML_CheckNode_NameEqual("instance")) { ParseNode_Instance(); continue; }
|
|
||||||
if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
|
|
||||||
MACRO_NODECHECK_LOOPEND("constellation");
|
|
||||||
ParseHelper_Node_Exit();
|
|
||||||
}// if(!mReader->isEmptyElement())
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
|
||||||
}// if(!mReader->isEmptyElement()) else
|
|
||||||
|
|
||||||
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
|
||||||
}
|
|
||||||
|
|
||||||
// <instance
|
|
||||||
// objectid="" - The Object ID of the new constellation being defined.
|
|
||||||
// >
|
|
||||||
// </instance>
|
|
||||||
// A collection of objects or constellations with specific relative locations.
|
|
||||||
// Multi elements - Yes.
|
|
||||||
// Parent element - <amf>.
|
|
||||||
void AMFImporter::ParseNode_Instance()
|
|
||||||
{
|
|
||||||
std::string objectid;
|
|
||||||
CAMFImporter_NodeElement* ne( nullptr );
|
|
||||||
|
|
||||||
// Read attributes for node <constellation>.
|
|
||||||
MACRO_ATTRREAD_LOOPBEG;
|
|
||||||
MACRO_ATTRREAD_CHECK_RET("objectid", objectid, mReader->getAttributeValue);
|
|
||||||
MACRO_ATTRREAD_LOOPEND;
|
|
||||||
|
|
||||||
// used object id must be defined, check that.
|
|
||||||
if(objectid.empty()) throw DeadlyImportError("\"objectid\" in <instance> must be defined.");
|
|
||||||
// create and define new grouping object.
|
|
||||||
ne = new CAMFImporter_NodeElement_Instance(mNodeElement_Cur);
|
|
||||||
|
|
||||||
CAMFImporter_NodeElement_Instance& als = *((CAMFImporter_NodeElement_Instance*)ne);// alias for convenience
|
|
||||||
|
|
||||||
als.ObjectID = objectid;
|
|
||||||
// Check for child nodes
|
|
||||||
if(!mReader->isEmptyElement())
|
|
||||||
{
|
|
||||||
bool read_flag[6] = { false, false, false, false, false, false };
|
|
||||||
|
|
||||||
als.Delta.Set(0, 0, 0);
|
|
||||||
als.Rotation.Set(0, 0, 0);
|
|
||||||
ParseHelper_Node_Enter(ne);
|
|
||||||
MACRO_NODECHECK_LOOPBEGIN("instance");
|
|
||||||
MACRO_NODECHECK_READCOMP_F("deltax", read_flag[0], als.Delta.x);
|
|
||||||
MACRO_NODECHECK_READCOMP_F("deltay", read_flag[1], als.Delta.y);
|
|
||||||
MACRO_NODECHECK_READCOMP_F("deltaz", read_flag[2], als.Delta.z);
|
|
||||||
MACRO_NODECHECK_READCOMP_F("rx", read_flag[3], als.Rotation.x);
|
|
||||||
MACRO_NODECHECK_READCOMP_F("ry", read_flag[4], als.Rotation.y);
|
|
||||||
MACRO_NODECHECK_READCOMP_F("rz", read_flag[5], als.Rotation.z);
|
|
||||||
MACRO_NODECHECK_LOOPEND("instance");
|
|
||||||
ParseHelper_Node_Exit();
|
|
||||||
// also convert degrees to radians.
|
|
||||||
als.Rotation.x = AI_MATH_PI_F * als.Rotation.x / 180.0f;
|
|
||||||
als.Rotation.y = AI_MATH_PI_F * als.Rotation.y / 180.0f;
|
|
||||||
als.Rotation.z = AI_MATH_PI_F * als.Rotation.z / 180.0f;
|
|
||||||
}// if(!mReader->isEmptyElement())
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
|
||||||
}// if(!mReader->isEmptyElement()) else
|
|
||||||
|
|
||||||
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
|
||||||
}
|
|
||||||
|
|
||||||
// <object
|
|
||||||
// id="" - A unique ObjectID for the new object being defined.
|
|
||||||
// >
|
|
||||||
// </object>
|
|
||||||
// An object definition.
|
|
||||||
// Multi elements - Yes.
|
|
||||||
// Parent element - <amf>.
|
|
||||||
void AMFImporter::ParseNode_Object()
|
|
||||||
{
|
|
||||||
std::string id;
|
|
||||||
CAMFImporter_NodeElement* ne( nullptr );
|
|
||||||
|
|
||||||
// Read attributes for node <object>.
|
|
||||||
MACRO_ATTRREAD_LOOPBEG;
|
|
||||||
MACRO_ATTRREAD_CHECK_RET("id", id, mReader->getAttributeValue);
|
|
||||||
MACRO_ATTRREAD_LOOPEND;
|
|
||||||
|
|
||||||
// create and if needed - define new geometry object.
|
|
||||||
ne = new CAMFImporter_NodeElement_Object(mNodeElement_Cur);
|
|
||||||
|
|
||||||
CAMFImporter_NodeElement_Object& als = *((CAMFImporter_NodeElement_Object*)ne);// alias for convenience
|
|
||||||
|
|
||||||
if(!id.empty()) als.ID = id;
|
|
||||||
// Check for child nodes
|
|
||||||
if(!mReader->isEmptyElement())
|
|
||||||
{
|
|
||||||
bool col_read = false;
|
|
||||||
|
|
||||||
ParseHelper_Node_Enter(ne);
|
|
||||||
MACRO_NODECHECK_LOOPBEGIN("object");
|
|
||||||
if(XML_CheckNode_NameEqual("color"))
|
|
||||||
{
|
|
||||||
// Check if color already defined for object.
|
|
||||||
if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <object>.");
|
|
||||||
// read data and set flag about it
|
|
||||||
ParseNode_Color();
|
|
||||||
col_read = true;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(XML_CheckNode_NameEqual("mesh")) { ParseNode_Mesh(); continue; }
|
|
||||||
if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
|
|
||||||
MACRO_NODECHECK_LOOPEND("object");
|
|
||||||
ParseHelper_Node_Exit();
|
|
||||||
}// if(!mReader->isEmptyElement())
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
|
||||||
}// if(!mReader->isEmptyElement()) else
|
|
||||||
|
|
||||||
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
|
||||||
}
|
|
||||||
|
|
||||||
// <metadata
|
|
||||||
// type="" - The type of the attribute.
|
|
||||||
// >
|
|
||||||
// </metadata>
|
|
||||||
// Specify additional information about an entity.
|
|
||||||
// Multi elements - Yes.
|
|
||||||
// Parent element - <amf>, <object>, <volume>, <material>, <vertex>.
|
|
||||||
//
|
|
||||||
// Reserved types are:
|
|
||||||
// "Name" - The alphanumeric label of the entity, to be used by the interpreter if interacting with the user.
|
|
||||||
// "Description" - A description of the content of the entity
|
|
||||||
// "URL" - A link to an external resource relating to the entity
|
|
||||||
// "Author" - Specifies the name(s) of the author(s) of the entity
|
|
||||||
// "Company" - Specifying the company generating the entity
|
|
||||||
// "CAD" - specifies the name of the originating CAD software and version
|
|
||||||
// "Revision" - specifies the revision of the entity
|
|
||||||
// "Tolerance" - specifies the desired manufacturing tolerance of the entity in entity's unit system
|
|
||||||
// "Volume" - specifies the total volume of the entity, in the entity's unit system, to be used for verification (object and volume only)
|
|
||||||
void AMFImporter::ParseNode_Metadata()
|
|
||||||
{
|
|
||||||
std::string type, value;
|
|
||||||
CAMFImporter_NodeElement* ne( nullptr );
|
|
||||||
|
|
||||||
// read attribute
|
|
||||||
MACRO_ATTRREAD_LOOPBEG;
|
|
||||||
MACRO_ATTRREAD_CHECK_RET("type", type, mReader->getAttributeValue);
|
|
||||||
MACRO_ATTRREAD_LOOPEND;
|
|
||||||
// and value of node.
|
|
||||||
value = mReader->getNodeData();
|
|
||||||
// Create node element and assign read data.
|
|
||||||
ne = new CAMFImporter_NodeElement_Metadata(mNodeElement_Cur);
|
|
||||||
((CAMFImporter_NodeElement_Metadata*)ne)->Type = type;
|
|
||||||
((CAMFImporter_NodeElement_Metadata*)ne)->Value = value;
|
|
||||||
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
|
||||||
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************************************************/
|
|
||||||
/******************************************************** Functions: BaseImporter set ********************************************************/
|
|
||||||
/*********************************************************************************************************************************************/
|
|
||||||
|
|
||||||
bool AMFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool pCheckSig) const
|
|
||||||
{
|
|
||||||
const std::string extension = GetExtension(pFile);
|
|
||||||
|
|
||||||
if ( extension == "amf" ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!extension.length() || pCheckSig)
|
|
||||||
{
|
|
||||||
const char* tokens[] = { "<amf" };
|
|
||||||
|
|
||||||
return SearchFileHeaderForToken( pIOHandler, pFile, tokens, 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AMFImporter::GetExtensionList(std::set<std::string>& pExtensionList)
|
|
||||||
{
|
|
||||||
pExtensionList.insert("amf");
|
|
||||||
}
|
|
||||||
|
|
||||||
const aiImporterDesc* AMFImporter::GetInfo () const
|
|
||||||
{
|
|
||||||
return &Description;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AMFImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
|
|
||||||
{
|
|
||||||
Clear();// delete old graph.
|
|
||||||
ParseFile(pFile, pIOHandler);
|
|
||||||
Postprocess_BuildScene(pScene);
|
|
||||||
// scene graph is ready, exit.
|
|
||||||
}
|
|
||||||
|
|
||||||
}// namespace Assimp
|
|
||||||
|
|
||||||
#endif // !ASSIMP_BUILD_NO_AMF_IMPORTER
|
|
|
@ -321,7 +321,7 @@ public:
|
||||||
struct Face : public FaceWithSmoothingGroup {
|
struct Face : public FaceWithSmoothingGroup {
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if _MSC_VER > 1920
|
||||||
#pragma warning(disable : 4315)
|
#pragma warning(disable : 4315)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1996,19 +1996,19 @@ void FBXConverter::SetTextureProperties(aiMaterial *out_mat, const TextureMap &_
|
||||||
TrySetTextureProperties(out_mat, _textures, "Maya|ReflectionMapTexture", aiTextureType_REFLECTION, mesh);
|
TrySetTextureProperties(out_mat, _textures, "Maya|ReflectionMapTexture", aiTextureType_REFLECTION, mesh);
|
||||||
|
|
||||||
// Maya PBR
|
// Maya PBR
|
||||||
TrySetTextureProperties(out_mat, _textures, "Maya|baseColor|file", aiTextureType_BASE_COLOR, mesh);
|
TrySetTextureProperties(out_mat, _textures, "Maya|baseColor", aiTextureType_BASE_COLOR, mesh);
|
||||||
TrySetTextureProperties(out_mat, _textures, "Maya|normalCamera|file", aiTextureType_NORMAL_CAMERA, mesh);
|
TrySetTextureProperties(out_mat, _textures, "Maya|normalCamera", aiTextureType_NORMAL_CAMERA, mesh);
|
||||||
TrySetTextureProperties(out_mat, _textures, "Maya|emissionColor|file", aiTextureType_EMISSION_COLOR, mesh);
|
TrySetTextureProperties(out_mat, _textures, "Maya|emissionColor", aiTextureType_EMISSION_COLOR, mesh);
|
||||||
TrySetTextureProperties(out_mat, _textures, "Maya|metalness|file", aiTextureType_METALNESS, mesh);
|
TrySetTextureProperties(out_mat, _textures, "Maya|metalness", aiTextureType_METALNESS, mesh);
|
||||||
TrySetTextureProperties(out_mat, _textures, "Maya|diffuseRoughness|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
|
TrySetTextureProperties(out_mat, _textures, "Maya|diffuseRoughness", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
|
||||||
|
|
||||||
// Maya stingray
|
// Maya stingray
|
||||||
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_color_map|file", aiTextureType_BASE_COLOR, mesh);
|
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_color_map", aiTextureType_BASE_COLOR, mesh);
|
||||||
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_normal_map|file", aiTextureType_NORMAL_CAMERA, mesh);
|
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_normal_map", aiTextureType_NORMAL_CAMERA, mesh);
|
||||||
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_emissive_map|file", aiTextureType_EMISSION_COLOR, mesh);
|
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_emissive_map", aiTextureType_EMISSION_COLOR, mesh);
|
||||||
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_metallic_map|file", aiTextureType_METALNESS, mesh);
|
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_metallic_map", aiTextureType_METALNESS, mesh);
|
||||||
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_roughness_map|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
|
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_roughness_map", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
|
||||||
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_ao_map|file", aiTextureType_AMBIENT_OCCLUSION, mesh);
|
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_ao_map", aiTextureType_AMBIENT_OCCLUSION, mesh);
|
||||||
|
|
||||||
// 3DSMax PBR
|
// 3DSMax PBR
|
||||||
TrySetTextureProperties(out_mat, _textures, "3dsMax|Parameters|base_color_map", aiTextureType_BASE_COLOR, mesh);
|
TrySetTextureProperties(out_mat, _textures, "3dsMax|Parameters|base_color_map", aiTextureType_BASE_COLOR, mesh);
|
||||||
|
|
|
@ -45,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "AssetLib/Step/STEPFile.h"
|
#include "AssetLib/Step/STEPFile.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if _MSC_VER > 1920
|
||||||
# pragma warning( disable : 4512 )
|
# pragma warning( disable : 4512 )
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,9 @@ typedef uint16_t M3D_INDEX;
|
||||||
#define M3D_BONEMAXLEVEL 8
|
#define M3D_BONEMAXLEVEL 8
|
||||||
#endif
|
#endif
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
|
#ifndef _inline
|
||||||
#define _inline __inline__
|
#define _inline __inline__
|
||||||
|
#endif
|
||||||
#define _pack __attribute__((packed))
|
#define _pack __attribute__((packed))
|
||||||
#define _unused __attribute__((unused))
|
#define _unused __attribute__((unused))
|
||||||
#else
|
#else
|
||||||
|
@ -99,7 +101,7 @@ typedef uint16_t M3D_INDEX;
|
||||||
#define _register
|
#define _register
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if _MSC_VER > 1920
|
||||||
# pragma warning(push)
|
# pragma warning(push)
|
||||||
# pragma warning(disable : 4100 4127 4189 4505 4244 4403 4701 4703)
|
# pragma warning(disable : 4100 4127 4189 4505 4244 4403 4701 4703)
|
||||||
# if (_MSC_VER > 1800 )
|
# if (_MSC_VER > 1800 )
|
||||||
|
|
|
@ -68,7 +68,7 @@ namespace Assimp {
|
||||||
namespace MDL {
|
namespace MDL {
|
||||||
namespace HalfLife {
|
namespace HalfLife {
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if _MSC_VER > 1920
|
||||||
# pragma warning(disable : 4706)
|
# pragma warning(disable : 4706)
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
|
@ -829,7 +829,7 @@ void HL1MDLLoader::read_meshes() {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int faceIdx = 0; faceIdx < num_faces; ++faceIdx) {
|
for (int faceIdx = 0; faceIdx < num_faces; ++faceIdx) {
|
||||||
if (i & 1) {
|
if (faceIdx & 1) {
|
||||||
// Preserve winding order.
|
// Preserve winding order.
|
||||||
mesh_faces.push_back(HL1MeshFace{
|
mesh_faces.push_back(HL1MeshFace{
|
||||||
tricmds[faceIdx + 1],
|
tricmds[faceIdx + 1],
|
||||||
|
|
|
@ -54,7 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if _MSC_VER > 1920
|
||||||
# pragma warning(push)
|
# pragma warning(push)
|
||||||
# pragma warning(disable : 4127 4456 4245 4512 )
|
# pragma warning(disable : 4127 4456 4245 4512 )
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
@ -727,7 +727,7 @@ struct InternGenericConvert<Maybe<T>> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if _MSC_VER > 1920
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 4127)
|
#pragma warning(disable : 4127)
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
@ -960,7 +960,7 @@ private:
|
||||||
const EXPRESS::ConversionSchema *schema;
|
const EXPRESS::ConversionSchema *schema;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if _MSC_VER > 1920
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
|
|
|
@ -1079,7 +1079,7 @@ ASSIMP_API void aiMatrix4DecomposeIntoScalingAxisAnglePosition(
|
||||||
const C_STRUCT aiMatrix4x4 *mat,
|
const C_STRUCT aiMatrix4x4 *mat,
|
||||||
C_STRUCT aiVector3D *scaling,
|
C_STRUCT aiVector3D *scaling,
|
||||||
C_STRUCT aiVector3D *axis,
|
C_STRUCT aiVector3D *axis,
|
||||||
float *angle,
|
ai_real *angle,
|
||||||
C_STRUCT aiVector3D *position) {
|
C_STRUCT aiVector3D *position) {
|
||||||
ai_assert(nullptr != mat);
|
ai_assert(nullptr != mat);
|
||||||
ai_assert(nullptr != scaling);
|
ai_assert(nullptr != scaling);
|
||||||
|
|
|
@ -74,7 +74,7 @@ Here we implement only the C++ interface (Assimp::Exporter).
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if _MSC_VER > 1920
|
||||||
# pragma warning( disable : 4800 )
|
# pragma warning( disable : 4800 )
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
|
|
|
@ -208,13 +208,14 @@ BinFloat ToBinary(const ai_real &pValue) {
|
||||||
// floating-point numbers are of sign-magnitude format, so find out what signed number
|
// floating-point numbers are of sign-magnitude format, so find out what signed number
|
||||||
// representation we must convert negative values to.
|
// representation we must convert negative values to.
|
||||||
// See http://en.wikipedia.org/wiki/Signed_number_representations.
|
// See http://en.wikipedia.org/wiki/Signed_number_representations.
|
||||||
|
const BinFloat mask = BinFloat(1) << (CHAR_BIT * sizeof(BinFloat) - 1);
|
||||||
|
|
||||||
// Two's complement?
|
// Two's complement?
|
||||||
const bool DefaultValue = ((-42 == (~42 + 1)) && (binValue & 0x80000000));
|
const bool DefaultValue = ((-42 == (~42 + 1)) && (binValue & mask));
|
||||||
const bool OneComplement = ((-42 == ~42) && (binValue & 0x80000000));
|
const bool OneComplement = ((-42 == ~42) && (binValue & mask));
|
||||||
|
|
||||||
if (DefaultValue)
|
if (DefaultValue)
|
||||||
return BinFloat(1 << (CHAR_BIT * sizeof(BinFloat) - 1)) - binValue;
|
return mask - binValue;
|
||||||
// One's complement?
|
// One's complement?
|
||||||
else if (OneComplement)
|
else if (OneComplement)
|
||||||
return BinFloat(-0) - binValue;
|
return BinFloat(-0) - binValue;
|
||||||
|
|
|
@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
void mydummy() {}
|
void mydummy() {}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if _MSC_VER > 1920
|
||||||
#pragma warning(disable : 4709)
|
#pragma warning(disable : 4709)
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -168,7 +168,6 @@ void ArmaturePopulate::BuildBoneStack(aiNode *,
|
||||||
const std::vector<aiBone *> &bones,
|
const std::vector<aiBone *> &bones,
|
||||||
std::map<aiBone *, aiNode *> &bone_stack,
|
std::map<aiBone *, aiNode *> &bone_stack,
|
||||||
std::vector<aiNode *> &node_stack) {
|
std::vector<aiNode *> &node_stack) {
|
||||||
ai_assert(scene);
|
|
||||||
ai_assert(root_node);
|
ai_assert(root_node);
|
||||||
ai_assert(!node_stack.empty());
|
ai_assert(!node_stack.empty());
|
||||||
|
|
||||||
|
|
|
@ -222,7 +222,7 @@ template <>
|
||||||
struct MinMaxChooser<aiVertexWeight> {
|
struct MinMaxChooser<aiVertexWeight> {
|
||||||
void operator()(aiVertexWeight &min, aiVertexWeight &max) {
|
void operator()(aiVertexWeight &min, aiVertexWeight &max) {
|
||||||
MinMaxChooser<unsigned int>()(min.mVertexId, max.mVertexId);
|
MinMaxChooser<unsigned int>()(min.mVertexId, max.mVertexId);
|
||||||
MinMaxChooser<float>()(min.mWeight, max.mWeight);
|
MinMaxChooser<ai_real>()(min.mWeight, max.mWeight);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
#### Supported file formats ####
|
||||||
|
|
||||||
|
__Importers__:
|
||||||
|
|
||||||
|
- 3D
|
||||||
|
- [3DS](https://en.wikipedia.org/wiki/.3ds)
|
||||||
|
- [3MF](https://en.wikipedia.org/wiki/3D_Manufacturing_Format)
|
||||||
|
- AC
|
||||||
|
- [AC3D](https://en.wikipedia.org/wiki/AC3D)
|
||||||
|
- ACC
|
||||||
|
- AMJ
|
||||||
|
- ASE
|
||||||
|
- ASK
|
||||||
|
- B3D
|
||||||
|
- [BLEND](https://en.wikipedia.org/wiki/.blend_(file_format))
|
||||||
|
- [BVH](https://en.wikipedia.org/wiki/Biovision_Hierarchy)
|
||||||
|
- CMS
|
||||||
|
- COB
|
||||||
|
- [DAE/Collada](https://en.wikipedia.org/wiki/COLLADA)
|
||||||
|
- [DXF](https://en.wikipedia.org/wiki/AutoCAD_DXF)
|
||||||
|
- ENFF
|
||||||
|
- [FBX](https://en.wikipedia.org/wiki/FBX)
|
||||||
|
- [glTF 1.0](https://en.wikipedia.org/wiki/GlTF#glTF_1.0) + GLB
|
||||||
|
- [glTF 2.0](https://en.wikipedia.org/wiki/GlTF#glTF_2.0):
|
||||||
|
At the moment for glTF2.0 the following extensions are supported:
|
||||||
|
+ KHR_lights_punctual ( 5.0 )
|
||||||
|
+ KHR_materials_pbrSpecularGlossiness ( 5.0 )
|
||||||
|
+ KHR_materials_unlit ( 5.0 )
|
||||||
|
+ KHR_texture_transform ( 5.1 under test )
|
||||||
|
- HMB
|
||||||
|
- IFC-STEP
|
||||||
|
- IRR / IRRMESH
|
||||||
|
- [LWO](https://en.wikipedia.org/wiki/LightWave_3D)
|
||||||
|
- LWS
|
||||||
|
- LXO
|
||||||
|
- [M3D](https://bztsrc.gitlab.io/model3d)
|
||||||
|
- MD2
|
||||||
|
- MD3
|
||||||
|
- MD5
|
||||||
|
- MDC
|
||||||
|
- MDL
|
||||||
|
- MESH / MESH.XML
|
||||||
|
- MOT
|
||||||
|
- MS3D
|
||||||
|
- NDO
|
||||||
|
- NFF
|
||||||
|
- [OBJ](https://en.wikipedia.org/wiki/Wavefront_.obj_file)
|
||||||
|
- [OFF](https://en.wikipedia.org/wiki/OFF_(file_format))
|
||||||
|
- [OGEX](https://en.wikipedia.org/wiki/Open_Game_Engine_Exchange)
|
||||||
|
- [PLY](https://en.wikipedia.org/wiki/PLY_(file_format))
|
||||||
|
- PMX
|
||||||
|
- PRJ
|
||||||
|
- Q3O
|
||||||
|
- Q3S
|
||||||
|
- RAW
|
||||||
|
- SCN
|
||||||
|
- SIB
|
||||||
|
- SMD
|
||||||
|
- [STP](https://en.wikipedia.org/wiki/ISO_10303-21)
|
||||||
|
- [STL](https://en.wikipedia.org/wiki/STL_(file_format))
|
||||||
|
- TER
|
||||||
|
- UC
|
||||||
|
- VTA
|
||||||
|
- X
|
||||||
|
- [X3D](https://en.wikipedia.org/wiki/X3D)
|
||||||
|
- XGL
|
||||||
|
- ZGL
|
||||||
|
|
||||||
|
Additionally, some formats are supported by dependency on non-free code or external SDKs (not built by default):
|
||||||
|
|
||||||
|
- [C4D](https://en.wikipedia.org/wiki/Cinema_4D) (https://github.com/assimp/assimp/wiki/Cinema4D-&-Melange) IMporting geometry + node hierarchy are currently supported
|
||||||
|
|
||||||
|
__Exporters__:
|
||||||
|
|
||||||
|
- DAE (Collada)
|
||||||
|
- STL
|
||||||
|
- OBJ
|
||||||
|
- PLY
|
||||||
|
- X
|
||||||
|
- 3DS
|
||||||
|
- JSON (for WebGl, via https://github.com/acgessler/assimp2json)
|
||||||
|
- ASSBIN
|
||||||
|
- STEP
|
||||||
|
- glTF 1.0 (partial)
|
||||||
|
- glTF 2.0 (partial)
|
||||||
|
- 3MF ( experimental )
|
||||||
|
- FBX ( experimental )
|
|
@ -42,12 +42,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef AI_ASSERT_H_INC
|
#ifndef AI_ASSERT_H_INC
|
||||||
#define AI_ASSERT_H_INC
|
#define AI_ASSERT_H_INC
|
||||||
|
|
||||||
|
#include <assimp/defs.h>
|
||||||
|
|
||||||
#if defined(ASSIMP_BUILD_DEBUG)
|
#if defined(ASSIMP_BUILD_DEBUG)
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
// Assert violation behavior can be customized: see AssertHandler.h.
|
// Assert violation behavior can be customized: see AssertHandler.h.
|
||||||
void aiAssertViolation(const char* failedExpression, const char* file, int line);
|
ASSIMP_API void aiAssertViolation(const char* failedExpression, const char* file, int line);
|
||||||
}
|
}
|
||||||
|
|
||||||
# define ai_assert(expression) (void)((!!(expression)) || (Assimp::aiAssertViolation(#expression, __FILE__, __LINE__), 0))
|
# define ai_assert(expression) (void)((!!(expression)) || (Assimp::aiAssertViolation(#expression, __FILE__, __LINE__), 0))
|
||||||
|
|
|
@ -1044,7 +1044,7 @@ ASSIMP_API void aiMatrix4DecomposeIntoScalingAxisAnglePosition(
|
||||||
const C_STRUCT aiMatrix4x4* mat,
|
const C_STRUCT aiMatrix4x4* mat,
|
||||||
C_STRUCT aiVector3D* scaling,
|
C_STRUCT aiVector3D* scaling,
|
||||||
C_STRUCT aiVector3D* axis,
|
C_STRUCT aiVector3D* axis,
|
||||||
float* angle,
|
ai_real* angle,
|
||||||
C_STRUCT aiVector3D* position);
|
C_STRUCT aiVector3D* position);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------
|
||||||
|
|
|
@ -176,7 +176,7 @@ TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4DecomposeIntoScalingAxisAnglePosition
|
||||||
aiVector3D scaling_c, scaling_cpp,
|
aiVector3D scaling_c, scaling_cpp,
|
||||||
axis_c, axis_cpp,
|
axis_c, axis_cpp,
|
||||||
position_c, position_cpp;
|
position_c, position_cpp;
|
||||||
float angle_c, angle_cpp;
|
ai_real angle_c, angle_cpp;
|
||||||
|
|
||||||
result_c = result_cpp = get_predetermined_transformation_matrix_for_decomposition();
|
result_c = result_cpp = get_predetermined_transformation_matrix_for_decomposition();
|
||||||
result_cpp.Decompose(scaling_cpp, axis_cpp, angle_cpp, position_cpp);
|
result_cpp.Decompose(scaling_cpp, axis_cpp, angle_cpp, position_cpp);
|
||||||
|
|
Loading…
Reference in New Issue