Rollup to upstream/master
commit
9e27fb3b89
|
@ -0,0 +1,38 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
|
@ -79,6 +79,12 @@ test/gtest/src/gtest-stamp/Debug/
|
|||
tools/assimp_view/assimp_viewer.vcxproj.user
|
||||
*.pyc
|
||||
|
||||
### Rust ###
|
||||
# Generated by Cargo; will have compiled files and executables
|
||||
port/assimp_rs/target/
|
||||
# Backup files generated by rustfmt
|
||||
port/assimp_rs/**/*.rs.bk
|
||||
|
||||
# Unix editor backups
|
||||
*~
|
||||
test/gtest/src/gtest-stamp/gtest-gitinfo.txt
|
||||
|
|
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).
|
||||
|
||||
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
|
||||
|
||||
If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
|
||||
|
||||
#### 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 )
|
||||
You can find the complete list of supported file-formats [here](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md)
|
||||
|
||||
### 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.
|
||||
|
@ -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>
|
||||
|
||||
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
|
||||
|
||||
Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/assimp/contribute)]
|
||||
|
|
|
@ -73,6 +73,9 @@ else()
|
|||
else()
|
||||
set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_SHARED_LIBRARY_SUFFIX@.@ASSIMP_VERSION_MAJOR@")
|
||||
endif()
|
||||
|
||||
# Import target "assimp::assimp" for configuration "Debug"
|
||||
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
|
||||
set_target_properties(assimp::assimp PROPERTIES
|
||||
IMPORTED_SONAME_DEBUG "${sharedLibraryName}"
|
||||
IMPORTED_LOCATION_DEBUG "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}"
|
||||
|
@ -81,6 +84,9 @@ else()
|
|||
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}" )
|
||||
else()
|
||||
set(staticLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_STATIC_LIBRARY_SUFFIX@")
|
||||
|
||||
# Import target "assimp::assimp" for configuration "Debug"
|
||||
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
|
||||
set_target_properties(assimp::assimp PROPERTIES
|
||||
IMPORTED_LOCATION_DEBUG "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}"
|
||||
)
|
||||
|
|
|
@ -73,6 +73,9 @@ else()
|
|||
else()
|
||||
set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_SHARED_LIBRARY_SUFFIX@.@ASSIMP_VERSION_MAJOR@")
|
||||
endif()
|
||||
|
||||
# Import target "assimp::assimp" for configuration "Release"
|
||||
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
||||
set_target_properties(assimp::assimp PROPERTIES
|
||||
IMPORTED_SONAME_RELEASE "${sharedLibraryName}"
|
||||
IMPORTED_LOCATION_RELEASE "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}"
|
||||
|
@ -81,6 +84,9 @@ else()
|
|||
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}" )
|
||||
else()
|
||||
set(staticLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_STATIC_LIBRARY_SUFFIX@")
|
||||
|
||||
# Import target "assimp::assimp" for configuration "Release"
|
||||
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
||||
set_target_properties(assimp::assimp PROPERTIES
|
||||
IMPORTED_LOCATION_RELEASE "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}"
|
||||
)
|
||||
|
|
|
@ -0,0 +1,707 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
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
|
|
@ -539,7 +539,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
|
|||
ai_assert(nullptr != anim);
|
||||
|
||||
if (pcIn->aCameraRollKeys.size() > 1) {
|
||||
ASSIMP_LOG_DEBUG("3DS: Converting camera roll track ...");
|
||||
ASSIMP_LOG_VERBOSE_DEBUG("3DS: Converting camera roll track ...");
|
||||
|
||||
// Camera roll keys - in fact they're just rotations
|
||||
// around the camera's z axis. The angles are given
|
||||
|
@ -558,7 +558,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
|
|||
#if 0
|
||||
if (pcIn->aTargetPositionKeys.size() > 1)
|
||||
{
|
||||
ASSIMP_LOG_DEBUG("3DS: Converting target track ...");
|
||||
ASSIMP_LOG_VERBOSE_DEBUG("3DS: Converting target track ...");
|
||||
|
||||
// Camera or spot light - need to convert the separate
|
||||
// target position channel to our representation
|
||||
|
|
|
@ -367,7 +367,7 @@ void Discreet3DSExporter::WriteTexture(const aiMaterial &mat, aiTextureType type
|
|||
aiTextureMapMode_Wrap, aiTextureMapMode_Wrap
|
||||
};
|
||||
ai_real blend = 1.0;
|
||||
if (mat.GetTexture(type, 0, &path, NULL, NULL, &blend, NULL, map_mode) != AI_SUCCESS || !path.length) {
|
||||
if (mat.GetTexture(type, 0, &path, nullptr, nullptr, &blend, nullptr, map_mode) != AI_SUCCESS || !path.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -462,12 +462,10 @@ struct Material {
|
|||
sTexAmbient(other.sTexAmbient),
|
||||
mTwoSided(other.mTwoSided) {
|
||||
// empty
|
||||
|
||||
}
|
||||
|
||||
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
|
||||
Material(Material &&other) AI_NO_EXCEPT :
|
||||
mName(std::move(other.mName)),
|
||||
Material(Material &&other) AI_NO_EXCEPT : mName(std::move(other.mName)),
|
||||
mDiffuse(std::move(other.mDiffuse)),
|
||||
mSpecularExponent(std::move(other.mSpecularExponent)),
|
||||
mShininessStrength(std::move(other.mShininessStrength)),
|
||||
|
@ -615,7 +613,12 @@ struct Node {
|
|||
Node() = delete;
|
||||
|
||||
explicit Node(const std::string &name) :
|
||||
mParent(NULL), mName(name), mInstanceNumber(0), mHierarchyPos(0), mHierarchyIndex(0), mInstanceCount(1) {
|
||||
mParent(nullptr),
|
||||
mName(name),
|
||||
mInstanceNumber(0),
|
||||
mHierarchyPos(0),
|
||||
mHierarchyIndex(0),
|
||||
mInstanceCount(1) {
|
||||
aRotationKeys.reserve(20);
|
||||
aPositionKeys.reserve(20);
|
||||
aScalingKeys.reserve(20);
|
||||
|
|
|
@ -314,19 +314,19 @@ private:
|
|||
++buf;
|
||||
comp[1] = *buf;
|
||||
++buf;
|
||||
diffuse.r = static_cast<ai_real>(strtol(comp, NULL, 16)) / ai_real(255.0);
|
||||
diffuse.r = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
|
||||
|
||||
comp[0] = *buf;
|
||||
++buf;
|
||||
comp[1] = *buf;
|
||||
++buf;
|
||||
diffuse.g = static_cast<ai_real>(strtol(comp, NULL, 16)) / ai_real(255.0);
|
||||
diffuse.g = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
|
||||
|
||||
comp[0] = *buf;
|
||||
++buf;
|
||||
comp[1] = *buf;
|
||||
++buf;
|
||||
diffuse.b = static_cast<ai_real>(strtol(comp, NULL, 16)) / ai_real(255.0);
|
||||
diffuse.b = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
|
||||
|
||||
if (7 == len)
|
||||
return true;
|
||||
|
@ -334,7 +334,7 @@ private:
|
|||
++buf;
|
||||
comp[1] = *buf;
|
||||
++buf;
|
||||
diffuse.a = static_cast<ai_real>(strtol(comp, NULL, 16)) / ai_real(255.0);
|
||||
diffuse.a = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -45,19 +45,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "D3MFOpcPackage.h"
|
||||
#include <assimp/Exceptional.h>
|
||||
|
||||
#include <assimp/ZipArchiveIOSystem.h>
|
||||
#include <assimp/ai_assert.h>
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
#include <assimp/IOStream.hpp>
|
||||
#include <assimp/IOSystem.hpp>
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
#include <assimp/ai_assert.h>
|
||||
#include <assimp/ZipArchiveIOSystem.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "3MFXmlTags.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include "3MFXmlTags.h"
|
||||
#include <cstdlib>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
|
@ -68,49 +68,45 @@ typedef std::shared_ptr<OpcPackageRelationship> OpcPackageRelationshipPtr;
|
|||
|
||||
class OpcPackageRelationshipReader {
|
||||
public:
|
||||
OpcPackageRelationshipReader(XmlReader* xmlReader) {
|
||||
while(xmlReader->read()) {
|
||||
if(xmlReader->getNodeType() == irr::io::EXN_ELEMENT &&
|
||||
xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_CONTAINER)
|
||||
{
|
||||
OpcPackageRelationshipReader(XmlReader *xmlReader) {
|
||||
while (xmlReader->read()) {
|
||||
if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT &&
|
||||
xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_CONTAINER) {
|
||||
ParseRootNode(xmlReader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ParseRootNode(XmlReader* xmlReader)
|
||||
{
|
||||
void ParseRootNode(XmlReader *xmlReader) {
|
||||
ParseAttributes(xmlReader);
|
||||
|
||||
while(xmlReader->read())
|
||||
{
|
||||
if(xmlReader->getNodeType() == irr::io::EXN_ELEMENT &&
|
||||
xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_NODE)
|
||||
{
|
||||
while (xmlReader->read()) {
|
||||
if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT &&
|
||||
xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_NODE) {
|
||||
ParseChildNode(xmlReader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ParseAttributes(XmlReader*) {
|
||||
void ParseAttributes(XmlReader *) {
|
||||
// empty
|
||||
}
|
||||
|
||||
bool validateRels( OpcPackageRelationshipPtr &relPtr ) {
|
||||
if ( relPtr->id.empty() || relPtr->type.empty() || relPtr->target.empty() ) {
|
||||
bool validateRels(OpcPackageRelationshipPtr &relPtr) {
|
||||
if (relPtr->id.empty() || relPtr->type.empty() || relPtr->target.empty()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ParseChildNode(XmlReader* xmlReader) {
|
||||
void ParseChildNode(XmlReader *xmlReader) {
|
||||
OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship());
|
||||
|
||||
relPtr->id = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_ID.c_str());
|
||||
relPtr->type = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_TYPE.c_str());
|
||||
relPtr->target = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_TARGET.c_str());
|
||||
if ( validateRels( relPtr ) ) {
|
||||
m_relationShips.push_back( relPtr );
|
||||
if (validateRels(relPtr)) {
|
||||
m_relationShips.push_back(relPtr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -118,51 +114,52 @@ public:
|
|||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
D3MFOpcPackage::D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile)
|
||||
: mRootStream(nullptr)
|
||||
, mZipArchive() {
|
||||
mZipArchive.reset( new ZipArchiveIOSystem( pIOHandler, rFile ) );
|
||||
if(!mZipArchive->isOpen()) {
|
||||
throw DeadlyImportError("Failed to open file " + rFile+ ".");
|
||||
D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
|
||||
mRootStream(nullptr), mZipArchive() {
|
||||
mZipArchive.reset(new ZipArchiveIOSystem(pIOHandler, rFile));
|
||||
if (!mZipArchive->isOpen()) {
|
||||
throw DeadlyImportError("Failed to open file " + rFile + ".");
|
||||
}
|
||||
|
||||
std::vector<std::string> fileList;
|
||||
mZipArchive->getFileList(fileList);
|
||||
|
||||
for (auto& file: fileList) {
|
||||
if(file == D3MF::XmlTag::ROOT_RELATIONSHIPS_ARCHIVE) {
|
||||
//PkgRelationshipReader pkgRelReader(file, archive);
|
||||
ai_assert(mZipArchive->Exists(file.c_str()));
|
||||
for (auto &file : fileList) {
|
||||
if (file == D3MF::XmlTag::ROOT_RELATIONSHIPS_ARCHIVE) {
|
||||
if (!mZipArchive->Exists(file.c_str())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
IOStream *fileStream = mZipArchive->Open(file.c_str());
|
||||
|
||||
if (nullptr == fileStream) {
|
||||
ai_assert(fileStream != nullptr);
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string rootFile = ReadPackageRootRelationship(fileStream);
|
||||
if ( rootFile.size() > 0 && rootFile[ 0 ] == '/' ) {
|
||||
rootFile = rootFile.substr( 1 );
|
||||
if ( rootFile[ 0 ] == '/' ) {
|
||||
if (rootFile.size() > 0 && rootFile[0] == '/') {
|
||||
rootFile = rootFile.substr(1);
|
||||
if (rootFile[0] == '/') {
|
||||
// deal with zip-bug
|
||||
rootFile = rootFile.substr( 1 );
|
||||
rootFile = rootFile.substr(1);
|
||||
}
|
||||
}
|
||||
|
||||
ASSIMP_LOG_DEBUG(rootFile);
|
||||
ASSIMP_LOG_VERBOSE_DEBUG(rootFile);
|
||||
|
||||
mZipArchive->Close(fileStream);
|
||||
|
||||
mRootStream = mZipArchive->Open(rootFile.c_str());
|
||||
ai_assert( mRootStream != nullptr );
|
||||
if ( nullptr == mRootStream ) {
|
||||
throw DeadlyExportError( "Cannot open root-file in archive : " + rootFile );
|
||||
ai_assert(mRootStream != nullptr);
|
||||
if (nullptr == mRootStream) {
|
||||
throw DeadlyExportError("Cannot open root-file in archive : " + rootFile);
|
||||
}
|
||||
|
||||
} else if( file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE) {
|
||||
ASSIMP_LOG_WARN_F("Ignored file of unsupported type CONTENT_TYPES_ARCHIVES",file);
|
||||
} else if (file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE) {
|
||||
ASSIMP_LOG_WARN_F("Ignored file of unsupported type CONTENT_TYPES_ARCHIVES", file);
|
||||
} else {
|
||||
ASSIMP_LOG_WARN_F("Ignored file of unknown type: ",file);
|
||||
ASSIMP_LOG_WARN_F("Ignored file of unknown type: ", file);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,32 +167,32 @@ D3MFOpcPackage::~D3MFOpcPackage() {
|
|||
mZipArchive->Close(mRootStream);
|
||||
}
|
||||
|
||||
IOStream* D3MFOpcPackage::RootStream() const {
|
||||
IOStream *D3MFOpcPackage::RootStream() const {
|
||||
return mRootStream;
|
||||
}
|
||||
|
||||
static const std::string ModelRef = "3D/3dmodel.model";
|
||||
|
||||
bool D3MFOpcPackage::validate() {
|
||||
if ( nullptr == mRootStream || nullptr == mZipArchive ) {
|
||||
if (nullptr == mRootStream || nullptr == mZipArchive) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return mZipArchive->Exists( ModelRef.c_str() );
|
||||
return mZipArchive->Exists(ModelRef.c_str());
|
||||
}
|
||||
|
||||
std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream* stream) {
|
||||
std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream *stream) {
|
||||
std::unique_ptr<CIrrXML_IOStreamReader> xmlStream(new CIrrXML_IOStreamReader(stream));
|
||||
std::unique_ptr<XmlReader> xml(irr::io::createIrrXMLReader(xmlStream.get()));
|
||||
|
||||
OpcPackageRelationshipReader reader(xml.get());
|
||||
|
||||
auto itr = std::find_if(reader.m_relationShips.begin(), reader.m_relationShips.end(), [](const OpcPackageRelationshipPtr& rel){
|
||||
auto itr = std::find_if(reader.m_relationShips.begin(), reader.m_relationShips.end(), [](const OpcPackageRelationshipPtr &rel) {
|
||||
return rel->type == XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE;
|
||||
});
|
||||
|
||||
if ( itr == reader.m_relationShips.end() ) {
|
||||
throw DeadlyImportError( "Cannot find " + XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE );
|
||||
if (itr == reader.m_relationShips.end()) {
|
||||
throw DeadlyImportError("Cannot find " + XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE);
|
||||
}
|
||||
|
||||
return (*itr)->target;
|
||||
|
|
|
@ -207,7 +207,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
|
|||
light->mName.length = ::ai_snprintf(light->mName.data, MAXLEN, "ACLight_%i", static_cast<unsigned int>(mLights->size()) - 1);
|
||||
obj.name = std::string(light->mName.data);
|
||||
|
||||
ASSIMP_LOG_DEBUG("AC3D: Light source encountered");
|
||||
ASSIMP_LOG_VERBOSE_DEBUG("AC3D: Light source encountered");
|
||||
obj.type = Object::Light;
|
||||
} else if (!ASSIMP_strincmp(buffer, "group", 5)) {
|
||||
obj.type = Object::Group;
|
||||
|
@ -294,7 +294,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
|
|||
// example writes no surf chunks
|
||||
if (!Q3DWorkAround) {
|
||||
ASSIMP_LOG_WARN("AC3D: SURF token was expected");
|
||||
ASSIMP_LOG_DEBUG("Continuing with Quick3D Workaround enabled");
|
||||
ASSIMP_LOG_VERBOSE_DEBUG("Continuing with Quick3D Workaround enabled");
|
||||
}
|
||||
--buffer; // make sure the line is processed a second time
|
||||
// break; --- see fix notes above
|
||||
|
@ -627,7 +627,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
|
|||
std::unique_ptr<Subdivider> div(Subdivider::Create(Subdivider::CATMULL_CLARKE));
|
||||
ASSIMP_LOG_INFO("AC3D: Evaluating subdivision surface: " + object.name);
|
||||
|
||||
std::vector<aiMesh *> cpy(meshes.size() - oldm, NULL);
|
||||
std::vector<aiMesh *> cpy(meshes.size() - oldm, nullptr);
|
||||
div->Subdivide(&meshes[oldm], cpy.size(), &cpy.front(), object.subDiv, true);
|
||||
std::copy(cpy.begin(), cpy.end(), meshes.begin() + oldm);
|
||||
|
||||
|
|
|
@ -366,7 +366,9 @@ void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) {
|
|||
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
|
||||
|
||||
// Check whether we can read from the file
|
||||
if (file.get() == NULL) throw DeadlyImportError("Failed to open AMF file " + pFile + ".");
|
||||
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()));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
|
|
@ -614,7 +614,7 @@ void ASEImporter::AddNodes(const std::vector<BaseNode *> &nodes,
|
|||
node->mNumChildren++;
|
||||
|
||||
// What we did is so great, it is at least worth a debug message
|
||||
ASSIMP_LOG_DEBUG("ASE: Generating separate target node (" + snode->mName + ")");
|
||||
ASSIMP_LOG_VERBOSE_DEBUG("ASE: Generating separate target node (" + snode->mName + ")");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -925,7 +925,7 @@ void Parser::ParseLV2AnimationBlock(ASE::BaseNode &mesh) {
|
|||
|
||||
ASSIMP_LOG_ERROR("ASE: Found target animation channel "
|
||||
"but the node is neither a camera nor a spot light");
|
||||
anim = NULL;
|
||||
anim = nullptr;
|
||||
} else
|
||||
anim = &mesh.mTargetAnim;
|
||||
}
|
||||
|
@ -1797,14 +1797,14 @@ void Parser::ParseLV4MeshFace(ASE::Face &out) {
|
|||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Parser::ParseLV4MeshLongTriple(unsigned int *apOut) {
|
||||
ai_assert(NULL != apOut);
|
||||
ai_assert(nullptr != apOut);
|
||||
|
||||
for (unsigned int i = 0; i < 3; ++i)
|
||||
ParseLV4MeshLong(apOut[i]);
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Parser::ParseLV4MeshLongTriple(unsigned int *apOut, unsigned int &rIndexOut) {
|
||||
ai_assert(NULL != apOut);
|
||||
ai_assert(nullptr != apOut);
|
||||
|
||||
// parse the index
|
||||
ParseLV4MeshLong(rIndexOut);
|
||||
|
@ -1814,7 +1814,7 @@ void Parser::ParseLV4MeshLongTriple(unsigned int *apOut, unsigned int &rIndexOut
|
|||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Parser::ParseLV4MeshFloatTriple(ai_real *apOut, unsigned int &rIndexOut) {
|
||||
ai_assert(NULL != apOut);
|
||||
ai_assert(nullptr != apOut);
|
||||
|
||||
// parse the index
|
||||
ParseLV4MeshLong(rIndexOut);
|
||||
|
@ -1824,7 +1824,7 @@ void Parser::ParseLV4MeshFloatTriple(ai_real *apOut, unsigned int &rIndexOut) {
|
|||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Parser::ParseLV4MeshFloatTriple(ai_real *apOut) {
|
||||
ai_assert(NULL != apOut);
|
||||
ai_assert(nullptr != apOut);
|
||||
|
||||
for (unsigned int i = 0; i < 3; ++i)
|
||||
ParseLV4MeshFloat(apOut[i]);
|
||||
|
|
|
@ -40,15 +40,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/** @file Defines the helper data structures for importing ASE files */
|
||||
#ifndef AI_ASEFILEHELPER_H_INC
|
||||
#define AI_ASEFILEHELPER_H_INC
|
||||
|
||||
// public ASSIMP headers
|
||||
#include <assimp/types.h>
|
||||
#include <assimp/mesh.h>
|
||||
#include <assimp/anim.h>
|
||||
#include <assimp/mesh.h>
|
||||
#include <assimp/types.h>
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
|
||||
|
||||
|
@ -66,16 +65,15 @@ using namespace D3DS;
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Helper structure representing an ASE material */
|
||||
struct Material : public D3DS::Material
|
||||
{
|
||||
struct Material : public D3DS::Material {
|
||||
//! Default constructor has been deleted
|
||||
Material() = delete;
|
||||
|
||||
//! Constructor with explicit name
|
||||
explicit Material(const std::string &name)
|
||||
: D3DS::Material(name)
|
||||
, pcInstance(NULL)
|
||||
, bNeed (false) {
|
||||
explicit Material(const std::string &name) :
|
||||
D3DS::Material(name),
|
||||
pcInstance(nullptr),
|
||||
bNeed(false) {
|
||||
// empty
|
||||
}
|
||||
|
||||
|
@ -93,19 +91,16 @@ struct Material : public D3DS::Material
|
|||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
|
||||
Material(Material &&other) AI_NO_EXCEPT
|
||||
: D3DS::Material(std::move(other))
|
||||
, avSubMaterials(std::move(other.avSubMaterials))
|
||||
, pcInstance(std::move(other.pcInstance))
|
||||
, bNeed(std::move(other.bNeed))
|
||||
{
|
||||
: D3DS::Material(std::move(other)),
|
||||
avSubMaterials(std::move(other.avSubMaterials)),
|
||||
pcInstance(std::move(other.pcInstance)),
|
||||
bNeed(std::move(other.bNeed)) {
|
||||
other.pcInstance = nullptr;
|
||||
}
|
||||
|
||||
|
||||
Material &operator=( Material &&other) AI_NO_EXCEPT {
|
||||
Material &operator=(Material &&other) AI_NO_EXCEPT {
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
|
@ -121,15 +116,13 @@ struct Material : public D3DS::Material
|
|||
return *this;
|
||||
}
|
||||
|
||||
|
||||
~Material() {}
|
||||
|
||||
|
||||
//! Contains all sub materials of this material
|
||||
std::vector<Material> avSubMaterials;
|
||||
|
||||
//! aiMaterial object
|
||||
aiMaterial* pcInstance;
|
||||
aiMaterial *pcInstance;
|
||||
|
||||
//! Can we remove this material?
|
||||
bool bNeed;
|
||||
|
@ -140,8 +133,8 @@ struct Material : public D3DS::Material
|
|||
struct Face : public FaceWithSmoothingGroup {
|
||||
//! Default constructor. Initializes everything with 0
|
||||
Face() AI_NO_EXCEPT
|
||||
: iMaterial(DEFAULT_MATINDEX)
|
||||
, iFace(0) {
|
||||
: iMaterial(DEFAULT_MATINDEX),
|
||||
iFace(0) {
|
||||
// empty
|
||||
}
|
||||
|
||||
|
@ -172,8 +165,8 @@ struct Bone {
|
|||
Bone() = delete;
|
||||
|
||||
//! Construction from an existing name
|
||||
explicit Bone( const std::string& name)
|
||||
: mName(name) {
|
||||
explicit Bone(const std::string &name) :
|
||||
mName(name) {
|
||||
// empty
|
||||
}
|
||||
|
||||
|
@ -186,7 +179,7 @@ struct Bone {
|
|||
struct BoneVertex {
|
||||
//! Bone and corresponding vertex weight.
|
||||
//! -1 for unrequired bones ....
|
||||
std::vector<std::pair<int,float> > mBoneWeights;
|
||||
std::vector<std::pair<int, float>> mBoneWeights;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -196,23 +189,24 @@ struct Animation {
|
|||
TRACK = 0x0,
|
||||
BEZIER = 0x1,
|
||||
TCB = 0x2
|
||||
} mRotationType, mScalingType, mPositionType;
|
||||
} mRotationType,
|
||||
mScalingType, mPositionType;
|
||||
|
||||
Animation() AI_NO_EXCEPT
|
||||
: mRotationType (TRACK)
|
||||
, mScalingType (TRACK)
|
||||
, mPositionType (TRACK) {
|
||||
: mRotationType(TRACK),
|
||||
mScalingType(TRACK),
|
||||
mPositionType(TRACK) {
|
||||
// empty
|
||||
}
|
||||
|
||||
//! List of track rotation keyframes
|
||||
std::vector< aiQuatKey > akeyRotations;
|
||||
std::vector<aiQuatKey> akeyRotations;
|
||||
|
||||
//! List of track position keyframes
|
||||
std::vector< aiVectorKey > akeyPositions;
|
||||
std::vector<aiVectorKey> akeyPositions;
|
||||
|
||||
//! List of track scaling keyframes
|
||||
std::vector< aiVectorKey > akeyScaling;
|
||||
std::vector<aiVectorKey> akeyScaling;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -220,7 +214,7 @@ struct Animation {
|
|||
struct InheritanceInfo {
|
||||
//! Default constructor
|
||||
InheritanceInfo() AI_NO_EXCEPT {
|
||||
for ( size_t i=0; i<3; ++i ) {
|
||||
for (size_t i = 0; i < 3; ++i) {
|
||||
abInheritPosition[i] = abInheritRotation[i] = abInheritScaling[i] = true;
|
||||
}
|
||||
}
|
||||
|
@ -246,10 +240,8 @@ struct BaseNode {
|
|||
} mType;
|
||||
|
||||
//! Construction from an existing name
|
||||
BaseNode(Type _mType, const std::string &name)
|
||||
: mType (_mType)
|
||||
, mName (name)
|
||||
, mProcessed (false) {
|
||||
BaseNode(Type _mType, const std::string &name) :
|
||||
mType(_mType), mName(name), mProcessed(false) {
|
||||
// Set mTargetPosition to qnan
|
||||
const ai_real qnan = get_qnan();
|
||||
mTargetPosition.x = qnan;
|
||||
|
@ -289,14 +281,9 @@ struct Mesh : public MeshWithSmoothingGroups<ASE::Face>, public BaseNode {
|
|||
Mesh() = delete;
|
||||
|
||||
//! Construction from an existing name
|
||||
explicit Mesh(const std::string &name)
|
||||
: BaseNode( BaseNode::Mesh, name )
|
||||
, mVertexColors()
|
||||
, mBoneVertices()
|
||||
, mBones()
|
||||
, iMaterialIndex(Face::DEFAULT_MATINDEX)
|
||||
, bSkip (false) {
|
||||
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) {
|
||||
explicit Mesh(const std::string &name) :
|
||||
BaseNode(BaseNode::Mesh, name), mVertexColors(), mBoneVertices(), mBones(), iMaterialIndex(Face::DEFAULT_MATINDEX), bSkip(false) {
|
||||
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++c) {
|
||||
this->mNumUVComponents[c] = 2;
|
||||
}
|
||||
}
|
||||
|
@ -325,10 +312,8 @@ struct Mesh : public MeshWithSmoothingGroups<ASE::Face>, public BaseNode {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Helper structure to represent an ASE light source */
|
||||
struct Light : public BaseNode
|
||||
{
|
||||
enum LightType
|
||||
{
|
||||
struct Light : public BaseNode {
|
||||
enum LightType {
|
||||
OMNI,
|
||||
TARGET,
|
||||
FREE,
|
||||
|
@ -339,17 +324,13 @@ struct Light : public BaseNode
|
|||
Light() = delete;
|
||||
|
||||
//! Construction from an existing name
|
||||
explicit Light(const std::string &name)
|
||||
: BaseNode (BaseNode::Light, name)
|
||||
, mLightType (OMNI)
|
||||
, mColor (1.f,1.f,1.f)
|
||||
, mIntensity (1.f) // light is white by default
|
||||
, mAngle (45.f)
|
||||
, mFalloff (0.f)
|
||||
{
|
||||
explicit Light(const std::string &name) :
|
||||
BaseNode(BaseNode::Light, name), mLightType(OMNI), mColor(1.f, 1.f, 1.f), mIntensity(1.f) // light is white by default
|
||||
,
|
||||
mAngle(45.f),
|
||||
mFalloff(0.f) {
|
||||
}
|
||||
|
||||
|
||||
LightType mLightType;
|
||||
aiColor3D mColor;
|
||||
ai_real mIntensity;
|
||||
|
@ -359,10 +340,8 @@ struct Light : public BaseNode
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Helper structure to represent an ASE camera */
|
||||
struct Camera : public BaseNode
|
||||
{
|
||||
enum CameraType
|
||||
{
|
||||
struct Camera : public BaseNode {
|
||||
enum CameraType {
|
||||
FREE,
|
||||
TARGET
|
||||
};
|
||||
|
@ -370,18 +349,16 @@ struct Camera : public BaseNode
|
|||
//! Default constructor has been deleted
|
||||
Camera() = delete;
|
||||
|
||||
|
||||
//! Construction from an existing name
|
||||
explicit Camera(const std::string &name)
|
||||
: BaseNode (BaseNode::Camera, name)
|
||||
, mFOV (0.75f) // in radians
|
||||
, mNear (0.1f)
|
||||
, mFar (1000.f) // could be zero
|
||||
, mCameraType (FREE)
|
||||
{
|
||||
explicit Camera(const std::string &name) :
|
||||
BaseNode(BaseNode::Camera, name), mFOV(0.75f) // in radians
|
||||
,
|
||||
mNear(0.1f),
|
||||
mFar(1000.f) // could be zero
|
||||
,
|
||||
mCameraType(FREE) {
|
||||
}
|
||||
|
||||
|
||||
ai_real mFOV, mNear, mFar;
|
||||
CameraType mCameraType;
|
||||
};
|
||||
|
@ -391,7 +368,7 @@ struct Camera : public BaseNode
|
|||
struct Dummy : public BaseNode {
|
||||
//! Constructor
|
||||
Dummy() AI_NO_EXCEPT
|
||||
: BaseNode (BaseNode::Dummy, "DUMMY") {
|
||||
: BaseNode(BaseNode::Dummy, "DUMMY") {
|
||||
// empty
|
||||
}
|
||||
};
|
||||
|
@ -414,7 +391,6 @@ private:
|
|||
}
|
||||
|
||||
public:
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Construct a parser from a given input file which is
|
||||
//! guaranteed to be terminated with zero.
|
||||
|
@ -422,15 +398,13 @@ public:
|
|||
//! @param fileFormatDefault Assumed file format version. If the
|
||||
//! file format is specified in the file the new value replaces
|
||||
//! the default value.
|
||||
Parser (const char* szFile, unsigned int fileFormatDefault);
|
||||
Parser(const char *szFile, unsigned int fileFormatDefault);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parses the file into the parsers internal representation
|
||||
void Parse();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse the *SCENE block in a file
|
||||
void ParseLV1SceneBlock();
|
||||
|
@ -446,45 +420,45 @@ private:
|
|||
// -------------------------------------------------------------------
|
||||
//! Parse a *<xxx>OBJECT block in a file
|
||||
//! \param mesh Node to be filled
|
||||
void ParseLV1ObjectBlock(BaseNode& mesh);
|
||||
void ParseLV1ObjectBlock(BaseNode &mesh);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a *MATERIAL blocks in a material list
|
||||
//! \param mat Material structure to be filled
|
||||
void ParseLV2MaterialBlock(Material& mat);
|
||||
void ParseLV2MaterialBlock(Material &mat);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a *NODE_TM block in a file
|
||||
//! \param mesh Node (!) object to be filled
|
||||
void ParseLV2NodeTransformBlock(BaseNode& mesh);
|
||||
void ParseLV2NodeTransformBlock(BaseNode &mesh);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a *TM_ANIMATION block in a file
|
||||
//! \param mesh Mesh object to be filled
|
||||
void ParseLV2AnimationBlock(BaseNode& mesh);
|
||||
void ParseLV3PosAnimationBlock(ASE::Animation& anim);
|
||||
void ParseLV3ScaleAnimationBlock(ASE::Animation& anim);
|
||||
void ParseLV3RotAnimationBlock(ASE::Animation& anim);
|
||||
void ParseLV2AnimationBlock(BaseNode &mesh);
|
||||
void ParseLV3PosAnimationBlock(ASE::Animation &anim);
|
||||
void ParseLV3ScaleAnimationBlock(ASE::Animation &anim);
|
||||
void ParseLV3RotAnimationBlock(ASE::Animation &anim);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a *MESH block in a file
|
||||
//! \param mesh Mesh object to be filled
|
||||
void ParseLV2MeshBlock(Mesh& mesh);
|
||||
void ParseLV2MeshBlock(Mesh &mesh);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a *LIGHT_SETTINGS block in a file
|
||||
//! \param light Light object to be filled
|
||||
void ParseLV2LightSettingsBlock(Light& light);
|
||||
void ParseLV2LightSettingsBlock(Light &light);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a *CAMERA_SETTINGS block in a file
|
||||
//! \param cam Camera object to be filled
|
||||
void ParseLV2CameraSettingsBlock(Camera& cam);
|
||||
void ParseLV2CameraSettingsBlock(Camera &cam);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse the *MAP_XXXXXX blocks in a material
|
||||
//! \param map Texture structure to be filled
|
||||
void ParseLV3MapBlock(Texture& map);
|
||||
void ParseLV3MapBlock(Texture &map);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a *MESH_VERTEX_LIST block in a file
|
||||
|
@ -493,7 +467,7 @@ private:
|
|||
//! A warning is sent to the logger if the validations fails.
|
||||
//! \param mesh Mesh object to be filled
|
||||
void ParseLV3MeshVertexListBlock(
|
||||
unsigned int iNumVertices,Mesh& mesh);
|
||||
unsigned int iNumVertices, Mesh &mesh);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a *MESH_FACE_LIST block in a file
|
||||
|
@ -502,7 +476,7 @@ private:
|
|||
//! A warning is sent to the logger if the validations fails.
|
||||
//! \param mesh Mesh object to be filled
|
||||
void ParseLV3MeshFaceListBlock(
|
||||
unsigned int iNumFaces,Mesh& mesh);
|
||||
unsigned int iNumFaces, Mesh &mesh);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a *MESH_TVERT_LIST block in a file
|
||||
|
@ -512,7 +486,7 @@ private:
|
|||
//! \param mesh Mesh object to be filled
|
||||
//! \param iChannel Output UVW channel
|
||||
void ParseLV3MeshTListBlock(
|
||||
unsigned int iNumVertices,Mesh& mesh, unsigned int iChannel = 0);
|
||||
unsigned int iNumVertices, Mesh &mesh, unsigned int iChannel = 0);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a *MESH_TFACELIST block in a file
|
||||
|
@ -522,7 +496,7 @@ private:
|
|||
//! \param mesh Mesh object to be filled
|
||||
//! \param iChannel Output UVW channel
|
||||
void ParseLV3MeshTFaceListBlock(
|
||||
unsigned int iNumFaces,Mesh& mesh, unsigned int iChannel = 0);
|
||||
unsigned int iNumFaces, Mesh &mesh, unsigned int iChannel = 0);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse an additional mapping channel
|
||||
|
@ -530,7 +504,7 @@ private:
|
|||
//! \param iChannel Channel index to be filled
|
||||
//! \param mesh Mesh object to be filled
|
||||
void ParseLV3MappingChannel(
|
||||
unsigned int iChannel, Mesh& mesh);
|
||||
unsigned int iChannel, Mesh &mesh);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a *MESH_CVERTLIST block in a file
|
||||
|
@ -539,7 +513,7 @@ private:
|
|||
//! A warning is sent to the logger if the validations fails.
|
||||
//! \param mesh Mesh object to be filled
|
||||
void ParseLV3MeshCListBlock(
|
||||
unsigned int iNumVertices, Mesh& mesh);
|
||||
unsigned int iNumVertices, Mesh &mesh);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a *MESH_CFACELIST block in a file
|
||||
|
@ -548,70 +522,70 @@ private:
|
|||
//! A warning is sent to the logger if the validations fails.
|
||||
//! \param mesh Mesh object to be filled
|
||||
void ParseLV3MeshCFaceListBlock(
|
||||
unsigned int iNumFaces, Mesh& mesh);
|
||||
unsigned int iNumFaces, Mesh &mesh);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a *MESH_NORMALS block in a file
|
||||
//! \param mesh Mesh object to be filled
|
||||
void ParseLV3MeshNormalListBlock(Mesh& mesh);
|
||||
void ParseLV3MeshNormalListBlock(Mesh &mesh);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a *MESH_WEIGHTSblock in a file
|
||||
//! \param mesh Mesh object to be filled
|
||||
void ParseLV3MeshWeightsBlock(Mesh& mesh);
|
||||
void ParseLV3MeshWeightsBlock(Mesh &mesh);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse the bone list of a file
|
||||
//! \param mesh Mesh object to be filled
|
||||
//! \param iNumBones Number of bones in the mesh
|
||||
void ParseLV4MeshBones(unsigned int iNumBones,Mesh& mesh);
|
||||
void ParseLV4MeshBones(unsigned int iNumBones, Mesh &mesh);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse the bone vertices list of a file
|
||||
//! \param mesh Mesh object to be filled
|
||||
//! \param iNumVertices Number of vertices to be parsed
|
||||
void ParseLV4MeshBonesVertices(unsigned int iNumVertices,Mesh& mesh);
|
||||
void ParseLV4MeshBonesVertices(unsigned int iNumVertices, Mesh &mesh);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a *MESH_FACE block in a file
|
||||
//! \param out receive the face data
|
||||
void ParseLV4MeshFace(ASE::Face& out);
|
||||
void ParseLV4MeshFace(ASE::Face &out);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a *MESH_VERT block in a file
|
||||
//! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL ...)
|
||||
//! \param apOut Output buffer (3 floats)
|
||||
//! \param rIndexOut Output index
|
||||
void ParseLV4MeshFloatTriple(ai_real* apOut, unsigned int& rIndexOut);
|
||||
void ParseLV4MeshFloatTriple(ai_real *apOut, unsigned int &rIndexOut);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a *MESH_VERT block in a file
|
||||
//! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL ...)
|
||||
//! \param apOut Output buffer (3 floats)
|
||||
void ParseLV4MeshFloatTriple(ai_real* apOut);
|
||||
void ParseLV4MeshFloatTriple(ai_real *apOut);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a *MESH_TFACE block in a file
|
||||
//! (also works for MESH_CFACE)
|
||||
//! \param apOut Output buffer (3 ints)
|
||||
//! \param rIndexOut Output index
|
||||
void ParseLV4MeshLongTriple(unsigned int* apOut, unsigned int& rIndexOut);
|
||||
void ParseLV4MeshLongTriple(unsigned int *apOut, unsigned int &rIndexOut);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a *MESH_TFACE block in a file
|
||||
//! (also works for MESH_CFACE)
|
||||
//! \param apOut Output buffer (3 ints)
|
||||
void ParseLV4MeshLongTriple(unsigned int* apOut);
|
||||
void ParseLV4MeshLongTriple(unsigned int *apOut);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a single float element
|
||||
//! \param fOut Output float
|
||||
void ParseLV4MeshFloat(ai_real& fOut);
|
||||
void ParseLV4MeshFloat(ai_real &fOut);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a single int element
|
||||
//! \param iOut Output integer
|
||||
void ParseLV4MeshLong(unsigned int& iOut);
|
||||
void ParseLV4MeshLong(unsigned int &iOut);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Skip everything to the next: '*' or '\0'
|
||||
|
@ -625,17 +599,17 @@ private:
|
|||
// -------------------------------------------------------------------
|
||||
//! Output a warning to the logger
|
||||
//! \param szWarn Warn message
|
||||
void LogWarning(const char* szWarn);
|
||||
void LogWarning(const char *szWarn);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Output a message to the logger
|
||||
//! \param szWarn Message
|
||||
void LogInfo(const char* szWarn);
|
||||
void LogInfo(const char *szWarn);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Output an error to the logger
|
||||
//! \param szWarn Error message
|
||||
AI_WONT_RETURN void LogError(const char* szWarn) AI_WONT_RETURN_SUFFIX;
|
||||
AI_WONT_RETURN void LogError(const char *szWarn) AI_WONT_RETURN_SUFFIX;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a string, enclosed in double quotation marks
|
||||
|
@ -643,12 +617,11 @@ private:
|
|||
//! \param szName Name of the enclosing element -> used in error
|
||||
//! messages.
|
||||
//! \return false if an error occurred
|
||||
bool ParseString(std::string& out,const char* szName);
|
||||
bool ParseString(std::string &out, const char *szName);
|
||||
|
||||
public:
|
||||
|
||||
//! Pointer to current data
|
||||
const char* filePtr;
|
||||
const char *filePtr;
|
||||
|
||||
//! background color to be passed to the viewer
|
||||
//! QNAN if none was found
|
||||
|
@ -695,9 +668,8 @@ public:
|
|||
unsigned int iFileFormat;
|
||||
};
|
||||
|
||||
|
||||
} // Namespace ASE
|
||||
} // Namespace ASSIMP
|
||||
} // namespace Assimp
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_3DS_IMPORTER
|
||||
|
||||
|
|
|
@ -336,7 +336,7 @@ protected:
|
|||
void WriteBinaryNode(IOStream *container, const aiNode *node) {
|
||||
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AINODE);
|
||||
|
||||
unsigned int nb_metadata = (node->mMetaData != NULL ? node->mMetaData->mNumProperties : 0);
|
||||
unsigned int nb_metadata = (node->mMetaData != nullptr ? node->mMetaData->mNumProperties : 0);
|
||||
|
||||
Write<aiString>(&chunk, node->mName);
|
||||
Write<aiMatrix4x4>(&chunk, node->mTransformation);
|
||||
|
@ -744,7 +744,7 @@ public:
|
|||
};
|
||||
|
||||
try {
|
||||
time_t tt = time(NULL);
|
||||
time_t tt = time(nullptr);
|
||||
#if _WIN32
|
||||
tm *p = gmtime(&tt);
|
||||
#else
|
||||
|
@ -790,7 +790,7 @@ public:
|
|||
// Up to here the data is uncompressed. For compressed files, the rest
|
||||
// is compressed using standard DEFLATE from zlib.
|
||||
if (compressed) {
|
||||
AssbinChunkWriter uncompressedStream(NULL, 0);
|
||||
AssbinChunkWriter uncompressedStream(nullptr, 0);
|
||||
WriteBinaryScene(&uncompressedStream, pScene);
|
||||
|
||||
uLongf uncompressedSize = static_cast<uLongf>(uncompressedStream.Tell());
|
||||
|
|
|
@ -604,7 +604,7 @@ void AssbinImporter::ReadBinaryScene(IOStream *stream, aiScene *scene) {
|
|||
|
||||
// Read node graph
|
||||
//scene->mRootNode = new aiNode[1];
|
||||
ReadBinaryNode(stream, &scene->mRootNode, (aiNode *)NULL);
|
||||
ReadBinaryNode(stream, &scene->mRootNode, (aiNode *)nullptr);
|
||||
|
||||
// Read all meshes
|
||||
if (scene->mNumMeshes) {
|
||||
|
|
|
@ -189,7 +189,7 @@ static std::string encodeXML(const std::string &data) {
|
|||
// -----------------------------------------------------------------------------------
|
||||
// Write a text model dump
|
||||
static void WriteDump(const char *pFile, const char *cmd, const aiScene *scene, IOStream *io, bool shortened) {
|
||||
time_t tt = ::time(NULL);
|
||||
time_t tt = ::time(nullptr);
|
||||
#if _WIN32
|
||||
tm *p = gmtime(&tt);
|
||||
#else
|
||||
|
|
|
@ -422,9 +422,9 @@ void BVHLoader::CreateAnimation(aiScene *pScene) {
|
|||
anim->mNumChannels = static_cast<unsigned int>(mNodes.size());
|
||||
anim->mChannels = new aiNodeAnim *[anim->mNumChannels];
|
||||
|
||||
// FIX: set the array elements to NULL to ensure proper deletion if an exception is thrown
|
||||
// FIX: set the array elements to nullptr to ensure proper deletion if an exception is thrown
|
||||
for (unsigned int i = 0; i < anim->mNumChannels; ++i)
|
||||
anim->mChannels[i] = NULL;
|
||||
anim->mChannels[i] = nullptr;
|
||||
|
||||
for (unsigned int a = 0; a < anim->mNumChannels; a++) {
|
||||
const Node &node = mNodes[a];
|
||||
|
@ -493,37 +493,30 @@ void BVHLoader::CreateAnimation(aiScene *pScene) {
|
|||
for (unsigned int fr = 0; fr < mAnimNumFrames; ++fr) {
|
||||
aiMatrix4x4 temp;
|
||||
aiMatrix3x3 rotMatrix;
|
||||
for (BVHLoader::ChannelType channel = Channel_RotationX; channel <= Channel_RotationZ; channel = (BVHLoader::ChannelType)(channel + 1)) {
|
||||
//Find channel in node
|
||||
std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel);
|
||||
|
||||
if (mapIter == channelMap.end())
|
||||
throw DeadlyImportError("Missing rotation channel in node " + nodeName);
|
||||
else {
|
||||
int channelIdx = mapIter->second;
|
||||
// translate ZXY euler angels into a quaternion
|
||||
const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
|
||||
|
||||
// Compute rotation transformations in the right order
|
||||
switch (channel) {
|
||||
for (unsigned int channelIdx = 0; channelIdx < node.mChannels.size(); ++ channelIdx) {
|
||||
switch (node.mChannels[channelIdx]) {
|
||||
case Channel_RotationX:
|
||||
aiMatrix4x4::RotationX(angle, temp);
|
||||
rotMatrix *= aiMatrix3x3(temp);
|
||||
{
|
||||
const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
|
||||
aiMatrix4x4::RotationX( angle, temp); rotMatrix *= aiMatrix3x3( temp);
|
||||
}
|
||||
break;
|
||||
case Channel_RotationY:
|
||||
aiMatrix4x4::RotationY(angle, temp);
|
||||
rotMatrix *= aiMatrix3x3(temp);
|
||||
{
|
||||
const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
|
||||
aiMatrix4x4::RotationY( angle, temp); rotMatrix *= aiMatrix3x3( temp);
|
||||
}
|
||||
break;
|
||||
case Channel_RotationZ:
|
||||
aiMatrix4x4::RotationZ(angle, temp);
|
||||
rotMatrix *= aiMatrix3x3(temp);
|
||||
{
|
||||
const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
|
||||
aiMatrix4x4::RotationZ( angle, temp); rotMatrix *= aiMatrix3x3( temp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rotkey->mTime = double(fr);
|
||||
rotkey->mValue = aiQuaternion(rotMatrix);
|
||||
++rotkey;
|
||||
|
|
|
@ -353,7 +353,7 @@ void SectionParser ::Next() {
|
|||
}
|
||||
|
||||
#ifdef ASSIMP_BUILD_BLENDER_DEBUG
|
||||
ASSIMP_LOG_DEBUG(current.id);
|
||||
ASSIMP_LOG_VERBOSE_DEBUG(current.id);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -230,7 +230,7 @@ public:
|
|||
|
||||
// --------------------------------------------------------
|
||||
/** Access a field of the structure by its canonical name. The pointer version
|
||||
* returns NULL on failure while the reference version raises an import error. */
|
||||
* returns nullptr on failure while the reference version raises an import error. */
|
||||
inline const Field &operator[](const std::string &ss) const;
|
||||
inline const Field *Get(const std::string &ss) const;
|
||||
|
||||
|
@ -359,7 +359,7 @@ private:
|
|||
template <typename T>
|
||||
T *_allocate(vector<T> &out, size_t &s) const {
|
||||
out.resize(s);
|
||||
return s ? &out.front() : NULL;
|
||||
return s ? &out.front() : nullptr;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
@ -367,14 +367,14 @@ private:
|
|||
struct _defaultInitializer {
|
||||
|
||||
template <typename T, unsigned int N>
|
||||
void operator()(T (&out)[N], const char * = NULL) {
|
||||
void operator()(T (&out)[N], const char * = nullptr) {
|
||||
for (unsigned int i = 0; i < N; ++i) {
|
||||
out[i] = T();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, unsigned int N, unsigned int M>
|
||||
void operator()(T (&out)[N][M], const char * = NULL) {
|
||||
void operator()(T (&out)[N][M], const char * = nullptr) {
|
||||
for (unsigned int i = 0; i < N; ++i) {
|
||||
for (unsigned int j = 0; j < M; ++j) {
|
||||
out[i][j] = T();
|
||||
|
@ -383,7 +383,7 @@ private:
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
void operator()(T &out, const char * = NULL) {
|
||||
void operator()(T &out, const char * = nullptr) {
|
||||
out = T();
|
||||
}
|
||||
};
|
||||
|
@ -448,7 +448,7 @@ public:
|
|||
|
||||
public:
|
||||
// --------------------------------------------------------
|
||||
/** Access a structure by its canonical name, the pointer version returns NULL on failure
|
||||
/** Access a structure by its canonical name, the pointer version returns nullptr on failure
|
||||
* while the reference version raises an error. */
|
||||
inline const Structure &operator[](const std::string &ss) const;
|
||||
inline const Structure *Get(const std::string &ss) const;
|
||||
|
|
|
@ -4,7 +4,6 @@ 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,
|
||||
|
@ -70,7 +69,7 @@ const Field& Structure :: operator [] (const std::string& ss) const
|
|||
const Field* Structure :: Get (const std::string& ss) const
|
||||
{
|
||||
std::map<std::string, size_t>::const_iterator it = indices.find(ss);
|
||||
return it == indices.end() ? NULL : &fields[(*it).second];
|
||||
return it == indices.end() ? nullptr : &fields[(*it).second];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
|
@ -239,11 +238,13 @@ bool Structure :: ReadFieldPtr(TOUT<T> (&out)[N], const char* name,
|
|||
try {
|
||||
f = &(*this)[name];
|
||||
|
||||
#ifdef _DEBUG
|
||||
// sanity check, should never happen if the genblenddna script is right
|
||||
if ((FieldFlag_Pointer|FieldFlag_Pointer) != (f->flags & (FieldFlag_Pointer|FieldFlag_Pointer))) {
|
||||
throw Error((Formatter::format(),"Field `",name,"` of structure `",
|
||||
this->name,"` ought to be a pointer AND an array"));
|
||||
}
|
||||
#endif // _DEBUG
|
||||
|
||||
db.reader->IncPtr(f->offset);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -290,7 +290,7 @@ aiNode *COBImporter::BuildNodes(const Node &root, const Scene &scin, aiScene *fi
|
|||
}
|
||||
std::unique_ptr<const Material> defmat;
|
||||
if (!min) {
|
||||
ASSIMP_LOG_DEBUG(format() << "Could not resolve material index "
|
||||
ASSIMP_LOG_VERBOSE_DEBUG(format() << "Could not resolve material index "
|
||||
<< reflist.first << " - creating default material for this slot");
|
||||
|
||||
defmat.reset(min = new Material());
|
||||
|
@ -322,7 +322,9 @@ aiNode *COBImporter::BuildNodes(const Node &root, const Scene &scin, aiScene *fi
|
|||
break;
|
||||
|
||||
default:
|
||||
ASSIMP_LOG_ERROR("Unknown option.");
|
||||
ai_assert(false); // shouldn't be here
|
||||
break;
|
||||
}
|
||||
mat->AddProperty(&shader, 1, AI_MATKEY_SHADING_MODEL);
|
||||
if (shader != aiShadingMode_Gouraud) {
|
||||
|
|
|
@ -127,7 +127,7 @@ void CSMImporter::InternReadFile( const std::string& pFile,
|
|||
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
|
||||
|
||||
// Check whether we can read from the file
|
||||
if( file.get() == NULL) {
|
||||
if( file.get() == nullptr) {
|
||||
throw DeadlyImportError( "Failed to open CSM file " + pFile + ".");
|
||||
}
|
||||
|
||||
|
|
|
@ -44,8 +44,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
|
||||
|
||||
#include "ColladaExporter.h"
|
||||
|
||||
#include <assimp/Bitmap.h>
|
||||
#include <assimp/ColladaMetaData.h>
|
||||
#include <assimp/DefaultIOSystem.h>
|
||||
#include <assimp/Exceptional.h>
|
||||
#include <assimp/MathFunctions.h>
|
||||
#include <assimp/SceneCombiner.h>
|
||||
#include <assimp/StringUtils.h>
|
||||
|
@ -56,15 +59,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/Exporter.hpp>
|
||||
#include <assimp/IOSystem.hpp>
|
||||
|
||||
#include <assimp/Exceptional.h>
|
||||
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
|
@ -91,8 +87,6 @@ void ExportSceneCollada(const char *pFile, IOSystem *pIOSystem, const aiScene *p
|
|||
outfile->Write(iDoTheExportThing.mOutput.str().c_str(), static_cast<size_t>(iDoTheExportThing.mOutput.tellp()), 1);
|
||||
}
|
||||
|
||||
} // end of namespace Assimp
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Encodes a string into a valid XML ID using the xsd:ID schema qualifications.
|
||||
static const std::string XMLIDEncode(const std::string &name) {
|
||||
|
@ -115,7 +109,7 @@ static const std::string XMLIDEncode(const std::string &name) {
|
|||
if (strchr(XML_ID_CHARS, *it) != nullptr) {
|
||||
idEncoded << *it;
|
||||
} else {
|
||||
// Select placeholder character based on invalid character to prevent name collisions
|
||||
// Select placeholder character based on invalid character to reduce ID collisions
|
||||
idEncoded << XML_ID_CHARS[(*it) % XML_ID_CHARS_COUNT];
|
||||
}
|
||||
}
|
||||
|
@ -123,20 +117,37 @@ static const std::string XMLIDEncode(const std::string &name) {
|
|||
return idEncoded.str();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Helper functions to create unique ids
|
||||
inline bool IsUniqueId(const std::unordered_set<std::string> &idSet, const std::string &idStr) {
|
||||
return (idSet.find(idStr) == idSet.end());
|
||||
}
|
||||
|
||||
inline std::string MakeUniqueId(const std::unordered_set<std::string> &idSet, const std::string &idPrefix, const std::string &postfix) {
|
||||
std::string result(idPrefix + postfix);
|
||||
if (!IsUniqueId(idSet, result)) {
|
||||
// Select a number to append
|
||||
size_t idnum = 1;
|
||||
do {
|
||||
result = idPrefix + '_' + to_string(idnum) + postfix;
|
||||
++idnum;
|
||||
} while (!IsUniqueId(idSet, result));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor for a specific scene to export
|
||||
ColladaExporter::ColladaExporter(const aiScene *pScene, IOSystem *pIOSystem, const std::string &path, const std::string &file) :
|
||||
mIOSystem(pIOSystem), mPath(path), mFile(file) {
|
||||
mIOSystem(pIOSystem),
|
||||
mPath(path),
|
||||
mFile(file),
|
||||
mScene(pScene),
|
||||
endstr("\n") {
|
||||
// make sure that all formatting happens using the standard, C locale and not the user's current locale
|
||||
mOutput.imbue(std::locale("C"));
|
||||
mOutput.precision(ASSIMP_AI_REAL_TEXT_PRECISION);
|
||||
|
||||
mScene = pScene;
|
||||
mSceneOwned = false;
|
||||
|
||||
// set up strings
|
||||
endstr = "\n";
|
||||
|
||||
// start writing the file
|
||||
WriteFile();
|
||||
}
|
||||
|
@ -144,9 +155,6 @@ ColladaExporter::ColladaExporter(const aiScene *pScene, IOSystem *pIOSystem, con
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Destructor
|
||||
ColladaExporter::~ColladaExporter() {
|
||||
if (mSceneOwned) {
|
||||
delete mScene;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -161,6 +169,9 @@ void ColladaExporter::WriteFile() {
|
|||
WriteTextures();
|
||||
WriteHeader();
|
||||
|
||||
// Add node names to the unique id database first so they are most likely to use their names as unique ids
|
||||
CreateNodeIds(mScene->mRootNode);
|
||||
|
||||
WriteCamerasLibrary();
|
||||
WriteLightsLibrary();
|
||||
WriteMaterials();
|
||||
|
@ -172,10 +183,11 @@ void ColladaExporter::WriteFile() {
|
|||
// customized, Writes the animation library
|
||||
WriteAnimationsLibrary();
|
||||
|
||||
// useless Collada fu at the end, just in case we haven't had enough indirections, yet.
|
||||
// instantiate the scene(s)
|
||||
// For Assimp there will only ever be one
|
||||
mOutput << startstr << "<scene>" << endstr;
|
||||
PushTag();
|
||||
mOutput << startstr << "<instance_visual_scene url=\"#" + XMLIDEncode(mScene->mRootNode->mName.C_Str()) + "\" />" << endstr;
|
||||
mOutput << startstr << "<instance_visual_scene url=\"#" + mSceneId + "\" />" << endstr;
|
||||
PopTag();
|
||||
mOutput << startstr << "</scene>" << endstr;
|
||||
PopTag();
|
||||
|
@ -201,7 +213,7 @@ void ColladaExporter::WriteHeader() {
|
|||
|
||||
static const unsigned int date_nb_chars = 20;
|
||||
char date_str[date_nb_chars];
|
||||
std::time_t date = std::time(NULL);
|
||||
std::time_t date = std::time(nullptr);
|
||||
std::strftime(date_str, date_nb_chars, "%Y-%m-%dT%H:%M:%S", std::localtime(&date));
|
||||
|
||||
aiVector3D scaling;
|
||||
|
@ -210,13 +222,13 @@ void ColladaExporter::WriteHeader() {
|
|||
mScene->mRootNode->mTransformation.Decompose(scaling, rotation, position);
|
||||
rotation.Normalize();
|
||||
|
||||
bool add_root_node = false;
|
||||
mAdd_root_node = false;
|
||||
|
||||
ai_real scale = 1.0;
|
||||
if (std::abs(scaling.x - scaling.y) <= epsilon && std::abs(scaling.x - scaling.z) <= epsilon && std::abs(scaling.y - scaling.z) <= epsilon) {
|
||||
scale = (ai_real)((((double)scaling.x) + ((double)scaling.y) + ((double)scaling.z)) / 3.0);
|
||||
} else {
|
||||
add_root_node = true;
|
||||
mAdd_root_node = true;
|
||||
}
|
||||
|
||||
std::string up_axis = "Y_UP";
|
||||
|
@ -227,33 +239,19 @@ void ColladaExporter::WriteHeader() {
|
|||
} else if (rotation.Equal(z_rot, epsilon)) {
|
||||
up_axis = "Z_UP";
|
||||
} else {
|
||||
add_root_node = true;
|
||||
mAdd_root_node = true;
|
||||
}
|
||||
|
||||
if (!position.Equal(aiVector3D(0, 0, 0))) {
|
||||
add_root_node = true;
|
||||
mAdd_root_node = true;
|
||||
}
|
||||
|
||||
if (mScene->mRootNode->mNumChildren == 0) {
|
||||
add_root_node = true;
|
||||
// Assimp root nodes can have meshes, Collada Scenes cannot
|
||||
if (mScene->mRootNode->mNumChildren == 0 || mScene->mRootNode->mMeshes != 0) {
|
||||
mAdd_root_node = true;
|
||||
}
|
||||
|
||||
if (add_root_node) {
|
||||
aiScene *scene;
|
||||
SceneCombiner::CopyScene(&scene, mScene);
|
||||
|
||||
aiNode *root = new aiNode("Scene");
|
||||
|
||||
root->mNumChildren = 1;
|
||||
root->mChildren = new aiNode *[root->mNumChildren];
|
||||
|
||||
root->mChildren[0] = scene->mRootNode;
|
||||
scene->mRootNode->mParent = root;
|
||||
scene->mRootNode = root;
|
||||
|
||||
mScene = scene;
|
||||
mSceneOwned = true;
|
||||
|
||||
if (mAdd_root_node) {
|
||||
up_axis = "Y_UP";
|
||||
scale = 1.0;
|
||||
}
|
||||
|
@ -352,7 +350,7 @@ void ColladaExporter::WriteTextures() {
|
|||
std::string name = mFile + "_texture_" + (i < 1000 ? "0" : "") + (i < 100 ? "0" : "") + (i < 10 ? "0" : "") + str + "." + ((const char *)texture->achFormatHint);
|
||||
|
||||
std::unique_ptr<IOStream> outfile(mIOSystem->Open(mPath + mIOSystem->getOsSeparator() + name, "wb"));
|
||||
if (outfile == NULL) {
|
||||
if (outfile == nullptr) {
|
||||
throw DeadlyExportError("could not open output texture file: " + mPath + name);
|
||||
}
|
||||
|
||||
|
@ -388,10 +386,10 @@ void ColladaExporter::WriteCamerasLibrary() {
|
|||
void ColladaExporter::WriteCamera(size_t pIndex) {
|
||||
|
||||
const aiCamera *cam = mScene->mCameras[pIndex];
|
||||
const std::string cameraName = XMLEscape(cam->mName.C_Str());
|
||||
const std::string cameraId = XMLIDEncode(cam->mName.C_Str());
|
||||
const std::string cameraId = GetObjectUniqueId(AiObjectType::Camera, pIndex);
|
||||
const std::string cameraName = GetObjectName(AiObjectType::Camera, pIndex);
|
||||
|
||||
mOutput << startstr << "<camera id=\"" << cameraId << "-camera\" name=\"" << cameraName << "\" >" << endstr;
|
||||
mOutput << startstr << "<camera id=\"" << cameraId << "\" name=\"" << cameraName << "\" >" << endstr;
|
||||
PushTag();
|
||||
mOutput << startstr << "<optics>" << endstr;
|
||||
PushTag();
|
||||
|
@ -441,10 +439,10 @@ void ColladaExporter::WriteLightsLibrary() {
|
|||
void ColladaExporter::WriteLight(size_t pIndex) {
|
||||
|
||||
const aiLight *light = mScene->mLights[pIndex];
|
||||
const std::string lightName = XMLEscape(light->mName.C_Str());
|
||||
const std::string lightId = XMLIDEncode(light->mName.C_Str());
|
||||
const std::string lightId = GetObjectUniqueId(AiObjectType::Light, pIndex);
|
||||
const std::string lightName = GetObjectName(AiObjectType::Light, pIndex);
|
||||
|
||||
mOutput << startstr << "<light id=\"" << lightId << "-light\" name=\""
|
||||
mOutput << startstr << "<light id=\"" << lightId << "\" name=\""
|
||||
<< lightName << "\" >" << endstr;
|
||||
PushTag();
|
||||
mOutput << startstr << "<technique_common>" << endstr;
|
||||
|
@ -561,12 +559,11 @@ void ColladaExporter::WriteAmbienttLight(const aiLight *const light) {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads a single surface entry from the given material keys
|
||||
void ColladaExporter::ReadMaterialSurface(Surface &poSurface, const aiMaterial *pSrcMat,
|
||||
aiTextureType pTexture, const char *pKey, size_t pType, size_t pIndex) {
|
||||
if (pSrcMat->GetTextureCount(pTexture) > 0) {
|
||||
bool ColladaExporter::ReadMaterialSurface(Surface &poSurface, const aiMaterial &pSrcMat, aiTextureType pTexture, const char *pKey, size_t pType, size_t pIndex) {
|
||||
if (pSrcMat.GetTextureCount(pTexture) > 0) {
|
||||
aiString texfile;
|
||||
unsigned int uvChannel = 0;
|
||||
pSrcMat->GetTexture(pTexture, 0, &texfile, NULL, &uvChannel);
|
||||
pSrcMat.GetTexture(pTexture, 0, &texfile, nullptr, &uvChannel);
|
||||
|
||||
std::string index_str(texfile.C_Str());
|
||||
|
||||
|
@ -596,8 +593,9 @@ void ColladaExporter::ReadMaterialSurface(Surface &poSurface, const aiMaterial *
|
|||
poSurface.exist = true;
|
||||
} else {
|
||||
if (pKey)
|
||||
poSurface.exist = pSrcMat->Get(pKey, static_cast<unsigned int>(pType), static_cast<unsigned int>(pIndex), poSurface.color) == aiReturn_SUCCESS;
|
||||
poSurface.exist = pSrcMat.Get(pKey, static_cast<unsigned int>(pType), static_cast<unsigned int>(pIndex), poSurface.color) == aiReturn_SUCCESS;
|
||||
}
|
||||
return poSurface.exist;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -608,9 +606,9 @@ static bool isalnum_C(char c) {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Writes an image entry for the given surface
|
||||
void ColladaExporter::WriteImageEntry(const Surface &pSurface, const std::string &pNameAdd) {
|
||||
void ColladaExporter::WriteImageEntry(const Surface &pSurface, const std::string &imageId) {
|
||||
if (!pSurface.texture.empty()) {
|
||||
mOutput << startstr << "<image id=\"" << XMLIDEncode(pNameAdd) << "\">" << endstr;
|
||||
mOutput << startstr << "<image id=\"" << imageId << "\">" << endstr;
|
||||
PushTag();
|
||||
mOutput << startstr << "<init_from>";
|
||||
|
||||
|
@ -631,14 +629,14 @@ void ColladaExporter::WriteImageEntry(const Surface &pSurface, const std::string
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Writes a color-or-texture entry into an effect definition
|
||||
void ColladaExporter::WriteTextureColorEntry(const Surface &pSurface, const std::string &pTypeName, const std::string &pImageName) {
|
||||
void ColladaExporter::WriteTextureColorEntry(const Surface &pSurface, const std::string &pTypeName, const std::string &imageId) {
|
||||
if (pSurface.exist) {
|
||||
mOutput << startstr << "<" << pTypeName << ">" << endstr;
|
||||
PushTag();
|
||||
if (pSurface.texture.empty()) {
|
||||
mOutput << startstr << "<color sid=\"" << pTypeName << "\">" << pSurface.color.r << " " << pSurface.color.g << " " << pSurface.color.b << " " << pSurface.color.a << "</color>" << endstr;
|
||||
} else {
|
||||
mOutput << startstr << "<texture texture=\"" << XMLIDEncode(pImageName) << "\" texcoord=\"CHANNEL" << pSurface.channel << "\" />" << endstr;
|
||||
mOutput << startstr << "<texture texture=\"" << imageId << "\" texcoord=\"CHANNEL" << pSurface.channel << "\" />" << endstr;
|
||||
}
|
||||
PopTag();
|
||||
mOutput << startstr << "</" << pTypeName << ">" << endstr;
|
||||
|
@ -647,24 +645,24 @@ void ColladaExporter::WriteTextureColorEntry(const Surface &pSurface, const std:
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Writes the two parameters necessary for referencing a texture in an effect entry
|
||||
void ColladaExporter::WriteTextureParamEntry(const Surface &pSurface, const std::string &pTypeName, const std::string &pMatName) {
|
||||
void ColladaExporter::WriteTextureParamEntry(const Surface &pSurface, const std::string &pTypeName, const std::string &materialId) {
|
||||
// if surface is a texture, write out the sampler and the surface parameters necessary to reference the texture
|
||||
if (!pSurface.texture.empty()) {
|
||||
mOutput << startstr << "<newparam sid=\"" << XMLIDEncode(pMatName) << "-" << pTypeName << "-surface\">" << endstr;
|
||||
mOutput << startstr << "<newparam sid=\"" << materialId << "-" << pTypeName << "-surface\">" << endstr;
|
||||
PushTag();
|
||||
mOutput << startstr << "<surface type=\"2D\">" << endstr;
|
||||
PushTag();
|
||||
mOutput << startstr << "<init_from>" << XMLIDEncode(pMatName) << "-" << pTypeName << "-image</init_from>" << endstr;
|
||||
mOutput << startstr << "<init_from>" << materialId << "-" << pTypeName << "-image</init_from>" << endstr;
|
||||
PopTag();
|
||||
mOutput << startstr << "</surface>" << endstr;
|
||||
PopTag();
|
||||
mOutput << startstr << "</newparam>" << endstr;
|
||||
|
||||
mOutput << startstr << "<newparam sid=\"" << XMLIDEncode(pMatName) << "-" << pTypeName << "-sampler\">" << endstr;
|
||||
mOutput << startstr << "<newparam sid=\"" << materialId << "-" << pTypeName << "-sampler\">" << endstr;
|
||||
PushTag();
|
||||
mOutput << startstr << "<sampler2D>" << endstr;
|
||||
PushTag();
|
||||
mOutput << startstr << "<source>" << XMLIDEncode(pMatName) << "-" << pTypeName << "-surface</source>" << endstr;
|
||||
mOutput << startstr << "<source>" << materialId << "-" << pTypeName << "-surface</source>" << endstr;
|
||||
PopTag();
|
||||
mOutput << startstr << "</sampler2D>" << endstr;
|
||||
PopTag();
|
||||
|
@ -687,80 +685,63 @@ void ColladaExporter::WriteFloatEntry(const Property &pProperty, const std::stri
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Writes the material setup
|
||||
void ColladaExporter::WriteMaterials() {
|
||||
std::vector<Material> materials;
|
||||
materials.resize(mScene->mNumMaterials);
|
||||
|
||||
/// collect all materials from the scene
|
||||
size_t numTextures = 0;
|
||||
for (size_t a = 0; a < mScene->mNumMaterials; ++a) {
|
||||
const aiMaterial *mat = mScene->mMaterials[a];
|
||||
|
||||
aiString name;
|
||||
if (mat->Get(AI_MATKEY_NAME, name) != aiReturn_SUCCESS) {
|
||||
name = "mat";
|
||||
materials[a].name = std::string("m") + to_string(a) + name.C_Str();
|
||||
} else {
|
||||
// try to use the material's name if no other material has already taken it, else append #
|
||||
std::string testName = name.C_Str();
|
||||
size_t materialCountWithThisName = 0;
|
||||
for (size_t i = 0; i < a; i++) {
|
||||
if (materials[i].name == testName) {
|
||||
materialCountWithThisName++;
|
||||
}
|
||||
}
|
||||
if (materialCountWithThisName == 0) {
|
||||
materials[a].name = name.C_Str();
|
||||
} else {
|
||||
materials[a].name = std::string(name.C_Str()) + to_string(materialCountWithThisName);
|
||||
}
|
||||
}
|
||||
Material &material = materials[a];
|
||||
material.id = GetObjectUniqueId(AiObjectType::Material, a);
|
||||
material.name = GetObjectName(AiObjectType::Material, a);
|
||||
|
||||
const aiMaterial &mat = *(mScene->mMaterials[a]);
|
||||
aiShadingMode shading = aiShadingMode_Flat;
|
||||
materials[a].shading_model = "phong";
|
||||
if (mat->Get(AI_MATKEY_SHADING_MODEL, shading) == aiReturn_SUCCESS) {
|
||||
material.shading_model = "phong";
|
||||
if (mat.Get(AI_MATKEY_SHADING_MODEL, shading) == aiReturn_SUCCESS) {
|
||||
if (shading == aiShadingMode_Phong) {
|
||||
materials[a].shading_model = "phong";
|
||||
material.shading_model = "phong";
|
||||
} else if (shading == aiShadingMode_Blinn) {
|
||||
materials[a].shading_model = "blinn";
|
||||
material.shading_model = "blinn";
|
||||
} else if (shading == aiShadingMode_NoShading) {
|
||||
materials[a].shading_model = "constant";
|
||||
material.shading_model = "constant";
|
||||
} else if (shading == aiShadingMode_Gouraud) {
|
||||
materials[a].shading_model = "lambert";
|
||||
material.shading_model = "lambert";
|
||||
}
|
||||
}
|
||||
|
||||
ReadMaterialSurface(materials[a].ambient, mat, aiTextureType_AMBIENT, AI_MATKEY_COLOR_AMBIENT);
|
||||
if (!materials[a].ambient.texture.empty()) numTextures++;
|
||||
ReadMaterialSurface(materials[a].diffuse, mat, aiTextureType_DIFFUSE, AI_MATKEY_COLOR_DIFFUSE);
|
||||
if (!materials[a].diffuse.texture.empty()) numTextures++;
|
||||
ReadMaterialSurface(materials[a].specular, mat, aiTextureType_SPECULAR, AI_MATKEY_COLOR_SPECULAR);
|
||||
if (!materials[a].specular.texture.empty()) numTextures++;
|
||||
ReadMaterialSurface(materials[a].emissive, mat, aiTextureType_EMISSIVE, AI_MATKEY_COLOR_EMISSIVE);
|
||||
if (!materials[a].emissive.texture.empty()) numTextures++;
|
||||
ReadMaterialSurface(materials[a].reflective, mat, aiTextureType_REFLECTION, AI_MATKEY_COLOR_REFLECTIVE);
|
||||
if (!materials[a].reflective.texture.empty()) numTextures++;
|
||||
ReadMaterialSurface(materials[a].transparent, mat, aiTextureType_OPACITY, AI_MATKEY_COLOR_TRANSPARENT);
|
||||
if (!materials[a].transparent.texture.empty()) numTextures++;
|
||||
ReadMaterialSurface(materials[a].normal, mat, aiTextureType_NORMALS, NULL, 0, 0);
|
||||
if (!materials[a].normal.texture.empty()) numTextures++;
|
||||
if (ReadMaterialSurface(material.ambient, mat, aiTextureType_AMBIENT, AI_MATKEY_COLOR_AMBIENT))
|
||||
++numTextures;
|
||||
if (ReadMaterialSurface(material.diffuse, mat, aiTextureType_DIFFUSE, AI_MATKEY_COLOR_DIFFUSE))
|
||||
++numTextures;
|
||||
if (ReadMaterialSurface(material.specular, mat, aiTextureType_SPECULAR, AI_MATKEY_COLOR_SPECULAR))
|
||||
++numTextures;
|
||||
if (ReadMaterialSurface(material.emissive, mat, aiTextureType_EMISSIVE, AI_MATKEY_COLOR_EMISSIVE))
|
||||
++numTextures;
|
||||
if (ReadMaterialSurface(material.reflective, mat, aiTextureType_REFLECTION, AI_MATKEY_COLOR_REFLECTIVE))
|
||||
++numTextures;
|
||||
if (ReadMaterialSurface(material.transparent, mat, aiTextureType_OPACITY, AI_MATKEY_COLOR_TRANSPARENT))
|
||||
++numTextures;
|
||||
if (ReadMaterialSurface(material.normal, mat, aiTextureType_NORMALS, nullptr, 0, 0))
|
||||
++numTextures;
|
||||
|
||||
materials[a].shininess.exist = mat->Get(AI_MATKEY_SHININESS, materials[a].shininess.value) == aiReturn_SUCCESS;
|
||||
materials[a].transparency.exist = mat->Get(AI_MATKEY_OPACITY, materials[a].transparency.value) == aiReturn_SUCCESS;
|
||||
materials[a].index_refraction.exist = mat->Get(AI_MATKEY_REFRACTI, materials[a].index_refraction.value) == aiReturn_SUCCESS;
|
||||
material.shininess.exist = mat.Get(AI_MATKEY_SHININESS, material.shininess.value) == aiReturn_SUCCESS;
|
||||
material.transparency.exist = mat.Get(AI_MATKEY_OPACITY, material.transparency.value) == aiReturn_SUCCESS;
|
||||
material.index_refraction.exist = mat.Get(AI_MATKEY_REFRACTI, material.index_refraction.value) == aiReturn_SUCCESS;
|
||||
}
|
||||
|
||||
// output textures if present
|
||||
if (numTextures > 0) {
|
||||
mOutput << startstr << "<library_images>" << endstr;
|
||||
PushTag();
|
||||
for (std::vector<Material>::const_iterator it = materials.begin(); it != materials.end(); ++it) {
|
||||
const Material &mat = *it;
|
||||
WriteImageEntry(mat.ambient, mat.name + "-ambient-image");
|
||||
WriteImageEntry(mat.diffuse, mat.name + "-diffuse-image");
|
||||
WriteImageEntry(mat.specular, mat.name + "-specular-image");
|
||||
WriteImageEntry(mat.emissive, mat.name + "-emission-image");
|
||||
WriteImageEntry(mat.reflective, mat.name + "-reflective-image");
|
||||
WriteImageEntry(mat.transparent, mat.name + "-transparent-image");
|
||||
WriteImageEntry(mat.normal, mat.name + "-normal-image");
|
||||
for (const Material &mat : materials) {
|
||||
WriteImageEntry(mat.ambient, mat.id + "-ambient-image");
|
||||
WriteImageEntry(mat.diffuse, mat.id + "-diffuse-image");
|
||||
WriteImageEntry(mat.specular, mat.id + "-specular-image");
|
||||
WriteImageEntry(mat.emissive, mat.id + "-emission-image");
|
||||
WriteImageEntry(mat.reflective, mat.id + "-reflective-image");
|
||||
WriteImageEntry(mat.transparent, mat.id + "-transparent-image");
|
||||
WriteImageEntry(mat.normal, mat.id + "-normal-image");
|
||||
}
|
||||
PopTag();
|
||||
mOutput << startstr << "</library_images>" << endstr;
|
||||
|
@ -770,40 +751,39 @@ void ColladaExporter::WriteMaterials() {
|
|||
if (!materials.empty()) {
|
||||
mOutput << startstr << "<library_effects>" << endstr;
|
||||
PushTag();
|
||||
for (std::vector<Material>::const_iterator it = materials.begin(); it != materials.end(); ++it) {
|
||||
const Material &mat = *it;
|
||||
for (const Material &mat : materials) {
|
||||
// this is so ridiculous it must be right
|
||||
mOutput << startstr << "<effect id=\"" << XMLIDEncode(mat.name) << "-fx\" name=\"" << XMLEscape(mat.name) << "\">" << endstr;
|
||||
mOutput << startstr << "<effect id=\"" << mat.id << "-fx\" name=\"" << mat.name << "\">" << endstr;
|
||||
PushTag();
|
||||
mOutput << startstr << "<profile_COMMON>" << endstr;
|
||||
PushTag();
|
||||
|
||||
// write sampler- and surface params for the texture entries
|
||||
WriteTextureParamEntry(mat.emissive, "emission", mat.name);
|
||||
WriteTextureParamEntry(mat.ambient, "ambient", mat.name);
|
||||
WriteTextureParamEntry(mat.diffuse, "diffuse", mat.name);
|
||||
WriteTextureParamEntry(mat.specular, "specular", mat.name);
|
||||
WriteTextureParamEntry(mat.reflective, "reflective", mat.name);
|
||||
WriteTextureParamEntry(mat.transparent, "transparent", mat.name);
|
||||
WriteTextureParamEntry(mat.normal, "normal", mat.name);
|
||||
WriteTextureParamEntry(mat.emissive, "emission", mat.id);
|
||||
WriteTextureParamEntry(mat.ambient, "ambient", mat.id);
|
||||
WriteTextureParamEntry(mat.diffuse, "diffuse", mat.id);
|
||||
WriteTextureParamEntry(mat.specular, "specular", mat.id);
|
||||
WriteTextureParamEntry(mat.reflective, "reflective", mat.id);
|
||||
WriteTextureParamEntry(mat.transparent, "transparent", mat.id);
|
||||
WriteTextureParamEntry(mat.normal, "normal", mat.id);
|
||||
|
||||
mOutput << startstr << "<technique sid=\"standard\">" << endstr;
|
||||
PushTag();
|
||||
mOutput << startstr << "<" << mat.shading_model << ">" << endstr;
|
||||
PushTag();
|
||||
|
||||
WriteTextureColorEntry(mat.emissive, "emission", mat.name + "-emission-sampler");
|
||||
WriteTextureColorEntry(mat.ambient, "ambient", mat.name + "-ambient-sampler");
|
||||
WriteTextureColorEntry(mat.diffuse, "diffuse", mat.name + "-diffuse-sampler");
|
||||
WriteTextureColorEntry(mat.specular, "specular", mat.name + "-specular-sampler");
|
||||
WriteTextureColorEntry(mat.emissive, "emission", mat.id + "-emission-sampler");
|
||||
WriteTextureColorEntry(mat.ambient, "ambient", mat.id + "-ambient-sampler");
|
||||
WriteTextureColorEntry(mat.diffuse, "diffuse", mat.id + "-diffuse-sampler");
|
||||
WriteTextureColorEntry(mat.specular, "specular", mat.id + "-specular-sampler");
|
||||
WriteFloatEntry(mat.shininess, "shininess");
|
||||
WriteTextureColorEntry(mat.reflective, "reflective", mat.name + "-reflective-sampler");
|
||||
WriteTextureColorEntry(mat.transparent, "transparent", mat.name + "-transparent-sampler");
|
||||
WriteTextureColorEntry(mat.reflective, "reflective", mat.id + "-reflective-sampler");
|
||||
WriteTextureColorEntry(mat.transparent, "transparent", mat.id + "-transparent-sampler");
|
||||
WriteFloatEntry(mat.transparency, "transparency");
|
||||
WriteFloatEntry(mat.index_refraction, "index_of_refraction");
|
||||
|
||||
if (!mat.normal.texture.empty()) {
|
||||
WriteTextureColorEntry(mat.normal, "bump", mat.name + "-normal-sampler");
|
||||
WriteTextureColorEntry(mat.normal, "bump", mat.id + "-normal-sampler");
|
||||
}
|
||||
|
||||
PopTag();
|
||||
|
@ -823,9 +803,9 @@ void ColladaExporter::WriteMaterials() {
|
|||
PushTag();
|
||||
for (std::vector<Material>::const_iterator it = materials.begin(); it != materials.end(); ++it) {
|
||||
const Material &mat = *it;
|
||||
mOutput << startstr << "<material id=\"" << XMLIDEncode(mat.name) << "\" name=\"" << XMLEscape(mat.name) << "\">" << endstr;
|
||||
mOutput << startstr << "<material id=\"" << mat.id << "\" name=\"" << mat.name << "\">" << endstr;
|
||||
PushTag();
|
||||
mOutput << startstr << "<instance_effect url=\"#" << XMLIDEncode(mat.name) << "-fx\"/>" << endstr;
|
||||
mOutput << startstr << "<instance_effect url=\"#" << mat.id << "-fx\"/>" << endstr;
|
||||
PopTag();
|
||||
mOutput << startstr << "</material>" << endstr;
|
||||
}
|
||||
|
@ -852,20 +832,18 @@ void ColladaExporter::WriteControllerLibrary() {
|
|||
// Writes a skin controller of the given mesh
|
||||
void ColladaExporter::WriteController(size_t pIndex) {
|
||||
const aiMesh *mesh = mScene->mMeshes[pIndex];
|
||||
const std::string idstr = mesh->mName.length == 0 ? GetMeshId(pIndex) : mesh->mName.C_Str();
|
||||
const std::string idstrEscaped = XMLIDEncode(idstr);
|
||||
|
||||
if (mesh->mNumFaces == 0 || mesh->mNumVertices == 0)
|
||||
// Is there a skin controller?
|
||||
if (mesh->mNumBones == 0 || mesh->mNumFaces == 0 || mesh->mNumVertices == 0)
|
||||
return;
|
||||
|
||||
if (mesh->mNumBones == 0)
|
||||
return;
|
||||
const std::string idstr = GetObjectUniqueId(AiObjectType::Mesh, pIndex);
|
||||
const std::string namestr = GetObjectName(AiObjectType::Mesh, pIndex);
|
||||
|
||||
mOutput << startstr << "<controller id=\"" << idstrEscaped << "-skin\" ";
|
||||
mOutput << startstr << "<controller id=\"" << idstr << "-skin\" ";
|
||||
mOutput << "name=\"skinCluster" << pIndex << "\">" << endstr;
|
||||
PushTag();
|
||||
|
||||
mOutput << startstr << "<skin source=\"#" << idstrEscaped << "\">" << endstr;
|
||||
mOutput << startstr << "<skin source=\"#" << idstr << "\">" << endstr;
|
||||
PushTag();
|
||||
|
||||
// bind pose matrix
|
||||
|
@ -882,20 +860,20 @@ void ColladaExporter::WriteController(size_t pIndex) {
|
|||
PopTag();
|
||||
mOutput << startstr << "</bind_shape_matrix>" << endstr;
|
||||
|
||||
mOutput << startstr << "<source id=\"" << idstrEscaped << "-skin-joints\" name=\"" << idstrEscaped << "-skin-joints\">" << endstr;
|
||||
mOutput << startstr << "<source id=\"" << idstr << "-skin-joints\" name=\"" << namestr << "-skin-joints\">" << endstr;
|
||||
PushTag();
|
||||
|
||||
mOutput << startstr << "<Name_array id=\"" << idstrEscaped << "-skin-joints-array\" count=\"" << mesh->mNumBones << "\">";
|
||||
mOutput << startstr << "<Name_array id=\"" << idstr << "-skin-joints-array\" count=\"" << mesh->mNumBones << "\">";
|
||||
|
||||
for (size_t i = 0; i < mesh->mNumBones; ++i)
|
||||
mOutput << XMLIDEncode(mesh->mBones[i]->mName.C_Str()) << " ";
|
||||
mOutput << GetBoneUniqueId(mesh->mBones[i]) << ' ';
|
||||
|
||||
mOutput << "</Name_array>" << endstr;
|
||||
|
||||
mOutput << startstr << "<technique_common>" << endstr;
|
||||
PushTag();
|
||||
|
||||
mOutput << startstr << "<accessor source=\"#" << idstrEscaped << "-skin-joints-array\" count=\"" << mesh->mNumBones << "\" stride=\"" << 1 << "\">" << endstr;
|
||||
mOutput << startstr << "<accessor source=\"#" << idstr << "-skin-joints-array\" count=\"" << mesh->mNumBones << "\" stride=\"" << 1 << "\">" << endstr;
|
||||
PushTag();
|
||||
|
||||
mOutput << startstr << "<param name=\"JOINT\" type=\"Name\"></param>" << endstr;
|
||||
|
@ -932,8 +910,8 @@ void ColladaExporter::WriteController(size_t pIndex) {
|
|||
mOutput << startstr << "<joints>" << endstr;
|
||||
PushTag();
|
||||
|
||||
mOutput << startstr << "<input semantic=\"JOINT\" source=\"#" << idstrEscaped << "-skin-joints\"></input>" << endstr;
|
||||
mOutput << startstr << "<input semantic=\"INV_BIND_MATRIX\" source=\"#" << idstrEscaped << "-skin-bind_poses\"></input>" << endstr;
|
||||
mOutput << startstr << "<input semantic=\"JOINT\" source=\"#" << idstr << "-skin-joints\"></input>" << endstr;
|
||||
mOutput << startstr << "<input semantic=\"INV_BIND_MATRIX\" source=\"#" << idstr << "-skin-bind_poses\"></input>" << endstr;
|
||||
|
||||
PopTag();
|
||||
mOutput << startstr << "</joints>" << endstr;
|
||||
|
@ -941,8 +919,8 @@ void ColladaExporter::WriteController(size_t pIndex) {
|
|||
mOutput << startstr << "<vertex_weights count=\"" << mesh->mNumVertices << "\">" << endstr;
|
||||
PushTag();
|
||||
|
||||
mOutput << startstr << "<input semantic=\"JOINT\" source=\"#" << idstrEscaped << "-skin-joints\" offset=\"0\"></input>" << endstr;
|
||||
mOutput << startstr << "<input semantic=\"WEIGHT\" source=\"#" << idstrEscaped << "-skin-weights\" offset=\"1\"></input>" << endstr;
|
||||
mOutput << startstr << "<input semantic=\"JOINT\" source=\"#" << idstr << "-skin-joints\" offset=\"0\"></input>" << endstr;
|
||||
mOutput << startstr << "<input semantic=\"WEIGHT\" source=\"#" << idstr << "-skin-weights\" offset=\"1\"></input>" << endstr;
|
||||
|
||||
mOutput << startstr << "<vcount>";
|
||||
|
||||
|
@ -1017,9 +995,8 @@ void ColladaExporter::WriteGeometryLibrary() {
|
|||
// Writes the given mesh
|
||||
void ColladaExporter::WriteGeometry(size_t pIndex) {
|
||||
const aiMesh *mesh = mScene->mMeshes[pIndex];
|
||||
const std::string idstr = mesh->mName.length == 0 ? GetMeshId(pIndex) : mesh->mName.C_Str();
|
||||
const std::string geometryName = XMLEscape(idstr);
|
||||
const std::string geometryId = XMLIDEncode(idstr);
|
||||
const std::string geometryId = GetObjectUniqueId(AiObjectType::Mesh, pIndex);
|
||||
const std::string geometryName = GetObjectName(AiObjectType::Mesh, pIndex);
|
||||
|
||||
if (mesh->mNumFaces == 0 || mesh->mNumVertices == 0)
|
||||
return;
|
||||
|
@ -1032,15 +1009,15 @@ void ColladaExporter::WriteGeometry(size_t pIndex) {
|
|||
PushTag();
|
||||
|
||||
// Positions
|
||||
WriteFloatArray(idstr + "-positions", FloatType_Vector, (ai_real *)mesh->mVertices, mesh->mNumVertices);
|
||||
WriteFloatArray(geometryId + "-positions", FloatType_Vector, (ai_real *)mesh->mVertices, mesh->mNumVertices);
|
||||
// Normals, if any
|
||||
if (mesh->HasNormals())
|
||||
WriteFloatArray(idstr + "-normals", FloatType_Vector, (ai_real *)mesh->mNormals, mesh->mNumVertices);
|
||||
WriteFloatArray(geometryId + "-normals", FloatType_Vector, (ai_real *)mesh->mNormals, mesh->mNumVertices);
|
||||
|
||||
// texture coords
|
||||
for (size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
|
||||
if (mesh->HasTextureCoords(static_cast<unsigned int>(a))) {
|
||||
WriteFloatArray(idstr + "-tex" + to_string(a), mesh->mNumUVComponents[a] == 3 ? FloatType_TexCoord3 : FloatType_TexCoord2,
|
||||
WriteFloatArray(geometryId + "-tex" + to_string(a), mesh->mNumUVComponents[a] == 3 ? FloatType_TexCoord3 : FloatType_TexCoord2,
|
||||
(ai_real *)mesh->mTextureCoords[a], mesh->mNumVertices);
|
||||
}
|
||||
}
|
||||
|
@ -1048,7 +1025,7 @@ void ColladaExporter::WriteGeometry(size_t pIndex) {
|
|||
// vertex colors
|
||||
for (size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
|
||||
if (mesh->HasVertexColors(static_cast<unsigned int>(a)))
|
||||
WriteFloatArray(idstr + "-color" + to_string(a), FloatType_Color, (ai_real *)mesh->mColors[a], mesh->mNumVertices);
|
||||
WriteFloatArray(geometryId + "-color" + to_string(a), FloatType_Color, (ai_real *)mesh->mColors[a], mesh->mNumVertices);
|
||||
}
|
||||
|
||||
// assemble vertex structure
|
||||
|
@ -1248,17 +1225,29 @@ void ColladaExporter::WriteFloatArray(const std::string &pIdString, FloatDataTyp
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Writes the scene library
|
||||
void ColladaExporter::WriteSceneLibrary() {
|
||||
const std::string sceneName = XMLEscape(mScene->mRootNode->mName.C_Str());
|
||||
const std::string sceneId = XMLIDEncode(mScene->mRootNode->mName.C_Str());
|
||||
// Determine if we are using the aiScene root or our own
|
||||
std::string sceneName("Scene");
|
||||
if (mAdd_root_node) {
|
||||
mSceneId = MakeUniqueId(mUniqueIds, sceneName, std::string());
|
||||
mUniqueIds.insert(mSceneId);
|
||||
} else {
|
||||
mSceneId = GetNodeUniqueId(mScene->mRootNode);
|
||||
sceneName = GetNodeName(mScene->mRootNode);
|
||||
}
|
||||
|
||||
mOutput << startstr << "<library_visual_scenes>" << endstr;
|
||||
PushTag();
|
||||
mOutput << startstr << "<visual_scene id=\"" + sceneId + "\" name=\"" + sceneName + "\">" << endstr;
|
||||
mOutput << startstr << "<visual_scene id=\"" + mSceneId + "\" name=\"" + sceneName + "\">" << endstr;
|
||||
PushTag();
|
||||
|
||||
// start recursive write at the root node
|
||||
if (mAdd_root_node) {
|
||||
// Export the root node
|
||||
WriteNode(mScene->mRootNode);
|
||||
} else {
|
||||
// Have already exported the root node
|
||||
for (size_t a = 0; a < mScene->mRootNode->mNumChildren; ++a)
|
||||
WriteNode(mScene, mScene->mRootNode->mChildren[a]);
|
||||
WriteNode(mScene->mRootNode->mChildren[a]);
|
||||
}
|
||||
|
||||
PopTag();
|
||||
mOutput << startstr << "</visual_scene>" << endstr;
|
||||
|
@ -1272,20 +1261,10 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex) {
|
|||
if (anim->mNumChannels == 0 && anim->mNumMeshChannels == 0 && anim->mNumMorphMeshChannels == 0)
|
||||
return;
|
||||
|
||||
const std::string animation_name_escaped = XMLEscape(anim->mName.C_Str());
|
||||
std::string idstr = anim->mName.C_Str();
|
||||
std::string ending = std::string("AnimId") + to_string(pIndex);
|
||||
if (idstr.length() >= ending.length()) {
|
||||
if (0 != idstr.compare(idstr.length() - ending.length(), ending.length(), ending)) {
|
||||
idstr = idstr + ending;
|
||||
}
|
||||
} else {
|
||||
idstr = idstr + ending;
|
||||
}
|
||||
const std::string animationNameEscaped = GetObjectName(AiObjectType::Animation, pIndex);
|
||||
const std::string idstrEscaped = GetObjectUniqueId(AiObjectType::Animation, pIndex);
|
||||
|
||||
const std::string idstrEscaped = XMLIDEncode(idstr);
|
||||
|
||||
mOutput << startstr << "<animation id=\"" + idstrEscaped + "\" name=\"" + animation_name_escaped + "\">" << endstr;
|
||||
mOutput << startstr << "<animation id=\"" + idstrEscaped + "\" name=\"" + animationNameEscaped + "\">" << endstr;
|
||||
PushTag();
|
||||
|
||||
std::string cur_node_idstr;
|
||||
|
@ -1435,20 +1414,21 @@ void ColladaExporter::WriteAnimationsLibrary() {
|
|||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Helper to find a bone by name in the scene
|
||||
aiBone *findBone(const aiScene *scene, const char *name) {
|
||||
aiBone *findBone(const aiScene *scene, const aiString &name) {
|
||||
for (size_t m = 0; m < scene->mNumMeshes; m++) {
|
||||
aiMesh *mesh = scene->mMeshes[m];
|
||||
for (size_t b = 0; b < mesh->mNumBones; b++) {
|
||||
aiBone *bone = mesh->mBones[b];
|
||||
if (0 == strcmp(name, bone->mName.C_Str())) {
|
||||
if (name == bone->mName) {
|
||||
return bone;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Helper to find the node associated with a bone in the scene
|
||||
const aiNode *findBoneNode(const aiNode *aNode, const aiBone *bone) {
|
||||
if (aNode && bone && aNode->mName == bone->mName) {
|
||||
return aNode;
|
||||
|
@ -1457,15 +1437,17 @@ const aiNode *findBoneNode(const aiNode *aNode, const aiBone *bone) {
|
|||
if (aNode && bone) {
|
||||
for (unsigned int i = 0; i < aNode->mNumChildren; ++i) {
|
||||
aiNode *aChild = aNode->mChildren[i];
|
||||
const aiNode *foundFromChild = 0;
|
||||
const aiNode *foundFromChild = nullptr;
|
||||
if (aChild) {
|
||||
foundFromChild = findBoneNode(aChild, bone);
|
||||
if (foundFromChild) return foundFromChild;
|
||||
if (foundFromChild) {
|
||||
return foundFromChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const aiNode *findSkeletonRootNode(const aiScene *scene, const aiMesh *mesh) {
|
||||
|
@ -1476,7 +1458,7 @@ const aiNode *findSkeletonRootNode(const aiScene *scene, const aiMesh *mesh) {
|
|||
|
||||
const aiNode *node = findBoneNode(scene->mRootNode, bone);
|
||||
if (node) {
|
||||
while (node->mParent && findBone(scene, node->mParent->mName.C_Str()) != 0) {
|
||||
while (node->mParent && findBone(scene, node->mParent->mName) != nullptr) {
|
||||
node = node->mParent;
|
||||
}
|
||||
topParentBoneNodes.insert(node);
|
||||
|
@ -1496,45 +1478,36 @@ const aiNode *findSkeletonRootNode(const aiScene *scene, const aiMesh *mesh) {
|
|||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Recursively writes the given node
|
||||
void ColladaExporter::WriteNode(const aiScene *pScene, aiNode *pNode) {
|
||||
// the node must have a name
|
||||
if (pNode->mName.length == 0) {
|
||||
std::stringstream ss;
|
||||
ss << "Node_" << pNode;
|
||||
pNode->mName.Set(ss.str());
|
||||
}
|
||||
|
||||
void ColladaExporter::WriteNode(const aiNode *pNode) {
|
||||
// If the node is associated with a bone, it is a joint node (JOINT)
|
||||
// otherwise it is a normal node (NODE)
|
||||
// Assimp-specific: nodes with no name cannot be associated with bones
|
||||
const char *node_type;
|
||||
bool is_joint, is_skeleton_root = false;
|
||||
if (nullptr == findBone(pScene, pNode->mName.C_Str())) {
|
||||
if (pNode->mName.length == 0 || nullptr == findBone(mScene, pNode->mName)) {
|
||||
node_type = "NODE";
|
||||
is_joint = false;
|
||||
} else {
|
||||
node_type = "JOINT";
|
||||
is_joint = true;
|
||||
if (!pNode->mParent || nullptr == findBone(pScene, pNode->mParent->mName.C_Str())) {
|
||||
if (!pNode->mParent || nullptr == findBone(mScene, pNode->mParent->mName)) {
|
||||
is_skeleton_root = true;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string node_id = XMLIDEncode(pNode->mName.data);
|
||||
const std::string node_name = XMLEscape(pNode->mName.data);
|
||||
const std::string node_id = GetNodeUniqueId(pNode);
|
||||
const std::string node_name = GetNodeName(pNode);
|
||||
mOutput << startstr << "<node ";
|
||||
if (is_skeleton_root) {
|
||||
mOutput << "id=\"" << node_id << "\" " << (is_joint ? "sid=\"" + node_id + "\"" : ""); // For now, only support one skeleton in a scene.
|
||||
mFoundSkeletonRootNodeID = node_id;
|
||||
} else {
|
||||
mOutput << "id=\"" << node_id << "\" " << (is_joint ? "sid=\"" + node_id + "\"" : "");
|
||||
mFoundSkeletonRootNodeID = node_id; // For now, only support one skeleton in a scene.
|
||||
}
|
||||
|
||||
mOutput << " name=\"" << node_name
|
||||
mOutput << "id=\"" << node_id << "\" " << (is_joint ? "sid=\"" + node_id + "\" " : "");
|
||||
mOutput << "name=\"" << node_name
|
||||
<< "\" type=\"" << node_type
|
||||
<< "\">" << endstr;
|
||||
PushTag();
|
||||
|
@ -1573,14 +1546,14 @@ void ColladaExporter::WriteNode(const aiScene *pScene, aiNode *pNode) {
|
|||
//check if it is a camera node
|
||||
for (size_t i = 0; i < mScene->mNumCameras; i++) {
|
||||
if (mScene->mCameras[i]->mName == pNode->mName) {
|
||||
mOutput << startstr << "<instance_camera url=\"#" << node_id << "-camera\"/>" << endstr;
|
||||
mOutput << startstr << "<instance_camera url=\"#" << GetObjectUniqueId(AiObjectType::Camera, i) << "\"/>" << endstr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//check if it is a light node
|
||||
for (size_t i = 0; i < mScene->mNumLights; i++) {
|
||||
if (mScene->mLights[i]->mName == pNode->mName) {
|
||||
mOutput << startstr << "<instance_light url=\"#" << node_id << "-light\"/>" << endstr;
|
||||
mOutput << startstr << "<instance_light url=\"#" << GetObjectUniqueId(AiObjectType::Light, i) << "\"/>" << endstr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1593,22 +1566,22 @@ void ColladaExporter::WriteNode(const aiScene *pScene, aiNode *pNode) {
|
|||
if (mesh->mNumFaces == 0 || mesh->mNumVertices == 0)
|
||||
continue;
|
||||
|
||||
const std::string meshName = mesh->mName.length == 0 ? GetMeshId(pNode->mMeshes[a]) : mesh->mName.C_Str();
|
||||
const std::string meshId = GetObjectUniqueId(AiObjectType::Mesh, pNode->mMeshes[a]);
|
||||
|
||||
if (mesh->mNumBones == 0) {
|
||||
mOutput << startstr << "<instance_geometry url=\"#" << XMLIDEncode(meshName) << "\">" << endstr;
|
||||
mOutput << startstr << "<instance_geometry url=\"#" << meshId << "\">" << endstr;
|
||||
PushTag();
|
||||
} else {
|
||||
mOutput << startstr
|
||||
<< "<instance_controller url=\"#" << XMLIDEncode(meshName) << "-skin\">"
|
||||
<< "<instance_controller url=\"#" << meshId << "-skin\">"
|
||||
<< endstr;
|
||||
PushTag();
|
||||
|
||||
// note! this mFoundSkeletonRootNodeID some how affects animation, it makes the mesh attaches to armature skeleton root node.
|
||||
// use the first bone to find skeleton root
|
||||
const aiNode *skeletonRootBoneNode = findSkeletonRootNode(pScene, mesh);
|
||||
const aiNode *skeletonRootBoneNode = findSkeletonRootNode(mScene, mesh);
|
||||
if (skeletonRootBoneNode) {
|
||||
mFoundSkeletonRootNodeID = XMLIDEncode(skeletonRootBoneNode->mName.C_Str());
|
||||
mFoundSkeletonRootNodeID = GetNodeUniqueId(skeletonRootBoneNode);
|
||||
}
|
||||
mOutput << startstr << "<skeleton>#" << mFoundSkeletonRootNodeID << "</skeleton>" << endstr;
|
||||
}
|
||||
|
@ -1616,7 +1589,7 @@ void ColladaExporter::WriteNode(const aiScene *pScene, aiNode *pNode) {
|
|||
PushTag();
|
||||
mOutput << startstr << "<technique_common>" << endstr;
|
||||
PushTag();
|
||||
mOutput << startstr << "<instance_material symbol=\"defaultMaterial\" target=\"#" << XMLIDEncode(materials[mesh->mMaterialIndex].name) << "\">" << endstr;
|
||||
mOutput << startstr << "<instance_material symbol=\"defaultMaterial\" target=\"#" << GetObjectUniqueId(AiObjectType::Material, mesh->mMaterialIndex) << "\">" << endstr;
|
||||
PushTag();
|
||||
for (size_t aa = 0; aa < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++aa) {
|
||||
if (mesh->HasTextureCoords(static_cast<unsigned int>(aa)))
|
||||
|
@ -1641,11 +1614,135 @@ void ColladaExporter::WriteNode(const aiScene *pScene, aiNode *pNode) {
|
|||
|
||||
// recurse into subnodes
|
||||
for (size_t a = 0; a < pNode->mNumChildren; ++a)
|
||||
WriteNode(pScene, pNode->mChildren[a]);
|
||||
WriteNode(pNode->mChildren[a]);
|
||||
|
||||
PopTag();
|
||||
mOutput << startstr << "</node>" << endstr;
|
||||
}
|
||||
|
||||
void ColladaExporter::CreateNodeIds(const aiNode *node) {
|
||||
GetNodeUniqueId(node);
|
||||
for (size_t a = 0; a < node->mNumChildren; ++a)
|
||||
CreateNodeIds(node->mChildren[a]);
|
||||
}
|
||||
|
||||
std::string ColladaExporter::GetNodeUniqueId(const aiNode *node) {
|
||||
// Use the pointer as the key. This is safe because the scene is immutable.
|
||||
auto idIt = mNodeIdMap.find(node);
|
||||
if (idIt != mNodeIdMap.cend())
|
||||
return idIt->second;
|
||||
|
||||
// Prefer the requested Collada Id if extant
|
||||
std::string idStr;
|
||||
aiString origId;
|
||||
if (node->mMetaData && node->mMetaData->Get(AI_METADATA_COLLADA_ID, origId)) {
|
||||
idStr = origId.C_Str();
|
||||
} else {
|
||||
idStr = node->mName.C_Str();
|
||||
}
|
||||
// Make sure the requested id is valid
|
||||
if (idStr.empty())
|
||||
idStr = "node";
|
||||
else
|
||||
idStr = XMLIDEncode(idStr);
|
||||
|
||||
// Ensure it's unique
|
||||
idStr = MakeUniqueId(mUniqueIds, idStr, std::string());
|
||||
mUniqueIds.insert(idStr);
|
||||
mNodeIdMap.insert(std::make_pair(node, idStr));
|
||||
return idStr;
|
||||
}
|
||||
|
||||
std::string ColladaExporter::GetNodeName(const aiNode *node) {
|
||||
|
||||
return XMLEscape(node->mName.C_Str());
|
||||
}
|
||||
|
||||
std::string ColladaExporter::GetBoneUniqueId(const aiBone *bone) {
|
||||
// Find the Node that is this Bone
|
||||
const aiNode *boneNode = findBoneNode(mScene->mRootNode, bone);
|
||||
if (boneNode == nullptr)
|
||||
return std::string();
|
||||
|
||||
return GetNodeUniqueId(boneNode);
|
||||
}
|
||||
|
||||
std::string ColladaExporter::GetObjectUniqueId(AiObjectType type, size_t pIndex) {
|
||||
auto idIt = GetObjectIdMap(type).find(pIndex);
|
||||
if (idIt != GetObjectIdMap(type).cend())
|
||||
return idIt->second;
|
||||
|
||||
// Not seen this object before, create and add
|
||||
NameIdPair result = AddObjectIndexToMaps(type, pIndex);
|
||||
return result.second;
|
||||
}
|
||||
|
||||
std::string ColladaExporter::GetObjectName(AiObjectType type, size_t pIndex) {
|
||||
auto objectName = GetObjectNameMap(type).find(pIndex);
|
||||
if (objectName != GetObjectNameMap(type).cend())
|
||||
return objectName->second;
|
||||
|
||||
// Not seen this object before, create and add
|
||||
NameIdPair result = AddObjectIndexToMaps(type, pIndex);
|
||||
return result.first;
|
||||
}
|
||||
|
||||
// Determine unique id and add the name and id to the maps
|
||||
// @param type object type
|
||||
// @param index object index
|
||||
// @param name in/out. Caller to set the original name if known.
|
||||
// @param idStr in/out. Caller to set the preferred id if known.
|
||||
ColladaExporter::NameIdPair ColladaExporter::AddObjectIndexToMaps(AiObjectType type, size_t index) {
|
||||
|
||||
std::string name;
|
||||
std::string idStr;
|
||||
std::string idPostfix;
|
||||
|
||||
// Get the name and id postfix
|
||||
switch (type) {
|
||||
case AiObjectType::Mesh: name = mScene->mMeshes[index]->mName.C_Str(); break;
|
||||
case AiObjectType::Material: name = mScene->mMaterials[index]->GetName().C_Str(); break;
|
||||
case AiObjectType::Animation: name = mScene->mAnimations[index]->mName.C_Str(); break;
|
||||
case AiObjectType::Light:
|
||||
name = mScene->mLights[index]->mName.C_Str();
|
||||
idPostfix = "-light";
|
||||
break;
|
||||
case AiObjectType::Camera:
|
||||
name = mScene->mCameras[index]->mName.C_Str();
|
||||
idPostfix = "-camera";
|
||||
break;
|
||||
case AiObjectType::Count: throw std::logic_error("ColladaExporter::AiObjectType::Count is not an object type");
|
||||
}
|
||||
|
||||
if (name.empty()) {
|
||||
// Default ids if empty name
|
||||
switch (type) {
|
||||
case AiObjectType::Mesh: idStr = std::string("mesh_"); break;
|
||||
case AiObjectType::Material: idStr = std::string("material_"); break; // This one should never happen
|
||||
case AiObjectType::Animation: idStr = std::string("animation_"); break;
|
||||
case AiObjectType::Light: idStr = std::string("light_"); break;
|
||||
case AiObjectType::Camera: idStr = std::string("camera_"); break;
|
||||
case AiObjectType::Count: throw std::logic_error("ColladaExporter::AiObjectType::Count is not an object type");
|
||||
}
|
||||
idStr.append(to_string(index));
|
||||
} else {
|
||||
idStr = XMLIDEncode(name);
|
||||
}
|
||||
|
||||
if (!name.empty())
|
||||
name = XMLEscape(name);
|
||||
|
||||
idStr = MakeUniqueId(mUniqueIds, idStr, idPostfix);
|
||||
|
||||
// Add to maps
|
||||
mUniqueIds.insert(idStr);
|
||||
GetObjectIdMap(type).insert(std::make_pair(index, idStr));
|
||||
GetObjectNameMap(type).insert(std::make_pair(index, name));
|
||||
|
||||
return std::make_pair(name, idStr);
|
||||
}
|
||||
|
||||
} // end of namespace Assimp
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -48,28 +48,28 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include <assimp/ai_assert.h>
|
||||
#include <assimp/material.h>
|
||||
#include <assimp/mesh.h>
|
||||
#include <assimp/light.h>
|
||||
#include <assimp/Exporter.hpp>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <assimp/StringUtils.h>
|
||||
#include <array>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
struct aiScene;
|
||||
struct aiNode;
|
||||
struct aiLight;
|
||||
struct aiBone;
|
||||
|
||||
namespace Assimp
|
||||
{
|
||||
namespace Assimp {
|
||||
|
||||
class IOSystem;
|
||||
|
||||
/// Helper class to export a given scene to a Collada file. Just for my personal
|
||||
/// comfort when implementing it.
|
||||
class ColladaExporter
|
||||
{
|
||||
class ColladaExporter {
|
||||
public:
|
||||
/// Constructor for a specific scene to export
|
||||
ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file);
|
||||
ColladaExporter(const aiScene *pScene, IOSystem *pIOSystem, const std::string &path, const std::string &file);
|
||||
|
||||
/// Destructor
|
||||
virtual ~ColladaExporter();
|
||||
|
@ -107,51 +107,87 @@ protected:
|
|||
void WriteControllerLibrary();
|
||||
|
||||
/// Writes a skin controller of the given mesh
|
||||
void WriteController( size_t pIndex);
|
||||
void WriteController(size_t pIndex);
|
||||
|
||||
/// Writes the geometry library
|
||||
void WriteGeometryLibrary();
|
||||
|
||||
/// Writes the given mesh
|
||||
void WriteGeometry( size_t pIndex);
|
||||
void WriteGeometry(size_t pIndex);
|
||||
|
||||
//enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color, FloatType_Mat4x4, FloatType_Weight };
|
||||
// customized to add animation related type
|
||||
enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color, FloatType_Mat4x4, FloatType_Weight, FloatType_Time };
|
||||
enum FloatDataType { FloatType_Vector,
|
||||
FloatType_TexCoord2,
|
||||
FloatType_TexCoord3,
|
||||
FloatType_Color,
|
||||
FloatType_Mat4x4,
|
||||
FloatType_Weight,
|
||||
FloatType_Time };
|
||||
|
||||
/// Writes a float array of the given type
|
||||
void WriteFloatArray( const std::string& pIdString, FloatDataType pType, const ai_real* pData, size_t pElementCount);
|
||||
void WriteFloatArray(const std::string &pIdString, FloatDataType pType, const ai_real *pData, size_t pElementCount);
|
||||
|
||||
/// Writes the scene library
|
||||
void WriteSceneLibrary();
|
||||
|
||||
// customized, Writes the animation library
|
||||
void WriteAnimationsLibrary();
|
||||
void WriteAnimationLibrary( size_t pIndex);
|
||||
void WriteAnimationLibrary(size_t pIndex);
|
||||
std::string mFoundSkeletonRootNodeID = "skeleton_root"; // will be replaced by found node id in the WriteNode call.
|
||||
|
||||
/// Recursively writes the given node
|
||||
void WriteNode( const aiScene* scene, aiNode* pNode);
|
||||
void WriteNode(const aiNode *pNode);
|
||||
|
||||
/// Enters a new xml element, which increases the indentation
|
||||
void PushTag() { startstr.append( " "); }
|
||||
void PushTag() { startstr.append(" "); }
|
||||
/// Leaves an element, decreasing the indentation
|
||||
void PopTag() {
|
||||
ai_assert( startstr.length() > 1);
|
||||
startstr.erase( startstr.length() - 2);
|
||||
ai_assert(startstr.length() > 1);
|
||||
startstr.erase(startstr.length() - 2);
|
||||
}
|
||||
|
||||
/// Creates a mesh ID for the given mesh
|
||||
std::string GetMeshId( size_t pIndex) const {
|
||||
return std::string( "meshId" ) + to_string(pIndex);
|
||||
}
|
||||
void CreateNodeIds(const aiNode *node);
|
||||
|
||||
/// Get or Create a unique Node ID string for the given Node
|
||||
std::string GetNodeUniqueId(const aiNode *node);
|
||||
std::string GetNodeName(const aiNode *node);
|
||||
|
||||
std::string GetBoneUniqueId(const aiBone *bone);
|
||||
|
||||
enum class AiObjectType {
|
||||
Mesh,
|
||||
Material,
|
||||
Animation,
|
||||
Light,
|
||||
Camera,
|
||||
Count,
|
||||
};
|
||||
/// Get or Create a unique ID string for the given scene object index
|
||||
std::string GetObjectUniqueId(AiObjectType type, size_t pIndex);
|
||||
/// Get or Create a name string for the given scene object index
|
||||
std::string GetObjectName(AiObjectType type, size_t pIndex);
|
||||
|
||||
typedef std::map<size_t, std::string> IndexIdMap;
|
||||
typedef std::pair<std::string, std::string> NameIdPair;
|
||||
NameIdPair AddObjectIndexToMaps(AiObjectType type, size_t pIndex);
|
||||
|
||||
// Helpers
|
||||
inline IndexIdMap &GetObjectIdMap(AiObjectType type) { return mObjectIdMap[static_cast<size_t>(type)]; }
|
||||
inline IndexIdMap &GetObjectNameMap(AiObjectType type) { return mObjectNameMap[static_cast<size_t>(type)]; }
|
||||
|
||||
private:
|
||||
std::unordered_set<std::string> mUniqueIds; // Cache of used unique ids
|
||||
std::map<const void *, std::string> mNodeIdMap; // Cache of encoded node and bone ids
|
||||
std::array<IndexIdMap, static_cast<size_t>(AiObjectType::Count)> mObjectIdMap; // Cache of encoded unique IDs
|
||||
std::array<IndexIdMap, static_cast<size_t>(AiObjectType::Count)> mObjectNameMap; // Cache of encoded names
|
||||
|
||||
public:
|
||||
/// Stringstream to write all output into
|
||||
std::stringstream mOutput;
|
||||
|
||||
/// The IOSystem for output
|
||||
IOSystem* mIOSystem;
|
||||
IOSystem *mIOSystem;
|
||||
|
||||
/// Path of the directory where the scene will be exported
|
||||
const std::string mPath;
|
||||
|
@ -160,37 +196,38 @@ public:
|
|||
const std::string mFile;
|
||||
|
||||
/// The scene to be written
|
||||
const aiScene* mScene;
|
||||
bool mSceneOwned;
|
||||
const aiScene *const mScene;
|
||||
std::string mSceneId;
|
||||
bool mAdd_root_node = false;
|
||||
|
||||
/// current line start string, contains the current indentation for simple stream insertion
|
||||
std::string startstr;
|
||||
/// current line end string for simple stream insertion
|
||||
std::string endstr;
|
||||
const std::string endstr;
|
||||
|
||||
// pair of color and texture - texture precedences color
|
||||
struct Surface
|
||||
{
|
||||
struct Surface {
|
||||
bool exist;
|
||||
aiColor4D color;
|
||||
std::string texture;
|
||||
size_t channel;
|
||||
Surface() { exist = false; channel = 0; }
|
||||
Surface() {
|
||||
exist = false;
|
||||
channel = 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct Property
|
||||
{
|
||||
struct Property {
|
||||
bool exist;
|
||||
ai_real value;
|
||||
Property()
|
||||
: exist(false)
|
||||
, value(0.0)
|
||||
{}
|
||||
Property() :
|
||||
exist(false),
|
||||
value(0.0) {}
|
||||
};
|
||||
|
||||
// summarize a material in an convenient way.
|
||||
struct Material
|
||||
{
|
||||
struct Material {
|
||||
std::string id;
|
||||
std::string name;
|
||||
std::string shading_model;
|
||||
Surface ambient, diffuse, specular, emissive, reflective, transparent, normal;
|
||||
|
@ -199,24 +236,22 @@ public:
|
|||
Material() {}
|
||||
};
|
||||
|
||||
std::vector<Material> materials;
|
||||
|
||||
std::map<unsigned int, std::string> textures;
|
||||
|
||||
public:
|
||||
/// Dammit C++ - y u no compile two-pass? No I have to add all methods below the struct definitions
|
||||
/// Reads a single surface entry from the given material keys
|
||||
void ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat, aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex);
|
||||
bool ReadMaterialSurface(Surface &poSurface, const aiMaterial &pSrcMat, aiTextureType pTexture, const char *pKey, size_t pType, size_t pIndex);
|
||||
/// Writes an image entry for the given surface
|
||||
void WriteImageEntry( const Surface& pSurface, const std::string& pNameAdd);
|
||||
void WriteImageEntry(const Surface &pSurface, const std::string &imageId);
|
||||
/// Writes the two parameters necessary for referencing a texture in an effect entry
|
||||
void WriteTextureParamEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pMatName);
|
||||
void WriteTextureParamEntry(const Surface &pSurface, const std::string &pTypeName, const std::string &materialId);
|
||||
/// Writes a color-or-texture entry into an effect definition
|
||||
void WriteTextureColorEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pImageName);
|
||||
void WriteTextureColorEntry(const Surface &pSurface, const std::string &pTypeName, const std::string &imageId);
|
||||
/// Writes a scalar property
|
||||
void WriteFloatEntry( const Property& pProperty, const std::string& pTypeName);
|
||||
void WriteFloatEntry(const Property &pProperty, const std::string &pTypeName);
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace Assimp
|
||||
|
||||
#endif // !! AI_COLLADAEXPORTER_H_INC
|
||||
|
|
|
@ -43,8 +43,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "ColladaHelper.h"
|
||||
|
||||
#include <assimp/commonMetaData.h>
|
||||
#include <assimp/ParsingUtils.h>
|
||||
#include <assimp/commonMetaData.h>
|
||||
|
||||
namespace Assimp {
|
||||
namespace Collada {
|
||||
|
@ -63,39 +63,32 @@ const MetaKeyPairVector &GetColladaAssimpMetaKeys() {
|
|||
|
||||
const MetaKeyPairVector MakeColladaAssimpMetaKeysCamelCase() {
|
||||
MetaKeyPairVector result = MakeColladaAssimpMetaKeys();
|
||||
for (auto &val : result)
|
||||
{
|
||||
for (auto &val : result) {
|
||||
ToCamelCase(val.first);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
const MetaKeyPairVector &GetColladaAssimpMetaKeysCamelCase()
|
||||
{
|
||||
const MetaKeyPairVector &GetColladaAssimpMetaKeysCamelCase() {
|
||||
static const MetaKeyPairVector result = MakeColladaAssimpMetaKeysCamelCase();
|
||||
return result;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Convert underscore_separated to CamelCase: "authoring_tool" becomes "AuthoringTool"
|
||||
void ToCamelCase(std::string &text)
|
||||
{
|
||||
void ToCamelCase(std::string &text) {
|
||||
if (text.empty())
|
||||
return;
|
||||
// Capitalise first character
|
||||
auto it = text.begin();
|
||||
(*it) = ToUpper(*it);
|
||||
++it;
|
||||
for (/*started above*/ ; it != text.end(); /*iterated below*/)
|
||||
{
|
||||
if ((*it) == '_')
|
||||
{
|
||||
for (/*started above*/; it != text.end(); /*iterated below*/) {
|
||||
if ((*it) == '_') {
|
||||
it = text.erase(it);
|
||||
if (it != text.end())
|
||||
(*it) = ToUpper(*it);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Make lower case
|
||||
(*it) = ToLower(*it);
|
||||
++it;
|
||||
|
|
|
@ -45,13 +45,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef AI_COLLADAHELPER_H_INC
|
||||
#define AI_COLLADAHELPER_H_INC
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <stdint.h>
|
||||
#include <assimp/light.h>
|
||||
#include <assimp/mesh.h>
|
||||
#include <assimp/material.h>
|
||||
#include <assimp/mesh.h>
|
||||
#include <stdint.h>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
struct aiMaterial;
|
||||
|
||||
|
@ -59,17 +59,14 @@ namespace Assimp {
|
|||
namespace Collada {
|
||||
|
||||
/** Collada file versions which evolved during the years ... */
|
||||
enum FormatVersion
|
||||
{
|
||||
enum FormatVersion {
|
||||
FV_1_5_n,
|
||||
FV_1_4_n,
|
||||
FV_1_3_n
|
||||
};
|
||||
|
||||
|
||||
/** Transformation types that can be applied to a node */
|
||||
enum TransformType
|
||||
{
|
||||
enum TransformType {
|
||||
TF_LOOKAT,
|
||||
TF_ROTATE,
|
||||
TF_TRANSLATE,
|
||||
|
@ -79,8 +76,7 @@ enum TransformType
|
|||
};
|
||||
|
||||
/** Different types of input data to a vertex or face */
|
||||
enum InputType
|
||||
{
|
||||
enum InputType {
|
||||
IT_Invalid,
|
||||
IT_Vertex, // special type for per-index data referring to the <vertices> element carrying the per-vertex data.
|
||||
IT_Position,
|
||||
|
@ -92,15 +88,13 @@ enum InputType
|
|||
};
|
||||
|
||||
/** Supported controller types */
|
||||
enum ControllerType
|
||||
{
|
||||
enum ControllerType {
|
||||
Skin,
|
||||
Morph
|
||||
};
|
||||
|
||||
/** Supported morph methods */
|
||||
enum MorphMethod
|
||||
{
|
||||
enum MorphMethod {
|
||||
Normalized,
|
||||
Relative
|
||||
};
|
||||
|
@ -118,24 +112,21 @@ const MetaKeyPairVector &GetColladaAssimpMetaKeysCamelCase();
|
|||
void ToCamelCase(std::string &text);
|
||||
|
||||
/** Contains all data for one of the different transformation types */
|
||||
struct Transform
|
||||
{
|
||||
struct Transform {
|
||||
std::string mID; ///< SID of the transform step, by which anim channels address their target node
|
||||
TransformType mType;
|
||||
ai_real f[16]; ///< Interpretation of data depends on the type of the transformation
|
||||
};
|
||||
|
||||
/** A collada camera. */
|
||||
struct Camera
|
||||
{
|
||||
Camera()
|
||||
: mOrtho (false)
|
||||
, mHorFov (10e10f)
|
||||
, mVerFov (10e10f)
|
||||
, mAspect (10e10f)
|
||||
, mZNear (0.1f)
|
||||
, mZFar (1000.f)
|
||||
{}
|
||||
struct Camera {
|
||||
Camera() :
|
||||
mOrtho(false),
|
||||
mHorFov(10e10f),
|
||||
mVerFov(10e10f),
|
||||
mAspect(10e10f),
|
||||
mZNear(0.1f),
|
||||
mZFar(1000.f) {}
|
||||
|
||||
// Name of camera
|
||||
std::string mName;
|
||||
|
@ -159,19 +150,17 @@ struct Camera
|
|||
#define ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET 1e9f
|
||||
|
||||
/** A collada light source. */
|
||||
struct Light
|
||||
{
|
||||
Light()
|
||||
: mType (aiLightSource_UNDEFINED)
|
||||
, mAttConstant (1.f)
|
||||
, mAttLinear (0.f)
|
||||
, mAttQuadratic (0.f)
|
||||
, mFalloffAngle (180.f)
|
||||
, mFalloffExponent (0.f)
|
||||
, mPenumbraAngle (ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET)
|
||||
, mOuterAngle (ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET)
|
||||
, mIntensity (1.f)
|
||||
{}
|
||||
struct Light {
|
||||
Light() :
|
||||
mType(aiLightSource_UNDEFINED),
|
||||
mAttConstant(1.f),
|
||||
mAttLinear(0.f),
|
||||
mAttQuadratic(0.f),
|
||||
mFalloffAngle(180.f),
|
||||
mFalloffExponent(0.f),
|
||||
mPenumbraAngle(ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET),
|
||||
mOuterAngle(ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET),
|
||||
mIntensity(1.f) {}
|
||||
|
||||
//! Type of the light source aiLightSourceType + ambient
|
||||
unsigned int mType;
|
||||
|
@ -180,7 +169,7 @@ struct Light
|
|||
aiColor3D mColor;
|
||||
|
||||
//! Light attenuation
|
||||
ai_real mAttConstant,mAttLinear,mAttQuadratic;
|
||||
ai_real mAttConstant, mAttLinear, mAttQuadratic;
|
||||
|
||||
//! Spot light falloff
|
||||
ai_real mFalloffAngle;
|
||||
|
@ -198,12 +187,10 @@ struct Light
|
|||
};
|
||||
|
||||
/** Short vertex index description */
|
||||
struct InputSemanticMapEntry
|
||||
{
|
||||
InputSemanticMapEntry()
|
||||
: mSet(0)
|
||||
, mType(IT_Invalid)
|
||||
{}
|
||||
struct InputSemanticMapEntry {
|
||||
InputSemanticMapEntry() :
|
||||
mSet(0),
|
||||
mType(IT_Invalid) {}
|
||||
|
||||
//! Index of set, optional
|
||||
unsigned int mSet;
|
||||
|
@ -213,8 +200,7 @@ struct InputSemanticMapEntry
|
|||
};
|
||||
|
||||
/** Table to map from effect to vertex input semantics */
|
||||
struct SemanticMappingTable
|
||||
{
|
||||
struct SemanticMappingTable {
|
||||
//! Name of material
|
||||
std::string mMatName;
|
||||
|
||||
|
@ -222,7 +208,7 @@ struct SemanticMappingTable
|
|||
std::map<std::string, InputSemanticMapEntry> mMap;
|
||||
|
||||
//! For std::find
|
||||
bool operator == (const std::string& s) const {
|
||||
bool operator==(const std::string &s) const {
|
||||
return s == mMatName;
|
||||
}
|
||||
};
|
||||
|
@ -230,8 +216,7 @@ struct SemanticMappingTable
|
|||
/** A reference to a mesh inside a node, including materials assigned to the various subgroups.
|
||||
* The ID refers to either a mesh or a controller which specifies the mesh
|
||||
*/
|
||||
struct MeshInstance
|
||||
{
|
||||
struct MeshInstance {
|
||||
///< ID of the mesh or controller to be instanced
|
||||
std::string mMeshOrController;
|
||||
|
||||
|
@ -240,34 +225,30 @@ struct MeshInstance
|
|||
};
|
||||
|
||||
/** A reference to a camera inside a node*/
|
||||
struct CameraInstance
|
||||
{
|
||||
struct CameraInstance {
|
||||
///< ID of the camera
|
||||
std::string mCamera;
|
||||
};
|
||||
|
||||
/** A reference to a light inside a node*/
|
||||
struct LightInstance
|
||||
{
|
||||
struct LightInstance {
|
||||
///< ID of the camera
|
||||
std::string mLight;
|
||||
};
|
||||
|
||||
/** A reference to a node inside a node*/
|
||||
struct NodeInstance
|
||||
{
|
||||
struct NodeInstance {
|
||||
///< ID of the node
|
||||
std::string mNode;
|
||||
};
|
||||
|
||||
/** A node in a scene hierarchy */
|
||||
struct Node
|
||||
{
|
||||
struct Node {
|
||||
std::string mName;
|
||||
std::string mID;
|
||||
std::string mSID;
|
||||
Node* mParent;
|
||||
std::vector<Node*> mChildren;
|
||||
Node *mParent;
|
||||
std::vector<Node *> mChildren;
|
||||
|
||||
/** Operations in order to calculate the resulting transformation to parent. */
|
||||
std::vector<Transform> mTransforms;
|
||||
|
@ -288,29 +269,27 @@ struct Node
|
|||
std::string mPrimaryCamera;
|
||||
|
||||
//! Constructor. Begin with a zero parent
|
||||
Node()
|
||||
: mParent( nullptr ){
|
||||
Node() :
|
||||
mParent(nullptr) {
|
||||
// empty
|
||||
}
|
||||
|
||||
//! Destructor: delete all children subsequently
|
||||
~Node() {
|
||||
for( std::vector<Node*>::iterator it = mChildren.begin(); it != mChildren.end(); ++it)
|
||||
for (std::vector<Node *>::iterator it = mChildren.begin(); it != mChildren.end(); ++it)
|
||||
delete *it;
|
||||
}
|
||||
};
|
||||
|
||||
/** Data source array: either floats or strings */
|
||||
struct Data
|
||||
{
|
||||
struct Data {
|
||||
bool mIsStringArray;
|
||||
std::vector<ai_real> mValues;
|
||||
std::vector<std::string> mStrings;
|
||||
};
|
||||
|
||||
/** Accessor to a data array */
|
||||
struct Accessor
|
||||
{
|
||||
struct Accessor {
|
||||
size_t mCount; // in number of objects
|
||||
size_t mSize; // size of an object, in elements (floats or strings, mostly 1)
|
||||
size_t mOffset; // in number of values
|
||||
|
@ -319,49 +298,54 @@ struct Accessor
|
|||
size_t mSubOffset[4]; // Suboffset inside the object for the common 4 elements. For a vector, that's XYZ, for a color RGBA and so on.
|
||||
// For example, SubOffset[0] denotes which of the values inside the object is the vector X component.
|
||||
std::string mSource; // URL of the source array
|
||||
mutable const Data* mData; // Pointer to the source array, if resolved. NULL else
|
||||
mutable const Data *mData; // Pointer to the source array, if resolved. nullptr else
|
||||
|
||||
Accessor()
|
||||
{
|
||||
mCount = 0; mSize = 0; mOffset = 0; mStride = 0; mData = NULL;
|
||||
Accessor() {
|
||||
mCount = 0;
|
||||
mSize = 0;
|
||||
mOffset = 0;
|
||||
mStride = 0;
|
||||
mData = nullptr;
|
||||
mSubOffset[0] = mSubOffset[1] = mSubOffset[2] = mSubOffset[3] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/** A single face in a mesh */
|
||||
struct Face
|
||||
{
|
||||
struct Face {
|
||||
std::vector<size_t> mIndices;
|
||||
};
|
||||
|
||||
/** An input channel for mesh data, referring to a single accessor */
|
||||
struct InputChannel
|
||||
{
|
||||
struct InputChannel {
|
||||
InputType mType; // Type of the data
|
||||
size_t mIndex; // Optional index, if multiple sets of the same data type are given
|
||||
size_t mOffset; // Index offset in the indices array of per-face indices. Don't ask, can't explain that any better.
|
||||
std::string mAccessor; // ID of the accessor where to read the actual values from.
|
||||
mutable const Accessor* mResolved; // Pointer to the accessor, if resolved. NULL else
|
||||
mutable const Accessor *mResolved; // Pointer to the accessor, if resolved. nullptr else
|
||||
|
||||
InputChannel() { mType = IT_Invalid; mIndex = 0; mOffset = 0; mResolved = NULL; }
|
||||
InputChannel() {
|
||||
mType = IT_Invalid;
|
||||
mIndex = 0;
|
||||
mOffset = 0;
|
||||
mResolved = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
/** Subset of a mesh with a certain material */
|
||||
struct SubMesh
|
||||
{
|
||||
struct SubMesh {
|
||||
std::string mMaterial; ///< subgroup identifier
|
||||
size_t mNumFaces; ///< number of faces in this submesh
|
||||
};
|
||||
|
||||
/** Contains data for a single mesh */
|
||||
struct Mesh
|
||||
{
|
||||
Mesh()
|
||||
{
|
||||
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
|
||||
struct Mesh {
|
||||
Mesh(const std::string &id) :
|
||||
mId(id) {
|
||||
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i)
|
||||
mNumUVComponents[i] = 2;
|
||||
}
|
||||
|
||||
const std::string mId;
|
||||
std::string mName;
|
||||
|
||||
// just to check if there's some sophisticated addressing involved...
|
||||
|
@ -394,8 +378,7 @@ struct Mesh
|
|||
};
|
||||
|
||||
/** Which type of primitives the ReadPrimitives() function is going to read */
|
||||
enum PrimitiveType
|
||||
{
|
||||
enum PrimitiveType {
|
||||
Prim_Invalid,
|
||||
Prim_Lines,
|
||||
Prim_LineStrip,
|
||||
|
@ -407,8 +390,7 @@ enum PrimitiveType
|
|||
};
|
||||
|
||||
/** A skeleton controller to deform a mesh with the use of joints */
|
||||
struct Controller
|
||||
{
|
||||
struct Controller {
|
||||
// controller type
|
||||
ControllerType mType;
|
||||
|
||||
|
@ -436,36 +418,32 @@ struct Controller
|
|||
std::vector<size_t> mWeightCounts;
|
||||
|
||||
// JointIndex-WeightIndex pairs for all vertices
|
||||
std::vector< std::pair<size_t, size_t> > mWeights;
|
||||
std::vector<std::pair<size_t, size_t>> mWeights;
|
||||
|
||||
std::string mMorphTarget;
|
||||
std::string mMorphWeight;
|
||||
};
|
||||
|
||||
/** A collada material. Pretty much the only member is a reference to an effect. */
|
||||
struct Material
|
||||
{
|
||||
struct Material {
|
||||
std::string mName;
|
||||
std::string mEffect;
|
||||
};
|
||||
|
||||
/** Type of the effect param */
|
||||
enum ParamType
|
||||
{
|
||||
enum ParamType {
|
||||
Param_Sampler,
|
||||
Param_Surface
|
||||
};
|
||||
|
||||
/** A param for an effect. Might be of several types, but they all just refer to each other, so I summarize them */
|
||||
struct EffectParam
|
||||
{
|
||||
struct EffectParam {
|
||||
ParamType mType;
|
||||
std::string mReference; // to which other thing the param is referring to.
|
||||
};
|
||||
|
||||
/** Shading type supported by the standard effect spec of Collada */
|
||||
enum ShadeType
|
||||
{
|
||||
enum ShadeType {
|
||||
Shade_Invalid,
|
||||
Shade_Constant,
|
||||
Shade_Lambert,
|
||||
|
@ -474,18 +452,16 @@ enum ShadeType
|
|||
};
|
||||
|
||||
/** Represents a texture sampler in collada */
|
||||
struct Sampler
|
||||
{
|
||||
Sampler()
|
||||
: mWrapU (true)
|
||||
, mWrapV (true)
|
||||
, mMirrorU ()
|
||||
, mMirrorV ()
|
||||
, mOp (aiTextureOp_Multiply)
|
||||
, mUVId (UINT_MAX)
|
||||
, mWeighting (1.f)
|
||||
, mMixWithPrevious (1.f)
|
||||
{}
|
||||
struct Sampler {
|
||||
Sampler() :
|
||||
mWrapU(true),
|
||||
mWrapV(true),
|
||||
mMirrorU(),
|
||||
mMirrorV(),
|
||||
mOp(aiTextureOp_Multiply),
|
||||
mUVId(UINT_MAX),
|
||||
mWeighting(1.f),
|
||||
mMixWithPrevious(1.f) {}
|
||||
|
||||
/** Name of image reference
|
||||
*/
|
||||
|
@ -537,8 +513,7 @@ struct Sampler
|
|||
|
||||
/** A collada effect. Can contain about anything according to the Collada spec,
|
||||
but we limit our version to a reasonable subset. */
|
||||
struct Effect
|
||||
{
|
||||
struct Effect {
|
||||
// Shading mode
|
||||
ShadeType mShadeType;
|
||||
|
||||
|
@ -566,30 +541,28 @@ struct Effect
|
|||
// Double-sided?
|
||||
bool mDoubleSided, mWireframe, mFaceted;
|
||||
|
||||
Effect()
|
||||
: mShadeType (Shade_Phong)
|
||||
, mEmissive ( 0, 0, 0, 1)
|
||||
, mAmbient ( 0.1f, 0.1f, 0.1f, 1)
|
||||
, mDiffuse ( 0.6f, 0.6f, 0.6f, 1)
|
||||
, mSpecular ( 0.4f, 0.4f, 0.4f, 1)
|
||||
, mTransparent ( 0, 0, 0, 1)
|
||||
, mShininess (10.0f)
|
||||
, mRefractIndex (1.f)
|
||||
, mReflectivity (0.f)
|
||||
, mTransparency (1.f)
|
||||
, mHasTransparency (false)
|
||||
, mRGBTransparency(false)
|
||||
, mInvertTransparency(false)
|
||||
, mDoubleSided (false)
|
||||
, mWireframe (false)
|
||||
, mFaceted (false)
|
||||
{
|
||||
Effect() :
|
||||
mShadeType(Shade_Phong),
|
||||
mEmissive(0, 0, 0, 1),
|
||||
mAmbient(0.1f, 0.1f, 0.1f, 1),
|
||||
mDiffuse(0.6f, 0.6f, 0.6f, 1),
|
||||
mSpecular(0.4f, 0.4f, 0.4f, 1),
|
||||
mTransparent(0, 0, 0, 1),
|
||||
mShininess(10.0f),
|
||||
mRefractIndex(1.f),
|
||||
mReflectivity(0.f),
|
||||
mTransparency(1.f),
|
||||
mHasTransparency(false),
|
||||
mRGBTransparency(false),
|
||||
mInvertTransparency(false),
|
||||
mDoubleSided(false),
|
||||
mWireframe(false),
|
||||
mFaceted(false) {
|
||||
}
|
||||
};
|
||||
|
||||
/** An image, meaning texture */
|
||||
struct Image
|
||||
{
|
||||
struct Image {
|
||||
std::string mFileName;
|
||||
|
||||
/** Embedded image data */
|
||||
|
@ -600,8 +573,7 @@ struct Image
|
|||
};
|
||||
|
||||
/** An animation channel. */
|
||||
struct AnimationChannel
|
||||
{
|
||||
struct AnimationChannel {
|
||||
/** URL of the data to animate. Could be about anything, but we support only the
|
||||
* "NodeID/TransformID.SubElement" notation
|
||||
*/
|
||||
|
@ -620,8 +592,7 @@ struct AnimationChannel
|
|||
};
|
||||
|
||||
/** An animation. Container for 0-x animation channels or 0-x animations */
|
||||
struct Animation
|
||||
{
|
||||
struct Animation {
|
||||
/** Anim name */
|
||||
std::string mName;
|
||||
|
||||
|
@ -629,22 +600,19 @@ struct Animation
|
|||
std::vector<AnimationChannel> mChannels;
|
||||
|
||||
/** the sub-animations, if any */
|
||||
std::vector<Animation*> mSubAnims;
|
||||
std::vector<Animation *> mSubAnims;
|
||||
|
||||
/** Destructor */
|
||||
~Animation()
|
||||
{
|
||||
for( std::vector<Animation*>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it)
|
||||
~Animation() {
|
||||
for (std::vector<Animation *>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it)
|
||||
delete *it;
|
||||
}
|
||||
|
||||
/** Collect all channels in the animation hierarchy into a single channel list. */
|
||||
void CollectChannelsRecursively(std::vector<AnimationChannel> &channels)
|
||||
{
|
||||
void CollectChannelsRecursively(std::vector<AnimationChannel> &channels) {
|
||||
channels.insert(channels.end(), mChannels.begin(), mChannels.end());
|
||||
|
||||
for (std::vector<Animation*>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it)
|
||||
{
|
||||
for (std::vector<Animation *>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it) {
|
||||
Animation *pAnim = (*it);
|
||||
|
||||
pAnim->CollectChannelsRecursively(channels);
|
||||
|
@ -652,18 +620,15 @@ struct Animation
|
|||
}
|
||||
|
||||
/** Combine all single-channel animations' channel into the same (parent) animation channel list. */
|
||||
void CombineSingleChannelAnimations()
|
||||
{
|
||||
void CombineSingleChannelAnimations() {
|
||||
CombineSingleChannelAnimationsRecursively(this);
|
||||
}
|
||||
|
||||
void CombineSingleChannelAnimationsRecursively(Animation *pParent)
|
||||
{
|
||||
void CombineSingleChannelAnimationsRecursively(Animation *pParent) {
|
||||
std::set<std::string> childrenTargets;
|
||||
bool childrenAnimationsHaveDifferentChannels = true;
|
||||
|
||||
for (std::vector<Animation*>::iterator it = pParent->mSubAnims.begin(); it != pParent->mSubAnims.end();)
|
||||
{
|
||||
for (std::vector<Animation *>::iterator it = pParent->mSubAnims.begin(); it != pParent->mSubAnims.end();) {
|
||||
Animation *anim = *it;
|
||||
CombineSingleChannelAnimationsRecursively(anim);
|
||||
|
||||
|
@ -678,10 +643,8 @@ struct Animation
|
|||
}
|
||||
|
||||
// We only want to combine animations if they have different channels
|
||||
if (childrenAnimationsHaveDifferentChannels)
|
||||
{
|
||||
for (std::vector<Animation*>::iterator it = pParent->mSubAnims.begin(); it != pParent->mSubAnims.end();)
|
||||
{
|
||||
if (childrenAnimationsHaveDifferentChannels) {
|
||||
for (std::vector<Animation *>::iterator it = pParent->mSubAnims.begin(); it != pParent->mSubAnims.end();) {
|
||||
Animation *anim = *it;
|
||||
|
||||
pParent->mChannels.push_back(anim->mChannels[0]);
|
||||
|
@ -696,29 +659,27 @@ struct Animation
|
|||
};
|
||||
|
||||
/** Description of a collada animation channel which has been determined to affect the current node */
|
||||
struct ChannelEntry
|
||||
{
|
||||
const Collada::AnimationChannel* mChannel; ///> the source channel
|
||||
struct ChannelEntry {
|
||||
const Collada::AnimationChannel *mChannel; ///> the source channel
|
||||
std::string mTargetId;
|
||||
std::string mTransformId; // the ID of the transformation step of the node which is influenced
|
||||
size_t mTransformIndex; // Index into the node's transform chain to apply the channel to
|
||||
size_t mSubElement; // starting index inside the transform data
|
||||
|
||||
// resolved data references
|
||||
const Collada::Accessor* mTimeAccessor; ///> Collada accessor to the time values
|
||||
const Collada::Data* mTimeData; ///> Source data array for the time values
|
||||
const Collada::Accessor* mValueAccessor; ///> Collada accessor to the key value values
|
||||
const Collada::Data* mValueData; ///> Source datat array for the key value values
|
||||
const Collada::Accessor *mTimeAccessor; ///> Collada accessor to the time values
|
||||
const Collada::Data *mTimeData; ///> Source data array for the time values
|
||||
const Collada::Accessor *mValueAccessor; ///> Collada accessor to the key value values
|
||||
const Collada::Data *mValueData; ///> Source datat array for the key value values
|
||||
|
||||
ChannelEntry()
|
||||
: mChannel()
|
||||
, mTransformIndex()
|
||||
, mSubElement()
|
||||
, mTimeAccessor()
|
||||
, mTimeData()
|
||||
, mValueAccessor()
|
||||
, mValueData()
|
||||
{}
|
||||
ChannelEntry() :
|
||||
mChannel(),
|
||||
mTransformIndex(),
|
||||
mSubElement(),
|
||||
mTimeAccessor(),
|
||||
mTimeData(),
|
||||
mValueAccessor(),
|
||||
mValueData() {}
|
||||
};
|
||||
|
||||
} // end of namespace Collada
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -47,34 +47,32 @@
|
|||
#ifndef AI_COLLADAPARSER_H_INC
|
||||
#define AI_COLLADAPARSER_H_INC
|
||||
|
||||
#include <assimp/irrXMLWrapper.h>
|
||||
#include "ColladaHelper.h"
|
||||
#include <assimp/ai_assert.h>
|
||||
#include <assimp/TinyFormatter.h>
|
||||
#include <assimp/ai_assert.h>
|
||||
#include <assimp/irrXMLWrapper.h>
|
||||
|
||||
namespace Assimp
|
||||
{
|
||||
class ZipArchiveIOSystem;
|
||||
namespace Assimp {
|
||||
class ZipArchiveIOSystem;
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
/** Parser helper class for the Collada loader.
|
||||
// ------------------------------------------------------------------------------------------
|
||||
/** Parser helper class for the Collada loader.
|
||||
*
|
||||
* Does all the XML reading and builds internal data structures from it,
|
||||
* but leaves the resolving of all the references to the loader.
|
||||
*/
|
||||
class ColladaParser
|
||||
{
|
||||
class ColladaParser {
|
||||
friend class ColladaLoader;
|
||||
|
||||
/** Converts a path read from a collada file to the usual representation */
|
||||
static void UriDecodePath(aiString& ss);
|
||||
static void UriDecodePath(aiString &ss);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
/** Map for generic metadata as aiString */
|
||||
typedef std::map<std::string, aiString> StringMetaData;
|
||||
|
||||
/** Constructor from XML file */
|
||||
ColladaParser(IOSystem* pIOHandler, const std::string& pFile);
|
||||
ColladaParser(IOSystem *pIOHandler, const std::string &pFile);
|
||||
|
||||
/** Destructor */
|
||||
~ColladaParser();
|
||||
|
@ -110,76 +108,76 @@ namespace Assimp
|
|||
void PostProcessRootAnimations();
|
||||
|
||||
/** Reads an animation into the given parent structure */
|
||||
void ReadAnimation( Collada::Animation* pParent);
|
||||
void ReadAnimation(Collada::Animation *pParent);
|
||||
|
||||
/** Reads an animation sampler into the given anim channel */
|
||||
void ReadAnimationSampler( Collada::AnimationChannel& pChannel);
|
||||
void ReadAnimationSampler(Collada::AnimationChannel &pChannel);
|
||||
|
||||
/** Reads the skeleton controller library */
|
||||
void ReadControllerLibrary();
|
||||
|
||||
/** Reads a controller into the given mesh structure */
|
||||
void ReadController( Collada::Controller& pController);
|
||||
void ReadController(Collada::Controller &pController);
|
||||
|
||||
/** Reads the joint definitions for the given controller */
|
||||
void ReadControllerJoints( Collada::Controller& pController);
|
||||
void ReadControllerJoints(Collada::Controller &pController);
|
||||
|
||||
/** Reads the joint weights for the given controller */
|
||||
void ReadControllerWeights( Collada::Controller& pController);
|
||||
void ReadControllerWeights(Collada::Controller &pController);
|
||||
|
||||
/** Reads the image library contents */
|
||||
void ReadImageLibrary();
|
||||
|
||||
/** Reads an image entry into the given image */
|
||||
void ReadImage( Collada::Image& pImage);
|
||||
void ReadImage(Collada::Image &pImage);
|
||||
|
||||
/** Reads the material library */
|
||||
void ReadMaterialLibrary();
|
||||
|
||||
/** Reads a material entry into the given material */
|
||||
void ReadMaterial( Collada::Material& pMaterial);
|
||||
void ReadMaterial(Collada::Material &pMaterial);
|
||||
|
||||
/** Reads the camera library */
|
||||
void ReadCameraLibrary();
|
||||
|
||||
/** Reads a camera entry into the given camera */
|
||||
void ReadCamera( Collada::Camera& pCamera);
|
||||
void ReadCamera(Collada::Camera &pCamera);
|
||||
|
||||
/** Reads the light library */
|
||||
void ReadLightLibrary();
|
||||
|
||||
/** Reads a light entry into the given light */
|
||||
void ReadLight( Collada::Light& pLight);
|
||||
void ReadLight(Collada::Light &pLight);
|
||||
|
||||
/** Reads the effect library */
|
||||
void ReadEffectLibrary();
|
||||
|
||||
/** Reads an effect entry into the given effect*/
|
||||
void ReadEffect( Collada::Effect& pEffect);
|
||||
void ReadEffect(Collada::Effect &pEffect);
|
||||
|
||||
/** Reads an COMMON effect profile */
|
||||
void ReadEffectProfileCommon( Collada::Effect& pEffect);
|
||||
void ReadEffectProfileCommon(Collada::Effect &pEffect);
|
||||
|
||||
/** Read sampler properties */
|
||||
void ReadSamplerProperties( Collada::Sampler& pSampler);
|
||||
void ReadSamplerProperties(Collada::Sampler &pSampler);
|
||||
|
||||
/** Reads an effect entry containing a color or a texture defining that color */
|
||||
void ReadEffectColor( aiColor4D& pColor, Collada::Sampler& pSampler);
|
||||
void ReadEffectColor(aiColor4D &pColor, Collada::Sampler &pSampler);
|
||||
|
||||
/** Reads an effect entry containing a float */
|
||||
void ReadEffectFloat( ai_real& pFloat);
|
||||
void ReadEffectFloat(ai_real &pFloat);
|
||||
|
||||
/** Reads an effect parameter specification of any kind */
|
||||
void ReadEffectParam( Collada::EffectParam& pParam);
|
||||
void ReadEffectParam(Collada::EffectParam &pParam);
|
||||
|
||||
/** Reads the geometry library contents */
|
||||
void ReadGeometryLibrary();
|
||||
|
||||
/** Reads a geometry from the geometry library. */
|
||||
void ReadGeometry( Collada::Mesh* pMesh);
|
||||
void ReadGeometry(Collada::Mesh &pMesh);
|
||||
|
||||
/** Reads a mesh from the geometry library */
|
||||
void ReadMesh( Collada::Mesh* pMesh);
|
||||
void ReadMesh(Collada::Mesh &pMesh);
|
||||
|
||||
/** Reads a source element - a combination of raw data and an accessor defining
|
||||
* things that should not be redefinable. Yes, that's another rant.
|
||||
|
@ -194,89 +192,89 @@ namespace Assimp
|
|||
/** Reads an accessor and stores it in the global library under the given ID -
|
||||
* accessors use the ID of the parent <source> element
|
||||
*/
|
||||
void ReadAccessor( const std::string& pID);
|
||||
void ReadAccessor(const std::string &pID);
|
||||
|
||||
/** Reads input declarations of per-vertex mesh data into the given mesh */
|
||||
void ReadVertexData( Collada::Mesh* pMesh);
|
||||
void ReadVertexData(Collada::Mesh &pMesh);
|
||||
|
||||
/** Reads input declarations of per-index mesh data into the given mesh */
|
||||
void ReadIndexData( Collada::Mesh* pMesh);
|
||||
void ReadIndexData(Collada::Mesh &pMesh);
|
||||
|
||||
/** Reads a single input channel element and stores it in the given array, if valid */
|
||||
void ReadInputChannel( std::vector<Collada::InputChannel>& poChannels);
|
||||
void ReadInputChannel(std::vector<Collada::InputChannel> &poChannels);
|
||||
|
||||
/** Reads a <p> primitive index list and assembles the mesh data into the given mesh */
|
||||
size_t ReadPrimitives( Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels,
|
||||
size_t pNumPrimitives, const std::vector<size_t>& pVCount, Collada::PrimitiveType pPrimType);
|
||||
size_t ReadPrimitives(Collada::Mesh &pMesh, std::vector<Collada::InputChannel> &pPerIndexChannels,
|
||||
size_t pNumPrimitives, const std::vector<size_t> &pVCount, Collada::PrimitiveType pPrimType);
|
||||
|
||||
/** Copies the data for a single primitive into the mesh, based on the InputChannels */
|
||||
void CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset,
|
||||
Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels,
|
||||
size_t currentPrimitive, const std::vector<size_t>& indices);
|
||||
Collada::Mesh &pMesh, std::vector<Collada::InputChannel> &pPerIndexChannels,
|
||||
size_t currentPrimitive, const std::vector<size_t> &indices);
|
||||
|
||||
/** Reads one triangle of a tristrip into the mesh */
|
||||
void ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Collada::Mesh* pMesh,
|
||||
std::vector<Collada::InputChannel>& pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t>& indices);
|
||||
void ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Collada::Mesh &pMesh,
|
||||
std::vector<Collada::InputChannel> &pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t> &indices);
|
||||
|
||||
/** Extracts a single object from an input channel and stores it in the appropriate mesh data array */
|
||||
void ExtractDataObjectFromChannel( const Collada::InputChannel& pInput, size_t pLocalIndex, Collada::Mesh* pMesh);
|
||||
void ExtractDataObjectFromChannel(const Collada::InputChannel &pInput, size_t pLocalIndex, Collada::Mesh &pMesh);
|
||||
|
||||
/** Reads the library of node hierarchies and scene parts */
|
||||
void ReadSceneLibrary();
|
||||
|
||||
/** Reads a scene node's contents including children and stores it in the given node */
|
||||
void ReadSceneNode( Collada::Node* pNode);
|
||||
void ReadSceneNode(Collada::Node *pNode);
|
||||
|
||||
/** Reads a node transformation entry of the given type and adds it to the given node's transformation list. */
|
||||
void ReadNodeTransformation( Collada::Node* pNode, Collada::TransformType pType);
|
||||
void ReadNodeTransformation(Collada::Node *pNode, Collada::TransformType pType);
|
||||
|
||||
/** Reads a mesh reference in a node and adds it to the node's mesh list */
|
||||
void ReadNodeGeometry( Collada::Node* pNode);
|
||||
void ReadNodeGeometry(Collada::Node *pNode);
|
||||
|
||||
/** Reads the collada scene */
|
||||
void ReadScene();
|
||||
|
||||
// Processes bind_vertex_input and bind elements
|
||||
void ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl);
|
||||
void ReadMaterialVertexInputBinding(Collada::SemanticMappingTable &tbl);
|
||||
|
||||
/** Reads embedded textures from a ZAE archive*/
|
||||
void ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
/** Aborts the file reading with an exception */
|
||||
AI_WONT_RETURN void ThrowException( const std::string& pError) const AI_WONT_RETURN_SUFFIX;
|
||||
void ReportWarning(const char* msg,...);
|
||||
AI_WONT_RETURN void ThrowException(const std::string &pError) const AI_WONT_RETURN_SUFFIX;
|
||||
void ReportWarning(const char *msg, ...);
|
||||
|
||||
/** Skips all data until the end node of the current element */
|
||||
void SkipElement();
|
||||
|
||||
/** Skips all data until the end node of the given element */
|
||||
void SkipElement( const char* pElement);
|
||||
void SkipElement(const char *pElement);
|
||||
|
||||
/** Compares the current xml element name to the given string and returns true if equal */
|
||||
bool IsElement( const char* pName) const;
|
||||
bool IsElement(const char *pName) const;
|
||||
|
||||
/** Tests for the opening tag of the given element, throws an exception if not found */
|
||||
void TestOpening( const char* pName);
|
||||
void TestOpening(const char *pName);
|
||||
|
||||
/** Tests for the closing tag of the given element, throws an exception if not found */
|
||||
void TestClosing( const char* pName);
|
||||
void TestClosing(const char *pName);
|
||||
|
||||
/** Checks the present element for the presence of the attribute, returns its index
|
||||
or throws an exception if not found */
|
||||
int GetAttribute( const char* pAttr) const;
|
||||
int GetAttribute(const char *pAttr) const;
|
||||
|
||||
/** Returns the index of the named attribute or -1 if not found. Does not throw,
|
||||
therefore useful for optional attributes */
|
||||
int TestAttribute( const char* pAttr) const;
|
||||
int TestAttribute(const char *pAttr) const;
|
||||
|
||||
/** Reads the text contents of an element, throws an exception if not given.
|
||||
Skips leading whitespace. */
|
||||
const char* GetTextContent();
|
||||
const char *GetTextContent();
|
||||
|
||||
/** Reads the text contents of an element, returns NULL if not given.
|
||||
/** Reads the text contents of an element, returns nullptr if not given.
|
||||
Skips leading whitespace. */
|
||||
const char* TestTextContent();
|
||||
const char *TestTextContent();
|
||||
|
||||
/** Reads a single bool from current text content */
|
||||
bool ReadBoolFromTextContent();
|
||||
|
@ -285,20 +283,21 @@ namespace Assimp
|
|||
ai_real ReadFloatFromTextContent();
|
||||
|
||||
/** Calculates the resulting transformation from all the given transform steps */
|
||||
aiMatrix4x4 CalculateResultTransform( const std::vector<Collada::Transform>& pTransforms) const;
|
||||
aiMatrix4x4 CalculateResultTransform(const std::vector<Collada::Transform> &pTransforms) const;
|
||||
|
||||
/** Determines the input data type for the given semantic string */
|
||||
Collada::InputType GetTypeForSemantic( const std::string& pSemantic);
|
||||
Collada::InputType GetTypeForSemantic(const std::string &pSemantic);
|
||||
|
||||
/** Finds the item in the given library by its reference, throws if not found */
|
||||
template <typename Type> const Type& ResolveLibraryReference( const std::map<std::string, Type>& pLibrary, const std::string& pURL) const;
|
||||
template <typename Type>
|
||||
const Type &ResolveLibraryReference(const std::map<std::string, Type> &pLibrary, const std::string &pURL) const;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
/** Filename, for a verbose error message */
|
||||
std::string mFileName;
|
||||
|
||||
/** XML reader, member for everyday use */
|
||||
irr::io::IrrXMLReader* mReader;
|
||||
irr::io::IrrXMLReader *mReader;
|
||||
|
||||
/** All data arrays found in the file by ID. Might be referred to by actually
|
||||
everyone. Collada, you are a steaming pile of indirection. */
|
||||
|
@ -310,11 +309,11 @@ namespace Assimp
|
|||
AccessorLibrary mAccessorLibrary;
|
||||
|
||||
/** Mesh library: mesh by ID */
|
||||
typedef std::map<std::string, Collada::Mesh*> MeshLibrary;
|
||||
typedef std::map<std::string, Collada::Mesh *> MeshLibrary;
|
||||
MeshLibrary mMeshLibrary;
|
||||
|
||||
/** node library: root node of the hierarchy part by ID */
|
||||
typedef std::map<std::string, Collada::Node*> NodeLibrary;
|
||||
typedef std::map<std::string, Collada::Node *> NodeLibrary;
|
||||
NodeLibrary mNodeLibrary;
|
||||
|
||||
/** Image library: stores texture properties by ID */
|
||||
|
@ -342,16 +341,16 @@ namespace Assimp
|
|||
ControllerLibrary mControllerLibrary;
|
||||
|
||||
/** Animation library: animation references by ID */
|
||||
typedef std::map<std::string, Collada::Animation*> AnimationLibrary;
|
||||
typedef std::map<std::string, Collada::Animation *> AnimationLibrary;
|
||||
AnimationLibrary mAnimationLibrary;
|
||||
|
||||
/** Animation clip library: clip animation references by ID */
|
||||
typedef std::vector<std::pair<std::string, std::vector<std::string> > > AnimationClipLibrary;
|
||||
typedef std::vector<std::pair<std::string, std::vector<std::string>>> AnimationClipLibrary;
|
||||
AnimationClipLibrary mAnimationClipLibrary;
|
||||
|
||||
/** Pointer to the root node. Don't delete, it just points to one of
|
||||
the nodes in the node library. */
|
||||
Collada::Node* mRootNode;
|
||||
Collada::Node *mRootNode;
|
||||
|
||||
/** Root animation container */
|
||||
Collada::Animation mAnims;
|
||||
|
@ -360,33 +359,33 @@ namespace Assimp
|
|||
ai_real mUnitSize;
|
||||
|
||||
/** Which is the up vector */
|
||||
enum { UP_X, UP_Y, UP_Z } mUpDirection;
|
||||
enum { UP_X,
|
||||
UP_Y,
|
||||
UP_Z } mUpDirection;
|
||||
|
||||
/** Asset metadata (global for scene) */
|
||||
StringMetaData mAssetMetaData;
|
||||
|
||||
/** Collada file format version */
|
||||
Collada::FormatVersion mFormat;
|
||||
};
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Check for element match
|
||||
inline bool ColladaParser::IsElement( const char* pName) const
|
||||
{
|
||||
ai_assert( mReader->getNodeType() == irr::io::EXN_ELEMENT);
|
||||
return ::strcmp( mReader->getNodeName(), pName) == 0;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Check for element match
|
||||
inline bool ColladaParser::IsElement(const char *pName) const {
|
||||
ai_assert(mReader->getNodeType() == irr::io::EXN_ELEMENT);
|
||||
return ::strcmp(mReader->getNodeName(), pName) == 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Finds the item in the given library by its reference, throws if not found
|
||||
template <typename Type>
|
||||
const Type& ColladaParser::ResolveLibraryReference( const std::map<std::string, Type>& pLibrary, const std::string& pURL) const
|
||||
{
|
||||
typename std::map<std::string, Type>::const_iterator it = pLibrary.find( pURL);
|
||||
if( it == pLibrary.end())
|
||||
ThrowException( Formatter::format() << "Unable to resolve library reference \"" << pURL << "\"." );
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Finds the item in the given library by its reference, throws if not found
|
||||
template <typename Type>
|
||||
const Type &ColladaParser::ResolveLibraryReference(const std::map<std::string, Type> &pLibrary, const std::string &pURL) const {
|
||||
typename std::map<std::string, Type>::const_iterator it = pLibrary.find(pURL);
|
||||
if (it == pLibrary.end())
|
||||
ThrowException(Formatter::format() << "Unable to resolve library reference \"" << pURL << "\".");
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
|
||||
} // end of namespace Assimp
|
||||
|
||||
|
|
|
@ -135,7 +135,7 @@ public:
|
|||
for(;splitter->length() && splitter->at(0) != '}'; splitter++, cnt++);
|
||||
|
||||
splitter++;
|
||||
ASSIMP_LOG_DEBUG((Formatter::format("DXF: skipped over control group ("),cnt," lines)"));
|
||||
ASSIMP_LOG_VERBOSE_DEBUG((Formatter::format("DXF: skipped over control group ("),cnt," lines)"));
|
||||
}
|
||||
} catch(std::logic_error&) {
|
||||
ai_assert(!splitter);
|
||||
|
|
|
@ -241,7 +241,7 @@ void DXFImporter::ConvertMeshes(aiScene* pScene, DXF::FileData& output) {
|
|||
}
|
||||
}
|
||||
|
||||
ASSIMP_LOG_DEBUG_F("DXF: Unexpanded polycount is ", icount, ", vertex count is ", vcount);
|
||||
ASSIMP_LOG_VERBOSE_DEBUG_F("DXF: Unexpanded polycount is ", icount, ", vertex count is ", vcount);
|
||||
}
|
||||
|
||||
if (! output.blocks.size() ) {
|
||||
|
@ -473,7 +473,7 @@ void DXFImporter::ParseBlocks(DXF::LineReader& reader, DXF::FileData& output) {
|
|||
++reader;
|
||||
}
|
||||
|
||||
ASSIMP_LOG_DEBUG_F("DXF: got ", output.blocks.size()," entries in BLOCKS" );
|
||||
ASSIMP_LOG_VERBOSE_DEBUG_F("DXF: got ", output.blocks.size()," entries in BLOCKS" );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -549,7 +549,7 @@ void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output)
|
|||
++reader;
|
||||
}
|
||||
|
||||
ASSIMP_LOG_DEBUG_F( "DXF: got ", block.lines.size()," polylines and ", block.insertions.size(),
|
||||
ASSIMP_LOG_VERBOSE_DEBUG_F( "DXF: got ", block.lines.size()," polylines and ", block.insertions.size(),
|
||||
" inserted blocks in ENTITIES" );
|
||||
}
|
||||
|
||||
|
|
|
@ -47,10 +47,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
|
||||
|
||||
#include "FBXParser.h"
|
||||
#include "FBXDocument.h"
|
||||
#include "FBXImporter.h"
|
||||
#include "FBXDocumentUtil.h"
|
||||
#include "FBXImporter.h"
|
||||
#include "FBXParser.h"
|
||||
|
||||
namespace Assimp {
|
||||
namespace FBX {
|
||||
|
@ -58,65 +58,60 @@ namespace FBX {
|
|||
using namespace Util;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationCurve::AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& /*doc*/)
|
||||
: Object(id, element, name)
|
||||
{
|
||||
const Scope& sc = GetRequiredScope(element);
|
||||
const Element& KeyTime = GetRequiredElement(sc,"KeyTime");
|
||||
const Element& KeyValueFloat = GetRequiredElement(sc,"KeyValueFloat");
|
||||
AnimationCurve::AnimationCurve(uint64_t id, const Element &element, const std::string &name, const Document & /*doc*/) :
|
||||
Object(id, element, name) {
|
||||
const Scope &sc = GetRequiredScope(element);
|
||||
const Element &KeyTime = GetRequiredElement(sc, "KeyTime");
|
||||
const Element &KeyValueFloat = GetRequiredElement(sc, "KeyValueFloat");
|
||||
|
||||
ParseVectorDataArray(keys, KeyTime);
|
||||
ParseVectorDataArray(values, KeyValueFloat);
|
||||
|
||||
if(keys.size() != values.size()) {
|
||||
DOMError("the number of key times does not match the number of keyframe values",&KeyTime);
|
||||
if (keys.size() != values.size()) {
|
||||
DOMError("the number of key times does not match the number of keyframe values", &KeyTime);
|
||||
}
|
||||
|
||||
// check if the key times are well-ordered
|
||||
if(!std::equal(keys.begin(), keys.end() - 1, keys.begin() + 1, std::less<KeyTimeList::value_type>())) {
|
||||
DOMError("the keyframes are not in ascending order",&KeyTime);
|
||||
if (!std::equal(keys.begin(), keys.end() - 1, keys.begin() + 1, std::less<KeyTimeList::value_type>())) {
|
||||
DOMError("the keyframes are not in ascending order", &KeyTime);
|
||||
}
|
||||
|
||||
const Element* KeyAttrDataFloat = sc["KeyAttrDataFloat"];
|
||||
if(KeyAttrDataFloat) {
|
||||
const Element *KeyAttrDataFloat = sc["KeyAttrDataFloat"];
|
||||
if (KeyAttrDataFloat) {
|
||||
ParseVectorDataArray(attributes, *KeyAttrDataFloat);
|
||||
}
|
||||
|
||||
const Element* KeyAttrFlags = sc["KeyAttrFlags"];
|
||||
if(KeyAttrFlags) {
|
||||
const Element *KeyAttrFlags = sc["KeyAttrFlags"];
|
||||
if (KeyAttrFlags) {
|
||||
ParseVectorDataArray(flags, *KeyAttrFlags);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationCurve::~AnimationCurve()
|
||||
{
|
||||
AnimationCurve::~AnimationCurve() {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name,
|
||||
const Document& doc, const char* const * target_prop_whitelist /*= NULL*/,
|
||||
size_t whitelist_size /*= 0*/)
|
||||
: Object(id, element, name)
|
||||
, target()
|
||||
, doc(doc)
|
||||
{
|
||||
const Scope& sc = GetRequiredScope(element);
|
||||
AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element &element, const std::string &name,
|
||||
const Document &doc, const char *const *target_prop_whitelist /*= nullptr*/,
|
||||
size_t whitelist_size /*= 0*/) :
|
||||
Object(id, element, name), target(), doc(doc) {
|
||||
const Scope &sc = GetRequiredScope(element);
|
||||
|
||||
// find target node
|
||||
const char* whitelist[] = {"Model","NodeAttribute","Deformer"};
|
||||
const std::vector<const Connection*>& conns = doc.GetConnectionsBySourceSequenced(ID(),whitelist,3);
|
||||
const char *whitelist[] = { "Model", "NodeAttribute", "Deformer" };
|
||||
const std::vector<const Connection *> &conns = doc.GetConnectionsBySourceSequenced(ID(), whitelist, 3);
|
||||
|
||||
for(const Connection* con : conns) {
|
||||
for (const Connection *con : conns) {
|
||||
|
||||
// link should go for a property
|
||||
if (!con->PropertyName().length()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(target_prop_whitelist) {
|
||||
const char* const s = con->PropertyName().c_str();
|
||||
if (target_prop_whitelist) {
|
||||
const char *const s = con->PropertyName().c_str();
|
||||
bool ok = false;
|
||||
for (size_t i = 0; i < whitelist_size; ++i) {
|
||||
if (!strcmp(s, target_prop_whitelist[i])) {
|
||||
|
@ -130,16 +125,14 @@ AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, cons
|
|||
}
|
||||
}
|
||||
|
||||
const Object* const ob = con->DestinationObject();
|
||||
if(!ob) {
|
||||
DOMWarning("failed to read destination object for AnimationCurveNode->Model link, ignoring",&element);
|
||||
const Object *const ob = con->DestinationObject();
|
||||
if (!ob) {
|
||||
DOMWarning("failed to read destination object for AnimationCurveNode->Model link, ignoring", &element);
|
||||
continue;
|
||||
}
|
||||
|
||||
// XXX support constraints as DOM class
|
||||
//ai_assert(dynamic_cast<const Model*>(ob) || dynamic_cast<const NodeAttribute*>(ob));
|
||||
target = ob;
|
||||
if(!target) {
|
||||
if (!target) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -147,42 +140,40 @@ AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, cons
|
|||
break;
|
||||
}
|
||||
|
||||
if(!target) {
|
||||
DOMWarning("failed to resolve target Model/NodeAttribute/Constraint for AnimationCurveNode",&element);
|
||||
if (!target) {
|
||||
DOMWarning("failed to resolve target Model/NodeAttribute/Constraint for AnimationCurveNode", &element);
|
||||
}
|
||||
|
||||
props = GetPropertyTable(doc,"AnimationCurveNode.FbxAnimCurveNode",element,sc,false);
|
||||
props = GetPropertyTable(doc, "AnimationCurveNode.FbxAnimCurveNode", element, sc, false);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationCurveNode::~AnimationCurveNode()
|
||||
{
|
||||
AnimationCurveNode::~AnimationCurveNode() {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const AnimationCurveMap& AnimationCurveNode::Curves() const
|
||||
{
|
||||
if ( curves.empty() ) {
|
||||
const AnimationCurveMap &AnimationCurveNode::Curves() const {
|
||||
if (curves.empty()) {
|
||||
// resolve attached animation curves
|
||||
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurve");
|
||||
const std::vector<const Connection *> &conns = doc.GetConnectionsByDestinationSequenced(ID(), "AnimationCurve");
|
||||
|
||||
for(const Connection* con : conns) {
|
||||
for (const Connection *con : conns) {
|
||||
|
||||
// link should go for a property
|
||||
if (!con->PropertyName().length()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const Object* const ob = con->SourceObject();
|
||||
if(!ob) {
|
||||
DOMWarning("failed to read source object for AnimationCurve->AnimationCurveNode link, ignoring",&element);
|
||||
const Object *const ob = con->SourceObject();
|
||||
if (nullptr == ob) {
|
||||
DOMWarning("failed to read source object for AnimationCurve->AnimationCurveNode link, ignoring", &element);
|
||||
continue;
|
||||
}
|
||||
|
||||
const AnimationCurve* const anim = dynamic_cast<const AnimationCurve*>(ob);
|
||||
if(!anim) {
|
||||
DOMWarning("source object for ->AnimationCurveNode link is not an AnimationCurve",&element);
|
||||
const AnimationCurve *const anim = dynamic_cast<const AnimationCurve *>(ob);
|
||||
if (nullptr == anim) {
|
||||
DOMWarning("source object for ->AnimationCurveNode link is not an AnimationCurve", &element);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -194,53 +185,49 @@ const AnimationCurveMap& AnimationCurveNode::Curves() const
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationLayer::AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc)
|
||||
: Object(id, element, name)
|
||||
, doc(doc)
|
||||
{
|
||||
const Scope& sc = GetRequiredScope(element);
|
||||
AnimationLayer::AnimationLayer(uint64_t id, const Element &element, const std::string &name, const Document &doc) :
|
||||
Object(id, element, name), doc(doc) {
|
||||
const Scope &sc = GetRequiredScope(element);
|
||||
|
||||
// note: the props table here bears little importance and is usually absent
|
||||
props = GetPropertyTable(doc,"AnimationLayer.FbxAnimLayer",element,sc, true);
|
||||
props = GetPropertyTable(doc, "AnimationLayer.FbxAnimLayer", element, sc, true);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationLayer::~AnimationLayer()
|
||||
{
|
||||
AnimationLayer::~AnimationLayer() {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationCurveNodeList AnimationLayer::Nodes(const char* const * target_prop_whitelist /*= NULL*/,
|
||||
size_t whitelist_size /*= 0*/) const
|
||||
{
|
||||
AnimationCurveNodeList AnimationLayer::Nodes(const char *const *target_prop_whitelist /*= nullptr*/,
|
||||
size_t whitelist_size /*= 0*/) const {
|
||||
AnimationCurveNodeList nodes;
|
||||
|
||||
// resolve attached animation nodes
|
||||
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurveNode");
|
||||
const std::vector<const Connection *> &conns = doc.GetConnectionsByDestinationSequenced(ID(), "AnimationCurveNode");
|
||||
nodes.reserve(conns.size());
|
||||
|
||||
for(const Connection* con : conns) {
|
||||
for (const Connection *con : conns) {
|
||||
|
||||
// link should not go to a property
|
||||
if (con->PropertyName().length()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const Object* const ob = con->SourceObject();
|
||||
if(!ob) {
|
||||
DOMWarning("failed to read source object for AnimationCurveNode->AnimationLayer link, ignoring",&element);
|
||||
const Object *const ob = con->SourceObject();
|
||||
if (!ob) {
|
||||
DOMWarning("failed to read source object for AnimationCurveNode->AnimationLayer link, ignoring", &element);
|
||||
continue;
|
||||
}
|
||||
|
||||
const AnimationCurveNode* const anim = dynamic_cast<const AnimationCurveNode*>(ob);
|
||||
if(!anim) {
|
||||
DOMWarning("source object for ->AnimationLayer link is not an AnimationCurveNode",&element);
|
||||
const AnimationCurveNode *const anim = dynamic_cast<const AnimationCurveNode *>(ob);
|
||||
if (!anim) {
|
||||
DOMWarning("source object for ->AnimationLayer link is not an AnimationCurveNode", &element);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(target_prop_whitelist) {
|
||||
const char* s = anim->TargetProperty().c_str();
|
||||
if (target_prop_whitelist) {
|
||||
const char *s = anim->TargetProperty().c_str();
|
||||
bool ok = false;
|
||||
for (size_t i = 0; i < whitelist_size; ++i) {
|
||||
if (!strcmp(s, target_prop_whitelist[i])) {
|
||||
|
@ -248,7 +235,7 @@ AnimationCurveNodeList AnimationLayer::Nodes(const char* const * target_prop_whi
|
|||
break;
|
||||
}
|
||||
}
|
||||
if(!ok) {
|
||||
if (!ok) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -259,34 +246,33 @@ AnimationCurveNodeList AnimationLayer::Nodes(const char* const * target_prop_whi
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationStack::AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc)
|
||||
: Object(id, element, name)
|
||||
{
|
||||
const Scope& sc = GetRequiredScope(element);
|
||||
AnimationStack::AnimationStack(uint64_t id, const Element &element, const std::string &name, const Document &doc) :
|
||||
Object(id, element, name) {
|
||||
const Scope &sc = GetRequiredScope(element);
|
||||
|
||||
// note: we don't currently use any of these properties so we shouldn't bother if it is missing
|
||||
props = GetPropertyTable(doc,"AnimationStack.FbxAnimStack",element,sc, true);
|
||||
props = GetPropertyTable(doc, "AnimationStack.FbxAnimStack", element, sc, true);
|
||||
|
||||
// resolve attached animation layers
|
||||
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationLayer");
|
||||
const std::vector<const Connection *> &conns = doc.GetConnectionsByDestinationSequenced(ID(), "AnimationLayer");
|
||||
layers.reserve(conns.size());
|
||||
|
||||
for(const Connection* con : conns) {
|
||||
for (const Connection *con : conns) {
|
||||
|
||||
// link should not go to a property
|
||||
if (con->PropertyName().length()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const Object* const ob = con->SourceObject();
|
||||
if(!ob) {
|
||||
DOMWarning("failed to read source object for AnimationLayer->AnimationStack link, ignoring",&element);
|
||||
const Object *const ob = con->SourceObject();
|
||||
if (!ob) {
|
||||
DOMWarning("failed to read source object for AnimationLayer->AnimationStack link, ignoring", &element);
|
||||
continue;
|
||||
}
|
||||
|
||||
const AnimationLayer* const anim = dynamic_cast<const AnimationLayer*>(ob);
|
||||
if(!anim) {
|
||||
DOMWarning("source object for ->AnimationStack link is not an AnimationLayer",&element);
|
||||
const AnimationLayer *const anim = dynamic_cast<const AnimationLayer *>(ob);
|
||||
if (!anim) {
|
||||
DOMWarning("source object for ->AnimationStack link is not an AnimationLayer", &element);
|
||||
continue;
|
||||
}
|
||||
layers.push_back(anim);
|
||||
|
@ -294,12 +280,11 @@ AnimationStack::AnimationStack(uint64_t id, const Element& element, const std::s
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationStack::~AnimationStack()
|
||||
{
|
||||
AnimationStack::~AnimationStack() {
|
||||
// empty
|
||||
}
|
||||
|
||||
} //!FBX
|
||||
} //!Assimp
|
||||
} // namespace FBX
|
||||
} // namespace Assimp
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_FBX_IMPORTER
|
||||
|
|
|
@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <stdint.h>
|
||||
#include <assimp/Exceptional.h>
|
||||
#include <assimp/ByteSwapper.h>
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
|
||||
namespace Assimp {
|
||||
namespace FBX {
|
||||
|
@ -427,6 +428,7 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
|
|||
void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length)
|
||||
{
|
||||
ai_assert(input);
|
||||
ASSIMP_LOG_DEBUG("Tokenizing binary FBX file");
|
||||
|
||||
if(length < 0x1b) {
|
||||
TokenizeError("file is too short",0);
|
||||
|
@ -451,6 +453,7 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length)
|
|||
/*Result ignored*/ ReadByte(input, cursor, input + length);
|
||||
/*Result ignored*/ ReadByte(input, cursor, input + length);
|
||||
const uint32_t version = ReadWord(input, cursor, input + length);
|
||||
ASSIMP_LOG_DEBUG_F("FBX version: ", version);
|
||||
const bool is64bits = version >= 7500;
|
||||
const char *end = input + length;
|
||||
while (cursor < end ) {
|
||||
|
|
|
@ -105,7 +105,7 @@ FBXConverter::FBXConverter(aiScene *out, const Document &doc, bool removeEmptyBo
|
|||
// The idea here is to traverse all objects to find these Textures and convert them,
|
||||
// so later during material conversion it will find converted texture in the textures_converted array.
|
||||
if (doc.Settings().readTextures) {
|
||||
ConvertOrphantEmbeddedTextures();
|
||||
ConvertOrphanedEmbeddedTextures();
|
||||
}
|
||||
ConvertRootNode();
|
||||
|
||||
|
@ -804,11 +804,6 @@ bool FBXConverter::GenerateTransformationNodeChain(const Model &model, const std
|
|||
aiMatrix4x4::Translation(-GeometricTranslation, chain[TransformationComp_GeometricTranslationInverse]);
|
||||
}
|
||||
|
||||
// is_complex needs to be consistent with NeedsComplexTransformationChain()
|
||||
// or the interplay between this code and the animation converter would
|
||||
// not be guaranteed.
|
||||
//ai_assert(NeedsComplexTransformationChain(model) == ((chainBits & chainMaskComplex) != 0));
|
||||
|
||||
// now, if we have more than just Translation, Scaling and Rotation,
|
||||
// we need to generate a full node chain to accommodate for assimp's
|
||||
// lack to express pivots and offsets.
|
||||
|
@ -1163,7 +1158,8 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
|
|||
const std::vector<aiVector3D> &curVertices = shapeGeometry->GetVertices();
|
||||
const std::vector<aiVector3D> &curNormals = shapeGeometry->GetNormals();
|
||||
const std::vector<unsigned int> &curIndices = shapeGeometry->GetIndices();
|
||||
animMesh->mName.Set(FixAnimMeshName(shapeGeometry->Name()));
|
||||
//losing channel name if using shapeGeometry->Name()
|
||||
animMesh->mName.Set(FixAnimMeshName(blendShapeChannel->Name()));
|
||||
for (size_t j = 0; j < curIndices.size(); j++) {
|
||||
const unsigned int curIndex = curIndices.at(j);
|
||||
aiVector3D vertex = curVertices.at(j);
|
||||
|
@ -1289,7 +1285,8 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
|
|||
}
|
||||
|
||||
if (binormals) {
|
||||
ai_assert(tangents.size() == vertices.size() && binormals->size() == vertices.size());
|
||||
ai_assert(tangents.size() == vertices.size());
|
||||
ai_assert(binormals->size() == vertices.size());
|
||||
|
||||
out_mesh->mTangents = new aiVector3D[vertices.size()];
|
||||
out_mesh->mBitangents = new aiVector3D[vertices.size()];
|
||||
|
@ -1542,10 +1539,10 @@ void FBXConverter::ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const
|
|||
aiBone *bone = nullptr;
|
||||
|
||||
if (bone_map.count(deformer_name)) {
|
||||
ASSIMP_LOG_DEBUG_F("retrieved bone from lookup ", bone_name.C_Str(), ". Deformer:", deformer_name);
|
||||
ASSIMP_LOG_VERBOSE_DEBUG_F("retrieved bone from lookup ", bone_name.C_Str(), ". Deformer:", deformer_name);
|
||||
bone = bone_map[deformer_name];
|
||||
} else {
|
||||
ASSIMP_LOG_DEBUG_F("created new bone ", bone_name.C_Str(), ". Deformer: ", deformer_name);
|
||||
ASSIMP_LOG_VERBOSE_DEBUG_F("created new bone ", bone_name.C_Str(), ". Deformer: ", deformer_name);
|
||||
bone = new aiBone();
|
||||
bone->mName = bone_name;
|
||||
|
||||
|
@ -1999,19 +1996,19 @@ void FBXConverter::SetTextureProperties(aiMaterial *out_mat, const TextureMap &_
|
|||
TrySetTextureProperties(out_mat, _textures, "Maya|ReflectionMapTexture", aiTextureType_REFLECTION, mesh);
|
||||
|
||||
// Maya PBR
|
||||
TrySetTextureProperties(out_mat, _textures, "Maya|baseColor|file", aiTextureType_BASE_COLOR, mesh);
|
||||
TrySetTextureProperties(out_mat, _textures, "Maya|normalCamera|file", aiTextureType_NORMAL_CAMERA, mesh);
|
||||
TrySetTextureProperties(out_mat, _textures, "Maya|emissionColor|file", aiTextureType_EMISSION_COLOR, mesh);
|
||||
TrySetTextureProperties(out_mat, _textures, "Maya|metalness|file", aiTextureType_METALNESS, mesh);
|
||||
TrySetTextureProperties(out_mat, _textures, "Maya|diffuseRoughness|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
|
||||
TrySetTextureProperties(out_mat, _textures, "Maya|baseColor", aiTextureType_BASE_COLOR, mesh);
|
||||
TrySetTextureProperties(out_mat, _textures, "Maya|normalCamera", aiTextureType_NORMAL_CAMERA, mesh);
|
||||
TrySetTextureProperties(out_mat, _textures, "Maya|emissionColor", aiTextureType_EMISSION_COLOR, mesh);
|
||||
TrySetTextureProperties(out_mat, _textures, "Maya|metalness", aiTextureType_METALNESS, mesh);
|
||||
TrySetTextureProperties(out_mat, _textures, "Maya|diffuseRoughness", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
|
||||
|
||||
// Maya stingray
|
||||
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_color_map|file", aiTextureType_BASE_COLOR, mesh);
|
||||
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_normal_map|file", aiTextureType_NORMAL_CAMERA, mesh);
|
||||
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_emissive_map|file", aiTextureType_EMISSION_COLOR, mesh);
|
||||
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_metallic_map|file", aiTextureType_METALNESS, mesh);
|
||||
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_roughness_map|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
|
||||
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_ao_map|file", aiTextureType_AMBIENT_OCCLUSION, mesh);
|
||||
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_color_map", aiTextureType_BASE_COLOR, mesh);
|
||||
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_normal_map", aiTextureType_NORMAL_CAMERA, mesh);
|
||||
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_emissive_map", aiTextureType_EMISSION_COLOR, mesh);
|
||||
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_metallic_map", aiTextureType_METALNESS, mesh);
|
||||
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_roughness_map", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
|
||||
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_ao_map", aiTextureType_AMBIENT_OCCLUSION, mesh);
|
||||
|
||||
// 3DSMax PBR
|
||||
TrySetTextureProperties(out_mat, _textures, "3dsMax|Parameters|base_color_map", aiTextureType_BASE_COLOR, mesh);
|
||||
|
@ -2719,7 +2716,7 @@ void FBXConverter::GenerateNodeAnimations(std::vector<aiNodeAnim *> &node_anims,
|
|||
if (doc.Settings().optimizeEmptyAnimationCurves &&
|
||||
IsRedundantAnimationData(target, comp, (chain[i]->second))) {
|
||||
|
||||
FBXImporter::LogDebug("dropping redundant animation channel for node " + target.Name());
|
||||
FBXImporter::LogVerboseDebug("dropping redundant animation channel for node " + target.Name());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -3164,7 +3161,8 @@ FBXConverter::KeyFrameListList FBXConverter::GetKeyframeList(const std::vector<c
|
|||
}
|
||||
|
||||
const AnimationCurve *const curve = kv.second;
|
||||
ai_assert(curve->GetKeys().size() == curve->GetValues().size() && curve->GetKeys().size());
|
||||
ai_assert(curve->GetKeys().size() == curve->GetValues().size());
|
||||
ai_assert(curve->GetKeys().size());
|
||||
|
||||
//get values within the start/stop time window
|
||||
std::shared_ptr<KeyTimeList> Keys(new KeyTimeList());
|
||||
|
@ -3315,6 +3313,7 @@ void FBXConverter::InterpolateKeys(aiQuatKey *valOut, const KeyTimeList &keys, c
|
|||
// http://www.3dkingdoms.com/weekly/weekly.php?a=36
|
||||
if (quat.x * lastq.x + quat.y * lastq.y + quat.z * lastq.z + quat.w * lastq.w < 0) {
|
||||
quat.Conjugate();
|
||||
quat.w = -quat.w;
|
||||
}
|
||||
lastq = quat;
|
||||
|
||||
|
@ -3466,7 +3465,7 @@ void FBXConverter::TransferDataToScene() {
|
|||
}
|
||||
}
|
||||
|
||||
void FBXConverter::ConvertOrphantEmbeddedTextures() {
|
||||
void FBXConverter::ConvertOrphanedEmbeddedTextures() {
|
||||
// in C++14 it could be:
|
||||
// for (auto&& [id, object] : objects)
|
||||
for (auto &&id_and_object : doc.Objects()) {
|
||||
|
|
|
@ -220,8 +220,8 @@ private:
|
|||
* each output vertex the DOM index it maps to.
|
||||
*/
|
||||
void ConvertWeights(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform,
|
||||
aiNode *parent = NULL, unsigned int materialIndex = NO_MATERIAL_SEPARATION,
|
||||
std::vector<unsigned int> *outputVertStartIndices = NULL);
|
||||
aiNode *parent = nullptr, unsigned int materialIndex = NO_MATERIAL_SEPARATION,
|
||||
std::vector<unsigned int> *outputVertStartIndices = nullptr);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const Cluster *cl,
|
||||
|
@ -412,7 +412,7 @@ private:
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// FBX file could have embedded textures not connected to anything
|
||||
void ConvertOrphantEmbeddedTextures();
|
||||
void ConvertOrphanedEmbeddedTextures();
|
||||
|
||||
private:
|
||||
// 0: not assigned yet, others: index is value - 1
|
||||
|
|
|
@ -55,6 +55,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "FBXDocumentUtil.h"
|
||||
#include "FBXProperties.h"
|
||||
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
|
@ -219,7 +221,7 @@ const Object* LazyObject::Get(bool dieOnError)
|
|||
if(!DefaultLogger::isNullLogger()) {
|
||||
ASSIMP_LOG_ERROR(ex.what());
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!object.get()) {
|
||||
|
@ -264,6 +266,8 @@ Document::Document(const Parser& parser, const ImportSettings& settings)
|
|||
: settings(settings)
|
||||
, parser(parser)
|
||||
{
|
||||
ASSIMP_LOG_DEBUG("Creating FBX Document");
|
||||
|
||||
// Cannot use array default initialization syntax because vc8 fails on it
|
||||
for (auto &timeStamp : creationTimeStamp) {
|
||||
timeStamp = 0;
|
||||
|
@ -308,6 +312,7 @@ void Document::ReadHeader() {
|
|||
|
||||
const Scope& shead = *ehead->Compound();
|
||||
fbxVersion = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(shead,"FBXVersion",ehead),0));
|
||||
ASSIMP_LOG_DEBUG_F("FBX Version: ", fbxVersion);
|
||||
|
||||
// While we may have some success with newer files, we don't support
|
||||
// the older 6.n fbx format
|
||||
|
@ -462,7 +467,7 @@ void Document::ReadPropertyTemplates()
|
|||
const Element *Properties70 = (*innerSc)["Properties70"];
|
||||
if(Properties70) {
|
||||
std::shared_ptr<const PropertyTable> props = std::make_shared<const PropertyTable>(
|
||||
*Properties70,std::shared_ptr<const PropertyTable>(static_cast<const PropertyTable*>(NULL))
|
||||
*Properties70, std::shared_ptr<const PropertyTable>(static_cast<const PropertyTable *>(nullptr))
|
||||
);
|
||||
|
||||
templates[oname+"."+pname] = props;
|
||||
|
|
|
@ -96,7 +96,7 @@ public:
|
|||
template <typename T>
|
||||
const T* Get(bool dieOnError = false) {
|
||||
const Object* const ob = Get(dieOnError);
|
||||
return ob ? dynamic_cast<const T*>(ob) : NULL;
|
||||
return ob ? dynamic_cast<const T *>(ob) : nullptr;
|
||||
}
|
||||
|
||||
uint64_t ID() const {
|
||||
|
@ -213,7 +213,8 @@ private:
|
|||
type name() const { \
|
||||
const int ival = PropertyGet<int>(Props(), fbx_stringize(name), static_cast<int>(default_value)); \
|
||||
if (ival < 0 || ival >= AI_CONCAT(type, _MAX)) { \
|
||||
ai_assert(static_cast<int>(default_value) >= 0 && static_cast<int>(default_value) < AI_CONCAT(type, _MAX)); \
|
||||
ai_assert(static_cast<int>(default_value) >= 0); \
|
||||
ai_assert(static_cast<int>(default_value) < AI_CONCAT(type, _MAX)); \
|
||||
return static_cast<type>(default_value); \
|
||||
} \
|
||||
return static_cast<type>(ival); \
|
||||
|
@ -744,7 +745,7 @@ public:
|
|||
wants animations for. If the curve node does not match one of these, std::range_error
|
||||
will be thrown. */
|
||||
AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc,
|
||||
const char* const * target_prop_whitelist = NULL, size_t whitelist_size = 0);
|
||||
const char *const *target_prop_whitelist = nullptr, size_t whitelist_size = 0);
|
||||
|
||||
virtual ~AnimationCurveNode();
|
||||
|
||||
|
@ -756,7 +757,7 @@ public:
|
|||
|
||||
const AnimationCurveMap& Curves() const;
|
||||
|
||||
/** Object the curve is assigned to, this can be NULL if the
|
||||
/** Object the curve is assigned to, this can be nullptr if the
|
||||
* target object has no DOM representation or could not
|
||||
* be read for other reasons.*/
|
||||
const Object* Target() const {
|
||||
|
@ -968,7 +969,7 @@ public:
|
|||
|
||||
// note: a connection ensures that the source and dest objects exist, but
|
||||
// not that they have DOM representations, so the return value of one of
|
||||
// these functions can still be NULL.
|
||||
// these functions can still be nullptr.
|
||||
const Object* SourceObject() const;
|
||||
const Object* DestinationObject() const;
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ void DOMError(const std::string& message, const Token& token)
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void DOMError(const std::string& message, const Element* element /*= NULL*/)
|
||||
void DOMError(const std::string& message, const Element* element /*= nullptr*/)
|
||||
{
|
||||
if(element) {
|
||||
DOMError(message,element->KeyToken());
|
||||
|
@ -84,7 +84,7 @@ void DOMWarning(const std::string& message, const Token& token)
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void DOMWarning(const std::string& message, const Element* element /*= NULL*/)
|
||||
void DOMWarning(const std::string& message, const Element* element /*= nullptr*/)
|
||||
{
|
||||
if(element) {
|
||||
DOMWarning(message,element->KeyToken());
|
||||
|
@ -106,7 +106,7 @@ std::shared_ptr<const PropertyTable> GetPropertyTable(const Document& doc,
|
|||
{
|
||||
const Element* const Properties70 = sc["Properties70"];
|
||||
std::shared_ptr<const PropertyTable> templateProps = std::shared_ptr<const PropertyTable>(
|
||||
static_cast<const PropertyTable*>(NULL));
|
||||
static_cast<const PropertyTable *>(nullptr));
|
||||
|
||||
if(templateName.length()) {
|
||||
PropertyTemplateMap::const_iterator it = doc.Templates().find(templateName);
|
||||
|
|
|
@ -146,6 +146,8 @@ void FBXImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
ThrowException("Could not open file for reading");
|
||||
}
|
||||
|
||||
ASSIMP_LOG_DEBUG("Reading FBX file");
|
||||
|
||||
// read entire file into memory - no streaming for this, fbx
|
||||
// files can grow large, but the assimp output data structure
|
||||
// then becomes very large, too. Assimp doesn't support
|
||||
|
|
|
@ -383,7 +383,7 @@ Video::Video(uint64_t id, const Element& element, const Document& doc, const std
|
|||
} catch (const runtime_error& runtimeError)
|
||||
{
|
||||
//we don't need the content data for contents that has already been loaded
|
||||
ASSIMP_LOG_DEBUG_F("Caught exception in FBXMaterial (likely because content was already loaded): ",
|
||||
ASSIMP_LOG_VERBOSE_DEBUG_F("Caught exception in FBXMaterial (likely because content was already loaded): ",
|
||||
runtimeError.what());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -241,7 +241,7 @@ const MatIndexArray& MeshGeometry::GetMaterialIndices() const {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
const unsigned int* MeshGeometry::ToOutputVertexIndex( unsigned int in_index, unsigned int& count ) const {
|
||||
if ( in_index >= m_mapping_counts.size() ) {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ai_assert( m_mapping_counts.size() == m_mapping_offsets.size() );
|
||||
|
|
|
@ -61,10 +61,10 @@ public:
|
|||
Geometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
|
||||
virtual ~Geometry();
|
||||
|
||||
/** Get the Skin attached to this geometry or NULL */
|
||||
/** Get the Skin attached to this geometry or nullptr */
|
||||
const Skin* DeformerSkin() const;
|
||||
|
||||
/** Get the BlendShape attached to this geometry or NULL */
|
||||
/** Get the BlendShape attached to this geometry or nullptr */
|
||||
const std::vector<const BlendShape*>& GetBlendShapes() const;
|
||||
|
||||
private:
|
||||
|
@ -123,7 +123,7 @@ public:
|
|||
/** Get per-face-vertex material assignments */
|
||||
const MatIndexArray& GetMaterialIndices() const;
|
||||
|
||||
/** Convert from a fbx file vertex index (for example from a #Cluster weight) or NULL
|
||||
/** Convert from a fbx file vertex index (for example from a #Cluster weight) or nullptr
|
||||
* if the vertex index is not valid. */
|
||||
const unsigned int* ToOutputVertexIndex( unsigned int in_index, unsigned int& count ) const;
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/ParsingUtils.h>
|
||||
#include <assimp/fast_atof.h>
|
||||
#include <assimp/ByteSwapper.h>
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
@ -76,7 +77,7 @@ namespace {
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AI_WONT_RETURN void ParseError(const std::string& message, const Element* element = NULL) AI_WONT_RETURN_SUFFIX;
|
||||
AI_WONT_RETURN void ParseError(const std::string &message, const Element *element = nullptr) AI_WONT_RETURN_SUFFIX;
|
||||
AI_WONT_RETURN void ParseError(const std::string& message, const Element* element)
|
||||
{
|
||||
if(element) {
|
||||
|
@ -180,7 +181,7 @@ Scope::Scope(Parser& parser,bool topLevel)
|
|||
}
|
||||
|
||||
TokenPtr n = parser.AdvanceToNextToken();
|
||||
if(n == NULL) {
|
||||
if (n == nullptr) {
|
||||
ParseError("unexpected end of file");
|
||||
}
|
||||
|
||||
|
@ -195,7 +196,7 @@ Scope::Scope(Parser& parser,bool topLevel)
|
|||
|
||||
// Element() should stop at the next Key token (or right after a Close token)
|
||||
n = parser.CurrentToken();
|
||||
if(n == NULL) {
|
||||
if (n == nullptr) {
|
||||
if (topLevel) {
|
||||
return;
|
||||
}
|
||||
|
@ -220,6 +221,7 @@ Parser::Parser (const TokenList& tokens, bool is_binary)
|
|||
, cursor(tokens.begin())
|
||||
, is_binary(is_binary)
|
||||
{
|
||||
ASSIMP_LOG_DEBUG("Parsing FBX tokens");
|
||||
root.reset(new Scope(*this,true));
|
||||
}
|
||||
|
||||
|
@ -234,7 +236,7 @@ TokenPtr Parser::AdvanceToNextToken()
|
|||
{
|
||||
last = current;
|
||||
if (cursor == tokens.end()) {
|
||||
current = NULL;
|
||||
current = nullptr;
|
||||
} else {
|
||||
current = *cursor++;
|
||||
}
|
||||
|
@ -256,7 +258,7 @@ TokenPtr Parser::LastToken() const
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
uint64_t ParseTokenAsID(const Token& t, const char*& err_out)
|
||||
{
|
||||
err_out = NULL;
|
||||
err_out = nullptr;
|
||||
|
||||
if (t.Type() != TokenType_DATA) {
|
||||
err_out = "expected TOK_DATA token";
|
||||
|
@ -294,7 +296,7 @@ uint64_t ParseTokenAsID(const Token& t, const char*& err_out)
|
|||
size_t ParseTokenAsDim(const Token& t, const char*& err_out)
|
||||
{
|
||||
// same as ID parsing, except there is a trailing asterisk
|
||||
err_out = NULL;
|
||||
err_out = nullptr;
|
||||
|
||||
if (t.Type() != TokenType_DATA) {
|
||||
err_out = "expected TOK_DATA token";
|
||||
|
@ -340,7 +342,7 @@ size_t ParseTokenAsDim(const Token& t, const char*& err_out)
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
float ParseTokenAsFloat(const Token& t, const char*& err_out)
|
||||
{
|
||||
err_out = NULL;
|
||||
err_out = nullptr;
|
||||
|
||||
if (t.Type() != TokenType_DATA) {
|
||||
err_out = "expected TOK_DATA token";
|
||||
|
@ -383,7 +385,7 @@ float ParseTokenAsFloat(const Token& t, const char*& err_out)
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
int ParseTokenAsInt(const Token& t, const char*& err_out)
|
||||
{
|
||||
err_out = NULL;
|
||||
err_out = nullptr;
|
||||
|
||||
if (t.Type() != TokenType_DATA) {
|
||||
err_out = "expected TOK_DATA token";
|
||||
|
@ -419,7 +421,7 @@ int ParseTokenAsInt(const Token& t, const char*& err_out)
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
int64_t ParseTokenAsInt64(const Token& t, const char*& err_out)
|
||||
{
|
||||
err_out = NULL;
|
||||
err_out = nullptr;
|
||||
|
||||
if (t.Type() != TokenType_DATA) {
|
||||
err_out = "expected TOK_DATA token";
|
||||
|
@ -456,7 +458,7 @@ int64_t ParseTokenAsInt64(const Token& t, const char*& err_out)
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
std::string ParseTokenAsString(const Token& t, const char*& err_out)
|
||||
{
|
||||
err_out = NULL;
|
||||
err_out = nullptr;
|
||||
|
||||
if (t.Type() != TokenType_DATA) {
|
||||
err_out = "expected TOK_DATA token";
|
||||
|
@ -1209,7 +1211,7 @@ bool HasElement( const Scope& sc, const std::string& index ) {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// extract a required element from a scope, abort if the element cannot be found
|
||||
const Element& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element /*= NULL*/)
|
||||
const Element& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element /*= nullptr*/)
|
||||
{
|
||||
const Element* el = sc[index];
|
||||
if(!el) {
|
||||
|
|
|
@ -137,7 +137,7 @@ public:
|
|||
return element->second;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ElementCollection GetCollection(const std::string& index) const {
|
||||
|
@ -219,7 +219,7 @@ void ParseVectorDataArray(std::vector<int64_t>& out, const Element& el);
|
|||
bool HasElement( const Scope& sc, const std::string& index );
|
||||
|
||||
// extract a required element from a scope, abort if the element cannot be found
|
||||
const Element& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element = NULL);
|
||||
const Element &GetRequiredElement(const Scope &sc, const std::string &index, const Element *element = nullptr);
|
||||
|
||||
// extract required compound scope
|
||||
const Scope& GetRequiredScope(const Element& el);
|
||||
|
|
|
@ -70,7 +70,7 @@ Property::~Property()
|
|||
namespace {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// read a typed property out of a FBX element. The return value is NULL if the property cannot be read.
|
||||
// read a typed property out of a FBX element. The return value is nullptr if the property cannot be read.
|
||||
Property* ReadTypedProperty(const Element& element)
|
||||
{
|
||||
ai_assert(element.KeyToken().StringContents() == "P");
|
||||
|
@ -112,7 +112,7 @@ Property* ReadTypedProperty(const Element& element)
|
|||
else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"Float") || !strcmp(cs,"FieldOfView") || !strcmp( cs, "UnitScaleFactor" ) ) {
|
||||
return new TypedProperty<float>(ParseTokenAsFloat(*tok[4]));
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
@ -197,7 +197,7 @@ const Property* PropertyTable::Get(const std::string& name) const
|
|||
return templateProps->Get(name);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ public:
|
|||
|
||||
const Property* Get(const std::string& name) const;
|
||||
|
||||
// PropertyTable's need not be coupled with FBX elements so this can be NULL
|
||||
// PropertyTable's need not be coupled with FBX elements so this can be nullptr
|
||||
const Element* GetElement() const {
|
||||
return element;
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "FBXTokenizer.h"
|
||||
#include "FBXUtil.h"
|
||||
#include <assimp/Exceptional.h>
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
|
||||
namespace Assimp {
|
||||
namespace FBX {
|
||||
|
@ -126,7 +127,7 @@ void ProcessDataToken( TokenList& output_tokens, const char*& start, const char*
|
|||
TokenizeError("unexpected character, expected data token", line, column);
|
||||
}
|
||||
|
||||
start = end = NULL;
|
||||
start = end = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -135,6 +136,7 @@ void ProcessDataToken( TokenList& output_tokens, const char*& start, const char*
|
|||
void Tokenize(TokenList& output_tokens, const char* input)
|
||||
{
|
||||
ai_assert(input);
|
||||
ASSIMP_LOG_DEBUG("Tokenizing ASCII FBX file");
|
||||
|
||||
// line and column numbers numbers are one-based
|
||||
unsigned int line = 1;
|
||||
|
@ -144,7 +146,7 @@ void Tokenize(TokenList& output_tokens, const char* input)
|
|||
bool in_double_quotes = false;
|
||||
bool pending_data_token = false;
|
||||
|
||||
const char* token_begin = NULL, *token_end = NULL;
|
||||
const char *token_begin = nullptr, *token_end = nullptr;
|
||||
for (const char* cur = input;*cur;column += (*cur == '\t' ? ASSIMP_FBX_TAB_WIDTH : 1), ++cur) {
|
||||
const char c = *cur;
|
||||
|
||||
|
|
|
@ -5,8 +5,6 @@ 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,
|
||||
|
@ -43,17 +41,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
/** @file Implementation of the MDL importer class */
|
||||
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_HMP_IMPORTER
|
||||
|
||||
// internal headers
|
||||
#include "AssetLib/HMP/HMPLoader.h"
|
||||
#include "AssetLib/MD2/MD2FileData.h"
|
||||
|
||||
#include <assimp/IOSystem.hpp>
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/importerdesc.h>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
#include <assimp/IOSystem.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
@ -74,24 +71,21 @@ static const aiImporterDesc desc = {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor to be privately used by Importer
|
||||
HMPImporter::HMPImporter()
|
||||
{
|
||||
HMPImporter::HMPImporter() {
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Destructor, private as well
|
||||
HMPImporter::~HMPImporter()
|
||||
{
|
||||
HMPImporter::~HMPImporter() {
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns whether the class can handle the format of the given file.
|
||||
bool HMPImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const
|
||||
{
|
||||
bool HMPImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool cs) const {
|
||||
const std::string extension = GetExtension(pFile);
|
||||
if (extension == "hmp" )
|
||||
if (extension == "hmp")
|
||||
return true;
|
||||
|
||||
// if check for extension is not enough, check for the magic tokens
|
||||
|
@ -100,78 +94,72 @@ bool HMPImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
|
|||
tokens[0] = AI_HMP_MAGIC_NUMBER_LE_4;
|
||||
tokens[1] = AI_HMP_MAGIC_NUMBER_LE_5;
|
||||
tokens[2] = AI_HMP_MAGIC_NUMBER_LE_7;
|
||||
return CheckMagicToken(pIOHandler,pFile,tokens,3,0);
|
||||
return CheckMagicToken(pIOHandler, pFile, tokens, 3, 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Get list of all file extensions that are handled by this loader
|
||||
const aiImporterDesc* HMPImporter::GetInfo () const
|
||||
{
|
||||
const aiImporterDesc *HMPImporter::GetInfo() const {
|
||||
return &desc;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Imports the given file into the given scene structure.
|
||||
void HMPImporter::InternReadFile( const std::string& pFile,
|
||||
aiScene* _pScene, IOSystem* _pIOHandler)
|
||||
{
|
||||
void HMPImporter::InternReadFile(const std::string &pFile,
|
||||
aiScene *_pScene, IOSystem *_pIOHandler) {
|
||||
pScene = _pScene;
|
||||
mIOHandler = _pIOHandler;
|
||||
std::unique_ptr<IOStream> file(mIOHandler->Open(pFile));
|
||||
|
||||
// Check whether we can read from the file
|
||||
if( file.get() == nullptr)
|
||||
throw DeadlyImportError( "Failed to open HMP file " + pFile + ".");
|
||||
if (file.get() == nullptr) {
|
||||
throw DeadlyImportError("Failed to open HMP file " + pFile + ".");
|
||||
}
|
||||
|
||||
// Check whether the HMP file is large enough to contain
|
||||
// at least the file header
|
||||
const size_t fileSize = file->FileSize();
|
||||
if( fileSize < 50)
|
||||
throw DeadlyImportError( "HMP File is too small.");
|
||||
if (fileSize < 50)
|
||||
throw DeadlyImportError("HMP File is too small.");
|
||||
|
||||
// Allocate storage and copy the contents of the file to a memory buffer
|
||||
mBuffer = new uint8_t[fileSize];
|
||||
file->Read( (void*)mBuffer, 1, fileSize);
|
||||
file->Read((void *)mBuffer, 1, fileSize);
|
||||
iFileSize = (unsigned int)fileSize;
|
||||
|
||||
// Determine the file subtype and call the appropriate member function
|
||||
const uint32_t iMagic = *((uint32_t*)this->mBuffer);
|
||||
const uint32_t iMagic = *((uint32_t *)this->mBuffer);
|
||||
|
||||
// HMP4 format
|
||||
if (AI_HMP_MAGIC_NUMBER_LE_4 == iMagic ||
|
||||
AI_HMP_MAGIC_NUMBER_BE_4 == iMagic)
|
||||
{
|
||||
AI_HMP_MAGIC_NUMBER_BE_4 == iMagic) {
|
||||
ASSIMP_LOG_DEBUG("HMP subtype: 3D GameStudio A4, magic word is HMP4");
|
||||
InternReadFile_HMP4();
|
||||
}
|
||||
// HMP5 format
|
||||
else if (AI_HMP_MAGIC_NUMBER_LE_5 == iMagic ||
|
||||
AI_HMP_MAGIC_NUMBER_BE_5 == iMagic)
|
||||
{
|
||||
AI_HMP_MAGIC_NUMBER_BE_5 == iMagic) {
|
||||
ASSIMP_LOG_DEBUG("HMP subtype: 3D GameStudio A5, magic word is HMP5");
|
||||
InternReadFile_HMP5();
|
||||
}
|
||||
// HMP7 format
|
||||
else if (AI_HMP_MAGIC_NUMBER_LE_7 == iMagic ||
|
||||
AI_HMP_MAGIC_NUMBER_BE_7 == iMagic)
|
||||
{
|
||||
AI_HMP_MAGIC_NUMBER_BE_7 == iMagic) {
|
||||
ASSIMP_LOG_DEBUG("HMP subtype: 3D GameStudio A7, magic word is HMP7");
|
||||
InternReadFile_HMP7();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Print the magic word to the logger
|
||||
char szBuffer[5];
|
||||
szBuffer[0] = ((char*)&iMagic)[0];
|
||||
szBuffer[1] = ((char*)&iMagic)[1];
|
||||
szBuffer[2] = ((char*)&iMagic)[2];
|
||||
szBuffer[3] = ((char*)&iMagic)[3];
|
||||
szBuffer[0] = ((char *)&iMagic)[0];
|
||||
szBuffer[1] = ((char *)&iMagic)[1];
|
||||
szBuffer[2] = ((char *)&iMagic)[2];
|
||||
szBuffer[3] = ((char *)&iMagic)[3];
|
||||
szBuffer[4] = '\0';
|
||||
|
||||
// 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");
|
||||
}
|
||||
|
||||
|
@ -179,17 +167,14 @@ void HMPImporter::InternReadFile( const std::string& pFile,
|
|||
pScene->mFlags |= AI_SCENE_FLAGS_TERRAIN;
|
||||
|
||||
delete[] mBuffer;
|
||||
mBuffer= nullptr;
|
||||
|
||||
mBuffer = nullptr;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void HMPImporter::ValidateHeader_HMP457( )
|
||||
{
|
||||
const HMP::Header_HMP5* const pcHeader = (const HMP::Header_HMP5*)mBuffer;
|
||||
void HMPImporter::ValidateHeader_HMP457() {
|
||||
const HMP::Header_HMP5 *const pcHeader = (const HMP::Header_HMP5 *)mBuffer;
|
||||
|
||||
if (120 > iFileSize)
|
||||
{
|
||||
if (120 > iFileSize) {
|
||||
throw DeadlyImportError("HMP file is too small (header size is "
|
||||
"120 bytes, this file is smaller)");
|
||||
}
|
||||
|
@ -197,32 +182,29 @@ void HMPImporter::ValidateHeader_HMP457( )
|
|||
if (!pcHeader->ftrisize_x || !pcHeader->ftrisize_y)
|
||||
throw DeadlyImportError("Size of triangles in either x or y direction is zero");
|
||||
|
||||
if(pcHeader->fnumverts_x < 1.0f || (pcHeader->numverts/pcHeader->fnumverts_x) < 1.0f)
|
||||
if (pcHeader->fnumverts_x < 1.0f || (pcHeader->numverts / pcHeader->fnumverts_x) < 1.0f)
|
||||
throw DeadlyImportError("Number of triangles in either x or y direction is zero");
|
||||
|
||||
if(!pcHeader->numframes)
|
||||
if (!pcHeader->numframes)
|
||||
throw DeadlyImportError("There are no frames. At least one should be there");
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void HMPImporter::InternReadFile_HMP4( )
|
||||
{
|
||||
void HMPImporter::InternReadFile_HMP4() {
|
||||
throw DeadlyImportError("HMP4 is currently not supported");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void HMPImporter::InternReadFile_HMP5( )
|
||||
{
|
||||
void HMPImporter::InternReadFile_HMP5() {
|
||||
// read the file header and skip everything to byte 84
|
||||
const HMP::Header_HMP5* pcHeader = (const HMP::Header_HMP5*)mBuffer;
|
||||
const unsigned char* szCurrent = (const unsigned char*)(mBuffer+84);
|
||||
const HMP::Header_HMP5 *pcHeader = (const HMP::Header_HMP5 *)mBuffer;
|
||||
const unsigned char *szCurrent = (const unsigned char *)(mBuffer + 84);
|
||||
ValidateHeader_HMP457();
|
||||
|
||||
// generate an output mesh
|
||||
pScene->mNumMeshes = 1;
|
||||
pScene->mMeshes = new aiMesh*[1];
|
||||
aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh();
|
||||
pScene->mMeshes = new aiMesh *[1];
|
||||
aiMesh *pcMesh = pScene->mMeshes[0] = new aiMesh();
|
||||
|
||||
pcMesh->mMaterialIndex = 0;
|
||||
pcMesh->mVertices = new aiVector3D[pcHeader->numverts];
|
||||
|
@ -232,35 +214,35 @@ void HMPImporter::InternReadFile_HMP5( )
|
|||
const unsigned int width = (unsigned int)pcHeader->fnumverts_x;
|
||||
|
||||
// generate/load a material for the terrain
|
||||
CreateMaterial(szCurrent,&szCurrent);
|
||||
CreateMaterial(szCurrent, &szCurrent);
|
||||
|
||||
// goto offset 120, I don't know why ...
|
||||
// (fixme) is this the frame header? I assume yes since it starts with 2.
|
||||
szCurrent += 36;
|
||||
SizeCheck(szCurrent + sizeof(const HMP::Vertex_HMP7)*height*width);
|
||||
SizeCheck(szCurrent + sizeof(const HMP::Vertex_HMP7) * height * width);
|
||||
|
||||
// now load all vertices from the file
|
||||
aiVector3D* pcVertOut = pcMesh->mVertices;
|
||||
aiVector3D* pcNorOut = pcMesh->mNormals;
|
||||
const HMP::Vertex_HMP5* src = (const HMP::Vertex_HMP5*) szCurrent;
|
||||
for (unsigned int y = 0; y < height;++y)
|
||||
{
|
||||
for (unsigned int x = 0; x < width;++x)
|
||||
{
|
||||
aiVector3D *pcVertOut = pcMesh->mVertices;
|
||||
aiVector3D *pcNorOut = pcMesh->mNormals;
|
||||
const HMP::Vertex_HMP5 *src = (const HMP::Vertex_HMP5 *)szCurrent;
|
||||
for (unsigned int y = 0; y < height; ++y) {
|
||||
for (unsigned int x = 0; x < width; ++x) {
|
||||
pcVertOut->x = x * pcHeader->ftrisize_x;
|
||||
pcVertOut->y = y * pcHeader->ftrisize_y;
|
||||
pcVertOut->z = (((float)src->z / 0xffff)-0.5f) * pcHeader->ftrisize_x * 8.0f;
|
||||
MD2::LookupNormalIndex(src->normals162index, *pcNorOut );
|
||||
++pcVertOut;++pcNorOut;++src;
|
||||
pcVertOut->z = (((float)src->z / 0xffff) - 0.5f) * pcHeader->ftrisize_x * 8.0f;
|
||||
MD2::LookupNormalIndex(src->normals162index, *pcNorOut);
|
||||
++pcVertOut;
|
||||
++pcNorOut;
|
||||
++src;
|
||||
}
|
||||
}
|
||||
|
||||
// generate texture coordinates if necessary
|
||||
if (pcHeader->numskins)
|
||||
GenerateTextureCoords(width,height);
|
||||
GenerateTextureCoords(width, height);
|
||||
|
||||
// now build a list of faces
|
||||
CreateOutputFaceList(width,height);
|
||||
CreateOutputFaceList(width, height);
|
||||
|
||||
// there is no nodegraph in HMP files. Simply assign the one mesh
|
||||
// (no, not the one ring) to the root node
|
||||
|
@ -272,17 +254,16 @@ void HMPImporter::InternReadFile_HMP5( )
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void HMPImporter::InternReadFile_HMP7( )
|
||||
{
|
||||
void HMPImporter::InternReadFile_HMP7() {
|
||||
// read the file header and skip everything to byte 84
|
||||
const HMP::Header_HMP5* const pcHeader = (const HMP::Header_HMP5*)mBuffer;
|
||||
const unsigned char* szCurrent = (const unsigned char*)(mBuffer+84);
|
||||
const HMP::Header_HMP5 *const pcHeader = (const HMP::Header_HMP5 *)mBuffer;
|
||||
const unsigned char *szCurrent = (const unsigned char *)(mBuffer + 84);
|
||||
ValidateHeader_HMP457();
|
||||
|
||||
// generate an output mesh
|
||||
pScene->mNumMeshes = 1;
|
||||
pScene->mMeshes = new aiMesh*[1];
|
||||
aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh();
|
||||
pScene->mMeshes = new aiMesh *[1];
|
||||
aiMesh *pcMesh = pScene->mMeshes[0] = new aiMesh();
|
||||
|
||||
pcMesh->mMaterialIndex = 0;
|
||||
pcMesh->mVertices = new aiVector3D[pcHeader->numverts];
|
||||
|
@ -292,44 +273,44 @@ void HMPImporter::InternReadFile_HMP7( )
|
|||
const unsigned int width = (unsigned int)pcHeader->fnumverts_x;
|
||||
|
||||
// generate/load a material for the terrain
|
||||
CreateMaterial(szCurrent,&szCurrent);
|
||||
CreateMaterial(szCurrent, &szCurrent);
|
||||
|
||||
// goto offset 120, I don't know why ...
|
||||
// (fixme) is this the frame header? I assume yes since it starts with 2.
|
||||
szCurrent += 36;
|
||||
|
||||
SizeCheck(szCurrent + sizeof(const HMP::Vertex_HMP7)*height*width);
|
||||
SizeCheck(szCurrent + sizeof(const HMP::Vertex_HMP7) * height * width);
|
||||
|
||||
// now load all vertices from the file
|
||||
aiVector3D* pcVertOut = pcMesh->mVertices;
|
||||
aiVector3D* pcNorOut = pcMesh->mNormals;
|
||||
const HMP::Vertex_HMP7* src = (const HMP::Vertex_HMP7*) szCurrent;
|
||||
for (unsigned int y = 0; y < height;++y)
|
||||
{
|
||||
for (unsigned int x = 0; x < width;++x)
|
||||
{
|
||||
aiVector3D *pcVertOut = pcMesh->mVertices;
|
||||
aiVector3D *pcNorOut = pcMesh->mNormals;
|
||||
const HMP::Vertex_HMP7 *src = (const HMP::Vertex_HMP7 *)szCurrent;
|
||||
for (unsigned int y = 0; y < height; ++y) {
|
||||
for (unsigned int x = 0; x < width; ++x) {
|
||||
pcVertOut->x = x * pcHeader->ftrisize_x;
|
||||
pcVertOut->y = y * pcHeader->ftrisize_y;
|
||||
|
||||
// FIXME: What exctly is the correct scaling factor to use?
|
||||
// possibly pcHeader->scale_origin[2] in combination with a
|
||||
// signed interpretation of src->z?
|
||||
pcVertOut->z = (((float)src->z / 0xffff)-0.5f) * pcHeader->ftrisize_x * 8.0f;
|
||||
pcVertOut->z = (((float)src->z / 0xffff) - 0.5f) * pcHeader->ftrisize_x * 8.0f;
|
||||
|
||||
pcNorOut->x = ((float)src->normal_x / 0x80 ); // * pcHeader->scale_origin[0];
|
||||
pcNorOut->y = ((float)src->normal_y / 0x80 ); // * pcHeader->scale_origin[1];
|
||||
pcNorOut->x = ((float)src->normal_x / 0x80); // * pcHeader->scale_origin[0];
|
||||
pcNorOut->y = ((float)src->normal_y / 0x80); // * pcHeader->scale_origin[1];
|
||||
pcNorOut->z = 1.0f;
|
||||
pcNorOut->Normalize();
|
||||
|
||||
++pcVertOut;++pcNorOut;++src;
|
||||
++pcVertOut;
|
||||
++pcNorOut;
|
||||
++src;
|
||||
}
|
||||
}
|
||||
|
||||
// generate texture coordinates if necessary
|
||||
if (pcHeader->numskins)GenerateTextureCoords(width,height);
|
||||
if (pcHeader->numskins) GenerateTextureCoords(width, height);
|
||||
|
||||
// now build a list of faces
|
||||
CreateOutputFaceList(width,height);
|
||||
CreateOutputFaceList(width, height);
|
||||
|
||||
// there is no nodegraph in HMP files. Simply assign the one mesh
|
||||
// (no, not the One Ring) to the root node
|
||||
|
@ -341,96 +322,89 @@ void HMPImporter::InternReadFile_HMP7( )
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void HMPImporter::CreateMaterial(const unsigned char* szCurrent,
|
||||
const unsigned char** szCurrentOut)
|
||||
{
|
||||
aiMesh* const pcMesh = pScene->mMeshes[0];
|
||||
const HMP::Header_HMP5* const pcHeader = (const HMP::Header_HMP5*)mBuffer;
|
||||
void HMPImporter::CreateMaterial(const unsigned char *szCurrent,
|
||||
const unsigned char **szCurrentOut) {
|
||||
aiMesh *const pcMesh = pScene->mMeshes[0];
|
||||
const HMP::Header_HMP5 *const pcHeader = (const HMP::Header_HMP5 *)mBuffer;
|
||||
|
||||
// we don't need to generate texture coordinates if
|
||||
// we have no textures in the file ...
|
||||
if (pcHeader->numskins)
|
||||
{
|
||||
if (pcHeader->numskins) {
|
||||
pcMesh->mTextureCoords[0] = new aiVector3D[pcHeader->numverts];
|
||||
pcMesh->mNumUVComponents[0] = 2;
|
||||
|
||||
// now read the first skin and skip all others
|
||||
ReadFirstSkin(pcHeader->numskins,szCurrent,&szCurrent);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadFirstSkin(pcHeader->numskins, szCurrent, &szCurrent);
|
||||
} else {
|
||||
// generate a default material
|
||||
const int iMode = (int)aiShadingMode_Gouraud;
|
||||
aiMaterial* pcHelper = new aiMaterial();
|
||||
aiMaterial *pcHelper = new aiMaterial();
|
||||
pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
|
||||
|
||||
aiColor3D clr;
|
||||
clr.b = clr.g = clr.r = 0.6f;
|
||||
pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
|
||||
pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
|
||||
pcHelper->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_DIFFUSE);
|
||||
pcHelper->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_SPECULAR);
|
||||
|
||||
clr.b = clr.g = clr.r = 0.05f;
|
||||
pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
|
||||
pcHelper->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_AMBIENT);
|
||||
|
||||
aiString szName;
|
||||
szName.Set(AI_DEFAULT_MATERIAL_NAME);
|
||||
pcHelper->AddProperty(&szName,AI_MATKEY_NAME);
|
||||
pcHelper->AddProperty(&szName, AI_MATKEY_NAME);
|
||||
|
||||
// add the material to the scene
|
||||
pScene->mNumMaterials = 1;
|
||||
pScene->mMaterials = new aiMaterial*[1];
|
||||
pScene->mMaterials = new aiMaterial *[1];
|
||||
pScene->mMaterials[0] = pcHelper;
|
||||
}
|
||||
*szCurrentOut = szCurrent;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void HMPImporter::CreateOutputFaceList(unsigned int width,unsigned int height)
|
||||
{
|
||||
aiMesh* const pcMesh = this->pScene->mMeshes[0];
|
||||
void HMPImporter::CreateOutputFaceList(unsigned int width, unsigned int height) {
|
||||
aiMesh *const pcMesh = this->pScene->mMeshes[0];
|
||||
|
||||
// Allocate enough storage
|
||||
pcMesh->mNumFaces = (width-1) * (height-1);
|
||||
pcMesh->mNumFaces = (width - 1) * (height - 1);
|
||||
pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
|
||||
|
||||
pcMesh->mNumVertices = pcMesh->mNumFaces*4;
|
||||
aiVector3D* pcVertices = new aiVector3D[pcMesh->mNumVertices];
|
||||
aiVector3D* pcNormals = new aiVector3D[pcMesh->mNumVertices];
|
||||
pcMesh->mNumVertices = pcMesh->mNumFaces * 4;
|
||||
aiVector3D *pcVertices = new aiVector3D[pcMesh->mNumVertices];
|
||||
aiVector3D *pcNormals = new aiVector3D[pcMesh->mNumVertices];
|
||||
|
||||
aiFace* pcFaceOut(pcMesh->mFaces);
|
||||
aiVector3D* pcVertOut = pcVertices;
|
||||
aiVector3D* pcNorOut = pcNormals;
|
||||
aiFace *pcFaceOut(pcMesh->mFaces);
|
||||
aiVector3D *pcVertOut = pcVertices;
|
||||
aiVector3D *pcNorOut = pcNormals;
|
||||
|
||||
aiVector3D* pcUVs = pcMesh->mTextureCoords[0] ? new aiVector3D[pcMesh->mNumVertices] : NULL;
|
||||
aiVector3D* pcUVOut(pcUVs);
|
||||
aiVector3D *pcUVs = pcMesh->mTextureCoords[0] ? new aiVector3D[pcMesh->mNumVertices] : nullptr;
|
||||
aiVector3D *pcUVOut(pcUVs);
|
||||
|
||||
// Build the terrain square
|
||||
unsigned int iCurrent = 0;
|
||||
for (unsigned int y = 0; y < height-1;++y) {
|
||||
for (unsigned int x = 0; x < width-1;++x,++pcFaceOut) {
|
||||
for (unsigned int y = 0; y < height - 1; ++y) {
|
||||
for (unsigned int x = 0; x < width - 1; ++x, ++pcFaceOut) {
|
||||
pcFaceOut->mNumIndices = 4;
|
||||
pcFaceOut->mIndices = new unsigned int[4];
|
||||
|
||||
*pcVertOut++ = pcMesh->mVertices[y*width+x];
|
||||
*pcVertOut++ = pcMesh->mVertices[(y+1)*width+x];
|
||||
*pcVertOut++ = pcMesh->mVertices[(y+1)*width+x+1];
|
||||
*pcVertOut++ = pcMesh->mVertices[y*width+x+1];
|
||||
*pcVertOut++ = pcMesh->mVertices[y * width + x];
|
||||
*pcVertOut++ = pcMesh->mVertices[(y + 1) * width + x];
|
||||
*pcVertOut++ = pcMesh->mVertices[(y + 1) * width + x + 1];
|
||||
*pcVertOut++ = pcMesh->mVertices[y * width + x + 1];
|
||||
|
||||
*pcNorOut++ = pcMesh->mNormals[y * width + x];
|
||||
*pcNorOut++ = pcMesh->mNormals[(y + 1) * width + x];
|
||||
*pcNorOut++ = pcMesh->mNormals[(y + 1) * width + x + 1];
|
||||
*pcNorOut++ = pcMesh->mNormals[y * width + x + 1];
|
||||
|
||||
*pcNorOut++ = pcMesh->mNormals[y*width+x];
|
||||
*pcNorOut++ = pcMesh->mNormals[(y+1)*width+x];
|
||||
*pcNorOut++ = pcMesh->mNormals[(y+1)*width+x+1];
|
||||
*pcNorOut++ = pcMesh->mNormals[y*width+x+1];
|
||||
|
||||
if (pcMesh->mTextureCoords[0])
|
||||
{
|
||||
*pcUVOut++ = pcMesh->mTextureCoords[0][y*width+x];
|
||||
*pcUVOut++ = pcMesh->mTextureCoords[0][(y+1)*width+x];
|
||||
*pcUVOut++ = pcMesh->mTextureCoords[0][(y+1)*width+x+1];
|
||||
*pcUVOut++ = pcMesh->mTextureCoords[0][y*width+x+1];
|
||||
if (pcMesh->mTextureCoords[0]) {
|
||||
*pcUVOut++ = pcMesh->mTextureCoords[0][y * width + x];
|
||||
*pcUVOut++ = pcMesh->mTextureCoords[0][(y + 1) * width + x];
|
||||
*pcUVOut++ = pcMesh->mTextureCoords[0][(y + 1) * width + x + 1];
|
||||
*pcUVOut++ = pcMesh->mTextureCoords[0][y * width + x + 1];
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < 4;++i)
|
||||
for (unsigned int i = 0; i < 4; ++i)
|
||||
pcFaceOut->mIndices[i] = iCurrent++;
|
||||
}
|
||||
}
|
||||
|
@ -440,58 +414,58 @@ void HMPImporter::CreateOutputFaceList(unsigned int width,unsigned int height)
|
|||
delete[] pcMesh->mNormals;
|
||||
pcMesh->mNormals = pcNormals;
|
||||
|
||||
if (pcMesh->mTextureCoords[0])
|
||||
{
|
||||
if (pcMesh->mTextureCoords[0]) {
|
||||
delete[] pcMesh->mTextureCoords[0];
|
||||
pcMesh->mTextureCoords[0] = pcUVs;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void HMPImporter::ReadFirstSkin(unsigned int iNumSkins, const unsigned char* szCursor,
|
||||
const unsigned char** szCursorOut)
|
||||
{
|
||||
ai_assert( 0 != iNumSkins );
|
||||
ai_assert( nullptr != szCursor);
|
||||
void HMPImporter::ReadFirstSkin(unsigned int iNumSkins, const unsigned char *szCursor,
|
||||
const unsigned char **szCursorOut) {
|
||||
ai_assert(0 != iNumSkins);
|
||||
ai_assert(nullptr != szCursor);
|
||||
|
||||
// read the type of the skin ...
|
||||
// sometimes we need to skip 12 bytes here, I don't know why ...
|
||||
uint32_t iType = *((uint32_t*)szCursor);
|
||||
uint32_t iType = *((uint32_t *)szCursor);
|
||||
szCursor += sizeof(uint32_t);
|
||||
if (0 == iType)
|
||||
{
|
||||
if (0 == iType) {
|
||||
szCursor += sizeof(uint32_t) * 2;
|
||||
iType = *((uint32_t*)szCursor);
|
||||
iType = *((uint32_t *)szCursor);
|
||||
szCursor += sizeof(uint32_t);
|
||||
if (!iType)
|
||||
throw DeadlyImportError("Unable to read HMP7 skin chunk");
|
||||
|
||||
}
|
||||
// read width and height
|
||||
uint32_t iWidth = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t);
|
||||
uint32_t iHeight = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t);
|
||||
uint32_t iWidth = *((uint32_t *)szCursor);
|
||||
szCursor += sizeof(uint32_t);
|
||||
uint32_t iHeight = *((uint32_t *)szCursor);
|
||||
szCursor += sizeof(uint32_t);
|
||||
|
||||
// allocate an output material
|
||||
aiMaterial* pcMat = new aiMaterial();
|
||||
aiMaterial *pcMat = new aiMaterial();
|
||||
|
||||
// read the skin, this works exactly as for MDL7
|
||||
ParseSkinLump_3DGS_MDL7(szCursor,&szCursor,
|
||||
pcMat,iType,iWidth,iHeight);
|
||||
ParseSkinLump_3DGS_MDL7(szCursor, &szCursor,
|
||||
pcMat, iType, iWidth, iHeight);
|
||||
|
||||
// now we need to skip any other skins ...
|
||||
for (unsigned int i = 1; i< iNumSkins;++i)
|
||||
{
|
||||
iType = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t);
|
||||
iWidth = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t);
|
||||
iHeight = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t);
|
||||
for (unsigned int i = 1; i < iNumSkins; ++i) {
|
||||
iType = *((uint32_t *)szCursor);
|
||||
szCursor += sizeof(uint32_t);
|
||||
iWidth = *((uint32_t *)szCursor);
|
||||
szCursor += sizeof(uint32_t);
|
||||
iHeight = *((uint32_t *)szCursor);
|
||||
szCursor += sizeof(uint32_t);
|
||||
|
||||
SkipSkinLump_3DGS_MDL7(szCursor,&szCursor,iType,iWidth,iHeight);
|
||||
SkipSkinLump_3DGS_MDL7(szCursor, &szCursor, iType, iWidth, iHeight);
|
||||
SizeCheck(szCursor);
|
||||
}
|
||||
|
||||
// setup the material ...
|
||||
pScene->mNumMaterials = 1;
|
||||
pScene->mMaterials = new aiMaterial*[1];
|
||||
pScene->mMaterials = new aiMaterial *[1];
|
||||
pScene->mMaterials[0] = pcMat;
|
||||
|
||||
*szCursorOut = szCursor;
|
||||
|
@ -500,20 +474,20 @@ void HMPImporter::ReadFirstSkin(unsigned int iNumSkins, const unsigned char* szC
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Generate proepr texture coords
|
||||
void HMPImporter::GenerateTextureCoords(
|
||||
const unsigned int width, const unsigned int height)
|
||||
{
|
||||
ai_assert(NULL != pScene->mMeshes && NULL != pScene->mMeshes[0] &&
|
||||
NULL != pScene->mMeshes[0]->mTextureCoords[0]);
|
||||
const unsigned int width, const unsigned int height) {
|
||||
ai_assert(nullptr != pScene->mMeshes);
|
||||
ai_assert(nullptr != pScene->mMeshes[0]);
|
||||
ai_assert(nullptr != pScene->mMeshes[0]->mTextureCoords[0]);
|
||||
|
||||
aiVector3D* uv = pScene->mMeshes[0]->mTextureCoords[0];
|
||||
aiVector3D *uv = pScene->mMeshes[0]->mTextureCoords[0];
|
||||
|
||||
const float fY = (1.0f / height) + (1.0f / height) / (height-1);
|
||||
const float fX = (1.0f / width) + (1.0f / width) / (width-1);
|
||||
const float fY = (1.0f / height) + (1.0f / height) / (height - 1);
|
||||
const float fX = (1.0f / width) + (1.0f / width) / (width - 1);
|
||||
|
||||
for (unsigned int y = 0; y < height;++y) {
|
||||
for (unsigned int x = 0; x < width;++x,++uv) {
|
||||
uv->y = fY*y;
|
||||
uv->x = fX*x;
|
||||
for (unsigned int y = 0; y < height; ++y) {
|
||||
for (unsigned int x = 0; x < width; ++x, ++uv) {
|
||||
uv->y = fY * y;
|
||||
uv->x = fX * x;
|
||||
uv->z = 0.0f;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ void WritePolygon(std::vector<IfcVector3> &resultpoly, TempMesh &result) {
|
|||
void ProcessBooleanHalfSpaceDifference(const Schema_2x3::IfcHalfSpaceSolid *hs, TempMesh &result,
|
||||
const TempMesh &first_operand,
|
||||
ConversionData & /*conv*/) {
|
||||
ai_assert(hs != NULL);
|
||||
ai_assert(hs != nullptr);
|
||||
|
||||
const Schema_2x3::IfcPlane *const plane = hs->BaseSurface->ToPtr<Schema_2x3::IfcPlane>();
|
||||
if (!plane) {
|
||||
|
@ -221,7 +221,7 @@ void ProcessBooleanHalfSpaceDifference(const Schema_2x3::IfcHalfSpaceSolid *hs,
|
|||
result.mVerts.pop_back();
|
||||
}
|
||||
}
|
||||
IFCImporter::LogDebug("generating CSG geometry by plane clipping (IfcBooleanClippingResult)");
|
||||
IFCImporter::LogVerboseDebug("generating CSG geometry by plane clipping (IfcBooleanClippingResult)");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -366,7 +366,7 @@ bool PointInPoly(const IfcVector3 &p, const std::vector<IfcVector3> &boundary) {
|
|||
void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const Schema_2x3::IfcPolygonalBoundedHalfSpace *hs, TempMesh &result,
|
||||
const TempMesh &first_operand,
|
||||
ConversionData &conv) {
|
||||
ai_assert(hs != NULL);
|
||||
ai_assert(hs != nullptr);
|
||||
|
||||
const Schema_2x3::IfcPlane *const plane = hs->BaseSurface->ToPtr<Schema_2x3::IfcPlane>();
|
||||
if (!plane) {
|
||||
|
@ -658,14 +658,14 @@ void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const Schema_2x3::IfcPoly
|
|||
}
|
||||
}
|
||||
}
|
||||
IFCImporter::LogDebug("generating CSG geometry by plane clipping with polygonal bounding (IfcBooleanClippingResult)");
|
||||
IFCImporter::LogVerboseDebug("generating CSG geometry by plane clipping with polygonal bounding (IfcBooleanClippingResult)");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ProcessBooleanExtrudedAreaSolidDifference(const Schema_2x3::IfcExtrudedAreaSolid *as, TempMesh &result,
|
||||
const TempMesh &first_operand,
|
||||
ConversionData &conv) {
|
||||
ai_assert(as != NULL);
|
||||
ai_assert(as != nullptr);
|
||||
|
||||
// This case is handled by reduction to an instance of the quadrify() algorithm.
|
||||
// Obviously, this won't work for arbitrarily complex cases. In fact, the first
|
||||
|
@ -706,7 +706,7 @@ void ProcessBooleanExtrudedAreaSolidDifference(const Schema_2x3::IfcExtrudedArea
|
|||
vit += pcount;
|
||||
}
|
||||
|
||||
IFCImporter::LogDebug("generating CSG geometry by geometric difference to a solid (IfcExtrudedAreaSolid)");
|
||||
IFCImporter::LogVerboseDebug("generating CSG geometry by geometric difference to a solid (IfcExtrudedAreaSolid)");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -223,7 +223,7 @@ public:
|
|||
}
|
||||
|
||||
if ( (std::string)curveSegment.Transition != "CONTINUOUS" ) {
|
||||
IFCImporter::LogDebug("ignoring transition code on composite curve segment, only continuous transitions are supported");
|
||||
IFCImporter::LogVerboseDebug("ignoring transition code on composite curve segment, only continuous transitions are supported");
|
||||
}
|
||||
|
||||
curves.push_back( CurveEntry(bc,IsTrue(curveSegment.SameSense)) );
|
||||
|
@ -389,7 +389,8 @@ public:
|
|||
|
||||
// --------------------------------------------------
|
||||
void SampleDiscrete(TempMesh& out,IfcFloat a,IfcFloat b) const {
|
||||
ai_assert(InRange(a) && InRange(b));
|
||||
ai_assert(InRange(a));
|
||||
ai_assert(InRange(b));
|
||||
return base->SampleDiscrete(out,TrimParam(a),TrimParam(b));
|
||||
}
|
||||
|
||||
|
@ -446,7 +447,8 @@ public:
|
|||
|
||||
// --------------------------------------------------
|
||||
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
|
||||
ai_assert(InRange(a) && InRange(b));
|
||||
ai_assert(InRange(a));
|
||||
ai_assert(InRange(b));
|
||||
return static_cast<size_t>( std::ceil(b) - std::floor(a) );
|
||||
}
|
||||
|
||||
|
@ -489,7 +491,7 @@ Curve* Curve::Convert(const IFC::Schema_2x3::IfcCurve& curve,ConversionData& con
|
|||
}
|
||||
|
||||
// XXX OffsetCurve2D, OffsetCurve3D not currently supported
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef ASSIMP_BUILD_DEBUG
|
||||
|
|
|
@ -174,7 +174,7 @@ void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t m
|
|||
TempOpening& opening = fake_openings.back();
|
||||
|
||||
opening.extrusionDir = master_normal;
|
||||
opening.solid = NULL;
|
||||
opening.solid = nullptr;
|
||||
|
||||
opening.profileMesh = std::make_shared<TempMesh>();
|
||||
opening.profileMesh->mVerts.reserve(*iit);
|
||||
|
@ -319,7 +319,7 @@ void ProcessRevolvedAreaSolid(const Schema_2x3::IfcRevolvedAreaSolid& solid, Tem
|
|||
ConvertAxisPlacement(trafo, solid.Position);
|
||||
|
||||
result.Transform(trafo);
|
||||
IFCImporter::LogDebug("generate mesh procedurally by radial extrusion (IfcRevolvedAreaSolid)");
|
||||
IFCImporter::LogVerboseDebug("generate mesh procedurally by radial extrusion (IfcRevolvedAreaSolid)");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -457,7 +457,7 @@ void ProcessSweptDiskSolid(const Schema_2x3::IfcSweptDiskSolid &solid, TempMesh&
|
|||
}
|
||||
}
|
||||
|
||||
IFCImporter::LogDebug("generate mesh procedurally by sweeping a disk along a curve (IfcSweptDiskSolid)");
|
||||
IFCImporter::LogVerboseDebug("generate mesh procedurally by sweeping a disk along a curve (IfcSweptDiskSolid)");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -660,7 +660,7 @@ void ProcessExtrudedArea(const Schema_2x3::IfcExtrudedAreaSolid& solid, const Te
|
|||
IFCImporter::LogWarn("failed to resolve all openings, presumably their topology is not supported by Assimp");
|
||||
}
|
||||
|
||||
IFCImporter::LogDebug("generate mesh procedurally by extrusion (IfcExtrudedAreaSolid)");
|
||||
IFCImporter::LogVerboseDebug("generate mesh procedurally by extrusion (IfcExtrudedAreaSolid)");
|
||||
|
||||
// If this is an opening element, store both the extruded mesh and the 2D profile mesh
|
||||
// it was created from. Return an empty mesh to the caller.
|
||||
|
|
|
@ -172,7 +172,7 @@ void IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
if (GetExtension(pFile) == "ifczip") {
|
||||
#ifndef ASSIMP_BUILD_NO_COMPRESSED_IFC
|
||||
unzFile zip = unzOpen(pFile.c_str());
|
||||
if (zip == NULL) {
|
||||
if (zip == nullptr) {
|
||||
ThrowException("Could not open ifczip file for reading, unzip failed");
|
||||
}
|
||||
|
||||
|
@ -373,7 +373,7 @@ void SetUnits(ConversionData &conv) {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SetCoordinateSpace(ConversionData &conv) {
|
||||
const Schema_2x3::IfcRepresentationContext *fav = NULL;
|
||||
const Schema_2x3::IfcRepresentationContext *fav = nullptr;
|
||||
for (const Schema_2x3::IfcRepresentationContext &v : conv.proj.RepresentationContexts) {
|
||||
fav = &v;
|
||||
// Model should be the most suitable type of context, hence ignore the others
|
||||
|
@ -641,14 +641,14 @@ aiNode *ProcessSpatialStructure(aiNode *parent, const Schema_2x3::IfcProduct &el
|
|||
bool skipGeometry = false;
|
||||
if (conv.settings.skipSpaceRepresentations) {
|
||||
if (el.ToPtr<Schema_2x3::IfcSpace>()) {
|
||||
IFCImporter::LogDebug("skipping IfcSpace entity due to importer settings");
|
||||
IFCImporter::LogVerboseDebug("skipping IfcSpace entity due to importer settings");
|
||||
skipGeometry = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (conv.settings.skipAnnotations) {
|
||||
if (el.ToPtr<Schema_2x3::IfcAnnotation>()) {
|
||||
IFCImporter::LogDebug("skipping IfcAnnotation entity due to importer settings");
|
||||
IFCImporter::LogVerboseDebug("skipping IfcAnnotation entity due to importer settings");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -790,7 +790,7 @@ aiNode *ProcessSpatialStructure(aiNode *parent, const Schema_2x3::IfcProduct &el
|
|||
for (const Schema_2x3::IfcObjectDefinition &def : aggr->RelatedObjects) {
|
||||
if (const Schema_2x3::IfcProduct *const prod = def.ToPtr<Schema_2x3::IfcProduct>()) {
|
||||
|
||||
aiNode *const ndnew = ProcessSpatialStructure(nd_aggr.get(), *prod, conv, NULL);
|
||||
aiNode *const ndnew = ProcessSpatialStructure(nd_aggr.get(), *prod, conv, nullptr);
|
||||
if (ndnew) {
|
||||
nd_aggr->mChildren[nd_aggr->mNumChildren++] = ndnew;
|
||||
}
|
||||
|
@ -856,7 +856,7 @@ void ProcessSpatialStructures(ConversionData &conv) {
|
|||
if (!prod) {
|
||||
continue;
|
||||
}
|
||||
IFCImporter::LogDebug("looking at spatial structure `" + (prod->Name ? prod->Name.Get() : "unnamed") + "`" + (prod->ObjectType ? " which is of type " + prod->ObjectType.Get() : ""));
|
||||
IFCImporter::LogVerboseDebug("looking at spatial structure `" + (prod->Name ? prod->Name.Get() : "unnamed") + "`" + (prod->ObjectType ? " which is of type " + prod->ObjectType.Get() : ""));
|
||||
|
||||
// the primary sites are referenced by an IFCRELAGGREGATES element which assigns them to the IFCPRODUCT
|
||||
const STEP::DB::RefMap &refs = conv.db.GetRefs();
|
||||
|
@ -868,9 +868,9 @@ void ProcessSpatialStructures(ConversionData &conv) {
|
|||
// comparing pointer values is not sufficient, we would need to cast them to the same type first
|
||||
// as there is multiple inheritance in the game.
|
||||
if (def.GetID() == prod->GetID()) {
|
||||
IFCImporter::LogDebug("selecting this spatial structure as root structure");
|
||||
IFCImporter::LogVerboseDebug("selecting this spatial structure as root structure");
|
||||
// got it, this is one primary site.
|
||||
nodes.push_back(ProcessSpatialStructure(NULL, *prod, conv, NULL));
|
||||
nodes.push_back(ProcessSpatialStructure(nullptr, *prod, conv, nullptr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -887,7 +887,7 @@ void ProcessSpatialStructures(ConversionData &conv) {
|
|||
continue;
|
||||
}
|
||||
|
||||
nodes.push_back(ProcessSpatialStructure(NULL, *prod, conv, NULL));
|
||||
nodes.push_back(ProcessSpatialStructure(nullptr, *prod, conv, nullptr));
|
||||
}
|
||||
|
||||
nb_nodes = nodes.size();
|
||||
|
@ -897,7 +897,7 @@ void ProcessSpatialStructures(ConversionData &conv) {
|
|||
conv.out->mRootNode = nodes[0];
|
||||
} else if (nb_nodes > 1) {
|
||||
conv.out->mRootNode = new aiNode("Root");
|
||||
conv.out->mRootNode->mParent = NULL;
|
||||
conv.out->mRootNode->mParent = nullptr;
|
||||
conv.out->mRootNode->mNumChildren = static_cast<unsigned int>(nb_nodes);
|
||||
conv.out->mRootNode->mChildren = new aiNode *[conv.out->mRootNode->mNumChildren];
|
||||
|
||||
|
|
|
@ -1359,7 +1359,7 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
|||
break;
|
||||
}
|
||||
else {
|
||||
IFCImporter::LogDebug("merging overlapping openings");
|
||||
IFCImporter::LogVerboseDebug("merging overlapping openings");
|
||||
ExtractVerticesFromClipper(poly[0].outer, temp_contour, false);
|
||||
|
||||
// Generate the union of the bounding boxes
|
||||
|
|
|
@ -54,333 +54,333 @@ namespace {
|
|||
typedef EXPRESS::ConversionSchema::SchemaEntry SchemaEntry;
|
||||
|
||||
static const SchemaEntry schema_raw_2x3[] = {
|
||||
SchemaEntry("ifcstairtypeenum",NULL )
|
||||
, SchemaEntry("ifcspacetypeenum",NULL )
|
||||
, SchemaEntry("ifcwalltypeenum",NULL )
|
||||
, SchemaEntry("ifcmonthinyearnumber",NULL )
|
||||
, SchemaEntry("ifcheatfluxdensitymeasure",NULL )
|
||||
, SchemaEntry("ifckinematicviscositymeasure",NULL )
|
||||
, SchemaEntry("ifcsequenceenum",NULL )
|
||||
, SchemaEntry("ifcairtoairheatrecoverytypeenum",NULL )
|
||||
, SchemaEntry("ifcactorselect",NULL )
|
||||
, SchemaEntry("ifctransformertypeenum",NULL )
|
||||
, SchemaEntry("ifcunitaryequipmenttypeenum",NULL )
|
||||
, SchemaEntry("ifcelectricflowstoragedevicetypeenum",NULL )
|
||||
, SchemaEntry("ifcenergysequenceenum",NULL )
|
||||
, SchemaEntry("ifcworkcontroltypeenum",NULL )
|
||||
, SchemaEntry("ifccurvaturemeasure",NULL )
|
||||
, SchemaEntry("ifcparametervalue",NULL )
|
||||
, SchemaEntry("ifcappliedvalueselect",NULL )
|
||||
, SchemaEntry("ifcwarpingconstantmeasure",NULL )
|
||||
, SchemaEntry("ifcarithmeticoperatorenum",NULL )
|
||||
, SchemaEntry("ifclinearforcemeasure",NULL )
|
||||
, SchemaEntry("ifcwindowpanelpositionenum",NULL )
|
||||
, SchemaEntry("ifcflowmetertypeenum",NULL )
|
||||
, SchemaEntry("ifcrampflighttypeenum",NULL )
|
||||
, SchemaEntry("ifcspecularhighlightselect",NULL )
|
||||
, SchemaEntry("ifcactiontypeenum",NULL )
|
||||
, SchemaEntry("ifcgeometricprojectionenum",NULL )
|
||||
, SchemaEntry("ifctimeseriesdatatypeenum",NULL )
|
||||
, SchemaEntry("ifcmagneticfluxmeasure",NULL )
|
||||
, SchemaEntry("ifcobjecttypeenum",NULL )
|
||||
, SchemaEntry("ifcdataoriginenum",NULL )
|
||||
, SchemaEntry("ifcmassdensitymeasure",NULL )
|
||||
, SchemaEntry("ifclightfixturetypeenum",NULL )
|
||||
, SchemaEntry("ifcservicelifetypeenum",NULL )
|
||||
, SchemaEntry("ifcelectricvoltagemeasure",NULL )
|
||||
, SchemaEntry("ifcheatingvaluemeasure",NULL )
|
||||
, SchemaEntry("ifcpresentabletext",NULL )
|
||||
, SchemaEntry("ifcaheadorbehind",NULL )
|
||||
, SchemaEntry("ifcsimplevalue",NULL )
|
||||
, SchemaEntry("ifcsensortypeenum",NULL )
|
||||
, SchemaEntry("ifcderivedunitenum",NULL )
|
||||
, SchemaEntry("ifcsizeselect",NULL )
|
||||
, SchemaEntry("ifctransportelementtypeenum",NULL )
|
||||
, SchemaEntry("ifcinventorytypeenum",NULL )
|
||||
, SchemaEntry("ifctextdecoration",NULL )
|
||||
, SchemaEntry("ifcdirectionsenseenum",NULL )
|
||||
, SchemaEntry("ifcductfittingtypeenum",NULL )
|
||||
, SchemaEntry("ifcdocumentstatusenum",NULL )
|
||||
, SchemaEntry("ifcslabtypeenum",NULL )
|
||||
, SchemaEntry("ifcdoorstyleconstructionenum",NULL )
|
||||
, SchemaEntry("ifcvolumemeasure",NULL )
|
||||
, SchemaEntry("ifcinductancemeasure",NULL )
|
||||
, SchemaEntry("ifccurtainwalltypeenum",NULL )
|
||||
, SchemaEntry("ifcsiunitname",NULL )
|
||||
, SchemaEntry("ifcspecularexponent",NULL )
|
||||
, SchemaEntry("ifcsoundpressuremeasure",NULL )
|
||||
, SchemaEntry("ifcanalysistheorytypeenum",NULL )
|
||||
, SchemaEntry("ifcgasterminaltypeenum",NULL )
|
||||
, SchemaEntry("ifcyearnumber",NULL )
|
||||
, SchemaEntry("ifcmodulusofelasticitymeasure",NULL )
|
||||
, SchemaEntry("ifcchangeactionenum",NULL )
|
||||
, SchemaEntry("ifcdampertypeenum",NULL )
|
||||
, SchemaEntry("ifcevaporatortypeenum",NULL )
|
||||
, SchemaEntry("ifcionconcentrationmeasure",NULL )
|
||||
, SchemaEntry("ifcductsegmenttypeenum",NULL )
|
||||
, SchemaEntry("ifcprotectivedevicetypeenum",NULL )
|
||||
, SchemaEntry("ifcabsorbeddosemeasure",NULL )
|
||||
, SchemaEntry("ifcmassperlengthmeasure",NULL )
|
||||
, SchemaEntry("ifctextfontname",NULL )
|
||||
, SchemaEntry("ifcorientationselect",NULL )
|
||||
, SchemaEntry("ifcilluminancemeasure",NULL )
|
||||
, SchemaEntry("ifcfiresuppressionterminaltypeenum",NULL )
|
||||
, SchemaEntry("ifcfontstyle",NULL )
|
||||
, SchemaEntry("ifcmomentofinertiameasure",NULL )
|
||||
, SchemaEntry("ifcmodulusofsubgradereactionmeasure",NULL )
|
||||
, SchemaEntry("ifccomplexnumber",NULL )
|
||||
, SchemaEntry("ifchumidifiertypeenum",NULL )
|
||||
, SchemaEntry("ifcpresentationstyleselect",NULL )
|
||||
, SchemaEntry("ifcthermaltransmittancemeasure",NULL )
|
||||
, SchemaEntry("ifcribplatedirectionenum",NULL )
|
||||
, SchemaEntry("ifcclassificationnotationselect",NULL )
|
||||
, SchemaEntry("ifcminuteinhour",NULL )
|
||||
, SchemaEntry("ifcinternalorexternalenum",NULL )
|
||||
, SchemaEntry("ifcrotationalfrequencymeasure",NULL )
|
||||
, SchemaEntry("ifcsanitaryterminaltypeenum",NULL )
|
||||
, SchemaEntry("ifcsymbolstyleselect",NULL )
|
||||
, SchemaEntry("ifcelementcompositionenum",NULL )
|
||||
, SchemaEntry("ifctextpath",NULL )
|
||||
, SchemaEntry("ifcpowermeasure",NULL )
|
||||
, SchemaEntry("ifcsurfacestyleelementselect",NULL )
|
||||
, SchemaEntry("ifcresourceconsumptionenum",NULL )
|
||||
, SchemaEntry("ifcelectriccapacitancemeasure",NULL )
|
||||
, SchemaEntry("ifclayersetdirectionenum",NULL )
|
||||
, SchemaEntry("ifcrailingtypeenum",NULL )
|
||||
, SchemaEntry("ifcobjectiveenum",NULL )
|
||||
, SchemaEntry("ifcdocumentselect",NULL )
|
||||
, SchemaEntry("ifcmodulusoflinearsubgradereactionmeasure",NULL )
|
||||
, SchemaEntry("ifcthermaladmittancemeasure",NULL )
|
||||
, SchemaEntry("ifctransitioncode",NULL )
|
||||
, SchemaEntry("ifcconnectiontypeenum",NULL )
|
||||
, SchemaEntry("ifcmonetarymeasure",NULL )
|
||||
, SchemaEntry("ifcstackterminaltypeenum",NULL )
|
||||
, SchemaEntry("ifccolour",NULL )
|
||||
, SchemaEntry("ifctext",NULL )
|
||||
, SchemaEntry("ifccontextdependentmeasure",NULL )
|
||||
, SchemaEntry("ifcthermalconductivitymeasure",NULL )
|
||||
, SchemaEntry("ifcprojectedortruelengthenum",NULL )
|
||||
, SchemaEntry("ifcpressuremeasure",NULL )
|
||||
, SchemaEntry("ifcmoisturediffusivitymeasure",NULL )
|
||||
, SchemaEntry("ifcbooleanoperator",NULL )
|
||||
, SchemaEntry("ifcpropertysourceenum",NULL )
|
||||
, SchemaEntry("ifctimestamp",NULL )
|
||||
, SchemaEntry("ifcmaterialselect",NULL )
|
||||
, SchemaEntry("ifcgloballyuniqueid",NULL )
|
||||
, SchemaEntry("ifcreflectancemethodenum",NULL )
|
||||
, SchemaEntry("ifcvaporpermeabilitymeasure",NULL )
|
||||
, SchemaEntry("ifctimeseriesscheduletypeenum",NULL )
|
||||
, SchemaEntry("ifclinearmomentmeasure",NULL )
|
||||
, SchemaEntry("ifcgeometricsetselect",NULL )
|
||||
, SchemaEntry("ifcsectionmodulusmeasure",NULL )
|
||||
, SchemaEntry("ifcbsplinecurveform",NULL )
|
||||
, SchemaEntry("ifcdimensionextentusage",NULL )
|
||||
, SchemaEntry("ifcthermalexpansioncoefficientmeasure",NULL )
|
||||
, SchemaEntry("ifchourinday",NULL )
|
||||
, SchemaEntry("ifclinearvelocitymeasure",NULL )
|
||||
, SchemaEntry("ifctorquemeasure",NULL )
|
||||
, SchemaEntry("ifctemperaturegradientmeasure",NULL )
|
||||
, SchemaEntry("ifcfillstyleselect",NULL )
|
||||
, SchemaEntry("ifcelectricchargemeasure",NULL )
|
||||
, SchemaEntry("ifcheatexchangertypeenum",NULL )
|
||||
, SchemaEntry("ifcelectriccurrentenum",NULL )
|
||||
, SchemaEntry("ifcdaylightsavinghour",NULL )
|
||||
, SchemaEntry("ifcshell",NULL )
|
||||
, SchemaEntry("ifcdoseequivalentmeasure",NULL )
|
||||
, SchemaEntry("ifcprojectordertypeenum",NULL )
|
||||
, SchemaEntry("ifcderivedmeasurevalue",NULL )
|
||||
, SchemaEntry("ifclightdistributioncurveenum",NULL )
|
||||
, SchemaEntry("ifcwarpingmomentmeasure",NULL )
|
||||
, SchemaEntry("ifcmembertypeenum",NULL )
|
||||
, SchemaEntry("ifcsoundpowermeasure",NULL )
|
||||
, SchemaEntry("ifctextalignment",NULL )
|
||||
, SchemaEntry("ifccurveoredgecurve",NULL )
|
||||
, SchemaEntry("ifcmassflowratemeasure",NULL )
|
||||
, SchemaEntry("ifcisothermalmoisturecapacitymeasure",NULL )
|
||||
, SchemaEntry("ifccsgselect",NULL )
|
||||
, SchemaEntry("ifccoolingtowertypeenum",NULL )
|
||||
, SchemaEntry("ifcmassmeasure",NULL )
|
||||
, SchemaEntry("ifcpileconstructionenum",NULL )
|
||||
, SchemaEntry("ifcdoorstyleoperationenum",NULL )
|
||||
, SchemaEntry("ifcflowdirectionenum",NULL )
|
||||
, SchemaEntry("ifcthermalloadsourceenum",NULL )
|
||||
, SchemaEntry("ifclengthmeasure",NULL )
|
||||
, SchemaEntry("ifcconstraintenum",NULL )
|
||||
, SchemaEntry("ifcaxis2placement",NULL )
|
||||
, SchemaEntry("ifcloadgrouptypeenum",NULL )
|
||||
, SchemaEntry("ifcvalue",NULL )
|
||||
, SchemaEntry("ifcreinforcingbarsurfaceenum",NULL )
|
||||
, SchemaEntry("ifcprojectorderrecordtypeenum",NULL )
|
||||
, SchemaEntry("ifcdatetimeselect",NULL )
|
||||
, SchemaEntry("ifcstructuralsurfacetypeenum",NULL )
|
||||
, SchemaEntry("ifcpermeablecoveringoperationenum",NULL )
|
||||
, SchemaEntry("ifcfontweight",NULL )
|
||||
, SchemaEntry("ifcphmeasure",NULL )
|
||||
, SchemaEntry("ifcdescriptivemeasure",NULL )
|
||||
, SchemaEntry("ifccurvestylefontselect",NULL )
|
||||
, SchemaEntry("ifcunit",NULL )
|
||||
, SchemaEntry("ifchatchlinedistanceselect",NULL )
|
||||
, SchemaEntry("ifctextstyleselect",NULL )
|
||||
, SchemaEntry("ifcmetricvalueselect",NULL )
|
||||
, SchemaEntry("ifcvectorordirection",NULL )
|
||||
, SchemaEntry("ifcassemblyplaceenum",NULL )
|
||||
, SchemaEntry("ifcairterminaltypeenum",NULL )
|
||||
, SchemaEntry("ifccoveringtypeenum",NULL )
|
||||
, SchemaEntry("ifcplanarforcemeasure",NULL )
|
||||
, SchemaEntry("ifcvalvetypeenum",NULL )
|
||||
, SchemaEntry("ifcalarmtypeenum",NULL )
|
||||
, SchemaEntry("ifcdynamicviscositymeasure",NULL )
|
||||
, SchemaEntry("ifccurrencyenum",NULL )
|
||||
, SchemaEntry("ifcmodulusofrotationalsubgradereactionmeasure",NULL )
|
||||
, SchemaEntry("ifccablecarrierfittingtypeenum",NULL )
|
||||
, SchemaEntry("ifcboolean",NULL )
|
||||
, SchemaEntry("ifcactionsourcetypeenum",NULL )
|
||||
, SchemaEntry("ifcstructuralactivityassignmentselect",NULL )
|
||||
, SchemaEntry("ifcdistributionchamberelementtypeenum",NULL )
|
||||
, SchemaEntry("ifcevaporativecoolertypeenum",NULL )
|
||||
, SchemaEntry("ifcmagneticfluxdensitymeasure",NULL )
|
||||
, SchemaEntry("ifclightdistributiondatasourceselect",NULL )
|
||||
, SchemaEntry("ifctubebundletypeenum",NULL )
|
||||
, SchemaEntry("ifcaccelerationmeasure",NULL )
|
||||
, SchemaEntry("ifcboilertypeenum",NULL )
|
||||
, SchemaEntry("ifcramptypeenum",NULL )
|
||||
, SchemaEntry("ifcluminousintensitydistributionmeasure",NULL )
|
||||
, SchemaEntry("ifctrimmingpreference",NULL )
|
||||
, SchemaEntry("ifcspecificheatcapacitymeasure",NULL )
|
||||
, SchemaEntry("ifcamountofsubstancemeasure",NULL )
|
||||
, SchemaEntry("ifcroleenum",NULL )
|
||||
, SchemaEntry("ifcdocumentconfidentialityenum",NULL )
|
||||
, SchemaEntry("ifcfrequencymeasure",NULL )
|
||||
, SchemaEntry("ifcsectiontypeenum",NULL )
|
||||
, SchemaEntry("ifcelementassemblytypeenum",NULL )
|
||||
, SchemaEntry("ifcfootingtypeenum",NULL )
|
||||
, SchemaEntry("ifclayereditem",NULL )
|
||||
, SchemaEntry("ifccablesegmenttypeenum",NULL )
|
||||
, SchemaEntry("ifcdefinedsymbolselect",NULL )
|
||||
, SchemaEntry("ifcbuildingelementproxytypeenum",NULL )
|
||||
, SchemaEntry("ifcelectricgeneratortypeenum",NULL )
|
||||
, SchemaEntry("ifcrotationalstiffnessmeasure",NULL )
|
||||
, SchemaEntry("ifcspaceheatertypeenum",NULL )
|
||||
, SchemaEntry("ifcareameasure",NULL )
|
||||
, SchemaEntry("ifclabel",NULL )
|
||||
, SchemaEntry("ifccostscheduletypeenum",NULL )
|
||||
, SchemaEntry("ifcswitchingdevicetypeenum",NULL )
|
||||
, SchemaEntry("ifcelectrictimecontroltypeenum",NULL )
|
||||
, SchemaEntry("ifcfiltertypeenum",NULL )
|
||||
, SchemaEntry("ifcpositivelengthmeasure",NULL )
|
||||
, SchemaEntry("ifcnullstyle",NULL )
|
||||
, SchemaEntry("ifcconditioncriterionselect",NULL )
|
||||
, SchemaEntry("ifcshearmodulusmeasure",NULL )
|
||||
, SchemaEntry("ifcnormalisedratiomeasure",NULL )
|
||||
, SchemaEntry("ifcdoorpaneloperationenum",NULL )
|
||||
, SchemaEntry("ifcpointorvertexpoint",NULL )
|
||||
, SchemaEntry("ifcrooftypeenum",NULL )
|
||||
, SchemaEntry("ifccountmeasure",NULL )
|
||||
, SchemaEntry("ifcelectricconductancemeasure",NULL )
|
||||
, SchemaEntry("ifcproceduretypeenum",NULL )
|
||||
, SchemaEntry("ifcflowinstrumenttypeenum",NULL )
|
||||
, SchemaEntry("ifcelectricmotortypeenum",NULL )
|
||||
, SchemaEntry("ifcsurfaceside",NULL )
|
||||
, SchemaEntry("ifcstructuralcurvetypeenum",NULL )
|
||||
, SchemaEntry("ifccondensertypeenum",NULL )
|
||||
, SchemaEntry("ifclinearstiffnessmeasure",NULL )
|
||||
, SchemaEntry("ifcunitenum",NULL )
|
||||
, SchemaEntry("ifcoccupanttypeenum",NULL )
|
||||
, SchemaEntry("ifcthermalloadtypeenum",NULL )
|
||||
, SchemaEntry("ifcreinforcingbarroleenum",NULL )
|
||||
, SchemaEntry("ifcbenchmarkenum",NULL )
|
||||
, SchemaEntry("ifcpositiveplaneanglemeasure",NULL )
|
||||
, SchemaEntry("ifctexttransformation",NULL )
|
||||
, SchemaEntry("ifcdraughtingcalloutelement",NULL )
|
||||
, SchemaEntry("ifcratiomeasure",NULL )
|
||||
, SchemaEntry("ifcsolidanglemeasure",NULL )
|
||||
, SchemaEntry("ifcpipesegmenttypeenum",NULL )
|
||||
, SchemaEntry("ifccablecarriersegmenttypeenum",NULL )
|
||||
, SchemaEntry("ifccolourorfactor",NULL )
|
||||
, SchemaEntry("ifcidentifier",NULL )
|
||||
, SchemaEntry("ifctendontypeenum",NULL )
|
||||
, SchemaEntry("ifccontrollertypeenum",NULL )
|
||||
, SchemaEntry("ifcradioactivitymeasure",NULL )
|
||||
, SchemaEntry("ifctimemeasure",NULL )
|
||||
, SchemaEntry("ifcpumptypeenum",NULL )
|
||||
, SchemaEntry("ifcelectricheatertypeenum",NULL )
|
||||
, SchemaEntry("ifcbeamtypeenum",NULL )
|
||||
, SchemaEntry("ifcstateenum",NULL )
|
||||
, SchemaEntry("ifcsiprefix",NULL )
|
||||
, SchemaEntry("ifcnumericmeasure",NULL )
|
||||
, SchemaEntry("ifcoutlettypeenum",NULL )
|
||||
, SchemaEntry("ifccompoundplaneanglemeasure",NULL )
|
||||
, SchemaEntry("ifcservicelifefactortypeenum",NULL )
|
||||
, SchemaEntry("ifclogicaloperatorenum",NULL )
|
||||
, SchemaEntry("ifcbooleanoperand",NULL )
|
||||
, SchemaEntry("ifcobjectreferenceselect",NULL )
|
||||
, SchemaEntry("ifccooledbeamtypeenum",NULL )
|
||||
, SchemaEntry("ifcductsilencertypeenum",NULL )
|
||||
, SchemaEntry("ifcsectionalareaintegralmeasure",NULL )
|
||||
, SchemaEntry("ifcfontvariant",NULL )
|
||||
, SchemaEntry("ifcvolumetricflowratemeasure",NULL )
|
||||
, SchemaEntry("ifcplatetypeenum",NULL )
|
||||
, SchemaEntry("ifcenvironmentalimpactcategoryenum",NULL )
|
||||
, SchemaEntry("ifcvibrationisolatortypeenum",NULL )
|
||||
, SchemaEntry("ifcthermodynamictemperaturemeasure",NULL )
|
||||
, SchemaEntry("ifcrotationalmassmeasure",NULL )
|
||||
, SchemaEntry("ifcsecondinminute",NULL )
|
||||
, SchemaEntry("ifcdayinmonthnumber",NULL )
|
||||
, SchemaEntry("ifcdimensioncount",NULL )
|
||||
, SchemaEntry("ifcwindowstyleoperationenum",NULL )
|
||||
, SchemaEntry("ifcthermalresistancemeasure",NULL )
|
||||
, SchemaEntry("ifcmeasurevalue",NULL )
|
||||
, SchemaEntry("ifcwindowpaneloperationenum",NULL )
|
||||
, SchemaEntry("ifcchillertypeenum",NULL )
|
||||
, SchemaEntry("ifcpositiveratiomeasure",NULL )
|
||||
, SchemaEntry("ifcinteger",NULL )
|
||||
, SchemaEntry("ifclogical",NULL )
|
||||
, SchemaEntry("ifcjunctionboxtypeenum",NULL )
|
||||
, SchemaEntry("ifcaddresstypeenum",NULL )
|
||||
, SchemaEntry("ifcwasteterminaltypeenum",NULL )
|
||||
, SchemaEntry("ifctrimmingselect",NULL )
|
||||
, SchemaEntry("ifclightemissionsourceenum",NULL )
|
||||
, SchemaEntry("ifcsoundscaleenum",NULL )
|
||||
, SchemaEntry("ifcluminousfluxmeasure",NULL )
|
||||
, SchemaEntry("ifcelectricresistancemeasure",NULL )
|
||||
, SchemaEntry("ifcintegercountratemeasure",NULL )
|
||||
, SchemaEntry("ifcphysicalorvirtualenum",NULL )
|
||||
, SchemaEntry("ifcmolecularweightmeasure",NULL )
|
||||
, SchemaEntry("ifcprofiletypeenum",NULL )
|
||||
, SchemaEntry("ifcboxalignment",NULL )
|
||||
, SchemaEntry("ifcglobalorlocalenum",NULL )
|
||||
, SchemaEntry("ifcspecularroughness",NULL )
|
||||
, SchemaEntry("ifclamptypeenum",NULL )
|
||||
, SchemaEntry("ifcpiletypeenum",NULL )
|
||||
, SchemaEntry("ifcelectriccurrentmeasure",NULL )
|
||||
, SchemaEntry("ifcfantypeenum",NULL )
|
||||
, SchemaEntry("ifcsurfaceorfacesurface",NULL )
|
||||
, SchemaEntry("ifcpipefittingtypeenum",NULL )
|
||||
, SchemaEntry("ifctanktypeenum",NULL )
|
||||
, SchemaEntry("ifccurvefontorscaledcurvefontselect",NULL )
|
||||
, SchemaEntry("ifcwindowstyleconstructionenum",NULL )
|
||||
, SchemaEntry("ifcairterminalboxtypeenum",NULL )
|
||||
, SchemaEntry("ifcstairflighttypeenum",NULL )
|
||||
, SchemaEntry("ifcluminousintensitymeasure",NULL )
|
||||
, SchemaEntry("ifcmotorconnectiontypeenum",NULL )
|
||||
, SchemaEntry("ifcplaneanglemeasure",NULL )
|
||||
, SchemaEntry("ifcactuatortypeenum",NULL )
|
||||
, SchemaEntry("ifccolumntypeenum",NULL )
|
||||
, SchemaEntry("ifctextfontselect",NULL )
|
||||
, SchemaEntry("ifcdoorpanelpositionenum",NULL )
|
||||
, SchemaEntry("ifccoiltypeenum",NULL )
|
||||
, SchemaEntry("ifcangularvelocitymeasure",NULL )
|
||||
, SchemaEntry("ifcanalysismodeltypeenum",NULL )
|
||||
, SchemaEntry("ifclibraryselect",NULL )
|
||||
, SchemaEntry("ifcforcemeasure",NULL )
|
||||
, SchemaEntry("ifcfillareastyletileshapeselect",NULL )
|
||||
, SchemaEntry("ifcelectricappliancetypeenum",NULL )
|
||||
, SchemaEntry("ifcsurfacetextureenum",NULL )
|
||||
, SchemaEntry("ifccharacterstyleselect",NULL )
|
||||
, SchemaEntry("ifcenergymeasure",NULL )
|
||||
, SchemaEntry("ifcreal",NULL )
|
||||
, SchemaEntry("ifccompressortypeenum",NULL )
|
||||
, SchemaEntry("ifcelectricdistributionpointfunctionenum",NULL )
|
||||
SchemaEntry("ifcstairtypeenum",nullptr )
|
||||
, SchemaEntry("ifcspacetypeenum",nullptr )
|
||||
, SchemaEntry("ifcwalltypeenum",nullptr )
|
||||
, SchemaEntry("ifcmonthinyearnumber",nullptr )
|
||||
, SchemaEntry("ifcheatfluxdensitymeasure",nullptr )
|
||||
, SchemaEntry("ifckinematicviscositymeasure",nullptr )
|
||||
, SchemaEntry("ifcsequenceenum",nullptr )
|
||||
, SchemaEntry("ifcairtoairheatrecoverytypeenum",nullptr )
|
||||
, SchemaEntry("ifcactorselect",nullptr )
|
||||
, SchemaEntry("ifctransformertypeenum",nullptr )
|
||||
, SchemaEntry("ifcunitaryequipmenttypeenum",nullptr )
|
||||
, SchemaEntry("ifcelectricflowstoragedevicetypeenum",nullptr )
|
||||
, SchemaEntry("ifcenergysequenceenum",nullptr )
|
||||
, SchemaEntry("ifcworkcontroltypeenum",nullptr )
|
||||
, SchemaEntry("ifccurvaturemeasure",nullptr )
|
||||
, SchemaEntry("ifcparametervalue",nullptr )
|
||||
, SchemaEntry("ifcappliedvalueselect",nullptr )
|
||||
, SchemaEntry("ifcwarpingconstantmeasure",nullptr )
|
||||
, SchemaEntry("ifcarithmeticoperatorenum",nullptr )
|
||||
, SchemaEntry("ifclinearforcemeasure",nullptr )
|
||||
, SchemaEntry("ifcwindowpanelpositionenum",nullptr )
|
||||
, SchemaEntry("ifcflowmetertypeenum",nullptr )
|
||||
, SchemaEntry("ifcrampflighttypeenum",nullptr )
|
||||
, SchemaEntry("ifcspecularhighlightselect",nullptr )
|
||||
, SchemaEntry("ifcactiontypeenum",nullptr )
|
||||
, SchemaEntry("ifcgeometricprojectionenum",nullptr )
|
||||
, SchemaEntry("ifctimeseriesdatatypeenum",nullptr )
|
||||
, SchemaEntry("ifcmagneticfluxmeasure",nullptr )
|
||||
, SchemaEntry("ifcobjecttypeenum",nullptr )
|
||||
, SchemaEntry("ifcdataoriginenum",nullptr )
|
||||
, SchemaEntry("ifcmassdensitymeasure",nullptr )
|
||||
, SchemaEntry("ifclightfixturetypeenum",nullptr )
|
||||
, SchemaEntry("ifcservicelifetypeenum",nullptr )
|
||||
, SchemaEntry("ifcelectricvoltagemeasure",nullptr )
|
||||
, SchemaEntry("ifcheatingvaluemeasure",nullptr )
|
||||
, SchemaEntry("ifcpresentabletext",nullptr )
|
||||
, SchemaEntry("ifcaheadorbehind",nullptr )
|
||||
, SchemaEntry("ifcsimplevalue",nullptr )
|
||||
, SchemaEntry("ifcsensortypeenum",nullptr )
|
||||
, SchemaEntry("ifcderivedunitenum",nullptr )
|
||||
, SchemaEntry("ifcsizeselect",nullptr )
|
||||
, SchemaEntry("ifctransportelementtypeenum",nullptr )
|
||||
, SchemaEntry("ifcinventorytypeenum",nullptr )
|
||||
, SchemaEntry("ifctextdecoration",nullptr )
|
||||
, SchemaEntry("ifcdirectionsenseenum",nullptr )
|
||||
, SchemaEntry("ifcductfittingtypeenum",nullptr )
|
||||
, SchemaEntry("ifcdocumentstatusenum",nullptr )
|
||||
, SchemaEntry("ifcslabtypeenum",nullptr )
|
||||
, SchemaEntry("ifcdoorstyleconstructionenum",nullptr )
|
||||
, SchemaEntry("ifcvolumemeasure",nullptr )
|
||||
, SchemaEntry("ifcinductancemeasure",nullptr )
|
||||
, SchemaEntry("ifccurtainwalltypeenum",nullptr )
|
||||
, SchemaEntry("ifcsiunitname",nullptr )
|
||||
, SchemaEntry("ifcspecularexponent",nullptr )
|
||||
, SchemaEntry("ifcsoundpressuremeasure",nullptr )
|
||||
, SchemaEntry("ifcanalysistheorytypeenum",nullptr )
|
||||
, SchemaEntry("ifcgasterminaltypeenum",nullptr )
|
||||
, SchemaEntry("ifcyearnumber",nullptr )
|
||||
, SchemaEntry("ifcmodulusofelasticitymeasure",nullptr )
|
||||
, SchemaEntry("ifcchangeactionenum",nullptr )
|
||||
, SchemaEntry("ifcdampertypeenum",nullptr )
|
||||
, SchemaEntry("ifcevaporatortypeenum",nullptr )
|
||||
, SchemaEntry("ifcionconcentrationmeasure",nullptr )
|
||||
, SchemaEntry("ifcductsegmenttypeenum",nullptr )
|
||||
, SchemaEntry("ifcprotectivedevicetypeenum",nullptr )
|
||||
, SchemaEntry("ifcabsorbeddosemeasure",nullptr )
|
||||
, SchemaEntry("ifcmassperlengthmeasure",nullptr )
|
||||
, SchemaEntry("ifctextfontname",nullptr )
|
||||
, SchemaEntry("ifcorientationselect",nullptr )
|
||||
, SchemaEntry("ifcilluminancemeasure",nullptr )
|
||||
, SchemaEntry("ifcfiresuppressionterminaltypeenum",nullptr )
|
||||
, SchemaEntry("ifcfontstyle",nullptr )
|
||||
, SchemaEntry("ifcmomentofinertiameasure",nullptr )
|
||||
, SchemaEntry("ifcmodulusofsubgradereactionmeasure",nullptr )
|
||||
, SchemaEntry("ifccomplexnumber",nullptr )
|
||||
, SchemaEntry("ifchumidifiertypeenum",nullptr )
|
||||
, SchemaEntry("ifcpresentationstyleselect",nullptr )
|
||||
, SchemaEntry("ifcthermaltransmittancemeasure",nullptr )
|
||||
, SchemaEntry("ifcribplatedirectionenum",nullptr )
|
||||
, SchemaEntry("ifcclassificationnotationselect",nullptr )
|
||||
, SchemaEntry("ifcminuteinhour",nullptr )
|
||||
, SchemaEntry("ifcinternalorexternalenum",nullptr )
|
||||
, SchemaEntry("ifcrotationalfrequencymeasure",nullptr )
|
||||
, SchemaEntry("ifcsanitaryterminaltypeenum",nullptr )
|
||||
, SchemaEntry("ifcsymbolstyleselect",nullptr )
|
||||
, SchemaEntry("ifcelementcompositionenum",nullptr )
|
||||
, SchemaEntry("ifctextpath",nullptr )
|
||||
, SchemaEntry("ifcpowermeasure",nullptr )
|
||||
, SchemaEntry("ifcsurfacestyleelementselect",nullptr )
|
||||
, SchemaEntry("ifcresourceconsumptionenum",nullptr )
|
||||
, SchemaEntry("ifcelectriccapacitancemeasure",nullptr )
|
||||
, SchemaEntry("ifclayersetdirectionenum",nullptr )
|
||||
, SchemaEntry("ifcrailingtypeenum",nullptr )
|
||||
, SchemaEntry("ifcobjectiveenum",nullptr )
|
||||
, SchemaEntry("ifcdocumentselect",nullptr )
|
||||
, SchemaEntry("ifcmodulusoflinearsubgradereactionmeasure",nullptr )
|
||||
, SchemaEntry("ifcthermaladmittancemeasure",nullptr )
|
||||
, SchemaEntry("ifctransitioncode",nullptr )
|
||||
, SchemaEntry("ifcconnectiontypeenum",nullptr )
|
||||
, SchemaEntry("ifcmonetarymeasure",nullptr )
|
||||
, SchemaEntry("ifcstackterminaltypeenum",nullptr )
|
||||
, SchemaEntry("ifccolour",nullptr )
|
||||
, SchemaEntry("ifctext",nullptr )
|
||||
, SchemaEntry("ifccontextdependentmeasure",nullptr )
|
||||
, SchemaEntry("ifcthermalconductivitymeasure",nullptr )
|
||||
, SchemaEntry("ifcprojectedortruelengthenum",nullptr )
|
||||
, SchemaEntry("ifcpressuremeasure",nullptr )
|
||||
, SchemaEntry("ifcmoisturediffusivitymeasure",nullptr )
|
||||
, SchemaEntry("ifcbooleanoperator",nullptr )
|
||||
, SchemaEntry("ifcpropertysourceenum",nullptr )
|
||||
, SchemaEntry("ifctimestamp",nullptr )
|
||||
, SchemaEntry("ifcmaterialselect",nullptr )
|
||||
, SchemaEntry("ifcgloballyuniqueid",nullptr )
|
||||
, SchemaEntry("ifcreflectancemethodenum",nullptr )
|
||||
, SchemaEntry("ifcvaporpermeabilitymeasure",nullptr )
|
||||
, SchemaEntry("ifctimeseriesscheduletypeenum",nullptr )
|
||||
, SchemaEntry("ifclinearmomentmeasure",nullptr )
|
||||
, SchemaEntry("ifcgeometricsetselect",nullptr )
|
||||
, SchemaEntry("ifcsectionmodulusmeasure",nullptr )
|
||||
, SchemaEntry("ifcbsplinecurveform",nullptr )
|
||||
, SchemaEntry("ifcdimensionextentusage",nullptr )
|
||||
, SchemaEntry("ifcthermalexpansioncoefficientmeasure",nullptr )
|
||||
, SchemaEntry("ifchourinday",nullptr )
|
||||
, SchemaEntry("ifclinearvelocitymeasure",nullptr )
|
||||
, SchemaEntry("ifctorquemeasure",nullptr )
|
||||
, SchemaEntry("ifctemperaturegradientmeasure",nullptr )
|
||||
, SchemaEntry("ifcfillstyleselect",nullptr )
|
||||
, SchemaEntry("ifcelectricchargemeasure",nullptr )
|
||||
, SchemaEntry("ifcheatexchangertypeenum",nullptr )
|
||||
, SchemaEntry("ifcelectriccurrentenum",nullptr )
|
||||
, SchemaEntry("ifcdaylightsavinghour",nullptr )
|
||||
, SchemaEntry("ifcshell",nullptr )
|
||||
, SchemaEntry("ifcdoseequivalentmeasure",nullptr )
|
||||
, SchemaEntry("ifcprojectordertypeenum",nullptr )
|
||||
, SchemaEntry("ifcderivedmeasurevalue",nullptr )
|
||||
, SchemaEntry("ifclightdistributioncurveenum",nullptr )
|
||||
, SchemaEntry("ifcwarpingmomentmeasure",nullptr )
|
||||
, SchemaEntry("ifcmembertypeenum",nullptr )
|
||||
, SchemaEntry("ifcsoundpowermeasure",nullptr )
|
||||
, SchemaEntry("ifctextalignment",nullptr )
|
||||
, SchemaEntry("ifccurveoredgecurve",nullptr )
|
||||
, SchemaEntry("ifcmassflowratemeasure",nullptr )
|
||||
, SchemaEntry("ifcisothermalmoisturecapacitymeasure",nullptr )
|
||||
, SchemaEntry("ifccsgselect",nullptr )
|
||||
, SchemaEntry("ifccoolingtowertypeenum",nullptr )
|
||||
, SchemaEntry("ifcmassmeasure",nullptr )
|
||||
, SchemaEntry("ifcpileconstructionenum",nullptr )
|
||||
, SchemaEntry("ifcdoorstyleoperationenum",nullptr )
|
||||
, SchemaEntry("ifcflowdirectionenum",nullptr )
|
||||
, SchemaEntry("ifcthermalloadsourceenum",nullptr )
|
||||
, SchemaEntry("ifclengthmeasure",nullptr )
|
||||
, SchemaEntry("ifcconstraintenum",nullptr )
|
||||
, SchemaEntry("ifcaxis2placement",nullptr )
|
||||
, SchemaEntry("ifcloadgrouptypeenum",nullptr )
|
||||
, SchemaEntry("ifcvalue",nullptr )
|
||||
, SchemaEntry("ifcreinforcingbarsurfaceenum",nullptr )
|
||||
, SchemaEntry("ifcprojectorderrecordtypeenum",nullptr )
|
||||
, SchemaEntry("ifcdatetimeselect",nullptr )
|
||||
, SchemaEntry("ifcstructuralsurfacetypeenum",nullptr )
|
||||
, SchemaEntry("ifcpermeablecoveringoperationenum",nullptr )
|
||||
, SchemaEntry("ifcfontweight",nullptr )
|
||||
, SchemaEntry("ifcphmeasure",nullptr )
|
||||
, SchemaEntry("ifcdescriptivemeasure",nullptr )
|
||||
, SchemaEntry("ifccurvestylefontselect",nullptr )
|
||||
, SchemaEntry("ifcunit",nullptr )
|
||||
, SchemaEntry("ifchatchlinedistanceselect",nullptr )
|
||||
, SchemaEntry("ifctextstyleselect",nullptr )
|
||||
, SchemaEntry("ifcmetricvalueselect",nullptr )
|
||||
, SchemaEntry("ifcvectorordirection",nullptr )
|
||||
, SchemaEntry("ifcassemblyplaceenum",nullptr )
|
||||
, SchemaEntry("ifcairterminaltypeenum",nullptr )
|
||||
, SchemaEntry("ifccoveringtypeenum",nullptr )
|
||||
, SchemaEntry("ifcplanarforcemeasure",nullptr )
|
||||
, SchemaEntry("ifcvalvetypeenum",nullptr )
|
||||
, SchemaEntry("ifcalarmtypeenum",nullptr )
|
||||
, SchemaEntry("ifcdynamicviscositymeasure",nullptr )
|
||||
, SchemaEntry("ifccurrencyenum",nullptr )
|
||||
, SchemaEntry("ifcmodulusofrotationalsubgradereactionmeasure",nullptr )
|
||||
, SchemaEntry("ifccablecarrierfittingtypeenum",nullptr )
|
||||
, SchemaEntry("ifcboolean",nullptr )
|
||||
, SchemaEntry("ifcactionsourcetypeenum",nullptr )
|
||||
, SchemaEntry("ifcstructuralactivityassignmentselect",nullptr )
|
||||
, SchemaEntry("ifcdistributionchamberelementtypeenum",nullptr )
|
||||
, SchemaEntry("ifcevaporativecoolertypeenum",nullptr )
|
||||
, SchemaEntry("ifcmagneticfluxdensitymeasure",nullptr )
|
||||
, SchemaEntry("ifclightdistributiondatasourceselect",nullptr )
|
||||
, SchemaEntry("ifctubebundletypeenum",nullptr )
|
||||
, SchemaEntry("ifcaccelerationmeasure",nullptr )
|
||||
, SchemaEntry("ifcboilertypeenum",nullptr )
|
||||
, SchemaEntry("ifcramptypeenum",nullptr )
|
||||
, SchemaEntry("ifcluminousintensitydistributionmeasure",nullptr )
|
||||
, SchemaEntry("ifctrimmingpreference",nullptr )
|
||||
, SchemaEntry("ifcspecificheatcapacitymeasure",nullptr )
|
||||
, SchemaEntry("ifcamountofsubstancemeasure",nullptr )
|
||||
, SchemaEntry("ifcroleenum",nullptr )
|
||||
, SchemaEntry("ifcdocumentconfidentialityenum",nullptr )
|
||||
, SchemaEntry("ifcfrequencymeasure",nullptr )
|
||||
, SchemaEntry("ifcsectiontypeenum",nullptr )
|
||||
, SchemaEntry("ifcelementassemblytypeenum",nullptr )
|
||||
, SchemaEntry("ifcfootingtypeenum",nullptr )
|
||||
, SchemaEntry("ifclayereditem",nullptr )
|
||||
, SchemaEntry("ifccablesegmenttypeenum",nullptr )
|
||||
, SchemaEntry("ifcdefinedsymbolselect",nullptr )
|
||||
, SchemaEntry("ifcbuildingelementproxytypeenum",nullptr )
|
||||
, SchemaEntry("ifcelectricgeneratortypeenum",nullptr )
|
||||
, SchemaEntry("ifcrotationalstiffnessmeasure",nullptr )
|
||||
, SchemaEntry("ifcspaceheatertypeenum",nullptr )
|
||||
, SchemaEntry("ifcareameasure",nullptr )
|
||||
, SchemaEntry("ifclabel",nullptr )
|
||||
, SchemaEntry("ifccostscheduletypeenum",nullptr )
|
||||
, SchemaEntry("ifcswitchingdevicetypeenum",nullptr )
|
||||
, SchemaEntry("ifcelectrictimecontroltypeenum",nullptr )
|
||||
, SchemaEntry("ifcfiltertypeenum",nullptr )
|
||||
, SchemaEntry("ifcpositivelengthmeasure",nullptr )
|
||||
, SchemaEntry("ifcnullstyle",nullptr )
|
||||
, SchemaEntry("ifcconditioncriterionselect",nullptr )
|
||||
, SchemaEntry("ifcshearmodulusmeasure",nullptr )
|
||||
, SchemaEntry("ifcnormalisedratiomeasure",nullptr )
|
||||
, SchemaEntry("ifcdoorpaneloperationenum",nullptr )
|
||||
, SchemaEntry("ifcpointorvertexpoint",nullptr )
|
||||
, SchemaEntry("ifcrooftypeenum",nullptr )
|
||||
, SchemaEntry("ifccountmeasure",nullptr )
|
||||
, SchemaEntry("ifcelectricconductancemeasure",nullptr )
|
||||
, SchemaEntry("ifcproceduretypeenum",nullptr )
|
||||
, SchemaEntry("ifcflowinstrumenttypeenum",nullptr )
|
||||
, SchemaEntry("ifcelectricmotortypeenum",nullptr )
|
||||
, SchemaEntry("ifcsurfaceside",nullptr )
|
||||
, SchemaEntry("ifcstructuralcurvetypeenum",nullptr )
|
||||
, SchemaEntry("ifccondensertypeenum",nullptr )
|
||||
, SchemaEntry("ifclinearstiffnessmeasure",nullptr )
|
||||
, SchemaEntry("ifcunitenum",nullptr )
|
||||
, SchemaEntry("ifcoccupanttypeenum",nullptr )
|
||||
, SchemaEntry("ifcthermalloadtypeenum",nullptr )
|
||||
, SchemaEntry("ifcreinforcingbarroleenum",nullptr )
|
||||
, SchemaEntry("ifcbenchmarkenum",nullptr )
|
||||
, SchemaEntry("ifcpositiveplaneanglemeasure",nullptr )
|
||||
, SchemaEntry("ifctexttransformation",nullptr )
|
||||
, SchemaEntry("ifcdraughtingcalloutelement",nullptr )
|
||||
, SchemaEntry("ifcratiomeasure",nullptr )
|
||||
, SchemaEntry("ifcsolidanglemeasure",nullptr )
|
||||
, SchemaEntry("ifcpipesegmenttypeenum",nullptr )
|
||||
, SchemaEntry("ifccablecarriersegmenttypeenum",nullptr )
|
||||
, SchemaEntry("ifccolourorfactor",nullptr )
|
||||
, SchemaEntry("ifcidentifier",nullptr )
|
||||
, SchemaEntry("ifctendontypeenum",nullptr )
|
||||
, SchemaEntry("ifccontrollertypeenum",nullptr )
|
||||
, SchemaEntry("ifcradioactivitymeasure",nullptr )
|
||||
, SchemaEntry("ifctimemeasure",nullptr )
|
||||
, SchemaEntry("ifcpumptypeenum",nullptr )
|
||||
, SchemaEntry("ifcelectricheatertypeenum",nullptr )
|
||||
, SchemaEntry("ifcbeamtypeenum",nullptr )
|
||||
, SchemaEntry("ifcstateenum",nullptr )
|
||||
, SchemaEntry("ifcsiprefix",nullptr )
|
||||
, SchemaEntry("ifcnumericmeasure",nullptr )
|
||||
, SchemaEntry("ifcoutlettypeenum",nullptr )
|
||||
, SchemaEntry("ifccompoundplaneanglemeasure",nullptr )
|
||||
, SchemaEntry("ifcservicelifefactortypeenum",nullptr )
|
||||
, SchemaEntry("ifclogicaloperatorenum",nullptr )
|
||||
, SchemaEntry("ifcbooleanoperand",nullptr )
|
||||
, SchemaEntry("ifcobjectreferenceselect",nullptr )
|
||||
, SchemaEntry("ifccooledbeamtypeenum",nullptr )
|
||||
, SchemaEntry("ifcductsilencertypeenum",nullptr )
|
||||
, SchemaEntry("ifcsectionalareaintegralmeasure",nullptr )
|
||||
, SchemaEntry("ifcfontvariant",nullptr )
|
||||
, SchemaEntry("ifcvolumetricflowratemeasure",nullptr )
|
||||
, SchemaEntry("ifcplatetypeenum",nullptr )
|
||||
, SchemaEntry("ifcenvironmentalimpactcategoryenum",nullptr )
|
||||
, SchemaEntry("ifcvibrationisolatortypeenum",nullptr )
|
||||
, SchemaEntry("ifcthermodynamictemperaturemeasure",nullptr )
|
||||
, SchemaEntry("ifcrotationalmassmeasure",nullptr )
|
||||
, SchemaEntry("ifcsecondinminute",nullptr )
|
||||
, SchemaEntry("ifcdayinmonthnumber",nullptr )
|
||||
, SchemaEntry("ifcdimensioncount",nullptr )
|
||||
, SchemaEntry("ifcwindowstyleoperationenum",nullptr )
|
||||
, SchemaEntry("ifcthermalresistancemeasure",nullptr )
|
||||
, SchemaEntry("ifcmeasurevalue",nullptr )
|
||||
, SchemaEntry("ifcwindowpaneloperationenum",nullptr )
|
||||
, SchemaEntry("ifcchillertypeenum",nullptr )
|
||||
, SchemaEntry("ifcpositiveratiomeasure",nullptr )
|
||||
, SchemaEntry("ifcinteger",nullptr )
|
||||
, SchemaEntry("ifclogical",nullptr )
|
||||
, SchemaEntry("ifcjunctionboxtypeenum",nullptr )
|
||||
, SchemaEntry("ifcaddresstypeenum",nullptr )
|
||||
, SchemaEntry("ifcwasteterminaltypeenum",nullptr )
|
||||
, SchemaEntry("ifctrimmingselect",nullptr )
|
||||
, SchemaEntry("ifclightemissionsourceenum",nullptr )
|
||||
, SchemaEntry("ifcsoundscaleenum",nullptr )
|
||||
, SchemaEntry("ifcluminousfluxmeasure",nullptr )
|
||||
, SchemaEntry("ifcelectricresistancemeasure",nullptr )
|
||||
, SchemaEntry("ifcintegercountratemeasure",nullptr )
|
||||
, SchemaEntry("ifcphysicalorvirtualenum",nullptr )
|
||||
, SchemaEntry("ifcmolecularweightmeasure",nullptr )
|
||||
, SchemaEntry("ifcprofiletypeenum",nullptr )
|
||||
, SchemaEntry("ifcboxalignment",nullptr )
|
||||
, SchemaEntry("ifcglobalorlocalenum",nullptr )
|
||||
, SchemaEntry("ifcspecularroughness",nullptr )
|
||||
, SchemaEntry("ifclamptypeenum",nullptr )
|
||||
, SchemaEntry("ifcpiletypeenum",nullptr )
|
||||
, SchemaEntry("ifcelectriccurrentmeasure",nullptr )
|
||||
, SchemaEntry("ifcfantypeenum",nullptr )
|
||||
, SchemaEntry("ifcsurfaceorfacesurface",nullptr )
|
||||
, SchemaEntry("ifcpipefittingtypeenum",nullptr )
|
||||
, SchemaEntry("ifctanktypeenum",nullptr )
|
||||
, SchemaEntry("ifccurvefontorscaledcurvefontselect",nullptr )
|
||||
, SchemaEntry("ifcwindowstyleconstructionenum",nullptr )
|
||||
, SchemaEntry("ifcairterminalboxtypeenum",nullptr )
|
||||
, SchemaEntry("ifcstairflighttypeenum",nullptr )
|
||||
, SchemaEntry("ifcluminousintensitymeasure",nullptr )
|
||||
, SchemaEntry("ifcmotorconnectiontypeenum",nullptr )
|
||||
, SchemaEntry("ifcplaneanglemeasure",nullptr )
|
||||
, SchemaEntry("ifcactuatortypeenum",nullptr )
|
||||
, SchemaEntry("ifccolumntypeenum",nullptr )
|
||||
, SchemaEntry("ifctextfontselect",nullptr )
|
||||
, SchemaEntry("ifcdoorpanelpositionenum",nullptr )
|
||||
, SchemaEntry("ifccoiltypeenum",nullptr )
|
||||
, SchemaEntry("ifcangularvelocitymeasure",nullptr )
|
||||
, SchemaEntry("ifcanalysismodeltypeenum",nullptr )
|
||||
, SchemaEntry("ifclibraryselect",nullptr )
|
||||
, SchemaEntry("ifcforcemeasure",nullptr )
|
||||
, SchemaEntry("ifcfillareastyletileshapeselect",nullptr )
|
||||
, SchemaEntry("ifcelectricappliancetypeenum",nullptr )
|
||||
, SchemaEntry("ifcsurfacetextureenum",nullptr )
|
||||
, SchemaEntry("ifccharacterstyleselect",nullptr )
|
||||
, SchemaEntry("ifcenergymeasure",nullptr )
|
||||
, SchemaEntry("ifcreal",nullptr )
|
||||
, SchemaEntry("ifccompressortypeenum",nullptr )
|
||||
, SchemaEntry("ifcelectricdistributionpointfunctionenum",nullptr )
|
||||
, SchemaEntry("ifcroot",&STEP::ObjectHelper<IfcRoot,4>::Construct )
|
||||
, SchemaEntry("ifcobjectdefinition",&STEP::ObjectHelper<IfcObjectDefinition,0>::Construct )
|
||||
, SchemaEntry("ifctypeobject",&STEP::ObjectHelper<IfcTypeObject,2>::Construct )
|
||||
|
|
|
@ -71,7 +71,7 @@ aiMesh* TempMesh::ToMesh()
|
|||
ai_assert(mVerts.size() == std::accumulate(mVertcnt.begin(),mVertcnt.end(),size_t(0)));
|
||||
|
||||
if (mVerts.empty()) {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<aiMesh> mesh(new aiMesh());
|
||||
|
@ -162,7 +162,7 @@ void TempMesh::RemoveDegenerates()
|
|||
}
|
||||
|
||||
if(drop) {
|
||||
IFCImporter::LogDebug("removing degenerate faces");
|
||||
IFCImporter::LogVerboseDebug("removing degenerate faces");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -437,7 +437,7 @@ void TempMesh::RemoveAdjacentDuplicates() {
|
|||
base += cnt;
|
||||
}
|
||||
if(drop) {
|
||||
IFCImporter::LogDebug("removing duplicate vertices");
|
||||
IFCImporter::LogVerboseDebug("removing duplicate vertices");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -201,7 +201,7 @@ struct ConversionData
|
|||
|
||||
struct MeshCacheIndex {
|
||||
const IFC::Schema_2x3::IfcRepresentationItem* item; unsigned int matindex;
|
||||
MeshCacheIndex() : item(NULL), matindex(0) { }
|
||||
MeshCacheIndex() : item(nullptr), matindex(0) { }
|
||||
MeshCacheIndex(const IFC::Schema_2x3::IfcRepresentationItem* i, unsigned int mi) : item(i), matindex(mi) { }
|
||||
bool operator == (const MeshCacheIndex& o) const { return item == o.item && matindex == o.matindex; }
|
||||
bool operator < (const MeshCacheIndex& o) const { return item < o.item || (item == o.item && matindex < o.matindex); }
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -139,8 +139,9 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
|
|||
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
|
||||
|
||||
// Check whether we can read from the file
|
||||
if( file.get() == NULL)
|
||||
throw DeadlyImportError( "Failed to open IRRMESH file " + pFile + "");
|
||||
if (file.get() == nullptr) {
|
||||
throw DeadlyImportError("Failed to open IRRMESH file " + pFile + ".");
|
||||
}
|
||||
|
||||
// Construct the irrXML parser
|
||||
CIrrXML_IOStreamReader st(file.get());
|
||||
|
|
|
@ -538,11 +538,11 @@ void AnimResolver::GetKeys(std::vector<aiVectorKey> &out,
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Extract animation channel
|
||||
void AnimResolver::ExtractAnimChannel(aiNodeAnim **out, unsigned int /*= 0*/) {
|
||||
*out = NULL;
|
||||
*out = nullptr;
|
||||
|
||||
//FIXME: crashes if more than one component is animated at different timings, to be resolved.
|
||||
|
||||
// If we have no envelopes, return NULL
|
||||
// If we have no envelopes, return nullptr
|
||||
if (envelopes.empty()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -211,7 +211,7 @@ public:
|
|||
// ------------------------------------------------------------------
|
||||
/** @brief Extract a node animation channel
|
||||
* @param out Receives a pointer to a newly allocated node anim.
|
||||
* If there's just one keyframe defined, *out is set to NULL and
|
||||
* If there's just one keyframe defined, *out is set to nullptr and
|
||||
* no animation channel is computed.
|
||||
* @param flags Any combination of the AI_LWO_ANIM_FLAG_XXX flags.
|
||||
*/
|
||||
|
@ -261,7 +261,7 @@ protected:
|
|||
* @param envl_y Y-component envelope
|
||||
* @param envl_z Z-component envelope
|
||||
* @param flags Any combination of the AI_LWO_ANIM_FLAG_XXX flags.
|
||||
* @note Up to two input envelopes may be NULL
|
||||
* @note Up to two input envelopes may be nullptr
|
||||
*/
|
||||
void GetKeys(std::vector<aiVectorKey>& out,
|
||||
LWO::Envelope* envl_x,
|
||||
|
|
|
@ -255,7 +255,7 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
|
|||
|
||||
mSurfaces->push_back( LWO::Surface () );
|
||||
LWO::Surface& surf = mSurfaces->back();
|
||||
LWO::Texture* pTex = NULL;
|
||||
LWO::Texture *pTex = nullptr;
|
||||
|
||||
GetS0(surf.mName,size);
|
||||
bool running = true;
|
||||
|
|
|
@ -422,7 +422,7 @@ void LWOImporter::InternReadFile(const std::string &pFile,
|
|||
// So we use a separate implementation.
|
||||
ComputeNormals(mesh, smoothingGroups, _mSurfaces[j]);
|
||||
} else {
|
||||
ASSIMP_LOG_DEBUG("LWO2: No need to compute normals, they're already there");
|
||||
ASSIMP_LOG_VERBOSE_DEBUG("LWO2: No need to compute normals, they're already there");
|
||||
}
|
||||
++p;
|
||||
}
|
||||
|
@ -917,7 +917,7 @@ inline void CreateNewEntry(std::vector<T> &list, unsigned int srcIdx) {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
inline void LWOImporter::DoRecursiveVMAPAssignment(VMapEntry *base, unsigned int numRead,
|
||||
unsigned int idx, float *data) {
|
||||
ai_assert(NULL != data);
|
||||
ai_assert(nullptr != data);
|
||||
LWO::ReferrerList &refList = mCurLayer->mPointReferrers;
|
||||
unsigned int i;
|
||||
|
||||
|
|
|
@ -305,7 +305,7 @@ private:
|
|||
/** Add children to a node
|
||||
* @param node Node to become a father
|
||||
* @param parent Index of the node
|
||||
* @param apcNodes Flat list of nodes - used nodes are set to NULL.
|
||||
* @param apcNodes Flat list of nodes - used nodes are set to nullptr.
|
||||
*/
|
||||
void AddChildren(aiNode* node, uint16_t parent,
|
||||
std::vector<aiNode*>& apcNodes);
|
||||
|
|
|
@ -79,7 +79,7 @@ inline aiTextureMapMode GetMapMode(LWO::Texture::Wrap in) {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool LWOImporter::HandleTextures(aiMaterial *pcMat, const TextureList &in, aiTextureType type) {
|
||||
ai_assert(NULL != pcMat);
|
||||
ai_assert(nullptr != pcMat);
|
||||
|
||||
unsigned int cur = 0, temp = 0;
|
||||
aiString s;
|
||||
|
@ -154,7 +154,7 @@ bool LWOImporter::HandleTextures(aiMaterial *pcMat, const TextureList &in, aiTex
|
|||
static_assert(sizeof(aiUVTransform) / sizeof(ai_real) == 5, "sizeof(aiUVTransform)/sizeof(ai_real) == 5");
|
||||
pcMat->AddProperty(&trafo, 1, AI_MATKEY_UVTRANSFORM(type, cur));
|
||||
}
|
||||
ASSIMP_LOG_DEBUG("LWO2: Setting up non-UV mapping");
|
||||
ASSIMP_LOG_VERBOSE_DEBUG("LWO2: Setting up non-UV mapping");
|
||||
}
|
||||
|
||||
// The older LWOB format does not use indirect references to clips.
|
||||
|
@ -603,7 +603,7 @@ void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader *head, unsi
|
|||
}
|
||||
|
||||
// get the destination channel
|
||||
TextureList *listRef = NULL;
|
||||
TextureList *listRef = nullptr;
|
||||
switch (tex.type) {
|
||||
case AI_LWO_COLR:
|
||||
listRef = &surf.mColorTextures;
|
||||
|
|
|
@ -101,7 +101,7 @@ void LWS::Element::Parse(const char *&buffer) {
|
|||
SkipSpaces(&buffer);
|
||||
|
||||
if (children.back().tokens[0] == "Plugin") {
|
||||
ASSIMP_LOG_DEBUG("LWS: Skipping over plugin-specific data");
|
||||
ASSIMP_LOG_VERBOSE_DEBUG("LWS: Skipping over plugin-specific data");
|
||||
|
||||
// strange stuff inside Plugin/Endplugin blocks. Needn't
|
||||
// follow LWS syntax, so we skip over it
|
||||
|
@ -342,7 +342,7 @@ void LWSImporter::BuildGraph(aiNode *nd, LWS::NodeDesc &src, std::vector<Attachm
|
|||
if (src.type == LWS::NodeDesc::OBJECT) {
|
||||
|
||||
// If the object is from an external file, get it
|
||||
aiScene *obj = NULL;
|
||||
aiScene *obj = nullptr;
|
||||
if (src.path.length()) {
|
||||
obj = batch.GetImport(src.id);
|
||||
if (!obj) {
|
||||
|
@ -359,7 +359,7 @@ void LWSImporter::BuildGraph(aiNode *nd, LWS::NodeDesc &src, std::vector<Attachm
|
|||
|
||||
//Remove first node from obj (the old pivot), reset transform of second node (the mesh node)
|
||||
aiNode *newRootNode = obj->mRootNode->mChildren[0];
|
||||
obj->mRootNode->mChildren[0] = NULL;
|
||||
obj->mRootNode->mChildren[0] = nullptr;
|
||||
delete obj->mRootNode;
|
||||
|
||||
obj->mRootNode = newRootNode;
|
||||
|
@ -600,7 +600,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
d.number = cur_object++;
|
||||
}
|
||||
std::string path = FindLWOFile(c);
|
||||
d.id = batch.AddLoadRequest(path, 0, NULL);
|
||||
d.id = batch.AddLoadRequest(path, 0, nullptr);
|
||||
|
||||
d.path = path;
|
||||
nodes.push_back(d);
|
||||
|
|
|
@ -84,7 +84,19 @@ public:
|
|||
*/
|
||||
struct NodeDesc {
|
||||
NodeDesc() :
|
||||
type(), id(), number(0), parent(0), name(""), isPivotSet(false), lightColor(1.f, 1.f, 1.f), lightIntensity(1.f), lightType(0), lightFalloffType(0), lightConeAngle(45.f), lightEdgeAngle(), parent_resolved(NULL) {}
|
||||
type(),
|
||||
id(),
|
||||
number(0),
|
||||
parent(0),
|
||||
name(""),
|
||||
isPivotSet(false),
|
||||
lightColor(1.f, 1.f, 1.f),
|
||||
lightIntensity(1.f),
|
||||
lightType(0),
|
||||
lightFalloffType(0),
|
||||
lightConeAngle(45.f),
|
||||
lightEdgeAngle(),
|
||||
parent_resolved(nullptr) {}
|
||||
|
||||
enum {
|
||||
|
||||
|
|
|
@ -181,7 +181,7 @@ M3D_INDEX addMaterial(const Assimp::M3DWrapper &m3d, const aiMaterial *mat) {
|
|||
}
|
||||
m3d->material[mi].name = SafeStr(name, true);
|
||||
m3d->material[mi].numprop = 0;
|
||||
m3d->material[mi].prop = NULL;
|
||||
m3d->material[mi].prop = nullptr;
|
||||
// iterate through the material property table and see what we got
|
||||
for (k = 0; k < 15; k++) {
|
||||
unsigned int j;
|
||||
|
@ -229,8 +229,8 @@ M3D_INDEX addMaterial(const Assimp::M3DWrapper &m3d, const aiMaterial *mat) {
|
|||
}
|
||||
if (aiTxProps[k].pKey &&
|
||||
mat->GetTexture((aiTextureType)aiTxProps[k].type,
|
||||
aiTxProps[k].index, &name, NULL, NULL, NULL,
|
||||
NULL, NULL) == AI_SUCCESS) {
|
||||
aiTxProps[k].index, &name, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr) == AI_SUCCESS) {
|
||||
unsigned int i;
|
||||
for (j = name.length - 1; j > 0 && name.data[j] != '.'; j++)
|
||||
;
|
||||
|
@ -259,7 +259,7 @@ M3D_INDEX addMaterial(const Assimp::M3DWrapper &m3d, const aiMaterial *mat) {
|
|||
m3d->texture[i].name = fn;
|
||||
m3d->texture[i].w = 0;
|
||||
m3d->texture[i].h = 0;
|
||||
m3d->texture[i].d = NULL;
|
||||
m3d->texture[i].d = nullptr;
|
||||
}
|
||||
addProp(&m3d->material[mi],
|
||||
m3d_propertytypes[k].id + 128, i);
|
||||
|
|
|
@ -618,8 +618,10 @@ aiColor4D M3DImporter::mkColor(uint32_t c) {
|
|||
void M3DImporter::convertPose(const M3DWrapper &m3d, aiMatrix4x4 *m, unsigned int posid, unsigned int orientid) {
|
||||
ai_assert(m != nullptr);
|
||||
ai_assert(m3d);
|
||||
ai_assert(posid != M3D_UNDEF && posid < m3d->numvertex);
|
||||
ai_assert(orientid != M3D_UNDEF && orientid < m3d->numvertex);
|
||||
ai_assert(posid != M3D_UNDEF);
|
||||
ai_assert(posid < m3d->numvertex);
|
||||
ai_assert(orientid != M3D_UNDEF);
|
||||
ai_assert(orientid < m3d->numvertex);
|
||||
if (!m3d->numvertex || !m3d->vertex)
|
||||
return;
|
||||
m3dv_t *p = &m3d->vertex[posid];
|
||||
|
|
|
@ -71,14 +71,14 @@ static const aiMatProp aiProps[] = {
|
|||
{ AI_MATKEY_OPACITY }, /* m3dp_d */
|
||||
{ AI_MATKEY_SHADING_MODEL }, /* m3dp_il */
|
||||
|
||||
{ NULL, 0, 0 }, /* m3dp_Pr */
|
||||
{ nullptr, 0, 0 }, /* m3dp_Pr */
|
||||
{ AI_MATKEY_REFLECTIVITY }, /* m3dp_Pm */
|
||||
{ NULL, 0, 0 }, /* m3dp_Ps */
|
||||
{ nullptr, 0, 0 }, /* m3dp_Ps */
|
||||
{ AI_MATKEY_REFRACTI }, /* m3dp_Ni */
|
||||
{ NULL, 0, 0 }, /* m3dp_Nt */
|
||||
{ NULL, 0, 0 },
|
||||
{ NULL, 0, 0 },
|
||||
{ NULL, 0, 0 }
|
||||
{ nullptr, 0, 0 }, /* m3dp_Nt */
|
||||
{ nullptr, 0, 0 },
|
||||
{ nullptr, 0, 0 },
|
||||
{ nullptr, 0, 0 }
|
||||
};
|
||||
|
||||
/* --- Texture Map Properties --- !!!!! must match m3d_propertytypes !!!!! */
|
||||
|
@ -88,19 +88,19 @@ static const aiMatProp aiTxProps[] = {
|
|||
{ AI_MATKEY_TEXTURE_SPECULAR(0) }, /* m3dp_map_Ks */
|
||||
{ AI_MATKEY_TEXTURE_SHININESS(0) }, /* m3dp_map_Ns */
|
||||
{ AI_MATKEY_TEXTURE_EMISSIVE(0) }, /* m3dp_map_Ke */
|
||||
{ NULL, 0, 0 }, /* m3dp_map_Tf */
|
||||
{ nullptr, 0, 0 }, /* m3dp_map_Tf */
|
||||
{ AI_MATKEY_TEXTURE_HEIGHT(0) }, /* m3dp_bump */
|
||||
{ AI_MATKEY_TEXTURE_OPACITY(0) }, /* m3dp_map_d */
|
||||
{ AI_MATKEY_TEXTURE_NORMALS(0) }, /* m3dp_map_N */
|
||||
|
||||
{ AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE_ROUGHNESS,0) },/* m3dp_map_Pr */
|
||||
{ AI_MATKEY_TEXTURE(aiTextureType_METALNESS,0) }, /* m3dp_map_Pm */
|
||||
{ NULL, 0, 0 }, /* m3dp_map_Ps */
|
||||
{ nullptr, 0, 0 }, /* m3dp_map_Ps */
|
||||
{ AI_MATKEY_TEXTURE(aiTextureType_REFLECTION,0) }, /* m3dp_map_Ni */
|
||||
{ NULL, 0, 0 }, /* m3dp_map_Nt */
|
||||
{ NULL, 0, 0 },
|
||||
{ NULL, 0, 0 },
|
||||
{ NULL, 0, 0 }
|
||||
{ nullptr, 0, 0 }, /* m3dp_map_Nt */
|
||||
{ nullptr, 0, 0 },
|
||||
{ nullptr, 0, 0 },
|
||||
{ nullptr, 0, 0 }
|
||||
};
|
||||
|
||||
#endif // AI_M3DMATERIALS_H_INC
|
||||
|
|
|
@ -72,7 +72,7 @@ unsigned char *m3dimporter_readfile(char *fn, unsigned int *size) {
|
|||
std::unique_ptr<Assimp::IOStream> pStream(
|
||||
(reinterpret_cast<Assimp::IOSystem *>(m3dimporter_pIOHandler))->Open(file, "rb"));
|
||||
size_t fileSize = 0;
|
||||
unsigned char *data = NULL;
|
||||
unsigned char *data = nullptr;
|
||||
// sometimes pStream is nullptr in a single-threaded scenario too for some reason
|
||||
// (should be an empty object returning nothing I guess)
|
||||
if (pStream) {
|
||||
|
|
|
@ -5071,7 +5071,7 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size
|
|||
ptr += sprintf(ptr, "\r\n");
|
||||
}
|
||||
/* mathematical shapes face */
|
||||
if (model->numshape && model->numshape && !(flags & M3D_EXP_NOFACE)) {
|
||||
if (model->numshape !(flags & M3D_EXP_NOFACE)) {
|
||||
for (j = 0; j < model->numshape; j++) {
|
||||
sn = _m3d_safestr(model->shape[j].name, 0);
|
||||
if (!sn) {
|
||||
|
|
|
@ -221,20 +221,21 @@ void MD2Importer::InternReadFile( const std::string& pFile,
|
|||
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
|
||||
|
||||
// Check whether we can read from the file
|
||||
if( file.get() == NULL)
|
||||
throw DeadlyImportError( "Failed to open MD2 file " + pFile + "");
|
||||
if (file.get() == nullptr) {
|
||||
throw DeadlyImportError("Failed to open MD2 file " + pFile + "");
|
||||
}
|
||||
|
||||
// check whether the md3 file is large enough to contain
|
||||
// at least the file header
|
||||
fileSize = (unsigned int)file->FileSize();
|
||||
if( fileSize < sizeof(MD2::Header))
|
||||
throw DeadlyImportError( "MD2 File is too small");
|
||||
if (fileSize < sizeof(MD2::Header)) {
|
||||
throw DeadlyImportError("MD2 File is too small");
|
||||
}
|
||||
|
||||
std::vector<uint8_t> mBuffer2(fileSize);
|
||||
file->Read(&mBuffer2[0], 1, fileSize);
|
||||
mBuffer = &mBuffer2[0];
|
||||
|
||||
|
||||
m_pcHeader = (BE_NCONST MD2::Header*)mBuffer;
|
||||
|
||||
#ifdef AI_BUILD_BIG_ENDIAN
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,8 +5,6 @@ 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,
|
||||
|
@ -82,7 +80,15 @@ static const aiImporterDesc desc = {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor to be privately used by Importer
|
||||
MD5Importer::MD5Importer() :
|
||||
mIOHandler(nullptr), mBuffer(), fileSize(), iLineNumber(), pScene(), bHadMD5Mesh(), bHadMD5Anim(), bHadMD5Camera(), configNoAutoLoad(false) {
|
||||
mIOHandler(nullptr),
|
||||
mBuffer(),
|
||||
mFileSize(),
|
||||
mLineNumber(),
|
||||
mScene(),
|
||||
mHadMD5Mesh(),
|
||||
mHadMD5Anim(),
|
||||
mHadMD5Camera(),
|
||||
mCconfigNoAutoLoad(false) {
|
||||
// empty
|
||||
}
|
||||
|
||||
|
@ -106,6 +112,7 @@ bool MD5Importer::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c
|
|||
const char *tokens[] = { "MD5Version" };
|
||||
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -119,16 +126,15 @@ const aiImporterDesc *MD5Importer::GetInfo() const {
|
|||
// Setup import properties
|
||||
void MD5Importer::SetupProperties(const Importer *pImp) {
|
||||
// AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD
|
||||
configNoAutoLoad = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD, 0));
|
||||
mCconfigNoAutoLoad = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD, 0));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Imports the given file into the given scene structure.
|
||||
void MD5Importer::InternReadFile(const std::string &pFile,
|
||||
aiScene *_pScene, IOSystem *pIOHandler) {
|
||||
void MD5Importer::InternReadFile(const std::string &pFile, aiScene *_pScene, IOSystem *pIOHandler) {
|
||||
mIOHandler = pIOHandler;
|
||||
pScene = _pScene;
|
||||
bHadMD5Mesh = bHadMD5Anim = bHadMD5Camera = false;
|
||||
mScene = _pScene;
|
||||
mHadMD5Mesh = mHadMD5Anim = mHadMD5Camera = false;
|
||||
|
||||
// remove the file extension
|
||||
const std::string::size_type pos = pFile.find_last_of('.');
|
||||
|
@ -138,7 +144,7 @@ void MD5Importer::InternReadFile(const std::string &pFile,
|
|||
try {
|
||||
if (extension == "md5camera") {
|
||||
LoadMD5CameraFile();
|
||||
} else if (configNoAutoLoad || extension == "md5anim") {
|
||||
} else if (mCconfigNoAutoLoad || extension == "md5anim") {
|
||||
// determine file extension and process just *one* file
|
||||
if (extension.length() == 0) {
|
||||
throw DeadlyImportError("Failure, need file extension to determine MD5 part type");
|
||||
|
@ -158,17 +164,17 @@ void MD5Importer::InternReadFile(const std::string &pFile,
|
|||
}
|
||||
|
||||
// make sure we have at least one file
|
||||
if (!bHadMD5Mesh && !bHadMD5Anim && !bHadMD5Camera) {
|
||||
if (!mHadMD5Mesh && !mHadMD5Anim && !mHadMD5Camera) {
|
||||
throw DeadlyImportError("Failed to read valid contents out of this MD5* file");
|
||||
}
|
||||
|
||||
// Now rotate the whole scene 90 degrees around the x axis to match our internal coordinate system
|
||||
pScene->mRootNode->mTransformation = aiMatrix4x4(1.f, 0.f, 0.f, 0.f,
|
||||
mScene->mRootNode->mTransformation = aiMatrix4x4(1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f, 0.f, -1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f);
|
||||
|
||||
// the output scene wouldn't pass the validation without this flag
|
||||
if (!bHadMD5Mesh) {
|
||||
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
|
||||
if (!mHadMD5Mesh) {
|
||||
mScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
|
||||
}
|
||||
|
||||
// clean the instance -- the BaseImporter instance may be reused later.
|
||||
|
@ -181,17 +187,17 @@ void MD5Importer::LoadFileIntoMemory(IOStream *file) {
|
|||
// unload the previous buffer, if any
|
||||
UnloadFileFromMemory();
|
||||
|
||||
ai_assert(NULL != file);
|
||||
fileSize = (unsigned int)file->FileSize();
|
||||
ai_assert(fileSize);
|
||||
ai_assert(nullptr != file);
|
||||
mFileSize = (unsigned int)file->FileSize();
|
||||
ai_assert(mFileSize);
|
||||
|
||||
// allocate storage and copy the contents of the file to a memory buffer
|
||||
mBuffer = new char[fileSize + 1];
|
||||
file->Read((void *)mBuffer, 1, fileSize);
|
||||
iLineNumber = 1;
|
||||
mBuffer = new char[mFileSize + 1];
|
||||
file->Read((void *)mBuffer, 1, mFileSize);
|
||||
mLineNumber = 1;
|
||||
|
||||
// append a terminal 0
|
||||
mBuffer[fileSize] = '\0';
|
||||
mBuffer[mFileSize] = '\0';
|
||||
|
||||
// now remove all line comments from the file
|
||||
CommentRemover::RemoveLineComments("//", mBuffer, ' ');
|
||||
|
@ -202,8 +208,8 @@ void MD5Importer::LoadFileIntoMemory(IOStream *file) {
|
|||
void MD5Importer::UnloadFileFromMemory() {
|
||||
// delete the file buffer
|
||||
delete[] mBuffer;
|
||||
mBuffer = NULL;
|
||||
fileSize = 0;
|
||||
mBuffer = nullptr;
|
||||
mFileSize = 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -243,7 +249,8 @@ void MD5Importer::MakeDataUnique(MD5::MeshDesc &meshSrc) {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Recursive node graph construction from a MD5MESH
|
||||
void MD5Importer::AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneList &bones) {
|
||||
ai_assert(NULL != piParent && !piParent->mNumChildren);
|
||||
ai_assert(nullptr != piParent);
|
||||
ai_assert(!piParent->mNumChildren);
|
||||
|
||||
// First find out how many children we'll have
|
||||
for (int i = 0; i < (int)bones.size(); ++i) {
|
||||
|
@ -293,7 +300,8 @@ void MD5Importer::AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneList &b
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Recursive node graph construction from a MD5ANIM
|
||||
void MD5Importer::AttachChilds_Anim(int iParentID, aiNode *piParent, AnimBoneList &bones, const aiNodeAnim **node_anims) {
|
||||
ai_assert(NULL != piParent && !piParent->mNumChildren);
|
||||
ai_assert(nullptr != piParent);
|
||||
ai_assert(!piParent->mNumChildren);
|
||||
|
||||
// First find out how many children we'll have
|
||||
for (int i = 0; i < (int)bones.size(); ++i) {
|
||||
|
@ -332,37 +340,37 @@ void MD5Importer::AttachChilds_Anim(int iParentID, aiNode *piParent, AnimBoneLis
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Load a MD5MESH file
|
||||
void MD5Importer::LoadMD5MeshFile() {
|
||||
std::string pFile = mFile + "md5mesh";
|
||||
std::unique_ptr<IOStream> file(mIOHandler->Open(pFile, "rb"));
|
||||
std::string filename = mFile + "md5mesh";
|
||||
std::unique_ptr<IOStream> file(mIOHandler->Open(filename, "rb"));
|
||||
|
||||
// Check whether we can read from the file
|
||||
if (file.get() == nullptr || !file->FileSize()) {
|
||||
ASSIMP_LOG_WARN("Failed to access MD5MESH file: " + pFile);
|
||||
ASSIMP_LOG_WARN("Failed to access MD5MESH file: " + filename);
|
||||
return;
|
||||
}
|
||||
bHadMD5Mesh = true;
|
||||
mHadMD5Mesh = true;
|
||||
LoadFileIntoMemory(file.get());
|
||||
|
||||
// now construct a parser and parse the file
|
||||
MD5::MD5Parser parser(mBuffer, fileSize);
|
||||
MD5::MD5Parser parser(mBuffer, mFileSize);
|
||||
|
||||
// load the mesh information from it
|
||||
MD5::MD5MeshParser meshParser(parser.mSections);
|
||||
|
||||
// create the bone hierarchy - first the root node and dummy nodes for all meshes
|
||||
pScene->mRootNode = new aiNode("<MD5_Root>");
|
||||
pScene->mRootNode->mNumChildren = 2;
|
||||
pScene->mRootNode->mChildren = new aiNode *[2];
|
||||
mScene->mRootNode = new aiNode("<MD5_Root>");
|
||||
mScene->mRootNode->mNumChildren = 2;
|
||||
mScene->mRootNode->mChildren = new aiNode *[2];
|
||||
|
||||
// build the hierarchy from the MD5MESH file
|
||||
aiNode *pcNode = pScene->mRootNode->mChildren[1] = new aiNode();
|
||||
aiNode *pcNode = mScene->mRootNode->mChildren[1] = new aiNode();
|
||||
pcNode->mName.Set("<MD5_Hierarchy>");
|
||||
pcNode->mParent = pScene->mRootNode;
|
||||
pcNode->mParent = mScene->mRootNode;
|
||||
AttachChilds_Mesh(-1, pcNode, meshParser.mJoints);
|
||||
|
||||
pcNode = pScene->mRootNode->mChildren[0] = new aiNode();
|
||||
pcNode = mScene->mRootNode->mChildren[0] = new aiNode();
|
||||
pcNode->mName.Set("<MD5_Mesh>");
|
||||
pcNode->mParent = pScene->mRootNode;
|
||||
pcNode->mParent = mScene->mRootNode;
|
||||
|
||||
#if 0
|
||||
if (pScene->mRootNode->mChildren[1]->mNumChildren) /* start at the right hierarchy level */
|
||||
|
@ -371,28 +379,31 @@ void MD5Importer::LoadMD5MeshFile() {
|
|||
|
||||
// FIX: MD5 files exported from Blender can have empty meshes
|
||||
for (std::vector<MD5::MeshDesc>::const_iterator it = meshParser.mMeshes.begin(), end = meshParser.mMeshes.end(); it != end; ++it) {
|
||||
if (!(*it).mFaces.empty() && !(*it).mVertices.empty())
|
||||
++pScene->mNumMaterials;
|
||||
if (!(*it).mFaces.empty() && !(*it).mVertices.empty()) {
|
||||
++mScene->mNumMaterials;
|
||||
}
|
||||
}
|
||||
|
||||
// generate all meshes
|
||||
pScene->mNumMeshes = pScene->mNumMaterials;
|
||||
pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
|
||||
pScene->mMaterials = new aiMaterial *[pScene->mNumMeshes];
|
||||
mScene->mNumMeshes = mScene->mNumMaterials;
|
||||
mScene->mMeshes = new aiMesh *[mScene->mNumMeshes];
|
||||
mScene->mMaterials = new aiMaterial *[mScene->mNumMeshes];
|
||||
|
||||
// storage for node mesh indices
|
||||
pcNode->mNumMeshes = pScene->mNumMeshes;
|
||||
pcNode->mNumMeshes = mScene->mNumMeshes;
|
||||
pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
|
||||
for (unsigned int m = 0; m < pcNode->mNumMeshes; ++m)
|
||||
for (unsigned int m = 0; m < pcNode->mNumMeshes; ++m) {
|
||||
pcNode->mMeshes[m] = m;
|
||||
}
|
||||
|
||||
unsigned int n = 0;
|
||||
for (std::vector<MD5::MeshDesc>::iterator it = meshParser.mMeshes.begin(), end = meshParser.mMeshes.end(); it != end; ++it) {
|
||||
MD5::MeshDesc &meshSrc = *it;
|
||||
if (meshSrc.mFaces.empty() || meshSrc.mVertices.empty())
|
||||
if (meshSrc.mFaces.empty() || meshSrc.mVertices.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
aiMesh *mesh = pScene->mMeshes[n] = new aiMesh();
|
||||
aiMesh *mesh = mScene->mMeshes[n] = new aiMesh();
|
||||
mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
|
||||
|
||||
// generate unique vertices in our internal verbose format
|
||||
|
@ -422,17 +433,19 @@ void MD5Importer::LoadMD5MeshFile() {
|
|||
for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights; ++w) {
|
||||
MD5::WeightDesc &weightDesc = meshSrc.mWeights[w];
|
||||
/* FIX for some invalid exporters */
|
||||
if (!(weightDesc.mWeight < AI_MD5_WEIGHT_EPSILON && weightDesc.mWeight >= -AI_MD5_WEIGHT_EPSILON))
|
||||
if (!(weightDesc.mWeight < AI_MD5_WEIGHT_EPSILON && weightDesc.mWeight >= -AI_MD5_WEIGHT_EPSILON)) {
|
||||
++piCount[weightDesc.mBone];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check how many we will need
|
||||
for (unsigned int p = 0; p < meshParser.mJoints.size(); ++p)
|
||||
for (unsigned int p = 0; p < meshParser.mJoints.size(); ++p) {
|
||||
if (piCount[p]) mesh->mNumBones++;
|
||||
}
|
||||
|
||||
if (mesh->mNumBones) // just for safety
|
||||
{
|
||||
// just for safety
|
||||
if (mesh->mNumBones) {
|
||||
mesh->mBones = new aiBone *[mesh->mNumBones];
|
||||
for (unsigned int q = 0, h = 0; q < meshParser.mJoints.size(); ++q) {
|
||||
if (!piCount[q]) continue;
|
||||
|
@ -457,8 +470,9 @@ void MD5Importer::LoadMD5MeshFile() {
|
|||
|
||||
// there are models which have weights which don't sum to 1 ...
|
||||
ai_real fSum = 0.0;
|
||||
for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights; ++w)
|
||||
for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights; ++w) {
|
||||
fSum += meshSrc.mWeights[w].mWeight;
|
||||
}
|
||||
if (!fSum) {
|
||||
ASSIMP_LOG_ERROR("MD5MESH: The sum of all vertex bone weights is 0");
|
||||
continue;
|
||||
|
@ -466,8 +480,9 @@ void MD5Importer::LoadMD5MeshFile() {
|
|||
|
||||
// process bone weights
|
||||
for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights; ++w) {
|
||||
if (w >= meshSrc.mWeights.size())
|
||||
if (w >= meshSrc.mWeights.size()) {
|
||||
throw DeadlyImportError("MD5MESH: Invalid weight index");
|
||||
}
|
||||
|
||||
MD5::WeightDesc &weightDesc = meshSrc.mWeights[w];
|
||||
if (weightDesc.mWeight < AI_MD5_WEIGHT_EPSILON && weightDesc.mWeight >= -AI_MD5_WEIGHT_EPSILON) {
|
||||
|
@ -504,12 +519,12 @@ void MD5Importer::LoadMD5MeshFile() {
|
|||
for (unsigned int c = 0; c < mesh->mNumFaces; ++c) {
|
||||
mesh->mFaces[c].mNumIndices = 3;
|
||||
mesh->mFaces[c].mIndices = meshSrc.mFaces[c].mIndices;
|
||||
meshSrc.mFaces[c].mIndices = NULL;
|
||||
meshSrc.mFaces[c].mIndices = nullptr;
|
||||
}
|
||||
|
||||
// generate a material for the mesh
|
||||
aiMaterial *mat = new aiMaterial();
|
||||
pScene->mMaterials[n] = mat;
|
||||
mScene->mMaterials[n] = mat;
|
||||
|
||||
// insert the typical doom3 textures:
|
||||
// nnn_local.tga - normal map
|
||||
|
@ -555,10 +570,11 @@ void MD5Importer::LoadMD5AnimFile() {
|
|||
ASSIMP_LOG_WARN("Failed to read MD5ANIM file: " + pFile);
|
||||
return;
|
||||
}
|
||||
|
||||
LoadFileIntoMemory(file.get());
|
||||
|
||||
// parse the basic file structure
|
||||
MD5::MD5Parser parser(mBuffer, fileSize);
|
||||
MD5::MD5Parser parser(mBuffer, mFileSize);
|
||||
|
||||
// load the animation information from the parse tree
|
||||
MD5::MD5AnimParser animParser(parser.mSections);
|
||||
|
@ -568,10 +584,10 @@ void MD5Importer::LoadMD5AnimFile() {
|
|||
animParser.mBaseFrames.size() != animParser.mAnimatedBones.size()) {
|
||||
ASSIMP_LOG_ERROR("MD5ANIM: No frames or animated bones loaded");
|
||||
} else {
|
||||
bHadMD5Anim = true;
|
||||
mHadMD5Anim = true;
|
||||
|
||||
pScene->mAnimations = new aiAnimation *[pScene->mNumAnimations = 1];
|
||||
aiAnimation *anim = pScene->mAnimations[0] = new aiAnimation();
|
||||
mScene->mAnimations = new aiAnimation *[mScene->mNumAnimations = 1];
|
||||
aiAnimation *anim = mScene->mAnimations[0] = new aiAnimation();
|
||||
anim->mNumChannels = (unsigned int)animParser.mAnimatedBones.size();
|
||||
anim->mChannels = new aiNodeAnim *[anim->mNumChannels];
|
||||
for (unsigned int i = 0; i < anim->mNumChannels; ++i) {
|
||||
|
@ -637,15 +653,15 @@ void MD5Importer::LoadMD5AnimFile() {
|
|||
|
||||
// If we didn't build the hierarchy yet (== we didn't load a MD5MESH),
|
||||
// construct it now from the data given in the MD5ANIM.
|
||||
if (!pScene->mRootNode) {
|
||||
pScene->mRootNode = new aiNode();
|
||||
pScene->mRootNode->mName.Set("<MD5_Hierarchy>");
|
||||
if (!mScene->mRootNode) {
|
||||
mScene->mRootNode = new aiNode();
|
||||
mScene->mRootNode->mName.Set("<MD5_Hierarchy>");
|
||||
|
||||
AttachChilds_Anim(-1, pScene->mRootNode, animParser.mAnimatedBones, (const aiNodeAnim **)anim->mChannels);
|
||||
AttachChilds_Anim(-1, mScene->mRootNode, animParser.mAnimatedBones, (const aiNodeAnim **)anim->mChannels);
|
||||
|
||||
// Call SkeletonMeshBuilder to construct a mesh to represent the shape
|
||||
if (pScene->mRootNode->mNumChildren) {
|
||||
SkeletonMeshBuilder skeleton_maker(pScene, pScene->mRootNode->mChildren[0]);
|
||||
if (mScene->mRootNode->mNumChildren) {
|
||||
SkeletonMeshBuilder skeleton_maker(mScene, mScene->mRootNode->mChildren[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -661,11 +677,11 @@ void MD5Importer::LoadMD5CameraFile() {
|
|||
if (!file.get() || !file->FileSize()) {
|
||||
throw DeadlyImportError("Failed to read MD5CAMERA file: " + pFile);
|
||||
}
|
||||
bHadMD5Camera = true;
|
||||
mHadMD5Camera = true;
|
||||
LoadFileIntoMemory(file.get());
|
||||
|
||||
// parse the basic file structure
|
||||
MD5::MD5Parser parser(mBuffer, fileSize);
|
||||
MD5::MD5Parser parser(mBuffer, mFileSize);
|
||||
|
||||
// load the camera animation data from the parse tree
|
||||
MD5::MD5CameraParser cameraParser(parser.mSections);
|
||||
|
@ -679,14 +695,14 @@ void MD5Importer::LoadMD5CameraFile() {
|
|||
|
||||
// Construct output graph - a simple root with a dummy child.
|
||||
// The root node performs the coordinate system conversion
|
||||
aiNode *root = pScene->mRootNode = new aiNode("<MD5CameraRoot>");
|
||||
aiNode *root = mScene->mRootNode = new aiNode("<MD5CameraRoot>");
|
||||
root->mChildren = new aiNode *[root->mNumChildren = 1];
|
||||
root->mChildren[0] = new aiNode("<MD5Camera>");
|
||||
root->mChildren[0]->mParent = root;
|
||||
|
||||
// ... but with one camera assigned to it
|
||||
pScene->mCameras = new aiCamera *[pScene->mNumCameras = 1];
|
||||
aiCamera *cam = pScene->mCameras[0] = new aiCamera();
|
||||
mScene->mCameras = new aiCamera *[mScene->mNumCameras = 1];
|
||||
aiCamera *cam = mScene->mCameras[0] = new aiCamera();
|
||||
cam->mName = "<MD5Camera>";
|
||||
|
||||
// FIXME: Fov is currently set to the first frame's value
|
||||
|
@ -703,8 +719,8 @@ void MD5Importer::LoadMD5CameraFile() {
|
|||
cuts.push_back(static_cast<unsigned int>(frames.size() - 1));
|
||||
}
|
||||
|
||||
pScene->mNumAnimations = static_cast<unsigned int>(cuts.size() - 1);
|
||||
aiAnimation **tmp = pScene->mAnimations = new aiAnimation *[pScene->mNumAnimations];
|
||||
mScene->mNumAnimations = static_cast<unsigned int>(cuts.size() - 1);
|
||||
aiAnimation **tmp = mScene->mAnimations = new aiAnimation *[mScene->mNumAnimations];
|
||||
for (std::vector<unsigned int>::const_iterator it = cuts.begin(); it != cuts.end() - 1; ++it) {
|
||||
|
||||
aiAnimation *anim = *tmp++ = new aiAnimation();
|
||||
|
|
|
@ -4,7 +4,6 @@ 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,
|
||||
|
@ -156,25 +155,25 @@ protected:
|
|||
char *mBuffer;
|
||||
|
||||
/** Size of the file */
|
||||
unsigned int fileSize;
|
||||
unsigned int mFileSize;
|
||||
|
||||
/** Current line number. For debugging purposes */
|
||||
unsigned int iLineNumber;
|
||||
unsigned int mLineNumber;
|
||||
|
||||
/** Scene to be filled */
|
||||
aiScene *pScene;
|
||||
aiScene *mScene;
|
||||
|
||||
/** true if a MD5MESH file has already been parsed */
|
||||
bool bHadMD5Mesh;
|
||||
bool mHadMD5Mesh;
|
||||
|
||||
/** true if a MD5ANIM file has already been parsed */
|
||||
bool bHadMD5Anim;
|
||||
bool mHadMD5Anim;
|
||||
|
||||
/** true if a MD5CAMERA file has already been parsed */
|
||||
bool bHadMD5Camera;
|
||||
bool mHadMD5Camera;
|
||||
|
||||
/** configuration option: prevent anim autoload */
|
||||
bool configNoAutoLoad;
|
||||
bool mCconfigNoAutoLoad;
|
||||
};
|
||||
|
||||
} // end of namespace Assimp
|
||||
|
|
|
@ -45,25 +45,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
* @brief Implementation of the MD5 parser class
|
||||
*/
|
||||
|
||||
|
||||
// internal headers
|
||||
#include "AssetLib/MD5/MD5Loader.h"
|
||||
#include "Material/MaterialSystem.h"
|
||||
|
||||
#include <assimp/fast_atof.h>
|
||||
#include <assimp/ParsingUtils.h>
|
||||
#include <assimp/StringComparison.h>
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
#include <assimp/fast_atof.h>
|
||||
#include <assimp/mesh.h>
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
|
||||
using namespace Assimp;
|
||||
using namespace Assimp::MD5;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Parse the segment structure fo a MD5 file
|
||||
MD5Parser::MD5Parser(char* _buffer, unsigned int _fileSize )
|
||||
{
|
||||
ai_assert(NULL != _buffer && 0 != _fileSize);
|
||||
MD5Parser::MD5Parser(char *_buffer, unsigned int _fileSize) {
|
||||
ai_assert(nullptr != _buffer);
|
||||
ai_assert(0 != _fileSize);
|
||||
|
||||
buffer = _buffer;
|
||||
fileSize = _fileSize;
|
||||
|
@ -78,48 +77,45 @@ MD5Parser::MD5Parser(char* _buffer, unsigned int _fileSize )
|
|||
bool running = true;
|
||||
while (running) {
|
||||
mSections.push_back(Section());
|
||||
Section& sec = mSections.back();
|
||||
if(!ParseSection(sec)) {
|
||||
Section &sec = mSections.back();
|
||||
if (!ParseSection(sec)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !DefaultLogger::isNullLogger()) {
|
||||
if (!DefaultLogger::isNullLogger()) {
|
||||
char szBuffer[128]; // should be sufficiently large
|
||||
::ai_snprintf(szBuffer,128,"MD5Parser end. Parsed %i sections",(int)mSections.size());
|
||||
::ai_snprintf(szBuffer, 128, "MD5Parser end. Parsed %i sections", (int)mSections.size());
|
||||
ASSIMP_LOG_DEBUG(szBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Report error to the log stream
|
||||
/*static*/ AI_WONT_RETURN void MD5Parser::ReportError (const char* error, unsigned int line)
|
||||
{
|
||||
/*static*/ AI_WONT_RETURN void MD5Parser::ReportError(const char *error, unsigned int line) {
|
||||
char szBuffer[1024];
|
||||
::ai_snprintf(szBuffer, 1024, "[MD5] Line %u: %s",line,error);
|
||||
::ai_snprintf(szBuffer, 1024, "[MD5] Line %u: %s", line, error);
|
||||
throw DeadlyImportError(szBuffer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Report warning to the log stream
|
||||
/*static*/ void MD5Parser::ReportWarning (const char* warn, unsigned int line)
|
||||
{
|
||||
/*static*/ void MD5Parser::ReportWarning(const char *warn, unsigned int line) {
|
||||
char szBuffer[1024];
|
||||
::sprintf(szBuffer,"[MD5] Line %u: %s",line,warn);
|
||||
::sprintf(szBuffer, "[MD5] Line %u: %s", line, warn);
|
||||
ASSIMP_LOG_WARN(szBuffer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Parse and validate the MD5 header
|
||||
void MD5Parser::ParseHeader()
|
||||
{
|
||||
void MD5Parser::ParseHeader() {
|
||||
// parse and validate the file version
|
||||
SkipSpaces();
|
||||
if (!TokenMatch(buffer,"MD5Version",10)) {
|
||||
if (!TokenMatch(buffer, "MD5Version", 10)) {
|
||||
ReportError("Invalid MD5 file: MD5Version tag has not been found");
|
||||
}
|
||||
SkipSpaces();
|
||||
unsigned int iVer = ::strtoul10(buffer,(const char**)&buffer);
|
||||
unsigned int iVer = ::strtoul10(buffer, (const char **)&buffer);
|
||||
if (10 != iVer) {
|
||||
ReportError("MD5 version tag is unknown (10 is expected)");
|
||||
}
|
||||
|
@ -127,23 +123,24 @@ void MD5Parser::ParseHeader()
|
|||
|
||||
// print the command line options to the console
|
||||
// FIX: can break the log length limit, so we need to be careful
|
||||
char* sz = buffer;
|
||||
while (!IsLineEnd( *buffer++));
|
||||
ASSIMP_LOG_INFO(std::string(sz,std::min((uintptr_t)MAX_LOG_MESSAGE_LENGTH, (uintptr_t)(buffer-sz))));
|
||||
char *sz = buffer;
|
||||
while (!IsLineEnd(*buffer++))
|
||||
;
|
||||
ASSIMP_LOG_INFO(std::string(sz, std::min((uintptr_t)MAX_LOG_MESSAGE_LENGTH, (uintptr_t)(buffer - sz))));
|
||||
SkipSpacesAndLineEnd();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Recursive MD5 parsing function
|
||||
bool MD5Parser::ParseSection(Section& out)
|
||||
{
|
||||
bool MD5Parser::ParseSection(Section &out) {
|
||||
// store the current line number for use in error messages
|
||||
out.iLineNumber = lineNumber;
|
||||
|
||||
// first parse the name of the section
|
||||
char* sz = buffer;
|
||||
while (!IsSpaceOrNewLine( *buffer))buffer++;
|
||||
out.mName = std::string(sz,(uintptr_t)(buffer-sz));
|
||||
char *sz = buffer;
|
||||
while (!IsSpaceOrNewLine(*buffer))
|
||||
buffer++;
|
||||
out.mName = std::string(sz, (uintptr_t)(buffer - sz));
|
||||
SkipSpaces();
|
||||
|
||||
bool running = true;
|
||||
|
@ -152,8 +149,7 @@ bool MD5Parser::ParseSection(Section& out)
|
|||
// it is a normal section so read all lines
|
||||
buffer++;
|
||||
bool run = true;
|
||||
while (run)
|
||||
{
|
||||
while (run) {
|
||||
if (!SkipSpacesAndLineEnd()) {
|
||||
return false; // seems this was the last section
|
||||
}
|
||||
|
@ -163,25 +159,26 @@ bool MD5Parser::ParseSection(Section& out)
|
|||
}
|
||||
|
||||
out.mElements.push_back(Element());
|
||||
Element& elem = out.mElements.back();
|
||||
Element &elem = out.mElements.back();
|
||||
|
||||
elem.iLineNumber = lineNumber;
|
||||
elem.szStart = buffer;
|
||||
|
||||
// terminate the line with zero
|
||||
while (!IsLineEnd( *buffer))buffer++;
|
||||
while (!IsLineEnd(*buffer))
|
||||
buffer++;
|
||||
if (*buffer) {
|
||||
++lineNumber;
|
||||
*buffer++ = '\0';
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (!IsSpaceOrNewLine(*buffer)) {
|
||||
} else if (!IsSpaceOrNewLine(*buffer)) {
|
||||
// it is an element at global scope. Parse its value and go on
|
||||
sz = buffer;
|
||||
while (!IsSpaceOrNewLine( *buffer++));
|
||||
out.mGlobalValue = std::string(sz,(uintptr_t)(buffer-sz));
|
||||
while (!IsSpaceOrNewLine(*buffer++))
|
||||
;
|
||||
out.mGlobalValue = std::string(sz, (uintptr_t)(buffer - sz));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
@ -193,161 +190,161 @@ bool MD5Parser::ParseSection(Section& out)
|
|||
// Some dirty macros just because they're so funny and easy to debug
|
||||
|
||||
// skip all spaces ... handle EOL correctly
|
||||
#define AI_MD5_SKIP_SPACES() if(!SkipSpaces(&sz)) \
|
||||
MD5Parser::ReportWarning("Unexpected end of line",elem.iLineNumber);
|
||||
#define AI_MD5_SKIP_SPACES() \
|
||||
if (!SkipSpaces(&sz)) \
|
||||
MD5Parser::ReportWarning("Unexpected end of line", elem.iLineNumber);
|
||||
|
||||
// read a triple float in brackets: (1.0 1.0 1.0)
|
||||
// read a triple float in brackets: (1.0 1.0 1.0)
|
||||
#define AI_MD5_READ_TRIPLE(vec) \
|
||||
AI_MD5_SKIP_SPACES(); \
|
||||
if ('(' != *sz++) \
|
||||
MD5Parser::ReportWarning("Unexpected token: ( was expected",elem.iLineNumber); \
|
||||
MD5Parser::ReportWarning("Unexpected token: ( was expected", elem.iLineNumber); \
|
||||
AI_MD5_SKIP_SPACES(); \
|
||||
sz = fast_atoreal_move<float>(sz,(float&)vec.x); \
|
||||
sz = fast_atoreal_move<float>(sz, (float &)vec.x); \
|
||||
AI_MD5_SKIP_SPACES(); \
|
||||
sz = fast_atoreal_move<float>(sz,(float&)vec.y); \
|
||||
sz = fast_atoreal_move<float>(sz, (float &)vec.y); \
|
||||
AI_MD5_SKIP_SPACES(); \
|
||||
sz = fast_atoreal_move<float>(sz,(float&)vec.z); \
|
||||
sz = fast_atoreal_move<float>(sz, (float &)vec.z); \
|
||||
AI_MD5_SKIP_SPACES(); \
|
||||
if (')' != *sz++) \
|
||||
MD5Parser::ReportWarning("Unexpected token: ) was expected",elem.iLineNumber);
|
||||
MD5Parser::ReportWarning("Unexpected token: ) was expected", elem.iLineNumber);
|
||||
|
||||
// parse a string, enclosed in quotation marks or not
|
||||
// parse a string, enclosed in quotation marks or not
|
||||
#define AI_MD5_PARSE_STRING(out) \
|
||||
bool bQuota = (*sz == '\"'); \
|
||||
const char* szStart = sz; \
|
||||
while (!IsSpaceOrNewLine(*sz))++sz; \
|
||||
const char* szEnd = sz; \
|
||||
const char *szStart = sz; \
|
||||
while (!IsSpaceOrNewLine(*sz)) \
|
||||
++sz; \
|
||||
const char *szEnd = sz; \
|
||||
if (bQuota) { \
|
||||
szStart++; \
|
||||
if ('\"' != *(szEnd-=1)) { \
|
||||
if ('\"' != *(szEnd -= 1)) { \
|
||||
MD5Parser::ReportWarning("Expected closing quotation marks in string", \
|
||||
elem.iLineNumber); \
|
||||
continue; \
|
||||
} \
|
||||
} \
|
||||
out.length = (size_t)(szEnd - szStart); \
|
||||
::memcpy(out.data,szStart,out.length); \
|
||||
::memcpy(out.data, szStart, out.length); \
|
||||
out.data[out.length] = '\0';
|
||||
|
||||
// parse a string, enclosed in quotation marks
|
||||
// parse a string, enclosed in quotation marks
|
||||
#define AI_MD5_PARSE_STRING_IN_QUOTATION(out) \
|
||||
while('\"'!=*sz)++sz; \
|
||||
const char* szStart = ++sz; \
|
||||
while('\"'!=*sz)++sz; \
|
||||
const char* szEnd = (sz++); \
|
||||
out.length = (ai_uint32) (szEnd - szStart); \
|
||||
::memcpy(out.data,szStart,out.length); \
|
||||
while ('\"' != *sz) \
|
||||
++sz; \
|
||||
const char *szStart = ++sz; \
|
||||
while ('\"' != *sz) \
|
||||
++sz; \
|
||||
const char *szEnd = (sz++); \
|
||||
out.length = (ai_uint32)(szEnd - szStart); \
|
||||
::memcpy(out.data, szStart, out.length); \
|
||||
out.data[out.length] = '\0';
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// .MD5MESH parsing function
|
||||
MD5MeshParser::MD5MeshParser(SectionList& mSections)
|
||||
{
|
||||
MD5MeshParser::MD5MeshParser(SectionList &mSections) {
|
||||
ASSIMP_LOG_DEBUG("MD5MeshParser begin");
|
||||
|
||||
// now parse all sections
|
||||
for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end();iter != iterEnd;++iter){
|
||||
if ( (*iter).mName == "numMeshes") {
|
||||
for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
|
||||
if ((*iter).mName == "numMeshes") {
|
||||
mMeshes.reserve(::strtoul10((*iter).mGlobalValue.c_str()));
|
||||
}
|
||||
else if ( (*iter).mName == "numJoints") {
|
||||
} else if ((*iter).mName == "numJoints") {
|
||||
mJoints.reserve(::strtoul10((*iter).mGlobalValue.c_str()));
|
||||
}
|
||||
else if ((*iter).mName == "joints") {
|
||||
} else if ((*iter).mName == "joints") {
|
||||
// "origin" -1 ( -0.000000 0.016430 -0.006044 ) ( 0.707107 0.000000 0.707107 )
|
||||
for (const auto & elem : (*iter).mElements){
|
||||
for (const auto &elem : (*iter).mElements) {
|
||||
mJoints.push_back(BoneDesc());
|
||||
BoneDesc& desc = mJoints.back();
|
||||
BoneDesc &desc = mJoints.back();
|
||||
|
||||
const char* sz = elem.szStart;
|
||||
const char *sz = elem.szStart;
|
||||
AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mName);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
|
||||
// negative values, at least -1, is allowed here
|
||||
desc.mParentIndex = (int)strtol10(sz,&sz);
|
||||
desc.mParentIndex = (int)strtol10(sz, &sz);
|
||||
|
||||
AI_MD5_READ_TRIPLE(desc.mPositionXYZ);
|
||||
AI_MD5_READ_TRIPLE(desc.mRotationQuat); // normalized quaternion, so w is not there
|
||||
}
|
||||
}
|
||||
else if ((*iter).mName == "mesh") {
|
||||
} else if ((*iter).mName == "mesh") {
|
||||
mMeshes.push_back(MeshDesc());
|
||||
MeshDesc& desc = mMeshes.back();
|
||||
MeshDesc &desc = mMeshes.back();
|
||||
|
||||
for (const auto & elem : (*iter).mElements){
|
||||
const char* sz = elem.szStart;
|
||||
for (const auto &elem : (*iter).mElements) {
|
||||
const char *sz = elem.szStart;
|
||||
|
||||
// shader attribute
|
||||
if (TokenMatch(sz,"shader",6)) {
|
||||
if (TokenMatch(sz, "shader", 6)) {
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mShader);
|
||||
}
|
||||
// numverts attribute
|
||||
else if (TokenMatch(sz,"numverts",8)) {
|
||||
else if (TokenMatch(sz, "numverts", 8)) {
|
||||
AI_MD5_SKIP_SPACES();
|
||||
desc.mVertices.resize(strtoul10(sz));
|
||||
}
|
||||
// numtris attribute
|
||||
else if (TokenMatch(sz,"numtris",7)) {
|
||||
else if (TokenMatch(sz, "numtris", 7)) {
|
||||
AI_MD5_SKIP_SPACES();
|
||||
desc.mFaces.resize(strtoul10(sz));
|
||||
}
|
||||
// numweights attribute
|
||||
else if (TokenMatch(sz,"numweights",10)) {
|
||||
else if (TokenMatch(sz, "numweights", 10)) {
|
||||
AI_MD5_SKIP_SPACES();
|
||||
desc.mWeights.resize(strtoul10(sz));
|
||||
}
|
||||
// vert attribute
|
||||
// "vert 0 ( 0.394531 0.513672 ) 0 1"
|
||||
else if (TokenMatch(sz,"vert",4)) {
|
||||
else if (TokenMatch(sz, "vert", 4)) {
|
||||
AI_MD5_SKIP_SPACES();
|
||||
const unsigned int idx = ::strtoul10(sz,&sz);
|
||||
const unsigned int idx = ::strtoul10(sz, &sz);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
if (idx >= desc.mVertices.size())
|
||||
desc.mVertices.resize(idx+1);
|
||||
desc.mVertices.resize(idx + 1);
|
||||
|
||||
VertexDesc& vert = desc.mVertices[idx];
|
||||
VertexDesc &vert = desc.mVertices[idx];
|
||||
if ('(' != *sz++)
|
||||
MD5Parser::ReportWarning("Unexpected token: ( was expected",elem.iLineNumber);
|
||||
MD5Parser::ReportWarning("Unexpected token: ( was expected", elem.iLineNumber);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
sz = fast_atoreal_move<float>(sz,(float&)vert.mUV.x);
|
||||
sz = fast_atoreal_move<float>(sz, (float &)vert.mUV.x);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
sz = fast_atoreal_move<float>(sz,(float&)vert.mUV.y);
|
||||
sz = fast_atoreal_move<float>(sz, (float &)vert.mUV.y);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
if (')' != *sz++)
|
||||
MD5Parser::ReportWarning("Unexpected token: ) was expected",elem.iLineNumber);
|
||||
MD5Parser::ReportWarning("Unexpected token: ) was expected", elem.iLineNumber);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
vert.mFirstWeight = ::strtoul10(sz,&sz);
|
||||
vert.mFirstWeight = ::strtoul10(sz, &sz);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
vert.mNumWeights = ::strtoul10(sz,&sz);
|
||||
vert.mNumWeights = ::strtoul10(sz, &sz);
|
||||
}
|
||||
// tri attribute
|
||||
// "tri 0 15 13 12"
|
||||
else if (TokenMatch(sz,"tri",3)) {
|
||||
else if (TokenMatch(sz, "tri", 3)) {
|
||||
AI_MD5_SKIP_SPACES();
|
||||
const unsigned int idx = strtoul10(sz,&sz);
|
||||
const unsigned int idx = strtoul10(sz, &sz);
|
||||
if (idx >= desc.mFaces.size())
|
||||
desc.mFaces.resize(idx+1);
|
||||
desc.mFaces.resize(idx + 1);
|
||||
|
||||
aiFace& face = desc.mFaces[idx];
|
||||
aiFace &face = desc.mFaces[idx];
|
||||
face.mIndices = new unsigned int[face.mNumIndices = 3];
|
||||
for (unsigned int i = 0; i < 3;++i) {
|
||||
for (unsigned int i = 0; i < 3; ++i) {
|
||||
AI_MD5_SKIP_SPACES();
|
||||
face.mIndices[i] = strtoul10(sz,&sz);
|
||||
face.mIndices[i] = strtoul10(sz, &sz);
|
||||
}
|
||||
}
|
||||
// weight attribute
|
||||
// "weight 362 5 0.500000 ( -3.553583 11.893474 9.719339 )"
|
||||
else if (TokenMatch(sz,"weight",6)) {
|
||||
else if (TokenMatch(sz, "weight", 6)) {
|
||||
AI_MD5_SKIP_SPACES();
|
||||
const unsigned int idx = strtoul10(sz,&sz);
|
||||
const unsigned int idx = strtoul10(sz, &sz);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
if (idx >= desc.mWeights.size())
|
||||
desc.mWeights.resize(idx+1);
|
||||
desc.mWeights.resize(idx + 1);
|
||||
|
||||
WeightDesc& weight = desc.mWeights[idx];
|
||||
weight.mBone = strtoul10(sz,&sz);
|
||||
WeightDesc &weight = desc.mWeights[idx];
|
||||
weight.mBone = strtoul10(sz, &sz);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
sz = fast_atoreal_move<float>(sz,weight.mWeight);
|
||||
sz = fast_atoreal_move<float>(sz, weight.mWeight);
|
||||
AI_MD5_READ_TRIPLE(weight.vOffsetPosition);
|
||||
}
|
||||
}
|
||||
|
@ -358,57 +355,54 @@ MD5MeshParser::MD5MeshParser(SectionList& mSections)
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// .MD5ANIM parsing function
|
||||
MD5AnimParser::MD5AnimParser(SectionList& mSections)
|
||||
{
|
||||
MD5AnimParser::MD5AnimParser(SectionList &mSections) {
|
||||
ASSIMP_LOG_DEBUG("MD5AnimParser begin");
|
||||
|
||||
fFrameRate = 24.0f;
|
||||
mNumAnimatedComponents = UINT_MAX;
|
||||
for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end();iter != iterEnd;++iter) {
|
||||
for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
|
||||
if ((*iter).mName == "hierarchy") {
|
||||
// "sheath" 0 63 6
|
||||
for (const auto & elem : (*iter).mElements) {
|
||||
mAnimatedBones.push_back ( AnimBoneDesc () );
|
||||
AnimBoneDesc& desc = mAnimatedBones.back();
|
||||
for (const auto &elem : (*iter).mElements) {
|
||||
mAnimatedBones.push_back(AnimBoneDesc());
|
||||
AnimBoneDesc &desc = mAnimatedBones.back();
|
||||
|
||||
const char* sz = elem.szStart;
|
||||
const char *sz = elem.szStart;
|
||||
AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mName);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
|
||||
// parent index - negative values are allowed (at least -1)
|
||||
desc.mParentIndex = ::strtol10(sz,&sz);
|
||||
desc.mParentIndex = ::strtol10(sz, &sz);
|
||||
|
||||
// flags (highest is 2^6-1)
|
||||
AI_MD5_SKIP_SPACES();
|
||||
if(63 < (desc.iFlags = ::strtoul10(sz,&sz))){
|
||||
MD5Parser::ReportWarning("Invalid flag combination in hierarchy section",elem.iLineNumber);
|
||||
if (63 < (desc.iFlags = ::strtoul10(sz, &sz))) {
|
||||
MD5Parser::ReportWarning("Invalid flag combination in hierarchy section", elem.iLineNumber);
|
||||
}
|
||||
AI_MD5_SKIP_SPACES();
|
||||
|
||||
// index of the first animation keyframe component for this joint
|
||||
desc.iFirstKeyIndex = ::strtoul10(sz,&sz);
|
||||
desc.iFirstKeyIndex = ::strtoul10(sz, &sz);
|
||||
}
|
||||
}
|
||||
else if((*iter).mName == "baseframe") {
|
||||
} else if ((*iter).mName == "baseframe") {
|
||||
// ( -0.000000 0.016430 -0.006044 ) ( 0.707107 0.000242 0.707107 )
|
||||
for (const auto & elem : (*iter).mElements) {
|
||||
const char* sz = elem.szStart;
|
||||
for (const auto &elem : (*iter).mElements) {
|
||||
const char *sz = elem.szStart;
|
||||
|
||||
mBaseFrames.push_back ( BaseFrameDesc () );
|
||||
BaseFrameDesc& desc = mBaseFrames.back();
|
||||
mBaseFrames.push_back(BaseFrameDesc());
|
||||
BaseFrameDesc &desc = mBaseFrames.back();
|
||||
|
||||
AI_MD5_READ_TRIPLE(desc.vPositionXYZ);
|
||||
AI_MD5_READ_TRIPLE(desc.vRotationQuat);
|
||||
}
|
||||
}
|
||||
else if((*iter).mName == "frame") {
|
||||
} else if ((*iter).mName == "frame") {
|
||||
if (!(*iter).mGlobalValue.length()) {
|
||||
MD5Parser::ReportWarning("A frame section must have a frame index",(*iter).iLineNumber);
|
||||
MD5Parser::ReportWarning("A frame section must have a frame index", (*iter).iLineNumber);
|
||||
continue;
|
||||
}
|
||||
|
||||
mFrames.push_back ( FrameDesc () );
|
||||
FrameDesc& desc = mFrames.back();
|
||||
mFrames.push_back(FrameDesc());
|
||||
FrameDesc &desc = mFrames.back();
|
||||
desc.iIndex = strtoul10((*iter).mGlobalValue.c_str());
|
||||
|
||||
// we do already know how much storage we will presumably need
|
||||
|
@ -417,18 +411,17 @@ MD5AnimParser::MD5AnimParser(SectionList& mSections)
|
|||
}
|
||||
|
||||
// now read all elements (continuous list of floats)
|
||||
for (const auto & elem : (*iter).mElements){
|
||||
const char* sz = elem.szStart;
|
||||
for (const auto &elem : (*iter).mElements) {
|
||||
const char *sz = elem.szStart;
|
||||
while (SkipSpacesAndLineEnd(&sz)) {
|
||||
float f;sz = fast_atoreal_move<float>(sz,f);
|
||||
float f;
|
||||
sz = fast_atoreal_move<float>(sz, f);
|
||||
desc.mValues.push_back(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if((*iter).mName == "numFrames") {
|
||||
} else if ((*iter).mName == "numFrames") {
|
||||
mFrames.reserve(strtoul10((*iter).mGlobalValue.c_str()));
|
||||
}
|
||||
else if((*iter).mName == "numJoints") {
|
||||
} else if ((*iter).mName == "numJoints") {
|
||||
const unsigned int num = strtoul10((*iter).mGlobalValue.c_str());
|
||||
mAnimatedBones.reserve(num);
|
||||
|
||||
|
@ -436,12 +429,10 @@ MD5AnimParser::MD5AnimParser(SectionList& mSections)
|
|||
if (UINT_MAX == mNumAnimatedComponents) {
|
||||
mNumAnimatedComponents = num * 6;
|
||||
}
|
||||
}
|
||||
else if((*iter).mName == "numAnimatedComponents") {
|
||||
mAnimatedBones.reserve( strtoul10((*iter).mGlobalValue.c_str()));
|
||||
}
|
||||
else if((*iter).mName == "frameRate") {
|
||||
fast_atoreal_move<float>((*iter).mGlobalValue.c_str(),fFrameRate);
|
||||
} else if ((*iter).mName == "numAnimatedComponents") {
|
||||
mAnimatedBones.reserve(strtoul10((*iter).mGlobalValue.c_str()));
|
||||
} else if ((*iter).mName == "frameRate") {
|
||||
fast_atoreal_move<float>((*iter).mGlobalValue.c_str(), fFrameRate);
|
||||
}
|
||||
}
|
||||
ASSIMP_LOG_DEBUG("MD5AnimParser end");
|
||||
|
@ -449,32 +440,27 @@ MD5AnimParser::MD5AnimParser(SectionList& mSections)
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// .MD5CAMERA parsing function
|
||||
MD5CameraParser::MD5CameraParser(SectionList& mSections)
|
||||
{
|
||||
MD5CameraParser::MD5CameraParser(SectionList &mSections) {
|
||||
ASSIMP_LOG_DEBUG("MD5CameraParser begin");
|
||||
fFrameRate = 24.0f;
|
||||
|
||||
for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end();iter != iterEnd;++iter) {
|
||||
for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
|
||||
if ((*iter).mName == "numFrames") {
|
||||
frames.reserve(strtoul10((*iter).mGlobalValue.c_str()));
|
||||
}
|
||||
else if ((*iter).mName == "frameRate") {
|
||||
fFrameRate = fast_atof ((*iter).mGlobalValue.c_str());
|
||||
}
|
||||
else if ((*iter).mName == "numCuts") {
|
||||
} else if ((*iter).mName == "frameRate") {
|
||||
fFrameRate = fast_atof((*iter).mGlobalValue.c_str());
|
||||
} else if ((*iter).mName == "numCuts") {
|
||||
cuts.reserve(strtoul10((*iter).mGlobalValue.c_str()));
|
||||
} else if ((*iter).mName == "cuts") {
|
||||
for (const auto &elem : (*iter).mElements) {
|
||||
cuts.push_back(strtoul10(elem.szStart) + 1);
|
||||
}
|
||||
else if ((*iter).mName == "cuts") {
|
||||
for (const auto & elem : (*iter).mElements){
|
||||
cuts.push_back(strtoul10(elem.szStart)+1);
|
||||
}
|
||||
}
|
||||
else if ((*iter).mName == "camera") {
|
||||
for (const auto & elem : (*iter).mElements){
|
||||
const char* sz = elem.szStart;
|
||||
} else if ((*iter).mName == "camera") {
|
||||
for (const auto &elem : (*iter).mElements) {
|
||||
const char *sz = elem.szStart;
|
||||
|
||||
frames.push_back(CameraAnimFrameDesc());
|
||||
CameraAnimFrameDesc& cur = frames.back();
|
||||
CameraAnimFrameDesc &cur = frames.back();
|
||||
AI_MD5_READ_TRIPLE(cur.vPositionXYZ);
|
||||
AI_MD5_READ_TRIPLE(cur.vRotationQuat);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
|
@ -484,4 +470,3 @@ MD5CameraParser::MD5CameraParser(SectionList& mSections)
|
|||
}
|
||||
ASSIMP_LOG_DEBUG("MD5CameraParser end");
|
||||
}
|
||||
|
||||
|
|
|
@ -267,7 +267,7 @@ void MDCImporter::InternReadFile(
|
|||
|
||||
// necessary that we don't crash if an exception occurs
|
||||
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
||||
pScene->mMeshes[i] = NULL;
|
||||
pScene->mMeshes[i] = nullptr;
|
||||
}
|
||||
|
||||
// now read all surfaces
|
||||
|
@ -347,8 +347,8 @@ void MDCImporter::InternReadFile(
|
|||
|
||||
#endif
|
||||
|
||||
const MDC::CompressedVertex *pcCVerts = NULL;
|
||||
int16_t *mdcCompVert = NULL;
|
||||
const MDC::CompressedVertex *pcCVerts = nullptr;
|
||||
int16_t *mdcCompVert = nullptr;
|
||||
|
||||
// access compressed frames for large frame numbers, but never for the first
|
||||
if (this->configFrameID && pcSurface->ulNumCompFrames > 0) {
|
||||
|
@ -359,7 +359,7 @@ void MDCImporter::InternReadFile(
|
|||
pcSurface->ulOffsetCompVerts) +
|
||||
*mdcCompVert * pcSurface->ulNumVertices;
|
||||
} else
|
||||
mdcCompVert = NULL;
|
||||
mdcCompVert = nullptr;
|
||||
}
|
||||
|
||||
// copy all faces
|
||||
|
|
|
@ -829,7 +829,7 @@ void HL1MDLLoader::read_meshes() {
|
|||
}
|
||||
} else {
|
||||
for (int faceIdx = 0; faceIdx < num_faces; ++faceIdx) {
|
||||
if (i & 1) {
|
||||
if (faceIdx & 1) {
|
||||
// Preserve winding order.
|
||||
mesh_faces.push_back(HL1MeshFace{
|
||||
tricmds[faceIdx + 1],
|
||||
|
|
|
@ -222,12 +222,14 @@ void HL1MDLLoader::load_file_into_buffer(const std::string &file_path, unsigned
|
|||
|
||||
std::unique_ptr<IOStream> file(io_->Open(file_path));
|
||||
|
||||
if (file.get() == NULL)
|
||||
if (file.get() == nullptr) {
|
||||
throw DeadlyImportError("Failed to open MDL file " + DefaultIOSystem::fileName(file_path) + ".");
|
||||
}
|
||||
|
||||
const size_t file_size = file->FileSize();
|
||||
if (file_size < sizeof(MDLFileHeader))
|
||||
if (file_size < sizeof(MDLFileHeader)) {
|
||||
throw DeadlyImportError("MDL file is too small.");
|
||||
}
|
||||
|
||||
buffer = new unsigned char[1 + file_size];
|
||||
file->Read((void *)buffer, 1, file_size);
|
||||
|
|
|
@ -278,7 +278,7 @@ void MDLImporter::SizeCheck(const void *szPos) {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Just for debugging purposes
|
||||
void MDLImporter::SizeCheck(const void *szPos, const char *szFile, unsigned int iLine) {
|
||||
ai_assert(NULL != szFile);
|
||||
ai_assert(nullptr != szFile);
|
||||
if (!szPos || (const unsigned char *)szPos > mBuffer + iFileSize) {
|
||||
// remove a directory if there is one
|
||||
const char *szFilePtr = ::strrchr(szFile, '\\');
|
||||
|
@ -304,7 +304,7 @@ void MDLImporter::SizeCheck(const void *szPos, const char *szFile, unsigned int
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Validate a quake file header
|
||||
void MDLImporter::ValidateHeader_Quake1(const MDL::Header *pcHeader) {
|
||||
// some values may not be NULL
|
||||
// some values may not be nullptr
|
||||
if (!pcHeader->num_frames)
|
||||
throw DeadlyImportError("[Quake 1 MDL] There are no frames in the file");
|
||||
|
||||
|
@ -359,7 +359,7 @@ void FlipQuakeHeader(BE_NCONST MDL::Header *pcHeader) {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Read a Quake 1 file
|
||||
void MDLImporter::InternReadFile_Quake1() {
|
||||
ai_assert(NULL != pScene);
|
||||
ai_assert(nullptr != pScene);
|
||||
|
||||
BE_NCONST MDL::Header *pcHeader = (BE_NCONST MDL::Header *)this->mBuffer;
|
||||
|
||||
|
@ -548,7 +548,7 @@ void MDLImporter::SetupMaterialProperties_3DGS_MDL5_Quake1() {
|
|||
delete pScene->mTextures[0];
|
||||
delete[] pScene->mTextures;
|
||||
|
||||
pScene->mTextures = NULL;
|
||||
pScene->mTextures = nullptr;
|
||||
pScene->mNumTextures = 0;
|
||||
} else {
|
||||
clr.b = clr.a = clr.g = clr.r = 1.0f;
|
||||
|
@ -572,7 +572,7 @@ void MDLImporter::SetupMaterialProperties_3DGS_MDL5_Quake1() {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Read a MDL 3,4,5 file
|
||||
void MDLImporter::InternReadFile_3DGS_MDL345() {
|
||||
ai_assert(NULL != pScene);
|
||||
ai_assert(nullptr != pScene);
|
||||
|
||||
// the header of MDL 3/4/5 is nearly identical to the original Quake1 header
|
||||
BE_NCONST MDL::Header *pcHeader = (BE_NCONST MDL::Header *)this->mBuffer;
|
||||
|
@ -791,7 +791,7 @@ void MDLImporter::ImportUVCoordinate_3DGS_MDL345(
|
|||
aiVector3D &vOut,
|
||||
const MDL::TexCoord_MDL3 *pcSrc,
|
||||
unsigned int iIndex) {
|
||||
ai_assert(NULL != pcSrc);
|
||||
ai_assert(nullptr != pcSrc);
|
||||
const MDL::Header *const pcHeader = (const MDL::Header *)this->mBuffer;
|
||||
|
||||
// validate UV indices
|
||||
|
@ -860,7 +860,7 @@ void MDLImporter::CalculateUVCoordinates_MDL5() {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Validate the header of a MDL7 file
|
||||
void MDLImporter::ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7 *pcHeader) {
|
||||
ai_assert(NULL != pcHeader);
|
||||
ai_assert(nullptr != pcHeader);
|
||||
|
||||
// There are some fixed sizes ...
|
||||
if (sizeof(MDL::ColorValue_MDL7) != pcHeader->colorvalue_stc_size) {
|
||||
|
@ -887,7 +887,7 @@ void MDLImporter::ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7 *pcHeader) {
|
|||
void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7 **apcOutBones) {
|
||||
const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7 *)this->mBuffer;
|
||||
const MDL::Bone_MDL7 *pcBones = (const MDL::Bone_MDL7 *)(pcHeader + 1);
|
||||
ai_assert(NULL != apcOutBones);
|
||||
ai_assert(nullptr != apcOutBones);
|
||||
|
||||
// first find the bone that has NO parent, calculate the
|
||||
// animation matrix for it, then go on and search for the next parent
|
||||
|
@ -979,7 +979,7 @@ MDL::IntBone_MDL7 **MDLImporter::LoadBones_3DGS_MDL7() {
|
|||
AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_32_CHARS != pcHeader->bone_stc_size &&
|
||||
AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE != pcHeader->bone_stc_size) {
|
||||
ASSIMP_LOG_WARN("Unknown size of bone data structure");
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MDL::IntBone_MDL7 **apcBonesOut = new MDL::IntBone_MDL7 *[pcHeader->bones_num];
|
||||
|
@ -990,7 +990,7 @@ MDL::IntBone_MDL7 **MDLImporter::LoadBones_3DGS_MDL7() {
|
|||
CalcAbsBoneMatrices_3DGS_MDL7(apcBonesOut);
|
||||
return apcBonesOut;
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -1014,7 +1014,7 @@ void MDLImporter::ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7 &groupInfo,
|
|||
unsigned int iIndex = pcGroupTris->v_index[c];
|
||||
if (iIndex > (unsigned int)groupInfo.pcGroup->numverts) {
|
||||
// (we might need to read this section a second time - to process frame vertices correctly)
|
||||
pcGroupTris->v_index[c] = (uint16_t) (iIndex = groupInfo.pcGroup->numverts - 1 );
|
||||
pcGroupTris->v_index[c] = (uint16_t)(iIndex = groupInfo.pcGroup->numverts - 1);
|
||||
ASSIMP_LOG_WARN("Index overflow in MDL7 vertex list");
|
||||
}
|
||||
|
||||
|
@ -1337,7 +1337,7 @@ void MDLImporter::SortByMaterials_3DGS_MDL7(
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Read a MDL7 file
|
||||
void MDLImporter::InternReadFile_3DGS_MDL7() {
|
||||
ai_assert(NULL != pScene);
|
||||
ai_assert(nullptr != pScene);
|
||||
|
||||
MDL::IntSharedData_MDL7 sharedData;
|
||||
|
||||
|
@ -1368,7 +1368,7 @@ void MDLImporter::InternReadFile_3DGS_MDL7() {
|
|||
|
||||
// load all bones (they are shared by all groups, so
|
||||
// we'll need to add them to all groups/meshes later)
|
||||
// apcBonesOut is a list of all bones or NULL if they could not been loaded
|
||||
// apcBonesOut is a list of all bones or nullptr if they could not been loaded
|
||||
szCurrent += pcHeader->bones_num * pcHeader->bone_stc_size;
|
||||
sharedData.apcOutBones = this->LoadBones_3DGS_MDL7();
|
||||
|
||||
|
@ -1558,9 +1558,9 @@ void MDLImporter::InternReadFile_3DGS_MDL7() {
|
|||
if (1 == pScene->mRootNode->mNumChildren && !sharedData.apcOutBones) {
|
||||
aiNode *pcOldRoot = this->pScene->mRootNode;
|
||||
pScene->mRootNode = pcOldRoot->mChildren[0];
|
||||
pcOldRoot->mChildren[0] = NULL;
|
||||
pcOldRoot->mChildren[0] = nullptr;
|
||||
delete pcOldRoot;
|
||||
pScene->mRootNode->mParent = NULL;
|
||||
pScene->mRootNode->mParent = nullptr;
|
||||
} else
|
||||
pScene->mRootNode->mName.Set("<mesh_root>");
|
||||
|
||||
|
@ -1665,7 +1665,8 @@ void MDLImporter::ParseBoneTrafoKeys_3DGS_MDL7(
|
|||
// Attach bones to the output nodegraph
|
||||
void MDLImporter::AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7 **apcBones,
|
||||
aiNode *pcParent, uint16_t iParentIndex) {
|
||||
ai_assert(NULL != apcBones && NULL != pcParent);
|
||||
ai_assert(nullptr != apcBones);
|
||||
ai_assert(nullptr != pcParent);
|
||||
|
||||
// get a pointer to the header ...
|
||||
const MDL::Header_MDL7 *const pcHeader = (const MDL::Header_MDL7 *)this->mBuffer;
|
||||
|
@ -1696,7 +1697,7 @@ void MDLImporter::AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7 **apcBon
|
|||
// Build output animations
|
||||
void MDLImporter::BuildOutputAnims_3DGS_MDL7(
|
||||
const MDL::IntBone_MDL7 **apcBonesOut) {
|
||||
ai_assert(NULL != apcBonesOut);
|
||||
ai_assert(nullptr != apcBonesOut);
|
||||
const MDL::Header_MDL7 *const pcHeader = (const MDL::Header_MDL7 *)mBuffer;
|
||||
|
||||
// one animation ...
|
||||
|
@ -1755,8 +1756,8 @@ void MDLImporter::BuildOutputAnims_3DGS_MDL7(
|
|||
void MDLImporter::AddAnimationBoneTrafoKey_3DGS_MDL7(unsigned int iTrafo,
|
||||
const MDL::BoneTransform_MDL7 *pcBoneTransforms,
|
||||
MDL::IntBone_MDL7 **apcBonesOut) {
|
||||
ai_assert(NULL != pcBoneTransforms);
|
||||
ai_assert(NULL != apcBonesOut);
|
||||
ai_assert(nullptr != pcBoneTransforms);
|
||||
ai_assert(nullptr != apcBonesOut);
|
||||
|
||||
// first .. get the transformation matrix
|
||||
aiMatrix4x4 mTransform;
|
||||
|
@ -1920,7 +1921,9 @@ void MDLImporter::JoinSkins_3DGS_MDL7(
|
|||
aiMaterial *pcMat1,
|
||||
aiMaterial *pcMat2,
|
||||
aiMaterial *pcMatOut) {
|
||||
ai_assert(NULL != pcMat1 && NULL != pcMat2 && NULL != pcMatOut);
|
||||
ai_assert(nullptr != pcMat1);
|
||||
ai_assert(nullptr != pcMat2);
|
||||
ai_assert(nullptr != pcMatOut);
|
||||
|
||||
// first create a full copy of the first skin property set
|
||||
// and assign it to the output material
|
||||
|
|
|
@ -320,7 +320,7 @@ protected:
|
|||
/** Load the bone list of a MDL7 file
|
||||
* \return If the bones could be loaded successfully, a valid
|
||||
* array containing pointers to a temporary bone
|
||||
* representation. NULL if the bones could not be loaded.
|
||||
* representation. nullptr if the bones could not be loaded.
|
||||
*/
|
||||
MDL::IntBone_MDL7** LoadBones_3DGS_MDL7();
|
||||
|
||||
|
|
|
@ -364,7 +364,7 @@ void MDLImporter::ParseTextureColorData(const unsigned char *szData,
|
|||
void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char *szData,
|
||||
unsigned int iType,
|
||||
unsigned int *piSkip) {
|
||||
ai_assert(NULL != piSkip);
|
||||
ai_assert(nullptr != piSkip);
|
||||
bool bNoRead = *piSkip == UINT_MAX;
|
||||
|
||||
// allocate a new texture object
|
||||
|
@ -428,7 +428,7 @@ void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char *szData,
|
|||
delete[] pc;
|
||||
}
|
||||
} else {
|
||||
pcNew->pcData = NULL;
|
||||
pcNew->pcData = nullptr;
|
||||
delete pcNew;
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -134,7 +134,7 @@ void MMDImporter::InternReadFile(const std::string &file, aiScene *pScene,
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
void MMDImporter::CreateDataFromImport(const pmx::PmxModel *pModel,
|
||||
aiScene *pScene) {
|
||||
if (pModel == NULL) {
|
||||
if (pModel == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@ namespace pmd
|
|||
stream->read((char*) &index_count, sizeof(uint32_t));
|
||||
stream->read((char*) &buffer, sizeof(char) * 20);
|
||||
char* pstar = strchr(buffer, '*');
|
||||
if (NULL == pstar)
|
||||
if (nullptr == pstar)
|
||||
{
|
||||
texture_filename = std::string(buffer);
|
||||
sphere_filename.clear();
|
||||
|
|
|
@ -657,7 +657,7 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
|
|||
}
|
||||
// fixup to pass the validation if not a single animation channel is non-trivial
|
||||
if (!anim->mNumChannels) {
|
||||
anim->mChannels = NULL;
|
||||
anim->mChannels = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,7 +154,7 @@ void NFFImporter::LoadNFF2MaterialTable(std::vector<ShadingInfo> &output,
|
|||
return;
|
||||
}
|
||||
|
||||
ShadingInfo *curShader = NULL;
|
||||
ShadingInfo *curShader = nullptr;
|
||||
|
||||
// No read the file line per line
|
||||
char line[4096];
|
||||
|
@ -238,9 +238,9 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
|||
|
||||
bool hasCam = false;
|
||||
|
||||
MeshInfo *currentMeshWithNormals = NULL;
|
||||
MeshInfo *currentMesh = NULL;
|
||||
MeshInfo *currentMeshWithUVCoords = NULL;
|
||||
MeshInfo *currentMeshWithNormals = nullptr;
|
||||
MeshInfo *currentMesh = nullptr;
|
||||
MeshInfo *currentMeshWithUVCoords = nullptr;
|
||||
|
||||
ShadingInfo s; // current material info
|
||||
|
||||
|
@ -542,7 +542,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
|||
// search the list of all shaders we have for this object whether
|
||||
// there is an identical one. In this case, we append our mesh
|
||||
// data to it.
|
||||
MeshInfo *mesh = NULL;
|
||||
MeshInfo *mesh = nullptr;
|
||||
for (std::vector<MeshInfo>::iterator it = meshes.begin() + objStart, end = meshes.end();
|
||||
it != end; ++it) {
|
||||
if ((*it).shader == shader && (*it).matIndex == matIdx) {
|
||||
|
@ -603,11 +603,11 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
|||
while (GetNextLine(buffer, line)) {
|
||||
sz = line;
|
||||
if ('p' == line[0] || TokenMatch(sz, "tpp", 3)) {
|
||||
MeshInfo *out = NULL;
|
||||
MeshInfo *out = nullptr;
|
||||
|
||||
// 'tpp' - texture polygon patch primitive
|
||||
if ('t' == line[0]) {
|
||||
currentMeshWithUVCoords = NULL;
|
||||
currentMeshWithUVCoords = nullptr;
|
||||
for (auto &mesh : meshesWithUVCoords) {
|
||||
if (mesh.shader == s) {
|
||||
currentMeshWithUVCoords = &mesh;
|
||||
|
@ -624,7 +624,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
|||
}
|
||||
// 'pp' - polygon patch primitive
|
||||
else if ('p' == line[1]) {
|
||||
currentMeshWithNormals = NULL;
|
||||
currentMeshWithNormals = nullptr;
|
||||
for (auto &mesh : meshesWithNormals) {
|
||||
if (mesh.shader == s) {
|
||||
currentMeshWithNormals = &mesh;
|
||||
|
@ -642,7 +642,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
|||
}
|
||||
// 'p' - polygon primitive
|
||||
else {
|
||||
currentMesh = NULL;
|
||||
currentMesh = nullptr;
|
||||
for (auto &mesh : meshes) {
|
||||
if (mesh.shader == s) {
|
||||
currentMesh = &mesh;
|
||||
|
@ -969,8 +969,8 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
|||
root->mNumChildren = numNamed + (hasCam ? 1 : 0) + (unsigned int)lights.size();
|
||||
root->mNumMeshes = pScene->mNumMeshes - numNamed;
|
||||
|
||||
aiNode **ppcChildren = NULL;
|
||||
unsigned int *pMeshes = NULL;
|
||||
aiNode **ppcChildren = nullptr;
|
||||
unsigned int *pMeshes = nullptr;
|
||||
if (root->mNumMeshes)
|
||||
pMeshes = root->mMeshes = new unsigned int[root->mNumMeshes];
|
||||
if (root->mNumChildren)
|
||||
|
@ -1037,7 +1037,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
|||
mesh->mNumFaces = (unsigned int)src.faces.size();
|
||||
|
||||
// Generate sub nodes for named meshes
|
||||
if (src.name[0] && NULL != ppcChildren) {
|
||||
if (src.name[0] && nullptr != ppcChildren) {
|
||||
aiNode *const node = *ppcChildren = new aiNode();
|
||||
node->mParent = root;
|
||||
node->mNumMeshes = 1;
|
||||
|
|
|
@ -70,14 +70,14 @@ void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
|
|||
// we're still here - export successfully completed. Write both the main OBJ file and the material script
|
||||
{
|
||||
std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
|
||||
if(outfile == NULL) {
|
||||
if (outfile == nullptr) {
|
||||
throw DeadlyExportError("could not open output .obj file: " + std::string(pFile));
|
||||
}
|
||||
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
|
||||
}
|
||||
{
|
||||
std::unique_ptr<IOStream> outfile (pIOSystem->Open(exporter.GetMaterialLibFileName(),"wt"));
|
||||
if(outfile == NULL) {
|
||||
if (outfile == nullptr) {
|
||||
throw DeadlyExportError("could not open output .mtl file: " + std::string(exporter.GetMaterialLibFileName()));
|
||||
}
|
||||
outfile->Write( exporter.mOutputMat.str().c_str(), static_cast<size_t>(exporter.mOutputMat.tellp()),1);
|
||||
|
@ -97,7 +97,7 @@ void ExportSceneObjNoMtl(const char* pFile,IOSystem* pIOSystem, const aiScene* p
|
|||
// we're still here - export successfully completed. Write both the main OBJ file and the material script
|
||||
{
|
||||
std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
|
||||
if(outfile == NULL) {
|
||||
if (outfile == nullptr) {
|
||||
throw DeadlyExportError("could not open output .obj file: " + std::string(pFile));
|
||||
}
|
||||
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
|
||||
|
|
|
@ -41,12 +41,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#pragma once
|
||||
#ifndef OBJ_FILEDATA_H_INC
|
||||
# define OBJ_FILEDATA_H_INC
|
||||
#define OBJ_FILEDATA_H_INC
|
||||
|
||||
# include <assimp/mesh.h>
|
||||
# include <assimp/types.h>
|
||||
# include <map>
|
||||
# include <vector>
|
||||
#include <assimp/mesh.h>
|
||||
#include <assimp/types.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace Assimp {
|
||||
namespace ObjFile {
|
||||
|
@ -215,7 +215,11 @@ struct Mesh {
|
|||
|
||||
/// Constructor
|
||||
explicit Mesh(const std::string &name) :
|
||||
m_name(name), m_pMaterial(NULL), m_uiNumIndices(0), m_uiMaterialIndex(NoMaterial), m_hasNormals(false) {
|
||||
m_name(name),
|
||||
m_pMaterial(nullptr),
|
||||
m_uiNumIndices(0),
|
||||
m_uiMaterialIndex(NoMaterial),
|
||||
m_hasNormals(false) {
|
||||
memset(m_uiUVCoordinates, 0, sizeof(unsigned int) * AI_MAX_NUMBER_OF_TEXTURECOORDS);
|
||||
}
|
||||
|
||||
|
@ -275,13 +279,13 @@ struct Model {
|
|||
//! \brief The default class constructor
|
||||
Model() :
|
||||
m_ModelName(""),
|
||||
m_pCurrent(NULL),
|
||||
m_pCurrentMaterial(NULL),
|
||||
m_pDefaultMaterial(NULL),
|
||||
m_pGroupFaceIDs(NULL),
|
||||
m_pCurrent(nullptr),
|
||||
m_pCurrentMaterial(nullptr),
|
||||
m_pDefaultMaterial(nullptr),
|
||||
m_pGroupFaceIDs(nullptr),
|
||||
m_strActiveGroup(""),
|
||||
m_TextureCoordDim(0),
|
||||
m_pCurrentMesh(NULL) {
|
||||
m_pCurrentMesh(nullptr) {
|
||||
// empty
|
||||
}
|
||||
|
||||
|
|
|
@ -252,9 +252,9 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model *pModel, aiScene
|
|||
aiNode *ObjFileImporter::createNodes(const ObjFile::Model *pModel, const ObjFile::Object *pObject,
|
||||
aiNode *pParent, aiScene *pScene,
|
||||
std::vector<aiMesh *> &MeshArray) {
|
||||
ai_assert(NULL != pModel);
|
||||
if (NULL == pObject) {
|
||||
return NULL;
|
||||
ai_assert(nullptr != pModel);
|
||||
if (nullptr == pObject) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Store older mesh size to be able to computes mesh offsets for new mesh instances
|
||||
|
@ -264,7 +264,7 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model *pModel, const ObjFile
|
|||
pNode->mName = pObject->m_strObjName;
|
||||
|
||||
// If we have a parent node, store it
|
||||
ai_assert(NULL != pParent);
|
||||
ai_assert(nullptr != pParent);
|
||||
appendChildToParentNode(pParent, pNode);
|
||||
|
||||
for (size_t i = 0; i < pObject->m_Meshes.size(); ++i) {
|
||||
|
@ -308,20 +308,20 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model *pModel, const ObjFile
|
|||
// Create topology data
|
||||
aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjFile::Object *pData, unsigned int meshIndex) {
|
||||
// Checking preconditions
|
||||
ai_assert(NULL != pModel);
|
||||
ai_assert(nullptr != pModel);
|
||||
|
||||
if (NULL == pData) {
|
||||
return NULL;
|
||||
if (nullptr == pData) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Create faces
|
||||
ObjFile::Mesh *pObjMesh = pModel->m_Meshes[meshIndex];
|
||||
if (!pObjMesh) {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (pObjMesh->m_Faces.empty()) {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<aiMesh> pMesh(new aiMesh);
|
||||
|
@ -331,7 +331,7 @@ aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjF
|
|||
|
||||
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) {
|
||||
ObjFile::Face *const inp = pObjMesh->m_Faces[index];
|
||||
ai_assert(NULL != inp);
|
||||
ai_assert(nullptr != inp);
|
||||
|
||||
if (inp->m_PrimitiveType == aiPrimitiveType_LINE) {
|
||||
pMesh->mNumFaces += static_cast<unsigned int>(inp->m_vertices.size() - 1);
|
||||
|
@ -400,7 +400,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
|
|||
aiMesh *pMesh,
|
||||
unsigned int numIndices) {
|
||||
// Checking preconditions
|
||||
ai_assert(NULL != pCurrentObject);
|
||||
ai_assert(nullptr != pCurrentObject);
|
||||
|
||||
// Break, if no faces are stored in object
|
||||
if (pCurrentObject->m_Meshes.empty())
|
||||
|
@ -408,7 +408,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
|
|||
|
||||
// Get current mesh
|
||||
ObjFile::Mesh *pObjMesh = pModel->m_Meshes[uiMeshIndex];
|
||||
if (NULL == pObjMesh || pObjMesh->m_uiNumIndices < 1) {
|
||||
if (nullptr == pObjMesh || pObjMesh->m_uiNumIndices < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -561,7 +561,7 @@ void ObjFileImporter::addTextureMappingModeProperty(aiMaterial *mat, aiTextureTy
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Creates the material
|
||||
void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pScene) {
|
||||
if (NULL == pScene) {
|
||||
if (nullptr == pScene) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -717,8 +717,8 @@ void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pSc
|
|||
// Appends this node to the parent node
|
||||
void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild) {
|
||||
// Checking preconditions
|
||||
ai_assert(NULL != pParent);
|
||||
ai_assert(NULL != pChild);
|
||||
ai_assert(nullptr != pParent);
|
||||
ai_assert(nullptr != pChild);
|
||||
|
||||
// Assign parent to child
|
||||
pChild->mParent = pParent;
|
||||
|
|
|
@ -200,7 +200,7 @@ void ObjFileMtlImporter::load() {
|
|||
// -------------------------------------------------------------------
|
||||
// Loads a color definition
|
||||
void ObjFileMtlImporter::getColorRGBA(aiColor3D *pColor) {
|
||||
ai_assert(NULL != pColor);
|
||||
ai_assert(nullptr != pColor);
|
||||
|
||||
ai_real r(0.0), g(0.0), b(0.0);
|
||||
m_DataIt = getFloat<DataArrayIt>(m_DataIt, m_DataItEnd, r);
|
||||
|
@ -274,7 +274,7 @@ void ObjFileMtlImporter::createMaterial() {
|
|||
// -------------------------------------------------------------------
|
||||
// Gets a texture name from data.
|
||||
void ObjFileMtlImporter::getTexture() {
|
||||
aiString *out(NULL);
|
||||
aiString *out(nullptr);
|
||||
int clampIndex = -1;
|
||||
|
||||
const char *pPtr(&(*m_DataIt));
|
||||
|
@ -332,7 +332,7 @@ void ObjFileMtlImporter::getTexture() {
|
|||
|
||||
std::string texture;
|
||||
m_DataIt = getName<DataArrayIt>(m_DataIt, m_DataItEnd, texture);
|
||||
if (NULL != out) {
|
||||
if (nullptr != out) {
|
||||
out->Set(texture);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -253,7 +253,6 @@ static bool isDataDefinitionEnd(const char *tmp) {
|
|||
if (*tmp == '\\') {
|
||||
tmp++;
|
||||
if (IsLineEnd(*tmp)) {
|
||||
tmp++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -495,19 +494,19 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
|
|||
}
|
||||
|
||||
// Set active material, if one set
|
||||
if (NULL != m_pModel->m_pCurrentMaterial) {
|
||||
if (nullptr != m_pModel->m_pCurrentMaterial) {
|
||||
face->m_pMaterial = m_pModel->m_pCurrentMaterial;
|
||||
} else {
|
||||
face->m_pMaterial = m_pModel->m_pDefaultMaterial;
|
||||
}
|
||||
|
||||
// Create a default object, if nothing is there
|
||||
if (NULL == m_pModel->m_pCurrent) {
|
||||
if (nullptr == m_pModel->m_pCurrent) {
|
||||
createObject(DefaultObjName);
|
||||
}
|
||||
|
||||
// Assign face to mesh
|
||||
if (NULL == m_pModel->m_pCurrentMesh) {
|
||||
if (nullptr == m_pModel->m_pCurrentMesh) {
|
||||
createMesh(DefaultObjName);
|
||||
}
|
||||
|
||||
|
@ -754,7 +753,7 @@ void ObjFileParser::getObjectName() {
|
|||
std::string strObjectName(pStart, &(*m_DataIt));
|
||||
if (!strObjectName.empty()) {
|
||||
// Reset current object
|
||||
m_pModel->m_pCurrent = NULL;
|
||||
m_pModel->m_pCurrent = nullptr;
|
||||
|
||||
// Search for actual object
|
||||
for (std::vector<ObjFile::Object *>::const_iterator it = m_pModel->m_Objects.begin();
|
||||
|
@ -767,7 +766,7 @@ void ObjFileParser::getObjectName() {
|
|||
}
|
||||
|
||||
// Allocate a new object, if current one was not found before
|
||||
if (NULL == m_pModel->m_pCurrent) {
|
||||
if (nullptr == m_pModel->m_pCurrent) {
|
||||
createObject(strObjectName);
|
||||
}
|
||||
}
|
||||
|
@ -776,7 +775,7 @@ void ObjFileParser::getObjectName() {
|
|||
// -------------------------------------------------------------------
|
||||
// Creates a new object instance
|
||||
void ObjFileParser::createObject(const std::string &objName) {
|
||||
ai_assert(NULL != m_pModel);
|
||||
ai_assert(nullptr != m_pModel);
|
||||
|
||||
m_pModel->m_pCurrent = new ObjFile::Object;
|
||||
m_pModel->m_pCurrent->m_strObjName = objName;
|
||||
|
@ -793,11 +792,12 @@ void ObjFileParser::createObject(const std::string &objName) {
|
|||
// -------------------------------------------------------------------
|
||||
// Creates a new mesh
|
||||
void ObjFileParser::createMesh(const std::string &meshName) {
|
||||
ai_assert(NULL != m_pModel);
|
||||
ai_assert(nullptr != m_pModel);
|
||||
|
||||
m_pModel->m_pCurrentMesh = new ObjFile::Mesh(meshName);
|
||||
m_pModel->m_Meshes.push_back(m_pModel->m_pCurrentMesh);
|
||||
unsigned int meshId = static_cast<unsigned int>(m_pModel->m_Meshes.size() - 1);
|
||||
if (NULL != m_pModel->m_pCurrent) {
|
||||
if (nullptr != m_pModel->m_pCurrent) {
|
||||
m_pModel->m_pCurrent->m_Meshes.push_back(meshId);
|
||||
} else {
|
||||
ASSIMP_LOG_ERROR("OBJ: No object detected to attach a new mesh instance.");
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue