Merge branch 'master' into fix_gltf2_export_componentType_error
commit
cc0b3e1249
|
@ -12,6 +12,8 @@ build
|
||||||
bin/
|
bin/
|
||||||
lib/
|
lib/
|
||||||
|
|
||||||
|
# QtCreator
|
||||||
|
CMakeLists.txt.user
|
||||||
|
|
||||||
# Generated
|
# Generated
|
||||||
assimp.pc
|
assimp.pc
|
||||||
|
@ -19,6 +21,7 @@ revision.h
|
||||||
contrib/zlib/zconf.h
|
contrib/zlib/zconf.h
|
||||||
contrib/zlib/zlib.pc
|
contrib/zlib/zlib.pc
|
||||||
include/assimp/config.h
|
include/assimp/config.h
|
||||||
|
unit.vcxproj.user
|
||||||
|
|
||||||
# CMake
|
# CMake
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
|
@ -85,3 +88,9 @@ lib64/assimp-vc120-mt.exp
|
||||||
xcuserdata
|
xcuserdata
|
||||||
|
|
||||||
cmake-build-debug
|
cmake-build-debug
|
||||||
|
install_manifest.txt
|
||||||
|
tools/assimp_qt_viewer/moc_glview.cpp
|
||||||
|
tools/assimp_qt_viewer/moc_glview.cpp_parameters
|
||||||
|
tools/assimp_qt_viewer/moc_mainwindow.cpp
|
||||||
|
tools/assimp_qt_viewer/moc_mainwindow.cpp_parameters
|
||||||
|
tools/assimp_qt_viewer/ui_mainwindow.h
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Build instructions
|
||||||
|
|
||||||
|
> cmake CMakeLists.txt
|
||||||
|
make -j4
|
||||||
|
|
||||||
|
##UWP
|
||||||
|
See https://stackoverflow.com/questions/40803170/cmake-uwp-using-cmake-to-build-universal-windows-app
|
|
@ -39,10 +39,12 @@ CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )
|
||||||
PROJECT( Assimp )
|
PROJECT( Assimp )
|
||||||
|
|
||||||
# All supported options ###############################################
|
# All supported options ###############################################
|
||||||
|
|
||||||
OPTION( BUILD_SHARED_LIBS
|
OPTION( BUILD_SHARED_LIBS
|
||||||
"Build package with shared libraries."
|
"Build package with shared libraries."
|
||||||
ON
|
ON
|
||||||
)
|
)
|
||||||
|
|
||||||
OPTION( BUILD_FRAMEWORK
|
OPTION( BUILD_FRAMEWORK
|
||||||
"Build package as Mac OS X Framework bundle."
|
"Build package as Mac OS X Framework bundle."
|
||||||
OFF
|
OFF
|
||||||
|
@ -103,6 +105,16 @@ OPTION ( BUILD_DOCS
|
||||||
"Build documentation using Doxygen."
|
"Build documentation using Doxygen."
|
||||||
OFF
|
OFF
|
||||||
)
|
)
|
||||||
|
OPTION( INJECT_DEBUG_POSTFIX
|
||||||
|
"Inject debug postfix in .a/.so lib names"
|
||||||
|
ON
|
||||||
|
)
|
||||||
|
|
||||||
|
IF (IOS)
|
||||||
|
IF (NOT CMAKE_BUILD_TYPE)
|
||||||
|
SET(CMAKE_BUILD_TYPE "Release")
|
||||||
|
ENDIF (NOT CMAKE_BUILD_TYPE)
|
||||||
|
ENDIF (IOS)
|
||||||
|
|
||||||
# Use subset of Windows.h
|
# Use subset of Windows.h
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
|
@ -152,7 +164,7 @@ EXECUTE_PROCESS(
|
||||||
|
|
||||||
# Get the latest abbreviated commit hash of the working branch
|
# Get the latest abbreviated commit hash of the working branch
|
||||||
EXECUTE_PROCESS(
|
EXECUTE_PROCESS(
|
||||||
COMMAND git log -1 --format=%h
|
COMMAND git log -1 --format=%h --no-show-signature
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
OUTPUT_VARIABLE GIT_COMMIT_HASH
|
OUTPUT_VARIABLE GIT_COMMIT_HASH
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
@ -198,13 +210,13 @@ ENDIF( UNIX )
|
||||||
# Grouped compiler settings
|
# Grouped compiler settings
|
||||||
IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
|
IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
|
||||||
# hide all not-exported symbols
|
# hide all not-exported symbols
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -fPIC -Wall -std=c++0x")
|
SET(CMAKE_CXX_FLAGS "-g -fvisibility=hidden -fPIC -fno-strict-aliasing -Wall -std=c++0x ${CMAKE_CXX_FLAGS}")
|
||||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
SET(CMAKE_C_FLAGS "-fPIC -fno-strict-aliasing ${CMAKE_C_FLAGS}")
|
||||||
SET(LIBSTDC++_LIBRARIES -lstdc++)
|
SET(LIBSTDC++_LIBRARIES -lstdc++)
|
||||||
ELSEIF(MSVC)
|
ELSEIF(MSVC)
|
||||||
# enable multi-core compilation with MSVC
|
# enable multi-core compilation with MSVC
|
||||||
ADD_COMPILE_OPTIONS(/MP)
|
ADD_COMPILE_OPTIONS(/MP)
|
||||||
IF("${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)")
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
ADD_COMPILE_OPTIONS( /bigobj )
|
ADD_COMPILE_OPTIONS( /bigobj )
|
||||||
ENDIF()
|
ENDIF()
|
||||||
# disable "elements of array '' will be default initialized" warning on MSVC2013
|
# disable "elements of array '' will be default initialized" warning on MSVC2013
|
||||||
|
@ -212,19 +224,26 @@ ELSEIF(MSVC)
|
||||||
ADD_COMPILE_OPTIONS(/wd4351)
|
ADD_COMPILE_OPTIONS(/wd4351)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
|
ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -fPIC -Wall -Wno-long-long -std=c++11" )
|
SET(CMAKE_CXX_FLAGS "-g -fvisibility=hidden -fPIC -fno-strict-aliasing -Wall -Wno-long-long -std=c++11 ${CMAKE_CXX_FLAGS}" )
|
||||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
SET(CMAKE_C_FLAGS "-fPIC -fno-strict-aliasing ${CMAKE_C_FLAGS}")
|
||||||
ELSEIF( CMAKE_COMPILER_IS_MINGW )
|
ELSEIF( CMAKE_COMPILER_IS_MINGW )
|
||||||
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -Wno-long-long -std=c++11" )
|
SET( CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -std=c++11 -Wa,-mbig-obj ${CMAKE_CXX_FLAGS}" )
|
||||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
SET(CMAKE_C_FLAGS "-fPIC -fno-strict-aliasing ${CMAKE_C_FLAGS} ")
|
||||||
ADD_DEFINITIONS( -U__STRICT_ANSI__ )
|
ADD_DEFINITIONS( -U__STRICT_ANSI__ )
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF ( IOS )
|
IF ( IOS )
|
||||||
|
|
||||||
|
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()
|
||||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3")
|
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3")
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3")
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
ENDIF( IOS )
|
||||||
|
|
||||||
IF (ASSIMP_COVERALLS)
|
IF (ASSIMP_COVERALLS)
|
||||||
MESSAGE(STATUS "Coveralls enabled")
|
MESSAGE(STATUS "Coveralls enabled")
|
||||||
INCLUDE(Coveralls)
|
INCLUDE(Coveralls)
|
||||||
|
@ -320,6 +339,8 @@ IF( NOT ZLIB_FOUND )
|
||||||
SET(ZLIB_FOUND 1)
|
SET(ZLIB_FOUND 1)
|
||||||
SET(ZLIB_LIBRARIES zlibstatic)
|
SET(ZLIB_LIBRARIES zlibstatic)
|
||||||
SET(ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/contrib/zlib ${CMAKE_CURRENT_BINARY_DIR}/contrib/zlib)
|
SET(ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/contrib/zlib ${CMAKE_CURRENT_BINARY_DIR}/contrib/zlib)
|
||||||
|
# need to ensure we don't link with system zlib or minizip as well.
|
||||||
|
SET(ASSIMP_BUILD_MINIZIP 1)
|
||||||
ELSE(NOT ZLIB_FOUND)
|
ELSE(NOT ZLIB_FOUND)
|
||||||
ADD_DEFINITIONS(-DASSIMP_BUILD_NO_OWN_ZLIB)
|
ADD_DEFINITIONS(-DASSIMP_BUILD_NO_OWN_ZLIB)
|
||||||
SET(ZLIB_LIBRARIES_LINKED -lz)
|
SET(ZLIB_LIBRARIES_LINKED -lz)
|
||||||
|
@ -327,7 +348,17 @@ ENDIF(NOT ZLIB_FOUND)
|
||||||
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
|
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
|
||||||
|
|
||||||
# Search for unzip
|
# Search for unzip
|
||||||
|
IF ( NOT IOS )
|
||||||
|
IF( NOT ASSIMP_BUILD_MINIZIP )
|
||||||
use_pkgconfig(UNZIP minizip)
|
use_pkgconfig(UNZIP minizip)
|
||||||
|
ENDIF( NOT ASSIMP_BUILD_MINIZIP )
|
||||||
|
ELSE ( NOT IOS )
|
||||||
|
IF(NOT BUILD_SHARED_LIBS)
|
||||||
|
IF( NOT ASSIMP_BUILD_MINIZIP )
|
||||||
|
use_pkgconfig(UNZIP minizip)
|
||||||
|
ENDIF( NOT ASSIMP_BUILD_MINIZIP )
|
||||||
|
ENDIF (NOT BUILD_SHARED_LIBS)
|
||||||
|
ENDIF ( NOT IOS )
|
||||||
|
|
||||||
IF ( ASSIMP_NO_EXPORT )
|
IF ( ASSIMP_NO_EXPORT )
|
||||||
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_EXPORT)
|
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_EXPORT)
|
||||||
|
@ -412,32 +443,9 @@ IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
||||||
ENDIF ( WIN32 AND DirectX_D3DX9_LIBRARY )
|
ENDIF ( WIN32 AND DirectX_D3DX9_LIBRARY )
|
||||||
|
|
||||||
ADD_SUBDIRECTORY( tools/assimp_cmd/ )
|
ADD_SUBDIRECTORY( tools/assimp_cmd/ )
|
||||||
|
IF (NOT IOS)
|
||||||
# Check dependencies for assimp_qt_viewer.
|
|
||||||
# Why here? Maybe user do not want Qt viewer and have no Qt.
|
|
||||||
# Why assimp_qt_viewer/CMakeLists.txt still contain similar check?
|
|
||||||
# Because viewer can be build independently of Assimp.
|
|
||||||
FIND_PACKAGE(Qt5Widgets QUIET)
|
|
||||||
FIND_PACKAGE(DevIL QUIET)
|
|
||||||
FIND_PACKAGE(OpenGL QUIET)
|
|
||||||
IF ( Qt5Widgets_FOUND AND IL_FOUND AND OPENGL_FOUND)
|
|
||||||
ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ )
|
ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ )
|
||||||
ELSE()
|
ENDIF (NOT IOS)
|
||||||
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "")
|
|
||||||
IF (NOT Qt5_FOUND)
|
|
||||||
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} Qt5")
|
|
||||||
ENDIF (NOT Qt5_FOUND)
|
|
||||||
|
|
||||||
IF (NOT IL_FOUND)
|
|
||||||
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} DevIL")
|
|
||||||
ENDIF (NOT IL_FOUND)
|
|
||||||
|
|
||||||
IF (NOT OPENGL_FOUND)
|
|
||||||
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} OpengGL")
|
|
||||||
ENDIF (NOT OPENGL_FOUND)
|
|
||||||
|
|
||||||
MESSAGE (WARNING "Build of assimp_qt_viewer is disabled. Unsatisfied dendencies: ${ASSIMP_QT_VIEWER_DEPENDENCIES}")
|
|
||||||
ENDIF ( Qt5Widgets_FOUND AND IL_FOUND AND OPENGL_FOUND)
|
|
||||||
ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
||||||
|
|
||||||
IF ( ASSIMP_BUILD_SAMPLES)
|
IF ( ASSIMP_BUILD_SAMPLES)
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
# How to contribute
|
# How to contribute
|
||||||
|
|
||||||
If you want to contribute you can follow these setps:
|
If you want to contribute, follow these steps:
|
||||||
- Fist create your own clone of assimp
|
|
||||||
- When you want to fix a bug or add a new feature create a branch on your own fork ( just follow https://help.github.com/articles/creating-a-pull-request-from-a-fork/ )
|
|
||||||
- Push it to the repo and open a pull request
|
|
||||||
- A pull request will start our CI-service, which checks if the build works for linux and windows.
|
|
||||||
It will check for memory leaks, compiler warnings and memory alignment issues. If any of these tests fails: fix it and the tests will be reastarted automatically
|
|
||||||
- At the end we will perform a code review and merge your branch to the master branch.
|
|
||||||
|
|
||||||
|
|
||||||
|
- First, create your own clone of assimp.
|
||||||
|
- When you want to fix a bug or add a new feature, create a branch on your own fork following [these instructions](https://help.github.com/articles/creating-a-pull-request-from-a-fork/).
|
||||||
|
- Push it to your fork of the repository and open a pull request.
|
||||||
|
- A pull request will start our continuous integration service, which checks if the build works for Linux and Windows.
|
||||||
|
It will check for memory leaks, compiler warnings and memory alignment issues. If any of these tests fail, fix it and the tests will be restarted automatically.
|
||||||
|
- At the end, we will perform a code review and merge your branch to the master branch.
|
||||||
|
|
3
INSTALL
3
INSTALL
|
@ -42,3 +42,6 @@ For Windows:
|
||||||
1. Open a command prompt
|
1. Open a command prompt
|
||||||
2. cmake CMakeLists.txt
|
2. cmake CMakeLists.txt
|
||||||
2. Open your default IDE and build it
|
2. Open your default IDE and build it
|
||||||
|
|
||||||
|
For iOS:
|
||||||
|
Just check the following project, which deploys a compiler toolchain for different iOS-versions: https://github.com/assimp/assimp/tree/master/port/iOS
|
||||||
|
|
|
@ -30,6 +30,8 @@ One-off donations via PayPal:
|
||||||
|
|
||||||
Please check our Wiki as well: https://github.com/assimp/assimp/wiki
|
Please check our Wiki as well: https://github.com/assimp/assimp/wiki
|
||||||
|
|
||||||
|
If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
|
||||||
|
|
||||||
#### Supported file formats ####
|
#### Supported file formats ####
|
||||||
|
|
||||||
__Importers__:
|
__Importers__:
|
||||||
|
|
|
@ -32,6 +32,9 @@ install:
|
||||||
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" set CMAKE_GENERATOR_NAME=Visual Studio 15 2017
|
- 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
|
- if "%platform%"=="x64" set CMAKE_GENERATOR_NAME=%CMAKE_GENERATOR_NAME% Win64
|
||||||
- cmake %CMAKE_DEFINES% -G "%CMAKE_GENERATOR_NAME%"
|
- cmake %CMAKE_DEFINES% -G "%CMAKE_GENERATOR_NAME%"
|
||||||
|
- 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
|
||||||
|
|
||||||
cache:
|
cache:
|
||||||
- code\assimp.dir\%CONFIGURATION%
|
- code\assimp.dir\%CONFIGURATION%
|
||||||
|
@ -50,6 +53,7 @@ build:
|
||||||
project: Assimp.sln
|
project: Assimp.sln
|
||||||
|
|
||||||
after_build:
|
after_build:
|
||||||
|
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" iscc packaging\windows-innosetup\script.iss
|
||||||
- 7z a assimp.7z bin\%CONFIGURATION%\* lib\%CONFIGURATION%\*
|
- 7z a assimp.7z bin\%CONFIGURATION%\* lib\%CONFIGURATION%\*
|
||||||
|
|
||||||
test_script:
|
test_script:
|
||||||
|
|
|
@ -204,8 +204,9 @@ void CopyTexture(aiMaterial& mat, D3DS::Texture& texture, aiTextureType type)
|
||||||
mat.AddProperty<ai_real>( &texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type,0));
|
mat.AddProperty<ai_real>( &texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type,0));
|
||||||
|
|
||||||
// Setup the texture mapping mode
|
// Setup the texture mapping mode
|
||||||
mat.AddProperty<int>((int*)&texture.mMapMode,1,AI_MATKEY_MAPPINGMODE_U(type,0));
|
int mapMode = static_cast<int>(texture.mMapMode);
|
||||||
mat.AddProperty<int>((int*)&texture.mMapMode,1,AI_MATKEY_MAPPINGMODE_V(type,0));
|
mat.AddProperty<int>(&mapMode,1,AI_MATKEY_MAPPINGMODE_U(type,0));
|
||||||
|
mat.AddProperty<int>(&mapMode,1,AI_MATKEY_MAPPINGMODE_V(type,0));
|
||||||
|
|
||||||
// Mirroring - double the scaling values
|
// Mirroring - double the scaling values
|
||||||
// FIXME: this is not really correct ...
|
// FIXME: this is not really correct ...
|
||||||
|
@ -313,7 +314,8 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material& oldMat,
|
||||||
case D3DS::Discreet3DS::Blinn :
|
case D3DS::Discreet3DS::Blinn :
|
||||||
eShading = aiShadingMode_Blinn; break;
|
eShading = aiShadingMode_Blinn; break;
|
||||||
}
|
}
|
||||||
mat.AddProperty<int>( (int*)&eShading,1,AI_MATKEY_SHADING_MODEL);
|
int eShading_ = static_cast<int>(eShading);
|
||||||
|
mat.AddProperty<int>(&eShading_, 1, AI_MATKEY_SHADING_MODEL);
|
||||||
|
|
||||||
// DIFFUSE texture
|
// DIFFUSE texture
|
||||||
if( oldMat.sTexDiffuse.mMapName.length() > 0)
|
if( oldMat.sTexDiffuse.mMapName.length() > 0)
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace D3DS {
|
||||||
*/
|
*/
|
||||||
class Discreet3DS {
|
class Discreet3DS {
|
||||||
private:
|
private:
|
||||||
Discreet3DS() {
|
Discreet3DS() AI_NO_EXCEPT {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,10 +328,9 @@ struct Face : public FaceWithSmoothingGroup
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Helper structure representing a texture */
|
/** Helper structure representing a texture */
|
||||||
struct Texture
|
struct Texture {
|
||||||
{
|
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
Texture()
|
Texture() AI_NO_EXCEPT
|
||||||
: mOffsetU (0.0)
|
: mOffsetU (0.0)
|
||||||
, mOffsetV (0.0)
|
, mOffsetV (0.0)
|
||||||
, mScaleU (1.0)
|
, mScaleU (1.0)
|
||||||
|
@ -339,8 +338,7 @@ struct Texture
|
||||||
, mRotation (0.0)
|
, mRotation (0.0)
|
||||||
, mMapMode (aiTextureMapMode_Wrap)
|
, mMapMode (aiTextureMapMode_Wrap)
|
||||||
, bPrivate()
|
, bPrivate()
|
||||||
, iUVSrc (0)
|
, iUVSrc (0) {
|
||||||
{
|
|
||||||
mTextureBlend = get_qnan();
|
mTextureBlend = get_qnan();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,7 +392,7 @@ struct Material
|
||||||
|
|
||||||
|
|
||||||
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
|
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
|
||||||
Material(Material &&other)
|
Material(Material &&other) AI_NO_EXCEPT
|
||||||
: mName(std::move(other.mName))
|
: mName(std::move(other.mName))
|
||||||
, mDiffuse(std::move(other.mDiffuse))
|
, mDiffuse(std::move(other.mDiffuse))
|
||||||
, mSpecularExponent(std::move(other.mSpecularExponent))
|
, mSpecularExponent(std::move(other.mSpecularExponent))
|
||||||
|
@ -418,7 +416,7 @@ struct Material
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Material &operator=(Material &&other) {
|
Material &operator=(Material &&other) AI_NO_EXCEPT {
|
||||||
if (this == &other) {
|
if (this == &other) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -447,7 +445,7 @@ struct Material
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
~Material() {}
|
virtual ~Material() {}
|
||||||
|
|
||||||
|
|
||||||
//! Name of the material
|
//! Name of the material
|
||||||
|
|
|
@ -71,7 +71,7 @@ static const aiImporterDesc desc = {
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
"3ds prj 3DS PRJ"
|
"3ds prj"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ Discreet3DSImporter::~Discreet3DSImporter() {
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool Discreet3DSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const {
|
bool Discreet3DSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const {
|
||||||
std::string extension = GetExtension(pFile);
|
std::string extension = GetExtension(pFile);
|
||||||
if(extension == "3ds" || extension == "3DS" || extension == "prj"|| extension == "PRJ" ) {
|
if(extension == "3ds" || extension == "prj") {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,8 +63,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
// Header files, stdlib.
|
// Header files, stdlib.
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp {
|
||||||
{
|
|
||||||
/// \class AMFImporter
|
/// \class AMFImporter
|
||||||
/// Class that holding scene graph which include: geometry, metadata, materials etc.
|
/// Class that holding scene graph which include: geometry, metadata, materials etc.
|
||||||
///
|
///
|
||||||
|
@ -99,34 +99,25 @@ namespace Assimp
|
||||||
/// new - <texmap> and children <utex1>, <utex2>, <utex3>, <vtex1>, <vtex2>, <vtex3>
|
/// new - <texmap> and children <utex1>, <utex2>, <utex3>, <vtex1>, <vtex2>, <vtex3>
|
||||||
/// old - <map> and children <u1>, <u2>, <u3>, <v1>, <v2>, <v3>
|
/// old - <map> and children <u1>, <u2>, <u3>, <v1>, <v2>, <v3>
|
||||||
///
|
///
|
||||||
class AMFImporter : public BaseImporter
|
class AMFImporter : public BaseImporter {
|
||||||
{
|
|
||||||
/***********************************************/
|
|
||||||
/******************** Types ********************/
|
|
||||||
/***********************************************/
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
struct SPP_Material;// forward declaration
|
struct SPP_Material;// forward declaration
|
||||||
|
|
||||||
/// \struct SPP_Composite
|
/// \struct SPP_Composite
|
||||||
/// Data type for postprocessing step. More suitable container for part of material's composition.
|
/// Data type for post-processing step. More suitable container for part of material's composition.
|
||||||
struct SPP_Composite
|
struct SPP_Composite {
|
||||||
{
|
|
||||||
SPP_Material* Material;///< Pointer to material - part of composition.
|
SPP_Material* Material;///< Pointer to material - part of composition.
|
||||||
std::string Formula;///< Formula for calculating ratio of \ref Material.
|
std::string Formula;///< Formula for calculating ratio of \ref Material.
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \struct SPP_Material
|
/// \struct SPP_Material
|
||||||
/// Data type for postprocessing step. More suitable container for material.
|
/// Data type for post-processing step. More suitable container for material.
|
||||||
struct SPP_Material
|
struct SPP_Material {
|
||||||
{
|
|
||||||
std::string ID;///< Material ID.
|
std::string ID;///< Material ID.
|
||||||
std::list<CAMFImporter_NodeElement_Metadata*> Metadata;///< Metadata of material.
|
std::list<CAMFImporter_NodeElement_Metadata*> Metadata;///< Metadata of material.
|
||||||
CAMFImporter_NodeElement_Color* Color;///< Color of material.
|
CAMFImporter_NodeElement_Color* Color;///< Color of material.
|
||||||
std::list<SPP_Composite> Composition;///< List of child materials if current material is composition of few another.
|
std::list<SPP_Composite> Composition;///< List of child materials if current material is composition of few another.
|
||||||
|
|
||||||
/// \fn aiColor4D GetColor(const float pX, const float pY, const float pZ) const
|
|
||||||
/// Return color calculated for specified coordinate.
|
/// Return color calculated for specified coordinate.
|
||||||
/// \param [in] pX - "x" coordinate.
|
/// \param [in] pX - "x" coordinate.
|
||||||
/// \param [in] pY - "y" coordinate.
|
/// \param [in] pY - "y" coordinate.
|
||||||
|
@ -135,10 +126,8 @@ private:
|
||||||
aiColor4D GetColor(const float pX, const float pY, const float pZ) const;
|
aiColor4D GetColor(const float pX, const float pY, const float pZ) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \struct SPP_Texture
|
|
||||||
/// Data type for post-processing step. More suitable container for texture.
|
/// Data type for post-processing step. More suitable container for texture.
|
||||||
struct SPP_Texture
|
struct SPP_Texture {
|
||||||
{
|
|
||||||
std::string ID;
|
std::string ID;
|
||||||
size_t Width, Height, Depth;
|
size_t Width, Height, Depth;
|
||||||
bool Tiled;
|
bool Tiled;
|
||||||
|
@ -146,53 +135,13 @@ private:
|
||||||
uint8_t *Data;
|
uint8_t *Data;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \struct SComplexFace
|
|
||||||
/// Data type for post-processing step. Contain face data.
|
/// Data type for post-processing step. Contain face data.
|
||||||
struct SComplexFace
|
struct SComplexFace {
|
||||||
{
|
|
||||||
aiFace Face;///< Face vertices.
|
aiFace Face;///< Face vertices.
|
||||||
const CAMFImporter_NodeElement_Color* Color;///< Face color. Equal to nullptr if color is not set for the face.
|
const CAMFImporter_NodeElement_Color* Color;///< Face color. Equal to nullptr if color is not set for the face.
|
||||||
const CAMFImporter_NodeElement_TexMap* TexMap;///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face.
|
const CAMFImporter_NodeElement_TexMap* TexMap;///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************/
|
|
||||||
/****************** Constants ******************/
|
|
||||||
/***********************************************/
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
static const aiImporterDesc Description;
|
|
||||||
|
|
||||||
/***********************************************/
|
|
||||||
/****************** Variables ******************/
|
|
||||||
/***********************************************/
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
CAMFImporter_NodeElement* mNodeElement_Cur;///< Current element.
|
|
||||||
std::list<CAMFImporter_NodeElement*> mNodeElement_List;///< All elements of scene graph.
|
|
||||||
irr::io::IrrXMLReader* mReader;///< Pointer to XML-reader object
|
|
||||||
std::string mUnit;
|
|
||||||
std::list<SPP_Material> mMaterial_Converted;///< List of converted materials for postprocessing step.
|
|
||||||
std::list<SPP_Texture> mTexture_Converted;///< List of converted textures for postprocessing step.
|
|
||||||
|
|
||||||
/***********************************************/
|
|
||||||
/****************** Functions ******************/
|
|
||||||
/***********************************************/
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
/// \fn AMFImporter(const AMFImporter& pScene)
|
|
||||||
/// Disabled copy constructor.
|
|
||||||
AMFImporter(const AMFImporter& pScene);
|
|
||||||
|
|
||||||
/// \fn AMFImporter& operator=(const AMFImporter& pScene)
|
|
||||||
/// Disabled assign operator.
|
|
||||||
AMFImporter& operator=(const AMFImporter& pScene);
|
|
||||||
|
|
||||||
/// \fn void Clear()
|
|
||||||
/// Clear all temporary data.
|
/// Clear all temporary data.
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
|
@ -200,7 +149,6 @@ private:
|
||||||
/************* Functions: find set *************/
|
/************* Functions: find set *************/
|
||||||
/***********************************************/
|
/***********************************************/
|
||||||
|
|
||||||
/// \fn bool Find_NodeElement(const std::string& pID, const CAMFImporter_NodeElement::EType pType, aiNode** pNode) const
|
|
||||||
/// Find specified node element in node elements list ( \ref mNodeElement_List).
|
/// Find specified node element in node elements list ( \ref mNodeElement_List).
|
||||||
/// \param [in] pID - ID(name) of requested node element.
|
/// \param [in] pID - ID(name) of requested node element.
|
||||||
/// \param [in] pType - type of node element.
|
/// \param [in] pType - type of node element.
|
||||||
|
@ -208,7 +156,6 @@ private:
|
||||||
/// \return true - if the node element is found, else - false.
|
/// \return true - if the node element is found, else - false.
|
||||||
bool Find_NodeElement(const std::string& pID, const CAMFImporter_NodeElement::EType pType, CAMFImporter_NodeElement** pNodeElement) const;
|
bool Find_NodeElement(const std::string& pID, const CAMFImporter_NodeElement::EType pType, CAMFImporter_NodeElement** pNodeElement) const;
|
||||||
|
|
||||||
/// \fn bool Find_ConvertedNode(const std::string& pID, std::list<aiNode*>& pNodeList, aiNode** pNode) const
|
|
||||||
/// Find requested aiNode in node list.
|
/// Find requested aiNode in node list.
|
||||||
/// \param [in] pID - ID(name) of requested node.
|
/// \param [in] pID - ID(name) of requested node.
|
||||||
/// \param [in] pNodeList - list of nodes where to find the node.
|
/// \param [in] pNodeList - list of nodes where to find the node.
|
||||||
|
@ -216,14 +163,12 @@ private:
|
||||||
/// \return true - if the node is found, else - false.
|
/// \return true - if the node is found, else - false.
|
||||||
bool Find_ConvertedNode(const std::string& pID, std::list<aiNode*>& pNodeList, aiNode** pNode) const;
|
bool Find_ConvertedNode(const std::string& pID, std::list<aiNode*>& pNodeList, aiNode** pNode) const;
|
||||||
|
|
||||||
/// \fn bool Find_ConvertedMaterial(const std::string& pID, const SPP_Material** pConvertedMaterial) const
|
|
||||||
/// Find material in list for converted materials. Use at postprocessing step.
|
/// Find material in list for converted materials. Use at postprocessing step.
|
||||||
/// \param [in] pID - material ID.
|
/// \param [in] pID - material ID.
|
||||||
/// \param [out] pConvertedMaterial - pointer to found converted material (\ref SPP_Material).
|
/// \param [out] pConvertedMaterial - pointer to found converted material (\ref SPP_Material).
|
||||||
/// \return true - if the material is found, else - false.
|
/// \return true - if the material is found, else - false.
|
||||||
bool Find_ConvertedMaterial(const std::string& pID, const SPP_Material** pConvertedMaterial) const;
|
bool Find_ConvertedMaterial(const std::string& pID, const SPP_Material** pConvertedMaterial) const;
|
||||||
|
|
||||||
/// \fn bool Find_ConvertedTexture(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A, uint32_t* pConvertedTextureIndex = nullptr) const
|
|
||||||
/// Find texture in list of converted textures. Use at postprocessing step,
|
/// Find texture in list of converted textures. Use at postprocessing step,
|
||||||
/// \param [in] pID_R - ID of source "red" texture.
|
/// \param [in] pID_R - ID of source "red" texture.
|
||||||
/// \param [in] pID_G - ID of source "green" texture.
|
/// \param [in] pID_G - ID of source "green" texture.
|
||||||
|
@ -235,11 +180,7 @@ private:
|
||||||
bool Find_ConvertedTexture(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A,
|
bool Find_ConvertedTexture(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A,
|
||||||
uint32_t* pConvertedTextureIndex = nullptr) const;
|
uint32_t* pConvertedTextureIndex = nullptr) const;
|
||||||
|
|
||||||
/***********************************************/
|
|
||||||
/********* Functions: postprocess set **********/
|
|
||||||
/***********************************************/
|
|
||||||
|
|
||||||
/// \fn void PostprocessHelper_CreateMeshDataArray(const CAMFImporter_NodeElement_Mesh& pNodeElement, std::vector<aiVector3D>& pVertexCoordinateArray, std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray) const
|
|
||||||
/// Get data stored in <vertices> and place it to arrays.
|
/// Get data stored in <vertices> and place it to arrays.
|
||||||
/// \param [in] pNodeElement - reference to node element which kept <object> data.
|
/// \param [in] pNodeElement - reference to node element which kept <object> data.
|
||||||
/// \param [in] pVertexCoordinateArray - reference to vertices coordinates kept in <vertices>.
|
/// \param [in] pVertexCoordinateArray - reference to vertices coordinates kept in <vertices>.
|
||||||
|
@ -248,7 +189,6 @@ private:
|
||||||
void PostprocessHelper_CreateMeshDataArray(const CAMFImporter_NodeElement_Mesh& pNodeElement, std::vector<aiVector3D>& pVertexCoordinateArray,
|
void PostprocessHelper_CreateMeshDataArray(const CAMFImporter_NodeElement_Mesh& pNodeElement, std::vector<aiVector3D>& pVertexCoordinateArray,
|
||||||
std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray) const;
|
std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray) const;
|
||||||
|
|
||||||
/// \fn size_t PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A)
|
|
||||||
/// Return converted texture ID which related to specified source textures ID's. If converted texture does not exist then it will be created and ID on new
|
/// Return converted texture ID which related to specified source textures ID's. If converted texture does not exist then it will be created and ID on new
|
||||||
/// converted texture will be returned. Conversion: set of textures from \ref CAMFImporter_NodeElement_Texture to one \ref SPP_Texture and place it
|
/// converted texture will be returned. Conversion: set of textures from \ref CAMFImporter_NodeElement_Texture to one \ref SPP_Texture and place it
|
||||||
/// to converted textures list.
|
/// to converted textures list.
|
||||||
|
@ -260,27 +200,23 @@ private:
|
||||||
/// \return index of the texture in array of the converted textures.
|
/// \return index of the texture in array of the converted textures.
|
||||||
size_t PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A);
|
size_t PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A);
|
||||||
|
|
||||||
/// \fn void PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace>& pInputList, std::list<std::list<SComplexFace> > pOutputList_Separated)
|
|
||||||
/// Separate input list by texture IDs. This step is needed because aiMesh can contain mesh which is use only one texture (or set: diffuse, bump etc).
|
/// Separate input list by texture IDs. This step is needed because aiMesh can contain mesh which is use only one texture (or set: diffuse, bump etc).
|
||||||
/// \param [in] pInputList - input list with faces. Some of them can contain color or texture mapping, or both of them, or nothing. Will be cleared after
|
/// \param [in] pInputList - input list with faces. Some of them can contain color or texture mapping, or both of them, or nothing. Will be cleared after
|
||||||
/// processing.
|
/// processing.
|
||||||
/// \param [out] pOutputList_Separated - output list of the faces lists. Separated faces list by used texture IDs. Will be cleared before processing.
|
/// \param [out] pOutputList_Separated - output list of the faces lists. Separated faces list by used texture IDs. Will be cleared before processing.
|
||||||
void PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace>& pInputList, std::list<std::list<SComplexFace> >& pOutputList_Separated);
|
void PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace>& pInputList, std::list<std::list<SComplexFace> >& pOutputList_Separated);
|
||||||
|
|
||||||
/// \fn void Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& pMetadataList, aiNode& pSceneNode) const
|
|
||||||
/// Check if child elements of node element is metadata and add it to scene node.
|
/// Check if child elements of node element is metadata and add it to scene node.
|
||||||
/// \param [in] pMetadataList - reference to list with collected metadata.
|
/// \param [in] pMetadataList - reference to list with collected metadata.
|
||||||
/// \param [out] pSceneNode - scene node in which metadata will be added.
|
/// \param [out] pSceneNode - scene node in which metadata will be added.
|
||||||
void Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& pMetadataList, aiNode& pSceneNode) const;
|
void Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& pMetadataList, aiNode& pSceneNode) const;
|
||||||
|
|
||||||
/// \fn void Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object& pNodeElement, std::list<aiMesh*>& pMeshList, aiNode** pSceneNode)
|
|
||||||
/// To create aiMesh and aiNode for it from <object>.
|
/// To create aiMesh and aiNode for it from <object>.
|
||||||
/// \param [in] pNodeElement - reference to node element which kept <object> data.
|
/// \param [in] pNodeElement - reference to node element which kept <object> data.
|
||||||
/// \param [out] pMeshList - reference to a list with all aiMesh of the scene.
|
/// \param [out] pMeshList - reference to a list with all aiMesh of the scene.
|
||||||
/// \param [out] pSceneNode - pointer to place where new aiNode will be created.
|
/// \param [out] pSceneNode - pointer to place where new aiNode will be created.
|
||||||
void Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object& pNodeElement, std::list<aiMesh*>& pMeshList, aiNode** pSceneNode);
|
void Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object& pNodeElement, std::list<aiMesh*>& pMeshList, aiNode** pSceneNode);
|
||||||
|
|
||||||
/// \fn void Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh& pNodeElement, const std::vector<aiVector3D>& pVertexCoordinateArray, const std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray, const CAMFImporter_NodeElement_Color* pObjectColor, std::list<aiMesh*>& pMeshList, aiNode& pSceneNode)
|
|
||||||
/// Create mesh for every <volume> in <mesh>.
|
/// Create mesh for every <volume> in <mesh>.
|
||||||
/// \param [in] pNodeElement - reference to node element which kept <mesh> data.
|
/// \param [in] pNodeElement - reference to node element which kept <mesh> data.
|
||||||
/// \param [in] pVertexCoordinateArray - reference to vertices coordinates for all <volume>'s.
|
/// \param [in] pVertexCoordinateArray - reference to vertices coordinates for all <volume>'s.
|
||||||
|
@ -294,27 +230,20 @@ private:
|
||||||
const std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray, const CAMFImporter_NodeElement_Color* pObjectColor,
|
const std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray, const CAMFImporter_NodeElement_Color* pObjectColor,
|
||||||
std::list<aiMesh*>& pMeshList, aiNode& pSceneNode);
|
std::list<aiMesh*>& pMeshList, aiNode& pSceneNode);
|
||||||
|
|
||||||
/// \fn void Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material& pMaterial)
|
|
||||||
/// Convert material from \ref CAMFImporter_NodeElement_Material to \ref SPP_Material.
|
/// Convert material from \ref CAMFImporter_NodeElement_Material to \ref SPP_Material.
|
||||||
/// \param [in] pMaterial - source CAMFImporter_NodeElement_Material.
|
/// \param [in] pMaterial - source CAMFImporter_NodeElement_Material.
|
||||||
void Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material& pMaterial);
|
void Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material& pMaterial);
|
||||||
|
|
||||||
/// \fn void Postprocess_BuildConstellation(CAMFImporter_NodeElement_Constellation& pConstellation, std::list<aiNode*>& pNodeList) const
|
|
||||||
/// Create and add to aiNode's list new part of scene graph defined by <constellation>.
|
/// Create and add to aiNode's list new part of scene graph defined by <constellation>.
|
||||||
/// \param [in] pConstellation - reference to <constellation> node.
|
/// \param [in] pConstellation - reference to <constellation> node.
|
||||||
/// \param [out] pNodeList - reference to aiNode's list.
|
/// \param [out] pNodeList - reference to aiNode's list.
|
||||||
void Postprocess_BuildConstellation(CAMFImporter_NodeElement_Constellation& pConstellation, std::list<aiNode*>& pNodeList) const;
|
void Postprocess_BuildConstellation(CAMFImporter_NodeElement_Constellation& pConstellation, std::list<aiNode*>& pNodeList) const;
|
||||||
|
|
||||||
/// \fn void Postprocess_BuildScene()
|
|
||||||
/// Build Assimp scene graph in aiScene from collected data.
|
/// Build Assimp scene graph in aiScene from collected data.
|
||||||
/// \param [out] pScene - pointer to aiScene where tree will be built.
|
/// \param [out] pScene - pointer to aiScene where tree will be built.
|
||||||
void Postprocess_BuildScene(aiScene* pScene);
|
void Postprocess_BuildScene(aiScene* pScene);
|
||||||
|
|
||||||
/***********************************************/
|
|
||||||
/************* Functions: throw set ************/
|
|
||||||
/***********************************************/
|
|
||||||
|
|
||||||
/// \fn void Throw_CloseNotFound(const std::string& pNode)
|
|
||||||
/// Call that function when close tag of node not found and exception must be raised.
|
/// Call that function when close tag of node not found and exception must be raised.
|
||||||
/// E.g.:
|
/// E.g.:
|
||||||
/// <amf>
|
/// <amf>
|
||||||
|
@ -324,19 +253,16 @@ private:
|
||||||
/// \param [in] pNode - node name in which exception happened.
|
/// \param [in] pNode - node name in which exception happened.
|
||||||
void Throw_CloseNotFound(const std::string& pNode);
|
void Throw_CloseNotFound(const std::string& pNode);
|
||||||
|
|
||||||
/// \fn void Throw_IncorrectAttr(const std::string& pAttrName)
|
|
||||||
/// Call that function when attribute name is incorrect and exception must be raised.
|
/// Call that function when attribute name is incorrect and exception must be raised.
|
||||||
/// \param [in] pAttrName - attribute name.
|
/// \param [in] pAttrName - attribute name.
|
||||||
/// \throw DeadlyImportError.
|
/// \throw DeadlyImportError.
|
||||||
void Throw_IncorrectAttr(const std::string& pAttrName);
|
void Throw_IncorrectAttr(const std::string& pAttrName);
|
||||||
|
|
||||||
/// \fn void Throw_IncorrectAttrValue(const std::string& pAttrName)
|
|
||||||
/// Call that function when attribute value is incorrect and exception must be raised.
|
/// Call that function when attribute value is incorrect and exception must be raised.
|
||||||
/// \param [in] pAttrName - attribute name.
|
/// \param [in] pAttrName - attribute name.
|
||||||
/// \throw DeadlyImportError.
|
/// \throw DeadlyImportError.
|
||||||
void Throw_IncorrectAttrValue(const std::string& pAttrName);
|
void Throw_IncorrectAttrValue(const std::string& pAttrName);
|
||||||
|
|
||||||
/// \fn void Throw_MoreThanOnceDefined(const std::string& pNode, const std::string& pDescription)
|
|
||||||
/// Call that function when some type of nodes are defined twice or more when must be used only once and exception must be raised.
|
/// Call that function when some type of nodes are defined twice or more when must be used only once and exception must be raised.
|
||||||
/// E.g.:
|
/// E.g.:
|
||||||
/// <object>
|
/// <object>
|
||||||
|
@ -348,204 +274,158 @@ private:
|
||||||
/// \param [in] pDescription - message about error. E.g. what the node defined while exception raised.
|
/// \param [in] pDescription - message about error. E.g. what the node defined while exception raised.
|
||||||
void Throw_MoreThanOnceDefined(const std::string& pNodeType, const std::string& pDescription);
|
void Throw_MoreThanOnceDefined(const std::string& pNodeType, const std::string& pDescription);
|
||||||
|
|
||||||
/// \fn void Throw_ID_NotFound(const std::string& pID) const
|
|
||||||
/// Call that function when referenced element ID are not found in graph and exception must be raised.
|
/// Call that function when referenced element ID are not found in graph and exception must be raised.
|
||||||
/// \param [in] pID - ID of of element which not found.
|
/// \param [in] pID - ID of of element which not found.
|
||||||
/// \throw DeadlyImportError.
|
/// \throw DeadlyImportError.
|
||||||
void Throw_ID_NotFound(const std::string& pID) const;
|
void Throw_ID_NotFound(const std::string& pID) const;
|
||||||
|
|
||||||
/***********************************************/
|
|
||||||
/************** Functions: LOG set *************/
|
|
||||||
/***********************************************/
|
|
||||||
|
|
||||||
/***********************************************/
|
|
||||||
/************** Functions: XML set *************/
|
|
||||||
/***********************************************/
|
|
||||||
|
|
||||||
/// \fn void XML_CheckNode_MustHaveChildren()
|
|
||||||
/// Check if current node have children: <node>...</node>. If not then exception will throwed.
|
/// Check if current node have children: <node>...</node>. If not then exception will throwed.
|
||||||
void XML_CheckNode_MustHaveChildren();
|
void XML_CheckNode_MustHaveChildren();
|
||||||
|
|
||||||
/// \fn bool XML_CheckNode_NameEqual(const std::string& pNodeName)
|
|
||||||
/// Check if current node name is equal to pNodeName.
|
/// Check if current node name is equal to pNodeName.
|
||||||
/// \param [in] pNodeName - name for checking.
|
/// \param [in] pNodeName - name for checking.
|
||||||
/// return true if current node name is equal to pNodeName, else - false.
|
/// return true if current node name is equal to pNodeName, else - false.
|
||||||
bool XML_CheckNode_NameEqual(const std::string& pNodeName) { return mReader->getNodeName() == pNodeName; }
|
bool XML_CheckNode_NameEqual(const std::string& pNodeName) { return mReader->getNodeName() == pNodeName; }
|
||||||
|
|
||||||
/// \fn void XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName)
|
|
||||||
/// Skip unsupported node and report about that. Depend on node name can be skipped begin tag of node all whole node.
|
/// Skip unsupported node and report about that. Depend on node name can be skipped begin tag of node all whole node.
|
||||||
/// \param [in] pParentNodeName - parent node name. Used for reporting.
|
/// \param [in] pParentNodeName - parent node name. Used for reporting.
|
||||||
void XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName);
|
void XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName);
|
||||||
|
|
||||||
/// \fn bool XML_SearchNode(const std::string& pNodeName)
|
|
||||||
/// Search for specified node in file. XML file read pointer(mReader) will point to found node or file end after search is end.
|
/// Search for specified node in file. XML file read pointer(mReader) will point to found node or file end after search is end.
|
||||||
/// \param [in] pNodeName - requested node name.
|
/// \param [in] pNodeName - requested node name.
|
||||||
/// return true - if node is found, else - false.
|
/// return true - if node is found, else - false.
|
||||||
bool XML_SearchNode(const std::string& pNodeName);
|
bool XML_SearchNode(const std::string& pNodeName);
|
||||||
|
|
||||||
/// \fn bool XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx)
|
|
||||||
/// Read attribute value.
|
/// Read attribute value.
|
||||||
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
|
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
|
||||||
/// \return read data.
|
/// \return read data.
|
||||||
bool XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx);
|
bool XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx);
|
||||||
|
|
||||||
/// \fn float XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx)
|
|
||||||
/// Read attribute value.
|
/// Read attribute value.
|
||||||
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
|
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
|
||||||
/// \return read data.
|
/// \return read data.
|
||||||
float XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx);
|
float XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx);
|
||||||
|
|
||||||
/// \fn uint32_t XML_ReadNode_GetAttrVal_AsU32(const int pAttrIdx)
|
|
||||||
/// Read attribute value.
|
/// Read attribute value.
|
||||||
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
|
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
|
||||||
/// \return read data.
|
/// \return read data.
|
||||||
uint32_t XML_ReadNode_GetAttrVal_AsU32(const int pAttrIdx);
|
uint32_t XML_ReadNode_GetAttrVal_AsU32(const int pAttrIdx);
|
||||||
|
|
||||||
/// \fn float XML_ReadNode_GetVal_AsFloat()
|
|
||||||
/// Read node value.
|
/// Read node value.
|
||||||
/// \return read data.
|
/// \return read data.
|
||||||
float XML_ReadNode_GetVal_AsFloat();
|
float XML_ReadNode_GetVal_AsFloat();
|
||||||
|
|
||||||
/// \fn uint32_t XML_ReadNode_GetVal_AsU32()
|
|
||||||
/// Read node value.
|
/// Read node value.
|
||||||
/// \return read data.
|
/// \return read data.
|
||||||
uint32_t XML_ReadNode_GetVal_AsU32();
|
uint32_t XML_ReadNode_GetVal_AsU32();
|
||||||
|
|
||||||
/// \fn void XML_ReadNode_GetVal_AsString(std::string& pValue)
|
|
||||||
/// Read node value.
|
/// Read node value.
|
||||||
/// \return read data.
|
/// \return read data.
|
||||||
void XML_ReadNode_GetVal_AsString(std::string& pValue);
|
void XML_ReadNode_GetVal_AsString(std::string& pValue);
|
||||||
|
|
||||||
/***********************************************/
|
|
||||||
/******** Functions: parse set private *********/
|
|
||||||
/***********************************************/
|
|
||||||
|
|
||||||
/// \fn void ParseHelper_Node_Enter(CAMFImporter_NodeElement* pNode)
|
|
||||||
/// Make pNode as current and enter deeper for parsing child nodes. At end \ref ParseHelper_Node_Exit must be called.
|
/// Make pNode as current and enter deeper for parsing child nodes. At end \ref ParseHelper_Node_Exit must be called.
|
||||||
/// \param [in] pNode - new current node.
|
/// \param [in] pNode - new current node.
|
||||||
void ParseHelper_Node_Enter(CAMFImporter_NodeElement* pNode);
|
void ParseHelper_Node_Enter(CAMFImporter_NodeElement* pNode);
|
||||||
|
|
||||||
/// \fn void ParseHelper_Group_End()
|
|
||||||
/// This function must be called when exiting from grouping node. \ref ParseHelper_Group_Begin.
|
/// This function must be called when exiting from grouping node. \ref ParseHelper_Group_Begin.
|
||||||
void ParseHelper_Node_Exit();
|
void ParseHelper_Node_Exit();
|
||||||
|
|
||||||
/// \fn void ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString)
|
|
||||||
/// Attribute values of floating point types can take form ".x"(without leading zero). irrXMLReader can not read this form of values and it
|
/// Attribute values of floating point types can take form ".x"(without leading zero). irrXMLReader can not read this form of values and it
|
||||||
/// must be converted to right form - "0.xxx".
|
/// must be converted to right form - "0.xxx".
|
||||||
/// \param [in] pInStr - pointer to input string which can contain incorrect form of values.
|
/// \param [in] pInStr - pointer to input string which can contain incorrect form of values.
|
||||||
/// \param [out[ pOutString - output string with right form of values.
|
/// \param [out[ pOutString - output string with right form of values.
|
||||||
void ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString);
|
void ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString);
|
||||||
|
|
||||||
/// \fn void ParseHelper_Decode_Base64(const std::string& pInputBase64, std::vector<uint8_t>& pOutputData) const
|
|
||||||
/// Decode Base64-encoded data.
|
/// Decode Base64-encoded data.
|
||||||
/// \param [in] pInputBase64 - reference to input Base64-encoded string.
|
/// \param [in] pInputBase64 - reference to input Base64-encoded string.
|
||||||
/// \param [out] pOutputData - reference to output array for decoded data.
|
/// \param [out] pOutputData - reference to output array for decoded data.
|
||||||
void ParseHelper_Decode_Base64(const std::string& pInputBase64, std::vector<uint8_t>& pOutputData) const;
|
void ParseHelper_Decode_Base64(const std::string& pInputBase64, std::vector<uint8_t>& pOutputData) const;
|
||||||
|
|
||||||
/// \fn void ParseNode_Root()
|
|
||||||
/// Parse <AMF> node of the file.
|
/// Parse <AMF> node of the file.
|
||||||
void ParseNode_Root();
|
void ParseNode_Root();
|
||||||
|
|
||||||
/******** Functions: top nodes *********/
|
|
||||||
|
|
||||||
/// \fn void ParseNode_Constellation()
|
|
||||||
/// Parse <constellation> node of the file.
|
/// Parse <constellation> node of the file.
|
||||||
void ParseNode_Constellation();
|
void ParseNode_Constellation();
|
||||||
|
|
||||||
/// \fn void ParseNode_Constellation()
|
|
||||||
/// Parse <instance> node of the file.
|
/// Parse <instance> node of the file.
|
||||||
void ParseNode_Instance();
|
void ParseNode_Instance();
|
||||||
|
|
||||||
/// \fn void ParseNode_Material()
|
|
||||||
/// Parse <material> node of the file.
|
/// Parse <material> node of the file.
|
||||||
void ParseNode_Material();
|
void ParseNode_Material();
|
||||||
|
|
||||||
/// \fn void ParseNode_Metadata()
|
|
||||||
/// Parse <metadata> node.
|
/// Parse <metadata> node.
|
||||||
void ParseNode_Metadata();
|
void ParseNode_Metadata();
|
||||||
|
|
||||||
/// \fn void ParseNode_Object()
|
|
||||||
/// Parse <object> node of the file.
|
/// Parse <object> node of the file.
|
||||||
void ParseNode_Object();
|
void ParseNode_Object();
|
||||||
|
|
||||||
/// \fn void ParseNode_Texture()
|
|
||||||
/// Parse <texture> node of the file.
|
/// Parse <texture> node of the file.
|
||||||
void ParseNode_Texture();
|
void ParseNode_Texture();
|
||||||
|
|
||||||
/******** Functions: geometry nodes *********/
|
|
||||||
|
|
||||||
/// \fn void ParseNode_Coordinates()
|
|
||||||
/// Parse <coordinates> node of the file.
|
/// Parse <coordinates> node of the file.
|
||||||
void ParseNode_Coordinates();
|
void ParseNode_Coordinates();
|
||||||
|
|
||||||
/// \fn void ParseNode_Edge()
|
|
||||||
/// Parse <edge> node of the file.
|
/// Parse <edge> node of the file.
|
||||||
void ParseNode_Edge();
|
void ParseNode_Edge();
|
||||||
|
|
||||||
/// \fn void ParseNode_Mesh()
|
|
||||||
/// Parse <mesh> node of the file.
|
/// Parse <mesh> node of the file.
|
||||||
void ParseNode_Mesh();
|
void ParseNode_Mesh();
|
||||||
|
|
||||||
/// \fn void ParseNode_Triangle()
|
|
||||||
/// Parse <triangle> node of the file.
|
/// Parse <triangle> node of the file.
|
||||||
void ParseNode_Triangle();
|
void ParseNode_Triangle();
|
||||||
|
|
||||||
/// \fn void ParseNode_Vertex()
|
|
||||||
/// Parse <vertex> node of the file.
|
/// Parse <vertex> node of the file.
|
||||||
void ParseNode_Vertex();
|
void ParseNode_Vertex();
|
||||||
|
|
||||||
/// \fn void ParseNode_Vertices()
|
|
||||||
/// Parse <vertices> node of the file.
|
/// Parse <vertices> node of the file.
|
||||||
void ParseNode_Vertices();
|
void ParseNode_Vertices();
|
||||||
|
|
||||||
/// \fn void ParseNode_Volume()
|
|
||||||
/// Parse <volume> node of the file.
|
/// Parse <volume> node of the file.
|
||||||
void ParseNode_Volume();
|
void ParseNode_Volume();
|
||||||
|
|
||||||
/******** Functions: material nodes *********/
|
|
||||||
|
|
||||||
/// \fn void ParseNode_Color()
|
|
||||||
/// Parse <color> node of the file.
|
/// Parse <color> node of the file.
|
||||||
void ParseNode_Color();
|
void ParseNode_Color();
|
||||||
|
|
||||||
/// \fn void ParseNode_TexMap(const bool pUseOldName = false)
|
|
||||||
/// Parse <texmap> of <map> node of the file.
|
/// Parse <texmap> of <map> node of the file.
|
||||||
/// \param [in] pUseOldName - if true then use old name of node(and children) - <map>, instead of new name - <texmap>.
|
/// \param [in] pUseOldName - if true then use old name of node(and children) - <map>, instead of new name - <texmap>.
|
||||||
void ParseNode_TexMap(const bool pUseOldName = false);
|
void ParseNode_TexMap(const bool pUseOldName = false);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// \fn AMFImporter()
|
|
||||||
/// Default constructor.
|
/// Default constructor.
|
||||||
AMFImporter()
|
AMFImporter() AI_NO_EXCEPT
|
||||||
: mNodeElement_Cur(nullptr), mReader(nullptr)
|
: mNodeElement_Cur(nullptr)
|
||||||
{}
|
, mReader(nullptr) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
/// \fn ~AMFImporter()
|
|
||||||
/// Default destructor.
|
/// Default destructor.
|
||||||
~AMFImporter();
|
~AMFImporter();
|
||||||
|
|
||||||
/***********************************************/
|
|
||||||
/******** Functions: parse set, public *********/
|
|
||||||
/***********************************************/
|
|
||||||
|
|
||||||
/// \fn void ParseFile(const std::string& pFile, IOSystem* pIOHandler)
|
|
||||||
/// Parse AMF file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph.
|
/// Parse AMF file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph.
|
||||||
/// Also exception can be throwed if trouble will found.
|
/// Also exception can be thrown if trouble will found.
|
||||||
/// \param [in] pFile - name of file to be parsed.
|
/// \param [in] pFile - name of file to be parsed.
|
||||||
/// \param [in] pIOHandler - pointer to IO helper object.
|
/// \param [in] pIOHandler - pointer to IO helper object.
|
||||||
void ParseFile(const std::string& pFile, IOSystem* pIOHandler);
|
void ParseFile(const std::string& pFile, IOSystem* pIOHandler);
|
||||||
|
|
||||||
/***********************************************/
|
|
||||||
/********* Functions: BaseImporter set *********/
|
|
||||||
/***********************************************/
|
|
||||||
|
|
||||||
bool CanRead(const std::string& pFile, IOSystem* pIOHandler, bool pCheckSig) const;
|
bool CanRead(const std::string& pFile, IOSystem* pIOHandler, bool pCheckSig) const;
|
||||||
void GetExtensionList(std::set<std::string>& pExtensionList);
|
void GetExtensionList(std::set<std::string>& pExtensionList);
|
||||||
void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
|
void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
|
||||||
const aiImporterDesc* GetInfo ()const;
|
const aiImporterDesc* GetInfo ()const;
|
||||||
|
|
||||||
};// class AMFImporter
|
AMFImporter(const AMFImporter& pScene) = delete;
|
||||||
|
AMFImporter& operator=(const AMFImporter& pScene) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const aiImporterDesc Description;
|
||||||
|
|
||||||
|
CAMFImporter_NodeElement* mNodeElement_Cur;///< Current element.
|
||||||
|
std::list<CAMFImporter_NodeElement*> mNodeElement_List;///< All elements of scene graph.
|
||||||
|
irr::io::IrrXMLReader* mReader;///< Pointer to XML-reader object
|
||||||
|
std::string mUnit;
|
||||||
|
std::list<SPP_Material> mMaterial_Converted;///< List of converted materials for postprocessing step.
|
||||||
|
std::list<SPP_Texture> mTexture_Converted;///< List of converted textures for postprocessing step.
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
}// namespace Assimp
|
}// namespace Assimp
|
||||||
|
|
||||||
|
|
|
@ -68,8 +68,7 @@ namespace Assimp
|
||||||
// Multi elements - No.
|
// Multi elements - No.
|
||||||
// Red, Greed, Blue and Alpha (transparency) component of a color in sRGB space, values ranging from 0 to 1. The
|
// Red, Greed, Blue and Alpha (transparency) component of a color in sRGB space, values ranging from 0 to 1. The
|
||||||
// values can be specified as constants, or as a formula depending on the coordinates.
|
// values can be specified as constants, or as a formula depending on the coordinates.
|
||||||
void AMFImporter::ParseNode_Color()
|
void AMFImporter::ParseNode_Color() {
|
||||||
{
|
|
||||||
std::string profile;
|
std::string profile;
|
||||||
CAMFImporter_NodeElement* ne;
|
CAMFImporter_NodeElement* ne;
|
||||||
|
|
||||||
|
@ -98,15 +97,19 @@ CAMFImporter_NodeElement* ne;
|
||||||
MACRO_NODECHECK_LOOPEND("color");
|
MACRO_NODECHECK_LOOPEND("color");
|
||||||
ParseHelper_Node_Exit();
|
ParseHelper_Node_Exit();
|
||||||
// check that all components was defined
|
// check that all components was defined
|
||||||
if(!(read_flag[0] && read_flag[1] && read_flag[2])) throw DeadlyImportError("Not all color components are defined.");
|
if (!(read_flag[0] && read_flag[1] && read_flag[2])) {
|
||||||
// check if <a> is absent. Then manually add "a == 1".
|
throw DeadlyImportError("Not all color components are defined.");
|
||||||
if(!read_flag[3]) als.Color.a = 1;
|
}
|
||||||
|
|
||||||
}// if(!mReader->isEmptyElement())
|
// check if <a> is absent. Then manually add "a == 1".
|
||||||
|
if (!read_flag[3]) {
|
||||||
|
als.Color.a = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
||||||
}// if(!mReader->isEmptyElement()) else
|
}
|
||||||
|
|
||||||
als.Composed = false;
|
als.Composed = false;
|
||||||
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
||||||
|
@ -119,8 +122,7 @@ CAMFImporter_NodeElement* ne;
|
||||||
// An available material.
|
// An available material.
|
||||||
// Multi elements - Yes.
|
// Multi elements - Yes.
|
||||||
// Parent element - <amf>.
|
// Parent element - <amf>.
|
||||||
void AMFImporter::ParseNode_Material()
|
void AMFImporter::ParseNode_Material() {
|
||||||
{
|
|
||||||
std::string id;
|
std::string id;
|
||||||
CAMFImporter_NodeElement* ne;
|
CAMFImporter_NodeElement* ne;
|
||||||
|
|
||||||
|
@ -131,8 +133,10 @@ CAMFImporter_NodeElement* ne;
|
||||||
|
|
||||||
// create new object.
|
// create new object.
|
||||||
ne = new CAMFImporter_NodeElement_Material(mNodeElement_Cur);
|
ne = new CAMFImporter_NodeElement_Material(mNodeElement_Cur);
|
||||||
|
|
||||||
// and assign read data
|
// and assign read data
|
||||||
((CAMFImporter_NodeElement_Material*)ne)->ID = id;
|
((CAMFImporter_NodeElement_Material*)ne)->ID = id;
|
||||||
|
|
||||||
// Check for child nodes
|
// Check for child nodes
|
||||||
if(!mReader->isEmptyElement())
|
if(!mReader->isEmptyElement())
|
||||||
{
|
{
|
||||||
|
@ -154,11 +158,11 @@ CAMFImporter_NodeElement* ne;
|
||||||
if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
|
if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
|
||||||
MACRO_NODECHECK_LOOPEND("material");
|
MACRO_NODECHECK_LOOPEND("material");
|
||||||
ParseHelper_Node_Exit();
|
ParseHelper_Node_Exit();
|
||||||
}// if(!mReader->isEmptyElement())
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
||||||
}// if(!mReader->isEmptyElement()) else
|
}
|
||||||
|
|
||||||
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
||||||
}
|
}
|
||||||
|
@ -188,7 +192,6 @@ uint32_t depth = 1;
|
||||||
std::string type;
|
std::string type;
|
||||||
bool tiled = false;
|
bool tiled = false;
|
||||||
std::string enc64_data;
|
std::string enc64_data;
|
||||||
CAMFImporter_NodeElement* ne;
|
|
||||||
|
|
||||||
// Read attributes for node <color>.
|
// Read attributes for node <color>.
|
||||||
MACRO_ATTRREAD_LOOPBEG;
|
MACRO_ATTRREAD_LOOPBEG;
|
||||||
|
@ -201,20 +204,34 @@ CAMFImporter_NodeElement* ne;
|
||||||
MACRO_ATTRREAD_LOOPEND;
|
MACRO_ATTRREAD_LOOPEND;
|
||||||
|
|
||||||
// create new texture object.
|
// create new texture object.
|
||||||
ne = new CAMFImporter_NodeElement_Texture(mNodeElement_Cur);
|
CAMFImporter_NodeElement *ne = new CAMFImporter_NodeElement_Texture(mNodeElement_Cur);
|
||||||
|
|
||||||
CAMFImporter_NodeElement_Texture& als = *((CAMFImporter_NodeElement_Texture*)ne);// alias for convenience
|
CAMFImporter_NodeElement_Texture& als = *((CAMFImporter_NodeElement_Texture*)ne);// alias for convenience
|
||||||
|
|
||||||
// Check for child nodes
|
// Check for child nodes
|
||||||
if(!mReader->isEmptyElement()) XML_ReadNode_GetVal_AsString(enc64_data);
|
if (!mReader->isEmptyElement()) {
|
||||||
|
XML_ReadNode_GetVal_AsString(enc64_data);
|
||||||
|
}
|
||||||
|
|
||||||
// check that all components was defined
|
// check that all components was defined
|
||||||
if(id.empty()) throw DeadlyImportError("ID for texture must be defined.");
|
if (id.empty()) {
|
||||||
if(width < 1) Throw_IncorrectAttrValue("width");
|
throw DeadlyImportError("ID for texture must be defined.");
|
||||||
if(height < 1) Throw_IncorrectAttrValue("height");
|
}
|
||||||
if(depth < 1) Throw_IncorrectAttrValue("depth");
|
if (width < 1) {
|
||||||
if(type != "grayscale") Throw_IncorrectAttrValue("type");
|
Throw_IncorrectAttrValue("width");
|
||||||
if(enc64_data.empty()) throw DeadlyImportError("Texture data not defined.");
|
}
|
||||||
|
if (height < 1) {
|
||||||
|
Throw_IncorrectAttrValue("height");
|
||||||
|
}
|
||||||
|
if (depth < 1) {
|
||||||
|
Throw_IncorrectAttrValue("depth");
|
||||||
|
}
|
||||||
|
if (type != "grayscale") {
|
||||||
|
Throw_IncorrectAttrValue("type");
|
||||||
|
}
|
||||||
|
if (enc64_data.empty()) {
|
||||||
|
throw DeadlyImportError("Texture data not defined.");
|
||||||
|
}
|
||||||
// copy data
|
// copy data
|
||||||
als.ID = id;
|
als.ID = id;
|
||||||
als.Width = width;
|
als.Width = width;
|
||||||
|
@ -222,8 +239,11 @@ CAMFImporter_NodeElement* ne;
|
||||||
als.Depth = depth;
|
als.Depth = depth;
|
||||||
als.Tiled = tiled;
|
als.Tiled = tiled;
|
||||||
ParseHelper_Decode_Base64(enc64_data, als.Data);
|
ParseHelper_Decode_Base64(enc64_data, als.Data);
|
||||||
|
|
||||||
// check data size
|
// check data size
|
||||||
if((width * height * depth) != als.Data.size()) throw DeadlyImportError("Texture has incorrect data size.");
|
if ((width * height * depth) != als.Data.size()) {
|
||||||
|
throw DeadlyImportError("Texture has incorrect data size.");
|
||||||
|
}
|
||||||
|
|
||||||
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
||||||
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
||||||
|
@ -243,10 +263,8 @@ CAMFImporter_NodeElement* ne;
|
||||||
// <utex1>, <utex2>, <utex3>, <vtex1>, <vtex2>, <vtex3>. Old name: <u1>, <u2>, <u3>, <v1>, <v2>, <v3>.
|
// <utex1>, <utex2>, <utex3>, <vtex1>, <vtex2>, <vtex3>. Old name: <u1>, <u2>, <u3>, <v1>, <v2>, <v3>.
|
||||||
// Multi elements - No.
|
// Multi elements - No.
|
||||||
// Texture coordinates for every vertex of triangle.
|
// Texture coordinates for every vertex of triangle.
|
||||||
void AMFImporter::ParseNode_TexMap(const bool pUseOldName)
|
void AMFImporter::ParseNode_TexMap(const bool pUseOldName) {
|
||||||
{
|
|
||||||
std::string rtexid, gtexid, btexid, atexid;
|
std::string rtexid, gtexid, btexid, atexid;
|
||||||
CAMFImporter_NodeElement* ne;
|
|
||||||
|
|
||||||
// Read attributes for node <color>.
|
// Read attributes for node <color>.
|
||||||
MACRO_ATTRREAD_LOOPBEG;
|
MACRO_ATTRREAD_LOOPBEG;
|
||||||
|
@ -257,7 +275,7 @@ CAMFImporter_NodeElement* ne;
|
||||||
MACRO_ATTRREAD_LOOPEND;
|
MACRO_ATTRREAD_LOOPEND;
|
||||||
|
|
||||||
// create new texture coordinates object.
|
// create new texture coordinates object.
|
||||||
ne = new CAMFImporter_NodeElement_TexMap(mNodeElement_Cur);
|
CAMFImporter_NodeElement *ne = new CAMFImporter_NodeElement_TexMap(mNodeElement_Cur);
|
||||||
|
|
||||||
CAMFImporter_NodeElement_TexMap& als = *((CAMFImporter_NodeElement_TexMap*)ne);// alias for convenience
|
CAMFImporter_NodeElement_TexMap& als = *((CAMFImporter_NodeElement_TexMap*)ne);// alias for convenience
|
||||||
// check data
|
// check data
|
||||||
|
|
|
@ -62,7 +62,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
/// \class CAMFImporter_NodeElement
|
/// \class CAMFImporter_NodeElement
|
||||||
/// Base class for elements of nodes.
|
/// Base class for elements of nodes.
|
||||||
class CAMFImporter_NodeElement {
|
class CAMFImporter_NodeElement {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Define what data type contain node element.
|
/// Define what data type contain node element.
|
||||||
enum EType {
|
enum EType {
|
||||||
|
@ -96,15 +95,11 @@ public: /// Destructor, virtual..
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
/// Disabled copy constructor and co.
|
||||||
/// Disabled copy constructor.
|
CAMFImporter_NodeElement(const CAMFImporter_NodeElement& pNodeElement) = delete;
|
||||||
CAMFImporter_NodeElement(const CAMFImporter_NodeElement& pNodeElement);
|
CAMFImporter_NodeElement(CAMFImporter_NodeElement&&) = delete;
|
||||||
|
CAMFImporter_NodeElement& operator=(const CAMFImporter_NodeElement& pNodeElement) = delete;
|
||||||
/// Disabled assign operator.
|
CAMFImporter_NodeElement() = delete;
|
||||||
CAMFImporter_NodeElement& operator=(const CAMFImporter_NodeElement& pNodeElement);
|
|
||||||
|
|
||||||
/// Disabled default constructor.
|
|
||||||
CAMFImporter_NodeElement();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// In constructor inheritor must set element type.
|
/// In constructor inheritor must set element type.
|
||||||
|
@ -121,9 +116,7 @@ protected:
|
||||||
|
|
||||||
/// \struct CAMFImporter_NodeElement_Constellation
|
/// \struct CAMFImporter_NodeElement_Constellation
|
||||||
/// A collection of objects or constellations with specific relative locations.
|
/// A collection of objects or constellations with specific relative locations.
|
||||||
struct CAMFImporter_NodeElement_Constellation : public CAMFImporter_NodeElement
|
struct CAMFImporter_NodeElement_Constellation : public CAMFImporter_NodeElement {
|
||||||
{
|
|
||||||
/// \fn CAMFImporter_NodeElement_Constellation(CAMFImporter_NodeElement* pParent)
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
CAMFImporter_NodeElement_Constellation(CAMFImporter_NodeElement* pParent)
|
CAMFImporter_NodeElement_Constellation(CAMFImporter_NodeElement* pParent)
|
||||||
|
@ -134,9 +127,7 @@ struct CAMFImporter_NodeElement_Constellation : public CAMFImporter_NodeElement
|
||||||
|
|
||||||
/// \struct CAMFImporter_NodeElement_Instance
|
/// \struct CAMFImporter_NodeElement_Instance
|
||||||
/// Part of constellation.
|
/// Part of constellation.
|
||||||
struct CAMFImporter_NodeElement_Instance : public CAMFImporter_NodeElement
|
struct CAMFImporter_NodeElement_Instance : public CAMFImporter_NodeElement {
|
||||||
{
|
|
||||||
/****************** Variables ******************/
|
|
||||||
|
|
||||||
std::string ObjectID;///< ID of object for instantiation.
|
std::string ObjectID;///< ID of object for instantiation.
|
||||||
/// \var Delta - The distance of translation in the x, y, or z direction, respectively, in the referenced object's coordinate system, to
|
/// \var Delta - The distance of translation in the x, y, or z direction, respectively, in the referenced object's coordinate system, to
|
||||||
|
@ -147,237 +138,185 @@ struct CAMFImporter_NodeElement_Instance : public CAMFImporter_NodeElement
|
||||||
/// instance of the object in the current constellation. Rotations shall be executed in order of x first, then y, then z.
|
/// instance of the object in the current constellation. Rotations shall be executed in order of x first, then y, then z.
|
||||||
aiVector3D Rotation;
|
aiVector3D Rotation;
|
||||||
|
|
||||||
/****************** Functions ******************/
|
|
||||||
|
|
||||||
/// \fn CAMFImporter_NodeElement_Instance(CAMFImporter_NodeElement* pParent)
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
CAMFImporter_NodeElement_Instance(CAMFImporter_NodeElement* pParent)
|
CAMFImporter_NodeElement_Instance(CAMFImporter_NodeElement* pParent)
|
||||||
: CAMFImporter_NodeElement(ENET_Instance, pParent)
|
: CAMFImporter_NodeElement(ENET_Instance, pParent)
|
||||||
{}
|
{}
|
||||||
|
};
|
||||||
};// struct CAMFImporter_NodeElement_Instance
|
|
||||||
|
|
||||||
/// \struct CAMFImporter_NodeElement_Metadata
|
/// \struct CAMFImporter_NodeElement_Metadata
|
||||||
/// Structure that define metadata node.
|
/// Structure that define metadata node.
|
||||||
struct CAMFImporter_NodeElement_Metadata : public CAMFImporter_NodeElement
|
struct CAMFImporter_NodeElement_Metadata : public CAMFImporter_NodeElement {
|
||||||
{
|
|
||||||
/****************** Variables ******************/
|
|
||||||
|
|
||||||
std::string Type;///< Type of "Value".
|
std::string Type;///< Type of "Value".
|
||||||
std::string Value;///< Value.
|
std::string Value;///< Value.
|
||||||
|
|
||||||
/****************** Functions ******************/
|
|
||||||
|
|
||||||
/// \fn CAMFImporter_NodeElement_Metadata(CAMFImporter_NodeElement* pParent)
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
CAMFImporter_NodeElement_Metadata(CAMFImporter_NodeElement* pParent)
|
CAMFImporter_NodeElement_Metadata(CAMFImporter_NodeElement* pParent)
|
||||||
: CAMFImporter_NodeElement(ENET_Metadata, pParent)
|
: CAMFImporter_NodeElement(ENET_Metadata, pParent)
|
||||||
{}
|
{}
|
||||||
|
};
|
||||||
};// struct CAMFImporter_NodeElement_Metadata
|
|
||||||
|
|
||||||
/// \struct CAMFImporter_NodeElement_Root
|
/// \struct CAMFImporter_NodeElement_Root
|
||||||
/// Structure that define root node.
|
/// Structure that define root node.
|
||||||
struct CAMFImporter_NodeElement_Root : public CAMFImporter_NodeElement
|
struct CAMFImporter_NodeElement_Root : public CAMFImporter_NodeElement {
|
||||||
{
|
|
||||||
/****************** Variables ******************/
|
|
||||||
|
|
||||||
std::string Unit;///< The units to be used. May be "inch", "millimeter", "meter", "feet", or "micron".
|
std::string Unit;///< The units to be used. May be "inch", "millimeter", "meter", "feet", or "micron".
|
||||||
std::string Version;///< Version of format.
|
std::string Version;///< Version of format.
|
||||||
|
|
||||||
/****************** Functions ******************/
|
|
||||||
|
|
||||||
/// \fn CAMFImporter_NodeElement_Root(CAMFImporter_NodeElement* pParent)
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
CAMFImporter_NodeElement_Root(CAMFImporter_NodeElement* pParent)
|
CAMFImporter_NodeElement_Root(CAMFImporter_NodeElement* pParent)
|
||||||
: CAMFImporter_NodeElement(ENET_Root, pParent)
|
: CAMFImporter_NodeElement(ENET_Root, pParent)
|
||||||
{}
|
{}
|
||||||
|
};
|
||||||
};// struct CAMFImporter_NodeElement_Root
|
|
||||||
|
|
||||||
/// \struct CAMFImporter_NodeElement_Color
|
/// \struct CAMFImporter_NodeElement_Color
|
||||||
/// Structure that define object node.
|
/// Structure that define object node.
|
||||||
struct CAMFImporter_NodeElement_Color : public CAMFImporter_NodeElement
|
struct CAMFImporter_NodeElement_Color : public CAMFImporter_NodeElement {
|
||||||
{
|
|
||||||
/****************** Variables ******************/
|
|
||||||
|
|
||||||
bool Composed; ///< Type of color stored: if true then look for formula in \ref Color_Composed[4], else - in \ref Color.
|
bool Composed; ///< Type of color stored: if true then look for formula in \ref Color_Composed[4], else - in \ref Color.
|
||||||
std::string Color_Composed[4];///< By components formulas of composed color. [0..3] => RGBA.
|
std::string Color_Composed[4]; ///< By components formulas of composed color. [0..3] - RGBA.
|
||||||
aiColor4D Color; ///< Constant color.
|
aiColor4D Color; ///< Constant color.
|
||||||
std::string Profile;///< The ICC color space used to interpret the three color channels <r>, <g> and <b>..
|
std::string Profile; ///< The ICC color space used to interpret the three color channels r, g and b..
|
||||||
|
|
||||||
/****************** Functions ******************/
|
/// @brief Constructor.
|
||||||
|
/// @param [in] pParent - pointer to parent node.
|
||||||
/// \fn CAMFImporter_NodeElement_Color(CAMFImporter_NodeElement* pParent)
|
|
||||||
/// Constructor.
|
|
||||||
/// \param [in] pParent - pointer to parent node.
|
|
||||||
CAMFImporter_NodeElement_Color(CAMFImporter_NodeElement* pParent)
|
CAMFImporter_NodeElement_Color(CAMFImporter_NodeElement* pParent)
|
||||||
: CAMFImporter_NodeElement(ENET_Color, pParent)
|
: CAMFImporter_NodeElement(ENET_Color, pParent)
|
||||||
{}
|
, Composed( false )
|
||||||
|
, Color()
|
||||||
};// struct CAMFImporter_NodeElement_Color
|
, Profile() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// \struct CAMFImporter_NodeElement_Material
|
/// \struct CAMFImporter_NodeElement_Material
|
||||||
/// Structure that define material node.
|
/// Structure that define material node.
|
||||||
struct CAMFImporter_NodeElement_Material : public CAMFImporter_NodeElement
|
struct CAMFImporter_NodeElement_Material : public CAMFImporter_NodeElement {
|
||||||
{
|
|
||||||
/// \fn CAMFImporter_NodeElement_Material(CAMFImporter_NodeElement* pParent)
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
CAMFImporter_NodeElement_Material(CAMFImporter_NodeElement* pParent)
|
CAMFImporter_NodeElement_Material(CAMFImporter_NodeElement* pParent)
|
||||||
: CAMFImporter_NodeElement(ENET_Material, pParent)
|
: CAMFImporter_NodeElement(ENET_Material, pParent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
};// struct CAMFImporter_NodeElement_Material
|
};
|
||||||
|
|
||||||
/// \struct CAMFImporter_NodeElement_Object
|
/// \struct CAMFImporter_NodeElement_Object
|
||||||
/// Structure that define object node.
|
/// Structure that define object node.
|
||||||
struct CAMFImporter_NodeElement_Object : public CAMFImporter_NodeElement
|
struct CAMFImporter_NodeElement_Object : public CAMFImporter_NodeElement {
|
||||||
{
|
|
||||||
/// \fn CAMFImporter_NodeElement_Object(CAMFImporter_NodeElement* pParent)
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
CAMFImporter_NodeElement_Object(CAMFImporter_NodeElement* pParent)
|
CAMFImporter_NodeElement_Object(CAMFImporter_NodeElement* pParent)
|
||||||
: CAMFImporter_NodeElement(ENET_Object, pParent)
|
: CAMFImporter_NodeElement(ENET_Object, pParent)
|
||||||
{}
|
{}
|
||||||
|
};
|
||||||
};// struct CAMFImporter_NodeElement_Object
|
|
||||||
|
|
||||||
/// \struct CAMFImporter_NodeElement_Mesh
|
/// \struct CAMFImporter_NodeElement_Mesh
|
||||||
/// Structure that define mesh node.
|
/// Structure that define mesh node.
|
||||||
struct CAMFImporter_NodeElement_Mesh : public CAMFImporter_NodeElement
|
struct CAMFImporter_NodeElement_Mesh : public CAMFImporter_NodeElement {
|
||||||
{
|
|
||||||
/// \fn CAMFImporter_NodeElement_Mesh(CAMFImporter_NodeElement* pParent)
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
CAMFImporter_NodeElement_Mesh(CAMFImporter_NodeElement* pParent)
|
CAMFImporter_NodeElement_Mesh(CAMFImporter_NodeElement* pParent)
|
||||||
: CAMFImporter_NodeElement(ENET_Mesh, pParent)
|
: CAMFImporter_NodeElement(ENET_Mesh, pParent)
|
||||||
{}
|
{}
|
||||||
|
};
|
||||||
};// struct CAMFImporter_NodeElement_Mesh
|
|
||||||
|
|
||||||
/// \struct CAMFImporter_NodeElement_Vertex
|
/// \struct CAMFImporter_NodeElement_Vertex
|
||||||
/// Structure that define vertex node.
|
/// Structure that define vertex node.
|
||||||
struct CAMFImporter_NodeElement_Vertex : public CAMFImporter_NodeElement
|
struct CAMFImporter_NodeElement_Vertex : public CAMFImporter_NodeElement {
|
||||||
{
|
|
||||||
/// \fn CAMFImporter_NodeElement_Vertex(CAMFImporter_NodeElement* pParent)
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
CAMFImporter_NodeElement_Vertex(CAMFImporter_NodeElement* pParent)
|
CAMFImporter_NodeElement_Vertex(CAMFImporter_NodeElement* pParent)
|
||||||
: CAMFImporter_NodeElement(ENET_Vertex, pParent)
|
: CAMFImporter_NodeElement(ENET_Vertex, pParent)
|
||||||
{}
|
{}
|
||||||
|
};
|
||||||
};// struct CAMFImporter_NodeElement_Vertex
|
|
||||||
|
|
||||||
/// \struct CAMFImporter_NodeElement_Edge
|
/// \struct CAMFImporter_NodeElement_Edge
|
||||||
/// Structure that define edge node.
|
/// Structure that define edge node.
|
||||||
struct CAMFImporter_NodeElement_Edge : public CAMFImporter_NodeElement
|
struct CAMFImporter_NodeElement_Edge : public CAMFImporter_NodeElement {
|
||||||
{
|
|
||||||
/// \fn CAMFImporter_NodeElement_Edge(CAMFImporter_NodeElement* pParent)
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
CAMFImporter_NodeElement_Edge(CAMFImporter_NodeElement* pParent)
|
CAMFImporter_NodeElement_Edge(CAMFImporter_NodeElement* pParent)
|
||||||
: CAMFImporter_NodeElement(ENET_Edge, pParent)
|
: CAMFImporter_NodeElement(ENET_Edge, pParent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
};// struct CAMFImporter_NodeElement_Vertex
|
};
|
||||||
|
|
||||||
/// \struct CAMFImporter_NodeElement_Vertices
|
/// \struct CAMFImporter_NodeElement_Vertices
|
||||||
/// Structure that define vertices node.
|
/// Structure that define vertices node.
|
||||||
struct CAMFImporter_NodeElement_Vertices : public CAMFImporter_NodeElement
|
struct CAMFImporter_NodeElement_Vertices : public CAMFImporter_NodeElement {
|
||||||
{
|
|
||||||
/// \fn CAMFImporter_NodeElement_Vertices(CAMFImporter_NodeElement* pParent)
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
CAMFImporter_NodeElement_Vertices(CAMFImporter_NodeElement* pParent)
|
CAMFImporter_NodeElement_Vertices(CAMFImporter_NodeElement* pParent)
|
||||||
: CAMFImporter_NodeElement(ENET_Vertices, pParent)
|
: CAMFImporter_NodeElement(ENET_Vertices, pParent)
|
||||||
{}
|
{}
|
||||||
|
};
|
||||||
};// struct CAMFImporter_NodeElement_Vertices
|
|
||||||
|
|
||||||
/// \struct CAMFImporter_NodeElement_Volume
|
/// \struct CAMFImporter_NodeElement_Volume
|
||||||
/// Structure that define volume node.
|
/// Structure that define volume node.
|
||||||
struct CAMFImporter_NodeElement_Volume : public CAMFImporter_NodeElement
|
struct CAMFImporter_NodeElement_Volume : public CAMFImporter_NodeElement {
|
||||||
{
|
|
||||||
/****************** Variables ******************/
|
|
||||||
|
|
||||||
std::string MaterialID;///< Which material to use.
|
std::string MaterialID;///< Which material to use.
|
||||||
std::string Type;///< What this volume describes can be “region” or “support”. If none specified, “object” is assumed.
|
std::string Type;///< What this volume describes can be “region” or “support”. If none specified, “object” is assumed.
|
||||||
|
|
||||||
/****************** Functions ******************/
|
|
||||||
|
|
||||||
/// \fn CAMFImporter_NodeElement_Volume(CAMFImporter_NodeElement* pParent)
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
CAMFImporter_NodeElement_Volume(CAMFImporter_NodeElement* pParent)
|
CAMFImporter_NodeElement_Volume(CAMFImporter_NodeElement* pParent)
|
||||||
: CAMFImporter_NodeElement(ENET_Volume, pParent)
|
: CAMFImporter_NodeElement(ENET_Volume, pParent)
|
||||||
{}
|
{}
|
||||||
|
};
|
||||||
};// struct CAMFImporter_NodeElement_Volume
|
|
||||||
|
|
||||||
/// \struct CAMFImporter_NodeElement_Coordinates
|
/// \struct CAMFImporter_NodeElement_Coordinates
|
||||||
/// Structure that define coordinates node.
|
/// Structure that define coordinates node.
|
||||||
struct CAMFImporter_NodeElement_Coordinates : public CAMFImporter_NodeElement
|
struct CAMFImporter_NodeElement_Coordinates : public CAMFImporter_NodeElement
|
||||||
{
|
{
|
||||||
/****************** Variables ******************/
|
|
||||||
|
|
||||||
aiVector3D Coordinate;///< Coordinate.
|
aiVector3D Coordinate;///< Coordinate.
|
||||||
|
|
||||||
/****************** Functions ******************/
|
|
||||||
|
|
||||||
/// \fn CAMFImporter_NodeElement_Coordinates(CAMFImporter_NodeElement* pParent)
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
CAMFImporter_NodeElement_Coordinates(CAMFImporter_NodeElement* pParent)
|
CAMFImporter_NodeElement_Coordinates(CAMFImporter_NodeElement* pParent)
|
||||||
: CAMFImporter_NodeElement(ENET_Coordinates, pParent)
|
: CAMFImporter_NodeElement(ENET_Coordinates, pParent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
};// struct CAMFImporter_NodeElement_Coordinates
|
};
|
||||||
|
|
||||||
/// \struct CAMFImporter_NodeElement_TexMap
|
/// \struct CAMFImporter_NodeElement_TexMap
|
||||||
/// Structure that define texture coordinates node.
|
/// Structure that define texture coordinates node.
|
||||||
struct CAMFImporter_NodeElement_TexMap : public CAMFImporter_NodeElement
|
struct CAMFImporter_NodeElement_TexMap : public CAMFImporter_NodeElement {
|
||||||
{
|
|
||||||
/****************** Variables ******************/
|
|
||||||
|
|
||||||
aiVector3D TextureCoordinate[3];///< Texture coordinates.
|
aiVector3D TextureCoordinate[3];///< Texture coordinates.
|
||||||
std::string TextureID_R;///< Texture ID for red color component.
|
std::string TextureID_R;///< Texture ID for red color component.
|
||||||
std::string TextureID_G;///< Texture ID for green color component.
|
std::string TextureID_G;///< Texture ID for green color component.
|
||||||
std::string TextureID_B;///< Texture ID for blue color component.
|
std::string TextureID_B;///< Texture ID for blue color component.
|
||||||
std::string TextureID_A;///< Texture ID for alpha color component.
|
std::string TextureID_A;///< Texture ID for alpha color component.
|
||||||
|
|
||||||
/****************** Functions ******************/
|
|
||||||
|
|
||||||
/// \fn CAMFImporter_NodeElement_TexMap(CAMFImporter_NodeElement* pParent)
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
CAMFImporter_NodeElement_TexMap(CAMFImporter_NodeElement* pParent)
|
CAMFImporter_NodeElement_TexMap(CAMFImporter_NodeElement* pParent)
|
||||||
: CAMFImporter_NodeElement(ENET_TexMap, pParent)
|
: CAMFImporter_NodeElement(ENET_TexMap, pParent)
|
||||||
{}
|
, TextureCoordinate{}
|
||||||
|
, TextureID_R()
|
||||||
};// struct CAMFImporter_NodeElement_TexMap
|
, TextureID_G()
|
||||||
|
, TextureID_B()
|
||||||
|
, TextureID_A() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// \struct CAMFImporter_NodeElement_Triangle
|
/// \struct CAMFImporter_NodeElement_Triangle
|
||||||
/// Structure that define triangle node.
|
/// Structure that define triangle node.
|
||||||
struct CAMFImporter_NodeElement_Triangle : public CAMFImporter_NodeElement
|
struct CAMFImporter_NodeElement_Triangle : public CAMFImporter_NodeElement {
|
||||||
{
|
|
||||||
/****************** Variables ******************/
|
|
||||||
|
|
||||||
size_t V[3];///< Triangle vertices.
|
size_t V[3];///< Triangle vertices.
|
||||||
|
|
||||||
/****************** Functions ******************/
|
|
||||||
|
|
||||||
/// \fn CAMFImporter_NodeElement_Triangle(CAMFImporter_NodeElement* pParent)
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
CAMFImporter_NodeElement_Triangle(CAMFImporter_NodeElement* pParent)
|
CAMFImporter_NodeElement_Triangle(CAMFImporter_NodeElement* pParent)
|
||||||
: CAMFImporter_NodeElement(ENET_Triangle, pParent)
|
: CAMFImporter_NodeElement(ENET_Triangle, pParent) {
|
||||||
{}
|
// empty
|
||||||
|
}
|
||||||
};// struct CAMFImporter_NodeElement_Triangle
|
};
|
||||||
|
|
||||||
/// Structure that define texture node.
|
/// Structure that define texture node.
|
||||||
struct CAMFImporter_NodeElement_Texture : public CAMFImporter_NodeElement {
|
struct CAMFImporter_NodeElement_Texture : public CAMFImporter_NodeElement {
|
||||||
|
@ -396,6 +335,6 @@ struct CAMFImporter_NodeElement_Texture : public CAMFImporter_NodeElement {
|
||||||
, Tiled( false ){
|
, Tiled( false ){
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
};// struct CAMFImporter_NodeElement_Texture
|
};
|
||||||
|
|
||||||
#endif // INCLUDED_AI_AMF_IMPORTER_NODE_H
|
#endif // INCLUDED_AI_AMF_IMPORTER_NODE_H
|
||||||
|
|
111
code/ASEParser.h
111
code/ASEParser.h
|
@ -71,21 +71,20 @@ struct Material : public D3DS::Material
|
||||||
//! Default constructor has been deleted
|
//! Default constructor has been deleted
|
||||||
Material() = delete;
|
Material() = delete;
|
||||||
|
|
||||||
|
|
||||||
//! Constructor with explicit name
|
//! Constructor with explicit name
|
||||||
explicit Material(const std::string &name)
|
explicit Material(const std::string &name)
|
||||||
: D3DS::Material(name)
|
: D3DS::Material(name)
|
||||||
, pcInstance(NULL)
|
, pcInstance(NULL)
|
||||||
, bNeed (false)
|
, bNeed (false) {
|
||||||
{}
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
Material(const Material &other) = default;
|
Material(const Material &other) = default;
|
||||||
Material &operator=(const Material &other) = default;
|
Material &operator=(const Material &other) = default;
|
||||||
|
|
||||||
|
|
||||||
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
|
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
|
||||||
Material(Material &&other)
|
Material(Material &&other) AI_NO_EXCEPT
|
||||||
: D3DS::Material(std::move(other))
|
: D3DS::Material(std::move(other))
|
||||||
, avSubMaterials(std::move(other.avSubMaterials))
|
, avSubMaterials(std::move(other.avSubMaterials))
|
||||||
, pcInstance(std::move(other.pcInstance))
|
, pcInstance(std::move(other.pcInstance))
|
||||||
|
@ -95,7 +94,7 @@ struct Material : public D3DS::Material
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Material &operator=(Material &&other) {
|
Material &operator=(Material &&other) AI_NO_EXCEPT {
|
||||||
if (this == &other) {
|
if (this == &other) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -127,19 +126,12 @@ struct Material : public D3DS::Material
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Helper structure to represent an ASE file face */
|
/** Helper structure to represent an ASE file face */
|
||||||
struct Face : public FaceWithSmoothingGroup
|
struct Face : public FaceWithSmoothingGroup {
|
||||||
{
|
|
||||||
//! Default constructor. Initializes everything with 0
|
//! Default constructor. Initializes everything with 0
|
||||||
Face()
|
Face() AI_NO_EXCEPT
|
||||||
{
|
: iMaterial(DEFAULT_MATINDEX)
|
||||||
mColorIndices[0] = mColorIndices[1] = mColorIndices[2] = 0;
|
, iFace(0) {
|
||||||
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
|
// empty
|
||||||
{
|
|
||||||
amUVIndices[i][0] = amUVIndices[i][1] = amUVIndices[i][2] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
iMaterial = DEFAULT_MATINDEX;
|
|
||||||
iFace = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! special value to indicate that no material index has
|
//! special value to indicate that no material index has
|
||||||
|
@ -147,8 +139,6 @@ struct Face : public FaceWithSmoothingGroup
|
||||||
//! will replace this value later.
|
//! will replace this value later.
|
||||||
static const unsigned int DEFAULT_MATINDEX = 0xFFFFFFFF;
|
static const unsigned int DEFAULT_MATINDEX = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//! Indices into each list of texture coordinates
|
//! Indices into each list of texture coordinates
|
||||||
unsigned int amUVIndices[AI_MAX_NUMBER_OF_TEXTURECOORDS][3];
|
unsigned int amUVIndices[AI_MAX_NUMBER_OF_TEXTURECOORDS][3];
|
||||||
|
|
||||||
|
@ -166,15 +156,15 @@ struct Face : public FaceWithSmoothingGroup
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Helper structure to represent an ASE file bone */
|
/** Helper structure to represent an ASE file bone */
|
||||||
struct Bone
|
struct Bone {
|
||||||
{
|
|
||||||
//! Constructor
|
//! Constructor
|
||||||
Bone() = delete;
|
Bone() = delete;
|
||||||
|
|
||||||
//! Construction from an existing name
|
//! Construction from an existing name
|
||||||
explicit Bone( const std::string& name)
|
explicit Bone( const std::string& name)
|
||||||
: mName (name)
|
: mName(name) {
|
||||||
{}
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
//! Name of the bone
|
//! Name of the bone
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
@ -182,29 +172,22 @@ struct Bone
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Helper structure to represent an ASE file bone vertex */
|
/** Helper structure to represent an ASE file bone vertex */
|
||||||
struct BoneVertex
|
struct BoneVertex {
|
||||||
{
|
|
||||||
//! Bone and corresponding vertex weight.
|
//! Bone and corresponding vertex weight.
|
||||||
//! -1 for unrequired bones ....
|
//! -1 for unrequired bones ....
|
||||||
std::vector<std::pair<int,float> > mBoneWeights;
|
std::vector<std::pair<int,float> > mBoneWeights;
|
||||||
|
|
||||||
//! Position of the bone vertex.
|
|
||||||
//! MUST be identical to the vertex position
|
|
||||||
//aiVector3D mPosition;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Helper structure to represent an ASE file animation */
|
/** Helper structure to represent an ASE file animation */
|
||||||
struct Animation
|
struct Animation {
|
||||||
{
|
enum Type {
|
||||||
enum Type
|
|
||||||
{
|
|
||||||
TRACK = 0x0,
|
TRACK = 0x0,
|
||||||
BEZIER = 0x1,
|
BEZIER = 0x1,
|
||||||
TCB = 0x2
|
TCB = 0x2
|
||||||
} mRotationType, mScalingType, mPositionType;
|
} mRotationType, mScalingType, mPositionType;
|
||||||
|
|
||||||
Animation()
|
Animation() AI_NO_EXCEPT
|
||||||
: mRotationType (TRACK)
|
: mRotationType (TRACK)
|
||||||
, mScalingType (TRACK)
|
, mScalingType (TRACK)
|
||||||
, mPositionType (TRACK)
|
, mPositionType (TRACK)
|
||||||
|
@ -218,20 +201,17 @@ struct Animation
|
||||||
|
|
||||||
//! List of track scaling keyframes
|
//! List of track scaling keyframes
|
||||||
std::vector< aiVectorKey > akeyScaling;
|
std::vector< aiVectorKey > akeyScaling;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Helper structure to represent the inheritance information of an ASE node */
|
/** Helper structure to represent the inheritance information of an ASE node */
|
||||||
struct InheritanceInfo
|
struct InheritanceInfo {
|
||||||
{
|
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
InheritanceInfo()
|
InheritanceInfo() AI_NO_EXCEPT {
|
||||||
{
|
for ( size_t i=0; i<3; ++i ) {
|
||||||
// set the inheritance flag for all axes by default to true
|
|
||||||
for (unsigned int i = 0; i < 3;++i)
|
|
||||||
abInheritPosition[i] = abInheritRotation[i] = abInheritScaling[i] = true;
|
abInheritPosition[i] = abInheritRotation[i] = abInheritScaling[i] = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//! Inherit the parent's position?, axis order is x,y,z
|
//! Inherit the parent's position?, axis order is x,y,z
|
||||||
bool abInheritPosition[3];
|
bool abInheritPosition[3];
|
||||||
|
@ -245,17 +225,19 @@ struct InheritanceInfo
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Represents an ASE file node. Base class for mesh, light and cameras */
|
/** Represents an ASE file node. Base class for mesh, light and cameras */
|
||||||
struct BaseNode
|
struct BaseNode {
|
||||||
{
|
enum Type {
|
||||||
enum Type {Light, Camera, Mesh, Dummy} mType;
|
Light,
|
||||||
|
Camera,
|
||||||
|
Mesh,
|
||||||
|
Dummy
|
||||||
|
} mType;
|
||||||
|
|
||||||
//! Construction from an existing name
|
//! Construction from an existing name
|
||||||
BaseNode(Type _mType, const std::string &name)
|
BaseNode(Type _mType, const std::string &name)
|
||||||
: mType (_mType)
|
: mType (_mType)
|
||||||
, mName (name)
|
, mName (name)
|
||||||
, mProcessed (false)
|
, mProcessed (false) {
|
||||||
{
|
|
||||||
// Set mTargetPosition to qnan
|
// Set mTargetPosition to qnan
|
||||||
const ai_real qnan = get_qnan();
|
const ai_real qnan = get_qnan();
|
||||||
mTargetPosition.x = qnan;
|
mTargetPosition.x = qnan;
|
||||||
|
@ -291,23 +273,22 @@ struct BaseNode
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Helper structure to represent an ASE file mesh */
|
/** Helper structure to represent an ASE file mesh */
|
||||||
struct Mesh : public MeshWithSmoothingGroups<ASE::Face>, public BaseNode
|
struct Mesh : public MeshWithSmoothingGroups<ASE::Face>, public BaseNode {
|
||||||
{
|
|
||||||
//! Default constructor has been deleted
|
//! Default constructor has been deleted
|
||||||
Mesh() = delete;
|
Mesh() = delete;
|
||||||
|
|
||||||
|
|
||||||
//! Construction from an existing name
|
//! Construction from an existing name
|
||||||
explicit Mesh(const std::string &name)
|
explicit Mesh(const std::string &name)
|
||||||
: BaseNode( BaseNode::Mesh, name )
|
: BaseNode( BaseNode::Mesh, name )
|
||||||
|
, mVertexColors()
|
||||||
|
, mBoneVertices()
|
||||||
|
, mBones()
|
||||||
, iMaterialIndex(Face::DEFAULT_MATINDEX)
|
, iMaterialIndex(Face::DEFAULT_MATINDEX)
|
||||||
, bSkip (false)
|
, bSkip (false) {
|
||||||
{
|
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) {
|
||||||
// use 2 texture vertex components by default
|
|
||||||
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
|
|
||||||
this->mNumUVComponents[c] = 2;
|
this->mNumUVComponents[c] = 2;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//! List of all texture coordinate sets
|
//! List of all texture coordinate sets
|
||||||
std::vector<aiVector3D> amTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
|
std::vector<aiVector3D> amTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
|
||||||
|
@ -396,12 +377,11 @@ struct Camera : public BaseNode
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Helper structure to represent an ASE helper object (dummy) */
|
/** Helper structure to represent an ASE helper object (dummy) */
|
||||||
struct Dummy : public BaseNode
|
struct Dummy : public BaseNode {
|
||||||
{
|
|
||||||
//! Constructor
|
//! Constructor
|
||||||
Dummy()
|
Dummy() AI_NO_EXCEPT
|
||||||
: BaseNode (BaseNode::Dummy, "DUMMY")
|
: BaseNode (BaseNode::Dummy, "DUMMY") {
|
||||||
{
|
// empty
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -416,12 +396,11 @@ struct Dummy : public BaseNode
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
/** \brief Class to parse ASE files
|
/** \brief Class to parse ASE files
|
||||||
*/
|
*/
|
||||||
class Parser
|
class Parser {
|
||||||
{
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Parser() AI_NO_EXCEPT {
|
||||||
Parser() {}
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -62,33 +62,30 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
using namespace Assimp;
|
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
size_t Write(IOStream * stream, const T& v)
|
size_t Write(IOStream * stream, const T& v) {
|
||||||
{
|
|
||||||
return stream->Write( &v, sizeof(T), 1 );
|
return stream->Write( &v, sizeof(T), 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Serialize an aiString
|
// Serialize an aiString
|
||||||
template <>
|
template <>
|
||||||
inline size_t Write<aiString>(IOStream * stream, const aiString& s)
|
inline
|
||||||
{
|
size_t Write<aiString>(IOStream * stream, const aiString& s) {
|
||||||
const size_t s2 = (uint32_t)s.length;
|
const size_t s2 = (uint32_t)s.length;
|
||||||
stream->Write(&s,4,1);
|
stream->Write(&s,4,1);
|
||||||
stream->Write(s.data,s2,1);
|
stream->Write(s.data,s2,1);
|
||||||
|
|
||||||
return s2+4;
|
return s2+4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Serialize an unsigned int as uint32_t
|
// Serialize an unsigned int as uint32_t
|
||||||
template <>
|
template <>
|
||||||
inline size_t Write<unsigned int>(IOStream * stream, const unsigned int& w)
|
inline
|
||||||
{
|
size_t Write<unsigned int>(IOStream * stream, const unsigned int& w) {
|
||||||
const uint32_t t = (uint32_t)w;
|
const uint32_t t = (uint32_t)w;
|
||||||
if (w > t) {
|
if (w > t) {
|
||||||
// this shouldn't happen, integers in Assimp data structures never exceed 2^32
|
// this shouldn't happen, integers in Assimp data structures never exceed 2^32
|
||||||
|
@ -96,114 +93,123 @@ inline size_t Write<unsigned int>(IOStream * stream, const unsigned int& w)
|
||||||
}
|
}
|
||||||
|
|
||||||
stream->Write(&t,4,1);
|
stream->Write(&t,4,1);
|
||||||
|
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Serialize an unsigned int as uint16_t
|
// Serialize an unsigned int as uint16_t
|
||||||
template <>
|
template <>
|
||||||
inline size_t Write<uint16_t>(IOStream * stream, const uint16_t& w)
|
inline
|
||||||
{
|
size_t Write<uint16_t>(IOStream * stream, const uint16_t& w) {
|
||||||
static_assert(sizeof(uint16_t)==2, "sizeof(uint16_t)==2");
|
static_assert(sizeof(uint16_t)==2, "sizeof(uint16_t)==2");
|
||||||
stream->Write(&w,2,1);
|
stream->Write(&w,2,1);
|
||||||
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Serialize a float
|
// Serialize a float
|
||||||
template <>
|
template <>
|
||||||
inline size_t Write<float>(IOStream * stream, const float& f)
|
inline
|
||||||
{
|
size_t Write<float>(IOStream * stream, const float& f) {
|
||||||
static_assert(sizeof(float)==4, "sizeof(float)==4");
|
static_assert(sizeof(float)==4, "sizeof(float)==4");
|
||||||
stream->Write(&f,4,1);
|
stream->Write(&f,4,1);
|
||||||
|
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Serialize a double
|
// Serialize a double
|
||||||
template <>
|
template <>
|
||||||
inline size_t Write<double>(IOStream * stream, const double& f)
|
inline
|
||||||
{
|
size_t Write<double>(IOStream * stream, const double& f) {
|
||||||
static_assert(sizeof(double)==8, "sizeof(double)==8");
|
static_assert(sizeof(double)==8, "sizeof(double)==8");
|
||||||
stream->Write(&f,8,1);
|
stream->Write(&f,8,1);
|
||||||
|
|
||||||
return 8;
|
return 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Serialize a vec3
|
// Serialize a vec3
|
||||||
template <>
|
template <>
|
||||||
inline size_t Write<aiVector3D>(IOStream * stream, const aiVector3D& v)
|
inline
|
||||||
{
|
size_t Write<aiVector3D>(IOStream * stream, const aiVector3D& v) {
|
||||||
size_t t = Write<float>(stream,v.x);
|
size_t t = Write<float>(stream,v.x);
|
||||||
t += Write<float>(stream,v.y);
|
t += Write<float>(stream,v.y);
|
||||||
t += Write<float>(stream,v.z);
|
t += Write<float>(stream,v.z);
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Serialize a color value
|
// Serialize a color value
|
||||||
template <>
|
template <>
|
||||||
inline size_t Write<aiColor3D>(IOStream * stream, const aiColor3D& v)
|
inline
|
||||||
{
|
size_t Write<aiColor3D>(IOStream * stream, const aiColor3D& v) {
|
||||||
size_t t = Write<float>(stream,v.r);
|
size_t t = Write<float>(stream,v.r);
|
||||||
t += Write<float>(stream,v.g);
|
t += Write<float>(stream,v.g);
|
||||||
t += Write<float>(stream,v.b);
|
t += Write<float>(stream,v.b);
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Serialize a color value
|
// Serialize a color value
|
||||||
template <>
|
template <>
|
||||||
inline size_t Write<aiColor4D>(IOStream * stream, const aiColor4D& v)
|
inline
|
||||||
{
|
size_t Write<aiColor4D>(IOStream * stream, const aiColor4D& v) {
|
||||||
size_t t = Write<float>(stream,v.r);
|
size_t t = Write<float>(stream,v.r);
|
||||||
t += Write<float>(stream,v.g);
|
t += Write<float>(stream,v.g);
|
||||||
t += Write<float>(stream,v.b);
|
t += Write<float>(stream,v.b);
|
||||||
t += Write<float>(stream,v.a);
|
t += Write<float>(stream,v.a);
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Serialize a quaternion
|
// Serialize a quaternion
|
||||||
template <>
|
template <>
|
||||||
inline size_t Write<aiQuaternion>(IOStream * stream, const aiQuaternion& v)
|
inline
|
||||||
{
|
size_t Write<aiQuaternion>(IOStream * stream, const aiQuaternion& v) {
|
||||||
size_t t = Write<float>(stream,v.w);
|
size_t t = Write<float>(stream,v.w);
|
||||||
t += Write<float>(stream,v.x);
|
t += Write<float>(stream,v.x);
|
||||||
t += Write<float>(stream,v.y);
|
t += Write<float>(stream,v.y);
|
||||||
t += Write<float>(stream,v.z);
|
t += Write<float>(stream,v.z);
|
||||||
ai_assert(t == 16);
|
ai_assert(t == 16);
|
||||||
|
|
||||||
return 16;
|
return 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Serialize a vertex weight
|
// Serialize a vertex weight
|
||||||
template <>
|
template <>
|
||||||
inline size_t Write<aiVertexWeight>(IOStream * stream, const aiVertexWeight& v)
|
inline
|
||||||
{
|
size_t Write<aiVertexWeight>(IOStream * stream, const aiVertexWeight& v) {
|
||||||
size_t t = Write<unsigned int>(stream,v.mVertexId);
|
size_t t = Write<unsigned int>(stream,v.mVertexId);
|
||||||
|
|
||||||
return t+Write<float>(stream,v.mWeight);
|
return t+Write<float>(stream,v.mWeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Serialize a mat4x4
|
// Serialize a mat4x4
|
||||||
template <>
|
template <>
|
||||||
inline size_t Write<aiMatrix4x4>(IOStream * stream, const aiMatrix4x4& m)
|
inline
|
||||||
{
|
size_t Write<aiMatrix4x4>(IOStream * stream, const aiMatrix4x4& m) {
|
||||||
for (unsigned int i = 0; i < 4;++i) {
|
for (unsigned int i = 0; i < 4;++i) {
|
||||||
for (unsigned int i2 = 0; i2 < 4;++i2) {
|
for (unsigned int i2 = 0; i2 < 4;++i2) {
|
||||||
Write<float>(stream,m[i][i2]);
|
Write<float>(stream,m[i][i2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 64;
|
return 64;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Serialize an aiVectorKey
|
// Serialize an aiVectorKey
|
||||||
template <>
|
template <>
|
||||||
inline size_t Write<aiVectorKey>(IOStream * stream, const aiVectorKey& v)
|
inline
|
||||||
{
|
size_t Write<aiVectorKey>(IOStream * stream, const aiVectorKey& v) {
|
||||||
const size_t t = Write<double>(stream,v.mTime);
|
const size_t t = Write<double>(stream,v.mTime);
|
||||||
return t + Write<aiVector3D>(stream,v.mValue);
|
return t + Write<aiVector3D>(stream,v.mValue);
|
||||||
}
|
}
|
||||||
|
@ -211,15 +217,15 @@ inline size_t Write<aiVectorKey>(IOStream * stream, const aiVectorKey& v)
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Serialize an aiQuatKey
|
// Serialize an aiQuatKey
|
||||||
template <>
|
template <>
|
||||||
inline size_t Write<aiQuatKey>(IOStream * stream, const aiQuatKey& v)
|
inline
|
||||||
{
|
size_t Write<aiQuatKey>(IOStream * stream, const aiQuatKey& v) {
|
||||||
const size_t t = Write<double>(stream,v.mTime);
|
const size_t t = Write<double>(stream,v.mTime);
|
||||||
return t + Write<aiQuaternion>(stream,v.mValue);
|
return t + Write<aiQuaternion>(stream,v.mValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size)
|
inline
|
||||||
{
|
size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) {
|
||||||
T minc, maxc;
|
T minc, maxc;
|
||||||
ArrayBounds(in,size,minc,maxc);
|
ArrayBounds(in,size,minc,maxc);
|
||||||
|
|
||||||
|
@ -230,10 +236,11 @@ inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size)
|
||||||
// We use this to write out non-byte arrays so that we write using the specializations.
|
// We use this to write out non-byte arrays so that we write using the specializations.
|
||||||
// This way we avoid writing out extra bytes that potentially come from struct alignment.
|
// This way we avoid writing out extra bytes that potentially come from struct alignment.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
|
inline
|
||||||
{
|
size_t WriteArray(IOStream * stream, const T* in, unsigned int size) {
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
for (unsigned int i=0; i<size; i++) n += Write<T>(stream,in[i]);
|
for (unsigned int i=0; i<size; i++) n += Write<T>(stream,in[i]);
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,19 +300,25 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
|
||||||
void * GetBufferPointer() { return buffer; }
|
void * GetBufferPointer() { return buffer; }
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
virtual size_t Read(void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) { return 0; }
|
virtual size_t Read(void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) {
|
||||||
virtual aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) { return aiReturn_FAILURE; }
|
return 0;
|
||||||
virtual size_t Tell() const { return cursor; }
|
}
|
||||||
virtual void Flush() { }
|
virtual aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) {
|
||||||
|
return aiReturn_FAILURE;
|
||||||
|
}
|
||||||
|
virtual size_t Tell() const {
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
virtual void Flush() {
|
||||||
|
// not implemented
|
||||||
|
}
|
||||||
|
|
||||||
virtual size_t FileSize() const
|
virtual size_t FileSize() const {
|
||||||
{
|
|
||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
virtual size_t Write(const void* pvBuffer, size_t pSize, size_t pCount)
|
virtual size_t Write(const void* pvBuffer, size_t pSize, size_t pCount) {
|
||||||
{
|
|
||||||
pSize *= pCount;
|
pSize *= pCount;
|
||||||
if (cursor + pSize > cur_size) {
|
if (cursor + pSize > cur_size) {
|
||||||
Grow(cursor + pSize);
|
Grow(cursor + pSize);
|
||||||
|
@ -332,7 +345,6 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
|
||||||
bool compressed;
|
bool compressed;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
void WriteBinaryNode( IOStream * container, const aiNode* node)
|
void WriteBinaryNode( IOStream * container, const aiNode* node)
|
||||||
{
|
{
|
||||||
|
@ -812,8 +824,7 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
|
void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/) {
|
||||||
{
|
|
||||||
AssbinExport exporter;
|
AssbinExport exporter;
|
||||||
exporter.WriteBinaryDump( pFile, pIOSystem, pScene );
|
exporter.WriteBinaryDump( pFile, pIOSystem, pScene );
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef AI_ASSBINEXPORTER_H_INC
|
#ifndef AI_ASSBINEXPORTER_H_INC
|
||||||
#define AI_ASSBINEXPORTER_H_INC
|
#define AI_ASSBINEXPORTER_H_INC
|
||||||
|
|
||||||
// nothing really needed here - reserved for future use like properties
|
#include <assimp/defs.h>
|
||||||
|
|
||||||
#endif
|
// nothing really needed here - reserved for future use like properties
|
||||||
|
namespace Assimp {
|
||||||
|
|
||||||
|
void ASSIMP_API ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // AI_ASSBINEXPORTER_H_INC
|
||||||
|
|
|
@ -79,16 +79,17 @@ static const aiImporterDesc desc = {
|
||||||
"assbin"
|
"assbin"
|
||||||
};
|
};
|
||||||
|
|
||||||
const aiImporterDesc* AssbinImporter::GetInfo() const
|
// -----------------------------------------------------------------------------------
|
||||||
{
|
const aiImporterDesc* AssbinImporter::GetInfo() const {
|
||||||
return &desc;
|
return &desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/ ) const
|
// -----------------------------------------------------------------------------------
|
||||||
{
|
bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/ ) const {
|
||||||
IOStream * in = pIOHandler->Open(pFile);
|
IOStream * in = pIOHandler->Open(pFile);
|
||||||
if (!in)
|
if (nullptr == in) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
char s[32];
|
char s[32];
|
||||||
in->Read( s, sizeof(char), 32 );
|
in->Read( s, sizeof(char), 32 );
|
||||||
|
@ -98,17 +99,17 @@ bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bo
|
||||||
return strncmp( s, "ASSIMP.binary-dump.", 19 ) == 0;
|
return strncmp( s, "ASSIMP.binary-dump.", 19 ) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T Read(IOStream * stream)
|
T Read(IOStream * stream) {
|
||||||
{
|
|
||||||
T t;
|
T t;
|
||||||
stream->Read( &t, sizeof(T), 1 );
|
stream->Read( &t, sizeof(T), 1 );
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------
|
||||||
template <>
|
template <>
|
||||||
aiVector3D Read<aiVector3D>(IOStream * stream)
|
aiVector3D Read<aiVector3D>(IOStream * stream) {
|
||||||
{
|
|
||||||
aiVector3D v;
|
aiVector3D v;
|
||||||
v.x = Read<float>(stream);
|
v.x = Read<float>(stream);
|
||||||
v.y = Read<float>(stream);
|
v.y = Read<float>(stream);
|
||||||
|
@ -116,9 +117,9 @@ aiVector3D Read<aiVector3D>(IOStream * stream)
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------
|
||||||
template <>
|
template <>
|
||||||
aiColor4D Read<aiColor4D>(IOStream * stream)
|
aiColor4D Read<aiColor4D>(IOStream * stream) {
|
||||||
{
|
|
||||||
aiColor4D c;
|
aiColor4D c;
|
||||||
c.r = Read<float>(stream);
|
c.r = Read<float>(stream);
|
||||||
c.g = Read<float>(stream);
|
c.g = Read<float>(stream);
|
||||||
|
@ -127,9 +128,9 @@ aiColor4D Read<aiColor4D>(IOStream * stream)
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------
|
||||||
template <>
|
template <>
|
||||||
aiQuaternion Read<aiQuaternion>(IOStream * stream)
|
aiQuaternion Read<aiQuaternion>(IOStream * stream) {
|
||||||
{
|
|
||||||
aiQuaternion v;
|
aiQuaternion v;
|
||||||
v.w = Read<float>(stream);
|
v.w = Read<float>(stream);
|
||||||
v.x = Read<float>(stream);
|
v.x = Read<float>(stream);
|
||||||
|
@ -138,9 +139,9 @@ aiQuaternion Read<aiQuaternion>(IOStream * stream)
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------
|
||||||
template <>
|
template <>
|
||||||
aiString Read<aiString>(IOStream * stream)
|
aiString Read<aiString>(IOStream * stream) {
|
||||||
{
|
|
||||||
aiString s;
|
aiString s;
|
||||||
stream->Read(&s.length,4,1);
|
stream->Read(&s.length,4,1);
|
||||||
stream->Read(s.data,s.length,1);
|
stream->Read(s.data,s.length,1);
|
||||||
|
@ -148,18 +149,18 @@ aiString Read<aiString>(IOStream * stream)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------
|
||||||
template <>
|
template <>
|
||||||
aiVertexWeight Read<aiVertexWeight>(IOStream * stream)
|
aiVertexWeight Read<aiVertexWeight>(IOStream * stream) {
|
||||||
{
|
|
||||||
aiVertexWeight w;
|
aiVertexWeight w;
|
||||||
w.mVertexId = Read<unsigned int>(stream);
|
w.mVertexId = Read<unsigned int>(stream);
|
||||||
w.mWeight = Read<float>(stream);
|
w.mWeight = Read<float>(stream);
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------
|
||||||
template <>
|
template <>
|
||||||
aiMatrix4x4 Read<aiMatrix4x4>(IOStream * stream)
|
aiMatrix4x4 Read<aiMatrix4x4>(IOStream * stream) {
|
||||||
{
|
|
||||||
aiMatrix4x4 m;
|
aiMatrix4x4 m;
|
||||||
for (unsigned int i = 0; i < 4;++i) {
|
for (unsigned int i = 0; i < 4;++i) {
|
||||||
for (unsigned int i2 = 0; i2 < 4;++i2) {
|
for (unsigned int i2 = 0; i2 < 4;++i2) {
|
||||||
|
@ -169,36 +170,43 @@ aiMatrix4x4 Read<aiMatrix4x4>(IOStream * stream)
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------
|
||||||
template <>
|
template <>
|
||||||
aiVectorKey Read<aiVectorKey>(IOStream * stream)
|
aiVectorKey Read<aiVectorKey>(IOStream * stream) {
|
||||||
{
|
|
||||||
aiVectorKey v;
|
aiVectorKey v;
|
||||||
v.mTime = Read<double>(stream);
|
v.mTime = Read<double>(stream);
|
||||||
v.mValue = Read<aiVector3D>(stream);
|
v.mValue = Read<aiVector3D>(stream);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------
|
||||||
template <>
|
template <>
|
||||||
aiQuatKey Read<aiQuatKey>(IOStream * stream)
|
aiQuatKey Read<aiQuatKey>(IOStream * stream) {
|
||||||
{
|
|
||||||
aiQuatKey v;
|
aiQuatKey v;
|
||||||
v.mTime = Read<double>(stream);
|
v.mTime = Read<double>(stream);
|
||||||
v.mValue = Read<aiQuaternion>(stream);
|
v.mValue = Read<aiQuaternion>(stream);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void ReadArray(IOStream * stream, T * out, unsigned int size)
|
void ReadArray( IOStream *stream, T * out, unsigned int size) {
|
||||||
{
|
ai_assert( nullptr != stream );
|
||||||
for (unsigned int i=0; i<size; i++) out[i] = Read<T>(stream);
|
ai_assert( nullptr != out );
|
||||||
|
|
||||||
|
for (unsigned int i=0; i<size; i++) {
|
||||||
|
out[i] = Read<T>(stream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> void ReadBounds( IOStream * stream, T* /*p*/, unsigned int n )
|
// -----------------------------------------------------------------------------------
|
||||||
{
|
template <typename T>
|
||||||
|
void ReadBounds( IOStream * stream, T* /*p*/, unsigned int n ) {
|
||||||
// not sure what to do here, the data isn't really useful.
|
// not sure what to do here, the data isn't really useful.
|
||||||
stream->Seek( sizeof(T) * n, aiOrigin_CUR );
|
stream->Seek( sizeof(T) * n, aiOrigin_CUR );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------
|
||||||
void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node, aiNode* parent ) {
|
void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node, aiNode* parent ) {
|
||||||
uint32_t chunkID = Read<uint32_t>(stream);
|
uint32_t chunkID = Read<uint32_t>(stream);
|
||||||
(void)(chunkID);
|
(void)(chunkID);
|
||||||
|
@ -273,8 +281,7 @@ void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node, aiNode* p
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b )
|
void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b ) {
|
||||||
{
|
|
||||||
uint32_t chunkID = Read<uint32_t>(stream);
|
uint32_t chunkID = Read<uint32_t>(stream);
|
||||||
(void)(chunkID);
|
(void)(chunkID);
|
||||||
ai_assert(chunkID == ASSBIN_CHUNK_AIBONE);
|
ai_assert(chunkID == ASSBIN_CHUNK_AIBONE);
|
||||||
|
@ -286,20 +293,22 @@ void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b )
|
||||||
|
|
||||||
// for the moment we write dumb min/max values for the bones, too.
|
// for the moment we write dumb min/max values for the bones, too.
|
||||||
// maybe I'll add a better, hash-like solution later
|
// maybe I'll add a better, hash-like solution later
|
||||||
if (shortened)
|
if (shortened) {
|
||||||
{
|
|
||||||
ReadBounds(stream,b->mWeights,b->mNumWeights);
|
ReadBounds(stream,b->mWeights,b->mNumWeights);
|
||||||
} // else write as usual
|
} else {
|
||||||
else
|
// else write as usual
|
||||||
{
|
|
||||||
b->mWeights = new aiVertexWeight[b->mNumWeights];
|
b->mWeights = new aiVertexWeight[b->mNumWeights];
|
||||||
ReadArray<aiVertexWeight>(stream,b->mWeights,b->mNumWeights);
|
ReadArray<aiVertexWeight>(stream,b->mWeights,b->mNumWeights);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------
|
||||||
|
static bool fitsIntoUI16(unsigned int mNumVertices) {
|
||||||
|
return ( mNumVertices < (1u<<16) );
|
||||||
|
}
|
||||||
|
|
||||||
void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
|
// -----------------------------------------------------------------------------------
|
||||||
{
|
void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) {
|
||||||
uint32_t chunkID = Read<uint32_t>(stream);
|
uint32_t chunkID = Read<uint32_t>(stream);
|
||||||
(void)(chunkID);
|
(void)(chunkID);
|
||||||
ai_assert(chunkID == ASSBIN_CHUNK_AIMESH);
|
ai_assert(chunkID == ASSBIN_CHUNK_AIMESH);
|
||||||
|
@ -314,70 +323,61 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
|
||||||
// first of all, write bits for all existent vertex components
|
// first of all, write bits for all existent vertex components
|
||||||
unsigned int c = Read<unsigned int>(stream);
|
unsigned int c = Read<unsigned int>(stream);
|
||||||
|
|
||||||
if (c & ASSBIN_MESH_HAS_POSITIONS)
|
if (c & ASSBIN_MESH_HAS_POSITIONS) {
|
||||||
{
|
|
||||||
if (shortened) {
|
if (shortened) {
|
||||||
ReadBounds(stream,mesh->mVertices,mesh->mNumVertices);
|
ReadBounds(stream,mesh->mVertices,mesh->mNumVertices);
|
||||||
} // else write as usual
|
} else {
|
||||||
else
|
// else write as usual
|
||||||
{
|
|
||||||
mesh->mVertices = new aiVector3D[mesh->mNumVertices];
|
mesh->mVertices = new aiVector3D[mesh->mNumVertices];
|
||||||
ReadArray<aiVector3D>(stream,mesh->mVertices,mesh->mNumVertices);
|
ReadArray<aiVector3D>(stream,mesh->mVertices,mesh->mNumVertices);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (c & ASSBIN_MESH_HAS_NORMALS)
|
if (c & ASSBIN_MESH_HAS_NORMALS) {
|
||||||
{
|
|
||||||
if (shortened) {
|
if (shortened) {
|
||||||
ReadBounds(stream,mesh->mNormals,mesh->mNumVertices);
|
ReadBounds(stream,mesh->mNormals,mesh->mNumVertices);
|
||||||
} // else write as usual
|
} else {
|
||||||
else
|
// else write as usual
|
||||||
{
|
|
||||||
mesh->mNormals = new aiVector3D[mesh->mNumVertices];
|
mesh->mNormals = new aiVector3D[mesh->mNumVertices];
|
||||||
ReadArray<aiVector3D>(stream,mesh->mNormals,mesh->mNumVertices);
|
ReadArray<aiVector3D>(stream,mesh->mNormals,mesh->mNumVertices);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (c & ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS)
|
if (c & ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS) {
|
||||||
{
|
|
||||||
if (shortened) {
|
if (shortened) {
|
||||||
ReadBounds(stream,mesh->mTangents,mesh->mNumVertices);
|
ReadBounds(stream,mesh->mTangents,mesh->mNumVertices);
|
||||||
ReadBounds(stream,mesh->mBitangents,mesh->mNumVertices);
|
ReadBounds(stream,mesh->mBitangents,mesh->mNumVertices);
|
||||||
} // else write as usual
|
} else {
|
||||||
else
|
// else write as usual
|
||||||
{
|
|
||||||
mesh->mTangents = new aiVector3D[mesh->mNumVertices];
|
mesh->mTangents = new aiVector3D[mesh->mNumVertices];
|
||||||
ReadArray<aiVector3D>(stream,mesh->mTangents,mesh->mNumVertices);
|
ReadArray<aiVector3D>(stream,mesh->mTangents,mesh->mNumVertices);
|
||||||
mesh->mBitangents = new aiVector3D[mesh->mNumVertices];
|
mesh->mBitangents = new aiVector3D[mesh->mNumVertices];
|
||||||
ReadArray<aiVector3D>(stream,mesh->mBitangents,mesh->mNumVertices);
|
ReadArray<aiVector3D>(stream,mesh->mBitangents,mesh->mNumVertices);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n)
|
for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) {
|
||||||
{
|
if (!(c & ASSBIN_MESH_HAS_COLOR(n))) {
|
||||||
if (!(c & ASSBIN_MESH_HAS_COLOR(n)))
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (shortened)
|
if (shortened) {
|
||||||
{
|
|
||||||
ReadBounds(stream,mesh->mColors[n],mesh->mNumVertices);
|
ReadBounds(stream,mesh->mColors[n],mesh->mNumVertices);
|
||||||
} // else write as usual
|
} else {
|
||||||
else
|
// else write as usual
|
||||||
{
|
|
||||||
mesh->mColors[n] = new aiColor4D[mesh->mNumVertices];
|
mesh->mColors[n] = new aiColor4D[mesh->mNumVertices];
|
||||||
ReadArray<aiColor4D>(stream,mesh->mColors[n],mesh->mNumVertices);
|
ReadArray<aiColor4D>(stream,mesh->mColors[n],mesh->mNumVertices);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n)
|
for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) {
|
||||||
{
|
if (!(c & ASSBIN_MESH_HAS_TEXCOORD(n))) {
|
||||||
if (!(c & ASSBIN_MESH_HAS_TEXCOORD(n)))
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// write number of UV components
|
// write number of UV components
|
||||||
mesh->mNumUVComponents[n] = Read<unsigned int>(stream);
|
mesh->mNumUVComponents[n] = Read<unsigned int>(stream);
|
||||||
|
|
||||||
if (shortened) {
|
if (shortened) {
|
||||||
ReadBounds(stream,mesh->mTextureCoords[n],mesh->mNumVertices);
|
ReadBounds(stream,mesh->mTextureCoords[n],mesh->mNumVertices);
|
||||||
} // else write as usual
|
} else {
|
||||||
else
|
// else write as usual
|
||||||
{
|
|
||||||
mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices];
|
mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices];
|
||||||
ReadArray<aiVector3D>(stream,mesh->mTextureCoords[n],mesh->mNumVertices);
|
ReadArray<aiVector3D>(stream,mesh->mTextureCoords[n],mesh->mNumVertices);
|
||||||
}
|
}
|
||||||
|
@ -389,9 +389,8 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
|
||||||
// using Assimp's standard hashing function.
|
// using Assimp's standard hashing function.
|
||||||
if (shortened) {
|
if (shortened) {
|
||||||
Read<unsigned int>(stream);
|
Read<unsigned int>(stream);
|
||||||
}
|
} else {
|
||||||
else // else write as usual
|
// else write as usual
|
||||||
{
|
|
||||||
// if there are less than 2^16 vertices, we can simply use 16 bit integers ...
|
// if there are less than 2^16 vertices, we can simply use 16 bit integers ...
|
||||||
mesh->mFaces = new aiFace[mesh->mNumFaces];
|
mesh->mFaces = new aiFace[mesh->mNumFaces];
|
||||||
for (unsigned int i = 0; i < mesh->mNumFaces;++i) {
|
for (unsigned int i = 0; i < mesh->mNumFaces;++i) {
|
||||||
|
@ -402,12 +401,10 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
|
||||||
f.mIndices = new unsigned int[f.mNumIndices];
|
f.mIndices = new unsigned int[f.mNumIndices];
|
||||||
|
|
||||||
for (unsigned int a = 0; a < f.mNumIndices;++a) {
|
for (unsigned int a = 0; a < f.mNumIndices;++a) {
|
||||||
if (mesh->mNumVertices < (1u<<16))
|
// Check if unsigned short ( 16 bit ) are big enought for the indices
|
||||||
{
|
if ( fitsIntoUI16( mesh->mNumVertices ) ) {
|
||||||
f.mIndices[a] = Read<uint16_t>(stream);
|
f.mIndices[a] = Read<uint16_t>(stream);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
f.mIndices[a] = Read<unsigned int>(stream);
|
f.mIndices[a] = Read<unsigned int>(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -424,8 +421,8 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop)
|
// -----------------------------------------------------------------------------------
|
||||||
{
|
void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop) {
|
||||||
uint32_t chunkID = Read<uint32_t>(stream);
|
uint32_t chunkID = Read<uint32_t>(stream);
|
||||||
(void)(chunkID);
|
(void)(chunkID);
|
||||||
ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIALPROPERTY);
|
ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIALPROPERTY);
|
||||||
|
@ -442,8 +439,7 @@ void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialPro
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat)
|
void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat) {
|
||||||
{
|
|
||||||
uint32_t chunkID = Read<uint32_t>(stream);
|
uint32_t chunkID = Read<uint32_t>(stream);
|
||||||
(void)(chunkID);
|
(void)(chunkID);
|
||||||
ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIAL);
|
ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIAL);
|
||||||
|
@ -465,8 +461,7 @@ void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat)
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
|
void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) {
|
||||||
{
|
|
||||||
uint32_t chunkID = Read<uint32_t>(stream);
|
uint32_t chunkID = Read<uint32_t>(stream);
|
||||||
(void)(chunkID);
|
(void)(chunkID);
|
||||||
ai_assert(chunkID == ASSBIN_CHUNK_AINODEANIM);
|
ai_assert(chunkID == ASSBIN_CHUNK_AINODEANIM);
|
||||||
|
@ -493,9 +488,8 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
|
||||||
if (shortened) {
|
if (shortened) {
|
||||||
ReadBounds(stream,nd->mRotationKeys,nd->mNumRotationKeys);
|
ReadBounds(stream,nd->mRotationKeys,nd->mNumRotationKeys);
|
||||||
|
|
||||||
} // else write as usual
|
} else {
|
||||||
else
|
// else write as usual
|
||||||
{
|
|
||||||
nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys];
|
nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys];
|
||||||
ReadArray<aiQuatKey>(stream,nd->mRotationKeys,nd->mNumRotationKeys);
|
ReadArray<aiQuatKey>(stream,nd->mRotationKeys,nd->mNumRotationKeys);
|
||||||
}
|
}
|
||||||
|
@ -504,19 +498,16 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
|
||||||
if (shortened) {
|
if (shortened) {
|
||||||
ReadBounds(stream,nd->mScalingKeys,nd->mNumScalingKeys);
|
ReadBounds(stream,nd->mScalingKeys,nd->mNumScalingKeys);
|
||||||
|
|
||||||
} // else write as usual
|
} else {
|
||||||
else
|
// else write as usual
|
||||||
{
|
|
||||||
nd->mScalingKeys = new aiVectorKey[nd->mNumScalingKeys];
|
nd->mScalingKeys = new aiVectorKey[nd->mNumScalingKeys];
|
||||||
ReadArray<aiVectorKey>(stream,nd->mScalingKeys,nd->mNumScalingKeys);
|
ReadArray<aiVectorKey>(stream,nd->mScalingKeys,nd->mNumScalingKeys);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim )
|
void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim ) {
|
||||||
{
|
|
||||||
uint32_t chunkID = Read<uint32_t>(stream);
|
uint32_t chunkID = Read<uint32_t>(stream);
|
||||||
(void)(chunkID);
|
(void)(chunkID);
|
||||||
ai_assert(chunkID == ASSBIN_CHUNK_AIANIMATION);
|
ai_assert(chunkID == ASSBIN_CHUNK_AIANIMATION);
|
||||||
|
@ -527,8 +518,7 @@ void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim )
|
||||||
anim->mTicksPerSecond = Read<double> (stream);
|
anim->mTicksPerSecond = Read<double> (stream);
|
||||||
anim->mNumChannels = Read<unsigned int>(stream);
|
anim->mNumChannels = Read<unsigned int>(stream);
|
||||||
|
|
||||||
if (anim->mNumChannels)
|
if (anim->mNumChannels) {
|
||||||
{
|
|
||||||
anim->mChannels = new aiNodeAnim*[ anim->mNumChannels ];
|
anim->mChannels = new aiNodeAnim*[ anim->mNumChannels ];
|
||||||
for (unsigned int a = 0; a < anim->mNumChannels;++a) {
|
for (unsigned int a = 0; a < anim->mNumChannels;++a) {
|
||||||
anim->mChannels[a] = new aiNodeAnim();
|
anim->mChannels[a] = new aiNodeAnim();
|
||||||
|
@ -537,8 +527,8 @@ void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex)
|
// -----------------------------------------------------------------------------------
|
||||||
{
|
void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex) {
|
||||||
uint32_t chunkID = Read<uint32_t>(stream);
|
uint32_t chunkID = Read<uint32_t>(stream);
|
||||||
(void)(chunkID);
|
(void)(chunkID);
|
||||||
ai_assert(chunkID == ASSBIN_CHUNK_AITEXTURE);
|
ai_assert(chunkID == ASSBIN_CHUNK_AITEXTURE);
|
||||||
|
@ -552,18 +542,15 @@ void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex)
|
||||||
if (!tex->mHeight) {
|
if (!tex->mHeight) {
|
||||||
tex->pcData = new aiTexel[ tex->mWidth ];
|
tex->pcData = new aiTexel[ tex->mWidth ];
|
||||||
stream->Read(tex->pcData,1,tex->mWidth);
|
stream->Read(tex->pcData,1,tex->mWidth);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
tex->pcData = new aiTexel[ tex->mWidth*tex->mHeight ];
|
tex->pcData = new aiTexel[ tex->mWidth*tex->mHeight ];
|
||||||
stream->Read(tex->pcData,1,tex->mWidth*tex->mHeight*4);
|
stream->Read(tex->pcData,1,tex->mWidth*tex->mHeight*4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l )
|
void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l ) {
|
||||||
{
|
|
||||||
uint32_t chunkID = Read<uint32_t>(stream);
|
uint32_t chunkID = Read<uint32_t>(stream);
|
||||||
(void)(chunkID);
|
(void)(chunkID);
|
||||||
ai_assert(chunkID == ASSBIN_CHUNK_AILIGHT);
|
ai_assert(chunkID == ASSBIN_CHUNK_AILIGHT);
|
||||||
|
@ -586,12 +573,10 @@ void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l )
|
||||||
l->mAngleInnerCone = Read<float>(stream);
|
l->mAngleInnerCone = Read<float>(stream);
|
||||||
l->mAngleOuterCone = Read<float>(stream);
|
l->mAngleOuterCone = Read<float>(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam )
|
void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam ) {
|
||||||
{
|
|
||||||
uint32_t chunkID = Read<uint32_t>(stream);
|
uint32_t chunkID = Read<uint32_t>(stream);
|
||||||
(void)(chunkID);
|
(void)(chunkID);
|
||||||
ai_assert(chunkID == ASSBIN_CHUNK_AICAMERA);
|
ai_assert(chunkID == ASSBIN_CHUNK_AICAMERA);
|
||||||
|
@ -607,8 +592,8 @@ void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam )
|
||||||
cam->mAspect = Read<float>(stream);
|
cam->mAspect = Read<float>(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
|
// -----------------------------------------------------------------------------------
|
||||||
{
|
void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) {
|
||||||
uint32_t chunkID = Read<uint32_t>(stream);
|
uint32_t chunkID = Read<uint32_t>(stream);
|
||||||
(void)(chunkID);
|
(void)(chunkID);
|
||||||
ai_assert(chunkID == ASSBIN_CHUNK_AISCENE);
|
ai_assert(chunkID == ASSBIN_CHUNK_AISCENE);
|
||||||
|
@ -623,12 +608,11 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
|
||||||
scene->mNumCameras = Read<unsigned int>(stream);
|
scene->mNumCameras = Read<unsigned int>(stream);
|
||||||
|
|
||||||
// Read node graph
|
// Read node graph
|
||||||
scene->mRootNode = new aiNode[1];
|
//scene->mRootNode = new aiNode[1];
|
||||||
ReadBinaryNode( stream, &scene->mRootNode, (aiNode*)NULL );
|
ReadBinaryNode( stream, &scene->mRootNode, (aiNode*)NULL );
|
||||||
|
|
||||||
// Read all meshes
|
// Read all meshes
|
||||||
if (scene->mNumMeshes)
|
if (scene->mNumMeshes) {
|
||||||
{
|
|
||||||
scene->mMeshes = new aiMesh*[scene->mNumMeshes];
|
scene->mMeshes = new aiMesh*[scene->mNumMeshes];
|
||||||
for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
|
for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
|
||||||
scene->mMeshes[i] = new aiMesh();
|
scene->mMeshes[i] = new aiMesh();
|
||||||
|
@ -637,8 +621,7 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read materials
|
// Read materials
|
||||||
if (scene->mNumMaterials)
|
if (scene->mNumMaterials) {
|
||||||
{
|
|
||||||
scene->mMaterials = new aiMaterial*[scene->mNumMaterials];
|
scene->mMaterials = new aiMaterial*[scene->mNumMaterials];
|
||||||
for (unsigned int i = 0; i< scene->mNumMaterials; ++i) {
|
for (unsigned int i = 0; i< scene->mNumMaterials; ++i) {
|
||||||
scene->mMaterials[i] = new aiMaterial();
|
scene->mMaterials[i] = new aiMaterial();
|
||||||
|
@ -647,8 +630,7 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read all animations
|
// Read all animations
|
||||||
if (scene->mNumAnimations)
|
if (scene->mNumAnimations) {
|
||||||
{
|
|
||||||
scene->mAnimations = new aiAnimation*[scene->mNumAnimations];
|
scene->mAnimations = new aiAnimation*[scene->mNumAnimations];
|
||||||
for (unsigned int i = 0; i < scene->mNumAnimations;++i) {
|
for (unsigned int i = 0; i < scene->mNumAnimations;++i) {
|
||||||
scene->mAnimations[i] = new aiAnimation();
|
scene->mAnimations[i] = new aiAnimation();
|
||||||
|
@ -657,8 +639,7 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read all textures
|
// Read all textures
|
||||||
if (scene->mNumTextures)
|
if (scene->mNumTextures) {
|
||||||
{
|
|
||||||
scene->mTextures = new aiTexture*[scene->mNumTextures];
|
scene->mTextures = new aiTexture*[scene->mNumTextures];
|
||||||
for (unsigned int i = 0; i < scene->mNumTextures;++i) {
|
for (unsigned int i = 0; i < scene->mNumTextures;++i) {
|
||||||
scene->mTextures[i] = new aiTexture();
|
scene->mTextures[i] = new aiTexture();
|
||||||
|
@ -667,8 +648,7 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read lights
|
// Read lights
|
||||||
if (scene->mNumLights)
|
if (scene->mNumLights) {
|
||||||
{
|
|
||||||
scene->mLights = new aiLight*[scene->mNumLights];
|
scene->mLights = new aiLight*[scene->mNumLights];
|
||||||
for (unsigned int i = 0; i < scene->mNumLights;++i) {
|
for (unsigned int i = 0; i < scene->mNumLights;++i) {
|
||||||
scene->mLights[i] = new aiLight();
|
scene->mLights[i] = new aiLight();
|
||||||
|
@ -677,8 +657,7 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read cameras
|
// Read cameras
|
||||||
if (scene->mNumCameras)
|
if (scene->mNumCameras) {
|
||||||
{
|
|
||||||
scene->mCameras = new aiCamera*[scene->mNumCameras];
|
scene->mCameras = new aiCamera*[scene->mNumCameras];
|
||||||
for (unsigned int i = 0; i < scene->mNumCameras;++i) {
|
for (unsigned int i = 0; i < scene->mNumCameras;++i) {
|
||||||
scene->mCameras[i] = new aiCamera();
|
scene->mCameras[i] = new aiCamera();
|
||||||
|
@ -688,16 +667,22 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler )
|
// -----------------------------------------------------------------------------------
|
||||||
{
|
void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ) {
|
||||||
IOStream * stream = pIOHandler->Open(pFile,"rb");
|
IOStream * stream = pIOHandler->Open(pFile,"rb");
|
||||||
if (!stream)
|
if (nullptr == stream) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
stream->Seek( 44, aiOrigin_CUR ); // signature
|
// signature
|
||||||
|
stream->Seek( 44, aiOrigin_CUR );
|
||||||
|
|
||||||
|
unsigned int versionMajor = Read<unsigned int>(stream);
|
||||||
|
unsigned int versionMinor = Read<unsigned int>(stream);
|
||||||
|
if (versionMinor != ASSBIN_VERSION_MINOR || versionMajor != ASSBIN_VERSION_MAJOR) {
|
||||||
|
throw DeadlyImportError( "Invalid version, data format not compatible!" );
|
||||||
|
}
|
||||||
|
|
||||||
/*unsigned int versionMajor =*/ Read<unsigned int>(stream);
|
|
||||||
/*unsigned int versionMinor =*/ Read<unsigned int>(stream);
|
|
||||||
/*unsigned int versionRevision =*/ Read<unsigned int>(stream);
|
/*unsigned int versionRevision =*/ Read<unsigned int>(stream);
|
||||||
/*unsigned int compileFlags =*/ Read<unsigned int>(stream);
|
/*unsigned int compileFlags =*/ Read<unsigned int>(stream);
|
||||||
|
|
||||||
|
@ -711,8 +696,7 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
stream->Seek( 128, aiOrigin_CUR ); // options
|
stream->Seek( 128, aiOrigin_CUR ); // options
|
||||||
stream->Seek( 64, aiOrigin_CUR ); // padding
|
stream->Seek( 64, aiOrigin_CUR ); // padding
|
||||||
|
|
||||||
if (compressed)
|
if (compressed) {
|
||||||
{
|
|
||||||
uLongf uncompressedSize = Read<uint32_t>(stream);
|
uLongf uncompressedSize = Read<uint32_t>(stream);
|
||||||
uLongf compressedSize = static_cast<uLongf>(stream->FileSize() - stream->Tell());
|
uLongf compressedSize = static_cast<uLongf>(stream->FileSize() - stream->Tell());
|
||||||
|
|
||||||
|
@ -729,9 +713,7 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
|
|
||||||
delete[] uncompressedData;
|
delete[] uncompressedData;
|
||||||
delete[] compressedData;
|
delete[] compressedData;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
ReadBinaryScene(stream,pScene);
|
ReadBinaryScene(stream,pScene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,7 @@ public:
|
||||||
aiScene* pScene,
|
aiScene* pScene,
|
||||||
IOSystem* pIOHandler
|
IOSystem* pIOHandler
|
||||||
);
|
);
|
||||||
|
void ReadHeader();
|
||||||
void ReadBinaryScene( IOStream * stream, aiScene* pScene );
|
void ReadBinaryScene( IOStream * stream, aiScene* pScene );
|
||||||
void ReadBinaryNode( IOStream * stream, aiNode** mRootNode, aiNode* parent );
|
void ReadBinaryNode( IOStream * stream, aiNode** mRootNode, aiNode* parent );
|
||||||
void ReadBinaryMesh( IOStream * stream, aiMesh* mesh );
|
void ReadBinaryMesh( IOStream * stream, aiMesh* mesh );
|
||||||
|
|
|
@ -54,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/importerdesc.h>
|
#include <assimp/importerdesc.h>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
using namespace Assimp::Formatter;
|
using namespace Assimp::Formatter;
|
||||||
|
@ -461,6 +462,13 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
|
||||||
aiNodeAnim* nodeAnim = new aiNodeAnim;
|
aiNodeAnim* nodeAnim = new aiNodeAnim;
|
||||||
anim->mChannels[a] = nodeAnim;
|
anim->mChannels[a] = nodeAnim;
|
||||||
nodeAnim->mNodeName.Set( nodeName);
|
nodeAnim->mNodeName.Set( nodeName);
|
||||||
|
std::map<BVHLoader::ChannelType, int> channelMap;
|
||||||
|
|
||||||
|
//Build map of channels
|
||||||
|
for (unsigned int channel = 0; channel < node.mChannels.size(); ++channel)
|
||||||
|
{
|
||||||
|
channelMap[node.mChannels[channel]] = channel;
|
||||||
|
}
|
||||||
|
|
||||||
// translational part, if given
|
// translational part, if given
|
||||||
if( node.mChannels.size() == 6)
|
if( node.mChannels.size() == 6)
|
||||||
|
@ -472,15 +480,31 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
|
||||||
{
|
{
|
||||||
poskey->mTime = double( fr);
|
poskey->mTime = double( fr);
|
||||||
|
|
||||||
// Now compute all translations in the right order
|
// Now compute all translations
|
||||||
for( unsigned int channel = 0; channel < 3; ++channel)
|
for(BVHLoader::ChannelType channel = Channel_PositionX; channel <= Channel_PositionZ; channel = (BVHLoader::ChannelType)(channel +1))
|
||||||
{
|
{
|
||||||
switch( node.mChannels[channel])
|
//Find channel in node
|
||||||
{
|
std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel);
|
||||||
case Channel_PositionX: poskey->mValue.x = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
|
|
||||||
case Channel_PositionY: poskey->mValue.y = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
|
if (mapIter == channelMap.end())
|
||||||
case Channel_PositionZ: poskey->mValue.z = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
|
throw DeadlyImportError("Missing position channel in node " + nodeName);
|
||||||
default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName );
|
else {
|
||||||
|
int channelIdx = mapIter->second;
|
||||||
|
switch (channel) {
|
||||||
|
case Channel_PositionX:
|
||||||
|
poskey->mValue.x = node.mChannelValues[fr * node.mChannels.size() + channelIdx];
|
||||||
|
break;
|
||||||
|
case Channel_PositionY:
|
||||||
|
poskey->mValue.y = node.mChannelValues[fr * node.mChannels.size() + channelIdx];
|
||||||
|
break;
|
||||||
|
case Channel_PositionZ:
|
||||||
|
poskey->mValue.z = node.mChannelValues[fr * node.mChannels.size() + channelIdx];
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++poskey;
|
++poskey;
|
||||||
|
@ -497,12 +521,6 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
|
||||||
|
|
||||||
// rotation part. Always present. First find value offsets
|
// rotation part. Always present. First find value offsets
|
||||||
{
|
{
|
||||||
unsigned int rotOffset = 0;
|
|
||||||
if( node.mChannels.size() == 6)
|
|
||||||
{
|
|
||||||
// Offset all further calculations
|
|
||||||
rotOffset = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then create the number of rotation keys
|
// Then create the number of rotation keys
|
||||||
nodeAnim->mNumRotationKeys = mAnimNumFrames;
|
nodeAnim->mNumRotationKeys = mAnimNumFrames;
|
||||||
|
@ -512,19 +530,32 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
|
||||||
{
|
{
|
||||||
aiMatrix4x4 temp;
|
aiMatrix4x4 temp;
|
||||||
aiMatrix3x3 rotMatrix;
|
aiMatrix3x3 rotMatrix;
|
||||||
|
for (BVHLoader::ChannelType channel = Channel_RotationX; channel <= Channel_RotationZ; channel = (BVHLoader::ChannelType)(channel + 1))
|
||||||
for( unsigned int channel = 0; channel < 3; ++channel)
|
|
||||||
{
|
{
|
||||||
|
//Find channel in node
|
||||||
|
std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel);
|
||||||
|
|
||||||
|
if (mapIter == channelMap.end())
|
||||||
|
throw DeadlyImportError("Missing rotation channel in node " + nodeName);
|
||||||
|
else {
|
||||||
|
int channelIdx = mapIter->second;
|
||||||
// translate ZXY euler angels into a quaternion
|
// translate ZXY euler angels into a quaternion
|
||||||
const float angle = node.mChannelValues[fr * node.mChannels.size() + rotOffset + channel] * float( AI_MATH_PI) / 180.0f;
|
const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
|
||||||
|
|
||||||
// Compute rotation transformations in the right order
|
// Compute rotation transformations in the right order
|
||||||
switch (node.mChannels[rotOffset+channel])
|
switch (channel)
|
||||||
{
|
{
|
||||||
case Channel_RotationX: aiMatrix4x4::RotationX( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
|
case Channel_RotationX:
|
||||||
case Channel_RotationY: aiMatrix4x4::RotationY( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
|
aiMatrix4x4::RotationX(angle, temp); rotMatrix *= aiMatrix3x3(temp);
|
||||||
case Channel_RotationZ: aiMatrix4x4::RotationZ( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
|
break;
|
||||||
default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName );
|
case Channel_RotationY:
|
||||||
|
aiMatrix4x4::RotationY(angle, temp); rotMatrix *= aiMatrix3x3(temp);
|
||||||
|
break;
|
||||||
|
case Channel_RotationZ: aiMatrix4x4::RotationZ(angle, temp); rotMatrix *= aiMatrix3x3(temp);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assimp/BaseImporter.h>
|
#include <assimp/BaseImporter.h>
|
||||||
|
#include <assimp/ParsingUtils.h>
|
||||||
#include "FileSystemFilter.h"
|
#include "FileSystemFilter.h"
|
||||||
#include "Importer.h"
|
#include "Importer.h"
|
||||||
#include <assimp/ByteSwapper.h>
|
#include <assimp/ByteSwapper.h>
|
||||||
|
@ -53,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/Importer.hpp>
|
#include <assimp/Importer.hpp>
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
#include <assimp/importerdesc.h>
|
#include <assimp/importerdesc.h>
|
||||||
|
|
||||||
#include <ios>
|
#include <ios>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -63,7 +65,7 @@ using namespace Assimp;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
BaseImporter::BaseImporter()
|
BaseImporter::BaseImporter() AI_NO_EXCEPT
|
||||||
: m_progress() {
|
: m_progress() {
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
@ -143,7 +145,8 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions) {
|
||||||
const char** tokens,
|
const char** tokens,
|
||||||
unsigned int numTokens,
|
unsigned int numTokens,
|
||||||
unsigned int searchBytes /* = 200 */,
|
unsigned int searchBytes /* = 200 */,
|
||||||
bool tokensSol /* false */)
|
bool tokensSol /* false */,
|
||||||
|
bool noAlphaBeforeTokens /* false */)
|
||||||
{
|
{
|
||||||
ai_assert( nullptr != tokens );
|
ai_assert( nullptr != tokens );
|
||||||
ai_assert( 0 != numTokens );
|
ai_assert( 0 != numTokens );
|
||||||
|
@ -157,15 +160,14 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions) {
|
||||||
if (pStream.get() ) {
|
if (pStream.get() ) {
|
||||||
// read 200 characters from the file
|
// read 200 characters from the file
|
||||||
std::unique_ptr<char[]> _buffer (new char[searchBytes+1 /* for the '\0' */]);
|
std::unique_ptr<char[]> _buffer (new char[searchBytes+1 /* for the '\0' */]);
|
||||||
char* buffer = _buffer.get();
|
char *buffer( _buffer.get() );
|
||||||
|
const size_t read( pStream->Read(buffer,1,searchBytes) );
|
||||||
const size_t read = pStream->Read(buffer,1,searchBytes);
|
if( 0 == read ) {
|
||||||
if( !read ) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for( size_t i = 0; i < read; ++i ) {
|
for( size_t i = 0; i < read; ++i ) {
|
||||||
buffer[ i ] = ::tolower( buffer[ i ] );
|
buffer[ i ] = static_cast<char>( ::tolower( buffer[ i ] ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// It is not a proper handling of unicode files here ...
|
// It is not a proper handling of unicode files here ...
|
||||||
|
@ -186,13 +188,18 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions) {
|
||||||
token.clear();
|
token.clear();
|
||||||
const char *ptr( tokens[ i ] );
|
const char *ptr( tokens[ i ] );
|
||||||
for ( size_t tokIdx = 0; tokIdx < len; ++tokIdx ) {
|
for ( size_t tokIdx = 0; tokIdx < len; ++tokIdx ) {
|
||||||
token.push_back( tolower( *ptr ) );
|
token.push_back( static_cast<char>( tolower( *ptr ) ) );
|
||||||
++ptr;
|
++ptr;
|
||||||
}
|
}
|
||||||
const char* r = strstr( buffer, token.c_str() );
|
const char* r = strstr( buffer, token.c_str() );
|
||||||
if( !r ) {
|
if( !r ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// We need to make sure that we didn't accidentially identify the end of another token as our token,
|
||||||
|
// e.g. in a previous version the "gltf " present in some gltf files was detected as "f "
|
||||||
|
if (noAlphaBeforeTokens && (r != buffer && isalpha(r[-1]))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// We got a match, either we don't care where it is, or it happens to
|
// We got a match, either we don't care where it is, or it happens to
|
||||||
// be in the beginning of the file / line
|
// be in the beginning of the file / line
|
||||||
if (!tokensSol || r == buffer || r[-1] == '\r' || r[-1] == '\n') {
|
if (!tokensSol || r == buffer || r[-1] == '\r' || r[-1] == '\n') {
|
||||||
|
@ -234,16 +241,19 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions) {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Get file extension from path
|
// Get file extension from path
|
||||||
/*static*/ std::string BaseImporter::GetExtension (const std::string& pFile)
|
std::string BaseImporter::GetExtension( const std::string& file ) {
|
||||||
{
|
std::string::size_type pos = file.find_last_of('.');
|
||||||
std::string::size_type pos = pFile.find_last_of('.');
|
|
||||||
|
|
||||||
// no file extension at all
|
// no file extension at all
|
||||||
if( pos == std::string::npos)
|
if (pos == std::string::npos) {
|
||||||
return "";
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// thanks to Andy Maloney for the hint
|
||||||
|
std::string ret = file.substr( pos + 1 );
|
||||||
|
std::transform( ret.begin(), ret.end(), ret.begin(), ToLower<char>);
|
||||||
|
|
||||||
std::string ret = pFile.substr(pos+1);
|
|
||||||
std::transform(ret.begin(),ret.end(),ret.begin(),::tolower); // thanks to Andy Maloney for the hint
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ using namespace Assimp;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
BaseProcess::BaseProcess()
|
BaseProcess::BaseProcess() AI_NO_EXCEPT
|
||||||
: shared()
|
: shared()
|
||||||
, progress()
|
, progress()
|
||||||
{
|
{
|
||||||
|
|
|
@ -211,20 +211,16 @@ private:
|
||||||
* should be executed. If the function returns true, the class' Execute()
|
* should be executed. If the function returns true, the class' Execute()
|
||||||
* function is called subsequently.
|
* function is called subsequently.
|
||||||
*/
|
*/
|
||||||
class ASSIMP_API_WINONLY BaseProcess
|
class ASSIMP_API_WINONLY BaseProcess {
|
||||||
{
|
|
||||||
friend class Importer;
|
friend class Importer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Constructor to be privately used by Importer */
|
/** Constructor to be privately used by Importer */
|
||||||
BaseProcess();
|
BaseProcess() AI_NO_EXCEPT;
|
||||||
|
|
||||||
/** Destructor, private as well */
|
/** Destructor, private as well */
|
||||||
virtual ~BaseProcess();
|
virtual ~BaseProcess();
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the processing step is present in the given flag.
|
/** Returns whether the processing step is present in the given flag.
|
||||||
* @param pFlags The processing flags the importer was called with. A
|
* @param pFlags The processing flags the importer was called with. A
|
||||||
|
|
|
@ -0,0 +1,185 @@
|
||||||
|
#include "BlenderCustomData.h"
|
||||||
|
#include "BlenderDNA.h"
|
||||||
|
#include <array>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
namespace Blender {
|
||||||
|
/**
|
||||||
|
* @brief read/convert of Structure array to memory
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
bool read(const Structure &s, T *p, const size_t cnt, const FileDatabase &db) {
|
||||||
|
for (size_t i = 0; i < cnt; ++i) {
|
||||||
|
T read;
|
||||||
|
s.Convert(read, db);
|
||||||
|
*p = read;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief pointer to function read memory for n CustomData types
|
||||||
|
*/
|
||||||
|
typedef bool (*PRead)(ElemBase *pOut, const size_t cnt, const FileDatabase &db);
|
||||||
|
typedef ElemBase * (*PCreate)(const size_t cnt);
|
||||||
|
typedef void(*PDestroy)(ElemBase *);
|
||||||
|
|
||||||
|
#define IMPL_STRUCT_READ(ty) \
|
||||||
|
bool read##ty(ElemBase *v, const size_t cnt, const FileDatabase &db) { \
|
||||||
|
return read<ty>(db.dna[#ty], dynamic_cast<ty *>(v), cnt, db); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define IMPL_STRUCT_CREATE(ty) \
|
||||||
|
ElemBase *create##ty(const size_t cnt) { \
|
||||||
|
return new ty[cnt]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define IMPL_STRUCT_DESTROY(ty) \
|
||||||
|
void destroy##ty(ElemBase *pE) { \
|
||||||
|
ty *p = dynamic_cast<ty *>(pE); \
|
||||||
|
delete[]p; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief helper macro to define Structure functions
|
||||||
|
*/
|
||||||
|
#define IMPL_STRUCT(ty) \
|
||||||
|
IMPL_STRUCT_READ(ty) \
|
||||||
|
IMPL_STRUCT_CREATE(ty) \
|
||||||
|
IMPL_STRUCT_DESTROY(ty)
|
||||||
|
|
||||||
|
// supported structures for CustomData
|
||||||
|
IMPL_STRUCT(MVert)
|
||||||
|
IMPL_STRUCT(MEdge)
|
||||||
|
IMPL_STRUCT(MFace)
|
||||||
|
IMPL_STRUCT(MTFace)
|
||||||
|
IMPL_STRUCT(MTexPoly)
|
||||||
|
IMPL_STRUCT(MLoopUV)
|
||||||
|
IMPL_STRUCT(MLoopCol)
|
||||||
|
IMPL_STRUCT(MPoly)
|
||||||
|
IMPL_STRUCT(MLoop)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief describes the size of data and the read function to be used for single CustomerData.type
|
||||||
|
*/
|
||||||
|
struct CustomDataTypeDescription {
|
||||||
|
PRead Read; ///< function to read one CustomData type element
|
||||||
|
PCreate Create; ///< function to allocate n type elements
|
||||||
|
PDestroy Destroy;
|
||||||
|
|
||||||
|
CustomDataTypeDescription(PRead read, PCreate create, PDestroy destroy)
|
||||||
|
: Read(read)
|
||||||
|
, Create(create)
|
||||||
|
, Destroy(destroy)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief helper macro to define Structure type specific CustomDataTypeDescription
|
||||||
|
* @note IMPL_STRUCT_READ for same ty must be used earlier to implement the typespecific read function
|
||||||
|
*/
|
||||||
|
#define DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(ty) \
|
||||||
|
CustomDataTypeDescription{&read##ty, &create##ty, &destroy##ty}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief helper macro to define CustomDataTypeDescription for UNSUPPORTED type
|
||||||
|
*/
|
||||||
|
#define DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION \
|
||||||
|
CustomDataTypeDescription{nullptr, nullptr, nullptr}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief descriptors for data pointed to from CustomDataLayer.data
|
||||||
|
* @note some of the CustomData uses already well defined Structures
|
||||||
|
* other (like CD_ORCO, ...) uses arrays of rawtypes or even arrays of Structures
|
||||||
|
* use a special readfunction for that cases
|
||||||
|
*/
|
||||||
|
std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDescriptions = { {
|
||||||
|
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MVert),
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MEdge),
|
||||||
|
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MFace),
|
||||||
|
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MTFace),
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MTexPoly),
|
||||||
|
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MLoopUV),
|
||||||
|
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MLoopCol),
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MPoly),
|
||||||
|
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MLoop),
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION
|
||||||
|
}};
|
||||||
|
|
||||||
|
|
||||||
|
bool isValidCustomDataType(const int cdtype) {
|
||||||
|
return cdtype >= 0 && cdtype < CD_NUMTYPES;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool readCustomData(std::shared_ptr<ElemBase> &out, const int cdtype, const size_t cnt, const FileDatabase &db) {
|
||||||
|
if (!isValidCustomDataType(cdtype)) {
|
||||||
|
throw Error((Formatter::format(), "CustomData.type ", cdtype, " out of index"));
|
||||||
|
}
|
||||||
|
|
||||||
|
const CustomDataTypeDescription cdtd = customDataTypeDescriptions[cdtype];
|
||||||
|
if (cdtd.Read && cdtd.Create && cdtd.Destroy && cnt > 0) {
|
||||||
|
// allocate cnt elements and parse them from file
|
||||||
|
out.reset(cdtd.Create(cnt), cdtd.Destroy);
|
||||||
|
return cdtd.Read(out.get(), cnt, db);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<CustomDataLayer> getCustomDataLayer(const CustomData &customdata, const CustomDataType cdtype, const std::string &name) {
|
||||||
|
for (auto it = customdata.layers.begin(); it != customdata.layers.end(); ++it) {
|
||||||
|
if (it->get()->type == cdtype && name == it->get()->name) {
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ElemBase * getCustomDataLayerData(const CustomData &customdata, const CustomDataType cdtype, const std::string &name)
|
||||||
|
{
|
||||||
|
const std::shared_ptr<CustomDataLayer> pLayer = getCustomDataLayer(customdata, cdtype, name);
|
||||||
|
if (pLayer && pLayer->data) {
|
||||||
|
return pLayer->data.get();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "BlenderDNA.h"
|
||||||
|
#include "BlenderScene.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
namespace Blender {
|
||||||
|
/* CustomData.type from Blender (2.79b) */
|
||||||
|
enum CustomDataType {
|
||||||
|
CD_AUTO_FROM_NAME = -1,
|
||||||
|
CD_MVERT = 0,
|
||||||
|
#ifdef DNA_DEPRECATED
|
||||||
|
CD_MSTICKY = 1, /* DEPRECATED */
|
||||||
|
#endif
|
||||||
|
CD_MDEFORMVERT = 2,
|
||||||
|
CD_MEDGE = 3,
|
||||||
|
CD_MFACE = 4,
|
||||||
|
CD_MTFACE = 5,
|
||||||
|
CD_MCOL = 6,
|
||||||
|
CD_ORIGINDEX = 7,
|
||||||
|
CD_NORMAL = 8,
|
||||||
|
/* CD_POLYINDEX = 9, */
|
||||||
|
CD_PROP_FLT = 10,
|
||||||
|
CD_PROP_INT = 11,
|
||||||
|
CD_PROP_STR = 12,
|
||||||
|
CD_ORIGSPACE = 13, /* for modifier stack face location mapping */
|
||||||
|
CD_ORCO = 14,
|
||||||
|
CD_MTEXPOLY = 15,
|
||||||
|
CD_MLOOPUV = 16,
|
||||||
|
CD_MLOOPCOL = 17,
|
||||||
|
CD_TANGENT = 18,
|
||||||
|
CD_MDISPS = 19,
|
||||||
|
CD_PREVIEW_MCOL = 20, /* for displaying weightpaint colors */
|
||||||
|
/* CD_ID_MCOL = 21, */
|
||||||
|
CD_TEXTURE_MLOOPCOL = 22,
|
||||||
|
CD_CLOTH_ORCO = 23,
|
||||||
|
CD_RECAST = 24,
|
||||||
|
|
||||||
|
/* BMESH ONLY START */
|
||||||
|
CD_MPOLY = 25,
|
||||||
|
CD_MLOOP = 26,
|
||||||
|
CD_SHAPE_KEYINDEX = 27,
|
||||||
|
CD_SHAPEKEY = 28,
|
||||||
|
CD_BWEIGHT = 29,
|
||||||
|
CD_CREASE = 30,
|
||||||
|
CD_ORIGSPACE_MLOOP = 31,
|
||||||
|
CD_PREVIEW_MLOOPCOL = 32,
|
||||||
|
CD_BM_ELEM_PYPTR = 33,
|
||||||
|
/* BMESH ONLY END */
|
||||||
|
|
||||||
|
CD_PAINT_MASK = 34,
|
||||||
|
CD_GRID_PAINT_MASK = 35,
|
||||||
|
CD_MVERT_SKIN = 36,
|
||||||
|
CD_FREESTYLE_EDGE = 37,
|
||||||
|
CD_FREESTYLE_FACE = 38,
|
||||||
|
CD_MLOOPTANGENT = 39,
|
||||||
|
CD_TESSLOOPNORMAL = 40,
|
||||||
|
CD_CUSTOMLOOPNORMAL = 41,
|
||||||
|
|
||||||
|
CD_NUMTYPES = 42
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief check if given cdtype is valid (ie >= 0 and < CD_NUMTYPES)
|
||||||
|
* @param[in] cdtype to check
|
||||||
|
* @return true when valid
|
||||||
|
*/
|
||||||
|
bool isValidCustomDataType(const int cdtype);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief returns CustomDataLayer ptr for given cdtype and name
|
||||||
|
* @param[in] customdata CustomData to search for wanted layer
|
||||||
|
* @param[in] cdtype to search for
|
||||||
|
* @param[in] name to search for
|
||||||
|
* @return CustomDataLayer * or nullptr if not found
|
||||||
|
*/
|
||||||
|
std::shared_ptr<CustomDataLayer> getCustomDataLayer(const CustomData &customdata, CustomDataType cdtype, const std::string &name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief returns CustomDataLayer data ptr for given cdtype and name
|
||||||
|
* @param[in] customdata CustomData to search for wanted layer
|
||||||
|
* @param[in] cdtype to search for
|
||||||
|
* @param[in] name to search for
|
||||||
|
* @return * to struct data or nullptr if not found
|
||||||
|
*/
|
||||||
|
const ElemBase * getCustomDataLayerData(const CustomData &customdata, CustomDataType cdtype, const std::string &name);
|
||||||
|
}
|
||||||
|
}
|
|
@ -309,6 +309,28 @@ public:
|
||||||
void ReadField(T& out, const char* name,
|
void ReadField(T& out, const char* name,
|
||||||
const FileDatabase& db) const;
|
const FileDatabase& db) const;
|
||||||
|
|
||||||
|
// --------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief field parsing for dynamic vectors
|
||||||
|
* @param[in] out vector of struct to be filled
|
||||||
|
* @param[in] name of field
|
||||||
|
* @param[in] db to access the file, dna, ...
|
||||||
|
* @return true when read was successful
|
||||||
|
*/
|
||||||
|
template <int error_policy, template <typename> class TOUT, typename T>
|
||||||
|
bool ReadFieldPtrVector(vector<TOUT<T>>&out, const char* name, const FileDatabase& db) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief parses raw customdata
|
||||||
|
* @param[in] out shared_ptr to be filled
|
||||||
|
* @param[in] cdtype customdata type to read
|
||||||
|
* @param[in] name of field ptr
|
||||||
|
* @param[in] db to access the file, dna, ...
|
||||||
|
* @return true when read was successful
|
||||||
|
*/
|
||||||
|
template <int error_policy>
|
||||||
|
bool ReadCustomDataPtr(std::shared_ptr<ElemBase>&out, int cdtype, const char* name, const FileDatabase& db) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
|
@ -803,6 +825,17 @@ private:
|
||||||
FileDatabase& db;
|
FileDatabase& db;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief read CustomData's data to ptr to mem
|
||||||
|
* @param[out] out memory ptr to set
|
||||||
|
* @param[in] cdtype to read
|
||||||
|
* @param[in] cnt cnt of elements to read
|
||||||
|
* @param[in] db to read elements from
|
||||||
|
* @return true when ok
|
||||||
|
*/
|
||||||
|
bool readCustomData(std::shared_ptr<ElemBase> &out, int cdtype, size_t cnt, const FileDatabase &db);
|
||||||
|
|
||||||
|
|
||||||
} // end Blend
|
} // end Blend
|
||||||
} // end Assimp
|
} // end Assimp
|
||||||
|
|
||||||
|
|
|
@ -307,6 +307,108 @@ void Structure :: ReadField(T& out, const char* name, const FileDatabase& db) co
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
// field parsing for raw untyped data (like CustomDataLayer.data)
|
||||||
|
template <int error_policy>
|
||||||
|
bool Structure::ReadCustomDataPtr(std::shared_ptr<ElemBase>&out, int cdtype, const char* name, const FileDatabase& db) const {
|
||||||
|
|
||||||
|
const StreamReaderAny::pos old = db.reader->GetCurrentPos();
|
||||||
|
|
||||||
|
Pointer ptrval;
|
||||||
|
const Field* f;
|
||||||
|
try {
|
||||||
|
f = &(*this)[name];
|
||||||
|
|
||||||
|
// sanity check, should never happen if the genblenddna script is right
|
||||||
|
if (!(f->flags & FieldFlag_Pointer)) {
|
||||||
|
throw Error((Formatter::format(), "Field `", name, "` of structure `",
|
||||||
|
this->name, "` ought to be a pointer"));
|
||||||
|
}
|
||||||
|
|
||||||
|
db.reader->IncPtr(f->offset);
|
||||||
|
Convert(ptrval, db);
|
||||||
|
// actually it is meaningless on which Structure the Convert is called
|
||||||
|
// because the `Pointer` argument triggers a special implementation.
|
||||||
|
}
|
||||||
|
catch (const Error& e) {
|
||||||
|
_defaultInitializer<error_policy>()(out, e.what());
|
||||||
|
out.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool readOk = true;
|
||||||
|
if (ptrval.val) {
|
||||||
|
// get block for ptr
|
||||||
|
const FileBlockHead* block = LocateFileBlockForAddress(ptrval, db);
|
||||||
|
db.reader->SetCurrentPos(block->start + static_cast<size_t>((ptrval.val - block->address.val)));
|
||||||
|
// read block->num instances of given type to out
|
||||||
|
readOk = readCustomData(out, cdtype, block->num, db);
|
||||||
|
}
|
||||||
|
|
||||||
|
// and recover the previous stream position
|
||||||
|
db.reader->SetCurrentPos(old);
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
||||||
|
++db.stats().fields_read;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return readOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
template <int error_policy, template <typename> class TOUT, typename T>
|
||||||
|
bool Structure::ReadFieldPtrVector(vector<TOUT<T>>&out, const char* name, const FileDatabase& db) const {
|
||||||
|
out.clear();
|
||||||
|
|
||||||
|
const StreamReaderAny::pos old = db.reader->GetCurrentPos();
|
||||||
|
|
||||||
|
Pointer ptrval;
|
||||||
|
const Field* f;
|
||||||
|
try {
|
||||||
|
f = &(*this)[name];
|
||||||
|
|
||||||
|
// sanity check, should never happen if the genblenddna script is right
|
||||||
|
if (!(f->flags & FieldFlag_Pointer)) {
|
||||||
|
throw Error((Formatter::format(), "Field `", name, "` of structure `",
|
||||||
|
this->name, "` ought to be a pointer"));
|
||||||
|
}
|
||||||
|
|
||||||
|
db.reader->IncPtr(f->offset);
|
||||||
|
Convert(ptrval, db);
|
||||||
|
// actually it is meaningless on which Structure the Convert is called
|
||||||
|
// because the `Pointer` argument triggers a special implementation.
|
||||||
|
}
|
||||||
|
catch (const Error& e) {
|
||||||
|
_defaultInitializer<error_policy>()(out, e.what());
|
||||||
|
out.clear();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (ptrval.val) {
|
||||||
|
// find the file block the pointer is pointing to
|
||||||
|
const FileBlockHead* block = LocateFileBlockForAddress(ptrval, db);
|
||||||
|
db.reader->SetCurrentPos(block->start + static_cast<size_t>((ptrval.val - block->address.val)));
|
||||||
|
// FIXME: basically, this could cause problems with 64 bit pointers on 32 bit systems.
|
||||||
|
// I really ought to improve StreamReader to work with 64 bit indices exclusively.
|
||||||
|
|
||||||
|
const Structure& s = db.dna[f->type];
|
||||||
|
for (size_t i = 0; i < block->num; ++i) {
|
||||||
|
TOUT<T> p(new T);
|
||||||
|
s.Convert(*p, db);
|
||||||
|
out.push_back(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
db.reader->SetCurrentPos(old);
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
||||||
|
++db.stats().fields_read;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
template <template <typename> class TOUT, typename T>
|
template <template <typename> class TOUT, typename T>
|
||||||
bool Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const FileDatabase& db,
|
bool Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const FileDatabase& db,
|
||||||
|
|
|
@ -54,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "BlenderIntermediate.h"
|
#include "BlenderIntermediate.h"
|
||||||
#include "BlenderModifier.h"
|
#include "BlenderModifier.h"
|
||||||
#include "BlenderBMesh.h"
|
#include "BlenderBMesh.h"
|
||||||
|
#include "BlenderCustomData.h"
|
||||||
#include <assimp/StringUtils.h>
|
#include <assimp/StringUtils.h>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/importerdesc.h>
|
#include <assimp/importerdesc.h>
|
||||||
|
@ -1021,6 +1022,34 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO should we create the TextureUVMapping map in Convert<Material> to prevent redundant processing?
|
||||||
|
|
||||||
|
// create texture <-> uvname mapping for all materials
|
||||||
|
// key is texture number, value is data *
|
||||||
|
typedef std::map<uint32_t, const MLoopUV *> TextureUVMapping;
|
||||||
|
// key is material number, value is the TextureUVMapping for the material
|
||||||
|
typedef std::map<uint32_t, TextureUVMapping> MaterialTextureUVMappings;
|
||||||
|
MaterialTextureUVMappings matTexUvMappings;
|
||||||
|
const uint32_t maxMat = static_cast<const uint32_t>(mesh->mat.size());
|
||||||
|
for (uint32_t m = 0; m < maxMat; ++m) {
|
||||||
|
// get material by index
|
||||||
|
const std::shared_ptr<Material> pMat = mesh->mat[m];
|
||||||
|
TextureUVMapping texuv;
|
||||||
|
const uint32_t maxTex = sizeof(pMat->mtex) / sizeof(pMat->mtex[0]);
|
||||||
|
for (uint32_t t = 0; t < maxTex; ++t) {
|
||||||
|
if (pMat->mtex[t] && pMat->mtex[t]->uvname[0]) {
|
||||||
|
// get the CustomData layer for given uvname and correct type
|
||||||
|
const ElemBase *pLoop = getCustomDataLayerData(mesh->ldata, CD_MLOOPUV, pMat->mtex[t]->uvname);
|
||||||
|
if (pLoop) {
|
||||||
|
texuv.insert(std::make_pair(t, dynamic_cast<const MLoopUV *>(pLoop)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (texuv.size()) {
|
||||||
|
matTexUvMappings.insert(std::make_pair(m, texuv));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// collect texture coordinates, they're stored in a separate per-face buffer
|
// collect texture coordinates, they're stored in a separate per-face buffer
|
||||||
if (mesh->mtface || mesh->mloopuv) {
|
if (mesh->mtface || mesh->mloopuv) {
|
||||||
if (mesh->totface > static_cast<int> ( mesh->mtface.size())) {
|
if (mesh->totface > static_cast<int> ( mesh->mtface.size())) {
|
||||||
|
@ -1028,8 +1057,17 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
||||||
}
|
}
|
||||||
for (std::vector<aiMesh*>::iterator it = temp->begin()+old; it != temp->end(); ++it) {
|
for (std::vector<aiMesh*>::iterator it = temp->begin()+old; it != temp->end(); ++it) {
|
||||||
ai_assert((*it)->mNumVertices && (*it)->mNumFaces);
|
ai_assert((*it)->mNumVertices && (*it)->mNumFaces);
|
||||||
|
const auto itMatTexUvMapping = matTexUvMappings.find((*it)->mMaterialIndex);
|
||||||
|
if (itMatTexUvMapping == matTexUvMappings.end()) {
|
||||||
|
// default behaviour like before
|
||||||
(*it)->mTextureCoords[0] = new aiVector3D[(*it)->mNumVertices];
|
(*it)->mTextureCoords[0] = new aiVector3D[(*it)->mNumVertices];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// create texture coords for every mapped tex
|
||||||
|
for (uint32_t i = 0; i < itMatTexUvMapping->second.size(); ++i) {
|
||||||
|
(*it)->mTextureCoords[i] = new aiVector3D[(*it)->mNumVertices];
|
||||||
|
}
|
||||||
|
}
|
||||||
(*it)->mNumFaces = (*it)->mNumVertices = 0;
|
(*it)->mNumFaces = (*it)->mNumVertices = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1051,13 +1089,34 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
||||||
aiMesh* const out = temp[ mat_num_to_mesh_idx[ v.mat_nr ] ];
|
aiMesh* const out = temp[ mat_num_to_mesh_idx[ v.mat_nr ] ];
|
||||||
const aiFace& f = out->mFaces[out->mNumFaces++];
|
const aiFace& f = out->mFaces[out->mNumFaces++];
|
||||||
|
|
||||||
|
const auto itMatTexUvMapping = matTexUvMappings.find(v.mat_nr);
|
||||||
|
if (itMatTexUvMapping == matTexUvMappings.end()) {
|
||||||
|
// old behavior
|
||||||
aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
|
aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
|
||||||
for (unsigned int j = 0; j < f.mNumIndices; ++j, ++vo, ++out->mNumVertices) {
|
for (unsigned int j = 0; j < f.mNumIndices; ++j, ++vo, ++out->mNumVertices) {
|
||||||
const MLoopUV& uv = mesh->mloopuv[v.loopstart + j];
|
const MLoopUV& uv = mesh->mloopuv[v.loopstart + j];
|
||||||
vo->x = uv.uv[0];
|
vo->x = uv.uv[0];
|
||||||
vo->y = uv.uv[1];
|
vo->y = uv.uv[1];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// create textureCoords for every mapped tex
|
||||||
|
for (uint32_t m = 0; m < itMatTexUvMapping->second.size(); ++m) {
|
||||||
|
const MLoopUV *tm = itMatTexUvMapping->second[m];
|
||||||
|
aiVector3D* vo = &out->mTextureCoords[m][out->mNumVertices];
|
||||||
|
uint32_t j = 0;
|
||||||
|
for (; j < f.mNumIndices; ++j, ++vo) {
|
||||||
|
const MLoopUV& uv = tm[v.loopstart + j];
|
||||||
|
vo->x = uv.uv[0];
|
||||||
|
vo->y = uv.uv[1];
|
||||||
|
}
|
||||||
|
// only update written mNumVertices in last loop
|
||||||
|
// TODO why must the numVertices be incremented here?
|
||||||
|
if (m == itMatTexUvMapping->second.size() - 1) {
|
||||||
|
out->mNumVertices += j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "BlenderScene.h"
|
#include "BlenderScene.h"
|
||||||
#include "BlenderSceneGen.h"
|
#include "BlenderSceneGen.h"
|
||||||
#include "BlenderDNA.h"
|
#include "BlenderDNA.h"
|
||||||
|
#include "BlenderCustomData.h"
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
using namespace Assimp::Blender;
|
using namespace Assimp::Blender;
|
||||||
|
@ -481,6 +482,12 @@ template <> void Structure :: Convert<Mesh> (
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.mcol,"*mcol",db);
|
ReadFieldPtr<ErrorPolicy_Igno>(dest.mcol,"*mcol",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Fail>(dest.mat,"**mat",db);
|
ReadFieldPtr<ErrorPolicy_Fail>(dest.mat,"**mat",db);
|
||||||
|
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.vdata, "vdata", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.edata, "edata", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.fdata, "fdata", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.pdata, "pdata", db);
|
||||||
|
ReadField<ErrorPolicy_Warn>(dest.ldata, "ldata", db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -786,6 +793,41 @@ template <> void Structure :: Convert<Image> (
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
template <> void Structure::Convert<CustomData>(
|
||||||
|
CustomData& dest,
|
||||||
|
const FileDatabase& db
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
ReadFieldArray<ErrorPolicy_Warn>(dest.typemap, "typemap", db);
|
||||||
|
ReadField<ErrorPolicy_Warn>(dest.totlayer, "totlayer", db);
|
||||||
|
ReadField<ErrorPolicy_Warn>(dest.maxlayer, "maxlayer", db);
|
||||||
|
ReadField<ErrorPolicy_Warn>(dest.totsize, "totsize", db);
|
||||||
|
ReadFieldPtrVector<ErrorPolicy_Warn>(dest.layers, "*layers", db);
|
||||||
|
|
||||||
|
db.reader->IncPtr(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
template <> void Structure::Convert<CustomDataLayer>(
|
||||||
|
CustomDataLayer& dest,
|
||||||
|
const FileDatabase& db
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
ReadField<ErrorPolicy_Fail>(dest.type, "type", db);
|
||||||
|
ReadField<ErrorPolicy_Fail>(dest.offset, "offset", db);
|
||||||
|
ReadField<ErrorPolicy_Fail>(dest.flag, "flag", db);
|
||||||
|
ReadField<ErrorPolicy_Fail>(dest.active, "active", db);
|
||||||
|
ReadField<ErrorPolicy_Fail>(dest.active_rnd, "active_rnd", db);
|
||||||
|
ReadField<ErrorPolicy_Fail>(dest.active_clone, "active_clone", db);
|
||||||
|
ReadField<ErrorPolicy_Fail>(dest.active_mask, "active_mask", db);
|
||||||
|
ReadField<ErrorPolicy_Fail>(dest.uid, "uid", db);
|
||||||
|
ReadFieldArray<ErrorPolicy_Warn>(dest.name, "name", db);
|
||||||
|
ReadCustomDataPtr<ErrorPolicy_Fail>(dest.data, dest.type, "*data", db);
|
||||||
|
|
||||||
|
db.reader->IncPtr(size);
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
void DNA::RegisterConverters() {
|
void DNA::RegisterConverters() {
|
||||||
|
|
||||||
|
@ -822,6 +864,8 @@ void DNA::RegisterConverters() {
|
||||||
converters["Camera"] = DNA::FactoryPair( &Structure::Allocate<Camera>, &Structure::Convert<Camera> );
|
converters["Camera"] = DNA::FactoryPair( &Structure::Allocate<Camera>, &Structure::Convert<Camera> );
|
||||||
converters["MirrorModifierData"] = DNA::FactoryPair( &Structure::Allocate<MirrorModifierData>, &Structure::Convert<MirrorModifierData> );
|
converters["MirrorModifierData"] = DNA::FactoryPair( &Structure::Allocate<MirrorModifierData>, &Structure::Convert<MirrorModifierData> );
|
||||||
converters["Image"] = DNA::FactoryPair( &Structure::Allocate<Image>, &Structure::Convert<Image> );
|
converters["Image"] = DNA::FactoryPair( &Structure::Allocate<Image>, &Structure::Convert<Image> );
|
||||||
|
converters["CustomData"] = DNA::FactoryPair(&Structure::Allocate<CustomData>, &Structure::Convert<CustomData>);
|
||||||
|
converters["CustomDataLayer"] = DNA::FactoryPair(&Structure::Allocate<CustomDataLayer>, &Structure::Convert<CustomDataLayer>);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER
|
#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER
|
||||||
|
|
|
@ -157,10 +157,16 @@ struct World : ElemBase {
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MVert : ElemBase {
|
struct MVert : ElemBase {
|
||||||
float co[3] FAIL;
|
float co[3] FAIL;
|
||||||
float no[3] FAIL;
|
float no[3] FAIL; // readed as short and divided through / 32767.f
|
||||||
char flag;
|
char flag;
|
||||||
int mat_nr WARN;
|
int mat_nr WARN;
|
||||||
int bweight;
|
int bweight;
|
||||||
|
|
||||||
|
MVert() : ElemBase()
|
||||||
|
, flag(0)
|
||||||
|
, mat_nr(0)
|
||||||
|
, bweight(0)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
@ -369,6 +375,72 @@ struct Material : ElemBase {
|
||||||
std::shared_ptr<MTex> mtex[18];
|
std::shared_ptr<MTex> mtex[18];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
CustomDataLayer 104
|
||||||
|
|
||||||
|
int type 0 4
|
||||||
|
int offset 4 4
|
||||||
|
int flag 8 4
|
||||||
|
int active 12 4
|
||||||
|
int active_rnd 16 4
|
||||||
|
int active_clone 20 4
|
||||||
|
int active_mask 24 4
|
||||||
|
int uid 28 4
|
||||||
|
char name 32 64
|
||||||
|
void *data 96 8
|
||||||
|
*/
|
||||||
|
struct CustomDataLayer : ElemBase {
|
||||||
|
int type;
|
||||||
|
int offset;
|
||||||
|
int flag;
|
||||||
|
int active;
|
||||||
|
int active_rnd;
|
||||||
|
int active_clone;
|
||||||
|
int active_mask;
|
||||||
|
int uid;
|
||||||
|
char name[64];
|
||||||
|
std::shared_ptr<ElemBase> data; // must be converted to real type according type member
|
||||||
|
|
||||||
|
CustomDataLayer()
|
||||||
|
: ElemBase()
|
||||||
|
, type(0)
|
||||||
|
, offset(0)
|
||||||
|
, flag(0)
|
||||||
|
, active(0)
|
||||||
|
, active_rnd(0)
|
||||||
|
, active_clone(0)
|
||||||
|
, active_mask(0)
|
||||||
|
, uid(0)
|
||||||
|
, data(nullptr)
|
||||||
|
{
|
||||||
|
memset(name, 0, sizeof name);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
CustomData 208
|
||||||
|
|
||||||
|
CustomDataLayer *layers 0 8
|
||||||
|
int typemap 8 168
|
||||||
|
int pad_i1 176 4
|
||||||
|
int totlayer 180 4
|
||||||
|
int maxlayer 184 4
|
||||||
|
int totsize 188 4
|
||||||
|
BLI_mempool *pool 192 8
|
||||||
|
CustomDataExternal *external 200 8
|
||||||
|
*/
|
||||||
|
struct CustomData : ElemBase {
|
||||||
|
vector<std::shared_ptr<struct CustomDataLayer> > layers;
|
||||||
|
int typemap[42]; // CD_NUMTYPES
|
||||||
|
int totlayer;
|
||||||
|
int maxlayer;
|
||||||
|
int totsize;
|
||||||
|
/*
|
||||||
|
std::shared_ptr<BLI_mempool> pool;
|
||||||
|
std::shared_ptr<CustomDataExternal> external;
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Mesh : ElemBase {
|
struct Mesh : ElemBase {
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
|
@ -398,6 +470,12 @@ struct Mesh : ElemBase {
|
||||||
vector<MCol> mcol;
|
vector<MCol> mcol;
|
||||||
|
|
||||||
vector< std::shared_ptr<Material> > mat FAIL;
|
vector< std::shared_ptr<Material> > mat FAIL;
|
||||||
|
|
||||||
|
struct CustomData vdata;
|
||||||
|
struct CustomData edata;
|
||||||
|
struct CustomData fdata;
|
||||||
|
struct CustomData pdata;
|
||||||
|
struct CustomData ldata;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
|
|
@ -248,6 +248,17 @@ template <> void Structure :: Convert<Image> (
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
|
template <> void Structure::Convert<CustomData>(
|
||||||
|
CustomData& dest,
|
||||||
|
const FileDatabase& db
|
||||||
|
) const
|
||||||
|
;
|
||||||
|
|
||||||
|
template <> void Structure::Convert<CustomDataLayer>(
|
||||||
|
CustomDataLayer& dest,
|
||||||
|
const FileDatabase& db
|
||||||
|
) const
|
||||||
|
;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -469,6 +469,8 @@ ADD_ASSIMP_IMPORTER( BLEND
|
||||||
BlenderBMesh.cpp
|
BlenderBMesh.cpp
|
||||||
BlenderTessellator.h
|
BlenderTessellator.h
|
||||||
BlenderTessellator.cpp
|
BlenderTessellator.cpp
|
||||||
|
BlenderCustomData.h
|
||||||
|
BlenderCustomData.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
ADD_ASSIMP_IMPORTER( IFC
|
ADD_ASSIMP_IMPORTER( IFC
|
||||||
|
@ -909,6 +911,12 @@ ENDIF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
||||||
|
|
||||||
ADD_LIBRARY( assimp ${assimp_src} )
|
ADD_LIBRARY( assimp ${assimp_src} )
|
||||||
|
|
||||||
|
TARGET_INCLUDE_DIRECTORIES ( assimp PUBLIC
|
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
|
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/../include>
|
||||||
|
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
|
||||||
|
)
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES(assimp ${ZLIB_LIBRARIES} ${OPENDDL_PARSER_LIBRARIES} ${IRRXML_LIBRARY} )
|
TARGET_LINK_LIBRARIES(assimp ${ZLIB_LIBRARIES} ${OPENDDL_PARSER_LIBRARIES} ${IRRXML_LIBRARY} )
|
||||||
|
|
||||||
if(ANDROID AND ASSIMP_ANDROID_JNIIOSYSTEM)
|
if(ANDROID AND ASSIMP_ANDROID_JNIIOSYSTEM)
|
||||||
|
|
|
@ -137,9 +137,7 @@ void COBImporter::SetupProperties(const Importer* /*pImp*/)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void COBImporter::InternReadFile( const std::string& pFile,
|
void COBImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) {
|
||||||
aiScene* pScene, IOSystem* pIOHandler)
|
|
||||||
{
|
|
||||||
COB::Scene scene;
|
COB::Scene scene;
|
||||||
std::unique_ptr<StreamReaderLE> stream(new StreamReaderLE( pIOHandler->Open(pFile,"rb")) );
|
std::unique_ptr<StreamReaderLE> stream(new StreamReaderLE( pIOHandler->Open(pFile,"rb")) );
|
||||||
|
|
||||||
|
|
|
@ -272,12 +272,13 @@ struct Node
|
||||||
/** Node instances at this node */
|
/** Node instances at this node */
|
||||||
std::vector<NodeInstance> mNodeInstances;
|
std::vector<NodeInstance> mNodeInstances;
|
||||||
|
|
||||||
/** Rootnodes: Name of primary camera, if any */
|
/** Root-nodes: Name of primary camera, if any */
|
||||||
std::string mPrimaryCamera;
|
std::string mPrimaryCamera;
|
||||||
|
|
||||||
//! Constructor. Begin with a zero parent
|
//! Constructor. Begin with a zero parent
|
||||||
Node() {
|
Node()
|
||||||
mParent = NULL;
|
: mParent( nullptr ){
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Destructor: delete all children subsequently
|
//! Destructor: delete all children subsequently
|
||||||
|
|
|
@ -201,6 +201,7 @@ void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, I
|
||||||
0, -1, 0, 0,
|
0, -1, 0, 0,
|
||||||
0, 0, 0, 1);
|
0, 0, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// store all meshes
|
// store all meshes
|
||||||
StoreSceneMeshes( pScene);
|
StoreSceneMeshes( pScene);
|
||||||
|
|
||||||
|
@ -740,10 +741,6 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
||||||
// create bones if given
|
// create bones if given
|
||||||
if( pSrcController && pSrcController->mType == Collada::Skin)
|
if( pSrcController && pSrcController->mType == Collada::Skin)
|
||||||
{
|
{
|
||||||
// refuse if the vertex count does not match
|
|
||||||
// if( pSrcController->mWeightCounts.size() != dstMesh->mNumVertices)
|
|
||||||
// throw DeadlyImportError( "Joint Controller vertex count does not match mesh vertex count");
|
|
||||||
|
|
||||||
// resolve references - joint names
|
// resolve references - joint names
|
||||||
const Collada::Accessor& jointNamesAcc = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, pSrcController->mJointNameSource);
|
const Collada::Accessor& jointNamesAcc = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, pSrcController->mJointNameSource);
|
||||||
const Collada::Data& jointNames = pParser.ResolveLibraryReference( pParser.mDataLibrary, jointNamesAcc.mSource);
|
const Collada::Data& jointNames = pParser.ResolveLibraryReference( pParser.mDataLibrary, jointNamesAcc.mSource);
|
||||||
|
@ -971,7 +968,8 @@ void ColladaLoader::StoreAnimations( aiScene* pScene, const ColladaParser& pPars
|
||||||
for( size_t b = a+1; b < mAnims.size(); ++b)
|
for( size_t b = a+1; b < mAnims.size(); ++b)
|
||||||
{
|
{
|
||||||
aiAnimation* other = mAnims[b];
|
aiAnimation* other = mAnims[b];
|
||||||
if( other->mNumChannels == 1 && other->mDuration == templateAnim->mDuration && other->mTicksPerSecond == templateAnim->mTicksPerSecond )
|
if( other->mNumChannels == 1 && other->mDuration == templateAnim->mDuration &&
|
||||||
|
other->mTicksPerSecond == templateAnim->mTicksPerSecond )
|
||||||
collectedAnimIndices.push_back( b);
|
collectedAnimIndices.push_back( b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ using namespace Assimp::Formatter;
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
ColladaParser::ColladaParser( IOSystem* pIOHandler, const std::string& pFile)
|
ColladaParser::ColladaParser( IOSystem* pIOHandler, const std::string& pFile)
|
||||||
: mFileName( pFile )
|
: mFileName( pFile )
|
||||||
, mReader( NULL )
|
, mReader( nullptr )
|
||||||
, mDataLibrary()
|
, mDataLibrary()
|
||||||
, mAccessorLibrary()
|
, mAccessorLibrary()
|
||||||
, mMeshLibrary()
|
, mMeshLibrary()
|
||||||
|
@ -79,20 +79,20 @@ ColladaParser::ColladaParser( IOSystem* pIOHandler, const std::string& pFile)
|
||||||
, mLightLibrary()
|
, mLightLibrary()
|
||||||
, mCameraLibrary()
|
, mCameraLibrary()
|
||||||
, mControllerLibrary()
|
, mControllerLibrary()
|
||||||
, mRootNode( NULL )
|
, mRootNode( nullptr )
|
||||||
, mAnims()
|
, mAnims()
|
||||||
, mUnitSize( 1.0f )
|
, mUnitSize( 1.0f )
|
||||||
, mUpDirection( UP_Y )
|
, mUpDirection( UP_Y )
|
||||||
, mFormat(FV_1_5_n ) // We assume the newest file format by default
|
, mFormat(FV_1_5_n ) // We assume the newest file format by default
|
||||||
{
|
{
|
||||||
// validate io-handler instance
|
// validate io-handler instance
|
||||||
if ( NULL == pIOHandler ) {
|
if (nullptr == pIOHandler ) {
|
||||||
throw DeadlyImportError("IOSystem is NULL." );
|
throw DeadlyImportError("IOSystem is NULL." );
|
||||||
}
|
}
|
||||||
|
|
||||||
// open the file
|
// open the file
|
||||||
std::unique_ptr<IOStream> file( pIOHandler->Open(pFile ) );
|
std::unique_ptr<IOStream> file( pIOHandler->Open(pFile ) );
|
||||||
if (file.get() == NULL) {
|
if (file.get() == nullptr) {
|
||||||
throw DeadlyImportError( "Failed to open file " + pFile + "." );
|
throw DeadlyImportError( "Failed to open file " + pFile + "." );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,9 +363,9 @@ void ColladaParser::ReadAnimationClipLibrary()
|
||||||
|
|
||||||
void ColladaParser::PostProcessControllers()
|
void ColladaParser::PostProcessControllers()
|
||||||
{
|
{
|
||||||
for (ControllerLibrary::iterator it = mControllerLibrary.begin(); it != mControllerLibrary.end(); ++it)
|
std::string meshId;
|
||||||
{
|
for (ControllerLibrary::iterator it = mControllerLibrary.begin(); it != mControllerLibrary.end(); ++it) {
|
||||||
std::string meshId = it->second.mMeshId;
|
meshId = it->second.mMeshId;
|
||||||
ControllerLibrary::iterator findItr = mControllerLibrary.find(meshId);
|
ControllerLibrary::iterator findItr = mControllerLibrary.find(meshId);
|
||||||
while(findItr != mControllerLibrary.end()) {
|
while(findItr != mControllerLibrary.end()) {
|
||||||
meshId = findItr->second.mMeshId;
|
meshId = findItr->second.mMeshId;
|
||||||
|
|
|
@ -59,6 +59,25 @@ using namespace Assimp;
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
|
#ifndef ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template <typename aiMeshType>
|
||||||
|
void flipUVs(aiMeshType* pMesh) {
|
||||||
|
if (pMesh == nullptr) { return; }
|
||||||
|
// mirror texture y coordinate
|
||||||
|
for (unsigned int tcIdx = 0; tcIdx < AI_MAX_NUMBER_OF_TEXTURECOORDS; tcIdx++) {
|
||||||
|
if (!pMesh->HasTextureCoords(tcIdx)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int vIdx = 0; vIdx < pMesh->mNumVertices; vIdx++) {
|
||||||
|
pMesh->mTextureCoords[tcIdx][vIdx].y = 1.0f - pMesh->mTextureCoords[tcIdx][vIdx].y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
MakeLeftHandedProcess::MakeLeftHandedProcess()
|
MakeLeftHandedProcess::MakeLeftHandedProcess()
|
||||||
|
@ -282,15 +301,9 @@ void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat)
|
||||||
// Converts a single mesh
|
// Converts a single mesh
|
||||||
void FlipUVsProcess::ProcessMesh( aiMesh* pMesh)
|
void FlipUVsProcess::ProcessMesh( aiMesh* pMesh)
|
||||||
{
|
{
|
||||||
// mirror texture y coordinate
|
flipUVs(pMesh);
|
||||||
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
|
for (unsigned int idx = 0; idx < pMesh->mNumAnimMeshes; idx++) {
|
||||||
if( !pMesh->HasTextureCoords( a ) ) {
|
flipUVs(pMesh->mAnimMeshes[idx]);
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for( unsigned int b = 0; b < pMesh->mNumVertices; b++ ) {
|
|
||||||
pMesh->mTextureCoords[ a ][ b ].y = 1.0f - pMesh->mTextureCoords[ a ][ b ].y;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -222,7 +222,7 @@ void D3MFExporter::writeMetaData() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const aiString *key;
|
const aiString *key = nullptr;
|
||||||
const aiMetadataEntry *entry(nullptr);
|
const aiMetadataEntry *entry(nullptr);
|
||||||
for ( size_t i = 0; i < numMetaEntries; ++i ) {
|
for ( size_t i = 0; i < numMetaEntries; ++i ) {
|
||||||
mScene->mMetaData->Get( i, key, entry );
|
mScene->mMetaData->Get( i, key, entry );
|
||||||
|
|
|
@ -297,8 +297,9 @@ private:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1)
|
||||||
const size_t len( strlen( color ) );
|
const size_t len( strlen( color ) );
|
||||||
if ( 9 != len ) {
|
if ( 9 != len && 7 != len) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,26 +314,28 @@ private:
|
||||||
++buf;
|
++buf;
|
||||||
comp[ 1 ] = *buf;
|
comp[ 1 ] = *buf;
|
||||||
++buf;
|
++buf;
|
||||||
diffuse.r = static_cast<ai_real>( strtol( comp, NULL, 16 ) );
|
diffuse.r = static_cast<ai_real>( strtol( comp, NULL, 16 ) ) / 255.0;
|
||||||
|
|
||||||
|
|
||||||
comp[ 0 ] = *buf;
|
comp[ 0 ] = *buf;
|
||||||
++buf;
|
++buf;
|
||||||
comp[ 1 ] = *buf;
|
comp[ 1 ] = *buf;
|
||||||
++buf;
|
++buf;
|
||||||
diffuse.g = static_cast< ai_real >( strtol( comp, NULL, 16 ) );
|
diffuse.g = static_cast< ai_real >( strtol( comp, NULL, 16 ) ) / 255.0;
|
||||||
|
|
||||||
comp[ 0 ] = *buf;
|
comp[ 0 ] = *buf;
|
||||||
++buf;
|
++buf;
|
||||||
comp[ 1 ] = *buf;
|
comp[ 1 ] = *buf;
|
||||||
++buf;
|
++buf;
|
||||||
diffuse.b = static_cast< ai_real >( strtol( comp, NULL, 16 ) );
|
diffuse.b = static_cast< ai_real >( strtol( comp, NULL, 16 ) ) / 255.0;
|
||||||
|
|
||||||
|
if(7 == len)
|
||||||
|
return true;
|
||||||
comp[ 0 ] = *buf;
|
comp[ 0 ] = *buf;
|
||||||
++buf;
|
++buf;
|
||||||
comp[ 1 ] = *buf;
|
comp[ 1 ] = *buf;
|
||||||
++buf;
|
++buf;
|
||||||
diffuse.a = static_cast< ai_real >( strtol( comp, NULL, 16 ) );
|
diffuse.a = static_cast< ai_real >( strtol( comp, NULL, 16 ) ) / 255.0;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,7 +119,7 @@ bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
aiTexel* imageContent = new aiTexel[1u + imageSize / sizeof(aiTexel)];
|
aiTexel* imageContent = new aiTexel[ 1ul + static_cast<unsigned long>( imageSize ) / sizeof(aiTexel)];
|
||||||
file.seekg(0, std::ios::beg);
|
file.seekg(0, std::ios::beg);
|
||||||
file.read(reinterpret_cast<char*>(imageContent), imageSize);
|
file.read(reinterpret_cast<char*>(imageContent), imageSize);
|
||||||
|
|
||||||
|
|
|
@ -150,14 +150,14 @@ Exporter::ExportFormatEntry gExporters[] =
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "gltf", "GL Transmission Format", "gltf", &ExportSceneGLTF,
|
|
||||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
|
||||||
Exporter::ExportFormatEntry( "glb", "GL Transmission Format (binary)", "glb", &ExportSceneGLB,
|
|
||||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
|
||||||
Exporter::ExportFormatEntry( "gltf2", "GL Transmission Format v. 2", "gltf", &ExportSceneGLTF2,
|
Exporter::ExportFormatEntry( "gltf2", "GL Transmission Format v. 2", "gltf", &ExportSceneGLTF2,
|
||||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
||||||
Exporter::ExportFormatEntry( "glb2", "GL Transmission Format v. 2 (binary)", "glb", &ExportSceneGLB2,
|
Exporter::ExportFormatEntry( "glb2", "GL Transmission Format v. 2 (binary)", "glb", &ExportSceneGLB2,
|
||||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
||||||
|
Exporter::ExportFormatEntry( "gltf", "GL Transmission Format", "gltf", &ExportSceneGLTF,
|
||||||
|
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
||||||
|
Exporter::ExportFormatEntry( "glb", "GL Transmission Format (binary)", "glb", &ExportSceneGLB,
|
||||||
|
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
|
||||||
|
|
|
@ -73,11 +73,7 @@ using namespace Util;
|
||||||
|
|
||||||
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
|
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
|
||||||
|
|
||||||
// XXX vc9's debugger won't step into anonymous namespaces
|
FBXConverter::FBXConverter( aiScene* out, const Document& doc )
|
||||||
//namespace {
|
|
||||||
|
|
||||||
|
|
||||||
Converter::Converter( aiScene* out, const Document& doc )
|
|
||||||
: defaultMaterialIndex()
|
: defaultMaterialIndex()
|
||||||
, out( out )
|
, out( out )
|
||||||
, doc( doc ) {
|
, doc( doc ) {
|
||||||
|
@ -118,7 +114,7 @@ Converter::Converter( aiScene* out, const Document& doc )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Converter::~Converter() {
|
FBXConverter::~FBXConverter() {
|
||||||
std::for_each( meshes.begin(), meshes.end(), Util::delete_fun<aiMesh>() );
|
std::for_each( meshes.begin(), meshes.end(), Util::delete_fun<aiMesh>() );
|
||||||
std::for_each( materials.begin(), materials.end(), Util::delete_fun<aiMaterial>() );
|
std::for_each( materials.begin(), materials.end(), Util::delete_fun<aiMaterial>() );
|
||||||
std::for_each( animations.begin(), animations.end(), Util::delete_fun<aiAnimation>() );
|
std::for_each( animations.begin(), animations.end(), Util::delete_fun<aiAnimation>() );
|
||||||
|
@ -127,7 +123,7 @@ Converter::~Converter() {
|
||||||
std::for_each( textures.begin(), textures.end(), Util::delete_fun<aiTexture>() );
|
std::for_each( textures.begin(), textures.end(), Util::delete_fun<aiTexture>() );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::ConvertRootNode() {
|
void FBXConverter::ConvertRootNode() {
|
||||||
out->mRootNode = new aiNode();
|
out->mRootNode = new aiNode();
|
||||||
out->mRootNode->mName.Set( "RootNode" );
|
out->mRootNode->mName.Set( "RootNode" );
|
||||||
|
|
||||||
|
@ -135,7 +131,7 @@ void Converter::ConvertRootNode() {
|
||||||
ConvertNodes( 0L, *out->mRootNode );
|
ConvertNodes( 0L, *out->mRootNode );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform ) {
|
void FBXConverter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform ) {
|
||||||
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced( id, "Model" );
|
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced( id, "Model" );
|
||||||
|
|
||||||
std::vector<aiNode*> nodes;
|
std::vector<aiNode*> nodes;
|
||||||
|
@ -189,12 +185,8 @@ void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& pa
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !name_carrier ) {
|
if ( !name_carrier ) {
|
||||||
NodeNameCache::const_iterator it( std::find( mNodeNames.begin(), mNodeNames.end(), original_name ) );
|
std::string old_original_name = original_name;
|
||||||
if ( it != mNodeNames.end() ) {
|
GetUniqueName(old_original_name, original_name);
|
||||||
original_name = original_name + std::string( "001" );
|
|
||||||
}
|
|
||||||
|
|
||||||
mNodeNames.push_back( original_name );
|
|
||||||
nodes_chain.push_back( new aiNode( original_name ) );
|
nodes_chain.push_back( new aiNode( original_name ) );
|
||||||
} else {
|
} else {
|
||||||
original_name = nodes_chain.back()->mName.C_Str();
|
original_name = nodes_chain.back()->mName.C_Str();
|
||||||
|
@ -286,7 +278,7 @@ void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& pa
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Converter::ConvertLights( const Model& model, const std::string &orig_name ) {
|
void FBXConverter::ConvertLights( const Model& model, const std::string &orig_name ) {
|
||||||
const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes();
|
const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes();
|
||||||
for( const NodeAttribute* attr : node_attrs ) {
|
for( const NodeAttribute* attr : node_attrs ) {
|
||||||
const Light* const light = dynamic_cast<const Light*>( attr );
|
const Light* const light = dynamic_cast<const Light*>( attr );
|
||||||
|
@ -296,7 +288,7 @@ void Converter::ConvertLights( const Model& model, const std::string &orig_name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::ConvertCameras( const Model& model, const std::string &orig_name ) {
|
void FBXConverter::ConvertCameras( const Model& model, const std::string &orig_name ) {
|
||||||
const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes();
|
const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes();
|
||||||
for( const NodeAttribute* attr : node_attrs ) {
|
for( const NodeAttribute* attr : node_attrs ) {
|
||||||
const Camera* const cam = dynamic_cast<const Camera*>( attr );
|
const Camera* const cam = dynamic_cast<const Camera*>( attr );
|
||||||
|
@ -306,7 +298,7 @@ void Converter::ConvertCameras( const Model& model, const std::string &orig_name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::ConvertLight( const Light& light, const std::string &orig_name ) {
|
void FBXConverter::ConvertLight( const Light& light, const std::string &orig_name ) {
|
||||||
lights.push_back( new aiLight() );
|
lights.push_back( new aiLight() );
|
||||||
aiLight* const out_light = lights.back();
|
aiLight* const out_light = lights.back();
|
||||||
|
|
||||||
|
@ -383,7 +375,7 @@ void Converter::ConvertLight( const Light& light, const std::string &orig_name )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::ConvertCamera( const Camera& cam, const std::string &orig_name )
|
void FBXConverter::ConvertCamera( const Camera& cam, const std::string &orig_name )
|
||||||
{
|
{
|
||||||
cameras.push_back( new aiCamera() );
|
cameras.push_back( new aiCamera() );
|
||||||
aiCamera* const out_camera = cameras.back();
|
aiCamera* const out_camera = cameras.back();
|
||||||
|
@ -402,36 +394,23 @@ void Converter::ConvertCamera( const Camera& cam, const std::string &orig_name )
|
||||||
out_camera->mClipPlaneFar = cam.FarPlane();
|
out_camera->mClipPlaneFar = cam.FarPlane();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool HasName( NodeNameCache &cache, const std::string &name ) {
|
void FBXConverter::GetUniqueName( const std::string &name, std::string &uniqueName )
|
||||||
NodeNameCache::const_iterator it( std::find( cache.begin(), cache.end(), name ) );
|
{
|
||||||
return it != cache.end();
|
int i = 0;
|
||||||
|
|
||||||
}
|
|
||||||
void Converter::GetUniqueName( const std::string &name, std::string uniqueName ) {
|
|
||||||
if ( !HasName( mNodeNames, name ) ) {
|
|
||||||
uniqueName = name;
|
uniqueName = name;
|
||||||
return;
|
while (mNodeNames.find(uniqueName) != mNodeNames.end())
|
||||||
}
|
{
|
||||||
|
|
||||||
int i( 0 );
|
|
||||||
std::string newName;
|
|
||||||
while ( HasName( mNodeNames, newName ) ) {
|
|
||||||
++i;
|
++i;
|
||||||
newName.clear();
|
|
||||||
newName += name;
|
|
||||||
std::stringstream ext;
|
std::stringstream ext;
|
||||||
ext << std::setfill( '0' ) << std::setw( 3 ) << i;
|
ext << name << std::setfill('0') << std::setw(3) << i;
|
||||||
newName += ext.str();
|
uniqueName = ext.str();
|
||||||
}
|
}
|
||||||
uniqueName = newName;
|
mNodeNames.insert(uniqueName);
|
||||||
mNodeNames.push_back( uniqueName );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char* Converter::NameTransformationComp( TransformationComp comp )
|
const char* FBXConverter::NameTransformationComp( TransformationComp comp ) {
|
||||||
{
|
switch ( comp ) {
|
||||||
switch ( comp )
|
|
||||||
{
|
|
||||||
case TransformationComp_Translation:
|
case TransformationComp_Translation:
|
||||||
return "Translation";
|
return "Translation";
|
||||||
case TransformationComp_RotationOffset:
|
case TransformationComp_RotationOffset:
|
||||||
|
@ -472,13 +451,12 @@ const char* Converter::NameTransformationComp( TransformationComp comp )
|
||||||
}
|
}
|
||||||
|
|
||||||
ai_assert( false );
|
ai_assert( false );
|
||||||
return NULL;
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Converter::NameTransformationCompProperty( TransformationComp comp )
|
const char* FBXConverter::NameTransformationCompProperty( TransformationComp comp ) {
|
||||||
{
|
switch ( comp ) {
|
||||||
switch ( comp )
|
|
||||||
{
|
|
||||||
case TransformationComp_Translation:
|
case TransformationComp_Translation:
|
||||||
return "Lcl Translation";
|
return "Lcl Translation";
|
||||||
case TransformationComp_RotationOffset:
|
case TransformationComp_RotationOffset:
|
||||||
|
@ -518,17 +496,18 @@ const char* Converter::NameTransformationCompProperty( TransformationComp comp )
|
||||||
}
|
}
|
||||||
|
|
||||||
ai_assert( false );
|
ai_assert( false );
|
||||||
return NULL;
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
aiVector3D Converter::TransformationCompDefaultValue( TransformationComp comp )
|
aiVector3D FBXConverter::TransformationCompDefaultValue( TransformationComp comp )
|
||||||
{
|
{
|
||||||
// XXX a neat way to solve the never-ending special cases for scaling
|
// XXX a neat way to solve the never-ending special cases for scaling
|
||||||
// would be to do everything in log space!
|
// would be to do everything in log space!
|
||||||
return comp == TransformationComp_Scaling ? aiVector3D( 1.f, 1.f, 1.f ) : aiVector3D();
|
return comp == TransformationComp_Scaling ? aiVector3D( 1.f, 1.f, 1.f ) : aiVector3D();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::GetRotationMatrix( Model::RotOrder mode, const aiVector3D& rotation, aiMatrix4x4& out )
|
void FBXConverter::GetRotationMatrix( Model::RotOrder mode, const aiVector3D& rotation, aiMatrix4x4& out )
|
||||||
{
|
{
|
||||||
if ( mode == Model::RotOrder_SphericXYZ ) {
|
if ( mode == Model::RotOrder_SphericXYZ ) {
|
||||||
FBXImporter::LogError( "Unsupported RotationMode: SphericXYZ" );
|
FBXImporter::LogError( "Unsupported RotationMode: SphericXYZ" );
|
||||||
|
@ -599,11 +578,15 @@ void Converter::GetRotationMatrix( Model::RotOrder mode, const aiVector3D& rotat
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ai_assert( false );
|
ai_assert( false );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ai_assert( ( order[ 0 ] >= 0 ) && ( order[ 0 ] <= 2 ) );
|
ai_assert( order[ 0 ] >= 0 );
|
||||||
ai_assert( ( order[ 1 ] >= 0 ) && ( order[ 1 ] <= 2 ) );
|
ai_assert( order[ 0 ] <= 2 );
|
||||||
ai_assert( ( order[ 2 ] >= 0 ) && ( order[ 2 ] <= 2 ) );
|
ai_assert( order[ 1 ] >= 0 );
|
||||||
|
ai_assert( order[ 1 ] <= 2 );
|
||||||
|
ai_assert( order[ 2 ] >= 0 );
|
||||||
|
ai_assert( order[ 2 ] <= 2 );
|
||||||
|
|
||||||
if ( !is_id[ order[ 0 ] ] ) {
|
if ( !is_id[ order[ 0 ] ] ) {
|
||||||
out = temp[ order[ 0 ] ];
|
out = temp[ order[ 0 ] ];
|
||||||
|
@ -618,7 +601,7 @@ void Converter::GetRotationMatrix( Model::RotOrder mode, const aiVector3D& rotat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Converter::NeedsComplexTransformationChain( const Model& model )
|
bool FBXConverter::NeedsComplexTransformationChain( const Model& model )
|
||||||
{
|
{
|
||||||
const PropertyTable& props = model.Props();
|
const PropertyTable& props = model.Props();
|
||||||
bool ok;
|
bool ok;
|
||||||
|
@ -649,13 +632,13 @@ bool Converter::NeedsComplexTransformationChain( const Model& model )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Converter::NameTransformationChainNode( const std::string& name, TransformationComp comp )
|
std::string FBXConverter::NameTransformationChainNode( const std::string& name, TransformationComp comp )
|
||||||
{
|
{
|
||||||
return name + std::string( MAGIC_NODE_TAG ) + "_" + NameTransformationComp( comp );
|
return name + std::string( MAGIC_NODE_TAG ) + "_" + NameTransformationComp( comp );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::GenerateTransformationNodeChain( const Model& model, std::vector<aiNode*>& output_nodes, std::vector<aiNode*>& post_output_nodes )
|
void FBXConverter::GenerateTransformationNodeChain( const Model& model, std::vector<aiNode*>& output_nodes,
|
||||||
{
|
std::vector<aiNode*>& post_output_nodes ) {
|
||||||
const PropertyTable& props = model.Props();
|
const PropertyTable& props = model.Props();
|
||||||
const Model::RotOrder rot = model.RotationOrder();
|
const Model::RotOrder rot = model.RotationOrder();
|
||||||
|
|
||||||
|
@ -826,7 +809,7 @@ void Converter::GenerateTransformationNodeChain( const Model& model, std::vector
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::SetupNodeMetadata( const Model& model, aiNode& nd )
|
void FBXConverter::SetupNodeMetadata( const Model& model, aiNode& nd )
|
||||||
{
|
{
|
||||||
const PropertyTable& props = model.Props();
|
const PropertyTable& props = model.Props();
|
||||||
DirectPropertyMap unparsedProperties = props.GetUnparsedProperties();
|
DirectPropertyMap unparsedProperties = props.GetUnparsedProperties();
|
||||||
|
@ -863,7 +846,7 @@ void Converter::SetupNodeMetadata( const Model& model, aiNode& nd )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::ConvertModel( const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform )
|
void FBXConverter::ConvertModel( const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform )
|
||||||
{
|
{
|
||||||
const std::vector<const Geometry*>& geos = model.GetGeometry();
|
const std::vector<const Geometry*>& geos = model.GetGeometry();
|
||||||
|
|
||||||
|
@ -890,7 +873,7 @@ void Converter::ConvertModel( const Model& model, aiNode& nd, const aiMatrix4x4&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<unsigned int> Converter::ConvertMesh( const MeshGeometry& mesh, const Model& model,
|
std::vector<unsigned int> FBXConverter::ConvertMesh( const MeshGeometry& mesh, const Model& model,
|
||||||
const aiMatrix4x4& node_global_transform, aiNode& nd)
|
const aiMatrix4x4& node_global_transform, aiNode& nd)
|
||||||
{
|
{
|
||||||
std::vector<unsigned int> temp;
|
std::vector<unsigned int> temp;
|
||||||
|
@ -925,7 +908,7 @@ std::vector<unsigned int> Converter::ConvertMesh( const MeshGeometry& mesh, cons
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
aiMesh* Converter::SetupEmptyMesh( const MeshGeometry& mesh, aiNode& nd)
|
aiMesh* FBXConverter::SetupEmptyMesh( const MeshGeometry& mesh, aiNode& nd)
|
||||||
{
|
{
|
||||||
aiMesh* const out_mesh = new aiMesh();
|
aiMesh* const out_mesh = new aiMesh();
|
||||||
meshes.push_back( out_mesh );
|
meshes.push_back( out_mesh );
|
||||||
|
@ -948,7 +931,7 @@ aiMesh* Converter::SetupEmptyMesh( const MeshGeometry& mesh, aiNode& nd)
|
||||||
return out_mesh;
|
return out_mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Converter::ConvertMeshSingleMaterial( const MeshGeometry& mesh, const Model& model,
|
unsigned int FBXConverter::ConvertMeshSingleMaterial( const MeshGeometry& mesh, const Model& model,
|
||||||
const aiMatrix4x4& node_global_transform, aiNode& nd)
|
const aiMatrix4x4& node_global_transform, aiNode& nd)
|
||||||
{
|
{
|
||||||
const MatIndexArray& mindices = mesh.GetMaterialIndices();
|
const MatIndexArray& mindices = mesh.GetMaterialIndices();
|
||||||
|
@ -1075,7 +1058,7 @@ unsigned int Converter::ConvertMeshSingleMaterial( const MeshGeometry& mesh, con
|
||||||
return static_cast<unsigned int>( meshes.size() - 1 );
|
return static_cast<unsigned int>( meshes.size() - 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<unsigned int> Converter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model,
|
std::vector<unsigned int> FBXConverter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model,
|
||||||
const aiMatrix4x4& node_global_transform, aiNode& nd)
|
const aiMatrix4x4& node_global_transform, aiNode& nd)
|
||||||
{
|
{
|
||||||
const MatIndexArray& mindices = mesh.GetMaterialIndices();
|
const MatIndexArray& mindices = mesh.GetMaterialIndices();
|
||||||
|
@ -1095,7 +1078,7 @@ std::vector<unsigned int> Converter::ConvertMeshMultiMaterial( const MeshGeometr
|
||||||
return indices;
|
return indices;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Converter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model,
|
unsigned int FBXConverter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model,
|
||||||
MatIndexArray::value_type index,
|
MatIndexArray::value_type index,
|
||||||
const aiMatrix4x4& node_global_transform,
|
const aiMatrix4x4& node_global_transform,
|
||||||
aiNode& nd)
|
aiNode& nd)
|
||||||
|
@ -1271,7 +1254,7 @@ unsigned int Converter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, cons
|
||||||
return static_cast<unsigned int>( meshes.size() - 1 );
|
return static_cast<unsigned int>( meshes.size() - 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::ConvertWeights( aiMesh* out, const Model& model, const MeshGeometry& geo,
|
void FBXConverter::ConvertWeights( aiMesh* out, const Model& model, const MeshGeometry& geo,
|
||||||
const aiMatrix4x4& node_global_transform ,
|
const aiMatrix4x4& node_global_transform ,
|
||||||
unsigned int materialIndex,
|
unsigned int materialIndex,
|
||||||
std::vector<unsigned int>* outputVertStartIndices )
|
std::vector<unsigned int>* outputVertStartIndices )
|
||||||
|
@ -1376,7 +1359,7 @@ void Converter::ConvertWeights( aiMesh* out, const Model& model, const MeshGeome
|
||||||
std::swap_ranges( bones.begin(), bones.end(), out->mBones );
|
std::swap_ranges( bones.begin(), bones.end(), out->mBones );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::ConvertCluster( std::vector<aiBone*>& bones, const Model& /*model*/, const Cluster& cl,
|
void FBXConverter::ConvertCluster( std::vector<aiBone*>& bones, const Model& /*model*/, const Cluster& cl,
|
||||||
std::vector<size_t>& out_indices,
|
std::vector<size_t>& out_indices,
|
||||||
std::vector<size_t>& index_out_indices,
|
std::vector<size_t>& index_out_indices,
|
||||||
std::vector<size_t>& count_out_indices,
|
std::vector<size_t>& count_out_indices,
|
||||||
|
@ -1417,7 +1400,7 @@ void Converter::ConvertCluster( std::vector<aiBone*>& bones, const Model& /*mode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::ConvertMaterialForMesh( aiMesh* out, const Model& model, const MeshGeometry& geo,
|
void FBXConverter::ConvertMaterialForMesh( aiMesh* out, const Model& model, const MeshGeometry& geo,
|
||||||
MatIndexArray::value_type materialIndex )
|
MatIndexArray::value_type materialIndex )
|
||||||
{
|
{
|
||||||
// locate source materials for this mesh
|
// locate source materials for this mesh
|
||||||
|
@ -1439,7 +1422,7 @@ void Converter::ConvertMaterialForMesh( aiMesh* out, const Model& model, const M
|
||||||
materials_converted[ mat ] = out->mMaterialIndex;
|
materials_converted[ mat ] = out->mMaterialIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Converter::GetDefaultMaterial()
|
unsigned int FBXConverter::GetDefaultMaterial()
|
||||||
{
|
{
|
||||||
if ( defaultMaterialIndex ) {
|
if ( defaultMaterialIndex ) {
|
||||||
return defaultMaterialIndex - 1;
|
return defaultMaterialIndex - 1;
|
||||||
|
@ -1461,7 +1444,7 @@ unsigned int Converter::GetDefaultMaterial()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned int Converter::ConvertMaterial( const Material& material, const MeshGeometry* const mesh )
|
unsigned int FBXConverter::ConvertMaterial( const Material& material, const MeshGeometry* const mesh )
|
||||||
{
|
{
|
||||||
const PropertyTable& props = material.Props();
|
const PropertyTable& props = material.Props();
|
||||||
|
|
||||||
|
@ -1496,7 +1479,7 @@ unsigned int Converter::ConvertMaterial( const Material& material, const MeshGeo
|
||||||
return static_cast<unsigned int>( materials.size() - 1 );
|
return static_cast<unsigned int>( materials.size() - 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Converter::ConvertVideo( const Video& video )
|
unsigned int FBXConverter::ConvertVideo( const Video& video )
|
||||||
{
|
{
|
||||||
// generate empty output texture
|
// generate empty output texture
|
||||||
aiTexture* out_tex = new aiTexture();
|
aiTexture* out_tex = new aiTexture();
|
||||||
|
@ -1526,23 +1509,13 @@ unsigned int Converter::ConvertVideo( const Video& video )
|
||||||
return static_cast<unsigned int>( textures.size() - 1 );
|
return static_cast<unsigned int>( textures.size() - 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap& textures,
|
aiString FBXConverter::GetTexturePath(const Texture* tex)
|
||||||
const std::string& propName,
|
|
||||||
aiTextureType target, const MeshGeometry* const mesh )
|
|
||||||
{
|
|
||||||
TextureMap::const_iterator it = textures.find( propName );
|
|
||||||
if ( it == textures.end() ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Texture* const tex = ( *it ).second;
|
|
||||||
if ( tex != 0 )
|
|
||||||
{
|
{
|
||||||
aiString path;
|
aiString path;
|
||||||
path.Set(tex->RelativeFilename());
|
path.Set(tex->RelativeFilename());
|
||||||
|
|
||||||
const Video* media = tex->Media();
|
const Video* media = tex->Media();
|
||||||
if (media != 0) {
|
if (media != nullptr) {
|
||||||
bool textureReady = false; //tells if our texture is ready (if it was loaded or if it was found)
|
bool textureReady = false; //tells if our texture is ready (if it was loaded or if it was found)
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
|
|
||||||
|
@ -1573,6 +1546,22 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FBXConverter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap& textures,
|
||||||
|
const std::string& propName,
|
||||||
|
aiTextureType target, const MeshGeometry* const mesh )
|
||||||
|
{
|
||||||
|
TextureMap::const_iterator it = textures.find( propName );
|
||||||
|
if ( it == textures.end() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Texture* const tex = ( *it ).second;
|
||||||
|
if ( tex != 0 )
|
||||||
|
{
|
||||||
|
aiString path = GetTexturePath(tex);
|
||||||
out_mat->AddProperty( &path, _AI_MATKEY_TEXTURE_BASE, target, 0 );
|
out_mat->AddProperty( &path, _AI_MATKEY_TEXTURE_BASE, target, 0 );
|
||||||
|
|
||||||
aiUVTransform uvTrafo;
|
aiUVTransform uvTrafo;
|
||||||
|
@ -1678,7 +1667,7 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::TrySetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures,
|
void FBXConverter::TrySetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures,
|
||||||
const std::string& propName,
|
const std::string& propName,
|
||||||
aiTextureType target, const MeshGeometry* const mesh ) {
|
aiTextureType target, const MeshGeometry* const mesh ) {
|
||||||
LayeredTextureMap::const_iterator it = layeredTextures.find( propName );
|
LayeredTextureMap::const_iterator it = layeredTextures.find( propName );
|
||||||
|
@ -1696,9 +1685,7 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const LayeredTextu
|
||||||
|
|
||||||
const Texture* const tex = ( *it ).second->getTexture(texIndex);
|
const Texture* const tex = ( *it ).second->getTexture(texIndex);
|
||||||
|
|
||||||
aiString path;
|
aiString path = GetTexturePath(tex);
|
||||||
path.Set( tex->RelativeFilename() );
|
|
||||||
|
|
||||||
out_mat->AddProperty( &path, _AI_MATKEY_TEXTURE_BASE, target, texIndex );
|
out_mat->AddProperty( &path, _AI_MATKEY_TEXTURE_BASE, target, texIndex );
|
||||||
|
|
||||||
aiUVTransform uvTrafo;
|
aiUVTransform uvTrafo;
|
||||||
|
@ -1803,7 +1790,7 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const LayeredTextu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::SetTextureProperties( aiMaterial* out_mat, const TextureMap& textures, const MeshGeometry* const mesh )
|
void FBXConverter::SetTextureProperties( aiMaterial* out_mat, const TextureMap& textures, const MeshGeometry* const mesh )
|
||||||
{
|
{
|
||||||
TrySetTextureProperties( out_mat, textures, "DiffuseColor", aiTextureType_DIFFUSE, mesh );
|
TrySetTextureProperties( out_mat, textures, "DiffuseColor", aiTextureType_DIFFUSE, mesh );
|
||||||
TrySetTextureProperties( out_mat, textures, "AmbientColor", aiTextureType_AMBIENT, mesh );
|
TrySetTextureProperties( out_mat, textures, "AmbientColor", aiTextureType_AMBIENT, mesh );
|
||||||
|
@ -1818,7 +1805,7 @@ void Converter::SetTextureProperties( aiMaterial* out_mat, const TextureMap& tex
|
||||||
TrySetTextureProperties( out_mat, textures, "ShininessExponent", aiTextureType_SHININESS, mesh );
|
TrySetTextureProperties( out_mat, textures, "ShininessExponent", aiTextureType_SHININESS, mesh );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::SetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh )
|
void FBXConverter::SetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh )
|
||||||
{
|
{
|
||||||
TrySetTextureProperties( out_mat, layeredTextures, "DiffuseColor", aiTextureType_DIFFUSE, mesh );
|
TrySetTextureProperties( out_mat, layeredTextures, "DiffuseColor", aiTextureType_DIFFUSE, mesh );
|
||||||
TrySetTextureProperties( out_mat, layeredTextures, "AmbientColor", aiTextureType_AMBIENT, mesh );
|
TrySetTextureProperties( out_mat, layeredTextures, "AmbientColor", aiTextureType_AMBIENT, mesh );
|
||||||
|
@ -1833,7 +1820,7 @@ void Converter::SetTextureProperties( aiMaterial* out_mat, const LayeredTextureM
|
||||||
TrySetTextureProperties( out_mat, layeredTextures, "ShininessExponent", aiTextureType_SHININESS, mesh );
|
TrySetTextureProperties( out_mat, layeredTextures, "ShininessExponent", aiTextureType_SHININESS, mesh );
|
||||||
}
|
}
|
||||||
|
|
||||||
aiColor3D Converter::GetColorPropertyFactored( const PropertyTable& props, const std::string& colorName,
|
aiColor3D FBXConverter::GetColorPropertyFactored( const PropertyTable& props, const std::string& colorName,
|
||||||
const std::string& factorName, bool& result, bool useTemplate )
|
const std::string& factorName, bool& result, bool useTemplate )
|
||||||
{
|
{
|
||||||
result = true;
|
result = true;
|
||||||
|
@ -1858,13 +1845,13 @@ aiColor3D Converter::GetColorPropertyFactored( const PropertyTable& props, const
|
||||||
return aiColor3D( BaseColor.x, BaseColor.y, BaseColor.z );
|
return aiColor3D( BaseColor.x, BaseColor.y, BaseColor.z );
|
||||||
}
|
}
|
||||||
|
|
||||||
aiColor3D Converter::GetColorPropertyFromMaterial( const PropertyTable& props, const std::string& baseName,
|
aiColor3D FBXConverter::GetColorPropertyFromMaterial( const PropertyTable& props, const std::string& baseName,
|
||||||
bool& result )
|
bool& result )
|
||||||
{
|
{
|
||||||
return GetColorPropertyFactored( props, baseName + "Color", baseName + "Factor", result, true );
|
return GetColorPropertyFactored( props, baseName + "Color", baseName + "Factor", result, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
aiColor3D Converter::GetColorProperty( const PropertyTable& props, const std::string& colorName,
|
aiColor3D FBXConverter::GetColorProperty( const PropertyTable& props, const std::string& colorName,
|
||||||
bool& result, bool useTemplate )
|
bool& result, bool useTemplate )
|
||||||
{
|
{
|
||||||
result = true;
|
result = true;
|
||||||
|
@ -1877,7 +1864,7 @@ aiColor3D Converter::GetColorProperty( const PropertyTable& props, const std::st
|
||||||
return aiColor3D( ColorVec.x, ColorVec.y, ColorVec.z );
|
return aiColor3D( ColorVec.x, ColorVec.y, ColorVec.z );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::SetShadingPropertiesCommon( aiMaterial* out_mat, const PropertyTable& props )
|
void FBXConverter::SetShadingPropertiesCommon( aiMaterial* out_mat, const PropertyTable& props )
|
||||||
{
|
{
|
||||||
// Set shading properties.
|
// Set shading properties.
|
||||||
// Modern FBX Files have two separate systems for defining these,
|
// Modern FBX Files have two separate systems for defining these,
|
||||||
|
@ -1976,8 +1963,7 @@ void Converter::SetShadingPropertiesCommon( aiMaterial* out_mat, const PropertyT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double Converter::FrameRateToDouble( FileGlobalSettings::FrameRate fp, double customFPSVal )
|
double FBXConverter::FrameRateToDouble( FileGlobalSettings::FrameRate fp, double customFPSVal ) {
|
||||||
{
|
|
||||||
switch ( fp ) {
|
switch ( fp ) {
|
||||||
case FileGlobalSettings::FrameRate_DEFAULT:
|
case FileGlobalSettings::FrameRate_DEFAULT:
|
||||||
return 1.0;
|
return 1.0;
|
||||||
|
@ -2025,11 +2011,12 @@ double Converter::FrameRateToDouble( FileGlobalSettings::FrameRate fp, double cu
|
||||||
}
|
}
|
||||||
|
|
||||||
ai_assert( false );
|
ai_assert( false );
|
||||||
|
|
||||||
return -1.0f;
|
return -1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Converter::ConvertAnimations()
|
void FBXConverter::ConvertAnimations()
|
||||||
{
|
{
|
||||||
// first of all determine framerate
|
// first of all determine framerate
|
||||||
const FileGlobalSettings::FrameRate fps = doc.GlobalSettings().TimeMode();
|
const FileGlobalSettings::FrameRate fps = doc.GlobalSettings().TimeMode();
|
||||||
|
@ -2042,7 +2029,7 @@ void Converter::ConvertAnimations()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Converter::FixNodeName( const std::string& name ) {
|
std::string FBXConverter::FixNodeName( const std::string& name ) {
|
||||||
// strip Model:: prefix, avoiding ambiguities (i.e. don't strip if
|
// strip Model:: prefix, avoiding ambiguities (i.e. don't strip if
|
||||||
// this causes ambiguities, well possible between empty identifiers,
|
// this causes ambiguities, well possible between empty identifiers,
|
||||||
// such as "Model::" and ""). Make sure the behaviour is consistent
|
// such as "Model::" and ""). Make sure the behaviour is consistent
|
||||||
|
@ -2055,7 +2042,7 @@ std::string Converter::FixNodeName( const std::string& name ) {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::ConvertAnimationStack( const AnimationStack& st )
|
void FBXConverter::ConvertAnimationStack( const AnimationStack& st )
|
||||||
{
|
{
|
||||||
const AnimationLayerList& layers = st.Layers();
|
const AnimationLayerList& layers = st.Layers();
|
||||||
if ( layers.empty() ) {
|
if ( layers.empty() ) {
|
||||||
|
@ -2197,7 +2184,7 @@ static void validateAnimCurveNodes( const std::vector<const AnimationCurveNode*>
|
||||||
#endif // ASSIMP_BUILD_DEBUG
|
#endif // ASSIMP_BUILD_DEBUG
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Converter::GenerateNodeAnimations( std::vector<aiNodeAnim*>& node_anims,
|
void FBXConverter::GenerateNodeAnimations( std::vector<aiNodeAnim*>& node_anims,
|
||||||
const std::string& fixed_name,
|
const std::string& fixed_name,
|
||||||
const std::vector<const AnimationCurveNode*>& curves,
|
const std::vector<const AnimationCurveNode*>& curves,
|
||||||
const LayerMap& layer_map,
|
const LayerMap& layer_map,
|
||||||
|
@ -2431,10 +2418,9 @@ void Converter::GenerateNodeAnimations( std::vector<aiNodeAnim*>& node_anims,
|
||||||
node_anim_chain_bits[ fixed_name ] = flags;
|
node_anim_chain_bits[ fixed_name ] = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Converter::IsRedundantAnimationData( const Model& target,
|
bool FBXConverter::IsRedundantAnimationData( const Model& target,
|
||||||
TransformationComp comp,
|
TransformationComp comp,
|
||||||
const std::vector<const AnimationCurveNode*>& curves )
|
const std::vector<const AnimationCurveNode*>& curves ) {
|
||||||
{
|
|
||||||
ai_assert( curves.size() );
|
ai_assert( curves.size() );
|
||||||
|
|
||||||
// look for animation nodes with
|
// look for animation nodes with
|
||||||
|
@ -2477,7 +2463,7 @@ bool Converter::IsRedundantAnimationData( const Model& target,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
aiNodeAnim* Converter::GenerateRotationNodeAnim( const std::string& name,
|
aiNodeAnim* FBXConverter::GenerateRotationNodeAnim( const std::string& name,
|
||||||
const Model& target,
|
const Model& target,
|
||||||
const std::vector<const AnimationCurveNode*>& curves,
|
const std::vector<const AnimationCurveNode*>& curves,
|
||||||
const LayerMap& layer_map,
|
const LayerMap& layer_map,
|
||||||
|
@ -2507,7 +2493,7 @@ aiNodeAnim* Converter::GenerateRotationNodeAnim( const std::string& name,
|
||||||
return na.release();
|
return na.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
aiNodeAnim* Converter::GenerateScalingNodeAnim( const std::string& name,
|
aiNodeAnim* FBXConverter::GenerateScalingNodeAnim( const std::string& name,
|
||||||
const Model& /*target*/,
|
const Model& /*target*/,
|
||||||
const std::vector<const AnimationCurveNode*>& curves,
|
const std::vector<const AnimationCurveNode*>& curves,
|
||||||
const LayerMap& layer_map,
|
const LayerMap& layer_map,
|
||||||
|
@ -2537,16 +2523,14 @@ aiNodeAnim* Converter::GenerateScalingNodeAnim( const std::string& name,
|
||||||
return na.release();
|
return na.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aiNodeAnim* FBXConverter::GenerateTranslationNodeAnim( const std::string& name,
|
||||||
aiNodeAnim* Converter::GenerateTranslationNodeAnim( const std::string& name,
|
|
||||||
const Model& /*target*/,
|
const Model& /*target*/,
|
||||||
const std::vector<const AnimationCurveNode*>& curves,
|
const std::vector<const AnimationCurveNode*>& curves,
|
||||||
const LayerMap& layer_map,
|
const LayerMap& layer_map,
|
||||||
int64_t start, int64_t stop,
|
int64_t start, int64_t stop,
|
||||||
double& max_time,
|
double& max_time,
|
||||||
double& min_time,
|
double& min_time,
|
||||||
bool inverse )
|
bool inverse ) {
|
||||||
{
|
|
||||||
std::unique_ptr<aiNodeAnim> na( new aiNodeAnim() );
|
std::unique_ptr<aiNodeAnim> na( new aiNodeAnim() );
|
||||||
na->mNodeName.Set( name );
|
na->mNodeName.Set( name );
|
||||||
|
|
||||||
|
@ -2575,7 +2559,7 @@ aiNodeAnim* Converter::GenerateTranslationNodeAnim( const std::string& name,
|
||||||
return na.release();
|
return na.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
aiNodeAnim* Converter::GenerateSimpleNodeAnim( const std::string& name,
|
aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim( const std::string& name,
|
||||||
const Model& target,
|
const Model& target,
|
||||||
NodeMap::const_iterator chain[ TransformationComp_MAXIMUM ],
|
NodeMap::const_iterator chain[ TransformationComp_MAXIMUM ],
|
||||||
NodeMap::const_iterator iter_end,
|
NodeMap::const_iterator iter_end,
|
||||||
|
@ -2711,7 +2695,7 @@ aiNodeAnim* Converter::GenerateSimpleNodeAnim( const std::string& name,
|
||||||
return na.release();
|
return na.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
Converter::KeyFrameListList Converter::GetKeyframeList( const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop )
|
FBXConverter::KeyFrameListList FBXConverter::GetKeyframeList( const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop )
|
||||||
{
|
{
|
||||||
KeyFrameListList inputs;
|
KeyFrameListList inputs;
|
||||||
inputs.reserve( nodes.size() * 3 );
|
inputs.reserve( nodes.size() * 3 );
|
||||||
|
@ -2767,12 +2751,11 @@ Converter::KeyFrameListList Converter::GetKeyframeList( const std::vector<const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
KeyTimeList Converter::GetKeyTimeList( const KeyFrameListList& inputs )
|
KeyTimeList FBXConverter::GetKeyTimeList( const KeyFrameListList& inputs ) {
|
||||||
{
|
ai_assert( !inputs.empty() );
|
||||||
ai_assert( inputs.size() );
|
|
||||||
|
|
||||||
// reserve some space upfront - it is likely that the keyframe lists
|
// reserve some space upfront - it is likely that the key-frame lists
|
||||||
// have matching time values, so max(of all keyframe lists) should
|
// have matching time values, so max(of all key-frame lists) should
|
||||||
// be a good estimate.
|
// be a good estimate.
|
||||||
KeyTimeList keys;
|
KeyTimeList keys;
|
||||||
|
|
||||||
|
@ -2816,17 +2799,15 @@ KeyTimeList Converter::GetKeyTimeList( const KeyFrameListList& inputs )
|
||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
|
void FBXConverter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
|
||||||
const aiVector3D& def_value,
|
const aiVector3D& def_value,
|
||||||
double& max_time,
|
double& max_time,
|
||||||
double& min_time )
|
double& min_time ) {
|
||||||
|
ai_assert( !keys.empty() );
|
||||||
{
|
ai_assert( nullptr != valOut );
|
||||||
ai_assert( keys.size() );
|
|
||||||
ai_assert( valOut );
|
|
||||||
|
|
||||||
std::vector<unsigned int> next_pos;
|
std::vector<unsigned int> next_pos;
|
||||||
const size_t count = inputs.size();
|
const size_t count( inputs.size() );
|
||||||
|
|
||||||
next_pos.resize( inputs.size(), 0 );
|
next_pos.resize( inputs.size(), 0 );
|
||||||
|
|
||||||
|
@ -2837,6 +2818,9 @@ void Converter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, c
|
||||||
const KeyFrameList& kfl = inputs[ i ];
|
const KeyFrameList& kfl = inputs[ i ];
|
||||||
|
|
||||||
const size_t ksize = std::get<0>(kfl)->size();
|
const size_t ksize = std::get<0>(kfl)->size();
|
||||||
|
if (ksize == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if ( ksize > next_pos[ i ] && std::get<0>(kfl)->at( next_pos[ i ] ) == time ) {
|
if ( ksize > next_pos[ i ] && std::get<0>(kfl)->at( next_pos[ i ] ) == time ) {
|
||||||
++next_pos[ i ];
|
++next_pos[ i ];
|
||||||
}
|
}
|
||||||
|
@ -2871,14 +2855,14 @@ void Converter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
|
void FBXConverter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
|
||||||
const aiVector3D& def_value,
|
const aiVector3D& def_value,
|
||||||
double& maxTime,
|
double& maxTime,
|
||||||
double& minTime,
|
double& minTime,
|
||||||
Model::RotOrder order )
|
Model::RotOrder order )
|
||||||
{
|
{
|
||||||
ai_assert( keys.size() );
|
ai_assert( !keys.empty() );
|
||||||
ai_assert( valOut );
|
ai_assert( nullptr != valOut );
|
||||||
|
|
||||||
std::unique_ptr<aiVectorKey[]> temp( new aiVectorKey[ keys.size() ] );
|
std::unique_ptr<aiVectorKey[]> temp( new aiVectorKey[ keys.size() ] );
|
||||||
InterpolateKeys( temp.get(), keys, inputs, def_value, maxTime, minTime );
|
InterpolateKeys( temp.get(), keys, inputs, def_value, maxTime, minTime );
|
||||||
|
@ -2909,7 +2893,7 @@ void Converter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::ConvertTransformOrder_TRStoSRT( aiQuatKey* out_quat, aiVectorKey* out_scale,
|
void FBXConverter::ConvertTransformOrder_TRStoSRT( aiQuatKey* out_quat, aiVectorKey* out_scale,
|
||||||
aiVectorKey* out_translation,
|
aiVectorKey* out_translation,
|
||||||
const KeyFrameListList& scaling,
|
const KeyFrameListList& scaling,
|
||||||
const KeyFrameListList& translation,
|
const KeyFrameListList& translation,
|
||||||
|
@ -2967,7 +2951,7 @@ void Converter::ConvertTransformOrder_TRStoSRT( aiQuatKey* out_quat, aiVectorKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
aiQuaternion Converter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrder order )
|
aiQuaternion FBXConverter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrder order )
|
||||||
{
|
{
|
||||||
aiMatrix4x4 m;
|
aiMatrix4x4 m;
|
||||||
GetRotationMatrix( order, rot, m );
|
GetRotationMatrix( order, rot, m );
|
||||||
|
@ -2975,7 +2959,7 @@ aiQuaternion Converter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrde
|
||||||
return aiQuaternion( aiMatrix3x3( m ) );
|
return aiQuaternion( aiMatrix3x3( m ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::ConvertScaleKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/,
|
void FBXConverter::ConvertScaleKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/,
|
||||||
int64_t start, int64_t stop,
|
int64_t start, int64_t stop,
|
||||||
double& maxTime,
|
double& maxTime,
|
||||||
double& minTime )
|
double& minTime )
|
||||||
|
@ -2995,7 +2979,7 @@ void Converter::ConvertScaleKeys( aiNodeAnim* na, const std::vector<const Animat
|
||||||
InterpolateKeys( na->mScalingKeys, keys, inputs, aiVector3D( 1.0f, 1.0f, 1.0f ), maxTime, minTime );
|
InterpolateKeys( na->mScalingKeys, keys, inputs, aiVector3D( 1.0f, 1.0f, 1.0f ), maxTime, minTime );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::ConvertTranslationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
void FBXConverter::ConvertTranslationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
||||||
const LayerMap& /*layers*/,
|
const LayerMap& /*layers*/,
|
||||||
int64_t start, int64_t stop,
|
int64_t start, int64_t stop,
|
||||||
double& maxTime,
|
double& maxTime,
|
||||||
|
@ -3013,7 +2997,7 @@ void Converter::ConvertTranslationKeys( aiNodeAnim* na, const std::vector<const
|
||||||
InterpolateKeys( na->mPositionKeys, keys, inputs, aiVector3D( 0.0f, 0.0f, 0.0f ), maxTime, minTime );
|
InterpolateKeys( na->mPositionKeys, keys, inputs, aiVector3D( 0.0f, 0.0f, 0.0f ), maxTime, minTime );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::ConvertRotationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
void FBXConverter::ConvertRotationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
||||||
const LayerMap& /*layers*/,
|
const LayerMap& /*layers*/,
|
||||||
int64_t start, int64_t stop,
|
int64_t start, int64_t stop,
|
||||||
double& maxTime,
|
double& maxTime,
|
||||||
|
@ -3033,7 +3017,7 @@ void Converter::ConvertRotationKeys( aiNodeAnim* na, const std::vector<const Ani
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::ConvertGlobalSettings() {
|
void FBXConverter::ConvertGlobalSettings() {
|
||||||
if (nullptr == out) {
|
if (nullptr == out) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3044,7 +3028,7 @@ void Converter::ConvertGlobalSettings() {
|
||||||
out->mMetaData->Set(index, "UnitScaleFactor", unitScalFactor);
|
out->mMetaData->Set(index, "UnitScaleFactor", unitScalFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::TransferDataToScene()
|
void FBXConverter::TransferDataToScene()
|
||||||
{
|
{
|
||||||
ai_assert( !out->mMeshes );
|
ai_assert( !out->mMeshes );
|
||||||
ai_assert( !out->mNumMeshes );
|
ai_assert( !out->mNumMeshes );
|
||||||
|
@ -3096,12 +3080,10 @@ void Converter::TransferDataToScene()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//} // !anon
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertToAssimpScene(aiScene* out, const Document& doc)
|
void ConvertToAssimpScene(aiScene* out, const Document& doc)
|
||||||
{
|
{
|
||||||
Converter converter(out,doc);
|
FBXConverter converter(out,doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // !FBX
|
} // !FBX
|
||||||
|
|
|
@ -68,7 +68,7 @@ namespace FBX {
|
||||||
|
|
||||||
class Document;
|
class Document;
|
||||||
|
|
||||||
using NodeNameCache = std::vector<std::string>;
|
using NodeNameCache = std::set<std::string>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a FBX #Document to #aiScene
|
* Convert a FBX #Document to #aiScene
|
||||||
|
@ -78,7 +78,7 @@ using NodeNameCache = std::vector<std::string>;
|
||||||
void ConvertToAssimpScene(aiScene* out, const Document& doc);
|
void ConvertToAssimpScene(aiScene* out, const Document& doc);
|
||||||
|
|
||||||
/** Dummy class to encapsulate the conversion process */
|
/** Dummy class to encapsulate the conversion process */
|
||||||
class Converter {
|
class FBXConverter {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* The different parts that make up the final local transformation of a fbx-node
|
* The different parts that make up the final local transformation of a fbx-node
|
||||||
|
@ -106,8 +106,8 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Converter(aiScene* out, const Document& doc);
|
FBXConverter(aiScene* out, const Document& doc);
|
||||||
~Converter();
|
~FBXConverter();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -131,7 +131,7 @@ private:
|
||||||
void ConvertCamera( const Camera& cam, const std::string &orig_name );
|
void ConvertCamera( const Camera& cam, const std::string &orig_name );
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void GetUniqueName( const std::string &name, std::string uniqueName );
|
void GetUniqueName( const std::string &name, std::string& uniqueName );
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// this returns unified names usable within assimp identifiers (i.e. no space characters -
|
// this returns unified names usable within assimp identifiers (i.e. no space characters -
|
||||||
|
@ -228,6 +228,10 @@ private:
|
||||||
// Video -> aiTexture
|
// Video -> aiTexture
|
||||||
unsigned int ConvertVideo(const Video& video);
|
unsigned int ConvertVideo(const Video& video);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// convert embedded texture if necessary and return actual texture path
|
||||||
|
aiString GetTexturePath(const Texture* tex);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void TrySetTextureProperties(aiMaterial* out_mat, const TextureMap& textures,
|
void TrySetTextureProperties(aiMaterial* out_mat, const TextureMap& textures,
|
||||||
const std::string& propName,
|
const std::string& propName,
|
||||||
|
|
|
@ -115,7 +115,7 @@ std::shared_ptr<const PropertyTable> GetPropertyTable(const Document& doc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!Properties70) {
|
if(!Properties70 || !Properties70->Compound()) {
|
||||||
if(!no_warn) {
|
if(!no_warn) {
|
||||||
DOMWarning("property table (Properties70) not found",&element);
|
DOMWarning("property table (Properties70) not found",&element);
|
||||||
}
|
}
|
||||||
|
|
|
@ -985,6 +985,10 @@ int64_t to_ktime(double ticks, const aiAnimation* anim) {
|
||||||
return (static_cast<int64_t>(ticks) / static_cast<int64_t>(anim->mTicksPerSecond)) * FBX::SECOND;
|
return (static_cast<int64_t>(ticks) / static_cast<int64_t>(anim->mTicksPerSecond)) * FBX::SECOND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t to_ktime(double time) {
|
||||||
|
return (static_cast<int64_t>(time * FBX::SECOND));
|
||||||
|
}
|
||||||
|
|
||||||
void FBXExporter::WriteObjects ()
|
void FBXExporter::WriteObjects ()
|
||||||
{
|
{
|
||||||
if (!binary) {
|
if (!binary) {
|
||||||
|
@ -2089,7 +2093,7 @@ void FBXExporter::WriteObjects ()
|
||||||
// position/translation
|
// position/translation
|
||||||
for (size_t ki = 0; ki < na->mNumPositionKeys; ++ki) {
|
for (size_t ki = 0; ki < na->mNumPositionKeys; ++ki) {
|
||||||
const aiVectorKey& k = na->mPositionKeys[ki];
|
const aiVectorKey& k = na->mPositionKeys[ki];
|
||||||
times.push_back(to_ktime(k.mTime, anim));
|
times.push_back(to_ktime(k.mTime));
|
||||||
xval.push_back(k.mValue.x);
|
xval.push_back(k.mValue.x);
|
||||||
yval.push_back(k.mValue.y);
|
yval.push_back(k.mValue.y);
|
||||||
zval.push_back(k.mValue.z);
|
zval.push_back(k.mValue.z);
|
||||||
|
@ -2103,7 +2107,7 @@ void FBXExporter::WriteObjects ()
|
||||||
times.clear(); xval.clear(); yval.clear(); zval.clear();
|
times.clear(); xval.clear(); yval.clear(); zval.clear();
|
||||||
for (size_t ki = 0; ki < na->mNumRotationKeys; ++ki) {
|
for (size_t ki = 0; ki < na->mNumRotationKeys; ++ki) {
|
||||||
const aiQuatKey& k = na->mRotationKeys[ki];
|
const aiQuatKey& k = na->mRotationKeys[ki];
|
||||||
times.push_back(to_ktime(k.mTime, anim));
|
times.push_back(to_ktime(k.mTime));
|
||||||
// TODO: aiQuaternion method to convert to Euler...
|
// TODO: aiQuaternion method to convert to Euler...
|
||||||
aiMatrix4x4 m(k.mValue.GetMatrix());
|
aiMatrix4x4 m(k.mValue.GetMatrix());
|
||||||
aiVector3D qs, qr, qt;
|
aiVector3D qs, qr, qt;
|
||||||
|
@ -2121,7 +2125,7 @@ void FBXExporter::WriteObjects ()
|
||||||
times.clear(); xval.clear(); yval.clear(); zval.clear();
|
times.clear(); xval.clear(); yval.clear(); zval.clear();
|
||||||
for (size_t ki = 0; ki < na->mNumScalingKeys; ++ki) {
|
for (size_t ki = 0; ki < na->mNumScalingKeys; ++ki) {
|
||||||
const aiVectorKey& k = na->mScalingKeys[ki];
|
const aiVectorKey& k = na->mScalingKeys[ki];
|
||||||
times.push_back(to_ktime(k.mTime, anim));
|
times.push_back(to_ktime(k.mTime));
|
||||||
xval.push_back(k.mValue.x);
|
xval.push_back(k.mValue.x);
|
||||||
yval.push_back(k.mValue.y);
|
yval.push_back(k.mValue.y);
|
||||||
zval.push_back(k.mValue.z);
|
zval.push_back(k.mValue.z);
|
||||||
|
|
|
@ -437,6 +437,9 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
|
||||||
// deal with this more elegantly and with less redundancy, but right
|
// deal with this more elegantly and with less redundancy, but right
|
||||||
// now it seems unavoidable.
|
// now it seems unavoidable.
|
||||||
if (MappingInformationType == "ByVertice" && isDirect) {
|
if (MappingInformationType == "ByVertice" && isDirect) {
|
||||||
|
if (!HasElement(source, dataElementName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
std::vector<T> tempData;
|
std::vector<T> tempData;
|
||||||
ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
|
ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ public:
|
||||||
FileSystemFilter(const std::string& file, IOSystem* old)
|
FileSystemFilter(const std::string& file, IOSystem* old)
|
||||||
: mWrapped (old)
|
: mWrapped (old)
|
||||||
, mSrc_file(file)
|
, mSrc_file(file)
|
||||||
, sep(mWrapped->getOsSeparator()) {
|
, mSep(mWrapped->getOsSeparator()) {
|
||||||
ai_assert(nullptr != mWrapped);
|
ai_assert(nullptr != mWrapped);
|
||||||
|
|
||||||
// Determine base directory
|
// Determine base directory
|
||||||
|
@ -116,7 +116,7 @@ public:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns the directory separator. */
|
/** Returns the directory separator. */
|
||||||
char getOsSeparator() const {
|
char getOsSeparator() const {
|
||||||
return sep;
|
return mSep;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
@ -256,7 +256,7 @@ private:
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
tmp = mBase;
|
tmp = mBase;
|
||||||
tmp += sep;
|
tmp += mSep;
|
||||||
|
|
||||||
std::string::size_type dirsep = in.rfind('/', last_dirsep);
|
std::string::size_type dirsep = in.rfind('/', last_dirsep);
|
||||||
if (std::string::npos == dirsep) {
|
if (std::string::npos == dirsep) {
|
||||||
|
@ -298,7 +298,7 @@ private:
|
||||||
in.erase(in.begin(),it+1);
|
in.erase(in.begin(),it+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char sep = getOsSeparator();
|
const char separator = getOsSeparator();
|
||||||
for (it = in.begin(); it != in.end(); ++it) {
|
for (it = in.begin(); it != in.end(); ++it) {
|
||||||
// Exclude :// and \\, which remain untouched.
|
// Exclude :// and \\, which remain untouched.
|
||||||
// https://sourceforge.net/tracker/?func=detail&aid=3031725&group_id=226462&atid=1067632
|
// https://sourceforge.net/tracker/?func=detail&aid=3031725&group_id=226462&atid=1067632
|
||||||
|
@ -313,7 +313,7 @@ private:
|
||||||
|
|
||||||
// Cleanup path delimiters
|
// Cleanup path delimiters
|
||||||
if (*it == '/' || (*it) == '\\') {
|
if (*it == '/' || (*it) == '\\') {
|
||||||
*it = sep;
|
*it = separator;
|
||||||
|
|
||||||
// And we're removing double delimiters, frequent issue with
|
// And we're removing double delimiters, frequent issue with
|
||||||
// incorrectly composited paths ...
|
// incorrectly composited paths ...
|
||||||
|
@ -337,7 +337,7 @@ private:
|
||||||
private:
|
private:
|
||||||
IOSystem *mWrapped;
|
IOSystem *mWrapped;
|
||||||
std::string mSrc_file, mBase;
|
std::string mSrc_file, mBase;
|
||||||
char sep;
|
char mSep;
|
||||||
};
|
};
|
||||||
|
|
||||||
} //!ns Assimp
|
} //!ns Assimp
|
||||||
|
|
|
@ -73,6 +73,7 @@ GenFaceNormalsProcess::~GenFaceNormalsProcess()
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool GenFaceNormalsProcess::IsActive( unsigned int pFlags) const {
|
bool GenFaceNormalsProcess::IsActive( unsigned int pFlags) const {
|
||||||
|
force_ = (pFlags & aiProcess_ForceGenNormals) != 0;
|
||||||
return (pFlags & aiProcess_GenNormals) != 0;
|
return (pFlags & aiProcess_GenNormals) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +106,8 @@ void GenFaceNormalsProcess::Execute( aiScene* pScene) {
|
||||||
bool GenFaceNormalsProcess::GenMeshFaceNormals (aiMesh* pMesh)
|
bool GenFaceNormalsProcess::GenMeshFaceNormals (aiMesh* pMesh)
|
||||||
{
|
{
|
||||||
if (NULL != pMesh->mNormals) {
|
if (NULL != pMesh->mNormals) {
|
||||||
return false;
|
if (force_) delete[] pMesh->mNormals;
|
||||||
|
else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the mesh consists of lines and/or points but not of
|
// If the mesh consists of lines and/or points but not of
|
||||||
|
@ -134,7 +136,7 @@ bool GenFaceNormalsProcess::GenMeshFaceNormals (aiMesh* pMesh)
|
||||||
const aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]];
|
const aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]];
|
||||||
const aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]];
|
const aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]];
|
||||||
const aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices-1]];
|
const aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices-1]];
|
||||||
const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).Normalize();
|
const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe();
|
||||||
|
|
||||||
for (unsigned int i = 0;i < face.mNumIndices;++i) {
|
for (unsigned int i = 0;i < face.mNumIndices;++i) {
|
||||||
pMesh->mNormals[face.mIndices[i]] = vNor;
|
pMesh->mNormals[face.mIndices[i]] = vNor;
|
||||||
|
|
|
@ -79,6 +79,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool GenMeshFaceNormals(aiMesh* pcMesh);
|
bool GenMeshFaceNormals(aiMesh* pcMesh);
|
||||||
|
mutable bool force_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -72,6 +72,7 @@ GenVertexNormalsProcess::~GenVertexNormalsProcess() {
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool GenVertexNormalsProcess::IsActive( unsigned int pFlags) const
|
bool GenVertexNormalsProcess::IsActive( unsigned int pFlags) const
|
||||||
{
|
{
|
||||||
|
force_ = (pFlags & aiProcess_ForceGenNormals) != 0;
|
||||||
return (pFlags & aiProcess_GenSmoothNormals) != 0;
|
return (pFlags & aiProcess_GenSmoothNormals) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,8 +114,10 @@ void GenVertexNormalsProcess::Execute( aiScene* pScene)
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int meshIndex)
|
bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int meshIndex)
|
||||||
{
|
{
|
||||||
if (NULL != pMesh->mNormals)
|
if (NULL != pMesh->mNormals) {
|
||||||
return false;
|
if (force_) delete[] pMesh->mNormals;
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
|
||||||
// If the mesh consists of lines and/or points but not of
|
// If the mesh consists of lines and/or points but not of
|
||||||
// triangles or higher-order polygons the normal vectors
|
// triangles or higher-order polygons the normal vectors
|
||||||
|
@ -146,7 +149,7 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int
|
||||||
const aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]];
|
const aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]];
|
||||||
const aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]];
|
const aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]];
|
||||||
const aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices-1]];
|
const aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices-1]];
|
||||||
const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1));
|
const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe();
|
||||||
|
|
||||||
for (unsigned int i = 0;i < face.mNumIndices;++i) {
|
for (unsigned int i = 0;i < face.mNumIndices;++i) {
|
||||||
pMesh->mNormals[face.mIndices[i]] = vNor;
|
pMesh->mNormals[face.mIndices[i]] = vNor;
|
||||||
|
@ -214,17 +217,15 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int
|
||||||
vertexFinder->FindPositions( pMesh->mVertices[i] , posEpsilon, verticesFound);
|
vertexFinder->FindPositions( pMesh->mVertices[i] , posEpsilon, verticesFound);
|
||||||
|
|
||||||
aiVector3D vr = pMesh->mNormals[i];
|
aiVector3D vr = pMesh->mNormals[i];
|
||||||
ai_real vrlen = vr.Length();
|
|
||||||
|
|
||||||
aiVector3D pcNor;
|
aiVector3D pcNor;
|
||||||
for (unsigned int a = 0; a < verticesFound.size(); ++a) {
|
for (unsigned int a = 0; a < verticesFound.size(); ++a) {
|
||||||
aiVector3D v = pMesh->mNormals[verticesFound[a]];
|
aiVector3D v = pMesh->mNormals[verticesFound[a]];
|
||||||
|
|
||||||
// check whether the angle between the two normals is not too large
|
// Check whether the angle between the two normals is not too large.
|
||||||
// HACK: if v.x is qnan the dot product will become qnan, too
|
// Skip the angle check on our own normal to avoid false negatives
|
||||||
// therefore the comparison against fLimit should be false
|
// (v*v is not guaranteed to be 1.0 for all unit vectors v)
|
||||||
// in every case.
|
if (is_not_qnan(v.x) && (verticesFound[a] == i || (v * vr >= fLimit)))
|
||||||
if (v * vr >= fLimit * vrlen * v.Length())
|
|
||||||
pcNor += v;
|
pcNor += v;
|
||||||
}
|
}
|
||||||
pcNew[i] = pcNor.NormalizeSafe();
|
pcNew[i] = pcNor.NormalizeSafe();
|
||||||
|
|
|
@ -107,6 +107,7 @@ private:
|
||||||
|
|
||||||
/** Configuration option: maximum smoothing angle, in radians*/
|
/** Configuration option: maximum smoothing angle, in radians*/
|
||||||
ai_real configMaxAngle;
|
ai_real configMaxAngle;
|
||||||
|
mutable bool force_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -383,6 +383,7 @@ bool _ValidateFlags(unsigned int pFlags)
|
||||||
void Importer::FreeScene( )
|
void Importer::FreeScene( )
|
||||||
{
|
{
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
|
|
||||||
delete pimpl->mScene;
|
delete pimpl->mScene;
|
||||||
pimpl->mScene = NULL;
|
pimpl->mScene = NULL;
|
||||||
|
|
||||||
|
@ -490,9 +491,9 @@ const aiScene* Importer::ReadFileFromMemory( const void* pBuffer,
|
||||||
SetIOHandler(new MemoryIOSystem((const uint8_t*)pBuffer,pLength));
|
SetIOHandler(new MemoryIOSystem((const uint8_t*)pBuffer,pLength));
|
||||||
|
|
||||||
// read the file and recover the previous IOSystem
|
// read the file and recover the previous IOSystem
|
||||||
static const size_t BufferSize(Importer::MaxLenHint + 28);
|
static const size_t BufSize(Importer::MaxLenHint + 28);
|
||||||
char fbuff[ BufferSize ];
|
char fbuff[BufSize];
|
||||||
ai_snprintf(fbuff, BufferSize, "%s.%s",AI_MEMORYIO_MAGIC_FILENAME,pHint);
|
ai_snprintf(fbuff, BufSize, "%s.%s",AI_MEMORYIO_MAGIC_FILENAME,pHint);
|
||||||
|
|
||||||
ReadFile(fbuff,pFlags);
|
ReadFile(fbuff,pFlags);
|
||||||
SetIOHandler(io);
|
SetIOHandler(io);
|
||||||
|
@ -930,9 +931,8 @@ BaseImporter* Importer::GetImporter (const char* szExtension) const
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Find a loader plugin for a given file extension
|
// Find a loader plugin for a given file extension
|
||||||
size_t Importer::GetImporterIndex (const char* szExtension) const
|
size_t Importer::GetImporterIndex (const char* szExtension) const {
|
||||||
{
|
ai_assert(nullptr != szExtension);
|
||||||
ai_assert(szExtension);
|
|
||||||
|
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
|
|
||||||
|
@ -943,7 +943,7 @@ size_t Importer::GetImporterIndex (const char* szExtension) const
|
||||||
if (ext.empty()) {
|
if (ext.empty()) {
|
||||||
return static_cast<size_t>(-1);
|
return static_cast<size_t>(-1);
|
||||||
}
|
}
|
||||||
std::transform(ext.begin(),ext.end(), ext.begin(), tolower);
|
std::transform( ext.begin(), ext.end(), ext.begin(), ToLower<char> );
|
||||||
|
|
||||||
std::set<std::string> str;
|
std::set<std::string> str;
|
||||||
for (std::vector<BaseImporter*>::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i) {
|
for (std::vector<BaseImporter*>::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i) {
|
||||||
|
@ -970,6 +970,8 @@ void Importer::GetExtensionList(aiString& szOut) const
|
||||||
(*i)->GetExtensionList(str);
|
(*i)->GetExtensionList(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// List can be empty
|
||||||
|
if( !str.empty() ) {
|
||||||
for (std::set<std::string>::const_iterator it = str.begin();; ) {
|
for (std::set<std::string>::const_iterator it = str.begin();; ) {
|
||||||
szOut.Append("*.");
|
szOut.Append("*.");
|
||||||
szOut.Append((*it).c_str());
|
szOut.Append((*it).c_str());
|
||||||
|
@ -979,6 +981,7 @@ void Importer::GetExtensionList(aiString& szOut) const
|
||||||
}
|
}
|
||||||
szOut.Append(";");
|
szOut.Append(";");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ASSIMP_END_EXCEPTION_REGION(void);
|
ASSIMP_END_EXCEPTION_REGION(void);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,11 +120,11 @@ public:
|
||||||
SharedPostProcessInfo* mPPShared;
|
SharedPostProcessInfo* mPPShared;
|
||||||
|
|
||||||
/// The default class constructor.
|
/// The default class constructor.
|
||||||
ImporterPimpl();
|
ImporterPimpl() AI_NO_EXCEPT;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline
|
inline
|
||||||
ImporterPimpl::ImporterPimpl()
|
ImporterPimpl::ImporterPimpl() AI_NO_EXCEPT
|
||||||
: mIOHandler( nullptr )
|
: mIOHandler( nullptr )
|
||||||
, mIsDefaultHandler( false )
|
, mIsDefaultHandler( false )
|
||||||
, mProgressHandler( nullptr )
|
, mProgressHandler( nullptr )
|
||||||
|
|
|
@ -317,7 +317,7 @@ void ProcessRevolvedAreaSolid(const Schema_2x3::IfcRevolvedAreaSolid& solid, Tem
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ProcessSweptDiskSolid(const Schema_2x3::IfcSweptDiskSolid solid, TempMesh& result, ConversionData& conv)
|
void ProcessSweptDiskSolid(const Schema_2x3::IfcSweptDiskSolid &solid, TempMesh& result, ConversionData& conv)
|
||||||
{
|
{
|
||||||
const Curve* const curve = Curve::Convert(*solid.Directrix, conv);
|
const Curve* const curve = Curve::Convert(*solid.Directrix, conv);
|
||||||
if(!curve) {
|
if(!curve) {
|
||||||
|
|
|
@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/Vertex.h>
|
#include <assimp/Vertex.h>
|
||||||
#include <assimp/TinyFormatter.h>
|
#include <assimp/TinyFormatter.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -239,6 +240,19 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We should care only about used vertices, not all of them
|
||||||
|
// (this can happen due to original file vertices buffer being used by
|
||||||
|
// multiple meshes)
|
||||||
|
std::unordered_set<unsigned int> usedVertexIndices;
|
||||||
|
usedVertexIndices.reserve(pMesh->mNumVertices);
|
||||||
|
for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
|
||||||
|
{
|
||||||
|
aiFace& face = pMesh->mFaces[a];
|
||||||
|
for( unsigned int b = 0; b < face.mNumIndices; b++) {
|
||||||
|
usedVertexIndices.insert(face.mIndices[b]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// We'll never have more vertices afterwards.
|
// We'll never have more vertices afterwards.
|
||||||
std::vector<Vertex> uniqueVertices;
|
std::vector<Vertex> uniqueVertices;
|
||||||
uniqueVertices.reserve( pMesh->mNumVertices);
|
uniqueVertices.reserve( pMesh->mNumVertices);
|
||||||
|
@ -292,6 +306,10 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
|
||||||
|
|
||||||
// Now check each vertex if it brings something new to the table
|
// Now check each vertex if it brings something new to the table
|
||||||
for( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
|
for( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
|
||||||
|
if (usedVertexIndices.find(a) == usedVertexIndices.end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// collect the vertex data
|
// collect the vertex data
|
||||||
Vertex v(pMesh,a);
|
Vertex v(pMesh,a);
|
||||||
|
|
||||||
|
|
|
@ -113,14 +113,14 @@ enum PrePostBehaviour
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \brief Data structure for a LWO animation keyframe
|
/** \brief Data structure for a LWO animation keyframe
|
||||||
*/
|
*/
|
||||||
struct Key
|
struct Key {
|
||||||
{
|
Key() AI_NO_EXCEPT
|
||||||
Key()
|
: time()
|
||||||
: time(),
|
, value()
|
||||||
value(),
|
, inter(IT_LINE)
|
||||||
inter (IT_LINE),
|
, params() {
|
||||||
params()
|
// empty
|
||||||
{}
|
}
|
||||||
|
|
||||||
//! Current time
|
//! Current time
|
||||||
double time;
|
double time;
|
||||||
|
@ -144,17 +144,16 @@ struct Key
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \brief Data structure for a LWO animation envelope
|
/** \brief Data structure for a LWO animation envelope
|
||||||
*/
|
*/
|
||||||
struct Envelope
|
struct Envelope {
|
||||||
{
|
Envelope() AI_NO_EXCEPT
|
||||||
Envelope()
|
|
||||||
: index()
|
: index()
|
||||||
, type(EnvelopeType_Unknown)
|
, type(EnvelopeType_Unknown)
|
||||||
, pre(PrePostBehaviour_Constant)
|
, pre(PrePostBehaviour_Constant)
|
||||||
, post(PrePostBehaviour_Constant)
|
, post(PrePostBehaviour_Constant)
|
||||||
|
|
||||||
, old_first(0)
|
, old_first(0)
|
||||||
, old_last (0)
|
, old_last(0) {
|
||||||
{}
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
//! Index of this envelope
|
//! Index of this envelope
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
|
@ -162,7 +161,7 @@ struct Envelope
|
||||||
//! Type of envelope
|
//! Type of envelope
|
||||||
EnvelopeType type;
|
EnvelopeType type;
|
||||||
|
|
||||||
//! Pre and post-behaviour
|
//! Pre- and post-behavior
|
||||||
PrePostBehaviour pre,post;
|
PrePostBehaviour pre,post;
|
||||||
|
|
||||||
//! Keyframes for this envelope
|
//! Keyframes for this envelope
|
||||||
|
|
|
@ -261,14 +261,14 @@ namespace LWO {
|
||||||
* \note We can't use the code in SmoothingGroups.inl here - the mesh
|
* \note We can't use the code in SmoothingGroups.inl here - the mesh
|
||||||
* structures of 3DS/ASE and LWO are too different.
|
* structures of 3DS/ASE and LWO are too different.
|
||||||
*/
|
*/
|
||||||
struct Face : public aiFace
|
struct Face : public aiFace {
|
||||||
{
|
|
||||||
//! Default construction
|
//! Default construction
|
||||||
Face()
|
Face() AI_NO_EXCEPT
|
||||||
: surfaceIndex( 0 )
|
: surfaceIndex( 0 )
|
||||||
, smoothGroup( 0 )
|
, smoothGroup( 0 )
|
||||||
, type (AI_LWO_FACE)
|
, type( AI_LWO_FACE ) {
|
||||||
{}
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
//! Construction from given type
|
//! Construction from given type
|
||||||
explicit Face(uint32_t _type)
|
explicit Face(uint32_t _type)
|
||||||
|
|
|
@ -253,7 +253,8 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
|
||||||
pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_TEXOP(type,cur));
|
pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_TEXOP(type,cur));
|
||||||
|
|
||||||
// setup the mapping mode
|
// setup the mapping mode
|
||||||
pcMat->AddProperty<int>((int*)&mapping,1,AI_MATKEY_MAPPING(type,cur));
|
int mapping_ = static_cast<int>(mapping);
|
||||||
|
pcMat->AddProperty<int>(&mapping_, 1, AI_MATKEY_MAPPING(type, cur));
|
||||||
|
|
||||||
// add the u-wrapping
|
// add the u-wrapping
|
||||||
temp = (unsigned int)GetMapMode(texture.wrapModeWidth);
|
temp = (unsigned int)GetMapMode(texture.wrapModeWidth);
|
||||||
|
@ -365,7 +366,8 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
|
||||||
}
|
}
|
||||||
if (surf.mMaximumSmoothAngle <= 0.0)
|
if (surf.mMaximumSmoothAngle <= 0.0)
|
||||||
m = aiShadingMode_Flat;
|
m = aiShadingMode_Flat;
|
||||||
pcMat->AddProperty((int*)&m,1,AI_MATKEY_SHADING_MODEL);
|
int m_ = static_cast<int>(m);
|
||||||
|
pcMat->AddProperty(&m_, 1, AI_MATKEY_SHADING_MODEL);
|
||||||
|
|
||||||
// (the diffuse value is just a scaling factor)
|
// (the diffuse value is just a scaling factor)
|
||||||
// If a diffuse texture is set, we set this value to 1.0
|
// If a diffuse texture is set, we set this value to 1.0
|
||||||
|
|
|
@ -120,7 +120,7 @@ public:
|
||||||
{
|
{
|
||||||
unsigned int mBone; ///< Index of the bone
|
unsigned int mBone; ///< Index of the bone
|
||||||
float mWeight; ///< Weight of that bone on this vertex
|
float mWeight; ///< Weight of that bone on this vertex
|
||||||
Weight()
|
Weight() AI_NO_EXCEPT
|
||||||
: mBone(0)
|
: mBone(0)
|
||||||
, mWeight(0.0f)
|
, mWeight(0.0f)
|
||||||
{ }
|
{ }
|
||||||
|
|
|
@ -125,7 +125,7 @@ enum AlphaTestFunc
|
||||||
*/
|
*/
|
||||||
struct ShaderMapBlock
|
struct ShaderMapBlock
|
||||||
{
|
{
|
||||||
ShaderMapBlock()
|
ShaderMapBlock() AI_NO_EXCEPT
|
||||||
: blend_src (BLEND_NONE)
|
: blend_src (BLEND_NONE)
|
||||||
, blend_dest (BLEND_NONE)
|
, blend_dest (BLEND_NONE)
|
||||||
, alpha_test (AT_NONE)
|
, alpha_test (AT_NONE)
|
||||||
|
@ -150,7 +150,7 @@ struct ShaderMapBlock
|
||||||
*/
|
*/
|
||||||
struct ShaderDataBlock
|
struct ShaderDataBlock
|
||||||
{
|
{
|
||||||
ShaderDataBlock()
|
ShaderDataBlock() AI_NO_EXCEPT
|
||||||
: cull (CULL_CW)
|
: cull (CULL_CW)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
|
@ -192,14 +192,14 @@ typedef std::vector< FrameDesc > FrameList;
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Represents a vertex descriptor in a MD5 file
|
/** Represents a vertex descriptor in a MD5 file
|
||||||
*/
|
*/
|
||||||
struct VertexDesc
|
struct VertexDesc {
|
||||||
{
|
VertexDesc() AI_NO_EXCEPT
|
||||||
VertexDesc()
|
|
||||||
: mFirstWeight(0)
|
: mFirstWeight(0)
|
||||||
, mNumWeights (0)
|
, mNumWeights(0) {
|
||||||
{}
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
//! UV cordinate of the vertex
|
//! UV coordinate of the vertex
|
||||||
aiVector2D mUV;
|
aiVector2D mUV;
|
||||||
|
|
||||||
//! Index of the first weight of the vertex in
|
//! Index of the first weight of the vertex in
|
||||||
|
|
|
@ -61,7 +61,6 @@ http://themdcfile.planetwolfenstein.gamespy.com/MDC_File_Format.pdf
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace MDC {
|
namespace MDC {
|
||||||
|
|
||||||
|
|
||||||
// to make it easier for us, we test the magic word against both "endianesses"
|
// to make it easier for us, we test the magic word against both "endianesses"
|
||||||
#define AI_MDC_MAGIC_NUMBER_BE AI_MAKE_MAGIC("CPDI")
|
#define AI_MDC_MAGIC_NUMBER_BE AI_MAKE_MAGIC("CPDI")
|
||||||
#define AI_MDC_MAGIC_NUMBER_LE AI_MAKE_MAGIC("IDPC")
|
#define AI_MDC_MAGIC_NUMBER_LE AI_MAKE_MAGIC("IDPC")
|
||||||
|
@ -79,8 +78,7 @@ namespace MDC {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \brief Data structure for a MDC file's main header
|
/** \brief Data structure for a MDC file's main header
|
||||||
*/
|
*/
|
||||||
struct Header
|
struct Header {
|
||||||
{
|
|
||||||
uint32_t ulIdent ;
|
uint32_t ulIdent ;
|
||||||
uint32_t ulVersion ;
|
uint32_t ulVersion ;
|
||||||
char ucName [ AI_MDC_MAXQPATH ] ;
|
char ucName [ AI_MDC_MAXQPATH ] ;
|
||||||
|
@ -100,8 +98,7 @@ struct Header
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \brief Data structure for a MDC file's surface header
|
/** \brief Data structure for a MDC file's surface header
|
||||||
*/
|
*/
|
||||||
struct Surface
|
struct Surface {
|
||||||
{
|
|
||||||
uint32_t ulIdent ;
|
uint32_t ulIdent ;
|
||||||
char ucName [ AI_MDC_MAXQPATH ] ;
|
char ucName [ AI_MDC_MAXQPATH ] ;
|
||||||
uint32_t ulFlags ;
|
uint32_t ulFlags ;
|
||||||
|
@ -118,23 +115,22 @@ struct Surface
|
||||||
uint32_t ulOffsetFrameBaseFrames ;
|
uint32_t ulOffsetFrameBaseFrames ;
|
||||||
uint32_t ulOffsetFrameCompFrames ;
|
uint32_t ulOffsetFrameCompFrames ;
|
||||||
uint32_t ulOffsetEnd;
|
uint32_t ulOffsetEnd;
|
||||||
Surface()
|
Surface() AI_NO_EXCEPT
|
||||||
: ulIdent(),
|
: ulIdent()
|
||||||
ulFlags(),
|
, ulFlags()
|
||||||
ulNumCompFrames(),
|
, ulNumCompFrames()
|
||||||
ulNumBaseFrames(),
|
, ulNumBaseFrames()
|
||||||
ulNumShaders(),
|
, ulNumShaders()
|
||||||
ulNumVertices(),
|
, ulNumVertices()
|
||||||
ulNumTriangles(),
|
, ulNumTriangles()
|
||||||
ulOffsetTriangles(),
|
, ulOffsetTriangles()
|
||||||
ulOffsetShaders(),
|
, ulOffsetShaders()
|
||||||
ulOffsetTexCoords(),
|
, ulOffsetTexCoords()
|
||||||
ulOffsetBaseVerts(),
|
, ulOffsetBaseVerts()
|
||||||
ulOffsetCompVerts(),
|
, ulOffsetCompVerts()
|
||||||
ulOffsetFrameBaseFrames(),
|
, ulOffsetFrameBaseFrames()
|
||||||
ulOffsetFrameCompFrames(),
|
, ulOffsetFrameCompFrames()
|
||||||
ulOffsetEnd()
|
, ulOffsetEnd() {
|
||||||
{
|
|
||||||
ucName[AI_MDC_MAXQPATH-1] = '\0';
|
ucName[AI_MDC_MAXQPATH-1] = '\0';
|
||||||
}
|
}
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
@ -142,8 +138,7 @@ struct Surface
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \brief Data structure for a MDC frame
|
/** \brief Data structure for a MDC frame
|
||||||
*/
|
*/
|
||||||
struct Frame
|
struct Frame {
|
||||||
{
|
|
||||||
//! bounding box minimum coords
|
//! bounding box minimum coords
|
||||||
aiVector3D bboxMin ;
|
aiVector3D bboxMin ;
|
||||||
|
|
||||||
|
@ -163,24 +158,21 @@ struct Frame
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \brief Data structure for a MDC triangle
|
/** \brief Data structure for a MDC triangle
|
||||||
*/
|
*/
|
||||||
struct Triangle
|
struct Triangle {
|
||||||
{
|
|
||||||
uint32_t aiIndices[3];
|
uint32_t aiIndices[3];
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \brief Data structure for a MDC texture coordinate
|
/** \brief Data structure for a MDC texture coordinate
|
||||||
*/
|
*/
|
||||||
struct TexturCoord
|
struct TexturCoord {
|
||||||
{
|
|
||||||
float u,v;
|
float u,v;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \brief Data structure for a MDC base vertex
|
/** \brief Data structure for a MDC base vertex
|
||||||
*/
|
*/
|
||||||
struct BaseVertex
|
struct BaseVertex {
|
||||||
{
|
|
||||||
int16_t x,y,z;
|
int16_t x,y,z;
|
||||||
uint16_t normal;
|
uint16_t normal;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
@ -188,25 +180,20 @@ struct BaseVertex
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \brief Data structure for a MDC compressed vertex
|
/** \brief Data structure for a MDC compressed vertex
|
||||||
*/
|
*/
|
||||||
struct CompressedVertex
|
struct CompressedVertex {
|
||||||
{
|
|
||||||
uint8_t xd,yd,zd,nd;
|
uint8_t xd,yd,zd,nd;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \brief Data structure for a MDC shader
|
/** \brief Data structure for a MDC shader
|
||||||
*/
|
*/
|
||||||
struct Shader
|
struct Shader {
|
||||||
{
|
|
||||||
char ucName [ AI_MDC_MAXQPATH ] ;
|
char ucName [ AI_MDC_MAXQPATH ] ;
|
||||||
uint32_t ulPath;
|
uint32_t ulPath;
|
||||||
|
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
#include <assimp/Compiler/poppack1.h>
|
#include <assimp/Compiler/poppack1.h>
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Build a floating point vertex from the compressed data in MDC files
|
/** Build a floating point vertex from the compressed data in MDC files
|
||||||
*/
|
*/
|
||||||
|
@ -215,6 +202,7 @@ void BuildVertex(const Frame& frame,
|
||||||
const CompressedVertex& cvert,
|
const CompressedVertex& cvert,
|
||||||
aiVector3D& vXYZOut,
|
aiVector3D& vXYZOut,
|
||||||
aiVector3D& vNorOut);
|
aiVector3D& vNorOut);
|
||||||
}}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // !! AI_MDCFILEHELPER_H_INC
|
#endif // !! AI_MDCFILEHELPER_H_INC
|
||||||
|
|
|
@ -434,11 +434,13 @@ void MDCImporter::InternReadFile(
|
||||||
else if (1 == pScene->mNumMeshes)
|
else if (1 == pScene->mNumMeshes)
|
||||||
{
|
{
|
||||||
pScene->mRootNode = new aiNode();
|
pScene->mRootNode = new aiNode();
|
||||||
|
if ( nullptr != pScene->mMeshes[0] ) {
|
||||||
pScene->mRootNode->mName = pScene->mMeshes[0]->mName;
|
pScene->mRootNode->mName = pScene->mMeshes[0]->mName;
|
||||||
pScene->mRootNode->mNumMeshes = 1;
|
pScene->mRootNode->mNumMeshes = 1;
|
||||||
pScene->mRootNode->mMeshes = new unsigned int[1];
|
pScene->mRootNode->mMeshes = new unsigned int[1];
|
||||||
pScene->mRootNode->mMeshes[0] = 0;
|
pScene->mRootNode->mMeshes[0] = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pScene->mRootNode = new aiNode();
|
pScene->mRootNode = new aiNode();
|
||||||
|
|
|
@ -717,11 +717,9 @@ struct GroupFrame
|
||||||
*/
|
*/
|
||||||
struct IntFace_MDL7 {
|
struct IntFace_MDL7 {
|
||||||
// provide a constructor for our own convenience
|
// provide a constructor for our own convenience
|
||||||
IntFace_MDL7()
|
IntFace_MDL7() AI_NO_EXCEPT {
|
||||||
{
|
::memset( mIndices, 0, sizeof(uint32_t) *3);
|
||||||
// set everything to zero
|
::memset( iMatIndex, 0, sizeof( unsigned int) *2);
|
||||||
mIndices[0] = mIndices[1] = mIndices[2] = 0;
|
|
||||||
iMatIndex[0] = iMatIndex[1] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Vertex indices
|
//! Vertex indices
|
||||||
|
@ -737,13 +735,11 @@ struct IntFace_MDL7 {
|
||||||
* which has been created from two single materials along with the
|
* which has been created from two single materials along with the
|
||||||
* original material indices.
|
* original material indices.
|
||||||
*/
|
*/
|
||||||
struct IntMaterial_MDL7
|
struct IntMaterial_MDL7 {
|
||||||
{
|
|
||||||
// provide a constructor for our own convenience
|
// provide a constructor for our own convenience
|
||||||
IntMaterial_MDL7()
|
IntMaterial_MDL7() AI_NO_EXCEPT
|
||||||
{
|
: pcMat( nullptr ) {
|
||||||
pcMat = NULL;
|
::memset( iOldMatIndices, 0, sizeof(unsigned int) *2);
|
||||||
iOldMatIndices[0] = iOldMatIndices[1] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Material instance
|
//! Material instance
|
||||||
|
@ -761,7 +757,7 @@ struct IntMaterial_MDL7
|
||||||
struct IntBone_MDL7 : aiBone
|
struct IntBone_MDL7 : aiBone
|
||||||
{
|
{
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
IntBone_MDL7() : iParent (0xffff)
|
IntBone_MDL7() AI_NO_EXCEPT : iParent (0xffff)
|
||||||
{
|
{
|
||||||
pkeyPositions.reserve(30);
|
pkeyPositions.reserve(30);
|
||||||
pkeyScalings.reserve(30);
|
pkeyScalings.reserve(30);
|
||||||
|
@ -806,12 +802,12 @@ struct IntFrameInfo_MDL7
|
||||||
struct IntGroupInfo_MDL7
|
struct IntGroupInfo_MDL7
|
||||||
{
|
{
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
IntGroupInfo_MDL7()
|
IntGroupInfo_MDL7() AI_NO_EXCEPT
|
||||||
: iIndex(0)
|
: iIndex(0)
|
||||||
, pcGroup(NULL)
|
, pcGroup(nullptr)
|
||||||
, pcGroupUVs(NULL)
|
, pcGroupUVs(nullptr)
|
||||||
, pcGroupTris(NULL)
|
, pcGroupTris(nullptr)
|
||||||
, pcGroupVerts(NULL)
|
, pcGroupVerts(nullptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//! Construction from an existing group header
|
//! Construction from an existing group header
|
||||||
|
@ -843,7 +839,7 @@ struct IntGroupInfo_MDL7
|
||||||
//! Holds the data that belongs to a MDL7 mesh group
|
//! Holds the data that belongs to a MDL7 mesh group
|
||||||
struct IntGroupData_MDL7
|
struct IntGroupData_MDL7
|
||||||
{
|
{
|
||||||
IntGroupData_MDL7()
|
IntGroupData_MDL7() AI_NO_EXCEPT
|
||||||
: bNeed2UV(false)
|
: bNeed2UV(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -872,10 +868,9 @@ struct IntGroupData_MDL7
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
//! Holds data from an MDL7 file that is shared by all mesh groups
|
//! Holds data from an MDL7 file that is shared by all mesh groups
|
||||||
struct IntSharedData_MDL7
|
struct IntSharedData_MDL7 {
|
||||||
{
|
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
IntSharedData_MDL7()
|
IntSharedData_MDL7() AI_NO_EXCEPT
|
||||||
: apcOutBones(),
|
: apcOutBones(),
|
||||||
iNum()
|
iNum()
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,6 +41,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "MMDPmxParser.h"
|
#include "MMDPmxParser.h"
|
||||||
|
#include <assimp/StringUtils.h>
|
||||||
#include "../contrib/utf8cpp/source/utf8.h"
|
#include "../contrib/utf8cpp/source/utf8.h"
|
||||||
#include <assimp/Exceptional.h>
|
#include <assimp/Exceptional.h>
|
||||||
|
|
||||||
|
@ -118,7 +119,7 @@ namespace pmx
|
||||||
stream->read((char*) &count, sizeof(uint8_t));
|
stream->read((char*) &count, sizeof(uint8_t));
|
||||||
if (count < 8)
|
if (count < 8)
|
||||||
{
|
{
|
||||||
throw;
|
throw DeadlyImportError("MMD: invalid size");
|
||||||
}
|
}
|
||||||
stream->read((char*) &encoding, sizeof(uint8_t));
|
stream->read((char*) &encoding, sizeof(uint8_t));
|
||||||
stream->read((char*) &uv, sizeof(uint8_t));
|
stream->read((char*) &uv, sizeof(uint8_t));
|
||||||
|
@ -395,7 +396,7 @@ namespace pmx
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw;
|
throw DeadlyImportError("MMD: unknown morth type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,7 +477,7 @@ namespace pmx
|
||||||
{
|
{
|
||||||
// 未実装
|
// 未実装
|
||||||
std::cerr << "Not Implemented Exception" << std::endl;
|
std::cerr << "Not Implemented Exception" << std::endl;
|
||||||
throw;
|
throw DeadlyImportError("MMD: Not Implemented Exception");
|
||||||
}
|
}
|
||||||
|
|
||||||
void PmxModel::Init()
|
void PmxModel::Init()
|
||||||
|
@ -516,14 +517,14 @@ namespace pmx
|
||||||
if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20)
|
if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20)
|
||||||
{
|
{
|
||||||
std::cerr << "invalid magic number." << std::endl;
|
std::cerr << "invalid magic number." << std::endl;
|
||||||
throw;
|
throw DeadlyImportError("MMD: invalid magic number.");
|
||||||
}
|
}
|
||||||
// バージョン
|
// バージョン
|
||||||
stream->read((char*) &version, sizeof(float));
|
stream->read((char*) &version, sizeof(float));
|
||||||
if (version != 2.0f && version != 2.1f)
|
if (version != 2.0f && version != 2.1f)
|
||||||
{
|
{
|
||||||
std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl;
|
std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl;
|
||||||
throw;
|
throw DeadlyImportError("MMD: this is not ver2.0 or ver2.1 but " + to_string(version));
|
||||||
}
|
}
|
||||||
// ファイル設定
|
// ファイル設定
|
||||||
this->setting.Read(stream);
|
this->setting.Read(stream);
|
||||||
|
@ -605,34 +606,5 @@ namespace pmx
|
||||||
{
|
{
|
||||||
this->joints[i].Read(stream, &setting);
|
this->joints[i].Read(stream, &setting);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (this->version == 2.1f)
|
|
||||||
//{
|
|
||||||
// stream->read((char*) &this->soft_body_count, sizeof(int));
|
|
||||||
// this->soft_bodies = mmd::make_unique<PmxSoftBody []>(this->soft_body_count);
|
|
||||||
// for (int i = 0; i < this->soft_body_count; i++)
|
|
||||||
// {
|
|
||||||
// this->soft_bodies[i].Read(stream, &setting);
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//std::unique_ptr<PmxModel> ReadFromFile(const char *filename)
|
|
||||||
//{
|
|
||||||
// auto stream = std::ifstream(filename, std::ios_base::binary);
|
|
||||||
// auto pmx = PmxModel::ReadFromStream(&stream);
|
|
||||||
// if (!stream.eof())
|
|
||||||
// {
|
|
||||||
// std::cerr << "don't reach the end of file." << std::endl;
|
|
||||||
// }
|
|
||||||
// stream.close();
|
|
||||||
// return pmx;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//std::unique_ptr<PmxModel> ReadFromStream(std::istream *stream)
|
|
||||||
//{
|
|
||||||
// auto pmx = mmd::make_unique<PmxModel>();
|
|
||||||
// pmx->Read(stream);
|
|
||||||
// return pmx;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ aiReturn aiGetMaterialProperty(const aiMaterial* pMat,
|
||||||
|
|
||||||
if (prop /* just for safety ... */
|
if (prop /* just for safety ... */
|
||||||
&& 0 == strcmp( prop->mKey.data, pKey )
|
&& 0 == strcmp( prop->mKey.data, pKey )
|
||||||
&& (UINT_MAX == type || prop->mSemantic == type) /* UINT_MAX is a wildcard, but this is undocumented :-) */
|
&& (UINT_MAX == type || prop->mSemantic == type) /* UINT_MAX is a wild-card, but this is undocumented :-) */
|
||||||
&& (UINT_MAX == index || prop->mIndex == index))
|
&& (UINT_MAX == index || prop->mIndex == index))
|
||||||
{
|
{
|
||||||
*pPropOut = pMat->mProperties[i];
|
*pPropOut = pMat->mProperties[i];
|
||||||
|
@ -314,7 +314,7 @@ aiReturn aiGetMaterialString(const aiMaterial* pMat,
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Get the number of textures on a particular texture stack
|
// Get the number of textures on a particular texture stack
|
||||||
ASSIMP_API unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial* pMat,
|
unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial* pMat,
|
||||||
C_ENUM aiTextureType type)
|
C_ENUM aiTextureType type)
|
||||||
{
|
{
|
||||||
ai_assert (pMat != NULL);
|
ai_assert (pMat != NULL);
|
||||||
|
@ -347,15 +347,18 @@ aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
|
||||||
unsigned int* flags /*= NULL*/
|
unsigned int* flags /*= NULL*/
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != mat && NULL != path);
|
ai_assert( NULL != mat );
|
||||||
|
ai_assert( NULL != path );
|
||||||
|
|
||||||
// Get the path to the texture
|
// Get the path to the texture
|
||||||
if (AI_SUCCESS != aiGetMaterialString(mat,AI_MATKEY_TEXTURE(type,index),path)) {
|
if (AI_SUCCESS != aiGetMaterialString(mat,AI_MATKEY_TEXTURE(type,index),path)) {
|
||||||
return AI_FAILURE;
|
return AI_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine mapping type
|
// Determine mapping type
|
||||||
aiTextureMapping mapping = aiTextureMapping_UV;
|
int mapping_ = static_cast<int>(aiTextureMapping_UV);
|
||||||
aiGetMaterialInteger(mat,AI_MATKEY_MAPPING(type,index),(int*)&mapping);
|
aiGetMaterialInteger(mat,AI_MATKEY_MAPPING(type,index), &mapping_);
|
||||||
|
aiTextureMapping mapping = static_cast<aiTextureMapping>(mapping_);
|
||||||
if (_mapping)
|
if (_mapping)
|
||||||
*_mapping = mapping;
|
*_mapping = mapping;
|
||||||
|
|
||||||
|
@ -380,15 +383,17 @@ aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
|
||||||
if (flags){
|
if (flags){
|
||||||
aiGetMaterialInteger(mat,AI_MATKEY_TEXFLAGS(type,index),(int*)flags);
|
aiGetMaterialInteger(mat,AI_MATKEY_TEXFLAGS(type,index),(int*)flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
return AI_SUCCESS;
|
return AI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const unsigned int DefaultNumAllocated = 5;
|
static const unsigned int DefaultNumAllocated = 5;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Construction. Actually the one and only way to get an aiMaterial instance
|
// Construction. Actually the one and only way to get an aiMaterial instance
|
||||||
aiMaterial::aiMaterial()
|
aiMaterial::aiMaterial()
|
||||||
: mProperties( NULL )
|
: mProperties( nullptr )
|
||||||
, mNumProperties( 0 )
|
, mNumProperties( 0 )
|
||||||
, mNumAllocated( DefaultNumAllocated ) {
|
, mNumAllocated( DefaultNumAllocated ) {
|
||||||
// Allocate 5 entries by default
|
// Allocate 5 entries by default
|
||||||
|
@ -403,6 +408,14 @@ aiMaterial::~aiMaterial()
|
||||||
delete[] mProperties;
|
delete[] mProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
aiString aiMaterial::GetName() {
|
||||||
|
aiString name;
|
||||||
|
Get(AI_MATKEY_NAME, name);
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void aiMaterial::Clear()
|
void aiMaterial::Clear()
|
||||||
{
|
{
|
||||||
|
@ -417,11 +430,9 @@ void aiMaterial::Clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiReturn aiMaterial::RemoveProperty (const char* pKey,unsigned int type,
|
aiReturn aiMaterial::RemoveProperty ( const char* pKey,unsigned int type, unsigned int index )
|
||||||
unsigned int index
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
ai_assert(NULL != pKey);
|
ai_assert( nullptr != pKey );
|
||||||
|
|
||||||
for (unsigned int i = 0; i < mNumProperties;++i) {
|
for (unsigned int i = 0; i < mNumProperties;++i) {
|
||||||
aiMaterialProperty* prop = mProperties[i];
|
aiMaterialProperty* prop = mProperties[i];
|
||||||
|
@ -460,10 +471,11 @@ aiReturn aiMaterial::AddBinaryProperty (const void* pInput,
|
||||||
if ( 0 == pSizeInBytes ) {
|
if ( 0 == pSizeInBytes ) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// first search the list whether there is already an entry with this key
|
// first search the list whether there is already an entry with this key
|
||||||
unsigned int iOutIndex = UINT_MAX;
|
unsigned int iOutIndex( UINT_MAX );
|
||||||
for ( unsigned int i = 0; i < mNumProperties; ++i ) {
|
for ( unsigned int i = 0; i < mNumProperties; ++i ) {
|
||||||
aiMaterialProperty* prop = mProperties[i];
|
aiMaterialProperty *prop( mProperties[ i ] );
|
||||||
|
|
||||||
if (prop /* just for safety */ && !strcmp( prop->mKey.data, pKey ) &&
|
if (prop /* just for safety */ && !strcmp( prop->mKey.data, pKey ) &&
|
||||||
prop->mSemantic == type && prop->mIndex == index){
|
prop->mSemantic == type && prop->mIndex == index){
|
||||||
|
@ -515,6 +527,7 @@ aiReturn aiMaterial::AddBinaryProperty (const void* pInput,
|
||||||
}
|
}
|
||||||
// push back ...
|
// push back ...
|
||||||
mProperties[mNumProperties++] = pcNew;
|
mProperties[mNumProperties++] = pcNew;
|
||||||
|
|
||||||
return AI_SUCCESS;
|
return AI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,41 +76,36 @@ using namespace std;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Default constructor
|
// Default constructor
|
||||||
ObjFileImporter::ObjFileImporter() :
|
ObjFileImporter::ObjFileImporter()
|
||||||
m_Buffer(),
|
: m_Buffer()
|
||||||
m_pRootObject( NULL ),
|
, m_pRootObject( nullptr )
|
||||||
m_strAbsPath( "" )
|
, m_strAbsPath( "" ) {
|
||||||
{
|
|
||||||
DefaultIOSystem io;
|
DefaultIOSystem io;
|
||||||
m_strAbsPath = io.getOsSeparator();
|
m_strAbsPath = io.getOsSeparator();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor.
|
// Destructor.
|
||||||
ObjFileImporter::~ObjFileImporter()
|
ObjFileImporter::~ObjFileImporter() {
|
||||||
{
|
|
||||||
delete m_pRootObject;
|
delete m_pRootObject;
|
||||||
m_pRootObject = NULL;
|
m_pRootObject = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns true, if file is an obj file.
|
// Returns true, if file is an obj file.
|
||||||
bool ObjFileImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler , bool checkSig ) const
|
bool ObjFileImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler , bool checkSig ) const {
|
||||||
{
|
if(!checkSig) {
|
||||||
if(!checkSig) //Check File Extension
|
//Check File Extension
|
||||||
{
|
|
||||||
return SimpleExtensionCheck(pFile,"obj");
|
return SimpleExtensionCheck(pFile,"obj");
|
||||||
}
|
} else {
|
||||||
else //Check file Header
|
// Check file Header
|
||||||
{
|
|
||||||
static const char *pTokens[] = { "mtllib", "usemtl", "v ", "vt ", "vn ", "o ", "g ", "s ", "f " };
|
static const char *pTokens[] = { "mtllib", "usemtl", "v ", "vt ", "vn ", "o ", "g ", "s ", "f " };
|
||||||
return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 9 );
|
return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 9, 200, false, true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const aiImporterDesc* ObjFileImporter::GetInfo () const
|
const aiImporterDesc* ObjFileImporter::GetInfo () const {
|
||||||
{
|
|
||||||
return &desc;
|
return &desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,12 +210,30 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene
|
||||||
ai_assert(false);
|
ai_assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pModel->m_Objects.size() > 0) {
|
||||||
|
|
||||||
|
unsigned int meshCount = 0;
|
||||||
|
unsigned int childCount = 0;
|
||||||
|
|
||||||
|
for(size_t index = 0; index < pModel->m_Objects.size(); ++index) {
|
||||||
|
if(pModel->m_Objects[index]) {
|
||||||
|
++childCount;
|
||||||
|
meshCount += (unsigned int)pModel->m_Objects[index]->m_Meshes.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate space for the child nodes on the root node
|
||||||
|
pScene->mRootNode->mChildren = new aiNode*[ childCount ];
|
||||||
|
|
||||||
// Create nodes for the whole scene
|
// Create nodes for the whole scene
|
||||||
std::vector<aiMesh*> MeshArray;
|
std::vector<aiMesh*> MeshArray;
|
||||||
|
MeshArray.reserve(meshCount);
|
||||||
for (size_t index = 0; index < pModel->m_Objects.size(); ++index) {
|
for (size_t index = 0; index < pModel->m_Objects.size(); ++index) {
|
||||||
createNodes(pModel, pModel->m_Objects[index], pScene->mRootNode, pScene, MeshArray);
|
createNodes(pModel, pModel->m_Objects[index], pScene->mRootNode, pScene, MeshArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ai_assert(pScene->mRootNode->mNumChildren == childCount);
|
||||||
|
|
||||||
// Create mesh pointer buffer for this scene
|
// Create mesh pointer buffer for this scene
|
||||||
if (pScene->mNumMeshes > 0) {
|
if (pScene->mNumMeshes > 0) {
|
||||||
pScene->mMeshes = new aiMesh*[MeshArray.size()];
|
pScene->mMeshes = new aiMesh*[MeshArray.size()];
|
||||||
|
@ -231,6 +244,46 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene
|
||||||
|
|
||||||
// Create all materials
|
// Create all materials
|
||||||
createMaterials(pModel, pScene);
|
createMaterials(pModel, pScene);
|
||||||
|
}else {
|
||||||
|
if (pModel->m_Vertices.empty()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<aiMesh> mesh( new aiMesh );
|
||||||
|
mesh->mPrimitiveTypes = aiPrimitiveType_POINT;
|
||||||
|
unsigned int n = pModel->m_Vertices.size();
|
||||||
|
mesh->mNumVertices = n;
|
||||||
|
|
||||||
|
mesh->mVertices = new aiVector3D[n];
|
||||||
|
memcpy(mesh->mVertices, pModel->m_Vertices.data(), n*sizeof(aiVector3D) );
|
||||||
|
|
||||||
|
if ( !pModel->m_Normals.empty() ) {
|
||||||
|
mesh->mNormals = new aiVector3D[n];
|
||||||
|
if (pModel->m_Normals.size() < n) {
|
||||||
|
throw DeadlyImportError("OBJ: vertex normal index out of range");
|
||||||
|
}
|
||||||
|
memcpy(mesh->mNormals, pModel->m_Normals.data(), n*sizeof(aiVector3D));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !pModel->m_VertexColors.empty() ){
|
||||||
|
mesh->mColors[0] = new aiColor4D[mesh->mNumVertices];
|
||||||
|
for (unsigned int i = 0; i < n; ++i) {
|
||||||
|
if (i < pModel->m_VertexColors.size() ) {
|
||||||
|
const aiVector3D& color = pModel->m_VertexColors[i];
|
||||||
|
mesh->mColors[0][i] = aiColor4D(color.x, color.y, color.z, 1.0);
|
||||||
|
}else {
|
||||||
|
throw DeadlyImportError("OBJ: vertex color index out of range");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pScene->mRootNode->mNumMeshes = 1;
|
||||||
|
pScene->mRootNode->mMeshes = new unsigned int[1];
|
||||||
|
pScene->mRootNode->mMeshes[0] = 0;
|
||||||
|
pScene->mMeshes = new aiMesh*[1];
|
||||||
|
pScene->mNumMeshes = 1;
|
||||||
|
pScene->mMeshes[0] = mesh.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -251,9 +304,8 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile
|
||||||
pNode->mName = pObject->m_strObjName;
|
pNode->mName = pObject->m_strObjName;
|
||||||
|
|
||||||
// If we have a parent node, store it
|
// If we have a parent node, store it
|
||||||
if( pParent != NULL ) {
|
ai_assert( NULL != pParent );
|
||||||
appendChildToParentNode( pParent, pNode );
|
appendChildToParentNode( pParent, pNode );
|
||||||
}
|
|
||||||
|
|
||||||
for ( size_t i=0; i< pObject->m_Meshes.size(); ++i ) {
|
for ( size_t i=0; i< pObject->m_Meshes.size(); ++i ) {
|
||||||
unsigned int meshId = pObject->m_Meshes[ i ];
|
unsigned int meshId = pObject->m_Meshes[ i ];
|
||||||
|
@ -406,8 +458,8 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
||||||
pMesh->mNumVertices = numIndices;
|
pMesh->mNumVertices = numIndices;
|
||||||
if (pMesh->mNumVertices == 0) {
|
if (pMesh->mNumVertices == 0) {
|
||||||
throw DeadlyImportError( "OBJ: no vertices" );
|
throw DeadlyImportError( "OBJ: no vertices" );
|
||||||
} else if (pMesh->mNumVertices > AI_MAX_ALLOC(aiVector3D)) {
|
} else if (pMesh->mNumVertices > AI_MAX_VERTICES) {
|
||||||
throw DeadlyImportError( "OBJ: Too many vertices, would run out of memory" );
|
throw DeadlyImportError( "OBJ: Too many vertices" );
|
||||||
}
|
}
|
||||||
pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ];
|
pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ];
|
||||||
|
|
||||||
|
@ -457,7 +509,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
||||||
// Copy all vertex colors
|
// Copy all vertex colors
|
||||||
if ( !pModel->m_VertexColors.empty())
|
if ( !pModel->m_VertexColors.empty())
|
||||||
{
|
{
|
||||||
const aiVector3D color = pModel->m_VertexColors[ vertex ];
|
const aiVector3D& color = pModel->m_VertexColors[ vertex ];
|
||||||
pMesh->mColors[0][ newIndex ] = aiColor4D(color.x, color.y, color.z, 1.0);
|
pMesh->mColors[0][ newIndex ] = aiColor4D(color.x, color.y, color.z, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -734,25 +786,8 @@ void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild)
|
||||||
// Assign parent to child
|
// Assign parent to child
|
||||||
pChild->mParent = pParent;
|
pChild->mParent = pParent;
|
||||||
|
|
||||||
// If already children was assigned to the parent node, store them in a
|
|
||||||
std::vector<aiNode*> temp;
|
|
||||||
if (pParent->mChildren != NULL)
|
|
||||||
{
|
|
||||||
ai_assert( 0 != pParent->mNumChildren );
|
|
||||||
for (size_t index = 0; index < pParent->mNumChildren; index++)
|
|
||||||
{
|
|
||||||
temp.push_back(pParent->mChildren [ index ] );
|
|
||||||
}
|
|
||||||
delete [] pParent->mChildren;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy node instances into parent node
|
// Copy node instances into parent node
|
||||||
pParent->mNumChildren++;
|
pParent->mNumChildren++;
|
||||||
pParent->mChildren = new aiNode*[ pParent->mNumChildren ];
|
|
||||||
for (size_t index = 0; index < pParent->mNumChildren-1; index++)
|
|
||||||
{
|
|
||||||
pParent->mChildren[ index ] = temp [ index ];
|
|
||||||
}
|
|
||||||
pParent->mChildren[ pParent->mNumChildren-1 ] = pChild;
|
pParent->mChildren[ pParent->mNumChildren-1 ] = pChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,8 +84,6 @@ static const std::string BumpOption = "-bm";
|
||||||
static const std::string ChannelOption = "-imfchan";
|
static const std::string ChannelOption = "-imfchan";
|
||||||
static const std::string TypeOption = "-type";
|
static const std::string TypeOption = "-type";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Constructor
|
// Constructor
|
||||||
ObjFileMtlImporter::ObjFileMtlImporter( std::vector<char> &buffer,
|
ObjFileMtlImporter::ObjFileMtlImporter( std::vector<char> &buffer,
|
||||||
|
@ -334,6 +332,11 @@ void ObjFileMtlImporter::getTexture() {
|
||||||
// Specular texture
|
// Specular texture
|
||||||
out = & m_pModel->m_pCurrentMaterial->textureSpecular;
|
out = & m_pModel->m_pCurrentMaterial->textureSpecular;
|
||||||
clampIndex = ObjFile::Material::TextureSpecularType;
|
clampIndex = ObjFile::Material::TextureSpecularType;
|
||||||
|
} else if ( !ASSIMP_strincmp( pPtr, DisplacementTexture1.c_str(), static_cast<unsigned int>(DisplacementTexture1.size()) ) ||
|
||||||
|
!ASSIMP_strincmp( pPtr, DisplacementTexture2.c_str(), static_cast<unsigned int>(DisplacementTexture2.size()) ) ) {
|
||||||
|
// Displacement texture
|
||||||
|
out = &m_pModel->m_pCurrentMaterial->textureDisp;
|
||||||
|
clampIndex = ObjFile::Material::TextureDispType;
|
||||||
} else if ( !ASSIMP_strincmp( pPtr, OpacityTexture.c_str(), static_cast<unsigned int>(OpacityTexture.size()) ) ) {
|
} else if ( !ASSIMP_strincmp( pPtr, OpacityTexture.c_str(), static_cast<unsigned int>(OpacityTexture.size()) ) ) {
|
||||||
// Opacity texture
|
// Opacity texture
|
||||||
out = & m_pModel->m_pCurrentMaterial->textureOpacity;
|
out = & m_pModel->m_pCurrentMaterial->textureOpacity;
|
||||||
|
@ -356,11 +359,6 @@ void ObjFileMtlImporter::getTexture() {
|
||||||
// Reflection texture(s)
|
// Reflection texture(s)
|
||||||
//Do nothing here
|
//Do nothing here
|
||||||
return;
|
return;
|
||||||
} else if ( !ASSIMP_strincmp( pPtr, DisplacementTexture1.c_str(), static_cast<unsigned int>(DisplacementTexture1.size()) ) ||
|
|
||||||
!ASSIMP_strincmp( pPtr, DisplacementTexture2.c_str(), static_cast<unsigned int>(DisplacementTexture2.size()) ) ) {
|
|
||||||
// Displacement texture
|
|
||||||
out = &m_pModel->m_pCurrentMaterial->textureDisp;
|
|
||||||
clampIndex = ObjFile::Material::TextureDispType;
|
|
||||||
} else if ( !ASSIMP_strincmp( pPtr, SpecularityTexture.c_str(), static_cast<unsigned int>(SpecularityTexture.size()) ) ) {
|
} else if ( !ASSIMP_strincmp( pPtr, SpecularityTexture.c_str(), static_cast<unsigned int>(SpecularityTexture.size()) ) ) {
|
||||||
// Specularity scaling (glossiness)
|
// Specularity scaling (glossiness)
|
||||||
out = & m_pModel->m_pCurrentMaterial->textureSpecularity;
|
out = & m_pModel->m_pCurrentMaterial->textureSpecularity;
|
||||||
|
|
|
@ -67,20 +67,22 @@ namespace Assimp {
|
||||||
class OptimizeMeshesProcess : public BaseProcess
|
class OptimizeMeshesProcess : public BaseProcess
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/// @brief The class constructor.
|
||||||
OptimizeMeshesProcess();
|
OptimizeMeshesProcess();
|
||||||
|
|
||||||
|
/// @brief The class destcructor,
|
||||||
~OptimizeMeshesProcess();
|
~OptimizeMeshesProcess();
|
||||||
|
|
||||||
|
|
||||||
/** @brief Internal utility to store additional mesh info
|
/** @brief Internal utility to store additional mesh info
|
||||||
*/
|
*/
|
||||||
struct MeshInfo
|
struct MeshInfo {
|
||||||
{
|
MeshInfo() AI_NO_EXCEPT
|
||||||
MeshInfo()
|
|
||||||
: instance_cnt(0)
|
: instance_cnt(0)
|
||||||
, vertex_format(0)
|
, vertex_format(0)
|
||||||
, output_id (0xffffffff)
|
, output_id(0xffffffff) {
|
||||||
{}
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
//! Number of times this mesh is referenced
|
//! Number of times this mesh is referenced
|
||||||
unsigned int instance_cnt;
|
unsigned int instance_cnt;
|
||||||
|
|
|
@ -55,7 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/importerdesc.h>
|
#include <assimp/importerdesc.h>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace ::Assimp;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static const aiImporterDesc desc = {
|
||||||
"Stanford Polygon Library (PLY) Importer",
|
"Stanford Polygon Library (PLY) Importer",
|
||||||
|
@ -73,13 +73,12 @@ static const aiImporterDesc desc = {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Internal stuff
|
// Internal stuff
|
||||||
namespace
|
namespace {
|
||||||
{
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Checks that property index is within range
|
// Checks that property index is within range
|
||||||
template <class T>
|
template <class T>
|
||||||
const T &GetProperty(const std::vector<T> &props, int idx)
|
inline
|
||||||
{
|
const T &GetProperty(const std::vector<T> &props, int idx) {
|
||||||
if (static_cast<size_t>(idx) >= props.size()) {
|
if (static_cast<size_t>(idx) >= props.size()) {
|
||||||
throw DeadlyImportError("Invalid .ply file: Property index is out of range.");
|
throw DeadlyImportError("Invalid .ply file: Property index is out of range.");
|
||||||
}
|
}
|
||||||
|
@ -88,7 +87,6 @@ namespace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
PLYImporter::PLYImporter()
|
PLYImporter::PLYImporter()
|
||||||
|
@ -129,7 +127,7 @@ const aiImporterDesc* PLYImporter::GetInfo() const {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
static bool isBigEndian(const char* szMe) {
|
static bool isBigEndian(const char* szMe) {
|
||||||
ai_assert(NULL != szMe);
|
ai_assert(nullptr != szMe);
|
||||||
|
|
||||||
// binary_little_endian
|
// binary_little_endian
|
||||||
// binary_big_endian
|
// binary_big_endian
|
||||||
|
@ -150,7 +148,7 @@ static bool isBigEndian(const char* szMe) {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) {
|
void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) {
|
||||||
static const std::string mode = "rb";
|
const std::string mode = "rb";
|
||||||
std::unique_ptr<IOStream> fileStream(pIOHandler->Open(pFile, mode));
|
std::unique_ptr<IOStream> fileStream(pIOHandler->Open(pFile, mode));
|
||||||
if (!fileStream.get()) {
|
if (!fileStream.get()) {
|
||||||
throw DeadlyImportError("Failed to open file " + pFile + ".");
|
throw DeadlyImportError("Failed to open file " + pFile + ".");
|
||||||
|
@ -184,7 +182,7 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
|
||||||
char* szMe = (char*)&this->mBuffer[0];
|
char* szMe = (char*)&this->mBuffer[0];
|
||||||
SkipSpacesAndLineEnd(szMe, (const char**)&szMe);
|
SkipSpacesAndLineEnd(szMe, (const char**)&szMe);
|
||||||
|
|
||||||
// determine the format of the file data and construct the aimesh
|
// determine the format of the file data and construct the aiMesh
|
||||||
PLY::DOM sPlyDom;
|
PLY::DOM sPlyDom;
|
||||||
this->pcDOM = &sPlyDom;
|
this->pcDOM = &sPlyDom;
|
||||||
|
|
||||||
|
@ -192,7 +190,7 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
|
||||||
if (TokenMatch(szMe, "ascii", 5)) {
|
if (TokenMatch(szMe, "ascii", 5)) {
|
||||||
SkipLine(szMe, (const char**)&szMe);
|
SkipLine(szMe, (const char**)&szMe);
|
||||||
if (!PLY::DOM::ParseInstance(streamedBuffer, &sPlyDom, this)) {
|
if (!PLY::DOM::ParseInstance(streamedBuffer, &sPlyDom, this)) {
|
||||||
if (mGeneratedMesh != NULL) {
|
if (mGeneratedMesh != nullptr) {
|
||||||
delete(mGeneratedMesh);
|
delete(mGeneratedMesh);
|
||||||
mGeneratedMesh = nullptr;
|
mGeneratedMesh = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -206,7 +204,7 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
|
||||||
|
|
||||||
// skip the line, parse the rest of the header and build the DOM
|
// skip the line, parse the rest of the header and build the DOM
|
||||||
if (!PLY::DOM::ParseInstanceBinary(streamedBuffer, &sPlyDom, this, bIsBE)) {
|
if (!PLY::DOM::ParseInstanceBinary(streamedBuffer, &sPlyDom, this, bIsBE)) {
|
||||||
if (mGeneratedMesh != NULL) {
|
if (mGeneratedMesh != nullptr) {
|
||||||
delete(mGeneratedMesh);
|
delete(mGeneratedMesh);
|
||||||
mGeneratedMesh = nullptr;
|
mGeneratedMesh = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -215,7 +213,7 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
|
||||||
throw DeadlyImportError("Invalid .ply file: Unable to build DOM (#2)");
|
throw DeadlyImportError("Invalid .ply file: Unable to build DOM (#2)");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (mGeneratedMesh != NULL) {
|
if (mGeneratedMesh != nullptr) {
|
||||||
delete(mGeneratedMesh);
|
delete(mGeneratedMesh);
|
||||||
mGeneratedMesh = nullptr;
|
mGeneratedMesh = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -225,7 +223,7 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AI_DEBUG_INVALIDATE_PTR(this->mBuffer);
|
AI_DEBUG_INVALIDATE_PTR(this->mBuffer);
|
||||||
if (mGeneratedMesh != NULL) {
|
if (mGeneratedMesh != nullptr) {
|
||||||
delete(mGeneratedMesh);
|
delete(mGeneratedMesh);
|
||||||
mGeneratedMesh = nullptr;
|
mGeneratedMesh = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -237,13 +235,13 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
|
||||||
//free the file buffer
|
//free the file buffer
|
||||||
streamedBuffer.close();
|
streamedBuffer.close();
|
||||||
|
|
||||||
if (mGeneratedMesh == NULL) {
|
if (mGeneratedMesh == nullptr) {
|
||||||
throw DeadlyImportError("Invalid .ply file: Unable to extract mesh data ");
|
throw DeadlyImportError("Invalid .ply file: Unable to extract mesh data ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// if no face list is existing we assume that the vertex
|
// if no face list is existing we assume that the vertex
|
||||||
// list is containing a list of points
|
// list is containing a list of points
|
||||||
bool pointsOnly = mGeneratedMesh->mFaces == NULL ? true : false;
|
bool pointsOnly = mGeneratedMesh->mFaces == nullptr ? true : false;
|
||||||
if (pointsOnly) {
|
if (pointsOnly) {
|
||||||
mGeneratedMesh->mPrimitiveTypes = aiPrimitiveType::aiPrimitiveType_POINT;
|
mGeneratedMesh->mPrimitiveTypes = aiPrimitiveType::aiPrimitiveType_POINT;
|
||||||
}
|
}
|
||||||
|
@ -277,8 +275,8 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
|
||||||
}
|
}
|
||||||
|
|
||||||
void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos) {
|
void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos) {
|
||||||
ai_assert(NULL != pcElement);
|
ai_assert(nullptr != pcElement);
|
||||||
ai_assert(NULL != instElement);
|
ai_assert(nullptr != instElement);
|
||||||
|
|
||||||
ai_uint aiPositions[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
|
ai_uint aiPositions[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
|
||||||
PLY::EDataType aiTypes[3] = { EDT_Char, EDT_Char, EDT_Char };
|
PLY::EDataType aiTypes[3] = { EDT_Char, EDT_Char, EDT_Char };
|
||||||
|
@ -481,13 +479,11 @@ void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementIn
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Convert a color component to [0...1]
|
// Convert a color component to [0...1]
|
||||||
ai_real PLYImporter::NormalizeColorValue(PLY::PropertyInstance::ValueUnion val, PLY::EDataType eType) {
|
ai_real PLYImporter::NormalizeColorValue(PLY::PropertyInstance::ValueUnion val, PLY::EDataType eType) {
|
||||||
switch (eType)
|
switch (eType) {
|
||||||
{
|
|
||||||
case EDT_Float:
|
case EDT_Float:
|
||||||
return val.fFloat;
|
return val.fFloat;
|
||||||
case EDT_Double:
|
case EDT_Double:
|
||||||
return (ai_real)val.fDouble;
|
return (ai_real)val.fDouble;
|
||||||
|
|
||||||
case EDT_UChar:
|
case EDT_UChar:
|
||||||
return (ai_real)val.iUInt / (ai_real)0xFF;
|
return (ai_real)val.iUInt / (ai_real)0xFF;
|
||||||
case EDT_Char:
|
case EDT_Char:
|
||||||
|
@ -500,20 +496,23 @@ ai_real PLYImporter::NormalizeColorValue(PLY::PropertyInstance::ValueUnion val,
|
||||||
return (ai_real)val.iUInt / (ai_real)0xFFFF;
|
return (ai_real)val.iUInt / (ai_real)0xFFFF;
|
||||||
case EDT_Int:
|
case EDT_Int:
|
||||||
return ((ai_real)val.iInt / (ai_real)0xFF) + 0.5f;
|
return ((ai_real)val.iInt / (ai_real)0xFF) + 0.5f;
|
||||||
default:;
|
default:
|
||||||
};
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Try to extract proper faces from the PLY DOM
|
// Try to extract proper faces from the PLY DOM
|
||||||
void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos)
|
void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInstance* instElement,
|
||||||
{
|
unsigned int pos) {
|
||||||
ai_assert(NULL != pcElement);
|
ai_assert(nullptr != pcElement);
|
||||||
ai_assert(NULL != instElement);
|
ai_assert(nullptr != instElement);
|
||||||
|
|
||||||
if (mGeneratedMesh == NULL)
|
if (mGeneratedMesh == nullptr) {
|
||||||
throw DeadlyImportError("Invalid .ply file: Vertices should be declared before faces");
|
throw DeadlyImportError("Invalid .ply file: Vertices should be declared before faces");
|
||||||
|
}
|
||||||
|
|
||||||
bool bOne = false;
|
bool bOne = false;
|
||||||
|
|
||||||
|
@ -531,35 +530,24 @@ void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInst
|
||||||
PLY::EDataType eType3 = EDT_Char;
|
PLY::EDataType eType3 = EDT_Char;
|
||||||
|
|
||||||
// face = unique number of vertex indices
|
// face = unique number of vertex indices
|
||||||
if (PLY::EEST_Face == pcElement->eSemantic)
|
if (PLY::EEST_Face == pcElement->eSemantic) {
|
||||||
{
|
|
||||||
unsigned int _a = 0;
|
unsigned int _a = 0;
|
||||||
for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
|
for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
|
||||||
a != pcElement->alProperties.end(); ++a, ++_a)
|
a != pcElement->alProperties.end(); ++a, ++_a) {
|
||||||
{
|
if (PLY::EST_VertexIndex == (*a).Semantic) {
|
||||||
if (PLY::EST_VertexIndex == (*a).Semantic)
|
|
||||||
{
|
|
||||||
// must be a dynamic list!
|
// must be a dynamic list!
|
||||||
if (!(*a).bIsList)
|
if (!(*a).bIsList) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
iProperty = _a;
|
iProperty = _a;
|
||||||
bOne = true;
|
bOne = true;
|
||||||
eType = (*a).eType;
|
eType = (*a).eType;
|
||||||
}
|
} else if (PLY::EST_TextureCoordinates == (*a).Semantic) {
|
||||||
/*else if (PLY::EST_MaterialIndex == (*a).Semantic)
|
|
||||||
{
|
|
||||||
if ((*a).bIsList)
|
|
||||||
continue;
|
|
||||||
iMaterialIndex = _a;
|
|
||||||
bOne = true;
|
|
||||||
eType2 = (*a).eType;
|
|
||||||
}*/
|
|
||||||
else if (PLY::EST_TextureCoordinates == (*a).Semantic)
|
|
||||||
{
|
|
||||||
// must be a dynamic list!
|
// must be a dynamic list!
|
||||||
if (!(*a).bIsList)
|
if (!(*a).bIsList) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
iTextureCoord = _a;
|
iTextureCoord = _a;
|
||||||
bOne = true;
|
bOne = true;
|
||||||
eType3 = (*a).eType;
|
eType3 = (*a).eType;
|
||||||
|
@ -568,15 +556,14 @@ void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInst
|
||||||
}
|
}
|
||||||
// triangle strip
|
// triangle strip
|
||||||
// TODO: triangle strip and material index support???
|
// TODO: triangle strip and material index support???
|
||||||
else if (PLY::EEST_TriStrip == pcElement->eSemantic)
|
else if (PLY::EEST_TriStrip == pcElement->eSemantic) {
|
||||||
{
|
|
||||||
unsigned int _a = 0;
|
unsigned int _a = 0;
|
||||||
for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
|
for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
|
||||||
a != pcElement->alProperties.end(); ++a, ++_a)
|
a != pcElement->alProperties.end(); ++a, ++_a) {
|
||||||
{
|
|
||||||
// must be a dynamic list!
|
// must be a dynamic list!
|
||||||
if (!(*a).bIsList)
|
if (!(*a).bIsList) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
iProperty = _a;
|
iProperty = _a;
|
||||||
bOne = true;
|
bOne = true;
|
||||||
bIsTriStrip = true;
|
bIsTriStrip = true;
|
||||||
|
@ -586,19 +573,15 @@ void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInst
|
||||||
}
|
}
|
||||||
|
|
||||||
// check whether we have at least one per-face information set
|
// check whether we have at least one per-face information set
|
||||||
if (bOne)
|
if (bOne) {
|
||||||
{
|
if (mGeneratedMesh->mFaces == nullptr) {
|
||||||
if (mGeneratedMesh->mFaces == NULL)
|
|
||||||
{
|
|
||||||
mGeneratedMesh->mNumFaces = pcElement->NumOccur;
|
mGeneratedMesh->mNumFaces = pcElement->NumOccur;
|
||||||
mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
|
mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bIsTriStrip)
|
if (!bIsTriStrip) {
|
||||||
{
|
|
||||||
// parse the list of vertex indices
|
// parse the list of vertex indices
|
||||||
if (0xFFFFFFFF != iProperty)
|
if (0xFFFFFFFF != iProperty) {
|
||||||
{
|
|
||||||
const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iProperty).avList.size();
|
const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iProperty).avList.size();
|
||||||
mGeneratedMesh->mFaces[pos].mNumIndices = iNum;
|
mGeneratedMesh->mFaces[pos].mNumIndices = iNum;
|
||||||
mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[iNum];
|
mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[iNum];
|
||||||
|
@ -606,8 +589,7 @@ void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInst
|
||||||
std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
|
std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
|
||||||
GetProperty(instElement->alProperties, iProperty).avList.begin();
|
GetProperty(instElement->alProperties, iProperty).avList.begin();
|
||||||
|
|
||||||
for (unsigned int a = 0; a < iNum; ++a, ++p)
|
for (unsigned int a = 0; a < iNum; ++a, ++p) {
|
||||||
{
|
|
||||||
mGeneratedMesh->mFaces[pos].mIndices[a] = PLY::PropertyInstance::ConvertTo<unsigned int>(*p, eType);
|
mGeneratedMesh->mFaces[pos].mIndices[a] = PLY::PropertyInstance::ConvertTo<unsigned int>(*p, eType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -620,8 +602,7 @@ void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInst
|
||||||
GetProperty(instElement->alProperties, iMaterialIndex).avList.front(), eType2);
|
GetProperty(instElement->alProperties, iMaterialIndex).avList.front(), eType2);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
if (0xFFFFFFFF != iTextureCoord)
|
if (0xFFFFFFFF != iTextureCoord) {
|
||||||
{
|
|
||||||
const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iTextureCoord).avList.size();
|
const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iTextureCoord).avList.size();
|
||||||
|
|
||||||
//should be 6 coords
|
//should be 6 coords
|
||||||
|
@ -630,30 +611,26 @@ void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInst
|
||||||
|
|
||||||
if ((iNum / 3) == 2) // X Y coord
|
if ((iNum / 3) == 2) // X Y coord
|
||||||
{
|
{
|
||||||
for (unsigned int a = 0; a < iNum; ++a, ++p)
|
for (unsigned int a = 0; a < iNum; ++a, ++p) {
|
||||||
{
|
|
||||||
unsigned int vindex = mGeneratedMesh->mFaces[pos].mIndices[a / 2];
|
unsigned int vindex = mGeneratedMesh->mFaces[pos].mIndices[a / 2];
|
||||||
if (vindex < mGeneratedMesh->mNumVertices)
|
if (vindex < mGeneratedMesh->mNumVertices) {
|
||||||
{
|
if (mGeneratedMesh->mTextureCoords[0] == nullptr ) {
|
||||||
if (mGeneratedMesh->mTextureCoords[0] == NULL)
|
|
||||||
{
|
|
||||||
mGeneratedMesh->mNumUVComponents[0] = 2;
|
mGeneratedMesh->mNumUVComponents[0] = 2;
|
||||||
mGeneratedMesh->mTextureCoords[0] = new aiVector3D[mGeneratedMesh->mNumVertices];
|
mGeneratedMesh->mTextureCoords[0] = new aiVector3D[mGeneratedMesh->mNumVertices];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a % 2 == 0)
|
if (a % 2 == 0) {
|
||||||
mGeneratedMesh->mTextureCoords[0][vindex].x = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3);
|
mGeneratedMesh->mTextureCoords[0][vindex].x = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3);
|
||||||
else
|
} else {
|
||||||
mGeneratedMesh->mTextureCoords[0][vindex].y = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3);
|
mGeneratedMesh->mTextureCoords[0][vindex].y = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3);
|
||||||
|
}
|
||||||
|
|
||||||
mGeneratedMesh->mTextureCoords[0][vindex].z = 0;
|
mGeneratedMesh->mTextureCoords[0][vindex].z = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else { // triangle strips
|
||||||
else // triangle strips
|
|
||||||
{
|
|
||||||
// normally we have only one triangle strip instance where
|
// normally we have only one triangle strip instance where
|
||||||
// a value of -1 indicates a restart of the strip
|
// a value of -1 indicates a restart of the strip
|
||||||
bool flip = false;
|
bool flip = false;
|
||||||
|
@ -679,8 +656,7 @@ void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInst
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mGeneratedMesh->mFaces == NULL)
|
if (mGeneratedMesh->mFaces == nullptr) {
|
||||||
{
|
|
||||||
mGeneratedMesh->mNumFaces = pcElement->NumOccur;
|
mGeneratedMesh->mNumFaces = pcElement->NumOccur;
|
||||||
mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
|
mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
|
||||||
}
|
}
|
||||||
|
@ -691,7 +667,9 @@ void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInst
|
||||||
mGeneratedMesh->mFaces[pos].mIndices[1] = aiTable[1];
|
mGeneratedMesh->mFaces[pos].mIndices[1] = aiTable[1];
|
||||||
mGeneratedMesh->mFaces[pos].mIndices[2] = p;
|
mGeneratedMesh->mFaces[pos].mIndices[2] = p;
|
||||||
|
|
||||||
if ((flip = !flip)) {
|
// every second pass swap the indices.
|
||||||
|
flip = !flip;
|
||||||
|
if ( flip ) {
|
||||||
std::swap(mGeneratedMesh->mFaces[pos].mIndices[0], mGeneratedMesh->mFaces[pos].mIndices[1]);
|
std::swap(mGeneratedMesh->mFaces[pos].mIndices[0], mGeneratedMesh->mFaces[pos].mIndices[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -209,7 +209,7 @@ enum EElementSemantic {
|
||||||
class Property {
|
class Property {
|
||||||
public:
|
public:
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
Property()
|
Property() AI_NO_EXCEPT
|
||||||
: eType (EDT_Int)
|
: eType (EDT_Int)
|
||||||
, Semantic()
|
, Semantic()
|
||||||
, bIsList(false)
|
, bIsList(false)
|
||||||
|
@ -257,7 +257,7 @@ public:
|
||||||
class Element {
|
class Element {
|
||||||
public:
|
public:
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
Element()
|
Element() AI_NO_EXCEPT
|
||||||
: eSemantic (EEST_INVALID)
|
: eSemantic (EEST_INVALID)
|
||||||
, NumOccur(0) {
|
, NumOccur(0) {
|
||||||
// empty
|
// empty
|
||||||
|
@ -297,8 +297,9 @@ class PropertyInstance
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
PropertyInstance ()
|
PropertyInstance() AI_NO_EXCEPT {
|
||||||
{}
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
union ValueUnion
|
union ValueUnion
|
||||||
{
|
{
|
||||||
|
@ -356,13 +357,13 @@ public:
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
/** \brief Class for an element instance in a PLY file
|
/** \brief Class for an element instance in a PLY file
|
||||||
*/
|
*/
|
||||||
class ElementInstance
|
class ElementInstance {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
ElementInstance ()
|
ElementInstance() AI_NO_EXCEPT
|
||||||
{}
|
: alProperties() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
//! List of all parsed properties
|
//! List of all parsed properties
|
||||||
std::vector< PropertyInstance > alProperties;
|
std::vector< PropertyInstance > alProperties;
|
||||||
|
@ -386,8 +387,10 @@ class ElementInstanceList
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
ElementInstanceList ()
|
ElementInstanceList() AI_NO_EXCEPT
|
||||||
{}
|
: alInstances() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
//! List of all element instances
|
//! List of all element instances
|
||||||
std::vector< ElementInstance > alInstances;
|
std::vector< ElementInstance > alInstances;
|
||||||
|
@ -411,8 +414,11 @@ class DOM
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
DOM()
|
DOM() AI_NO_EXCEPT
|
||||||
{}
|
: alElements()
|
||||||
|
, alElementData() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Contains all elements of the file format
|
//! Contains all elements of the file format
|
||||||
|
|
|
@ -164,9 +164,6 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out)
|
||||||
#if (!defined ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS)
|
#if (!defined ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS)
|
||||||
out.push_back( new OptimizeGraphProcess());
|
out.push_back( new OptimizeGraphProcess());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_FINDDEGENERATES_PROCESS)
|
|
||||||
out.push_back( new FindDegeneratesProcess());
|
|
||||||
#endif
|
|
||||||
#ifndef ASSIMP_BUILD_NO_GENUVCOORDS_PROCESS
|
#ifndef ASSIMP_BUILD_NO_GENUVCOORDS_PROCESS
|
||||||
out.push_back( new ComputeUVMappingProcess());
|
out.push_back( new ComputeUVMappingProcess());
|
||||||
#endif
|
#endif
|
||||||
|
@ -179,6 +176,12 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out)
|
||||||
#if (!defined ASSIMP_BUILD_NO_TRIANGULATE_PROCESS)
|
#if (!defined ASSIMP_BUILD_NO_TRIANGULATE_PROCESS)
|
||||||
out.push_back( new TriangulateProcess());
|
out.push_back( new TriangulateProcess());
|
||||||
#endif
|
#endif
|
||||||
|
#if (!defined ASSIMP_BUILD_NO_FINDDEGENERATES_PROCESS)
|
||||||
|
//find degenerates should run after triangulation (to sort out small
|
||||||
|
//generated triangles) but before sort by p types (in case there are lines
|
||||||
|
//and points generated and inserted into a mesh)
|
||||||
|
out.push_back( new FindDegeneratesProcess());
|
||||||
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_SORTBYPTYPE_PROCESS)
|
#if (!defined ASSIMP_BUILD_NO_SORTBYPTYPE_PROCESS)
|
||||||
out.push_back( new SortByPTypeProcess());
|
out.push_back( new SortByPTypeProcess());
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -63,16 +63,16 @@ struct aiNode;
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
namespace SMD {
|
namespace SMD {
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Data structure for a vertex in a SMD file
|
/** Data structure for a vertex in a SMD file
|
||||||
*/
|
*/
|
||||||
struct Vertex
|
struct Vertex {
|
||||||
{
|
Vertex() AI_NO_EXCEPT
|
||||||
Vertex() : iParentNode(UINT_MAX)
|
: iParentNode(UINT_MAX) {
|
||||||
{}
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
//! Vertex position, normal and texture coordinate
|
//! Vertex position, normal and texture coordinate
|
||||||
aiVector3D pos,nor,uv;
|
aiVector3D pos,nor,uv;
|
||||||
|
@ -90,10 +90,12 @@ struct Vertex
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Data structure for a face in a SMD file
|
/** Data structure for a face in a SMD file
|
||||||
*/
|
*/
|
||||||
struct Face
|
struct Face {
|
||||||
{
|
Face() AI_NO_EXCEPT
|
||||||
Face() : iTexture(0x0)
|
: iTexture(0x0)
|
||||||
{}
|
, avVertices{} {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
//! Texture index for the face
|
//! Texture index for the face
|
||||||
unsigned int iTexture;
|
unsigned int iTexture;
|
||||||
|
@ -105,11 +107,12 @@ struct Face
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Data structure for a bone in a SMD file
|
/** Data structure for a bone in a SMD file
|
||||||
*/
|
*/
|
||||||
struct Bone
|
struct Bone {
|
||||||
{
|
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
Bone() : iParent(UINT_MAX), bIsUsed(false)
|
Bone() AI_NO_EXCEPT
|
||||||
{
|
: iParent(UINT_MAX)
|
||||||
|
, bIsUsed(false) {
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Destructor
|
//! Destructor
|
||||||
|
@ -124,12 +127,10 @@ struct Bone
|
||||||
uint32_t iParent;
|
uint32_t iParent;
|
||||||
|
|
||||||
//! Animation of the bone
|
//! Animation of the bone
|
||||||
struct Animation
|
struct Animation {
|
||||||
{
|
|
||||||
//! Public default constructor
|
//! Public default constructor
|
||||||
Animation()
|
Animation() AI_NO_EXCEPT
|
||||||
: iFirstTimeKey()
|
: iFirstTimeKey() {
|
||||||
{
|
|
||||||
asKeys.reserve(20);
|
asKeys.reserve(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,9 @@ static bool IsBinarySTL(const char* buffer, unsigned int fileSize) {
|
||||||
return expectedBinaryFileSize == fileSize;
|
return expectedBinaryFileSize == fileSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const size_t BufferSize = 500;
|
||||||
|
static const char UnicodeBoundary = 127;
|
||||||
|
|
||||||
// An ascii STL buffer will begin with "solid NAME", where NAME is optional.
|
// An ascii STL buffer will begin with "solid NAME", where NAME is optional.
|
||||||
// Note: The "solid NAME" check is necessary, but not sufficient, to determine
|
// Note: The "solid NAME" check is necessary, but not sufficient, to determine
|
||||||
// if the buffer is ASCII; a binary header could also begin with "solid NAME".
|
// if the buffer is ASCII; a binary header could also begin with "solid NAME".
|
||||||
|
@ -108,10 +111,10 @@ static bool IsAsciiSTL(const char* buffer, unsigned int fileSize) {
|
||||||
bool isASCII( strncmp( buffer, "solid", 5 ) == 0 );
|
bool isASCII( strncmp( buffer, "solid", 5 ) == 0 );
|
||||||
if( isASCII ) {
|
if( isASCII ) {
|
||||||
// A lot of importers are write solid even if the file is binary. So we have to check for ASCII-characters.
|
// A lot of importers are write solid even if the file is binary. So we have to check for ASCII-characters.
|
||||||
if( fileSize >= 500 ) {
|
if( fileSize >= BufferSize) {
|
||||||
isASCII = true;
|
isASCII = true;
|
||||||
for( unsigned int i = 0; i < 500; i++ ) {
|
for( unsigned int i = 0; i < BufferSize; i++ ) {
|
||||||
if( buffer[ i ] > 127 ) {
|
if( buffer[ i ] > UnicodeBoundary) {
|
||||||
isASCII = false;
|
isASCII = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -352,7 +355,7 @@ void STLImporter::LoadASCIIFile( aiNode *root ) {
|
||||||
|
|
||||||
if (positionBuffer.empty()) {
|
if (positionBuffer.empty()) {
|
||||||
pMesh->mNumFaces = 0;
|
pMesh->mNumFaces = 0;
|
||||||
throw DeadlyImportError("STL: ASCII file is empty or invalid; no data loaded");
|
ASSIMP_LOG_WARN("STL: mesh is empty or invalid; no data loaded");
|
||||||
}
|
}
|
||||||
if (positionBuffer.size() % 3 != 0) {
|
if (positionBuffer.size() % 3 != 0) {
|
||||||
pMesh->mNumFaces = 0;
|
pMesh->mNumFaces = 0;
|
||||||
|
@ -362,14 +365,23 @@ void STLImporter::LoadASCIIFile( aiNode *root ) {
|
||||||
pMesh->mNumFaces = 0;
|
pMesh->mNumFaces = 0;
|
||||||
throw DeadlyImportError("Normal buffer size does not match position buffer size");
|
throw DeadlyImportError("Normal buffer size does not match position buffer size");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// only process positionbuffer when filled, else exception when accessing with index operator
|
||||||
|
// see line 353: only warning is triggered
|
||||||
|
// see line 373(now): access to empty positionbuffer with index operator forced exception
|
||||||
|
if (!positionBuffer.empty()) {
|
||||||
pMesh->mNumFaces = static_cast<unsigned int>(positionBuffer.size() / 3);
|
pMesh->mNumFaces = static_cast<unsigned int>(positionBuffer.size() / 3);
|
||||||
pMesh->mNumVertices = static_cast<unsigned int>(positionBuffer.size());
|
pMesh->mNumVertices = static_cast<unsigned int>(positionBuffer.size());
|
||||||
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
|
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
|
||||||
memcpy(pMesh->mVertices, &positionBuffer[0].x, pMesh->mNumVertices * sizeof(aiVector3D));
|
memcpy(pMesh->mVertices, &positionBuffer[0].x, pMesh->mNumVertices * sizeof(aiVector3D));
|
||||||
positionBuffer.clear();
|
positionBuffer.clear();
|
||||||
|
}
|
||||||
|
// also only process normalBuffer when filled, else exception when accessing with index operator
|
||||||
|
if (!normalBuffer.empty()) {
|
||||||
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
|
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
|
||||||
memcpy(pMesh->mNormals, &normalBuffer[0].x, pMesh->mNumVertices * sizeof(aiVector3D));
|
memcpy(pMesh->mNormals, &normalBuffer[0].x, pMesh->mNumVertices * sizeof(aiVector3D));
|
||||||
normalBuffer.clear();
|
normalBuffer.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// now copy faces
|
// now copy faces
|
||||||
addFacesToMesh(pMesh);
|
addFacesToMesh(pMesh);
|
||||||
|
@ -526,11 +538,21 @@ bool STLImporter::LoadBinaryFile()
|
||||||
// now copy faces
|
// now copy faces
|
||||||
addFacesToMesh(pMesh);
|
addFacesToMesh(pMesh);
|
||||||
|
|
||||||
|
aiNode* root = pScene->mRootNode;
|
||||||
|
|
||||||
|
// allocate one node
|
||||||
|
aiNode* node = new aiNode();
|
||||||
|
node->mParent = root;
|
||||||
|
|
||||||
|
root->mNumChildren = 1u;
|
||||||
|
root->mChildren = new aiNode*[root->mNumChildren];
|
||||||
|
root->mChildren[0] = node;
|
||||||
|
|
||||||
// add all created meshes to the single node
|
// add all created meshes to the single node
|
||||||
pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
|
node->mNumMeshes = pScene->mNumMeshes;
|
||||||
pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
|
node->mMeshes = new unsigned int[pScene->mNumMeshes];
|
||||||
for (unsigned int i = 0; i < pScene->mNumMeshes; i++)
|
for (unsigned int i = 0; i < pScene->mNumMeshes; i++)
|
||||||
pScene->mRootNode->mMeshes[i] = i;
|
node->mMeshes[i] = i;
|
||||||
|
|
||||||
if (bIsMaterialise && !pMesh->mColors[0])
|
if (bIsMaterialise && !pMesh->mColors[0])
|
||||||
{
|
{
|
||||||
|
|
|
@ -713,24 +713,24 @@ void SceneCombiner::MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator
|
||||||
out->mNumBones = 0;
|
out->mNumBones = 0;
|
||||||
out->mBones = new aiBone*[asBones.size()];
|
out->mBones = new aiBone*[asBones.size()];
|
||||||
|
|
||||||
for (std::list<BoneWithHash>::const_iterator it = asBones.begin(),end = asBones.end(); it != end;++it) {
|
for (std::list<BoneWithHash>::const_iterator boneIt = asBones.begin(),boneEnd = asBones.end(); boneIt != boneEnd; ++boneIt ) {
|
||||||
// Allocate a bone and setup it's name
|
// Allocate a bone and setup it's name
|
||||||
aiBone* pc = out->mBones[out->mNumBones++] = new aiBone();
|
aiBone* pc = out->mBones[out->mNumBones++] = new aiBone();
|
||||||
pc->mName = aiString( *((*it).second ));
|
pc->mName = aiString( *( boneIt->second ));
|
||||||
|
|
||||||
std::vector< BoneSrcIndex >::const_iterator wend = (*it).pSrcBones.end();
|
std::vector< BoneSrcIndex >::const_iterator wend = boneIt->pSrcBones.end();
|
||||||
|
|
||||||
// Loop through all bones to be joined for this bone
|
// Loop through all bones to be joined for this bone
|
||||||
for (std::vector< BoneSrcIndex >::const_iterator wmit = (*it).pSrcBones.begin(); wmit != wend; ++wmit) {
|
for (std::vector< BoneSrcIndex >::const_iterator wmit = boneIt->pSrcBones.begin(); wmit != wend; ++wmit) {
|
||||||
pc->mNumWeights += (*wmit).first->mNumWeights;
|
pc->mNumWeights += (*wmit).first->mNumWeights;
|
||||||
|
|
||||||
// NOTE: different offset matrices for bones with equal names
|
// NOTE: different offset matrices for bones with equal names
|
||||||
// are - at the moment - not handled correctly.
|
// are - at the moment - not handled correctly.
|
||||||
if (wmit != (*it).pSrcBones.begin() && pc->mOffsetMatrix != (*wmit).first->mOffsetMatrix) {
|
if (wmit != boneIt->pSrcBones.begin() && pc->mOffsetMatrix != wmit->first->mOffsetMatrix) {
|
||||||
ASSIMP_LOG_WARN("Bones with equal names but different offset matrices can't be joined at the moment");
|
ASSIMP_LOG_WARN("Bones with equal names but different offset matrices can't be joined at the moment");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
pc->mOffsetMatrix = (*wmit).first->mOffsetMatrix;
|
pc->mOffsetMatrix = wmit->first->mOffsetMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate the vertex weight array
|
// Allocate the vertex weight array
|
||||||
|
@ -738,7 +738,7 @@ void SceneCombiner::MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator
|
||||||
|
|
||||||
// And copy the final weights - adjust the vertex IDs by the
|
// And copy the final weights - adjust the vertex IDs by the
|
||||||
// face index offset of the corresponding mesh.
|
// face index offset of the corresponding mesh.
|
||||||
for (std::vector< BoneSrcIndex >::const_iterator wmit = (*it).pSrcBones.begin(); wmit != wend; ++wmit) {
|
for (std::vector< BoneSrcIndex >::const_iterator wmit = (*boneIt).pSrcBones.begin(); wmit != wend; ++wmit) {
|
||||||
aiBone* pip = (*wmit).first;
|
aiBone* pip = (*wmit).first;
|
||||||
for (unsigned int mp = 0; mp < pip->mNumWeights;++mp,++avw) {
|
for (unsigned int mp = 0; mp < pip->mNumWeights;++mp,++avw) {
|
||||||
const aiVertexWeight& vfi = pip->mWeights[mp];
|
const aiVertexWeight& vfi = pip->mWeights[mp];
|
||||||
|
@ -849,14 +849,14 @@ void SceneCombiner::MergeMeshes(aiMesh** _out, unsigned int /*flags*/,
|
||||||
// copy vertex colors
|
// copy vertex colors
|
||||||
n = 0;
|
n = 0;
|
||||||
while ((**begin).HasVertexColors(n)) {
|
while ((**begin).HasVertexColors(n)) {
|
||||||
aiColor4D* pv2 = out->mColors[n] = new aiColor4D[out->mNumVertices];
|
aiColor4D *pVec2 = out->mColors[n] = new aiColor4D[out->mNumVertices];
|
||||||
for ( std::vector<aiMesh*>::const_iterator it = begin; it != end; ++it ) {
|
for ( std::vector<aiMesh*>::const_iterator it = begin; it != end; ++it ) {
|
||||||
if ((*it)->mColors[n]) {
|
if ((*it)->mColors[n]) {
|
||||||
::memcpy(pv2,(*it)->mColors[n],(*it)->mNumVertices*sizeof(aiColor4D));
|
::memcpy( pVec2, (*it)->mColors[ n ], (*it)->mNumVertices * sizeof( aiColor4D ) ) ;
|
||||||
} else {
|
} else {
|
||||||
ASSIMP_LOG_WARN( "JoinMeshes: VCs expected but input mesh contains no VCs" );
|
ASSIMP_LOG_WARN( "JoinMeshes: VCs expected but input mesh contains no VCs" );
|
||||||
}
|
}
|
||||||
pv2 += (*it)->mNumVertices;
|
pVec2 += (*it)->mNumVertices;
|
||||||
}
|
}
|
||||||
++n;
|
++n;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,12 +55,8 @@ namespace Assimp {
|
||||||
class Importer;
|
class Importer;
|
||||||
|
|
||||||
struct ScenePrivateData {
|
struct ScenePrivateData {
|
||||||
ScenePrivateData()
|
// The struct constructor.
|
||||||
: mOrigImporter( nullptr )
|
ScenePrivateData() AI_NO_EXCEPT;
|
||||||
, mPPStepsApplied( 0 )
|
|
||||||
, mIsCopy( false ) {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
// Importer that originally loaded the scene though the C-API
|
// Importer that originally loaded the scene though the C-API
|
||||||
// If set, this object is owned by this private data instance.
|
// If set, this object is owned by this private data instance.
|
||||||
|
@ -77,6 +73,14 @@ struct ScenePrivateData {
|
||||||
bool mIsCopy;
|
bool mIsCopy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline
|
||||||
|
ScenePrivateData::ScenePrivateData() AI_NO_EXCEPT
|
||||||
|
: mOrigImporter( nullptr )
|
||||||
|
, mPPStepsApplied( 0 )
|
||||||
|
, mIsCopy( false ) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
// Access private data stored in the scene
|
// Access private data stored in the scene
|
||||||
inline
|
inline
|
||||||
ScenePrivateData* ScenePriv(aiScene* in) {
|
ScenePrivateData* ScenePriv(aiScene* in) {
|
||||||
|
|
|
@ -393,7 +393,7 @@ void SplitByBoneCountProcess::UpdateNode( aiNode* pNode) const
|
||||||
newMeshList.insert( newMeshList.end(), replaceMeshes.begin(), replaceMeshes.end());
|
newMeshList.insert( newMeshList.end(), replaceMeshes.begin(), replaceMeshes.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
delete pNode->mMeshes;
|
delete [] pNode->mMeshes;
|
||||||
pNode->mNumMeshes = static_cast<unsigned int>(newMeshList.size());
|
pNode->mNumMeshes = static_cast<unsigned int>(newMeshList.size());
|
||||||
pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
|
pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
|
||||||
std::copy( newMeshList.begin(), newMeshList.end(), pNode->mMeshes);
|
std::copy( newMeshList.begin(), newMeshList.end(), pNode->mMeshes);
|
||||||
|
|
|
@ -65,14 +65,14 @@ namespace Assimp {
|
||||||
/** Small helper structure representing a shortcut into the material list
|
/** Small helper structure representing a shortcut into the material list
|
||||||
* to be able to update some values quickly.
|
* to be able to update some values quickly.
|
||||||
*/
|
*/
|
||||||
struct TTUpdateInfo
|
struct TTUpdateInfo {
|
||||||
{
|
TTUpdateInfo() AI_NO_EXCEPT
|
||||||
TTUpdateInfo() :
|
: directShortcut(nullptr)
|
||||||
directShortcut (NULL)
|
, mat(nullptr)
|
||||||
, mat (NULL)
|
|
||||||
, semantic(0)
|
, semantic(0)
|
||||||
, index (0)
|
, index(0) {
|
||||||
{}
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
//! Direct shortcut, if available
|
//! Direct shortcut, if available
|
||||||
unsigned int* directShortcut;
|
unsigned int* directShortcut;
|
||||||
|
@ -88,15 +88,14 @@ struct TTUpdateInfo
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Helper class representing texture coordinate transformations
|
/** Helper class representing texture coordinate transformations
|
||||||
*/
|
*/
|
||||||
struct STransformVecInfo : public aiUVTransform
|
struct STransformVecInfo : public aiUVTransform {
|
||||||
{
|
STransformVecInfo() AI_NO_EXCEPT
|
||||||
|
|
||||||
STransformVecInfo()
|
|
||||||
: uvIndex(0)
|
: uvIndex(0)
|
||||||
, mapU(aiTextureMapMode_Wrap)
|
, mapU(aiTextureMapMode_Wrap)
|
||||||
, mapV(aiTextureMapMode_Wrap)
|
, mapV(aiTextureMapMode_Wrap)
|
||||||
, lockedPos (AI_TT_UV_IDX_LOCK_NONE)
|
, lockedPos(AI_TT_UV_IDX_LOCK_NONE) {
|
||||||
{}
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
//! Source texture coordinate index
|
//! Source texture coordinate index
|
||||||
unsigned int uvIndex;
|
unsigned int uvIndex;
|
||||||
|
|
|
@ -105,10 +105,12 @@ void TriangulateProcess::Execute( aiScene* pScene)
|
||||||
bool bHas = false;
|
bool bHas = false;
|
||||||
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
|
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
|
||||||
{
|
{
|
||||||
|
if (pScene->mMeshes[ a ]) {
|
||||||
if ( TriangulateMesh( pScene->mMeshes[ a ] ) ) {
|
if ( TriangulateMesh( pScene->mMeshes[ a ] ) ) {
|
||||||
bHas = true;
|
bHas = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if ( bHas ) {
|
if ( bHas ) {
|
||||||
ASSIMP_LOG_INFO( "TriangulateProcess finished. All polygons have been triangulated." );
|
ASSIMP_LOG_INFO( "TriangulateProcess finished. All polygons have been triangulated." );
|
||||||
} else {
|
} else {
|
||||||
|
@ -485,21 +487,22 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
|
||||||
for(aiFace* f = last_face; f != curOut; ) {
|
for(aiFace* f = last_face; f != curOut; ) {
|
||||||
unsigned int* i = f->mIndices;
|
unsigned int* i = f->mIndices;
|
||||||
|
|
||||||
// drop dumb 0-area triangles
|
// drop dumb 0-area triangles - deactivated for now:
|
||||||
if (std::fabs(GetArea2D(temp_verts[i[0]],temp_verts[i[1]],temp_verts[i[2]])) < 1e-5f) {
|
//FindDegenerates post processing step can do the same thing
|
||||||
ASSIMP_LOG_DEBUG("Dropping triangle with area 0");
|
//if (std::fabs(GetArea2D(temp_verts[i[0]],temp_verts[i[1]],temp_verts[i[2]])) < 1e-5f) {
|
||||||
--curOut;
|
// ASSIMP_LOG_DEBUG("Dropping triangle with area 0");
|
||||||
|
// --curOut;
|
||||||
|
|
||||||
delete[] f->mIndices;
|
// delete[] f->mIndices;
|
||||||
f->mIndices = NULL;
|
// f->mIndices = nullptr;
|
||||||
|
|
||||||
for(aiFace* ff = f; ff != curOut; ++ff) {
|
// for(aiFace* ff = f; ff != curOut; ++ff) {
|
||||||
ff->mNumIndices = (ff+1)->mNumIndices;
|
// ff->mNumIndices = (ff+1)->mNumIndices;
|
||||||
ff->mIndices = (ff+1)->mIndices;
|
// ff->mIndices = (ff+1)->mIndices;
|
||||||
(ff+1)->mIndices = NULL;
|
// (ff+1)->mIndices = nullptr;
|
||||||
}
|
// }
|
||||||
continue;
|
// continue;
|
||||||
}
|
//}
|
||||||
|
|
||||||
i[0] = idx[i[0]];
|
i[0] = idx[i[0]];
|
||||||
i[1] = idx[i[1]];
|
i[1] = idx[i[1]];
|
||||||
|
|
|
@ -369,7 +369,7 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
|
||||||
|
|
||||||
// positions must always be there ...
|
// positions must always be there ...
|
||||||
if (!pMesh->mNumVertices || (!pMesh->mVertices && !mScene->mFlags)) {
|
if (!pMesh->mNumVertices || (!pMesh->mVertices && !mScene->mFlags)) {
|
||||||
ReportError("The mesh contains no vertices");
|
ReportError("The mesh %s contains no vertices", pMesh->mName.C_Str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pMesh->mNumVertices > AI_MAX_VERTICES) {
|
if (pMesh->mNumVertices > AI_MAX_VERTICES) {
|
||||||
|
@ -386,7 +386,7 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
|
||||||
|
|
||||||
// faces, too
|
// faces, too
|
||||||
if (!pMesh->mNumFaces || (!pMesh->mFaces && !mScene->mFlags)) {
|
if (!pMesh->mNumFaces || (!pMesh->mFaces && !mScene->mFlags)) {
|
||||||
ReportError("Mesh contains no faces");
|
ReportError("Mesh %s contains no faces", pMesh->mName.C_Str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// now check whether the face indexing layout is correct:
|
// now check whether the face indexing layout is correct:
|
||||||
|
|
|
@ -150,9 +150,11 @@ ASSIMP_API aiScene::~aiScene() {
|
||||||
delete mMeshes[a];
|
delete mMeshes[a];
|
||||||
delete [] mMeshes;
|
delete [] mMeshes;
|
||||||
|
|
||||||
if (mNumMaterials && mMaterials)
|
if (mNumMaterials && mMaterials) {
|
||||||
for( unsigned int a = 0; a < mNumMaterials; a++)
|
for (unsigned int a = 0; a < mNumMaterials; ++a ) {
|
||||||
delete mMaterials[ a ];
|
delete mMaterials[ a ];
|
||||||
|
}
|
||||||
|
}
|
||||||
delete [] mMaterials;
|
delete [] mMaterials;
|
||||||
|
|
||||||
if (mNumAnimations && mAnimations)
|
if (mNumAnimations && mAnimations)
|
||||||
|
|
|
@ -55,32 +55,33 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/anim.h>
|
#include <assimp/anim.h>
|
||||||
#include <assimp/Defines.h>
|
#include <assimp/Defines.h>
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp {
|
||||||
{
|
namespace XFile {
|
||||||
namespace XFile
|
|
||||||
{
|
|
||||||
|
|
||||||
/** Helper structure representing a XFile mesh face */
|
/** Helper structure representing a XFile mesh face */
|
||||||
struct Face
|
struct Face {
|
||||||
{
|
|
||||||
std::vector<unsigned int> mIndices;
|
std::vector<unsigned int> mIndices;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Helper structure representing a texture filename inside a material and its potential source */
|
/** Helper structure representing a texture filename inside a material and its potential source */
|
||||||
struct TexEntry
|
struct TexEntry {
|
||||||
{
|
|
||||||
std::string mName;
|
std::string mName;
|
||||||
bool mIsNormalMap; // true if the texname was specified in a NormalmapFilename tag
|
bool mIsNormalMap; // true if the texname was specified in a NormalmapFilename tag
|
||||||
|
|
||||||
TexEntry() { mIsNormalMap = false; }
|
TexEntry() AI_NO_EXCEPT
|
||||||
|
: mName()
|
||||||
|
, mIsNormalMap(false) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
TexEntry(const std::string& pName, bool pIsNormalMap = false)
|
TexEntry(const std::string& pName, bool pIsNormalMap = false)
|
||||||
: mName( pName), mIsNormalMap( pIsNormalMap)
|
: mName(pName)
|
||||||
{ /* done */ }
|
, mIsNormalMap(pIsNormalMap) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Helper structure representing a XFile material */
|
/** Helper structure representing a XFile material */
|
||||||
struct Material
|
struct Material {
|
||||||
{
|
|
||||||
std::string mName;
|
std::string mName;
|
||||||
bool mIsReference; // if true, mName holds a name by which the actual material can be found in the material list
|
bool mIsReference; // if true, mName holds a name by which the actual material can be found in the material list
|
||||||
aiColor4D mDiffuse;
|
aiColor4D mDiffuse;
|
||||||
|
@ -88,19 +89,18 @@ struct Material
|
||||||
aiColor3D mSpecular;
|
aiColor3D mSpecular;
|
||||||
aiColor3D mEmissive;
|
aiColor3D mEmissive;
|
||||||
std::vector<TexEntry> mTextures;
|
std::vector<TexEntry> mTextures;
|
||||||
|
|
||||||
size_t sceneIndex; ///< the index under which it was stored in the scene's material list
|
size_t sceneIndex; ///< the index under which it was stored in the scene's material list
|
||||||
|
|
||||||
Material()
|
Material() AI_NO_EXCEPT
|
||||||
: mIsReference(false),
|
: mIsReference(false)
|
||||||
mSpecularExponent(),
|
, mSpecularExponent()
|
||||||
sceneIndex(SIZE_MAX)
|
, sceneIndex(SIZE_MAX) {
|
||||||
{}
|
// empty
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Helper structure to represent a bone weight */
|
/** Helper structure to represent a bone weight */
|
||||||
struct BoneWeight
|
struct BoneWeight {
|
||||||
{
|
|
||||||
unsigned int mVertex;
|
unsigned int mVertex;
|
||||||
ai_real mWeight;
|
ai_real mWeight;
|
||||||
};
|
};
|
||||||
|
@ -114,8 +114,7 @@ struct Bone
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Helper structure to represent an XFile mesh */
|
/** Helper structure to represent an XFile mesh */
|
||||||
struct Mesh
|
struct Mesh {
|
||||||
{
|
|
||||||
std::string mName;
|
std::string mName;
|
||||||
std::vector<aiVector3D> mPositions;
|
std::vector<aiVector3D> mPositions;
|
||||||
std::vector<Face> mPosFaces;
|
std::vector<Face> mPosFaces;
|
||||||
|
@ -131,38 +130,65 @@ struct Mesh
|
||||||
|
|
||||||
std::vector<Bone> mBones;
|
std::vector<Bone> mBones;
|
||||||
|
|
||||||
explicit Mesh(const std::string &pName = "") { mName = pName; mNumTextures = 0; mNumColorSets = 0; }
|
explicit Mesh(const std::string &pName = "") AI_NO_EXCEPT
|
||||||
|
: mName( pName )
|
||||||
|
, mPositions()
|
||||||
|
, mPosFaces()
|
||||||
|
, mNormals()
|
||||||
|
, mNormFaces()
|
||||||
|
, mNumTextures(0)
|
||||||
|
, mTexCoords{}
|
||||||
|
, mNumColorSets(0)
|
||||||
|
, mColors{}
|
||||||
|
, mFaceMaterials()
|
||||||
|
, mMaterials()
|
||||||
|
, mBones() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Helper structure to represent a XFile frame */
|
/** Helper structure to represent a XFile frame */
|
||||||
struct Node
|
struct Node {
|
||||||
{
|
|
||||||
std::string mName;
|
std::string mName;
|
||||||
aiMatrix4x4 mTrafoMatrix;
|
aiMatrix4x4 mTrafoMatrix;
|
||||||
Node* mParent;
|
Node* mParent;
|
||||||
std::vector<Node*> mChildren;
|
std::vector<Node*> mChildren;
|
||||||
std::vector<Mesh*> mMeshes;
|
std::vector<Mesh*> mMeshes;
|
||||||
|
|
||||||
Node() { mParent = NULL; }
|
Node() AI_NO_EXCEPT
|
||||||
explicit Node( Node* pParent) { mParent = pParent; }
|
: mName()
|
||||||
~Node()
|
, mTrafoMatrix()
|
||||||
{
|
, mParent(nullptr)
|
||||||
for( unsigned int a = 0; a < mChildren.size(); a++)
|
, mChildren()
|
||||||
|
, mMeshes() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
explicit Node( Node* pParent)
|
||||||
|
: mName()
|
||||||
|
, mTrafoMatrix()
|
||||||
|
, mParent(pParent)
|
||||||
|
, mChildren()
|
||||||
|
, mMeshes() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
~Node() {
|
||||||
|
for (unsigned int a = 0; a < mChildren.size(); ++a ) {
|
||||||
delete mChildren[a];
|
delete mChildren[a];
|
||||||
for( unsigned int a = 0; a < mMeshes.size(); a++)
|
}
|
||||||
|
for (unsigned int a = 0; a < mMeshes.size(); ++a) {
|
||||||
delete mMeshes[a];
|
delete mMeshes[a];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MatrixKey
|
struct MatrixKey {
|
||||||
{
|
|
||||||
double mTime;
|
double mTime;
|
||||||
aiMatrix4x4 mMatrix;
|
aiMatrix4x4 mMatrix;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Helper structure representing a single animated bone in a XFile */
|
/** Helper structure representing a single animated bone in a XFile */
|
||||||
struct AnimBone
|
struct AnimBone {
|
||||||
{
|
|
||||||
std::string mBoneName;
|
std::string mBoneName;
|
||||||
std::vector<aiVectorKey> mPosKeys; // either three separate key sequences for position, rotation, scaling
|
std::vector<aiVectorKey> mPosKeys; // either three separate key sequences for position, rotation, scaling
|
||||||
std::vector<aiQuatKey> mRotKeys;
|
std::vector<aiQuatKey> mRotKeys;
|
||||||
|
@ -194,15 +220,23 @@ struct Scene
|
||||||
std::vector<Animation*> mAnims;
|
std::vector<Animation*> mAnims;
|
||||||
unsigned int mAnimTicksPerSecond;
|
unsigned int mAnimTicksPerSecond;
|
||||||
|
|
||||||
Scene() { mRootNode = NULL; mAnimTicksPerSecond = 0; }
|
Scene() AI_NO_EXCEPT
|
||||||
~Scene()
|
: mRootNode(nullptr)
|
||||||
{
|
, mGlobalMeshes()
|
||||||
|
, mGlobalMaterials()
|
||||||
|
, mAnimTicksPerSecond(0) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
~Scene() {
|
||||||
delete mRootNode;
|
delete mRootNode;
|
||||||
for( unsigned int a = 0; a < mGlobalMeshes.size(); a++)
|
mRootNode = nullptr;
|
||||||
|
for (unsigned int a = 0; a < mGlobalMeshes.size(); ++a ) {
|
||||||
delete mGlobalMeshes[a];
|
delete mGlobalMeshes[a];
|
||||||
for( unsigned int a = 0; a < mAnims.size(); a++)
|
}
|
||||||
|
for (unsigned int a = 0; a < mAnims.size(); ++a ) {
|
||||||
delete mAnims[a];
|
delete mAnims[a];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace XFile
|
} // end of namespace XFile
|
||||||
|
|
|
@ -332,6 +332,11 @@ void XFileImporter::CreateMeshes( aiScene* pScene, aiNode* pNode, const std::vec
|
||||||
// collect vertex data for indices of this face
|
// collect vertex data for indices of this face
|
||||||
for( unsigned int d = 0; d < df.mNumIndices; ++d ) {
|
for( unsigned int d = 0; d < df.mNumIndices; ++d ) {
|
||||||
df.mIndices[d] = newIndex;
|
df.mIndices[d] = newIndex;
|
||||||
|
const unsigned int newIdx( pf.mIndices[ d ] );
|
||||||
|
if ( newIdx > sourceMesh->mPositions.size() ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
orgPoints[newIndex] = pf.mIndices[d];
|
orgPoints[newIndex] = pf.mIndices[d];
|
||||||
|
|
||||||
// Position
|
// Position
|
||||||
|
@ -459,7 +464,7 @@ void XFileImporter::CreateAnimations( aiScene* pScene, const XFile::Scene* pData
|
||||||
nbone->mNodeName.Set( bone->mBoneName);
|
nbone->mNodeName.Set( bone->mBoneName);
|
||||||
nanim->mChannels[b] = nbone;
|
nanim->mChannels[b] = nbone;
|
||||||
|
|
||||||
// keyframes are given as combined transformation matrix keys
|
// key-frames are given as combined transformation matrix keys
|
||||||
if( !bone->mTrafoKeys.empty() )
|
if( !bone->mTrafoKeys.empty() )
|
||||||
{
|
{
|
||||||
nbone->mNumPositionKeys = (unsigned int)bone->mTrafoKeys.size();
|
nbone->mNumPositionKeys = (unsigned int)bone->mTrafoKeys.size();
|
||||||
|
|
|
@ -471,7 +471,10 @@ void XFileParser::ParseDataObjectMesh( Mesh* pMesh)
|
||||||
unsigned int numIndices = ReadInt();
|
unsigned int numIndices = ReadInt();
|
||||||
Face& face = pMesh->mPosFaces[a];
|
Face& face = pMesh->mPosFaces[a];
|
||||||
for (unsigned int b = 0; b < numIndices; ++b) {
|
for (unsigned int b = 0; b < numIndices; ++b) {
|
||||||
face.mIndices.push_back( ReadInt() );
|
const int idx( ReadInt() );
|
||||||
|
if ( static_cast<unsigned int>( idx ) <= numVertices ) {
|
||||||
|
face.mIndices.push_back( idx );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TestForSeparator();
|
TestForSeparator();
|
||||||
}
|
}
|
||||||
|
@ -1305,7 +1308,8 @@ unsigned int XFileParser::ReadInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
--mBinaryNumCount;
|
--mBinaryNumCount;
|
||||||
if ( mEnd - mP >= 4) {
|
const size_t len( mEnd - mP );
|
||||||
|
if ( len >= 4) {
|
||||||
return ReadBinDWord();
|
return ReadBinDWord();
|
||||||
} else {
|
} else {
|
||||||
mP = mEnd;
|
mP = mEnd;
|
||||||
|
@ -1340,6 +1344,7 @@ unsigned int XFileParser::ReadInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckForSeparator();
|
CheckForSeparator();
|
||||||
|
|
||||||
return isNegative ? ((unsigned int) -int( number)) : number;
|
return isNegative ? ((unsigned int) -int( number)) : number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -766,10 +766,17 @@ namespace glTF2
|
||||||
Ref<Accessor> indices;
|
Ref<Accessor> indices;
|
||||||
|
|
||||||
Ref<Material> material;
|
Ref<Material> material;
|
||||||
|
|
||||||
|
struct Target {
|
||||||
|
AccessorList position, normal, tangent;
|
||||||
|
};
|
||||||
|
std::vector<Target> targets;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<Primitive> primitives;
|
std::vector<Primitive> primitives;
|
||||||
|
|
||||||
|
std::vector<float> weights;
|
||||||
|
|
||||||
Mesh() {}
|
Mesh() {}
|
||||||
|
|
||||||
/// \fn void Read(Value& pJSON_Object, Asset& pAsset_Root)
|
/// \fn void Read(Value& pJSON_Object, Asset& pAsset_Root)
|
||||||
|
|
|
@ -931,6 +931,21 @@ namespace {
|
||||||
else return false;
|
else return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool GetAttribTargetVector(Mesh::Primitive& p, const int targetIndex, const char* attr, Mesh::AccessorList*& v, int& pos)
|
||||||
|
{
|
||||||
|
if ((pos = Compare(attr, "POSITION"))) {
|
||||||
|
v = &(p.targets[targetIndex].position);
|
||||||
|
}
|
||||||
|
else if ((pos = Compare(attr, "NORMAL"))) {
|
||||||
|
v = &(p.targets[targetIndex].normal);
|
||||||
|
}
|
||||||
|
else if ((pos = Compare(attr, "TANGENT"))) {
|
||||||
|
v = &(p.targets[targetIndex].tangent);
|
||||||
|
}
|
||||||
|
else return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Mesh::Read(Value& pJSON_Object, Asset& pAsset_Root)
|
inline void Mesh::Read(Value& pJSON_Object, Asset& pAsset_Root)
|
||||||
|
@ -965,6 +980,26 @@ inline void Mesh::Read(Value& pJSON_Object, Asset& pAsset_Root)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Value* targetsArray = FindArray(primitive, "targets")) {
|
||||||
|
prim.targets.resize(targetsArray->Size());
|
||||||
|
for (unsigned int i = 0; i < targetsArray->Size(); ++i) {
|
||||||
|
Value& target = (*targetsArray)[i];
|
||||||
|
if (!target.IsObject()) continue;
|
||||||
|
for (Value::MemberIterator it = target.MemberBegin(); it != target.MemberEnd(); ++it) {
|
||||||
|
if (!it->value.IsUint()) continue;
|
||||||
|
const char* attr = it->name.GetString();
|
||||||
|
// Valid attribute semantics include POSITION, NORMAL, TANGENT
|
||||||
|
int undPos = 0;
|
||||||
|
Mesh::AccessorList* vec = 0;
|
||||||
|
if (GetAttribTargetVector(prim, i, attr, vec, undPos)) {
|
||||||
|
size_t idx = (attr[undPos] == '_') ? atoi(attr + undPos + 1) : 0;
|
||||||
|
if ((*vec).size() <= idx) (*vec).resize(idx + 1);
|
||||||
|
(*vec)[idx] = pAsset_Root.accessors.Retrieve(it->value.GetUint());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Value* indices = FindUInt(primitive, "indices")) {
|
if (Value* indices = FindUInt(primitive, "indices")) {
|
||||||
prim.indices = pAsset_Root.accessors.Retrieve(indices->GetUint());
|
prim.indices = pAsset_Root.accessors.Retrieve(indices->GetUint());
|
||||||
}
|
}
|
||||||
|
@ -974,6 +1009,16 @@ inline void Mesh::Read(Value& pJSON_Object, Asset& pAsset_Root)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Value* weights = FindArray(pJSON_Object, "weights")) {
|
||||||
|
this->weights.resize(weights->Size());
|
||||||
|
for (unsigned int i = 0; i < weights->Size(); ++i) {
|
||||||
|
Value& weightValue = (*weights)[i];
|
||||||
|
if (weightValue.IsNumber()) {
|
||||||
|
this->weights[i] = weightValue.GetFloat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Camera::Read(Value& obj, Asset& /*r*/)
|
inline void Camera::Read(Value& obj, Asset& /*r*/)
|
||||||
|
@ -1216,12 +1261,15 @@ inline void Asset::Load(const std::string& pFile, bool isBinary)
|
||||||
|
|
||||||
// Read the "scene" property, which specifies which scene to load
|
// Read the "scene" property, which specifies which scene to load
|
||||||
// and recursively load everything referenced by it
|
// and recursively load everything referenced by it
|
||||||
|
unsigned int sceneIndex = 0;
|
||||||
if (Value* scene = FindUInt(doc, "scene")) {
|
if (Value* scene = FindUInt(doc, "scene")) {
|
||||||
unsigned int sceneIndex = scene->GetUint();
|
sceneIndex = scene->GetUint();
|
||||||
|
}
|
||||||
|
|
||||||
Ref<Scene> s = scenes.Retrieve(sceneIndex);
|
if (Value* scenesArray = FindArray(doc, "scenes")) {
|
||||||
|
if (sceneIndex < scenesArray->Size()) {
|
||||||
this->scene = s;
|
this->scene = scenes.Retrieve(sceneIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up
|
// Clean up
|
||||||
|
|
|
@ -94,19 +94,7 @@ glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const ai
|
||||||
, mIOSystem(pIOSystem)
|
, mIOSystem(pIOSystem)
|
||||||
, mProperties(pProperties)
|
, mProperties(pProperties)
|
||||||
{
|
{
|
||||||
aiScene* sceneCopy_tmp;
|
mScene = pScene;
|
||||||
SceneCombiner::CopyScene(&sceneCopy_tmp, pScene);
|
|
||||||
std::unique_ptr<aiScene> sceneCopy(sceneCopy_tmp);
|
|
||||||
|
|
||||||
SplitLargeMeshesProcess_Triangle tri_splitter;
|
|
||||||
tri_splitter.SetLimit(0xffff);
|
|
||||||
tri_splitter.Execute(sceneCopy.get());
|
|
||||||
|
|
||||||
SplitLargeMeshesProcess_Vertex vert_splitter;
|
|
||||||
vert_splitter.SetLimit(0xffff);
|
|
||||||
vert_splitter.Execute(sceneCopy.get());
|
|
||||||
|
|
||||||
mScene = sceneCopy.get();
|
|
||||||
|
|
||||||
mAsset.reset( new Asset( pIOSystem ) );
|
mAsset.reset( new Asset( pIOSystem ) );
|
||||||
|
|
||||||
|
@ -516,7 +504,7 @@ void glTF2Exporter::ExportMaterials()
|
||||||
if (mat->Get(AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR, pbrSG.glossinessFactor) != AI_SUCCESS) {
|
if (mat->Get(AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR, pbrSG.glossinessFactor) != AI_SUCCESS) {
|
||||||
float shininess;
|
float shininess;
|
||||||
|
|
||||||
if (mat->Get(AI_MATKEY_SHININESS, shininess)) {
|
if (mat->Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS) {
|
||||||
pbrSG.glossinessFactor = shininess / 1000;
|
pbrSG.glossinessFactor = shininess / 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -682,12 +670,7 @@ void ExportSkin(Asset& mAsset, const aiMesh* aimesh, Ref<Mesh>& meshRef, Ref<Buf
|
||||||
|
|
||||||
void glTF2Exporter::ExportMeshes()
|
void glTF2Exporter::ExportMeshes()
|
||||||
{
|
{
|
||||||
// Not for
|
typedef decltype(aiFace::mNumIndices) IndicesType;
|
||||||
// using IndicesType = decltype(aiFace::mNumIndices);
|
|
||||||
// But yes for
|
|
||||||
// using IndicesType = unsigned short;
|
|
||||||
// because "ComponentType_UNSIGNED_SHORT" used for indices. And it's a maximal type according to glTF specification.
|
|
||||||
typedef unsigned short IndicesType;
|
|
||||||
|
|
||||||
std::string fname = std::string(mFilename);
|
std::string fname = std::string(mFilename);
|
||||||
std::string bufferIdPrefix = fname.substr(0, fname.rfind(".gltf"));
|
std::string bufferIdPrefix = fname.substr(0, fname.rfind(".gltf"));
|
||||||
|
@ -779,11 +762,11 @@ void glTF2Exporter::ExportMeshes()
|
||||||
indices.resize(aim->mNumFaces * nIndicesPerFace);
|
indices.resize(aim->mNumFaces * nIndicesPerFace);
|
||||||
for (size_t i = 0; i < aim->mNumFaces; ++i) {
|
for (size_t i = 0; i < aim->mNumFaces; ++i) {
|
||||||
for (size_t j = 0; j < nIndicesPerFace; ++j) {
|
for (size_t j = 0; j < nIndicesPerFace; ++j) {
|
||||||
indices[i*nIndicesPerFace + j] = uint16_t(aim->mFaces[i].mIndices[j]);
|
indices[i*nIndicesPerFace + j] = IndicesType(aim->mFaces[i].mIndices[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p.indices = ExportData(*mAsset, meshId, b, unsigned(indices.size()), &indices[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_UNSIGNED_SHORT, true);
|
p.indices = ExportData(*mAsset, meshId, b, unsigned(indices.size()), &indices[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_UNSIGNED_INT, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (aim->mPrimitiveTypes) {
|
switch (aim->mPrimitiveTypes) {
|
||||||
|
|
|
@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/ai_assert.h>
|
#include <assimp/ai_assert.h>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/importerdesc.h>
|
#include <assimp/importerdesc.h>
|
||||||
|
#include <assimp/CreateAnimMesh.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
@ -65,6 +66,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
using namespace glTF2;
|
using namespace glTF2;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
// generate bitangents from normals and tangents according to spec
|
||||||
|
struct Tangent {
|
||||||
|
aiVector3D xyz;
|
||||||
|
ai_real w;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
//
|
//
|
||||||
// glTF2Importer
|
// glTF2Importer
|
||||||
|
@ -109,18 +117,29 @@ bool glTF2Importer::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool
|
||||||
|
|
||||||
if (pIOHandler) {
|
if (pIOHandler) {
|
||||||
glTF2::Asset asset(pIOHandler);
|
glTF2::Asset asset(pIOHandler);
|
||||||
try {
|
|
||||||
asset.Load(pFile, extension == "glb");
|
asset.Load(pFile, extension == "glb");
|
||||||
std::string version = asset.asset.version;
|
std::string version = asset.asset.version;
|
||||||
return !version.empty() && version[0] == '2';
|
return !version.empty() && version[0] == '2';
|
||||||
} catch (...) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static aiTextureMapMode ConvertWrappingMode(SamplerWrap gltfWrapMode)
|
||||||
|
{
|
||||||
|
switch (gltfWrapMode) {
|
||||||
|
case SamplerWrap::Mirrored_Repeat:
|
||||||
|
return aiTextureMapMode_Mirror;
|
||||||
|
|
||||||
|
case SamplerWrap::Clamp_To_Edge:
|
||||||
|
return aiTextureMapMode_Clamp;
|
||||||
|
|
||||||
|
case SamplerWrap::UNSET:
|
||||||
|
case SamplerWrap::Repeat:
|
||||||
|
default:
|
||||||
|
return aiTextureMapMode_Wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//static void CopyValue(const glTF2::vec3& v, aiColor3D& out)
|
//static void CopyValue(const glTF2::vec3& v, aiColor3D& out)
|
||||||
//{
|
//{
|
||||||
|
@ -198,8 +217,10 @@ inline void SetMaterialTextureProperty(std::vector<int>& embeddedTexIdxs, Asset&
|
||||||
mat->AddProperty(&name, AI_MATKEY_GLTF_MAPPINGNAME(texType, texSlot));
|
mat->AddProperty(&name, AI_MATKEY_GLTF_MAPPINGNAME(texType, texSlot));
|
||||||
mat->AddProperty(&id, AI_MATKEY_GLTF_MAPPINGID(texType, texSlot));
|
mat->AddProperty(&id, AI_MATKEY_GLTF_MAPPINGID(texType, texSlot));
|
||||||
|
|
||||||
mat->AddProperty(&sampler->wrapS, 1, AI_MATKEY_MAPPINGMODE_U(texType, texSlot));
|
aiTextureMapMode wrapS = ConvertWrappingMode(sampler->wrapS);
|
||||||
mat->AddProperty(&sampler->wrapT, 1, AI_MATKEY_MAPPINGMODE_V(texType, texSlot));
|
aiTextureMapMode wrapT = ConvertWrappingMode(sampler->wrapT);
|
||||||
|
mat->AddProperty(&wrapS, 1, AI_MATKEY_MAPPINGMODE_U(texType, texSlot));
|
||||||
|
mat->AddProperty(&wrapT, 1, AI_MATKEY_MAPPINGMODE_V(texType, texSlot));
|
||||||
|
|
||||||
if (sampler->magFilter != SamplerMagFilter::UNSET) {
|
if (sampler->magFilter != SamplerMagFilter::UNSET) {
|
||||||
mat->AddProperty(&sampler->magFilter, 1, AI_MATKEY_GLTF_MAPPINGFILTER_MAG(texType, texSlot));
|
mat->AddProperty(&sampler->magFilter, 1, AI_MATKEY_GLTF_MAPPINGFILTER_MAG(texType, texSlot));
|
||||||
|
@ -399,10 +420,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
|
||||||
// only extract tangents if normals are present
|
// only extract tangents if normals are present
|
||||||
if (attr.tangent.size() > 0 && attr.tangent[0]) {
|
if (attr.tangent.size() > 0 && attr.tangent[0]) {
|
||||||
// generate bitangents from normals and tangents according to spec
|
// generate bitangents from normals and tangents according to spec
|
||||||
struct Tangent {
|
Tangent *tangents = nullptr;
|
||||||
aiVector3D xyz;
|
|
||||||
ai_real w;
|
|
||||||
} *tangents = nullptr;
|
|
||||||
|
|
||||||
attr.tangent[0]->ExtractData(tangents);
|
attr.tangent[0]->ExtractData(tangents);
|
||||||
|
|
||||||
|
@ -419,6 +437,12 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
|
for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
|
||||||
|
if (attr.texcoord[tc]->count != aim->mNumVertices) {
|
||||||
|
DefaultLogger::get()->warn("Texcoord stream size in mesh \"" + mesh.name +
|
||||||
|
"\" does not match the vertex count");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]);
|
attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]);
|
||||||
aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents();
|
aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents();
|
||||||
|
|
||||||
|
@ -428,11 +452,57 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Mesh::Primitive::Target>& targets = prim.targets;
|
||||||
|
if (targets.size() > 0) {
|
||||||
|
aim->mNumAnimMeshes = targets.size();
|
||||||
|
aim->mAnimMeshes = new aiAnimMesh*[aim->mNumAnimMeshes];
|
||||||
|
for (size_t i = 0; i < targets.size(); i++) {
|
||||||
|
aim->mAnimMeshes[i] = aiCreateAnimMesh(aim);
|
||||||
|
aiAnimMesh& aiAnimMesh = *(aim->mAnimMeshes[i]);
|
||||||
|
Mesh::Primitive::Target& target = targets[i];
|
||||||
|
|
||||||
|
if (target.position.size() > 0) {
|
||||||
|
aiVector3D *positionDiff = nullptr;
|
||||||
|
target.position[0]->ExtractData(positionDiff);
|
||||||
|
for(unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) {
|
||||||
|
aiAnimMesh.mVertices[vertexId] += positionDiff[vertexId];
|
||||||
|
}
|
||||||
|
delete [] positionDiff;
|
||||||
|
}
|
||||||
|
if (target.normal.size() > 0) {
|
||||||
|
aiVector3D *normalDiff = nullptr;
|
||||||
|
target.normal[0]->ExtractData(normalDiff);
|
||||||
|
for(unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) {
|
||||||
|
aiAnimMesh.mNormals[vertexId] += normalDiff[vertexId];
|
||||||
|
}
|
||||||
|
delete [] normalDiff;
|
||||||
|
}
|
||||||
|
if (target.tangent.size() > 0) {
|
||||||
|
Tangent *tangent = nullptr;
|
||||||
|
attr.tangent[0]->ExtractData(tangent);
|
||||||
|
|
||||||
|
aiVector3D *tangentDiff = nullptr;
|
||||||
|
target.tangent[0]->ExtractData(tangentDiff);
|
||||||
|
|
||||||
|
for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; ++vertexId) {
|
||||||
|
tangent[vertexId].xyz += tangentDiff[vertexId];
|
||||||
|
aiAnimMesh.mTangents[vertexId] = tangent[vertexId].xyz;
|
||||||
|
aiAnimMesh.mBitangents[vertexId] = (aiAnimMesh.mNormals[vertexId] ^ tangent[vertexId].xyz) * tangent[vertexId].w;
|
||||||
|
}
|
||||||
|
delete [] tangent;
|
||||||
|
delete [] tangentDiff;
|
||||||
|
}
|
||||||
|
if (mesh.weights.size() > i) {
|
||||||
|
aiAnimMesh.mWeight = mesh.weights[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (prim.indices) {
|
|
||||||
aiFace* faces = 0;
|
aiFace* faces = 0;
|
||||||
unsigned int nFaces = 0;
|
unsigned int nFaces = 0;
|
||||||
|
|
||||||
|
if (prim.indices) {
|
||||||
unsigned int count = prim.indices->count;
|
unsigned int count = prim.indices->count;
|
||||||
|
|
||||||
Accessor::Indexer data = prim.indices->GetIndexer();
|
Accessor::Indexer data = prim.indices->GetIndexer();
|
||||||
|
@ -482,9 +552,18 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
|
||||||
case PrimitiveMode_TRIANGLE_STRIP: {
|
case PrimitiveMode_TRIANGLE_STRIP: {
|
||||||
nFaces = count - 2;
|
nFaces = count - 2;
|
||||||
faces = new aiFace[nFaces];
|
faces = new aiFace[nFaces];
|
||||||
SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
|
for (unsigned int i = 0; i < nFaces; ++i) {
|
||||||
for (unsigned int i = 3; i < count; ++i) {
|
//The ordering is to ensure that the triangles are all drawn with the same orientation
|
||||||
SetFace(faces[i - 2], faces[i - 1].mIndices[1], faces[i - 1].mIndices[2], data.GetUInt(i));
|
if ((i + 1) % 2 == 0)
|
||||||
|
{
|
||||||
|
//For even n, vertices n + 1, n, and n + 2 define triangle n
|
||||||
|
SetFace(faces[i], data.GetUInt(i + 1), data.GetUInt(i), data.GetUInt(i + 2));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//For odd n, vertices n, n+1, and n+2 define triangle n
|
||||||
|
SetFace(faces[i], data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -492,19 +571,92 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
|
||||||
nFaces = count - 2;
|
nFaces = count - 2;
|
||||||
faces = new aiFace[nFaces];
|
faces = new aiFace[nFaces];
|
||||||
SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
|
SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
|
||||||
for (unsigned int i = 3; i < count; ++i) {
|
for (unsigned int i = 1; i < nFaces; ++i) {
|
||||||
SetFace(faces[i - 2], faces[0].mIndices[0], faces[i - 1].mIndices[2], data.GetUInt(i));
|
SetFace(faces[i], faces[0].mIndices[0], faces[i - 1].mIndices[2], data.GetUInt(i + 2));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else { // no indices provided so directly generate from counts
|
||||||
|
|
||||||
|
// use the already determined count as it includes checks
|
||||||
|
unsigned int count = aim->mNumVertices;
|
||||||
|
|
||||||
|
switch (prim.mode) {
|
||||||
|
case PrimitiveMode_POINTS: {
|
||||||
|
nFaces = count;
|
||||||
|
faces = new aiFace[nFaces];
|
||||||
|
for (unsigned int i = 0; i < count; ++i) {
|
||||||
|
SetFace(faces[i], i);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PrimitiveMode_LINES: {
|
||||||
|
nFaces = count / 2;
|
||||||
|
faces = new aiFace[nFaces];
|
||||||
|
for (unsigned int i = 0; i < count; i += 2) {
|
||||||
|
SetFace(faces[i / 2], i, i + 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PrimitiveMode_LINE_LOOP:
|
||||||
|
case PrimitiveMode_LINE_STRIP: {
|
||||||
|
nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
|
||||||
|
faces = new aiFace[nFaces];
|
||||||
|
SetFace(faces[0], 0, 1);
|
||||||
|
for (unsigned int i = 2; i < count; ++i) {
|
||||||
|
SetFace(faces[i - 1], faces[i - 2].mIndices[1], i);
|
||||||
|
}
|
||||||
|
if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
|
||||||
|
SetFace(faces[count - 1], faces[count - 2].mIndices[1], faces[0].mIndices[0]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PrimitiveMode_TRIANGLES: {
|
||||||
|
nFaces = count / 3;
|
||||||
|
faces = new aiFace[nFaces];
|
||||||
|
for (unsigned int i = 0; i < count; i += 3) {
|
||||||
|
SetFace(faces[i / 3], i, i + 1, i + 2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PrimitiveMode_TRIANGLE_STRIP: {
|
||||||
|
nFaces = count - 2;
|
||||||
|
faces = new aiFace[nFaces];
|
||||||
|
for (unsigned int i = 0; i < nFaces; ++i) {
|
||||||
|
//The ordering is to ensure that the triangles are all drawn with the same orientation
|
||||||
|
if ((i+1) % 2 == 0)
|
||||||
|
{
|
||||||
|
//For even n, vertices n + 1, n, and n + 2 define triangle n
|
||||||
|
SetFace(faces[i], i+1, i, i+2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//For odd n, vertices n, n+1, and n+2 define triangle n
|
||||||
|
SetFace(faces[i], i, i+1, i+2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PrimitiveMode_TRIANGLE_FAN:
|
||||||
|
nFaces = count - 2;
|
||||||
|
faces = new aiFace[nFaces];
|
||||||
|
SetFace(faces[0], 0, 1, 2);
|
||||||
|
for (unsigned int i = 1; i < nFaces; ++i) {
|
||||||
|
SetFace(faces[i], faces[0].mIndices[0], faces[i - 1].mIndices[2], i + 2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (faces) {
|
if (faces) {
|
||||||
aim->mFaces = faces;
|
aim->mFaces = faces;
|
||||||
aim->mNumFaces = nFaces;
|
aim->mNumFaces = nFaces;
|
||||||
ai_assert(CheckValidFacesIndices(faces, nFaces, aim->mNumVertices));
|
ai_assert(CheckValidFacesIndices(faces, nFaces, aim->mNumVertices));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (prim.material) {
|
if (prim.material) {
|
||||||
aim->mMaterialIndex = prim.material.GetIndex();
|
aim->mMaterialIndex = prim.material.GetIndex();
|
||||||
|
@ -716,12 +868,6 @@ void glTF2Importer::InternReadFile(const std::string& pFile, aiScene* pScene, IO
|
||||||
|
|
||||||
ImportNodes(asset);
|
ImportNodes(asset);
|
||||||
|
|
||||||
// TODO: it does not split the loaded vertices, should it?
|
|
||||||
//pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
|
|
||||||
MakeVerboseFormatProcess process;
|
|
||||||
process.Execute(pScene);
|
|
||||||
|
|
||||||
|
|
||||||
if (pScene->mNumMeshes == 0) {
|
if (pScene->mNumMeshes == 0) {
|
||||||
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
|
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -351,10 +351,10 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (prim.indices) {
|
|
||||||
aiFace* faces = 0;
|
aiFace* faces = 0;
|
||||||
unsigned int nFaces = 0;
|
unsigned int nFaces = 0;
|
||||||
|
|
||||||
|
if (prim.indices) {
|
||||||
unsigned int count = prim.indices->count;
|
unsigned int count = prim.indices->count;
|
||||||
|
|
||||||
Accessor::Indexer data = prim.indices->GetIndexer();
|
Accessor::Indexer data = prim.indices->GetIndexer();
|
||||||
|
@ -419,14 +419,78 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else { // no indices provided so directly generate from counts
|
||||||
|
|
||||||
|
// use the already determined count as it includes checks
|
||||||
|
unsigned int count = aim->mNumVertices;
|
||||||
|
|
||||||
|
switch (prim.mode) {
|
||||||
|
case PrimitiveMode_POINTS: {
|
||||||
|
nFaces = count;
|
||||||
|
faces = new aiFace[nFaces];
|
||||||
|
for (unsigned int i = 0; i < count; ++i) {
|
||||||
|
SetFace(faces[i], i);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PrimitiveMode_LINES: {
|
||||||
|
nFaces = count / 2;
|
||||||
|
faces = new aiFace[nFaces];
|
||||||
|
for (unsigned int i = 0; i < count; i += 2) {
|
||||||
|
SetFace(faces[i / 2], i, i + 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PrimitiveMode_LINE_LOOP:
|
||||||
|
case PrimitiveMode_LINE_STRIP: {
|
||||||
|
nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
|
||||||
|
faces = new aiFace[nFaces];
|
||||||
|
SetFace(faces[0], 0, 1);
|
||||||
|
for (unsigned int i = 2; i < count; ++i) {
|
||||||
|
SetFace(faces[i - 1], faces[i - 2].mIndices[1], i);
|
||||||
|
}
|
||||||
|
if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
|
||||||
|
SetFace(faces[count - 1], faces[count - 2].mIndices[1], faces[0].mIndices[0]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PrimitiveMode_TRIANGLES: {
|
||||||
|
nFaces = count / 3;
|
||||||
|
faces = new aiFace[nFaces];
|
||||||
|
for (unsigned int i = 0; i < count; i += 3) {
|
||||||
|
SetFace(faces[i / 3], i, i + 1, i + 2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PrimitiveMode_TRIANGLE_STRIP: {
|
||||||
|
nFaces = count - 2;
|
||||||
|
faces = new aiFace[nFaces];
|
||||||
|
SetFace(faces[0], 0, 1, 2);
|
||||||
|
for (unsigned int i = 3; i < count; ++i) {
|
||||||
|
SetFace(faces[i - 2], faces[i - 1].mIndices[1], faces[i - 1].mIndices[2], i);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PrimitiveMode_TRIANGLE_FAN:
|
||||||
|
nFaces = count - 2;
|
||||||
|
faces = new aiFace[nFaces];
|
||||||
|
SetFace(faces[0], 0, 1, 2);
|
||||||
|
for (unsigned int i = 3; i < count; ++i) {
|
||||||
|
SetFace(faces[i - 2], faces[0].mIndices[0], faces[i - 1].mIndices[2], i);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (faces) {
|
if (faces) {
|
||||||
aim->mFaces = faces;
|
aim->mFaces = faces;
|
||||||
aim->mNumFaces = nFaces;
|
aim->mNumFaces = nFaces;
|
||||||
ai_assert(CheckValidFacesIndices(faces, nFaces, aim->mNumVertices));
|
ai_assert(CheckValidFacesIndices(faces, nFaces, aim->mNumVertices));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (prim.material) {
|
if (prim.material) {
|
||||||
aim->mMaterialIndex = prim.material.GetIndex();
|
aim->mMaterialIndex = prim.material.GetIndex();
|
||||||
|
@ -676,11 +740,6 @@ void glTFImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOS
|
||||||
|
|
||||||
ImportNodes(asset);
|
ImportNodes(asset);
|
||||||
|
|
||||||
// TODO: it does not split the loaded vertices, should it?
|
|
||||||
//pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
|
|
||||||
MakeVerboseFormatProcess process;
|
|
||||||
process.Execute(pScene);
|
|
||||||
|
|
||||||
|
|
||||||
if (pScene->mNumMeshes == 0) {
|
if (pScene->mNumMeshes == 0) {
|
||||||
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
|
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
|
||||||
|
|
|
@ -21,7 +21,6 @@ class array
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
array()
|
array()
|
||||||
: data(0), allocated(0), used(0),
|
: data(0), allocated(0), used(0),
|
||||||
free_when_destroyed(true), is_sorted(true)
|
free_when_destroyed(true), is_sorted(true)
|
||||||
|
|
|
@ -100,10 +100,16 @@ static bool isUnsignedIntegerType( Value::ValueType integerType ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static DDLNode *createDDLNode( Text *id, OpenDDLParser *parser ) {
|
static DDLNode *createDDLNode( Text *id, OpenDDLParser *parser ) {
|
||||||
|
// Basic checks
|
||||||
if( ddl_nullptr == id || ddl_nullptr == parser ) {
|
if( ddl_nullptr == id || ddl_nullptr == parser ) {
|
||||||
return ddl_nullptr;
|
return ddl_nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the buffer is empty ( an empty node ) return nullptr
|
||||||
|
if ( ddl_nullptr == id->m_buffer ) {
|
||||||
|
return ddl_nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string type( id->m_buffer );
|
const std::string type( id->m_buffer );
|
||||||
DDLNode *parent( parser->top() );
|
DDLNode *parent( parser->top() );
|
||||||
DDLNode *node = DDLNode::create( type, "", parent );
|
DDLNode *node = DDLNode::create( type, "", parent );
|
||||||
|
|
|
@ -77,19 +77,17 @@ class IOStream;
|
||||||
* imports the given file. ReadFile is not overridable, it just calls
|
* imports the given file. ReadFile is not overridable, it just calls
|
||||||
* InternReadFile() and catches any ImportErrorException that might occur.
|
* InternReadFile() and catches any ImportErrorException that might occur.
|
||||||
*/
|
*/
|
||||||
class ASSIMP_API BaseImporter
|
class ASSIMP_API BaseImporter {
|
||||||
{
|
|
||||||
friend class Importer;
|
friend class Importer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Constructor to be privately used by #Importer */
|
/** Constructor to be privately used by #Importer */
|
||||||
BaseImporter();
|
BaseImporter() AI_NO_EXCEPT;
|
||||||
|
|
||||||
/** Destructor, private as well */
|
/** Destructor, private as well */
|
||||||
virtual ~BaseImporter();
|
virtual ~BaseImporter();
|
||||||
|
|
||||||
public:
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
*
|
*
|
||||||
|
@ -244,7 +242,8 @@ public: // static utilities
|
||||||
const char** tokens,
|
const char** tokens,
|
||||||
unsigned int numTokens,
|
unsigned int numTokens,
|
||||||
unsigned int searchBytes = 200,
|
unsigned int searchBytes = 200,
|
||||||
bool tokensSol = false);
|
bool tokensSol = false,
|
||||||
|
bool noAlphaBeforeTokens = false);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Check whether a file has a specific file extension
|
/** @brief Check whether a file has a specific file extension
|
||||||
|
|
|
@ -60,9 +60,8 @@ namespace Assimp {
|
||||||
* This is required to read big-endian model formats on little-endian machines,
|
* This is required to read big-endian model formats on little-endian machines,
|
||||||
* and vice versa. Direct use of this class is DEPRECATED. Use #StreamReader instead. */
|
* and vice versa. Direct use of this class is DEPRECATED. Use #StreamReader instead. */
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
class ByteSwap
|
class ByteSwap {
|
||||||
{
|
ByteSwap() AI_NO_EXCEPT {}
|
||||||
ByteSwap() {}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ class ASSIMP_API DefaultIOStream : public IOStream
|
||||||
#endif // __ANDROID__
|
#endif // __ANDROID__
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DefaultIOStream();
|
DefaultIOStream() AI_NO_EXCEPT;
|
||||||
DefaultIOStream(FILE* pFile, const std::string &strFilename);
|
DefaultIOStream(FILE* pFile, const std::string &strFilename);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -111,27 +111,25 @@ private:
|
||||||
FILE* mFile;
|
FILE* mFile;
|
||||||
// Filename
|
// Filename
|
||||||
std::string mFilename;
|
std::string mFilename;
|
||||||
|
|
||||||
// Cached file size
|
// Cached file size
|
||||||
mutable size_t mCachedSize;
|
mutable size_t mCachedSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
inline DefaultIOStream::DefaultIOStream () :
|
inline
|
||||||
mFile (NULL),
|
DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT
|
||||||
mFilename (""),
|
: mFile(nullptr)
|
||||||
mCachedSize(SIZE_MAX)
|
, mFilename("")
|
||||||
{
|
, mCachedSize(SIZE_MAX) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
inline DefaultIOStream::DefaultIOStream (FILE* pFile,
|
inline
|
||||||
const std::string &strFilename) :
|
DefaultIOStream::DefaultIOStream (FILE* pFile, const std::string &strFilename)
|
||||||
mFile(pFile),
|
: mFile(pFile)
|
||||||
mFilename(strFilename),
|
, mFilename(strFilename)
|
||||||
mCachedSize(SIZE_MAX)
|
, mCachedSize(SIZE_MAX) {
|
||||||
{
|
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
|
|
|
@ -50,8 +50,7 @@ namespace Assimp {
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Default implementation of IOSystem using the standard C file functions */
|
/** Default implementation of IOSystem using the standard C file functions */
|
||||||
class ASSIMP_API DefaultIOSystem : public IOSystem
|
class ASSIMP_API DefaultIOSystem : public IOSystem {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Tests for the existence of a file at the given path. */
|
/** Tests for the existence of a file at the given path. */
|
||||||
|
|
|
@ -71,7 +71,7 @@ class ASSIMP_API IOStream
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
/** Constructor protected, use IOSystem::Open() to create an instance. */
|
/** Constructor protected, use IOSystem::Open() to create an instance. */
|
||||||
IOStream();
|
IOStream() AI_NO_EXCEPT;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
@ -126,7 +126,7 @@ public:
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
inline
|
inline
|
||||||
IOStream::IOStream() {
|
IOStream::IOStream() AI_NO_EXCEPT {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ public:
|
||||||
* Create an instance of your derived class and assign it to an
|
* Create an instance of your derived class and assign it to an
|
||||||
* #Assimp::Importer instance by calling Importer::SetIOHandler().
|
* #Assimp::Importer instance by calling Importer::SetIOHandler().
|
||||||
*/
|
*/
|
||||||
IOSystem();
|
IOSystem() AI_NO_EXCEPT;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Virtual destructor.
|
/** @brief Virtual destructor.
|
||||||
|
@ -105,9 +105,6 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual ~IOSystem();
|
virtual ~IOSystem();
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief For backward compatibility
|
/** @brief For backward compatibility
|
||||||
* @see Exists(const char*)
|
* @see Exists(const char*)
|
||||||
|
@ -233,7 +230,7 @@ private:
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
AI_FORCE_INLINE
|
AI_FORCE_INLINE
|
||||||
IOSystem::IOSystem()
|
IOSystem::IOSystem() AI_NO_EXCEPT
|
||||||
: m_pathStack() {
|
: m_pathStack() {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,11 +44,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* @brief LineSplitter, a helper class to iterate through all lines
|
* @brief LineSplitter, a helper class to iterate through all lines
|
||||||
* of a file easily. Works with StreamReader.
|
* of a file easily. Works with StreamReader.
|
||||||
*/
|
*/
|
||||||
|
#pragma once
|
||||||
#ifndef INCLUDED_LINE_SPLITTER_H
|
#ifndef INCLUDED_LINE_SPLITTER_H
|
||||||
#define INCLUDED_LINE_SPLITTER_H
|
#define INCLUDED_LINE_SPLITTER_H
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#include "StreamReader.h"
|
#include "StreamReader.h"
|
||||||
#include "ParsingUtils.h"
|
#include "ParsingUtils.h"
|
||||||
|
|
||||||
|
@ -81,72 +81,131 @@ public:
|
||||||
/** construct from existing stream reader
|
/** construct from existing stream reader
|
||||||
note: trim is *always* assumed true if skyp_empty_lines==true
|
note: trim is *always* assumed true if skyp_empty_lines==true
|
||||||
*/
|
*/
|
||||||
LineSplitter(StreamReaderLE& stream, bool skip_empty_lines = true, bool trim = true)
|
LineSplitter(StreamReaderLE& stream, bool skip_empty_lines = true, bool trim = true);
|
||||||
: idx( 0 )
|
|
||||||
, stream(stream)
|
|
||||||
, swallow()
|
|
||||||
, skip_empty_lines(skip_empty_lines)
|
|
||||||
, trim(trim) {
|
|
||||||
cur.reserve(1024);
|
|
||||||
operator++();
|
|
||||||
|
|
||||||
idx = 0;
|
~LineSplitter();
|
||||||
}
|
|
||||||
|
|
||||||
~LineSplitter() {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
/** pseudo-iterator increment */
|
/** pseudo-iterator increment */
|
||||||
LineSplitter& operator++() {
|
LineSplitter& operator++();
|
||||||
if(swallow) {
|
|
||||||
swallow = false;
|
// -----------------------------------------
|
||||||
|
LineSplitter& operator++(int);
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
/** get a pointer to the beginning of a particular token */
|
||||||
|
const char* operator[] (size_t idx) const;
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
/** extract the start positions of N tokens from the current line*/
|
||||||
|
template <size_t N>
|
||||||
|
void get_tokens(const char* (&tokens)[N]) const;
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
/** member access */
|
||||||
|
const std::string* operator -> () const;
|
||||||
|
|
||||||
|
std::string operator* () const;
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
/** boolean context */
|
||||||
|
operator bool() const;
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
/** line indices are zero-based, empty lines are included */
|
||||||
|
operator line_idx() const;
|
||||||
|
|
||||||
|
line_idx get_index() const;
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
/** access the underlying stream object */
|
||||||
|
StreamReaderLE& get_stream();
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
/** !strcmp((*this)->substr(0,strlen(check)),check) */
|
||||||
|
bool match_start(const char* check);
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
/** swallow the next call to ++, return the previous value. */
|
||||||
|
void swallow_next_increment();
|
||||||
|
|
||||||
|
LineSplitter( const LineSplitter & ) = delete;
|
||||||
|
LineSplitter(LineSplitter &&) = delete;
|
||||||
|
LineSplitter &operator = ( const LineSplitter & ) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
line_idx mIdx;
|
||||||
|
std::string mCur;
|
||||||
|
StreamReaderLE& mStream;
|
||||||
|
bool mSwallow, mSkip_empty_lines, mTrim;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline
|
||||||
|
LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool trim )
|
||||||
|
: mIdx(0)
|
||||||
|
, mCur()
|
||||||
|
, mStream(stream)
|
||||||
|
, mSwallow()
|
||||||
|
, mSkip_empty_lines(skip_empty_lines)
|
||||||
|
, mTrim(trim) {
|
||||||
|
mCur.reserve(1024);
|
||||||
|
operator++();
|
||||||
|
mIdx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
LineSplitter::~LineSplitter() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
LineSplitter& LineSplitter::operator++() {
|
||||||
|
if (mSwallow) {
|
||||||
|
mSwallow = false;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!*this) {
|
if (!*this) {
|
||||||
throw std::logic_error("End of file, no more lines to be retrieved.");
|
throw std::logic_error("End of file, no more lines to be retrieved.");
|
||||||
}
|
}
|
||||||
|
|
||||||
char s;
|
char s;
|
||||||
cur.clear();
|
mCur.clear();
|
||||||
while(stream.GetRemainingSize() && (s = stream.GetI1(),1)) {
|
while (mStream.GetRemainingSize() && (s = mStream.GetI1(), 1)) {
|
||||||
if (s == '\n' || s == '\r') {
|
if (s == '\n' || s == '\r') {
|
||||||
if (skip_empty_lines) {
|
if (mSkip_empty_lines) {
|
||||||
while (stream.GetRemainingSize() && ((s = stream.GetI1()) == ' ' || s == '\r' || s == '\n'));
|
while (mStream.GetRemainingSize() && ((s = mStream.GetI1()) == ' ' || s == '\r' || s == '\n'));
|
||||||
if (stream.GetRemainingSize()) {
|
if (mStream.GetRemainingSize()) {
|
||||||
stream.IncPtr(-1);
|
mStream.IncPtr(-1);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// skip both potential line terminators but don't read past this line.
|
// skip both potential line terminators but don't read past this line.
|
||||||
if (stream.GetRemainingSize() && (s == '\r' && stream.GetI1() != '\n')) {
|
if (mStream.GetRemainingSize() && (s == '\r' && mStream.GetI1() != '\n')) {
|
||||||
stream.IncPtr(-1);
|
mStream.IncPtr(-1);
|
||||||
}
|
}
|
||||||
if (trim) {
|
if (mTrim) {
|
||||||
while (stream.GetRemainingSize() && ((s = stream.GetI1()) == ' ' || s == '\t'));
|
while (mStream.GetRemainingSize() && ((s = mStream.GetI1()) == ' ' || s == '\t'));
|
||||||
if (stream.GetRemainingSize()) {
|
if (mStream.GetRemainingSize()) {
|
||||||
stream.IncPtr(-1);
|
mStream.IncPtr(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cur += s;
|
mCur += s;
|
||||||
}
|
}
|
||||||
++idx;
|
++mIdx;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
inline
|
||||||
LineSplitter& operator++(int) {
|
LineSplitter &LineSplitter::operator++(int) {
|
||||||
return ++(*this);
|
return ++(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
inline
|
||||||
/** get a pointer to the beginning of a particular token */
|
const char *LineSplitter::operator[] (size_t idx) const {
|
||||||
const char* operator[] (size_t idx) const {
|
|
||||||
const char* s = operator->()->c_str();
|
const char* s = operator->()->c_str();
|
||||||
|
|
||||||
SkipSpaces(&s);
|
SkipSpaces(&s);
|
||||||
|
@ -162,18 +221,15 @@ public:
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
|
||||||
/** extract the start positions of N tokens from the current line*/
|
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
void get_tokens(const char* (&tokens)[N]) const {
|
inline
|
||||||
|
void LineSplitter::get_tokens(const char* (&tokens)[N]) const {
|
||||||
const char* s = operator->()->c_str();
|
const char* s = operator->()->c_str();
|
||||||
|
|
||||||
SkipSpaces(&s);
|
SkipSpaces(&s);
|
||||||
for (size_t i = 0; i < N; ++i) {
|
for (size_t i = 0; i < N; ++i) {
|
||||||
if (IsLineEnd(*s)) {
|
if (IsLineEnd(*s)) {
|
||||||
|
|
||||||
throw std::range_error("Token count out of range, EOL reached");
|
throw std::range_error("Token count out of range, EOL reached");
|
||||||
|
|
||||||
}
|
}
|
||||||
tokens[i] = s;
|
tokens[i] = s;
|
||||||
|
|
||||||
|
@ -182,63 +238,48 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
inline
|
||||||
/** member access */
|
const std::string* LineSplitter::operator -> () const {
|
||||||
const std::string* operator -> () const {
|
return &mCur;
|
||||||
return &cur;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string operator* () const {
|
inline
|
||||||
return cur;
|
std::string LineSplitter::operator* () const {
|
||||||
|
return mCur;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
inline
|
||||||
/** boolean context */
|
LineSplitter::operator bool() const {
|
||||||
operator bool() const {
|
return mStream.GetRemainingSize() > 0;
|
||||||
return stream.GetRemainingSize()>0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
inline
|
||||||
/** line indices are zero-based, empty lines are included */
|
LineSplitter::operator line_idx() const {
|
||||||
operator line_idx() const {
|
return mIdx;
|
||||||
return idx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
line_idx get_index() const {
|
inline
|
||||||
return idx;
|
LineSplitter::line_idx LineSplitter::get_index() const {
|
||||||
|
return mIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
inline
|
||||||
/** access the underlying stream object */
|
StreamReaderLE &LineSplitter::get_stream() {
|
||||||
StreamReaderLE& get_stream() {
|
return mStream;
|
||||||
return stream;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
inline
|
||||||
/** !strcmp((*this)->substr(0,strlen(check)),check) */
|
bool LineSplitter::match_start(const char* check) {
|
||||||
bool match_start(const char* check) {
|
const size_t len = ::strlen(check);
|
||||||
const size_t len = strlen(check);
|
|
||||||
|
|
||||||
return len <= cur.length() && std::equal(check,check+len,cur.begin());
|
return len <= mCur.length() && std::equal(check, check + len, mCur.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
// -----------------------------------------
|
void LineSplitter::swallow_next_increment() {
|
||||||
/** swallow the next call to ++, return the previous value. */
|
mSwallow = true;
|
||||||
void swallow_next_increment() {
|
|
||||||
swallow = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
} // Namespace Assimp
|
||||||
LineSplitter( const LineSplitter & );
|
|
||||||
LineSplitter &operator = ( const LineSplitter & );
|
|
||||||
|
|
||||||
private:
|
|
||||||
line_idx idx;
|
|
||||||
std::string cur;
|
|
||||||
StreamReaderLE& stream;
|
|
||||||
bool swallow, skip_empty_lines, trim;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif // INCLUDED_LINE_SPLITTER_H
|
#endif // INCLUDED_LINE_SPLITTER_H
|
||||||
|
|
|
@ -65,7 +65,7 @@ class ASSIMP_API LogStream
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
/** @brief Default constructor */
|
/** @brief Default constructor */
|
||||||
LogStream();
|
LogStream() AI_NO_EXCEPT;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** @brief Virtual destructor */
|
/** @brief Virtual destructor */
|
||||||
|
@ -91,12 +91,12 @@ public:
|
||||||
* @return New LogStream instance. */
|
* @return New LogStream instance. */
|
||||||
static LogStream* createDefaultStream(aiDefaultLogStream stream,
|
static LogStream* createDefaultStream(aiDefaultLogStream stream,
|
||||||
const char* name = "AssimpLog.txt",
|
const char* name = "AssimpLog.txt",
|
||||||
IOSystem* io = NULL);
|
IOSystem* io = nullptr );
|
||||||
|
|
||||||
}; // !class LogStream
|
}; // !class LogStream
|
||||||
|
|
||||||
inline
|
inline
|
||||||
LogStream::LogStream() {
|
LogStream::LogStream() AI_NO_EXCEPT {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,7 @@ protected:
|
||||||
/**
|
/**
|
||||||
* Default constructor
|
* Default constructor
|
||||||
*/
|
*/
|
||||||
Logger();
|
Logger() AI_NO_EXCEPT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construction with a given log severity
|
* Construction with a given log severity
|
||||||
|
@ -215,8 +215,9 @@ protected:
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
// Default constructor
|
// Default constructor
|
||||||
inline
|
inline
|
||||||
Logger::Logger() {
|
Logger::Logger() AI_NO_EXCEPT
|
||||||
setLogSeverity(NORMAL);
|
: m_Severity(NORMAL) {
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
|
@ -229,8 +230,9 @@ Logger::~Logger() {
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
// Construction with given logging severity
|
// Construction with given logging severity
|
||||||
inline
|
inline
|
||||||
Logger::Logger(LogSeverity severity) {
|
Logger::Logger(LogSeverity severity)
|
||||||
setLogSeverity(severity);
|
: m_Severity(severity) {
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2018, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue