Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
676ef9637b |
+1
-1
@@ -70,7 +70,7 @@ IncludeCategories:
|
||||
- Regex: '^<.*'
|
||||
Priority: 3
|
||||
# IncludeIsMainRegex: '(Test)?$'
|
||||
IndentCaseLabels: false
|
||||
IndentCaseLabels: false
|
||||
#IndentPPDirectives: AfterHash
|
||||
IndentWidth: 4
|
||||
# IndentWrappedFunctionNames: false
|
||||
|
||||
@@ -23,10 +23,6 @@ jobs:
|
||||
os: windows-latest
|
||||
cxx: cl.exe
|
||||
cc: cl.exe
|
||||
- name: windows-hunter-latest-cl.exe
|
||||
os: windows-latest
|
||||
cxx: cl.exe
|
||||
cc: cl.exe
|
||||
- name: ubuntu-latest-clang++
|
||||
os: ubuntu-latest
|
||||
cxx: clang++
|
||||
|
||||
@@ -4,9 +4,7 @@
|
||||
### Install prerequisites
|
||||
You need to install
|
||||
* cmake
|
||||
* Your compiler (must support C++17 and C99 at least)
|
||||
* For Windows
|
||||
* DX-SDK 9 if you want to use our 3D-Viewer
|
||||
* Your compiler
|
||||
|
||||
### Get the source
|
||||
Make sure you have a working git-installation. Open a command prompt and clone the Asset-Importer-Lib via:
|
||||
@@ -41,7 +39,7 @@ This will generate the project files for the visual studio. All dependencies use
|
||||
See <https://stackoverflow.com/questions/40803170/cmake-uwp-using-cmake-to-build-universal-windows-app>
|
||||
|
||||
### Build instructions for MinGW
|
||||
Older versions of MinGW's compiler (e.g. 5.1.0) do not support the -mbig_obj flag
|
||||
Older versions of MinGW's compiler (e.g. 5.1.0) do not support the -mbig_obj flag
|
||||
required to compile some of assimp's files, especially for debug builds.
|
||||
Version 7.3.0 of g++-mingw-w64 & gcc-mingw-w64 appears to work.
|
||||
|
||||
|
||||
@@ -290,7 +290,7 @@ FEATURES:
|
||||
- Added support for 64 bit version header introduced in FbxSdk2016
|
||||
- Travis: enable coverall support.
|
||||
- PyAssimp: New version of the pyASSIMP 3D viewer, with much improved 3D controls
|
||||
- Morph animation support for collada
|
||||
- Morph animation support for collada
|
||||
- Added support for parameters Ni and Tf in OBJ/MTL file format
|
||||
- aiScene: add method to add children
|
||||
- Added new option to IFC importer to control tessellation angle + removed unused IFC option
|
||||
@@ -300,7 +300,7 @@ FEATURES:
|
||||
- travis ci: enable sudo support.
|
||||
- openddlparser: integrate release v0.4.0
|
||||
- aiMetaData: Added support for metadata in assbin format
|
||||
|
||||
|
||||
FIXES/HOUSEKEEPING:
|
||||
- Introduce usage of #pragma statement
|
||||
- Put cmake-scripts into their own folder
|
||||
@@ -352,7 +352,7 @@ FIXES/HOUSEKEEPING:
|
||||
- add vertex color export support ( issue 809 )
|
||||
- Fix memory leak in Collada importer ( issue 1169 )
|
||||
- add stp to the list of supported extensions for step-files ( issue 1183 )
|
||||
- fix clang build ( Issue-1169 )
|
||||
- fix clang build ( Issue-1169 )
|
||||
- fix for FreeBSD
|
||||
- Import FindPkgMacros to main CMake Configuration
|
||||
- Extended support for tessellation parameter to more IFC shapes
|
||||
@@ -375,7 +375,7 @@ FIXES/HOUSEKEEPING:
|
||||
- Obj-Importer: do not break when detecting an overflow ( issue 1244 )
|
||||
- Obj-Importer: fix parsing of multible line data definitions
|
||||
- Fixed bug where IFC models with multiple IFCSite only loaded 1 site instead of the complete model
|
||||
- PLYImporter: - optimize memory and speed on ply importer / change parser to use a file stream - manage texture path in ply
|
||||
- PLYImporter: - optimize memory and speed on ply importer / change parser to use a file stream - manage texture path in ply
|
||||
import - manage texture coords on faces in ply import - correction on point cloud faces generation
|
||||
- Utf8: integrate new lib ( issue 1158 )
|
||||
- fixed CMAKE_MODULE_PATH overwriting previous values
|
||||
@@ -400,7 +400,7 @@ FIXES/HOUSEKEEPING:
|
||||
- Remove std functions deprecated by C++11.
|
||||
- X-Importer: make it deal with lines
|
||||
- use correct path for compilers ( issue 1335 )
|
||||
- Collada: add workaround to deal with polygon with holes
|
||||
- Collada: add workaround to deal with polygon with holes
|
||||
- update python readme
|
||||
- Use unique node names when loading Collada files
|
||||
- Fixed many FBX bugs
|
||||
@@ -429,7 +429,7 @@ FEATURES:
|
||||
- C4D: update to latest Melange-SDK
|
||||
- Add a gitter channel
|
||||
- Coverity check enabled
|
||||
- Switch to <...> include brackets for public headers
|
||||
- Switch to <...> include brackets for public headers
|
||||
- Enable export by pyAssimp
|
||||
- CI: check windows build
|
||||
- Add functionality to perform a singlepost-processing step
|
||||
@@ -564,7 +564,7 @@ API CHANGES:
|
||||
currently used, however ...)
|
||||
- Some Assimp::Importer methods are const now.
|
||||
|
||||
|
||||
|
||||
1.1 (2010-04-17)
|
||||
This is the list of relevant changes from the 1.0 (r412) release to 1.1 (r700).
|
||||
|
||||
|
||||
+2
-5
@@ -347,11 +347,8 @@ ELSEIF(MSVC)
|
||||
elseif((GENERATOR_IS_MULTI_CONFIG) OR (CMAKE_BUILD_TYPE MATCHES Release))
|
||||
message("-- MSVC PDB generation disabled. Release binary will not be debuggable.")
|
||||
endif()
|
||||
if(NOT /utf-8 IN_LIST CMAKE_CXX_FLAGS)
|
||||
# Source code is encoded in UTF-8
|
||||
ADD_COMPILE_OPTIONS(/source-charset:utf-8)
|
||||
endif ()
|
||||
|
||||
# Source code is encoded in UTF-8
|
||||
ADD_COMPILE_OPTIONS(/source-charset:utf-8)
|
||||
ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||
IF(NOT ASSIMP_HUNTER_ENABLED)
|
||||
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
@@ -60,7 +60,7 @@ The GUY who performed some of the CSM mocaps.
|
||||
Contributed fixes for the documentation and the doxygen markup
|
||||
|
||||
- Zhao Lei
|
||||
Contributed several bugfixes fixing memory leaks and improving float parsing
|
||||
Contributed several bugfixes fixing memory leaks and improving float parsing
|
||||
|
||||
- sueastside
|
||||
Updated PyAssimp to the latest Assimp data structures and provided a script to keep the Python binding up-to-date.
|
||||
@@ -129,7 +129,7 @@ Contributed a patch to fix the VertexTriangleAdjacency postprocessing step.
|
||||
Contributed the Debian build fixes ( architecture macro ).
|
||||
|
||||
- gellule
|
||||
Several LWO and LWS fixes (pivoting).
|
||||
Several LWO and LWS fixes (pivoting).
|
||||
|
||||
- Marcel Metz
|
||||
GCC/Linux fixes for the SimpleOpenGL sample.
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
FROM gcc:latest
|
||||
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y ninja-build cmake
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y ninja-build cmake
|
||||
|
||||
WORKDIR /app
|
||||
RUN apt install zlib1g-dev
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
|
||||
|
||||
========================================================================
|
||||
Open Asset Import Library (assimp) INSTALL
|
||||
Open Asset Import Library (assimp) INSTALL
|
||||
========================================================================
|
||||
|
||||
------------------------------
|
||||
Getting the documentation
|
||||
------------------------------
|
||||
|
||||
A regularly-updated copy is available at
|
||||
A regularly-updated copy is available at
|
||||
https://assimp-docs.readthedocs.io/en/latest/
|
||||
|
||||
------------------------------
|
||||
Building Assimp
|
||||
Building Assimp
|
||||
------------------------------
|
||||
|
||||
Just check the build-instructions which you can find here: https://github.com/assimp/assimp/blob/master/Build.md
|
||||
|
||||
@@ -3,7 +3,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Open Asset Import Library is a library that loads various 3D file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
|
||||
|
||||
### Current project status ###
|
||||
### Current project status ###
|
||||

|
||||
[](https://www.codacy.com/gh/assimp/assimp/dashboard?utm_source=github.com&utm_medium=referral&utm_content=assimp/assimp&utm_campaign=Badge_Grade)
|
||||
[](https://sonarcloud.io/summary/new_code?id=assimp_assimp)
|
||||
@@ -32,7 +32,7 @@ Clone [our model database](https://github.com/assimp/assimp-mdb).
|
||||
- Ask questions at [the Assimp Discussion Board](https://github.com/assimp/assimp/discussions).
|
||||
- Find us on [https://discord.gg/s9KJfaem](https://discord.gg/kKazXMXDy2)
|
||||
- Ask [the Assimp community on Reddit](https://www.reddit.com/r/Assimp/).
|
||||
- Ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest).
|
||||
- Ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest).
|
||||
- Nothing has worked? File a question or an issue report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues)
|
||||
|
||||
#### Supported file formats ####
|
||||
|
||||
+1
-1
@@ -11,6 +11,6 @@ currently being supported with security updates.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you have found any security vulnerability you can contact us via
|
||||
If you have found any security vulnerability you can contact us via
|
||||
kim.kulling@googlemail.com
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# Creates source debian files and manages library dependencies
|
||||
#
|
||||
# Features:
|
||||
#
|
||||
#
|
||||
# - Automatically generates symbols and run-time dependencies from the build dependencies
|
||||
# - Custom copy of source directory via CPACK_DEBIAN_PACKAGE_SOURCE_COPY
|
||||
# - Simultaneous output of multiple debian source packages for each distribution
|
||||
@@ -114,6 +114,7 @@ foreach(RELEASE ${CPACK_DEBIAN_DISTRIBUTION_RELEASES})
|
||||
endif( CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER} )
|
||||
endif( CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
|
||||
|
||||
file(APPEND ${DEBIAN_CONTROL} "\n"
|
||||
"Standards-Version: 3.8.4\n"
|
||||
"Homepage: ${CPACK_PACKAGE_VENDOR}\n"
|
||||
@@ -172,7 +173,7 @@ foreach(RELEASE ${CPACK_DEBIAN_DISTRIBUTION_RELEASES})
|
||||
endforeach(DEP ${CPACK_DEBIAN_PACKAGE_SUGGESTS})
|
||||
endif( CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER} )
|
||||
endif( CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
|
||||
|
||||
|
||||
file(APPEND ${DEBIAN_CONTROL} "\n"
|
||||
"Description: ${CPACK_PACKAGE_DISPLAY_NAME} ${CPACK_PACKAGE_DESCRIPTION_SUMMARY}\n"
|
||||
"${DEB_LONG_DESCRIPTION}"
|
||||
|
||||
@@ -26,7 +26,7 @@ if(WIN32) # The only platform it makes sense to check for DirectX SDK
|
||||
getenv_path(DIRECTX_BASE)
|
||||
|
||||
# construct search paths
|
||||
set(DirectX_PREFIX_PATH
|
||||
set(DirectX_PREFIX_PATH
|
||||
"${DXSDK_DIR}" "${ENV_DXSDK_DIR}"
|
||||
"${DIRECTX_HOME}" "${ENV_DIRECTX_HOME}"
|
||||
"${DIRECTX_ROOT}" "${ENV_DIRECTX_ROOT}"
|
||||
@@ -66,7 +66,7 @@ if(WIN32) # The only platform it makes sense to check for DirectX SDK
|
||||
find_library(DirectX_D3DCOMPILER_LIBRARY NAMES d3dcompiler HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX})
|
||||
|
||||
findpkg_finish(DirectX)
|
||||
set(DirectX_LIBRARIES ${DirectX_LIBRARIES}
|
||||
set(DirectX_LIBRARIES ${DirectX_LIBRARIES}
|
||||
${DirectX_D3DX9_LIBRARY}
|
||||
${DirectX_DXERR_LIBRARY}
|
||||
${DirectX_DXGUID_LIBRARY}
|
||||
@@ -82,7 +82,7 @@ if(WIN32) # The only platform it makes sense to check for DirectX SDK
|
||||
get_filename_component(DirectX_LIBRARY_DIR "${DirectX_LIBRARY}" PATH)
|
||||
message(STATUS "DX lib dir: ${DirectX_LIBRARY_DIR}")
|
||||
find_library(DirectX_D3D11_LIBRARY NAMES d3d11 HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX})
|
||||
find_library(DirectX_D3DX11_LIBRARY NAMES d3dx11 HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX})
|
||||
find_library(DirectX_D3DX11_LIBRARY NAMES d3dx11 HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX})
|
||||
if (DirectX_D3D11_INCLUDE_DIR AND DirectX_D3D11_LIBRARY)
|
||||
set(DirectX_D3D11_FOUND TRUE)
|
||||
set(DirectX_D3D11_INCLUDE_DIR ${DirectX_D3D11_INCLUDE_DIR})
|
||||
@@ -92,8 +92,8 @@ if(WIN32) # The only platform it makes sense to check for DirectX SDK
|
||||
${DirectX_DXGI_LIBRARY}
|
||||
${DirectX_DXERR_LIBRARY}
|
||||
${DirectX_DXGUID_LIBRARY}
|
||||
${DirectX_D3DCOMPILER_LIBRARY}
|
||||
)
|
||||
${DirectX_D3DCOMPILER_LIBRARY}
|
||||
)
|
||||
endif ()
|
||||
mark_as_advanced(DirectX_D3D11_INCLUDE_DIR DirectX_D3D11_LIBRARY DirectX_D3DX11_LIBRARY)
|
||||
endif ()
|
||||
|
||||
@@ -3,7 +3,7 @@ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(ASSIMP_ARCHITECTURE "32")
|
||||
endif(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
|
||||
|
||||
if(WIN32)
|
||||
set(ASSIMP_ROOT_DIR CACHE PATH "ASSIMP root directory")
|
||||
|
||||
@@ -17,29 +17,29 @@ if(WIN32)
|
||||
|
||||
if(MSVC12)
|
||||
set(ASSIMP_MSVC_VERSION "vc120")
|
||||
elseif(MSVC14)
|
||||
elseif(MSVC14)
|
||||
set(ASSIMP_MSVC_VERSION "vc140")
|
||||
endif(MSVC12)
|
||||
|
||||
|
||||
if(MSVC12 OR MSVC14)
|
||||
|
||||
|
||||
find_path(ASSIMP_LIBRARY_DIR
|
||||
NAMES
|
||||
assimp-${ASSIMP_MSVC_VERSION}-mt.lib
|
||||
HINTS
|
||||
${ASSIMP_ROOT_DIR}/lib${ASSIMP_ARCHITECTURE}
|
||||
)
|
||||
|
||||
|
||||
find_library(ASSIMP_LIBRARY_RELEASE assimp-${ASSIMP_MSVC_VERSION}-mt.lib PATHS ${ASSIMP_LIBRARY_DIR})
|
||||
find_library(ASSIMP_LIBRARY_DEBUG assimp-${ASSIMP_MSVC_VERSION}-mtd.lib PATHS ${ASSIMP_LIBRARY_DIR})
|
||||
|
||||
set(ASSIMP_LIBRARY
|
||||
|
||||
set(ASSIMP_LIBRARY
|
||||
optimized ${ASSIMP_LIBRARY_RELEASE}
|
||||
debug ${ASSIMP_LIBRARY_DEBUG}
|
||||
)
|
||||
|
||||
|
||||
set(ASSIMP_LIBRARIES "ASSIMP_LIBRARY_RELEASE" "ASSIMP_LIBRARY_DEBUG")
|
||||
|
||||
|
||||
FUNCTION(ASSIMP_COPY_BINARIES TargetDirectory)
|
||||
ADD_CUSTOM_TARGET(AssimpCopyBinaries
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${ASSIMP_ROOT_DIR}/bin${ASSIMP_ARCHITECTURE}/assimp-${ASSIMP_MSVC_VERSION}-mtd.dll ${TargetDirectory}/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.dll
|
||||
@@ -47,37 +47,9 @@ if(WIN32)
|
||||
COMMENT "Copying Assimp binaries to '${TargetDirectory}'"
|
||||
VERBATIM)
|
||||
ENDFUNCTION(ASSIMP_COPY_BINARIES)
|
||||
|
||||
if (NOT TARGET ASSIMP)
|
||||
set(INCLUDE_DIRS ${ASSIMP_ROOT_DIR}/include)
|
||||
|
||||
find_library(ASSIMP_LIB_DEBUG
|
||||
NAMES assimp-${ASSIMP_MSVC_VERSION}-mtd.lib
|
||||
PATHS ${ASSIMP_LIBRARY_DIR})
|
||||
|
||||
find_file(ASSIMP_DLL_DEBUG
|
||||
NAMES assimp-${ASSIMP_MSVC_VERSION}-mtd.dll
|
||||
PATHS ${ASSIMP_ROOT_DIR}/bin${ASSIMP_ARCHITECTURE})
|
||||
|
||||
find_library(ASSIMP_LIB_RELEASE
|
||||
NAMES assimp-${ASSIMP_MSVC_VERSION}-mt.lib
|
||||
PATHS ${ASSIMP_LIBRARY_DIR})
|
||||
|
||||
find_file(ASSIMP_DLL_RELEASE
|
||||
NAMES assimp-${ASSIMP_MSVC_VERSION}-mt.dll
|
||||
PATHS ${ASSIMP_ROOT_DIR}/bin${ASSIMP_ARCHITECTURE})
|
||||
|
||||
add_library(ASSIMP SHARED IMPORTED)
|
||||
set_target_properties(ASSIMP PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${INCLUDE_DIRS}"
|
||||
IMPORTED_IMPLIB_DEBUG ${ASSIMP_LIB_DEBUG}
|
||||
IMPORTED_IMPLIB_RELEASE ${ASSIMP_LIB_RELEASE}
|
||||
IMPORTED_LOCATION_DEBUG ${ASSIMP_DLL_DEBUG}
|
||||
IMPORTED_LOCATION_RELEASE ${ASSIMP_DLL_RELEASE}
|
||||
)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
else(WIN32)
|
||||
|
||||
find_path(
|
||||
@@ -109,5 +81,5 @@ else(WIN32)
|
||||
message(FATAL_ERROR "Could not find asset importer library")
|
||||
endif (assimp_FIND_REQUIRED)
|
||||
endif (assimp_FOUND)
|
||||
|
||||
|
||||
endif(WIN32)
|
||||
|
||||
@@ -31,7 +31,7 @@ option(HUNTER_STATUS_PRINT "Print working status" ON)
|
||||
option(HUNTER_STATUS_DEBUG "Print a lot info" OFF)
|
||||
option(HUNTER_TLS_VERIFY "Enable/disable TLS certificate checking on downloads" ON)
|
||||
|
||||
set(HUNTER_ERROR_PAGE "https://hunter.readthedocs.io/en/latest/reference/errors")
|
||||
set(HUNTER_ERROR_PAGE "https://docs.hunter.sh/en/latest/reference/errors")
|
||||
|
||||
function(hunter_gate_status_print)
|
||||
if(HUNTER_STATUS_PRINT OR HUNTER_STATUS_DEBUG)
|
||||
|
||||
@@ -9,14 +9,14 @@ MACRO(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource SourcesVar
|
||||
OBJECT_OUTPUTS "${PrecompiledBinary}")
|
||||
|
||||
# Do not consider .c files
|
||||
foreach(fname ${Sources})
|
||||
foreach(fname ${Sources})
|
||||
GET_FILENAME_COMPONENT(fext ${fname} EXT)
|
||||
if(fext STREQUAL ".cpp")
|
||||
SET_SOURCE_FILES_PROPERTIES(${fname}
|
||||
PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledBinary}\" /FI\"${PrecompiledBinary}\" /Fp\"${PrecompiledBinary}\""
|
||||
OBJECT_DEPENDS "${PrecompiledBinary}")
|
||||
OBJECT_DEPENDS "${PrecompiledBinary}")
|
||||
endif(fext STREQUAL ".cpp")
|
||||
endforeach(fname)
|
||||
endforeach(fname)
|
||||
|
||||
ENDIF(MSVC)
|
||||
# Add precompiled header to SourcesVar
|
||||
|
||||
@@ -91,12 +91,15 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() {
|
||||
// now iterate through all meshes and through all faces and
|
||||
// find all faces that are using the default material
|
||||
unsigned int cnt = 0;
|
||||
for (auto i = mScene->mMeshes.begin(); i != mScene->mMeshes.end(); ++i) {
|
||||
for (auto a = (*i).mFaceMaterials.begin(); a != (*i).mFaceMaterials.end(); ++a) {
|
||||
for (std::vector<D3DS::Mesh>::iterator
|
||||
i = mScene->mMeshes.begin();
|
||||
i != mScene->mMeshes.end(); ++i) {
|
||||
for (std::vector<unsigned int>::iterator
|
||||
a = (*i).mFaceMaterials.begin();
|
||||
a != (*i).mFaceMaterials.end(); ++a) {
|
||||
// NOTE: The additional check seems to be necessary,
|
||||
// some exporters seem to generate invalid data here
|
||||
|
||||
if (NotSet == (*a)) {
|
||||
if (0xcdcdcdcd == (*a)) {
|
||||
(*a) = idx;
|
||||
++cnt;
|
||||
} else if ((*a) >= mScene->mMaterials.size()) {
|
||||
@@ -108,7 +111,7 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() {
|
||||
}
|
||||
if (cnt && idx == mScene->mMaterials.size()) {
|
||||
// We need to create our own default material
|
||||
Material sMat("%%%DEFAULT");
|
||||
D3DS::Material sMat("%%%DEFAULT");
|
||||
sMat.mDiffuse = aiColor3D(0.3f, 0.3f, 0.3f);
|
||||
mScene->mMaterials.push_back(sMat);
|
||||
|
||||
@@ -118,17 +121,17 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Check whether all indices are valid. Otherwise we'd crash before the validation step is reached
|
||||
void Discreet3DSImporter::CheckIndices(Mesh &sMesh) {
|
||||
for (auto i = sMesh.mFaces.begin(); i != sMesh.mFaces.end(); ++i) {
|
||||
void Discreet3DSImporter::CheckIndices(D3DS::Mesh &sMesh) {
|
||||
for (std::vector<D3DS::Face>::iterator i = sMesh.mFaces.begin(); i != sMesh.mFaces.end(); ++i) {
|
||||
// check whether all indices are in range
|
||||
for (unsigned int a = 0; a < 3; ++a) {
|
||||
if ((*i).mIndices[a] >= sMesh.mPositions.size()) {
|
||||
ASSIMP_LOG_WARN("3DS: Vertex index overflow)");
|
||||
(*i).mIndices[a] = static_cast<uint32_t>(sMesh.mPositions.size() - 1);
|
||||
(*i).mIndices[a] = (uint32_t)sMesh.mPositions.size() - 1;
|
||||
}
|
||||
if (!sMesh.mTexCoords.empty() && (*i).mIndices[a] >= sMesh.mTexCoords.size()) {
|
||||
ASSIMP_LOG_WARN("3DS: Texture coordinate index overflow)");
|
||||
(*i).mIndices[a] = static_cast<uint32_t>(sMesh.mTexCoords.size() - 1);
|
||||
(*i).mIndices[a] = (uint32_t)sMesh.mTexCoords.size() - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,7 +139,7 @@ void Discreet3DSImporter::CheckIndices(Mesh &sMesh) {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Generate out unique verbose format representation
|
||||
void Discreet3DSImporter::MakeUnique(Mesh &sMesh) {
|
||||
void Discreet3DSImporter::MakeUnique(D3DS::Mesh &sMesh) {
|
||||
// TODO: really necessary? I don't think. Just a waste of memory and time
|
||||
// to do it now in a separate buffer.
|
||||
|
||||
@@ -147,7 +150,7 @@ void Discreet3DSImporter::MakeUnique(Mesh &sMesh) {
|
||||
vNew2.resize(sMesh.mFaces.size() * 3);
|
||||
|
||||
for (unsigned int i = 0, base = 0; i < sMesh.mFaces.size(); ++i) {
|
||||
Face &face = sMesh.mFaces[i];
|
||||
D3DS::Face &face = sMesh.mFaces[i];
|
||||
|
||||
// Positions
|
||||
for (unsigned int a = 0; a < 3; ++a, ++base) {
|
||||
@@ -164,9 +167,10 @@ void Discreet3DSImporter::MakeUnique(Mesh &sMesh) {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Convert a 3DS texture to texture keys in an aiMaterial
|
||||
void CopyTexture(aiMaterial &mat, Texture &texture, aiTextureType type) {
|
||||
void CopyTexture(aiMaterial &mat, D3DS::Texture &texture, aiTextureType type) {
|
||||
// Setup the texture name
|
||||
aiString tex(texture.mMapName);
|
||||
aiString tex;
|
||||
tex.Set(texture.mMapName);
|
||||
mat.AddProperty(&tex, AI_MATKEY_TEXTURE(type, 0));
|
||||
|
||||
// Setup the texture blend factor
|
||||
@@ -193,11 +197,13 @@ void CopyTexture(aiMaterial &mat, Texture &texture, aiTextureType type) {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Convert a 3DS material to an aiMaterial
|
||||
void Discreet3DSImporter::ConvertMaterial(Material &oldMat, aiMaterial &mat) {
|
||||
void Discreet3DSImporter::ConvertMaterial(D3DS::Material &oldMat,
|
||||
aiMaterial &mat) {
|
||||
// NOTE: Pass the background image to the viewer by bypassing the
|
||||
// material system. This is an evil hack, never do it again!
|
||||
if (mBackgroundImage.empty() && bHasBG) {
|
||||
aiString tex(mBackgroundImage);
|
||||
if (0 != mBackgroundImage.length() && bHasBG) {
|
||||
aiString tex;
|
||||
tex.Set(mBackgroundImage);
|
||||
mat.AddProperty(&tex, AI_MATKEY_GLOBAL_BACKGROUND_IMAGE);
|
||||
|
||||
// Be sure this is only done for the first material
|
||||
@@ -209,7 +215,8 @@ void Discreet3DSImporter::ConvertMaterial(Material &oldMat, aiMaterial &mat) {
|
||||
oldMat.mAmbient.g += mClrAmbient.g;
|
||||
oldMat.mAmbient.b += mClrAmbient.b;
|
||||
|
||||
aiString name(oldMat.mName);
|
||||
aiString name;
|
||||
name.Set(oldMat.mName);
|
||||
mat.AddProperty(&name, AI_MATKEY_NAME);
|
||||
|
||||
// Material colors
|
||||
@@ -219,9 +226,10 @@ void Discreet3DSImporter::ConvertMaterial(Material &oldMat, aiMaterial &mat) {
|
||||
mat.AddProperty(&oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE);
|
||||
|
||||
// Phong shininess and shininess strength
|
||||
if (Discreet3DS::Phong == oldMat.mShading || Discreet3DS::Metal == oldMat.mShading) {
|
||||
if (D3DS::Discreet3DS::Phong == oldMat.mShading ||
|
||||
D3DS::Discreet3DS::Metal == oldMat.mShading) {
|
||||
if (!oldMat.mSpecularExponent || !oldMat.mShininessStrength) {
|
||||
oldMat.mShading = Discreet3DS::Gouraud;
|
||||
oldMat.mShading = D3DS::Discreet3DS::Gouraud;
|
||||
} else {
|
||||
mat.AddProperty(&oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS);
|
||||
mat.AddProperty(&oldMat.mShininessStrength, 1, AI_MATKEY_SHININESS_STRENGTH);
|
||||
@@ -243,41 +251,40 @@ void Discreet3DSImporter::ConvertMaterial(Material &oldMat, aiMaterial &mat) {
|
||||
// Shading mode
|
||||
aiShadingMode eShading = aiShadingMode_NoShading;
|
||||
switch (oldMat.mShading) {
|
||||
case Discreet3DS::Flat:
|
||||
case D3DS::Discreet3DS::Flat:
|
||||
eShading = aiShadingMode_Flat;
|
||||
break;
|
||||
|
||||
// I don't know what "Wire" shading should be,
|
||||
// assume it is simple lambertian diffuse shading
|
||||
case Discreet3DS::Wire: {
|
||||
case D3DS::Discreet3DS::Wire: {
|
||||
// Set the wireframe flag
|
||||
unsigned int iWire = 1;
|
||||
mat.AddProperty<int>((int *)&iWire, 1, AI_MATKEY_ENABLE_WIREFRAME);
|
||||
}
|
||||
[[fallthrough]];
|
||||
|
||||
case Discreet3DS::Gouraud:
|
||||
case D3DS::Discreet3DS::Gouraud:
|
||||
eShading = aiShadingMode_Gouraud;
|
||||
break;
|
||||
|
||||
// assume cook-torrance shading for metals.
|
||||
case Discreet3DS::Phong:
|
||||
case D3DS::Discreet3DS::Phong:
|
||||
eShading = aiShadingMode_Phong;
|
||||
break;
|
||||
|
||||
case Discreet3DS::Metal:
|
||||
case D3DS::Discreet3DS::Metal:
|
||||
eShading = aiShadingMode_CookTorrance;
|
||||
break;
|
||||
|
||||
// FIX to workaround a warning with GCC 4 who complained
|
||||
// about a missing case Blinn: here - Blinn isn't a valid
|
||||
// value in the 3DS Loader, it is just needed for ASE
|
||||
case Discreet3DS::Blinn:
|
||||
case D3DS::Discreet3DS::Blinn:
|
||||
eShading = aiShadingMode_Blinn;
|
||||
break;
|
||||
}
|
||||
|
||||
const int eShading_ = eShading;
|
||||
int eShading_ = static_cast<int>(eShading);
|
||||
mat.AddProperty<int>(&eShading_, 1, AI_MATKEY_SHADING_MODEL);
|
||||
|
||||
// DIFFUSE texture
|
||||
@@ -646,7 +653,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
|
||||
pcOut->mChildren = new aiNode *[pcIn->mChildren.size()];
|
||||
|
||||
// Recursively process all children
|
||||
|
||||
|
||||
for (unsigned int i = 0; i < size; ++i) {
|
||||
pcOut->mChildren[i] = new aiNode();
|
||||
pcOut->mChildren[i]->mParent = pcOut;
|
||||
@@ -776,7 +783,7 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene *pcOut) {
|
||||
// Convert all meshes in the scene and generate the final output scene.
|
||||
void Discreet3DSImporter::ConvertScene(aiScene *pcOut) {
|
||||
// Allocate enough storage for all output materials
|
||||
pcOut->mNumMaterials = static_cast<unsigned int>(mScene->mMaterials.size());
|
||||
pcOut->mNumMaterials = (unsigned int)mScene->mMaterials.size();
|
||||
pcOut->mMaterials = new aiMaterial *[pcOut->mNumMaterials];
|
||||
|
||||
// ... and convert the 3DS materials to aiMaterial's
|
||||
@@ -790,17 +797,17 @@ void Discreet3DSImporter::ConvertScene(aiScene *pcOut) {
|
||||
ConvertMeshes(pcOut);
|
||||
|
||||
// Now copy all light sources to the output scene
|
||||
pcOut->mNumLights = static_cast<unsigned int>(mScene->mLights.size());
|
||||
pcOut->mNumLights = (unsigned int)mScene->mLights.size();
|
||||
if (pcOut->mNumLights) {
|
||||
pcOut->mLights = new aiLight *[pcOut->mNumLights];
|
||||
memcpy(pcOut->mLights, &mScene->mLights[0], sizeof(void *) * pcOut->mNumLights);
|
||||
::memcpy(pcOut->mLights, &mScene->mLights[0], sizeof(void *) * pcOut->mNumLights);
|
||||
}
|
||||
|
||||
// Now copy all cameras to the output scene
|
||||
pcOut->mNumCameras = static_cast<unsigned int>(mScene->mCameras.size());
|
||||
pcOut->mNumCameras = (unsigned int)mScene->mCameras.size();
|
||||
if (pcOut->mNumCameras) {
|
||||
pcOut->mCameras = new aiCamera *[pcOut->mNumCameras];
|
||||
memcpy(pcOut->mCameras, &mScene->mCameras[0], sizeof(void *) * pcOut->mNumCameras);
|
||||
::memcpy(pcOut->mCameras, &mScene->mCameras[0], sizeof(void *) * pcOut->mNumCameras);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -106,7 +106,7 @@ Discreet3DSImporter::Discreet3DSImporter() :
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns whether the class can handle the format of the given file.
|
||||
bool Discreet3DSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
||||
static constexpr uint16_t token[] = { 0x4d4d, 0x3dc2 /*, 0x3daa */ };
|
||||
static const uint16_t token[] = { 0x4d4d, 0x3dc2 /*, 0x3daa */ };
|
||||
return CheckMagicToken(pIOHandler, pFile, token, AI_COUNT_OF(token), 0, sizeof token[0]);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
@@ -55,7 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
struct aiNode;
|
||||
|
||||
namespace Assimp {
|
||||
namespace Assimp {
|
||||
|
||||
using namespace D3DS;
|
||||
|
||||
@@ -124,6 +125,7 @@ protected:
|
||||
void ParseColorChunk(aiColor3D* p_pcOut,
|
||||
bool p_bAcceptPercent = true);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Skip a chunk in the file
|
||||
*/
|
||||
|
||||
@@ -85,7 +85,7 @@ bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bo
|
||||
if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) {
|
||||
return false;
|
||||
}
|
||||
static constexpr char ModelRef[] = "3D/3dmodel.model";
|
||||
static const char *const ModelRef = "3D/3dmodel.model";
|
||||
ZipArchiveIOSystem archive(pIOHandler, filename);
|
||||
if (!archive.Exists(ModelRef)) {
|
||||
return false;
|
||||
|
||||
@@ -147,7 +147,7 @@ AC3DImporter::AC3DImporter() :
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns whether the class can handle the format of the given file.
|
||||
bool AC3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
||||
static constexpr uint32_t tokens[] = { AI_MAKE_MAGIC("AC3D") };
|
||||
static const uint32_t tokens[] = { AI_MAKE_MAGIC("AC3D") };
|
||||
return CheckMagicToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
AMFNodeElementBase *Parent; ///< Parent element. If nullptr then this node is root.
|
||||
std::list<AMFNodeElementBase *> Child; ///< Child elements.
|
||||
|
||||
public:
|
||||
public:
|
||||
/// Destructor, virtual..
|
||||
virtual ~AMFNodeElementBase() = default;
|
||||
|
||||
|
||||
@@ -731,10 +731,6 @@ void ASEImporter::BuildUniqueRepresentation(ASE::Mesh &mesh) {
|
||||
unsigned int iCurrent = 0, fi = 0;
|
||||
for (std::vector<ASE::Face>::iterator i = mesh.mFaces.begin(); i != mesh.mFaces.end(); ++i, ++fi) {
|
||||
for (unsigned int n = 0; n < 3; ++n, ++iCurrent) {
|
||||
const uint32_t curIndex = (*i).mIndices[n];
|
||||
if (curIndex >= mesh.mPositions.size()) {
|
||||
throw DeadlyImportError("ASE: Invalid vertex index in face ", fi, ".");
|
||||
}
|
||||
mPositions[iCurrent] = mesh.mPositions[(*i).mIndices[n]];
|
||||
|
||||
// add texture coordinates
|
||||
|
||||
@@ -1406,13 +1406,10 @@ void Parser::ParseLV4MeshBonesVertices(unsigned int iNumVertices, ASE::Mesh &mes
|
||||
if (TokenMatch(mFilePtr, "MESH_BONE_VERTEX", 16)) {
|
||||
// read the vertex index
|
||||
unsigned int iIndex = strtoul10(mFilePtr, &mFilePtr);
|
||||
if (mesh.mBoneVertices.empty()) {
|
||||
SkipSection();
|
||||
}
|
||||
if (iIndex >= mesh.mBoneVertices.size() ) {
|
||||
if (iIndex >= mesh.mPositions.size()) {
|
||||
iIndex = (unsigned int)mesh.mPositions.size() - 1;
|
||||
LogWarning("Bone vertex index is out of bounds. Using the largest valid "
|
||||
"bone vertex index instead");
|
||||
iIndex = (unsigned int)mesh.mBoneVertices.size() - 1;
|
||||
}
|
||||
|
||||
// --- ignored
|
||||
|
||||
@@ -48,7 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
|
||||
|
||||
// internal headers
|
||||
#include "AssbinLoader.h"
|
||||
#include "AssetLib/Assbin/AssbinLoader.h"
|
||||
#include "Common/assbin_chunks.h"
|
||||
#include <assimp/MemoryIOWrapper.h>
|
||||
#include <assimp/anim.h>
|
||||
@@ -94,7 +94,7 @@ bool AssbinImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, boo
|
||||
const size_t read = in->Read(s, sizeof(char), 32);
|
||||
|
||||
pIOHandler->Close(in);
|
||||
|
||||
|
||||
if (read < 19) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
@@ -60,7 +61,7 @@ struct aiCamera;
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
|
||||
|
||||
namespace Assimp {
|
||||
namespace Assimp {
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
/** Importer class for 3D Studio r3 and r4 3DS files
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
@@ -49,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <assimp/IOSystem.hpp>
|
||||
#include <assimp/Exporter.hpp>
|
||||
|
||||
namespace Assimp {
|
||||
namespace Assimp {
|
||||
|
||||
void ExportSceneAssxml(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#ifndef ASSIMP_BUILD_NO_B3D_IMPORTER
|
||||
|
||||
// internal headers
|
||||
#include "B3DImporter.h"
|
||||
#include "AssetLib/B3D/B3DImporter.h"
|
||||
#include "PostProcessing/ConvertToLHProcess.h"
|
||||
#include "PostProcessing/TextureTransform.h"
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -116,7 +116,7 @@ namespace Blender {
|
||||
mywrap arr;
|
||||
};
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(disable:4351)
|
||||
#endif
|
||||
|
||||
@@ -171,7 +171,7 @@ namespace Blender {
|
||||
// original file data
|
||||
const FileDatabase& db;
|
||||
};
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(default:4351)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ BlenderImporter::~BlenderImporter() {
|
||||
delete modifier_cache;
|
||||
}
|
||||
|
||||
static constexpr char Token[] = "BLENDER";
|
||||
static const char Token[] = "BLENDER";
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns whether the class can handle the format of the given file.
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "BlenderDNA.h"
|
||||
#include "BlenderScene.h"
|
||||
|
||||
namespace Assimp {
|
||||
namespace Assimp {
|
||||
namespace Blender {
|
||||
|
||||
template <> void Structure :: Convert<Object> (
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace {
|
||||
|
||||
aiString aiStringFrom(cineware::String const & cinestring) {
|
||||
aiString result;
|
||||
cinestring.GetCString(result.data, AI_MAXLEN - 1);
|
||||
cinestring.GetCString(result.data, MAXLEN-1);
|
||||
result.length = static_cast<ai_uint32>(cinestring.GetLength());
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace cineware {
|
||||
class BaseShader;
|
||||
}
|
||||
|
||||
namespace Assimp {
|
||||
namespace Assimp {
|
||||
// TinyFormatter.h
|
||||
namespace Formatter {
|
||||
template <typename T,typename TR, typename A> class basic_formatter;
|
||||
|
||||
@@ -45,8 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_COB_IMPORTER
|
||||
|
||||
#include "COBLoader.h"
|
||||
#include "COBScene.h"
|
||||
#include "AssetLib/COB/COBLoader.h"
|
||||
#include "AssetLib/COB/COBScene.h"
|
||||
#include "PostProcessing/ConvertToLHProcess.h"
|
||||
|
||||
#include <assimp/LineSplitter.h>
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -118,11 +118,10 @@ void CSMImporter::InternReadFile( const std::string& pFile,
|
||||
// now process the file and look out for '$' sections
|
||||
while (true) {
|
||||
SkipSpaces(&buffer, end);
|
||||
if ('\0' == *buffer) {
|
||||
if ('\0' == *buffer)
|
||||
break;
|
||||
}
|
||||
|
||||
if ('$' == *buffer) {
|
||||
if ('$' == *buffer) {
|
||||
++buffer;
|
||||
if (TokenMatchI(buffer,"firstframe",10)) {
|
||||
SkipSpaces(&buffer, end);
|
||||
@@ -150,9 +149,8 @@ void CSMImporter::InternReadFile( const std::string& pFile,
|
||||
anims_temp.push_back(new aiNodeAnim());
|
||||
aiNodeAnim* nda = anims_temp.back();
|
||||
|
||||
char *ot = nda->mNodeName.data;
|
||||
const char *ot_end = nda->mNodeName.data + AI_MAXLEN;
|
||||
while (!IsSpaceOrNewLine(*buffer) && buffer != end && ot != ot_end) {
|
||||
char* ot = nda->mNodeName.data;
|
||||
while (!IsSpaceOrNewLine(*buffer)) {
|
||||
*ot++ = *buffer++;
|
||||
}
|
||||
|
||||
|
||||
@@ -1116,9 +1116,9 @@ void ColladaExporter::WriteGeometry(size_t pIndex) {
|
||||
}
|
||||
for (size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
|
||||
if (mesh->HasTextureCoords(static_cast<unsigned int>(a))) {
|
||||
mOutput << startstr
|
||||
<< "<input semantic=\"TEXCOORD\" source=\"#"
|
||||
<< geometryId
|
||||
mOutput << startstr
|
||||
<< "<input semantic=\"TEXCOORD\" source=\"#"
|
||||
<< geometryId
|
||||
<< "-tex" << a << "\" "
|
||||
<< "set=\"" << a << "\""
|
||||
<< " />" << endstr;
|
||||
@@ -1199,26 +1199,26 @@ void ColladaExporter::WriteGeometry(size_t pIndex) {
|
||||
void ColladaExporter::WriteFloatArray(const std::string &pIdString, FloatDataType pType, const ai_real *pData, size_t pElementCount) {
|
||||
size_t floatsPerElement = 0;
|
||||
switch (pType) {
|
||||
case FloatType_Vector:
|
||||
floatsPerElement = 3;
|
||||
case FloatType_Vector:
|
||||
floatsPerElement = 3;
|
||||
break;
|
||||
case FloatType_TexCoord2:
|
||||
floatsPerElement = 2;
|
||||
case FloatType_TexCoord2:
|
||||
floatsPerElement = 2;
|
||||
break;
|
||||
case FloatType_TexCoord3:
|
||||
floatsPerElement = 3;
|
||||
case FloatType_TexCoord3:
|
||||
floatsPerElement = 3;
|
||||
break;
|
||||
case FloatType_Color:
|
||||
floatsPerElement = 3;
|
||||
case FloatType_Color:
|
||||
floatsPerElement = 3;
|
||||
break;
|
||||
case FloatType_Mat4x4:
|
||||
floatsPerElement = 16;
|
||||
case FloatType_Mat4x4:
|
||||
floatsPerElement = 16;
|
||||
break;
|
||||
case FloatType_Weight:
|
||||
floatsPerElement = 1;
|
||||
case FloatType_Weight:
|
||||
floatsPerElement = 1;
|
||||
break;
|
||||
case FloatType_Time:
|
||||
floatsPerElement = 1;
|
||||
case FloatType_Time:
|
||||
floatsPerElement = 1;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
@@ -1342,7 +1342,7 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex) {
|
||||
if (anim == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (anim->mNumChannels == 0 && anim->mNumMeshChannels == 0 && anim->mNumMorphMeshChannels == 0) {
|
||||
return;
|
||||
}
|
||||
@@ -1486,12 +1486,12 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex) {
|
||||
|
||||
{
|
||||
// channels
|
||||
mOutput << startstr
|
||||
<< "<channel source=\"#"
|
||||
<< XMLIDEncode(nodeAnim->mNodeName.data + std::string("_matrix-sampler"))
|
||||
<< "\" target=\""
|
||||
<< XMLIDEncode(nodeAnim->mNodeName.data)
|
||||
<< "/matrix\"/>"
|
||||
mOutput << startstr
|
||||
<< "<channel source=\"#"
|
||||
<< XMLIDEncode(nodeAnim->mNodeName.data + std::string("_matrix-sampler"))
|
||||
<< "\" target=\""
|
||||
<< XMLIDEncode(nodeAnim->mNodeName.data)
|
||||
<< "/matrix\"/>"
|
||||
<< endstr;
|
||||
}
|
||||
}
|
||||
@@ -1505,7 +1505,7 @@ void ColladaExporter::WriteAnimationsLibrary() {
|
||||
if (mScene->mNumAnimations == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
mOutput << startstr << "<library_animations>" << endstr;
|
||||
PushTag();
|
||||
|
||||
@@ -1688,7 +1688,7 @@ std::string ColladaExporter::GetNodeUniqueId(const aiNode *node) {
|
||||
idStr = MakeUniqueId(mUniqueIds, idStr, std::string());
|
||||
mUniqueIds.insert(idStr);
|
||||
mNodeIdMap.insert(std::make_pair(node, idStr));
|
||||
|
||||
|
||||
return idStr;
|
||||
}
|
||||
|
||||
@@ -1744,14 +1744,14 @@ ColladaExporter::NameIdPair ColladaExporter::AddObjectIndexToMaps(AiObjectType t
|
||||
|
||||
// Get the name and id postfix
|
||||
switch (type) {
|
||||
case AiObjectType::Mesh:
|
||||
name = mScene->mMeshes[index]->mName.C_Str();
|
||||
case AiObjectType::Mesh:
|
||||
name = mScene->mMeshes[index]->mName.C_Str();
|
||||
break;
|
||||
case AiObjectType::Material:
|
||||
name = mScene->mMaterials[index]->GetName().C_Str();
|
||||
case AiObjectType::Material:
|
||||
name = mScene->mMaterials[index]->GetName().C_Str();
|
||||
break;
|
||||
case AiObjectType::Animation:
|
||||
name = mScene->mAnimations[index]->mName.C_Str();
|
||||
case AiObjectType::Animation:
|
||||
name = mScene->mAnimations[index]->mName.C_Str();
|
||||
break;
|
||||
case AiObjectType::Light:
|
||||
name = mScene->mLights[index]->mName.C_Str();
|
||||
@@ -1761,7 +1761,7 @@ ColladaExporter::NameIdPair ColladaExporter::AddObjectIndexToMaps(AiObjectType t
|
||||
name = mScene->mCameras[index]->mName.C_Str();
|
||||
idPostfix = "-camera";
|
||||
break;
|
||||
case AiObjectType::Count:
|
||||
case AiObjectType::Count:
|
||||
throw std::logic_error("ColladaExporter::AiObjectType::Count is not an object type");
|
||||
}
|
||||
|
||||
|
||||
@@ -89,14 +89,6 @@ inline void AddNodeMetaData(aiNode *node, const std::string &key, const T &value
|
||||
node->mMetaData->Add(key, value);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads a float value from an accessor and its data array.
|
||||
static ai_real ReadFloat(const Accessor &pAccessor, const Data &pData, size_t pIndex, size_t pOffset) {
|
||||
size_t pos = pAccessor.mStride * pIndex + pAccessor.mOffset + pOffset;
|
||||
ai_assert(pos < pData.mValues.size());
|
||||
return pData.mValues[pos];
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor to be privately used by Importer
|
||||
ColladaLoader::ColladaLoader() :
|
||||
@@ -160,7 +152,7 @@ void ColladaLoader::InternReadFile(const std::string &pFile, aiScene *pScene, IO
|
||||
throw DeadlyImportError("Collada: File came out empty. Something is wrong here.");
|
||||
}
|
||||
|
||||
// reserve some storage to avoid unnecessary reallocates
|
||||
// reserve some storage to avoid unnecessary reallocs
|
||||
newMats.reserve(parser.mMaterialLibrary.size() * 2u);
|
||||
mMeshes.reserve(parser.mMeshLibrary.size() * 2u);
|
||||
|
||||
@@ -184,7 +176,7 @@ void ColladaLoader::InternReadFile(const std::string &pFile, aiScene *pScene, IO
|
||||
0, 0, parser.mUnitSize, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
if (!ignoreUpDirection) {
|
||||
// Convert to Y_UP, if different orientation
|
||||
if (parser.mUpDirection == ColladaParser::UP_X) {
|
||||
@@ -232,7 +224,7 @@ void ColladaLoader::InternReadFile(const std::string &pFile, aiScene *pScene, IO
|
||||
// Recursively constructs a scene node for the given parser node and returns it.
|
||||
aiNode *ColladaLoader::BuildHierarchy(const ColladaParser &pParser, const Collada::Node *pNode) {
|
||||
// create a node for it
|
||||
auto *node = new aiNode();
|
||||
aiNode *node = new aiNode();
|
||||
|
||||
// find a name for the new node. It's more complicated than you might think
|
||||
node->mName.Set(FindNameForNode(pNode));
|
||||
@@ -280,24 +272,24 @@ aiNode *ColladaLoader::BuildHierarchy(const ColladaParser &pParser, const Collad
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Resolve node instances
|
||||
void ColladaLoader::ResolveNodeInstances(const ColladaParser &pParser, const Node *pNode,
|
||||
std::vector<const Node*> &resolved) const {
|
||||
std::vector<const Node*> &resolved) {
|
||||
// reserve enough storage
|
||||
resolved.reserve(pNode->mNodeInstances.size());
|
||||
|
||||
// ... and iterate through all nodes to be instanced as children of pNode
|
||||
for (const auto &[mNode] : pNode->mNodeInstances) {
|
||||
for (const auto &nodeInst : pNode->mNodeInstances) {
|
||||
// find the corresponding node in the library
|
||||
const auto itt = pParser.mNodeLibrary.find(mNode);
|
||||
const ColladaParser::NodeLibrary::const_iterator itt = pParser.mNodeLibrary.find(nodeInst.mNode);
|
||||
const Node *nd = itt == pParser.mNodeLibrary.end() ? nullptr : (*itt).second;
|
||||
|
||||
// FIX for http://sourceforge.net/tracker/?func=detail&aid=3054873&group_id=226462&atid=1067632
|
||||
// need to check for both name and ID to catch all. To avoid breaking valid files,
|
||||
// the workaround is only enabled when the first attempt to resolve the node has failed.
|
||||
if (nullptr == nd) {
|
||||
nd = FindNode(pParser.mRootNode, mNode);
|
||||
nd = FindNode(pParser.mRootNode, nodeInst.mNode);
|
||||
}
|
||||
if (nullptr == nd) {
|
||||
ASSIMP_LOG_ERROR("Collada: Unable to resolve reference to instanced node ", mNode);
|
||||
ASSIMP_LOG_ERROR("Collada: Unable to resolve reference to instanced node ", nodeInst.mNode);
|
||||
} else {
|
||||
// attach this node to the list of children
|
||||
resolved.push_back(nd);
|
||||
@@ -307,8 +299,8 @@ void ColladaLoader::ResolveNodeInstances(const ColladaParser &pParser, const Nod
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Resolve UV channels
|
||||
static void ApplyVertexToEffectSemanticMapping(Sampler &sampler, const SemanticMappingTable &table) {
|
||||
const auto it = table.mMap.find(sampler.mUVChannel);
|
||||
void ColladaLoader::ApplyVertexToEffectSemanticMapping(Sampler &sampler, const SemanticMappingTable &table) {
|
||||
SemanticMappingTable::InputSemanticMap::const_iterator it = table.mMap.find(sampler.mUVChannel);
|
||||
if (it == table.mMap.end()) {
|
||||
return;
|
||||
}
|
||||
@@ -325,7 +317,7 @@ static void ApplyVertexToEffectSemanticMapping(Sampler &sampler, const SemanticM
|
||||
void ColladaLoader::BuildLightsForNode(const ColladaParser &pParser, const Node *pNode, aiNode *pTarget) {
|
||||
for (const LightInstance &lid : pNode->mLights) {
|
||||
// find the referred light
|
||||
auto srcLightIt = pParser.mLightLibrary.find(lid.mLight);
|
||||
ColladaParser::LightLibrary::const_iterator srcLightIt = pParser.mLightLibrary.find(lid.mLight);
|
||||
if (srcLightIt == pParser.mLightLibrary.end()) {
|
||||
ASSIMP_LOG_WARN("Collada: Unable to find light for ID \"", lid.mLight, "\". Skipping.");
|
||||
continue;
|
||||
@@ -333,7 +325,7 @@ void ColladaLoader::BuildLightsForNode(const ColladaParser &pParser, const Node
|
||||
const Collada::Light *srcLight = &srcLightIt->second;
|
||||
|
||||
// now fill our ai data structure
|
||||
auto out = new aiLight();
|
||||
aiLight *out = new aiLight();
|
||||
out->mName = pTarget->mName;
|
||||
out->mType = (aiLightSourceType)srcLight->mType;
|
||||
|
||||
@@ -390,7 +382,7 @@ void ColladaLoader::BuildLightsForNode(const ColladaParser &pParser, const Node
|
||||
void ColladaLoader::BuildCamerasForNode(const ColladaParser &pParser, const Node *pNode, aiNode *pTarget) {
|
||||
for (const CameraInstance &cid : pNode->mCameras) {
|
||||
// find the referred light
|
||||
auto srcCameraIt = pParser.mCameraLibrary.find(cid.mCamera);
|
||||
ColladaParser::CameraLibrary::const_iterator srcCameraIt = pParser.mCameraLibrary.find(cid.mCamera);
|
||||
if (srcCameraIt == pParser.mCameraLibrary.end()) {
|
||||
ASSIMP_LOG_WARN("Collada: Unable to find camera for ID \"", cid.mCamera, "\". Skipping.");
|
||||
continue;
|
||||
@@ -403,7 +395,7 @@ void ColladaLoader::BuildCamerasForNode(const ColladaParser &pParser, const Node
|
||||
}
|
||||
|
||||
// now fill our ai data structure
|
||||
auto *out = new aiCamera();
|
||||
aiCamera *out = new aiCamera();
|
||||
out->mName = pTarget->mName;
|
||||
|
||||
// collada cameras point in -Z by default, rest is specified in node transform
|
||||
@@ -453,10 +445,10 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
|
||||
const Controller *srcController = nullptr;
|
||||
|
||||
// find the referred mesh
|
||||
auto srcMeshIt = pParser.mMeshLibrary.find(mid.mMeshOrController);
|
||||
ColladaParser::MeshLibrary::const_iterator srcMeshIt = pParser.mMeshLibrary.find(mid.mMeshOrController);
|
||||
if (srcMeshIt == pParser.mMeshLibrary.end()) {
|
||||
// if not found in the mesh-library, it might also be a controller referring to a mesh
|
||||
auto srcContrIt = pParser.mControllerLibrary.find(mid.mMeshOrController);
|
||||
ColladaParser::ControllerLibrary::const_iterator srcContrIt = pParser.mControllerLibrary.find(mid.mMeshOrController);
|
||||
if (srcContrIt != pParser.mControllerLibrary.end()) {
|
||||
srcController = &srcContrIt->second;
|
||||
srcMeshIt = pParser.mMeshLibrary.find(srcController->mMeshId);
|
||||
@@ -470,7 +462,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// ID found in the mesh library -> direct reference to a not skinned mesh
|
||||
// ID found in the mesh library -> direct reference to an unskinned mesh
|
||||
srcMesh = srcMeshIt->second;
|
||||
}
|
||||
|
||||
@@ -484,7 +476,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
|
||||
|
||||
// find material assigned to this submesh
|
||||
std::string meshMaterial;
|
||||
auto meshMatIt = mid.mMaterials.find(submesh.mMaterial);
|
||||
std::map<std::string, SemanticMappingTable>::const_iterator meshMatIt = mid.mMaterials.find(submesh.mMaterial);
|
||||
|
||||
const Collada::SemanticMappingTable *table = nullptr;
|
||||
if (meshMatIt != mid.mMaterials.end()) {
|
||||
@@ -500,7 +492,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
|
||||
|
||||
// OK ... here the *real* fun starts ... we have the vertex-input-to-effect-semantic-table
|
||||
// given. The only mapping stuff which we do actually support is the UV channel.
|
||||
auto matIt = mMaterialIndexByName.find(meshMaterial);
|
||||
std::map<std::string, size_t>::const_iterator matIt = mMaterialIndexByName.find(meshMaterial);
|
||||
unsigned int matIdx = 0;
|
||||
if (matIt != mMaterialIndexByName.end()) {
|
||||
matIdx = static_cast<unsigned int>(matIt->second);
|
||||
@@ -523,7 +515,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
|
||||
ColladaMeshIndex index(mid.mMeshOrController, sm, meshMaterial);
|
||||
|
||||
// if we already have the mesh at the library, just add its index to the node's array
|
||||
auto dstMeshIt = mMeshIndexByID.find(index);
|
||||
std::map<ColladaMeshIndex, size_t>::const_iterator dstMeshIt = mMeshIndexByID.find(index);
|
||||
if (dstMeshIt != mMeshIndexByID.end()) {
|
||||
newMeshRefs.push_back(dstMeshIt->second);
|
||||
} else {
|
||||
@@ -538,7 +530,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
|
||||
faceStart += submesh.mNumFaces;
|
||||
|
||||
// assign the material index
|
||||
auto subMatIt = mMaterialIndexByName.find(submesh.mMaterial);
|
||||
std::map<std::string, size_t>::const_iterator subMatIt = mMaterialIndexByName.find(submesh.mMaterial);
|
||||
if (subMatIt != mMaterialIndexByName.end()) {
|
||||
dstMesh->mMaterialIndex = static_cast<unsigned int>(subMatIt->second);
|
||||
} else {
|
||||
@@ -626,7 +618,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
|
||||
std::copy(pSrcMesh->mTangents.begin() + pStartVertex, pSrcMesh->mTangents.begin() + pStartVertex + numVertices, dstMesh->mTangents);
|
||||
}
|
||||
|
||||
// bi-tangents, if given.
|
||||
// bitangents, if given.
|
||||
if (pSrcMesh->mBitangents.size() >= pStartVertex + numVertices) {
|
||||
dstMesh->mBitangents = new aiVector3D[numVertices];
|
||||
std::copy(pSrcMesh->mBitangents.begin() + pStartVertex, pSrcMesh->mBitangents.begin() + pStartVertex + numVertices, dstMesh->mBitangents);
|
||||
@@ -672,7 +664,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
|
||||
std::vector<float> targetWeights;
|
||||
Collada::MorphMethod method = Normalized;
|
||||
|
||||
for (auto it = pParser.mControllerLibrary.begin();
|
||||
for (std::map<std::string, Controller>::const_iterator it = pParser.mControllerLibrary.begin();
|
||||
it != pParser.mControllerLibrary.end(); ++it) {
|
||||
const Controller &c = it->second;
|
||||
const Collada::Mesh *baseMesh = pParser.ResolveLibraryReference(pParser.mMeshLibrary, c.mMeshId);
|
||||
@@ -762,7 +754,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
|
||||
std::vector<IndexPairVector::const_iterator> weightStartPerVertex;
|
||||
weightStartPerVertex.resize(pSrcController->mWeightCounts.size(), pSrcController->mWeights.end());
|
||||
|
||||
auto pit = pSrcController->mWeights.begin();
|
||||
IndexPairVector::const_iterator pit = pSrcController->mWeights.begin();
|
||||
for (size_t a = 0; a < pSrcController->mWeightCounts.size(); ++a) {
|
||||
weightStartPerVertex[a] = pit;
|
||||
pit += pSrcController->mWeightCounts[a];
|
||||
@@ -774,7 +766,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
|
||||
// the controller assigns the vertex weights
|
||||
size_t orgIndex = pSrcMesh->mFacePosIndices[a];
|
||||
// find the vertex weights for this vertex
|
||||
auto iit = weightStartPerVertex[orgIndex];
|
||||
IndexPairVector::const_iterator iit = weightStartPerVertex[orgIndex];
|
||||
size_t pairCount = pSrcController->mWeightCounts[orgIndex];
|
||||
|
||||
for (size_t b = 0; b < pairCount; ++b, ++iit) {
|
||||
@@ -815,7 +807,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
|
||||
}
|
||||
|
||||
// create bone with its weights
|
||||
auto bone = new aiBone;
|
||||
aiBone *bone = new aiBone;
|
||||
bone->mName = ReadString(jointNamesAcc, jointNames, a);
|
||||
bone->mOffsetMatrix.a1 = ReadFloat(jointMatrixAcc, jointMatrices, a, 0);
|
||||
bone->mOffsetMatrix.a2 = ReadFloat(jointMatrixAcc, jointMatrices, a, 1);
|
||||
@@ -981,7 +973,7 @@ void ColladaLoader::StoreAnimations(aiScene *pScene, const ColladaParser &pParse
|
||||
|
||||
// if there are other animations which fit the template anim, combine all channels into a single anim
|
||||
if (!collectedAnimIndices.empty()) {
|
||||
auto *combinedAnim = new aiAnimation();
|
||||
aiAnimation *combinedAnim = new aiAnimation();
|
||||
combinedAnim->mName = aiString(std::string("combinedAnim_") + char('0' + a));
|
||||
combinedAnim->mDuration = templateAnim->mDuration;
|
||||
combinedAnim->mTicksPerSecond = templateAnim->mTicksPerSecond;
|
||||
@@ -1048,7 +1040,7 @@ struct MorphTimeValues {
|
||||
};
|
||||
|
||||
void insertMorphTimeValue(std::vector<MorphTimeValues> &values, float time, float weight, unsigned int value) {
|
||||
MorphTimeValues::key k{};
|
||||
MorphTimeValues::key k;
|
||||
k.mValue = value;
|
||||
k.mWeight = weight;
|
||||
if (values.empty() || time < values[0].mTime) {
|
||||
@@ -1085,7 +1077,7 @@ static float getWeightAtKey(const std::vector<MorphTimeValues> &values, int key,
|
||||
return mKey.mWeight;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// no value at key found, try to interpolate if present at other keys. if not, return zero
|
||||
// TODO: interpolation
|
||||
return 0.0f;
|
||||
@@ -1114,7 +1106,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
|
||||
|
||||
// now check all channels if they affect the current node
|
||||
std::string targetID, subElement;
|
||||
for (auto cit = pSrcAnim->mChannels.begin();
|
||||
for (std::vector<AnimationChannel>::const_iterator cit = pSrcAnim->mChannels.begin();
|
||||
cit != pSrcAnim->mChannels.end(); ++cit) {
|
||||
const AnimationChannel &srcChannel = *cit;
|
||||
ChannelEntry entry;
|
||||
@@ -1357,7 +1349,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
|
||||
|
||||
// build an animation channel for the given node out of these trafo keys
|
||||
if (!resultTrafos.empty()) {
|
||||
auto *dstAnim = new aiNodeAnim;
|
||||
aiNodeAnim *dstAnim = new aiNodeAnim;
|
||||
dstAnim->mNodeName = nodeName;
|
||||
dstAnim->mNumPositionKeys = static_cast<unsigned int>(resultTrafos.size());
|
||||
dstAnim->mNumRotationKeys = static_cast<unsigned int>(resultTrafos.size());
|
||||
@@ -1399,7 +1391,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
|
||||
// or 2) one channel with morph target count arrays
|
||||
// assume first
|
||||
|
||||
auto *morphAnim = new aiMeshMorphAnim;
|
||||
aiMeshMorphAnim *morphAnim = new aiMeshMorphAnim;
|
||||
morphAnim->mName.Set(nodeName);
|
||||
|
||||
std::vector<MorphTimeValues> morphTimeValues;
|
||||
@@ -1442,7 +1434,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
|
||||
}
|
||||
|
||||
if (!anims.empty() || !morphAnims.empty()) {
|
||||
auto anim = new aiAnimation;
|
||||
aiAnimation *anim = new aiAnimation;
|
||||
anim->mName.Set(pName);
|
||||
anim->mNumChannels = static_cast<unsigned int>(anims.size());
|
||||
if (anim->mNumChannels > 0) {
|
||||
@@ -1522,7 +1514,7 @@ void ColladaLoader::AddTexture(aiMaterial &mat,
|
||||
map = sampler.mUVId;
|
||||
} else {
|
||||
map = -1;
|
||||
for (auto it = sampler.mUVChannel.begin(); it != sampler.mUVChannel.end(); ++it) {
|
||||
for (std::string::const_iterator it = sampler.mUVChannel.begin(); it != sampler.mUVChannel.end(); ++it) {
|
||||
if (IsNumeric(*it)) {
|
||||
map = strtoul10(&(*it));
|
||||
break;
|
||||
@@ -1540,7 +1532,7 @@ void ColladaLoader::AddTexture(aiMaterial &mat,
|
||||
// Fills materials from the collada material definitions
|
||||
void ColladaLoader::FillMaterials(const ColladaParser &pParser, aiScene * /*pScene*/) {
|
||||
for (auto &elem : newMats) {
|
||||
auto &mat = (aiMaterial &)*elem.second;
|
||||
aiMaterial &mat = (aiMaterial &)*elem.second;
|
||||
Collada::Effect &effect = *elem.first;
|
||||
|
||||
// resolve shading mode
|
||||
@@ -1650,17 +1642,17 @@ void ColladaLoader::FillMaterials(const ColladaParser &pParser, aiScene * /*pSce
|
||||
void ColladaLoader::BuildMaterials(ColladaParser &pParser, aiScene * /*pScene*/) {
|
||||
newMats.reserve(pParser.mMaterialLibrary.size());
|
||||
|
||||
for (auto matIt = pParser.mMaterialLibrary.begin();
|
||||
for (ColladaParser::MaterialLibrary::const_iterator matIt = pParser.mMaterialLibrary.begin();
|
||||
matIt != pParser.mMaterialLibrary.end(); ++matIt) {
|
||||
const Material &material = matIt->second;
|
||||
// a material is only a reference to an effect
|
||||
auto effIt = pParser.mEffectLibrary.find(material.mEffect);
|
||||
ColladaParser::EffectLibrary::iterator effIt = pParser.mEffectLibrary.find(material.mEffect);
|
||||
if (effIt == pParser.mEffectLibrary.end())
|
||||
continue;
|
||||
Effect &effect = effIt->second;
|
||||
|
||||
// create material
|
||||
auto *mat = new aiMaterial;
|
||||
aiMaterial *mat = new aiMaterial;
|
||||
aiString name(material.mName.empty() ? matIt->first : material.mName);
|
||||
mat->AddProperty(&name, AI_MATKEY_NAME);
|
||||
|
||||
@@ -1683,7 +1675,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser &pParse
|
||||
std::string name = pName;
|
||||
while (true) {
|
||||
// the given string is a param entry. Find it
|
||||
auto it = pEffect.mParams.find(name);
|
||||
Effect::ParamLibrary::const_iterator it = pEffect.mParams.find(name);
|
||||
// if not found, we're at the end of the recursion. The resulting string should be the image ID
|
||||
if (it == pEffect.mParams.end())
|
||||
break;
|
||||
@@ -1693,7 +1685,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser &pParse
|
||||
}
|
||||
|
||||
// find the image referred by this name in the image library of the scene
|
||||
auto imIt = pParser.mImageLibrary.find(name);
|
||||
ColladaParser::ImageLibrary::const_iterator imIt = pParser.mImageLibrary.find(name);
|
||||
if (imIt == pParser.mImageLibrary.end()) {
|
||||
ASSIMP_LOG_WARN("Collada: Unable to resolve effect texture entry \"", pName, "\", ended up at ID \"", name, "\".");
|
||||
|
||||
@@ -1705,7 +1697,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser &pParse
|
||||
|
||||
// if this is an embedded texture image setup an aiTexture for it
|
||||
if (!imIt->second.mImageData.empty()) {
|
||||
auto *tex = new aiTexture();
|
||||
aiTexture *tex = new aiTexture();
|
||||
|
||||
// Store embedded texture name reference
|
||||
tex->mFilename.Set(imIt->second.mFileName.c_str());
|
||||
@@ -1737,6 +1729,14 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser &pParse
|
||||
return result;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads a float value from an accessor and its data array.
|
||||
ai_real ColladaLoader::ReadFloat(const Accessor &pAccessor, const Data &pData, size_t pIndex, size_t pOffset) const {
|
||||
size_t pos = pAccessor.mStride * pIndex + pAccessor.mOffset + pOffset;
|
||||
ai_assert(pos < pData.mValues.size());
|
||||
return pData.mValues[pos];
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads a string value from an accessor and its data array.
|
||||
const std::string &ColladaLoader::ReadString(const Accessor &pAccessor, const Data &pData, size_t pIndex) const {
|
||||
|
||||
@@ -76,10 +76,10 @@ struct ColladaMeshIndex {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Loader class to read Collada scenes.
|
||||
/**
|
||||
* @brief Loader class to read Collada scenes.
|
||||
*
|
||||
* Collada is over-engineered to death, with every new iteration bringing more useless stuff,
|
||||
* Collada is over-engineered to death, with every new iteration bringing more useless stuff,
|
||||
* so I limited the data to what I think is useful for games.
|
||||
*/
|
||||
class ColladaLoader : public BaseImporter {
|
||||
@@ -109,9 +109,9 @@ protected:
|
||||
|
||||
/// Resolve node instances
|
||||
void ResolveNodeInstances(const ColladaParser &pParser, const Collada::Node *pNode,
|
||||
std::vector<const Collada::Node *> &resolved) const;
|
||||
std::vector<const Collada::Node *> &resolved);
|
||||
|
||||
/// Builds meshes for the given node and references them
|
||||
/// Builds meshes for the given node and references them
|
||||
void BuildMeshesForNode(const ColladaParser &pParser, const Collada::Node *pNode,
|
||||
aiNode *pTarget);
|
||||
|
||||
@@ -166,6 +166,10 @@ protected:
|
||||
/** Fill materials from the collada material definitions */
|
||||
void FillMaterials(const ColladaParser &pParser, aiScene *pScene);
|
||||
|
||||
/** Resolve UV channel mappings*/
|
||||
void ApplyVertexToEffectSemanticMapping(Collada::Sampler &sampler,
|
||||
const Collada::SemanticMappingTable &table);
|
||||
|
||||
/** Add a texture and all of its sampling properties to a material*/
|
||||
void AddTexture(aiMaterial &mat, const ColladaParser &pParser,
|
||||
const Collada::Effect &effect,
|
||||
@@ -176,13 +180,22 @@ protected:
|
||||
aiString FindFilenameForEffectTexture(const ColladaParser &pParser,
|
||||
const Collada::Effect &pEffect, const std::string &pName);
|
||||
|
||||
/** Reads a float value from an accessor and its data array.
|
||||
* @param pAccessor The accessor to use for reading
|
||||
* @param pData The data array to read from
|
||||
* @param pIndex The index of the element to retrieve
|
||||
* @param pOffset Offset into the element, for multipart elements such as vectors or matrices
|
||||
* @return the specified value
|
||||
*/
|
||||
ai_real ReadFloat(const Collada::Accessor &pAccessor, const Collada::Data &pData, size_t pIndex, size_t pOffset) const;
|
||||
|
||||
/** Reads a string value from an accessor and its data array.
|
||||
* @param pAccessor The accessor to use for reading
|
||||
* @param pData The data array to read from
|
||||
* @param pIndex The index of the element to retrieve
|
||||
* @return the specified value
|
||||
*/
|
||||
[[nodiscard]] const std::string &ReadString(const Collada::Accessor &pAccessor, const Collada::Data &pData, size_t pIndex) const;
|
||||
const std::string &ReadString(const Collada::Accessor &pAccessor, const Collada::Data &pData, size_t pIndex) const;
|
||||
|
||||
/** Recursively collects all nodes into the given array */
|
||||
void CollectNodes(const aiNode *pNode, std::vector<const aiNode *> &poNodes) const;
|
||||
@@ -195,7 +208,7 @@ protected:
|
||||
/** Finds a proper name for a node derived from the collada-node's properties */
|
||||
std::string FindNameForNode(const Collada::Node *pNode);
|
||||
|
||||
private:
|
||||
protected:
|
||||
/** Filename, for a verbose error message */
|
||||
std::string mFileName;
|
||||
|
||||
|
||||
@@ -61,7 +61,6 @@ using namespace Assimp;
|
||||
using namespace Assimp::Collada;
|
||||
using namespace Assimp::Formatter;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void ReportWarning(const char *msg, ...) {
|
||||
ai_assert(nullptr != msg);
|
||||
|
||||
@@ -76,7 +75,6 @@ static void ReportWarning(const char *msg, ...) {
|
||||
ASSIMP_LOG_WARN("Validation warning: ", std::string(szBuffer, iLen));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static bool FindCommonKey(const std::string &collada_key, const MetaKeyPairVector &key_renaming, size_t &found_index) {
|
||||
for (size_t i = 0; i < key_renaming.size(); ++i) {
|
||||
if (key_renaming[i].first == collada_key) {
|
||||
@@ -89,7 +87,6 @@ static bool FindCommonKey(const std::string &collada_key, const MetaKeyPairVecto
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void readUrlAttribute(XmlNode &node, std::string &url) {
|
||||
url.clear();
|
||||
if (!XmlParser::getStdStrAttribute(node, "url", url)) {
|
||||
@@ -101,319 +98,23 @@ static void readUrlAttribute(XmlNode &node, std::string &url) {
|
||||
url = url.c_str() + 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads a node transformation entry of the given type and adds it to the given node's transformation list.
|
||||
static void ReadNodeTransformation(XmlNode &node, Node *pNode, TransformType pType) {
|
||||
if (node.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string tagName = node.name();
|
||||
|
||||
Transform tf;
|
||||
tf.mType = pType;
|
||||
|
||||
// read SID
|
||||
if (XmlParser::hasAttribute(node, "sid")) {
|
||||
XmlParser::getStdStrAttribute(node, "sid", tf.mID);
|
||||
}
|
||||
|
||||
// how many parameters to read per transformation type
|
||||
static constexpr unsigned int sNumParameters[] = { 9, 4, 3, 3, 7, 16 };
|
||||
std::string value;
|
||||
XmlParser::getValueAsString(node, value);
|
||||
const char *content = value.c_str();
|
||||
const char *end = value.c_str() + value.size();
|
||||
// read as many parameters and store in the transformation
|
||||
for (unsigned int a = 0; a < sNumParameters[pType]; a++) {
|
||||
// skip whitespace before the number
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
// read a number
|
||||
content = fast_atoreal_move<ai_real>(content, tf.f[a]);
|
||||
}
|
||||
|
||||
// place the transformation at the queue of the node
|
||||
pNode->mTransforms.push_back(tf);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads a single string metadata item
|
||||
static void ReadMetaDataItem(XmlNode &node, ColladaParser::StringMetaData &metadata) {
|
||||
const MetaKeyPairVector &key_renaming = GetColladaAssimpMetaKeysCamelCase();
|
||||
const std::string name = node.name();
|
||||
if (name.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string v;
|
||||
if (!XmlParser::getValueAsString(node, v)) {
|
||||
return;
|
||||
}
|
||||
|
||||
v = ai_trim(v);
|
||||
aiString aistr;
|
||||
aistr.Set(v);
|
||||
|
||||
std::string camel_key_str(name);
|
||||
ToCamelCase(camel_key_str);
|
||||
|
||||
size_t found_index;
|
||||
if (FindCommonKey(camel_key_str, key_renaming, found_index)) {
|
||||
metadata.emplace(key_renaming[found_index].second, aistr);
|
||||
} else {
|
||||
metadata.emplace(camel_key_str, aistr);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads an animation sampler into the given anim channel
|
||||
static void ReadAnimationSampler(const XmlNode &node, AnimationChannel &pChannel) {
|
||||
for (XmlNode ¤tNode : node.children()) {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == "input") {
|
||||
if (XmlParser::hasAttribute(currentNode, "semantic")) {
|
||||
std::string semantic, sourceAttr;
|
||||
XmlParser::getStdStrAttribute(currentNode, "semantic", semantic);
|
||||
if (XmlParser::hasAttribute(currentNode, "source")) {
|
||||
XmlParser::getStdStrAttribute(currentNode, "source", sourceAttr);
|
||||
const char *source = sourceAttr.c_str();
|
||||
if (source[0] != '#') {
|
||||
throw DeadlyImportError("Unsupported URL format");
|
||||
}
|
||||
source++;
|
||||
|
||||
if (semantic == "INPUT") {
|
||||
pChannel.mSourceTimes = source;
|
||||
} else if (semantic == "OUTPUT") {
|
||||
pChannel.mSourceValues = source;
|
||||
} else if (semantic == "IN_TANGENT") {
|
||||
pChannel.mInTanValues = source;
|
||||
} else if (semantic == "OUT_TANGENT") {
|
||||
pChannel.mOutTanValues = source;
|
||||
} else if (semantic == "INTERPOLATION") {
|
||||
pChannel.mInterpolationValues = source;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads the joint definitions for the given controller
|
||||
static void ReadControllerJoints(const XmlNode &node, Controller &pController) {
|
||||
for (XmlNode ¤tNode : node.children()) {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == "input") {
|
||||
const char *attrSemantic = currentNode.attribute("semantic").as_string();
|
||||
const char *attrSource = currentNode.attribute("source").as_string();
|
||||
if (attrSource[0] != '#') {
|
||||
throw DeadlyImportError("Unsupported URL format in \"", attrSource, "\" in source attribute of <joints> data <input> element");
|
||||
}
|
||||
++attrSource;
|
||||
// parse source URL to corresponding source
|
||||
if (strcmp(attrSemantic, "JOINT") == 0) {
|
||||
pController.mJointNameSource = attrSource;
|
||||
} else if (strcmp(attrSemantic, "INV_BIND_MATRIX") == 0) {
|
||||
pController.mJointOffsetMatrixSource = attrSource;
|
||||
} else {
|
||||
throw DeadlyImportError("Unknown semantic \"", attrSemantic, "\" in <joints> data <input> element");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void ReadControllerWeightsInput(const XmlNode ¤tNode, Controller &pController) {
|
||||
InputChannel channel;
|
||||
|
||||
const char *attrSemantic = currentNode.attribute("semantic").as_string();
|
||||
const char *attrSource = currentNode.attribute("source").as_string();
|
||||
channel.mOffset = currentNode.attribute("offset").as_int();
|
||||
|
||||
// local URLS always start with a '#'. We don't support global URLs
|
||||
if (attrSource[0] != '#') {
|
||||
throw DeadlyImportError("Unsupported URL format in \"", attrSource, "\" in source attribute of <vertex_weights> data <input> element");
|
||||
}
|
||||
channel.mAccessor = attrSource + 1;
|
||||
|
||||
// parse source URL to corresponding source
|
||||
if (strcmp(attrSemantic, "JOINT") == 0) {
|
||||
pController.mWeightInputJoints = channel;
|
||||
} else if (strcmp(attrSemantic, "WEIGHT") == 0) {
|
||||
pController.mWeightInputWeights = channel;
|
||||
} else {
|
||||
throw DeadlyImportError("Unknown semantic \"", attrSemantic, "\" in <vertex_weights> data <input> element");
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void ReadControllerWeightsVCount(const XmlNode ¤tNode, Controller &pController) {
|
||||
const std::string stdText = currentNode.text().as_string();
|
||||
const char *text = stdText.c_str();
|
||||
const char *end = text + stdText.size();
|
||||
size_t numWeights = 0;
|
||||
for (auto it = pController.mWeightCounts.begin(); it != pController.mWeightCounts.end(); ++it) {
|
||||
if (*text == 0) {
|
||||
throw DeadlyImportError("Out of data while reading <vcount>");
|
||||
}
|
||||
|
||||
*it = strtoul10(text, &text);
|
||||
numWeights += *it;
|
||||
SkipSpacesAndLineEnd(&text, end);
|
||||
}
|
||||
// reserve weight count
|
||||
pController.mWeights.resize(numWeights);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void ReadControllerWeightsJoint2verts(XmlNode ¤tNode, Controller &pController) {
|
||||
// read JointIndex - WeightIndex pairs
|
||||
std::string stdText;
|
||||
XmlParser::getValueAsString(currentNode, stdText);
|
||||
const char *text = stdText.c_str();
|
||||
const char *end = text + stdText.size();
|
||||
for (auto it = pController.mWeights.begin(); it != pController.mWeights.end(); ++it) {
|
||||
if (text == nullptr) {
|
||||
throw DeadlyImportError("Out of data while reading <vertex_weights>");
|
||||
}
|
||||
SkipSpacesAndLineEnd(&text, end);
|
||||
it->first = strtoul10(text, &text);
|
||||
SkipSpacesAndLineEnd(&text, end);
|
||||
if (*text == 0) {
|
||||
throw DeadlyImportError("Out of data while reading <vertex_weights>");
|
||||
}
|
||||
it->second = strtoul10(text, &text);
|
||||
SkipSpacesAndLineEnd(&text, end);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads the joint weights for the given controller
|
||||
static void ReadControllerWeights(XmlNode &node, Controller &pController) {
|
||||
// Read vertex count from attributes and resize the array accordingly
|
||||
int vertexCount = 0;
|
||||
XmlParser::getIntAttribute(node, "count", vertexCount);
|
||||
pController.mWeightCounts.resize(vertexCount);
|
||||
|
||||
for (XmlNode ¤tNode : node.children()) {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == "input") {
|
||||
ReadControllerWeightsInput(currentNode, pController);
|
||||
} else if (currentName == "vcount" && vertexCount > 0) {
|
||||
ReadControllerWeightsVCount(currentNode, pController);
|
||||
} else if (currentName == "v" && vertexCount > 0) {
|
||||
ReadControllerWeightsJoint2verts(currentNode, pController);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads a material entry into the given material
|
||||
static void ReadMaterial(const XmlNode &node, Material &pMaterial) {
|
||||
for (XmlNode ¤tNode : node.children()) {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == "instance_effect") {
|
||||
std::string url;
|
||||
readUrlAttribute(currentNode, url);
|
||||
pMaterial.mEffect = url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads a light entry into the given light
|
||||
static void ReadLight(XmlNode &node, Light &pLight) {
|
||||
XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
|
||||
XmlNode currentNode;
|
||||
// TODO: Check the current technique and skip over unsupported extra techniques
|
||||
|
||||
while (xmlIt.getNext(currentNode)) {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == "spot") {
|
||||
pLight.mType = aiLightSource_SPOT;
|
||||
} else if (currentName == "ambient") {
|
||||
pLight.mType = aiLightSource_AMBIENT;
|
||||
} else if (currentName == "directional") {
|
||||
pLight.mType = aiLightSource_DIRECTIONAL;
|
||||
} else if (currentName == "point") {
|
||||
pLight.mType = aiLightSource_POINT;
|
||||
} else if (currentName == "color") {
|
||||
// text content contains 3 floats
|
||||
std::string v;
|
||||
XmlParser::getValueAsString(currentNode, v);
|
||||
const char *content = v.c_str();
|
||||
const char *end = content + v.size();
|
||||
|
||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.r);
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
|
||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.g);
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
|
||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.b);
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
} else if (currentName == "constant_attenuation") {
|
||||
XmlParser::getValueAsReal(currentNode, pLight.mAttConstant);
|
||||
} else if (currentName == "linear_attenuation") {
|
||||
XmlParser::getValueAsReal(currentNode, pLight.mAttLinear);
|
||||
} else if (currentName == "quadratic_attenuation") {
|
||||
XmlParser::getValueAsReal(currentNode, pLight.mAttQuadratic);
|
||||
} else if (currentName == "falloff_angle") {
|
||||
XmlParser::getValueAsReal(currentNode, pLight.mFalloffAngle);
|
||||
} else if (currentName == "falloff_exponent") {
|
||||
XmlParser::getValueAsReal(currentNode, pLight.mFalloffExponent);
|
||||
}
|
||||
// FCOLLADA extensions
|
||||
// -------------------------------------------------------
|
||||
else if (currentName == "outer_cone") {
|
||||
XmlParser::getValueAsReal(currentNode, pLight.mOuterAngle);
|
||||
} else if (currentName == "penumbra_angle") { // this one is deprecated, now calculated using outer_cone
|
||||
XmlParser::getValueAsReal(currentNode, pLight.mPenumbraAngle);
|
||||
} else if (currentName == "intensity") {
|
||||
XmlParser::getValueAsReal(currentNode, pLight.mIntensity);
|
||||
} else if (currentName == "falloff") {
|
||||
XmlParser::getValueAsReal(currentNode, pLight.mOuterAngle);
|
||||
} else if (currentName == "hotspot_beam") {
|
||||
XmlParser::getValueAsReal(currentNode, pLight.mFalloffAngle);
|
||||
}
|
||||
// OpenCOLLADA extensions
|
||||
// -------------------------------------------------------
|
||||
else if (currentName == "decay_falloff") {
|
||||
XmlParser::getValueAsReal(currentNode, pLight.mOuterAngle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads a camera entry into the given light
|
||||
static void ReadCamera(XmlNode &node, Camera &camera) {
|
||||
XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
|
||||
XmlNode currentNode;
|
||||
while (xmlIt.getNext(currentNode)) {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == "orthographic") {
|
||||
camera.mOrtho = true;
|
||||
} else if (currentName == "xfov" || currentName == "xmag") {
|
||||
XmlParser::getValueAsReal(currentNode, camera.mHorFov);
|
||||
} else if (currentName == "yfov" || currentName == "ymag") {
|
||||
XmlParser::getValueAsReal(currentNode, camera.mVerFov);
|
||||
} else if (currentName == "aspect_ratio") {
|
||||
XmlParser::getValueAsReal(currentNode, camera.mAspect);
|
||||
} else if (currentName == "znear") {
|
||||
XmlParser::getValueAsReal(currentNode, camera.mZNear);
|
||||
} else if (currentName == "zfar") {
|
||||
XmlParser::getValueAsReal(currentNode, camera.mZFar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor to be privately used by Importer
|
||||
ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
|
||||
mFileName(pFile),
|
||||
mXmlParser(),
|
||||
mDataLibrary(),
|
||||
mAccessorLibrary(),
|
||||
mMeshLibrary(),
|
||||
mNodeLibrary(),
|
||||
mImageLibrary(),
|
||||
mEffectLibrary(),
|
||||
mMaterialLibrary(),
|
||||
mLightLibrary(),
|
||||
mCameraLibrary(),
|
||||
mControllerLibrary(),
|
||||
mRootNode(nullptr),
|
||||
mAnims(),
|
||||
mUnitSize(1.0f),
|
||||
mUpDirection(UP_Y),
|
||||
mFormat(FV_1_5_n) {
|
||||
@@ -421,13 +122,13 @@ ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
|
||||
throw DeadlyImportError("IOSystem is nullptr.");
|
||||
}
|
||||
|
||||
std::unique_ptr<IOStream> daeFile;
|
||||
std::unique_ptr<IOStream> daefile;
|
||||
std::unique_ptr<ZipArchiveIOSystem> zip_archive;
|
||||
|
||||
// Determine type
|
||||
const std::string extension = BaseImporter::GetExtension(pFile);
|
||||
std::string extension = BaseImporter::GetExtension(pFile);
|
||||
if (extension != "dae") {
|
||||
zip_archive = std::make_unique<ZipArchiveIOSystem>(pIOHandler, pFile);
|
||||
zip_archive.reset(new ZipArchiveIOSystem(pIOHandler, pFile));
|
||||
}
|
||||
|
||||
if (zip_archive && zip_archive->isOpen()) {
|
||||
@@ -437,24 +138,24 @@ ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
|
||||
throw DeadlyImportError("Invalid ZAE");
|
||||
}
|
||||
|
||||
daeFile.reset(zip_archive->Open(dae_filename.c_str()));
|
||||
if (daeFile == nullptr) {
|
||||
daefile.reset(zip_archive->Open(dae_filename.c_str()));
|
||||
if (daefile == nullptr) {
|
||||
throw DeadlyImportError("Invalid ZAE manifest: '", dae_filename, "' is missing");
|
||||
}
|
||||
} else {
|
||||
// attempt to open the file directly
|
||||
daeFile.reset(pIOHandler->Open(pFile));
|
||||
if (daeFile == nullptr) {
|
||||
daefile.reset(pIOHandler->Open(pFile));
|
||||
if (daefile == nullptr) {
|
||||
throw DeadlyImportError("Failed to open file '", pFile, "'.");
|
||||
}
|
||||
}
|
||||
|
||||
// generate a XML reader for it
|
||||
if (!mXmlParser.parse(daeFile.get())) {
|
||||
if (!mXmlParser.parse(daefile.get())) {
|
||||
throw DeadlyImportError("Unable to read file, malformed XML");
|
||||
}
|
||||
// start reading
|
||||
const XmlNode node = mXmlParser.getRootNode();
|
||||
XmlNode node = mXmlParser.getRootNode();
|
||||
XmlNode colladaNode = node.child("COLLADA");
|
||||
if (colladaNode.empty()) {
|
||||
return;
|
||||
@@ -489,14 +190,14 @@ std::string ColladaParser::ReadZaeManifest(ZipArchiveIOSystem &zip_archive) {
|
||||
zip_archive.getFileListExtension(file_list, "dae");
|
||||
|
||||
if (file_list.empty()) {
|
||||
return {};
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return file_list.front();
|
||||
}
|
||||
XmlParser manifestParser;
|
||||
if (!manifestParser.parse(manifestfile.get())) {
|
||||
return {};
|
||||
return std::string();
|
||||
}
|
||||
|
||||
XmlNode root = manifestParser.getRootNode();
|
||||
@@ -504,7 +205,7 @@ std::string ColladaParser::ReadZaeManifest(ZipArchiveIOSystem &zip_archive) {
|
||||
if (name != "dae_root") {
|
||||
root = *manifestParser.findNode("dae_root");
|
||||
if (nullptr == root) {
|
||||
return {};
|
||||
return std::string();
|
||||
}
|
||||
std::string v;
|
||||
XmlParser::getValueAsString(root, v);
|
||||
@@ -513,7 +214,7 @@ std::string ColladaParser::ReadZaeManifest(ZipArchiveIOSystem &zip_archive) {
|
||||
return std::string(ai_str.C_Str());
|
||||
}
|
||||
|
||||
return {};
|
||||
return std::string();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -545,7 +246,7 @@ void ColladaParser::UriDecodePath(aiString &ss) {
|
||||
char mychar[3] = { it[1], it[2], 0 };
|
||||
size_t nbr = strtoul16(mychar);
|
||||
it += 3;
|
||||
*out++ = static_cast<char>(nbr & 0xFF);
|
||||
*out++ = (char)(nbr & 0xFF);
|
||||
} else {
|
||||
*out++ = *it++;
|
||||
}
|
||||
@@ -560,11 +261,12 @@ void ColladaParser::UriDecodePath(aiString &ss) {
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads the contents of the file
|
||||
void ColladaParser::ReadContents(XmlNode &node) {
|
||||
if (const std::string name = node.name(); name == "COLLADA") {
|
||||
const std::string name = node.name();
|
||||
if (name == "COLLADA") {
|
||||
std::string version;
|
||||
if (XmlParser::getStdStrAttribute(node, "version", version)) {
|
||||
aiString v;
|
||||
v.Set(version);
|
||||
v.Set(version.c_str());
|
||||
mAssetMetaData.emplace(AI_METADATA_SOURCE_FORMAT_VERSION, v);
|
||||
if (!::strncmp(version.c_str(), "1.5", 3)) {
|
||||
mFormat = FV_1_5_n;
|
||||
@@ -585,7 +287,8 @@ void ColladaParser::ReadContents(XmlNode &node) {
|
||||
// Reads the structure of the file
|
||||
void ColladaParser::ReadStructure(XmlNode &node) {
|
||||
for (XmlNode ¤tNode : node.children()) {
|
||||
if (const std::string ¤tName = currentNode.name(); currentName == "asset") {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == "asset") {
|
||||
ReadAssetInfo(currentNode);
|
||||
} else if (currentName == "library_animations") {
|
||||
ReadAnimationLibrary(currentNode);
|
||||
@@ -626,7 +329,8 @@ void ColladaParser::ReadAssetInfo(XmlNode &node) {
|
||||
}
|
||||
|
||||
for (XmlNode ¤tNode : node.children()) {
|
||||
if (const std::string ¤tName = currentNode.name(); currentName == "unit") {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == "unit") {
|
||||
mUnitSize = 1.f;
|
||||
std::string tUnitSizeString;
|
||||
if (XmlParser::getStdStrAttribute(currentNode, "meter", tUnitSizeString)) {
|
||||
@@ -660,6 +364,35 @@ void ColladaParser::ReadAssetInfo(XmlNode &node) {
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads a single string metadata item
|
||||
void ColladaParser::ReadMetaDataItem(XmlNode &node, StringMetaData &metadata) {
|
||||
const Collada::MetaKeyPairVector &key_renaming = GetColladaAssimpMetaKeysCamelCase();
|
||||
const std::string name = node.name();
|
||||
if (name.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string v;
|
||||
if (!XmlParser::getValueAsString(node, v)) {
|
||||
return;
|
||||
}
|
||||
|
||||
v = ai_trim(v);
|
||||
aiString aistr;
|
||||
aistr.Set(v);
|
||||
|
||||
std::string camel_key_str(name);
|
||||
ToCamelCase(camel_key_str);
|
||||
|
||||
size_t found_index;
|
||||
if (FindCommonKey(camel_key_str, key_renaming, found_index)) {
|
||||
metadata.emplace(key_renaming[found_index].second, aistr);
|
||||
} else {
|
||||
metadata.emplace(camel_key_str, aistr);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads the animation clips
|
||||
void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) {
|
||||
@@ -691,16 +424,15 @@ void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) {
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// The controller post processing step
|
||||
void ColladaParser::PostProcessControllers() {
|
||||
std::string meshId;
|
||||
for (auto &it : mControllerLibrary) {
|
||||
std::string meshId = it.second.mMeshId;
|
||||
meshId = it.second.mMeshId;
|
||||
if (meshId.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto findItr = mControllerLibrary.find(meshId);
|
||||
ControllerLibrary::iterator findItr = mControllerLibrary.find(meshId);
|
||||
while (findItr != mControllerLibrary.end()) {
|
||||
meshId = findItr->second.mMeshId;
|
||||
findItr = mControllerLibrary.find(meshId);
|
||||
@@ -722,13 +454,13 @@ void ColladaParser::PostProcessRootAnimations() {
|
||||
for (auto &it : mAnimationClipLibrary) {
|
||||
std::string clipName = it.first;
|
||||
|
||||
auto *clip = new Animation();
|
||||
Animation *clip = new Animation();
|
||||
clip->mName = clipName;
|
||||
|
||||
temp.mSubAnims.push_back(clip);
|
||||
|
||||
for (const std::string &animationID : it.second) {
|
||||
auto animation = mAnimationLibrary.find(animationID);
|
||||
AnimationLibrary::iterator animation = mAnimationLibrary.find(animationID);
|
||||
|
||||
if (animation != mAnimationLibrary.end()) {
|
||||
Animation *pSourceAnimation = animation->second;
|
||||
@@ -801,7 +533,7 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
|
||||
std::string id;
|
||||
if (XmlParser::getStdStrAttribute(currentNode, "id", id)) {
|
||||
// have it read into a channel
|
||||
auto newChannel = channels.insert(std::make_pair(id, AnimationChannel())).first;
|
||||
ChannelMap::iterator newChannel = channels.insert(std::make_pair(id, AnimationChannel())).first;
|
||||
ReadAnimationSampler(currentNode, newChannel->second);
|
||||
}
|
||||
} else if (currentName == "channel") {
|
||||
@@ -811,7 +543,7 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
|
||||
if (source_name[0] == '#') {
|
||||
source_name = source_name.substr(1, source_name.size() - 1);
|
||||
}
|
||||
auto cit = channels.find(source_name);
|
||||
ChannelMap::iterator cit = channels.find(source_name);
|
||||
if (cit != channels.end()) {
|
||||
cit->second.mTarget = target;
|
||||
}
|
||||
@@ -836,6 +568,40 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads an animation sampler into the given anim channel
|
||||
void ColladaParser::ReadAnimationSampler(XmlNode &node, Collada::AnimationChannel &pChannel) {
|
||||
for (XmlNode ¤tNode : node.children()) {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == "input") {
|
||||
if (XmlParser::hasAttribute(currentNode, "semantic")) {
|
||||
std::string semantic, sourceAttr;
|
||||
XmlParser::getStdStrAttribute(currentNode, "semantic", semantic);
|
||||
if (XmlParser::hasAttribute(currentNode, "source")) {
|
||||
XmlParser::getStdStrAttribute(currentNode, "source", sourceAttr);
|
||||
const char *source = sourceAttr.c_str();
|
||||
if (source[0] != '#') {
|
||||
throw DeadlyImportError("Unsupported URL format");
|
||||
}
|
||||
source++;
|
||||
|
||||
if (semantic == "INPUT") {
|
||||
pChannel.mSourceTimes = source;
|
||||
} else if (semantic == "OUTPUT") {
|
||||
pChannel.mSourceValues = source;
|
||||
} else if (semantic == "IN_TANGENT") {
|
||||
pChannel.mInTanValues = source;
|
||||
} else if (semantic == "OUT_TANGENT") {
|
||||
pChannel.mOutTanValues = source;
|
||||
} else if (semantic == "INTERPOLATION") {
|
||||
pChannel.mInterpolationValues = source;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads the skeleton controller library
|
||||
void ColladaParser::ReadControllerLibrary(XmlNode &node) {
|
||||
@@ -848,7 +614,8 @@ void ColladaParser::ReadControllerLibrary(XmlNode &node) {
|
||||
if (currentName != "controller") {
|
||||
continue;
|
||||
}
|
||||
if (std::string id; XmlParser::getStdStrAttribute(currentNode, "id", id)) {
|
||||
std::string id;
|
||||
if (XmlParser::getStdStrAttribute(currentNode, "id", id)) {
|
||||
mControllerLibrary[id] = Controller();
|
||||
ReadController(currentNode, mControllerLibrary[id]);
|
||||
}
|
||||
@@ -865,11 +632,13 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
|
||||
XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
|
||||
XmlNode currentNode;
|
||||
while (xmlIt.getNext(currentNode)) {
|
||||
if (const std::string ¤tName = currentNode.name(); currentName == "morph") {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == "morph") {
|
||||
controller.mType = Morph;
|
||||
std::string id = currentNode.attribute("source").as_string();
|
||||
controller.mMeshId = id.substr(1, id.size() - 1);
|
||||
if (const int methodIndex = currentNode.attribute("method").as_int(); methodIndex > 0) {
|
||||
int methodIndex = currentNode.attribute("method").as_int();
|
||||
if (methodIndex > 0) {
|
||||
std::string method;
|
||||
XmlParser::getValueAsString(currentNode, method);
|
||||
|
||||
@@ -878,7 +647,8 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
|
||||
}
|
||||
}
|
||||
} else if (currentName == "skin") {
|
||||
if (std::string id; XmlParser::getStdStrAttribute(currentNode, "source", id)) {
|
||||
std::string id;
|
||||
if (XmlParser::getStdStrAttribute(currentNode, "source", id)) {
|
||||
controller.mMeshId = id.substr(1, id.size() - 1);
|
||||
}
|
||||
} else if (currentName == "bind_shape_matrix") {
|
||||
@@ -886,10 +656,10 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
|
||||
XmlParser::getValueAsString(currentNode, v);
|
||||
const char *content = v.c_str();
|
||||
const char *end = content + v.size();
|
||||
for (float & a : controller.mBindShapeMatrix) {
|
||||
for (unsigned int a = 0; a < 16; a++) {
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
// read a number
|
||||
content = fast_atoreal_move<ai_real>(content, a);
|
||||
content = fast_atoreal_move<ai_real>(content, controller.mBindShapeMatrix[a]);
|
||||
// skip whitespace after it
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
}
|
||||
@@ -916,13 +686,108 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads the joint definitions for the given controller
|
||||
void ColladaParser::ReadControllerJoints(XmlNode &node, Collada::Controller &pController) {
|
||||
for (XmlNode ¤tNode : node.children()) {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == "input") {
|
||||
const char *attrSemantic = currentNode.attribute("semantic").as_string();
|
||||
const char *attrSource = currentNode.attribute("source").as_string();
|
||||
if (attrSource[0] != '#') {
|
||||
throw DeadlyImportError("Unsupported URL format in \"", attrSource, "\" in source attribute of <joints> data <input> element");
|
||||
}
|
||||
++attrSource;
|
||||
// parse source URL to corresponding source
|
||||
if (strcmp(attrSemantic, "JOINT") == 0) {
|
||||
pController.mJointNameSource = attrSource;
|
||||
} else if (strcmp(attrSemantic, "INV_BIND_MATRIX") == 0) {
|
||||
pController.mJointOffsetMatrixSource = attrSource;
|
||||
} else {
|
||||
throw DeadlyImportError("Unknown semantic \"", attrSemantic, "\" in <joints> data <input> element");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads the joint weights for the given controller
|
||||
void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pController) {
|
||||
// Read vertex count from attributes and resize the array accordingly
|
||||
int vertexCount = 0;
|
||||
XmlParser::getIntAttribute(node, "count", vertexCount);
|
||||
pController.mWeightCounts.resize(vertexCount);
|
||||
|
||||
for (XmlNode ¤tNode : node.children()) {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == "input") {
|
||||
InputChannel channel;
|
||||
|
||||
const char *attrSemantic = currentNode.attribute("semantic").as_string();
|
||||
const char *attrSource = currentNode.attribute("source").as_string();
|
||||
channel.mOffset = currentNode.attribute("offset").as_int();
|
||||
|
||||
// local URLS always start with a '#'. We don't support global URLs
|
||||
if (attrSource[0] != '#') {
|
||||
throw DeadlyImportError("Unsupported URL format in \"", attrSource, "\" in source attribute of <vertex_weights> data <input> element");
|
||||
}
|
||||
channel.mAccessor = attrSource + 1;
|
||||
|
||||
// parse source URL to corresponding source
|
||||
if (strcmp(attrSemantic, "JOINT") == 0) {
|
||||
pController.mWeightInputJoints = channel;
|
||||
} else if (strcmp(attrSemantic, "WEIGHT") == 0) {
|
||||
pController.mWeightInputWeights = channel;
|
||||
} else {
|
||||
throw DeadlyImportError("Unknown semantic \"", attrSemantic, "\" in <vertex_weights> data <input> element");
|
||||
}
|
||||
} else if (currentName == "vcount" && vertexCount > 0) {
|
||||
const std::string stdText = currentNode.text().as_string();
|
||||
const char *text = stdText.c_str();
|
||||
const char *end = text + stdText.size();
|
||||
size_t numWeights = 0;
|
||||
for (std::vector<size_t>::iterator it = pController.mWeightCounts.begin(); it != pController.mWeightCounts.end(); ++it) {
|
||||
if (*text == 0) {
|
||||
throw DeadlyImportError("Out of data while reading <vcount>");
|
||||
}
|
||||
|
||||
*it = strtoul10(text, &text);
|
||||
numWeights += *it;
|
||||
SkipSpacesAndLineEnd(&text, end);
|
||||
}
|
||||
// reserve weight count
|
||||
pController.mWeights.resize(numWeights);
|
||||
} else if (currentName == "v" && vertexCount > 0) {
|
||||
// read JointIndex - WeightIndex pairs
|
||||
std::string stdText;
|
||||
XmlParser::getValueAsString(currentNode, stdText);
|
||||
const char *text = stdText.c_str();
|
||||
const char *end = text + stdText.size();
|
||||
for (std::vector<std::pair<size_t, size_t>>::iterator it = pController.mWeights.begin(); it != pController.mWeights.end(); ++it) {
|
||||
if (text == nullptr) {
|
||||
throw DeadlyImportError("Out of data while reading <vertex_weights>");
|
||||
}
|
||||
SkipSpacesAndLineEnd(&text, end);
|
||||
it->first = strtoul10(text, &text);
|
||||
SkipSpacesAndLineEnd(&text, end);
|
||||
if (*text == 0) {
|
||||
throw DeadlyImportError("Out of data while reading <vertex_weights>");
|
||||
}
|
||||
it->second = strtoul10(text, &text);
|
||||
SkipSpacesAndLineEnd(&text, end);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads the image library contents
|
||||
void ColladaParser::ReadImageLibrary(const XmlNode &node) {
|
||||
void ColladaParser::ReadImageLibrary(XmlNode &node) {
|
||||
for (XmlNode ¤tNode : node.children()) {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == "image") {
|
||||
if (std::basic_string<char> id; XmlParser::getStdStrAttribute(currentNode, "id", id)) {
|
||||
std::string id;
|
||||
if (XmlParser::getStdStrAttribute(currentNode, "id", id)) {
|
||||
mImageLibrary[id] = Image();
|
||||
// read on from there
|
||||
ReadImage(currentNode, mImageLibrary[id]);
|
||||
@@ -933,7 +798,7 @@ void ColladaParser::ReadImageLibrary(const XmlNode &node) {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads an image entry into the given image
|
||||
void ColladaParser::ReadImage(const XmlNode &node, Collada::Image &pImage) const {
|
||||
void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) {
|
||||
for (XmlNode ¤tNode : node.children()) {
|
||||
const std::string currentName = currentNode.name();
|
||||
if (currentName == "image") {
|
||||
@@ -996,13 +861,13 @@ void ColladaParser::ReadImage(const XmlNode &node, Collada::Image &pImage) const
|
||||
// Reads the material library
|
||||
void ColladaParser::ReadMaterialLibrary(XmlNode &node) {
|
||||
std::map<std::string, int> names;
|
||||
for (const XmlNode ¤tNode : node.children()) {
|
||||
for (XmlNode ¤tNode : node.children()) {
|
||||
std::string id = currentNode.attribute("id").as_string();
|
||||
std::string name = currentNode.attribute("name").as_string();
|
||||
mMaterialLibrary[id] = Material();
|
||||
|
||||
if (!name.empty()) {
|
||||
auto it = names.find(name);
|
||||
std::map<std::string, int>::iterator it = names.find(name);
|
||||
if (it != names.end()) {
|
||||
std::ostringstream strStream;
|
||||
strStream << ++it->second;
|
||||
@@ -1057,6 +922,107 @@ void ColladaParser::ReadCameraLibrary(XmlNode &node) {
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads a material entry into the given material
|
||||
void ColladaParser::ReadMaterial(XmlNode &node, Collada::Material &pMaterial) {
|
||||
for (XmlNode ¤tNode : node.children()) {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == "instance_effect") {
|
||||
std::string url;
|
||||
readUrlAttribute(currentNode, url);
|
||||
pMaterial.mEffect = url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads a light entry into the given light
|
||||
void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) {
|
||||
XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
|
||||
XmlNode currentNode;
|
||||
// TODO: Check the current technique and skip over unsupported extra techniques
|
||||
|
||||
while (xmlIt.getNext(currentNode)) {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == "spot") {
|
||||
pLight.mType = aiLightSource_SPOT;
|
||||
} else if (currentName == "ambient") {
|
||||
pLight.mType = aiLightSource_AMBIENT;
|
||||
} else if (currentName == "directional") {
|
||||
pLight.mType = aiLightSource_DIRECTIONAL;
|
||||
} else if (currentName == "point") {
|
||||
pLight.mType = aiLightSource_POINT;
|
||||
} else if (currentName == "color") {
|
||||
// text content contains 3 floats
|
||||
std::string v;
|
||||
XmlParser::getValueAsString(currentNode, v);
|
||||
const char *content = v.c_str();
|
||||
const char *end = content + v.size();
|
||||
|
||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.r);
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
|
||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.g);
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
|
||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.b);
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
} else if (currentName == "constant_attenuation") {
|
||||
XmlParser::getValueAsReal(currentNode, pLight.mAttConstant);
|
||||
} else if (currentName == "linear_attenuation") {
|
||||
XmlParser::getValueAsReal(currentNode, pLight.mAttLinear);
|
||||
} else if (currentName == "quadratic_attenuation") {
|
||||
XmlParser::getValueAsReal(currentNode, pLight.mAttQuadratic);
|
||||
} else if (currentName == "falloff_angle") {
|
||||
XmlParser::getValueAsReal(currentNode, pLight.mFalloffAngle);
|
||||
} else if (currentName == "falloff_exponent") {
|
||||
XmlParser::getValueAsReal(currentNode, pLight.mFalloffExponent);
|
||||
}
|
||||
// FCOLLADA extensions
|
||||
// -------------------------------------------------------
|
||||
else if (currentName == "outer_cone") {
|
||||
XmlParser::getValueAsReal(currentNode, pLight.mOuterAngle);
|
||||
} else if (currentName == "penumbra_angle") { // this one is deprecated, now calculated using outer_cone
|
||||
XmlParser::getValueAsReal(currentNode, pLight.mPenumbraAngle);
|
||||
} else if (currentName == "intensity") {
|
||||
XmlParser::getValueAsReal(currentNode, pLight.mIntensity);
|
||||
}
|
||||
else if (currentName == "falloff") {
|
||||
XmlParser::getValueAsReal(currentNode, pLight.mOuterAngle);
|
||||
} else if (currentName == "hotspot_beam") {
|
||||
XmlParser::getValueAsReal(currentNode, pLight.mFalloffAngle);
|
||||
}
|
||||
// OpenCOLLADA extensions
|
||||
// -------------------------------------------------------
|
||||
else if (currentName == "decay_falloff") {
|
||||
XmlParser::getValueAsReal(currentNode, pLight.mOuterAngle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads a camera entry into the given light
|
||||
void ColladaParser::ReadCamera(XmlNode &node, Collada::Camera &camera) {
|
||||
XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
|
||||
XmlNode currentNode;
|
||||
while (xmlIt.getNext(currentNode)) {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == "orthographic") {
|
||||
camera.mOrtho = true;
|
||||
} else if (currentName == "xfov" || currentName == "xmag") {
|
||||
XmlParser::getValueAsReal(currentNode, camera.mHorFov);
|
||||
} else if (currentName == "yfov" || currentName == "ymag") {
|
||||
XmlParser::getValueAsReal(currentNode, camera.mVerFov);
|
||||
} else if (currentName == "aspect_ratio") {
|
||||
XmlParser::getValueAsReal(currentNode, camera.mAspect);
|
||||
} else if (currentName == "znear") {
|
||||
XmlParser::getValueAsReal(currentNode, camera.mZNear);
|
||||
} else if (currentName == "zfar") {
|
||||
XmlParser::getValueAsReal(currentNode, camera.mZFar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads the effect library
|
||||
void ColladaParser::ReadEffectLibrary(XmlNode &node) {
|
||||
@@ -1260,7 +1226,7 @@ void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &p
|
||||
std::string v;
|
||||
XmlParser::getValueAsString(currentNode, v);
|
||||
const char *content = v.c_str();
|
||||
const char *end = v.c_str() + v.size() + 1;
|
||||
const char *end = v.c_str() + v.size() + 1;
|
||||
|
||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.r);
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
@@ -1386,7 +1352,7 @@ void ColladaParser::ReadGeometry(XmlNode &node, Collada::Mesh &pMesh) {
|
||||
if (node.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (XmlNode ¤tNode : node.children()) {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == "mesh") {
|
||||
@@ -1767,6 +1733,7 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
|
||||
expectedPointCount = 3 * pNumPrimitives;
|
||||
break;
|
||||
default:
|
||||
// other primitive types don't state the index count upfront... we need to guess
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1808,7 +1775,7 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
|
||||
}
|
||||
|
||||
// find the data for all sources
|
||||
for (auto it = pMesh.mPerVertexData.begin(); it != pMesh.mPerVertexData.end(); ++it) {
|
||||
for (std::vector<InputChannel>::iterator it = pMesh.mPerVertexData.begin(); it != pMesh.mPerVertexData.end(); ++it) {
|
||||
InputChannel &input = *it;
|
||||
if (input.mResolved) {
|
||||
continue;
|
||||
@@ -1827,7 +1794,7 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
|
||||
}
|
||||
}
|
||||
// and the same for the per-index channels
|
||||
for (auto it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it) {
|
||||
for (std::vector<InputChannel>::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it) {
|
||||
InputChannel &input = *it;
|
||||
if (input.mResolved) {
|
||||
continue;
|
||||
@@ -1935,11 +1902,11 @@ void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t n
|
||||
ai_assert((baseOffset + numOffsets - 1) < indices.size());
|
||||
|
||||
// extract per-vertex channels using the global per-vertex offset
|
||||
for (auto it = pMesh.mPerVertexData.begin(); it != pMesh.mPerVertexData.end(); ++it) {
|
||||
for (std::vector<InputChannel>::iterator it = pMesh.mPerVertexData.begin(); it != pMesh.mPerVertexData.end(); ++it) {
|
||||
ExtractDataObjectFromChannel(*it, indices[baseOffset + perVertexOffset], pMesh);
|
||||
}
|
||||
// and extract per-index channels using there specified offset
|
||||
for (auto it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it) {
|
||||
for (std::vector<InputChannel>::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it) {
|
||||
ExtractDataObjectFromChannel(*it, indices[baseOffset + it->mOffset], pMesh);
|
||||
}
|
||||
|
||||
@@ -2206,6 +2173,40 @@ void ColladaParser::ReadSceneNode(XmlNode &node, Node *pNode) {
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads a node transformation entry of the given type and adds it to the given node's transformation list.
|
||||
void ColladaParser::ReadNodeTransformation(XmlNode &node, Node *pNode, TransformType pType) {
|
||||
if (node.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string tagName = node.name();
|
||||
|
||||
Transform tf;
|
||||
tf.mType = pType;
|
||||
|
||||
// read SID
|
||||
if (XmlParser::hasAttribute(node, "sid")) {
|
||||
XmlParser::getStdStrAttribute(node, "sid", tf.mID);
|
||||
}
|
||||
|
||||
// how many parameters to read per transformation type
|
||||
static constexpr unsigned int sNumParameters[] = { 9, 4, 3, 3, 7, 16 };
|
||||
std::string value;
|
||||
XmlParser::getValueAsString(node, value);
|
||||
const char *content = value.c_str();
|
||||
const char *end = value.c_str() + value.size();
|
||||
// read as many parameters and store in the transformation
|
||||
for (unsigned int a = 0; a < sNumParameters[pType]; a++) {
|
||||
// skip whitespace before the number
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
// read a number
|
||||
content = fast_atoreal_move<ai_real>(content, tf.f[a]);
|
||||
}
|
||||
|
||||
// place the transformation at the queue of the node
|
||||
pNode->mTransforms.push_back(tf);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Processes bind_vertex_input and bind elements
|
||||
@@ -2243,7 +2244,9 @@ void ColladaParser::ReadMaterialVertexInputBinding(XmlNode &node, Collada::Seman
|
||||
void ColladaParser::ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive) {
|
||||
// Attempt to load any undefined Collada::Image in ImageLibrary
|
||||
for (auto &it : mImageLibrary) {
|
||||
if (Image &image = it.second; image.mImageData.empty()) {
|
||||
Collada::Image &image = it.second;
|
||||
|
||||
if (image.mImageData.empty()) {
|
||||
std::unique_ptr<IOStream> image_file(zip_archive.Open(image.mFileName.c_str()));
|
||||
if (image_file) {
|
||||
image.mImageData.resize(image_file->FileSize());
|
||||
@@ -2326,7 +2329,7 @@ void ColladaParser::ReadScene(XmlNode &node) {
|
||||
}
|
||||
|
||||
// find the referred scene, skip the leading #
|
||||
auto sit = mNodeLibrary.find(url.c_str() + 1);
|
||||
NodeLibrary::const_iterator sit = mNodeLibrary.find(url.c_str() + 1);
|
||||
if (sit == mNodeLibrary.end()) {
|
||||
throw DeadlyImportError("Unable to resolve visual_scene reference \"", std::string(std::move(url)), "\" in <instance_visual_scene> element.");
|
||||
}
|
||||
@@ -2398,7 +2401,7 @@ aiMatrix4x4 ColladaParser::CalculateResultTransform(const std::vector<Transform>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Determines the input data type for the given semantic string
|
||||
InputType ColladaParser::GetTypeForSemantic(const std::string &semantic) {
|
||||
Collada::InputType ColladaParser::GetTypeForSemantic(const std::string &semantic) {
|
||||
if (semantic.empty()) {
|
||||
ASSIMP_LOG_WARN("Vertex input type is empty.");
|
||||
return IT_Invalid;
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#define AI_COLLADAPARSER_H_INC
|
||||
|
||||
#include "ColladaHelper.h"
|
||||
#include <assimp/TinyFormatter.h>
|
||||
#include <assimp/ai_assert.h>
|
||||
#include <assimp/XmlParser.h>
|
||||
|
||||
@@ -66,240 +67,268 @@ class ZipArchiveIOSystem;
|
||||
class ColladaParser {
|
||||
friend class ColladaLoader;
|
||||
|
||||
public:
|
||||
/// Map for generic metadata as aiString.
|
||||
using StringMetaData = std::map<std::string, aiString>;
|
||||
/** Converts a path read from a collada file to the usual representation */
|
||||
static void UriDecodePath(aiString &ss);
|
||||
|
||||
/// Constructor from XML file.
|
||||
protected:
|
||||
/** Map for generic metadata as aiString */
|
||||
typedef std::map<std::string, aiString> StringMetaData;
|
||||
|
||||
/** Constructor from XML file */
|
||||
ColladaParser(IOSystem *pIOHandler, const std::string &pFile);
|
||||
|
||||
/// Destructor
|
||||
/** Destructor */
|
||||
~ColladaParser();
|
||||
|
||||
/// Attempts to read the ZAE manifest and returns the DAE to open
|
||||
/** Attempts to read the ZAE manifest and returns the DAE to open */
|
||||
static std::string ReadZaeManifest(ZipArchiveIOSystem &zip_archive);
|
||||
|
||||
/// Reads the contents of the file
|
||||
/** Reads the contents of the file */
|
||||
void ReadContents(XmlNode &node);
|
||||
|
||||
/// Reads the structure of the file
|
||||
/** Reads the structure of the file */
|
||||
void ReadStructure(XmlNode &node);
|
||||
|
||||
/// Reads asset information such as coordinate system information and legal blah
|
||||
/** Reads asset information such as coordinate system information and legal blah */
|
||||
void ReadAssetInfo(XmlNode &node);
|
||||
|
||||
/// Reads contributor information such as author and legal blah
|
||||
/** Reads contributor information such as author and legal blah */
|
||||
void ReadContributorInfo(XmlNode &node);
|
||||
|
||||
/// Reads the animation library
|
||||
/** Reads generic metadata into provided map and renames keys for Assimp */
|
||||
void ReadMetaDataItem(XmlNode &node, StringMetaData &metadata);
|
||||
|
||||
/** Reads the animation library */
|
||||
void ReadAnimationLibrary(XmlNode &node);
|
||||
|
||||
/// Reads the animation clip library
|
||||
/** Reads the animation clip library */
|
||||
void ReadAnimationClipLibrary(XmlNode &node);
|
||||
|
||||
/// Unwrap controllers dependency hierarchy
|
||||
/** Unwrap controllers dependency hierarchy */
|
||||
void PostProcessControllers();
|
||||
|
||||
/// Re-build animations from animation clip library, if present, otherwise combine single-channel animations
|
||||
/** Re-build animations from animation clip library, if present, otherwise combine single-channel animations */
|
||||
void PostProcessRootAnimations();
|
||||
|
||||
/// Reads an animation into the given parent structure
|
||||
/** Reads an animation into the given parent structure */
|
||||
void ReadAnimation(XmlNode &node, Collada::Animation *pParent);
|
||||
|
||||
/// Reads the skeleton controller library
|
||||
/** Reads an animation sampler into the given anim channel */
|
||||
void ReadAnimationSampler(XmlNode &node, Collada::AnimationChannel &pChannel);
|
||||
|
||||
/** Reads the skeleton controller library */
|
||||
void ReadControllerLibrary(XmlNode &node);
|
||||
|
||||
/// Reads a controller into the given mesh structure
|
||||
/** Reads a controller into the given mesh structure */
|
||||
void ReadController(XmlNode &node, Collada::Controller &pController);
|
||||
|
||||
/// Reads the image library contents
|
||||
void ReadImageLibrary(const XmlNode &node);
|
||||
/** Reads the joint definitions for the given controller */
|
||||
void ReadControllerJoints(XmlNode &node, Collada::Controller &pController);
|
||||
|
||||
/// Reads an image entry into the given image
|
||||
void ReadImage(const XmlNode &node, Collada::Image &pImage) const;
|
||||
/** Reads the joint weights for the given controller */
|
||||
void ReadControllerWeights(XmlNode &node, Collada::Controller &pController);
|
||||
|
||||
/// Reads the material library
|
||||
/** Reads the image library contents */
|
||||
void ReadImageLibrary(XmlNode &node);
|
||||
|
||||
/** Reads an image entry into the given image */
|
||||
void ReadImage(XmlNode &node, Collada::Image &pImage);
|
||||
|
||||
/** Reads the material library */
|
||||
void ReadMaterialLibrary(XmlNode &node);
|
||||
|
||||
/// Reads the camera library
|
||||
/** Reads a material entry into the given material */
|
||||
void ReadMaterial(XmlNode &node, Collada::Material &pMaterial);
|
||||
|
||||
/** Reads the camera library */
|
||||
void ReadCameraLibrary(XmlNode &node);
|
||||
|
||||
/// Reads the light library
|
||||
/** Reads a camera entry into the given camera */
|
||||
void ReadCamera(XmlNode &node, Collada::Camera &pCamera);
|
||||
|
||||
/** Reads the light library */
|
||||
void ReadLightLibrary(XmlNode &node);
|
||||
|
||||
/// Reads the effect library
|
||||
/** Reads a light entry into the given light */
|
||||
void ReadLight(XmlNode &node, Collada::Light &pLight);
|
||||
|
||||
/** Reads the effect library */
|
||||
void ReadEffectLibrary(XmlNode &node);
|
||||
|
||||
/// Reads an effect entry into the given effect
|
||||
/** Reads an effect entry into the given effect*/
|
||||
void ReadEffect(XmlNode &node, Collada::Effect &pEffect);
|
||||
|
||||
/// Reads an COMMON effect profile
|
||||
/** Reads an COMMON effect profile */
|
||||
void ReadEffectProfileCommon(XmlNode &node, Collada::Effect &pEffect);
|
||||
|
||||
/// Read sampler properties
|
||||
/** Read sampler properties */
|
||||
void ReadSamplerProperties(XmlNode &node, Collada::Sampler &pSampler);
|
||||
|
||||
/// Reads an effect entry containing a color or a texture defining that color
|
||||
/** Reads an effect entry containing a color or a texture defining that color */
|
||||
void ReadEffectColor(XmlNode &node, aiColor4D &pColor, Collada::Sampler &pSampler);
|
||||
|
||||
/// Reads an effect entry containing a float
|
||||
/** Reads an effect entry containing a float */
|
||||
void ReadEffectFloat(XmlNode &node, ai_real &pFloat);
|
||||
|
||||
/// Reads an effect parameter specification of any kind
|
||||
/** Reads an effect parameter specification of any kind */
|
||||
void ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam);
|
||||
|
||||
/// Reads the geometry library contents
|
||||
/** Reads the geometry library contents */
|
||||
void ReadGeometryLibrary(XmlNode &node);
|
||||
|
||||
/// Reads a geometry from the geometry library.
|
||||
/** Reads a geometry from the geometry library. */
|
||||
void ReadGeometry(XmlNode &node, Collada::Mesh &pMesh);
|
||||
|
||||
/// Reads a mesh from the geometry library
|
||||
/** Reads a mesh from the geometry library */
|
||||
void ReadMesh(XmlNode &node, Collada::Mesh &pMesh);
|
||||
|
||||
/// Reads a source element - a combination of raw data and an accessor defining
|
||||
///things that should not be definable. Yes, that's another rant.
|
||||
/** Reads a source element - a combination of raw data and an accessor defining
|
||||
* things that should not be redefinable. Yes, that's another rant.
|
||||
*/
|
||||
void ReadSource(XmlNode &node);
|
||||
|
||||
/// Reads a data array holding a number of elements, and stores it in the global library.
|
||||
/// Currently supported are array of floats and arrays of strings.
|
||||
/** Reads a data array holding a number of elements, and stores it in the global library.
|
||||
* Currently supported are array of floats and arrays of strings.
|
||||
*/
|
||||
void ReadDataArray(XmlNode &node);
|
||||
|
||||
/// Reads an accessor and stores it in the global library under the given ID -
|
||||
/// accessors use the ID of the parent <source> element
|
||||
/** Reads an accessor and stores it in the global library under the given ID -
|
||||
* accessors use the ID of the parent <source> element
|
||||
*/
|
||||
void ReadAccessor(XmlNode &node, const std::string &pID);
|
||||
|
||||
/// Reads input declarations of per-vertex mesh data into the given mesh
|
||||
/** Reads input declarations of per-vertex mesh data into the given mesh */
|
||||
void ReadVertexData(XmlNode &node, Collada::Mesh &pMesh);
|
||||
|
||||
/// Reads input declarations of per-index mesh data into the given mesh
|
||||
/** Reads input declarations of per-index mesh data into the given mesh */
|
||||
void ReadIndexData(XmlNode &node, Collada::Mesh &pMesh);
|
||||
|
||||
/// Reads a single input channel element and stores it in the given array, if valid
|
||||
/** Reads a single input channel element and stores it in the given array, if valid */
|
||||
void ReadInputChannel(XmlNode &node, std::vector<Collada::InputChannel> &poChannels);
|
||||
|
||||
/// Reads a <p> primitive index list and assembles the mesh data into the given mesh
|
||||
/** Reads a <p> primitive index list and assembles the mesh data into the given mesh */
|
||||
size_t ReadPrimitives(XmlNode &node, Collada::Mesh &pMesh, std::vector<Collada::InputChannel> &pPerIndexChannels,
|
||||
size_t pNumPrimitives, const std::vector<size_t> &pVCount, Collada::PrimitiveType pPrimType);
|
||||
|
||||
/// Copies the data for a single primitive into the mesh, based on the InputChannels
|
||||
/** Copies the data for a single primitive into the mesh, based on the InputChannels */
|
||||
void CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset,
|
||||
Collada::Mesh &pMesh, std::vector<Collada::InputChannel> &pPerIndexChannels,
|
||||
size_t currentPrimitive, const std::vector<size_t> &indices);
|
||||
|
||||
/// Reads one triangle of a tristrip into the mesh
|
||||
/** Reads one triangle of a tristrip into the mesh */
|
||||
void ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Collada::Mesh &pMesh,
|
||||
std::vector<Collada::InputChannel> &pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t> &indices);
|
||||
|
||||
/// Extracts a single object from an input channel and stores it in the appropriate mesh data array
|
||||
/** Extracts a single object from an input channel and stores it in the appropriate mesh data array */
|
||||
void ExtractDataObjectFromChannel(const Collada::InputChannel &pInput, size_t pLocalIndex, Collada::Mesh &pMesh);
|
||||
|
||||
/// Reads the library of node hierarchies and scene parts
|
||||
/** Reads the library of node hierarchies and scene parts */
|
||||
void ReadSceneLibrary(XmlNode &node);
|
||||
|
||||
/// Reads a scene node's contents including children and stores it in the given node
|
||||
/** Reads a scene node's contents including children and stores it in the given node */
|
||||
void ReadSceneNode(XmlNode &node, Collada::Node *pNode);
|
||||
|
||||
/// Reads a mesh reference in a node and adds it to the node's mesh list
|
||||
|
||||
/** Reads a node transformation entry of the given type and adds it to the given node's transformation list. */
|
||||
void ReadNodeTransformation(XmlNode &node, Collada::Node *pNode, Collada::TransformType pType);
|
||||
|
||||
/** Reads a mesh reference in a node and adds it to the node's mesh list */
|
||||
void ReadNodeGeometry(XmlNode &node, Collada::Node *pNode);
|
||||
|
||||
/// Reads the collada scene
|
||||
/** Reads the collada scene */
|
||||
void ReadScene(XmlNode &node);
|
||||
|
||||
/// Processes bind_vertex_input and bind elements
|
||||
// Processes bind_vertex_input and bind elements
|
||||
void ReadMaterialVertexInputBinding(XmlNode &node, Collada::SemanticMappingTable &tbl);
|
||||
|
||||
/// Reads embedded textures from a ZAE archive
|
||||
/** Reads embedded textures from a ZAE archive*/
|
||||
void ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive);
|
||||
|
||||
protected:
|
||||
/// Converts a path read from a collada file to the usual representation
|
||||
static void UriDecodePath(aiString &ss);
|
||||
|
||||
/// Calculates the resulting transformation from all the given transform steps
|
||||
/** Calculates the resulting transformation from all the given transform steps */
|
||||
aiMatrix4x4 CalculateResultTransform(const std::vector<Collada::Transform> &pTransforms) const;
|
||||
|
||||
/// Determines the input data type for the given semantic string
|
||||
/** Determines the input data type for the given semantic string */
|
||||
Collada::InputType GetTypeForSemantic(const std::string &pSemantic);
|
||||
|
||||
/// Finds the item in the given library by its reference, throws if not found
|
||||
/** Finds the item in the given library by its reference, throws if not found */
|
||||
template <typename Type>
|
||||
const Type &ResolveLibraryReference(const std::map<std::string, Type> &pLibrary, const std::string &pURL) const;
|
||||
|
||||
private:
|
||||
/// Filename, for a verbose error message
|
||||
protected:
|
||||
// Filename, for a verbose error message
|
||||
std::string mFileName;
|
||||
|
||||
/// XML reader, member for everyday use
|
||||
// XML reader, member for everyday use
|
||||
XmlParser mXmlParser;
|
||||
|
||||
/// All data arrays found in the file by ID. Might be referred to by actually
|
||||
/// everyone. Collada, you are a steaming pile of indirection.
|
||||
/** All data arrays found in the file by ID. Might be referred to by actually
|
||||
everyone. Collada, you are a steaming pile of indirection. */
|
||||
using DataLibrary = std::map<std::string, Collada::Data> ;
|
||||
DataLibrary mDataLibrary;
|
||||
|
||||
/// Same for accessors which define how the data in a data array is accessed.
|
||||
/** Same for accessors which define how the data in a data array is accessed. */
|
||||
using AccessorLibrary = std::map<std::string, Collada::Accessor> ;
|
||||
AccessorLibrary mAccessorLibrary;
|
||||
|
||||
/// Mesh library: mesh by ID
|
||||
/** Mesh library: mesh by ID */
|
||||
using MeshLibrary = std::map<std::string, Collada::Mesh *>;
|
||||
MeshLibrary mMeshLibrary;
|
||||
|
||||
/// node library: root node of the hierarchy part by ID
|
||||
/** node library: root node of the hierarchy part by ID */
|
||||
using NodeLibrary = std::map<std::string, Collada::Node *>;
|
||||
NodeLibrary mNodeLibrary;
|
||||
|
||||
/// Image library: stores texture properties by ID
|
||||
/** Image library: stores texture properties by ID */
|
||||
using ImageLibrary = std::map<std::string, Collada::Image> ;
|
||||
ImageLibrary mImageLibrary;
|
||||
|
||||
/// Effect library: surface attributes by ID
|
||||
/** Effect library: surface attributes by ID */
|
||||
using EffectLibrary = std::map<std::string, Collada::Effect> ;
|
||||
EffectLibrary mEffectLibrary;
|
||||
|
||||
/// Material library: surface material by ID
|
||||
/** Material library: surface material by ID */
|
||||
using MaterialLibrary = std::map<std::string, Collada::Material> ;
|
||||
MaterialLibrary mMaterialLibrary;
|
||||
|
||||
/// Light library: surface light by ID
|
||||
/** Light library: surface light by ID */
|
||||
using LightLibrary = std::map<std::string, Collada::Light> ;
|
||||
LightLibrary mLightLibrary;
|
||||
|
||||
/// Camera library: surface material by ID
|
||||
/** Camera library: surface material by ID */
|
||||
using CameraLibrary = std::map<std::string, Collada::Camera> ;
|
||||
CameraLibrary mCameraLibrary;
|
||||
|
||||
/// Controller library: joint controllers by ID
|
||||
/** Controller library: joint controllers by ID */
|
||||
using ControllerLibrary = std::map<std::string, Collada::Controller> ;
|
||||
ControllerLibrary mControllerLibrary;
|
||||
|
||||
/// Animation library: animation references by ID
|
||||
/** Animation library: animation references by ID */
|
||||
using AnimationLibrary = std::map<std::string, Collada::Animation *> ;
|
||||
AnimationLibrary mAnimationLibrary;
|
||||
|
||||
/// Animation clip library: clip animation references by ID
|
||||
/** Animation clip library: clip animation references by ID */
|
||||
using AnimationClipLibrary = std::vector<std::pair<std::string, std::vector<std::string>>> ;
|
||||
AnimationClipLibrary mAnimationClipLibrary;
|
||||
|
||||
/// Pointer to the root node. Don't delete, it just points to one of the nodes in the node library.
|
||||
/** Pointer to the root node. Don't delete, it just points to one of
|
||||
the nodes in the node library. */
|
||||
Collada::Node *mRootNode;
|
||||
|
||||
/// Root animation container
|
||||
/** Root animation container */
|
||||
Collada::Animation mAnims;
|
||||
|
||||
/// Size unit: how large compared to a meter
|
||||
/** Size unit: how large compared to a meter */
|
||||
ai_real mUnitSize;
|
||||
|
||||
/// Which is the up vector
|
||||
/** Which is the up vector */
|
||||
enum { UP_X,
|
||||
UP_Y,
|
||||
UP_Z } mUpDirection;
|
||||
|
||||
/// Asset metadata (global for scene)
|
||||
/** Asset metadata (global for scene) */
|
||||
StringMetaData mAssetMetaData;
|
||||
|
||||
/// Collada file format version
|
||||
/** Collada file format version */
|
||||
Collada::FormatVersion mFormat;
|
||||
};
|
||||
|
||||
|
||||
@@ -45,8 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_DXF_IMPORTER
|
||||
|
||||
#include "DXFLoader.h"
|
||||
#include "DXFHelper.h"
|
||||
#include "AssetLib/DXF/DXFLoader.h"
|
||||
#include "AssetLib/DXF/DXFHelper.h"
|
||||
#include "PostProcessing/ConvertToLHProcess.h"
|
||||
|
||||
#include <assimp/ParsingUtils.h>
|
||||
|
||||
@@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <assimp/BaseImporter.h>
|
||||
#include <map>
|
||||
|
||||
namespace Assimp {
|
||||
namespace Assimp {
|
||||
|
||||
// Forward declarations
|
||||
namespace DXF {
|
||||
|
||||
@@ -146,7 +146,7 @@ const AnimationCurveMap &AnimationCurveNode::Curves() const {
|
||||
if (!curves.empty()) {
|
||||
return curves;
|
||||
}
|
||||
|
||||
|
||||
// resolve attached animation curves
|
||||
const std::vector<const Connection *> &conns = doc.GetConnectionsByDestinationSequenced(ID(), "AnimationCurve");
|
||||
|
||||
|
||||
@@ -2958,7 +2958,7 @@ void FBXConverter::GenerateNodeAnimations(std::vector<aiNodeAnim *> &node_anims,
|
||||
// be invoked _later_ (animations come first). If this node has only rotation,
|
||||
// scaling and translation _and_ there are no animated other components either,
|
||||
// we can use a single node and also a single node animation channel.
|
||||
if (!doc.Settings().preservePivots || (!has_complex && !NeedsComplexTransformationChain(target))) {
|
||||
if( !has_complex && !NeedsComplexTransformationChain(target)) {
|
||||
aiNodeAnim* const nd = GenerateSimpleNodeAnim(fixed_name, target, chain,
|
||||
node_property_map.end(),
|
||||
start, stop,
|
||||
|
||||
@@ -269,7 +269,7 @@ Document::~Document()
|
||||
{
|
||||
// The document does not own the memory for the following objects, but we need to call their d'tor
|
||||
// so they can properly free memory like string members:
|
||||
|
||||
|
||||
for (ObjectMap::value_type &v : objects) {
|
||||
delete_LazyObject(v.second);
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ private: // internal functions used for writing
|
||||
void BeginChildrenAscii(std::ostream &s, int indent);
|
||||
void DumpChildrenAscii(std::ostream &s, int indent);
|
||||
void EndAscii(std::ostream &s, int indent, bool has_children);
|
||||
|
||||
|
||||
// static helper functions
|
||||
static void WritePropertyNodeAscii(
|
||||
const std::string& name,
|
||||
|
||||
@@ -286,8 +286,6 @@ void FBXExportProperty::DumpAscii(std::ostream& s, int indent) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// assimp issue #6112; fallthrough confirmed by @mesilliac
|
||||
[[fallthrough]];
|
||||
case 'R':
|
||||
s << '"';
|
||||
// we might as well check this now,
|
||||
|
||||
@@ -51,7 +51,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <assimp/IOSystem.hpp>
|
||||
#include <assimp/Exporter.hpp>
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
#include <assimp/Logger.hpp>
|
||||
#include <assimp/StreamWriter.h> // StreamWriterLE
|
||||
#include <assimp/Exceptional.h> // DeadlyExportError
|
||||
#include <assimp/material.h> // aiTextureType
|
||||
@@ -1043,40 +1042,14 @@ aiMatrix4x4 get_world_transform(const aiNode* node, const aiScene* scene) {
|
||||
}
|
||||
|
||||
inline int64_t to_ktime(double ticks, const aiAnimation* anim) {
|
||||
// Defensive: handle zero or near-zero mTicksPerSecond
|
||||
double tps = anim->mTicksPerSecond;
|
||||
double timeVal;
|
||||
if (FP_ZERO == std::fpclassify(tps)) {
|
||||
timeVal = ticks;
|
||||
} else {
|
||||
timeVal = ticks / tps;
|
||||
if (FP_ZERO == std::fpclassify(anim->mTicksPerSecond)) {
|
||||
return static_cast<int64_t>(ticks) * FBX::SECOND;
|
||||
}
|
||||
|
||||
// Clamp to prevent overflow
|
||||
const double kMax = static_cast<double>(INT64_MAX) / static_cast<double>(FBX::SECOND);
|
||||
const double kMin = static_cast<double>(INT64_MIN) / static_cast<double>(FBX::SECOND);
|
||||
|
||||
if (timeVal > kMax) {
|
||||
return INT64_MAX;
|
||||
}
|
||||
if (timeVal < kMin) {
|
||||
return INT64_MIN;
|
||||
}
|
||||
return static_cast<int64_t>(timeVal * FBX::SECOND);
|
||||
return (static_cast<int64_t>(ticks / anim->mTicksPerSecond)) * FBX::SECOND;
|
||||
}
|
||||
|
||||
inline int64_t to_ktime(double time) {
|
||||
// Clamp to prevent overflow
|
||||
const double kMax = static_cast<double>(INT64_MAX) / static_cast<double>(FBX::SECOND);
|
||||
const double kMin = static_cast<double>(INT64_MIN) / static_cast<double>(FBX::SECOND);
|
||||
|
||||
if (time > kMax) {
|
||||
return INT64_MAX;
|
||||
}
|
||||
if (time < kMin) {
|
||||
return INT64_MIN;
|
||||
}
|
||||
return static_cast<int64_t>(time * FBX::SECOND);
|
||||
return (static_cast<int64_t>(time * FBX::SECOND));
|
||||
}
|
||||
|
||||
void FBXExporter::WriteObjects () {
|
||||
@@ -1095,6 +1068,8 @@ void FBXExporter::WriteObjects () {
|
||||
// save vertex_indices as it is needed later
|
||||
std::vector<std::vector<int32_t>> vVertexIndice(mScene->mNumMeshes);
|
||||
|
||||
std::vector<uint32_t> uniq_v_before_mi;
|
||||
|
||||
const auto bTransparencyFactorReferencedToOpacity = mProperties->GetPropertyBool(AI_CONFIG_EXPORT_FBX_TRANSPARENCY_FACTOR_REFER_TO_OPACITY, false);
|
||||
|
||||
// geometry (aiMesh)
|
||||
@@ -1132,6 +1107,9 @@ void FBXExporter::WriteObjects () {
|
||||
|
||||
std::vector<std::vector<double>> uv_data;
|
||||
std::vector<std::vector<int32_t>> uv_indices;
|
||||
std::map<aiVector3D, int32_t> index_by_uv;
|
||||
|
||||
std::vector<int32_t> offsets = { 0 };
|
||||
|
||||
indent = 2;
|
||||
|
||||
@@ -1140,10 +1118,11 @@ void FBXExporter::WriteObjects () {
|
||||
const aiMesh *m = mScene->mMeshes[mi];
|
||||
|
||||
size_t v_offset = vertex_indices.size();
|
||||
size_t uniq_v_before = flattened_vertices.size() / 3;
|
||||
|
||||
// map of vertex value to its index in the data vector
|
||||
std::map<aiVector3D,size_t> index_by_vertex_value;
|
||||
if (bJoinIdenticalVertices) {
|
||||
if(bJoinIdenticalVertices){
|
||||
int32_t index = 0;
|
||||
for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
|
||||
aiVector3D vtx = m->mVertices[vi];
|
||||
@@ -1159,7 +1138,7 @@ void FBXExporter::WriteObjects () {
|
||||
}
|
||||
} else { // do not join vertex, respect the export flag
|
||||
vertex_indices.resize(v_offset + m->mNumVertices);
|
||||
std::iota(vertex_indices.begin() + v_offset, vertex_indices.end(), 0);
|
||||
std::iota(vertex_indices.begin() + v_offset, vertex_indices.end(), (int)v_offset);
|
||||
for(unsigned int v = 0; v < m->mNumVertices; ++ v) {
|
||||
aiVector3D vtx = m->mVertices[v];
|
||||
flattened_vertices.insert(flattened_vertices.end(), {vtx.x, vtx.y, vtx.z});
|
||||
@@ -1167,8 +1146,8 @@ void FBXExporter::WriteObjects () {
|
||||
}
|
||||
vVertexIndice[mi].insert(
|
||||
// TODO test whether this can be end or not
|
||||
vVertexIndice[mi].end(),
|
||||
vertex_indices.begin() + v_offset,
|
||||
vVertexIndice[mi].begin(),
|
||||
vertex_indices.begin(),
|
||||
vertex_indices.end()
|
||||
);
|
||||
|
||||
@@ -1179,14 +1158,19 @@ void FBXExporter::WriteObjects () {
|
||||
// the last vertex index of each polygon is negated and - 1
|
||||
for (size_t fi = 0; fi < m->mNumFaces; fi++) {
|
||||
const aiFace &f = m->mFaces[fi];
|
||||
if (f.mNumIndices == 0) continue;
|
||||
size_t pvi = 0;
|
||||
for (; pvi < f.mNumIndices - 1; pvi++) {
|
||||
polygon_data.push_back(vertex_indices[v_offset + f.mIndices[pvi]]);
|
||||
polygon_data.push_back(
|
||||
static_cast<int32_t>(uniq_v_before + vertex_indices[v_offset + f.mIndices[pvi]])
|
||||
);
|
||||
}
|
||||
polygon_data.push_back(-1 - vertex_indices[v_offset+f.mIndices[pvi]]);
|
||||
polygon_data.push_back(
|
||||
static_cast<int32_t>(-1 - (uniq_v_before + vertex_indices[v_offset+f.mIndices[pvi]]))
|
||||
);
|
||||
}
|
||||
|
||||
uniq_v_before_mi.push_back(static_cast<uint32_t>(uniq_v_before));
|
||||
|
||||
if (m->HasNormals()) {
|
||||
normal_data.reserve(3 * polygon_data.size());
|
||||
for (size_t fi = 0; fi < m->mNumFaces; fi++) {
|
||||
@@ -1213,12 +1197,10 @@ void FBXExporter::WriteObjects () {
|
||||
const auto num_uv = static_cast<size_t>(m->GetNumUVChannels());
|
||||
uv_indices.resize(std::max(num_uv, uv_indices.size()));
|
||||
uv_data.resize(std::max(num_uv, uv_data.size()));
|
||||
std::map<aiVector3D, int32_t> index_by_uv;
|
||||
|
||||
// uvs, if any
|
||||
for (size_t uvi = 0; uvi < m->GetNumUVChannels(); uvi++) {
|
||||
const auto nc = m->mNumUVComponents[uvi];
|
||||
if (nc > 2) {
|
||||
if (m->mNumUVComponents[uvi] > 2) {
|
||||
// FBX only supports 2-channel UV maps...
|
||||
// or at least i'm not sure how to indicate a different number
|
||||
std::stringstream err;
|
||||
@@ -1234,7 +1216,7 @@ void FBXExporter::WriteObjects () {
|
||||
ASSIMP_LOG_WARN(err.str());
|
||||
}
|
||||
|
||||
int32_t index = static_cast<int32_t>(uv_data[uvi].size()) / nc;
|
||||
int32_t index = 0;
|
||||
for (size_t fi = 0; fi < m->mNumFaces; fi++) {
|
||||
const aiFace &f = m->mFaces[fi];
|
||||
for (size_t pvi = 0; pvi < f.mNumIndices; pvi++) {
|
||||
@@ -1243,7 +1225,7 @@ void FBXExporter::WriteObjects () {
|
||||
if (elem == index_by_uv.end()) {
|
||||
index_by_uv[curUv] = index;
|
||||
uv_indices[uvi].push_back(index);
|
||||
for (uint32_t x = 0; x < nc; ++x) {
|
||||
for (uint32_t x = 0; x < m->mNumUVComponents[uvi]; ++x) {
|
||||
uv_data[uvi].push_back(curUv[x]);
|
||||
}
|
||||
++index;
|
||||
@@ -1253,6 +1235,8 @@ void FBXExporter::WriteObjects () {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
offsets.push_back((int32_t)polygon_data.size());
|
||||
}
|
||||
|
||||
|
||||
@@ -1260,42 +1244,38 @@ void FBXExporter::WriteObjects () {
|
||||
FBX::Node::WritePropertyNode("PolygonVertexIndex", polygon_data, outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("GeometryVersion", int32_t(124), outstream, binary, indent);
|
||||
|
||||
if (!normal_data.empty()) {
|
||||
FBX::Node normals("LayerElementNormal", int32_t(0));
|
||||
normals.Begin(outstream, binary, indent);
|
||||
normals.DumpProperties(outstream, binary, indent);
|
||||
normals.EndProperties(outstream, binary, indent);
|
||||
normals.BeginChildren(outstream, binary, indent);
|
||||
indent = 3;
|
||||
FBX::Node::WritePropertyNode("Version", int32_t(101), outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("Name", "", outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("MappingInformationType", "ByPolygonVertex", outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("ReferenceInformationType", "Direct", outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("Normals", normal_data, outstream, binary, indent);
|
||||
// note: version 102 has a NormalsW also... not sure what it is,
|
||||
// so stick with version 101 for now.
|
||||
indent = 2;
|
||||
normals.End(outstream, binary, indent, true);
|
||||
}
|
||||
FBX::Node normals("LayerElementNormal", int32_t(0));
|
||||
normals.Begin(outstream, binary, indent);
|
||||
normals.DumpProperties(outstream, binary, indent);
|
||||
normals.EndProperties(outstream, binary, indent);
|
||||
normals.BeginChildren(outstream, binary, indent);
|
||||
indent = 3;
|
||||
FBX::Node::WritePropertyNode("Version", int32_t(101),outstream,binary,indent);
|
||||
FBX::Node::WritePropertyNode("Name", "",outstream,binary,indent);
|
||||
FBX::Node::WritePropertyNode("MappingInformationType", "ByPolygonVertex",outstream,binary,indent);
|
||||
FBX::Node::WritePropertyNode("ReferenceInformationType", "Direct",outstream,binary,indent);
|
||||
FBX::Node::WritePropertyNode("Normals", normal_data,outstream,binary,indent);
|
||||
// note: version 102 has a NormalsW also... not sure what it is,
|
||||
// so stick with version 101 for now.
|
||||
indent = 2;
|
||||
normals.End(outstream,binary,indent,true);
|
||||
|
||||
if (!color_data.empty()) {
|
||||
const auto colorChannelIndex = 0;
|
||||
FBX::Node vertexcolors("LayerElementColor", int32_t(colorChannelIndex));
|
||||
vertexcolors.Begin(outstream, binary, indent);
|
||||
vertexcolors.DumpProperties(outstream, binary, indent);
|
||||
vertexcolors.EndProperties(outstream, binary, indent);
|
||||
vertexcolors.BeginChildren(outstream, binary, indent);
|
||||
indent = 3;
|
||||
FBX::Node::WritePropertyNode("Version", int32_t(101), outstream, binary, indent);
|
||||
char layerName[8];
|
||||
snprintf(layerName, sizeof(layerName), "COLOR_%d", colorChannelIndex);
|
||||
FBX::Node::WritePropertyNode("Name", (const char *)layerName, outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("MappingInformationType", "ByPolygonVertex", outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("ReferenceInformationType", "Direct", outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("Colors", color_data, outstream, binary, indent);
|
||||
indent = 2;
|
||||
vertexcolors.End(outstream, binary, indent, true);
|
||||
}
|
||||
const auto colorChannelIndex = 0;
|
||||
FBX::Node vertexcolors("LayerElementColor", int32_t(colorChannelIndex));
|
||||
vertexcolors.Begin(outstream, binary, indent);
|
||||
vertexcolors.DumpProperties(outstream, binary, indent);
|
||||
vertexcolors.EndProperties(outstream, binary, indent);
|
||||
vertexcolors.BeginChildren(outstream, binary, indent);
|
||||
indent = 3;
|
||||
FBX::Node::WritePropertyNode("Version", int32_t(101), outstream, binary, indent);
|
||||
char layerName[8];
|
||||
snprintf(layerName, sizeof(layerName), "COLOR_%d", colorChannelIndex);
|
||||
FBX::Node::WritePropertyNode("Name", (const char *)layerName, outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("MappingInformationType", "ByPolygonVertex", outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("ReferenceInformationType", "Direct", outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("Colors", color_data, outstream, binary, indent);
|
||||
indent = 2;
|
||||
vertexcolors.End(outstream, binary, indent, true);
|
||||
|
||||
for (uint32_t uvi = 0; uvi < uv_data.size(); uvi++) {
|
||||
FBX::Node uv("LayerElementUV", int32_t(uvi));
|
||||
@@ -1306,7 +1286,7 @@ void FBXExporter::WriteObjects () {
|
||||
indent = 3;
|
||||
FBX::Node::WritePropertyNode("Version", int32_t(101), outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("Name", "", outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("MappingInformationType", "ByPolygonVertex", outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("MappingInformationType", "ByPolgonVertex", outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("ReferenceInformationType", "IndexToDirect", outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("UV", uv_data[uvi], outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("UVIndex", uv_indices[uvi], outstream, binary, indent);
|
||||
@@ -1347,21 +1327,15 @@ void FBXExporter::WriteObjects () {
|
||||
// TODO: handle multiple uv sets correctly?
|
||||
FBX::Node layer("Layer", int32_t(0));
|
||||
layer.AddChild("Version", int32_t(100));
|
||||
FBX::Node le;
|
||||
FBX::Node le("LayerElement");
|
||||
le.AddChild("Type", "LayerElementNormal");
|
||||
le.AddChild("TypedIndex", int32_t(0));
|
||||
layer.AddChild(le);
|
||||
|
||||
if (!normal_data.empty()) {
|
||||
le = FBX::Node("LayerElement");
|
||||
le.AddChild("Type", "LayerElementNormal");
|
||||
le.AddChild("TypedIndex", int32_t(0));
|
||||
layer.AddChild(le);
|
||||
}
|
||||
|
||||
if (!color_data.empty()) {
|
||||
le = FBX::Node("LayerElement");
|
||||
le.AddChild("Type", "LayerElementColor");
|
||||
le.AddChild("TypedIndex", int32_t(0));
|
||||
layer.AddChild(le);
|
||||
}
|
||||
le = FBX::Node("LayerElement");
|
||||
le.AddChild("Type", "LayerElementColor");
|
||||
le.AddChild("TypedIndex", int32_t(0));
|
||||
layer.AddChild(le);
|
||||
|
||||
le = FBX::Node("LayerElement");
|
||||
le.AddChild("Type", "LayerElementMaterial");
|
||||
@@ -2055,11 +2029,8 @@ void FBXExporter::WriteObjects () {
|
||||
std::vector<double> subdef_weights;
|
||||
int32_t last_index = -1;
|
||||
for (size_t wi = 0; wi < b->mNumWeights; ++wi) {
|
||||
if (b->mWeights[wi].mVertexId >= vVertexIndice[mi].size()) {
|
||||
ASSIMP_LOG_ERROR("UNREAL: Skipping vertex index to prevent buffer overflow.");
|
||||
continue;
|
||||
}
|
||||
int32_t vi = vVertexIndice[mi][b->mWeights[wi].mVertexId];
|
||||
int32_t vi = vVertexIndice[mi][b->mWeights[wi].mVertexId] \
|
||||
+ uniq_v_before_mi[mi];
|
||||
bool bIsWeightedAlready = (setWeightedVertex.find(vi) != setWeightedVertex.end());
|
||||
if (vi == last_index || bIsWeightedAlready) {
|
||||
// only for vertices we exported to fbx
|
||||
@@ -2539,9 +2510,9 @@ void add_meta(FBX::Node& fbx_node, const aiNode* node){
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// write a single model node to the stream
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -82,7 +82,7 @@ using ElementCollection = std::pair<ElementMap::const_iterator,ElementMap::const
|
||||
* @endverbatim
|
||||
*
|
||||
* As can be seen in this sample, elements can contain nested #Scope
|
||||
* as their trailing member.
|
||||
* as their trailing member.
|
||||
**/
|
||||
class Element {
|
||||
public:
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
@@ -42,8 +43,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//! @file Data structures for the 3D Game Studio Heightmap format (HMP)
|
||||
//!
|
||||
|
||||
namespace Assimp {
|
||||
namespace HMP {
|
||||
namespace Assimp {
|
||||
namespace HMP {
|
||||
|
||||
#include <assimp/Compiler/pushpack1.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -44,7 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#ifndef ASSIMP_BUILD_NO_HMP_IMPORTER
|
||||
|
||||
// internal headers
|
||||
#include "HMPLoader.h"
|
||||
#include "AssetLib/HMP/HMPLoader.h"
|
||||
#include "AssetLib/MD2/MD2FileData.h"
|
||||
|
||||
#include <assimp/StringUtils.h>
|
||||
@@ -81,7 +81,7 @@ HMPImporter::~HMPImporter() = default;
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns whether the class can handle the format of the given file.
|
||||
bool HMPImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
||||
static constexpr uint32_t tokens[] = {
|
||||
static const uint32_t tokens[] = {
|
||||
AI_HMP_MAGIC_NUMBER_LE_4,
|
||||
AI_HMP_MAGIC_NUMBER_LE_5,
|
||||
AI_HMP_MAGIC_NUMBER_LE_7
|
||||
|
||||
@@ -48,7 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <assimp/BaseImporter.h>
|
||||
|
||||
// internal headers
|
||||
#include "HMPFileData.h"
|
||||
#include "AssetLib/HMP/HMPFileData.h"
|
||||
#include "AssetLib/MDL/MDLLoader.h"
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
@@ -52,8 +53,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <assimp/Compiler/pushpack1.h>
|
||||
|
||||
namespace Assimp {
|
||||
namespace MDL {
|
||||
namespace Assimp {
|
||||
namespace MDL {
|
||||
|
||||
// magic bytes used in Half Life 2 MDL models
|
||||
#define AI_MDL_MAGIC_NUMBER_BE_HL2a AI_MAKE_MAGIC("IDST")
|
||||
|
||||
@@ -43,7 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||
|
||||
#include "IFCUtil.h"
|
||||
#include "AssetLib/IFC/IFCUtil.h"
|
||||
#include "Common/PolyTools.h"
|
||||
#include "PostProcessing/ProcessHelper.h"
|
||||
|
||||
@@ -669,7 +669,7 @@ void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const Schema_2x3::IfcPoly
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ProcessBooleanExtrudedAreaSolidDifference(const Schema_2x3::IfcExtrudedAreaSolid *as,
|
||||
void ProcessBooleanExtrudedAreaSolidDifference(const Schema_2x3::IfcExtrudedAreaSolid *as,
|
||||
TempMesh &result,
|
||||
const TempMesh &first_operand,
|
||||
ConversionData &conv) {
|
||||
|
||||
@@ -102,10 +102,10 @@ class Circle : public Conic {
|
||||
public:
|
||||
// --------------------------------------------------
|
||||
Circle(const Schema_2x3::IfcCircle& entity, ConversionData& conv) : Conic(entity,conv) , entity(entity) {}
|
||||
|
||||
|
||||
// --------------------------------------------------
|
||||
~Circle() override = default;
|
||||
|
||||
|
||||
// --------------------------------------------------
|
||||
IfcVector3 Eval(IfcFloat u) const override {
|
||||
u = -conv.angle_scale * u;
|
||||
|
||||
@@ -127,7 +127,7 @@ void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t m
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (outer_polygon_it == end) {
|
||||
return;
|
||||
}
|
||||
@@ -234,7 +234,7 @@ void ProcessRevolvedAreaSolid(const Schema_2x3::IfcRevolvedAreaSolid& solid, Tem
|
||||
return;
|
||||
}
|
||||
|
||||
const unsigned int cnt_segments =
|
||||
const unsigned int cnt_segments =
|
||||
std::max(2u,static_cast<unsigned int>(conv.settings.cylindricalTessellation * std::fabs(max_angle)/AI_MATH_HALF_PI_F));
|
||||
const IfcFloat delta = max_angle/cnt_segments;
|
||||
|
||||
@@ -294,8 +294,8 @@ void ProcessRevolvedAreaSolid(const Schema_2x3::IfcRevolvedAreaSolid& solid, Tem
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ProcessSweptDiskSolid(const Schema_2x3::IfcSweptDiskSolid &solid,
|
||||
TempMesh& result,
|
||||
void ProcessSweptDiskSolid(const Schema_2x3::IfcSweptDiskSolid &solid,
|
||||
TempMesh& result,
|
||||
ConversionData& conv) {
|
||||
const Curve* const curve = Curve::Convert(*solid.Directrix, conv);
|
||||
if(!curve) {
|
||||
@@ -687,9 +687,9 @@ void ProcessExtrudedArea(const Schema_2x3::IfcExtrudedAreaSolid& solid, const Te
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ProcessExtrudedAreaSolid(const Schema_2x3::IfcExtrudedAreaSolid& solid,
|
||||
void ProcessExtrudedAreaSolid(const Schema_2x3::IfcExtrudedAreaSolid& solid,
|
||||
TempMesh& result,
|
||||
ConversionData& conv,
|
||||
ConversionData& conv,
|
||||
bool collect_openings) {
|
||||
TempMesh meshout;
|
||||
|
||||
@@ -728,7 +728,7 @@ void ProcessExtrudedAreaSolid(const Schema_2x3::IfcExtrudedAreaSolid& solid,
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ProcessSweptAreaSolid(const Schema_2x3::IfcSweptAreaSolid& swept,
|
||||
void ProcessSweptAreaSolid(const Schema_2x3::IfcSweptAreaSolid& swept,
|
||||
TempMesh& meshout,
|
||||
ConversionData& conv) {
|
||||
if(const Schema_2x3::IfcExtrudedAreaSolid* const solid = swept.ToPtr<Schema_2x3::IfcExtrudedAreaSolid>()) {
|
||||
@@ -741,8 +741,8 @@ void ProcessSweptAreaSolid(const Schema_2x3::IfcSweptAreaSolid& swept,
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo,
|
||||
unsigned int matid,
|
||||
bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo,
|
||||
unsigned int matid,
|
||||
std::set<unsigned int>& mesh_indices,
|
||||
ConversionData& conv) {
|
||||
bool fix_orientation = false;
|
||||
@@ -841,7 +841,7 @@ void AssignAddedMeshes(std::set<unsigned int>& mesh_indices,aiNode* nd, Conversi
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool TryQueryMeshCache(const Schema_2x3::IfcRepresentationItem& item,
|
||||
std::set<unsigned int>& mesh_indices,
|
||||
std::set<unsigned int>& mesh_indices,
|
||||
unsigned int mat_index,
|
||||
ConversionData& conv) {
|
||||
ConversionData::MeshCacheIndex idx(&item, mat_index);
|
||||
@@ -855,7 +855,7 @@ bool TryQueryMeshCache(const Schema_2x3::IfcRepresentationItem& item,
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void PopulateMeshCache(const Schema_2x3::IfcRepresentationItem& item,
|
||||
const std::set<unsigned int>& mesh_indices,
|
||||
const std::set<unsigned int>& mesh_indices,
|
||||
unsigned int mat_index,
|
||||
ConversionData& conv) {
|
||||
ConversionData::MeshCacheIndex idx(&item, mat_index);
|
||||
@@ -863,7 +863,7 @@ void PopulateMeshCache(const Schema_2x3::IfcRepresentationItem& item,
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool ProcessRepresentationItem(const Schema_2x3::IfcRepresentationItem& item,
|
||||
bool ProcessRepresentationItem(const Schema_2x3::IfcRepresentationItem& item,
|
||||
unsigned int matid,
|
||||
std::set<unsigned int>& mesh_indices,
|
||||
ConversionData& conv) {
|
||||
|
||||
@@ -245,11 +245,11 @@ void IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
||||
|
||||
// tell the reader for which types we need to simulate STEPs reverse indices
|
||||
static const char *const inverse_indices_to_track[] = {
|
||||
"ifcrelcontainedinspatialstructure",
|
||||
"ifcrelaggregates",
|
||||
"ifcrelvoidselement",
|
||||
"ifcreldefinesbyproperties",
|
||||
"ifcpropertyset",
|
||||
"ifcrelcontainedinspatialstructure",
|
||||
"ifcrelaggregates",
|
||||
"ifcrelvoidselement",
|
||||
"ifcreldefinesbyproperties",
|
||||
"ifcpropertyset",
|
||||
"ifcstyleditem"
|
||||
};
|
||||
|
||||
@@ -260,6 +260,8 @@ void IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
||||
ThrowException("missing IfcProject entity");
|
||||
}
|
||||
|
||||
|
||||
|
||||
ConversionData conv(*db, proj->To<Schema_2x3::IfcProject>(), pScene, settings);
|
||||
SetUnits(conv);
|
||||
SetCoordinateSpace(conv);
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -69,7 +69,7 @@ AI_FORCE_INLINE ulong64 to_int64(IfcFloat p) {
|
||||
|
||||
AI_FORCE_INLINE IfcFloat from_int64(ulong64 p) {
|
||||
return (static_cast<IfcFloat>((p)) / max_ulong64);
|
||||
}
|
||||
}
|
||||
|
||||
AI_FORCE_INLINE void fillRectangle(const IfcVector2& pmin, const IfcVector2& pmax, std::vector<IfcVector2>& out) {
|
||||
out.emplace_back(pmin.x, pmin.y);
|
||||
@@ -176,7 +176,7 @@ struct ProjectedWindowContour {
|
||||
SkipList skiplist;
|
||||
bool is_rectangular;
|
||||
|
||||
ProjectedWindowContour(const Contour& contour, const BoundingBox& bb, bool is_rectangular)
|
||||
ProjectedWindowContour(const Contour& contour, const BoundingBox& bb, bool is_rectangular)
|
||||
: contour(contour), bb(bb) , is_rectangular(is_rectangular) {}
|
||||
|
||||
~ProjectedWindowContour() = default;
|
||||
@@ -215,7 +215,7 @@ static bool IsDuplicateVertex(const IfcVector2& vv, const std::vector<IfcVector2
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ExtractVerticesFromClipper(const ClipperLib::Path& poly, std::vector<IfcVector2>& temp_contour,
|
||||
void ExtractVerticesFromClipper(const ClipperLib::Path& poly, std::vector<IfcVector2>& temp_contour,
|
||||
bool filter_duplicates = false) {
|
||||
temp_contour.clear();
|
||||
for(const ClipperLib::IntPoint& point : poly) {
|
||||
@@ -362,7 +362,7 @@ void InsertWindowContours(const ContourVector& contours, const std::vector<TempO
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void MergeWindowContours (const std::vector<IfcVector2>& a, const std::vector<IfcVector2>& b,
|
||||
void MergeWindowContours (const std::vector<IfcVector2>& a, const std::vector<IfcVector2>& b,
|
||||
ClipperLib::Paths& out) {
|
||||
out.clear();
|
||||
|
||||
@@ -988,16 +988,16 @@ void Quadrify(const ContourVector& contours, TempMesh& curmesh) {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour,
|
||||
IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour,
|
||||
const TempMesh& in_mesh,
|
||||
bool &ok,
|
||||
bool &ok,
|
||||
IfcVector3& nor_out) {
|
||||
const std::vector<IfcVector3>& in_verts = in_mesh.mVerts;
|
||||
if (in_verts.empty()){
|
||||
ok = false;
|
||||
return IfcMatrix4();
|
||||
}
|
||||
|
||||
|
||||
ok = true;
|
||||
IfcMatrix4 m = IfcMatrix4(DerivePlaneCoordinateSpace(in_mesh, ok, nor_out));
|
||||
if(!ok) {
|
||||
|
||||
@@ -50,8 +50,8 @@ namespace Assimp {
|
||||
namespace IFC {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ProcessPolyLine(const Schema_2x3::IfcPolyline& def,
|
||||
TempMesh& meshout,
|
||||
void ProcessPolyLine(const Schema_2x3::IfcPolyline& def,
|
||||
TempMesh& meshout,
|
||||
ConversionData& /*conv*/) {
|
||||
// this won't produce a valid mesh, it just spits out a list of vertices
|
||||
IfcVector3 t;
|
||||
@@ -63,8 +63,8 @@ void ProcessPolyLine(const Schema_2x3::IfcPolyline& def,
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool ProcessCurve(const Schema_2x3::IfcCurve& curve,
|
||||
TempMesh& meshout,
|
||||
bool ProcessCurve(const Schema_2x3::IfcCurve& curve,
|
||||
TempMesh& meshout,
|
||||
ConversionData& conv) {
|
||||
std::unique_ptr<const Curve> cv(Curve::Convert(curve,conv));
|
||||
if (!cv) {
|
||||
@@ -90,22 +90,22 @@ bool ProcessCurve(const Schema_2x3::IfcCurve& curve,
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ProcessClosedProfile(const Schema_2x3::IfcArbitraryClosedProfileDef& def,
|
||||
TempMesh& meshout,
|
||||
void ProcessClosedProfile(const Schema_2x3::IfcArbitraryClosedProfileDef& def,
|
||||
TempMesh& meshout,
|
||||
ConversionData& conv) {
|
||||
ProcessCurve(def.OuterCurve,meshout,conv);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ProcessOpenProfile(const Schema_2x3::IfcArbitraryOpenProfileDef& def,
|
||||
TempMesh& meshout,
|
||||
void ProcessOpenProfile(const Schema_2x3::IfcArbitraryOpenProfileDef& def,
|
||||
TempMesh& meshout,
|
||||
ConversionData& conv) {
|
||||
ProcessCurve(def.Curve,meshout,conv);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ProcessParametrizedProfile(const Schema_2x3::IfcParameterizedProfileDef& def,
|
||||
TempMesh& meshout,
|
||||
void ProcessParametrizedProfile(const Schema_2x3::IfcParameterizedProfileDef& def,
|
||||
TempMesh& meshout,
|
||||
ConversionData& conv) {
|
||||
if(const Schema_2x3::IfcRectangleProfileDef* const cprofile = def.ToPtr<Schema_2x3::IfcRectangleProfileDef>()) {
|
||||
const IfcFloat x = cprofile->XDim*0.5f, y = cprofile->YDim*0.5f;
|
||||
|
||||
@@ -44,7 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||
|
||||
#include "IFCUtil.h"
|
||||
#include "AssetLib/IFC/IFCUtil.h"
|
||||
#include "Common/PolyTools.h"
|
||||
#include "Geometry/GeometryUtils.h"
|
||||
#include "PostProcessing/ProcessHelper.h"
|
||||
@@ -375,7 +375,7 @@ void TempMesh::RemoveAdjacentDuplicates() {
|
||||
ArrayBounds(&*base, cnt ,vmin,vmax);
|
||||
|
||||
const IfcFloat epsilon = (vmax-vmin).SquareLength() / static_cast<IfcFloat>(1e9);
|
||||
|
||||
|
||||
// drop any identical, adjacent vertices. this pass will collect the dropouts
|
||||
// of the previous pass as a side-effect.
|
||||
FuzzyVectorCompare fz(epsilon);
|
||||
@@ -461,7 +461,7 @@ void ConvertColor(aiColor4D& out, const Schema_2x3::IfcColourRgb& in) {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertColor(aiColor4D& out,
|
||||
void ConvertColor(aiColor4D& out,
|
||||
const Schema_2x3::IfcColourOrFactor& in,
|
||||
ConversionData& conv,
|
||||
const aiColor4D* base) {
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
@@ -46,8 +47,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#ifndef INCLUDED_IFCUTIL_H
|
||||
#define INCLUDED_IFCUTIL_H
|
||||
|
||||
#include "IFCReaderGen_2x3.h"
|
||||
#include "IFCLoader.h"
|
||||
#include "AssetLib/IFC/IFCReaderGen_2x3.h"
|
||||
#include "AssetLib/IFC/IFCLoader.h"
|
||||
#include "AssetLib/Step/STEPFile.h"
|
||||
|
||||
#include <assimp/mesh.h>
|
||||
|
||||
@@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "assimp/StringComparison.h"
|
||||
#ifndef ASSIMP_BUILD_NO_IRR_IMPORTER
|
||||
|
||||
#include "IRRLoader.h"
|
||||
#include "AssetLib/Irr/IRRLoader.h"
|
||||
#include "Common/Importer.h"
|
||||
|
||||
#include <assimp/GenericProperty.h>
|
||||
|
||||
@@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#ifndef AI_IRRLOADER_H_INCLUDED
|
||||
#define AI_IRRLOADER_H_INCLUDED
|
||||
|
||||
#include "IRRShared.h"
|
||||
#include "AssetLib/Irr/IRRShared.h"
|
||||
#include "Common/Importer.h"
|
||||
|
||||
#include <assimp/SceneCombiner.h>
|
||||
|
||||
@@ -322,7 +322,7 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
|
||||
// NOTE this might explode for UTF-16 and wchars
|
||||
const char *sz = indicesNode.text().get();
|
||||
const char *end = sz + std::strlen(sz);
|
||||
|
||||
|
||||
// For each index loop over aiMesh faces
|
||||
while (SkipSpacesAndLineEnd(&sz, end)) {
|
||||
if (curFace >= faceEnd) {
|
||||
@@ -380,7 +380,7 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
|
||||
aiMaterial *mat = (aiMaterial *)curMat;
|
||||
mat->AddProperty(&curColors[0].a, 1, AI_MATKEY_OPACITY);
|
||||
}
|
||||
|
||||
|
||||
// end of previous buffer. A material and a mesh should be there
|
||||
if (!curMat || !curMesh) {
|
||||
ASSIMP_LOG_ERROR("IRRMESH: A buffer must contain a mesh and a material");
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -78,7 +78,7 @@ void LWOImporter::LoadLWOBFile() {
|
||||
else
|
||||
LoadLWOBPolygons(head.length);
|
||||
} break;
|
||||
|
||||
|
||||
case AI_LWO_SRFS: // list of tags
|
||||
{
|
||||
if (!mTags->empty())
|
||||
|
||||
@@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
|
||||
|
||||
// internal headers
|
||||
#include "LWOLoader.h"
|
||||
#include "AssetLib/LWO/LWOLoader.h"
|
||||
#include "PostProcessing/ConvertToLHProcess.h"
|
||||
#include "PostProcessing/ProcessHelper.h"
|
||||
#include "Geometry/GeometryUtils.h"
|
||||
@@ -104,7 +104,7 @@ LWOImporter::~LWOImporter() = default;
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns whether the class can handle the format of the given file.
|
||||
bool LWOImporter::CanRead(const std::string &file, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
||||
static constexpr uint32_t tokens[] = {
|
||||
static const uint32_t tokens[] = {
|
||||
AI_LWO_FOURCC_LWOB,
|
||||
AI_LWO_FOURCC_LWO2,
|
||||
AI_LWO_FOURCC_LXOB
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -45,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_LWS_IMPORTER
|
||||
|
||||
#include "LWSLoader.h"
|
||||
#include "AssetLib/LWS/LWSLoader.h"
|
||||
#include "Common/Importer.h"
|
||||
#include "PostProcessing/ConvertToLHProcess.h"
|
||||
|
||||
@@ -149,7 +149,7 @@ LWSImporter::LWSImporter() :
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns whether the class can handle the format of the given file.
|
||||
bool LWSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
||||
static constexpr uint32_t tokens[] = {
|
||||
static const uint32_t tokens[] = {
|
||||
AI_MAKE_MAGIC("LWSC"),
|
||||
AI_MAKE_MAGIC("LWMO")
|
||||
};
|
||||
@@ -255,7 +255,7 @@ void LWSImporter::ReadEnvelope(const LWS::Element &dad, LWO::Envelope &fill) {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Read animation channels in the old LightWave animation format
|
||||
void LWSImporter::ReadEnvelope_Old(std::list<LWS::Element>::const_iterator &it,const std::list<LWS::Element>::const_iterator &endIt,
|
||||
void LWSImporter::ReadEnvelope_Old(std::list<LWS::Element>::const_iterator &it,const std::list<LWS::Element>::const_iterator &endIt,
|
||||
LWS::NodeDesc &nodes, unsigned int) {
|
||||
if (++it == endIt) {
|
||||
ASSIMP_LOG_ERROR("LWS: Encountered unexpected end of file while parsing object motion");
|
||||
@@ -274,7 +274,7 @@ void LWSImporter::ReadEnvelope_Old(std::list<LWS::Element>::const_iterator &it,c
|
||||
ASSIMP_LOG_ERROR("LWS: Encountered unexpected end of file while parsing object motion");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const unsigned int sub_num = strtoul10((*it).tokens[0].c_str());
|
||||
for (unsigned int n = 0; n < sub_num; ++n) {
|
||||
if (++it == endIt) {
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
@@ -51,8 +52,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <assimp/Compiler/pushpack1.h>
|
||||
|
||||
namespace Assimp {
|
||||
namespace MD2 {
|
||||
namespace Assimp {
|
||||
namespace MD2 {
|
||||
|
||||
// to make it easier for us, we test the magic word against both "endiannesses"
|
||||
#define AI_MD2_MAGIC_NUMBER_BE AI_MAKE_MAGIC("IDP2")
|
||||
|
||||
@@ -101,7 +101,7 @@ MD2Importer::MD2Importer()
|
||||
// Returns whether the class can handle the format of the given file.
|
||||
bool MD2Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const
|
||||
{
|
||||
static constexpr uint32_t tokens[] = { AI_MD2_MAGIC_NUMBER_LE };
|
||||
static const uint32_t tokens[] = { AI_MD2_MAGIC_NUMBER_LE };
|
||||
return CheckMagicToken(pIOHandler,pFile,tokens,AI_COUNT_OF(tokens));
|
||||
}
|
||||
|
||||
@@ -319,22 +319,16 @@ void MD2Importer::InternReadFile( const std::string& pFile,
|
||||
clr.b = clr.g = clr.r = 0.05f;
|
||||
pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
|
||||
|
||||
const ai_uint32 MaxNameLength = AI_MAXLEN - 1; // one byte reserved for \0
|
||||
ai_uint32 iLen = static_cast<ai_uint32>(::strlen(pcSkins->name));
|
||||
bool nameTooLong = iLen > MaxNameLength;
|
||||
|
||||
if (pcSkins->name[0] && !nameTooLong)
|
||||
if (pcSkins->name[0])
|
||||
{
|
||||
aiString szString;
|
||||
::memcpy(szString.data, pcSkins->name, iLen);
|
||||
const ai_uint32 iLen = (ai_uint32) ::strlen(pcSkins->name);
|
||||
::memcpy(szString.data,pcSkins->name,iLen);
|
||||
szString.data[iLen] = '\0';
|
||||
szString.length = iLen;
|
||||
|
||||
pcHelper->AddProperty(&szString,AI_MATKEY_TEXTURE_DIFFUSE(0));
|
||||
}
|
||||
else if (nameTooLong) {
|
||||
ASSIMP_LOG_WARN("Texture file name is too long. It will be skipped.");
|
||||
}
|
||||
else{
|
||||
ASSIMP_LOG_WARN("Texture file name has zero length. It will be skipped.");
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
@@ -59,7 +60,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <assimp/Compiler/pushpack1.h>
|
||||
|
||||
namespace Assimp {
|
||||
namespace MD3 {
|
||||
namespace MD3 {
|
||||
|
||||
// to make it easier for us, we test the magic word against both "endiannesses"
|
||||
#define AI_MD3_MAGIC_NUMBER_BE AI_MAKE_MAGIC("IDP3")
|
||||
|
||||
@@ -5,6 +5,8 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
@@ -50,7 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_MD3_IMPORTER
|
||||
|
||||
#include "MD3Loader.h"
|
||||
#include "AssetLib/MD3/MD3Loader.h"
|
||||
#include "Common/Importer.h"
|
||||
|
||||
#include <assimp/GenericProperty.h>
|
||||
@@ -350,7 +352,7 @@ MD3Importer::~MD3Importer() = default;
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns whether the class can handle the format of the given file.
|
||||
bool MD3Importer::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
||||
static constexpr uint32_t tokens[] = { AI_MD3_MAGIC_NUMBER_LE };
|
||||
static const uint32_t tokens[] = { AI_MD3_MAGIC_NUMBER_LE };
|
||||
return CheckMagicToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// internal headers
|
||||
#include "MD5Loader.h"
|
||||
#include "AssetLib/MD5/MD5Loader.h"
|
||||
#include "Material/MaterialSystem.h"
|
||||
|
||||
#include <assimp/ParsingUtils.h>
|
||||
@@ -127,7 +127,7 @@ void MD5Parser::ParseHeader() {
|
||||
if (buffer == bufferEnd) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ASSIMP_LOG_INFO(std::string(sz, std::min((uintptr_t)MAX_LOG_MESSAGE_LENGTH, (uintptr_t)(buffer - sz))));
|
||||
SkipSpacesAndLineEnd();
|
||||
}
|
||||
@@ -291,7 +291,7 @@ inline void AI_MD5_PARSE_STRING_IN_QUOTATION(const char **sz, const char *buffer
|
||||
}
|
||||
if ('\0' != **sz) {
|
||||
const char *szStart = ++(*sz);
|
||||
|
||||
|
||||
while (('\"' != **sz && '\0' != **sz) && *sz != bufferEnd) {
|
||||
++*sz;
|
||||
}
|
||||
@@ -324,7 +324,7 @@ MD5MeshParser::MD5MeshParser(SectionArray &mSections) {
|
||||
|
||||
const char *sz = elem.szStart;
|
||||
AI_MD5_PARSE_STRING_IN_QUOTATION(&sz, elem.end, desc.mName);
|
||||
|
||||
|
||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||
|
||||
// negative values, at least -1, is allowed here
|
||||
|
||||
@@ -422,7 +422,7 @@ inline bool MD5Parser::SkipSpacesAndLineEnd( const char* in, const char** out) {
|
||||
*out = in;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool bHad = false, running = true;
|
||||
while (running) {
|
||||
if( *in == '\r' || *in == '\n') {
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -44,9 +44,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#ifndef ASSIMP_BUILD_NO_MDC_IMPORTER
|
||||
|
||||
// internal headers
|
||||
#include "MDCLoader.h"
|
||||
#include "AssetLib/MDC/MDCLoader.h"
|
||||
#include "AssetLib/MD3/MD3FileData.h"
|
||||
#include "MDCNormalTable.h" // shouldn't be included by other units
|
||||
#include "AssetLib/MDC/MDCNormalTable.h" // shouldn't be included by other units
|
||||
|
||||
#include <assimp/importerdesc.h>
|
||||
#include <assimp/scene.h>
|
||||
@@ -106,7 +106,7 @@ MDCImporter::MDCImporter() :
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns whether the class can handle the format of the given file.
|
||||
bool MDCImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
||||
static constexpr uint32_t tokens[] = { AI_MDC_MAGIC_NUMBER_LE };
|
||||
static const uint32_t tokens[] = { AI_MDC_MAGIC_NUMBER_LE };
|
||||
return CheckMagicToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
@@ -62,8 +63,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
struct aiMaterial;
|
||||
|
||||
namespace Assimp {
|
||||
namespace MDL {
|
||||
namespace Assimp {
|
||||
namespace MDL {
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
// to make it easier for us, we test the magic word against both "endiannesses"
|
||||
@@ -602,7 +603,7 @@ struct Vertex_MDL7
|
||||
union {
|
||||
uint8_t norm162index;
|
||||
float norm[3];
|
||||
} PACK_STRUCT;
|
||||
};
|
||||
} PACK_STRUCT;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
@@ -48,10 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_MDL_IMPORTER
|
||||
|
||||
#include "MDLLoader.h"
|
||||
#include "AssetLib/MDL/MDLLoader.h"
|
||||
#include "AssetLib/MD2/MD2FileData.h"
|
||||
#include "HalfLife/HL1MDLLoader.h"
|
||||
#include "MDLDefaultColorMap.h"
|
||||
#include "AssetLib/MDL/HalfLife/HL1MDLLoader.h"
|
||||
#include "AssetLib/MDL/MDLDefaultColorMap.h"
|
||||
|
||||
#include <assimp/StringUtils.h>
|
||||
#include <assimp/importerdesc.h>
|
||||
@@ -268,8 +268,8 @@ void MDLImporter::InternReadFile(const std::string &pFile,
|
||||
// Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
|
||||
pScene->mRootNode->mTransformation = aiMatrix4x4(
|
||||
1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f,
|
||||
0.f, -1.f, 0.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f,
|
||||
0.f, -1.f, 0.f, 0.f,
|
||||
0.f, 0.f, 0.f, 1.f);
|
||||
}
|
||||
|
||||
@@ -420,7 +420,7 @@ void MDLImporter::InternReadFile_Quake1() {
|
||||
}
|
||||
// go to the end of the skin section / the beginning of the next skin
|
||||
bool overflow = false;
|
||||
if (pcHeader->skinwidth != 0 && pcHeader->skinheight != 0) {
|
||||
if (pcHeader->skinwidth != 0 || pcHeader->skinheight != 0) {
|
||||
if ((pcHeader->skinheight > INT_MAX / pcHeader->skinwidth) || (pcHeader->skinwidth > INT_MAX / pcHeader->skinheight)){
|
||||
overflow = true;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <assimp/BaseImporter.h>
|
||||
#include "MDLFileData.h"
|
||||
#include "AssetLib/HMP/HalfLifeFileData.h"
|
||||
#include "HalfLife/HL1ImportSettings.h"
|
||||
#include "AssetLib/MDL/HalfLife/HL1ImportSettings.h"
|
||||
|
||||
struct aiNode;
|
||||
struct aiTexture;
|
||||
|
||||
@@ -209,8 +209,6 @@ void MDLImporter::CreateTexture_3DGS_MDL4(const unsigned char *szData,
|
||||
return;
|
||||
}
|
||||
|
||||
static const uint32_t MaxTextureSize = 4096;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Load color data of a texture and convert it to our output format
|
||||
void MDLImporter::ParseTextureColorData(const unsigned char *szData,
|
||||
@@ -221,11 +219,6 @@ void MDLImporter::ParseTextureColorData(const unsigned char *szData,
|
||||
|
||||
// allocate storage for the texture image
|
||||
if (do_read) {
|
||||
// check for max texture sizes
|
||||
if (pcNew->mWidth > MaxTextureSize || pcNew->mHeight > MaxTextureSize) {
|
||||
throw DeadlyImportError("Invalid MDL file. A texture is too big.");
|
||||
}
|
||||
|
||||
if(pcNew->mWidth != 0 && pcNew->mHeight > UINT_MAX/pcNew->mWidth) {
|
||||
throw DeadlyImportError("Invalid MDL file. A texture is too big.");
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -41,10 +41,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
|
||||
|
||||
#include "MMDImporter.h"
|
||||
#include "MMDPmdParser.h"
|
||||
#include "MMDPmxParser.h"
|
||||
#include "MMDVmdParser.h"
|
||||
#include "AssetLib/MMD/MMDImporter.h"
|
||||
#include "AssetLib/MMD/MMDPmdParser.h"
|
||||
#include "AssetLib/MMD/MMDPmxParser.h"
|
||||
#include "AssetLib/MMD/MMDVmdParser.h"
|
||||
#include "PostProcessing/ConvertToLHProcess.h"
|
||||
|
||||
#include <assimp/DefaultIOSystem.h>
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2025, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user