Merge branch 'master' into master
commit
72da1e6d7b
|
@ -260,20 +260,9 @@ public:
|
||||||
VEC4,
|
VEC4,
|
||||||
MAT2,
|
MAT2,
|
||||||
MAT3,
|
MAT3,
|
||||||
MAT4 };
|
MAT4
|
||||||
|
|
||||||
private:
|
|
||||||
static const size_t NUM_VALUES = static_cast<size_t>(MAT4) + 1;
|
|
||||||
|
|
||||||
struct Info {
|
|
||||||
const char *name;
|
|
||||||
unsigned int numComponents;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <int N>
|
|
||||||
struct data { static const Info infos[NUM_VALUES]; };
|
|
||||||
|
|
||||||
public:
|
|
||||||
inline static Value FromString(const char *str) {
|
inline static Value FromString(const char *str) {
|
||||||
for (size_t i = 0; i < NUM_VALUES; ++i) {
|
for (size_t i = 0; i < NUM_VALUES; ++i) {
|
||||||
if (strcmp(data<0>::infos[i].name, str) == 0) {
|
if (strcmp(data<0>::infos[i].name, str) == 0) {
|
||||||
|
@ -290,40 +279,31 @@ public:
|
||||||
inline static unsigned int GetNumComponents(Value type) {
|
inline static unsigned int GetNumComponents(Value type) {
|
||||||
return data<0>::infos[static_cast<size_t>(type)].numComponents;
|
return data<0>::infos[static_cast<size_t>(type)].numComponents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const size_t NUM_VALUES = static_cast<size_t>(MAT4) + 1;
|
||||||
|
struct Info {
|
||||||
|
const char *name;
|
||||||
|
unsigned int numComponents;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <int N>
|
||||||
|
struct data {
|
||||||
|
static const Info infos[NUM_VALUES];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// must match the order of the AttribTypeTraits::Value enum!
|
// must match the order of the AttribTypeTraits::Value enum!
|
||||||
template <int N>
|
template <int N>
|
||||||
const AttribType::Info
|
const AttribType::Info AttribType::data<N>::infos[AttribType::NUM_VALUES] = {
|
||||||
AttribType::data<N>::infos[AttribType::NUM_VALUES] = {
|
{ "SCALAR", 1 },
|
||||||
{ "SCALAR", 1 }, { "VEC2", 2 }, { "VEC3", 3 }, { "VEC4", 4 }, { "MAT2", 4 }, { "MAT3", 9 }, { "MAT4", 16 }
|
{ "VEC2", 2 },
|
||||||
};
|
{ "VEC3", 3 },
|
||||||
|
{ "VEC4", 4 },
|
||||||
/*
|
{ "MAT2", 4 },
|
||||||
//! A reference to one top-level object, which is valid
|
{ "MAT3", 9 },
|
||||||
//! until the Asset instance is destroyed
|
{ "MAT4", 16 }
|
||||||
template<class T>
|
};
|
||||||
class Ref
|
|
||||||
{
|
|
||||||
std::vector<T*>* vector;
|
|
||||||
unsigned int index;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Ref() : vector(0), 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 != 0; }
|
|
||||||
|
|
||||||
T* operator->()
|
|
||||||
{ return (*vector)[index]; }
|
|
||||||
|
|
||||||
T& operator*()
|
|
||||||
{ return *((*vector)[index]); }
|
|
||||||
};*/
|
|
||||||
|
|
||||||
//! Base class for all glTF top-level objects
|
//! Base class for all glTF top-level objects
|
||||||
struct Object {
|
struct Object {
|
||||||
|
@ -333,6 +313,7 @@ struct Object {
|
||||||
//! Objects marked as special are not exported (used to emulate the binary body buffer)
|
//! Objects marked as special are not exported (used to emulate the binary body buffer)
|
||||||
virtual bool IsSpecial() const { return false; }
|
virtual bool IsSpecial() const { return false; }
|
||||||
|
|
||||||
|
Object() = default;
|
||||||
virtual ~Object() {}
|
virtual ~Object() {}
|
||||||
|
|
||||||
//! Maps special IDs to another ID, where needed. Subclasses may override it (statically)
|
//! Maps special IDs to another ID, where needed. Subclasses may override it (statically)
|
||||||
|
@ -401,21 +382,19 @@ struct Accessor : public Object {
|
||||||
return Indexer(*this);
|
return Indexer(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Accessor() {}
|
Accessor() = default;
|
||||||
void Read(Value &obj, Asset &r);
|
void Read(Value &obj, Asset &r);
|
||||||
};
|
};
|
||||||
|
|
||||||
//! A buffer points to binary geometry, animation, or skins.
|
//! A buffer points to binary geometry, animation, or skins.
|
||||||
struct Buffer : public Object {
|
struct Buffer : public Object {
|
||||||
/********************* Types *********************/
|
/********************* Types *********************/
|
||||||
public:
|
|
||||||
enum Type {
|
enum Type {
|
||||||
Type_arraybuffer,
|
Type_arraybuffer,
|
||||||
Type_text
|
Type_text
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \struct SEncodedRegion
|
/// @brief Descriptor of encoded region in "bufferView".
|
||||||
/// Descriptor of encoded region in "bufferView".
|
|
||||||
struct SEncodedRegion {
|
struct SEncodedRegion {
|
||||||
const size_t Offset; ///< Offset from begin of "bufferView" to encoded region, in bytes.
|
const size_t Offset; ///< Offset from begin of "bufferView" to encoded region, in bytes.
|
||||||
const size_t EncodedData_Length; ///< Size of encoded region, in bytes.
|
const size_t EncodedData_Length; ///< Size of encoded region, in bytes.
|
||||||
|
@ -423,8 +402,7 @@ public:
|
||||||
const size_t DecodedData_Length; ///< Size of decoded region, in bytes.
|
const size_t DecodedData_Length; ///< Size of decoded region, in bytes.
|
||||||
const std::string ID; ///< ID of the region.
|
const std::string ID; ///< ID of the region.
|
||||||
|
|
||||||
/// \fn SEncodedRegion(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string pID)
|
/// @brief Constructor.
|
||||||
/// Constructor.
|
|
||||||
/// \param [in] pOffset - offset from begin of "bufferView" to encoded region, in bytes.
|
/// \param [in] pOffset - offset from begin of "bufferView" to encoded region, in bytes.
|
||||||
/// \param [in] pEncodedData_Length - size of encoded region, in bytes.
|
/// \param [in] pEncodedData_Length - size of encoded region, in bytes.
|
||||||
/// \param [in] pDecodedData - pointer to decoded data array.
|
/// \param [in] pDecodedData - pointer to decoded data array.
|
||||||
|
@ -433,16 +411,13 @@ public:
|
||||||
SEncodedRegion(const size_t pOffset, const size_t pEncodedData_Length, uint8_t *pDecodedData, const size_t pDecodedData_Length, const std::string &pID) :
|
SEncodedRegion(const size_t pOffset, const size_t pEncodedData_Length, uint8_t *pDecodedData, const size_t pDecodedData_Length, const std::string &pID) :
|
||||||
Offset(pOffset), EncodedData_Length(pEncodedData_Length), DecodedData(pDecodedData), DecodedData_Length(pDecodedData_Length), ID(pID) {}
|
Offset(pOffset), EncodedData_Length(pEncodedData_Length), DecodedData(pDecodedData), DecodedData_Length(pDecodedData_Length), ID(pID) {}
|
||||||
|
|
||||||
/// \fn ~SEncodedRegion()
|
|
||||||
/// Destructor.
|
/// Destructor.
|
||||||
~SEncodedRegion() { delete[] DecodedData; }
|
~SEncodedRegion() { delete[] DecodedData; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************* Variables *******************/
|
/******************* Variables *******************/
|
||||||
|
|
||||||
//std::string uri; //!< The uri of the buffer. Can be a filepath, a data uri, etc. (required)
|
|
||||||
size_t byteLength; //!< The length of the buffer in bytes. (default: 0)
|
size_t byteLength; //!< The length of the buffer in bytes. (default: 0)
|
||||||
//std::string type; //!< XMLHttpRequest responseType (default: "arraybuffer")
|
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
|
|
||||||
|
@ -486,7 +461,6 @@ public:
|
||||||
|
|
||||||
bool LoadFromStream(IOStream &stream, size_t length = 0, size_t baseOffset = 0);
|
bool LoadFromStream(IOStream &stream, size_t length = 0, size_t baseOffset = 0);
|
||||||
|
|
||||||
/// \fn void EncodedRegion_Mark(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string& pID)
|
|
||||||
/// Mark region of "bufferView" as encoded. When data is request from such region then "bufferView" use decoded data.
|
/// Mark region of "bufferView" as encoded. When data is request from such region then "bufferView" use decoded data.
|
||||||
/// \param [in] pOffset - offset from begin of "bufferView" to encoded region, in bytes.
|
/// \param [in] pOffset - offset from begin of "bufferView" to encoded region, in bytes.
|
||||||
/// \param [in] pEncodedData_Length - size of encoded region, in bytes.
|
/// \param [in] pEncodedData_Length - size of encoded region, in bytes.
|
||||||
|
@ -495,12 +469,10 @@ public:
|
||||||
/// \param [in] pID - ID of the region.
|
/// \param [in] pID - ID of the region.
|
||||||
void EncodedRegion_Mark(const size_t pOffset, const size_t pEncodedData_Length, uint8_t *pDecodedData, const size_t pDecodedData_Length, const std::string &pID);
|
void EncodedRegion_Mark(const size_t pOffset, const size_t pEncodedData_Length, uint8_t *pDecodedData, const size_t pDecodedData_Length, const std::string &pID);
|
||||||
|
|
||||||
/// \fn void EncodedRegion_SetCurrent(const std::string& pID)
|
|
||||||
/// Select current encoded region by ID. \sa EncodedRegion_Current.
|
/// Select current encoded region by ID. \sa EncodedRegion_Current.
|
||||||
/// \param [in] pID - ID of the region.
|
/// \param [in] pID - ID of the region.
|
||||||
void EncodedRegion_SetCurrent(const std::string &pID);
|
void EncodedRegion_SetCurrent(const std::string &pID);
|
||||||
|
|
||||||
/// \fn bool ReplaceData(const size_t pBufferData_Offset, const size_t pBufferData_Count, const uint8_t* pReplace_Data, const size_t pReplace_Count)
|
|
||||||
/// Replace part of buffer data. Pay attention that function work with original array of data (\ref mData) not with encoded regions.
|
/// Replace part of buffer data. Pay attention that function work with original array of data (\ref mData) not with encoded regions.
|
||||||
/// \param [in] pBufferData_Offset - index of first element in buffer from which new data will be placed.
|
/// \param [in] pBufferData_Offset - index of first element in buffer from which new data will be placed.
|
||||||
/// \param [in] pBufferData_Count - count of bytes in buffer which will be replaced.
|
/// \param [in] pBufferData_Count - count of bytes in buffer which will be replaced.
|
||||||
|
@ -558,37 +530,29 @@ struct Camera : public Object {
|
||||||
} ortographic;
|
} ortographic;
|
||||||
};
|
};
|
||||||
|
|
||||||
Camera() {}
|
Camera() = default;
|
||||||
void Read(Value &obj, Asset &r);
|
void Read(Value &obj, Asset &r);
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Image data used to create a texture.
|
//! Image data used to create a texture.
|
||||||
struct Image : public Object {
|
struct Image : public Object {
|
||||||
std::string uri; //! The uri of the image, that can be a file path, a data URI, etc.. (required)
|
std::string uri; //! The uri of the image, that can be a file path, a data URI, etc.. (required)
|
||||||
|
|
||||||
Ref<BufferView> bufferView;
|
Ref<BufferView> bufferView;
|
||||||
|
|
||||||
std::string mimeType;
|
std::string mimeType;
|
||||||
|
|
||||||
int width, height;
|
int width, height;
|
||||||
|
|
||||||
private:
|
|
||||||
std::unique_ptr<uint8_t[]> mData;
|
|
||||||
size_t mDataLength;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Image();
|
Image();
|
||||||
void Read(Value &obj, Asset &r);
|
void Read(Value &obj, Asset &r);
|
||||||
|
|
||||||
inline bool HasData() const { return mDataLength > 0; }
|
inline bool HasData() const { return mDataLength > 0; }
|
||||||
|
|
||||||
inline size_t GetDataLength() const { return mDataLength; }
|
inline size_t GetDataLength() const { return mDataLength; }
|
||||||
|
|
||||||
inline const uint8_t *GetData() const { return mData.get(); }
|
inline const uint8_t *GetData() const { return mData.get(); }
|
||||||
|
|
||||||
inline uint8_t *StealData();
|
inline uint8_t *StealData();
|
||||||
|
|
||||||
inline void SetData(uint8_t *data, size_t length, Asset &r);
|
inline void SetData(uint8_t *data, size_t length, Asset &r);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<uint8_t[]> mData;
|
||||||
|
size_t mDataLength;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Holds a material property that can be a texture or a color
|
//! Holds a material property that can be a texture or a color
|
||||||
|
@ -671,6 +635,7 @@ struct Mesh : public Object {
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
|
#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
|
||||||
|
|
||||||
/// \struct SCompression_Open3DGC
|
/// \struct SCompression_Open3DGC
|
||||||
/// Compression of mesh data using Open3DGC algorithm.
|
/// Compression of mesh data using Open3DGC algorithm.
|
||||||
struct SCompression_Open3DGC : public SExtension {
|
struct SCompression_Open3DGC : public SExtension {
|
||||||
|
@ -703,7 +668,6 @@ struct Mesh : public Object {
|
||||||
|
|
||||||
Mesh() {}
|
Mesh() {}
|
||||||
|
|
||||||
/// \fn ~Mesh()
|
|
||||||
/// Destructor.
|
/// Destructor.
|
||||||
~Mesh() {
|
~Mesh() {
|
||||||
for (std::list<SExtension *>::iterator it = Extension.begin(), it_end = Extension.end(); it != it_end; it++) {
|
for (std::list<SExtension *>::iterator it = Extension.begin(), it_end = Extension.end(); it != it_end; it++) {
|
||||||
|
@ -711,15 +675,13 @@ struct Mesh : public Object {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \fn void Read(Value& pJSON_Object, Asset& pAsset_Root)
|
/// @brief Get mesh data from JSON-object and place them to root asset.
|
||||||
/// Get mesh data from JSON-object and place them to root asset.
|
|
||||||
/// \param [in] pJSON_Object - reference to pJSON-object from which data are read.
|
/// \param [in] pJSON_Object - reference to pJSON-object from which data are read.
|
||||||
/// \param [out] pAsset_Root - reference to root asset where data will be stored.
|
/// \param [out] pAsset_Root - reference to root asset where data will be stored.
|
||||||
void Read(Value &pJSON_Object, Asset &pAsset_Root);
|
void Read(Value &pJSON_Object, Asset &pAsset_Root);
|
||||||
|
|
||||||
#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
|
#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
|
||||||
/// \fn void Decode_O3DGC(const SCompression_Open3DGC& pCompression_Open3DGC, Asset& pAsset_Root)
|
/// @brief Decode part of "buffer" which encoded with Open3DGC algorithm.
|
||||||
/// Decode part of "buffer" which encoded with Open3DGC algorithm.
|
|
||||||
/// \param [in] pCompression_Open3DGC - reference to structure which describe encoded region.
|
/// \param [in] pCompression_Open3DGC - reference to structure which describe encoded region.
|
||||||
/// \param [out] pAsset_Root - reference to root assed where data will be stored.
|
/// \param [out] pAsset_Root - reference to root assed where data will be stored.
|
||||||
void Decode_O3DGC(const SCompression_Open3DGC &pCompression_Open3DGC, Asset &pAsset_Root);
|
void Decode_O3DGC(const SCompression_Open3DGC &pCompression_Open3DGC, Asset &pAsset_Root);
|
||||||
|
@ -759,7 +721,7 @@ struct Sampler : public Object {
|
||||||
SamplerWrap wrapS; //!< The texture wrapping in the S direction. (required)
|
SamplerWrap wrapS; //!< The texture wrapping in the S direction. (required)
|
||||||
SamplerWrap wrapT; //!< The texture wrapping in the T direction. (required)
|
SamplerWrap wrapT; //!< The texture wrapping in the T direction. (required)
|
||||||
|
|
||||||
Sampler() {}
|
Sampler() = default;
|
||||||
void Read(Value &obj, Asset &r);
|
void Read(Value &obj, Asset &r);
|
||||||
void SetDefaults();
|
void SetDefaults();
|
||||||
};
|
};
|
||||||
|
@ -767,12 +729,12 @@ struct Sampler : public Object {
|
||||||
struct Scene : public Object {
|
struct Scene : public Object {
|
||||||
std::vector<Ref<Node>> nodes;
|
std::vector<Ref<Node>> nodes;
|
||||||
|
|
||||||
Scene() {}
|
Scene() = default;
|
||||||
void Read(Value &obj, Asset &r);
|
void Read(Value &obj, Asset &r);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Shader : public Object {
|
struct Shader : public Object {
|
||||||
Shader() {}
|
Shader() = default;
|
||||||
void Read(Value &obj, Asset &r);
|
void Read(Value &obj, Asset &r);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -782,7 +744,7 @@ struct Skin : public Object {
|
||||||
std::vector<Ref<Node>> jointNames; //!< Joint names of the joints (nodes with a jointName property) in this skin.
|
std::vector<Ref<Node>> jointNames; //!< Joint names of the joints (nodes with a jointName property) in this skin.
|
||||||
std::string name; //!< The user-defined name of this object.
|
std::string name; //!< The user-defined name of this object.
|
||||||
|
|
||||||
Skin() {}
|
Skin() = default;
|
||||||
void Read(Value &obj, Asset &r);
|
void Read(Value &obj, Asset &r);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -796,7 +758,7 @@ struct Technique : public Object {
|
||||||
struct Functions {
|
struct Functions {
|
||||||
};
|
};
|
||||||
|
|
||||||
Technique() {}
|
Technique() = default;
|
||||||
void Read(Value &obj, Asset &r);
|
void Read(Value &obj, Asset &r);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -805,13 +767,7 @@ struct Texture : public Object {
|
||||||
Ref<Sampler> sampler; //!< The ID of the sampler used by this texture. (required)
|
Ref<Sampler> sampler; //!< The ID of the sampler used by this texture. (required)
|
||||||
Ref<Image> source; //!< The ID of the image used by this texture. (required)
|
Ref<Image> source; //!< The ID of the image used by this texture. (required)
|
||||||
|
|
||||||
//TextureFormat format; //!< The texture's format. (default: TextureFormat_RGBA)
|
Texture() = default;
|
||||||
//TextureFormat internalFormat; //!< The texture's internal format. (default: TextureFormat_RGBA)
|
|
||||||
|
|
||||||
//TextureTarget target; //!< The target that the WebGL texture should be bound to. (default: TextureTarget_TEXTURE_2D)
|
|
||||||
//TextureType type; //!< Texel datatype. (default: TextureType_UNSIGNED_BYTE)
|
|
||||||
|
|
||||||
Texture() {}
|
|
||||||
void Read(Value &obj, Asset &r);
|
void Read(Value &obj, Asset &r);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -826,7 +782,6 @@ struct Light : public Object {
|
||||||
};
|
};
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
|
|
||||||
vec4 color;
|
vec4 color;
|
||||||
float distance;
|
float distance;
|
||||||
float constantAttenuation;
|
float constantAttenuation;
|
||||||
|
@ -835,9 +790,8 @@ struct Light : public Object {
|
||||||
float falloffAngle;
|
float falloffAngle;
|
||||||
float falloffExponent;
|
float falloffExponent;
|
||||||
|
|
||||||
Light() {}
|
Light() = default;
|
||||||
void Read(Value &obj, Asset &r);
|
void Read(Value &obj, Asset &r);
|
||||||
|
|
||||||
void SetDefaults();
|
void SetDefaults();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -865,15 +819,11 @@ struct Animation : public Object {
|
||||||
Ref<Accessor> translation; //!< Accessor reference to a buffer storing a array of three-component floating-point vectors.
|
Ref<Accessor> translation; //!< Accessor reference to a buffer storing a array of three-component floating-point vectors.
|
||||||
};
|
};
|
||||||
|
|
||||||
// AnimChannel Channels[3]; //!< Connect the output values of the key-frame animation to a specific node in the hierarchy.
|
|
||||||
// AnimParameters Parameters; //!< The samplers that interpolate between the key-frames.
|
|
||||||
// AnimSampler Samplers[3]; //!< The parameterized inputs representing the key-frame data.
|
|
||||||
|
|
||||||
std::vector<AnimChannel> Channels; //!< Connect the output values of the key-frame animation to a specific node in the hierarchy.
|
std::vector<AnimChannel> Channels; //!< Connect the output values of the key-frame animation to a specific node in the hierarchy.
|
||||||
AnimParameters Parameters; //!< The samplers that interpolate between the key-frames.
|
AnimParameters Parameters; //!< The samplers that interpolate between the key-frames.
|
||||||
std::vector<AnimSampler> Samplers; //!< The parameterized inputs representing the key-frame data.
|
std::vector<AnimSampler> Samplers; //!< The parameterized inputs representing the key-frame data.
|
||||||
|
|
||||||
Animation() {}
|
Animation() = default;
|
||||||
void Read(Value &obj, Asset &r);
|
void Read(Value &obj, Asset &r);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -963,13 +913,11 @@ struct AssetMetadata {
|
||||||
|
|
||||||
//! Root object for a glTF asset
|
//! Root object for a glTF asset
|
||||||
class Asset {
|
class Asset {
|
||||||
typedef std::gltf_unordered_map<std::string, int> IdMap;
|
using IdMap = std::gltf_unordered_map<std::string, int>;
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
friend class LazyDict;
|
friend class LazyDict;
|
||||||
|
|
||||||
friend struct Buffer; // To access OpenFile
|
friend struct Buffer; // To access OpenFile
|
||||||
|
|
||||||
friend class AssetWriter;
|
friend class AssetWriter;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -1010,12 +958,9 @@ public:
|
||||||
LazyDict<Material> materials;
|
LazyDict<Material> materials;
|
||||||
LazyDict<Mesh> meshes;
|
LazyDict<Mesh> meshes;
|
||||||
LazyDict<Node> nodes;
|
LazyDict<Node> nodes;
|
||||||
//LazyDict<Program> programs;
|
|
||||||
LazyDict<Sampler> samplers;
|
LazyDict<Sampler> samplers;
|
||||||
LazyDict<Scene> scenes;
|
LazyDict<Scene> scenes;
|
||||||
//LazyDict<Shader> shaders;
|
|
||||||
LazyDict<Skin> skins;
|
LazyDict<Skin> skins;
|
||||||
//LazyDict<Technique> techniques;
|
|
||||||
LazyDict<Texture> textures;
|
LazyDict<Texture> textures;
|
||||||
|
|
||||||
LazyDict<Light> lights; // KHR_materials_common ext
|
LazyDict<Light> lights; // KHR_materials_common ext
|
||||||
|
@ -1024,16 +969,20 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Asset(IOSystem *io = 0) :
|
Asset(IOSystem *io = 0) :
|
||||||
mIOSystem(io), asset(), accessors(*this, "accessors"), animations(*this, "animations"), buffers(*this, "buffers"), bufferViews(*this, "bufferViews"), cameras(*this, "cameras"), images(*this, "images"), materials(*this, "materials"), meshes(*this, "meshes"), nodes(*this, "nodes")
|
mIOSystem(io),
|
||||||
//, programs (*this, "programs")
|
asset(),
|
||||||
,
|
accessors(*this, "accessors"),
|
||||||
|
animations(*this, "animations"),
|
||||||
|
buffers(*this, "buffers"),
|
||||||
|
bufferViews(*this, "bufferViews"),
|
||||||
|
cameras(*this, "cameras"),
|
||||||
|
images(*this, "images"),
|
||||||
|
materials(*this, "materials"),
|
||||||
|
meshes(*this, "meshes"),
|
||||||
|
nodes(*this, "nodes"),
|
||||||
samplers(*this, "samplers"),
|
samplers(*this, "samplers"),
|
||||||
scenes(*this, "scenes")
|
scenes(*this, "scenes"),
|
||||||
//, shaders (*this, "shaders")
|
skins(*this, "skins"),
|
||||||
,
|
|
||||||
skins(*this, "skins")
|
|
||||||
//, techniques (*this, "techniques")
|
|
||||||
,
|
|
||||||
textures(*this, "textures"),
|
textures(*this, "textures"),
|
||||||
lights(*this, "lights", "KHR_materials_common") {
|
lights(*this, "lights", "KHR_materials_common") {
|
||||||
memset(&extensionsUsed, 0, sizeof(extensionsUsed));
|
memset(&extensionsUsed, 0, sizeof(extensionsUsed));
|
||||||
|
|
|
@ -237,8 +237,6 @@ bool ParseDataURI(const char *const_uri, size_t uriLen, DataURI &out);
|
||||||
#define CHECK_EXT(EXT) \
|
#define CHECK_EXT(EXT) \
|
||||||
if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
|
if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//! Helper struct to represent values that might not be present
|
//! Helper struct to represent values that might not be present
|
||||||
template <class T>
|
template <class T>
|
||||||
struct Nullable {
|
struct Nullable {
|
||||||
|
|
|
@ -106,7 +106,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
# define gltf_unordered_map tr1::unordered_map
|
# define gltf_unordered_map tr1::unordered_map
|
||||||
# define gltf_unordered_set tr1::unordered_set
|
# define gltf_unordered_set tr1::unordered_set
|
||||||
# else
|
# else
|
||||||
# define gltf_unordered_map unordered_map
|
# define gltf_unordered_map unordered_map
|
||||||
# define gltf_unordered_set unordered_set
|
# define gltf_unordered_set unordered_set
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -1087,29 +1087,11 @@ class Asset {
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
friend class LazyDict;
|
friend class LazyDict;
|
||||||
|
|
||||||
friend struct Buffer; // To access OpenFile
|
friend struct Buffer; // To access OpenFile
|
||||||
|
|
||||||
friend class AssetWriter;
|
friend class AssetWriter;
|
||||||
|
|
||||||
private:
|
|
||||||
IOSystem *mIOSystem;
|
|
||||||
rapidjson::IRemoteSchemaDocumentProvider *mSchemaDocumentProvider;
|
|
||||||
|
|
||||||
std::string mCurrentAssetDir;
|
|
||||||
|
|
||||||
size_t mSceneLength;
|
|
||||||
size_t mBodyOffset, mBodyLength;
|
|
||||||
|
|
||||||
std::vector<LazyDictBase *> mDicts;
|
std::vector<LazyDictBase *> mDicts;
|
||||||
|
|
||||||
IdMap mUsedIds;
|
|
||||||
|
|
||||||
Ref<Buffer> mBodyBuffer;
|
|
||||||
|
|
||||||
Asset(Asset &);
|
|
||||||
Asset &operator=(const Asset &);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Keeps info about the enabled extensions
|
//! Keeps info about the enabled extensions
|
||||||
struct Extensions {
|
struct Extensions {
|
||||||
|
@ -1125,16 +1107,36 @@ public:
|
||||||
bool KHR_draco_mesh_compression;
|
bool KHR_draco_mesh_compression;
|
||||||
bool FB_ngon_encoding;
|
bool FB_ngon_encoding;
|
||||||
bool KHR_texture_basisu;
|
bool KHR_texture_basisu;
|
||||||
|
|
||||||
|
Extensions() :
|
||||||
|
KHR_materials_pbrSpecularGlossiness(false),
|
||||||
|
KHR_materials_unlit(false),
|
||||||
|
KHR_lights_punctual(false),
|
||||||
|
KHR_texture_transform(false),
|
||||||
|
KHR_materials_sheen(false),
|
||||||
|
KHR_materials_clearcoat(false),
|
||||||
|
KHR_materials_transmission(false),
|
||||||
|
KHR_materials_volume(false),
|
||||||
|
KHR_materials_ior(false),
|
||||||
|
KHR_draco_mesh_compression(false),
|
||||||
|
FB_ngon_encoding(false),
|
||||||
|
KHR_texture_basisu(false) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
} extensionsUsed;
|
} extensionsUsed;
|
||||||
|
|
||||||
//! Keeps info about the required extensions
|
//! Keeps info about the required extensions
|
||||||
struct RequiredExtensions {
|
struct RequiredExtensions {
|
||||||
bool KHR_draco_mesh_compression;
|
bool KHR_draco_mesh_compression;
|
||||||
bool KHR_texture_basisu;
|
bool KHR_texture_basisu;
|
||||||
|
|
||||||
|
RequiredExtensions() : KHR_draco_mesh_compression(false), KHR_texture_basisu(false) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
} extensionsRequired;
|
} extensionsRequired;
|
||||||
|
|
||||||
AssetMetadata asset;
|
AssetMetadata asset;
|
||||||
Value *extras = nullptr;
|
Value *extras;
|
||||||
|
|
||||||
// Dictionaries for each type of object
|
// Dictionaries for each type of object
|
||||||
|
|
||||||
|
@ -1157,9 +1159,11 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Asset(IOSystem *io = nullptr, rapidjson::IRemoteSchemaDocumentProvider *schemaDocumentProvider = nullptr) :
|
Asset(IOSystem *io = nullptr, rapidjson::IRemoteSchemaDocumentProvider *schemaDocumentProvider = nullptr) :
|
||||||
mIOSystem(io),
|
mDicts(),
|
||||||
mSchemaDocumentProvider(schemaDocumentProvider),
|
extensionsUsed(),
|
||||||
|
extensionsRequired(),
|
||||||
asset(),
|
asset(),
|
||||||
|
extras(nullptr),
|
||||||
accessors(*this, "accessors"),
|
accessors(*this, "accessors"),
|
||||||
animations(*this, "animations"),
|
animations(*this, "animations"),
|
||||||
buffers(*this, "buffers"),
|
buffers(*this, "buffers"),
|
||||||
|
@ -1173,9 +1177,10 @@ public:
|
||||||
samplers(*this, "samplers"),
|
samplers(*this, "samplers"),
|
||||||
scenes(*this, "scenes"),
|
scenes(*this, "scenes"),
|
||||||
skins(*this, "skins"),
|
skins(*this, "skins"),
|
||||||
textures(*this, "textures") {
|
textures(*this, "textures") ,
|
||||||
memset(&extensionsUsed, 0, sizeof(extensionsUsed));
|
mIOSystem(io),
|
||||||
memset(&extensionsRequired, 0, sizeof(extensionsRequired));
|
mSchemaDocumentProvider(schemaDocumentProvider) {
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Main function
|
//! Main function
|
||||||
|
@ -1192,18 +1197,31 @@ public:
|
||||||
|
|
||||||
Ref<Buffer> GetBodyBuffer() { return mBodyBuffer; }
|
Ref<Buffer> GetBodyBuffer() { return mBodyBuffer; }
|
||||||
|
|
||||||
|
Asset(Asset &) = delete;
|
||||||
|
Asset &operator=(const Asset &) = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ReadBinaryHeader(IOStream &stream, std::vector<char> &sceneData);
|
void ReadBinaryHeader(IOStream &stream, std::vector<char> &sceneData);
|
||||||
|
|
||||||
//! Obtain a JSON document from the stream.
|
/// Obtain a JSON document from the stream.
|
||||||
// \param second argument is a buffer used by the document. It must be kept
|
/// \param second argument is a buffer used by the document. It must be kept
|
||||||
// alive while the document is in use.
|
/// alive while the document is in use.
|
||||||
Document ReadDocument(IOStream& stream, bool isBinary, std::vector<char>& sceneData);
|
Document ReadDocument(IOStream& stream, bool isBinary, std::vector<char>& sceneData);
|
||||||
|
|
||||||
void ReadExtensionsUsed(Document &doc);
|
void ReadExtensionsUsed(Document &doc);
|
||||||
void ReadExtensionsRequired(Document &doc);
|
void ReadExtensionsRequired(Document &doc);
|
||||||
|
|
||||||
IOStream *OpenFile(const std::string &path, const char *mode, bool absolute = false);
|
IOStream *OpenFile(const std::string &path, const char *mode, bool absolute = false);
|
||||||
|
|
||||||
|
private:
|
||||||
|
IOSystem *mIOSystem;
|
||||||
|
rapidjson::IRemoteSchemaDocumentProvider *mSchemaDocumentProvider;
|
||||||
|
std::string mCurrentAssetDir;
|
||||||
|
size_t mSceneLength;
|
||||||
|
size_t mBodyOffset;
|
||||||
|
size_t mBodyLength;
|
||||||
|
IdMap mUsedIds;
|
||||||
|
Ref<Buffer> mBodyBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::string getContextForErrorMessages(const std::string &id, const std::string &name) {
|
inline std::string getContextForErrorMessages(const std::string &id, const std::string &name) {
|
||||||
|
|
|
@ -515,72 +515,74 @@ void glTF2Exporter::GetMatTexProp(const aiMaterial &mat, float &prop, const char
|
||||||
}
|
}
|
||||||
|
|
||||||
void glTF2Exporter::GetMatTex(const aiMaterial &mat, Ref<Texture> &texture, unsigned int &texCoord, aiTextureType tt, unsigned int slot = 0) {
|
void glTF2Exporter::GetMatTex(const aiMaterial &mat, Ref<Texture> &texture, unsigned int &texCoord, aiTextureType tt, unsigned int slot = 0) {
|
||||||
if (mat.GetTextureCount(tt) > 0) {
|
if (mat.GetTextureCount(tt) == 0) {
|
||||||
aiString tex;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Read texcoord (UV map index)
|
aiString tex;
|
||||||
mat.Get(AI_MATKEY_UVWSRC(tt, slot), texCoord);
|
|
||||||
|
|
||||||
if (mat.Get(AI_MATKEY_TEXTURE(tt, slot), tex) == AI_SUCCESS) {
|
// Read texcoord (UV map index)
|
||||||
std::string path = tex.C_Str();
|
mat.Get(AI_MATKEY_UVWSRC(tt, slot), texCoord);
|
||||||
|
|
||||||
if (path.size() > 0) {
|
if (mat.Get(AI_MATKEY_TEXTURE(tt, slot), tex) == AI_SUCCESS) {
|
||||||
std::map<std::string, unsigned int>::iterator it = mTexturesByPath.find(path);
|
std::string path = tex.C_Str();
|
||||||
if (it != mTexturesByPath.end()) {
|
|
||||||
texture = mAsset->textures.Get(it->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool useBasisUniversal = false;
|
if (path.size() > 0) {
|
||||||
if (!texture) {
|
std::map<std::string, unsigned int>::iterator it = mTexturesByPath.find(path);
|
||||||
std::string texId = mAsset->FindUniqueID("", "texture");
|
if (it != mTexturesByPath.end()) {
|
||||||
texture = mAsset->textures.Create(texId);
|
texture = mAsset->textures.Get(it->second);
|
||||||
mTexturesByPath[path] = texture.GetIndex();
|
}
|
||||||
|
|
||||||
std::string imgId = mAsset->FindUniqueID("", "image");
|
bool useBasisUniversal = false;
|
||||||
texture->source = mAsset->images.Create(imgId);
|
if (!texture) {
|
||||||
|
std::string texId = mAsset->FindUniqueID("", "texture");
|
||||||
|
texture = mAsset->textures.Create(texId);
|
||||||
|
mTexturesByPath[path] = texture.GetIndex();
|
||||||
|
|
||||||
const aiTexture *curTex = mScene->GetEmbeddedTexture(path.c_str());
|
std::string imgId = mAsset->FindUniqueID("", "image");
|
||||||
if (curTex != nullptr) { // embedded
|
texture->source = mAsset->images.Create(imgId);
|
||||||
texture->source->name = curTex->mFilename.C_Str();
|
|
||||||
|
|
||||||
//basisu: embedded ktx2, bu
|
const aiTexture *curTex = mScene->GetEmbeddedTexture(path.c_str());
|
||||||
if (curTex->achFormatHint[0]) {
|
if (curTex != nullptr) { // embedded
|
||||||
std::string mimeType = "image/";
|
texture->source->name = curTex->mFilename.C_Str();
|
||||||
if (memcmp(curTex->achFormatHint, "jpg", 3) == 0)
|
|
||||||
mimeType += "jpeg";
|
|
||||||
else if (memcmp(curTex->achFormatHint, "ktx", 3) == 0) {
|
|
||||||
useBasisUniversal = true;
|
|
||||||
mimeType += "ktx";
|
|
||||||
} else if (memcmp(curTex->achFormatHint, "kx2", 3) == 0) {
|
|
||||||
useBasisUniversal = true;
|
|
||||||
mimeType += "ktx2";
|
|
||||||
} else if (memcmp(curTex->achFormatHint, "bu", 2) == 0) {
|
|
||||||
useBasisUniversal = true;
|
|
||||||
mimeType += "basis";
|
|
||||||
} else
|
|
||||||
mimeType += curTex->achFormatHint;
|
|
||||||
texture->source->mimeType = mimeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The asset has its own buffer, see Image::SetData
|
//basisu: embedded ktx2, bu
|
||||||
//basisu: "image/ktx2", "image/basis" as is
|
if (curTex->achFormatHint[0]) {
|
||||||
texture->source->SetData(reinterpret_cast<uint8_t *>(curTex->pcData), curTex->mWidth, *mAsset);
|
std::string mimeType = "image/";
|
||||||
} else {
|
if (memcmp(curTex->achFormatHint, "jpg", 3) == 0)
|
||||||
texture->source->uri = path;
|
mimeType += "jpeg";
|
||||||
if (texture->source->uri.find(".ktx") != std::string::npos ||
|
else if (memcmp(curTex->achFormatHint, "ktx", 3) == 0) {
|
||||||
texture->source->uri.find(".basis") != std::string::npos) {
|
|
||||||
useBasisUniversal = true;
|
useBasisUniversal = true;
|
||||||
}
|
mimeType += "ktx";
|
||||||
|
} else if (memcmp(curTex->achFormatHint, "kx2", 3) == 0) {
|
||||||
|
useBasisUniversal = true;
|
||||||
|
mimeType += "ktx2";
|
||||||
|
} else if (memcmp(curTex->achFormatHint, "bu", 2) == 0) {
|
||||||
|
useBasisUniversal = true;
|
||||||
|
mimeType += "basis";
|
||||||
|
} else
|
||||||
|
mimeType += curTex->achFormatHint;
|
||||||
|
texture->source->mimeType = mimeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
//basisu
|
// The asset has its own buffer, see Image::SetData
|
||||||
if (useBasisUniversal) {
|
//basisu: "image/ktx2", "image/basis" as is
|
||||||
mAsset->extensionsUsed.KHR_texture_basisu = true;
|
texture->source->SetData(reinterpret_cast<uint8_t *>(curTex->pcData), curTex->mWidth, *mAsset);
|
||||||
mAsset->extensionsRequired.KHR_texture_basisu = true;
|
} else {
|
||||||
|
texture->source->uri = path;
|
||||||
|
if (texture->source->uri.find(".ktx") != std::string::npos ||
|
||||||
|
texture->source->uri.find(".basis") != std::string::npos) {
|
||||||
|
useBasisUniversal = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GetTexSampler(mat, texture, tt, slot);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//basisu
|
||||||
|
if (useBasisUniversal) {
|
||||||
|
mAsset->extensionsUsed.KHR_texture_basisu = true;
|
||||||
|
mAsset->extensionsRequired.KHR_texture_basisu = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetTexSampler(mat, texture, tt, slot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -588,12 +590,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial &mat, Ref<Texture> &texture, unsi
|
||||||
|
|
||||||
void glTF2Exporter::GetMatTex(const aiMaterial &mat, TextureInfo &prop, aiTextureType tt, unsigned int slot = 0) {
|
void glTF2Exporter::GetMatTex(const aiMaterial &mat, TextureInfo &prop, aiTextureType tt, unsigned int slot = 0) {
|
||||||
Ref<Texture> &texture = prop.texture;
|
Ref<Texture> &texture = prop.texture;
|
||||||
|
|
||||||
GetMatTex(mat, texture, prop.texCoord, tt, slot);
|
GetMatTex(mat, texture, prop.texCoord, tt, slot);
|
||||||
|
|
||||||
//if (texture) {
|
|
||||||
// GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot);
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void glTF2Exporter::GetMatTex(const aiMaterial &mat, NormalTextureInfo &prop, aiTextureType tt, unsigned int slot = 0) {
|
void glTF2Exporter::GetMatTex(const aiMaterial &mat, NormalTextureInfo &prop, aiTextureType tt, unsigned int slot = 0) {
|
||||||
|
@ -681,12 +678,14 @@ bool glTF2Exporter::GetMatSpecGloss(const aiMaterial &mat, glTF2::PbrSpecularGlo
|
||||||
|
|
||||||
bool glTF2Exporter::GetMatSheen(const aiMaterial &mat, glTF2::MaterialSheen &sheen) {
|
bool glTF2Exporter::GetMatSheen(const aiMaterial &mat, glTF2::MaterialSheen &sheen) {
|
||||||
// Return true if got any valid Sheen properties or textures
|
// Return true if got any valid Sheen properties or textures
|
||||||
if (GetMatColor(mat, sheen.sheenColorFactor, AI_MATKEY_SHEEN_COLOR_FACTOR) != aiReturn_SUCCESS)
|
if (GetMatColor(mat, sheen.sheenColorFactor, AI_MATKEY_SHEEN_COLOR_FACTOR) != aiReturn_SUCCESS) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Default Sheen color factor {0,0,0} disables Sheen, so do not export
|
// Default Sheen color factor {0,0,0} disables Sheen, so do not export
|
||||||
if (sheen.sheenColorFactor == defaultSheenFactor)
|
if (sheen.sheenColorFactor == defaultSheenFactor) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
mat.Get(AI_MATKEY_SHEEN_ROUGHNESS_FACTOR, sheen.sheenRoughnessFactor);
|
mat.Get(AI_MATKEY_SHEEN_ROUGHNESS_FACTOR, sheen.sheenRoughnessFactor);
|
||||||
|
|
||||||
|
@ -781,9 +780,7 @@ void glTF2Exporter::ExportMaterials() {
|
||||||
aiColor4D specularColor;
|
aiColor4D specularColor;
|
||||||
ai_real shininess;
|
ai_real shininess;
|
||||||
|
|
||||||
if (
|
if (mat.Get(AI_MATKEY_COLOR_SPECULAR, specularColor) == AI_SUCCESS && mat.Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS) {
|
||||||
mat.Get(AI_MATKEY_COLOR_SPECULAR, specularColor) == AI_SUCCESS &&
|
|
||||||
mat.Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS) {
|
|
||||||
// convert specular color to luminance
|
// convert specular color to luminance
|
||||||
float specularIntensity = specularColor[0] * 0.2125f + specularColor[1] * 0.7154f + specularColor[2] * 0.0721f;
|
float specularIntensity = specularColor[0] * 0.2125f + specularColor[1] * 0.7154f + specularColor[2] * 0.0721f;
|
||||||
//normalize shininess (assuming max is 1000) with an inverse exponentional curve
|
//normalize shininess (assuming max is 1000) with an inverse exponentional curve
|
||||||
|
@ -916,7 +913,8 @@ Ref<Node> FindSkeletonRootJoint(Ref<Skin> &skinRef) {
|
||||||
return parentNodeRef;
|
return parentNodeRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportSkin(Asset &mAsset, const aiMesh *aimesh, Ref<Mesh> &meshRef, Ref<Buffer> &bufferRef, Ref<Skin> &skinRef, std::vector<aiMatrix4x4> &inverseBindMatricesData) {
|
void ExportSkin(Asset &mAsset, const aiMesh *aimesh, Ref<Mesh> &meshRef, Ref<Buffer> &bufferRef, Ref<Skin> &skinRef,
|
||||||
|
std::vector<aiMatrix4x4> &inverseBindMatricesData) {
|
||||||
if (aimesh->mNumBones < 1) {
|
if (aimesh->mNumBones < 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -986,7 +984,8 @@ void ExportSkin(Asset &mAsset, const aiMesh *aimesh, Ref<Mesh> &meshRef, Ref<Buf
|
||||||
} // End: for-loop mNumMeshes
|
} // End: for-loop mNumMeshes
|
||||||
|
|
||||||
Mesh::Primitive &p = meshRef->primitives.back();
|
Mesh::Primitive &p = meshRef->primitives.back();
|
||||||
Ref<Accessor> vertexJointAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices, vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
|
Ref<Accessor> vertexJointAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices,
|
||||||
|
vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
|
||||||
if (vertexJointAccessor) {
|
if (vertexJointAccessor) {
|
||||||
size_t offset = vertexJointAccessor->bufferView->byteOffset;
|
size_t offset = vertexJointAccessor->bufferView->byteOffset;
|
||||||
size_t bytesLen = vertexJointAccessor->bufferView->byteLength;
|
size_t bytesLen = vertexJointAccessor->bufferView->byteLength;
|
||||||
|
@ -1069,8 +1068,11 @@ void glTF2Exporter::ExportMeshes() {
|
||||||
p.ngonEncoded = (aim->mPrimitiveTypes & aiPrimitiveType_NGONEncodingFlag) != 0;
|
p.ngonEncoded = (aim->mPrimitiveTypes & aiPrimitiveType_NGONEncodingFlag) != 0;
|
||||||
|
|
||||||
/******************* Vertices ********************/
|
/******************* Vertices ********************/
|
||||||
Ref<Accessor> v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
|
Ref<Accessor> v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3,
|
||||||
if (v) p.attributes.position.push_back(v);
|
AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
|
||||||
|
if (v) {
|
||||||
|
p.attributes.position.push_back(v);
|
||||||
|
}
|
||||||
|
|
||||||
/******************** Normals ********************/
|
/******************** Normals ********************/
|
||||||
// Normalize all normals as the validator can emit a warning otherwise
|
// Normalize all normals as the validator can emit a warning otherwise
|
||||||
|
@ -1080,13 +1082,17 @@ void glTF2Exporter::ExportMeshes() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Accessor> n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
|
Ref<Accessor> n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3,
|
||||||
if (n) p.attributes.normal.push_back(n);
|
AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
|
||||||
|
if (n) {
|
||||||
|
p.attributes.normal.push_back(n);
|
||||||
|
}
|
||||||
|
|
||||||
/************** Texture coordinates **************/
|
/************** Texture coordinates **************/
|
||||||
for (int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
|
for (int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
|
||||||
if (!aim->HasTextureCoords(i))
|
if (!aim->HasTextureCoords(i)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Flip UV y coords
|
// Flip UV y coords
|
||||||
if (aim->mNumUVComponents[i] > 1) {
|
if (aim->mNumUVComponents[i] > 1) {
|
||||||
|
@ -1098,16 +1104,21 @@ void glTF2Exporter::ExportMeshes() {
|
||||||
if (aim->mNumUVComponents[i] > 0) {
|
if (aim->mNumUVComponents[i] > 0) {
|
||||||
AttribType::Value type = (aim->mNumUVComponents[i] == 2) ? AttribType::VEC2 : AttribType::VEC3;
|
AttribType::Value type = (aim->mNumUVComponents[i] == 2) ? AttribType::VEC2 : AttribType::VEC3;
|
||||||
|
|
||||||
Ref<Accessor> tc = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mTextureCoords[i], AttribType::VEC3, type, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
|
Ref<Accessor> tc = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mTextureCoords[i],
|
||||||
if (tc) p.attributes.texcoord.push_back(tc);
|
AttribType::VEC3, type, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
|
||||||
|
if (tc) {
|
||||||
|
p.attributes.texcoord.push_back(tc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************** Vertex colors ****************/
|
/*************** Vertex colors ****************/
|
||||||
for (unsigned int indexColorChannel = 0; indexColorChannel < aim->GetNumColorChannels(); ++indexColorChannel) {
|
for (unsigned int indexColorChannel = 0; indexColorChannel < aim->GetNumColorChannels(); ++indexColorChannel) {
|
||||||
Ref<Accessor> c = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mColors[indexColorChannel], AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
|
Ref<Accessor> c = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mColors[indexColorChannel],
|
||||||
if (c)
|
AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
|
||||||
|
if (c) {
|
||||||
p.attributes.color.push_back(c);
|
p.attributes.color.push_back(c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************** Vertices indices ****************/
|
/*************** Vertices indices ****************/
|
||||||
|
@ -1121,7 +1132,8 @@ void glTF2Exporter::ExportMeshes() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p.indices = ExportData(*mAsset, meshId, b, indices.size(), &indices[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_UNSIGNED_INT, BufferViewTarget_ELEMENT_ARRAY_BUFFER);
|
p.indices = ExportData(*mAsset, meshId, b, indices.size(), &indices[0], AttribType::SCALAR, AttribType::SCALAR,
|
||||||
|
ComponentType_UNSIGNED_INT, BufferViewTarget_ELEMENT_ARRAY_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (aim->mPrimitiveTypes) {
|
switch (aim->mPrimitiveTypes) {
|
||||||
|
@ -1136,6 +1148,7 @@ void glTF2Exporter::ExportMeshes() {
|
||||||
break;
|
break;
|
||||||
default: // aiPrimitiveType_TRIANGLE
|
default: // aiPrimitiveType_TRIANGLE
|
||||||
p.mode = PrimitiveMode_TRIANGLES;
|
p.mode = PrimitiveMode_TRIANGLES;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************** Skins ****************/
|
/*************** Skins ****************/
|
||||||
|
@ -1155,8 +1168,9 @@ void glTF2Exporter::ExportMeshes() {
|
||||||
p.targets.resize(aim->mNumAnimMeshes);
|
p.targets.resize(aim->mNumAnimMeshes);
|
||||||
for (unsigned int am = 0; am < aim->mNumAnimMeshes; ++am) {
|
for (unsigned int am = 0; am < aim->mNumAnimMeshes; ++am) {
|
||||||
aiAnimMesh *pAnimMesh = aim->mAnimMeshes[am];
|
aiAnimMesh *pAnimMesh = aim->mAnimMeshes[am];
|
||||||
if (bExportTargetNames)
|
if (bExportTargetNames) {
|
||||||
m->targetNames.push_back(pAnimMesh->mName.data);
|
m->targetNames.emplace_back(pAnimMesh->mName.data);
|
||||||
|
}
|
||||||
// position
|
// position
|
||||||
if (pAnimMesh->HasPositions()) {
|
if (pAnimMesh->HasPositions()) {
|
||||||
// NOTE: in gltf it is the diff stored
|
// NOTE: in gltf it is the diff stored
|
||||||
|
@ -1319,12 +1333,12 @@ unsigned int glTF2Exporter::ExportNodeHierarchy(const aiNode *n) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < n->mNumMeshes; ++i) {
|
for (unsigned int i = 0; i < n->mNumMeshes; ++i) {
|
||||||
node->meshes.push_back(mAsset->meshes.Get(n->mMeshes[i]));
|
node->meshes.emplace_back(mAsset->meshes.Get(n->mMeshes[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < n->mNumChildren; ++i) {
|
for (unsigned int i = 0; i < n->mNumChildren; ++i) {
|
||||||
unsigned int idx = ExportNode(n->mChildren[i], node);
|
unsigned int idx = ExportNode(n->mChildren[i], node);
|
||||||
node->children.push_back(mAsset->nodes.Get(idx));
|
node->children.emplace_back(mAsset->nodes.Get(idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
return node.GetIndex();
|
return node.GetIndex();
|
||||||
|
@ -1366,12 +1380,12 @@ unsigned int glTF2Exporter::ExportNode(const aiNode *n, Ref<Node> &parent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < n->mNumMeshes; ++i) {
|
for (unsigned int i = 0; i < n->mNumMeshes; ++i) {
|
||||||
node->meshes.push_back(mAsset->meshes.Get(n->mMeshes[i]));
|
node->meshes.emplace_back(mAsset->meshes.Get(n->mMeshes[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < n->mNumChildren; ++i) {
|
for (unsigned int i = 0; i < n->mNumChildren; ++i) {
|
||||||
unsigned int idx = ExportNode(n->mChildren[i], node);
|
unsigned int idx = ExportNode(n->mChildren[i], node);
|
||||||
node->children.push_back(mAsset->nodes.Get(idx));
|
node->children.emplace_back(mAsset->nodes.Get(idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
return node.GetIndex();
|
return node.GetIndex();
|
||||||
|
@ -1386,7 +1400,7 @@ void glTF2Exporter::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(0u));
|
scene->nodes.emplace_back(mAsset->nodes.Get(0u));
|
||||||
}
|
}
|
||||||
|
|
||||||
// set as the default scene
|
// set as the default scene
|
||||||
|
@ -1521,12 +1535,6 @@ void glTF2Exporter::ExportAnimations() {
|
||||||
AddSampler(animRef, animNode, scaleSampler, AnimationPath_SCALE);
|
AddSampler(animRef, animNode, scaleSampler, AnimationPath_SCALE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assimp documentation states this is not used (not implemented)
|
|
||||||
// for (unsigned int channelIndex = 0; channelIndex < anim->mNumMeshChannels; ++channelIndex) {
|
|
||||||
// const aiMeshAnim* meshChannel = anim->mMeshChannels[channelIndex];
|
|
||||||
// }
|
|
||||||
|
|
||||||
} // End: for-loop mNumAnimations
|
} // End: for-loop mNumAnimations
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(utMesh, emptyMeshHasNoContentTest) {
|
TEST_F(utMesh, emptyMeshHasNoContentTest) {
|
||||||
EXPECT_EQ(0, mesh->mName.length);
|
EXPECT_EQ(0u, mesh->mName.length);
|
||||||
EXPECT_FALSE(mesh->HasPositions());
|
EXPECT_FALSE(mesh->HasPositions());
|
||||||
EXPECT_FALSE(mesh->HasFaces());
|
EXPECT_FALSE(mesh->HasFaces());
|
||||||
EXPECT_FALSE(mesh->HasNormals());
|
EXPECT_FALSE(mesh->HasNormals());
|
||||||
|
@ -69,8 +69,8 @@ TEST_F(utMesh, emptyMeshHasNoContentTest) {
|
||||||
EXPECT_FALSE(mesh->HasVertexColors(AI_MAX_NUMBER_OF_COLOR_SETS));
|
EXPECT_FALSE(mesh->HasVertexColors(AI_MAX_NUMBER_OF_COLOR_SETS));
|
||||||
EXPECT_FALSE(mesh->HasTextureCoords(0));
|
EXPECT_FALSE(mesh->HasTextureCoords(0));
|
||||||
EXPECT_FALSE(mesh->HasTextureCoords(AI_MAX_NUMBER_OF_TEXTURECOORDS));
|
EXPECT_FALSE(mesh->HasTextureCoords(AI_MAX_NUMBER_OF_TEXTURECOORDS));
|
||||||
EXPECT_EQ(0, mesh->GetNumUVChannels());
|
EXPECT_EQ(0u, mesh->GetNumUVChannels());
|
||||||
EXPECT_EQ(0, mesh->GetNumColorChannels());
|
EXPECT_EQ(0u, mesh->GetNumColorChannels());
|
||||||
EXPECT_FALSE(mesh->HasBones());
|
EXPECT_FALSE(mesh->HasBones());
|
||||||
EXPECT_FALSE(mesh->HasTextureCoordsName(0));
|
EXPECT_FALSE(mesh->HasTextureCoordsName(0));
|
||||||
EXPECT_FALSE(mesh->HasTextureCoordsName(AI_MAX_NUMBER_OF_TEXTURECOORDS));
|
EXPECT_FALSE(mesh->HasTextureCoordsName(AI_MAX_NUMBER_OF_TEXTURECOORDS));
|
||||||
|
@ -80,8 +80,8 @@ TEST_F(utMesh, setTextureCoordsName) {
|
||||||
EXPECT_FALSE(mesh->HasTextureCoordsName(0));
|
EXPECT_FALSE(mesh->HasTextureCoordsName(0));
|
||||||
const aiString texcoords_name("texcoord_name");
|
const aiString texcoords_name("texcoord_name");
|
||||||
mesh->SetTextureCoordsName(0, texcoords_name);
|
mesh->SetTextureCoordsName(0, texcoords_name);
|
||||||
EXPECT_TRUE(mesh->HasTextureCoordsName(0));
|
EXPECT_TRUE(mesh->HasTextureCoordsName(0u));
|
||||||
EXPECT_FALSE(mesh->HasTextureCoordsName(1));
|
EXPECT_FALSE(mesh->HasTextureCoordsName(1u));
|
||||||
ASSERT_NE(nullptr, mesh->mTextureCoordsNames);
|
ASSERT_NE(nullptr, mesh->mTextureCoordsNames);
|
||||||
ASSERT_NE(nullptr, mesh->mTextureCoordsNames[0]);
|
ASSERT_NE(nullptr, mesh->mTextureCoordsNames[0]);
|
||||||
EXPECT_STREQ(texcoords_name.C_Str(), mesh->mTextureCoordsNames[0]->C_Str());
|
EXPECT_STREQ(texcoords_name.C_Str(), mesh->mTextureCoordsNames[0]->C_Str());
|
||||||
|
@ -94,3 +94,4 @@ TEST_F(utMesh, setTextureCoordsName) {
|
||||||
EXPECT_EQ(nullptr, mesh->mTextureCoordsNames[0]);
|
EXPECT_EQ(nullptr, mesh->mTextureCoordsNames[0]);
|
||||||
EXPECT_EQ(nullptr, mesh->GetTextureCoordsName(0));
|
EXPECT_EQ(nullptr, mesh->GetTextureCoordsName(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,9 +124,9 @@ TEST_F(utColladaExport, testExportLight) {
|
||||||
ASSERT_NE(pTest, nullptr);
|
ASSERT_NE(pTest, nullptr);
|
||||||
ASSERT_TRUE(pTest->HasLights());
|
ASSERT_TRUE(pTest->HasLights());
|
||||||
|
|
||||||
const unsigned int origNumLights(pTest->mNumLights);
|
const unsigned int origNumLights = pTest->mNumLights;
|
||||||
// There are FIVE!!! LIGHTS!!!
|
// There are FIVE!!! LIGHTS!!!
|
||||||
EXPECT_EQ(5, origNumLights) << "lights.dae should contain five lights";
|
EXPECT_EQ(5u, origNumLights) << "lights.dae should contain five lights";
|
||||||
|
|
||||||
std::vector<aiLight> origLights(5);
|
std::vector<aiLight> origLights(5);
|
||||||
for (size_t i = 0; i < origNumLights; i++) {
|
for (size_t i = 0; i < origNumLights; i++) {
|
||||||
|
|
Loading…
Reference in New Issue