commit
03514a9237
|
@ -253,7 +253,7 @@ ELSEIF(MSVC)
|
||||||
IF(MSVC12)
|
IF(MSVC12)
|
||||||
ADD_COMPILE_OPTIONS(/wd4351)
|
ADD_COMPILE_OPTIONS(/wd4351)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
SET(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /MDd /Ob2")
|
SET(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /MDd /Ob2 /DEBUG:FULL /Zi")
|
||||||
ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
|
ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
|
||||||
IF(NOT HUNTER_ENABLED)
|
IF(NOT HUNTER_ENABLED)
|
||||||
SET(CMAKE_CXX_FLAGS "-fPIC -std=c++11 ${CMAKE_CXX_FLAGS}")
|
SET(CMAKE_CXX_FLAGS "-fPIC -std=c++11 ${CMAKE_CXX_FLAGS}")
|
||||||
|
@ -271,7 +271,7 @@ ELSEIF( CMAKE_COMPILER_IS_MINGW )
|
||||||
SET(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
|
SET(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
|
||||||
SET(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
|
SET(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -Wa,-mbig-obj ${CMAKE_CXX_FLAGS}")
|
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -Wa,-mbig-obj -O3 ${CMAKE_CXX_FLAGS}")
|
||||||
SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
|
SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
|
||||||
ADD_DEFINITIONS( -U__STRICT_ANSI__ )
|
ADD_DEFINITIONS( -U__STRICT_ANSI__ )
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -588,7 +588,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser& pParser, const Colla
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Find mesh from either meshes or morph target meshes
|
// Find mesh from either meshes or morph target meshes
|
||||||
aiMesh *ColladaLoader::findMesh(std::string meshid) {
|
aiMesh *ColladaLoader::findMesh(const std::string& meshid) {
|
||||||
for (unsigned int i = 0; i < mMeshes.size(); ++i) {
|
for (unsigned int i = 0; i < mMeshes.size(); ++i) {
|
||||||
if (std::string(mMeshes[i]->mName.data) == meshid) {
|
if (std::string(mMeshes[i]->mName.data) == meshid) {
|
||||||
return mMeshes[i];
|
return mMeshes[i];
|
||||||
|
@ -688,7 +688,7 @@ aiMesh* ColladaLoader::CreateMesh(const ColladaParser& pParser, const Collada::M
|
||||||
Collada::MorphMethod method = Collada::Normalized;
|
Collada::MorphMethod method = Collada::Normalized;
|
||||||
|
|
||||||
for (std::map<std::string, Collada::Controller>::const_iterator it = pParser.mControllerLibrary.begin();
|
for (std::map<std::string, Collada::Controller>::const_iterator it = pParser.mControllerLibrary.begin();
|
||||||
it != pParser.mControllerLibrary.end(); it++) {
|
it != pParser.mControllerLibrary.end(); ++it) {
|
||||||
const Collada::Controller &c = it->second;
|
const Collada::Controller &c = it->second;
|
||||||
const Collada::Mesh* baseMesh = pParser.ResolveLibraryReference(pParser.mMeshLibrary, c.mMeshId);
|
const Collada::Mesh* baseMesh = pParser.ResolveLibraryReference(pParser.mMeshLibrary, c.mMeshId);
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -76,9 +76,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, 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 +116,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 +133,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
|
||||||
}
|
}
|
||||||
|
@ -588,6 +609,8 @@ aiScene* BatchLoader::GetImport( unsigned int which )
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BatchLoader::LoadAll()
|
void BatchLoader::LoadAll()
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -315,34 +315,6 @@ 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) {
|
||||||
|
@ -352,7 +324,7 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
|
||||||
// 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);
|
||||||
|
|
||||||
|
@ -472,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) {
|
||||||
|
|
|
@ -1091,6 +1091,35 @@ void SceneCombiner::Copy( aiMesh** _dest, const aiMesh* src ) {
|
||||||
aiFace& f = dest->mFaces[i];
|
aiFace& f = dest->mFaces[i];
|
||||||
GetArrayCopy(f.mIndices,f.mNumIndices);
|
GetArrayCopy(f.mIndices,f.mNumIndices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make a deep copy of all blend shapes
|
||||||
|
CopyPtrArray(dest->mAnimMeshes, dest->mAnimMeshes, dest->mNumAnimMeshes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void SceneCombiner::Copy(aiAnimMesh** _dest, const aiAnimMesh* src) {
|
||||||
|
if (nullptr == _dest || nullptr == src) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
aiAnimMesh* dest = *_dest = new aiAnimMesh();
|
||||||
|
|
||||||
|
// get a flat copy
|
||||||
|
::memcpy(dest, src, sizeof(aiAnimMesh));
|
||||||
|
|
||||||
|
// and reallocate all arrays
|
||||||
|
GetArrayCopy(dest->mVertices, dest->mNumVertices);
|
||||||
|
GetArrayCopy(dest->mNormals, dest->mNumVertices);
|
||||||
|
GetArrayCopy(dest->mTangents, dest->mNumVertices);
|
||||||
|
GetArrayCopy(dest->mBitangents, dest->mNumVertices);
|
||||||
|
|
||||||
|
unsigned int n = 0;
|
||||||
|
while (dest->HasTextureCoords(n))
|
||||||
|
GetArrayCopy(dest->mTextureCoords[n++], dest->mNumVertices);
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
while (dest->HasVertexColors(n))
|
||||||
|
GetArrayCopy(dest->mColors[n++], dest->mNumVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -78,7 +78,7 @@ namespace Assimp {
|
||||||
|
|
||||||
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
|
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
|
||||||
|
|
||||||
FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit )
|
FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones )
|
||||||
: defaultMaterialIndex()
|
: defaultMaterialIndex()
|
||||||
, lights()
|
, lights()
|
||||||
, cameras()
|
, cameras()
|
||||||
|
@ -90,8 +90,7 @@ namespace Assimp {
|
||||||
, mNodeNames()
|
, mNodeNames()
|
||||||
, anim_fps()
|
, anim_fps()
|
||||||
, out(out)
|
, out(out)
|
||||||
, doc(doc)
|
, doc(doc) {
|
||||||
, mCurrentUnit(FbxUnit::cm) {
|
|
||||||
// animations need to be converted first since this will
|
// animations need to be converted first since this will
|
||||||
// populate the node_anim_chain_bits map, which is needed
|
// populate the node_anim_chain_bits map, which is needed
|
||||||
// to determine which nodes need to be generated.
|
// to determine which nodes need to be generated.
|
||||||
|
@ -119,7 +118,6 @@ namespace Assimp {
|
||||||
|
|
||||||
ConvertGlobalSettings();
|
ConvertGlobalSettings();
|
||||||
TransferDataToScene();
|
TransferDataToScene();
|
||||||
ConvertToUnitScale(unit);
|
|
||||||
|
|
||||||
// if we didn't read any meshes set the AI_SCENE_FLAGS_INCOMPLETE
|
// if we didn't read any meshes set the AI_SCENE_FLAGS_INCOMPLETE
|
||||||
// to make sure the scene passes assimp's validation. FBX files
|
// to make sure the scene passes assimp's validation. FBX files
|
||||||
|
@ -3537,46 +3535,6 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
|
||||||
out->mMetaData->Set(14, "CustomFrameRate", doc.GlobalSettings().CustomFrameRate());
|
out->mMetaData->Set(14, "CustomFrameRate", doc.GlobalSettings().CustomFrameRate());
|
||||||
}
|
}
|
||||||
|
|
||||||
void FBXConverter::ConvertToUnitScale( FbxUnit unit ) {
|
|
||||||
if (mCurrentUnit == unit) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ai_real scale = 1.0;
|
|
||||||
if (mCurrentUnit == FbxUnit::cm) {
|
|
||||||
if (unit == FbxUnit::m) {
|
|
||||||
scale = (ai_real)0.01;
|
|
||||||
} else if (unit == FbxUnit::km) {
|
|
||||||
scale = (ai_real)0.00001;
|
|
||||||
}
|
|
||||||
} else if (mCurrentUnit == FbxUnit::m) {
|
|
||||||
if (unit == FbxUnit::cm) {
|
|
||||||
scale = (ai_real)100.0;
|
|
||||||
} else if (unit == FbxUnit::km) {
|
|
||||||
scale = (ai_real)0.001;
|
|
||||||
}
|
|
||||||
} else if (mCurrentUnit == FbxUnit::km) {
|
|
||||||
if (unit == FbxUnit::cm) {
|
|
||||||
scale = (ai_real)100000.0;
|
|
||||||
} else if (unit == FbxUnit::m) {
|
|
||||||
scale = (ai_real)1000.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto mesh : meshes) {
|
|
||||||
if (nullptr == mesh) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mesh->HasPositions()) {
|
|
||||||
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
|
||||||
aiVector3D &pos = mesh->mVertices[i];
|
|
||||||
pos *= scale;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FBXConverter::TransferDataToScene()
|
void FBXConverter::TransferDataToScene()
|
||||||
{
|
{
|
||||||
ai_assert(!out->mMeshes);
|
ai_assert(!out->mMeshes);
|
||||||
|
@ -3630,9 +3588,9 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit)
|
void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones)
|
||||||
{
|
{
|
||||||
FBXConverter converter(out, doc, removeEmptyBones, unit);
|
FBXConverter converter(out, doc, removeEmptyBones);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // !FBX
|
} // !FBX
|
||||||
|
|
|
@ -76,23 +76,13 @@ namespace Assimp {
|
||||||
namespace FBX {
|
namespace FBX {
|
||||||
|
|
||||||
class Document;
|
class Document;
|
||||||
|
|
||||||
enum class FbxUnit {
|
|
||||||
cm = 0,
|
|
||||||
m,
|
|
||||||
km,
|
|
||||||
NumUnits,
|
|
||||||
|
|
||||||
Undefined
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a FBX #Document to #aiScene
|
* Convert a FBX #Document to #aiScene
|
||||||
* @param out Empty scene to be populated
|
* @param out Empty scene to be populated
|
||||||
* @param doc Parsed FBX document
|
* @param doc Parsed FBX document
|
||||||
* @param removeEmptyBones Will remove bones, which do not have any references to vertices.
|
* @param removeEmptyBones Will remove bones, which do not have any references to vertices.
|
||||||
*/
|
*/
|
||||||
void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit);
|
void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones);
|
||||||
|
|
||||||
/** Dummy class to encapsulate the conversion process */
|
/** Dummy class to encapsulate the conversion process */
|
||||||
class FBXConverter {
|
class FBXConverter {
|
||||||
|
@ -123,7 +113,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit);
|
FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones);
|
||||||
~FBXConverter();
|
~FBXConverter();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -430,10 +420,6 @@ private:
|
||||||
|
|
||||||
void ConvertGlobalSettings();
|
void ConvertGlobalSettings();
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Will perform the conversion from a given unit to the requested unit.
|
|
||||||
void ConvertToUnitScale(FbxUnit unit);
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// copy generated meshes, animations, lights, cameras and textures to the output scene
|
// copy generated meshes, animations, lights, cameras and textures to the output scene
|
||||||
void TransferDataToScene();
|
void TransferDataToScene();
|
||||||
|
@ -470,7 +456,6 @@ private:
|
||||||
|
|
||||||
aiScene* const out;
|
aiScene* const out;
|
||||||
const FBX::Document& doc;
|
const FBX::Document& doc;
|
||||||
FbxUnit mCurrentUnit;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
// RESOURCES:
|
// RESOURCES:
|
||||||
// https://code.blender.org/2013/08/fbx-binary-file-format-specification/
|
// https://code.blender.org/2013/08/fbx-binary-file-format-specification/
|
||||||
|
@ -1005,6 +1006,9 @@ void FBXExporter::WriteObjects ()
|
||||||
object_node.EndProperties(outstream, binary, indent);
|
object_node.EndProperties(outstream, binary, indent);
|
||||||
object_node.BeginChildren(outstream, binary, indent);
|
object_node.BeginChildren(outstream, binary, indent);
|
||||||
|
|
||||||
|
bool bJoinIdenticalVertices = mProperties->GetPropertyBool("bJoinIdenticalVertices", true);
|
||||||
|
std::vector<std::vector<int32_t>> vVertexIndice;//save vertex_indices as it is needed later
|
||||||
|
|
||||||
// geometry (aiMesh)
|
// geometry (aiMesh)
|
||||||
mesh_uids.clear();
|
mesh_uids.clear();
|
||||||
indent = 1;
|
indent = 1;
|
||||||
|
@ -1031,21 +1035,35 @@ void FBXExporter::WriteObjects ()
|
||||||
std::vector<int32_t> vertex_indices;
|
std::vector<int32_t> vertex_indices;
|
||||||
// map of vertex value to its index in the data vector
|
// map of vertex value to its index in the data vector
|
||||||
std::map<aiVector3D,size_t> index_by_vertex_value;
|
std::map<aiVector3D,size_t> index_by_vertex_value;
|
||||||
int32_t index = 0;
|
if(bJoinIdenticalVertices){
|
||||||
for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
|
int32_t index = 0;
|
||||||
aiVector3D vtx = m->mVertices[vi];
|
for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
|
||||||
auto elem = index_by_vertex_value.find(vtx);
|
aiVector3D vtx = m->mVertices[vi];
|
||||||
if (elem == index_by_vertex_value.end()) {
|
auto elem = index_by_vertex_value.find(vtx);
|
||||||
vertex_indices.push_back(index);
|
if (elem == index_by_vertex_value.end()) {
|
||||||
index_by_vertex_value[vtx] = index;
|
vertex_indices.push_back(index);
|
||||||
flattened_vertices.push_back(vtx[0]);
|
index_by_vertex_value[vtx] = index;
|
||||||
flattened_vertices.push_back(vtx[1]);
|
flattened_vertices.push_back(vtx[0]);
|
||||||
flattened_vertices.push_back(vtx[2]);
|
flattened_vertices.push_back(vtx[1]);
|
||||||
++index;
|
flattened_vertices.push_back(vtx[2]);
|
||||||
} else {
|
++index;
|
||||||
vertex_indices.push_back(int32_t(elem->second));
|
} else {
|
||||||
|
vertex_indices.push_back(int32_t(elem->second));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else { // do not join vertex, respect the export flag
|
||||||
|
vertex_indices.resize(m->mNumVertices);
|
||||||
|
std::iota(vertex_indices.begin(), vertex_indices.end(), 0);
|
||||||
|
for(unsigned int v = 0; v < m->mNumVertices; ++ v) {
|
||||||
|
aiVector3D vtx = m->mVertices[v];
|
||||||
|
flattened_vertices.push_back(vtx.x);
|
||||||
|
flattened_vertices.push_back(vtx.y);
|
||||||
|
flattened_vertices.push_back(vtx.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vVertexIndice.push_back(vertex_indices);
|
||||||
|
|
||||||
FBX::Node::WritePropertyNode(
|
FBX::Node::WritePropertyNode(
|
||||||
"Vertices", flattened_vertices, outstream, binary, indent
|
"Vertices", flattened_vertices, outstream, binary, indent
|
||||||
);
|
);
|
||||||
|
@ -1116,6 +1134,51 @@ void FBXExporter::WriteObjects ()
|
||||||
normals.End(outstream, binary, indent, true);
|
normals.End(outstream, binary, indent, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// colors, if any
|
||||||
|
// TODO only one color channel currently
|
||||||
|
const int32_t colorChannelIndex = 0;
|
||||||
|
if (m->HasVertexColors(colorChannelIndex)) {
|
||||||
|
FBX::Node vertexcolors("LayerElementColor", int32_t(colorChannelIndex));
|
||||||
|
vertexcolors.Begin(outstream, binary, indent);
|
||||||
|
vertexcolors.DumpProperties(outstream, binary, indent);
|
||||||
|
vertexcolors.EndProperties(outstream, binary, indent);
|
||||||
|
vertexcolors.BeginChildren(outstream, binary, indent);
|
||||||
|
indent = 3;
|
||||||
|
FBX::Node::WritePropertyNode(
|
||||||
|
"Version", int32_t(101), outstream, binary, indent
|
||||||
|
);
|
||||||
|
char layerName[8];
|
||||||
|
sprintf(layerName, "COLOR_%d", colorChannelIndex);
|
||||||
|
FBX::Node::WritePropertyNode(
|
||||||
|
"Name", (const char*)layerName, outstream, binary, indent
|
||||||
|
);
|
||||||
|
FBX::Node::WritePropertyNode(
|
||||||
|
"MappingInformationType", "ByPolygonVertex",
|
||||||
|
outstream, binary, indent
|
||||||
|
);
|
||||||
|
FBX::Node::WritePropertyNode(
|
||||||
|
"ReferenceInformationType", "Direct",
|
||||||
|
outstream, binary, indent
|
||||||
|
);
|
||||||
|
std::vector<double> color_data;
|
||||||
|
color_data.reserve(4 * polygon_data.size());
|
||||||
|
for (size_t fi = 0; fi < m->mNumFaces; ++fi) {
|
||||||
|
const aiFace &f = m->mFaces[fi];
|
||||||
|
for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) {
|
||||||
|
const aiColor4D &c = m->mColors[colorChannelIndex][f.mIndices[pvi]];
|
||||||
|
color_data.push_back(c.r);
|
||||||
|
color_data.push_back(c.g);
|
||||||
|
color_data.push_back(c.b);
|
||||||
|
color_data.push_back(c.a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FBX::Node::WritePropertyNode(
|
||||||
|
"Colors", color_data, outstream, binary, indent
|
||||||
|
);
|
||||||
|
indent = 2;
|
||||||
|
vertexcolors.End(outstream, binary, indent, true);
|
||||||
|
}
|
||||||
|
|
||||||
// uvs, if any
|
// uvs, if any
|
||||||
for (size_t uvi = 0; uvi < m->GetNumUVChannels(); ++uvi) {
|
for (size_t uvi = 0; uvi < m->GetNumUVChannels(); ++uvi) {
|
||||||
if (m->mNumUVComponents[uvi] > 2) {
|
if (m->mNumUVComponents[uvi] > 2) {
|
||||||
|
@ -1209,6 +1272,11 @@ void FBXExporter::WriteObjects ()
|
||||||
le.AddChild("Type", "LayerElementNormal");
|
le.AddChild("Type", "LayerElementNormal");
|
||||||
le.AddChild("TypedIndex", int32_t(0));
|
le.AddChild("TypedIndex", int32_t(0));
|
||||||
layer.AddChild(le);
|
layer.AddChild(le);
|
||||||
|
// TODO only 1 color channel currently
|
||||||
|
le = FBX::Node("LayerElement");
|
||||||
|
le.AddChild("Type", "LayerElementColor");
|
||||||
|
le.AddChild("TypedIndex", int32_t(0));
|
||||||
|
layer.AddChild(le);
|
||||||
le = FBX::Node("LayerElement");
|
le = FBX::Node("LayerElement");
|
||||||
le.AddChild("Type", "LayerElementMaterial");
|
le.AddChild("Type", "LayerElementMaterial");
|
||||||
le.AddChild("TypedIndex", int32_t(0));
|
le.AddChild("TypedIndex", int32_t(0));
|
||||||
|
@ -1748,28 +1816,8 @@ void FBXExporter::WriteObjects ()
|
||||||
// connect it
|
// connect it
|
||||||
connections.emplace_back("C", "OO", deformer_uid, mesh_uids[mi]);
|
connections.emplace_back("C", "OO", deformer_uid, mesh_uids[mi]);
|
||||||
|
|
||||||
// we will be indexing by vertex...
|
//computed before
|
||||||
// but there might be a different number of "vertices"
|
std::vector<int32_t>& vertex_indices = vVertexIndice[mi];
|
||||||
// between assimp and our output FBX.
|
|
||||||
// this code is cut-and-pasted from the geometry section above...
|
|
||||||
// ideally this should not be so.
|
|
||||||
// ---
|
|
||||||
// index of original vertex in vertex data vector
|
|
||||||
std::vector<int32_t> vertex_indices;
|
|
||||||
// map of vertex value to its index in the data vector
|
|
||||||
std::map<aiVector3D,size_t> index_by_vertex_value;
|
|
||||||
int32_t index = 0;
|
|
||||||
for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
|
|
||||||
aiVector3D vtx = m->mVertices[vi];
|
|
||||||
auto elem = index_by_vertex_value.find(vtx);
|
|
||||||
if (elem == index_by_vertex_value.end()) {
|
|
||||||
vertex_indices.push_back(index);
|
|
||||||
index_by_vertex_value[vtx] = index;
|
|
||||||
++index;
|
|
||||||
} else {
|
|
||||||
vertex_indices.push_back(int32_t(elem->second));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO, FIXME: this won't work if anything is not in the bind pose.
|
// TODO, FIXME: this won't work if anything is not in the bind pose.
|
||||||
// for now if such a situation is detected, we throw an exception.
|
// for now if such a situation is detected, we throw an exception.
|
||||||
|
@ -2435,7 +2483,7 @@ void FBXExporter::WriteModelNodes(
|
||||||
void FBXExporter::WriteAnimationCurveNode(
|
void FBXExporter::WriteAnimationCurveNode(
|
||||||
StreamWriterLE& outstream,
|
StreamWriterLE& outstream,
|
||||||
int64_t uid,
|
int64_t uid,
|
||||||
std::string name, // "T", "R", or "S"
|
const std::string& name, // "T", "R", or "S"
|
||||||
aiVector3D default_value,
|
aiVector3D default_value,
|
||||||
std::string property_name, // "Lcl Translation" etc
|
std::string property_name, // "Lcl Translation" etc
|
||||||
int64_t layer_uid,
|
int64_t layer_uid,
|
||||||
|
|
|
@ -156,7 +156,7 @@ namespace Assimp
|
||||||
void WriteAnimationCurveNode(
|
void WriteAnimationCurveNode(
|
||||||
StreamWriterLE& outstream,
|
StreamWriterLE& outstream,
|
||||||
int64_t uid,
|
int64_t uid,
|
||||||
std::string name, // "T", "R", or "S"
|
const std::string& name, // "T", "R", or "S"
|
||||||
aiVector3D default_value,
|
aiVector3D default_value,
|
||||||
std::string property_name, // "Lcl Translation" etc
|
std::string property_name, // "Lcl Translation" etc
|
||||||
int64_t animation_layer_uid,
|
int64_t animation_layer_uid,
|
||||||
|
|
|
@ -185,16 +185,15 @@ void FBXImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
|
||||||
// take the raw parse-tree and convert it to a FBX DOM
|
// take the raw parse-tree and convert it to a FBX DOM
|
||||||
Document doc(parser,settings);
|
Document doc(parser,settings);
|
||||||
|
|
||||||
FbxUnit unit(FbxUnit::cm);
|
|
||||||
if (settings.convertToMeters) {
|
|
||||||
unit = FbxUnit::m;
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert the FBX DOM to aiScene
|
// convert the FBX DOM to aiScene
|
||||||
ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones, unit);
|
ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones);
|
||||||
|
|
||||||
// units is relative to CM :) we need it in meters for assimp
|
// size relative to cm
|
||||||
SetFileScale( doc.GlobalSettings().UnitScaleFactor() * 0.01f);
|
float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor();
|
||||||
|
|
||||||
|
// Set FBX file scale is relative to CM must be converted to M for
|
||||||
|
// assimp universal format (M)
|
||||||
|
SetFileScale( size_relative_to_cm * 0.01f);
|
||||||
|
|
||||||
std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
|
std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,7 +128,7 @@ void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t m
|
||||||
outer_polygon_it = begin + master_bounds;
|
outer_polygon_it = begin + master_bounds;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for(iit = begin; iit != end; iit++) {
|
for(iit = begin; iit != end; ++iit) {
|
||||||
// find the polygon with the largest area and take it as the outer bound.
|
// find the polygon with the largest area and take it as the outer bound.
|
||||||
IfcVector3& n = normals[std::distance(begin,iit)];
|
IfcVector3& n = normals[std::distance(begin,iit)];
|
||||||
const IfcFloat area = n.SquareLength();
|
const IfcFloat area = n.SquareLength();
|
||||||
|
|
|
@ -244,8 +244,8 @@ void ObjFileParser::copyNextWord(char *pBuffer, size_t length) {
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
|
m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||||
if ( *m_DataIt == '\\' ) {
|
if ( *m_DataIt == '\\' ) {
|
||||||
m_DataIt++;
|
++m_DataIt;
|
||||||
m_DataIt++;
|
++m_DataIt;
|
||||||
m_DataIt = getNextWord<DataArrayIt>( m_DataIt, m_DataItEnd );
|
m_DataIt = getNextWord<DataArrayIt>( m_DataIt, m_DataItEnd );
|
||||||
}
|
}
|
||||||
while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) {
|
while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) {
|
||||||
|
|
|
@ -224,3 +224,32 @@ bool MakeVerboseFormatProcess::MakeVerboseFormat(aiMesh* pcMesh)
|
||||||
}
|
}
|
||||||
return (pcMesh->mNumVertices != iOldNumVertices);
|
return (pcMesh->mNumVertices != iOldNumVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
bool IsMeshInVerboseFormat(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 MakeVerboseFormatProcess::IsVerboseFormat(const aiScene* pScene) {
|
||||||
|
for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
||||||
|
if(!IsMeshInVerboseFormat(pScene->mMeshes[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -94,6 +94,13 @@ public:
|
||||||
* @param pScene The imported data to work at. */
|
* @param pScene The imported data to work at. */
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Checks whether the scene is already in verbose format.
|
||||||
|
* @param pScene The data to check.
|
||||||
|
* @return true if the scene is already in verbose format. */
|
||||||
|
static bool IsVerboseFormat(const aiScene* pScene);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ aiMatrix4x4 out_matr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// multiplicate all matrices in reverse order
|
// multiplicate all matrices in reverse order
|
||||||
for(std::list<aiMatrix4x4>::reverse_iterator rit = matr.rbegin(); rit != matr.rend(); rit++) out_matr = out_matr * (*rit);
|
for(std::list<aiMatrix4x4>::reverse_iterator rit = matr.rbegin(); rit != matr.rend(); ++rit) out_matr = out_matr * (*rit);
|
||||||
|
|
||||||
return out_matr;
|
return out_matr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,8 +136,8 @@ X3DImporter::~X3DImporter() {
|
||||||
void X3DImporter::Clear() {
|
void X3DImporter::Clear() {
|
||||||
NodeElement_Cur = nullptr;
|
NodeElement_Cur = nullptr;
|
||||||
// Delete all elements
|
// Delete all elements
|
||||||
if(NodeElement_List.size()) {
|
if(!NodeElement_List.empty()) {
|
||||||
for ( std::list<CX3DImporter_NodeElement*>::iterator it = NodeElement_List.begin(); it != NodeElement_List.end(); it++ ) {
|
for ( std::list<CX3DImporter_NodeElement*>::iterator it = NodeElement_List.begin(); it != NodeElement_List.end(); ++it ) {
|
||||||
delete *it;
|
delete *it;
|
||||||
}
|
}
|
||||||
NodeElement_List.clear();
|
NodeElement_List.clear();
|
||||||
|
@ -151,7 +151,7 @@ void X3DImporter::Clear() {
|
||||||
|
|
||||||
bool X3DImporter::FindNodeElement_FromRoot(const std::string& pID, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement)
|
bool X3DImporter::FindNodeElement_FromRoot(const std::string& pID, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement)
|
||||||
{
|
{
|
||||||
for(std::list<CX3DImporter_NodeElement*>::iterator it = NodeElement_List.begin(); it != NodeElement_List.end(); it++)
|
for(std::list<CX3DImporter_NodeElement*>::iterator it = NodeElement_List.begin(); it != NodeElement_List.end(); ++it)
|
||||||
{
|
{
|
||||||
if(((*it)->Type == pType) && ((*it)->ID == pID))
|
if(((*it)->Type == pType) && ((*it)->ID == pID))
|
||||||
{
|
{
|
||||||
|
@ -182,7 +182,7 @@ bool X3DImporter::FindNodeElement_FromNode(CX3DImporter_NodeElement* pStartNode,
|
||||||
}// if((pStartNode->Type() == pType) && (pStartNode->ID() == pID))
|
}// if((pStartNode->Type() == pType) && (pStartNode->ID() == pID))
|
||||||
|
|
||||||
// Check childs of pStartNode.
|
// Check childs of pStartNode.
|
||||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = pStartNode->Child.begin(); ch_it != pStartNode->Child.end(); ch_it++)
|
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = pStartNode->Child.begin(); ch_it != pStartNode->Child.end(); ++ch_it)
|
||||||
{
|
{
|
||||||
found = FindNodeElement_FromNode(*ch_it, pID, pType, pElement);
|
found = FindNodeElement_FromNode(*ch_it, pID, pType, pElement);
|
||||||
if ( found )
|
if ( found )
|
||||||
|
@ -617,7 +617,7 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrCol3f(const int pAttrIdx, std::ve
|
||||||
if(tlist.size() > 0)
|
if(tlist.size() > 0)
|
||||||
{
|
{
|
||||||
pValue.reserve(tlist.size());
|
pValue.reserve(tlist.size());
|
||||||
for(std::list<aiColor3D>::iterator it = tlist.begin(); it != tlist.end(); it++) pValue.push_back(*it);
|
for(std::list<aiColor3D>::iterator it = tlist.begin(); it != tlist.end(); ++it) pValue.push_back(*it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -647,10 +647,10 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrCol4f(const int pAttrIdx, std::ve
|
||||||
|
|
||||||
XML_ReadNode_GetAttrVal_AsListCol4f(pAttrIdx, tlist);// read as list
|
XML_ReadNode_GetAttrVal_AsListCol4f(pAttrIdx, tlist);// read as list
|
||||||
// and copy to array
|
// and copy to array
|
||||||
if(tlist.size() > 0)
|
if(!tlist.empty())
|
||||||
{
|
{
|
||||||
pValue.reserve(tlist.size());
|
pValue.reserve(tlist.size());
|
||||||
for ( std::list<aiColor4D>::iterator it = tlist.begin(); it != tlist.end(); it++ )
|
for ( std::list<aiColor4D>::iterator it = tlist.begin(); it != tlist.end(); ++it )
|
||||||
{
|
{
|
||||||
pValue.push_back( *it );
|
pValue.push_back( *it );
|
||||||
}
|
}
|
||||||
|
@ -684,10 +684,10 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrVec2f(const int pAttrIdx, std::ve
|
||||||
|
|
||||||
XML_ReadNode_GetAttrVal_AsListVec2f(pAttrIdx, tlist);// read as list
|
XML_ReadNode_GetAttrVal_AsListVec2f(pAttrIdx, tlist);// read as list
|
||||||
// and copy to array
|
// and copy to array
|
||||||
if(tlist.size() > 0)
|
if(!tlist.empty())
|
||||||
{
|
{
|
||||||
pValue.reserve(tlist.size());
|
pValue.reserve(tlist.size());
|
||||||
for ( std::list<aiVector2D>::iterator it = tlist.begin(); it != tlist.end(); it++ )
|
for ( std::list<aiVector2D>::iterator it = tlist.begin(); it != tlist.end(); ++it )
|
||||||
{
|
{
|
||||||
pValue.push_back( *it );
|
pValue.push_back( *it );
|
||||||
}
|
}
|
||||||
|
@ -722,10 +722,10 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrVec3f(const int pAttrIdx, std::ve
|
||||||
|
|
||||||
XML_ReadNode_GetAttrVal_AsListVec3f(pAttrIdx, tlist);// read as list
|
XML_ReadNode_GetAttrVal_AsListVec3f(pAttrIdx, tlist);// read as list
|
||||||
// and copy to array
|
// and copy to array
|
||||||
if(tlist.size() > 0)
|
if(!tlist.empty())
|
||||||
{
|
{
|
||||||
pValue.reserve(tlist.size());
|
pValue.reserve(tlist.size());
|
||||||
for ( std::list<aiVector3D>::iterator it = tlist.begin(); it != tlist.end(); it++ )
|
for ( std::list<aiVector3D>::iterator it = tlist.begin(); it != tlist.end(); ++it )
|
||||||
{
|
{
|
||||||
pValue.push_back( *it );
|
pValue.push_back( *it );
|
||||||
}
|
}
|
||||||
|
@ -823,7 +823,7 @@ void X3DImporter::GeometryHelper_Extend_PointToLine(const std::list<aiVector3D>&
|
||||||
std::list<aiVector3D>::const_iterator pit = pPoint.begin();
|
std::list<aiVector3D>::const_iterator pit = pPoint.begin();
|
||||||
std::list<aiVector3D>::const_iterator pit_last = pPoint.end();
|
std::list<aiVector3D>::const_iterator pit_last = pPoint.end();
|
||||||
|
|
||||||
pit_last--;
|
--pit_last;
|
||||||
|
|
||||||
if ( pPoint.size() < 2 )
|
if ( pPoint.size() < 2 )
|
||||||
{
|
{
|
||||||
|
@ -837,7 +837,7 @@ void X3DImporter::GeometryHelper_Extend_PointToLine(const std::list<aiVector3D>&
|
||||||
{
|
{
|
||||||
pLine.push_back(*pit);// second point of previous line
|
pLine.push_back(*pit);// second point of previous line
|
||||||
pLine.push_back(*pit);// first point of next line
|
pLine.push_back(*pit);// first point of next line
|
||||||
pit++;
|
++pit;
|
||||||
}
|
}
|
||||||
// add last point of last line
|
// add last point of last line
|
||||||
pLine.push_back(*pit);
|
pLine.push_back(*pit);
|
||||||
|
@ -855,7 +855,7 @@ void X3DImporter::GeometryHelper_Extend_PolylineIdxToLineIdx(const std::list<int
|
||||||
{
|
{
|
||||||
std::list<int32_t>::const_iterator plit_next;
|
std::list<int32_t>::const_iterator plit_next;
|
||||||
|
|
||||||
plit_next = plit, plit_next++;
|
plit_next = plit, ++plit_next;
|
||||||
pLineCoordIdx.push_back(*plit);// second point of previous line.
|
pLineCoordIdx.push_back(*plit);// second point of previous line.
|
||||||
pLineCoordIdx.push_back(-1);// delimiter
|
pLineCoordIdx.push_back(-1);// delimiter
|
||||||
if((*plit_next == (-1)) || (plit_next == pPolylineCoordIdx.end())) break;// current polyline is finished
|
if((*plit_next == (-1)) || (plit_next == pPolylineCoordIdx.end())) break;// current polyline is finished
|
||||||
|
@ -910,7 +910,7 @@ void X3DImporter::GeometryHelper_CoordIdxStr2FacesArr(const std::vector<int32_t>
|
||||||
pFaces.reserve(f_data.size() / 3);
|
pFaces.reserve(f_data.size() / 3);
|
||||||
inds.reserve(4);
|
inds.reserve(4);
|
||||||
//PrintVectorSet("build. ci", pCoordIdx);
|
//PrintVectorSet("build. ci", pCoordIdx);
|
||||||
for(std::vector<int32_t>::iterator it = f_data.begin(); it != f_data.end(); it++)
|
for(std::vector<int32_t>::iterator it = f_data.begin(); it != f_data.end(); ++it)
|
||||||
{
|
{
|
||||||
// when face is got count how many indices in it.
|
// when face is got count how many indices in it.
|
||||||
if(*it == (-1))
|
if(*it == (-1))
|
||||||
|
@ -957,7 +957,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<aiColor3D
|
||||||
std::list<aiColor4D> tcol;
|
std::list<aiColor4D> tcol;
|
||||||
|
|
||||||
// create RGBA array from RGB.
|
// create RGBA array from RGB.
|
||||||
for(std::list<aiColor3D>::const_iterator it = pColors.begin(); it != pColors.end(); it++) tcol.push_back(aiColor4D((*it).r, (*it).g, (*it).b, 1));
|
for(std::list<aiColor3D>::const_iterator it = pColors.begin(); it != pColors.end(); ++it) tcol.push_back(aiColor4D((*it).r, (*it).g, (*it).b, 1));
|
||||||
|
|
||||||
// call existing function for adding RGBA colors
|
// call existing function for adding RGBA colors
|
||||||
MeshGeometry_AddColor(pMesh, tcol, pColorPerVertex);
|
MeshGeometry_AddColor(pMesh, tcol, pColorPerVertex);
|
||||||
|
@ -997,7 +997,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<aiColor4D
|
||||||
pMesh.mColors[ 0 ][ pMesh.mFaces[ fi ].mIndices[ vi ] ] = *col_it;
|
pMesh.mColors[ 0 ][ pMesh.mFaces[ fi ].mIndices[ vi ] ] = *col_it;
|
||||||
}
|
}
|
||||||
|
|
||||||
col_it++;
|
++col_it;
|
||||||
}
|
}
|
||||||
}// if(pColorPerVertex) else
|
}// if(pColorPerVertex) else
|
||||||
}
|
}
|
||||||
|
@ -1008,7 +1008,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::vector<int32_t
|
||||||
std::list<aiColor4D> tcol;
|
std::list<aiColor4D> tcol;
|
||||||
|
|
||||||
// create RGBA array from RGB.
|
// create RGBA array from RGB.
|
||||||
for ( std::list<aiColor3D>::const_iterator it = pColors.begin(); it != pColors.end(); it++ )
|
for ( std::list<aiColor3D>::const_iterator it = pColors.begin(); it != pColors.end(); ++it )
|
||||||
{
|
{
|
||||||
tcol.push_back( aiColor4D( ( *it ).r, ( *it ).g, ( *it ).b, 1 ) );
|
tcol.push_back( aiColor4D( ( *it ).r, ( *it ).g, ( *it ).b, 1 ) );
|
||||||
}
|
}
|
||||||
|
@ -1031,7 +1031,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::vector<int32_t
|
||||||
|
|
||||||
// copy list to array because we are need indexed access to colors.
|
// copy list to array because we are need indexed access to colors.
|
||||||
col_arr_copy.reserve(pColors.size());
|
col_arr_copy.reserve(pColors.size());
|
||||||
for ( std::list<aiColor4D>::const_iterator it = pColors.begin(); it != pColors.end(); it++ )
|
for ( std::list<aiColor4D>::const_iterator it = pColors.begin(); it != pColors.end(); ++it )
|
||||||
{
|
{
|
||||||
col_arr_copy.push_back( *it );
|
col_arr_copy.push_back( *it );
|
||||||
}
|
}
|
||||||
|
@ -1048,7 +1048,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::vector<int32_t
|
||||||
}
|
}
|
||||||
// create list with colors for every vertex.
|
// create list with colors for every vertex.
|
||||||
col_tgt_arr.resize(pMesh.mNumVertices);
|
col_tgt_arr.resize(pMesh.mNumVertices);
|
||||||
for(std::vector<int32_t>::const_iterator colidx_it = pColorIdx.begin(), coordidx_it = pCoordIdx.begin(); colidx_it != pColorIdx.end(); colidx_it++, coordidx_it++)
|
for(std::vector<int32_t>::const_iterator colidx_it = pColorIdx.begin(), coordidx_it = pCoordIdx.begin(); colidx_it != pColorIdx.end(); ++colidx_it, ++coordidx_it)
|
||||||
{
|
{
|
||||||
if ( *colidx_it == ( -1 ) )
|
if ( *colidx_it == ( -1 ) )
|
||||||
{
|
{
|
||||||
|
@ -1121,7 +1121,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::vector<int32_t
|
||||||
}// if(pColorPerVertex) else
|
}// if(pColorPerVertex) else
|
||||||
|
|
||||||
// copy array to list for calling function that add colors.
|
// copy array to list for calling function that add colors.
|
||||||
for(std::vector<aiColor4D>::const_iterator it = col_tgt_arr.begin(); it != col_tgt_arr.end(); it++) col_tgt_list.push_back(*it);
|
for(std::vector<aiColor4D>::const_iterator it = col_tgt_arr.begin(); it != col_tgt_arr.end(); ++it) col_tgt_list.push_back(*it);
|
||||||
// add prepared colors list to mesh.
|
// add prepared colors list to mesh.
|
||||||
MeshGeometry_AddColor(pMesh, col_tgt_list, pColorPerVertex);
|
MeshGeometry_AddColor(pMesh, col_tgt_list, pColorPerVertex);
|
||||||
}
|
}
|
||||||
|
@ -1134,7 +1134,7 @@ void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::vector<int32_
|
||||||
|
|
||||||
// copy list to array because we are need indexed access to normals.
|
// copy list to array because we are need indexed access to normals.
|
||||||
norm_arr_copy.reserve(pNormals.size());
|
norm_arr_copy.reserve(pNormals.size());
|
||||||
for ( std::list<aiVector3D>::const_iterator it = pNormals.begin(); it != pNormals.end(); it++ )
|
for ( std::list<aiVector3D>::const_iterator it = pNormals.begin(); it != pNormals.end(); ++it )
|
||||||
{
|
{
|
||||||
norm_arr_copy.push_back( *it );
|
norm_arr_copy.push_back( *it );
|
||||||
}
|
}
|
||||||
|
@ -1147,7 +1147,7 @@ void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::vector<int32_
|
||||||
if(pNormalIdx.size() != pCoordIdx.size()) throw DeadlyImportError("Normals and Coords inidces count must be equal.");
|
if(pNormalIdx.size() != pCoordIdx.size()) throw DeadlyImportError("Normals and Coords inidces count must be equal.");
|
||||||
|
|
||||||
tind.reserve(pNormalIdx.size());
|
tind.reserve(pNormalIdx.size());
|
||||||
for(std::vector<int32_t>::const_iterator it = pNormalIdx.begin(); it != pNormalIdx.end(); it++)
|
for(std::vector<int32_t>::const_iterator it = pNormalIdx.begin(); it != pNormalIdx.end(); ++it)
|
||||||
{
|
{
|
||||||
if(*it != (-1)) tind.push_back(*it);
|
if(*it != (-1)) tind.push_back(*it);
|
||||||
}
|
}
|
||||||
|
@ -1227,7 +1227,7 @@ void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::list<aiVector
|
||||||
// apply color to all vertices of face
|
// apply color to all vertices of face
|
||||||
for(size_t vi = 0, vi_e = pMesh.mFaces[fi].mNumIndices; vi < vi_e; vi++) pMesh.mNormals[pMesh.mFaces[fi].mIndices[vi]] = *norm_it;
|
for(size_t vi = 0, vi_e = pMesh.mFaces[fi].mNumIndices; vi < vi_e; vi++) pMesh.mNormals[pMesh.mFaces[fi].mIndices[vi]] = *norm_it;
|
||||||
|
|
||||||
norm_it++;
|
++norm_it;
|
||||||
}
|
}
|
||||||
}// if(pNormalPerVertex) else
|
}// if(pNormalPerVertex) else
|
||||||
}
|
}
|
||||||
|
@ -1241,7 +1241,7 @@ void X3DImporter::MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::vector<int3
|
||||||
|
|
||||||
// copy list to array because we are need indexed access to normals.
|
// copy list to array because we are need indexed access to normals.
|
||||||
texcoord_arr_copy.reserve(pTexCoords.size());
|
texcoord_arr_copy.reserve(pTexCoords.size());
|
||||||
for(std::list<aiVector2D>::const_iterator it = pTexCoords.begin(); it != pTexCoords.end(); it++)
|
for(std::list<aiVector2D>::const_iterator it = pTexCoords.begin(); it != pTexCoords.end(); ++it)
|
||||||
{
|
{
|
||||||
texcoord_arr_copy.push_back(aiVector3D((*it).x, (*it).y, 0));
|
texcoord_arr_copy.push_back(aiVector3D((*it).x, (*it).y, 0));
|
||||||
}
|
}
|
||||||
|
@ -1291,7 +1291,7 @@ void X3DImporter::MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list<aiVect
|
||||||
|
|
||||||
// copy list to array because we are need convert aiVector2D to aiVector3D and also get indexed access as a bonus.
|
// copy list to array because we are need convert aiVector2D to aiVector3D and also get indexed access as a bonus.
|
||||||
tc_arr_copy.reserve(pTexCoords.size());
|
tc_arr_copy.reserve(pTexCoords.size());
|
||||||
for ( std::list<aiVector2D>::const_iterator it = pTexCoords.begin(); it != pTexCoords.end(); it++ )
|
for ( std::list<aiVector2D>::const_iterator it = pTexCoords.begin(); it != pTexCoords.end(); ++it )
|
||||||
{
|
{
|
||||||
tc_arr_copy.push_back( aiVector3D( ( *it ).x, ( *it ).y, 0 ) );
|
tc_arr_copy.push_back( aiVector3D( ( *it ).x, ( *it ).y, 0 ) );
|
||||||
}
|
}
|
||||||
|
@ -1699,7 +1699,7 @@ void X3DImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
|
||||||
// create nodes tree
|
// create nodes tree
|
||||||
Postprocess_BuildNode(*NodeElement_Cur, *pScene->mRootNode, mesh_list, mat_list, light_list);
|
Postprocess_BuildNode(*NodeElement_Cur, *pScene->mRootNode, mesh_list, mat_list, light_list);
|
||||||
// copy needed data to scene
|
// copy needed data to scene
|
||||||
if(mesh_list.size() > 0)
|
if(!mesh_list.empty())
|
||||||
{
|
{
|
||||||
std::list<aiMesh*>::const_iterator it = mesh_list.begin();
|
std::list<aiMesh*>::const_iterator it = mesh_list.begin();
|
||||||
|
|
||||||
|
@ -1708,7 +1708,7 @@ void X3DImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
|
||||||
for(size_t i = 0; i < pScene->mNumMeshes; i++) pScene->mMeshes[i] = *it++;
|
for(size_t i = 0; i < pScene->mNumMeshes; i++) pScene->mMeshes[i] = *it++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mat_list.size() > 0)
|
if(!mat_list.empty())
|
||||||
{
|
{
|
||||||
std::list<aiMaterial*>::const_iterator it = mat_list.begin();
|
std::list<aiMaterial*>::const_iterator it = mat_list.begin();
|
||||||
|
|
||||||
|
@ -1717,7 +1717,7 @@ void X3DImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
|
||||||
for(size_t i = 0; i < pScene->mNumMaterials; i++) pScene->mMaterials[i] = *it++;
|
for(size_t i = 0; i < pScene->mNumMaterials; i++) pScene->mMaterials[i] = *it++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(light_list.size() > 0)
|
if(!light_list.empty())
|
||||||
{
|
{
|
||||||
std::list<aiLight*>::const_iterator it = light_list.begin();
|
std::list<aiLight*>::const_iterator it = light_list.begin();
|
||||||
|
|
||||||
|
|
|
@ -356,7 +356,7 @@ void X3DImporter::ParseNode_Geometry2D_Polyline2D()
|
||||||
std::list<aiVector3D> tlist;
|
std::list<aiVector3D> tlist;
|
||||||
|
|
||||||
// convert vec2 to vec3
|
// convert vec2 to vec3
|
||||||
for(std::list<aiVector2D>::iterator it2 = lineSegments.begin(); it2 != lineSegments.end(); it2++) tlist.push_back(aiVector3D(it2->x, it2->y, 0));
|
for(std::list<aiVector2D>::iterator it2 = lineSegments.begin(); it2 != lineSegments.end(); ++it2) tlist.push_back(aiVector3D(it2->x, it2->y, 0));
|
||||||
|
|
||||||
// convert point set to line set
|
// convert point set to line set
|
||||||
GeometryHelper_Extend_PointToLine(tlist, ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices);
|
GeometryHelper_Extend_PointToLine(tlist, ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices);
|
||||||
|
@ -399,7 +399,7 @@ void X3DImporter::ParseNode_Geometry2D_Polypoint2D()
|
||||||
if(!def.empty()) ne->ID = def;
|
if(!def.empty()) ne->ID = def;
|
||||||
|
|
||||||
// convert vec2 to vec3
|
// convert vec2 to vec3
|
||||||
for(std::list<aiVector2D>::iterator it2 = point.begin(); it2 != point.end(); it2++)
|
for(std::list<aiVector2D>::iterator it2 = point.begin(); it2 != point.end(); ++it2)
|
||||||
{
|
{
|
||||||
((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices.push_back(aiVector3D(it2->x, it2->y, 0));
|
((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices.push_back(aiVector3D(it2->x, it2->y, 0));
|
||||||
}
|
}
|
||||||
|
@ -500,7 +500,7 @@ void X3DImporter::ParseNode_Geometry2D_TriangleSet2D()
|
||||||
if(!def.empty()) ne->ID = def;
|
if(!def.empty()) ne->ID = def;
|
||||||
|
|
||||||
// convert vec2 to vec3
|
// convert vec2 to vec3
|
||||||
for(std::list<aiVector2D>::iterator it2 = vertices.begin(); it2 != vertices.end(); it2++)
|
for(std::list<aiVector2D>::iterator it2 = vertices.begin(); it2 != vertices.end(); ++it2)
|
||||||
{
|
{
|
||||||
((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices.push_back(aiVector3D(it2->x, it2->y, 0));
|
((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices.push_back(aiVector3D(it2->x, it2->y, 0));
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,11 +153,11 @@ void X3DImporter::ParseNode_Geometry3D_Cone()
|
||||||
{
|
{
|
||||||
StandardShapes::MakeCircle(bottomRadius, tess, tvec);
|
StandardShapes::MakeCircle(bottomRadius, tess, tvec);
|
||||||
height = -(height / 2);
|
height = -(height / 2);
|
||||||
for(std::vector<aiVector3D>::iterator it = tvec.begin(); it != tvec.end(); it++) it->y = height;// y - because circle made in oXZ.
|
for(std::vector<aiVector3D>::iterator it = tvec.begin(); it != tvec.end(); ++it) it->y = height;// y - because circle made in oXZ.
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy data from temp array
|
// copy data from temp array
|
||||||
for(std::vector<aiVector3D>::iterator it = tvec.begin(); it != tvec.end(); it++) ((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices.push_back(*it);
|
for(std::vector<aiVector3D>::iterator it = tvec.begin(); it != tvec.end(); ++it) ((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices.push_back(*it);
|
||||||
|
|
||||||
((CX3DImporter_NodeElement_Geometry3D*)ne)->Solid = solid;
|
((CX3DImporter_NodeElement_Geometry3D*)ne)->Solid = solid;
|
||||||
((CX3DImporter_NodeElement_Geometry3D*)ne)->NumIndices = 3;
|
((CX3DImporter_NodeElement_Geometry3D*)ne)->NumIndices = 3;
|
||||||
|
@ -226,11 +226,11 @@ void X3DImporter::ParseNode_Geometry3D_Cylinder()
|
||||||
// copy data from temp arrays
|
// copy data from temp arrays
|
||||||
std::list<aiVector3D>& vlist = ((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices;// just short alias.
|
std::list<aiVector3D>& vlist = ((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices;// just short alias.
|
||||||
|
|
||||||
for(std::vector<aiVector3D>::iterator it = tside.begin(); it != tside.end(); it++) vlist.push_back(*it);
|
for(std::vector<aiVector3D>::iterator it = tside.begin(); it != tside.end(); ++it) vlist.push_back(*it);
|
||||||
|
|
||||||
if(top)
|
if(top)
|
||||||
{
|
{
|
||||||
for(std::vector<aiVector3D>::iterator it = tcir.begin(); it != tcir.end(); it++)
|
for(std::vector<aiVector3D>::iterator it = tcir.begin(); it != tcir.end(); ++it)
|
||||||
{
|
{
|
||||||
(*it).y = height;// y - because circle made in oXZ.
|
(*it).y = height;// y - because circle made in oXZ.
|
||||||
vlist.push_back(*it);
|
vlist.push_back(*it);
|
||||||
|
@ -239,7 +239,7 @@ void X3DImporter::ParseNode_Geometry3D_Cylinder()
|
||||||
|
|
||||||
if(bottom)
|
if(bottom)
|
||||||
{
|
{
|
||||||
for(std::vector<aiVector3D>::iterator it = tcir.begin(); it != tcir.end(); it++)
|
for(std::vector<aiVector3D>::iterator it = tcir.begin(); it != tcir.end(); ++it)
|
||||||
{
|
{
|
||||||
(*it).y = -height;// y - because circle made in oXZ.
|
(*it).y = -height;// y - because circle made in oXZ.
|
||||||
vlist.push_back(*it);
|
vlist.push_back(*it);
|
||||||
|
@ -336,7 +336,7 @@ void X3DImporter::ParseNode_Geometry3D_ElevationGrid()
|
||||||
aiVector3D tvec(xSpacing * xi, *he_it, zSpacing * zi);
|
aiVector3D tvec(xSpacing * xi, *he_it, zSpacing * zi);
|
||||||
|
|
||||||
grid_alias.Vertices.push_back(tvec);
|
grid_alias.Vertices.push_back(tvec);
|
||||||
he_it++;
|
++he_it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}// END: create grid vertices list
|
}// END: create grid vertices list
|
||||||
|
@ -977,7 +977,7 @@ void X3DImporter::ParseNode_Geometry3D_Sphere()
|
||||||
|
|
||||||
StandardShapes::MakeSphere(tess, tlist);
|
StandardShapes::MakeSphere(tess, tlist);
|
||||||
// copy data from temp array and apply scale
|
// copy data from temp array and apply scale
|
||||||
for(std::vector<aiVector3D>::iterator it = tlist.begin(); it != tlist.end(); it++)
|
for(std::vector<aiVector3D>::iterator it = tlist.begin(); it != tlist.end(); ++it)
|
||||||
{
|
{
|
||||||
((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices.push_back(*it * radius);
|
((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices.push_back(*it * radius);
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,7 @@ void X3DImporter::ParseNode_Networking_Inline()
|
||||||
// at this place new group mode created and made current, so we can name it.
|
// at this place new group mode created and made current, so we can name it.
|
||||||
if(!def.empty()) NodeElement_Cur->ID = def;
|
if(!def.empty()) NodeElement_Cur->ID = def;
|
||||||
|
|
||||||
if(load && (url.size() > 0))
|
if(load && !url.empty())
|
||||||
{
|
{
|
||||||
std::string full_path = mpIOHandler->CurrentDirectory() + url.front();
|
std::string full_path = mpIOHandler->CurrentDirectory() + url.front();
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ aiMatrix4x4 X3DImporter::PostprocessHelper_Matrix_GlobalToCurrent() const
|
||||||
}
|
}
|
||||||
|
|
||||||
// multiplicate all matrices in reverse order
|
// multiplicate all matrices in reverse order
|
||||||
for(std::list<aiMatrix4x4>::reverse_iterator rit = matr.rbegin(); rit != matr.rend(); rit++) out_matr = out_matr * (*rit);
|
for(std::list<aiMatrix4x4>::reverse_iterator rit = matr.rbegin(); rit != matr.rend(); ++rit) out_matr = out_matr * (*rit);
|
||||||
|
|
||||||
return out_matr;
|
return out_matr;
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ aiMatrix4x4 X3DImporter::PostprocessHelper_Matrix_GlobalToCurrent() const
|
||||||
void X3DImporter::PostprocessHelper_CollectMetadata(const CX3DImporter_NodeElement& pNodeElement, std::list<CX3DImporter_NodeElement*>& pList) const
|
void X3DImporter::PostprocessHelper_CollectMetadata(const CX3DImporter_NodeElement& pNodeElement, std::list<CX3DImporter_NodeElement*>& pList) const
|
||||||
{
|
{
|
||||||
// walk through childs and find for metadata.
|
// walk through childs and find for metadata.
|
||||||
for(std::list<CX3DImporter_NodeElement*>::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); el_it++)
|
for(std::list<CX3DImporter_NodeElement*>::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); ++el_it)
|
||||||
{
|
{
|
||||||
if(((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaBoolean) || ((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaDouble) ||
|
if(((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaBoolean) || ((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaDouble) ||
|
||||||
((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaFloat) || ((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaInteger) ||
|
((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaFloat) || ((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaInteger) ||
|
||||||
|
@ -194,7 +194,7 @@ void X3DImporter::Postprocess_BuildMaterial(const CX3DImporter_NodeElement& pNod
|
||||||
aiMaterial& taimat = **pMaterial;// creating alias for convenience.
|
aiMaterial& taimat = **pMaterial;// creating alias for convenience.
|
||||||
|
|
||||||
// at this point pNodeElement point to <Appearance> node. Walk through childs and add all stored data.
|
// at this point pNodeElement point to <Appearance> node. Walk through childs and add all stored data.
|
||||||
for(std::list<CX3DImporter_NodeElement*>::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); el_it++)
|
for(std::list<CX3DImporter_NodeElement*>::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); ++el_it)
|
||||||
{
|
{
|
||||||
if((*el_it)->Type == CX3DImporter_NodeElement::ENET_Material)
|
if((*el_it)->Type == CX3DImporter_NodeElement::ENET_Material)
|
||||||
{
|
{
|
||||||
|
@ -255,7 +255,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
||||||
std::vector<aiVector3D> tarr;
|
std::vector<aiVector3D> tarr;
|
||||||
|
|
||||||
tarr.reserve(tnemesh.Vertices.size());
|
tarr.reserve(tnemesh.Vertices.size());
|
||||||
for(std::list<aiVector3D>::iterator it = tnemesh.Vertices.begin(); it != tnemesh.Vertices.end(); it++) tarr.push_back(*it);
|
for(std::list<aiVector3D>::iterator it = tnemesh.Vertices.begin(); it != tnemesh.Vertices.end(); ++it) tarr.push_back(*it);
|
||||||
*pMesh = StandardShapes::MakeMesh(tarr, static_cast<unsigned int>(tnemesh.NumIndices));// create mesh from vertices using Assimp help.
|
*pMesh = StandardShapes::MakeMesh(tarr, static_cast<unsigned int>(tnemesh.NumIndices));// create mesh from vertices using Assimp help.
|
||||||
|
|
||||||
return;// mesh is build, nothing to do anymore.
|
return;// mesh is build, nothing to do anymore.
|
||||||
|
@ -273,7 +273,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
||||||
std::vector<aiVector3D> tarr;
|
std::vector<aiVector3D> tarr;
|
||||||
|
|
||||||
tarr.reserve(tnemesh.Vertices.size());
|
tarr.reserve(tnemesh.Vertices.size());
|
||||||
for(std::list<aiVector3D>::iterator it = tnemesh.Vertices.begin(); it != tnemesh.Vertices.end(); it++) tarr.push_back(*it);
|
for(std::list<aiVector3D>::iterator it = tnemesh.Vertices.begin(); it != tnemesh.Vertices.end(); ++it) tarr.push_back(*it);
|
||||||
|
|
||||||
*pMesh = StandardShapes::MakeMesh(tarr, static_cast<unsigned int>(tnemesh.NumIndices));// create mesh from vertices using Assimp help.
|
*pMesh = StandardShapes::MakeMesh(tarr, static_cast<unsigned int>(tnemesh.NumIndices));// create mesh from vertices using Assimp help.
|
||||||
|
|
||||||
|
@ -438,7 +438,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
||||||
|
|
||||||
vec_copy.reserve(((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.size());
|
vec_copy.reserve(((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.size());
|
||||||
for(std::list<aiVector3D>::const_iterator it = ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.begin();
|
for(std::list<aiVector3D>::const_iterator it = ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.begin();
|
||||||
it != ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.end(); it++)
|
it != ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.end(); ++it)
|
||||||
{
|
{
|
||||||
vec_copy.push_back(*it);
|
vec_copy.push_back(*it);
|
||||||
}
|
}
|
||||||
|
@ -544,7 +544,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
||||||
|
|
||||||
vec_copy.reserve(((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.size());
|
vec_copy.reserve(((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.size());
|
||||||
for(std::list<aiVector3D>::const_iterator it = ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.begin();
|
for(std::list<aiVector3D>::const_iterator it = ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.begin();
|
||||||
it != ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.end(); it++)
|
it != ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.end(); ++it)
|
||||||
{
|
{
|
||||||
vec_copy.push_back(*it);
|
vec_copy.push_back(*it);
|
||||||
}
|
}
|
||||||
|
@ -554,7 +554,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy additional information from children
|
// copy additional information from children
|
||||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||||
{
|
{
|
||||||
ai_assert(*pMesh);
|
ai_assert(*pMesh);
|
||||||
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
|
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
|
||||||
|
@ -580,7 +580,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
||||||
CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
|
CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
|
||||||
|
|
||||||
// at first search for <Coordinate> node and create mesh.
|
// at first search for <Coordinate> node and create mesh.
|
||||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||||
{
|
{
|
||||||
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
|
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
|
||||||
{
|
{
|
||||||
|
@ -589,7 +589,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy additional information from children
|
// copy additional information from children
|
||||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||||
{
|
{
|
||||||
ai_assert(*pMesh);
|
ai_assert(*pMesh);
|
||||||
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
|
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
|
||||||
|
@ -639,16 +639,16 @@ void X3DImporter::Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeEle
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(size_t i = 0; i < (size_t)tne_group.Choice; i++) chit_begin++;// forward iterator to chosen node.
|
for(size_t i = 0; i < (size_t)tne_group.Choice; i++) ++chit_begin;// forward iterator to chosen node.
|
||||||
|
|
||||||
chit_end = chit_begin;
|
chit_end = chit_begin;
|
||||||
chit_end++;// point end iterator to next element after chosen node.
|
++chit_end;// point end iterator to next element after chosen node.
|
||||||
}
|
}
|
||||||
}// if(tne_group.UseChoice)
|
}// if(tne_group.UseChoice)
|
||||||
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_Group)
|
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_Group)
|
||||||
|
|
||||||
// Reserve memory for fast access and check children.
|
// Reserve memory for fast access and check children.
|
||||||
for(std::list<CX3DImporter_NodeElement*>::const_iterator it = chit_begin; it != chit_end; it++)
|
for(std::list<CX3DImporter_NodeElement*>::const_iterator it = chit_begin; it != chit_end; ++it)
|
||||||
{// in this loop we do not read metadata because it's already read at begin.
|
{// in this loop we do not read metadata because it's already read at begin.
|
||||||
if((*it)->Type == CX3DImporter_NodeElement::ENET_Group)
|
if((*it)->Type == CX3DImporter_NodeElement::ENET_Group)
|
||||||
{
|
{
|
||||||
|
@ -677,7 +677,7 @@ void X3DImporter::Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeEle
|
||||||
}// for(std::list<CX3DImporter_NodeElement*>::const_iterator it = chit_begin; it != chit_end; it++)
|
}// for(std::list<CX3DImporter_NodeElement*>::const_iterator it = chit_begin; it != chit_end; it++)
|
||||||
|
|
||||||
// copy data about children and meshes to aiNode.
|
// copy data about children and meshes to aiNode.
|
||||||
if(SceneNode_Child.size() > 0)
|
if(!SceneNode_Child.empty())
|
||||||
{
|
{
|
||||||
std::list<aiNode*>::const_iterator it = SceneNode_Child.begin();
|
std::list<aiNode*>::const_iterator it = SceneNode_Child.begin();
|
||||||
|
|
||||||
|
@ -686,7 +686,7 @@ void X3DImporter::Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeEle
|
||||||
for(size_t i = 0; i < pSceneNode.mNumChildren; i++) pSceneNode.mChildren[i] = *it++;
|
for(size_t i = 0; i < pSceneNode.mNumChildren; i++) pSceneNode.mChildren[i] = *it++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(SceneNode_Mesh.size() > 0)
|
if(!SceneNode_Mesh.empty())
|
||||||
{
|
{
|
||||||
std::list<unsigned int>::const_iterator it = SceneNode_Mesh.begin();
|
std::list<unsigned int>::const_iterator it = SceneNode_Mesh.begin();
|
||||||
|
|
||||||
|
@ -706,7 +706,7 @@ void X3DImporter::Postprocess_BuildShape(const CX3DImporter_NodeElement_Shape& p
|
||||||
CX3DImporter_NodeElement::EType mesh_type = CX3DImporter_NodeElement::ENET_Invalid;
|
CX3DImporter_NodeElement::EType mesh_type = CX3DImporter_NodeElement::ENET_Invalid;
|
||||||
unsigned int mat_ind = 0;
|
unsigned int mat_ind = 0;
|
||||||
|
|
||||||
for(std::list<CX3DImporter_NodeElement*>::const_iterator it = pShapeNodeElement.Child.begin(); it != pShapeNodeElement.Child.end(); it++)
|
for(std::list<CX3DImporter_NodeElement*>::const_iterator it = pShapeNodeElement.Child.begin(); it != pShapeNodeElement.Child.end(); ++it)
|
||||||
{
|
{
|
||||||
if(PostprocessHelper_ElementIsMesh((*it)->Type))
|
if(PostprocessHelper_ElementIsMesh((*it)->Type))
|
||||||
{
|
{
|
||||||
|
@ -779,7 +779,7 @@ void X3DImporter::Postprocess_CollectMetadata(const CX3DImporter_NodeElement& pN
|
||||||
// copy collected metadata to output node.
|
// copy collected metadata to output node.
|
||||||
pSceneNode.mMetaData = aiMetadata::Alloc( static_cast<unsigned int>(meta_list.size()) );
|
pSceneNode.mMetaData = aiMetadata::Alloc( static_cast<unsigned int>(meta_list.size()) );
|
||||||
meta_idx = 0;
|
meta_idx = 0;
|
||||||
for(std::list<CX3DImporter_NodeElement*>::const_iterator it = meta_list.begin(); it != meta_list.end(); it++, meta_idx++)
|
for(std::list<CX3DImporter_NodeElement*>::const_iterator it = meta_list.begin(); it != meta_list.end(); ++it, ++meta_idx)
|
||||||
{
|
{
|
||||||
CX3DImporter_NodeElement_Meta* cur_meta = (CX3DImporter_NodeElement_Meta*)*it;
|
CX3DImporter_NodeElement_Meta* cur_meta = (CX3DImporter_NodeElement_Meta*)*it;
|
||||||
|
|
||||||
|
|
|
@ -295,7 +295,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleFanSet()
|
||||||
ne_alias.CoordIndex.clear();
|
ne_alias.CoordIndex.clear();
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
int32_t idx[3];
|
int32_t idx[3];
|
||||||
for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++)
|
for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); ++idx_it)
|
||||||
{
|
{
|
||||||
idx[2] = *idx_it;
|
idx[2] = *idx_it;
|
||||||
if (idx[2] < 0)
|
if (idx[2] < 0)
|
||||||
|
@ -413,7 +413,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleSet()
|
||||||
ne_alias.CoordIndex.clear();
|
ne_alias.CoordIndex.clear();
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
int32_t idx[3];
|
int32_t idx[3];
|
||||||
for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++)
|
for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); ++idx_it)
|
||||||
{
|
{
|
||||||
idx[counter++] = *idx_it;
|
idx[counter++] = *idx_it;
|
||||||
if (counter > 2)
|
if (counter > 2)
|
||||||
|
@ -519,7 +519,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleStripSet()
|
||||||
ne_alias.CoordIndex.clear();
|
ne_alias.CoordIndex.clear();
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
int32_t idx[3];
|
int32_t idx[3];
|
||||||
for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++)
|
for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); ++idx_it)
|
||||||
{
|
{
|
||||||
idx[2] = *idx_it;
|
idx[2] = *idx_it;
|
||||||
if (idx[2] < 0)
|
if (idx[2] < 0)
|
||||||
|
@ -617,7 +617,7 @@ void X3DImporter::ParseNode_Rendering_LineSet()
|
||||||
size_t coord_num = 0;
|
size_t coord_num = 0;
|
||||||
|
|
||||||
ne_alias.CoordIndex.clear();
|
ne_alias.CoordIndex.clear();
|
||||||
for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++)
|
for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); ++vc_it)
|
||||||
{
|
{
|
||||||
if(*vc_it < 2) throw DeadlyImportError("LineSet. vertexCount shall be greater than or equal to two.");
|
if(*vc_it < 2) throw DeadlyImportError("LineSet. vertexCount shall be greater than or equal to two.");
|
||||||
|
|
||||||
|
@ -765,7 +765,7 @@ void X3DImporter::ParseNode_Rendering_TriangleFanSet()
|
||||||
// assign indices for first triangle
|
// assign indices for first triangle
|
||||||
coord_num_first = 0;
|
coord_num_first = 0;
|
||||||
coord_num_prev = 1;
|
coord_num_prev = 1;
|
||||||
for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++)
|
for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); ++vc_it)
|
||||||
{
|
{
|
||||||
if(*vc_it < 3) throw DeadlyImportError("TriangleFanSet. fanCount shall be greater than or equal to three.");
|
if(*vc_it < 3) throw DeadlyImportError("TriangleFanSet. fanCount shall be greater than or equal to three.");
|
||||||
|
|
||||||
|
@ -956,7 +956,7 @@ void X3DImporter::ParseNode_Rendering_TriangleStripSet()
|
||||||
|
|
||||||
ne_alias.CoordIndex.clear();
|
ne_alias.CoordIndex.clear();
|
||||||
coord_num_sb = 0;
|
coord_num_sb = 0;
|
||||||
for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++)
|
for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); ++vc_it)
|
||||||
{
|
{
|
||||||
if(*vc_it < 3) throw DeadlyImportError("TriangleStripSet. stripCount shall be greater than or equal to three.");
|
if(*vc_it < 3) throw DeadlyImportError("TriangleStripSet. stripCount shall be greater than or equal to three.");
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ void X3DImporter::ParseNode_Texturing_ImageTexture()
|
||||||
((CX3DImporter_NodeElement_ImageTexture*)ne)->RepeatS = repeatS;
|
((CX3DImporter_NodeElement_ImageTexture*)ne)->RepeatS = repeatS;
|
||||||
((CX3DImporter_NodeElement_ImageTexture*)ne)->RepeatT = repeatT;
|
((CX3DImporter_NodeElement_ImageTexture*)ne)->RepeatT = repeatT;
|
||||||
// Attribute "url" can contain list of strings. But we need only one - first.
|
// Attribute "url" can contain list of strings. But we need only one - first.
|
||||||
if(url.size() > 0)
|
if(!url.empty())
|
||||||
((CX3DImporter_NodeElement_ImageTexture*)ne)->URL = url.front();
|
((CX3DImporter_NodeElement_ImageTexture*)ne)->URL = url.front();
|
||||||
else
|
else
|
||||||
((CX3DImporter_NodeElement_ImageTexture*)ne)->URL = "";
|
((CX3DImporter_NodeElement_ImageTexture*)ne)->URL = "";
|
||||||
|
|
|
@ -1041,7 +1041,7 @@ aiNodeAnim* CreateNodeAnim(glTF2::Asset& r, Node& node, AnimationSamplers& sampl
|
||||||
delete[] values;
|
delete[] values;
|
||||||
} else if (node.rotation.isPresent) {
|
} else if (node.rotation.isPresent) {
|
||||||
anim->mNumRotationKeys = 1;
|
anim->mNumRotationKeys = 1;
|
||||||
anim->mRotationKeys = new aiQuatKey();
|
anim->mRotationKeys = new aiQuatKey[anim->mNumRotationKeys];
|
||||||
anim->mRotationKeys->mTime = 0.f;
|
anim->mRotationKeys->mTime = 0.f;
|
||||||
anim->mRotationKeys->mValue.x = node.rotation.value[0];
|
anim->mRotationKeys->mValue.x = node.rotation.value[0];
|
||||||
anim->mRotationKeys->mValue.y = node.rotation.value[1];
|
anim->mRotationKeys->mValue.y = node.rotation.value[1];
|
||||||
|
@ -1064,7 +1064,7 @@ aiNodeAnim* CreateNodeAnim(glTF2::Asset& r, Node& node, AnimationSamplers& sampl
|
||||||
delete[] values;
|
delete[] values;
|
||||||
} else if (node.scale.isPresent) {
|
} else if (node.scale.isPresent) {
|
||||||
anim->mNumScalingKeys = 1;
|
anim->mNumScalingKeys = 1;
|
||||||
anim->mScalingKeys = new aiVectorKey();
|
anim->mScalingKeys = new aiVectorKey[anim->mNumScalingKeys];
|
||||||
anim->mScalingKeys->mTime = 0.f;
|
anim->mScalingKeys->mTime = 0.f;
|
||||||
anim->mScalingKeys->mValue.x = node.scale.value[0];
|
anim->mScalingKeys->mValue.x = node.scale.value[0];
|
||||||
anim->mScalingKeys->mValue.y = node.scale.value[1];
|
anim->mScalingKeys->mValue.y = node.scale.value[1];
|
||||||
|
@ -1130,6 +1130,7 @@ void glTF2Importer::ImportAnimations(glTF2::Asset& r)
|
||||||
|
|
||||||
// Use the latest keyframe for the duration of the animation
|
// Use the latest keyframe for the duration of the animation
|
||||||
double maxDuration = 0;
|
double maxDuration = 0;
|
||||||
|
unsigned int maxNumberOfKeys = 0;
|
||||||
for (unsigned int j = 0; j < ai_anim->mNumChannels; ++j) {
|
for (unsigned int j = 0; j < ai_anim->mNumChannels; ++j) {
|
||||||
auto chan = ai_anim->mChannels[j];
|
auto chan = ai_anim->mChannels[j];
|
||||||
if (chan->mNumPositionKeys) {
|
if (chan->mNumPositionKeys) {
|
||||||
|
@ -1137,21 +1138,25 @@ void glTF2Importer::ImportAnimations(glTF2::Asset& r)
|
||||||
if (lastPosKey.mTime > maxDuration) {
|
if (lastPosKey.mTime > maxDuration) {
|
||||||
maxDuration = lastPosKey.mTime;
|
maxDuration = lastPosKey.mTime;
|
||||||
}
|
}
|
||||||
|
maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumPositionKeys);
|
||||||
}
|
}
|
||||||
if (chan->mNumRotationKeys) {
|
if (chan->mNumRotationKeys) {
|
||||||
auto lastRotKey = chan->mRotationKeys[chan->mNumRotationKeys - 1];
|
auto lastRotKey = chan->mRotationKeys[chan->mNumRotationKeys - 1];
|
||||||
if (lastRotKey.mTime > maxDuration) {
|
if (lastRotKey.mTime > maxDuration) {
|
||||||
maxDuration = lastRotKey.mTime;
|
maxDuration = lastRotKey.mTime;
|
||||||
}
|
}
|
||||||
|
maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumRotationKeys);
|
||||||
}
|
}
|
||||||
if (chan->mNumScalingKeys) {
|
if (chan->mNumScalingKeys) {
|
||||||
auto lastScaleKey = chan->mScalingKeys[chan->mNumScalingKeys - 1];
|
auto lastScaleKey = chan->mScalingKeys[chan->mNumScalingKeys - 1];
|
||||||
if (lastScaleKey.mTime > maxDuration) {
|
if (lastScaleKey.mTime > maxDuration) {
|
||||||
maxDuration = lastScaleKey.mTime;
|
maxDuration = lastScaleKey.mTime;
|
||||||
}
|
}
|
||||||
|
maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumScalingKeys);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ai_anim->mDuration = maxDuration;
|
ai_anim->mDuration = maxDuration;
|
||||||
|
ai_anim->mTicksPerSecond = (maxNumberOfKeys > 0 && maxDuration > 0) ? (maxNumberOfKeys / (maxDuration/1000)) : 30;
|
||||||
|
|
||||||
mScene->mAnimations[i] = ai_anim;
|
mScene->mAnimations[i] = ai_anim;
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,7 +215,7 @@ TEST(IteratorTest, ParamIteratorConformsToForwardIteratorConcept) {
|
||||||
// Verifies that prefix and postfix operator++() advance an iterator
|
// Verifies that prefix and postfix operator++() advance an iterator
|
||||||
// all the same.
|
// all the same.
|
||||||
it2 = it;
|
it2 = it;
|
||||||
it++;
|
++it;
|
||||||
++it2;
|
++it2;
|
||||||
EXPECT_TRUE(*it == *it2);
|
EXPECT_TRUE(*it == *it2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,6 +82,10 @@ class IOStream;
|
||||||
class ASSIMP_API BaseImporter {
|
class ASSIMP_API BaseImporter {
|
||||||
friend class Importer;
|
friend class Importer;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* Pushes state into importer for the importer scale */
|
||||||
|
virtual void UpdateImporterScale( Importer* pImp );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Constructor to be privately used by #Importer */
|
/** Constructor to be privately used by #Importer */
|
||||||
|
@ -134,7 +138,7 @@ public:
|
||||||
* a suitable response to the caller.
|
* a suitable response to the caller.
|
||||||
*/
|
*/
|
||||||
aiScene* ReadFile(
|
aiScene* ReadFile(
|
||||||
const Importer* pImp,
|
Importer* pImp,
|
||||||
const std::string& pFile,
|
const std::string& pFile,
|
||||||
IOSystem* pIOHandler
|
IOSystem* pIOHandler
|
||||||
);
|
);
|
||||||
|
@ -209,14 +213,6 @@ public:
|
||||||
return applicationUnits;
|
return applicationUnits;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns scale used by application called by ScaleProcess */
|
|
||||||
double GetImporterScale() const
|
|
||||||
{
|
|
||||||
ai_assert(importerScale != 0);
|
|
||||||
ai_assert(fileScale != 0);
|
|
||||||
return importerScale * fileScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Called by #Importer::GetExtensionList for each loaded importer.
|
/** Called by #Importer::GetExtensionList for each loaded importer.
|
||||||
* Take the extension list contained in the structure returned by
|
* Take the extension list contained in the structure returned by
|
||||||
|
@ -230,6 +226,7 @@ protected:
|
||||||
double fileScale = 1.0;
|
double fileScale = 1.0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Imports the given file into the given scene structure. The
|
/** Imports the given file into the given scene structure. The
|
||||||
* function is expected to throw an ImportErrorException if there is
|
* function is expected to throw an ImportErrorException if there is
|
||||||
|
|
|
@ -65,6 +65,7 @@ struct aiLight;
|
||||||
struct aiMetadata;
|
struct aiMetadata;
|
||||||
struct aiBone;
|
struct aiBone;
|
||||||
struct aiMesh;
|
struct aiMesh;
|
||||||
|
struct aiAnimMesh;
|
||||||
struct aiAnimation;
|
struct aiAnimation;
|
||||||
struct aiNodeAnim;
|
struct aiNodeAnim;
|
||||||
|
|
||||||
|
@ -363,6 +364,7 @@ public:
|
||||||
static void Copy (aiMesh** dest, const aiMesh* src);
|
static void Copy (aiMesh** dest, const aiMesh* src);
|
||||||
|
|
||||||
// similar to Copy():
|
// similar to Copy():
|
||||||
|
static void Copy (aiAnimMesh** dest, const aiAnimMesh* src);
|
||||||
static void Copy (aiMaterial** dest, const aiMaterial* src);
|
static void Copy (aiMaterial** dest, const aiMaterial* src);
|
||||||
static void Copy (aiTexture** dest, const aiTexture* src);
|
static void Copy (aiTexture** dest, const aiTexture* src);
|
||||||
static void Copy (aiAnimation** dest, const aiAnimation* src);
|
static void Copy (aiAnimation** dest, const aiAnimation* src);
|
||||||
|
|
|
@ -26,9 +26,9 @@
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
|
|
||||||
/* the global Assimp scene object */
|
/* the global Assimp scene object */
|
||||||
const struct aiScene* scene = NULL;
|
const C_STRUCT aiScene* scene = NULL;
|
||||||
GLuint scene_list = 0;
|
GLuint scene_list = 0;
|
||||||
struct aiVector3D scene_min, scene_max, scene_center;
|
C_STRUCT aiVector3D scene_min, scene_max, scene_center;
|
||||||
|
|
||||||
/* current rotation angle */
|
/* current rotation angle */
|
||||||
static float angle = 0.f;
|
static float angle = 0.f;
|
||||||
|
@ -49,22 +49,22 @@ void reshape(int width, int height)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------- */
|
||||||
void get_bounding_box_for_node (const struct aiNode* nd,
|
void get_bounding_box_for_node (const a<C_STRUCT iNode* nd,
|
||||||
struct aiVector3D* min,
|
C_STRUCT aiVector3D* min,
|
||||||
struct aiVector3D* max,
|
C_STRUCT aiVector3D* max,
|
||||||
struct aiMatrix4x4* trafo
|
C_STRUCT aiMatrix4x4* trafo
|
||||||
){
|
){
|
||||||
struct aiMatrix4x4 prev;
|
C_STRUCT aiMatrix4x4 prev;
|
||||||
unsigned int n = 0, t;
|
unsigned int n = 0, t;
|
||||||
|
|
||||||
prev = *trafo;
|
prev = *trafo;
|
||||||
aiMultiplyMatrix4(trafo,&nd->mTransformation);
|
aiMultiplyMatrix4(trafo,&nd->mTransformation);
|
||||||
|
|
||||||
for (; n < nd->mNumMeshes; ++n) {
|
for (; n < nd->mNumMeshes; ++n) {
|
||||||
const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
|
const C_STRUCT aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
|
||||||
for (t = 0; t < mesh->mNumVertices; ++t) {
|
for (t = 0; t < mesh->mNumVertices; ++t) {
|
||||||
|
|
||||||
struct aiVector3D tmp = mesh->mVertices[t];
|
C_STRUCT aiVector3D tmp = mesh->mVertices[t];
|
||||||
aiTransformVecByMatrix4(&tmp,trafo);
|
aiTransformVecByMatrix4(&tmp,trafo);
|
||||||
|
|
||||||
min->x = aisgl_min(min->x,tmp.x);
|
min->x = aisgl_min(min->x,tmp.x);
|
||||||
|
@ -84,9 +84,9 @@ void get_bounding_box_for_node (const struct aiNode* nd,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------- */
|
||||||
void get_bounding_box (struct aiVector3D* min, struct aiVector3D* max)
|
void get_bounding_box(C_STRUCT aiVector3D* min, C_STRUCT aiVector3D* max)
|
||||||
{
|
{
|
||||||
struct aiMatrix4x4 trafo;
|
aiMatrix4x4 trafo;
|
||||||
aiIdentityMatrix4(&trafo);
|
aiIdentityMatrix4(&trafo);
|
||||||
|
|
||||||
min->x = min->y = min->z = 1e10f;
|
min->x = min->y = min->z = 1e10f;
|
||||||
|
@ -95,7 +95,7 @@ void get_bounding_box (struct aiVector3D* min, struct aiVector3D* max)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------- */
|
||||||
void color4_to_float4(const struct aiColor4D *c, float f[4])
|
void color4_to_float4(const C_STRUCT aiColor4D *c, float f[4])
|
||||||
{
|
{
|
||||||
f[0] = c->r;
|
f[0] = c->r;
|
||||||
f[1] = c->g;
|
f[1] = c->g;
|
||||||
|
@ -113,16 +113,16 @@ void set_float4(float f[4], float a, float b, float c, float d)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------- */
|
||||||
void apply_material(const struct aiMaterial *mtl)
|
void apply_material(const C_STRUCT aiMaterial *mtl)
|
||||||
{
|
{
|
||||||
float c[4];
|
float c[4];
|
||||||
|
|
||||||
GLenum fill_mode;
|
GLenum fill_mode;
|
||||||
int ret1, ret2;
|
int ret1, ret2;
|
||||||
struct aiColor4D diffuse;
|
C_STRUCT aiColor4D diffuse;
|
||||||
struct aiColor4D specular;
|
C_STRUCT aiColor4D specular;
|
||||||
struct aiColor4D ambient;
|
C_STRUCT aiColor4D ambient;
|
||||||
struct aiColor4D emission;
|
C_STRUCT aiColor4D emission;
|
||||||
ai_real shininess, strength;
|
ai_real shininess, strength;
|
||||||
int two_sided;
|
int two_sided;
|
||||||
int wireframe;
|
int wireframe;
|
||||||
|
@ -179,11 +179,11 @@ void apply_material(const struct aiMaterial *mtl)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------- */
|
||||||
void recursive_render (const struct aiScene *sc, const struct aiNode* nd)
|
void recursive_render (const C_STRUCT aiScene *sc, const C_STRUCT aiNode* nd)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
unsigned int n = 0, t;
|
unsigned int n = 0, t;
|
||||||
struct aiMatrix4x4 m = nd->mTransformation;
|
C_STRUCT aiMatrix4x4 m = nd->mTransformation;
|
||||||
|
|
||||||
/* update transform */
|
/* update transform */
|
||||||
aiTransposeMatrix4(&m);
|
aiTransposeMatrix4(&m);
|
||||||
|
@ -192,7 +192,7 @@ void recursive_render (const struct aiScene *sc, const struct aiNode* nd)
|
||||||
|
|
||||||
/* draw all meshes assigned to this node */
|
/* draw all meshes assigned to this node */
|
||||||
for (; n < nd->mNumMeshes; ++n) {
|
for (; n < nd->mNumMeshes; ++n) {
|
||||||
const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
|
const C_STRUCT aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
|
||||||
|
|
||||||
apply_material(sc->mMaterials[mesh->mMaterialIndex]);
|
apply_material(sc->mMaterials[mesh->mMaterialIndex]);
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ void recursive_render (const struct aiScene *sc, const struct aiNode* nd)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (t = 0; t < mesh->mNumFaces; ++t) {
|
for (t = 0; t < mesh->mNumFaces; ++t) {
|
||||||
const struct aiFace* face = &mesh->mFaces[t];
|
const C_STRUCT aiFace* face = &mesh->mFaces[t];
|
||||||
GLenum face_mode;
|
GLenum face_mode;
|
||||||
|
|
||||||
switch(face->mNumIndices) {
|
switch(face->mNumIndices) {
|
||||||
|
@ -324,7 +324,7 @@ int loadasset (const char* path)
|
||||||
/* ---------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------- */
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct aiLogStream stream;
|
C_STRUCT aiLogStream stream;
|
||||||
|
|
||||||
glutInitWindowSize(900,600);
|
glutInitWindowSize(900,600);
|
||||||
glutInitWindowPosition(100,100);
|
glutInitWindowPosition(100,100);
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,282 @@
|
||||||
|
{
|
||||||
|
"accessors": [
|
||||||
|
{
|
||||||
|
"bufferView": 0,
|
||||||
|
"componentType": 5126,
|
||||||
|
"count": 24,
|
||||||
|
"type": "VEC3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView": 1,
|
||||||
|
"componentType": 5126,
|
||||||
|
"count": 24,
|
||||||
|
"type": "VEC4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView": 2,
|
||||||
|
"componentType": 5126,
|
||||||
|
"count": 24,
|
||||||
|
"type": "VEC3",
|
||||||
|
"max": [
|
||||||
|
0.0100000035,
|
||||||
|
0.0100000035,
|
||||||
|
0.01
|
||||||
|
],
|
||||||
|
"min": [
|
||||||
|
-0.0100000044,
|
||||||
|
-0.0100000054,
|
||||||
|
-0.01
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView": 3,
|
||||||
|
"componentType": 5126,
|
||||||
|
"count": 24,
|
||||||
|
"type": "VEC3",
|
||||||
|
"name": "thin"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView": 4,
|
||||||
|
"componentType": 5126,
|
||||||
|
"count": 24,
|
||||||
|
"type": "VEC3",
|
||||||
|
"max": [
|
||||||
|
0.0,
|
||||||
|
0.01893253,
|
||||||
|
0.0
|
||||||
|
],
|
||||||
|
"min": [
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
0.0
|
||||||
|
],
|
||||||
|
"name": "thin"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView": 5,
|
||||||
|
"componentType": 5126,
|
||||||
|
"count": 24,
|
||||||
|
"type": "VEC3",
|
||||||
|
"name": "thin"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView": 6,
|
||||||
|
"componentType": 5126,
|
||||||
|
"count": 24,
|
||||||
|
"type": "VEC3",
|
||||||
|
"name": "angle"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView": 7,
|
||||||
|
"componentType": 5126,
|
||||||
|
"count": 24,
|
||||||
|
"type": "VEC3",
|
||||||
|
"max": [
|
||||||
|
0.0,
|
||||||
|
0.0198908355,
|
||||||
|
0.0
|
||||||
|
],
|
||||||
|
"min": [
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
0.0
|
||||||
|
],
|
||||||
|
"name": "angle"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView": 8,
|
||||||
|
"componentType": 5126,
|
||||||
|
"count": 24,
|
||||||
|
"type": "VEC3",
|
||||||
|
"name": "angle"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView": 9,
|
||||||
|
"componentType": 5123,
|
||||||
|
"count": 36,
|
||||||
|
"type": "SCALAR"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView": 10,
|
||||||
|
"componentType": 5126,
|
||||||
|
"count": 127,
|
||||||
|
"type": "SCALAR",
|
||||||
|
"max": [
|
||||||
|
4.19999743
|
||||||
|
],
|
||||||
|
"min": [
|
||||||
|
0.0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView": 11,
|
||||||
|
"componentType": 5126,
|
||||||
|
"count": 254,
|
||||||
|
"type": "SCALAR"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"animations": [
|
||||||
|
{
|
||||||
|
"channels": [
|
||||||
|
{
|
||||||
|
"sampler": 0,
|
||||||
|
"target": {
|
||||||
|
"node": 0,
|
||||||
|
"path": "weights"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"samplers": [
|
||||||
|
{
|
||||||
|
"input": 10,
|
||||||
|
"interpolation": "LINEAR",
|
||||||
|
"output": 11
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "Square"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"asset": {
|
||||||
|
"generator": "glTF Tools for Unity",
|
||||||
|
"version": "2.0"
|
||||||
|
},
|
||||||
|
"bufferViews": [
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteLength": 288
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteOffset": 288,
|
||||||
|
"byteLength": 384
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteOffset": 672,
|
||||||
|
"byteLength": 288
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteOffset": 960,
|
||||||
|
"byteLength": 288
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteOffset": 1248,
|
||||||
|
"byteLength": 288
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteOffset": 1536,
|
||||||
|
"byteLength": 288
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteOffset": 1824,
|
||||||
|
"byteLength": 288
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteOffset": 2112,
|
||||||
|
"byteLength": 288
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteOffset": 2400,
|
||||||
|
"byteLength": 288
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteOffset": 2688,
|
||||||
|
"byteLength": 72
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteOffset": 2760,
|
||||||
|
"byteLength": 508
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteOffset": 3268,
|
||||||
|
"byteLength": 1016
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buffers": [
|
||||||
|
{
|
||||||
|
"uri": "AnimatedMorphCube.bin",
|
||||||
|
"byteLength": 4284
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meshes": [
|
||||||
|
{
|
||||||
|
"primitives": [
|
||||||
|
{
|
||||||
|
"attributes": {
|
||||||
|
"NORMAL": 0,
|
||||||
|
"TANGENT": 1,
|
||||||
|
"POSITION": 2
|
||||||
|
},
|
||||||
|
"indices": 9,
|
||||||
|
"material": 0,
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"NORMAL": 3,
|
||||||
|
"POSITION": 4,
|
||||||
|
"TANGENT": 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"NORMAL": 6,
|
||||||
|
"POSITION": 7,
|
||||||
|
"TANGENT": 8
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"weights": [
|
||||||
|
0.0,
|
||||||
|
0.0
|
||||||
|
],
|
||||||
|
"name": "Cube"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"materials": [
|
||||||
|
{
|
||||||
|
"pbrMetallicRoughness": {
|
||||||
|
"baseColorFactor": [
|
||||||
|
0.6038274,
|
||||||
|
0.6038274,
|
||||||
|
0.6038274,
|
||||||
|
1.0
|
||||||
|
],
|
||||||
|
"metallicFactor": 0.0,
|
||||||
|
"roughnessFactor": 0.5
|
||||||
|
},
|
||||||
|
"name": "Material"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"mesh": 0,
|
||||||
|
"rotation": [
|
||||||
|
0.0,
|
||||||
|
0.7071067,
|
||||||
|
-0.7071068,
|
||||||
|
0.0
|
||||||
|
],
|
||||||
|
"scale": [
|
||||||
|
100.0,
|
||||||
|
100.0,
|
||||||
|
100.0
|
||||||
|
],
|
||||||
|
"name": "AnimatedMorphCube"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"scene": 0,
|
||||||
|
"scenes": [
|
||||||
|
{
|
||||||
|
"nodes": [
|
||||||
|
0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -123,7 +123,7 @@ void SceneDiffer::showReport() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( std::vector<std::string>::iterator it = m_diffs.begin(); it != m_diffs.end(); it++ ) {
|
for ( std::vector<std::string>::iterator it = m_diffs.begin(); it != m_diffs.end(); ++it ) {
|
||||||
std::cout << *it << "\n";
|
std::cout << *it << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -380,4 +380,13 @@ TEST_F( utglTF2ImportExport, exportglTF2FromFileTest ) {
|
||||||
EXPECT_TRUE( exporterTest() );
|
EXPECT_TRUE( exporterTest() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F( utglTF2ImportExport, crash_in_anim_mesh_destructor ) {
|
||||||
|
Assimp::Importer importer;
|
||||||
|
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Sample-Models/AnimatedMorphCube-glTF/AnimatedMorphCube.gltf",
|
||||||
|
aiProcess_ValidateDataStructure);
|
||||||
|
ASSERT_NE( nullptr, scene );
|
||||||
|
Assimp::Exporter exporter;
|
||||||
|
ASSERT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "glb2", ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Sample-Models/AnimatedMorphCube-glTF/AnimatedMorphCube_out.glTF"));
|
||||||
|
}
|
||||||
|
|
||||||
#endif // ASSIMP_BUILD_NO_EXPORT
|
#endif // ASSIMP_BUILD_NO_EXPORT
|
||||||
|
|
|
@ -203,7 +203,7 @@ void CGLView::Matrix_NodeToRoot(const aiNode* pNode, aiMatrix4x4& pOutMatrix)
|
||||||
}
|
}
|
||||||
|
|
||||||
// multiply all matrices in reverse order
|
// multiply all matrices in reverse order
|
||||||
for ( std::list<aiMatrix4x4>::reverse_iterator rit = mat_list.rbegin(); rit != mat_list.rend(); rit++)
|
for ( std::list<aiMatrix4x4>::reverse_iterator rit = mat_list.rbegin(); rit != mat_list.rend(); ++rit)
|
||||||
{
|
{
|
||||||
pOutMatrix = pOutMatrix * (*rit);
|
pOutMatrix = pOutMatrix * (*rit);
|
||||||
}
|
}
|
||||||
|
@ -729,7 +729,7 @@ void CGLView::FreeScene() {
|
||||||
GLuint* id_tex = new GLuint[id_tex_size];
|
GLuint* id_tex = new GLuint[id_tex_size];
|
||||||
QMap<QString, GLuint>::iterator it = mTexture_IDMap.begin();
|
QMap<QString, GLuint>::iterator it = mTexture_IDMap.begin();
|
||||||
|
|
||||||
for(int idx = 0; idx < id_tex_size; idx++, it++)
|
for(int idx = 0; idx < id_tex_size; idx++, ++it)
|
||||||
{
|
{
|
||||||
id_tex[idx] = it.value();
|
id_tex[idx] = it.value();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue