Merge branch 'master' into kimkulling/refactoring_geoutils
|
@ -138,7 +138,7 @@ IF (WIN32)
|
||||||
ELSE()
|
ELSE()
|
||||||
OPTION( ASSIMP_BUILD_ZLIB
|
OPTION( ASSIMP_BUILD_ZLIB
|
||||||
"Build your own zlib"
|
"Build your own zlib"
|
||||||
OFF
|
ON
|
||||||
)
|
)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
|
|
@ -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
|
@ -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.
|
||||||
|
|
|
@ -266,8 +266,15 @@ void Discreet3DSImporter::ParseMainChunk() {
|
||||||
};
|
};
|
||||||
|
|
||||||
ASSIMP_3DS_END_CHUNK();
|
ASSIMP_3DS_END_CHUNK();
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wunreachable-code-return"
|
||||||
|
#endif
|
||||||
// recursively continue processing this hierarchy level
|
// recursively continue processing this hierarchy level
|
||||||
return ParseMainChunk();
|
return ParseMainChunk();
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -68,7 +68,7 @@ using namespace D3DS;
|
||||||
class Discreet3DSImporter : public BaseImporter {
|
class Discreet3DSImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
Discreet3DSImporter();
|
Discreet3DSImporter();
|
||||||
~Discreet3DSImporter();
|
~Discreet3DSImporter() override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
|
|
|
@ -93,7 +93,7 @@ public:
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
~EmbeddedTexture() = default;
|
~EmbeddedTexture() override = default;
|
||||||
|
|
||||||
ResourceType getType() const override {
|
ResourceType getType() const override {
|
||||||
return ResourceType::RT_EmbeddedTexture2D;
|
return ResourceType::RT_EmbeddedTexture2D;
|
||||||
|
@ -110,7 +110,7 @@ public:
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
~Texture2DGroup() = default;
|
~Texture2DGroup() override = default;
|
||||||
|
|
||||||
ResourceType getType() const override {
|
ResourceType getType() const override {
|
||||||
return ResourceType::RT_Texture2DGroup;
|
return ResourceType::RT_Texture2DGroup;
|
||||||
|
@ -127,7 +127,7 @@ public:
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
~BaseMaterials() = default;
|
~BaseMaterials() override = default;
|
||||||
|
|
||||||
ResourceType getType() const override {
|
ResourceType getType() const override {
|
||||||
return ResourceType::RT_BaseMaterials;
|
return ResourceType::RT_BaseMaterials;
|
||||||
|
@ -152,7 +152,7 @@ public:
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
~Object() = default;
|
~Object() override = default;
|
||||||
|
|
||||||
ResourceType getType() const override {
|
ResourceType getType() const override {
|
||||||
return ResourceType::RT_Object;
|
return ResourceType::RT_Object;
|
||||||
|
|
|
@ -282,11 +282,11 @@ public:
|
||||||
bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const;
|
bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const;
|
||||||
bool Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const;
|
bool Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const;
|
||||||
bool Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const;
|
bool Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const;
|
||||||
void Throw_CloseNotFound(const std::string &nodeName);
|
AI_WONT_RETURN void Throw_CloseNotFound(const std::string &nodeName) AI_WONT_RETURN_SUFFIX;
|
||||||
void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName);
|
AI_WONT_RETURN void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
|
||||||
void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName);
|
AI_WONT_RETURN void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
|
||||||
void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription);
|
AI_WONT_RETURN void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription) AI_WONT_RETURN_SUFFIX;
|
||||||
void Throw_ID_NotFound(const std::string &pID) const;
|
AI_WONT_RETURN void Throw_ID_NotFound(const std::string &pID) const AI_WONT_RETURN_SUFFIX;
|
||||||
void XML_CheckNode_MustHaveChildren(pugi::xml_node &node);
|
void XML_CheckNode_MustHaveChildren(pugi::xml_node &node);
|
||||||
bool XML_SearchNode(const std::string &nodeName);
|
bool XML_SearchNode(const std::string &nodeName);
|
||||||
void ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString);
|
void ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -304,7 +304,6 @@ void Parser::Parse() {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_TOP_LEVEL_SECTION();
|
AI_ASE_HANDLE_TOP_LEVEL_SECTION();
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -734,7 +733,6 @@ void Parser::ParseLV3MapBlock(Texture &map) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MAP_XXXXXX");
|
AI_ASE_HANDLE_SECTION("3", "*MAP_XXXXXX");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -859,7 +857,6 @@ void Parser::ParseLV1ObjectBlock(ASE::BaseNode &node) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_TOP_LEVEL_SECTION();
|
AI_ASE_HANDLE_TOP_LEVEL_SECTION();
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -883,7 +880,6 @@ void Parser::ParseLV2CameraSettingsBlock(ASE::Camera &camera) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("2", "CAMERA_SETTINGS");
|
AI_ASE_HANDLE_SECTION("2", "CAMERA_SETTINGS");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -1189,7 +1185,6 @@ void Parser::ParseLV2NodeTransformBlock(ASE::BaseNode &mesh) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("2", "*NODE_TM");
|
AI_ASE_HANDLE_SECTION("2", "*NODE_TM");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV2MeshBlock(ASE::Mesh &mesh) {
|
void Parser::ParseLV2MeshBlock(ASE::Mesh &mesh) {
|
||||||
|
@ -1310,7 +1305,6 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh &mesh) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("2", "*MESH");
|
AI_ASE_HANDLE_SECTION("2", "*MESH");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh &mesh) {
|
void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh &mesh) {
|
||||||
|
@ -1344,7 +1338,6 @@ void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh &mesh) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_WEIGHTS");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_WEIGHTS");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV4MeshBones(unsigned int iNumBones, ASE::Mesh &mesh) {
|
void Parser::ParseLV4MeshBones(unsigned int iNumBones, ASE::Mesh &mesh) {
|
||||||
|
@ -1414,7 +1407,6 @@ void Parser::ParseLV4MeshBonesVertices(unsigned int iNumVertices, ASE::Mesh &mes
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("4", "*MESH_BONE_VERTEX");
|
AI_ASE_HANDLE_SECTION("4", "*MESH_BONE_VERTEX");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshVertexListBlock(
|
void Parser::ParseLV3MeshVertexListBlock(
|
||||||
|
@ -1443,7 +1435,6 @@ void Parser::ParseLV3MeshVertexListBlock(
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_VERTEX_LIST");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_VERTEX_LIST");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh) {
|
void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh) {
|
||||||
|
@ -1470,7 +1461,6 @@ void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh)
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_FACE_LIST");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_FACE_LIST");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
|
void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
|
||||||
|
@ -1503,7 +1493,6 @@ void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_TVERT_LIST");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_TVERT_LIST");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces,
|
void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces,
|
||||||
|
@ -1532,7 +1521,6 @@ void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces,
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_TFACE_LIST");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_TFACE_LIST");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh &mesh) {
|
void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh &mesh) {
|
||||||
|
@ -1567,7 +1555,6 @@ void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh &mesh) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_MAPPING_CHANNEL");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_MAPPING_CHANNEL");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh &mesh) {
|
void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh &mesh) {
|
||||||
|
@ -1595,7 +1582,6 @@ void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh &mesh)
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_CVERTEX_LIST");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_CVERTEX_LIST");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh) {
|
void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh) {
|
||||||
|
@ -1623,7 +1609,6 @@ void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh)
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_CFACE_LIST");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_CFACE_LIST");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh &sMesh) {
|
void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh &sMesh) {
|
||||||
|
@ -1681,7 +1666,6 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh &sMesh) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_NORMALS");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_NORMALS");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV4MeshFace(ASE::Face &out) {
|
void Parser::ParseLV4MeshFace(ASE::Face &out) {
|
||||||
|
|
|
@ -7,7 +7,7 @@ For details, see http://sourceforge.net/projects/libb64
|
||||||
|
|
||||||
#include "cencode.h" // changed from <B64/cencode.h>
|
#include "cencode.h" // changed from <B64/cencode.h>
|
||||||
|
|
||||||
const int CHARS_PER_LINE = 72;
|
static const int CHARS_PER_LINE = 72;
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
|
|
|
@ -418,7 +418,6 @@ void B3DImporter::ReadTRIS(int v0) {
|
||||||
ASSIMP_LOG_ERROR("Bad triangle index: i0=", i0, ", i1=", i1, ", i2=", i2);
|
ASSIMP_LOG_ERROR("Bad triangle index: i0=", i0, ", i1=", i1, ", i2=", i2);
|
||||||
#endif
|
#endif
|
||||||
Fail("Bad triangle index");
|
Fail("Bad triangle index");
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
face->mNumIndices = 3;
|
face->mNumIndices = 3;
|
||||||
face->mIndices = new unsigned[3];
|
face->mIndices = new unsigned[3];
|
||||||
|
|
|
@ -96,7 +96,8 @@ struct CustomDataTypeDescription {
|
||||||
* other (like CD_ORCO, ...) uses arrays of rawtypes or even arrays of Structures
|
* other (like CD_ORCO, ...) uses arrays of rawtypes or even arrays of Structures
|
||||||
* use a special readfunction for that cases
|
* use a special readfunction for that cases
|
||||||
*/
|
*/
|
||||||
std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDescriptions = { { DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MVert),
|
static std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDescriptions = { {
|
||||||
|
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MVert),
|
||||||
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MEdge),
|
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MEdge),
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -1855,7 +1855,6 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
|
||||||
default:
|
default:
|
||||||
// LineStrip is not supported due to expected index unmangling
|
// LineStrip is not supported due to expected index unmangling
|
||||||
throw DeadlyImportError("Unsupported primitive type.");
|
throw DeadlyImportError("Unsupported primitive type.");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// store the face size to later reconstruct the face from
|
// store the face size to later reconstruct the face from
|
||||||
|
|
|
@ -139,6 +139,7 @@ size_t Offset(const char* begin, const char* cursor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
AI_WONT_RETURN void TokenizeError(const std::string& message, const char* begin, const char* cursor) AI_WONT_RETURN_SUFFIX;
|
||||||
void TokenizeError(const std::string& message, const char* begin, const char* cursor) {
|
void TokenizeError(const std::string& message, const char* begin, const char* cursor) {
|
||||||
TokenizeError(message, Offset(begin, cursor));
|
TokenizeError(message, Offset(begin, cursor));
|
||||||
}
|
}
|
||||||
|
|
|
@ -421,6 +421,8 @@ void FBXConverter::ConvertCamera(const Camera &cam, const std::string &orig_name
|
||||||
|
|
||||||
out_camera->mAspect = cam.AspectWidth() / cam.AspectHeight();
|
out_camera->mAspect = cam.AspectWidth() / cam.AspectHeight();
|
||||||
|
|
||||||
|
// NOTE: Camera mPosition, mLookAt and mUp must be set to default here.
|
||||||
|
// All transformations to the camera will be handled by its node in the scenegraph.
|
||||||
out_camera->mPosition = aiVector3D(0.0f);
|
out_camera->mPosition = aiVector3D(0.0f);
|
||||||
out_camera->mLookAt = aiVector3D(1.0f, 0.0f, 0.0f);
|
out_camera->mLookAt = aiVector3D(1.0f, 0.0f, 0.0f);
|
||||||
out_camera->mUp = aiVector3D(0.0f, 1.0f, 0.0f);
|
out_camera->mUp = aiVector3D(0.0f, 1.0f, 0.0f);
|
||||||
|
@ -640,7 +642,7 @@ void FBXConverter::GetRotationMatrix(Model::RotOrder mode, const aiVector3D &rot
|
||||||
bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
|
bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
|
||||||
const PropertyTable &props = model.Props();
|
const PropertyTable &props = model.Props();
|
||||||
|
|
||||||
const auto zero_epsilon = ai_epsilon;
|
const auto zero_epsilon = Math::getEpsilon<ai_real>();
|
||||||
const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
|
const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
|
||||||
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
|
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
|
||||||
const TransformationComp comp = static_cast<TransformationComp>(i);
|
const TransformationComp comp = static_cast<TransformationComp>(i);
|
||||||
|
@ -1180,15 +1182,23 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
|
||||||
std::vector<aiAnimMesh *> animMeshes;
|
std::vector<aiAnimMesh *> animMeshes;
|
||||||
for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
|
for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
|
||||||
for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
|
for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
|
||||||
const std::vector<const ShapeGeometry *> &shapeGeometries = blendShapeChannel->GetShapeGeometries();
|
const auto& shapeGeometries = blendShapeChannel->GetShapeGeometries();
|
||||||
for (size_t i = 0; i < shapeGeometries.size(); i++) {
|
for (const ShapeGeometry *shapeGeometry : shapeGeometries) {
|
||||||
aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh);
|
aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh);
|
||||||
const ShapeGeometry *shapeGeometry = shapeGeometries.at(i);
|
const auto &curVertices = shapeGeometry->GetVertices();
|
||||||
const std::vector<aiVector3D> &curVertices = shapeGeometry->GetVertices();
|
const auto &curNormals = shapeGeometry->GetNormals();
|
||||||
const std::vector<aiVector3D> &curNormals = shapeGeometry->GetNormals();
|
const auto &curIndices = shapeGeometry->GetIndices();
|
||||||
const std::vector<unsigned int> &curIndices = shapeGeometry->GetIndices();
|
|
||||||
//losing channel name if using shapeGeometry->Name()
|
//losing channel name if using shapeGeometry->Name()
|
||||||
animMesh->mName.Set(FixAnimMeshName(blendShapeChannel->Name()));
|
// if blendShapeChannel Name is empty or don't have a ".", add geoMetryName;
|
||||||
|
auto aniName = FixAnimMeshName(blendShapeChannel->Name());
|
||||||
|
auto geoMetryName = FixAnimMeshName(shapeGeometry->Name());
|
||||||
|
if (aniName.empty()) {
|
||||||
|
aniName = geoMetryName;
|
||||||
|
}
|
||||||
|
else if (aniName.find('.') == aniName.npos) {
|
||||||
|
aniName += "." + geoMetryName;
|
||||||
|
}
|
||||||
|
animMesh->mName.Set(aniName);
|
||||||
for (size_t j = 0; j < curIndices.size(); j++) {
|
for (size_t j = 0; j < curIndices.size(); j++) {
|
||||||
const unsigned int curIndex = curIndices.at(j);
|
const unsigned int curIndex = curIndices.at(j);
|
||||||
aiVector3D vertex = curVertices.at(j);
|
aiVector3D vertex = curVertices.at(j);
|
||||||
|
@ -1410,13 +1420,12 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
|
||||||
std::vector<aiAnimMesh *> animMeshes;
|
std::vector<aiAnimMesh *> animMeshes;
|
||||||
for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
|
for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
|
||||||
for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
|
for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
|
||||||
const std::vector<const ShapeGeometry *> &shapeGeometries = blendShapeChannel->GetShapeGeometries();
|
const auto& shapeGeometries = blendShapeChannel->GetShapeGeometries();
|
||||||
for (size_t i = 0; i < shapeGeometries.size(); i++) {
|
for (const ShapeGeometry *shapeGeometry : shapeGeometries) {
|
||||||
aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh);
|
aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh);
|
||||||
const ShapeGeometry *shapeGeometry = shapeGeometries.at(i);
|
const auto& curVertices = shapeGeometry->GetVertices();
|
||||||
const std::vector<aiVector3D> &curVertices = shapeGeometry->GetVertices();
|
const auto& curNormals = shapeGeometry->GetNormals();
|
||||||
const std::vector<aiVector3D> &curNormals = shapeGeometry->GetNormals();
|
const auto& curIndices = shapeGeometry->GetIndices();
|
||||||
const std::vector<unsigned int> &curIndices = shapeGeometry->GetIndices();
|
|
||||||
animMesh->mName.Set(FixAnimMeshName(shapeGeometry->Name()));
|
animMesh->mName.Set(FixAnimMeshName(shapeGeometry->Name()));
|
||||||
for (size_t j = 0; j < curIndices.size(); j++) {
|
for (size_t j = 0; j < curIndices.size(); j++) {
|
||||||
unsigned int curIndex = curIndices.at(j);
|
unsigned int curIndex = curIndices.at(j);
|
||||||
|
|
|
@ -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) */
|
||||||
|
|
|
@ -138,20 +138,6 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Material::~Material() = default;
|
Material::~Material() = default;
|
||||||
|
|
||||||
aiVector2D uvTrans;
|
|
||||||
aiVector2D uvScaling;
|
|
||||||
ai_real uvRotation;
|
|
||||||
|
|
||||||
std::string type;
|
|
||||||
std::string relativeFileName;
|
|
||||||
std::string fileName;
|
|
||||||
std::string alphaSource;
|
|
||||||
std::shared_ptr<const PropertyTable> props;
|
|
||||||
|
|
||||||
unsigned int crop[4]{};
|
|
||||||
|
|
||||||
const Video* media;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Texture::Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name) :
|
Texture::Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name) :
|
||||||
Object(id,element,name),
|
Object(id,element,name),
|
||||||
|
|
|
@ -69,13 +69,16 @@ Geometry::Geometry(uint64_t id, const Element& element, const std::string& name,
|
||||||
}
|
}
|
||||||
const BlendShape* const bsp = ProcessSimpleConnection<BlendShape>(*con, false, "BlendShape -> Geometry", element);
|
const BlendShape* const bsp = ProcessSimpleConnection<BlendShape>(*con, false, "BlendShape -> Geometry", element);
|
||||||
if (bsp) {
|
if (bsp) {
|
||||||
blendShapes.push_back(bsp);
|
auto pr = blendShapes.insert(bsp);
|
||||||
|
if (!pr.second) {
|
||||||
|
FBXImporter::LogWarn("there is the same blendShape id ", bsp->ID());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const std::vector<const BlendShape*>& Geometry::GetBlendShapes() const {
|
const std::unordered_set<const BlendShape*>& Geometry::GetBlendShapes() const {
|
||||||
return blendShapes;
|
return blendShapes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -88,6 +88,7 @@ namespace {
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
AI_WONT_RETURN void ParseError(const std::string& message, TokenPtr token) AI_WONT_RETURN_SUFFIX;
|
||||||
void ParseError(const std::string& message, TokenPtr token)
|
void ParseError(const std::string& message, TokenPtr token)
|
||||||
{
|
{
|
||||||
if(token) {
|
if(token) {
|
||||||
|
@ -188,15 +189,19 @@ Scope::Scope(Parser& parser,bool topLevel)
|
||||||
ParseError("unexpected content: empty string.");
|
ParseError("unexpected content: empty string.");
|
||||||
}
|
}
|
||||||
|
|
||||||
elements.insert(ElementMap::value_type(str,new_Element(*n,parser)));
|
auto *element = new_Element(*n, parser);
|
||||||
|
|
||||||
// Element() should stop at the next Key token (or right after a Close token)
|
// Element() should stop at the next Key token (or right after a Close token)
|
||||||
n = parser.CurrentToken();
|
n = parser.CurrentToken();
|
||||||
if (n == nullptr) {
|
if (n == nullptr) {
|
||||||
if (topLevel) {
|
if (topLevel) {
|
||||||
|
elements.insert(ElementMap::value_type(str, element));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
delete element;
|
||||||
ParseError("unexpected end of file",parser.LastToken());
|
ParseError("unexpected end of file",parser.LastToken());
|
||||||
|
} else {
|
||||||
|
elements.insert(ElementMap::value_type(str, element));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ protected:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Import a HMP4 file
|
/** Import a HMP4 file
|
||||||
*/
|
*/
|
||||||
void InternReadFile_HMP4();
|
AI_WONT_RETURN void InternReadFile_HMP4() AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Import a HMP5 file
|
/** Import a HMP5 file
|
||||||
|
|
|
@ -65,7 +65,6 @@ void LWOImporter::LoadLWOBFile()
|
||||||
if (mFileBuffer + head.length > end)
|
if (mFileBuffer + head.length > end)
|
||||||
{
|
{
|
||||||
throw DeadlyImportError("LWOB: Invalid chunk length");
|
throw DeadlyImportError("LWOB: Invalid chunk length");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
uint8_t* const next = mFileBuffer+head.length;
|
uint8_t* const next = mFileBuffer+head.length;
|
||||||
switch (head.type)
|
switch (head.type)
|
||||||
|
|
|
@ -1484,7 +1484,6 @@ void LWOImporter::LoadLWO2File() {
|
||||||
|
|
||||||
if (mFileBuffer + head.length > end) {
|
if (mFileBuffer + head.length > end) {
|
||||||
throw DeadlyImportError("LWO2: Chunk length points behind the file");
|
throw DeadlyImportError("LWO2: Chunk length points behind the file");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
uint8_t *const next = mFileBuffer + head.length;
|
uint8_t *const next = mFileBuffer + head.length;
|
||||||
mFileBuffer += bufOffset;
|
mFileBuffer += bufOffset;
|
||||||
|
|
|
@ -345,7 +345,7 @@ void LWOImporter::ConvertMaterial(const LWO::Surface &surf, aiMaterial *pcMat) {
|
||||||
|
|
||||||
// (the diffuse value is just a scaling factor)
|
// (the diffuse value is just a scaling factor)
|
||||||
// If a diffuse texture is set, we set this value to 1.0
|
// If a diffuse texture is set, we set this value to 1.0
|
||||||
clr = (b && false ? aiColor3D(1.0, 1.0, 1.0) : surf.mColor);
|
clr = (b ? aiColor3D(1.0, 1.0, 1.0) : surf.mColor);
|
||||||
clr.r *= surf.mDiffuseValue;
|
clr.r *= surf.mDiffuseValue;
|
||||||
clr.g *= surf.mDiffuseValue;
|
clr.g *= surf.mDiffuseValue;
|
||||||
clr.b *= surf.mDiffuseValue;
|
clr.b *= surf.mDiffuseValue;
|
||||||
|
|
|
@ -365,9 +365,7 @@ public:
|
||||||
static void ReportWarning (const char* warn, unsigned int line);
|
static void ReportWarning (const char* warn, unsigned int line);
|
||||||
|
|
||||||
|
|
||||||
void ReportError (const char* error) {
|
AI_WONT_RETURN void ReportError (const char* error) AI_WONT_RETURN_SUFFIX;
|
||||||
return ReportError(error, lineNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReportWarning (const char* warn) {
|
void ReportWarning (const char* warn) {
|
||||||
return ReportWarning(warn, lineNumber);
|
return ReportWarning(warn, lineNumber);
|
||||||
|
@ -404,6 +402,9 @@ private:
|
||||||
unsigned int lineNumber;
|
unsigned int lineNumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline void MD5Parser::ReportError(const char* error) {
|
||||||
|
ReportError(error, lineNumber);
|
||||||
|
}
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
inline bool MD5Parser::SkipLine(const char* in, const char** out) {
|
inline bool MD5Parser::SkipLine(const char* in, const char** out) {
|
||||||
++lineNumber;
|
++lineNumber;
|
||||||
|
|
|
@ -470,14 +470,16 @@ void HL1MDLLoader::read_bones() {
|
||||||
|
|
||||||
temp_bones_.resize(header_->numbones);
|
temp_bones_.resize(header_->numbones);
|
||||||
|
|
||||||
|
// Create the main 'bones' node that will contain all MDL root bones.
|
||||||
aiNode *bones_node = new aiNode(AI_MDL_HL1_NODE_BONES);
|
aiNode *bones_node = new aiNode(AI_MDL_HL1_NODE_BONES);
|
||||||
rootnode_children_.push_back(bones_node);
|
rootnode_children_.push_back(bones_node);
|
||||||
bones_node->mNumChildren = static_cast<unsigned int>(header_->numbones);
|
|
||||||
bones_node->mChildren = new aiNode *[bones_node->mNumChildren];
|
// Store roots bones IDs temporarily.
|
||||||
|
std::vector<int> roots;
|
||||||
|
|
||||||
// Create bone matrices in local space.
|
// Create bone matrices in local space.
|
||||||
for (int i = 0; i < header_->numbones; ++i) {
|
for (int i = 0; i < header_->numbones; ++i) {
|
||||||
aiNode *bone_node = temp_bones_[i].node = bones_node->mChildren[i] = new aiNode(unique_bones_names[i]);
|
aiNode *bone_node = temp_bones_[i].node = new aiNode(unique_bones_names[i]);
|
||||||
|
|
||||||
aiVector3D angles(pbone[i].value[3], pbone[i].value[4], pbone[i].value[5]);
|
aiVector3D angles(pbone[i].value[3], pbone[i].value[4], pbone[i].value[5]);
|
||||||
temp_bones_[i].absolute_transform = bone_node->mTransformation =
|
temp_bones_[i].absolute_transform = bone_node->mTransformation =
|
||||||
|
@ -485,9 +487,11 @@ void HL1MDLLoader::read_bones() {
|
||||||
aiVector3D(pbone[i].value[0], pbone[i].value[1], pbone[i].value[2]));
|
aiVector3D(pbone[i].value[0], pbone[i].value[1], pbone[i].value[2]));
|
||||||
|
|
||||||
if (pbone[i].parent == -1) {
|
if (pbone[i].parent == -1) {
|
||||||
bone_node->mParent = scene_->mRootNode;
|
bone_node->mParent = bones_node;
|
||||||
|
roots.push_back(i); // This bone has no parent. Add it to the roots list.
|
||||||
} else {
|
} else {
|
||||||
bone_node->mParent = bones_node->mChildren[pbone[i].parent];
|
bone_node->mParent = temp_bones_[pbone[i].parent].node;
|
||||||
|
temp_bones_[pbone[i].parent].children.push_back(i); // Add this bone to the parent bone's children list.
|
||||||
|
|
||||||
temp_bones_[i].absolute_transform =
|
temp_bones_[i].absolute_transform =
|
||||||
temp_bones_[pbone[i].parent].absolute_transform * bone_node->mTransformation;
|
temp_bones_[pbone[i].parent].absolute_transform * bone_node->mTransformation;
|
||||||
|
@ -496,6 +500,36 @@ void HL1MDLLoader::read_bones() {
|
||||||
temp_bones_[i].offset_matrix = temp_bones_[i].absolute_transform;
|
temp_bones_[i].offset_matrix = temp_bones_[i].absolute_transform;
|
||||||
temp_bones_[i].offset_matrix.Inverse();
|
temp_bones_[i].offset_matrix.Inverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allocate memory for each MDL root bone.
|
||||||
|
bones_node->mNumChildren = static_cast<unsigned int>(roots.size());
|
||||||
|
bones_node->mChildren = new aiNode *[bones_node->mNumChildren];
|
||||||
|
|
||||||
|
// Build all bones children hierarchy starting from each MDL root bone.
|
||||||
|
for (size_t i = 0; i < roots.size(); ++i)
|
||||||
|
{
|
||||||
|
const TempBone &root_bone = temp_bones_[roots[i]];
|
||||||
|
bones_node->mChildren[i] = root_bone.node;
|
||||||
|
build_bone_children_hierarchy(root_bone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HL1MDLLoader::build_bone_children_hierarchy(const TempBone &bone)
|
||||||
|
{
|
||||||
|
if (bone.children.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
aiNode* bone_node = bone.node;
|
||||||
|
bone_node->mNumChildren = static_cast<unsigned int>(bone.children.size());
|
||||||
|
bone_node->mChildren = new aiNode *[bone_node->mNumChildren];
|
||||||
|
|
||||||
|
// Build each child bone's hierarchy recursively.
|
||||||
|
for (size_t i = 0; i < bone.children.size(); ++i)
|
||||||
|
{
|
||||||
|
const TempBone &child_bone = temp_bones_[bone.children[i]];
|
||||||
|
bone_node->mChildren[i] = child_bone.node;
|
||||||
|
build_bone_children_hierarchy(child_bone);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -143,6 +143,14 @@ private:
|
||||||
*/
|
*/
|
||||||
static bool get_num_blend_controllers(const int num_blend_animations, int &num_blend_controllers);
|
static bool get_num_blend_controllers(const int num_blend_animations, int &num_blend_controllers);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Build a bone's node children hierarchy.
|
||||||
|
*
|
||||||
|
* \param[in] bone The bone for which we must build all children hierarchy.
|
||||||
|
*/
|
||||||
|
struct TempBone;
|
||||||
|
void build_bone_children_hierarchy(const TempBone& bone);
|
||||||
|
|
||||||
/** Output scene to be filled */
|
/** Output scene to be filled */
|
||||||
aiScene *scene_;
|
aiScene *scene_;
|
||||||
|
|
||||||
|
@ -198,11 +206,13 @@ private:
|
||||||
TempBone() :
|
TempBone() :
|
||||||
node(nullptr),
|
node(nullptr),
|
||||||
absolute_transform(),
|
absolute_transform(),
|
||||||
offset_matrix() {}
|
offset_matrix(),
|
||||||
|
children() {}
|
||||||
|
|
||||||
aiNode *node;
|
aiNode *node;
|
||||||
aiMatrix4x4 absolute_transform;
|
aiMatrix4x4 absolute_transform;
|
||||||
aiMatrix4x4 offset_matrix;
|
aiMatrix4x4 offset_matrix;
|
||||||
|
std::vector<int> children; // Bone children
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<TempBone> temp_bones_;
|
std::vector<TempBone> temp_bones_;
|
||||||
|
|
|
@ -139,7 +139,7 @@ protected:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Import a CS:S/HL2 MDL file (not fully implemented)
|
/** Import a CS:S/HL2 MDL file (not fully implemented)
|
||||||
*/
|
*/
|
||||||
void InternReadFile_HL2( );
|
AI_WONT_RETURN void InternReadFile_HL2( ) AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Check whether a given position is inside the valid range
|
/** Check whether a given position is inside the valid range
|
||||||
|
|
|
@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <assimp/types.h>
|
||||||
#include "MMDCpp14.h"
|
#include "MMDCpp14.h"
|
||||||
|
|
||||||
namespace pmx
|
namespace pmx
|
||||||
|
@ -730,7 +731,7 @@ namespace pmx
|
||||||
std::unique_ptr<PmxAncherRigidBody []> anchers;
|
std::unique_ptr<PmxAncherRigidBody []> anchers;
|
||||||
int pin_vertex_count;
|
int pin_vertex_count;
|
||||||
std::unique_ptr<int []> pin_vertices;
|
std::unique_ptr<int []> pin_vertices;
|
||||||
void Read(std::istream *stream, PmxSetting *setting);
|
AI_WONT_RETURN void Read(std::istream *stream, PmxSetting *setting) AI_WONT_RETURN_SUFFIX;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PmxModel
|
class PmxModel
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
Copyright (c) 2006-2023, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -84,7 +84,6 @@ ObjFileImporter::ObjFileImporter() :
|
||||||
// Destructor.
|
// Destructor.
|
||||||
ObjFileImporter::~ObjFileImporter() {
|
ObjFileImporter::~ObjFileImporter() {
|
||||||
delete m_pRootObject;
|
delete m_pRootObject;
|
||||||
m_pRootObject = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -270,7 +269,7 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model *pModel, const ObjFile
|
||||||
for (size_t i = 0; i < pObject->m_Meshes.size(); ++i) {
|
for (size_t i = 0; i < pObject->m_Meshes.size(); ++i) {
|
||||||
unsigned int meshId = pObject->m_Meshes[i];
|
unsigned int meshId = pObject->m_Meshes[i];
|
||||||
aiMesh *pMesh = createTopology(pModel, pObject, meshId);
|
aiMesh *pMesh = createTopology(pModel, pObject, meshId);
|
||||||
if (pMesh) {
|
if (pMesh != nullptr) {
|
||||||
if (pMesh->mNumFaces > 0) {
|
if (pMesh->mNumFaces > 0) {
|
||||||
MeshArray.push_back(pMesh);
|
MeshArray.push_back(pMesh);
|
||||||
} else {
|
} else {
|
||||||
|
@ -324,14 +323,13 @@ aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjF
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<aiMesh> pMesh(new aiMesh);
|
aiMesh *pMesh = new aiMesh;
|
||||||
if (!pObjMesh->m_name.empty()) {
|
if (!pObjMesh->m_name.empty()) {
|
||||||
pMesh->mName.Set(pObjMesh->m_name);
|
pMesh->mName.Set(pObjMesh->m_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) {
|
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) {
|
||||||
const ObjFile::Face *inp = pObjMesh->m_Faces[index];
|
const ObjFile::Face *inp = pObjMesh->m_Faces[index];
|
||||||
//ai_assert(nullptr != inp);
|
|
||||||
|
|
||||||
if (inp->mPrimitiveType == aiPrimitiveType_LINE) {
|
if (inp->mPrimitiveType == aiPrimitiveType_LINE) {
|
||||||
pMesh->mNumFaces += static_cast<unsigned int>(inp->m_vertices.size() - 1);
|
pMesh->mNumFaces += static_cast<unsigned int>(inp->m_vertices.size() - 1);
|
||||||
|
@ -387,9 +385,9 @@ aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjF
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create mesh vertices
|
// Create mesh vertices
|
||||||
createVertexArray(pModel, pData, meshIndex, pMesh.get(), uiIdxCount);
|
createVertexArray(pModel, pData, meshIndex, pMesh, uiIdxCount);
|
||||||
|
|
||||||
return pMesh.release();
|
return pMesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -236,7 +236,7 @@ void ObjFileParser::parseFile(IOStreamBuffer<char> &streamBuffer) {
|
||||||
getNameNoSpace(m_DataIt, m_DataItEnd, name);
|
getNameNoSpace(m_DataIt, m_DataItEnd, name);
|
||||||
insideCstype = name == "cstype";
|
insideCstype = name == "cstype";
|
||||||
goto pf_skip_line;
|
goto pf_skip_line;
|
||||||
} break;
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
pf_skip_line:
|
pf_skip_line:
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace Assimp {
|
||||||
namespace Ogre {
|
namespace Ogre {
|
||||||
|
|
||||||
//AI_WONT_RETURN void ThrowAttibuteError(const XmlParser *reader, const std::string &name, const std::string &error = "") AI_WONT_RETURN_SUFFIX;
|
//AI_WONT_RETURN void ThrowAttibuteError(const XmlParser *reader, const std::string &name, const std::string &error = "") AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN void ThrowAttibuteError(const std::string &nodeName, const std::string &name, const std::string &error) AI_WONT_RETURN_SUFFIX;
|
||||||
AI_WONT_RETURN void ThrowAttibuteError(const std::string &nodeName, const std::string &name, const std::string &error) {
|
AI_WONT_RETURN void ThrowAttibuteError(const std::string &nodeName, const std::string &name, const std::string &error) {
|
||||||
if (!error.empty()) {
|
if (!error.empty()) {
|
||||||
throw DeadlyImportError(error, " in node '", nodeName, "' and attribute '", name, "'");
|
throw DeadlyImportError(error, " in node '", nodeName, "' and attribute '", name, "'");
|
||||||
|
@ -128,7 +128,6 @@ bool OgreXmlSerializer::ReadAttribute<bool>(XmlNode &xmlNode, const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
ThrowAttibuteError(xmlNode.name(), name, "Boolean value is expected to be 'true' or 'false', encountered '" + value + "'");
|
ThrowAttibuteError(xmlNode.name(), name, "Boolean value is expected to be 'true' or 'false', encountered '" + value + "'");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mesh XML constants
|
// Mesh XML constants
|
||||||
|
|
|
@ -460,14 +460,12 @@ void OpenGEXImporter::handleMetricNode(DDLNode *node, aiScene * /*pScene*/) {
|
||||||
void OpenGEXImporter::handleNameNode(DDLNode *node, aiScene * /*pScene*/) {
|
void OpenGEXImporter::handleNameNode(DDLNode *node, aiScene * /*pScene*/) {
|
||||||
if (nullptr == m_currentNode) {
|
if (nullptr == m_currentNode) {
|
||||||
throw DeadlyImportError("No current node for name.");
|
throw DeadlyImportError("No current node for name.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *val(node->getValue());
|
Value *val(node->getValue());
|
||||||
if (nullptr != val) {
|
if (nullptr != val) {
|
||||||
if (Value::ValueType::ddl_string != val->m_type) {
|
if (Value::ValueType::ddl_string != val->m_type) {
|
||||||
throw DeadlyImportError("OpenGEX: invalid data type for value in node name.");
|
throw DeadlyImportError("OpenGEX: invalid data type for value in node name.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string name(val->getString());
|
const std::string name(val->getString());
|
||||||
|
@ -508,7 +506,6 @@ static void getRefNames(DDLNode *node, std::vector<std::string> &names) {
|
||||||
void OpenGEXImporter::handleObjectRefNode(DDLNode *node, aiScene * /*pScene*/) {
|
void OpenGEXImporter::handleObjectRefNode(DDLNode *node, aiScene * /*pScene*/) {
|
||||||
if (nullptr == m_currentNode) {
|
if (nullptr == m_currentNode) {
|
||||||
throw DeadlyImportError("No parent node for name.");
|
throw DeadlyImportError("No parent node for name.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> objRefNames;
|
std::vector<std::string> objRefNames;
|
||||||
|
@ -532,7 +529,6 @@ void OpenGEXImporter::handleObjectRefNode(DDLNode *node, aiScene * /*pScene*/) {
|
||||||
void OpenGEXImporter::handleMaterialRefNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
void OpenGEXImporter::handleMaterialRefNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
||||||
if (nullptr == m_currentNode) {
|
if (nullptr == m_currentNode) {
|
||||||
throw DeadlyImportError("No parent node for name.");
|
throw DeadlyImportError("No parent node for name.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> matRefNames;
|
std::vector<std::string> matRefNames;
|
||||||
|
@ -672,14 +668,12 @@ static void setMatrix(aiNode *node, DataArrayList *transformData) {
|
||||||
void OpenGEXImporter::handleTransformNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
void OpenGEXImporter::handleTransformNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
||||||
if (nullptr == m_currentNode) {
|
if (nullptr == m_currentNode) {
|
||||||
throw DeadlyImportError("No parent node for name.");
|
throw DeadlyImportError("No parent node for name.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DataArrayList *transformData(node->getDataArrayList());
|
DataArrayList *transformData(node->getDataArrayList());
|
||||||
if (nullptr != transformData) {
|
if (nullptr != transformData) {
|
||||||
if (transformData->m_numItems != 16) {
|
if (transformData->m_numItems != 16) {
|
||||||
throw DeadlyImportError("Invalid number of data for transform matrix.");
|
throw DeadlyImportError("Invalid number of data for transform matrix.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
setMatrix(m_currentNode, transformData);
|
setMatrix(m_currentNode, transformData);
|
||||||
}
|
}
|
||||||
|
@ -835,7 +829,6 @@ static void copyColor4DArray(size_t numItems, DataArrayList *vaList, aiColor4D *
|
||||||
void OpenGEXImporter::handleVertexArrayNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
void OpenGEXImporter::handleVertexArrayNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
||||||
if (nullptr == node) {
|
if (nullptr == node) {
|
||||||
throw DeadlyImportError("No parent node for name.");
|
throw DeadlyImportError("No parent node for name.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Property *prop = node->getProperties();
|
Property *prop = node->getProperties();
|
||||||
|
@ -876,12 +869,10 @@ void OpenGEXImporter::handleVertexArrayNode(ODDLParser::DDLNode *node, aiScene *
|
||||||
void OpenGEXImporter::handleIndexArrayNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
void OpenGEXImporter::handleIndexArrayNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
||||||
if (nullptr == node) {
|
if (nullptr == node) {
|
||||||
throw DeadlyImportError("No parent node for name.");
|
throw DeadlyImportError("No parent node for name.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nullptr == m_currentMesh) {
|
if (nullptr == m_currentMesh) {
|
||||||
throw DeadlyImportError("No current mesh for index data found.");
|
throw DeadlyImportError("No current mesh for index data found.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DataArrayList *vaList = node->getDataArrayList();
|
DataArrayList *vaList = node->getDataArrayList();
|
||||||
|
|
|
@ -382,11 +382,10 @@ void Q3DImporter::InternReadFile(const std::string &pFile,
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
goto outer;
|
goto outer;
|
||||||
} break;
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw DeadlyImportError("Quick3D: Unknown chunk");
|
throw DeadlyImportError("Quick3D: Unknown chunk");
|
||||||
break;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
outer:
|
outer:
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace Assimp {
|
||||||
class RAWImporter : public BaseImporter {
|
class RAWImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
RAWImporter();
|
RAWImporter();
|
||||||
~RAWImporter();
|
~RAWImporter() override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
|
|
|
@ -85,7 +85,7 @@ static const aiImporterDesc desc = {
|
||||||
struct SIBChunk {
|
struct SIBChunk {
|
||||||
uint32_t Tag;
|
uint32_t Tag;
|
||||||
uint32_t Size;
|
uint32_t Size;
|
||||||
} PACK_STRUCT;
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
POS,
|
POS,
|
||||||
|
|
|
@ -56,7 +56,7 @@ namespace Assimp {
|
||||||
class UnrealImporter : public BaseImporter {
|
class UnrealImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
UnrealImporter();
|
UnrealImporter();
|
||||||
~UnrealImporter();
|
~UnrealImporter() override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Returns whether we can handle the format of the given file
|
/** @brief Returns whether we can handle the format of the given file
|
||||||
|
|
|
@ -839,7 +839,6 @@ void XFileParser::ParseDataObjectAnimationKey(AnimBone *pAnimBone) {
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ThrowException("Unknown key type ", keyType, " in animation.");
|
ThrowException("Unknown key type ", keyType, " in animation.");
|
||||||
break;
|
|
||||||
} // end switch
|
} // end switch
|
||||||
|
|
||||||
// key separator
|
// key separator
|
||||||
|
|
|
@ -55,6 +55,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
AI_WONT_RETURN inline void Throw_ArgOutOfRange(const std::string &argument) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN inline void Throw_CloseNotFound(const std::string &node) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN inline void Throw_ConvertFail_Str2ArrF(const std::string &nodeName, const std::string &pAttrValue) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN inline void Throw_ConvertFail_Str2ArrD(const std::string &nodeName, const std::string &pAttrValue) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN inline void Throw_ConvertFail_Str2ArrB(const std::string &nodeName, const std::string &pAttrValue) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN inline void Throw_ConvertFail_Str2ArrI(const std::string &nodeName, const std::string &pAttrValue) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN inline void Throw_DEF_And_USE(const std::string &nodeName) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN inline void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN inline void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN inline void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN inline void Throw_TagCountIncorrect(const std::string &pNode) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN inline void Throw_USE_NotFound(const std::string &nodeName, const std::string &pAttrValue) AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
inline void Throw_ArgOutOfRange(const std::string &argument) {
|
inline void Throw_ArgOutOfRange(const std::string &argument) {
|
||||||
throw DeadlyImportError("Argument value is out of range for: \"" + argument + "\".");
|
throw DeadlyImportError("Argument value is out of range for: \"" + argument + "\".");
|
||||||
|
|
|
@ -12,7 +12,6 @@ bool X3DXmlHelper::getColor3DAttribute(XmlNode &node, const char *attributeName,
|
||||||
tokenize<std::string>(val, values, " ");
|
tokenize<std::string>(val, values, " ");
|
||||||
if (values.size() != 3) {
|
if (values.size() != 3) {
|
||||||
Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
|
Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
auto it = values.begin();
|
auto it = values.begin();
|
||||||
color.r = stof(*it++);
|
color.r = stof(*it++);
|
||||||
|
@ -30,7 +29,6 @@ bool X3DXmlHelper::getVector2DAttribute(XmlNode &node, const char *attributeName
|
||||||
tokenize<std::string>(val, values, " ");
|
tokenize<std::string>(val, values, " ");
|
||||||
if (values.size() != 2) {
|
if (values.size() != 2) {
|
||||||
Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
|
Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
auto it = values.begin();
|
auto it = values.begin();
|
||||||
color.x = stof(*it++);
|
color.x = stof(*it++);
|
||||||
|
@ -47,7 +45,6 @@ bool X3DXmlHelper::getVector3DAttribute(XmlNode &node, const char *attributeName
|
||||||
tokenize<std::string>(val, values, " ");
|
tokenize<std::string>(val, values, " ");
|
||||||
if (values.size() != 3) {
|
if (values.size() != 3) {
|
||||||
Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
|
Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
auto it = values.begin();
|
auto it = values.begin();
|
||||||
color.x = stof(*it++);
|
color.x = stof(*it++);
|
||||||
|
|
|
@ -513,21 +513,22 @@ struct Camera : public Object {
|
||||||
};
|
};
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
|
struct Perspective {
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
float aspectRatio; //!<The floating - point aspect ratio of the field of view. (0 = undefined = use the canvas one)
|
float aspectRatio; //!<The floating - point aspect ratio of the field of view. (0 = undefined = use the canvas one)
|
||||||
float yfov; //!<The floating - point vertical field of view in radians. (required)
|
float yfov; //!<The floating - point vertical field of view in radians. (required)
|
||||||
float zfar; //!<The floating - point distance to the far clipping plane. (required)
|
float zfar; //!<The floating - point distance to the far clipping plane. (required)
|
||||||
float znear; //!< The floating - point distance to the near clipping plane. (required)
|
float znear; //!< The floating - point distance to the near clipping plane. (required)
|
||||||
} perspective;
|
};
|
||||||
|
|
||||||
struct {
|
struct Ortographic {
|
||||||
float xmag; //! The floating-point horizontal magnification of the view. (required)
|
float xmag; //! The floating-point horizontal magnification of the view. (required)
|
||||||
float ymag; //! The floating-point vertical magnification of the view. (required)
|
float ymag; //! The floating-point vertical magnification of the view. (required)
|
||||||
float zfar; //! The floating-point distance to the far clipping plane. (required)
|
float zfar; //! The floating-point distance to the far clipping plane. (required)
|
||||||
float znear; //! The floating-point distance to the near clipping plane. (required)
|
float znear; //! The floating-point distance to the near clipping plane. (required)
|
||||||
} ortographic;
|
};
|
||||||
|
union {
|
||||||
|
struct Perspective perspective;
|
||||||
|
struct Ortographic ortographic;
|
||||||
};
|
};
|
||||||
|
|
||||||
Camera() = default;
|
Camera() = default;
|
||||||
|
|
|
@ -483,7 +483,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Buffer();
|
Buffer();
|
||||||
~Buffer();
|
~Buffer() override;
|
||||||
|
|
||||||
void Read(Value &obj, Asset &r);
|
void Read(Value &obj, Asset &r);
|
||||||
|
|
||||||
|
@ -565,7 +565,7 @@ struct Accessor : public Object {
|
||||||
inline size_t GetMaxByteSize();
|
inline size_t GetMaxByteSize();
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void ExtractData(T *&outData);
|
size_t ExtractData(T *&outData, const std::vector<unsigned int> *remappingIndices = nullptr);
|
||||||
|
|
||||||
void WriteData(size_t count, const void *src_buffer, size_t src_stride);
|
void WriteData(size_t count, const void *src_buffer, size_t src_stride);
|
||||||
void WriteSparseValues(size_t count, const void *src_data, size_t src_dataStride);
|
void WriteSparseValues(size_t count, const void *src_data, size_t src_dataStride);
|
||||||
|
|
|
@ -962,14 +962,15 @@ inline size_t Accessor::GetMaxByteSize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void Accessor::ExtractData(T *&outData) {
|
size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remappingIndices) {
|
||||||
uint8_t *data = GetPointer();
|
uint8_t *data = GetPointer();
|
||||||
if (!data) {
|
if (!data) {
|
||||||
throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name));
|
throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const size_t usedCount = (remappingIndices != nullptr) ? remappingIndices->size() : count;
|
||||||
const size_t elemSize = GetElementSize();
|
const size_t elemSize = GetElementSize();
|
||||||
const size_t totalSize = elemSize * count;
|
const size_t totalSize = elemSize * usedCount;
|
||||||
|
|
||||||
const size_t stride = GetStride();
|
const size_t stride = GetStride();
|
||||||
|
|
||||||
|
@ -980,19 +981,32 @@ void Accessor::ExtractData(T *&outData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t maxSize = GetMaxByteSize();
|
const size_t maxSize = GetMaxByteSize();
|
||||||
if (count * stride > maxSize) {
|
|
||||||
throw DeadlyImportError("GLTF: count*stride ", (count * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
|
|
||||||
}
|
|
||||||
|
|
||||||
outData = new T[count];
|
outData = new T[usedCount];
|
||||||
|
|
||||||
|
if (remappingIndices != nullptr) {
|
||||||
|
const unsigned int maxIndex = static_cast<unsigned int>(maxSize / stride - 1);
|
||||||
|
for (size_t i = 0; i < usedCount; ++i) {
|
||||||
|
size_t srcIdx = (*remappingIndices)[i];
|
||||||
|
if (srcIdx > maxIndex) {
|
||||||
|
throw DeadlyImportError("GLTF: index*stride ", (srcIdx * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
|
||||||
|
}
|
||||||
|
memcpy(outData + i, data + srcIdx * stride, elemSize);
|
||||||
|
}
|
||||||
|
} else { // non-indexed cases
|
||||||
|
if (usedCount * stride > maxSize) {
|
||||||
|
throw DeadlyImportError("GLTF: count*stride ", (usedCount * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
|
||||||
|
}
|
||||||
if (stride == elemSize && targetElemSize == elemSize) {
|
if (stride == elemSize && targetElemSize == elemSize) {
|
||||||
memcpy(outData, data, totalSize);
|
memcpy(outData, data, totalSize);
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = 0; i < count; ++i) {
|
for (size_t i = 0; i < usedCount; ++i) {
|
||||||
memcpy(outData + i, data + i * stride, elemSize);
|
memcpy(outData + i, data + i * stride, elemSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return usedCount;
|
||||||
|
}
|
||||||
|
|
||||||
inline void Accessor::WriteData(size_t _count, const void *src_buffer, size_t src_stride) {
|
inline void Accessor::WriteData(size_t _count, const void *src_buffer, size_t src_stride) {
|
||||||
uint8_t *buffer_ptr = bufferView->buffer->GetPointer();
|
uint8_t *buffer_ptr = bufferView->buffer->GetPointer();
|
||||||
|
|
|
@ -453,6 +453,11 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
unsigned int k = 0;
|
unsigned int k = 0;
|
||||||
meshOffsets.clear();
|
meshOffsets.clear();
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<unsigned int> usedVertexIndices;
|
||||||
|
std::vector<unsigned int> reverseMappingIndices;
|
||||||
|
std::vector<unsigned int> indexBuffer;
|
||||||
|
|
||||||
for (unsigned int m = 0; m < r.meshes.Size(); ++m) {
|
for (unsigned int m = 0; m < r.meshes.Size(); ++m) {
|
||||||
Mesh &mesh = r.meshes[m];
|
Mesh &mesh = r.meshes[m];
|
||||||
|
|
||||||
|
@ -462,6 +467,50 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
for (unsigned int p = 0; p < mesh.primitives.size(); ++p) {
|
for (unsigned int p = 0; p < mesh.primitives.size(); ++p) {
|
||||||
Mesh::Primitive &prim = mesh.primitives[p];
|
Mesh::Primitive &prim = mesh.primitives[p];
|
||||||
|
|
||||||
|
Mesh::Primitive::Attributes &attr = prim.attributes;
|
||||||
|
|
||||||
|
// Find out the maximum number of vertices:
|
||||||
|
size_t numAllVertices = 0;
|
||||||
|
if (!attr.position.empty() && attr.position[0]) {
|
||||||
|
numAllVertices = attr.position[0]->count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract used vertices:
|
||||||
|
bool useIndexBuffer = prim.indices;
|
||||||
|
std::vector<unsigned int>* vertexRemappingTable = nullptr;
|
||||||
|
if (useIndexBuffer) {
|
||||||
|
size_t count = prim.indices->count;
|
||||||
|
indexBuffer.resize(count);
|
||||||
|
usedVertexIndices.clear();
|
||||||
|
reverseMappingIndices.clear();
|
||||||
|
usedVertexIndices.reserve(count / 3); // this is a very rough heuristic to reduce re-allocations
|
||||||
|
vertexRemappingTable = &usedVertexIndices;
|
||||||
|
Accessor::Indexer data = prim.indices->GetIndexer();
|
||||||
|
if (!data.IsValid()) {
|
||||||
|
throw DeadlyImportError("GLTF: Invalid accessor without data in mesh ", getContextForErrorMessages(mesh.id, mesh.name));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the vertex remapping table and the modified index buffer (used later instead of the original one)
|
||||||
|
// In case no index buffer is used, the original vertex arrays are being used so no remapping is required in the first place.
|
||||||
|
const unsigned int unusedIndex = ~0u;
|
||||||
|
for (unsigned int i = 0; i < count; ++i) {
|
||||||
|
unsigned int index = data.GetUInt(i);
|
||||||
|
if (index >= numAllVertices) {
|
||||||
|
// Out-of-range indices will be filtered out when adding the faces and then lead to a warning. At this stage, we just keep them.
|
||||||
|
indexBuffer[i] = index;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (index >= reverseMappingIndices.size()) {
|
||||||
|
reverseMappingIndices.resize(index + 1, unusedIndex);
|
||||||
|
}
|
||||||
|
if (reverseMappingIndices[index] == unusedIndex) {
|
||||||
|
reverseMappingIndices[index] = static_cast<unsigned int>(usedVertexIndices.size());
|
||||||
|
usedVertexIndices.push_back(index);
|
||||||
|
}
|
||||||
|
indexBuffer[i] = reverseMappingIndices[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
aiMesh *aim = new aiMesh();
|
aiMesh *aim = new aiMesh();
|
||||||
meshes.push_back(std::unique_ptr<aiMesh>(aim));
|
meshes.push_back(std::unique_ptr<aiMesh>(aim));
|
||||||
|
|
||||||
|
@ -491,28 +540,25 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mesh::Primitive::Attributes &attr = prim.attributes;
|
|
||||||
|
|
||||||
if (!attr.position.empty() && attr.position[0]) {
|
if (!attr.position.empty() && attr.position[0]) {
|
||||||
aim->mNumVertices = static_cast<unsigned int>(attr.position[0]->count);
|
aim->mNumVertices = static_cast<unsigned int>(attr.position[0]->ExtractData(aim->mVertices, vertexRemappingTable));
|
||||||
attr.position[0]->ExtractData(aim->mVertices);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!attr.normal.empty() && attr.normal[0]) {
|
if (!attr.normal.empty() && attr.normal[0]) {
|
||||||
if (attr.normal[0]->count != aim->mNumVertices) {
|
if (attr.normal[0]->count != numAllVertices) {
|
||||||
DefaultLogger::get()->warn("Normal count in mesh \"", mesh.name, "\" does not match the vertex count, normals ignored.");
|
DefaultLogger::get()->warn("Normal count in mesh \"", mesh.name, "\" does not match the vertex count, normals ignored.");
|
||||||
} else {
|
} else {
|
||||||
attr.normal[0]->ExtractData(aim->mNormals);
|
attr.normal[0]->ExtractData(aim->mNormals, vertexRemappingTable);
|
||||||
|
|
||||||
// only extract tangents if normals are present
|
// only extract tangents if normals are present
|
||||||
if (!attr.tangent.empty() && attr.tangent[0]) {
|
if (!attr.tangent.empty() && attr.tangent[0]) {
|
||||||
if (attr.tangent[0]->count != aim->mNumVertices) {
|
if (attr.tangent[0]->count != numAllVertices) {
|
||||||
DefaultLogger::get()->warn("Tangent count in mesh \"", mesh.name, "\" does not match the vertex count, tangents ignored.");
|
DefaultLogger::get()->warn("Tangent count in mesh \"", mesh.name, "\" does not match the vertex count, tangents ignored.");
|
||||||
} else {
|
} else {
|
||||||
// generate bitangents from normals and tangents according to spec
|
// generate bitangents from normals and tangents according to spec
|
||||||
Tangent *tangents = nullptr;
|
Tangent *tangents = nullptr;
|
||||||
|
|
||||||
attr.tangent[0]->ExtractData(tangents);
|
attr.tangent[0]->ExtractData(tangents, vertexRemappingTable);
|
||||||
|
|
||||||
aim->mTangents = new aiVector3D[aim->mNumVertices];
|
aim->mTangents = new aiVector3D[aim->mNumVertices];
|
||||||
aim->mBitangents = new aiVector3D[aim->mNumVertices];
|
aim->mBitangents = new aiVector3D[aim->mNumVertices];
|
||||||
|
@ -529,7 +575,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t c = 0; c < attr.color.size() && c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c) {
|
for (size_t c = 0; c < attr.color.size() && c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c) {
|
||||||
if (attr.color[c]->count != aim->mNumVertices) {
|
if (attr.color[c]->count != numAllVertices) {
|
||||||
DefaultLogger::get()->warn("Color stream size in mesh \"", mesh.name,
|
DefaultLogger::get()->warn("Color stream size in mesh \"", mesh.name,
|
||||||
"\" does not match the vertex count");
|
"\" does not match the vertex count");
|
||||||
continue;
|
continue;
|
||||||
|
@ -537,7 +583,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
|
|
||||||
auto componentType = attr.color[c]->componentType;
|
auto componentType = attr.color[c]->componentType;
|
||||||
if (componentType == glTF2::ComponentType_FLOAT) {
|
if (componentType == glTF2::ComponentType_FLOAT) {
|
||||||
attr.color[c]->ExtractData(aim->mColors[c]);
|
attr.color[c]->ExtractData(aim->mColors[c], vertexRemappingTable);
|
||||||
} else {
|
} else {
|
||||||
if (componentType == glTF2::ComponentType_UNSIGNED_BYTE) {
|
if (componentType == glTF2::ComponentType_UNSIGNED_BYTE) {
|
||||||
aim->mColors[c] = GetVertexColorsForType<unsigned char>(attr.color[c]);
|
aim->mColors[c] = GetVertexColorsForType<unsigned char>(attr.color[c]);
|
||||||
|
@ -552,13 +598,13 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attr.texcoord[tc]->count != aim->mNumVertices) {
|
if (attr.texcoord[tc]->count != numAllVertices) {
|
||||||
DefaultLogger::get()->warn("Texcoord stream size in mesh \"", mesh.name,
|
DefaultLogger::get()->warn("Texcoord stream size in mesh \"", mesh.name,
|
||||||
"\" does not match the vertex count");
|
"\" does not match the vertex count");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]);
|
attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc], vertexRemappingTable);
|
||||||
aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents();
|
aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents();
|
||||||
|
|
||||||
aiVector3D *values = aim->mTextureCoords[tc];
|
aiVector3D *values = aim->mTextureCoords[tc];
|
||||||
|
@ -583,11 +629,11 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
Mesh::Primitive::Target &target = targets[i];
|
Mesh::Primitive::Target &target = targets[i];
|
||||||
|
|
||||||
if (needPositions) {
|
if (needPositions) {
|
||||||
if (target.position[0]->count != aim->mNumVertices) {
|
if (target.position[0]->count != numAllVertices) {
|
||||||
ASSIMP_LOG_WARN("Positions of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count");
|
ASSIMP_LOG_WARN("Positions of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count");
|
||||||
} else {
|
} else {
|
||||||
aiVector3D *positionDiff = nullptr;
|
aiVector3D *positionDiff = nullptr;
|
||||||
target.position[0]->ExtractData(positionDiff);
|
target.position[0]->ExtractData(positionDiff, vertexRemappingTable);
|
||||||
for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) {
|
for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) {
|
||||||
aiAnimMesh.mVertices[vertexId] += positionDiff[vertexId];
|
aiAnimMesh.mVertices[vertexId] += positionDiff[vertexId];
|
||||||
}
|
}
|
||||||
|
@ -595,11 +641,11 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (needNormals) {
|
if (needNormals) {
|
||||||
if (target.normal[0]->count != aim->mNumVertices) {
|
if (target.normal[0]->count != numAllVertices) {
|
||||||
ASSIMP_LOG_WARN("Normals of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count");
|
ASSIMP_LOG_WARN("Normals of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count");
|
||||||
} else {
|
} else {
|
||||||
aiVector3D *normalDiff = nullptr;
|
aiVector3D *normalDiff = nullptr;
|
||||||
target.normal[0]->ExtractData(normalDiff);
|
target.normal[0]->ExtractData(normalDiff, vertexRemappingTable);
|
||||||
for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) {
|
for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) {
|
||||||
aiAnimMesh.mNormals[vertexId] += normalDiff[vertexId];
|
aiAnimMesh.mNormals[vertexId] += normalDiff[vertexId];
|
||||||
}
|
}
|
||||||
|
@ -610,14 +656,14 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
if (!aiAnimMesh.HasNormals()) {
|
if (!aiAnimMesh.HasNormals()) {
|
||||||
// prevent nullptr access to aiAnimMesh.mNormals below when no normals are available
|
// prevent nullptr access to aiAnimMesh.mNormals below when no normals are available
|
||||||
ASSIMP_LOG_WARN("Bitangents of target ", i, " in mesh \"", mesh.name, "\" can't be computed, because mesh has no normals.");
|
ASSIMP_LOG_WARN("Bitangents of target ", i, " in mesh \"", mesh.name, "\" can't be computed, because mesh has no normals.");
|
||||||
} else if (target.tangent[0]->count != aim->mNumVertices) {
|
} else if (target.tangent[0]->count != numAllVertices) {
|
||||||
ASSIMP_LOG_WARN("Tangents of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count");
|
ASSIMP_LOG_WARN("Tangents of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count");
|
||||||
} else {
|
} else {
|
||||||
Tangent *tangent = nullptr;
|
Tangent *tangent = nullptr;
|
||||||
attr.tangent[0]->ExtractData(tangent);
|
attr.tangent[0]->ExtractData(tangent, vertexRemappingTable);
|
||||||
|
|
||||||
aiVector3D *tangentDiff = nullptr;
|
aiVector3D *tangentDiff = nullptr;
|
||||||
target.tangent[0]->ExtractData(tangentDiff);
|
target.tangent[0]->ExtractData(tangentDiff, vertexRemappingTable);
|
||||||
|
|
||||||
for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; ++vertexId) {
|
for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; ++vertexId) {
|
||||||
tangent[vertexId].xyz += tangentDiff[vertexId];
|
tangent[vertexId].xyz += tangentDiff[vertexId];
|
||||||
|
@ -641,20 +687,15 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
aiFace *facePtr = nullptr;
|
aiFace *facePtr = nullptr;
|
||||||
size_t nFaces = 0;
|
size_t nFaces = 0;
|
||||||
|
|
||||||
if (prim.indices) {
|
if (useIndexBuffer) {
|
||||||
size_t count = prim.indices->count;
|
size_t count = indexBuffer.size();
|
||||||
|
|
||||||
Accessor::Indexer data = prim.indices->GetIndexer();
|
|
||||||
if (!data.IsValid()) {
|
|
||||||
throw DeadlyImportError("GLTF: Invalid accessor without data in mesh ", getContextForErrorMessages(mesh.id, mesh.name));
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (prim.mode) {
|
switch (prim.mode) {
|
||||||
case PrimitiveMode_POINTS: {
|
case PrimitiveMode_POINTS: {
|
||||||
nFaces = count;
|
nFaces = count;
|
||||||
facePtr = faces = new aiFace[nFaces];
|
facePtr = faces = new aiFace[nFaces];
|
||||||
for (unsigned int i = 0; i < count; ++i) {
|
for (unsigned int i = 0; i < count; ++i) {
|
||||||
SetFaceAndAdvance1(facePtr, aim->mNumVertices, data.GetUInt(i));
|
SetFaceAndAdvance1(facePtr, aim->mNumVertices, indexBuffer[i]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -667,7 +708,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
}
|
}
|
||||||
facePtr = faces = new aiFace[nFaces];
|
facePtr = faces = new aiFace[nFaces];
|
||||||
for (unsigned int i = 0; i < count; i += 2) {
|
for (unsigned int i = 0; i < count; i += 2) {
|
||||||
SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1));
|
SetFaceAndAdvance2(facePtr, aim->mNumVertices, indexBuffer[i], indexBuffer[i + 1]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -676,12 +717,12 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
case PrimitiveMode_LINE_STRIP: {
|
case PrimitiveMode_LINE_STRIP: {
|
||||||
nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
|
nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
|
||||||
facePtr = faces = new aiFace[nFaces];
|
facePtr = faces = new aiFace[nFaces];
|
||||||
SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(1));
|
SetFaceAndAdvance2(facePtr, aim->mNumVertices, indexBuffer[0], indexBuffer[1]);
|
||||||
for (unsigned int i = 2; i < count; ++i) {
|
for (unsigned int i = 2; i < count; ++i) {
|
||||||
SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(i - 1), data.GetUInt(i));
|
SetFaceAndAdvance2(facePtr, aim->mNumVertices, indexBuffer[i - 1], indexBuffer[i]);
|
||||||
}
|
}
|
||||||
if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
|
if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
|
||||||
SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(static_cast<int>(count) - 1), faces[0].mIndices[0]);
|
SetFaceAndAdvance2(facePtr, aim->mNumVertices, indexBuffer[static_cast<int>(count) - 1], faces[0].mIndices[0]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -694,7 +735,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
}
|
}
|
||||||
facePtr = faces = new aiFace[nFaces];
|
facePtr = faces = new aiFace[nFaces];
|
||||||
for (unsigned int i = 0; i < count; i += 3) {
|
for (unsigned int i = 0; i < count; i += 3) {
|
||||||
SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
|
SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[i], indexBuffer[i + 1], indexBuffer[i + 2]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -705,10 +746,10 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
// The ordering is to ensure that the triangles are all drawn with the same orientation
|
// The ordering is to ensure that the triangles are all drawn with the same orientation
|
||||||
if ((i + 1) % 2 == 0) {
|
if ((i + 1) % 2 == 0) {
|
||||||
// For even n, vertices n + 1, n, and n + 2 define triangle n
|
// For even n, vertices n + 1, n, and n + 2 define triangle n
|
||||||
SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i + 1), data.GetUInt(i), data.GetUInt(i + 2));
|
SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[i + 1], indexBuffer[i], indexBuffer[i + 2]);
|
||||||
} else {
|
} else {
|
||||||
// For odd n, vertices n, n+1, and n+2 define triangle n
|
// For odd n, vertices n, n+1, and n+2 define triangle n
|
||||||
SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
|
SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[i], indexBuffer[i + 1], indexBuffer[i + 2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -716,9 +757,9 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
case PrimitiveMode_TRIANGLE_FAN:
|
case PrimitiveMode_TRIANGLE_FAN:
|
||||||
nFaces = count - 2;
|
nFaces = count - 2;
|
||||||
facePtr = faces = new aiFace[nFaces];
|
facePtr = faces = new aiFace[nFaces];
|
||||||
SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
|
SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[0], indexBuffer[1], indexBuffer[2]);
|
||||||
for (unsigned int i = 1; i < nFaces; ++i) {
|
for (unsigned int i = 1; i < nFaces; ++i) {
|
||||||
SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(i + 1), data.GetUInt(i + 2));
|
SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[0], indexBuffer[i + 1], indexBuffer[i + 2]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1172,11 +1213,6 @@ aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector<unsigned int> &
|
||||||
|
|
||||||
if (node.camera) {
|
if (node.camera) {
|
||||||
pScene->mCameras[node.camera.GetIndex()]->mName = ainode->mName;
|
pScene->mCameras[node.camera.GetIndex()]->mName = ainode->mName;
|
||||||
if (node.translation.isPresent) {
|
|
||||||
aiVector3D trans;
|
|
||||||
CopyValue(node.translation.value, trans);
|
|
||||||
pScene->mCameras[node.camera.GetIndex()]->mPosition = trans;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.light) {
|
if (node.light) {
|
||||||
|
|
|
@ -1195,7 +1195,61 @@ TARGET_USE_COMMON_OUTPUT_DIRECTORY(assimp)
|
||||||
IF (ASSIMP_WARNINGS_AS_ERRORS)
|
IF (ASSIMP_WARNINGS_AS_ERRORS)
|
||||||
MESSAGE(STATUS "Treating all warnings as errors (for assimp library only)")
|
MESSAGE(STATUS "Treating all warnings as errors (for assimp library only)")
|
||||||
IF (MSVC)
|
IF (MSVC)
|
||||||
|
|
||||||
|
IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) # clang-cl
|
||||||
|
TARGET_COMPILE_OPTIONS(assimp PRIVATE -Wall -Werror
|
||||||
|
-Wno-unused-function
|
||||||
|
-Wno-microsoft-enum-value
|
||||||
|
-Wno-switch-enum
|
||||||
|
-Wno-covered-switch-default
|
||||||
|
-Wno-reserved-identifier
|
||||||
|
-Wno-c++98-compat-pedantic
|
||||||
|
-Wno-c++98-compat
|
||||||
|
-Wno-documentation
|
||||||
|
-Wno-documentation-unknown-command
|
||||||
|
-Wno-deprecated-dynamic-exception-spec
|
||||||
|
-Wno-undef
|
||||||
|
-Wno-suggest-destructor-override
|
||||||
|
-Wno-suggest-override
|
||||||
|
-Wno-zero-as-null-pointer-constant
|
||||||
|
-Wno-global-constructors
|
||||||
|
-Wno-exit-time-destructors
|
||||||
|
-Wno-extra-semi-stmt
|
||||||
|
-Wno-missing-prototypes
|
||||||
|
-Wno-old-style-cast
|
||||||
|
-Wno-cast-align
|
||||||
|
-Wno-cast-qual
|
||||||
|
-Wno-float-equal
|
||||||
|
-Wno-implicit-int-float-conversion
|
||||||
|
-Wno-sign-conversion
|
||||||
|
-Wno-implicit-float-conversion
|
||||||
|
-Wno-implicit-int-conversion
|
||||||
|
-Wno-float-conversion
|
||||||
|
-Wno-double-promotion
|
||||||
|
-Wno-unused-macros
|
||||||
|
-Wno-disabled-macro-expansion
|
||||||
|
-Wno-shadow-field
|
||||||
|
-Wno-shadow
|
||||||
|
-Wno-language-extension-token
|
||||||
|
-Wno-header-hygiene
|
||||||
|
-Wno-tautological-value-range-compare
|
||||||
|
-Wno-tautological-type-limit-compare
|
||||||
|
-Wno-missing-variable-declarations
|
||||||
|
-Wno-extra-semi
|
||||||
|
-Wno-nonportable-system-include-path
|
||||||
|
-Wno-undefined-reinterpret-cast
|
||||||
|
-Wno-shift-sign-overflow
|
||||||
|
-Wno-deprecated
|
||||||
|
-Wno-format-nonliteral
|
||||||
|
-Wno-comma
|
||||||
|
-Wno-implicit-fallthrough
|
||||||
|
-Wno-unused-template
|
||||||
|
-Wno-undefined-func-template
|
||||||
|
-Wno-declaration-after-statement
|
||||||
|
)
|
||||||
|
ELSE()
|
||||||
TARGET_COMPILE_OPTIONS(assimp PRIVATE /W4 /WX)
|
TARGET_COMPILE_OPTIONS(assimp PRIVATE /W4 /WX)
|
||||||
|
ENDIF()
|
||||||
ELSE()
|
ELSE()
|
||||||
TARGET_COMPILE_OPTIONS(assimp PRIVATE -Wall -Werror)
|
TARGET_COMPILE_OPTIONS(assimp PRIVATE -Wall -Werror)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
|
@ -214,7 +214,12 @@ void GetImporterInstanceList(std::vector<BaseImporter *> &out) {
|
||||||
// Some importers may be unimplemented or otherwise unsuitable for general use
|
// Some importers may be unimplemented or otherwise unsuitable for general use
|
||||||
// in their current state. Devs can set ASSIMP_ENABLE_DEV_IMPORTERS in their
|
// in their current state. Devs can set ASSIMP_ENABLE_DEV_IMPORTERS in their
|
||||||
// local environment to enable them, otherwise they're left out of the registry.
|
// local environment to enable them, otherwise they're left out of the registry.
|
||||||
|
#if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP
|
||||||
|
// not supported under uwp
|
||||||
const char *envStr = std::getenv("ASSIMP_ENABLE_DEV_IMPORTERS");
|
const char *envStr = std::getenv("ASSIMP_ENABLE_DEV_IMPORTERS");
|
||||||
|
#else
|
||||||
|
const char *envStr = { "0" };
|
||||||
|
#endif
|
||||||
bool devImportersEnabled = envStr && strcmp(envStr, "0");
|
bool devImportersEnabled = envStr && strcmp(envStr, "0");
|
||||||
|
|
||||||
// Ensure no unused var warnings if all uses are #ifndef'd away below:
|
// Ensure no unused var warnings if all uses are #ifndef'd away below:
|
||||||
|
@ -377,9 +382,6 @@ void GetImporterInstanceList(std::vector<BaseImporter *> &out) {
|
||||||
#ifndef ASSIMP_BUILD_NO_IQM_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_IQM_IMPORTER
|
||||||
out.push_back(new IQMImporter());
|
out.push_back(new IQMImporter());
|
||||||
#endif
|
#endif
|
||||||
//#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
|
|
||||||
// out.push_back(new StepFile::StepFileImporter());
|
|
||||||
//#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** will delete all registered importers. */
|
/** will delete all registered importers. */
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ class ZipFile : public IOStream {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::string m_Filename;
|
std::string m_Filename;
|
||||||
virtual ~ZipFile();
|
virtual ~ZipFile() override;
|
||||||
|
|
||||||
// IOStream interface
|
// IOStream interface
|
||||||
size_t Read(void *pvBuffer, size_t pSize, size_t pCount) override;
|
size_t Read(void *pvBuffer, size_t pSize, size_t pCount) override;
|
||||||
|
|
|
@ -111,6 +111,12 @@ void MakeLeftHandedProcess::Execute(aiScene *pScene) {
|
||||||
ProcessAnimation(nodeAnim);
|
ProcessAnimation(nodeAnim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// process the cameras accordingly
|
||||||
|
for( unsigned int a = 0; a < pScene->mNumCameras; ++a)
|
||||||
|
{
|
||||||
|
ProcessCamera(pScene->mCameras[a]);
|
||||||
|
}
|
||||||
ASSIMP_LOG_DEBUG("MakeLeftHandedProcess finished");
|
ASSIMP_LOG_DEBUG("MakeLeftHandedProcess finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,6 +228,13 @@ void MakeLeftHandedProcess::ProcessAnimation(aiNodeAnim *pAnim) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Converts a single camera to left handed coordinates.
|
||||||
|
void MakeLeftHandedProcess::ProcessCamera( aiCamera* pCam)
|
||||||
|
{
|
||||||
|
pCam->mLookAt = ai_real(2.0f) * pCam->mPosition - pCam->mLookAt;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
|
#endif // !! ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
|
||||||
#ifndef ASSIMP_BUILD_NO_FLIPUVS_PROCESS
|
#ifndef ASSIMP_BUILD_NO_FLIPUVS_PROCESS
|
||||||
// # FlipUVsProcess
|
// # FlipUVsProcess
|
||||||
|
|
|
@ -58,6 +58,7 @@ struct aiMesh;
|
||||||
struct aiNodeAnim;
|
struct aiNodeAnim;
|
||||||
struct aiNode;
|
struct aiNode;
|
||||||
struct aiMaterial;
|
struct aiMaterial;
|
||||||
|
struct aiCamera;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
@ -109,6 +110,14 @@ protected:
|
||||||
* @param pAnim The bone animation to transform
|
* @param pAnim The bone animation to transform
|
||||||
*/
|
*/
|
||||||
void ProcessAnimation( aiNodeAnim* pAnim);
|
void ProcessAnimation( aiNodeAnim* pAnim);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Converts a single camera to left handed coordinates.
|
||||||
|
* The camera viewing direction is inverted by reflecting mLookAt
|
||||||
|
* across mPosition.
|
||||||
|
* @param pCam The camera to convert
|
||||||
|
*/
|
||||||
|
void ProcessCamera( aiCamera* pCam);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -588,7 +588,7 @@ void PretransformVertices::Execute(aiScene *pScene) {
|
||||||
// multiply all properties of the camera with the absolute
|
// multiply all properties of the camera with the absolute
|
||||||
// transformation of the corresponding node
|
// transformation of the corresponding node
|
||||||
cam->mPosition = nd->mTransformation * cam->mPosition;
|
cam->mPosition = nd->mTransformation * cam->mPosition;
|
||||||
cam->mLookAt = aiMatrix3x3(nd->mTransformation) * cam->mLookAt;
|
cam->mLookAt = nd->mTransformation * cam->mLookAt;
|
||||||
cam->mUp = aiMatrix3x3(nd->mTransformation) * cam->mUp;
|
cam->mUp = aiMatrix3x3(nd->mTransformation) * cam->mUp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -286,7 +286,6 @@ void ValidateDSProcess::Validate(const aiMesh *pMesh) {
|
||||||
switch (face.mNumIndices) {
|
switch (face.mNumIndices) {
|
||||||
case 0:
|
case 0:
|
||||||
ReportError("aiMesh::mFaces[%i].mNumIndices is 0", i);
|
ReportError("aiMesh::mFaces[%i].mNumIndices is 0", i);
|
||||||
break;
|
|
||||||
case 1:
|
case 1:
|
||||||
if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POINT)) {
|
if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POINT)) {
|
||||||
ReportError("aiMesh::mFaces[%i] is a POINT but aiMesh::mPrimitiveTypes "
|
ReportError("aiMesh::mFaces[%i] is a POINT but aiMesh::mPrimitiveTypes "
|
||||||
|
@ -898,7 +897,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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,6 +92,7 @@ namespace o3dgc
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
// - - Static functions - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - Static functions - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
AI_WONT_RETURN static void AC_Error(const char * msg) AI_WONT_RETURN_SUFFIX;
|
||||||
static void AC_Error(const char * msg)
|
static void AC_Error(const char * msg)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "\n\n -> Arithmetic coding error: ");
|
fprintf(stderr, "\n\n -> Arithmetic coding error: ");
|
||||||
|
|
|
@ -118,8 +118,8 @@ void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangl
|
||||||
Point* p1 = triangle->PointCCW(point);
|
Point* p1 = triangle->PointCCW(point);
|
||||||
Orientation o1 = Orient2d(eq, *p1, ep);
|
Orientation o1 = Orient2d(eq, *p1, ep);
|
||||||
if (o1 == COLLINEAR) {
|
if (o1 == COLLINEAR) {
|
||||||
// ASSIMP_CHANGE (aramis_acg)
|
|
||||||
throw std::runtime_error("EdgeEvent - collinear points not supported");
|
|
||||||
if( triangle->Contains(&eq, p1)) {
|
if( triangle->Contains(&eq, p1)) {
|
||||||
triangle->MarkConstrainedEdge(&eq, p1 );
|
triangle->MarkConstrainedEdge(&eq, p1 );
|
||||||
// We are modifying the constraint maybe it would be better to
|
// We are modifying the constraint maybe it would be better to
|
||||||
|
@ -137,8 +137,8 @@ void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangl
|
||||||
Point* p2 = triangle->PointCW(point);
|
Point* p2 = triangle->PointCW(point);
|
||||||
Orientation o2 = Orient2d(eq, *p2, ep);
|
Orientation o2 = Orient2d(eq, *p2, ep);
|
||||||
if (o2 == COLLINEAR) {
|
if (o2 == COLLINEAR) {
|
||||||
// ASSIMP_CHANGE (aramis_acg)
|
|
||||||
throw std::runtime_error("EdgeEvent - collinear points not supported");
|
|
||||||
|
|
||||||
if( triangle->Contains(&eq, p2)) {
|
if( triangle->Contains(&eq, p2)) {
|
||||||
triangle->MarkConstrainedEdge(&eq, p2 );
|
triangle->MarkConstrainedEdge(&eq, p2 );
|
||||||
|
|
|
@ -103,7 +103,7 @@ int cryptrand(unsigned char *buf, unsigned int len)
|
||||||
unsigned __int64 pentium_tsc[1];
|
unsigned __int64 pentium_tsc[1];
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
|
#if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP
|
||||||
if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
|
if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
|
||||||
{
|
{
|
||||||
result = CryptGenRandom(provider, len, buf);
|
result = CryptGenRandom(provider, len, buf);
|
||||||
|
@ -111,6 +111,7 @@ int cryptrand(unsigned char *buf, unsigned int len)
|
||||||
if (result)
|
if (result)
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
for (rlen = 0; rlen < (int)len; ++rlen)
|
for (rlen = 0; rlen < (int)len; ++rlen)
|
||||||
{
|
{
|
||||||
|
|
|
@ -78,7 +78,7 @@
|
||||||
# pragma warning(disable : 4131 4244 4189 4245)
|
# pragma warning(disable : 4131 4244 4189 4245)
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
const char unz_copyright[] =
|
static const char unz_copyright[] =
|
||||||
" unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
|
" unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
|
||||||
|
|
||||||
/* unz_file_info_internal contain internal info about a file in zipfile*/
|
/* unz_file_info_internal contain internal info about a file in zipfile*/
|
||||||
|
|
|
@ -76,7 +76,15 @@ if(MSVC)
|
||||||
set(CMAKE_DEBUG_POSTFIX "d")
|
set(CMAKE_DEBUG_POSTFIX "d")
|
||||||
add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
|
add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
|
||||||
add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
|
add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
|
||||||
|
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) # clang-cl
|
||||||
|
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-non-prototype")
|
||||||
|
endif()
|
||||||
|
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
else()
|
||||||
|
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) # clang-cl
|
||||||
|
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-non-prototype")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
|
if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
|
||||||
|
|
|
@ -66,7 +66,7 @@ ASSIMP_API void setAiAssertHandler(AiAssertHandler handler);
|
||||||
*
|
*
|
||||||
* @brief This issues a message to stderr and calls abort.
|
* @brief This issues a message to stderr and calls abort.
|
||||||
*/
|
*/
|
||||||
ASSIMP_API void defaultAiAssertHandler(const char* failedExpression, const char* file, int line);
|
AI_WONT_RETURN ASSIMP_API void defaultAiAssertHandler(const char* failedExpression, const char* file, int line) AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -84,7 +84,7 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Destructor public to allow simple deletion to close the file. */
|
/** Destructor public to allow simple deletion to close the file. */
|
||||||
~DefaultIOStream ();
|
~DefaultIOStream () override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/// Read from stream
|
/// Read from stream
|
||||||
|
|
|
@ -145,7 +145,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Destructor.
|
/// @brief Destructor.
|
||||||
~MemoryIOSystem() = default;
|
~MemoryIOSystem() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/// @brief Tests for the existence of a file at the given path.
|
/// @brief Tests for the existence of a file at the given path.
|
||||||
|
|
|
@ -56,7 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) && !defined(__clang__)
|
||||||
#define AI_SIZEFMT "%Iu"
|
#define AI_SIZEFMT "%Iu"
|
||||||
#else
|
#else
|
||||||
#define AI_SIZEFMT "%zu"
|
#define AI_SIZEFMT "%zu"
|
||||||
|
|
|
@ -63,7 +63,7 @@ public:
|
||||||
//! Open a Zip using the proffered IOSystem
|
//! Open a Zip using the proffered IOSystem
|
||||||
ZipArchiveIOSystem(IOSystem* pIOHandler, const char *pFilename, const char* pMode = "r");
|
ZipArchiveIOSystem(IOSystem* pIOHandler, const char *pFilename, const char* pMode = "r");
|
||||||
ZipArchiveIOSystem(IOSystem* pIOHandler, const std::string& rFilename, const char* pMode = "r");
|
ZipArchiveIOSystem(IOSystem* pIOHandler, const std::string& rFilename, const char* pMode = "r");
|
||||||
virtual ~ZipArchiveIOSystem();
|
virtual ~ZipArchiveIOSystem() override;
|
||||||
bool Exists(const char* pFilename) const override;
|
bool Exists(const char* pFilename) const override;
|
||||||
char getOsSeparator() const override;
|
char getOsSeparator() const override;
|
||||||
IOStream* Open(const char* pFilename, const char* pMode = "rb") override;
|
IOStream* Open(const char* pFilename, const char* pMode = "rb") override;
|
||||||
|
|
|
@ -184,6 +184,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
# define AI_WONT_RETURN_SUFFIX __attribute__((noreturn))
|
# define AI_WONT_RETURN_SUFFIX __attribute__((noreturn))
|
||||||
|
#elif _MSC_VER
|
||||||
|
#if defined(__clang__)
|
||||||
|
# define AI_WONT_RETURN_SUFFIX __attribute__((noreturn))
|
||||||
|
#else
|
||||||
|
# define AI_WONT_RETURN_SUFFIX
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
# define AI_WONT_RETURN_SUFFIX
|
# define AI_WONT_RETURN_SUFFIX
|
||||||
#endif // (defined __clang__)
|
#endif // (defined __clang__)
|
||||||
|
|
|
@ -39,7 +39,9 @@
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
const double fast_atof_table[16] = { // we write [16] here instead of [] to work around a swig bug
|
static constexpr size_t NumItems = 16;
|
||||||
|
|
||||||
|
constexpr double fast_atof_table[NumItems] = { // we write [16] here instead of [] to work around a swig bug
|
||||||
0.0,
|
0.0,
|
||||||
0.1,
|
0.1,
|
||||||
0.01,
|
0.01,
|
||||||
|
@ -58,12 +60,10 @@ const double fast_atof_table[16] = { // we write [16] here instead of [] to wo
|
||||||
0.000000000000001
|
0.000000000000001
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
// Convert a string in decimal format to a number
|
// Convert a string in decimal format to a number
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
inline
|
inline unsigned int strtoul10( const char* in, const char** out=0) {
|
||||||
unsigned int strtoul10( const char* in, const char** out=0) {
|
|
||||||
unsigned int value = 0;
|
unsigned int value = 0;
|
||||||
|
|
||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
|
@ -83,8 +83,7 @@ unsigned int strtoul10( const char* in, const char** out=0) {
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
// Convert a string in octal format to a number
|
// Convert a string in octal format to a number
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
inline
|
inline unsigned int strtoul8( const char* in, const char** out=0) {
|
||||||
unsigned int strtoul8( const char* in, const char** out=0) {
|
|
||||||
unsigned int value( 0 );
|
unsigned int value( 0 );
|
||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
if ( *in < '0' || *in > '7' ) {
|
if ( *in < '0' || *in > '7' ) {
|
||||||
|
@ -103,8 +102,7 @@ unsigned int strtoul8( const char* in, const char** out=0) {
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
// Convert a string in hex format to a number
|
// Convert a string in hex format to a number
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
inline
|
inline unsigned int strtoul16( const char* in, const char** out=0) {
|
||||||
unsigned int strtoul16( const char* in, const char** out=0) {
|
|
||||||
unsigned int value( 0 );
|
unsigned int value( 0 );
|
||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
if ( *in >= '0' && *in <= '9' ) {
|
if ( *in >= '0' && *in <= '9' ) {
|
||||||
|
@ -128,8 +126,7 @@ unsigned int strtoul16( const char* in, const char** out=0) {
|
||||||
// Convert just one hex digit
|
// Convert just one hex digit
|
||||||
// Return value is UINT_MAX if the input character is not a hex digit.
|
// Return value is UINT_MAX if the input character is not a hex digit.
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
inline
|
inline unsigned int HexDigitToDecimal(char in) {
|
||||||
unsigned int HexDigitToDecimal(char in) {
|
|
||||||
unsigned int out( UINT_MAX );
|
unsigned int out( UINT_MAX );
|
||||||
if ( in >= '0' && in <= '9' ) {
|
if ( in >= '0' && in <= '9' ) {
|
||||||
out = in - '0';
|
out = in - '0';
|
||||||
|
@ -146,16 +143,14 @@ unsigned int HexDigitToDecimal(char in) {
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
// Convert a hex-encoded octet (2 characters, i.e. df or 1a).
|
// Convert a hex-encoded octet (2 characters, i.e. df or 1a).
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
inline
|
inline uint8_t HexOctetToDecimal(const char* in) {
|
||||||
uint8_t HexOctetToDecimal(const char* in) {
|
|
||||||
return ((uint8_t)HexDigitToDecimal(in[0])<<4)+(uint8_t)HexDigitToDecimal(in[1]);
|
return ((uint8_t)HexDigitToDecimal(in[0])<<4)+(uint8_t)HexDigitToDecimal(in[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
// signed variant of strtoul10
|
// signed variant of strtoul10
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
inline
|
inline int strtol10( const char* in, const char** out=0) {
|
||||||
int strtol10( const char* in, const char** out=0) {
|
|
||||||
bool inv = (*in=='-');
|
bool inv = (*in=='-');
|
||||||
if ( inv || *in == '+' ) {
|
if ( inv || *in == '+' ) {
|
||||||
++in;
|
++in;
|
||||||
|
@ -163,7 +158,11 @@ int strtol10( const char* in, const char** out=0) {
|
||||||
|
|
||||||
int value = strtoul10(in,out);
|
int value = strtoul10(in,out);
|
||||||
if (inv) {
|
if (inv) {
|
||||||
|
if (value < INT_MAX) {
|
||||||
value = -value;
|
value = -value;
|
||||||
|
} else {
|
||||||
|
ASSIMP_LOG_WARN( "Converting the string \"", in, "\" into an inverted value resulted in overflow." );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -174,8 +173,7 @@ int strtol10( const char* in, const char** out=0) {
|
||||||
// 0NNN - oct
|
// 0NNN - oct
|
||||||
// NNN - dec
|
// NNN - dec
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
inline
|
inline unsigned int strtoul_cppstyle( const char* in, const char** out=0) {
|
||||||
unsigned int strtoul_cppstyle( const char* in, const char** out=0) {
|
|
||||||
if ('0' == in[0]) {
|
if ('0' == in[0]) {
|
||||||
return 'x' == in[1] ? strtoul16(in+2,out) : strtoul8(in+1,out);
|
return 'x' == in[1] ? strtoul16(in+2,out) : strtoul8(in+1,out);
|
||||||
}
|
}
|
||||||
|
@ -187,8 +185,7 @@ unsigned int strtoul_cppstyle( const char* in, const char** out=0) {
|
||||||
// It is mainly used by fast_atof to prevent ugly and unwanted integer overflows.
|
// It is mainly used by fast_atof to prevent ugly and unwanted integer overflows.
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
template<typename ExceptionType = DeadlyImportError>
|
template<typename ExceptionType = DeadlyImportError>
|
||||||
inline
|
inline uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* max_inout=0) {
|
||||||
uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* max_inout=0) {
|
|
||||||
unsigned int cur = 0;
|
unsigned int cur = 0;
|
||||||
uint64_t value = 0;
|
uint64_t value = 0;
|
||||||
|
|
||||||
|
@ -241,8 +238,7 @@ uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* max_ino
|
||||||
// signed variant of strtoul10_64
|
// signed variant of strtoul10_64
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
template<typename ExceptionType = DeadlyImportError>
|
template<typename ExceptionType = DeadlyImportError>
|
||||||
inline
|
inline int64_t strtol10_64(const char* in, const char** out = 0, unsigned int* max_inout = 0) {
|
||||||
int64_t strtol10_64(const char* in, const char** out = 0, unsigned int* max_inout = 0) {
|
|
||||||
bool inv = (*in == '-');
|
bool inv = (*in == '-');
|
||||||
if ( inv || *in == '+' ) {
|
if ( inv || *in == '+' ) {
|
||||||
++in;
|
++in;
|
||||||
|
@ -264,8 +260,7 @@ int64_t strtol10_64(const char* in, const char** out = 0, unsigned int* max_inou
|
||||||
// If you find any bugs, please send them to me, niko (at) irrlicht3d.org.
|
// If you find any bugs, please send them to me, niko (at) irrlicht3d.org.
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
template<typename Real, typename ExceptionType = DeadlyImportError>
|
template<typename Real, typename ExceptionType = DeadlyImportError>
|
||||||
inline
|
inline const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true) {
|
||||||
const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true) {
|
|
||||||
Real f = 0;
|
Real f = 0;
|
||||||
|
|
||||||
bool inv = (*c == '-');
|
bool inv = (*c == '-');
|
||||||
|
@ -354,8 +349,7 @@ const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true)
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
// The same but more human.
|
// The same but more human.
|
||||||
template<typename ExceptionType = DeadlyImportError>
|
template<typename ExceptionType = DeadlyImportError>
|
||||||
inline
|
inline ai_real fast_atof(const char* c) {
|
||||||
ai_real fast_atof(const char* c) {
|
|
||||||
ai_real ret(0.0);
|
ai_real ret(0.0);
|
||||||
fast_atoreal_move<ai_real, ExceptionType>(c, ret);
|
fast_atoreal_move<ai_real, ExceptionType>(c, ret);
|
||||||
|
|
||||||
|
@ -372,8 +366,7 @@ ai_real fast_atof( const char* c, const char** cout) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ExceptionType = DeadlyImportError>
|
template<typename ExceptionType = DeadlyImportError>
|
||||||
inline
|
inline ai_real fast_atof( const char** inout) {
|
||||||
ai_real fast_atof( const char** inout) {
|
|
||||||
ai_real ret(0.0);
|
ai_real ret(0.0);
|
||||||
*inout = fast_atoreal_move<ai_real, ExceptionType>(*inout, ret);
|
*inout = fast_atoreal_move<ai_real, ExceptionType>(*inout, ret);
|
||||||
|
|
||||||
|
|
|
@ -115,6 +115,10 @@ def _init(self, target = None, parent = None):
|
||||||
if m.startswith("_"):
|
if m.startswith("_"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# We should not be accessing `mPrivate` according to structs.Scene.
|
||||||
|
if m == 'mPrivate':
|
||||||
|
continue
|
||||||
|
|
||||||
if m.startswith('mNum'):
|
if m.startswith('mNum'):
|
||||||
if 'm' + m[4:] in dirself:
|
if 'm' + m[4:] in dirself:
|
||||||
continue # will be processed later on
|
continue # will be processed later on
|
||||||
|
@ -211,7 +215,7 @@ def _init(self, target = None, parent = None):
|
||||||
|
|
||||||
|
|
||||||
else: # starts with 'm' but not iterable
|
else: # starts with 'm' but not iterable
|
||||||
setattr(target, m, obj)
|
setattr(target, name, obj)
|
||||||
logger.debug("Added " + name + " as self." + name + " (type: " + str(type(obj)) + ")")
|
logger.debug("Added " + name + " as self." + name + " (type: " + str(type(obj)) + ")")
|
||||||
|
|
||||||
if _is_init_type(obj):
|
if _is_init_type(obj):
|
||||||
|
|
After Width: | Height: | Size: 192 KiB |
|
@ -1,6 +1,6 @@
|
||||||
class mar expands Actor;
|
class mar expands Actor;
|
||||||
|
|
||||||
#exec MESH IMPORT MESH=mar ANIVFILE=MODELS\mar_a.3d DATAFILE=MODELS\mar_d.3d X=0 Y=0 Z=0
|
#exec MESH IMPORT MESH=mar ANIVFILE=MODELS\mar_rifle_a.3d DATAFILE=MODELS\mar_rifle_d.3d X=0 Y=0 Z=0
|
||||||
#exec MESH ORIGIN MESH=mar X=0 Y=0 Z=0
|
#exec MESH ORIGIN MESH=mar X=0 Y=0 Z=0
|
||||||
|
|
||||||
#exec MESH SEQUENCE MESH=mar SEQ=All STARTFRAME=0 NUMFRAMES=30
|
#exec MESH SEQUENCE MESH=mar SEQ=All STARTFRAME=0 NUMFRAMES=30
|
||||||
|
@ -9,7 +9,7 @@ class mar expands Actor;
|
||||||
#exec MESHMAP NEW MESHMAP=mar MESH=mar
|
#exec MESHMAP NEW MESHMAP=mar MESH=mar
|
||||||
#exec MESHMAP SCALE MESHMAP=mar X=0.1 Y=0.1 Z=0.2
|
#exec MESHMAP SCALE MESHMAP=mar X=0.1 Y=0.1 Z=0.2
|
||||||
|
|
||||||
#exec TEXTURE IMPORT NAME=Jtex1 FILE=..\3DS\m_rifl.bmp GROUP=Skins FLAGS=2
|
#exec TEXTURE IMPORT NAME=Jtex1 FILE=m_rifl.bmp GROUP=Skins FLAGS=2
|
||||||
#exec TEXTURE IMPORT NAME=Jtex1 FILE=texture1.pcx GROUP=Skins PALETTE=Jtex1
|
#exec TEXTURE IMPORT NAME=Jtex1 FILE=texture1.pcx GROUP=Skins PALETTE=Jtex1
|
||||||
#exec MESHMAP SETTEXTURE MESHMAP=mar NUM=1 TEXTURE=Jtex1
|
#exec MESHMAP SETTEXTURE MESHMAP=mar NUM=1 TEXTURE=Jtex1
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
*MAP_CLASS "Bitmap"
|
*MAP_CLASS "Bitmap"
|
||||||
*MAP_SUBNO 1
|
*MAP_SUBNO 1
|
||||||
*MAP_AMOUNT 1.0000
|
*MAP_AMOUNT 1.0000
|
||||||
*BITMAP "../3DS/MP5SIL.BMP"
|
*BITMAP "mp5sil.bmp"
|
||||||
*MAP_TYPE Screen
|
*MAP_TYPE Screen
|
||||||
*UVW_U_OFFSET 0.000000
|
*UVW_U_OFFSET 0.000000
|
||||||
*UVW_V_OFFSET 0.000000
|
*UVW_V_OFFSET 0.000000
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
*MAP_CLASS "Bitmap"
|
*MAP_CLASS "Bitmap"
|
||||||
*MAP_SUBNO 1
|
*MAP_SUBNO 1
|
||||||
*MAP_AMOUNT 1.0000
|
*MAP_AMOUNT 1.0000
|
||||||
*BITMAP "../3DS/m_rifl.bmp"
|
*BITMAP "m_rifl.bmp"
|
||||||
*MAP_TYPE Screen
|
*MAP_TYPE Screen
|
||||||
*UVW_U_OFFSET 0.000000
|
*UVW_U_OFFSET 0.000000
|
||||||
*UVW_V_OFFSET 0.000000
|
*UVW_V_OFFSET 0.000000
|
||||||
|
|
After Width: | Height: | Size: 192 KiB |
After Width: | Height: | Size: 192 KiB |
After Width: | Height: | Size: 228 KiB |
After Width: | Height: | Size: 118 KiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 64 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 192 KiB |
|
@ -4,4 +4,4 @@ Ka 0.588235 0.588235 0.588235
|
||||||
Ks 0.898039 0.898039 0.898039
|
Ks 0.898039 0.898039 0.898039
|
||||||
Ns 128
|
Ns 128
|
||||||
Tr 0
|
Tr 0
|
||||||
map_Kd ./../3DS/m_rifl.bmp
|
map_Kd m_rifl.bmp
|
||||||
|
|
|
@ -10,7 +10,7 @@ OBJECT poly
|
||||||
name "sphere"
|
name "sphere"
|
||||||
subdiv 3
|
subdiv 3
|
||||||
loc -0.0624103 -0.012381 0.0558408
|
loc -0.0624103 -0.012381 0.0558408
|
||||||
texture "./../LWO/LWO2/MappingModes/earthSpherical.jpg"
|
texture "earthSpherical.jpg"
|
||||||
crease 45.000000
|
crease 45.000000
|
||||||
numvert 134
|
numvert 134
|
||||||
-0.00202139 0.0563461 0
|
-0.00202139 0.0563461 0
|
||||||
|
|
|
@ -10,7 +10,7 @@ OBJECT poly
|
||||||
name "sphere"
|
name "sphere"
|
||||||
subdiv 4
|
subdiv 4
|
||||||
loc -0.0624103 -0.012381 0.0558408
|
loc -0.0624103 -0.012381 0.0558408
|
||||||
texture "./../LWO/LWO2/MappingModes/earthSpherical.jpg"
|
texture "earthSpherical.jpg"
|
||||||
texrep 1.9 2.5
|
texrep 1.9 2.5
|
||||||
texoff 0.019 0.5
|
texoff 0.019 0.5
|
||||||
crease 45.000000
|
crease 45.000000
|
||||||
|
|
|
@ -9,7 +9,7 @@ kids 0
|
||||||
OBJECT poly
|
OBJECT poly
|
||||||
name "ä¸ĺ›˝čŹś"
|
name "ä¸ĺ›˝čŹś"
|
||||||
loc -0.0624103 -0.012381 0.0558408
|
loc -0.0624103 -0.012381 0.0558408
|
||||||
texture "./../LWO/LWO2/MappingModes/earthSpherical.jpg"
|
texture "earthSpherical.jpg"
|
||||||
crease 45.000000
|
crease 45.000000
|
||||||
numvert 134
|
numvert 134
|
||||||
-0.00202139 0.0563461 0
|
-0.00202139 0.0563461 0
|
||||||
|
|
After Width: | Height: | Size: 412 KiB |
After Width: | Height: | Size: 64 KiB |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 81 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 34 KiB |