Compare commits

..
90 changed files with 2519 additions and 700 deletions
+2 -2
View File
@@ -48,7 +48,7 @@ jobs:
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2
- uses: actions/checkout@v5
- uses: actions/checkout@v4
with:
submodules: true
@@ -188,7 +188,7 @@ jobs:
- id: upload-url
run: |
echo "url=$(cat create-release/release_upload_url.txt)" >> $GITHUB_OUTPUT
- uses: actions/download-artifact@v5
- uses: actions/download-artifact@v4
with:
name: 'assimp-bins-${{ matrix.name }}-${{ github.sha }}'
- uses: actions/upload-release-asset@v1
+1 -1
View File
@@ -27,7 +27,7 @@ jobs:
os: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4.2.2
- uses: lukka/get-cmake@latest
+3 -3
View File
@@ -14,7 +14,7 @@ jobs:
name: adress-sanitizer
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: lukka/get-cmake@latest
- uses: lukka/set-shell-env@v1
with:
@@ -38,7 +38,7 @@ jobs:
name: undefined-behavior-sanitizer
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: lukka/get-cmake@latest
- uses: lukka/set-shell-env@v1
with:
@@ -62,7 +62,7 @@ jobs:
name: printf-sanitizer
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- name: run scan_printf script
run: ./scripts/scan_printf.sh
+3 -4
View File
@@ -67,7 +67,7 @@ The cmake-build-environment provides options to configure the build. The followi
- **ASSIMP_NO_EXPORT (default OFF)**: Disable Assimp's export functionality.
- **ASSIMP_BUILD_ZLIB (default OFF)**: Build our own zlib.
- **ASSIMP_BUILD_ALL_EXPORTERS_BY_DEFAULT (default ON)**: Build Assimp with all exporters enabled.
- **ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT (default ON)**: Build Assimp with (most) importers enabled. Currently, USD importer is not included. See ASSIMP_BUILD_USD_IMPORTER.
- **ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT (default ON)**: Build Assimp with all importers enabled.
- **ASSIMP_BUILD_ASSIMP_TOOLS (default OFF)**: If the supplementary tools for Assimp are built in addition to the library.
- **ASSIMP_BUILD_SAMPLES (default OFF)**: If the official samples are built as well (needs Glut).
- **ASSIMP_BUILD_TESTS (default ON)**: If the test suite for Assimp is built in addition to the library.
@@ -83,7 +83,6 @@ The cmake-build-environment provides options to configure the build. The followi
- **USE_STATIC_CRT (default OFF)**: Link against the static MSVC runtime libraries.
- **ASSIMP_BUILD_DRACO (default OFF)**: Build Draco libraries. Primarily for glTF.
- **ASSIMP_BUILD_ASSIMP_VIEW (default ON, if DirectX found, OFF otherwise)**: Build Assimp view tool (requires DirectX).
- **ASSIMP_BUILD_USD_IMPORTER (default OFF, requires ASSIMP_WARNINGS_AS_ERRORS to be OFF)**: Build USD importer, defaults to off for CI purposes
### Install prebuild binaries
## Install on all platforms using vcpkg
@@ -110,5 +109,5 @@ You need to have pip installed:
pip install pyassimp
```
### Get the SDK from itch.io
Just check [itch.io](https://kimkulling.itch.io/the-asset-importer-lib)
### Get the SDK from itchi.io
Just check [itchi.io](https://kimkulling.itch.io/the-asset-importer-lib)
+1 -1
View File
@@ -591,7 +591,7 @@ ELSE()
SET(ASSIMP_BUILD_MINIZIP 1)
ELSE()
ADD_DEFINITIONS(-DASSIMP_BUILD_NO_OWN_ZLIB)
SET(ZLIB_LIBRARIES_LINKED -l${ZLIB_LIBRARIES})
SET(ZLIB_LIBRARIES_LINKED -lz)
ENDIF()
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
ENDIF()
-17
View File
@@ -1,17 +0,0 @@
{
"version": 3,
"cmakeMinimumRequired": {
"major": 3,
"minor": 20,
"patch": 0
},
"configurePresets": [
{
"name": "assimp_with_tools",
"binaryDir": "${sourceDir}",
"cacheVariables": {
"ASSIMP_BUILD_ASSIMP_TOOLS" : "ON"
}
}
]
}
+1 -1
View File
@@ -1,6 +1,6 @@
Open Asset Import Library (assimp)
Copyright (c) 2006-2025, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
+4 -4
View File
@@ -23,14 +23,14 @@ Additionally, assimp features various __mesh post-processing tools__: normals an
Read [our latest documentation](https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/).
### Pre-built binaries ###
Download binaries from [our Itch Projectspace](https://kimkulling.itch.io/the-asset-importer-lib).
Download binaries from [our Itchi Projectspace](https://kimkulling.itch.io/the-asset-importer-lib).
### Test data ###
Clone [our model database for testing purposes](https://github.com/assimp/assimp-mdb).
Clone [our model database](https://github.com/assimp/assimp-mdb).
### Communities ###
- Ask questions at [the Assimp Discussion Board](https://github.com/assimp/assimp/discussions).
- Find us on [discord](https://discord.gg/kKazXMXDy2)
- Find us on [https://discord.gg/s9KJfaem](https://discord.gg/kKazXMXDy2)
- Ask [the Assimp community on Reddit](https://www.reddit.com/r/Assimp/).
- Ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest).
- Nothing has worked? File a question or an issue report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues)
@@ -83,7 +83,7 @@ The source code is organized in the following way:
code/AssetLib/<FormatName> Implementation for import and export of the format
### Contributing ###
We would greatly appreciate for you to contribute to assimp. The easiest way to get involved is to submit
I would greatly appreciate contributing to assimp. The easiest way to get involved is to submit
a pull request with your changes against the main repository's `master` branch.
## Contributors
+2 -1
View File
@@ -2,7 +2,8 @@
## Supported Versions
The current version of Assimp that's being supported with security updates:
Use this section to tell people about which versions of your project are
currently being supported with security updates.
| Version | Supported |
| ------- | ------------------ |
+1 -1
View File
@@ -319,7 +319,7 @@ void Discreet3DSImporter::ConvertMaterial(Material &oldMat, aiMaterial &mat) {
// ------------------------------------------------------------------------------------------------
// Split meshes by their materials and generate output aiMesh'es
void Discreet3DSImporter::ConvertMeshes(aiScene *pcOut) {
MeshArray avOutMeshes;
std::vector<aiMesh *> avOutMeshes;
avOutMeshes.reserve(mScene->mMeshes.size() * 2);
unsigned int iFaceCnt = 0, num = 0;
+1 -1
View File
@@ -157,7 +157,7 @@ struct Component {
class Object : public Resource {
public:
MeshArray mMeshes;
std::vector<aiMesh *> mMeshes;
std::vector<unsigned int> mMeshIndex;
std::vector<Component> mComponents;
std::string mName;
+6 -8
View File
@@ -58,8 +58,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <map>
#include <vector>
namespace Assimp::D3MF {
namespace Assimp {
namespace D3MF {
// ------------------------------------------------------------------------------------------------
using OpcPackageRelationshipPtr = std::shared_ptr<OpcPackageRelationship>;
@@ -131,11 +132,9 @@ static bool IsEmbeddedTexture( const std::string &filename ) {
// ------------------------------------------------------------------------------------------------
D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
mRootStream(nullptr),
mZipArchive(nullptr) {
mZipArchive() {
mZipArchive = new ZipArchiveIOSystem(pIOHandler, rFile);
if (!mZipArchive->isOpen()) {
delete mZipArchive;
mZipArchive = nullptr;
throw DeadlyImportError("Failed to open file ", rFile, ".");
}
@@ -185,9 +184,7 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
}
D3MFOpcPackage::~D3MFOpcPackage() {
if (mRootStream && mZipArchive) {
mZipArchive->Close(mRootStream);
}
mZipArchive->Close(mRootStream);
delete mZipArchive;
}
@@ -253,6 +250,7 @@ void D3MFOpcPackage::LoadEmbeddedTextures(IOStream *fileStream, const std::strin
mEmbeddedTextures.emplace_back(texture);
}
} // Namespace Assimp::D3MF
} // Namespace D3MF
} // Namespace Assimp
#endif //ASSIMP_BUILD_NO_3MF_IMPORTER
+1 -7
View File
@@ -495,16 +495,13 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
}
mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
for (unsigned int vertex_index = 0; vertex_index < mesh->mNumVertices; vertex_index++) {
mesh->mTextureCoords[0][vertex_index].z = IdNotSet; //mark not set
mesh->mTextureCoords[0][vertex_index].z = IdNotSet;//mark not set
}
}
auto update_texture = [&](int idx) {
if (pindex[idx] != IdNotSet) {
size_t vertex_index = face.mIndices[idx];
if (vertex_index >= mesh->mNumVertices) {
return;
}
mesh->mTextureCoords[0][vertex_index] =
aiVector3D(group->mTex2dCoords[pindex[idx]].x, group->mTex2dCoords[pindex[idx]].y, 0.0f);
}
@@ -524,9 +521,6 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
auto update_color = [&](int idx) {
if (pindex[idx] != IdNotSet) {
size_t vertex_index = face.mIndices[idx];
if (vertex_index >= mesh->mNumVertices) {
return;
}
mesh->mColors[0][vertex_index] = group->mColors[pindex[idx]];
}
};
+8 -41
View File
@@ -75,8 +75,6 @@ static constexpr aiImporterDesc desc = {
"ac acc ac3d"
};
static constexpr auto ACDoubleSidedFlag = 0x20;
// ------------------------------------------------------------------------------------------------
// skip to the next token
inline const char *AcSkipToNextToken(const char *buffer, const char *end) {
@@ -125,36 +123,12 @@ inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *end,
}
for (unsigned int _i = 0; _i < num; ++_i) {
buffer = AcSkipToNextToken(buffer, end);
buffer = fast_atoreal_move(buffer, ((float *)out)[_i]);
buffer = fast_atoreal_move<float>(buffer, ((float *)out)[_i]);
}
return buffer;
}
// ------------------------------------------------------------------------------------------------
// Reverses vertex indices in a face.
static void flipWindingOrder(aiFace &f) {
std::reverse(f.mIndices, f.mIndices + f.mNumIndices);
}
// ------------------------------------------------------------------------------------------------
// Duplicates a face and inverts it. Also duplicates all vertices (so the new face gets its own
// set of normals and isn’t smoothed against the original).
static void buildBacksideOfFace(const aiFace &origFace, aiFace *&outFaces, aiVector3D *&outVertices, const aiVector3D *allVertices,
aiVector3D *&outUV, const aiVector3D *allUV, unsigned &curIdx) {
auto &newFace = *outFaces++;
newFace = origFace;
flipWindingOrder(newFace);
for (unsigned f = 0; f < newFace.mNumIndices; ++f) {
*outVertices++ = allVertices[newFace.mIndices[f]];
if (outUV) {
*outUV = allUV[newFace.mIndices[f]];
outUV++;
}
newFace.mIndices[f] = curIdx++;
}
}
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
AC3DImporter::AC3DImporter() :
@@ -418,7 +392,7 @@ void AC3DImporter::ConvertMaterial(const Object &object,
// ------------------------------------------------------------------------------------------------
// Converts the loaded data to the internal verbose representation
aiNode *AC3DImporter::ConvertObjectSection(Object &object,
MeshArray &meshes,
std::vector<aiMesh *> &meshes,
std::vector<aiMaterial *> &outMaterials,
const std::vector<Material> &materials,
aiNode *parent) {
@@ -477,8 +451,6 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
if ((*it).entries.empty()) {
ASSIMP_LOG_WARN("AC3D: surface has zero vertex references");
}
const bool isDoubleSided = ACDoubleSidedFlag == (it->flags & ACDoubleSidedFlag);
const int doubleSidedFactor = isDoubleSided ? 2 : 1;
// validate all vertex indices to make sure we won't crash here
for (it2 = (*it).entries.begin(),
@@ -508,8 +480,8 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
// triangle strip
case Surface::TriangleStrip:
needMat[idx].first += static_cast<unsigned int>(it->entries.size() - 2) * doubleSidedFactor;
needMat[idx].second += static_cast<unsigned int>(it->entries.size() - 2) * 3 * doubleSidedFactor;
needMat[idx].first += (unsigned int)(*it).entries.size() - 2;
needMat[idx].second += ((unsigned int)(*it).entries.size() - 2) * 3;
break;
default:
@@ -522,8 +494,8 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
case Surface::Polygon:
// the number of faces increments by one, the number
// of vertices by surface.numref.
needMat[idx].first += doubleSidedFactor;
needMat[idx].second += static_cast<unsigned int>(it->entries.size()) * doubleSidedFactor;
needMat[idx].first++;
needMat[idx].second += (unsigned int)(*it).entries.size();
};
}
unsigned int *pip = node->mMeshes = new unsigned int[node->mNumMeshes];
@@ -573,7 +545,6 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
for (it = object.surfaces.begin(); it != end; ++it) {
if (mat == (*it).mat) {
const Surface &src = *it;
const bool isDoubleSided = ACDoubleSidedFlag == (src.flags & ACDoubleSidedFlag);
// closed polygon
uint8_t type = (*it).GetType();
@@ -599,8 +570,6 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
++uv;
}
}
if(isDoubleSided) // Need a backface?
buildBacksideOfFace(faces[-1], faces, vertices, mesh->mVertices, uv, mesh->mTextureCoords[0], cur);
}
} else if (type == Surface::TriangleStrip) {
for (unsigned int i = 0; i < (unsigned int)src.entries.size() - 2; ++i) {
@@ -650,8 +619,6 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
uv->y = entry3.second.y;
++uv;
}
if(isDoubleSided) // Need a backface?
buildBacksideOfFace(faces[-1], faces, vertices, mesh->mVertices, uv, mesh->mTextureCoords[0], cur);
}
} else {
@@ -710,7 +677,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
std::unique_ptr<Subdivider> div(Subdivider::Create(Subdivider::CATMULL_CLARKE));
ASSIMP_LOG_INFO("AC3D: Evaluating subdivision surface: ", object.name);
MeshArray cpy(meshes.size() - oldm, nullptr);
std::vector<aiMesh *> cpy(meshes.size() - oldm, nullptr);
div->Subdivide(&meshes[oldm], cpy.size(), &cpy.front(), object.subDiv, true);
std::copy(cpy.begin(), cpy.end(), meshes.begin() + oldm);
@@ -846,7 +813,7 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
}
mNumMeshes += (mNumMeshes >> 2u) + 1;
MeshArray meshes;
std::vector<aiMesh *> meshes;
meshes.reserve(mNumMeshes);
std::vector<aiMaterial *> omaterials;
+1 -1
View File
@@ -226,7 +226,7 @@ private:
* @param materials Material list
* @param Scenegraph node for the object */
aiNode *ConvertObjectSection(Object &object,
MeshArray &meshes,
std::vector<aiMesh *> &meshes,
std::vector<aiMaterial *> &outMaterials,
const std::vector<Material> &materials,
aiNode *parent = nullptr);
+2
View File
@@ -99,6 +99,8 @@ namespace Assimp {
///
class AMFImporter : public BaseImporter {
using AMFMetaDataArray = std::vector<AMFMetadata *>;
using MeshArray = std::vector<aiMesh *>;
using NodeArray = std::vector<aiNode *>;
public:
struct SPP_Material;
+3 -3
View File
@@ -162,7 +162,7 @@ void ASEImporter::InternReadFile(const std::string &pFile,
// process all meshes
bool tookNormals = false;
MeshArray avOutMeshes;
std::vector<aiMesh *> avOutMeshes;
avOutMeshes.reserve(mParser->m_vMeshes.size() * 2);
for (std::vector<ASE::Mesh>::iterator i = mParser->m_vMeshes.begin(); i != mParser->m_vMeshes.end(); ++i) {
if ((*i).bSkip) {
@@ -187,7 +187,7 @@ void ASEImporter::InternReadFile(const std::string &pFile,
// Now build the output mesh list. Remove dummies
pScene->mNumMeshes = (unsigned int)avOutMeshes.size();
aiMesh **pp = pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
for (MeshArray::const_iterator i = avOutMeshes.begin(); i != avOutMeshes.end(); ++i) {
for (std::vector<aiMesh *>::const_iterator i = avOutMeshes.begin(); i != avOutMeshes.end(); ++i) {
if (!(*i)->mNumFaces) {
continue;
}
@@ -902,7 +902,7 @@ void ASEImporter::ConvertMaterial(ASE::Material &mat) {
// ------------------------------------------------------------------------------------------------
// Build output meshes
void ASEImporter::ConvertMeshes(ASE::Mesh &mesh, MeshArray &avOutMeshes) {
void ASEImporter::ConvertMeshes(ASE::Mesh &mesh, std::vector<aiMesh *> &avOutMeshes) {
// validate the material index of the mesh
if (mesh.iMaterialIndex >= mParser->m_vMaterials.size()) {
mesh.iMaterialIndex = (unsigned int)mParser->m_vMaterials.size() - 1;
+3 -3
View File
@@ -1427,7 +1427,7 @@ void Parser::ParseLV4MeshBonesVertices(unsigned int iNumVertices, ASE::Mesh &mes
// then parse the vertex weight
if (!SkipSpaces(&mFilePtr, mEnd)) break;
mFilePtr = fast_atoreal_move(mFilePtr, pairOut.second);
mFilePtr = fast_atoreal_move<float>(mFilePtr, pairOut.second);
// -1 marks unused entries
if (-1 != pairOut.first) {
@@ -1893,7 +1893,7 @@ void Parser::ParseLV4MeshReal(ai_real &fOut) {
return;
}
// parse the first float
mFilePtr = fast_atoreal_move(mFilePtr, fOut);
mFilePtr = fast_atoreal_move<ai_real>(mFilePtr, fOut);
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV4MeshFloat(float &fOut) {
@@ -1906,7 +1906,7 @@ void Parser::ParseLV4MeshFloat(float &fOut) {
return;
}
// parse the first float
mFilePtr = fast_atoreal_move(mFilePtr, fOut);
mFilePtr = fast_atoreal_move<float>(mFilePtr, fOut);
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV4MeshLong(unsigned int &iOut) {
+1 -1
View File
@@ -385,7 +385,7 @@ float BVHLoader::GetNextTokenAsFloat() {
// check if the float is valid by testing if the atof() function consumed every char of the token
const char *ctoken = token.c_str();
float result = 0.0f;
ctoken = fast_atoreal_move(ctoken, result);
ctoken = fast_atoreal_move<float>(ctoken, result);
if (ctoken != token.c_str() + token.length())
ThrowException("Expected a floating point number, but found \"", token, "\".");
+3 -3
View File
@@ -961,7 +961,7 @@ void BlenderImporter::ConvertMesh(const Scene & /*in*/, const Object * /*obj*/,
if (mesh->totface > static_cast<int>(mesh->mtface.size())) {
ThrowException("Number of UV faces is larger than the corresponding UV face array (#1)");
}
for (MeshArray::iterator it = temp->begin() + old; it != temp->end(); ++it) {
for (std::vector<aiMesh *>::iterator it = temp->begin() + old; it != temp->end(); ++it) {
ai_assert(0 != (*it)->mNumVertices);
ai_assert(0 != (*it)->mNumFaces);
const auto itMatTexUvMapping = matTexUvMappings.find((*it)->mMaterialIndex);
@@ -1030,7 +1030,7 @@ void BlenderImporter::ConvertMesh(const Scene & /*in*/, const Object * /*obj*/,
if (mesh->totface > static_cast<int>(mesh->tface.size())) {
ThrowException("Number of faces is larger than the corresponding UV face array (#2)");
}
for (MeshArray::iterator it = temp->begin() + old; it != temp->end(); ++it) {
for (std::vector<aiMesh *>::iterator it = temp->begin() + old; it != temp->end(); ++it) {
ai_assert(0 != (*it)->mNumVertices);
ai_assert(0 != (*it)->mNumFaces);
@@ -1057,7 +1057,7 @@ void BlenderImporter::ConvertMesh(const Scene & /*in*/, const Object * /*obj*/,
if (mesh->totface > static_cast<int>((mesh->mcol.size() / 4))) {
ThrowException("Number of faces is larger than the corresponding color face array");
}
for (MeshArray::iterator it = temp->begin() + old; it != temp->end(); ++it) {
for (std::vector<aiMesh *>::iterator it = temp->begin() + old; it != temp->end(); ++it) {
ai_assert(0 != (*it)->mNumVertices);
ai_assert(0 != (*it)->mNumFaces);
+8 -8
View File
@@ -166,10 +166,10 @@ void C4DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
// copy meshes over
pScene->mNumMeshes = static_cast<unsigned int>(meshes.size());
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]();
std::copy(mMeshes.begin(), mMeshes.end(), pScene->mMeshes);
std::copy(meshes.begin(), meshes.end(), pScene->mMeshes);
// copy materials over, adding a default material if necessary
unsigned int mat_count = static_cast<unsigned int>(mMaterials.size());
unsigned int mat_count = static_cast<unsigned int>(materials.size());
for(aiMesh* mesh : meshes) {
ai_assert(mesh->mMaterialIndex <= mat_count);
if(mesh->mMaterialIndex >= mat_count) {
@@ -179,14 +179,14 @@ void C4DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
const aiString name(AI_DEFAULT_MATERIAL_NAME);
def_material->AddProperty(&name, AI_MATKEY_NAME);
mMaterials.push_back(def_material.release());
materials.push_back(def_material.release());
break;
}
}
pScene->mNumMaterials = static_cast<unsigned int>(materials.size());
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials]();
std::copy(mMaterials.begin(), mMaterials.end(), pScene->mMaterials);
std::copy(materials.begin(), materials.end(), pScene->mMaterials);
}
// ------------------------------------------------------------------------------------------------
@@ -251,8 +251,8 @@ void C4DImporter::ReadMaterials(BaseMaterial* mat) {
while (mat) {
if (mat->GetType() == Mmaterial) {
aiMaterial* out = new aiMaterial();
mMaterialMapping[mat] = static_cast<unsigned int>(mMaterials.size());
mMaterials.push_back(out);
material_mapping[mat] = static_cast<unsigned int>(materials.size());
materials.push_back(out);
auto const ai_name = aiStringFrom(mat->GetName());
out->AddProperty(&ai_name, AI_MATKEY_NAME);
@@ -289,7 +289,7 @@ void C4DImporter::ReadMaterials(BaseMaterial* mat) {
// ------------------------------------------------------------------------------------------------
void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent) {
ai_assert(parent != nullptr );
NodeArray nodes;
std::vector<aiNode*> nodes;
// based on Cineware sample code
while (object) {
@@ -577,7 +577,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object) {
unsigned int C4DImporter::ResolveMaterial(PolygonObject* obj) {
ai_assert(obj != nullptr);
const unsigned int mat_count = static_cast<unsigned int>(mMaterials.size());
const unsigned int mat_count = static_cast<unsigned int>(materials.size());
BaseTag* tag = obj->GetTag(Ttexture);
if(tag == nullptr) {
+4 -5
View File
@@ -97,12 +97,11 @@ private:
bool ReadShader(aiMaterial* out, cineware::BaseShader* shader);
private:
MeshArray mMeshes;
MaterialArray materials;
std::vector<aiMesh*> meshes;
std::vector<aiMaterial*> materials;
using MaterialMap = std::map<cineware::BaseMaterial*, unsigned int> ;
MaterialMap mMaterialMapping;
typedef std::map<cineware::BaseMaterial*, unsigned int> MaterialMap;
MaterialMap material_mapping;
}; // !class C4DImporter
+4 -4
View File
@@ -135,7 +135,7 @@ void CSMImporter::InternReadFile( const std::string& pFile,
else if (TokenMatchI(buffer,"rate",4)) {
SkipSpaces(&buffer, end);
float d = { 0.0f };
buffer = fast_atoreal_move(buffer,d);
buffer = fast_atoreal_move<float>(buffer,d);
anim->mTicksPerSecond = d;
}
else if (TokenMatchI(buffer,"order",5)) {
@@ -226,17 +226,17 @@ void CSMImporter::InternReadFile( const std::string& pFile,
} else {
aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys;
sub->mTime = (double)frame;
buffer = fast_atoreal_move(buffer, sub->mValue.x);
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.x);
if (!SkipSpacesAndLineEnd(&buffer, end)) {
throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample y coord");
}
buffer = fast_atoreal_move(buffer, sub->mValue.y);
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.y);
if (!SkipSpacesAndLineEnd(&buffer, end)) {
throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample z coord");
}
buffer = fast_atoreal_move(buffer, sub->mValue.z);
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.z);
++s->mNumPositionKeys;
}
+1 -1
View File
@@ -668,7 +668,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
}
// create morph target meshes if any
MeshArray targetMeshes;
std::vector<aiMesh *> targetMeshes;
std::vector<float> targetWeights;
Collada::MorphMethod method = Normalized;
+2 -2
View File
@@ -206,10 +206,10 @@ private:
std::map<std::string, size_t> mMaterialIndexByName;
/** Accumulated meshes for the target scene */
MeshArray mMeshes;
std::vector<aiMesh *> mMeshes;
/** Accumulated morph target meshes */
MeshArray mTargetMeshes;
std::vector<aiMesh *> mTargetMeshes;
/** Temporary material list */
std::vector<std::pair<Collada::Effect *, aiMaterial *>> newMats;
+11 -11
View File
@@ -129,7 +129,7 @@ static void ReadNodeTransformation(XmlNode &node, Node *pNode, TransformType pTy
// skip whitespace before the number
SkipSpacesAndLineEnd(&content, end);
// read a number
content = fast_atoreal_move(content, tf.f[a]);
content = fast_atoreal_move<ai_real>(content, tf.f[a]);
}
// place the transformation at the queue of the node
@@ -346,13 +346,13 @@ static void ReadLight(XmlNode &node, Light &pLight) {
const char *content = v.c_str();
const char *end = content + v.size();
content = fast_atoreal_move(content, pLight.mColor.r);
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.r);
SkipSpacesAndLineEnd(&content, end);
content = fast_atoreal_move(content, pLight.mColor.g);
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.g);
SkipSpacesAndLineEnd(&content, end);
content = fast_atoreal_move(content, pLight.mColor.b);
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.b);
SkipSpacesAndLineEnd(&content, end);
} else if (currentName == "constant_attenuation") {
XmlParser::getValueAsReal(currentNode, pLight.mAttConstant);
@@ -631,7 +631,7 @@ void ColladaParser::ReadAssetInfo(XmlNode &node) {
std::string tUnitSizeString;
if (XmlParser::getStdStrAttribute(currentNode, "meter", tUnitSizeString)) {
try {
fast_atoreal_move(tUnitSizeString.data(), mUnitSize);
fast_atoreal_move<ai_real>(tUnitSizeString.data(), mUnitSize);
} catch (const DeadlyImportError& die) {
std::string warning("Collada: Failed to parse meter parameter to real number. Exception:\n");
warning.append(die.what());
@@ -889,7 +889,7 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
for (auto & a : controller.mBindShapeMatrix) {
SkipSpacesAndLineEnd(&content, end);
// read a number
content = fast_atoreal_move(content, a);
content = fast_atoreal_move<ai_real>(content, a);
// skip whitespace after it
SkipSpacesAndLineEnd(&content, end);
}
@@ -1262,16 +1262,16 @@ void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &p
const char *content = v.c_str();
const char *end = v.c_str() + v.size() + 1;
content = fast_atoreal_move(content, pColor.r);
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.r);
SkipSpacesAndLineEnd(&content, end);
content = fast_atoreal_move(content, pColor.g);
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.g);
SkipSpacesAndLineEnd(&content, end);
content = fast_atoreal_move(content, pColor.b);
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.b);
SkipSpacesAndLineEnd(&content, end);
content = fast_atoreal_move(content, pColor.a);
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.a);
SkipSpacesAndLineEnd(&content, end);
} else if (currentName == "texture") {
// get name of source texture/sampler
@@ -1494,7 +1494,7 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
// read a number
ai_real value;
content = fast_atoreal_move(content, value);
content = fast_atoreal_move<ai_real>(content, value);
data.mValues.push_back(value);
// skip whitespace after it
SkipSpacesAndLineEnd(&content, end);
+1 -3
View File
@@ -91,9 +91,7 @@ AI_WONT_RETURN void TokenizeError(const std::string& message, size_t offset)
// ------------------------------------------------------------------------------------------------
size_t Offset(const char* begin, const char* cursor) {
if (begin > cursor) {
return 0;
}
ai_assert(begin <= cursor);
return cursor - begin;
}
+30 -29
View File
@@ -72,7 +72,7 @@ namespace FBX {
using namespace Util;
static constexpr char MAGIC_NODE_TAG[] = "_$AssimpFbx$";
#define MAGIC_NODE_TAG "_$AssimpFbx$"
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000LL
@@ -125,10 +125,21 @@ static void correctRootTransform(const aiScene *scene) {
FBXConverter::FBXConverter(aiScene *out, const Document &doc, bool removeEmptyBones) :
defaultMaterialIndex(),
mMeshes(),
lights(),
cameras(),
textures(),
materials_converted(),
textures_converted(),
meshes_converted(),
node_anim_chain_bits(),
mNodeNames(),
anim_fps(),
mSceneOut(out),
doc(doc),
mRemoveEmptyBones(removeEmptyBones) {
// animations need to be converted first since this will
// populate the node_anim_chain_bits map, which is needed
// to determine which nodes need to be generated.
@@ -151,7 +162,7 @@ FBXConverter::FBXConverter(aiScene *out, const Document &doc, bool removeEmptyBo
continue;
}
auto mat = dynamic_cast<const Material *>(ob);
const Material *mat = dynamic_cast<const Material *>(ob);
if (mat) {
if (materials_converted.find(mat) == materials_converted.end()) {
@@ -211,6 +222,7 @@ static std::string getAncestorBaseName(const aiNode *node) {
return std::string(nodeName, length);
}
// Make unique name
std::string FBXConverter::MakeUniqueNodeName(const Model *const model, const aiNode &parent) {
std::string original_name = FixNodeName(model->Name());
if (original_name.empty()) {
@@ -224,18 +236,9 @@ std::string FBXConverter::MakeUniqueNodeName(const Model *const model, const aiN
/// This struct manages nodes which may or may not end up in the node hierarchy.
/// When a node becomes a child of another node, that node becomes its owner and mOwnership should be released.
struct FBXConverter::PotentialNode {
PotentialNode() : mOwnership(new aiNode), mNode(mOwnership.get()) {
// empty
}
explicit PotentialNode(const std::string& name) : mOwnership(new aiNode(name)), mNode(mOwnership.get()) {
// empty
}
aiNode* operator->() {
return mNode;
}
PotentialNode() : mOwnership(new aiNode), mNode(mOwnership.get()) {}
PotentialNode(const std::string& name) : mOwnership(new aiNode(name)), mNode(mOwnership.get()) {}
aiNode* operator->() { return mNode; }
std::unique_ptr<aiNode> mOwnership;
aiNode* mNode;
};
@@ -1089,14 +1092,14 @@ aiMesh *FBXConverter::SetupEmptyMesh(const Geometry &mesh, aiNode *parent) {
}
static aiSkeleton *createAiSkeleton(SkeletonBoneContainer &sbc) {
if (sbc.meshArray.empty() || sbc.skeletonBoneToMeshLookup.empty()) {
if (sbc.MeshArray.empty() || sbc.SkeletonBoneToMeshLookup.empty()) {
return nullptr;
}
aiSkeleton *skeleton = new aiSkeleton;
for (auto *mesh : sbc.meshArray) {
auto it = sbc.skeletonBoneToMeshLookup.find(mesh);
if (it == sbc.skeletonBoneToMeshLookup.end()) {
for (auto *mesh : sbc.MeshArray) {
auto it = sbc.SkeletonBoneToMeshLookup.find(mesh);
if (it == sbc.SkeletonBoneToMeshLookup.end()) {
continue;
}
SkeletonBoneArray *ba = it->second;
@@ -1544,12 +1547,12 @@ static void copyBoneToSkeletonBone(aiMesh *mesh, aiBone *bone, aiSkeletonBone *s
void FBXConverter::ConvertWeightsToSkeleton(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform, aiNode *parent, unsigned int materialIndex,
std::vector<unsigned int> *outputVertStartIndices, SkeletonBoneContainer &skeletonContainer) {
if (skeletonContainer.skeletonBoneToMeshLookup.find(out) != skeletonContainer.skeletonBoneToMeshLookup.end()) {
if (skeletonContainer.SkeletonBoneToMeshLookup.find(out) != skeletonContainer.SkeletonBoneToMeshLookup.end()) {
return;
}
ConvertWeights(out, geo, absolute_transform, parent, materialIndex, outputVertStartIndices);
skeletonContainer.meshArray.emplace_back(out);
skeletonContainer.MeshArray.emplace_back(out);
SkeletonBoneArray *ba = new SkeletonBoneArray;
for (size_t i = 0; i < out->mNumBones; ++i) {
aiBone *bone = out->mBones[i];
@@ -1560,7 +1563,7 @@ void FBXConverter::ConvertWeightsToSkeleton(aiMesh *out, const MeshGeometry &geo
copyBoneToSkeletonBone(out, bone, skeletonBone);
ba->emplace_back(skeletonBone);
}
skeletonContainer.skeletonBoneToMeshLookup[out] = ba;
skeletonContainer.SkeletonBoneToMeshLookup[out] = ba;
}
void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform,
@@ -1568,6 +1571,8 @@ void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo, const ai
std::vector<unsigned int> *outputVertStartIndices) {
ai_assert(geo.DeformerSkin());
std::vector<size_t> out_indices, index_out_indices, count_out_indices;
const Skin &sk = *geo.DeformerSkin();
std::vector<aiBone*> bones;
@@ -1575,10 +1580,6 @@ void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo, const ai
ai_assert(no_mat_check || outputVertStartIndices);
try {
std::vector<size_t> count_out_indices;
std::vector<size_t> index_out_indices;
std::vector<size_t> out_indices;
// iterate over the sub deformers
for (const Cluster *cluster : sk.Clusters()) {
ai_assert(cluster);
@@ -1750,10 +1751,10 @@ unsigned int FBXConverter::GetDefaultMaterial() {
return defaultMaterialIndex - 1;
}
auto out_mat = new aiMaterial();
aiMaterial *out_mat = new aiMaterial();
materials.push_back(out_mat);
const auto diffuse = aiColor3D(0.8f, 0.8f, 0.8f);
const aiColor3D diffuse = aiColor3D(0.8f, 0.8f, 0.8f);
out_mat->AddProperty(&diffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
aiString s;
@@ -1769,7 +1770,7 @@ unsigned int FBXConverter::ConvertMaterial(const Material &material, const MeshG
const PropertyTable &props = material.Props();
// generate empty output material
auto out_mat = new aiMaterial();
aiMaterial *out_mat = new aiMaterial();
materials_converted[&material] = static_cast<unsigned int>(materials.size());
materials.push_back(out_mat);
@@ -1808,7 +1809,7 @@ unsigned int FBXConverter::ConvertMaterial(const Material &material, const MeshG
unsigned int FBXConverter::ConvertVideo(const Video &video) {
// generate empty output texture
auto out_tex = new aiTexture();
aiTexture *out_tex = new aiTexture();
textures.push_back(out_tex);
// assuming the texture is compressed
+2 -2
View File
@@ -80,8 +80,8 @@ using SkeletonBoneArray = std::vector<aiSkeletonBone *>;
using SkeletonBoneToMesh = std::map<aiMesh*, SkeletonBoneArray*>;
struct SkeletonBoneContainer {
MeshArray meshArray;
SkeletonBoneToMesh skeletonBoneToMeshLookup;
std::vector<aiMesh *> MeshArray;
SkeletonBoneToMesh SkeletonBoneToMeshLookup;
};
class Document;
+16 -60
View File
@@ -365,14 +365,10 @@ float ParseTokenAsFloat(const Token& t, const char*& err_out)
}
if (data[0] == 'F') {
BE_NCONST float id = SafeParse<float>(data+1, t.end());
AI_SWAP4(id);
return id;
return SafeParse<float>(data+1, t.end());
}
else {
BE_NCONST double id = SafeParse<double>(data+1, t.end());
AI_SWAP8(id);
return static_cast<float>(id);
return static_cast<float>( SafeParse<double>(data+1, t.end()) );
}
}
@@ -641,15 +637,9 @@ void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
if (type == 'd') {
const double* d = reinterpret_cast<const double*>(&buff[0]);
for (unsigned int i = 0; i < count3; ++i, d += 3) {
BE_NCONST double val1 = d[0];
BE_NCONST double val2 = d[1];
BE_NCONST double val3 = d[2];
AI_SWAP8(val1);
AI_SWAP8(val2);
AI_SWAP8(val3);
out.emplace_back(static_cast<ai_real>(val1),
static_cast<ai_real>(val2),
static_cast<ai_real>(val3));
out.emplace_back(static_cast<ai_real>(d[0]),
static_cast<ai_real>(d[1]),
static_cast<ai_real>(d[2]));
}
// for debugging
/*for ( size_t i = 0; i < out.size(); i++ ) {
@@ -662,13 +652,7 @@ void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
else if (type == 'f') {
const float* f = reinterpret_cast<const float*>(&buff[0]);
for (unsigned int i = 0; i < count3; ++i, f += 3) {
BE_NCONST float val1 = f[0];
BE_NCONST float val2 = f[1];
BE_NCONST float val3 = f[2];
AI_SWAP4(val1);
AI_SWAP4(val2);
AI_SWAP4(val3);
out.emplace_back(val1,val2,val3);
out.emplace_back(f[0],f[1],f[2]);
}
}
@@ -742,32 +726,16 @@ void ParseVectorDataArray(std::vector<aiColor4D>& out, const Element& el)
if (type == 'd') {
const double* d = reinterpret_cast<const double*>(&buff[0]);
for (unsigned int i = 0; i < count4; ++i, d += 4) {
BE_NCONST double val1 = d[0];
BE_NCONST double val2 = d[1];
BE_NCONST double val3 = d[2];
BE_NCONST double val4 = d[3];
AI_SWAP8(val1);
AI_SWAP8(val2);
AI_SWAP8(val3);
AI_SWAP8(val4);
out.emplace_back(static_cast<float>(val1),
static_cast<float>(val2),
static_cast<float>(val3),
static_cast<float>(val4));
out.emplace_back(static_cast<float>(d[0]),
static_cast<float>(d[1]),
static_cast<float>(d[2]),
static_cast<float>(d[3]));
}
}
else if (type == 'f') {
const float* f = reinterpret_cast<const float*>(&buff[0]);
for (unsigned int i = 0; i < count4; ++i, f += 4) {
BE_NCONST float val1 = f[0];
BE_NCONST float val2 = f[1];
BE_NCONST float val3 = f[2];
BE_NCONST float val4 = f[3];
AI_SWAP4(val1);
AI_SWAP4(val2);
AI_SWAP4(val3);
AI_SWAP4(val4);
out.emplace_back(val1,val2,val3,val4);
out.emplace_back(f[0],f[1],f[2],f[3]);
}
}
return;
@@ -839,21 +807,13 @@ void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el) {
if (type == 'd') {
const double* d = reinterpret_cast<const double*>(&buff[0]);
for (unsigned int i = 0; i < count2; ++i, d += 2) {
BE_NCONST double val1 = d[0];
BE_NCONST double val2 = d[1];
AI_SWAP8(val1);
AI_SWAP8(val2);
out.emplace_back(static_cast<float>(val1),
static_cast<float>(val2));
out.emplace_back(static_cast<float>(d[0]),
static_cast<float>(d[1]));
}
} else if (type == 'f') {
const float* f = reinterpret_cast<const float*>(&buff[0]);
for (unsigned int i = 0; i < count2; ++i, f += 2) {
BE_NCONST float val1 = f[0];
BE_NCONST float val2 = f[1];
AI_SWAP4(val1);
AI_SWAP4(val2);
out.emplace_back(val1,val2);
out.emplace_back(f[0],f[1]);
}
}
@@ -978,17 +938,13 @@ void ParseVectorDataArray(std::vector<float>& out, const Element& el)
if (type == 'd') {
const double* d = reinterpret_cast<const double*>(&buff[0]);
for (unsigned int i = 0; i < count; ++i, ++d) {
BE_NCONST double val = *d;
AI_SWAP8(val);
out.push_back(static_cast<float>(val));
out.push_back(static_cast<float>(*d));
}
}
else if (type == 'f') {
const float* f = reinterpret_cast<const float*>(&buff[0]);
for (unsigned int i = 0; i < count; ++i, ++f) {
BE_NCONST float val = *f;
AI_SWAP4(val);
out.push_back(val);
out.push_back(*f);
}
}
+3 -3
View File
@@ -162,7 +162,7 @@ aiMesh *IRRImporter::BuildSingleQuadMesh(const SkyboxVertex &v1,
}
// ------------------------------------------------------------------------------------------------
void IRRImporter::BuildSkybox(MeshArray &meshes, std::vector<aiMaterial *> materials) {
void IRRImporter::BuildSkybox(std::vector<aiMesh *> &meshes, std::vector<aiMaterial *> materials) {
// Update the material of the skybox - replace the name and disable shading for skyboxes.
for (unsigned int i = 0; i < 6; ++i) {
aiMaterial *out = (aiMaterial *)(*(materials.end() - (6 - i)));
@@ -602,7 +602,7 @@ void SetupMapping(aiMaterial *mat, aiTextureMapping mode, const aiVector3D &axis
// ------------------------------------------------------------------------------------------------
void IRRImporter::GenerateGraph(Node *root, aiNode *rootOut, aiScene *scene,
BatchLoader &batch,
MeshArray &meshes,
std::vector<aiMesh *> &meshes,
std::vector<aiNodeAnim *> &anims,
std::vector<AttachmentInfo> &attach,
std::vector<aiMaterial *> &materials,
@@ -1283,7 +1283,7 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
std::vector<aiNodeAnim *> anims;
std::vector<aiMaterial *> materials;
std::vector<AttachmentInfo> attach;
MeshArray meshes;
std::vector<aiMesh *> meshes;
// try to guess how much storage we'll need
anims.reserve(guessedAnimCnt + (guessedAnimCnt >> 2));
+2 -2
View File
@@ -229,7 +229,7 @@ private:
/// Fill the scene-graph recursively
void GenerateGraph(Node *root, aiNode *rootOut, aiScene *scene,
BatchLoader &batch,
MeshArray &meshes,
std::vector<aiMesh *> &meshes,
std::vector<aiNodeAnim *> &anims,
std::vector<AttachmentInfo> &attach,
std::vector<aiMaterial *> &materials,
@@ -248,7 +248,7 @@ private:
/// @param meshes Receives 6 output meshes
/// @param materials The last 6 materials are assigned to the newly
/// created meshes. The names of the materials are adjusted.
void BuildSkybox(MeshArray &meshes,
void BuildSkybox(std::vector<aiMesh *> &meshes,
std::vector<aiMaterial *> materials);
// -------------------------------------------------------------------
+17 -17
View File
@@ -121,7 +121,7 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
// final data
std::vector<aiMaterial *> materials;
MeshArray meshes;
std::vector<aiMesh *> meshes;
materials.reserve(5);
meshes.reserve(5);
@@ -433,24 +433,24 @@ void IRRMeshImporter::ParseBufferVertices(const char *sz, const char *end, Verte
aiColor4D c;
// Read the vertex position
sz = fast_atoreal_move(sz, temp.x);
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
SkipSpaces(&sz, end);
sz = fast_atoreal_move(sz, temp.y);
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
SkipSpaces(&sz, end);
sz = fast_atoreal_move(sz, temp.z);
sz = fast_atoreal_move<float>(sz, (float &)temp.z);
SkipSpaces(&sz, end);
vertices.push_back(temp);
// Read the vertex normals
sz = fast_atoreal_move(sz, temp.x);
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
SkipSpaces(&sz, end);
sz = fast_atoreal_move(sz, temp.y);
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
SkipSpaces(&sz, end);
sz = fast_atoreal_move(sz, temp.z);
sz = fast_atoreal_move<float>(sz, (float &)temp.z);
SkipSpaces(&sz, end);
normals.push_back(temp);
@@ -466,10 +466,10 @@ void IRRMeshImporter::ParseBufferVertices(const char *sz, const char *end, Verte
SkipSpaces(&sz, end);
// read the first UV coordinate set
sz = fast_atoreal_move(sz, temp.x);
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
SkipSpaces(&sz, end);
sz = fast_atoreal_move(sz, temp.y);
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
SkipSpaces(&sz, end);
temp.z = 0.f;
temp.y = 1.f - temp.y; // DX to OGL
@@ -479,35 +479,35 @@ void IRRMeshImporter::ParseBufferVertices(const char *sz, const char *end, Verte
// So by definition, all buffers have either UV2 or tangents or neither
// read the (optional) second UV coordinate set
if (vertexFormat == VertexFormat::t2coord) {
sz = fast_atoreal_move(sz, temp.x);
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
SkipSpaces(&sz, end);
sz = fast_atoreal_move(sz, temp.y);
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
temp.y = 1.f - temp.y; // DX to OGL
UV2s.push_back(temp);
}
// read optional tangent and bitangent vectors
else if (vertexFormat == VertexFormat::tangent) {
// tangents
sz = fast_atoreal_move(sz, temp.x);
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
SkipSpaces(&sz, end);
sz = fast_atoreal_move(sz, temp.z);
sz = fast_atoreal_move<float>(sz, (float &)temp.z);
SkipSpaces(&sz, end);
sz = fast_atoreal_move(sz, temp.y);
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
SkipSpaces(&sz, end);
temp.y *= -1.0f;
tangents.push_back(temp);
// bitangents
sz = fast_atoreal_move(sz, temp.x);
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
SkipSpaces(&sz, end);
sz = fast_atoreal_move(sz, temp.z);
sz = fast_atoreal_move<float>(sz, (float &)temp.z);
SkipSpaces(&sz, end);
sz = fast_atoreal_move(sz, temp.y);
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
SkipSpaces(&sz, end);
temp.y *= -1.0f;
bitangents.push_back(temp);
+3 -3
View File
@@ -139,21 +139,21 @@ void IrrlichtBase::ReadVectorProperty(VectorProperty &out, pugi::xml_node& vecto
const char *end = ptr + len;
SkipSpaces(&ptr, end);
ptr = fast_atoreal_move(ptr, out.value.x);
ptr = fast_atoreal_move<float>(ptr, (float &)out.value.x);
SkipSpaces(&ptr, end);
if (',' != *ptr) {
ASSIMP_LOG_ERROR("IRR(MESH): Expected comma in vector definition");
} else {
SkipSpaces(ptr + 1, &ptr, end);
}
ptr = fast_atoreal_move(ptr, out.value.y);
ptr = fast_atoreal_move<float>(ptr, (float &)out.value.y);
SkipSpaces(&ptr, end);
if (',' != *ptr) {
ASSIMP_LOG_ERROR("IRR(MESH): Expected comma in vector definition");
} else {
SkipSpaces(ptr + 1, &ptr, end);
}
ptr = fast_atoreal_move(ptr, out.value.z);
ptr = fast_atoreal_move<float>(ptr, (float &)out.value.z);
}
}
}
+1 -1
View File
@@ -239,7 +239,7 @@ void LWOImporter::InternReadFile(const std::string &pFile,
ResolveClips();
// now process all layers and build meshes and nodes
MeshArray apcMeshes;
std::vector<aiMesh *> apcMeshes;
std::map<uint16_t, aiNode *> apcNodes;
apcMeshes.reserve(mLayers->size() * std::min(((unsigned int)mSurfaces->size() / 2u), 1u));
+12 -12
View File
@@ -208,9 +208,9 @@ void LWSImporter::ReadEnvelope(const LWS::Element &dad, LWO::Envelope &fill) {
float f;
SkipSpaces(&c, end);
c = fast_atoreal_move(c, key.value);
c = fast_atoreal_move<float>(c, key.value);
SkipSpaces(&c, end);
c = fast_atoreal_move(c, f);
c = fast_atoreal_move<float>(c, f);
key.time = f;
@@ -242,7 +242,7 @@ void LWSImporter::ReadEnvelope(const LWS::Element &dad, LWO::Envelope &fill) {
}
for (unsigned int i = 0; i < num; ++i) {
SkipSpaces(&c, end);
c = fast_atoreal_move(c, key.params[i]);
c = fast_atoreal_move<float>(c, key.params[i]);
}
} else if ((*it).tokens[0] == "Behaviors") {
SkipSpaces(&c, end);
@@ -284,11 +284,11 @@ void LWSImporter::ReadEnvelope_Old(std::list<LWS::Element>::const_iterator &it,c
// parse value and time, skip the rest for the moment.
LWO::Key key;
const char *c = fast_atoreal_move((*it).tokens[0].c_str(), key.value);
const char *c = fast_atoreal_move<float>((*it).tokens[0].c_str(), key.value);
const char *end = c + (*it).tokens[0].size();
SkipSpaces(&c, end);
float f;
fast_atoreal_move((*it).tokens[0].c_str(), f);
fast_atoreal_move<float>((*it).tokens[0].c_str(), f);
key.time = f;
envl.keys.emplace_back(key);
@@ -775,7 +775,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
ASSIMP_LOG_ERROR("LWS: envelopes for LightIntensity not supported, set to 1.0");
nodes.back().lightIntensity = (ai_real)1.0;
} else {
fast_atoreal_move(c, nodes.back().lightIntensity);
fast_atoreal_move<float>(c, nodes.back().lightIntensity);
}
}
}
@@ -816,11 +816,11 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightColor\'");
} else {
c = fast_atoreal_move(c, nodes.back().lightColor.r);
c = fast_atoreal_move<float>(c, (float &)nodes.back().lightColor.r);
SkipSpaces(&c, end);
c = fast_atoreal_move(c, nodes.back().lightColor.g);
c = fast_atoreal_move<float>(c, (float &)nodes.back().lightColor.g);
SkipSpaces(&c, end);
c = fast_atoreal_move(c, nodes.back().lightColor.b);
c = fast_atoreal_move<float>(c, (float &)nodes.back().lightColor.b);
}
}
@@ -829,11 +829,11 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
if (nodes.empty()) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'PivotPosition\'");
} else {
c = fast_atoreal_move(c, nodes.back().pivotPos.x);
c = fast_atoreal_move<float>(c, (float &)nodes.back().pivotPos.x);
SkipSpaces(&c, end);
c = fast_atoreal_move(c, nodes.back().pivotPos.y);
c = fast_atoreal_move<float>(c, (float &)nodes.back().pivotPos.y);
SkipSpaces(&c, end);
c = fast_atoreal_move(c, nodes.back().pivotPos.z);
c = fast_atoreal_move<float>(c, (float &)nodes.back().pivotPos.z);
// Mark pivotPos as set
nodes.back().isPivotSet = true;
}
+8 -8
View File
@@ -246,11 +246,11 @@ inline void AI_MD5_READ_TRIPLE(aiVector3D &vec, const char **sz, const char *buf
return;
++*sz;
AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
*sz = fast_atoreal_move(*sz, vec.x);
*sz = fast_atoreal_move<float>(*sz, (float &)vec.x);
AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
*sz = fast_atoreal_move(*sz, vec.y);
*sz = fast_atoreal_move<float>(*sz, (float &)vec.y);
AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
*sz = fast_atoreal_move(*sz, vec.z);
*sz = fast_atoreal_move<float>(*sz, (float &)vec.z);
AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
if (')' != **sz) {
MD5Parser::ReportWarning("Unexpected token: ) was expected", linenumber);
@@ -377,9 +377,9 @@ MD5MeshParser::MD5MeshParser(SectionArray &mSections) {
if ('(' != *sz++)
MD5Parser::ReportWarning("Unexpected token: ( was expected", elem.iLineNumber);
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
sz = fast_atoreal_move(sz, vert.mUV.x);
sz = fast_atoreal_move<float>(sz, (float &)vert.mUV.x);
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
sz = fast_atoreal_move(sz, vert.mUV.y);
sz = fast_atoreal_move<float>(sz, (float &)vert.mUV.y);
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
if (')' != *sz++)
MD5Parser::ReportWarning("Unexpected token: ) was expected", elem.iLineNumber);
@@ -415,7 +415,7 @@ MD5MeshParser::MD5MeshParser(SectionArray &mSections) {
WeightDesc &weight = desc.mWeights[idx];
weight.mBone = strtoul10(sz, &sz);
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
sz = fast_atoreal_move(sz, weight.mWeight);
sz = fast_atoreal_move<float>(sz, weight.mWeight);
AI_MD5_READ_TRIPLE(weight.vOffsetPosition, &sz, elem.end, elem.iLineNumber);
}
}
@@ -486,7 +486,7 @@ MD5AnimParser::MD5AnimParser(SectionArray &mSections) {
const char *sz = elem.szStart;
while (SkipSpacesAndLineEnd(&sz, elem.end)) {
float f;
sz = fast_atoreal_move(sz, f);
sz = fast_atoreal_move<float>(sz, f);
desc.mValues.push_back(f);
}
}
@@ -503,7 +503,7 @@ MD5AnimParser::MD5AnimParser(SectionArray &mSections) {
} else if ((*iter).mName == "numAnimatedComponents") {
mAnimatedBones.reserve(strtoul10((*iter).mGlobalValue.c_str()));
} else if ((*iter).mName == "frameRate") {
fast_atoreal_move((*iter).mGlobalValue.c_str(), fFrameRate);
fast_atoreal_move<float>((*iter).mGlobalValue.c_str(), fFrameRate);
}
}
ASSIMP_LOG_DEBUG("MD5AnimParser end");
+2 -8
View File
@@ -51,7 +51,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "MDLLoader.h"
#include "AssetLib/MD2/MD2FileData.h"
#include "HalfLife/HL1MDLLoader.h"
#include "HalfLife/HL1FileData.h"
#include "MDLDefaultColorMap.h"
#include <assimp/StringUtils.h>
@@ -1405,10 +1404,10 @@ void MDLImporter::InternReadFile_3DGS_MDL7() {
sharedData.apcOutBones = this->LoadBones_3DGS_MDL7();
// vector to held all created meshes
MeshArray *avOutList;
std::vector<aiMesh *> *avOutList;
// 3 meshes per group - that should be OK for most models
avOutList = new MeshArray[pcHeader->groups_num];
avOutList = new std::vector<aiMesh *>[pcHeader->groups_num];
for (uint32_t i = 0; i < pcHeader->groups_num; ++i)
avOutList[i].reserve(3);
@@ -1981,11 +1980,6 @@ void MDLImporter::InternReadFile_HL1(const std::string &pFile, const uint32_t iM
if (iMagicWord == AI_MDL_MAGIC_NUMBER_BE_HL2b || iMagicWord == AI_MDL_MAGIC_NUMBER_LE_HL2b)
throw DeadlyImportError("Impossible to properly load a model from an MDL sequence file.");
// Check if the buffer is large enough to hold the header
if (iFileSize < sizeof(HalfLife::Header_HL1)) {
throw DeadlyImportError("HL1 MDL file is too small to contain header.");
}
// Read the MDL file.
HalfLife::HL1MDLLoader loader(
pScene,
+1 -1
View File
@@ -86,7 +86,7 @@ const aiImporterDesc *NFFImporter::GetInfo() const {
// ------------------------------------------------------------------------------------------------
#define AI_NFF_PARSE_FLOAT(f) \
SkipSpaces(&sz, lineEnd); \
if (!IsLineEnd(*sz)) sz = fast_atoreal_move(sz, (ai_real &)f);
if (!IsLineEnd(*sz)) sz = fast_atoreal_move<ai_real>(sz, (ai_real &)f);
// ------------------------------------------------------------------------------------------------
#define AI_NFF_PARSE_TRIPLE(v) \
+11 -11
View File
@@ -212,14 +212,14 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// stop at dimensions: this allows loading 1D or 2D coordinate vertices
for (unsigned int dim = 0; dim < dimensions; ++dim) {
SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move(sz, *vec[dim]);
sz = fast_atoreal_move<ai_real>(sz, *vec[dim]);
}
// if has homogeneous coordinate, divide others by this one
if (hasHomogenous) {
SkipSpaces(&sz, lineEnd);
ai_real w = 1.;
sz = fast_atoreal_move(sz, w);
sz = fast_atoreal_move<ai_real>(sz, w);
for (unsigned int dim = 0; dim < dimensions; ++dim) {
*(vec[dim]) /= w;
}
@@ -229,11 +229,11 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
if (hasNormals) {
aiVector3D &n = mesh->mNormals[i];
SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move(sz, n.x);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)n.x);
SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move(sz, n.y);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)n.y);
SkipSpaces(&sz, lineEnd);
fast_atoreal_move(sz, n.z);
fast_atoreal_move<ai_real>(sz, (ai_real &)n.z);
}
// reading colors is a pain because the specification says it can be
@@ -243,22 +243,22 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
if (hasColors) {
aiColor4D &c = mesh->mColors[0][i];
SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move(sz, c.r);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)c.r);
if (*sz != '#' && *sz != '\n' && *sz != '\r') {
SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move(sz, c.g);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)c.g);
} else {
c.g = 0.;
}
if (*sz != '#' && *sz != '\n' && *sz != '\r') {
SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move(sz, c.b);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)c.b);
} else {
c.b = 0.;
}
if (*sz != '#' && *sz != '\n' && *sz != '\r') {
SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move(sz, c.a);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)c.a);
} else {
c.a = 1.;
}
@@ -266,9 +266,9 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
if (hasTexCoord) {
aiVector3D &t = mesh->mTextureCoords[0][i];
SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move(sz, t.x);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)t.x);
SkipSpaces(&sz, lineEnd);
fast_atoreal_move(sz, t.y);
fast_atoreal_move<ai_real>(sz, (ai_real &)t.y);
}
}
+3 -5
View File
@@ -4,6 +4,7 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2025, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -395,12 +396,9 @@ void ObjExporter::AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4
// ------------------------------------------------------------------------------------------------
void ObjExporter::AddNode(const aiNode* nd, const aiMatrix4x4& mParent, bool merge_identical_vertices) {
if (nd == nullptr) {
return;
}
const aiMatrix4x4& mAbs = mParent * nd->mTransformation;
aiMesh *cm{nullptr};
aiMesh *cm( nullptr );
for(unsigned int i = 0; i < nd->mNumMeshes; ++i) {
cm = pScene->mMeshes[nd->mMeshes[i]];
if (nullptr != cm) {
+23 -27
View File
@@ -165,23 +165,21 @@ struct Material {
//! Ambient color
aiColor3D ambient;
//! Diffuse color
aiColor3D diffuse = aiColor3D(0.6f, 0.6f, 0.6f);
aiColor3D diffuse;
//! Specular color
aiColor3D specular;
//! Emissive color
aiColor3D emissive;
//! Alpha value
ai_real alpha = ai_real(1.0);
ai_real alpha;
//! Shineness factor
ai_real shineness = ai_real(0.0);
ai_real shineness;
//! Illumination model
int illumination_model = 1;
int illumination_model;
//! Index of refraction
ai_real ior = ai_real(1.0);
ai_real ior;
//! Transparency color
aiColor3D transparent = aiColor3D(1.0f, 1.0f, 1.0f);
//! Ambient occlusion
Maybe<ai_real> ambient_occlusion;
aiColor3D transparent;
//! PBR Roughness
Maybe<ai_real> roughness;
@@ -189,33 +187,31 @@ struct Material {
Maybe<ai_real> metallic;
//! PBR Metallic
Maybe<aiColor3D> sheen;
//! PBR Sheen: an additional grazing component, primarily intended for cloth.
Maybe<ai_real> sheen_grazing;
//! PBR Sheen Tint: amount to tint sheen towards base color.
Maybe<ai_real> sheen_tint;
//! PBR Clearcoat
Maybe<ai_real> clearcoat;
//! PBR Clearcoat Thickness
Maybe<ai_real> clearcoat_thickness;
//! PBR Clearcoat Rougness
Maybe<ai_real> clearcoat_roughness;
//! PBR clearcoatGloss: controls clearcoat glossiness (0 = a “satin” appearance, 1 = a “gloss” appearance).
Maybe<ai_real> clearcoat_gloss;
//! PBR Anisotropy
ai_real anisotropy = ai_real(0.0);
//! PBR Anisotropy Rotation
Maybe<ai_real> anisotropy_rotation;
//! PBR Subsurface Scattering
Maybe<ai_real> subsurface_scattering;
//! PBR Specular Tint: a concession for artistic control that tints incident specular towards the base color.
Maybe<ai_real> specular_tint;
// See: https://disneyanimation.com/publications/physically-based-shading-at-disney/
ai_real anisotropy;
//! bump map multiplier (normal map scalar)(-bm)
ai_real bump_multiplier = ai_real(1.0);
//! bump map multipler (normal map scalar)(-bm)
ai_real bump_multiplier;
//! Constructor
Material() {
Material() :
diffuse(0.6f, 0.6f, 0.6f),
alpha(ai_real(1.0)),
shineness(ai_real(0.0)),
illumination_model(1),
ior(ai_real(1.0)),
transparent(1.0f, 1.0, 1.0),
roughness(),
metallic(),
sheen(),
clearcoat_thickness(),
clearcoat_roughness(),
anisotropy(ai_real(0.0)),
bump_multiplier(ai_real(1.0)) {
std::fill_n(clamp, static_cast<unsigned int>(TextureTypeCount), false);
}
+8 -114
View File
@@ -235,64 +235,24 @@ void ObjFileMtlImporter::load() {
++m_DataIt;
if (m_pModel->mCurrentMaterial != nullptr)
getFloatValue(m_pModel->mCurrentMaterial->clearcoat_roughness);
} else if (*m_DataIt == 't') {
++m_DataIt;
if (m_pModel->mCurrentMaterial != nullptr)
getFloatValue(m_pModel->mCurrentMaterial->clearcoat_thickness);
} else {
if (m_pModel->mCurrentMaterial != nullptr)
getFloatValue(m_pModel->mCurrentMaterial->clearcoat);
getFloatValue(m_pModel->mCurrentMaterial->clearcoat_thickness);
}
break;
}
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
}
break;
case 'm': // Texture or metallic
{
// Save start of token (after 'm')
auto tokenStart = m_DataIt; // points to 'm'
auto tokenEnd = getNextToken(m_DataIt, m_DataItEnd); // move iterator to end of token
std::string keyword(tokenStart, tokenEnd);
m_DataIt = tokenEnd; // advance iterator
if (keyword.compare(0, 3, "map") == 0) {
// starts with "map", treat as texture map
m_DataIt = tokenStart;
getTexture();
} else if (keyword == "metallic" || keyword == "metal" || keyword == "metalness") {
// parse metallic float value instead of texture
getFloatIfMaterialValid(&ObjFile::Material::metallic);
}
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} break;
case 'm': // Texture
case 'b': // quick'n'dirty - for 'bump' sections
case 'r': // quick'n'dirty - for 'refl' sections
{
getTexture();
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} break;
case 'r': // refl (map) or roughness (float)
{
auto tokenStart = m_DataIt; // points to 'r'
auto tokenEnd = getNextToken(m_DataIt, m_DataItEnd);
std::string keyword(tokenStart, tokenEnd);
m_DataIt = tokenEnd;
if (keyword == "roughness" || keyword == "rough") {
getFloatIfMaterialValid(&ObjFile::Material::roughness);
} else if (keyword == "refl" || keyword == "reflection") {
m_DataIt = tokenStart;
getTexture();
}
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} break;
case 'i': // Illumination model
{
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
@@ -301,60 +261,11 @@ void ObjFileMtlImporter::load() {
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} break;
case 'a': {
auto tokenStart = m_DataIt;
auto tokenEnd = getNextToken(m_DataIt, m_DataItEnd);
std::string keyword(tokenStart, tokenEnd);
m_DataIt = tokenEnd;
if (keyword == "aniso" || keyword == "anisotropy") {
getFloatIfMaterialValid(&ObjFile::Material::anisotropy);
} else if (keyword == "ao") {
getFloatIfMaterialValid(&ObjFile::Material::ambient_occlusion);
} else if (keyword == "anisor" || ai_stdStrToLower(keyword) == "anisotropicrotation") {
getFloatIfMaterialValid(&ObjFile::Material::anisotropy_rotation);
} else {
ASSIMP_LOG_WARN("Unhandled keyword: ", keyword );
}
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} break;
case 's': {
auto tokenStart = m_DataIt;
auto tokenEnd = getNextToken(m_DataIt, m_DataItEnd);
std::string keyword(tokenStart, tokenEnd);
m_DataIt = tokenEnd;
if (keyword == "subsurface" || keyword == "scattering") {
getFloatIfMaterialValid(&ObjFile::Material::subsurface_scattering);
} else if (ai_stdStrToLower(keyword) == "speculartint") {
getFloatIfMaterialValid(&ObjFile::Material::specular_tint);
} else if (keyword == "sheen") {
getFloatIfMaterialValid(&ObjFile::Material::sheen_grazing);
} else if (ai_stdStrToLower(keyword) == "sheentint") {
getFloatIfMaterialValid(&ObjFile::Material::sheen_tint);
} else {
ASSIMP_LOG_WARN("Unhandled keyword: ", keyword );
}
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} break;
case 'c': {
auto tokenStart = m_DataIt;
auto tokenEnd = getNextToken(m_DataIt, m_DataItEnd);
std::string keyword(tokenStart, tokenEnd);
m_DataIt = tokenEnd;
if (ai_stdStrToLower(keyword) == "clearcoat") {
getFloatIfMaterialValid(&ObjFile::Material::clearcoat);
} else if (ai_stdStrToLower(keyword) == "clearcoatgloss") {
getFloatIfMaterialValid(&ObjFile::Material::clearcoat_gloss);
} else {
ASSIMP_LOG_WARN("Unhandled keyword: ", keyword );
}
case 'a': // Anisotropy
{
++m_DataIt;
if (m_pModel->mCurrentMaterial != nullptr)
getFloatValue(m_pModel->mCurrentMaterial->anisotropy);
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} break;
@@ -421,23 +332,6 @@ void ObjFileMtlImporter::getFloatValue(Maybe<ai_real> &value) {
value = Maybe<ai_real>();
}
// -------------------------------------------------------------------
// Writes a loaded single float value if material not null
void ObjFileMtlImporter::getFloatIfMaterialValid(ai_real ObjFile::Material::*member) {
if (m_pModel != nullptr && m_pModel->mCurrentMaterial != nullptr) {
// This will call getFloatValue(ai_real&)
getFloatValue(m_pModel->mCurrentMaterial->*member);
}
}
// -------------------------------------------------------------------
void ObjFileMtlImporter::getFloatIfMaterialValid(Maybe<ai_real> ObjFile::Material::*member) {
// It can directly access `m_pModel` because it's part of the class
if (m_pModel != nullptr && m_pModel->mCurrentMaterial != nullptr) {
getFloatValue(m_pModel->mCurrentMaterial->*member);
}
}
// -------------------------------------------------------------------
// Creates a material from loaded data.
void ObjFileMtlImporter::createMaterial() {
-2
View File
@@ -87,8 +87,6 @@ private:
/// Gets a float value from data.
void getFloatValue(ai_real &value);
void getFloatValue(Maybe<ai_real> &value);
void getFloatIfMaterialValid(ai_real ObjFile::Material::*member);
void getFloatIfMaterialValid(Maybe<ai_real> ObjFile::Material::*member);
/// Creates a new material from loaded data.
void createMaterial();
/// Get texture name from loaded data.
-7
View File
@@ -121,13 +121,6 @@ void ObjFileParser::parseFile(IOStreamBuffer<char> &streamBuffer) {
m_DataItEnd = buffer.end();
mEnd = &buffer[buffer.size() - 1] + 1;
if (processed == 0 && std::distance(m_DataIt, m_DataItEnd) >= 3 &&
static_cast<unsigned char>(*m_DataIt) == 0xEF &&
static_cast<unsigned char>(*(m_DataIt + 1)) == 0xBB &&
static_cast<unsigned char>(*(m_DataIt + 2)) == 0xBF) {
m_DataIt += 3; // skip BOM
}
// Handle progress reporting
const size_t filePos(streamBuffer.getFilePos());
if (lastFilePos < filePos) {
+2 -2
View File
@@ -828,13 +828,13 @@ bool PLY::PropertyInstance::ParseValue(const char *&pCur,
// technically this should cast to float, but people tend to use float descriptors for double data
// this is the best way to not risk losing precision on import and it doesn't hurt to do this
ai_real f;
pCur = fast_atoreal_move(pCur, f);
pCur = fast_atoreal_move<ai_real>(pCur, f);
out->fFloat = (ai_real)f;
break;
case EDT_Double:
double d;
pCur = fast_atoreal_move(pCur, d);
pCur = fast_atoreal_move<double>(pCur, d);
out->fDouble = (double)d;
break;
+1 -1
View File
@@ -270,7 +270,7 @@ void Q3BSPFileImporter::CreateNodes(const Q3BSP::Q3BSPModel *pModel, aiScene *pS
}
unsigned int matIdx(0);
MeshArray MeshArray;
std::vector<aiMesh *> MeshArray;
std::vector<aiNode *> NodeArray;
for (FaceMapIt it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end(); ++it) {
std::vector<Q3BSP::sQ3BSPFace *> *pArray = (*it).second;
+1 -1
View File
@@ -136,7 +136,7 @@ void RAWImporter::InternReadFile(const std::string &pFile,
unsigned int num;
for (num = 0; num < 12; ++num) {
if (!SkipSpaces(&sz, end) || !IsNumeric(*sz)) break;
sz = fast_atoreal_move(sz, data[num]);
sz = fast_atoreal_move<float>(sz, data[num]);
}
if (num != 12 && num != 9) {
ASSIMP_LOG_ERROR("A line may have either 9 or 12 floats and an optional texture");
+1 -1
View File
@@ -116,7 +116,7 @@ struct SIBObject {
struct SIB {
std::vector<aiMaterial *> mtls;
MeshArray meshes;
std::vector<aiMesh *> meshes;
std::vector<aiLight *> lights;
std::vector<SIBObject> objs, insts;
};
+1 -1
View File
@@ -982,7 +982,7 @@ bool SMDImporter::ParseFloat(const char *szCurrent, const char **szCurrentOut, c
return false;
}
*szCurrentOut = fast_atoreal_move(szCurrent,out);
*szCurrentOut = fast_atoreal_move<float>(szCurrent,out);
return true;
}
+1 -1
View File
@@ -404,7 +404,7 @@ std::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*& i
for(;*cur && *cur != ',' && *cur != ')' && !IsSpace(*cur);++cur) {
if (*cur == '.') {
double f;
inout = fast_atoreal_move(start,f);
inout = fast_atoreal_move<double>(start,f);
return std::make_shared<EXPRESS::REAL>(f);
}
}
+7 -7
View File
@@ -222,7 +222,7 @@ void STLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// ------------------------------------------------------------------------------------------------
// Read an ASCII STL file
void STLImporter::LoadASCIIFile(aiNode *root) {
MeshArray meshes;
std::vector<aiMesh *> meshes;
std::vector<aiNode *> nodes;
const char *sz = mBuffer;
const char *bufferEnd = mBuffer + mFileSize;
@@ -294,11 +294,11 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
aiVector3D vn;
sz += 7;
SkipSpaces(&sz, bufferEnd);
sz = fast_atoreal_move(sz, vn.x);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn.x);
SkipSpaces(&sz, bufferEnd);
sz = fast_atoreal_move(sz, vn.y);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn.y);
SkipSpaces(&sz, bufferEnd);
sz = fast_atoreal_move(sz, vn.z);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn.z);
normalBuffer.emplace_back(vn);
normalBuffer.emplace_back(vn);
normalBuffer.emplace_back(vn);
@@ -315,11 +315,11 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
SkipSpaces(&sz, bufferEnd);
positionBuffer.emplace_back();
aiVector3D *vn = &positionBuffer.back();
sz = fast_atoreal_move(sz, vn->x);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn->x);
SkipSpaces(&sz, bufferEnd);
sz = fast_atoreal_move(sz, vn->y);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn->y);
SkipSpaces(&sz, bufferEnd);
sz = fast_atoreal_move(sz, vn->z);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn->z);
faceVertexCounter++;
}
} else if (!::strncmp(sz, "endsolid", 8)) {
+3 -3
View File
@@ -383,11 +383,11 @@ void UnrealImporter::InternReadFile(const std::string &pFile,
for (; !IsLineEnd(*data); ++data) {
if (data[0] == 'X' && data[1] == '=') {
data = fast_atoreal_move(data + 2, nd->mTransformation.a1);
data = fast_atoreal_move<float>(data + 2, (float &)nd->mTransformation.a1);
} else if (data[0] == 'Y' && data[1] == '=') {
data = fast_atoreal_move(data + 2, nd->mTransformation.b2);
data = fast_atoreal_move<float>(data + 2, (float &)nd->mTransformation.b2);
} else if (data[0] == 'Z' && data[1] == '=') {
data = fast_atoreal_move(data + 2, nd->mTransformation.c3);
data = fast_atoreal_move<float>(data + 2, (float &)nd->mTransformation.c3);
}
}
}
+1 -1
View File
@@ -219,7 +219,7 @@ void XFileImporter::CreateMeshes(aiScene *pScene, aiNode *pNode, const std::vect
}
// create a mesh for each mesh-material combination in the source node
MeshArray meshes;
std::vector<aiMesh *> meshes;
for (unsigned int a = 0; a < pMeshes.size(); ++a) {
XFile::Mesh *sourceMesh = pMeshes[a];
if (nullptr == sourceMesh) {
+1 -1
View File
@@ -1277,7 +1277,7 @@ ai_real XFileParser::ReadFloat() {
}
ai_real result = 0.0;
mP = fast_atoreal_move(mP, result);
mP = fast_atoreal_move<ai_real>(mP, result);
CheckForSeparator();
+4 -10
View File
@@ -128,17 +128,13 @@ void X3DGeoHelper::rect_parallel_epiped(const aiVector3D &pSize, std::list<aiVec
#undef MESH_RectParallelepiped_CREATE_VERT
static constexpr int InvalidIndex = -1;
void X3DGeoHelper::coordIdx_str2faces_arr(const std::vector<int32_t> &pCoordIdx, std::vector<aiFace> &pFaces, unsigned int &pPrimitiveTypes) {
std::vector<int32_t> f_data(pCoordIdx);
std::vector<unsigned int> inds;
unsigned int prim_type = 0;
if (!f_data.empty()) {
if (f_data.back() != InvalidIndex) {
f_data.push_back(InvalidIndex);
}
if (f_data.back() != (-1)) {
f_data.push_back(-1);
}
// reserve average size.
@@ -195,10 +191,8 @@ mg_m_err:
void X3DGeoHelper::coordIdx_str2lines_arr(const std::vector<int32_t> &pCoordIdx, std::vector<aiFace> &pFaces) {
std::vector<int32_t> f_data(pCoordIdx);
if (!f_data.empty()) {
if (f_data.back() != InvalidIndex) {
f_data.push_back(InvalidIndex);
}
if (f_data.back() != (-1)) {
f_data.push_back(-1);
}
// reserve average size.
+1 -1
View File
@@ -139,7 +139,7 @@ void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
ReadWorld(*worldNode, scope);
}
MeshArray &meshes = scope.meshes_linear;
std::vector<aiMesh *> &meshes = scope.meshes_linear;
std::vector<aiMaterial *> &materials = scope.materials_linear;
if (meshes.empty() || materials.empty()) {
ThrowException("failed to extract data from XGL file, no meshes loaded");
+1 -1
View File
@@ -192,7 +192,7 @@ static bool CheckValidFacesIndices(const aiFace *faces, unsigned nFaces, unsigne
}
void glTFImporter::ImportMeshes(Asset &r) {
MeshArray meshes;
std::vector<aiMesh *> meshes;
unsigned int k = 0;
meshOffsets.clear();
+3 -16
View File
@@ -59,7 +59,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Header files, standard library.
#include <cinttypes>
#include <cmath>
#include <limits>
#include <memory>
#include <iostream>
@@ -1239,25 +1238,13 @@ void glTF2Exporter::ExportMeshes() {
}
/******************** Tangents ********************/
if (nullptr != aim->mTangents && nullptr != aim->mBitangents) {
// Find the handedness by calculating the bitangent without the handedness factor,
// the use a dot product to find out if the original bitangent was inverted (multiplied
// by a factor of -1.0) or not (multiplied by 1.0)
std::vector<ai_real> tangentsWithHandedness(aim->mNumVertices * 4);
if (nullptr != aim->mTangents) {
for (uint32_t i = 0; i < aim->mNumVertices; ++i) {
aiVector3D calculatedBitangent = aim->mNormals[i] ^ aim->mTangents[i];
ai_real bitangentDotProduct = calculatedBitangent * aim->mBitangents[i];
ai_real handedness = std::copysign(1.0, bitangentDotProduct);
aim->mTangents[i].NormalizeSafe();
tangentsWithHandedness[i * 4] = aim->mTangents[i][0];
tangentsWithHandedness[i * 4 + 1] = aim->mTangents[i][1];
tangentsWithHandedness[i * 4 + 2] = aim->mTangents[i][2];
tangentsWithHandedness[i * 4 + 3] = handedness;
}
Ref<Accessor> t = ExportData(
*mAsset, meshId, b, aim->mNumVertices, &tangentsWithHandedness[0], AttribType::VEC4,
AttribType::VEC4, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER
*mAsset, meshId, b, aim->mNumVertices, aim->mTangents, AttribType::VEC3,
AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER
);
if (t) {
p.attributes.tangent.push_back(t);
-15
View File
@@ -347,21 +347,6 @@ struct ReadHelper<int64_t> {
}
};
#ifdef __APPLE__
// On Mac size_t and uint64_t are not the same, so we need a specialized version
// here to properly parse byteOffset and other parameters > 2^31
// On Windows and Linux the types match andno additional specialization is required
template <>
struct ReadHelper<size_t> {
static bool Read(Value &val, size_t &out) {
return val.IsInt64() ? out = val.GetInt64(), true : false;
}
};
#endif
template <class T>
inline static bool ReadValue(Value &val, T &out) {
return ReadHelper<T>::Read(val, out);
+9
View File
@@ -740,6 +740,8 @@ SET( PostProcessing_SRCS
PostProcessing/GenFaceNormalsProcess.h
PostProcessing/GenVertexNormalsProcess.cpp
PostProcessing/GenVertexNormalsProcess.h
PostProcessing/GenerateMikkTSpaceTangents.cpp
PostProcessing/GenerateMikkTSpaceTangents.h
PostProcessing/PretransformVertices.cpp
PostProcessing/PretransformVertices.h
PostProcessing/ImproveCacheLocality.cpp
@@ -1170,6 +1172,12 @@ ENDIF()
SOURCE_GROUP( Contrib\\Poly2Tri FILES ${Poly2Tri_SRCS})
#ENDIF()
# mikktspacetangets
SET( MikkTSpaceTangents_SRCS
../contrib/MikkTSpace/mikktspace.c
../contrib/MikkTSpace/mikktspace.h
)
# minizip/unzip
IF(ASSIMP_HUNTER_ENABLED)
hunter_add_package(minizip)
@@ -1367,6 +1375,7 @@ SET( assimp_src
${Tinyusdz_DEP_SOURCES}
${Pugixml_SRCS}
${stb_SRCS}
${MikkTSpaceTangents_SRCS}
# Necessary to show the headers in the project when using the VC++ generator:
${PUBLIC_HEADERS}
+14 -13
View File
@@ -678,8 +678,8 @@ void SceneCombiner::MergeScenes(aiScene **_dest, aiScene *master, std::vector<At
// ------------------------------------------------------------------------------------------------
// Build a list of unique bones
void SceneCombiner::BuildUniqueBoneList(std::list<BoneWithHash> &asBones,
MeshArray::const_iterator it,
MeshArray::const_iterator end) {
std::vector<aiMesh *>::const_iterator it,
std::vector<aiMesh *>::const_iterator end) {
unsigned int iOffset = 0;
for (; it != end; ++it) {
for (unsigned int l = 0; l < (*it)->mNumBones; ++l) {
@@ -712,7 +712,8 @@ void SceneCombiner::BuildUniqueBoneList(std::list<BoneWithHash> &asBones,
// ------------------------------------------------------------------------------------------------
// Merge a list of bones
void SceneCombiner::MergeBones(aiMesh *out, MeshArray::const_iterator it, MeshArray::const_iterator end) {
void SceneCombiner::MergeBones(aiMesh *out, std::vector<aiMesh *>::const_iterator it,
std::vector<aiMesh *>::const_iterator end) {
if (nullptr == out || out->mNumBones == 0) {
return;
}
@@ -770,8 +771,8 @@ void SceneCombiner::MergeBones(aiMesh *out, MeshArray::const_iterator it, MeshAr
// ------------------------------------------------------------------------------------------------
// Merge a list of meshes
void SceneCombiner::MergeMeshes(aiMesh **_out, unsigned int /*flags*/,
MeshArray::const_iterator begin,
MeshArray::const_iterator end) {
std::vector<aiMesh *>::const_iterator begin,
std::vector<aiMesh *>::const_iterator end) {
if (nullptr == _out) {
return;
}
@@ -787,7 +788,7 @@ void SceneCombiner::MergeMeshes(aiMesh **_out, unsigned int /*flags*/,
std::string name;
// Find out how much output storage we'll need
for (MeshArray::const_iterator it = begin; it != end; ++it) {
for (std::vector<aiMesh *>::const_iterator it = begin; it != end; ++it) {
const char *meshName((*it)->mName.C_Str());
name += std::string(meshName);
if (it != end - 1) {
@@ -809,7 +810,7 @@ void SceneCombiner::MergeMeshes(aiMesh **_out, unsigned int /*flags*/,
if ((**begin).HasPositions()) {
pv2 = out->mVertices = new aiVector3D[out->mNumVertices];
for (MeshArray::const_iterator it = begin; it != end; ++it) {
for (std::vector<aiMesh *>::const_iterator it = begin; it != end; ++it) {
if ((*it)->mVertices) {
::memcpy(pv2, (*it)->mVertices, (*it)->mNumVertices * sizeof(aiVector3D));
} else
@@ -821,7 +822,7 @@ void SceneCombiner::MergeMeshes(aiMesh **_out, unsigned int /*flags*/,
if ((**begin).HasNormals()) {
pv2 = out->mNormals = new aiVector3D[out->mNumVertices];
for (MeshArray::const_iterator it = begin; it != end; ++it) {
for (std::vector<aiMesh *>::const_iterator it = begin; it != end; ++it) {
if ((*it)->mNormals) {
::memcpy(pv2, (*it)->mNormals, (*it)->mNumVertices * sizeof(aiVector3D));
} else {
@@ -836,7 +837,7 @@ void SceneCombiner::MergeMeshes(aiMesh **_out, unsigned int /*flags*/,
pv2 = out->mTangents = new aiVector3D[out->mNumVertices];
aiVector3D *pv2b = out->mBitangents = new aiVector3D[out->mNumVertices];
for (MeshArray::const_iterator it = begin; it != end; ++it) {
for (std::vector<aiMesh *>::const_iterator it = begin; it != end; ++it) {
if ((*it)->mTangents) {
::memcpy(pv2, (*it)->mTangents, (*it)->mNumVertices * sizeof(aiVector3D));
::memcpy(pv2b, (*it)->mBitangents, (*it)->mNumVertices * sizeof(aiVector3D));
@@ -853,7 +854,7 @@ void SceneCombiner::MergeMeshes(aiMesh **_out, unsigned int /*flags*/,
out->mNumUVComponents[n] = (*begin)->mNumUVComponents[n];
pv2 = out->mTextureCoords[n] = new aiVector3D[out->mNumVertices];
for (MeshArray::const_iterator it = begin; it != end; ++it) {
for (std::vector<aiMesh *>::const_iterator it = begin; it != end; ++it) {
if ((*it)->mTextureCoords[n]) {
::memcpy(pv2, (*it)->mTextureCoords[n], (*it)->mNumVertices * sizeof(aiVector3D));
} else {
@@ -867,7 +868,7 @@ void SceneCombiner::MergeMeshes(aiMesh **_out, unsigned int /*flags*/,
n = 0;
while ((**begin).HasVertexColors(n)) {
aiColor4D *pVec2 = out->mColors[n] = new aiColor4D[out->mNumVertices];
for (MeshArray::const_iterator it = begin; it != end; ++it) {
for (std::vector<aiMesh *>::const_iterator it = begin; it != end; ++it) {
if ((*it)->mColors[n]) {
::memcpy(pVec2, (*it)->mColors[n], (*it)->mNumVertices * sizeof(aiColor4D));
} else {
@@ -886,7 +887,7 @@ void SceneCombiner::MergeMeshes(aiMesh **_out, unsigned int /*flags*/,
aiFace *pf2 = out->mFaces;
unsigned int ofs = 0;
for (MeshArray::const_iterator it = begin; it != end; ++it) {
for (std::vector<aiMesh *>::const_iterator it = begin; it != end; ++it) {
for (unsigned int m = 0; m < (*it)->mNumFaces; ++m, ++pf2) {
aiFace &face = (*it)->mFaces[m];
pf2->mNumIndices = face.mNumIndices;
@@ -909,7 +910,7 @@ void SceneCombiner::MergeMeshes(aiMesh **_out, unsigned int /*flags*/,
MergeBones(out, begin, end);
// delete all source meshes
for (MeshArray::const_iterator it = begin; it != end; ++it)
for (std::vector<aiMesh *>::const_iterator it = begin; it != end; ++it)
delete *it;
}
+3 -3
View File
@@ -158,8 +158,8 @@ void CatmullClarkSubdivider::Subdivide(
return;
}
MeshArray inmeshes;
MeshArray outmeshes;
std::vector<aiMesh *> inmeshes;
std::vector<aiMesh *> outmeshes;
std::vector<unsigned int> maptbl;
inmeshes.reserve(nmesh);
@@ -577,7 +577,7 @@ void CatmullClarkSubdivider::InternSubdivide(
// 7. Apply the next subdivision step.
// ---------------------------------------------------------------------
if (num != 1) {
MeshArray tmp(nmesh);
std::vector<aiMesh *> tmp(nmesh);
InternSubdivide(out, nmesh, &tmp.front(), num - 1);
for (size_t i = 0; i < nmesh; ++i) {
delete out[i];
+1 -1
View File
@@ -159,7 +159,7 @@ aiReturn GetMaterialFloatArray(const aiMaterial *pMat,
ai_assert(prop->mDataLength >= 5);
ai_assert(!prop->mData[prop->mDataLength - 1]);
for (unsigned int a = 0;; ++a) {
cur = fast_atoreal_move(cur, pOut[a]);
cur = fast_atoreal_move<TReal>(cur, pOut[a]);
if (a == iWrite - 1) {
break;
}
+7 -3
View File
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2025, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -63,7 +61,11 @@ CalcTangentsProcess::CalcTangentsProcess() :
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool CalcTangentsProcess::IsActive(unsigned int pFlags) const {
return (pFlags & aiProcess_CalcTangentSpace) != 0;
const bool active = ((pFlags & aiProcess_CalcTangentSpace) != 0);
if (mActive) {
return active;
}
return false;
}
// ------------------------------------------------------------------------------------------------
@@ -71,6 +73,8 @@ bool CalcTangentsProcess::IsActive(unsigned int pFlags) const {
void CalcTangentsProcess::SetupProperties(const Importer *pImp) {
ai_assert(nullptr != pImp);
mActive = pImp->GetPropertyBool(AI_CONFIG_POSTPROCESS_USE_MIKKTSPACE_TANGENTS, false);
// get the current value of the property
configMaxAngle = pImp->GetPropertyFloat(AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE, 45.f);
configMaxAngle = std::max(std::min(configMaxAngle, 45.0f), 0.0f);
@@ -102,6 +102,7 @@ private:
/** Configuration option: maximum smoothing angle, in radians*/
float configMaxAngle;
unsigned int configSourceUV;
bool mActive = true;
};
} // end of namespace Assimp
@@ -0,0 +1,99 @@
#include "GenerateMikkTSpaceTangents.h"
#include <assimp/scene.h>
#include <assimp/postprocess.h>
namespace Assimp {
static int get_num_faces(const SMikkTSpaceContext *context);
static int get_num_vertices_of_face(const SMikkTSpaceContext *context, int iFace);
static void get_position(const SMikkTSpaceContext *context, float outpos[], int iFace, int iVert);
static void get_normal(const SMikkTSpaceContext *context, float outnormal[], int iFace, int iVert);
static void get_tex_coords(const SMikkTSpaceContext *context, float outuv[], int iFace, int iVert);
static void set_tspace_basic(const SMikkTSpaceContext *context, const float tangentu[], float fSign, int iFace, int iVert);
static int get_num_faces(const SMikkTSpaceContext *context) {
const aiMesh *currentMesh = static_cast<aiMesh*>(context->m_pUserData);
const int numFaces = static_cast<int>(currentMesh->mNumFaces);
return numFaces;
}
static int get_num_vertices_of_face(const SMikkTSpaceContext *context, int iFace) {
const aiMesh *currentMesh = static_cast<aiMesh*>(context->m_pUserData);
const aiFace &face = currentMesh->mFaces[iFace];
return face.mNumIndices;
}
static void get_position(const SMikkTSpaceContext *context, float outpos[], int /*iFace*/, int iVert) {
const aiMesh *currentMesh = static_cast<aiMesh*>(context->m_pUserData);
const aiVector3D &v = currentMesh->mVertices[static_cast<size_t>(iVert)];
outpos[0] = v.x;
outpos[1] = v.y;
outpos[2] = v.z;
}
static void get_normal(const SMikkTSpaceContext *context, float outnormal[], int /*iFace*/, int iVert) {
const aiMesh *currentMesh = static_cast<aiMesh*>(context->m_pUserData);
const aiVector3D &n = currentMesh->mNormals[static_cast<size_t>(iVert)];
outnormal[0] = n.x;
outnormal[1] = n.y;
outnormal[2] = n.z;
}
static void get_tex_coords(const SMikkTSpaceContext *context, float outuv[], int /*iFace*/, int iVert) {
const aiMesh *currentMesh = static_cast<aiMesh*>(context->m_pUserData);
aiVector3D &t = currentMesh->mTextureCoords[static_cast<size_t>(iVert)][0];
if (currentMesh->mNumUVComponents[iVert] == 2) {
outuv[0] = t.x;
outuv[1] = t.y;
} else if (currentMesh->mNumUVComponents[iVert] == 3){
outuv[0] = t.x;
outuv[1] = t.y;
outuv[2] = 0.0;
}
}
static void set_tspace_basic(const SMikkTSpaceContext *context, const float tangentu[], float /*fSign*/, int /*iFace*/, int iVert) {
const aiMesh *currentMesh = static_cast<aiMesh*>(context->m_pUserData);
currentMesh->mTangents[iVert].x = tangentu[0];
currentMesh->mTangents[iVert].y = tangentu[1];
currentMesh->mTangents[iVert].z = tangentu[2];
}
bool GenerateMikkTSpaceTangents::IsActive(unsigned int pFlags) const {
const bool active = (pFlags & aiProcess_CalcTangentSpace) != 0;
if (mActive) {
return active;
}
return false;
}
void GenerateMikkTSpaceTangents::Execute(aiScene* pScene) {
mIface.m_getNumFaces = get_num_faces;
mIface.m_getNumVerticesOfFace = get_num_vertices_of_face;
mIface.m_getNormal = get_normal;
mIface.m_getPosition = get_position;
mIface.m_getTexCoord = get_tex_coords;
mIface.m_setTSpaceBasic = set_tspace_basic;
mContext.m_pInterface = &mIface;
for (size_t i=0; i<pScene->mNumMeshes; ++i) {
aiMesh *mesh = pScene->mMeshes[i];
ExecutePerMesh(mesh);
}
}
void GenerateMikkTSpaceTangents::SetupProperties(const Importer *pImp) {
mActive = pImp->GetPropertyBool(AI_CONFIG_POSTPROCESS_USE_MIKKTSPACE_TANGENTS, false);
}
void GenerateMikkTSpaceTangents::ExecutePerMesh(aiMesh *mesh) {
if (mesh == nullptr) {
return;
}
mContext.m_pUserData = mesh;
genTangSpaceDefault(&mContext);
}
} // namespace Assimp
@@ -0,0 +1,25 @@
#pragma once
#include "Common/BaseProcess.h"
#include "contrib/MikkTSpace/mikktspace.h"
struct aiMesh;
namespace Assimp {
class GenerateMikkTSpaceTangents final : public BaseProcess {
public:
GenerateMikkTSpaceTangents() = default;
~GenerateMikkTSpaceTangents() override = default;
bool IsActive(unsigned int pFlags) const override;
void Execute(aiScene* pScene) override;
void SetupProperties(const Importer *pImp) override;
void ExecutePerMesh(aiMesh *mesh);
private:
bool mActive = false;
SMikkTSpaceInterface mIface;
SMikkTSpaceContext mContext;
};
} // namespace Assimp
+1 -60
View File
@@ -100,65 +100,6 @@ void JoinVerticesProcess::Execute( aiScene* pScene) {
namespace {
struct CompareVerticesAlmostEqual {
bool operator () (const Vertex & a, const Vertex & b) const {
static const float epsilon = 1e-5f;
static const float squareEpsilon = epsilon * epsilon;
if ((a.position - b.position).SquareLength() > squareEpsilon) {
return false;
}
// We just test the other attributes even if they're not present in the mesh.
// In this case they're initialized to 0 so the comparison succeeds.
// By this method the non-present attributes are effectively ignored in the comparison.
if ((a.normal - b.normal).SquareLength() > squareEpsilon) {
return false;
}
if ((a.tangent - b.tangent).SquareLength() > squareEpsilon) {
return false;
}
if ((a.bitangent - b.bitangent).SquareLength() > squareEpsilon) {
return false;
}
for (uint32_t i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; i ++) {
if ((a.texcoords[i] - b.texcoords[i]).SquareLength() > squareEpsilon) {
return false;
}
}
for (uint32_t i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; i ++) {
if (GetColorDifference(a.colors[i], b.colors[i]) > squareEpsilon) {
return false;
}
}
// If reached this point, they are ~equal
return true;
}
};
struct HashVertex {
inline void hash_combine(std::size_t& seed, const ai_real& v) const {
std::hash<ai_real> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
size_t operator () (const Vertex & v) const {
size_t hash = 0;
hash_combine(hash, v.position.x);
hash_combine(hash, v.position.y);
hash_combine(hash, v.position.z);
return hash;
}
};
template<class XMesh>
void updateXMeshVertices(XMesh *pMesh, std::vector<int> &uniqueVertices) {
// replace vertex data with the unique data sets
@@ -267,7 +208,7 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) {
}
}
// a map that maps a vertex to its new index
std::unordered_map<Vertex, int, HashVertex, CompareVerticesAlmostEqual> vertex2Index = {};
std::map<Vertex, int> vertex2Index = {};
// we can not end up with more vertices than we started with
// Now check each vertex if it brings something new to the table
int newIndex = 0;
+2 -2
View File
@@ -332,7 +332,7 @@ void PretransformVertices::ApplyTransform(aiMesh *mesh, const aiMatrix4x4 &mat)
// ------------------------------------------------------------------------------------------------
// Simple routine to build meshes in worldspace, no further optimization
void PretransformVertices::BuildWCSMeshes(MeshArray &out, aiMesh **in,
void PretransformVertices::BuildWCSMeshes(std::vector<aiMesh *> &out, aiMesh **in,
unsigned int numIn, aiNode *node) const {
// NOTE:
// aiMesh::mNumBones store original source mesh, or UINT_MAX if not a copy
@@ -459,7 +459,7 @@ void PretransformVertices::Execute(aiScene *pScene) {
}
// now build a list of output meshes
MeshArray apcOutMeshes;
std::vector<aiMesh *> apcOutMeshes;
// Keep scene hierarchy? It's an easy job in this case ...
// we go on and transform all meshes, if one is referenced by nodes
+1 -1
View File
@@ -139,7 +139,7 @@ private:
// -------------------------------------------------------------------
// Simple routine to build meshes in worldspace, no further optimization
void BuildWCSMeshes(MeshArray &out, aiMesh **in,
void BuildWCSMeshes(std::vector<aiMesh *> &out, aiMesh **in,
unsigned int numIn, aiNode *node) const;
// -------------------------------------------------------------------
+2 -6
View File
@@ -126,7 +126,7 @@ void SortByPTypeProcess::Execute(aiScene *pScene) {
unsigned int aiNumMeshesPerPType[4] = { 0, 0, 0, 0 };
MeshArray outMeshes;
std::vector<aiMesh *> outMeshes;
outMeshes.reserve(static_cast<size_t>(pScene->mNumMeshes) << 1u);
bool bAnyChanges = false;
@@ -165,7 +165,6 @@ void SortByPTypeProcess::Execute(aiScene *pScene) {
if (!(mConfigRemoveMeshes & mesh->mPrimitiveTypes)) {
*meshIdx = static_cast<unsigned int>(outMeshes.size());
outMeshes.emplace_back(mesh);
pScene->mMeshes[i] = nullptr; // Indicate ownership transfer
} else {
delete mesh;
pScene->mMeshes[i] = nullptr;
@@ -189,15 +188,12 @@ void SortByPTypeProcess::Execute(aiScene *pScene) {
unsigned int numPolyVerts = 0;
for (; pFirstFace != pLastFace; ++pFirstFace) {
if (pFirstFace->mNumIndices >= 1 && pFirstFace->mNumIndices <= 3)
if (pFirstFace->mNumIndices <= 3)
++aiNumPerPType[pFirstFace->mNumIndices - 1];
else {
++aiNumPerPType[3];
numPolyVerts += pFirstFace->mNumIndices;
}
if (pFirstFace->mNumIndices == 0) {
ASSIMP_LOG_WARN("Face with 0 indices treated as polygon");
}
}
VertexWeightTable *avw = ComputeVertexBoneWeightTable(mesh);
File diff suppressed because it is too large Load Diff
+145
View File
@@ -0,0 +1,145 @@
/** \file mikktspace/mikktspace.h
* \ingroup mikktspace
*/
/**
* Copyright (C) 2011 by Morten S. Mikkelsen
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef __MIKKTSPACE_H__
#define __MIKKTSPACE_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Author: Morten S. Mikkelsen
* Version: 1.0
*
* The files mikktspace.h and mikktspace.c are designed to be
* stand-alone files and it is important that they are kept this way.
* Not having dependencies on structures/classes/libraries specific
* to the program, in which they are used, allows them to be copied
* and used as is into any tool, program or plugin.
* The code is designed to consistently generate the same
* tangent spaces, for a given mesh, in any tool in which it is used.
* This is done by performing an internal welding step and subsequently an order-independent evaluation
* of tangent space for meshes consisting of triangles and quads.
* This means faces can be received in any order and the same is true for
* the order of vertices of each face. The generated result will not be affected
* by such reordering. Additionally, whether degenerate (vertices or texture coordinates)
* primitives are present or not will not affect the generated results either.
* Once tangent space calculation is done the vertices of degenerate primitives will simply
* inherit tangent space from neighboring non degenerate primitives.
* The analysis behind this implementation can be found in my master's thesis
* which is available for download --> http://image.diku.dk/projects/media/morten.mikkelsen.08.pdf
* Note that though the tangent spaces at the vertices are generated in an order-independent way,
* by this implementation, the interpolated tangent space is still affected by which diagonal is
* chosen to split each quad. A sensible solution is to have your tools pipeline always
* split quads by the shortest diagonal. This choice is order-independent and works with mirroring.
* If these have the same length then compare the diagonals defined by the texture coordinates.
* XNormal which is a tool for baking normal maps allows you to write your own tangent space plugin
* and also quad triangulator plugin.
*/
typedef int tbool;
typedef struct SMikkTSpaceContext SMikkTSpaceContext;
typedef struct {
// Returns the number of faces (triangles/quads) on the mesh to be processed.
int (*m_getNumFaces)(const SMikkTSpaceContext * pContext);
// Returns the number of vertices on face number iFace
// iFace is a number in the range {0, 1, ..., getNumFaces()-1}
int (*m_getNumVerticesOfFace)(const SMikkTSpaceContext * pContext, const int iFace);
// returns the position/normal/texcoord of the referenced face of vertex number iVert.
// iVert is in the range {0,1,2} for triangles and {0,1,2,3} for quads.
void (*m_getPosition)(const SMikkTSpaceContext * pContext, float fvPosOut[], const int iFace, const int iVert);
void (*m_getNormal)(const SMikkTSpaceContext * pContext, float fvNormOut[], const int iFace, const int iVert);
void (*m_getTexCoord)(const SMikkTSpaceContext * pContext, float fvTexcOut[], const int iFace, const int iVert);
// either (or both) of the two setTSpace callbacks can be set.
// The call-back m_setTSpaceBasic() is sufficient for basic normal mapping.
// This function is used to return the tangent and fSign to the application.
// fvTangent is a unit length vector.
// For normal maps it is sufficient to use the following simplified version of the bitangent which is generated at pixel/vertex level.
// bitangent = fSign * cross(vN, tangent);
// Note that the results are returned unindexed. It is possible to generate a new index list
// But averaging/overwriting tangent spaces by using an already existing index list WILL produce INCRORRECT results.
// DO NOT! use an already existing index list.
void (*m_setTSpaceBasic)(const SMikkTSpaceContext * pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert);
// This function is used to return tangent space results to the application.
// fvTangent and fvBiTangent are unit length vectors and fMagS and fMagT are their
// true magnitudes which can be used for relief mapping effects.
// fvBiTangent is the "real" bitangent and thus may not be perpendicular to fvTangent.
// However, both are perpendicular to the vertex normal.
// For normal maps it is sufficient to use the following simplified version of the bitangent which is generated at pixel/vertex level.
// fSign = bIsOrientationPreserving ? 1.0f : (-1.0f);
// bitangent = fSign * cross(vN, tangent);
// Note that the results are returned unindexed. It is possible to generate a new index list
// But averaging/overwriting tangent spaces by using an already existing index list WILL produce INCRORRECT results.
// DO NOT! use an already existing index list.
void (*m_setTSpace)(const SMikkTSpaceContext * pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT,
const tbool bIsOrientationPreserving, const int iFace, const int iVert);
} SMikkTSpaceInterface;
struct SMikkTSpaceContext
{
SMikkTSpaceInterface * m_pInterface; // initialized with callback functions
void * m_pUserData; // pointer to client side mesh data etc. (passed as the first parameter with every interface call)
};
// these are both thread safe!
tbool genTangSpaceDefault(const SMikkTSpaceContext * pContext); // Default (recommended) fAngularThreshold is 180 degrees (which means threshold disabled)
tbool genTangSpace(const SMikkTSpaceContext * pContext, const float fAngularThreshold);
// To avoid visual errors (distortions/unwanted hard edges in lighting), when using sampled normal maps, the
// normal map sampler must use the exact inverse of the pixel shader transformation.
// The most efficient transformation we can possibly do in the pixel shader is
// achieved by using, directly, the "unnormalized" interpolated tangent, bitangent and vertex normal: vT, vB and vN.
// pixel shader (fast transform out)
// vNout = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
// where vNt is the tangent space normal. The normal map sampler must likewise use the
// interpolated and "unnormalized" tangent, bitangent and vertex normal to be compliant with the pixel shader.
// sampler does (exact inverse of pixel shader):
// float3 row0 = cross(vB, vN);
// float3 row1 = cross(vN, vT);
// float3 row2 = cross(vT, vB);
// float fSign = dot(vT, row0)<0 ? -1 : 1;
// vNt = normalize( fSign * float3(dot(vNout,row0), dot(vNout,row1), dot(vNout,row2)) );
// where vNout is the sampled normal in some chosen 3D space.
//
// Should you choose to reconstruct the bitangent in the pixel shader instead
// of the vertex shader, as explained earlier, then be sure to do this in the normal map sampler also.
// Finally, beware of quad triangulations. If the normal map sampler doesn't use the same triangulation of
// quads as your renderer then problems will occur since the interpolated tangent spaces will differ
// eventhough the vertex level tangent spaces match. This can be solved either by triangulating before
// sampling/exporting or by using the order-independent choice of diagonal for splitting quads suggested earlier.
// However, this must be used both by the sampler and your tools/rendering pipeline.
#ifdef __cplusplus
}
#endif
#endif
+6 -12
View File
@@ -583,9 +583,6 @@ char *OpenDDLParser::parsePrimitiveDataType(char *in, char *end, Value::ValueTyp
size_t prim_len(0);
for (size_t i = 0; i < (size_t) Value::ValueType::ddl_types_max; i++) {
prim_len = strlen(Grammar::PrimitiveTypeToken[i]);
if (static_cast<size_t>(end - in) < prim_len) {
continue;
}
if (0 == strncmp(in, Grammar::PrimitiveTypeToken[i], prim_len)) {
type = static_cast<Value::ValueType>(i);
break;
@@ -598,9 +595,6 @@ char *OpenDDLParser::parsePrimitiveDataType(char *in, char *end, Value::ValueTyp
} else {
in += prim_len;
}
if (in >= end) {
return in;
}
bool ok(true);
if (*in == Grammar::OpenArrayToken[0]) {
@@ -608,13 +602,13 @@ char *OpenDDLParser::parsePrimitiveDataType(char *in, char *end, Value::ValueTyp
++in;
char *start(in);
while (in != end) {
++in;
if (*in == Grammar::CloseArrayToken[0]) {
len = ::atoi(start);
ok = true;
++in;
break;
}
++in;
}
} else {
len = 1;
@@ -636,9 +630,9 @@ char *OpenDDLParser::parseReference(char *in, char *end, std::vector<Name *> &na
if (nextName) {
names.push_back(nextName);
}
while (in != end && Grammar::CommaSeparator[0] == *in) {
while (Grammar::CommaSeparator[0] == *in) {
in = getNextSeparator(in, end);
if (in != end && Grammar::CommaSeparator[0] == *in) {
if (Grammar::CommaSeparator[0] == *in) {
in = parseName(in, end, &nextName);
if (nextName) {
names.push_back(nextName);
@@ -661,7 +655,7 @@ char *OpenDDLParser::parseBooleanLiteral(char *in, char *end, Value **boolean) {
char *start(in);
size_t len(0);
while (in != end && !isSeparator(*in)) {
while (!isSeparator(*in) && in != end) {
++in;
++len;
}
@@ -694,7 +688,7 @@ char *OpenDDLParser::parseIntegerLiteral(char *in, char *end, Value **integer, V
in = lookForNextToken(in, end);
char *start(in);
while (in != end && !isSeparator(*in)) {
while (!isSeparator(*in) && in != end) {
++in;
}
@@ -837,7 +831,7 @@ char *OpenDDLParser::parseHexaLiteral(char *in, char *end, Value **data) {
bool ok(true);
char *start(in);
int pos(0);
while (in != end && !isSeparator(*in)) {
while (!isSeparator(*in) && in != end) {
if ((*in < '0' && *in > '9') || (*in < 'a' && *in > 'f') || (*in < 'A' && *in > 'F')) {
ok = false;
break;
+1 -1
View File
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2025, assimp team
Copyright (c) 2006-2020, assimp team
All rights reserved.
-2
View File
@@ -58,7 +58,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/types.h>
#include <exception>
#include <vector>
namespace Assimp {
// =======================================================================
@@ -68,7 +67,6 @@ class IOStream;
class IOSystem;
class ProgressHandler;
// =======================================================================
// Plugin development
//
+6 -6
View File
@@ -240,8 +240,8 @@ public:
* @param end Points to the mesh after the last mesh to be processed
*/
static void MergeMeshes(aiMesh **dest, unsigned int flags,
MeshArray::const_iterator begin,
MeshArray::const_iterator end);
std::vector<aiMesh *>::const_iterator begin,
std::vector<aiMesh *>::const_iterator end);
// -------------------------------------------------------------------
/** Merges two or more bones
@@ -251,8 +251,8 @@ public:
* @param begin First mesh to be processed
* @param end Points to the mesh after the last mesh to be processed
*/
static void MergeBones(aiMesh *out, MeshArray::const_iterator it,
MeshArray::const_iterator end);
static void MergeBones(aiMesh *out, std::vector<aiMesh *>::const_iterator it,
std::vector<aiMesh *>::const_iterator end);
// -------------------------------------------------------------------
/** Merges two or more materials
@@ -277,8 +277,8 @@ public:
* @param end Last mesh to be processed
*/
static void BuildUniqueBoneList(std::list<BoneWithHash> &asBones,
MeshArray::const_iterator it,
MeshArray::const_iterator end);
std::vector<aiMesh *>::const_iterator it,
std::vector<aiMesh *>::const_iterator end);
// -------------------------------------------------------------------
/** Add a name prefix to all nodes in a scene.
+23
View File
@@ -183,6 +183,29 @@ struct Vertex {
return *this;
}
bool operator < (const Vertex & o) const {
if (position < o.position) return true;
if (position != o.position) return false;
if (normal < o.normal) return true;
if (normal != o.normal) return false;
for (uint32_t i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; i ++) {
if (texcoords[i] < o.texcoords[i]) return true;
if (texcoords[i] != o.texcoords[i]) return false;
}
// note that tangent/bitangent are not checked since they are optional
for (uint32_t i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; i ++) {
if (colors[i] < o.colors[i]) return true;
if (colors[i] != o.colors[i]) return false;
}
// if reached this point, they are equal
return false;
}
// ----------------------------------------------------------------------------
/// Convert back to non-interleaved storage
void SortBack(aiMesh* out, unsigned int idx) const {
+4 -1
View File
@@ -1175,6 +1175,9 @@ enum aiComponent
#endif // AI_CONFIG_APP_SCALE_KEY
#define AI_CONFIG_POSTPROCESS_USE_MIKKTSPACE_TANGENTS \
"POSTPROCESS_USE_MIKKTSPACE_TANGENTS"
// ---------- All the Build/Compile-time defines ------------
/** @brief Specifies if double precision is supported inside assimp
@@ -1182,6 +1185,6 @@ enum aiComponent
* Property type: Bool. Default value: undefined.
*/
#cmakedefine ASSIMP_DOUBLE_PRECISION 1
#define ASSIMP_DOUBLE_PRECISION 1
#endif // !! AI_CONFIG_H_INC
-1
View File
@@ -1174,4 +1174,3 @@ struct aiSkeleton {
#endif //! extern "C"
#endif // AI_MESH_H_INC
-12
View File
@@ -70,15 +70,9 @@ union _IEEESingle {
float Float;
struct
{
#if (defined AI_BUILD_BIG_ENDIAN)
uint32_t Sign : 1;
uint32_t Exp : 8;
uint32_t Frac : 23;
#else
uint32_t Frac : 23;
uint32_t Exp : 8;
uint32_t Sign : 1;
#endif
} IEEE;
};
@@ -89,15 +83,9 @@ union _IEEEDouble {
double Double;
struct
{
#if (defined AI_BUILD_BIG_ENDIAN)
uint64_t Sign : 1;
uint64_t Exp : 11;
uint64_t Frac : 52;
#else
uint64_t Frac : 52;
uint64_t Exp : 11;
uint64_t Sign : 1;
#endif
} IEEE;
};
-11
View File
@@ -77,17 +77,6 @@ typedef uint32_t ai_uint32;
#include <new> // for std::nothrow_t
#include <string> // for aiString::Set(const std::string&)
struct aiNode;
struct aiMesh;
struct aiMaterial;
#include <vector>
using MeshArray = std::vector<aiMesh *>;
using NodeArray = std::vector<aiNode *>;
using MaterialArray = std::vector<aiMaterial*>;
namespace Assimp {
//! @cond never
namespace Intern {
+5 -5
View File
@@ -2,7 +2,7 @@
[Setup]
AppName=Open Asset Import Library - SDK
AppVerName=Open Asset Import Library - SDK (v6.0.2)
AppVerName=Open Asset Import Library - SDK (v5.4.3)
DefaultDirName={pf}\Assimp
DefaultGroupName=Assimp
UninstallDisplayIcon={app}\bin\x64\assimp.exe
@@ -12,9 +12,9 @@ SetupIconFile=..\..\tools\shared\assimp_tools_icon.ico
WizardImageFile=..\..\tools\shared\assimp_tools_icon.bmp
WizardSmallImageFile=..\..\tools\shared\assimp_tools_icon.bmp
LicenseFile=License.rtf
OutputBaseFileName=assimp-sdk-6.0.2-setup
VersionInfoVersion=6.0.2.0
VersionInfoTextVersion=6.0.2
OutputBaseFileName=assimp-sdk-5.4.3-setup
VersionInfoVersion=5.4.3.0
VersionInfoTextVersion=5.4.3
VersionInfoCompany=Assimp Development Team
ArchitecturesInstallIn64BitMode=x64
@@ -43,7 +43,7 @@ Source: "vc_redist.x64.exe"; DestDir: "{app}\stub\"; Check: IsWin64
; Common stuff
Source: "..\..\CREDITS"; DestDir: "{app}"
Source: "..\..\LICENSE"; DestDir: "{app}"
Source: "..\..\README.md"; DestDir: "{app}"
Source: "..\..\README"; DestDir: "{app}"
Source: "WEB"; DestDir: "{app}"
Source: "..\..\scripts\*"; DestDir: "{app}\scripts"; Flags: recursesubdirs
+5 -13
View File
@@ -36,21 +36,13 @@ aiProcess_JoinIdenticalVertices = 0x2
#
aiProcess_MakeLeftHanded = 0x4
## <hr>Triangulates all faces of all meshes.
## <hr>Triangulates all faces of all meshes.
#
# By default the imported mesh data might contain faces with more than 3
# indices. For rendering you'll usually want all faces to be triangles.
# This post processing step splits up faces with more than 3 indices into
# triangles. Line and point primitives are *not* modified! If you want
# 'triangles only' with no other kinds of primitives, try the following
# solution:
# - Specify both #aiProcess_Triangulate and #aiProcess_SortByPType
# - Ignore all point and line meshes when you process assimp's output
#
aiProcess_Triangulate = 0x8
# <hr>Removes some parts of the data structure (animations, materials,
# light sources, cameras, textures, vertex components).
# indices. For rendering you'll usually want all faces to be triangles.
# This post processing stepaiProcess_ForceGenNormals
## <hr>Removes some parts of the data structure (animations, materials,
# light sources, cameras, textures, vertex components).
#
# The components to be removed are specified in a separate
# configuration option, <tt>#AI_CONFIG_PP_RVC_FLAGS<tt>. This is quite useful
+1 -1
View File
@@ -314,7 +314,7 @@ public final class AiMesh {
* @return true if tangents and bitangents are available
*/
public boolean hasTangentsAndBitangents() {
return m_tangents != null && m_bitangents != null;
return m_tangents != null && m_tangents != null;
}
-21
View File
@@ -1,21 +0,0 @@
AC3Db
MATERIAL "" rgb 1 1 1 amb 0.2 0.2 0.2 emis 0 0 0 spec 0.5 0.5 0.5 shi 10 trans 0
OBJECT world
kids 1
OBJECT poly
name "rect"
loc 1 0.5 0
numvert 4
-1 0.5 0
1 0.5 0
1 -0.5 0
-1 -0.5 0
numsurf 1
SURF 0x20
mat 0
refs 4
3 0 0
2 1 0
1 1 1
0 0 1
kids 0
-11
View File
@@ -141,14 +141,3 @@ TEST(utACImportExport, testFormatDetection) {
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/AC/TestFormatDetection", aiProcess_ValidateDataStructure);
ASSERT_NE(nullptr, scene);
}
TEST(utACImportExport, importDobuleSidedFaces) {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/AC/doubleSidedFace.ac", aiProcess_ValidateDataStructure);
ASSERT_NE(nullptr, scene);
// The scene contains one double-sided, rectangular AC surface. It should resolve to two quads (front + back) with eight
// vertices (one per side to guarantee proper normal vectors).
ASSERT_EQ(scene->mNumMeshes, 1u);
ASSERT_EQ(scene->mMeshes[0]->mNumFaces, 2u);
ASSERT_EQ(scene->mMeshes[0]->mNumVertices, 8u);
}
+16 -2
View File
@@ -5,6 +5,8 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2025, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -48,7 +50,18 @@ using namespace ::Assimp::Profiling;
class utProfiler : public ::testing::Test {
public:
LogStream *mStream = nullptr;
LogStream *m_stream;
/*virtual void SetUp() {
m_stream = new UTLogStream;
DefaultLogger::create();
DefaultLogger::get()->attachStream( m_stream );
}
virtual void TearDown() {
DefaultLogger::get()->detatchStream( m_stream );
m_stream = nullptr;
}*/
};
TEST_F( utProfiler, addRegion_success ) {
@@ -57,7 +70,8 @@ TEST_F( utProfiler, addRegion_success ) {
for ( int i=0; i<10; i++ ) {
volatile int j=0;
j++;
(void)j; /* avoid gcc-16 warnings about unused variable */
}
myProfiler.EndRegion( "t1" );
//UTLogStream *stream( (UTLogStream*) m_stream );
//EXPECT_FALSE( stream->m_messages.empty() );
}
+1 -1
View File
@@ -50,7 +50,7 @@ class utSceneCombiner : public ::testing::Test {
};
TEST_F(utSceneCombiner, MergeMeshes_ValidNames_Test) {
MeshArray merge_list;
std::vector<aiMesh *> merge_list;
aiMesh *mesh1 = new aiMesh;
mesh1->mName.Set("mesh_1");
merge_list.push_back(mesh1);