Compare commits
71
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d403434c76 | ||
|
|
56414694b3 | ||
|
|
7610b184eb | ||
|
|
4d197881ff | ||
|
|
10cd8982b0 | ||
|
+18 |
ac0cfc8d9c | ||
|
|
11272f13bd | ||
|
|
f588492ab5 | ||
|
|
f635984770 | ||
|
|
0b30e3b343 | ||
|
|
a989b30b58 | ||
|
|
ab28db52f0 | ||
|
|
c4812fcc47 | ||
|
|
19108dff6a | ||
|
|
05a4fb57f1 | ||
|
|
a53807a02a | ||
|
|
1cc7f2ba74 | ||
|
|
e98ec7b2d3 | ||
|
|
0be7cdd6db | ||
|
|
c6f997b584 | ||
|
|
3e2e3c9b12 | ||
|
|
34cda45471 | ||
|
|
a4b8943533 | ||
|
|
0996221017 | ||
|
|
672594c230 | ||
|
|
0978918f71 | ||
|
|
8e35cb1a9f | ||
|
|
ea249be466 | ||
|
|
276d3e998f | ||
|
|
b2d5fa201a | ||
|
|
95f09deaae | ||
|
|
e778c84cd6 | ||
|
|
5f7c06a71e | ||
|
|
7dcf6a8984 | ||
|
|
cc6ab1408f | ||
|
|
f544f9c217 | ||
|
|
194da5b2fd | ||
|
|
f28a96121d | ||
|
|
6401aa9744 | ||
|
|
1894bfb22c | ||
|
|
b8133b04c7 | ||
|
|
709fe3c3d0 | ||
|
|
489c8d565b | ||
|
|
0581ed5f11 | ||
|
|
5c568616ec | ||
|
|
45cb880835 | ||
|
|
dd98d4aea3 | ||
|
|
01ac320de8 | ||
|
|
a815a78433 | ||
|
|
69f8eb21fd | ||
|
|
72b9939b9f | ||
|
|
4c8a3bd39c | ||
|
|
8ef3838beb | ||
|
|
441884387f | ||
|
|
f7bbf6dc15 | ||
|
|
aadd49311a | ||
|
|
3f107bebf2 | ||
|
|
a38ec50fd3 | ||
|
|
4c42db1805 | ||
|
|
26e2372882 | ||
|
|
36b004e286 | ||
|
|
3a0ee8792f | ||
|
|
e3f9cf5564 | ||
|
|
6d7ea78792 | ||
|
|
13316790aa | ||
|
|
9255412906 | ||
|
|
8355e0c4bc | ||
|
|
6fa9d09a97 | ||
|
|
9f4e7c6d8d | ||
|
|
59bc03d931 | ||
|
|
edcb350129 |
@@ -48,7 +48,7 @@ jobs:
|
|||||||
- name: ccache
|
- name: ccache
|
||||||
uses: hendrikmuhs/ccache-action@v1.2
|
uses: hendrikmuhs/ccache-action@v1.2
|
||||||
|
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ jobs:
|
|||||||
run: cd build/bin && ./unit ${{ steps.hunter_extra_test_args.outputs.args }}
|
run: cd build/bin && ./unit ${{ steps.hunter_extra_test_args.outputs.args }}
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v5
|
||||||
if: matrix.name == 'windows-msvc'
|
if: matrix.name == 'windows-msvc'
|
||||||
with:
|
with:
|
||||||
name: 'assimp-bins-${{ matrix.name }}'
|
name: 'assimp-bins-${{ matrix.name }}'
|
||||||
@@ -141,7 +141,7 @@ jobs:
|
|||||||
prerelease: true
|
prerelease: true
|
||||||
- run: |
|
- run: |
|
||||||
echo '${{steps.create-release.outputs.upload_url}}' > release_upload_url.txt
|
echo '${{steps.create-release.outputs.upload_url}}' > release_upload_url.txt
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v5
|
||||||
with:
|
with:
|
||||||
name: create-release
|
name: create-release
|
||||||
path: release_upload_url.txt
|
path: release_upload_url.txt
|
||||||
@@ -188,7 +188,7 @@ jobs:
|
|||||||
- id: upload-url
|
- id: upload-url
|
||||||
run: |
|
run: |
|
||||||
echo "url=$(cat create-release/release_upload_url.txt)" >> $GITHUB_OUTPUT
|
echo "url=$(cat create-release/release_upload_url.txt)" >> $GITHUB_OUTPUT
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: 'assimp-bins-${{ matrix.name }}-${{ github.sha }}'
|
name: 'assimp-bins-${{ matrix.name }}-${{ github.sha }}'
|
||||||
- uses: actions/upload-release-asset@v1
|
- uses: actions/upload-release-asset@v1
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ jobs:
|
|||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4.2.2
|
- uses: actions/checkout@v6
|
||||||
|
|
||||||
- uses: lukka/get-cmake@latest
|
- uses: lukka/get-cmake@latest
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ jobs:
|
|||||||
dry-run: false
|
dry-run: false
|
||||||
language: c++
|
language: c++
|
||||||
- name: Upload Crash
|
- name: Upload Crash
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v5
|
||||||
if: failure() && steps.build.outcome == 'success'
|
if: failure() && steps.build.outcome == 'success'
|
||||||
with:
|
with:
|
||||||
name: artifacts
|
name: artifacts
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ jobs:
|
|||||||
name: adress-sanitizer
|
name: adress-sanitizer
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
- uses: lukka/get-cmake@latest
|
- uses: lukka/get-cmake@latest
|
||||||
- uses: lukka/set-shell-env@v1
|
- uses: lukka/set-shell-env@v1
|
||||||
with:
|
with:
|
||||||
@@ -38,7 +38,7 @@ jobs:
|
|||||||
name: undefined-behavior-sanitizer
|
name: undefined-behavior-sanitizer
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
- uses: lukka/get-cmake@latest
|
- uses: lukka/get-cmake@latest
|
||||||
- uses: lukka/set-shell-env@v1
|
- uses: lukka/set-shell-env@v1
|
||||||
with:
|
with:
|
||||||
@@ -62,7 +62,7 @@ jobs:
|
|||||||
name: printf-sanitizer
|
name: printf-sanitizer
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: run scan_printf script
|
- name: run scan_printf script
|
||||||
run: ./scripts/scan_printf.sh
|
run: ./scripts/scan_printf.sh
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ cmake --build .
|
|||||||
Note that by default this builds a shared library into the `bin` directory. If you want to build it as a static library see the build options at the bottom of this file.
|
Note that by default this builds a shared library into the `bin` directory. If you want to build it as a static library see the build options at the bottom of this file.
|
||||||
|
|
||||||
### Build instructions for Windows with Visual-Studio
|
### Build instructions for Windows with Visual-Studio
|
||||||
First, you have to install Visual-Studio on your windows-system. You can get the Community-Version for free here: https://visualstudio.microsoft.com/de/downloads/
|
First, you have to install Visual-Studio on your windows-system. You can get the Community-Version for free [here](https://visualstudio.microsoft.com/downloads/)
|
||||||
To generate the build environment for your IDE open a command prompt, navigate to your repo and type:
|
To generate the build environment for your IDE open a command prompt, navigate to your repo and type:
|
||||||
```bash
|
```bash
|
||||||
cmake CMakeLists.txt
|
cmake CMakeLists.txt
|
||||||
@@ -67,7 +67,7 @@ The cmake-build-environment provides options to configure the build. The followi
|
|||||||
- **ASSIMP_NO_EXPORT (default OFF)**: Disable Assimp's export functionality.
|
- **ASSIMP_NO_EXPORT (default OFF)**: Disable Assimp's export functionality.
|
||||||
- **ASSIMP_BUILD_ZLIB (default OFF)**: Build our own zlib.
|
- **ASSIMP_BUILD_ZLIB (default OFF)**: Build our own zlib.
|
||||||
- **ASSIMP_BUILD_ALL_EXPORTERS_BY_DEFAULT (default ON)**: Build Assimp with all exporters enabled.
|
- **ASSIMP_BUILD_ALL_EXPORTERS_BY_DEFAULT (default ON)**: Build Assimp with all exporters enabled.
|
||||||
- **ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT (default ON)**: Build Assimp with all importers enabled.
|
- **ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT (default ON)**: Build Assimp with (most) importers enabled. Currently, USD importer is not included. See ASSIMP_BUILD_USD_IMPORTER.
|
||||||
- **ASSIMP_BUILD_ASSIMP_TOOLS (default OFF)**: If the supplementary tools for Assimp are built in addition to the library.
|
- **ASSIMP_BUILD_ASSIMP_TOOLS (default OFF)**: If the supplementary tools for Assimp are built in addition to the library.
|
||||||
- **ASSIMP_BUILD_SAMPLES (default OFF)**: If the official samples are built as well (needs Glut).
|
- **ASSIMP_BUILD_SAMPLES (default OFF)**: If the official samples are built as well (needs Glut).
|
||||||
- **ASSIMP_BUILD_TESTS (default ON)**: If the test suite for Assimp is built in addition to the library.
|
- **ASSIMP_BUILD_TESTS (default ON)**: If the test suite for Assimp is built in addition to the library.
|
||||||
@@ -83,6 +83,7 @@ The cmake-build-environment provides options to configure the build. The followi
|
|||||||
- **USE_STATIC_CRT (default OFF)**: Link against the static MSVC runtime libraries.
|
- **USE_STATIC_CRT (default OFF)**: Link against the static MSVC runtime libraries.
|
||||||
- **ASSIMP_BUILD_DRACO (default OFF)**: Build Draco libraries. Primarily for glTF.
|
- **ASSIMP_BUILD_DRACO (default OFF)**: Build Draco libraries. Primarily for glTF.
|
||||||
- **ASSIMP_BUILD_ASSIMP_VIEW (default ON, if DirectX found, OFF otherwise)**: Build Assimp view tool (requires DirectX).
|
- **ASSIMP_BUILD_ASSIMP_VIEW (default ON, if DirectX found, OFF otherwise)**: Build Assimp view tool (requires DirectX).
|
||||||
|
- **ASSIMP_BUILD_USD_IMPORTER (default OFF, requires ASSIMP_WARNINGS_AS_ERRORS to be OFF)**: Build USD importer, defaults to off for CI purposes
|
||||||
|
|
||||||
### Install prebuild binaries
|
### Install prebuild binaries
|
||||||
## Install on all platforms using vcpkg
|
## Install on all platforms using vcpkg
|
||||||
@@ -109,5 +110,5 @@ You need to have pip installed:
|
|||||||
pip install pyassimp
|
pip install pyassimp
|
||||||
```
|
```
|
||||||
|
|
||||||
### Get the SDK from itchi.io
|
### Get the SDK from itch.io
|
||||||
Just check [itchi.io](https://kimkulling.itch.io/the-asset-importer-lib)
|
Just check [itch.io](https://kimkulling.itch.io/the-asset-importer-lib)
|
||||||
|
|||||||
+1
-1
@@ -591,7 +591,7 @@ ELSE()
|
|||||||
SET(ASSIMP_BUILD_MINIZIP 1)
|
SET(ASSIMP_BUILD_MINIZIP 1)
|
||||||
ELSE()
|
ELSE()
|
||||||
ADD_DEFINITIONS(-DASSIMP_BUILD_NO_OWN_ZLIB)
|
ADD_DEFINITIONS(-DASSIMP_BUILD_NO_OWN_ZLIB)
|
||||||
SET(ZLIB_LIBRARIES_LINKED -lz)
|
SET(ZLIB_LIBRARIES_LINKED -l${ZLIB_LIBRARIES})
|
||||||
ENDIF()
|
ENDIF()
|
||||||
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
|
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"cmakeMinimumRequired": {
|
||||||
|
"major": 3,
|
||||||
|
"minor": 20,
|
||||||
|
"patch": 0
|
||||||
|
},
|
||||||
|
"configurePresets": [
|
||||||
|
{
|
||||||
|
"name": "assimp",
|
||||||
|
"binaryDir": "${sourceDir}",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Release",
|
||||||
|
"ASSIMP_BUILD_ASSIMP_TOOLS": "OFF"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "assimp_double_precision",
|
||||||
|
"binaryDir": "${sourceDir}",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Release",
|
||||||
|
"ASSIMP_BUILD_ASSIMP_TOOLS": "OFF",
|
||||||
|
"ASSIMP_DOUBLE_PRECISION": "ON"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "assimp_with_tools",
|
||||||
|
"binaryDir": "${sourceDir}",
|
||||||
|
"cacheVariables": {
|
||||||
|
"ASSIMP_BUILD_ASSIMP_TOOLS": "ON"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2021, assimp team
|
Copyright (c) 2006-2025, 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,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ Open Asset Import Library (assimp)
|
|||||||
|
|
||||||
Open Asset Import Library is a library that loads various 3D file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
|
Open Asset Import Library is a library that loads various 3D file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
|
||||||
|
|
||||||
### Current project status ###
|
### Current project status
|
||||||

|

|
||||||
[](https://www.codacy.com/gh/assimp/assimp/dashboard?utm_source=github.com&utm_medium=referral&utm_content=assimp/assimp&utm_campaign=Badge_Grade)
|
[](https://www.codacy.com/gh/assimp/assimp/dashboard?utm_source=github.com&utm_medium=referral&utm_content=assimp/assimp&utm_campaign=Badge_Grade)
|
||||||
[](https://sonarcloud.io/summary/new_code?id=assimp_assimp)
|
[](https://sonarcloud.io/summary/new_code?id=assimp_assimp)
|
||||||
@@ -16,32 +16,32 @@ Open Asset Import Library is a library that loads various 3D file formats into a
|
|||||||
APIs are provided for C and C++. Various bindings exist to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
|
APIs are provided for C and C++. Various bindings exist to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
|
||||||
Additionally, assimp features various __mesh post-processing tools__: normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials and many more.
|
Additionally, assimp features various __mesh post-processing tools__: normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials and many more.
|
||||||
|
|
||||||
## Project activity ##
|
## Project activity
|
||||||

|

|
||||||
|
|
||||||
### Documentation ###
|
### Documentation
|
||||||
Read [our latest documentation](https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/).
|
Read [our latest documentation](https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/).
|
||||||
|
|
||||||
### Pre-built binaries ###
|
### Pre-built binaries
|
||||||
Download binaries from [our Itchi Projectspace](https://kimkulling.itch.io/the-asset-importer-lib).
|
Download binaries from [our Itch Projectspace](https://kimkulling.itch.io/the-asset-importer-lib).
|
||||||
|
|
||||||
### Test data ###
|
### Test data
|
||||||
Clone [our model database](https://github.com/assimp/assimp-mdb).
|
Clone [our model database for testing purposes](https://github.com/assimp/assimp-mdb).
|
||||||
|
|
||||||
### Communities ###
|
### Communities
|
||||||
- Ask questions at [the Assimp Discussion Board](https://github.com/assimp/assimp/discussions).
|
- Ask questions at [the Assimp Discussion Board](https://github.com/assimp/assimp/discussions).
|
||||||
- Find us on [https://discord.gg/s9KJfaem](https://discord.gg/kKazXMXDy2)
|
- Find us on [discord](https://discord.gg/kKazXMXDy2)
|
||||||
- Ask [the Assimp community on Reddit](https://www.reddit.com/r/Assimp/).
|
- Ask [the Assimp community on Reddit](https://www.reddit.com/r/Assimp/).
|
||||||
- Ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest).
|
- Ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest).
|
||||||
- Nothing has worked? File a question or an issue report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues)
|
- Nothing has worked? File a question or an issue report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues)
|
||||||
|
|
||||||
#### Supported file formats ####
|
#### Supported file formats
|
||||||
See [the complete list of supported formats](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md).
|
See [the complete list of supported formats](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md).
|
||||||
|
|
||||||
### Building ###
|
### Building
|
||||||
Start by reading [our build instructions](https://github.com/assimp/assimp/blob/master/Build.md). We are available in vcpkg, and our build system is CMake; if you used CMake before there is a good chance you know what to do.
|
Start by reading [our build instructions](https://github.com/assimp/assimp/blob/master/Build.md). We are available in vcpkg, and our build system is CMake; if you used CMake before there is a good chance you know what to do.
|
||||||
|
|
||||||
### Ports ###
|
### Ports
|
||||||
* [Android](port/AndroidJNI/README.md)
|
* [Android](port/AndroidJNI/README.md)
|
||||||
* [Python](port/PyAssimp/README.md)
|
* [Python](port/PyAssimp/README.md)
|
||||||
* [.NET](https://github.com/Saalvage/AssimpNetter)
|
* [.NET](https://github.com/Saalvage/AssimpNetter)
|
||||||
@@ -54,36 +54,40 @@ Start by reading [our build instructions](https://github.com/assimp/assimp/blob/
|
|||||||
* [HAXE-Port](https://github.com/longde123/assimp-haxe) The Assimp-HAXE-port.
|
* [HAXE-Port](https://github.com/longde123/assimp-haxe) The Assimp-HAXE-port.
|
||||||
* [Rust](https://github.com/jkvargas/russimp)
|
* [Rust](https://github.com/jkvargas/russimp)
|
||||||
|
|
||||||
### Other tools ###
|
### Other tools
|
||||||
[Qt5-ModelViewer](https://github.com/sharjith/ModelViewer-Qt5) is a powerful viewer based on Qt5 and Assimp's import and export abilities.<br>
|
[Qt5-ModelViewer](https://github.com/sharjith/ModelViewer-Qt5) is a powerful viewer based on Qt5 and Assimp's import and export abilities.<br>
|
||||||
[Assimp-Viewer](https://github.com/assimp/assimp_view) is an experimental implementation for an Asset-Viewer based on ImGUI and Assimp (experimental).
|
[Assimp-Viewer](https://github.com/assimp/assimp_view) is an experimental implementation for an Asset-Viewer based on ImGUI and Assimp (experimental).
|
||||||
|
|
||||||
#### Repository structure ####
|
#### Repository structure ####
|
||||||
Open Asset Import Library is implemented in C++. The directory structure looks like this:
|
Open Asset Import Library is implemented in C++. The directory structure looks like this:
|
||||||
|
|
||||||
/code Source code
|
```txt
|
||||||
/contrib Third-party libraries
|
code Source code
|
||||||
/doc Documentation (Doxygen source and pre-compiled docs)
|
├── AssetLib/ The asset-importer and exporter lib
|
||||||
/fuzz Contains the test code for the Google Fuzzer project
|
├── CApi/ C-API files
|
||||||
/include Public header C and C++ header files
|
├── Common/ Common code used from all modules
|
||||||
/scripts Scripts are used to generate the loading code for some formats
|
├── Geometry/ Geometry utilities
|
||||||
/port Ports to other languages and scripts to maintain those.
|
├── Material/ Common materials
|
||||||
/test Unit- and regression tests, test suite of models
|
├── Pbrt/ Physical based materials
|
||||||
/tools Tools (old assimp viewer, command line `assimp`)
|
├── PostProcessing/ Post-processing steps
|
||||||
/samples A small number of samples to illustrate possible use cases for Assimp
|
├── res Resouce files
|
||||||
|
contrib Third-party libraries
|
||||||
|
doc Documentation (Doxygen source and pre-compiled docs)
|
||||||
|
fuzz Contains the test code for the Google Fuzzer project
|
||||||
|
include Public header C and C++ header files
|
||||||
|
scripts Scripts are used to generate the loading code for some formats
|
||||||
|
port Ports to other languages and scripts to maintain those.
|
||||||
|
test Unit- and regression tests, test suite of models
|
||||||
|
├── headercheck Implements headerchecks
|
||||||
|
├── models-nonbsd Non-BSP licensed headers
|
||||||
|
├── models BSP-licensed models
|
||||||
|
├── unit Unit tests
|
||||||
|
tools Tools (old assimp viewer, command line `assimp`)
|
||||||
|
samples Small number of samples to illustrate possible use cases for Assimp
|
||||||
|
```
|
||||||
|
### Contributing
|
||||||
|
|
||||||
The source code is organized in the following way:
|
We would greatly appreciate for you to contribute to assimp. The easiest way to get involved is to submit
|
||||||
|
|
||||||
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/AssetLib/<FormatName> Implementation for import and export of the format
|
|
||||||
|
|
||||||
### Contributing ###
|
|
||||||
I would greatly appreciate contributing to assimp. 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.
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
|
|||||||
+2
-3
@@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
## Supported Versions
|
## Supported Versions
|
||||||
|
|
||||||
Use this section to tell people about which versions of your project are
|
The current version of Assimp that's being supported with security updates:
|
||||||
currently being supported with security updates.
|
|
||||||
|
|
||||||
| Version | Supported |
|
| Version | Supported |
|
||||||
| ------- | ------------------ |
|
| ------- | ------------------ |
|
||||||
@@ -12,5 +11,5 @@ currently being supported with security updates.
|
|||||||
## Reporting a Vulnerability
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
If you have found any security vulnerability you can contact us via
|
If you have found any security vulnerability you can contact us via
|
||||||
kim.kulling@googlemail.com
|
kim.kulling@assimp.org
|
||||||
|
|
||||||
|
|||||||
@@ -56,23 +56,27 @@ namespace Assimp {
|
|||||||
|
|
||||||
static constexpr unsigned int NotSet = 0xcdcdcdcd;
|
static constexpr unsigned int NotSet = 0xcdcdcdcd;
|
||||||
|
|
||||||
|
using namespace D3DS;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Setup final material indices, generae a default material if necessary
|
// Setup final material indices, generate a default material if necessary
|
||||||
void Discreet3DSImporter::ReplaceDefaultMaterial() {
|
void Discreet3DSImporter::ReplaceDefaultMaterial() {
|
||||||
// Try to find an existing material that matches the
|
// Try to find an existing material that matches the
|
||||||
// typical default material setting:
|
// typical default material setting:
|
||||||
// - no textures
|
// - no textures
|
||||||
// - diffuse color (in grey!)
|
// - diffuse color (in grey!)
|
||||||
// NOTE: This is here to workaround the fact that some
|
// NOTE: This is here to work-around the fact that some
|
||||||
// exporters are writing a default material, too.
|
// exporters are writing a default material, too.
|
||||||
unsigned int idx(NotSet);
|
unsigned int idx(NotSet);
|
||||||
for (unsigned int i = 0; i < mScene->mMaterials.size(); ++i) {
|
for (unsigned int i = 0; i < mScene->mMaterials.size(); ++i) {
|
||||||
std::string s = mScene->mMaterials[i].mName;
|
auto s = mScene->mMaterials[i].mName;
|
||||||
for (char &it : s) {
|
for (char &it : s) {
|
||||||
it = static_cast<char>(::tolower(static_cast<unsigned char>(it)));
|
it = static_cast<char>(::tolower(static_cast<unsigned char>(it)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::string::npos == s.find("default")) continue;
|
if (std::string::npos == s.find("default")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (mScene->mMaterials[i].mDiffuse.r !=
|
if (mScene->mMaterials[i].mDiffuse.r !=
|
||||||
mScene->mMaterials[i].mDiffuse.g ||
|
mScene->mMaterials[i].mDiffuse.g ||
|
||||||
@@ -85,22 +89,22 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() {
|
|||||||
idx = i;
|
idx = i;
|
||||||
}
|
}
|
||||||
if (NotSet == idx) {
|
if (NotSet == idx) {
|
||||||
idx = (unsigned int)mScene->mMaterials.size();
|
idx = static_cast<unsigned int>(mScene->mMaterials.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// now iterate through all meshes and through all faces and
|
// now iterate through all meshes and through all faces and
|
||||||
// find all faces that are using the default material
|
// find all faces that are using the default material
|
||||||
unsigned int cnt = 0;
|
unsigned int cnt = 0;
|
||||||
for (auto i = mScene->mMeshes.begin(); i != mScene->mMeshes.end(); ++i) {
|
for (auto i = mScene->mMeshes.begin(); i != mScene->mMeshes.end(); ++i) {
|
||||||
for (auto a = (*i).mFaceMaterials.begin(); a != (*i).mFaceMaterials.end(); ++a) {
|
for (auto a = i->mFaceMaterials.begin(); a != i->mFaceMaterials.end(); ++a) {
|
||||||
// NOTE: The additional check seems to be necessary,
|
// NOTE: The additional check seems to be necessary,
|
||||||
// some exporters seem to generate invalid data here
|
// some exporters seem to generate invalid data here
|
||||||
|
|
||||||
if (NotSet == (*a)) {
|
if (NotSet == *a) {
|
||||||
(*a) = idx;
|
*a = idx;
|
||||||
++cnt;
|
++cnt;
|
||||||
} else if ((*a) >= mScene->mMaterials.size()) {
|
} else if ((*a) >= mScene->mMaterials.size()) {
|
||||||
(*a) = idx;
|
*a = idx;
|
||||||
ASSIMP_LOG_WARN("Material index overflow in 3DS file. Using default material");
|
ASSIMP_LOG_WARN("Material index overflow in 3DS file. Using default material");
|
||||||
++cnt;
|
++cnt;
|
||||||
}
|
}
|
||||||
@@ -174,7 +178,7 @@ void CopyTexture(aiMaterial &mat, Texture &texture, aiTextureType type) {
|
|||||||
mat.AddProperty<ai_real>(&texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type, 0));
|
mat.AddProperty<ai_real>(&texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type, 0));
|
||||||
|
|
||||||
// Setup the texture mapping mode
|
// Setup the texture mapping mode
|
||||||
int mapMode = static_cast<int>(texture.mMapMode);
|
auto mapMode = static_cast<int>(texture.mMapMode);
|
||||||
mat.AddProperty<int>(&mapMode, 1, AI_MATKEY_MAPPINGMODE_U(type, 0));
|
mat.AddProperty<int>(&mapMode, 1, AI_MATKEY_MAPPINGMODE_U(type, 0));
|
||||||
mat.AddProperty<int>(&mapMode, 1, AI_MATKEY_MAPPINGMODE_V(type, 0));
|
mat.AddProperty<int>(&mapMode, 1, AI_MATKEY_MAPPINGMODE_V(type, 0));
|
||||||
|
|
||||||
@@ -326,10 +330,11 @@ void Discreet3DSImporter::ConvertMeshes(aiScene *pcOut) {
|
|||||||
aiString name;
|
aiString name;
|
||||||
|
|
||||||
// we need to split all meshes by their materials
|
// we need to split all meshes by their materials
|
||||||
for (std::vector<D3DS::Mesh>::iterator i = mScene->mMeshes.begin(); i != mScene->mMeshes.end(); ++i) {
|
for (auto i = mScene->mMeshes.begin(); i != mScene->mMeshes.end(); ++i) {
|
||||||
std::unique_ptr<std::vector<unsigned int>[]> aiSplit(new std::vector<unsigned int>[mScene->mMaterials.size()]);
|
std::unique_ptr<std::vector<unsigned int>[]> aiSplit(new std::vector<unsigned int>[mScene->mMaterials.size()]);
|
||||||
|
|
||||||
name.length = ASSIMP_itoa10(name.data, num++);
|
name.length = ASSIMP_itoa10(name.data, num);
|
||||||
|
++num;
|
||||||
|
|
||||||
unsigned int iNum = 0;
|
unsigned int iNum = 0;
|
||||||
for (std::vector<unsigned int>::const_iterator a = (*i).mFaceMaterials.begin();
|
for (std::vector<unsigned int>::const_iterator a = (*i).mFaceMaterials.begin();
|
||||||
@@ -341,7 +346,7 @@ void Discreet3DSImporter::ConvertMeshes(aiScene *pcOut) {
|
|||||||
if (aiSplit[p].empty()) {
|
if (aiSplit[p].empty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
aiMesh *meshOut = new aiMesh();
|
auto *meshOut = new aiMesh();
|
||||||
meshOut->mName = name;
|
meshOut->mName = name;
|
||||||
meshOut->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
|
meshOut->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
|
||||||
|
|
||||||
@@ -353,7 +358,7 @@ void Discreet3DSImporter::ConvertMeshes(aiScene *pcOut) {
|
|||||||
avOutMeshes.push_back(meshOut);
|
avOutMeshes.push_back(meshOut);
|
||||||
|
|
||||||
// convert vertices
|
// convert vertices
|
||||||
meshOut->mNumFaces = (unsigned int)aiSplit[p].size();
|
meshOut->mNumFaces = static_cast<unsigned int>(aiSplit[p].size());
|
||||||
meshOut->mNumVertices = meshOut->mNumFaces * 3;
|
meshOut->mNumVertices = meshOut->mNumFaces * 3;
|
||||||
|
|
||||||
// allocate enough storage for faces
|
// allocate enough storage for faces
|
||||||
@@ -401,8 +406,7 @@ void Discreet3DSImporter::ConvertMeshes(aiScene *pcOut) {
|
|||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Add a node to the scenegraph and setup its final transformation
|
// Add a node to the scenegraph and setup its final transformation
|
||||||
void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
|
void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut, D3DS::Node *pcIn, aiMatrix4x4 & /*absTrafo*/) {
|
||||||
D3DS::Node *pcIn, aiMatrix4x4 & /*absTrafo*/) {
|
|
||||||
std::vector<unsigned int> iArray;
|
std::vector<unsigned int> iArray;
|
||||||
iArray.reserve(3);
|
iArray.reserve(3);
|
||||||
|
|
||||||
@@ -410,7 +414,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
|
|||||||
|
|
||||||
// Find all meshes with the same name as the node
|
// Find all meshes with the same name as the node
|
||||||
for (unsigned int a = 0; a < pcSOut->mNumMeshes; ++a) {
|
for (unsigned int a = 0; a < pcSOut->mNumMeshes; ++a) {
|
||||||
const D3DS::Mesh *pcMesh = (const D3DS::Mesh *)pcSOut->mMeshes[a]->mColors[0];
|
const auto *pcMesh = (const D3DS::Mesh *)pcSOut->mMeshes[a]->mColors[0];
|
||||||
ai_assert(nullptr != pcMesh);
|
ai_assert(nullptr != pcMesh);
|
||||||
|
|
||||||
if (pcIn->mName == pcMesh->mName)
|
if (pcIn->mName == pcMesh->mName)
|
||||||
@@ -419,7 +423,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
|
|||||||
if (!iArray.empty()) {
|
if (!iArray.empty()) {
|
||||||
// The matrix should be identical for all meshes with the
|
// The matrix should be identical for all meshes with the
|
||||||
// same name. It HAS to be identical for all meshes .....
|
// same name. It HAS to be identical for all meshes .....
|
||||||
D3DS::Mesh *imesh = ((D3DS::Mesh *)pcSOut->mMeshes[iArray[0]]->mColors[0]);
|
auto *imesh = ((D3DS::Mesh *)pcSOut->mMeshes[iArray[0]]->mColors[0]);
|
||||||
|
|
||||||
// Compute the inverse of the transformation matrix to move the
|
// Compute the inverse of the transformation matrix to move the
|
||||||
// vertices back to their relative and local space
|
// vertices back to their relative and local space
|
||||||
@@ -428,7 +432,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
|
|||||||
mInvTransposed.Transpose();
|
mInvTransposed.Transpose();
|
||||||
aiVector3D pivot = pcIn->vPivot;
|
aiVector3D pivot = pcIn->vPivot;
|
||||||
|
|
||||||
pcOut->mNumMeshes = (unsigned int)iArray.size();
|
pcOut->mNumMeshes = static_cast<unsigned int>(iArray.size());
|
||||||
pcOut->mMeshes = new unsigned int[iArray.size()];
|
pcOut->mMeshes = new unsigned int[iArray.size()];
|
||||||
for (unsigned int i = 0; i < iArray.size(); ++i) {
|
for (unsigned int i = 0; i < iArray.size(); ++i) {
|
||||||
const unsigned int iIndex = iArray[i];
|
const unsigned int iIndex = iArray[i];
|
||||||
@@ -447,7 +451,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
|
|||||||
|
|
||||||
// Handle negative transformation matrix determinant -> invert vertex x
|
// Handle negative transformation matrix determinant -> invert vertex x
|
||||||
if (imesh->mMat.Determinant() < 0.0f) {
|
if (imesh->mMat.Determinant() < 0.0f) {
|
||||||
/* we *must* have normals */
|
// we *must* have normals
|
||||||
for (pvCurrent = mesh->mVertices, t2 = mesh->mNormals; pvCurrent != pvEnd; ++pvCurrent, ++t2) {
|
for (pvCurrent = mesh->mVertices, t2 = mesh->mNormals; pvCurrent != pvEnd; ++pvCurrent, ++t2) {
|
||||||
pvCurrent->x *= -1.f;
|
pvCurrent->x *= -1.f;
|
||||||
t2->x *= -1.f;
|
t2->x *= -1.f;
|
||||||
@@ -474,7 +478,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
|
|||||||
// Setup the name of the node
|
// Setup the name of the node
|
||||||
// First instance keeps its name otherwise something might break, all others will be postfixed with their instance number
|
// First instance keeps its name otherwise something might break, all others will be postfixed with their instance number
|
||||||
if (pcIn->mInstanceNumber > 1) {
|
if (pcIn->mInstanceNumber > 1) {
|
||||||
char tmp[12];
|
char tmp[12] = {'\0'};
|
||||||
ASSIMP_itoa10(tmp, pcIn->mInstanceNumber);
|
ASSIMP_itoa10(tmp, pcIn->mInstanceNumber);
|
||||||
std::string tempStr = pcIn->mName + "_inst_";
|
std::string tempStr = pcIn->mName + "_inst_";
|
||||||
tempStr += tmp;
|
tempStr += tmp;
|
||||||
@@ -487,7 +491,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
|
|||||||
if (pcIn->aRotationKeys.size()) {
|
if (pcIn->aRotationKeys.size()) {
|
||||||
|
|
||||||
// FIX to get to Assimp's quaternion conventions
|
// FIX to get to Assimp's quaternion conventions
|
||||||
for (std::vector<aiQuatKey>::iterator it = pcIn->aRotationKeys.begin(); it != pcIn->aRotationKeys.end(); ++it) {
|
for (auto it = pcIn->aRotationKeys.begin(); it != pcIn->aRotationKeys.end(); ++it) {
|
||||||
(*it).mValue.w *= -1.f;
|
(*it).mValue.w *= -1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -599,11 +603,11 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Allocate a new node anim and setup its name
|
// Allocate a new node anim and setup its name
|
||||||
aiNodeAnim *nda = anim->mChannels[anim->mNumChannels++] = new aiNodeAnim();
|
auto *nda = anim->mChannels[anim->mNumChannels++] = new aiNodeAnim();
|
||||||
nda->mNodeName.Set(pcIn->mName);
|
nda->mNodeName.Set(pcIn->mName);
|
||||||
|
|
||||||
// POSITION keys
|
// POSITION keys
|
||||||
if (pcIn->aPositionKeys.size() > 0) {
|
if (!pcIn->aPositionKeys.empty()) {
|
||||||
nda->mNumPositionKeys = (unsigned int)pcIn->aPositionKeys.size();
|
nda->mNumPositionKeys = (unsigned int)pcIn->aPositionKeys.size();
|
||||||
nda->mPositionKeys = new aiVectorKey[nda->mNumPositionKeys];
|
nda->mPositionKeys = new aiVectorKey[nda->mNumPositionKeys];
|
||||||
::memcpy(nda->mPositionKeys, &pcIn->aPositionKeys[0],
|
::memcpy(nda->mPositionKeys, &pcIn->aPositionKeys[0],
|
||||||
@@ -611,7 +615,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ROTATION keys
|
// ROTATION keys
|
||||||
if (pcIn->aRotationKeys.size() > 0) {
|
if (!pcIn->aRotationKeys.empty()) {
|
||||||
nda->mNumRotationKeys = (unsigned int)pcIn->aRotationKeys.size();
|
nda->mNumRotationKeys = (unsigned int)pcIn->aRotationKeys.size();
|
||||||
nda->mRotationKeys = new aiQuatKey[nda->mNumRotationKeys];
|
nda->mRotationKeys = new aiQuatKey[nda->mNumRotationKeys];
|
||||||
|
|
||||||
@@ -627,7 +631,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SCALING keys
|
// SCALING keys
|
||||||
if (pcIn->aScalingKeys.size() > 0) {
|
if (!pcIn->aScalingKeys.empty()) {
|
||||||
nda->mNumScalingKeys = (unsigned int)pcIn->aScalingKeys.size();
|
nda->mNumScalingKeys = (unsigned int)pcIn->aScalingKeys.size();
|
||||||
nda->mScalingKeys = new aiVectorKey[nda->mNumScalingKeys];
|
nda->mScalingKeys = new aiVectorKey[nda->mNumScalingKeys];
|
||||||
::memcpy(nda->mScalingKeys, &pcIn->aScalingKeys[0],
|
::memcpy(nda->mScalingKeys, &pcIn->aScalingKeys[0],
|
||||||
@@ -636,7 +640,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Allocate storage for children
|
// Allocate storage for children
|
||||||
const unsigned int size = static_cast<unsigned int>(pcIn->mChildren.size());
|
const auto size = static_cast<unsigned int>(pcIn->mChildren.size());
|
||||||
|
|
||||||
pcOut->mNumChildren = size;
|
pcOut->mNumChildren = size;
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
@@ -679,7 +683,7 @@ void CountTracks(D3DS::Node *node, unsigned int &cnt) {
|
|||||||
// Generate the output node graph
|
// Generate the output node graph
|
||||||
void Discreet3DSImporter::GenerateNodeGraph(aiScene *pcOut) {
|
void Discreet3DSImporter::GenerateNodeGraph(aiScene *pcOut) {
|
||||||
pcOut->mRootNode = new aiNode();
|
pcOut->mRootNode = new aiNode();
|
||||||
if (0 == mRootNode->mChildren.size()) {
|
if (mRootNode->mChildren.empty()) {
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// It seems the file is so messed up that it has not even a hierarchy.
|
// It seems the file is so messed up that it has not even a hierarchy.
|
||||||
// generate a flat hiearachy which looks like this:
|
// generate a flat hiearachy which looks like this:
|
||||||
@@ -701,7 +705,8 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene *pcOut) {
|
|||||||
// Build dummy nodes for all meshes
|
// Build dummy nodes for all meshes
|
||||||
unsigned int a = 0;
|
unsigned int a = 0;
|
||||||
for (unsigned int i = 0; i < pcOut->mNumMeshes; ++i, ++a) {
|
for (unsigned int i = 0; i < pcOut->mNumMeshes; ++i, ++a) {
|
||||||
aiNode *pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
|
pcOut->mRootNode->mChildren[a] = new aiNode();
|
||||||
|
auto *pcNode = pcOut->mRootNode->mChildren[a];
|
||||||
pcNode->mParent = pcOut->mRootNode;
|
pcNode->mParent = pcOut->mRootNode;
|
||||||
pcNode->mMeshes = new unsigned int[1];
|
pcNode->mMeshes = new unsigned int[1];
|
||||||
pcNode->mMeshes[0] = i;
|
pcNode->mMeshes[0] = i;
|
||||||
@@ -713,7 +718,7 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene *pcOut) {
|
|||||||
|
|
||||||
// Build dummy nodes for all cameras
|
// Build dummy nodes for all cameras
|
||||||
for (unsigned int i = 0; i < (unsigned int)mScene->mCameras.size(); ++i, ++a) {
|
for (unsigned int i = 0; i < (unsigned int)mScene->mCameras.size(); ++i, ++a) {
|
||||||
aiNode *pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
|
auto *pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
|
||||||
pcNode->mParent = pcOut->mRootNode;
|
pcNode->mParent = pcOut->mRootNode;
|
||||||
|
|
||||||
// Build a name for the node
|
// Build a name for the node
|
||||||
@@ -722,7 +727,7 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene *pcOut) {
|
|||||||
|
|
||||||
// Build dummy nodes for all lights
|
// Build dummy nodes for all lights
|
||||||
for (unsigned int i = 0; i < (unsigned int)mScene->mLights.size(); ++i, ++a) {
|
for (unsigned int i = 0; i < (unsigned int)mScene->mLights.size(); ++i, ++a) {
|
||||||
aiNode *pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
|
auto *pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
|
||||||
pcNode->mParent = pcOut->mRootNode;
|
pcNode->mParent = pcOut->mRootNode;
|
||||||
|
|
||||||
// Build a name for the node
|
// Build a name for the node
|
||||||
@@ -738,7 +743,7 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene *pcOut) {
|
|||||||
// Allocate a primary animation channel
|
// Allocate a primary animation channel
|
||||||
pcOut->mNumAnimations = 1;
|
pcOut->mNumAnimations = 1;
|
||||||
pcOut->mAnimations = new aiAnimation *[1];
|
pcOut->mAnimations = new aiAnimation *[1];
|
||||||
aiAnimation *anim = pcOut->mAnimations[0] = new aiAnimation();
|
auto *anim = pcOut->mAnimations[0] = new aiAnimation();
|
||||||
|
|
||||||
anim->mName.Set("3DSMasterAnim");
|
anim->mName.Set("3DSMasterAnim");
|
||||||
|
|
||||||
@@ -781,7 +786,7 @@ void Discreet3DSImporter::ConvertScene(aiScene *pcOut) {
|
|||||||
|
|
||||||
// ... and convert the 3DS materials to aiMaterial's
|
// ... and convert the 3DS materials to aiMaterial's
|
||||||
for (unsigned int i = 0; i < pcOut->mNumMaterials; ++i) {
|
for (unsigned int i = 0; i < pcOut->mNumMaterials; ++i) {
|
||||||
aiMaterial *pcNew = new aiMaterial();
|
auto *pcNew = new aiMaterial();
|
||||||
ConvertMaterial(mScene->mMaterials[i], *pcNew);
|
ConvertMaterial(mScene->mMaterials[i], *pcNew);
|
||||||
pcOut->mMaterials[i] = pcNew;
|
pcOut->mMaterials[i] = pcNew;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,26 +76,26 @@ class ChunkWriter {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
ChunkWriter(StreamWriterLE &writer, uint16_t chunk_type) :
|
ChunkWriter(StreamWriterLE &writer, uint16_t chunk_type) :
|
||||||
writer(writer) {
|
mWriter(writer) {
|
||||||
chunk_start_pos = writer.GetCurrentPos();
|
mChunkStartPos = writer.GetCurrentPos();
|
||||||
writer.PutU2(chunk_type);
|
writer.PutU2(chunk_type);
|
||||||
writer.PutU4((uint32_t)CHUNK_SIZE_NOT_SET);
|
writer.PutU4((uint32_t)CHUNK_SIZE_NOT_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ChunkWriter() {
|
~ChunkWriter() {
|
||||||
std::size_t head_pos = writer.GetCurrentPos();
|
std::size_t head_pos = mWriter.GetCurrentPos();
|
||||||
|
|
||||||
ai_assert(head_pos > chunk_start_pos);
|
ai_assert(head_pos > mChunkStartPos);
|
||||||
const std::size_t chunk_size = head_pos - chunk_start_pos;
|
const std::size_t chunk_size = head_pos - mChunkStartPos;
|
||||||
|
|
||||||
writer.SetCurrentPos(chunk_start_pos + SIZE_OFFSET);
|
mWriter.SetCurrentPos(mChunkStartPos + SIZE_OFFSET);
|
||||||
writer.PutU4(static_cast<uint32_t>(chunk_size));
|
mWriter.PutU4(static_cast<uint32_t>(chunk_size));
|
||||||
writer.SetCurrentPos(head_pos);
|
mWriter.SetCurrentPos(head_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StreamWriterLE &writer;
|
StreamWriterLE &mWriter;
|
||||||
std::size_t chunk_start_pos;
|
std::size_t mChunkStartPos;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return an unique name for a given |mesh| attached to |node| that
|
// Return an unique name for a given |mesh| attached to |node| that
|
||||||
@@ -122,8 +122,7 @@ std::string GetMaterialName(const aiMaterial &mat, unsigned int index) {
|
|||||||
char postfix[10] = { 0 };
|
char postfix[10] = { 0 };
|
||||||
ASSIMP_itoa10(postfix, index);
|
ASSIMP_itoa10(postfix, index);
|
||||||
|
|
||||||
aiString mat_name;
|
if (aiString mat_name; AI_SUCCESS == mat.Get(AI_MATKEY_NAME, mat_name)) {
|
||||||
if (AI_SUCCESS == mat.Get(AI_MATKEY_NAME, mat_name)) {
|
|
||||||
return mat_name.C_Str() + underscore + postfix;
|
return mat_name.C_Str() + underscore + postfix;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,8 +302,7 @@ void Discreet3DSExporter::WriteMaterials() {
|
|||||||
WriteColor(color);
|
WriteColor(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
aiShadingMode shading_mode = aiShadingMode_Flat;
|
if (aiShadingMode shading_mode = aiShadingMode_Flat; mat.Get(AI_MATKEY_SHADING_MODEL, shading_mode) == AI_SUCCESS) {
|
||||||
if (mat.Get(AI_MATKEY_SHADING_MODEL, shading_mode) == AI_SUCCESS) {
|
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHADING);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHADING);
|
||||||
|
|
||||||
Discreet3DS::shadetype3ds shading_mode_out;
|
Discreet3DS::shadetype3ds shading_mode_out;
|
||||||
@@ -332,7 +330,7 @@ void Discreet3DSExporter::WriteMaterials() {
|
|||||||
default:
|
default:
|
||||||
shading_mode_out = Discreet3DS::Flat;
|
shading_mode_out = Discreet3DS::Flat;
|
||||||
ai_assert(false);
|
ai_assert(false);
|
||||||
};
|
}
|
||||||
writer.PutU2(static_cast<uint16_t>(shading_mode_out));
|
writer.PutU2(static_cast<uint16_t>(shading_mode_out));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,8 +344,7 @@ void Discreet3DSExporter::WriteMaterials() {
|
|||||||
WritePercentChunk(f);
|
WritePercentChunk(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
int twosided;
|
if (int twosided; mat.Get(AI_MATKEY_TWOSIDED, twosided) == AI_SUCCESS && twosided != 0) {
|
||||||
if (mat.Get(AI_MATKEY_TWOSIDED, twosided) == AI_SUCCESS && twosided != 0) {
|
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_TWO_SIDE);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_TWO_SIDE);
|
||||||
writer.PutI2(1);
|
writer.PutI2(1);
|
||||||
}
|
}
|
||||||
@@ -541,7 +538,7 @@ void Discreet3DSExporter::WriteFaceMaterialChunk(const aiMesh &mesh) {
|
|||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Discreet3DSExporter::WriteString(const std::string &s) {
|
void Discreet3DSExporter::WriteString(const std::string &s) {
|
||||||
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
|
for (auto it = s.begin(); it != s.end(); ++it) {
|
||||||
writer.PutI1(*it);
|
writer.PutI1(*it);
|
||||||
}
|
}
|
||||||
writer.PutI1('\0');
|
writer.PutI1('\0');
|
||||||
|
|||||||
@@ -54,8 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <assimp/qnan.h>
|
#include <assimp/qnan.h>
|
||||||
#include <cstdio> //sprintf
|
#include <cstdio> //sprintf
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp::D3DS {
|
||||||
namespace D3DS {
|
|
||||||
|
|
||||||
#include <assimp/Compiler/pushpack1.h>
|
#include <assimp/Compiler/pushpack1.h>
|
||||||
|
|
||||||
@@ -579,7 +578,6 @@ struct Scene {
|
|||||||
// Node* pcRootNode;
|
// Node* pcRootNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace D3DS
|
} // end of namespace Assimp::D3DS
|
||||||
} // end of namespace Assimp
|
|
||||||
|
|
||||||
#endif // AI_XFILEHELPER_H_INC
|
#endif // AI_XFILEHELPER_H_INC
|
||||||
|
|||||||
+177
-178
@@ -56,6 +56,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
using namespace D3DS;
|
||||||
|
|
||||||
static constexpr aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Discreet 3DS Importer",
|
"Discreet 3DS Importer",
|
||||||
"",
|
"",
|
||||||
@@ -75,7 +77,7 @@ static constexpr aiImporterDesc desc = {
|
|||||||
// - computes its length
|
// - computes its length
|
||||||
#define ASSIMP_3DS_BEGIN_CHUNK() \
|
#define ASSIMP_3DS_BEGIN_CHUNK() \
|
||||||
while (true) { \
|
while (true) { \
|
||||||
if (stream->GetRemainingSizeToLimit() < sizeof(Discreet3DS::Chunk)) { \
|
if (mStream->GetRemainingSizeToLimit() < sizeof(Discreet3DS::Chunk)) { \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
Discreet3DS::Chunk chunk; \
|
Discreet3DS::Chunk chunk; \
|
||||||
@@ -83,23 +85,23 @@ static constexpr aiImporterDesc desc = {
|
|||||||
int chunkSize = chunk.Size - sizeof(Discreet3DS::Chunk); \
|
int chunkSize = chunk.Size - sizeof(Discreet3DS::Chunk); \
|
||||||
if (chunkSize <= 0) \
|
if (chunkSize <= 0) \
|
||||||
continue; \
|
continue; \
|
||||||
const unsigned int oldReadLimit = stream->SetReadLimit( \
|
const unsigned int oldReadLimit = mStream->SetReadLimit( \
|
||||||
stream->GetCurrentPos() + chunkSize);
|
mStream->GetCurrentPos() + chunkSize);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// End a parsing block
|
// End a parsing block
|
||||||
// Must follow at the end of each parsing block, reset chunk end marker to previous value
|
// Must follow at the end of each parsing block, reset chunk end marker to previous value
|
||||||
#define ASSIMP_3DS_END_CHUNK() \
|
#define ASSIMP_3DS_END_CHUNK() \
|
||||||
stream->SkipToReadLimit(); \
|
mStream->SkipToReadLimit(); \
|
||||||
stream->SetReadLimit(oldReadLimit); \
|
mStream->SetReadLimit(oldReadLimit); \
|
||||||
if (stream->GetRemainingSizeToLimit() == 0) \
|
if (mStream->GetRemainingSizeToLimit() == 0) \
|
||||||
return; \
|
return; \
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
Discreet3DSImporter::Discreet3DSImporter() :
|
Discreet3DSImporter::Discreet3DSImporter() :
|
||||||
stream(), mLastNodeIndex(), mCurrentNode(), mRootNode(), mScene(), mMasterScale(), bHasBG(), bIsPrj() {
|
mStream(nullptr), mLastNodeIndex(), mCurrentNode(), mRootNode(), mScene(), mMasterScale(), bHasBG(), bIsPrj() {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,9 +126,7 @@ void Discreet3DSImporter::SetupProperties(const Importer * /*pImp*/) {
|
|||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void Discreet3DSImporter::InternReadFile(const std::string &pFile,
|
void Discreet3DSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
|
||||||
aiScene *pScene, IOSystem *pIOHandler) {
|
|
||||||
|
|
||||||
auto theFile = pIOHandler->Open(pFile, "rb");
|
auto theFile = pIOHandler->Open(pFile, "rb");
|
||||||
if (!theFile) {
|
if (!theFile) {
|
||||||
throw DeadlyImportError("3DS: Could not open ", pFile);
|
throw DeadlyImportError("3DS: Could not open ", pFile);
|
||||||
@@ -138,14 +138,14 @@ void Discreet3DSImporter::InternReadFile(const std::string &pFile,
|
|||||||
if (theStream.GetRemainingSize() < 16) {
|
if (theStream.GetRemainingSize() < 16) {
|
||||||
throw DeadlyImportError("3DS file is either empty or corrupt: ", pFile);
|
throw DeadlyImportError("3DS file is either empty or corrupt: ", pFile);
|
||||||
}
|
}
|
||||||
this->stream = &theStream;
|
mStream = &theStream;
|
||||||
|
|
||||||
// Allocate our temporary 3DS representation
|
// Allocate our temporary 3DS representation
|
||||||
D3DS::Scene _scene;
|
Scene _scene;
|
||||||
mScene = &_scene;
|
mScene = &_scene;
|
||||||
|
|
||||||
// Initialize members
|
// Initialize members
|
||||||
D3DS::Node _rootNode("UNNAMED");
|
Node _rootNode("UNNAMED");
|
||||||
mLastNodeIndex = -1;
|
mLastNodeIndex = -1;
|
||||||
mCurrentNode = &_rootNode;
|
mCurrentNode = &_rootNode;
|
||||||
mRootNode = mCurrentNode;
|
mRootNode = mCurrentNode;
|
||||||
@@ -166,12 +166,12 @@ void Discreet3DSImporter::InternReadFile(const std::string &pFile,
|
|||||||
// vectors from the smoothing groups we read from the
|
// vectors from the smoothing groups we read from the
|
||||||
// file.
|
// file.
|
||||||
for (auto &mesh : mScene->mMeshes) {
|
for (auto &mesh : mScene->mMeshes) {
|
||||||
if (mesh.mFaces.size() > 0 && mesh.mPositions.size() == 0) {
|
if (!mesh.mFaces.empty() && mesh.mPositions.empty()) {
|
||||||
throw DeadlyImportError("3DS file contains faces but no vertices: ", pFile);
|
throw DeadlyImportError("3DS file contains faces but no vertices: ", pFile);
|
||||||
}
|
}
|
||||||
CheckIndices(mesh);
|
CheckIndices(mesh);
|
||||||
MakeUnique(mesh);
|
MakeUnique(mesh);
|
||||||
ComputeNormalsWithSmoothingsGroups<D3DS::Face>(mesh);
|
ComputeNormalsWithSmoothingsGroups<Face>(mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace all occurrences of the default material with a
|
// Replace all occurrences of the default material with a
|
||||||
@@ -196,12 +196,12 @@ void Discreet3DSImporter::InternReadFile(const std::string &pFile,
|
|||||||
|
|
||||||
AI_DEBUG_INVALIDATE_PTR(mRootNode);
|
AI_DEBUG_INVALIDATE_PTR(mRootNode);
|
||||||
AI_DEBUG_INVALIDATE_PTR(mScene);
|
AI_DEBUG_INVALIDATE_PTR(mScene);
|
||||||
AI_DEBUG_INVALIDATE_PTR(this->stream);
|
AI_DEBUG_INVALIDATE_PTR(mStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Applies a master-scaling factor to the imported scene
|
// Applies a master-scaling factor to the imported scene
|
||||||
void Discreet3DSImporter::ApplyMasterScale(aiScene *pScene) {
|
void Discreet3DSImporter::ApplyMasterScale(const aiScene *pScene) {
|
||||||
// There are some 3DS files with a zero scaling factor
|
// There are some 3DS files with a zero scaling factor
|
||||||
if (!mMasterScale)
|
if (!mMasterScale)
|
||||||
mMasterScale = 1.0f;
|
mMasterScale = 1.0f;
|
||||||
@@ -223,14 +223,14 @@ void Discreet3DSImporter::ApplyMasterScale(aiScene *pScene) {
|
|||||||
void Discreet3DSImporter::ReadChunk(Discreet3DS::Chunk *pcOut) {
|
void Discreet3DSImporter::ReadChunk(Discreet3DS::Chunk *pcOut) {
|
||||||
ai_assert(pcOut != nullptr);
|
ai_assert(pcOut != nullptr);
|
||||||
|
|
||||||
pcOut->Flag = stream->GetI2();
|
pcOut->Flag = mStream->GetI2();
|
||||||
pcOut->Size = stream->GetI4();
|
pcOut->Size = mStream->GetI4();
|
||||||
|
|
||||||
if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSize()) {
|
if (pcOut->Size - sizeof(Discreet3DS::Chunk) > mStream->GetRemainingSize()) {
|
||||||
throw DeadlyImportError("Chunk is too large");
|
throw DeadlyImportError("Chunk is too large");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSizeToLimit()) {
|
if (pcOut->Size - sizeof(Discreet3DS::Chunk) > mStream->GetRemainingSizeToLimit()) {
|
||||||
ASSIMP_LOG_ERROR("3DS: Chunk overflow");
|
ASSIMP_LOG_ERROR("3DS: Chunk overflow");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -241,8 +241,7 @@ void Discreet3DSImporter::SkipChunk() {
|
|||||||
Discreet3DS::Chunk psChunk;
|
Discreet3DS::Chunk psChunk;
|
||||||
ReadChunk(&psChunk);
|
ReadChunk(&psChunk);
|
||||||
|
|
||||||
stream->IncPtr(psChunk.Size - sizeof(Discreet3DS::Chunk));
|
mStream->IncPtr(psChunk.Size - sizeof(Discreet3DS::Chunk));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
@@ -259,7 +258,7 @@ void Discreet3DSImporter::ParseMainChunk() {
|
|||||||
case Discreet3DS::CHUNK_MAIN:
|
case Discreet3DS::CHUNK_MAIN:
|
||||||
ParseEditorChunk();
|
ParseEditorChunk();
|
||||||
break;
|
break;
|
||||||
};
|
}
|
||||||
|
|
||||||
ASSIMP_3DS_END_CHUNK();
|
ASSIMP_3DS_END_CHUNK();
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
@@ -275,30 +274,29 @@ void Discreet3DSImporter::ParseMainChunk() {
|
|||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Discreet3DSImporter::ParseEditorChunk() {
|
void Discreet3DSImporter::ParseEditorChunk() {
|
||||||
ASSIMP_3DS_BEGIN_CHUNK();
|
ASSIMP_3DS_BEGIN_CHUNK()
|
||||||
|
|
||||||
// get chunk type
|
// get chunk type
|
||||||
switch (chunk.Flag) {
|
switch (chunk.Flag) {
|
||||||
case Discreet3DS::CHUNK_OBJMESH:
|
case Discreet3DS::CHUNK_OBJMESH:
|
||||||
|
ParseObjectChunk();
|
||||||
|
break;
|
||||||
|
|
||||||
ParseObjectChunk();
|
// NOTE: In several documentations in the internet this
|
||||||
|
// chunk appears at different locations
|
||||||
|
case Discreet3DS::CHUNK_KEYFRAMER:
|
||||||
|
ParseKeyframeChunk();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Discreet3DS::CHUNK_VERSION: {
|
||||||
|
// print the version number
|
||||||
|
char buff[10];
|
||||||
|
ASSIMP_itoa10(buff, mStream->GetI2());
|
||||||
|
ASSIMP_LOG_INFO("3DS file format version: ", buff);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// NOTE: In several documentations in the internet this
|
|
||||||
// chunk appears at different locations
|
|
||||||
case Discreet3DS::CHUNK_KEYFRAMER:
|
|
||||||
|
|
||||||
ParseKeyframeChunk();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_VERSION: {
|
|
||||||
// print the version number
|
|
||||||
char buff[10];
|
|
||||||
ASSIMP_itoa10(buff, stream->GetI2());
|
|
||||||
ASSIMP_LOG_INFO("3DS file format version: ", buff);
|
|
||||||
} break;
|
|
||||||
};
|
};
|
||||||
ASSIMP_3DS_END_CHUNK();
|
ASSIMP_3DS_END_CHUNK()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
@@ -309,10 +307,10 @@ void Discreet3DSImporter::ParseObjectChunk() {
|
|||||||
switch (chunk.Flag) {
|
switch (chunk.Flag) {
|
||||||
case Discreet3DS::CHUNK_OBJBLOCK: {
|
case Discreet3DS::CHUNK_OBJBLOCK: {
|
||||||
unsigned int cnt = 0;
|
unsigned int cnt = 0;
|
||||||
const char *sz = (const char *)stream->GetPtr();
|
const auto *sz = (const char *)mStream->GetPtr();
|
||||||
|
|
||||||
// Get the name of the geometry object
|
// Get the name of the geometry object
|
||||||
while (stream->GetI1())
|
while (mStream->GetI1())
|
||||||
++cnt;
|
++cnt;
|
||||||
ParseChunk(sz, cnt);
|
ParseChunk(sz, cnt);
|
||||||
} break;
|
} break;
|
||||||
@@ -340,8 +338,8 @@ void Discreet3DSImporter::ParseObjectChunk() {
|
|||||||
// Specifies the background image. The string should already be
|
// Specifies the background image. The string should already be
|
||||||
// properly 0 terminated but we need to be sure
|
// properly 0 terminated but we need to be sure
|
||||||
unsigned int cnt = 0;
|
unsigned int cnt = 0;
|
||||||
const char *sz = (const char *)stream->GetPtr();
|
auto *sz = (const char *)mStream->GetPtr();
|
||||||
while (stream->GetI1())
|
while (mStream->GetI1())
|
||||||
++cnt;
|
++cnt;
|
||||||
mBackgroundImage = std::string(sz, cnt);
|
mBackgroundImage = std::string(sz, cnt);
|
||||||
} break;
|
} break;
|
||||||
@@ -352,7 +350,7 @@ void Discreet3DSImporter::ParseObjectChunk() {
|
|||||||
|
|
||||||
case Discreet3DS::CHUNK_MASTER_SCALE:
|
case Discreet3DS::CHUNK_MASTER_SCALE:
|
||||||
// Scene master scaling factor
|
// Scene master scaling factor
|
||||||
mMasterScale = stream->GetF4();
|
mMasterScale = mStream->GetF4();
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
ASSIMP_3DS_END_CHUNK();
|
ASSIMP_3DS_END_CHUNK();
|
||||||
@@ -379,15 +377,15 @@ void Discreet3DSImporter::ParseChunk(const char *name, unsigned int num) {
|
|||||||
|
|
||||||
case Discreet3DS::CHUNK_LIGHT: {
|
case Discreet3DS::CHUNK_LIGHT: {
|
||||||
// This starts a new light
|
// This starts a new light
|
||||||
aiLight *light = new aiLight();
|
auto *light = new aiLight();
|
||||||
mScene->mLights.push_back(light);
|
mScene->mLights.push_back(light);
|
||||||
|
|
||||||
light->mName.Set(std::string(name, num));
|
light->mName.Set(std::string(name, num));
|
||||||
|
|
||||||
// First read the position of the light
|
// First read the position of the light
|
||||||
light->mPosition.x = stream->GetF4();
|
light->mPosition.x = mStream->GetF4();
|
||||||
light->mPosition.y = stream->GetF4();
|
light->mPosition.y = mStream->GetF4();
|
||||||
light->mPosition.z = stream->GetF4();
|
light->mPosition.z = mStream->GetF4();
|
||||||
|
|
||||||
light->mColorDiffuse = aiColor3D(1.f, 1.f, 1.f);
|
light->mColorDiffuse = aiColor3D(1.f, 1.f, 1.f);
|
||||||
|
|
||||||
@@ -408,19 +406,19 @@ void Discreet3DSImporter::ParseChunk(const char *name, unsigned int num) {
|
|||||||
|
|
||||||
case Discreet3DS::CHUNK_CAMERA: {
|
case Discreet3DS::CHUNK_CAMERA: {
|
||||||
// This starts a new camera
|
// This starts a new camera
|
||||||
aiCamera *camera = new aiCamera();
|
auto *camera = new aiCamera();
|
||||||
mScene->mCameras.push_back(camera);
|
mScene->mCameras.push_back(camera);
|
||||||
camera->mName.Set(std::string(name, num));
|
camera->mName.Set(std::string(name, num));
|
||||||
|
|
||||||
// First read the position of the camera
|
// First read the position of the camera
|
||||||
camera->mPosition.x = stream->GetF4();
|
camera->mPosition.x = mStream->GetF4();
|
||||||
camera->mPosition.y = stream->GetF4();
|
camera->mPosition.y = mStream->GetF4();
|
||||||
camera->mPosition.z = stream->GetF4();
|
camera->mPosition.z = mStream->GetF4();
|
||||||
|
|
||||||
// Then the camera target
|
// Then the camera target
|
||||||
camera->mLookAt.x = stream->GetF4() - camera->mPosition.x;
|
camera->mLookAt.x = mStream->GetF4() - camera->mPosition.x;
|
||||||
camera->mLookAt.y = stream->GetF4() - camera->mPosition.y;
|
camera->mLookAt.y = mStream->GetF4() - camera->mPosition.y;
|
||||||
camera->mLookAt.z = stream->GetF4() - camera->mPosition.z;
|
camera->mLookAt.z = mStream->GetF4() - camera->mPosition.z;
|
||||||
ai_real len = camera->mLookAt.Length();
|
ai_real len = camera->mLookAt.Length();
|
||||||
if (len < 1e-5) {
|
if (len < 1e-5) {
|
||||||
|
|
||||||
@@ -432,12 +430,12 @@ void Discreet3DSImporter::ParseChunk(const char *name, unsigned int num) {
|
|||||||
camera->mLookAt /= len;
|
camera->mLookAt /= len;
|
||||||
|
|
||||||
// And finally - the camera rotation angle, in counter clockwise direction
|
// And finally - the camera rotation angle, in counter clockwise direction
|
||||||
const ai_real angle = AI_DEG_TO_RAD(stream->GetF4());
|
const ai_real angle = AI_DEG_TO_RAD(mStream->GetF4());
|
||||||
aiQuaternion quat(camera->mLookAt, angle);
|
aiQuaternion quat(camera->mLookAt, angle);
|
||||||
camera->mUp = quat.GetMatrix() * aiVector3D(0.0, 1.0, 0.0);
|
camera->mUp = quat.GetMatrix() * aiVector3D(0.0, 1.0, 0.0);
|
||||||
|
|
||||||
// Read the lense angle
|
// Read the lense angle
|
||||||
camera->mHorizontalFOV = AI_DEG_TO_RAD(stream->GetF4());
|
camera->mHorizontalFOV = AI_DEG_TO_RAD(mStream->GetF4());
|
||||||
if (camera->mHorizontalFOV < 0.001f) {
|
if (camera->mHorizontalFOV < 0.001f) {
|
||||||
camera->mHorizontalFOV = float(AI_DEG_TO_RAD(45.f));
|
camera->mHorizontalFOV = float(AI_DEG_TO_RAD(45.f));
|
||||||
}
|
}
|
||||||
@@ -463,34 +461,34 @@ void Discreet3DSImporter::ParseLightChunk() {
|
|||||||
light->mType = aiLightSource_SPOT;
|
light->mType = aiLightSource_SPOT;
|
||||||
|
|
||||||
// We wouldn't need to normalize here, but we do it
|
// We wouldn't need to normalize here, but we do it
|
||||||
light->mDirection.x = stream->GetF4() - light->mPosition.x;
|
light->mDirection.x = mStream->GetF4() - light->mPosition.x;
|
||||||
light->mDirection.y = stream->GetF4() - light->mPosition.y;
|
light->mDirection.y = mStream->GetF4() - light->mPosition.y;
|
||||||
light->mDirection.z = stream->GetF4() - light->mPosition.z;
|
light->mDirection.z = mStream->GetF4() - light->mPosition.z;
|
||||||
light->mDirection.Normalize();
|
light->mDirection.Normalize();
|
||||||
|
|
||||||
// Now the hotspot and falloff angles - in degrees
|
// Now the hotspot and falloff angles - in degrees
|
||||||
light->mAngleInnerCone = AI_DEG_TO_RAD(stream->GetF4());
|
light->mAngleInnerCone = AI_DEG_TO_RAD(mStream->GetF4());
|
||||||
|
|
||||||
// FIX: the falloff angle is just an offset
|
// FIX: the falloff angle is just an offset
|
||||||
light->mAngleOuterCone = light->mAngleInnerCone + AI_DEG_TO_RAD(stream->GetF4());
|
light->mAngleOuterCone = light->mAngleInnerCone + AI_DEG_TO_RAD(mStream->GetF4());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// intensity multiplier
|
// intensity multiplier
|
||||||
case Discreet3DS::CHUNK_DL_MULTIPLIER:
|
case Discreet3DS::CHUNK_DL_MULTIPLIER:
|
||||||
light->mColorDiffuse = light->mColorDiffuse * stream->GetF4();
|
light->mColorDiffuse = light->mColorDiffuse * mStream->GetF4();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// light color
|
// light color
|
||||||
case Discreet3DS::CHUNK_RGBF:
|
case Discreet3DS::CHUNK_RGBF:
|
||||||
case Discreet3DS::CHUNK_LINRGBF:
|
case Discreet3DS::CHUNK_LINRGBF:
|
||||||
light->mColorDiffuse.r *= stream->GetF4();
|
light->mColorDiffuse.r *= mStream->GetF4();
|
||||||
light->mColorDiffuse.g *= stream->GetF4();
|
light->mColorDiffuse.g *= mStream->GetF4();
|
||||||
light->mColorDiffuse.b *= stream->GetF4();
|
light->mColorDiffuse.b *= mStream->GetF4();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// light attenuation
|
// light attenuation
|
||||||
case Discreet3DS::CHUNK_DL_ATTENUATE:
|
case Discreet3DS::CHUNK_DL_ATTENUATE:
|
||||||
light->mAttenuationLinear = stream->GetF4();
|
light->mAttenuationLinear = mStream->GetF4();
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -505,10 +503,10 @@ void Discreet3DSImporter::ParseCameraChunk() {
|
|||||||
// get chunk type
|
// get chunk type
|
||||||
switch (chunk.Flag) {
|
switch (chunk.Flag) {
|
||||||
// near and far clip plane
|
// near and far clip plane
|
||||||
case Discreet3DS::CHUNK_CAM_RANGES:
|
case Discreet3DS::CHUNK_CAM_RANGES:
|
||||||
camera->mClipPlaneNear = stream->GetF4();
|
camera->mClipPlaneNear = mStream->GetF4();
|
||||||
camera->mClipPlaneFar = stream->GetF4();
|
camera->mClipPlaneFar = mStream->GetF4();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSIMP_3DS_END_CHUNK();
|
ASSIMP_3DS_END_CHUNK();
|
||||||
@@ -555,14 +553,13 @@ void Discreet3DSImporter::InverseNodeSearch(D3DS::Node *pcNode, D3DS::Node *pcCu
|
|||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Find a node with a specific name in the import hierarchy
|
// Find a node with a specific name in the import hierarchy
|
||||||
D3DS::Node *FindNode(D3DS::Node *root, const std::string &name) {
|
Node *FindNode(Node *root, const std::string &name) {
|
||||||
if (root->mName == name) {
|
if (root->mName == name) {
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::vector<D3DS::Node *>::iterator it = root->mChildren.begin(); it != root->mChildren.end(); ++it) {
|
for (auto it = root->mChildren.begin(); it != root->mChildren.end(); ++it) {
|
||||||
D3DS::Node *nd = FindNode(*it, name);
|
if (auto *nd = FindNode(*it, name); nullptr != nd) {
|
||||||
if (nullptr != nd) {
|
|
||||||
return nd;
|
return nd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -580,7 +577,7 @@ bool KeyUniqueCompare(const T &first, const T &second) {
|
|||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Skip some additional import data.
|
// Skip some additional import data.
|
||||||
void Discreet3DSImporter::SkipTCBInfo() {
|
void Discreet3DSImporter::SkipTCBInfo() {
|
||||||
unsigned int flags = stream->GetI2();
|
unsigned int flags = mStream->GetI2();
|
||||||
|
|
||||||
if (!flags) {
|
if (!flags) {
|
||||||
// Currently we can't do anything with these values. They occur
|
// Currently we can't do anything with these values. They occur
|
||||||
@@ -591,19 +588,19 @@ void Discreet3DSImporter::SkipTCBInfo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (flags & Discreet3DS::KEY_USE_TENS) {
|
if (flags & Discreet3DS::KEY_USE_TENS) {
|
||||||
stream->IncPtr(4);
|
mStream->IncPtr(4);
|
||||||
}
|
}
|
||||||
if (flags & Discreet3DS::KEY_USE_BIAS) {
|
if (flags & Discreet3DS::KEY_USE_BIAS) {
|
||||||
stream->IncPtr(4);
|
mStream->IncPtr(4);
|
||||||
}
|
}
|
||||||
if (flags & Discreet3DS::KEY_USE_CONT) {
|
if (flags & Discreet3DS::KEY_USE_CONT) {
|
||||||
stream->IncPtr(4);
|
mStream->IncPtr(4);
|
||||||
}
|
}
|
||||||
if (flags & Discreet3DS::KEY_USE_EASE_FROM) {
|
if (flags & Discreet3DS::KEY_USE_EASE_FROM) {
|
||||||
stream->IncPtr(4);
|
mStream->IncPtr(4);
|
||||||
}
|
}
|
||||||
if (flags & Discreet3DS::KEY_USE_EASE_TO) {
|
if (flags & Discreet3DS::KEY_USE_EASE_TO) {
|
||||||
stream->IncPtr(4);
|
mStream->IncPtr(4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -622,15 +619,15 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) {
|
|||||||
|
|
||||||
// First of all: get the name of the object
|
// First of all: get the name of the object
|
||||||
unsigned int cnt = 0;
|
unsigned int cnt = 0;
|
||||||
const char *sz = (const char *)stream->GetPtr();
|
auto *sz = (const char *)mStream->GetPtr();
|
||||||
|
|
||||||
while (stream->GetI1())
|
while (mStream->GetI1())
|
||||||
++cnt;
|
++cnt;
|
||||||
std::string name = std::string(sz, cnt);
|
std::string name = std::string(sz, cnt);
|
||||||
|
|
||||||
// Now find out whether we have this node already (target animation channels
|
// Now find out whether we have this node already (target animation channels
|
||||||
// are stored with a separate object ID)
|
// are stored with a separate object ID)
|
||||||
D3DS::Node *pcNode = FindNode(mRootNode, name);
|
Node *pcNode = FindNode(mRootNode, name);
|
||||||
int instanceNumber = 1;
|
int instanceNumber = 1;
|
||||||
|
|
||||||
if (pcNode) {
|
if (pcNode) {
|
||||||
@@ -646,10 +643,10 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) {
|
|||||||
pcNode->mInstanceNumber = instanceNumber;
|
pcNode->mInstanceNumber = instanceNumber;
|
||||||
|
|
||||||
// There are two unknown values which we can safely ignore
|
// There are two unknown values which we can safely ignore
|
||||||
stream->IncPtr(4);
|
mStream->IncPtr(4);
|
||||||
|
|
||||||
// Now read the hierarchy position of the object
|
// Now read the hierarchy position of the object
|
||||||
uint16_t hierarchy = stream->GetI2() + 1;
|
uint16_t hierarchy = mStream->GetI2() + 1;
|
||||||
pcNode->mHierarchyPos = hierarchy;
|
pcNode->mHierarchyPos = hierarchy;
|
||||||
pcNode->mHierarchyIndex = mLastNodeIndex;
|
pcNode->mHierarchyIndex = mLastNodeIndex;
|
||||||
|
|
||||||
@@ -678,8 +675,8 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) {
|
|||||||
|
|
||||||
// This is the "real" name of a $$$DUMMY object
|
// This is the "real" name of a $$$DUMMY object
|
||||||
{
|
{
|
||||||
const char *sz = (const char *)stream->GetPtr();
|
const char *sz = (const char *)mStream->GetPtr();
|
||||||
while (stream->GetI1())
|
while (mStream->GetI1())
|
||||||
;
|
;
|
||||||
|
|
||||||
// If object name is DUMMY, take this one instead
|
// If object name is DUMMY, take this one instead
|
||||||
@@ -698,16 +695,16 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pivot = origin of rotation and scaling
|
// Pivot = origin of rotation and scaling
|
||||||
mCurrentNode->vPivot.x = stream->GetF4();
|
mCurrentNode->vPivot.x = mStream->GetF4();
|
||||||
mCurrentNode->vPivot.y = stream->GetF4();
|
mCurrentNode->vPivot.y = mStream->GetF4();
|
||||||
mCurrentNode->vPivot.z = stream->GetF4();
|
mCurrentNode->vPivot.z = mStream->GetF4();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// ////////////////////////////////////////////////////////////////////
|
// ////////////////////////////////////////////////////////////////////
|
||||||
// POSITION KEYFRAME
|
// POSITION KEYFRAME
|
||||||
case Discreet3DS::CHUNK_TRACKPOS: {
|
case Discreet3DS::CHUNK_TRACKPOS: {
|
||||||
stream->IncPtr(10);
|
mStream->IncPtr(10);
|
||||||
const unsigned int numFrames = stream->GetI4();
|
const unsigned int numFrames = mStream->GetI4();
|
||||||
bool sortKeys = false;
|
bool sortKeys = false;
|
||||||
|
|
||||||
// This could also be meant as the target position for
|
// This could also be meant as the target position for
|
||||||
@@ -720,16 +717,16 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) {
|
|||||||
|
|
||||||
l->reserve(numFrames);
|
l->reserve(numFrames);
|
||||||
for (unsigned int i = 0; i < numFrames; ++i) {
|
for (unsigned int i = 0; i < numFrames; ++i) {
|
||||||
const unsigned int fidx = stream->GetI4();
|
const unsigned int fidx = mStream->GetI4();
|
||||||
|
|
||||||
// Setup a new position key
|
// Setup a new position key
|
||||||
aiVectorKey v;
|
aiVectorKey v;
|
||||||
v.mTime = (double)fidx;
|
v.mTime = (double)fidx;
|
||||||
|
|
||||||
SkipTCBInfo();
|
SkipTCBInfo();
|
||||||
v.mValue.x = stream->GetF4();
|
v.mValue.x = mStream->GetF4();
|
||||||
v.mValue.y = stream->GetF4();
|
v.mValue.y = mStream->GetF4();
|
||||||
v.mValue.z = stream->GetF4();
|
v.mValue.z = mStream->GetF4();
|
||||||
|
|
||||||
// check whether we'll need to sort the keys
|
// check whether we'll need to sort the keys
|
||||||
if (!l->empty() && v.mTime <= l->back().mTime)
|
if (!l->empty() && v.mTime <= l->back().mTime)
|
||||||
@@ -759,11 +756,11 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) {
|
|||||||
bool sortKeys = false;
|
bool sortKeys = false;
|
||||||
std::vector<aiFloatKey> *l = &mCurrentNode->aCameraRollKeys;
|
std::vector<aiFloatKey> *l = &mCurrentNode->aCameraRollKeys;
|
||||||
|
|
||||||
stream->IncPtr(10);
|
mStream->IncPtr(10);
|
||||||
const unsigned int numFrames = stream->GetI4();
|
const unsigned int numFrames = mStream->GetI4();
|
||||||
l->reserve(numFrames);
|
l->reserve(numFrames);
|
||||||
for (unsigned int i = 0; i < numFrames; ++i) {
|
for (unsigned int i = 0; i < numFrames; ++i) {
|
||||||
const unsigned int fidx = stream->GetI4();
|
const unsigned int fidx = mStream->GetI4();
|
||||||
|
|
||||||
// Setup a new position key
|
// Setup a new position key
|
||||||
aiFloatKey v;
|
aiFloatKey v;
|
||||||
@@ -771,7 +768,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) {
|
|||||||
|
|
||||||
// This is just a single float
|
// This is just a single float
|
||||||
SkipTCBInfo();
|
SkipTCBInfo();
|
||||||
v.mValue = stream->GetF4();
|
v.mValue = mStream->GetF4();
|
||||||
|
|
||||||
// Check whether we'll need to sort the keys
|
// Check whether we'll need to sort the keys
|
||||||
if (!l->empty() && v.mTime <= l->back().mTime)
|
if (!l->empty() && v.mTime <= l->back().mTime)
|
||||||
@@ -798,26 +795,26 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) {
|
|||||||
// ////////////////////////////////////////////////////////////////////
|
// ////////////////////////////////////////////////////////////////////
|
||||||
// ROTATION KEYFRAME
|
// ROTATION KEYFRAME
|
||||||
case Discreet3DS::CHUNK_TRACKROTATE: {
|
case Discreet3DS::CHUNK_TRACKROTATE: {
|
||||||
stream->IncPtr(10);
|
mStream->IncPtr(10);
|
||||||
const unsigned int numFrames = stream->GetI4();
|
const unsigned int numFrames = mStream->GetI4();
|
||||||
|
|
||||||
bool sortKeys = false;
|
bool sortKeys = false;
|
||||||
std::vector<aiQuatKey> *l = &mCurrentNode->aRotationKeys;
|
std::vector<aiQuatKey> *l = &mCurrentNode->aRotationKeys;
|
||||||
l->reserve(numFrames);
|
l->reserve(numFrames);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < numFrames; ++i) {
|
for (unsigned int i = 0; i < numFrames; ++i) {
|
||||||
const unsigned int fidx = stream->GetI4();
|
const unsigned int fidx = mStream->GetI4();
|
||||||
SkipTCBInfo();
|
SkipTCBInfo();
|
||||||
|
|
||||||
aiQuatKey v;
|
aiQuatKey v;
|
||||||
v.mTime = (double)fidx;
|
v.mTime = (double)fidx;
|
||||||
|
|
||||||
// The rotation keyframe is given as an axis-angle pair
|
// The rotation keyframe is given as an axis-angle pair
|
||||||
const float rad = stream->GetF4();
|
const float rad = mStream->GetF4();
|
||||||
aiVector3D axis;
|
aiVector3D axis;
|
||||||
axis.x = stream->GetF4();
|
axis.x = mStream->GetF4();
|
||||||
axis.y = stream->GetF4();
|
axis.y = mStream->GetF4();
|
||||||
axis.z = stream->GetF4();
|
axis.z = mStream->GetF4();
|
||||||
|
|
||||||
if (!axis.x && !axis.y && !axis.z)
|
if (!axis.x && !axis.y && !axis.z)
|
||||||
axis.y = 1.f;
|
axis.y = 1.f;
|
||||||
@@ -842,16 +839,16 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) {
|
|||||||
// ////////////////////////////////////////////////////////////////////
|
// ////////////////////////////////////////////////////////////////////
|
||||||
// SCALING KEYFRAME
|
// SCALING KEYFRAME
|
||||||
case Discreet3DS::CHUNK_TRACKSCALE: {
|
case Discreet3DS::CHUNK_TRACKSCALE: {
|
||||||
stream->IncPtr(10);
|
mStream->IncPtr(10);
|
||||||
const unsigned int numFrames = stream->GetI2();
|
const unsigned int numFrames = mStream->GetI2();
|
||||||
stream->IncPtr(2);
|
mStream->IncPtr(2);
|
||||||
|
|
||||||
bool sortKeys = false;
|
bool sortKeys = false;
|
||||||
std::vector<aiVectorKey> *l = &mCurrentNode->aScalingKeys;
|
std::vector<aiVectorKey> *l = &mCurrentNode->aScalingKeys;
|
||||||
l->reserve(numFrames);
|
l->reserve(numFrames);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < numFrames; ++i) {
|
for (unsigned int i = 0; i < numFrames; ++i) {
|
||||||
const unsigned int fidx = stream->GetI4();
|
const unsigned int fidx = mStream->GetI4();
|
||||||
SkipTCBInfo();
|
SkipTCBInfo();
|
||||||
|
|
||||||
// Setup a new key
|
// Setup a new key
|
||||||
@@ -859,9 +856,9 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) {
|
|||||||
v.mTime = (double)fidx;
|
v.mTime = (double)fidx;
|
||||||
|
|
||||||
// ... and read its value
|
// ... and read its value
|
||||||
v.mValue.x = stream->GetF4();
|
v.mValue.x = mStream->GetF4();
|
||||||
v.mValue.y = stream->GetF4();
|
v.mValue.y = mStream->GetF4();
|
||||||
v.mValue.z = stream->GetF4();
|
v.mValue.z = mStream->GetF4();
|
||||||
|
|
||||||
// check whether we'll need to sort the keys
|
// check whether we'll need to sort the keys
|
||||||
if (!l->empty() && v.mTime <= l->back().mTime)
|
if (!l->empty() && v.mTime <= l->back().mTime)
|
||||||
@@ -902,23 +899,23 @@ void Discreet3DSImporter::ParseFaceChunk() {
|
|||||||
if (num > mMesh.mFaces.size()) {
|
if (num > mMesh.mFaces.size()) {
|
||||||
throw DeadlyImportError("3DS: More smoothing groups than faces");
|
throw DeadlyImportError("3DS: More smoothing groups than faces");
|
||||||
}
|
}
|
||||||
for (std::vector<D3DS::Face>::iterator i = mMesh.mFaces.begin(); m != num; ++i, ++m) {
|
for (auto i = mMesh.mFaces.begin(); m != num; ++i, ++m) {
|
||||||
// nth bit is set for nth smoothing group
|
// nth bit is set for nth smoothing group
|
||||||
(*i).iSmoothGroup = stream->GetI4();
|
i->iSmoothGroup = mStream->GetI4();
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_FACEMAT: {
|
case Discreet3DS::CHUNK_FACEMAT: {
|
||||||
// at fist an asciiz with the material name
|
// at fist an asciiz with the material name
|
||||||
const char *sz = (const char *)stream->GetPtr();
|
const char *sz = (const char *)mStream->GetPtr();
|
||||||
while (stream->GetI1())
|
while (mStream->GetI1())
|
||||||
;
|
;
|
||||||
|
|
||||||
// find the index of the material
|
// find the index of the material
|
||||||
unsigned int idx = 0xcdcdcdcd, cnt = 0;
|
unsigned int idx = 0xcdcdcdcd, cnt = 0;
|
||||||
for (std::vector<D3DS::Material>::const_iterator i = mScene->mMaterials.begin(); i != mScene->mMaterials.end(); ++i, ++cnt) {
|
for (auto i = mScene->mMaterials.begin(); i != mScene->mMaterials.end(); ++i, ++cnt) {
|
||||||
// use case independent comparisons. hopefully it will work.
|
// use case independent comparisons. hopefully it will work.
|
||||||
if ((*i).mName.length() && !ASSIMP_stricmp(sz, (*i).mName.c_str())) {
|
if (i->mName.length() && !ASSIMP_stricmp(sz, i->mName.c_str())) {
|
||||||
idx = cnt;
|
idx = cnt;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -928,9 +925,9 @@ void Discreet3DSImporter::ParseFaceChunk() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now continue and read all material indices
|
// Now continue and read all material indices
|
||||||
cnt = (uint16_t)stream->GetI2();
|
cnt = (uint16_t)mStream->GetI2();
|
||||||
for (unsigned int i = 0; i < cnt; ++i) {
|
for (unsigned int i = 0; i < cnt; ++i) {
|
||||||
unsigned int fidx = (uint16_t)stream->GetI2();
|
unsigned int fidx = (uint16_t)mStream->GetI2();
|
||||||
|
|
||||||
// check range
|
// check range
|
||||||
if (fidx >= mMesh.mFaceMaterials.size()) {
|
if (fidx >= mMesh.mFaceMaterials.size()) {
|
||||||
@@ -955,59 +952,59 @@ void Discreet3DSImporter::ParseMeshChunk() {
|
|||||||
switch (chunk.Flag) {
|
switch (chunk.Flag) {
|
||||||
case Discreet3DS::CHUNK_VERTLIST: {
|
case Discreet3DS::CHUNK_VERTLIST: {
|
||||||
// This is the list of all vertices in the current mesh
|
// This is the list of all vertices in the current mesh
|
||||||
int num = (int)(uint16_t)stream->GetI2();
|
int num = (int)(uint16_t)mStream->GetI2();
|
||||||
mMesh.mPositions.reserve(num);
|
mMesh.mPositions.reserve(num);
|
||||||
while (num-- > 0) {
|
while (num-- > 0) {
|
||||||
aiVector3D v;
|
aiVector3D v;
|
||||||
v.x = stream->GetF4();
|
v.x = mStream->GetF4();
|
||||||
v.y = stream->GetF4();
|
v.y = mStream->GetF4();
|
||||||
v.z = stream->GetF4();
|
v.z = mStream->GetF4();
|
||||||
mMesh.mPositions.push_back(v);
|
mMesh.mPositions.push_back(v);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case Discreet3DS::CHUNK_TRMATRIX: {
|
case Discreet3DS::CHUNK_TRMATRIX: {
|
||||||
// This is the RLEATIVE transformation matrix of the current mesh. Vertices are
|
// This is the RLEATIVE transformation matrix of the current mesh. Vertices are
|
||||||
// pretransformed by this matrix wonder.
|
// pretransformed by this matrix wonder.
|
||||||
mMesh.mMat.a1 = stream->GetF4();
|
mMesh.mMat.a1 = mStream->GetF4();
|
||||||
mMesh.mMat.b1 = stream->GetF4();
|
mMesh.mMat.b1 = mStream->GetF4();
|
||||||
mMesh.mMat.c1 = stream->GetF4();
|
mMesh.mMat.c1 = mStream->GetF4();
|
||||||
mMesh.mMat.a2 = stream->GetF4();
|
mMesh.mMat.a2 = mStream->GetF4();
|
||||||
mMesh.mMat.b2 = stream->GetF4();
|
mMesh.mMat.b2 = mStream->GetF4();
|
||||||
mMesh.mMat.c2 = stream->GetF4();
|
mMesh.mMat.c2 = mStream->GetF4();
|
||||||
mMesh.mMat.a3 = stream->GetF4();
|
mMesh.mMat.a3 = mStream->GetF4();
|
||||||
mMesh.mMat.b3 = stream->GetF4();
|
mMesh.mMat.b3 = mStream->GetF4();
|
||||||
mMesh.mMat.c3 = stream->GetF4();
|
mMesh.mMat.c3 = mStream->GetF4();
|
||||||
mMesh.mMat.a4 = stream->GetF4();
|
mMesh.mMat.a4 = mStream->GetF4();
|
||||||
mMesh.mMat.b4 = stream->GetF4();
|
mMesh.mMat.b4 = mStream->GetF4();
|
||||||
mMesh.mMat.c4 = stream->GetF4();
|
mMesh.mMat.c4 = mStream->GetF4();
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_MAPLIST: {
|
case Discreet3DS::CHUNK_MAPLIST: {
|
||||||
// This is the list of all UV coords in the current mesh
|
// This is the list of all UV coords in the current mesh
|
||||||
int num = (int)(uint16_t)stream->GetI2();
|
int num = (int)(uint16_t)mStream->GetI2();
|
||||||
mMesh.mTexCoords.reserve(num);
|
mMesh.mTexCoords.reserve(num);
|
||||||
while (num-- > 0) {
|
while (num-- > 0) {
|
||||||
aiVector3D v;
|
aiVector3D v;
|
||||||
v.x = stream->GetF4();
|
v.x = mStream->GetF4();
|
||||||
v.y = stream->GetF4();
|
v.y = mStream->GetF4();
|
||||||
mMesh.mTexCoords.push_back(v);
|
mMesh.mTexCoords.push_back(v);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_FACELIST: {
|
case Discreet3DS::CHUNK_FACELIST: {
|
||||||
// This is the list of all faces in the current mesh
|
// This is the list of all faces in the current mesh
|
||||||
int num = (int)(uint16_t)stream->GetI2();
|
int num = (int)(uint16_t)mStream->GetI2();
|
||||||
mMesh.mFaces.reserve(num);
|
mMesh.mFaces.reserve(num);
|
||||||
while (num-- > 0) {
|
while (num-- > 0) {
|
||||||
// 3DS faces are ALWAYS triangles
|
// 3DS faces are ALWAYS triangles
|
||||||
mMesh.mFaces.emplace_back();
|
mMesh.mFaces.emplace_back();
|
||||||
D3DS::Face &sFace = mMesh.mFaces.back();
|
Face &sFace = mMesh.mFaces.back();
|
||||||
|
|
||||||
sFace.mIndices[0] = (uint16_t)stream->GetI2();
|
sFace.mIndices[0] = (uint16_t)mStream->GetI2();
|
||||||
sFace.mIndices[1] = (uint16_t)stream->GetI2();
|
sFace.mIndices[1] = (uint16_t)mStream->GetI2();
|
||||||
sFace.mIndices[2] = (uint16_t)stream->GetI2();
|
sFace.mIndices[2] = (uint16_t)mStream->GetI2();
|
||||||
|
|
||||||
stream->IncPtr(2); // skip edge visibility flag
|
mStream->IncPtr(2); // skip edge visibility flag
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resize the material array (0xcdcdcdcd marks the default material; so if a face is
|
// Resize the material array (0xcdcdcdcd marks the default material; so if a face is
|
||||||
@@ -1015,7 +1012,7 @@ void Discreet3DSImporter::ParseMeshChunk() {
|
|||||||
mMesh.mFaceMaterials.resize(mMesh.mFaces.size(), 0xcdcdcdcd);
|
mMesh.mFaceMaterials.resize(mMesh.mFaces.size(), 0xcdcdcdcd);
|
||||||
|
|
||||||
// Larger 3DS files could have multiple FACE chunks here
|
// Larger 3DS files could have multiple FACE chunks here
|
||||||
chunkSize = (int)stream->GetRemainingSizeToLimit();
|
chunkSize = (int)mStream->GetRemainingSizeToLimit();
|
||||||
if (chunkSize > (int)sizeof(Discreet3DS::Chunk))
|
if (chunkSize > (int)sizeof(Discreet3DS::Chunk))
|
||||||
ParseFaceChunk();
|
ParseFaceChunk();
|
||||||
} break;
|
} break;
|
||||||
@@ -1032,9 +1029,9 @@ void Discreet3DSImporter::ParseMaterialChunk() {
|
|||||||
|
|
||||||
{
|
{
|
||||||
// The material name string is already zero-terminated, but we need to be sure ...
|
// The material name string is already zero-terminated, but we need to be sure ...
|
||||||
const char *sz = (const char *)stream->GetPtr();
|
const char *sz = (const char *)mStream->GetPtr();
|
||||||
unsigned int cnt = 0;
|
unsigned int cnt = 0;
|
||||||
while (stream->GetI1())
|
while (mStream->GetI1())
|
||||||
++cnt;
|
++cnt;
|
||||||
|
|
||||||
if (!cnt) {
|
if (!cnt) {
|
||||||
@@ -1102,7 +1099,7 @@ void Discreet3DSImporter::ParseMaterialChunk() {
|
|||||||
|
|
||||||
case Discreet3DS::CHUNK_MAT_SHADING:
|
case Discreet3DS::CHUNK_MAT_SHADING:
|
||||||
// This is the material shading mode
|
// This is the material shading mode
|
||||||
mScene->mMaterials.back().mShading = (D3DS::Discreet3DS::shadetype3ds)stream->GetI2();
|
mScene->mMaterials.back().mShading = (Discreet3DS::shadetype3ds)mStream->GetI2();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_MAT_TWO_SIDE:
|
case Discreet3DS::CHUNK_MAT_TWO_SIDE:
|
||||||
@@ -1178,31 +1175,31 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture *pcOut) {
|
|||||||
switch (chunk.Flag) {
|
switch (chunk.Flag) {
|
||||||
case Discreet3DS::CHUNK_MAPFILE: {
|
case Discreet3DS::CHUNK_MAPFILE: {
|
||||||
// The material name string is already zero-terminated, but we need to be sure ...
|
// The material name string is already zero-terminated, but we need to be sure ...
|
||||||
const char *sz = (const char *)stream->GetPtr();
|
const char *sz = (const char *)mStream->GetPtr();
|
||||||
unsigned int cnt = 0;
|
unsigned int cnt = 0;
|
||||||
while (stream->GetI1())
|
while (mStream->GetI1())
|
||||||
++cnt;
|
++cnt;
|
||||||
pcOut->mMapName = std::string(sz, cnt);
|
pcOut->mMapName = std::string(sz, cnt);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_PERCENTD:
|
case Discreet3DS::CHUNK_PERCENTD:
|
||||||
// Manually parse the blend factor
|
// Manually parse the blend factor
|
||||||
pcOut->mTextureBlend = ai_real(stream->GetF8());
|
pcOut->mTextureBlend = ai_real(mStream->GetF8());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_PERCENTF:
|
case Discreet3DS::CHUNK_PERCENTF:
|
||||||
// Manually parse the blend factor
|
// Manually parse the blend factor
|
||||||
pcOut->mTextureBlend = stream->GetF4();
|
pcOut->mTextureBlend = mStream->GetF4();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_PERCENTW:
|
case Discreet3DS::CHUNK_PERCENTW:
|
||||||
// Manually parse the blend factor
|
// Manually parse the blend factor
|
||||||
pcOut->mTextureBlend = (ai_real)((uint16_t)stream->GetI2()) / ai_real(100.0);
|
pcOut->mTextureBlend = (ai_real)((uint16_t) mStream->GetI2()) / ai_real(100.0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_MAT_MAP_USCALE:
|
case Discreet3DS::CHUNK_MAT_MAP_USCALE:
|
||||||
// Texture coordinate scaling in the U direction
|
// Texture coordinate scaling in the U direction
|
||||||
pcOut->mScaleU = stream->GetF4();
|
pcOut->mScaleU = mStream->GetF4();
|
||||||
if (0.0f == pcOut->mScaleU) {
|
if (0.0f == pcOut->mScaleU) {
|
||||||
ASSIMP_LOG_WARN("Texture coordinate scaling in the x direction is zero. Assuming 1.");
|
ASSIMP_LOG_WARN("Texture coordinate scaling in the x direction is zero. Assuming 1.");
|
||||||
pcOut->mScaleU = 1.0f;
|
pcOut->mScaleU = 1.0f;
|
||||||
@@ -1210,7 +1207,7 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture *pcOut) {
|
|||||||
break;
|
break;
|
||||||
case Discreet3DS::CHUNK_MAT_MAP_VSCALE:
|
case Discreet3DS::CHUNK_MAT_MAP_VSCALE:
|
||||||
// Texture coordinate scaling in the V direction
|
// Texture coordinate scaling in the V direction
|
||||||
pcOut->mScaleV = stream->GetF4();
|
pcOut->mScaleV = mStream->GetF4();
|
||||||
if (0.0f == pcOut->mScaleV) {
|
if (0.0f == pcOut->mScaleV) {
|
||||||
ASSIMP_LOG_WARN("Texture coordinate scaling in the y direction is zero. Assuming 1.");
|
ASSIMP_LOG_WARN("Texture coordinate scaling in the y direction is zero. Assuming 1.");
|
||||||
pcOut->mScaleV = 1.0f;
|
pcOut->mScaleV = 1.0f;
|
||||||
@@ -1219,21 +1216,21 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture *pcOut) {
|
|||||||
|
|
||||||
case Discreet3DS::CHUNK_MAT_MAP_UOFFSET:
|
case Discreet3DS::CHUNK_MAT_MAP_UOFFSET:
|
||||||
// Texture coordinate offset in the U direction
|
// Texture coordinate offset in the U direction
|
||||||
pcOut->mOffsetU = -stream->GetF4();
|
pcOut->mOffsetU = -mStream->GetF4();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_MAT_MAP_VOFFSET:
|
case Discreet3DS::CHUNK_MAT_MAP_VOFFSET:
|
||||||
// Texture coordinate offset in the V direction
|
// Texture coordinate offset in the V direction
|
||||||
pcOut->mOffsetV = stream->GetF4();
|
pcOut->mOffsetV = mStream->GetF4();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_MAT_MAP_ANG:
|
case Discreet3DS::CHUNK_MAT_MAP_ANG:
|
||||||
// Texture coordinate rotation, CCW in DEGREES
|
// Texture coordinate rotation, CCW in DEGREES
|
||||||
pcOut->mRotation = -AI_DEG_TO_RAD(stream->GetF4());
|
pcOut->mRotation = -AI_DEG_TO_RAD(mStream->GetF4());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_MAT_MAP_TILING: {
|
case Discreet3DS::CHUNK_MAT_MAP_TILING: {
|
||||||
const uint16_t iFlags = stream->GetI2();
|
const uint16_t iFlags = mStream->GetI2();
|
||||||
|
|
||||||
// Get the mapping mode (for both axes)
|
// Get the mapping mode (for both axes)
|
||||||
if (iFlags & 0x2u)
|
if (iFlags & 0x2u)
|
||||||
@@ -1258,9 +1255,11 @@ ai_real Discreet3DSImporter::ParsePercentageChunk() {
|
|||||||
ReadChunk(&chunk);
|
ReadChunk(&chunk);
|
||||||
|
|
||||||
if (Discreet3DS::CHUNK_PERCENTF == chunk.Flag) {
|
if (Discreet3DS::CHUNK_PERCENTF == chunk.Flag) {
|
||||||
return stream->GetF4() * ai_real(100) / ai_real(0xFFFF);
|
return mStream->GetF4() * ai_real(100) / ai_real(0xFFFF);
|
||||||
} else if (Discreet3DS::CHUNK_PERCENTW == chunk.Flag) {
|
}
|
||||||
return (ai_real)((uint16_t)stream->GetI2()) / (ai_real)0xFFFF;
|
|
||||||
|
if (Discreet3DS::CHUNK_PERCENTW == chunk.Flag) {
|
||||||
|
return (ai_real)((uint16_t)mStream->GetI2()) / (ai_real)0xFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
return get_qnan();
|
return get_qnan();
|
||||||
@@ -1291,9 +1290,9 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D *out, bool acceptPercent) {
|
|||||||
*out = clrError;
|
*out = clrError;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
out->r = stream->GetF4();
|
out->r = mStream->GetF4();
|
||||||
out->g = stream->GetF4();
|
out->g = mStream->GetF4();
|
||||||
out->b = stream->GetF4();
|
out->b = mStream->GetF4();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_LINRGBB:
|
case Discreet3DS::CHUNK_LINRGBB:
|
||||||
@@ -1305,15 +1304,15 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D *out, bool acceptPercent) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const ai_real invVal = ai_real(1.0) / ai_real(255.0);
|
const ai_real invVal = ai_real(1.0) / ai_real(255.0);
|
||||||
out->r = (ai_real)(uint8_t)stream->GetI1() * invVal;
|
out->r = (ai_real)(uint8_t)mStream->GetI1() * invVal;
|
||||||
out->g = (ai_real)(uint8_t)stream->GetI1() * invVal;
|
out->g = (ai_real)(uint8_t)mStream->GetI1() * invVal;
|
||||||
out->b = (ai_real)(uint8_t)stream->GetI1() * invVal;
|
out->b = (ai_real)(uint8_t)mStream->GetI1() * invVal;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
// Percentage chunks are accepted, too.
|
// Percentage chunks are accepted, too.
|
||||||
case Discreet3DS::CHUNK_PERCENTF:
|
case Discreet3DS::CHUNK_PERCENTF:
|
||||||
if (acceptPercent && 4 <= diff) {
|
if (acceptPercent && 4 <= diff) {
|
||||||
out->g = out->b = out->r = stream->GetF4();
|
out->g = out->b = out->r = mStream->GetF4();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*out = clrError;
|
*out = clrError;
|
||||||
@@ -1321,14 +1320,14 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D *out, bool acceptPercent) {
|
|||||||
|
|
||||||
case Discreet3DS::CHUNK_PERCENTW:
|
case Discreet3DS::CHUNK_PERCENTW:
|
||||||
if (acceptPercent && 1 <= diff) {
|
if (acceptPercent && 1 <= diff) {
|
||||||
out->g = out->b = out->r = (ai_real)(uint8_t)stream->GetI1() / ai_real(255.0);
|
out->g = out->b = out->r = (ai_real)(uint8_t)mStream->GetI1() / ai_real(255.0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*out = clrError;
|
*out = clrError;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
stream->IncPtr(diff);
|
mStream->IncPtr(diff);
|
||||||
// Skip unknown chunks, hope this won't cause any problems.
|
// Skip unknown chunks, hope this won't cause any problems.
|
||||||
return ParseColorChunk(out, acceptPercent);
|
return ParseColorChunk(out, acceptPercent);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <assimp/BaseImporter.h>
|
#include <assimp/BaseImporter.h>
|
||||||
#include <assimp/types.h>
|
#include <assimp/types.h>
|
||||||
|
|
||||||
|
|
||||||
#include "3DSHelper.h"
|
#include "3DSHelper.h"
|
||||||
#include <assimp/StreamReader.h>
|
#include <assimp/StreamReader.h>
|
||||||
|
|
||||||
@@ -57,8 +56,6 @@ struct aiNode;
|
|||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
using namespace D3DS;
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
/** Importer class for 3D Studio r3 and r4 3DS files
|
/** Importer class for 3D Studio r3 and r4 3DS files
|
||||||
*/
|
*/
|
||||||
@@ -99,15 +96,14 @@ protected:
|
|||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Converts a temporary material to the outer representation
|
/** Converts a temporary material to the outer representation
|
||||||
*/
|
*/
|
||||||
void ConvertMaterial(D3DS::Material& p_cMat,
|
void ConvertMaterial(D3DS::Material& p_cMat, aiMaterial& p_pcOut);
|
||||||
aiMaterial& p_pcOut);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Read a chunk
|
/** Read a chunk
|
||||||
*
|
*
|
||||||
* @param pcOut Receives the current chunk
|
* @param pcOut Receives the current chunk
|
||||||
*/
|
*/
|
||||||
void ReadChunk(Discreet3DS::Chunk* pcOut);
|
void ReadChunk(D3DS::Discreet3DS::Chunk* pcOut);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Parse a percentage chunk. mCurrent will point to the next
|
/** Parse a percentage chunk. mCurrent will point to the next
|
||||||
@@ -117,12 +113,10 @@ protected:
|
|||||||
ai_real ParsePercentageChunk();
|
ai_real ParsePercentageChunk();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Parse a color chunk. mCurrent will point to the next
|
/** Parse a color chunk. mCurrent will point to the next chunk behind
|
||||||
* chunk behind afterwards. If no color chunk is found
|
* afterward. If no color chunk is found QNAN is returned in all members.
|
||||||
* QNAN is returned in all members.
|
*/
|
||||||
*/
|
void ParseColorChunk(aiColor3D* p_pcOut, bool p_bAcceptPercent = true);
|
||||||
void ParseColorChunk(aiColor3D* p_pcOut,
|
|
||||||
bool p_bAcceptPercent = true);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Skip a chunk in the file
|
/** Skip a chunk in the file
|
||||||
@@ -130,7 +124,7 @@ protected:
|
|||||||
void SkipChunk();
|
void SkipChunk();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Generate the nodegraph
|
/** Generate the node-graph
|
||||||
*/
|
*/
|
||||||
void GenerateNodeGraph(aiScene* pcOut);
|
void GenerateNodeGraph(aiScene* pcOut);
|
||||||
|
|
||||||
@@ -226,19 +220,19 @@ protected:
|
|||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Add a node to the node graph
|
/** Add a node to the node graph
|
||||||
*/
|
*/
|
||||||
void AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Node* pcIn,
|
void AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut, D3DS::Node* pcIn,
|
||||||
aiMatrix4x4& absTrafo);
|
aiMatrix4x4& absTrafo);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Search for a node in the graph.
|
/** Search for a node in the graph.
|
||||||
* Called recursively
|
* Called recursively
|
||||||
*/
|
*/
|
||||||
void InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCurrent);
|
void InverseNodeSearch(D3DS::Node* pcNode, D3DS::Node* pcCurrent);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Apply the master scaling factor to the mesh
|
/** Apply the master scaling factor to the mesh
|
||||||
*/
|
*/
|
||||||
void ApplyMasterScale(aiScene* pScene);
|
void ApplyMasterScale(const aiScene* pScene);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Clamp all indices in the file to a valid range
|
/** Clamp all indices in the file to a valid range
|
||||||
@@ -250,31 +244,26 @@ protected:
|
|||||||
*/
|
*/
|
||||||
void SkipTCBInfo();
|
void SkipTCBInfo();
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
/// Stream to read from
|
||||||
/** Stream to read from */
|
StreamReaderLE* mStream;
|
||||||
StreamReaderLE* stream;
|
/// Last touched node index
|
||||||
|
|
||||||
/** Last touched node index */
|
|
||||||
short mLastNodeIndex;
|
short mLastNodeIndex;
|
||||||
|
/// Current node
|
||||||
/** Current node, root node */
|
D3DS::Node* mCurrentNode;
|
||||||
D3DS::Node* mCurrentNode, *mRootNode;
|
/// Root node
|
||||||
|
D3DS::Node *mRootNode;
|
||||||
/** Scene under construction */
|
/// Scene under construction
|
||||||
D3DS::Scene* mScene;
|
D3DS::Scene* mScene;
|
||||||
|
/// Ambient base color of the scene
|
||||||
/** Ambient base color of the scene */
|
|
||||||
aiColor3D mClrAmbient;
|
aiColor3D mClrAmbient;
|
||||||
|
/// Master scaling factor of the scene
|
||||||
/** Master scaling factor of the scene */
|
|
||||||
ai_real mMasterScale;
|
ai_real mMasterScale;
|
||||||
|
/// Path to the background image of the scene
|
||||||
/** Path to the background image of the scene */
|
|
||||||
std::string mBackgroundImage;
|
std::string mBackgroundImage;
|
||||||
|
/// true for has a background
|
||||||
bool bHasBG;
|
bool bHasBG;
|
||||||
|
/// true if PRJ file
|
||||||
/** true if PRJ file */
|
|
||||||
bool bIsPrj;
|
bool bIsPrj;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -49,8 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
struct aiMaterial;
|
struct aiMaterial;
|
||||||
struct aiMesh;
|
struct aiMesh;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp:: D3MF {
|
||||||
namespace D3MF {
|
|
||||||
|
|
||||||
enum class ResourceType {
|
enum class ResourceType {
|
||||||
RT_Object,
|
RT_Object,
|
||||||
@@ -65,8 +64,7 @@ class Resource {
|
|||||||
public:
|
public:
|
||||||
int mId;
|
int mId;
|
||||||
|
|
||||||
Resource(int id) :
|
explicit Resource(int id) : mId(id) {
|
||||||
mId(id) {
|
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +75,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class EmbeddedTexture : public Resource {
|
class EmbeddedTexture final : public Resource {
|
||||||
public:
|
public:
|
||||||
std::string mPath;
|
std::string mPath;
|
||||||
std::string mContentType;
|
std::string mContentType;
|
||||||
@@ -85,12 +83,7 @@ public:
|
|||||||
std::string mTilestyleV;
|
std::string mTilestyleV;
|
||||||
std::vector<char> mBuffer;
|
std::vector<char> mBuffer;
|
||||||
|
|
||||||
EmbeddedTexture(int id) :
|
explicit EmbeddedTexture(int id) : Resource(id) {
|
||||||
Resource(id),
|
|
||||||
mPath(),
|
|
||||||
mContentType(),
|
|
||||||
mTilestyleU(),
|
|
||||||
mTilestyleV() {
|
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,13 +94,12 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Texture2DGroup : public Resource {
|
class Texture2DGroup final : public Resource {
|
||||||
public:
|
public:
|
||||||
std::vector<aiVector2D> mTex2dCoords;
|
std::vector<aiVector2D> mTex2dCoords;
|
||||||
int mTexId;
|
int mTexId;
|
||||||
Texture2DGroup(int id) :
|
|
||||||
Resource(id),
|
explicit Texture2DGroup(int id) : Resource(id), mTexId(-1) {
|
||||||
mTexId(-1) {
|
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,11 +110,11 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ColorGroup : public Resource {
|
class ColorGroup final : public Resource {
|
||||||
public:
|
public:
|
||||||
std::vector<aiColor4D> mColors;
|
std::vector<aiColor4D> mColors;
|
||||||
ColorGroup(int id) :
|
|
||||||
Resource(id){
|
explicit ColorGroup(int id) : Resource(id) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,13 +125,11 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class BaseMaterials : public Resource {
|
class BaseMaterials final : public Resource {
|
||||||
public:
|
public:
|
||||||
std::vector<unsigned int> mMaterialIndex;
|
std::vector<unsigned int> mMaterialIndex;
|
||||||
|
|
||||||
BaseMaterials(int id) :
|
explicit BaseMaterials(int id) : Resource(id) {
|
||||||
Resource(id),
|
|
||||||
mMaterialIndex() {
|
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,14 +145,14 @@ struct Component {
|
|||||||
aiMatrix4x4 mTransformation;
|
aiMatrix4x4 mTransformation;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Object : public Resource {
|
class Object final : public Resource {
|
||||||
public:
|
public:
|
||||||
std::vector<aiMesh *> mMeshes;
|
std::vector<aiMesh *> mMeshes;
|
||||||
std::vector<unsigned int> mMeshIndex;
|
std::vector<unsigned int> mMeshIndex;
|
||||||
std::vector<Component> mComponents;
|
std::vector<Component> mComponents;
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
|
||||||
Object(int id) :
|
explicit Object(int id) :
|
||||||
Resource(id),
|
Resource(id),
|
||||||
mName(std::string("Object_") + ai_to_string(id)) {
|
mName(std::string("Object_") + ai_to_string(id)) {
|
||||||
// empty
|
// empty
|
||||||
@@ -175,5 +165,4 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace D3MF
|
} // namespace Assimp::D3MF
|
||||||
} // namespace Assimp
|
|
||||||
|
|||||||
@@ -40,85 +40,80 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp::D3MF::XmlTag {
|
||||||
namespace D3MF {
|
|
||||||
|
|
||||||
namespace XmlTag {
|
|
||||||
// Root tag
|
// Root tag
|
||||||
const char* const RootTag = "3MF";
|
constexpr char RootTag[] = "3MF";
|
||||||
|
|
||||||
// Meta-data
|
// Meta-data
|
||||||
const char* const meta = "metadata";
|
constexpr char meta[] = "metadata";
|
||||||
const char* const meta_name = "name";
|
constexpr char meta_name[] = "name";
|
||||||
|
|
||||||
// Model-data specific tags
|
// Model-data specific tags
|
||||||
const char* const model = "model";
|
constexpr char model[] = "model";
|
||||||
const char* const model_unit = "unit";
|
constexpr char model_unit[] = "unit";
|
||||||
const char* const metadata = "metadata";
|
constexpr char metadata[] = "metadata";
|
||||||
const char* const resources = "resources";
|
constexpr char resources[] = "resources";
|
||||||
const char* const object = "object";
|
constexpr char object[] = "object";
|
||||||
const char* const mesh = "mesh";
|
constexpr char mesh[] = "mesh";
|
||||||
const char* const components = "components";
|
constexpr char components[] = "components";
|
||||||
const char* const component = "component";
|
constexpr char component[] = "component";
|
||||||
const char* const vertices = "vertices";
|
constexpr char vertices[] = "vertices";
|
||||||
const char* const vertex = "vertex";
|
constexpr char vertex[] = "vertex";
|
||||||
const char* const triangles = "triangles";
|
constexpr char triangles[] = "triangles";
|
||||||
const char* const triangle = "triangle";
|
constexpr char triangle[] = "triangle";
|
||||||
const char* const x = "x";
|
constexpr char x[] = "x";
|
||||||
const char* const y = "y";
|
constexpr char y[] = "y";
|
||||||
const char* const z = "z";
|
constexpr char z[] = "z";
|
||||||
const char* const v1 = "v1";
|
constexpr char v1[] = "v1";
|
||||||
const char* const v2 = "v2";
|
constexpr char v2[] = "v2";
|
||||||
const char* const v3 = "v3";
|
constexpr char v3[] = "v3";
|
||||||
const char* const id = "id";
|
constexpr char id[] = "id";
|
||||||
const char* const pid = "pid";
|
constexpr char pid[] = "pid";
|
||||||
const char* const pindex = "pindex";
|
constexpr char pindex[] = "pindex";
|
||||||
const char* const p1 = "p1";
|
constexpr char p1[] = "p1";
|
||||||
const char *const p2 = "p2";
|
constexpr char p2[] = "p2";
|
||||||
const char *const p3 = "p3";
|
constexpr char p3[] = "p3";
|
||||||
const char* const name = "name";
|
constexpr char name[] = "name";
|
||||||
const char* const type = "type";
|
constexpr char type[] = "type";
|
||||||
const char* const build = "build";
|
constexpr char build[] = "build";
|
||||||
const char* const item = "item";
|
constexpr char item[] = "item";
|
||||||
const char* const objectid = "objectid";
|
constexpr char objectid[] = "objectid";
|
||||||
const char* const transform = "transform";
|
constexpr char transform[] = "transform";
|
||||||
const char *const path = "path";
|
constexpr char path[] = "path";
|
||||||
|
|
||||||
// Material definitions
|
// Material definitions
|
||||||
const char* const basematerials = "basematerials";
|
constexpr char basematerials[] = "basematerials";
|
||||||
const char* const basematerials_base = "base";
|
constexpr char basematerials_base[] = "base";
|
||||||
const char* const basematerials_name = "name";
|
constexpr char basematerials_name[] = "name";
|
||||||
const char* const basematerials_displaycolor = "displaycolor";
|
constexpr char basematerials_displaycolor[] = "displaycolor";
|
||||||
const char* const texture_2d = "m:texture2d";
|
constexpr char texture_2d[] = "m:texture2d";
|
||||||
const char *const texture_group = "m:texture2dgroup";
|
constexpr char texture_group[] = "m:texture2dgroup";
|
||||||
const char *const texture_content_type = "contenttype";
|
constexpr char texture_content_type[] = "contenttype";
|
||||||
const char *const texture_tilestyleu = "tilestyleu";
|
constexpr char texture_tilestyleu[] = "tilestyleu";
|
||||||
const char *const texture_tilestylev = "tilestylev";
|
constexpr char texture_tilestylev[] = "tilestylev";
|
||||||
const char *const texture_2d_coord = "m:tex2coord";
|
constexpr char texture_2d_coord[] = "m:tex2coord";
|
||||||
const char *const texture_cuurd_u = "u";
|
constexpr char texture_cuurd_u[] = "u";
|
||||||
const char *const texture_cuurd_v = "v";
|
constexpr char texture_cuurd_v[] = "v";
|
||||||
|
|
||||||
// vertex color definitions
|
// vertex color definitions
|
||||||
const char *const colorgroup = "m:colorgroup";
|
constexpr char colorgroup[] = "m:colorgroup";
|
||||||
const char *const color_item = "m:color";
|
constexpr char color_item[] = "m:color";
|
||||||
const char *const color_vaule = "color";
|
constexpr char color_value[] = "color";
|
||||||
|
|
||||||
// Meta info tags
|
// Meta info tags
|
||||||
const char* const CONTENT_TYPES_ARCHIVE = "[Content_Types].xml";
|
constexpr char CONTENT_TYPES_ARCHIVE[] = "[Content_Types].xml";
|
||||||
const char* const ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels";
|
constexpr char ROOT_RELATIONSHIPS_ARCHIVE[] = "_rels/.rels";
|
||||||
const char* const SCHEMA_CONTENTTYPES = "http://schemas.openxmlformats.org/package/2006/content-types";
|
constexpr char SCHEMA_CONTENTTYPES[] = "http://schemas.openxmlformats.org/package/2006/content-types";
|
||||||
const char* const SCHEMA_RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships";
|
constexpr char SCHEMA_RELATIONSHIPS[] = "http://schemas.openxmlformats.org/package/2006/relationships";
|
||||||
const char* const RELS_RELATIONSHIP_CONTAINER = "Relationships";
|
constexpr char RELS_RELATIONSHIP_CONTAINER[] = "Relationships";
|
||||||
const char* const RELS_RELATIONSHIP_NODE = "Relationship";
|
constexpr char RELS_RELATIONSHIP_NODE[] = "Relationship";
|
||||||
const char* const RELS_ATTRIB_TARGET = "Target";
|
constexpr char RELS_ATTRIB_TARGET[] = "Target";
|
||||||
const char* const RELS_ATTRIB_TYPE = "Type";
|
constexpr char RELS_ATTRIB_TYPE[] = "Type";
|
||||||
const char* const RELS_ATTRIB_ID = "Id";
|
constexpr char RELS_ATTRIB_ID[] = "Id";
|
||||||
const char* const PACKAGE_START_PART_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel";
|
constexpr char PACKAGE_START_PART_RELATIONSHIP_TYPE[] = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel";
|
||||||
const char* const PACKAGE_PRINT_TICKET_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/printticket";
|
constexpr char PACKAGE_PRINT_TICKET_RELATIONSHIP_TYPE[] = "http://schemas.microsoft.com/3dmanufacturing/2013/01/printticket";
|
||||||
const char* const PACKAGE_TEXTURE_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture";
|
constexpr char PACKAGE_TEXTURE_RELATIONSHIP_TYPE[] = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture";
|
||||||
const char* const PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
|
constexpr char PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE[] = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
|
||||||
const char* const PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
|
constexpr char PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE[] = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
|
||||||
}
|
|
||||||
|
|
||||||
} // Namespace D3MF
|
} // namespace Assimp::D3MF
|
||||||
} // Namespace Assimp
|
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/Exporter.hpp>
|
#include <assimp/Exporter.hpp>
|
||||||
#include <assimp/IOStream.hpp>
|
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
|
|
||||||
#include "3MFXmlTags.h"
|
#include "3MFXmlTags.h"
|
||||||
@@ -94,7 +93,7 @@ D3MFExporter::~D3MFExporter() {
|
|||||||
mRelations.clear();
|
mRelations.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3MFExporter::validate() {
|
bool D3MFExporter::validate() const {
|
||||||
if (mArchiveName.empty()) {
|
if (mArchiveName.empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class D3MFExporter {
|
|||||||
public:
|
public:
|
||||||
D3MFExporter( const char* pFile, const aiScene* pScene );
|
D3MFExporter( const char* pFile, const aiScene* pScene );
|
||||||
~D3MFExporter();
|
~D3MFExporter();
|
||||||
bool validate();
|
bool validate() const;
|
||||||
bool exportArchive( const char *file );
|
bool exportArchive( const char *file );
|
||||||
bool exportContentTypes();
|
bool exportContentTypes();
|
||||||
bool exportRelations();
|
bool exportRelations();
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ namespace Assimp {
|
|||||||
///
|
///
|
||||||
/// Implements the basic topology import and embedded textures.
|
/// Implements the basic topology import and embedded textures.
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
class D3MFImporter : public BaseImporter {
|
class D3MFImporter final : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
/// @brief The default class constructor.
|
/// @brief The default class constructor.
|
||||||
D3MFImporter() = default;
|
D3MFImporter() = default;
|
||||||
|
|||||||
@@ -65,10 +65,9 @@ namespace D3MF {
|
|||||||
|
|
||||||
using OpcPackageRelationshipPtr = std::shared_ptr<OpcPackageRelationship>;
|
using OpcPackageRelationshipPtr = std::shared_ptr<OpcPackageRelationship>;
|
||||||
|
|
||||||
class OpcPackageRelationshipReader {
|
class OpcPackageRelationshipReader final {
|
||||||
public:
|
public:
|
||||||
OpcPackageRelationshipReader(XmlParser &parser) :
|
explicit OpcPackageRelationshipReader(XmlParser &parser) : mRelations() {
|
||||||
mRelations() {
|
|
||||||
XmlNode root = parser.getRootNode();
|
XmlNode root = parser.getRootNode();
|
||||||
ParseRootNode(root);
|
ParseRootNode(root);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -680,7 +680,7 @@ void XmlSerializer::ReadColor(XmlNode &node, ColorGroup *colorGroup) {
|
|||||||
for (XmlNode currentNode : node.children()) {
|
for (XmlNode currentNode : node.children()) {
|
||||||
const std::string currentName = currentNode.name();
|
const std::string currentName = currentNode.name();
|
||||||
if (currentName == XmlTag::color_item) {
|
if (currentName == XmlTag::color_item) {
|
||||||
const char *color = currentNode.attribute(XmlTag::color_vaule).as_string();
|
const char *color = currentNode.attribute(XmlTag::color_value).as_string();
|
||||||
aiColor4D color_value;
|
aiColor4D color_value;
|
||||||
if (parseColor(color, color_value)) {
|
if (parseColor(color, color_value)) {
|
||||||
colorGroup->mColors.push_back(color_value);
|
colorGroup->mColors.push_back(color_value);
|
||||||
|
|||||||
@@ -59,9 +59,10 @@ class Texture2DGroup;
|
|||||||
class EmbeddedTexture;
|
class EmbeddedTexture;
|
||||||
class ColorGroup;
|
class ColorGroup;
|
||||||
|
|
||||||
|
/// @brief his class implements ther 3mf serialization.
|
||||||
class XmlSerializer final {
|
class XmlSerializer final {
|
||||||
public:
|
public:
|
||||||
XmlSerializer(XmlParser &xmlParser);
|
explicit XmlSerializer(XmlParser &xmlParser);
|
||||||
~XmlSerializer();
|
~XmlSerializer();
|
||||||
void ImportXml(aiScene *scene);
|
void ImportXml(aiScene *scene);
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ static constexpr aiImporterDesc desc = {
|
|||||||
"ac acc ac3d"
|
"ac acc ac3d"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static constexpr auto ACDoubleSidedFlag = 0x20;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// skip to the next token
|
// skip to the next token
|
||||||
inline const char *AcSkipToNextToken(const char *buffer, const char *end) {
|
inline const char *AcSkipToNextToken(const char *buffer, const char *end) {
|
||||||
@@ -123,12 +125,36 @@ inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *end,
|
|||||||
}
|
}
|
||||||
for (unsigned int _i = 0; _i < num; ++_i) {
|
for (unsigned int _i = 0; _i < num; ++_i) {
|
||||||
buffer = AcSkipToNextToken(buffer, end);
|
buffer = AcSkipToNextToken(buffer, end);
|
||||||
buffer = fast_atoreal_move<float>(buffer, ((float *)out)[_i]);
|
buffer = fast_atoreal_move(buffer, ((float *)out)[_i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Reverses vertex indices in a face.
|
||||||
|
static void flipWindingOrder(aiFace &f) {
|
||||||
|
std::reverse(f.mIndices, f.mIndices + f.mNumIndices);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Duplicates a face and inverts it. Also duplicates all vertices (so the new face gets its own
|
||||||
|
// set of normals and isn’t smoothed against the original).
|
||||||
|
static void buildBacksideOfFace(const aiFace &origFace, aiFace *&outFaces, aiVector3D *&outVertices, const aiVector3D *allVertices,
|
||||||
|
aiVector3D *&outUV, const aiVector3D *allUV, unsigned &curIdx) {
|
||||||
|
auto &newFace = *outFaces++;
|
||||||
|
newFace = origFace;
|
||||||
|
flipWindingOrder(newFace);
|
||||||
|
for (unsigned f = 0; f < newFace.mNumIndices; ++f) {
|
||||||
|
*outVertices++ = allVertices[newFace.mIndices[f]];
|
||||||
|
if (outUV) {
|
||||||
|
*outUV = allUV[newFace.mIndices[f]];
|
||||||
|
outUV++;
|
||||||
|
}
|
||||||
|
newFace.mIndices[f] = curIdx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
AC3DImporter::AC3DImporter() :
|
AC3DImporter::AC3DImporter() :
|
||||||
@@ -451,6 +477,8 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
|
|||||||
if ((*it).entries.empty()) {
|
if ((*it).entries.empty()) {
|
||||||
ASSIMP_LOG_WARN("AC3D: surface has zero vertex references");
|
ASSIMP_LOG_WARN("AC3D: surface has zero vertex references");
|
||||||
}
|
}
|
||||||
|
const bool isDoubleSided = ACDoubleSidedFlag == (it->flags & ACDoubleSidedFlag);
|
||||||
|
const int doubleSidedFactor = isDoubleSided ? 2 : 1;
|
||||||
|
|
||||||
// validate all vertex indices to make sure we won't crash here
|
// validate all vertex indices to make sure we won't crash here
|
||||||
for (it2 = (*it).entries.begin(),
|
for (it2 = (*it).entries.begin(),
|
||||||
@@ -480,8 +508,8 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
|
|||||||
|
|
||||||
// triangle strip
|
// triangle strip
|
||||||
case Surface::TriangleStrip:
|
case Surface::TriangleStrip:
|
||||||
needMat[idx].first += (unsigned int)(*it).entries.size() - 2;
|
needMat[idx].first += static_cast<unsigned int>(it->entries.size() - 2) * doubleSidedFactor;
|
||||||
needMat[idx].second += ((unsigned int)(*it).entries.size() - 2) * 3;
|
needMat[idx].second += static_cast<unsigned int>(it->entries.size() - 2) * 3 * doubleSidedFactor;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -494,8 +522,8 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
|
|||||||
case Surface::Polygon:
|
case Surface::Polygon:
|
||||||
// the number of faces increments by one, the number
|
// the number of faces increments by one, the number
|
||||||
// of vertices by surface.numref.
|
// of vertices by surface.numref.
|
||||||
needMat[idx].first++;
|
needMat[idx].first += doubleSidedFactor;
|
||||||
needMat[idx].second += (unsigned int)(*it).entries.size();
|
needMat[idx].second += static_cast<unsigned int>(it->entries.size()) * doubleSidedFactor;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
unsigned int *pip = node->mMeshes = new unsigned int[node->mNumMeshes];
|
unsigned int *pip = node->mMeshes = new unsigned int[node->mNumMeshes];
|
||||||
@@ -545,6 +573,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
|
|||||||
for (it = object.surfaces.begin(); it != end; ++it) {
|
for (it = object.surfaces.begin(); it != end; ++it) {
|
||||||
if (mat == (*it).mat) {
|
if (mat == (*it).mat) {
|
||||||
const Surface &src = *it;
|
const Surface &src = *it;
|
||||||
|
const bool isDoubleSided = ACDoubleSidedFlag == (src.flags & ACDoubleSidedFlag);
|
||||||
|
|
||||||
// closed polygon
|
// closed polygon
|
||||||
uint8_t type = (*it).GetType();
|
uint8_t type = (*it).GetType();
|
||||||
@@ -570,6 +599,8 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
|
|||||||
++uv;
|
++uv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(isDoubleSided) // Need a backface?
|
||||||
|
buildBacksideOfFace(faces[-1], faces, vertices, mesh->mVertices, uv, mesh->mTextureCoords[0], cur);
|
||||||
}
|
}
|
||||||
} else if (type == Surface::TriangleStrip) {
|
} else if (type == Surface::TriangleStrip) {
|
||||||
for (unsigned int i = 0; i < (unsigned int)src.entries.size() - 2; ++i) {
|
for (unsigned int i = 0; i < (unsigned int)src.entries.size() - 2; ++i) {
|
||||||
@@ -619,6 +650,8 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
|
|||||||
uv->y = entry3.second.y;
|
uv->y = entry3.second.y;
|
||||||
++uv;
|
++uv;
|
||||||
}
|
}
|
||||||
|
if(isDoubleSided) // Need a backface?
|
||||||
|
buildBacksideOfFace(faces[-1], faces, vertices, mesh->mVertices, uv, mesh->mTextureCoords[0], cur);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace Assimp {
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** AC3D (*.ac) importer class
|
/** AC3D (*.ac) importer class
|
||||||
*/
|
*/
|
||||||
class AC3DImporter : public BaseImporter {
|
class AC3DImporter final : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
AC3DImporter();
|
AC3DImporter();
|
||||||
~AC3DImporter() override = default;
|
~AC3DImporter() override = default;
|
||||||
|
|||||||
@@ -327,8 +327,7 @@ void AMFImporter::ParseNode_Root() {
|
|||||||
// Multi elements - Yes.
|
// Multi elements - Yes.
|
||||||
// Parent element - <amf>.
|
// Parent element - <amf>.
|
||||||
void AMFImporter::ParseNode_Constellation(XmlNode &node) {
|
void AMFImporter::ParseNode_Constellation(XmlNode &node) {
|
||||||
std::string id;
|
std::string id = node.attribute("id").as_string();
|
||||||
id = node.attribute("id").as_string();
|
|
||||||
|
|
||||||
// create and if needed - define new grouping object.
|
// create and if needed - define new grouping object.
|
||||||
AMFNodeElementBase *ne = new AMFConstellation(mNodeElement_Cur);
|
AMFNodeElementBase *ne = new AMFConstellation(mNodeElement_Cur);
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ namespace Assimp {
|
|||||||
/// new - <texmap> and children <utex1>, <utex2>, <utex3>, <vtex1>, <vtex2>, <vtex3>
|
/// new - <texmap> and children <utex1>, <utex2>, <utex3>, <vtex1>, <vtex2>, <vtex3>
|
||||||
/// old - <map> and children <u1>, <u2>, <u3>, <v1>, <v2>, <v3>
|
/// old - <map> and children <u1>, <u2>, <u3>, <v1>, <v2>, <v3>
|
||||||
///
|
///
|
||||||
class AMFImporter : public BaseImporter {
|
class AMFImporter final : public BaseImporter {
|
||||||
using AMFMetaDataArray = std::vector<AMFMetadata *>;
|
using AMFMetaDataArray = std::vector<AMFMetadata *>;
|
||||||
using MeshArray = std::vector<aiMesh *>;
|
using MeshArray = std::vector<aiMesh *>;
|
||||||
using NodeArray = std::vector<aiNode *>;
|
using NodeArray = std::vector<aiNode *>;
|
||||||
|
|||||||
@@ -107,16 +107,16 @@ protected:
|
|||||||
}; // class IAMFImporter_NodeElement
|
}; // class IAMFImporter_NodeElement
|
||||||
|
|
||||||
/// A collection of objects or constellations with specific relative locations.
|
/// A collection of objects or constellations with specific relative locations.
|
||||||
struct AMFConstellation : public AMFNodeElementBase {
|
struct AMFConstellation final : public AMFNodeElementBase {
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
AMFConstellation(AMFNodeElementBase *pParent) :
|
explicit AMFConstellation(AMFNodeElementBase *pParent) :
|
||||||
AMFNodeElementBase(ENET_Constellation, pParent) {}
|
AMFNodeElementBase(ENET_Constellation, pParent) {}
|
||||||
|
|
||||||
}; // struct CAMFImporter_NodeElement_Constellation
|
}; // struct CAMFImporter_NodeElement_Constellation
|
||||||
|
|
||||||
/// Part of constellation.
|
/// Part of constellation.
|
||||||
struct AMFInstance : public AMFNodeElementBase {
|
struct AMFInstance final : public AMFNodeElementBase {
|
||||||
|
|
||||||
std::string ObjectID; ///< ID of object for instantiation.
|
std::string ObjectID; ///< ID of object for instantiation.
|
||||||
/// \var Delta - The distance of translation in the x, y, or z direction, respectively, in the referenced object's coordinate system, to
|
/// \var Delta - The distance of translation in the x, y, or z direction, respectively, in the referenced object's coordinate system, to
|
||||||
@@ -129,7 +129,7 @@ struct AMFInstance : public AMFNodeElementBase {
|
|||||||
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
AMFInstance(AMFNodeElementBase *pParent) :
|
explicit AMFInstance(AMFNodeElementBase *pParent) :
|
||||||
AMFNodeElementBase(ENET_Instance, pParent) {}
|
AMFNodeElementBase(ENET_Instance, pParent) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -141,8 +141,10 @@ struct AMFMetadata : public AMFNodeElementBase {
|
|||||||
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
AMFMetadata(AMFNodeElementBase *pParent) :
|
explicit AMFMetadata(AMFNodeElementBase *pParent) :
|
||||||
AMFNodeElementBase(ENET_Metadata, pParent) {}
|
AMFNodeElementBase(ENET_Metadata, pParent) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Structure that define root node.
|
/// Structure that define root node.
|
||||||
@@ -153,8 +155,10 @@ struct AMFRoot : public AMFNodeElementBase {
|
|||||||
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
AMFRoot(AMFNodeElementBase *pParent) :
|
explicit AMFRoot(AMFNodeElementBase *pParent) :
|
||||||
AMFNodeElementBase(ENET_Root, pParent) {}
|
AMFNodeElementBase(ENET_Root, pParent) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Structure that define object node.
|
/// Structure that define object node.
|
||||||
@@ -166,7 +170,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) :
|
explicit AMFColor(AMFNodeElementBase *pParent) :
|
||||||
AMFNodeElementBase(ENET_Color, pParent), Composed(false), Color() {
|
AMFNodeElementBase(ENET_Color, pParent), Composed(false), Color() {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
@@ -174,53 +178,62 @@ struct AMFColor : public AMFNodeElementBase {
|
|||||||
|
|
||||||
/// Structure that define material node.
|
/// Structure that define material node.
|
||||||
struct AMFMaterial : public AMFNodeElementBase {
|
struct AMFMaterial : public AMFNodeElementBase {
|
||||||
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
AMFMaterial(AMFNodeElementBase *pParent) :
|
explicit AMFMaterial(AMFNodeElementBase *pParent) :
|
||||||
AMFNodeElementBase(ENET_Material, pParent) {}
|
AMFNodeElementBase(ENET_Material, pParent) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Structure that define object node.
|
/// Structure that define object node.
|
||||||
struct AMFObject : public AMFNodeElementBase {
|
struct AMFObject : public AMFNodeElementBase {
|
||||||
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
AMFObject(AMFNodeElementBase *pParent) :
|
explicit AMFObject(AMFNodeElementBase *pParent) :
|
||||||
AMFNodeElementBase(ENET_Object, pParent) {}
|
AMFNodeElementBase(ENET_Object, pParent) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \struct CAMFImporter_NodeElement_Mesh
|
|
||||||
/// Structure that define mesh node.
|
/// Structure that define mesh node.
|
||||||
struct AMFMesh : public AMFNodeElementBase {
|
struct AMFMesh : public AMFNodeElementBase {
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
AMFMesh(AMFNodeElementBase *pParent) :
|
explicit AMFMesh(AMFNodeElementBase *pParent) :
|
||||||
AMFNodeElementBase(ENET_Mesh, pParent) {}
|
AMFNodeElementBase(ENET_Mesh, pParent) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Structure that define vertex node.
|
/// Structure that define vertex node.
|
||||||
struct AMFVertex : public AMFNodeElementBase {
|
struct AMFVertex : public AMFNodeElementBase {
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
AMFVertex(AMFNodeElementBase *pParent) :
|
explicit AMFVertex(AMFNodeElementBase *pParent) :
|
||||||
AMFNodeElementBase(ENET_Vertex, pParent) {}
|
AMFNodeElementBase(ENET_Vertex, pParent) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Structure that define edge node.
|
/// Structure that define edge node.
|
||||||
struct AMFEdge : public AMFNodeElementBase {
|
struct AMFEdge : public AMFNodeElementBase {
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
AMFEdge(AMFNodeElementBase *pParent) :
|
explicit AMFEdge(AMFNodeElementBase *pParent) :
|
||||||
AMFNodeElementBase(ENET_Edge, pParent) {}
|
AMFNodeElementBase(ENET_Edge, pParent) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Structure that define vertices node.
|
/// Structure that define vertices node.
|
||||||
struct AMFVertices : public AMFNodeElementBase {
|
struct AMFVertices : public AMFNodeElementBase {
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
AMFVertices(AMFNodeElementBase *pParent) :
|
explicit AMFVertices(AMFNodeElementBase *pParent) :
|
||||||
AMFNodeElementBase(ENET_Vertices, pParent) {}
|
AMFNodeElementBase(ENET_Vertices, pParent) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Structure that define volume node.
|
/// Structure that define volume node.
|
||||||
@@ -230,8 +243,10 @@ struct AMFVolume : public AMFNodeElementBase {
|
|||||||
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
AMFVolume(AMFNodeElementBase *pParent) :
|
explicit AMFVolume(AMFNodeElementBase *pParent) :
|
||||||
AMFNodeElementBase(ENET_Volume, pParent) {}
|
AMFNodeElementBase(ENET_Volume, pParent) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Structure that define coordinates node.
|
/// Structure that define coordinates node.
|
||||||
@@ -240,8 +255,10 @@ struct AMFCoordinates : public AMFNodeElementBase {
|
|||||||
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
AMFCoordinates(AMFNodeElementBase *pParent) :
|
explicit AMFCoordinates(AMFNodeElementBase *pParent) :
|
||||||
AMFNodeElementBase(ENET_Coordinates, pParent) {}
|
AMFNodeElementBase(ENET_Coordinates, pParent) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Structure that define texture coordinates node.
|
/// Structure that define texture coordinates node.
|
||||||
@@ -254,7 +271,7 @@ struct AMFTexMap : public AMFNodeElementBase {
|
|||||||
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
AMFTexMap(AMFNodeElementBase *pParent) :
|
explicit AMFTexMap(AMFNodeElementBase *pParent) :
|
||||||
AMFNodeElementBase(ENET_TexMap, pParent), TextureCoordinate{} {
|
AMFNodeElementBase(ENET_TexMap, pParent), TextureCoordinate{} {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
@@ -266,7 +283,7 @@ struct AMFTriangle : public AMFNodeElementBase {
|
|||||||
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
AMFTriangle(AMFNodeElementBase *pParent) :
|
explicit AMFTriangle(AMFNodeElementBase *pParent) :
|
||||||
AMFNodeElementBase(ENET_Triangle, pParent) {
|
AMFNodeElementBase(ENET_Triangle, pParent) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
@@ -280,7 +297,7 @@ struct AMFTexture : public AMFNodeElementBase {
|
|||||||
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// \param [in] pParent - pointer to parent node.
|
/// \param [in] pParent - pointer to parent node.
|
||||||
AMFTexture(AMFNodeElementBase *pParent) :
|
explicit AMFTexture(AMFNodeElementBase *pParent) :
|
||||||
AMFNodeElementBase(ENET_Texture, pParent), Width(0), Height(0), Depth(0), Data(), Tiled(false) {
|
AMFNodeElementBase(ENET_Texture, pParent), Width(0), Height(0), Depth(0), Data(), Tiled(false) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,8 +57,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*pY*/, const float /*pZ*/) const {
|
aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*pY*/, const float /*pZ*/) const {
|
||||||
aiColor4D tcol;
|
|
||||||
|
|
||||||
// Check if stored data are supported.
|
// Check if stored data are supported.
|
||||||
if (!Composition.empty()) {
|
if (!Composition.empty()) {
|
||||||
throw DeadlyImportError("IME. GetColor for composition");
|
throw DeadlyImportError("IME. GetColor for composition");
|
||||||
@@ -68,7 +66,7 @@ aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*
|
|||||||
throw DeadlyImportError("IME. GetColor, composed color");
|
throw DeadlyImportError("IME. GetColor, composed color");
|
||||||
}
|
}
|
||||||
|
|
||||||
tcol = Color->Color;
|
aiColor4D tcol = Color->Color;
|
||||||
|
|
||||||
// Check if default color must be used
|
// Check if default color must be used
|
||||||
if ((tcol.r == 0) && (tcol.g == 0) && (tcol.b == 0) && (tcol.a == 0)) {
|
if ((tcol.r == 0) && (tcol.g == 0) && (tcol.b == 0) && (tcol.a == 0)) {
|
||||||
@@ -532,11 +530,9 @@ void AMFImporter::Postprocess_BuildMeshSet(const AMFMesh &pNodeElement, const st
|
|||||||
col_arr.reserve(VertexCount_Max * 2);
|
col_arr.reserve(VertexCount_Max * 2);
|
||||||
|
|
||||||
{ // fill arrays
|
{ // fill arrays
|
||||||
size_t vert_idx_from, vert_idx_to;
|
|
||||||
|
|
||||||
// first iteration.
|
// first iteration.
|
||||||
vert_idx_to = 0;
|
size_t vert_idx_to = 0;
|
||||||
vert_idx_from = VertexIndex_GetMinimal(face_list_cur, nullptr);
|
size_t vert_idx_from = VertexIndex_GetMinimal(face_list_cur, nullptr);
|
||||||
vert_arr.push_back(pVertexCoordinateArray.at(vert_idx_from));
|
vert_arr.push_back(pVertexCoordinateArray.at(vert_idx_from));
|
||||||
col_arr.push_back(Vertex_CalculateColor(vert_idx_from));
|
col_arr.push_back(Vertex_CalculateColor(vert_idx_from));
|
||||||
if (vert_idx_from != vert_idx_to) VertexIndex_Replace(face_list_cur, vert_idx_from, vert_idx_to);
|
if (vert_idx_from != vert_idx_to) VertexIndex_Replace(face_list_cur, vert_idx_from, vert_idx_to);
|
||||||
|
|||||||
@@ -1270,5 +1270,4 @@ bool ASEImporter::GenerateNormals(ASE::Mesh &mesh) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif // ASSIMP_BUILD_NO_3DS_IMPORTER
|
#endif // ASSIMP_BUILD_NO_3DS_IMPORTER
|
||||||
|
#endif // ASSIMP_BUILD_NO_ASE_IMPORTER
|
||||||
#endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ namespace Assimp {
|
|||||||
/** Importer class for the 3DS ASE ASCII format.
|
/** Importer class for the 3DS ASE ASCII format.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ASEImporter : public BaseImporter {
|
class ASEImporter final : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
ASEImporter();
|
ASEImporter();
|
||||||
~ASEImporter() override = default;
|
~ASEImporter() override = default;
|
||||||
|
|||||||
@@ -1427,7 +1427,7 @@ void Parser::ParseLV4MeshBonesVertices(unsigned int iNumVertices, ASE::Mesh &mes
|
|||||||
|
|
||||||
// then parse the vertex weight
|
// then parse the vertex weight
|
||||||
if (!SkipSpaces(&mFilePtr, mEnd)) break;
|
if (!SkipSpaces(&mFilePtr, mEnd)) break;
|
||||||
mFilePtr = fast_atoreal_move<float>(mFilePtr, pairOut.second);
|
mFilePtr = fast_atoreal_move(mFilePtr, pairOut.second);
|
||||||
|
|
||||||
// -1 marks unused entries
|
// -1 marks unused entries
|
||||||
if (-1 != pairOut.first) {
|
if (-1 != pairOut.first) {
|
||||||
@@ -1893,7 +1893,7 @@ void Parser::ParseLV4MeshReal(ai_real &fOut) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// parse the first float
|
// parse the first float
|
||||||
mFilePtr = fast_atoreal_move<ai_real>(mFilePtr, fOut);
|
mFilePtr = fast_atoreal_move(mFilePtr, fOut);
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV4MeshFloat(float &fOut) {
|
void Parser::ParseLV4MeshFloat(float &fOut) {
|
||||||
@@ -1906,7 +1906,7 @@ void Parser::ParseLV4MeshFloat(float &fOut) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// parse the first float
|
// parse the first float
|
||||||
mFilePtr = fast_atoreal_move<float>(mFilePtr, fOut);
|
mFilePtr = fast_atoreal_move(mFilePtr, fOut);
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV4MeshLong(unsigned int &iOut) {
|
void Parser::ParseLV4MeshLong(unsigned int &iOut) {
|
||||||
|
|||||||
@@ -57,14 +57,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
// ASE is quite similar to 3ds. We can reuse some structures
|
// ASE is quite similar to 3ds. We can reuse some structures
|
||||||
#include "AssetLib/3DS/3DSLoader.h"
|
#include "AssetLib/3DS/3DSLoader.h"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp::ASE {
|
||||||
namespace ASE {
|
|
||||||
|
|
||||||
using namespace D3DS;
|
using namespace D3DS;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Helper structure representing an ASE material */
|
/** Helper structure representing an ASE material */
|
||||||
struct Material : public D3DS::Material {
|
struct Material final : D3DS::Material {
|
||||||
//! Default constructor has been deleted
|
//! Default constructor has been deleted
|
||||||
Material() = delete;
|
Material() = delete;
|
||||||
|
|
||||||
@@ -115,7 +114,7 @@ struct Material : public D3DS::Material {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Material() = default;
|
~Material() override = default;
|
||||||
|
|
||||||
//! Contains all sub materials of this material
|
//! Contains all sub materials of this material
|
||||||
std::vector<Material> avSubMaterials;
|
std::vector<Material> avSubMaterials;
|
||||||
@@ -373,8 +372,8 @@ struct Dummy : public BaseNode {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Parameters to Parser::Parse()
|
// Parameters to Parser::Parse()
|
||||||
#define AI_ASE_NEW_FILE_FORMAT 200
|
static constexpr unsigned int AI_ASE_NEW_FILE_FORMAT = 200;
|
||||||
#define AI_ASE_OLD_FILE_FORMAT 110
|
static constexpr unsigned int AI_ASE_OLD_FILE_FORMAT = 110;
|
||||||
|
|
||||||
// Internally we're a little bit more tolerant
|
// Internally we're a little bit more tolerant
|
||||||
#define AI_ASE_IS_NEW_FILE_FORMAT() (iFileFormat >= 200)
|
#define AI_ASE_IS_NEW_FILE_FORMAT() (iFileFormat >= 200)
|
||||||
@@ -668,8 +667,7 @@ public:
|
|||||||
unsigned int iFileFormat;
|
unsigned int iFileFormat;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Namespace ASE
|
} // Namespace Assimp::ASE
|
||||||
} // namespace Assimp
|
|
||||||
|
|
||||||
#endif // ASSIMP_BUILD_NO_3DS_IMPORTER
|
#endif // ASSIMP_BUILD_NO_3DS_IMPORTER
|
||||||
|
|
||||||
|
|||||||
@@ -239,29 +239,7 @@ inline size_t WriteArray(IOStream *stream, const T *in, unsigned int size) {
|
|||||||
* and the chunk contents to the container stream. This allows relatively easy chunk
|
* and the chunk contents to the container stream. This allows relatively easy chunk
|
||||||
* chunk construction, even recursively.
|
* chunk construction, even recursively.
|
||||||
*/
|
*/
|
||||||
class AssbinChunkWriter : public IOStream {
|
class AssbinChunkWriter final : public IOStream {
|
||||||
private:
|
|
||||||
uint8_t *buffer;
|
|
||||||
uint32_t magic;
|
|
||||||
IOStream *container;
|
|
||||||
size_t cur_size, cursor, initial;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
void Grow(size_t need = 0) {
|
|
||||||
size_t new_size = std::max(initial, std::max(need, cur_size + (cur_size >> 1)));
|
|
||||||
|
|
||||||
const uint8_t *const old = buffer;
|
|
||||||
buffer = new uint8_t[new_size];
|
|
||||||
|
|
||||||
if (old) {
|
|
||||||
memcpy(buffer, old, cur_size);
|
|
||||||
delete[] old;
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_size = new_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AssbinChunkWriter(IOStream *container, uint32_t magic, size_t initial = 4096) :
|
AssbinChunkWriter(IOStream *container, uint32_t magic, size_t initial = 4096) :
|
||||||
buffer(nullptr),
|
buffer(nullptr),
|
||||||
@@ -315,6 +293,28 @@ public:
|
|||||||
|
|
||||||
return pCount;
|
return pCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
void Grow(size_t need = 0) {
|
||||||
|
size_t new_size = std::max(initial, std::max(need, cur_size + (cur_size >> 1)));
|
||||||
|
|
||||||
|
const uint8_t *const old = buffer;
|
||||||
|
buffer = new uint8_t[new_size];
|
||||||
|
|
||||||
|
if (old) {
|
||||||
|
memcpy(buffer, old, cur_size);
|
||||||
|
delete[] old;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_size = new_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t *buffer;
|
||||||
|
uint32_t magic;
|
||||||
|
IOStream *container;
|
||||||
|
size_t cur_size, cursor, initial;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -77,8 +77,7 @@ static int ioprintf(IOStream *io, const char *format, ...) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const int Size = 4096;
|
static const int Size = 4096;
|
||||||
char sz[Size];
|
char sz[Size] = {};
|
||||||
::memset(sz, '\0', Size);
|
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start(va, format);
|
va_start(va, format);
|
||||||
const unsigned int nSize = vsnprintf(sz, Size - 1, format, va);
|
const unsigned int nSize = vsnprintf(sz, Size - 1, format, va);
|
||||||
@@ -302,7 +301,11 @@ static void WriteDump(const char *pFile, const char *cmd, const aiScene *scene,
|
|||||||
bool compressed = (tex->mHeight == 0);
|
bool compressed = (tex->mHeight == 0);
|
||||||
|
|
||||||
// mesh header
|
// mesh header
|
||||||
ioprintf(io, "\t<Texture width=\"%u\" height=\"%u\" compressed=\"%s\"> \n",
|
std::string texName = "unknown";
|
||||||
|
if (tex->mFilename.length != 0u) {
|
||||||
|
texName = tex->mFilename.data;
|
||||||
|
}
|
||||||
|
ioprintf(io, "\t<Texture name=\"%s\" width=\"%u\" height=\"%u\" compressed=\"%s\"> \n", texName.c_str(),
|
||||||
(compressed ? -1 : tex->mWidth), (compressed ? -1 : tex->mHeight),
|
(compressed ? -1 : tex->mWidth), (compressed ? -1 : tex->mHeight),
|
||||||
(compressed ? "true" : "false"));
|
(compressed ? "true" : "false"));
|
||||||
|
|
||||||
@@ -350,7 +353,7 @@ static void WriteDump(const char *pFile, const char *cmd, const aiScene *scene,
|
|||||||
for (unsigned int n = 0; n < mat->mNumProperties; ++n) {
|
for (unsigned int n = 0; n < mat->mNumProperties; ++n) {
|
||||||
|
|
||||||
const aiMaterialProperty *prop = mat->mProperties[n];
|
const aiMaterialProperty *prop = mat->mProperties[n];
|
||||||
const char *sz = "";
|
auto sz = "";
|
||||||
if (prop->mType == aiPTI_Float) {
|
if (prop->mType == aiPTI_Float) {
|
||||||
sz = "float";
|
sz = "float";
|
||||||
} else if (prop->mType == aiPTI_Integer) {
|
} else if (prop->mType == aiPTI_Integer) {
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ struct aiAnimation;
|
|||||||
|
|
||||||
namespace Assimp{
|
namespace Assimp{
|
||||||
|
|
||||||
class B3DImporter : public BaseImporter{
|
class B3DImporter final : public BaseImporter{
|
||||||
public:
|
public:
|
||||||
B3DImporter() = default;
|
B3DImporter() = default;
|
||||||
~B3DImporter() override;
|
~B3DImporter() override;
|
||||||
|
|||||||
@@ -385,7 +385,7 @@ float BVHLoader::GetNextTokenAsFloat() {
|
|||||||
// check if the float is valid by testing if the atof() function consumed every char of the token
|
// check if the float is valid by testing if the atof() function consumed every char of the token
|
||||||
const char *ctoken = token.c_str();
|
const char *ctoken = token.c_str();
|
||||||
float result = 0.0f;
|
float result = 0.0f;
|
||||||
ctoken = fast_atoreal_move<float>(ctoken, result);
|
ctoken = fast_atoreal_move(ctoken, result);
|
||||||
|
|
||||||
if (ctoken != token.c_str() + token.length())
|
if (ctoken != token.c_str() + token.length())
|
||||||
ThrowException("Expected a floating point number, but found \"", token, "\".");
|
ThrowException("Expected a floating point number, but found \"", token, "\".");
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ namespace Assimp {
|
|||||||
* the hierarchy. It contains no actual mesh data, but we generate a dummy mesh
|
* the hierarchy. It contains no actual mesh data, but we generate a dummy mesh
|
||||||
* inside the loader just to be able to see something.
|
* inside the loader just to be able to see something.
|
||||||
*/
|
*/
|
||||||
class BVHLoader : public BaseImporter {
|
class BVHLoader final : public BaseImporter {
|
||||||
|
|
||||||
/** Possible animation channels for which the motion data holds the values */
|
/** Possible animation channels for which the motion data holds the values */
|
||||||
enum ChannelType {
|
enum ChannelType {
|
||||||
|
|||||||
@@ -74,7 +74,9 @@ BlenderBMeshConverter::~BlenderBMeshConverter() {
|
|||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool BlenderBMeshConverter::ContainsBMesh() const {
|
bool BlenderBMeshConverter::ContainsBMesh() const {
|
||||||
// TODO - Should probably do some additional verification here
|
if (BMesh == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return BMesh->totpoly && BMesh->totloop && BMesh->totvert;
|
return BMesh->totpoly && BMesh->totloop && BMesh->totvert;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,14 +63,12 @@ namespace Assimp
|
|||||||
struct MLoop;
|
struct MLoop;
|
||||||
}
|
}
|
||||||
|
|
||||||
class BlenderBMeshConverter: public LogFunctions< BlenderBMeshConverter >
|
class BlenderBMeshConverter final : public LogFunctions< BlenderBMeshConverter >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BlenderBMeshConverter( const Blender::Mesh* mesh );
|
explicit BlenderBMeshConverter( const Blender::Mesh* mesh );
|
||||||
~BlenderBMeshConverter( );
|
~BlenderBMeshConverter();
|
||||||
|
bool ContainsBMesh() const;
|
||||||
bool ContainsBMesh( ) const;
|
|
||||||
|
|
||||||
const Blender::Mesh* TriangulateBMesh( );
|
const Blender::Mesh* TriangulateBMesh( );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ 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
|
||||||
*/
|
*/
|
||||||
static std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDescriptions = { {
|
static const std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDescriptions = { {
|
||||||
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MVert),
|
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MVert),
|
||||||
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
@@ -142,7 +142,8 @@ static std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDescript
|
|||||||
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
|
|
||||||
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION } };
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION
|
||||||
|
} };
|
||||||
|
|
||||||
bool isValidCustomDataType(const int cdtype) {
|
bool isValidCustomDataType(const int cdtype) {
|
||||||
return cdtype >= 0 && cdtype < CD_NUMTYPES;
|
return cdtype >= 0 && cdtype < CD_NUMTYPES;
|
||||||
|
|||||||
@@ -55,14 +55,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
// enable verbose log output. really verbose, so be careful.
|
// enable verbose log output. really verbose, so be careful.
|
||||||
#ifdef ASSIMP_BUILD_DEBUG
|
#ifdef ASSIMP_BUILD_DEBUG
|
||||||
#define ASSIMP_BUILD_BLENDER_DEBUG
|
# define ASSIMP_BUILD_BLENDER_DEBUG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// set this to non-zero to dump BlenderDNA stuff to dna.txt.
|
// set this to non-zero to dump BlenderDNA stuff to dna.txt.
|
||||||
// you could set it on the assimp build command line too without touching it here.
|
// you could set it on the assimp build command line too without touching it here.
|
||||||
// !!! please make sure this is set to 0 in the repo !!!
|
// !!! please make sure this is set to 0 in the repo !!!
|
||||||
#ifndef ASSIMP_BUILD_BLENDER_DEBUG_DNA
|
#ifndef ASSIMP_BUILD_BLENDER_DEBUG_DNA
|
||||||
#define ASSIMP_BUILD_BLENDER_DEBUG_DNA 0
|
# define ASSIMP_BUILD_BLENDER_DEBUG_DNA 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// #define ASSIMP_BUILD_BLENDER_NO_STATS
|
// #define ASSIMP_BUILD_BLENDER_NO_STATS
|
||||||
@@ -124,22 +124,14 @@ struct ElemBase {
|
|||||||
* they used to point to.*/
|
* they used to point to.*/
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Pointer {
|
struct Pointer {
|
||||||
Pointer() :
|
uint64_t val{0};
|
||||||
val() {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
uint64_t val;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
/** Represents a generic offset within a BLEND file */
|
/** Represents a generic offset within a BLEND file */
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct FileOffset {
|
struct FileOffset {
|
||||||
FileOffset() :
|
uint64_t val{0};
|
||||||
val() {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
uint64_t val;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
@@ -204,7 +196,7 @@ enum ErrorPolicy {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifdef ASSIMP_BUILD_BLENDER_DEBUG
|
#ifdef ASSIMP_BUILD_BLENDER_DEBUG
|
||||||
#define ErrorPolicy_Igno ErrorPolicy_Warn
|
# define ErrorPolicy_Igno ErrorPolicy_Warn
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
@@ -396,10 +388,9 @@ private:
|
|||||||
mutable size_t cache_idx;
|
mutable size_t cache_idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------
|
||||||
template <>
|
template<>
|
||||||
struct Structure::_defaultInitializer<ErrorPolicy_Warn> {
|
struct Structure::_defaultInitializer<ErrorPolicy_Warn> {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void operator()(T &out, const char *reason = "<add reason>") {
|
void operator()(T &out, const char *reason = "<add reason>") {
|
||||||
ASSIMP_LOG_WARN(reason);
|
ASSIMP_LOG_WARN(reason);
|
||||||
@@ -409,9 +400,9 @@ struct Structure::_defaultInitializer<ErrorPolicy_Warn> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
// -------------------------------------------------------------------------------------------------------
|
||||||
|
template<>
|
||||||
struct Structure::_defaultInitializer<ErrorPolicy_Fail> {
|
struct Structure::_defaultInitializer<ErrorPolicy_Fail> {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void operator()(T & /*out*/, const char *message = "") {
|
void operator()(T & /*out*/, const char *message = "") {
|
||||||
// obviously, it is crucial that _DefaultInitializer is used
|
// obviously, it is crucial that _DefaultInitializer is used
|
||||||
@@ -619,31 +610,23 @@ public:
|
|||||||
/** Import statistics, i.e. number of file blocks read*/
|
/** Import statistics, i.e. number of file blocks read*/
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
class Statistics {
|
class Statistics {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Statistics() :
|
Statistics() = default;
|
||||||
fields_read(), pointers_resolved(), cache_hits()
|
~Statistics() = default;
|
||||||
// , blocks_read ()
|
|
||||||
,
|
|
||||||
cached_objects() {}
|
|
||||||
|
|
||||||
public:
|
/// total number of fields we read
|
||||||
/** total number of fields we read */
|
|
||||||
unsigned int fields_read;
|
unsigned int fields_read;
|
||||||
|
|
||||||
/** total number of resolved pointers */
|
/// total number of resolved pointers
|
||||||
unsigned int pointers_resolved;
|
unsigned int pointers_resolved;
|
||||||
|
|
||||||
/** number of pointers resolved from the cache */
|
/// number of pointers resolved from the cache
|
||||||
unsigned int cache_hits;
|
unsigned int cache_hits;
|
||||||
|
|
||||||
/** number of blocks (from FileDatabase::entries)
|
/// objects in FileData::cache
|
||||||
we did actually read from. */
|
|
||||||
// unsigned int blocks_read;
|
|
||||||
|
|
||||||
/** objects in FileData::cache */
|
|
||||||
unsigned int cached_objects;
|
unsigned int cached_objects;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
@@ -656,15 +639,13 @@ public:
|
|||||||
typedef std::map<Pointer, TOUT<ElemBase>> StructureCache;
|
typedef std::map<Pointer, TOUT<ElemBase>> StructureCache;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ObjectCache(const FileDatabase &db) :
|
explicit ObjectCache(const FileDatabase &db) : db(db) {
|
||||||
db(db) {
|
|
||||||
// currently there are only ~400 structure records per blend file.
|
// currently there are only ~400 structure records per blend file.
|
||||||
// we read only a small part of them and don't cache objects
|
// we read only a small part of them and don't cache objects
|
||||||
// which we don't need, so this should suffice.
|
// which we don't need, so this should suffice.
|
||||||
caches.reserve(64);
|
caches.reserve(64);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
/** Check whether a specific item is in the cache.
|
/** Check whether a specific item is in the cache.
|
||||||
* @param s Data type of the item
|
* @param s Data type of the item
|
||||||
@@ -672,10 +653,7 @@ public:
|
|||||||
* cache doesn't know the item yet.
|
* cache doesn't know the item yet.
|
||||||
* @param ptr Item address to look for. */
|
* @param ptr Item address to look for. */
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void get(
|
void get( const Structure &s,TOUT<T> &out, const Pointer &ptr) const;
|
||||||
const Structure &s,
|
|
||||||
TOUT<T> &out,
|
|
||||||
const Pointer &ptr) const;
|
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
/** Add an item to the cache after the item has
|
/** Add an item to the cache after the item has
|
||||||
@@ -700,7 +678,7 @@ private:
|
|||||||
template <>
|
template <>
|
||||||
class ObjectCache<Blender::vector> {
|
class ObjectCache<Blender::vector> {
|
||||||
public:
|
public:
|
||||||
ObjectCache(const FileDatabase &) {}
|
explicit ObjectCache(const FileDatabase &) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void get(const Structure &, vector<T> &, const Pointer &) {}
|
void get(const Structure &, vector<T> &, const Pointer &) {}
|
||||||
@@ -709,7 +687,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(disable : 4355)
|
# pragma warning(disable : 4355)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
@@ -724,16 +702,6 @@ public:
|
|||||||
FileDatabase() :
|
FileDatabase() :
|
||||||
_cacheArrays(*this), _cache(*this), next_cache_idx() {}
|
_cacheArrays(*this), _cache(*this), next_cache_idx() {}
|
||||||
|
|
||||||
public:
|
|
||||||
// publicly accessible fields
|
|
||||||
bool i64bit;
|
|
||||||
bool little;
|
|
||||||
|
|
||||||
DNA dna;
|
|
||||||
std::shared_ptr<StreamReaderAny> reader;
|
|
||||||
vector<FileBlockHead> entries;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Statistics &stats() const {
|
Statistics &stats() const {
|
||||||
return _stats;
|
return _stats;
|
||||||
}
|
}
|
||||||
@@ -752,6 +720,15 @@ public:
|
|||||||
return _cacheArrays;
|
return _cacheArrays;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
// publicly accessible fields
|
||||||
|
bool i64bit;
|
||||||
|
bool little;
|
||||||
|
|
||||||
|
DNA dna;
|
||||||
|
std::shared_ptr<StreamReaderAny> reader;
|
||||||
|
vector<FileBlockHead> entries;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
||||||
mutable Statistics _stats;
|
mutable Statistics _stats;
|
||||||
@@ -764,20 +741,19 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(default : 4355)
|
# pragma warning(default : 4355)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
/** Factory to extract a #DNA from the DNA1 file block in a BLEND file. */
|
/** Factory to extract a #DNA from the DNA1 file block in a BLEND file. */
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
class DNAParser {
|
class DNAParser {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Bind the parser to a empty DNA and an input stream */
|
/** Bind the parser to a empty DNA and an input stream */
|
||||||
DNAParser(FileDatabase &db) :
|
explicit DNAParser(FileDatabase &db) : db(db) {
|
||||||
db(db) {}
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
/** Locate the DNA in the file and parse it. The input
|
/** Locate the DNA in the file and parse it. The input
|
||||||
* stream is expected to point to the beginning of the DN1
|
* stream is expected to point to the beginning of the DN1
|
||||||
@@ -788,7 +764,6 @@ public:
|
|||||||
* afterwards.*/
|
* afterwards.*/
|
||||||
void Parse();
|
void Parse();
|
||||||
|
|
||||||
public:
|
|
||||||
/** Obtain a reference to the extracted DNA information */
|
/** Obtain a reference to the extracted DNA information */
|
||||||
const Blender::DNA &GetDNA() const {
|
const Blender::DNA &GetDNA() const {
|
||||||
return db.dna;
|
return db.dna;
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ class BlenderModifier;
|
|||||||
* call it is outsourced to BlenderDNA.cpp/BlenderDNA.h. This class only performs the
|
* call it is outsourced to BlenderDNA.cpp/BlenderDNA.h. This class only performs the
|
||||||
* conversion from intermediate format to aiScene. */
|
* conversion from intermediate format to aiScene. */
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
class BlenderImporter : public BaseImporter, public LogFunctions<BlenderImporter> {
|
class BlenderImporter final : public BaseImporter, public LogFunctions<BlenderImporter> {
|
||||||
public:
|
public:
|
||||||
BlenderImporter();
|
BlenderImporter();
|
||||||
~BlenderImporter() override;
|
~BlenderImporter() override;
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ private:
|
|||||||
* Mirror modifier. Status: implemented.
|
* Mirror modifier. Status: implemented.
|
||||||
*/
|
*/
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
class BlenderModifier_Mirror : public BlenderModifier {
|
class BlenderModifier_Mirror final : public BlenderModifier {
|
||||||
public:
|
public:
|
||||||
// --------------------
|
// --------------------
|
||||||
virtual bool IsActive( const ModifierData& modin);
|
virtual bool IsActive( const ModifierData& modin);
|
||||||
@@ -131,7 +131,7 @@ public:
|
|||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
/** Subdivision modifier. Status: dummy. */
|
/** Subdivision modifier. Status: dummy. */
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
class BlenderModifier_Subdivision : public BlenderModifier {
|
class BlenderModifier_Subdivision final : public BlenderModifier {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
|
|||||||
@@ -47,8 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include "BlenderDNA.h"
|
#include "BlenderDNA.h"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp::Blender {
|
||||||
namespace Blender {
|
|
||||||
|
|
||||||
// Minor parts of this file are extracts from blender data structures,
|
// Minor parts of this file are extracts from blender data structures,
|
||||||
// declared in the ./source/blender/makesdna directory.
|
// declared in the ./source/blender/makesdna directory.
|
||||||
@@ -115,32 +114,32 @@ struct Collection;
|
|||||||
static const size_t MaxNameLen = 1024;
|
static const size_t MaxNameLen = 1024;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct ID : ElemBase {
|
struct ID final : ElemBase {
|
||||||
char name[MaxNameLen] WARN;
|
char name[MaxNameLen] WARN;
|
||||||
short flag;
|
short flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct ListBase : ElemBase {
|
struct ListBase final : ElemBase {
|
||||||
std::shared_ptr<ElemBase> first;
|
std::shared_ptr<ElemBase> first;
|
||||||
std::weak_ptr<ElemBase> last;
|
std::weak_ptr<ElemBase> last;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct PackedFile : ElemBase {
|
struct PackedFile final : ElemBase {
|
||||||
int size WARN;
|
int size WARN;
|
||||||
int seek WARN;
|
int seek WARN;
|
||||||
std::shared_ptr<FileOffset> data WARN;
|
std::shared_ptr<FileOffset> data WARN;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct GroupObject : ElemBase {
|
struct GroupObject final : ElemBase {
|
||||||
std::shared_ptr<GroupObject> prev, next FAIL;
|
std::shared_ptr<GroupObject> prev, next FAIL;
|
||||||
std::shared_ptr<Object> ob;
|
std::shared_ptr<Object> ob;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Group : ElemBase {
|
struct Group final : ElemBase {
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
int layer;
|
int layer;
|
||||||
|
|
||||||
@@ -148,32 +147,32 @@ struct Group : ElemBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct CollectionObject : ElemBase {
|
struct CollectionObject final : ElemBase {
|
||||||
//CollectionObject* prev;
|
//CollectionObject* prev;
|
||||||
std::shared_ptr<CollectionObject> next;
|
std::shared_ptr<CollectionObject> next;
|
||||||
Object *ob;
|
Object *ob;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct CollectionChild : ElemBase {
|
struct CollectionChild final : ElemBase {
|
||||||
std::shared_ptr<CollectionChild> next, prev;
|
std::shared_ptr<CollectionChild> next, prev;
|
||||||
std::shared_ptr<Collection> collection;
|
std::shared_ptr<Collection> collection;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Collection : ElemBase {
|
struct Collection final : ElemBase {
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
ListBase gobject; // CollectionObject
|
ListBase gobject; // CollectionObject
|
||||||
ListBase children; // CollectionChild
|
ListBase children; // CollectionChild
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct World : ElemBase {
|
struct World final : ElemBase {
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MVert : ElemBase {
|
struct MVert final : ElemBase {
|
||||||
float co[3] FAIL;
|
float co[3] FAIL;
|
||||||
float no[3] FAIL; // read as short and divided through / 32767.f
|
float no[3] FAIL; // read as short and divided through / 32767.f
|
||||||
char flag;
|
char flag;
|
||||||
@@ -185,31 +184,31 @@ struct MVert : ElemBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MEdge : ElemBase {
|
struct MEdge final : ElemBase {
|
||||||
int v1, v2 FAIL;
|
int v1, v2 FAIL;
|
||||||
char crease, bweight;
|
char crease, bweight;
|
||||||
short flag;
|
short flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MLoop : ElemBase {
|
struct MLoop final : ElemBase {
|
||||||
int v, e;
|
int v, e;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MLoopUV : ElemBase {
|
struct MLoopUV final : ElemBase {
|
||||||
float uv[2];
|
float uv[2];
|
||||||
int flag;
|
int flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
// Note that red and blue are not swapped, as with MCol
|
// Note that red and blue are not swapped, as with MCol
|
||||||
struct MLoopCol : ElemBase {
|
struct MLoopCol final : ElemBase {
|
||||||
unsigned char r, g, b, a;
|
unsigned char r, g, b, a;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MPoly : ElemBase {
|
struct MPoly final : ElemBase {
|
||||||
int loopstart;
|
int loopstart;
|
||||||
int totloop;
|
int totloop;
|
||||||
short mat_nr;
|
short mat_nr;
|
||||||
@@ -217,26 +216,26 @@ struct MPoly : ElemBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MTexPoly : ElemBase {
|
struct MTexPoly final : ElemBase {
|
||||||
Image *tpage;
|
Image *tpage;
|
||||||
char flag, transp;
|
char flag, transp;
|
||||||
short mode, tile, pad;
|
short mode, tile, pad;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MCol : ElemBase {
|
struct MCol final : ElemBase {
|
||||||
char r, g, b, a FAIL;
|
char r, g, b, a FAIL;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MFace : ElemBase {
|
struct MFace final : ElemBase {
|
||||||
int v1, v2, v3, v4 FAIL;
|
int v1, v2, v3, v4 FAIL;
|
||||||
int mat_nr FAIL;
|
int mat_nr FAIL;
|
||||||
char flag;
|
char flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct TFace : ElemBase {
|
struct TFace final : ElemBase {
|
||||||
float uv[4][2] FAIL;
|
float uv[4][2] FAIL;
|
||||||
int col[4] FAIL;
|
int col[4] FAIL;
|
||||||
char flag;
|
char flag;
|
||||||
@@ -246,7 +245,7 @@ struct TFace : ElemBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MTFace : ElemBase {
|
struct MTFace final : ElemBase {
|
||||||
MTFace() :
|
MTFace() :
|
||||||
flag(0),
|
flag(0),
|
||||||
mode(0),
|
mode(0),
|
||||||
@@ -264,24 +263,24 @@ struct MTFace : ElemBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MDeformWeight : ElemBase {
|
struct MDeformWeight final : ElemBase {
|
||||||
int def_nr FAIL;
|
int def_nr FAIL;
|
||||||
float weight FAIL;
|
float weight FAIL;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MDeformVert : ElemBase {
|
struct MDeformVert final : ElemBase {
|
||||||
vector<MDeformWeight> dw WARN;
|
vector<MDeformWeight> dw WARN;
|
||||||
int totweight;
|
int totweight;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
#define MA_RAYMIRROR 0x40000
|
constexpr uint32_t MA_RAYMIRROR = 0x40000;
|
||||||
#define MA_TRANSPARENCY 0x10000
|
constexpr uint32_t MA_TRANSPARENCY = 0x10000;
|
||||||
#define MA_RAYTRANSP 0x20000
|
constexpr uint32_t MA_RAYTRANSP = 0x20000;
|
||||||
#define MA_ZTRANSP 0x00040
|
constexpr uint32_t MA_ZTRANSP = 0x00040;
|
||||||
|
|
||||||
struct Material : ElemBase {
|
struct Material final : ElemBase {
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
|
|
||||||
float r, g, b WARN;
|
float r, g, b WARN;
|
||||||
@@ -403,7 +402,7 @@ CustomDataLayer 104
|
|||||||
char name 32 64
|
char name 32 64
|
||||||
void *data 96 8
|
void *data 96 8
|
||||||
*/
|
*/
|
||||||
struct CustomDataLayer : ElemBase {
|
struct CustomDataLayer final : ElemBase {
|
||||||
int type;
|
int type;
|
||||||
int offset;
|
int offset;
|
||||||
int flag;
|
int flag;
|
||||||
@@ -441,7 +440,7 @@ CustomData 208
|
|||||||
BLI_mempool *pool 192 8
|
BLI_mempool *pool 192 8
|
||||||
CustomDataExternal *external 200 8
|
CustomDataExternal *external 200 8
|
||||||
*/
|
*/
|
||||||
struct CustomData : ElemBase {
|
struct CustomData final : ElemBase {
|
||||||
vector<std::shared_ptr<struct CustomDataLayer>> layers;
|
vector<std::shared_ptr<struct CustomDataLayer>> layers;
|
||||||
int typemap[42]; // CD_NUMTYPES
|
int typemap[42]; // CD_NUMTYPES
|
||||||
int totlayer;
|
int totlayer;
|
||||||
@@ -454,7 +453,7 @@ struct CustomData : ElemBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Mesh : ElemBase {
|
struct Mesh final : ElemBase {
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
|
|
||||||
int totface FAIL;
|
int totface FAIL;
|
||||||
@@ -491,7 +490,7 @@ struct Mesh : ElemBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Library : ElemBase {
|
struct Library final : ElemBase {
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
|
|
||||||
char name[240] WARN;
|
char name[240] WARN;
|
||||||
@@ -515,7 +514,7 @@ struct Camera : ElemBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Lamp : ElemBase {
|
struct Lamp final : ElemBase {
|
||||||
|
|
||||||
enum FalloffType {
|
enum FalloffType {
|
||||||
FalloffType_Constant = 0x0,
|
FalloffType_Constant = 0x0,
|
||||||
@@ -602,7 +601,7 @@ struct Lamp : ElemBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct ModifierData : ElemBase {
|
struct ModifierData final : ElemBase {
|
||||||
enum ModifierType {
|
enum ModifierType {
|
||||||
eModifierType_None = 0,
|
eModifierType_None = 0,
|
||||||
eModifierType_Subsurf,
|
eModifierType_Subsurf,
|
||||||
@@ -652,9 +651,8 @@ struct SharedModifierData : ElemBase {
|
|||||||
ModifierData modifier;
|
ModifierData modifier;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct SubsurfModifierData : SharedModifierData {
|
struct SubsurfModifierData final : SharedModifierData {
|
||||||
|
|
||||||
enum Type {
|
enum Type {
|
||||||
|
|
||||||
@@ -674,7 +672,7 @@ struct SubsurfModifierData : SharedModifierData {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MirrorModifierData : SharedModifierData {
|
struct MirrorModifierData final : SharedModifierData {
|
||||||
|
|
||||||
enum Flags {
|
enum Flags {
|
||||||
Flags_CLIPPING = 1 << 0,
|
Flags_CLIPPING = 1 << 0,
|
||||||
@@ -692,7 +690,7 @@ struct MirrorModifierData : SharedModifierData {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Object : ElemBase {
|
struct Object final : ElemBase {
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
|
|
||||||
enum Type {
|
enum Type {
|
||||||
@@ -733,7 +731,7 @@ struct Object : ElemBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Base : ElemBase {
|
struct Base final : ElemBase {
|
||||||
Base *prev WARN;
|
Base *prev WARN;
|
||||||
std::shared_ptr<Base> next WARN;
|
std::shared_ptr<Base> next WARN;
|
||||||
std::shared_ptr<Object> object WARN;
|
std::shared_ptr<Object> object WARN;
|
||||||
@@ -745,7 +743,7 @@ struct Base : ElemBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Scene : ElemBase {
|
struct Scene final : ElemBase {
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
|
|
||||||
std::shared_ptr<Object> camera WARN;
|
std::shared_ptr<Object> camera WARN;
|
||||||
@@ -759,7 +757,7 @@ struct Scene : ElemBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Image : ElemBase {
|
struct Image final : ElemBase {
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
|
|
||||||
char name[240] WARN;
|
char name[240] WARN;
|
||||||
@@ -789,7 +787,7 @@ struct Image : ElemBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Tex : ElemBase {
|
struct Tex final : ElemBase {
|
||||||
|
|
||||||
// actually, the only texture type we support is Type_IMAGE
|
// actually, the only texture type we support is Type_IMAGE
|
||||||
enum Type {
|
enum Type {
|
||||||
@@ -874,14 +872,13 @@ struct Tex : ElemBase {
|
|||||||
|
|
||||||
//char use_nodes;
|
//char use_nodes;
|
||||||
|
|
||||||
Tex() :
|
Tex() : imaflag(ImageFlags_INTERPOL), type(Type_CLOUDS) {
|
||||||
imaflag(ImageFlags_INTERPOL), type(Type_CLOUDS) {
|
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MTex : ElemBase {
|
struct MTex final : ElemBase {
|
||||||
|
|
||||||
enum Projection {
|
enum Projection {
|
||||||
Proj_N = 0,
|
Proj_N = 0,
|
||||||
@@ -970,6 +967,6 @@ struct MTex : ElemBase {
|
|||||||
MTex() = default;
|
MTex() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Blender
|
} // namespace Assimp::Blender
|
||||||
} // namespace Assimp
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -381,7 +381,14 @@ inline PointP2T& BlenderTessellatorP2T::GetActualPointStructure( p2t::Point& poi
|
|||||||
# pragma clang diagnostic push
|
# pragma clang diagnostic push
|
||||||
# pragma clang diagnostic ignored "-Winvalid-offsetof"
|
# pragma clang diagnostic ignored "-Winvalid-offsetof"
|
||||||
#endif // __clang__
|
#endif // __clang__
|
||||||
|
#if defined __GNUC__
|
||||||
|
# pragma GCC diagnostic push
|
||||||
|
# pragma GCC diagnostic ignored "-Winvalid-offsetof"
|
||||||
|
#endif // __GNUC__
|
||||||
unsigned int pointOffset = offsetof( PointP2T, point2D );
|
unsigned int pointOffset = offsetof( PointP2T, point2D );
|
||||||
|
#if defined __GNUC__
|
||||||
|
# pragma GCC diagnostic pop
|
||||||
|
#endif // __GNUC__
|
||||||
#if defined __clang__
|
#if defined __clang__
|
||||||
# pragma clang diagnostic pop
|
# pragma clang diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
using namespace Assimp::COB;
|
using namespace Assimp::COB;
|
||||||
using namespace Assimp::Formatter;
|
using namespace Assimp::Formatter;
|
||||||
|
|
||||||
@@ -109,10 +110,29 @@ void COBImporter::SetupProperties(const Importer * /*pImp*/) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
/*static*/ AI_WONT_RETURN void COBImporter::ThrowException(const std::string &msg) {
|
AI_WONT_RETURN void COBImporter::ThrowException(const std::string &msg) {
|
||||||
throw DeadlyImportError("COB: ", msg);
|
throw DeadlyImportError("COB: ", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
static bool isValidASCIIHeader(const char *head) {
|
||||||
|
ai_assert(head != nullptr);
|
||||||
|
|
||||||
|
if (strncmp(head, "Caligari ", 9) != 0) {
|
||||||
|
COBImporter::ThrowException("Could not found magic id: `Caligari`");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(&head[9], "V00.", 4) != 0) {
|
||||||
|
COBImporter::ThrowException("Could not found Version tag: `V00.`");
|
||||||
|
}
|
||||||
|
ASSIMP_LOG_INFO("File format tag: ", std::string(head + 9, 6));
|
||||||
|
if (head[16] != 'L') {
|
||||||
|
COBImporter::ThrowException("File is big-endian, which is not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void COBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
|
void COBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
|
||||||
@@ -126,19 +146,15 @@ void COBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||||||
std::unique_ptr<StreamReaderLE> stream(new StreamReaderLE(file));
|
std::unique_ptr<StreamReaderLE> stream(new StreamReaderLE(file));
|
||||||
|
|
||||||
// check header
|
// check header
|
||||||
char head[32];
|
static constexpr size_t HeaderSize = 32u;
|
||||||
stream->CopyAndAdvance(head, 32);
|
char head[HeaderSize] = {};
|
||||||
if (strncmp(head, "Caligari ", 9) != 0) {
|
stream->CopyAndAdvance(head, HeaderSize);
|
||||||
ThrowException("Could not found magic id: `Caligari`");
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSIMP_LOG_INFO("File format tag: ", std::string(head + 9, 6));
|
|
||||||
if (head[16] != 'L') {
|
|
||||||
ThrowException("File is big-endian, which is not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
// load data into intermediate structures
|
// load data into intermediate structures
|
||||||
if (head[15] == 'A') {
|
if (head[15] == 'A') {
|
||||||
|
if (!isValidASCIIHeader(head)) {
|
||||||
|
ThrowException("Invalid ASCII file header");
|
||||||
|
}
|
||||||
ReadAsciiFile(scene, stream.get());
|
ReadAsciiFile(scene, stream.get());
|
||||||
} else {
|
} else {
|
||||||
ReadBinaryFile(scene, stream.get());
|
ReadBinaryFile(scene, stream.get());
|
||||||
@@ -1170,6 +1186,6 @@ void COBImporter::ReadUnit_Binary(COB::Scene &out, StreamReaderLE &reader, const
|
|||||||
ASSIMP_LOG_WARN("`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist");
|
ASSIMP_LOG_WARN("`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace Assimp
|
||||||
|
|
||||||
#endif // ASSIMP_BUILD_NO_COB_IMPORTER
|
#endif // ASSIMP_BUILD_NO_COB_IMPORTER
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ namespace COB {
|
|||||||
*
|
*
|
||||||
* Currently relatively limited, loads only ASCII files and needs more test coverage. */
|
* Currently relatively limited, loads only ASCII files and needs more test coverage. */
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
class COBImporter : public BaseImporter {
|
class COBImporter final : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
COBImporter() = default;
|
COBImporter() = default;
|
||||||
~COBImporter() override = default;
|
~COBImporter() override = default;
|
||||||
@@ -81,6 +81,10 @@ public:
|
|||||||
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
|
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
|
||||||
bool checkSig) const override;
|
bool checkSig) const override;
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Prepend 'COB: ' and throw msg.*/
|
||||||
|
AI_WONT_RETURN static void ThrowException(const std::string &msg) AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// --------------------
|
// --------------------
|
||||||
const aiImporterDesc *GetInfo() const override;
|
const aiImporterDesc *GetInfo() const override;
|
||||||
@@ -93,10 +97,6 @@ protected:
|
|||||||
IOSystem *pIOHandler) override;
|
IOSystem *pIOHandler) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Prepend 'COB: ' and throw msg.*/
|
|
||||||
AI_WONT_RETURN static void ThrowException(const std::string &msg) AI_WONT_RETURN_SUFFIX;
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Read from an ascii scene/object file
|
/** @brief Read from an ascii scene/object file
|
||||||
* @param out Receives output data.
|
* @param out Receives output data.
|
||||||
@@ -148,4 +148,5 @@ private:
|
|||||||
}; // !class COBImporter
|
}; // !class COBImporter
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
||||||
#endif // AI_UNREALIMPORTER_H_INC
|
#endif // AI_UNREALIMPORTER_H_INC
|
||||||
|
|||||||
@@ -52,68 +52,66 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <deque>
|
#include <deque>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp::COB {
|
||||||
namespace COB {
|
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** Represents a single vertex index in a face */
|
/** Represents a single vertex index in a face */
|
||||||
struct VertexIndex
|
struct VertexIndex {
|
||||||
{
|
|
||||||
// intentionally uninitialized
|
// intentionally uninitialized
|
||||||
unsigned int pos_idx,uv_idx;
|
unsigned int pos_idx,uv_idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** COB Face data structure */
|
/** COB Face data structure */
|
||||||
struct Face
|
struct Face {
|
||||||
{
|
|
||||||
// intentionally uninitialized
|
// intentionally uninitialized
|
||||||
unsigned int material, flags;
|
unsigned int material;
|
||||||
|
unsigned int flags;
|
||||||
std::vector<VertexIndex> indices;
|
std::vector<VertexIndex> indices;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** COB chunk header information */
|
/** COB chunk header information */
|
||||||
const unsigned int NO_SIZE = UINT_MAX;
|
constexpr unsigned int NO_SIZE = UINT_MAX;
|
||||||
|
|
||||||
struct ChunkInfo
|
struct ChunkInfo {
|
||||||
{
|
ChunkInfo() = default;
|
||||||
ChunkInfo ()
|
virtual ~ChunkInfo() = default;
|
||||||
: id (0)
|
|
||||||
, parent_id (0)
|
|
||||||
, version (0)
|
|
||||||
, size (NO_SIZE)
|
|
||||||
{}
|
|
||||||
|
|
||||||
// Id of this chunk, unique within file
|
// Id of this chunk, unique within file
|
||||||
unsigned int id;
|
unsigned int id{ 0 };
|
||||||
|
|
||||||
// and the corresponding parent
|
// and the corresponding parent
|
||||||
unsigned int parent_id;
|
unsigned int parent_id{ 0 };
|
||||||
|
|
||||||
// version. v1.23 becomes 123
|
// version. v1.23 becomes 123
|
||||||
unsigned int version;
|
unsigned int version{ 0 };
|
||||||
|
|
||||||
// chunk size in bytes, only relevant for binary files
|
// chunk size in bytes, only relevant for binary files
|
||||||
// NO_SIZE is also valid.
|
// NO_SIZE is also valid.
|
||||||
unsigned int size;
|
unsigned int size{NO_SIZE};
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** A node in the scenegraph */
|
/** A node in the scenegraph */
|
||||||
struct Node : public ChunkInfo
|
struct Node : ChunkInfo {
|
||||||
{
|
|
||||||
enum Type {
|
enum Type {
|
||||||
TYPE_MESH,TYPE_GROUP,TYPE_LIGHT,TYPE_CAMERA,TYPE_BONE
|
TYPE_INVALID = -1,
|
||||||
|
TYPE_MESH = 0,
|
||||||
|
TYPE_GROUP,
|
||||||
|
TYPE_LIGHT,
|
||||||
|
TYPE_CAMERA,
|
||||||
|
TYPE_BONE,
|
||||||
|
TYPE_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ~Node() = default;
|
~Node() override = default;
|
||||||
Node(Type type) : type(type), unit_scale(1.f){}
|
explicit Node(Type type) : type(type), unit_scale(1.f){}
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
|
|
||||||
// used during resolving
|
// used during resolving
|
||||||
typedef std::deque<const Node*> ChildList;
|
using ChildList = std::deque<const Node*> ;
|
||||||
mutable ChildList temp_children;
|
mutable ChildList temp_children;
|
||||||
|
|
||||||
// unique name
|
// unique name
|
||||||
@@ -128,8 +126,7 @@ struct Node : public ChunkInfo
|
|||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** COB Mesh data structure */
|
/** COB Mesh data structure */
|
||||||
struct Mesh : public Node
|
struct Mesh final : Node {
|
||||||
{
|
|
||||||
using ChunkInfo::operator=;
|
using ChunkInfo::operator=;
|
||||||
enum DrawFlags {
|
enum DrawFlags {
|
||||||
SOLID = 0x1,
|
SOLID = 0x1,
|
||||||
@@ -162,107 +159,118 @@ struct Mesh : public Node
|
|||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** COB Group data structure */
|
/** COB Group data structure */
|
||||||
struct Group : public Node
|
struct Group final : Node {
|
||||||
{
|
|
||||||
using ChunkInfo::operator=;
|
using ChunkInfo::operator=;
|
||||||
Group() : Node(TYPE_GROUP) {}
|
|
||||||
|
Group() : Node(TYPE_GROUP) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** COB Bone data structure */
|
/** COB Bone data structure */
|
||||||
struct Bone : public Node
|
struct Bone final : Node {
|
||||||
{
|
|
||||||
using ChunkInfo::operator=;
|
using ChunkInfo::operator=;
|
||||||
Bone() : Node(TYPE_BONE) {}
|
|
||||||
|
Bone() : Node(TYPE_BONE) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** COB Light data structure */
|
/** COB Light data structure */
|
||||||
struct Light : public Node
|
struct Light final : Node {
|
||||||
{
|
|
||||||
enum LightType {
|
enum LightType {
|
||||||
SPOT,LOCAL,INFINITE
|
SPOT,
|
||||||
|
LOCAL,
|
||||||
|
INFINITE
|
||||||
};
|
};
|
||||||
|
|
||||||
using ChunkInfo::operator=;
|
using ChunkInfo::operator=;
|
||||||
Light() : Node(TYPE_LIGHT),angle(),inner_angle(),ltype(SPOT) {}
|
|
||||||
|
Light() : Node(TYPE_LIGHT), ltype() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
aiColor3D color;
|
aiColor3D color;
|
||||||
float angle,inner_angle;
|
float angle{ 0.0f };
|
||||||
|
float inner_angle{ 0.0f };
|
||||||
|
|
||||||
LightType ltype;
|
LightType ltype{SPOT};
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** COB Camera data structure */
|
/** COB Camera data structure */
|
||||||
struct Camera : public Node
|
struct Camera final : Node {
|
||||||
{
|
|
||||||
using ChunkInfo::operator=;
|
using ChunkInfo::operator=;
|
||||||
Camera() : Node(TYPE_CAMERA) {}
|
|
||||||
|
Camera() : Node(TYPE_CAMERA) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** COB Texture data structure */
|
/** COB Texture data structure */
|
||||||
struct Texture
|
struct Texture {
|
||||||
{
|
|
||||||
std::string path;
|
std::string path;
|
||||||
aiUVTransform transform;
|
aiUVTransform transform;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** COB Material data structure */
|
/** COB Material data structure */
|
||||||
struct Material : ChunkInfo
|
struct Material : ChunkInfo {
|
||||||
{
|
|
||||||
using ChunkInfo::operator=;
|
using ChunkInfo::operator=;
|
||||||
|
|
||||||
enum Shader {
|
enum Shader {
|
||||||
FLAT,PHONG,METAL
|
FLAT,
|
||||||
|
PHONG,
|
||||||
|
METAL
|
||||||
};
|
};
|
||||||
|
|
||||||
enum AutoFacet {
|
enum AutoFacet {
|
||||||
FACETED,AUTOFACETED,SMOOTH
|
FACETED,
|
||||||
|
AUTOFACETED,
|
||||||
|
SMOOTH
|
||||||
};
|
};
|
||||||
|
|
||||||
Material() : alpha(),exp(),ior(),ka(),ks(1.f),
|
Material() : shader(FLAT) {
|
||||||
matnum(UINT_MAX),
|
// empty
|
||||||
shader(FLAT),autofacet(FACETED),
|
}
|
||||||
autofacet_angle()
|
|
||||||
{}
|
|
||||||
|
|
||||||
std::string type;
|
std::string type;
|
||||||
|
|
||||||
aiColor3D rgb;
|
aiColor3D rgb;
|
||||||
float alpha, exp, ior,ka,ks;
|
float alpha{ 0.0f };
|
||||||
|
float exp{ 0.0f };
|
||||||
unsigned int matnum;
|
float ior{ 0.0f };
|
||||||
|
float ka{ 0.0f };
|
||||||
|
float ks{ 1.0f };
|
||||||
|
unsigned int matnum{ UINT_MAX };
|
||||||
Shader shader;
|
Shader shader;
|
||||||
|
AutoFacet autofacet{FACETED};
|
||||||
AutoFacet autofacet;
|
float autofacet_angle{ 0.0f };
|
||||||
float autofacet_angle;
|
|
||||||
|
|
||||||
std::shared_ptr<Texture> tex_env,tex_bump,tex_color;
|
std::shared_ptr<Texture> tex_env,tex_bump,tex_color;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** Embedded bitmap, for instance for the thumbnail image */
|
/** Embedded bitmap, for instance for the thumbnail image */
|
||||||
struct Bitmap : ChunkInfo
|
struct Bitmap : ChunkInfo {
|
||||||
{
|
Bitmap() = default;
|
||||||
Bitmap() : orig_size() {}
|
|
||||||
struct BitmapHeader
|
struct BitmapHeader {
|
||||||
{
|
// empty
|
||||||
};
|
};
|
||||||
|
|
||||||
BitmapHeader head;
|
BitmapHeader head;
|
||||||
size_t orig_size;
|
size_t orig_size{ 0u };
|
||||||
std::vector<char> buff_zipped;
|
std::vector<char> buff_zipped;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::deque< std::shared_ptr<Node> > NodeList;
|
using NodeList = std::deque< std::shared_ptr<Node>>;
|
||||||
typedef std::vector< Material > MaterialList;
|
using MaterialList = std::vector< Material >;
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** Represents a master COB scene, even if we loaded just a single COB file */
|
/** Represents a master COB scene, even if we loaded just a single COB file */
|
||||||
struct Scene
|
struct Scene {
|
||||||
{
|
|
||||||
NodeList nodes;
|
NodeList nodes;
|
||||||
MaterialList materials;
|
MaterialList materials;
|
||||||
|
|
||||||
@@ -270,7 +278,6 @@ struct Scene
|
|||||||
Bitmap thumbnail;
|
Bitmap thumbnail;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end COB
|
} // end Assimp::COB
|
||||||
} // end Assimp
|
|
||||||
|
|
||||||
#endif
|
#endif // INCLUDED_AI_COB_SCENE_H
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ void CSMImporter::InternReadFile( const std::string& pFile,
|
|||||||
else if (TokenMatchI(buffer,"rate",4)) {
|
else if (TokenMatchI(buffer,"rate",4)) {
|
||||||
SkipSpaces(&buffer, end);
|
SkipSpaces(&buffer, end);
|
||||||
float d = { 0.0f };
|
float d = { 0.0f };
|
||||||
buffer = fast_atoreal_move<float>(buffer,d);
|
buffer = fast_atoreal_move(buffer,d);
|
||||||
anim->mTicksPerSecond = d;
|
anim->mTicksPerSecond = d;
|
||||||
}
|
}
|
||||||
else if (TokenMatchI(buffer,"order",5)) {
|
else if (TokenMatchI(buffer,"order",5)) {
|
||||||
@@ -226,17 +226,17 @@ void CSMImporter::InternReadFile( const std::string& pFile,
|
|||||||
} else {
|
} else {
|
||||||
aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys;
|
aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys;
|
||||||
sub->mTime = (double)frame;
|
sub->mTime = (double)frame;
|
||||||
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.x);
|
buffer = fast_atoreal_move(buffer, sub->mValue.x);
|
||||||
|
|
||||||
if (!SkipSpacesAndLineEnd(&buffer, end)) {
|
if (!SkipSpacesAndLineEnd(&buffer, end)) {
|
||||||
throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample y coord");
|
throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample y coord");
|
||||||
}
|
}
|
||||||
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.y);
|
buffer = fast_atoreal_move(buffer, sub->mValue.y);
|
||||||
|
|
||||||
if (!SkipSpacesAndLineEnd(&buffer, end)) {
|
if (!SkipSpacesAndLineEnd(&buffer, end)) {
|
||||||
throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample z coord");
|
throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample z coord");
|
||||||
}
|
}
|
||||||
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.z);
|
buffer = fast_atoreal_move(buffer, sub->mValue.z);
|
||||||
|
|
||||||
++s->mNumPositionKeys;
|
++s->mNumPositionKeys;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ namespace Assimp {
|
|||||||
* Link to file format specification:
|
* Link to file format specification:
|
||||||
* <max_8_dvd>\samples\Motion\Docs\CSM.rtf
|
* <max_8_dvd>\samples\Motion\Docs\CSM.rtf
|
||||||
*/
|
*/
|
||||||
class CSMImporter : public BaseImporter {
|
class CSMImporter final : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
CSMImporter();
|
CSMImporter();
|
||||||
~CSMImporter() override = default;
|
~CSMImporter() override = default;
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class IOSystem;
|
|||||||
|
|
||||||
/// Helper class to export a given scene to a Collada file. Just for my personal
|
/// Helper class to export a given scene to a Collada file. Just for my personal
|
||||||
/// comfort when implementing it.
|
/// comfort when implementing it.
|
||||||
class ColladaExporter {
|
class ColladaExporter final {
|
||||||
public:
|
public:
|
||||||
/// Constructor for a specific scene to export
|
/// Constructor for a specific scene to export
|
||||||
ColladaExporter(const aiScene *pScene, IOSystem *pIOSystem, const std::string &path, const std::string &file);
|
ColladaExporter(const aiScene *pScene, IOSystem *pIOSystem, const std::string &path, const std::string &file);
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ struct SubMesh {
|
|||||||
|
|
||||||
/// Contains data for a single mesh
|
/// Contains data for a single mesh
|
||||||
struct Mesh {
|
struct Mesh {
|
||||||
Mesh(const std::string &id) :
|
explicit Mesh(const std::string &id) :
|
||||||
mId(id) {
|
mId(id) {
|
||||||
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
|
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
|
||||||
mNumUVComponents[i] = 2;
|
mNumUVComponents[i] = 2;
|
||||||
|
|||||||
@@ -77,12 +77,12 @@ static constexpr aiImporterDesc desc = {
|
|||||||
"dae xml zae"
|
"dae xml zae"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const float kMillisecondsFromSeconds = 1000.f;
|
static constexpr float kMillisecondsFromSeconds = 1000.f;
|
||||||
|
|
||||||
// Add an item of metadata to a node
|
// Add an item of metadata to a node
|
||||||
// Assumes the key is not already in the list
|
// Assumes the key is not already in the list
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void AddNodeMetaData(aiNode *node, const std::string &key, const T &value) {
|
void AddNodeMetaData(aiNode *node, const std::string &key, const T &value) {
|
||||||
if (nullptr == node->mMetaData) {
|
if (nullptr == node->mMetaData) {
|
||||||
node->mMetaData = new aiMetadata();
|
node->mMetaData = new aiMetadata();
|
||||||
}
|
}
|
||||||
@@ -92,7 +92,7 @@ inline void AddNodeMetaData(aiNode *node, const std::string &key, const T &value
|
|||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads a float value from an accessor and its data array.
|
// Reads a float value from an accessor and its data array.
|
||||||
static ai_real ReadFloat(const Accessor &pAccessor, const Data &pData, size_t pIndex, size_t pOffset) {
|
static ai_real ReadFloat(const Accessor &pAccessor, const Data &pData, size_t pIndex, size_t pOffset) {
|
||||||
size_t pos = pAccessor.mStride * pIndex + pAccessor.mOffset + pOffset;
|
const size_t pos = pAccessor.mStride * pIndex + pAccessor.mOffset + pOffset;
|
||||||
ai_assert(pos < pData.mValues.size());
|
ai_assert(pos < pData.mValues.size());
|
||||||
return pData.mValues[pos];
|
return pData.mValues[pos];
|
||||||
}
|
}
|
||||||
@@ -1819,4 +1819,4 @@ std::string ColladaLoader::FindNameForNode(const Node *pNode) {
|
|||||||
|
|
||||||
} // Namespace Assimp
|
} // Namespace Assimp
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_DAE_IMPORTER
|
#endif // !! ASSIMP_BUILD_NO_COLLADA_IMPORTER
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ struct ColladaMeshIndex {
|
|||||||
* Collada is over-engineered to death, with every new iteration bringing more useless stuff,
|
* Collada is over-engineered to death, with every new iteration bringing more useless stuff,
|
||||||
* so I limited the data to what I think is useful for games.
|
* so I limited the data to what I think is useful for games.
|
||||||
*/
|
*/
|
||||||
class ColladaLoader : public BaseImporter {
|
class ColladaLoader final : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
/// The class constructor.
|
/// The class constructor.
|
||||||
ColladaLoader();
|
ColladaLoader();
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ static void ReadNodeTransformation(XmlNode &node, Node *pNode, TransformType pTy
|
|||||||
// skip whitespace before the number
|
// skip whitespace before the number
|
||||||
SkipSpacesAndLineEnd(&content, end);
|
SkipSpacesAndLineEnd(&content, end);
|
||||||
// read a number
|
// read a number
|
||||||
content = fast_atoreal_move<ai_real>(content, tf.f[a]);
|
content = fast_atoreal_move(content, tf.f[a]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// place the transformation at the queue of the node
|
// place the transformation at the queue of the node
|
||||||
@@ -346,13 +346,13 @@ static void ReadLight(XmlNode &node, Light &pLight) {
|
|||||||
const char *content = v.c_str();
|
const char *content = v.c_str();
|
||||||
const char *end = content + v.size();
|
const char *end = content + v.size();
|
||||||
|
|
||||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.r);
|
content = fast_atoreal_move(content, pLight.mColor.r);
|
||||||
SkipSpacesAndLineEnd(&content, end);
|
SkipSpacesAndLineEnd(&content, end);
|
||||||
|
|
||||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.g);
|
content = fast_atoreal_move(content, pLight.mColor.g);
|
||||||
SkipSpacesAndLineEnd(&content, end);
|
SkipSpacesAndLineEnd(&content, end);
|
||||||
|
|
||||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.b);
|
content = fast_atoreal_move(content, pLight.mColor.b);
|
||||||
SkipSpacesAndLineEnd(&content, end);
|
SkipSpacesAndLineEnd(&content, end);
|
||||||
} else if (currentName == "constant_attenuation") {
|
} else if (currentName == "constant_attenuation") {
|
||||||
XmlParser::getValueAsReal(currentNode, pLight.mAttConstant);
|
XmlParser::getValueAsReal(currentNode, pLight.mAttConstant);
|
||||||
@@ -631,7 +631,7 @@ void ColladaParser::ReadAssetInfo(XmlNode &node) {
|
|||||||
std::string tUnitSizeString;
|
std::string tUnitSizeString;
|
||||||
if (XmlParser::getStdStrAttribute(currentNode, "meter", tUnitSizeString)) {
|
if (XmlParser::getStdStrAttribute(currentNode, "meter", tUnitSizeString)) {
|
||||||
try {
|
try {
|
||||||
fast_atoreal_move<ai_real>(tUnitSizeString.data(), mUnitSize);
|
fast_atoreal_move(tUnitSizeString.data(), mUnitSize);
|
||||||
} catch (const DeadlyImportError& die) {
|
} catch (const DeadlyImportError& die) {
|
||||||
std::string warning("Collada: Failed to parse meter parameter to real number. Exception:\n");
|
std::string warning("Collada: Failed to parse meter parameter to real number. Exception:\n");
|
||||||
warning.append(die.what());
|
warning.append(die.what());
|
||||||
@@ -889,7 +889,7 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
|
|||||||
for (auto & a : controller.mBindShapeMatrix) {
|
for (auto & a : controller.mBindShapeMatrix) {
|
||||||
SkipSpacesAndLineEnd(&content, end);
|
SkipSpacesAndLineEnd(&content, end);
|
||||||
// read a number
|
// read a number
|
||||||
content = fast_atoreal_move<ai_real>(content, a);
|
content = fast_atoreal_move(content, a);
|
||||||
// skip whitespace after it
|
// skip whitespace after it
|
||||||
SkipSpacesAndLineEnd(&content, end);
|
SkipSpacesAndLineEnd(&content, end);
|
||||||
}
|
}
|
||||||
@@ -1262,16 +1262,16 @@ void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &p
|
|||||||
const char *content = v.c_str();
|
const char *content = v.c_str();
|
||||||
const char *end = v.c_str() + v.size() + 1;
|
const char *end = v.c_str() + v.size() + 1;
|
||||||
|
|
||||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.r);
|
content = fast_atoreal_move(content, pColor.r);
|
||||||
SkipSpacesAndLineEnd(&content, end);
|
SkipSpacesAndLineEnd(&content, end);
|
||||||
|
|
||||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.g);
|
content = fast_atoreal_move(content, pColor.g);
|
||||||
SkipSpacesAndLineEnd(&content, end);
|
SkipSpacesAndLineEnd(&content, end);
|
||||||
|
|
||||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.b);
|
content = fast_atoreal_move(content, pColor.b);
|
||||||
SkipSpacesAndLineEnd(&content, end);
|
SkipSpacesAndLineEnd(&content, end);
|
||||||
|
|
||||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.a);
|
content = fast_atoreal_move(content, pColor.a);
|
||||||
SkipSpacesAndLineEnd(&content, end);
|
SkipSpacesAndLineEnd(&content, end);
|
||||||
} else if (currentName == "texture") {
|
} else if (currentName == "texture") {
|
||||||
// get name of source texture/sampler
|
// get name of source texture/sampler
|
||||||
@@ -1494,7 +1494,7 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
|
|||||||
|
|
||||||
// read a number
|
// read a number
|
||||||
ai_real value;
|
ai_real value;
|
||||||
content = fast_atoreal_move<ai_real>(content, value);
|
content = fast_atoreal_move(content, value);
|
||||||
data.mValues.push_back(value);
|
data.mValues.push_back(value);
|
||||||
// skip whitespace after it
|
// skip whitespace after it
|
||||||
SkipSpacesAndLineEnd(&content, end);
|
SkipSpacesAndLineEnd(&content, end);
|
||||||
@@ -1929,7 +1929,7 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
|
|||||||
void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, Mesh &pMesh,
|
void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, Mesh &pMesh,
|
||||||
std::vector<InputChannel> &pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t> &indices) {
|
std::vector<InputChannel> &pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t> &indices) {
|
||||||
// calculate the base offset of the vertex whose attributes we ant to copy
|
// calculate the base offset of the vertex whose attributes we ant to copy
|
||||||
size_t baseOffset = currentPrimitive * numOffsets * numPoints + currentVertex * numOffsets;
|
const auto baseOffset = currentPrimitive * numOffsets * numPoints + currentVertex * numOffsets;
|
||||||
|
|
||||||
// don't overrun the boundaries of the index list
|
// don't overrun the boundaries of the index list
|
||||||
ai_assert((baseOffset + numOffsets - 1) < indices.size());
|
ai_assert((baseOffset + numOffsets - 1) < indices.size());
|
||||||
@@ -1944,6 +1944,9 @@ void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t n
|
|||||||
}
|
}
|
||||||
|
|
||||||
// store the vertex-data index for later assignment of bone vertex weights
|
// store the vertex-data index for later assignment of bone vertex weights
|
||||||
|
if (const auto indexOffset = baseOffset + perVertexOffset; indexOffset >= indices.size()) {
|
||||||
|
throw DeadlyImportError("index offset out of range");
|
||||||
|
}
|
||||||
pMesh.mFacePosIndices.push_back(indices[baseOffset + perVertexOffset]);
|
pMesh.mFacePosIndices.push_back(indices[baseOffset + perVertexOffset]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2423,4 +2426,4 @@ InputType ColladaParser::GetTypeForSemantic(const std::string &semantic) {
|
|||||||
return IT_Invalid;
|
return IT_Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_DAE_IMPORTER
|
#endif // !! ASSIMP_BUILD_NO_COLLADA_IMPORTER
|
||||||
|
|||||||
@@ -53,15 +53,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp::DXF {
|
||||||
namespace DXF {
|
|
||||||
|
|
||||||
// read pairs of lines, parse group code and value and provide utilities
|
// read pairs of lines, parse group code and value and provide utilities
|
||||||
// to convert the data to the target data type.
|
// to convert the data to the target data type.
|
||||||
// do NOT skip empty lines. In DXF files, they count as valid data.
|
// do NOT skip empty lines. In DXF files, they count as valid data.
|
||||||
class LineReader {
|
class LineReader {
|
||||||
public:
|
public:
|
||||||
LineReader(StreamReaderLE& reader) : splitter(reader,false,true), groupcode( 0 ), end() {
|
explicit LineReader(StreamReaderLE& reader) : splitter(reader,false,true), groupcode( 0 ), end() {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +100,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
float ValueAsFloat() const {
|
ai_real ValueAsFloat() const {
|
||||||
return fast_atof(value.c_str());
|
return fast_atof(value.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,7 +202,6 @@ struct FileData {
|
|||||||
std::vector<Block> blocks;
|
std::vector<Block> blocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace DXF
|
} // namespace Assimp::DXF
|
||||||
} // namespace Assimp
|
|
||||||
|
|
||||||
#endif // INCLUDED_DXFHELPER_H
|
#endif // INCLUDED_DXFHELPER_H
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ namespace DXF {
|
|||||||
/**
|
/**
|
||||||
* @brief DXF importer implementation.
|
* @brief DXF importer implementation.
|
||||||
*/
|
*/
|
||||||
class DXFImporter : public BaseImporter {
|
class DXFImporter final : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
DXFImporter() = default;
|
DXFImporter() = default;
|
||||||
~DXFImporter() override = default;
|
~DXFImporter() override = default;
|
||||||
|
|||||||
@@ -91,7 +91,9 @@ AI_WONT_RETURN void TokenizeError(const std::string& message, size_t offset)
|
|||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
size_t Offset(const char* begin, const char* cursor) {
|
size_t Offset(const char* begin, const char* cursor) {
|
||||||
ai_assert(begin <= cursor);
|
if (begin > cursor) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return cursor - begin;
|
return cursor - begin;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,8 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp::FBX {
|
||||||
namespace FBX {
|
|
||||||
|
|
||||||
static constexpr size_t NumNullRecords = 25;
|
static constexpr size_t NumNullRecords = 25;
|
||||||
|
|
||||||
@@ -84,8 +83,7 @@ enum TransformInheritance {
|
|||||||
TransformInheritance_MAX // end-of-enum sentinel
|
TransformInheritance_MAX // end-of-enum sentinel
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace FBX
|
} // namespace Assimp::FBX
|
||||||
} // namespace Assimp
|
|
||||||
|
|
||||||
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
|
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
//
|
//
|
||||||
#if _MSC_VER > 1500 || (defined __GNUC___)
|
#if _MSC_VER > 1500 || (defined __GNUC__)
|
||||||
# define ASSIMP_FBX_USE_UNORDERED_MULTIMAP
|
# define ASSIMP_FBX_USE_UNORDERED_MULTIMAP
|
||||||
# else
|
# else
|
||||||
# define fbx_unordered_map map
|
# define fbx_unordered_map map
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ std::string FBXConverter::MakeUniqueNodeName(const Model *const model, const aiN
|
|||||||
/// When a node becomes a child of another node, that node becomes its owner and mOwnership should be released.
|
/// When a node becomes a child of another node, that node becomes its owner and mOwnership should be released.
|
||||||
struct FBXConverter::PotentialNode {
|
struct FBXConverter::PotentialNode {
|
||||||
PotentialNode() : mOwnership(new aiNode), mNode(mOwnership.get()) {}
|
PotentialNode() : mOwnership(new aiNode), mNode(mOwnership.get()) {}
|
||||||
PotentialNode(const std::string& name) : mOwnership(new aiNode(name)), mNode(mOwnership.get()) {}
|
explicit PotentialNode(const std::string& name) : mOwnership(new aiNode(name)), mNode(mOwnership.get()) {}
|
||||||
aiNode* operator->() { return mNode; }
|
aiNode* operator->() { return mNode; }
|
||||||
std::unique_ptr<aiNode> mOwnership;
|
std::unique_ptr<aiNode> mOwnership;
|
||||||
aiNode* mNode;
|
aiNode* mNode;
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ class NodeAttribute : public Object {
|
|||||||
public:
|
public:
|
||||||
NodeAttribute(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
NodeAttribute(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||||
|
|
||||||
virtual ~NodeAttribute() = default;
|
~NodeAttribute() override = default;
|
||||||
|
|
||||||
const PropertyTable& Props() const {
|
const PropertyTable& Props() const {
|
||||||
ai_assert(props.get());
|
ai_assert(props.get());
|
||||||
@@ -186,11 +186,11 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** DOM base class for FBX camera settings attached to a node */
|
/** DOM base class for FBX camera settings attached to a node */
|
||||||
class CameraSwitcher : public NodeAttribute {
|
class CameraSwitcher final : public NodeAttribute {
|
||||||
public:
|
public:
|
||||||
CameraSwitcher(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
CameraSwitcher(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||||
|
|
||||||
virtual ~CameraSwitcher() = default;
|
~CameraSwitcher() override= default;
|
||||||
|
|
||||||
int CameraID() const {
|
int CameraID() const {
|
||||||
return cameraId;
|
return cameraId;
|
||||||
@@ -231,11 +231,11 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
/** DOM base class for FBX cameras attached to a node */
|
/** DOM base class for FBX cameras attached to a node */
|
||||||
class Camera : public NodeAttribute {
|
class Camera final : public NodeAttribute {
|
||||||
public:
|
public:
|
||||||
Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||||
|
|
||||||
virtual ~Camera() = default;
|
~Camera() override = default;
|
||||||
|
|
||||||
fbx_simple_property(Position, aiVector3D, aiVector3D(0,0,0))
|
fbx_simple_property(Position, aiVector3D, aiVector3D(0,0,0))
|
||||||
fbx_simple_property(UpVector, aiVector3D, aiVector3D(0,1,0))
|
fbx_simple_property(UpVector, aiVector3D, aiVector3D(0,1,0))
|
||||||
@@ -257,24 +257,24 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** DOM base class for FBX null markers attached to a node */
|
/** DOM base class for FBX null markers attached to a node */
|
||||||
class Null : public NodeAttribute {
|
class Null final : public NodeAttribute {
|
||||||
public:
|
public:
|
||||||
Null(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
Null(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||||
virtual ~Null() = default;
|
~Null() override = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** DOM base class for FBX limb node markers attached to a node */
|
/** DOM base class for FBX limb node markers attached to a node */
|
||||||
class LimbNode : public NodeAttribute {
|
class LimbNode final : public NodeAttribute {
|
||||||
public:
|
public:
|
||||||
LimbNode(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
LimbNode(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||||
virtual ~LimbNode() = default;
|
~LimbNode() override = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** DOM base class for FBX lights attached to a node */
|
/** DOM base class for FBX lights attached to a node */
|
||||||
class Light : public NodeAttribute {
|
class Light final : public NodeAttribute {
|
||||||
public:
|
public:
|
||||||
Light(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
Light(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||||
virtual ~Light() = default;
|
~Light() override = default;
|
||||||
|
|
||||||
enum Type {
|
enum Type {
|
||||||
Type_Point,
|
Type_Point,
|
||||||
@@ -329,7 +329,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** DOM base class for FBX models (even though its semantics are more "node" than "model" */
|
/** DOM base class for FBX models (even though its semantics are more "node" than "model" */
|
||||||
class Model : public Object {
|
class Model final : public Object {
|
||||||
public:
|
public:
|
||||||
enum RotOrder {
|
enum RotOrder {
|
||||||
RotOrder_EulerXYZ = 0,
|
RotOrder_EulerXYZ = 0,
|
||||||
@@ -354,7 +354,7 @@ public:
|
|||||||
|
|
||||||
Model(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
Model(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||||
|
|
||||||
virtual ~Model() = default;
|
~Model() override = default;
|
||||||
|
|
||||||
fbx_simple_property(QuaternionInterpolate, int, 0)
|
fbx_simple_property(QuaternionInterpolate, int, 0)
|
||||||
|
|
||||||
@@ -477,11 +477,11 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** DOM class for generic FBX textures */
|
/** DOM class for generic FBX textures */
|
||||||
class Texture : public Object {
|
class Texture final : public Object {
|
||||||
public:
|
public:
|
||||||
Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||||
|
|
||||||
virtual ~Texture();
|
~Texture() override;
|
||||||
|
|
||||||
const std::string& Type() const {
|
const std::string& Type() const {
|
||||||
return type;
|
return type;
|
||||||
@@ -542,10 +542,10 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** DOM class for layered FBX textures */
|
/** DOM class for layered FBX textures */
|
||||||
class LayeredTexture : public Object {
|
class LayeredTexture final : public Object {
|
||||||
public:
|
public:
|
||||||
LayeredTexture(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
LayeredTexture(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||||
virtual ~LayeredTexture();
|
~LayeredTexture() override;
|
||||||
|
|
||||||
// Can only be called after construction of the layered texture object due to construction flag.
|
// Can only be called after construction of the layered texture object due to construction flag.
|
||||||
void fillTexture(const Document& doc);
|
void fillTexture(const Document& doc);
|
||||||
@@ -608,11 +608,11 @@ using TextureMap = std::fbx_unordered_map<std::string, const Texture*>;
|
|||||||
using LayeredTextureMap = std::fbx_unordered_map<std::string, const LayeredTexture*>;
|
using LayeredTextureMap = std::fbx_unordered_map<std::string, const LayeredTexture*>;
|
||||||
|
|
||||||
/** DOM class for generic FBX videos */
|
/** DOM class for generic FBX videos */
|
||||||
class Video : public Object {
|
class Video final : public Object {
|
||||||
public:
|
public:
|
||||||
Video(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
Video(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||||
|
|
||||||
virtual ~Video();
|
~Video() override;
|
||||||
|
|
||||||
const std::string& Type() const {
|
const std::string& Type() const {
|
||||||
return type;
|
return type;
|
||||||
@@ -697,10 +697,10 @@ using KeyTimeList = std::vector<int64_t>;
|
|||||||
using KeyValueList = std::vector<float>;
|
using KeyValueList = std::vector<float>;
|
||||||
|
|
||||||
/** Represents a FBX animation curve (i.e. a 1-dimensional set of keyframes and values therefore) */
|
/** Represents a FBX animation curve (i.e. a 1-dimensional set of keyframes and values therefore) */
|
||||||
class AnimationCurve : public Object {
|
class AnimationCurve final : public Object {
|
||||||
public:
|
public:
|
||||||
AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& doc);
|
AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& doc);
|
||||||
virtual ~AnimationCurve() = default;
|
~AnimationCurve() override = default;
|
||||||
|
|
||||||
/** get list of keyframe positions (time).
|
/** get list of keyframe positions (time).
|
||||||
* Invariant: |GetKeys()| > 0 */
|
* Invariant: |GetKeys()| > 0 */
|
||||||
@@ -733,7 +733,7 @@ private:
|
|||||||
using AnimationCurveMap = std::map<std::string, const AnimationCurve*>;
|
using AnimationCurveMap = std::map<std::string, const AnimationCurve*>;
|
||||||
|
|
||||||
/** Represents a FBX animation curve (i.e. a mapping from single animation curves to nodes) */
|
/** Represents a FBX animation curve (i.e. a mapping from single animation curves to nodes) */
|
||||||
class AnimationCurveNode : public Object {
|
class AnimationCurveNode final : public Object {
|
||||||
public:
|
public:
|
||||||
/* the optional white list specifies a list of property names for which the caller
|
/* the optional white list specifies a list of property names for which the caller
|
||||||
wants animations for. If the curve node does not match one of these, std::range_error
|
wants animations for. If the curve node does not match one of these, std::range_error
|
||||||
@@ -741,7 +741,7 @@ public:
|
|||||||
AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc,
|
AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc,
|
||||||
const char *const *target_prop_whitelist = nullptr, size_t whitelist_size = 0);
|
const char *const *target_prop_whitelist = nullptr, size_t whitelist_size = 0);
|
||||||
|
|
||||||
virtual ~AnimationCurveNode() = default;
|
~AnimationCurveNode() override = default;
|
||||||
|
|
||||||
const PropertyTable& Props() const {
|
const PropertyTable& Props() const {
|
||||||
ai_assert(props.get());
|
ai_assert(props.get());
|
||||||
@@ -783,7 +783,7 @@ private:
|
|||||||
using AnimationCurveNodeList = std::vector<const AnimationCurveNode*>;
|
using AnimationCurveNodeList = std::vector<const AnimationCurveNode*>;
|
||||||
|
|
||||||
/** Represents a FBX animation layer (i.e. a list of node animations) */
|
/** Represents a FBX animation layer (i.e. a list of node animations) */
|
||||||
class AnimationLayer : public Object {
|
class AnimationLayer final : public Object {
|
||||||
public:
|
public:
|
||||||
AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc);
|
AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc);
|
||||||
virtual ~AnimationLayer() = default;
|
virtual ~AnimationLayer() = default;
|
||||||
@@ -806,7 +806,7 @@ private:
|
|||||||
using AnimationLayerList = std::vector<const AnimationLayer*>;
|
using AnimationLayerList = std::vector<const AnimationLayer*>;
|
||||||
|
|
||||||
/** Represents a FBX animation stack (i.e. a list of animation layers) */
|
/** Represents a FBX animation stack (i.e. a list of animation layers) */
|
||||||
class AnimationStack : public Object {
|
class AnimationStack final : public Object {
|
||||||
public:
|
public:
|
||||||
AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc);
|
AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc);
|
||||||
virtual ~AnimationStack() = default;
|
virtual ~AnimationStack() = default;
|
||||||
@@ -851,7 +851,7 @@ using WeightIndexArray = std::vector<unsigned int>;
|
|||||||
|
|
||||||
|
|
||||||
/** DOM class for BlendShapeChannel deformers */
|
/** DOM class for BlendShapeChannel deformers */
|
||||||
class BlendShapeChannel : public Deformer {
|
class BlendShapeChannel final : public Deformer {
|
||||||
public:
|
public:
|
||||||
BlendShapeChannel(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
BlendShapeChannel(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||||
|
|
||||||
@@ -876,7 +876,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** DOM class for BlendShape deformers */
|
/** DOM class for BlendShape deformers */
|
||||||
class BlendShape : public Deformer {
|
class BlendShape final : public Deformer {
|
||||||
public:
|
public:
|
||||||
BlendShape(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
BlendShape(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||||
|
|
||||||
@@ -891,7 +891,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** DOM class for skin deformer clusters (aka sub-deformers) */
|
/** DOM class for skin deformer clusters (aka sub-deformers) */
|
||||||
class Cluster : public Deformer {
|
class Cluster final : public Deformer {
|
||||||
public:
|
public:
|
||||||
Cluster(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
Cluster(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||||
|
|
||||||
@@ -935,7 +935,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** DOM class for skin deformers */
|
/** DOM class for skin deformers */
|
||||||
class Skin : public Deformer {
|
class Skin final : public Deformer {
|
||||||
public:
|
public:
|
||||||
Skin(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
Skin(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||||
|
|
||||||
|
|||||||
@@ -1582,6 +1582,7 @@ void FBXExporter::WriteObjects () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::map<std::string, std::string> tpath_by_image;
|
||||||
// FbxVideo - stores images used by textures.
|
// FbxVideo - stores images used by textures.
|
||||||
for (const auto &it : uid_by_image) {
|
for (const auto &it : uid_by_image) {
|
||||||
FBX::Node n("Video");
|
FBX::Node n("Video");
|
||||||
@@ -1601,10 +1602,21 @@ void FBXExporter::WriteObjects () {
|
|||||||
std::stringstream newPath;
|
std::stringstream newPath;
|
||||||
if (embedded_texture->mFilename.length > 0) {
|
if (embedded_texture->mFilename.length > 0) {
|
||||||
newPath << embedded_texture->mFilename.C_Str();
|
newPath << embedded_texture->mFilename.C_Str();
|
||||||
|
// If newPath doesn't end in an extension, add extension from embedded_texture->achFormatHint
|
||||||
|
std::string np = newPath.str();
|
||||||
|
size_t dot_pos = np.find_last_of('.');
|
||||||
|
if (dot_pos == std::string::npos || dot_pos < np.find_last_of("/\\")) {
|
||||||
|
// No extension found, add one
|
||||||
|
newPath << "." << embedded_texture->achFormatHint;
|
||||||
|
}
|
||||||
} else if (embedded_texture->achFormatHint[0]) {
|
} else if (embedded_texture->achFormatHint[0]) {
|
||||||
int texture_index = std::stoi(path.substr(1, path.size() - 1));
|
int texture_index = std::stoi(path.substr(1, path.size() - 1));
|
||||||
newPath << texture_index << "." << embedded_texture->achFormatHint;
|
newPath << texture_index << "." << embedded_texture->achFormatHint;
|
||||||
}
|
}
|
||||||
|
auto elem = tpath_by_image.find(path);
|
||||||
|
if (elem == tpath_by_image.end()) {
|
||||||
|
tpath_by_image[path] = newPath.str();
|
||||||
|
}
|
||||||
path = newPath.str();
|
path = newPath.str();
|
||||||
// embed the texture
|
// embed the texture
|
||||||
size_t texture_size = static_cast<size_t>(embedded_texture->mWidth * std::max(embedded_texture->mHeight, 1u));
|
size_t texture_size = static_cast<size_t>(embedded_texture->mWidth * std::max(embedded_texture->mHeight, 1u));
|
||||||
@@ -1723,6 +1735,17 @@ void FBXExporter::WriteObjects () {
|
|||||||
unsigned int max = sizeof(aiUVTransform);
|
unsigned int max = sizeof(aiUVTransform);
|
||||||
aiGetMaterialFloatArray(mat, AI_MATKEY_UVTRANSFORM(aiTextureType_DIFFUSE, 0), (ai_real *)&trafo, &max);
|
aiGetMaterialFloatArray(mat, AI_MATKEY_UVTRANSFORM(aiTextureType_DIFFUSE, 0), (ai_real *)&trafo, &max);
|
||||||
|
|
||||||
|
auto tp_elem = tpath_by_image.find(texture_path);
|
||||||
|
std::string tfile_path = texture_path;
|
||||||
|
if (tp_elem != tpath_by_image.end()) {
|
||||||
|
tfile_path = tp_elem->second;
|
||||||
|
} else {
|
||||||
|
std::stringstream err;
|
||||||
|
err << "Texture path not found for texure " << texture_path;
|
||||||
|
err << " on material " << i;
|
||||||
|
ASSIMP_LOG_WARN(err.str());
|
||||||
|
}
|
||||||
|
|
||||||
// now write the actual texture node
|
// now write the actual texture node
|
||||||
FBX::Node tnode("Texture");
|
FBX::Node tnode("Texture");
|
||||||
// TODO: some way to determine texture name?
|
// TODO: some way to determine texture name?
|
||||||
@@ -1743,8 +1766,8 @@ void FBXExporter::WriteObjects () {
|
|||||||
// can't easily determine which texture path will be correct,
|
// can't easily determine which texture path will be correct,
|
||||||
// so just store what we have in every field.
|
// so just store what we have in every field.
|
||||||
// these being incorrect is a common problem with FBX anyway.
|
// these being incorrect is a common problem with FBX anyway.
|
||||||
tnode.AddChild("FileName", texture_path);
|
tnode.AddChild("FileName", tp_elem->second);
|
||||||
tnode.AddChild("RelativeFilename", texture_path);
|
tnode.AddChild("RelativeFilename", tp_elem->second);
|
||||||
tnode.AddChild("ModelUVTranslation", double(0.0), double(0.0));
|
tnode.AddChild("ModelUVTranslation", double(0.0), double(0.0));
|
||||||
tnode.AddChild("ModelUVScaling", double(1.0), double(1.0));
|
tnode.AddChild("ModelUVScaling", double(1.0), double(1.0));
|
||||||
tnode.AddChild("Texture_Alpha_Source", "None");
|
tnode.AddChild("Texture_Alpha_Source", "None");
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ typedef class basic_formatter<char, std::char_traits<char>, std::allocator<char>
|
|||||||
///
|
///
|
||||||
/// See http://en.wikipedia.org/wiki/FBX
|
/// See http://en.wikipedia.org/wiki/FBX
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
class FBXImporter : public BaseImporter, public LogFunctions<FBXImporter> {
|
class FBXImporter final : public BaseImporter, public LogFunctions<FBXImporter> {
|
||||||
public:
|
public:
|
||||||
/// @brief The class constructor.
|
/// @brief The class constructor.
|
||||||
FBXImporter() = default;
|
FBXImporter() = default;
|
||||||
|
|||||||
@@ -365,10 +365,14 @@ float ParseTokenAsFloat(const Token& t, const char*& err_out)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (data[0] == 'F') {
|
if (data[0] == 'F') {
|
||||||
return SafeParse<float>(data+1, t.end());
|
BE_NCONST float id = SafeParse<float>(data+1, t.end());
|
||||||
|
AI_SWAP4(id);
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return static_cast<float>( SafeParse<double>(data+1, t.end()) );
|
BE_NCONST double id = SafeParse<double>(data+1, t.end());
|
||||||
|
AI_SWAP8(id);
|
||||||
|
return static_cast<float>(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -637,9 +641,15 @@ void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
|
|||||||
if (type == 'd') {
|
if (type == 'd') {
|
||||||
const double* d = reinterpret_cast<const double*>(&buff[0]);
|
const double* d = reinterpret_cast<const double*>(&buff[0]);
|
||||||
for (unsigned int i = 0; i < count3; ++i, d += 3) {
|
for (unsigned int i = 0; i < count3; ++i, d += 3) {
|
||||||
out.emplace_back(static_cast<ai_real>(d[0]),
|
BE_NCONST double val1 = d[0];
|
||||||
static_cast<ai_real>(d[1]),
|
BE_NCONST double val2 = d[1];
|
||||||
static_cast<ai_real>(d[2]));
|
BE_NCONST double val3 = d[2];
|
||||||
|
AI_SWAP8(val1);
|
||||||
|
AI_SWAP8(val2);
|
||||||
|
AI_SWAP8(val3);
|
||||||
|
out.emplace_back(static_cast<ai_real>(val1),
|
||||||
|
static_cast<ai_real>(val2),
|
||||||
|
static_cast<ai_real>(val3));
|
||||||
}
|
}
|
||||||
// for debugging
|
// for debugging
|
||||||
/*for ( size_t i = 0; i < out.size(); i++ ) {
|
/*for ( size_t i = 0; i < out.size(); i++ ) {
|
||||||
@@ -652,7 +662,13 @@ void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
|
|||||||
else if (type == 'f') {
|
else if (type == 'f') {
|
||||||
const float* f = reinterpret_cast<const float*>(&buff[0]);
|
const float* f = reinterpret_cast<const float*>(&buff[0]);
|
||||||
for (unsigned int i = 0; i < count3; ++i, f += 3) {
|
for (unsigned int i = 0; i < count3; ++i, f += 3) {
|
||||||
out.emplace_back(f[0],f[1],f[2]);
|
BE_NCONST float val1 = f[0];
|
||||||
|
BE_NCONST float val2 = f[1];
|
||||||
|
BE_NCONST float val3 = f[2];
|
||||||
|
AI_SWAP4(val1);
|
||||||
|
AI_SWAP4(val2);
|
||||||
|
AI_SWAP4(val3);
|
||||||
|
out.emplace_back(val1,val2,val3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -726,16 +742,32 @@ void ParseVectorDataArray(std::vector<aiColor4D>& out, const Element& el)
|
|||||||
if (type == 'd') {
|
if (type == 'd') {
|
||||||
const double* d = reinterpret_cast<const double*>(&buff[0]);
|
const double* d = reinterpret_cast<const double*>(&buff[0]);
|
||||||
for (unsigned int i = 0; i < count4; ++i, d += 4) {
|
for (unsigned int i = 0; i < count4; ++i, d += 4) {
|
||||||
out.emplace_back(static_cast<float>(d[0]),
|
BE_NCONST double val1 = d[0];
|
||||||
static_cast<float>(d[1]),
|
BE_NCONST double val2 = d[1];
|
||||||
static_cast<float>(d[2]),
|
BE_NCONST double val3 = d[2];
|
||||||
static_cast<float>(d[3]));
|
BE_NCONST double val4 = d[3];
|
||||||
|
AI_SWAP8(val1);
|
||||||
|
AI_SWAP8(val2);
|
||||||
|
AI_SWAP8(val3);
|
||||||
|
AI_SWAP8(val4);
|
||||||
|
out.emplace_back(static_cast<float>(val1),
|
||||||
|
static_cast<float>(val2),
|
||||||
|
static_cast<float>(val3),
|
||||||
|
static_cast<float>(val4));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == 'f') {
|
else if (type == 'f') {
|
||||||
const float* f = reinterpret_cast<const float*>(&buff[0]);
|
const float* f = reinterpret_cast<const float*>(&buff[0]);
|
||||||
for (unsigned int i = 0; i < count4; ++i, f += 4) {
|
for (unsigned int i = 0; i < count4; ++i, f += 4) {
|
||||||
out.emplace_back(f[0],f[1],f[2],f[3]);
|
BE_NCONST float val1 = f[0];
|
||||||
|
BE_NCONST float val2 = f[1];
|
||||||
|
BE_NCONST float val3 = f[2];
|
||||||
|
BE_NCONST float val4 = f[3];
|
||||||
|
AI_SWAP4(val1);
|
||||||
|
AI_SWAP4(val2);
|
||||||
|
AI_SWAP4(val3);
|
||||||
|
AI_SWAP4(val4);
|
||||||
|
out.emplace_back(val1,val2,val3,val4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -807,13 +839,21 @@ void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el) {
|
|||||||
if (type == 'd') {
|
if (type == 'd') {
|
||||||
const double* d = reinterpret_cast<const double*>(&buff[0]);
|
const double* d = reinterpret_cast<const double*>(&buff[0]);
|
||||||
for (unsigned int i = 0; i < count2; ++i, d += 2) {
|
for (unsigned int i = 0; i < count2; ++i, d += 2) {
|
||||||
out.emplace_back(static_cast<float>(d[0]),
|
BE_NCONST double val1 = d[0];
|
||||||
static_cast<float>(d[1]));
|
BE_NCONST double val2 = d[1];
|
||||||
|
AI_SWAP8(val1);
|
||||||
|
AI_SWAP8(val2);
|
||||||
|
out.emplace_back(static_cast<float>(val1),
|
||||||
|
static_cast<float>(val2));
|
||||||
}
|
}
|
||||||
} else if (type == 'f') {
|
} else if (type == 'f') {
|
||||||
const float* f = reinterpret_cast<const float*>(&buff[0]);
|
const float* f = reinterpret_cast<const float*>(&buff[0]);
|
||||||
for (unsigned int i = 0; i < count2; ++i, f += 2) {
|
for (unsigned int i = 0; i < count2; ++i, f += 2) {
|
||||||
out.emplace_back(f[0],f[1]);
|
BE_NCONST float val1 = f[0];
|
||||||
|
BE_NCONST float val2 = f[1];
|
||||||
|
AI_SWAP4(val1);
|
||||||
|
AI_SWAP4(val2);
|
||||||
|
out.emplace_back(val1,val2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -938,13 +978,17 @@ void ParseVectorDataArray(std::vector<float>& out, const Element& el)
|
|||||||
if (type == 'd') {
|
if (type == 'd') {
|
||||||
const double* d = reinterpret_cast<const double*>(&buff[0]);
|
const double* d = reinterpret_cast<const double*>(&buff[0]);
|
||||||
for (unsigned int i = 0; i < count; ++i, ++d) {
|
for (unsigned int i = 0; i < count; ++i, ++d) {
|
||||||
out.push_back(static_cast<float>(*d));
|
BE_NCONST double val = *d;
|
||||||
|
AI_SWAP8(val);
|
||||||
|
out.push_back(static_cast<float>(val));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == 'f') {
|
else if (type == 'f') {
|
||||||
const float* f = reinterpret_cast<const float*>(&buff[0]);
|
const float* f = reinterpret_cast<const float*>(&buff[0]);
|
||||||
for (unsigned int i = 0; i < count; ++i, ++f) {
|
for (unsigned int i = 0; i < count; ++i, ++f) {
|
||||||
out.push_back(*f);
|
BE_NCONST float val = *f;
|
||||||
|
AI_SWAP4(val);
|
||||||
|
out.push_back(val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,11 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
|
namespace Assimp::FBX::Util {
|
||||||
|
|
||||||
namespace Assimp {
|
|
||||||
namespace FBX {
|
|
||||||
namespace Util {
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const char* TokenTypeString(TokenType t)
|
const char* TokenTypeString(TokenType t)
|
||||||
@@ -233,8 +229,5 @@ std::string EncodeBase64(const char* data, size_t length)
|
|||||||
return encoded_string;
|
return encoded_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // !Util
|
} // namespace Assimp::FBX::Util
|
||||||
} // !FBX
|
|
||||||
} // !Assimp
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -49,10 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "FBXTokenizer.h"
|
#include "FBXTokenizer.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp::FBX::Util {
|
||||||
namespace FBX {
|
|
||||||
|
|
||||||
namespace Util {
|
|
||||||
|
|
||||||
/** helper for std::for_each to delete all heap-allocated items in a container */
|
/** helper for std::for_each to delete all heap-allocated items in a container */
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -73,12 +70,9 @@ struct destructor_fun {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** Get a string representation for a #TokenType. */
|
/** Get a string representation for a #TokenType. */
|
||||||
const char* TokenTypeString(TokenType t);
|
const char* TokenTypeString(TokenType t);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Format log/error messages using a given offset in the source binary file
|
/** Format log/error messages using a given offset in the source binary file
|
||||||
*
|
*
|
||||||
* @param offset offset within the file
|
* @param offset offset within the file
|
||||||
@@ -129,8 +123,6 @@ char EncodeBase64(char byte);
|
|||||||
* @return base64-encoded string*/
|
* @return base64-encoded string*/
|
||||||
std::string EncodeBase64(const char* data, size_t length);
|
std::string EncodeBase64(const char* data, size_t length);
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ! INCLUDED_AI_FBX_UTIL_H
|
#endif // ! INCLUDED_AI_FBX_UTIL_H
|
||||||
|
|||||||
@@ -433,24 +433,24 @@ void IRRMeshImporter::ParseBufferVertices(const char *sz, const char *end, Verte
|
|||||||
aiColor4D c;
|
aiColor4D c;
|
||||||
|
|
||||||
// Read the vertex position
|
// Read the vertex position
|
||||||
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
|
sz = fast_atoreal_move(sz, temp.x);
|
||||||
SkipSpaces(&sz, end);
|
SkipSpaces(&sz, end);
|
||||||
|
|
||||||
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
|
sz = fast_atoreal_move(sz, temp.y);
|
||||||
SkipSpaces(&sz, end);
|
SkipSpaces(&sz, end);
|
||||||
|
|
||||||
sz = fast_atoreal_move<float>(sz, (float &)temp.z);
|
sz = fast_atoreal_move(sz, temp.z);
|
||||||
SkipSpaces(&sz, end);
|
SkipSpaces(&sz, end);
|
||||||
vertices.push_back(temp);
|
vertices.push_back(temp);
|
||||||
|
|
||||||
// Read the vertex normals
|
// Read the vertex normals
|
||||||
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
|
sz = fast_atoreal_move(sz, temp.x);
|
||||||
SkipSpaces(&sz, end);
|
SkipSpaces(&sz, end);
|
||||||
|
|
||||||
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
|
sz = fast_atoreal_move(sz, temp.y);
|
||||||
SkipSpaces(&sz, end);
|
SkipSpaces(&sz, end);
|
||||||
|
|
||||||
sz = fast_atoreal_move<float>(sz, (float &)temp.z);
|
sz = fast_atoreal_move(sz, temp.z);
|
||||||
SkipSpaces(&sz, end);
|
SkipSpaces(&sz, end);
|
||||||
normals.push_back(temp);
|
normals.push_back(temp);
|
||||||
|
|
||||||
@@ -466,10 +466,10 @@ void IRRMeshImporter::ParseBufferVertices(const char *sz, const char *end, Verte
|
|||||||
SkipSpaces(&sz, end);
|
SkipSpaces(&sz, end);
|
||||||
|
|
||||||
// read the first UV coordinate set
|
// read the first UV coordinate set
|
||||||
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
|
sz = fast_atoreal_move(sz, temp.x);
|
||||||
SkipSpaces(&sz, end);
|
SkipSpaces(&sz, end);
|
||||||
|
|
||||||
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
|
sz = fast_atoreal_move(sz, temp.y);
|
||||||
SkipSpaces(&sz, end);
|
SkipSpaces(&sz, end);
|
||||||
temp.z = 0.f;
|
temp.z = 0.f;
|
||||||
temp.y = 1.f - temp.y; // DX to OGL
|
temp.y = 1.f - temp.y; // DX to OGL
|
||||||
@@ -479,35 +479,35 @@ void IRRMeshImporter::ParseBufferVertices(const char *sz, const char *end, Verte
|
|||||||
// So by definition, all buffers have either UV2 or tangents or neither
|
// So by definition, all buffers have either UV2 or tangents or neither
|
||||||
// read the (optional) second UV coordinate set
|
// read the (optional) second UV coordinate set
|
||||||
if (vertexFormat == VertexFormat::t2coord) {
|
if (vertexFormat == VertexFormat::t2coord) {
|
||||||
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
|
sz = fast_atoreal_move(sz, temp.x);
|
||||||
SkipSpaces(&sz, end);
|
SkipSpaces(&sz, end);
|
||||||
|
|
||||||
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
|
sz = fast_atoreal_move(sz, temp.y);
|
||||||
temp.y = 1.f - temp.y; // DX to OGL
|
temp.y = 1.f - temp.y; // DX to OGL
|
||||||
UV2s.push_back(temp);
|
UV2s.push_back(temp);
|
||||||
}
|
}
|
||||||
// read optional tangent and bitangent vectors
|
// read optional tangent and bitangent vectors
|
||||||
else if (vertexFormat == VertexFormat::tangent) {
|
else if (vertexFormat == VertexFormat::tangent) {
|
||||||
// tangents
|
// tangents
|
||||||
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
|
sz = fast_atoreal_move(sz, temp.x);
|
||||||
SkipSpaces(&sz, end);
|
SkipSpaces(&sz, end);
|
||||||
|
|
||||||
sz = fast_atoreal_move<float>(sz, (float &)temp.z);
|
sz = fast_atoreal_move(sz, temp.z);
|
||||||
SkipSpaces(&sz, end);
|
SkipSpaces(&sz, end);
|
||||||
|
|
||||||
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
|
sz = fast_atoreal_move(sz, temp.y);
|
||||||
SkipSpaces(&sz, end);
|
SkipSpaces(&sz, end);
|
||||||
temp.y *= -1.0f;
|
temp.y *= -1.0f;
|
||||||
tangents.push_back(temp);
|
tangents.push_back(temp);
|
||||||
|
|
||||||
// bitangents
|
// bitangents
|
||||||
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
|
sz = fast_atoreal_move(sz, temp.x);
|
||||||
SkipSpaces(&sz, end);
|
SkipSpaces(&sz, end);
|
||||||
|
|
||||||
sz = fast_atoreal_move<float>(sz, (float &)temp.z);
|
sz = fast_atoreal_move(sz, temp.z);
|
||||||
SkipSpaces(&sz, end);
|
SkipSpaces(&sz, end);
|
||||||
|
|
||||||
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
|
sz = fast_atoreal_move(sz, temp.y);
|
||||||
SkipSpaces(&sz, end);
|
SkipSpaces(&sz, end);
|
||||||
temp.y *= -1.0f;
|
temp.y *= -1.0f;
|
||||||
bitangents.push_back(temp);
|
bitangents.push_back(temp);
|
||||||
|
|||||||
@@ -139,21 +139,21 @@ void IrrlichtBase::ReadVectorProperty(VectorProperty &out, pugi::xml_node& vecto
|
|||||||
const char *end = ptr + len;
|
const char *end = ptr + len;
|
||||||
|
|
||||||
SkipSpaces(&ptr, end);
|
SkipSpaces(&ptr, end);
|
||||||
ptr = fast_atoreal_move<float>(ptr, (float &)out.value.x);
|
ptr = fast_atoreal_move(ptr, out.value.x);
|
||||||
SkipSpaces(&ptr, end);
|
SkipSpaces(&ptr, end);
|
||||||
if (',' != *ptr) {
|
if (',' != *ptr) {
|
||||||
ASSIMP_LOG_ERROR("IRR(MESH): Expected comma in vector definition");
|
ASSIMP_LOG_ERROR("IRR(MESH): Expected comma in vector definition");
|
||||||
} else {
|
} else {
|
||||||
SkipSpaces(ptr + 1, &ptr, end);
|
SkipSpaces(ptr + 1, &ptr, end);
|
||||||
}
|
}
|
||||||
ptr = fast_atoreal_move<float>(ptr, (float &)out.value.y);
|
ptr = fast_atoreal_move(ptr, out.value.y);
|
||||||
SkipSpaces(&ptr, end);
|
SkipSpaces(&ptr, end);
|
||||||
if (',' != *ptr) {
|
if (',' != *ptr) {
|
||||||
ASSIMP_LOG_ERROR("IRR(MESH): Expected comma in vector definition");
|
ASSIMP_LOG_ERROR("IRR(MESH): Expected comma in vector definition");
|
||||||
} else {
|
} else {
|
||||||
SkipSpaces(ptr + 1, &ptr, end);
|
SkipSpaces(ptr + 1, &ptr, end);
|
||||||
}
|
}
|
||||||
ptr = fast_atoreal_move<float>(ptr, (float &)out.value.z);
|
ptr = fast_atoreal_move(ptr, out.value.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
|||||||
|
|
||||||
Copyright (c) 2006-2025, assimp team
|
Copyright (c) 2006-2025, 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,
|
||||||
@@ -1150,4 +1148,4 @@ void LWOImporter::LoadLWO3Surface(unsigned int size) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_X_IMPORTER
|
#endif // ASSIMP_BUILD_NO_LWO_IMPORTER
|
||||||
|
|||||||
@@ -208,9 +208,9 @@ void LWSImporter::ReadEnvelope(const LWS::Element &dad, LWO::Envelope &fill) {
|
|||||||
|
|
||||||
float f;
|
float f;
|
||||||
SkipSpaces(&c, end);
|
SkipSpaces(&c, end);
|
||||||
c = fast_atoreal_move<float>(c, key.value);
|
c = fast_atoreal_move(c, key.value);
|
||||||
SkipSpaces(&c, end);
|
SkipSpaces(&c, end);
|
||||||
c = fast_atoreal_move<float>(c, f);
|
c = fast_atoreal_move(c, f);
|
||||||
|
|
||||||
key.time = f;
|
key.time = f;
|
||||||
|
|
||||||
@@ -242,7 +242,7 @@ void LWSImporter::ReadEnvelope(const LWS::Element &dad, LWO::Envelope &fill) {
|
|||||||
}
|
}
|
||||||
for (unsigned int i = 0; i < num; ++i) {
|
for (unsigned int i = 0; i < num; ++i) {
|
||||||
SkipSpaces(&c, end);
|
SkipSpaces(&c, end);
|
||||||
c = fast_atoreal_move<float>(c, key.params[i]);
|
c = fast_atoreal_move(c, key.params[i]);
|
||||||
}
|
}
|
||||||
} else if ((*it).tokens[0] == "Behaviors") {
|
} else if ((*it).tokens[0] == "Behaviors") {
|
||||||
SkipSpaces(&c, end);
|
SkipSpaces(&c, end);
|
||||||
@@ -284,11 +284,11 @@ void LWSImporter::ReadEnvelope_Old(std::list<LWS::Element>::const_iterator &it,c
|
|||||||
|
|
||||||
// parse value and time, skip the rest for the moment.
|
// parse value and time, skip the rest for the moment.
|
||||||
LWO::Key key;
|
LWO::Key key;
|
||||||
const char *c = fast_atoreal_move<float>((*it).tokens[0].c_str(), key.value);
|
const char *c = fast_atoreal_move((*it).tokens[0].c_str(), key.value);
|
||||||
const char *end = c + (*it).tokens[0].size();
|
const char *end = c + (*it).tokens[0].size();
|
||||||
SkipSpaces(&c, end);
|
SkipSpaces(&c, end);
|
||||||
float f;
|
float f;
|
||||||
fast_atoreal_move<float>((*it).tokens[0].c_str(), f);
|
fast_atoreal_move((*it).tokens[0].c_str(), f);
|
||||||
key.time = f;
|
key.time = f;
|
||||||
|
|
||||||
envl.keys.emplace_back(key);
|
envl.keys.emplace_back(key);
|
||||||
@@ -775,7 +775,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||||||
ASSIMP_LOG_ERROR("LWS: envelopes for LightIntensity not supported, set to 1.0");
|
ASSIMP_LOG_ERROR("LWS: envelopes for LightIntensity not supported, set to 1.0");
|
||||||
nodes.back().lightIntensity = (ai_real)1.0;
|
nodes.back().lightIntensity = (ai_real)1.0;
|
||||||
} else {
|
} else {
|
||||||
fast_atoreal_move<float>(c, nodes.back().lightIntensity);
|
fast_atoreal_move(c, nodes.back().lightIntensity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -816,11 +816,11 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||||||
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) {
|
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) {
|
||||||
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightColor\'");
|
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightColor\'");
|
||||||
} else {
|
} else {
|
||||||
c = fast_atoreal_move<float>(c, (float &)nodes.back().lightColor.r);
|
c = fast_atoreal_move(c, nodes.back().lightColor.r);
|
||||||
SkipSpaces(&c, end);
|
SkipSpaces(&c, end);
|
||||||
c = fast_atoreal_move<float>(c, (float &)nodes.back().lightColor.g);
|
c = fast_atoreal_move(c, nodes.back().lightColor.g);
|
||||||
SkipSpaces(&c, end);
|
SkipSpaces(&c, end);
|
||||||
c = fast_atoreal_move<float>(c, (float &)nodes.back().lightColor.b);
|
c = fast_atoreal_move(c, nodes.back().lightColor.b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -829,11 +829,11 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||||||
if (nodes.empty()) {
|
if (nodes.empty()) {
|
||||||
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'PivotPosition\'");
|
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'PivotPosition\'");
|
||||||
} else {
|
} else {
|
||||||
c = fast_atoreal_move<float>(c, (float &)nodes.back().pivotPos.x);
|
c = fast_atoreal_move(c, nodes.back().pivotPos.x);
|
||||||
SkipSpaces(&c, end);
|
SkipSpaces(&c, end);
|
||||||
c = fast_atoreal_move<float>(c, (float &)nodes.back().pivotPos.y);
|
c = fast_atoreal_move(c, nodes.back().pivotPos.y);
|
||||||
SkipSpaces(&c, end);
|
SkipSpaces(&c, end);
|
||||||
c = fast_atoreal_move<float>(c, (float &)nodes.back().pivotPos.z);
|
c = fast_atoreal_move(c, nodes.back().pivotPos.z);
|
||||||
// Mark pivotPos as set
|
// Mark pivotPos as set
|
||||||
nodes.back().isPivotSet = true;
|
nodes.back().isPivotSet = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -332,7 +332,7 @@ void M3DImporter::importTextures(const M3DWrapper &m3d) {
|
|||||||
/* if we have the texture loaded, set format hint and pcData too */
|
/* if we have the texture loaded, set format hint and pcData too */
|
||||||
tx->mWidth = t->w;
|
tx->mWidth = t->w;
|
||||||
tx->mHeight = t->h;
|
tx->mHeight = t->h;
|
||||||
strcpy(tx->achFormatHint, formatHint[t->f - 1]);
|
strncpy(tx->achFormatHint, formatHint[t->f - 1], 8);
|
||||||
tx->pcData = new aiTexel[tx->mWidth * tx->mHeight];
|
tx->pcData = new aiTexel[tx->mWidth * tx->mHeight];
|
||||||
for (j = k = 0; j < tx->mWidth * tx->mHeight; j++) {
|
for (j = k = 0; j < tx->mWidth * tx->mHeight; j++) {
|
||||||
switch (t->f) {
|
switch (t->f) {
|
||||||
|
|||||||
@@ -246,11 +246,11 @@ inline void AI_MD5_READ_TRIPLE(aiVector3D &vec, const char **sz, const char *buf
|
|||||||
return;
|
return;
|
||||||
++*sz;
|
++*sz;
|
||||||
AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
|
AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
|
||||||
*sz = fast_atoreal_move<float>(*sz, (float &)vec.x);
|
*sz = fast_atoreal_move(*sz, vec.x);
|
||||||
AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
|
AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
|
||||||
*sz = fast_atoreal_move<float>(*sz, (float &)vec.y);
|
*sz = fast_atoreal_move(*sz, vec.y);
|
||||||
AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
|
AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
|
||||||
*sz = fast_atoreal_move<float>(*sz, (float &)vec.z);
|
*sz = fast_atoreal_move(*sz, vec.z);
|
||||||
AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
|
AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
|
||||||
if (')' != **sz) {
|
if (')' != **sz) {
|
||||||
MD5Parser::ReportWarning("Unexpected token: ) was expected", linenumber);
|
MD5Parser::ReportWarning("Unexpected token: ) was expected", linenumber);
|
||||||
@@ -377,9 +377,9 @@ MD5MeshParser::MD5MeshParser(SectionArray &mSections) {
|
|||||||
if ('(' != *sz++)
|
if ('(' != *sz++)
|
||||||
MD5Parser::ReportWarning("Unexpected token: ( was expected", elem.iLineNumber);
|
MD5Parser::ReportWarning("Unexpected token: ( was expected", elem.iLineNumber);
|
||||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||||
sz = fast_atoreal_move<float>(sz, (float &)vert.mUV.x);
|
sz = fast_atoreal_move(sz, vert.mUV.x);
|
||||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||||
sz = fast_atoreal_move<float>(sz, (float &)vert.mUV.y);
|
sz = fast_atoreal_move(sz, vert.mUV.y);
|
||||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||||
if (')' != *sz++)
|
if (')' != *sz++)
|
||||||
MD5Parser::ReportWarning("Unexpected token: ) was expected", elem.iLineNumber);
|
MD5Parser::ReportWarning("Unexpected token: ) was expected", elem.iLineNumber);
|
||||||
@@ -393,11 +393,15 @@ MD5MeshParser::MD5MeshParser(SectionArray &mSections) {
|
|||||||
else if (TokenMatch(sz, "tri", 3)) {
|
else if (TokenMatch(sz, "tri", 3)) {
|
||||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||||
const unsigned int idx = strtoul10(sz, &sz);
|
const unsigned int idx = strtoul10(sz, &sz);
|
||||||
if (idx >= desc.mFaces.size())
|
if (idx >= desc.mFaces.size()) {
|
||||||
desc.mFaces.resize(idx + 1);
|
desc.mFaces.resize(idx + 1);
|
||||||
|
}
|
||||||
|
|
||||||
aiFace &face = desc.mFaces[idx];
|
aiFace &face = desc.mFaces[idx];
|
||||||
face.mIndices = new unsigned int[face.mNumIndices = 3];
|
if (face.mNumIndices != 3) {
|
||||||
|
delete [] face.mIndices;
|
||||||
|
face.mIndices = new unsigned int[face.mNumIndices = 3];
|
||||||
|
}
|
||||||
for (unsigned int i = 0; i < 3; ++i) {
|
for (unsigned int i = 0; i < 3; ++i) {
|
||||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||||
face.mIndices[i] = strtoul10(sz, &sz);
|
face.mIndices[i] = strtoul10(sz, &sz);
|
||||||
@@ -415,7 +419,7 @@ MD5MeshParser::MD5MeshParser(SectionArray &mSections) {
|
|||||||
WeightDesc &weight = desc.mWeights[idx];
|
WeightDesc &weight = desc.mWeights[idx];
|
||||||
weight.mBone = strtoul10(sz, &sz);
|
weight.mBone = strtoul10(sz, &sz);
|
||||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||||
sz = fast_atoreal_move<float>(sz, weight.mWeight);
|
sz = fast_atoreal_move(sz, weight.mWeight);
|
||||||
AI_MD5_READ_TRIPLE(weight.vOffsetPosition, &sz, elem.end, elem.iLineNumber);
|
AI_MD5_READ_TRIPLE(weight.vOffsetPosition, &sz, elem.end, elem.iLineNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -486,7 +490,7 @@ MD5AnimParser::MD5AnimParser(SectionArray &mSections) {
|
|||||||
const char *sz = elem.szStart;
|
const char *sz = elem.szStart;
|
||||||
while (SkipSpacesAndLineEnd(&sz, elem.end)) {
|
while (SkipSpacesAndLineEnd(&sz, elem.end)) {
|
||||||
float f;
|
float f;
|
||||||
sz = fast_atoreal_move<float>(sz, f);
|
sz = fast_atoreal_move(sz, f);
|
||||||
desc.mValues.push_back(f);
|
desc.mValues.push_back(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -503,7 +507,7 @@ MD5AnimParser::MD5AnimParser(SectionArray &mSections) {
|
|||||||
} else if ((*iter).mName == "numAnimatedComponents") {
|
} else if ((*iter).mName == "numAnimatedComponents") {
|
||||||
mAnimatedBones.reserve(strtoul10((*iter).mGlobalValue.c_str()));
|
mAnimatedBones.reserve(strtoul10((*iter).mGlobalValue.c_str()));
|
||||||
} else if ((*iter).mName == "frameRate") {
|
} else if ((*iter).mName == "frameRate") {
|
||||||
fast_atoreal_move<float>((*iter).mGlobalValue.c_str(), fFrameRate);
|
fast_atoreal_move((*iter).mGlobalValue.c_str(), fFrameRate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ASSIMP_LOG_DEBUG("MD5AnimParser end");
|
ASSIMP_LOG_DEBUG("MD5AnimParser end");
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "MDLLoader.h"
|
#include "MDLLoader.h"
|
||||||
#include "AssetLib/MD2/MD2FileData.h"
|
#include "AssetLib/MD2/MD2FileData.h"
|
||||||
#include "HalfLife/HL1MDLLoader.h"
|
#include "HalfLife/HL1MDLLoader.h"
|
||||||
|
#include "HalfLife/HL1FileData.h"
|
||||||
#include "MDLDefaultColorMap.h"
|
#include "MDLDefaultColorMap.h"
|
||||||
|
|
||||||
#include <assimp/StringUtils.h>
|
#include <assimp/StringUtils.h>
|
||||||
@@ -1980,6 +1981,11 @@ void MDLImporter::InternReadFile_HL1(const std::string &pFile, const uint32_t iM
|
|||||||
if (iMagicWord == AI_MDL_MAGIC_NUMBER_BE_HL2b || iMagicWord == AI_MDL_MAGIC_NUMBER_LE_HL2b)
|
if (iMagicWord == AI_MDL_MAGIC_NUMBER_BE_HL2b || iMagicWord == AI_MDL_MAGIC_NUMBER_LE_HL2b)
|
||||||
throw DeadlyImportError("Impossible to properly load a model from an MDL sequence file.");
|
throw DeadlyImportError("Impossible to properly load a model from an MDL sequence file.");
|
||||||
|
|
||||||
|
// Check if the buffer is large enough to hold the header
|
||||||
|
if (iFileSize < sizeof(HalfLife::Header_HL1)) {
|
||||||
|
throw DeadlyImportError("HL1 MDL file is too small to contain header.");
|
||||||
|
}
|
||||||
|
|
||||||
// Read the MDL file.
|
// Read the MDL file.
|
||||||
HalfLife::HL1MDLLoader loader(
|
HalfLife::HL1MDLLoader loader(
|
||||||
pScene,
|
pScene,
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
|||||||
|
|
||||||
Copyright (c) 2006-2025, assimp team
|
Copyright (c) 2006-2025, 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,
|
||||||
@@ -46,10 +44,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
* Written against http://chumbalum.swissquake.ch/ms3d/ms3dspec.txt
|
* Written against http://chumbalum.swissquake.ch/ms3d/ms3dspec.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_MS3D_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_MS3D_IMPORTER
|
||||||
|
|
||||||
// internal headers
|
|
||||||
#include "MS3DLoader.h"
|
#include "MS3DLoader.h"
|
||||||
#include <assimp/StreamReader.h>
|
#include <assimp/StreamReader.h>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
@@ -392,13 +388,14 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
|
|||||||
|
|
||||||
if (need_default && materials.size()) {
|
if (need_default && materials.size()) {
|
||||||
ASSIMP_LOG_WARN("MS3D: Found group with no material assigned, spawning default material");
|
ASSIMP_LOG_WARN("MS3D: Found group with no material assigned, spawning default material");
|
||||||
// if one of the groups has no material assigned, but there are other
|
// if one of the groups has no material assigned, but there are other
|
||||||
// groups with materials, a default material needs to be added (
|
// groups with materials, a default material needs to be added (
|
||||||
// scenepreprocessor adds a default material only if nummat==0).
|
// scenepreprocessor adds a default material only if nummat==0).
|
||||||
materials.emplace_back();
|
materials.emplace_back();
|
||||||
TempMaterial& m = materials.back();
|
TempMaterial& m = materials.back();
|
||||||
|
constexpr char DefaultMat[18] = "<MS3D_DefaultMat>";
|
||||||
strcpy(m.name,"<MS3D_DefaultMat>");
|
strncpy(m.name, DefaultMat, sizeof(m.name));
|
||||||
|
m.name[18]='\0';
|
||||||
m.diffuse = aiColor4D(0.6f,0.6f,0.6f,1.0);
|
m.diffuse = aiColor4D(0.6f,0.6f,0.6f,1.0);
|
||||||
m.transparency = 1.f;
|
m.transparency = 1.f;
|
||||||
m.shininess = 0.f;
|
m.shininess = 0.f;
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ const aiImporterDesc *NFFImporter::GetInfo() const {
|
|||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
#define AI_NFF_PARSE_FLOAT(f) \
|
#define AI_NFF_PARSE_FLOAT(f) \
|
||||||
SkipSpaces(&sz, lineEnd); \
|
SkipSpaces(&sz, lineEnd); \
|
||||||
if (!IsLineEnd(*sz)) sz = fast_atoreal_move<ai_real>(sz, (ai_real &)f);
|
if (!IsLineEnd(*sz)) sz = fast_atoreal_move(sz, (ai_real &)f);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
#define AI_NFF_PARSE_TRIPLE(v) \
|
#define AI_NFF_PARSE_TRIPLE(v) \
|
||||||
|
|||||||
@@ -212,14 +212,14 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||||||
// stop at dimensions: this allows loading 1D or 2D coordinate vertices
|
// stop at dimensions: this allows loading 1D or 2D coordinate vertices
|
||||||
for (unsigned int dim = 0; dim < dimensions; ++dim) {
|
for (unsigned int dim = 0; dim < dimensions; ++dim) {
|
||||||
SkipSpaces(&sz, lineEnd);
|
SkipSpaces(&sz, lineEnd);
|
||||||
sz = fast_atoreal_move<ai_real>(sz, *vec[dim]);
|
sz = fast_atoreal_move(sz, *vec[dim]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if has homogeneous coordinate, divide others by this one
|
// if has homogeneous coordinate, divide others by this one
|
||||||
if (hasHomogenous) {
|
if (hasHomogenous) {
|
||||||
SkipSpaces(&sz, lineEnd);
|
SkipSpaces(&sz, lineEnd);
|
||||||
ai_real w = 1.;
|
ai_real w = 1.;
|
||||||
sz = fast_atoreal_move<ai_real>(sz, w);
|
sz = fast_atoreal_move(sz, w);
|
||||||
for (unsigned int dim = 0; dim < dimensions; ++dim) {
|
for (unsigned int dim = 0; dim < dimensions; ++dim) {
|
||||||
*(vec[dim]) /= w;
|
*(vec[dim]) /= w;
|
||||||
}
|
}
|
||||||
@@ -229,11 +229,11 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||||||
if (hasNormals) {
|
if (hasNormals) {
|
||||||
aiVector3D &n = mesh->mNormals[i];
|
aiVector3D &n = mesh->mNormals[i];
|
||||||
SkipSpaces(&sz, lineEnd);
|
SkipSpaces(&sz, lineEnd);
|
||||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)n.x);
|
sz = fast_atoreal_move(sz, n.x);
|
||||||
SkipSpaces(&sz, lineEnd);
|
SkipSpaces(&sz, lineEnd);
|
||||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)n.y);
|
sz = fast_atoreal_move(sz, n.y);
|
||||||
SkipSpaces(&sz, lineEnd);
|
SkipSpaces(&sz, lineEnd);
|
||||||
fast_atoreal_move<ai_real>(sz, (ai_real &)n.z);
|
fast_atoreal_move(sz, n.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
// reading colors is a pain because the specification says it can be
|
// reading colors is a pain because the specification says it can be
|
||||||
@@ -243,22 +243,22 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||||||
if (hasColors) {
|
if (hasColors) {
|
||||||
aiColor4D &c = mesh->mColors[0][i];
|
aiColor4D &c = mesh->mColors[0][i];
|
||||||
SkipSpaces(&sz, lineEnd);
|
SkipSpaces(&sz, lineEnd);
|
||||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)c.r);
|
sz = fast_atoreal_move(sz, c.r);
|
||||||
if (*sz != '#' && *sz != '\n' && *sz != '\r') {
|
if (*sz != '#' && *sz != '\n' && *sz != '\r') {
|
||||||
SkipSpaces(&sz, lineEnd);
|
SkipSpaces(&sz, lineEnd);
|
||||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)c.g);
|
sz = fast_atoreal_move(sz, c.g);
|
||||||
} else {
|
} else {
|
||||||
c.g = 0.;
|
c.g = 0.;
|
||||||
}
|
}
|
||||||
if (*sz != '#' && *sz != '\n' && *sz != '\r') {
|
if (*sz != '#' && *sz != '\n' && *sz != '\r') {
|
||||||
SkipSpaces(&sz, lineEnd);
|
SkipSpaces(&sz, lineEnd);
|
||||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)c.b);
|
sz = fast_atoreal_move(sz, c.b);
|
||||||
} else {
|
} else {
|
||||||
c.b = 0.;
|
c.b = 0.;
|
||||||
}
|
}
|
||||||
if (*sz != '#' && *sz != '\n' && *sz != '\r') {
|
if (*sz != '#' && *sz != '\n' && *sz != '\r') {
|
||||||
SkipSpaces(&sz, lineEnd);
|
SkipSpaces(&sz, lineEnd);
|
||||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)c.a);
|
sz = fast_atoreal_move(sz, c.a);
|
||||||
} else {
|
} else {
|
||||||
c.a = 1.;
|
c.a = 1.;
|
||||||
}
|
}
|
||||||
@@ -266,9 +266,9 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||||||
if (hasTexCoord) {
|
if (hasTexCoord) {
|
||||||
aiVector3D &t = mesh->mTextureCoords[0][i];
|
aiVector3D &t = mesh->mTextureCoords[0][i];
|
||||||
SkipSpaces(&sz, lineEnd);
|
SkipSpaces(&sz, lineEnd);
|
||||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)t.x);
|
sz = fast_atoreal_move(sz, t.x);
|
||||||
SkipSpaces(&sz, lineEnd);
|
SkipSpaces(&sz, lineEnd);
|
||||||
fast_atoreal_move<ai_real>(sz, (ai_real &)t.y);
|
fast_atoreal_move(sz, t.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
|||||||
|
|
||||||
Copyright (c) 2006-2025, assimp team
|
Copyright (c) 2006-2025, 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,
|
||||||
@@ -396,9 +395,12 @@ void ObjExporter::AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4
|
|||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ObjExporter::AddNode(const aiNode* nd, const aiMatrix4x4& mParent, bool merge_identical_vertices) {
|
void ObjExporter::AddNode(const aiNode* nd, const aiMatrix4x4& mParent, bool merge_identical_vertices) {
|
||||||
|
if (nd == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const aiMatrix4x4& mAbs = mParent * nd->mTransformation;
|
const aiMatrix4x4& mAbs = mParent * nd->mTransformation;
|
||||||
|
aiMesh *cm{nullptr};
|
||||||
aiMesh *cm( nullptr );
|
|
||||||
for(unsigned int i = 0; i < nd->mNumMeshes; ++i) {
|
for(unsigned int i = 0; i < nd->mNumMeshes; ++i) {
|
||||||
cm = pScene->mMeshes[nd->mMeshes[i]];
|
cm = pScene->mMeshes[nd->mMeshes[i]];
|
||||||
if (nullptr != cm) {
|
if (nullptr != cm) {
|
||||||
|
|||||||
@@ -165,21 +165,23 @@ struct Material {
|
|||||||
//! Ambient color
|
//! Ambient color
|
||||||
aiColor3D ambient;
|
aiColor3D ambient;
|
||||||
//! Diffuse color
|
//! Diffuse color
|
||||||
aiColor3D diffuse;
|
aiColor3D diffuse = aiColor3D(0.6f, 0.6f, 0.6f);
|
||||||
//! Specular color
|
//! Specular color
|
||||||
aiColor3D specular;
|
aiColor3D specular;
|
||||||
//! Emissive color
|
//! Emissive color
|
||||||
aiColor3D emissive;
|
aiColor3D emissive;
|
||||||
//! Alpha value
|
//! Alpha value
|
||||||
ai_real alpha;
|
ai_real alpha = ai_real(1.0);
|
||||||
//! Shineness factor
|
//! Shineness factor
|
||||||
ai_real shineness;
|
ai_real shineness = ai_real(0.0);
|
||||||
//! Illumination model
|
//! Illumination model
|
||||||
int illumination_model;
|
int illumination_model = 1;
|
||||||
//! Index of refraction
|
//! Index of refraction
|
||||||
ai_real ior;
|
ai_real ior = ai_real(1.0);
|
||||||
//! Transparency color
|
//! Transparency color
|
||||||
aiColor3D transparent;
|
aiColor3D transparent = aiColor3D(1.0f, 1.0f, 1.0f);
|
||||||
|
//! Ambient occlusion
|
||||||
|
Maybe<ai_real> ambient_occlusion;
|
||||||
|
|
||||||
//! PBR Roughness
|
//! PBR Roughness
|
||||||
Maybe<ai_real> roughness;
|
Maybe<ai_real> roughness;
|
||||||
@@ -187,31 +189,33 @@ struct Material {
|
|||||||
Maybe<ai_real> metallic;
|
Maybe<ai_real> metallic;
|
||||||
//! PBR Metallic
|
//! PBR Metallic
|
||||||
Maybe<aiColor3D> sheen;
|
Maybe<aiColor3D> sheen;
|
||||||
|
//! PBR Sheen: an additional grazing component, primarily intended for cloth.
|
||||||
|
Maybe<ai_real> sheen_grazing;
|
||||||
|
//! PBR Sheen Tint: amount to tint sheen towards base color.
|
||||||
|
Maybe<ai_real> sheen_tint;
|
||||||
|
//! PBR Clearcoat
|
||||||
|
Maybe<ai_real> clearcoat;
|
||||||
//! PBR Clearcoat Thickness
|
//! PBR Clearcoat Thickness
|
||||||
Maybe<ai_real> clearcoat_thickness;
|
Maybe<ai_real> clearcoat_thickness;
|
||||||
//! PBR Clearcoat Rougness
|
//! PBR Clearcoat Rougness
|
||||||
Maybe<ai_real> clearcoat_roughness;
|
Maybe<ai_real> clearcoat_roughness;
|
||||||
|
//! PBR clearcoatGloss: controls clearcoat glossiness (0 = a “satin” appearance, 1 = a “gloss” appearance).
|
||||||
|
Maybe<ai_real> clearcoat_gloss;
|
||||||
//! PBR Anisotropy
|
//! PBR Anisotropy
|
||||||
ai_real anisotropy;
|
ai_real anisotropy = ai_real(0.0);
|
||||||
|
//! PBR Anisotropy Rotation
|
||||||
|
Maybe<ai_real> anisotropy_rotation;
|
||||||
|
//! PBR Subsurface Scattering
|
||||||
|
Maybe<ai_real> subsurface_scattering;
|
||||||
|
//! PBR Specular Tint: a concession for artistic control that tints incident specular towards the base color.
|
||||||
|
Maybe<ai_real> specular_tint;
|
||||||
|
// See: https://disneyanimation.com/publications/physically-based-shading-at-disney/
|
||||||
|
|
||||||
//! bump map multipler (normal map scalar)(-bm)
|
//! bump map multiplier (normal map scalar)(-bm)
|
||||||
ai_real bump_multiplier;
|
ai_real bump_multiplier = ai_real(1.0);
|
||||||
|
|
||||||
//! Constructor
|
//! Constructor
|
||||||
Material() :
|
Material() {
|
||||||
diffuse(0.6f, 0.6f, 0.6f),
|
|
||||||
alpha(ai_real(1.0)),
|
|
||||||
shineness(ai_real(0.0)),
|
|
||||||
illumination_model(1),
|
|
||||||
ior(ai_real(1.0)),
|
|
||||||
transparent(1.0f, 1.0, 1.0),
|
|
||||||
roughness(),
|
|
||||||
metallic(),
|
|
||||||
sheen(),
|
|
||||||
clearcoat_thickness(),
|
|
||||||
clearcoat_roughness(),
|
|
||||||
anisotropy(ai_real(0.0)),
|
|
||||||
bump_multiplier(ai_real(1.0)) {
|
|
||||||
std::fill_n(clamp, static_cast<unsigned int>(TextureTypeCount), false);
|
std::fill_n(clamp, static_cast<unsigned int>(TextureTypeCount), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -235,24 +235,64 @@ void ObjFileMtlImporter::load() {
|
|||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
if (m_pModel->mCurrentMaterial != nullptr)
|
if (m_pModel->mCurrentMaterial != nullptr)
|
||||||
getFloatValue(m_pModel->mCurrentMaterial->clearcoat_roughness);
|
getFloatValue(m_pModel->mCurrentMaterial->clearcoat_roughness);
|
||||||
} else {
|
} else if (*m_DataIt == 't') {
|
||||||
|
++m_DataIt;
|
||||||
if (m_pModel->mCurrentMaterial != nullptr)
|
if (m_pModel->mCurrentMaterial != nullptr)
|
||||||
getFloatValue(m_pModel->mCurrentMaterial->clearcoat_thickness);
|
getFloatValue(m_pModel->mCurrentMaterial->clearcoat_thickness);
|
||||||
|
} else {
|
||||||
|
if (m_pModel->mCurrentMaterial != nullptr)
|
||||||
|
getFloatValue(m_pModel->mCurrentMaterial->clearcoat);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'm': // Texture or metallic
|
||||||
|
{
|
||||||
|
// Save start of token (after 'm')
|
||||||
|
auto tokenStart = m_DataIt; // points to 'm'
|
||||||
|
auto tokenEnd = getNextToken(m_DataIt, m_DataItEnd); // move iterator to end of token
|
||||||
|
|
||||||
|
std::string keyword(tokenStart, tokenEnd);
|
||||||
|
m_DataIt = tokenEnd; // advance iterator
|
||||||
|
|
||||||
|
if (keyword.compare(0, 3, "map") == 0) {
|
||||||
|
// starts with "map", treat as texture map
|
||||||
|
m_DataIt = tokenStart;
|
||||||
|
getTexture();
|
||||||
|
} else if (keyword == "metallic" || keyword == "metal" || keyword == "metalness") {
|
||||||
|
// parse metallic float value instead of texture
|
||||||
|
getFloatIfMaterialValid(&ObjFile::Material::metallic);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
||||||
|
} break;
|
||||||
|
|
||||||
case 'm': // Texture
|
|
||||||
case 'b': // quick'n'dirty - for 'bump' sections
|
case 'b': // quick'n'dirty - for 'bump' sections
|
||||||
case 'r': // quick'n'dirty - for 'refl' sections
|
|
||||||
{
|
{
|
||||||
getTexture();
|
getTexture();
|
||||||
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case 'r': // refl (map) or roughness (float)
|
||||||
|
{
|
||||||
|
auto tokenStart = m_DataIt; // points to 'r'
|
||||||
|
auto tokenEnd = getNextToken(m_DataIt, m_DataItEnd);
|
||||||
|
std::string keyword(tokenStart, tokenEnd);
|
||||||
|
m_DataIt = tokenEnd;
|
||||||
|
|
||||||
|
if (keyword == "roughness" || keyword == "rough") {
|
||||||
|
getFloatIfMaterialValid(&ObjFile::Material::roughness);
|
||||||
|
} else if (keyword == "refl" || keyword == "reflection") {
|
||||||
|
m_DataIt = tokenStart;
|
||||||
|
getTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
||||||
|
} break;
|
||||||
|
|
||||||
case 'i': // Illumination model
|
case 'i': // Illumination model
|
||||||
{
|
{
|
||||||
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||||
@@ -261,11 +301,60 @@ void ObjFileMtlImporter::load() {
|
|||||||
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case 'a': // Anisotropy
|
case 'a': {
|
||||||
{
|
auto tokenStart = m_DataIt;
|
||||||
++m_DataIt;
|
auto tokenEnd = getNextToken(m_DataIt, m_DataItEnd);
|
||||||
if (m_pModel->mCurrentMaterial != nullptr)
|
std::string keyword(tokenStart, tokenEnd);
|
||||||
getFloatValue(m_pModel->mCurrentMaterial->anisotropy);
|
m_DataIt = tokenEnd;
|
||||||
|
|
||||||
|
if (keyword == "aniso" || keyword == "anisotropy") {
|
||||||
|
getFloatIfMaterialValid(&ObjFile::Material::anisotropy);
|
||||||
|
} else if (keyword == "ao") {
|
||||||
|
getFloatIfMaterialValid(&ObjFile::Material::ambient_occlusion);
|
||||||
|
} else if (keyword == "anisor" || ai_stdStrToLower(keyword) == "anisotropicrotation") {
|
||||||
|
getFloatIfMaterialValid(&ObjFile::Material::anisotropy_rotation);
|
||||||
|
} else {
|
||||||
|
ASSIMP_LOG_WARN("Unhandled keyword: ", keyword );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case 's': {
|
||||||
|
auto tokenStart = m_DataIt;
|
||||||
|
auto tokenEnd = getNextToken(m_DataIt, m_DataItEnd);
|
||||||
|
std::string keyword(tokenStart, tokenEnd);
|
||||||
|
m_DataIt = tokenEnd;
|
||||||
|
|
||||||
|
if (keyword == "subsurface" || keyword == "scattering") {
|
||||||
|
getFloatIfMaterialValid(&ObjFile::Material::subsurface_scattering);
|
||||||
|
} else if (ai_stdStrToLower(keyword) == "speculartint") {
|
||||||
|
getFloatIfMaterialValid(&ObjFile::Material::specular_tint);
|
||||||
|
} else if (keyword == "sheen") {
|
||||||
|
getFloatIfMaterialValid(&ObjFile::Material::sheen_grazing);
|
||||||
|
} else if (ai_stdStrToLower(keyword) == "sheentint") {
|
||||||
|
getFloatIfMaterialValid(&ObjFile::Material::sheen_tint);
|
||||||
|
} else {
|
||||||
|
ASSIMP_LOG_WARN("Unhandled keyword: ", keyword );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case 'c': {
|
||||||
|
auto tokenStart = m_DataIt;
|
||||||
|
auto tokenEnd = getNextToken(m_DataIt, m_DataItEnd);
|
||||||
|
std::string keyword(tokenStart, tokenEnd);
|
||||||
|
m_DataIt = tokenEnd;
|
||||||
|
|
||||||
|
if (ai_stdStrToLower(keyword) == "clearcoat") {
|
||||||
|
getFloatIfMaterialValid(&ObjFile::Material::clearcoat);
|
||||||
|
} else if (ai_stdStrToLower(keyword) == "clearcoatgloss") {
|
||||||
|
getFloatIfMaterialValid(&ObjFile::Material::clearcoat_gloss);
|
||||||
|
} else {
|
||||||
|
ASSIMP_LOG_WARN("Unhandled keyword: ", keyword );
|
||||||
|
}
|
||||||
|
|
||||||
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@@ -332,6 +421,23 @@ void ObjFileMtlImporter::getFloatValue(Maybe<ai_real> &value) {
|
|||||||
value = Maybe<ai_real>();
|
value = Maybe<ai_real>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// Writes a loaded single float value if material not null
|
||||||
|
void ObjFileMtlImporter::getFloatIfMaterialValid(ai_real ObjFile::Material::*member) {
|
||||||
|
if (m_pModel != nullptr && m_pModel->mCurrentMaterial != nullptr) {
|
||||||
|
// This will call getFloatValue(ai_real&)
|
||||||
|
getFloatValue(m_pModel->mCurrentMaterial->*member);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
void ObjFileMtlImporter::getFloatIfMaterialValid(Maybe<ai_real> ObjFile::Material::*member) {
|
||||||
|
// It can directly access `m_pModel` because it's part of the class
|
||||||
|
if (m_pModel != nullptr && m_pModel->mCurrentMaterial != nullptr) {
|
||||||
|
getFloatValue(m_pModel->mCurrentMaterial->*member);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Creates a material from loaded data.
|
// Creates a material from loaded data.
|
||||||
void ObjFileMtlImporter::createMaterial() {
|
void ObjFileMtlImporter::createMaterial() {
|
||||||
|
|||||||
@@ -87,6 +87,8 @@ private:
|
|||||||
/// Gets a float value from data.
|
/// Gets a float value from data.
|
||||||
void getFloatValue(ai_real &value);
|
void getFloatValue(ai_real &value);
|
||||||
void getFloatValue(Maybe<ai_real> &value);
|
void getFloatValue(Maybe<ai_real> &value);
|
||||||
|
void getFloatIfMaterialValid(ai_real ObjFile::Material::*member);
|
||||||
|
void getFloatIfMaterialValid(Maybe<ai_real> ObjFile::Material::*member);
|
||||||
/// Creates a new material from loaded data.
|
/// Creates a new material from loaded data.
|
||||||
void createMaterial();
|
void createMaterial();
|
||||||
/// Get texture name from loaded data.
|
/// Get texture name from loaded data.
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ ObjFileParser::ObjFileParser(IOStreamBuffer<char> &streamBuffer, const std::stri
|
|||||||
m_buffer(),
|
m_buffer(),
|
||||||
m_pIO(io),
|
m_pIO(io),
|
||||||
m_progress(progress),
|
m_progress(progress),
|
||||||
m_originalObjFileName(originalObjFileName) {
|
m_originalObjFileName(originalObjFileName) {
|
||||||
std::fill_n(m_buffer, Buffersize, '\0');
|
std::fill_n(m_buffer, Buffersize, '\0');
|
||||||
|
|
||||||
// Create the model instance to store all the data
|
// Create the model instance to store all the data
|
||||||
@@ -121,6 +121,13 @@ void ObjFileParser::parseFile(IOStreamBuffer<char> &streamBuffer) {
|
|||||||
m_DataItEnd = buffer.end();
|
m_DataItEnd = buffer.end();
|
||||||
mEnd = &buffer[buffer.size() - 1] + 1;
|
mEnd = &buffer[buffer.size() - 1] + 1;
|
||||||
|
|
||||||
|
if (processed == 0 && std::distance(m_DataIt, m_DataItEnd) >= 3 &&
|
||||||
|
static_cast<unsigned char>(*m_DataIt) == 0xEF &&
|
||||||
|
static_cast<unsigned char>(*(m_DataIt + 1)) == 0xBB &&
|
||||||
|
static_cast<unsigned char>(*(m_DataIt + 2)) == 0xBF) {
|
||||||
|
m_DataIt += 3; // skip BOM
|
||||||
|
}
|
||||||
|
|
||||||
// Handle progress reporting
|
// Handle progress reporting
|
||||||
const size_t filePos(streamBuffer.getFilePos());
|
const size_t filePos(streamBuffer.getFilePos());
|
||||||
if (lastFilePos < filePos) {
|
if (lastFilePos < filePos) {
|
||||||
|
|||||||
@@ -828,13 +828,13 @@ bool PLY::PropertyInstance::ParseValue(const char *&pCur,
|
|||||||
// technically this should cast to float, but people tend to use float descriptors for double data
|
// technically this should cast to float, but people tend to use float descriptors for double data
|
||||||
// this is the best way to not risk losing precision on import and it doesn't hurt to do this
|
// this is the best way to not risk losing precision on import and it doesn't hurt to do this
|
||||||
ai_real f;
|
ai_real f;
|
||||||
pCur = fast_atoreal_move<ai_real>(pCur, f);
|
pCur = fast_atoreal_move(pCur, f);
|
||||||
out->fFloat = (ai_real)f;
|
out->fFloat = (ai_real)f;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EDT_Double:
|
case EDT_Double:
|
||||||
double d;
|
double d;
|
||||||
pCur = fast_atoreal_move<double>(pCur, d);
|
pCur = fast_atoreal_move(pCur, d);
|
||||||
out->fDouble = (double)d;
|
out->fDouble = (double)d;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
static constexpr aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
@@ -309,6 +311,11 @@ void Q3DImporter::InternReadFile(const std::string &pFile,
|
|||||||
throw DeadlyImportError("Quick3D: Invalid texture. Width or height is zero");
|
throw DeadlyImportError("Quick3D: Invalid texture. Width or height is zero");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const unsigned int uint_max = std::numeric_limits<unsigned int>::max();
|
||||||
|
if (tex->mWidth > (uint_max / tex->mHeight)) {
|
||||||
|
throw DeadlyImportError("Quick3D: Texture dimensions are too large, resulting in overflow.");
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int mul = tex->mWidth * tex->mHeight;
|
unsigned int mul = tex->mWidth * tex->mHeight;
|
||||||
aiTexel *begin = tex->pcData = new aiTexel[mul];
|
aiTexel *begin = tex->pcData = new aiTexel[mul];
|
||||||
aiTexel *const end = &begin[mul - 1] + 1;
|
aiTexel *const end = &begin[mul - 1] + 1;
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ void RAWImporter::InternReadFile(const std::string &pFile,
|
|||||||
unsigned int num;
|
unsigned int num;
|
||||||
for (num = 0; num < 12; ++num) {
|
for (num = 0; num < 12; ++num) {
|
||||||
if (!SkipSpaces(&sz, end) || !IsNumeric(*sz)) break;
|
if (!SkipSpaces(&sz, end) || !IsNumeric(*sz)) break;
|
||||||
sz = fast_atoreal_move<float>(sz, data[num]);
|
sz = fast_atoreal_move(sz, data[num]);
|
||||||
}
|
}
|
||||||
if (num != 12 && num != 9) {
|
if (num != 12 && num != 9) {
|
||||||
ASSIMP_LOG_ERROR("A line may have either 9 or 12 floats and an optional texture");
|
ASSIMP_LOG_ERROR("A line may have either 9 or 12 floats and an optional texture");
|
||||||
|
|||||||
@@ -982,7 +982,7 @@ bool SMDImporter::ParseFloat(const char *szCurrent, const char **szCurrentOut, c
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*szCurrentOut = fast_atoreal_move<float>(szCurrent,out);
|
*szCurrentOut = fast_atoreal_move(szCurrent,out);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -404,7 +404,7 @@ std::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*& i
|
|||||||
for(;*cur && *cur != ',' && *cur != ')' && !IsSpace(*cur);++cur) {
|
for(;*cur && *cur != ',' && *cur != ')' && !IsSpace(*cur);++cur) {
|
||||||
if (*cur == '.') {
|
if (*cur == '.') {
|
||||||
double f;
|
double f;
|
||||||
inout = fast_atoreal_move<double>(start,f);
|
inout = fast_atoreal_move(start,f);
|
||||||
return std::make_shared<EXPRESS::REAL>(f);
|
return std::make_shared<EXPRESS::REAL>(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -294,11 +294,11 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
|
|||||||
aiVector3D vn;
|
aiVector3D vn;
|
||||||
sz += 7;
|
sz += 7;
|
||||||
SkipSpaces(&sz, bufferEnd);
|
SkipSpaces(&sz, bufferEnd);
|
||||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn.x);
|
sz = fast_atoreal_move(sz, vn.x);
|
||||||
SkipSpaces(&sz, bufferEnd);
|
SkipSpaces(&sz, bufferEnd);
|
||||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn.y);
|
sz = fast_atoreal_move(sz, vn.y);
|
||||||
SkipSpaces(&sz, bufferEnd);
|
SkipSpaces(&sz, bufferEnd);
|
||||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn.z);
|
sz = fast_atoreal_move(sz, vn.z);
|
||||||
normalBuffer.emplace_back(vn);
|
normalBuffer.emplace_back(vn);
|
||||||
normalBuffer.emplace_back(vn);
|
normalBuffer.emplace_back(vn);
|
||||||
normalBuffer.emplace_back(vn);
|
normalBuffer.emplace_back(vn);
|
||||||
@@ -315,11 +315,11 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
|
|||||||
SkipSpaces(&sz, bufferEnd);
|
SkipSpaces(&sz, bufferEnd);
|
||||||
positionBuffer.emplace_back();
|
positionBuffer.emplace_back();
|
||||||
aiVector3D *vn = &positionBuffer.back();
|
aiVector3D *vn = &positionBuffer.back();
|
||||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn->x);
|
sz = fast_atoreal_move(sz, vn->x);
|
||||||
SkipSpaces(&sz, bufferEnd);
|
SkipSpaces(&sz, bufferEnd);
|
||||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn->y);
|
sz = fast_atoreal_move(sz, vn->y);
|
||||||
SkipSpaces(&sz, bufferEnd);
|
SkipSpaces(&sz, bufferEnd);
|
||||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn->z);
|
sz = fast_atoreal_move(sz, vn->z);
|
||||||
faceVertexCounter++;
|
faceVertexCounter++;
|
||||||
}
|
}
|
||||||
} else if (!::strncmp(sz, "endsolid", 8)) {
|
} else if (!::strncmp(sz, "endsolid", 8)) {
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
# pragma warning(disable : 4127 4456 4245 4512 )
|
# pragma warning(disable : 4127 4456 4245 4512 )
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
#if _MSC_VER > 1500 || (defined __GNUC___)
|
#if _MSC_VER > 1500 || (defined __GNUC__)
|
||||||
# define ASSIMP_STEP_USE_UNORDERED_MULTIMAP
|
# define ASSIMP_STEP_USE_UNORDERED_MULTIMAP
|
||||||
#else
|
#else
|
||||||
# define step_unordered_map map
|
# define step_unordered_map map
|
||||||
@@ -919,6 +919,10 @@ private:
|
|||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
|
#if _MSC_VER > 1920
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace STEP
|
} // namespace STEP
|
||||||
} // namespace Assimp
|
} // namespace Assimp
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
//
|
//
|
||||||
#if _MSC_VER > 1500 || (defined __GNUC___)
|
#if _MSC_VER > 1500 || (defined __GNUC__)
|
||||||
# define ASSIMP_STEP_USE_UNORDERED_MULTIMAP
|
# define ASSIMP_STEP_USE_UNORDERED_MULTIMAP
|
||||||
# else
|
# else
|
||||||
# define step_unordered_map map
|
# define step_unordered_map map
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "assimp/MemoryIOWrapper.h"
|
#include "assimp/MemoryIOWrapper.h"
|
||||||
#include <assimp/StringUtils.h>
|
#include <assimp/StringUtils.h>
|
||||||
#include <assimp/StreamReader.h>
|
#include <assimp/StreamReader.h>
|
||||||
|
#include <assimp/metadata.h>
|
||||||
|
|
||||||
#include "io-util.hh" // namespace tinyusdz::io
|
#include "io-util.hh" // namespace tinyusdz::io
|
||||||
#include "tydra/scene-access.hh"
|
#include "tydra/scene-access.hh"
|
||||||
@@ -219,6 +220,9 @@ void USDImporterImplTinyusdz::InternReadFile(
|
|||||||
textures(render_scene, pScene, nameWExt);
|
textures(render_scene, pScene, nameWExt);
|
||||||
textureImages(render_scene, pScene, nameWExt);
|
textureImages(render_scene, pScene, nameWExt);
|
||||||
buffers(render_scene, pScene, nameWExt);
|
buffers(render_scene, pScene, nameWExt);
|
||||||
|
|
||||||
|
std::map<size_t, tinyusdz::tydra::Node> meshNodes;
|
||||||
|
setupNodes(render_scene, pScene, stage, meshNodes, nameWExt);
|
||||||
pScene->mRootNode = nodesRecursive(nullptr, render_scene.nodes[0], render_scene.skeletons);
|
pScene->mRootNode = nodesRecursive(nullptr, render_scene.nodes[0], render_scene.skeletons);
|
||||||
|
|
||||||
setupBlendShapes(render_scene, pScene, nameWExt);
|
setupBlendShapes(render_scene, pScene, nameWExt);
|
||||||
@@ -798,11 +802,50 @@ void USDImporterImplTinyusdz::buffers(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void USDImporterImplTinyusdz::setupNodes(
|
||||||
|
const tinyusdz::tydra::RenderScene &render_scene,
|
||||||
|
aiScene *pScene,
|
||||||
|
const tinyusdz::Stage &usdStage,
|
||||||
|
std::map<size_t, tinyusdz::tydra::Node> &meshNodes,
|
||||||
|
const std::string &nameWExt) {
|
||||||
|
stringstream ss;
|
||||||
|
|
||||||
|
pScene->mRootNode = nodes(render_scene, usdStage, meshNodes, nameWExt);
|
||||||
|
pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
|
||||||
|
pScene->mRootNode->mMeshes = new unsigned int[pScene->mRootNode->mNumMeshes];
|
||||||
|
ss.str("");
|
||||||
|
ss << "setupNodes(): pScene->mNumMeshes: " << pScene->mNumMeshes;
|
||||||
|
if (pScene->mRootNode != nullptr) {
|
||||||
|
ss << ", mRootNode->mNumMeshes: " << pScene->mRootNode->mNumMeshes;
|
||||||
|
}
|
||||||
|
TINYUSDZLOGD(TAG, "%s", ss.str().c_str());
|
||||||
|
|
||||||
|
for (unsigned int meshIdx = 0; meshIdx < pScene->mNumMeshes; meshIdx++) {
|
||||||
|
pScene->mRootNode->mMeshes[meshIdx] = meshIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
aiNode *USDImporterImplTinyusdz::nodes(
|
||||||
|
const tinyusdz::tydra::RenderScene &render_scene,
|
||||||
|
const tinyusdz::Stage &usdStage,
|
||||||
|
std::map<size_t, tinyusdz::tydra::Node> &meshNodes,
|
||||||
|
const std::string &nameWExt) {
|
||||||
|
const size_t numNodes{render_scene.nodes.size()};
|
||||||
|
(void) numNodes; // Ignore unused variable when -Werror enabled
|
||||||
|
stringstream ss;
|
||||||
|
ss.str("");
|
||||||
|
ss << "nodes(): model" << nameWExt << ", numNodes: " << numNodes;
|
||||||
|
TINYUSDZLOGD(TAG, "%s", ss.str().c_str());
|
||||||
|
return nodesRecursive(nullptr, usdStage.root_prims()[0], render_scene.nodes[0], meshNodes);
|
||||||
|
}
|
||||||
|
|
||||||
using Assimp::tinyusdzNodeTypeFor;
|
using Assimp::tinyusdzNodeTypeFor;
|
||||||
using Assimp::tinyUsdzMat4ToAiMat4;
|
using Assimp::tinyUsdzMat4ToAiMat4;
|
||||||
using tinyusdz::tydra::NodeType;
|
using tinyusdz::tydra::NodeType;
|
||||||
aiNode *USDImporterImplTinyusdz::nodesRecursive(
|
aiNode *USDImporterImplTinyusdz::nodesRecursive(
|
||||||
aiNode *pNodeParent,
|
aiNode *pNodeParent,
|
||||||
|
const tinyusdz::Prim& prim,
|
||||||
const tinyusdz::tydra::Node &node,
|
const tinyusdz::tydra::Node &node,
|
||||||
const std::vector<tinyusdz::tydra::SkelHierarchy> &skeletons) {
|
const std::vector<tinyusdz::tydra::SkelHierarchy> &skeletons) {
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
@@ -844,6 +887,22 @@ aiNode *USDImporterImplTinyusdz::nodesRecursive(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Composition: references
|
||||||
|
if (prim.metas().references.has_value())
|
||||||
|
{
|
||||||
|
const tinyusdz::ListEditQual referenceQual = prim.metas().references->first;
|
||||||
|
const std::vector<tinyusdz::Reference> references = prim.metas().references->second;
|
||||||
|
|
||||||
|
for (const auto &reference : references)
|
||||||
|
{
|
||||||
|
cNode->mMetaData = aiMetadata::Alloc(1);
|
||||||
|
cNode->mMetaData->Add("ref", aiString(reference.asset_path.GetAssetPath()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t i{0};
|
||||||
|
for (const auto &childNode: node.children) {
|
||||||
|
cNode->mChildren[i] = nodesRecursive(cNode, prim.children()[i], childNode, meshNodes);
|
||||||
cNode->mNumChildren = numChildren;
|
cNode->mNumChildren = numChildren;
|
||||||
|
|
||||||
// Done. No more children.
|
// Done. No more children.
|
||||||
|
|||||||
@@ -124,8 +124,23 @@ public:
|
|||||||
aiScene *pScene,
|
aiScene *pScene,
|
||||||
const std::string &nameWExt);
|
const std::string &nameWExt);
|
||||||
|
|
||||||
|
void setupNodes(
|
||||||
|
const tinyusdz::tydra::RenderScene &render_scene,
|
||||||
|
aiScene *pScene,
|
||||||
|
const tinyusdz::Stage &usdStage,
|
||||||
|
std::map<size_t, tinyusdz::tydra::Node> &meshNodes,
|
||||||
|
const std::string &nameWExt
|
||||||
|
);
|
||||||
|
|
||||||
|
aiNode *nodes(
|
||||||
|
const tinyusdz::tydra::RenderScene &render_scene,
|
||||||
|
const tinyusdz::Stage &usdStage,
|
||||||
|
std::map<size_t, tinyusdz::tydra::Node> &meshNodes,
|
||||||
|
const std::string &nameWExt);
|
||||||
|
|
||||||
aiNode *nodesRecursive(
|
aiNode *nodesRecursive(
|
||||||
aiNode *pNodeParent,
|
aiNode *pNodeParent,
|
||||||
|
const tinyusdz::Prim &prim,
|
||||||
const tinyusdz::tydra::Node &node,
|
const tinyusdz::tydra::Node &node,
|
||||||
const std::vector<tinyusdz::tydra::SkelHierarchy> &skeletons);
|
const std::vector<tinyusdz::tydra::SkelHierarchy> &skeletons);
|
||||||
|
|
||||||
|
|||||||
@@ -383,11 +383,11 @@ void UnrealImporter::InternReadFile(const std::string &pFile,
|
|||||||
|
|
||||||
for (; !IsLineEnd(*data); ++data) {
|
for (; !IsLineEnd(*data); ++data) {
|
||||||
if (data[0] == 'X' && data[1] == '=') {
|
if (data[0] == 'X' && data[1] == '=') {
|
||||||
data = fast_atoreal_move<float>(data + 2, (float &)nd->mTransformation.a1);
|
data = fast_atoreal_move(data + 2, nd->mTransformation.a1);
|
||||||
} else if (data[0] == 'Y' && data[1] == '=') {
|
} else if (data[0] == 'Y' && data[1] == '=') {
|
||||||
data = fast_atoreal_move<float>(data + 2, (float &)nd->mTransformation.b2);
|
data = fast_atoreal_move(data + 2, nd->mTransformation.b2);
|
||||||
} else if (data[0] == 'Z' && data[1] == '=') {
|
} else if (data[0] == 'Z' && data[1] == '=') {
|
||||||
data = fast_atoreal_move<float>(data + 2, (float &)nd->mTransformation.c3);
|
data = fast_atoreal_move(data + 2, nd->mTransformation.c3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#if !defined(ASSIMP_BUILD_NO_VRML_IMPORTER)
|
#if !defined(ASSIMP_BUILD_NO_VRML_IMPORTER)
|
||||||
#include "contrib/meshlab/autoclone/meshlab_repo-src/src/meshlabplugins/io_x3d/vrml/Parser.h"
|
#include "meshlabplugins/io_x3d/vrml/Parser.h"
|
||||||
#endif // #if !defined(ASSIMP_BUILD_NO_VRML_IMPORTER)
|
#endif // #if !defined(ASSIMP_BUILD_NO_VRML_IMPORTER)
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|||||||
@@ -1277,7 +1277,7 @@ ai_real XFileParser::ReadFloat() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ai_real result = 0.0;
|
ai_real result = 0.0;
|
||||||
mP = fast_atoreal_move<ai_real>(mP, result);
|
mP = fast_atoreal_move(mP, result);
|
||||||
|
|
||||||
CheckForSeparator();
|
CheckForSeparator();
|
||||||
|
|
||||||
|
|||||||
@@ -128,13 +128,17 @@ void X3DGeoHelper::rect_parallel_epiped(const aiVector3D &pSize, std::list<aiVec
|
|||||||
|
|
||||||
#undef MESH_RectParallelepiped_CREATE_VERT
|
#undef MESH_RectParallelepiped_CREATE_VERT
|
||||||
|
|
||||||
|
static constexpr int InvalidIndex = -1;
|
||||||
|
|
||||||
void X3DGeoHelper::coordIdx_str2faces_arr(const std::vector<int32_t> &pCoordIdx, std::vector<aiFace> &pFaces, unsigned int &pPrimitiveTypes) {
|
void X3DGeoHelper::coordIdx_str2faces_arr(const std::vector<int32_t> &pCoordIdx, std::vector<aiFace> &pFaces, unsigned int &pPrimitiveTypes) {
|
||||||
std::vector<int32_t> f_data(pCoordIdx);
|
std::vector<int32_t> f_data(pCoordIdx);
|
||||||
std::vector<unsigned int> inds;
|
std::vector<unsigned int> inds;
|
||||||
unsigned int prim_type = 0;
|
unsigned int prim_type = 0;
|
||||||
|
|
||||||
if (f_data.back() != (-1)) {
|
if (!f_data.empty()) {
|
||||||
f_data.push_back(-1);
|
if (f_data.back() != InvalidIndex) {
|
||||||
|
f_data.push_back(InvalidIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// reserve average size.
|
// reserve average size.
|
||||||
@@ -191,8 +195,10 @@ mg_m_err:
|
|||||||
void X3DGeoHelper::coordIdx_str2lines_arr(const std::vector<int32_t> &pCoordIdx, std::vector<aiFace> &pFaces) {
|
void X3DGeoHelper::coordIdx_str2lines_arr(const std::vector<int32_t> &pCoordIdx, std::vector<aiFace> &pFaces) {
|
||||||
std::vector<int32_t> f_data(pCoordIdx);
|
std::vector<int32_t> f_data(pCoordIdx);
|
||||||
|
|
||||||
if (f_data.back() != (-1)) {
|
if (!f_data.empty()) {
|
||||||
f_data.push_back(-1);
|
if (f_data.back() != InvalidIndex) {
|
||||||
|
f_data.push_back(InvalidIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// reserve average size.
|
// reserve average size.
|
||||||
|
|||||||
@@ -49,8 +49,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#ifndef GLTFASSET_H_INC
|
#ifndef GLTFASSET_H_INC
|
||||||
#define GLTFASSET_H_INC
|
#define GLTFASSET_H_INC
|
||||||
|
|
||||||
#if !defined(ASSIMP_BUILD_NO_GLTF_IMPORTER) && !defined(ASSIMP_BUILD_NO_GLTF1_IMPORTER)
|
|
||||||
|
|
||||||
#include "AssetLib/glTFCommon/glTFCommon.h"
|
#include "AssetLib/glTFCommon/glTFCommon.h"
|
||||||
#include <assimp/Exceptional.h>
|
#include <assimp/Exceptional.h>
|
||||||
#include <list>
|
#include <list>
|
||||||
@@ -83,7 +81,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if _MSC_VER > 1500 || (defined __GNUC___)
|
#if _MSC_VER > 1500 || (defined __GNUC__)
|
||||||
# define ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
|
# define ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
|
||||||
# else
|
# else
|
||||||
# define gltf_unordered_map map
|
# define gltf_unordered_map map
|
||||||
@@ -1008,6 +1006,4 @@ private:
|
|||||||
// Include the implementation of the methods
|
// Include the implementation of the methods
|
||||||
#include "glTFAsset.inl"
|
#include "glTFAsset.inl"
|
||||||
|
|
||||||
#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
|
|
||||||
|
|
||||||
#endif // GLTFASSET_H_INC
|
#endif // GLTFASSET_H_INC
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#ifndef GLTFASSETWRITER_H_INC
|
#ifndef GLTFASSETWRITER_H_INC
|
||||||
#define GLTFASSETWRITER_H_INC
|
#define GLTFASSETWRITER_H_INC
|
||||||
|
|
||||||
#if !defined(ASSIMP_BUILD_NO_GLTF_IMPORTER) && !defined(ASSIMP_BUILD_NO_GLTF1_IMPORTER)
|
//#if !defined(ASSIMP_BUILD_NO_GLTF_IMPORTER) && !defined(ASSIMP_BUILD_NO_GLTF1_IMPORTER)
|
||||||
|
|
||||||
#include "glTFAsset.h"
|
#include "glTFAsset.h"
|
||||||
|
|
||||||
@@ -63,16 +63,6 @@ class AssetWriter
|
|||||||
template<class T>
|
template<class T>
|
||||||
friend void WriteLazyDict(LazyDict<T>& d, AssetWriter& w);
|
friend void WriteLazyDict(LazyDict<T>& d, AssetWriter& w);
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void WriteBinaryData(IOStream* outfile, size_t sceneLength);
|
|
||||||
|
|
||||||
void WriteMetadata();
|
|
||||||
void WriteExtensionsUsed();
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
void WriteObjects(LazyDict<T>& d);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Document mDoc;
|
Document mDoc;
|
||||||
Asset& mAsset;
|
Asset& mAsset;
|
||||||
@@ -80,9 +70,19 @@ public:
|
|||||||
MemoryPoolAllocator<>& mAl;
|
MemoryPoolAllocator<>& mAl;
|
||||||
|
|
||||||
AssetWriter(Asset& asset);
|
AssetWriter(Asset& asset);
|
||||||
|
~AssetWriter() = default;
|
||||||
|
|
||||||
void WriteFile(const char* path);
|
void WriteFile(const char* path);
|
||||||
void WriteGLBFile(const char* path);
|
void WriteGLBFile(const char* path);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void WriteBinaryData(IOStream* outfile, size_t sceneLength);
|
||||||
|
|
||||||
|
void WriteMetadata();
|
||||||
|
void WriteExtensionsUsed();
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void WriteObjects(LazyDict<T>& d);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -90,6 +90,6 @@ public:
|
|||||||
// Include the implementation of the methods
|
// Include the implementation of the methods
|
||||||
#include "glTFAssetWriter.inl"
|
#include "glTFAssetWriter.inl"
|
||||||
|
|
||||||
#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
|
//#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
|
||||||
|
|
||||||
#endif // GLTFASSETWRITER_H_INC
|
#endif // GLTFASSETWRITER_H_INC
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER
|
||||||
|
|
||||||
#include "AssetLib/glTF/glTFExporter.h"
|
#include "AssetLib/glTF/glTFExporter.h"
|
||||||
|
#include "AssetLib/glTF/glTFAsset.h"
|
||||||
#include "AssetLib/glTF/glTFAssetWriter.h"
|
#include "AssetLib/glTF/glTFAssetWriter.h"
|
||||||
#include "PostProcessing/SplitLargeMeshes.h"
|
#include "PostProcessing/SplitLargeMeshes.h"
|
||||||
|
|
||||||
@@ -62,6 +63,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#include <rapidjson/rapidjson.h>
|
||||||
|
#include <rapidjson/document.h>
|
||||||
|
#include <rapidjson/error/en.h>
|
||||||
|
|
||||||
#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
|
#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
|
||||||
// Header files, Open3DGC.
|
// Header files, Open3DGC.
|
||||||
# include <Open3DGC/o3dgcSC3DMCEncoder.h>
|
# include <Open3DGC/o3dgcSC3DMCEncoder.h>
|
||||||
@@ -1064,6 +1069,5 @@ void glTFExporter::ExportAnimations()
|
|||||||
} // End: for-loop mNumAnimations
|
} // End: for-loop mNumAnimations
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // ASSIMP_BUILD_NO_GLTF_EXPORTER
|
#endif // ASSIMP_BUILD_NO_GLTF_EXPORTER
|
||||||
#endif // ASSIMP_BUILD_NO_EXPORT
|
#endif // ASSIMP_BUILD_NO_EXPORT
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user