Merge branch 'master' into clang-cl-15.0.1-support
commit
85b470a3ee
|
@ -57,3 +57,13 @@ jobs:
|
||||||
- name: test
|
- name: test
|
||||||
run: cd build/bin && ./unit
|
run: cd build/bin && ./unit
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
|
job3:
|
||||||
|
name: printf-sanitizer
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: run scan_printf script
|
||||||
|
run: ./scripts/scan_printf.sh
|
||||||
|
shell: bash
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
We as members, contributors, and leaders pledge to make participation in our
|
||||||
|
community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||||
|
identity and expression, level of experience, education, socio-economic status,
|
||||||
|
nationality, personal appearance, race, religion, or sexual identity
|
||||||
|
and orientation.
|
||||||
|
|
||||||
|
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||||
|
diverse, inclusive, and healthy community.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to a positive environment for our
|
||||||
|
community include:
|
||||||
|
|
||||||
|
* Demonstrating empathy and kindness toward other people
|
||||||
|
* Being respectful of differing opinions, viewpoints, and experiences
|
||||||
|
* Giving and gracefully accepting constructive feedback
|
||||||
|
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||||
|
and learning from the experience
|
||||||
|
* Focusing on what is best not just for us as individuals, but for the
|
||||||
|
overall community
|
||||||
|
|
||||||
|
Examples of unacceptable behavior include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery, and sexual attention or
|
||||||
|
advances of any kind
|
||||||
|
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or email
|
||||||
|
address, without their explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Enforcement Responsibilities
|
||||||
|
|
||||||
|
Community leaders are responsible for clarifying and enforcing our standards of
|
||||||
|
acceptable behavior and will take appropriate and fair corrective action in
|
||||||
|
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||||
|
or harmful.
|
||||||
|
|
||||||
|
Community leaders have the right and responsibility to remove, edit, or reject
|
||||||
|
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||||
|
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||||
|
decisions when appropriate.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies within all community spaces, and also applies when
|
||||||
|
an individual is officially representing the community in public spaces.
|
||||||
|
Examples of representing our community include using an official e-mail address,
|
||||||
|
posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported to the community leaders responsible for enforcement at
|
||||||
|
.
|
||||||
|
All complaints will be reviewed and investigated promptly and fairly.
|
||||||
|
|
||||||
|
All community leaders are obligated to respect the privacy and security of the
|
||||||
|
reporter of any incident.
|
||||||
|
|
||||||
|
## Enforcement Guidelines
|
||||||
|
|
||||||
|
Community leaders will follow these Community Impact Guidelines in determining
|
||||||
|
the consequences for any action they deem in violation of this Code of Conduct:
|
||||||
|
|
||||||
|
### 1. Correction
|
||||||
|
|
||||||
|
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||||
|
unprofessional or unwelcome in the community.
|
||||||
|
|
||||||
|
**Consequence**: A private, written warning from community leaders, providing
|
||||||
|
clarity around the nature of the violation and an explanation of why the
|
||||||
|
behavior was inappropriate. A public apology may be requested.
|
||||||
|
|
||||||
|
### 2. Warning
|
||||||
|
|
||||||
|
**Community Impact**: A violation through a single incident or series
|
||||||
|
of actions.
|
||||||
|
|
||||||
|
**Consequence**: A warning with consequences for continued behavior. No
|
||||||
|
interaction with the people involved, including unsolicited interaction with
|
||||||
|
those enforcing the Code of Conduct, for a specified period of time. This
|
||||||
|
includes avoiding interactions in community spaces as well as external channels
|
||||||
|
like social media. Violating these terms may lead to a temporary or
|
||||||
|
permanent ban.
|
||||||
|
|
||||||
|
### 3. Temporary Ban
|
||||||
|
|
||||||
|
**Community Impact**: A serious violation of community standards, including
|
||||||
|
sustained inappropriate behavior.
|
||||||
|
|
||||||
|
**Consequence**: A temporary ban from any sort of interaction or public
|
||||||
|
communication with the community for a specified period of time. No public or
|
||||||
|
private interaction with the people involved, including unsolicited interaction
|
||||||
|
with those enforcing the Code of Conduct, is allowed during this period.
|
||||||
|
Violating these terms may lead to a permanent ban.
|
||||||
|
|
||||||
|
### 4. Permanent Ban
|
||||||
|
|
||||||
|
**Community Impact**: Demonstrating a pattern of violation of community
|
||||||
|
standards, including sustained inappropriate behavior, harassment of an
|
||||||
|
individual, or aggression toward or disparagement of classes of individuals.
|
||||||
|
|
||||||
|
**Consequence**: A permanent ban from any sort of public interaction within
|
||||||
|
the community.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||||
|
version 2.0, available at
|
||||||
|
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||||
|
|
||||||
|
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||||
|
enforcement ladder](https://github.com/mozilla/diversity).
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see the FAQ at
|
||||||
|
https://www.contributor-covenant.org/faq. Translations are available at
|
||||||
|
https://www.contributor-covenant.org/translations.
|
41
Readme.md
41
Readme.md
|
@ -1,6 +1,8 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
==================================
|
==================================
|
||||||
A library to import and export various 3d-model-formats including scene-post-processing to generate missing render data.
|
|
||||||
|
Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
|
||||||
|
|
||||||
### Current project status ###
|
### Current project status ###
|
||||||
[![Financial Contributors on Open Collective](https://opencollective.com/assimp/all/badge.svg?label=financial+contributors)](https://opencollective.com/assimp)
|
[![Financial Contributors on Open Collective](https://opencollective.com/assimp/all/badge.svg?label=financial+contributors)](https://opencollective.com/assimp)
|
||||||
![C/C++ CI](https://github.com/assimp/assimp/workflows/C/C++%20CI/badge.svg)
|
![C/C++ CI](https://github.com/assimp/assimp/workflows/C/C++%20CI/badge.svg)
|
||||||
|
@ -14,7 +16,6 @@ A library to import and export various 3d-model-formats including scene-post-pro
|
||||||
[![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue")
|
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue")
|
||||||
[![Percentage of issues still open](http://isitmaintained.com/badge/open/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Percentage of issues still open")
|
[![Percentage of issues still open](http://isitmaintained.com/badge/open/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Percentage of issues still open")
|
||||||
[![Total alerts](https://img.shields.io/lgtm/alerts/g/assimp/assimp.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/assimp/assimp/alerts/)
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
|
APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
|
||||||
|
@ -23,15 +24,19 @@ Additionally, assimp features various __mesh post processing tools__: normals an
|
||||||
### Latest Doc's ###
|
### Latest Doc's ###
|
||||||
Please check the latest documents at [Asset-Importer-Lib-Doc](https://assimp-docs.readthedocs.io/en/latest/).
|
Please check the latest documents at [Asset-Importer-Lib-Doc](https://assimp-docs.readthedocs.io/en/latest/).
|
||||||
|
|
||||||
### Get involved ###
|
### Prebuild binaries ###
|
||||||
This is the development repo containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [Github Assimp Releases](https://github.com/assimp/assimp/releases).
|
Please check our [Itchi Projectspace](https://kimkulling.itch.io/the-asset-importer-lib)
|
||||||
<br>
|
|
||||||
You find a bug in the docs? Use [Doc-Repo](https://github.com/assimp/assimp-docs).
|
|
||||||
<br>
|
|
||||||
Please check our Wiki as well: https://github.com/assimp/assimp/wiki
|
|
||||||
|
|
||||||
If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
|
If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
|
||||||
|
|
||||||
|
### Communities ###
|
||||||
|
- Ask a question at [The Assimp-Discussion Board](https://github.com/assimp/assimp/discussions)
|
||||||
|
- Ask on [Assimp-Community on Reddit](https://www.reddit.com/r/Assimp/)
|
||||||
|
- Ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest).
|
||||||
|
- Nothing has worked? File a question or an issue-report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues)
|
||||||
|
|
||||||
|
And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
|
||||||
|
|
||||||
#### Supported file formats ####
|
#### Supported file formats ####
|
||||||
You can find the complete list of supported file-formats [here](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md)
|
You can find the complete list of supported file-formats [here](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md)
|
||||||
|
|
||||||
|
@ -66,28 +71,18 @@ Open Asset Import Library is implemented in C++. The directory structure looks l
|
||||||
/port Ports to other languages and scripts to maintain those.
|
/port Ports to other languages and scripts to maintain those.
|
||||||
/test Unit- and regression tests, test suite of models
|
/test Unit- and regression tests, test suite of models
|
||||||
/tools Tools (old assimp viewer, command line `assimp`)
|
/tools Tools (old assimp viewer, command line `assimp`)
|
||||||
/samples A small number of samples to illustrate possible
|
/samples A small number of samples to illustrate possible use-cases for Assimp
|
||||||
use cases for Assimp
|
|
||||||
|
|
||||||
The source code is organized in the following way:
|
The source code is organized in the following way:
|
||||||
|
|
||||||
code/Common The base implementation for importers and the infrastructure
|
code/Common The base implementation for importers and the infrastructure
|
||||||
|
code/CApi Special implementations which are only used for the C-API
|
||||||
|
code/Geometry A collection of geometry tools
|
||||||
|
code/Material The material system
|
||||||
|
code/PBR An exporter for physical based models
|
||||||
code/PostProcessing The post-processing steps
|
code/PostProcessing The post-processing steps
|
||||||
code/AssetLib/<FormatName> Implementation for import and export for the format
|
code/AssetLib/<FormatName> Implementation for import and export for the format
|
||||||
|
|
||||||
### Where to get help ###
|
|
||||||
To find our documentation, visit [our website](https://assimp.org/) or check out [Wiki](https://github.com/assimp/assimp/wiki)
|
|
||||||
|
|
||||||
If the docs don't solve your problem, you can:
|
|
||||||
- Ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest).
|
|
||||||
- Ask on [Assimp-Community on Reddit](https://www.reddit.com/r/Assimp/)
|
|
||||||
- Ask a question at [The Assimp-Discussion Board](https://github.com/assimp/assimp/discussions)
|
|
||||||
- Nothing has worked? File a question or an issue-report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues)
|
|
||||||
|
|
||||||
Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
|
|
||||||
|
|
||||||
And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
|
|
||||||
|
|
||||||
### Contributing ###
|
### Contributing ###
|
||||||
Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
|
Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
|
||||||
a pull request with your changes against the main repository's `master` branch.
|
a pull request with your changes against the main repository's `master` branch.
|
||||||
|
|
|
@ -815,6 +815,7 @@ nl_clean_loop:
|
||||||
for (; next_it != nodeArray.end(); ++next_it) {
|
for (; next_it != nodeArray.end(); ++next_it) {
|
||||||
if ((*next_it)->FindNode((*nl_it)->mName) != nullptr) {
|
if ((*next_it)->FindNode((*nl_it)->mName) != nullptr) {
|
||||||
// if current top node(nl_it) found in another top node then erase it from node_list and restart search loop.
|
// if current top node(nl_it) found in another top node then erase it from node_list and restart search loop.
|
||||||
|
// FIXME: this leaks memory on test models test8.amf and test9.amf
|
||||||
nodeArray.erase(nl_it);
|
nodeArray.erase(nl_it);
|
||||||
|
|
||||||
goto nl_clean_loop;
|
goto nl_clean_loop;
|
||||||
|
|
|
@ -569,7 +569,7 @@ void Structure ::Convert<MVert>(
|
||||||
const FileDatabase &db) const {
|
const FileDatabase &db) const {
|
||||||
|
|
||||||
ReadFieldArray<ErrorPolicy_Fail>(dest.co, "co", db);
|
ReadFieldArray<ErrorPolicy_Fail>(dest.co, "co", db);
|
||||||
ReadFieldArray<ErrorPolicy_Fail>(dest.no, "no", db);
|
ReadFieldArray<ErrorPolicy_Warn>(dest.no, "no", db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.flag, "flag", db);
|
ReadField<ErrorPolicy_Igno>(dest.flag, "flag", db);
|
||||||
//ReadField<ErrorPolicy_Warn>(dest.mat_nr,"mat_nr",db);
|
//ReadField<ErrorPolicy_Warn>(dest.mat_nr,"mat_nr",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.bweight, "bweight", db);
|
ReadField<ErrorPolicy_Igno>(dest.bweight, "bweight", db);
|
||||||
|
|
|
@ -873,8 +873,12 @@ void FBXConverter::SetupNodeMetadata(const Model &model, aiNode &nd) {
|
||||||
data->Set(index++, prop.first, interpretedBool->Value());
|
data->Set(index++, prop.first, interpretedBool->Value());
|
||||||
} else if (const TypedProperty<int> *interpretedInt = prop.second->As<TypedProperty<int>>()) {
|
} else if (const TypedProperty<int> *interpretedInt = prop.second->As<TypedProperty<int>>()) {
|
||||||
data->Set(index++, prop.first, interpretedInt->Value());
|
data->Set(index++, prop.first, interpretedInt->Value());
|
||||||
|
} else if (const TypedProperty<uint32_t> *interpretedUInt = prop.second->As<TypedProperty<uint32_t>>()) {
|
||||||
|
data->Set(index++, prop.first, interpretedUInt->Value());
|
||||||
} else if (const TypedProperty<uint64_t> *interpretedUint64 = prop.second->As<TypedProperty<uint64_t>>()) {
|
} else if (const TypedProperty<uint64_t> *interpretedUint64 = prop.second->As<TypedProperty<uint64_t>>()) {
|
||||||
data->Set(index++, prop.first, interpretedUint64->Value());
|
data->Set(index++, prop.first, interpretedUint64->Value());
|
||||||
|
} else if (const TypedProperty<int64_t> *interpretedint64 = prop.second->As<TypedProperty<int64_t>>()) {
|
||||||
|
data->Set(index++, prop.first, interpretedint64->Value());
|
||||||
} else if (const TypedProperty<float> *interpretedFloat = prop.second->As<TypedProperty<float>>()) {
|
} else if (const TypedProperty<float> *interpretedFloat = prop.second->As<TypedProperty<float>>()) {
|
||||||
data->Set(index++, prop.first, interpretedFloat->Value());
|
data->Set(index++, prop.first, interpretedFloat->Value());
|
||||||
} else if (const TypedProperty<std::string> *interpretedString = prop.second->As<TypedProperty<std::string>>()) {
|
} else if (const TypedProperty<std::string> *interpretedString = prop.second->As<TypedProperty<std::string>>()) {
|
||||||
|
@ -1176,15 +1180,23 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
|
||||||
std::vector<aiAnimMesh *> animMeshes;
|
std::vector<aiAnimMesh *> animMeshes;
|
||||||
for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
|
for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
|
||||||
for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
|
for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
|
||||||
const std::vector<const ShapeGeometry *> &shapeGeometries = blendShapeChannel->GetShapeGeometries();
|
const auto& shapeGeometries = blendShapeChannel->GetShapeGeometries();
|
||||||
for (size_t i = 0; i < shapeGeometries.size(); i++) {
|
for (const ShapeGeometry *shapeGeometry : shapeGeometries) {
|
||||||
aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh);
|
aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh);
|
||||||
const ShapeGeometry *shapeGeometry = shapeGeometries.at(i);
|
const auto &curVertices = shapeGeometry->GetVertices();
|
||||||
const std::vector<aiVector3D> &curVertices = shapeGeometry->GetVertices();
|
const auto &curNormals = shapeGeometry->GetNormals();
|
||||||
const std::vector<aiVector3D> &curNormals = shapeGeometry->GetNormals();
|
const auto &curIndices = shapeGeometry->GetIndices();
|
||||||
const std::vector<unsigned int> &curIndices = shapeGeometry->GetIndices();
|
|
||||||
//losing channel name if using shapeGeometry->Name()
|
//losing channel name if using shapeGeometry->Name()
|
||||||
animMesh->mName.Set(FixAnimMeshName(blendShapeChannel->Name()));
|
// if blendShapeChannel Name is empty or don't have a ".", add geoMetryName;
|
||||||
|
auto aniName = FixAnimMeshName(blendShapeChannel->Name());
|
||||||
|
auto geoMetryName = FixAnimMeshName(shapeGeometry->Name());
|
||||||
|
if (aniName.empty()) {
|
||||||
|
aniName = geoMetryName;
|
||||||
|
}
|
||||||
|
else if (aniName.find('.') == aniName.npos) {
|
||||||
|
aniName += "." + geoMetryName;
|
||||||
|
}
|
||||||
|
animMesh->mName.Set(aniName);
|
||||||
for (size_t j = 0; j < curIndices.size(); j++) {
|
for (size_t j = 0; j < curIndices.size(); j++) {
|
||||||
const unsigned int curIndex = curIndices.at(j);
|
const unsigned int curIndex = curIndices.at(j);
|
||||||
aiVector3D vertex = curVertices.at(j);
|
aiVector3D vertex = curVertices.at(j);
|
||||||
|
@ -1406,13 +1418,12 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
|
||||||
std::vector<aiAnimMesh *> animMeshes;
|
std::vector<aiAnimMesh *> animMeshes;
|
||||||
for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
|
for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
|
||||||
for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
|
for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
|
||||||
const std::vector<const ShapeGeometry *> &shapeGeometries = blendShapeChannel->GetShapeGeometries();
|
const auto& shapeGeometries = blendShapeChannel->GetShapeGeometries();
|
||||||
for (size_t i = 0; i < shapeGeometries.size(); i++) {
|
for (const ShapeGeometry *shapeGeometry : shapeGeometries) {
|
||||||
aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh);
|
aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh);
|
||||||
const ShapeGeometry *shapeGeometry = shapeGeometries.at(i);
|
const auto& curVertices = shapeGeometry->GetVertices();
|
||||||
const std::vector<aiVector3D> &curVertices = shapeGeometry->GetVertices();
|
const auto& curNormals = shapeGeometry->GetNormals();
|
||||||
const std::vector<aiVector3D> &curNormals = shapeGeometry->GetNormals();
|
const auto& curIndices = shapeGeometry->GetIndices();
|
||||||
const std::vector<unsigned int> &curIndices = shapeGeometry->GetIndices();
|
|
||||||
animMesh->mName.Set(FixAnimMeshName(shapeGeometry->Name()));
|
animMesh->mName.Set(FixAnimMeshName(shapeGeometry->Name()));
|
||||||
for (size_t j = 0; j < curIndices.size(); j++) {
|
for (size_t j = 0; j < curIndices.size(); j++) {
|
||||||
unsigned int curIndex = curIndices.at(j);
|
unsigned int curIndex = curIndices.at(j);
|
||||||
|
|
|
@ -154,8 +154,10 @@ BlendShape::BlendShape(uint64_t id, const Element& element, const Document& doc,
|
||||||
for (const Connection* con : conns) {
|
for (const Connection* con : conns) {
|
||||||
const BlendShapeChannel* const bspc = ProcessSimpleConnection<BlendShapeChannel>(*con, false, "BlendShapeChannel -> BlendShape", element);
|
const BlendShapeChannel* const bspc = ProcessSimpleConnection<BlendShapeChannel>(*con, false, "BlendShapeChannel -> BlendShape", element);
|
||||||
if (bspc) {
|
if (bspc) {
|
||||||
blendShapeChannels.push_back(bspc);
|
auto pr = blendShapeChannels.insert(bspc);
|
||||||
continue;
|
if (!pr.second) {
|
||||||
|
FBXImporter::LogWarn("there is the same blendShapeChannel id ", bspc->ID());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,8 +181,10 @@ BlendShapeChannel::BlendShapeChannel(uint64_t id, const Element& element, const
|
||||||
for (const Connection* con : conns) {
|
for (const Connection* con : conns) {
|
||||||
const ShapeGeometry* const sg = ProcessSimpleConnection<ShapeGeometry>(*con, false, "Shape -> BlendShapeChannel", element);
|
const ShapeGeometry* const sg = ProcessSimpleConnection<ShapeGeometry>(*con, false, "Shape -> BlendShapeChannel", element);
|
||||||
if (sg) {
|
if (sg) {
|
||||||
shapeGeometries.push_back(sg);
|
auto pr = shapeGeometries.insert(sg);
|
||||||
continue;
|
if (!pr.second) {
|
||||||
|
FBXImporter::LogWarn("there is the same shapeGeometrie id ", sg->ID());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define INCLUDED_AI_FBX_DOCUMENT_H
|
#define INCLUDED_AI_FBX_DOCUMENT_H
|
||||||
|
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
#include <unordered_set>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <assimp/mesh.h>
|
#include <assimp/mesh.h>
|
||||||
#include "FBXProperties.h"
|
#include "FBXProperties.h"
|
||||||
|
@ -855,14 +856,14 @@ public:
|
||||||
return fullWeights;
|
return fullWeights;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<const ShapeGeometry*>& GetShapeGeometries() const {
|
const std::unordered_set<const ShapeGeometry*>& GetShapeGeometries() const {
|
||||||
return shapeGeometries;
|
return shapeGeometries;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float percent;
|
float percent;
|
||||||
WeightArray fullWeights;
|
WeightArray fullWeights;
|
||||||
std::vector<const ShapeGeometry*> shapeGeometries;
|
std::unordered_set<const ShapeGeometry*> shapeGeometries;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** DOM class for BlendShape deformers */
|
/** DOM class for BlendShape deformers */
|
||||||
|
@ -872,12 +873,12 @@ public:
|
||||||
|
|
||||||
virtual ~BlendShape();
|
virtual ~BlendShape();
|
||||||
|
|
||||||
const std::vector<const BlendShapeChannel*>& BlendShapeChannels() const {
|
const std::unordered_set<const BlendShapeChannel*>& BlendShapeChannels() const {
|
||||||
return blendShapeChannels;
|
return blendShapeChannels;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<const BlendShapeChannel*> blendShapeChannels;
|
std::unordered_set<const BlendShapeChannel*> blendShapeChannels;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** DOM class for skin deformer clusters (aka sub-deformers) */
|
/** DOM class for skin deformer clusters (aka sub-deformers) */
|
||||||
|
|
|
@ -69,13 +69,16 @@ Geometry::Geometry(uint64_t id, const Element& element, const std::string& name,
|
||||||
}
|
}
|
||||||
const BlendShape* const bsp = ProcessSimpleConnection<BlendShape>(*con, false, "BlendShape -> Geometry", element);
|
const BlendShape* const bsp = ProcessSimpleConnection<BlendShape>(*con, false, "BlendShape -> Geometry", element);
|
||||||
if (bsp) {
|
if (bsp) {
|
||||||
blendShapes.push_back(bsp);
|
auto pr = blendShapes.insert(bsp);
|
||||||
|
if (!pr.second) {
|
||||||
|
FBXImporter::LogWarn("there is the same blendShape id ", bsp->ID());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const std::vector<const BlendShape*>& Geometry::GetBlendShapes() const {
|
const std::unordered_set<const BlendShape*>& Geometry::GetBlendShapes() const {
|
||||||
return blendShapes;
|
return blendShapes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,11 +72,12 @@ public:
|
||||||
|
|
||||||
/// @brief Get the BlendShape attached to this geometry or nullptr
|
/// @brief Get the BlendShape attached to this geometry or nullptr
|
||||||
/// @return The blendshape arrays.
|
/// @return The blendshape arrays.
|
||||||
const std::vector<const BlendShape*>& GetBlendShapes() const;
|
const std::unordered_set<const BlendShape*>& GetBlendShapes() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Skin* skin;
|
const Skin* skin;
|
||||||
std::vector<const BlendShape*> blendShapes;
|
std::unordered_set<const BlendShape*> blendShapes;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<int> MatIndexArray;
|
typedef std::vector<int> MatIndexArray;
|
||||||
|
|
|
@ -470,14 +470,16 @@ void HL1MDLLoader::read_bones() {
|
||||||
|
|
||||||
temp_bones_.resize(header_->numbones);
|
temp_bones_.resize(header_->numbones);
|
||||||
|
|
||||||
|
// Create the main 'bones' node that will contain all MDL root bones.
|
||||||
aiNode *bones_node = new aiNode(AI_MDL_HL1_NODE_BONES);
|
aiNode *bones_node = new aiNode(AI_MDL_HL1_NODE_BONES);
|
||||||
rootnode_children_.push_back(bones_node);
|
rootnode_children_.push_back(bones_node);
|
||||||
bones_node->mNumChildren = static_cast<unsigned int>(header_->numbones);
|
|
||||||
bones_node->mChildren = new aiNode *[bones_node->mNumChildren];
|
// Store roots bones IDs temporarily.
|
||||||
|
std::vector<int> roots;
|
||||||
|
|
||||||
// Create bone matrices in local space.
|
// Create bone matrices in local space.
|
||||||
for (int i = 0; i < header_->numbones; ++i) {
|
for (int i = 0; i < header_->numbones; ++i) {
|
||||||
aiNode *bone_node = temp_bones_[i].node = bones_node->mChildren[i] = new aiNode(unique_bones_names[i]);
|
aiNode *bone_node = temp_bones_[i].node = new aiNode(unique_bones_names[i]);
|
||||||
|
|
||||||
aiVector3D angles(pbone[i].value[3], pbone[i].value[4], pbone[i].value[5]);
|
aiVector3D angles(pbone[i].value[3], pbone[i].value[4], pbone[i].value[5]);
|
||||||
temp_bones_[i].absolute_transform = bone_node->mTransformation =
|
temp_bones_[i].absolute_transform = bone_node->mTransformation =
|
||||||
|
@ -485,9 +487,11 @@ void HL1MDLLoader::read_bones() {
|
||||||
aiVector3D(pbone[i].value[0], pbone[i].value[1], pbone[i].value[2]));
|
aiVector3D(pbone[i].value[0], pbone[i].value[1], pbone[i].value[2]));
|
||||||
|
|
||||||
if (pbone[i].parent == -1) {
|
if (pbone[i].parent == -1) {
|
||||||
bone_node->mParent = scene_->mRootNode;
|
bone_node->mParent = bones_node;
|
||||||
|
roots.push_back(i); // This bone has no parent. Add it to the roots list.
|
||||||
} else {
|
} else {
|
||||||
bone_node->mParent = bones_node->mChildren[pbone[i].parent];
|
bone_node->mParent = temp_bones_[pbone[i].parent].node;
|
||||||
|
temp_bones_[pbone[i].parent].children.push_back(i); // Add this bone to the parent bone's children list.
|
||||||
|
|
||||||
temp_bones_[i].absolute_transform =
|
temp_bones_[i].absolute_transform =
|
||||||
temp_bones_[pbone[i].parent].absolute_transform * bone_node->mTransformation;
|
temp_bones_[pbone[i].parent].absolute_transform * bone_node->mTransformation;
|
||||||
|
@ -496,6 +500,36 @@ void HL1MDLLoader::read_bones() {
|
||||||
temp_bones_[i].offset_matrix = temp_bones_[i].absolute_transform;
|
temp_bones_[i].offset_matrix = temp_bones_[i].absolute_transform;
|
||||||
temp_bones_[i].offset_matrix.Inverse();
|
temp_bones_[i].offset_matrix.Inverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allocate memory for each MDL root bone.
|
||||||
|
bones_node->mNumChildren = static_cast<unsigned int>(roots.size());
|
||||||
|
bones_node->mChildren = new aiNode *[bones_node->mNumChildren];
|
||||||
|
|
||||||
|
// Build all bones children hierarchy starting from each MDL root bone.
|
||||||
|
for (size_t i = 0; i < roots.size(); ++i)
|
||||||
|
{
|
||||||
|
const TempBone &root_bone = temp_bones_[roots[i]];
|
||||||
|
bones_node->mChildren[i] = root_bone.node;
|
||||||
|
build_bone_children_hierarchy(root_bone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HL1MDLLoader::build_bone_children_hierarchy(const TempBone &bone)
|
||||||
|
{
|
||||||
|
if (bone.children.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
aiNode* bone_node = bone.node;
|
||||||
|
bone_node->mNumChildren = static_cast<unsigned int>(bone.children.size());
|
||||||
|
bone_node->mChildren = new aiNode *[bone_node->mNumChildren];
|
||||||
|
|
||||||
|
// Build each child bone's hierarchy recursively.
|
||||||
|
for (size_t i = 0; i < bone.children.size(); ++i)
|
||||||
|
{
|
||||||
|
const TempBone &child_bone = temp_bones_[bone.children[i]];
|
||||||
|
bone_node->mChildren[i] = child_bone.node;
|
||||||
|
build_bone_children_hierarchy(child_bone);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -143,6 +143,14 @@ private:
|
||||||
*/
|
*/
|
||||||
static bool get_num_blend_controllers(const int num_blend_animations, int &num_blend_controllers);
|
static bool get_num_blend_controllers(const int num_blend_animations, int &num_blend_controllers);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Build a bone's node children hierarchy.
|
||||||
|
*
|
||||||
|
* \param[in] bone The bone for which we must build all children hierarchy.
|
||||||
|
*/
|
||||||
|
struct TempBone;
|
||||||
|
void build_bone_children_hierarchy(const TempBone& bone);
|
||||||
|
|
||||||
/** Output scene to be filled */
|
/** Output scene to be filled */
|
||||||
aiScene *scene_;
|
aiScene *scene_;
|
||||||
|
|
||||||
|
@ -198,11 +206,13 @@ private:
|
||||||
TempBone() :
|
TempBone() :
|
||||||
node(nullptr),
|
node(nullptr),
|
||||||
absolute_transform(),
|
absolute_transform(),
|
||||||
offset_matrix() {}
|
offset_matrix(),
|
||||||
|
children() {}
|
||||||
|
|
||||||
aiNode *node;
|
aiNode *node;
|
||||||
aiMatrix4x4 absolute_transform;
|
aiMatrix4x4 absolute_transform;
|
||||||
aiMatrix4x4 offset_matrix;
|
aiMatrix4x4 offset_matrix;
|
||||||
|
std::vector<int> children; // Bone children
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<TempBone> temp_bones_;
|
std::vector<TempBone> temp_bones_;
|
||||||
|
|
|
@ -490,7 +490,7 @@ bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *me
|
||||||
OgreXmlSerializer serializer(xmlParser.get());
|
OgreXmlSerializer serializer(xmlParser.get());
|
||||||
XmlNode root = xmlParser->getRootNode();
|
XmlNode root = xmlParser->getRootNode();
|
||||||
if (std::string(root.name()) != nnSkeleton) {
|
if (std::string(root.name()) != nnSkeleton) {
|
||||||
printf("\nSkeleton is not a valid root: %s\n", root.name());
|
ASSIMP_LOG_VERBOSE_DEBUG("nSkeleton is not a valid root: ", root.name(), ".");
|
||||||
for (auto &a : root.children()) {
|
for (auto &a : root.children()) {
|
||||||
if (std::string(a.name()) == nnSkeleton) {
|
if (std::string(a.name()) == nnSkeleton) {
|
||||||
root = a;
|
root = a;
|
||||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -47,14 +45,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
CIOStreamWrapper::~CIOStreamWrapper() {
|
CIOStreamWrapper::~CIOStreamWrapper() {
|
||||||
/* Various places depend on this destructor to close the file */
|
// Various places depend on this destructor to close the file
|
||||||
if (mFile) {
|
if (mFile != nullptr) {
|
||||||
|
|
||||||
mIO->mFileSystem->CloseProc(mIO->mFileSystem, mFile);
|
mIO->mFileSystem->CloseProc(mIO->mFileSystem, mFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...................................................................
|
// ------------------------------------------------------------------------------------------------
|
||||||
size_t CIOStreamWrapper::Read(void *pvBuffer,
|
size_t CIOStreamWrapper::Read(void *pvBuffer,
|
||||||
size_t pSize,
|
size_t pSize,
|
||||||
size_t pCount) {
|
size_t pCount) {
|
||||||
|
@ -62,7 +62,7 @@ size_t CIOStreamWrapper::Read(void *pvBuffer,
|
||||||
return mFile->ReadProc(mFile, (char *)pvBuffer, pSize, pCount);
|
return mFile->ReadProc(mFile, (char *)pvBuffer, pSize, pCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...................................................................
|
// ------------------------------------------------------------------------------------------------
|
||||||
size_t CIOStreamWrapper::Write(const void *pvBuffer,
|
size_t CIOStreamWrapper::Write(const void *pvBuffer,
|
||||||
size_t pSize,
|
size_t pSize,
|
||||||
size_t pCount) {
|
size_t pCount) {
|
||||||
|
@ -70,23 +70,23 @@ size_t CIOStreamWrapper::Write(const void *pvBuffer,
|
||||||
return mFile->WriteProc(mFile, (const char *)pvBuffer, pSize, pCount);
|
return mFile->WriteProc(mFile, (const char *)pvBuffer, pSize, pCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...................................................................
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiReturn CIOStreamWrapper::Seek(size_t pOffset,
|
aiReturn CIOStreamWrapper::Seek(size_t pOffset,
|
||||||
aiOrigin pOrigin) {
|
aiOrigin pOrigin) {
|
||||||
return mFile->SeekProc(mFile, pOffset, pOrigin);
|
return mFile->SeekProc(mFile, pOffset, pOrigin);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...................................................................
|
// ------------------------------------------------------------------------------------------------
|
||||||
size_t CIOStreamWrapper::Tell() const {
|
size_t CIOStreamWrapper::Tell() const {
|
||||||
return mFile->TellProc(mFile);
|
return mFile->TellProc(mFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...................................................................
|
// ------------------------------------------------------------------------------------------------
|
||||||
size_t CIOStreamWrapper::FileSize() const {
|
size_t CIOStreamWrapper::FileSize() const {
|
||||||
return mFile->FileSizeProc(mFile);
|
return mFile->FileSizeProc(mFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...................................................................
|
// ------------------------------------------------------------------------------------------------
|
||||||
void CIOStreamWrapper::Flush() {
|
void CIOStreamWrapper::Flush() {
|
||||||
return mFile->FlushProc(mFile);
|
return mFile->FlushProc(mFile);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,48 +47,59 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/cfileio.h>
|
#include <assimp/cfileio.h>
|
||||||
#include <assimp/IOStream.hpp>
|
#include <assimp/IOStream.hpp>
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
|
#include <assimp/ai_assert.h>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
class CIOSystemWrapper;
|
class CIOSystemWrapper;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Custom IOStream implementation for the C-API
|
/// @brief Custom IOStream implementation for the C-API-
|
||||||
class CIOStreamWrapper : public IOStream {
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
class CIOStreamWrapper final : public IOStream {
|
||||||
public:
|
public:
|
||||||
explicit CIOStreamWrapper(aiFile *pFile, CIOSystemWrapper *io) :
|
explicit CIOStreamWrapper(aiFile *pFile, CIOSystemWrapper *io);
|
||||||
mFile(pFile),
|
~CIOStreamWrapper() override;
|
||||||
mIO(io) {}
|
size_t Read(void *pvBuffer, size_t pSize, size_t pCount) override;
|
||||||
~CIOStreamWrapper(void);
|
size_t Write(const void *pvBuffer, size_t pSize, size_t pCount) override;
|
||||||
|
aiReturn Seek(size_t pOffset, aiOrigin pOrigin) override;
|
||||||
size_t Read(void *pvBuffer, size_t pSize, size_t pCount);
|
size_t Tell(void) const override;
|
||||||
size_t Write(const void *pvBuffer, size_t pSize, size_t pCount);
|
size_t FileSize() const override;
|
||||||
aiReturn Seek(size_t pOffset, aiOrigin pOrigin);
|
void Flush() override;
|
||||||
size_t Tell(void) const;
|
|
||||||
size_t FileSize() const;
|
|
||||||
void Flush();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
aiFile *mFile;
|
aiFile *mFile;
|
||||||
CIOSystemWrapper *mIO;
|
CIOSystemWrapper *mIO;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CIOSystemWrapper : public IOSystem {
|
inline CIOStreamWrapper::CIOStreamWrapper(aiFile *pFile, CIOSystemWrapper *io) :
|
||||||
|
mFile(pFile),
|
||||||
|
mIO(io) {
|
||||||
|
ai_assert(io != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
/// @brief Custom IO-System wrapper implementation for the C-API.
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
class CIOSystemWrapper final : public IOSystem {
|
||||||
friend class CIOStreamWrapper;
|
friend class CIOStreamWrapper;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CIOSystemWrapper(aiFileIO *pFile) :
|
explicit CIOSystemWrapper(aiFileIO *pFile);
|
||||||
mFileSystem(pFile) {}
|
~CIOSystemWrapper() override = default;
|
||||||
|
bool Exists(const char *pFile) const override;
|
||||||
bool Exists(const char *pFile) const;
|
char getOsSeparator() const override;
|
||||||
char getOsSeparator() const;
|
IOStream *Open(const char *pFile, const char *pMode = "rb") override;
|
||||||
IOStream *Open(const char *pFile, const char *pMode = "rb");
|
void Close(IOStream *pFile) override;
|
||||||
void Close(IOStream *pFile);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
aiFileIO *mFileSystem;
|
aiFileIO *mFileSystem;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline CIOSystemWrapper::CIOSystemWrapper(aiFileIO *pFile) : mFileSystem(pFile) {
|
||||||
|
ai_assert(pFile != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Assimp
|
} // namespace Assimp
|
||||||
|
|
||||||
#endif
|
#endif // AI_CIOSYSTEM_H_INCLUDED
|
||||||
|
|
|
@ -218,6 +218,12 @@ SET( CApi_SRCS
|
||||||
)
|
)
|
||||||
SOURCE_GROUP(CApi FILES ${CApi_SRCS})
|
SOURCE_GROUP(CApi FILES ${CApi_SRCS})
|
||||||
|
|
||||||
|
SET(Geometry_SRCS
|
||||||
|
Geometry/GeometryUtils.h
|
||||||
|
Geometry/GeometryUtils.cpp
|
||||||
|
)
|
||||||
|
SOURCE_GROUP(Geometry FILES ${Geometry_SRCS})
|
||||||
|
|
||||||
SET( STEPParser_SRCS
|
SET( STEPParser_SRCS
|
||||||
AssetLib/STEPParser/STEPFileReader.h
|
AssetLib/STEPParser/STEPFileReader.h
|
||||||
AssetLib/STEPParser/STEPFileReader.cpp
|
AssetLib/STEPParser/STEPFileReader.cpp
|
||||||
|
@ -1129,6 +1135,7 @@ SET( assimp_src
|
||||||
${Core_SRCS}
|
${Core_SRCS}
|
||||||
${CApi_SRCS}
|
${CApi_SRCS}
|
||||||
${Common_SRCS}
|
${Common_SRCS}
|
||||||
|
${Geometry_SRCS}
|
||||||
${Logging_SRCS}
|
${Logging_SRCS}
|
||||||
${Exporter_SRCS}
|
${Exporter_SRCS}
|
||||||
${PostProcessing_SRCS}
|
${PostProcessing_SRCS}
|
||||||
|
|
|
@ -74,26 +74,8 @@ inline bool OnLeftSideOfLine2D(const T& p0, const T& p1,const T& p2) {
|
||||||
* both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/
|
* both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool PointInTriangle2D(const T& p0, const T& p1,const T& p2, const T& pp) {
|
inline bool PointInTriangle2D(const T& p0, const T& p1,const T& p2, const T& pp) {
|
||||||
// Point in triangle test using baryzentric coordinates
|
// pp should be left side of the three triangle side, by ccw arrow
|
||||||
const aiVector2D v0 = p1 - p0;
|
return OnLeftSideOfLine2D(p0, p1, pp) && OnLeftSideOfLine2D(p1, p2, pp) && OnLeftSideOfLine2D(p2, p0, pp);
|
||||||
const aiVector2D v1 = p2 - p0;
|
|
||||||
const aiVector2D v2 = pp - p0;
|
|
||||||
|
|
||||||
double dot00 = v0 * v0;
|
|
||||||
double dot11 = v1 * v1;
|
|
||||||
const double dot01 = v0 * v1;
|
|
||||||
const double dot02 = v0 * v2;
|
|
||||||
const double dot12 = v1 * v2;
|
|
||||||
const double denom = dot00 * dot11 - dot01 * dot01;
|
|
||||||
if (denom == 0.0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const double invDenom = 1.0 / denom;
|
|
||||||
dot11 = (dot11 * dot02 - dot01 * dot12) * invDenom;
|
|
||||||
dot00 = (dot00 * dot12 - dot01 * dot02) * invDenom;
|
|
||||||
|
|
||||||
return (dot11 > 0) && (dot00 > 0) && (dot11 + dot00 < 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
void mydummy() {}
|
void mydummy() {}
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -78,7 +81,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<unsigned int> UIntVector;
|
typedef std::vector<unsigned int> UIntVector;
|
||||||
typedef std::map<uint64_t, Edge> EdgeMap;
|
typedef std::unordered_map<uint64_t, Edge> EdgeMap;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Hashing function to derive an index into an #EdgeMap from two given
|
// Hashing function to derive an index into an #EdgeMap from two given
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
/*
|
/*
|
||||||
---------------------------------------------------------------------------
|
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
with or without modification, are permitted provided that the following
|
with or without modification, are permitted provided that the
|
||||||
conditions are met:
|
following conditions are met:
|
||||||
|
|
||||||
* Redistributions of source code must retain the above
|
* Redistributions of source code must retain the above
|
||||||
copyright notice, this list of conditions and the
|
copyright notice, this list of conditions and the
|
||||||
|
@ -38,55 +35,45 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
---------------------------------------------------------------------------
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ASSIMP_SAMPLES_SHARED_CODE_UTFCONVERTER_H
|
#include "GeometryUtils.h"
|
||||||
#define ASSIMP_SAMPLES_SHARED_CODE_UTFCONVERTER_H
|
|
||||||
|
|
||||||
#include <string>
|
#include <assimp/vector3.h>
|
||||||
#include <locale>
|
|
||||||
#include <codecvt>
|
|
||||||
|
|
||||||
namespace AssimpSamples {
|
namespace Assimp {
|
||||||
namespace SharedCode {
|
|
||||||
|
|
||||||
// Used to convert between multibyte and unicode strings.
|
ai_real GeometryUtils::heron( ai_real a, ai_real b, ai_real c ) {
|
||||||
class UTFConverter {
|
ai_real s = (a + b + c) / 2;
|
||||||
using UTFConverterImpl = std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>;
|
ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), (ai_real)0.5 );
|
||||||
public:
|
return area;
|
||||||
UTFConverter(const char* s) :
|
|
||||||
s_(s),
|
|
||||||
ws_(impl_.from_bytes(s)) {
|
|
||||||
}
|
|
||||||
UTFConverter(const wchar_t* s) :
|
|
||||||
s_(impl_.to_bytes(s)),
|
|
||||||
ws_(s) {
|
|
||||||
}
|
|
||||||
UTFConverter(const std::string& s) :
|
|
||||||
s_(s),
|
|
||||||
ws_(impl_.from_bytes(s)) {
|
|
||||||
}
|
|
||||||
UTFConverter(const std::wstring& s) :
|
|
||||||
s_(impl_.to_bytes(s)),
|
|
||||||
ws_(s) {
|
|
||||||
}
|
|
||||||
inline const char* c_str() const {
|
|
||||||
return s_.c_str();
|
|
||||||
}
|
|
||||||
inline const std::string& str() const {
|
|
||||||
return s_;
|
|
||||||
}
|
|
||||||
inline const wchar_t* c_wstr() const {
|
|
||||||
return ws_.c_str();
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
static UTFConverterImpl impl_;
|
|
||||||
std::string s_;
|
|
||||||
std::wstring ws_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ASSIMP_SAMPLES_SHARED_CODE_UTFCONVERTER_H
|
ai_real GeometryUtils::distance3D( const aiVector3D &vA, aiVector3D &vB ) {
|
||||||
|
const ai_real lx = ( vB.x - vA.x );
|
||||||
|
const ai_real ly = ( vB.y - vA.y );
|
||||||
|
const ai_real lz = ( vB.z - vA.z );
|
||||||
|
ai_real a = lx*lx + ly*ly + lz*lz;
|
||||||
|
ai_real d = pow( a, (ai_real)0.5 );
|
||||||
|
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
ai_real GeometryUtils::calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh ) {
|
||||||
|
ai_real area = 0;
|
||||||
|
|
||||||
|
aiVector3D vA( mesh->mVertices[ face.mIndices[ 0 ] ] );
|
||||||
|
aiVector3D vB( mesh->mVertices[ face.mIndices[ 1 ] ] );
|
||||||
|
aiVector3D vC( mesh->mVertices[ face.mIndices[ 2 ] ] );
|
||||||
|
|
||||||
|
ai_real a( distance3D( vA, vB ) );
|
||||||
|
ai_real b( distance3D( vB, vC ) );
|
||||||
|
ai_real c( distance3D( vC, vA ) );
|
||||||
|
area = heron( a, b, c );
|
||||||
|
|
||||||
|
return area;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Assimp
|
|
@ -1,17 +1,14 @@
|
||||||
/*
|
/*
|
||||||
---------------------------------------------------------------------------
|
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
with or without modification, are permitted provided that the following
|
with or without modification, are permitted provided that the
|
||||||
conditions are met:
|
following conditions are met:
|
||||||
|
|
||||||
* Redistributions of source code must retain the above
|
* Redistributions of source code must retain the above
|
||||||
copyright notice, this list of conditions and the
|
copyright notice, this list of conditions and the
|
||||||
|
@ -38,15 +35,33 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
---------------------------------------------------------------------------
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "UTFConverter.h"
|
#include <assimp/types.h>
|
||||||
|
#include <assimp/mesh.h>
|
||||||
|
|
||||||
namespace AssimpSamples {
|
namespace Assimp {
|
||||||
namespace SharedCode {
|
|
||||||
|
|
||||||
typename UTFConverter::UTFConverterImpl UTFConverter::impl_;
|
// ---------------------------------------------------------------------------
|
||||||
|
/// @brief This helper class supports some basic geometry algorithms.
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
class GeometryUtils {
|
||||||
|
public:
|
||||||
|
static ai_real heron( ai_real a, ai_real b, ai_real c );
|
||||||
|
|
||||||
}
|
/// @brief Will compute the distance between 2 3D-vectors
|
||||||
}
|
/// @param vA Vector a.
|
||||||
|
/// @param vB Vector b.
|
||||||
|
/// @return The distance.
|
||||||
|
static ai_real distance3D( const aiVector3D &vA, aiVector3D &vB );
|
||||||
|
|
||||||
|
/// @brief Will calculate the area of a triangle described by a aiFace.
|
||||||
|
/// @param face The face
|
||||||
|
/// @param mesh The mesh containing the face
|
||||||
|
/// @return The area.
|
||||||
|
static ai_real calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh );
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Assimp
|
|
@ -60,10 +60,6 @@ CalcTangentsProcess::CalcTangentsProcess() :
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
CalcTangentsProcess::~CalcTangentsProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool CalcTangentsProcess::IsActive(unsigned int pFlags) const {
|
bool CalcTangentsProcess::IsActive(unsigned int pFlags) const {
|
||||||
|
|
|
@ -59,14 +59,11 @@ namespace Assimp
|
||||||
* because the joining of vertices also considers tangents and bitangents for
|
* because the joining of vertices also considers tangents and bitangents for
|
||||||
* uniqueness.
|
* uniqueness.
|
||||||
*/
|
*/
|
||||||
class ASSIMP_API_WINONLY CalcTangentsProcess : public BaseProcess
|
class ASSIMP_API_WINONLY CalcTangentsProcess : public BaseProcess {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CalcTangentsProcess();
|
CalcTangentsProcess();
|
||||||
~CalcTangentsProcess();
|
~CalcTangentsProcess() override = default;
|
||||||
|
|
||||||
public:
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the processing step is present in the given flag.
|
/** Returns whether the processing step is present in the given flag.
|
||||||
* @param pFlags The processing flags the importer was called with.
|
* @param pFlags The processing flags the importer was called with.
|
||||||
|
@ -74,24 +71,21 @@ public:
|
||||||
* @return true if the process is present in this flag fields,
|
* @return true if the process is present in this flag fields,
|
||||||
* false if not.
|
* false if not.
|
||||||
*/
|
*/
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Called prior to ExecuteOnScene().
|
/** Called prior to ExecuteOnScene().
|
||||||
* The function is a request to the process to update its configuration
|
* The function is a request to the process to update its configuration
|
||||||
* basing on the Importer's configuration property list.
|
* basing on the Importer's configuration property list.
|
||||||
*/
|
*/
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp) override;
|
||||||
|
|
||||||
|
|
||||||
// setter for configMaxAngle
|
// setter for configMaxAngle
|
||||||
inline void SetMaxSmoothAngle(float f)
|
void SetMaxSmoothAngle(float f) {
|
||||||
{
|
|
||||||
configMaxAngle =f;
|
configMaxAngle =f;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Calculates tangents and bitangents for a specific mesh.
|
/** Calculates tangents and bitangents for a specific mesh.
|
||||||
* @param pMesh The mesh to process.
|
* @param pMesh The mesh to process.
|
||||||
|
@ -103,10 +97,9 @@ protected:
|
||||||
/** Executes the post processing step on the given imported data.
|
/** Executes the post processing step on the given imported data.
|
||||||
* @param pScene The imported data to work at.
|
* @param pScene The imported data to work at.
|
||||||
*/
|
*/
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/** Configuration option: maximum smoothing angle, in radians*/
|
/** Configuration option: maximum smoothing angle, in radians*/
|
||||||
float configMaxAngle;
|
float configMaxAngle;
|
||||||
unsigned int configSourceUV;
|
unsigned int configSourceUV;
|
||||||
|
|
|
@ -57,14 +57,6 @@ namespace {
|
||||||
const static ai_real angle_epsilon = ai_real( 0.95 );
|
const static ai_real angle_epsilon = ai_real( 0.95 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Constructor to be privately used by Importer
|
|
||||||
ComputeUVMappingProcess::ComputeUVMappingProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
ComputeUVMappingProcess::~ComputeUVMappingProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool ComputeUVMappingProcess::IsActive( unsigned int pFlags) const
|
bool ComputeUVMappingProcess::IsActive( unsigned int pFlags) const
|
||||||
|
|
|
@ -59,13 +59,10 @@ namespace Assimp {
|
||||||
/** ComputeUVMappingProcess - converts special mappings, such as spherical,
|
/** ComputeUVMappingProcess - converts special mappings, such as spherical,
|
||||||
* cylindrical or boxed to proper UV coordinates for rendering.
|
* cylindrical or boxed to proper UV coordinates for rendering.
|
||||||
*/
|
*/
|
||||||
class ComputeUVMappingProcess : public BaseProcess
|
class ComputeUVMappingProcess : public BaseProcess {
|
||||||
{
|
|
||||||
public:
|
|
||||||
ComputeUVMappingProcess();
|
|
||||||
~ComputeUVMappingProcess();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
ComputeUVMappingProcess() = default;
|
||||||
|
~ComputeUVMappingProcess() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the processing step is present in the given flag field.
|
/** Returns whether the processing step is present in the given flag field.
|
||||||
|
@ -73,14 +70,14 @@ public:
|
||||||
* combination of #aiPostProcessSteps.
|
* combination of #aiPostProcessSteps.
|
||||||
* @return true if the process is present in this flag fields, false if not.
|
* @return true if the process is present in this flag fields, false if not.
|
||||||
*/
|
*/
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Executes the post processing step on the given imported data.
|
/** Executes the post processing step on the given imported data.
|
||||||
* At the moment a process is not supposed to fail.
|
* At the moment a process is not supposed to fail.
|
||||||
* @param pScene The imported data to work at.
|
* @param pScene The imported data to work at.
|
||||||
*/
|
*/
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -125,8 +122,7 @@ protected:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// temporary structure to describe a mapping
|
// temporary structure to describe a mapping
|
||||||
struct MappingInfo
|
struct MappingInfo {
|
||||||
{
|
|
||||||
explicit MappingInfo(aiTextureMapping _type)
|
explicit MappingInfo(aiTextureMapping _type)
|
||||||
: type (_type)
|
: type (_type)
|
||||||
, axis (0.f,1.f,0.f)
|
, axis (0.f,1.f,0.f)
|
||||||
|
@ -137,8 +133,7 @@ private:
|
||||||
aiVector3D axis;
|
aiVector3D axis;
|
||||||
unsigned int uv;
|
unsigned int uv;
|
||||||
|
|
||||||
bool operator== (const MappingInfo& other)
|
bool operator== (const MappingInfo& other) {
|
||||||
{
|
|
||||||
return type == other.type && axis == other.axis;
|
return type == other.type && axis == other.axis;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -79,14 +79,6 @@ void flipUVs(aiMeshType *pMesh) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Constructor to be privately used by Importer
|
|
||||||
MakeLeftHandedProcess::MakeLeftHandedProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
MakeLeftHandedProcess::~MakeLeftHandedProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool MakeLeftHandedProcess::IsActive(unsigned int pFlags) const {
|
bool MakeLeftHandedProcess::IsActive(unsigned int pFlags) const {
|
||||||
|
@ -305,14 +297,6 @@ void FlipUVsProcess::ProcessMesh(aiMesh *pMesh) {
|
||||||
#ifndef ASSIMP_BUILD_NO_FLIPWINDING_PROCESS
|
#ifndef ASSIMP_BUILD_NO_FLIPWINDING_PROCESS
|
||||||
// # FlipWindingOrderProcess
|
// # FlipWindingOrderProcess
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Constructor to be privately used by Importer
|
|
||||||
FlipWindingOrderProcess::FlipWindingOrderProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
FlipWindingOrderProcess::~FlipWindingOrderProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool FlipWindingOrderProcess::IsActive(unsigned int pFlags) const {
|
bool FlipWindingOrderProcess::IsActive(unsigned int pFlags) const {
|
||||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -72,22 +71,18 @@ namespace Assimp {
|
||||||
*
|
*
|
||||||
* @note RH-LH and LH-RH is the same, so this class can be used for both
|
* @note RH-LH and LH-RH is the same, so this class can be used for both
|
||||||
*/
|
*/
|
||||||
class MakeLeftHandedProcess : public BaseProcess
|
class MakeLeftHandedProcess : public BaseProcess {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MakeLeftHandedProcess();
|
MakeLeftHandedProcess() = default;
|
||||||
~MakeLeftHandedProcess();
|
~MakeLeftHandedProcess() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Recursively converts a node and all of its children
|
/** Recursively converts a node and all of its children
|
||||||
*/
|
*/
|
||||||
|
@ -120,24 +115,22 @@ protected:
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Postprocessing step to flip the face order of the imported data
|
/** Postprocessing step to flip the face order of the imported data
|
||||||
*/
|
*/
|
||||||
class FlipWindingOrderProcess : public BaseProcess
|
class FlipWindingOrderProcess : public BaseProcess {
|
||||||
{
|
|
||||||
friend class Importer;
|
friend class Importer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Constructor to be privately used by Importer */
|
/** Constructor to be privately used by Importer */
|
||||||
FlipWindingOrderProcess();
|
FlipWindingOrderProcess() = default;
|
||||||
|
|
||||||
/** Destructor, private as well */
|
/** Destructor, private as well */
|
||||||
~FlipWindingOrderProcess();
|
~FlipWindingOrderProcess() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
public:
|
|
||||||
/** Some other types of post-processing require winding order flips */
|
/** Some other types of post-processing require winding order flips */
|
||||||
static void ProcessMesh( aiMesh* pMesh);
|
static void ProcessMesh( aiMesh* pMesh);
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,42 +43,26 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
/// @file DeboneProcess.cpp
|
/// @file DeboneProcess.cpp
|
||||||
/** Implementation of the DeboneProcess post processing step */
|
/** Implementation of the DeboneProcess post processing step */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// internal headers of the post-processing framework
|
// internal headers of the post-processing framework
|
||||||
#include "ProcessHelper.h"
|
#include "ProcessHelper.h"
|
||||||
#include "DeboneProcess.h"
|
#include "DeboneProcess.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
DeboneProcess::DeboneProcess()
|
DeboneProcess::DeboneProcess() : mNumBones(0), mNumBonesCanDoWithout(0), mThreshold(AI_DEBONE_THRESHOLD), mAllOrNone(false) {}
|
||||||
{
|
|
||||||
mNumBones = 0;
|
|
||||||
mNumBonesCanDoWithout = 0;
|
|
||||||
|
|
||||||
mThreshold = AI_DEBONE_THRESHOLD;
|
|
||||||
mAllOrNone = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
DeboneProcess::~DeboneProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool DeboneProcess::IsActive( unsigned int pFlags) const
|
bool DeboneProcess::IsActive( unsigned int pFlags) const {
|
||||||
{
|
|
||||||
return (pFlags & aiProcess_Debone) != 0;
|
return (pFlags & aiProcess_Debone) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
void DeboneProcess::SetupProperties(const Importer* pImp)
|
void DeboneProcess::SetupProperties(const Importer* pImp) {
|
||||||
{
|
|
||||||
// get the current value of the property
|
// get the current value of the property
|
||||||
mAllOrNone = pImp->GetPropertyInteger(AI_CONFIG_PP_DB_ALL_OR_NONE,0)?true:false;
|
mAllOrNone = pImp->GetPropertyInteger(AI_CONFIG_PP_DB_ALL_OR_NONE,0)?true:false;
|
||||||
mThreshold = pImp->GetPropertyFloat(AI_CONFIG_PP_DB_THRESHOLD,AI_DEBONE_THRESHOLD);
|
mThreshold = pImp->GetPropertyFloat(AI_CONFIG_PP_DB_THRESHOLD,AI_DEBONE_THRESHOLD);
|
||||||
|
@ -86,8 +70,7 @@ void DeboneProcess::SetupProperties(const Importer* pImp)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
void DeboneProcess::Execute( aiScene* pScene)
|
void DeboneProcess::Execute( aiScene* pScene) {
|
||||||
{
|
|
||||||
ASSIMP_LOG_DEBUG("DeboneProcess begin");
|
ASSIMP_LOG_DEBUG("DeboneProcess begin");
|
||||||
|
|
||||||
if(!pScene->mNumMeshes) {
|
if(!pScene->mNumMeshes) {
|
||||||
|
@ -117,10 +100,8 @@ void DeboneProcess::Execute( aiScene* pScene)
|
||||||
// build a new array of meshes for the scene
|
// build a new array of meshes for the scene
|
||||||
std::vector<aiMesh*> meshes;
|
std::vector<aiMesh*> meshes;
|
||||||
|
|
||||||
for(unsigned int a=0;a<pScene->mNumMeshes;a++)
|
for (unsigned int a=0;a<pScene->mNumMeshes; ++a) {
|
||||||
{
|
|
||||||
aiMesh* srcMesh = pScene->mMeshes[a];
|
aiMesh* srcMesh = pScene->mMeshes[a];
|
||||||
|
|
||||||
std::vector<std::pair<aiMesh*,const aiBone*> > newMeshes;
|
std::vector<std::pair<aiMesh*,const aiBone*> > newMeshes;
|
||||||
|
|
||||||
if(splitList[a]) {
|
if(splitList[a]) {
|
||||||
|
@ -150,8 +131,7 @@ void DeboneProcess::Execute( aiScene* pScene)
|
||||||
|
|
||||||
// and destroy the source mesh. It should be completely contained inside the new submeshes
|
// and destroy the source mesh. It should be completely contained inside the new submeshes
|
||||||
delete srcMesh;
|
delete srcMesh;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// Mesh is kept unchanged - store it's new place in the mesh array
|
// Mesh is kept unchanged - store it's new place in the mesh array
|
||||||
mSubMeshIndices[a].emplace_back(static_cast<unsigned int>(meshes.size()), (aiNode *)nullptr);
|
mSubMeshIndices[a].emplace_back(static_cast<unsigned int>(meshes.size()), (aiNode *)nullptr);
|
||||||
meshes.push_back(srcMesh);
|
meshes.push_back(srcMesh);
|
||||||
|
@ -173,8 +153,7 @@ void DeboneProcess::Execute( aiScene* pScene)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Counts bones total/removable in a given mesh.
|
// Counts bones total/removable in a given mesh.
|
||||||
bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh)
|
bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh) {
|
||||||
{
|
|
||||||
if(!pMesh->HasBones()) {
|
if(!pMesh->HasBones()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -193,25 +172,23 @@ bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh)
|
||||||
for(unsigned int i=0;i<pMesh->mNumBones;i++) {
|
for(unsigned int i=0;i<pMesh->mNumBones;i++) {
|
||||||
for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++) {
|
for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++) {
|
||||||
float w = pMesh->mBones[i]->mWeights[j].mWeight;
|
float w = pMesh->mBones[i]->mWeights[j].mWeight;
|
||||||
|
if (w == 0.0f) {
|
||||||
if(w==0.0f) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId;
|
unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId;
|
||||||
if(w>=mThreshold) {
|
if (w >= mThreshold) {
|
||||||
|
if (vertexBones[vid] != cUnowned) {
|
||||||
if(vertexBones[vid]!=cUnowned) {
|
//double entry
|
||||||
if(vertexBones[vid]==i) //double entry
|
if(vertexBones[vid]==i) {
|
||||||
{
|
|
||||||
ASSIMP_LOG_WARN("Encountered double entry in bone weights");
|
ASSIMP_LOG_WARN("Encountered double entry in bone weights");
|
||||||
}
|
} else {
|
||||||
else //TODO: track attraction in order to break tie
|
//TODO: track attraction in order to break tie
|
||||||
{
|
|
||||||
vertexBones[vid] = cCoowned;
|
vertexBones[vid] = cCoowned;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
vertexBones[vid] = i;
|
||||||
}
|
}
|
||||||
else vertexBones[vid] = i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isBoneNecessary[i]) {
|
if(!isBoneNecessary[i]) {
|
||||||
|
@ -227,13 +204,16 @@ bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh)
|
||||||
if(isInterstitialRequired) {
|
if(isInterstitialRequired) {
|
||||||
for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
|
for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
|
||||||
unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]];
|
unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]];
|
||||||
|
for (unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) {
|
||||||
for(unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) {
|
|
||||||
unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]];
|
unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]];
|
||||||
|
|
||||||
if(v!=w) {
|
if (v != w) {
|
||||||
if(v<pMesh->mNumBones) isBoneNecessary[v] = true;
|
if(v<pMesh->mNumBones) {
|
||||||
if(w<pMesh->mNumBones) isBoneNecessary[w] = true;
|
isBoneNecessary[v] = true;
|
||||||
|
}
|
||||||
|
if (w<pMesh->mNumBones) {
|
||||||
|
isBoneNecessary[w] = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -252,8 +232,7 @@ bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Splits the given mesh by bone count.
|
// Splits the given mesh by bone count.
|
||||||
void DeboneProcess::SplitMesh( const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const
|
void DeboneProcess::SplitMesh( const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const {
|
||||||
{
|
|
||||||
// same deal here as ConsiderMesh basically
|
// same deal here as ConsiderMesh basically
|
||||||
|
|
||||||
std::vector<bool> isBoneNecessary(pMesh->mNumBones,false);
|
std::vector<bool> isBoneNecessary(pMesh->mNumBones,false);
|
||||||
|
@ -371,8 +350,7 @@ void DeboneProcess::SplitMesh( const aiMesh* pMesh, std::vector< std::pair< aiMe
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Recursively updates the node's mesh list to account for the changed mesh list
|
// Recursively updates the node's mesh list to account for the changed mesh list
|
||||||
void DeboneProcess::UpdateNode(aiNode* pNode) const
|
void DeboneProcess::UpdateNode(aiNode* pNode) const {
|
||||||
{
|
|
||||||
// rebuild the node's mesh index list
|
// rebuild the node's mesh index list
|
||||||
|
|
||||||
std::vector<unsigned int> newMeshList;
|
std::vector<unsigned int> newMeshList;
|
||||||
|
@ -430,8 +408,7 @@ void DeboneProcess::UpdateNode(aiNode* pNode) const
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Apply the node transformation to a mesh
|
// Apply the node transformation to a mesh
|
||||||
void DeboneProcess::ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const
|
void DeboneProcess::ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const {
|
||||||
{
|
|
||||||
// Check whether we need to transform the coordinates at all
|
// Check whether we need to transform the coordinates at all
|
||||||
if (!mat.IsIdentity()) {
|
if (!mat.IsIdentity()) {
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ namespace Assimp {
|
||||||
class DeboneProcess : public BaseProcess {
|
class DeboneProcess : public BaseProcess {
|
||||||
public:
|
public:
|
||||||
DeboneProcess();
|
DeboneProcess();
|
||||||
~DeboneProcess();
|
~DeboneProcess() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the processing step is present in the given flag.
|
/** Returns whether the processing step is present in the given flag.
|
||||||
|
@ -79,14 +79,14 @@ public:
|
||||||
* @return true if the process is present in this flag fields,
|
* @return true if the process is present in this flag fields,
|
||||||
* false if not.
|
* false if not.
|
||||||
*/
|
*/
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Called prior to ExecuteOnScene().
|
/** Called prior to ExecuteOnScene().
|
||||||
* The function is a request to the process to update its configuration
|
* The function is a request to the process to update its configuration
|
||||||
* basing on the Importer's configuration property list.
|
* basing on the Importer's configuration property list.
|
||||||
*/
|
*/
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
@ -94,7 +94,7 @@ protected:
|
||||||
* At the moment a process is not supposed to fail.
|
* At the moment a process is not supposed to fail.
|
||||||
* @param pScene The imported data to work at.
|
* @param pScene The imported data to work at.
|
||||||
*/
|
*/
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Counts bones total/removable in a given mesh.
|
/** Counts bones total/removable in a given mesh.
|
||||||
|
|
|
@ -54,14 +54,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Constructor to be privately used by Importer
|
|
||||||
DropFaceNormalsProcess::DropFaceNormalsProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
DropFaceNormalsProcess::~DropFaceNormalsProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool DropFaceNormalsProcess::IsActive( unsigned int pFlags) const {
|
bool DropFaceNormalsProcess::IsActive( unsigned int pFlags) const {
|
||||||
|
|
|
@ -55,8 +55,8 @@ namespace Assimp {
|
||||||
*/
|
*/
|
||||||
class ASSIMP_API_WINONLY DropFaceNormalsProcess : public BaseProcess {
|
class ASSIMP_API_WINONLY DropFaceNormalsProcess : public BaseProcess {
|
||||||
public:
|
public:
|
||||||
DropFaceNormalsProcess();
|
DropFaceNormalsProcess() = default;
|
||||||
~DropFaceNormalsProcess();
|
~DropFaceNormalsProcess() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the processing step is present in the given flag field.
|
/** Returns whether the processing step is present in the given flag field.
|
||||||
|
@ -64,15 +64,14 @@ public:
|
||||||
* combination of #aiPostProcessSteps.
|
* combination of #aiPostProcessSteps.
|
||||||
* @return true if the process is present in this flag fields, false if not.
|
* @return true if the process is present in this flag fields, false if not.
|
||||||
*/
|
*/
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Executes the post processing step on the given imported data.
|
/** Executes the post processing step on the given imported data.
|
||||||
* At the moment a process is not supposed to fail.
|
* At the moment a process is not supposed to fail.
|
||||||
* @param pScene The imported data to work at.
|
* @param pScene The imported data to work at.
|
||||||
*/
|
*/
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool DropMeshFaceNormals(aiMesh* pcMesh);
|
bool DropMeshFaceNormals(aiMesh* pcMesh);
|
||||||
|
|
|
@ -49,10 +49,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
EmbedTexturesProcess::EmbedTexturesProcess() = default;
|
|
||||||
|
|
||||||
EmbedTexturesProcess::~EmbedTexturesProcess() = default;
|
|
||||||
|
|
||||||
bool EmbedTexturesProcess::IsActive(unsigned int pFlags) const {
|
bool EmbedTexturesProcess::IsActive(unsigned int pFlags) const {
|
||||||
return (pFlags & aiProcess_EmbedTextures) != 0;
|
return (pFlags & aiProcess_EmbedTextures) != 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,19 +62,19 @@ namespace Assimp {
|
||||||
class ASSIMP_API EmbedTexturesProcess : public BaseProcess {
|
class ASSIMP_API EmbedTexturesProcess : public BaseProcess {
|
||||||
public:
|
public:
|
||||||
/// The default class constructor.
|
/// The default class constructor.
|
||||||
EmbedTexturesProcess();
|
EmbedTexturesProcess() = default;
|
||||||
|
|
||||||
/// The class destructor.
|
/// The class destructor.
|
||||||
virtual ~EmbedTexturesProcess();
|
~EmbedTexturesProcess() override = default;
|
||||||
|
|
||||||
/// Overwritten, @see BaseProcess
|
/// Overwritten, @see BaseProcess
|
||||||
virtual bool IsActive(unsigned int pFlags) const;
|
bool IsActive(unsigned int pFlags) const override;
|
||||||
|
|
||||||
/// Overwritten, @see BaseProcess
|
/// Overwritten, @see BaseProcess
|
||||||
virtual void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp) override;
|
||||||
|
|
||||||
/// Overwritten, @see BaseProcess
|
/// Overwritten, @see BaseProcess
|
||||||
virtual void Execute(aiScene* pScene);
|
virtual void Execute(aiScene* pScene) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Resolve the path and add the file content to the scene as a texture.
|
// Resolve the path and add the file content to the scene as a texture.
|
||||||
|
|
|
@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "ProcessHelper.h"
|
#include "ProcessHelper.h"
|
||||||
#include "FindDegenerates.h"
|
#include "FindDegenerates.h"
|
||||||
|
#include "Geometry/GeometryUtils.h"
|
||||||
|
|
||||||
#include <assimp/Exceptional.h>
|
#include <assimp/Exceptional.h>
|
||||||
|
|
||||||
|
@ -63,10 +64,6 @@ FindDegeneratesProcess::FindDegeneratesProcess() :
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
FindDegeneratesProcess::~FindDegeneratesProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool FindDegeneratesProcess::IsActive( unsigned int pFlags) const {
|
bool FindDegeneratesProcess::IsActive( unsigned int pFlags) const {
|
||||||
|
@ -132,37 +129,6 @@ static void updateSceneGraph(aiNode* pNode, const std::unordered_map<unsigned in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ai_real heron( ai_real a, ai_real b, ai_real c ) {
|
|
||||||
ai_real s = (a + b + c) / 2;
|
|
||||||
ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), (ai_real)0.5 );
|
|
||||||
return area;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ai_real distance3D( const aiVector3D &vA, aiVector3D &vB ) {
|
|
||||||
const ai_real lx = ( vB.x - vA.x );
|
|
||||||
const ai_real ly = ( vB.y - vA.y );
|
|
||||||
const ai_real lz = ( vB.z - vA.z );
|
|
||||||
ai_real a = lx*lx + ly*ly + lz*lz;
|
|
||||||
ai_real d = pow( a, (ai_real)0.5 );
|
|
||||||
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ai_real calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh ) {
|
|
||||||
ai_real area = 0;
|
|
||||||
|
|
||||||
aiVector3D vA( mesh->mVertices[ face.mIndices[ 0 ] ] );
|
|
||||||
aiVector3D vB( mesh->mVertices[ face.mIndices[ 1 ] ] );
|
|
||||||
aiVector3D vC( mesh->mVertices[ face.mIndices[ 2 ] ] );
|
|
||||||
|
|
||||||
ai_real a( distance3D( vA, vB ) );
|
|
||||||
ai_real b( distance3D( vB, vC ) );
|
|
||||||
ai_real c( distance3D( vC, vA ) );
|
|
||||||
area = heron( a, b, c );
|
|
||||||
|
|
||||||
return area;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported mesh
|
// Executes the post processing step on the given imported mesh
|
||||||
bool FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
|
bool FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
|
||||||
|
@ -218,7 +184,7 @@ bool FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
|
||||||
|
|
||||||
if ( mConfigCheckAreaOfTriangle ) {
|
if ( mConfigCheckAreaOfTriangle ) {
|
||||||
if ( face.mNumIndices == 3 ) {
|
if ( face.mNumIndices == 3 ) {
|
||||||
ai_real area = calculateAreaOfTriangle( face, mesh );
|
ai_real area = GeometryUtils::calculateAreaOfTriangle( face, mesh );
|
||||||
if (area < ai_epsilon) {
|
if (area < ai_epsilon) {
|
||||||
if ( mConfigRemoveDegenerates ) {
|
if ( mConfigRemoveDegenerates ) {
|
||||||
remove_me[ a ] = true;
|
remove_me[ a ] = true;
|
||||||
|
|
|
@ -59,19 +59,19 @@ namespace Assimp {
|
||||||
class ASSIMP_API FindDegeneratesProcess : public BaseProcess {
|
class ASSIMP_API FindDegeneratesProcess : public BaseProcess {
|
||||||
public:
|
public:
|
||||||
FindDegeneratesProcess();
|
FindDegeneratesProcess();
|
||||||
~FindDegeneratesProcess();
|
~FindDegeneratesProcess() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Check whether step is active
|
// Check whether step is active
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Execute step on a given scene
|
// Execute step on a given scene
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Setup import settings
|
// Setup import settings
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp) override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Execute step on a given mesh
|
// Execute step on a given mesh
|
||||||
|
@ -105,23 +105,19 @@ private:
|
||||||
bool mConfigCheckAreaOfTriangle;
|
bool mConfigCheckAreaOfTriangle;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline
|
inline void FindDegeneratesProcess::EnableInstantRemoval(bool enabled) {
|
||||||
void FindDegeneratesProcess::EnableInstantRemoval(bool enabled) {
|
|
||||||
mConfigRemoveDegenerates = enabled;
|
mConfigRemoveDegenerates = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline bool FindDegeneratesProcess::IsInstantRemoval() const {
|
||||||
bool FindDegeneratesProcess::IsInstantRemoval() const {
|
|
||||||
return mConfigRemoveDegenerates;
|
return mConfigRemoveDegenerates;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline void FindDegeneratesProcess::EnableAreaCheck( bool enabled ) {
|
||||||
void FindDegeneratesProcess::EnableAreaCheck( bool enabled ) {
|
|
||||||
mConfigCheckAreaOfTriangle = enabled;
|
mConfigCheckAreaOfTriangle = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline bool FindDegeneratesProcess::isAreaCheckEnabled() const {
|
||||||
bool FindDegeneratesProcess::isAreaCheckEnabled() const {
|
|
||||||
return mConfigCheckAreaOfTriangle;
|
return mConfigCheckAreaOfTriangle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,10 +58,6 @@ FindInstancesProcess::FindInstancesProcess()
|
||||||
: configSpeedFlag (false)
|
: configSpeedFlag (false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
FindInstancesProcess::~FindInstancesProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool FindInstancesProcess::IsActive( unsigned int pFlags) const
|
bool FindInstancesProcess::IsActive( unsigned int pFlags) const
|
||||||
|
|
|
@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "PostProcessing/ProcessHelper.h"
|
#include "PostProcessing/ProcessHelper.h"
|
||||||
|
|
||||||
class FindInstancesProcessTest;
|
class FindInstancesProcessTest;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
@ -60,8 +61,7 @@ namespace Assimp {
|
||||||
* @param in Input mesh
|
* @param in Input mesh
|
||||||
* @return Hash.
|
* @return Hash.
|
||||||
*/
|
*/
|
||||||
inline
|
inline uint64_t GetMeshHash(aiMesh* in) {
|
||||||
uint64_t GetMeshHash(aiMesh* in) {
|
|
||||||
ai_assert(nullptr != in);
|
ai_assert(nullptr != in);
|
||||||
|
|
||||||
// ... get an unique value representing the vertex format of the mesh
|
// ... get an unique value representing the vertex format of the mesh
|
||||||
|
@ -83,8 +83,7 @@ uint64_t GetMeshHash(aiMesh* in) {
|
||||||
* @param e Epsilon
|
* @param e Epsilon
|
||||||
* @return true if the arrays are identical
|
* @return true if the arrays are identical
|
||||||
*/
|
*/
|
||||||
inline
|
inline bool CompareArrays(const aiVector3D* first, const aiVector3D* second,
|
||||||
bool CompareArrays(const aiVector3D* first, const aiVector3D* second,
|
|
||||||
unsigned int size, float e) {
|
unsigned int size, float e) {
|
||||||
for (const aiVector3D* end = first+size; first != end; ++first,++second) {
|
for (const aiVector3D* end = first+size; first != end; ++first,++second) {
|
||||||
if ( (*first - *second).SquareLength() >= e)
|
if ( (*first - *second).SquareLength() >= e)
|
||||||
|
@ -107,31 +106,27 @@ inline bool CompareArrays(const aiColor4D* first, const aiColor4D* second,
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** @brief A post-processing steps to search for instanced meshes
|
/** @brief A post-processing steps to search for instanced meshes
|
||||||
*/
|
*/
|
||||||
class FindInstancesProcess : public BaseProcess
|
class FindInstancesProcess : public BaseProcess {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FindInstancesProcess();
|
FindInstancesProcess();
|
||||||
~FindInstancesProcess();
|
~FindInstancesProcess() override = default;
|
||||||
|
|
||||||
public:
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Check whether step is active in given flags combination
|
// Check whether step is active in given flags combination
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Execute step on a given scene
|
// Execute step on a given scene
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Setup properties prior to executing the process
|
// Setup properties prior to executing the process
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool configSpeedFlag;
|
bool configSpeedFlag;
|
||||||
|
|
||||||
}; // ! end class FindInstancesProcess
|
}; // ! end class FindInstancesProcess
|
||||||
|
|
||||||
} // ! end namespace Assimp
|
} // ! end namespace Assimp
|
||||||
|
|
||||||
#endif // !! AI_FINDINSTANCES_H_INC
|
#endif // !! AI_FINDINSTANCES_H_INC
|
||||||
|
|
|
@ -60,10 +60,6 @@ FindInvalidDataProcess::FindInvalidDataProcess() :
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
FindInvalidDataProcess::~FindInvalidDataProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool FindInvalidDataProcess::IsActive(unsigned int pFlags) const {
|
bool FindInvalidDataProcess::IsActive(unsigned int pFlags) const {
|
||||||
|
|
|
@ -64,35 +64,37 @@ namespace Assimp {
|
||||||
* which have zero normal vectors. */
|
* which have zero normal vectors. */
|
||||||
class ASSIMP_API FindInvalidDataProcess : public BaseProcess {
|
class ASSIMP_API FindInvalidDataProcess : public BaseProcess {
|
||||||
public:
|
public:
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/// The default class constructor / destructor.
|
||||||
FindInvalidDataProcess();
|
FindInvalidDataProcess();
|
||||||
~FindInvalidDataProcess();
|
~FindInvalidDataProcess() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//
|
/// Returns active state.
|
||||||
bool IsActive(unsigned int pFlags) const;
|
bool IsActive(unsigned int pFlags) const override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Setup import settings
|
/// Setup import settings
|
||||||
void SetupProperties(const Importer *pImp);
|
void SetupProperties(const Importer *pImp) override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Run the step
|
/// Run the step
|
||||||
void Execute(aiScene *pScene);
|
void Execute(aiScene *pScene) override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Executes the post-processing step on the given mesh
|
/// Executes the post-processing step on the given mesh
|
||||||
* @param pMesh The mesh to process.
|
/// @param pMesh The mesh to process.
|
||||||
* @return 0 - nothing, 1 - removed sth, 2 - please delete me */
|
/// @return 0 - nothing, 1 - removed sth, 2 - please delete me */
|
||||||
int ProcessMesh(aiMesh *pMesh);
|
int ProcessMesh(aiMesh *pMesh);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Executes the post-processing step on the given animation
|
/// Executes the post-processing step on the given animation
|
||||||
* @param anim The animation to process. */
|
/// @param anim The animation to process. */
|
||||||
void ProcessAnimation(aiAnimation *anim);
|
void ProcessAnimation(aiAnimation *anim);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Executes the post-processing step on the given anim channel
|
/// Executes the post-processing step on the given anim channel
|
||||||
* @param anim The animation channel to process.*/
|
/// @param anim The animation channel to process.*/
|
||||||
void ProcessAnimationChannel(aiNodeAnim *anim);
|
void ProcessAnimationChannel(aiNodeAnim *anim);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -56,26 +56,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Constructor to be privately used by Importer
|
|
||||||
FixInfacingNormalsProcess::FixInfacingNormalsProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
FixInfacingNormalsProcess::~FixInfacingNormalsProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool FixInfacingNormalsProcess::IsActive( unsigned int pFlags) const
|
bool FixInfacingNormalsProcess::IsActive( unsigned int pFlags) const {
|
||||||
{
|
|
||||||
return (pFlags & aiProcess_FixInfacingNormals) != 0;
|
return (pFlags & aiProcess_FixInfacingNormals) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
void FixInfacingNormalsProcess::Execute( aiScene* pScene)
|
void FixInfacingNormalsProcess::Execute( aiScene* pScene) {
|
||||||
{
|
|
||||||
ASSIMP_LOG_DEBUG("FixInfacingNormalsProcess begin");
|
ASSIMP_LOG_DEBUG("FixInfacingNormalsProcess begin");
|
||||||
|
|
||||||
bool bHas( false );
|
bool bHas( false );
|
||||||
|
|
|
@ -49,8 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
struct aiMesh;
|
struct aiMesh;
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp {
|
||||||
{
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** The FixInfacingNormalsProcess tries to determine whether the normal
|
/** The FixInfacingNormalsProcess tries to determine whether the normal
|
||||||
|
@ -59,8 +58,10 @@ namespace Assimp
|
||||||
*/
|
*/
|
||||||
class FixInfacingNormalsProcess : public BaseProcess {
|
class FixInfacingNormalsProcess : public BaseProcess {
|
||||||
public:
|
public:
|
||||||
FixInfacingNormalsProcess();
|
// -------------------------------------------------------------------
|
||||||
~FixInfacingNormalsProcess();
|
/// The default class constructor / destructor.
|
||||||
|
FixInfacingNormalsProcess() = default;
|
||||||
|
~FixInfacingNormalsProcess() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the processing step is present in the given flag field.
|
/** Returns whether the processing step is present in the given flag field.
|
||||||
|
@ -68,14 +69,14 @@ public:
|
||||||
* combination of #aiPostProcessSteps.
|
* combination of #aiPostProcessSteps.
|
||||||
* @return true if the process is present in this flag fields, false if not.
|
* @return true if the process is present in this flag fields, false if not.
|
||||||
*/
|
*/
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Executes the post processing step on the given imported data.
|
/** Executes the post processing step on the given imported data.
|
||||||
* At the moment a process is not supposed to fail.
|
* At the moment a process is not supposed to fail.
|
||||||
* @param pScene The imported data to work at.
|
* @param pScene The imported data to work at.
|
||||||
*/
|
*/
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
|
@ -48,10 +48,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
GenBoundingBoxesProcess::GenBoundingBoxesProcess() = default;
|
|
||||||
|
|
||||||
GenBoundingBoxesProcess::~GenBoundingBoxesProcess() = default;
|
|
||||||
|
|
||||||
bool GenBoundingBoxesProcess::IsActive(unsigned int pFlags) const {
|
bool GenBoundingBoxesProcess::IsActive(unsigned int pFlags) const {
|
||||||
return 0 != ( pFlags & aiProcess_GenBoundingBoxes );
|
return 0 != ( pFlags & aiProcess_GenBoundingBoxes );
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ conditions are met:
|
||||||
copyright notice, this list of conditions and the
|
copyright notice, this list of conditions and the
|
||||||
following disclaimer in the documentation and/or other
|
following disclaimer in the documentation and/or other
|
||||||
materials provided with the distribution.
|
materials provided with the distribution.
|
||||||
|
s
|
||||||
* Neither the name of the assimp team, nor the names of its
|
* Neither the name of the assimp team, nor the names of its
|
||||||
contributors may be used to endorse or promote products
|
contributors may be used to endorse or promote products
|
||||||
derived from this software without specific prior
|
derived from this software without specific prior
|
||||||
|
@ -54,18 +54,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
/** Post-processing process to find axis-aligned bounding volumes for amm meshes
|
/**
|
||||||
* used in a scene
|
* @brief Post-processing process to find axis-aligned bounding volumes for amm meshes
|
||||||
|
* used in a scene.
|
||||||
*/
|
*/
|
||||||
class ASSIMP_API GenBoundingBoxesProcess : public BaseProcess {
|
class ASSIMP_API GenBoundingBoxesProcess : public BaseProcess {
|
||||||
public:
|
public:
|
||||||
/// The class constructor.
|
// -------------------------------------------------------------------
|
||||||
GenBoundingBoxesProcess();
|
/// The default class constructor / destructor.
|
||||||
/// The class destructor.
|
GenBoundingBoxesProcess() = default;
|
||||||
~GenBoundingBoxesProcess();
|
~GenBoundingBoxesProcess() override = default;
|
||||||
/// Will return true, if aiProcess_GenBoundingBoxes is defined.
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/// @brief Will return true, if aiProcess_GenBoundingBoxes is defined.
|
||||||
bool IsActive(unsigned int pFlags) const override;
|
bool IsActive(unsigned int pFlags) const override;
|
||||||
/// The execution callback.
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/// @brief The execution callback.
|
||||||
void Execute(aiScene* pScene) override;
|
void Execute(aiScene* pScene) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -54,14 +54,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Constructor to be privately used by Importer
|
|
||||||
GenFaceNormalsProcess::GenFaceNormalsProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
GenFaceNormalsProcess::~GenFaceNormalsProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool GenFaceNormalsProcess::IsActive(unsigned int pFlags) const {
|
bool GenFaceNormalsProcess::IsActive(unsigned int pFlags) const {
|
||||||
|
|
|
@ -47,35 +47,33 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "Common/BaseProcess.h"
|
#include "Common/BaseProcess.h"
|
||||||
#include <assimp/mesh.h>
|
#include <assimp/mesh.h>
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp {
|
||||||
{
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** The GenFaceNormalsProcess computes face normals for all faces of all meshes
|
/**
|
||||||
*/
|
* @brief The GenFaceNormalsProcess computes face normals for all faces of all meshes
|
||||||
class ASSIMP_API_WINONLY GenFaceNormalsProcess : public BaseProcess
|
*/
|
||||||
{
|
class ASSIMP_API_WINONLY GenFaceNormalsProcess : public BaseProcess {
|
||||||
public:
|
public:
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/// The default class constructor / destructor.
|
||||||
|
GenFaceNormalsProcess() = default;
|
||||||
|
~GenFaceNormalsProcess() override = default;
|
||||||
|
|
||||||
GenFaceNormalsProcess();
|
|
||||||
~GenFaceNormalsProcess();
|
|
||||||
|
|
||||||
public:
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the processing step is present in the given flag field.
|
/** Returns whether the processing step is present in the given flag field.
|
||||||
* @param pFlags The processing flags the importer was called with. A bitwise
|
* @param pFlags The processing flags the importer was called with. A bitwise
|
||||||
* combination of #aiPostProcessSteps.
|
* combination of #aiPostProcessSteps.
|
||||||
* @return true if the process is present in this flag fields, false if not.
|
* @return true if the process is present in this flag fields, false if not.
|
||||||
*/
|
*/
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Executes the post processing step on the given imported data.
|
/** Executes the post processing step on the given imported data.
|
||||||
* At the moment a process is not supposed to fail.
|
* At the moment a process is not supposed to fail.
|
||||||
* @param pScene The imported data to work at.
|
* @param pScene The imported data to work at.
|
||||||
*/
|
*/
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool GenMeshFaceNormals(aiMesh* pcMesh);
|
bool GenMeshFaceNormals(aiMesh* pcMesh);
|
||||||
|
|
|
@ -60,10 +60,6 @@ GenVertexNormalsProcess::GenVertexNormalsProcess() :
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
GenVertexNormalsProcess::~GenVertexNormalsProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool GenVertexNormalsProcess::IsActive(unsigned int pFlags) const {
|
bool GenVertexNormalsProcess::IsActive(unsigned int pFlags) const {
|
||||||
|
@ -109,11 +105,11 @@ void GenVertexNormalsProcess::Execute(aiScene *pScene) {
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
bool GenVertexNormalsProcess::GenMeshVertexNormals(aiMesh *pMesh, unsigned int meshIndex) {
|
bool GenVertexNormalsProcess::GenMeshVertexNormals(aiMesh *pMesh, unsigned int meshIndex) {
|
||||||
if (nullptr != pMesh->mNormals) {
|
if (nullptr != pMesh->mNormals) {
|
||||||
if (force_)
|
if (!force_) {
|
||||||
delete[] pMesh->mNormals;
|
|
||||||
else
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
delete[] pMesh->mNormals;
|
||||||
|
}
|
||||||
|
|
||||||
// If the mesh consists of lines and/or points but not of
|
// If the mesh consists of lines and/or points but not of
|
||||||
// triangles or higher-order polygons the normal vectors
|
// triangles or higher-order polygons the normal vectors
|
||||||
|
@ -144,8 +140,9 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals(aiMesh *pMesh, unsigned int m
|
||||||
const aiVector3D *pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices - 1]];
|
const aiVector3D *pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices - 1]];
|
||||||
// Boolean XOR - if either but not both of these flags is set, then the winding order has
|
// Boolean XOR - if either but not both of these flags is set, then the winding order has
|
||||||
// changed and the cross product to calculate the normal needs to be reversed
|
// changed and the cross product to calculate the normal needs to be reversed
|
||||||
if (flippedWindingOrder_ != leftHanded_)
|
if (flippedWindingOrder_ != leftHanded_) {
|
||||||
std::swap(pV2, pV3);
|
std::swap(pV2, pV3);
|
||||||
|
}
|
||||||
const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe();
|
const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe();
|
||||||
|
|
||||||
for (unsigned int i = 0; i < face.mNumIndices; ++i) {
|
for (unsigned int i = 0; i < face.mNumIndices; ++i) {
|
||||||
|
|
|
@ -60,8 +60,10 @@ namespace Assimp {
|
||||||
*/
|
*/
|
||||||
class ASSIMP_API GenVertexNormalsProcess : public BaseProcess {
|
class ASSIMP_API GenVertexNormalsProcess : public BaseProcess {
|
||||||
public:
|
public:
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/// The default class constructor / destructor.
|
||||||
GenVertexNormalsProcess();
|
GenVertexNormalsProcess();
|
||||||
~GenVertexNormalsProcess();
|
~GenVertexNormalsProcess() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the processing step is present in the given flag.
|
/** Returns whether the processing step is present in the given flag.
|
||||||
|
@ -70,22 +72,21 @@ public:
|
||||||
* @return true if the process is present in this flag fields,
|
* @return true if the process is present in this flag fields,
|
||||||
* false if not.
|
* false if not.
|
||||||
*/
|
*/
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Called prior to ExecuteOnScene().
|
/** Called prior to ExecuteOnScene().
|
||||||
* The function is a request to the process to update its configuration
|
* The function is a request to the process to update its configuration
|
||||||
* basing on the Importer's configuration property list.
|
* basing on the Importer's configuration property list.
|
||||||
*/
|
*/
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp) override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Executes the post processing step on the given imported data.
|
/** Executes the post processing step on the given imported data.
|
||||||
* At the moment a process is not supposed to fail.
|
* At the moment a process is not supposed to fail.
|
||||||
* @param pScene The imported data to work at.
|
* @param pScene The imported data to work at.
|
||||||
*/
|
*/
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
|
|
||||||
// setter for configMaxAngle
|
// setter for configMaxAngle
|
||||||
inline void SetMaxSmoothAngle(ai_real f) {
|
inline void SetMaxSmoothAngle(ai_real f) {
|
||||||
|
|
|
@ -68,10 +68,6 @@ ImproveCacheLocalityProcess::ImproveCacheLocalityProcess()
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
ImproveCacheLocalityProcess::~ImproveCacheLocalityProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool ImproveCacheLocalityProcess::IsActive( unsigned int pFlags) const {
|
bool ImproveCacheLocalityProcess::IsActive( unsigned int pFlags) const {
|
||||||
|
|
|
@ -51,8 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
struct aiMesh;
|
struct aiMesh;
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp {
|
||||||
{
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** The ImproveCacheLocalityProcess reorders all faces for improved vertex
|
/** The ImproveCacheLocalityProcess reorders all faces for improved vertex
|
||||||
|
@ -61,26 +60,24 @@ namespace Assimp
|
||||||
*
|
*
|
||||||
* @note This step expects triagulated input data.
|
* @note This step expects triagulated input data.
|
||||||
*/
|
*/
|
||||||
class ImproveCacheLocalityProcess : public BaseProcess
|
class ImproveCacheLocalityProcess : public BaseProcess {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/// The default class constructor / destructor.
|
||||||
ImproveCacheLocalityProcess();
|
ImproveCacheLocalityProcess();
|
||||||
~ImproveCacheLocalityProcess();
|
~ImproveCacheLocalityProcess() override = default;
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Check whether the pp step is active
|
// Check whether the pp step is active
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Executes the pp step on a given scene
|
// Executes the pp step on a given scene
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Configures the pp step
|
// Configures the pp step
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
|
@ -51,8 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
struct aiMesh;
|
struct aiMesh;
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp {
|
||||||
{
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** The JoinVerticesProcess unites identical vertices in all imported meshes.
|
/** The JoinVerticesProcess unites identical vertices in all imported meshes.
|
||||||
|
@ -65,12 +64,9 @@ namespace Assimp
|
||||||
class ASSIMP_API JoinVerticesProcess : public BaseProcess {
|
class ASSIMP_API JoinVerticesProcess : public BaseProcess {
|
||||||
public:
|
public:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/// @brief The default class constructor.
|
/// The default class constructor / destructor.
|
||||||
JoinVerticesProcess() = default;
|
JoinVerticesProcess() = default;
|
||||||
|
~JoinVerticesProcess() override = default;
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/// @brief The default class destructor.
|
|
||||||
~JoinVerticesProcess() = default;
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the processing step is present in the given flag field.
|
/** Returns whether the processing step is present in the given flag field.
|
||||||
|
@ -78,14 +74,14 @@ public:
|
||||||
* combination of #aiPostProcessSteps.
|
* combination of #aiPostProcessSteps.
|
||||||
* @return true if the process is present in this flag fields, false if not.
|
* @return true if the process is present in this flag fields, false if not.
|
||||||
*/
|
*/
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Executes the post processing step on the given imported data.
|
/** Executes the post processing step on the given imported data.
|
||||||
* At the moment a process is not supposed to fail.
|
* At the moment a process is not supposed to fail.
|
||||||
* @param pScene The imported data to work at.
|
* @param pScene The imported data to work at.
|
||||||
*/
|
*/
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Unites identical vertices in the given mesh.
|
/** Unites identical vertices in the given mesh.
|
||||||
|
|
|
@ -53,11 +53,9 @@ namespace Assimp {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
LimitBoneWeightsProcess::LimitBoneWeightsProcess() : mMaxWeights(AI_LMW_MAX_WEIGHTS) {}
|
LimitBoneWeightsProcess::LimitBoneWeightsProcess() : mMaxWeights(AI_LMW_MAX_WEIGHTS) {
|
||||||
|
// empty
|
||||||
// ------------------------------------------------------------------------------------------------
|
}
|
||||||
// Destructor, private as well
|
|
||||||
LimitBoneWeightsProcess::~LimitBoneWeightsProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
|
|
|
@ -74,8 +74,10 @@ namespace Assimp {
|
||||||
*/
|
*/
|
||||||
class ASSIMP_API LimitBoneWeightsProcess : public BaseProcess {
|
class ASSIMP_API LimitBoneWeightsProcess : public BaseProcess {
|
||||||
public:
|
public:
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/// The default class constructor / destructor.
|
||||||
LimitBoneWeightsProcess();
|
LimitBoneWeightsProcess();
|
||||||
~LimitBoneWeightsProcess();
|
~LimitBoneWeightsProcess() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the processing step is present in the given flag.
|
/** Returns whether the processing step is present in the given flag.
|
||||||
|
@ -84,27 +86,27 @@ public:
|
||||||
* @return true if the process is present in this flag fields,
|
* @return true if the process is present in this flag fields,
|
||||||
* false if not.
|
* false if not.
|
||||||
*/
|
*/
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Called prior to ExecuteOnScene().
|
/** Called prior to ExecuteOnScene().
|
||||||
* The function is a request to the process to update its configuration
|
* The function is a request to the process to update its configuration
|
||||||
* basing on the Importer's configuration property list.
|
* basing on the Importer's configuration property list.
|
||||||
*/
|
*/
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp) override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Limits the bone weight count for all vertices in the given mesh.
|
|
||||||
* @param pMesh The mesh to process.
|
|
||||||
*/
|
|
||||||
void ProcessMesh( aiMesh* pMesh);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Executes the post processing step on the given imported data.
|
/** Executes the post processing step on the given imported data.
|
||||||
* At the moment a process is not supposed to fail.
|
* At the moment a process is not supposed to fail.
|
||||||
* @param pScene The imported data to work at.
|
* @param pScene The imported data to work at.
|
||||||
*/
|
*/
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Limits the bone weight count for all vertices in the given mesh.
|
||||||
|
* @param pMesh The mesh to process.
|
||||||
|
*/
|
||||||
|
void ProcessMesh( aiMesh* pMesh);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Describes a bone weight on a vertex */
|
/** Describes a bone weight on a vertex */
|
||||||
|
|
|
@ -49,10 +49,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
MakeVerboseFormatProcess::MakeVerboseFormatProcess() = default;
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
MakeVerboseFormatProcess::~MakeVerboseFormatProcess() = default;
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
void MakeVerboseFormatProcess::Execute(aiScene *pScene) {
|
void MakeVerboseFormatProcess::Execute(aiScene *pScene) {
|
||||||
|
|
|
@ -66,22 +66,19 @@ namespace Assimp {
|
||||||
* The step has been added because it was required by the viewer, however
|
* The step has been added because it was required by the viewer, however
|
||||||
* it has been moved to the main library since others might find it
|
* it has been moved to the main library since others might find it
|
||||||
* useful, too. */
|
* useful, too. */
|
||||||
class ASSIMP_API_WINONLY MakeVerboseFormatProcess : public BaseProcess
|
class ASSIMP_API_WINONLY MakeVerboseFormatProcess : public BaseProcess {
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
|
|
||||||
MakeVerboseFormatProcess();
|
|
||||||
~MakeVerboseFormatProcess();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/// The default class constructor / destructor.
|
||||||
|
MakeVerboseFormatProcess() = default;
|
||||||
|
~MakeVerboseFormatProcess() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the processing step is present in the given flag field.
|
/** Returns whether the processing step is present in the given flag field.
|
||||||
* @param pFlags The processing flags the importer was called with. A bitwise
|
* @param pFlags The processing flags the importer was called with. A bitwise
|
||||||
* combination of #aiPostProcessSteps.
|
* combination of #aiPostProcessSteps.
|
||||||
* @return true if the process is present in this flag fields, false if not */
|
* @return true if the process is present in this flag fields, false if not */
|
||||||
bool IsActive( unsigned int /*pFlags*/ ) const
|
bool IsActive( unsigned int /*pFlags*/ ) const override
|
||||||
{
|
{
|
||||||
// NOTE: There is no direct flag that corresponds to
|
// NOTE: There is no direct flag that corresponds to
|
||||||
// this postprocess step.
|
// this postprocess step.
|
||||||
|
@ -92,7 +89,7 @@ public:
|
||||||
/** Executes the post processing step on the given imported data.
|
/** Executes the post processing step on the given imported data.
|
||||||
* At the moment a process is not supposed to fail.
|
* At the moment a process is not supposed to fail.
|
||||||
* @param pScene The imported data to work at. */
|
* @param pScene The imported data to work at. */
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -78,10 +78,6 @@ OptimizeGraphProcess::OptimizeGraphProcess() :
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
OptimizeGraphProcess::~OptimizeGraphProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool OptimizeGraphProcess::IsActive(unsigned int pFlags) const {
|
bool OptimizeGraphProcess::IsActive(unsigned int pFlags) const {
|
||||||
|
|
|
@ -71,8 +71,10 @@ namespace Assimp {
|
||||||
*/
|
*/
|
||||||
class OptimizeGraphProcess : public BaseProcess {
|
class OptimizeGraphProcess : public BaseProcess {
|
||||||
public:
|
public:
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/// The default class constructor / destructor.
|
||||||
OptimizeGraphProcess();
|
OptimizeGraphProcess();
|
||||||
~OptimizeGraphProcess();
|
~OptimizeGraphProcess() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
bool IsActive( unsigned int pFlags) const override;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
|
@ -69,10 +69,6 @@ OptimizeMeshesProcess::OptimizeMeshesProcess()
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
OptimizeMeshesProcess::~OptimizeMeshesProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool OptimizeMeshesProcess::IsActive( unsigned int pFlags) const
|
bool OptimizeMeshesProcess::IsActive( unsigned int pFlags) const
|
||||||
|
|
|
@ -68,11 +68,10 @@ namespace Assimp {
|
||||||
*/
|
*/
|
||||||
class OptimizeMeshesProcess : public BaseProcess {
|
class OptimizeMeshesProcess : public BaseProcess {
|
||||||
public:
|
public:
|
||||||
/// @brief The class constructor.
|
// -------------------------------------------------------------------
|
||||||
|
/// The default class constructor / destructor.
|
||||||
OptimizeMeshesProcess();
|
OptimizeMeshesProcess();
|
||||||
|
~OptimizeMeshesProcess() override = default;
|
||||||
/// @brief The class destructor.
|
|
||||||
~OptimizeMeshesProcess();
|
|
||||||
|
|
||||||
/** @brief Internal utility to store additional mesh info
|
/** @brief Internal utility to store additional mesh info
|
||||||
*/
|
*/
|
||||||
|
@ -94,16 +93,14 @@ public:
|
||||||
unsigned int output_id;
|
unsigned int output_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp) override;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Specify whether you want meshes with different
|
/** @brief Specify whether you want meshes with different
|
||||||
|
|
|
@ -68,10 +68,6 @@ PretransformVertices::PretransformVertices() :
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
PretransformVertices::~PretransformVertices() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool PretransformVertices::IsActive(unsigned int pFlags) const {
|
bool PretransformVertices::IsActive(unsigned int pFlags) const {
|
||||||
|
|
|
@ -68,8 +68,10 @@ namespace Assimp {
|
||||||
*/
|
*/
|
||||||
class ASSIMP_API PretransformVertices : public BaseProcess {
|
class ASSIMP_API PretransformVertices : public BaseProcess {
|
||||||
public:
|
public:
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/// The default class constructor / destructor.
|
||||||
PretransformVertices();
|
PretransformVertices();
|
||||||
~PretransformVertices();
|
~PretransformVertices() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Check whether step is active
|
// Check whether step is active
|
||||||
|
|
|
@ -62,10 +62,6 @@ RemoveRedundantMatsProcess::RemoveRedundantMatsProcess()
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
RemoveRedundantMatsProcess::~RemoveRedundantMatsProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool RemoveRedundantMatsProcess::IsActive( unsigned int pFlags) const
|
bool RemoveRedundantMatsProcess::IsActive( unsigned int pFlags) const
|
||||||
|
|
|
@ -59,23 +59,22 @@ namespace Assimp {
|
||||||
*/
|
*/
|
||||||
class ASSIMP_API RemoveRedundantMatsProcess : public BaseProcess {
|
class ASSIMP_API RemoveRedundantMatsProcess : public BaseProcess {
|
||||||
public:
|
public:
|
||||||
/// The default class constructor.
|
// -------------------------------------------------------------------
|
||||||
|
/// The default class constructor / destructor.
|
||||||
RemoveRedundantMatsProcess();
|
RemoveRedundantMatsProcess();
|
||||||
|
~RemoveRedundantMatsProcess() override = default;
|
||||||
/// The class destructor.
|
|
||||||
~RemoveRedundantMatsProcess();
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Check whether step is active
|
// Check whether step is active
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Execute step on a given scene
|
// Execute step on a given scene
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Setup import settings
|
// Setup import settings
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp) override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Set list of fixed (inmutable) materials
|
/** @brief Set list of fixed (inmutable) materials
|
||||||
|
|
|
@ -56,10 +56,6 @@ using namespace Assimp;
|
||||||
RemoveVCProcess::RemoveVCProcess() :
|
RemoveVCProcess::RemoveVCProcess() :
|
||||||
configDeleteFlags(), mScene() {}
|
configDeleteFlags(), mScene() {}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
RemoveVCProcess::~RemoveVCProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool RemoveVCProcess::IsActive(unsigned int pFlags) const {
|
bool RemoveVCProcess::IsActive(unsigned int pFlags) const {
|
||||||
|
|
|
@ -58,11 +58,10 @@ namespace Assimp {
|
||||||
*/
|
*/
|
||||||
class ASSIMP_API RemoveVCProcess : public BaseProcess {
|
class ASSIMP_API RemoveVCProcess : public BaseProcess {
|
||||||
public:
|
public:
|
||||||
/// The default class constructor.
|
// -------------------------------------------------------------------
|
||||||
|
/// The default class constructor / destructor.
|
||||||
RemoveVCProcess();
|
RemoveVCProcess();
|
||||||
|
~RemoveVCProcess() override = default;
|
||||||
/// The class destructor.
|
|
||||||
~RemoveVCProcess();
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the processing step is present in the given flag field.
|
/** Returns whether the processing step is present in the given flag field.
|
||||||
|
@ -70,37 +69,35 @@ public:
|
||||||
* combination of #aiPostProcessSteps.
|
* combination of #aiPostProcessSteps.
|
||||||
* @return true if the process is present in this flag fields, false if not.
|
* @return true if the process is present in this flag fields, false if not.
|
||||||
*/
|
*/
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Executes the post processing step on the given imported data.
|
/** Executes the post processing step on the given imported data.
|
||||||
* At the moment a process is not supposed to fail.
|
* At the moment a process is not supposed to fail.
|
||||||
* @param pScene The imported data to work at.
|
* @param pScene The imported data to work at.
|
||||||
*/
|
*/
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Called prior to ExecuteOnScene().
|
/** Called prior to ExecuteOnScene().
|
||||||
* The function is a request to the process to update its configuration
|
* The function is a request to the process to update its configuration
|
||||||
* basing on the Importer's configuration property list.
|
* basing on the Importer's configuration property list.
|
||||||
*/
|
*/
|
||||||
virtual void SetupProperties(const Importer* pImp);
|
virtual void SetupProperties(const Importer* pImp) override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Manually setup the configuration flags for the step
|
/** Manually setup the configuration flags for the step
|
||||||
*
|
*
|
||||||
* @param Bitwise combination of the #aiComponent enumerated values.
|
* @param Bitwise combination of the #aiComponent enumerated values.
|
||||||
*/
|
*/
|
||||||
void SetDeleteFlags(unsigned int f)
|
void SetDeleteFlags(unsigned int f) {
|
||||||
{
|
|
||||||
configDeleteFlags = f;
|
configDeleteFlags = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Query the current configuration.
|
/** Query the current configuration.
|
||||||
*/
|
*/
|
||||||
unsigned int GetDeleteFlags() const
|
unsigned int GetDeleteFlags() const {
|
||||||
{
|
|
||||||
return configDeleteFlags;
|
return configDeleteFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,25 +47,27 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
ScaleProcess::ScaleProcess()
|
// ------------------------------------------------------------------------------------------------
|
||||||
: BaseProcess()
|
ScaleProcess::ScaleProcess() : BaseProcess(), mScale( AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT ) {
|
||||||
, mScale( AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT ) {
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
ScaleProcess::~ScaleProcess() = default;
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
void ScaleProcess::setScale( ai_real scale ) {
|
void ScaleProcess::setScale( ai_real scale ) {
|
||||||
mScale = scale;
|
mScale = scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
ai_real ScaleProcess::getScale() const {
|
ai_real ScaleProcess::getScale() const {
|
||||||
return mScale;
|
return mScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool ScaleProcess::IsActive( unsigned int pFlags ) const {
|
bool ScaleProcess::IsActive( unsigned int pFlags ) const {
|
||||||
return ( pFlags & aiProcess_GlobalScale ) != 0;
|
return ( pFlags & aiProcess_GlobalScale ) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ScaleProcess::SetupProperties( const Importer* pImp ) {
|
void ScaleProcess::SetupProperties( const Importer* pImp ) {
|
||||||
// User scaling
|
// User scaling
|
||||||
mScale = pImp->GetPropertyFloat( AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY, 1.0f );
|
mScale = pImp->GetPropertyFloat( AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY, 1.0f );
|
||||||
|
@ -78,6 +80,7 @@ void ScaleProcess::SetupProperties( const Importer* pImp ) {
|
||||||
mScale *= importerScale;
|
mScale *= importerScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ScaleProcess::Execute( aiScene* pScene ) {
|
void ScaleProcess::Execute( aiScene* pScene ) {
|
||||||
if(mScale == 1.0f) {
|
if(mScale == 1.0f) {
|
||||||
return; // nothing to scale
|
return; // nothing to scale
|
||||||
|
@ -96,37 +99,30 @@ void ScaleProcess::Execute( aiScene* pScene ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process animations and update position transform to new unit system
|
// Process animations and update position transform to new unit system
|
||||||
for( unsigned int animationID = 0; animationID < pScene->mNumAnimations; animationID++ )
|
for( unsigned int animationID = 0; animationID < pScene->mNumAnimations; animationID++ ) {
|
||||||
{
|
|
||||||
aiAnimation* animation = pScene->mAnimations[animationID];
|
aiAnimation* animation = pScene->mAnimations[animationID];
|
||||||
|
|
||||||
for( unsigned int animationChannel = 0; animationChannel < animation->mNumChannels; animationChannel++)
|
for( unsigned int animationChannel = 0; animationChannel < animation->mNumChannels; animationChannel++) {
|
||||||
{
|
|
||||||
aiNodeAnim* anim = animation->mChannels[animationChannel];
|
aiNodeAnim* anim = animation->mChannels[animationChannel];
|
||||||
|
|
||||||
for( unsigned int posKey = 0; posKey < anim->mNumPositionKeys; posKey++)
|
for( unsigned int posKey = 0; posKey < anim->mNumPositionKeys; posKey++) {
|
||||||
{
|
|
||||||
aiVectorKey& vectorKey = anim->mPositionKeys[posKey];
|
aiVectorKey& vectorKey = anim->mPositionKeys[posKey];
|
||||||
vectorKey.mValue *= mScale;
|
vectorKey.mValue *= mScale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for( unsigned int meshID = 0; meshID < pScene->mNumMeshes; meshID++)
|
for( unsigned int meshID = 0; meshID < pScene->mNumMeshes; meshID++) {
|
||||||
{
|
|
||||||
aiMesh *mesh = pScene->mMeshes[meshID];
|
aiMesh *mesh = pScene->mMeshes[meshID];
|
||||||
|
|
||||||
// Reconstruct mesh vertices to the new unit system
|
// Reconstruct mesh vertices to the new unit system
|
||||||
for( unsigned int vertexID = 0; vertexID < mesh->mNumVertices; vertexID++)
|
for( unsigned int vertexID = 0; vertexID < mesh->mNumVertices; vertexID++) {
|
||||||
{
|
|
||||||
aiVector3D& vertex = mesh->mVertices[vertexID];
|
aiVector3D& vertex = mesh->mVertices[vertexID];
|
||||||
vertex *= mScale;
|
vertex *= mScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// bone placement / scaling
|
// bone placement / scaling
|
||||||
for( unsigned int boneID = 0; boneID < mesh->mNumBones; boneID++)
|
for( unsigned int boneID = 0; boneID < mesh->mNumBones; boneID++) {
|
||||||
{
|
|
||||||
// Reconstruct matrix by transform rather than by scale
|
// Reconstruct matrix by transform rather than by scale
|
||||||
// This prevent scale values being changed which can
|
// This prevent scale values being changed which can
|
||||||
// be meaningful in some cases
|
// be meaningful in some cases
|
||||||
|
@ -152,12 +148,10 @@ void ScaleProcess::Execute( aiScene* pScene ) {
|
||||||
|
|
||||||
// animation mesh processing
|
// animation mesh processing
|
||||||
// convert by position rather than scale.
|
// convert by position rather than scale.
|
||||||
for( unsigned int animMeshID = 0; animMeshID < mesh->mNumAnimMeshes; animMeshID++)
|
for( unsigned int animMeshID = 0; animMeshID < mesh->mNumAnimMeshes; animMeshID++) {
|
||||||
{
|
|
||||||
aiAnimMesh * animMesh = mesh->mAnimMeshes[animMeshID];
|
aiAnimMesh * animMesh = mesh->mAnimMeshes[animMeshID];
|
||||||
|
|
||||||
for( unsigned int vertexID = 0; vertexID < animMesh->mNumVertices; vertexID++)
|
for( unsigned int vertexID = 0; vertexID < animMesh->mNumVertices; vertexID++) {
|
||||||
{
|
|
||||||
aiVector3D& vertex = animMesh->mVertices[vertexID];
|
aiVector3D& vertex = animMesh->mVertices[vertexID];
|
||||||
vertex *= mScale;
|
vertex *= mScale;
|
||||||
}
|
}
|
||||||
|
@ -167,16 +161,17 @@ void ScaleProcess::Execute( aiScene* pScene ) {
|
||||||
traverseNodes( pScene->mRootNode );
|
traverseNodes( pScene->mRootNode );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ScaleProcess::traverseNodes( aiNode *node, unsigned int nested_node_id ) {
|
void ScaleProcess::traverseNodes( aiNode *node, unsigned int nested_node_id ) {
|
||||||
applyScaling( node );
|
applyScaling( node );
|
||||||
|
|
||||||
for( size_t i = 0; i < node->mNumChildren; i++)
|
for( size_t i = 0; i < node->mNumChildren; i++) {
|
||||||
{
|
|
||||||
// recurse into the tree until we are done!
|
// recurse into the tree until we are done!
|
||||||
traverseNodes( node->mChildren[i], nested_node_id+1 );
|
traverseNodes( node->mChildren[i], nested_node_id+1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ScaleProcess::applyScaling( aiNode *currentNode ) {
|
void ScaleProcess::applyScaling( aiNode *currentNode ) {
|
||||||
if ( nullptr != currentNode ) {
|
if ( nullptr != currentNode ) {
|
||||||
// Reconstruct matrix by transform rather than by scale
|
// Reconstruct matrix by transform rather than by scale
|
||||||
|
|
|
@ -62,11 +62,10 @@ namespace Assimp {
|
||||||
*/
|
*/
|
||||||
class ASSIMP_API ScaleProcess : public BaseProcess {
|
class ASSIMP_API ScaleProcess : public BaseProcess {
|
||||||
public:
|
public:
|
||||||
/// The default class constructor.
|
// -------------------------------------------------------------------
|
||||||
|
/// The default class constructor / destructor.
|
||||||
ScaleProcess();
|
ScaleProcess();
|
||||||
|
~ScaleProcess() override = default;
|
||||||
/// The class destructor.
|
|
||||||
virtual ~ScaleProcess();
|
|
||||||
|
|
||||||
/// Will set the scale manually.
|
/// Will set the scale manually.
|
||||||
void setScale( ai_real scale );
|
void setScale( ai_real scale );
|
||||||
|
@ -75,13 +74,13 @@ public:
|
||||||
ai_real getScale() const;
|
ai_real getScale() const;
|
||||||
|
|
||||||
/// Overwritten, @see BaseProcess
|
/// Overwritten, @see BaseProcess
|
||||||
virtual bool IsActive( unsigned int pFlags ) const;
|
virtual bool IsActive( unsigned int pFlags ) const override;
|
||||||
|
|
||||||
/// Overwritten, @see BaseProcess
|
/// Overwritten, @see BaseProcess
|
||||||
virtual void SetupProperties( const Importer* pImp );
|
virtual void SetupProperties( const Importer* pImp ) override;
|
||||||
|
|
||||||
/// Overwritten, @see BaseProcess
|
/// Overwritten, @see BaseProcess
|
||||||
virtual void Execute( aiScene* pScene );
|
virtual void Execute( aiScene* pScene ) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void traverseNodes( aiNode *currentNode, unsigned int nested_node_id = 0 );
|
void traverseNodes( aiNode *currentNode, unsigned int nested_node_id = 0 );
|
||||||
|
|
|
@ -59,10 +59,6 @@ SortByPTypeProcess::SortByPTypeProcess() :
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
SortByPTypeProcess::~SortByPTypeProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool SortByPTypeProcess::IsActive(unsigned int pFlags) const {
|
bool SortByPTypeProcess::IsActive(unsigned int pFlags) const {
|
||||||
|
|
|
@ -60,17 +60,19 @@ namespace Assimp {
|
||||||
*/
|
*/
|
||||||
class ASSIMP_API SortByPTypeProcess : public BaseProcess {
|
class ASSIMP_API SortByPTypeProcess : public BaseProcess {
|
||||||
public:
|
public:
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/// The default class constructor / destructor.
|
||||||
SortByPTypeProcess();
|
SortByPTypeProcess();
|
||||||
~SortByPTypeProcess();
|
~SortByPTypeProcess() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int mConfigRemoveMeshes;
|
int mConfigRemoveMeshes;
|
||||||
|
|
|
@ -40,7 +40,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/// @file SplitByBoneCountProcess.cpp
|
/// @file SplitByBoneCountProcess.cpp
|
||||||
/// Implementation of the SplitByBoneCount postprocessing step
|
/// Implementation of the SplitByBoneCount postprocessing step
|
||||||
|
|
||||||
|
@ -59,47 +58,36 @@ using namespace Assimp::Formatter;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor
|
// Constructor
|
||||||
SplitByBoneCountProcess::SplitByBoneCountProcess()
|
SplitByBoneCountProcess::SplitByBoneCountProcess() : mMaxBoneCount(AI_SBBC_DEFAULT_MAX_BONES) {
|
||||||
{
|
// empty
|
||||||
// set default, might be overridden by importer config
|
|
||||||
mMaxBoneCount = AI_SBBC_DEFAULT_MAX_BONES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor
|
|
||||||
SplitByBoneCountProcess::~SplitByBoneCountProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag.
|
// Returns whether the processing step is present in the given flag.
|
||||||
bool SplitByBoneCountProcess::IsActive( unsigned int pFlags) const
|
bool SplitByBoneCountProcess::IsActive( unsigned int pFlags) const {
|
||||||
{
|
|
||||||
return !!(pFlags & aiProcess_SplitByBoneCount);
|
return !!(pFlags & aiProcess_SplitByBoneCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Updates internal properties
|
// Updates internal properties
|
||||||
void SplitByBoneCountProcess::SetupProperties(const Importer* pImp)
|
void SplitByBoneCountProcess::SetupProperties(const Importer* pImp) {
|
||||||
{
|
|
||||||
mMaxBoneCount = pImp->GetPropertyInteger(AI_CONFIG_PP_SBBC_MAX_BONES,AI_SBBC_DEFAULT_MAX_BONES);
|
mMaxBoneCount = pImp->GetPropertyInteger(AI_CONFIG_PP_SBBC_MAX_BONES,AI_SBBC_DEFAULT_MAX_BONES);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
void SplitByBoneCountProcess::Execute( aiScene* pScene)
|
void SplitByBoneCountProcess::Execute( aiScene* pScene) {
|
||||||
{
|
|
||||||
ASSIMP_LOG_DEBUG("SplitByBoneCountProcess begin");
|
ASSIMP_LOG_DEBUG("SplitByBoneCountProcess begin");
|
||||||
|
|
||||||
// early out
|
// early out
|
||||||
bool isNecessary = false;
|
bool isNecessary = false;
|
||||||
for( unsigned int a = 0; a < pScene->mNumMeshes; ++a)
|
for( unsigned int a = 0; a < pScene->mNumMeshes; ++a)
|
||||||
if( pScene->mMeshes[a]->mNumBones > mMaxBoneCount )
|
if( pScene->mMeshes[a]->mNumBones > mMaxBoneCount ) {
|
||||||
{
|
|
||||||
isNecessary = true;
|
isNecessary = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !isNecessary )
|
if( !isNecessary ) {
|
||||||
{
|
|
||||||
ASSIMP_LOG_DEBUG("SplitByBoneCountProcess early-out: no meshes with more than ", mMaxBoneCount, " bones." );
|
ASSIMP_LOG_DEBUG("SplitByBoneCountProcess early-out: no meshes with more than ", mMaxBoneCount, " bones." );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -111,28 +99,23 @@ void SplitByBoneCountProcess::Execute( aiScene* pScene)
|
||||||
// build a new array of meshes for the scene
|
// build a new array of meshes for the scene
|
||||||
std::vector<aiMesh*> meshes;
|
std::vector<aiMesh*> meshes;
|
||||||
|
|
||||||
for( unsigned int a = 0; a < pScene->mNumMeshes; ++a)
|
for( unsigned int a = 0; a < pScene->mNumMeshes; ++a) {
|
||||||
{
|
|
||||||
aiMesh* srcMesh = pScene->mMeshes[a];
|
aiMesh* srcMesh = pScene->mMeshes[a];
|
||||||
|
|
||||||
std::vector<aiMesh*> newMeshes;
|
std::vector<aiMesh*> newMeshes;
|
||||||
SplitMesh( pScene->mMeshes[a], newMeshes);
|
SplitMesh( pScene->mMeshes[a], newMeshes);
|
||||||
|
|
||||||
// mesh was split
|
// mesh was split
|
||||||
if( !newMeshes.empty() )
|
if( !newMeshes.empty() ) {
|
||||||
{
|
|
||||||
// store new meshes and indices of the new meshes
|
// store new meshes and indices of the new meshes
|
||||||
for( unsigned int b = 0; b < newMeshes.size(); ++b)
|
for( unsigned int b = 0; b < newMeshes.size(); ++b) {
|
||||||
{
|
|
||||||
mSubMeshIndices[a].push_back( static_cast<unsigned int>(meshes.size()));
|
mSubMeshIndices[a].push_back( static_cast<unsigned int>(meshes.size()));
|
||||||
meshes.push_back( newMeshes[b]);
|
meshes.push_back( newMeshes[b]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// and destroy the source mesh. It should be completely contained inside the new submeshes
|
// and destroy the source mesh. It should be completely contained inside the new submeshes
|
||||||
delete srcMesh;
|
delete srcMesh;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Mesh is kept unchanged - store it's new place in the mesh array
|
// Mesh is kept unchanged - store it's new place in the mesh array
|
||||||
mSubMeshIndices[a].push_back( static_cast<unsigned int>(meshes.size()));
|
mSubMeshIndices[a].push_back( static_cast<unsigned int>(meshes.size()));
|
||||||
meshes.push_back( srcMesh);
|
meshes.push_back( srcMesh);
|
||||||
|
@ -153,11 +136,9 @@ void SplitByBoneCountProcess::Execute( aiScene* pScene)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Splits the given mesh by bone count.
|
// Splits the given mesh by bone count.
|
||||||
void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh*>& poNewMeshes) const
|
void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh*>& poNewMeshes) const {
|
||||||
{
|
|
||||||
// skip if not necessary
|
// skip if not necessary
|
||||||
if( pMesh->mNumBones <= mMaxBoneCount )
|
if( pMesh->mNumBones <= mMaxBoneCount ) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,17 +146,13 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||||
// TODO: (thom) maybe add a custom allocator here to avoid allocating tens of thousands of small arrays
|
// TODO: (thom) maybe add a custom allocator here to avoid allocating tens of thousands of small arrays
|
||||||
typedef std::pair<unsigned int, float> BoneWeight;
|
typedef std::pair<unsigned int, float> BoneWeight;
|
||||||
std::vector< std::vector<BoneWeight> > vertexBones( pMesh->mNumVertices);
|
std::vector< std::vector<BoneWeight> > vertexBones( pMesh->mNumVertices);
|
||||||
for( unsigned int a = 0; a < pMesh->mNumBones; ++a)
|
for( unsigned int a = 0; a < pMesh->mNumBones; ++a) {
|
||||||
{
|
|
||||||
const aiBone* bone = pMesh->mBones[a];
|
const aiBone* bone = pMesh->mBones[a];
|
||||||
for( unsigned int b = 0; b < bone->mNumWeights; ++b)
|
for( unsigned int b = 0; b < bone->mNumWeights; ++b) {
|
||||||
{
|
if (bone->mWeights[b].mWeight > 0.0f) {
|
||||||
if (bone->mWeights[b].mWeight > 0.0f)
|
|
||||||
{
|
|
||||||
int vertexId = bone->mWeights[b].mVertexId;
|
int vertexId = bone->mWeights[b].mVertexId;
|
||||||
vertexBones[vertexId].emplace_back(a, bone->mWeights[b].mWeight);
|
vertexBones[vertexId].emplace_back(a, bone->mWeights[b].mWeight);
|
||||||
if (vertexBones[vertexId].size() > mMaxBoneCount)
|
if (vertexBones[vertexId].size() > mMaxBoneCount) {
|
||||||
{
|
|
||||||
throw DeadlyImportError("SplitByBoneCountProcess: Single face requires more bones than specified max bone count!");
|
throw DeadlyImportError("SplitByBoneCountProcess: Single face requires more bones than specified max bone count!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,8 +161,7 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||||
|
|
||||||
unsigned int numFacesHandled = 0;
|
unsigned int numFacesHandled = 0;
|
||||||
std::vector<bool> isFaceHandled( pMesh->mNumFaces, false);
|
std::vector<bool> isFaceHandled( pMesh->mNumFaces, false);
|
||||||
while( numFacesHandled < pMesh->mNumFaces )
|
while( numFacesHandled < pMesh->mNumFaces ) {
|
||||||
{
|
|
||||||
// which bones are used in the current submesh
|
// which bones are used in the current submesh
|
||||||
unsigned int numBones = 0;
|
unsigned int numBones = 0;
|
||||||
std::vector<bool> isBoneUsed( pMesh->mNumBones, false);
|
std::vector<bool> isBoneUsed( pMesh->mNumBones, false);
|
||||||
|
@ -196,11 +172,9 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||||
unsigned int numSubMeshVertices = 0;
|
unsigned int numSubMeshVertices = 0;
|
||||||
|
|
||||||
// add faces to the new submesh as long as all bones affecting the faces' vertices fit in the limit
|
// add faces to the new submesh as long as all bones affecting the faces' vertices fit in the limit
|
||||||
for( unsigned int a = 0; a < pMesh->mNumFaces; ++a)
|
for( unsigned int a = 0; a < pMesh->mNumFaces; ++a) {
|
||||||
{
|
|
||||||
// skip if the face is already stored in a submesh
|
// skip if the face is already stored in a submesh
|
||||||
if( isFaceHandled[a] )
|
if( isFaceHandled[a] ) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// a small local set of new bones for the current face. State of all used bones for that face
|
// a small local set of new bones for the current face. State of all used bones for that face
|
||||||
|
@ -209,30 +183,24 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||||
|
|
||||||
const aiFace& face = pMesh->mFaces[a];
|
const aiFace& face = pMesh->mFaces[a];
|
||||||
// check every vertex if its bones would still fit into the current submesh
|
// check every vertex if its bones would still fit into the current submesh
|
||||||
for( unsigned int b = 0; b < face.mNumIndices; ++b )
|
for( unsigned int b = 0; b < face.mNumIndices; ++b ) {
|
||||||
{
|
|
||||||
const std::vector<BoneWeight>& vb = vertexBones[face.mIndices[b]];
|
const std::vector<BoneWeight>& vb = vertexBones[face.mIndices[b]];
|
||||||
for( unsigned int c = 0; c < vb.size(); ++c)
|
for( unsigned int c = 0; c < vb.size(); ++c) {
|
||||||
{
|
|
||||||
unsigned int boneIndex = vb[c].first;
|
unsigned int boneIndex = vb[c].first;
|
||||||
if( !isBoneUsed[boneIndex] )
|
if( !isBoneUsed[boneIndex] ) {
|
||||||
{
|
|
||||||
newBonesAtCurrentFace.insert(boneIndex);
|
newBonesAtCurrentFace.insert(boneIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// leave out the face if the new bones required for this face don't fit the bone count limit anymore
|
// leave out the face if the new bones required for this face don't fit the bone count limit anymore
|
||||||
if( numBones + newBonesAtCurrentFace.size() > mMaxBoneCount )
|
if( numBones + newBonesAtCurrentFace.size() > mMaxBoneCount ) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// mark all new bones as necessary
|
// mark all new bones as necessary
|
||||||
for (std::set<unsigned int>::iterator it = newBonesAtCurrentFace.begin(); it != newBonesAtCurrentFace.end(); ++it)
|
for (std::set<unsigned int>::iterator it = newBonesAtCurrentFace.begin(); it != newBonesAtCurrentFace.end(); ++it) {
|
||||||
{
|
if (!isBoneUsed[*it]) {
|
||||||
if (!isBoneUsed[*it])
|
|
||||||
{
|
|
||||||
isBoneUsed[*it] = true;
|
isBoneUsed[*it] = true;
|
||||||
numBones++;
|
numBones++;
|
||||||
}
|
}
|
||||||
|
@ -261,27 +229,21 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||||
newMesh->mNumVertices = numSubMeshVertices;
|
newMesh->mNumVertices = numSubMeshVertices;
|
||||||
newMesh->mNumFaces = static_cast<unsigned int>(subMeshFaces.size());
|
newMesh->mNumFaces = static_cast<unsigned int>(subMeshFaces.size());
|
||||||
newMesh->mVertices = new aiVector3D[newMesh->mNumVertices];
|
newMesh->mVertices = new aiVector3D[newMesh->mNumVertices];
|
||||||
if( pMesh->HasNormals() )
|
if( pMesh->HasNormals() ) {
|
||||||
{
|
|
||||||
newMesh->mNormals = new aiVector3D[newMesh->mNumVertices];
|
newMesh->mNormals = new aiVector3D[newMesh->mNumVertices];
|
||||||
}
|
}
|
||||||
if( pMesh->HasTangentsAndBitangents() )
|
if( pMesh->HasTangentsAndBitangents() ) {
|
||||||
{
|
|
||||||
newMesh->mTangents = new aiVector3D[newMesh->mNumVertices];
|
newMesh->mTangents = new aiVector3D[newMesh->mNumVertices];
|
||||||
newMesh->mBitangents = new aiVector3D[newMesh->mNumVertices];
|
newMesh->mBitangents = new aiVector3D[newMesh->mNumVertices];
|
||||||
}
|
}
|
||||||
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
|
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a ) {
|
||||||
{
|
if( pMesh->HasTextureCoords( a) ) {
|
||||||
if( pMesh->HasTextureCoords( a) )
|
|
||||||
{
|
|
||||||
newMesh->mTextureCoords[a] = new aiVector3D[newMesh->mNumVertices];
|
newMesh->mTextureCoords[a] = new aiVector3D[newMesh->mNumVertices];
|
||||||
}
|
}
|
||||||
newMesh->mNumUVComponents[a] = pMesh->mNumUVComponents[a];
|
newMesh->mNumUVComponents[a] = pMesh->mNumUVComponents[a];
|
||||||
}
|
}
|
||||||
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a )
|
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a ) {
|
||||||
{
|
if( pMesh->HasVertexColors( a) ) {
|
||||||
if( pMesh->HasVertexColors( a) )
|
|
||||||
{
|
|
||||||
newMesh->mColors[a] = new aiColor4D[newMesh->mNumVertices];
|
newMesh->mColors[a] = new aiColor4D[newMesh->mNumVertices];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,41 +252,33 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||||
newMesh->mFaces = new aiFace[subMeshFaces.size()];
|
newMesh->mFaces = new aiFace[subMeshFaces.size()];
|
||||||
unsigned int nvi = 0; // next vertex index
|
unsigned int nvi = 0; // next vertex index
|
||||||
std::vector<unsigned int> previousVertexIndices( numSubMeshVertices, std::numeric_limits<unsigned int>::max()); // per new vertex: its index in the source mesh
|
std::vector<unsigned int> previousVertexIndices( numSubMeshVertices, std::numeric_limits<unsigned int>::max()); // per new vertex: its index in the source mesh
|
||||||
for( unsigned int a = 0; a < subMeshFaces.size(); ++a )
|
for( unsigned int a = 0; a < subMeshFaces.size(); ++a ) {
|
||||||
{
|
|
||||||
const aiFace& srcFace = pMesh->mFaces[subMeshFaces[a]];
|
const aiFace& srcFace = pMesh->mFaces[subMeshFaces[a]];
|
||||||
aiFace& dstFace = newMesh->mFaces[a];
|
aiFace& dstFace = newMesh->mFaces[a];
|
||||||
dstFace.mNumIndices = srcFace.mNumIndices;
|
dstFace.mNumIndices = srcFace.mNumIndices;
|
||||||
dstFace.mIndices = new unsigned int[dstFace.mNumIndices];
|
dstFace.mIndices = new unsigned int[dstFace.mNumIndices];
|
||||||
|
|
||||||
// accumulate linearly all the vertices of the source face
|
// accumulate linearly all the vertices of the source face
|
||||||
for( unsigned int b = 0; b < dstFace.mNumIndices; ++b )
|
for( unsigned int b = 0; b < dstFace.mNumIndices; ++b ) {
|
||||||
{
|
|
||||||
unsigned int srcIndex = srcFace.mIndices[b];
|
unsigned int srcIndex = srcFace.mIndices[b];
|
||||||
dstFace.mIndices[b] = nvi;
|
dstFace.mIndices[b] = nvi;
|
||||||
previousVertexIndices[nvi] = srcIndex;
|
previousVertexIndices[nvi] = srcIndex;
|
||||||
|
|
||||||
newMesh->mVertices[nvi] = pMesh->mVertices[srcIndex];
|
newMesh->mVertices[nvi] = pMesh->mVertices[srcIndex];
|
||||||
if( pMesh->HasNormals() )
|
if( pMesh->HasNormals() ) {
|
||||||
{
|
|
||||||
newMesh->mNormals[nvi] = pMesh->mNormals[srcIndex];
|
newMesh->mNormals[nvi] = pMesh->mNormals[srcIndex];
|
||||||
}
|
}
|
||||||
if( pMesh->HasTangentsAndBitangents() )
|
if( pMesh->HasTangentsAndBitangents() ) {
|
||||||
{
|
|
||||||
newMesh->mTangents[nvi] = pMesh->mTangents[srcIndex];
|
newMesh->mTangents[nvi] = pMesh->mTangents[srcIndex];
|
||||||
newMesh->mBitangents[nvi] = pMesh->mBitangents[srcIndex];
|
newMesh->mBitangents[nvi] = pMesh->mBitangents[srcIndex];
|
||||||
}
|
}
|
||||||
for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++c )
|
for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++c ) {
|
||||||
{
|
if( pMesh->HasTextureCoords( c) ) {
|
||||||
if( pMesh->HasTextureCoords( c) )
|
|
||||||
{
|
|
||||||
newMesh->mTextureCoords[c][nvi] = pMesh->mTextureCoords[c][srcIndex];
|
newMesh->mTextureCoords[c][nvi] = pMesh->mTextureCoords[c][srcIndex];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c )
|
for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c ) {
|
||||||
{
|
if( pMesh->HasVertexColors( c) ) {
|
||||||
if( pMesh->HasVertexColors( c) )
|
|
||||||
{
|
|
||||||
newMesh->mColors[c][nvi] = pMesh->mColors[c][srcIndex];
|
newMesh->mColors[c][nvi] = pMesh->mColors[c][srcIndex];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -340,10 +294,8 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||||
newMesh->mBones = new aiBone*[numBones];
|
newMesh->mBones = new aiBone*[numBones];
|
||||||
|
|
||||||
std::vector<unsigned int> mappedBoneIndex( pMesh->mNumBones, std::numeric_limits<unsigned int>::max());
|
std::vector<unsigned int> mappedBoneIndex( pMesh->mNumBones, std::numeric_limits<unsigned int>::max());
|
||||||
for( unsigned int a = 0; a < pMesh->mNumBones; ++a )
|
for( unsigned int a = 0; a < pMesh->mNumBones; ++a ) {
|
||||||
{
|
if( !isBoneUsed[a] ) {
|
||||||
if( !isBoneUsed[a] )
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,24 +312,20 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||||
ai_assert( newMesh->mNumBones == numBones );
|
ai_assert( newMesh->mNumBones == numBones );
|
||||||
|
|
||||||
// iterate over all new vertices and count which bones affected its old vertex in the source mesh
|
// iterate over all new vertices and count which bones affected its old vertex in the source mesh
|
||||||
for( unsigned int a = 0; a < numSubMeshVertices; ++a )
|
for( unsigned int a = 0; a < numSubMeshVertices; ++a ) {
|
||||||
{
|
|
||||||
unsigned int oldIndex = previousVertexIndices[a];
|
unsigned int oldIndex = previousVertexIndices[a];
|
||||||
const std::vector<BoneWeight>& bonesOnThisVertex = vertexBones[oldIndex];
|
const std::vector<BoneWeight>& bonesOnThisVertex = vertexBones[oldIndex];
|
||||||
|
|
||||||
for( unsigned int b = 0; b < bonesOnThisVertex.size(); ++b )
|
for( unsigned int b = 0; b < bonesOnThisVertex.size(); ++b ) {
|
||||||
{
|
|
||||||
unsigned int newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ];
|
unsigned int newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ];
|
||||||
if( newBoneIndex != std::numeric_limits<unsigned int>::max() )
|
if( newBoneIndex != std::numeric_limits<unsigned int>::max() ) {
|
||||||
{
|
|
||||||
newMesh->mBones[newBoneIndex]->mNumWeights++;
|
newMesh->mBones[newBoneIndex]->mNumWeights++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate all bone weight arrays accordingly
|
// allocate all bone weight arrays accordingly
|
||||||
for( unsigned int a = 0; a < newMesh->mNumBones; ++a )
|
for( unsigned int a = 0; a < newMesh->mNumBones; ++a ) {
|
||||||
{
|
|
||||||
aiBone* bone = newMesh->mBones[a];
|
aiBone* bone = newMesh->mBones[a];
|
||||||
ai_assert( bone->mNumWeights > 0 );
|
ai_assert( bone->mNumWeights > 0 );
|
||||||
bone->mWeights = new aiVertexWeight[bone->mNumWeights];
|
bone->mWeights = new aiVertexWeight[bone->mNumWeights];
|
||||||
|
@ -385,16 +333,14 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||||
}
|
}
|
||||||
|
|
||||||
// now copy all the bone vertex weights for all the vertices which made it into the new submesh
|
// now copy all the bone vertex weights for all the vertices which made it into the new submesh
|
||||||
for( unsigned int a = 0; a < numSubMeshVertices; ++a)
|
for( unsigned int a = 0; a < numSubMeshVertices; ++a) {
|
||||||
{
|
|
||||||
// find the source vertex for it in the source mesh
|
// find the source vertex for it in the source mesh
|
||||||
unsigned int previousIndex = previousVertexIndices[a];
|
unsigned int previousIndex = previousVertexIndices[a];
|
||||||
// these bones were affecting it
|
// these bones were affecting it
|
||||||
const std::vector<BoneWeight>& bonesOnThisVertex = vertexBones[previousIndex];
|
const std::vector<BoneWeight>& bonesOnThisVertex = vertexBones[previousIndex];
|
||||||
// all of the bones affecting it should be present in the new submesh, or else
|
// all of the bones affecting it should be present in the new submesh, or else
|
||||||
// the face it comprises shouldn't be present
|
// the face it comprises shouldn't be present
|
||||||
for( unsigned int b = 0; b < bonesOnThisVertex.size(); ++b)
|
for( unsigned int b = 0; b < bonesOnThisVertex.size(); ++b) {
|
||||||
{
|
|
||||||
unsigned int newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ];
|
unsigned int newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ];
|
||||||
ai_assert( newBoneIndex != std::numeric_limits<unsigned int>::max() );
|
ai_assert( newBoneIndex != std::numeric_limits<unsigned int>::max() );
|
||||||
aiVertexWeight* dstWeight = newMesh->mBones[newBoneIndex]->mWeights + newMesh->mBones[newBoneIndex]->mNumWeights;
|
aiVertexWeight* dstWeight = newMesh->mBones[newBoneIndex]->mWeights + newMesh->mBones[newBoneIndex]->mNumWeights;
|
||||||
|
@ -450,14 +396,11 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Recursively updates the node's mesh list to account for the changed mesh list
|
// Recursively updates the node's mesh list to account for the changed mesh list
|
||||||
void SplitByBoneCountProcess::UpdateNode( aiNode* pNode) const
|
void SplitByBoneCountProcess::UpdateNode( aiNode* pNode) const {
|
||||||
{
|
|
||||||
// rebuild the node's mesh index list
|
// rebuild the node's mesh index list
|
||||||
if( pNode->mNumMeshes > 0 )
|
if( pNode->mNumMeshes == 0 ) {
|
||||||
{
|
|
||||||
std::vector<unsigned int> newMeshList;
|
std::vector<unsigned int> newMeshList;
|
||||||
for( unsigned int a = 0; a < pNode->mNumMeshes; ++a)
|
for( unsigned int a = 0; a < pNode->mNumMeshes; ++a) {
|
||||||
{
|
|
||||||
unsigned int srcIndex = pNode->mMeshes[a];
|
unsigned int srcIndex = pNode->mMeshes[a];
|
||||||
const std::vector<unsigned int>& replaceMeshes = mSubMeshIndices[srcIndex];
|
const std::vector<unsigned int>& replaceMeshes = mSubMeshIndices[srcIndex];
|
||||||
newMeshList.insert( newMeshList.end(), replaceMeshes.begin(), replaceMeshes.end());
|
newMeshList.insert( newMeshList.end(), replaceMeshes.begin(), replaceMeshes.end());
|
||||||
|
@ -470,8 +413,7 @@ void SplitByBoneCountProcess::UpdateNode( aiNode* pNode) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// do that also recursively for all children
|
// do that also recursively for all children
|
||||||
for( unsigned int a = 0; a < pNode->mNumChildren; ++a )
|
for( unsigned int a = 0; a < pNode->mNumChildren; ++a ) {
|
||||||
{
|
|
||||||
UpdateNode( pNode->mChildren[a]);
|
UpdateNode( pNode->mChildren[a]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -51,9 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/mesh.h>
|
#include <assimp/mesh.h>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** Postprocessing filter to split meshes with many bones into submeshes
|
/** Postprocessing filter to split meshes with many bones into submeshes
|
||||||
* so that each submesh has a certain max bone count.
|
* so that each submesh has a certain max bone count.
|
||||||
|
@ -61,34 +58,29 @@ namespace Assimp
|
||||||
* Applied BEFORE the JoinVertices-Step occurs.
|
* Applied BEFORE the JoinVertices-Step occurs.
|
||||||
* Returns NON-UNIQUE vertices, splits by bone count.
|
* Returns NON-UNIQUE vertices, splits by bone count.
|
||||||
*/
|
*/
|
||||||
class SplitByBoneCountProcess : public BaseProcess
|
class SplitByBoneCountProcess : public BaseProcess {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/// The default class constructor / destructor.
|
||||||
SplitByBoneCountProcess();
|
SplitByBoneCountProcess();
|
||||||
~SplitByBoneCountProcess();
|
~SplitByBoneCountProcess() override = default;
|
||||||
|
|
||||||
public:
|
/// @brief Returns whether the processing step is present in the given flag.
|
||||||
/** Returns whether the processing step is present in the given flag.
|
/// @param pFlags The processing flags the importer was called with. A
|
||||||
* @param pFlags The processing flags the importer was called with. A
|
/// bitwise combination of #aiPostProcessSteps.
|
||||||
* bitwise combination of #aiPostProcessSteps.
|
/// @return true if the process is present in this flag fields, false if not.
|
||||||
* @return true if the process is present in this flag fields,
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
* false if not.
|
|
||||||
*/
|
|
||||||
bool IsActive( unsigned int pFlags) const;
|
|
||||||
|
|
||||||
/** Called prior to ExecuteOnScene().
|
/// @brief Called prior to ExecuteOnScene().
|
||||||
* The function is a request to the process to update its configuration
|
/// The function is a request to the process to update its configuration
|
||||||
* basing on the Importer's configuration property list.
|
/// basing on the Importer's configuration property list.
|
||||||
*/
|
virtual void SetupProperties(const Importer* pImp) override;
|
||||||
virtual void SetupProperties(const Importer* pImp);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Executes the post processing step on the given imported data.
|
/// Executes the post processing step on the given imported data.
|
||||||
* At the moment a process is not supposed to fail.
|
/// At the moment a process is not supposed to fail.
|
||||||
* @param pScene The imported data to work at.
|
/// @param pScene The imported data to work at.
|
||||||
*/
|
void Execute( aiScene* pScene) override;
|
||||||
void Execute( aiScene* pScene);
|
|
||||||
|
|
||||||
/// Splits the given mesh by bone count.
|
/// Splits the given mesh by bone count.
|
||||||
/// @param pMesh the Mesh to split. Is not changed at all, but might be superfluous in case it was split.
|
/// @param pMesh the Mesh to split. Is not changed at all, but might be superfluous in case it was split.
|
||||||
|
|
|
@ -55,9 +55,6 @@ SplitLargeMeshesProcess_Triangle::SplitLargeMeshesProcess_Triangle() {
|
||||||
LIMIT = AI_SLM_DEFAULT_MAX_TRIANGLES;
|
LIMIT = AI_SLM_DEFAULT_MAX_TRIANGLES;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
SplitLargeMeshesProcess_Triangle::~SplitLargeMeshesProcess_Triangle() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool SplitLargeMeshesProcess_Triangle::IsActive( unsigned int pFlags) const {
|
bool SplitLargeMeshesProcess_Triangle::IsActive( unsigned int pFlags) const {
|
||||||
|
@ -329,9 +326,6 @@ SplitLargeMeshesProcess_Vertex::SplitLargeMeshesProcess_Vertex() {
|
||||||
LIMIT = AI_SLM_DEFAULT_MAX_VERTICES;
|
LIMIT = AI_SLM_DEFAULT_MAX_VERTICES;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
SplitLargeMeshesProcess_Vertex::~SplitLargeMeshesProcess_Vertex() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool SplitLargeMeshesProcess_Vertex::IsActive( unsigned int pFlags) const {
|
bool SplitLargeMeshesProcess_Vertex::IsActive( unsigned int pFlags) const {
|
||||||
|
|
|
@ -83,16 +83,15 @@ class SplitLargeMeshesProcess_Vertex;
|
||||||
* Applied BEFORE the JoinVertices-Step occurs.
|
* Applied BEFORE the JoinVertices-Step occurs.
|
||||||
* Returns NON-UNIQUE vertices, splits by triangle number.
|
* Returns NON-UNIQUE vertices, splits by triangle number.
|
||||||
*/
|
*/
|
||||||
class ASSIMP_API SplitLargeMeshesProcess_Triangle : public BaseProcess
|
class ASSIMP_API SplitLargeMeshesProcess_Triangle : public BaseProcess {
|
||||||
{
|
|
||||||
friend class SplitLargeMeshesProcess_Vertex;
|
friend class SplitLargeMeshesProcess_Vertex;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/// The default class constructor / destructor.
|
||||||
SplitLargeMeshesProcess_Triangle();
|
SplitLargeMeshesProcess_Triangle();
|
||||||
~SplitLargeMeshesProcess_Triangle();
|
~SplitLargeMeshesProcess_Triangle() override = default;
|
||||||
|
|
||||||
public:
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the processing step is present in the given flag.
|
/** Returns whether the processing step is present in the given flag.
|
||||||
* @param pFlags The processing flags the importer was called with. A
|
* @param pFlags The processing flags the importer was called with. A
|
||||||
|
@ -100,16 +99,14 @@ public:
|
||||||
* @return true if the process is present in this flag fields,
|
* @return true if the process is present in this flag fields,
|
||||||
* false if not.
|
* false if not.
|
||||||
*/
|
*/
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Called prior to ExecuteOnScene().
|
/** Called prior to ExecuteOnScene().
|
||||||
* The function is a request to the process to update its configuration
|
* The function is a request to the process to update its configuration
|
||||||
* basing on the Importer's configuration property list.
|
* basing on the Importer's configuration property list.
|
||||||
*/
|
*/
|
||||||
virtual void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp) override;
|
||||||
|
|
||||||
|
|
||||||
//! Set the split limit - needed for unit testing
|
//! Set the split limit - needed for unit testing
|
||||||
inline void SetLimit(unsigned int l)
|
inline void SetLimit(unsigned int l)
|
||||||
|
@ -119,14 +116,12 @@ public:
|
||||||
inline unsigned int GetLimit() const
|
inline unsigned int GetLimit() const
|
||||||
{return LIMIT;}
|
{return LIMIT;}
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Executes the post processing step on the given imported data.
|
/** Executes the post processing step on the given imported data.
|
||||||
* At the moment a process is not supposed to fail.
|
* At the moment a process is not supposed to fail.
|
||||||
* @param pScene The imported data to work at.
|
* @param pScene The imported data to work at.
|
||||||
*/
|
*/
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Apply the algorithm to a given mesh
|
//! Apply the algorithm to a given mesh
|
||||||
|
@ -144,36 +139,31 @@ public:
|
||||||
unsigned int LIMIT;
|
unsigned int LIMIT;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Post-processing filter to split large meshes into sub-meshes
|
/** Post-processing filter to split large meshes into sub-meshes
|
||||||
*
|
*
|
||||||
* Applied AFTER the JoinVertices-Step occurs.
|
* Applied AFTER the JoinVertices-Step occurs.
|
||||||
* Returns UNIQUE vertices, splits by vertex number.
|
* Returns UNIQUE vertices, splits by vertex number.
|
||||||
*/
|
*/
|
||||||
class ASSIMP_API SplitLargeMeshesProcess_Vertex : public BaseProcess
|
class ASSIMP_API SplitLargeMeshesProcess_Vertex : public BaseProcess {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SplitLargeMeshesProcess_Vertex();
|
SplitLargeMeshesProcess_Vertex();
|
||||||
~SplitLargeMeshesProcess_Vertex();
|
~SplitLargeMeshesProcess_Vertex() override = default;
|
||||||
|
|
||||||
public:
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the processing step is present in the given flag field.
|
/** Returns whether the processing step is present in the given flag field.
|
||||||
* @param pFlags The processing flags the importer was called with. A bitwise
|
* @param pFlags The processing flags the importer was called with. A bitwise
|
||||||
* combination of #aiPostProcessSteps.
|
* combination of #aiPostProcessSteps.
|
||||||
* @return true if the process is present in this flag fields, false if not.
|
* @return true if the process is present in this flag fields, false if not.
|
||||||
*/
|
*/
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Called prior to ExecuteOnScene().
|
/** Called prior to ExecuteOnScene().
|
||||||
* The function is a request to the process to update its configuration
|
* The function is a request to the process to update its configuration
|
||||||
* basing on the Importer's configuration property list.
|
* basing on the Importer's configuration property list.
|
||||||
*/
|
*/
|
||||||
virtual void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp) override;
|
||||||
|
|
||||||
|
|
||||||
//! Set the split limit - needed for unit testing
|
//! Set the split limit - needed for unit testing
|
||||||
inline void SetLimit(unsigned int l)
|
inline void SetLimit(unsigned int l)
|
||||||
|
@ -183,14 +173,12 @@ public:
|
||||||
inline unsigned int GetLimit() const
|
inline unsigned int GetLimit() const
|
||||||
{return LIMIT;}
|
{return LIMIT;}
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Executes the post processing step on the given imported data.
|
/** Executes the post processing step on the given imported data.
|
||||||
* At the moment a process is not supposed to fail.
|
* At the moment a process is not supposed to fail.
|
||||||
* @param pScene The imported data to work at.
|
* @param pScene The imported data to work at.
|
||||||
*/
|
*/
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Apply the algorithm to a given mesh
|
//! Apply the algorithm to a given mesh
|
||||||
|
|
|
@ -56,33 +56,24 @@ using namespace Assimp;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
TextureTransformStep::TextureTransformStep() :
|
TextureTransformStep::TextureTransformStep() : configFlags() {
|
||||||
configFlags()
|
|
||||||
{
|
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
TextureTransformStep::~TextureTransformStep() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool TextureTransformStep::IsActive( unsigned int pFlags) const
|
bool TextureTransformStep::IsActive( unsigned int pFlags) const {
|
||||||
{
|
|
||||||
return (pFlags & aiProcess_TransformUVCoords) != 0;
|
return (pFlags & aiProcess_TransformUVCoords) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Setup properties
|
// Setup properties
|
||||||
void TextureTransformStep::SetupProperties(const Importer* pImp)
|
void TextureTransformStep::SetupProperties(const Importer* pImp) {
|
||||||
{
|
|
||||||
configFlags = pImp->GetPropertyInteger(AI_CONFIG_PP_TUV_EVALUATE,AI_UVTRAFO_ALL);
|
configFlags = pImp->GetPropertyInteger(AI_CONFIG_PP_TUV_EVALUATE,AI_UVTRAFO_ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info)
|
void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info) {
|
||||||
{
|
|
||||||
/* This function tries to simplify the input UV transformation.
|
/* This function tries to simplify the input UV transformation.
|
||||||
* That's very important as it allows us to reduce the number
|
* That's very important as it allows us to reduce the number
|
||||||
* of output UV channels. The order in which the transformations
|
* of output UV channels. The order in which the transformations
|
||||||
|
@ -90,7 +81,7 @@ void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int rounded;
|
int rounded;
|
||||||
char szTemp[512];
|
char szTemp[512] = {};
|
||||||
|
|
||||||
/* Optimize the rotation angle. That's slightly difficult as
|
/* Optimize the rotation angle. That's slightly difficult as
|
||||||
* we have an inprecise floating-point number (when comparing
|
* we have an inprecise floating-point number (when comparing
|
||||||
|
@ -98,12 +89,10 @@ void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info)
|
||||||
* an epsilon of 5 degrees). If there is a rotation value, we can't
|
* an epsilon of 5 degrees). If there is a rotation value, we can't
|
||||||
* perform any further optimizations.
|
* perform any further optimizations.
|
||||||
*/
|
*/
|
||||||
if (info.mRotation)
|
if (info.mRotation) {
|
||||||
{
|
|
||||||
float out = info.mRotation;
|
float out = info.mRotation;
|
||||||
rounded = static_cast<int>((info.mRotation / static_cast<float>(AI_MATH_TWO_PI)));
|
rounded = static_cast<int>((info.mRotation / static_cast<float>(AI_MATH_TWO_PI)));
|
||||||
if (rounded)
|
if (rounded) {
|
||||||
{
|
|
||||||
out -= rounded * static_cast<float>(AI_MATH_PI);
|
out -= rounded * static_cast<float>(AI_MATH_PI);
|
||||||
ASSIMP_LOG_INFO("Texture coordinate rotation ", info.mRotation, " can be simplified to ", out);
|
ASSIMP_LOG_INFO("Texture coordinate rotation ", info.mRotation, " can be simplified to ", out);
|
||||||
}
|
}
|
||||||
|
@ -187,8 +176,7 @@ void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void UpdateUVIndex(const std::list<TTUpdateInfo>& l, unsigned int n)
|
void UpdateUVIndex(const std::list<TTUpdateInfo>& l, unsigned int n) {
|
||||||
{
|
|
||||||
// Don't set if == 0 && wasn't set before
|
// Don't set if == 0 && wasn't set before
|
||||||
for (std::list<TTUpdateInfo>::const_iterator it = l.begin();it != l.end(); ++it) {
|
for (std::list<TTUpdateInfo>::const_iterator it = l.begin();it != l.end(); ++it) {
|
||||||
const TTUpdateInfo& info = *it;
|
const TTUpdateInfo& info = *it;
|
||||||
|
@ -203,8 +191,7 @@ void UpdateUVIndex(const std::list<TTUpdateInfo>& l, unsigned int n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
inline const char* MappingModeToChar(aiTextureMapMode map)
|
inline static const char* MappingModeToChar(aiTextureMapMode map) {
|
||||||
{
|
|
||||||
if (aiTextureMapMode_Wrap == map)
|
if (aiTextureMapMode_Wrap == map)
|
||||||
return "-w";
|
return "-w";
|
||||||
|
|
||||||
|
@ -215,8 +202,7 @@ inline const char* MappingModeToChar(aiTextureMapMode map)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void TextureTransformStep::Execute( aiScene* pScene)
|
void TextureTransformStep::Execute( aiScene* pScene) {
|
||||||
{
|
|
||||||
ASSIMP_LOG_DEBUG("TransformUVCoordsProcess begin");
|
ASSIMP_LOG_DEBUG("TransformUVCoordsProcess begin");
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -193,28 +193,23 @@ struct STransformVecInfo : public aiUVTransform {
|
||||||
/** Helper step to compute final UV coordinate sets if there are scalings
|
/** Helper step to compute final UV coordinate sets if there are scalings
|
||||||
* or rotations in the original data read from the file.
|
* or rotations in the original data read from the file.
|
||||||
*/
|
*/
|
||||||
class TextureTransformStep : public BaseProcess
|
class TextureTransformStep : public BaseProcess {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/// The default class constructor / destructor.
|
||||||
TextureTransformStep();
|
TextureTransformStep();
|
||||||
~TextureTransformStep();
|
~TextureTransformStep() override = default;
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp) override;
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Preprocess a specific UV transformation setup
|
/** Preprocess a specific UV transformation setup
|
||||||
*
|
*
|
||||||
|
@ -223,10 +218,9 @@ protected:
|
||||||
void PreProcessUVTransform(STransformVecInfo& info);
|
void PreProcessUVTransform(STransformVecInfo& info);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
unsigned int configFlags;
|
unsigned int configFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace Assimp
|
||||||
|
|
||||||
#endif //! AI_TEXTURE_TRANSFORM_H_INCLUDED
|
#endif //! AI_TEXTURE_TRANSFORM_H_INCLUDED
|
||||||
|
|
|
@ -156,15 +156,6 @@ namespace {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Constructor to be privately used by Importer
|
|
||||||
TriangulateProcess::TriangulateProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
TriangulateProcess::~TriangulateProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool TriangulateProcess::IsActive( unsigned int pFlags) const
|
bool TriangulateProcess::IsActive( unsigned int pFlags) const
|
||||||
|
@ -468,6 +459,21 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Skip when three point is in a line
|
||||||
|
aiVector2D left = *pnt0 - *pnt1;
|
||||||
|
aiVector2D right = *pnt2 - *pnt1;
|
||||||
|
|
||||||
|
left.Normalize();
|
||||||
|
right.Normalize();
|
||||||
|
auto mul = left * right;
|
||||||
|
|
||||||
|
// if the angle is 0 or 180
|
||||||
|
if (std::abs(mul - 1.f) < ai_epsilon || std::abs(mul + 1.f) < ai_epsilon) {
|
||||||
|
// skip this ear
|
||||||
|
ASSIMP_LOG_WARN("Skip a ear, due to its angle is near 0 or 180.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// and no other point may be contained in this triangle
|
// and no other point may be contained in this triangle
|
||||||
for ( tmp = 0; tmp < max; ++tmp) {
|
for ( tmp = 0; tmp < max; ++tmp) {
|
||||||
|
|
||||||
|
|
|
@ -61,8 +61,10 @@ namespace Assimp {
|
||||||
*/
|
*/
|
||||||
class ASSIMP_API TriangulateProcess : public BaseProcess {
|
class ASSIMP_API TriangulateProcess : public BaseProcess {
|
||||||
public:
|
public:
|
||||||
TriangulateProcess();
|
// -------------------------------------------------------------------
|
||||||
~TriangulateProcess();
|
/// The default class constructor / destructor.
|
||||||
|
TriangulateProcess() = default;
|
||||||
|
~TriangulateProcess() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the processing step is present in the given flag field.
|
/** Returns whether the processing step is present in the given flag field.
|
||||||
|
@ -70,14 +72,14 @@ public:
|
||||||
* combination of #aiPostProcessSteps.
|
* combination of #aiPostProcessSteps.
|
||||||
* @return true if the process is present in this flag fields, false if not.
|
* @return true if the process is present in this flag fields, false if not.
|
||||||
*/
|
*/
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Executes the post processing step on the given imported data.
|
/** Executes the post processing step on the given imported data.
|
||||||
* At the moment a process is not supposed to fail.
|
* At the moment a process is not supposed to fail.
|
||||||
* @param pScene The imported data to work at.
|
* @param pScene The imported data to work at.
|
||||||
*/
|
*/
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Triangulates the given mesh.
|
/** Triangulates the given mesh.
|
||||||
|
|
|
@ -60,12 +60,7 @@ using namespace Assimp;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
ValidateDSProcess::ValidateDSProcess() :
|
ValidateDSProcess::ValidateDSProcess() : mScene(nullptr) {}
|
||||||
mScene() {}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
ValidateDSProcess::~ValidateDSProcess() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
|
@ -916,7 +911,12 @@ void ValidateDSProcess::Validate(const aiNode *pNode) {
|
||||||
nodeName, pNode->mNumChildren);
|
nodeName, pNode->mNumChildren);
|
||||||
}
|
}
|
||||||
for (unsigned int i = 0; i < pNode->mNumChildren; ++i) {
|
for (unsigned int i = 0; i < pNode->mNumChildren; ++i) {
|
||||||
Validate(pNode->mChildren[i]);
|
const aiNode *pChild = pNode->mChildren[i];
|
||||||
|
Validate(pChild);
|
||||||
|
if (pChild->mParent != pNode) {
|
||||||
|
const char *parentName = (pChild->mParent != nullptr) ? pChild->mParent->mName.C_Str() : "null";
|
||||||
|
ReportError("aiNode \"%s\" child %i \"%s\" parent is someone else: \"%s\"", pNode->mName.C_Str(), i, pChild->mName.C_Str(), parentName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,22 +69,20 @@ namespace Assimp {
|
||||||
/** Validates the whole ASSIMP scene data structure for correctness.
|
/** Validates the whole ASSIMP scene data structure for correctness.
|
||||||
* ImportErrorException is thrown of the scene is corrupt.*/
|
* ImportErrorException is thrown of the scene is corrupt.*/
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
class ValidateDSProcess : public BaseProcess
|
class ValidateDSProcess : public BaseProcess {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/// The default class constructor / destructor.
|
||||||
ValidateDSProcess();
|
ValidateDSProcess();
|
||||||
~ValidateDSProcess();
|
~ValidateDSProcess() override = default;
|
||||||
|
|
||||||
public:
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
bool IsActive( unsigned int pFlags) const;
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
void Execute( aiScene* pScene);
|
bool IsActive( unsigned int pFlags) const override;
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
void Execute( aiScene* pScene) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Report a validation error. This will throw an exception,
|
/** Report a validation error. This will throw an exception,
|
||||||
* control won't return.
|
* control won't return.
|
||||||
|
|
|
@ -1,102 +1,137 @@
|
||||||
# Generated with cmake-format 0.5.1
|
with section('parse'):
|
||||||
# How wide to allow formatted cmake files
|
# Specify structure for custom cmake functions
|
||||||
line_width = 80
|
additional_commands = {
|
||||||
|
'draco_add_emscripten_executable': {
|
||||||
# How many spaces to tab for indent
|
'kwargs': {
|
||||||
tab_size = 2
|
'NAME': '*',
|
||||||
|
'SOURCES': '*',
|
||||||
# If arglists are longer than this, break them always
|
'OUTPUT_NAME': '*',
|
||||||
max_subargs_per_line = 10
|
'DEFINES': '*',
|
||||||
|
'INCLUDES': '*',
|
||||||
# If true, separate flow control names from their parentheses with a space
|
'COMPILE_FLAGS': '*',
|
||||||
separate_ctrl_name_with_space = False
|
'LINK_FLAGS': '*',
|
||||||
|
'OBJLIB_DEPS': '*',
|
||||||
# If true, separate function names from parentheses with a space
|
'LIB_DEPS': '*',
|
||||||
separate_fn_name_with_space = False
|
'GLUE_PATH': '*',
|
||||||
|
'PRE_LINK_JS_SOURCES': '*',
|
||||||
# If a statement is wrapped to more than one line, than dangle the closing
|
'POST_LINK_JS_SOURCES': '*',
|
||||||
# parenthesis on its own line
|
'FEATURES': '*',
|
||||||
dangle_parens = False
|
},
|
||||||
|
'pargs': 0,
|
||||||
# What character to use for bulleted lists
|
},
|
||||||
bullet_char = '*'
|
'draco_add_executable': {
|
||||||
|
'kwargs': {
|
||||||
# What character to use as punctuation after numerals in an enumerated list
|
'NAME': '*',
|
||||||
enum_char = '.'
|
'SOURCES': '*',
|
||||||
|
'OUTPUT_NAME': '*',
|
||||||
# What style line endings to use in the output.
|
'TEST': 0,
|
||||||
line_ending = u'unix'
|
'DEFINES': '*',
|
||||||
|
'INCLUDES': '*',
|
||||||
# Format command names consistently as 'lower' or 'upper' case
|
'COMPILE_FLAGS': '*',
|
||||||
command_case = u'lower'
|
'LINK_FLAGS': '*',
|
||||||
|
'OBJLIB_DEPS': '*',
|
||||||
# Format keywords consistently as 'lower' or 'upper' case
|
'LIB_DEPS': '*',
|
||||||
keyword_case = u'unchanged'
|
},
|
||||||
|
'pargs': 0,
|
||||||
# Specify structure for custom cmake functions
|
},
|
||||||
additional_commands = {
|
'draco_add_library': {
|
||||||
"foo": {
|
'kwargs': {
|
||||||
"flags": [
|
'NAME': '*',
|
||||||
"BAR",
|
'TYPE': '*',
|
||||||
"BAZ"
|
'SOURCES': '*',
|
||||||
],
|
'TEST': 0,
|
||||||
"kwargs": {
|
'OUTPUT_NAME': '*',
|
||||||
"HEADERS": "*",
|
'DEFINES': '*',
|
||||||
"DEPENDS": "*",
|
'INCLUDES': '*',
|
||||||
"SOURCES": "*"
|
'COMPILE_FLAGS': '*',
|
||||||
|
'LINK_FLAGS': '*',
|
||||||
|
'OBJLIB_DEPS': '*',
|
||||||
|
'LIB_DEPS': '*',
|
||||||
|
'PUBLIC_INCLUDES': '*',
|
||||||
|
},
|
||||||
|
'pargs': 0,
|
||||||
|
},
|
||||||
|
'draco_generate_emscripten_glue': {
|
||||||
|
'kwargs': {
|
||||||
|
'INPUT_IDL': '*',
|
||||||
|
'OUTPUT_PATH': '*',
|
||||||
|
},
|
||||||
|
'pargs': 0,
|
||||||
|
},
|
||||||
|
'draco_get_required_emscripten_flags': {
|
||||||
|
'kwargs': {
|
||||||
|
'FLAG_LIST_VAR_COMPILER': '*',
|
||||||
|
'FLAG_LIST_VAR_LINKER': '*',
|
||||||
|
},
|
||||||
|
'pargs': 0,
|
||||||
|
},
|
||||||
|
'draco_option': {
|
||||||
|
'kwargs': {
|
||||||
|
'NAME': '*',
|
||||||
|
'HELPSTRING': '*',
|
||||||
|
'VALUE': '*',
|
||||||
|
},
|
||||||
|
'pargs': 0,
|
||||||
|
},
|
||||||
|
# Rules for built in CMake commands and those from dependencies.
|
||||||
|
'list': {
|
||||||
|
'kwargs': {
|
||||||
|
'APPEND': '*',
|
||||||
|
'FILTER': '*',
|
||||||
|
'FIND': '*',
|
||||||
|
'GET': '*',
|
||||||
|
'INSERT': '*',
|
||||||
|
'JOIN': '*',
|
||||||
|
'LENGTH': '*',
|
||||||
|
'POP_BACK': '*',
|
||||||
|
'POP_FRONT': '*',
|
||||||
|
'PREPEND': '*',
|
||||||
|
'REMOVE_DUPLICATES': '*',
|
||||||
|
'REMOVE_ITEM': '*',
|
||||||
|
'REVERSE': '*',
|
||||||
|
'SORT': '*',
|
||||||
|
'SUBLIST': '*',
|
||||||
|
'TRANSFORM': '*',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'protobuf_generate': {
|
||||||
|
'kwargs': {
|
||||||
|
'IMPORT_DIRS': '*',
|
||||||
|
'LANGUAGE': '*',
|
||||||
|
'OUT_VAR': '*',
|
||||||
|
'PROTOC_OUT_DIR': '*',
|
||||||
|
'PROTOS': '*',
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# A list of command names which should always be wrapped
|
with section('format'):
|
||||||
always_wrap = []
|
# Formatting options.
|
||||||
|
|
||||||
# Specify the order of wrapping algorithms during successive reflow attempts
|
# How wide to allow formatted cmake files
|
||||||
algorithm_order = [0, 1, 2, 3, 4]
|
line_width = 80
|
||||||
|
|
||||||
# If true, the argument lists which are known to be sortable will be sorted
|
# How many spaces to tab for indent
|
||||||
# lexicographicall
|
tab_size = 2
|
||||||
autosort = False
|
|
||||||
|
|
||||||
# enable comment markup parsing and reflow
|
# If true, separate flow control names from their parentheses with a space
|
||||||
enable_markup = True
|
separate_ctrl_name_with_space = False
|
||||||
|
|
||||||
# If comment markup is enabled, don't reflow the first comment block in
|
# If true, separate function names from parentheses with a space
|
||||||
# eachlistfile. Use this to preserve formatting of your
|
separate_fn_name_with_space = False
|
||||||
# copyright/licensestatements.
|
|
||||||
first_comment_is_literal = False
|
|
||||||
|
|
||||||
# If comment markup is enabled, don't reflow any comment block which matchesthis
|
# If a statement is wrapped to more than one line, than dangle the closing
|
||||||
# (regex) pattern. Default is `None` (disabled).
|
# parenthesis on its own line.
|
||||||
literal_comment_pattern = None
|
dangle_parens = False
|
||||||
|
|
||||||
# Regular expression to match preformat fences in comments
|
# Do not sort argument lists.
|
||||||
# default=r'^\s*([`~]{3}[`~]*)(.*)$'
|
enable_sort = False
|
||||||
fence_pattern = u'^\\s*([`~]{3}[`~]*)(.*)$'
|
|
||||||
|
|
||||||
# Regular expression to match rulers in comments
|
# What style line endings to use in the output.
|
||||||
# default=r'^\s*[^\w\s]{3}.*[^\w\s]{3}$'
|
line_ending = 'unix'
|
||||||
ruler_pattern = u'^\\s*[^\\w\\s]{3}.*[^\\w\\s]{3}$'
|
|
||||||
|
|
||||||
# If true, emit the unicode byte-order mark (BOM) at the start of the file
|
# Format command names consistently as 'lower' or 'upper' case
|
||||||
emit_byteorder_mark = False
|
command_case = 'canonical'
|
||||||
|
|
||||||
# If a comment line starts with at least this many consecutive hash characters,
|
# Format keywords consistently as 'lower' or 'upper' case
|
||||||
# then don't lstrip() them off. This allows for lazy hash rulers where the first
|
keyword_case = 'upper'
|
||||||
# hash char is not separated by space
|
|
||||||
hashruler_min_length = 10
|
|
||||||
|
|
||||||
# If true, then insert a space between the first hash char and remaining hash
|
|
||||||
# chars in a hash ruler, and normalize its length to fill the column
|
|
||||||
canonicalize_hashrulers = True
|
|
||||||
|
|
||||||
# Specify the encoding of the input file. Defaults to utf-8.
|
|
||||||
input_encoding = u'utf-8'
|
|
||||||
|
|
||||||
# Specify the encoding of the output file. Defaults to utf-8. Note that cmake
|
|
||||||
# only claims to support utf-8 so be careful when using anything else
|
|
||||||
output_encoding = u'utf-8'
|
|
||||||
|
|
||||||
# A dictionary containing any per-command configuration overrides. Currently
|
|
||||||
# only `command_case` is supported.
|
|
||||||
per_command = {}
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
*.obj eol=lf
|
|
@ -0,0 +1,12 @@
|
||||||
|
[submodule "third_party/googletest"]
|
||||||
|
path = third_party/googletest
|
||||||
|
url = https://github.com/google/googletest.git
|
||||||
|
[submodule "third_party/eigen"]
|
||||||
|
path = third_party/eigen
|
||||||
|
url = https://gitlab.com/libeigen/eigen.git
|
||||||
|
[submodule "third_party/tinygltf"]
|
||||||
|
path = third_party/tinygltf
|
||||||
|
url = https://github.com/syoyo/tinygltf.git
|
||||||
|
[submodule "third_party/filesystem"]
|
||||||
|
path = third_party/filesystem
|
||||||
|
url = https://github.com/gulrak/filesystem
|
|
@ -4,8 +4,10 @@ _**Contents**_
|
||||||
* [Mac OS X](#mac-os-x)
|
* [Mac OS X](#mac-os-x)
|
||||||
* [Windows](#windows)
|
* [Windows](#windows)
|
||||||
* [CMake Build Configuration](#cmake-build-configuration)
|
* [CMake Build Configuration](#cmake-build-configuration)
|
||||||
|
* [Transcoder](#transcoder)
|
||||||
* [Debugging and Optimization](#debugging-and-optimization)
|
* [Debugging and Optimization](#debugging-and-optimization)
|
||||||
* [Googletest Integration](#googletest-integration)
|
* [Googletest Integration](#googletest-integration)
|
||||||
|
* [Third Party Libraries](#third-party-libraries)
|
||||||
* [Javascript Encoder/Decoder](#javascript-encoderdecoder)
|
* [Javascript Encoder/Decoder](#javascript-encoderdecoder)
|
||||||
* [WebAssembly Decoder](#webassembly-decoder)
|
* [WebAssembly Decoder](#webassembly-decoder)
|
||||||
* [WebAssembly Mesh Only Decoder](#webassembly-mesh-only-decoder)
|
* [WebAssembly Mesh Only Decoder](#webassembly-mesh-only-decoder)
|
||||||
|
@ -72,6 +74,43 @@ C:\Users\nobody> cmake ../ -G "Visual Studio 16 2019" -A x64
|
||||||
CMake Build Configuration
|
CMake Build Configuration
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
|
Transcoder
|
||||||
|
----------
|
||||||
|
|
||||||
|
Before attempting to build Draco with transcoding support you must run an
|
||||||
|
additional Git command to obtain the submodules:
|
||||||
|
|
||||||
|
~~~~~ bash
|
||||||
|
# Run this command from within your Draco clone.
|
||||||
|
$ git submodule update --init
|
||||||
|
# See below if you prefer to use existing versions of Draco dependencies.
|
||||||
|
~~~~~
|
||||||
|
|
||||||
|
In order to build the `draco_transcoder` target, the transcoding support needs
|
||||||
|
to be explicitly enabled when you run `cmake`, for example:
|
||||||
|
|
||||||
|
~~~~~ bash
|
||||||
|
$ cmake ../ -DDRACO_TRANSCODER_SUPPORTED=ON
|
||||||
|
~~~~~
|
||||||
|
|
||||||
|
The above option is currently not compatible with our Javascript or WebAssembly
|
||||||
|
builds but all other use cases are supported. Note that binaries and libraries
|
||||||
|
built with the transcoder support may result in increased binary sizes of the
|
||||||
|
produced libraries and executables compared to the default CMake settings.
|
||||||
|
|
||||||
|
The following CMake variables can be used to configure Draco to use local
|
||||||
|
copies of third party dependencies instead of git submodules.
|
||||||
|
|
||||||
|
- `DRACO_EIGEN_PATH`: this path must contain an Eigen directory that includes
|
||||||
|
the Eigen sources.
|
||||||
|
- `DRACO_FILESYSTEM_PATH`: this path must contain the ghc directory where the
|
||||||
|
filesystem includes are located.
|
||||||
|
- `DRACO_TINYGLTF_PATH`: this path must contain tiny_gltf.h and its
|
||||||
|
dependencies.
|
||||||
|
|
||||||
|
When not specified the Draco build requires the presence of the submodules that
|
||||||
|
are stored within `draco/third_party`.
|
||||||
|
|
||||||
Debugging and Optimization
|
Debugging and Optimization
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
|
@ -114,17 +153,52 @@ $ cmake ../ -DDRACO_SANITIZE=address
|
||||||
Googletest Integration
|
Googletest Integration
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
Draco includes testing support built using Googletest. To enable Googletest unit
|
Draco includes testing support built using Googletest. The Googletest repository
|
||||||
test support the DRACO_TESTS cmake variable must be turned on at cmake
|
is included as a submodule of the Draco git repository. Run the following
|
||||||
generation time:
|
command to clone the Googletest repository:
|
||||||
|
|
||||||
|
~~~~~ bash
|
||||||
|
$ git submodule update --init
|
||||||
|
~~~~~
|
||||||
|
|
||||||
|
To enable Googletest unit test support the DRACO_TESTS cmake variable must be
|
||||||
|
turned on at cmake generation time:
|
||||||
|
|
||||||
~~~~~ bash
|
~~~~~ bash
|
||||||
$ cmake ../ -DDRACO_TESTS=ON
|
$ cmake ../ -DDRACO_TESTS=ON
|
||||||
~~~~~
|
~~~~~
|
||||||
|
|
||||||
When cmake is used as shown in the above example the googletest directory must
|
To run the tests execute `draco_tests` from your build output directory:
|
||||||
be a sibling of the Draco repository root directory. To run the tests execute
|
|
||||||
`draco_tests` from your build output directory.
|
~~~~~ bash
|
||||||
|
$ ./draco_tests
|
||||||
|
~~~~~
|
||||||
|
|
||||||
|
Draco can be configured to use a local Googletest installation. The
|
||||||
|
`DRACO_GOOGLETEST_PATH` variable overrides the behavior described above and
|
||||||
|
configures Draco to use the Googletest at the specified path.
|
||||||
|
|
||||||
|
Third Party Libraries
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
When Draco is built with transcoding and/or testing support enabled the project
|
||||||
|
has dependencies on third party libraries:
|
||||||
|
|
||||||
|
- [Eigen](https://eigen.tuxfamily.org/)
|
||||||
|
- Provides various math utilites.
|
||||||
|
- [Googletest](https://github.com/google/googletest)
|
||||||
|
- Provides testing support.
|
||||||
|
- [Gulrak/filesystem](https://github.com/gulrak/filesystem)
|
||||||
|
- Provides C++17 std::filesystem emulation for pre-C++17 environments.
|
||||||
|
- [TinyGLTF](https://github.com/syoyo/tinygltf)
|
||||||
|
- Provides GLTF I/O support.
|
||||||
|
|
||||||
|
These dependencies are managed as Git submodules. To obtain the dependencies
|
||||||
|
run the following command in your Draco repository:
|
||||||
|
|
||||||
|
~~~~~ bash
|
||||||
|
$ git submodule update --init
|
||||||
|
~~~~~
|
||||||
|
|
||||||
WebAssembly Decoder
|
WebAssembly Decoder
|
||||||
-------------------
|
-------------------
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,10 +2,93 @@
|
||||||
<img width="350px" src="docs/artwork/draco3d-vert.svg" />
|
<img width="350px" src="docs/artwork/draco3d-vert.svg" />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
[![Build Status](https://github.com/google/draco/workflows/Build/badge.svg)](https://github.com/google/draco/actions?query=workflow%3ABuild)
|
[![draco-ci](https://github.com/google/draco/workflows/draco-ci/badge.svg?branch=master)](https://github.com/google/draco/actions/workflows/ci.yml)
|
||||||
|
|
||||||
News
|
News
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
Attention GStatic users: the Draco team strongly recommends using the versioned
|
||||||
|
URLs for accessing Draco GStatic content. If you are using the URLs that include
|
||||||
|
the `v1/decoders` substring within the URL, edge caching and GStatic propagation
|
||||||
|
delays can result in transient errors that can be difficult to diagnose when
|
||||||
|
new Draco releases are launched. To avoid the issue pin your sites to a
|
||||||
|
versioned release.
|
||||||
|
|
||||||
|
### Version 1.5.6 release:
|
||||||
|
* Using the versioned www.gstatic.com WASM and Javascript decoders continues
|
||||||
|
to be recommended. To use v1.5.6, use this URL:
|
||||||
|
* https://www.gstatic.com/draco/versioned/decoders/1.5.6/*
|
||||||
|
* The CMake flag DRACO_DEBUG_MSVC_WARNINGS has been replaced with
|
||||||
|
DRACO_DEBUG_COMPILER_WARNINGS, and the behavior has changed. It is now a
|
||||||
|
boolean flag defined in draco_options.cmake.
|
||||||
|
* Bug fixes.
|
||||||
|
* Security fixes.
|
||||||
|
|
||||||
|
### Version 1.5.5 release:
|
||||||
|
* Using the versioned www.gstatic.com WASM and Javascript decoders continues
|
||||||
|
to be recommended. To use v1.5.5, use this URL:
|
||||||
|
* https://www.gstatic.com/draco/versioned/decoders/1.5.5/*
|
||||||
|
* Bug fix: https://github.com/google/draco/issues/935
|
||||||
|
|
||||||
|
### Version 1.5.4 release:
|
||||||
|
* Using the versioned www.gstatic.com WASM and Javascript decoders continues
|
||||||
|
to be recommended. To use v1.5.4, use this URL:
|
||||||
|
* https://www.gstatic.com/draco/versioned/decoders/1.5.4/*
|
||||||
|
* Added partial support for glTF extensions EXT_mesh_features and
|
||||||
|
EXT_structural_metadata.
|
||||||
|
* Bug fixes.
|
||||||
|
* Security fixes.
|
||||||
|
|
||||||
|
### Version 1.5.3 release:
|
||||||
|
* Using the versioned www.gstatic.com WASM and Javascript decoders continues
|
||||||
|
to be recommended. To use v1.5.3, use this URL:
|
||||||
|
* https://www.gstatic.com/draco/versioned/decoders/1.5.3/*
|
||||||
|
* Bug fixes.
|
||||||
|
|
||||||
|
### Version 1.5.2 release
|
||||||
|
* This is the same as v1.5.1 with the following two bug fixes:
|
||||||
|
* Fixes DRACO_TRANSCODER_SUPPORTED enabled builds.
|
||||||
|
* ABI version updated.
|
||||||
|
|
||||||
|
### Version 1.5.1 release
|
||||||
|
* Adds assertion enabled Emscripten builds to the release, and a subset of the
|
||||||
|
assertion enabled builds to GStatic. See the file listing below.
|
||||||
|
* Custom paths to third party dependencies are now supported. See BUILDING.md
|
||||||
|
for more information.
|
||||||
|
* The CMake configuration file draco-config.cmake is now tested and known to
|
||||||
|
work for using Draco in Linux, MacOS, and Windows CMake projects. See the
|
||||||
|
`install_test` subdirectory of `src/draco/tools` for more information.
|
||||||
|
* Bug fixes.
|
||||||
|
|
||||||
|
### Version 1.5.0 release
|
||||||
|
* Adds the draco_transcoder tool. See the section below on the glTF transcoding
|
||||||
|
tool, and BUILDING.md for build and dependency information.
|
||||||
|
* Some changes to configuration variables have been made for this release:
|
||||||
|
- The DRACO_GLTF flag has been renamed to DRACO_GLTF_BITSTREAM to help
|
||||||
|
increase understanding of its purpose, which is to limit Draco features to
|
||||||
|
those included in the Draco glTF specification.
|
||||||
|
- Variables exported in CMake via draco-config.cmake and find-draco.cmake
|
||||||
|
(formerly FindDraco.cmake) have been renamed. It's unlikely that this
|
||||||
|
impacts any existing projects as the aforementioned files were not formed
|
||||||
|
correctly. See [PR775](https://github.com/google/draco/pull/775) for full
|
||||||
|
details of the changes.
|
||||||
|
* A CMake version file has been added.
|
||||||
|
* The CMake install target now uses absolute paths direct from CMake instead
|
||||||
|
of building them using CMAKE_INSTALL_PREFIX. This was done to make Draco
|
||||||
|
easier to use for downstream packagers and should have little to no impact on
|
||||||
|
users picking up Draco from source.
|
||||||
|
* Certain MSVC warnings have had their levels changed via compiler flag to
|
||||||
|
reduce the amount of noise output by the MSVC compilers. Set MSVC warning
|
||||||
|
level to 4, or define DRACO_DEBUG_MSVC_WARNINGS at CMake configuration time
|
||||||
|
to restore previous behavior.
|
||||||
|
* Bug fixes.
|
||||||
|
|
||||||
|
### Version 1.4.3 release
|
||||||
|
* Using the versioned www.gstatic.com WASM and Javascript decoders continues
|
||||||
|
to be recommended. To use v1.4.3, use this URL:
|
||||||
|
* https://www.gstatic.com/draco/versioned/decoders/1.4.3/*
|
||||||
|
* Bug fixes
|
||||||
|
|
||||||
### Version 1.4.1 release
|
### Version 1.4.1 release
|
||||||
* Using the versioned www.gstatic.com WASM and Javascript decoders is now
|
* Using the versioned www.gstatic.com WASM and Javascript decoders is now
|
||||||
recommended. To use v1.4.1, use this URL:
|
recommended. To use v1.4.1, use this URL:
|
||||||
|
@ -129,6 +212,7 @@ _**Contents**_
|
||||||
* [Encoding Tool](#encoding-tool)
|
* [Encoding Tool](#encoding-tool)
|
||||||
* [Encoding Point Clouds](#encoding-point-clouds)
|
* [Encoding Point Clouds](#encoding-point-clouds)
|
||||||
* [Decoding Tool](#decoding-tool)
|
* [Decoding Tool](#decoding-tool)
|
||||||
|
* [glTF Transcoding Tool](#gltf-transcoding-tool)
|
||||||
* [C++ Decoder API](#c-decoder-api)
|
* [C++ Decoder API](#c-decoder-api)
|
||||||
* [Javascript Encoder API](#javascript-encoder-api)
|
* [Javascript Encoder API](#javascript-encoder-api)
|
||||||
* [Javascript Decoder API](#javascript-decoder-api)
|
* [Javascript Decoder API](#javascript-decoder-api)
|
||||||
|
@ -136,6 +220,7 @@ _**Contents**_
|
||||||
* [Metadata API](#metadata-api)
|
* [Metadata API](#metadata-api)
|
||||||
* [NPM Package](#npm-package)
|
* [NPM Package](#npm-package)
|
||||||
* [three.js Renderer Example](#threejs-renderer-example)
|
* [three.js Renderer Example](#threejs-renderer-example)
|
||||||
|
* [GStatic Javascript Builds](#gstatic-javascript-builds)
|
||||||
* [Support](#support)
|
* [Support](#support)
|
||||||
* [License](#license)
|
* [License](#license)
|
||||||
* [References](#references)
|
* [References](#references)
|
||||||
|
@ -170,16 +255,18 @@ Command Line Applications
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
The default target created from the build files will be the `draco_encoder`
|
The default target created from the build files will be the `draco_encoder`
|
||||||
and `draco_decoder` command line applications. For both applications, if you
|
and `draco_decoder` command line applications. Additionally, `draco_transcoder`
|
||||||
run them without any arguments or `-h`, the applications will output usage and
|
is generated when CMake is run with the DRACO_TRANSCODER_SUPPORTED variable set
|
||||||
options.
|
to ON (see [BUILDING](BUILDING.md#transcoder) for more details). For all
|
||||||
|
applications, if you run them without any arguments or `-h`, the applications
|
||||||
|
will output usage and options.
|
||||||
|
|
||||||
Encoding Tool
|
Encoding Tool
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
`draco_encoder` will read OBJ or PLY files as input, and output Draco-encoded
|
`draco_encoder` will read OBJ, STL or PLY files as input, and output
|
||||||
files. We have included Stanford's [Bunny] mesh for testing. The basic command
|
Draco-encoded files. We have included Stanford's [Bunny] mesh for testing. The
|
||||||
line looks like this:
|
basic command line looks like this:
|
||||||
|
|
||||||
~~~~~ bash
|
~~~~~ bash
|
||||||
./draco_encoder -i testdata/bun_zipper.ply -o out.drc
|
./draco_encoder -i testdata/bun_zipper.ply -o out.drc
|
||||||
|
@ -232,15 +319,34 @@ and denser point clouds.
|
||||||
Decoding Tool
|
Decoding Tool
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
`draco_decoder` will read Draco files as input, and output OBJ or PLY files.
|
`draco_decoder` will read Draco files as input, and output OBJ, STL or PLY
|
||||||
The basic command line looks like this:
|
files. The basic command line looks like this:
|
||||||
|
|
||||||
~~~~~ bash
|
~~~~~ bash
|
||||||
./draco_decoder -i in.drc -o out.obj
|
./draco_decoder -i in.drc -o out.obj
|
||||||
~~~~~
|
~~~~~
|
||||||
|
|
||||||
|
glTF Transcoding Tool
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
`draco_transcoder` can be used to add Draco compression to glTF assets. The
|
||||||
|
basic command line looks like this:
|
||||||
|
|
||||||
|
~~~~~ bash
|
||||||
|
./draco_transcoder -i in.glb -o out.glb
|
||||||
|
~~~~~
|
||||||
|
|
||||||
|
This command line will add geometry compression to all meshes in the `in.glb`
|
||||||
|
file. Quantization values for different glTF attributes can be specified
|
||||||
|
similarly to the `draco_encoder` tool. For example `-qp` can be used to define
|
||||||
|
quantization of the position attribute:
|
||||||
|
|
||||||
|
~~~~~ bash
|
||||||
|
./draco_transcoder -i in.glb -o out.glb -qp 12
|
||||||
|
~~~~~
|
||||||
|
|
||||||
C++ Decoder API
|
C++ Decoder API
|
||||||
-------------
|
---------------
|
||||||
|
|
||||||
If you'd like to add decoding to your applications you will need to include
|
If you'd like to add decoding to your applications you will need to include
|
||||||
the `draco_dec` library. In order to use the Draco decoder you need to
|
the `draco_dec` library. In order to use the Draco decoder you need to
|
||||||
|
@ -442,6 +548,30 @@ Javascript decoder using the `three.js` renderer.
|
||||||
|
|
||||||
Please see the [javascript/example/README.md](javascript/example/README.md) file for more information.
|
Please see the [javascript/example/README.md](javascript/example/README.md) file for more information.
|
||||||
|
|
||||||
|
GStatic Javascript Builds
|
||||||
|
=========================
|
||||||
|
|
||||||
|
Prebuilt versions of the Emscripten-built Draco javascript decoders are hosted
|
||||||
|
on www.gstatic.com in version labeled directories:
|
||||||
|
|
||||||
|
https://www.gstatic.com/draco/versioned/decoders/VERSION/*
|
||||||
|
|
||||||
|
As of the v1.4.3 release the files available are:
|
||||||
|
|
||||||
|
- [draco_decoder.js](https://www.gstatic.com/draco/versioned/decoders/1.4.3/draco_decoder.js)
|
||||||
|
- [draco_decoder.wasm](https://www.gstatic.com/draco/versioned/decoders/1.4.3/draco_decoder.wasm)
|
||||||
|
- [draco_decoder_gltf.js](https://www.gstatic.com/draco/versioned/decoders/1.4.3/draco_decoder_gltf.js)
|
||||||
|
- [draco_decoder_gltf.wasm](https://www.gstatic.com/draco/versioned/decoders/1.4.3/draco_decoder_gltf.wasm)
|
||||||
|
- [draco_wasm_wrapper.js](https://www.gstatic.com/draco/versioned/decoders/1.4.3/draco_wasm_wrapper.js)
|
||||||
|
- [draco_wasm_wrapper_gltf.js](https://www.gstatic.com/draco/versioned/decoders/1.4.3/draco_wasm_wrapper_gltf.js)
|
||||||
|
|
||||||
|
Beginning with the v1.5.1 release assertion enabled builds of the following
|
||||||
|
files are available:
|
||||||
|
|
||||||
|
- [draco_decoder.js](https://www.gstatic.com/draco/versioned/decoders/1.5.1/with_asserts/draco_decoder.js)
|
||||||
|
- [draco_decoder.wasm](https://www.gstatic.com/draco/versioned/decoders/1.5.1/with_asserts/draco_decoder.wasm)
|
||||||
|
- [draco_wasm_wrapper.js](https://www.gstatic.com/draco/versioned/decoders/1.5.1/with_asserts/draco_wasm_wrapper.js)
|
||||||
|
|
||||||
Support
|
Support
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
@PACKAGE_INIT@
|
|
||||||
set_and_check(draco_INCLUDE_DIR "@PACKAGE_draco_include_install_dir@")
|
|
||||||
set_and_check(draco_LIBRARY_DIR "@PACKAGE_draco_lib_install_dir@")
|
|
|
@ -1,56 +0,0 @@
|
||||||
# Finddraco
|
|
||||||
#
|
|
||||||
# Locates draco and sets the following variables:
|
|
||||||
#
|
|
||||||
# draco_FOUND draco_INCLUDE_DIRS draco_LIBARY_DIRS draco_LIBRARIES
|
|
||||||
# draco_VERSION_STRING
|
|
||||||
#
|
|
||||||
# draco_FOUND is set to YES only when all other variables are successfully
|
|
||||||
# configured.
|
|
||||||
|
|
||||||
unset(draco_FOUND)
|
|
||||||
unset(draco_INCLUDE_DIRS)
|
|
||||||
unset(draco_LIBRARY_DIRS)
|
|
||||||
unset(draco_LIBRARIES)
|
|
||||||
unset(draco_VERSION_STRING)
|
|
||||||
|
|
||||||
mark_as_advanced(draco_FOUND)
|
|
||||||
mark_as_advanced(draco_INCLUDE_DIRS)
|
|
||||||
mark_as_advanced(draco_LIBRARY_DIRS)
|
|
||||||
mark_as_advanced(draco_LIBRARIES)
|
|
||||||
mark_as_advanced(draco_VERSION_STRING)
|
|
||||||
|
|
||||||
set(draco_version_file_no_prefix "draco/src/draco/core/draco_version.h")
|
|
||||||
|
|
||||||
# Set draco_INCLUDE_DIRS
|
|
||||||
find_path(draco_INCLUDE_DIRS NAMES "${draco_version_file_no_prefix}")
|
|
||||||
|
|
||||||
# Extract the version string from draco_version.h.
|
|
||||||
if(draco_INCLUDE_DIRS)
|
|
||||||
set(draco_version_file
|
|
||||||
"${draco_INCLUDE_DIRS}/draco/src/draco/core/draco_version.h")
|
|
||||||
file(STRINGS "${draco_version_file}" draco_version REGEX "kdracoVersion")
|
|
||||||
list(GET draco_version 0 draco_version)
|
|
||||||
string(REPLACE "static const char kdracoVersion[] = " "" draco_version
|
|
||||||
"${draco_version}")
|
|
||||||
string(REPLACE ";" "" draco_version "${draco_version}")
|
|
||||||
string(REPLACE "\"" "" draco_version "${draco_version}")
|
|
||||||
set(draco_VERSION_STRING ${draco_version})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Find the library.
|
|
||||||
if(BUILD_SHARED_LIBS)
|
|
||||||
find_library(draco_LIBRARIES NAMES draco.dll libdraco.dylib libdraco.so)
|
|
||||||
else()
|
|
||||||
find_library(draco_LIBRARIES NAMES draco.lib libdraco.a)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Store path to library.
|
|
||||||
get_filename_component(draco_LIBRARY_DIRS ${draco_LIBRARIES} DIRECTORY)
|
|
||||||
|
|
||||||
if(draco_INCLUDE_DIRS
|
|
||||||
AND draco_LIBRARY_DIRS
|
|
||||||
AND draco_LIBRARIES
|
|
||||||
AND draco_VERSION_STRING)
|
|
||||||
set(draco_FOUND YES)
|
|
||||||
endif()
|
|
|
@ -1,220 +0,0 @@
|
||||||
if(DRACO_CMAKE_COMPILER_FLAGS_CMAKE_)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
set(DRACO_CMAKE_COMPILER_FLAGS_CMAKE_ 1)
|
|
||||||
|
|
||||||
include(CheckCCompilerFlag)
|
|
||||||
include(CheckCXXCompilerFlag)
|
|
||||||
include("${draco_root}/cmake/compiler_tests.cmake")
|
|
||||||
|
|
||||||
# Strings used to cache failed C/CXX flags.
|
|
||||||
set(DRACO_FAILED_C_FLAGS)
|
|
||||||
set(DRACO_FAILED_CXX_FLAGS)
|
|
||||||
|
|
||||||
# Checks C compiler for support of $c_flag. Adds $c_flag to $CMAKE_C_FLAGS when
|
|
||||||
# the compile test passes. Caches $c_flag in $DRACO_FAILED_C_FLAGS when the test
|
|
||||||
# fails.
|
|
||||||
macro(add_c_flag_if_supported c_flag)
|
|
||||||
unset(C_FLAG_FOUND CACHE)
|
|
||||||
string(FIND "${CMAKE_C_FLAGS}" "${c_flag}" C_FLAG_FOUND)
|
|
||||||
unset(C_FLAG_FAILED CACHE)
|
|
||||||
string(FIND "${DRACO_FAILED_C_FLAGS}" "${c_flag}" C_FLAG_FAILED)
|
|
||||||
|
|
||||||
if(${C_FLAG_FOUND} EQUAL -1 AND ${C_FLAG_FAILED} EQUAL -1)
|
|
||||||
unset(C_FLAG_SUPPORTED CACHE)
|
|
||||||
message("Checking C compiler flag support for: " ${c_flag})
|
|
||||||
check_c_compiler_flag("${c_flag}" C_FLAG_SUPPORTED)
|
|
||||||
if(${C_FLAG_SUPPORTED})
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${c_flag}" CACHE STRING "")
|
|
||||||
else()
|
|
||||||
set(DRACO_FAILED_C_FLAGS
|
|
||||||
"${DRACO_FAILED_C_FLAGS} ${c_flag}"
|
|
||||||
CACHE STRING "" FORCE)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Checks C++ compiler for support of $cxx_flag. Adds $cxx_flag to
|
|
||||||
# $CMAKE_CXX_FLAGS when the compile test passes. Caches $c_flag in
|
|
||||||
# $DRACO_FAILED_CXX_FLAGS when the test fails.
|
|
||||||
macro(add_cxx_flag_if_supported cxx_flag)
|
|
||||||
unset(CXX_FLAG_FOUND CACHE)
|
|
||||||
string(FIND "${CMAKE_CXX_FLAGS}" "${cxx_flag}" CXX_FLAG_FOUND)
|
|
||||||
unset(CXX_FLAG_FAILED CACHE)
|
|
||||||
string(FIND "${DRACO_FAILED_CXX_FLAGS}" "${cxx_flag}" CXX_FLAG_FAILED)
|
|
||||||
|
|
||||||
if(${CXX_FLAG_FOUND} EQUAL -1 AND ${CXX_FLAG_FAILED} EQUAL -1)
|
|
||||||
unset(CXX_FLAG_SUPPORTED CACHE)
|
|
||||||
message("Checking CXX compiler flag support for: " ${cxx_flag})
|
|
||||||
check_cxx_compiler_flag("${cxx_flag}" CXX_FLAG_SUPPORTED)
|
|
||||||
if(${CXX_FLAG_SUPPORTED})
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${cxx_flag}" CACHE STRING "")
|
|
||||||
else()
|
|
||||||
set(DRACO_FAILED_CXX_FLAGS
|
|
||||||
"${DRACO_FAILED_CXX_FLAGS} ${cxx_flag}"
|
|
||||||
CACHE STRING "" FORCE)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Convenience method for adding a flag to both the C and C++ compiler command
|
|
||||||
# lines.
|
|
||||||
macro(add_compiler_flag_if_supported flag)
|
|
||||||
add_c_flag_if_supported(${flag})
|
|
||||||
add_cxx_flag_if_supported(${flag})
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Checks C compiler for support of $c_flag and terminates generation when
|
|
||||||
# support is not present.
|
|
||||||
macro(require_c_flag c_flag update_c_flags)
|
|
||||||
unset(C_FLAG_FOUND CACHE)
|
|
||||||
string(FIND "${CMAKE_C_FLAGS}" "${c_flag}" C_FLAG_FOUND)
|
|
||||||
|
|
||||||
if(${C_FLAG_FOUND} EQUAL -1)
|
|
||||||
unset(HAVE_C_FLAG CACHE)
|
|
||||||
message("Checking C compiler flag support for: " ${c_flag})
|
|
||||||
check_c_compiler_flag("${c_flag}" HAVE_C_FLAG)
|
|
||||||
if(NOT ${HAVE_C_FLAG})
|
|
||||||
message(
|
|
||||||
FATAL_ERROR "${PROJECT_NAME} requires support for C flag: ${c_flag}.")
|
|
||||||
endif()
|
|
||||||
if(${update_c_flags})
|
|
||||||
set(CMAKE_C_FLAGS "${c_flag} ${CMAKE_C_FLAGS}" CACHE STRING "" FORCE)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Checks CXX compiler for support of $cxx_flag and terminates generation when
|
|
||||||
# support is not present.
|
|
||||||
macro(require_cxx_flag cxx_flag update_cxx_flags)
|
|
||||||
unset(CXX_FLAG_FOUND CACHE)
|
|
||||||
string(FIND "${CMAKE_CXX_FLAGS}" "${cxx_flag}" CXX_FLAG_FOUND)
|
|
||||||
|
|
||||||
if(${CXX_FLAG_FOUND} EQUAL -1)
|
|
||||||
unset(HAVE_CXX_FLAG CACHE)
|
|
||||||
message("Checking CXX compiler flag support for: " ${cxx_flag})
|
|
||||||
check_cxx_compiler_flag("${cxx_flag}" HAVE_CXX_FLAG)
|
|
||||||
if(NOT ${HAVE_CXX_FLAG})
|
|
||||||
message(
|
|
||||||
FATAL_ERROR
|
|
||||||
"${PROJECT_NAME} requires support for CXX flag: ${cxx_flag}.")
|
|
||||||
endif()
|
|
||||||
if(${update_cxx_flags})
|
|
||||||
set(CMAKE_CXX_FLAGS
|
|
||||||
"${cxx_flag} ${CMAKE_CXX_FLAGS}"
|
|
||||||
CACHE STRING "" FORCE)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Checks for support of $flag by both the C and CXX compilers. Terminates
|
|
||||||
# generation when support is not present in both compilers.
|
|
||||||
macro(require_compiler_flag flag update_cmake_flags)
|
|
||||||
require_c_flag(${flag} ${update_cmake_flags})
|
|
||||||
require_cxx_flag(${flag} ${update_cmake_flags})
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Checks only non-MSVC targets for support of $c_flag and terminates generation
|
|
||||||
# when support is not present.
|
|
||||||
macro(require_c_flag_nomsvc c_flag update_c_flags)
|
|
||||||
if(NOT MSVC)
|
|
||||||
require_c_flag(${c_flag} ${update_c_flags})
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Checks only non-MSVC targets for support of $cxx_flag and terminates
|
|
||||||
# generation when support is not present.
|
|
||||||
macro(require_cxx_flag_nomsvc cxx_flag update_cxx_flags)
|
|
||||||
if(NOT MSVC)
|
|
||||||
require_cxx_flag(${cxx_flag} ${update_cxx_flags})
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Checks only non-MSVC targets for support of $flag by both the C and CXX
|
|
||||||
# compilers. Terminates generation when support is not present in both
|
|
||||||
# compilers.
|
|
||||||
macro(require_compiler_flag_nomsvc flag update_cmake_flags)
|
|
||||||
require_c_flag_nomsvc(${flag} ${update_cmake_flags})
|
|
||||||
require_cxx_flag_nomsvc(${flag} ${update_cmake_flags})
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Adds $flag to assembler command line.
|
|
||||||
macro(append_as_flag flag)
|
|
||||||
unset(AS_FLAG_FOUND CACHE)
|
|
||||||
string(FIND "${DRACO_AS_FLAGS}" "${flag}" AS_FLAG_FOUND)
|
|
||||||
|
|
||||||
if(${AS_FLAG_FOUND} EQUAL -1)
|
|
||||||
set(DRACO_AS_FLAGS "${DRACO_AS_FLAGS} ${flag}")
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Adds $flag to the C compiler command line.
|
|
||||||
macro(append_c_flag flag)
|
|
||||||
unset(C_FLAG_FOUND CACHE)
|
|
||||||
string(FIND "${CMAKE_C_FLAGS}" "${flag}" C_FLAG_FOUND)
|
|
||||||
|
|
||||||
if(${C_FLAG_FOUND} EQUAL -1)
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Adds $flag to the CXX compiler command line.
|
|
||||||
macro(append_cxx_flag flag)
|
|
||||||
unset(CXX_FLAG_FOUND CACHE)
|
|
||||||
string(FIND "${CMAKE_CXX_FLAGS}" "${flag}" CXX_FLAG_FOUND)
|
|
||||||
|
|
||||||
if(${CXX_FLAG_FOUND} EQUAL -1)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Adds $flag to the C and CXX compiler command lines.
|
|
||||||
macro(append_compiler_flag flag)
|
|
||||||
append_c_flag(${flag})
|
|
||||||
append_cxx_flag(${flag})
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Adds $flag to the executable linker command line.
|
|
||||||
macro(append_exe_linker_flag flag)
|
|
||||||
unset(LINKER_FLAG_FOUND CACHE)
|
|
||||||
string(FIND "${CMAKE_EXE_LINKER_FLAGS}" "${flag}" LINKER_FLAG_FOUND)
|
|
||||||
|
|
||||||
if(${LINKER_FLAG_FOUND} EQUAL -1)
|
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${flag}")
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Adds $flag to the link flags for $target.
|
|
||||||
function(append_link_flag_to_target target flags)
|
|
||||||
unset(target_link_flags)
|
|
||||||
get_target_property(target_link_flags ${target} LINK_FLAGS)
|
|
||||||
|
|
||||||
if(target_link_flags)
|
|
||||||
unset(link_flag_found)
|
|
||||||
string(FIND "${target_link_flags}" "${flags}" link_flag_found)
|
|
||||||
|
|
||||||
if(NOT ${link_flag_found} EQUAL -1)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(target_link_flags "${target_link_flags} ${flags}")
|
|
||||||
else()
|
|
||||||
set(target_link_flags "${flags}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set_target_properties(${target} PROPERTIES LINK_FLAGS ${target_link_flags})
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# Adds $flag to executable linker flags, and makes sure C/CXX builds still work.
|
|
||||||
macro(require_linker_flag flag)
|
|
||||||
append_exe_linker_flag(${flag})
|
|
||||||
|
|
||||||
unset(c_passed)
|
|
||||||
draco_check_c_compiles("LINKER_FLAG_C_TEST(${flag})" "" c_passed)
|
|
||||||
unset(cxx_passed)
|
|
||||||
draco_check_cxx_compiles("LINKER_FLAG_CXX_TEST(${flag})" "" cxx_passed)
|
|
||||||
|
|
||||||
if(NOT c_passed OR NOT cxx_passed)
|
|
||||||
message(FATAL_ERROR "Linker flag test for ${flag} failed.")
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
|
@ -1,103 +0,0 @@
|
||||||
if(DRACO_CMAKE_COMPILER_TESTS_CMAKE_)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
set(DRACO_CMAKE_COMPILER_TESTS_CMAKE_ 1)
|
|
||||||
|
|
||||||
include(CheckCSourceCompiles)
|
|
||||||
include(CheckCXXSourceCompiles)
|
|
||||||
|
|
||||||
# The basic main() macro used in all compile tests.
|
|
||||||
set(DRACO_C_MAIN "\nint main(void) { return 0; }")
|
|
||||||
set(DRACO_CXX_MAIN "\nint main() { return 0; }")
|
|
||||||
|
|
||||||
# Strings containing the names of passed and failed tests.
|
|
||||||
set(DRACO_C_PASSED_TESTS)
|
|
||||||
set(DRACO_C_FAILED_TESTS)
|
|
||||||
set(DRACO_CXX_PASSED_TESTS)
|
|
||||||
set(DRACO_CXX_FAILED_TESTS)
|
|
||||||
|
|
||||||
macro(draco_push_var var new_value)
|
|
||||||
set(SAVED_${var} ${var})
|
|
||||||
set(${var} ${new_value})
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
macro(draco_pop_var var)
|
|
||||||
set(var ${SAVED_${var}})
|
|
||||||
unset(SAVED_${var})
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Confirms $test_source compiles and stores $test_name in one of
|
|
||||||
# $DRACO_C_PASSED_TESTS or $DRACO_C_FAILED_TESTS depending on out come. When the
|
|
||||||
# test passes $result_var is set to 1. When it fails $result_var is unset. The
|
|
||||||
# test is not run if the test name is found in either of the passed or failed
|
|
||||||
# test variables.
|
|
||||||
macro(draco_check_c_compiles test_name test_source result_var)
|
|
||||||
unset(C_TEST_PASSED CACHE)
|
|
||||||
unset(C_TEST_FAILED CACHE)
|
|
||||||
string(FIND "${DRACO_C_PASSED_TESTS}" "${test_name}" C_TEST_PASSED)
|
|
||||||
string(FIND "${DRACO_C_FAILED_TESTS}" "${test_name}" C_TEST_FAILED)
|
|
||||||
if(${C_TEST_PASSED} EQUAL -1 AND ${C_TEST_FAILED} EQUAL -1)
|
|
||||||
unset(C_TEST_COMPILED CACHE)
|
|
||||||
message("Running C compiler test: ${test_name}")
|
|
||||||
check_c_source_compiles("${test_source} ${DRACO_C_MAIN}" C_TEST_COMPILED)
|
|
||||||
set(${result_var} ${C_TEST_COMPILED})
|
|
||||||
|
|
||||||
if(${C_TEST_COMPILED})
|
|
||||||
set(DRACO_C_PASSED_TESTS "${DRACO_C_PASSED_TESTS} ${test_name}")
|
|
||||||
else()
|
|
||||||
set(DRACO_C_FAILED_TESTS "${DRACO_C_FAILED_TESTS} ${test_name}")
|
|
||||||
message("C Compiler test ${test_name} failed.")
|
|
||||||
endif()
|
|
||||||
elseif(NOT ${C_TEST_PASSED} EQUAL -1)
|
|
||||||
set(${result_var} 1)
|
|
||||||
else() # ${C_TEST_FAILED} NOT EQUAL -1
|
|
||||||
unset(${result_var})
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Confirms $test_source compiles and stores $test_name in one of
|
|
||||||
# $DRACO_CXX_PASSED_TESTS or $DRACO_CXX_FAILED_TESTS depending on out come. When
|
|
||||||
# the test passes $result_var is set to 1. When it fails $result_var is unset.
|
|
||||||
# The test is not run if the test name is found in either of the passed or
|
|
||||||
# failed test variables.
|
|
||||||
macro(draco_check_cxx_compiles test_name test_source result_var)
|
|
||||||
unset(CXX_TEST_PASSED CACHE)
|
|
||||||
unset(CXX_TEST_FAILED CACHE)
|
|
||||||
string(FIND "${DRACO_CXX_PASSED_TESTS}" "${test_name}" CXX_TEST_PASSED)
|
|
||||||
string(FIND "${DRACO_CXX_FAILED_TESTS}" "${test_name}" CXX_TEST_FAILED)
|
|
||||||
if(${CXX_TEST_PASSED} EQUAL -1 AND ${CXX_TEST_FAILED} EQUAL -1)
|
|
||||||
unset(CXX_TEST_COMPILED CACHE)
|
|
||||||
message("Running CXX compiler test: ${test_name}")
|
|
||||||
check_cxx_source_compiles("${test_source} ${DRACO_CXX_MAIN}"
|
|
||||||
CXX_TEST_COMPILED)
|
|
||||||
set(${result_var} ${CXX_TEST_COMPILED})
|
|
||||||
|
|
||||||
if(${CXX_TEST_COMPILED})
|
|
||||||
set(DRACO_CXX_PASSED_TESTS "${DRACO_CXX_PASSED_TESTS} ${test_name}")
|
|
||||||
else()
|
|
||||||
set(DRACO_CXX_FAILED_TESTS "${DRACO_CXX_FAILED_TESTS} ${test_name}")
|
|
||||||
message("CXX Compiler test ${test_name} failed.")
|
|
||||||
endif()
|
|
||||||
elseif(NOT ${CXX_TEST_PASSED} EQUAL -1)
|
|
||||||
set(${result_var} 1)
|
|
||||||
else() # ${CXX_TEST_FAILED} NOT EQUAL -1
|
|
||||||
unset(${result_var})
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Convenience macro that confirms $test_source compiles as C and C++.
|
|
||||||
# $result_var is set to 1 when both tests are successful, and 0 when one or both
|
|
||||||
# tests fail. Note: This macro is intended to be used to write to result
|
|
||||||
# variables that are expanded via configure_file(). $result_var is set to 1 or 0
|
|
||||||
# to allow direct usage of the value in generated source files.
|
|
||||||
macro(draco_check_source_compiles test_name test_source result_var)
|
|
||||||
unset(C_PASSED)
|
|
||||||
unset(CXX_PASSED)
|
|
||||||
draco_check_c_compiles(${test_name} ${test_source} C_PASSED)
|
|
||||||
draco_check_cxx_compiles(${test_name} ${test_source} CXX_PASSED)
|
|
||||||
if(${C_PASSED} AND ${CXX_PASSED})
|
|
||||||
set(${result_var} 1)
|
|
||||||
else()
|
|
||||||
set(${result_var} 0)
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
|
@ -1,2 +1,3 @@
|
||||||
set(DRACO_INCLUDE_DIRS "@DRACO_INCLUDE_DIRS@")
|
@PACKAGE_INIT@
|
||||||
set(DRACO_LIBRARIES "draco")
|
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/draco-targets.cmake")
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
prefix=@prefix@
|
|
||||||
exec_prefix=@exec_prefix@
|
|
||||||
libdir=@libdir@
|
|
||||||
includedir=@includedir@
|
|
||||||
|
|
||||||
Name: @PROJECT_NAME@
|
Name: @PROJECT_NAME@
|
||||||
Description: Draco geometry de(com)pression library.
|
Description: Draco geometry de(com)pression library.
|
||||||
Version: @DRACO_VERSION@
|
Version: @DRACO_VERSION@
|
||||||
Cflags: -I${includedir}
|
Cflags: -I@includes_path@
|
||||||
Libs: -L${libdir} -ldraco
|
Libs: -L@libs_path@ -ldraco
|
||||||
Libs.private: @CMAKE_THREAD_LIBS_INIT@
|
Libs.private: @CMAKE_THREAD_LIBS_INIT@
|
||||||
|
|
|
@ -1,3 +1,17 @@
|
||||||
|
# Copyright 2021 The Draco Authors
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
# use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
# the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations under
|
||||||
|
# the License.
|
||||||
|
|
||||||
if(DRACO_CMAKE_DRACO_BUILD_DEFINITIONS_CMAKE_)
|
if(DRACO_CMAKE_DRACO_BUILD_DEFINITIONS_CMAKE_)
|
||||||
return()
|
return()
|
||||||
endif() # DRACO_CMAKE_DRACO_BUILD_DEFINITIONS_CMAKE_
|
endif() # DRACO_CMAKE_DRACO_BUILD_DEFINITIONS_CMAKE_
|
||||||
|
@ -17,10 +31,6 @@ macro(set_draco_target)
|
||||||
endif()
|
endif()
|
||||||
set(draco_plugin_dependency draco_static)
|
set(draco_plugin_dependency draco_static)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(BUILD_SHARED_LIBS)
|
|
||||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
|
||||||
endif()
|
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
# Configures flags and sets build system globals.
|
# Configures flags and sets build system globals.
|
||||||
|
@ -36,23 +46,37 @@ macro(draco_set_build_definitions)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
draco_load_version_info()
|
draco_load_version_info()
|
||||||
set(DRACO_SOVERSION 1)
|
|
||||||
|
# Library version info. See the libtool docs for updating the values:
|
||||||
|
# https://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info
|
||||||
|
#
|
||||||
|
# c=<current>, r=<revision>, a=<age>
|
||||||
|
#
|
||||||
|
# libtool generates a .so file as .so.[c-a].a.r, while -version-info c:r:a is
|
||||||
|
# passed to libtool.
|
||||||
|
#
|
||||||
|
# We set DRACO_SOVERSION = [c-a].a.r
|
||||||
|
set(LT_CURRENT 8)
|
||||||
|
set(LT_REVISION 0)
|
||||||
|
set(LT_AGE 0)
|
||||||
|
math(EXPR DRACO_SOVERSION_MAJOR "${LT_CURRENT} - ${LT_AGE}")
|
||||||
|
set(DRACO_SOVERSION "${DRACO_SOVERSION_MAJOR}.${LT_AGE}.${LT_REVISION}")
|
||||||
|
unset(LT_CURRENT)
|
||||||
|
unset(LT_REVISION)
|
||||||
|
unset(LT_AGE)
|
||||||
|
|
||||||
list(APPEND draco_include_paths "${draco_root}" "${draco_root}/src"
|
list(APPEND draco_include_paths "${draco_root}" "${draco_root}/src"
|
||||||
"${draco_build}")
|
"${draco_build}")
|
||||||
|
|
||||||
if(DRACO_ABSL)
|
if(DRACO_TRANSCODER_SUPPORTED)
|
||||||
list(APPEND draco_include_path "${draco_root}/third_party/abseil-cpp")
|
draco_setup_eigen()
|
||||||
|
draco_setup_filesystem()
|
||||||
|
draco_setup_tinygltf()
|
||||||
|
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
list(APPEND draco_gtest_include_paths
|
|
||||||
"${draco_root}/../googletest/googlemock/include"
|
|
||||||
"${draco_root}/../googletest/googlemock"
|
|
||||||
"${draco_root}/../googletest/googletest/include"
|
|
||||||
"${draco_root}/../googletest/googletest")
|
|
||||||
list(APPEND draco_test_include_paths ${draco_include_paths}
|
|
||||||
${draco_gtest_include_paths})
|
|
||||||
list(APPEND draco_defines "DRACO_CMAKE=1"
|
list(APPEND draco_defines "DRACO_CMAKE=1"
|
||||||
"DRACO_FLAGS_SRCDIR=\"${draco_root}\""
|
"DRACO_FLAGS_SRCDIR=\"${draco_root}\""
|
||||||
"DRACO_FLAGS_TMPDIR=\"/tmp\"")
|
"DRACO_FLAGS_TMPDIR=\"/tmp\"")
|
||||||
|
@ -63,11 +87,22 @@ macro(draco_set_build_definitions)
|
||||||
if(BUILD_SHARED_LIBS)
|
if(BUILD_SHARED_LIBS)
|
||||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
|
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
|
||||||
endif()
|
endif()
|
||||||
else()
|
endif()
|
||||||
|
|
||||||
|
if(NOT MSVC)
|
||||||
if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
|
if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
|
||||||
# Ensure 64-bit platforms can support large files.
|
# Ensure 64-bit platforms can support large files.
|
||||||
list(APPEND draco_defines "_LARGEFILE_SOURCE" "_FILE_OFFSET_BITS=64")
|
list(APPEND draco_defines "_LARGEFILE_SOURCE" "_FILE_OFFSET_BITS=64")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(NOT DRACO_DEBUG_COMPILER_WARNINGS)
|
||||||
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
|
list(APPEND draco_clang_cxx_flags
|
||||||
|
"-Wno-implicit-const-int-float-conversion")
|
||||||
|
else()
|
||||||
|
list(APPEND draco_base_cxx_flags "-Wno-deprecated-declarations")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(ANDROID)
|
if(ANDROID)
|
||||||
|
@ -102,13 +137,9 @@ macro(draco_set_build_definitions)
|
||||||
set(draco_neon_source_file_suffix "neon.cc")
|
set(draco_neon_source_file_suffix "neon.cc")
|
||||||
set(draco_sse4_source_file_suffix "sse4.cc")
|
set(draco_sse4_source_file_suffix "sse4.cc")
|
||||||
|
|
||||||
if((${CMAKE_CXX_COMPILER_ID}
|
if((${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" AND ${CMAKE_CXX_COMPILER_VERSION}
|
||||||
STREQUAL
|
VERSION_LESS 5)
|
||||||
"GNU"
|
OR (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang"
|
||||||
AND ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 5)
|
|
||||||
OR (${CMAKE_CXX_COMPILER_ID}
|
|
||||||
STREQUAL
|
|
||||||
"Clang"
|
|
||||||
AND ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 4))
|
AND ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 4))
|
||||||
message(
|
message(
|
||||||
WARNING "GNU/GCC < v5 or Clang/LLVM < v4, ENABLING COMPATIBILITY MODE.")
|
WARNING "GNU/GCC < v5 or Clang/LLVM < v4, ENABLING COMPATIBILITY MODE.")
|
||||||
|
@ -117,7 +148,9 @@ macro(draco_set_build_definitions)
|
||||||
|
|
||||||
if(EMSCRIPTEN)
|
if(EMSCRIPTEN)
|
||||||
draco_check_emscripten_environment()
|
draco_check_emscripten_environment()
|
||||||
draco_get_required_emscripten_flags(FLAG_LIST_VAR draco_base_cxx_flags)
|
draco_get_required_emscripten_flags(
|
||||||
|
FLAG_LIST_VAR_COMPILER draco_base_cxx_flags
|
||||||
|
FLAG_LIST_VAR_LINKER draco_base_exe_linker_flags)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
draco_configure_sanitizer()
|
draco_configure_sanitizer()
|
||||||
|
|
|
@ -1,3 +1,17 @@
|
||||||
|
# Copyright 2021 The Draco Authors
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
# use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
# the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations under
|
||||||
|
# the License.
|
||||||
|
|
||||||
if(DRACO_CMAKE_DRACO_CPU_DETECTION_CMAKE_)
|
if(DRACO_CMAKE_DRACO_CPU_DETECTION_CMAKE_)
|
||||||
return()
|
return()
|
||||||
endif() # DRACO_CMAKE_DRACO_CPU_DETECTION_CMAKE_
|
endif() # DRACO_CMAKE_DRACO_CPU_DETECTION_CMAKE_
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
# Copyright 2022 The Draco Authors
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
# use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
# the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations under
|
||||||
|
# the License.
|
||||||
|
|
||||||
|
if(DRACO_CMAKE_DRACO_DEPENDENCIES_CMAKE)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
set(DRACO_CMAKE_DRACO_DEPENDENCIES_CMAKE 1)
|
||||||
|
|
||||||
|
include("${draco_root}/cmake/draco_variables.cmake")
|
||||||
|
|
||||||
|
# Each variable holds a user specified custom path to a local copy of the
|
||||||
|
# sources that belong to each project that Draco depends on. When paths are
|
||||||
|
# empty the build will be generated pointing to the Draco git submodules.
|
||||||
|
# Otherwise the paths specified by the user will be used in the build
|
||||||
|
# configuration.
|
||||||
|
|
||||||
|
# Path to the Eigen. The path must contain the Eigen directory.
|
||||||
|
set(DRACO_EIGEN_PATH)
|
||||||
|
draco_track_configuration_variable(DRACO_EIGEN_PATH)
|
||||||
|
|
||||||
|
# Path to the gulrak/filesystem installation. The path specified must contain
|
||||||
|
# the ghc subdirectory that houses the filesystem includes.
|
||||||
|
set(DRACO_FILESYSTEM_PATH)
|
||||||
|
draco_track_configuration_variable(DRACO_FILESYSTEM_PATH)
|
||||||
|
|
||||||
|
# Path to the googletest installation. The path must be to the root of the
|
||||||
|
# Googletest project directory.
|
||||||
|
set(DRACO_GOOGLETEST_PATH)
|
||||||
|
draco_track_configuration_variable(DRACO_GOOGLETEST_PATH)
|
||||||
|
|
||||||
|
# Path to the syoyo/tinygltf installation. The path must be to the root of the
|
||||||
|
# project directory.
|
||||||
|
set(DRACO_TINYGLTF_PATH)
|
||||||
|
draco_track_configuration_variable(DRACO_TINYGLTF_PATH)
|
||||||
|
|
||||||
|
# Utility macro for killing the build due to a missing submodule directory.
|
||||||
|
macro(draco_die_missing_submodule dir)
|
||||||
|
message(FATAL_ERROR "${dir} missing, run git submodule update --init")
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
# Determines the Eigen location and updates the build configuration accordingly.
|
||||||
|
macro(draco_setup_eigen)
|
||||||
|
if(DRACO_EIGEN_PATH)
|
||||||
|
set(eigen_path "${DRACO_EIGEN_PATH}")
|
||||||
|
|
||||||
|
if(NOT IS_DIRECTORY "${eigen_path}")
|
||||||
|
message(FATAL_ERROR "DRACO_EIGEN_PATH does not exist.")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(eigen_path "${draco_root}/third_party/eigen")
|
||||||
|
|
||||||
|
if(NOT IS_DIRECTORY "${eigen_path}")
|
||||||
|
draco_die_missing_submodule("${eigen_path}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(eigen_include_path "${eigen_path}/Eigen")
|
||||||
|
|
||||||
|
if(NOT EXISTS "${eigen_path}/Eigen")
|
||||||
|
message(FATAL_ERROR "The eigen path does not contain an Eigen directory.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
list(APPEND draco_include_paths "${eigen_path}")
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
# Determines the gulrak/filesystem location and updates the build configuration
|
||||||
|
# accordingly.
|
||||||
|
macro(draco_setup_filesystem)
|
||||||
|
if(DRACO_FILESYSTEM_PATH)
|
||||||
|
set(fs_path "${DRACO_FILESYSTEM_PATH}")
|
||||||
|
|
||||||
|
if(NOT IS_DIRECTORY "${fs_path}")
|
||||||
|
message(FATAL_ERROR "DRACO_FILESYSTEM_PATH does not exist.")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(fs_path "${draco_root}/third_party/filesystem/include")
|
||||||
|
|
||||||
|
if(NOT IS_DIRECTORY "${fs_path}")
|
||||||
|
draco_die_missing_submodule("${fs_path}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
list(APPEND draco_include_paths "${fs_path}")
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
# Determines the Googletest location and sets up include and source list vars
|
||||||
|
# for the draco_tests build.
|
||||||
|
macro(draco_setup_googletest)
|
||||||
|
if(DRACO_GOOGLETEST_PATH)
|
||||||
|
set(gtest_path "${DRACO_GOOGLETEST_PATH}")
|
||||||
|
if(NOT IS_DIRECTORY "${gtest_path}")
|
||||||
|
message(FATAL_ERROR "DRACO_GOOGLETEST_PATH does not exist.")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(gtest_path "${draco_root}/third_party/googletest")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
list(APPEND draco_test_include_paths ${draco_include_paths}
|
||||||
|
"${gtest_path}/include" "${gtest_path}/googlemock"
|
||||||
|
"${gtest_path}/googletest/include" "${gtest_path}/googletest")
|
||||||
|
|
||||||
|
list(APPEND draco_gtest_all "${gtest_path}/googletest/src/gtest-all.cc")
|
||||||
|
list(APPEND draco_gtest_main "${gtest_path}/googletest/src/gtest_main.cc")
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
|
||||||
|
# Determines the location of TinyGLTF and updates the build configuration
|
||||||
|
# accordingly.
|
||||||
|
macro(draco_setup_tinygltf)
|
||||||
|
if(DRACO_TINYGLTF_PATH)
|
||||||
|
set(tinygltf_path "${DRACO_TINYGLTF_PATH}")
|
||||||
|
|
||||||
|
if(NOT IS_DIRECTORY "${tinygltf_path}")
|
||||||
|
message(FATAL_ERROR "DRACO_TINYGLTF_PATH does not exist.")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(tinygltf_path "${draco_root}/third_party/tinygltf")
|
||||||
|
|
||||||
|
if(NOT IS_DIRECTORY "${tinygltf_path}")
|
||||||
|
draco_die_missing_submodule("${tinygltf_path}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
list(APPEND draco_include_paths "${tinygltf_path}")
|
||||||
|
endmacro()
|
|
@ -1,3 +1,17 @@
|
||||||
|
# Copyright 2021 The Draco Authors
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
# use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
# the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations under
|
||||||
|
# the License.
|
||||||
|
|
||||||
if(DRACO_CMAKE_DRACO_EMSCRIPTEN_CMAKE_)
|
if(DRACO_CMAKE_DRACO_EMSCRIPTEN_CMAKE_)
|
||||||
return()
|
return()
|
||||||
endif() # DRACO_CMAKE_DRACO_EMSCRIPTEN_CMAKE_
|
endif() # DRACO_CMAKE_DRACO_EMSCRIPTEN_CMAKE_
|
||||||
|
@ -18,39 +32,64 @@ endmacro()
|
||||||
|
|
||||||
# Obtains the required Emscripten flags for Draco targets.
|
# Obtains the required Emscripten flags for Draco targets.
|
||||||
macro(draco_get_required_emscripten_flags)
|
macro(draco_get_required_emscripten_flags)
|
||||||
set(em_FLAG_LIST_VAR)
|
set(em_FLAG_LIST_VAR_COMPILER)
|
||||||
|
set(em_FLAG_LIST_VAR_LINKER)
|
||||||
set(em_flags)
|
set(em_flags)
|
||||||
set(em_single_arg_opts FLAG_LIST_VAR)
|
set(em_single_arg_opts FLAG_LIST_VAR_COMPILER FLAG_LIST_VAR_LINKER)
|
||||||
set(em_multi_arg_opts)
|
set(em_multi_arg_opts)
|
||||||
cmake_parse_arguments(em "${em_flags}" "${em_single_arg_opts}"
|
cmake_parse_arguments(em "${em_flags}" "${em_single_arg_opts}"
|
||||||
"${em_multi_arg_opts}" ${ARGN})
|
"${em_multi_arg_opts}" ${ARGN})
|
||||||
if(NOT em_FLAG_LIST_VAR)
|
if(NOT em_FLAG_LIST_VAR_COMPILER)
|
||||||
message(FATAL "draco_get_required_emscripten_flags: FLAG_LIST_VAR required")
|
message(
|
||||||
|
FATAL
|
||||||
|
"draco_get_required_emscripten_flags: FLAG_LIST_VAR_COMPILER required")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT em_FLAG_LIST_VAR_LINKER)
|
||||||
|
message(
|
||||||
|
FATAL
|
||||||
|
"draco_get_required_emscripten_flags: FLAG_LIST_VAR_LINKER required")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(DRACO_JS_GLUE)
|
if(DRACO_JS_GLUE)
|
||||||
unset(required_flags)
|
unset(required_flags)
|
||||||
list(APPEND ${em_FLAG_LIST_VAR} "-sALLOW_MEMORY_GROWTH=1")
|
# TODO(tomfinegan): Revisit splitting of compile/link flags for Emscripten,
|
||||||
list(APPEND ${em_FLAG_LIST_VAR} "-Wno-almost-asm")
|
# and drop -Wno-unused-command-line-argument. Emscripten complains about
|
||||||
list(APPEND ${em_FLAG_LIST_VAR} "--memory-init-file" "0")
|
# what are supposedly link-only flags sent with compile commands, but then
|
||||||
list(APPEND ${em_FLAG_LIST_VAR} "-fno-omit-frame-pointer")
|
# proceeds to produce broken code if the warnings are heeded.
|
||||||
list(APPEND ${em_FLAG_LIST_VAR} "-sMODULARIZE=1")
|
list(APPEND ${em_FLAG_LIST_VAR_COMPILER}
|
||||||
list(APPEND ${em_FLAG_LIST_VAR} "-sNO_FILESYSTEM=1")
|
"-Wno-unused-command-line-argument")
|
||||||
list(APPEND ${em_FLAG_LIST_VAR} "-sEXPORTED_RUNTIME_METHODS=[]")
|
|
||||||
list(APPEND ${em_FLAG_LIST_VAR} "-sPRECISE_F32=1")
|
list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "-Wno-almost-asm")
|
||||||
list(APPEND ${em_FLAG_LIST_VAR} "-sNODEJS_CATCH_EXIT=0")
|
list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "--memory-init-file" "0")
|
||||||
list(APPEND ${em_FLAG_LIST_VAR} "-sNODEJS_CATCH_REJECTION=0")
|
list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "-fno-omit-frame-pointer")
|
||||||
|
|
||||||
|
# According to Emscripten the following flags are linker only, but sending
|
||||||
|
# these flags (en masse) to only the linker results in a broken Emscripten
|
||||||
|
# build with an empty DracoDecoderModule.
|
||||||
|
list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "-sALLOW_MEMORY_GROWTH=1")
|
||||||
|
list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "-sMODULARIZE=1")
|
||||||
|
list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "-sFILESYSTEM=0")
|
||||||
|
list(APPEND ${em_FLAG_LIST_VAR_COMPILER}
|
||||||
|
"-sEXPORTED_FUNCTIONS=[\"_free\",\"_malloc\"]")
|
||||||
|
list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "-sPRECISE_F32=1")
|
||||||
|
list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "-sNODEJS_CATCH_EXIT=0")
|
||||||
|
list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "-sNODEJS_CATCH_REJECTION=0")
|
||||||
|
|
||||||
if(DRACO_FAST)
|
if(DRACO_FAST)
|
||||||
list(APPEND ${em_FLAG_LIST_VAR} "--llvm-lto" "1")
|
list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "--llvm-lto" "1")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# The WASM flag is reported as linker only.
|
||||||
if(DRACO_WASM)
|
if(DRACO_WASM)
|
||||||
list(APPEND ${em_FLAG_LIST_VAR} "-sWASM=1")
|
list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "-sWASM=1")
|
||||||
else()
|
else()
|
||||||
list(APPEND ${em_FLAG_LIST_VAR} "-sWASM=0")
|
list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "-sWASM=0")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# The LEGACY_VM_SUPPORT flag is reported as linker only.
|
||||||
if(DRACO_IE_COMPATIBLE)
|
if(DRACO_IE_COMPATIBLE)
|
||||||
list(APPEND ${em_FLAG_LIST_VAR} "-sLEGACY_VM_SUPPORT=1")
|
list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "-sLEGACY_VM_SUPPORT=1")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endmacro()
|
endmacro()
|
||||||
|
@ -66,9 +105,10 @@ macro(draco_generate_emscripten_glue)
|
||||||
"${glue_multi_arg_opts}" ${ARGN})
|
"${glue_multi_arg_opts}" ${ARGN})
|
||||||
|
|
||||||
if(DRACO_VERBOSE GREATER 1)
|
if(DRACO_VERBOSE GREATER 1)
|
||||||
message("--------- draco_generate_emscripten_glue -----------\n"
|
message(
|
||||||
|
"--------- draco_generate_emscripten_glue -----------\n"
|
||||||
"glue_INPUT_IDL=${glue_INPUT_IDL}\n"
|
"glue_INPUT_IDL=${glue_INPUT_IDL}\n"
|
||||||
"glue_OUTPUT_PATH=${glue_OUTPUT_PATH}\n" ]
|
"glue_OUTPUT_PATH=${glue_OUTPUT_PATH}\n"
|
||||||
"----------------------------------------------------\n")
|
"----------------------------------------------------\n")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -79,17 +119,17 @@ macro(draco_generate_emscripten_glue)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Generate the glue source.
|
# Generate the glue source.
|
||||||
execute_process(COMMAND ${PYTHON_EXECUTABLE}
|
execute_process(
|
||||||
$ENV{EMSCRIPTEN}/tools/webidl_binder.py
|
COMMAND ${PYTHON_EXECUTABLE} $ENV{EMSCRIPTEN}/tools/webidl_binder.py
|
||||||
${glue_INPUT_IDL} ${glue_OUTPUT_PATH})
|
${glue_INPUT_IDL} ${glue_OUTPUT_PATH})
|
||||||
if(NOT EXISTS "${glue_OUTPUT_PATH}.cpp")
|
if(NOT EXISTS "${glue_OUTPUT_PATH}.cpp")
|
||||||
message(FATAL_ERROR "JS glue generation failed for ${glue_INPUT_IDL}.")
|
message(FATAL_ERROR "JS glue generation failed for ${glue_INPUT_IDL}.")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Create a dependency so that it regenerated on edits.
|
# Create a dependency so that it regenerated on edits.
|
||||||
add_custom_command(OUTPUT "${glue_OUTPUT_PATH}.cpp"
|
add_custom_command(
|
||||||
COMMAND ${PYTHON_EXECUTABLE}
|
OUTPUT "${glue_OUTPUT_PATH}.cpp"
|
||||||
$ENV{EMSCRIPTEN}/tools/webidl_binder.py
|
COMMAND ${PYTHON_EXECUTABLE} $ENV{EMSCRIPTEN}/tools/webidl_binder.py
|
||||||
${glue_INPUT_IDL} ${glue_OUTPUT_PATH}
|
${glue_INPUT_IDL} ${glue_OUTPUT_PATH}
|
||||||
DEPENDS ${draco_js_dec_idl}
|
DEPENDS ${draco_js_dec_idl}
|
||||||
COMMENT "Generating ${glue_OUTPUT_PATH}.cpp."
|
COMMENT "Generating ${glue_OUTPUT_PATH}.cpp."
|
||||||
|
@ -120,8 +160,14 @@ macro(draco_add_emscripten_executable)
|
||||||
unset(emexe_LINK_FLAGS)
|
unset(emexe_LINK_FLAGS)
|
||||||
set(optional_args)
|
set(optional_args)
|
||||||
set(single_value_args NAME GLUE_PATH)
|
set(single_value_args NAME GLUE_PATH)
|
||||||
set(multi_value_args SOURCES DEFINES FEATURES INCLUDES LINK_FLAGS
|
set(multi_value_args
|
||||||
PRE_LINK_JS_SOURCES POST_LINK_JS_SOURCES)
|
SOURCES
|
||||||
|
DEFINES
|
||||||
|
FEATURES
|
||||||
|
INCLUDES
|
||||||
|
LINK_FLAGS
|
||||||
|
PRE_LINK_JS_SOURCES
|
||||||
|
POST_LINK_JS_SOURCES)
|
||||||
|
|
||||||
cmake_parse_arguments(emexe "${optional_args}" "${single_value_args}"
|
cmake_parse_arguments(emexe "${optional_args}" "${single_value_args}"
|
||||||
"${multi_value_args}" ${ARGN})
|
"${multi_value_args}" ${ARGN})
|
||||||
|
@ -136,7 +182,8 @@ macro(draco_add_emscripten_executable)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(DRACO_VERBOSE GREATER 1)
|
if(DRACO_VERBOSE GREATER 1)
|
||||||
message("--------- draco_add_emscripten_executable ---------\n"
|
message(
|
||||||
|
"--------- draco_add_emscripten_executable ---------\n"
|
||||||
"emexe_NAME=${emexe_NAME}\n"
|
"emexe_NAME=${emexe_NAME}\n"
|
||||||
"emexe_SOURCES=${emexe_SOURCES}\n"
|
"emexe_SOURCES=${emexe_SOURCES}\n"
|
||||||
"emexe_DEFINES=${emexe_DEFINES}\n"
|
"emexe_DEFINES=${emexe_DEFINES}\n"
|
||||||
|
@ -153,30 +200,30 @@ macro(draco_add_emscripten_executable)
|
||||||
# passed in with the target.
|
# passed in with the target.
|
||||||
list(APPEND emexe_LINK_FLAGS ${DRACO_CXX_FLAGS})
|
list(APPEND emexe_LINK_FLAGS ${DRACO_CXX_FLAGS})
|
||||||
|
|
||||||
if(DRACO_GLTF)
|
if(DRACO_GLTF_BITSTREAM)
|
||||||
draco_add_executable(NAME
|
# Add "_gltf" suffix to target output name.
|
||||||
${emexe_NAME}
|
draco_add_executable(
|
||||||
OUTPUT_NAME
|
NAME ${emexe_NAME}
|
||||||
${emexe_NAME}_gltf
|
OUTPUT_NAME ${emexe_NAME}_gltf
|
||||||
SOURCES
|
SOURCES ${emexe_SOURCES}
|
||||||
${emexe_SOURCES}
|
DEFINES ${emexe_DEFINES}
|
||||||
DEFINES
|
INCLUDES ${emexe_INCLUDES}
|
||||||
${emexe_DEFINES}
|
LINK_FLAGS ${emexe_LINK_FLAGS})
|
||||||
INCLUDES
|
|
||||||
${emexe_INCLUDES}
|
|
||||||
LINK_FLAGS
|
|
||||||
${emexe_LINK_FLAGS})
|
|
||||||
else()
|
else()
|
||||||
draco_add_executable(NAME ${emexe_NAME} SOURCES ${emexe_SOURCES} DEFINES
|
draco_add_executable(
|
||||||
${emexe_DEFINES} INCLUDES ${emexe_INCLUDES} LINK_FLAGS
|
NAME ${emexe_NAME}
|
||||||
${emexe_LINK_FLAGS})
|
SOURCES ${emexe_SOURCES}
|
||||||
|
DEFINES ${emexe_DEFINES}
|
||||||
|
INCLUDES ${emexe_INCLUDES}
|
||||||
|
LINK_FLAGS ${emexe_LINK_FLAGS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
foreach(feature ${emexe_FEATURES})
|
foreach(feature ${emexe_FEATURES})
|
||||||
draco_enable_feature(FEATURE ${feature} TARGETS ${emexe_NAME})
|
draco_enable_feature(FEATURE ${feature} TARGETS ${emexe_NAME})
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
set_property(SOURCE ${emexe_SOURCES}
|
set_property(
|
||||||
|
SOURCE ${emexe_SOURCES}
|
||||||
APPEND
|
APPEND
|
||||||
PROPERTY OBJECT_DEPENDS "${emexe_GLUE_PATH}.cpp")
|
PROPERTY OBJECT_DEPENDS "${emexe_GLUE_PATH}.cpp")
|
||||||
em_link_pre_js(${emexe_NAME} ${emexe_PRE_LINK_JS_SOURCES})
|
em_link_pre_js(${emexe_NAME} ${emexe_PRE_LINK_JS_SOURCES})
|
||||||
|
|
|
@ -1,3 +1,17 @@
|
||||||
|
# Copyright 2021 The Draco Authors
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
# use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
# the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations under
|
||||||
|
# the License.
|
||||||
|
|
||||||
if(DRACO_CMAKE_DRACO_FLAGS_CMAKE_)
|
if(DRACO_CMAKE_DRACO_FLAGS_CMAKE_)
|
||||||
return()
|
return()
|
||||||
endif() # DRACO_CMAKE_DRACO_FLAGS_CMAKE_
|
endif() # DRACO_CMAKE_DRACO_FLAGS_CMAKE_
|
||||||
|
@ -85,8 +99,8 @@ macro(draco_test_cxx_flag)
|
||||||
# are passed as a list it will remove the list separators, and attempt to run
|
# are passed as a list it will remove the list separators, and attempt to run
|
||||||
# a compile command using list entries concatenated together as a single
|
# a compile command using list entries concatenated together as a single
|
||||||
# argument. Avoid the problem by forcing the argument to be a string.
|
# argument. Avoid the problem by forcing the argument to be a string.
|
||||||
draco_set_and_stringify(SOURCE_VARS all_cxx_flags DEST all_cxx_flags)
|
draco_set_and_stringify(SOURCE_VARS all_cxx_flags DEST all_cxx_flags_string)
|
||||||
check_cxx_compiler_flag("${all_cxx_flags}" draco_all_cxx_flags_pass)
|
check_cxx_compiler_flag("${all_cxx_flags_string}" draco_all_cxx_flags_pass)
|
||||||
|
|
||||||
if(cxx_test_FLAG_REQUIRED AND NOT draco_all_cxx_flags_pass)
|
if(cxx_test_FLAG_REQUIRED AND NOT draco_all_cxx_flags_pass)
|
||||||
draco_die("Flag test failed for required flag(s): "
|
draco_die("Flag test failed for required flag(s): "
|
||||||
|
@ -245,3 +259,34 @@ macro(draco_set_cxx_flags)
|
||||||
draco_test_cxx_flag(FLAG_LIST_VAR_NAMES ${cxx_flag_lists})
|
draco_test_cxx_flag(FLAG_LIST_VAR_NAMES ${cxx_flag_lists})
|
||||||
endif()
|
endif()
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
|
# Collects Draco built-in and user-specified linker flags and tests them. Halts
|
||||||
|
# configuration and reports the error when any flags cause the build to fail.
|
||||||
|
#
|
||||||
|
# Note: draco_test_exe_linker_flag() does the real work of setting the flags and
|
||||||
|
# running the test compile commands.
|
||||||
|
macro(draco_set_exe_linker_flags)
|
||||||
|
unset(linker_flag_lists)
|
||||||
|
|
||||||
|
if(DRACO_VERBOSE)
|
||||||
|
message("draco_set_exe_linker_flags: "
|
||||||
|
"draco_base_exe_linker_flags=${draco_base_exe_linker_flags}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(draco_base_exe_linker_flags)
|
||||||
|
list(APPEND linker_flag_lists draco_base_exe_linker_flags)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(linker_flag_lists)
|
||||||
|
unset(test_linker_flags)
|
||||||
|
|
||||||
|
if(DRACO_VERBOSE)
|
||||||
|
message("draco_set_exe_linker_flags: "
|
||||||
|
"linker_flag_lists=${linker_flag_lists}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
draco_set_and_stringify(DEST test_linker_flags SOURCE_VARS
|
||||||
|
${linker_flag_lists})
|
||||||
|
draco_test_exe_linker_flag(FLAG_LIST_VAR_NAME test_linker_flags)
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
|
@ -1,3 +1,17 @@
|
||||||
|
# Copyright 2021 The Draco Authors
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
# use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
# the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations under
|
||||||
|
# the License.
|
||||||
|
|
||||||
if(DRACO_CMAKE_DRACO_HELPERS_CMAKE_)
|
if(DRACO_CMAKE_DRACO_HELPERS_CMAKE_)
|
||||||
return()
|
return()
|
||||||
endif() # DRACO_CMAKE_DRACO_HELPERS_CMAKE_
|
endif() # DRACO_CMAKE_DRACO_HELPERS_CMAKE_
|
||||||
|
|
|
@ -1,32 +1,32 @@
|
||||||
|
# Copyright 2021 The Draco Authors
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
# use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
# the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations under
|
||||||
|
# the License.
|
||||||
|
|
||||||
if(DRACO_CMAKE_DRACO_INSTALL_CMAKE_)
|
if(DRACO_CMAKE_DRACO_INSTALL_CMAKE_)
|
||||||
return()
|
return()
|
||||||
endif() # DRACO_CMAKE_DRACO_INSTALL_CMAKE_
|
endif() # DRACO_CMAKE_DRACO_INSTALL_CMAKE_
|
||||||
set(DRACO_CMAKE_DRACO_INSTALL_CMAKE_ 1)
|
set(DRACO_CMAKE_DRACO_INSTALL_CMAKE_ 1)
|
||||||
|
|
||||||
|
include(CMakePackageConfigHelpers)
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
# Sets up the draco install targets. Must be called after the static library
|
# Sets up the draco install targets. Must be called after the static library
|
||||||
# target is created.
|
# target is created.
|
||||||
macro(draco_setup_install_target)
|
macro(draco_setup_install_target)
|
||||||
include(GNUInstallDirs)
|
set(bin_path "${CMAKE_INSTALL_BINDIR}")
|
||||||
|
set(data_path "${CMAKE_INSTALL_DATAROOTDIR}")
|
||||||
# pkg-config: draco.pc
|
set(includes_path "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||||
set(prefix "${CMAKE_INSTALL_PREFIX}")
|
set(libs_path "${CMAKE_INSTALL_LIBDIR}")
|
||||||
set(exec_prefix "\${prefix}")
|
|
||||||
set(libdir "\${prefix}/${CMAKE_INSTALL_LIBDIR}")
|
|
||||||
set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
|
|
||||||
set(draco_lib_name "draco")
|
|
||||||
|
|
||||||
configure_file("${draco_root}/cmake/draco.pc.template"
|
|
||||||
"${draco_build}/draco.pc" @ONLY NEWLINE_STYLE UNIX)
|
|
||||||
install(FILES "${draco_build}/draco.pc"
|
|
||||||
DESTINATION "${prefix}/${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
|
||||||
|
|
||||||
# CMake config: draco-config.cmake
|
|
||||||
set(DRACO_INCLUDE_DIRS "${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
|
|
||||||
configure_file("${draco_root}/cmake/draco-config.cmake.template"
|
|
||||||
"${draco_build}/draco-config.cmake" @ONLY NEWLINE_STYLE UNIX)
|
|
||||||
install(
|
|
||||||
FILES "${draco_build}/draco-config.cmake"
|
|
||||||
DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/cmake")
|
|
||||||
|
|
||||||
foreach(file ${draco_sources})
|
foreach(file ${draco_sources})
|
||||||
if(file MATCHES "h$")
|
if(file MATCHES "h$")
|
||||||
|
@ -34,46 +34,88 @@ macro(draco_setup_install_target)
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
list(REMOVE_DUPLICATES draco_api_includes)
|
||||||
|
|
||||||
# Strip $draco_src_root from the file paths: we need to install relative to
|
# Strip $draco_src_root from the file paths: we need to install relative to
|
||||||
# $include_directory.
|
# $include_directory.
|
||||||
list(TRANSFORM draco_api_includes REPLACE "${draco_src_root}/" "")
|
list(TRANSFORM draco_api_includes REPLACE "${draco_src_root}/" "")
|
||||||
set(include_directory "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}")
|
|
||||||
|
|
||||||
foreach(draco_api_include ${draco_api_includes})
|
foreach(draco_api_include ${draco_api_includes})
|
||||||
get_filename_component(file_directory ${draco_api_include} DIRECTORY)
|
get_filename_component(file_directory ${draco_api_include} DIRECTORY)
|
||||||
set(target_directory "${include_directory}/draco/${file_directory}")
|
set(target_directory "${includes_path}/draco/${file_directory}")
|
||||||
install(FILES ${draco_src_root}/${draco_api_include}
|
install(FILES ${draco_src_root}/${draco_api_include}
|
||||||
DESTINATION "${target_directory}")
|
DESTINATION "${target_directory}")
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
install(
|
install(FILES "${draco_build}/draco/draco_features.h"
|
||||||
FILES "${draco_build}/draco/draco_features.h"
|
DESTINATION "${includes_path}/draco/")
|
||||||
DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/draco/")
|
|
||||||
|
|
||||||
install(TARGETS draco_decoder DESTINATION
|
install(TARGETS draco_decoder DESTINATION "${bin_path}")
|
||||||
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}")
|
install(TARGETS draco_encoder DESTINATION "${bin_path}")
|
||||||
install(TARGETS draco_encoder DESTINATION
|
|
||||||
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}")
|
if(DRACO_TRANSCODER_SUPPORTED)
|
||||||
|
install(TARGETS draco_transcoder DESTINATION "${bin_path}")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
install(TARGETS draco DESTINATION
|
install(
|
||||||
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
|
TARGETS draco
|
||||||
|
EXPORT dracoExport
|
||||||
|
RUNTIME DESTINATION "${bin_path}"
|
||||||
|
ARCHIVE DESTINATION "${libs_path}"
|
||||||
|
LIBRARY DESTINATION "${libs_path}")
|
||||||
else()
|
else()
|
||||||
install(TARGETS draco_static DESTINATION
|
install(
|
||||||
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
|
TARGETS draco_static
|
||||||
|
EXPORT dracoExport
|
||||||
|
DESTINATION "${libs_path}")
|
||||||
|
|
||||||
if(BUILD_SHARED_LIBS)
|
if(BUILD_SHARED_LIBS)
|
||||||
install(TARGETS draco_shared DESTINATION
|
install(
|
||||||
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
|
TARGETS draco_shared
|
||||||
|
EXPORT dracoExport
|
||||||
|
RUNTIME DESTINATION "${bin_path}"
|
||||||
|
ARCHIVE DESTINATION "${libs_path}"
|
||||||
|
LIBRARY DESTINATION "${libs_path}")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(DRACO_UNITY_PLUGIN)
|
if(DRACO_UNITY_PLUGIN)
|
||||||
install(TARGETS dracodec_unity DESTINATION
|
install(TARGETS dracodec_unity DESTINATION "${libs_path}")
|
||||||
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
|
|
||||||
endif()
|
|
||||||
if(DRACO_MAYA_PLUGIN)
|
|
||||||
install(TARGETS draco_maya_wrapper DESTINATION
|
|
||||||
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(DRACO_MAYA_PLUGIN)
|
||||||
|
install(TARGETS draco_maya_wrapper DESTINATION "${libs_path}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# pkg-config: draco.pc
|
||||||
|
configure_file("${draco_root}/cmake/draco.pc.template"
|
||||||
|
"${draco_build}/draco.pc" @ONLY NEWLINE_STYLE UNIX)
|
||||||
|
install(FILES "${draco_build}/draco.pc" DESTINATION "${libs_path}/pkgconfig")
|
||||||
|
|
||||||
|
# CMake config: draco-config.cmake
|
||||||
|
configure_package_config_file(
|
||||||
|
"${draco_root}/cmake/draco-config.cmake.template"
|
||||||
|
"${draco_build}/draco-config.cmake"
|
||||||
|
INSTALL_DESTINATION "${data_path}/cmake/draco")
|
||||||
|
|
||||||
|
write_basic_package_version_file(
|
||||||
|
"${draco_build}/draco-config-version.cmake"
|
||||||
|
VERSION ${DRACO_VERSION}
|
||||||
|
COMPATIBILITY AnyNewerVersion)
|
||||||
|
|
||||||
|
export(
|
||||||
|
EXPORT dracoExport
|
||||||
|
NAMESPACE draco::
|
||||||
|
FILE "${draco_build}/draco-targets.cmake")
|
||||||
|
|
||||||
|
install(
|
||||||
|
EXPORT dracoExport
|
||||||
|
NAMESPACE draco::
|
||||||
|
FILE draco-targets.cmake
|
||||||
|
DESTINATION "${data_path}/cmake/draco")
|
||||||
|
|
||||||
|
install(FILES "${draco_build}/draco-config.cmake"
|
||||||
|
"${draco_build}/draco-config-version.cmake"
|
||||||
|
DESTINATION "${data_path}/cmake/draco")
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
|
@ -1,3 +1,17 @@
|
||||||
|
# Copyright 2021 The Draco Authors
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
# use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
# the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations under
|
||||||
|
# the License.
|
||||||
|
|
||||||
if(DRACO_CMAKE_DRACO_INTRINSICS_CMAKE_)
|
if(DRACO_CMAKE_DRACO_INTRINSICS_CMAKE_)
|
||||||
return()
|
return()
|
||||||
endif() # DRACO_CMAKE_DRACO_INTRINSICS_CMAKE_
|
endif() # DRACO_CMAKE_DRACO_INTRINSICS_CMAKE_
|
||||||
|
@ -61,14 +75,12 @@ macro(draco_process_intrinsics_sources)
|
||||||
unset(sse4_sources)
|
unset(sse4_sources)
|
||||||
list(APPEND sse4_sources ${arg_SOURCES})
|
list(APPEND sse4_sources ${arg_SOURCES})
|
||||||
|
|
||||||
list(FILTER sse4_sources INCLUDE REGEX
|
list(FILTER sse4_sources INCLUDE REGEX "${draco_sse4_source_file_suffix}$")
|
||||||
"${draco_sse4_source_file_suffix}$")
|
|
||||||
|
|
||||||
if(sse4_sources)
|
if(sse4_sources)
|
||||||
unset(sse4_flags)
|
unset(sse4_flags)
|
||||||
draco_get_intrinsics_flag_for_suffix(SUFFIX
|
draco_get_intrinsics_flag_for_suffix(
|
||||||
${draco_sse4_source_file_suffix}
|
SUFFIX ${draco_sse4_source_file_suffix} VARIABLE sse4_flags)
|
||||||
VARIABLE sse4_flags)
|
|
||||||
if(sse4_flags)
|
if(sse4_flags)
|
||||||
draco_set_compiler_flags_for_sources(SOURCES ${sse4_sources} FLAGS
|
draco_set_compiler_flags_for_sources(SOURCES ${sse4_sources} FLAGS
|
||||||
${sse4_flags})
|
${sse4_flags})
|
||||||
|
@ -79,14 +91,12 @@ macro(draco_process_intrinsics_sources)
|
||||||
if(DRACO_ENABLE_NEON AND draco_have_neon)
|
if(DRACO_ENABLE_NEON AND draco_have_neon)
|
||||||
unset(neon_sources)
|
unset(neon_sources)
|
||||||
list(APPEND neon_sources ${arg_SOURCES})
|
list(APPEND neon_sources ${arg_SOURCES})
|
||||||
list(FILTER neon_sources INCLUDE REGEX
|
list(FILTER neon_sources INCLUDE REGEX "${draco_neon_source_file_suffix}$")
|
||||||
"${draco_neon_source_file_suffix}$")
|
|
||||||
|
|
||||||
if(neon_sources AND DRACO_NEON_INTRINSICS_FLAG)
|
if(neon_sources AND DRACO_NEON_INTRINSICS_FLAG)
|
||||||
unset(neon_flags)
|
unset(neon_flags)
|
||||||
draco_get_intrinsics_flag_for_suffix(SUFFIX
|
draco_get_intrinsics_flag_for_suffix(
|
||||||
${draco_neon_source_file_suffix}
|
SUFFIX ${draco_neon_source_file_suffix} VARIABLE neon_flags)
|
||||||
VARIABLE neon_flags)
|
|
||||||
if(neon_flags)
|
if(neon_flags)
|
||||||
draco_set_compiler_flags_for_sources(SOURCES ${neon_sources} FLAGS
|
draco_set_compiler_flags_for_sources(SOURCES ${neon_sources} FLAGS
|
||||||
${neon_flags})
|
${neon_flags})
|
||||||
|
|
|
@ -1,3 +1,17 @@
|
||||||
|
# Copyright 2021 The Draco Authors
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
# use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
# the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations under
|
||||||
|
# the License.
|
||||||
|
|
||||||
if(DRACO_CMAKE_DRACO_OPTIONS_CMAKE_)
|
if(DRACO_CMAKE_DRACO_OPTIONS_CMAKE_)
|
||||||
return()
|
return()
|
||||||
endif() # DRACO_CMAKE_DRACO_OPTIONS_CMAKE_
|
endif() # DRACO_CMAKE_DRACO_OPTIONS_CMAKE_
|
||||||
|
@ -18,14 +32,19 @@ macro(draco_option)
|
||||||
cmake_parse_arguments(option "${optional_args}" "${single_value_args}"
|
cmake_parse_arguments(option "${optional_args}" "${single_value_args}"
|
||||||
"${multi_value_args}" ${ARGN})
|
"${multi_value_args}" ${ARGN})
|
||||||
|
|
||||||
if(NOT (option_NAME AND option_HELPSTRING AND DEFINED option_VALUE))
|
if(NOT
|
||||||
|
(option_NAME
|
||||||
|
AND option_HELPSTRING
|
||||||
|
AND DEFINED option_VALUE))
|
||||||
message(FATAL_ERROR "draco_option: NAME HELPSTRING and VALUE required.")
|
message(FATAL_ERROR "draco_option: NAME HELPSTRING and VALUE required.")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
option(${option_NAME} ${option_HELPSTRING} ${option_VALUE})
|
option(${option_NAME} ${option_HELPSTRING} ${option_VALUE})
|
||||||
|
|
||||||
if(DRACO_VERBOSE GREATER 2)
|
if(DRACO_VERBOSE GREATER 2)
|
||||||
message("--------- draco_option ---------\n" "option_NAME=${option_NAME}\n"
|
message(
|
||||||
|
"--------- draco_option ---------\n"
|
||||||
|
"option_NAME=${option_NAME}\n"
|
||||||
"option_HELPSTRING=${option_HELPSTRING}\n"
|
"option_HELPSTRING=${option_HELPSTRING}\n"
|
||||||
"option_VALUE=${option_VALUE}\n"
|
"option_VALUE=${option_VALUE}\n"
|
||||||
"------------------------------------------\n")
|
"------------------------------------------\n")
|
||||||
|
@ -44,33 +63,74 @@ endmacro()
|
||||||
|
|
||||||
# Set default options.
|
# Set default options.
|
||||||
macro(draco_set_default_options)
|
macro(draco_set_default_options)
|
||||||
draco_option(NAME DRACO_FAST HELPSTRING "Try to build faster libs." VALUE OFF)
|
draco_option(
|
||||||
draco_option(NAME DRACO_JS_GLUE HELPSTRING
|
NAME DRACO_FAST
|
||||||
"Enable JS Glue and JS targets when using Emscripten." VALUE ON)
|
HELPSTRING "Try to build faster libs."
|
||||||
draco_option(NAME DRACO_IE_COMPATIBLE HELPSTRING
|
VALUE OFF)
|
||||||
"Enable support for older IE builds when using Emscripten." VALUE
|
draco_option(
|
||||||
OFF)
|
NAME DRACO_JS_GLUE
|
||||||
draco_option(NAME DRACO_MESH_COMPRESSION HELPSTRING "Enable mesh compression."
|
HELPSTRING "Enable JS Glue and JS targets when using Emscripten."
|
||||||
VALUE ON)
|
VALUE ON)
|
||||||
draco_option(NAME DRACO_POINT_CLOUD_COMPRESSION HELPSTRING
|
draco_option(
|
||||||
"Enable point cloud compression." VALUE ON)
|
NAME DRACO_IE_COMPATIBLE
|
||||||
draco_option(NAME DRACO_PREDICTIVE_EDGEBREAKER HELPSTRING
|
HELPSTRING "Enable support for older IE builds when using Emscripten."
|
||||||
"Enable predictive edgebreaker." VALUE ON)
|
VALUE OFF)
|
||||||
draco_option(NAME DRACO_STANDARD_EDGEBREAKER HELPSTRING
|
draco_option(
|
||||||
"Enable stand edgebreaker." VALUE ON)
|
NAME DRACO_MESH_COMPRESSION
|
||||||
draco_option(NAME DRACO_BACKWARDS_COMPATIBILITY HELPSTRING
|
HELPSTRING "Enable mesh compression."
|
||||||
"Enable backwards compatibility." VALUE ON)
|
VALUE ON)
|
||||||
draco_option(NAME DRACO_DECODER_ATTRIBUTE_DEDUPLICATION HELPSTRING
|
draco_option(
|
||||||
"Enable attribute deduping." VALUE OFF)
|
NAME DRACO_POINT_CLOUD_COMPRESSION
|
||||||
draco_option(NAME DRACO_TESTS HELPSTRING "Enables tests." VALUE OFF)
|
HELPSTRING "Enable point cloud compression."
|
||||||
draco_option(NAME DRACO_WASM HELPSTRING "Enables WASM support." VALUE OFF)
|
VALUE ON)
|
||||||
draco_option(NAME DRACO_UNITY_PLUGIN HELPSTRING
|
draco_option(
|
||||||
"Build plugin library for Unity." VALUE OFF)
|
NAME DRACO_PREDICTIVE_EDGEBREAKER
|
||||||
draco_option(NAME DRACO_ANIMATION_ENCODING HELPSTRING "Enable animation."
|
HELPSTRING "Enable predictive edgebreaker."
|
||||||
|
VALUE ON)
|
||||||
|
draco_option(
|
||||||
|
NAME DRACO_STANDARD_EDGEBREAKER
|
||||||
|
HELPSTRING "Enable stand edgebreaker."
|
||||||
|
VALUE ON)
|
||||||
|
draco_option(
|
||||||
|
NAME DRACO_BACKWARDS_COMPATIBILITY
|
||||||
|
HELPSTRING "Enable backwards compatibility."
|
||||||
|
VALUE ON)
|
||||||
|
draco_option(
|
||||||
|
NAME DRACO_DECODER_ATTRIBUTE_DEDUPLICATION
|
||||||
|
HELPSTRING "Enable attribute deduping."
|
||||||
|
VALUE OFF)
|
||||||
|
draco_option(
|
||||||
|
NAME DRACO_TESTS
|
||||||
|
HELPSTRING "Enables tests."
|
||||||
|
VALUE OFF)
|
||||||
|
draco_option(
|
||||||
|
NAME DRACO_WASM
|
||||||
|
HELPSTRING "Enables WASM support."
|
||||||
|
VALUE OFF)
|
||||||
|
draco_option(
|
||||||
|
NAME DRACO_UNITY_PLUGIN
|
||||||
|
HELPSTRING "Build plugin library for Unity."
|
||||||
|
VALUE OFF)
|
||||||
|
draco_option(
|
||||||
|
NAME DRACO_ANIMATION_ENCODING
|
||||||
|
HELPSTRING "Enable animation."
|
||||||
|
VALUE OFF)
|
||||||
|
draco_option(
|
||||||
|
NAME DRACO_GLTF_BITSTREAM
|
||||||
|
HELPSTRING "Draco GLTF extension bitstream specified features only."
|
||||||
|
VALUE OFF)
|
||||||
|
draco_option(
|
||||||
|
NAME DRACO_MAYA_PLUGIN
|
||||||
|
HELPSTRING "Build plugin library for Maya."
|
||||||
|
VALUE OFF)
|
||||||
|
draco_option(
|
||||||
|
NAME DRACO_TRANSCODER_SUPPORTED
|
||||||
|
HELPSTRING "Enable the Draco transcoder."
|
||||||
|
VALUE OFF)
|
||||||
|
draco_option(
|
||||||
|
NAME DRACO_DEBUG_COMPILER_WARNINGS
|
||||||
|
HELPSTRING "Turn on more warnings."
|
||||||
VALUE OFF)
|
VALUE OFF)
|
||||||
draco_option(NAME DRACO_GLTF HELPSTRING "Support GLTF." VALUE OFF)
|
|
||||||
draco_option(NAME DRACO_MAYA_PLUGIN HELPSTRING
|
|
||||||
"Build plugin library for Maya." VALUE OFF)
|
|
||||||
draco_check_deprecated_options()
|
draco_check_deprecated_options()
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
|
@ -117,14 +177,16 @@ macro(draco_check_deprecated_options)
|
||||||
DRACO_MAYA_PLUGIN)
|
DRACO_MAYA_PLUGIN)
|
||||||
draco_handle_deprecated_option(OLDNAME BUILD_USD_PLUGIN NEWNAME
|
draco_handle_deprecated_option(OLDNAME BUILD_USD_PLUGIN NEWNAME
|
||||||
BUILD_SHARED_LIBS)
|
BUILD_SHARED_LIBS)
|
||||||
|
draco_handle_deprecated_option(OLDNAME DRACO_GLTF NEWNAME
|
||||||
|
DRACO_GLTF_BITSTREAM)
|
||||||
|
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
# Macro for setting Draco features based on user configuration. Features enabled
|
# Macro for setting Draco features based on user configuration. Features enabled
|
||||||
# by this macro are Draco global.
|
# by this macro are Draco global.
|
||||||
macro(draco_set_optional_features)
|
macro(draco_set_optional_features)
|
||||||
if(DRACO_GLTF)
|
if(DRACO_GLTF_BITSTREAM)
|
||||||
# Override settings when building for GLTF.
|
# Enable only the features included in the Draco GLTF bitstream spec.
|
||||||
draco_enable_feature(FEATURE "DRACO_MESH_COMPRESSION_SUPPORTED")
|
draco_enable_feature(FEATURE "DRACO_MESH_COMPRESSION_SUPPORTED")
|
||||||
draco_enable_feature(FEATURE "DRACO_NORMAL_ENCODING_SUPPORTED")
|
draco_enable_feature(FEATURE "DRACO_NORMAL_ENCODING_SUPPORTED")
|
||||||
draco_enable_feature(FEATURE "DRACO_STANDARD_EDGEBREAKER_SUPPORTED")
|
draco_enable_feature(FEATURE "DRACO_STANDARD_EDGEBREAKER_SUPPORTED")
|
||||||
|
@ -170,6 +232,11 @@ macro(draco_set_optional_features)
|
||||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(DRACO_TRANSCODER_SUPPORTED)
|
||||||
|
draco_enable_feature(FEATURE "DRACO_TRANSCODER_SUPPORTED")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
# Macro that handles tracking of Draco preprocessor symbols for the purpose of
|
# Macro that handles tracking of Draco preprocessor symbols for the purpose of
|
||||||
|
@ -221,8 +288,56 @@ function(draco_generate_features_h)
|
||||||
file(APPEND "${draco_features_file_name}.new" "#define ${feature}\n")
|
file(APPEND "${draco_features_file_name}.new" "#define ${feature}\n")
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
if(MSVC)
|
||||||
|
if(NOT DRACO_DEBUG_COMPILER_WARNINGS)
|
||||||
file(APPEND "${draco_features_file_name}.new"
|
file(APPEND "${draco_features_file_name}.new"
|
||||||
"\n#endif // DRACO_FEATURES_H_")
|
"// Enable DRACO_DEBUG_COMPILER_WARNINGS at CMake generation \n"
|
||||||
|
"// time to remove these pragmas.\n")
|
||||||
|
|
||||||
|
# warning C4018: '<operator>': signed/unsigned mismatch.
|
||||||
|
file(APPEND "${draco_features_file_name}.new"
|
||||||
|
"#pragma warning(disable:4018)\n")
|
||||||
|
|
||||||
|
# warning C4146: unary minus operator applied to unsigned type, result
|
||||||
|
# still unsigned
|
||||||
|
file(APPEND "${draco_features_file_name}.new"
|
||||||
|
"#pragma warning(disable:4146)\n")
|
||||||
|
|
||||||
|
# warning C4244: 'return': conversion from '<type>' to '<type>', possible
|
||||||
|
# loss of data.
|
||||||
|
file(APPEND "${draco_features_file_name}.new"
|
||||||
|
"#pragma warning(disable:4244)\n")
|
||||||
|
|
||||||
|
# warning C4267: 'initializing' conversion from '<type>' to '<type>',
|
||||||
|
# possible loss of data.
|
||||||
|
file(APPEND "${draco_features_file_name}.new"
|
||||||
|
"#pragma warning(disable:4267)\n")
|
||||||
|
|
||||||
|
# warning C4305: 'context' : truncation from 'type1' to 'type2'.
|
||||||
|
file(APPEND "${draco_features_file_name}.new"
|
||||||
|
"#pragma warning(disable:4305)\n")
|
||||||
|
|
||||||
|
# warning C4661: 'identifier' : no suitable definition provided for
|
||||||
|
# explicit template instantiation request.
|
||||||
|
file(APPEND "${draco_features_file_name}.new"
|
||||||
|
"#pragma warning(disable:4661)\n")
|
||||||
|
|
||||||
|
# warning C4800: Implicit conversion from 'type' to bool. Possible
|
||||||
|
# information loss.
|
||||||
|
# Also, in older MSVC releases:
|
||||||
|
# warning C4800: 'type' : forcing value to bool 'true' or 'false'
|
||||||
|
# (performance warning).
|
||||||
|
file(APPEND "${draco_features_file_name}.new"
|
||||||
|
"#pragma warning(disable:4800)\n")
|
||||||
|
|
||||||
|
# warning C4804: '<operator>': unsafe use of type '<type>' in operation.
|
||||||
|
file(APPEND "${draco_features_file_name}.new"
|
||||||
|
"#pragma warning(disable:4804)\n")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
file(APPEND "${draco_features_file_name}.new"
|
||||||
|
"\n#endif // DRACO_FEATURES_H_\n")
|
||||||
|
|
||||||
# Will replace ${draco_features_file_name} only if the file content has
|
# Will replace ${draco_features_file_name} only if the file content has
|
||||||
# changed. This prevents forced Draco rebuilds after CMake runs.
|
# changed. This prevents forced Draco rebuilds after CMake runs.
|
||||||
|
|
|
@ -1,3 +1,17 @@
|
||||||
|
# Copyright 2021 The Draco Authors
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
# use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
# the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations under
|
||||||
|
# the License.
|
||||||
|
|
||||||
if(DRACO_CMAKE_DRACO_SANITIZER_CMAKE_)
|
if(DRACO_CMAKE_DRACO_SANITIZER_CMAKE_)
|
||||||
return()
|
return()
|
||||||
endif() # DRACO_CMAKE_DRACO_SANITIZER_CMAKE_
|
endif() # DRACO_CMAKE_DRACO_SANITIZER_CMAKE_
|
||||||
|
@ -5,7 +19,9 @@ set(DRACO_CMAKE_DRACO_SANITIZER_CMAKE_ 1)
|
||||||
|
|
||||||
# Handles the details of enabling sanitizers.
|
# Handles the details of enabling sanitizers.
|
||||||
macro(draco_configure_sanitizer)
|
macro(draco_configure_sanitizer)
|
||||||
if(DRACO_SANITIZE AND NOT EMSCRIPTEN AND NOT MSVC)
|
if(DRACO_SANITIZE
|
||||||
|
AND NOT EMSCRIPTEN
|
||||||
|
AND NOT MSVC)
|
||||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
if(DRACO_SANITIZE MATCHES "cfi")
|
if(DRACO_SANITIZE MATCHES "cfi")
|
||||||
list(APPEND SAN_CXX_FLAGS "-flto" "-fno-sanitize-trap=cfi")
|
list(APPEND SAN_CXX_FLAGS "-flto" "-fno-sanitize-trap=cfi")
|
||||||
|
@ -13,8 +29,8 @@ macro(draco_configure_sanitizer)
|
||||||
"-fuse-ld=gold")
|
"-fuse-ld=gold")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(${CMAKE_SIZEOF_VOID_P} EQUAL 4
|
if(${CMAKE_SIZEOF_VOID_P} EQUAL 4 AND DRACO_SANITIZE MATCHES
|
||||||
AND DRACO_SANITIZE MATCHES "integer|undefined")
|
"integer|undefined")
|
||||||
list(APPEND SAN_LINKER_FLAGS "--rtlib=compiler-rt" "-lgcc_s")
|
list(APPEND SAN_LINKER_FLAGS "--rtlib=compiler-rt" "-lgcc_s")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue