Merge branch 'master' into master
commit
03163a1dda
|
@ -1,2 +0,0 @@
|
||||||
service_name: travis-pro
|
|
||||||
repo_token: GZXuNlublKFy7HAewHAZLk5ZwgipTFAOA
|
|
|
@ -99,7 +99,7 @@ jobs:
|
||||||
- name: Set Windows specific CMake arguments
|
- name: Set Windows specific CMake arguments
|
||||||
if: contains(matrix.name, 'windows')
|
if: contains(matrix.name, 'windows')
|
||||||
id: windows_extra_cmake_args
|
id: windows_extra_cmake_args
|
||||||
run: echo "::set-output name=args::-DASSIMP_BUILD_ASSIMP_TOOLS=1 -DASSIMP_BUILD_ASSIMP_VIEW=1"
|
run: echo "::set-output name=args::-DASSIMP_BUILD_ASSIMP_TOOLS=1 -DASSIMP_BUILD_ASSIMP_VIEW=1 -DASSIMP_BUILD_ZLIB=1"
|
||||||
|
|
||||||
- name: Set Hunter specific CMake arguments
|
- name: Set Hunter specific CMake arguments
|
||||||
if: contains(matrix.name, 'hunter')
|
if: contains(matrix.name, 'hunter')
|
||||||
|
|
|
@ -57,3 +57,13 @@ jobs:
|
||||||
- name: test
|
- name: test
|
||||||
run: cd build/bin && ./unit
|
run: cd build/bin && ./unit
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
|
job3:
|
||||||
|
name: printf-sanitizer
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: run scan_printf script
|
||||||
|
run: ./scripts/scan_printf.sh
|
||||||
|
shell: bash
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Open Asset Import Library (assimp)
|
# Open Asset Import Library (assimp)
|
||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
# Copyright (c) 2006-2022, assimp team
|
# Copyright (c) 2006-2023, assimp team
|
||||||
#
|
#
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
|
@ -84,10 +84,6 @@ OPTION( ASSIMP_NO_EXPORT
|
||||||
"Disable Assimp's export functionality."
|
"Disable Assimp's export functionality."
|
||||||
OFF
|
OFF
|
||||||
)
|
)
|
||||||
OPTION( ASSIMP_BUILD_ZLIB
|
|
||||||
"Build your own zlib"
|
|
||||||
OFF
|
|
||||||
)
|
|
||||||
OPTION( ASSIMP_BUILD_ASSIMP_TOOLS
|
OPTION( ASSIMP_BUILD_ASSIMP_TOOLS
|
||||||
"If the supplementary tools for Assimp are built in addition to the library."
|
"If the supplementary tools for Assimp are built in addition to the library."
|
||||||
OFF
|
OFF
|
||||||
|
@ -134,6 +130,18 @@ OPTION ( ASSIMP_IGNORE_GIT_HASH
|
||||||
OFF
|
OFF
|
||||||
)
|
)
|
||||||
|
|
||||||
|
IF (WIN32)
|
||||||
|
OPTION( ASSIMP_BUILD_ZLIB
|
||||||
|
"Build your own zlib"
|
||||||
|
ON
|
||||||
|
)
|
||||||
|
ELSE()
|
||||||
|
OPTION( ASSIMP_BUILD_ZLIB
|
||||||
|
"Build your own zlib"
|
||||||
|
ON
|
||||||
|
)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
IF (WIN32)
|
IF (WIN32)
|
||||||
# Use subset of Windows.h
|
# Use subset of Windows.h
|
||||||
ADD_DEFINITIONS( -DWIN32_LEAN_AND_MEAN )
|
ADD_DEFINITIONS( -DWIN32_LEAN_AND_MEAN )
|
||||||
|
@ -262,13 +270,13 @@ IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT MINGW)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
# hide all not-exported symbols
|
# hide all not-exported symbols
|
||||||
IF(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "mips64" )
|
IF(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "mips64" )
|
||||||
SET(CMAKE_CXX_FLAGS "-mxgot -fvisibility=hidden -fno-strict-aliasing -Wall ${CMAKE_CXX_FLAGS}")
|
SET(CMAKE_CXX_FLAGS "-mxgot -fvisibility=hidden -fno-strict-aliasing -Wall ${CMAKE_CXX_FLAGS}")
|
||||||
SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
|
SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
|
||||||
SET(LIBSTDC++_LIBRARIES -lstdc++)
|
SET(LIBSTDC++_LIBRARIES -lstdc++)
|
||||||
ELSE()
|
ELSE()
|
||||||
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall ${CMAKE_CXX_FLAGS}")
|
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall ${CMAKE_CXX_FLAGS}")
|
||||||
SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
|
SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
|
||||||
SET(LIBSTDC++_LIBRARIES -lstdc++)
|
SET(LIBSTDC++_LIBRARIES -lstdc++)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ELSEIF(MSVC)
|
ELSEIF(MSVC)
|
||||||
# enable multi-core compilation with MSVC
|
# enable multi-core compilation with MSVC
|
||||||
|
@ -277,13 +285,15 @@ ELSEIF(MSVC)
|
||||||
ELSE() # msvc
|
ELSE() # msvc
|
||||||
ADD_COMPILE_OPTIONS(/MP /bigobj /W4 /WX)
|
ADD_COMPILE_OPTIONS(/MP /bigobj /W4 /WX)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
# disable "elements of array '' will be default initialized" warning on MSVC2013
|
# disable "elements of array '' will be default initialized" warning on MSVC2013
|
||||||
IF(MSVC12)
|
IF(MSVC12)
|
||||||
ADD_COMPILE_OPTIONS(/wd4351)
|
ADD_COMPILE_OPTIONS(/wd4351)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ADD_COMPILE_OPTIONS(/wd4244) #supress warning for double to float conversion if Double precission is activated
|
# supress warning for double to float conversion if Double precission is activated
|
||||||
|
ADD_COMPILE_OPTIONS(/wd4244)
|
||||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_DEBUG /Zi /Od")
|
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_DEBUG /Zi /Od")
|
||||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
|
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
|
||||||
SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG:FULL /PDBALTPATH:%_PDB% /OPT:REF /OPT:ICF")
|
SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG:FULL /PDBALTPATH:%_PDB% /OPT:REF /OPT:ICF")
|
||||||
ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||||
IF(NOT ASSIMP_HUNTER_ENABLED)
|
IF(NOT ASSIMP_HUNTER_ENABLED)
|
||||||
|
@ -388,14 +398,6 @@ IF (NOT TARGET uninstall AND ASSIMP_INSTALL)
|
||||||
ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
# cmake configuration files
|
|
||||||
if(${BUILD_SHARED_LIBS})
|
|
||||||
set(BUILD_LIB_TYPE SHARED)
|
|
||||||
else()
|
|
||||||
set(BUILD_LIB_TYPE STATIC)
|
|
||||||
add_definitions(-DDDL_STATIC_LIBRARY=OFF)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
IF( UNIX )
|
IF( UNIX )
|
||||||
# Use GNUInstallDirs for Unix predefined directories
|
# Use GNUInstallDirs for Unix predefined directories
|
||||||
INCLUDE(GNUInstallDirs)
|
INCLUDE(GNUInstallDirs)
|
||||||
|
@ -488,7 +490,11 @@ ELSE()
|
||||||
FIND_PACKAGE(ZLIB)
|
FIND_PACKAGE(ZLIB)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF( NOT ZLIB_FOUND )
|
IF ( NOT ZLIB_FOUND AND NOT ASSIMP_BUILD_ZLIB )
|
||||||
|
message( FATAL_ERROR
|
||||||
|
"Build configured with -DASSIMP_BUILD_ZLIB=OFF but unable to find zlib"
|
||||||
|
)
|
||||||
|
ELSEIF( NOT ZLIB_FOUND )
|
||||||
MESSAGE(STATUS "compiling zlib from sources")
|
MESSAGE(STATUS "compiling zlib from sources")
|
||||||
INCLUDE(CheckIncludeFile)
|
INCLUDE(CheckIncludeFile)
|
||||||
INCLUDE(CheckTypeSize)
|
INCLUDE(CheckTypeSize)
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
We as members, contributors, and leaders pledge to make participation in our
|
||||||
|
community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||||
|
identity and expression, level of experience, education, socio-economic status,
|
||||||
|
nationality, personal appearance, race, religion, or sexual identity
|
||||||
|
and orientation.
|
||||||
|
|
||||||
|
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||||
|
diverse, inclusive, and healthy community.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to a positive environment for our
|
||||||
|
community include:
|
||||||
|
|
||||||
|
* Demonstrating empathy and kindness toward other people
|
||||||
|
* Being respectful of differing opinions, viewpoints, and experiences
|
||||||
|
* Giving and gracefully accepting constructive feedback
|
||||||
|
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||||
|
and learning from the experience
|
||||||
|
* Focusing on what is best not just for us as individuals, but for the
|
||||||
|
overall community
|
||||||
|
|
||||||
|
Examples of unacceptable behavior include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery, and sexual attention or
|
||||||
|
advances of any kind
|
||||||
|
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or email
|
||||||
|
address, without their explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Enforcement Responsibilities
|
||||||
|
|
||||||
|
Community leaders are responsible for clarifying and enforcing our standards of
|
||||||
|
acceptable behavior and will take appropriate and fair corrective action in
|
||||||
|
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||||
|
or harmful.
|
||||||
|
|
||||||
|
Community leaders have the right and responsibility to remove, edit, or reject
|
||||||
|
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||||
|
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||||
|
decisions when appropriate.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies within all community spaces, and also applies when
|
||||||
|
an individual is officially representing the community in public spaces.
|
||||||
|
Examples of representing our community include using an official e-mail address,
|
||||||
|
posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported to the community leaders responsible for enforcement at
|
||||||
|
.
|
||||||
|
All complaints will be reviewed and investigated promptly and fairly.
|
||||||
|
|
||||||
|
All community leaders are obligated to respect the privacy and security of the
|
||||||
|
reporter of any incident.
|
||||||
|
|
||||||
|
## Enforcement Guidelines
|
||||||
|
|
||||||
|
Community leaders will follow these Community Impact Guidelines in determining
|
||||||
|
the consequences for any action they deem in violation of this Code of Conduct:
|
||||||
|
|
||||||
|
### 1. Correction
|
||||||
|
|
||||||
|
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||||
|
unprofessional or unwelcome in the community.
|
||||||
|
|
||||||
|
**Consequence**: A private, written warning from community leaders, providing
|
||||||
|
clarity around the nature of the violation and an explanation of why the
|
||||||
|
behavior was inappropriate. A public apology may be requested.
|
||||||
|
|
||||||
|
### 2. Warning
|
||||||
|
|
||||||
|
**Community Impact**: A violation through a single incident or series
|
||||||
|
of actions.
|
||||||
|
|
||||||
|
**Consequence**: A warning with consequences for continued behavior. No
|
||||||
|
interaction with the people involved, including unsolicited interaction with
|
||||||
|
those enforcing the Code of Conduct, for a specified period of time. This
|
||||||
|
includes avoiding interactions in community spaces as well as external channels
|
||||||
|
like social media. Violating these terms may lead to a temporary or
|
||||||
|
permanent ban.
|
||||||
|
|
||||||
|
### 3. Temporary Ban
|
||||||
|
|
||||||
|
**Community Impact**: A serious violation of community standards, including
|
||||||
|
sustained inappropriate behavior.
|
||||||
|
|
||||||
|
**Consequence**: A temporary ban from any sort of interaction or public
|
||||||
|
communication with the community for a specified period of time. No public or
|
||||||
|
private interaction with the people involved, including unsolicited interaction
|
||||||
|
with those enforcing the Code of Conduct, is allowed during this period.
|
||||||
|
Violating these terms may lead to a permanent ban.
|
||||||
|
|
||||||
|
### 4. Permanent Ban
|
||||||
|
|
||||||
|
**Community Impact**: Demonstrating a pattern of violation of community
|
||||||
|
standards, including sustained inappropriate behavior, harassment of an
|
||||||
|
individual, or aggression toward or disparagement of classes of individuals.
|
||||||
|
|
||||||
|
**Consequence**: A permanent ban from any sort of public interaction within
|
||||||
|
the community.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||||
|
version 2.0, available at
|
||||||
|
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||||
|
|
||||||
|
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||||
|
enforcement ladder](https://github.com/mozilla/diversity).
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see the FAQ at
|
||||||
|
https://www.contributor-covenant.org/faq. Translations are available at
|
||||||
|
https://www.contributor-covenant.org/translations.
|
38
Readme.md
38
Readme.md
|
@ -1,6 +1,8 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
==================================
|
==================================
|
||||||
A library to import and export various 3d-model-formats including scene-post-processing to generate missing render data.
|
|
||||||
|
Open Asset Import Library is a library to load 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 ###
|
||||||
[![Financial Contributors on Open Collective](https://opencollective.com/assimp/all/badge.svg?label=financial+contributors)](https://opencollective.com/assimp)
|
[![Financial Contributors on Open Collective](https://opencollective.com/assimp/all/badge.svg?label=financial+contributors)](https://opencollective.com/assimp)
|
||||||
![C/C++ CI](https://github.com/assimp/assimp/workflows/C/C++%20CI/badge.svg)
|
![C/C++ CI](https://github.com/assimp/assimp/workflows/C/C++%20CI/badge.svg)
|
||||||
|
@ -14,7 +16,6 @@ A library to import and export various 3d-model-formats including scene-post-pro
|
||||||
[![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue")
|
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue")
|
||||||
[![Percentage of issues still open](http://isitmaintained.com/badge/open/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Percentage of issues still open")
|
[![Percentage of issues still open](http://isitmaintained.com/badge/open/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Percentage of issues still open")
|
||||||
[![Total alerts](https://img.shields.io/lgtm/alerts/g/assimp/assimp.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/assimp/assimp/alerts/)
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
|
APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
|
||||||
|
@ -23,15 +24,19 @@ Additionally, assimp features various __mesh post processing tools__: normals an
|
||||||
### Latest Doc's ###
|
### Latest Doc's ###
|
||||||
Please check the latest documents at [Asset-Importer-Lib-Doc](https://assimp-docs.readthedocs.io/en/latest/).
|
Please check the latest documents at [Asset-Importer-Lib-Doc](https://assimp-docs.readthedocs.io/en/latest/).
|
||||||
|
|
||||||
### Get involved ###
|
### Prebuild binaries ###
|
||||||
This is the development repo containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [Github Assimp Releases](https://github.com/assimp/assimp/releases).
|
Please check our [Itchi Projectspace](https://kimkulling.itch.io/the-asset-importer-lib)
|
||||||
<br>
|
|
||||||
You find a bug in the docs? Use [Doc-Repo](https://github.com/assimp/assimp-docs).
|
|
||||||
<br>
|
|
||||||
Please check our Wiki as well: https://github.com/assimp/assimp/wiki
|
|
||||||
|
|
||||||
If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
|
If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
|
||||||
|
|
||||||
|
### Communities ###
|
||||||
|
- Ask a question at [The Assimp-Discussion Board](https://github.com/assimp/assimp/discussions)
|
||||||
|
- Ask on [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).
|
||||||
|
- Nothing has worked? File a question or an issue-report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues)
|
||||||
|
|
||||||
|
And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
|
||||||
|
|
||||||
#### Supported file formats ####
|
#### Supported file formats ####
|
||||||
You can find the complete list of supported file-formats [here](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md)
|
You can find the complete list of supported file-formats [here](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md)
|
||||||
|
|
||||||
|
@ -66,25 +71,18 @@ Open Asset Import Library is implemented in C++. The directory structure looks l
|
||||||
/port Ports to other languages and scripts to maintain those.
|
/port Ports to other languages and scripts to maintain those.
|
||||||
/test Unit- and regression tests, test suite of models
|
/test Unit- and regression tests, test suite of models
|
||||||
/tools Tools (old assimp viewer, command line `assimp`)
|
/tools Tools (old assimp viewer, command line `assimp`)
|
||||||
/samples A small number of samples to illustrate possible
|
/samples A small number of samples to illustrate possible use-cases for Assimp
|
||||||
use cases for Assimp
|
|
||||||
|
|
||||||
The source code is organized in the following way:
|
The source code is organized in the following way:
|
||||||
|
|
||||||
code/Common The base implementation for importers and the infrastructure
|
code/Common The base implementation for importers and the infrastructure
|
||||||
|
code/CApi Special implementations which are only used for the C-API
|
||||||
|
code/Geometry A collection of geometry tools
|
||||||
|
code/Material The material system
|
||||||
|
code/PBR An exporter for physical based models
|
||||||
code/PostProcessing The post-processing steps
|
code/PostProcessing The post-processing steps
|
||||||
code/AssetLib/<FormatName> Implementation for import and export for the format
|
code/AssetLib/<FormatName> Implementation for import and export for the format
|
||||||
|
|
||||||
### Where to get help ###
|
|
||||||
For more information, visit [our website](http://assimp.org/). Or check out the `./doc`- folder, which contains the official documentation in HTML format.
|
|
||||||
(CHMs for Windows are included in some release packages and should be located right here in the root folder).
|
|
||||||
|
|
||||||
If the docs don't solve your problem, ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest). If you think you found a bug, please open an issue on Github.
|
|
||||||
|
|
||||||
Open Asset Import Library is a library to load 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.
|
|
||||||
|
|
||||||
And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
|
|
||||||
|
|
||||||
### Contributing ###
|
### Contributing ###
|
||||||
Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
|
Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
|
||||||
a pull request with your changes against the main repository's `master` branch.
|
a pull request with your changes against the main repository's `master` branch.
|
||||||
|
|
|
@ -322,7 +322,6 @@ struct Texture {
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
Texture() AI_NO_EXCEPT
|
Texture() AI_NO_EXCEPT
|
||||||
: mTextureBlend(0.0f),
|
: mTextureBlend(0.0f),
|
||||||
mMapName(),
|
|
||||||
mOffsetU(0.0),
|
mOffsetU(0.0),
|
||||||
mOffsetV(0.0),
|
mOffsetV(0.0),
|
||||||
mScaleU(1.0),
|
mScaleU(1.0),
|
||||||
|
@ -334,51 +333,11 @@ struct Texture {
|
||||||
mTextureBlend = get_qnan();
|
mTextureBlend = get_qnan();
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture(const Texture &other) :
|
Texture(const Texture &other) = default;
|
||||||
mTextureBlend(other.mTextureBlend),
|
|
||||||
mMapName(other.mMapName),
|
|
||||||
mOffsetU(other.mOffsetU),
|
|
||||||
mOffsetV(other.mOffsetV),
|
|
||||||
mScaleU(other.mScaleU),
|
|
||||||
mScaleV(other.mScaleV),
|
|
||||||
mRotation(other.mRotation),
|
|
||||||
mMapMode(other.mMapMode),
|
|
||||||
bPrivate(other.bPrivate),
|
|
||||||
iUVSrc(other.iUVSrc) {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
Texture(Texture &&other) AI_NO_EXCEPT : mTextureBlend(other.mTextureBlend),
|
Texture(Texture &&other) AI_NO_EXCEPT = default;
|
||||||
mMapName(std::move(other.mMapName)),
|
|
||||||
mOffsetU(other.mOffsetU),
|
|
||||||
mOffsetV(other.mOffsetV),
|
|
||||||
mScaleU(other.mScaleU),
|
|
||||||
mScaleV(other.mScaleV),
|
|
||||||
mRotation(other.mRotation),
|
|
||||||
mMapMode(other.mMapMode),
|
|
||||||
bPrivate(other.bPrivate),
|
|
||||||
iUVSrc(other.iUVSrc) {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
Texture &operator=(Texture &&other) AI_NO_EXCEPT {
|
Texture &operator=(Texture &&other) AI_NO_EXCEPT = default;
|
||||||
if (this == &other) {
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
mTextureBlend = other.mTextureBlend;
|
|
||||||
mMapName = std::move(other.mMapName);
|
|
||||||
mOffsetU = other.mOffsetU;
|
|
||||||
mOffsetV = other.mOffsetV;
|
|
||||||
mScaleU = other.mScaleU;
|
|
||||||
mScaleV = other.mScaleV;
|
|
||||||
mRotation = other.mRotation;
|
|
||||||
mMapMode = other.mMapMode;
|
|
||||||
bPrivate = other.bPrivate;
|
|
||||||
iUVSrc = other.iUVSrc;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Specifies the blend factor for the texture
|
//! Specifies the blend factor for the texture
|
||||||
ai_real mTextureBlend;
|
ai_real mTextureBlend;
|
||||||
|
@ -436,83 +395,9 @@ struct Material {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
Material(const Material &other) :
|
Material(const Material &other) = default;
|
||||||
mName(other.mName),
|
|
||||||
mDiffuse(other.mDiffuse),
|
|
||||||
mSpecularExponent(other.mSpecularExponent),
|
|
||||||
mShininessStrength(other.mShininessStrength),
|
|
||||||
mSpecular(other.mSpecular),
|
|
||||||
mAmbient(other.mAmbient),
|
|
||||||
mShading(other.mShading),
|
|
||||||
mTransparency(other.mTransparency),
|
|
||||||
sTexDiffuse(other.sTexDiffuse),
|
|
||||||
sTexOpacity(other.sTexOpacity),
|
|
||||||
sTexSpecular(other.sTexSpecular),
|
|
||||||
sTexReflective(other.sTexReflective),
|
|
||||||
sTexBump(other.sTexBump),
|
|
||||||
sTexEmissive(other.sTexEmissive),
|
|
||||||
sTexShininess(other.sTexShininess),
|
|
||||||
mBumpHeight(other.mBumpHeight),
|
|
||||||
mEmissive(other.mEmissive),
|
|
||||||
sTexAmbient(other.sTexAmbient),
|
|
||||||
mTwoSided(other.mTwoSided) {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
|
virtual ~Material() = default;
|
||||||
Material(Material &&other) AI_NO_EXCEPT : mName(std::move(other.mName)),
|
|
||||||
mDiffuse(other.mDiffuse),
|
|
||||||
mSpecularExponent(other.mSpecularExponent),
|
|
||||||
mShininessStrength(other.mShininessStrength),
|
|
||||||
mSpecular(other.mSpecular),
|
|
||||||
mAmbient(other.mAmbient),
|
|
||||||
mShading(other.mShading),
|
|
||||||
mTransparency(other.mTransparency),
|
|
||||||
sTexDiffuse(std::move(other.sTexDiffuse)),
|
|
||||||
sTexOpacity(std::move(other.sTexOpacity)),
|
|
||||||
sTexSpecular(std::move(other.sTexSpecular)),
|
|
||||||
sTexReflective(std::move(other.sTexReflective)),
|
|
||||||
sTexBump(std::move(other.sTexBump)),
|
|
||||||
sTexEmissive(std::move(other.sTexEmissive)),
|
|
||||||
sTexShininess(std::move(other.sTexShininess)),
|
|
||||||
mBumpHeight(other.mBumpHeight),
|
|
||||||
mEmissive(other.mEmissive),
|
|
||||||
sTexAmbient(std::move(other.sTexAmbient)),
|
|
||||||
mTwoSided(other.mTwoSided) {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
Material &operator=(Material &&other) AI_NO_EXCEPT {
|
|
||||||
if (this == &other) {
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
mName = std::move(other.mName);
|
|
||||||
mDiffuse = other.mDiffuse;
|
|
||||||
mSpecularExponent = other.mSpecularExponent;
|
|
||||||
mShininessStrength = other.mShininessStrength,
|
|
||||||
mSpecular = other.mSpecular;
|
|
||||||
mAmbient = other.mAmbient;
|
|
||||||
mShading = other.mShading;
|
|
||||||
mTransparency = other.mTransparency;
|
|
||||||
sTexDiffuse = std::move(other.sTexDiffuse);
|
|
||||||
sTexOpacity = std::move(other.sTexOpacity);
|
|
||||||
sTexSpecular = std::move(other.sTexSpecular);
|
|
||||||
sTexReflective = std::move(other.sTexReflective);
|
|
||||||
sTexBump = std::move(other.sTexBump);
|
|
||||||
sTexEmissive = std::move(other.sTexEmissive);
|
|
||||||
sTexShininess = std::move(other.sTexShininess);
|
|
||||||
mBumpHeight = other.mBumpHeight;
|
|
||||||
mEmissive = other.mEmissive;
|
|
||||||
sTexAmbient = std::move(other.sTexAmbient);
|
|
||||||
mTwoSided = other.mTwoSided;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~Material() {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Name of the material
|
//! Name of the material
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
|
|
@ -266,8 +266,15 @@ void Discreet3DSImporter::ParseMainChunk() {
|
||||||
};
|
};
|
||||||
|
|
||||||
ASSIMP_3DS_END_CHUNK();
|
ASSIMP_3DS_END_CHUNK();
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wunreachable-code-return"
|
||||||
|
#endif
|
||||||
// recursively continue processing this hierarchy level
|
// recursively continue processing this hierarchy level
|
||||||
return ParseMainChunk();
|
return ParseMainChunk();
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -68,7 +68,7 @@ using namespace D3DS;
|
||||||
class Discreet3DSImporter : public BaseImporter {
|
class Discreet3DSImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
Discreet3DSImporter();
|
Discreet3DSImporter();
|
||||||
~Discreet3DSImporter();
|
~Discreet3DSImporter() override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
|
|
|
@ -69,9 +69,7 @@ public:
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Resource() {
|
virtual ~Resource() = default;
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ResourceType getType() const {
|
virtual ResourceType getType() const {
|
||||||
return ResourceType::RT_Unknown;
|
return ResourceType::RT_Unknown;
|
||||||
|
@ -95,7 +93,7 @@ public:
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
~EmbeddedTexture() = default;
|
~EmbeddedTexture() override = default;
|
||||||
|
|
||||||
ResourceType getType() const override {
|
ResourceType getType() const override {
|
||||||
return ResourceType::RT_EmbeddedTexture2D;
|
return ResourceType::RT_EmbeddedTexture2D;
|
||||||
|
@ -112,7 +110,7 @@ public:
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
~Texture2DGroup() = default;
|
~Texture2DGroup() override = default;
|
||||||
|
|
||||||
ResourceType getType() const override {
|
ResourceType getType() const override {
|
||||||
return ResourceType::RT_Texture2DGroup;
|
return ResourceType::RT_Texture2DGroup;
|
||||||
|
@ -129,7 +127,7 @@ public:
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
~BaseMaterials() = default;
|
~BaseMaterials() override = default;
|
||||||
|
|
||||||
ResourceType getType() const override {
|
ResourceType getType() const override {
|
||||||
return ResourceType::RT_BaseMaterials;
|
return ResourceType::RT_BaseMaterials;
|
||||||
|
@ -154,7 +152,7 @@ public:
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
~Object() = default;
|
~Object() override = default;
|
||||||
|
|
||||||
ResourceType getType() const override {
|
ResourceType getType() const override {
|
||||||
return ResourceType::RT_Object;
|
return ResourceType::RT_Object;
|
||||||
|
|
|
@ -83,7 +83,7 @@ void ExportScene3MF(const char *pFile, IOSystem *pIOSystem, const aiScene *pScen
|
||||||
namespace D3MF {
|
namespace D3MF {
|
||||||
|
|
||||||
D3MFExporter::D3MFExporter(const char *pFile, const aiScene *pScene) :
|
D3MFExporter::D3MFExporter(const char *pFile, const aiScene *pScene) :
|
||||||
mArchiveName(pFile), m_zipArchive(nullptr), mScene(pScene), mModelOutput(), mRelOutput(), mContentOutput(), mBuildItems(), mRelations() {
|
mArchiveName(pFile), m_zipArchive(nullptr), mScene(pScene) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -160,7 +160,7 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
|
||||||
// deal with zip-bug
|
// deal with zip-bug
|
||||||
rootFile = rootFile.substr(1);
|
rootFile = rootFile.substr(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSIMP_LOG_VERBOSE_DEBUG(rootFile);
|
ASSIMP_LOG_VERBOSE_DEBUG(rootFile);
|
||||||
|
|
||||||
|
|
|
@ -216,7 +216,7 @@ void XmlSerializer::ImportXml(aiScene *scene) {
|
||||||
if (nullptr == scene) {
|
if (nullptr == scene) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
scene->mRootNode = new aiNode(XmlTag::RootTag);
|
scene->mRootNode = new aiNode(XmlTag::RootTag);
|
||||||
XmlNode node = mXmlParser->getRootNode().child(XmlTag::model);
|
XmlNode node = mXmlParser->getRootNode().child(XmlTag::model);
|
||||||
if (node.empty()) {
|
if (node.empty()) {
|
||||||
|
@ -444,7 +444,7 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
|
||||||
}
|
}
|
||||||
mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
|
mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -227,7 +227,9 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
|
||||||
}
|
}
|
||||||
} else if (TokenMatch(buffer, "texture", 7)) {
|
} else if (TokenMatch(buffer, "texture", 7)) {
|
||||||
SkipSpaces(&buffer);
|
SkipSpaces(&buffer);
|
||||||
buffer = AcGetString(buffer, obj.texture);
|
std::string texture;
|
||||||
|
buffer = AcGetString(buffer, texture);
|
||||||
|
obj.textures.push_back(texture);
|
||||||
} else if (TokenMatch(buffer, "texrep", 6)) {
|
} else if (TokenMatch(buffer, "texrep", 6)) {
|
||||||
SkipSpaces(&buffer);
|
SkipSpaces(&buffer);
|
||||||
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &obj.texRepeat);
|
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &obj.texRepeat);
|
||||||
|
@ -351,8 +353,8 @@ void AC3DImporter::ConvertMaterial(const Object &object,
|
||||||
s.Set(matSrc.name);
|
s.Set(matSrc.name);
|
||||||
matDest.AddProperty(&s, AI_MATKEY_NAME);
|
matDest.AddProperty(&s, AI_MATKEY_NAME);
|
||||||
}
|
}
|
||||||
if (object.texture.length()) {
|
if (!object.textures.empty()) {
|
||||||
s.Set(object.texture);
|
s.Set(object.textures[0]);
|
||||||
matDest.AddProperty(&s, AI_MATKEY_TEXTURE_DIFFUSE(0));
|
matDest.AddProperty(&s, AI_MATKEY_TEXTURE_DIFFUSE(0));
|
||||||
|
|
||||||
// UV transformation
|
// UV transformation
|
||||||
|
@ -532,7 +534,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
|
||||||
// allocate UV coordinates, but only if the texture name for the
|
// allocate UV coordinates, but only if the texture name for the
|
||||||
// surface is not empty
|
// surface is not empty
|
||||||
aiVector3D *uv = nullptr;
|
aiVector3D *uv = nullptr;
|
||||||
if (object.texture.length()) {
|
if (!object.textures.empty()) {
|
||||||
uv = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
|
uv = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
|
||||||
mesh->mNumUVComponents[0] = 2;
|
mesh->mNumUVComponents[0] = 2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,6 @@ public:
|
||||||
type(World),
|
type(World),
|
||||||
name(),
|
name(),
|
||||||
children(),
|
children(),
|
||||||
texture(),
|
|
||||||
texRepeat(1.f, 1.f),
|
texRepeat(1.f, 1.f),
|
||||||
texOffset(0.0f, 0.0f),
|
texOffset(0.0f, 0.0f),
|
||||||
rotation(),
|
rotation(),
|
||||||
|
@ -151,7 +150,8 @@ public:
|
||||||
std::vector<Object> children;
|
std::vector<Object> children;
|
||||||
|
|
||||||
// texture to be assigned to all surfaces of the object
|
// texture to be assigned to all surfaces of the object
|
||||||
std::string texture;
|
// the .acc format supports up to 4 textures
|
||||||
|
std::vector<std::string> textures;
|
||||||
|
|
||||||
// texture repat factors (scaling for all coordinates)
|
// texture repat factors (scaling for all coordinates)
|
||||||
aiVector2D texRepeat, texOffset;
|
aiVector2D texRepeat, texOffset;
|
||||||
|
|
|
@ -83,11 +83,7 @@ void AMFImporter::Clear() {
|
||||||
|
|
||||||
AMFImporter::AMFImporter() AI_NO_EXCEPT :
|
AMFImporter::AMFImporter() AI_NO_EXCEPT :
|
||||||
mNodeElement_Cur(nullptr),
|
mNodeElement_Cur(nullptr),
|
||||||
mXmlParser(nullptr),
|
mXmlParser(nullptr) {
|
||||||
mUnit(),
|
|
||||||
mVersion(),
|
|
||||||
mMaterial_Converted(),
|
|
||||||
mTexture_Converted() {
|
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -282,11 +282,11 @@ public:
|
||||||
bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const;
|
bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const;
|
||||||
bool Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const;
|
bool Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const;
|
||||||
bool Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const;
|
bool Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const;
|
||||||
void Throw_CloseNotFound(const std::string &nodeName);
|
AI_WONT_RETURN void Throw_CloseNotFound(const std::string &nodeName) AI_WONT_RETURN_SUFFIX;
|
||||||
void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName);
|
AI_WONT_RETURN void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
|
||||||
void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName);
|
AI_WONT_RETURN void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
|
||||||
void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription);
|
AI_WONT_RETURN void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription) AI_WONT_RETURN_SUFFIX;
|
||||||
void Throw_ID_NotFound(const std::string &pID) const;
|
AI_WONT_RETURN void Throw_ID_NotFound(const std::string &pID) const AI_WONT_RETURN_SUFFIX;
|
||||||
void XML_CheckNode_MustHaveChildren(pugi::xml_node &node);
|
void XML_CheckNode_MustHaveChildren(pugi::xml_node &node);
|
||||||
bool XML_SearchNode(const std::string &nodeName);
|
bool XML_SearchNode(const std::string &nodeName);
|
||||||
void ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString);
|
void ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString);
|
||||||
|
|
|
@ -88,9 +88,7 @@ public:
|
||||||
std::list<AMFNodeElementBase *> Child; ///< Child elements.
|
std::list<AMFNodeElementBase *> Child; ///< Child elements.
|
||||||
|
|
||||||
public: /// Destructor, virtual..
|
public: /// Destructor, virtual..
|
||||||
virtual ~AMFNodeElementBase() {
|
virtual ~AMFNodeElementBase() = default;
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Disabled copy constructor and co.
|
/// Disabled copy constructor and co.
|
||||||
AMFNodeElementBase(const AMFNodeElementBase &pNodeElement) = delete;
|
AMFNodeElementBase(const AMFNodeElementBase &pNodeElement) = delete;
|
||||||
|
@ -103,7 +101,7 @@ protected:
|
||||||
/// \param [in] pType - element type.
|
/// \param [in] pType - element type.
|
||||||
/// \param [in] pParent - parent element.
|
/// \param [in] pParent - parent element.
|
||||||
AMFNodeElementBase(const EType pType, AMFNodeElementBase *pParent) :
|
AMFNodeElementBase(const EType pType, AMFNodeElementBase *pParent) :
|
||||||
Type(pType), ID(), Parent(pParent), Child() {
|
Type(pType), Parent(pParent) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
}; // class IAMFImporter_NodeElement
|
}; // class IAMFImporter_NodeElement
|
||||||
|
@ -174,7 +172,7 @@ struct AMFColor : public AMFNodeElementBase {
|
||||||
/// @brief Constructor.
|
/// @brief Constructor.
|
||||||
/// @param [in] pParent - pointer to parent node.
|
/// @param [in] pParent - pointer to parent node.
|
||||||
AMFColor(AMFNodeElementBase *pParent) :
|
AMFColor(AMFNodeElementBase *pParent) :
|
||||||
AMFNodeElementBase(ENET_Color, pParent), Composed(false), Color(), Profile() {
|
AMFNodeElementBase(ENET_Color, pParent), Composed(false), Color() {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -270,7 +268,7 @@ struct AMFTexMap : public AMFNodeElementBase {
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
AMFTexMap(AMFNodeElementBase *pParent) :
|
AMFTexMap(AMFNodeElementBase *pParent) :
|
||||||
AMFNodeElementBase(ENET_TexMap, pParent), TextureCoordinate{}, TextureID_R(), TextureID_G(), TextureID_B(), TextureID_A() {
|
AMFNodeElementBase(ENET_TexMap, pParent), TextureCoordinate{} {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -815,6 +815,7 @@ nl_clean_loop:
|
||||||
for (; next_it != nodeArray.end(); ++next_it) {
|
for (; next_it != nodeArray.end(); ++next_it) {
|
||||||
if ((*next_it)->FindNode((*nl_it)->mName) != nullptr) {
|
if ((*next_it)->FindNode((*nl_it)->mName) != nullptr) {
|
||||||
// if current top node(nl_it) found in another top node then erase it from node_list and restart search loop.
|
// if current top node(nl_it) found in another top node then erase it from node_list and restart search loop.
|
||||||
|
// FIXME: this leaks memory on test models test8.amf and test9.amf
|
||||||
nodeArray.erase(nl_it);
|
nodeArray.erase(nl_it);
|
||||||
|
|
||||||
goto nl_clean_loop;
|
goto nl_clean_loop;
|
||||||
|
|
|
@ -44,7 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
|
||||||
|
|
||||||
// internal headers
|
// internal headers
|
||||||
|
@ -322,21 +321,6 @@ void ASEImporter::BuildAnimations(const std::vector<BaseNode *> &nodes) {
|
||||||
aiNodeAnim *nd = pcAnim->mChannels[iNum++] = new aiNodeAnim();
|
aiNodeAnim *nd = pcAnim->mChannels[iNum++] = new aiNodeAnim();
|
||||||
nd->mNodeName.Set(me->mName + ".Target");
|
nd->mNodeName.Set(me->mName + ".Target");
|
||||||
|
|
||||||
// If there is no input position channel we will need
|
|
||||||
// to supply the default position from the node's
|
|
||||||
// local transformation matrix.
|
|
||||||
/*TargetAnimationHelper helper;
|
|
||||||
if (me->mAnim.akeyPositions.empty())
|
|
||||||
{
|
|
||||||
aiMatrix4x4& mat = (*i)->mTransform;
|
|
||||||
helper.SetFixedMainAnimationChannel(aiVector3D(
|
|
||||||
mat.a4, mat.b4, mat.c4));
|
|
||||||
}
|
|
||||||
else helper.SetMainAnimationChannel (&me->mAnim.akeyPositions);
|
|
||||||
helper.SetTargetAnimationChannel (&me->mTargetAnim.akeyPositions);
|
|
||||||
|
|
||||||
helper.Process(&me->mTargetAnim.akeyPositions);*/
|
|
||||||
|
|
||||||
// Allocate the key array and fill it
|
// Allocate the key array and fill it
|
||||||
nd->mNumPositionKeys = (unsigned int)me->mTargetAnim.akeyPositions.size();
|
nd->mNumPositionKeys = (unsigned int)me->mTargetAnim.akeyPositions.size();
|
||||||
nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys];
|
nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys];
|
||||||
|
|
|
@ -304,7 +304,6 @@ void Parser::Parse() {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_TOP_LEVEL_SECTION();
|
AI_ASE_HANDLE_TOP_LEVEL_SECTION();
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -734,7 +733,6 @@ void Parser::ParseLV3MapBlock(Texture &map) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MAP_XXXXXX");
|
AI_ASE_HANDLE_SECTION("3", "*MAP_XXXXXX");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -859,7 +857,6 @@ void Parser::ParseLV1ObjectBlock(ASE::BaseNode &node) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_TOP_LEVEL_SECTION();
|
AI_ASE_HANDLE_TOP_LEVEL_SECTION();
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -883,7 +880,6 @@ void Parser::ParseLV2CameraSettingsBlock(ASE::Camera &camera) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("2", "CAMERA_SETTINGS");
|
AI_ASE_HANDLE_SECTION("2", "CAMERA_SETTINGS");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -1189,7 +1185,6 @@ void Parser::ParseLV2NodeTransformBlock(ASE::BaseNode &mesh) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("2", "*NODE_TM");
|
AI_ASE_HANDLE_SECTION("2", "*NODE_TM");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV2MeshBlock(ASE::Mesh &mesh) {
|
void Parser::ParseLV2MeshBlock(ASE::Mesh &mesh) {
|
||||||
|
@ -1310,7 +1305,6 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh &mesh) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("2", "*MESH");
|
AI_ASE_HANDLE_SECTION("2", "*MESH");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh &mesh) {
|
void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh &mesh) {
|
||||||
|
@ -1344,7 +1338,6 @@ void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh &mesh) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_WEIGHTS");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_WEIGHTS");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV4MeshBones(unsigned int iNumBones, ASE::Mesh &mesh) {
|
void Parser::ParseLV4MeshBones(unsigned int iNumBones, ASE::Mesh &mesh) {
|
||||||
|
@ -1414,7 +1407,6 @@ void Parser::ParseLV4MeshBonesVertices(unsigned int iNumVertices, ASE::Mesh &mes
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("4", "*MESH_BONE_VERTEX");
|
AI_ASE_HANDLE_SECTION("4", "*MESH_BONE_VERTEX");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshVertexListBlock(
|
void Parser::ParseLV3MeshVertexListBlock(
|
||||||
|
@ -1443,7 +1435,6 @@ void Parser::ParseLV3MeshVertexListBlock(
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_VERTEX_LIST");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_VERTEX_LIST");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh) {
|
void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh) {
|
||||||
|
@ -1470,7 +1461,6 @@ void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh)
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_FACE_LIST");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_FACE_LIST");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
|
void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
|
||||||
|
@ -1503,7 +1493,6 @@ void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_TVERT_LIST");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_TVERT_LIST");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces,
|
void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces,
|
||||||
|
@ -1532,7 +1521,6 @@ void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces,
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_TFACE_LIST");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_TFACE_LIST");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh &mesh) {
|
void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh &mesh) {
|
||||||
|
@ -1567,7 +1555,6 @@ void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh &mesh) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_MAPPING_CHANNEL");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_MAPPING_CHANNEL");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh &mesh) {
|
void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh &mesh) {
|
||||||
|
@ -1595,7 +1582,6 @@ void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh &mesh)
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_CVERTEX_LIST");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_CVERTEX_LIST");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh) {
|
void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh) {
|
||||||
|
@ -1623,7 +1609,6 @@ void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh)
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_CFACE_LIST");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_CFACE_LIST");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh &sMesh) {
|
void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh &sMesh) {
|
||||||
|
@ -1681,7 +1666,6 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh &sMesh) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_NORMALS");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_NORMALS");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV4MeshFace(ASE::Face &out) {
|
void Parser::ParseLV4MeshFace(ASE::Face &out) {
|
||||||
|
|
|
@ -56,5 +56,5 @@ namespace Assimp {
|
||||||
void ASSIMP_API ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/);
|
void ASSIMP_API ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/);
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif // AI_ASSBINEXPORTER_H_INC
|
#endif // AI_ASSBINEXPORTER_H_INC
|
||||||
|
|
|
@ -291,15 +291,15 @@ public:
|
||||||
size_t Read(void * /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) override {
|
size_t Read(void * /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) override {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) override {
|
aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) override {
|
||||||
return aiReturn_FAILURE;
|
return aiReturn_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Tell() const override {
|
size_t Tell() const override {
|
||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Flush() override {
|
void Flush() override {
|
||||||
// not implemented
|
// not implemented
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ For details, see http://sourceforge.net/projects/libb64
|
||||||
|
|
||||||
#include "cencode.h" // changed from <B64/cencode.h>
|
#include "cencode.h" // changed from <B64/cencode.h>
|
||||||
|
|
||||||
const int CHARS_PER_LINE = 72;
|
static const int CHARS_PER_LINE = 72;
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
|
|
|
@ -43,7 +43,7 @@ public:
|
||||||
Flag_WriteSpecialFloats = 0x2,
|
Flag_WriteSpecialFloats = 0x2,
|
||||||
Flag_SkipWhitespaces = 0x4
|
Flag_SkipWhitespaces = 0x4
|
||||||
};
|
};
|
||||||
|
|
||||||
JSONWriter(Assimp::IOStream &out, unsigned int flags = 0u) :
|
JSONWriter(Assimp::IOStream &out, unsigned int flags = 0u) :
|
||||||
out(out), indent (""), newline("\n"), space(" "), buff (), first(false), flags(flags) {
|
out(out), indent (""), newline("\n"), space(" "), buff (), first(false), flags(flags) {
|
||||||
// make sure that all formatting happens using the standard, C locale and not the user's current locale
|
// make sure that all formatting happens using the standard, C locale and not the user's current locale
|
||||||
|
@ -499,18 +499,18 @@ static void Write(JSONWriter &out, const aiMaterial &ai, bool is_elem = true) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case aiPTI_String:
|
case aiPTI_String:
|
||||||
{
|
{
|
||||||
aiString s;
|
aiString s;
|
||||||
aiGetMaterialString(&ai, prop->mKey.data, prop->mSemantic, prop->mIndex, &s);
|
aiGetMaterialString(&ai, prop->mKey.data, prop->mSemantic, prop->mIndex, &s);
|
||||||
out.SimpleValue(s);
|
out.SimpleValue(s);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case aiPTI_Buffer:
|
case aiPTI_Buffer:
|
||||||
{
|
{
|
||||||
// binary data is written as series of hex-encoded octets
|
// binary data is written as series of hex-encoded octets
|
||||||
out.SimpleValue(prop->mData, prop->mDataLength);
|
out.SimpleValue(prop->mData, prop->mDataLength);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ai_assert(false);
|
ai_assert(false);
|
||||||
|
|
|
@ -150,7 +150,7 @@ AI_WONT_RETURN void B3DImporter::Fail(const string &str) {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
int B3DImporter::ReadByte() {
|
int B3DImporter::ReadByte() {
|
||||||
if (_pos > _buf.size()) {
|
if (_pos >= _buf.size()) {
|
||||||
Fail("EOF");
|
Fail("EOF");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,7 +418,6 @@ void B3DImporter::ReadTRIS(int v0) {
|
||||||
ASSIMP_LOG_ERROR("Bad triangle index: i0=", i0, ", i1=", i1, ", i2=", i2);
|
ASSIMP_LOG_ERROR("Bad triangle index: i0=", i0, ", i1=", i1, ", i2=", i2);
|
||||||
#endif
|
#endif
|
||||||
Fail("Bad triangle index");
|
Fail("Bad triangle index");
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
face->mNumIndices = 3;
|
face->mNumIndices = 3;
|
||||||
face->mIndices = new unsigned[3];
|
face->mIndices = new unsigned[3];
|
||||||
|
|
|
@ -52,8 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
template <>
|
template <>
|
||||||
const char *LogFunctions<BlenderBMeshConverter>::Prefix() {
|
const char *LogFunctions<BlenderBMeshConverter>::Prefix() {
|
||||||
static auto prefix = "BLEND_BMESH: ";
|
return "BLEND_BMESH: ";
|
||||||
return prefix;
|
|
||||||
}
|
}
|
||||||
} // namespace Assimp
|
} // namespace Assimp
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,8 @@ struct CustomDataTypeDescription {
|
||||||
* other (like CD_ORCO, ...) uses arrays of rawtypes or even arrays of Structures
|
* other (like CD_ORCO, ...) uses arrays of rawtypes or even arrays of Structures
|
||||||
* use a special readfunction for that cases
|
* use a special readfunction for that cases
|
||||||
*/
|
*/
|
||||||
std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDescriptions = { { DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MVert),
|
static std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDescriptions = { {
|
||||||
|
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MVert),
|
||||||
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MEdge),
|
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MEdge),
|
||||||
|
|
|
@ -106,9 +106,7 @@ struct ElemBase {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~ElemBase() {
|
virtual ~ElemBase() = default;
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Type name of the element. The type
|
/** Type name of the element. The type
|
||||||
* string points is the `c_str` of the `name` attribute of the
|
* string points is the `c_str` of the `name` attribute of the
|
||||||
|
|
|
@ -80,8 +80,7 @@ namespace Assimp {
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
const char *LogFunctions<BlenderImporter>::Prefix() {
|
const char *LogFunctions<BlenderImporter>::Prefix() {
|
||||||
static auto prefix = "BLEND: ";
|
return "BLEND: ";
|
||||||
return prefix;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Assimp
|
} // namespace Assimp
|
||||||
|
|
|
@ -62,9 +62,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* The class destructor, virtual.
|
* The class destructor, virtual.
|
||||||
*/
|
*/
|
||||||
virtual ~BlenderModifier() {
|
virtual ~BlenderModifier() = default;
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -569,7 +569,7 @@ void Structure ::Convert<MVert>(
|
||||||
const FileDatabase &db) const {
|
const FileDatabase &db) const {
|
||||||
|
|
||||||
ReadFieldArray<ErrorPolicy_Fail>(dest.co, "co", db);
|
ReadFieldArray<ErrorPolicy_Fail>(dest.co, "co", db);
|
||||||
ReadFieldArray<ErrorPolicy_Fail>(dest.no, "no", db);
|
ReadFieldArray<ErrorPolicy_Warn>(dest.no, "no", db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.flag, "flag", db);
|
ReadField<ErrorPolicy_Igno>(dest.flag, "flag", db);
|
||||||
//ReadField<ErrorPolicy_Warn>(dest.mat_nr,"mat_nr",db);
|
//ReadField<ErrorPolicy_Warn>(dest.mat_nr,"mat_nr",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.bweight, "bweight", db);
|
ReadField<ErrorPolicy_Igno>(dest.bweight, "bweight", db);
|
||||||
|
|
|
@ -182,7 +182,7 @@ struct MVert : ElemBase {
|
||||||
int bweight;
|
int bweight;
|
||||||
|
|
||||||
MVert() :
|
MVert() :
|
||||||
ElemBase(), flag(0), mat_nr(0), bweight(0) {}
|
flag(0), mat_nr(0), bweight(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
@ -417,7 +417,6 @@ struct CustomDataLayer : ElemBase {
|
||||||
std::shared_ptr<ElemBase> data; // must be converted to real type according type member
|
std::shared_ptr<ElemBase> data; // must be converted to real type according type member
|
||||||
|
|
||||||
CustomDataLayer() :
|
CustomDataLayer() :
|
||||||
ElemBase(),
|
|
||||||
type(0),
|
type(0),
|
||||||
offset(0),
|
offset(0),
|
||||||
flag(0),
|
flag(0),
|
||||||
|
@ -729,7 +728,7 @@ struct Object : ElemBase {
|
||||||
ListBase modifiers;
|
ListBase modifiers;
|
||||||
|
|
||||||
Object() :
|
Object() :
|
||||||
ElemBase(), type(Type_EMPTY), parent(nullptr), track(), proxy(), proxy_from(), data() {
|
type(Type_EMPTY), parent(nullptr) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -741,8 +740,7 @@ struct Base : ElemBase {
|
||||||
std::shared_ptr<Object> object WARN;
|
std::shared_ptr<Object> object WARN;
|
||||||
|
|
||||||
Base() :
|
Base() :
|
||||||
ElemBase(), prev(nullptr), next(), object() {
|
prev(nullptr) {
|
||||||
// empty
|
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -758,10 +756,7 @@ struct Scene : ElemBase {
|
||||||
|
|
||||||
ListBase base;
|
ListBase base;
|
||||||
|
|
||||||
Scene() :
|
Scene() = default;
|
||||||
ElemBase(), camera(), world(), basact(), master_collection() {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
@ -791,10 +786,7 @@ struct Image : ElemBase {
|
||||||
|
|
||||||
short gen_x, gen_y, gen_type;
|
short gen_x, gen_y, gen_type;
|
||||||
|
|
||||||
Image() :
|
Image() = default;
|
||||||
ElemBase() {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
@ -884,7 +876,7 @@ struct Tex : ElemBase {
|
||||||
//char use_nodes;
|
//char use_nodes;
|
||||||
|
|
||||||
Tex() :
|
Tex() :
|
||||||
ElemBase(), imaflag(ImageFlags_INTERPOL), type(Type_CLOUDS), ima() {
|
imaflag(ImageFlags_INTERPOL), type(Type_CLOUDS) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -976,10 +968,7 @@ struct MTex : ElemBase {
|
||||||
//float shadowfac;
|
//float shadowfac;
|
||||||
//float zenupfac, zendownfac, blendfac;
|
//float zenupfac, zendownfac, blendfac;
|
||||||
|
|
||||||
MTex() :
|
MTex() = default;
|
||||||
ElemBase() {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Blender
|
} // namespace Blender
|
||||||
|
|
|
@ -62,8 +62,7 @@ namspace Assimp
|
||||||
{
|
{
|
||||||
template< > const char* LogFunctions< BlenderTessellatorGL >::Prefix()
|
template< > const char* LogFunctions< BlenderTessellatorGL >::Prefix()
|
||||||
{
|
{
|
||||||
static auto prefix = "BLEND_TESS_GL: ";
|
return "BLEND_TESS_GL: ";
|
||||||
return prefix;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,9 +80,7 @@ BlenderTessellatorGL::BlenderTessellatorGL( BlenderBMeshConverter& converter ):
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
BlenderTessellatorGL::~BlenderTessellatorGL( )
|
BlenderTessellatorGL::~BlenderTessellatorGL() = default;
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorGL::Tessellate( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices )
|
void BlenderTessellatorGL::Tessellate( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices )
|
||||||
|
@ -259,8 +256,7 @@ namespace Assimp
|
||||||
{
|
{
|
||||||
template< > const char* LogFunctions< BlenderTessellatorP2T >::Prefix()
|
template< > const char* LogFunctions< BlenderTessellatorP2T >::Prefix()
|
||||||
{
|
{
|
||||||
static auto prefix = "BLEND_TESS_P2T: ";
|
return "BLEND_TESS_P2T: ";
|
||||||
return prefix;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,8 +86,7 @@ void GetWriterInfo(int &id, String &appname) {
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
template<> const char* LogFunctions<C4DImporter>::Prefix() {
|
template<> const char* LogFunctions<C4DImporter>::Prefix() {
|
||||||
static auto prefix = "C4D: ";
|
return "C4D: ";
|
||||||
return prefix;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,15 +105,10 @@ static const aiImporterDesc desc = {
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
C4DImporter::C4DImporter()
|
C4DImporter::C4DImporter() = default;
|
||||||
: BaseImporter() {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
C4DImporter::~C4DImporter() {
|
C4DImporter::~C4DImporter() = default;
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool C4DImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const {
|
bool C4DImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const {
|
||||||
|
@ -124,7 +118,7 @@ bool C4DImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, b
|
||||||
} else if ((!extension.length() || checkSig) && pIOHandler) {
|
} else if ((!extension.length() || checkSig) && pIOHandler) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -448,7 +448,7 @@ void ColladaExporter::WriteLight(size_t pIndex) {
|
||||||
PushTag();
|
PushTag();
|
||||||
switch (light->mType) {
|
switch (light->mType) {
|
||||||
case aiLightSource_AMBIENT:
|
case aiLightSource_AMBIENT:
|
||||||
WriteAmbienttLight(light);
|
WriteAmbientLight(light);
|
||||||
break;
|
break;
|
||||||
case aiLightSource_DIRECTIONAL:
|
case aiLightSource_DIRECTIONAL:
|
||||||
WriteDirectionalLight(light);
|
WriteDirectionalLight(light);
|
||||||
|
@ -543,7 +543,7 @@ void ColladaExporter::WriteSpotLight(const aiLight *const light) {
|
||||||
mOutput << startstr << "</spot>" << endstr;
|
mOutput << startstr << "</spot>" << endstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaExporter::WriteAmbienttLight(const aiLight *const light) {
|
void ColladaExporter::WriteAmbientLight(const aiLight *const light) {
|
||||||
|
|
||||||
const aiColor3D &color = light->mColorAmbient;
|
const aiColor3D &color = light->mColorAmbient;
|
||||||
mOutput << startstr << "<ambient>" << endstr;
|
mOutput << startstr << "<ambient>" << endstr;
|
||||||
|
|
|
@ -101,7 +101,7 @@ protected:
|
||||||
void WritePointLight(const aiLight *const light);
|
void WritePointLight(const aiLight *const light);
|
||||||
void WriteDirectionalLight(const aiLight *const light);
|
void WriteDirectionalLight(const aiLight *const light);
|
||||||
void WriteSpotLight(const aiLight *const light);
|
void WriteSpotLight(const aiLight *const light);
|
||||||
void WriteAmbienttLight(const aiLight *const light);
|
void WriteAmbientLight(const aiLight *const light);
|
||||||
|
|
||||||
/// Writes the controller library
|
/// Writes the controller library
|
||||||
void WriteControllerLibrary();
|
void WriteControllerLibrary();
|
||||||
|
|
|
@ -666,7 +666,7 @@ struct ChannelEntry {
|
||||||
const Collada::Accessor *mTimeAccessor; ///> Collada accessor to the time values
|
const Collada::Accessor *mTimeAccessor; ///> Collada accessor to the time values
|
||||||
const Collada::Data *mTimeData; ///> Source data array for the time values
|
const Collada::Data *mTimeData; ///> Source data array for the time values
|
||||||
const Collada::Accessor *mValueAccessor; ///> Collada accessor to the key value values
|
const Collada::Accessor *mValueAccessor; ///> Collada accessor to the key value values
|
||||||
const Collada::Data *mValueData; ///> Source datat array for the key value values
|
const Collada::Data *mValueData; ///> Source data array for the key value values
|
||||||
|
|
||||||
ChannelEntry() :
|
ChannelEntry() :
|
||||||
mChannel(),
|
mChannel(),
|
||||||
|
|
|
@ -92,15 +92,6 @@ inline void AddNodeMetaData(aiNode *node, const std::string &key, const T &value
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
ColladaLoader::ColladaLoader() :
|
ColladaLoader::ColladaLoader() :
|
||||||
mFileName(),
|
|
||||||
mMeshIndexByID(),
|
|
||||||
mMaterialIndexByName(),
|
|
||||||
mMeshes(),
|
|
||||||
newMats(),
|
|
||||||
mCameras(),
|
|
||||||
mLights(),
|
|
||||||
mTextures(),
|
|
||||||
mAnims(),
|
|
||||||
noSkeletonMesh(false),
|
noSkeletonMesh(false),
|
||||||
removeEmptyBones(false),
|
removeEmptyBones(false),
|
||||||
ignoreUpDirection(false),
|
ignoreUpDirection(false),
|
||||||
|
@ -1523,7 +1514,7 @@ void ColladaLoader::AddTexture(aiMaterial &mat,
|
||||||
map = -1;
|
map = -1;
|
||||||
for (std::string::const_iterator 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)) {
|
if (IsNumeric(*it)) {
|
||||||
map = strtoul10(&(*it));
|
map = strtoul10(&(*it));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -762,6 +762,7 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
|
||||||
if (text == nullptr) {
|
if (text == nullptr) {
|
||||||
throw DeadlyImportError("Out of data while reading <vertex_weights>");
|
throw DeadlyImportError("Out of data while reading <vertex_weights>");
|
||||||
}
|
}
|
||||||
|
SkipSpacesAndLineEnd(&text);
|
||||||
it->first = strtoul10(text, &text);
|
it->first = strtoul10(text, &text);
|
||||||
SkipSpacesAndLineEnd(&text);
|
SkipSpacesAndLineEnd(&text);
|
||||||
if (*text == 0) {
|
if (*text == 0) {
|
||||||
|
@ -1854,7 +1855,6 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
|
||||||
default:
|
default:
|
||||||
// LineStrip is not supported due to expected index unmangling
|
// LineStrip is not supported due to expected index unmangling
|
||||||
throw DeadlyImportError("Unsupported primitive type.");
|
throw DeadlyImportError("Unsupported primitive type.");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// store the face size to later reconstruct the face from
|
// store the face size to later reconstruct the face from
|
||||||
|
|
|
@ -65,7 +65,6 @@ public:
|
||||||
LineReader(StreamReaderLE& reader)
|
LineReader(StreamReaderLE& reader)
|
||||||
: splitter(reader,false,true)
|
: splitter(reader,false,true)
|
||||||
, groupcode( 0 )
|
, groupcode( 0 )
|
||||||
, value()
|
|
||||||
, end() {
|
, end() {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
@ -186,8 +185,7 @@ struct InsertBlock {
|
||||||
InsertBlock()
|
InsertBlock()
|
||||||
: pos()
|
: pos()
|
||||||
, scale(1.f,1.f,1.f)
|
, scale(1.f,1.f,1.f)
|
||||||
, angle()
|
, angle() {
|
||||||
, name() {
|
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -371,7 +371,7 @@ void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& bloc
|
||||||
ASSIMP_LOG_ERROR("DXF: PolyLine instance is nullptr, skipping.");
|
ASSIMP_LOG_ERROR("DXF: PolyLine instance is nullptr, skipping.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<DXF::PolyLine> pl_out = std::shared_ptr<DXF::PolyLine>(new DXF::PolyLine(*pl_in));
|
std::shared_ptr<DXF::PolyLine> pl_out = std::shared_ptr<DXF::PolyLine>(new DXF::PolyLine(*pl_in));
|
||||||
|
|
||||||
if (bl_src.base.Length() || insert.scale.x!=1.f || insert.scale.y!=1.f || insert.scale.z!=1.f || insert.angle || insert.pos.Length()) {
|
if (bl_src.base.Length() || insert.scale.x!=1.f || insert.scale.y!=1.f || insert.scale.z!=1.f || insert.angle || insert.pos.Length()) {
|
||||||
|
|
|
@ -139,6 +139,7 @@ size_t Offset(const char* begin, const char* cursor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
AI_WONT_RETURN void TokenizeError(const std::string& message, const char* begin, const char* cursor) AI_WONT_RETURN_SUFFIX;
|
||||||
void TokenizeError(const std::string& message, const char* begin, const char* cursor) {
|
void TokenizeError(const std::string& message, const char* begin, const char* cursor) {
|
||||||
TokenizeError(message, Offset(begin, cursor));
|
TokenizeError(message, Offset(begin, cursor));
|
||||||
}
|
}
|
||||||
|
@ -341,8 +342,7 @@ void ReadData(const char*& sbegin_out, const char*& send_out, const char* input,
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, const char* end, bool const is64bits)
|
bool ReadScope(TokenList &output_tokens, StackAllocator &token_allocator, const char *input, const char *&cursor, const char *end, bool const is64bits) {
|
||||||
{
|
|
||||||
// the first word contains the offset at which this block ends
|
// the first word contains the offset at which this block ends
|
||||||
const uint64_t end_offset = is64bits ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end);
|
const uint64_t end_offset = is64bits ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end);
|
||||||
|
|
||||||
|
@ -408,7 +408,7 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
|
||||||
|
|
||||||
// XXX this is vulnerable to stack overflowing ..
|
// XXX this is vulnerable to stack overflowing ..
|
||||||
while(Offset(input, cursor) < end_offset - sentinel_block_length) {
|
while(Offset(input, cursor) < end_offset - sentinel_block_length) {
|
||||||
ReadScope(output_tokens, input, cursor, input + end_offset - sentinel_block_length, is64bits);
|
ReadScope(output_tokens, token_allocator, input, cursor, input + end_offset - sentinel_block_length, is64bits);
|
||||||
}
|
}
|
||||||
output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_CLOSE_BRACKET, Offset(input, cursor) ));
|
output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_CLOSE_BRACKET, Offset(input, cursor) ));
|
||||||
|
|
||||||
|
@ -431,8 +431,7 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// TODO: Test FBX Binary files newer than the 7500 version to check if the 64 bits address behaviour is consistent
|
// TODO: Test FBX Binary files newer than the 7500 version to check if the 64 bits address behaviour is consistent
|
||||||
void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length)
|
void TokenizeBinary(TokenList &output_tokens, const char *input, size_t length, StackAllocator &token_allocator) {
|
||||||
{
|
|
||||||
ai_assert(input);
|
ai_assert(input);
|
||||||
ASSIMP_LOG_DEBUG("Tokenizing binary FBX file");
|
ASSIMP_LOG_DEBUG("Tokenizing binary FBX file");
|
||||||
|
|
||||||
|
@ -465,7 +464,7 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while (cursor < end ) {
|
while (cursor < end ) {
|
||||||
if (!ReadScope(output_tokens, input, cursor, input + length, is64bits)) {
|
if (!ReadScope(output_tokens, token_allocator, input, cursor, input + length, is64bits)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@ const char NULL_RECORD[NumNullRecords] = { // 25 null bytes in 64-bit and 13 nul
|
||||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
||||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
|
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
|
||||||
}; // who knows why, it looks like two integers 32/64 bit (compressed and uncompressed sizes?) + 1 byte (might be compression type?)
|
}; // who knows why, it looks like two integers 32/64 bit (compressed and uncompressed sizes?) + 1 byte (might be compression type?)
|
||||||
|
static std::string NULL_RECORD_STRING(NumNullRecords, '\0');
|
||||||
const std::string SEPARATOR = { '\x00', '\x01' }; // for use inside strings
|
const std::string SEPARATOR = { '\x00', '\x01' }; // for use inside strings
|
||||||
const std::string MAGIC_NODE_TAG = "_$AssimpFbx$"; // from import
|
const std::string MAGIC_NODE_TAG = "_$AssimpFbx$"; // from import
|
||||||
const int64_t SECOND = 46186158000; // FBX's kTime unit
|
const int64_t SECOND = 46186158000; // FBX's kTime unit
|
||||||
|
|
|
@ -421,6 +421,8 @@ void FBXConverter::ConvertCamera(const Camera &cam, const std::string &orig_name
|
||||||
|
|
||||||
out_camera->mAspect = cam.AspectWidth() / cam.AspectHeight();
|
out_camera->mAspect = cam.AspectWidth() / cam.AspectHeight();
|
||||||
|
|
||||||
|
// NOTE: Camera mPosition, mLookAt and mUp must be set to default here.
|
||||||
|
// All transformations to the camera will be handled by its node in the scenegraph.
|
||||||
out_camera->mPosition = aiVector3D(0.0f);
|
out_camera->mPosition = aiVector3D(0.0f);
|
||||||
out_camera->mLookAt = aiVector3D(1.0f, 0.0f, 0.0f);
|
out_camera->mLookAt = aiVector3D(1.0f, 0.0f, 0.0f);
|
||||||
out_camera->mUp = aiVector3D(0.0f, 1.0f, 0.0f);
|
out_camera->mUp = aiVector3D(0.0f, 1.0f, 0.0f);
|
||||||
|
@ -640,7 +642,7 @@ void FBXConverter::GetRotationMatrix(Model::RotOrder mode, const aiVector3D &rot
|
||||||
bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
|
bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
|
||||||
const PropertyTable &props = model.Props();
|
const PropertyTable &props = model.Props();
|
||||||
|
|
||||||
const auto zero_epsilon = ai_epsilon;
|
const auto zero_epsilon = Math::getEpsilon<ai_real>();
|
||||||
const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
|
const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
|
||||||
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
|
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
|
||||||
const TransformationComp comp = static_cast<TransformationComp>(i);
|
const TransformationComp comp = static_cast<TransformationComp>(i);
|
||||||
|
@ -873,8 +875,12 @@ void FBXConverter::SetupNodeMetadata(const Model &model, aiNode &nd) {
|
||||||
data->Set(index++, prop.first, interpretedBool->Value());
|
data->Set(index++, prop.first, interpretedBool->Value());
|
||||||
} else if (const TypedProperty<int> *interpretedInt = prop.second->As<TypedProperty<int>>()) {
|
} else if (const TypedProperty<int> *interpretedInt = prop.second->As<TypedProperty<int>>()) {
|
||||||
data->Set(index++, prop.first, interpretedInt->Value());
|
data->Set(index++, prop.first, interpretedInt->Value());
|
||||||
|
} else if (const TypedProperty<uint32_t> *interpretedUInt = prop.second->As<TypedProperty<uint32_t>>()) {
|
||||||
|
data->Set(index++, prop.first, interpretedUInt->Value());
|
||||||
} else if (const TypedProperty<uint64_t> *interpretedUint64 = prop.second->As<TypedProperty<uint64_t>>()) {
|
} else if (const TypedProperty<uint64_t> *interpretedUint64 = prop.second->As<TypedProperty<uint64_t>>()) {
|
||||||
data->Set(index++, prop.first, interpretedUint64->Value());
|
data->Set(index++, prop.first, interpretedUint64->Value());
|
||||||
|
} else if (const TypedProperty<int64_t> *interpretedint64 = prop.second->As<TypedProperty<int64_t>>()) {
|
||||||
|
data->Set(index++, prop.first, interpretedint64->Value());
|
||||||
} else if (const TypedProperty<float> *interpretedFloat = prop.second->As<TypedProperty<float>>()) {
|
} else if (const TypedProperty<float> *interpretedFloat = prop.second->As<TypedProperty<float>>()) {
|
||||||
data->Set(index++, prop.first, interpretedFloat->Value());
|
data->Set(index++, prop.first, interpretedFloat->Value());
|
||||||
} else if (const TypedProperty<std::string> *interpretedString = prop.second->As<TypedProperty<std::string>>()) {
|
} else if (const TypedProperty<std::string> *interpretedString = prop.second->As<TypedProperty<std::string>>()) {
|
||||||
|
@ -1176,15 +1182,23 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
|
||||||
std::vector<aiAnimMesh *> animMeshes;
|
std::vector<aiAnimMesh *> animMeshes;
|
||||||
for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
|
for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
|
||||||
for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
|
for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
|
||||||
const std::vector<const ShapeGeometry *> &shapeGeometries = blendShapeChannel->GetShapeGeometries();
|
const auto& shapeGeometries = blendShapeChannel->GetShapeGeometries();
|
||||||
for (size_t i = 0; i < shapeGeometries.size(); i++) {
|
for (const ShapeGeometry *shapeGeometry : shapeGeometries) {
|
||||||
aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh);
|
aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh);
|
||||||
const ShapeGeometry *shapeGeometry = shapeGeometries.at(i);
|
const auto &curVertices = shapeGeometry->GetVertices();
|
||||||
const std::vector<aiVector3D> &curVertices = shapeGeometry->GetVertices();
|
const auto &curNormals = shapeGeometry->GetNormals();
|
||||||
const std::vector<aiVector3D> &curNormals = shapeGeometry->GetNormals();
|
const auto &curIndices = shapeGeometry->GetIndices();
|
||||||
const std::vector<unsigned int> &curIndices = shapeGeometry->GetIndices();
|
|
||||||
//losing channel name if using shapeGeometry->Name()
|
//losing channel name if using shapeGeometry->Name()
|
||||||
animMesh->mName.Set(FixAnimMeshName(blendShapeChannel->Name()));
|
// if blendShapeChannel Name is empty or don't have a ".", add geoMetryName;
|
||||||
|
auto aniName = FixAnimMeshName(blendShapeChannel->Name());
|
||||||
|
auto geoMetryName = FixAnimMeshName(shapeGeometry->Name());
|
||||||
|
if (aniName.empty()) {
|
||||||
|
aniName = geoMetryName;
|
||||||
|
}
|
||||||
|
else if (aniName.find('.') == aniName.npos) {
|
||||||
|
aniName += "." + geoMetryName;
|
||||||
|
}
|
||||||
|
animMesh->mName.Set(aniName);
|
||||||
for (size_t j = 0; j < curIndices.size(); j++) {
|
for (size_t j = 0; j < curIndices.size(); j++) {
|
||||||
const unsigned int curIndex = curIndices.at(j);
|
const unsigned int curIndex = curIndices.at(j);
|
||||||
aiVector3D vertex = curVertices.at(j);
|
aiVector3D vertex = curVertices.at(j);
|
||||||
|
@ -1406,13 +1420,12 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
|
||||||
std::vector<aiAnimMesh *> animMeshes;
|
std::vector<aiAnimMesh *> animMeshes;
|
||||||
for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
|
for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
|
||||||
for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
|
for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
|
||||||
const std::vector<const ShapeGeometry *> &shapeGeometries = blendShapeChannel->GetShapeGeometries();
|
const auto& shapeGeometries = blendShapeChannel->GetShapeGeometries();
|
||||||
for (size_t i = 0; i < shapeGeometries.size(); i++) {
|
for (const ShapeGeometry *shapeGeometry : shapeGeometries) {
|
||||||
aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh);
|
aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh);
|
||||||
const ShapeGeometry *shapeGeometry = shapeGeometries.at(i);
|
const auto& curVertices = shapeGeometry->GetVertices();
|
||||||
const std::vector<aiVector3D> &curVertices = shapeGeometry->GetVertices();
|
const auto& curNormals = shapeGeometry->GetNormals();
|
||||||
const std::vector<aiVector3D> &curNormals = shapeGeometry->GetNormals();
|
const auto& curIndices = shapeGeometry->GetIndices();
|
||||||
const std::vector<unsigned int> &curIndices = shapeGeometry->GetIndices();
|
|
||||||
animMesh->mName.Set(FixAnimMeshName(shapeGeometry->Name()));
|
animMesh->mName.Set(FixAnimMeshName(shapeGeometry->Name()));
|
||||||
for (size_t j = 0; j < curIndices.size(); j++) {
|
for (size_t j = 0; j < curIndices.size(); j++) {
|
||||||
unsigned int curIndex = curIndices.at(j);
|
unsigned int curIndex = curIndices.at(j);
|
||||||
|
@ -1455,7 +1468,9 @@ static void copyBoneToSkeletonBone(aiMesh *mesh, aiBone *bone, aiSkeletonBone *s
|
||||||
skeletonBone->mWeights = bone->mWeights;
|
skeletonBone->mWeights = bone->mWeights;
|
||||||
skeletonBone->mOffsetMatrix = bone->mOffsetMatrix;
|
skeletonBone->mOffsetMatrix = bone->mOffsetMatrix;
|
||||||
skeletonBone->mMeshId = mesh;
|
skeletonBone->mMeshId = mesh;
|
||||||
|
#ifndef ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS
|
||||||
skeletonBone->mNode = bone->mNode;
|
skeletonBone->mNode = bone->mNode;
|
||||||
|
#endif
|
||||||
skeletonBone->mParent = -1;
|
skeletonBone->mParent = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1563,7 +1578,7 @@ void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo, const ai
|
||||||
out->mBones = nullptr;
|
out->mBones = nullptr;
|
||||||
out->mNumBones = 0;
|
out->mNumBones = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
out->mBones = new aiBone *[bones.size()]();
|
out->mBones = new aiBone *[bones.size()]();
|
||||||
out->mNumBones = static_cast<unsigned int>(bones.size());
|
out->mNumBones = static_cast<unsigned int>(bones.size());
|
||||||
|
@ -3228,7 +3243,7 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
|
|
||||||
const auto zero_epsilon = ai_epsilon;
|
const auto zero_epsilon = ai_epsilon;
|
||||||
|
|
||||||
const aiVector3D& preRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
|
const aiVector3D& preRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
|
||||||
|
|
|
@ -154,8 +154,10 @@ BlendShape::BlendShape(uint64_t id, const Element& element, const Document& doc,
|
||||||
for (const Connection* con : conns) {
|
for (const Connection* con : conns) {
|
||||||
const BlendShapeChannel* const bspc = ProcessSimpleConnection<BlendShapeChannel>(*con, false, "BlendShapeChannel -> BlendShape", element);
|
const BlendShapeChannel* const bspc = ProcessSimpleConnection<BlendShapeChannel>(*con, false, "BlendShapeChannel -> BlendShape", element);
|
||||||
if (bspc) {
|
if (bspc) {
|
||||||
blendShapeChannels.push_back(bspc);
|
auto pr = blendShapeChannels.insert(bspc);
|
||||||
continue;
|
if (!pr.second) {
|
||||||
|
FBXImporter::LogWarn("there is the same blendShapeChannel id ", bspc->ID());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,8 +181,10 @@ BlendShapeChannel::BlendShapeChannel(uint64_t id, const Element& element, const
|
||||||
for (const Connection* con : conns) {
|
for (const Connection* con : conns) {
|
||||||
const ShapeGeometry* const sg = ProcessSimpleConnection<ShapeGeometry>(*con, false, "Shape -> BlendShapeChannel", element);
|
const ShapeGeometry* const sg = ProcessSimpleConnection<ShapeGeometry>(*con, false, "Shape -> BlendShapeChannel", element);
|
||||||
if (sg) {
|
if (sg) {
|
||||||
shapeGeometries.push_back(sg);
|
auto pr = shapeGeometries.insert(sg);
|
||||||
continue;
|
if (!pr.second) {
|
||||||
|
FBXImporter::LogWarn("there is the same shapeGeometrie id ", sg->ID());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -243,7 +243,7 @@ FileGlobalSettings::FileGlobalSettings(const Document &doc, std::shared_ptr<cons
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Document::Document(const Parser& parser, const ImportSettings& settings) :
|
Document::Document(Parser& parser, const ImportSettings& settings) :
|
||||||
settings(settings), parser(parser) {
|
settings(settings), parser(parser) {
|
||||||
ASSIMP_LOG_DEBUG("Creating FBX Document");
|
ASSIMP_LOG_DEBUG("Creating FBX Document");
|
||||||
|
|
||||||
|
@ -265,13 +265,17 @@ Document::Document(const Parser& parser, const ImportSettings& settings) :
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Document::~Document() {
|
Document::~Document()
|
||||||
for(ObjectMap::value_type& v : objects) {
|
{
|
||||||
delete v.second;
|
// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(ConnectionMap::value_type& v : src_connections) {
|
for (ConnectionMap::value_type &v : src_connections) {
|
||||||
delete v.second;
|
delete_Connection(v.second);
|
||||||
}
|
}
|
||||||
// |dest_connections| contain the same Connection objects as the |src_connections|
|
// |dest_connections| contain the same Connection objects as the |src_connections|
|
||||||
}
|
}
|
||||||
|
@ -356,9 +360,11 @@ void Document::ReadObjects() {
|
||||||
DOMError("no Objects dictionary found");
|
DOMError("no Objects dictionary found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StackAllocator &allocator = parser.GetAllocator();
|
||||||
|
|
||||||
// add a dummy entry to represent the Model::RootNode object (id 0),
|
// add a dummy entry to represent the Model::RootNode object (id 0),
|
||||||
// which is only indirectly defined in the input file
|
// which is only indirectly defined in the input file
|
||||||
objects[0] = new LazyObject(0L, *eobjects, *this);
|
objects[0] = new_LazyObject(0L, *eobjects, *this);
|
||||||
|
|
||||||
const Scope& sobjects = *eobjects->Compound();
|
const Scope& sobjects = *eobjects->Compound();
|
||||||
for(const ElementMap::value_type& el : sobjects.Elements()) {
|
for(const ElementMap::value_type& el : sobjects.Elements()) {
|
||||||
|
@ -381,11 +387,13 @@ void Document::ReadObjects() {
|
||||||
DOMError("encountered object with implicitly defined id 0",el.second);
|
DOMError("encountered object with implicitly defined id 0",el.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(objects.find(id) != objects.end()) {
|
const auto foundObject = objects.find(id);
|
||||||
|
if(foundObject != objects.end()) {
|
||||||
DOMWarning("encountered duplicate object id, ignoring first occurrence",el.second);
|
DOMWarning("encountered duplicate object id, ignoring first occurrence",el.second);
|
||||||
|
delete foundObject->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
objects[id] = new LazyObject(id, *el.second, *this);
|
objects[id] = new_LazyObject(id, *el.second, *this);
|
||||||
|
|
||||||
// grab all animation stacks upfront since there is no listing of them
|
// grab all animation stacks upfront since there is no listing of them
|
||||||
if(!strcmp(el.first.c_str(),"AnimationStack")) {
|
if(!strcmp(el.first.c_str(),"AnimationStack")) {
|
||||||
|
@ -452,8 +460,10 @@ void Document::ReadPropertyTemplates() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Document::ReadConnections() {
|
void Document::ReadConnections()
|
||||||
const Scope& sc = parser.GetRootScope();
|
{
|
||||||
|
StackAllocator &allocator = parser.GetAllocator();
|
||||||
|
const Scope &sc = parser.GetRootScope();
|
||||||
// read property templates from "Definitions" section
|
// read property templates from "Definitions" section
|
||||||
const Element* const econns = sc["Connections"];
|
const Element* const econns = sc["Connections"];
|
||||||
if(!econns || !econns->Compound()) {
|
if(!econns || !econns->Compound()) {
|
||||||
|
@ -492,7 +502,7 @@ void Document::ReadConnections() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// add new connection
|
// add new connection
|
||||||
const Connection* const c = new Connection(insertionOrder++,src,dest,prop,*this);
|
const Connection* const c = new_Connection(insertionOrder++,src,dest,prop,*this);
|
||||||
src_connections.insert(ConnectionMap::value_type(src,c));
|
src_connections.insert(ConnectionMap::value_type(src,c));
|
||||||
dest_connections.insert(ConnectionMap::value_type(dest,c));
|
dest_connections.insert(ConnectionMap::value_type(dest,c));
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define INCLUDED_AI_FBX_DOCUMENT_H
|
#define INCLUDED_AI_FBX_DOCUMENT_H
|
||||||
|
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
#include <unordered_set>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <assimp/mesh.h>
|
#include <assimp/mesh.h>
|
||||||
#include "FBXProperties.h"
|
#include "FBXProperties.h"
|
||||||
|
@ -80,6 +81,10 @@ class BlendShape;
|
||||||
class Skin;
|
class Skin;
|
||||||
class Cluster;
|
class Cluster;
|
||||||
|
|
||||||
|
#define new_LazyObject new (allocator.Allocate(sizeof(LazyObject))) LazyObject
|
||||||
|
#define new_Connection new (allocator.Allocate(sizeof(Connection))) Connection
|
||||||
|
#define delete_LazyObject(_p) (_p)->~LazyObject()
|
||||||
|
#define delete_Connection(_p) (_p)->~Connection()
|
||||||
|
|
||||||
/** Represents a delay-parsed FBX objects. Many objects in the scene
|
/** Represents a delay-parsed FBX objects. Many objects in the scene
|
||||||
* are not needed by assimp, so it makes no sense to parse them
|
* are not needed by assimp, so it makes no sense to parse them
|
||||||
|
@ -855,14 +860,14 @@ public:
|
||||||
return fullWeights;
|
return fullWeights;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<const ShapeGeometry*>& GetShapeGeometries() const {
|
const std::unordered_set<const ShapeGeometry*>& GetShapeGeometries() const {
|
||||||
return shapeGeometries;
|
return shapeGeometries;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float percent;
|
float percent;
|
||||||
WeightArray fullWeights;
|
WeightArray fullWeights;
|
||||||
std::vector<const ShapeGeometry*> shapeGeometries;
|
std::unordered_set<const ShapeGeometry*> shapeGeometries;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** DOM class for BlendShape deformers */
|
/** DOM class for BlendShape deformers */
|
||||||
|
@ -872,12 +877,12 @@ public:
|
||||||
|
|
||||||
virtual ~BlendShape();
|
virtual ~BlendShape();
|
||||||
|
|
||||||
const std::vector<const BlendShapeChannel*>& BlendShapeChannels() const {
|
const std::unordered_set<const BlendShapeChannel*>& BlendShapeChannels() const {
|
||||||
return blendShapeChannels;
|
return blendShapeChannels;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<const BlendShapeChannel*> blendShapeChannels;
|
std::unordered_set<const BlendShapeChannel*> blendShapeChannels;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** DOM class for skin deformer clusters (aka sub-deformers) */
|
/** DOM class for skin deformer clusters (aka sub-deformers) */
|
||||||
|
@ -1072,7 +1077,7 @@ private:
|
||||||
/** DOM root for a FBX file */
|
/** DOM root for a FBX file */
|
||||||
class Document {
|
class Document {
|
||||||
public:
|
public:
|
||||||
Document(const Parser& parser, const ImportSettings& settings);
|
Document(Parser& parser, const ImportSettings& settings);
|
||||||
|
|
||||||
~Document();
|
~Document();
|
||||||
|
|
||||||
|
@ -1156,7 +1161,7 @@ private:
|
||||||
const ImportSettings& settings;
|
const ImportSettings& settings;
|
||||||
|
|
||||||
ObjectMap objects;
|
ObjectMap objects;
|
||||||
const Parser& parser;
|
Parser& parser;
|
||||||
|
|
||||||
PropertyTemplateMap templates;
|
PropertyTemplateMap templates;
|
||||||
ConnectionMap src_connections;
|
ConnectionMap src_connections;
|
||||||
|
|
|
@ -360,7 +360,7 @@ void FBX::Node::EndBinary(
|
||||||
bool has_children
|
bool has_children
|
||||||
) {
|
) {
|
||||||
// if there were children, add a null record
|
// if there were children, add a null record
|
||||||
if (has_children) { s.PutString(Assimp::FBX::NULL_RECORD); }
|
if (has_children) { s.PutString(Assimp::FBX::NULL_RECORD_STRING); }
|
||||||
|
|
||||||
// now go back and write initial pos
|
// now go back and write initial pos
|
||||||
this->end_pos = s.Tell();
|
this->end_pos = s.Tell();
|
||||||
|
|
|
@ -77,8 +77,6 @@ public: // constructors
|
||||||
/// The class constructor with the name.
|
/// The class constructor with the name.
|
||||||
Node(const std::string& n)
|
Node(const std::string& n)
|
||||||
: name(n)
|
: name(n)
|
||||||
, properties()
|
|
||||||
, children()
|
|
||||||
, force_has_children( false ) {
|
, force_has_children( false ) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
@ -87,8 +85,6 @@ public: // constructors
|
||||||
template <typename... More>
|
template <typename... More>
|
||||||
Node(const std::string& n, More&&... more)
|
Node(const std::string& n, More&&... more)
|
||||||
: name(n)
|
: name(n)
|
||||||
, properties()
|
|
||||||
, children()
|
|
||||||
, force_has_children(false) {
|
, force_has_children(false) {
|
||||||
AddProperties(std::forward<More>(more)...);
|
AddProperties(std::forward<More>(more)...);
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,8 +62,7 @@ namespace Assimp {
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
const char *LogFunctions<FBXImporter>::Prefix() {
|
const char *LogFunctions<FBXImporter>::Prefix() {
|
||||||
static auto prefix = "FBX: ";
|
return "FBX: ";
|
||||||
return prefix;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Assimp
|
} // namespace Assimp
|
||||||
|
@ -90,10 +89,7 @@ static const aiImporterDesc desc = {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by #Importer
|
// Constructor to be privately used by #Importer
|
||||||
FBXImporter::FBXImporter() :
|
FBXImporter::FBXImporter() = default;
|
||||||
mSettings() {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
|
@ -156,19 +152,19 @@ void FBXImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
||||||
// broad-phase tokenized pass in which we identify the core
|
// broad-phase tokenized pass in which we identify the core
|
||||||
// syntax elements of FBX (brackets, commas, key:value mappings)
|
// syntax elements of FBX (brackets, commas, key:value mappings)
|
||||||
TokenList tokens;
|
TokenList tokens;
|
||||||
try {
|
Assimp::StackAllocator tempAllocator;
|
||||||
|
try {
|
||||||
bool is_binary = false;
|
bool is_binary = false;
|
||||||
if (!strncmp(begin, "Kaydara FBX Binary", 18)) {
|
if (!strncmp(begin, "Kaydara FBX Binary", 18)) {
|
||||||
is_binary = true;
|
is_binary = true;
|
||||||
TokenizeBinary(tokens, begin, contents.size());
|
TokenizeBinary(tokens, begin, contents.size(), tempAllocator);
|
||||||
} else {
|
} else {
|
||||||
Tokenize(tokens, begin);
|
Tokenize(tokens, begin, tempAllocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
// use this information to construct a very rudimentary
|
// use this information to construct a very rudimentary
|
||||||
// parse-tree representing the FBX scope structure
|
// parse-tree representing the FBX scope structure
|
||||||
Parser parser(tokens, is_binary);
|
Parser parser(tokens, tempAllocator, is_binary);
|
||||||
|
|
||||||
// take the raw parse-tree and convert it to a FBX DOM
|
// take the raw parse-tree and convert it to a FBX DOM
|
||||||
Document doc(parser, mSettings);
|
Document doc(parser, mSettings);
|
||||||
|
@ -187,10 +183,12 @@ void FBXImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
||||||
// assimp universal format (M)
|
// assimp universal format (M)
|
||||||
SetFileScale(size_relative_to_cm * 0.01f);
|
SetFileScale(size_relative_to_cm * 0.01f);
|
||||||
|
|
||||||
std::for_each(tokens.begin(), tokens.end(), Util::delete_fun<Token>());
|
// This collection does not own the memory for the tokens, but we need to call their d'tor
|
||||||
} catch (std::exception &) {
|
std::for_each(tokens.begin(), tokens.end(), Util::destructor_fun<Token>());
|
||||||
std::for_each(tokens.begin(), tokens.end(), Util::delete_fun<Token>());
|
|
||||||
throw;
|
} catch (std::exception &) {
|
||||||
|
std::for_each(tokens.begin(), tokens.end(), Util::destructor_fun<Token>());
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -138,20 +138,6 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Material::~Material() = default;
|
Material::~Material() = default;
|
||||||
|
|
||||||
aiVector2D uvTrans;
|
|
||||||
aiVector2D uvScaling;
|
|
||||||
ai_real uvRotation;
|
|
||||||
|
|
||||||
std::string type;
|
|
||||||
std::string relativeFileName;
|
|
||||||
std::string fileName;
|
|
||||||
std::string alphaSource;
|
|
||||||
std::shared_ptr<const PropertyTable> props;
|
|
||||||
|
|
||||||
unsigned int crop[4]{};
|
|
||||||
|
|
||||||
const Video* media;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Texture::Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name) :
|
Texture::Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name) :
|
||||||
Object(id,element,name),
|
Object(id,element,name),
|
||||||
|
|
|
@ -69,13 +69,16 @@ Geometry::Geometry(uint64_t id, const Element& element, const std::string& name,
|
||||||
}
|
}
|
||||||
const BlendShape* const bsp = ProcessSimpleConnection<BlendShape>(*con, false, "BlendShape -> Geometry", element);
|
const BlendShape* const bsp = ProcessSimpleConnection<BlendShape>(*con, false, "BlendShape -> Geometry", element);
|
||||||
if (bsp) {
|
if (bsp) {
|
||||||
blendShapes.push_back(bsp);
|
auto pr = blendShapes.insert(bsp);
|
||||||
|
if (!pr.second) {
|
||||||
|
FBXImporter::LogWarn("there is the same blendShape id ", bsp->ID());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const std::vector<const BlendShape*>& Geometry::GetBlendShapes() const {
|
const std::unordered_set<const BlendShape*>& Geometry::GetBlendShapes() const {
|
||||||
return blendShapes;
|
return blendShapes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2023, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -53,84 +52,101 @@ namespace Assimp {
|
||||||
namespace FBX {
|
namespace FBX {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DOM base class for all kinds of FBX geometry
|
* @brief DOM base class for all kinds of FBX geometry
|
||||||
*/
|
*/
|
||||||
class Geometry : public Object {
|
class Geometry : public Object {
|
||||||
public:
|
public:
|
||||||
/// @brief The class constructor with all parameters.
|
/// @brief The class constructor with all parameters.
|
||||||
/// @param id The id.
|
/// @param id The id.
|
||||||
/// @param element
|
/// @param element The element instance
|
||||||
/// @param name
|
/// @param name The name instance
|
||||||
/// @param doc
|
/// @param doc The document instance
|
||||||
Geometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
|
Geometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
|
||||||
|
|
||||||
|
/// @brief The class destructor, default.
|
||||||
virtual ~Geometry() = default;
|
virtual ~Geometry() = default;
|
||||||
|
|
||||||
/// Get the Skin attached to this geometry or nullptr
|
/// @brief Get the Skin attached to this geometry or nullptr.
|
||||||
|
/// @return The deformer skip instance as a pointer, nullptr if none.
|
||||||
const Skin* DeformerSkin() const;
|
const Skin* DeformerSkin() const;
|
||||||
|
|
||||||
/// Get the BlendShape attached to this geometry or nullptr
|
/// @brief Get the BlendShape attached to this geometry or nullptr
|
||||||
const std::vector<const BlendShape*>& GetBlendShapes() const;
|
/// @return The blendshape arrays.
|
||||||
|
const std::unordered_set<const BlendShape*>& GetBlendShapes() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Skin* skin;
|
const Skin* skin;
|
||||||
std::vector<const BlendShape*> blendShapes;
|
std::unordered_set<const BlendShape*> blendShapes;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<int> MatIndexArray;
|
typedef std::vector<int> MatIndexArray;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DOM class for FBX geometry of type "Mesh"
|
* @brief DOM class for FBX geometry of type "Mesh"
|
||||||
*/
|
*/
|
||||||
class MeshGeometry : public Geometry {
|
class MeshGeometry : public Geometry {
|
||||||
public:
|
public:
|
||||||
/** The class constructor */
|
/// @brief The class constructor
|
||||||
|
/// @param id The id.
|
||||||
|
/// @param element The element instance
|
||||||
|
/// @param name The name instance
|
||||||
|
/// @param doc The document instance
|
||||||
MeshGeometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
|
MeshGeometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
|
||||||
|
|
||||||
/** The class destructor */
|
/// @brief The class destructor, default.
|
||||||
virtual ~MeshGeometry() = default;
|
virtual ~MeshGeometry() = default;
|
||||||
|
|
||||||
/** Get a list of all vertex points, non-unique*/
|
/// brief Get a vector of all vertex points, non-unique.
|
||||||
|
/// @return The vertices vector.
|
||||||
const std::vector<aiVector3D>& GetVertices() const;
|
const std::vector<aiVector3D>& GetVertices() const;
|
||||||
|
|
||||||
/** Get a list of all vertex normals or an empty array if
|
/// @brief Get a vector of all vertex normals or an empty array if no normals are specified.
|
||||||
* no normals are specified. */
|
/// @return The normal vector.
|
||||||
const std::vector<aiVector3D>& GetNormals() const;
|
const std::vector<aiVector3D>& GetNormals() const;
|
||||||
|
|
||||||
/** Get a list of all vertex tangents or an empty array
|
/// @brief Get a vector of all vertex tangents or an empty array if no tangents are specified.
|
||||||
* if no tangents are specified */
|
/// @return The vertex tangents vector.
|
||||||
const std::vector<aiVector3D>& GetTangents() const;
|
const std::vector<aiVector3D>& GetTangents() const;
|
||||||
|
|
||||||
/** Get a list of all vertex bi-normals or an empty array
|
/// @brief Get a vector of all vertex bi-normals or an empty array if no bi-normals are specified.
|
||||||
* if no bi-normals are specified */
|
/// @return The binomal vector.
|
||||||
const std::vector<aiVector3D>& GetBinormals() const;
|
const std::vector<aiVector3D>& GetBinormals() const;
|
||||||
|
|
||||||
/** Return list of faces - each entry denotes a face and specifies
|
/// @brief Return list of faces - each entry denotes a face and specifies how many vertices it has.
|
||||||
* how many vertices it has. Vertices are taken from the
|
/// Vertices are taken from the vertex data arrays in sequential order.
|
||||||
* vertex data arrays in sequential order. */
|
/// @return The face indices vector.
|
||||||
const std::vector<unsigned int>& GetFaceIndexCounts() const;
|
const std::vector<unsigned int>& GetFaceIndexCounts() const;
|
||||||
|
|
||||||
/** Get a UV coordinate slot, returns an empty array if
|
/// @brief Get a UV coordinate slot, returns an empty array if the requested slot does not exist.
|
||||||
* the requested slot does not exist. */
|
/// @param index The requested texture coordinate slot.
|
||||||
|
/// @return The texture coordinates.
|
||||||
const std::vector<aiVector2D>& GetTextureCoords( unsigned int index ) const;
|
const std::vector<aiVector2D>& GetTextureCoords( unsigned int index ) const;
|
||||||
|
|
||||||
/** Get a UV coordinate slot, returns an empty array if
|
/// @brief Get a UV coordinate slot, returns an empty array if the requested slot does not exist.
|
||||||
* the requested slot does not exist. */
|
/// @param index The requested texture coordinate slot.
|
||||||
|
/// @return The texture coordinate channel name.
|
||||||
std::string GetTextureCoordChannelName( unsigned int index ) const;
|
std::string GetTextureCoordChannelName( unsigned int index ) const;
|
||||||
|
|
||||||
/** Get a vertex color coordinate slot, returns an empty array if
|
/// @brief Get a vertex color coordinate slot, returns an empty array if the requested slot does not exist.
|
||||||
* the requested slot does not exist. */
|
/// @param index The requested texture coordinate slot.
|
||||||
|
/// @return The vertex color vector.
|
||||||
const std::vector<aiColor4D>& GetVertexColors( unsigned int index ) const;
|
const std::vector<aiColor4D>& GetVertexColors( unsigned int index ) const;
|
||||||
|
|
||||||
/** Get per-face-vertex material assignments */
|
/// @brief Get per-face-vertex material assignments.
|
||||||
|
/// @return The Material indices Array.
|
||||||
const MatIndexArray& GetMaterialIndices() const;
|
const MatIndexArray& GetMaterialIndices() const;
|
||||||
|
|
||||||
/** Convert from a fbx file vertex index (for example from a #Cluster weight) or nullptr
|
/// @brief Convert from a fbx file vertex index (for example from a #Cluster weight) or nullptr if the vertex index is not valid.
|
||||||
* if the vertex index is not valid. */
|
/// @param in_index The requested input index.
|
||||||
|
/// @param count The number of indices.
|
||||||
|
/// @return The indices.
|
||||||
const unsigned int* ToOutputVertexIndex( unsigned int in_index, unsigned int& count ) const;
|
const unsigned int* ToOutputVertexIndex( unsigned int in_index, unsigned int& count ) const;
|
||||||
|
|
||||||
/** Determine the face to which a particular output vertex index belongs.
|
/// @brief Determine the face to which a particular output vertex index belongs.
|
||||||
* This mapping is always unique. */
|
/// This mapping is always unique.
|
||||||
|
/// @param in_index The requested input index.
|
||||||
|
/// @return The face-to-vertex index.
|
||||||
unsigned int FaceForVertexIndex( unsigned int in_index ) const;
|
unsigned int FaceForVertexIndex( unsigned int in_index ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -88,6 +88,7 @@ namespace {
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
AI_WONT_RETURN void ParseError(const std::string& message, TokenPtr token) AI_WONT_RETURN_SUFFIX;
|
||||||
void ParseError(const std::string& message, TokenPtr token)
|
void ParseError(const std::string& message, TokenPtr token)
|
||||||
{
|
{
|
||||||
if(token) {
|
if(token) {
|
||||||
|
@ -115,8 +116,11 @@ namespace Assimp {
|
||||||
namespace FBX {
|
namespace FBX {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Element::Element(const Token& key_token, Parser& parser) : key_token(key_token) {
|
Element::Element(const Token& key_token, Parser& parser) :
|
||||||
|
key_token(key_token), compound(nullptr)
|
||||||
|
{
|
||||||
TokenPtr n = nullptr;
|
TokenPtr n = nullptr;
|
||||||
|
StackAllocator &allocator = parser.GetAllocator();
|
||||||
do {
|
do {
|
||||||
n = parser.AdvanceToNextToken();
|
n = parser.AdvanceToNextToken();
|
||||||
if(!n) {
|
if(!n) {
|
||||||
|
@ -145,7 +149,7 @@ Element::Element(const Token& key_token, Parser& parser) : key_token(key_token)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n->Type() == TokenType_OPEN_BRACKET) {
|
if (n->Type() == TokenType_OPEN_BRACKET) {
|
||||||
compound.reset(new Scope(parser));
|
compound = new_Scope(parser);
|
||||||
|
|
||||||
// current token should be a TOK_CLOSE_BRACKET
|
// current token should be a TOK_CLOSE_BRACKET
|
||||||
n = parser.CurrentToken();
|
n = parser.CurrentToken();
|
||||||
|
@ -163,6 +167,15 @@ Element::Element(const Token& key_token, Parser& parser) : key_token(key_token)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
Element::~Element()
|
||||||
|
{
|
||||||
|
if (compound) {
|
||||||
|
delete_Scope(compound);
|
||||||
|
}
|
||||||
|
|
||||||
|
// no need to delete tokens, they are owned by the parser
|
||||||
|
}
|
||||||
|
|
||||||
Scope::Scope(Parser& parser,bool topLevel)
|
Scope::Scope(Parser& parser,bool topLevel)
|
||||||
{
|
{
|
||||||
if(!topLevel) {
|
if(!topLevel) {
|
||||||
|
@ -172,6 +185,7 @@ Scope::Scope(Parser& parser,bool topLevel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StackAllocator &allocator = parser.GetAllocator();
|
||||||
TokenPtr n = parser.AdvanceToNextToken();
|
TokenPtr n = parser.AdvanceToNextToken();
|
||||||
if (n == nullptr) {
|
if (n == nullptr) {
|
||||||
ParseError("unexpected end of file");
|
ParseError("unexpected end of file");
|
||||||
|
@ -187,37 +201,46 @@ Scope::Scope(Parser& parser,bool topLevel)
|
||||||
if (str.empty()) {
|
if (str.empty()) {
|
||||||
ParseError("unexpected content: empty string.");
|
ParseError("unexpected content: empty string.");
|
||||||
}
|
}
|
||||||
|
|
||||||
elements.insert(ElementMap::value_type(str,new_Element(*n,parser)));
|
auto *element = new_Element(*n, parser);
|
||||||
|
|
||||||
// Element() should stop at the next Key token (or right after a Close token)
|
// Element() should stop at the next Key token (or right after a Close token)
|
||||||
n = parser.CurrentToken();
|
n = parser.CurrentToken();
|
||||||
if (n == nullptr) {
|
if (n == nullptr) {
|
||||||
if (topLevel) {
|
if (topLevel) {
|
||||||
|
elements.insert(ElementMap::value_type(str, element));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
delete element;
|
||||||
ParseError("unexpected end of file",parser.LastToken());
|
ParseError("unexpected end of file",parser.LastToken());
|
||||||
|
} else {
|
||||||
|
elements.insert(ElementMap::value_type(str, element));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Scope::~Scope() {
|
Scope::~Scope()
|
||||||
for(ElementMap::value_type& v : elements) {
|
{
|
||||||
delete v.second;
|
// This collection does not own the memory for the elements, but we need to call their d'tor:
|
||||||
|
|
||||||
|
for (ElementMap::value_type &v : elements) {
|
||||||
|
delete_Element(v.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Parser::Parser (const TokenList& tokens, bool is_binary)
|
Parser::Parser(const TokenList &tokens, StackAllocator &allocator, bool is_binary) :
|
||||||
: tokens(tokens)
|
tokens(tokens), allocator(allocator), last(), current(), cursor(tokens.begin()), is_binary(is_binary)
|
||||||
, last()
|
|
||||||
, current()
|
|
||||||
, cursor(tokens.begin())
|
|
||||||
, is_binary(is_binary)
|
|
||||||
{
|
{
|
||||||
ASSIMP_LOG_DEBUG("Parsing FBX tokens");
|
ASSIMP_LOG_DEBUG("Parsing FBX tokens");
|
||||||
root.reset(new Scope(*this,true));
|
root = new_Scope(*this, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
Parser::~Parser()
|
||||||
|
{
|
||||||
|
delete_Scope(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -52,6 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/LogAux.h>
|
#include <assimp/LogAux.h>
|
||||||
#include <assimp/fast_atof.h>
|
#include <assimp/fast_atof.h>
|
||||||
|
|
||||||
|
#include "Common/StackAllocator.h"
|
||||||
#include "FBXCompileConfig.h"
|
#include "FBXCompileConfig.h"
|
||||||
#include "FBXTokenizer.h"
|
#include "FBXTokenizer.h"
|
||||||
|
|
||||||
|
@ -63,14 +64,14 @@ class Parser;
|
||||||
class Element;
|
class Element;
|
||||||
|
|
||||||
// XXX should use C++11's unique_ptr - but assimp's need to keep working with 03
|
// XXX should use C++11's unique_ptr - but assimp's need to keep working with 03
|
||||||
typedef std::vector< Scope* > ScopeList;
|
using ScopeList = std::vector<Scope*>;
|
||||||
typedef std::fbx_unordered_multimap< std::string, Element* > ElementMap;
|
using ElementMap = std::fbx_unordered_multimap< std::string, Element*>;
|
||||||
|
using ElementCollection = std::pair<ElementMap::const_iterator,ElementMap::const_iterator>;
|
||||||
typedef std::pair<ElementMap::const_iterator,ElementMap::const_iterator> ElementCollection;
|
|
||||||
|
|
||||||
# define new_Scope new Scope
|
|
||||||
# define new_Element new Element
|
|
||||||
|
|
||||||
|
#define new_Scope new (allocator.Allocate(sizeof(Scope))) Scope
|
||||||
|
#define new_Element new (allocator.Allocate(sizeof(Element))) Element
|
||||||
|
#define delete_Scope(_p) (_p)->~Scope()
|
||||||
|
#define delete_Element(_p) (_p)->~Element()
|
||||||
|
|
||||||
/** FBX data entity that consists of a key:value tuple.
|
/** FBX data entity that consists of a key:value tuple.
|
||||||
*
|
*
|
||||||
|
@ -82,15 +83,16 @@ typedef std::pair<ElementMap::const_iterator,ElementMap::const_iterator> Element
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*
|
*
|
||||||
* As can be seen in this sample, elements can contain nested #Scope
|
* As can be seen in this sample, elements can contain nested #Scope
|
||||||
* as their trailing member. **/
|
* as their trailing member.
|
||||||
|
**/
|
||||||
class Element
|
class Element
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Element(const Token& key_token, Parser& parser);
|
Element(const Token& key_token, Parser& parser);
|
||||||
~Element() = default;
|
~Element();
|
||||||
|
|
||||||
const Scope* Compound() const {
|
const Scope* Compound() const {
|
||||||
return compound.get();
|
return compound;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Token& KeyToken() const {
|
const Token& KeyToken() const {
|
||||||
|
@ -104,7 +106,7 @@ public:
|
||||||
private:
|
private:
|
||||||
const Token& key_token;
|
const Token& key_token;
|
||||||
TokenList tokens;
|
TokenList tokens;
|
||||||
std::unique_ptr<Scope> compound;
|
Scope* compound;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** FBX data entity that consists of a 'scope', a collection
|
/** FBX data entity that consists of a 'scope', a collection
|
||||||
|
@ -159,8 +161,8 @@ class Parser
|
||||||
public:
|
public:
|
||||||
/** Parse given a token list. Does not take ownership of the tokens -
|
/** Parse given a token list. Does not take ownership of the tokens -
|
||||||
* the objects must persist during the entire parser lifetime */
|
* the objects must persist during the entire parser lifetime */
|
||||||
Parser (const TokenList& tokens,bool is_binary);
|
Parser(const TokenList &tokens, StackAllocator &allocator, bool is_binary);
|
||||||
~Parser() = default;
|
~Parser();
|
||||||
|
|
||||||
const Scope& GetRootScope() const {
|
const Scope& GetRootScope() const {
|
||||||
return *root;
|
return *root;
|
||||||
|
@ -170,6 +172,10 @@ public:
|
||||||
return is_binary;
|
return is_binary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StackAllocator &GetAllocator() {
|
||||||
|
return allocator;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Scope;
|
friend class Scope;
|
||||||
friend class Element;
|
friend class Element;
|
||||||
|
@ -180,10 +186,10 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const TokenList& tokens;
|
const TokenList& tokens;
|
||||||
|
StackAllocator &allocator;
|
||||||
TokenPtr last, current;
|
TokenPtr last, current;
|
||||||
TokenList::const_iterator cursor;
|
TokenList::const_iterator cursor;
|
||||||
std::unique_ptr<Scope> root;
|
Scope *root;
|
||||||
|
|
||||||
const bool is_binary;
|
const bool is_binary;
|
||||||
};
|
};
|
||||||
|
|
|
@ -94,7 +94,8 @@ AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int line,
|
||||||
|
|
||||||
// process a potential data token up to 'cur', adding it to 'output_tokens'.
|
// process a potential data token up to 'cur', adding it to 'output_tokens'.
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ProcessDataToken( TokenList& output_tokens, const char*& start, const char*& end,
|
void ProcessDataToken(TokenList &output_tokens, StackAllocator &token_allocator,
|
||||||
|
const char*& start, const char*& end,
|
||||||
unsigned int line,
|
unsigned int line,
|
||||||
unsigned int column,
|
unsigned int column,
|
||||||
TokenType type = TokenType_DATA,
|
TokenType type = TokenType_DATA,
|
||||||
|
@ -131,8 +132,7 @@ void ProcessDataToken( TokenList& output_tokens, const char*& start, const char*
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Tokenize(TokenList& output_tokens, const char* input)
|
void Tokenize(TokenList &output_tokens, const char *input, StackAllocator &token_allocator) {
|
||||||
{
|
|
||||||
ai_assert(input);
|
ai_assert(input);
|
||||||
ASSIMP_LOG_DEBUG("Tokenizing ASCII FBX file");
|
ASSIMP_LOG_DEBUG("Tokenizing ASCII FBX file");
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ void Tokenize(TokenList& output_tokens, const char* input)
|
||||||
in_double_quotes = false;
|
in_double_quotes = false;
|
||||||
token_end = cur;
|
token_end = cur;
|
||||||
|
|
||||||
ProcessDataToken(output_tokens,token_begin,token_end,line,column);
|
ProcessDataToken(output_tokens, token_allocator, token_begin, token_end, line, column);
|
||||||
pending_data_token = false;
|
pending_data_token = false;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
@ -181,30 +181,30 @@ void Tokenize(TokenList& output_tokens, const char* input)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case ';':
|
case ';':
|
||||||
ProcessDataToken(output_tokens,token_begin,token_end,line,column);
|
ProcessDataToken(output_tokens, token_allocator, token_begin, token_end, line, column);
|
||||||
comment = true;
|
comment = true;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case '{':
|
case '{':
|
||||||
ProcessDataToken(output_tokens,token_begin,token_end, line, column);
|
ProcessDataToken(output_tokens, token_allocator, token_begin, token_end, line, column);
|
||||||
output_tokens.push_back(new_Token(cur,cur+1,TokenType_OPEN_BRACKET,line,column));
|
output_tokens.push_back(new_Token(cur,cur+1,TokenType_OPEN_BRACKET,line,column));
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case '}':
|
case '}':
|
||||||
ProcessDataToken(output_tokens,token_begin,token_end,line,column);
|
ProcessDataToken(output_tokens, token_allocator, token_begin, token_end, line, column);
|
||||||
output_tokens.push_back(new_Token(cur,cur+1,TokenType_CLOSE_BRACKET,line,column));
|
output_tokens.push_back(new_Token(cur,cur+1,TokenType_CLOSE_BRACKET,line,column));
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case ',':
|
case ',':
|
||||||
if (pending_data_token) {
|
if (pending_data_token) {
|
||||||
ProcessDataToken(output_tokens,token_begin,token_end,line,column,TokenType_DATA,true);
|
ProcessDataToken(output_tokens, token_allocator, token_begin, token_end, line, column, TokenType_DATA, true);
|
||||||
}
|
}
|
||||||
output_tokens.push_back(new_Token(cur,cur+1,TokenType_COMMA,line,column));
|
output_tokens.push_back(new_Token(cur,cur+1,TokenType_COMMA,line,column));
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case ':':
|
case ':':
|
||||||
if (pending_data_token) {
|
if (pending_data_token) {
|
||||||
ProcessDataToken(output_tokens,token_begin,token_end,line,column,TokenType_KEY,true);
|
ProcessDataToken(output_tokens, token_allocator, token_begin, token_end, line, column, TokenType_KEY, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TokenizeError("unexpected colon", line, column);
|
TokenizeError("unexpected colon", line, column);
|
||||||
|
@ -226,7 +226,7 @@ void Tokenize(TokenList& output_tokens, const char* input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessDataToken(output_tokens,token_begin,token_end,line,column,type);
|
ProcessDataToken(output_tokens, token_allocator, token_begin, token_end, line, column, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
pending_data_token = false;
|
pending_data_token = false;
|
||||||
|
|
|
@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define INCLUDED_AI_FBX_TOKENIZER_H
|
#define INCLUDED_AI_FBX_TOKENIZER_H
|
||||||
|
|
||||||
#include "FBXCompileConfig.h"
|
#include "FBXCompileConfig.h"
|
||||||
|
#include "Common/StackAllocator.h"
|
||||||
#include <assimp/ai_assert.h>
|
#include <assimp/ai_assert.h>
|
||||||
#include <assimp/defs.h>
|
#include <assimp/defs.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -154,11 +155,11 @@ private:
|
||||||
const unsigned int column;
|
const unsigned int column;
|
||||||
};
|
};
|
||||||
|
|
||||||
// XXX should use C++11's unique_ptr - but assimp's need to keep working with 03
|
|
||||||
typedef const Token* TokenPtr;
|
typedef const Token* TokenPtr;
|
||||||
typedef std::vector< TokenPtr > TokenList;
|
typedef std::vector< TokenPtr > TokenList;
|
||||||
|
|
||||||
#define new_Token new Token
|
#define new_Token new (token_allocator.Allocate(sizeof(Token))) Token
|
||||||
|
#define delete_Token(_p) (_p)->~Token()
|
||||||
|
|
||||||
|
|
||||||
/** Main FBX tokenizer function. Transform input buffer into a list of preprocessed tokens.
|
/** Main FBX tokenizer function. Transform input buffer into a list of preprocessed tokens.
|
||||||
|
@ -168,7 +169,7 @@ typedef std::vector< TokenPtr > TokenList;
|
||||||
* @param output_tokens Receives a list of all tokens in the input data.
|
* @param output_tokens Receives a list of all tokens in the input data.
|
||||||
* @param input_buffer Textual input buffer to be processed, 0-terminated.
|
* @param input_buffer Textual input buffer to be processed, 0-terminated.
|
||||||
* @throw DeadlyImportError if something goes wrong */
|
* @throw DeadlyImportError if something goes wrong */
|
||||||
void Tokenize(TokenList& output_tokens, const char* input);
|
void Tokenize(TokenList &output_tokens, const char *input, StackAllocator &tokenAllocator);
|
||||||
|
|
||||||
|
|
||||||
/** Tokenizer function for binary FBX files.
|
/** Tokenizer function for binary FBX files.
|
||||||
|
@ -179,7 +180,7 @@ void Tokenize(TokenList& output_tokens, const char* input);
|
||||||
* @param input_buffer Binary input buffer to be processed.
|
* @param input_buffer Binary input buffer to be processed.
|
||||||
* @param length Length of input buffer, in bytes. There is no 0-terminal.
|
* @param length Length of input buffer, in bytes. There is no 0-terminal.
|
||||||
* @throw DeadlyImportError if something goes wrong */
|
* @throw DeadlyImportError if something goes wrong */
|
||||||
void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length);
|
void TokenizeBinary(TokenList &output_tokens, const char *input, size_t length, StackAllocator &tokenAllocator);
|
||||||
|
|
||||||
|
|
||||||
} // ! FBX
|
} // ! FBX
|
||||||
|
|
|
@ -66,6 +66,17 @@ struct delete_fun
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** helper for std::for_each to call the destructor on all items in a container without freeing their heap*/
|
||||||
|
template <typename T>
|
||||||
|
struct destructor_fun {
|
||||||
|
void operator()(const volatile T* del) {
|
||||||
|
if (del) {
|
||||||
|
del->~T();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/** Get a string representation for a #TokenType. */
|
/** Get a string representation for a #TokenType. */
|
||||||
const char* TokenTypeString(TokenType t);
|
const char* TokenTypeString(TokenType t);
|
||||||
|
|
||||||
|
|
|
@ -327,7 +327,7 @@ void HMPImporter::CreateMaterial(const unsigned char *szCurrent,
|
||||||
ReadFirstSkin(pcHeader->numskins, szCurrent, &szCurrent);
|
ReadFirstSkin(pcHeader->numskins, szCurrent, &szCurrent);
|
||||||
*szCurrentOut = szCurrent;
|
*szCurrentOut = szCurrent;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate a default material
|
// generate a default material
|
||||||
const int iMode = (int)aiShadingMode_Gouraud;
|
const int iMode = (int)aiShadingMode_Gouraud;
|
||||||
|
@ -484,11 +484,11 @@ void HMPImporter::GenerateTextureCoords(const unsigned int width, const unsigned
|
||||||
if (uv == nullptr) {
|
if (uv == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (height == 0.0f || width == 0.0) {
|
if (height == 0.0f || width == 0.0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const float fY = (1.0f / height) + (1.0f / height) / height;
|
const float fY = (1.0f / height) + (1.0f / height) / height;
|
||||||
const float fX = (1.0f / width) + (1.0f / width) / width;
|
const float fX = (1.0f / width) + (1.0f / width) / width;
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ protected:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Import a HMP4 file
|
/** Import a HMP4 file
|
||||||
*/
|
*/
|
||||||
void InternReadFile_HMP4();
|
AI_WONT_RETURN void InternReadFile_HMP4() AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Import a HMP5 file
|
/** Import a HMP5 file
|
||||||
|
|
|
@ -73,8 +73,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
template <>
|
template <>
|
||||||
const char *LogFunctions<IFCImporter>::Prefix() {
|
const char *LogFunctions<IFCImporter>::Prefix() {
|
||||||
static auto prefix = "IFC: ";
|
return "IFC: ";
|
||||||
return prefix;
|
|
||||||
}
|
}
|
||||||
} // namespace Assimp
|
} // namespace Assimp
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "AssetLib/IFC/IFCUtil.h"
|
#include "AssetLib/IFC/IFCUtil.h"
|
||||||
#include "Common/PolyTools.h"
|
#include "Common/PolyTools.h"
|
||||||
|
#include "Geometry/GeometryUtils.h"
|
||||||
#include "PostProcessing/ProcessHelper.h"
|
#include "PostProcessing/ProcessHelper.h"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
@ -235,7 +236,7 @@ IfcVector3 TempMesh::ComputeLastPolygonNormal(bool normalize) const {
|
||||||
struct CompareVector {
|
struct CompareVector {
|
||||||
bool operator () (const IfcVector3& a, const IfcVector3& b) const {
|
bool operator () (const IfcVector3& a, const IfcVector3& b) const {
|
||||||
IfcVector3 d = a - b;
|
IfcVector3 d = a - b;
|
||||||
IfcFloat eps = ai_epsilon;
|
constexpr IfcFloat eps = ai_epsilon;
|
||||||
return d.x < -eps || (std::abs(d.x) < eps && d.y < -eps) || (std::abs(d.x) < eps && std::abs(d.y) < eps && d.z < -eps);
|
return d.x < -eps || (std::abs(d.x) < eps && d.y < -eps) || (std::abs(d.x) < eps && std::abs(d.y) < eps && d.z < -eps);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -71,11 +71,7 @@ static const aiImporterDesc desc = {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
IRRMeshImporter::IRRMeshImporter() :
|
IRRMeshImporter::IRRMeshImporter() = default;
|
||||||
BaseImporter(),
|
|
||||||
IrrlichtBase() {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor, private as well
|
// Destructor, private as well
|
||||||
|
|
|
@ -63,9 +63,7 @@ protected:
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
~IrrlichtBase() {
|
~IrrlichtBase() = default;
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @brief Data structure for a simple name-value property
|
/** @brief Data structure for a simple name-value property
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -162,8 +162,11 @@ void AnimResolver::UpdateAnimRangeSetup() {
|
||||||
const double my_last = (*it).keys.back().time;
|
const double my_last = (*it).keys.back().time;
|
||||||
|
|
||||||
const double delta = my_last - my_first;
|
const double delta = my_last - my_first;
|
||||||
const size_t old_size = (*it).keys.size();
|
if (delta == 0.0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t old_size = (*it).keys.size();
|
||||||
const float value_delta = (*it).keys.back().value - (*it).keys.front().value;
|
const float value_delta = (*it).keys.back().value - (*it).keys.front().value;
|
||||||
|
|
||||||
// NOTE: We won't handle reset, linear and constant here.
|
// NOTE: We won't handle reset, linear and constant here.
|
||||||
|
@ -176,8 +179,7 @@ void AnimResolver::UpdateAnimRangeSetup() {
|
||||||
case LWO::PrePostBehaviour_Oscillate: {
|
case LWO::PrePostBehaviour_Oscillate: {
|
||||||
const double start_time = delta - std::fmod(my_first - first, delta);
|
const double start_time = delta - std::fmod(my_first - first, delta);
|
||||||
std::vector<LWO::Key>::iterator n = std::find_if((*it).keys.begin(), (*it).keys.end(),
|
std::vector<LWO::Key>::iterator n = std::find_if((*it).keys.begin(), (*it).keys.end(),
|
||||||
[start_time](double t) { return start_time > t; }),
|
[start_time](double t) { return start_time > t; }), m;
|
||||||
m;
|
|
||||||
|
|
||||||
size_t ofs = 0;
|
size_t ofs = 0;
|
||||||
if (n != (*it).keys.end()) {
|
if (n != (*it).keys.end()) {
|
||||||
|
|
|
@ -65,7 +65,6 @@ void LWOImporter::LoadLWOBFile()
|
||||||
if (mFileBuffer + head.length > end)
|
if (mFileBuffer + head.length > end)
|
||||||
{
|
{
|
||||||
throw DeadlyImportError("LWOB: Invalid chunk length");
|
throw DeadlyImportError("LWOB: Invalid chunk length");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
uint8_t* const next = mFileBuffer+head.length;
|
uint8_t* const next = mFileBuffer+head.length;
|
||||||
switch (head.type)
|
switch (head.type)
|
||||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -51,6 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "AssetLib/LWO/LWOLoader.h"
|
#include "AssetLib/LWO/LWOLoader.h"
|
||||||
#include "PostProcessing/ConvertToLHProcess.h"
|
#include "PostProcessing/ConvertToLHProcess.h"
|
||||||
#include "PostProcessing/ProcessHelper.h"
|
#include "PostProcessing/ProcessHelper.h"
|
||||||
|
#include "Geometry/GeometryUtils.h"
|
||||||
|
|
||||||
#include <assimp/ByteSwapper.h>
|
#include <assimp/ByteSwapper.h>
|
||||||
#include <assimp/SGSpatialSort.h>
|
#include <assimp/SGSpatialSort.h>
|
||||||
|
@ -178,7 +177,7 @@ void LWOImporter::InternReadFile(const std::string &pFile,
|
||||||
mLayers->push_back(Layer());
|
mLayers->push_back(Layer());
|
||||||
mCurLayer = &mLayers->back();
|
mCurLayer = &mLayers->back();
|
||||||
mCurLayer->mName = "<LWODefault>";
|
mCurLayer->mName = "<LWODefault>";
|
||||||
mCurLayer->mIndex = (uint16_t) -1;
|
mCurLayer->mIndex = 1;
|
||||||
|
|
||||||
// old lightwave file format (prior to v6)
|
// old lightwave file format (prior to v6)
|
||||||
mIsLWO2 = false;
|
mIsLWO2 = false;
|
||||||
|
@ -215,7 +214,7 @@ void LWOImporter::InternReadFile(const std::string &pFile,
|
||||||
} else {
|
} else {
|
||||||
mIsLWO2 = true;
|
mIsLWO2 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadLWO2File();
|
LoadLWO2File();
|
||||||
|
|
||||||
// The newer lightwave format allows the user to configure the
|
// The newer lightwave format allows the user to configure the
|
||||||
|
@ -398,14 +397,6 @@ void LWOImporter::InternReadFile(const std::string &pFile,
|
||||||
pvVC[w]++;
|
pvVC[w]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
// process vertex weights. We can't properly reconstruct the whole skeleton for now,
|
|
||||||
// but we can create dummy bones for all weight channels which we have.
|
|
||||||
for (unsigned int w = 0; w < layer.mWeightChannels.size();++w)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
face.mIndices[q] = vert;
|
face.mIndices[q] = vert;
|
||||||
}
|
}
|
||||||
pf->mIndices = face.mIndices;
|
pf->mIndices = face.mIndices;
|
||||||
|
@ -429,7 +420,7 @@ void LWOImporter::InternReadFile(const std::string &pFile,
|
||||||
// Generate nodes to render the mesh. Store the source layer in the mParent member of the nodes
|
// Generate nodes to render the mesh. Store the source layer in the mParent member of the nodes
|
||||||
unsigned int num = static_cast<unsigned int>(apcMeshes.size() - meshStart);
|
unsigned int num = static_cast<unsigned int>(apcMeshes.size() - meshStart);
|
||||||
if (layer.mName != "<LWODefault>" || num > 0) {
|
if (layer.mName != "<LWODefault>" || num > 0) {
|
||||||
aiNode *pcNode = new aiNode();
|
std::unique_ptr<aiNode> pcNode(new aiNode());
|
||||||
pcNode->mName.Set(layer.mName);
|
pcNode->mName.Set(layer.mName);
|
||||||
pcNode->mParent = (aiNode *)&layer;
|
pcNode->mParent = (aiNode *)&layer;
|
||||||
pcNode->mNumMeshes = num;
|
pcNode->mNumMeshes = num;
|
||||||
|
@ -439,7 +430,8 @@ void LWOImporter::InternReadFile(const std::string &pFile,
|
||||||
for (unsigned int p = 0; p < pcNode->mNumMeshes; ++p)
|
for (unsigned int p = 0; p < pcNode->mNumMeshes; ++p)
|
||||||
pcNode->mMeshes[p] = p + meshStart;
|
pcNode->mMeshes[p] = p + meshStart;
|
||||||
}
|
}
|
||||||
apcNodes[layer.mIndex] = pcNode;
|
ASSIMP_LOG_DEBUG("insert apcNode for layer ", layer.mIndex, " \"", layer.mName, "\"");
|
||||||
|
apcNodes[layer.mIndex] = pcNode.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,7 +527,6 @@ void LWOImporter::ComputeNormals(aiMesh *mesh, const std::vector<unsigned int> &
|
||||||
continue;
|
continue;
|
||||||
vNormals += v;
|
vNormals += v;
|
||||||
}
|
}
|
||||||
mesh->mNormals[idx] = vNormals.Normalize();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -556,7 +547,6 @@ void LWOImporter::ComputeNormals(aiMesh *mesh, const std::vector<unsigned int> &
|
||||||
const aiVector3D &v = faceNormals[*a];
|
const aiVector3D &v = faceNormals[*a];
|
||||||
vNormals += v;
|
vNormals += v;
|
||||||
}
|
}
|
||||||
vNormals.Normalize();
|
|
||||||
for (std::vector<unsigned int>::const_iterator a = poResult.begin(); a != poResult.end(); ++a) {
|
for (std::vector<unsigned int>::const_iterator a = poResult.begin(); a != poResult.end(); ++a) {
|
||||||
mesh->mNormals[*a] = vNormals;
|
mesh->mNormals[*a] = vNormals;
|
||||||
vertexDone[*a] = true;
|
vertexDone[*a] = true;
|
||||||
|
@ -564,6 +554,7 @@ void LWOImporter::ComputeNormals(aiMesh *mesh, const std::vector<unsigned int> &
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
GeometryUtils::normalizeVectorArray(mesh->mNormals, mesh->mNormals, mesh->mNumVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -572,40 +563,64 @@ void LWOImporter::GenerateNodeGraph(std::map<uint16_t, aiNode *> &apcNodes) {
|
||||||
aiNode *root = mScene->mRootNode = new aiNode();
|
aiNode *root = mScene->mRootNode = new aiNode();
|
||||||
root->mName.Set("<LWORoot>");
|
root->mName.Set("<LWORoot>");
|
||||||
|
|
||||||
//Set parent of all children, inserting pivots
|
ASSIMP_LOG_DEBUG("apcNodes initial size: ", apcNodes.size());
|
||||||
std::map<uint16_t, aiNode *> mapPivot;
|
if (!apcNodes.empty()) {
|
||||||
for (auto itapcNodes = apcNodes.begin(); itapcNodes != apcNodes.end(); ++itapcNodes) {
|
ASSIMP_LOG_DEBUG("first apcNode is: ", apcNodes.begin()->first, " \"", apcNodes.begin()->second->mName.C_Str(), "\"");
|
||||||
|
|
||||||
//Get the parent index
|
|
||||||
LWO::Layer *nodeLayer = (LWO::Layer *)(itapcNodes->second->mParent);
|
|
||||||
uint16_t parentIndex = nodeLayer->mParent;
|
|
||||||
|
|
||||||
//Create pivot node, store it into the pivot map, and set the parent as the pivot
|
|
||||||
aiNode *pivotNode = new aiNode();
|
|
||||||
pivotNode->mName.Set("Pivot-" + std::string(itapcNodes->second->mName.data));
|
|
||||||
itapcNodes->second->mParent = pivotNode;
|
|
||||||
|
|
||||||
//Look for the parent node to attach the pivot to
|
|
||||||
if (apcNodes.find(parentIndex) != apcNodes.end()) {
|
|
||||||
pivotNode->mParent = apcNodes[parentIndex];
|
|
||||||
} else {
|
|
||||||
//If not, attach to the root node
|
|
||||||
pivotNode->mParent = root;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Set the node and the pivot node transformation
|
|
||||||
itapcNodes->second->mTransformation.a4 = -nodeLayer->mPivot.x;
|
|
||||||
itapcNodes->second->mTransformation.b4 = -nodeLayer->mPivot.y;
|
|
||||||
itapcNodes->second->mTransformation.c4 = -nodeLayer->mPivot.z;
|
|
||||||
pivotNode->mTransformation.a4 = nodeLayer->mPivot.x;
|
|
||||||
pivotNode->mTransformation.b4 = nodeLayer->mPivot.y;
|
|
||||||
pivotNode->mTransformation.c4 = nodeLayer->mPivot.z;
|
|
||||||
mapPivot[-(itapcNodes->first + 2)] = pivotNode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Merge pivot map into node map
|
//Set parent of all children, inserting pivots
|
||||||
for (auto itMapPivot = mapPivot.begin(); itMapPivot != mapPivot.end(); ++itMapPivot) {
|
{
|
||||||
apcNodes[itMapPivot->first] = itMapPivot->second;
|
std::map<uint16_t, aiNode *> mapPivot;
|
||||||
|
for (auto itapcNodes = apcNodes.begin(); itapcNodes != apcNodes.end(); ++itapcNodes) {
|
||||||
|
|
||||||
|
//Get the parent index
|
||||||
|
LWO::Layer *nodeLayer = (LWO::Layer *)(itapcNodes->second->mParent);
|
||||||
|
uint16_t parentIndex = nodeLayer->mParent;
|
||||||
|
|
||||||
|
//Create pivot node, store it into the pivot map, and set the parent as the pivot
|
||||||
|
std::unique_ptr<aiNode> pivotNode(new aiNode());
|
||||||
|
pivotNode->mName.Set("Pivot-" + std::string(itapcNodes->second->mName.data));
|
||||||
|
itapcNodes->second->mParent = pivotNode.get();
|
||||||
|
|
||||||
|
//Look for the parent node to attach the pivot to
|
||||||
|
if (apcNodes.find(parentIndex) != apcNodes.end()) {
|
||||||
|
pivotNode->mParent = apcNodes[parentIndex];
|
||||||
|
} else {
|
||||||
|
//If not, attach to the root node
|
||||||
|
pivotNode->mParent = root;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the node and the pivot node transformation
|
||||||
|
itapcNodes->second->mTransformation.a4 = -nodeLayer->mPivot.x;
|
||||||
|
itapcNodes->second->mTransformation.b4 = -nodeLayer->mPivot.y;
|
||||||
|
itapcNodes->second->mTransformation.c4 = -nodeLayer->mPivot.z;
|
||||||
|
pivotNode->mTransformation.a4 = nodeLayer->mPivot.x;
|
||||||
|
pivotNode->mTransformation.b4 = nodeLayer->mPivot.y;
|
||||||
|
pivotNode->mTransformation.c4 = nodeLayer->mPivot.z;
|
||||||
|
uint16_t pivotNodeId = static_cast<uint16_t>(-(itapcNodes->first + 2));
|
||||||
|
ASSIMP_LOG_DEBUG("insert pivot node: ", pivotNodeId);
|
||||||
|
auto oldNodeIt = mapPivot.find(pivotNodeId);
|
||||||
|
if (oldNodeIt != mapPivot.end()) {
|
||||||
|
ASSIMP_LOG_ERROR("attempted to insert pivot node which already exists in pivot map ", pivotNodeId, " \"", pivotNode->mName.C_Str(), "\"");
|
||||||
|
} else {
|
||||||
|
mapPivot.emplace(pivotNodeId, pivotNode.release());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSIMP_LOG_DEBUG("pivot nodes: ", mapPivot.size());
|
||||||
|
//Merge pivot map into node map
|
||||||
|
for (auto itMapPivot = mapPivot.begin(); itMapPivot != mapPivot.end();) {
|
||||||
|
uint16_t pivotNodeId = itMapPivot->first;
|
||||||
|
auto oldApcNodeIt = apcNodes.find(pivotNodeId);
|
||||||
|
if (oldApcNodeIt != apcNodes.end()) {
|
||||||
|
ASSIMP_LOG_ERROR("attempted to insert pivot node which already exists in apc nodes ", pivotNodeId, " \"", itMapPivot->second->mName.C_Str(), "\"");
|
||||||
|
} else {
|
||||||
|
apcNodes.emplace(pivotNodeId, itMapPivot->second);
|
||||||
|
}
|
||||||
|
itMapPivot->second = nullptr;
|
||||||
|
itMapPivot = mapPivot.erase(itMapPivot);
|
||||||
|
}
|
||||||
|
ASSIMP_LOG_DEBUG("total nodes: ", apcNodes.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
//Set children of all parents
|
//Set children of all parents
|
||||||
|
@ -627,8 +642,15 @@ void LWOImporter::GenerateNodeGraph(std::map<uint16_t, aiNode *> &apcNodes) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mScene->mRootNode->mNumChildren)
|
if (!mScene->mRootNode->mNumChildren) {
|
||||||
|
ASSIMP_LOG_DEBUG("All apcNodes:");
|
||||||
|
for (auto nodeIt = apcNodes.begin(); nodeIt != apcNodes.end(); ) {
|
||||||
|
ASSIMP_LOG_DEBUG("Node ", nodeIt->first, " \"", nodeIt->second->mName.C_Str(), "\"");
|
||||||
|
nodeIt->second = nullptr;
|
||||||
|
nodeIt = apcNodes.erase(nodeIt);
|
||||||
|
}
|
||||||
throw DeadlyImportError("LWO: Unable to build a valid node graph");
|
throw DeadlyImportError("LWO: Unable to build a valid node graph");
|
||||||
|
}
|
||||||
|
|
||||||
// Remove a single root node with no meshes assigned to it ...
|
// Remove a single root node with no meshes assigned to it ...
|
||||||
if (1 == mScene->mRootNode->mNumChildren) {
|
if (1 == mScene->mRootNode->mNumChildren) {
|
||||||
|
@ -1462,7 +1484,6 @@ void LWOImporter::LoadLWO2File() {
|
||||||
|
|
||||||
if (mFileBuffer + head.length > end) {
|
if (mFileBuffer + head.length > end) {
|
||||||
throw DeadlyImportError("LWO2: Chunk length points behind the file");
|
throw DeadlyImportError("LWO2: Chunk length points behind the file");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
uint8_t *const next = mFileBuffer + head.length;
|
uint8_t *const next = mFileBuffer + head.length;
|
||||||
mFileBuffer += bufOffset;
|
mFileBuffer += bufOffset;
|
||||||
|
|
|
@ -345,7 +345,7 @@ void LWOImporter::ConvertMaterial(const LWO::Surface &surf, aiMaterial *pcMat) {
|
||||||
|
|
||||||
// (the diffuse value is just a scaling factor)
|
// (the diffuse value is just a scaling factor)
|
||||||
// If a diffuse texture is set, we set this value to 1.0
|
// If a diffuse texture is set, we set this value to 1.0
|
||||||
clr = (b && false ? aiColor3D(1.0, 1.0, 1.0) : surf.mColor);
|
clr = (b ? aiColor3D(1.0, 1.0, 1.0) : surf.mColor);
|
||||||
clr.r *= surf.mDiffuseValue;
|
clr.r *= surf.mDiffuseValue;
|
||||||
clr.g *= surf.mDiffuseValue;
|
clr.g *= surf.mDiffuseValue;
|
||||||
clr.b *= surf.mDiffuseValue;
|
clr.b *= surf.mDiffuseValue;
|
||||||
|
|
|
@ -65,7 +65,7 @@ class M3DImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
/// \brief Default constructor
|
/// \brief Default constructor
|
||||||
M3DImporter();
|
M3DImporter();
|
||||||
~M3DImporter() override {}
|
~M3DImporter() override = default;
|
||||||
|
|
||||||
/// \brief Returns whether the class can handle the format of the given file.
|
/// \brief Returns whether the class can handle the format of the given file.
|
||||||
/// \remark See BaseImporter::CanRead() for details.
|
/// \remark See BaseImporter::CanRead() for details.
|
||||||
|
|
|
@ -39,8 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#ifndef ASSIMP_BUILD_NO_M3D_IMPORTER
|
#if !defined ASSIMP_BUILD_NO_M3D_IMPORTER || !(defined ASSIMP_BUILD_NO_EXPORT || defined ASSIMP_BUILD_NO_M3D_EXPORTER)
|
||||||
#if !(ASSIMP_BUILD_NO_EXPORT || ASSIMP_BUILD_NO_M3D_EXPORTER)
|
|
||||||
|
|
||||||
#include "M3DWrapper.h"
|
#include "M3DWrapper.h"
|
||||||
|
|
||||||
|
@ -149,4 +148,3 @@ void M3DWrapper::ClearSave() {
|
||||||
} // namespace Assimp
|
} // namespace Assimp
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
|
@ -47,8 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef AI_M3DWRAPPER_H_INC
|
#ifndef AI_M3DWRAPPER_H_INC
|
||||||
#define AI_M3DWRAPPER_H_INC
|
#define AI_M3DWRAPPER_H_INC
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_M3D_IMPORTER
|
#if !defined ASSIMP_BUILD_NO_M3D_IMPORTER || !(defined ASSIMP_BUILD_NO_EXPORT || defined ASSIMP_BUILD_NO_M3D_EXPORTER)
|
||||||
#if !(ASSIMP_BUILD_NO_EXPORT || ASSIMP_BUILD_NO_M3D_EXPORTER)
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -126,7 +125,6 @@ inline m3d_t *M3DWrapper::M3D() const {
|
||||||
|
|
||||||
} // namespace Assimp
|
} // namespace Assimp
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif // ASSIMP_BUILD_NO_M3D_IMPORTER
|
#endif // ASSIMP_BUILD_NO_M3D_IMPORTER
|
||||||
|
|
||||||
#endif // AI_M3DWRAPPER_H_INC
|
#endif // AI_M3DWRAPPER_H_INC
|
||||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -117,6 +115,9 @@ void MD5Parser::ParseHeader() {
|
||||||
ReportError("MD5 version tag is unknown (10 is expected)");
|
ReportError("MD5 version tag is unknown (10 is expected)");
|
||||||
}
|
}
|
||||||
SkipLine();
|
SkipLine();
|
||||||
|
if (buffer == bufferEnd) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// print the command line options to the console
|
// print the command line options to the console
|
||||||
// FIX: can break the log length limit, so we need to be careful
|
// FIX: can break the log length limit, so we need to be careful
|
||||||
|
@ -135,8 +136,9 @@ bool MD5Parser::ParseSection(Section &out) {
|
||||||
|
|
||||||
// first parse the name of the section
|
// first parse the name of the section
|
||||||
char *sz = buffer;
|
char *sz = buffer;
|
||||||
while (!IsSpaceOrNewLine(*buffer))
|
while (!IsSpaceOrNewLine(*buffer)) {
|
||||||
buffer++;
|
++buffer;
|
||||||
|
}
|
||||||
out.mName = std::string(sz, (uintptr_t)(buffer - sz));
|
out.mName = std::string(sz, (uintptr_t)(buffer - sz));
|
||||||
SkipSpaces();
|
SkipSpaces();
|
||||||
|
|
||||||
|
@ -144,14 +146,14 @@ bool MD5Parser::ParseSection(Section &out) {
|
||||||
while (running) {
|
while (running) {
|
||||||
if ('{' == *buffer) {
|
if ('{' == *buffer) {
|
||||||
// it is a normal section so read all lines
|
// it is a normal section so read all lines
|
||||||
buffer++;
|
++buffer;
|
||||||
bool run = true;
|
bool run = true;
|
||||||
while (run) {
|
while (run) {
|
||||||
if (!SkipSpacesAndLineEnd()) {
|
if (!SkipSpacesAndLineEnd()) {
|
||||||
return false; // seems this was the last section
|
return false; // seems this was the last section
|
||||||
}
|
}
|
||||||
if ('}' == *buffer) {
|
if ('}' == *buffer) {
|
||||||
buffer++;
|
++buffer;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +165,7 @@ bool MD5Parser::ParseSection(Section &out) {
|
||||||
|
|
||||||
// terminate the line with zero
|
// terminate the line with zero
|
||||||
while (!IsLineEnd(*buffer))
|
while (!IsLineEnd(*buffer))
|
||||||
buffer++;
|
++buffer;
|
||||||
if (*buffer) {
|
if (*buffer) {
|
||||||
++lineNumber;
|
++lineNumber;
|
||||||
*buffer++ = '\0';
|
*buffer++ = '\0';
|
||||||
|
|
|
@ -365,9 +365,7 @@ public:
|
||||||
static void ReportWarning (const char* warn, unsigned int line);
|
static void ReportWarning (const char* warn, unsigned int line);
|
||||||
|
|
||||||
|
|
||||||
void ReportError (const char* error) {
|
AI_WONT_RETURN void ReportError (const char* error) AI_WONT_RETURN_SUFFIX;
|
||||||
return ReportError(error, lineNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReportWarning (const char* warn) {
|
void ReportWarning (const char* warn) {
|
||||||
return ReportWarning(warn, lineNumber);
|
return ReportWarning(warn, lineNumber);
|
||||||
|
@ -394,7 +392,7 @@ private:
|
||||||
|
|
||||||
bool SkipLine(const char* in, const char** out);
|
bool SkipLine(const char* in, const char** out);
|
||||||
bool SkipLine( );
|
bool SkipLine( );
|
||||||
bool SkipSpacesAndLineEnd( const char* in, const char** out);
|
bool SkipSpacesAndLineEnd( const char* in, const char** out);
|
||||||
bool SkipSpacesAndLineEnd();
|
bool SkipSpacesAndLineEnd();
|
||||||
bool SkipSpaces();
|
bool SkipSpaces();
|
||||||
|
|
||||||
|
@ -404,6 +402,9 @@ private:
|
||||||
unsigned int lineNumber;
|
unsigned int lineNumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline void MD5Parser::ReportError(const char* error) {
|
||||||
|
ReportError(error, lineNumber);
|
||||||
|
}
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
inline bool MD5Parser::SkipLine(const char* in, const char** out) {
|
inline bool MD5Parser::SkipLine(const char* in, const char** out) {
|
||||||
++lineNumber;
|
++lineNumber;
|
||||||
|
|
|
@ -470,14 +470,16 @@ void HL1MDLLoader::read_bones() {
|
||||||
|
|
||||||
temp_bones_.resize(header_->numbones);
|
temp_bones_.resize(header_->numbones);
|
||||||
|
|
||||||
|
// Create the main 'bones' node that will contain all MDL root bones.
|
||||||
aiNode *bones_node = new aiNode(AI_MDL_HL1_NODE_BONES);
|
aiNode *bones_node = new aiNode(AI_MDL_HL1_NODE_BONES);
|
||||||
rootnode_children_.push_back(bones_node);
|
rootnode_children_.push_back(bones_node);
|
||||||
bones_node->mNumChildren = static_cast<unsigned int>(header_->numbones);
|
|
||||||
bones_node->mChildren = new aiNode *[bones_node->mNumChildren];
|
// Store roots bones IDs temporarily.
|
||||||
|
std::vector<int> roots;
|
||||||
|
|
||||||
// Create bone matrices in local space.
|
// Create bone matrices in local space.
|
||||||
for (int i = 0; i < header_->numbones; ++i) {
|
for (int i = 0; i < header_->numbones; ++i) {
|
||||||
aiNode *bone_node = temp_bones_[i].node = bones_node->mChildren[i] = new aiNode(unique_bones_names[i]);
|
aiNode *bone_node = temp_bones_[i].node = new aiNode(unique_bones_names[i]);
|
||||||
|
|
||||||
aiVector3D angles(pbone[i].value[3], pbone[i].value[4], pbone[i].value[5]);
|
aiVector3D angles(pbone[i].value[3], pbone[i].value[4], pbone[i].value[5]);
|
||||||
temp_bones_[i].absolute_transform = bone_node->mTransformation =
|
temp_bones_[i].absolute_transform = bone_node->mTransformation =
|
||||||
|
@ -485,9 +487,11 @@ void HL1MDLLoader::read_bones() {
|
||||||
aiVector3D(pbone[i].value[0], pbone[i].value[1], pbone[i].value[2]));
|
aiVector3D(pbone[i].value[0], pbone[i].value[1], pbone[i].value[2]));
|
||||||
|
|
||||||
if (pbone[i].parent == -1) {
|
if (pbone[i].parent == -1) {
|
||||||
bone_node->mParent = scene_->mRootNode;
|
bone_node->mParent = bones_node;
|
||||||
|
roots.push_back(i); // This bone has no parent. Add it to the roots list.
|
||||||
} else {
|
} else {
|
||||||
bone_node->mParent = bones_node->mChildren[pbone[i].parent];
|
bone_node->mParent = temp_bones_[pbone[i].parent].node;
|
||||||
|
temp_bones_[pbone[i].parent].children.push_back(i); // Add this bone to the parent bone's children list.
|
||||||
|
|
||||||
temp_bones_[i].absolute_transform =
|
temp_bones_[i].absolute_transform =
|
||||||
temp_bones_[pbone[i].parent].absolute_transform * bone_node->mTransformation;
|
temp_bones_[pbone[i].parent].absolute_transform * bone_node->mTransformation;
|
||||||
|
@ -496,6 +500,36 @@ void HL1MDLLoader::read_bones() {
|
||||||
temp_bones_[i].offset_matrix = temp_bones_[i].absolute_transform;
|
temp_bones_[i].offset_matrix = temp_bones_[i].absolute_transform;
|
||||||
temp_bones_[i].offset_matrix.Inverse();
|
temp_bones_[i].offset_matrix.Inverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allocate memory for each MDL root bone.
|
||||||
|
bones_node->mNumChildren = static_cast<unsigned int>(roots.size());
|
||||||
|
bones_node->mChildren = new aiNode *[bones_node->mNumChildren];
|
||||||
|
|
||||||
|
// Build all bones children hierarchy starting from each MDL root bone.
|
||||||
|
for (size_t i = 0; i < roots.size(); ++i)
|
||||||
|
{
|
||||||
|
const TempBone &root_bone = temp_bones_[roots[i]];
|
||||||
|
bones_node->mChildren[i] = root_bone.node;
|
||||||
|
build_bone_children_hierarchy(root_bone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HL1MDLLoader::build_bone_children_hierarchy(const TempBone &bone)
|
||||||
|
{
|
||||||
|
if (bone.children.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
aiNode* bone_node = bone.node;
|
||||||
|
bone_node->mNumChildren = static_cast<unsigned int>(bone.children.size());
|
||||||
|
bone_node->mChildren = new aiNode *[bone_node->mNumChildren];
|
||||||
|
|
||||||
|
// Build each child bone's hierarchy recursively.
|
||||||
|
for (size_t i = 0; i < bone.children.size(); ++i)
|
||||||
|
{
|
||||||
|
const TempBone &child_bone = temp_bones_[bone.children[i]];
|
||||||
|
bone_node->mChildren[i] = child_bone.node;
|
||||||
|
build_bone_children_hierarchy(child_bone);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -143,6 +143,14 @@ private:
|
||||||
*/
|
*/
|
||||||
static bool get_num_blend_controllers(const int num_blend_animations, int &num_blend_controllers);
|
static bool get_num_blend_controllers(const int num_blend_animations, int &num_blend_controllers);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Build a bone's node children hierarchy.
|
||||||
|
*
|
||||||
|
* \param[in] bone The bone for which we must build all children hierarchy.
|
||||||
|
*/
|
||||||
|
struct TempBone;
|
||||||
|
void build_bone_children_hierarchy(const TempBone& bone);
|
||||||
|
|
||||||
/** Output scene to be filled */
|
/** Output scene to be filled */
|
||||||
aiScene *scene_;
|
aiScene *scene_;
|
||||||
|
|
||||||
|
@ -198,11 +206,13 @@ private:
|
||||||
TempBone() :
|
TempBone() :
|
||||||
node(nullptr),
|
node(nullptr),
|
||||||
absolute_transform(),
|
absolute_transform(),
|
||||||
offset_matrix() {}
|
offset_matrix(),
|
||||||
|
children() {}
|
||||||
|
|
||||||
aiNode *node;
|
aiNode *node;
|
||||||
aiMatrix4x4 absolute_transform;
|
aiMatrix4x4 absolute_transform;
|
||||||
aiMatrix4x4 offset_matrix;
|
aiMatrix4x4 offset_matrix;
|
||||||
|
std::vector<int> children; // Bone children
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<TempBone> temp_bones_;
|
std::vector<TempBone> temp_bones_;
|
||||||
|
|
|
@ -975,7 +975,7 @@ void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7 **apcOutBones)
|
||||||
}
|
}
|
||||||
|
|
||||||
// store the name of the bone
|
// store the name of the bone
|
||||||
pcOutBone->mName.length = (size_t)iMaxLen;
|
pcOutBone->mName.length = static_cast<ai_uint32>(iMaxLen);
|
||||||
::memcpy(pcOutBone->mName.data, pcBone->name, pcOutBone->mName.length);
|
::memcpy(pcOutBone->mName.data, pcBone->name, pcOutBone->mName.length);
|
||||||
pcOutBone->mName.data[pcOutBone->mName.length] = '\0';
|
pcOutBone->mName.data[pcOutBone->mName.length] = '\0';
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,7 +139,7 @@ protected:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Import a CS:S/HL2 MDL file (not fully implemented)
|
/** Import a CS:S/HL2 MDL file (not fully implemented)
|
||||||
*/
|
*/
|
||||||
void InternReadFile_HL2( );
|
AI_WONT_RETURN void InternReadFile_HL2( ) AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Check whether a given position is inside the valid range
|
/** Check whether a given position is inside the valid range
|
||||||
|
|
|
@ -470,7 +470,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
|
||||||
ASSIMP_LOG_ERROR("Found a reference to an embedded DDS texture, but texture width is zero, aborting import.");
|
ASSIMP_LOG_ERROR("Found a reference to an embedded DDS texture, but texture width is zero, aborting import.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcNew.reset(new aiTexture);
|
pcNew.reset(new aiTexture);
|
||||||
pcNew->mHeight = 0;
|
pcNew->mHeight = 0;
|
||||||
pcNew->mWidth = iWidth;
|
pcNew->mWidth = iWidth;
|
||||||
|
|
|
@ -269,7 +269,7 @@ aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel,
|
||||||
dynamic_cast<pmx::PmxVertexSkinningSDEF *>(v->skinning.get());
|
dynamic_cast<pmx::PmxVertexSkinningSDEF *>(v->skinning.get());
|
||||||
switch (v->skinning_type) {
|
switch (v->skinning_type) {
|
||||||
case pmx::PmxVertexSkinningType::BDEF1:
|
case pmx::PmxVertexSkinningType::BDEF1:
|
||||||
bone_vertex_map[vsBDEF1_ptr->bone_index].emplace_back(index, 1.0);
|
bone_vertex_map[vsBDEF1_ptr->bone_index].emplace_back(index, static_cast<ai_real>(1));
|
||||||
break;
|
break;
|
||||||
case pmx::PmxVertexSkinningType::BDEF2:
|
case pmx::PmxVertexSkinningType::BDEF2:
|
||||||
bone_vertex_map[vsBDEF2_ptr->bone_index1].emplace_back(index, vsBDEF2_ptr->bone_weight);
|
bone_vertex_map[vsBDEF2_ptr->bone_index1].emplace_back(index, vsBDEF2_ptr->bone_weight);
|
||||||
|
|
|
@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <assimp/types.h>
|
||||||
#include "MMDCpp14.h"
|
#include "MMDCpp14.h"
|
||||||
|
|
||||||
namespace pmx
|
namespace pmx
|
||||||
|
@ -730,7 +731,7 @@ namespace pmx
|
||||||
std::unique_ptr<PmxAncherRigidBody []> anchers;
|
std::unique_ptr<PmxAncherRigidBody []> anchers;
|
||||||
int pin_vertex_count;
|
int pin_vertex_count;
|
||||||
std::unique_ptr<int []> pin_vertices;
|
std::unique_ptr<int []> pin_vertices;
|
||||||
void Read(std::istream *stream, PmxSetting *setting);
|
AI_WONT_RETURN void Read(std::istream *stream, PmxSetting *setting) AI_WONT_RETURN_SUFFIX;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PmxModel
|
class PmxModel
|
||||||
|
|
|
@ -486,7 +486,7 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
|
||||||
|
|
||||||
for (unsigned int j = 0,n = 0; j < m->mNumFaces; ++j) {
|
for (unsigned int j = 0,n = 0; j < m->mNumFaces; ++j) {
|
||||||
aiFace& f = m->mFaces[j];
|
aiFace& f = m->mFaces[j];
|
||||||
if (g.triangles[j]>triangles.size()) {
|
if (g.triangles[j] >= triangles.size()) {
|
||||||
throw DeadlyImportError("MS3D: Encountered invalid triangle index, file is malformed");
|
throw DeadlyImportError("MS3D: Encountered invalid triangle index, file is malformed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,7 +494,7 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
|
||||||
f.mIndices = new unsigned int[f.mNumIndices=3];
|
f.mIndices = new unsigned int[f.mNumIndices=3];
|
||||||
|
|
||||||
for (unsigned int k = 0; k < 3; ++k,++n) {
|
for (unsigned int k = 0; k < 3; ++k,++n) {
|
||||||
if (t.indices[k]>vertices.size()) {
|
if (t.indices[k] >= vertices.size()) {
|
||||||
throw DeadlyImportError("MS3D: Encountered invalid vertex index, file is malformed");
|
throw DeadlyImportError("MS3D: Encountered invalid vertex index, file is malformed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ private:
|
||||||
|
|
||||||
aiColor3D color, diffuse, specular, ambient, emissive;
|
aiColor3D color, diffuse, specular, ambient, emissive;
|
||||||
ai_real refracti;
|
ai_real refracti;
|
||||||
std::string texFile;
|
std::string texFile;
|
||||||
bool twoSided; // For NFF2
|
bool twoSided; // For NFF2
|
||||||
bool shaded;
|
bool shaded;
|
||||||
ai_real opacity, shininess;
|
ai_real opacity, shininess;
|
||||||
|
|
|
@ -290,11 +290,12 @@ void OFFImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
|
||||||
sz = line; SkipSpaces(&sz);
|
sz = line; SkipSpaces(&sz);
|
||||||
idx = strtoul10(sz,&sz);
|
idx = strtoul10(sz,&sz);
|
||||||
if(!idx || idx > 9) {
|
if(!idx || idx > 9) {
|
||||||
ASSIMP_LOG_ERROR("OFF: Faces with zero indices aren't allowed");
|
ASSIMP_LOG_ERROR("OFF: Faces with zero indices aren't allowed");
|
||||||
--mesh->mNumFaces;
|
--mesh->mNumFaces;
|
||||||
|
++i;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
faces->mNumIndices = idx;
|
faces->mNumIndices = idx;
|
||||||
faces->mIndices = new unsigned int[faces->mNumIndices];
|
faces->mIndices = new unsigned int[faces->mNumIndices];
|
||||||
for (unsigned int m = 0; m < faces->mNumIndices;++m) {
|
for (unsigned int m = 0; m < faces->mNumIndices;++m) {
|
||||||
SkipSpaces(&sz);
|
SkipSpaces(&sz);
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
Copyright (c) 2006-2023, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -84,7 +84,6 @@ ObjFileImporter::ObjFileImporter() :
|
||||||
// Destructor.
|
// Destructor.
|
||||||
ObjFileImporter::~ObjFileImporter() {
|
ObjFileImporter::~ObjFileImporter() {
|
||||||
delete m_pRootObject;
|
delete m_pRootObject;
|
||||||
m_pRootObject = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -270,7 +269,7 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model *pModel, const ObjFile
|
||||||
for (size_t i = 0; i < pObject->m_Meshes.size(); ++i) {
|
for (size_t i = 0; i < pObject->m_Meshes.size(); ++i) {
|
||||||
unsigned int meshId = pObject->m_Meshes[i];
|
unsigned int meshId = pObject->m_Meshes[i];
|
||||||
aiMesh *pMesh = createTopology(pModel, pObject, meshId);
|
aiMesh *pMesh = createTopology(pModel, pObject, meshId);
|
||||||
if (pMesh) {
|
if (pMesh != nullptr) {
|
||||||
if (pMesh->mNumFaces > 0) {
|
if (pMesh->mNumFaces > 0) {
|
||||||
MeshArray.push_back(pMesh);
|
MeshArray.push_back(pMesh);
|
||||||
} else {
|
} else {
|
||||||
|
@ -324,14 +323,13 @@ aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjF
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<aiMesh> pMesh(new aiMesh);
|
aiMesh *pMesh = new aiMesh;
|
||||||
if (!pObjMesh->m_name.empty()) {
|
if (!pObjMesh->m_name.empty()) {
|
||||||
pMesh->mName.Set(pObjMesh->m_name);
|
pMesh->mName.Set(pObjMesh->m_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) {
|
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) {
|
||||||
const ObjFile::Face *inp = pObjMesh->m_Faces[index];
|
const ObjFile::Face *inp = pObjMesh->m_Faces[index];
|
||||||
//ai_assert(nullptr != inp);
|
|
||||||
|
|
||||||
if (inp->mPrimitiveType == aiPrimitiveType_LINE) {
|
if (inp->mPrimitiveType == aiPrimitiveType_LINE) {
|
||||||
pMesh->mNumFaces += static_cast<unsigned int>(inp->m_vertices.size() - 1);
|
pMesh->mNumFaces += static_cast<unsigned int>(inp->m_vertices.size() - 1);
|
||||||
|
@ -387,9 +385,9 @@ aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjF
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create mesh vertices
|
// Create mesh vertices
|
||||||
createVertexArray(pModel, pData, meshIndex, pMesh.get(), uiIdxCount);
|
createVertexArray(pModel, pData, meshIndex, pMesh, uiIdxCount);
|
||||||
|
|
||||||
return pMesh.release();
|
return pMesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -514,16 +514,16 @@ void ObjFileMtlImporter::getTextureOption(bool &clamp, int &clampIndex, aiString
|
||||||
DataArrayIt it = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
DataArrayIt it = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||||
getFloat(it, m_DataItEnd, m_pModel->mCurrentMaterial->bump_multiplier);
|
getFloat(it, m_DataItEnd, m_pModel->mCurrentMaterial->bump_multiplier);
|
||||||
skipToken = 2;
|
skipToken = 2;
|
||||||
} else if (!ASSIMP_strincmp(pPtr, BlendUOption, static_cast<unsigned int>(strlen(BlendUOption))) ||
|
} else if (!ASSIMP_strincmp(pPtr, BlendUOption, static_cast<unsigned int>(strlen(BlendUOption))) ||
|
||||||
!ASSIMP_strincmp(pPtr, BlendVOption, static_cast<unsigned int>(strlen(BlendVOption))) ||
|
!ASSIMP_strincmp(pPtr, BlendVOption, static_cast<unsigned int>(strlen(BlendVOption))) ||
|
||||||
!ASSIMP_strincmp(pPtr, BoostOption, static_cast<unsigned int>(strlen(BoostOption))) ||
|
!ASSIMP_strincmp(pPtr, BoostOption, static_cast<unsigned int>(strlen(BoostOption))) ||
|
||||||
!ASSIMP_strincmp(pPtr, ResolutionOption, static_cast<unsigned int>(strlen(ResolutionOption))) ||
|
!ASSIMP_strincmp(pPtr, ResolutionOption, static_cast<unsigned int>(strlen(ResolutionOption))) ||
|
||||||
!ASSIMP_strincmp(pPtr, ChannelOption, static_cast<unsigned int>(strlen(ChannelOption)))) {
|
!ASSIMP_strincmp(pPtr, ChannelOption, static_cast<unsigned int>(strlen(ChannelOption)))) {
|
||||||
skipToken = 2;
|
skipToken = 2;
|
||||||
} else if (!ASSIMP_strincmp(pPtr, ModifyMapOption, static_cast<unsigned int>(strlen(ModifyMapOption)))) {
|
} else if (!ASSIMP_strincmp(pPtr, ModifyMapOption, static_cast<unsigned int>(strlen(ModifyMapOption)))) {
|
||||||
skipToken = 3;
|
skipToken = 3;
|
||||||
} else if (!ASSIMP_strincmp(pPtr, OffsetOption, static_cast<unsigned int>(strlen(OffsetOption))) ||
|
} else if (!ASSIMP_strincmp(pPtr, OffsetOption, static_cast<unsigned int>(strlen(OffsetOption))) ||
|
||||||
!ASSIMP_strincmp(pPtr, ScaleOption, static_cast<unsigned int>(strlen(ScaleOption))) ||
|
!ASSIMP_strincmp(pPtr, ScaleOption, static_cast<unsigned int>(strlen(ScaleOption))) ||
|
||||||
!ASSIMP_strincmp(pPtr, TurbulenceOption, static_cast<unsigned int>(strlen(TurbulenceOption)))) {
|
!ASSIMP_strincmp(pPtr, TurbulenceOption, static_cast<unsigned int>(strlen(TurbulenceOption)))) {
|
||||||
skipToken = 4;
|
skipToken = 4;
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,7 +236,7 @@ void ObjFileParser::parseFile(IOStreamBuffer<char> &streamBuffer) {
|
||||||
getNameNoSpace(m_DataIt, m_DataItEnd, name);
|
getNameNoSpace(m_DataIt, m_DataItEnd, name);
|
||||||
insideCstype = name == "cstype";
|
insideCstype = name == "cstype";
|
||||||
goto pf_skip_line;
|
goto pf_skip_line;
|
||||||
} break;
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
pf_skip_line:
|
pf_skip_line:
|
||||||
|
@ -440,7 +440,7 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
|
||||||
const bool vt = (!m_pModel->mTextureCoord.empty());
|
const bool vt = (!m_pModel->mTextureCoord.empty());
|
||||||
const bool vn = (!m_pModel->mNormals.empty());
|
const bool vn = (!m_pModel->mNormals.empty());
|
||||||
int iPos = 0;
|
int iPos = 0;
|
||||||
while (m_DataIt != m_DataItEnd) {
|
while (m_DataIt < m_DataItEnd) {
|
||||||
int iStep = 1;
|
int iStep = 1;
|
||||||
|
|
||||||
if (IsLineEnd(*m_DataIt)) {
|
if (IsLineEnd(*m_DataIt)) {
|
||||||
|
@ -458,7 +458,7 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
|
||||||
//OBJ USES 1 Base ARRAYS!!!!
|
//OBJ USES 1 Base ARRAYS!!!!
|
||||||
const char *token = &(*m_DataIt);
|
const char *token = &(*m_DataIt);
|
||||||
const int iVal = ::atoi(token);
|
const int iVal = ::atoi(token);
|
||||||
|
|
||||||
// increment iStep position based off of the sign and # of digits
|
// increment iStep position based off of the sign and # of digits
|
||||||
int tmp = iVal;
|
int tmp = iVal;
|
||||||
if (iVal < 0) {
|
if (iVal < 0) {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2021, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns true, if the last entry of the buffer is reached.
|
* @brief Returns true, if the last entry of the buffer is reached.
|
||||||
* @param[in] it Iterator of current position.
|
* @param[in] it Iterator of current position.
|
||||||
* @param[in] end Iterator with end of buffer.
|
* @param[in] end Iterator with end of buffer.
|
||||||
|
@ -67,7 +67,7 @@ inline bool isEndOfBuffer(char_t it, char_t end) {
|
||||||
return (it == end);
|
return (it == end);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns next word separated by a space
|
* @brief Returns next word separated by a space
|
||||||
* @param[in] pBuffer Pointer to data buffer
|
* @param[in] pBuffer Pointer to data buffer
|
||||||
* @param[in] pEnd Pointer to end of buffer
|
* @param[in] pEnd Pointer to end of buffer
|
||||||
|
@ -85,7 +85,7 @@ inline Char_T getNextWord(Char_T pBuffer, Char_T pEnd) {
|
||||||
return pBuffer;
|
return pBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns pointer a next token
|
* @brief Returns pointer a next token
|
||||||
* @param[in] pBuffer Pointer to data buffer
|
* @param[in] pBuffer Pointer to data buffer
|
||||||
* @param[in] pEnd Pointer to end of buffer
|
* @param[in] pEnd Pointer to end of buffer
|
||||||
|
@ -102,7 +102,7 @@ inline Char_T getNextToken(Char_T pBuffer, Char_T pEnd) {
|
||||||
return getNextWord(pBuffer, pEnd);
|
return getNextWord(pBuffer, pEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Skips a line
|
* @brief Skips a line
|
||||||
* @param[in] it Iterator set to current position
|
* @param[in] it Iterator set to current position
|
||||||
* @param[in] end Iterator set to end of scratch buffer for readout
|
* @param[in] end Iterator set to end of scratch buffer for readout
|
||||||
|
@ -111,6 +111,10 @@ inline Char_T getNextToken(Char_T pBuffer, Char_T pEnd) {
|
||||||
*/
|
*/
|
||||||
template <class char_t>
|
template <class char_t>
|
||||||
inline char_t skipLine(char_t it, char_t end, unsigned int &uiLine) {
|
inline char_t skipLine(char_t it, char_t end, unsigned int &uiLine) {
|
||||||
|
if (it >= end) {
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
while (!isEndOfBuffer(it, end) && !IsLineEnd(*it)) {
|
while (!isEndOfBuffer(it, end) && !IsLineEnd(*it)) {
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
@ -127,9 +131,9 @@ inline char_t skipLine(char_t it, char_t end, unsigned int &uiLine) {
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get a name from the current line. Preserve space in the middle,
|
* @brief Get a name from the current line. Preserve space in the middle,
|
||||||
* but trim it at the end.
|
* but trim it at the end.
|
||||||
* @param[in] it set to current position
|
* @param[in] it set to current position
|
||||||
* @param[in] end set to end of scratch buffer for readout
|
* @param[in] end set to end of scratch buffer for readout
|
||||||
* @param[out] name Separated name
|
* @param[out] name Separated name
|
||||||
|
@ -158,13 +162,13 @@ inline char_t getName(char_t it, char_t end, std::string &name) {
|
||||||
std::string strName(pStart, &(*it));
|
std::string strName(pStart, &(*it));
|
||||||
if (!strName.empty()) {
|
if (!strName.empty()) {
|
||||||
name = strName;
|
name = strName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get a name from the current line. Do not preserve space
|
* @brief Get a name from the current line. Do not preserve space
|
||||||
* in the middle, but trim it at the end.
|
* in the middle, but trim it at the end.
|
||||||
* @param it set to current position
|
* @param it set to current position
|
||||||
|
@ -198,11 +202,11 @@ inline char_t getNameNoSpace(char_t it, char_t end, std::string &name) {
|
||||||
if (!strName.empty()) {
|
if (!strName.empty()) {
|
||||||
name = strName;
|
name = strName;
|
||||||
}
|
}
|
||||||
|
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get next word from given line
|
* @brief Get next word from given line
|
||||||
* @param[in] it set to current position
|
* @param[in] it set to current position
|
||||||
* @param[in] end set to end of scratch buffer for readout
|
* @param[in] end set to end of scratch buffer for readout
|
||||||
|
@ -226,7 +230,7 @@ inline char_t CopyNextWord(char_t it, char_t end, char *pBuffer, size_t length)
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get next float from given line
|
* @brief Get next float from given line
|
||||||
* @param[in] it set to current position
|
* @param[in] it set to current position
|
||||||
* @param[in] end set to end of scratch buffer for readout
|
* @param[in] end set to end of scratch buffer for readout
|
||||||
|
|
|
@ -60,17 +60,17 @@ namespace Ogre {
|
||||||
class OgreImporter : public BaseImporter {
|
class OgreImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
/// BaseImporter override.
|
/// BaseImporter override.
|
||||||
virtual bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const override;
|
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// BaseImporter override.
|
/// BaseImporter override.
|
||||||
virtual void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
|
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
|
||||||
|
|
||||||
/// BaseImporter override.
|
/// BaseImporter override.
|
||||||
virtual const aiImporterDesc *GetInfo() const override;
|
const aiImporterDesc *GetInfo() const override;
|
||||||
|
|
||||||
/// BaseImporter override.
|
/// BaseImporter override.
|
||||||
virtual void SetupProperties(const Importer *pImp) override;
|
void SetupProperties(const Importer *pImp) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Read materials referenced by the @c mesh to @c pScene.
|
/// Read materials referenced by the @c mesh to @c pScene.
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace Assimp {
|
||||||
namespace Ogre {
|
namespace Ogre {
|
||||||
|
|
||||||
//AI_WONT_RETURN void ThrowAttibuteError(const XmlParser *reader, const std::string &name, const std::string &error = "") AI_WONT_RETURN_SUFFIX;
|
//AI_WONT_RETURN void ThrowAttibuteError(const XmlParser *reader, const std::string &name, const std::string &error = "") AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN void ThrowAttibuteError(const std::string &nodeName, const std::string &name, const std::string &error) AI_WONT_RETURN_SUFFIX;
|
||||||
AI_WONT_RETURN void ThrowAttibuteError(const std::string &nodeName, const std::string &name, const std::string &error) {
|
AI_WONT_RETURN void ThrowAttibuteError(const std::string &nodeName, const std::string &name, const std::string &error) {
|
||||||
if (!error.empty()) {
|
if (!error.empty()) {
|
||||||
throw DeadlyImportError(error, " in node '", nodeName, "' and attribute '", name, "'");
|
throw DeadlyImportError(error, " in node '", nodeName, "' and attribute '", name, "'");
|
||||||
|
@ -128,7 +128,6 @@ bool OgreXmlSerializer::ReadAttribute<bool>(XmlNode &xmlNode, const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
ThrowAttibuteError(xmlNode.name(), name, "Boolean value is expected to be 'true' or 'false', encountered '" + value + "'");
|
ThrowAttibuteError(xmlNode.name(), name, "Boolean value is expected to be 'true' or 'false', encountered '" + value + "'");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mesh XML constants
|
// Mesh XML constants
|
||||||
|
@ -490,7 +489,7 @@ bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *me
|
||||||
OgreXmlSerializer serializer(xmlParser.get());
|
OgreXmlSerializer serializer(xmlParser.get());
|
||||||
XmlNode root = xmlParser->getRootNode();
|
XmlNode root = xmlParser->getRootNode();
|
||||||
if (std::string(root.name()) != nnSkeleton) {
|
if (std::string(root.name()) != nnSkeleton) {
|
||||||
printf("\nSkeleton is not a valid root: %s\n", root.name());
|
ASSIMP_LOG_VERBOSE_DEBUG("nSkeleton is not a valid root: ", root.name(), ".");
|
||||||
for (auto &a : root.children()) {
|
for (auto &a : root.children()) {
|
||||||
if (std::string(a.name()) == nnSkeleton) {
|
if (std::string(a.name()) == nnSkeleton) {
|
||||||
root = a;
|
root = a;
|
||||||
|
|
|
@ -261,7 +261,6 @@ OpenGEXImporter::RefInfo::RefInfo(aiNode *node, Type type, std::vector<std::stri
|
||||||
OpenGEXImporter::OpenGEXImporter() :
|
OpenGEXImporter::OpenGEXImporter() :
|
||||||
m_root(nullptr),
|
m_root(nullptr),
|
||||||
m_nodeChildMap(),
|
m_nodeChildMap(),
|
||||||
m_meshCache(),
|
|
||||||
m_mesh2refMap(),
|
m_mesh2refMap(),
|
||||||
m_material2refMap(),
|
m_material2refMap(),
|
||||||
m_ctx(nullptr),
|
m_ctx(nullptr),
|
||||||
|
@ -461,14 +460,12 @@ void OpenGEXImporter::handleMetricNode(DDLNode *node, aiScene * /*pScene*/) {
|
||||||
void OpenGEXImporter::handleNameNode(DDLNode *node, aiScene * /*pScene*/) {
|
void OpenGEXImporter::handleNameNode(DDLNode *node, aiScene * /*pScene*/) {
|
||||||
if (nullptr == m_currentNode) {
|
if (nullptr == m_currentNode) {
|
||||||
throw DeadlyImportError("No current node for name.");
|
throw DeadlyImportError("No current node for name.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *val(node->getValue());
|
Value *val(node->getValue());
|
||||||
if (nullptr != val) {
|
if (nullptr != val) {
|
||||||
if (Value::ValueType::ddl_string != val->m_type) {
|
if (Value::ValueType::ddl_string != val->m_type) {
|
||||||
throw DeadlyImportError("OpenGEX: invalid data type for value in node name.");
|
throw DeadlyImportError("OpenGEX: invalid data type for value in node name.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string name(val->getString());
|
const std::string name(val->getString());
|
||||||
|
@ -509,7 +506,6 @@ static void getRefNames(DDLNode *node, std::vector<std::string> &names) {
|
||||||
void OpenGEXImporter::handleObjectRefNode(DDLNode *node, aiScene * /*pScene*/) {
|
void OpenGEXImporter::handleObjectRefNode(DDLNode *node, aiScene * /*pScene*/) {
|
||||||
if (nullptr == m_currentNode) {
|
if (nullptr == m_currentNode) {
|
||||||
throw DeadlyImportError("No parent node for name.");
|
throw DeadlyImportError("No parent node for name.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> objRefNames;
|
std::vector<std::string> objRefNames;
|
||||||
|
@ -533,7 +529,6 @@ void OpenGEXImporter::handleObjectRefNode(DDLNode *node, aiScene * /*pScene*/) {
|
||||||
void OpenGEXImporter::handleMaterialRefNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
void OpenGEXImporter::handleMaterialRefNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
||||||
if (nullptr == m_currentNode) {
|
if (nullptr == m_currentNode) {
|
||||||
throw DeadlyImportError("No parent node for name.");
|
throw DeadlyImportError("No parent node for name.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> matRefNames;
|
std::vector<std::string> matRefNames;
|
||||||
|
@ -673,14 +668,12 @@ static void setMatrix(aiNode *node, DataArrayList *transformData) {
|
||||||
void OpenGEXImporter::handleTransformNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
void OpenGEXImporter::handleTransformNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
||||||
if (nullptr == m_currentNode) {
|
if (nullptr == m_currentNode) {
|
||||||
throw DeadlyImportError("No parent node for name.");
|
throw DeadlyImportError("No parent node for name.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DataArrayList *transformData(node->getDataArrayList());
|
DataArrayList *transformData(node->getDataArrayList());
|
||||||
if (nullptr != transformData) {
|
if (nullptr != transformData) {
|
||||||
if (transformData->m_numItems != 16) {
|
if (transformData->m_numItems != 16) {
|
||||||
throw DeadlyImportError("Invalid number of data for transform matrix.");
|
throw DeadlyImportError("Invalid number of data for transform matrix.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
setMatrix(m_currentNode, transformData);
|
setMatrix(m_currentNode, transformData);
|
||||||
}
|
}
|
||||||
|
@ -836,7 +829,6 @@ static void copyColor4DArray(size_t numItems, DataArrayList *vaList, aiColor4D *
|
||||||
void OpenGEXImporter::handleVertexArrayNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
void OpenGEXImporter::handleVertexArrayNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
||||||
if (nullptr == node) {
|
if (nullptr == node) {
|
||||||
throw DeadlyImportError("No parent node for name.");
|
throw DeadlyImportError("No parent node for name.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Property *prop = node->getProperties();
|
Property *prop = node->getProperties();
|
||||||
|
@ -877,12 +869,10 @@ void OpenGEXImporter::handleVertexArrayNode(ODDLParser::DDLNode *node, aiScene *
|
||||||
void OpenGEXImporter::handleIndexArrayNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
void OpenGEXImporter::handleIndexArrayNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
||||||
if (nullptr == node) {
|
if (nullptr == node) {
|
||||||
throw DeadlyImportError("No parent node for name.");
|
throw DeadlyImportError("No parent node for name.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nullptr == m_currentMesh) {
|
if (nullptr == m_currentMesh) {
|
||||||
throw DeadlyImportError("No current mesh for index data found.");
|
throw DeadlyImportError("No current mesh for index data found.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DataArrayList *vaList = node->getDataArrayList();
|
DataArrayList *vaList = node->getDataArrayList();
|
||||||
|
|
|
@ -308,8 +308,8 @@ bool PLY::Element::ParseElement(IOStreamBuffer<char> &streamBuffer, std::vector<
|
||||||
streamBuffer.getNextLine(buffer);
|
streamBuffer.getNextLine(buffer);
|
||||||
pCur = (char *)&buffer[0];
|
pCur = (char *)&buffer[0];
|
||||||
|
|
||||||
// skip all comments
|
// skip all comments and go to next line
|
||||||
PLY::DOM::SkipComments(buffer);
|
if (PLY::DOM::SkipComments(buffer)) continue;
|
||||||
|
|
||||||
PLY::Property prop;
|
PLY::Property prop;
|
||||||
if (!PLY::Property::ParseProperty(buffer, &prop))
|
if (!PLY::Property::ParseProperty(buffer, &prop))
|
||||||
|
@ -420,7 +420,7 @@ bool PLY::DOM::ParseHeader(IOStreamBuffer<char> &streamBuffer, std::vector<char>
|
||||||
if (PLY::Element::ParseElement(streamBuffer, buffer, &out)) {
|
if (PLY::Element::ParseElement(streamBuffer, buffer, &out)) {
|
||||||
// add the element to the list of elements
|
// add the element to the list of elements
|
||||||
alElements.push_back(out);
|
alElements.push_back(out);
|
||||||
} else if (TokenMatch(buffer, "end_header", 10)) { //checks for /n ending, if it doesn't end with /r/n
|
} else if (TokenMatch(buffer, "end_header", 10)) {
|
||||||
// we have reached the end of the header
|
// we have reached the end of the header
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -296,9 +296,7 @@ class PropertyInstance
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
PropertyInstance() AI_NO_EXCEPT {
|
PropertyInstance() AI_NO_EXCEPT = default;
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
union ValueUnion
|
union ValueUnion
|
||||||
{
|
{
|
||||||
|
@ -359,10 +357,7 @@ public:
|
||||||
class ElementInstance {
|
class ElementInstance {
|
||||||
public:
|
public:
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
ElementInstance() AI_NO_EXCEPT
|
ElementInstance() AI_NO_EXCEPT = default;
|
||||||
: alProperties() {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
//! List of all parsed properties
|
//! List of all parsed properties
|
||||||
std::vector< PropertyInstance > alProperties;
|
std::vector< PropertyInstance > alProperties;
|
||||||
|
@ -386,10 +381,7 @@ class ElementInstanceList
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
ElementInstanceList() AI_NO_EXCEPT
|
ElementInstanceList() AI_NO_EXCEPT = default;
|
||||||
: alInstances() {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
//! List of all element instances
|
//! List of all element instances
|
||||||
std::vector< ElementInstance > alInstances;
|
std::vector< ElementInstance > alInstances;
|
||||||
|
@ -413,11 +405,7 @@ class DOM
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
DOM() AI_NO_EXCEPT
|
DOM() AI_NO_EXCEPT = default;
|
||||||
: alElements()
|
|
||||||
, alElementData() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Contains all elements of the file format
|
//! Contains all elements of the file format
|
||||||
|
|
|
@ -169,19 +169,7 @@ struct Q3BSPModel {
|
||||||
std::vector<char> m_EntityData;
|
std::vector<char> m_EntityData;
|
||||||
std::string m_ModelName;
|
std::string m_ModelName;
|
||||||
|
|
||||||
Q3BSPModel() :
|
Q3BSPModel() = default;
|
||||||
m_Data(),
|
|
||||||
m_Lumps(),
|
|
||||||
m_Vertices(),
|
|
||||||
m_Faces(),
|
|
||||||
m_Indices(),
|
|
||||||
m_Textures(),
|
|
||||||
m_Lightmaps(),
|
|
||||||
m_EntityData(),
|
|
||||||
m_ModelName()
|
|
||||||
{
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
~Q3BSPModel() {
|
~Q3BSPModel() {
|
||||||
for ( unsigned int i=0; i<m_Lumps.size(); i++ ) {
|
for ( unsigned int i=0; i<m_Lumps.size(); i++ ) {
|
||||||
|
|
|
@ -139,7 +139,7 @@ static void normalizePathName(const std::string &rPath, std::string &normalizedP
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor.
|
// Constructor.
|
||||||
Q3BSPFileImporter::Q3BSPFileImporter() :
|
Q3BSPFileImporter::Q3BSPFileImporter() :
|
||||||
m_pCurrentMesh(nullptr), m_pCurrentFace(nullptr), m_MaterialLookupMap(), mTextures() {
|
m_pCurrentMesh(nullptr), m_pCurrentFace(nullptr) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -382,11 +382,10 @@ void Q3DImporter::InternReadFile(const std::string &pFile,
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
goto outer;
|
goto outer;
|
||||||
} break;
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw DeadlyImportError("Quick3D: Unknown chunk");
|
throw DeadlyImportError("Quick3D: Unknown chunk");
|
||||||
break;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
outer:
|
outer:
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace Assimp {
|
||||||
class RAWImporter : public BaseImporter {
|
class RAWImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
RAWImporter();
|
RAWImporter();
|
||||||
~RAWImporter();
|
~RAWImporter() override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
|
|
|
@ -85,7 +85,7 @@ static const aiImporterDesc desc = {
|
||||||
struct SIBChunk {
|
struct SIBChunk {
|
||||||
uint32_t Tag;
|
uint32_t Tag;
|
||||||
uint32_t Size;
|
uint32_t Size;
|
||||||
} PACK_STRUCT;
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
POS,
|
POS,
|
||||||
|
|
|
@ -83,12 +83,11 @@ static const aiImporterDesc desc = {
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
SMDImporter::SMDImporter() :
|
SMDImporter::SMDImporter() :
|
||||||
configFrameID(),
|
configFrameID(),
|
||||||
mBuffer(),
|
|
||||||
pScene( nullptr ),
|
pScene( nullptr ),
|
||||||
iFileSize( 0 ),
|
iFileSize( 0 ),
|
||||||
iSmallestFrame( INT_MAX ),
|
iSmallestFrame( INT_MAX ),
|
||||||
dLengthOfAnim( 0.0 ),
|
dLengthOfAnim( 0.0 ),
|
||||||
bHasUVs(false ),
|
bHasUVs(false ),
|
||||||
iLineNumber((unsigned int)-1) {
|
iLineNumber((unsigned int)-1) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
@ -591,7 +590,7 @@ void SMDImporter::CreateOutputMaterials() {
|
||||||
pScene->mMaterials[iMat] = pcMat;
|
pScene->mMaterials[iMat] = pcMat;
|
||||||
|
|
||||||
aiString szName;
|
aiString szName;
|
||||||
szName.length = (size_t)ai_snprintf(szName.data,MAXLEN,"Texture_%u",iMat);
|
szName.length = static_cast<ai_uint32>(ai_snprintf(szName.data,MAXLEN,"Texture_%u",iMat));
|
||||||
pcMat->AddProperty(&szName,AI_MATKEY_NAME);
|
pcMat->AddProperty(&szName,AI_MATKEY_NAME);
|
||||||
|
|
||||||
if (aszTextures[iMat].length())
|
if (aszTextures[iMat].length())
|
||||||
|
|
|
@ -87,10 +87,10 @@ struct Vertex {
|
||||||
*/
|
*/
|
||||||
struct Face {
|
struct Face {
|
||||||
Face() AI_NO_EXCEPT :
|
Face() AI_NO_EXCEPT :
|
||||||
iTexture(0x0), avVertices{} {
|
iTexture(0x0) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Texture index for the face
|
//! Texture index for the face
|
||||||
unsigned int iTexture;
|
unsigned int iTexture;
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue