Merge branch 'master' into umw_dev
commit
02c4b7f1bc
|
@ -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
|
||||||
|
@ -38,6 +41,7 @@ tools/assimp_cmd/Makefile
|
||||||
|
|
||||||
# Tests
|
# Tests
|
||||||
test/results
|
test/results
|
||||||
|
test/readlinetest*
|
||||||
|
|
||||||
# Python
|
# Python
|
||||||
__pycache__
|
__pycache__
|
||||||
|
@ -84,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
|
258
CHANGES
258
CHANGES
|
@ -1,6 +1,264 @@
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
4.1.0 (2017-12):
|
||||||
|
- FEATURES:
|
||||||
|
- Export 3MF ( experimental )
|
||||||
|
- Import / Export glTF 2
|
||||||
|
- Introduce new zib-lib to eb able to export zip-archives
|
||||||
|
- FIXES/HOUSEKEEPING:
|
||||||
|
- Added missing include to stdlib.h and remove load library call
|
||||||
|
- Fix install for builds with MSVC compiler and NMake.
|
||||||
|
- Update list of supported file formats.
|
||||||
|
- Add TriLib to the official list of supported ports.
|
||||||
|
- Re-enabling PACK_STRUCT for MDL files.
|
||||||
|
- Use std.::unique_ptr
|
||||||
|
- Update D3MFExporter.h
|
||||||
|
- Update MD3Loader.cpp, using index
|
||||||
|
- Fix all warnings on MSVC14
|
||||||
|
- Copy assimp dll to unit folder on windows
|
||||||
|
- Update jvm port supported formats
|
||||||
|
- Add support for building Mac OS X Framework bundles
|
||||||
|
- Check for nullptr dereferencing before copying scene data
|
||||||
|
- Update ValidateDataStructure.h, typo
|
||||||
|
- Enable data structure validation in cases where it doesn't cause failures
|
||||||
|
- Remove some dead assignments
|
||||||
|
- fast_atof: Silence some uninitialized variable warnings
|
||||||
|
- Check for area test if the face is a triangle.
|
||||||
|
- Set mNumUVComponents to 0 when deleting texture coordinate sets
|
||||||
|
- Only scale the root node because this will rescale all children nodes as well.
|
||||||
|
- Issue 1514: Fix frame pointer arithmetic
|
||||||
|
- Prevent failing stringstream to crash the export process
|
||||||
|
- powf -> pow
|
||||||
|
- add Defines.h to include folder for install.
|
||||||
|
- Android:
|
||||||
|
- Fix android build
|
||||||
|
- Fix assimp for cross compile for android
|
||||||
|
- Use define for D_FILE_OFFSET_BITS only for not-android systems.
|
||||||
|
- FBX:
|
||||||
|
- Fix handling with embedded textures
|
||||||
|
- FBX 7500 Binary reading
|
||||||
|
- Remove dead assignment
|
||||||
|
- Fix export of deleted meshes; Add LazyDict::Remove method
|
||||||
|
- Log an error instead of letting the fbx-importer crash. ( issue 213 )
|
||||||
|
- Replace bad pointer casting with memcpy
|
||||||
|
- Remove useless const qualifier from return value
|
||||||
|
- Add explicit instantiation of log_prefix so other FBX source files can see it
|
||||||
|
- add missing inversion of postrotation matrix for fbx.
|
||||||
|
- FIReader: Silence uninitialized variable warning
|
||||||
|
- Update version check in FBX reader to check for version >= 7500
|
||||||
|
- Use actual min/max of anim keys when start/stop time is missing
|
||||||
|
- GLTF1:
|
||||||
|
- Fix output of glTF 1 version string
|
||||||
|
- Fix delete / delete[] mismatch in glTFAsset
|
||||||
|
- Don’t ignore rgba(1,1,1,1) color properties
|
||||||
|
- glTF2 primitives fixes
|
||||||
|
- Don’t ignore rgba(1,1,1,1) color properties
|
||||||
|
- Fix delete / delete[] mismatch in glTFAsset
|
||||||
|
- Remove KHR_binary_glTF code
|
||||||
|
- glTF nodes can only hold one mesh. this simply assigns to and check’s a Node’s Mesh
|
||||||
|
- version in glb header is stored as uint32_t
|
||||||
|
- GLTF2:
|
||||||
|
- node name conflict fix
|
||||||
|
- Fix transform matrices multiplication order
|
||||||
|
- Preserve node names when importing
|
||||||
|
- Add support for tangents in import
|
||||||
|
- Fix typo on gltf2 camera parameters
|
||||||
|
- Moved byteStride from accessor to bufferView
|
||||||
|
- Implemented reading binary glTF2 (glb) files
|
||||||
|
- Fix signed/unsigned warning
|
||||||
|
- Add postprocess step for scaling
|
||||||
|
- Fix shininess to roughness conversion
|
||||||
|
- Prefer “BLEND” over “MASK” as an alphaMode default
|
||||||
|
- Approximate specularity / glossiness in metallicRoughness materials
|
||||||
|
- Diffuse color and diffuse texture import and export improvements
|
||||||
|
- Addressed some mismatched news/deletes caused by the new glTF2 sources.
|
||||||
|
- Fix delete / delete[] mismatches in glTF2 importer
|
||||||
|
- use correct name of exporter to gltf2
|
||||||
|
- Fix possible infinite loop when exporting to gltf2
|
||||||
|
- Fix glTF2::Asset::FindUniqueID() when the input string is >= 256 chars
|
||||||
|
- Fix glTF2 alphaMode storage and reading
|
||||||
|
- Fix glTF 2.0 multi-primitive support
|
||||||
|
- Load gltf .bin files from correct directory
|
||||||
|
- Add support for importing both glTF and glTF2 files
|
||||||
|
- ampler improvements; Add new LazyDict method
|
||||||
|
- Changes to GLTF2 materials
|
||||||
|
- Remove Light, Technique references
|
||||||
|
- Start removing materials common, and adding pbrSpecularGlossiness
|
||||||
|
- Use !ObjectEmpty() vs. MemberCount() > 0
|
||||||
|
- Working read, import, export, and write of gltf2 (pbr) material
|
||||||
|
- Check in gltf2 models to test directory
|
||||||
|
- Remove un-needed test models
|
||||||
|
- Start managing and importing gltf2 pbr materials
|
||||||
|
- Update glTF2 Asset to use indexes
|
||||||
|
- Duplicate gltfImporter as gltf2Importer; Include glTF2 importer in CMake List
|
||||||
|
- glTF2: Fix animation export
|
||||||
|
- use opacity for diffuse alpha + alphaMode
|
||||||
|
- STL:
|
||||||
|
- Restore import of multi mesh binary STLs
|
||||||
|
- Blender:
|
||||||
|
- Silence warning about uninitialized member
|
||||||
|
- MDLImporter:
|
||||||
|
- Don't take address of packed struct member
|
||||||
|
- assimp_cmd:
|
||||||
|
- Fix strict-aliasing warnings
|
||||||
|
- Open3DGC:
|
||||||
|
- Fix strict-aliasing warnings
|
||||||
|
- Add assertions to silence static analyzer warnings
|
||||||
|
- Remove redundant const qualifiers from return types
|
||||||
|
- Fix some uninitialized variable warnings
|
||||||
|
- Remove OPEN3DGC and compression references
|
||||||
|
- unzip:
|
||||||
|
- Remove dead assignment
|
||||||
|
- Bail on bad compression method
|
||||||
|
- Fix possibly uninitialized variables
|
||||||
|
- clipper:
|
||||||
|
- Add assertion to silence a static analyzer warning
|
||||||
|
- OpenDDLExport:
|
||||||
|
- Reduce scope of a variable
|
||||||
|
- Remove dead variable
|
||||||
|
- Remove dead assignment
|
||||||
|
- Fix another potential memory leak
|
||||||
|
- X3DImporter:
|
||||||
|
- Add assertions to silence static analyzer warnings
|
||||||
|
- Add missing unittest
|
||||||
|
- Workaround for buggy Android NDK (issue #1361)
|
||||||
|
- TerragenLoader:
|
||||||
|
- Remove unused variable
|
||||||
|
- SIBImporter:
|
||||||
|
- Add assertions to silence static analyzer warnings
|
||||||
|
- IFC:
|
||||||
|
- Remove dead code
|
||||||
|
- Add explicit instantiation of log_prefix so IFCMaterial.cpp can see it
|
||||||
|
- PLY:
|
||||||
|
- Remove dead assignment and reduce scope of a variable
|
||||||
|
- fix vertex attribute lookup.
|
||||||
|
- OpenGEX:
|
||||||
|
- Add assertion to silence a static analyzer warning
|
||||||
|
- Fix for TextureFile with number in file name
|
||||||
|
- Return early when element is TextureFile
|
||||||
|
- NFF:
|
||||||
|
- Add assertions to silence static analyzer warnings
|
||||||
|
- Split up some complicated assignments
|
||||||
|
- Raw: Fix misleading indentation warning
|
||||||
|
- Reduce scope of a variable
|
||||||
|
- LWO
|
||||||
|
- Reduce scope of a variable
|
||||||
|
- IRRLoader:
|
||||||
|
- Fix confusing boolean casting
|
||||||
|
- AssbinExporter:
|
||||||
|
- Add assertion to silence a static analyzer warning
|
||||||
|
- ASE:
|
||||||
|
- Add assertion to silence a static analyzer warning
|
||||||
|
- AMFImporter:
|
||||||
|
- Add assertion to silence a static analyzer warning
|
||||||
|
- Add a block
|
||||||
|
- OptimizeGraph:
|
||||||
|
- Fix possible null pointer dereference
|
||||||
|
- RemoveRedundantMaterials:
|
||||||
|
- Add assertion to silence a static analyzer warning
|
||||||
|
- ImproveCacheLocality:
|
||||||
|
- Add assertion to silence a static analyzer warning
|
||||||
|
- RemoveRedundantMaterials:
|
||||||
|
- Set pointer to nullptr after deleting it
|
||||||
|
- Travis:
|
||||||
|
- Disable unit tests in scan-build config
|
||||||
|
- Move slower builds earlier to improve parallelization
|
||||||
|
- Add static analysis to build
|
||||||
|
- Remove unused branch rule for travis.
|
||||||
|
- Add Clang UBSan build configuration
|
||||||
|
- Treat warnings as errors, without typos this time
|
||||||
|
- Unittests:
|
||||||
|
- Add VS-based source groups for the unittests.
|
||||||
|
- Collada:
|
||||||
|
- export <library_animations> tag
|
||||||
|
- Update ColladaExporter.cpp
|
||||||
|
- Silence uninitialized variable warning
|
||||||
|
- Add support for line strip primitives
|
||||||
|
- Obj Wavefront:
|
||||||
|
- check in exporting against out-of-bounds-access .
|
||||||
|
- Issue 1351: use correct name for obj-meshname export for groups.
|
||||||
|
- fix mem-lead: face will be not released in case of an error.
|
||||||
|
- Anatoscope obj exporter nomtl
|
||||||
|
- Raise exception when obj file contains invalid face indices
|
||||||
|
- Added alternative displacement texture token in OBJ MTL material.
|
||||||
|
- Obj: rename attribute from exporter.
|
||||||
|
- Fix OBJ discarding all material names if the material library is missing
|
||||||
|
- Step:
|
||||||
|
- use correct lookup for utf32
|
||||||
|
- MD2:
|
||||||
|
- Fix MD2 frames containing garbage
|
||||||
|
- STL
|
||||||
|
- add missing const.
|
||||||
|
- Fix memory-alignment bug.
|
||||||
|
- Fix issue 104: deal with more solids in one STL file.
|
||||||
|
- CMake
|
||||||
|
- Fix issue 213: use correct include folder for assimp
|
||||||
|
- Doxygen
|
||||||
|
- Fix issue 1513: put irrXML onto exclucde list for doxygen run
|
||||||
|
- PyAssimp:
|
||||||
|
- Search for libassimp.so in LD_LIBRARY_PATH if available.
|
||||||
|
- Fix operator precedence issue in header check
|
||||||
|
- Split setup.py into multiple lines
|
||||||
|
- Detect if Anaconda and fixed 3d_viewer for Python 3
|
||||||
|
- created a python3 version of the 3dviewer and fixed the / = float in py3
|
||||||
|
- Blender:
|
||||||
|
- Fix invalid access to mesh array when the array is empty.
|
||||||
|
- Fix short overflow.
|
||||||
|
- Silence warning about inline function which is declared but not defined
|
||||||
|
- JAssimp
|
||||||
|
- Changed license header for IHMC contributions from Apache 2.0 to BSD
|
||||||
|
- Add Node metadata to the Jassmip Java API
|
||||||
|
- Added supported for custom IO Systems in Java. Implemented ClassLoader IO System
|
||||||
|
- Added a link to pure jvm assimp port
|
||||||
|
- Clang sanitizer:
|
||||||
|
- Undefined Behavior sanitizer
|
||||||
|
- Fixed a divide by zero error in IFCBoolean that was latent, but nevertheless a bug
|
||||||
|
- B3DImporter:
|
||||||
|
- Replace bad pointer casting with memcpy
|
||||||
|
- AppVeyor:
|
||||||
|
- Cleanup and Addition of VS 2017 and running Tests
|
||||||
|
- Fixed File Size reported as 0 in tests that use temporary files
|
||||||
|
- x86 isn't a valid VS platform. Win32 it is, then.
|
||||||
|
- Replaced the worker image name, which doesn't work as generator name, with a manually created generator name.
|
||||||
|
- Cleaned up appveyor setup, added VS 2017 to the build matrix and attempted to add running of tests.
|
||||||
|
- Treat warnings as errors on Appveyor
|
||||||
|
- Disable warning 4351 on MSVC 2013
|
||||||
|
- OpenGEXImporter:
|
||||||
|
- Copy materials to scene
|
||||||
|
- Store RefInfo in unique_ptr so they get automatically cleaned up
|
||||||
|
- Fix IOStream leak
|
||||||
|
- Store ChildInfo in unique_ptr so they get automatically cleaned up
|
||||||
|
- improve logging to be able to detect error-prone situations.
|
||||||
|
- AMFImporter:
|
||||||
|
- Fix memory leak
|
||||||
|
- UnrealLoader:
|
||||||
|
- Fix IOStream leak
|
||||||
|
- Upgrade RapidJSON to get rid of a clang warning
|
||||||
|
- zlib:
|
||||||
|
- Update zlib contribution
|
||||||
|
- Removed unnecessary files from zlib contribution
|
||||||
|
- Replaced unsigned long for the crc table to z_crc_t, to match what is returned by get-crc_table
|
||||||
|
- MakeVerboseFormat:
|
||||||
|
- Fix delete / delete[] mismatches in MakeVerboseFormat
|
||||||
|
- MaterialSystem:
|
||||||
|
- Fix out-of-bounds read in MaterialSystem unit test
|
||||||
|
- SIB:
|
||||||
|
- Added support for SIB models from Silo 2.5
|
||||||
|
- AssbinExporter:
|
||||||
|
- Fix strict aliasing violation
|
||||||
|
- Add Write specialization for aiColor3D
|
||||||
|
- DefaultLogger:
|
||||||
|
- Whitespace cleanup to fix GCC misleading indentation warning
|
||||||
|
- MDP:
|
||||||
|
- Fix encoding issues.
|
||||||
|
- PreTransformVertices:
|
||||||
|
- fix name lost in mesh and nodes when load with flag
|
||||||
|
- C4D:
|
||||||
|
- Fixes for C4D importer
|
||||||
|
- Unzip:
|
||||||
|
- Latest greatest.
|
||||||
|
|
||||||
4.0.1 (2017-07-28)
|
4.0.1 (2017-07-28)
|
||||||
- FIXES/HOUSEKEEPING:
|
- FIXES/HOUSEKEEPING:
|
||||||
- fix version test.
|
- fix version test.
|
||||||
|
|
|
@ -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 )
|
||||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3")
|
|
||||||
|
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_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
|
||||||
use_pkgconfig(UNZIP minizip)
|
IF ( NOT IOS )
|
||||||
|
IF( NOT ASSIMP_BUILD_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.
|
ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ )
|
||||||
# Why here? Maybe user do not want Qt viewer and have no Qt.
|
ENDIF (NOT IOS)
|
||||||
# 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/ )
|
|
||||||
ELSE()
|
|
||||||
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)
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
# How to contribute
|
||||||
|
|
||||||
|
If you want to contribute, follow these steps:
|
||||||
|
|
||||||
|
- 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__:
|
||||||
|
@ -140,8 +142,6 @@ Open Asset Import Library is implemented in C++. The directory structure is:
|
||||||
/tools Tools (old assimp viewer, command line `assimp`)
|
/tools Tools (old assimp viewer, command line `assimp`)
|
||||||
/samples A small number of samples to illustrate possible
|
/samples A small number of samples to illustrate possible
|
||||||
use cases for Assimp
|
use cases for Assimp
|
||||||
/workspaces Build environments for vc,xcode,... (deprecated,
|
|
||||||
CMake has superseeded all legacy build options!)
|
|
||||||
|
|
||||||
|
|
||||||
### Where to get help ###
|
### Where to get help ###
|
||||||
|
|
|
@ -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,19 +328,17 @@ 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)
|
||||||
, mScaleV (1.0)
|
, mScaleV (1.0)
|
||||||
, 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,100 +99,49 @@ 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
|
||||||
|
/// Data type for post-processing step. More suitable container for part of material's composition.
|
||||||
|
struct SPP_Composite {
|
||||||
|
SPP_Material* Material;///< Pointer to material - part of composition.
|
||||||
|
std::string Formula;///< Formula for calculating ratio of \ref Material.
|
||||||
|
};
|
||||||
|
|
||||||
/// \struct SPP_Composite
|
/// \struct SPP_Material
|
||||||
/// Data type for postprocessing step. More suitable container for part of material's composition.
|
/// Data type for post-processing step. More suitable container for material.
|
||||||
struct SPP_Composite
|
struct SPP_Material {
|
||||||
{
|
std::string ID;///< Material ID.
|
||||||
SPP_Material* Material;///< Pointer to material - part of composition.
|
std::list<CAMFImporter_NodeElement_Metadata*> Metadata;///< Metadata of material.
|
||||||
std::string Formula;///< Formula for calculating ratio of \ref 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.
|
||||||
|
|
||||||
/// \struct SPP_Material
|
/// Return color calculated for specified coordinate.
|
||||||
/// Data type for postprocessing step. More suitable container for material.
|
/// \param [in] pX - "x" coordinate.
|
||||||
struct SPP_Material
|
/// \param [in] pY - "y" coordinate.
|
||||||
{
|
/// \param [in] pZ - "z" coordinate.
|
||||||
std::string ID;///< Material ID.
|
/// \return calculated color.
|
||||||
std::list<CAMFImporter_NodeElement_Metadata*> Metadata;///< Metadata of material.
|
aiColor4D GetColor(const float pX, const float pY, const float pZ) const;
|
||||||
CAMFImporter_NodeElement_Color* Color;///< Color of material.
|
};
|
||||||
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
|
/// Data type for post-processing step. More suitable container for texture.
|
||||||
/// Return color calculated for specified coordinate.
|
struct SPP_Texture {
|
||||||
/// \param [in] pX - "x" coordinate.
|
std::string ID;
|
||||||
/// \param [in] pY - "y" coordinate.
|
size_t Width, Height, Depth;
|
||||||
/// \param [in] pZ - "z" coordinate.
|
bool Tiled;
|
||||||
/// \return calculated color.
|
char FormatHint[9];// 8 for string + 1 for terminator.
|
||||||
aiColor4D GetColor(const float pX, const float pY, const float pZ) const;
|
uint8_t *Data;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \struct SPP_Texture
|
/// Data type for post-processing step. Contain face data.
|
||||||
/// Data type for post-processing step. More suitable container for texture.
|
struct SComplexFace {
|
||||||
struct SPP_Texture
|
aiFace Face;///< Face vertices.
|
||||||
{
|
const CAMFImporter_NodeElement_Color* Color;///< Face color. Equal to nullptr if color is not set for the face.
|
||||||
std::string ID;
|
const CAMFImporter_NodeElement_TexMap* TexMap;///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face.
|
||||||
size_t Width, Height, Depth;
|
};
|
||||||
bool Tiled;
|
|
||||||
char FormatHint[ 9 ];// 8 for string + 1 for terminator.
|
|
||||||
uint8_t *Data;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// \struct SComplexFace
|
|
||||||
/// Data type for post-processing step. Contain face data.
|
|
||||||
struct SComplexFace
|
|
||||||
{
|
|
||||||
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_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,15 +163,13 @@ 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.
|
||||||
/// \param [in] pID_B - ID of source "blue" texture.
|
/// \param [in] pID_B - ID of source "blue" 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
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \def MACRO_ATTRREAD_CHECK_REF
|
/// \def MACRO_ATTRREAD_CHECK_REF
|
||||||
/// Check curent attribute name and if it equal to requested then read value. Result write to output variable by reference. If result was read then
|
/// Check current attribute name and if it equal to requested then read value. Result write to output variable by reference. If result was read then
|
||||||
/// "continue" will called.
|
/// "continue" will called.
|
||||||
/// \param [in] pAttrName - attribute name.
|
/// \param [in] pAttrName - attribute name.
|
||||||
/// \param [out] pVarName - output variable name.
|
/// \param [out] pVarName - output variable name.
|
||||||
|
@ -84,7 +84,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \def MACRO_ATTRREAD_CHECK_RET
|
/// \def MACRO_ATTRREAD_CHECK_RET
|
||||||
/// Check curent attribute name and if it equal to requested then read value. Result write to output variable using return value of \ref pFunction.
|
/// Check current attribute name and if it equal to requested then read value. Result write to output variable using return value of \ref pFunction.
|
||||||
/// If result was read then "continue" will called.
|
/// If result was read then "continue" will called.
|
||||||
/// \param [in] pAttrName - attribute name.
|
/// \param [in] pAttrName - attribute name.
|
||||||
/// \param [out] pVarName - output variable name.
|
/// \param [out] pVarName - output variable name.
|
||||||
|
@ -130,7 +130,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
} while(false)
|
} while(false)
|
||||||
|
|
||||||
/// \def MACRO_NODECHECK_READCOMP_F
|
/// \def MACRO_NODECHECK_READCOMP_F
|
||||||
/// Check curent node name and if it equal to requested then read value. Result write to output variable of type "float".
|
/// Check current node name and if it equal to requested then read value. Result write to output variable of type "float".
|
||||||
/// If result was read then "continue" will called. Also check if node data already read then raise exception.
|
/// If result was read then "continue" will called. Also check if node data already read then raise exception.
|
||||||
/// \param [in] pNodeName - node name.
|
/// \param [in] pNodeName - node name.
|
||||||
/// \param [in, out] pReadFlag - read flag.
|
/// \param [in, out] pReadFlag - read flag.
|
||||||
|
@ -147,7 +147,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \def MACRO_NODECHECK_READCOMP_U32
|
/// \def MACRO_NODECHECK_READCOMP_U32
|
||||||
/// Check curent node name and if it equal to requested then read value. Result write to output variable of type "uint32_t".
|
/// Check current node name and if it equal to requested then read value. Result write to output variable of type "uint32_t".
|
||||||
/// If result was read then "continue" will called. Also check if node data already read then raise exception.
|
/// If result was read then "continue" will called. Also check if node data already read then raise exception.
|
||||||
/// \param [in] pNodeName - node name.
|
/// \param [in] pNodeName - node name.
|
||||||
/// \param [in, out] pReadFlag - read flag.
|
/// \param [in, out] pReadFlag - read flag.
|
||||||
|
|
|
@ -68,10 +68,9 @@ 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;
|
|
||||||
|
|
||||||
// Read attributes for node <color>.
|
// Read attributes for node <color>.
|
||||||
MACRO_ATTRREAD_LOOPBEG;
|
MACRO_ATTRREAD_LOOPBEG;
|
||||||
|
@ -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 manualy 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,10 +122,9 @@ 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;
|
|
||||||
|
|
||||||
// Read attributes for node <color>.
|
// Read attributes for node <color>.
|
||||||
MACRO_ATTRREAD_LOOPBEG;
|
MACRO_ATTRREAD_LOOPBEG;
|
||||||
|
@ -131,9 +133,11 @@ 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())
|
||||||
{
|
{
|
||||||
bool col_read = false;
|
bool col_read = false;
|
||||||
|
@ -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.
|
||||||
}
|
}
|
||||||
|
@ -181,14 +185,13 @@ CAMFImporter_NodeElement* ne;
|
||||||
// Parent element - <amf>.
|
// Parent element - <amf>.
|
||||||
void AMFImporter::ParseNode_Texture()
|
void AMFImporter::ParseNode_Texture()
|
||||||
{
|
{
|
||||||
std::string id;
|
std::string id;
|
||||||
uint32_t width = 0;
|
uint32_t width = 0;
|
||||||
uint32_t height = 0;
|
uint32_t height = 0;
|
||||||
uint32_t depth = 1;
|
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
|
|
||||||
if((width * height * depth) != als.Data.size()) throw DeadlyImportError("Texture has incorrect data size.");
|
// check 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 {
|
||||||
{
|
bool Composed; ///< Type of color stored: if true then look for formula in \ref Color_Composed[4], else - in \ref Color.
|
||||||
/****************** Variables ******************/
|
std::string Color_Composed[4]; ///< By components formulas of composed color. [0..3] - RGBA.
|
||||||
|
aiColor4D Color; ///< Constant color.
|
||||||
|
std::string Profile; ///< The ICC color space used to interpret the three color channels r, g and b..
|
||||||
|
|
||||||
bool Composed;///< Type of color stored: if true then look for formula in \ref Color_Composed[4], else - in \ref Color.
|
/// @brief Constructor.
|
||||||
std::string Color_Composed[4];///< By components formulas of composed color. [0..3] => RGBA.
|
/// @param [in] pParent - pointer to parent node.
|
||||||
aiColor4D Color;///< Constant color.
|
|
||||||
std::string Profile;///< The ICC color space used to interpret the three color channels <r>, <g> and <b>..
|
|
||||||
|
|
||||||
/****************** Functions ******************/
|
|
||||||
|
|
||||||
/// \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
|
||||||
|
|
|
@ -770,7 +770,7 @@ std::list<aiNode*> ch_node;
|
||||||
// find referenced object
|
// find referenced object
|
||||||
if(!Find_ConvertedNode(als.ObjectID, pNodeList, &found_node)) Throw_ID_NotFound(als.ObjectID);
|
if(!Find_ConvertedNode(als.ObjectID, pNodeList, &found_node)) Throw_ID_NotFound(als.ObjectID);
|
||||||
|
|
||||||
// create node for apllying transformation
|
// create node for applying transformation
|
||||||
t_node = new aiNode;
|
t_node = new aiNode;
|
||||||
t_node->mParent = con_node;
|
t_node->mParent = con_node;
|
||||||
// apply transformation
|
// apply transformation
|
||||||
|
|
115
code/ASEParser.h
115
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,19 +201,16 @@ 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
|
||||||
|
@ -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,24 +273,23 @@ 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,18 +396,17 @@ 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:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Construct a parser from a given input file which is
|
//! Construct a parser from a given input file which is
|
||||||
//! guaranted to be terminated with zero.
|
//! guaranteed to be terminated with zero.
|
||||||
//! @param szFile Input file
|
//! @param szFile Input file
|
||||||
//! @param fileFormatDefault Assumed file format version. If the
|
//! @param fileFormatDefault Assumed file format version. If the
|
||||||
//! file format is specified in the file the new value replaces
|
//! file format is specified in the file the new value replaces
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,32 +70,33 @@ namespace Assimp {
|
||||||
class AssbinImporter : public BaseImporter
|
class AssbinImporter : public BaseImporter
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
bool shortened;
|
bool shortened;
|
||||||
bool compressed;
|
bool compressed;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual bool CanRead(
|
virtual bool CanRead(
|
||||||
const std::string& pFile,
|
const std::string& pFile,
|
||||||
IOSystem* pIOHandler,
|
IOSystem* pIOHandler,
|
||||||
bool checkSig
|
bool checkSig
|
||||||
) const;
|
) const;
|
||||||
virtual const aiImporterDesc* GetInfo() const;
|
virtual const aiImporterDesc* GetInfo() const;
|
||||||
virtual void InternReadFile(
|
virtual void InternReadFile(
|
||||||
const std::string& pFile,
|
const std::string& pFile,
|
||||||
aiScene* pScene,
|
aiScene* pScene,
|
||||||
IOSystem* pIOHandler
|
IOSystem* pIOHandler
|
||||||
);
|
);
|
||||||
void ReadBinaryScene( IOStream * stream, aiScene* pScene );
|
void ReadHeader();
|
||||||
void ReadBinaryNode( IOStream * stream, aiNode** mRootNode, aiNode* parent );
|
void ReadBinaryScene( IOStream * stream, aiScene* pScene );
|
||||||
void ReadBinaryMesh( IOStream * stream, aiMesh* mesh );
|
void ReadBinaryNode( IOStream * stream, aiNode** mRootNode, aiNode* parent );
|
||||||
void ReadBinaryBone( IOStream * stream, aiBone* bone );
|
void ReadBinaryMesh( IOStream * stream, aiMesh* mesh );
|
||||||
void ReadBinaryMaterial(IOStream * stream, aiMaterial* mat);
|
void ReadBinaryBone( IOStream * stream, aiBone* bone );
|
||||||
void ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop);
|
void ReadBinaryMaterial(IOStream * stream, aiMaterial* mat);
|
||||||
void ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd);
|
void ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop);
|
||||||
void ReadBinaryAnim( IOStream * stream, aiAnimation* anim );
|
void ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd);
|
||||||
void ReadBinaryTexture(IOStream * stream, aiTexture* tex);
|
void ReadBinaryAnim( IOStream * stream, aiAnimation* anim );
|
||||||
void ReadBinaryLight( IOStream * stream, aiLight* l );
|
void ReadBinaryTexture(IOStream * stream, aiTexture* tex);
|
||||||
void ReadBinaryCamera( IOStream * stream, aiCamera* cam );
|
void ReadBinaryLight( IOStream * stream, aiLight* l );
|
||||||
|
void ReadBinaryCamera( IOStream * stream, aiCamera* cam );
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -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,16 +480,32 @@ 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,20 +530,33 @@ 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))
|
||||||
|
{
|
||||||
|
//Find channel in node
|
||||||
|
std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel);
|
||||||
|
|
||||||
for( unsigned int channel = 0; channel < 3; ++channel)
|
if (mapIter == channelMap.end())
|
||||||
{
|
throw DeadlyImportError("Missing rotation channel in node " + nodeName);
|
||||||
// translate ZXY euler angels into a quaternion
|
else {
|
||||||
const float angle = node.mChannelValues[fr * node.mChannels.size() + rotOffset + channel] * float( AI_MATH_PI) / 180.0f;
|
int channelIdx = mapIter->second;
|
||||||
|
// translate ZXY euler angels into a quaternion
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rotkey->mTime = double( fr);
|
rotkey->mTime = double( fr);
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -227,7 +227,7 @@ void DNAParser::Parse ()
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void DNA :: DumpToFile()
|
void DNA :: DumpToFile()
|
||||||
{
|
{
|
||||||
// we dont't bother using the VFS here for this is only for debugging.
|
// we don't bother using the VFS here for this is only for debugging.
|
||||||
// (and all your bases are belong to us).
|
// (and all your bases are belong to us).
|
||||||
|
|
||||||
std::ofstream f("dna.txt");
|
std::ofstream f("dna.txt");
|
||||||
|
|
|
@ -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:
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
|
@ -663,7 +685,7 @@ public:
|
||||||
/** Check whether a specific item is in the cache.
|
/** Check whether a specific item is in the cache.
|
||||||
* @param s Data type of the item
|
* @param s Data type of the item
|
||||||
* @param out Output pointer. Unchanged if the
|
* @param out Output pointer. Unchanged if the
|
||||||
* cache doens't know the item yet.
|
* cache doesn't know the item yet.
|
||||||
* @param ptr Item address to look for. */
|
* @param ptr Item address to look for. */
|
||||||
template <typename T> void get (
|
template <typename T> void get (
|
||||||
const Structure& s,
|
const Structure& s,
|
||||||
|
@ -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);
|
||||||
(*it)->mTextureCoords[0] = new aiVector3D[(*it)->mNumVertices];
|
if (itMatTexUvMapping == matTexUvMappings.end()) {
|
||||||
|
// default behaviour like before
|
||||||
|
(*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++];
|
||||||
|
|
||||||
aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
|
const auto itMatTexUvMapping = matTexUvMappings.find(v.mat_nr);
|
||||||
for (unsigned int j = 0; j < f.mNumIndices; ++j,++vo,++out->mNumVertices) {
|
if (itMatTexUvMapping == matTexUvMappings.end()) {
|
||||||
const MLoopUV& uv = mesh->mloopuv[v.loopstart + j];
|
// old behavior
|
||||||
vo->x = uv.uv[0];
|
aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
|
||||||
vo->y = uv.uv[1];
|
for (unsigned int j = 0; j < f.mNumIndices; ++j, ++vo, ++out->mNumVertices) {
|
||||||
|
const MLoopUV& uv = mesh->mloopuv[v.loopstart + j];
|
||||||
|
vo->x = uv.uv[0];
|
||||||
|
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
|
||||||
|
;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define INCLUDED_AI_BLEND_TESSELLATOR_H
|
#define INCLUDED_AI_BLEND_TESSELLATOR_H
|
||||||
|
|
||||||
// Use these to toggle between GLU Tessellate or poly2tri
|
// Use these to toggle between GLU Tessellate or poly2tri
|
||||||
// Note (acg) keep GLU Tesselate disabled by default - if it is turned on,
|
// Note (acg) keep GLU Tessellate disabled by default - if it is turned on,
|
||||||
// assimp needs to be linked against GLU, which is currently not yet
|
// assimp needs to be linked against GLU, which is currently not yet
|
||||||
// made configurable in CMake and potentially not wanted by most users
|
// made configurable in CMake and potentially not wanted by most users
|
||||||
// as it requires a Gl environment.
|
// as it requires a Gl environment.
|
||||||
|
|
|
@ -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")) );
|
||||||
|
|
||||||
|
|
|
@ -189,7 +189,7 @@ protected:
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
// summarize a material in an convinient way.
|
// summarize a material in an convenient way.
|
||||||
struct Material
|
struct Material
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -181,26 +181,27 @@ void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, I
|
||||||
// ... then fill the materials with the now adjusted settings
|
// ... then fill the materials with the now adjusted settings
|
||||||
FillMaterials(parser, pScene);
|
FillMaterials(parser, pScene);
|
||||||
|
|
||||||
// Apply unitsize scale calculation
|
// Apply unitsize scale calculation
|
||||||
pScene->mRootNode->mTransformation *= aiMatrix4x4(parser.mUnitSize, 0, 0, 0,
|
pScene->mRootNode->mTransformation *= aiMatrix4x4(parser.mUnitSize, 0, 0, 0,
|
||||||
0, parser.mUnitSize, 0, 0,
|
0, parser.mUnitSize, 0, 0,
|
||||||
0, 0, parser.mUnitSize, 0,
|
0, 0, parser.mUnitSize, 0,
|
||||||
0, 0, 0, 1);
|
0, 0, 0, 1);
|
||||||
if( !ignoreUpDirection ) {
|
if( !ignoreUpDirection ) {
|
||||||
// Convert to Y_UP, if different orientation
|
// Convert to Y_UP, if different orientation
|
||||||
if( parser.mUpDirection == ColladaParser::UP_X)
|
if( parser.mUpDirection == ColladaParser::UP_X)
|
||||||
pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
||||||
0, -1, 0, 0,
|
0, -1, 0, 0,
|
||||||
1, 0, 0, 0,
|
1, 0, 0, 0,
|
||||||
0, 0, 1, 0,
|
0, 0, 1, 0,
|
||||||
0, 0, 0, 1);
|
0, 0, 0, 1);
|
||||||
else if( parser.mUpDirection == ColladaParser::UP_Z)
|
else if( parser.mUpDirection == ColladaParser::UP_Z)
|
||||||
pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
||||||
1, 0, 0, 0,
|
1, 0, 0, 0,
|
||||||
0, 0, 1, 0,
|
0, 0, 1, 0,
|
||||||
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);
|
||||||
|
@ -956,7 +953,7 @@ void ColladaLoader::StoreSceneMaterials( aiScene* pScene)
|
||||||
// Stores all animations
|
// Stores all animations
|
||||||
void ColladaLoader::StoreAnimations( aiScene* pScene, const ColladaParser& pParser)
|
void ColladaLoader::StoreAnimations( aiScene* pScene, const ColladaParser& pParser)
|
||||||
{
|
{
|
||||||
// recursivly collect all animations from the collada scene
|
// recursively collect all animations from the collada scene
|
||||||
StoreAnimations( pScene, pParser, &pParser.mAnims, "");
|
StoreAnimations( pScene, pParser, &pParser.mAnims, "");
|
||||||
|
|
||||||
// catch special case: many animations with the same length, each affecting only a single node.
|
// catch special case: many animations with the same length, each affecting only a single node.
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1784,7 +1782,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pPars
|
||||||
|
|
||||||
// TODO: check the possibility of using the flag "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
|
// TODO: check the possibility of using the flag "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
|
||||||
// In FBX files textures are now stored internally by Assimp with their filename included
|
// In FBX files textures are now stored internally by Assimp with their filename included
|
||||||
// Now Assimp can lookup thru the loaded textures after all data is processed
|
// Now Assimp can lookup through the loaded textures after all data is processed
|
||||||
// We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it
|
// We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it
|
||||||
// This may occur on this case too, it has to be studied
|
// This may occur on this case too, it has to be studied
|
||||||
// setup texture reference string
|
// setup texture reference string
|
||||||
|
@ -1819,9 +1817,12 @@ void ColladaLoader::ConvertPath (aiString& ss)
|
||||||
|
|
||||||
// Maxon Cinema Collada Export writes "file:///C:\andsoon" with three slashes...
|
// Maxon Cinema Collada Export writes "file:///C:\andsoon" with three slashes...
|
||||||
// I need to filter it without destroying linux paths starting with "/somewhere"
|
// I need to filter it without destroying linux paths starting with "/somewhere"
|
||||||
if( ss.data[0] == '/' && isalpha( ss.data[1]) && ss.data[2] == ':' )
|
#if defined( _MSC_VER )
|
||||||
{
|
if( ss.data[0] == '/' && isalpha( (unsigned char) ss.data[1]) && ss.data[2] == ':' ) {
|
||||||
ss.length--;
|
#else
|
||||||
|
if (ss.data[ 0 ] == '/' && isalpha( ss.data[ 1 ] ) && ss.data[ 2 ] == ':') {
|
||||||
|
#endif
|
||||||
|
--ss.length;
|
||||||
::memmove( ss.data, ss.data+1, ss.length);
|
::memmove( ss.data, ss.data+1, ss.length);
|
||||||
ss.data[ss.length] = 0;
|
ss.data[ss.length] = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,17 +363,17 @@ 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;
|
||||||
findItr = mControllerLibrary.find(meshId);
|
findItr = mControllerLibrary.find(meshId);
|
||||||
}
|
}
|
||||||
|
|
||||||
it->second.mMeshId = meshId;
|
it->second.mMeshId = meshId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -448,8 +448,8 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int le
|
||||||
/*Result ignored*/ ReadByte(input, cursor, input + length);
|
/*Result ignored*/ ReadByte(input, cursor, input + length);
|
||||||
const uint32_t version = ReadWord(input, cursor, input + length);
|
const uint32_t version = ReadWord(input, cursor, input + length);
|
||||||
const bool is64bits = version >= 7500;
|
const bool is64bits = version >= 7500;
|
||||||
while (cursor < input + length)
|
const char *end = input + length;
|
||||||
{
|
while (cursor < end ) {
|
||||||
if (!ReadScope(output_tokens, input, cursor, input + length, is64bits)) {
|
if (!ReadScope(output_tokens, input, cursor, input + length, is64bits)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,133 +394,120 @@ 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;
|
||||||
|
uniqueName = name;
|
||||||
}
|
while (mNodeNames.find(uniqueName) != mNodeNames.end())
|
||||||
void Converter::GetUniqueName( const std::string &name, std::string uniqueName ) {
|
{
|
||||||
if ( !HasName( mNodeNames, name ) ) {
|
|
||||||
uniqueName = name;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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:
|
||||||
{
|
return "Translation";
|
||||||
case TransformationComp_Translation:
|
case TransformationComp_RotationOffset:
|
||||||
return "Translation";
|
return "RotationOffset";
|
||||||
case TransformationComp_RotationOffset:
|
case TransformationComp_RotationPivot:
|
||||||
return "RotationOffset";
|
return "RotationPivot";
|
||||||
case TransformationComp_RotationPivot:
|
case TransformationComp_PreRotation:
|
||||||
return "RotationPivot";
|
return "PreRotation";
|
||||||
case TransformationComp_PreRotation:
|
case TransformationComp_Rotation:
|
||||||
return "PreRotation";
|
return "Rotation";
|
||||||
case TransformationComp_Rotation:
|
case TransformationComp_PostRotation:
|
||||||
return "Rotation";
|
return "PostRotation";
|
||||||
case TransformationComp_PostRotation:
|
case TransformationComp_RotationPivotInverse:
|
||||||
return "PostRotation";
|
return "RotationPivotInverse";
|
||||||
case TransformationComp_RotationPivotInverse:
|
case TransformationComp_ScalingOffset:
|
||||||
return "RotationPivotInverse";
|
return "ScalingOffset";
|
||||||
case TransformationComp_ScalingOffset:
|
case TransformationComp_ScalingPivot:
|
||||||
return "ScalingOffset";
|
return "ScalingPivot";
|
||||||
case TransformationComp_ScalingPivot:
|
case TransformationComp_Scaling:
|
||||||
return "ScalingPivot";
|
return "Scaling";
|
||||||
case TransformationComp_Scaling:
|
case TransformationComp_ScalingPivotInverse:
|
||||||
return "Scaling";
|
return "ScalingPivotInverse";
|
||||||
case TransformationComp_ScalingPivotInverse:
|
case TransformationComp_GeometricScaling:
|
||||||
return "ScalingPivotInverse";
|
return "GeometricScaling";
|
||||||
case TransformationComp_GeometricScaling:
|
case TransformationComp_GeometricRotation:
|
||||||
return "GeometricScaling";
|
return "GeometricRotation";
|
||||||
case TransformationComp_GeometricRotation:
|
case TransformationComp_GeometricTranslation:
|
||||||
return "GeometricRotation";
|
return "GeometricTranslation";
|
||||||
case TransformationComp_GeometricTranslation:
|
case TransformationComp_GeometricScalingInverse:
|
||||||
return "GeometricTranslation";
|
return "GeometricScalingInverse";
|
||||||
case TransformationComp_GeometricScalingInverse:
|
case TransformationComp_GeometricRotationInverse:
|
||||||
return "GeometricScalingInverse";
|
return "GeometricRotationInverse";
|
||||||
case TransformationComp_GeometricRotationInverse:
|
case TransformationComp_GeometricTranslationInverse:
|
||||||
return "GeometricRotationInverse";
|
return "GeometricTranslationInverse";
|
||||||
case TransformationComp_GeometricTranslationInverse:
|
case TransformationComp_MAXIMUM: // this is to silence compiler warnings
|
||||||
return "GeometricTranslationInverse";
|
default:
|
||||||
case TransformationComp_MAXIMUM: // this is to silence compiler warnings
|
break;
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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:
|
||||||
{
|
return "Lcl Translation";
|
||||||
case TransformationComp_Translation:
|
case TransformationComp_RotationOffset:
|
||||||
return "Lcl Translation";
|
return "RotationOffset";
|
||||||
case TransformationComp_RotationOffset:
|
case TransformationComp_RotationPivot:
|
||||||
return "RotationOffset";
|
return "RotationPivot";
|
||||||
case TransformationComp_RotationPivot:
|
case TransformationComp_PreRotation:
|
||||||
return "RotationPivot";
|
return "PreRotation";
|
||||||
case TransformationComp_PreRotation:
|
case TransformationComp_Rotation:
|
||||||
return "PreRotation";
|
return "Lcl Rotation";
|
||||||
case TransformationComp_Rotation:
|
case TransformationComp_PostRotation:
|
||||||
return "Lcl Rotation";
|
return "PostRotation";
|
||||||
case TransformationComp_PostRotation:
|
case TransformationComp_RotationPivotInverse:
|
||||||
return "PostRotation";
|
return "RotationPivotInverse";
|
||||||
case TransformationComp_RotationPivotInverse:
|
case TransformationComp_ScalingOffset:
|
||||||
return "RotationPivotInverse";
|
return "ScalingOffset";
|
||||||
case TransformationComp_ScalingOffset:
|
case TransformationComp_ScalingPivot:
|
||||||
return "ScalingOffset";
|
return "ScalingPivot";
|
||||||
case TransformationComp_ScalingPivot:
|
case TransformationComp_Scaling:
|
||||||
return "ScalingPivot";
|
return "Lcl Scaling";
|
||||||
case TransformationComp_Scaling:
|
case TransformationComp_ScalingPivotInverse:
|
||||||
return "Lcl Scaling";
|
return "ScalingPivotInverse";
|
||||||
case TransformationComp_ScalingPivotInverse:
|
case TransformationComp_GeometricScaling:
|
||||||
return "ScalingPivotInverse";
|
return "GeometricScaling";
|
||||||
case TransformationComp_GeometricScaling:
|
case TransformationComp_GeometricRotation:
|
||||||
return "GeometricScaling";
|
return "GeometricRotation";
|
||||||
case TransformationComp_GeometricRotation:
|
case TransformationComp_GeometricTranslation:
|
||||||
return "GeometricRotation";
|
return "GeometricTranslation";
|
||||||
case TransformationComp_GeometricTranslation:
|
case TransformationComp_GeometricScalingInverse:
|
||||||
return "GeometricTranslation";
|
return "GeometricScalingInverse";
|
||||||
case TransformationComp_GeometricScalingInverse:
|
case TransformationComp_GeometricRotationInverse:
|
||||||
return "GeometricScalingInverse";
|
return "GeometricRotationInverse";
|
||||||
case TransformationComp_GeometricRotationInverse:
|
case TransformationComp_GeometricTranslationInverse:
|
||||||
return "GeometricRotationInverse";
|
return "GeometricTranslationInverse";
|
||||||
case TransformationComp_GeometricTranslationInverse:
|
case TransformationComp_MAXIMUM: // this is to silence compiler warnings
|
||||||
return "GeometricTranslationInverse";
|
break;
|
||||||
case TransformationComp_MAXIMUM: // this is to silence compiler warnings
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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,7 +1509,47 @@ 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)
|
||||||
|
{
|
||||||
|
aiString path;
|
||||||
|
path.Set(tex->RelativeFilename());
|
||||||
|
|
||||||
|
const Video* media = tex->Media();
|
||||||
|
if (media != nullptr) {
|
||||||
|
bool textureReady = false; //tells if our texture is ready (if it was loaded or if it was found)
|
||||||
|
unsigned int index;
|
||||||
|
|
||||||
|
VideoMap::const_iterator it = textures_converted.find(media);
|
||||||
|
if (it != textures_converted.end()) {
|
||||||
|
index = (*it).second;
|
||||||
|
textureReady = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (media->ContentLength() > 0) {
|
||||||
|
index = ConvertVideo(*media);
|
||||||
|
textures_converted[media] = index;
|
||||||
|
textureReady = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture), if the texture is ready
|
||||||
|
if (doc.Settings().useLegacyEmbeddedTextureNaming) {
|
||||||
|
if (textureReady) {
|
||||||
|
// TODO: check the possibility of using the flag "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
|
||||||
|
// In FBX files textures are now stored internally by Assimp with their filename included
|
||||||
|
// Now Assimp can lookup through the loaded textures after all data is processed
|
||||||
|
// We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it
|
||||||
|
// This may occur on this case too, it has to be studied
|
||||||
|
path.data[0] = '*';
|
||||||
|
path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FBXConverter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap& textures,
|
||||||
const std::string& propName,
|
const std::string& propName,
|
||||||
aiTextureType target, const MeshGeometry* const mesh )
|
aiTextureType target, const MeshGeometry* const mesh )
|
||||||
{
|
{
|
||||||
|
@ -1538,41 +1561,7 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap&
|
||||||
const Texture* const tex = ( *it ).second;
|
const Texture* const tex = ( *it ).second;
|
||||||
if ( tex != 0 )
|
if ( tex != 0 )
|
||||||
{
|
{
|
||||||
aiString path;
|
aiString path = GetTexturePath(tex);
|
||||||
path.Set( tex->RelativeFilename() );
|
|
||||||
|
|
||||||
const Video* media = tex->Media();
|
|
||||||
if (media != 0) {
|
|
||||||
bool textureReady = false; //tells if our texture is ready (if it was loaded or if it was found)
|
|
||||||
unsigned int index;
|
|
||||||
|
|
||||||
VideoMap::const_iterator it = textures_converted.find(media);
|
|
||||||
if (it != textures_converted.end()) {
|
|
||||||
index = (*it).second;
|
|
||||||
textureReady = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (media->ContentLength() > 0) {
|
|
||||||
index = ConvertVideo(*media);
|
|
||||||
textures_converted[media] = index;
|
|
||||||
textureReady = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture), if the texture is ready
|
|
||||||
if (doc.Settings().useLegacyEmbeddedTextureNaming) {
|
|
||||||
if (textureReady) {
|
|
||||||
// TODO: check the possibility of using the flag "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
|
|
||||||
// In FBX files textures are now stored internally by Assimp with their filename included
|
|
||||||
// Now Assimp can lookup thru the loaded textures after all data is processed
|
|
||||||
// We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it
|
|
||||||
// This may occur on this case too, it has to be studied
|
|
||||||
path.data[0] = '*';
|
|
||||||
path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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,60 +1963,60 @@ 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;
|
||||||
|
|
||||||
case FileGlobalSettings::FrameRate_120:
|
case FileGlobalSettings::FrameRate_120:
|
||||||
return 120.0;
|
return 120.0;
|
||||||
|
|
||||||
case FileGlobalSettings::FrameRate_100:
|
case FileGlobalSettings::FrameRate_100:
|
||||||
return 100.0;
|
return 100.0;
|
||||||
|
|
||||||
case FileGlobalSettings::FrameRate_60:
|
case FileGlobalSettings::FrameRate_60:
|
||||||
return 60.0;
|
return 60.0;
|
||||||
|
|
||||||
case FileGlobalSettings::FrameRate_50:
|
case FileGlobalSettings::FrameRate_50:
|
||||||
return 50.0;
|
return 50.0;
|
||||||
|
|
||||||
case FileGlobalSettings::FrameRate_48:
|
case FileGlobalSettings::FrameRate_48:
|
||||||
return 48.0;
|
return 48.0;
|
||||||
|
|
||||||
case FileGlobalSettings::FrameRate_30:
|
case FileGlobalSettings::FrameRate_30:
|
||||||
case FileGlobalSettings::FrameRate_30_DROP:
|
case FileGlobalSettings::FrameRate_30_DROP:
|
||||||
return 30.0;
|
return 30.0;
|
||||||
|
|
||||||
case FileGlobalSettings::FrameRate_NTSC_DROP_FRAME:
|
case FileGlobalSettings::FrameRate_NTSC_DROP_FRAME:
|
||||||
case FileGlobalSettings::FrameRate_NTSC_FULL_FRAME:
|
case FileGlobalSettings::FrameRate_NTSC_FULL_FRAME:
|
||||||
return 29.9700262;
|
return 29.9700262;
|
||||||
|
|
||||||
case FileGlobalSettings::FrameRate_PAL:
|
case FileGlobalSettings::FrameRate_PAL:
|
||||||
return 25.0;
|
return 25.0;
|
||||||
|
|
||||||
case FileGlobalSettings::FrameRate_CINEMA:
|
case FileGlobalSettings::FrameRate_CINEMA:
|
||||||
return 24.0;
|
return 24.0;
|
||||||
|
|
||||||
case FileGlobalSettings::FrameRate_1000:
|
case FileGlobalSettings::FrameRate_1000:
|
||||||
return 1000.0;
|
return 1000.0;
|
||||||
|
|
||||||
case FileGlobalSettings::FrameRate_CINEMA_ND:
|
case FileGlobalSettings::FrameRate_CINEMA_ND:
|
||||||
return 23.976;
|
return 23.976;
|
||||||
|
|
||||||
case FileGlobalSettings::FrameRate_CUSTOM:
|
case FileGlobalSettings::FrameRate_CUSTOM:
|
||||||
return customFPSVal;
|
return customFPSVal;
|
||||||
|
|
||||||
case FileGlobalSettings::FrameRate_MAX: // this is to silence compiler warnings
|
case FileGlobalSettings::FrameRate_MAX: // this is to silence compiler warnings
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
|
|
|
@ -575,11 +575,11 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bo
|
||||||
ai_assert( count != 0 );
|
ai_assert( count != 0 );
|
||||||
ai_assert( count <= MAX_CLASSNAMES);
|
ai_assert( count <= MAX_CLASSNAMES);
|
||||||
|
|
||||||
size_t lenghts[MAX_CLASSNAMES];
|
size_t lengths[MAX_CLASSNAMES];
|
||||||
|
|
||||||
const size_t c = count;
|
const size_t c = count;
|
||||||
for (size_t i = 0; i < c; ++i) {
|
for (size_t i = 0; i < c; ++i) {
|
||||||
lenghts[ i ] = strlen(classnames[i]);
|
lengths[ i ] = strlen(classnames[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<const Connection*> temp;
|
std::vector<const Connection*> temp;
|
||||||
|
@ -597,7 +597,7 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bo
|
||||||
|
|
||||||
for (size_t i = 0; i < c; ++i) {
|
for (size_t i = 0; i < c; ++i) {
|
||||||
ai_assert(classnames[i]);
|
ai_assert(classnames[i]);
|
||||||
if(static_cast<size_t>(std::distance(key.begin(),key.end())) == lenghts[i] && !strncmp(classnames[i],obtype,lenghts[i])) {
|
if(static_cast<size_t>(std::distance(key.begin(),key.end())) == lengths[i] && !strncmp(classnames[i],obtype,lengths[i])) {
|
||||||
obtype = NULL;
|
obtype = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -450,7 +450,7 @@ void FBXExporter::WriteDocuments ()
|
||||||
p.AddP70string("ActiveAnimStackName", ""); // should do this properly?
|
p.AddP70string("ActiveAnimStackName", ""); // should do this properly?
|
||||||
doc.AddChild(p);
|
doc.AddChild(p);
|
||||||
|
|
||||||
// UID for root node in scene heirarchy.
|
// UID for root node in scene hierarchy.
|
||||||
// always set to 0 in the case of a single document.
|
// always set to 0 in the case of a single document.
|
||||||
// not sure what happens if more than one document exists,
|
// not sure what happens if more than one document exists,
|
||||||
// but that won't matter to us as we're exporting a single scene.
|
// but that won't matter to us as we're exporting a single scene.
|
||||||
|
@ -650,7 +650,7 @@ void FBXExporter::WriteDefinitions ()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Model / FbxNode
|
// Model / FbxNode
|
||||||
// <~~ node heirarchy
|
// <~~ node hierarchy
|
||||||
count = int32_t(count_nodes(mScene->mRootNode)) - 1; // (not counting root node)
|
count = int32_t(count_nodes(mScene->mRootNode)) - 1; // (not counting root node)
|
||||||
if (count) {
|
if (count) {
|
||||||
n = FBX::Node("ObjectType", "Model");
|
n = FBX::Node("ObjectType", "Model");
|
||||||
|
@ -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) {
|
||||||
|
@ -1223,7 +1227,7 @@ void FBXExporter::WriteObjects ()
|
||||||
// it's all about this material
|
// it's all about this material
|
||||||
aiMaterial* m = mScene->mMaterials[i];
|
aiMaterial* m = mScene->mMaterials[i];
|
||||||
|
|
||||||
// these are used to recieve material data
|
// these are used to receive material data
|
||||||
float f; aiColor3D c;
|
float f; aiColor3D c;
|
||||||
|
|
||||||
// start the node record
|
// start the node record
|
||||||
|
@ -1311,7 +1315,7 @@ void FBXExporter::WriteObjects ()
|
||||||
// Now the legacy system.
|
// Now the legacy system.
|
||||||
// For safety let's include it.
|
// For safety let's include it.
|
||||||
// thrse values don't exist in the property template,
|
// thrse values don't exist in the property template,
|
||||||
// and usualy are completely ignored when loading.
|
// and usually are completely ignored when loading.
|
||||||
// One notable exception is the "Opacity" property,
|
// One notable exception is the "Opacity" property,
|
||||||
// which Blender uses as (1.0 - alpha).
|
// which Blender uses as (1.0 - alpha).
|
||||||
c.r = 0.0f; c.g = 0.0f; c.b = 0.0f;
|
c.r = 0.0f; c.g = 0.0f; c.b = 0.0f;
|
||||||
|
@ -1532,7 +1536,7 @@ void FBXExporter::WriteObjects ()
|
||||||
// bones.
|
// bones.
|
||||||
//
|
//
|
||||||
// output structure:
|
// output structure:
|
||||||
// subset of node heirarchy that are "skeleton",
|
// subset of node hierarchy that are "skeleton",
|
||||||
// i.e. do not have meshes but only bones.
|
// i.e. do not have meshes but only bones.
|
||||||
// but.. i'm not sure how anyone could guarantee that...
|
// but.. i'm not sure how anyone could guarantee that...
|
||||||
//
|
//
|
||||||
|
@ -1544,7 +1548,7 @@ void FBXExporter::WriteObjects ()
|
||||||
//
|
//
|
||||||
// well. we can assume a sane input, i suppose.
|
// well. we can assume a sane input, i suppose.
|
||||||
//
|
//
|
||||||
// so input is the bone node heirarchy,
|
// so input is the bone node hierarchy,
|
||||||
// with an extra thing for the transformation of the MESH in BONE space.
|
// with an extra thing for the transformation of the MESH in BONE space.
|
||||||
//
|
//
|
||||||
// output is a set of bone nodes,
|
// output is a set of bone nodes,
|
||||||
|
@ -1556,7 +1560,7 @@ void FBXExporter::WriteObjects ()
|
||||||
// and represents the influence of that bone on the grandparent mesh.
|
// and represents the influence of that bone on the grandparent mesh.
|
||||||
// the subdeformer has a list of indices, and weights,
|
// the subdeformer has a list of indices, and weights,
|
||||||
// with indices specifying vertex indices,
|
// with indices specifying vertex indices,
|
||||||
// and weights specifying the correspoding influence of this bone.
|
// and weights specifying the corresponding influence of this bone.
|
||||||
// it also has Transform and TransformLink elements,
|
// it also has Transform and TransformLink elements,
|
||||||
// specifying the transform of the MESH in BONE space,
|
// specifying the transform of the MESH in BONE space,
|
||||||
// and the transformation of the BONE in WORLD space,
|
// and the transformation of the BONE in WORLD space,
|
||||||
|
@ -1806,7 +1810,7 @@ void FBXExporter::WriteObjects ()
|
||||||
// and a correct skeleton would still be output.
|
// and a correct skeleton would still be output.
|
||||||
|
|
||||||
// transformlink should be the position of the bone in world space.
|
// transformlink should be the position of the bone in world space.
|
||||||
// if the bone is in the bind pose (or nonexistant),
|
// if the bone is in the bind pose (or nonexistent),
|
||||||
// we can just use the matrix we already calculated
|
// we can just use the matrix we already calculated
|
||||||
if (bone_xform_okay) {
|
if (bone_xform_okay) {
|
||||||
sdnode.AddChild("TransformLink", bone_xform);
|
sdnode.AddChild("TransformLink", bone_xform);
|
||||||
|
@ -1945,7 +1949,7 @@ void FBXExporter::WriteObjects ()
|
||||||
|
|
||||||
// TODO: cameras, lights
|
// TODO: cameras, lights
|
||||||
|
|
||||||
// write nodes (i.e. model heirarchy)
|
// write nodes (i.e. model hierarchy)
|
||||||
// start at root node
|
// start at root node
|
||||||
WriteModelNodes(
|
WriteModelNodes(
|
||||||
outstream, mScene->mRootNode, 0, limbnodes
|
outstream, mScene->mRootNode, 0, limbnodes
|
||||||
|
@ -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);
|
||||||
|
@ -2203,8 +2207,8 @@ void FBXExporter::WriteModelNode(
|
||||||
} else {
|
} else {
|
||||||
// apply the transformation chain.
|
// apply the transformation chain.
|
||||||
// these transformation elements are created when importing FBX,
|
// these transformation elements are created when importing FBX,
|
||||||
// which has a complex transformation heirarchy for each node.
|
// which has a complex transformation hierarchy for each node.
|
||||||
// as such we can bake the heirarchy back into the node on export.
|
// as such we can bake the hierarchy back into the node on export.
|
||||||
for (auto &item : transform_chain) {
|
for (auto &item : transform_chain) {
|
||||||
auto elem = transform_types.find(item.first);
|
auto elem = transform_types.find(item.first);
|
||||||
if (elem == transform_types.end()) {
|
if (elem == transform_types.end()) {
|
||||||
|
|
|
@ -90,7 +90,7 @@ namespace Assimp
|
||||||
const ExportProperties* mProperties; // currently unused
|
const ExportProperties* mProperties; // currently unused
|
||||||
std::shared_ptr<IOStream> outfile; // file to write to
|
std::shared_ptr<IOStream> outfile; // file to write to
|
||||||
|
|
||||||
std::vector<FBX::Node> connections; // conection storage
|
std::vector<FBX::Node> connections; // connection storage
|
||||||
|
|
||||||
std::vector<int64_t> mesh_uids;
|
std::vector<int64_t> mesh_uids;
|
||||||
std::vector<int64_t> material_uids;
|
std::vector<int64_t> material_uids;
|
||||||
|
|
|
@ -302,7 +302,7 @@ Video::Video(uint64_t id, const Element& element, const Document& doc, const std
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Content) {
|
if(Content) {
|
||||||
//this field is ommited when the embedded texture is already loaded, let's ignore if it's not found
|
//this field is omitted when the embedded texture is already loaded, let's ignore if it's not found
|
||||||
try {
|
try {
|
||||||
const Token& token = GetRequiredToken(*Content, 0);
|
const Token& token = GetRequiredToken(*Content, 0);
|
||||||
const char* data = token.begin();
|
const char* data = token.begin();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -54,6 +54,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
//remove mesh at position 'index' from the scene
|
||||||
|
static void removeMesh(aiScene* pScene, unsigned const index);
|
||||||
|
//correct node indices to meshes and remove references to deleted mesh
|
||||||
|
static void updateSceneGraph(aiNode* pNode, unsigned const index);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
FindDegeneratesProcess::FindDegeneratesProcess()
|
FindDegeneratesProcess::FindDegeneratesProcess()
|
||||||
|
@ -87,11 +92,50 @@ void FindDegeneratesProcess::SetupProperties(const Importer* pImp) {
|
||||||
void FindDegeneratesProcess::Execute( aiScene* pScene) {
|
void FindDegeneratesProcess::Execute( aiScene* pScene) {
|
||||||
ASSIMP_LOG_DEBUG("FindDegeneratesProcess begin");
|
ASSIMP_LOG_DEBUG("FindDegeneratesProcess begin");
|
||||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i){
|
for (unsigned int i = 0; i < pScene->mNumMeshes;++i){
|
||||||
ExecuteOnMesh( pScene->mMeshes[ i ] );
|
if (ExecuteOnMesh(pScene->mMeshes[i])) {
|
||||||
|
removeMesh(pScene, i);
|
||||||
|
--i; //the current i is removed, do not skip the next one
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ASSIMP_LOG_DEBUG("FindDegeneratesProcess finished");
|
ASSIMP_LOG_DEBUG("FindDegeneratesProcess finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void removeMesh(aiScene* pScene, unsigned const index) {
|
||||||
|
//we start at index and copy the pointers one position forward
|
||||||
|
//save the mesh pointer to delete it later
|
||||||
|
auto delete_me = pScene->mMeshes[index];
|
||||||
|
for (unsigned i = index; i < pScene->mNumMeshes - 1; ++i) {
|
||||||
|
pScene->mMeshes[i] = pScene->mMeshes[i+1];
|
||||||
|
}
|
||||||
|
pScene->mMeshes[pScene->mNumMeshes - 1] = nullptr;
|
||||||
|
--(pScene->mNumMeshes);
|
||||||
|
delete delete_me;
|
||||||
|
|
||||||
|
//removing a mesh also requires updating all references to it in the scene graph
|
||||||
|
updateSceneGraph(pScene->mRootNode, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateSceneGraph(aiNode* pNode, unsigned const index) {
|
||||||
|
for (unsigned i = 0; i < pNode->mNumMeshes; ++i) {
|
||||||
|
if (pNode->mMeshes[i] > index) {
|
||||||
|
--(pNode->mMeshes[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pNode->mMeshes[i] == index) {
|
||||||
|
for (unsigned j = i; j < pNode->mNumMeshes -1; ++j) {
|
||||||
|
pNode->mMeshes[j] = pNode->mMeshes[j+1];
|
||||||
|
}
|
||||||
|
--(pNode->mNumMeshes);
|
||||||
|
--i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//recurse to all children
|
||||||
|
for (unsigned i = 0; i < pNode->mNumChildren; ++i) {
|
||||||
|
updateSceneGraph(pNode->mChildren[i], index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static ai_real heron( ai_real a, ai_real b, ai_real c ) {
|
static ai_real heron( ai_real a, ai_real b, ai_real c ) {
|
||||||
ai_real s = (a + b + c) / 2;
|
ai_real s = (a + b + c) / 2;
|
||||||
ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), (ai_real)0.5 );
|
ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), (ai_real)0.5 );
|
||||||
|
@ -125,7 +169,7 @@ static ai_real calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh ) {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported mesh
|
// Executes the post processing step on the given imported mesh
|
||||||
void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
|
bool FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
|
||||||
mesh->mPrimitiveTypes = 0;
|
mesh->mPrimitiveTypes = 0;
|
||||||
|
|
||||||
std::vector<bool> remove_me;
|
std::vector<bool> remove_me;
|
||||||
|
@ -161,7 +205,7 @@ void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
|
||||||
|
|
||||||
// NOTE: we set the removed vertex index to an unique value
|
// NOTE: we set the removed vertex index to an unique value
|
||||||
// to make sure the developer gets notified when his
|
// to make sure the developer gets notified when his
|
||||||
// application attemps to access this data.
|
// application attempts to access this data.
|
||||||
face.mIndices[ face.mNumIndices ] = 0xdeadbeef;
|
face.mIndices[ face.mNumIndices ] = 0xdeadbeef;
|
||||||
|
|
||||||
if(first) {
|
if(first) {
|
||||||
|
@ -227,30 +271,28 @@ evil_jump_outside:
|
||||||
if (&face_src != &face_dest) {
|
if (&face_src != &face_dest) {
|
||||||
// clear source
|
// clear source
|
||||||
face_src.mNumIndices = 0;
|
face_src.mNumIndices = 0;
|
||||||
face_src.mIndices = NULL;
|
face_src.mIndices = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Otherwise delete it if we don't need this face
|
// Otherwise delete it if we don't need this face
|
||||||
delete[] face_src.mIndices;
|
delete[] face_src.mIndices;
|
||||||
face_src.mIndices = NULL;
|
face_src.mIndices = nullptr;
|
||||||
face_src.mNumIndices = 0;
|
face_src.mNumIndices = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Just leave the rest of the array unreferenced, we don't care for now
|
// Just leave the rest of the array unreferenced, we don't care for now
|
||||||
mesh->mNumFaces = n;
|
mesh->mNumFaces = n;
|
||||||
if (!mesh->mNumFaces) {
|
if (!mesh->mNumFaces) {
|
||||||
// WTF!?
|
//The whole mesh consists of degenerated faces
|
||||||
// OK ... for completeness and because I'm not yet tired,
|
//signal upward, that this mesh should be deleted.
|
||||||
// let's write code that will hopefully never be called
|
ASSIMP_LOG_DEBUG("FindDegeneratesProcess removed a mesh full of degenerated primitives");
|
||||||
// (famous last words)
|
return true;
|
||||||
|
|
||||||
// OK ... bad idea.
|
|
||||||
throw DeadlyImportError("Mesh is empty after removal of degenerated primitives ... WTF!?");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deg && !DefaultLogger::isNullLogger()) {
|
if (deg && !DefaultLogger::isNullLogger()) {
|
||||||
ASSIMP_LOG_WARN_F( "Found ", deg, " degenerated primitives");
|
ASSIMP_LOG_WARN_F( "Found ", deg, " degenerated primitives");
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,8 @@ public:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Execute step on a given mesh
|
// Execute step on a given mesh
|
||||||
void ExecuteOnMesh( aiMesh* mesh);
|
///@returns true if the current mesh should be deleted, false otherwise
|
||||||
|
bool ExecuteOnMesh( aiMesh* mesh);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/// @brief Enable the instant removal of degenerated primitives
|
/// @brief Enable the instant removal of degenerated primitives
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -78,7 +78,8 @@ 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
|
||||||
|
|
|
@ -91,7 +91,7 @@ protected:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Read a property of the specified type from the current XML element.
|
/** Read a property of the specified type from the current XML element.
|
||||||
* @param out Recives output data
|
* @param out Receives output data
|
||||||
*/
|
*/
|
||||||
void ReadHexProperty (HexProperty& out);
|
void ReadHexProperty (HexProperty& out);
|
||||||
void ReadStringProperty (StringProperty& out);
|
void ReadStringProperty (StringProperty& out);
|
||||||
|
|
|
@ -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,20 +931,19 @@ 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();
|
||||||
|
|
||||||
// skip over wildcard and dot characters at string head --
|
// skip over wildcard and dot characters at string head --
|
||||||
for(;*szExtension == '*' || *szExtension == '.'; ++szExtension);
|
for ( ; *szExtension == '*' || *szExtension == '.'; ++szExtension );
|
||||||
|
|
||||||
std::string ext(szExtension);
|
std::string ext(szExtension);
|
||||||
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,15 +970,18 @@ void Importer::GetExtensionList(aiString& szOut) const
|
||||||
(*i)->GetExtensionList(str);
|
(*i)->GetExtensionList(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::set<std::string>::const_iterator it = str.begin();; ) {
|
// List can be empty
|
||||||
szOut.Append("*.");
|
if( !str.empty() ) {
|
||||||
szOut.Append((*it).c_str());
|
for (std::set<std::string>::const_iterator it = str.begin();; ) {
|
||||||
|
szOut.Append("*.");
|
||||||
|
szOut.Append((*it).c_str());
|
||||||
|
|
||||||
if (++it == str.end()) {
|
if (++it == str.end()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
szOut.Append(";");
|
szOut.Append(";");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ASSIMP_END_EXCEPTION_REGION(void);
|
ASSIMP_END_EXCEPTION_REGION(void);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -997,33 +1000,33 @@ bool Importer::SetPropertyInteger(const char* szName, int iValue)
|
||||||
// Set a configuration property
|
// Set a configuration property
|
||||||
bool Importer::SetPropertyFloat(const char* szName, ai_real iValue)
|
bool Importer::SetPropertyFloat(const char* szName, ai_real iValue)
|
||||||
{
|
{
|
||||||
bool exising;
|
bool existing;
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
exising = SetGenericProperty<ai_real>(pimpl->mFloatProperties, szName,iValue);
|
existing = SetGenericProperty<ai_real>(pimpl->mFloatProperties, szName,iValue);
|
||||||
ASSIMP_END_EXCEPTION_REGION(bool);
|
ASSIMP_END_EXCEPTION_REGION(bool);
|
||||||
return exising;
|
return existing;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Set a configuration property
|
// Set a configuration property
|
||||||
bool Importer::SetPropertyString(const char* szName, const std::string& value)
|
bool Importer::SetPropertyString(const char* szName, const std::string& value)
|
||||||
{
|
{
|
||||||
bool exising;
|
bool existing;
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
exising = SetGenericProperty<std::string>(pimpl->mStringProperties, szName,value);
|
existing = SetGenericProperty<std::string>(pimpl->mStringProperties, szName,value);
|
||||||
ASSIMP_END_EXCEPTION_REGION(bool);
|
ASSIMP_END_EXCEPTION_REGION(bool);
|
||||||
return exising;
|
return existing;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Set a configuration property
|
// Set a configuration property
|
||||||
bool Importer::SetPropertyMatrix(const char* szName, const aiMatrix4x4& value)
|
bool Importer::SetPropertyMatrix(const char* szName, const aiMatrix4x4& value)
|
||||||
{
|
{
|
||||||
bool exising;
|
bool existing;
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
exising = SetGenericProperty<aiMatrix4x4>(pimpl->mMatrixProperties, szName,value);
|
existing = SetGenericProperty<aiMatrix4x4>(pimpl->mMatrixProperties, szName,value);
|
||||||
ASSIMP_END_EXCEPTION_REGION(bool);
|
ASSIMP_END_EXCEPTION_REGION(bool);
|
||||||
return exising;
|
return existing;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -317,7 +317,7 @@ void TempMesh::FixupFaceOrientation()
|
||||||
IfcVector3 farthestCenter = std::accumulate(mVerts.begin() + faceStartIndices[farthestIndex],
|
IfcVector3 farthestCenter = std::accumulate(mVerts.begin() + faceStartIndices[farthestIndex],
|
||||||
mVerts.begin() + faceStartIndices[farthestIndex] + mVertcnt[farthestIndex], IfcVector3(0.0))
|
mVerts.begin() + faceStartIndices[farthestIndex] + mVertcnt[farthestIndex], IfcVector3(0.0))
|
||||||
/ IfcFloat(mVertcnt[farthestIndex]);
|
/ IfcFloat(mVertcnt[farthestIndex]);
|
||||||
// We accapt a bit of negative orientation without reversing. In case of doubt, prefer the orientation given in
|
// We accept a bit of negative orientation without reversing. In case of doubt, prefer the orientation given in
|
||||||
// the file.
|
// the file.
|
||||||
if( (farthestNormal * (farthestCenter - vavg).Normalize()) < -0.4 )
|
if( (farthestNormal * (farthestCenter - vavg).Normalize()) < -0.4 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -118,7 +119,7 @@ bool areVerticesEqual(const Vertex &lhs, const Vertex &rhs, bool complex)
|
||||||
// Squared because we check against squared length of the vector difference
|
// Squared because we check against squared length of the vector difference
|
||||||
static const float squareEpsilon = epsilon * epsilon;
|
static const float squareEpsilon = epsilon * epsilon;
|
||||||
|
|
||||||
// Square compare is useful for animeshes vertexes compare
|
// Square compare is useful for animeshes vertices compare
|
||||||
if ((lhs.position - rhs.position).SquareLength() > squareEpsilon) {
|
if ((lhs.position - rhs.position).SquareLength() > squareEpsilon) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -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_last(0) {
|
||||||
, old_first (0)
|
// empty
|
||||||
, old_last (0)
|
}
|
||||||
{}
|
|
||||||
|
|
||||||
//! 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
|
||||||
|
|
|
@ -410,7 +410,7 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
|
||||||
// name to attach light to node -> unique due to LWs indexing system
|
// name to attach light to node -> unique due to LWs indexing system
|
||||||
lit->mName = nd->mName;
|
lit->mName = nd->mName;
|
||||||
|
|
||||||
// detemine light type and setup additional members
|
// determine light type and setup additional members
|
||||||
if (src.lightType == 2) { /* spot light */
|
if (src.lightType == 2) { /* spot light */
|
||||||
|
|
||||||
lit->mType = aiLightSource_SPOT;
|
lit->mType = aiLightSource_SPOT;
|
||||||
|
|
|
@ -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,10 +434,12 @@ void MDCImporter::InternReadFile(
|
||||||
else if (1 == pScene->mNumMeshes)
|
else if (1 == pScene->mNumMeshes)
|
||||||
{
|
{
|
||||||
pScene->mRootNode = new aiNode();
|
pScene->mRootNode = new aiNode();
|
||||||
pScene->mRootNode->mName = pScene->mMeshes[0]->mName;
|
if ( nullptr != pScene->mMeshes[0] ) {
|
||||||
pScene->mRootNode->mNumMeshes = 1;
|
pScene->mRootNode->mName = pScene->mMeshes[0]->mName;
|
||||||
pScene->mRootNode->mMeshes = new unsigned int[1];
|
pScene->mRootNode->mNumMeshes = 1;
|
||||||
pScene->mRootNode->mMeshes[0] = 0;
|
pScene->mRootNode->mMeshes = new unsigned int[1];
|
||||||
|
pScene->mRootNode->mMeshes[0] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
@ -141,7 +141,7 @@ void MDLImporter::SetupProperties(const Importer* pImp)
|
||||||
configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
|
configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// AI_CONFIG_IMPORT_MDL_COLORMAP - pallette file
|
// AI_CONFIG_IMPORT_MDL_COLORMAP - palette file
|
||||||
configPalette = pImp->GetPropertyString(AI_CONFIG_IMPORT_MDL_COLORMAP,"colormap.lmp");
|
configPalette = pImp->GetPropertyString(AI_CONFIG_IMPORT_MDL_COLORMAP,"colormap.lmp");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1496,7 +1496,7 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
|
||||||
groupData.vTextureCoords1.resize(iNumVertices,aiVector3D());
|
groupData.vTextureCoords1.resize(iNumVertices,aiVector3D());
|
||||||
|
|
||||||
// check whether the triangle data structure is large enough
|
// check whether the triangle data structure is large enough
|
||||||
// to contain a second UV coodinate set
|
// to contain a second UV coordinate set
|
||||||
if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV) {
|
if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV) {
|
||||||
groupData.vTextureCoords2.resize(iNumVertices,aiVector3D());
|
groupData.vTextureCoords2.resize(iNumVertices,aiVector3D());
|
||||||
groupData.bNeed2UV = true;
|
groupData.bNeed2UV = true;
|
||||||
|
|
|
@ -217,7 +217,7 @@ aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel,
|
||||||
pMesh->mNumFaces = indexCount / 3;
|
pMesh->mNumFaces = indexCount / 3;
|
||||||
pMesh->mFaces = new aiFace[pMesh->mNumFaces];
|
pMesh->mFaces = new aiFace[pMesh->mNumFaces];
|
||||||
|
|
||||||
const int numIndices = 3; // trianglular face
|
const int numIndices = 3; // triangular face
|
||||||
for (unsigned int index = 0; index < pMesh->mNumFaces; index++) {
|
for (unsigned int index = 0; index < pMesh->mNumFaces; index++) {
|
||||||
pMesh->mFaces[index].mNumIndices = numIndices;
|
pMesh->mFaces[index].mNumIndices = numIndices;
|
||||||
unsigned int *indices = new unsigned int[numIndices];
|
unsigned int *indices = new unsigned int[numIndices];
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
@ -116,7 +117,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));
|
||||||
|
@ -393,7 +394,7 @@ namespace pmx
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw;
|
throw DeadlyImportError("MMD: unknown morth type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,8 +474,8 @@ namespace pmx
|
||||||
void PmxSoftBody::Read(std::istream * /*stream*/, PmxSetting * /*setting*/)
|
void PmxSoftBody::Read(std::istream * /*stream*/, PmxSetting * /*setting*/)
|
||||||
{
|
{
|
||||||
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()
|
||||||
{
|
{
|
||||||
|
@ -512,14 +513,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);
|
||||||
|
|
||||||
this->model_name = ReadString(stream, setting.encoding);
|
this->model_name = ReadString(stream, setting.encoding);
|
||||||
|
@ -598,34 +599,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;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,9 +63,9 @@ aiReturn aiGetMaterialProperty(const aiMaterial* pMat,
|
||||||
unsigned int index,
|
unsigned int index,
|
||||||
const aiMaterialProperty** pPropOut)
|
const aiMaterialProperty** pPropOut)
|
||||||
{
|
{
|
||||||
ai_assert (pMat != NULL);
|
ai_assert( pMat != NULL );
|
||||||
ai_assert (pKey != NULL);
|
ai_assert( pKey != NULL );
|
||||||
ai_assert (pPropOut != NULL);
|
ai_assert( pPropOut != NULL );
|
||||||
|
|
||||||
/* Just search for a property with exactly this name ..
|
/* Just search for a property with exactly this name ..
|
||||||
* could be improved by hashing, but it's possibly
|
* could be improved by hashing, but it's possibly
|
||||||
|
@ -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];
|
||||||
|
@ -96,8 +96,8 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
|
||||||
ai_real* pOut,
|
ai_real* pOut,
|
||||||
unsigned int* pMax)
|
unsigned int* pMax)
|
||||||
{
|
{
|
||||||
ai_assert (pOut != NULL);
|
ai_assert( pOut != NULL );
|
||||||
ai_assert (pMat != NULL);
|
ai_assert( pMat != NULL );
|
||||||
|
|
||||||
const aiMaterialProperty* prop;
|
const aiMaterialProperty* prop;
|
||||||
aiGetMaterialProperty(pMat,pKey,type,index, (const aiMaterialProperty**) &prop);
|
aiGetMaterialProperty(pMat,pKey,type,index, (const aiMaterialProperty**) &prop);
|
||||||
|
@ -182,8 +182,8 @@ aiReturn aiGetMaterialIntegerArray(const aiMaterial* pMat,
|
||||||
int* pOut,
|
int* pOut,
|
||||||
unsigned int* pMax)
|
unsigned int* pMax)
|
||||||
{
|
{
|
||||||
ai_assert (pOut != NULL);
|
ai_assert( pOut != NULL );
|
||||||
ai_assert (pMat != NULL);
|
ai_assert( pMat != NULL );
|
||||||
|
|
||||||
const aiMaterialProperty* prop;
|
const aiMaterialProperty* prop;
|
||||||
aiGetMaterialProperty(pMat,pKey,type,index,(const aiMaterialProperty**) &prop);
|
aiGetMaterialProperty(pMat,pKey,type,index,(const aiMaterialProperty**) &prop);
|
||||||
|
@ -274,7 +274,7 @@ aiReturn aiGetMaterialUVTransform(const aiMaterial* pMat,
|
||||||
aiUVTransform* pOut)
|
aiUVTransform* pOut)
|
||||||
{
|
{
|
||||||
unsigned int iMax = 4;
|
unsigned int iMax = 4;
|
||||||
return aiGetMaterialFloatArray(pMat,pKey,type,index,(ai_real*)pOut,&iMax);
|
return aiGetMaterialFloatArray(pMat,pKey,type,index,(ai_real*)pOut,&iMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -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,12 +408,20 @@ aiMaterial::~aiMaterial()
|
||||||
delete[] mProperties;
|
delete[] mProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
aiString aiMaterial::GetName() {
|
||||||
|
aiString name;
|
||||||
|
Get(AI_MATKEY_NAME, name);
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void aiMaterial::Clear()
|
void aiMaterial::Clear()
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < mNumProperties;++i) {
|
for ( unsigned int i = 0; i < mNumProperties; ++i ) {
|
||||||
// delete this entry
|
// delete this entry
|
||||||
delete mProperties[i];
|
delete mProperties[ i ];
|
||||||
AI_DEBUG_INVALIDATE_PTR(mProperties[i]);
|
AI_DEBUG_INVALIDATE_PTR(mProperties[i]);
|
||||||
}
|
}
|
||||||
mNumProperties = 0;
|
mNumProperties = 0;
|
||||||
|
@ -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];
|
||||||
|
@ -453,17 +464,18 @@ aiReturn aiMaterial::AddBinaryProperty (const void* pInput,
|
||||||
aiPropertyTypeInfo pType
|
aiPropertyTypeInfo pType
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ai_assert (pInput != NULL);
|
ai_assert( pInput != NULL );
|
||||||
ai_assert (pKey != NULL);
|
ai_assert( pKey != NULL );
|
||||||
ai_assert (0 != pSizeInBytes);
|
ai_assert( 0 != pSizeInBytes );
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -271,7 +271,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
|
||||||
|
|
||||||
ShadingInfo s; // current material info
|
ShadingInfo s; // current material info
|
||||||
|
|
||||||
// degree of tesselation
|
// degree of tessellation
|
||||||
unsigned int iTesselation = 4;
|
unsigned int iTesselation = 4;
|
||||||
|
|
||||||
// some temporary variables we need to parse the file
|
// some temporary variables we need to parse the file
|
||||||
|
@ -988,7 +988,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
|
||||||
::ai_snprintf(currentMesh.name,128,"cone_%i",cone++);
|
::ai_snprintf(currentMesh.name,128,"cone_%i",cone++);
|
||||||
else ::ai_snprintf(currentMesh.name,128,"cylinder_%i",cylinder++);
|
else ::ai_snprintf(currentMesh.name,128,"cylinder_%i",cylinder++);
|
||||||
}
|
}
|
||||||
// 'tess' - tesselation
|
// 'tess' - tessellation
|
||||||
else if (TokenMatch(sz,"tess",4))
|
else if (TokenMatch(sz,"tess",4))
|
||||||
{
|
{
|
||||||
SkipSpaces(&sz);
|
SkipSpaces(&sz);
|
||||||
|
|
|
@ -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,22 +210,80 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene
|
||||||
ai_assert(false);
|
ai_assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create nodes for the whole scene
|
if (pModel->m_Objects.size() > 0) {
|
||||||
std::vector<aiMesh*> MeshArray;
|
|
||||||
for (size_t index = 0; index < pModel->m_Objects.size(); ++index ) {
|
|
||||||
createNodes(pModel, pModel->m_Objects[ index ], pScene->mRootNode, pScene, MeshArray);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create mesh pointer buffer for this scene
|
unsigned int meshCount = 0;
|
||||||
if (pScene->mNumMeshes > 0) {
|
unsigned int childCount = 0;
|
||||||
pScene->mMeshes = new aiMesh*[ MeshArray.size() ];
|
|
||||||
for (size_t index =0; index < MeshArray.size(); ++index ) {
|
for(size_t index = 0; index < pModel->m_Objects.size(); ++index) {
|
||||||
pScene->mMeshes[ index ] = MeshArray[ index ];
|
if(pModel->m_Objects[index]) {
|
||||||
|
++childCount;
|
||||||
|
meshCount += (unsigned int)pModel->m_Objects[index]->m_Meshes.size();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Create all materials
|
// Allocate space for the child nodes on the root node
|
||||||
createMaterials( pModel, pScene );
|
pScene->mRootNode->mChildren = new aiNode*[ childCount ];
|
||||||
|
|
||||||
|
// Create nodes for the whole scene
|
||||||
|
std::vector<aiMesh*> MeshArray;
|
||||||
|
MeshArray.reserve(meshCount);
|
||||||
|
for (size_t index = 0; index < pModel->m_Objects.size(); ++index) {
|
||||||
|
createNodes(pModel, pModel->m_Objects[index], pScene->mRootNode, pScene, MeshArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
ai_assert(pScene->mRootNode->mNumChildren == childCount);
|
||||||
|
|
||||||
|
// Create mesh pointer buffer for this scene
|
||||||
|
if (pScene->mNumMeshes > 0) {
|
||||||
|
pScene->mMeshes = new aiMesh*[MeshArray.size()];
|
||||||
|
for (size_t index = 0; index < MeshArray.size(); ++index) {
|
||||||
|
pScene->mMeshes[index] = MeshArray[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create all materials
|
||||||
|
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;
|
||||||
|
|
|
@ -691,7 +691,7 @@ void OpenGEXImporter::handleTransformNode( ODDLParser::DDLNode *node, aiScene *
|
||||||
void OpenGEXImporter::handleMeshNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
void OpenGEXImporter::handleMeshNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||||
m_currentMesh = new aiMesh;
|
m_currentMesh = new aiMesh;
|
||||||
const size_t meshidx( m_meshCache.size() );
|
const size_t meshidx( m_meshCache.size() );
|
||||||
// ownership is transfered but a reference remains in m_currentMesh
|
// ownership is transferred but a reference remains in m_currentMesh
|
||||||
m_meshCache.emplace_back( m_currentMesh );
|
m_meshCache.emplace_back( m_currentMesh );
|
||||||
|
|
||||||
Property *prop = node->getProperties();
|
Property *prop = node->getProperties();
|
||||||
|
|
|
@ -102,7 +102,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Rmeove a node from the list of locked nodes.
|
/** @brief Remove a node from the list of locked nodes.
|
||||||
* @param name Name to be unlocked
|
* @param name Name to be unlocked
|
||||||
*/
|
*/
|
||||||
inline void RemoveLockedNode(std::string& name)
|
inline void RemoveLockedNode(std::string& name)
|
||||||
|
|
|
@ -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,22 +73,20 @@ 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>
|
inline
|
||||||
const T &GetProperty(const std::vector<T> &props, int idx)
|
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.");
|
}
|
||||||
|
|
||||||
|
return props[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
return props[idx];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// 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 };
|
||||||
|
@ -416,7 +414,7 @@ void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementIn
|
||||||
haveColor = true;
|
haveColor = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// assume 1.0 for the alpha channel ifit is not set
|
// assume 1.0 for the alpha channel if it is not set
|
||||||
if (0xFFFFFFFF == aiColors[3]) {
|
if (0xFFFFFFFF == aiColors[3]) {
|
||||||
cOut.a = 1.0;
|
cOut.a = 1.0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -481,225 +479,205 @@ 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:
|
||||||
|
return (ai_real)val.iUInt / (ai_real)0xFF;
|
||||||
|
case EDT_Char:
|
||||||
|
return (ai_real)(val.iInt + (0xFF / 2)) / (ai_real)0xFF;
|
||||||
|
case EDT_UShort:
|
||||||
|
return (ai_real)val.iUInt / (ai_real)0xFFFF;
|
||||||
|
case EDT_Short:
|
||||||
|
return (ai_real)(val.iInt + (0xFFFF / 2)) / (ai_real)0xFFFF;
|
||||||
|
case EDT_UInt:
|
||||||
|
return (ai_real)val.iUInt / (ai_real)0xFFFF;
|
||||||
|
case EDT_Int:
|
||||||
|
return ((ai_real)val.iInt / (ai_real)0xFF) + 0.5f;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case EDT_UChar:
|
return 0.0f;
|
||||||
return (ai_real)val.iUInt / (ai_real)0xFF;
|
|
||||||
case EDT_Char:
|
|
||||||
return (ai_real)(val.iInt + (0xFF / 2)) / (ai_real)0xFF;
|
|
||||||
case EDT_UShort:
|
|
||||||
return (ai_real)val.iUInt / (ai_real)0xFFFF;
|
|
||||||
case EDT_Short:
|
|
||||||
return (ai_real)(val.iInt + (0xFFFF / 2)) / (ai_real)0xFFFF;
|
|
||||||
case EDT_UInt:
|
|
||||||
return (ai_real)val.iUInt / (ai_real)0xFFFF;
|
|
||||||
case EDT_Int:
|
|
||||||
return ((ai_real)val.iInt / (ai_real)0xFF) + 0.5f;
|
|
||||||
default:;
|
|
||||||
};
|
|
||||||
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;
|
|
||||||
|
|
||||||
// index of the vertex index list
|
|
||||||
unsigned int iProperty = 0xFFFFFFFF;
|
|
||||||
PLY::EDataType eType = EDT_Char;
|
|
||||||
bool bIsTriStrip = false;
|
|
||||||
|
|
||||||
// index of the material index property
|
|
||||||
//unsigned int iMaterialIndex = 0xFFFFFFFF;
|
|
||||||
//PLY::EDataType eType2 = EDT_Char;
|
|
||||||
|
|
||||||
// texture coordinates
|
|
||||||
unsigned int iTextureCoord = 0xFFFFFFFF;
|
|
||||||
PLY::EDataType eType3 = EDT_Char;
|
|
||||||
|
|
||||||
// face = unique number of vertex indices
|
|
||||||
if (PLY::EEST_Face == pcElement->eSemantic)
|
|
||||||
{
|
|
||||||
unsigned int _a = 0;
|
|
||||||
for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
|
|
||||||
a != pcElement->alProperties.end(); ++a, ++_a)
|
|
||||||
{
|
|
||||||
if (PLY::EST_VertexIndex == (*a).Semantic)
|
|
||||||
{
|
|
||||||
// must be a dynamic list!
|
|
||||||
if (!(*a).bIsList)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
iProperty = _a;
|
|
||||||
bOne = true;
|
|
||||||
eType = (*a).eType;
|
|
||||||
}
|
|
||||||
/*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!
|
|
||||||
if (!(*a).bIsList)
|
|
||||||
continue;
|
|
||||||
iTextureCoord = _a;
|
|
||||||
bOne = true;
|
|
||||||
eType3 = (*a).eType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// triangle strip
|
|
||||||
// TODO: triangle strip and material index support???
|
|
||||||
else if (PLY::EEST_TriStrip == pcElement->eSemantic)
|
|
||||||
{
|
|
||||||
unsigned int _a = 0;
|
|
||||||
for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
|
|
||||||
a != pcElement->alProperties.end(); ++a, ++_a)
|
|
||||||
{
|
|
||||||
// must be a dynamic list!
|
|
||||||
if (!(*a).bIsList)
|
|
||||||
continue;
|
|
||||||
iProperty = _a;
|
|
||||||
bOne = true;
|
|
||||||
bIsTriStrip = true;
|
|
||||||
eType = (*a).eType;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check whether we have at least one per-face information set
|
|
||||||
if (bOne)
|
|
||||||
{
|
|
||||||
if (mGeneratedMesh->mFaces == NULL)
|
|
||||||
{
|
|
||||||
mGeneratedMesh->mNumFaces = pcElement->NumOccur;
|
|
||||||
mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bIsTriStrip)
|
bool bOne = false;
|
||||||
{
|
|
||||||
// parse the list of vertex indices
|
|
||||||
if (0xFFFFFFFF != iProperty)
|
|
||||||
{
|
|
||||||
const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iProperty).avList.size();
|
|
||||||
mGeneratedMesh->mFaces[pos].mNumIndices = iNum;
|
|
||||||
mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[iNum];
|
|
||||||
|
|
||||||
std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
|
// index of the vertex index list
|
||||||
GetProperty(instElement->alProperties, iProperty).avList.begin();
|
unsigned int iProperty = 0xFFFFFFFF;
|
||||||
|
PLY::EDataType eType = EDT_Char;
|
||||||
|
bool bIsTriStrip = false;
|
||||||
|
|
||||||
for (unsigned int a = 0; a < iNum; ++a, ++p)
|
// index of the material index property
|
||||||
{
|
//unsigned int iMaterialIndex = 0xFFFFFFFF;
|
||||||
mGeneratedMesh->mFaces[pos].mIndices[a] = PLY::PropertyInstance::ConvertTo<unsigned int>(*p, eType);
|
//PLY::EDataType eType2 = EDT_Char;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse the material index
|
// texture coordinates
|
||||||
// cannot be handled without processing the whole file first
|
unsigned int iTextureCoord = 0xFFFFFFFF;
|
||||||
/*if (0xFFFFFFFF != iMaterialIndex)
|
PLY::EDataType eType3 = EDT_Char;
|
||||||
{
|
|
||||||
mGeneratedMesh->mFaces[pos]. = PLY::PropertyInstance::ConvertTo<unsigned int>(
|
|
||||||
GetProperty(instElement->alProperties, iMaterialIndex).avList.front(), eType2);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (0xFFFFFFFF != iTextureCoord)
|
// face = unique number of vertex indices
|
||||||
{
|
if (PLY::EEST_Face == pcElement->eSemantic) {
|
||||||
const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iTextureCoord).avList.size();
|
unsigned int _a = 0;
|
||||||
|
for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
|
||||||
|
a != pcElement->alProperties.end(); ++a, ++_a) {
|
||||||
|
if (PLY::EST_VertexIndex == (*a).Semantic) {
|
||||||
|
// must be a dynamic list!
|
||||||
|
if (!(*a).bIsList) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
//should be 6 coords
|
iProperty = _a;
|
||||||
std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
|
bOne = true;
|
||||||
GetProperty(instElement->alProperties, iTextureCoord).avList.begin();
|
eType = (*a).eType;
|
||||||
|
} else if (PLY::EST_TextureCoordinates == (*a).Semantic) {
|
||||||
if ((iNum / 3) == 2) // X Y coord
|
// must be a dynamic list!
|
||||||
{
|
if (!(*a).bIsList) {
|
||||||
for (unsigned int a = 0; a < iNum; ++a, ++p)
|
continue;
|
||||||
{
|
}
|
||||||
unsigned int vindex = mGeneratedMesh->mFaces[pos].mIndices[a / 2];
|
iTextureCoord = _a;
|
||||||
if (vindex < mGeneratedMesh->mNumVertices)
|
bOne = true;
|
||||||
{
|
eType3 = (*a).eType;
|
||||||
if (mGeneratedMesh->mTextureCoords[0] == NULL)
|
|
||||||
{
|
|
||||||
mGeneratedMesh->mNumUVComponents[0] = 2;
|
|
||||||
mGeneratedMesh->mTextureCoords[0] = new aiVector3D[mGeneratedMesh->mNumVertices];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a % 2 == 0)
|
|
||||||
mGeneratedMesh->mTextureCoords[0][vindex].x = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3);
|
|
||||||
else
|
|
||||||
mGeneratedMesh->mTextureCoords[0][vindex].y = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3);
|
|
||||||
|
|
||||||
mGeneratedMesh->mTextureCoords[0][vindex].z = 0;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else // triangle strips
|
// triangle strip
|
||||||
{
|
// TODO: triangle strip and material index support???
|
||||||
// normally we have only one triangle strip instance where
|
else if (PLY::EEST_TriStrip == pcElement->eSemantic) {
|
||||||
// a value of -1 indicates a restart of the strip
|
unsigned int _a = 0;
|
||||||
bool flip = false;
|
for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
|
||||||
const std::vector<PLY::PropertyInstance::ValueUnion>& quak = GetProperty(instElement->alProperties, iProperty).avList;
|
a != pcElement->alProperties.end(); ++a, ++_a) {
|
||||||
//pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u)); //Limits memory consumption
|
// must be a dynamic list!
|
||||||
|
if (!(*a).bIsList) {
|
||||||
int aiTable[2] = { -1, -1 };
|
continue;
|
||||||
for (std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator a = quak.begin(); a != quak.end(); ++a) {
|
}
|
||||||
const int p = PLY::PropertyInstance::ConvertTo<int>(*a, eType);
|
iProperty = _a;
|
||||||
|
bOne = true;
|
||||||
if (-1 == p) {
|
bIsTriStrip = true;
|
||||||
// restart the strip ...
|
eType = (*a).eType;
|
||||||
aiTable[0] = aiTable[1] = -1;
|
break;
|
||||||
flip = false;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if (-1 == aiTable[0]) {
|
}
|
||||||
aiTable[0] = p;
|
|
||||||
continue;
|
// check whether we have at least one per-face information set
|
||||||
}
|
if (bOne) {
|
||||||
if (-1 == aiTable[1]) {
|
if (mGeneratedMesh->mFaces == nullptr) {
|
||||||
aiTable[1] = p;
|
mGeneratedMesh->mNumFaces = pcElement->NumOccur;
|
||||||
continue;
|
mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mGeneratedMesh->mFaces == NULL)
|
if (!bIsTriStrip) {
|
||||||
|
// parse the list of vertex indices
|
||||||
|
if (0xFFFFFFFF != iProperty) {
|
||||||
|
const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iProperty).avList.size();
|
||||||
|
mGeneratedMesh->mFaces[pos].mNumIndices = iNum;
|
||||||
|
mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[iNum];
|
||||||
|
|
||||||
|
std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
|
||||||
|
GetProperty(instElement->alProperties, iProperty).avList.begin();
|
||||||
|
|
||||||
|
for (unsigned int a = 0; a < iNum; ++a, ++p) {
|
||||||
|
mGeneratedMesh->mFaces[pos].mIndices[a] = PLY::PropertyInstance::ConvertTo<unsigned int>(*p, eType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse the material index
|
||||||
|
// cannot be handled without processing the whole file first
|
||||||
|
/*if (0xFFFFFFFF != iMaterialIndex)
|
||||||
{
|
{
|
||||||
mGeneratedMesh->mNumFaces = pcElement->NumOccur;
|
mGeneratedMesh->mFaces[pos]. = PLY::PropertyInstance::ConvertTo<unsigned int>(
|
||||||
mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
|
GetProperty(instElement->alProperties, iMaterialIndex).avList.front(), eType2);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
if (0xFFFFFFFF != iTextureCoord) {
|
||||||
|
const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iTextureCoord).avList.size();
|
||||||
|
|
||||||
|
//should be 6 coords
|
||||||
|
std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
|
||||||
|
GetProperty(instElement->alProperties, iTextureCoord).avList.begin();
|
||||||
|
|
||||||
|
if ((iNum / 3) == 2) // X Y coord
|
||||||
|
{
|
||||||
|
for (unsigned int a = 0; a < iNum; ++a, ++p) {
|
||||||
|
unsigned int vindex = mGeneratedMesh->mFaces[pos].mIndices[a / 2];
|
||||||
|
if (vindex < mGeneratedMesh->mNumVertices) {
|
||||||
|
if (mGeneratedMesh->mTextureCoords[0] == nullptr ) {
|
||||||
|
mGeneratedMesh->mNumUVComponents[0] = 2;
|
||||||
|
mGeneratedMesh->mTextureCoords[0] = new aiVector3D[mGeneratedMesh->mNumVertices];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a % 2 == 0) {
|
||||||
|
mGeneratedMesh->mTextureCoords[0][vindex].x = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3);
|
||||||
|
} else {
|
||||||
|
mGeneratedMesh->mTextureCoords[0][vindex].y = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3);
|
||||||
|
}
|
||||||
|
|
||||||
|
mGeneratedMesh->mTextureCoords[0][vindex].z = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // triangle strips
|
||||||
|
// normally we have only one triangle strip instance where
|
||||||
|
// a value of -1 indicates a restart of the strip
|
||||||
|
bool flip = false;
|
||||||
|
const std::vector<PLY::PropertyInstance::ValueUnion>& quak = GetProperty(instElement->alProperties, iProperty).avList;
|
||||||
|
//pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u)); //Limits memory consumption
|
||||||
|
|
||||||
|
int aiTable[2] = { -1, -1 };
|
||||||
|
for (std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator a = quak.begin(); a != quak.end(); ++a) {
|
||||||
|
const int p = PLY::PropertyInstance::ConvertTo<int>(*a, eType);
|
||||||
|
|
||||||
|
if (-1 == p) {
|
||||||
|
// restart the strip ...
|
||||||
|
aiTable[0] = aiTable[1] = -1;
|
||||||
|
flip = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (-1 == aiTable[0]) {
|
||||||
|
aiTable[0] = p;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (-1 == aiTable[1]) {
|
||||||
|
aiTable[1] = p;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mGeneratedMesh->mFaces == nullptr) {
|
||||||
|
mGeneratedMesh->mNumFaces = pcElement->NumOccur;
|
||||||
|
mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
|
||||||
|
}
|
||||||
|
|
||||||
|
mGeneratedMesh->mFaces[pos].mNumIndices = 3;
|
||||||
|
mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[3];
|
||||||
|
mGeneratedMesh->mFaces[pos].mIndices[0] = aiTable[0];
|
||||||
|
mGeneratedMesh->mFaces[pos].mIndices[1] = aiTable[1];
|
||||||
|
mGeneratedMesh->mFaces[pos].mIndices[2] = p;
|
||||||
|
|
||||||
|
// every second pass swap the indices.
|
||||||
|
flip = !flip;
|
||||||
|
if ( flip ) {
|
||||||
|
std::swap(mGeneratedMesh->mFaces[pos].mIndices[0], mGeneratedMesh->mFaces[pos].mIndices[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
aiTable[0] = aiTable[1];
|
||||||
|
aiTable[1] = p;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mGeneratedMesh->mFaces[pos].mNumIndices = 3;
|
|
||||||
mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[3];
|
|
||||||
mGeneratedMesh->mFaces[pos].mIndices[0] = aiTable[0];
|
|
||||||
mGeneratedMesh->mFaces[pos].mIndices[1] = aiTable[1];
|
|
||||||
mGeneratedMesh->mFaces[pos].mIndices[2] = p;
|
|
||||||
|
|
||||||
if ((flip = !flip)) {
|
|
||||||
std::swap(mGeneratedMesh->mFaces[pos].mIndices[0], mGeneratedMesh->mFaces[pos].mIndices[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
aiTable[0] = aiTable[1];
|
|
||||||
aiTable[1] = p;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -212,7 +212,7 @@ template <> struct MinMaxChooser<aiVertexWeight> {
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
/** @brief Find the min/max values of an array of Ts
|
/** @brief Find the min/max values of an array of Ts
|
||||||
* @param in Input array
|
* @param in Input array
|
||||||
* @param size Numebr of elements to process
|
* @param size Number of elements to process
|
||||||
* @param[out] min minimum value
|
* @param[out] min minimum value
|
||||||
* @param[out] max maximum value
|
* @param[out] max maximum value
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -62,17 +62,17 @@ struct aiNode;
|
||||||
// STL headers
|
// STL headers
|
||||||
#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");
|
||||||
}
|
}
|
||||||
pMesh->mNumFaces = static_cast<unsigned int>(positionBuffer.size() / 3);
|
|
||||||
pMesh->mNumVertices = static_cast<unsigned int>(positionBuffer.size());
|
// only process positionbuffer when filled, else exception when accessing with index operator
|
||||||
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
|
// see line 353: only warning is triggered
|
||||||
memcpy(pMesh->mVertices, &positionBuffer[0].x, pMesh->mNumVertices * sizeof(aiVector3D));
|
// see line 373(now): access to empty positionbuffer with index operator forced exception
|
||||||
positionBuffer.clear();
|
if (!positionBuffer.empty()) {
|
||||||
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
|
pMesh->mNumFaces = static_cast<unsigned int>(positionBuffer.size() / 3);
|
||||||
memcpy(pMesh->mNormals, &normalBuffer[0].x, pMesh->mNumVertices * sizeof(aiVector3D));
|
pMesh->mNumVertices = static_cast<unsigned int>(positionBuffer.size());
|
||||||
normalBuffer.clear();
|
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
|
||||||
|
memcpy(pMesh->mVertices, &positionBuffer[0].x, pMesh->mNumVertices * sizeof(aiVector3D));
|
||||||
|
positionBuffer.clear();
|
||||||
|
}
|
||||||
|
// also only process normalBuffer when filled, else exception when accessing with index operator
|
||||||
|
if (!normalBuffer.empty()) {
|
||||||
|
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
|
||||||
|
memcpy(pMesh->mNormals, &normalBuffer[0].x, pMesh->mNumVertices * sizeof(aiVector3D));
|
||||||
|
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])
|
||||||
{
|
{
|
||||||
|
|
|
@ -707,30 +707,30 @@ void SceneCombiner::MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator
|
||||||
// we work with hashes to make the comparisons MUCH faster,
|
// we work with hashes to make the comparisons MUCH faster,
|
||||||
// at least if we have many bones.
|
// at least if we have many bones.
|
||||||
std::list<BoneWithHash> asBones;
|
std::list<BoneWithHash> asBones;
|
||||||
BuildUniqueBoneList(asBones, it,end);
|
BuildUniqueBoneList( asBones, it, end );
|
||||||
|
|
||||||
// now create the output bones
|
// now create the output bones
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ void ScenePreprocessor::ProcessMesh (aiMesh* mesh)
|
||||||
|
|
||||||
aiVector3D* p = mesh->mTextureCoords[i], *end = p+mesh->mNumVertices;
|
aiVector3D* p = mesh->mTextureCoords[i], *end = p+mesh->mNumVertices;
|
||||||
|
|
||||||
// Ensure unsued components are zeroed. This will make 1D texture channels work
|
// Ensure unused components are zeroed. This will make 1D texture channels work
|
||||||
// as if they were 2D channels .. just in case an application doesn't handle
|
// as if they were 2D channels .. just in case an application doesn't handle
|
||||||
// this case
|
// this case
|
||||||
if (2 == mesh->mNumUVComponents[i]) {
|
if (2 == mesh->mNumUVComponents[i]) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -223,7 +223,7 @@ namespace {
|
||||||
if( (-42 == (~42 + 1)) && (binValue & 0x80000000))
|
if( (-42 == (~42 + 1)) && (binValue & 0x80000000))
|
||||||
return BinFloat(1 << (CHAR_BIT * sizeof(BinFloat) - 1)) - binValue;
|
return BinFloat(1 << (CHAR_BIT * sizeof(BinFloat) - 1)) - binValue;
|
||||||
// One's complement?
|
// One's complement?
|
||||||
else if( (-42 == ~42) && (binValue & 0x80000000))
|
else if ( (-42 == ~42) && (binValue & 0x80000000))
|
||||||
return BinFloat(-0) - binValue;
|
return BinFloat(-0) - binValue;
|
||||||
// Sign-magnitude?
|
// Sign-magnitude?
|
||||||
else if( (-42 == (42 | (-0))) && (binValue & 0x80000000)) // -0 = 1000... binary
|
else if( (-42 == (42 | (-0))) && (binValue & 0x80000000)) // -0 = 1000... binary
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -377,7 +377,7 @@ void StandardShapes::MakeSphere(unsigned int tess,
|
||||||
MakeIcosahedron(positions);
|
MakeIcosahedron(positions);
|
||||||
|
|
||||||
// ... and subdivide it until the requested output
|
// ... and subdivide it until the requested output
|
||||||
// tesselation is reached
|
// tessellation is reached
|
||||||
for (unsigned int i = 0; i<tess;++i)
|
for (unsigned int i = 0; i<tess;++i)
|
||||||
Subdivide(positions);
|
Subdivide(positions);
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue