update assimp to 6.0.5

This commit is contained in:
AzaezelX 2026-06-09 12:46:56 -05:00
parent 2d2eb57e2e
commit f5cf21cfeb
941 changed files with 22718 additions and 12240 deletions

View file

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2026, assimp team
All rights reserved.
@ -49,14 +49,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GLTFASSET_H_INC
#define GLTFASSET_H_INC
#if !defined(ASSIMP_BUILD_NO_GLTF_IMPORTER) && !defined(ASSIMP_BUILD_NO_GLTF1_IMPORTER)
#include "glTFCommon.h"
#include "AssetLib/glTFCommon/glTFCommon.h"
#include <assimp/Exceptional.h>
#include <algorithm>
#include <list>
#include <map>
#include <stdexcept>
#include <string>
#include <vector>
@ -86,7 +81,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
#if _MSC_VER > 1500 || (defined __GNUC___)
#if _MSC_VER > 1500 || (defined __GNUC__)
# define ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
# else
# define gltf_unordered_map map
@ -103,7 +98,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// clang-format on
#include "AssetLib/glTF/glTFCommon.h"
#include "AssetLib/glTFCommon/glTFCommon.h"
namespace glTF {
@ -1011,6 +1006,4 @@ private:
// Include the implementation of the methods
#include "glTFAsset.inl"
#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
#endif // GLTFASSET_H_INC

View file

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2026, assimp team
All rights reserved.

View file

@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2026, assimp team
All rights reserved.
@ -50,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GLTFASSETWRITER_H_INC
#define GLTFASSETWRITER_H_INC
#if !defined(ASSIMP_BUILD_NO_GLTF_IMPORTER) && !defined(ASSIMP_BUILD_NO_GLTF1_IMPORTER)
//#if !defined(ASSIMP_BUILD_NO_GLTF_IMPORTER) && !defined(ASSIMP_BUILD_NO_GLTF1_IMPORTER)
#include "glTFAsset.h"
@ -64,16 +63,6 @@ class AssetWriter
template<class T>
friend void WriteLazyDict(LazyDict<T>& d, AssetWriter& w);
private:
void WriteBinaryData(IOStream* outfile, size_t sceneLength);
void WriteMetadata();
void WriteExtensionsUsed();
template<class T>
void WriteObjects(LazyDict<T>& d);
public:
Document mDoc;
Asset& mAsset;
@ -81,9 +70,19 @@ public:
MemoryPoolAllocator<>& mAl;
AssetWriter(Asset& asset);
~AssetWriter() = default;
void WriteFile(const char* path);
void WriteGLBFile(const char* path);
private:
void WriteBinaryData(IOStream* outfile, size_t sceneLength);
void WriteMetadata();
void WriteExtensionsUsed();
template<class T>
void WriteObjects(LazyDict<T>& d);
};
}
@ -91,6 +90,6 @@ public:
// Include the implementation of the methods
#include "glTFAssetWriter.inl"
#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
//#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
#endif // GLTFASSETWRITER_H_INC

View file

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2026, assimp team
All rights reserved.

View file

@ -1,117 +0,0 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
#include "AssetLib/glTF/glTFCommon.h"
namespace glTFCommon {
using namespace glTFCommon::Util;
namespace Util {
bool ParseDataURI(const char *const_uri, size_t uriLen, DataURI &out) {
if (nullptr == const_uri) {
return false;
}
if (const_uri[0] != 0x10) { // we already parsed this uri?
if (strncmp(const_uri, "data:", 5) != 0) // not a data uri?
return false;
}
// set defaults
out.mediaType = "text/plain";
out.charset = "US-ASCII";
out.base64 = false;
char *uri = const_cast<char *>(const_uri);
if (uri[0] != 0x10) {
uri[0] = 0x10;
uri[1] = uri[2] = uri[3] = uri[4] = 0;
size_t i = 5, j;
if (uri[i] != ';' && uri[i] != ',') { // has media type?
uri[1] = char(i);
for (;i < uriLen && uri[i] != ';' && uri[i] != ','; ++i) {
// nothing to do!
}
}
while (i < uriLen && uri[i] == ';') {
uri[i++] = '\0';
for (j = i; i < uriLen && uri[i] != ';' && uri[i] != ','; ++i) {
// nothing to do!
}
if (strncmp(uri + j, "charset=", 8) == 0) {
uri[2] = char(j + 8);
} else if (strncmp(uri + j, "base64", 6) == 0) {
uri[3] = char(j);
}
}
if (i < uriLen) {
uri[i++] = '\0';
uri[4] = char(i);
} else {
uri[1] = uri[2] = uri[3] = 0;
uri[4] = 5;
}
}
if (uri[1] != 0) {
out.mediaType = uri + uri[1];
}
if (uri[2] != 0) {
out.charset = uri + uri[2];
}
if (uri[3] != 0) {
out.base64 = true;
}
out.data = uri + uri[4];
out.dataLength = (uri + uriLen) - out.data;
return true;
}
} // namespace Util
} // namespace glTFCommon
#endif

View file

@ -1,520 +0,0 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
#ifndef AI_GLFTCOMMON_H_INC
#define AI_GLFTCOMMON_H_INC
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
#include <assimp/Exceptional.h>
#include <algorithm>
#include <list>
#include <map>
#include <stdexcept>
#include <string>
#include <vector>
#include <rapidjson/document.h>
#include <rapidjson/error/en.h>
#include <rapidjson/rapidjson.h>
// clang-format off
#ifdef ASSIMP_API
# include <assimp/ByteSwapper.h>
# include <assimp/DefaultIOSystem.h>
# include <memory>
#else
# include <memory>
# define AI_SWAP4(p)
# define ai_assert
#endif
#if _MSC_VER > 1500 || (defined __GNUC___)
# define ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
#else
# define gltf_unordered_map map
#endif
#ifdef ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
# include <unordered_map>
# if defined(_MSC_VER) && _MSC_VER <= 1600
# define gltf_unordered_map tr1::unordered_map
# else
# define gltf_unordered_map unordered_map
# endif
#endif
// clang-format on
namespace glTFCommon {
using rapidjson::Document;
using rapidjson::Value;
#ifdef ASSIMP_API
using Assimp::IOStream;
using Assimp::IOSystem;
using std::shared_ptr;
#else
using std::shared_ptr;
typedef std::runtime_error DeadlyImportError;
typedef std::runtime_error DeadlyExportError;
enum aiOrigin {
aiOrigin_SET = 0,
aiOrigin_CUR = 1,
aiOrigin_END = 2
};
class IOSystem;
class IOStream {
public:
IOStream(FILE *file) :
f(file) {}
~IOStream() {
fclose(f);
}
size_t Read(void *b, size_t sz, size_t n) { return fread(b, sz, n, f); }
size_t Write(const void *b, size_t sz, size_t n) { return fwrite(b, sz, n, f); }
int Seek(size_t off, aiOrigin orig) { return fseek(f, off, int(orig)); }
size_t Tell() const { return ftell(f); }
size_t FileSize() {
long p = Tell(), len = (Seek(0, aiOrigin_END), Tell());
return size_t((Seek(p, aiOrigin_SET), len));
}
private:
FILE *f;
};
#endif
// Vec/matrix types, as raw float arrays
typedef float(vec3)[3];
typedef float(vec4)[4];
typedef float(mat4)[16];
inline void CopyValue(const glTFCommon::vec3 &v, aiColor4D &out) {
out.r = v[0];
out.g = v[1];
out.b = v[2];
out.a = 1.0;
}
inline void CopyValue(const glTFCommon::vec4 &v, aiColor4D &out) {
out.r = v[0];
out.g = v[1];
out.b = v[2];
out.a = v[3];
}
inline void CopyValue(const glTFCommon::vec4 &v, aiColor3D &out) {
out.r = v[0];
out.g = v[1];
out.b = v[2];
}
inline void CopyValue(const glTFCommon::vec3 &v, aiColor3D &out) {
out.r = v[0];
out.g = v[1];
out.b = v[2];
}
inline void CopyValue(const glTFCommon::vec3 &v, aiVector3D &out) {
out.x = v[0];
out.y = v[1];
out.z = v[2];
}
inline void CopyValue(const glTFCommon::vec4 &v, aiQuaternion &out) {
out.x = v[0];
out.y = v[1];
out.z = v[2];
out.w = v[3];
}
inline void CopyValue(const glTFCommon::mat4 &v, aiMatrix4x4 &o) {
o.a1 = v[0];
o.b1 = v[1];
o.c1 = v[2];
o.d1 = v[3];
o.a2 = v[4];
o.b2 = v[5];
o.c2 = v[6];
o.d2 = v[7];
o.a3 = v[8];
o.b3 = v[9];
o.c3 = v[10];
o.d3 = v[11];
o.a4 = v[12];
o.b4 = v[13];
o.c4 = v[14];
o.d4 = v[15];
}
#if _MSC_VER
# pragma warning(push)
# pragma warning(disable : 4310)
#endif // _MSC_VER
inline std::string getCurrentAssetDir(const std::string &pFile) {
int pos = std::max(int(pFile.rfind('/')), int(pFile.rfind('\\')));
if (pos == int(std::string::npos)) {
return std::string();
}
return pFile.substr(0, pos + 1);
}
#if _MSC_VER
# pragma warning(pop)
#endif // _MSC_VER
namespace Util {
void EncodeBase64(const uint8_t *in, size_t inLength, std::string &out);
size_t DecodeBase64(const char *in, size_t inLength, uint8_t *&out);
inline size_t DecodeBase64(const char *in, uint8_t *&out) {
return DecodeBase64(in, strlen(in), out);
}
struct DataURI {
const char *mediaType;
const char *charset;
bool base64;
const char *data;
size_t dataLength;
};
//! Check if a uri is a data URI
bool ParseDataURI(const char *const_uri, size_t uriLen, DataURI &out);
} // namespace Util
#define CHECK_EXT(EXT) \
if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
//! Helper struct to represent values that might not be present
template <class T>
struct Nullable {
T value;
bool isPresent;
Nullable() :
isPresent(false) {}
Nullable(T &val) :
value(val),
isPresent(true) {}
};
//! A reference to one top-level object, which is valid
//! until the Asset instance is destroyed
template <class T>
class Ref {
std::vector<T *> *vector;
unsigned int index;
public:
Ref() :
vector(nullptr),
index(0) {}
Ref(std::vector<T *> &vec, unsigned int idx) :
vector(&vec),
index(idx) {}
inline unsigned int GetIndex() const { return index; }
operator bool() const { return vector != nullptr && index < vector->size(); }
T *operator->() { return (*vector)[index]; }
T &operator*() { return *((*vector)[index]); }
};
//
// JSON Value reading helpers
//
template <class T>
struct ReadHelper {
static bool Read(Value &val, T &out) {
return val.IsInt() ? out = static_cast<T>(val.GetInt()), true : false;
}
};
template <>
struct ReadHelper<bool> {
static bool Read(Value &val, bool &out) {
return val.IsBool() ? out = val.GetBool(), true : false;
}
};
template <>
struct ReadHelper<float> {
static bool Read(Value &val, float &out) {
return val.IsNumber() ? out = static_cast<float>(val.GetDouble()), true : false;
}
};
template <unsigned int N>
struct ReadHelper<float[N]> {
static bool Read(Value &val, float (&out)[N]) {
if (!val.IsArray() || val.Size() != N) return false;
for (unsigned int i = 0; i < N; ++i) {
if (val[i].IsNumber())
out[i] = static_cast<float>(val[i].GetDouble());
}
return true;
}
};
template <>
struct ReadHelper<const char *> {
static bool Read(Value &val, const char *&out) {
return val.IsString() ? (out = val.GetString(), true) : false;
}
};
template <>
struct ReadHelper<std::string> {
static bool Read(Value &val, std::string &out) {
return val.IsString() ? (out = std::string(val.GetString(), val.GetStringLength()), true) : false;
}
};
template <class T>
struct ReadHelper<Nullable<T>> {
static bool Read(Value &val, Nullable<T> &out) {
return out.isPresent = ReadHelper<T>::Read(val, out.value);
}
};
template <>
struct ReadHelper<uint64_t> {
static bool Read(Value &val, uint64_t &out) {
return val.IsUint64() ? out = val.GetUint64(), true : false;
}
};
template <>
struct ReadHelper<int64_t> {
static bool Read(Value &val, int64_t &out) {
return val.IsInt64() ? out = val.GetInt64(), true : false;
}
};
template <class T>
inline static bool ReadValue(Value &val, T &out) {
return ReadHelper<T>::Read(val, out);
}
template <class T>
inline static bool ReadMember(Value &obj, const char *id, T &out) {
if (!obj.IsObject()) {
return false;
}
Value::MemberIterator it = obj.FindMember(id);
if (it != obj.MemberEnd()) {
return ReadHelper<T>::Read(it->value, out);
}
return false;
}
template <class T>
inline static T MemberOrDefault(Value &obj, const char *id, T defaultValue) {
T out;
return ReadMember(obj, id, out) ? out : defaultValue;
}
inline Value *FindMember(Value &val, const char *id) {
if (!val.IsObject()) {
return nullptr;
}
Value::MemberIterator it = val.FindMember(id);
return (it != val.MemberEnd()) ? &it->value : nullptr;
}
template <int N>
inline void throwUnexpectedTypeError(const char (&expectedTypeName)[N], const char *memberId, const char *context, const char *extraContext) {
std::string fullContext = context;
if (extraContext && (strlen(extraContext) > 0)) {
fullContext = fullContext + " (" + extraContext + ")";
}
throw DeadlyImportError("Member \"", memberId, "\" was not of type \"", expectedTypeName, "\" when reading ", fullContext);
}
// Look-up functions with type checks. Context and extra context help the user identify the problem if there's an error.
inline Value *FindStringInContext(Value &val, const char *memberId, const char *context, const char *extraContext = nullptr) {
if (!val.IsObject()) {
return nullptr;
}
Value::MemberIterator it = val.FindMember(memberId);
if (it == val.MemberEnd()) {
return nullptr;
}
if (!it->value.IsString()) {
throwUnexpectedTypeError("string", memberId, context, extraContext);
}
return &it->value;
}
inline Value *FindNumberInContext(Value &val, const char *memberId, const char *context, const char *extraContext = nullptr) {
if (!val.IsObject()) {
return nullptr;
}
Value::MemberIterator it = val.FindMember(memberId);
if (it == val.MemberEnd()) {
return nullptr;
}
if (!it->value.IsNumber()) {
throwUnexpectedTypeError("number", memberId, context, extraContext);
}
return &it->value;
}
inline Value *FindUIntInContext(Value &val, const char *memberId, const char *context, const char *extraContext = nullptr) {
if (!val.IsObject()) {
return nullptr;
}
Value::MemberIterator it = val.FindMember(memberId);
if (it == val.MemberEnd()) {
return nullptr;
}
if (!it->value.IsUint()) {
throwUnexpectedTypeError("uint", memberId, context, extraContext);
}
return &it->value;
}
inline Value *FindArrayInContext(Value &val, const char *memberId, const char *context, const char *extraContext = nullptr) {
if (!val.IsObject()) {
return nullptr;
}
Value::MemberIterator it = val.FindMember(memberId);
if (it == val.MemberEnd()) {
return nullptr;
}
if (!it->value.IsArray()) {
throwUnexpectedTypeError("array", memberId, context, extraContext);
}
return &it->value;
}
inline Value *FindObjectInContext(Value &val, const char *memberId, const char *context, const char *extraContext = nullptr) {
if (!val.IsObject()) {
return nullptr;
}
Value::MemberIterator it = val.FindMember(memberId);
if (it == val.MemberEnd()) {
return nullptr;
}
if (!it->value.IsObject()) {
throwUnexpectedTypeError("object", memberId, context, extraContext);
}
return &it->value;
}
inline Value *FindExtensionInContext(Value &val, const char *extensionId, const char *context, const char *extraContext = nullptr) {
if (Value *extensionList = FindObjectInContext(val, "extensions", context, extraContext)) {
if (Value *extension = FindObjectInContext(*extensionList, extensionId, context, extraContext)) {
return extension;
}
}
return nullptr;
}
// Overloads when the value is the document.
inline Value *FindString(Document &doc, const char *memberId) {
return FindStringInContext(doc, memberId, "the document");
}
inline Value *FindNumber(Document &doc, const char *memberId) {
return FindNumberInContext(doc, memberId, "the document");
}
inline Value *FindUInt(Document &doc, const char *memberId) {
return FindUIntInContext(doc, memberId, "the document");
}
inline Value *FindArray(Document &val, const char *memberId) {
return FindArrayInContext(val, memberId, "the document");
}
inline Value *FindObject(Document &doc, const char *memberId) {
return FindObjectInContext(doc, memberId, "the document");
}
inline Value *FindExtension(Value &val, const char *extensionId) {
return FindExtensionInContext(val, extensionId, "the document");
}
inline Value *FindString(Value &val, const char *id) {
Value::MemberIterator it = val.FindMember(id);
return (it != val.MemberEnd() && it->value.IsString()) ? &it->value : nullptr;
}
inline Value *FindObject(Value &val, const char *id) {
Value::MemberIterator it = val.FindMember(id);
return (it != val.MemberEnd() && it->value.IsObject()) ? &it->value : nullptr;
}
inline Value *FindArray(Value &val, const char *id) {
Value::MemberIterator it = val.FindMember(id);
return (it != val.MemberEnd() && it->value.IsArray()) ? &it->value : nullptr;
}
inline Value *FindNumber(Value &val, const char *id) {
Value::MemberIterator it = val.FindMember(id);
return (it != val.MemberEnd() && it->value.IsNumber()) ? &it->value : nullptr;
}
} // namespace glTFCommon
#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
#endif // AI_GLFTCOMMON_H_INC

View file

@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2026, assimp team
All rights reserved.
@ -43,6 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER
#include "AssetLib/glTF/glTFExporter.h"
#include "AssetLib/glTF/glTFAsset.h"
#include "AssetLib/glTF/glTFAssetWriter.h"
#include "PostProcessing/SplitLargeMeshes.h"
@ -63,6 +63,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <limits>
#include <inttypes.h>
#include <rapidjson/rapidjson.h>
#include <rapidjson/document.h>
#include <rapidjson/error/en.h>
#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
// Header files, Open3DGC.
# include <Open3DGC/o3dgcSC3DMCEncoder.h>
@ -1065,6 +1069,5 @@ void glTFExporter::ExportAnimations()
} // End: for-loop mNumAnimations
}
#endif // ASSIMP_BUILD_NO_GLTF_EXPORTER
#endif // ASSIMP_BUILD_NO_EXPORT

View file

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2026, assimp team
All rights reserved.
@ -49,7 +49,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined(ASSIMP_BUILD_NO_GLTF_EXPORTER) && !defined(ASSIMP_BUILD_NO_GLTF1_EXPORTER)
#include <assimp/material.h>
#include <assimp/types.h>
#include <assimp/defs.h>
#include <map>

View file

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2026, assimp team
All rights reserved.
@ -41,10 +41,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined(ASSIMP_BUILD_NO_GLTF_IMPORTER) && !defined(ASSIMP_BUILD_NO_GLTF1_IMPORTER)
#include "AssetLib/glTF/glTFImporter.h"
#include "AssetLib/glTF/glTFAsset.h"
#include "glTFImporter.h"
#include "glTFAsset.h"
#if !defined(ASSIMP_BUILD_NO_EXPORT)
#include "AssetLib/glTF/glTFAssetWriter.h"
# include "glTFAssetWriter.h"
#endif
#include "PostProcessing/MakeVerboseFormat.h"
@ -55,9 +55,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/Importer.hpp>
#include <memory>
using namespace Assimp;
using namespace glTF;
@ -67,7 +64,11 @@ static constexpr aiImporterDesc desc = {
"",
"",
"",
aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportCompressedFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental,
aiImporterFlags_SupportTextFlavour |
aiImporterFlags_SupportBinaryFlavour |
aiImporterFlags_SupportCompressedFlavour |
aiImporterFlags_LimitedSupport |
aiImporterFlags_Experimental,
0,
0,
0,
@ -75,19 +76,85 @@ static constexpr aiImporterDesc desc = {
"gltf glb"
};
namespace {
void SetMaterialColorProperty(const std::vector<int> &embeddedTexIdxs, Asset &, TexProperty prop, aiMaterial *mat,
aiTextureType texType, const char *pKey, unsigned int type, unsigned int idx) {
if (prop.texture) {
if (prop.texture->source) {
aiString uri(prop.texture->source->uri);
if (const int texIdx = embeddedTexIdxs[prop.texture->source.GetIndex()]; texIdx != -1) { // embedded
// setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture)
uri.data[0] = '*';
uri.length = 1 + ASSIMP_itoa10(uri.data + 1, AI_MAXLEN - 1, texIdx);
}
mat->AddProperty(&uri, _AI_MATKEY_TEXTURE_BASE, texType, 0);
}
return;
}
aiColor4D col;
CopyValue(prop.color, col);
mat->AddProperty(&col, 1, pKey, type, idx);
}
void SetFace(aiFace &face, int a) {
face.mNumIndices = 1;
face.mIndices = new unsigned int[1];
face.mIndices[0] = a;
}
void SetFace(aiFace &face, int a, int b) {
face.mNumIndices = 2;
face.mIndices = new unsigned int[2];
face.mIndices[0] = a;
face.mIndices[1] = b;
}
void SetFace(aiFace &face, int a, int b, int c) {
face.mNumIndices = 3;
face.mIndices = new unsigned int[3];
face.mIndices[0] = a;
face.mIndices[1] = b;
face.mIndices[2] = c;
}
bool CheckValidFacesIndices(const aiFace *faces, unsigned nFaces, unsigned nVerts) {
for (unsigned i = 0; i < nFaces; ++i) {
for (unsigned j = 0; j < faces[i].mNumIndices; ++j) {
unsigned idx = faces[i].mIndices[j];
if (idx >= nVerts)
return false;
}
}
return true;
}
void createDefaultMaterial(aiScene *scene) {
if (scene == nullptr) {
return;
}
scene->mNumMaterials = 1;
scene->mMaterials = nullptr;
scene->mMaterials = new aiMaterial *[1];
scene->mMaterials[0] = new aiMaterial();
}
} // Anonymous namespace
glTFImporter::glTFImporter() :
mScene(nullptr) {
// empty
}
glTFImporter::~glTFImporter() = default;
const aiImporterDesc *glTFImporter::GetInfo() const {
return &desc;
}
bool glTFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /* checkSig */) const {
glTF::Asset asset(pIOHandler);
Asset asset(pIOHandler);
try {
asset.Load(pFile,
CheckMagicToken(
@ -98,42 +165,21 @@ bool glTFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool
return false;
}
}
inline void SetMaterialColorProperty(std::vector<int> &embeddedTexIdxs, Asset & /*r*/, glTF::TexProperty prop, aiMaterial *mat,
aiTextureType texType, const char *pKey, unsigned int type, unsigned int idx) {
if (prop.texture) {
if (prop.texture->source) {
aiString uri(prop.texture->source->uri);
int texIdx = embeddedTexIdxs[prop.texture->source.GetIndex()];
if (texIdx != -1) { // embedded
// setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture)
uri.data[0] = '*';
uri.length = 1 + ASSIMP_itoa10(uri.data + 1, AI_MAXLEN - 1, texIdx);
}
mat->AddProperty(&uri, _AI_MATKEY_TEXTURE_BASE, texType, 0);
}
} else {
aiColor4D col;
CopyValue(prop.color, col);
mat->AddProperty(&col, 1, pKey, type, idx);
void glTFImporter::ImportMaterials(Asset &r) const {
mScene->mNumMaterials = r.materials.Size();
if (mScene->mNumMaterials == 0) {
createDefaultMaterial(mScene);
return;
}
}
void glTFImporter::ImportMaterials(glTF::Asset &r) {
mScene->mNumMaterials = unsigned(r.materials.Size());
mScene->mMaterials = new aiMaterial *[mScene->mNumMaterials];
for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) {
aiMaterial *aimat = mScene->mMaterials[i] = new aiMaterial();
Material &mat = r.materials[i];
/*if (!mat.name.empty())*/ {
aiString str(mat.id /*mat.name*/);
aimat->AddProperty(&str, AI_MATKEY_NAME);
}
aiString str(mat.id);
aimat->AddProperty(&str, AI_MATKEY_NAME);
SetMaterialColorProperty(embeddedTexIdxs, r, mat.ambient, aimat, aiTextureType_AMBIENT, AI_MATKEY_COLOR_AMBIENT);
SetMaterialColorProperty(embeddedTexIdxs, r, mat.diffuse, aimat, aiTextureType_DIFFUSE, AI_MATKEY_COLOR_DIFFUSE);
@ -150,49 +196,9 @@ void glTFImporter::ImportMaterials(glTF::Asset &r) {
aimat->AddProperty(&mat.shininess, 1, AI_MATKEY_SHININESS);
}
}
if (mScene->mNumMaterials == 0) {
mScene->mNumMaterials = 1;
// Delete the array of length zero created above.
delete[] mScene->mMaterials;
mScene->mMaterials = new aiMaterial *[1];
mScene->mMaterials[0] = new aiMaterial();
}
}
static inline void SetFace(aiFace &face, int a) {
face.mNumIndices = 1;
face.mIndices = new unsigned int[1];
face.mIndices[0] = a;
}
static inline void SetFace(aiFace &face, int a, int b) {
face.mNumIndices = 2;
face.mIndices = new unsigned int[2];
face.mIndices[0] = a;
face.mIndices[1] = b;
}
static inline void SetFace(aiFace &face, int a, int b, int c) {
face.mNumIndices = 3;
face.mIndices = new unsigned int[3];
face.mIndices[0] = a;
face.mIndices[1] = b;
face.mIndices[2] = c;
}
static inline bool CheckValidFacesIndices(aiFace *faces, unsigned nFaces, unsigned nVerts) {
for (unsigned i = 0; i < nFaces; ++i) {
for (unsigned j = 0; j < faces[i].mNumIndices; ++j) {
unsigned idx = faces[i].mIndices[j];
if (idx >= nVerts)
return false;
}
}
return true;
}
void glTFImporter::ImportMeshes(glTF::Asset &r) {
void glTFImporter::ImportMeshes(Asset &r) {
std::vector<aiMesh *> meshes;
unsigned int k = 0;
@ -230,10 +236,10 @@ void glTFImporter::ImportMeshes(glTF::Asset &r) {
} // if(mesh.Extension.size() > 0)
meshOffsets.push_back(k);
k += unsigned(mesh.primitives.size());
k += static_cast<unsigned>(mesh.primitives.size());
for (unsigned int p = 0; p < mesh.primitives.size(); ++p) {
Mesh::Primitive &prim = mesh.primitives[p];
auto &[mode, attributes, indices, material] = mesh.primitives[p];
aiMesh *aim = new aiMesh();
meshes.push_back(aim);
@ -245,7 +251,7 @@ void glTFImporter::ImportMeshes(glTF::Asset &r) {
len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, unsigned(AI_MAXLEN - len - 1), p);
}
switch (prim.mode) {
switch (mode) {
case PrimitiveMode_POINTS:
aim->mPrimitiveTypes |= aiPrimitiveType_POINT;
break;
@ -263,7 +269,7 @@ void glTFImporter::ImportMeshes(glTF::Asset &r) {
break;
}
Mesh::Primitive::Attributes &attr = prim.attributes;
Mesh::Primitive::Attributes &attr = attributes;
if (attr.position.size() > 0 && attr.position[0]) {
aim->mNumVertices = attr.position[0]->count;
@ -285,13 +291,13 @@ void glTFImporter::ImportMeshes(glTF::Asset &r) {
aiFace *faces = nullptr;
unsigned int nFaces = 0;
if (prim.indices) {
unsigned int count = prim.indices->count;
if (indices) {
unsigned int count = indices->count;
Accessor::Indexer data = prim.indices->GetIndexer();
Accessor::Indexer data = indices->GetIndexer();
ai_assert(data.IsValid());
switch (prim.mode) {
switch (mode) {
case PrimitiveMode_POINTS: {
nFaces = count;
faces = new aiFace[nFaces];
@ -316,13 +322,13 @@ void glTFImporter::ImportMeshes(glTF::Asset &r) {
case PrimitiveMode_LINE_LOOP:
case PrimitiveMode_LINE_STRIP: {
nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
nFaces = count - ((mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
faces = new aiFace[nFaces];
SetFace(faces[0], data.GetUInt(0), data.GetUInt(1));
for (unsigned int i = 2; i < count; ++i) {
SetFace(faces[i - 1], faces[i - 2].mIndices[1], data.GetUInt(i));
}
if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
if (mode == PrimitiveMode_LINE_LOOP) { // close the loop
SetFace(faces[count - 1], faces[count - 2].mIndices[1], faces[0].mIndices[0]);
}
break;
@ -363,7 +369,7 @@ void glTFImporter::ImportMeshes(glTF::Asset &r) {
// use the already determined count as it includes checks
unsigned int count = aim->mNumVertices;
switch (prim.mode) {
switch (mode) {
case PrimitiveMode_POINTS: {
nFaces = count;
faces = new aiFace[nFaces];
@ -388,13 +394,13 @@ void glTFImporter::ImportMeshes(glTF::Asset &r) {
case PrimitiveMode_LINE_LOOP:
case PrimitiveMode_LINE_STRIP: {
nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
nFaces = count - ((mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
faces = new aiFace[nFaces];
SetFace(faces[0], 0, 1);
for (unsigned int i = 2; i < count; ++i) {
SetFace(faces[i - 1], faces[i - 2].mIndices[1], i);
}
if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
if (mode == PrimitiveMode_LINE_LOOP) { // close the loop
SetFace(faces[count - 1], faces[count - 2].mIndices[1], faces[0].mIndices[0]);
}
break;
@ -442,8 +448,8 @@ void glTFImporter::ImportMeshes(glTF::Asset &r) {
}
}
if (prim.material) {
aim->mMaterialIndex = prim.material.GetIndex();
if (material) {
aim->mMaterialIndex = material.GetIndex();
}
}
}
@ -453,7 +459,7 @@ void glTFImporter::ImportMeshes(glTF::Asset &r) {
CopyVector(meshes, mScene->mMeshes, mScene->mNumMeshes);
}
void glTFImporter::ImportCameras(glTF::Asset &r) {
void glTFImporter::ImportCameras(Asset &r) const {
if (!r.cameras.Size()) {
return;
}
@ -461,29 +467,30 @@ void glTFImporter::ImportCameras(glTF::Asset &r) {
mScene->mNumCameras = r.cameras.Size();
mScene->mCameras = new aiCamera *[r.cameras.Size()];
for (size_t i = 0; i < r.cameras.Size(); ++i) {
Camera &cam = r.cameras[i];
aiCamera *aicam = mScene->mCameras[i] = new aiCamera();
const Camera &cam = r.cameras[i];
mScene->mCameras[i] = new aiCamera();
const auto aiCameraPtr = mScene->mCameras[i];
if (cam.type == Camera::Perspective) {
aicam->mAspect = cam.perspective.aspectRatio;
aicam->mHorizontalFOV = cam.perspective.yfov * ((aicam->mAspect == 0.f) ? 1.f : aicam->mAspect);
aicam->mClipPlaneFar = cam.perspective.zfar;
aicam->mClipPlaneNear = cam.perspective.znear;
aiCameraPtr->mAspect = cam.perspective.aspectRatio;
aiCameraPtr->mHorizontalFOV = cam.perspective.yfov * ((aiCameraPtr->mAspect == 0.f) ? 1.f : aiCameraPtr->mAspect);
aiCameraPtr->mClipPlaneFar = cam.perspective.zfar;
aiCameraPtr->mClipPlaneNear = cam.perspective.znear;
} else {
aicam->mClipPlaneFar = cam.ortographic.zfar;
aicam->mClipPlaneNear = cam.ortographic.znear;
aicam->mHorizontalFOV = 0.0;
aicam->mAspect = 1.0f;
aiCameraPtr->mClipPlaneFar = cam.ortographic.zfar;
aiCameraPtr->mClipPlaneNear = cam.ortographic.znear;
aiCameraPtr->mHorizontalFOV = 0.0;
aiCameraPtr->mAspect = 1.0f;
if (0.f != cam.ortographic.ymag) {
aicam->mAspect = cam.ortographic.xmag / cam.ortographic.ymag;
aiCameraPtr->mAspect = cam.ortographic.xmag / cam.ortographic.ymag;
}
}
}
}
void glTFImporter::ImportLights(glTF::Asset &r) {
if (!r.lights.Size()) return;
void glTFImporter::ImportLights(Asset &r) const {
if (!r.lights.Size()) {
return;
}
mScene->mNumLights = r.lights.Size();
mScene->mLights = new aiLight *[r.lights.Size()];
@ -516,7 +523,7 @@ void glTFImporter::ImportLights(glTF::Asset &r) {
CopyValue(l.color, ail->mColorSpecular);
ail->mAngleOuterCone = l.falloffAngle;
ail->mAngleInnerCone = l.falloffExponent; // TODO fix this, it does not look right at all
ail->mAngleInnerCone = l.falloffAngle * (1.0f - 1.0f / (1.0f + l.falloffExponent));
ail->mAttenuationConstant = l.constantAttenuation;
ail->mAttenuationLinear = l.linearAttenuation;
@ -524,13 +531,13 @@ void glTFImporter::ImportLights(glTF::Asset &r) {
}
}
aiNode *ImportNode(aiScene *pScene, glTF::Asset &r, std::vector<unsigned int> &meshOffsets, glTF::Ref<glTF::Node> &ptr) {
aiNode *ImportNode(aiScene *pScene, Asset &r, std::vector<unsigned int> &meshOffsets, Ref<Node> &ptr) {
Node &node = *ptr;
aiNode *ainode = new aiNode(node.id);
if (!node.children.empty()) {
ainode->mNumChildren = unsigned(node.children.size());
ainode->mNumChildren = static_cast<unsigned>(node.children.size());
ainode->mChildren = new aiNode *[ainode->mNumChildren];
for (unsigned int i = 0; i < ainode->mNumChildren; ++i) {
@ -570,7 +577,7 @@ aiNode *ImportNode(aiScene *pScene, glTF::Asset &r, std::vector<unsigned int> &m
if (!node.meshes.empty()) {
int count = 0;
for (size_t i = 0; i < node.meshes.size(); ++i) {
int idx = node.meshes[i].GetIndex();
const int idx = node.meshes[i].GetIndex();
count += meshOffsets[idx + 1] - meshOffsets[idx];
}
@ -579,7 +586,7 @@ aiNode *ImportNode(aiScene *pScene, glTF::Asset &r, std::vector<unsigned int> &m
int k = 0;
for (size_t i = 0; i < node.meshes.size(); ++i) {
int idx = node.meshes[i].GetIndex();
const int idx = node.meshes[i].GetIndex();
for (unsigned int j = meshOffsets[idx]; j < meshOffsets[idx + 1]; ++j, ++k) {
ainode->mMeshes[k] = j;
}
@ -597,14 +604,15 @@ aiNode *ImportNode(aiScene *pScene, glTF::Asset &r, std::vector<unsigned int> &m
return ainode;
}
void glTFImporter::ImportNodes(glTF::Asset &r) {
if (!r.scene) return;
void glTFImporter::ImportNodes(Asset &r) {
if (!r.scene) {
return;
}
std::vector<Ref<Node>> rootNodes = r.scene->nodes;
// The root nodes
unsigned int numRootNodes = unsigned(rootNodes.size());
if (numRootNodes == 1) { // a single root node: use it
if (auto numRootNodes = static_cast<unsigned>(rootNodes.size()); numRootNodes == 1) { // a single root node: use it
mScene->mRootNode = ImportNode(mScene, r, meshOffsets, rootNodes[0]);
} else if (numRootNodes > 1) { // more than one root node: create a fake root
aiNode *root = new aiNode("ROOT");
@ -616,13 +624,9 @@ void glTFImporter::ImportNodes(glTF::Asset &r) {
}
mScene->mRootNode = root;
}
//if (!mScene->mRootNode) {
// mScene->mRootNode = new aiNode("EMPTY");
//}
}
void glTFImporter::ImportEmbeddedTextures(glTF::Asset &r) {
void glTFImporter::ImportEmbeddedTextures(Asset &r) {
embeddedTexIdxs.resize(r.images.Size(), -1);
int numEmbeddedTexs = 0;
@ -647,32 +651,32 @@ void glTFImporter::ImportEmbeddedTextures(glTF::Asset &r) {
aiTexture *tex = mScene->mTextures[idx] = new aiTexture();
size_t length = img.GetDataLength();
const size_t length = img.GetDataLength();
void *data = img.StealData();
tex->mFilename = img.name;
tex->mWidth = static_cast<unsigned int>(length);
tex->mHeight = 0;
tex->pcData = reinterpret_cast<aiTexel *>(data);
tex->pcData = static_cast<aiTexel *>(data);
if (!img.mimeType.empty()) {
const char *ext = strchr(img.mimeType.c_str(), '/') + 1;
if (ext) {
if (const char *ext = strchr(img.mimeType.c_str(), '/') + 1) {
if (strncmp(ext, "jpeg", 4) == 0) {
ext = "jpg";
}
const size_t len = strlen(ext);
if (len <= 3) {
strncpy(tex->achFormatHint, ext, len);
}
tex->achFormatHint[3] = '\0';
size_t len = strlen(ext);
if (len > 3) len = 3;
memcpy(tex->achFormatHint, ext, len);
}
}
}
}
void glTFImporter::ImportCommonMetadata(glTF::Asset &a) {
void glTFImporter::ImportCommonMetadata(const Asset &a) const {
ai_assert(mScene->mMetaData == nullptr);
const bool hasVersion = !a.asset.version.empty();
const bool hasGenerator = !a.asset.generator.empty();
const bool hasCopyright = !a.asset.copyright.empty();
@ -698,7 +702,7 @@ void glTFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOS
this->mScene = pScene;
// read the asset file
glTF::Asset asset(pIOHandler);
Asset asset(pIOHandler);
asset.Load(pFile,
CheckMagicToken(
pIOHandler, pFile, AI_GLB_MAGIC_NUMBER, 1, 0,

View file

@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2026, assimp team
All rights reserved.
@ -62,7 +61,7 @@ namespace Assimp {
class glTFImporter : public BaseImporter {
public:
glTFImporter();
~glTFImporter() override;
~glTFImporter() override = default;
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const override;
protected:
@ -71,12 +70,12 @@ protected:
private:
void ImportEmbeddedTextures(glTF::Asset &a);
void ImportMaterials(glTF::Asset &a);
void ImportMaterials(glTF::Asset &a) const;
void ImportMeshes(glTF::Asset &a);
void ImportCameras(glTF::Asset &a);
void ImportLights(glTF::Asset &a);
void ImportCameras(glTF::Asset &a) const;
void ImportLights(glTF::Asset &a) const;
void ImportNodes(glTF::Asset &a);
void ImportCommonMetadata(glTF::Asset &a);
void ImportCommonMetadata(const glTF::Asset &a) const;
private:
std::vector<unsigned int> meshOffsets;