Merge branch 'master' into new_obj_stream_handling

pull/1043/head
Kim Kulling 2016-10-22 21:04:02 +02:00
commit cbe2e9af49
58 changed files with 840 additions and 11256 deletions

1
.gitignore vendored
View File

@ -31,6 +31,7 @@ assimp-config-version.cmake
# MakeFile # MakeFile
Makefile Makefile
code/Makefile
test/Makefile test/Makefile
test/headercheck/Makefile test/headercheck/Makefile
tools/assimp_cmd/Makefile tools/assimp_cmd/Makefile

View File

@ -77,6 +77,7 @@ OPTION ( ASSIMP_BUILD_TESTS
ON ON
) )
IF(MSVC) IF(MSVC)
set (CMAKE_PREFIX_PATH "D:\\libs\\devil")
OPTION( ASSIMP_INSTALL_PDB OPTION( ASSIMP_INSTALL_PDB
"Install MSVC debug files." "Install MSVC debug files."
ON ON
@ -336,10 +337,10 @@ IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
# Why here? Maybe user do not want Qt viewer and have no Qt. # Why here? Maybe user do not want Qt viewer and have no Qt.
# Why assimp_qt_viewer/CMakeLists.txt still contain similar check? # Why assimp_qt_viewer/CMakeLists.txt still contain similar check?
# Because viewer can be build independently of Assimp. # Because viewer can be build independently of Assimp.
FIND_PACKAGE(Qt5 QUIET) FIND_PACKAGE(Qt5Widgets QUIET)
FIND_PACKAGE(DevIL QUIET) FIND_PACKAGE(DevIL QUIET)
FIND_PACKAGE(OpenGL QUIET) FIND_PACKAGE(OpenGL QUIET)
IF ( Qt5_FOUND AND IL_FOUND AND OPENGL_FOUND) IF ( Qt5Widgets_FOUND AND IL_FOUND AND OPENGL_FOUND)
ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ ) ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ )
ELSE() ELSE()
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "") SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "")
@ -356,7 +357,7 @@ IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
ENDIF (NOT OPENGL_FOUND) ENDIF (NOT OPENGL_FOUND)
MESSAGE (WARNING "Build of assimp_qt_viewer is disabled. Unsatisfied dendencies: ${ASSIMP_QT_VIEWER_DEPENDENCIES}") MESSAGE (WARNING "Build of assimp_qt_viewer is disabled. Unsatisfied dendencies: ${ASSIMP_QT_VIEWER_DEPENDENCIES}")
ENDIF ( Qt5_FOUND AND IL_FOUND AND OPENGL_FOUND) ENDIF ( Qt5Widgets_FOUND AND IL_FOUND AND OPENGL_FOUND)
ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS ) ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
IF ( ASSIMP_BUILD_SAMPLES) IF ( ASSIMP_BUILD_SAMPLES)

View File

@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Header files, Assimp. // Header files, Assimp.
#include "SceneCombiner.h" #include "SceneCombiner.h"
#include "StandardShapes.h" #include "StandardShapes.h"
#include "StringUtils.h"
// Header files, stdlib. // Header files, stdlib.
#include <algorithm> #include <algorithm>
@ -950,7 +951,7 @@ nl_clean_loop:
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials]; pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
for(const SPP_Texture& tex_convd: mTexture_Converted) for(const SPP_Texture& tex_convd: mTexture_Converted)
{ {
const aiString texture_id(AI_EMBEDDED_TEXNAME_PREFIX + std::to_string(idx)); const aiString texture_id(AI_EMBEDDED_TEXNAME_PREFIX + to_string(idx));
const int mode = aiTextureOp_Multiply; const int mode = aiTextureOp_Multiply;
const int repeat = tex_convd.Tiled ? 1 : 0; const int repeat = tex_convd.Tiled ? 1 : 0;

View File

@ -70,11 +70,11 @@ ASSIMP_API const aiExportFormatDesc* aiGetExportFormatDescription( size_t index)
} }
aiExportFormatDesc *desc = new aiExportFormatDesc; aiExportFormatDesc *desc = new aiExportFormatDesc;
desc->description = new char[ strlen( orig->description ) + 1 ]; desc->description = new char[ strlen( orig->description ) + 1 ]();
::strncpy( (char*) desc->description, orig->description, strlen( orig->description ) ); ::strncpy( (char*) desc->description, orig->description, strlen( orig->description ) );
desc->fileExtension = new char[ strlen( orig->fileExtension ) + 1 ]; desc->fileExtension = new char[ strlen( orig->fileExtension ) + 1 ]();
::strncpy( ( char* ) desc->fileExtension, orig->fileExtension, strlen( orig->fileExtension ) ); ::strncpy( ( char* ) desc->fileExtension, orig->fileExtension, strlen( orig->fileExtension ) );
desc->id = new char[ strlen( orig->id ) + 1 ]; desc->id = new char[ strlen( orig->id ) + 1 ]();
::strncpy( ( char* ) desc->id, orig->id, strlen( orig->id ) ); ::strncpy( ( char* ) desc->id, orig->id, strlen( orig->id ) );
return desc; return desc;

View File

@ -299,7 +299,7 @@ void WriteDump(const aiScene* scene, IOStream* io, bool shortened) {
else if (!shortened){ else if (!shortened){
ioprintf(io,"\t\t<Data length=\"%i\"> \n",tex->mWidth*tex->mHeight*4); ioprintf(io,"\t\t<Data length=\"%i\"> \n",tex->mWidth*tex->mHeight*4);
// const unsigned int width = (unsigned int)log10((double)std::max(tex->mHeight,tex->mWidth))+1; // const unsigned int width = (unsigned int)std::log10((double)std::max(tex->mHeight,tex->mWidth))+1;
for (unsigned int y = 0; y < tex->mHeight;++y) { for (unsigned int y = 0; y < tex->mHeight;++y) {
for (unsigned int x = 0; x < tex->mWidth;++x) { for (unsigned int x = 0; x < tex->mWidth;++x) {
aiTexel* tx = tex->pcData + y*tex->mWidth+x; aiTexel* tx = tex->pcData + y*tex->mWidth+x;
@ -457,7 +457,7 @@ void WriteDump(const aiScene* scene, IOStream* io, bool shortened) {
ioprintf(io,"<MeshList num=\"%i\">\n",scene->mNumMeshes); ioprintf(io,"<MeshList num=\"%i\">\n",scene->mNumMeshes);
for (unsigned int i = 0; i < scene->mNumMeshes;++i) { for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
aiMesh* mesh = scene->mMeshes[i]; aiMesh* mesh = scene->mMeshes[i];
// const unsigned int width = (unsigned int)log10((double)mesh->mNumVertices)+1; // const unsigned int width = (unsigned int)std::log10((double)mesh->mNumVertices)+1;
// mesh header // mesh header
ioprintf(io,"\t<Mesh types=\"%s %s %s %s\" material_index=\"%i\">\n", ioprintf(io,"\t<Mesh types=\"%s %s %s %s\" material_index=\"%i\">\n",

View File

@ -1143,7 +1143,7 @@ aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* obj,
out->mUp = aiVector3D(0.f, 1.f, 0.f); out->mUp = aiVector3D(0.f, 1.f, 0.f);
out->mLookAt = aiVector3D(0.f, 0.f, -1.f); out->mLookAt = aiVector3D(0.f, 0.f, -1.f);
if (cam->sensor_x && cam->lens) { if (cam->sensor_x && cam->lens) {
out->mHorizontalFOV = atan2(cam->sensor_x, 2.f * cam->lens); out->mHorizontalFOV = std::atan2(cam->sensor_x, 2.f * cam->lens);
} }
out->mClipPlaneNear = cam->clipsta; out->mClipPlaneNear = cam->clipsta;
out->mClipPlaneFar = cam->clipend; out->mClipPlaneFar = cam->clipend;

View File

@ -0,0 +1,134 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2016, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/** @file aiFileIO -> IOSystem wrapper*/
#include "CInterfaceIOWrapper.h"
namespace Assimp {
CIOStreamWrapper::~CIOStreamWrapper(void)
{
/* Various places depend on this destructor to close the file */
if (mFile) {
mIO->mFileSystem->CloseProc(mIO->mFileSystem, mFile);
mFile = nullptr;
}
}
// ...................................................................
size_t CIOStreamWrapper::Read(void* pvBuffer,
size_t pSize,
size_t pCount
){
// need to typecast here as C has no void*
return mFile->ReadProc(mFile,(char*)pvBuffer,pSize,pCount);
}
// ...................................................................
size_t CIOStreamWrapper::Write(const void* pvBuffer,
size_t pSize,
size_t pCount
){
// need to typecast here as C has no void*
return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount);
}
// ...................................................................
aiReturn CIOStreamWrapper::Seek(size_t pOffset,
aiOrigin pOrigin
){
return mFile->SeekProc(mFile,pOffset,pOrigin);
}
// ...................................................................
size_t CIOStreamWrapper::Tell(void) const {
return mFile->TellProc(mFile);
}
// ...................................................................
size_t CIOStreamWrapper::FileSize() const {
return mFile->FileSizeProc(mFile);
}
// ...................................................................
void CIOStreamWrapper::Flush () {
return mFile->FlushProc(mFile);
}
// ------------------------------------------------------------------------------------------------
// Custom IOStream implementation for the C-API
bool CIOSystemWrapper::Exists( const char* pFile) const {
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,"rb");
if (p){
mFileSystem->CloseProc(mFileSystem,p);
return true;
}
return false;
}
// ...................................................................
char CIOSystemWrapper::getOsSeparator() const {
#ifndef _WIN32
return '/';
#else
return '\\';
#endif
}
// ...................................................................
IOStream* CIOSystemWrapper::Open(const char* pFile,const char* pMode) {
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,pMode);
if (!p) {
return NULL;
}
return new CIOStreamWrapper(p, this);
}
// ...................................................................
void CIOSystemWrapper::Close( IOStream* pFile) {
if (!pFile) {
return;
}
delete pFile;
}
}

View File

@ -50,106 +50,43 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp { namespace Assimp {
class CIOSystemWrapper;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Custom IOStream implementation for the C-API // Custom IOStream implementation for the C-API
class CIOStreamWrapper : public IOStream class CIOStreamWrapper : public IOStream
{ {
friend class CIOSystemWrapper;
public: public:
explicit CIOStreamWrapper(aiFile* pFile, CIOSystemWrapper* io)
explicit CIOStreamWrapper(aiFile* pFile) : mFile(pFile),
: mFile(pFile) mIO(io)
{} {}
~CIOStreamWrapper(void);
// ................................................................... size_t Read(void* pvBuffer, size_t pSize, size_t pCount);
size_t Read(void* pvBuffer, size_t Write(const void* pvBuffer, size_t pSize, size_t pCount);
size_t pSize, aiReturn Seek(size_t pOffset, aiOrigin pOrigin);
size_t pCount size_t Tell(void) const;
){ size_t FileSize() const;
// need to typecast here as C has no void* void Flush();
return mFile->ReadProc(mFile,(char*)pvBuffer,pSize,pCount);
}
// ...................................................................
size_t Write(const void* pvBuffer,
size_t pSize,
size_t pCount
){
// need to typecast here as C has no void*
return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount);
}
// ...................................................................
aiReturn Seek(size_t pOffset,
aiOrigin pOrigin
){
return mFile->SeekProc(mFile,pOffset,pOrigin);
}
// ...................................................................
size_t Tell(void) const {
return mFile->TellProc(mFile);
}
// ...................................................................
size_t FileSize() const {
return mFile->FileSizeProc(mFile);
}
// ...................................................................
void Flush () {
return mFile->FlushProc(mFile);
}
private: private:
aiFile* mFile; aiFile* mFile;
CIOSystemWrapper* mIO;
}; };
// ------------------------------------------------------------------------------------------------
// Custom IOStream implementation for the C-API
class CIOSystemWrapper : public IOSystem class CIOSystemWrapper : public IOSystem
{ {
friend class CIOStreamWrapper;
public: public:
explicit CIOSystemWrapper(aiFileIO* pFile) explicit CIOSystemWrapper(aiFileIO* pFile)
: mFileSystem(pFile) : mFileSystem(pFile)
{} {}
// ................................................................... bool Exists( const char* pFile) const;
bool Exists( const char* pFile) const { char getOsSeparator() const;
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,"rb"); IOStream* Open(const char* pFile,const char* pMode = "rb");
if (p){ void Close( IOStream* pFile);
mFileSystem->CloseProc(mFileSystem,p);
return true;
}
return false;
}
// ...................................................................
char getOsSeparator() const {
#ifndef _WIN32
return '/';
#else
return '\\';
#endif
}
// ...................................................................
IOStream* Open(const char* pFile,const char* pMode = "rb") {
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,pMode);
if (!p) {
return NULL;
}
return new CIOStreamWrapper(p);
}
// ...................................................................
void Close( IOStream* pFile) {
if (!pFile) {
return;
}
mFileSystem->CloseProc(mFileSystem,((CIOStreamWrapper*) pFile)->mFile);
delete pFile;
}
private: private:
aiFileIO* mFileSystem; aiFileIO* mFileSystem;
}; };

View File

@ -128,6 +128,7 @@ SET( Common_SRCS
DefaultIOStream.h DefaultIOStream.h
DefaultIOSystem.cpp DefaultIOSystem.cpp
DefaultIOSystem.h DefaultIOSystem.h
CInterfaceIOWrapper.cpp
CInterfaceIOWrapper.h CInterfaceIOWrapper.h
Hash.h Hash.h
Importer.cpp Importer.cpp

View File

@ -256,7 +256,7 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
} }
std::vector<unsigned int> verticesFound; std::vector<unsigned int> verticesFound;
const float fLimit = cosf(configMaxAngle); const float fLimit = std::cos(configMaxAngle);
std::vector<unsigned int> closeVertices; std::vector<unsigned int> closeVertices;
// in the second pass we now smooth out all tangents and bitangents at the same local position // in the second pass we now smooth out all tangents and bitangents at the same local position

View File

@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "fast_atof.h" #include "fast_atof.h"
#include "SceneCombiner.h" #include "SceneCombiner.h"
#include "DefaultIOSystem.h" #include "DefaultIOSystem.h"
#include "StringUtils.h"
#include "XMLTools.h" #include "XMLTools.h"
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <assimp/Exporter.hpp> #include <assimp/Exporter.hpp>
@ -637,7 +638,7 @@ void ColladaExporter::WriteMaterials()
aiString name; aiString name;
if( mat->Get( AI_MATKEY_NAME, name) != aiReturn_SUCCESS ) if( mat->Get( AI_MATKEY_NAME, name) != aiReturn_SUCCESS )
name = "mat"; name = "mat";
materials[a].name = std::string( "m") + std::to_string(a) + name.C_Str(); materials[a].name = std::string( "m") + to_string(a) + name.C_Str();
for( std::string::iterator it = materials[a].name.begin(); it != materials[a].name.end(); ++it ) { for( std::string::iterator it = materials[a].name.begin(); it != materials[a].name.end(); ++it ) {
if( !isalnum_C( *it ) ) { if( !isalnum_C( *it ) ) {
*it = '_'; *it = '_';
@ -813,7 +814,7 @@ void ColladaExporter::WriteGeometry( size_t pIndex)
{ {
if( mesh->HasTextureCoords( a) ) if( mesh->HasTextureCoords( a) )
{ {
WriteFloatArray( idstr + "-tex" + std::to_string(a), mesh->mNumUVComponents[a] == 3 ? FloatType_TexCoord3 : FloatType_TexCoord2, WriteFloatArray( idstr + "-tex" + to_string(a), mesh->mNumUVComponents[a] == 3 ? FloatType_TexCoord3 : FloatType_TexCoord2,
(ai_real*) mesh->mTextureCoords[a], mesh->mNumVertices); (ai_real*) mesh->mTextureCoords[a], mesh->mNumVertices);
} }
} }
@ -822,7 +823,7 @@ void ColladaExporter::WriteGeometry( size_t pIndex)
for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a)
{ {
if( mesh->HasVertexColors( a) ) if( mesh->HasVertexColors( a) )
WriteFloatArray( idstr + "-color" + std::to_string(a), FloatType_Color, (ai_real*) mesh->mColors[a], mesh->mNumVertices); WriteFloatArray( idstr + "-color" + to_string(a), FloatType_Color, (ai_real*) mesh->mColors[a], mesh->mNumVertices);
} }
// assemble vertex structure // assemble vertex structure

View File

@ -53,6 +53,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <vector> #include <vector>
#include <map> #include <map>
#include "StringUtils.h"
struct aiScene; struct aiScene;
struct aiNode; struct aiNode;
@ -122,7 +124,9 @@ protected:
void PopTag() { ai_assert( startstr.length() > 1); startstr.erase( startstr.length() - 2); } void PopTag() { ai_assert( startstr.length() > 1); startstr.erase( startstr.length() - 2); }
/// Creates a mesh ID for the given mesh /// Creates a mesh ID for the given mesh
std::string GetMeshId( size_t pIndex) const { return std::string( "meshId" ) + std::to_string(pIndex); } std::string GetMeshId( size_t pIndex) const {
return std::string( "meshId" ) + to_string(pIndex);
}
public: public:
/// Stringstream to write all output into /// Stringstream to write all output into

View File

@ -420,13 +420,13 @@ void ColladaLoader::BuildCamerasForNode( const ColladaParser& pParser, const Col
out->mHorizontalFOV = srcCamera->mHorFov; out->mHorizontalFOV = srcCamera->mHorFov;
if (srcCamera->mVerFov != 10e10f && srcCamera->mAspect == 10e10f) { if (srcCamera->mVerFov != 10e10f && srcCamera->mAspect == 10e10f) {
out->mAspect = tan(AI_DEG_TO_RAD(srcCamera->mHorFov)) / out->mAspect = std::tan(AI_DEG_TO_RAD(srcCamera->mHorFov)) /
tan(AI_DEG_TO_RAD(srcCamera->mVerFov)); std::tan(AI_DEG_TO_RAD(srcCamera->mVerFov));
} }
} }
else if (srcCamera->mAspect != 10e10f && srcCamera->mVerFov != 10e10f) { else if (srcCamera->mAspect != 10e10f && srcCamera->mVerFov != 10e10f) {
out->mHorizontalFOV = 2.0f * AI_RAD_TO_DEG(atan(srcCamera->mAspect * out->mHorizontalFOV = 2.0f * AI_RAD_TO_DEG(std::atan(srcCamera->mAspect *
tan(AI_DEG_TO_RAD(srcCamera->mVerFov) * 0.5f))); std::tan(AI_DEG_TO_RAD(srcCamera->mVerFov) * 0.5f)));
} }
// Collada uses degrees, we use radians // Collada uses degrees, we use radians
@ -1181,7 +1181,7 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
const ai_real last_eval_angle = last_key_angle + (cur_key_angle - last_key_angle) * (time - last_key_time) / (cur_key_time - last_key_time); const ai_real last_eval_angle = last_key_angle + (cur_key_angle - last_key_angle) * (time - last_key_time) / (cur_key_time - last_key_time);
const ai_real delta = std::abs(cur_key_angle - last_eval_angle); const ai_real delta = std::abs(cur_key_angle - last_eval_angle);
if (delta >= 180.0) { if (delta >= 180.0) {
const int subSampleCount = static_cast<int>(floorf(delta / 90.0)); const int subSampleCount = static_cast<int>(std::floor(delta / 90.0));
if (cur_key_time != time) { if (cur_key_time != time) {
const ai_real nextSampleTime = time + (cur_key_time - time) / subSampleCount; const ai_real nextSampleTime = time + (cur_key_time - time) / subSampleCount;
nextTime = std::min(nextTime, nextSampleTime); nextTime = std::min(nextTime, nextSampleTime);

View File

@ -300,7 +300,7 @@ void ColladaParser::ReadAnimationClipLibrary()
else if (indexID >= 0) else if (indexID >= 0)
animName = mReader->getAttributeValue(indexID); animName = mReader->getAttributeValue(indexID);
else else
animName = std::string("animation_") + std::to_string(mAnimationClipLibrary.size()); animName = std::string("animation_") + to_string(mAnimationClipLibrary.size());
std::pair<std::string, std::vector<std::string> > clip; std::pair<std::string, std::vector<std::string> > clip;

View File

@ -206,7 +206,7 @@ void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D
// lon = arctan (y/x) // lon = arctan (y/x)
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize(); const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
out[pnt] = aiVector3D((atan2 (diff.z, diff.y) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F, out[pnt] = aiVector3D((std::atan2(diff.z, diff.y) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
(std::asin (diff.x) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0); (std::asin (diff.x) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
} }
} }
@ -214,7 +214,7 @@ void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D
// ... just the same again // ... just the same again
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize(); const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
out[pnt] = aiVector3D((atan2 (diff.x, diff.z) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F, out[pnt] = aiVector3D((std::atan2(diff.x, diff.z) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
(std::asin (diff.y) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0); (std::asin (diff.y) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
} }
} }
@ -222,7 +222,7 @@ void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D
// ... just the same again // ... just the same again
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize(); const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
out[pnt] = aiVector3D((atan2 (diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F, out[pnt] = aiVector3D((std::atan2(diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
(std::asin (diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0); (std::asin (diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
} }
} }
@ -234,8 +234,8 @@ void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D
// again the same, except we're applying a transformation now // again the same, except we're applying a transformation now
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
const aiVector3D diff = ((mTrafo*mesh->mVertices[pnt])-center).Normalize(); const aiVector3D diff = ((mTrafo*mesh->mVertices[pnt])-center).Normalize();
out[pnt] = aiVector3D((atan2 (diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F, out[pnt] = aiVector3D((std::atan2(diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
(asin (diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0); (std::asin(diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
} }
} }
@ -268,7 +268,7 @@ void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,const aiVector
aiVector3D& uv = out[pnt]; aiVector3D& uv = out[pnt];
uv.y = (pos.x - min.x) / diff; uv.y = (pos.x - min.x) / diff;
uv.x = (atan2 ( pos.z - center.z, pos.y - center.y) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI; uv.x = (std::atan2( pos.z - center.z, pos.y - center.y) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI;
} }
} }
else if (axis * base_axis_y >= angle_epsilon) { else if (axis * base_axis_y >= angle_epsilon) {
@ -281,7 +281,7 @@ void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,const aiVector
aiVector3D& uv = out[pnt]; aiVector3D& uv = out[pnt];
uv.y = (pos.y - min.y) / diff; uv.y = (pos.y - min.y) / diff;
uv.x = (atan2 ( pos.x - center.x, pos.z - center.z) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI; uv.x = (std::atan2( pos.x - center.x, pos.z - center.z) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI;
} }
} }
else if (axis * base_axis_z >= angle_epsilon) { else if (axis * base_axis_z >= angle_epsilon) {
@ -294,7 +294,7 @@ void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,const aiVector
aiVector3D& uv = out[pnt]; aiVector3D& uv = out[pnt];
uv.y = (pos.z - min.z) / diff; uv.y = (pos.z - min.z) / diff;
uv.x = (atan2 ( pos.y - center.y, pos.x - center.x) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI; uv.x = (std::atan2( pos.y - center.y, pos.x - center.x) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI;
} }
} }
// slower code path in case the mapping axis is not one of the coordinate system axes // slower code path in case the mapping axis is not one of the coordinate system axes
@ -310,7 +310,7 @@ void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,const aiVector
aiVector3D& uv = out[pnt]; aiVector3D& uv = out[pnt];
uv.y = (pos.y - min.y) / diff; uv.y = (pos.y - min.y) / diff;
uv.x = (atan2 ( pos.x - center.x, pos.z - center.z) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI; uv.x = (std::atan2( pos.x - center.x, pos.z - center.z) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI;
} }
} }

View File

@ -44,8 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/IOStream.hpp> #include <assimp/IOStream.hpp>
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <contrib/unzip/unzip.h>
#include "irrXMLWrapper.h"
#include "StringComparison.h" #include "StringComparison.h"
#include "StringUtils.h" #include "StringUtils.h"
@ -61,10 +59,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/ai_assert.h> #include <assimp/ai_assert.h>
#include "D3MFOpcPackage.h"
#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER #ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
#include "D3MFOpcPackage.h"
#include <contrib/unzip/unzip.h>
#include "irrXMLWrapper.h"
namespace Assimp { namespace Assimp {
namespace D3MF { namespace D3MF {
@ -148,14 +148,21 @@ private:
std::vector<unsigned long> meshIds; std::vector<unsigned long> meshIds;
int id = std::atoi(xmlReader->getAttributeValue(D3MF::XmlTag::id.c_str())); const char *attrib( nullptr );
std::string name(xmlReader->getAttributeValue(D3MF::XmlTag::name.c_str())); std::string name, type;
std::string type(xmlReader->getAttributeValue(D3MF::XmlTag::type.c_str())); attrib = xmlReader->getAttributeValue( D3MF::XmlTag::name.c_str() );
if ( nullptr != attrib ) {
name = attrib;
}
attrib = xmlReader->getAttributeValue( D3MF::XmlTag::name.c_str() );
if ( nullptr != attrib ) {
type = attrib;
}
node->mParent = scene->mRootNode; node->mParent = scene->mRootNode;
node->mName.Set(name); node->mName.Set(name);
unsigned long meshIdx = meshes.size(); size_t meshIdx = meshes.size();
while(ReadToEndElement(D3MF::XmlTag::object)) while(ReadToEndElement(D3MF::XmlTag::object))
{ {

View File

@ -42,7 +42,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "D3MFOpcPackage.h" #include "D3MFOpcPackage.h"
#include "Exceptional.h" #include "Exceptional.h"
#include <contrib/unzip/unzip.h>
#include <assimp/IOStream.hpp> #include <assimp/IOStream.hpp>
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
@ -57,6 +56,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER #ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
#include <contrib/unzip/unzip.h>
namespace Assimp { namespace Assimp {
namespace D3MF { namespace D3MF {

View File

@ -120,7 +120,7 @@ size_t DefaultIOStream::FileSize() const
// //
// See here for details: // See here for details:
// https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file // https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file
#if defined _WIN32 && !defined __GNUC__ #if defined _WIN32
struct __stat64 fileStat; struct __stat64 fileStat;
int err = _stat64( mFilename.c_str(), &fileStat ); int err = _stat64( mFilename.c_str(), &fileStat );
if (0 != err) if (0 != err)

View File

@ -55,6 +55,46 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp { namespace Assimp {
namespace FBX { namespace FBX {
enum Flag
{
e_unknown_0 = 1 << 0,
e_unknown_1 = 1 << 1,
e_unknown_2 = 1 << 2,
e_unknown_3 = 1 << 3,
e_unknown_4 = 1 << 4,
e_unknown_5 = 1 << 5,
e_unknown_6 = 1 << 6,
e_unknown_7 = 1 << 7,
e_unknown_8 = 1 << 8,
e_unknown_9 = 1 << 9,
e_unknown_10 = 1 << 10,
e_unknown_11 = 1 << 11,
e_unknown_12 = 1 << 12,
e_unknown_13 = 1 << 13,
e_unknown_14 = 1 << 14,
e_unknown_15 = 1 << 15,
e_unknown_16 = 1 << 16,
e_unknown_17 = 1 << 17,
e_unknown_18 = 1 << 18,
e_unknown_19 = 1 << 19,
e_unknown_20 = 1 << 20,
e_unknown_21 = 1 << 21,
e_unknown_22 = 1 << 22,
e_unknown_23 = 1 << 23,
e_flag_field_size_64_bit = 1 << 24, // Not sure what is
e_unknown_25 = 1 << 25,
e_unknown_26 = 1 << 26,
e_unknown_27 = 1 << 27,
e_unknown_28 = 1 << 28,
e_unknown_29 = 1 << 29,
e_unknown_30 = 1 << 30,
e_unknown_31 = 1 << 31
};
bool check_flag(uint32_t flags, Flag to_check)
{
return (flags & to_check) != 0;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int offset) Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int offset)
@ -118,6 +158,21 @@ uint32_t ReadWord(const char* input, const char*& cursor, const char* end)
return word; return word;
} }
uint64_t ReadDoubleWord(const char* input, const char*& cursor, const char* end)
{
const size_t k_to_read = sizeof(uint64_t);
if(Offset(cursor, end) < k_to_read) {
TokenizeError("cannot ReadDoubleWord, out of bounds",input, cursor);
}
uint64_t dword = *reinterpret_cast<const uint64_t*>(cursor);
AI_SWAP8(dword);
cursor += k_to_read;
return dword;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
uint8_t ReadByte(const char* input, const char*& cursor, const char* end) uint8_t ReadByte(const char* input, const char*& cursor, const char* end)
@ -287,10 +342,10 @@ void ReadData(const char*& sbegin_out, const char*& send_out, const char* input,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, const char* end) bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, const char* end, uint32_t const flags)
{ {
// the first word contains the offset at which this block ends // the first word contains the offset at which this block ends
const uint32_t end_offset = ReadWord(input, cursor, end); const uint64_t end_offset = check_flag(flags, e_flag_field_size_64_bit) ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end);
// we may get 0 if reading reached the end of the file - // we may get 0 if reading reached the end of the file -
// fbx files have a mysterious extra footer which I don't know // fbx files have a mysterious extra footer which I don't know
@ -308,10 +363,10 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
} }
// the second data word contains the number of properties in the scope // the second data word contains the number of properties in the scope
const uint32_t prop_count = ReadWord(input, cursor, end); const uint64_t prop_count = check_flag(flags, e_flag_field_size_64_bit) ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end);
// the third data word contains the length of the property list // the third data word contains the length of the property list
const uint32_t prop_length = ReadWord(input, cursor, end); const uint64_t prop_length = check_flag(flags, e_flag_field_size_64_bit) ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end);
// now comes the name of the scope/key // now comes the name of the scope/key
const char* sbeg, *send; const char* sbeg, *send;
@ -337,29 +392,28 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
// at the end of each nested block, there is a NUL record to indicate // at the end of each nested block, there is a NUL record to indicate
// that the sub-scope exists (i.e. to distinguish between P: and P : {}) // that the sub-scope exists (i.e. to distinguish between P: and P : {})
// this NUL record is 13 bytes long. // this NUL record is 13 bytes long on 32 bit version and 25 bytes long on 64 bit.
#define BLOCK_SENTINEL_LENGTH 13 const size_t sentinel_block_length = check_flag(flags, e_flag_field_size_64_bit) ? (sizeof(uint64_t) * 3 + 1) : (sizeof(uint32_t) * 3 + 1);
if (Offset(input, cursor) < end_offset) { if (Offset(input, cursor) < end_offset) {
if (end_offset - Offset(input, cursor) < sentinel_block_length) {
if (end_offset - Offset(input, cursor) < BLOCK_SENTINEL_LENGTH) {
TokenizeError("insufficient padding bytes at block end",input, cursor); TokenizeError("insufficient padding bytes at block end",input, cursor);
} }
output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_OPEN_BRACKET, Offset(input, cursor) )); output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_OPEN_BRACKET, Offset(input, cursor) ));
// XXX this is vulnerable to stack overflowing .. // XXX this is vulnerable to stack overflowing ..
while(Offset(input, cursor) < end_offset - BLOCK_SENTINEL_LENGTH) { while(Offset(input, cursor) < end_offset - sentinel_block_length) {
ReadScope(output_tokens, input, cursor, input + end_offset - BLOCK_SENTINEL_LENGTH); ReadScope(output_tokens, input, cursor, input + end_offset - sentinel_block_length, flags);
} }
output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_CLOSE_BRACKET, Offset(input, cursor) )); output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_CLOSE_BRACKET, Offset(input, cursor) ));
for (unsigned int i = 0; i < BLOCK_SENTINEL_LENGTH; ++i) { for (unsigned int i = 0; i < sentinel_block_length; ++i) {
if(cursor[i] != '\0') { if(cursor[i] != '\0') {
TokenizeError("failed to read nested block sentinel, expected all bytes to be 0",input, cursor); TokenizeError("failed to read nested block sentinel, expected all bytes to be 0",input, cursor);
} }
} }
cursor += BLOCK_SENTINEL_LENGTH; cursor += sentinel_block_length;
} }
if (Offset(input, cursor) != end_offset) { if (Offset(input, cursor) != end_offset) {
@ -386,12 +440,17 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int le
} }
//uint32_t offset = 0x1b; //uint32_t offset = 0x15;
const char* cursor = input + 0x15;
const char* cursor = input + 0x1b; const uint32_t flags = ReadWord(input, cursor, input + length);
while (cursor < input + length) { const uint8_t padding_0 = ReadByte(input, cursor, input + length); // unused
if(!ReadScope(output_tokens, input, cursor, input + length)) { const uint8_t padding_1 = ReadByte(input, cursor, input + length); // unused
while (cursor < input + length)
{
if(!ReadScope(output_tokens, input, cursor, input + length, flags)) {
break; break;
} }
} }

View File

@ -148,9 +148,9 @@ bool FixInfacingNormalsProcess::ProcessMesh( aiMesh* pcMesh, unsigned int index)
// Check whether this is a planar surface // Check whether this is a planar surface
const float fDelta1_yz = fDelta1_y * fDelta1_z; const float fDelta1_yz = fDelta1_y * fDelta1_z;
if (fDelta1_x < 0.05f * sqrtf( fDelta1_yz ))return false; if (fDelta1_x < 0.05f * std::sqrt( fDelta1_yz ))return false;
if (fDelta1_y < 0.05f * sqrtf( fDelta1_z * fDelta1_x ))return false; if (fDelta1_y < 0.05f * std::sqrt( fDelta1_z * fDelta1_x ))return false;
if (fDelta1_z < 0.05f * sqrtf( fDelta1_y * fDelta1_x ))return false; if (fDelta1_z < 0.05f * std::sqrt( fDelta1_y * fDelta1_x ))return false;
// now compare the volumes of the bounding boxes // now compare the volumes of the bounding boxes
if (std::fabs(fDelta0_x * fDelta0_y * fDelta0_z) < if (std::fabs(fDelta0_x * fDelta0_y * fDelta0_z) <

File diff suppressed because it is too large Load Diff

View File

@ -160,7 +160,7 @@ void AnimResolver::UpdateAnimRangeSetup()
case LWO::PrePostBehaviour_Repeat: case LWO::PrePostBehaviour_Repeat:
case LWO::PrePostBehaviour_Oscillate: case LWO::PrePostBehaviour_Oscillate:
{ {
const double start_time = delta - fmod(my_first-first,delta); const double start_time = delta - std::fmod(my_first-first,delta);
std::vector<LWO::Key>::iterator n = std::find_if((*it).keys.begin(),(*it).keys.end(), std::vector<LWO::Key>::iterator n = std::find_if((*it).keys.begin(),(*it).keys.end(),
std::bind1st(std::greater<double>(),start_time)),m; std::bind1st(std::greater<double>(),start_time)),m;

View File

@ -851,7 +851,7 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
case AI_LWO_SMAN: case AI_LWO_SMAN:
{ {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SMAN,4); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SMAN,4);
surf.mMaximumSmoothAngle = fabs( GetF4() ); surf.mMaximumSmoothAngle = std::fabs( GetF4() );
break; break;
} }
// vertex color channel to be applied to the surface // vertex color channel to be applied to the surface

View File

@ -298,10 +298,10 @@ inline void Vec3NormalToLatLng( const aiVector3D& p_vIn, uint16_t& p_iOut )
{ {
int a, b; int a, b;
a = int(57.2957795f * ( atan2f( p_vIn[1], p_vIn[0] ) ) * (255.0f / 360.0f )); a = int(57.2957795f * ( std::atan2( p_vIn[1], p_vIn[0] ) ) * (255.0f / 360.0f ));
a &= 0xff; a &= 0xff;
b = int(57.2957795f * ( acosf( p_vIn[2] ) ) * ( 255.0f / 360.0f )); b = int(57.2957795f * ( std::acos( p_vIn[2] ) ) * ( 255.0f / 360.0f ));
b &= 0xff; b &= 0xff;
((unsigned char*)&p_iOut)[0] = b; // longitude ((unsigned char*)&p_iOut)[0] = b; // longitude

View File

@ -228,6 +228,15 @@ bool MD5Parser::ParseSection(Section& out)
::memcpy(out.data,szStart,out.length); \ ::memcpy(out.data,szStart,out.length); \
out.data[out.length] = '\0'; out.data[out.length] = '\0';
// parse a string, enclosed in quotation marks
#define AI_MD5_PARSE_STRING_IN_QUOTATION(out) \
while('\"'!=*sz)++sz; \
const char* szStart = ++sz; \
while('\"'!=*sz)++sz; \
const char* szEnd = (sz++); \
out.length = (size_t)(szEnd - szStart); \
::memcpy(out.data,szStart,out.length); \
out.data[out.length] = '\0';
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// .MD5MESH parsing function // .MD5MESH parsing function
MD5MeshParser::MD5MeshParser(SectionList& mSections) MD5MeshParser::MD5MeshParser(SectionList& mSections)
@ -249,7 +258,7 @@ MD5MeshParser::MD5MeshParser(SectionList& mSections)
BoneDesc& desc = mJoints.back(); BoneDesc& desc = mJoints.back();
const char* sz = elem.szStart; const char* sz = elem.szStart;
AI_MD5_PARSE_STRING(desc.mName); AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mName);
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
// negative values, at least -1, is allowed here // negative values, at least -1, is allowed here
@ -269,7 +278,7 @@ MD5MeshParser::MD5MeshParser(SectionList& mSections)
// shader attribute // shader attribute
if (TokenMatch(sz,"shader",6)) { if (TokenMatch(sz,"shader",6)) {
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
AI_MD5_PARSE_STRING(desc.mShader); AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mShader);
} }
// numverts attribute // numverts attribute
else if (TokenMatch(sz,"numverts",8)) { else if (TokenMatch(sz,"numverts",8)) {
@ -362,7 +371,7 @@ MD5AnimParser::MD5AnimParser(SectionList& mSections)
AnimBoneDesc& desc = mAnimatedBones.back(); AnimBoneDesc& desc = mAnimatedBones.back();
const char* sz = elem.szStart; const char* sz = elem.szStart;
AI_MD5_PARSE_STRING(desc.mName); AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mName);
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
// parent index - negative values are allowed (at least -1) // parent index - negative values are allowed (at least -1)

File diff suppressed because it is too large Load Diff

View File

@ -187,6 +187,11 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
std::string name; std::string name;
getName(m_DataIt, m_DataItEnd, name); getName(m_DataIt, m_DataItEnd, name);
size_t nextSpace = name.find(" ");
if (nextSpace != std::string::npos)
name = name.substr(0, nextSpace);
if (name == "mg") if (name == "mg")
getGroupNumberAndResolution(); getGroupNumberAndResolution();
else if(name == "mtllib") else if(name == "mtllib")

View File

@ -757,7 +757,6 @@ static void fillColor4( aiColor4D *col4, Value *vals ) {
ai_assert( nullptr != col4 ); ai_assert( nullptr != col4 );
ai_assert( nullptr != vals ); ai_assert( nullptr != vals );
float r( 0.0f ), g( 0.0f ), b( 0.0f ), a ( 1.0f );
Value *next( vals ); Value *next( vals );
col4->r = next->getFloat(); col4->r = next->getFloat();
next = next->m_next; next = next->m_next;

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2008, assimp team Copyright (c) 2006-2016, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------
Copyright (c) 2006-2008, assimp team Copyright (c) 2006-2016, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -40,7 +40,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER #ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
//#include <windows.h>
#include "DefaultIOSystem.h" #include "DefaultIOSystem.h"
#include "Q3BSPFileImporter.h" #include "Q3BSPFileImporter.h"
#include "Q3BSPZipArchive.h" #include "Q3BSPZipArchive.h"
@ -76,14 +75,6 @@ static const aiImporterDesc desc = {
namespace Assimp { namespace Assimp {
/*
static void getSupportedExtensions(std::vector<std::string> &supportedExtensions) {
supportedExtensions.push_back( ".jpg" );
supportedExtensions.push_back( ".png" );
supportedExtensions.push_back( ".tga" );
}
*/
using namespace Q3BSP; using namespace Q3BSP;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -175,7 +166,7 @@ Q3BSPFileImporter::~Q3BSPFileImporter() {
bool Q3BSPFileImporter::CanRead( const std::string& rFile, IOSystem* /*pIOHandler*/, bool checkSig ) const bool Q3BSPFileImporter::CanRead( const std::string& rFile, IOSystem* /*pIOHandler*/, bool checkSig ) const
{ {
if(!checkSig) { if(!checkSig) {
return SimpleExtensionCheck( rFile, "pk3" ); return SimpleExtensionCheck( rFile, "pk3", "bsp" );
} }
// TODO perhaps add keyword based detection // TODO perhaps add keyword based detection
return false; return false;

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2008, assimp team Copyright (c) 2006-2016, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2008, assimp team Copyright (c) 2006-2016, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2008, assimp team Copyright (c) 2006-2016, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2008, assimp team Copyright (c) 2006-2016, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2008, assimp team Copyright (c) 2006-2016, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -58,23 +58,14 @@ namespace Q3BSP {
/// \brief /// \brief
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
class IOSystem2Unzip { class IOSystem2Unzip {
public: public:
static voidpf open(voidpf opaque, const char* filename, int mode); static voidpf open(voidpf opaque, const char* filename, int mode);
static uLong read(voidpf opaque, voidpf stream, void* buf, uLong size); static uLong read(voidpf opaque, voidpf stream, void* buf, uLong size);
static uLong write(voidpf opaque, voidpf stream, const void* buf, uLong size); static uLong write(voidpf opaque, voidpf stream, const void* buf, uLong size);
static long tell(voidpf opaque, voidpf stream); static long tell(voidpf opaque, voidpf stream);
static long seek(voidpf opaque, voidpf stream, uLong offset, int origin); static long seek(voidpf opaque, voidpf stream, uLong offset, int origin);
static int close(voidpf opaque, voidpf stream); static int close(voidpf opaque, voidpf stream);
static int testerror(voidpf opaque, voidpf stream); static int testerror(voidpf opaque, voidpf stream);
static zlib_filefunc_def get(IOSystem* pIOHandler); static zlib_filefunc_def get(IOSystem* pIOHandler);
}; };
@ -85,31 +76,20 @@ class IOSystem2Unzip {
/// \brief /// \brief
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
class ZipFile : public IOStream { class ZipFile : public IOStream {
friend class Q3BSPZipArchive; friend class Q3BSPZipArchive;
public: public:
explicit ZipFile(size_t size); explicit ZipFile(size_t size);
~ZipFile(); ~ZipFile();
size_t Read(void* pvBuffer, size_t pSize, size_t pCount ); size_t Read(void* pvBuffer, size_t pSize, size_t pCount );
size_t Write(const void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/); size_t Write(const void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/);
size_t FileSize() const; size_t FileSize() const;
aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/); aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/);
size_t Tell() const; size_t Tell() const;
void Flush(); void Flush();
private: private:
void* m_Buffer; void* m_Buffer;
size_t m_Size; size_t m_Size;
}; };
@ -121,39 +101,25 @@ class ZipFile : public IOStream {
/// from a P3K archive ( Quake level format ). /// from a P3K archive ( Quake level format ).
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
class Q3BSPZipArchive : public Assimp::IOSystem { class Q3BSPZipArchive : public Assimp::IOSystem {
public: public:
static const unsigned int FileNameSize = 256; static const unsigned int FileNameSize = 256;
public: public:
Q3BSPZipArchive(IOSystem* pIOHandler, const std::string & rFile); Q3BSPZipArchive(IOSystem* pIOHandler, const std::string & rFile);
~Q3BSPZipArchive(); ~Q3BSPZipArchive();
bool Exists(const char* pFile) const; bool Exists(const char* pFile) const;
char getOsSeparator() const; char getOsSeparator() const;
IOStream* Open(const char* pFile, const char* pMode = "rb"); IOStream* Open(const char* pFile, const char* pMode = "rb");
void Close(IOStream* pFile); void Close(IOStream* pFile);
bool isOpen() const; bool isOpen() const;
void getFileList(std::vector<std::string> &rFileList); void getFileList(std::vector<std::string> &rFileList);
private: private:
bool mapArchive(); bool mapArchive();
private: private:
unzFile m_ZipFileHandle; unzFile m_ZipFileHandle;
std::map<std::string, ZipFile*> m_ArchiveMap; std::map<std::string, ZipFile*> m_ArchiveMap;
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -710,8 +710,8 @@ static void ReadLightInfo(aiLight* light, StreamReaderLE* stream)
// OpenGL: I = cos(angle)^E // OpenGL: I = cos(angle)^E
// Solving: angle = acos(I^(1/E)) // Solving: angle = acos(I^(1/E))
ai_real E = 1.0 / std::max(spotExponent, (ai_real)0.00001); ai_real E = 1.0 / std::max(spotExponent, (ai_real)0.00001);
ai_real inner = acos(pow((ai_real)0.99, E)); ai_real inner = std::acos(std::pow((ai_real)0.99, E));
ai_real outer = acos(pow((ai_real)0.01, E)); ai_real outer = std::acos(std::pow((ai_real)0.01, E));
// Apply the cutoff. // Apply the cutoff.
outer = std::min(outer, AI_DEG_TO_RAD(spotCutoff)); outer = std::min(outer, AI_DEG_TO_RAD(spotCutoff));

View File

@ -72,7 +72,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "LineSplitter.h" #include "LineSplitter.h"
// uncomment this to have the loader evaluate all entities upon loading. // uncomment this to have the loader evaluate all entities upon loading.
// this is intended as stress test - by default, entities are evaluated // this is intended as stress test - by default, entities are evaluated
// lazily and therefore not unless needed. // lazily and therefore not unless needed.
@ -118,15 +117,13 @@ namespace STEP {
// ******************************************************************************** // ********************************************************************************
namespace STEP { namespace STEP {
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------
/** Exception class used by the STEP loading & parsing code. It is typically /** Exception class used by the STEP loading & parsing code. It is typically
* coupled with a line number. */ * coupled with a line number. */
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------
struct SyntaxError : DeadlyImportError struct SyntaxError : DeadlyImportError {
{
enum { enum {
LINE_NOT_SPECIFIED = 0xffffffffffffffffLL LINE_NOT_SPECIFIED = 0xffffffffffffffffLL
}; };
@ -253,7 +250,7 @@ namespace STEP {
{ {
public: public:
// This is the type that will ultimatively be used to // This is the type that will cd ultimatively be used to
// expose this data type to the user. // expose this data type to the user.
typedef T Out; typedef T Out;
@ -1001,26 +998,20 @@ namespace STEP {
refs.insert(std::make_pair(who,by_whom)); refs.insert(std::make_pair(who,by_whom));
} }
private: private:
HeaderInfo header; HeaderInfo header;
ObjectMap objects; ObjectMap objects;
ObjectMapByType objects_bytype; ObjectMapByType objects_bytype;
RefMap refs; RefMap refs;
InverseWhitelist inv_whitelist; InverseWhitelist inv_whitelist;
std::shared_ptr<StreamReaderLE> reader; std::shared_ptr<StreamReaderLE> reader;
LineSplitter splitter; LineSplitter splitter;
uint64_t evaluated_count; uint64_t evaluated_count;
const EXPRESS::ConversionSchema* schema; const EXPRESS::ConversionSchema* schema;
}; };
} }
} // end Assimp } // end Assimp
#endif
#endif // INCLUDED_AI_STEPFILE_H

View File

@ -43,6 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cstdarg> #include <cstdarg>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <sstream> #include <sstream>
#include <string> #include <string>

View File

@ -10,6 +10,7 @@
// Header files, Assimp. // Header files, Assimp.
#include "Exceptional.h" #include "Exceptional.h"
#include "StringUtils.h"
#include <assimp/Exporter.hpp> #include <assimp/Exporter.hpp>
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>

View File

@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "X3DImporter.hpp" #include "X3DImporter.hpp"
#include "X3DImporter_Macro.hpp" #include "X3DImporter_Macro.hpp"
#include "StringUtils.h"
// Header files, Assimp. // Header files, Assimp.
#include "DefaultIOSystem.h" #include "DefaultIOSystem.h"
@ -55,11 +56,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <memory> #include <memory>
#include <string> #include <string>
namespace Assimp namespace Assimp {
{
/// \var aiImporterDesc X3DImporter::Description /// \var aiImporterDesc X3DImporter::Description
/// Conastant which hold importer description /// Constant which holds the importer description
const aiImporterDesc X3DImporter::Description = { const aiImporterDesc X3DImporter::Description = {
"Extensible 3D(X3D) Importer", "Extensible 3D(X3D) Importer",
"smalcom", "smalcom",
@ -87,7 +87,7 @@ void X3DImporter::Clear()
X3DImporter::~X3DImporter() X3DImporter::~X3DImporter()
{ {
if(mReader != nullptr) delete mReader; delete mReader;
// Clear() is accounting if data already is deleted. So, just check again if all data is deleted. // Clear() is accounting if data already is deleted. So, just check again if all data is deleted.
Clear(); Clear();
} }
@ -120,7 +120,10 @@ bool found = false;// flag: true - if requested element is found.
if((pStartNode->Type == pType) && (pStartNode->ID == pID)) if((pStartNode->Type == pType) && (pStartNode->ID == pID))
{ {
found = true; found = true;
if(pElement != nullptr) *pElement = pStartNode; if ( pElement != nullptr )
{
*pElement = pStartNode;
}
goto fne_fn_end; goto fne_fn_end;
}// if((pStartNode->Type() == pType) && (pStartNode->ID() == pID)) }// if((pStartNode->Type() == pType) && (pStartNode->ID() == pID))
@ -129,7 +132,10 @@ bool found = false;// flag: true - if requested element is found.
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) break; if ( found )
{
break;
}
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = it->Child.begin(); ch_it != it->Child.end(); ch_it++) }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = it->Child.begin(); ch_it != it->Child.end(); ch_it++)
fne_fn_end: fne_fn_end:
@ -150,7 +156,6 @@ bool X3DImporter::FindNodeElement(const std::string& pID, const CX3DImporter_Nod
if(((CX3DImporter_NodeElement_Group*)tnd)->Static) if(((CX3DImporter_NodeElement_Group*)tnd)->Static)
{ {
static_search = true;// Flag found, stop walking up. Node with static flag will holded in tnd variable. static_search = true;// Flag found, stop walking up. Node with static flag will holded in tnd variable.
break; break;
} }
} }
@ -160,10 +165,14 @@ bool X3DImporter::FindNodeElement(const std::string& pID, const CX3DImporter_Nod
// at now call appropriate search function. // at now call appropriate search function.
if ( static_search ) if ( static_search )
{
return FindNodeElement_FromNode( tnd, pID, pType, pElement ); return FindNodeElement_FromNode( tnd, pID, pType, pElement );
}
else else
{
return FindNodeElement_FromRoot( pID, pType, pElement ); return FindNodeElement_FromRoot( pID, pType, pElement );
} }
}
/*********************************************************************************************************************************************/ /*********************************************************************************************************************************************/
/************************************************************ Functions: throw set ***********************************************************/ /************************************************************ Functions: throw set ***********************************************************/
@ -775,7 +784,7 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsListS(const int pAttrIdx, std::list<
aiVector3D X3DImporter::GeometryHelper_Make_Point2D(const float pAngle, const float pRadius) aiVector3D X3DImporter::GeometryHelper_Make_Point2D(const float pAngle, const float pRadius)
{ {
return aiVector3D(pRadius * cosf(pAngle), pRadius * sinf(pAngle), 0); return aiVector3D(pRadius * std::cos(pAngle), pRadius * std::sin(pAngle), 0);
} }
void X3DImporter::GeometryHelper_Make_Arc2D(const float pStartAngle, const float pEndAngle, const float pRadius, size_t pNumSegments, void X3DImporter::GeometryHelper_Make_Arc2D(const float pStartAngle, const float pEndAngle, const float pRadius, size_t pNumSegments,
@ -796,7 +805,7 @@ void X3DImporter::GeometryHelper_Make_Arc2D(const float pStartAngle, const float
} }
// calculate arc angle and check type of arc // calculate arc angle and check type of arc
float angle_full = fabs(pEndAngle - pStartAngle); float angle_full = std::fabs(pEndAngle - pStartAngle);
if ( ( angle_full > AI_MATH_TWO_PI_F ) || ( angle_full == 0.0f ) ) if ( ( angle_full > AI_MATH_TWO_PI_F ) || ( angle_full == 0.0f ) )
{ {
angle_full = AI_MATH_TWO_PI_F; angle_full = AI_MATH_TWO_PI_F;
@ -968,8 +977,8 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<aiColor4D
{ {
if(pColors.size() < pMesh.mNumVertices) if(pColors.size() < pMesh.mNumVertices)
{ {
throw DeadlyImportError("MeshGeometry_AddColor1. Colors count(" + std::to_string(pColors.size()) + ") can not be less than Vertices count(" + throw DeadlyImportError("MeshGeometry_AddColor1. Colors count(" + to_string(pColors.size()) + ") can not be less than Vertices count(" +
std::to_string(pMesh.mNumVertices) + ")."); to_string(pMesh.mNumVertices) + ").");
} }
// copy colors to mesh // copy colors to mesh
@ -980,8 +989,8 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<aiColor4D
{ {
if(pColors.size() < pMesh.mNumFaces) if(pColors.size() < pMesh.mNumFaces)
{ {
throw DeadlyImportError("MeshGeometry_AddColor1. Colors count(" + std::to_string(pColors.size()) + ") can not be less than Faces count(" + throw DeadlyImportError("MeshGeometry_AddColor1. Colors count(" + to_string(pColors.size()) + ") can not be less than Faces count(" +
std::to_string(pMesh.mNumFaces) + ")."); to_string(pMesh.mNumFaces) + ").");
} }
// copy colors to mesh // copy colors to mesh
@ -989,7 +998,10 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<aiColor4D
for(size_t fi = 0; fi < pMesh.mNumFaces; fi++) for(size_t fi = 0; fi < pMesh.mNumFaces; fi++)
{ {
// 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.mColors[0][pMesh.mFaces[fi].mIndices[vi]] = *col_it; for ( size_t vi = 0, vi_e = pMesh.mFaces[ fi ].mNumIndices; vi < vi_e; vi++ )
{
pMesh.mColors[ 0 ][ pMesh.mFaces[ fi ].mIndices[ vi ] ] = *col_it;
}
col_it++; col_it++;
} }
@ -1037,16 +1049,25 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<int32_t>&
// check indices array count. // check indices array count.
if(pColorIdx.size() < pCoordIdx.size()) if(pColorIdx.size() < pCoordIdx.size())
{ {
throw DeadlyImportError("MeshGeometry_AddColor2. Colors indices count(" + std::to_string(pColorIdx.size()) + throw DeadlyImportError("MeshGeometry_AddColor2. Colors indices count(" + to_string(pColorIdx.size()) +
") can not be less than Coords inidces count(" + std::to_string(pCoordIdx.size()) + ")."); ") can not be less than Coords inidces count(" + to_string(pCoordIdx.size()) + ").");
} }
// 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::list<int32_t>::const_iterator colidx_it = pColorIdx.begin(), coordidx_it = pCoordIdx.begin(); colidx_it != pColorIdx.end(); colidx_it++, coordidx_it++) for(std::list<int32_t>::const_iterator colidx_it = pColorIdx.begin(), coordidx_it = pCoordIdx.begin(); colidx_it != pColorIdx.end(); colidx_it++, coordidx_it++)
{ {
if(*colidx_it == (-1)) continue;// skip faces delimiter if ( *colidx_it == ( -1 ) )
if((unsigned int)(*coordidx_it) > pMesh.mNumVertices) throw DeadlyImportError("MeshGeometry_AddColor2. Coordinate idx is out of range."); {
if((unsigned int)*colidx_it > pMesh.mNumVertices) throw DeadlyImportError("MeshGeometry_AddColor2. Color idx is out of range."); continue;// skip faces delimiter
}
if ( ( unsigned int ) ( *coordidx_it ) > pMesh.mNumVertices )
{
throw DeadlyImportError( "MeshGeometry_AddColor2. Coordinate idx is out of range." );
}
if ( ( unsigned int ) *colidx_it > pMesh.mNumVertices )
{
throw DeadlyImportError( "MeshGeometry_AddColor2. Color idx is out of range." );
}
col_tgt_arr[*coordidx_it] = col_arr_copy[*colidx_it]; col_tgt_arr[*coordidx_it] = col_arr_copy[*colidx_it];
} }
@ -1057,12 +1078,15 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<int32_t>&
// check indices array count. // check indices array count.
if(pColors.size() < pMesh.mNumVertices) if(pColors.size() < pMesh.mNumVertices)
{ {
throw DeadlyImportError("MeshGeometry_AddColor2. Colors count(" + std::to_string(pColors.size()) + ") can not be less than Vertices count(" + throw DeadlyImportError("MeshGeometry_AddColor2. Colors count(" + to_string(pColors.size()) + ") can not be less than Vertices count(" +
std::to_string(pMesh.mNumVertices) + ")."); to_string(pMesh.mNumVertices) + ").");
} }
// 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(size_t i = 0; i < pMesh.mNumVertices; i++) col_tgt_arr[i] = col_arr_copy[i]; for ( size_t i = 0; i < pMesh.mNumVertices; i++ )
{
col_tgt_arr[ i ] = col_arr_copy[ i ];
}
}// if(pColorIdx.size() > 0) else }// if(pColorIdx.size() > 0) else
}// if(pColorPerVertex) }// if(pColorPerVertex)
else else
@ -1072,8 +1096,8 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<int32_t>&
// check indices array count. // check indices array count.
if(pColorIdx.size() < pMesh.mNumFaces) if(pColorIdx.size() < pMesh.mNumFaces)
{ {
throw DeadlyImportError("MeshGeometry_AddColor2. Colors indices count(" + std::to_string(pColorIdx.size()) + throw DeadlyImportError("MeshGeometry_AddColor2. Colors indices count(" + to_string(pColorIdx.size()) +
") can not be less than Faces count(" + std::to_string(pMesh.mNumFaces) + ")."); ") can not be less than Faces count(" + to_string(pMesh.mNumFaces) + ").");
} }
// create list with colors for every vertex using faces indices. // create list with colors for every vertex using faces indices.
col_tgt_arr.resize(pMesh.mNumFaces); col_tgt_arr.resize(pMesh.mNumFaces);
@ -1092,8 +1116,8 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<int32_t>&
// check indices array count. // check indices array count.
if(pColors.size() < pMesh.mNumFaces) if(pColors.size() < pMesh.mNumFaces)
{ {
throw DeadlyImportError("MeshGeometry_AddColor2. Colors count(" + std::to_string(pColors.size()) + ") can not be less than Faces count(" + throw DeadlyImportError("MeshGeometry_AddColor2. Colors count(" + to_string(pColors.size()) + ") can not be less than Faces count(" +
std::to_string(pMesh.mNumFaces) + ")."); to_string(pMesh.mNumFaces) + ").");
} }
// create list with colors for every vertex using faces indices. // create list with colors for every vertex using faces indices.
col_tgt_arr.resize(pMesh.mNumFaces); col_tgt_arr.resize(pMesh.mNumFaces);
@ -1148,8 +1172,8 @@ void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::list<int32_t>
for(size_t i = 0; (i < pMesh.mNumVertices) && (i < tind.size()); i++) for(size_t i = 0; (i < pMesh.mNumVertices) && (i < tind.size()); i++)
{ {
if(tind[i] >= norm_arr_copy.size()) if(tind[i] >= norm_arr_copy.size())
throw DeadlyImportError("MeshGeometry_AddNormal. Normal index(" + std::to_string(tind[i]) + throw DeadlyImportError("MeshGeometry_AddNormal. Normal index(" + to_string(tind[i]) +
") is out of range. Normals count: " + std::to_string(norm_arr_copy.size()) + "."); ") is out of range. Normals count: " + to_string(norm_arr_copy.size()) + ".");
pMesh.mNormals[i] = norm_arr_copy[tind[i]]; pMesh.mNormals[i] = norm_arr_copy[tind[i]];
} }
@ -1249,7 +1273,7 @@ void X3DImporter::MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list<int32_
for(size_t fi = 0, fi_e = faces.size(); fi < fi_e; fi++) for(size_t fi = 0, fi_e = faces.size(); fi < fi_e; fi++)
{ {
if(pMesh.mFaces[fi].mNumIndices != faces.at(fi).mNumIndices) if(pMesh.mFaces[fi].mNumIndices != faces.at(fi).mNumIndices)
throw DeadlyImportError("Number of indices in texture face and mesh face must be equal. Invalid face index: " + std::to_string(fi) + "."); throw DeadlyImportError("Number of indices in texture face and mesh face must be equal. Invalid face index: " + to_string(fi) + ".");
for(size_t ii = 0; ii < pMesh.mFaces[fi].mNumIndices; ii++) for(size_t ii = 0; ii < pMesh.mFaces[fi].mNumIndices; ii++)
{ {
@ -1288,10 +1312,8 @@ void X3DImporter::MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list<aiVect
aiMesh* X3DImporter::GeometryHelper_MakeMesh(const std::list<int32_t>& pCoordIdx, const std::list<aiVector3D>& pVertices) const aiMesh* X3DImporter::GeometryHelper_MakeMesh(const std::list<int32_t>& pCoordIdx, const std::list<aiVector3D>& pVertices) const
{ {
aiMesh* tmesh( nullptr );
std::vector<aiFace> faces; std::vector<aiFace> faces;
unsigned int prim_type = 0; unsigned int prim_type = 0;
size_t ts;
// create faces array from input string with vertices indices. // create faces array from input string with vertices indices.
GeometryHelper_CoordIdxStr2FacesArr(pCoordIdx, faces, prim_type); GeometryHelper_CoordIdxStr2FacesArr(pCoordIdx, faces, prim_type);
@ -1303,8 +1325,8 @@ aiMesh* X3DImporter::GeometryHelper_MakeMesh(const std::list<int32_t>& pCoordIdx
// //
// Create new mesh and copy geometry data. // Create new mesh and copy geometry data.
// //
tmesh = new aiMesh; aiMesh *tmesh = new aiMesh;
ts = faces.size(); size_t ts = faces.size();
// faces // faces
tmesh->mFaces = new aiFace[ts]; tmesh->mFaces = new aiFace[ts];
tmesh->mNumFaces = ts; tmesh->mNumFaces = ts;
@ -1457,7 +1479,7 @@ void X3DImporter::ParseNode_Head()
{ {
XML_CheckNode_MustBeEmpty(); XML_CheckNode_MustBeEmpty();
// adding metada from <head> as MetaString from <Scene> // adding metadata from <head> as MetaString from <Scene>
CX3DImporter_NodeElement_MetaString* ms = new CX3DImporter_NodeElement_MetaString(NodeElement_Cur); CX3DImporter_NodeElement_MetaString* ms = new CX3DImporter_NodeElement_MetaString(NodeElement_Cur);
ms->Name = mReader->getAttributeValueSafe("name"); ms->Name = mReader->getAttributeValueSafe("name");
@ -1466,8 +1488,10 @@ void X3DImporter::ParseNode_Head()
{ {
ms->Value.push_back(mReader->getAttributeValueSafe("content")); ms->Value.push_back(mReader->getAttributeValueSafe("content"));
NodeElement_List.push_back(ms); NodeElement_List.push_back(ms);
if(NodeElement_Cur != nullptr) NodeElement_Cur->Child.push_back(ms); if ( NodeElement_Cur != nullptr )
{
NodeElement_Cur->Child.push_back( ms );
}
} }
}// if(XML_CheckNode_NameEqual("meta")) }// if(XML_CheckNode_NameEqual("meta"))
}// if(mReader->getNodeType() == irr::io::EXN_ELEMENT) }// if(mReader->getNodeType() == irr::io::EXN_ELEMENT)
@ -1476,14 +1500,15 @@ void X3DImporter::ParseNode_Head()
if(XML_CheckNode_NameEqual("head")) if(XML_CheckNode_NameEqual("head"))
{ {
close_found = true; close_found = true;
break; break;
} }
}// if(mReader->getNodeType() == irr::io::EXN_ELEMENT) else }// if(mReader->getNodeType() == irr::io::EXN_ELEMENT) else
}// while(mReader->read()) }// while(mReader->read())
if(!close_found) Throw_CloseNotFound("head"); if ( !close_found )
{
Throw_CloseNotFound( "head" );
}
} }
void X3DImporter::ParseNode_Scene() void X3DImporter::ParseNode_Scene()
@ -1501,10 +1526,10 @@ auto GroupCounter_Decrease = [&](size_t& pCounter, const char* pGroupName) -> vo
pCounter--; pCounter--;
}; };
const char* GroupName_Group = "Group"; static const char* GroupName_Group = "Group";
const char* GroupName_StaticGroup = "StaticGroup"; static const char* GroupName_StaticGroup = "StaticGroup";
const char* GroupName_Transform = "Transform"; static const char* GroupName_Transform = "Transform";
const char* GroupName_Switch = "Switch"; static const char* GroupName_Switch = "Switch";
bool close_found = false; bool close_found = false;
size_t counter_group = 0; size_t counter_group = 0;

View File

@ -157,7 +157,7 @@ void X3DImporter::ParseNode_Geometry2D_ArcClose2D()
// create point list of geometry object. // create point list of geometry object.
GeometryHelper_Make_Arc2D(startAngle, endAngle, radius, 10, ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices);///TODO: IME - AI_CONFIG for NumSeg GeometryHelper_Make_Arc2D(startAngle, endAngle, radius, 10, ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices);///TODO: IME - AI_CONFIG for NumSeg
// add chord or two radiuses only if not a circle was defined // add chord or two radiuses only if not a circle was defined
if(!((fabs(endAngle - startAngle) >= AI_MATH_TWO_PI_F) || (endAngle == startAngle))) if(!((std::fabs(endAngle - startAngle) >= AI_MATH_TWO_PI_F) || (endAngle == startAngle)))
{ {
std::list<aiVector3D>& vlist = ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices;// just short alias. std::list<aiVector3D>& vlist = ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices;// just short alias.

View File

@ -46,9 +46,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "X3DImporter.hpp" #include "X3DImporter.hpp"
#include "X3DImporter_Macro.hpp" #include "X3DImporter_Macro.hpp"
#include "StringUtils.h"
namespace Assimp namespace Assimp {
{
// <DirectionalLight // <DirectionalLight
// DEF="" ID // DEF="" ID
@ -95,7 +95,7 @@ void X3DImporter::ParseNode_Lighting_DirectionalLight()
if(!def.empty()) if(!def.empty())
ne->ID = def; ne->ID = def;
else else
ne->ID = "DirectionalLight_" + std::to_string((size_t)ne);// make random name ne->ID = "DirectionalLight_" + to_string((size_t)ne);// make random name
((CX3DImporter_NodeElement_Light*)ne)->AmbientIntensity = ambientIntensity; ((CX3DImporter_NodeElement_Light*)ne)->AmbientIntensity = ambientIntensity;
((CX3DImporter_NodeElement_Light*)ne)->Color = color; ((CX3DImporter_NodeElement_Light*)ne)->Color = color;
@ -178,7 +178,7 @@ void X3DImporter::ParseNode_Lighting_PointLight()
// Assimp want a node with name similar to a light. "Why? I don't no." ) // Assimp want a node with name similar to a light. "Why? I don't no." )
ParseHelper_Group_Begin(false); ParseHelper_Group_Begin(false);
// make random name // make random name
if(ne->ID.empty()) ne->ID = "PointLight_" + std::to_string((size_t)ne); if(ne->ID.empty()) ne->ID = "PointLight_" + to_string((size_t)ne);
NodeElement_Cur->ID = ne->ID;// assign name to node and return to light element. NodeElement_Cur->ID = ne->ID;// assign name to node and return to light element.
ParseHelper_Node_Exit(); ParseHelper_Node_Exit();
@ -268,7 +268,7 @@ void X3DImporter::ParseNode_Lighting_SpotLight()
// Assimp want a node with name similar to a light. "Why? I don't no." ) // Assimp want a node with name similar to a light. "Why? I don't no." )
ParseHelper_Group_Begin(false); ParseHelper_Group_Begin(false);
// make random name // make random name
if(ne->ID.empty()) ne->ID = "SpotLight_" + std::to_string((size_t)ne); if(ne->ID.empty()) ne->ID = "SpotLight_" + to_string((size_t)ne);
NodeElement_Cur->ID = ne->ID;// assign name to node and return to light element. NodeElement_Cur->ID = ne->ID;// assign name to node and return to light element.
ParseHelper_Node_Exit(); ParseHelper_Node_Exit();

View File

@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Header files, Assimp. // Header files, Assimp.
#include "StandardShapes.h" #include "StandardShapes.h"
#include "StringUtils.h"
// Header files, stdlib. // Header files, stdlib.
#include <algorithm> #include <algorithm>
@ -174,7 +175,7 @@ void X3DImporter::Postprocess_BuildLight(const CX3DImporter_NodeElement& pNodeEl
break; break;
default: default:
throw DeadlyImportError("Postprocess_BuildLight. Unknown type of light: " + std::to_string(pNodeElement.Type) + "."); throw DeadlyImportError("Postprocess_BuildLight. Unknown type of light: " + to_string(pNodeElement.Type) + ".");
} }
pSceneLightList.push_back(new_light); pSceneLightList.push_back(new_light);
@ -296,7 +297,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate) else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate)
MeshGeometry_AddTexCoord(**pMesh, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value); MeshGeometry_AddTexCoord(**pMesh, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
else else
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of ElevationGrid: " + std::to_string((*ch_it)->Type) + "."); throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of ElevationGrid: " + to_string((*ch_it)->Type) + ".");
}// 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++)
return;// mesh is build, nothing to do anymore. return;// mesh is build, nothing to do anymore.
@ -333,7 +334,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate) else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate)
MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value); MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
else else
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedFaceSet: " + std::to_string((*ch_it)->Type) + "."); throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedFaceSet: " + to_string((*ch_it)->Type) + ".");
}// 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++)
return;// mesh is build, nothing to do anymore. return;// mesh is build, nothing to do anymore.
@ -363,7 +364,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
{} // skip because already read when mesh created. {} // skip because already read when mesh created.
else else
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedLineSet: " + std::to_string((*ch_it)->Type) + "."); throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedLineSet: " + to_string((*ch_it)->Type) + ".");
}// 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++)
return;// mesh is build, nothing to do anymore. return;// mesh is build, nothing to do anymore.
@ -401,7 +402,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value); MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
else else
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedTriangleSet or IndexedTriangleFanSet, or \ throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedTriangleSet or IndexedTriangleFanSet, or \
IndexedTriangleStripSet: " + std::to_string((*ch_it)->Type) + "."); IndexedTriangleStripSet: " + to_string((*ch_it)->Type) + ".");
}// 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++)
return;// mesh is build, nothing to do anymore. return;// mesh is build, nothing to do anymore.
@ -451,7 +452,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
{} // skip because already read when mesh created. {} // skip because already read when mesh created.
else else
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of PointSet: " + std::to_string((*ch_it)->Type) + "."); throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of PointSet: " + to_string((*ch_it)->Type) + ".");
}// 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++)
return;// mesh is build, nothing to do anymore. return;// mesh is build, nothing to do anymore.
@ -480,7 +481,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
{} // skip because already read when mesh created. {} // skip because already read when mesh created.
else else
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of LineSet: " + std::to_string((*ch_it)->Type) + "."); throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of LineSet: " + to_string((*ch_it)->Type) + ".");
}// 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++)
return;// mesh is build, nothing to do anymore. return;// mesh is build, nothing to do anymore.
@ -514,7 +515,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate) else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate)
MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value); MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
else else
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TrianlgeFanSet: " + std::to_string((*ch_it)->Type) + "."); throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TrianlgeFanSet: " + to_string((*ch_it)->Type) + ".");
}// 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++)
return;// mesh is build, nothing to do anymore. return;// mesh is build, nothing to do anymore.
@ -557,7 +558,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate) else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate)
MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value); MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
else else
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TrianlgeSet: " + std::to_string((*ch_it)->Type) + "."); throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TrianlgeSet: " + to_string((*ch_it)->Type) + ".");
}// 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++)
return;// mesh is build, nothing to do anymore. return;// mesh is build, nothing to do anymore.
@ -591,13 +592,13 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate) else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate)
MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value); MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
else else
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TriangleStripSet: " + std::to_string((*ch_it)->Type) + "."); throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TriangleStripSet: " + to_string((*ch_it)->Type) + ".");
}// 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++)
return;// mesh is build, nothing to do anymore. return;// mesh is build, nothing to do anymore.
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleStripSet) }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleStripSet)
throw DeadlyImportError("Postprocess_BuildMesh. Unknown mesh type: " + std::to_string(pNodeElement.Type) + "."); throw DeadlyImportError("Postprocess_BuildMesh. Unknown mesh type: " + to_string(pNodeElement.Type) + ".");
} }
void X3DImporter::Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeElement, aiNode& pSceneNode, std::list<aiMesh*>& pSceneMeshList, void X3DImporter::Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeElement, aiNode& pSceneNode, std::list<aiMesh*>& pSceneMeshList,
@ -659,7 +660,7 @@ void X3DImporter::Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeEle
} }
else if(!PostprocessHelper_ElementIsMetadata((*it)->Type))// skip metadata else if(!PostprocessHelper_ElementIsMetadata((*it)->Type))// skip metadata
{ {
throw DeadlyImportError("Postprocess_BuildNode. Unknown type: " + std::to_string((*it)->Type) + "."); throw DeadlyImportError("Postprocess_BuildNode. Unknown type: " + to_string((*it)->Type) + ".");
} }
}// 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++)

View File

@ -731,7 +731,7 @@ void XFileParser::ParseDataObjectMaterial( Material* pMaterial)
std::string matName; std::string matName;
readHeadOfDataObject( &matName); readHeadOfDataObject( &matName);
if( matName.empty()) if( matName.empty())
matName = std::string( "material") + std::to_string( mLineNumber ); matName = std::string( "material") + to_string( mLineNumber );
pMaterial->mName = matName; pMaterial->mName = matName;
pMaterial->mIsReference = false; pMaterial->mIsReference = false;

View File

@ -501,7 +501,7 @@ aiMatrix4x4 XGLImporter::ReadTrafo()
up.Normalize(); up.Normalize();
right = forward ^ up; right = forward ^ up;
if (fabs(up * forward) > 1e-4) { if (std::fabs(up * forward) > 1e-4) {
// this is definitely wrong - a degenerate coordinate space ruins everything // this is definitely wrong - a degenerate coordinate space ruins everything
// so subtitute identity transform. // so subtitute identity transform.
LogError("<forward> and <up> vectors in <transform> are skewing, ignoring trafo"); LogError("<forward> and <up> vectors in <transform> are skewing, ignoring trafo");

View File

@ -811,6 +811,8 @@ namespace glTF
Ref<Skin> skin; //!< The ID of the skin referenced by this node. Ref<Skin> skin; //!< The ID of the skin referenced by this node.
std::string jointName; //!< Name used when this node is a joint in a skin. std::string jointName; //!< Name used when this node is a joint in a skin.
Ref<Node> parent; //!< This is not part of the glTF specification. Used as a helper.
Node() {} Node() {}
void Read(Value& obj, Asset& r); void Read(Value& obj, Asset& r);
}; };
@ -852,7 +854,7 @@ namespace glTF
{ {
Nullable<mat4> bindShapeMatrix; //!< Floating-point 4x4 transformation matrix stored in column-major order. Nullable<mat4> bindShapeMatrix; //!< Floating-point 4x4 transformation matrix stored in column-major order.
Ref<Accessor> inverseBindMatrices; //!< The ID of the accessor containing the floating-point 4x4 inverse-bind matrices. Ref<Accessor> inverseBindMatrices; //!< The ID of the accessor containing the floating-point 4x4 inverse-bind matrices.
std::vector<std::string/*Ref<Node>*/> jointNames; //!< Joint names of the joints (nodes with a jointName property) in this skin. std::vector<Ref<Node>> jointNames; //!< Joint names of the joints (nodes with a jointName property) in this skin.
std::string name; //!< The user-defined name of this object. std::string name; //!< The user-defined name of this object.
Skin() {} Skin() {}

View File

@ -292,14 +292,14 @@ inline void Buffer::Read(Value& obj, Asset& r)
this->mData.reset(data); this->mData.reset(data);
if (statedLength > 0 && this->byteLength != statedLength) { if (statedLength > 0 && this->byteLength != statedLength) {
throw DeadlyImportError("GLTF: buffer \"" + id + "\", expected " + std::to_string(statedLength) + throw DeadlyImportError("GLTF: buffer \"" + id + "\", expected " + to_string(statedLength) +
" bytes, but found " + std::to_string(dataURI.dataLength)); " bytes, but found " + to_string(dataURI.dataLength));
} }
} }
else { // assume raw data else { // assume raw data
if (statedLength != dataURI.dataLength) { if (statedLength != dataURI.dataLength) {
throw DeadlyImportError("GLTF: buffer \"" + id + "\", expected " + std::to_string(statedLength) + throw DeadlyImportError("GLTF: buffer \"" + id + "\", expected " + to_string(statedLength) +
" bytes, but found " + std::to_string(dataURI.dataLength)); " bytes, but found " + to_string(dataURI.dataLength));
} }
this->mData.reset(new uint8_t[dataURI.dataLength]); this->mData.reset(new uint8_t[dataURI.dataLength]);
@ -991,7 +991,7 @@ Ref<Buffer> buf = pAsset_Root.buffers.Get(pCompression_Open3DGC.Buffer);
break; break;
default: default:
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of float attribute: " + std::to_string(ifs.GetFloatAttributeType(idx))); throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of float attribute: " + to_string(ifs.GetFloatAttributeType(idx)));
} }
tval *= ifs.GetFloatAttributeDim(idx) * sizeof(o3dgc::Real);// After checking count of objects we can get size of array. tval *= ifs.GetFloatAttributeDim(idx) * sizeof(o3dgc::Real);// After checking count of objects we can get size of array.
@ -1003,11 +1003,10 @@ Ref<Buffer> buf = pAsset_Root.buffers.Get(pCompression_Open3DGC.Buffer);
{ {
// size = number_of_elements * components_per_element * size_of_component. See float attributes note. // size = number_of_elements * components_per_element * size_of_component. See float attributes note.
size_t tval = ifs.GetNIntAttribute(idx); size_t tval = ifs.GetNIntAttribute(idx);
switch( ifs.GetIntAttributeType( idx ) ) switch( ifs.GetIntAttributeType( idx ) )
{ {
default: default:
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: " + std::to_string(ifs.GetIntAttributeType(idx))); throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: " + to_string(ifs.GetIntAttributeType(idx)));
} }
tval *= ifs.GetIntAttributeDim(idx) * sizeof(long);// See float attributes note. tval *= ifs.GetIntAttributeDim(idx) * sizeof(long);// See float attributes note.
@ -1046,7 +1045,7 @@ Ref<Buffer> buf = pAsset_Root.buffers.Get(pCompression_Open3DGC.Buffer);
break; break;
default: default:
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of float attribute: " + std::to_string(ifs.GetFloatAttributeType(idx))); throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of float attribute: " + to_string(ifs.GetFloatAttributeType(idx)));
} }
} }
@ -1056,7 +1055,7 @@ Ref<Buffer> buf = pAsset_Root.buffers.Get(pCompression_Open3DGC.Buffer);
{ {
// ifs.SetIntAttribute(idx, (long* const)(decoded_data + get_buf_offset(primitives[0].attributes.joint))); // ifs.SetIntAttribute(idx, (long* const)(decoded_data + get_buf_offset(primitives[0].attributes.joint)));
default: default:
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: " + std::to_string(ifs.GetIntAttributeType(idx))); throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: " + to_string(ifs.GetIntAttributeType(idx)));
} }
} }
@ -1621,6 +1620,4 @@ namespace Util {
} }
} } // ns glTF

