mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-04-29 16:25:42 +00:00
commit
5c08846a25
663 changed files with 106600 additions and 21826 deletions
|
|
@ -48,7 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// internal headers
|
// internal headers
|
||||||
#include "3DSLoader.h"
|
#include "3DSLoader.h"
|
||||||
#include "TargetAnimation.h"
|
#include "Common/TargetAnimation.h"
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/StringComparison.h>
|
#include <assimp/StringComparison.h>
|
||||||
|
|
@ -72,7 +72,7 @@ void Discreet3DSImporter::ReplaceDefaultMaterial()
|
||||||
unsigned int idx( NotSet );
|
unsigned int idx( NotSet );
|
||||||
for (unsigned int i = 0; i < mScene->mMaterials.size();++i)
|
for (unsigned int i = 0; i < mScene->mMaterials.size();++i)
|
||||||
{
|
{
|
||||||
std::string &s = mScene->mMaterials[i].mName;
|
std::string s = mScene->mMaterials[i].mName;
|
||||||
for ( std::string::iterator it = s.begin(); it != s.end(); ++it ) {
|
for ( std::string::iterator it = s.begin(); it != s.end(); ++it ) {
|
||||||
*it = static_cast< char >( ::tolower( *it ) );
|
*it = static_cast< char >( ::tolower( *it ) );
|
||||||
}
|
}
|
||||||
|
|
@ -43,15 +43,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||||
#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
|
||||||
|
|
||||||
#include "3DSExporter.h"
|
#include "3DS/3DSExporter.h"
|
||||||
#include "3DSLoader.h"
|
#include "3DS/3DSLoader.h"
|
||||||
#include "3DSHelper.h"
|
#include "3DS/3DSHelper.h"
|
||||||
|
#include "PostProcessing/SplitLargeMeshes.h"
|
||||||
|
|
||||||
#include <assimp/SceneCombiner.h>
|
#include <assimp/SceneCombiner.h>
|
||||||
#include "SplitLargeMeshes.h"
|
|
||||||
#include <assimp/StringComparison.h>
|
#include <assimp/StringComparison.h>
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/Exporter.hpp>
|
#include <assimp/Exporter.hpp>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
@ -50,9 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
|
||||||
|
|
||||||
// internal headers
|
|
||||||
#include "3DSLoader.h"
|
#include "3DSLoader.h"
|
||||||
#include <assimp/Macros.h>
|
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
|
@ -55,7 +55,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "3MFXmlTags.h"
|
#include "3MFXmlTags.h"
|
||||||
#include "D3MFOpcPackage.h"
|
#include "D3MFOpcPackage.h"
|
||||||
|
|
||||||
#include <contrib/zip/src/zip.h>
|
#ifdef ASSIMP_USE_HUNTER
|
||||||
|
# include <zip/zip.h>
|
||||||
|
#else
|
||||||
|
# include <contrib/zip/src/zip.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
|
@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/importerdesc.h>
|
#include <assimp/importerdesc.h>
|
||||||
#include <assimp/StringComparison.h>
|
#include <assimp/StringComparison.h>
|
||||||
#include <assimp/StringUtils.h>
|
#include <assimp/StringUtils.h>
|
||||||
|
#include <assimp/ZipArchiveIOSystem.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
@ -58,7 +59,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "D3MFOpcPackage.h"
|
#include "D3MFOpcPackage.h"
|
||||||
#include <unzip.h>
|
|
||||||
#include <assimp/irrXMLWrapper.h>
|
#include <assimp/irrXMLWrapper.h>
|
||||||
#include "3MFXmlTags.h"
|
#include "3MFXmlTags.h"
|
||||||
#include <assimp/fast_atof.h>
|
#include <assimp/fast_atof.h>
|
||||||
|
|
@ -449,7 +449,7 @@ bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bo
|
||||||
if ( nullptr == pIOHandler ) {
|
if ( nullptr == pIOHandler ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ( !D3MF::D3MFOpcPackage::isZipArchive( pIOHandler, filename ) ) {
|
if ( !ZipArchiveIOSystem::isZipArchive( pIOHandler, filename ) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
D3MF::D3MFOpcPackage opcPackage( pIOHandler, filename );
|
D3MF::D3MFOpcPackage opcPackage( pIOHandler, filename );
|
||||||
207
Engine/lib/assimp/code/3MF/D3MFOpcPackage.cpp
Normal file
207
Engine/lib/assimp/code/3MF/D3MFOpcPackage.cpp
Normal file
|
|
@ -0,0 +1,207 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2019, 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.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
|
||||||
|
|
||||||
|
#include "D3MFOpcPackage.h"
|
||||||
|
#include <assimp/Exceptional.h>
|
||||||
|
|
||||||
|
#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 <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#include "3MFXmlTags.h"
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
|
||||||
|
namespace D3MF {
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
ParseRootNode(xmlReader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParseRootNode(XmlReader* xmlReader)
|
||||||
|
{
|
||||||
|
ParseAttributes(xmlReader);
|
||||||
|
|
||||||
|
while(xmlReader->read())
|
||||||
|
{
|
||||||
|
if(xmlReader->getNodeType() == irr::io::EXN_ELEMENT &&
|
||||||
|
xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_NODE)
|
||||||
|
{
|
||||||
|
ParseChildNode(xmlReader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParseAttributes(XmlReader*) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
bool validateRels( OpcPackageRelationshipPtr &relPtr ) {
|
||||||
|
if ( relPtr->id.empty() || relPtr->type.empty() || relPtr->target.empty() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<OpcPackageRelationshipPtr> m_relationShips;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
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()));
|
||||||
|
|
||||||
|
IOStream *fileStream = mZipArchive->Open(file.c_str());
|
||||||
|
|
||||||
|
ai_assert(fileStream != nullptr);
|
||||||
|
|
||||||
|
std::string rootFile = ReadPackageRootRelationship(fileStream);
|
||||||
|
if ( rootFile.size() > 0 && rootFile[ 0 ] == '/' ) {
|
||||||
|
rootFile = rootFile.substr( 1 );
|
||||||
|
if ( rootFile[ 0 ] == '/' ) {
|
||||||
|
// deal with zip-bug
|
||||||
|
rootFile = rootFile.substr( 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSIMP_LOG_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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
} 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
D3MFOpcPackage::~D3MFOpcPackage() {
|
||||||
|
mZipArchive->Close(mRootStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
IOStream* D3MFOpcPackage::RootStream() const {
|
||||||
|
return mRootStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const std::string ModelRef = "3D/3dmodel.model";
|
||||||
|
|
||||||
|
bool D3MFOpcPackage::validate() {
|
||||||
|
if ( nullptr == mRootStream || nullptr == mZipArchive ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mZipArchive->Exists( ModelRef.c_str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
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){
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return (*itr)->target;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // Namespace D3MF
|
||||||
|
} // Namespace Assimp
|
||||||
|
|
||||||
|
#endif //ASSIMP_BUILD_NO_3MF_IMPORTER
|
||||||
|
|
@ -49,6 +49,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/irrXMLWrapper.h>
|
#include <assimp/irrXMLWrapper.h>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
class ZipArchiveIOSystem;
|
||||||
|
|
||||||
namespace D3MF {
|
namespace D3MF {
|
||||||
|
|
||||||
using XmlReader = irr::io::IrrXMLReader ;
|
using XmlReader = irr::io::IrrXMLReader ;
|
||||||
|
|
@ -60,22 +62,19 @@ struct OpcPackageRelationship {
|
||||||
std::string target;
|
std::string target;
|
||||||
};
|
};
|
||||||
|
|
||||||
class D3MFZipArchive;
|
|
||||||
|
|
||||||
class D3MFOpcPackage {
|
class D3MFOpcPackage {
|
||||||
public:
|
public:
|
||||||
D3MFOpcPackage( IOSystem* pIOHandler, const std::string& rFile );
|
D3MFOpcPackage( IOSystem* pIOHandler, const std::string& rFile );
|
||||||
~D3MFOpcPackage();
|
~D3MFOpcPackage();
|
||||||
IOStream* RootStream() const;
|
IOStream* RootStream() const;
|
||||||
bool validate();
|
bool validate();
|
||||||
static bool isZipArchive( IOSystem* pIOHandler, const std::string& rFile );
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string ReadPackageRootRelationship(IOStream* stream);
|
std::string ReadPackageRootRelationship(IOStream* stream);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IOStream* mRootStream;
|
IOStream* mRootStream;
|
||||||
std::unique_ptr<D3MFZipArchive> mZipArchive;
|
std::unique_ptr<ZipArchiveIOSystem> mZipArchive;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Namespace D3MF
|
} // Namespace D3MF
|
||||||
|
|
@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/ParsingUtils.h>
|
#include <assimp/ParsingUtils.h>
|
||||||
#include <assimp/fast_atof.h>
|
#include <assimp/fast_atof.h>
|
||||||
#include <assimp/Subdivision.h>
|
#include <assimp/Subdivision.h>
|
||||||
#include "Importer.h"
|
#include "Common/Importer.h"
|
||||||
#include <assimp/BaseImporter.h>
|
#include <assimp/BaseImporter.h>
|
||||||
#include <assimp/Importer.hpp>
|
#include <assimp/Importer.hpp>
|
||||||
#include <assimp/light.h>
|
#include <assimp/light.h>
|
||||||
|
|
@ -83,7 +83,7 @@ void AMFImporter::Clear()
|
||||||
mMaterial_Converted.clear();
|
mMaterial_Converted.clear();
|
||||||
mTexture_Converted.clear();
|
mTexture_Converted.clear();
|
||||||
// Delete all elements
|
// Delete all elements
|
||||||
if(mNodeElement_List.size())
|
if(!mNodeElement_List.empty())
|
||||||
{
|
{
|
||||||
for(CAMFImporter_NodeElement* ne: mNodeElement_List) { delete ne; }
|
for(CAMFImporter_NodeElement* ne: mNodeElement_List) { delete ne; }
|
||||||
|
|
||||||
|
|
@ -66,7 +66,7 @@ aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*
|
||||||
aiColor4D tcol;
|
aiColor4D tcol;
|
||||||
|
|
||||||
// Check if stored data are supported.
|
// Check if stored data are supported.
|
||||||
if(Composition.size() != 0)
|
if(!Composition.empty())
|
||||||
{
|
{
|
||||||
throw DeadlyImportError("IME. GetColor for composition");
|
throw DeadlyImportError("IME. GetColor for composition");
|
||||||
}
|
}
|
||||||
|
|
@ -321,7 +321,7 @@ void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace
|
||||||
};
|
};
|
||||||
|
|
||||||
pOutputList_Separated.clear();
|
pOutputList_Separated.clear();
|
||||||
if(pInputList.size() == 0) return;
|
if(pInputList.empty()) return;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
|
@ -334,19 +334,19 @@ void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace
|
||||||
{
|
{
|
||||||
auto it_old = it;
|
auto it_old = it;
|
||||||
|
|
||||||
it++;
|
++it;
|
||||||
face_list_cur.push_back(*it_old);
|
face_list_cur.push_back(*it_old);
|
||||||
pInputList.erase(it_old);
|
pInputList.erase(it_old);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
it++;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(face_list_cur.size() > 0) pOutputList_Separated.push_back(face_list_cur);
|
if(!face_list_cur.empty()) pOutputList_Separated.push_back(face_list_cur);
|
||||||
|
|
||||||
} while(pInputList.size() > 0);
|
} while(!pInputList.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AMFImporter::Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& metadataList, aiNode& sceneNode) const
|
void AMFImporter::Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& metadataList, aiNode& sceneNode) const
|
||||||
|
|
@ -712,7 +712,7 @@ std::list<unsigned int> mesh_idx;
|
||||||
}// for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child)
|
}// for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child)
|
||||||
|
|
||||||
// if meshes was created then assign new indices with current aiNode
|
// if meshes was created then assign new indices with current aiNode
|
||||||
if(mesh_idx.size() > 0)
|
if(!mesh_idx.empty())
|
||||||
{
|
{
|
||||||
std::list<unsigned int>::const_iterator mit = mesh_idx.begin();
|
std::list<unsigned int>::const_iterator mit = mesh_idx.begin();
|
||||||
|
|
||||||
|
|
@ -787,7 +787,7 @@ std::list<aiNode*> ch_node;
|
||||||
}// for(const CAMFImporter_NodeElement* ne: pConstellation.Child)
|
}// for(const CAMFImporter_NodeElement* ne: pConstellation.Child)
|
||||||
|
|
||||||
// copy found aiNode's as children
|
// copy found aiNode's as children
|
||||||
if(ch_node.size() == 0) throw DeadlyImportError("<constellation> must have at least one <instance>.");
|
if(ch_node.empty()) throw DeadlyImportError("<constellation> must have at least one <instance>.");
|
||||||
|
|
||||||
size_t ch_idx = 0;
|
size_t ch_idx = 0;
|
||||||
|
|
||||||
|
|
@ -883,13 +883,13 @@ nl_clean_loop:
|
||||||
if(node_list.size() > 1)
|
if(node_list.size() > 1)
|
||||||
{
|
{
|
||||||
// walk through all nodes
|
// walk through all nodes
|
||||||
for(std::list<aiNode*>::iterator nl_it = node_list.begin(); nl_it != node_list.end(); nl_it++)
|
for(std::list<aiNode*>::iterator nl_it = node_list.begin(); nl_it != node_list.end(); ++nl_it)
|
||||||
{
|
{
|
||||||
// and try to find them in another top nodes.
|
// and try to find them in another top nodes.
|
||||||
std::list<aiNode*>::const_iterator next_it = nl_it;
|
std::list<aiNode*>::const_iterator next_it = nl_it;
|
||||||
|
|
||||||
next_it++;
|
++next_it;
|
||||||
for(; next_it != node_list.end(); next_it++)
|
for(; next_it != node_list.end(); ++next_it)
|
||||||
{
|
{
|
||||||
if((*next_it)->FindNode((*nl_it)->mName) != nullptr)
|
if((*next_it)->FindNode((*nl_it)->mName) != nullptr)
|
||||||
{
|
{
|
||||||
|
|
@ -907,7 +907,7 @@ nl_clean_loop:
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Nodes
|
// Nodes
|
||||||
if(node_list.size() > 0)
|
if(!node_list.empty())
|
||||||
{
|
{
|
||||||
std::list<aiNode*>::const_iterator nl_it = node_list.begin();
|
std::list<aiNode*>::const_iterator nl_it = node_list.begin();
|
||||||
|
|
||||||
|
|
@ -924,7 +924,7 @@ nl_clean_loop:
|
||||||
|
|
||||||
//
|
//
|
||||||
// Meshes
|
// Meshes
|
||||||
if(mesh_list.size() > 0)
|
if(!mesh_list.empty())
|
||||||
{
|
{
|
||||||
std::list<aiMesh*>::const_iterator ml_it = mesh_list.begin();
|
std::list<aiMesh*>::const_iterator ml_it = mesh_list.begin();
|
||||||
|
|
||||||
|
|
@ -53,7 +53,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "ASELoader.h"
|
#include "ASELoader.h"
|
||||||
#include <assimp/StringComparison.h>
|
#include <assimp/StringComparison.h>
|
||||||
#include <assimp/SkeletonMeshBuilder.h>
|
#include <assimp/SkeletonMeshBuilder.h>
|
||||||
#include "TargetAnimation.h"
|
#include "Common/TargetAnimation.h"
|
||||||
|
|
||||||
#include <assimp/Importer.hpp>
|
#include <assimp/Importer.hpp>
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
|
@ -88,23 +89,25 @@ ASEImporter::ASEImporter()
|
||||||
, mBuffer()
|
, mBuffer()
|
||||||
, pcScene()
|
, pcScene()
|
||||||
, configRecomputeNormals()
|
, configRecomputeNormals()
|
||||||
, noSkeletonMesh()
|
, noSkeletonMesh() {
|
||||||
{}
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor, private as well
|
// Destructor, private as well
|
||||||
ASEImporter::~ASEImporter()
|
ASEImporter::~ASEImporter() {
|
||||||
{}
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool ASEImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const
|
bool ASEImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const {
|
||||||
{
|
|
||||||
// check file extension
|
// check file extension
|
||||||
const std::string extension = GetExtension(pFile);
|
const std::string extension = GetExtension(pFile);
|
||||||
|
|
||||||
if( extension == "ase" || extension == "ask")
|
if (extension == "ase" || extension == "ask") {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if ((!extension.length() || cs) && pIOHandler) {
|
if ((!extension.length() || cs) && pIOHandler) {
|
||||||
const char* tokens[] = {"*3dsmax_asciiexport"};
|
const char* tokens[] = {"*3dsmax_asciiexport"};
|
||||||
|
|
@ -115,15 +118,13 @@ bool ASEImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Loader meta information
|
// Loader meta information
|
||||||
const aiImporterDesc* ASEImporter::GetInfo () const
|
const aiImporterDesc* ASEImporter::GetInfo () const {
|
||||||
{
|
|
||||||
return &desc;
|
return &desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Setup configuration options
|
// Setup configuration options
|
||||||
void ASEImporter::SetupProperties(const Importer* pImp)
|
void ASEImporter::SetupProperties(const Importer* pImp) {
|
||||||
{
|
|
||||||
configRecomputeNormals = (pImp->GetPropertyInteger(
|
configRecomputeNormals = (pImp->GetPropertyInteger(
|
||||||
AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS,1) ? true : false);
|
AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS,1) ? true : false);
|
||||||
|
|
||||||
|
|
@ -133,12 +134,11 @@ void ASEImporter::SetupProperties(const Importer* pImp)
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void ASEImporter::InternReadFile( const std::string& pFile,
|
void ASEImporter::InternReadFile( const std::string& pFile,
|
||||||
aiScene* pScene, IOSystem* pIOHandler)
|
aiScene* pScene, IOSystem* pIOHandler) {
|
||||||
{
|
|
||||||
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
|
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
|
||||||
|
|
||||||
// Check whether we can read from the file
|
// Check whether we can read from the file
|
||||||
if( file.get() == NULL) {
|
if( file.get() == nullptr) {
|
||||||
throw DeadlyImportError( "Failed to open ASE file " + pFile + ".");
|
throw DeadlyImportError( "Failed to open ASE file " + pFile + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1299,7 +1299,7 @@ void ASEImporter::BuildMaterialIndices()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dekete our temporary array
|
// Delete our temporary array
|
||||||
delete[] pcIntMaterials;
|
delete[] pcIntMaterials;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2019, assimp team
|
Copyright (c) 2006-2019, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
|
@ -45,20 +45,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* @brief Implementation of the ASE parser class
|
* @brief Implementation of the ASE parser class
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
|
||||||
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
|
||||||
|
|
||||||
// internal headers
|
// internal headers
|
||||||
#include "TextureTransform.h"
|
#include "PostProcessing/TextureTransform.h"
|
||||||
#include "ASELoader.h"
|
#include "ASELoader.h"
|
||||||
|
|
||||||
#include <assimp/fast_atof.h>
|
#include <assimp/fast_atof.h>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
using namespace Assimp::ASE;
|
using namespace Assimp::ASE;
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Begin an ASE parsing function
|
// Begin an ASE parsing function
|
||||||
|
|
||||||
|
|
@ -57,7 +57,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/qnan.h>
|
#include <assimp/qnan.h>
|
||||||
|
|
||||||
// ASE is quite similar to 3ds. We can reuse some structures
|
// ASE is quite similar to 3ds. We can reuse some structures
|
||||||
#include "3DSLoader.h"
|
#include "3DS/3DSLoader.h"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace ASE {
|
namespace ASE {
|
||||||
|
|
@ -188,10 +188,11 @@ struct Animation {
|
||||||
} mRotationType, mScalingType, mPositionType;
|
} mRotationType, mScalingType, mPositionType;
|
||||||
|
|
||||||
Animation() AI_NO_EXCEPT
|
Animation() AI_NO_EXCEPT
|
||||||
: mRotationType (TRACK)
|
: mRotationType (TRACK)
|
||||||
, mScalingType (TRACK)
|
, mScalingType (TRACK)
|
||||||
, mPositionType (TRACK)
|
, mPositionType (TRACK) {
|
||||||
{}
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
//! List of track rotation keyframes
|
//! List of track rotation keyframes
|
||||||
std::vector< aiQuatKey > akeyRotations;
|
std::vector< aiQuatKey > akeyRotations;
|
||||||
|
|
@ -243,7 +244,6 @@ struct BaseNode {
|
||||||
mTargetPosition.x = qnan;
|
mTargetPosition.x = qnan;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Name of the mesh
|
//! Name of the mesh
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
|
||||||
|
|
@ -46,12 +46,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||||
#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
|
||||||
|
|
||||||
#include "assbin_chunks.h"
|
#include "Common/assbin_chunks.h"
|
||||||
|
#include "PostProcessing/ProcessHelper.h"
|
||||||
|
|
||||||
#include <assimp/version.h>
|
#include <assimp/version.h>
|
||||||
#include <assimp/IOStream.hpp>
|
#include <assimp/IOStream.hpp>
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
#include <assimp/Exporter.hpp>
|
#include <assimp/Exporter.hpp>
|
||||||
#include "ProcessHelper.h"
|
|
||||||
#include <assimp/Exceptional.h>
|
#include <assimp/Exceptional.h>
|
||||||
|
|
||||||
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
||||||
|
|
@ -50,8 +50,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
|
||||||
|
|
||||||
// internal headers
|
// internal headers
|
||||||
#include "AssbinLoader.h"
|
#include "Assbin/AssbinLoader.h"
|
||||||
#include "assbin_chunks.h"
|
#include "Common/assbin_chunks.h"
|
||||||
#include <assimp/MemoryIOWrapper.h>
|
#include <assimp/MemoryIOWrapper.h>
|
||||||
#include <assimp/mesh.h>
|
#include <assimp/mesh.h>
|
||||||
#include <assimp/anim.h>
|
#include <assimp/anim.h>
|
||||||
|
|
@ -68,7 +68,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static const aiImporterDesc desc = {
|
||||||
".assbin Importer",
|
"Assimp Binary Importer",
|
||||||
"Gargaj / Conspiracy",
|
"Gargaj / Conspiracy",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
|
@ -708,7 +708,7 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
|
|
||||||
unsigned char * uncompressedData = new unsigned char[ uncompressedSize ];
|
unsigned char * uncompressedData = new unsigned char[ uncompressedSize ];
|
||||||
|
|
||||||
int res = uncompress( uncompressedData, &uncompressedSize, compressedData, len );
|
int res = uncompress( uncompressedData, &uncompressedSize, compressedData, (uLong) len );
|
||||||
if(res != Z_OK)
|
if(res != Z_OK)
|
||||||
{
|
{
|
||||||
delete [] uncompressedData;
|
delete [] uncompressedData;
|
||||||
109
Engine/lib/assimp/code/Assjson/cencode.c
Normal file
109
Engine/lib/assimp/code/Assjson/cencode.c
Normal file
|
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
cencoder.c - c source to a base64 encoding algorithm implementation
|
||||||
|
|
||||||
|
This is part of the libb64 project, and has been placed in the public domain.
|
||||||
|
For details, see http://sourceforge.net/projects/libb64
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cencode.h" // changed from <B64/cencode.h>
|
||||||
|
|
||||||
|
const int CHARS_PER_LINE = 72;
|
||||||
|
|
||||||
|
void base64_init_encodestate(base64_encodestate* state_in)
|
||||||
|
{
|
||||||
|
state_in->step = step_A;
|
||||||
|
state_in->result = 0;
|
||||||
|
state_in->stepcount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char base64_encode_value(char value_in)
|
||||||
|
{
|
||||||
|
static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
if (value_in > 63) return '=';
|
||||||
|
return encoding[(int)value_in];
|
||||||
|
}
|
||||||
|
|
||||||
|
int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in)
|
||||||
|
{
|
||||||
|
const char* plainchar = plaintext_in;
|
||||||
|
const char* const plaintextend = plaintext_in + length_in;
|
||||||
|
char* codechar = code_out;
|
||||||
|
char result;
|
||||||
|
char fragment;
|
||||||
|
|
||||||
|
result = state_in->result;
|
||||||
|
|
||||||
|
switch (state_in->step)
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
case step_A:
|
||||||
|
if (plainchar == plaintextend)
|
||||||
|
{
|
||||||
|
state_in->result = result;
|
||||||
|
state_in->step = step_A;
|
||||||
|
return codechar - code_out;
|
||||||
|
}
|
||||||
|
fragment = *plainchar++;
|
||||||
|
result = (fragment & 0x0fc) >> 2;
|
||||||
|
*codechar++ = base64_encode_value(result);
|
||||||
|
result = (fragment & 0x003) << 4;
|
||||||
|
case step_B:
|
||||||
|
if (plainchar == plaintextend)
|
||||||
|
{
|
||||||
|
state_in->result = result;
|
||||||
|
state_in->step = step_B;
|
||||||
|
return codechar - code_out;
|
||||||
|
}
|
||||||
|
fragment = *plainchar++;
|
||||||
|
result |= (fragment & 0x0f0) >> 4;
|
||||||
|
*codechar++ = base64_encode_value(result);
|
||||||
|
result = (fragment & 0x00f) << 2;
|
||||||
|
case step_C:
|
||||||
|
if (plainchar == plaintextend)
|
||||||
|
{
|
||||||
|
state_in->result = result;
|
||||||
|
state_in->step = step_C;
|
||||||
|
return codechar - code_out;
|
||||||
|
}
|
||||||
|
fragment = *plainchar++;
|
||||||
|
result |= (fragment & 0x0c0) >> 6;
|
||||||
|
*codechar++ = base64_encode_value(result);
|
||||||
|
result = (fragment & 0x03f) >> 0;
|
||||||
|
*codechar++ = base64_encode_value(result);
|
||||||
|
|
||||||
|
++(state_in->stepcount);
|
||||||
|
if (state_in->stepcount == CHARS_PER_LINE/4)
|
||||||
|
{
|
||||||
|
*codechar++ = '\n';
|
||||||
|
state_in->stepcount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* control should not reach here */
|
||||||
|
return codechar - code_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
|
||||||
|
{
|
||||||
|
char* codechar = code_out;
|
||||||
|
|
||||||
|
switch (state_in->step)
|
||||||
|
{
|
||||||
|
case step_B:
|
||||||
|
*codechar++ = base64_encode_value(state_in->result);
|
||||||
|
*codechar++ = '=';
|
||||||
|
*codechar++ = '=';
|
||||||
|
break;
|
||||||
|
case step_C:
|
||||||
|
*codechar++ = base64_encode_value(state_in->result);
|
||||||
|
*codechar++ = '=';
|
||||||
|
break;
|
||||||
|
case step_A:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*codechar++ = '\n';
|
||||||
|
|
||||||
|
return codechar - code_out;
|
||||||
|
}
|
||||||
|
|
||||||
31
Engine/lib/assimp/code/Assjson/cencode.h
Normal file
31
Engine/lib/assimp/code/Assjson/cencode.h
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
cencode.h - c header for a base64 encoding algorithm
|
||||||
|
|
||||||
|
This is part of the libb64 project, and has been placed in the public domain.
|
||||||
|
For details, see http://sourceforge.net/projects/libb64
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BASE64_CENCODE_H
|
||||||
|
#define BASE64_CENCODE_H
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
step_A, step_B, step_C
|
||||||
|
} base64_encodestep;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
base64_encodestep step;
|
||||||
|
char result;
|
||||||
|
int stepcount;
|
||||||
|
} base64_encodestate;
|
||||||
|
|
||||||
|
void base64_init_encodestate(base64_encodestate* state_in);
|
||||||
|
|
||||||
|
char base64_encode_value(char value_in);
|
||||||
|
|
||||||
|
int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in);
|
||||||
|
|
||||||
|
int base64_encode_blockend(char* code_out, base64_encodestate* state_in);
|
||||||
|
|
||||||
|
#endif /* BASE64_CENCODE_H */
|
||||||
809
Engine/lib/assimp/code/Assjson/json_exporter.cpp
Normal file
809
Engine/lib/assimp/code/Assjson/json_exporter.cpp
Normal file
|
|
@ -0,0 +1,809 @@
|
||||||
|
/*
|
||||||
|
Assimp2Json
|
||||||
|
Copyright (c) 2011, Alexander C. Gessler
|
||||||
|
|
||||||
|
Licensed under a 3-clause BSD license. See the LICENSE file for more information.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||||
|
#ifndef ASSIMP_BUILD_NO_ASSJSON_EXPORTER
|
||||||
|
|
||||||
|
#include <assimp/Importer.hpp>
|
||||||
|
#include <assimp/Exporter.hpp>
|
||||||
|
#include <assimp/IOStream.hpp>
|
||||||
|
#include <assimp/IOSystem.hpp>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <limits>
|
||||||
|
#include <cassert>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#define CURRENT_FORMAT_VERSION 100
|
||||||
|
|
||||||
|
// grab scoped_ptr from assimp to avoid a dependency on boost.
|
||||||
|
//#include <assimp/../../code/BoostWorkaround/boost/scoped_ptr.hpp>
|
||||||
|
|
||||||
|
#include "mesh_splitter.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "cencode.h"
|
||||||
|
}
|
||||||
|
namespace Assimp {
|
||||||
|
|
||||||
|
void ExportAssimp2Json(const char*, Assimp::IOSystem*, const aiScene*, const Assimp::ExportProperties*);
|
||||||
|
|
||||||
|
// small utility class to simplify serializing the aiScene to Json
|
||||||
|
class JSONWriter {
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Flag_DoNotIndent = 0x1,
|
||||||
|
Flag_WriteSpecialFloats = 0x2,
|
||||||
|
};
|
||||||
|
|
||||||
|
JSONWriter(Assimp::IOStream& out, unsigned int flags = 0u)
|
||||||
|
: out(out)
|
||||||
|
, first()
|
||||||
|
, flags(flags) {
|
||||||
|
// make sure that all formatting happens using the standard, C locale and not the user's current locale
|
||||||
|
buff.imbue(std::locale("C"));
|
||||||
|
}
|
||||||
|
|
||||||
|
~JSONWriter() {
|
||||||
|
Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Flush() {
|
||||||
|
const std::string s = buff.str();
|
||||||
|
out.Write(s.c_str(), s.length(), 1);
|
||||||
|
buff.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushIndent() {
|
||||||
|
indent += '\t';
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopIndent() {
|
||||||
|
indent.erase(indent.end() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Key(const std::string& name) {
|
||||||
|
AddIndentation();
|
||||||
|
Delimit();
|
||||||
|
buff << '\"' + name + "\": ";
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Literal>
|
||||||
|
void Element(const Literal& name) {
|
||||||
|
AddIndentation();
|
||||||
|
Delimit();
|
||||||
|
|
||||||
|
LiteralToString(buff, name) << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Literal>
|
||||||
|
void SimpleValue(const Literal& s) {
|
||||||
|
LiteralToString(buff, s) << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimpleValue(const void* buffer, size_t len) {
|
||||||
|
base64_encodestate s;
|
||||||
|
base64_init_encodestate(&s);
|
||||||
|
|
||||||
|
char* const out = new char[std::max(len * 2, static_cast<size_t>(16u))];
|
||||||
|
const int n = base64_encode_block(reinterpret_cast<const char*>(buffer), static_cast<int>(len), out, &s);
|
||||||
|
out[n + base64_encode_blockend(out + n, &s)] = '\0';
|
||||||
|
|
||||||
|
// base64 encoding may add newlines, but JSON strings may not contain 'real' newlines
|
||||||
|
// (only escaped ones). Remove any newlines in out.
|
||||||
|
for (char* cur = out; *cur; ++cur) {
|
||||||
|
if (*cur == '\n') {
|
||||||
|
*cur = ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buff << '\"' << out << "\"\n";
|
||||||
|
delete[] out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartObj(bool is_element = false) {
|
||||||
|
// if this appears as a plain array element, we need to insert a delimiter and we should also indent it
|
||||||
|
if (is_element) {
|
||||||
|
AddIndentation();
|
||||||
|
if (!first) {
|
||||||
|
buff << ',';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
first = true;
|
||||||
|
buff << "{\n";
|
||||||
|
PushIndent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EndObj() {
|
||||||
|
PopIndent();
|
||||||
|
AddIndentation();
|
||||||
|
first = false;
|
||||||
|
buff << "}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartArray(bool is_element = false) {
|
||||||
|
// if this appears as a plain array element, we need to insert a delimiter and we should also indent it
|
||||||
|
if (is_element) {
|
||||||
|
AddIndentation();
|
||||||
|
if (!first) {
|
||||||
|
buff << ',';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
first = true;
|
||||||
|
buff << "[\n";
|
||||||
|
PushIndent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EndArray() {
|
||||||
|
PopIndent();
|
||||||
|
AddIndentation();
|
||||||
|
buff << "]\n";
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddIndentation() {
|
||||||
|
if (!(flags & Flag_DoNotIndent)) {
|
||||||
|
buff << indent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Delimit() {
|
||||||
|
if (!first) {
|
||||||
|
buff << ',';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
buff << ' ';
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename Literal>
|
||||||
|
std::stringstream& LiteralToString(std::stringstream& stream, const Literal& s) {
|
||||||
|
stream << s;
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream& LiteralToString(std::stringstream& stream, const aiString& s) {
|
||||||
|
std::string t;
|
||||||
|
|
||||||
|
// escape backslashes and single quotes, both would render the JSON invalid if left as is
|
||||||
|
t.reserve(s.length);
|
||||||
|
for (size_t i = 0; i < s.length; ++i) {
|
||||||
|
|
||||||
|
if (s.data[i] == '\\' || s.data[i] == '\'' || s.data[i] == '\"') {
|
||||||
|
t.push_back('\\');
|
||||||
|
}
|
||||||
|
|
||||||
|
t.push_back(s.data[i]);
|
||||||
|
}
|
||||||
|
stream << "\"";
|
||||||
|
stream << t;
|
||||||
|
stream << "\"";
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream& LiteralToString(std::stringstream& stream, float f) {
|
||||||
|
if (!std::numeric_limits<float>::is_iec559) {
|
||||||
|
// on a non IEEE-754 platform, we make no assumptions about the representation or existence
|
||||||
|
// of special floating-point numbers.
|
||||||
|
stream << f;
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSON does not support writing Inf/Nan
|
||||||
|
// [RFC 4672: "Numeric values that cannot be represented as sequences of digits
|
||||||
|
// (such as Infinity and NaN) are not permitted."]
|
||||||
|
// Nevertheless, many parsers will accept the special keywords Infinity, -Infinity and NaN
|
||||||
|
if (std::numeric_limits<float>::infinity() == fabs(f)) {
|
||||||
|
if (flags & Flag_WriteSpecialFloats) {
|
||||||
|
stream << (f < 0 ? "\"-" : "\"") + std::string("Infinity\"");
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
// we should print this warning, but we can't - this is called from within a generic assimp exporter, we cannot use cerr
|
||||||
|
// std::cerr << "warning: cannot represent infinite number literal, substituting 0 instead (use -i flag to enforce Infinity/NaN)" << std::endl;
|
||||||
|
stream << "0.0";
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
// f!=f is the most reliable test for NaNs that I know of
|
||||||
|
else if (f != f) {
|
||||||
|
if (flags & Flag_WriteSpecialFloats) {
|
||||||
|
stream << "\"NaN\"";
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
// we should print this warning, but we can't - this is called from within a generic assimp exporter, we cannot use cerr
|
||||||
|
// std::cerr << "warning: cannot represent infinite number literal, substituting 0 instead (use -i flag to enforce Infinity/NaN)" << std::endl;
|
||||||
|
stream << "0.0";
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream << f;
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Assimp::IOStream& out;
|
||||||
|
std::string indent, newline;
|
||||||
|
std::stringstream buff;
|
||||||
|
bool first;
|
||||||
|
|
||||||
|
unsigned int flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
void Write(JSONWriter& out, const aiVector3D& ai, bool is_elem = true) {
|
||||||
|
out.StartArray(is_elem);
|
||||||
|
out.Element(ai.x);
|
||||||
|
out.Element(ai.y);
|
||||||
|
out.Element(ai.z);
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write(JSONWriter& out, const aiQuaternion& ai, bool is_elem = true) {
|
||||||
|
out.StartArray(is_elem);
|
||||||
|
out.Element(ai.w);
|
||||||
|
out.Element(ai.x);
|
||||||
|
out.Element(ai.y);
|
||||||
|
out.Element(ai.z);
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write(JSONWriter& out, const aiColor3D& ai, bool is_elem = true) {
|
||||||
|
out.StartArray(is_elem);
|
||||||
|
out.Element(ai.r);
|
||||||
|
out.Element(ai.g);
|
||||||
|
out.Element(ai.b);
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write(JSONWriter& out, const aiMatrix4x4& ai, bool is_elem = true) {
|
||||||
|
out.StartArray(is_elem);
|
||||||
|
for (unsigned int x = 0; x < 4; ++x) {
|
||||||
|
for (unsigned int y = 0; y < 4; ++y) {
|
||||||
|
out.Element(ai[x][y]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write(JSONWriter& out, const aiBone& ai, bool is_elem = true) {
|
||||||
|
out.StartObj(is_elem);
|
||||||
|
|
||||||
|
out.Key("name");
|
||||||
|
out.SimpleValue(ai.mName);
|
||||||
|
|
||||||
|
out.Key("offsetmatrix");
|
||||||
|
Write(out, ai.mOffsetMatrix, false);
|
||||||
|
|
||||||
|
out.Key("weights");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int i = 0; i < ai.mNumWeights; ++i) {
|
||||||
|
out.StartArray(true);
|
||||||
|
out.Element(ai.mWeights[i].mVertexId);
|
||||||
|
out.Element(ai.mWeights[i].mWeight);
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
out.EndObj();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write(JSONWriter& out, const aiFace& ai, bool is_elem = true) {
|
||||||
|
out.StartArray(is_elem);
|
||||||
|
for (unsigned int i = 0; i < ai.mNumIndices; ++i) {
|
||||||
|
out.Element(ai.mIndices[i]);
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write(JSONWriter& out, const aiMesh& ai, bool is_elem = true) {
|
||||||
|
out.StartObj(is_elem);
|
||||||
|
|
||||||
|
out.Key("name");
|
||||||
|
out.SimpleValue(ai.mName);
|
||||||
|
|
||||||
|
out.Key("materialindex");
|
||||||
|
out.SimpleValue(ai.mMaterialIndex);
|
||||||
|
|
||||||
|
out.Key("primitivetypes");
|
||||||
|
out.SimpleValue(ai.mPrimitiveTypes);
|
||||||
|
|
||||||
|
out.Key("vertices");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int i = 0; i < ai.mNumVertices; ++i) {
|
||||||
|
out.Element(ai.mVertices[i].x);
|
||||||
|
out.Element(ai.mVertices[i].y);
|
||||||
|
out.Element(ai.mVertices[i].z);
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
|
||||||
|
if (ai.HasNormals()) {
|
||||||
|
out.Key("normals");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int i = 0; i < ai.mNumVertices; ++i) {
|
||||||
|
out.Element(ai.mNormals[i].x);
|
||||||
|
out.Element(ai.mNormals[i].y);
|
||||||
|
out.Element(ai.mNormals[i].z);
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ai.HasTangentsAndBitangents()) {
|
||||||
|
out.Key("tangents");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int i = 0; i < ai.mNumVertices; ++i) {
|
||||||
|
out.Element(ai.mTangents[i].x);
|
||||||
|
out.Element(ai.mTangents[i].y);
|
||||||
|
out.Element(ai.mTangents[i].z);
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
|
||||||
|
out.Key("bitangents");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int i = 0; i < ai.mNumVertices; ++i) {
|
||||||
|
out.Element(ai.mBitangents[i].x);
|
||||||
|
out.Element(ai.mBitangents[i].y);
|
||||||
|
out.Element(ai.mBitangents[i].z);
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ai.GetNumUVChannels()) {
|
||||||
|
out.Key("numuvcomponents");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int n = 0; n < ai.GetNumUVChannels(); ++n) {
|
||||||
|
out.Element(ai.mNumUVComponents[n]);
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
|
||||||
|
out.Key("texturecoords");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int n = 0; n < ai.GetNumUVChannels(); ++n) {
|
||||||
|
const unsigned int numc = ai.mNumUVComponents[n] ? ai.mNumUVComponents[n] : 2;
|
||||||
|
|
||||||
|
out.StartArray(true);
|
||||||
|
for (unsigned int i = 0; i < ai.mNumVertices; ++i) {
|
||||||
|
for (unsigned int c = 0; c < numc; ++c) {
|
||||||
|
out.Element(ai.mTextureCoords[n][i][c]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ai.GetNumColorChannels()) {
|
||||||
|
out.Key("colors");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int n = 0; n < ai.GetNumColorChannels(); ++n) {
|
||||||
|
out.StartArray(true);
|
||||||
|
for (unsigned int i = 0; i < ai.mNumVertices; ++i) {
|
||||||
|
out.Element(ai.mColors[n][i].r);
|
||||||
|
out.Element(ai.mColors[n][i].g);
|
||||||
|
out.Element(ai.mColors[n][i].b);
|
||||||
|
out.Element(ai.mColors[n][i].a);
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ai.mNumBones) {
|
||||||
|
out.Key("bones");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int n = 0; n < ai.mNumBones; ++n) {
|
||||||
|
Write(out, *ai.mBones[n]);
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
out.Key("faces");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int n = 0; n < ai.mNumFaces; ++n) {
|
||||||
|
Write(out, ai.mFaces[n]);
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
|
||||||
|
out.EndObj();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write(JSONWriter& out, const aiNode& ai, bool is_elem = true) {
|
||||||
|
out.StartObj(is_elem);
|
||||||
|
|
||||||
|
out.Key("name");
|
||||||
|
out.SimpleValue(ai.mName);
|
||||||
|
|
||||||
|
out.Key("transformation");
|
||||||
|
Write(out, ai.mTransformation, false);
|
||||||
|
|
||||||
|
if (ai.mNumMeshes) {
|
||||||
|
out.Key("meshes");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int n = 0; n < ai.mNumMeshes; ++n) {
|
||||||
|
out.Element(ai.mMeshes[n]);
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ai.mNumChildren) {
|
||||||
|
out.Key("children");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int n = 0; n < ai.mNumChildren; ++n) {
|
||||||
|
Write(out, *ai.mChildren[n]);
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
out.EndObj();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write(JSONWriter& out, const aiMaterial& ai, bool is_elem = true) {
|
||||||
|
out.StartObj(is_elem);
|
||||||
|
|
||||||
|
out.Key("properties");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int i = 0; i < ai.mNumProperties; ++i) {
|
||||||
|
const aiMaterialProperty* const prop = ai.mProperties[i];
|
||||||
|
out.StartObj(true);
|
||||||
|
out.Key("key");
|
||||||
|
out.SimpleValue(prop->mKey);
|
||||||
|
out.Key("semantic");
|
||||||
|
out.SimpleValue(prop->mSemantic);
|
||||||
|
out.Key("index");
|
||||||
|
out.SimpleValue(prop->mIndex);
|
||||||
|
|
||||||
|
out.Key("type");
|
||||||
|
out.SimpleValue(prop->mType);
|
||||||
|
|
||||||
|
out.Key("value");
|
||||||
|
switch (prop->mType) {
|
||||||
|
case aiPTI_Float:
|
||||||
|
if (prop->mDataLength / sizeof(float) > 1) {
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int i = 0; i < prop->mDataLength / sizeof(float); ++i) {
|
||||||
|
out.Element(reinterpret_cast<float*>(prop->mData)[i]);
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
out.SimpleValue(*reinterpret_cast<float*>(prop->mData));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case aiPTI_Integer:
|
||||||
|
if (prop->mDataLength / sizeof(int) > 1) {
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int i = 0; i < prop->mDataLength / sizeof(int); ++i) {
|
||||||
|
out.Element(reinterpret_cast<int*>(prop->mData)[i]);
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
} else {
|
||||||
|
out.SimpleValue(*reinterpret_cast<int*>(prop->mData));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case aiPTI_String:
|
||||||
|
{
|
||||||
|
aiString s;
|
||||||
|
aiGetMaterialString(&ai, prop->mKey.data, prop->mSemantic, prop->mIndex, &s);
|
||||||
|
out.SimpleValue(s);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case aiPTI_Buffer:
|
||||||
|
{
|
||||||
|
// binary data is written as series of hex-encoded octets
|
||||||
|
out.SimpleValue(prop->mData, prop->mDataLength);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
out.EndObj();
|
||||||
|
}
|
||||||
|
|
||||||
|
out.EndArray();
|
||||||
|
out.EndObj();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write(JSONWriter& out, const aiTexture& ai, bool is_elem = true) {
|
||||||
|
out.StartObj(is_elem);
|
||||||
|
|
||||||
|
out.Key("width");
|
||||||
|
out.SimpleValue(ai.mWidth);
|
||||||
|
|
||||||
|
out.Key("height");
|
||||||
|
out.SimpleValue(ai.mHeight);
|
||||||
|
|
||||||
|
out.Key("formathint");
|
||||||
|
out.SimpleValue(aiString(ai.achFormatHint));
|
||||||
|
|
||||||
|
out.Key("data");
|
||||||
|
if (!ai.mHeight) {
|
||||||
|
out.SimpleValue(ai.pcData, ai.mWidth);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int y = 0; y < ai.mHeight; ++y) {
|
||||||
|
out.StartArray(true);
|
||||||
|
for (unsigned int x = 0; x < ai.mWidth; ++x) {
|
||||||
|
const aiTexel& tx = ai.pcData[y*ai.mWidth + x];
|
||||||
|
out.StartArray(true);
|
||||||
|
out.Element(static_cast<unsigned int>(tx.r));
|
||||||
|
out.Element(static_cast<unsigned int>(tx.g));
|
||||||
|
out.Element(static_cast<unsigned int>(tx.b));
|
||||||
|
out.Element(static_cast<unsigned int>(tx.a));
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
out.EndObj();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write(JSONWriter& out, const aiLight& ai, bool is_elem = true) {
|
||||||
|
out.StartObj(is_elem);
|
||||||
|
|
||||||
|
out.Key("name");
|
||||||
|
out.SimpleValue(ai.mName);
|
||||||
|
|
||||||
|
out.Key("type");
|
||||||
|
out.SimpleValue(ai.mType);
|
||||||
|
|
||||||
|
if (ai.mType == aiLightSource_SPOT || ai.mType == aiLightSource_UNDEFINED) {
|
||||||
|
out.Key("angleinnercone");
|
||||||
|
out.SimpleValue(ai.mAngleInnerCone);
|
||||||
|
|
||||||
|
out.Key("angleoutercone");
|
||||||
|
out.SimpleValue(ai.mAngleOuterCone);
|
||||||
|
}
|
||||||
|
|
||||||
|
out.Key("attenuationconstant");
|
||||||
|
out.SimpleValue(ai.mAttenuationConstant);
|
||||||
|
|
||||||
|
out.Key("attenuationlinear");
|
||||||
|
out.SimpleValue(ai.mAttenuationLinear);
|
||||||
|
|
||||||
|
out.Key("attenuationquadratic");
|
||||||
|
out.SimpleValue(ai.mAttenuationQuadratic);
|
||||||
|
|
||||||
|
out.Key("diffusecolor");
|
||||||
|
Write(out, ai.mColorDiffuse, false);
|
||||||
|
|
||||||
|
out.Key("specularcolor");
|
||||||
|
Write(out, ai.mColorSpecular, false);
|
||||||
|
|
||||||
|
out.Key("ambientcolor");
|
||||||
|
Write(out, ai.mColorAmbient, false);
|
||||||
|
|
||||||
|
if (ai.mType != aiLightSource_POINT) {
|
||||||
|
out.Key("direction");
|
||||||
|
Write(out, ai.mDirection, false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ai.mType != aiLightSource_DIRECTIONAL) {
|
||||||
|
out.Key("position");
|
||||||
|
Write(out, ai.mPosition, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
out.EndObj();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write(JSONWriter& out, const aiNodeAnim& ai, bool is_elem = true) {
|
||||||
|
out.StartObj(is_elem);
|
||||||
|
|
||||||
|
out.Key("name");
|
||||||
|
out.SimpleValue(ai.mNodeName);
|
||||||
|
|
||||||
|
out.Key("prestate");
|
||||||
|
out.SimpleValue(ai.mPreState);
|
||||||
|
|
||||||
|
out.Key("poststate");
|
||||||
|
out.SimpleValue(ai.mPostState);
|
||||||
|
|
||||||
|
if (ai.mNumPositionKeys) {
|
||||||
|
out.Key("positionkeys");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int n = 0; n < ai.mNumPositionKeys; ++n) {
|
||||||
|
const aiVectorKey& pos = ai.mPositionKeys[n];
|
||||||
|
out.StartArray(true);
|
||||||
|
out.Element(pos.mTime);
|
||||||
|
Write(out, pos.mValue);
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ai.mNumRotationKeys) {
|
||||||
|
out.Key("rotationkeys");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int n = 0; n < ai.mNumRotationKeys; ++n) {
|
||||||
|
const aiQuatKey& rot = ai.mRotationKeys[n];
|
||||||
|
out.StartArray(true);
|
||||||
|
out.Element(rot.mTime);
|
||||||
|
Write(out, rot.mValue);
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ai.mNumScalingKeys) {
|
||||||
|
out.Key("scalingkeys");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int n = 0; n < ai.mNumScalingKeys; ++n) {
|
||||||
|
const aiVectorKey& scl = ai.mScalingKeys[n];
|
||||||
|
out.StartArray(true);
|
||||||
|
out.Element(scl.mTime);
|
||||||
|
Write(out, scl.mValue);
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
out.EndObj();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write(JSONWriter& out, const aiAnimation& ai, bool is_elem = true) {
|
||||||
|
out.StartObj(is_elem);
|
||||||
|
|
||||||
|
out.Key("name");
|
||||||
|
out.SimpleValue(ai.mName);
|
||||||
|
|
||||||
|
out.Key("tickspersecond");
|
||||||
|
out.SimpleValue(ai.mTicksPerSecond);
|
||||||
|
|
||||||
|
out.Key("duration");
|
||||||
|
out.SimpleValue(ai.mDuration);
|
||||||
|
|
||||||
|
out.Key("channels");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int n = 0; n < ai.mNumChannels; ++n) {
|
||||||
|
Write(out, *ai.mChannels[n]);
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
out.EndObj();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write(JSONWriter& out, const aiCamera& ai, bool is_elem = true) {
|
||||||
|
out.StartObj(is_elem);
|
||||||
|
|
||||||
|
out.Key("name");
|
||||||
|
out.SimpleValue(ai.mName);
|
||||||
|
|
||||||
|
out.Key("aspect");
|
||||||
|
out.SimpleValue(ai.mAspect);
|
||||||
|
|
||||||
|
out.Key("clipplanefar");
|
||||||
|
out.SimpleValue(ai.mClipPlaneFar);
|
||||||
|
|
||||||
|
out.Key("clipplanenear");
|
||||||
|
out.SimpleValue(ai.mClipPlaneNear);
|
||||||
|
|
||||||
|
out.Key("horizontalfov");
|
||||||
|
out.SimpleValue(ai.mHorizontalFOV);
|
||||||
|
|
||||||
|
out.Key("up");
|
||||||
|
Write(out, ai.mUp, false);
|
||||||
|
|
||||||
|
out.Key("lookat");
|
||||||
|
Write(out, ai.mLookAt, false);
|
||||||
|
|
||||||
|
out.EndObj();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteFormatInfo(JSONWriter& out) {
|
||||||
|
out.StartObj();
|
||||||
|
out.Key("format");
|
||||||
|
out.SimpleValue("\"assimp2json\"");
|
||||||
|
out.Key("version");
|
||||||
|
out.SimpleValue(CURRENT_FORMAT_VERSION);
|
||||||
|
out.EndObj();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write(JSONWriter& out, const aiScene& ai) {
|
||||||
|
out.StartObj();
|
||||||
|
|
||||||
|
out.Key("__metadata__");
|
||||||
|
WriteFormatInfo(out);
|
||||||
|
|
||||||
|
out.Key("rootnode");
|
||||||
|
Write(out, *ai.mRootNode, false);
|
||||||
|
|
||||||
|
out.Key("flags");
|
||||||
|
out.SimpleValue(ai.mFlags);
|
||||||
|
|
||||||
|
if (ai.HasMeshes()) {
|
||||||
|
out.Key("meshes");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int n = 0; n < ai.mNumMeshes; ++n) {
|
||||||
|
Write(out, *ai.mMeshes[n]);
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ai.HasMaterials()) {
|
||||||
|
out.Key("materials");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int n = 0; n < ai.mNumMaterials; ++n) {
|
||||||
|
Write(out, *ai.mMaterials[n]);
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ai.HasAnimations()) {
|
||||||
|
out.Key("animations");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int n = 0; n < ai.mNumAnimations; ++n) {
|
||||||
|
Write(out, *ai.mAnimations[n]);
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ai.HasLights()) {
|
||||||
|
out.Key("lights");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int n = 0; n < ai.mNumLights; ++n) {
|
||||||
|
Write(out, *ai.mLights[n]);
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ai.HasCameras()) {
|
||||||
|
out.Key("cameras");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int n = 0; n < ai.mNumCameras; ++n) {
|
||||||
|
Write(out, *ai.mCameras[n]);
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ai.HasTextures()) {
|
||||||
|
out.Key("textures");
|
||||||
|
out.StartArray();
|
||||||
|
for (unsigned int n = 0; n < ai.mNumTextures; ++n) {
|
||||||
|
Write(out, *ai.mTextures[n]);
|
||||||
|
}
|
||||||
|
out.EndArray();
|
||||||
|
}
|
||||||
|
out.EndObj();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ExportAssimp2Json(const char* file, Assimp::IOSystem* io, const aiScene* scene, const Assimp::ExportProperties*) {
|
||||||
|
std::unique_ptr<Assimp::IOStream> str(io->Open(file, "wt"));
|
||||||
|
if (!str) {
|
||||||
|
//throw Assimp::DeadlyExportError("could not open output file");
|
||||||
|
}
|
||||||
|
|
||||||
|
// get a copy of the scene so we can modify it
|
||||||
|
aiScene* scenecopy_tmp;
|
||||||
|
aiCopyScene(scene, &scenecopy_tmp);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// split meshes so they fit into a 16 bit index buffer
|
||||||
|
MeshSplitter splitter;
|
||||||
|
splitter.SetLimit(1 << 16);
|
||||||
|
splitter.Execute(scenecopy_tmp);
|
||||||
|
|
||||||
|
// XXX Flag_WriteSpecialFloats is turned on by default, right now we don't have a configuration interface for exporters
|
||||||
|
JSONWriter s(*str, JSONWriter::Flag_WriteSpecialFloats);
|
||||||
|
Write(s, *scenecopy_tmp);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
aiFreeScene(scenecopy_tmp);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
aiFreeScene(scenecopy_tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ASSIMP_BUILD_NO_ASSJSON_EXPORTER
|
||||||
|
#endif // ASSIMP_BUILD_NO_EXPORT
|
||||||
320
Engine/lib/assimp/code/Assjson/mesh_splitter.cpp
Normal file
320
Engine/lib/assimp/code/Assjson/mesh_splitter.cpp
Normal file
|
|
@ -0,0 +1,320 @@
|
||||||
|
/*
|
||||||
|
Assimp2Json
|
||||||
|
Copyright (c) 2011, Alexander C. Gessler
|
||||||
|
|
||||||
|
Licensed under a 3-clause BSD license. See the LICENSE file for more information.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mesh_splitter.h"
|
||||||
|
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Note: this is largely based on assimp's SplitLargeMeshes_Vertex process.
|
||||||
|
// it is refactored and the coding style is slightly improved, though.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Executes the post processing step on the given imported data.
|
||||||
|
void MeshSplitter::Execute( aiScene* pScene) {
|
||||||
|
std::vector<std::pair<aiMesh*, unsigned int> > source_mesh_map;
|
||||||
|
|
||||||
|
for( unsigned int a = 0; a < pScene->mNumMeshes; a++) {
|
||||||
|
SplitMesh(a, pScene->mMeshes[a],source_mesh_map);
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned int size = static_cast<unsigned int>(source_mesh_map.size());
|
||||||
|
if (size != pScene->mNumMeshes) {
|
||||||
|
// it seems something has been split. rebuild the mesh list
|
||||||
|
delete[] pScene->mMeshes;
|
||||||
|
pScene->mNumMeshes = size;
|
||||||
|
pScene->mMeshes = new aiMesh*[size]();
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < size;++i) {
|
||||||
|
pScene->mMeshes[i] = source_mesh_map[i].first;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now we need to update all nodes
|
||||||
|
UpdateNode(pScene->mRootNode,source_mesh_map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void MeshSplitter::UpdateNode(aiNode* pcNode, const std::vector<std::pair<aiMesh*, unsigned int> >& source_mesh_map) {
|
||||||
|
// TODO: should better use std::(multi)set for source_mesh_map.
|
||||||
|
|
||||||
|
// for every index in out list build a new entry
|
||||||
|
std::vector<unsigned int> aiEntries;
|
||||||
|
aiEntries.reserve(pcNode->mNumMeshes + 1);
|
||||||
|
for (unsigned int i = 0; i < pcNode->mNumMeshes;++i) {
|
||||||
|
for (unsigned int a = 0, end = static_cast<unsigned int>(source_mesh_map.size()); a < end;++a) {
|
||||||
|
if (source_mesh_map[a].second == pcNode->mMeshes[i]) {
|
||||||
|
aiEntries.push_back(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// now build the new list
|
||||||
|
delete pcNode->mMeshes;
|
||||||
|
pcNode->mNumMeshes = static_cast<unsigned int>(aiEntries.size());
|
||||||
|
pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
|
||||||
|
|
||||||
|
for (unsigned int b = 0; b < pcNode->mNumMeshes;++b) {
|
||||||
|
pcNode->mMeshes[b] = aiEntries[b];
|
||||||
|
}
|
||||||
|
|
||||||
|
// recursively update children
|
||||||
|
for (unsigned int i = 0, end = pcNode->mNumChildren; i < end;++i) {
|
||||||
|
UpdateNode ( pcNode->mChildren[i], source_mesh_map );
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WAS_NOT_COPIED 0xffffffff
|
||||||
|
|
||||||
|
typedef std::pair <unsigned int,float> PerVertexWeight;
|
||||||
|
typedef std::vector <PerVertexWeight> VertexWeightTable;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
VertexWeightTable* ComputeVertexBoneWeightTable(const aiMesh* pMesh) {
|
||||||
|
if (!pMesh || !pMesh->mNumVertices || !pMesh->mNumBones) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
VertexWeightTable* const avPerVertexWeights = new VertexWeightTable[pMesh->mNumVertices];
|
||||||
|
for (unsigned int i = 0; i < pMesh->mNumBones;++i) {
|
||||||
|
|
||||||
|
aiBone* bone = pMesh->mBones[i];
|
||||||
|
for (unsigned int a = 0; a < bone->mNumWeights;++a) {
|
||||||
|
const aiVertexWeight& weight = bone->mWeights[a];
|
||||||
|
avPerVertexWeights[weight.mVertexId].push_back( std::make_pair(i,weight.mWeight) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return avPerVertexWeights;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void MeshSplitter :: SplitMesh(unsigned int a, aiMesh* in_mesh, std::vector<std::pair<aiMesh*, unsigned int> >& source_mesh_map) {
|
||||||
|
// TODO: should better use std::(multi)set for source_mesh_map.
|
||||||
|
|
||||||
|
if (in_mesh->mNumVertices <= LIMIT) {
|
||||||
|
source_mesh_map.push_back(std::make_pair(in_mesh,a));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// build a per-vertex weight list if necessary
|
||||||
|
VertexWeightTable* avPerVertexWeights = ComputeVertexBoneWeightTable(in_mesh);
|
||||||
|
|
||||||
|
// we need to split this mesh into sub meshes. Estimate submesh size
|
||||||
|
const unsigned int sub_meshes = (in_mesh->mNumVertices / LIMIT) + 1;
|
||||||
|
|
||||||
|
// create a std::vector<unsigned int> to remember which vertices have already
|
||||||
|
// been copied and to which position (i.e. output index)
|
||||||
|
std::vector<unsigned int> was_copied_to;
|
||||||
|
was_copied_to.resize(in_mesh->mNumVertices,WAS_NOT_COPIED);
|
||||||
|
|
||||||
|
// Try to find a good estimate for the number of output faces
|
||||||
|
// per mesh. Add 12.5% as buffer
|
||||||
|
unsigned int size_estimated = in_mesh->mNumFaces / sub_meshes;
|
||||||
|
size_estimated += size_estimated / 8;
|
||||||
|
|
||||||
|
// now generate all submeshes
|
||||||
|
unsigned int base = 0;
|
||||||
|
while (true) {
|
||||||
|
const unsigned int out_vertex_index = LIMIT;
|
||||||
|
|
||||||
|
aiMesh* out_mesh = new aiMesh();
|
||||||
|
out_mesh->mNumVertices = 0;
|
||||||
|
out_mesh->mMaterialIndex = in_mesh->mMaterialIndex;
|
||||||
|
|
||||||
|
// the name carries the adjacency information between the meshes
|
||||||
|
out_mesh->mName = in_mesh->mName;
|
||||||
|
|
||||||
|
typedef std::vector<aiVertexWeight> BoneWeightList;
|
||||||
|
if (in_mesh->HasBones()) {
|
||||||
|
out_mesh->mBones = new aiBone*[in_mesh->mNumBones]();
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear the temporary helper array
|
||||||
|
if (base) {
|
||||||
|
std::fill(was_copied_to.begin(), was_copied_to.end(), WAS_NOT_COPIED);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<aiFace> vFaces;
|
||||||
|
|
||||||
|
// reserve enough storage for most cases
|
||||||
|
if (in_mesh->HasPositions()) {
|
||||||
|
out_mesh->mVertices = new aiVector3D[out_vertex_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_mesh->HasNormals()) {
|
||||||
|
out_mesh->mNormals = new aiVector3D[out_vertex_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_mesh->HasTangentsAndBitangents()) {
|
||||||
|
out_mesh->mTangents = new aiVector3D[out_vertex_index];
|
||||||
|
out_mesh->mBitangents = new aiVector3D[out_vertex_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int c = 0; in_mesh->HasVertexColors(c);++c) {
|
||||||
|
out_mesh->mColors[c] = new aiColor4D[out_vertex_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int c = 0; in_mesh->HasTextureCoords(c);++c) {
|
||||||
|
out_mesh->mNumUVComponents[c] = in_mesh->mNumUVComponents[c];
|
||||||
|
out_mesh->mTextureCoords[c] = new aiVector3D[out_vertex_index];
|
||||||
|
}
|
||||||
|
vFaces.reserve(size_estimated);
|
||||||
|
|
||||||
|
// (we will also need to copy the array of indices)
|
||||||
|
while (base < in_mesh->mNumFaces) {
|
||||||
|
const unsigned int iNumIndices = in_mesh->mFaces[base].mNumIndices;
|
||||||
|
|
||||||
|
// doesn't catch degenerates but is quite fast
|
||||||
|
unsigned int iNeed = 0;
|
||||||
|
for (unsigned int v = 0; v < iNumIndices;++v) {
|
||||||
|
unsigned int index = in_mesh->mFaces[base].mIndices[v];
|
||||||
|
|
||||||
|
// check whether we do already have this vertex
|
||||||
|
if (WAS_NOT_COPIED == was_copied_to[index]) {
|
||||||
|
iNeed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (out_mesh->mNumVertices + iNeed > out_vertex_index) {
|
||||||
|
// don't use this face
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
vFaces.push_back(aiFace());
|
||||||
|
aiFace& rFace = vFaces.back();
|
||||||
|
|
||||||
|
// setup face type and number of indices
|
||||||
|
rFace.mNumIndices = iNumIndices;
|
||||||
|
rFace.mIndices = new unsigned int[iNumIndices];
|
||||||
|
|
||||||
|
// need to update the output primitive types
|
||||||
|
switch (rFace.mNumIndices)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
out_mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
out_mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
out_mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
out_mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
|
||||||
|
}
|
||||||
|
|
||||||
|
// and copy the contents of the old array, offset them by current base
|
||||||
|
for (unsigned int v = 0; v < iNumIndices;++v) {
|
||||||
|
const unsigned int index = in_mesh->mFaces[base].mIndices[v];
|
||||||
|
|
||||||
|
// check whether we do already have this vertex
|
||||||
|
if (WAS_NOT_COPIED != was_copied_to[index]) {
|
||||||
|
rFace.mIndices[v] = was_copied_to[index];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy positions
|
||||||
|
out_mesh->mVertices[out_mesh->mNumVertices] = (in_mesh->mVertices[index]);
|
||||||
|
|
||||||
|
// copy normals
|
||||||
|
if (in_mesh->HasNormals()) {
|
||||||
|
out_mesh->mNormals[out_mesh->mNumVertices] = (in_mesh->mNormals[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy tangents/bi-tangents
|
||||||
|
if (in_mesh->HasTangentsAndBitangents()) {
|
||||||
|
out_mesh->mTangents[out_mesh->mNumVertices] = (in_mesh->mTangents[index]);
|
||||||
|
out_mesh->mBitangents[out_mesh->mNumVertices] = (in_mesh->mBitangents[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// texture coordinates
|
||||||
|
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) {
|
||||||
|
if (in_mesh->HasTextureCoords( c)) {
|
||||||
|
out_mesh->mTextureCoords[c][out_mesh->mNumVertices] = in_mesh->mTextureCoords[c][index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// vertex colors
|
||||||
|
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS;++c) {
|
||||||
|
if (in_mesh->HasVertexColors( c)) {
|
||||||
|
out_mesh->mColors[c][out_mesh->mNumVertices] = in_mesh->mColors[c][index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// check whether we have bone weights assigned to this vertex
|
||||||
|
rFace.mIndices[v] = out_mesh->mNumVertices;
|
||||||
|
if (avPerVertexWeights) {
|
||||||
|
VertexWeightTable& table = avPerVertexWeights[ out_mesh->mNumVertices ];
|
||||||
|
for (VertexWeightTable::const_iterator iter = table.begin(), end = table.end(); iter != end;++iter) {
|
||||||
|
// allocate the bone weight array if necessary and store it in the mBones field (HACK!)
|
||||||
|
BoneWeightList* weight_list = reinterpret_cast<BoneWeightList*>(out_mesh->mBones[(*iter).first]);
|
||||||
|
if (!weight_list) {
|
||||||
|
weight_list = new BoneWeightList();
|
||||||
|
out_mesh->mBones[(*iter).first] = reinterpret_cast<aiBone*>(weight_list);
|
||||||
|
}
|
||||||
|
weight_list->push_back(aiVertexWeight(out_mesh->mNumVertices,(*iter).second));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
was_copied_to[index] = out_mesh->mNumVertices;
|
||||||
|
out_mesh->mNumVertices++;
|
||||||
|
}
|
||||||
|
base++;
|
||||||
|
if(out_mesh->mNumVertices == out_vertex_index) {
|
||||||
|
// break here. The face is only added if it was complete
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check which bones we'll need to create for this submesh
|
||||||
|
if (in_mesh->HasBones()) {
|
||||||
|
aiBone** ppCurrent = out_mesh->mBones;
|
||||||
|
for (unsigned int k = 0; k < in_mesh->mNumBones;++k) {
|
||||||
|
// check whether the bone exists
|
||||||
|
BoneWeightList* const weight_list = reinterpret_cast<BoneWeightList*>(out_mesh->mBones[k]);
|
||||||
|
|
||||||
|
if (weight_list) {
|
||||||
|
const aiBone* const bone_in = in_mesh->mBones[k];
|
||||||
|
aiBone* const bone_out = new aiBone();
|
||||||
|
*ppCurrent++ = bone_out;
|
||||||
|
bone_out->mName = aiString(bone_in->mName);
|
||||||
|
bone_out->mOffsetMatrix =bone_in->mOffsetMatrix;
|
||||||
|
bone_out->mNumWeights = (unsigned int)weight_list->size();
|
||||||
|
bone_out->mWeights = new aiVertexWeight[bone_out->mNumWeights];
|
||||||
|
|
||||||
|
// copy the vertex weights
|
||||||
|
::memcpy(bone_out->mWeights, &(*weight_list)[0],bone_out->mNumWeights * sizeof(aiVertexWeight));
|
||||||
|
|
||||||
|
delete weight_list;
|
||||||
|
out_mesh->mNumBones++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy the face list to the mesh
|
||||||
|
out_mesh->mFaces = new aiFace[vFaces.size()];
|
||||||
|
out_mesh->mNumFaces = (unsigned int)vFaces.size();
|
||||||
|
|
||||||
|
for (unsigned int p = 0; p < out_mesh->mNumFaces;++p) {
|
||||||
|
out_mesh->mFaces[p] = vFaces[p];
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the newly created mesh to the list
|
||||||
|
source_mesh_map.push_back(std::make_pair(out_mesh,a));
|
||||||
|
|
||||||
|
if (base == in_mesh->mNumFaces) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete the per-vertex weight list again
|
||||||
|
delete[] avPerVertexWeights;
|
||||||
|
|
||||||
|
// now delete the old mesh data
|
||||||
|
delete in_mesh;
|
||||||
|
}
|
||||||
61
Engine/lib/assimp/code/Assjson/mesh_splitter.h
Normal file
61
Engine/lib/assimp/code/Assjson/mesh_splitter.h
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
Assimp2Json
|
||||||
|
Copyright (c) 2011, Alexander C. Gessler
|
||||||
|
|
||||||
|
Licensed under a 3-clause BSD license. See the LICENSE file for more information.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_MESH_SPLITTER
|
||||||
|
#define INCLUDED_MESH_SPLITTER
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Note: this is largely based on assimp's SplitLargeMeshes_Vertex process.
|
||||||
|
// it is refactored and the coding style is slightly improved, though.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
struct aiScene;
|
||||||
|
struct aiMesh;
|
||||||
|
struct aiNode;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** Splits meshes of unique vertices into meshes with no more vertices than
|
||||||
|
* a given, configurable threshold value.
|
||||||
|
*/
|
||||||
|
class MeshSplitter
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void SetLimit(unsigned int l) {
|
||||||
|
LIMIT = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int GetLimit() const {
|
||||||
|
return LIMIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Executes the post processing step on the given imported data.
|
||||||
|
* At the moment a process is not supposed to fail.
|
||||||
|
* @param pScene The imported data to work at.
|
||||||
|
*/
|
||||||
|
void Execute( aiScene* pScene);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void UpdateNode(aiNode* pcNode, const std::vector<std::pair<aiMesh*, unsigned int> >& source_mesh_map);
|
||||||
|
void SplitMesh (unsigned int index, aiMesh* mesh, std::vector<std::pair<aiMesh*, unsigned int> >& source_mesh_map);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
unsigned int LIMIT;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // INCLUDED_MESH_SPLITTER
|
||||||
|
|
||||||
|
|
@ -46,13 +46,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||||
#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include "PostProcessing/ProcessHelper.h"
|
||||||
|
|
||||||
#include <assimp/version.h>
|
#include <assimp/version.h>
|
||||||
#include "ProcessHelper.h"
|
|
||||||
#include <assimp/IOStream.hpp>
|
#include <assimp/IOStream.hpp>
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
#include <assimp/Exporter.hpp>
|
#include <assimp/Exporter.hpp>
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
||||||
# include <zlib.h>
|
# include <zlib.h>
|
||||||
#else
|
#else
|
||||||
|
|
@ -555,8 +557,6 @@ void WriteDump(const aiScene* scene, IOStream* io, bool shortened) {
|
||||||
mesh->mNormals[n].z);
|
mesh->mNormals[n].z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
}
|
|
||||||
ioprintf(io,"\t\t</Normals>\n");
|
ioprintf(io,"\t\t</Normals>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -49,17 +49,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef ASSIMP_BUILD_NO_B3D_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_B3D_IMPORTER
|
||||||
|
|
||||||
// internal headers
|
// internal headers
|
||||||
#include "B3DImporter.h"
|
#include "B3D/B3DImporter.h"
|
||||||
#include "TextureTransform.h"
|
#include "PostProcessing/TextureTransform.h"
|
||||||
#include "ConvertToLHProcess.h"
|
#include "PostProcessing/ConvertToLHProcess.h"
|
||||||
|
|
||||||
#include <assimp/StringUtils.h>
|
#include <assimp/StringUtils.h>
|
||||||
#include <memory>
|
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
#include <assimp/anim.h>
|
#include <assimp/anim.h>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/importerdesc.h>
|
#include <assimp/importerdesc.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
@ -1,361 +0,0 @@
|
||||||
/*
|
|
||||||
Open Asset Import Library (assimp)
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2006-2017, 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 Definition of the base class for all importer worker classes. */
|
|
||||||
#ifndef INCLUDED_AI_BASEIMPORTER_H
|
|
||||||
#define INCLUDED_AI_BASEIMPORTER_H
|
|
||||||
|
|
||||||
#include "Exceptional.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <set>
|
|
||||||
#include <assimp/types.h>
|
|
||||||
#include <assimp/ProgressHandler.hpp>
|
|
||||||
|
|
||||||
struct aiScene;
|
|
||||||
struct aiImporterDesc;
|
|
||||||
|
|
||||||
namespace Assimp {
|
|
||||||
|
|
||||||
class Importer;
|
|
||||||
class IOSystem;
|
|
||||||
class BaseProcess;
|
|
||||||
class SharedPostProcessInfo;
|
|
||||||
class IOStream;
|
|
||||||
|
|
||||||
// utility to do char4 to uint32 in a portable manner
|
|
||||||
#define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \
|
|
||||||
(string[1] << 16) + (string[2] << 8) + string[3]))
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
/** FOR IMPORTER PLUGINS ONLY: The BaseImporter defines a common interface
|
|
||||||
* for all importer worker classes.
|
|
||||||
*
|
|
||||||
* The interface defines two functions: CanRead() is used to check if the
|
|
||||||
* importer can handle the format of the given file. If an implementation of
|
|
||||||
* this function returns true, the importer then calls ReadFile() which
|
|
||||||
* imports the given file. ReadFile is not overridable, it just calls
|
|
||||||
* InternReadFile() and catches any ImportErrorException that might occur.
|
|
||||||
*/
|
|
||||||
class ASSIMP_API BaseImporter
|
|
||||||
{
|
|
||||||
friend class Importer;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/** Constructor to be privately used by #Importer */
|
|
||||||
BaseImporter();
|
|
||||||
|
|
||||||
/** Destructor, private as well */
|
|
||||||
virtual ~BaseImporter();
|
|
||||||
|
|
||||||
public:
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Returns whether the class can handle the format of the given file.
|
|
||||||
*
|
|
||||||
* The implementation should be as quick as possible. A check for
|
|
||||||
* the file extension is enough. If no suitable loader is found with
|
|
||||||
* this strategy, CanRead() is called again, the 'checkSig' parameter
|
|
||||||
* set to true this time. Now the implementation is expected to
|
|
||||||
* perform a full check of the file structure, possibly searching the
|
|
||||||
* first bytes of the file for magic identifiers or keywords.
|
|
||||||
*
|
|
||||||
* @param pFile Path and file name of the file to be examined.
|
|
||||||
* @param pIOHandler The IO handler to use for accessing any file.
|
|
||||||
* @param checkSig Set to true if this method is called a second time.
|
|
||||||
* This time, the implementation may take more time to examine the
|
|
||||||
* contents of the file to be loaded for magic bytes, keywords, etc
|
|
||||||
* to be able to load files with unknown/not existent file extensions.
|
|
||||||
* @return true if the class can read this file, false if not.
|
|
||||||
*/
|
|
||||||
virtual bool CanRead(
|
|
||||||
const std::string& pFile,
|
|
||||||
IOSystem* pIOHandler,
|
|
||||||
bool checkSig
|
|
||||||
) const = 0;
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Imports the given file and returns the imported data.
|
|
||||||
* If the import succeeds, ownership of the data is transferred to
|
|
||||||
* the caller. If the import fails, NULL is returned. The function
|
|
||||||
* takes care that any partially constructed data is destroyed
|
|
||||||
* beforehand.
|
|
||||||
*
|
|
||||||
* @param pImp #Importer object hosting this loader.
|
|
||||||
* @param pFile Path of the file to be imported.
|
|
||||||
* @param pIOHandler IO-Handler used to open this and possible other files.
|
|
||||||
* @return The imported data or NULL if failed. If it failed a
|
|
||||||
* human-readable error description can be retrieved by calling
|
|
||||||
* GetErrorText()
|
|
||||||
*
|
|
||||||
* @note This function is not intended to be overridden. Implement
|
|
||||||
* InternReadFile() to do the import. If an exception is thrown somewhere
|
|
||||||
* in InternReadFile(), this function will catch it and transform it into
|
|
||||||
* a suitable response to the caller.
|
|
||||||
*/
|
|
||||||
aiScene* ReadFile(
|
|
||||||
const Importer* pImp,
|
|
||||||
const std::string& pFile,
|
|
||||||
IOSystem* pIOHandler
|
|
||||||
);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Returns the error description of the last error that occurred.
|
|
||||||
* @return A description of the last error that occurred. An empty
|
|
||||||
* string if there was no error.
|
|
||||||
*/
|
|
||||||
const std::string& GetErrorText() const {
|
|
||||||
return m_ErrorText;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Called prior to ReadFile().
|
|
||||||
* The function is a request to the importer to update its configuration
|
|
||||||
* basing on the Importer's configuration property list.
|
|
||||||
* @param pImp Importer instance
|
|
||||||
*/
|
|
||||||
virtual void SetupProperties(
|
|
||||||
const Importer* pImp
|
|
||||||
);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Called by #Importer::GetImporterInfo to get a description of
|
|
||||||
* some loader features. Importers must provide this information. */
|
|
||||||
virtual const aiImporterDesc* GetInfo() const = 0;
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Called by #Importer::GetExtensionList for each loaded importer.
|
|
||||||
* Take the extension list contained in the structure returned by
|
|
||||||
* #GetInfo and insert all file extensions into the given set.
|
|
||||||
* @param extension set to collect file extensions in*/
|
|
||||||
void GetExtensionList(std::set<std::string>& extensions);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Imports the given file into the given scene structure. The
|
|
||||||
* function is expected to throw an ImportErrorException if there is
|
|
||||||
* an error. If it terminates normally, the data in aiScene is
|
|
||||||
* expected to be correct. Override this function to implement the
|
|
||||||
* actual importing.
|
|
||||||
* <br>
|
|
||||||
* The output scene must meet the following requirements:<br>
|
|
||||||
* <ul>
|
|
||||||
* <li>At least a root node must be there, even if its only purpose
|
|
||||||
* is to reference one mesh.</li>
|
|
||||||
* <li>aiMesh::mPrimitiveTypes may be 0. The types of primitives
|
|
||||||
* in the mesh are determined automatically in this case.</li>
|
|
||||||
* <li>the vertex data is stored in a pseudo-indexed "verbose" format.
|
|
||||||
* In fact this means that every vertex that is referenced by
|
|
||||||
* a face is unique. Or the other way round: a vertex index may
|
|
||||||
* not occur twice in a single aiMesh.</li>
|
|
||||||
* <li>aiAnimation::mDuration may be -1. Assimp determines the length
|
|
||||||
* of the animation automatically in this case as the length of
|
|
||||||
* the longest animation channel.</li>
|
|
||||||
* <li>aiMesh::mBitangents may be NULL if tangents and normals are
|
|
||||||
* given. In this case bitangents are computed as the cross product
|
|
||||||
* between normal and tangent.</li>
|
|
||||||
* <li>There needn't be a material. If none is there a default material
|
|
||||||
* is generated. However, it is recommended practice for loaders
|
|
||||||
* to generate a default material for yourself that matches the
|
|
||||||
* default material setting for the file format better than Assimp's
|
|
||||||
* generic default material. Note that default materials *should*
|
|
||||||
* be named AI_DEFAULT_MATERIAL_NAME if they're just color-shaded
|
|
||||||
* or AI_DEFAULT_TEXTURED_MATERIAL_NAME if they define a (dummy)
|
|
||||||
* texture. </li>
|
|
||||||
* </ul>
|
|
||||||
* If the AI_SCENE_FLAGS_INCOMPLETE-Flag is <b>not</b> set:<ul>
|
|
||||||
* <li> at least one mesh must be there</li>
|
|
||||||
* <li> there may be no meshes with 0 vertices or faces</li>
|
|
||||||
* </ul>
|
|
||||||
* This won't be checked (except by the validation step): Assimp will
|
|
||||||
* crash if one of the conditions is not met!
|
|
||||||
*
|
|
||||||
* @param pFile Path of the file to be imported.
|
|
||||||
* @param pScene The scene object to hold the imported data.
|
|
||||||
* NULL is not a valid parameter.
|
|
||||||
* @param pIOHandler The IO handler to use for any file access.
|
|
||||||
* NULL is not a valid parameter. */
|
|
||||||
virtual void InternReadFile(
|
|
||||||
const std::string& pFile,
|
|
||||||
aiScene* pScene,
|
|
||||||
IOSystem* pIOHandler
|
|
||||||
) = 0;
|
|
||||||
|
|
||||||
public: // static utilities
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** A utility for CanRead().
|
|
||||||
*
|
|
||||||
* The function searches the header of a file for a specific token
|
|
||||||
* and returns true if this token is found. This works for text
|
|
||||||
* files only. There is a rudimentary handling of UNICODE files.
|
|
||||||
* The comparison is case independent.
|
|
||||||
*
|
|
||||||
* @param pIOSystem IO System to work with
|
|
||||||
* @param file File name of the file
|
|
||||||
* @param tokens List of tokens to search for
|
|
||||||
* @param numTokens Size of the token array
|
|
||||||
* @param searchBytes Number of bytes to be searched for the tokens.
|
|
||||||
*/
|
|
||||||
static bool SearchFileHeaderForToken(
|
|
||||||
IOSystem* pIOSystem,
|
|
||||||
const std::string& file,
|
|
||||||
const char** tokens,
|
|
||||||
unsigned int numTokens,
|
|
||||||
unsigned int searchBytes = 200,
|
|
||||||
bool tokensSol = false);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** @brief Check whether a file has a specific file extension
|
|
||||||
* @param pFile Input file
|
|
||||||
* @param ext0 Extension to check for. Lowercase characters only, no dot!
|
|
||||||
* @param ext1 Optional second extension
|
|
||||||
* @param ext2 Optional third extension
|
|
||||||
* @note Case-insensitive
|
|
||||||
*/
|
|
||||||
static bool SimpleExtensionCheck (
|
|
||||||
const std::string& pFile,
|
|
||||||
const char* ext0,
|
|
||||||
const char* ext1 = NULL,
|
|
||||||
const char* ext2 = NULL);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** @brief Extract file extension from a string
|
|
||||||
* @param pFile Input file
|
|
||||||
* @return Extension without trailing dot, all lowercase
|
|
||||||
*/
|
|
||||||
static std::string GetExtension (
|
|
||||||
const std::string& pFile);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** @brief Check whether a file starts with one or more magic tokens
|
|
||||||
* @param pFile Input file
|
|
||||||
* @param pIOHandler IO system to be used
|
|
||||||
* @param magic n magic tokens
|
|
||||||
* @params num Size of magic
|
|
||||||
* @param offset Offset from file start where tokens are located
|
|
||||||
* @param Size of one token, in bytes. Maximally 16 bytes.
|
|
||||||
* @return true if one of the given tokens was found
|
|
||||||
*
|
|
||||||
* @note For convenience, the check is also performed for the
|
|
||||||
* byte-swapped variant of all tokens (big endian). Only for
|
|
||||||
* tokens of size 2,4.
|
|
||||||
*/
|
|
||||||
static bool CheckMagicToken(
|
|
||||||
IOSystem* pIOHandler,
|
|
||||||
const std::string& pFile,
|
|
||||||
const void* magic,
|
|
||||||
unsigned int num,
|
|
||||||
unsigned int offset = 0,
|
|
||||||
unsigned int size = 4);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** An utility for all text file loaders. It converts a file to our
|
|
||||||
* UTF8 character set. Errors are reported, but ignored.
|
|
||||||
*
|
|
||||||
* @param data File buffer to be converted to UTF8 data. The buffer
|
|
||||||
* is resized as appropriate. */
|
|
||||||
static void ConvertToUTF8(
|
|
||||||
std::vector<char>& data);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** An utility for all text file loaders. It converts a file from our
|
|
||||||
* UTF8 character set back to ISO-8859-1. Errors are reported, but ignored.
|
|
||||||
*
|
|
||||||
* @param data File buffer to be converted from UTF8 to ISO-8859-1. The buffer
|
|
||||||
* is resized as appropriate. */
|
|
||||||
static void ConvertUTF8toISO8859_1(
|
|
||||||
std::string& data);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/// @brief Enum to define, if empty files are ok or not.
|
|
||||||
enum TextFileMode {
|
|
||||||
ALLOW_EMPTY,
|
|
||||||
FORBID_EMPTY
|
|
||||||
};
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Utility for text file loaders which copies the contents of the
|
|
||||||
* file into a memory buffer and converts it to our UTF8
|
|
||||||
* representation.
|
|
||||||
* @param stream Stream to read from.
|
|
||||||
* @param data Output buffer to be resized and filled with the
|
|
||||||
* converted text file data. The buffer is terminated with
|
|
||||||
* a binary 0.
|
|
||||||
* @param mode Whether it is OK to load empty text files. */
|
|
||||||
static void TextFileToBuffer(
|
|
||||||
IOStream* stream,
|
|
||||||
std::vector<char>& data,
|
|
||||||
TextFileMode mode = FORBID_EMPTY);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Utility function to move a std::vector into a aiScene array
|
|
||||||
* @param vec The vector to be moved
|
|
||||||
* @param out The output pointer to the allocated array.
|
|
||||||
* @param numOut The output count of elements copied. */
|
|
||||||
template<typename T>
|
|
||||||
AI_FORCE_INLINE
|
|
||||||
static void CopyVector(
|
|
||||||
std::vector<T>& vec,
|
|
||||||
T*& out,
|
|
||||||
unsigned int& outLength)
|
|
||||||
{
|
|
||||||
outLength = unsigned(vec.size());
|
|
||||||
if (outLength) {
|
|
||||||
out = new T[outLength];
|
|
||||||
std::swap_ranges(vec.begin(), vec.end(), out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/// Error description in case there was one.
|
|
||||||
std::string m_ErrorText;
|
|
||||||
/// Currently set progress handler.
|
|
||||||
ProgressHandler* m_progress;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // end of namespace Assimp
|
|
||||||
|
|
||||||
#endif // AI_BASEIMPORTER_H_INC
|
|
||||||
|
|
@ -1,123 +0,0 @@
|
||||||
/*
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
Open Asset Import Library (assimp)
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2006-2017, 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 Bitmap.h
|
|
||||||
* @brief Defines bitmap format helper for textures
|
|
||||||
*
|
|
||||||
* Used for file formats which embed their textures into the model file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef AI_BITMAP_H_INC
|
|
||||||
#define AI_BITMAP_H_INC
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <cstddef>
|
|
||||||
|
|
||||||
struct aiTexture;
|
|
||||||
|
|
||||||
namespace Assimp {
|
|
||||||
|
|
||||||
class IOStream;
|
|
||||||
|
|
||||||
class Bitmap {
|
|
||||||
protected:
|
|
||||||
|
|
||||||
struct Header {
|
|
||||||
uint16_t type;
|
|
||||||
uint32_t size;
|
|
||||||
uint16_t reserved1;
|
|
||||||
uint16_t reserved2;
|
|
||||||
uint32_t offset;
|
|
||||||
|
|
||||||
// We define the struct size because sizeof(Header) might return a wrong result because of structure padding.
|
|
||||||
// Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field).
|
|
||||||
static const std::size_t header_size =
|
|
||||||
sizeof(uint16_t) + // type
|
|
||||||
sizeof(uint32_t) + // size
|
|
||||||
sizeof(uint16_t) + // reserved1
|
|
||||||
sizeof(uint16_t) + // reserved2
|
|
||||||
sizeof(uint32_t); // offset
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DIB {
|
|
||||||
uint32_t size;
|
|
||||||
int32_t width;
|
|
||||||
int32_t height;
|
|
||||||
uint16_t planes;
|
|
||||||
uint16_t bits_per_pixel;
|
|
||||||
uint32_t compression;
|
|
||||||
uint32_t image_size;
|
|
||||||
int32_t x_resolution;
|
|
||||||
int32_t y_resolution;
|
|
||||||
uint32_t nb_colors;
|
|
||||||
uint32_t nb_important_colors;
|
|
||||||
|
|
||||||
// We define the struct size because sizeof(DIB) might return a wrong result because of structure padding.
|
|
||||||
// Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field).
|
|
||||||
static const std::size_t dib_size =
|
|
||||||
sizeof(uint32_t) + // size
|
|
||||||
sizeof(int32_t) + // width
|
|
||||||
sizeof(int32_t) + // height
|
|
||||||
sizeof(uint16_t) + // planes
|
|
||||||
sizeof(uint16_t) + // bits_per_pixel
|
|
||||||
sizeof(uint32_t) + // compression
|
|
||||||
sizeof(uint32_t) + // image_size
|
|
||||||
sizeof(int32_t) + // x_resolution
|
|
||||||
sizeof(int32_t) + // y_resolution
|
|
||||||
sizeof(uint32_t) + // nb_colors
|
|
||||||
sizeof(uint32_t); // nb_important_colors
|
|
||||||
};
|
|
||||||
|
|
||||||
static const std::size_t mBytesPerPixel = 4;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static void Save(aiTexture* texture, IOStream* file);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static void WriteHeader(Header& header, IOStream* file);
|
|
||||||
static void WriteDIB(DIB& dib, IOStream* file);
|
|
||||||
static void WriteData(aiTexture* texture, IOStream* file);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // AI_BITMAP_H_INC
|
|
||||||
|
|
@ -416,7 +416,7 @@ template <> struct Structure :: _defaultInitializer<ErrorPolicy_Fail> {
|
||||||
void operator ()(T& /*out*/,const char* = "") {
|
void operator ()(T& /*out*/,const char* = "") {
|
||||||
// obviously, it is crucial that _DefaultInitializer is used
|
// obviously, it is crucial that _DefaultInitializer is used
|
||||||
// only from within a catch clause.
|
// only from within a catch clause.
|
||||||
throw;
|
throw DeadlyImportError("Constructing BlenderDNA Structure encountered an error");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1225,6 +1225,16 @@ aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* obj, c
|
||||||
case Lamp::Type_Local:
|
case Lamp::Type_Local:
|
||||||
out->mType = aiLightSource_POINT;
|
out->mType = aiLightSource_POINT;
|
||||||
break;
|
break;
|
||||||
|
case Lamp::Type_Spot:
|
||||||
|
out->mType = aiLightSource_SPOT;
|
||||||
|
|
||||||
|
// blender orients directional lights as facing toward -z
|
||||||
|
out->mDirection = aiVector3D(0.f, 0.f, -1.f);
|
||||||
|
out->mUp = aiVector3D(0.f, 1.f, 0.f);
|
||||||
|
|
||||||
|
out->mAngleInnerCone = lamp->spotsize * (1.0f - lamp->spotblend);
|
||||||
|
out->mAngleOuterCone = lamp->spotsize;
|
||||||
|
break;
|
||||||
case Lamp::Type_Sun:
|
case Lamp::Type_Sun:
|
||||||
out->mType = aiLightSource_DIRECTIONAL;
|
out->mType = aiLightSource_DIRECTIONAL;
|
||||||
|
|
||||||
|
|
@ -1255,6 +1265,23 @@ aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* obj, c
|
||||||
out->mColorAmbient = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy;
|
out->mColorAmbient = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy;
|
||||||
out->mColorSpecular = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy;
|
out->mColorSpecular = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy;
|
||||||
out->mColorDiffuse = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy;
|
out->mColorDiffuse = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy;
|
||||||
|
|
||||||
|
// If default values are supplied, compute the coefficients from light's max distance
|
||||||
|
// Read this: https://imdoingitwrong.wordpress.com/2011/01/31/light-attenuation/
|
||||||
|
//
|
||||||
|
if (lamp->constant_coefficient == 1.0f && lamp->linear_coefficient == 0.0f && lamp->quadratic_coefficient == 0.0f && lamp->dist > 0.0f)
|
||||||
|
{
|
||||||
|
out->mAttenuationConstant = 1.0f;
|
||||||
|
out->mAttenuationLinear = 2.0f / lamp->dist;
|
||||||
|
out->mAttenuationQuadratic = 1.0f / (lamp->dist * lamp->dist);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out->mAttenuationConstant = lamp->constant_coefficient;
|
||||||
|
out->mAttenuationLinear = lamp->linear_coefficient;
|
||||||
|
out->mAttenuationQuadratic = lamp->quadratic_coefficient;
|
||||||
|
}
|
||||||
|
|
||||||
return out.release();
|
return out.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -211,9 +211,12 @@ template <> void Structure :: Convert<Lamp> (
|
||||||
ReadField<ErrorPolicy_Warn>(dest.b,"b",db);
|
ReadField<ErrorPolicy_Warn>(dest.b,"b",db);
|
||||||
ReadField<ErrorPolicy_Warn>(dest.k,"k",db);
|
ReadField<ErrorPolicy_Warn>(dest.k,"k",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.energy,"energy",db);
|
ReadField<ErrorPolicy_Igno>(dest.energy,"energy",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.dist,"dist",db);
|
ReadField<ErrorPolicy_Warn>(dest.dist,"dist",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.spotsize,"spotsize",db);
|
ReadField<ErrorPolicy_Igno>(dest.spotsize,"spotsize",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.spotblend,"spotblend",db);
|
ReadField<ErrorPolicy_Igno>(dest.spotblend,"spotblend",db);
|
||||||
|
ReadField<ErrorPolicy_Warn>(dest.constant_coefficient, "coeff_const", db);
|
||||||
|
ReadField<ErrorPolicy_Warn>(dest.linear_coefficient, "coeff_lin", db);
|
||||||
|
ReadField<ErrorPolicy_Warn>(dest.quadratic_coefficient, "coeff_quad", db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.att1,"att1",db);
|
ReadField<ErrorPolicy_Igno>(dest.att1,"att1",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.att2,"att2",db);
|
ReadField<ErrorPolicy_Igno>(dest.att2,"att2",db);
|
||||||
ReadField<ErrorPolicy_Igno>(temp,"falloff_type",db);
|
ReadField<ErrorPolicy_Igno>(temp,"falloff_type",db);
|
||||||
|
|
@ -538,6 +538,10 @@ struct Lamp : ElemBase {
|
||||||
float energy, dist, spotsize, spotblend;
|
float energy, dist, spotsize, spotblend;
|
||||||
//float haint;
|
//float haint;
|
||||||
|
|
||||||
|
float constant_coefficient;
|
||||||
|
float linear_coefficient;
|
||||||
|
float quadratic_coefficient;
|
||||||
|
|
||||||
float att1, att2;
|
float att1, att2;
|
||||||
//struct CurveMapping *curfalloff;
|
//struct CurveMapping *curfalloff;
|
||||||
FalloffType falloff_type;
|
FalloffType falloff_type;
|
||||||
|
|
@ -144,7 +144,11 @@ namespace Assimp
|
||||||
|
|
||||||
#if ASSIMP_BLEND_WITH_POLY_2_TRI
|
#if ASSIMP_BLEND_WITH_POLY_2_TRI
|
||||||
|
|
||||||
#include "../contrib/poly2tri/poly2tri/poly2tri.h"
|
#ifdef ASSIMP_USE_HUNTER
|
||||||
|
# include <poly2tri/poly2tri.h>
|
||||||
|
#else
|
||||||
|
# include "../contrib/poly2tri/poly2tri/poly2tri.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
|
|
@ -1,337 +0,0 @@
|
||||||
/*
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
Open Asset Import Library (assimp)
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2006-2017, 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 Provides cheat implementations for IOSystem and IOStream to
|
|
||||||
* redirect exporter output to a blob chain.*/
|
|
||||||
|
|
||||||
#ifndef AI_BLOBIOSYSTEM_H_INCLUDED
|
|
||||||
#define AI_BLOBIOSYSTEM_H_INCLUDED
|
|
||||||
|
|
||||||
#include <assimp/IOStream.hpp>
|
|
||||||
#include <assimp/cexport.h>
|
|
||||||
#include <assimp/IOSystem.hpp>
|
|
||||||
#include <assimp/DefaultLogger.hpp>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <set>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace Assimp {
|
|
||||||
class BlobIOSystem;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
|
||||||
/** Redirect IOStream to a blob */
|
|
||||||
// --------------------------------------------------------------------------------------------
|
|
||||||
class BlobIOStream : public IOStream
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
BlobIOStream(BlobIOSystem* creator, const std::string& file, size_t initial = 4096)
|
|
||||||
: buffer()
|
|
||||||
, cur_size()
|
|
||||||
, file_size()
|
|
||||||
, cursor()
|
|
||||||
, initial(initial)
|
|
||||||
, file(file)
|
|
||||||
, creator(creator)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
virtual ~BlobIOStream();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
aiExportDataBlob* GetBlob()
|
|
||||||
{
|
|
||||||
aiExportDataBlob* blob = new aiExportDataBlob();
|
|
||||||
blob->size = file_size;
|
|
||||||
blob->data = buffer;
|
|
||||||
|
|
||||||
buffer = NULL;
|
|
||||||
|
|
||||||
return blob;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
virtual size_t Read( void *,
|
|
||||||
size_t,
|
|
||||||
size_t )
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
virtual size_t Write(const void* pvBuffer,
|
|
||||||
size_t pSize,
|
|
||||||
size_t pCount)
|
|
||||||
{
|
|
||||||
pSize *= pCount;
|
|
||||||
if (cursor + pSize > cur_size) {
|
|
||||||
Grow(cursor + pSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(buffer+cursor, pvBuffer, pSize);
|
|
||||||
cursor += pSize;
|
|
||||||
|
|
||||||
file_size = std::max(file_size,cursor);
|
|
||||||
return pCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
virtual aiReturn Seek(size_t pOffset,
|
|
||||||
aiOrigin pOrigin)
|
|
||||||
{
|
|
||||||
switch(pOrigin)
|
|
||||||
{
|
|
||||||
case aiOrigin_CUR:
|
|
||||||
cursor += pOffset;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case aiOrigin_END:
|
|
||||||
cursor = file_size - pOffset;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case aiOrigin_SET:
|
|
||||||
cursor = pOffset;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return AI_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cursor > file_size) {
|
|
||||||
Grow(cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
file_size = std::max(cursor,file_size);
|
|
||||||
return AI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
virtual size_t Tell() const
|
|
||||||
{
|
|
||||||
return cursor;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
virtual size_t FileSize() const
|
|
||||||
{
|
|
||||||
return file_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
virtual void Flush()
|
|
||||||
{
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
void Grow(size_t need = 0)
|
|
||||||
{
|
|
||||||
// 1.5 and phi are very heap-friendly growth factors (the first
|
|
||||||
// allows for frequent re-use of heap blocks, the second
|
|
||||||
// forms a fibonacci sequence with similar characteristics -
|
|
||||||
// since this heavily depends on the heap implementation
|
|
||||||
// and other factors as well, i'll just go with 1.5 since
|
|
||||||
// it is quicker to compute).
|
|
||||||
size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) ));
|
|
||||||
|
|
||||||
const uint8_t* const old = buffer;
|
|
||||||
buffer = new uint8_t[new_size];
|
|
||||||
|
|
||||||
if (old) {
|
|
||||||
memcpy(buffer,old,cur_size);
|
|
||||||
delete[] old;
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_size = new_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
uint8_t* buffer;
|
|
||||||
size_t cur_size,file_size, cursor, initial;
|
|
||||||
|
|
||||||
const std::string file;
|
|
||||||
BlobIOSystem* const creator;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#define AI_BLOBIO_MAGIC "$blobfile"
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
|
||||||
/** Redirect IOSystem to a blob */
|
|
||||||
// --------------------------------------------------------------------------------------------
|
|
||||||
class BlobIOSystem : public IOSystem
|
|
||||||
{
|
|
||||||
|
|
||||||
friend class BlobIOStream;
|
|
||||||
typedef std::pair<std::string, aiExportDataBlob*> BlobEntry;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
BlobIOSystem()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~BlobIOSystem()
|
|
||||||
{
|
|
||||||
for(BlobEntry& blobby : blobs) {
|
|
||||||
delete blobby.second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
const char* GetMagicFileName() const
|
|
||||||
{
|
|
||||||
return AI_BLOBIO_MAGIC;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
aiExportDataBlob* GetBlobChain()
|
|
||||||
{
|
|
||||||
// one must be the master
|
|
||||||
aiExportDataBlob* master = NULL, *cur;
|
|
||||||
for(const BlobEntry& blobby : blobs) {
|
|
||||||
if (blobby.first == AI_BLOBIO_MAGIC) {
|
|
||||||
master = blobby.second;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!master) {
|
|
||||||
DefaultLogger::get()->error("BlobIOSystem: no data written or master file was not closed properly.");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
master->name.Set("");
|
|
||||||
|
|
||||||
cur = master;
|
|
||||||
for(const BlobEntry& blobby : blobs) {
|
|
||||||
if (blobby.second == master) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
cur->next = blobby.second;
|
|
||||||
cur = cur->next;
|
|
||||||
|
|
||||||
// extract the file extension from the file written
|
|
||||||
const std::string::size_type s = blobby.first.find_first_of('.');
|
|
||||||
cur->name.Set(s == std::string::npos ? blobby.first : blobby.first.substr(s+1));
|
|
||||||
}
|
|
||||||
|
|
||||||
// give up blob ownership
|
|
||||||
blobs.clear();
|
|
||||||
return master;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
virtual bool Exists( const char* pFile) const {
|
|
||||||
return created.find(std::string(pFile)) != created.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
virtual char getOsSeparator() const {
|
|
||||||
return '/';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
virtual IOStream* Open(const char* pFile,
|
|
||||||
const char* pMode)
|
|
||||||
{
|
|
||||||
if (pMode[0] != 'w') {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
created.insert(std::string(pFile));
|
|
||||||
return new BlobIOStream(this,std::string(pFile));
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
virtual void Close( IOStream* pFile)
|
|
||||||
{
|
|
||||||
delete pFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
void OnDestruct(const std::string& filename, BlobIOStream* child)
|
|
||||||
{
|
|
||||||
// we don't know in which the files are closed, so we
|
|
||||||
// can't reliably say that the first must be the master
|
|
||||||
// file ...
|
|
||||||
blobs.push_back( BlobEntry(filename,child->GetBlob()) );
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::set<std::string> created;
|
|
||||||
std::vector< BlobEntry > blobs;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
|
||||||
BlobIOStream :: ~BlobIOStream()
|
|
||||||
{
|
|
||||||
creator->OnDestruct(file,this);
|
|
||||||
delete[] buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // end Assimp
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,287 +0,0 @@
|
||||||
/*
|
|
||||||
Open Asset Import Library (assimp)
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2006-2017, 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 Helper class tp perform various byte oder swappings
|
|
||||||
(e.g. little to big endian) */
|
|
||||||
#ifndef AI_BYTESWAPPER_H_INC
|
|
||||||
#define AI_BYTESWAPPER_H_INC
|
|
||||||
|
|
||||||
#include <assimp/ai_assert.h>
|
|
||||||
#include <assimp/types.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
#include <stdlib.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Assimp {
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
/** Defines some useful byte order swap routines.
|
|
||||||
*
|
|
||||||
* This is required to read big-endian model formats on little-endian machines,
|
|
||||||
* and vice versa. Direct use of this class is DEPRECATED. Use #StreamReader instead. */
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
class ByteSwap
|
|
||||||
{
|
|
||||||
ByteSwap() {}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
/** Swap two bytes of data
|
|
||||||
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
|
||||||
static inline void Swap2(void* _szOut)
|
|
||||||
{
|
|
||||||
ai_assert(_szOut);
|
|
||||||
|
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
uint16_t* const szOut = reinterpret_cast<uint16_t*>(_szOut);
|
|
||||||
*szOut = _byteswap_ushort(*szOut);
|
|
||||||
#else
|
|
||||||
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
|
|
||||||
std::swap(szOut[0],szOut[1]);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
/** Swap four bytes of data
|
|
||||||
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
|
||||||
static inline void Swap4(void* _szOut)
|
|
||||||
{
|
|
||||||
ai_assert(_szOut);
|
|
||||||
|
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
uint32_t* const szOut = reinterpret_cast<uint32_t*>(_szOut);
|
|
||||||
*szOut = _byteswap_ulong(*szOut);
|
|
||||||
#else
|
|
||||||
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
|
|
||||||
std::swap(szOut[0],szOut[3]);
|
|
||||||
std::swap(szOut[1],szOut[2]);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
/** Swap eight bytes of data
|
|
||||||
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
|
||||||
static inline void Swap8(void* _szOut)
|
|
||||||
{
|
|
||||||
ai_assert(_szOut);
|
|
||||||
|
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
uint64_t* const szOut = reinterpret_cast<uint64_t*>(_szOut);
|
|
||||||
*szOut = _byteswap_uint64(*szOut);
|
|
||||||
#else
|
|
||||||
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
|
|
||||||
std::swap(szOut[0],szOut[7]);
|
|
||||||
std::swap(szOut[1],szOut[6]);
|
|
||||||
std::swap(szOut[2],szOut[5]);
|
|
||||||
std::swap(szOut[3],szOut[4]);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
/** ByteSwap a float. Not a joke.
|
|
||||||
* @param[inout] fOut ehm. .. */
|
|
||||||
static inline void Swap(float* fOut) {
|
|
||||||
Swap4(fOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
/** ByteSwap a double. Not a joke.
|
|
||||||
* @param[inout] fOut ehm. .. */
|
|
||||||
static inline void Swap(double* fOut) {
|
|
||||||
Swap8(fOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
/** ByteSwap an int16t. Not a joke.
|
|
||||||
* @param[inout] fOut ehm. .. */
|
|
||||||
static inline void Swap(int16_t* fOut) {
|
|
||||||
Swap2(fOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void Swap(uint16_t* fOut) {
|
|
||||||
Swap2(fOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
/** ByteSwap an int32t. Not a joke.
|
|
||||||
* @param[inout] fOut ehm. .. */
|
|
||||||
static inline void Swap(int32_t* fOut){
|
|
||||||
Swap4(fOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void Swap(uint32_t* fOut){
|
|
||||||
Swap4(fOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
/** ByteSwap an int64t. Not a joke.
|
|
||||||
* @param[inout] fOut ehm. .. */
|
|
||||||
static inline void Swap(int64_t* fOut) {
|
|
||||||
Swap8(fOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void Swap(uint64_t* fOut) {
|
|
||||||
Swap8(fOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
//! Templatized ByteSwap
|
|
||||||
//! \returns param tOut as swapped
|
|
||||||
template<typename Type>
|
|
||||||
static inline Type Swapped(Type tOut)
|
|
||||||
{
|
|
||||||
return _swapper<Type,sizeof(Type)>()(tOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
template <typename T, size_t size> struct _swapper;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T> struct ByteSwap::_swapper<T,2> {
|
|
||||||
T operator() (T tOut) {
|
|
||||||
Swap2(&tOut);
|
|
||||||
return tOut;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T> struct ByteSwap::_swapper<T,4> {
|
|
||||||
T operator() (T tOut) {
|
|
||||||
Swap4(&tOut);
|
|
||||||
return tOut;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T> struct ByteSwap::_swapper<T,8> {
|
|
||||||
T operator() (T tOut) {
|
|
||||||
Swap8(&tOut);
|
|
||||||
return tOut;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
// ByteSwap macros for BigEndian/LittleEndian support
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
#if (defined AI_BUILD_BIG_ENDIAN)
|
|
||||||
# define AI_LE(t) (t)
|
|
||||||
# define AI_BE(t) ByteSwap::Swapped(t)
|
|
||||||
# define AI_LSWAP2(p)
|
|
||||||
# define AI_LSWAP4(p)
|
|
||||||
# define AI_LSWAP8(p)
|
|
||||||
# define AI_LSWAP2P(p)
|
|
||||||
# define AI_LSWAP4P(p)
|
|
||||||
# define AI_LSWAP8P(p)
|
|
||||||
# define LE_NCONST const
|
|
||||||
# define AI_SWAP2(p) ByteSwap::Swap2(&(p))
|
|
||||||
# define AI_SWAP4(p) ByteSwap::Swap4(&(p))
|
|
||||||
# define AI_SWAP8(p) ByteSwap::Swap8(&(p))
|
|
||||||
# define AI_SWAP2P(p) ByteSwap::Swap2((p))
|
|
||||||
# define AI_SWAP4P(p) ByteSwap::Swap4((p))
|
|
||||||
# define AI_SWAP8P(p) ByteSwap::Swap8((p))
|
|
||||||
# define BE_NCONST
|
|
||||||
#else
|
|
||||||
# define AI_BE(t) (t)
|
|
||||||
# define AI_LE(t) ByteSwap::Swapped(t)
|
|
||||||
# define AI_SWAP2(p)
|
|
||||||
# define AI_SWAP4(p)
|
|
||||||
# define AI_SWAP8(p)
|
|
||||||
# define AI_SWAP2P(p)
|
|
||||||
# define AI_SWAP4P(p)
|
|
||||||
# define AI_SWAP8P(p)
|
|
||||||
# define BE_NCONST const
|
|
||||||
# define AI_LSWAP2(p) ByteSwap::Swap2(&(p))
|
|
||||||
# define AI_LSWAP4(p) ByteSwap::Swap4(&(p))
|
|
||||||
# define AI_LSWAP8(p) ByteSwap::Swap8(&(p))
|
|
||||||
# define AI_LSWAP2P(p) ByteSwap::Swap2((p))
|
|
||||||
# define AI_LSWAP4P(p) ByteSwap::Swap4((p))
|
|
||||||
# define AI_LSWAP8P(p) ByteSwap::Swap8((p))
|
|
||||||
# define LE_NCONST
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
namespace Intern {
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
|
||||||
template <typename T, bool doit>
|
|
||||||
struct ByteSwapper {
|
|
||||||
void operator() (T* inout) {
|
|
||||||
ByteSwap::Swap(inout);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct ByteSwapper<T,false> {
|
|
||||||
void operator() (T*) {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
|
||||||
template <bool SwapEndianess, typename T, bool RuntimeSwitch>
|
|
||||||
struct Getter {
|
|
||||||
void operator() (T* inout, bool le) {
|
|
||||||
#ifdef AI_BUILD_BIG_ENDIAN
|
|
||||||
le = le;
|
|
||||||
#else
|
|
||||||
le = !le;
|
|
||||||
#endif
|
|
||||||
if (le) {
|
|
||||||
ByteSwapper<T,(sizeof(T)>1?true:false)> () (inout);
|
|
||||||
}
|
|
||||||
else ByteSwapper<T,false> () (inout);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <bool SwapEndianess, typename T>
|
|
||||||
struct Getter<SwapEndianess,T,false> {
|
|
||||||
|
|
||||||
void operator() (T* inout, bool /*le*/) {
|
|
||||||
// static branch
|
|
||||||
ByteSwapper<T,(SwapEndianess && sizeof(T)>1)> () (inout);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // end Intern
|
|
||||||
} // end Assimp
|
|
||||||
|
|
||||||
#endif //!! AI_BYTESWAPPER_H_INC
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2019, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
|
@ -68,8 +68,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
using namespace melange;
|
using namespace melange;
|
||||||
|
|
||||||
// overload this function and fill in your own unique data
|
// overload this function and fill in your own unique data
|
||||||
void GetWriterInfo(int &id, String &appname)
|
void GetWriterInfo(int &id, String &appname) {
|
||||||
{
|
|
||||||
id = 2424226;
|
id = 2424226;
|
||||||
appname = "Open Asset Import Library";
|
appname = "Open Asset Import Library";
|
||||||
}
|
}
|
||||||
|
|
@ -78,7 +77,10 @@ using namespace Assimp;
|
||||||
using namespace Assimp::Formatter;
|
using namespace Assimp::Formatter;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
template<> const std::string LogFunctions<C4DImporter>::log_prefix = "C4D: ";
|
template<> const char* LogFunctions<C4DImporter>::Prefix() {
|
||||||
|
static auto prefix = "C4D: ";
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static const aiImporterDesc desc = {
|
||||||
|
|
@ -97,47 +99,44 @@ static const aiImporterDesc desc = {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
C4DImporter::C4DImporter()
|
C4DImporter::C4DImporter()
|
||||||
{}
|
: BaseImporter() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
C4DImporter::~C4DImporter()
|
C4DImporter::~C4DImporter() {
|
||||||
{}
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool C4DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
|
bool C4DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const {
|
||||||
{
|
|
||||||
const std::string& extension = GetExtension(pFile);
|
const std::string& extension = GetExtension(pFile);
|
||||||
if (extension == "c4d") {
|
if (extension == "c4d") {
|
||||||
return true;
|
return true;
|
||||||
}
|
} else if ((!extension.length() || checkSig) && pIOHandler) {
|
||||||
|
|
||||||
else if ((!extension.length() || checkSig) && pIOHandler) {
|
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const aiImporterDesc* C4DImporter::GetInfo () const
|
const aiImporterDesc* C4DImporter::GetInfo () const {
|
||||||
{
|
|
||||||
return &desc;
|
return &desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void C4DImporter::SetupProperties(const Importer* /*pImp*/)
|
void C4DImporter::SetupProperties(const Importer* /*pImp*/) {
|
||||||
{
|
|
||||||
// nothing to be done for the moment
|
// nothing to be done for the moment
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void C4DImporter::InternReadFile( const std::string& pFile,
|
void C4DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) {
|
||||||
aiScene* pScene, IOSystem* pIOHandler)
|
|
||||||
{
|
|
||||||
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
|
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
|
||||||
|
|
||||||
if( file.get() == NULL) {
|
if( file.get() == nullptr ) {
|
||||||
ThrowException("failed to open file " + pFile);
|
ThrowException("failed to open file " + pFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -151,7 +150,7 @@ void C4DImporter::InternReadFile( const std::string& pFile,
|
||||||
|
|
||||||
// open document first
|
// open document first
|
||||||
BaseDocument* doc = LoadDocument(f, SCENEFILTER_OBJECTS | SCENEFILTER_MATERIALS);
|
BaseDocument* doc = LoadDocument(f, SCENEFILTER_OBJECTS | SCENEFILTER_MATERIALS);
|
||||||
if(doc == NULL) {
|
if(doc == nullptr ) {
|
||||||
ThrowException("failed to read document " + pFile);
|
ThrowException("failed to read document " + pFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -160,11 +159,10 @@ void C4DImporter::InternReadFile( const std::string& pFile,
|
||||||
// first convert all materials
|
// first convert all materials
|
||||||
ReadMaterials(doc->GetFirstMaterial());
|
ReadMaterials(doc->GetFirstMaterial());
|
||||||
|
|
||||||
// process C4D scenegraph recursively
|
// process C4D scene-graph recursively
|
||||||
try {
|
try {
|
||||||
RecurseHierarchy(doc->GetFirstObject(), pScene->mRootNode);
|
RecurseHierarchy(doc->GetFirstObject(), pScene->mRootNode);
|
||||||
}
|
} catch(...) {
|
||||||
catch(...) {
|
|
||||||
for(aiMesh* mesh : meshes) {
|
for(aiMesh* mesh : meshes) {
|
||||||
delete mesh;
|
delete mesh;
|
||||||
}
|
}
|
||||||
|
|
@ -201,8 +199,7 @@ void C4DImporter::InternReadFile( const std::string& pFile,
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader)
|
bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader) {
|
||||||
{
|
|
||||||
// based on Melange sample code (C4DImportExport.cpp)
|
// based on Melange sample code (C4DImportExport.cpp)
|
||||||
while(shader) {
|
while(shader) {
|
||||||
if(shader->GetType() == Xlayer) {
|
if(shader->GetType() == Xlayer) {
|
||||||
|
|
@ -220,15 +217,12 @@ bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader)
|
||||||
// Ignore the actual layer blending - models for real-time rendering should not
|
// Ignore the actual layer blending - models for real-time rendering should not
|
||||||
// use them in a non-trivial way. Just try to find textures that we can apply
|
// use them in a non-trivial way. Just try to find textures that we can apply
|
||||||
// to the model.
|
// to the model.
|
||||||
while (lsl)
|
while (lsl) {
|
||||||
{
|
if (lsl->GetType() == TypeFolder) {
|
||||||
if (lsl->GetType() == TypeFolder)
|
|
||||||
{
|
|
||||||
BlendFolder* const folder = dynamic_cast<BlendFolder*>(lsl);
|
BlendFolder* const folder = dynamic_cast<BlendFolder*>(lsl);
|
||||||
LayerShaderLayer *subLsl = dynamic_cast<LayerShaderLayer*>(folder->m_Children.GetObject(0));
|
LayerShaderLayer *subLsl = dynamic_cast<LayerShaderLayer*>(folder->m_Children.GetObject(0));
|
||||||
|
|
||||||
while (subLsl)
|
while (subLsl) {
|
||||||
{
|
|
||||||
if (subLsl->GetType() == TypeShader) {
|
if (subLsl->GetType() == TypeShader) {
|
||||||
BlendShader* const shader = dynamic_cast<BlendShader*>(subLsl);
|
BlendShader* const shader = dynamic_cast<BlendShader*>(subLsl);
|
||||||
if(ReadShader(out, static_cast<BaseShader*>(shader->m_pLink->GetLink()))) {
|
if(ReadShader(out, static_cast<BaseShader*>(shader->m_pLink->GetLink()))) {
|
||||||
|
|
@ -238,8 +232,7 @@ bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader)
|
||||||
|
|
||||||
subLsl = subLsl->GetNext();
|
subLsl = subLsl->GetNext();
|
||||||
}
|
}
|
||||||
}
|
} else if (lsl->GetType() == TypeShader) {
|
||||||
else if (lsl->GetType() == TypeShader) {
|
|
||||||
BlendShader* const shader = dynamic_cast<BlendShader*>(lsl);
|
BlendShader* const shader = dynamic_cast<BlendShader*>(lsl);
|
||||||
if(ReadShader(out, static_cast<BaseShader*>(shader->m_pLink->GetLink()))) {
|
if(ReadShader(out, static_cast<BaseShader*>(shader->m_pLink->GetLink()))) {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -248,33 +241,27 @@ bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader)
|
||||||
|
|
||||||
lsl = lsl->GetNext();
|
lsl = lsl->GetNext();
|
||||||
}
|
}
|
||||||
}
|
} else if ( shader->GetType() == Xbitmap ) {
|
||||||
else if ( shader->GetType() == Xbitmap )
|
|
||||||
{
|
|
||||||
aiString path;
|
aiString path;
|
||||||
shader->GetFileName().GetString().GetCString(path.data, MAXLEN-1);
|
shader->GetFileName().GetString().GetCString(path.data, MAXLEN-1);
|
||||||
path.length = ::strlen(path.data);
|
path.length = ::strlen(path.data);
|
||||||
out->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0));
|
out->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0));
|
||||||
return true;
|
return true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
LogWarn("ignoring shader type: " + std::string(GetObjectTypeName(shader->GetType())));
|
LogWarn("ignoring shader type: " + std::string(GetObjectTypeName(shader->GetType())));
|
||||||
}
|
}
|
||||||
shader = shader->GetNext();
|
shader = shader->GetNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void C4DImporter::ReadMaterials(melange::BaseMaterial* mat)
|
void C4DImporter::ReadMaterials(melange::BaseMaterial* mat) {
|
||||||
{
|
|
||||||
// based on Melange sample code
|
// based on Melange sample code
|
||||||
while (mat)
|
while (mat) {
|
||||||
{
|
|
||||||
const String& name = mat->GetName();
|
const String& name = mat->GetName();
|
||||||
if (mat->GetType() == Mmaterial)
|
if (mat->GetType() == Mmaterial) {
|
||||||
{
|
|
||||||
aiMaterial* out = new aiMaterial();
|
aiMaterial* out = new aiMaterial();
|
||||||
material_mapping[mat] = static_cast<unsigned int>(materials.size());
|
material_mapping[mat] = static_cast<unsigned int>(materials.size());
|
||||||
materials.push_back(out);
|
materials.push_back(out);
|
||||||
|
|
@ -286,8 +273,7 @@ void C4DImporter::ReadMaterials(melange::BaseMaterial* mat)
|
||||||
|
|
||||||
Material& m = dynamic_cast<Material&>(*mat);
|
Material& m = dynamic_cast<Material&>(*mat);
|
||||||
|
|
||||||
if (m.GetChannelState(CHANNEL_COLOR))
|
if (m.GetChannelState(CHANNEL_COLOR)) {
|
||||||
{
|
|
||||||
GeData data;
|
GeData data;
|
||||||
mat->GetParameter(MATERIAL_COLOR_COLOR, data);
|
mat->GetParameter(MATERIAL_COLOR_COLOR, data);
|
||||||
Vector color = data.GetVector();
|
Vector color = data.GetVector();
|
||||||
|
|
@ -307,9 +293,7 @@ void C4DImporter::ReadMaterials(melange::BaseMaterial* mat)
|
||||||
if(shader) {
|
if(shader) {
|
||||||
ReadShader(out, shader);
|
ReadShader(out, shader);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
LogWarn("ignoring plugin material: " + std::string(GetObjectTypeName(mat->GetType())));
|
LogWarn("ignoring plugin material: " + std::string(GetObjectTypeName(mat->GetType())));
|
||||||
}
|
}
|
||||||
mat = mat->GetNext();
|
mat = mat->GetNext();
|
||||||
|
|
@ -317,14 +301,12 @@ void C4DImporter::ReadMaterials(melange::BaseMaterial* mat)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent)
|
void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent) {
|
||||||
{
|
ai_assert(parent != nullptr );
|
||||||
ai_assert(parent != NULL);
|
|
||||||
std::vector<aiNode*> nodes;
|
std::vector<aiNode*> nodes;
|
||||||
|
|
||||||
// based on Melange sample code
|
// based on Melange sample code
|
||||||
while (object)
|
while (object) {
|
||||||
{
|
|
||||||
const String& name = object->GetName();
|
const String& name = object->GetName();
|
||||||
const LONG type = object->GetType();
|
const LONG type = object->GetType();
|
||||||
const Matrix& ml = object->GetMl();
|
const Matrix& ml = object->GetMl();
|
||||||
|
|
@ -356,26 +338,20 @@ void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent)
|
||||||
nodes.push_back(nd);
|
nodes.push_back(nd);
|
||||||
|
|
||||||
GeData data;
|
GeData data;
|
||||||
if (type == Ocamera)
|
if (type == Ocamera) {
|
||||||
{
|
|
||||||
object->GetParameter(CAMERAOBJECT_FOV, data);
|
object->GetParameter(CAMERAOBJECT_FOV, data);
|
||||||
// TODO: read camera
|
// TODO: read camera
|
||||||
}
|
} else if (type == Olight) {
|
||||||
else if (type == Olight)
|
|
||||||
{
|
|
||||||
// TODO: read light
|
// TODO: read light
|
||||||
}
|
} else if (type == Opolygon) {
|
||||||
else if (type == Opolygon)
|
|
||||||
{
|
|
||||||
aiMesh* const mesh = ReadMesh(object);
|
aiMesh* const mesh = ReadMesh(object);
|
||||||
if(mesh != NULL) {
|
if(mesh != nullptr) {
|
||||||
nd->mNumMeshes = 1;
|
nd->mNumMeshes = 1;
|
||||||
nd->mMeshes = new unsigned int[1];
|
nd->mMeshes = new unsigned int[1];
|
||||||
nd->mMeshes[0] = static_cast<unsigned int>(meshes.size());
|
nd->mMeshes[0] = static_cast<unsigned int>(meshes.size());
|
||||||
meshes.push_back(mesh);
|
meshes.push_back(mesh);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
LogWarn("ignoring object: " + std::string(GetObjectTypeName(type)));
|
LogWarn("ignoring object: " + std::string(GetObjectTypeName(type)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -389,28 +365,27 @@ void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent)
|
||||||
std::copy(nodes.begin(), nodes.end(), parent->mChildren);
|
std::copy(nodes.begin(), nodes.end(), parent->mChildren);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiMesh* C4DImporter::ReadMesh(BaseObject* object)
|
aiMesh* C4DImporter::ReadMesh(BaseObject* object) {
|
||||||
{
|
ai_assert(object != nullptr);
|
||||||
ai_assert(object != NULL && object->GetType() == Opolygon);
|
ai_assert( object->GetType() == Opolygon );
|
||||||
|
|
||||||
// based on Melange sample code
|
// based on Melange sample code
|
||||||
PolygonObject* const polyObject = dynamic_cast<PolygonObject*>(object);
|
PolygonObject* const polyObject = dynamic_cast<PolygonObject*>(object);
|
||||||
ai_assert(polyObject != NULL);
|
ai_assert(polyObject != nullptr);
|
||||||
|
|
||||||
const LONG pointCount = polyObject->GetPointCount();
|
const LONG pointCount = polyObject->GetPointCount();
|
||||||
const LONG polyCount = polyObject->GetPolygonCount();
|
const LONG polyCount = polyObject->GetPolygonCount();
|
||||||
if(!polyObject || !pointCount) {
|
if(!polyObject || !pointCount) {
|
||||||
LogWarn("ignoring mesh with zero vertices or faces");
|
LogWarn("ignoring mesh with zero vertices or faces");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Vector* points = polyObject->GetPointR();
|
const Vector* points = polyObject->GetPointR();
|
||||||
ai_assert(points != NULL);
|
ai_assert(points != nullptr);
|
||||||
|
|
||||||
const CPolygon* polys = polyObject->GetPolygonR();
|
const CPolygon* polys = polyObject->GetPolygonR();
|
||||||
ai_assert(polys != NULL);
|
ai_assert(polys != nullptr);
|
||||||
|
|
||||||
std::unique_ptr<aiMesh> mesh(new aiMesh());
|
std::unique_ptr<aiMesh> mesh(new aiMesh());
|
||||||
mesh->mNumFaces = static_cast<unsigned int>(polyCount);
|
mesh->mNumFaces = static_cast<unsigned int>(polyCount);
|
||||||
|
|
@ -443,14 +418,14 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object)
|
||||||
|
|
||||||
// check if there are normals, tangents or UVW coordinates
|
// check if there are normals, tangents or UVW coordinates
|
||||||
BaseTag* tag = object->GetTag(Tnormal);
|
BaseTag* tag = object->GetTag(Tnormal);
|
||||||
NormalTag* normals_src = NULL;
|
NormalTag* normals_src = nullptr;
|
||||||
if(tag) {
|
if(tag) {
|
||||||
normals_src = dynamic_cast<NormalTag*>(tag);
|
normals_src = dynamic_cast<NormalTag*>(tag);
|
||||||
normals = mesh->mNormals = new aiVector3D[mesh->mNumVertices]();
|
normals = mesh->mNormals = new aiVector3D[mesh->mNumVertices]();
|
||||||
}
|
}
|
||||||
|
|
||||||
tag = object->GetTag(Ttangent);
|
tag = object->GetTag(Ttangent);
|
||||||
TangentTag* tangents_src = NULL;
|
TangentTag* tangents_src = nullptr;
|
||||||
if(tag) {
|
if(tag) {
|
||||||
tangents_src = dynamic_cast<TangentTag*>(tag);
|
tangents_src = dynamic_cast<TangentTag*>(tag);
|
||||||
tangents = mesh->mTangents = new aiVector3D[mesh->mNumVertices]();
|
tangents = mesh->mTangents = new aiVector3D[mesh->mNumVertices]();
|
||||||
|
|
@ -458,15 +433,14 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object)
|
||||||
}
|
}
|
||||||
|
|
||||||
tag = object->GetTag(Tuvw);
|
tag = object->GetTag(Tuvw);
|
||||||
UVWTag* uvs_src = NULL;
|
UVWTag* uvs_src = nullptr;
|
||||||
if(tag) {
|
if(tag) {
|
||||||
uvs_src = dynamic_cast<UVWTag*>(tag);
|
uvs_src = dynamic_cast<UVWTag*>(tag);
|
||||||
uvs = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices]();
|
uvs = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices]();
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy vertices and extra channels over and populate faces
|
// copy vertices and extra channels over and populate faces
|
||||||
for (LONG i = 0; i < polyCount; ++i, ++face)
|
for (LONG i = 0; i < polyCount; ++i, ++face) {
|
||||||
{
|
|
||||||
ai_assert(polys[i].a < pointCount && polys[i].a >= 0);
|
ai_assert(polys[i].a < pointCount && polys[i].a >= 0);
|
||||||
const Vector& pointA = points[polys[i].a];
|
const Vector& pointA = points[polys[i].a];
|
||||||
verts->x = pointA.x;
|
verts->x = pointA.x;
|
||||||
|
|
@ -489,8 +463,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object)
|
||||||
++verts;
|
++verts;
|
||||||
|
|
||||||
// TODO: do we also need to handle lines or points with similar checks?
|
// TODO: do we also need to handle lines or points with similar checks?
|
||||||
if (polys[i].c != polys[i].d)
|
if (polys[i].c != polys[i].d) {
|
||||||
{
|
|
||||||
ai_assert(polys[i].d < pointCount && polys[i].d >= 0);
|
ai_assert(polys[i].d < pointCount && polys[i].d >= 0);
|
||||||
|
|
||||||
face->mNumIndices = 4;
|
face->mNumIndices = 4;
|
||||||
|
|
@ -500,8 +473,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object)
|
||||||
verts->y = pointD.y;
|
verts->y = pointD.y;
|
||||||
verts->z = pointD.z;
|
verts->z = pointD.z;
|
||||||
++verts;
|
++verts;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
face->mNumIndices = 3;
|
face->mNumIndices = 3;
|
||||||
}
|
}
|
||||||
face->mIndices = new unsigned int[face->mNumIndices];
|
face->mIndices = new unsigned int[face->mNumIndices];
|
||||||
|
|
@ -513,8 +485,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object)
|
||||||
if (normals_src) {
|
if (normals_src) {
|
||||||
if(i >= normals_src->GetDataCount()) {
|
if(i >= normals_src->GetDataCount()) {
|
||||||
LogError("unexpected number of normals, ignoring");
|
LogError("unexpected number of normals, ignoring");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
ConstNormalHandle normal_handle = normals_src->GetDataAddressR();
|
ConstNormalHandle normal_handle = normals_src->GetDataAddressR();
|
||||||
NormalStruct nor;
|
NormalStruct nor;
|
||||||
NormalTag::Get(normal_handle, i, nor);
|
NormalTag::Get(normal_handle, i, nor);
|
||||||
|
|
@ -616,26 +587,25 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object)
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh->mMaterialIndex = ResolveMaterial(polyObject);
|
mesh->mMaterialIndex = ResolveMaterial(polyObject);
|
||||||
|
|
||||||
return mesh.release();
|
return mesh.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
unsigned int C4DImporter::ResolveMaterial(PolygonObject* obj)
|
unsigned int C4DImporter::ResolveMaterial(PolygonObject* obj) {
|
||||||
{
|
ai_assert(obj != nullptr);
|
||||||
ai_assert(obj != NULL);
|
|
||||||
|
|
||||||
const unsigned int mat_count = static_cast<unsigned int>(materials.size());
|
const unsigned int mat_count = static_cast<unsigned int>(materials.size());
|
||||||
|
|
||||||
BaseTag* tag = obj->GetTag(Ttexture);
|
BaseTag* tag = obj->GetTag(Ttexture);
|
||||||
if(tag == NULL) {
|
if(tag == nullptr) {
|
||||||
return mat_count;
|
return mat_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureTag& ttag = dynamic_cast<TextureTag&>(*tag);
|
TextureTag& ttag = dynamic_cast<TextureTag&>(*tag);
|
||||||
|
|
||||||
BaseMaterial* const mat = ttag.GetMaterial();
|
BaseMaterial* const mat = ttag.GetMaterial();
|
||||||
ai_assert(mat != NULL);
|
ai_assert(mat != nullptr);
|
||||||
|
|
||||||
const MaterialMap::const_iterator it = material_mapping.find(mat);
|
const MaterialMap::const_iterator it = material_mapping.find(mat);
|
||||||
if(it == material_mapping.end()) {
|
if(it == material_mapping.end()) {
|
||||||
|
|
@ -643,6 +613,7 @@ unsigned int C4DImporter::ResolveMaterial(PolygonObject* obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
ai_assert((*it).second < mat_count);
|
ai_assert((*it).second < mat_count);
|
||||||
|
|
||||||
return (*it).second;
|
return (*it).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2019, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
|
@ -48,6 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/LogAux.h>
|
#include <assimp/LogAux.h>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
// Forward declarations
|
||||||
struct aiNode;
|
struct aiNode;
|
||||||
struct aiMesh;
|
struct aiMesh;
|
||||||
struct aiMaterial;
|
struct aiMaterial;
|
||||||
|
|
@ -61,8 +63,7 @@ namespace melange {
|
||||||
class BaseShader;
|
class BaseShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
// TinyFormatter.h
|
// TinyFormatter.h
|
||||||
namespace Formatter {
|
namespace Formatter {
|
||||||
template <typename T,typename TR, typename A> class basic_formatter;
|
template <typename T,typename TR, typename A> class basic_formatter;
|
||||||
|
|
@ -75,17 +76,10 @@ namespace Assimp {
|
||||||
*
|
*
|
||||||
* Note that Melange is not free software. */
|
* Note that Melange is not free software. */
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
class C4DImporter : public BaseImporter, public LogFunctions<C4DImporter>
|
class C4DImporter : public BaseImporter, public LogFunctions<C4DImporter> {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
C4DImporter();
|
C4DImporter();
|
||||||
~C4DImporter();
|
~C4DImporter();
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// --------------------
|
|
||||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
||||||
bool checkSig) const;
|
bool checkSig) const;
|
||||||
|
|
||||||
|
|
@ -119,5 +113,5 @@ private:
|
||||||
}; // !class C4DImporter
|
}; // !class C4DImporter
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
#endif // INCLUDED_AI_CINEMA_4D_LOADER_H
|
|
||||||
|
|
||||||
|
#endif // INCLUDED_AI_CINEMA_4D_LOADER_H
|
||||||
|
|
@ -49,7 +49,7 @@ Assimp C export interface. See Exporter.cpp for some notes.
|
||||||
|
|
||||||
#include "CInterfaceIOWrapper.h"
|
#include "CInterfaceIOWrapper.h"
|
||||||
#include <assimp/SceneCombiner.h>
|
#include <assimp/SceneCombiner.h>
|
||||||
#include "ScenePrivate.h"
|
#include "Common/ScenePrivate.h"
|
||||||
#include <assimp/Exporter.hpp>
|
#include <assimp/Exporter.hpp>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -45,20 +45,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_COB_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_COB_IMPORTER
|
||||||
#include "COBLoader.h"
|
#include "COB/COBLoader.h"
|
||||||
#include "COBScene.h"
|
#include "COB/COBScene.h"
|
||||||
#include "ConvertToLHProcess.h"
|
#include "PostProcessing/ConvertToLHProcess.h"
|
||||||
|
|
||||||
#include <assimp/StreamReader.h>
|
#include <assimp/StreamReader.h>
|
||||||
#include <assimp/ParsingUtils.h>
|
#include <assimp/ParsingUtils.h>
|
||||||
#include <assimp/fast_atof.h>
|
#include <assimp/fast_atof.h>
|
||||||
#include <assimp/LineSplitter.h>
|
#include <assimp/LineSplitter.h>
|
||||||
#include <assimp/TinyFormatter.h>
|
#include <assimp/TinyFormatter.h>
|
||||||
#include <memory>
|
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/importerdesc.h>
|
#include <assimp/importerdesc.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
using namespace Assimp::COB;
|
using namespace Assimp::COB;
|
||||||
using namespace Assimp::Formatter;
|
using namespace Assimp::Formatter;
|
||||||
|
|
@ -144,7 +146,7 @@ void COBImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
|
||||||
// check header
|
// check header
|
||||||
char head[32];
|
char head[32];
|
||||||
stream->CopyAndAdvance(head,32);
|
stream->CopyAndAdvance(head,32);
|
||||||
if (strncmp(head,"Caligari ",9)) {
|
if (strncmp(head,"Caligari ",9) != 0) {
|
||||||
ThrowException("Could not found magic id: `Caligari`");
|
ThrowException("Could not found magic id: `Caligari`");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -656,14 +658,14 @@ void COBImporter::ReadLght_Ascii(Scene& out, LineSplitter& splitter, const Chunk
|
||||||
ReadFloat3Tuple_Ascii(msh.color ,&rgb);
|
ReadFloat3Tuple_Ascii(msh.color ,&rgb);
|
||||||
|
|
||||||
SkipSpaces(&rgb);
|
SkipSpaces(&rgb);
|
||||||
if (strncmp(rgb,"cone angle",10)) {
|
if (strncmp(rgb,"cone angle",10) != 0) {
|
||||||
ASSIMP_LOG_WARN_F( "Expected `cone angle` entity in `color` line in `Lght` chunk ", nfo.id );
|
ASSIMP_LOG_WARN_F( "Expected `cone angle` entity in `color` line in `Lght` chunk ", nfo.id );
|
||||||
}
|
}
|
||||||
SkipSpaces(rgb+10,&rgb);
|
SkipSpaces(rgb+10,&rgb);
|
||||||
msh.angle = fast_atof(&rgb);
|
msh.angle = fast_atof(&rgb);
|
||||||
|
|
||||||
SkipSpaces(&rgb);
|
SkipSpaces(&rgb);
|
||||||
if (strncmp(rgb,"inner angle",11)) {
|
if (strncmp(rgb,"inner angle",11) != 0) {
|
||||||
ASSIMP_LOG_WARN_F( "Expected `inner angle` entity in `color` line in `Lght` chunk ", nfo.id);
|
ASSIMP_LOG_WARN_F( "Expected `inner angle` entity in `color` line in `Lght` chunk ", nfo.id);
|
||||||
}
|
}
|
||||||
SkipSpaces(rgb+11,&rgb);
|
SkipSpaces(rgb+11,&rgb);
|
||||||
|
|
@ -896,6 +898,7 @@ public:
|
||||||
: nfo(nfo)
|
: nfo(nfo)
|
||||||
, reader(reader)
|
, reader(reader)
|
||||||
, cur(reader.GetCurrentPos()) {
|
, cur(reader.GetCurrentPos()) {
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
~chunk_guard() {
|
~chunk_guard() {
|
||||||
|
|
@ -903,7 +906,7 @@ public:
|
||||||
if(nfo.size != static_cast<unsigned int>(-1)) {
|
if(nfo.size != static_cast<unsigned int>(-1)) {
|
||||||
try {
|
try {
|
||||||
reader.IncPtr( static_cast< int >( nfo.size ) - reader.GetCurrentPos() + cur );
|
reader.IncPtr( static_cast< int >( nfo.size ) - reader.GetCurrentPos() + cur );
|
||||||
} catch ( DeadlyImportError e ) {
|
} catch (const DeadlyImportError& ) {
|
||||||
// out of limit so correct the value
|
// out of limit so correct the value
|
||||||
reader.IncPtr( reader.GetReadLimit() );
|
reader.IncPtr( reader.GetReadLimit() );
|
||||||
}
|
}
|
||||||
|
|
@ -911,15 +914,17 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const COB::ChunkInfo& nfo;
|
const COB::ChunkInfo& nfo;
|
||||||
StreamReaderLE& reader;
|
StreamReaderLE& reader;
|
||||||
long cur;
|
long cur;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void COBImporter::ReadBinaryFile(Scene& out, StreamReaderLE* reader)
|
void COBImporter::ReadBinaryFile(Scene& out, StreamReaderLE* reader) {
|
||||||
{
|
if (nullptr == reader) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
std::string type;
|
std::string type;
|
||||||
type += reader -> GetI1()
|
type += reader -> GetI1()
|
||||||
|
|
@ -1214,7 +1219,7 @@ void COBImporter::ReadGrou_Binary(COB::Scene& out, StreamReaderLE& reader, const
|
||||||
|
|
||||||
const chunk_guard cn(nfo,reader);
|
const chunk_guard cn(nfo,reader);
|
||||||
|
|
||||||
out.nodes.push_back(std::shared_ptr<Group>(new Group()));
|
out.nodes.push_back(std::make_shared<Group>());
|
||||||
Group& msh = (Group&)(*out.nodes.back().get());
|
Group& msh = (Group&)(*out.nodes.back().get());
|
||||||
msh = nfo;
|
msh = nfo;
|
||||||
|
|
||||||
|
|
@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "ColladaExporter.h"
|
#include "ColladaExporter.h"
|
||||||
#include <assimp/Bitmap.h>
|
#include <assimp/Bitmap.h>
|
||||||
|
#include <assimp/MathFunctions.h>
|
||||||
#include <assimp/fast_atof.h>
|
#include <assimp/fast_atof.h>
|
||||||
#include <assimp/SceneCombiner.h>
|
#include <assimp/SceneCombiner.h>
|
||||||
#include <assimp/StringUtils.h>
|
#include <assimp/StringUtils.h>
|
||||||
|
|
@ -64,13 +65,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp {
|
||||||
{
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp
|
// Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp
|
||||||
void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
|
void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/) {
|
||||||
{
|
|
||||||
std::string path = DefaultIOSystem::absolutePath(std::string(pFile));
|
std::string path = DefaultIOSystem::absolutePath(std::string(pFile));
|
||||||
std::string file = DefaultIOSystem::completeBaseName(std::string(pFile));
|
std::string file = DefaultIOSystem::completeBaseName(std::string(pFile));
|
||||||
|
|
||||||
|
|
@ -93,15 +92,45 @@ void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* p
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // 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) {
|
||||||
|
const char XML_ID_CHARS[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-.";
|
||||||
|
const unsigned int XML_ID_CHARS_COUNT = sizeof(XML_ID_CHARS) / sizeof(char);
|
||||||
|
|
||||||
|
if (name.length() == 0) {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream idEncoded;
|
||||||
|
|
||||||
|
// xsd:ID must start with letter or underscore
|
||||||
|
if (!((name[0] >= 'A' && name[0] <= 'z') || name[0] == '_')) {
|
||||||
|
idEncoded << '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::string::const_iterator it = name.begin(); it != name.end(); ++it) {
|
||||||
|
// xsd:ID can only contain letters, digits, underscores, hyphens and periods
|
||||||
|
if (strchr(XML_ID_CHARS, *it) != nullptr) {
|
||||||
|
idEncoded << *it;
|
||||||
|
} else {
|
||||||
|
// Select placeholder character based on invalid character to prevent name collisions
|
||||||
|
idEncoded << XML_ID_CHARS[(*it) % XML_ID_CHARS_COUNT];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return idEncoded.str();
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor for a specific scene to export
|
// 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)
|
ColladaExporter::ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file)
|
||||||
{
|
: mIOSystem(pIOSystem)
|
||||||
|
, mPath(path)
|
||||||
|
, mFile(file) {
|
||||||
// make sure that all formatting happens using the standard, C locale and not the user's current locale
|
// make sure that all formatting happens using the standard, C locale and not the user's current locale
|
||||||
mOutput.imbue( std::locale("C") );
|
mOutput.imbue( std::locale("C") );
|
||||||
mOutput.precision(16);
|
mOutput.precision(ASSIMP_AI_REAL_TEXT_PRECISION);
|
||||||
|
|
||||||
mScene = pScene;
|
mScene = pScene;
|
||||||
mSceneOwned = false;
|
mSceneOwned = false;
|
||||||
|
|
@ -115,17 +144,15 @@ ColladaExporter::ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, co
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor
|
// Destructor
|
||||||
ColladaExporter::~ColladaExporter()
|
ColladaExporter::~ColladaExporter() {
|
||||||
{
|
if ( mSceneOwned ) {
|
||||||
if(mSceneOwned) {
|
|
||||||
delete mScene;
|
delete mScene;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Starts writing the contents
|
// Starts writing the contents
|
||||||
void ColladaExporter::WriteFile()
|
void ColladaExporter::WriteFile() {
|
||||||
{
|
|
||||||
// write the DTD
|
// write the DTD
|
||||||
mOutput << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" << endstr;
|
mOutput << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" << endstr;
|
||||||
// COLLADA element start
|
// COLLADA element start
|
||||||
|
|
@ -149,7 +176,7 @@ void ColladaExporter::WriteFile()
|
||||||
// useless Collada fu at the end, just in case we haven't had enough indirections, yet.
|
// useless Collada fu at the end, just in case we haven't had enough indirections, yet.
|
||||||
mOutput << startstr << "<scene>" << endstr;
|
mOutput << startstr << "<scene>" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<instance_visual_scene url=\"#" + XMLEscape(mScene->mRootNode->mName.C_Str()) + "\" />" << endstr;
|
mOutput << startstr << "<instance_visual_scene url=\"#" + XMLIDEncode(mScene->mRootNode->mName.C_Str()) + "\" />" << endstr;
|
||||||
PopTag();
|
PopTag();
|
||||||
mOutput << startstr << "</scene>" << endstr;
|
mOutput << startstr << "</scene>" << endstr;
|
||||||
PopTag();
|
PopTag();
|
||||||
|
|
@ -158,9 +185,8 @@ void ColladaExporter::WriteFile()
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Writes the asset header
|
// Writes the asset header
|
||||||
void ColladaExporter::WriteHeader()
|
void ColladaExporter::WriteHeader() {
|
||||||
{
|
static const ai_real epsilon = Math::getEpsilon<ai_real>();
|
||||||
static const ai_real epsilon = ai_real( 0.00001 );
|
|
||||||
static const aiQuaternion x_rot(aiMatrix3x3(
|
static const aiQuaternion x_rot(aiMatrix3x3(
|
||||||
0, -1, 0,
|
0, -1, 0,
|
||||||
1, 0, 0,
|
1, 0, 0,
|
||||||
|
|
@ -238,25 +264,64 @@ void ColladaExporter::WriteHeader()
|
||||||
mOutput << startstr << "<contributor>" << endstr;
|
mOutput << startstr << "<contributor>" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
||||||
aiMetadata* meta = mScene->mRootNode->mMetaData;
|
// If no Scene metadata, use root node metadata
|
||||||
|
aiMetadata* meta = mScene->mMetaData;
|
||||||
|
if (nullptr == meta) {
|
||||||
|
meta = mScene->mRootNode->mMetaData;
|
||||||
|
}
|
||||||
|
|
||||||
aiString value;
|
aiString value;
|
||||||
if (!meta || !meta->Get("Author", value))
|
if (!meta || !meta->Get("Author", value)) {
|
||||||
mOutput << startstr << "<author>" << "Assimp" << "</author>" << endstr;
|
mOutput << startstr << "<author>" << "Assimp" << "</author>" << endstr;
|
||||||
else
|
} else {
|
||||||
mOutput << startstr << "<author>" << XMLEscape(value.C_Str()) << "</author>" << endstr;
|
mOutput << startstr << "<author>" << XMLEscape(value.C_Str()) << "</author>" << endstr;
|
||||||
|
}
|
||||||
|
|
||||||
if (!meta || !meta->Get("AuthoringTool", value))
|
if (nullptr == meta || !meta->Get("AuthoringTool", value)) {
|
||||||
mOutput << startstr << "<authoring_tool>" << "Assimp Exporter" << "</authoring_tool>" << endstr;
|
mOutput << startstr << "<authoring_tool>" << "Assimp Exporter" << "</authoring_tool>" << endstr;
|
||||||
else
|
} else {
|
||||||
mOutput << startstr << "<authoring_tool>" << XMLEscape(value.C_Str()) << "</authoring_tool>" << endstr;
|
mOutput << startstr << "<authoring_tool>" << XMLEscape(value.C_Str()) << "</authoring_tool>" << endstr;
|
||||||
|
}
|
||||||
|
|
||||||
//mOutput << startstr << "<author>" << mScene->author.C_Str() << "</author>" << endstr;
|
if (meta) {
|
||||||
//mOutput << startstr << "<authoring_tool>" << mScene->authoringTool.C_Str() << "</authoring_tool>" << endstr;
|
if (meta->Get("Comments", value)) {
|
||||||
|
mOutput << startstr << "<comments>" << XMLEscape(value.C_Str()) << "</comments>" << endstr;
|
||||||
|
}
|
||||||
|
if (meta->Get("Copyright", value)) {
|
||||||
|
mOutput << startstr << "<copyright>" << XMLEscape(value.C_Str()) << "</copyright>" << endstr;
|
||||||
|
}
|
||||||
|
if (meta->Get("SourceData", value)) {
|
||||||
|
mOutput << startstr << "<source_data>" << XMLEscape(value.C_Str()) << "</source_data>" << endstr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PopTag();
|
PopTag();
|
||||||
mOutput << startstr << "</contributor>" << endstr;
|
mOutput << startstr << "</contributor>" << endstr;
|
||||||
mOutput << startstr << "<created>" << date_str << "</created>" << endstr;
|
|
||||||
|
if (nullptr == meta || !meta->Get("Created", value)) {
|
||||||
|
mOutput << startstr << "<created>" << date_str << "</created>" << endstr;
|
||||||
|
} else {
|
||||||
|
mOutput << startstr << "<created>" << XMLEscape(value.C_Str()) << "</created>" << endstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modified date is always the date saved
|
||||||
mOutput << startstr << "<modified>" << date_str << "</modified>" << endstr;
|
mOutput << startstr << "<modified>" << date_str << "</modified>" << endstr;
|
||||||
|
|
||||||
|
if (meta) {
|
||||||
|
if (meta->Get("Keywords", value)) {
|
||||||
|
mOutput << startstr << "<keywords>" << XMLEscape(value.C_Str()) << "</keywords>" << endstr;
|
||||||
|
}
|
||||||
|
if (meta->Get("Revision", value)) {
|
||||||
|
mOutput << startstr << "<revision>" << XMLEscape(value.C_Str()) << "</revision>" << endstr;
|
||||||
|
}
|
||||||
|
if (meta->Get("Subject", value)) {
|
||||||
|
mOutput << startstr << "<subject>" << XMLEscape(value.C_Str()) << "</subject>" << endstr;
|
||||||
|
}
|
||||||
|
if (meta->Get("Title", value)) {
|
||||||
|
mOutput << startstr << "<title>" << XMLEscape(value.C_Str()) << "</title>" << endstr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mOutput << startstr << "<unit name=\"meter\" meter=\"" << scale << "\" />" << endstr;
|
mOutput << startstr << "<unit name=\"meter\" meter=\"" << scale << "\" />" << endstr;
|
||||||
mOutput << startstr << "<up_axis>" << up_axis << "</up_axis>" << endstr;
|
mOutput << startstr << "<up_axis>" << up_axis << "</up_axis>" << endstr;
|
||||||
PopTag();
|
PopTag();
|
||||||
|
|
@ -269,18 +334,21 @@ void ColladaExporter::WriteTextures() {
|
||||||
static const unsigned int buffer_size = 1024;
|
static const unsigned int buffer_size = 1024;
|
||||||
char str[buffer_size];
|
char str[buffer_size];
|
||||||
|
|
||||||
if(mScene->HasTextures()) {
|
if (mScene->HasTextures()) {
|
||||||
for(unsigned int i = 0; i < mScene->mNumTextures; i++) {
|
for(unsigned int i = 0; i < mScene->mNumTextures; i++) {
|
||||||
// It would be great to be able to create a directory in portable standard C++, but it's not the case,
|
// It would be great to be able to create a directory in portable standard C++, but it's not the case,
|
||||||
// so we just write the textures in the current directory.
|
// so we just write the textures in the current directory.
|
||||||
|
|
||||||
aiTexture* texture = mScene->mTextures[i];
|
aiTexture* texture = mScene->mTextures[i];
|
||||||
|
if ( nullptr == texture ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ASSIMP_itoa10(str, buffer_size, i + 1);
|
ASSIMP_itoa10(str, buffer_size, i + 1);
|
||||||
|
|
||||||
std::string name = mFile + "_texture_" + (i < 1000 ? "0" : "") + (i < 100 ? "0" : "") + (i < 10 ? "0" : "") + str + "." + ((const char*) texture->achFormatHint);
|
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 + name, "wb"));
|
std::unique_ptr<IOStream> outfile(mIOSystem->Open(mPath + mIOSystem->getOsSeparator() + name, "wb"));
|
||||||
if(outfile == NULL) {
|
if(outfile == NULL) {
|
||||||
throw DeadlyExportError("could not open output texture file: " + mPath + name);
|
throw DeadlyExportError("could not open output texture file: " + mPath + name);
|
||||||
}
|
}
|
||||||
|
|
@ -318,9 +386,10 @@ void ColladaExporter::WriteCamerasLibrary() {
|
||||||
void ColladaExporter::WriteCamera(size_t pIndex){
|
void ColladaExporter::WriteCamera(size_t pIndex){
|
||||||
|
|
||||||
const aiCamera *cam = mScene->mCameras[pIndex];
|
const aiCamera *cam = mScene->mCameras[pIndex];
|
||||||
const std::string idstrEscaped = XMLEscape(cam->mName.C_Str());
|
const std::string cameraName = XMLEscape(cam->mName.C_Str());
|
||||||
|
const std::string cameraId = XMLIDEncode(cam->mName.C_Str());
|
||||||
|
|
||||||
mOutput << startstr << "<camera id=\"" << idstrEscaped << "-camera\" name=\"" << idstrEscaped << "_name\" >" << endstr;
|
mOutput << startstr << "<camera id=\"" << cameraId << "-camera\" name=\"" << cameraName << "\" >" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<optics>" << endstr;
|
mOutput << startstr << "<optics>" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
@ -374,10 +443,11 @@ void ColladaExporter::WriteLightsLibrary() {
|
||||||
void ColladaExporter::WriteLight(size_t pIndex){
|
void ColladaExporter::WriteLight(size_t pIndex){
|
||||||
|
|
||||||
const aiLight *light = mScene->mLights[pIndex];
|
const aiLight *light = mScene->mLights[pIndex];
|
||||||
const std::string idstrEscaped = XMLEscape(light->mName.C_Str());
|
const std::string lightName = XMLEscape(light->mName.C_Str());
|
||||||
|
const std::string lightId = XMLIDEncode(light->mName.C_Str());
|
||||||
|
|
||||||
mOutput << startstr << "<light id=\"" << idstrEscaped << "-light\" name=\""
|
mOutput << startstr << "<light id=\"" << lightId << "-light\" name=\""
|
||||||
<< idstrEscaped << "_name\" >" << endstr;
|
<< lightName << "\" >" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<technique_common>" << endstr;
|
mOutput << startstr << "<technique_common>" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
@ -428,6 +498,7 @@ void ColladaExporter::WritePointLight(const aiLight *const light){
|
||||||
mOutput << startstr << "</point>" << endstr;
|
mOutput << startstr << "</point>" << endstr;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaExporter::WriteDirectionalLight(const aiLight *const light){
|
void ColladaExporter::WriteDirectionalLight(const aiLight *const light){
|
||||||
const aiColor3D &color= light->mColorDiffuse;
|
const aiColor3D &color= light->mColorDiffuse;
|
||||||
mOutput << startstr << "<directional>" << endstr;
|
mOutput << startstr << "<directional>" << endstr;
|
||||||
|
|
@ -440,6 +511,7 @@ void ColladaExporter::WriteDirectionalLight(const aiLight *const light){
|
||||||
mOutput << startstr << "</directional>" << endstr;
|
mOutput << startstr << "</directional>" << endstr;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaExporter::WriteSpotLight(const aiLight *const light){
|
void ColladaExporter::WriteSpotLight(const aiLight *const light){
|
||||||
|
|
||||||
const aiColor3D &color= light->mColorDiffuse;
|
const aiColor3D &color= light->mColorDiffuse;
|
||||||
|
|
@ -496,18 +568,16 @@ void ColladaExporter::WriteAmbienttLight(const aiLight *const light){
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads a single surface entry from the given material keys
|
// 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)
|
void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat,
|
||||||
{
|
aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex) {
|
||||||
if( pSrcMat->GetTextureCount( pTexture) > 0 )
|
if( pSrcMat->GetTextureCount( pTexture) > 0 ) {
|
||||||
{
|
|
||||||
aiString texfile;
|
aiString texfile;
|
||||||
unsigned int uvChannel = 0;
|
unsigned int uvChannel = 0;
|
||||||
pSrcMat->GetTexture( pTexture, 0, &texfile, NULL, &uvChannel);
|
pSrcMat->GetTexture( pTexture, 0, &texfile, NULL, &uvChannel);
|
||||||
|
|
||||||
std::string index_str(texfile.C_Str());
|
std::string index_str(texfile.C_Str());
|
||||||
|
|
||||||
if(index_str.size() != 0 && index_str[0] == '*')
|
if(index_str.size() != 0 && index_str[0] == '*') {
|
||||||
{
|
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
|
|
||||||
index_str = index_str.substr(1, std::string::npos);
|
index_str = index_str.substr(1, std::string::npos);
|
||||||
|
|
@ -525,15 +595,13 @@ void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial*
|
||||||
} else {
|
} else {
|
||||||
throw DeadlyExportError("could not find embedded texture at index " + index_str);
|
throw DeadlyExportError("could not find embedded texture at index " + index_str);
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
{
|
|
||||||
poSurface.texture = texfile.C_Str();
|
poSurface.texture = texfile.C_Str();
|
||||||
}
|
}
|
||||||
|
|
||||||
poSurface.channel = uvChannel;
|
poSurface.channel = uvChannel;
|
||||||
poSurface.exist = true;
|
poSurface.exist = true;
|
||||||
} else
|
} else {
|
||||||
{
|
|
||||||
if( pKey )
|
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;
|
||||||
}
|
}
|
||||||
|
|
@ -541,18 +609,16 @@ void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial*
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reimplementation of isalnum(,C locale), because AppVeyor does not see standard version.
|
// Reimplementation of isalnum(,C locale), because AppVeyor does not see standard version.
|
||||||
static bool isalnum_C(char c)
|
static bool isalnum_C(char c) {
|
||||||
{
|
|
||||||
return ( nullptr != strchr("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",c) );
|
return ( nullptr != strchr("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",c) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Writes an image entry for the given surface
|
// 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& pNameAdd) {
|
||||||
{
|
|
||||||
if( !pSurface.texture.empty() )
|
if( !pSurface.texture.empty() )
|
||||||
{
|
{
|
||||||
mOutput << startstr << "<image id=\"" << XMLEscape(pNameAdd) << "\">" << endstr;
|
mOutput << startstr << "<image id=\"" << XMLIDEncode(pNameAdd) << "\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<init_from>";
|
mOutput << startstr << "<init_from>";
|
||||||
|
|
||||||
|
|
@ -585,7 +651,7 @@ void ColladaExporter::WriteTextureColorEntry( const Surface& pSurface, const std
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mOutput << startstr << "<texture texture=\"" << XMLEscape(pImageName) << "\" texcoord=\"CHANNEL" << pSurface.channel << "\" />" << endstr;
|
mOutput << startstr << "<texture texture=\"" << XMLIDEncode(pImageName) << "\" texcoord=\"CHANNEL" << pSurface.channel << "\" />" << endstr;
|
||||||
}
|
}
|
||||||
PopTag();
|
PopTag();
|
||||||
mOutput << startstr << "</" << pTypeName << ">" << endstr;
|
mOutput << startstr << "</" << pTypeName << ">" << endstr;
|
||||||
|
|
@ -599,21 +665,21 @@ void ColladaExporter::WriteTextureParamEntry( const Surface& pSurface, const std
|
||||||
// if surface is a texture, write out the sampler and the surface parameters necessary to reference the texture
|
// if surface is a texture, write out the sampler and the surface parameters necessary to reference the texture
|
||||||
if( !pSurface.texture.empty() )
|
if( !pSurface.texture.empty() )
|
||||||
{
|
{
|
||||||
mOutput << startstr << "<newparam sid=\"" << XMLEscape(pMatName) << "-" << pTypeName << "-surface\">" << endstr;
|
mOutput << startstr << "<newparam sid=\"" << XMLIDEncode(pMatName) << "-" << pTypeName << "-surface\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<surface type=\"2D\">" << endstr;
|
mOutput << startstr << "<surface type=\"2D\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<init_from>" << XMLEscape(pMatName) << "-" << pTypeName << "-image</init_from>" << endstr;
|
mOutput << startstr << "<init_from>" << XMLIDEncode(pMatName) << "-" << pTypeName << "-image</init_from>" << endstr;
|
||||||
PopTag();
|
PopTag();
|
||||||
mOutput << startstr << "</surface>" << endstr;
|
mOutput << startstr << "</surface>" << endstr;
|
||||||
PopTag();
|
PopTag();
|
||||||
mOutput << startstr << "</newparam>" << endstr;
|
mOutput << startstr << "</newparam>" << endstr;
|
||||||
|
|
||||||
mOutput << startstr << "<newparam sid=\"" << XMLEscape(pMatName) << "-" << pTypeName << "-sampler\">" << endstr;
|
mOutput << startstr << "<newparam sid=\"" << XMLIDEncode(pMatName) << "-" << pTypeName << "-sampler\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<sampler2D>" << endstr;
|
mOutput << startstr << "<sampler2D>" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<source>" << XMLEscape(pMatName) << "-" << pTypeName << "-surface</source>" << endstr;
|
mOutput << startstr << "<source>" << XMLIDEncode(pMatName) << "-" << pTypeName << "-surface</source>" << endstr;
|
||||||
PopTag();
|
PopTag();
|
||||||
mOutput << startstr << "</sampler2D>" << endstr;
|
mOutput << startstr << "</sampler2D>" << endstr;
|
||||||
PopTag();
|
PopTag();
|
||||||
|
|
@ -665,11 +731,6 @@ void ColladaExporter::WriteMaterials()
|
||||||
materials[a].name = std::string(name.C_Str()) + to_string(materialCountWithThisName);
|
materials[a].name = std::string(name.C_Str()) + to_string(materialCountWithThisName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for( std::string::iterator it = materials[a].name.begin(); it != materials[a].name.end(); ++it ) {
|
|
||||||
if( !isalnum_C( *it ) ) {
|
|
||||||
*it = '_';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
aiShadingMode shading = aiShadingMode_Flat;
|
aiShadingMode shading = aiShadingMode_Flat;
|
||||||
materials[a].shading_model = "phong";
|
materials[a].shading_model = "phong";
|
||||||
|
|
@ -734,7 +795,7 @@ void ColladaExporter::WriteMaterials()
|
||||||
{
|
{
|
||||||
const Material& mat = *it;
|
const Material& mat = *it;
|
||||||
// this is so ridiculous it must be right
|
// this is so ridiculous it must be right
|
||||||
mOutput << startstr << "<effect id=\"" << XMLEscape(mat.name) << "-fx\" name=\"" << XMLEscape(mat.name) << "\">" << endstr;
|
mOutput << startstr << "<effect id=\"" << XMLIDEncode(mat.name) << "-fx\" name=\"" << XMLEscape(mat.name) << "\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<profile_COMMON>" << endstr;
|
mOutput << startstr << "<profile_COMMON>" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
@ -785,9 +846,9 @@ void ColladaExporter::WriteMaterials()
|
||||||
for( std::vector<Material>::const_iterator it = materials.begin(); it != materials.end(); ++it )
|
for( std::vector<Material>::const_iterator it = materials.begin(); it != materials.end(); ++it )
|
||||||
{
|
{
|
||||||
const Material& mat = *it;
|
const Material& mat = *it;
|
||||||
mOutput << startstr << "<material id=\"" << XMLEscape(mat.name) << "\" name=\"" << mat.name << "\">" << endstr;
|
mOutput << startstr << "<material id=\"" << XMLIDEncode(mat.name) << "\" name=\"" << XMLEscape(mat.name) << "\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<instance_effect url=\"#" << XMLEscape(mat.name) << "-fx\"/>" << endstr;
|
mOutput << startstr << "<instance_effect url=\"#" << XMLIDEncode(mat.name) << "-fx\"/>" << endstr;
|
||||||
PopTag();
|
PopTag();
|
||||||
mOutput << startstr << "</material>" << endstr;
|
mOutput << startstr << "</material>" << endstr;
|
||||||
}
|
}
|
||||||
|
|
@ -803,8 +864,9 @@ void ColladaExporter::WriteControllerLibrary()
|
||||||
mOutput << startstr << "<library_controllers>" << endstr;
|
mOutput << startstr << "<library_controllers>" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
||||||
for( size_t a = 0; a < mScene->mNumMeshes; ++a)
|
for( size_t a = 0; a < mScene->mNumMeshes; ++a) {
|
||||||
WriteController( a);
|
WriteController( a);
|
||||||
|
}
|
||||||
|
|
||||||
PopTag();
|
PopTag();
|
||||||
mOutput << startstr << "</library_controllers>" << endstr;
|
mOutput << startstr << "</library_controllers>" << endstr;
|
||||||
|
|
@ -815,8 +877,8 @@ void ColladaExporter::WriteControllerLibrary()
|
||||||
void ColladaExporter::WriteController( size_t pIndex)
|
void ColladaExporter::WriteController( size_t pIndex)
|
||||||
{
|
{
|
||||||
const aiMesh* mesh = mScene->mMeshes[pIndex];
|
const aiMesh* mesh = mScene->mMeshes[pIndex];
|
||||||
const std::string idstr = GetMeshId( pIndex);
|
const std::string idstr = mesh->mName.length == 0 ? GetMeshId(pIndex) : mesh->mName.C_Str();
|
||||||
const std::string idstrEscaped = XMLEscape(idstr);
|
const std::string idstrEscaped = XMLIDEncode(idstr);
|
||||||
|
|
||||||
if ( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
|
if ( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
|
||||||
return;
|
return;
|
||||||
|
|
@ -851,7 +913,7 @@ void ColladaExporter::WriteController( size_t pIndex)
|
||||||
mOutput << startstr << "<Name_array id=\"" << idstrEscaped << "-skin-joints-array\" count=\"" << mesh->mNumBones << "\">";
|
mOutput << startstr << "<Name_array id=\"" << idstrEscaped << "-skin-joints-array\" count=\"" << mesh->mNumBones << "\">";
|
||||||
|
|
||||||
for( size_t i = 0; i < mesh->mNumBones; ++i )
|
for( size_t i = 0; i < mesh->mNumBones; ++i )
|
||||||
mOutput << XMLEscape(mesh->mBones[i]->mName.C_Str()) << " ";
|
mOutput << XMLIDEncode(mesh->mBones[i]->mName.C_Str()) << " ";
|
||||||
|
|
||||||
mOutput << "</Name_array>" << endstr;
|
mOutput << "</Name_array>" << endstr;
|
||||||
|
|
||||||
|
|
@ -986,14 +1048,15 @@ void ColladaExporter::WriteGeometryLibrary()
|
||||||
void ColladaExporter::WriteGeometry( size_t pIndex)
|
void ColladaExporter::WriteGeometry( size_t pIndex)
|
||||||
{
|
{
|
||||||
const aiMesh* mesh = mScene->mMeshes[pIndex];
|
const aiMesh* mesh = mScene->mMeshes[pIndex];
|
||||||
const std::string idstr = GetMeshId( pIndex);
|
const std::string idstr = mesh->mName.length == 0 ? GetMeshId(pIndex) : mesh->mName.C_Str();
|
||||||
const std::string idstrEscaped = XMLEscape(idstr);
|
const std::string geometryName = XMLEscape(idstr);
|
||||||
|
const std::string geometryId = XMLIDEncode(idstr);
|
||||||
|
|
||||||
if ( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
|
if ( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// opening tag
|
// opening tag
|
||||||
mOutput << startstr << "<geometry id=\"" << idstrEscaped << "\" name=\"" << idstrEscaped << "_name\" >" << endstr;
|
mOutput << startstr << "<geometry id=\"" << geometryId << "\" name=\"" << geometryName << "\" >" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
||||||
mOutput << startstr << "<mesh>" << endstr;
|
mOutput << startstr << "<mesh>" << endstr;
|
||||||
|
|
@ -1024,9 +1087,9 @@ void ColladaExporter::WriteGeometry( size_t pIndex)
|
||||||
|
|
||||||
// assemble vertex structure
|
// assemble vertex structure
|
||||||
// Only write input for POSITION since we will write other as shared inputs in polygon definition
|
// Only write input for POSITION since we will write other as shared inputs in polygon definition
|
||||||
mOutput << startstr << "<vertices id=\"" << idstrEscaped << "-vertices" << "\">" << endstr;
|
mOutput << startstr << "<vertices id=\"" << geometryId << "-vertices" << "\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<input semantic=\"POSITION\" source=\"#" << idstrEscaped << "-positions\" />" << endstr;
|
mOutput << startstr << "<input semantic=\"POSITION\" source=\"#" << geometryId << "-positions\" />" << endstr;
|
||||||
PopTag();
|
PopTag();
|
||||||
mOutput << startstr << "</vertices>" << endstr;
|
mOutput << startstr << "</vertices>" << endstr;
|
||||||
|
|
||||||
|
|
@ -1044,18 +1107,18 @@ void ColladaExporter::WriteGeometry( size_t pIndex)
|
||||||
{
|
{
|
||||||
mOutput << startstr << "<lines count=\"" << countLines << "\" material=\"defaultMaterial\">" << endstr;
|
mOutput << startstr << "<lines count=\"" << countLines << "\" material=\"defaultMaterial\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<input offset=\"0\" semantic=\"VERTEX\" source=\"#" << idstrEscaped << "-vertices\" />" << endstr;
|
mOutput << startstr << "<input offset=\"0\" semantic=\"VERTEX\" source=\"#" << geometryId << "-vertices\" />" << endstr;
|
||||||
if( mesh->HasNormals() )
|
if( mesh->HasNormals() )
|
||||||
mOutput << startstr << "<input semantic=\"NORMAL\" source=\"#" << idstrEscaped << "-normals\" />" << endstr;
|
mOutput << startstr << "<input semantic=\"NORMAL\" source=\"#" << geometryId << "-normals\" />" << endstr;
|
||||||
for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
|
for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
|
||||||
{
|
{
|
||||||
if( mesh->HasTextureCoords(static_cast<unsigned int>(a)) )
|
if( mesh->HasTextureCoords(static_cast<unsigned int>(a)) )
|
||||||
mOutput << startstr << "<input semantic=\"TEXCOORD\" source=\"#" << idstrEscaped << "-tex" << a << "\" " << "set=\"" << a << "\"" << " />" << endstr;
|
mOutput << startstr << "<input semantic=\"TEXCOORD\" source=\"#" << geometryId << "-tex" << a << "\" " << "set=\"" << a << "\"" << " />" << endstr;
|
||||||
}
|
}
|
||||||
for( size_t a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a )
|
for( size_t a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a )
|
||||||
{
|
{
|
||||||
if( mesh->HasVertexColors(static_cast<unsigned int>(a) ) )
|
if( mesh->HasVertexColors(static_cast<unsigned int>(a) ) )
|
||||||
mOutput << startstr << "<input semantic=\"COLOR\" source=\"#" << idstrEscaped << "-color" << a << "\" " << "set=\"" << a << "\"" << " />" << endstr;
|
mOutput << startstr << "<input semantic=\"COLOR\" source=\"#" << geometryId << "-color" << a << "\" " << "set=\"" << a << "\"" << " />" << endstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
mOutput << startstr << "<p>";
|
mOutput << startstr << "<p>";
|
||||||
|
|
@ -1078,18 +1141,18 @@ void ColladaExporter::WriteGeometry( size_t pIndex)
|
||||||
{
|
{
|
||||||
mOutput << startstr << "<polylist count=\"" << countPoly << "\" material=\"defaultMaterial\">" << endstr;
|
mOutput << startstr << "<polylist count=\"" << countPoly << "\" material=\"defaultMaterial\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<input offset=\"0\" semantic=\"VERTEX\" source=\"#" << idstrEscaped << "-vertices\" />" << endstr;
|
mOutput << startstr << "<input offset=\"0\" semantic=\"VERTEX\" source=\"#" << geometryId << "-vertices\" />" << endstr;
|
||||||
if( mesh->HasNormals() )
|
if( mesh->HasNormals() )
|
||||||
mOutput << startstr << "<input offset=\"0\" semantic=\"NORMAL\" source=\"#" << idstrEscaped << "-normals\" />" << endstr;
|
mOutput << startstr << "<input offset=\"0\" semantic=\"NORMAL\" source=\"#" << geometryId << "-normals\" />" << endstr;
|
||||||
for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
|
for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
|
||||||
{
|
{
|
||||||
if( mesh->HasTextureCoords(static_cast<unsigned int>(a)) )
|
if( mesh->HasTextureCoords(static_cast<unsigned int>(a)) )
|
||||||
mOutput << startstr << "<input offset=\"0\" semantic=\"TEXCOORD\" source=\"#" << idstrEscaped << "-tex" << a << "\" " << "set=\"" << a << "\"" << " />" << endstr;
|
mOutput << startstr << "<input offset=\"0\" semantic=\"TEXCOORD\" source=\"#" << geometryId << "-tex" << a << "\" " << "set=\"" << a << "\"" << " />" << endstr;
|
||||||
}
|
}
|
||||||
for( size_t a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a )
|
for( size_t a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a )
|
||||||
{
|
{
|
||||||
if( mesh->HasVertexColors(static_cast<unsigned int>(a) ) )
|
if( mesh->HasVertexColors(static_cast<unsigned int>(a) ) )
|
||||||
mOutput << startstr << "<input offset=\"0\" semantic=\"COLOR\" source=\"#" << idstrEscaped << "-color" << a << "\" " << "set=\"" << a << "\"" << " />" << endstr;
|
mOutput << startstr << "<input offset=\"0\" semantic=\"COLOR\" source=\"#" << geometryId << "-color" << a << "\" " << "set=\"" << a << "\"" << " />" << endstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
mOutput << startstr << "<vcount>";
|
mOutput << startstr << "<vcount>";
|
||||||
|
|
@ -1138,13 +1201,13 @@ void ColladaExporter::WriteFloatArray( const std::string& pIdString, FloatDataTy
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string arrayId = pIdString + "-array";
|
std::string arrayId = XMLIDEncode(pIdString) + "-array";
|
||||||
|
|
||||||
mOutput << startstr << "<source id=\"" << XMLEscape(pIdString) << "\" name=\"" << XMLEscape(pIdString) << "\">" << endstr;
|
mOutput << startstr << "<source id=\"" << XMLIDEncode(pIdString) << "\" name=\"" << XMLEscape(pIdString) << "\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
||||||
// source array
|
// source array
|
||||||
mOutput << startstr << "<float_array id=\"" << XMLEscape(arrayId) << "\" count=\"" << pElementCount * floatsPerElement << "\"> ";
|
mOutput << startstr << "<float_array id=\"" << arrayId << "\" count=\"" << pElementCount * floatsPerElement << "\"> ";
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
||||||
if( pType == FloatType_TexCoord2 )
|
if( pType == FloatType_TexCoord2 )
|
||||||
|
|
@ -1230,11 +1293,12 @@ void ColladaExporter::WriteFloatArray( const std::string& pIdString, FloatDataTy
|
||||||
// Writes the scene library
|
// Writes the scene library
|
||||||
void ColladaExporter::WriteSceneLibrary()
|
void ColladaExporter::WriteSceneLibrary()
|
||||||
{
|
{
|
||||||
const std::string scene_name_escaped = XMLEscape(mScene->mRootNode->mName.C_Str());
|
const std::string sceneName = XMLEscape(mScene->mRootNode->mName.C_Str());
|
||||||
|
const std::string sceneId = XMLIDEncode(mScene->mRootNode->mName.C_Str());
|
||||||
|
|
||||||
mOutput << startstr << "<library_visual_scenes>" << endstr;
|
mOutput << startstr << "<library_visual_scenes>" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<visual_scene id=\"" + scene_name_escaped + "\" name=\"" + scene_name_escaped + "\">" << endstr;
|
mOutput << startstr << "<visual_scene id=\"" + sceneId + "\" name=\"" + sceneName + "\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
||||||
// start recursive write at the root node
|
// start recursive write at the root node
|
||||||
|
|
@ -1265,7 +1329,7 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
|
||||||
idstr = idstr + ending;
|
idstr = idstr + ending;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string idstrEscaped = XMLEscape(idstr);
|
const std::string idstrEscaped = XMLIDEncode(idstr);
|
||||||
|
|
||||||
mOutput << startstr << "<animation id=\"" + idstrEscaped + "\" name=\"" + animation_name_escaped + "\">" << endstr;
|
mOutput << startstr << "<animation id=\"" + idstrEscaped + "\" name=\"" + animation_name_escaped + "\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
@ -1337,13 +1401,13 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-interpolation");
|
const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-interpolation");
|
||||||
std::string arrayId = node_idstr + "-array";
|
std::string arrayId = XMLIDEncode(node_idstr) + "-array";
|
||||||
|
|
||||||
mOutput << startstr << "<source id=\"" << XMLEscape(node_idstr) << "\">" << endstr;
|
mOutput << startstr << "<source id=\"" << XMLIDEncode(node_idstr) << "\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
||||||
// source array
|
// source array
|
||||||
mOutput << startstr << "<Name_array id=\"" << XMLEscape(arrayId) << "\" count=\"" << names.size() << "\"> ";
|
mOutput << startstr << "<Name_array id=\"" << arrayId << "\" count=\"" << names.size() << "\"> ";
|
||||||
for( size_t a = 0; a < names.size(); ++a ) {
|
for( size_t a = 0; a < names.size(); ++a ) {
|
||||||
mOutput << names[a] << " ";
|
mOutput << names[a] << " ";
|
||||||
}
|
}
|
||||||
|
|
@ -1352,7 +1416,7 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
|
||||||
mOutput << startstr << "<technique_common>" << endstr;
|
mOutput << startstr << "<technique_common>" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
||||||
mOutput << startstr << "<accessor source=\"#" << XMLEscape(arrayId) << "\" count=\"" << names.size() << "\" stride=\"" << 1 << "\">" << endstr;
|
mOutput << startstr << "<accessor source=\"#" << arrayId << "\" count=\"" << names.size() << "\" stride=\"" << 1 << "\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
||||||
mOutput << startstr << "<param name=\"INTERPOLATION\" type=\"name\"></param>" << endstr;
|
mOutput << startstr << "<param name=\"INTERPOLATION\" type=\"name\"></param>" << endstr;
|
||||||
|
|
@ -1374,12 +1438,12 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
|
||||||
{
|
{
|
||||||
// samplers
|
// samplers
|
||||||
const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-sampler");
|
const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-sampler");
|
||||||
mOutput << startstr << "<sampler id=\"" << XMLEscape(node_idstr) << "\">" << endstr;
|
mOutput << startstr << "<sampler id=\"" << XMLIDEncode(node_idstr) << "\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
||||||
mOutput << startstr << "<input semantic=\"INPUT\" source=\"#" << XMLEscape( nodeAnim->mNodeName.data + std::string("_matrix-input") ) << "\"/>" << endstr;
|
mOutput << startstr << "<input semantic=\"INPUT\" source=\"#" << XMLIDEncode( nodeAnim->mNodeName.data + std::string("_matrix-input") ) << "\"/>" << endstr;
|
||||||
mOutput << startstr << "<input semantic=\"OUTPUT\" source=\"#" << XMLEscape( nodeAnim->mNodeName.data + std::string("_matrix-output") ) << "\"/>" << endstr;
|
mOutput << startstr << "<input semantic=\"OUTPUT\" source=\"#" << XMLIDEncode( nodeAnim->mNodeName.data + std::string("_matrix-output") ) << "\"/>" << endstr;
|
||||||
mOutput << startstr << "<input semantic=\"INTERPOLATION\" source=\"#" << XMLEscape( nodeAnim->mNodeName.data + std::string("_matrix-interpolation") ) << "\"/>" << endstr;
|
mOutput << startstr << "<input semantic=\"INTERPOLATION\" source=\"#" << XMLIDEncode( nodeAnim->mNodeName.data + std::string("_matrix-interpolation") ) << "\"/>" << endstr;
|
||||||
|
|
||||||
PopTag();
|
PopTag();
|
||||||
mOutput << startstr << "</sampler>" << endstr;
|
mOutput << startstr << "</sampler>" << endstr;
|
||||||
|
|
@ -1391,7 +1455,7 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
|
||||||
|
|
||||||
{
|
{
|
||||||
// channels
|
// channels
|
||||||
mOutput << startstr << "<channel source=\"#" << XMLEscape( nodeAnim->mNodeName.data + std::string("_matrix-sampler") ) << "\" target=\"" << XMLEscape(nodeAnim->mNodeName.data) << "/matrix\"/>" << endstr;
|
mOutput << startstr << "<channel source=\"#" << XMLIDEncode( nodeAnim->mNodeName.data + std::string("_matrix-sampler") ) << "\" target=\"" << XMLIDEncode(nodeAnim->mNodeName.data) << "/matrix\"/>" << endstr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1402,8 +1466,6 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ColladaExporter::WriteAnimationsLibrary()
|
void ColladaExporter::WriteAnimationsLibrary()
|
||||||
{
|
{
|
||||||
const std::string scene_name_escaped = XMLEscape(mScene->mRootNode->mName.C_Str());
|
|
||||||
|
|
||||||
if ( mScene->mNumAnimations > 0 ) {
|
if ( mScene->mNumAnimations > 0 ) {
|
||||||
mOutput << startstr << "<library_animations>" << endstr;
|
mOutput << startstr << "<library_animations>" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
@ -1511,16 +1573,17 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string node_name_escaped = XMLEscape(pNode->mName.data);
|
const std::string node_id = XMLIDEncode(pNode->mName.data);
|
||||||
|
const std::string node_name = XMLEscape(pNode->mName.data);
|
||||||
mOutput << startstr << "<node ";
|
mOutput << startstr << "<node ";
|
||||||
if(is_skeleton_root) {
|
if(is_skeleton_root) {
|
||||||
mOutput << "id=\"" << node_name_escaped << "\" " << (is_joint ? "sid=\"" + node_name_escaped +"\"" : "") ; // For now, only support one skeleton in a scene.
|
mOutput << "id=\"" << node_id << "\" " << (is_joint ? "sid=\"" + node_id +"\"" : "") ; // For now, only support one skeleton in a scene.
|
||||||
mFoundSkeletonRootNodeID = node_name_escaped;
|
mFoundSkeletonRootNodeID = node_id;
|
||||||
} else {
|
} else {
|
||||||
mOutput << "id=\"" << node_name_escaped << "\" " << (is_joint ? "sid=\"" + node_name_escaped +"\"": "") ;
|
mOutput << "id=\"" << node_id << "\" " << (is_joint ? "sid=\"" + node_id +"\"": "") ;
|
||||||
}
|
}
|
||||||
|
|
||||||
mOutput << " name=\"" << node_name_escaped
|
mOutput << " name=\"" << node_name
|
||||||
<< "\" type=\"" << node_type
|
<< "\" type=\"" << node_type
|
||||||
<< "\">" << endstr;
|
<< "\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
@ -1559,14 +1622,14 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
|
||||||
//check if it is a camera node
|
//check if it is a camera node
|
||||||
for(size_t i=0; i<mScene->mNumCameras; i++){
|
for(size_t i=0; i<mScene->mNumCameras; i++){
|
||||||
if(mScene->mCameras[i]->mName == pNode->mName){
|
if(mScene->mCameras[i]->mName == pNode->mName){
|
||||||
mOutput << startstr <<"<instance_camera url=\"#" << node_name_escaped << "-camera\"/>" << endstr;
|
mOutput << startstr <<"<instance_camera url=\"#" << node_id << "-camera\"/>" << endstr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//check if it is a light node
|
//check if it is a light node
|
||||||
for(size_t i=0; i<mScene->mNumLights; i++){
|
for(size_t i=0; i<mScene->mNumLights; i++){
|
||||||
if(mScene->mLights[i]->mName == pNode->mName){
|
if(mScene->mLights[i]->mName == pNode->mName){
|
||||||
mOutput << startstr <<"<instance_light url=\"#" << node_name_escaped << "-light\"/>" << endstr;
|
mOutput << startstr <<"<instance_light url=\"#" << node_id << "-light\"/>" << endstr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1580,15 +1643,17 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
|
||||||
if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
|
if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
const std::string meshName = mesh->mName.length == 0 ? GetMeshId(pNode->mMeshes[a]) : mesh->mName.C_Str();
|
||||||
|
|
||||||
if( mesh->mNumBones == 0 )
|
if( mesh->mNumBones == 0 )
|
||||||
{
|
{
|
||||||
mOutput << startstr << "<instance_geometry url=\"#" << XMLEscape(GetMeshId( pNode->mMeshes[a])) << "\">" << endstr;
|
mOutput << startstr << "<instance_geometry url=\"#" << XMLIDEncode(meshName) << "\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mOutput << startstr
|
mOutput << startstr
|
||||||
<< "<instance_controller url=\"#" << XMLEscape(GetMeshId( pNode->mMeshes[a])) << "-skin\">"
|
<< "<instance_controller url=\"#" << XMLIDEncode(meshName) << "-skin\">"
|
||||||
<< endstr;
|
<< endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
||||||
|
|
@ -1596,7 +1661,7 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
|
||||||
// use the first bone to find skeleton root
|
// use the first bone to find skeleton root
|
||||||
const aiNode * skeletonRootBoneNode = findSkeletonRootNode( pScene, mesh );
|
const aiNode * skeletonRootBoneNode = findSkeletonRootNode( pScene, mesh );
|
||||||
if ( skeletonRootBoneNode ) {
|
if ( skeletonRootBoneNode ) {
|
||||||
mFoundSkeletonRootNodeID = XMLEscape( skeletonRootBoneNode->mName.C_Str() );
|
mFoundSkeletonRootNodeID = XMLIDEncode( skeletonRootBoneNode->mName.C_Str() );
|
||||||
}
|
}
|
||||||
mOutput << startstr << "<skeleton>#" << mFoundSkeletonRootNodeID << "</skeleton>" << endstr;
|
mOutput << startstr << "<skeleton>#" << mFoundSkeletonRootNodeID << "</skeleton>" << endstr;
|
||||||
}
|
}
|
||||||
|
|
@ -1604,7 +1669,7 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<technique_common>" << endstr;
|
mOutput << startstr << "<technique_common>" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<instance_material symbol=\"defaultMaterial\" target=\"#" << XMLEscape(materials[mesh->mMaterialIndex].name) << "\">" << endstr;
|
mOutput << startstr << "<instance_material symbol=\"defaultMaterial\" target=\"#" << XMLIDEncode(materials[mesh->mMaterialIndex].name) << "\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
|
for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
|
||||||
{
|
{
|
||||||
|
|
@ -150,7 +150,6 @@ public:
|
||||||
/// Stringstream to write all output into
|
/// Stringstream to write all output into
|
||||||
std::stringstream mOutput;
|
std::stringstream mOutput;
|
||||||
|
|
||||||
protected:
|
|
||||||
/// The IOSystem for output
|
/// The IOSystem for output
|
||||||
IOSystem* mIOSystem;
|
IOSystem* mIOSystem;
|
||||||
|
|
||||||
|
|
@ -204,7 +203,7 @@ protected:
|
||||||
|
|
||||||
std::map<unsigned int, std::string> textures;
|
std::map<unsigned int, std::string> textures;
|
||||||
|
|
||||||
protected:
|
public:
|
||||||
/// Dammit C++ - y u no compile two-pass? No I have to add all methods below the struct definitions
|
/// 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
|
/// 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);
|
void ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat, aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex);
|
||||||
|
|
@ -580,15 +580,11 @@ struct Image
|
||||||
{
|
{
|
||||||
std::string mFileName;
|
std::string mFileName;
|
||||||
|
|
||||||
/** If image file name is zero, embedded image data
|
/** Embedded image data */
|
||||||
*/
|
|
||||||
std::vector<uint8_t> mImageData;
|
std::vector<uint8_t> mImageData;
|
||||||
|
|
||||||
/** If image file name is zero, file format of
|
/** File format hint of embedded image data */
|
||||||
* embedded image data.
|
|
||||||
*/
|
|
||||||
std::string mEmbeddedFormat;
|
std::string mEmbeddedFormat;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** An animation channel. */
|
/** An animation channel. */
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -94,20 +94,20 @@ public:
|
||||||
public:
|
public:
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
* See BaseImporter::CanRead() for details. */
|
* See BaseImporter::CanRead() for details. */
|
||||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
|
bool CanRead(const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Return importer meta information.
|
/** Return importer meta information.
|
||||||
* See #BaseImporter::GetInfo for the details
|
* See #BaseImporter::GetInfo for the details
|
||||||
*/
|
*/
|
||||||
const aiImporterDesc* GetInfo () const;
|
const aiImporterDesc* GetInfo () const override;
|
||||||
|
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp) override;
|
||||||
|
|
||||||
/** Imports the given file into the given scene structure.
|
/** Imports the given file into the given scene structure.
|
||||||
* See BaseImporter::InternReadFile() for details
|
* See BaseImporter::InternReadFile() for details
|
||||||
*/
|
*/
|
||||||
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
|
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) override;
|
||||||
|
|
||||||
/** Recursively constructs a scene node for the given parser node and returns it. */
|
/** Recursively constructs a scene node for the given parser node and returns it. */
|
||||||
aiNode* BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode);
|
aiNode* BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode);
|
||||||
|
|
@ -120,7 +120,7 @@ protected:
|
||||||
void BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode,
|
void BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode,
|
||||||
aiNode* pTarget);
|
aiNode* pTarget);
|
||||||
|
|
||||||
aiMesh *findMesh(std::string meshid);
|
aiMesh *findMesh(const std::string& meshid);
|
||||||
|
|
||||||
/** Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh */
|
/** Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh */
|
||||||
aiMesh* CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh,
|
aiMesh* CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh,
|
||||||
|
|
@ -184,9 +184,6 @@ protected:
|
||||||
aiString FindFilenameForEffectTexture( const ColladaParser& pParser,
|
aiString FindFilenameForEffectTexture( const ColladaParser& pParser,
|
||||||
const Collada::Effect& pEffect, const std::string& pName);
|
const Collada::Effect& pEffect, const std::string& pName);
|
||||||
|
|
||||||
/** Converts a path read from a collada file to the usual representation */
|
|
||||||
void ConvertPath( aiString& ss);
|
|
||||||
|
|
||||||
/** Reads a float value from an accessor and its data array.
|
/** Reads a float value from an accessor and its data array.
|
||||||
* @param pAccessor The accessor to use for reading
|
* @param pAccessor The accessor to use for reading
|
||||||
* @param pData The data array to read from
|
* @param pData The data array to read from
|
||||||
3473
Engine/lib/assimp/code/Collada/ColladaParser.cpp
Normal file
3473
Engine/lib/assimp/code/Collada/ColladaParser.cpp
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -54,6 +54,7 @@
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
|
class ZipArchiveIOSystem;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------
|
||||||
/** Parser helper class for the Collada loader.
|
/** Parser helper class for the Collada loader.
|
||||||
|
|
@ -65,13 +66,22 @@ namespace Assimp
|
||||||
{
|
{
|
||||||
friend class ColladaLoader;
|
friend class ColladaLoader;
|
||||||
|
|
||||||
|
/** Converts a path read from a collada file to the usual representation */
|
||||||
|
static void UriDecodePath(aiString& ss);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
/** Map for generic metadata as aiString */
|
||||||
|
typedef std::map<std::string, aiString> StringMetaData;
|
||||||
|
|
||||||
/** Constructor from XML file */
|
/** Constructor from XML file */
|
||||||
ColladaParser( IOSystem* pIOHandler, const std::string& pFile);
|
ColladaParser(IOSystem* pIOHandler, const std::string& pFile);
|
||||||
|
|
||||||
/** Destructor */
|
/** Destructor */
|
||||||
~ColladaParser();
|
~ColladaParser();
|
||||||
|
|
||||||
|
/** Attempts to read the ZAE manifest and returns the DAE to open */
|
||||||
|
static std::string ReadZaeManifest(ZipArchiveIOSystem &zip_archive);
|
||||||
|
|
||||||
/** Reads the contents of the file */
|
/** Reads the contents of the file */
|
||||||
void ReadContents();
|
void ReadContents();
|
||||||
|
|
||||||
|
|
@ -81,6 +91,15 @@ namespace Assimp
|
||||||
/** Reads asset information such as coordinate system information and legal blah */
|
/** Reads asset information such as coordinate system information and legal blah */
|
||||||
void ReadAssetInfo();
|
void ReadAssetInfo();
|
||||||
|
|
||||||
|
/** Reads contributor information such as author and legal blah */
|
||||||
|
void ReadContributorInfo();
|
||||||
|
|
||||||
|
/** Reads generic metadata into provided map */
|
||||||
|
void ReadMetaDataItem(StringMetaData &metadata);
|
||||||
|
|
||||||
|
/** Convert underscore_seperated to CamelCase "authoring_tool" becomes "AuthoringTool" */
|
||||||
|
static void ToCamelCase(std::string &text);
|
||||||
|
|
||||||
/** Reads the animation library */
|
/** Reads the animation library */
|
||||||
void ReadAnimationLibrary();
|
void ReadAnimationLibrary();
|
||||||
|
|
||||||
|
|
@ -223,6 +242,9 @@ namespace Assimp
|
||||||
// Processes bind_vertex_input and bind elements
|
// 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 */
|
/** Aborts the file reading with an exception */
|
||||||
AI_WONT_RETURN void ThrowException( const std::string& pError) const AI_WONT_RETURN_SUFFIX;
|
AI_WONT_RETURN void ThrowException( const std::string& pError) const AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
@ -343,6 +365,9 @@ namespace Assimp
|
||||||
/** Which is the up vector */
|
/** 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 file format version */
|
||||||
Collada::FormatVersion mFormat;
|
Collada::FormatVersion mFormat;
|
||||||
};
|
};
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -54,7 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/Exceptional.h>
|
#include <assimp/Exceptional.h>
|
||||||
#include <assimp/BaseImporter.h>
|
#include <assimp/BaseImporter.h>
|
||||||
|
|
||||||
#include "CInterfaceIOWrapper.h"
|
#include "CApi/CInterfaceIOWrapper.h"
|
||||||
#include "Importer.h"
|
#include "Importer.h"
|
||||||
#include "ScenePrivate.h"
|
#include "ScenePrivate.h"
|
||||||
|
|
||||||
|
|
@ -67,7 +67,20 @@ using namespace Assimp;
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
BaseImporter::BaseImporter() AI_NO_EXCEPT
|
BaseImporter::BaseImporter() AI_NO_EXCEPT
|
||||||
: m_progress() {
|
: m_progress() {
|
||||||
// nothing to do here
|
/**
|
||||||
|
* Assimp Importer
|
||||||
|
* unit conversions available
|
||||||
|
* if you need another measurment unit add it below.
|
||||||
|
* it's currently defined in assimp that we prefer meters.
|
||||||
|
*
|
||||||
|
* NOTE: Initialised here rather than in the header file
|
||||||
|
* to workaround a VS2013 bug with brace initialisers
|
||||||
|
* */
|
||||||
|
importerUnits[ImporterUnits::M] = 1.0;
|
||||||
|
importerUnits[ImporterUnits::CM] = 0.01;
|
||||||
|
importerUnits[ImporterUnits::MM] = 0.001;
|
||||||
|
importerUnits[ImporterUnits::INCHES] = 0.0254;
|
||||||
|
importerUnits[ImporterUnits::FEET] = 0.3048;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
@ -76,9 +89,25 @@ BaseImporter::~BaseImporter() {
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BaseImporter::UpdateImporterScale( Importer* pImp )
|
||||||
|
{
|
||||||
|
ai_assert(pImp != nullptr);
|
||||||
|
ai_assert(importerScale != 0.0);
|
||||||
|
ai_assert(fileScale != 0.0);
|
||||||
|
|
||||||
|
double activeScale = importerScale * fileScale;
|
||||||
|
|
||||||
|
// Set active scaling
|
||||||
|
pImp->SetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, static_cast<float>( activeScale) );
|
||||||
|
|
||||||
|
ASSIMP_LOG_DEBUG_F("UpdateImporterScale scale set: %f", activeScale );
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file and returns the imported data.
|
// Imports the given file and returns the imported data.
|
||||||
aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile, IOSystem* pIOHandler) {
|
aiScene* BaseImporter::ReadFile(Importer* pImp, const std::string& pFile, IOSystem* pIOHandler) {
|
||||||
|
|
||||||
|
|
||||||
m_progress = pImp->GetProgressHandler();
|
m_progress = pImp->GetProgressHandler();
|
||||||
if (nullptr == m_progress) {
|
if (nullptr == m_progress) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
@ -100,6 +129,11 @@ aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile,
|
||||||
{
|
{
|
||||||
InternReadFile( pFile, sc.get(), &filter);
|
InternReadFile( pFile, sc.get(), &filter);
|
||||||
|
|
||||||
|
// Calculate import scale hook - required because pImp not available anywhere else
|
||||||
|
// passes scale into ScaleProcess
|
||||||
|
UpdateImporterScale(pImp);
|
||||||
|
|
||||||
|
|
||||||
} catch( const std::exception& err ) {
|
} catch( const std::exception& err ) {
|
||||||
// extract error description
|
// extract error description
|
||||||
m_ErrorText = err.what();
|
m_ErrorText = err.what();
|
||||||
|
|
@ -112,7 +146,7 @@ aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BaseImporter::SetupProperties(const Importer* /*pImp*/)
|
void BaseImporter::SetupProperties(const Importer* pImp)
|
||||||
{
|
{
|
||||||
// the default implementation does nothing
|
// the default implementation does nothing
|
||||||
}
|
}
|
||||||
|
|
@ -320,7 +354,11 @@ std::string BaseImporter::GetExtension( const std::string& file ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "../contrib/utf8cpp/source/utf8.h"
|
#ifdef ASSIMP_USE_HUNTER
|
||||||
|
# include <utf8/utf8.h>
|
||||||
|
#else
|
||||||
|
# include "../contrib/utf8cpp/source/utf8.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Convert to UTF8 data
|
// Convert to UTF8 data
|
||||||
|
|
@ -584,6 +622,8 @@ aiScene* BatchLoader::GetImport( unsigned int which )
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BatchLoader::LoadAll()
|
void BatchLoader::LoadAll()
|
||||||
{
|
{
|
||||||
|
|
@ -89,7 +89,7 @@ void BaseProcess::ExecuteOnScene( Importer* pImp)
|
||||||
|
|
||||||
// and kill the partially imported data
|
// and kill the partially imported data
|
||||||
delete pImp->Pimpl()->mScene;
|
delete pImp->Pimpl()->mScene;
|
||||||
pImp->Pimpl()->mScene = NULL;
|
pImp->Pimpl()->mScene = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,10 +47,6 @@ namespace Assimp {
|
||||||
aiAnimMesh *aiCreateAnimMesh(const aiMesh *mesh)
|
aiAnimMesh *aiCreateAnimMesh(const aiMesh *mesh)
|
||||||
{
|
{
|
||||||
aiAnimMesh *animesh = new aiAnimMesh;
|
aiAnimMesh *animesh = new aiAnimMesh;
|
||||||
animesh->mVertices = NULL;
|
|
||||||
animesh->mNormals = NULL;
|
|
||||||
animesh->mTangents = NULL;
|
|
||||||
animesh->mBitangents = NULL;
|
|
||||||
animesh->mNumVertices = mesh->mNumVertices;
|
animesh->mNumVertices = mesh->mNumVertices;
|
||||||
if (mesh->mVertices) {
|
if (mesh->mVertices) {
|
||||||
animesh->mVertices = new aiVector3D[animesh->mNumVertices];
|
animesh->mVertices = new aiVector3D[animesh->mNumVertices];
|
||||||
|
|
@ -52,6 +52,35 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
template<size_t sizeOfPointer>
|
||||||
|
size_t select_ftell(FILE* file)
|
||||||
|
{
|
||||||
|
return ::ftell(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t sizeOfPointer>
|
||||||
|
int select_fseek(FILE* file, int64_t offset, int origin)
|
||||||
|
{
|
||||||
|
return ::fseek(file, static_cast<long>(offset), origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined _WIN32 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601)
|
||||||
|
template<>
|
||||||
|
size_t select_ftell<8>(FILE* file)
|
||||||
|
{
|
||||||
|
return ::_ftelli64(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
int select_fseek<8>(FILE* file, int64_t offset, int origin)
|
||||||
|
{
|
||||||
|
return ::_fseeki64(file, offset, origin);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
DefaultIOStream::~DefaultIOStream()
|
DefaultIOStream::~DefaultIOStream()
|
||||||
{
|
{
|
||||||
|
|
@ -93,7 +122,7 @@ aiReturn DefaultIOStream::Seek(size_t pOffset,
|
||||||
aiOrigin_END == SEEK_END && aiOrigin_SET == SEEK_SET");
|
aiOrigin_END == SEEK_END && aiOrigin_SET == SEEK_SET");
|
||||||
|
|
||||||
// do the seek
|
// do the seek
|
||||||
return (0 == ::fseek(mFile, (long)pOffset,(int)pOrigin) ? AI_SUCCESS : AI_FAILURE);
|
return (0 == select_fseek<sizeof(void*)>(mFile, (int64_t)pOffset,(int)pOrigin) ? AI_SUCCESS : AI_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
|
|
@ -102,7 +131,7 @@ size_t DefaultIOStream::Tell() const
|
||||||
if (!mFile) {
|
if (!mFile) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return ::ftell(mFile);
|
return select_ftell<sizeof(void*)>(mFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
|
|
@ -61,83 +61,66 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
// maximum path length
|
#ifdef _WIN32
|
||||||
// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
|
static std::wstring Utf8ToWide(const char* in)
|
||||||
#ifdef PATH_MAX
|
{
|
||||||
# define PATHLIMIT PATH_MAX
|
int size = MultiByteToWideChar(CP_UTF8, 0, in, -1, nullptr, 0);
|
||||||
#else
|
// size includes terminating null; std::wstring adds null automatically
|
||||||
# define PATHLIMIT 4096
|
std::wstring out(static_cast<size_t>(size) - 1, L'\0');
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, in, -1, &out[0], size);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string WideToUtf8(const wchar_t* in)
|
||||||
|
{
|
||||||
|
int size = WideCharToMultiByte(CP_UTF8, 0, in, -1, nullptr, 0, nullptr, nullptr);
|
||||||
|
// size includes terminating null; std::string adds null automatically
|
||||||
|
std::string out(static_cast<size_t>(size) - 1, '\0');
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, in, -1, &out[0], size, nullptr, nullptr);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Tests for the existence of a file at the given path.
|
// Tests for the existence of a file at the given path.
|
||||||
bool DefaultIOSystem::Exists( const char* pFile) const
|
bool DefaultIOSystem::Exists(const char* pFile) const
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
wchar_t fileName16[PATHLIMIT];
|
struct __stat64 filestat;
|
||||||
|
if (_wstat64(Utf8ToWide(pFile).c_str(), &filestat) != 0) {
|
||||||
#ifndef WindowsStore
|
return false;
|
||||||
bool isUnicode = IsTextUnicode(pFile, static_cast<int>(strlen(pFile)), NULL) != 0;
|
|
||||||
if (isUnicode) {
|
|
||||||
|
|
||||||
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, pFile, -1, fileName16, PATHLIMIT);
|
|
||||||
struct __stat64 filestat;
|
|
||||||
if (0 != _wstat64(fileName16, &filestat)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
#endif
|
|
||||||
FILE* file = ::fopen(pFile, "rb");
|
|
||||||
if (!file)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
::fclose(file);
|
|
||||||
#ifndef WindowsStore
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
FILE* file = ::fopen( pFile, "rb");
|
FILE* file = ::fopen(pFile, "rb");
|
||||||
if( !file)
|
if (!file)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
::fclose( file);
|
::fclose(file);
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Open a new file with a given path.
|
// Open a new file with a given path.
|
||||||
IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode)
|
IOStream* DefaultIOSystem::Open(const char* strFile, const char* strMode)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != strFile);
|
ai_assert(strFile != nullptr);
|
||||||
ai_assert(NULL != strMode);
|
ai_assert(strMode != nullptr);
|
||||||
FILE* file;
|
FILE* file;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
wchar_t fileName16[PATHLIMIT];
|
file = ::_wfopen(Utf8ToWide(strFile).c_str(), Utf8ToWide(strMode).c_str());
|
||||||
#ifndef WindowsStore
|
|
||||||
bool isUnicode = IsTextUnicode(strFile, static_cast<int>(strlen(strFile)), NULL) != 0;
|
|
||||||
if (isUnicode) {
|
|
||||||
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, strFile, -1, fileName16, PATHLIMIT);
|
|
||||||
std::string mode8(strMode);
|
|
||||||
file = ::_wfopen(fileName16, std::wstring(mode8.begin(), mode8.end()).c_str());
|
|
||||||
} else {
|
|
||||||
#endif
|
|
||||||
file = ::fopen(strFile, strMode);
|
|
||||||
#ifndef WindowsStore
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
file = ::fopen(strFile, strMode);
|
file = ::fopen(strFile, strMode);
|
||||||
#endif
|
#endif
|
||||||
if (nullptr == file)
|
if (!file)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return new DefaultIOStream(file, (std::string) strFile);
|
return new DefaultIOStream(file, strFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Closes the given file and releases all resources associated with it.
|
// Closes the given file and releases all resources associated with it.
|
||||||
void DefaultIOSystem::Close( IOStream* pFile)
|
void DefaultIOSystem::Close(IOStream* pFile)
|
||||||
{
|
{
|
||||||
delete pFile;
|
delete pFile;
|
||||||
}
|
}
|
||||||
|
|
@ -155,78 +138,56 @@ char DefaultIOSystem::getOsSeparator() const
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// IOSystem default implementation (ComparePaths isn't a pure virtual function)
|
// IOSystem default implementation (ComparePaths isn't a pure virtual function)
|
||||||
bool IOSystem::ComparePaths (const char* one, const char* second) const
|
bool IOSystem::ComparePaths(const char* one, const char* second) const
|
||||||
{
|
{
|
||||||
return !ASSIMP_stricmp(one,second);
|
return !ASSIMP_stricmp(one, second);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Convert a relative path into an absolute path
|
// Convert a relative path into an absolute path
|
||||||
inline static void MakeAbsolutePath (const char* in, char* _out)
|
inline static std::string MakeAbsolutePath(const char* in)
|
||||||
{
|
{
|
||||||
ai_assert(in && _out);
|
ai_assert(in);
|
||||||
#if defined( _MSC_VER ) || defined( __MINGW32__ )
|
std::string out;
|
||||||
#ifndef WindowsStore
|
#ifdef _WIN32
|
||||||
bool isUnicode = IsTextUnicode(in, static_cast<int>(strlen(in)), NULL) != 0;
|
wchar_t* ret = ::_wfullpath(nullptr, Utf8ToWide(in).c_str(), 0);
|
||||||
if (isUnicode) {
|
if (ret) {
|
||||||
wchar_t out16[PATHLIMIT];
|
out = WideToUtf8(ret);
|
||||||
wchar_t in16[PATHLIMIT];
|
free(ret);
|
||||||
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, in, -1, out16, PATHLIMIT);
|
}
|
||||||
wchar_t* ret = ::_wfullpath(out16, in16, PATHLIMIT);
|
#else
|
||||||
if (ret) {
|
char* ret = realpath(in, nullptr);
|
||||||
WideCharToMultiByte(CP_UTF8, MB_PRECOMPOSED, out16, -1, _out, PATHLIMIT, nullptr, nullptr);
|
if (ret) {
|
||||||
}
|
out = ret;
|
||||||
if (!ret) {
|
free(ret);
|
||||||
// preserve the input path, maybe someone else is able to fix
|
|
||||||
// the path before it is accessed (e.g. our file system filter)
|
|
||||||
ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
|
|
||||||
strcpy(_out, in);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
#endif
|
|
||||||
char* ret = :: _fullpath(_out, in, PATHLIMIT);
|
|
||||||
if (!ret) {
|
|
||||||
// preserve the input path, maybe someone else is able to fix
|
|
||||||
// the path before it is accessed (e.g. our file system filter)
|
|
||||||
ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
|
|
||||||
strcpy(_out, in);
|
|
||||||
}
|
|
||||||
#ifndef WindowsStore
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#else
|
if (!ret) {
|
||||||
// use realpath
|
|
||||||
char* ret = realpath(in, _out);
|
|
||||||
if(!ret) {
|
|
||||||
// preserve the input path, maybe someone else is able to fix
|
// preserve the input path, maybe someone else is able to fix
|
||||||
// the path before it is accessed (e.g. our file system filter)
|
// the path before it is accessed (e.g. our file system filter)
|
||||||
ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
|
ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
|
||||||
strcpy(_out,in);
|
out = in;
|
||||||
}
|
}
|
||||||
#endif
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// DefaultIOSystem's more specialized implementation
|
// DefaultIOSystem's more specialized implementation
|
||||||
bool DefaultIOSystem::ComparePaths (const char* one, const char* second) const
|
bool DefaultIOSystem::ComparePaths(const char* one, const char* second) const
|
||||||
{
|
{
|
||||||
// chances are quite good both paths are formatted identically,
|
// chances are quite good both paths are formatted identically,
|
||||||
// so we can hopefully return here already
|
// so we can hopefully return here already
|
||||||
if( !ASSIMP_stricmp(one,second) )
|
if (!ASSIMP_stricmp(one, second))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
char temp1[PATHLIMIT];
|
std::string temp1 = MakeAbsolutePath(one);
|
||||||
char temp2[PATHLIMIT];
|
std::string temp2 = MakeAbsolutePath(second);
|
||||||
|
|
||||||
MakeAbsolutePath (one, temp1);
|
return !ASSIMP_stricmp(temp1, temp2);
|
||||||
MakeAbsolutePath (second, temp2);
|
|
||||||
|
|
||||||
return !ASSIMP_stricmp(temp1,temp2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
std::string DefaultIOSystem::fileName( const std::string &path )
|
std::string DefaultIOSystem::fileName(const std::string& path)
|
||||||
{
|
{
|
||||||
std::string ret = path;
|
std::string ret = path;
|
||||||
std::size_t last = ret.find_last_of("\\/");
|
std::size_t last = ret.find_last_of("\\/");
|
||||||
|
|
@ -235,16 +196,16 @@ std::string DefaultIOSystem::fileName( const std::string &path )
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
std::string DefaultIOSystem::completeBaseName( const std::string &path )
|
std::string DefaultIOSystem::completeBaseName(const std::string& path)
|
||||||
{
|
{
|
||||||
std::string ret = fileName(path);
|
std::string ret = fileName(path);
|
||||||
std::size_t pos = ret.find_last_of('.');
|
std::size_t pos = ret.find_last_of('.');
|
||||||
if(pos != ret.npos) ret = ret.substr(0, pos);
|
if (pos != std::string::npos) ret = ret.substr(0, pos);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
std::string DefaultIOSystem::absolutePath( const std::string &path )
|
std::string DefaultIOSystem::absolutePath(const std::string& path)
|
||||||
{
|
{
|
||||||
std::string ret = path;
|
std::string ret = path;
|
||||||
std::size_t last = ret.find_last_of("\\/");
|
std::size_t last = ret.find_last_of("\\/");
|
||||||
|
|
@ -253,5 +214,3 @@ std::string DefaultIOSystem::absolutePath( const std::string &path )
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
#undef PATHLIMIT
|
|
||||||
|
|
@ -61,15 +61,16 @@ Here we implement only the C++ interface (Assimp::Exporter).
|
||||||
#include <assimp/mesh.h>
|
#include <assimp/mesh.h>
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
|
|
||||||
#include "DefaultProgressHandler.h"
|
|
||||||
#include "BaseProcess.h"
|
|
||||||
#include "JoinVerticesProcess.h"
|
|
||||||
#include "MakeVerboseFormat.h"
|
|
||||||
#include "ConvertToLHProcess.h"
|
|
||||||
#include "PretransformVertices.h"
|
|
||||||
#include <assimp/Exceptional.h>
|
#include <assimp/Exceptional.h>
|
||||||
#include "ScenePrivate.h"
|
|
||||||
|
#include "Common/DefaultProgressHandler.h"
|
||||||
|
#include "Common/BaseProcess.h"
|
||||||
|
#include "Common/ScenePrivate.h"
|
||||||
|
#include "PostProcessing/CalcTangentsProcess.h"
|
||||||
|
#include "PostProcessing/MakeVerboseFormat.h"
|
||||||
|
#include "PostProcessing/JoinVerticesProcess.h"
|
||||||
|
#include "PostProcessing/ConvertToLHProcess.h"
|
||||||
|
#include "PostProcessing/PretransformVertices.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
|
@ -101,89 +102,92 @@ void ExportSceneX3D(const char*, IOSystem*, const aiScene*, const ExportProperti
|
||||||
void ExportSceneFBX(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneFBX(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneFBXA(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneFBXA(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportScene3MF( const char*, IOSystem*, const aiScene*, const ExportProperties* );
|
void ExportScene3MF( const char*, IOSystem*, const aiScene*, const ExportProperties* );
|
||||||
|
void ExportSceneM3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
void ExportSceneA3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
void ExportAssimp2Json(const char* , IOSystem*, const aiScene* , const Assimp::ExportProperties*);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// global array of all export formats which Assimp supports in its current build
|
static void setupExporterArray(std::vector<Exporter::ExportFormatEntry> &exporters) {
|
||||||
Exporter::ExportFormatEntry gExporters[] =
|
|
||||||
{
|
|
||||||
#ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "collada", "COLLADA - Digital Asset Exchange Schema", "dae", &ExportSceneCollada ),
|
exporters.push_back(Exporter::ExportFormatEntry("collada", "COLLADA - Digital Asset Exchange Schema", "dae", &ExportSceneCollada));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_X_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_X_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "x", "X Files", "x", &ExportSceneXFile,
|
exporters.push_back(Exporter::ExportFormatEntry("x", "X Files", "x", &ExportSceneXFile,
|
||||||
aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_FlipUVs ),
|
aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_FlipUVs));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_STEP_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_STEP_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "stp", "Step Files", "stp", &ExportSceneStep, 0 ),
|
exporters.push_back(Exporter::ExportFormatEntry("stp", "Step Files", "stp", &ExportSceneStep, 0));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "obj", "Wavefront OBJ format", "obj", &ExportSceneObj,
|
exporters.push_back(Exporter::ExportFormatEntry("obj", "Wavefront OBJ format", "obj", &ExportSceneObj,
|
||||||
aiProcess_GenSmoothNormals /*| aiProcess_PreTransformVertices */ ),
|
aiProcess_GenSmoothNormals /*| aiProcess_PreTransformVertices */));
|
||||||
Exporter::ExportFormatEntry( "objnomtl", "Wavefront OBJ format without material file", "obj", &ExportSceneObjNoMtl,
|
exporters.push_back(Exporter::ExportFormatEntry("objnomtl", "Wavefront OBJ format without material file", "obj", &ExportSceneObjNoMtl,
|
||||||
aiProcess_GenSmoothNormals /*| aiProcess_PreTransformVertices */ ),
|
aiProcess_GenSmoothNormals /*| aiProcess_PreTransformVertices */));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_STL_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_STL_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "stl", "Stereolithography", "stl" , &ExportSceneSTL,
|
exporters.push_back(Exporter::ExportFormatEntry("stl", "Stereolithography", "stl", &ExportSceneSTL,
|
||||||
aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices
|
aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices));
|
||||||
),
|
exporters.push_back(Exporter::ExportFormatEntry("stlb", "Stereolithography (binary)", "stl", &ExportSceneSTLBinary,
|
||||||
Exporter::ExportFormatEntry( "stlb", "Stereolithography (binary)", "stl" , &ExportSceneSTLBinary,
|
aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices));
|
||||||
aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices
|
|
||||||
),
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_PLY_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_PLY_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "ply", "Stanford Polygon Library", "ply" , &ExportScenePly,
|
exporters.push_back(Exporter::ExportFormatEntry("ply", "Stanford Polygon Library", "ply", &ExportScenePly,
|
||||||
aiProcess_PreTransformVertices
|
aiProcess_PreTransformVertices));
|
||||||
),
|
exporters.push_back(Exporter::ExportFormatEntry("plyb", "Stanford Polygon Library (binary)", "ply", &ExportScenePlyBinary,
|
||||||
Exporter::ExportFormatEntry( "plyb", "Stanford Polygon Library (binary)", "ply", &ExportScenePlyBinary,
|
aiProcess_PreTransformVertices));
|
||||||
aiProcess_PreTransformVertices
|
|
||||||
),
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "3ds", "Autodesk 3DS (legacy)", "3ds" , &ExportScene3DS,
|
exporters.push_back(Exporter::ExportFormatEntry("3ds", "Autodesk 3DS (legacy)", "3ds", &ExportScene3DS,
|
||||||
aiProcess_Triangulate | aiProcess_SortByPType | aiProcess_JoinIdenticalVertices ),
|
aiProcess_Triangulate | aiProcess_SortByPType | aiProcess_JoinIdenticalVertices));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "gltf2", "GL Transmission Format v. 2", "gltf", &ExportSceneGLTF2,
|
exporters.push_back(Exporter::ExportFormatEntry("gltf2", "GL Transmission Format v. 2", "gltf", &ExportSceneGLTF2,
|
||||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType));
|
||||||
Exporter::ExportFormatEntry( "glb2", "GL Transmission Format v. 2 (binary)", "glb", &ExportSceneGLB2,
|
exporters.push_back(Exporter::ExportFormatEntry("glb2", "GL Transmission Format v. 2 (binary)", "glb", &ExportSceneGLB2,
|
||||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType));
|
||||||
Exporter::ExportFormatEntry( "gltf", "GL Transmission Format", "gltf", &ExportSceneGLTF,
|
exporters.push_back(Exporter::ExportFormatEntry("gltf", "GL Transmission Format", "gltf", &ExportSceneGLTF,
|
||||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType));
|
||||||
Exporter::ExportFormatEntry( "glb", "GL Transmission Format (binary)", "glb", &ExportSceneGLB,
|
exporters.push_back(Exporter::ExportFormatEntry("glb", "GL Transmission Format (binary)", "glb", &ExportSceneGLB,
|
||||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "assbin", "Assimp Binary", "assbin" , &ExportSceneAssbin, 0 ),
|
exporters.push_back(Exporter::ExportFormatEntry("assbin", "Assimp Binary File", "assbin", &ExportSceneAssbin, 0));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "assxml", "Assxml Document", "assxml" , &ExportSceneAssxml, 0 ),
|
exporters.push_back(Exporter::ExportFormatEntry("assxml", "Assimp XML Document", "assxml", &ExportSceneAssxml, 0));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_X3D_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_X3D_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "x3d", "Extensible 3D", "x3d" , &ExportSceneX3D, 0 ),
|
exporters.push_back(Exporter::ExportFormatEntry("x3d", "Extensible 3D", "x3d", &ExportSceneX3D, 0));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "fbx", "Autodesk FBX (binary)", "fbx", &ExportSceneFBX, 0 ),
|
exporters.push_back(Exporter::ExportFormatEntry("fbx", "Autodesk FBX (binary)", "fbx", &ExportSceneFBX, 0));
|
||||||
Exporter::ExportFormatEntry( "fbxa", "Autodesk FBX (ascii)", "fbx", &ExportSceneFBXA, 0 ),
|
exporters.push_back(Exporter::ExportFormatEntry("fbxa", "Autodesk FBX (ascii)", "fbx", &ExportSceneFBXA, 0));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_M3D_EXPORTER
|
||||||
|
exporters.push_back(Exporter::ExportFormatEntry("m3d", "Model 3D (binary)", "m3d", &ExportSceneM3D, 0));
|
||||||
|
exporters.push_back(Exporter::ExportFormatEntry("a3d", "Model 3D (ascii)", "m3d", &ExportSceneA3D, 0));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "3mf", "The 3MF-File-Format", "3mf", &ExportScene3MF, 0 )
|
exporters.push_back(Exporter::ExportFormatEntry("3mf", "The 3MF-File-Format", "3mf", &ExportScene3MF, 0));
|
||||||
#endif
|
#endif
|
||||||
};
|
|
||||||
|
|
||||||
#define ASSIMP_NUM_EXPORTERS (sizeof(gExporters)/sizeof(gExporters[0]))
|
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_ASSJSON_EXPORTER
|
||||||
|
exporters.push_back(Exporter::ExportFormatEntry("assjson", "Assimp JSON Document", "json", &ExportAssimp2Json, 0));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
class ExporterPimpl {
|
class ExporterPimpl {
|
||||||
public:
|
public:
|
||||||
|
|
@ -199,10 +203,7 @@ public:
|
||||||
GetPostProcessingStepInstanceList(mPostProcessingSteps);
|
GetPostProcessingStepInstanceList(mPostProcessingSteps);
|
||||||
|
|
||||||
// grab all built-in exporters
|
// grab all built-in exporters
|
||||||
if ( 0 != ( ASSIMP_NUM_EXPORTERS ) ) {
|
setupExporterArray(mExporters);
|
||||||
mExporters.resize( ASSIMP_NUM_EXPORTERS );
|
|
||||||
std::copy( gExporters, gExporters + ASSIMP_NUM_EXPORTERS, mExporters.begin() );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~ExporterPimpl() {
|
~ExporterPimpl() {
|
||||||
|
|
@ -246,24 +247,28 @@ Exporter :: Exporter()
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Exporter::~Exporter() {
|
Exporter::~Exporter() {
|
||||||
FreeBlob();
|
ai_assert(nullptr != pimpl);
|
||||||
|
FreeBlob();
|
||||||
delete pimpl;
|
delete pimpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Exporter::SetIOHandler( IOSystem* pIOHandler) {
|
void Exporter::SetIOHandler( IOSystem* pIOHandler) {
|
||||||
pimpl->mIsDefaultIOHandler = !pIOHandler;
|
ai_assert(nullptr != pimpl);
|
||||||
|
pimpl->mIsDefaultIOHandler = !pIOHandler;
|
||||||
pimpl->mIOSystem.reset(pIOHandler);
|
pimpl->mIOSystem.reset(pIOHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
IOSystem* Exporter::GetIOHandler() const {
|
IOSystem* Exporter::GetIOHandler() const {
|
||||||
return pimpl->mIOSystem.get();
|
ai_assert(nullptr != pimpl);
|
||||||
|
return pimpl->mIOSystem.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool Exporter::IsDefaultIOHandler() const {
|
bool Exporter::IsDefaultIOHandler() const {
|
||||||
return pimpl->mIsDefaultIOHandler;
|
ai_assert(nullptr != pimpl);
|
||||||
|
return pimpl->mIsDefaultIOHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
@ -288,7 +293,8 @@ void Exporter::SetProgressHandler(ProgressHandler* pHandler) {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const char* pFormatId,
|
const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const char* pFormatId,
|
||||||
unsigned int, const ExportProperties* /*pProperties*/ ) {
|
unsigned int pPreprocessing, const ExportProperties* pProperties) {
|
||||||
|
ai_assert(nullptr != pimpl);
|
||||||
if (pimpl->blob) {
|
if (pimpl->blob) {
|
||||||
delete pimpl->blob;
|
delete pimpl->blob;
|
||||||
pimpl->blob = nullptr;
|
pimpl->blob = nullptr;
|
||||||
|
|
@ -298,7 +304,7 @@ const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const cha
|
||||||
BlobIOSystem* blobio = new BlobIOSystem();
|
BlobIOSystem* blobio = new BlobIOSystem();
|
||||||
pimpl->mIOSystem = std::shared_ptr<IOSystem>( blobio );
|
pimpl->mIOSystem = std::shared_ptr<IOSystem>( blobio );
|
||||||
|
|
||||||
if (AI_SUCCESS != Export(pScene,pFormatId,blobio->GetMagicFileName())) {
|
if (AI_SUCCESS != Export(pScene,pFormatId,blobio->GetMagicFileName(), pPreprocessing, pProperties)) {
|
||||||
pimpl->mIOSystem = old;
|
pimpl->mIOSystem = old;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
@ -309,44 +315,16 @@ const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const cha
|
||||||
return pimpl->blob;
|
return pimpl->blob;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
bool IsVerboseFormat(const aiMesh* mesh) {
|
|
||||||
// avoid slow vector<bool> specialization
|
|
||||||
std::vector<unsigned int> seen(mesh->mNumVertices,0);
|
|
||||||
for(unsigned int i = 0; i < mesh->mNumFaces; ++i) {
|
|
||||||
const aiFace& f = mesh->mFaces[i];
|
|
||||||
for(unsigned int j = 0; j < f.mNumIndices; ++j) {
|
|
||||||
if(++seen[f.mIndices[j]] == 2) {
|
|
||||||
// found a duplicate index
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
bool IsVerboseFormat(const aiScene* pScene) {
|
|
||||||
for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
|
||||||
if(!IsVerboseFormat(pScene->mMeshes[i])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const char* pPath,
|
aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const char* pPath,
|
||||||
unsigned int pPreprocessing, const ExportProperties* pProperties) {
|
unsigned int pPreprocessing, const ExportProperties* pProperties) {
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
|
ai_assert(nullptr != pimpl);
|
||||||
// when they create scenes from scratch, users will likely create them not in verbose
|
// when they create scenes from scratch, users will likely create them not in verbose
|
||||||
// format. They will likely not be aware that there is a flag in the scene to indicate
|
// format. They will likely not be aware that there is a flag in the scene to indicate
|
||||||
// this, however. To avoid surprises and bug reports, we check for duplicates in
|
// this, however. To avoid surprises and bug reports, we check for duplicates in
|
||||||
// meshes upfront.
|
// meshes upfront.
|
||||||
const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || IsVerboseFormat(pScene);
|
const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || MakeVerboseFormatProcess::IsVerboseFormat(pScene);
|
||||||
|
|
||||||
pimpl->mProgressHandler->UpdateFileWrite(0, 4);
|
pimpl->mProgressHandler->UpdateFileWrite(0, 4);
|
||||||
|
|
||||||
|
|
@ -466,7 +444,10 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
|
||||||
}
|
}
|
||||||
|
|
||||||
ExportProperties emptyProperties; // Never pass NULL ExportProperties so Exporters don't have to worry.
|
ExportProperties emptyProperties; // Never pass NULL ExportProperties so Exporters don't have to worry.
|
||||||
exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProperties ? pProperties : &emptyProperties);
|
ExportProperties* pProp = pProperties ? (ExportProperties*)pProperties : &emptyProperties;
|
||||||
|
pProp->SetPropertyBool("bJoinIdenticalVertices", must_join_again);
|
||||||
|
exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProp);
|
||||||
|
exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProp);
|
||||||
|
|
||||||
pimpl->mProgressHandler->UpdateFileWrite(4, 4);
|
pimpl->mProgressHandler->UpdateFileWrite(4, 4);
|
||||||
} catch (DeadlyExportError& err) {
|
} catch (DeadlyExportError& err) {
|
||||||
|
|
@ -485,11 +466,13 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const char* Exporter::GetErrorString() const {
|
const char* Exporter::GetErrorString() const {
|
||||||
|
ai_assert(nullptr != pimpl);
|
||||||
return pimpl->mError.c_str();
|
return pimpl->mError.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Exporter::FreeBlob() {
|
void Exporter::FreeBlob() {
|
||||||
|
ai_assert(nullptr != pimpl);
|
||||||
delete pimpl->blob;
|
delete pimpl->blob;
|
||||||
pimpl->blob = nullptr;
|
pimpl->blob = nullptr;
|
||||||
|
|
||||||
|
|
@ -498,30 +481,34 @@ void Exporter::FreeBlob() {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const aiExportDataBlob* Exporter::GetBlob() const {
|
const aiExportDataBlob* Exporter::GetBlob() const {
|
||||||
return pimpl->blob;
|
ai_assert(nullptr != pimpl);
|
||||||
|
return pimpl->blob;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const aiExportDataBlob* Exporter::GetOrphanedBlob() const {
|
const aiExportDataBlob* Exporter::GetOrphanedBlob() const {
|
||||||
const aiExportDataBlob* tmp = pimpl->blob;
|
ai_assert(nullptr != pimpl);
|
||||||
|
const aiExportDataBlob *tmp = pimpl->blob;
|
||||||
pimpl->blob = nullptr;
|
pimpl->blob = nullptr;
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
size_t Exporter::GetExportFormatCount() const {
|
size_t Exporter::GetExportFormatCount() const {
|
||||||
|
ai_assert(nullptr != pimpl);
|
||||||
return pimpl->mExporters.size();
|
return pimpl->mExporters.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const aiExportFormatDesc* Exporter::GetExportFormatDescription( size_t index ) const {
|
const aiExportFormatDesc* Exporter::GetExportFormatDescription( size_t index ) const {
|
||||||
if (index >= GetExportFormatCount()) {
|
ai_assert(nullptr != pimpl);
|
||||||
|
if (index >= GetExportFormatCount()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return from static storage if the requested index is built-in.
|
// Return from static storage if the requested index is built-in.
|
||||||
if (index < sizeof(gExporters) / sizeof(gExporters[0])) {
|
if (index < pimpl->mExporters.size()) {
|
||||||
return &gExporters[index].mDescription;
|
return &pimpl->mExporters[index].mDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &pimpl->mExporters[index].mDescription;
|
return &pimpl->mExporters[index].mDescription;
|
||||||
|
|
@ -529,7 +516,8 @@ const aiExportFormatDesc* Exporter::GetExportFormatDescription( size_t index ) c
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiReturn Exporter::RegisterExporter(const ExportFormatEntry& desc) {
|
aiReturn Exporter::RegisterExporter(const ExportFormatEntry& desc) {
|
||||||
for(const ExportFormatEntry& e : pimpl->mExporters) {
|
ai_assert(nullptr != pimpl);
|
||||||
|
for (const ExportFormatEntry &e : pimpl->mExporters) {
|
||||||
if (!strcmp(e.mDescription.id,desc.mDescription.id)) {
|
if (!strcmp(e.mDescription.id,desc.mDescription.id)) {
|
||||||
return aiReturn_FAILURE;
|
return aiReturn_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
@ -541,7 +529,8 @@ aiReturn Exporter::RegisterExporter(const ExportFormatEntry& desc) {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Exporter::UnregisterExporter(const char* id) {
|
void Exporter::UnregisterExporter(const char* id) {
|
||||||
for(std::vector<ExportFormatEntry>::iterator it = pimpl->mExporters.begin();
|
ai_assert(nullptr != pimpl);
|
||||||
|
for (std::vector<ExportFormatEntry>::iterator it = pimpl->mExporters.begin();
|
||||||
it != pimpl->mExporters.end(); ++it) {
|
it != pimpl->mExporters.end(); ++it) {
|
||||||
if (!strcmp((*it).mDescription.id,id)) {
|
if (!strcmp((*it).mDescription.id,id)) {
|
||||||
pimpl->mExporters.erase(it);
|
pimpl->mExporters.erase(it);
|
||||||
|
|
@ -64,15 +64,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Internal headers
|
// Internal headers
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
#include "Importer.h"
|
#include "Common/Importer.h"
|
||||||
#include <assimp/BaseImporter.h>
|
#include "Common/BaseProcess.h"
|
||||||
#include "BaseProcess.h"
|
#include "Common/DefaultProgressHandler.h"
|
||||||
|
#include "PostProcessing/ProcessHelper.h"
|
||||||
|
#include "Common/ScenePreprocessor.h"
|
||||||
|
#include "Common/ScenePrivate.h"
|
||||||
|
|
||||||
#include "DefaultProgressHandler.h"
|
#include <assimp/BaseImporter.h>
|
||||||
#include <assimp/GenericProperty.h>
|
#include <assimp/GenericProperty.h>
|
||||||
#include "ProcessHelper.h"
|
|
||||||
#include "ScenePreprocessor.h"
|
|
||||||
#include "ScenePrivate.h"
|
|
||||||
#include <assimp/MemoryIOWrapper.h>
|
#include <assimp/MemoryIOWrapper.h>
|
||||||
#include <assimp/Profiler.h>
|
#include <assimp/Profiler.h>
|
||||||
#include <assimp/TinyFormatter.h>
|
#include <assimp/TinyFormatter.h>
|
||||||
|
|
@ -86,7 +86,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/DefaultIOSystem.h>
|
#include <assimp/DefaultIOSystem.h>
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
|
#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
|
||||||
# include "ValidateDataStructure.h"
|
# include "PostProcessing/ValidateDataStructure.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace Assimp::Profiling;
|
using namespace Assimp::Profiling;
|
||||||
|
|
@ -590,10 +590,12 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)
|
||||||
|
|
||||||
// Find an worker class which can handle the file
|
// Find an worker class which can handle the file
|
||||||
BaseImporter* imp = NULL;
|
BaseImporter* imp = NULL;
|
||||||
|
SetPropertyInteger("importerIndex", -1);
|
||||||
for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) {
|
for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) {
|
||||||
|
|
||||||
if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, false)) {
|
if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, false)) {
|
||||||
imp = pimpl->mImporter[a];
|
imp = pimpl->mImporter[a];
|
||||||
|
SetPropertyInteger("importerIndex", a);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -606,6 +608,7 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)
|
||||||
for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) {
|
for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) {
|
||||||
if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, true)) {
|
if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, true)) {
|
||||||
imp = pimpl->mImporter[a];
|
imp = pimpl->mImporter[a];
|
||||||
|
SetPropertyInteger("importerIndex", a);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -56,146 +56,149 @@ corresponding preprocessor flag to selectively disable formats.
|
||||||
// (include_new_importers_here)
|
// (include_new_importers_here)
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
#ifndef ASSIMP_BUILD_NO_X_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_X_IMPORTER
|
||||||
# include "XFileImporter.h"
|
# include "X/XFileImporter.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
|
||||||
# include "AMFImporter.hpp"
|
# include "AMF/AMFImporter.hpp"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
|
||||||
# include "3DSLoader.h"
|
# include "3DS/3DSLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_MD3_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_MD3_IMPORTER
|
||||||
# include "MD3Loader.h"
|
# include "MD3/MD3Loader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_MDL_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_MDL_IMPORTER
|
||||||
# include "MDLLoader.h"
|
# include "MDL/MDLLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_MD2_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_MD2_IMPORTER
|
||||||
# include "MD2Loader.h"
|
# include "MD2/MD2Loader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_PLY_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_PLY_IMPORTER
|
||||||
# include "PlyLoader.h"
|
# include "Ply/PlyLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
|
||||||
# include "ASELoader.h"
|
# include "ASE/ASELoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
|
||||||
# include "ObjFileImporter.h"
|
# include "Obj/ObjFileImporter.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_HMP_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_HMP_IMPORTER
|
||||||
# include "HMPLoader.h"
|
# include "HMP/HMPLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_SMD_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_SMD_IMPORTER
|
||||||
# include "SMDLoader.h"
|
# include "SMD/SMDLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_MDC_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_MDC_IMPORTER
|
||||||
# include "MDCLoader.h"
|
# include "MDC/MDCLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_MD5_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_MD5_IMPORTER
|
||||||
# include "MD5Loader.h"
|
# include "MD5/MD5Loader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_STL_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_STL_IMPORTER
|
||||||
# include "STLLoader.h"
|
# include "STL/STLLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
|
||||||
# include "LWOLoader.h"
|
# include "LWO/LWOLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_DXF_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_DXF_IMPORTER
|
||||||
# include "DXFLoader.h"
|
# include "DXF/DXFLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_NFF_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_NFF_IMPORTER
|
||||||
# include "NFFLoader.h"
|
# include "NFF/NFFLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_RAW_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_RAW_IMPORTER
|
||||||
# include "RawLoader.h"
|
# include "Raw/RawLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_SIB_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_SIB_IMPORTER
|
||||||
# include "SIBImporter.h"
|
# include "SIB/SIBImporter.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_OFF_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_OFF_IMPORTER
|
||||||
# include "OFFLoader.h"
|
# include "OFF/OFFLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_AC_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_AC_IMPORTER
|
||||||
# include "ACLoader.h"
|
# include "AC/ACLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_BVH_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_BVH_IMPORTER
|
||||||
# include "BVHLoader.h"
|
# include "BVH/BVHLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER
|
||||||
# include "IRRMeshLoader.h"
|
# include "Irr/IRRMeshLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_IRR_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_IRR_IMPORTER
|
||||||
# include "IRRLoader.h"
|
# include "Irr/IRRLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_Q3D_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_Q3D_IMPORTER
|
||||||
# include "Q3DLoader.h"
|
# include "Q3D/Q3DLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_B3D_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_B3D_IMPORTER
|
||||||
# include "B3DImporter.h"
|
# include "B3D/B3DImporter.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER
|
||||||
# include "ColladaLoader.h"
|
# include "Collada/ColladaLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_TERRAGEN_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_TERRAGEN_IMPORTER
|
||||||
# include "TerragenLoader.h"
|
# include "Terragen/TerragenLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_CSM_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_CSM_IMPORTER
|
||||||
# include "CSMLoader.h"
|
# include "CSM/CSMLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_3D_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_3D_IMPORTER
|
||||||
# include "UnrealLoader.h"
|
# include "Unreal/UnrealLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_LWS_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_LWS_IMPORTER
|
||||||
# include "LWSLoader.h"
|
# include "LWS/LWSLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
|
||||||
# include "OgreImporter.h"
|
# include "Ogre/OgreImporter.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_OPENGEX_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_OPENGEX_IMPORTER
|
||||||
# include "OpenGEXImporter.h"
|
# include "OpenGEX/OpenGEXImporter.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_MS3D_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_MS3D_IMPORTER
|
||||||
# include "MS3DLoader.h"
|
# include "MS3D/MS3DLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_COB_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_COB_IMPORTER
|
||||||
# include "COBLoader.h"
|
# include "COB/COBLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
|
||||||
# include "BlenderLoader.h"
|
# include "Blender/BlenderLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
|
||||||
# include "Q3BSPFileImporter.h"
|
# include "Q3BSP/Q3BSPFileImporter.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_NDO_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_NDO_IMPORTER
|
||||||
# include "NDOLoader.h"
|
# include "NDO/NDOLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||||
# include "Importer/IFC/IFCLoader.h"
|
# include "Importer/IFC/IFCLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_XGL_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_XGL_IMPORTER
|
||||||
# include "XGLLoader.h"
|
# include "XGL/XGLLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
|
||||||
# include "FBXImporter.h"
|
# include "FBX/FBXImporter.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
|
||||||
# include "AssbinLoader.h"
|
# include "Assbin/AssbinLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
|
||||||
# include "glTFImporter.h"
|
# include "glTF/glTFImporter.h"
|
||||||
# include "glTF2Importer.h"
|
# include "glTF2/glTF2Importer.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_C4D_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_C4D_IMPORTER
|
||||||
# include "C4DImporter.h"
|
# include "C4D/C4DImporter.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
|
||||||
# include "D3MFImporter.h"
|
# include "3MF/D3MFImporter.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
|
||||||
# include "X3DImporter.hpp"
|
# include "X3D/X3DImporter.hpp"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
|
||||||
# include "MMDImporter.h"
|
# include "MMD/MMDImporter.h"
|
||||||
|
#endif
|
||||||
|
#ifndef ASSIMP_BUILD_NO_M3D_IMPORTER
|
||||||
|
# include "M3D/M3DImporter.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
|
||||||
# include "Importer/StepFile/StepFileImporter.h"
|
# include "Importer/StepFile/StepFileImporter.h"
|
||||||
|
|
@ -223,6 +226,9 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
|
||||||
#if (!defined ASSIMP_BUILD_NO_3DS_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_3DS_IMPORTER)
|
||||||
out.push_back( new Discreet3DSImporter());
|
out.push_back( new Discreet3DSImporter());
|
||||||
#endif
|
#endif
|
||||||
|
#if (!defined ASSIMP_BUILD_NO_M3D_IMPORTER)
|
||||||
|
out.push_back( new M3DImporter());
|
||||||
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_MD3_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_MD3_IMPORTER)
|
||||||
out.push_back( new MD3Importer());
|
out.push_back( new MD3Importer());
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -364,7 +370,7 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
|
||||||
void DeleteImporterInstanceList(std::vector< BaseImporter* >& deleteList){
|
void DeleteImporterInstanceList(std::vector< BaseImporter* >& deleteList){
|
||||||
for(size_t i= 0; i<deleteList.size();++i){
|
for(size_t i= 0; i<deleteList.size();++i){
|
||||||
delete deleteList[i];
|
delete deleteList[i];
|
||||||
deleteList[i]=NULL;
|
deleteList[i]=nullptr;
|
||||||
}//for
|
}//for
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,89 +48,97 @@ directly (unless you are adding new steps), instead use the
|
||||||
corresponding preprocessor flag to selectively disable steps.
|
corresponding preprocessor flag to selectively disable steps.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ProcessHelper.h"
|
#include "PostProcessing/ProcessHelper.h"
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_CALCTANGENTS_PROCESS
|
#ifndef ASSIMP_BUILD_NO_CALCTANGENTS_PROCESS
|
||||||
# include "CalcTangentsProcess.h"
|
# include "PostProcessing/CalcTangentsProcess.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_JOINVERTICES_PROCESS
|
#ifndef ASSIMP_BUILD_NO_JOINVERTICES_PROCESS
|
||||||
# include "JoinVerticesProcess.h"
|
# include "PostProcessing/JoinVerticesProcess.h"
|
||||||
#endif
|
#endif
|
||||||
#if !(defined ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS && defined ASSIMP_BUILD_NO_FLIPUVS_PROCESS && defined ASSIMP_BUILD_NO_FLIPWINDINGORDER_PROCESS)
|
#if !(defined ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS && defined ASSIMP_BUILD_NO_FLIPUVS_PROCESS && defined ASSIMP_BUILD_NO_FLIPWINDINGORDER_PROCESS)
|
||||||
# include "ConvertToLHProcess.h"
|
# include "PostProcessing/ConvertToLHProcess.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_TRIANGULATE_PROCESS
|
#ifndef ASSIMP_BUILD_NO_TRIANGULATE_PROCESS
|
||||||
# include "TriangulateProcess.h"
|
# include "PostProcessing/TriangulateProcess.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_DROPFACENORMALS_PROCESS
|
#ifndef ASSIMP_BUILD_NO_DROPFACENORMALS_PROCESS
|
||||||
# include "DropFaceNormalsProcess.h"
|
# include "PostProcessing/DropFaceNormalsProcess.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS
|
#ifndef ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS
|
||||||
# include "GenFaceNormalsProcess.h"
|
# include "PostProcessing/GenFaceNormalsProcess.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_GENVERTEXNORMALS_PROCESS
|
#ifndef ASSIMP_BUILD_NO_GENVERTEXNORMALS_PROCESS
|
||||||
# include "GenVertexNormalsProcess.h"
|
# include "PostProcessing/GenVertexNormalsProcess.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_REMOVEVC_PROCESS
|
#ifndef ASSIMP_BUILD_NO_REMOVEVC_PROCESS
|
||||||
# include "RemoveVCProcess.h"
|
# include "PostProcessing/RemoveVCProcess.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS
|
#ifndef ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS
|
||||||
# include "SplitLargeMeshes.h"
|
# include "PostProcessing/SplitLargeMeshes.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS
|
#ifndef ASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS
|
||||||
# include "PretransformVertices.h"
|
# include "PostProcessing/PretransformVertices.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_LIMITBONEWEIGHTS_PROCESS
|
#ifndef ASSIMP_BUILD_NO_LIMITBONEWEIGHTS_PROCESS
|
||||||
# include "LimitBoneWeightsProcess.h"
|
# include "PostProcessing/LimitBoneWeightsProcess.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
|
#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
|
||||||
# include "ValidateDataStructure.h"
|
# include "PostProcessing/ValidateDataStructure.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_IMPROVECACHELOCALITY_PROCESS
|
#ifndef ASSIMP_BUILD_NO_IMPROVECACHELOCALITY_PROCESS
|
||||||
# include "ImproveCacheLocality.h"
|
# include "PostProcessing/ImproveCacheLocality.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_FIXINFACINGNORMALS_PROCESS
|
#ifndef ASSIMP_BUILD_NO_FIXINFACINGNORMALS_PROCESS
|
||||||
# include "FixNormalsStep.h"
|
# include "PostProcessing/FixNormalsStep.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_REMOVE_REDUNDANTMATERIALS_PROCESS
|
#ifndef ASSIMP_BUILD_NO_REMOVE_REDUNDANTMATERIALS_PROCESS
|
||||||
# include "RemoveRedundantMaterials.h"
|
# include "PostProcessing/RemoveRedundantMaterials.h"
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_EMBEDTEXTURES_PROCESS)
|
#if (!defined ASSIMP_BUILD_NO_EMBEDTEXTURES_PROCESS)
|
||||||
# include "EmbedTexturesProcess.h"
|
# include "PostProcessing/EmbedTexturesProcess.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS
|
#ifndef ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS
|
||||||
# include "FindInvalidDataProcess.h"
|
# include "PostProcessing/FindInvalidDataProcess.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_FINDDEGENERATES_PROCESS
|
#ifndef ASSIMP_BUILD_NO_FINDDEGENERATES_PROCESS
|
||||||
# include "FindDegenerates.h"
|
# include "PostProcessing/FindDegenerates.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_SORTBYPTYPE_PROCESS
|
#ifndef ASSIMP_BUILD_NO_SORTBYPTYPE_PROCESS
|
||||||
# include "SortByPTypeProcess.h"
|
# include "PostProcessing/SortByPTypeProcess.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_GENUVCOORDS_PROCESS
|
#ifndef ASSIMP_BUILD_NO_GENUVCOORDS_PROCESS
|
||||||
# include "ComputeUVMappingProcess.h"
|
# include "PostProcessing/ComputeUVMappingProcess.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS
|
#ifndef ASSIMP_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS
|
||||||
# include "TextureTransform.h"
|
# include "PostProcessing/TextureTransform.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_FINDINSTANCES_PROCESS
|
#ifndef ASSIMP_BUILD_NO_FINDINSTANCES_PROCESS
|
||||||
# include "FindInstancesProcess.h"
|
# include "PostProcessing/FindInstancesProcess.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS
|
#ifndef ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS
|
||||||
# include "OptimizeMeshes.h"
|
# include "PostProcessing/OptimizeMeshes.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS
|
#ifndef ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS
|
||||||
# include "OptimizeGraph.h"
|
# include "PostProcessing/OptimizeGraph.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_SPLITBYBONECOUNT_PROCESS
|
#ifndef ASSIMP_BUILD_NO_SPLITBYBONECOUNT_PROCESS
|
||||||
# include "SplitByBoneCountProcess.h"
|
# include "Common/SplitByBoneCountProcess.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_DEBONE_PROCESS
|
#ifndef ASSIMP_BUILD_NO_DEBONE_PROCESS
|
||||||
# include "DeboneProcess.h"
|
# include "PostProcessing/DeboneProcess.h"
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS)
|
#if (!defined ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS)
|
||||||
# include "ScaleProcess.h"
|
# include "PostProcessing/ScaleProcess.h"
|
||||||
#endif
|
#endif
|
||||||
|
#if (!defined ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS)
|
||||||
|
# include "PostProcessing/ArmaturePopulate.h"
|
||||||
|
#endif
|
||||||
|
#if (!defined ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS)
|
||||||
|
# include "PostProcessing/GenBoundingBoxesProcess.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
|
@ -173,6 +181,12 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out)
|
||||||
#ifndef ASSIMP_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS
|
#ifndef ASSIMP_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS
|
||||||
out.push_back( new TextureTransformStep());
|
out.push_back( new TextureTransformStep());
|
||||||
#endif
|
#endif
|
||||||
|
#if (!defined ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS)
|
||||||
|
out.push_back( new ScaleProcess());
|
||||||
|
#endif
|
||||||
|
#if (!defined ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS)
|
||||||
|
out.push_back( new ArmaturePopulate());
|
||||||
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS)
|
#if (!defined ASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS)
|
||||||
out.push_back( new PretransformVertices());
|
out.push_back( new PretransformVertices());
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -208,9 +222,6 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out)
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS)
|
#if (!defined ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS)
|
||||||
out.push_back( new GenFaceNormalsProcess());
|
out.push_back( new GenFaceNormalsProcess());
|
||||||
#endif
|
|
||||||
#if (!defined ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS)
|
|
||||||
out.push_back( new ScaleProcess());
|
|
||||||
#endif
|
#endif
|
||||||
// .........................................................................
|
// .........................................................................
|
||||||
// DON'T change the order of these five ..
|
// DON'T change the order of these five ..
|
||||||
|
|
@ -246,6 +257,9 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out)
|
||||||
#if (!defined ASSIMP_BUILD_NO_IMPROVECACHELOCALITY_PROCESS)
|
#if (!defined ASSIMP_BUILD_NO_IMPROVECACHELOCALITY_PROCESS)
|
||||||
out.push_back( new ImproveCacheLocalityProcess());
|
out.push_back( new ImproveCacheLocalityProcess());
|
||||||
#endif
|
#endif
|
||||||
|
#if (!defined ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS)
|
||||||
|
out.push_back(new GenBoundingBoxesProcess);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue