Merge pull request #868 from otgerrogla/master
Fixed a few GLTF importer/exporter bugspull/873/head
commit
8449afad71
|
@ -269,9 +269,13 @@ option ( ASSIMP_BUILD_ASSIMP_TOOLS
|
||||||
ON
|
ON
|
||||||
)
|
)
|
||||||
IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
||||||
IF ( WIN32 AND DirectX_FOUND )
|
IF ( WIN32 )
|
||||||
|
option ( ASSIMP_BUILD_ASSIMP_VIEW "If the Assimp view tool is built. (requires DirectX)" ${DirectX_FOUND} )
|
||||||
|
IF ( ASSIMP_BUILD_ASSIMP_VIEW )
|
||||||
ADD_SUBDIRECTORY( tools/assimp_view/ )
|
ADD_SUBDIRECTORY( tools/assimp_view/ )
|
||||||
ENDIF ( WIN32 AND DirectX_FOUND )
|
ENDIF ( ASSIMP_BUILD_ASSIMP_VIEW )
|
||||||
|
ENDIF ( WIN32 )
|
||||||
|
|
||||||
ADD_SUBDIRECTORY( tools/assimp_cmd/ )
|
ADD_SUBDIRECTORY( tools/assimp_cmd/ )
|
||||||
ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
||||||
|
|
||||||
|
|
|
@ -375,7 +375,7 @@ public: // static utilities
|
||||||
T*& out,
|
T*& out,
|
||||||
unsigned int& outLength)
|
unsigned int& outLength)
|
||||||
{
|
{
|
||||||
outLength = vec.size();
|
outLength = unsigned(vec.size());
|
||||||
if (outLength) {
|
if (outLength) {
|
||||||
out = new T[outLength];
|
out = new T[outLength];
|
||||||
std::swap_ranges(vec.begin(), vec.end(), out);
|
std::swap_ranges(vec.begin(), vec.end(), out);
|
||||||
|
|
|
@ -446,6 +446,9 @@ ADD_ASSIMP_IMPORTER(IFC
|
||||||
STEPFileEncoding.cpp
|
STEPFileEncoding.cpp
|
||||||
STEPFileEncoding.h
|
STEPFileEncoding.h
|
||||||
)
|
)
|
||||||
|
if (MSVC AND ASSIMP_BUILD_IFC_IMPORTER)
|
||||||
|
set_source_files_properties(IFCReaderGen.cpp PROPERTIES COMPILE_FLAGS "/bigobj")
|
||||||
|
endif (MSVC AND ASSIMP_BUILD_IFC_IMPORTER)
|
||||||
|
|
||||||
ADD_ASSIMP_IMPORTER(XGL
|
ADD_ASSIMP_IMPORTER(XGL
|
||||||
XGLLoader.cpp
|
XGLLoader.cpp
|
||||||
|
|
|
@ -211,7 +211,7 @@ namespace glTF
|
||||||
ComponentType_FLOAT = 5126
|
ComponentType_FLOAT = 5126
|
||||||
};
|
};
|
||||||
|
|
||||||
inline size_t ComponentTypeSize(ComponentType t)
|
inline unsigned int ComponentTypeSize(ComponentType t)
|
||||||
{
|
{
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case ComponentType_SHORT:
|
case ComponentType_SHORT:
|
||||||
|
@ -313,13 +313,13 @@ namespace glTF
|
||||||
class Ref
|
class Ref
|
||||||
{
|
{
|
||||||
std::vector<T*>* vector;
|
std::vector<T*>* vector;
|
||||||
int index;
|
unsigned int index;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Ref() : vector(0), index(0) {}
|
Ref() : vector(0), index(0) {}
|
||||||
Ref(std::vector<T*>& vec, int idx) : vector(&vec), index(idx) {}
|
Ref(std::vector<T*>& vec, unsigned int idx) : vector(&vec), index(idx) {}
|
||||||
|
|
||||||
inline size_t GetIndex() const
|
inline unsigned int GetIndex() const
|
||||||
{ return index; }
|
{ return index; }
|
||||||
|
|
||||||
operator bool() const
|
operator bool() const
|
||||||
|
@ -384,7 +384,7 @@ namespace glTF
|
||||||
inline uint8_t* GetPointer();
|
inline uint8_t* GetPointer();
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void ExtractData(T*& outData);
|
bool ExtractData(T*& outData);
|
||||||
|
|
||||||
void WriteData(size_t count, const void* src_buffer, size_t src_stride);
|
void WriteData(size_t count, const void* src_buffer, size_t src_stride);
|
||||||
|
|
||||||
|
@ -410,6 +410,11 @@ namespace glTF
|
||||||
{
|
{
|
||||||
return GetValue<unsigned int>(i);
|
return GetValue<unsigned int>(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool IsValid() const
|
||||||
|
{
|
||||||
|
return data != 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Indexer GetIndexer()
|
inline Indexer GetIndexer()
|
||||||
|
@ -466,7 +471,7 @@ namespace glTF
|
||||||
|
|
||||||
void Read(Value& obj, Asset& r);
|
void Read(Value& obj, Asset& r);
|
||||||
|
|
||||||
void LoadFromStream(IOStream& stream, size_t length = 0, size_t baseOffset = 0);
|
bool LoadFromStream(IOStream& stream, size_t length = 0, size_t baseOffset = 0);
|
||||||
|
|
||||||
size_t AppendData(uint8_t* data, size_t length);
|
size_t AppendData(uint8_t* data, size_t length);
|
||||||
void Grow(size_t amount);
|
void Grow(size_t amount);
|
||||||
|
@ -754,12 +759,12 @@ namespace glTF
|
||||||
virtual void WriteObjects(AssetWriter& writer) = 0;
|
virtual void WriteObjects(AssetWriter& writer) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! (Stub class that is specialized in glTFAssetWriter.h)
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct LazyDictWriter
|
class LazyDict;
|
||||||
{
|
|
||||||
static void Write(T& d, AssetWriter& w) {}
|
//! (Implemented in glTFAssetWriter.h)
|
||||||
};
|
template<class T>
|
||||||
|
void WriteLazyDict(LazyDict<T>& d, AssetWriter& w);
|
||||||
|
|
||||||
//! Manages lazy loading of the glTF top-level objects, and keeps a reference to them by ID
|
//! Manages lazy loading of the glTF top-level objects, and keeps a reference to them by ID
|
||||||
//! It is the owner the loaded objects, so when it is destroyed it also deletes them
|
//! It is the owner the loaded objects, so when it is destroyed it also deletes them
|
||||||
|
@ -769,7 +774,7 @@ namespace glTF
|
||||||
friend class Asset;
|
friend class Asset;
|
||||||
friend class AssetWriter;
|
friend class AssetWriter;
|
||||||
|
|
||||||
typedef typename std::gltf_unordered_map< std::string, size_t > Dict;
|
typedef typename std::gltf_unordered_map< std::string, unsigned int > Dict;
|
||||||
|
|
||||||
std::vector<T*> mObjs; //! The read objects
|
std::vector<T*> mObjs; //! The read objects
|
||||||
Dict mObjsById; //! The read objects accesible by id
|
Dict mObjsById; //! The read objects accesible by id
|
||||||
|
@ -782,7 +787,7 @@ namespace glTF
|
||||||
void DetachFromDocument();
|
void DetachFromDocument();
|
||||||
|
|
||||||
void WriteObjects(AssetWriter& writer)
|
void WriteObjects(AssetWriter& writer)
|
||||||
{ LazyDictWriter< LazyDict >::Write(*this, writer); }
|
{ WriteLazyDict<T>(*this, writer); }
|
||||||
|
|
||||||
Ref<T> Add(T* obj);
|
Ref<T> Add(T* obj);
|
||||||
|
|
||||||
|
@ -791,14 +796,14 @@ namespace glTF
|
||||||
~LazyDict();
|
~LazyDict();
|
||||||
|
|
||||||
Ref<T> Get(const char* id);
|
Ref<T> Get(const char* id);
|
||||||
Ref<T> Get(size_t i);
|
Ref<T> Get(unsigned int i);
|
||||||
|
|
||||||
Ref<T> Create(const char* id);
|
Ref<T> Create(const char* id);
|
||||||
Ref<T> Create(const std::string& id)
|
Ref<T> Create(const std::string& id)
|
||||||
{ return Create(id.c_str()); }
|
{ return Create(id.c_str()); }
|
||||||
|
|
||||||
inline size_t Size() const
|
inline unsigned int Size() const
|
||||||
{ return mObjs.size(); }
|
{ return unsigned(mObjs.size()); }
|
||||||
|
|
||||||
inline T& operator[](size_t i)
|
inline T& operator[](size_t i)
|
||||||
{ return *mObjs[i]; }
|
{ return *mObjs[i]; }
|
||||||
|
@ -820,6 +825,12 @@ namespace glTF
|
||||||
int version; //!< The glTF format version (should be 1)
|
int version; //!< The glTF format version (should be 1)
|
||||||
|
|
||||||
void Read(Document& doc);
|
void Read(Document& doc);
|
||||||
|
|
||||||
|
AssetMetadata()
|
||||||
|
: premultipliedAlpha(false)
|
||||||
|
, version(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -894,6 +905,7 @@ namespace glTF
|
||||||
public:
|
public:
|
||||||
Asset(IOSystem* io = 0)
|
Asset(IOSystem* io = 0)
|
||||||
: mIOSystem(io)
|
: mIOSystem(io)
|
||||||
|
, asset()
|
||||||
, accessors (*this, "accessors")
|
, accessors (*this, "accessors")
|
||||||
, animations (*this, "animations")
|
, animations (*this, "animations")
|
||||||
, buffers (*this, "buffers")
|
, buffers (*this, "buffers")
|
||||||
|
@ -913,7 +925,6 @@ namespace glTF
|
||||||
, lights (*this, "lights", "KHR_materials_common")
|
, lights (*this, "lights", "KHR_materials_common")
|
||||||
{
|
{
|
||||||
memset(&extensionsUsed, 0, sizeof(extensionsUsed));
|
memset(&extensionsUsed, 0, sizeof(extensionsUsed));
|
||||||
memset(&asset, 0, sizeof(asset));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Main function
|
//! Main function
|
||||||
|
|
|
@ -61,9 +61,9 @@ namespace {
|
||||||
return val.IsNumber() ? out = static_cast<float>(val.GetDouble()), true : false;
|
return val.IsNumber() ? out = static_cast<float>(val.GetDouble()), true : false;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
template<size_t N> struct ReadHelper<float[N]> { static bool Read(Value& val, float (&out)[N]) {
|
template<unsigned int N> struct ReadHelper<float[N]> { static bool Read(Value& val, float (&out)[N]) {
|
||||||
if (!val.IsArray() || val.Size() != N) return false;
|
if (!val.IsArray() || val.Size() != N) return false;
|
||||||
for (size_t i = 0; i < N; ++i) {
|
for (unsigned int i = 0; i < N; ++i) {
|
||||||
if (val[i].IsNumber())
|
if (val[i].IsNumber())
|
||||||
out[i] = static_cast<float>(val[i].GetDouble());
|
out[i] = static_cast<float>(val[i].GetDouble());
|
||||||
}
|
}
|
||||||
|
@ -71,11 +71,11 @@ namespace {
|
||||||
}};
|
}};
|
||||||
|
|
||||||
template<> struct ReadHelper<const char*> { static bool Read(Value& val, const char*& out) {
|
template<> struct ReadHelper<const char*> { static bool Read(Value& val, const char*& out) {
|
||||||
return val.IsString() ? out = val.GetString(), true : false;
|
return val.IsString() ? (out = val.GetString(), true) : false;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
template<> struct ReadHelper<std::string> { static bool Read(Value& val, std::string& out) {
|
template<> struct ReadHelper<std::string> { static bool Read(Value& val, std::string& out) {
|
||||||
return val.IsString() ? out = val.GetString(), true : false;
|
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) {
|
template<class T> struct ReadHelper< Nullable<T> > { static bool Read(Value& val, Nullable<T>& out) {
|
||||||
|
@ -176,7 +176,7 @@ inline void LazyDict<T>::DetachFromDocument()
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
Ref<T> LazyDict<T>::Get(size_t i)
|
Ref<T> LazyDict<T>::Get(unsigned int i)
|
||||||
{
|
{
|
||||||
return Ref<T>(mObjs, i);
|
return Ref<T>(mObjs, i);
|
||||||
}
|
}
|
||||||
|
@ -196,10 +196,10 @@ Ref<T> LazyDict<T>::Get(const char* id)
|
||||||
|
|
||||||
Value::MemberIterator obj = mDict->FindMember(id);
|
Value::MemberIterator obj = mDict->FindMember(id);
|
||||||
if (obj == mDict->MemberEnd()) {
|
if (obj == mDict->MemberEnd()) {
|
||||||
throw DeadlyImportError("Missing object with id \"" + std::string(id) + "\" in \"" + mDictId + "\"");
|
throw DeadlyImportError("GLTF: Missing object with id \"" + std::string(id) + "\" in \"" + mDictId + "\"");
|
||||||
}
|
}
|
||||||
if (!obj->value.IsObject()) {
|
if (!obj->value.IsObject()) {
|
||||||
throw DeadlyImportError("Object with id \"" + std::string(id) + "\" is not a JSON object!");
|
throw DeadlyImportError("GLTF: Object with id \"" + std::string(id) + "\" is not a JSON object");
|
||||||
}
|
}
|
||||||
|
|
||||||
// create an instance of the given type
|
// create an instance of the given type
|
||||||
|
@ -213,7 +213,7 @@ Ref<T> LazyDict<T>::Get(const char* id)
|
||||||
template<class T>
|
template<class T>
|
||||||
Ref<T> LazyDict<T>::Add(T* obj)
|
Ref<T> LazyDict<T>::Add(T* obj)
|
||||||
{
|
{
|
||||||
size_t idx = mObjs.size();
|
unsigned int idx = unsigned(mObjs.size());
|
||||||
mObjs.push_back(obj);
|
mObjs.push_back(obj);
|
||||||
mObjsById[obj->id] = idx;
|
mObjsById[obj->id] = idx;
|
||||||
mAsset.mUsedIds[obj->id] = true;
|
mAsset.mUsedIds[obj->id] = true;
|
||||||
|
@ -225,7 +225,7 @@ Ref<T> LazyDict<T>::Create(const char* id)
|
||||||
{
|
{
|
||||||
Asset::IdMap::iterator it = mAsset.mUsedIds.find(id);
|
Asset::IdMap::iterator it = mAsset.mUsedIds.find(id);
|
||||||
if (it != mAsset.mUsedIds.end()) {
|
if (it != mAsset.mUsedIds.end()) {
|
||||||
throw DeadlyImportError("Two objects with the same ID exist!");
|
throw DeadlyImportError("GLTF: two objects with the same ID exist");
|
||||||
}
|
}
|
||||||
T* inst = new T();
|
T* inst = new T();
|
||||||
inst->id = id;
|
inst->id = id;
|
||||||
|
@ -249,7 +249,12 @@ inline void Buffer::Read(Value& obj, Asset& r)
|
||||||
byteLength = statedLength;
|
byteLength = statedLength;
|
||||||
|
|
||||||
Value* it = FindString(obj, "uri");
|
Value* it = FindString(obj, "uri");
|
||||||
if (!it) return;
|
if (!it) {
|
||||||
|
if (statedLength > 0) {
|
||||||
|
throw DeadlyImportError("GLTF: buffer with non-zero length missing the \"uri\" attribute");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const char* uri = it->GetString();
|
const char* uri = it->GetString();
|
||||||
|
|
||||||
|
@ -261,22 +266,32 @@ inline void Buffer::Read(Value& obj, Asset& r)
|
||||||
this->mData.reset(data);
|
this->mData.reset(data);
|
||||||
|
|
||||||
if (statedLength > 0 && this->byteLength != statedLength) {
|
if (statedLength > 0 && this->byteLength != statedLength) {
|
||||||
// error?
|
throw DeadlyImportError("GLTF: buffer length mismatch");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else { // assume raw data
|
||||||
|
this->mData.reset(new uint8_t[dataURI.dataLength]);
|
||||||
|
memcmp(dataURI.data, this->mData.get(), dataURI.dataLength);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else { // Local file
|
else { // Local file
|
||||||
if (byteLength > 0) {
|
if (byteLength > 0) {
|
||||||
IOStream* file = r.OpenFile(uri, "rb");
|
IOStream* file = r.OpenFile(uri, "rb");
|
||||||
if (file) {
|
if (file) {
|
||||||
LoadFromStream(*file, byteLength);
|
bool ok = LoadFromStream(*file, byteLength);
|
||||||
delete file;
|
delete file;
|
||||||
|
|
||||||
|
if (!ok)
|
||||||
|
throw DeadlyImportError("GLTF: error while reading referenced file \"" + std::string(uri) + "\"" );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw DeadlyImportError("GLTF: could not open referenced file \"" + std::string(uri) + "\"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Buffer::LoadFromStream(IOStream& stream, size_t length, size_t baseOffset)
|
inline bool Buffer::LoadFromStream(IOStream& stream, size_t length, size_t baseOffset)
|
||||||
{
|
{
|
||||||
byteLength = length ? length : stream.FileSize();
|
byteLength = length ? length : stream.FileSize();
|
||||||
|
|
||||||
|
@ -287,8 +302,9 @@ inline void Buffer::LoadFromStream(IOStream& stream, size_t length, size_t baseO
|
||||||
mData.reset(new uint8_t[byteLength]);
|
mData.reset(new uint8_t[byteLength]);
|
||||||
|
|
||||||
if (stream.Read(mData.get(), byteLength, 1) != 1) {
|
if (stream.Read(mData.get(), byteLength, 1) != 1) {
|
||||||
throw DeadlyImportError("Unable to load buffer from file!");
|
return false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t Buffer::AppendData(uint8_t* data, size_t length)
|
inline size_t Buffer::AppendData(uint8_t* data, size_t length)
|
||||||
|
@ -345,7 +361,7 @@ inline unsigned int Accessor::GetNumComponents()
|
||||||
|
|
||||||
inline unsigned int Accessor::GetBytesPerComponent()
|
inline unsigned int Accessor::GetBytesPerComponent()
|
||||||
{
|
{
|
||||||
return ComponentTypeSize(componentType);
|
return int(ComponentTypeSize(componentType));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned int Accessor::GetElementSize()
|
inline unsigned int Accessor::GetElementSize()
|
||||||
|
@ -356,9 +372,11 @@ inline unsigned int Accessor::GetElementSize()
|
||||||
inline uint8_t* Accessor::GetPointer()
|
inline uint8_t* Accessor::GetPointer()
|
||||||
{
|
{
|
||||||
if (!bufferView || !bufferView->buffer) return 0;
|
if (!bufferView || !bufferView->buffer) return 0;
|
||||||
|
uint8_t* basePtr = bufferView->buffer->GetPointer();
|
||||||
|
if (!basePtr) return 0;
|
||||||
|
|
||||||
size_t offset = byteOffset + bufferView->byteOffset;
|
size_t offset = byteOffset + bufferView->byteOffset;
|
||||||
return bufferView->buffer->GetPointer() + offset;
|
return basePtr + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -384,10 +402,10 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void Accessor::ExtractData(T*& outData)
|
bool Accessor::ExtractData(T*& outData)
|
||||||
{
|
{
|
||||||
uint8_t* data = GetPointer();
|
uint8_t* data = GetPointer();
|
||||||
ai_assert(data);
|
if (!data) return false;
|
||||||
|
|
||||||
const size_t elemSize = GetElementSize();
|
const size_t elemSize = GetElementSize();
|
||||||
const size_t totalSize = elemSize * count;
|
const size_t totalSize = elemSize * count;
|
||||||
|
@ -408,6 +426,8 @@ void Accessor::ExtractData(T*& outData)
|
||||||
memcpy(outData + i, data + i*stride, elemSize);
|
memcpy(outData + i, data + i*stride, elemSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Accessor::WriteData(size_t count, const void* src_buffer, size_t src_stride)
|
inline void Accessor::WriteData(size_t count, const void* src_buffer, size_t src_stride)
|
||||||
|
@ -683,7 +703,7 @@ inline void Camera::Read(Value& obj, Asset& r)
|
||||||
const char* subobjId = (type == Camera::Orthographic) ? "ortographic" : "perspective";
|
const char* subobjId = (type == Camera::Orthographic) ? "ortographic" : "perspective";
|
||||||
|
|
||||||
Value* it = FindObject(obj, subobjId);
|
Value* it = FindObject(obj, subobjId);
|
||||||
if (!it) throw DeadlyImportError("Camera missing its parameters!");
|
if (!it) throw DeadlyImportError("GLTF: Camera missing its parameters");
|
||||||
|
|
||||||
if (type == Camera::Perspective) {
|
if (type == Camera::Perspective) {
|
||||||
perspective.aspectRatio = MemberOrDefault(*it, "aspectRatio", 0.f);
|
perspective.aspectRatio = MemberOrDefault(*it, "aspectRatio", 0.f);
|
||||||
|
@ -770,12 +790,12 @@ inline void Node::Read(Value& obj, Asset& r)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Value* meshes = FindArray(obj, "meshes")) {
|
if (Value* meshes = FindArray(obj, "meshes")) {
|
||||||
size_t numMeshes = (size_t)meshes->Size();
|
unsigned numMeshes = (unsigned)meshes->Size();
|
||||||
|
|
||||||
std::vector<unsigned int> meshList;
|
std::vector<unsigned int> meshList;
|
||||||
|
|
||||||
this->meshes.reserve(numMeshes);
|
this->meshes.reserve(numMeshes);
|
||||||
for (size_t i = 0; i < numMeshes; ++i) {
|
for (unsigned i = 0; i < numMeshes; ++i) {
|
||||||
if ((*meshes)[i].IsString()) {
|
if ((*meshes)[i].IsString()) {
|
||||||
Ref<Mesh> mesh = r.meshes.Get((*meshes)[i].GetString());
|
Ref<Mesh> mesh = r.meshes.Get((*meshes)[i].GetString());
|
||||||
if (mesh) this->meshes.push_back(mesh);
|
if (mesh) this->meshes.push_back(mesh);
|
||||||
|
@ -842,7 +862,7 @@ inline void AssetMetadata::Read(Document& doc)
|
||||||
|
|
||||||
if (version != 1) {
|
if (version != 1) {
|
||||||
char msg[128];
|
char msg[128];
|
||||||
ai_snprintf(msg, 128, "Unsupported glTF version: %d", version);
|
ai_snprintf(msg, 128, "GLTF: Unsupported glTF version: %d", version);
|
||||||
throw DeadlyImportError(msg);
|
throw DeadlyImportError(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -857,22 +877,22 @@ inline void Asset::ReadBinaryHeader(IOStream& stream)
|
||||||
{
|
{
|
||||||
GLB_Header header;
|
GLB_Header header;
|
||||||
if (stream.Read(&header, sizeof(header), 1) != 1) {
|
if (stream.Read(&header, sizeof(header), 1) != 1) {
|
||||||
throw DeadlyImportError("Unable to read the file header");
|
throw DeadlyImportError("GLTF: Unable to read the file header");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strncmp((char*)header.magic, AI_GLB_MAGIC_NUMBER, sizeof(header.magic)) != 0) {
|
if (strncmp((char*)header.magic, AI_GLB_MAGIC_NUMBER, sizeof(header.magic)) != 0) {
|
||||||
throw DeadlyImportError("Invalid binary glTF file");
|
throw DeadlyImportError("GLTF: Invalid binary glTF file");
|
||||||
}
|
}
|
||||||
|
|
||||||
AI_SWAP4(header.version);
|
AI_SWAP4(header.version);
|
||||||
asset.version = header.version;
|
asset.version = header.version;
|
||||||
if (header.version != 1) {
|
if (header.version != 1) {
|
||||||
throw DeadlyImportError("Unsupported binary glTF version");
|
throw DeadlyImportError("GLTF: Unsupported binary glTF version");
|
||||||
}
|
}
|
||||||
|
|
||||||
AI_SWAP4(header.sceneFormat);
|
AI_SWAP4(header.sceneFormat);
|
||||||
if (header.sceneFormat != SceneFormat_JSON) {
|
if (header.sceneFormat != SceneFormat_JSON) {
|
||||||
throw DeadlyImportError("Unsupported binary glTF scene format");
|
throw DeadlyImportError("GLTF: Unsupported binary glTF scene format");
|
||||||
}
|
}
|
||||||
|
|
||||||
AI_SWAP4(header.length);
|
AI_SWAP4(header.length);
|
||||||
|
@ -894,7 +914,7 @@ inline void Asset::Load(const std::string& pFile, bool isBinary)
|
||||||
|
|
||||||
shared_ptr<IOStream> stream(OpenFile(pFile.c_str(), "rb", true));
|
shared_ptr<IOStream> stream(OpenFile(pFile.c_str(), "rb", true));
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
throw DeadlyImportError("Could not open file for reading");
|
throw DeadlyImportError("GLTF: Could not open file for reading");
|
||||||
}
|
}
|
||||||
|
|
||||||
// is binary? then read the header
|
// is binary? then read the header
|
||||||
|
@ -914,7 +934,7 @@ inline void Asset::Load(const std::string& pFile, bool isBinary)
|
||||||
sceneData[mSceneLength] = '\0';
|
sceneData[mSceneLength] = '\0';
|
||||||
|
|
||||||
if (stream->Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
|
if (stream->Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
|
||||||
throw DeadlyImportError("Could not read the file contents");
|
throw DeadlyImportError("GLTF: Could not read the file contents");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -926,17 +946,19 @@ inline void Asset::Load(const std::string& pFile, bool isBinary)
|
||||||
if (doc.HasParseError()) {
|
if (doc.HasParseError()) {
|
||||||
char buffer[32];
|
char buffer[32];
|
||||||
ai_snprintf(buffer, 32, "%d", static_cast<int>(doc.GetErrorOffset()));
|
ai_snprintf(buffer, 32, "%d", static_cast<int>(doc.GetErrorOffset()));
|
||||||
throw DeadlyImportError(std::string("JSON parse error, offset ") + buffer + ": "
|
throw DeadlyImportError(std::string("GLTF: JSON parse error, offset ") + buffer + ": "
|
||||||
+ GetParseError_En(doc.GetParseError()));
|
+ GetParseError_En(doc.GetParseError()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!doc.IsObject()) {
|
if (!doc.IsObject()) {
|
||||||
throw DeadlyImportError("gltf file must be a JSON object!");
|
throw DeadlyImportError("GLTF: JSON document root must be a JSON object");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill the buffer instance for the current file embedded contents
|
// Fill the buffer instance for the current file embedded contents
|
||||||
if (mBodyLength > 0) {
|
if (mBodyLength > 0) {
|
||||||
mBodyBuffer->LoadFromStream(*stream, mBodyLength, mBodyOffset);
|
if (!mBodyBuffer->LoadFromStream(*stream, mBodyLength, mBodyOffset)) {
|
||||||
|
throw DeadlyImportError("GLTF: Unable to read gltf file");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -967,7 +989,7 @@ inline void Asset::SetAsBinary()
|
||||||
{
|
{
|
||||||
if (!extensionsUsed.KHR_binary_glTF) {
|
if (!extensionsUsed.KHR_binary_glTF) {
|
||||||
extensionsUsed.KHR_binary_glTF = true;
|
extensionsUsed.KHR_binary_glTF = true;
|
||||||
mBodyBuffer = buffers.Create("KHR_binary_glTF");
|
mBodyBuffer = buffers.Create("binary_glTF");
|
||||||
mBodyBuffer->MarkAsSpecial();
|
mBodyBuffer->MarkAsSpecial();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1013,30 +1035,26 @@ inline std::string Asset::FindUniqueID(const std::string& str, const char* suffi
|
||||||
{
|
{
|
||||||
std::string id = str;
|
std::string id = str;
|
||||||
|
|
||||||
Asset::IdMap::iterator it;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (!id.empty()) {
|
if (!id.empty()) {
|
||||||
it = mUsedIds.find(id);
|
if (mUsedIds.find(id) == mUsedIds.end())
|
||||||
if (it == mUsedIds.end()) break;
|
return id;
|
||||||
|
|
||||||
id += "_";
|
id += "_";
|
||||||
}
|
}
|
||||||
|
|
||||||
id += suffix;
|
id += suffix;
|
||||||
|
|
||||||
it = mUsedIds.find(id);
|
Asset::IdMap::iterator it = mUsedIds.find(id);
|
||||||
if (it == mUsedIds.end()) break;
|
if (it == mUsedIds.end())
|
||||||
|
return id;
|
||||||
|
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
int offset = ai_snprintf(buffer, 256, "%s_", id.c_str());
|
int offset = ai_snprintf(buffer, sizeof(buffer), "%s_", id.c_str());
|
||||||
for (int i = 0; it != mUsedIds.end(); ++i) {
|
for (int i = 0; it != mUsedIds.end(); ++i) {
|
||||||
ai_snprintf(buffer + offset, 256, "%d", i);
|
ai_snprintf(buffer + offset, sizeof(buffer) - offset, "%d", i);
|
||||||
|
|
||||||
id = buffer;
|
id = buffer;
|
||||||
it = mUsedIds.find(id);
|
it = mUsedIds.find(id);
|
||||||
}
|
}
|
||||||
} while (false); // fake loop to allow using "break"
|
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
@ -1066,7 +1084,7 @@ namespace Util {
|
||||||
|
|
||||||
size_t i = 5, j;
|
size_t i = 5, j;
|
||||||
if (uri[i] != ';' && uri[i] != ',') { // has media type?
|
if (uri[i] != ';' && uri[i] != ',') { // has media type?
|
||||||
uri[1] = i;
|
uri[1] = char(i);
|
||||||
for (; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
|
for (; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
|
||||||
// nothing to do!
|
// nothing to do!
|
||||||
}
|
}
|
||||||
|
@ -1078,14 +1096,14 @@ namespace Util {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( strncmp( uri + j, "charset=", 8 ) == 0 ) {
|
if ( strncmp( uri + j, "charset=", 8 ) == 0 ) {
|
||||||
uri[ 2 ] = j + 8;
|
uri[2] = char(j + 8);
|
||||||
} else if ( strncmp( uri + j, "base64", 6 ) == 0 ) {
|
} else if ( strncmp( uri + j, "base64", 6 ) == 0 ) {
|
||||||
uri[ 3 ] = j;
|
uri[3] = char(j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i < uriLen) {
|
if (i < uriLen) {
|
||||||
uri[i++] = '\0';
|
uri[i++] = '\0';
|
||||||
uri[4] = i;
|
uri[4] = char(i);
|
||||||
} else {
|
} else {
|
||||||
uri[1] = uri[2] = uri[3] = 0;
|
uri[1] = uri[2] = uri[3] = 0;
|
||||||
uri[4] = 5;
|
uri[4] = 5;
|
||||||
|
|
|
@ -58,7 +58,7 @@ using rapidjson::MemoryPoolAllocator;
|
||||||
class AssetWriter
|
class AssetWriter
|
||||||
{
|
{
|
||||||
template<class T>
|
template<class T>
|
||||||
friend struct LazyDictWriter;
|
friend void WriteLazyDict(LazyDict<T>& d, AssetWriter& w);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ namespace glTF {
|
||||||
if (v.empty()) return;
|
if (v.empty()) return;
|
||||||
Value lst;
|
Value lst;
|
||||||
lst.SetArray();
|
lst.SetArray();
|
||||||
lst.Reserve(v.size(), al);
|
lst.Reserve(unsigned(v.size()), al);
|
||||||
for (size_t i = 0; i < v.size(); ++i) {
|
for (size_t i = 0; i < v.size(); ++i) {
|
||||||
lst.PushBack(StringRef(v[i]->id), al);
|
lst.PushBack(StringRef(v[i]->id), al);
|
||||||
}
|
}
|
||||||
|
@ -201,7 +201,7 @@ namespace glTF {
|
||||||
{
|
{
|
||||||
Value primitives;
|
Value primitives;
|
||||||
primitives.SetArray();
|
primitives.SetArray();
|
||||||
primitives.Reserve(m.primitives.size(), w.mAl);
|
primitives.Reserve(unsigned(m.primitives.size()), w.mAl);
|
||||||
|
|
||||||
for (size_t i = 0; i < m.primitives.size(); ++i) {
|
for (size_t i = 0; i < m.primitives.size(); ++i) {
|
||||||
Mesh::Primitive& p = m.primitives[i];
|
Mesh::Primitive& p = m.primitives[i];
|
||||||
|
@ -396,10 +396,10 @@ namespace glTF {
|
||||||
header.version = 1;
|
header.version = 1;
|
||||||
AI_SWAP4(header.version);
|
AI_SWAP4(header.version);
|
||||||
|
|
||||||
header.length = sizeof(header) + sceneLength + bodyLength;
|
header.length = uint32_t(sizeof(header) + sceneLength + bodyLength);
|
||||||
AI_SWAP4(header.length);
|
AI_SWAP4(header.length);
|
||||||
|
|
||||||
header.sceneLength = sceneLength;
|
header.sceneLength = uint32_t(sceneLength);
|
||||||
AI_SWAP4(header.sceneLength);
|
AI_SWAP4(header.sceneLength);
|
||||||
|
|
||||||
header.sceneFormat = SceneFormat_JSON;
|
header.sceneFormat = SceneFormat_JSON;
|
||||||
|
@ -484,13 +484,10 @@ namespace glTF {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct LazyDictWriter< LazyDict<T> >
|
void WriteLazyDict(LazyDict<T>& d, AssetWriter& w)
|
||||||
{
|
|
||||||
static void Write(LazyDict<T>& d, AssetWriter& w)
|
|
||||||
{
|
{
|
||||||
w.WriteObjects(d);
|
w.WriteObjects(d);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -159,7 +159,7 @@ inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& bu
|
||||||
// accessor
|
// accessor
|
||||||
Ref<Accessor> acc = a.accessors.Create(a.FindUniqueID(meshName, "accessor"));
|
Ref<Accessor> acc = a.accessors.Create(a.FindUniqueID(meshName, "accessor"));
|
||||||
acc->bufferView = bv;
|
acc->bufferView = bv;
|
||||||
acc->byteOffset = offset;
|
acc->byteOffset = unsigned(offset);
|
||||||
acc->byteStride = 0;
|
acc->byteStride = 0;
|
||||||
acc->componentType = compType;
|
acc->componentType = compType;
|
||||||
acc->count = count;
|
acc->count = count;
|
||||||
|
@ -187,7 +187,7 @@ void glTFExporter::GetMatColorOrTex(const aiMaterial* mat, glTF::TexProperty& pr
|
||||||
|
|
||||||
if (path.size() > 0) {
|
if (path.size() > 0) {
|
||||||
if (path[0] != '*') {
|
if (path[0] != '*') {
|
||||||
std::map<std::string, size_t>::iterator it = mTexturesByPath.find(path);
|
std::map<std::string, unsigned int>::iterator it = mTexturesByPath.find(path);
|
||||||
if (it != mTexturesByPath.end()) {
|
if (it != mTexturesByPath.end()) {
|
||||||
prop.texture = mAsset->textures.Get(it->second);
|
prop.texture = mAsset->textures.Get(it->second);
|
||||||
}
|
}
|
||||||
|
@ -292,7 +292,7 @@ void glTFExporter::ExportMeshes()
|
||||||
indices[i*nIndicesPerFace + j] = uint16_t(aim->mFaces[i].mIndices[j]);
|
indices[i*nIndicesPerFace + j] = uint16_t(aim->mFaces[i].mIndices[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.indices = ExportData(*mAsset, meshId, b, indices.size(), &indices[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_UNSIGNED_SHORT);
|
p.indices = ExportData(*mAsset, meshId, b, unsigned(indices.size()), &indices[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_UNSIGNED_SHORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (aim->mPrimitiveTypes) {
|
switch (aim->mPrimitiveTypes) {
|
||||||
|
@ -308,7 +308,7 @@ void glTFExporter::ExportMeshes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t glTFExporter::ExportNode(const aiNode* n)
|
unsigned int glTFExporter::ExportNode(const aiNode* n)
|
||||||
{
|
{
|
||||||
Ref<Node> node = mAsset->nodes.Create(mAsset->FindUniqueID(n->mName.C_Str(), "node"));
|
Ref<Node> node = mAsset->nodes.Create(mAsset->FindUniqueID(n->mName.C_Str(), "node"));
|
||||||
|
|
||||||
|
@ -322,7 +322,7 @@ size_t glTFExporter::ExportNode(const aiNode* n)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < n->mNumChildren; ++i) {
|
for (unsigned int i = 0; i < n->mNumChildren; ++i) {
|
||||||
size_t idx = ExportNode(n->mChildren[i]);
|
unsigned int idx = ExportNode(n->mChildren[i]);
|
||||||
node->children.push_back(mAsset->nodes.Get(idx));
|
node->children.push_back(mAsset->nodes.Get(idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,7 +337,7 @@ void glTFExporter::ExportScene()
|
||||||
|
|
||||||
// root node will be the first one exported (idx 0)
|
// root node will be the first one exported (idx 0)
|
||||||
if (mAsset->nodes.Size() > 0) {
|
if (mAsset->nodes.Size() > 0) {
|
||||||
scene->nodes.push_back(mAsset->nodes.Get(size_t(0)));
|
scene->nodes.push_back(mAsset->nodes.Get(0u));
|
||||||
}
|
}
|
||||||
|
|
||||||
// set as the default scene
|
// set as the default scene
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace Assimp
|
||||||
const aiScene* mScene;
|
const aiScene* mScene;
|
||||||
const ExportProperties* mProperties;
|
const ExportProperties* mProperties;
|
||||||
|
|
||||||
std::map<std::string, size_t> mTexturesByPath;
|
std::map<std::string, unsigned int> mTexturesByPath;
|
||||||
|
|
||||||
glTF::Asset* mAsset;
|
glTF::Asset* mAsset;
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ namespace Assimp
|
||||||
void ExportMetadata();
|
void ExportMetadata();
|
||||||
void ExportMaterials();
|
void ExportMaterials();
|
||||||
void ExportMeshes();
|
void ExportMeshes();
|
||||||
size_t ExportNode(const aiNode* node);
|
unsigned int ExportNode(const aiNode* node);
|
||||||
void ExportScene();
|
void ExportScene();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "MakeVerboseFormat.h"
|
||||||
|
|
||||||
#include "glTFAsset.h"
|
#include "glTFAsset.h"
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
@ -180,7 +182,7 @@ inline void SetMaterialColorProperty(std::vector<int>& embeddedTexIdxs, Asset& r
|
||||||
|
|
||||||
void glTFImporter::ImportMaterials(glTF::Asset& r)
|
void glTFImporter::ImportMaterials(glTF::Asset& r)
|
||||||
{
|
{
|
||||||
mScene->mNumMaterials = r.materials.Size();
|
mScene->mNumMaterials = unsigned(r.materials.Size());
|
||||||
mScene->mMaterials = new aiMaterial*[mScene->mNumMaterials];
|
mScene->mMaterials = new aiMaterial*[mScene->mNumMaterials];
|
||||||
|
|
||||||
for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) {
|
for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) {
|
||||||
|
@ -244,7 +246,7 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
|
||||||
Mesh& mesh = r.meshes[m];
|
Mesh& mesh = r.meshes[m];
|
||||||
|
|
||||||
meshOffsets.push_back(k);
|
meshOffsets.push_back(k);
|
||||||
k += mesh.primitives.size();
|
k += unsigned(mesh.primitives.size());
|
||||||
|
|
||||||
for (unsigned int p = 0; p < mesh.primitives.size(); ++p) {
|
for (unsigned int p = 0; p < mesh.primitives.size(); ++p) {
|
||||||
Mesh::Primitive& prim = mesh.primitives[p];
|
Mesh::Primitive& prim = mesh.primitives[p];
|
||||||
|
@ -256,7 +258,7 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
|
||||||
if (mesh.primitives.size() > 1) {
|
if (mesh.primitives.size() > 1) {
|
||||||
size_t& len = aim->mName.length;
|
size_t& len = aim->mName.length;
|
||||||
aim->mName.data[len] = '-';
|
aim->mName.data[len] = '-';
|
||||||
len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, MAXLEN - len - 1, p);
|
len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, unsigned(MAXLEN - len - 1), p);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (prim.mode) {
|
switch (prim.mode) {
|
||||||
|
@ -295,11 +297,12 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
|
||||||
|
|
||||||
if (prim.indices) {
|
if (prim.indices) {
|
||||||
aiFace* faces = 0;
|
aiFace* faces = 0;
|
||||||
size_t nFaces = 0;
|
unsigned int nFaces = 0;
|
||||||
|
|
||||||
unsigned int count = prim.indices->count;
|
unsigned int count = prim.indices->count;
|
||||||
|
|
||||||
Accessor::Indexer data = prim.indices->GetIndexer();
|
Accessor::Indexer data = prim.indices->GetIndexer();
|
||||||
|
assert(data.IsValid());
|
||||||
|
|
||||||
switch (prim.mode) {
|
switch (prim.mode) {
|
||||||
case PrimitiveMode_POINTS: {
|
case PrimitiveMode_POINTS: {
|
||||||
|
@ -451,7 +454,7 @@ aiNode* ImportNode(aiScene* pScene, glTF::Asset& r, std::vector<unsigned int>& m
|
||||||
aiNode* ainode = new aiNode(node.id);
|
aiNode* ainode = new aiNode(node.id);
|
||||||
|
|
||||||
if (!node.children.empty()) {
|
if (!node.children.empty()) {
|
||||||
ainode->mNumChildren = node.children.size();
|
ainode->mNumChildren = unsigned(node.children.size());
|
||||||
ainode->mChildren = new aiNode*[ainode->mNumChildren];
|
ainode->mChildren = new aiNode*[ainode->mNumChildren];
|
||||||
|
|
||||||
for (unsigned int i = 0; i < ainode->mNumChildren; ++i) {
|
for (unsigned int i = 0; i < ainode->mNumChildren; ++i) {
|
||||||
|
@ -503,7 +506,7 @@ aiNode* ImportNode(aiScene* pScene, glTF::Asset& r, std::vector<unsigned int>& m
|
||||||
int k = 0;
|
int k = 0;
|
||||||
for (size_t i = 0; i < node.meshes.size(); ++i) {
|
for (size_t i = 0; i < node.meshes.size(); ++i) {
|
||||||
int idx = node.meshes[i].GetIndex();
|
int idx = node.meshes[i].GetIndex();
|
||||||
for (size_t j = meshOffsets[idx]; j < meshOffsets[idx + 1]; ++j, ++k) {
|
for (unsigned int j = meshOffsets[idx]; j < meshOffsets[idx + 1]; ++j, ++k) {
|
||||||
ainode->mMeshes[k] = j;
|
ainode->mMeshes[k] = j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -527,7 +530,7 @@ void glTFImporter::ImportNodes(glTF::Asset& r)
|
||||||
std::vector< Ref<Node> > rootNodes = r.scene->nodes;
|
std::vector< Ref<Node> > rootNodes = r.scene->nodes;
|
||||||
|
|
||||||
// The root nodes
|
// The root nodes
|
||||||
unsigned int numRootNodes = rootNodes.size();
|
unsigned int numRootNodes = unsigned(rootNodes.size());
|
||||||
if (numRootNodes == 1) { // a single root node: use it
|
if (numRootNodes == 1) { // a single root node: use it
|
||||||
mScene->mRootNode = ImportNode(mScene, r, meshOffsets, rootNodes[0]);
|
mScene->mRootNode = ImportNode(mScene, r, meshOffsets, rootNodes[0]);
|
||||||
}
|
}
|
||||||
|
@ -617,7 +620,10 @@ void glTFImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOS
|
||||||
ImportNodes(asset);
|
ImportNodes(asset);
|
||||||
|
|
||||||
// TODO: it does not split the loaded vertices, should it?
|
// TODO: it does not split the loaded vertices, should it?
|
||||||
pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
|
//pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
|
||||||
|
Assimp::MakeVerboseFormatProcess process;
|
||||||
|
process.Execute(pScene);
|
||||||
|
|
||||||
|
|
||||||
if (pScene->mNumMeshes == 0) {
|
if (pScene->mNumMeshes == 0) {
|
||||||
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
|
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
|
||||||
|
|
Loading…
Reference in New Issue