Merge pull request #2 from assimp/master

Updating to latest version from origin
pull/2987/head
Tomas Mariancik 2019-10-18 14:30:34 +02:00 committed by GitHub
commit d8979cbc1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
165 changed files with 3393 additions and 4817 deletions

View File

@ -7,6 +7,7 @@
#
function generate() {
OPTIONS="-DASSIMP_WERROR=ON"
OPTIONS="$OPTIONS -DASSIMP_NO_EXPORT=NO"
if [ "$DISABLE_EXPORTERS" = "YES" ] ; then
OPTIONS="$OPTIONS -DASSIMP_NO_EXPORT=YES"

View File

@ -0,0 +1,26 @@
:: This is an example file to generate binaries using Windows Operating System
:: This script is configured to be executed from the source directory
:: Compiled binaries will be placed in BINARIES_DIR\code\CONFIG
:: NOTE
:: The build process will generate a config.h file that is placed in BINARIES_DIR\include
:: This file must be merged with SOURCE_DIR\include
:: You should write yourself a script that copies the files where you want them.
:: Also see: https://github.com/assimp/assimp/pull/2646
SET SOURCE_DIR=.
:: For generators see "cmake --help"
SET GENERATOR=Visual Studio 15 2017
SET BINARIES_DIR="./BINARIES/Win32"
cmake CMakeLists.txt -G "%GENERATOR%" -S %SOURCE_DIR% -B %BINARIES_DIR%
cmake --build %BINARIES_DIR% --config release
SET BINARIES_DIR="./BINARIES/x64"
cmake CMakeLists.txt -G "%GENERATOR% Win64" -S %SOURCE_DIR% -B %BINARIES_DIR%
cmake --build %BINARIES_DIR% --config debug
cmake --build %BINARIES_DIR% --config release
PAUSE

View File

@ -1,17 +1,31 @@
# Build Instructions
## Install CMake
## Build on all platforms using vcpkg
You can download and install assimp using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager:
```bash
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
vcpkg install assimp
```
The assimp port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
## Manual build instructions
### Install CMake
Asset-Importer-Lib can be build for a lot of different platforms. We are using cmake to generate the build environment for these via cmake. So you have to make sure that you have a working cmake-installation on your system. You can download it at https://cmake.org/ or for linux install it via
```bash
sudo apt-get install cmake
```
## Get the source
### Get the source
Make sure you have a working git-installation. Open a command prompt and clone the Asset-Importer-Lib via:
```bash
git clone https://github.com/assimp/assimp.git
```
## Build instructions for Windows with Visual-Studio
### Build instructions for Windows with Visual-Studio
First you have to install Visual-Studio on your windows-system. You can get the Community-Version for free here: https://visualstudio.microsoft.com/de/downloads/
To generate the build environment for your IDE open a command prompt, navigate to your repo and type:
@ -20,10 +34,10 @@ cmake CMakeLists.txt
```
This will generate the project files for the visual studio. All dependencies used to build Asset-IMporter-Lib shall be part of the repo. If you want to use you own zlib.installation this is possible as well. Check the options for it.
## Build instructions for Windows with UWP
### Build instructions for Windows with UWP
See <https://stackoverflow.com/questions/40803170/cmake-uwp-using-cmake-to-build-universal-windows-app>
## Build instructions for Linux / Unix
### Build instructions for Linux / Unix
Open a terminal and got to your repository. You can generate the makefiles and build the library via:
```bash
@ -34,7 +48,7 @@ The option -j descripes the number of parallel processes for the build. In this
If you want to use a IDE for linux you can try QTCreator for instance.
## Build instructions for MinGW
### Build instructions for MinGW
Older versions of MinGW's compiler (e.g. 5.1.0) do not support the -mbig_obj flag
required to compile some of assimp's files, especially for debug builds.
Version 7.3.0 of g++-mingw-w64 & gcc-mingw-w64 appears to work.
@ -50,7 +64,7 @@ The following toolchain may or may not be helpful for building assimp using MinG
Besides the toolchain, compilation should be the same as for Linux / Unix.
## CMake build options
### CMake build options
The cmake-build-environment provides options to configure the build. The following options can be used:
- **BUILD_SHARED_LIBS ( default ON )**: Generation of shared libs ( dll for windows, so for Linux ). Set this to OFF to get a static lib.
- **BUILD_FRAMEWORK ( default OFF, MacOnly)**: Build package as Mac OS X Framework bundle

View File

@ -253,7 +253,7 @@ ELSEIF(MSVC)
IF(MSVC12)
ADD_COMPILE_OPTIONS(/wd4351)
ENDIF()
SET(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /MDd /Ob2")
SET(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /MDd /Ob2 /DEBUG:FULL /Zi")
ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
IF(NOT HUNTER_ENABLED)
SET(CMAKE_CXX_FLAGS "-fPIC -std=c++11 ${CMAKE_CXX_FLAGS}")
@ -271,22 +271,20 @@ ELSEIF( CMAKE_COMPILER_IS_MINGW )
SET(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
SET(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
ENDIF()
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -Wa,-mbig-obj ${CMAKE_CXX_FLAGS}")
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -Wa,-mbig-obj -O3 ${CMAKE_CXX_FLAGS}")
SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
ADD_DEFINITIONS( -U__STRICT_ANSI__ )
ENDIF()
IF ( IOS AND NOT HUNTER_ENABLED)
IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -Og")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -Og")
ELSE()
ELSE()
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3")
# Experimental for pdb generation
ENDIF()
ENDIF()
ENDIF( IOS AND NOT HUNTER_ENABLED)
IF (ASSIMP_COVERALLS)
@ -559,17 +557,15 @@ ENDIF(NOT HUNTER_ENABLED)
ADD_SUBDIRECTORY( code/ )
IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
# The viewer for windows only
IF ( WIN32 AND DirectX_D3DX9_LIBRARY )
OPTION ( ASSIMP_BUILD_ASSIMP_VIEW "If the Assimp view tool is built. (requires DirectX)" ${DirectX_FOUND} )
IF ( ASSIMP_BUILD_ASSIMP_VIEW )
ADD_SUBDIRECTORY( tools/assimp_view/ )
ENDIF ( ASSIMP_BUILD_ASSIMP_VIEW )
ENDIF ( WIN32 AND DirectX_D3DX9_LIBRARY )
# Te command line tool
ADD_SUBDIRECTORY( tools/assimp_cmd/ )
IF (NOT IOS)
ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ )
ENDIF (NOT IOS)
ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
IF ( ASSIMP_BUILD_SAMPLES)

View File

@ -120,7 +120,7 @@ __Exporters__:
- FBX ( experimental )
### Building ###
Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file. Our build system is CMake, if you used CMake before there is a good chance you know what to do.
Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file. We are available in vcpkg, and our build system is CMake; if you used CMake before there is a good chance you know what to do.
### Ports ###
* [Android](port/AndroidJNI/README.md)

View File

@ -16,6 +16,8 @@ matrix:
image:
- Visual Studio 2015
- Visual Studio 2017
- Visual Studio 2019
- MinGW
platform:
- Win32
@ -26,10 +28,13 @@ configuration: Release
install:
- set PATH=C:\Ruby24-x64\bin;%PATH%
- set CMAKE_DEFINES -DASSIMP_WERROR=ON
- if [%COMPILER%]==[MinGW] set PATH=C:\MinGW\bin;%PATH%
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" set CMAKE_GENERATOR_NAME=Visual Studio 14 2015
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" set CMAKE_GENERATOR_NAME=Visual Studio 15 2017
- if "%platform%"=="x64" set CMAKE_GENERATOR_NAME=%CMAKE_GENERATOR_NAME% Win64
- cmake %CMAKE_DEFINES% -G "%CMAKE_GENERATOR_NAME%" .
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2019" set CMAKE_GENERATOR_NAME=Visual Studio 16 2019
- cmake %CMAKE_DEFINES% -G "%CMAKE_GENERATOR_NAME%" -A %platform% .
# Rename sh.exe as sh.exe in PATH interferes with MinGW
- rename "C:\Program Files\Git\usr\bin\sh.exe" "sh2.exe"
- set PATH=%PATH%;"C:\\Program Files (x86)\\Inno Setup 5"
- ps: Invoke-WebRequest -Uri https://download.microsoft.com/download/5/7/b/57b2947c-7221-4f33-b35e-2fc78cb10df4/vc_redist.x64.exe -OutFile .\packaging\windows-innosetup\vc_redist.x64.exe
- ps: Invoke-WebRequest -Uri https://download.microsoft.com/download/1/d/8/1d8137db-b5bb-4925-8c5d-927424a2e4de/vc_redist.x86.exe -OutFile .\packaging\windows-innosetup\vc_redist.x86.exe

View File

@ -63,7 +63,11 @@ if(MSVC)
else()
set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@" CACHE STRING "the suffix for the assimp libraries" )
if(ASSIMP_BUILD_SHARED_LIBS)
if(APPLE)
set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@.@ASSIMP_VERSION_MAJOR@@CMAKE_SHARED_LIBRARY_SUFFIX@")
else(APPLE)
set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_SHARED_LIBRARY_SUFFIX@.@ASSIMP_VERSION_MAJOR@")
endif()
set_target_properties(assimp::assimp PROPERTIES
IMPORTED_SONAME_DEBUG "${sharedLibraryName}"
IMPORTED_LOCATION_DEBUG "${_IMPORT_PREFIX}/lib/${sharedLibraryName}"

View File

@ -63,7 +63,11 @@ if(MSVC)
else()
set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@" CACHE STRING "the suffix for the assimp libraries" )
if(ASSIMP_BUILD_SHARED_LIBS)
if(APPLE)
set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}.@ASSIMP_VERSION_MAJOR@@CMAKE_SHARED_LIBRARY_SUFFIX@")
else(APPLE)
set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_SHARED_LIBRARY_SUFFIX@.@ASSIMP_VERSION_MAJOR@")
endif()
set_target_properties(assimp::assimp PROPERTIES
IMPORTED_SONAME_RELEASE "${sharedLibraryName}"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/${sharedLibraryName}"

View File

@ -54,14 +54,18 @@ else(WIN32)
find_path(
assimp_INCLUDE_DIRS
NAMES postprocess.h scene.h version.h config.h cimport.h
PATHS /usr/local/include/
NAMES assimp/postprocess.h assimp/scene.h assimp/version.h assimp/config.h assimp/cimport.h
PATHS /usr/local/include
PATHS /usr/include/
)
find_library(
assimp_LIBRARIES
NAMES assimp
PATHS /usr/local/lib/
PATHS /usr/lib64/
PATHS /usr/lib/
)
if (assimp_INCLUDE_DIRS AND assimp_LIBRARIES)

View File

@ -50,9 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
// internal headers
#include "3DSLoader.h"
#include <assimp/Macros.h>
#include <assimp/IOSystem.hpp>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>

View File

@ -83,7 +83,7 @@ void AMFImporter::Clear()
mMaterial_Converted.clear();
mTexture_Converted.clear();
// Delete all elements
if(mNodeElement_List.size())
if(!mNodeElement_List.empty())
{
for(CAMFImporter_NodeElement* ne: mNodeElement_List) { delete ne; }

View File

@ -66,7 +66,7 @@ aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*
aiColor4D tcol;
// Check if stored data are supported.
if(Composition.size() != 0)
if(!Composition.empty())
{
throw DeadlyImportError("IME. GetColor for composition");
}
@ -321,7 +321,7 @@ void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace
};
pOutputList_Separated.clear();
if(pInputList.size() == 0) return;
if(pInputList.empty()) return;
do
{
@ -334,19 +334,19 @@ void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace
{
auto it_old = it;
it++;
++it;
face_list_cur.push_back(*it_old);
pInputList.erase(it_old);
}
else
{
it++;
++it;
}
}
if(face_list_cur.size() > 0) pOutputList_Separated.push_back(face_list_cur);
if(!face_list_cur.empty()) pOutputList_Separated.push_back(face_list_cur);
} while(pInputList.size() > 0);
} while(!pInputList.empty());
}
void AMFImporter::Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& metadataList, aiNode& sceneNode) const
@ -712,7 +712,7 @@ std::list<unsigned int> mesh_idx;
}// for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child)
// if meshes was created then assign new indices with current aiNode
if(mesh_idx.size() > 0)
if(!mesh_idx.empty())
{
std::list<unsigned int>::const_iterator mit = mesh_idx.begin();
@ -787,7 +787,7 @@ std::list<aiNode*> ch_node;
}// for(const CAMFImporter_NodeElement* ne: pConstellation.Child)
// copy found aiNode's as children
if(ch_node.size() == 0) throw DeadlyImportError("<constellation> must have at least one <instance>.");
if(ch_node.empty()) throw DeadlyImportError("<constellation> must have at least one <instance>.");
size_t ch_idx = 0;
@ -883,13 +883,13 @@ nl_clean_loop:
if(node_list.size() > 1)
{
// walk through all nodes
for(std::list<aiNode*>::iterator nl_it = node_list.begin(); nl_it != node_list.end(); nl_it++)
for(std::list<aiNode*>::iterator nl_it = node_list.begin(); nl_it != node_list.end(); ++nl_it)
{
// and try to find them in another top nodes.
std::list<aiNode*>::const_iterator next_it = nl_it;
next_it++;
for(; next_it != node_list.end(); next_it++)
++next_it;
for(; next_it != node_list.end(); ++next_it)
{
if((*next_it)->FindNode((*nl_it)->mName) != nullptr)
{
@ -907,7 +907,7 @@ nl_clean_loop:
//
//
// Nodes
if(node_list.size() > 0)
if(!node_list.empty())
{
std::list<aiNode*>::const_iterator nl_it = node_list.begin();
@ -924,7 +924,7 @@ nl_clean_loop:
//
// Meshes
if(mesh_list.size() > 0)
if(!mesh_list.empty())
{
std::list<aiMesh*>::const_iterator ml_it = mesh_list.begin();

View File

@ -137,7 +137,6 @@ SET( PUBLIC_HEADERS
${HEADER_PATH}/irrXMLWrapper.h
${HEADER_PATH}/BlobIOSystem.h
${HEADER_PATH}/MathFunctions.h
${HEADER_PATH}/Macros.h
${HEADER_PATH}/Exceptional.h
${HEADER_PATH}/ByteSwapper.h
)
@ -766,6 +765,8 @@ ADD_ASSIMP_EXPORTER( X3D
)
ADD_ASSIMP_IMPORTER( GLTF
glTF/glTFCommon.h
glTF/glTFCommon.cpp
glTF/glTFAsset.h
glTF/glTFAsset.inl
glTF/glTFAssetWriter.h
@ -1057,6 +1058,8 @@ MESSAGE(STATUS "Disabled importer formats:${ASSIMP_IMPORTERS_DISABLED}")
MESSAGE(STATUS "Enabled exporter formats:${ASSIMP_EXPORTERS_ENABLED}")
MESSAGE(STATUS "Disabled exporter formats:${ASSIMP_EXPORTERS_DISABLED}")
SOURCE_GROUP( include\\assimp FILES ${PUBLIC_HEADERS} )
SET( assimp_src
# Assimp Files
${Core_SRCS}

View File

@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ColladaExporter.h"
#include <assimp/Bitmap.h>
#include <assimp/MathFunctions.h>
#include <assimp/fast_atof.h>
#include <assimp/SceneCombiner.h>
#include <assimp/StringUtils.h>
@ -155,7 +156,7 @@ void ColladaExporter::WriteFile() {
// ------------------------------------------------------------------------------------------------
// Writes the asset header
void ColladaExporter::WriteHeader() {
static const ai_real epsilon = ai_real( 0.00001 );
static const ai_real epsilon = Math::getEpsilon<ai_real>();
static const aiQuaternion x_rot(aiMatrix3x3(
0, -1, 0,
1, 0, 0,
@ -317,7 +318,7 @@ void ColladaExporter::WriteTextures() {
std::string name = mFile + "_texture_" + (i < 1000 ? "0" : "") + (i < 100 ? "0" : "") + (i < 10 ? "0" : "") + str + "." + ((const char*) texture->achFormatHint);
std::unique_ptr<IOStream> outfile(mIOSystem->Open(mPath + name, "wb"));
std::unique_ptr<IOStream> outfile(mIOSystem->Open(mPath + mIOSystem->getOsSeparator() + name, "wb"));
if(outfile == NULL) {
throw DeadlyExportError("could not open output texture file: " + mPath + name);
}

View File

@ -588,7 +588,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser& pParser, const Colla
// ------------------------------------------------------------------------------------------------
// Find mesh from either meshes or morph target meshes
aiMesh *ColladaLoader::findMesh(std::string meshid) {
aiMesh *ColladaLoader::findMesh(const std::string& meshid) {
for (unsigned int i = 0; i < mMeshes.size(); ++i) {
if (std::string(mMeshes[i]->mName.data) == meshid) {
return mMeshes[i];
@ -688,7 +688,7 @@ aiMesh* ColladaLoader::CreateMesh(const ColladaParser& pParser, const Collada::M
Collada::MorphMethod method = Collada::Normalized;
for (std::map<std::string, Collada::Controller>::const_iterator it = pParser.mControllerLibrary.begin();
it != pParser.mControllerLibrary.end(); it++) {
it != pParser.mControllerLibrary.end(); ++it) {
const Collada::Controller &c = it->second;
const Collada::Mesh* baseMesh = pParser.ResolveLibraryReference(pParser.mMeshLibrary, c.mMeshId);

View File

@ -120,7 +120,7 @@ protected:
void BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode,
aiNode* pTarget);
aiMesh *findMesh(std::string meshid);
aiMesh *findMesh(const std::string& meshid);
/** Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh */
aiMesh* CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh,

View File

@ -76,9 +76,25 @@ BaseImporter::~BaseImporter() {
// nothing to do here
}
void BaseImporter::UpdateImporterScale( Importer* pImp )
{
ai_assert(pImp != nullptr);
ai_assert(importerScale != 0.0);
ai_assert(fileScale != 0.0);
double activeScale = importerScale * fileScale;
// Set active scaling
pImp->SetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, static_cast<float>( activeScale) );
ASSIMP_LOG_DEBUG_F("UpdateImporterScale scale set: %f", activeScale );
}
// ------------------------------------------------------------------------------------------------
// Imports the given file and returns the imported data.
aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile, IOSystem* pIOHandler) {
aiScene* BaseImporter::ReadFile(Importer* pImp, const std::string& pFile, IOSystem* pIOHandler) {
m_progress = pImp->GetProgressHandler();
if (nullptr == m_progress) {
return nullptr;
@ -100,6 +116,11 @@ aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile,
{
InternReadFile( pFile, sc.get(), &filter);
// Calculate import scale hook - required because pImp not available anywhere else
// passes scale into ScaleProcess
UpdateImporterScale(pImp);
} catch( const std::exception& err ) {
// extract error description
m_ErrorText = err.what();
@ -112,7 +133,7 @@ aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile,
}
// ------------------------------------------------------------------------------------------------
void BaseImporter::SetupProperties(const Importer* /*pImp*/)
void BaseImporter::SetupProperties(const Importer* pImp)
{
// the default implementation does nothing
}
@ -588,6 +609,8 @@ aiScene* BatchLoader::GetImport( unsigned int which )
return nullptr;
}
// ------------------------------------------------------------------------------------------------
void BatchLoader::LoadAll()
{

View File

@ -61,83 +61,66 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp;
// maximum path length
// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
#ifdef PATH_MAX
# define PATHLIMIT PATH_MAX
#else
# define PATHLIMIT 4096
#ifdef _WIN32
static std::wstring Utf8ToWide(const char* in)
{
int size = MultiByteToWideChar(CP_UTF8, 0, in, -1, nullptr, 0);
// size includes terminating null; std::wstring adds null automatically
std::wstring out(static_cast<size_t>(size) - 1, L'\0');
MultiByteToWideChar(CP_UTF8, 0, in, -1, &out[0], size);
return out;
}
static std::string WideToUtf8(const wchar_t* in)
{
int size = WideCharToMultiByte(CP_UTF8, 0, in, -1, nullptr, 0, nullptr, nullptr);
// size includes terminating null; std::string adds null automatically
std::string out(static_cast<size_t>(size) - 1, '\0');
WideCharToMultiByte(CP_UTF8, 0, in, -1, &out[0], size, nullptr, nullptr);
return out;
}
#endif
// ------------------------------------------------------------------------------------------------
// Tests for the existence of a file at the given path.
bool DefaultIOSystem::Exists( const char* pFile) const
bool DefaultIOSystem::Exists(const char* pFile) const
{
#ifdef _WIN32
wchar_t fileName16[PATHLIMIT];
#ifndef WindowsStore
bool isUnicode = IsTextUnicode(pFile, static_cast<int>(strlen(pFile)), NULL) != 0;
if (isUnicode) {
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, pFile, -1, fileName16, PATHLIMIT);
struct __stat64 filestat;
if (0 != _wstat64(fileName16, &filestat)) {
if (_wstat64(Utf8ToWide(pFile).c_str(), &filestat) != 0) {
return false;
}
} else {
#endif
#else
FILE* file = ::fopen(pFile, "rb");
if (!file)
return false;
::fclose(file);
#ifndef WindowsStore
}
#endif
#else
FILE* file = ::fopen( pFile, "rb");
if( !file)
return false;
::fclose( file);
#endif
return true;
}
// ------------------------------------------------------------------------------------------------
// Open a new file with a given path.
IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode)
IOStream* DefaultIOSystem::Open(const char* strFile, const char* strMode)
{
ai_assert(NULL != strFile);
ai_assert(NULL != strMode);
ai_assert(strFile != nullptr);
ai_assert(strMode != nullptr);
FILE* file;
#ifdef _WIN32
wchar_t fileName16[PATHLIMIT];
#ifndef WindowsStore
bool isUnicode = IsTextUnicode(strFile, static_cast<int>(strlen(strFile)), NULL) != 0;
if (isUnicode) {
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, strFile, -1, fileName16, PATHLIMIT);
std::string mode8(strMode);
file = ::_wfopen(fileName16, std::wstring(mode8.begin(), mode8.end()).c_str());
} else {
#endif
file = ::fopen(strFile, strMode);
#ifndef WindowsStore
}
#endif
file = ::_wfopen(Utf8ToWide(strFile).c_str(), Utf8ToWide(strMode).c_str());
#else
file = ::fopen(strFile, strMode);
#endif
if (nullptr == file)
if (!file)
return nullptr;
return new DefaultIOStream(file, (std::string) strFile);
return new DefaultIOStream(file, strFile);
}
// ------------------------------------------------------------------------------------------------
// Closes the given file and releases all resources associated with it.
void DefaultIOSystem::Close( IOStream* pFile)
void DefaultIOSystem::Close(IOStream* pFile)
{
delete pFile;
}
@ -155,78 +138,56 @@ char DefaultIOSystem::getOsSeparator() const
// ------------------------------------------------------------------------------------------------
// IOSystem default implementation (ComparePaths isn't a pure virtual function)
bool IOSystem::ComparePaths (const char* one, const char* second) const
bool IOSystem::ComparePaths(const char* one, const char* second) const
{
return !ASSIMP_stricmp(one,second);
return !ASSIMP_stricmp(one, second);
}
// ------------------------------------------------------------------------------------------------
// Convert a relative path into an absolute path
inline static void MakeAbsolutePath (const char* in, char* _out)
inline static std::string MakeAbsolutePath(const char* in)
{
ai_assert(in && _out);
#if defined( _MSC_VER ) || defined( __MINGW32__ )
#ifndef WindowsStore
bool isUnicode = IsTextUnicode(in, static_cast<int>(strlen(in)), NULL) != 0;
if (isUnicode) {
wchar_t out16[PATHLIMIT];
wchar_t in16[PATHLIMIT];
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, in, -1, out16, PATHLIMIT);
wchar_t* ret = ::_wfullpath(out16, in16, PATHLIMIT);
ai_assert(in);
std::string out;
#ifdef _WIN32
wchar_t* ret = ::_wfullpath(nullptr, Utf8ToWide(in).c_str(), 0);
if (ret) {
WideCharToMultiByte(CP_UTF8, MB_PRECOMPOSED, out16, -1, _out, PATHLIMIT, nullptr, nullptr);
out = WideToUtf8(ret);
free(ret);
}
if (!ret) {
// preserve the input path, maybe someone else is able to fix
// the path before it is accessed (e.g. our file system filter)
ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
strcpy(_out, in);
}
} else {
#endif
char* ret = :: _fullpath(_out, in, PATHLIMIT);
if (!ret) {
// preserve the input path, maybe someone else is able to fix
// the path before it is accessed (e.g. our file system filter)
ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
strcpy(_out, in);
}
#ifndef WindowsStore
}
#endif
#else
// use realpath
char* ret = realpath(in, _out);
if(!ret) {
char* ret = realpath(in, nullptr);
if (ret) {
out = ret;
free(ret);
}
#endif
if (!ret) {
// preserve the input path, maybe someone else is able to fix
// the path before it is accessed (e.g. our file system filter)
ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
strcpy(_out,in);
out = in;
}
#endif
return out;
}
// ------------------------------------------------------------------------------------------------
// DefaultIOSystem's more specialized implementation
bool DefaultIOSystem::ComparePaths (const char* one, const char* second) const
bool DefaultIOSystem::ComparePaths(const char* one, const char* second) const
{
// chances are quite good both paths are formatted identically,
// so we can hopefully return here already
if( !ASSIMP_stricmp(one,second) )
if (!ASSIMP_stricmp(one, second))
return true;
char temp1[PATHLIMIT];
char temp2[PATHLIMIT];
std::string temp1 = MakeAbsolutePath(one);
std::string temp2 = MakeAbsolutePath(second);
MakeAbsolutePath (one, temp1);
MakeAbsolutePath (second, temp2);
return !ASSIMP_stricmp(temp1,temp2);
return !ASSIMP_stricmp(temp1, temp2);
}
// ------------------------------------------------------------------------------------------------
std::string DefaultIOSystem::fileName( const std::string &path )
std::string DefaultIOSystem::fileName(const std::string& path)
{
std::string ret = path;
std::size_t last = ret.find_last_of("\\/");
@ -235,16 +196,16 @@ std::string DefaultIOSystem::fileName( const std::string &path )
}
// ------------------------------------------------------------------------------------------------
std::string DefaultIOSystem::completeBaseName( const std::string &path )
std::string DefaultIOSystem::completeBaseName(const std::string& path)
{
std::string ret = fileName(path);
std::size_t pos = ret.find_last_of('.');
if(pos != ret.npos) ret = ret.substr(0, pos);
if (pos != std::string::npos) ret = ret.substr(0, pos);
return ret;
}
// ------------------------------------------------------------------------------------------------
std::string DefaultIOSystem::absolutePath( const std::string &path )
std::string DefaultIOSystem::absolutePath(const std::string& path)
{
std::string ret = path;
std::size_t last = ret.find_last_of("\\/");
@ -253,5 +214,3 @@ std::string DefaultIOSystem::absolutePath( const std::string &path )
}
// ------------------------------------------------------------------------------------------------
#undef PATHLIMIT

View File

@ -315,34 +315,6 @@ const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const cha
return pimpl->blob;
}
// ------------------------------------------------------------------------------------------------
bool IsVerboseFormat(const aiMesh* mesh) {
// avoid slow vector<bool> specialization
std::vector<unsigned int> seen(mesh->mNumVertices,0);
for(unsigned int i = 0; i < mesh->mNumFaces; ++i) {
const aiFace& f = mesh->mFaces[i];
for(unsigned int j = 0; j < f.mNumIndices; ++j) {
if(++seen[f.mIndices[j]] == 2) {
// found a duplicate index
return false;
}
}
}
return true;
}
// ------------------------------------------------------------------------------------------------
bool IsVerboseFormat(const aiScene* pScene) {
for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
if(!IsVerboseFormat(pScene->mMeshes[i])) {
return false;
}
}
return true;
}
// ------------------------------------------------------------------------------------------------
aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const char* pPath,
unsigned int pPreprocessing, const ExportProperties* pProperties) {
@ -352,7 +324,7 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
// format. They will likely not be aware that there is a flag in the scene to indicate
// this, however. To avoid surprises and bug reports, we check for duplicates in
// meshes upfront.
const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || IsVerboseFormat(pScene);
const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || MakeVerboseFormatProcess::IsVerboseFormat(pScene);
pimpl->mProgressHandler->UpdateFileWrite(0, 4);
@ -472,7 +444,10 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
}
ExportProperties emptyProperties; // Never pass NULL ExportProperties so Exporters don't have to worry.
exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProperties ? pProperties : &emptyProperties);
ExportProperties* pProp = pProperties ? (ExportProperties*)pProperties : &emptyProperties;
pProp->SetPropertyBool("bJoinIdenticalVertices", must_join_again);
exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProp);
exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProp);
pimpl->mProgressHandler->UpdateFileWrite(4, 4);
} catch (DeadlyExportError& err) {

View File

@ -1091,6 +1091,35 @@ void SceneCombiner::Copy( aiMesh** _dest, const aiMesh* src ) {
aiFace& f = dest->mFaces[i];
GetArrayCopy(f.mIndices,f.mNumIndices);
}
// make a deep copy of all blend shapes
CopyPtrArray(dest->mAnimMeshes, dest->mAnimMeshes, dest->mNumAnimMeshes);
}
// ------------------------------------------------------------------------------------------------
void SceneCombiner::Copy(aiAnimMesh** _dest, const aiAnimMesh* src) {
if (nullptr == _dest || nullptr == src) {
return;
}
aiAnimMesh* dest = *_dest = new aiAnimMesh();
// get a flat copy
::memcpy(dest, src, sizeof(aiAnimMesh));
// and reallocate all arrays
GetArrayCopy(dest->mVertices, dest->mNumVertices);
GetArrayCopy(dest->mNormals, dest->mNumVertices);
GetArrayCopy(dest->mTangents, dest->mNumVertices);
GetArrayCopy(dest->mBitangents, dest->mNumVertices);
unsigned int n = 0;
while (dest->HasTextureCoords(n))
GetArrayCopy(dest->mTextureCoords[n++], dest->mNumVertices);
n = 0;
while (dest->HasVertexColors(n))
GetArrayCopy(dest->mColors[n++], dest->mNumVertices);
}
// ------------------------------------------------------------------------------------------------
@ -1167,6 +1196,7 @@ void SceneCombiner::Copy( aiAnimation** _dest, const aiAnimation* src ) {
// and reallocate all arrays
CopyPtrArray( dest->mChannels, src->mChannels, dest->mNumChannels );
CopyPtrArray( dest->mMorphMeshChannels, src->mMorphMeshChannels, dest->mNumMorphMeshChannels );
}
// ------------------------------------------------------------------------------------------------
@ -1186,6 +1216,26 @@ void SceneCombiner::Copy(aiNodeAnim** _dest, const aiNodeAnim* src) {
GetArrayCopy( dest->mRotationKeys, dest->mNumRotationKeys );
}
void SceneCombiner::Copy(aiMeshMorphAnim** _dest, const aiMeshMorphAnim* src) {
if ( nullptr == _dest || nullptr == src ) {
return;
}
aiMeshMorphAnim* dest = *_dest = new aiMeshMorphAnim();
// get a flat copy
::memcpy(dest,src,sizeof(aiMeshMorphAnim));
// and reallocate all arrays
GetArrayCopy( dest->mKeys, dest->mNumKeys );
for (ai_uint i = 0; i < dest->mNumKeys;++i) {
dest->mKeys[i].mValues = new unsigned int[dest->mKeys[i].mNumValuesAndWeights];
dest->mKeys[i].mWeights = new double[dest->mKeys[i].mNumValuesAndWeights];
::memcpy(dest->mKeys[i].mValues, src->mKeys[i].mValues, dest->mKeys[i].mNumValuesAndWeights * sizeof(unsigned int));
::memcpy(dest->mKeys[i].mWeights, src->mKeys[i].mWeights, dest->mKeys[i].mNumValuesAndWeights * sizeof(double));
}
}
// ------------------------------------------------------------------------------------------------
void SceneCombiner::Copy( aiCamera** _dest,const aiCamera* src) {
if ( nullptr == _dest || nullptr == src ) {

View File

@ -46,8 +46,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/scene.h>
#include "ScenePrivate.h"
static const unsigned int MajorVersion = 4;
static const unsigned int MinorVersion = 1;
static const unsigned int MajorVersion = 5;
static const unsigned int MinorVersion = 0;
// --------------------------------------------------------------------------------
// Legal information string - don't remove this.

View File

@ -55,6 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FBXImporter.h"
#include <assimp/StringComparison.h>
#include <assimp/MathFunctions.h>
#include <assimp/scene.h>
@ -78,7 +79,7 @@ namespace Assimp {
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit )
FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones )
: defaultMaterialIndex()
, lights()
, cameras()
@ -90,8 +91,7 @@ namespace Assimp {
, mNodeNames()
, anim_fps()
, out(out)
, doc(doc)
, mCurrentUnit(FbxUnit::cm) {
, doc(doc) {
// animations need to be converted first since this will
// populate the node_anim_chain_bits map, which is needed
// to determine which nodes need to be generated.
@ -119,7 +119,6 @@ namespace Assimp {
ConvertGlobalSettings();
TransferDataToScene();
ConvertToUnitScale(unit);
// if we didn't read any meshes set the AI_SCENE_FLAGS_INCOMPLETE
// to make sure the scene passes assimp's validation. FBX files
@ -555,7 +554,7 @@ namespace Assimp {
return;
}
const float angle_epsilon = 1e-6f;
const float angle_epsilon = Math::getEpsilon<float>();
out = aiMatrix4x4();
@ -696,7 +695,7 @@ namespace Assimp {
std::fill_n(chain, static_cast<unsigned int>(TransformationComp_MAXIMUM), aiMatrix4x4());
// generate transformation matrices for all the different transformation components
const float zero_epsilon = 1e-6f;
const float zero_epsilon = Math::getEpsilon<float>();
const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
const aiVector3D& PreRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
@ -2003,6 +2002,21 @@ namespace Assimp {
TrySetTextureProperties(out_mat, textures, "Maya|SpecularTexture", aiTextureType_SPECULAR, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|FalloffTexture", aiTextureType_OPACITY, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|ReflectionMapTexture", aiTextureType_REFLECTION, mesh);
// Maya PBR
TrySetTextureProperties(out_mat, textures, "Maya|baseColor|file", aiTextureType_BASE_COLOR, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|normalCamera|file", aiTextureType_NORMAL_CAMERA, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|emissionColor|file", aiTextureType_EMISSION_COLOR, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|metalness|file", aiTextureType_METALNESS, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|diffuseRoughness|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
// Maya stingray
TrySetTextureProperties(out_mat, textures, "Maya|TEX_color_map|file", aiTextureType_BASE_COLOR, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|TEX_normal_map|file", aiTextureType_NORMAL_CAMERA, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|TEX_emissive_map|file", aiTextureType_EMISSION_COLOR, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|TEX_metallic_map|file", aiTextureType_METALNESS, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|TEX_roughness_map|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|TEX_ao_map|file", aiTextureType_AMBIENT_OCCLUSION, mesh);
}
void FBXConverter::SetTextureProperties(aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh)
@ -2954,7 +2968,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
TransformationCompDefaultValue(comp)
);
const float epsilon = 1e-6f;
const float epsilon = Math::getEpsilon<float>();
return (dyn_val - static_val).SquareLength() < epsilon;
}
@ -3537,46 +3551,6 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
out->mMetaData->Set(14, "CustomFrameRate", doc.GlobalSettings().CustomFrameRate());
}
void FBXConverter::ConvertToUnitScale( FbxUnit unit ) {
if (mCurrentUnit == unit) {
return;
}
ai_real scale = 1.0;
if (mCurrentUnit == FbxUnit::cm) {
if (unit == FbxUnit::m) {
scale = (ai_real)0.01;
} else if (unit == FbxUnit::km) {
scale = (ai_real)0.00001;
}
} else if (mCurrentUnit == FbxUnit::m) {
if (unit == FbxUnit::cm) {
scale = (ai_real)100.0;
} else if (unit == FbxUnit::km) {
scale = (ai_real)0.001;
}
} else if (mCurrentUnit == FbxUnit::km) {
if (unit == FbxUnit::cm) {
scale = (ai_real)100000.0;
} else if (unit == FbxUnit::m) {
scale = (ai_real)1000.0;
}
}
for (auto mesh : meshes) {
if (nullptr == mesh) {
continue;
}
if (mesh->HasPositions()) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D &pos = mesh->mVertices[i];
pos *= scale;
}
}
}
}
void FBXConverter::TransferDataToScene()
{
ai_assert(!out->mMeshes);
@ -3630,9 +3604,9 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
}
// ------------------------------------------------------------------------------------------------
void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit)
void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones)
{
FBXConverter converter(out, doc, removeEmptyBones, unit);
FBXConverter converter(out, doc, removeEmptyBones);
}
} // !FBX

View File

@ -76,23 +76,13 @@ namespace Assimp {
namespace FBX {
class Document;
enum class FbxUnit {
cm = 0,
m,
km,
NumUnits,
Undefined
};
/**
* Convert a FBX #Document to #aiScene
* @param out Empty scene to be populated
* @param doc Parsed FBX document
* @param removeEmptyBones Will remove bones, which do not have any references to vertices.
*/
void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit);
void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones);
/** Dummy class to encapsulate the conversion process */
class FBXConverter {
@ -123,7 +113,7 @@ public:
};
public:
FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit);
FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones);
~FBXConverter();
private:
@ -430,10 +420,6 @@ private:
void ConvertGlobalSettings();
// ------------------------------------------------------------------------------------------------
// Will perform the conversion from a given unit to the requested unit.
void ConvertToUnitScale(FbxUnit unit);
// ------------------------------------------------------------------------------------------------
// copy generated meshes, animations, lights, cameras and textures to the output scene
void TransferDataToScene();
@ -470,7 +456,6 @@ private:
aiScene* const out;
const FBX::Document& doc;
FbxUnit mCurrentUnit;
};
}

View File

@ -59,11 +59,7 @@ namespace FBX {
FBXExportProperty::FBXExportProperty(bool v)
: type('C')
, data(1) {
data = {
uint8_t(v)
};
}
, data(1, uint8_t(v)) {}
FBXExportProperty::FBXExportProperty(int16_t v)
: type('Y')

View File

@ -67,6 +67,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <vector>
#include <array>
#include <unordered_set>
#include <numeric>
// RESOURCES:
// https://code.blender.org/2013/08/fbx-binary-file-format-specification/
@ -1005,6 +1006,9 @@ void FBXExporter::WriteObjects ()
object_node.EndProperties(outstream, binary, indent);
object_node.BeginChildren(outstream, binary, indent);
bool bJoinIdenticalVertices = mProperties->GetPropertyBool("bJoinIdenticalVertices", true);
std::vector<std::vector<int32_t>> vVertexIndice;//save vertex_indices as it is needed later
// geometry (aiMesh)
mesh_uids.clear();
indent = 1;
@ -1031,6 +1035,7 @@ void FBXExporter::WriteObjects ()
std::vector<int32_t> vertex_indices;
// map of vertex value to its index in the data vector
std::map<aiVector3D,size_t> index_by_vertex_value;
if(bJoinIdenticalVertices){
int32_t index = 0;
for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
aiVector3D vtx = m->mVertices[vi];
@ -1046,6 +1051,19 @@ void FBXExporter::WriteObjects ()
vertex_indices.push_back(int32_t(elem->second));
}
}
}
else { // do not join vertex, respect the export flag
vertex_indices.resize(m->mNumVertices);
std::iota(vertex_indices.begin(), vertex_indices.end(), 0);
for(unsigned int v = 0; v < m->mNumVertices; ++ v) {
aiVector3D vtx = m->mVertices[v];
flattened_vertices.push_back(vtx.x);
flattened_vertices.push_back(vtx.y);
flattened_vertices.push_back(vtx.z);
}
}
vVertexIndice.push_back(vertex_indices);
FBX::Node::WritePropertyNode(
"Vertices", flattened_vertices, outstream, binary, indent
);
@ -1116,6 +1134,51 @@ void FBXExporter::WriteObjects ()
normals.End(outstream, binary, indent, true);
}
// colors, if any
// TODO only one color channel currently
const int32_t colorChannelIndex = 0;
if (m->HasVertexColors(colorChannelIndex)) {
FBX::Node vertexcolors("LayerElementColor", int32_t(colorChannelIndex));
vertexcolors.Begin(outstream, binary, indent);
vertexcolors.DumpProperties(outstream, binary, indent);
vertexcolors.EndProperties(outstream, binary, indent);
vertexcolors.BeginChildren(outstream, binary, indent);
indent = 3;
FBX::Node::WritePropertyNode(
"Version", int32_t(101), outstream, binary, indent
);
char layerName[8];
sprintf(layerName, "COLOR_%d", colorChannelIndex);
FBX::Node::WritePropertyNode(
"Name", (const char*)layerName, outstream, binary, indent
);
FBX::Node::WritePropertyNode(
"MappingInformationType", "ByPolygonVertex",
outstream, binary, indent
);
FBX::Node::WritePropertyNode(
"ReferenceInformationType", "Direct",
outstream, binary, indent
);
std::vector<double> color_data;
color_data.reserve(4 * polygon_data.size());
for (size_t fi = 0; fi < m->mNumFaces; ++fi) {
const aiFace &f = m->mFaces[fi];
for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) {
const aiColor4D &c = m->mColors[colorChannelIndex][f.mIndices[pvi]];
color_data.push_back(c.r);
color_data.push_back(c.g);
color_data.push_back(c.b);
color_data.push_back(c.a);
}
}
FBX::Node::WritePropertyNode(
"Colors", color_data, outstream, binary, indent
);
indent = 2;
vertexcolors.End(outstream, binary, indent, true);
}
// uvs, if any
for (size_t uvi = 0; uvi < m->GetNumUVChannels(); ++uvi) {
if (m->mNumUVComponents[uvi] > 2) {
@ -1209,6 +1272,11 @@ void FBXExporter::WriteObjects ()
le.AddChild("Type", "LayerElementNormal");
le.AddChild("TypedIndex", int32_t(0));
layer.AddChild(le);
// TODO only 1 color channel currently
le = FBX::Node("LayerElement");
le.AddChild("Type", "LayerElementColor");
le.AddChild("TypedIndex", int32_t(0));
layer.AddChild(le);
le = FBX::Node("LayerElement");
le.AddChild("Type", "LayerElementMaterial");
le.AddChild("TypedIndex", int32_t(0));
@ -1221,7 +1289,7 @@ void FBXExporter::WriteObjects ()
for(unsigned int lr = 1; lr < m->GetNumUVChannels(); ++ lr)
{
FBX::Node layerExtra("Layer", int32_t(1));
FBX::Node layerExtra("Layer", int32_t(lr));
layerExtra.AddChild("Version", int32_t(100));
FBX::Node leExtra("LayerElement");
leExtra.AddChild("Type", "LayerElementUV");
@ -1748,28 +1816,8 @@ void FBXExporter::WriteObjects ()
// connect it
connections.emplace_back("C", "OO", deformer_uid, mesh_uids[mi]);
// we will be indexing by vertex...
// but there might be a different number of "vertices"
// between assimp and our output FBX.
// this code is cut-and-pasted from the geometry section above...
// ideally this should not be so.
// ---
// index of original vertex in vertex data vector
std::vector<int32_t> vertex_indices;
// map of vertex value to its index in the data vector
std::map<aiVector3D,size_t> index_by_vertex_value;
int32_t index = 0;
for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
aiVector3D vtx = m->mVertices[vi];
auto elem = index_by_vertex_value.find(vtx);
if (elem == index_by_vertex_value.end()) {
vertex_indices.push_back(index);
index_by_vertex_value[vtx] = index;
++index;
} else {
vertex_indices.push_back(int32_t(elem->second));
}
}
//computed before
std::vector<int32_t>& vertex_indices = vVertexIndice[mi];
// TODO, FIXME: this won't work if anything is not in the bind pose.
// for now if such a situation is detected, we throw an exception.
@ -2435,7 +2483,7 @@ void FBXExporter::WriteModelNodes(
void FBXExporter::WriteAnimationCurveNode(
StreamWriterLE& outstream,
int64_t uid,
std::string name, // "T", "R", or "S"
const std::string& name, // "T", "R", or "S"
aiVector3D default_value,
std::string property_name, // "Lcl Translation" etc
int64_t layer_uid,

View File

@ -156,7 +156,7 @@ namespace Assimp
void WriteAnimationCurveNode(
StreamWriterLE& outstream,
int64_t uid,
std::string name, // "T", "R", or "S"
const std::string& name, // "T", "R", or "S"
aiVector3D default_value,
std::string property_name, // "Lcl Translation" etc
int64_t animation_layer_uid,

View File

@ -185,16 +185,15 @@ void FBXImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
// take the raw parse-tree and convert it to a FBX DOM
Document doc(parser,settings);
FbxUnit unit(FbxUnit::cm);
if (settings.convertToMeters) {
unit = FbxUnit::m;
}
// convert the FBX DOM to aiScene
ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones, unit);
ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones);
// units is relative to CM :) we need it in meters for assimp
SetFileScale( doc.GlobalSettings().UnitScaleFactor() * 0.01f);
// size relative to cm
float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor();
// Set FBX file scale is relative to CM must be converted to M for
// assimp universal format (M)
SetFileScale( size_relative_to_cm * 0.01f);
std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
}

View File

@ -311,10 +311,9 @@ class TrimmedCurve : public BoundedCurve {
public:
// --------------------------------------------------
TrimmedCurve(const Schema_2x3::IfcTrimmedCurve& entity, ConversionData& conv)
: BoundedCurve(entity,conv)
: BoundedCurve(entity,conv),
base(std::shared_ptr<const Curve>(Curve::Convert(entity.BasisCurve,conv)))
{
base = std::shared_ptr<const Curve>(Curve::Convert(entity.BasisCurve,conv));
typedef std::shared_ptr<const STEP::EXPRESS::DataType> Entry;
// for some reason, trimmed curves can either specify a parametric value
@ -500,7 +499,7 @@ bool Curve::InRange(IfcFloat u) const {
if (IsClosed()) {
return true;
}
const IfcFloat epsilon = 1e-5;
const IfcFloat epsilon = Math::getEpsilon<float>();
return u - range.first > -epsilon && range.second - u > -epsilon;
}
#endif

View File

@ -128,7 +128,7 @@ void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t m
outer_polygon_it = begin + master_bounds;
}
else {
for(iit = begin; iit != end; iit++) {
for(iit = begin; iit != end; ++iit) {
// find the polygon with the largest area and take it as the outer bound.
IfcVector3& n = normals[std::distance(begin,iit)];
const IfcFloat area = n.SquareLength();

View File

@ -593,7 +593,7 @@ typedef std::vector<std::pair<
bool BoundingBoxesAdjacent(const BoundingBox& bb, const BoundingBox& ibb)
{
// TODO: I'm pretty sure there is a much more compact way to check this
const IfcFloat epsilon = 1e-5f;
const IfcFloat epsilon = Math::getEpsilon<float>();
return (std::fabs(bb.second.x - ibb.first.x) < epsilon && bb.first.y <= ibb.second.y && bb.second.y >= ibb.first.y) ||
(std::fabs(bb.first.x - ibb.second.x) < epsilon && ibb.first.y <= bb.second.y && ibb.second.y >= bb.first.y) ||
(std::fabs(bb.second.y - ibb.first.y) < epsilon && bb.first.x <= ibb.second.x && bb.second.x >= ibb.first.x) ||
@ -681,7 +681,7 @@ bool IntersectingLineSegments(const IfcVector2& n0, const IfcVector2& n1,
// ------------------------------------------------------------------------------------------------
void FindAdjacentContours(ContourVector::iterator current, const ContourVector& contours)
{
const IfcFloat sqlen_epsilon = static_cast<IfcFloat>(1e-8);
const IfcFloat sqlen_epsilon = static_cast<IfcFloat>(Math::getEpsilon<float>());
const BoundingBox& bb = (*current).bb;
// What is to be done here is to populate the skip lists for the contour
@ -758,7 +758,7 @@ void FindAdjacentContours(ContourVector::iterator current, const ContourVector&
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE bool LikelyBorder(const IfcVector2& vdelta)
{
const IfcFloat dot_point_epsilon = static_cast<IfcFloat>(1e-5);
const IfcFloat dot_point_epsilon = static_cast<IfcFloat>(Math::getEpsilon<float>());
return std::fabs(vdelta.x * vdelta.y) < dot_point_epsilon;
}

View File

@ -57,7 +57,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/material.h>
#include <assimp/scene.h>
#include <assimp/importerdesc.h>
#include <assimp/Macros.h>
using namespace Assimp;
using namespace irr;

View File

@ -344,7 +344,7 @@ void MD2Importer::InternReadFile( const std::string& pFile,
if (pcSkins->name[0])
{
aiString szString;
const size_t iLen = ::strlen(pcSkins->name);
const ai_uint32 iLen = (ai_uint32) ::strlen(pcSkins->name);
::memcpy(szString.data,pcSkins->name,iLen);
szString.data[iLen] = '\0';
szString.length = iLen;

View File

@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "MD5Loader.h"
#include <assimp/StringComparison.h>
#include <assimp/fast_atof.h>
#include <assimp/MathFunctions.h>
#include <assimp/SkeletonMeshBuilder.h>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
@ -64,7 +65,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp;
// Minimum weight value. Weights inside [-n ... n] are ignored
#define AI_MD5_WEIGHT_EPSILON 1e-5f
#define AI_MD5_WEIGHT_EPSILON Math::getEpsilon<float>()
static const aiImporterDesc desc = {

View File

@ -235,7 +235,7 @@ bool MD5Parser::ParseSection(Section& out)
const char* szStart = ++sz; \
while('\"'!=*sz)++sz; \
const char* szEnd = (sz++); \
out.length = (size_t)(szEnd - szStart); \
out.length = (ai_uint32) (szEnd - szStart); \
::memcpy(out.data,szStart,out.length); \
out.data[out.length] = '\0';
// ------------------------------------------------------------------------------------------------

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2019, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -54,7 +52,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "MDL/MDLDefaultColorMap.h"
#include "MD2/MD2FileData.h"
#include <assimp/Macros.h>
#include <assimp/qnan.h>
#include <assimp/StringUtils.h>
#include <assimp/Importer.hpp>
@ -94,23 +91,24 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
MDLImporter::MDLImporter()
: configFrameID(),
mBuffer(),
iGSFileVersion(),
pIOHandler(),
pScene(),
iFileSize()
{}
: configFrameID()
, mBuffer()
, iGSFileVersion()
, pIOHandler()
, pScene()
, iFileSize() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
MDLImporter::~MDLImporter()
{}
MDLImporter::~MDLImporter() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool MDLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{
bool MDLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const {
const std::string extension = GetExtension(pFile);
// if check for extension is not enough, check for the magic tokens
@ -404,23 +402,15 @@ void MDLImporter::InternReadFile_Quake1() {
// now get a pointer to the first frame in the file
BE_NCONST MDL::Frame* pcFrames = (BE_NCONST MDL::Frame*)szCurrent;
BE_NCONST MDL::SimpleFrame* pcFirstFrame;
MDL::SimpleFrame* pcFirstFrame;
if (0 == pcFrames->type) {
// get address of single frame
pcFirstFrame = &pcFrames->frame;
pcFirstFrame =( MDL::SimpleFrame*) &pcFrames->frame;
} else {
// get the first frame in the group
#if 1
// FIXME: the cast is wrong and cause a warning on clang 5.0
// disable this code for now, fix it later
ai_assert(false && "Bad pointer cast");
pcFirstFrame = nullptr; // Workaround: msvc++ C4703 error
#else
BE_NCONST MDL::GroupFrame* pcFrames2 = (BE_NCONST MDL::GroupFrame*)pcFrames;
pcFirstFrame = (BE_NCONST MDL::SimpleFrame*)(&pcFrames2->time + pcFrames->type);
#endif
BE_NCONST MDL::GroupFrame* pcFrames2 = (BE_NCONST MDL::GroupFrame*) pcFrames;
pcFirstFrame = &(pcFrames2->frames[0]);
}
BE_NCONST MDL::Vertex* pcVertices = (BE_NCONST MDL::Vertex*) ((pcFirstFrame->name) + sizeof(pcFirstFrame->name));
VALIDATE_FILE_SIZE((const unsigned char*)(pcVertices + pcHeader->num_verts));

View File

@ -89,16 +89,12 @@ public:
MDLImporter();
~MDLImporter();
public:
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const;
// -------------------------------------------------------------------
/** Called prior to ReadFile().
* The function is a request to the importer to update its configuration
@ -107,8 +103,6 @@ public:
void SetupProperties(const Importer* pImp);
protected:
// -------------------------------------------------------------------
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details
@ -122,8 +116,6 @@ protected:
void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler);
protected:
// -------------------------------------------------------------------
/** Import a quake 1 MDL file (IDPO)
*/
@ -154,7 +146,6 @@ protected:
void SizeCheck(const void* szPos);
void SizeCheck(const void* szPos, const char* szFile, unsigned int iLine);
// -------------------------------------------------------------------
/** Validate the header data structure of a game studio MDL7 file
* \param pcHeader Input header to be validated
@ -167,7 +158,6 @@ protected:
*/
void ValidateHeader_Quake1(const MDL::Header* pcHeader);
// -------------------------------------------------------------------
/** Try to load a palette from the current directory (colormap.lmp)
* If it is not found the default palette of Quake1 is returned
@ -179,9 +169,8 @@ protected:
*/
void FreePalette(const unsigned char* pszColorMap);
// -------------------------------------------------------------------
/** Load a paletized texture from the file and convert it to 32bpp
/** Load a palletized texture from the file and convert it to 32bpp
*/
void CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData);
@ -195,7 +184,6 @@ protected:
unsigned int iType,
unsigned int* piSkip);
// -------------------------------------------------------------------
/** Used to load textures from MDL5
* \param szData Input data
@ -206,7 +194,6 @@ protected:
unsigned int iType,
unsigned int* piSkip);
// -------------------------------------------------------------------
/** Checks whether a texture can be replaced with a single color
* This is useful for all file formats before MDL7 (all those
@ -218,14 +205,12 @@ protected:
*/
aiColor4D ReplaceTextureWithColor(const aiTexture* pcTexture);
// -------------------------------------------------------------------
/** Converts the absolute texture coordinates in MDL5 files to
* relative in a range between 0 and 1
*/
void CalculateUVCoordinates_MDL5();
// -------------------------------------------------------------------
/** Read an UV coordinate from the file. If the file format is not
* MDL5, the function calculates relative texture coordinates
@ -245,7 +230,6 @@ protected:
*/
void SetupMaterialProperties_3DGS_MDL5_Quake1( );
// -------------------------------------------------------------------
/** Parse a skin lump in a MDL7/HMP7 file with all of its features
* variant 1: Current cursor position is the beginning of the skin header

View File

@ -51,7 +51,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/types.h>
#include <assimp/material.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/Macros.h>
using namespace Assimp;
@ -545,23 +544,7 @@ aiReturn aiMaterial::AddProperty (const aiString* pInput,
unsigned int type,
unsigned int index)
{
// We don't want to add the whole buffer .. write a 32 bit length
// prefix followed by the zero-terminated UTF8 string.
// (HACK) I don't want to break the ABI now, but we definitely
// ought to change aiString::mLength to uint32_t one day.
if (sizeof(size_t) == 8) {
aiString copy = *pInput;
uint32_t* s = reinterpret_cast<uint32_t*>(&copy.length);
s[1] = static_cast<uint32_t>(pInput->length);
return AddBinaryProperty(s+1,
static_cast<unsigned int>(pInput->length+1+4),
pKey,
type,
index,
aiPTI_String);
}
ai_assert(sizeof(size_t)==4);
ai_assert(sizeof(ai_uint32)==4);
return AddBinaryProperty(pInput,
static_cast<unsigned int>(pInput->length+1+4),
pKey,

View File

@ -79,10 +79,7 @@ using namespace std;
ObjFileImporter::ObjFileImporter()
: m_Buffer()
, m_pRootObject( nullptr )
, m_strAbsPath( "" ) {
DefaultIOSystem io;
m_strAbsPath = io.getOsSeparator();
}
, m_strAbsPath( std::string(1, DefaultIOSystem().getOsSeparator()) ) {}
// ------------------------------------------------------------------------------------------------
// Destructor.

View File

@ -244,8 +244,8 @@ void ObjFileParser::copyNextWord(char *pBuffer, size_t length) {
size_t index = 0;
m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
if ( *m_DataIt == '\\' ) {
m_DataIt++;
m_DataIt++;
++m_DataIt;
++m_DataIt;
m_DataIt = getNextWord<DataArrayIt>( m_DataIt, m_DataItEnd );
}
while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) {

View File

@ -49,7 +49,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// internal headers
#include "PlyLoader.h"
#include <assimp/IOStreamBuffer.h>
#include <assimp/Macros.h>
#include <memory>
#include <assimp/IOSystem.hpp>
#include <assimp/scene.h>

View File

@ -354,12 +354,12 @@ void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D&
}
else if (axis * base_axis_z >= angle_epsilon) {
FindMeshCenter(mesh, center, min, max);
diffu = max.y - min.y;
diffv = max.z - min.z;
diffu = max.x - min.x;
diffv = max.y - min.y;
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
const aiVector3D& pos = mesh->mVertices[pnt];
out[pnt].Set((pos.y - min.y) / diffu,(pos.x - min.x) / diffv,0.0);
out[pnt].Set((pos.x - min.x) / diffu,(pos.y - min.y) / diffv,0.0);
}
}
// slower code path in case the mapping axis is not one of the coordinate system axes

View File

@ -52,7 +52,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FindInvalidDataProcess.h"
#include "ProcessHelper.h"
#include <assimp/Macros.h>
#include <assimp/Exceptional.h>
#include <assimp/qnan.h>

View File

@ -224,3 +224,32 @@ bool MakeVerboseFormatProcess::MakeVerboseFormat(aiMesh* pcMesh)
}
return (pcMesh->mNumVertices != iOldNumVertices);
}
// ------------------------------------------------------------------------------------------------
bool IsMeshInVerboseFormat(const aiMesh* mesh) {
// avoid slow vector<bool> specialization
std::vector<unsigned int> seen(mesh->mNumVertices,0);
for(unsigned int i = 0; i < mesh->mNumFaces; ++i) {
const aiFace& f = mesh->mFaces[i];
for(unsigned int j = 0; j < f.mNumIndices; ++j) {
if(++seen[f.mIndices[j]] == 2) {
// found a duplicate index
return false;
}
}
}
return true;
}
// ------------------------------------------------------------------------------------------------
bool MakeVerboseFormatProcess::IsVerboseFormat(const aiScene* pScene) {
for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
if(!IsMeshInVerboseFormat(pScene->mMeshes[i])) {
return false;
}
}
return true;
}

View File

@ -94,6 +94,13 @@ public:
* @param pScene The imported data to work at. */
void Execute( aiScene* pScene);
public:
// -------------------------------------------------------------------
/** Checks whether the scene is already in verbose format.
* @param pScene The data to check.
* @return true if the scene is already in verbose format. */
static bool IsVerboseFormat(const aiScene* pScene);
private:

View File

@ -538,13 +538,17 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
{
Validate(&pAnimation->mName);
// validate all materials
if (pAnimation->mNumChannels)
// validate all animations
if (pAnimation->mNumChannels || pAnimation->mNumMorphMeshChannels)
{
if (!pAnimation->mChannels) {
if (!pAnimation->mChannels && pAnimation->mNumChannels) {
ReportError("aiAnimation::mChannels is NULL (aiAnimation::mNumChannels is %i)",
pAnimation->mNumChannels);
}
if (!pAnimation->mMorphMeshChannels && pAnimation->mNumMorphMeshChannels) {
ReportError("aiAnimation::mMorphMeshChannels is NULL (aiAnimation::mNumMorphMeshChannels is %i)",
pAnimation->mNumMorphMeshChannels);
}
for (unsigned int i = 0; i < pAnimation->mNumChannels;++i)
{
if (!pAnimation->mChannels[i])
@ -554,6 +558,15 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
}
Validate(pAnimation, pAnimation->mChannels[i]);
}
for (unsigned int i = 0; i < pAnimation->mNumMorphMeshChannels;++i)
{
if (!pAnimation->mMorphMeshChannels[i])
{
ReportError("aiAnimation::mMorphMeshChannels[%i] is NULL (aiAnimation::mNumMorphMeshChannels is %i)",
i, pAnimation->mNumMorphMeshChannels);
}
Validate(pAnimation, pAnimation->mMorphMeshChannels[i]);
}
}
else {
ReportError("aiAnimation::mNumChannels is 0. At least one node animation channel must be there.");
@ -903,6 +916,48 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
}
}
void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
const aiMeshMorphAnim* pMeshMorphAnim)
{
Validate(&pMeshMorphAnim->mName);
if (!pMeshMorphAnim->mNumKeys) {
ReportError("Empty mesh morph animation channel");
}
// otherwise check whether one of the keys exceeds the total duration of the animation
if (pMeshMorphAnim->mNumKeys)
{
if (!pMeshMorphAnim->mKeys)
{
ReportError("aiMeshMorphAnim::mKeys is NULL (aiMeshMorphAnim::mNumKeys is %i)",
pMeshMorphAnim->mNumKeys);
}
double dLast = -10e10;
for (unsigned int i = 0; i < pMeshMorphAnim->mNumKeys;++i)
{
// ScenePreprocessor will compute the duration if still the default value
// (Aramis) Add small epsilon, comparison tended to fail if max_time == duration,
// seems to be due the compilers register usage/width.
if (pAnimation->mDuration > 0. && pMeshMorphAnim->mKeys[i].mTime > pAnimation->mDuration+0.001)
{
ReportError("aiMeshMorphAnim::mKeys[%i].mTime (%.5f) is larger "
"than aiAnimation::mDuration (which is %.5f)",i,
(float)pMeshMorphAnim->mKeys[i].mTime,
(float)pAnimation->mDuration);
}
if (i && pMeshMorphAnim->mKeys[i].mTime <= dLast)
{
ReportWarning("aiMeshMorphAnim::mKeys[%i].mTime (%.5f) is smaller "
"than aiMeshMorphAnim::mKeys[%i] (which is %.5f)",i,
(float)pMeshMorphAnim->mKeys[i].mTime,
i-1, (float)dLast);
}
dLast = pMeshMorphAnim->mKeys[i].mTime;
}
}
}
// ------------------------------------------------------------------------------------------------
void ValidateDSProcess::Validate( const aiNode* pNode)
{
@ -958,7 +1013,7 @@ void ValidateDSProcess::Validate( const aiString* pString)
{
if (pString->length > MAXLEN)
{
ReportError("aiString::length is too large (%lu, maximum is %lu)",
ReportError("aiString::length is too large (%u, maximum is %lu)",
pString->length,MAXLEN);
}
const char* sz = pString->data;

View File

@ -55,6 +55,7 @@ struct aiBone;
struct aiMesh;
struct aiAnimation;
struct aiNodeAnim;
struct aiMeshMorphAnim;
struct aiTexture;
struct aiMaterial;
struct aiNode;
@ -150,6 +151,13 @@ protected:
void Validate( const aiAnimation* pAnimation,
const aiNodeAnim* pBoneAnim);
/** Validates a mesh morph animation channel.
* @param pAnimation Input animation.
* @param pMeshMorphAnim Mesh morph animation channel.
* */
void Validate( const aiAnimation* pAnimation,
const aiMeshMorphAnim* pMeshMorphAnim);
// -------------------------------------------------------------------
/** Validates a node and all of its subnodes
* @param Node Input node*/

View File

@ -596,11 +596,11 @@ void XFileParser::ParseDataObjectMeshNormals( Mesh* pMesh)
// do not crah when no face definitions are there
if (numFaces > 0) {
// normal face creation
pMesh->mNormFaces.resize( pMesh->mNormFaces.size() + numFaces );
pMesh->mNormFaces.resize( numFaces );
for( unsigned int a = 0; a < numFaces; ++a ) {
unsigned int numIndices = ReadInt();
pMesh->mNormFaces.push_back( Face() );
Face& face = pMesh->mNormFaces.back();
pMesh->mNormFaces[a] = Face();
Face& face = pMesh->mNormFaces[a];
for( unsigned int b = 0; b < numIndices; ++b ) {
face.mIndices.push_back( ReadInt());
}

View File

@ -68,7 +68,7 @@ aiMatrix4x4 out_matr;
}
// multiplicate all matrices in reverse order
for(std::list<aiMatrix4x4>::reverse_iterator rit = matr.rbegin(); rit != matr.rend(); rit++) out_matr = out_matr * (*rit);
for(std::list<aiMatrix4x4>::reverse_iterator rit = matr.rbegin(); rit != matr.rend(); ++rit) out_matr = out_matr * (*rit);
return out_matr;
}

View File

@ -136,8 +136,8 @@ X3DImporter::~X3DImporter() {
void X3DImporter::Clear() {
NodeElement_Cur = nullptr;
// Delete all elements
if(NodeElement_List.size()) {
for ( std::list<CX3DImporter_NodeElement*>::iterator it = NodeElement_List.begin(); it != NodeElement_List.end(); it++ ) {
if(!NodeElement_List.empty()) {
for ( std::list<CX3DImporter_NodeElement*>::iterator it = NodeElement_List.begin(); it != NodeElement_List.end(); ++it ) {
delete *it;
}
NodeElement_List.clear();
@ -151,7 +151,7 @@ void X3DImporter::Clear() {
bool X3DImporter::FindNodeElement_FromRoot(const std::string& pID, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement)
{
for(std::list<CX3DImporter_NodeElement*>::iterator it = NodeElement_List.begin(); it != NodeElement_List.end(); it++)
for(std::list<CX3DImporter_NodeElement*>::iterator it = NodeElement_List.begin(); it != NodeElement_List.end(); ++it)
{
if(((*it)->Type == pType) && ((*it)->ID == pID))
{
@ -182,7 +182,7 @@ bool X3DImporter::FindNodeElement_FromNode(CX3DImporter_NodeElement* pStartNode,
}// if((pStartNode->Type() == pType) && (pStartNode->ID() == pID))
// Check childs of pStartNode.
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = pStartNode->Child.begin(); ch_it != pStartNode->Child.end(); ch_it++)
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = pStartNode->Child.begin(); ch_it != pStartNode->Child.end(); ++ch_it)
{
found = FindNodeElement_FromNode(*ch_it, pID, pType, pElement);
if ( found )
@ -614,10 +614,10 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrCol3f(const int pAttrIdx, std::ve
XML_ReadNode_GetAttrVal_AsListCol3f(pAttrIdx, tlist);// read as list
// and copy to array
if(tlist.size() > 0)
if(!tlist.empty())
{
pValue.reserve(tlist.size());
for(std::list<aiColor3D>::iterator it = tlist.begin(); it != tlist.end(); it++) pValue.push_back(*it);
for(std::list<aiColor3D>::iterator it = tlist.begin(); it != tlist.end(); ++it) pValue.push_back(*it);
}
}
@ -647,10 +647,10 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrCol4f(const int pAttrIdx, std::ve
XML_ReadNode_GetAttrVal_AsListCol4f(pAttrIdx, tlist);// read as list
// and copy to array
if(tlist.size() > 0)
if(!tlist.empty())
{
pValue.reserve(tlist.size());
for ( std::list<aiColor4D>::iterator it = tlist.begin(); it != tlist.end(); it++ )
for ( std::list<aiColor4D>::iterator it = tlist.begin(); it != tlist.end(); ++it )
{
pValue.push_back( *it );
}
@ -684,10 +684,10 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrVec2f(const int pAttrIdx, std::ve
XML_ReadNode_GetAttrVal_AsListVec2f(pAttrIdx, tlist);// read as list
// and copy to array
if(tlist.size() > 0)
if(!tlist.empty())
{
pValue.reserve(tlist.size());
for ( std::list<aiVector2D>::iterator it = tlist.begin(); it != tlist.end(); it++ )
for ( std::list<aiVector2D>::iterator it = tlist.begin(); it != tlist.end(); ++it )
{
pValue.push_back( *it );
}
@ -722,10 +722,10 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrVec3f(const int pAttrIdx, std::ve
XML_ReadNode_GetAttrVal_AsListVec3f(pAttrIdx, tlist);// read as list
// and copy to array
if(tlist.size() > 0)
if(!tlist.empty())
{
pValue.reserve(tlist.size());
for ( std::list<aiVector3D>::iterator it = tlist.begin(); it != tlist.end(); it++ )
for ( std::list<aiVector3D>::iterator it = tlist.begin(); it != tlist.end(); ++it )
{
pValue.push_back( *it );
}
@ -823,7 +823,7 @@ void X3DImporter::GeometryHelper_Extend_PointToLine(const std::list<aiVector3D>&
std::list<aiVector3D>::const_iterator pit = pPoint.begin();
std::list<aiVector3D>::const_iterator pit_last = pPoint.end();
pit_last--;
--pit_last;
if ( pPoint.size() < 2 )
{
@ -837,7 +837,7 @@ void X3DImporter::GeometryHelper_Extend_PointToLine(const std::list<aiVector3D>&
{
pLine.push_back(*pit);// second point of previous line
pLine.push_back(*pit);// first point of next line
pit++;
++pit;
}
// add last point of last line
pLine.push_back(*pit);
@ -855,7 +855,7 @@ void X3DImporter::GeometryHelper_Extend_PolylineIdxToLineIdx(const std::list<int
{
std::list<int32_t>::const_iterator plit_next;
plit_next = plit, plit_next++;
plit_next = plit, ++plit_next;
pLineCoordIdx.push_back(*plit);// second point of previous line.
pLineCoordIdx.push_back(-1);// delimiter
if((*plit_next == (-1)) || (plit_next == pPolylineCoordIdx.end())) break;// current polyline is finished
@ -910,7 +910,7 @@ void X3DImporter::GeometryHelper_CoordIdxStr2FacesArr(const std::vector<int32_t>
pFaces.reserve(f_data.size() / 3);
inds.reserve(4);
//PrintVectorSet("build. ci", pCoordIdx);
for(std::vector<int32_t>::iterator it = f_data.begin(); it != f_data.end(); it++)
for(std::vector<int32_t>::iterator it = f_data.begin(); it != f_data.end(); ++it)
{
// when face is got count how many indices in it.
if(*it == (-1))
@ -957,7 +957,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<aiColor3D
std::list<aiColor4D> tcol;
// create RGBA array from RGB.
for(std::list<aiColor3D>::const_iterator it = pColors.begin(); it != pColors.end(); it++) tcol.push_back(aiColor4D((*it).r, (*it).g, (*it).b, 1));
for(std::list<aiColor3D>::const_iterator it = pColors.begin(); it != pColors.end(); ++it) tcol.push_back(aiColor4D((*it).r, (*it).g, (*it).b, 1));
// call existing function for adding RGBA colors
MeshGeometry_AddColor(pMesh, tcol, pColorPerVertex);
@ -997,7 +997,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<aiColor4D
pMesh.mColors[ 0 ][ pMesh.mFaces[ fi ].mIndices[ vi ] ] = *col_it;
}
col_it++;
++col_it;
}
}// if(pColorPerVertex) else
}
@ -1008,7 +1008,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::vector<int32_t
std::list<aiColor4D> tcol;
// create RGBA array from RGB.
for ( std::list<aiColor3D>::const_iterator it = pColors.begin(); it != pColors.end(); it++ )
for ( std::list<aiColor3D>::const_iterator it = pColors.begin(); it != pColors.end(); ++it )
{
tcol.push_back( aiColor4D( ( *it ).r, ( *it ).g, ( *it ).b, 1 ) );
}
@ -1031,7 +1031,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::vector<int32_t
// copy list to array because we are need indexed access to colors.
col_arr_copy.reserve(pColors.size());
for ( std::list<aiColor4D>::const_iterator it = pColors.begin(); it != pColors.end(); it++ )
for ( std::list<aiColor4D>::const_iterator it = pColors.begin(); it != pColors.end(); ++it )
{
col_arr_copy.push_back( *it );
}
@ -1048,7 +1048,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::vector<int32_t
}
// create list with colors for every vertex.
col_tgt_arr.resize(pMesh.mNumVertices);
for(std::vector<int32_t>::const_iterator colidx_it = pColorIdx.begin(), coordidx_it = pCoordIdx.begin(); colidx_it != pColorIdx.end(); colidx_it++, coordidx_it++)
for(std::vector<int32_t>::const_iterator colidx_it = pColorIdx.begin(), coordidx_it = pCoordIdx.begin(); colidx_it != pColorIdx.end(); ++colidx_it, ++coordidx_it)
{
if ( *colidx_it == ( -1 ) )
{
@ -1121,7 +1121,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::vector<int32_t
}// if(pColorPerVertex) else
// copy array to list for calling function that add colors.
for(std::vector<aiColor4D>::const_iterator it = col_tgt_arr.begin(); it != col_tgt_arr.end(); it++) col_tgt_list.push_back(*it);
for(std::vector<aiColor4D>::const_iterator it = col_tgt_arr.begin(); it != col_tgt_arr.end(); ++it) col_tgt_list.push_back(*it);
// add prepared colors list to mesh.
MeshGeometry_AddColor(pMesh, col_tgt_list, pColorPerVertex);
}
@ -1134,7 +1134,7 @@ void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::vector<int32_
// copy list to array because we are need indexed access to normals.
norm_arr_copy.reserve(pNormals.size());
for ( std::list<aiVector3D>::const_iterator it = pNormals.begin(); it != pNormals.end(); it++ )
for ( std::list<aiVector3D>::const_iterator it = pNormals.begin(); it != pNormals.end(); ++it )
{
norm_arr_copy.push_back( *it );
}
@ -1147,7 +1147,7 @@ void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::vector<int32_
if(pNormalIdx.size() != pCoordIdx.size()) throw DeadlyImportError("Normals and Coords inidces count must be equal.");
tind.reserve(pNormalIdx.size());
for(std::vector<int32_t>::const_iterator it = pNormalIdx.begin(); it != pNormalIdx.end(); it++)
for(std::vector<int32_t>::const_iterator it = pNormalIdx.begin(); it != pNormalIdx.end(); ++it)
{
if(*it != (-1)) tind.push_back(*it);
}
@ -1227,7 +1227,7 @@ void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::list<aiVector
// apply color to all vertices of face
for(size_t vi = 0, vi_e = pMesh.mFaces[fi].mNumIndices; vi < vi_e; vi++) pMesh.mNormals[pMesh.mFaces[fi].mIndices[vi]] = *norm_it;
norm_it++;
++norm_it;
}
}// if(pNormalPerVertex) else
}
@ -1241,7 +1241,7 @@ void X3DImporter::MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::vector<int3
// copy list to array because we are need indexed access to normals.
texcoord_arr_copy.reserve(pTexCoords.size());
for(std::list<aiVector2D>::const_iterator it = pTexCoords.begin(); it != pTexCoords.end(); it++)
for(std::list<aiVector2D>::const_iterator it = pTexCoords.begin(); it != pTexCoords.end(); ++it)
{
texcoord_arr_copy.push_back(aiVector3D((*it).x, (*it).y, 0));
}
@ -1291,7 +1291,7 @@ void X3DImporter::MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list<aiVect
// copy list to array because we are need convert aiVector2D to aiVector3D and also get indexed access as a bonus.
tc_arr_copy.reserve(pTexCoords.size());
for ( std::list<aiVector2D>::const_iterator it = pTexCoords.begin(); it != pTexCoords.end(); it++ )
for ( std::list<aiVector2D>::const_iterator it = pTexCoords.begin(); it != pTexCoords.end(); ++it )
{
tc_arr_copy.push_back( aiVector3D( ( *it ).x, ( *it ).y, 0 ) );
}
@ -1699,7 +1699,7 @@ void X3DImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
// create nodes tree
Postprocess_BuildNode(*NodeElement_Cur, *pScene->mRootNode, mesh_list, mat_list, light_list);
// copy needed data to scene
if(mesh_list.size() > 0)
if(!mesh_list.empty())
{
std::list<aiMesh*>::const_iterator it = mesh_list.begin();
@ -1708,7 +1708,7 @@ void X3DImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
for(size_t i = 0; i < pScene->mNumMeshes; i++) pScene->mMeshes[i] = *it++;
}
if(mat_list.size() > 0)
if(!mat_list.empty())
{
std::list<aiMaterial*>::const_iterator it = mat_list.begin();
@ -1717,7 +1717,7 @@ void X3DImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
for(size_t i = 0; i < pScene->mNumMaterials; i++) pScene->mMaterials[i] = *it++;
}
if(light_list.size() > 0)
if(!light_list.empty())
{
std::list<aiLight*>::const_iterator it = light_list.begin();

View File

@ -356,7 +356,7 @@ void X3DImporter::ParseNode_Geometry2D_Polyline2D()
std::list<aiVector3D> tlist;
// convert vec2 to vec3
for(std::list<aiVector2D>::iterator it2 = lineSegments.begin(); it2 != lineSegments.end(); it2++) tlist.push_back(aiVector3D(it2->x, it2->y, 0));
for(std::list<aiVector2D>::iterator it2 = lineSegments.begin(); it2 != lineSegments.end(); ++it2) tlist.push_back(aiVector3D(it2->x, it2->y, 0));
// convert point set to line set
GeometryHelper_Extend_PointToLine(tlist, ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices);
@ -399,7 +399,7 @@ void X3DImporter::ParseNode_Geometry2D_Polypoint2D()
if(!def.empty()) ne->ID = def;
// convert vec2 to vec3
for(std::list<aiVector2D>::iterator it2 = point.begin(); it2 != point.end(); it2++)
for(std::list<aiVector2D>::iterator it2 = point.begin(); it2 != point.end(); ++it2)
{
((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices.push_back(aiVector3D(it2->x, it2->y, 0));
}
@ -500,7 +500,7 @@ void X3DImporter::ParseNode_Geometry2D_TriangleSet2D()
if(!def.empty()) ne->ID = def;
// convert vec2 to vec3
for(std::list<aiVector2D>::iterator it2 = vertices.begin(); it2 != vertices.end(); it2++)
for(std::list<aiVector2D>::iterator it2 = vertices.begin(); it2 != vertices.end(); ++it2)
{
((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices.push_back(aiVector3D(it2->x, it2->y, 0));
}

View File

@ -153,11 +153,11 @@ void X3DImporter::ParseNode_Geometry3D_Cone()
{
StandardShapes::MakeCircle(bottomRadius, tess, tvec);
height = -(height / 2);
for(std::vector<aiVector3D>::iterator it = tvec.begin(); it != tvec.end(); it++) it->y = height;// y - because circle made in oXZ.
for(std::vector<aiVector3D>::iterator it = tvec.begin(); it != tvec.end(); ++it) it->y = height;// y - because circle made in oXZ.
}
// copy data from temp array
for(std::vector<aiVector3D>::iterator it = tvec.begin(); it != tvec.end(); it++) ((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices.push_back(*it);
for(std::vector<aiVector3D>::iterator it = tvec.begin(); it != tvec.end(); ++it) ((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices.push_back(*it);
((CX3DImporter_NodeElement_Geometry3D*)ne)->Solid = solid;
((CX3DImporter_NodeElement_Geometry3D*)ne)->NumIndices = 3;
@ -226,11 +226,11 @@ void X3DImporter::ParseNode_Geometry3D_Cylinder()
// copy data from temp arrays
std::list<aiVector3D>& vlist = ((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices;// just short alias.
for(std::vector<aiVector3D>::iterator it = tside.begin(); it != tside.end(); it++) vlist.push_back(*it);
for(std::vector<aiVector3D>::iterator it = tside.begin(); it != tside.end(); ++it) vlist.push_back(*it);
if(top)
{
for(std::vector<aiVector3D>::iterator it = tcir.begin(); it != tcir.end(); it++)
for(std::vector<aiVector3D>::iterator it = tcir.begin(); it != tcir.end(); ++it)
{
(*it).y = height;// y - because circle made in oXZ.
vlist.push_back(*it);
@ -239,7 +239,7 @@ void X3DImporter::ParseNode_Geometry3D_Cylinder()
if(bottom)
{
for(std::vector<aiVector3D>::iterator it = tcir.begin(); it != tcir.end(); it++)
for(std::vector<aiVector3D>::iterator it = tcir.begin(); it != tcir.end(); ++it)
{
(*it).y = -height;// y - because circle made in oXZ.
vlist.push_back(*it);
@ -336,7 +336,7 @@ void X3DImporter::ParseNode_Geometry3D_ElevationGrid()
aiVector3D tvec(xSpacing * xi, *he_it, zSpacing * zi);
grid_alias.Vertices.push_back(tvec);
he_it++;
++he_it;
}
}
}// END: create grid vertices list
@ -977,7 +977,7 @@ void X3DImporter::ParseNode_Geometry3D_Sphere()
StandardShapes::MakeSphere(tess, tlist);
// copy data from temp array and apply scale
for(std::vector<aiVector3D>::iterator it = tlist.begin(); it != tlist.end(); it++)
for(std::vector<aiVector3D>::iterator it = tlist.begin(); it != tlist.end(); ++it)
{
((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices.push_back(*it * radius);
}

View File

@ -93,7 +93,7 @@ void X3DImporter::ParseNode_Networking_Inline()
// at this place new group mode created and made current, so we can name it.
if(!def.empty()) NodeElement_Cur->ID = def;
if(load && (url.size() > 0))
if(load && !url.empty())
{
std::string full_path = mpIOHandler->CurrentDirectory() + url.front();

View File

@ -81,7 +81,7 @@ aiMatrix4x4 X3DImporter::PostprocessHelper_Matrix_GlobalToCurrent() const
}
// multiplicate all matrices in reverse order
for(std::list<aiMatrix4x4>::reverse_iterator rit = matr.rbegin(); rit != matr.rend(); rit++) out_matr = out_matr * (*rit);
for(std::list<aiMatrix4x4>::reverse_iterator rit = matr.rbegin(); rit != matr.rend(); ++rit) out_matr = out_matr * (*rit);
return out_matr;
}
@ -89,7 +89,7 @@ aiMatrix4x4 X3DImporter::PostprocessHelper_Matrix_GlobalToCurrent() const
void X3DImporter::PostprocessHelper_CollectMetadata(const CX3DImporter_NodeElement& pNodeElement, std::list<CX3DImporter_NodeElement*>& pList) const
{
// walk through childs and find for metadata.
for(std::list<CX3DImporter_NodeElement*>::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); el_it++)
for(std::list<CX3DImporter_NodeElement*>::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); ++el_it)
{
if(((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaBoolean) || ((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaDouble) ||
((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaFloat) || ((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaInteger) ||
@ -194,7 +194,7 @@ void X3DImporter::Postprocess_BuildMaterial(const CX3DImporter_NodeElement& pNod
aiMaterial& taimat = **pMaterial;// creating alias for convenience.
// at this point pNodeElement point to <Appearance> node. Walk through childs and add all stored data.
for(std::list<CX3DImporter_NodeElement*>::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); el_it++)
for(std::list<CX3DImporter_NodeElement*>::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); ++el_it)
{
if((*el_it)->Type == CX3DImporter_NodeElement::ENET_Material)
{
@ -255,7 +255,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
std::vector<aiVector3D> tarr;
tarr.reserve(tnemesh.Vertices.size());
for(std::list<aiVector3D>::iterator it = tnemesh.Vertices.begin(); it != tnemesh.Vertices.end(); it++) tarr.push_back(*it);
for(std::list<aiVector3D>::iterator it = tnemesh.Vertices.begin(); it != tnemesh.Vertices.end(); ++it) tarr.push_back(*it);
*pMesh = StandardShapes::MakeMesh(tarr, static_cast<unsigned int>(tnemesh.NumIndices));// create mesh from vertices using Assimp help.
return;// mesh is build, nothing to do anymore.
@ -273,7 +273,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
std::vector<aiVector3D> tarr;
tarr.reserve(tnemesh.Vertices.size());
for(std::list<aiVector3D>::iterator it = tnemesh.Vertices.begin(); it != tnemesh.Vertices.end(); it++) tarr.push_back(*it);
for(std::list<aiVector3D>::iterator it = tnemesh.Vertices.begin(); it != tnemesh.Vertices.end(); ++it) tarr.push_back(*it);
*pMesh = StandardShapes::MakeMesh(tarr, static_cast<unsigned int>(tnemesh.NumIndices));// create mesh from vertices using Assimp help.
@ -289,7 +289,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
// at first create mesh from existing vertices.
*pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIdx, tnemesh.Vertices);
// copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
@ -301,7 +301,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
MeshGeometry_AddTexCoord(**pMesh, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
else
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.
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_ElevationGrid)
@ -313,7 +313,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience
// at first search for <Coordinate> node and create mesh.
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
{
@ -322,7 +322,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
}
// copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
@ -338,7 +338,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
else
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.
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedFaceSet)
@ -348,7 +348,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience
// at first search for <Coordinate> node and create mesh.
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
{
@ -357,7 +357,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
}
// copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{
ai_assert(*pMesh);
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
@ -369,7 +369,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
{} // skip because already read when mesh created.
else
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.
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedLineSet)
@ -381,7 +381,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience
// at first search for <Coordinate> node and create mesh.
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
{
@ -390,7 +390,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
}
// copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{
ai_assert(*pMesh);
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
@ -408,7 +408,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
else
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedTriangleSet or IndexedTriangleFanSet, or \
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.
}// if((pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedTriangleFanSet) || (pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedTriangleStripSet))
@ -430,7 +430,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
// at first search for <Coordinate> node and create mesh.
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
{
@ -438,7 +438,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
vec_copy.reserve(((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.size());
for(std::list<aiVector3D>::const_iterator it = ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.begin();
it != ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.end(); it++)
it != ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.end(); ++it)
{
vec_copy.push_back(*it);
}
@ -448,7 +448,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
}
// copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{
ai_assert(*pMesh);
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
@ -459,7 +459,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
{} // skip because already read when mesh created.
else
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.
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_PointSet)
@ -469,7 +469,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
// at first search for <Coordinate> node and create mesh.
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
{
@ -478,7 +478,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
}
// copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{
ai_assert(*pMesh);
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
@ -489,7 +489,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
{} // skip because already read when mesh created.
else
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.
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_LineSet)
@ -499,7 +499,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
// at first search for <Coordinate> node and create mesh.
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
{
@ -508,7 +508,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
}
// copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{
if ( nullptr == *pMesh ) {
break;
@ -526,7 +526,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
else
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.
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleFanSet)
@ -536,7 +536,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
// at first search for <Coordinate> node and create mesh.
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
{
@ -544,7 +544,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
vec_copy.reserve(((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.size());
for(std::list<aiVector3D>::const_iterator it = ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.begin();
it != ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.end(); it++)
it != ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.end(); ++it)
{
vec_copy.push_back(*it);
}
@ -554,7 +554,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
}
// copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{
ai_assert(*pMesh);
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
@ -570,7 +570,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
else
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.
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleSet)
@ -580,7 +580,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
// at first search for <Coordinate> node and create mesh.
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
{
@ -589,7 +589,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
}
// copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{
ai_assert(*pMesh);
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
@ -605,7 +605,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
else
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.
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleStripSet)
@ -639,16 +639,16 @@ void X3DImporter::Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeEle
}
else
{
for(size_t i = 0; i < (size_t)tne_group.Choice; i++) chit_begin++;// forward iterator to chosen node.
for(size_t i = 0; i < (size_t)tne_group.Choice; i++) ++chit_begin;// forward iterator to chosen node.
chit_end = chit_begin;
chit_end++;// point end iterator to next element after chosen node.
++chit_end;// point end iterator to next element after chosen node.
}
}// if(tne_group.UseChoice)
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_Group)
// Reserve memory for fast access and check children.
for(std::list<CX3DImporter_NodeElement*>::const_iterator it = chit_begin; it != chit_end; it++)
for(std::list<CX3DImporter_NodeElement*>::const_iterator it = chit_begin; it != chit_end; ++it)
{// in this loop we do not read metadata because it's already read at begin.
if((*it)->Type == CX3DImporter_NodeElement::ENET_Group)
{
@ -677,7 +677,7 @@ void X3DImporter::Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeEle
}// for(std::list<CX3DImporter_NodeElement*>::const_iterator it = chit_begin; it != chit_end; it++)
// copy data about children and meshes to aiNode.
if(SceneNode_Child.size() > 0)
if(!SceneNode_Child.empty())
{
std::list<aiNode*>::const_iterator it = SceneNode_Child.begin();
@ -686,7 +686,7 @@ void X3DImporter::Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeEle
for(size_t i = 0; i < pSceneNode.mNumChildren; i++) pSceneNode.mChildren[i] = *it++;
}
if(SceneNode_Mesh.size() > 0)
if(!SceneNode_Mesh.empty())
{
std::list<unsigned int>::const_iterator it = SceneNode_Mesh.begin();
@ -706,7 +706,7 @@ void X3DImporter::Postprocess_BuildShape(const CX3DImporter_NodeElement_Shape& p
CX3DImporter_NodeElement::EType mesh_type = CX3DImporter_NodeElement::ENET_Invalid;
unsigned int mat_ind = 0;
for(std::list<CX3DImporter_NodeElement*>::const_iterator it = pShapeNodeElement.Child.begin(); it != pShapeNodeElement.Child.end(); it++)
for(std::list<CX3DImporter_NodeElement*>::const_iterator it = pShapeNodeElement.Child.begin(); it != pShapeNodeElement.Child.end(); ++it)
{
if(PostprocessHelper_ElementIsMesh((*it)->Type))
{
@ -779,7 +779,7 @@ void X3DImporter::Postprocess_CollectMetadata(const CX3DImporter_NodeElement& pN
// copy collected metadata to output node.
pSceneNode.mMetaData = aiMetadata::Alloc( static_cast<unsigned int>(meta_list.size()) );
meta_idx = 0;
for(std::list<CX3DImporter_NodeElement*>::const_iterator it = meta_list.begin(); it != meta_list.end(); it++, meta_idx++)
for(std::list<CX3DImporter_NodeElement*>::const_iterator it = meta_list.begin(); it != meta_list.end(); ++it, ++meta_idx)
{
CX3DImporter_NodeElement_Meta* cur_meta = (CX3DImporter_NodeElement_Meta*)*it;

View File

@ -295,7 +295,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleFanSet()
ne_alias.CoordIndex.clear();
int counter = 0;
int32_t idx[3];
for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++)
for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); ++idx_it)
{
idx[2] = *idx_it;
if (idx[2] < 0)
@ -413,7 +413,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleSet()
ne_alias.CoordIndex.clear();
int counter = 0;
int32_t idx[3];
for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++)
for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); ++idx_it)
{
idx[counter++] = *idx_it;
if (counter > 2)
@ -519,7 +519,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleStripSet()
ne_alias.CoordIndex.clear();
int counter = 0;
int32_t idx[3];
for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++)
for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); ++idx_it)
{
idx[2] = *idx_it;
if (idx[2] < 0)
@ -617,7 +617,7 @@ void X3DImporter::ParseNode_Rendering_LineSet()
size_t coord_num = 0;
ne_alias.CoordIndex.clear();
for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++)
for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); ++vc_it)
{
if(*vc_it < 2) throw DeadlyImportError("LineSet. vertexCount shall be greater than or equal to two.");
@ -765,7 +765,7 @@ void X3DImporter::ParseNode_Rendering_TriangleFanSet()
// assign indices for first triangle
coord_num_first = 0;
coord_num_prev = 1;
for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++)
for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); ++vc_it)
{
if(*vc_it < 3) throw DeadlyImportError("TriangleFanSet. fanCount shall be greater than or equal to three.");
@ -956,7 +956,7 @@ void X3DImporter::ParseNode_Rendering_TriangleStripSet()
ne_alias.CoordIndex.clear();
coord_num_sb = 0;
for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++)
for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); ++vc_it)
{
if(*vc_it < 3) throw DeadlyImportError("TriangleStripSet. stripCount shall be greater than or equal to three.");

View File

@ -89,7 +89,7 @@ void X3DImporter::ParseNode_Texturing_ImageTexture()
((CX3DImporter_NodeElement_ImageTexture*)ne)->RepeatS = repeatS;
((CX3DImporter_NodeElement_ImageTexture*)ne)->RepeatT = repeatT;
// Attribute "url" can contain list of strings. But we need only one - first.
if(url.size() > 0)
if(!url.empty())
((CX3DImporter_NodeElement_ImageTexture*)ne)->URL = url.front();
else
((CX3DImporter_NodeElement_ImageTexture*)ne)->URL = "";

View File

@ -92,38 +92,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# endif
#endif
#include "glTF/glTFCommon.h"
namespace glTF
{
#ifdef ASSIMP_API
using Assimp::IOStream;
using Assimp::IOSystem;
using std::shared_ptr;
#else
using std::shared_ptr;
typedef std::runtime_error DeadlyImportError;
typedef std::runtime_error DeadlyExportError;
enum aiOrigin { aiOrigin_SET = 0, aiOrigin_CUR = 1, aiOrigin_END = 2 };
class IOSystem;
class IOStream
{
FILE* f;
public:
IOStream(FILE* file) : f(file) {}
~IOStream() { fclose(f); f = 0; }
size_t Read(void* b, size_t sz, size_t n) { return fread(b, sz, n, f); }
size_t Write(const void* b, size_t sz, size_t n) { return fwrite(b, sz, n, f); }
int Seek(size_t off, aiOrigin orig) { return fseek(f, off, int(orig)); }
size_t Tell() const { return ftell(f); }
size_t FileSize() {
long p = Tell(), len = (Seek(0, aiOrigin_END), Tell());
return size_t((Seek(p, aiOrigin_SET), len));
}
};
#endif
using glTFCommon::shared_ptr;
using glTFCommon::IOSystem;
using glTFCommon::IOStream;
using rapidjson::Value;
using rapidjson::Document;
@ -136,37 +111,9 @@ namespace glTF
struct Light;
struct Skin;
// Vec/matrix types, as raw float arrays
typedef float (vec3)[3];
typedef float (vec4)[4];
typedef float (mat4)[16];
namespace Util
{
void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);
size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
inline size_t DecodeBase64(const char* in, uint8_t*& out)
{
return DecodeBase64(in, strlen(in), out);
}
struct DataURI
{
const char* mediaType;
const char* charset;
bool base64;
const char* data;
size_t dataLength;
};
//! Check if a uri is a data URI
inline bool ParseDataURI(const char* uri, size_t uriLen, DataURI& out);
}
using glTFCommon::vec3;
using glTFCommon::vec4;
using glTFCommon::mat4;
//! Magic number for GLB files
#define AI_GLB_MAGIC_NUMBER "glTF"

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2019, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -52,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
using namespace Assimp;
using namespace glTFCommon;
namespace glTF {
@ -301,7 +301,7 @@ inline void Buffer::Read(Value& obj, Asset& r)
const char* uri = it->GetString();
Util::DataURI dataURI;
glTFCommon::Util::DataURI dataURI;
if (ParseDataURI(uri, it->GetStringLength(), dataURI)) {
if (dataURI.base64) {
uint8_t* data = 0;
@ -654,12 +654,12 @@ inline void Image::Read(Value& obj, Asset& r)
if (Value* uri = FindString(obj, "uri")) {
const char* uristr = uri->GetString();
Util::DataURI dataURI;
glTFCommon::Util::DataURI dataURI;
if (ParseDataURI(uristr, uri->GetStringLength(), dataURI)) {
mimeType = dataURI.mediaType;
if (dataURI.base64) {
uint8_t *ptr = nullptr;
mDataLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, ptr);
mDataLength = glTFCommon::Util::DecodeBase64(dataURI.data, dataURI.dataLength, ptr);
mData.reset(ptr);
}
}
@ -1180,8 +1180,12 @@ inline void Light::SetDefaults()
falloffExponent = 0.f;
}
inline void Node::Read(Value& obj, Asset& r)
{
inline
void Node::Read(Value& obj, Asset& r) {
if (name.empty()) {
name = id;
}
if (Value* children = FindArray(obj, "children")) {
this->children.reserve(children->Size());
for (unsigned int i = 0; i < children->Size(); ++i) {
@ -1474,190 +1478,4 @@ inline std::string Asset::FindUniqueID(const std::string& str, const char* suffi
return id;
}
namespace Util {
inline
bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out) {
if ( NULL == const_uri ) {
return false;
}
if (const_uri[0] != 0x10) { // we already parsed this uri?
if (strncmp(const_uri, "data:", 5) != 0) // not a data uri?
return false;
}
// set defaults
out.mediaType = "text/plain";
out.charset = "US-ASCII";
out.base64 = false;
char* uri = const_cast<char*>(const_uri);
if (uri[0] != 0x10) {
uri[0] = 0x10;
uri[1] = uri[2] = uri[3] = uri[4] = 0;
size_t i = 5, j;
if (uri[i] != ';' && uri[i] != ',') { // has media type?
uri[1] = char(i);
for (; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
// nothing to do!
}
}
while (uri[i] == ';' && i < uriLen) {
uri[i++] = '\0';
for (j = i; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
// nothing to do!
}
if ( strncmp( uri + j, "charset=", 8 ) == 0 ) {
uri[2] = char(j + 8);
} else if ( strncmp( uri + j, "base64", 6 ) == 0 ) {
uri[3] = char(j);
}
}
if (i < uriLen) {
uri[i++] = '\0';
uri[4] = char(i);
} else {
uri[1] = uri[2] = uri[3] = 0;
uri[4] = 5;
}
}
if ( uri[ 1 ] != 0 ) {
out.mediaType = uri + uri[ 1 ];
}
if ( uri[ 2 ] != 0 ) {
out.charset = uri + uri[ 2 ];
}
if ( uri[ 3 ] != 0 ) {
out.base64 = true;
}
out.data = uri + uri[4];
out.dataLength = (uri + uriLen) - out.data;
return true;
}
template<bool B>
struct DATA
{
static const uint8_t tableDecodeBase64[128];
};
template<bool B>
const uint8_t DATA<B>::tableDecodeBase64[128] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 64, 0, 0,
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0
};
inline char EncodeCharBase64(uint8_t b)
{
return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[size_t(b)];
}
inline uint8_t DecodeCharBase64(char c)
{
return DATA<true>::tableDecodeBase64[size_t(c)]; // TODO faster with lookup table or ifs?
/*if (c >= 'A' && c <= 'Z') return c - 'A';
if (c >= 'a' && c <= 'z') return c - 'a' + 26;
if (c >= '0' && c <= '9') return c - '0' + 52;
if (c == '+') return 62;
if (c == '/') return 63;
return 64; // '-' */
}
inline size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out)
{
ai_assert(inLength % 4 == 0);
if (inLength < 4) {
out = 0;
return 0;
}
int nEquals = int(in[inLength - 1] == '=') +
int(in[inLength - 2] == '=');
size_t outLength = (inLength * 3) / 4 - nEquals;
out = new uint8_t[outLength];
memset(out, 0, outLength);
size_t i, j = 0;
for (i = 0; i + 4 < inLength; i += 4) {
uint8_t b0 = DecodeCharBase64(in[i]);
uint8_t b1 = DecodeCharBase64(in[i + 1]);
uint8_t b2 = DecodeCharBase64(in[i + 2]);
uint8_t b3 = DecodeCharBase64(in[i + 3]);
out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
out[j++] = (uint8_t)((b2 << 6) | b3);
}
{
uint8_t b0 = DecodeCharBase64(in[i]);
uint8_t b1 = DecodeCharBase64(in[i + 1]);
uint8_t b2 = DecodeCharBase64(in[i + 2]);
uint8_t b3 = DecodeCharBase64(in[i + 3]);
out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
if (b2 < 64) out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
if (b3 < 64) out[j++] = (uint8_t)((b2 << 6) | b3);
}
return outLength;
}
inline void EncodeBase64(
const uint8_t* in, size_t inLength,
std::string& out)
{
size_t outLength = ((inLength + 2) / 3) * 4;
size_t j = out.size();
out.resize(j + outLength);
for (size_t i = 0; i < inLength; i += 3) {
uint8_t b = (in[i] & 0xFC) >> 2;
out[j++] = EncodeCharBase64(b);
b = (in[i] & 0x03) << 4;
if (i + 1 < inLength) {
b |= (in[i + 1] & 0xF0) >> 4;
out[j++] = EncodeCharBase64(b);
b = (in[i + 1] & 0x0F) << 2;
if (i + 2 < inLength) {
b |= (in[i + 2] & 0xC0) >> 6;
out[j++] = EncodeCharBase64(b);
b = in[i + 2] & 0x3F;
out[j++] = EncodeCharBase64(b);
}
else {
out[j++] = EncodeCharBase64(b);
out[j++] = '=';
}
}
else {
out[j++] = EncodeCharBase64(b);
out[j++] = '=';
out[j++] = '=';
}
}
}
}
} // ns glTF

View File

@ -55,7 +55,8 @@ namespace glTF {
namespace {
template<size_t N>
inline Value& MakeValue(Value& val, float(&r)[N], MemoryPoolAllocator<>& al) {
inline
Value& MakeValue(Value& val, float(&r)[N], MemoryPoolAllocator<>& al) {
val.SetArray();
val.Reserve(N, al);
for (decltype(N) i = 0; i < N; ++i) {
@ -64,7 +65,8 @@ namespace glTF {
return val;
}
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.Reserve(static_cast<rapidjson::SizeType>(r.size()), al);
for (unsigned int i = 0; i < r.size(); ++i) {
@ -213,7 +215,7 @@ namespace glTF {
else if (img.HasData()) {
uri = "data:" + (img.mimeType.empty() ? "application/octet-stream" : img.mimeType);
uri += ";base64,";
Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri);
glTFCommon::Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri);
}
else {
uri = img.uri;

View File

@ -0,0 +1,193 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2019, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
#include "glTF/glTFCommon.h"
namespace glTFCommon {
using namespace glTFCommon::Util;
namespace Util {
size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out) {
ai_assert(inLength % 4 == 0);
if (inLength < 4) {
out = 0;
return 0;
}
int nEquals = int(in[inLength - 1] == '=') +
int(in[inLength - 2] == '=');
size_t outLength = (inLength * 3) / 4 - nEquals;
out = new uint8_t[outLength];
memset(out, 0, outLength);
size_t i, j = 0;
for (i = 0; i + 4 < inLength; i += 4) {
uint8_t b0 = DecodeCharBase64(in[i]);
uint8_t b1 = DecodeCharBase64(in[i + 1]);
uint8_t b2 = DecodeCharBase64(in[i + 2]);
uint8_t b3 = DecodeCharBase64(in[i + 3]);
out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
out[j++] = (uint8_t)((b2 << 6) | b3);
}
{
uint8_t b0 = DecodeCharBase64(in[i]);
uint8_t b1 = DecodeCharBase64(in[i + 1]);
uint8_t b2 = DecodeCharBase64(in[i + 2]);
uint8_t b3 = DecodeCharBase64(in[i + 3]);
out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
if (b2 < 64) out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
if (b3 < 64) out[j++] = (uint8_t)((b2 << 6) | b3);
}
return outLength;
}
void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out) {
size_t outLength = ((inLength + 2) / 3) * 4;
size_t j = out.size();
out.resize(j + outLength);
for (size_t i = 0; i < inLength; i += 3) {
uint8_t b = (in[i] & 0xFC) >> 2;
out[j++] = EncodeCharBase64(b);
b = (in[i] & 0x03) << 4;
if (i + 1 < inLength) {
b |= (in[i + 1] & 0xF0) >> 4;
out[j++] = EncodeCharBase64(b);
b = (in[i + 1] & 0x0F) << 2;
if (i + 2 < inLength) {
b |= (in[i + 2] & 0xC0) >> 6;
out[j++] = EncodeCharBase64(b);
b = in[i + 2] & 0x3F;
out[j++] = EncodeCharBase64(b);
}
else {
out[j++] = EncodeCharBase64(b);
out[j++] = '=';
}
}
else {
out[j++] = EncodeCharBase64(b);
out[j++] = '=';
out[j++] = '=';
}
}
}
bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out) {
if (nullptr == const_uri) {
return false;
}
if (const_uri[0] != 0x10) { // we already parsed this uri?
if (strncmp(const_uri, "data:", 5) != 0) // not a data uri?
return false;
}
// set defaults
out.mediaType = "text/plain";
out.charset = "US-ASCII";
out.base64 = false;
char* uri = const_cast<char*>(const_uri);
if (uri[0] != 0x10) {
uri[0] = 0x10;
uri[1] = uri[2] = uri[3] = uri[4] = 0;
size_t i = 5, j;
if (uri[i] != ';' && uri[i] != ',') { // has media type?
uri[1] = char(i);
for (; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
// nothing to do!
}
}
while (uri[i] == ';' && i < uriLen) {
uri[i++] = '\0';
for (j = i; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
// nothing to do!
}
if (strncmp(uri + j, "charset=", 8) == 0) {
uri[2] = char(j + 8);
}
else if (strncmp(uri + j, "base64", 6) == 0) {
uri[3] = char(j);
}
}
if (i < uriLen) {
uri[i++] = '\0';
uri[4] = char(i);
}
else {
uri[1] = uri[2] = uri[3] = 0;
uri[4] = 5;
}
}
if (uri[1] != 0) {
out.mediaType = uri + uri[1];
}
if (uri[2] != 0) {
out.charset = uri + uri[2];
}
if (uri[3] != 0) {
out.base64 = true;
}
out.data = uri + uri[4];
out.dataLength = (uri + uriLen) - out.data;
return true;
}
}
}

View File

@ -0,0 +1,248 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2019, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
#ifndef AI_GLFTCOMMON_H_INC
#define AI_GLFTCOMMON_H_INC
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
#include <assimp/Exceptional.h>
#include <map>
#include <string>
#include <list>
#include <vector>
#include <algorithm>
#include <stdexcept>
#define RAPIDJSON_HAS_STDSTRING 1
#include <rapidjson/rapidjson.h>
#include <rapidjson/document.h>
#include <rapidjson/error/en.h>
#ifdef ASSIMP_API
# include <memory>
# include <assimp/DefaultIOSystem.h>
# include <assimp/ByteSwapper.h>
#else
# include <memory>
# define AI_SWAP4(p)
# define ai_assert
#endif
#if _MSC_VER > 1500 || (defined __GNUC___)
# define ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
# else
# define gltf_unordered_map map
#endif
#ifdef ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
# include <unordered_map>
# if _MSC_VER > 1600
# define gltf_unordered_map unordered_map
# else
# define gltf_unordered_map tr1::unordered_map
# endif
#endif
namespace glTFCommon {
#ifdef ASSIMP_API
using Assimp::IOStream;
using Assimp::IOSystem;
using std::shared_ptr;
#else
using std::shared_ptr;
typedef std::runtime_error DeadlyImportError;
typedef std::runtime_error DeadlyExportError;
enum aiOrigin {
aiOrigin_SET = 0,
aiOrigin_CUR = 1,
aiOrigin_END = 2
};
class IOSystem;
class IOStream {
public:
IOStream(FILE* file) : f(file) {}
~IOStream() { fclose(f); f = 0; }
size_t Read(void* b, size_t sz, size_t n) { return fread(b, sz, n, f); }
size_t Write(const void* b, size_t sz, size_t n) { return fwrite(b, sz, n, f); }
int Seek(size_t off, aiOrigin orig) { return fseek(f, off, int(orig)); }
size_t Tell() const { return ftell(f); }
size_t FileSize() {
long p = Tell(), len = (Seek(0, aiOrigin_END), Tell());
return size_t((Seek(p, aiOrigin_SET), len));
}
private:
FILE* f;
};
#endif
// Vec/matrix types, as raw float arrays
typedef float(vec3)[3];
typedef float(vec4)[4];
typedef float(mat4)[16];
inline
void CopyValue(const glTFCommon::vec3& v, aiColor4D& out) {
out.r = v[0];
out.g = v[1];
out.b = v[2];
out.a = 1.0;
}
inline
void CopyValue(const glTFCommon::vec4& v, aiColor4D& out) {
out.r = v[0];
out.g = v[1];
out.b = v[2];
out.a = v[3];
}
inline
void CopyValue(const glTFCommon::vec4& v, aiColor3D& out) {
out.r = v[0];
out.g = v[1];
out.b = v[2];
}
inline
void CopyValue(const glTFCommon::vec3& v, aiColor3D& out) {
out.r = v[0];
out.g = v[1];
out.b = v[2];
}
inline
void CopyValue(const glTFCommon::vec3& v, aiVector3D& out) {
out.x = v[0];
out.y = v[1];
out.z = v[2];
}
inline
void CopyValue(const glTFCommon::vec4& v, aiQuaternion& out) {
out.x = v[0];
out.y = v[1];
out.z = v[2];
out.w = v[3];
}
inline
void CopyValue(const glTFCommon::mat4& v, aiMatrix4x4& o) {
o.a1 = v[0]; o.b1 = v[1]; o.c1 = v[2]; o.d1 = v[3];
o.a2 = v[4]; o.b2 = v[5]; o.c2 = v[6]; o.d2 = v[7];
o.a3 = v[8]; o.b3 = v[9]; o.c3 = v[10]; o.d3 = v[11];
o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
}
namespace Util {
void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);
size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
inline
size_t DecodeBase64(const char* in, uint8_t*& out) {
return DecodeBase64(in, strlen(in), out);
}
struct DataURI {
const char* mediaType;
const char* charset;
bool base64;
const char* data;
size_t dataLength;
};
//! Check if a uri is a data URI
bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out);
template<bool B>
struct DATA {
static const uint8_t tableDecodeBase64[128];
};
template<bool B>
const uint8_t DATA<B>::tableDecodeBase64[128] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 64, 0, 0,
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0
};
inline
char EncodeCharBase64(uint8_t b) {
return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[size_t(b)];
}
inline
uint8_t DecodeCharBase64(char c) {
return DATA<true>::tableDecodeBase64[size_t(c)]; // TODO faster with lookup table or ifs?
/*if (c >= 'A' && c <= 'Z') return c - 'A';
if (c >= 'a' && c <= 'z') return c - 'a' + 26;
if (c >= '0' && c <= '9') return c - '0' + 52;
if (c == '+') return 62;
if (c == '/') return 63;
return 64; // '-' */
}
size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);
}
}
#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
#endif // AI_GLFTCOMMON_H_INC

View File

@ -242,7 +242,10 @@ inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& bu
namespace {
void GetMatScalar(const aiMaterial* mat, float& val, const char* propName, int type, int idx) {
ai_assert(mat->Get(propName, type, idx, val) == AI_SUCCESS);
ai_assert( nullptr != mat );
if ( nullptr != mat ) {
mat->Get(propName, type, idx, val);
}
}
}

View File

@ -82,7 +82,7 @@ glTFImporter::glTFImporter()
: BaseImporter()
, meshOffsets()
, embeddedTexIdxs()
, mScene( NULL ) {
, mScene( nullptr ) {
// empty
}
@ -90,17 +90,16 @@ glTFImporter::~glTFImporter() {
// empty
}
const aiImporterDesc* glTFImporter::GetInfo() const
{
const aiImporterDesc* glTFImporter::GetInfo() const {
return &desc;
}
bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool /* checkSig */) const
{
bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool /* checkSig */) const {
const std::string &extension = GetExtension(pFile);
if (extension != "gltf" && extension != "glb")
if (extension != "gltf" && extension != "glb") {
return false;
}
if (pIOHandler) {
glTF::Asset asset(pIOHandler);
@ -116,44 +115,9 @@ bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool
return false;
}
//static void CopyValue(const glTF::vec3& v, aiColor3D& out)
//{
// out.r = v[0]; out.g = v[1]; out.b = v[2];
//}
static void CopyValue(const glTF::vec4& v, aiColor4D& out)
{
out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = v[3];
}
static void CopyValue(const glTF::vec4& v, aiColor3D& out)
{
out.r = v[0]; out.g = v[1]; out.b = v[2];
}
static void CopyValue(const glTF::vec3& v, aiVector3D& out)
{
out.x = v[0]; out.y = v[1]; out.z = v[2];
}
static void CopyValue(const glTF::vec4& v, aiQuaternion& out)
{
out.x = v[0]; out.y = v[1]; out.z = v[2]; out.w = v[3];
}
static void CopyValue(const glTF::mat4& v, aiMatrix4x4& o)
{
o.a1 = v[ 0]; o.b1 = v[ 1]; o.c1 = v[ 2]; o.d1 = v[ 3];
o.a2 = v[ 4]; o.b2 = v[ 5]; o.c2 = v[ 6]; o.d2 = v[ 7];
o.a3 = v[ 8]; o.b3 = v[ 9]; o.c3 = v[10]; o.d3 = v[11];
o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
}
inline void SetMaterialColorProperty(std::vector<int>& embeddedTexIdxs, Asset& /*r*/, glTF::TexProperty prop, aiMaterial* mat,
aiTextureType texType, const char* pKey, unsigned int type, unsigned int idx)
{
inline
void SetMaterialColorProperty(std::vector<int>& embeddedTexIdxs, Asset& /*r*/, glTF::TexProperty prop, aiMaterial* mat,
aiTextureType texType, const char* pKey, unsigned int type, unsigned int idx) {
if (prop.texture) {
if (prop.texture->source) {
aiString uri(prop.texture->source->uri);
@ -167,16 +131,14 @@ inline void SetMaterialColorProperty(std::vector<int>& embeddedTexIdxs, Asset& /
mat->AddProperty(&uri, _AI_MATKEY_TEXTURE_BASE, texType, 0);
}
}
else {
} else {
aiColor4D col;
CopyValue(prop.color, col);
mat->AddProperty(&col, 1, pKey, type, idx);
}
}
void glTFImporter::ImportMaterials(glTF::Asset& r)
{
void glTFImporter::ImportMaterials(glTF::Asset& r) {
mScene->mNumMaterials = unsigned(r.materials.Size());
mScene->mMaterials = new aiMaterial*[mScene->mNumMaterials];
@ -304,7 +266,7 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
aim->mName = mesh.id;
if (mesh.primitives.size() > 1) {
size_t& len = aim->mName.length;
ai_uint32& len = aim->mName.length;
aim->mName.data[len] = '-';
len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, unsigned(MAXLEN - len - 1), p);
}
@ -499,27 +461,31 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
CopyVector(meshes, mScene->mMeshes, mScene->mNumMeshes);
}
void glTFImporter::ImportCameras(glTF::Asset& r)
{
if (!r.cameras.Size()) return;
void glTFImporter::ImportCameras(glTF::Asset& r) {
if (!r.cameras.Size()) {
return;
}
mScene->mNumCameras = r.cameras.Size();
mScene->mCameras = new aiCamera*[r.cameras.Size()];
for (size_t i = 0; i < r.cameras.Size(); ++i) {
Camera& cam = r.cameras[i];
aiCamera* aicam = mScene->mCameras[i] = new aiCamera();
if (cam.type == Camera::Perspective) {
aicam->mAspect = cam.perspective.aspectRatio;
aicam->mHorizontalFOV = cam.perspective.yfov * aicam->mAspect;
aicam->mHorizontalFOV = cam.perspective.yfov * ((aicam->mAspect == 0.f) ? 1.f : aicam->mAspect);
aicam->mClipPlaneFar = cam.perspective.zfar;
aicam->mClipPlaneNear = cam.perspective.znear;
} else {
aicam->mClipPlaneFar = cam.ortographic.zfar;
aicam->mClipPlaneNear = cam.ortographic.znear;
aicam->mHorizontalFOV = 0.0;
aicam->mAspect = 1.0f;
if (0.f != cam.ortographic.ymag) {
aicam->mAspect = cam.ortographic.xmag / cam.ortographic.ymag;
}
else {
// assimp does not support orthographic cameras
}
}
}

View File

@ -95,38 +95,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/StringUtils.h>
#include "glTF/glTFCommon.h"
namespace glTF2
{
#ifdef ASSIMP_API
using Assimp::IOStream;
using Assimp::IOSystem;
using std::shared_ptr;
#else
using std::shared_ptr;
typedef std::runtime_error DeadlyImportError;
typedef std::runtime_error DeadlyExportError;
enum aiOrigin { aiOrigin_SET = 0, aiOrigin_CUR = 1, aiOrigin_END = 2 };
class IOSystem;
class IOStream
{
FILE* f;
public:
IOStream(FILE* file) : f(file) {}
~IOStream() { fclose(f); f = 0; }
size_t Read(void* b, size_t sz, size_t n) { return fread(b, sz, n, f); }
size_t Write(const void* b, size_t sz, size_t n) { return fwrite(b, sz, n, f); }
int Seek(size_t off, aiOrigin orig) { return fseek(f, off, int(orig)); }
size_t Tell() const { return ftell(f); }
size_t FileSize() {
long p = Tell(), len = (Seek(0, aiOrigin_END), Tell());
return size_t((Seek(p, aiOrigin_SET), len));
}
};
#endif
using glTFCommon::shared_ptr;
using glTFCommon::IOSystem;
using glTFCommon::IOStream;
using rapidjson::Value;
using rapidjson::Document;
@ -138,35 +113,9 @@ namespace glTF2
struct Texture;
struct Skin;
// Vec/matrix types, as raw float arrays
typedef float (vec3)[3];
typedef float (vec4)[4];
typedef float (mat4)[16];
namespace Util
{
void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);
size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
inline size_t DecodeBase64(const char* in, uint8_t*& out)
{
return DecodeBase64(in, strlen(in), out);
}
struct DataURI
{
const char* mediaType;
const char* charset;
bool base64;
const char* data;
size_t dataLength;
};
//! Check if a uri is a data URI
inline bool ParseDataURI(const char* uri, size_t uriLen, DataURI& out);
}
using glTFCommon::vec3;
using glTFCommon::vec4;
using glTFCommon::mat4;
//! Magic number for GLB files
#define AI_GLB_MAGIC_NUMBER "glTF"
@ -552,7 +501,7 @@ namespace glTF2
/// but in real life you'll get:
/// "accessor_0" : { byteOffset: 0, byteLength: 4}, "accessor_1" : { byteOffset: 2, byteLength: 4}
/// Yes, accessor of next mesh has offset and length which mean: current mesh data is decoded, all other data is encoded.
/// And when before you start to read data of current mesh (with encoded data ofcourse) you must decode region of "bufferView", after read finished
/// And when before you start to read data of current mesh (with encoded data of course) you must decode region of "bufferView", after read finished
/// delete encoding mark. And after that you can repeat process: decode data of mesh, read, delete decoded data.
///
/// Remark. Encoding all data at once is good in world with computers which do not has RAM limitation. So, you must use step by step encoding in

View File

@ -282,9 +282,7 @@ Ref<T> LazyDict<T>::Retrieve(unsigned int i)
template<class T>
Ref<T> LazyDict<T>::Get(unsigned int i)
{
return Ref<T>(mObjs, i);
}
template<class T>
@ -361,11 +359,11 @@ inline void Buffer::Read(Value& obj, Asset& r)
const char* uri = it->GetString();
Util::DataURI dataURI;
glTFCommon::Util::DataURI dataURI;
if (ParseDataURI(uri, it->GetStringLength(), dataURI)) {
if (dataURI.base64) {
uint8_t* data = 0;
this->byteLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, data);
this->byteLength = glTFCommon::Util::DecodeBase64(dataURI.data, dataURI.dataLength, data);
this->mData.reset(data, std::default_delete<uint8_t[]>());
if (statedLength > 0 && this->byteLength != statedLength) {
@ -717,12 +715,12 @@ inline void Image::Read(Value& obj, Asset& r)
if (Value* uri = FindString(obj, "uri")) {
const char* uristr = uri->GetString();
Util::DataURI dataURI;
glTFCommon::Util::DataURI dataURI;
if (ParseDataURI(uristr, uri->GetStringLength(), dataURI)) {
mimeType = dataURI.mediaType;
if (dataURI.base64) {
uint8_t *ptr = nullptr;
mDataLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, ptr);
mDataLength = glTFCommon::Util::DecodeBase64(dataURI.data, dataURI.dataLength, ptr);
mData.reset(ptr);
}
}
@ -1100,8 +1098,11 @@ inline void Light::Read(Value& obj, Asset& /*r*/)
}
}
inline void Node::Read(Value& obj, Asset& r)
{
inline
void Node::Read(Value& obj, Asset& r) {
if (name.empty()) {
name = id;
}
if (Value* children = FindArray(obj, "children")) {
this->children.reserve(children->Size());
@ -1515,190 +1516,4 @@ inline std::string Asset::FindUniqueID(const std::string& str, const char* suffi
return id;
}
namespace Util {
inline
bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out) {
if ( NULL == const_uri ) {
return false;
}
if (const_uri[0] != 0x10) { // we already parsed this uri?
if (strncmp(const_uri, "data:", 5) != 0) // not a data uri?
return false;
}
// set defaults
out.mediaType = "text/plain";
out.charset = "US-ASCII";
out.base64 = false;
char* uri = const_cast<char*>(const_uri);
if (uri[0] != 0x10) {
uri[0] = 0x10;
uri[1] = uri[2] = uri[3] = uri[4] = 0;
size_t i = 5, j;
if (uri[i] != ';' && uri[i] != ',') { // has media type?
uri[1] = char(i);
for (; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
// nothing to do!
}
}
while (uri[i] == ';' && i < uriLen) {
uri[i++] = '\0';
for (j = i; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
// nothing to do!
}
if ( strncmp( uri + j, "charset=", 8 ) == 0 ) {
uri[2] = char(j + 8);
} else if ( strncmp( uri + j, "base64", 6 ) == 0 ) {
uri[3] = char(j);
}
}
if (i < uriLen) {
uri[i++] = '\0';
uri[4] = char(i);
} else {
uri[1] = uri[2] = uri[3] = 0;
uri[4] = 5;
}
}
if ( uri[ 1 ] != 0 ) {
out.mediaType = uri + uri[ 1 ];
}
if ( uri[ 2 ] != 0 ) {
out.charset = uri + uri[ 2 ];
}
if ( uri[ 3 ] != 0 ) {
out.base64 = true;
}
out.data = uri + uri[4];
out.dataLength = (uri + uriLen) - out.data;
return true;
}
template<bool B>
struct DATA
{
static const uint8_t tableDecodeBase64[128];
};
template<bool B>
const uint8_t DATA<B>::tableDecodeBase64[128] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 64, 0, 0,
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0
};
inline char EncodeCharBase64(uint8_t b)
{
return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[size_t(b)];
}
inline uint8_t DecodeCharBase64(char c)
{
return DATA<true>::tableDecodeBase64[size_t(c)]; // TODO faster with lookup table or ifs?
/*if (c >= 'A' && c <= 'Z') return c - 'A';
if (c >= 'a' && c <= 'z') return c - 'a' + 26;
if (c >= '0' && c <= '9') return c - '0' + 52;
if (c == '+') return 62;
if (c == '/') return 63;
return 64; // '-' */
}
inline size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out)
{
ai_assert(inLength % 4 == 0);
if (inLength < 4) {
out = 0;
return 0;
}
int nEquals = int(in[inLength - 1] == '=') +
int(in[inLength - 2] == '=');
size_t outLength = (inLength * 3) / 4 - nEquals;
out = new uint8_t[outLength];
memset(out, 0, outLength);
size_t i, j = 0;
for (i = 0; i + 4 < inLength; i += 4) {
uint8_t b0 = DecodeCharBase64(in[i]);
uint8_t b1 = DecodeCharBase64(in[i + 1]);
uint8_t b2 = DecodeCharBase64(in[i + 2]);
uint8_t b3 = DecodeCharBase64(in[i + 3]);
out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
out[j++] = (uint8_t)((b2 << 6) | b3);
}
{
uint8_t b0 = DecodeCharBase64(in[i]);
uint8_t b1 = DecodeCharBase64(in[i + 1]);
uint8_t b2 = DecodeCharBase64(in[i + 2]);
uint8_t b3 = DecodeCharBase64(in[i + 3]);
out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
if (b2 < 64) out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
if (b3 < 64) out[j++] = (uint8_t)((b2 << 6) | b3);
}
return outLength;
}
inline void EncodeBase64(
const uint8_t* in, size_t inLength,
std::string& out)
{
size_t outLength = ((inLength + 2) / 3) * 4;
size_t j = out.size();
out.resize(j + outLength);
for (size_t i = 0; i < inLength; i += 3) {
uint8_t b = (in[i] & 0xFC) >> 2;
out[j++] = EncodeCharBase64(b);
b = (in[i] & 0x03) << 4;
if (i + 1 < inLength) {
b |= (in[i + 1] & 0xF0) >> 4;
out[j++] = EncodeCharBase64(b);
b = (in[i + 1] & 0x0F) << 2;
if (i + 2 < inLength) {
b |= (in[i + 2] & 0xC0) >> 6;
out[j++] = EncodeCharBase64(b);
b = in[i + 2] & 0x3F;
out[j++] = EncodeCharBase64(b);
}
else {
out[j++] = EncodeCharBase64(b);
out[j++] = '=';
}
}
else {
out[j++] = EncodeCharBase64(b);
out[j++] = '=';
out[j++] = '=';
}
}
}
}
} // ns glTF

View File

@ -218,7 +218,7 @@ namespace glTF2 {
if (img.HasData()) {
uri = "data:" + (img.mimeType.empty() ? "application/octet-stream" : img.mimeType);
uri += ";base64,";
Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri);
glTFCommon::Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri);
}
else {
uri = img.uri;

View File

@ -64,6 +64,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp;
using namespace glTF2;
using namespace glTFCommon;
namespace {
// generate bi-tangents from normals and tangents according to spec
@ -140,22 +141,23 @@ static aiTextureMapMode ConvertWrappingMode(SamplerWrap gltfWrapMode)
}
}
static void CopyValue(const glTF2::vec3& v, aiColor3D& out)
/*static void CopyValue(const glTF2::vec3& v, aiColor3D& out)
{
out.r = v[0]; out.g = v[1]; out.b = v[2];
}
static void CopyValue(const glTF2::vec4& v, aiColor4D& out)
{
out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = v[3];
}
}*/
/*static void CopyValue(const glTF2::vec4& v, aiColor3D& out)
{
out.r = v[0]; out.g = v[1]; out.b = v[2];
}*/
static void CopyValue(const glTF2::vec3& v, aiColor4D& out)
/*static void CopyValue(const glTF2::vec3& v, aiColor4D& out)
{
out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = 1.0;
}
@ -168,15 +170,15 @@ static void CopyValue(const glTF2::vec3& v, aiVector3D& out)
static void CopyValue(const glTF2::vec4& v, aiQuaternion& out)
{
out.x = v[0]; out.y = v[1]; out.z = v[2]; out.w = v[3];
}
}*/
static void CopyValue(const glTF2::mat4& v, aiMatrix4x4& o)
/*static void CopyValue(const glTF2::mat4& v, aiMatrix4x4& o)
{
o.a1 = v[ 0]; o.b1 = v[ 1]; o.c1 = v[ 2]; o.d1 = v[ 3];
o.a2 = v[ 4]; o.b2 = v[ 5]; o.c2 = v[ 6]; o.d2 = v[ 7];
o.a3 = v[ 8]; o.b3 = v[ 9]; o.c3 = v[10]; o.d3 = v[11];
o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
}
}*/
inline void SetMaterialColorProperty(Asset& /*r*/, vec4& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx)
{
@ -188,7 +190,7 @@ inline void SetMaterialColorProperty(Asset& /*r*/, vec4& prop, aiMaterial* mat,
inline void SetMaterialColorProperty(Asset& /*r*/, vec3& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx)
{
aiColor4D col;
CopyValue(prop, col);
glTFCommon::CopyValue(prop, col);
mat->AddProperty(&col, 1, pKey, type, idx);
}
@ -383,7 +385,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
aim->mName = mesh.name.empty() ? mesh.id : mesh.name;
if (mesh.primitives.size() > 1) {
size_t& len = aim->mName.length;
ai_uint32& len = aim->mName.length;
aim->mName.data[len] = '-';
len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, unsigned(MAXLEN - len - 1), p);
}
@ -442,7 +444,6 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
"\" does not match the vertex count");
continue;
}
aim->mColors[c] = new aiColor4D[attr.color[c]->count];
attr.color[c]->ExtractData(aim->mColors[c]);
}
for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
@ -700,12 +701,17 @@ void glTF2Importer::ImportCameras(glTF2::Asset& r)
if (cam.type == Camera::Perspective) {
aicam->mAspect = cam.cameraProperties.perspective.aspectRatio;
aicam->mHorizontalFOV = cam.cameraProperties.perspective.yfov * aicam->mAspect;
aicam->mHorizontalFOV = cam.cameraProperties.perspective.yfov * ((aicam->mAspect == 0.f) ? 1.f : aicam->mAspect);
aicam->mClipPlaneFar = cam.cameraProperties.perspective.zfar;
aicam->mClipPlaneNear = cam.cameraProperties.perspective.znear;
} else {
aicam->mClipPlaneFar = cam.cameraProperties.ortographic.zfar;
aicam->mClipPlaneNear = cam.cameraProperties.ortographic.znear;
aicam->mHorizontalFOV = 0.0;
aicam->mAspect = 1.0f;
if (0.f != cam.cameraProperties.ortographic.ymag ) {
aicam->mAspect = cam.cameraProperties.ortographic.xmag / cam.cameraProperties.ortographic.ymag;
}
else {
// assimp does not support orthographic cameras
}
}
}
@ -901,6 +907,9 @@ aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector<unsigned int>&
std::vector<std::vector<aiVertexWeight>> weighting(mesh->mNumBones);
BuildVertexWeightMapping(node.meshes[0]->primitives[primitiveNo], weighting);
mat4* pbindMatrices = nullptr;
node.skin->inverseBindMatrices->ExtractData(pbindMatrices);
for (uint32_t i = 0; i < mesh->mNumBones; ++i) {
aiBone* bone = new aiBone();
@ -916,6 +925,8 @@ aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector<unsigned int>&
}
GetNodeTransform(bone->mOffsetMatrix, *joint);
CopyValue(pbindMatrices[i], bone->mOffsetMatrix);
std::vector<aiVertexWeight>& weights = weighting[i];
bone->mNumWeights = static_cast<uint32_t>(weights.size());
@ -931,6 +942,10 @@ aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector<unsigned int>&
}
mesh->mBones[i] = bone;
}
if (pbindMatrices) {
delete[] pbindMatrices;
}
}
}
@ -987,11 +1002,18 @@ void glTF2Importer::ImportNodes(glTF2::Asset& r)
}
struct AnimationSamplers {
AnimationSamplers() : translation(nullptr), rotation(nullptr), scale(nullptr) {}
AnimationSamplers()
: translation(nullptr)
, rotation(nullptr)
, scale(nullptr)
, weight(nullptr) {
// empty
}
Animation::Sampler* translation;
Animation::Sampler* rotation;
Animation::Sampler* scale;
Animation::Sampler* weight;
};
aiNodeAnim* CreateNodeAnim(glTF2::Asset& r, Node& node, AnimationSamplers& samplers)
@ -1016,7 +1038,7 @@ aiNodeAnim* CreateNodeAnim(glTF2::Asset& r, Node& node, AnimationSamplers& sampl
delete[] values;
} else if (node.translation.isPresent) {
anim->mNumPositionKeys = 1;
anim->mPositionKeys = new aiVectorKey();
anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys];
anim->mPositionKeys->mTime = 0.f;
anim->mPositionKeys->mValue.x = node.translation.value[0];
anim->mPositionKeys->mValue.y = node.translation.value[1];
@ -1041,7 +1063,7 @@ aiNodeAnim* CreateNodeAnim(glTF2::Asset& r, Node& node, AnimationSamplers& sampl
delete[] values;
} else if (node.rotation.isPresent) {
anim->mNumRotationKeys = 1;
anim->mRotationKeys = new aiQuatKey();
anim->mRotationKeys = new aiQuatKey[anim->mNumRotationKeys];
anim->mRotationKeys->mTime = 0.f;
anim->mRotationKeys->mValue.x = node.rotation.value[0];
anim->mRotationKeys->mValue.y = node.rotation.value[1];
@ -1064,7 +1086,7 @@ aiNodeAnim* CreateNodeAnim(glTF2::Asset& r, Node& node, AnimationSamplers& sampl
delete[] values;
} else if (node.scale.isPresent) {
anim->mNumScalingKeys = 1;
anim->mScalingKeys = new aiVectorKey();
anim->mScalingKeys = new aiVectorKey[anim->mNumScalingKeys];
anim->mScalingKeys->mTime = 0.f;
anim->mScalingKeys->mValue.x = node.scale.value[0];
anim->mScalingKeys->mValue.y = node.scale.value[1];
@ -1074,6 +1096,43 @@ aiNodeAnim* CreateNodeAnim(glTF2::Asset& r, Node& node, AnimationSamplers& sampl
return anim;
}
aiMeshMorphAnim* CreateMeshMorphAnim(glTF2::Asset& r, Node& node, AnimationSamplers& samplers)
{
aiMeshMorphAnim* anim = new aiMeshMorphAnim();
anim->mName = GetNodeName(node);
static const float kMillisecondsFromSeconds = 1000.f;
if (nullptr != samplers.weight) {
float* times = nullptr;
samplers.weight->input->ExtractData(times);
float* values = nullptr;
samplers.weight->output->ExtractData(values);
anim->mNumKeys = static_cast<uint32_t>(samplers.weight->input->count);
const unsigned int numMorphs = samplers.weight->output->count / anim->mNumKeys;
anim->mKeys = new aiMeshMorphKey[anim->mNumKeys];
unsigned int k = 0u;
for (unsigned int i = 0u; i < anim->mNumKeys; ++i) {
anim->mKeys[i].mTime = times[i] * kMillisecondsFromSeconds;
anim->mKeys[i].mNumValuesAndWeights = numMorphs;
anim->mKeys[i].mValues = new unsigned int[numMorphs];
anim->mKeys[i].mWeights = new double[numMorphs];
for (unsigned int j = 0u; j < numMorphs; ++j, ++k) {
anim->mKeys[i].mValues[j] = j;
anim->mKeys[i].mWeights[j] = ( 0.f > values[k] ) ? 0.f : values[k];
}
}
delete[] times;
delete[] values;
}
return anim;
}
std::unordered_map<unsigned int, AnimationSamplers> GatherSamplers(Animation& anim)
{
std::unordered_map<unsigned int, AnimationSamplers> samplers;
@ -1092,6 +1151,8 @@ std::unordered_map<unsigned int, AnimationSamplers> GatherSamplers(Animation& an
sampler.rotation = &anim.samplers[channel.sampler];
} else if (channel.target.path == AnimationPath_SCALE) {
sampler.scale = &anim.samplers[channel.sampler];
} else if (channel.target.path == AnimationPath_WEIGHTS) {
sampler.weight = &anim.samplers[channel.sampler];
}
}
@ -1118,18 +1179,45 @@ void glTF2Importer::ImportAnimations(glTF2::Asset& r)
std::unordered_map<unsigned int, AnimationSamplers> samplers = GatherSamplers(anim);
ai_anim->mNumChannels = static_cast<uint32_t>(samplers.size());
uint32_t numChannels = 0u;
uint32_t numMorphMeshChannels = 0u;
for (auto& iter : samplers) {
if ((nullptr != iter.second.rotation) || (nullptr != iter.second.scale) || (nullptr != iter.second.translation)) {
++numChannels;
}
if (nullptr != iter.second.weight) {
++numMorphMeshChannels;
}
}
ai_anim->mNumChannels = numChannels;
if (ai_anim->mNumChannels > 0) {
ai_anim->mChannels = new aiNodeAnim*[ai_anim->mNumChannels];
int j = 0;
for (auto& iter : samplers) {
if ((nullptr != iter.second.rotation) || (nullptr != iter.second.scale) || (nullptr != iter.second.translation)) {
ai_anim->mChannels[j] = CreateNodeAnim(r, r.nodes[iter.first], iter.second);
++j;
}
}
}
ai_anim->mNumMorphMeshChannels = numMorphMeshChannels;
if (ai_anim->mNumMorphMeshChannels > 0) {
ai_anim->mMorphMeshChannels = new aiMeshMorphAnim*[ai_anim->mNumMorphMeshChannels];
int j = 0;
for (auto& iter : samplers) {
if (nullptr != iter.second.weight) {
ai_anim->mMorphMeshChannels[j] = CreateMeshMorphAnim(r, r.nodes[iter.first], iter.second);
++j;
}
}
}
// Use the latest keyframe for the duration of the animation
double maxDuration = 0;
unsigned int maxNumberOfKeys = 0;
for (unsigned int j = 0; j < ai_anim->mNumChannels; ++j) {
auto chan = ai_anim->mChannels[j];
if (chan->mNumPositionKeys) {
@ -1137,21 +1225,38 @@ void glTF2Importer::ImportAnimations(glTF2::Asset& r)
if (lastPosKey.mTime > maxDuration) {
maxDuration = lastPosKey.mTime;
}
maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumPositionKeys);
}
if (chan->mNumRotationKeys) {
auto lastRotKey = chan->mRotationKeys[chan->mNumRotationKeys - 1];
if (lastRotKey.mTime > maxDuration) {
maxDuration = lastRotKey.mTime;
}
maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumRotationKeys);
}
if (chan->mNumScalingKeys) {
auto lastScaleKey = chan->mScalingKeys[chan->mNumScalingKeys - 1];
if (lastScaleKey.mTime > maxDuration) {
maxDuration = lastScaleKey.mTime;
}
maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumScalingKeys);
}
}
for (unsigned int j = 0; j < ai_anim->mNumMorphMeshChannels; ++j) {
const auto* const chan = ai_anim->mMorphMeshChannels[j];
if (0u != chan->mNumKeys) {
const auto& lastKey = chan->mKeys[chan->mNumKeys - 1u];
if (lastKey.mTime > maxDuration) {
maxDuration = lastKey.mTime;
}
maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumKeys);
}
}
ai_anim->mDuration = maxDuration;
ai_anim->mTicksPerSecond = 1000.0;
mScene->mAnimations[i] = ai_anim;
}

View File

@ -141,7 +141,7 @@ void VerifyGenerator(const ParamGenerator<T>& generator,
<< ", expected_values[i] is " << PrintValue(expected_values[i])
<< ", *it is " << PrintValue(*it)
<< ", and 'it' is an iterator created with the copy constructor.\n";
it++;
++it;
}
EXPECT_TRUE(it == generator.end())
<< "At the presumed end of sequence when accessing via an iterator "
@ -161,7 +161,7 @@ void VerifyGenerator(const ParamGenerator<T>& generator,
<< ", expected_values[i] is " << PrintValue(expected_values[i])
<< ", *it is " << PrintValue(*it)
<< ", and 'it' is an iterator created with the copy constructor.\n";
it++;
++it;
}
EXPECT_TRUE(it == generator.end())
<< "At the presumed end of sequence when accessing via an iterator "
@ -196,7 +196,7 @@ TEST(IteratorTest, ParamIteratorConformsToForwardIteratorConcept) {
<< "element same as its source points to";
// Verifies that iterator assignment works as expected.
it++;
++it;
EXPECT_FALSE(*it == *it2);
it2 = it;
EXPECT_TRUE(*it == *it2) << "Assigned iterators must point to the "
@ -215,7 +215,7 @@ TEST(IteratorTest, ParamIteratorConformsToForwardIteratorConcept) {
// Verifies that prefix and postfix operator++() advance an iterator
// all the same.
it2 = it;
it++;
++it;
++it2;
EXPECT_TRUE(*it == *it2);
}

View File

@ -215,7 +215,7 @@ namespace io
two methods to read your data and give a pointer to an instance of
your implementation when calling createIrrXMLReader(),
createIrrXMLReaderUTF16() or createIrrXMLReaderUTF32() */
class IFileReadCallBack
class IRRXML_API IFileReadCallBack
{
public:

View File

@ -41,9 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file Definition of the base class for all importer worker classes. */
#pragma once
#ifndef INCLUDED_AI_BASEIMPORTER_H
#define INCLUDED_AI_BASEIMPORTER_H
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include "Exceptional.h"
#include <vector>
@ -82,6 +87,10 @@ class IOStream;
class ASSIMP_API BaseImporter {
friend class Importer;
private:
/* Pushes state into importer for the importer scale */
virtual void UpdateImporterScale( Importer* pImp );
public:
/** Constructor to be privately used by #Importer */
@ -134,7 +143,7 @@ public:
* a suitable response to the caller.
*/
aiScene* ReadFile(
const Importer* pImp,
Importer* pImp,
const std::string& pFile,
IOSystem* pIOHandler
);
@ -209,14 +218,6 @@ public:
return applicationUnits;
}
/* Returns scale used by application called by ScaleProcess */
double GetImporterScale() const
{
ai_assert(importerScale != 0);
ai_assert(fileScale != 0);
return importerScale * fileScale;
}
// -------------------------------------------------------------------
/** Called by #Importer::GetExtensionList for each loaded importer.
* Take the extension list contained in the structure returned by
@ -230,6 +231,7 @@ protected:
double fileScale = 1.0;
// -------------------------------------------------------------------
/** Imports the given file into the given scene structure. The
* function is expected to throw an ImportErrorException if there is

View File

@ -46,10 +46,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Used for file formats which embed their textures into the model file.
*/
#pragma once
#ifndef AI_BITMAP_H_INC
#define AI_BITMAP_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include "defs.h"
#include <stdint.h>
#include <cstddef>

View File

@ -42,9 +42,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Helper class tp perform various byte oder swappings
(e.g. little to big endian) */
#pragma once
#ifndef AI_BYTESWAPPER_H_INC
#define AI_BYTESWAPPER_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/ai_assert.h>
#include <assimp/types.h>
#include <stdint.h>

View File

@ -43,16 +43,26 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file CreateAnimMesh.h
* Create AnimMesh from Mesh
*/
#pragma once
#ifndef INCLUDED_AI_CREATE_ANIM_MESH_H
#define INCLUDED_AI_CREATE_ANIM_MESH_H
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/mesh.h>
namespace Assimp {
/** Create aiAnimMesh from aiMesh. */
/**
* Create aiAnimMesh from aiMesh.
* @param mesh The input mesh to create an animated mesh from.
* @return The new created animated mesh.
*/
ASSIMP_API aiAnimMesh *aiCreateAnimMesh(const aiMesh *mesh);
} // end of namespace Assimp
#endif // INCLUDED_AI_CREATE_ANIM_MESH_H

View File

@ -41,9 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file Default file I/O using fXXX()-family of functions */
#pragma once
#ifndef AI_DEFAULTIOSTREAM_H_INC
#define AI_DEFAULTIOSTREAM_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <stdio.h>
#include <assimp/IOStream.hpp>
#include <assimp/importerdesc.h>
@ -57,8 +62,7 @@ namespace Assimp {
//! @note An instance of this class can exist without a valid file handle
//! attached to it. All calls fail, but the instance can nevertheless be
//! used with no restrictions.
class ASSIMP_API DefaultIOStream : public IOStream
{
class ASSIMP_API DefaultIOStream : public IOStream {
friend class DefaultIOSystem;
#if __ANDROID__
# if __ANDROID_API__ > 9
@ -82,7 +86,6 @@ public:
size_t pSize,
size_t pCount);
// -------------------------------------------------------------------
/// Write to stream
size_t Write(const void* pvBuffer,
@ -107,16 +110,13 @@ public:
void Flush();
private:
// File data-structure, using clib
FILE* mFile;
// Filename
std::string mFilename;
// Cached file size
mutable size_t mCachedSize;
};
// ----------------------------------------------------------------------------------
inline
AI_FORCE_INLINE
DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT
: mFile(nullptr)
, mFilename("")
@ -125,7 +125,7 @@ DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT
}
// ----------------------------------------------------------------------------------
inline
AI_FORCE_INLINE
DefaultIOStream::DefaultIOStream (FILE* pFile, const std::string &strFilename)
: mFile(pFile)
, mFilename(strFilename)
@ -137,4 +137,3 @@ DefaultIOStream::DefaultIOStream (FILE* pFile, const std::string &strFilename)
} // ns assimp
#endif //!!AI_DEFAULTIOSTREAM_H_INC

View File

@ -41,9 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file Default implementation of IOSystem using the standard C file functions */
#pragma once
#ifndef AI_DEFAULTIOSYSTEM_H_INC
#define AI_DEFAULTIOSYSTEM_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/IOSystem.hpp>
namespace Assimp {

View File

@ -38,6 +38,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
#pragma once
#ifndef AI_DEFINES_H_INC
#define AI_DEFINES_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
// We need those constants, workaround for any platforms where nobody defined them yet
#if (!defined SIZE_MAX)
# define SIZE_MAX (~((size_t)0))
@ -47,3 +55,4 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# define UINT_MAX (~((unsigned int)0))
#endif
#endif // AI_DEINES_H_INC

View File

@ -38,11 +38,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
#ifndef INCLUDED_EXCEPTIONAL_H
#define INCLUDED_EXCEPTIONAL_H
#pragma once
#ifndef AI_INCLUDED_EXCEPTIONAL_H
#define AI_INCLUDED_EXCEPTIONAL_H
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <stdexcept>
#include <assimp/DefaultIOStream.h>
using std::runtime_error;
#ifdef _MSC_VER
@ -53,17 +59,14 @@ using std::runtime_error;
/** FOR IMPORTER PLUGINS ONLY: Simple exception class to be thrown if an
* unrecoverable error occurs while importing. Loading APIs return
* NULL instead of a valid aiScene then. */
class DeadlyImportError
: public runtime_error
{
class DeadlyImportError : public runtime_error {
public:
/** Constructor with arguments */
explicit DeadlyImportError( const std::string& errorText)
: runtime_error(errorText)
{
: runtime_error(errorText) {
// empty
}
private:
};
typedef DeadlyImportError DeadlyExportError;
@ -84,7 +87,7 @@ struct ExceptionSwallower {
template <typename T>
struct ExceptionSwallower<T*> {
T* operator ()() const {
return NULL;
return nullptr;
}
};
@ -122,4 +125,4 @@ struct ExceptionSwallower<void> {
}\
}
#endif // INCLUDED_EXCEPTIONAL_H
#endif // AI_INCLUDED_EXCEPTIONAL_H

View File

@ -48,6 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_EXPORT_HPP_INC
#define AI_EXPORT_HPP_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#ifndef ASSIMP_BUILD_NO_EXPORT
#include "cexport.h"

View File

@ -40,12 +40,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
#pragma once
#ifndef AI_GENERIC_PROPERTY_H_INCLUDED
#define AI_GENERIC_PROPERTY_H_INCLUDED
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/Importer.hpp>
#include <assimp/ai_assert.h>
#include "Hash.h"
#include <assimp/Hash.h>
#include <map>

View File

@ -39,10 +39,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
#pragma once
#ifndef AI_HASH_H_INCLUDED
#define AI_HASH_H_INCLUDED
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <stdint.h>
#include <string.h>

View File

@ -48,7 +48,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_IOSTREAM_H_INC
#define AI_IOSTREAM_H_INC
#include "types.h"
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/types.h>
#ifndef __cplusplus
# error This header requires C++ to be used. aiFileIO.h is the \
@ -125,13 +129,13 @@ public:
}; //! class IOStream
// ----------------------------------------------------------------------------------
inline
AI_FORCE_INLINE
IOStream::IOStream() AI_NO_EXCEPT {
// empty
}
// ----------------------------------------------------------------------------------
inline
AI_FORCE_INLINE
IOStream::~IOStream() {
// empty
}

View File

@ -1,5 +1,3 @@
#pragma once
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
@ -42,10 +40,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
#pragma once
#ifndef AI_IOSTREAMBUFFER_H_INC
#define AI_IOSTREAMBUFFER_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/types.h>
#include <assimp/IOStream.hpp>
#include "ParsingUtils.h"
#include <assimp/ParsingUtils.h>
#include <vector>
@ -124,7 +129,7 @@ private:
};
template<class T>
inline
AI_FORCE_INLINE
IOStreamBuffer<T>::IOStreamBuffer( size_t cache )
: m_stream( nullptr )
, m_filesize( 0 )
@ -138,13 +143,13 @@ IOStreamBuffer<T>::IOStreamBuffer( size_t cache )
}
template<class T>
inline
AI_FORCE_INLINE
IOStreamBuffer<T>::~IOStreamBuffer() {
// empty
}
template<class T>
inline
AI_FORCE_INLINE
bool IOStreamBuffer<T>::open( IOStream *stream ) {
// file still opened!
if ( nullptr != m_stream ) {
@ -174,7 +179,7 @@ bool IOStreamBuffer<T>::open( IOStream *stream ) {
}
template<class T>
inline
AI_FORCE_INLINE
bool IOStreamBuffer<T>::close() {
if ( nullptr == m_stream ) {
return false;
@ -192,19 +197,19 @@ bool IOStreamBuffer<T>::close() {
}
template<class T>
inline
AI_FORCE_INLINE
size_t IOStreamBuffer<T>::size() const {
return m_filesize;
}
template<class T>
inline
AI_FORCE_INLINE
size_t IOStreamBuffer<T>::cacheSize() const {
return m_cacheSize;
}
template<class T>
inline
AI_FORCE_INLINE
bool IOStreamBuffer<T>::readNextBlock() {
m_stream->Seek( m_filePos, aiOrigin_SET );
size_t readLen = m_stream->Read( &m_cache[ 0 ], sizeof( T ), m_cacheSize );
@ -222,25 +227,25 @@ bool IOStreamBuffer<T>::readNextBlock() {
}
template<class T>
inline
AI_FORCE_INLINE
size_t IOStreamBuffer<T>::getNumBlocks() const {
return m_numBlocks;
}
template<class T>
inline
AI_FORCE_INLINE
size_t IOStreamBuffer<T>::getCurrentBlockIndex() const {
return m_blockIdx;
}
template<class T>
inline
AI_FORCE_INLINE
size_t IOStreamBuffer<T>::getFilePos() const {
return m_filePos;
}
template<class T>
inline
AI_FORCE_INLINE
bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationToken ) {
buffer.resize( m_cacheSize );
if ( m_cachePos >= m_cacheSize || 0 == m_filePos ) {
@ -289,13 +294,13 @@ bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationT
return true;
}
static inline
static AI_FORCE_INLINE
bool isEndOfCache( size_t pos, size_t cacheSize ) {
return ( pos == cacheSize );
}
template<class T>
inline
AI_FORCE_INLINE
bool IOStreamBuffer<T>::getNextLine(std::vector<T> &buffer) {
buffer.resize(m_cacheSize);
if ( isEndOfCache( m_cachePos, m_cacheSize ) || 0 == m_filePos) {
@ -335,7 +340,7 @@ bool IOStreamBuffer<T>::getNextLine(std::vector<T> &buffer) {
}
template<class T>
inline
AI_FORCE_INLINE
bool IOStreamBuffer<T>::getNextBlock( std::vector<T> &buffer) {
// Return the last block-value if getNextLine was used before
if ( 0 != m_cachePos ) {
@ -353,3 +358,5 @@ bool IOStreamBuffer<T>::getNextBlock( std::vector<T> &buffer) {
}
} // !ns Assimp
#endif // AI_IOSTREAMBUFFER_H_INC

View File

@ -50,6 +50,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_IOSYSTEM_H_INC
#define AI_IOSYSTEM_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#ifndef __cplusplus
# error This header requires C++ to be used. aiFileIO.h is the \
corresponding C interface.

View File

@ -48,6 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_ASSIMP_HPP_INC
#define AI_ASSIMP_HPP_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#ifndef __cplusplus
# error This header requires C++ to be used. Use assimp.h for plain C.
#endif // __cplusplus

View File

@ -48,9 +48,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef INCLUDED_LINE_SPLITTER_H
#define INCLUDED_LINE_SPLITTER_H
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <stdexcept>
#include "StreamReader.h"
#include "ParsingUtils.h"
#include <assimp/StreamReader.h>
#include <assimp/ParsingUtils.h>
namespace Assimp {
@ -140,7 +144,7 @@ private:
bool mSwallow, mSkip_empty_lines, mTrim;
};
inline
AI_FORCE_INLINE
LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool trim )
: mIdx(0)
, mCur()
@ -153,12 +157,12 @@ LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool t
mIdx = 0;
}
inline
AI_FORCE_INLINE
LineSplitter::~LineSplitter() {
// empty
}
inline
AI_FORCE_INLINE
LineSplitter& LineSplitter::operator++() {
if (mSwallow) {
mSwallow = false;
@ -199,12 +203,12 @@ LineSplitter& LineSplitter::operator++() {
return *this;
}
inline
AI_FORCE_INLINE
LineSplitter &LineSplitter::operator++(int) {
return ++(*this);
}
inline
AI_FORCE_INLINE
const char *LineSplitter::operator[] (size_t idx) const {
const char* s = operator->()->c_str();
@ -222,7 +226,7 @@ const char *LineSplitter::operator[] (size_t idx) const {
}
template <size_t N>
inline
AI_FORCE_INLINE
void LineSplitter::get_tokens(const char* (&tokens)[N]) const {
const char* s = operator->()->c_str();
@ -238,44 +242,44 @@ void LineSplitter::get_tokens(const char* (&tokens)[N]) const {
}
}
inline
AI_FORCE_INLINE
const std::string* LineSplitter::operator -> () const {
return &mCur;
}
inline
AI_FORCE_INLINE
std::string LineSplitter::operator* () const {
return mCur;
}
inline
AI_FORCE_INLINE
LineSplitter::operator bool() const {
return mStream.GetRemainingSize() > 0;
}
inline
AI_FORCE_INLINE
LineSplitter::operator line_idx() const {
return mIdx;
}
inline
AI_FORCE_INLINE
LineSplitter::line_idx LineSplitter::get_index() const {
return mIdx;
}
inline
AI_FORCE_INLINE
StreamReaderLE &LineSplitter::get_stream() {
return mStream;
}
inline
AI_FORCE_INLINE
bool LineSplitter::match_start(const char* check) {
const size_t len = ::strlen(check);
return len <= mCur.length() && std::equal(check, check + len, mCur.begin());
}
inline
AI_FORCE_INLINE
void LineSplitter::swallow_next_increment() {
mSwallow = true;
}

View File

@ -43,9 +43,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file LogAux.h
* @brief Common logging usage patterns for importer implementations
*/
#pragma once
#ifndef INCLUDED_AI_LOGAUX_H
#define INCLUDED_AI_LOGAUX_H
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/TinyFormatter.h>
#include <assimp/Exceptional.h>
#include <assimp/DefaultLogger.hpp>

View File

@ -1,49 +0,0 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2019, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/* Helper macro to set a pointer to NULL in debug builds
*/
#if (defined ASSIMP_BUILD_DEBUG)
# define AI_DEBUG_INVALIDATE_PTR(x) x = NULL;
#else
# define AI_DEBUG_INVALIDATE_PTR(x)
#endif

View File

@ -39,22 +39,28 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#pragma once
#ifdef __GNUC__
# pragma GCC system_header
#endif
/** @file MathFunctions.h
* @brief Implementation of the math functions (gcd and lcm)
* @brief Implementation of math utility functions.
*
* Copied from BoostWorkaround/math
*/
*/
#include <limits>
namespace Assimp {
namespace Math {
// TODO: use binary GCD for unsigned integers ....
template < typename IntegerType >
IntegerType gcd( IntegerType a, IntegerType b )
{
inline
IntegerType gcd( IntegerType a, IntegerType b ) {
const IntegerType zero = (IntegerType)0;
while ( true )
{
while ( true ) {
if ( a == zero )
return b;
b %= a;
@ -66,12 +72,19 @@ IntegerType gcd( IntegerType a, IntegerType b )
}
template < typename IntegerType >
IntegerType lcm( IntegerType a, IntegerType b )
{
inline
IntegerType lcm( IntegerType a, IntegerType b ) {
const IntegerType t = gcd (a,b);
if (!t)return t;
if (!t)
return t;
return a / t * b;
}
template<class T>
inline
T getEpsilon() {
return std::numeric_limits<T>::epsilon();
}
}
}

View File

@ -42,12 +42,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file MemoryIOWrapper.h
* Handy IOStream/IOSystem implemetation to read directly from a memory buffer */
#pragma once
#ifndef AI_MEMORYIOSTREAM_H_INC
#define AI_MEMORYIOSTREAM_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/IOStream.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/ai_assert.h>
#include <stdint.h>
namespace Assimp {

View File

@ -44,11 +44,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file ParsingUtils.h
* @brief Defines helper functions for text parsing
*/
#pragma once
#ifndef AI_PARSING_UTILS_H_INC
#define AI_PARSING_UTILS_H_INC
#include "StringComparison.h"
#include "StringUtils.h"
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/StringComparison.h>
#include <assimp/StringUtils.h>
#include <assimp/defs.h>
namespace Assimp {

View File

@ -43,12 +43,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Profiler.h
* @brief Utility to measure the respective runtime of each import step
*/
#ifndef INCLUDED_PROFILER_H
#define INCLUDED_PROFILER_H
#pragma once
#ifndef AI_INCLUDED_PROFILER_H
#define AI_INCLUDED_PROFILER_H
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <chrono>
#include <assimp/DefaultLogger.hpp>
#include "TinyFormatter.h"
#include <assimp/TinyFormatter.h>
#include <map>
@ -67,7 +72,6 @@ public:
// empty
}
public:
/** Start a named timer */
void BeginRegion(const std::string& region) {
@ -95,5 +99,5 @@ private:
}
}
#endif
#endif // AI_INCLUDED_PROFILER_H

View File

@ -47,7 +47,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_PROGRESSHANDLER_H_INC
#define AI_PROGRESSHANDLER_H_INC
#include "types.h"
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/types.h>
namespace Assimp {

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2019, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -43,9 +42,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Declares a helper class, "CommentRemover", which can be
* used to remove comments (single and multi line) from a text file.
*/
#pragma once
#ifndef AI_REMOVE_COMMENTS_H_INC
#define AI_REMOVE_COMMENTS_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/defs.h>
@ -58,8 +61,7 @@ namespace Assimp {
* to those in C or C++ so this code has been moved to a separate
* module.
*/
class ASSIMP_API CommentRemover
{
class ASSIMP_API CommentRemover {
// class cannot be instanced
CommentRemover() {}

View File

@ -42,9 +42,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** Small helper classes to optimize finding vertices close to a given location
*/
#pragma once
#ifndef AI_D3DSSPATIALSORT_H_INC
#define AI_D3DSSPATIALSORT_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/types.h>
#include <vector>
#include <stdint.h>

View File

@ -43,17 +43,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Declares a helper class, "SceneCombiner" providing various
* utilities to merge scenes.
*/
#pragma once
#ifndef AI_SCENE_COMBINER_H_INC
#define AI_SCENE_COMBINER_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/ai_assert.h>
#include <assimp/types.h>
#include <assimp/Defines.h>
#include <stddef.h>
#include <set>
#include <list>
#include <stdint.h>
#include <vector>
struct aiScene;
@ -65,8 +70,10 @@ struct aiLight;
struct aiMetadata;
struct aiBone;
struct aiMesh;
struct aiAnimMesh;
struct aiAnimation;
struct aiNodeAnim;
struct aiMeshMorphAnim;
namespace Assimp {
@ -363,6 +370,7 @@ public:
static void Copy (aiMesh** dest, const aiMesh* src);
// similar to Copy():
static void Copy (aiAnimMesh** dest, const aiAnimMesh* src);
static void Copy (aiMaterial** dest, const aiMaterial* src);
static void Copy (aiTexture** dest, const aiTexture* src);
static void Copy (aiAnimation** dest, const aiAnimation* src);
@ -370,6 +378,7 @@ public:
static void Copy (aiBone** dest, const aiBone* src);
static void Copy (aiLight** dest, const aiLight* src);
static void Copy (aiNodeAnim** dest, const aiNodeAnim* src);
static void Copy (aiMeshMorphAnim** dest, const aiMeshMorphAnim* src);
static void Copy (aiMetadata** dest, const aiMetadata* src);
// recursive, of course

View File

@ -47,9 +47,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* for animation skeletons.
*/
#pragma once
#ifndef AI_SKELETONMESHBUILDER_H_INC
#define AI_SKELETONMESHBUILDER_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <vector>
#include <assimp/mesh.h>

View File

@ -43,10 +43,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Defines the helper data structures for importing 3DS files.
http://www.jalix.org/ressources/graphics/3DS/_unofficials/3ds-unofficial.txt */
#pragma once
#ifndef AI_SMOOTHINGGROUPS_H_INC
#define AI_SMOOTHINGGROUPS_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/vector3.h>
#include <stdint.h>
#include <vector>

View File

@ -41,13 +41,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Generation of normal vectors basing on smoothing groups */
#pragma once
#ifndef AI_SMOOTHINGGROUPS_INL_INCLUDED
#define AI_SMOOTHINGGROUPS_INL_INCLUDED
// internal headers
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/SGSpatialSort.h>
// CRT header
#include <algorithm>
using namespace Assimp;

View File

@ -41,9 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** Small helper classes to optimise finding vertizes close to a given location */
#pragma once
#ifndef AI_SPATIALSORT_H_INC
#define AI_SPATIALSORT_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <vector>
#include <assimp/types.h>

View File

@ -41,11 +41,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file Declares a helper class, "StandardShapes" which generates
* vertices for standard shapes, such as cylnders, cones, spheres ..
* vertices for standard shapes, such as cylinders, cones, spheres ..
*/
#pragma once
#ifndef AI_STANDARD_SHAPES_H_INC
#define AI_STANDARD_SHAPES_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/vector3.h>
#include <vector>

View File

@ -44,15 +44,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Defines the StreamReader class which reads data from
* a binary stream with a well-defined endianness.
*/
#pragma once
#ifndef AI_STREAMREADER_H_INCLUDED
#define AI_STREAMREADER_H_INCLUDED
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/IOStream.hpp>
#include <assimp/Defines.h>
#include <assimp/ByteSwapper.h>
#include <assimp/Exceptional.h>
#include "ByteSwapper.h"
#include "Exceptional.h"
#include <memory>
namespace Assimp {

Some files were not shown because too many files have changed in this diff Show More