View File

@ -65,7 +65,7 @@ namespace glTF {
inline Value& MakeValue(Value& val, const std::vector<float> & r, MemoryPoolAllocator<>& al) { inline Value& MakeValue(Value& val, const std::vector<float> & r, MemoryPoolAllocator<>& al) {
val.SetArray(); val.SetArray();
val.Reserve(r.size(), al); val.Reserve(r.size(), al);
for (int i = 0; i < r.size(); ++i) { for (unsigned int i = 0; i < r.size(); ++i) {
val.PushBack(r[i], al); val.PushBack(r[i], al);
} }
return val; return val;
@ -436,7 +436,7 @@ namespace glTF {
vJointNames.Reserve(unsigned(b.jointNames.size()), w.mAl); vJointNames.Reserve(unsigned(b.jointNames.size()), w.mAl);
for (size_t i = 0; i < unsigned(b.jointNames.size()); ++i) { for (size_t i = 0; i < unsigned(b.jointNames.size()); ++i) {
vJointNames.PushBack(StringRef(b.jointNames[i]), w.mAl); vJointNames.PushBack(StringRef(b.jointNames[i]->jointName), w.mAl);
} }
obj.AddMember("jointNames", vJointNames, w.mAl); obj.AddMember("jointNames", vJointNames, w.mAl);

View File

@ -132,7 +132,7 @@ glTFExporter::glTFExporter(const char* filename, IOSystem* pIOSystem, const aiSc
ExportMaterials(); ExportMaterials();
if (mScene->mRootNode) { if (mScene->mRootNode) {
ExportNode(mScene->mRootNode); ExportNodeHierarchy(mScene->mRootNode);
} }
ExportMeshes(); ExportMeshes();
@ -152,7 +152,10 @@ glTFExporter::glTFExporter(const char* filename, IOSystem* pIOSystem, const aiSc
} }
} }
/*
* Copy a 4x4 matrix from struct aiMatrix to typedef mat4.
* Also converts from row-major to column-major storage.
*/
static void CopyValue(const aiMatrix4x4& v, glTF::mat4& o) static void CopyValue(const aiMatrix4x4& v, glTF::mat4& o)
{ {
o[ 0] = v.a1; o[ 1] = v.b1; o[ 2] = v.c1; o[ 3] = v.d1; o[ 0] = v.a1; o[ 1] = v.b1; o[ 2] = v.c1; o[ 3] = v.d1;
@ -161,6 +164,14 @@ static void CopyValue(const aiMatrix4x4& v, glTF::mat4& o)
o[12] = v.a4; o[13] = v.b4; o[14] = v.c4; o[15] = v.d4; o[12] = v.a4; o[13] = v.b4; o[14] = v.c4; o[15] = v.d4;
} }
static void CopyValue(const aiMatrix4x4& v, aiMatrix4x4& o)
{
o.a1 = v.a1; o.a2 = v.a2; o.a3 = v.a3; o.a4 = v.a4;
o.b1 = v.b1; o.b2 = v.b2; o.b3 = v.b3; o.b4 = v.b4;
o.c1 = v.c1; o.c2 = v.c2; o.c3 = v.c3; o.c4 = v.c4;
o.d1 = v.d1; o.d2 = v.d2; o.d3 = v.d3; o.d4 = v.d4;
}
static void IdentityMatrix4(glTF::mat4& o) static void IdentityMatrix4(glTF::mat4& o)
{ {
o[ 0] = 1; o[ 1] = 0; o[ 2] = 0; o[ 3] = 0; o[ 0] = 1; o[ 1] = 0; o[ 2] = 0; o[ 3] = 0;
@ -201,17 +212,16 @@ inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& bu
// calculate min and max values // calculate min and max values
{ {
// Allocate and initialize with large values. // Allocate and initialize with large values.
float float_MAX = 10000000000000; float float_MAX = 10000000000000.0f;
for (int i = 0 ; i < numCompsOut ; i++) { for (unsigned int i = 0 ; i < numCompsOut ; i++) {
acc->min.push_back( float_MAX); acc->min.push_back( float_MAX);
acc->max.push_back(-float_MAX); acc->max.push_back(-float_MAX);
} }
// Search and set extreme values. // Search and set extreme values.
float valueTmp; float valueTmp;
for (int i = 0 ; i < count ; i++) { for (unsigned int i = 0 ; i < count ; i++) {
for (int j = 0 ; j < numCompsOut ; j++) { for (unsigned int j = 0 ; j < numCompsOut ; j++) {
if (numCompsOut == 1) { if (numCompsOut == 1) {
valueTmp = static_cast<unsigned short*>(data)[i]; valueTmp = static_cast<unsigned short*>(data)[i];
} else { } else {
@ -364,20 +374,61 @@ void glTFExporter::ExportMaterials()
} }
} }
void ExportSkin(Asset& mAsset, const aiMesh* aim, Ref<Mesh>& meshRef, Ref<Buffer>& bufferRef) /*
* Search through node hierarchy and find the node containing the given meshID.
* Returns true on success, and false otherwise.
*/
bool FindMeshNode(Ref<Node>& nodeIn, Ref<Node>& meshNode, std::string meshID)
{ {
std::string skinName = aim->mName.C_Str(); for (unsigned int i = 0; i < nodeIn->meshes.size(); ++i) {
skinName = mAsset.FindUniqueID(skinName, "skin"); if (meshID.compare(nodeIn->meshes[i]->id) == 0) {
Ref<Skin> skinRef = mAsset.skins.Create(skinName); meshNode = nodeIn;
skinRef->name = skinName; return true;
}
}
mat4* inverseBindMatricesData = new mat4[aim->mNumBones]; for (unsigned int i = 0; i < nodeIn->children.size(); ++i) {
if(FindMeshNode(nodeIn->children[i], meshNode, meshID)) {
return true;
}
}
return false;
}
/*
* Find the root joint of the skeleton.
* Starts will any joint node and traces up the tree,
* until a parent is found that does not have a jointName.
* Returns the first parent Ref<Node> found that does not have a jointName.
*/
Ref<Node> FindSkeletonRootJoint(Ref<Skin>& skinRef)
{
Ref<Node> startNodeRef;
Ref<Node> parentNodeRef;
// Arbitrarily use the first joint to start the search.
startNodeRef = skinRef->jointNames[0];
parentNodeRef = skinRef->jointNames[0];
do {
startNodeRef = parentNodeRef;
parentNodeRef = startNodeRef->parent;
} while (!parentNodeRef->jointName.empty());
return parentNodeRef;
}
void ExportSkin(Asset& mAsset, const aiMesh* aim, Ref<Mesh>& meshRef, Ref<Buffer>& bufferRef, Ref<Skin>& skinRef, std::vector<aiMatrix4x4>& inverseBindMatricesData)
{
if (aim->mNumBones < 1) {
return;
}
//-------------------------------------------------------
// Store the vertex joint and weight data. // Store the vertex joint and weight data.
vec4* vertexJointData = new vec4[aim->mNumVertices]; vec4* vertexJointData = new vec4[aim->mNumVertices];
vec4* vertexWeightData = new vec4[aim->mNumVertices]; vec4* vertexWeightData = new vec4[aim->mNumVertices];
unsigned int* jointsPerVertex = new unsigned int[aim->mNumVertices]; int* jointsPerVertex = new int[aim->mNumVertices];
for (size_t i = 0; i < aim->mNumVertices; ++i) { for (size_t i = 0; i < aim->mNumVertices; ++i) {
jointsPerVertex[i] = 0; jointsPerVertex[i] = 0;
for (size_t j = 0; j < 4; ++j) { for (size_t j = 0; j < 4; ++j) {
@ -392,48 +443,49 @@ void ExportSkin(Asset& mAsset, const aiMesh* aim, Ref<Mesh>& meshRef, Ref<Buffer
// aib->mName =====> skinRef->jointNames // aib->mName =====> skinRef->jointNames
// Find the node with id = mName. // Find the node with id = mName.
Ref<Node> nodeRef = mAsset.nodes.Get(aib->mName.C_Str()); Ref<Node> nodeRef = mAsset.nodes.Get(aib->mName.C_Str());
nodeRef->jointName = "joint_" + std::to_string(idx_bone); nodeRef->jointName = nodeRef->id;
skinRef->jointNames.push_back("joint_" + std::to_string(idx_bone));
// Identity Matrix =====> skinRef->bindShapeMatrix unsigned int jointNamesIndex;
// Temporary. Hard-coded identity matrix here bool addJointToJointNames = true;
skinRef->bindShapeMatrix.isPresent = true; for (int idx_joint = 0; idx_joint < skinRef->jointNames.size(); ++idx_joint) {
IdentityMatrix4(skinRef->bindShapeMatrix.value); if (skinRef->jointNames[idx_joint]->jointName.compare(nodeRef->jointName) == 0) {
addJointToJointNames = false;
jointNamesIndex = idx_joint;
}
}
if (addJointToJointNames) {
skinRef->jointNames.push_back(nodeRef);
// aib->mOffsetMatrix =====> skinRef->inverseBindMatrices // aib->mOffsetMatrix =====> skinRef->inverseBindMatrices
CopyValue(aib->mOffsetMatrix, inverseBindMatricesData[idx_bone]); aiMatrix4x4 tmpMatrix4;
CopyValue(aib->mOffsetMatrix, tmpMatrix4);
inverseBindMatricesData.push_back(tmpMatrix4);
jointNamesIndex = inverseBindMatricesData.size() - 1;
}
// aib->mWeights =====> vertexWeightData // aib->mWeights =====> vertexWeightData
for (unsigned int idx_weights = 0; idx_weights < aib->mNumWeights; ++idx_weights) { for (unsigned int idx_weights = 0; idx_weights < aib->mNumWeights; ++idx_weights) {
aiVertexWeight tmpVertWeight = aib->mWeights[idx_weights]; unsigned int vertexId = aib->mWeights[idx_weights].mVertexId;
vertexJointData[tmpVertWeight.mVertexId][jointsPerVertex[tmpVertWeight.mVertexId]] = idx_bone; float vertWeight = aib->mWeights[idx_weights].mWeight;
vertexWeightData[tmpVertWeight.mVertexId][jointsPerVertex[tmpVertWeight.mVertexId]] = tmpVertWeight.mWeight;
jointsPerVertex[tmpVertWeight.mVertexId] += 1; // A vertex can only have at most four joint weights. Ignore all others.
if (jointsPerVertex[vertexId] > 3) { continue; }
vertexJointData[vertexId][jointsPerVertex[vertexId]] = jointNamesIndex;
vertexWeightData[vertexId][jointsPerVertex[vertexId]] = vertWeight;
jointsPerVertex[vertexId] += 1;
} }
} // End: for-loop mNumMeshes } // End: for-loop mNumMeshes
// Create the Accessor for skinRef->inverseBindMatrices
Ref<Accessor> invBindMatrixAccessor = ExportData(mAsset, skinName, bufferRef, aim->mNumBones, inverseBindMatricesData, AttribType::MAT4, AttribType::MAT4, ComponentType_FLOAT);
if (invBindMatrixAccessor) skinRef->inverseBindMatrices = invBindMatrixAccessor;
Mesh::Primitive& p = meshRef->primitives.back(); Mesh::Primitive& p = meshRef->primitives.back();
Ref<Accessor> vertexJointAccessor = ExportData(mAsset, skinName, bufferRef, aim->mNumVertices, vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT); Ref<Accessor> vertexJointAccessor = ExportData(mAsset, skinRef->id, bufferRef, aim->mNumVertices, vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
if (vertexJointAccessor) p.attributes.joint.push_back(vertexJointAccessor); if (vertexJointAccessor) p.attributes.joint.push_back(vertexJointAccessor);
Ref<Accessor> vertexWeightAccessor = ExportData(mAsset, skinName, bufferRef, aim->mNumVertices, vertexWeightData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT); Ref<Accessor> vertexWeightAccessor = ExportData(mAsset, skinRef->id, bufferRef, aim->mNumVertices, vertexWeightData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
if (vertexWeightAccessor) p.attributes.weight.push_back(vertexWeightAccessor); if (vertexWeightAccessor) p.attributes.weight.push_back(vertexWeightAccessor);
// Create the skinned mesh instance node.
Ref<Node> node = mAsset.nodes.Create(mAsset.FindUniqueID(skinName, "node"));
// Ref<Node> node = mAsset.nodes.Get(aim->mBones[0]->mName.C_Str());
node->meshes.push_back(meshRef);
node->name = node->id;
node->skeletons.push_back(mAsset.nodes.Get(aim->mBones[0]->mName.C_Str()));
node->skin = skinRef;
} }
void glTFExporter::ExportMeshes() void glTFExporter::ExportMeshes()
@ -463,6 +515,26 @@ void glTFExporter::ExportMeshes()
b = mAsset->buffers.Create(bufferId); b = mAsset->buffers.Create(bufferId);
} }
//----------------------------------------
// Initialize variables for the skin
bool createSkin = false;
for (unsigned int idx_mesh = 0; idx_mesh < mScene->mNumMeshes; ++idx_mesh) {
const aiMesh* aim = mScene->mMeshes[idx_mesh];
if(aim->HasBones()) {
createSkin = true;
break;
}
}
Ref<Skin> skinRef;
std::string skinName = mAsset->FindUniqueID("skin", "skin");
std::vector<aiMatrix4x4> inverseBindMatricesData;
if(createSkin) {
skinRef = mAsset->skins.Create(skinName);
skinRef->name = skinName;
}
//----------------------------------------
for (unsigned int idx_mesh = 0; idx_mesh < mScene->mNumMeshes; ++idx_mesh) { for (unsigned int idx_mesh = 0; idx_mesh < mScene->mNumMeshes; ++idx_mesh) {
const aiMesh* aim = mScene->mMeshes[idx_mesh]; const aiMesh* aim = mScene->mMeshes[idx_mesh];
@ -558,10 +630,9 @@ void glTFExporter::ExportMeshes()
} }
/*************** Skins ****************/ /*************** Skins ****************/
///TODO: Fix skinning animation if(aim->HasBones()) {
// if(aim->HasBones()) { ExportSkin(*mAsset, aim, m, b, skinRef, inverseBindMatricesData);
// ExportSkin(*mAsset, aim, m, b); }
// }
/****************** Compression ******************/ /****************** Compression ******************/
///TODO: animation: weights, joints. ///TODO: animation: weights, joints.
@ -655,9 +726,41 @@ void glTFExporter::ExportMeshes()
#endif #endif
}// if(comp_allow) }// if(comp_allow)
}// for (unsigned int i = 0; i < mScene->mNumMeshes; ++i) }// for (unsigned int i = 0; i < mScene->mNumMeshes; ++i)
//----------------------------------------
// Finish the skin
// Create the Accessor for skinRef->inverseBindMatrices
if (createSkin) {
mat4* invBindMatrixData = new mat4[inverseBindMatricesData.size()];
for (int idx_joint = 0; idx_joint < inverseBindMatricesData.size(); ++idx_joint) {
CopyValue(inverseBindMatricesData[idx_joint], invBindMatrixData[idx_joint]);
} }
unsigned int glTFExporter::ExportNode(const aiNode* n) Ref<Accessor> invBindMatrixAccessor = ExportData(*mAsset, skinName, b, inverseBindMatricesData.size(), invBindMatrixData, AttribType::MAT4, AttribType::MAT4, ComponentType_FLOAT);
if (invBindMatrixAccessor) skinRef->inverseBindMatrices = invBindMatrixAccessor;
// Identity Matrix =====> skinRef->bindShapeMatrix
// Temporary. Hard-coded identity matrix here
skinRef->bindShapeMatrix.isPresent = true;
IdentityMatrix4(skinRef->bindShapeMatrix.value);
// Find node that contains this mesh and add "skeletons" and "skin" attributes to that node.
Ref<Node> rootNode = mAsset->nodes.Get(unsigned(0));
Ref<Node> meshNode;
std::string meshID = mAsset->meshes.Get(unsigned(0))->id;
FindMeshNode(rootNode, meshNode, meshID);
Ref<Node> rootJoint = FindSkeletonRootJoint(skinRef);
meshNode->skeletons.push_back(rootJoint);
meshNode->skin = skinRef;
}
}
/*
* Export the root node of the node hierarchy.
* Calls ExportNode for all children.
*/
unsigned int glTFExporter::ExportNodeHierarchy(const aiNode* n)
{ {
Ref<Node> node = mAsset->nodes.Create(mAsset->FindUniqueID(n->mName.C_Str(), "node")); Ref<Node> node = mAsset->nodes.Create(mAsset->FindUniqueID(n->mName.C_Str(), "node"));
@ -671,7 +774,34 @@ unsigned int glTFExporter::ExportNode(const aiNode* n)
} }
for (unsigned int i = 0; i < n->mNumChildren; ++i) { for (unsigned int i = 0; i < n->mNumChildren; ++i) {
unsigned int idx = ExportNode(n->mChildren[i]); unsigned int idx = ExportNode(n->mChildren[i], node);
node->children.push_back(mAsset->nodes.Get(idx));
}
return node.GetIndex();
}
/*
* Export node and recursively calls ExportNode for all children.
* Since these nodes are not the root node, we also export the parent Ref<Node>
*/
unsigned int glTFExporter::ExportNode(const aiNode* n, Ref<Node>& parent)
{
Ref<Node> node = mAsset->nodes.Create(mAsset->FindUniqueID(n->mName.C_Str(), "node"));
node->parent = parent;
if (!n->mTransformation.IsIdentity()) {
node->matrix.isPresent = true;
CopyValue(n->mTransformation, node->matrix.value);
}
for (unsigned int i = 0; i < n->mNumMeshes; ++i) {
node->meshes.push_back(mAsset->meshes.Get(n->mMeshes[i]));
}
for (unsigned int i = 0; i < n->mNumChildren; ++i) {
unsigned int idx = ExportNode(n->mChildren[i], node);
node->children.push_back(mAsset->nodes.Get(idx)); node->children.push_back(mAsset->nodes.Get(idx));
} }
@ -753,9 +883,12 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref<Animati
//------------------------------------------------------- //-------------------------------------------------------
// Extract rotation parameter data // Extract rotation parameter data
if(nodeChannel->mNumRotationKeys > 0) { if(nodeChannel->mNumRotationKeys > 0) {
C_STRUCT aiQuaternion* rotationData = new aiQuaternion[nodeChannel->mNumRotationKeys]; vec4* rotationData = new vec4[nodeChannel->mNumRotationKeys];
for (size_t i = 0; i < nodeChannel->mNumRotationKeys; ++i) { for (size_t i = 0; i < nodeChannel->mNumRotationKeys; ++i) {
rotationData[i] = nodeChannel->mRotationKeys[i].mValue; rotationData[i][0] = nodeChannel->mRotationKeys[i].mValue.x;
rotationData[i][1] = nodeChannel->mRotationKeys[i].mValue.y;
rotationData[i][2] = nodeChannel->mRotationKeys[i].mValue.z;
rotationData[i][3] = nodeChannel->mRotationKeys[i].mValue.w;
} }
Ref<Accessor> rotAccessor = ExportData(mAsset, animId, buffer, nodeChannel->mNumRotationKeys, rotationData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT); Ref<Accessor> rotAccessor = ExportData(mAsset, animId, buffer, nodeChannel->mNumRotationKeys, rotationData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
@ -780,7 +913,7 @@ void glTFExporter::ExportAnimations()
// It appears that assimp stores this type of animation as multiple animations. // It appears that assimp stores this type of animation as multiple animations.
// where each aiNodeAnim in mChannels animates a specific node. // where each aiNodeAnim in mChannels animates a specific node.
std::string name = nameAnim + "_" + std::to_string(channelIndex); std::string name = nameAnim + "_" + to_string(channelIndex);
name = mAsset->FindUniqueID(name, "animation"); name = mAsset->FindUniqueID(name, "animation");
Ref<Animation> animRef = mAsset->animations.Create(name); Ref<Animation> animRef = mAsset->animations.Create(name);

View File

@ -58,8 +58,12 @@ struct aiMaterial;
namespace glTF namespace glTF
{ {
template<class T>
class Ref;
class Asset; class Asset;
struct TexProperty; struct TexProperty;
struct Node;
} }
namespace Assimp namespace Assimp
@ -98,7 +102,8 @@ namespace Assimp
void ExportMetadata(); void ExportMetadata();
void ExportMaterials(); void ExportMaterials();
void ExportMeshes(); void ExportMeshes();
unsigned int ExportNode(const aiNode* node); unsigned int ExportNodeHierarchy(const aiNode* n);
unsigned int ExportNode(const aiNode* node, glTF::Ref<glTF::Node>& parent);
void ExportScene(); void ExportScene();
void ExportAnimations(); void ExportAnimations();
}; };

View File

@ -41,8 +41,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER #ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
#include "glTFImporter.h" #include "glTFImporter.h"
#include "StringComparison.h" #include "StringComparison.h"
#include "StringUtils.h"
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <assimp/scene.h> #include <assimp/scene.h>
@ -285,7 +285,7 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
else else
#endif #endif
{ {
throw DeadlyImportError("GLTF: Can not import mesh: unknown mesh extension (code: \"" + std::to_string(cur_ext->Type) + throw DeadlyImportError("GLTF: Can not import mesh: unknown mesh extension (code: \"" + to_string(cur_ext->Type) +
"\"), only Open3DGC is supported."); "\"), only Open3DGC is supported.");
} }
} }

View File

@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_FILEIO_H_INC #ifndef AI_FILEIO_H_INC
#define AI_FILEIO_H_INC #define AI_FILEIO_H_INC
#include "types.h" #include <assimp/types.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -58,10 +58,10 @@ typedef size_t (*aiFileWriteProc) (C_STRUCT aiFile*, const char*, size_t, si
typedef size_t (*aiFileReadProc) (C_STRUCT aiFile*, char*, size_t,size_t); typedef size_t (*aiFileReadProc) (C_STRUCT aiFile*, char*, size_t,size_t);
typedef size_t (*aiFileTellProc) (C_STRUCT aiFile*); typedef size_t (*aiFileTellProc) (C_STRUCT aiFile*);
typedef void (*aiFileFlushProc) (C_STRUCT aiFile*); typedef void (*aiFileFlushProc) (C_STRUCT aiFile*);
typedef aiReturn (*aiFileSeek)(C_STRUCT aiFile*, size_t, aiOrigin); typedef C_ENUM aiReturn (*aiFileSeek) (C_STRUCT aiFile*, size_t, C_ENUM aiOrigin);
// aiFileIO callbacks // aiFileIO callbacks
typedef aiFile* (*aiFileOpenProc) (C_STRUCT aiFileIO*, const char*, const char*); typedef C_STRUCT aiFile* (*aiFileOpenProc) (C_STRUCT aiFileIO*, const char*, const char*);
typedef void (*aiFileCloseProc) (C_STRUCT aiFileIO*, C_STRUCT aiFile*); typedef void (*aiFileCloseProc) (C_STRUCT aiFileIO*, C_STRUCT aiFile*);
// Represents user-defined data // Represents user-defined data

View File

@ -367,21 +367,21 @@ inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector
// Use a small epsilon to solve floating-point inaccuracies // Use a small epsilon to solve floating-point inaccuracies
const TReal epsilon = 10e-3f; const TReal epsilon = 10e-3f;
pRotation.y = asin(vCols[2].x);// D. Angle around oY. pRotation.y = std::asin(vCols[2].x);// D. Angle around oY.
TReal C = cos(pRotation.y); TReal C = std::cos(pRotation.y);
if(fabs(C) > epsilon) if(std::fabs(C) > epsilon)
{ {
// Finding angle around oX. // Finding angle around oX.
TReal tan_x = vCols[2].z / C;// A TReal tan_x = vCols[2].z / C;// A
TReal tan_y = -vCols[2].y / C;// B TReal tan_y = -vCols[2].y / C;// B
pRotation.x = atan2(tan_y, tan_x); pRotation.x = std::atan2(tan_y, tan_x);
// Finding angle around oZ. // Finding angle around oZ.
tan_x = vCols[0].x / C;// E tan_x = vCols[0].x / C;// E
tan_y = -vCols[1].x / C;// F tan_y = -vCols[1].x / C;// F
pRotation.z = atan2(tan_y, tan_x); pRotation.z = std::atan2(tan_y, tan_x);
} }
else else
{// oY is fixed. {// oY is fixed.
@ -391,7 +391,7 @@ inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector
TReal tan_x = vCols[1].y;// -BDF+AE => E TReal tan_x = vCols[1].y;// -BDF+AE => E
TReal tan_y = vCols[0].y;// BDE+AF => F TReal tan_y = vCols[0].y;// BDE+AF => F
pRotation.z = atan2(tan_y, tan_x); pRotation.z = std::atan2(tan_y, tan_x);
} }
} }
@ -407,14 +407,14 @@ aiQuaterniont<TReal> pRotation;
pRotation.Normalize(); pRotation.Normalize();
TReal angle_cos = pRotation.w; TReal angle_cos = pRotation.w;
TReal angle_sin = sqrt(1.0f - angle_cos * angle_cos); TReal angle_sin = std::sqrt(1.0f - angle_cos * angle_cos);
pRotationAngle = acos(angle_cos) * 2; pRotationAngle = std::acos(angle_cos) * 2;
// Use a small epsilon to solve floating-point inaccuracies // Use a small epsilon to solve floating-point inaccuracies
const TReal epsilon = 10e-3f; const TReal epsilon = 10e-3f;
if(fabs(angle_sin) < epsilon) angle_sin = 1; if(std::fabs(angle_sin) < epsilon) angle_sin = 1;
pRotationAxis.x = pRotation.x / angle_sin; pRotationAxis.x = pRotation.x / angle_sin;
pRotationAxis.y = pRotation.y / angle_sin; pRotationAxis.y = pRotation.y / angle_sin;

View File

@ -48,7 +48,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Some runtime headers // Some runtime headers
#include <sys/types.h> #include <sys/types.h>
#include <math.h>
#include <stddef.h> #include <stddef.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>

View File

@ -3,12 +3,12 @@ set(PROJECT_VERSION "")
cmake_minimum_required(VERSION 2.6) cmake_minimum_required(VERSION 2.6)
find_package(Qt4 REQUIRED) find_package(Qt5Widgets REQUIRED)
find_package(DevIL REQUIRED) find_package(DevIL REQUIRED)
find_package(OpenGL REQUIRED) find_package(OpenGL REQUIRED)
include_directories( include_directories(
${QT_INCLUDES} ${Qt5Widgets_INCLUDES}
${Assimp_SOURCE_DIR}/include ${Assimp_SOURCE_DIR}/include
${Assimp_SOURCE_DIR}/code ${Assimp_SOURCE_DIR}/code
${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}
@ -21,15 +21,16 @@ link_directories(${Assimp_BINARY_DIR})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pedantic -Wall") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pedantic -Wall")
set(assimp_qt_viewer_SRCS main.cpp loggerview.cpp glview.cpp mainwindow.cpp) set(assimp_qt_viewer_SRCS main.cpp loggerview.cpp glview.cpp mainwindow.cpp)
qt4_wrap_ui(UISrcs mainwindow.ui) qt5_wrap_ui(UISrcs mainwindow.ui)
qt4_wrap_cpp(MOCrcs mainwindow.hpp glview.hpp) qt5_wrap_cpp(MOCrcs mainwindow.hpp glview.hpp)
add_executable(${PROJECT_NAME} ${assimp_qt_viewer_SRCS} ${UISrcs} ${MOCrcs}) add_executable(${PROJECT_NAME} ${assimp_qt_viewer_SRCS} ${UISrcs} ${MOCrcs})
target_link_libraries(${PROJECT_NAME} ${QT_LIBRARIES} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${IL_LIBRARIES} ${OPENGL_LIBRARIES} assimp) target_link_libraries(${PROJECT_NAME} ${QT_LIBRARIES} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${IL_LIBRARIES} ${OPENGL_LIBRARIES} assimp)
qt5_use_modules(${PROJECT_NAME} Widgets OpenGL)
if(WIN32) # Check if we are on Windows if(WIN32) # Check if we are on Windows
if(MSVC) # Check if we are using the Visual Studio compiler if(MSVC) # Check if we are using the Visual Studio compiler
set_target_properties(TestProject PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS") #set_target_properties(TestProject PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS")
elseif(CMAKE_COMPILER_IS_GNUCXX) elseif(CMAKE_COMPILER_IS_GNUCXX)
# SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mwindows") # Not tested # SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mwindows") # Not tested
else() else()

View File

@ -9,7 +9,7 @@
#include <GL/glu.h> #include <GL/glu.h>
// Header files, DevIL. // Header files, DevIL.
#include <IL/il.h> #include <il.h>
// Header files, Assimp. // Header files, Assimp.
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
@ -158,8 +158,11 @@ std::list<aiMatrix4x4> mat_list;
} while(node_cur != nullptr); } while(node_cur != nullptr);
} }
// multiplicate 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++) pOutMatrix = pOutMatrix * (*rit); for ( std::list<aiMatrix4x4>::reverse_iterator rit = mat_list.rbegin(); rit != mat_list.rend(); rit++)
{
pOutMatrix = pOutMatrix * (*rit);
}
} }
void CGLView::ImportTextures(const QString& pScenePath) void CGLView::ImportTextures(const QString& pScenePath)

View File

@ -325,7 +325,7 @@ bool selected = ui->lstLight->isItemSelected(ui->lstLight->currentItem());
mGLView->updateGL(); mGLView->updateGL();
} }
void MainWindow::on_lstCamera_clicked(__unused const QModelIndex &index) void MainWindow::on_lstCamera_clicked( const QModelIndex &)
{ {
mGLView->Camera_Set(ui->lstLight->currentRow()); mGLView->Camera_Set(ui->lstLight->currentRow());
mGLView->updateGL(); mGLView->updateGL();

View File

@ -6,7 +6,7 @@
#pragma once #pragma once
// Header files, Qt. // Header files, Qt.
#include <QMainWindow> #include <QtWidgets>
// Header files, project. // Header files, project.
#include "glview.hpp" #include "glview.hpp"