2020-06-12 00:37:06 +00:00
/*
2017-07-19 20:21:43 +00:00
Open Asset Import Library ( assimp )
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2022-01-10 20:13:43 +00:00
Copyright ( c ) 2006 - 2022 , assimp team
2018-01-28 18:42:05 +00:00
2017-07-19 20:21:43 +00:00
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 .
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
/** @file glTFAsset.h
* Declares a glTF class to handle gltf / glb files
*
* glTF Extensions Support :
2017-09-01 03:40:44 +00:00
* KHR_materials_pbrSpecularGlossiness full
2022-11-08 21:09:50 +00:00
* KHR_materials_specular full
2018-05-18 21:01:25 +00:00
* KHR_materials_unlit full
2019-08-03 18:51:00 +00:00
* KHR_lights_punctual full
2020-12-20 06:59:12 +00:00
* KHR_materials_sheen full
2020-12-23 07:12:09 +00:00
* KHR_materials_clearcoat full
2020-12-23 09:43:01 +00:00
* KHR_materials_transmission full
2021-09-29 16:05:17 +00:00
* KHR_materials_volume full
2021-10-07 08:36:53 +00:00
* KHR_materials_ior full
2022-11-03 21:11:21 +00:00
* KHR_materials_emissive_strength full
2017-07-19 20:21:43 +00:00
*/
2017-07-20 17:59:21 +00:00
# ifndef GLTF2ASSET_H_INC
# define GLTF2ASSET_H_INC
2017-07-19 20:21:43 +00:00
2020-07-05 18:22:31 +00:00
# if !defined(ASSIMP_BUILD_NO_GLTF_IMPORTER) && !defined(ASSIMP_BUILD_NO_GLTF2_IMPORTER)
2017-07-19 20:21:43 +00:00
2019-06-10 21:26:00 +00:00
# include <assimp/Exceptional.h>
2020-03-15 09:17:54 +00:00
# include <algorithm>
# include <list>
2017-07-19 20:21:43 +00:00
# include <map>
2020-03-11 09:54:24 +00:00
# include <set>
2020-03-15 09:17:54 +00:00
# include <stdexcept>
2017-07-19 20:21:43 +00:00
# include <string>
# include <vector>
2021-09-14 18:45:36 +00:00
// clang-format off
2020-06-09 08:14:57 +00:00
# if (__GNUC__ == 8 && __GNUC_MINOR__ >= 0)
2020-05-28 19:02:13 +00:00
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wclass-memaccess"
2020-06-09 08:14:57 +00:00
# endif
2017-07-19 20:21:43 +00:00
# include <rapidjson/document.h>
# include <rapidjson/error/en.h>
2020-03-15 09:17:54 +00:00
# include <rapidjson/rapidjson.h>
2021-10-06 12:41:45 +00:00
# include <rapidjson/schema.h>
2020-06-09 08:14:57 +00:00
# if (__GNUC__ == 8 && __GNUC_MINOR__ >= 0)
2021-09-14 18:45:36 +00:00
# pragma GCC diagnostic pop
2020-06-09 08:14:57 +00:00
# endif
2017-07-19 20:21:43 +00:00
# ifdef ASSIMP_API
2021-09-14 18:45:36 +00:00
# include <assimp / ByteSwapper.h>
# include <assimp / DefaultIOSystem.h>
# include <memory>
2017-07-19 20:21:43 +00:00
# else
2021-09-14 18:45:36 +00:00
# include <memory>
# define AI_SWAP4(p)
# define ai_assert
2017-07-19 20:21:43 +00:00
# endif
# if _MSC_VER > 1500 || (defined __GNUC___)
2021-09-14 18:45:36 +00:00
# define ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
2020-03-15 09:17:54 +00:00
# else
2021-09-14 18:45:36 +00:00
# define gltf_unordered_map map
# define gltf_unordered_set set
2017-07-19 20:21:43 +00:00
# endif
# ifdef ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
2021-09-14 18:45:36 +00:00
# include <unordered_map>
# include <unordered_set>
# if defined(_MSC_VER) && _MSC_VER <= 1600
# define gltf_unordered_map tr1::unordered_map
# define gltf_unordered_set tr1::unordered_set
# else
2022-02-22 20:07:42 +00:00
# define gltf_unordered_map unordered_map
2021-09-14 18:45:36 +00:00
# define gltf_unordered_set unordered_set
# endif
2017-07-19 20:21:43 +00:00
# endif
2021-09-14 18:45:36 +00:00
// clang-format on
2017-07-19 20:21:43 +00:00
2018-01-06 00:18:33 +00:00
# include <assimp/StringUtils.h>
2021-11-16 11:42:59 +00:00
# include <assimp/material.h>
# include <assimp/GltfMaterial.h>
2017-11-15 20:26:25 +00:00
2020-05-02 13:14:38 +00:00
# include "AssetLib/glTF/glTFCommon.h"
2019-09-11 15:00:39 +00:00
2020-03-15 09:17:54 +00:00
namespace glTF2 {
2020-05-02 13:14:38 +00:00
2021-09-14 18:45:36 +00:00
using glTFCommon : : Nullable ;
using glTFCommon : : Ref ;
2020-03-15 09:17:54 +00:00
using glTFCommon : : IOStream ;
using glTFCommon : : IOSystem ;
using glTFCommon : : shared_ptr ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
using rapidjson : : Document ;
using rapidjson : : Value ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
class Asset ;
class AssetWriter ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
struct BufferView ; // here due to cross-reference
struct Texture ;
struct Skin ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
using glTFCommon : : mat4 ;
using glTFCommon : : vec3 ;
using glTFCommon : : vec4 ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
//! Magic number for GLB files
# define AI_GLB_MAGIC_NUMBER "glTF"
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
# ifdef ASSIMP_API
# include <assimp/Compiler/pushpack1.h>
# endif
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
//! For binary .glb files
//! 12-byte header (+ the JSON + a "body" data section)
struct GLB_Header {
uint8_t magic [ 4 ] ; //!< Magic number: "glTF"
uint32_t version ; //!< Version number (always 2 as of the last update)
uint32_t length ; //!< Total length of the Binary glTF, including header, scene, and body, in bytes
} PACK_STRUCT ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
struct GLB_Chunk {
uint32_t chunkLength ;
uint32_t chunkType ;
} PACK_STRUCT ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
# ifdef ASSIMP_API
# include <assimp/Compiler/poppack1.h>
# endif
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
//! Values for the GLB_Chunk::chunkType field
enum ChunkType {
ChunkType_JSON = 0x4E4F534A ,
ChunkType_BIN = 0x004E4942
} ;
//! Values for the mesh primitive modes
enum PrimitiveMode {
PrimitiveMode_POINTS = 0 ,
PrimitiveMode_LINES = 1 ,
PrimitiveMode_LINE_LOOP = 2 ,
PrimitiveMode_LINE_STRIP = 3 ,
PrimitiveMode_TRIANGLES = 4 ,
PrimitiveMode_TRIANGLE_STRIP = 5 ,
PrimitiveMode_TRIANGLE_FAN = 6
} ;
//! Values for the Accessor::componentType field
enum ComponentType {
ComponentType_BYTE = 5120 ,
ComponentType_UNSIGNED_BYTE = 5121 ,
ComponentType_SHORT = 5122 ,
ComponentType_UNSIGNED_SHORT = 5123 ,
ComponentType_UNSIGNED_INT = 5125 ,
ComponentType_FLOAT = 5126
} ;
inline unsigned int ComponentTypeSize ( ComponentType t ) {
switch ( t ) {
2020-05-18 18:15:18 +00:00
case ComponentType_SHORT :
case ComponentType_UNSIGNED_SHORT :
return 2 ;
case ComponentType_UNSIGNED_INT :
case ComponentType_FLOAT :
return 4 ;
case ComponentType_BYTE :
case ComponentType_UNSIGNED_BYTE :
return 1 ;
default :
2021-03-09 20:08:28 +00:00
throw DeadlyImportError ( " GLTF: Unsupported Component Type " , ai_to_string ( t ) ) ;
2020-03-15 09:17:54 +00:00
}
}
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
//! Values for the BufferView::target field
enum BufferViewTarget {
BufferViewTarget_NONE = 0 ,
BufferViewTarget_ARRAY_BUFFER = 34962 ,
BufferViewTarget_ELEMENT_ARRAY_BUFFER = 34963
} ;
//! Values for the Sampler::magFilter field
enum class SamplerMagFilter : unsigned int {
UNSET = 0 ,
SamplerMagFilter_Nearest = 9728 ,
SamplerMagFilter_Linear = 9729
} ;
//! Values for the Sampler::minFilter field
enum class SamplerMinFilter : unsigned int {
UNSET = 0 ,
SamplerMinFilter_Nearest = 9728 ,
SamplerMinFilter_Linear = 9729 ,
SamplerMinFilter_Nearest_Mipmap_Nearest = 9984 ,
SamplerMinFilter_Linear_Mipmap_Nearest = 9985 ,
SamplerMinFilter_Nearest_Mipmap_Linear = 9986 ,
SamplerMinFilter_Linear_Mipmap_Linear = 9987
} ;
//! Values for the Sampler::wrapS and Sampler::wrapT field
enum class SamplerWrap : unsigned int {
UNSET = 0 ,
Clamp_To_Edge = 33071 ,
Mirrored_Repeat = 33648 ,
Repeat = 10497
} ;
//! Values for the Texture::format and Texture::internalFormat fields
enum TextureFormat {
TextureFormat_ALPHA = 6406 ,
TextureFormat_RGB = 6407 ,
TextureFormat_RGBA = 6408 ,
TextureFormat_LUMINANCE = 6409 ,
TextureFormat_LUMINANCE_ALPHA = 6410
} ;
//! Values for the Texture::target field
enum TextureTarget {
TextureTarget_TEXTURE_2D = 3553
} ;
//! Values for the Texture::type field
enum TextureType {
TextureType_UNSIGNED_BYTE = 5121 ,
TextureType_UNSIGNED_SHORT_5_6_5 = 33635 ,
TextureType_UNSIGNED_SHORT_4_4_4_4 = 32819 ,
TextureType_UNSIGNED_SHORT_5_5_5_1 = 32820
} ;
//! Values for the Animation::Target::path field
enum AnimationPath {
AnimationPath_TRANSLATION ,
AnimationPath_ROTATION ,
AnimationPath_SCALE ,
AnimationPath_WEIGHTS ,
} ;
//! Values for the Animation::Sampler::interpolation field
enum Interpolation {
Interpolation_LINEAR ,
Interpolation_STEP ,
Interpolation_CUBICSPLINE ,
} ;
//! Values for the Accessor::type field (helper class)
class AttribType {
public :
enum Value { SCALAR ,
VEC2 ,
VEC3 ,
VEC4 ,
MAT2 ,
MAT3 ,
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 ) {
for ( size_t i = 0 ; i < NUM_VALUES ; + + i ) {
if ( strcmp ( data < 0 > : : infos [ i ] . name , str ) = = 0 ) {
return static_cast < Value > ( i ) ;
2017-07-19 20:21:43 +00:00
}
}
2020-03-15 09:17:54 +00:00
return SCALAR ;
}
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
inline static const char * ToString ( Value type ) {
return data < 0 > : : infos [ static_cast < size_t > ( type ) ] . name ;
}
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
inline static unsigned int GetNumComponents ( Value type ) {
return data < 0 > : : infos [ static_cast < size_t > ( type ) ] . numComponents ;
}
} ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
// must match the order of the AttribTypeTraits::Value enum!
template < int N >
const AttribType : : Info
AttribType : : data < N > : : infos [ AttribType : : NUM_VALUES ] = {
{ " SCALAR " , 1 } , { " VEC2 " , 2 } , { " VEC3 " , 3 } , { " VEC4 " , 4 } , { " MAT2 " , 4 } , { " MAT3 " , 9 } , { " MAT4 " , 16 }
} ;
2017-07-19 20:21:43 +00:00
2021-06-12 02:20:40 +00:00
struct CustomExtension {
2021-09-14 18:45:36 +00:00
2021-06-12 02:20:40 +00:00
//
// A struct containing custom extension data added to a glTF2 file
// Has to contain Object, Array, String, Double, Uint64, and Int64 at a minimum
// String, Double, Uint64, and Int64 are stored in the Nullables
// Object and Array are stored in the std::vector
//
std : : string name ;
Nullable < std : : string > mStringValue ;
Nullable < double > mDoubleValue ;
Nullable < uint64_t > mUint64Value ;
Nullable < int64_t > mInt64Value ;
Nullable < bool > mBoolValue ;
// std::vector<CustomExtension> handles both Object and Array
Nullable < std : : vector < CustomExtension > > mValues ;
operator bool ( ) const {
return Size ( ) ! = 0 ;
}
size_t Size ( ) const {
if ( mValues . isPresent ) {
return mValues . value . size ( ) ;
} else if ( mStringValue . isPresent | | mDoubleValue . isPresent | | mUint64Value . isPresent | | mInt64Value . isPresent | | mBoolValue . isPresent ) {
return 1 ;
}
return 0 ;
}
CustomExtension ( ) = default ;
2021-07-29 11:28:51 +00:00
2021-06-24 14:18:11 +00:00
~ CustomExtension ( ) = default ;
2021-07-29 11:28:51 +00:00
2023-01-16 20:47:11 +00:00
CustomExtension ( const CustomExtension & other ) = default ;
2022-07-08 16:15:49 +00:00
CustomExtension & operator = ( const CustomExtension & ) = default ;
2021-06-12 02:20:40 +00:00
} ;
2020-03-15 09:17:54 +00:00
//! Base class for all glTF top-level objects
struct Object {
int index ; //!< The index of this object within its property container
int oIndex ; //!< The original index of this object defined in the JSON
std : : string id ; //!< The globally unique ID used to reference this object
std : : string name ; //!< The user-defined name of this object
2017-07-19 20:21:43 +00:00
2021-06-12 03:16:53 +00:00
CustomExtension customExtensions ;
2021-06-27 04:53:40 +00:00
CustomExtension extras ;
2021-06-12 02:20:40 +00:00
2020-03-15 09:17:54 +00:00
//! Objects marked as special are not exported (used to emulate the binary body buffer)
virtual bool IsSpecial ( ) const { return false ; }
2017-07-19 20:21:43 +00:00
2022-09-01 16:28:45 +00:00
virtual ~ Object ( ) = default ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
//! Maps special IDs to another ID, where needed. Subclasses may override it (statically)
static const char * TranslateId ( Asset & /*r*/ , const char * id ) { return id ; }
2021-03-15 13:06:11 +00:00
inline Value * FindString ( Value & val , const char * id ) ;
inline Value * FindNumber ( Value & val , const char * id ) ;
inline Value * FindUInt ( Value & val , const char * id ) ;
inline Value * FindArray ( Value & val , const char * id ) ;
inline Value * FindObject ( Value & val , const char * id ) ;
inline Value * FindExtension ( Value & val , const char * extensionId ) ;
2021-06-12 02:50:44 +00:00
inline void ReadExtensions ( Value & val ) ;
2021-06-27 04:53:40 +00:00
inline void ReadExtras ( Value & val ) ;
2020-03-15 09:17:54 +00:00
} ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
//
// Classes for each glTF top-level object type
//
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
//! A buffer points to binary geometry, animation, or skins.
struct Buffer : public Object {
/********************* Types *********************/
public :
enum Type {
Type_arraybuffer ,
Type_text
} ;
/// \struct SEncodedRegion
/// Descriptor of encoded region in "bufferView".
struct SEncodedRegion {
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.
uint8_t * const DecodedData ; ///< Cached encoded data.
const size_t DecodedData_Length ; ///< Size of decoded region, in bytes.
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)
/// Constructor.
/// \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] pDecodedData - pointer to decoded data array.
/// \param [in] pDecodedData_Length - size of encoded region, in bytes.
/// \param [in] pID - ID of the region.
2021-06-22 16:27:15 +00:00
SEncodedRegion ( const size_t pOffset , const size_t pEncodedData_Length , uint8_t * pDecodedData , const size_t pDecodedData_Length , const std : : string & pID ) :
2020-05-18 18:15:18 +00:00
Offset ( pOffset ) ,
EncodedData_Length ( pEncodedData_Length ) ,
DecodedData ( pDecodedData ) ,
DecodedData_Length ( pDecodedData_Length ) ,
ID ( pID ) { }
2020-03-15 09:17:54 +00:00
/// \fn ~SEncodedRegion()
/// Destructor.
~ SEncodedRegion ( ) { delete [ ] DecodedData ; }
} ;
/******************* 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)
//std::string type; //!< XMLHttpRequest responseType (default: "arraybuffer")
size_t capacity = 0 ; //!< The capacity of the buffer in bytes. (default: 0)
Type type ;
/// \var EncodedRegion_Current
/// Pointer to currently active encoded region.
/// Why not decoding all regions at once and not to set one buffer with decoded data?
/// Yes, why not? Even "accessor" point to decoded data. I mean that fields "byteOffset", "byteStride" and "count" has values which describes decoded
/// data array. But only in range of mesh while is active parameters from "compressedData". For another mesh accessors point to decoded data too. But
/// offset is counted for another regions is encoded.
/// Example. You have two meshes. For every of it you have 4 bytes of data. That data compressed to 2 bytes. So, you have buffer with encoded data:
/// M1_E0, M1_E1, M2_E0, M2_E1.
/// After decoding you'll get:
/// M1_D0, M1_D1, M1_D2, M1_D3, M2_D0, M2_D1, M2_D2, M2_D3.
/// "accessors" must to use values that point to decoded data - obviously. So, you'll expect "accessors" like
/// "accessor_0" : { byteOffset: 0, byteLength: 4}, "accessor_1" : { byteOffset: 4, byteLength: 4}
/// but in real life you'll get:
/// "accessor_0" : { byteOffset: 0, byteLength: 4}, "accessor_1" : { byteOffset: 2, byteLength: 4}
/// Yes, accessor of next mesh has offset and length which mean: current mesh data is decoded, all other data is encoded.
/// And when before you start to read data of current mesh (with encoded data of course) you must decode region of "bufferView", after read finished
/// delete encoding mark. And after that you can repeat process: decode data of mesh, read, delete decoded data.
///
/// Remark. Encoding all data at once is good in world with computers which do not has RAM limitation. So, you must use step by step encoding in
/// exporter and importer. And, thanks to such way, there is no need to load whole file into memory.
SEncodedRegion * EncodedRegion_Current ;
private :
shared_ptr < uint8_t > mData ; //!< Pointer to the data
bool mIsSpecial ; //!< Set to true for special cases (e.g. the body buffer)
/// \var EncodedRegion_List
/// List of encoded regions.
std : : list < SEncodedRegion * > EncodedRegion_List ;
/******************* Functions *******************/
public :
Buffer ( ) ;
~ Buffer ( ) ;
void Read ( Value & obj , Asset & r ) ;
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.
/// \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] pDecodedData - pointer to decoded data array.
/// \param [in] pDecodedData_Length - size of encoded region, in bytes.
/// \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 ) ;
/// \fn void EncodedRegion_SetCurrent(const std::string& pID)
/// Select current encoded region by ID. \sa EncodedRegion_Current.
/// \param [in] pID - ID of the region.
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.
/// \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] pReplace_Data - pointer to array with new data for buffer.
/// \param [in] pReplace_Count - count of bytes in new data.
/// \return true - if successfully replaced, false if input arguments is out of range.
bool ReplaceData ( const size_t pBufferData_Offset , const size_t pBufferData_Count , const uint8_t * pReplace_Data , const size_t pReplace_Count ) ;
bool ReplaceData_joint ( const size_t pBufferData_Offset , const size_t pBufferData_Count , const uint8_t * pReplace_Data , const size_t pReplace_Count ) ;
size_t AppendData ( uint8_t * data , size_t length ) ;
void Grow ( size_t amount ) ;
uint8_t * GetPointer ( ) { return mData . get ( ) ; }
void MarkAsSpecial ( ) { mIsSpecial = true ; }
2021-09-14 18:45:36 +00:00
bool IsSpecial ( ) const override { return mIsSpecial ; }
2020-03-15 09:17:54 +00:00
std : : string GetURI ( ) { return std : : string ( this - > id ) + " .bin " ; }
static const char * TranslateId ( Asset & r , const char * id ) ;
} ;
//! A view into a buffer generally representing a subset of the buffer.
struct BufferView : public Object {
Ref < Buffer > buffer ; //! The ID of the buffer. (required)
size_t byteOffset ; //! The offset into the buffer in bytes. (required)
size_t byteLength ; //! The length of the bufferView in bytes. (default: 0)
unsigned int byteStride ; //!< The stride, in bytes, between attributes referenced by this accessor. (default: 0)
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
BufferViewTarget target ; //! The target that the WebGL buffer should be bound to.
void Read ( Value & obj , Asset & r ) ;
2020-05-11 21:34:35 +00:00
uint8_t * GetPointer ( size_t accOffset ) ;
2020-03-15 09:17:54 +00:00
} ;
2017-07-19 20:21:43 +00:00
2021-01-26 15:56:49 +00:00
//! A typed view into a BufferView. A BufferView contains raw binary data.
//! An accessor provides a typed view into a BufferView or a subset of a BufferView
//! similar to how WebGL's vertexAttribPointer() defines an attribute in a buffer.
struct Accessor : public Object {
struct Sparse ;
Ref < BufferView > bufferView ; //!< The ID of the bufferView. (required)
size_t byteOffset ; //!< The offset relative to the start of the bufferView in bytes. (required)
ComponentType componentType ; //!< The datatype of components in the attribute. (required)
size_t count ; //!< The number of attributes referenced by this accessor. (required)
AttribType : : Value type ; //!< Specifies if the attribute is a scalar, vector, or matrix. (required)
std : : vector < double > max ; //!< Maximum value of each component in this attribute.
std : : vector < double > min ; //!< Minimum value of each component in this attribute.
std : : unique_ptr < Sparse > sparse ;
std : : unique_ptr < Buffer > decodedBuffer ; // Packed decoded data, returned instead of original bufferView if present
unsigned int GetNumComponents ( ) ;
unsigned int GetBytesPerComponent ( ) ;
unsigned int GetElementSize ( ) ;
inline uint8_t * GetPointer ( ) ;
inline size_t GetStride ( ) ;
inline size_t GetMaxByteSize ( ) ;
template < class T >
void ExtractData ( T * & outData ) ;
void WriteData ( size_t count , const void * src_buffer , size_t src_stride ) ;
void WriteSparseValues ( size_t count , const void * src_data , size_t src_dataStride ) ;
void WriteSparseIndices ( size_t count , const void * src_idx , size_t src_idxStride ) ;
//! Helper class to iterate the data
class Indexer {
friend struct Accessor ;
// This field is reported as not used, making it protectd is the easiest way to work around it without going to the bottom of what the problem is:
// ../code/glTF2/glTF2Asset.h:392:19: error: private field 'accessor' is not used [-Werror,-Wunused-private-field]
protected :
Accessor & accessor ;
private :
uint8_t * data ;
size_t elemSize , stride ;
Indexer ( Accessor & acc ) ;
public :
//! Accesses the i-th value as defined by the accessor
template < class T >
T GetValue ( int i ) ;
//! Accesses the i-th value as defined by the accessor
inline unsigned int GetUInt ( int i ) {
return GetValue < unsigned int > ( i ) ;
}
inline bool IsValid ( ) const {
2021-01-27 10:56:57 +00:00
return data ! = nullptr ;
2021-01-26 15:56:49 +00:00
}
} ;
inline Indexer GetIndexer ( ) {
return Indexer ( * this ) ;
}
2022-09-01 16:28:45 +00:00
Accessor ( ) = default ;
2021-01-26 15:56:49 +00:00
void Read ( Value & obj , Asset & r ) ;
//sparse
struct Sparse {
size_t count ;
ComponentType indicesType ;
Ref < BufferView > indices ;
size_t indicesByteOffset ;
Ref < BufferView > values ;
size_t valuesByteOffset ;
std : : vector < uint8_t > data ; //!< Actual data, which may be defaulted to an array of zeros or the original data, with the sparse buffer view applied on top of it.
void PopulateData ( size_t numBytes , uint8_t * bytes ) ;
void PatchData ( unsigned int elementSize ) ;
} ;
} ;
2020-03-15 09:17:54 +00:00
struct Camera : public Object {
enum Type {
Perspective ,
Orthographic
} ;
Type type ;
union {
struct {
float aspectRatio ; //!<The floating - point aspect ratio of the field of view. (0 = undefined = use the canvas one)
float yfov ; //!<The floating - point vertical field of view in radians. (required)
float zfar ; //!<The floating - point distance to the far clipping plane. (required)
float znear ; //!< The floating - point distance to the near clipping plane. (required)
} perspective ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
struct {
float xmag ; //! The floating-point horizontal magnification of the view. (required)
float ymag ; //! The floating-point vertical magnification of the view. (required)
float zfar ; //! The floating-point distance to the far clipping plane. (required)
float znear ; //! The floating-point distance to the near clipping plane. (required)
} ortographic ;
} cameraProperties ;
Camera ( ) :
2020-05-18 18:15:18 +00:00
type ( Perspective ) ,
cameraProperties ( ) {
2020-03-15 09:17:54 +00:00
// empty
}
void Read ( Value & obj , Asset & r ) ;
} ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
//! A light (from KHR_lights_punctual extension)
struct Light : public Object {
enum Type {
Directional ,
Point ,
Spot
2017-07-19 20:21:43 +00:00
} ;
2020-03-15 09:17:54 +00:00
Type type ;
2019-08-03 18:51:00 +00:00
2020-03-15 09:17:54 +00:00
vec3 color ;
float intensity ;
Nullable < float > range ;
2019-08-03 18:51:00 +00:00
2020-03-15 09:17:54 +00:00
float innerConeAngle ;
float outerConeAngle ;
2019-08-03 18:51:00 +00:00
2022-09-01 16:28:45 +00:00
Light ( ) = default ;
2020-03-15 09:17:54 +00:00
void Read ( Value & obj , Asset & r ) ;
} ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
//! Image data used to create a texture.
struct Image : public Object {
std : : string uri ; //! The uri of the image, that can be a file path, a data URI, etc.. (required)
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
Ref < BufferView > bufferView ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
std : : string mimeType ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
int width , height ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
private :
std : : unique_ptr < uint8_t [ ] > mData ;
size_t mDataLength ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
public :
Image ( ) ;
void Read ( Value & obj , Asset & r ) ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
inline bool HasData ( ) const { return mDataLength > 0 ; }
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
inline size_t GetDataLength ( ) const { return mDataLength ; }
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
inline const uint8_t * GetData ( ) const { return mData . get ( ) ; }
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
inline uint8_t * StealData ( ) ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
inline void SetData ( uint8_t * data , size_t length , Asset & r ) ;
} ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
const vec4 defaultBaseColor = { 1 , 1 , 1 , 1 } ;
const vec3 defaultEmissiveFactor = { 0 , 0 , 0 } ;
const vec4 defaultDiffuseFactor = { 1 , 1 , 1 , 1 } ;
const vec3 defaultSpecularFactor = { 1 , 1 , 1 } ;
2022-11-08 21:09:50 +00:00
const vec3 defaultSpecularColorFactor = { 0 , 0 , 0 } ;
2020-12-20 06:59:12 +00:00
const vec3 defaultSheenFactor = { 0 , 0 , 0 } ;
2021-09-29 16:05:17 +00:00
const vec3 defaultAttenuationColor = { 1 , 1 , 1 } ;
2017-09-05 19:45:32 +00:00
2020-03-15 09:17:54 +00:00
struct TextureInfo {
Ref < Texture > texture ;
unsigned int index ;
unsigned int texCoord = 0 ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
bool textureTransformSupported = false ;
struct TextureTransformExt {
float offset [ 2 ] ;
float rotation ;
float scale [ 2 ] ;
} TextureTransformExt_t ;
} ;
2019-11-16 07:08:57 +00:00
2020-03-15 09:17:54 +00:00
struct NormalTextureInfo : TextureInfo {
float scale = 1 ;
} ;
2017-08-30 21:25:11 +00:00
2020-03-15 09:17:54 +00:00
struct OcclusionTextureInfo : TextureInfo {
float strength = 1 ;
} ;
2017-08-28 03:47:54 +00:00
2020-03-15 09:17:54 +00:00
struct PbrMetallicRoughness {
vec4 baseColorFactor ;
TextureInfo baseColorTexture ;
TextureInfo metallicRoughnessTexture ;
float metallicFactor ;
float roughnessFactor ;
} ;
2017-08-31 22:30:43 +00:00
2020-03-15 09:17:54 +00:00
struct PbrSpecularGlossiness {
vec4 diffuseFactor ;
vec3 specularFactor ;
float glossinessFactor ;
TextureInfo diffuseTexture ;
TextureInfo specularGlossinessTexture ;
2017-09-05 20:29:00 +00:00
2020-03-15 09:17:54 +00:00
PbrSpecularGlossiness ( ) { SetDefaults ( ) ; }
void SetDefaults ( ) ;
} ;
2017-08-31 22:30:43 +00:00
2022-11-08 21:09:50 +00:00
struct MaterialSpecular {
float specularFactor ;
vec3 specularColorFactor ;
TextureInfo specularTexture ;
TextureInfo specularColorTexture ;
MaterialSpecular ( ) { SetDefaults ( ) ; }
void SetDefaults ( ) ;
} ;
2020-12-20 06:59:12 +00:00
struct MaterialSheen {
vec3 sheenColorFactor ;
float sheenRoughnessFactor ;
TextureInfo sheenColorTexture ;
TextureInfo sheenRoughnessTexture ;
MaterialSheen ( ) { SetDefaults ( ) ; }
void SetDefaults ( ) ;
} ;
2020-12-23 07:12:09 +00:00
struct MaterialClearcoat {
float clearcoatFactor = 0.f ;
float clearcoatRoughnessFactor = 0.f ;
TextureInfo clearcoatTexture ;
TextureInfo clearcoatRoughnessTexture ;
NormalTextureInfo clearcoatNormalTexture ;
} ;
2020-12-23 09:43:01 +00:00
struct MaterialTransmission {
TextureInfo transmissionTexture ;
float transmissionFactor = 0.f ;
} ;
2021-09-29 16:05:17 +00:00
struct MaterialVolume {
float thicknessFactor = 0.f ;
TextureInfo thicknessTexture ;
float attenuationDistance = 0.f ;
vec3 attenuationColor ;
MaterialVolume ( ) { SetDefaults ( ) ; }
void SetDefaults ( ) ;
} ;
2021-10-07 08:36:53 +00:00
struct MaterialIOR {
float ior = 0.f ;
MaterialIOR ( ) { SetDefaults ( ) ; }
void SetDefaults ( ) ;
} ;
2022-11-03 21:11:21 +00:00
struct MaterialEmissiveStrength {
float emissiveStrength = 0.f ;
MaterialEmissiveStrength ( ) { SetDefaults ( ) ; }
void SetDefaults ( ) ;
} ;
2020-03-15 09:17:54 +00:00
//! The material appearance of a primitive.
struct Material : public Object {
//PBR metallic roughness properties
PbrMetallicRoughness pbrMetallicRoughness ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
//other basic material properties
NormalTextureInfo normalTexture ;
OcclusionTextureInfo occlusionTexture ;
TextureInfo emissiveTexture ;
vec3 emissiveFactor ;
std : : string alphaMode ;
float alphaCutoff ;
bool doubleSided ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
//extension: KHR_materials_pbrSpecularGlossiness
Nullable < PbrSpecularGlossiness > pbrSpecularGlossiness ;
2017-07-19 20:21:43 +00:00
2022-11-08 21:09:50 +00:00
//extension: KHR_materials_specular
Nullable < MaterialSpecular > materialSpecular ;
2020-12-20 06:59:12 +00:00
//extension: KHR_materials_sheen
Nullable < MaterialSheen > materialSheen ;
2020-12-23 07:12:09 +00:00
//extension: KHR_materials_clearcoat
Nullable < MaterialClearcoat > materialClearcoat ;
2020-12-23 09:43:01 +00:00
//extension: KHR_materials_transmission
Nullable < MaterialTransmission > materialTransmission ;
2021-09-29 16:05:17 +00:00
//extension: KHR_materials_volume
Nullable < MaterialVolume > materialVolume ;
2021-09-30 07:47:53 +00:00
2021-10-07 08:36:53 +00:00
//extension: KHR_materials_ior
Nullable < MaterialIOR > materialIOR ;
2022-11-04 16:37:28 +00:00
//extension: KHR_materials_emissive_strength
2022-11-03 21:11:21 +00:00
Nullable < MaterialEmissiveStrength > materialEmissiveStrength ;
2020-03-15 09:17:54 +00:00
//extension: KHR_materials_unlit
bool unlit ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
Material ( ) { SetDefaults ( ) ; }
void Read ( Value & obj , Asset & r ) ;
void SetDefaults ( ) ;
2021-03-15 13:06:11 +00:00
inline void SetTextureProperties ( Asset & r , Value * prop , TextureInfo & out ) ;
inline void ReadTextureProperty ( Asset & r , Value & vals , const char * propName , TextureInfo & out ) ;
inline void ReadTextureProperty ( Asset & r , Value & vals , const char * propName , NormalTextureInfo & out ) ;
inline void ReadTextureProperty ( Asset & r , Value & vals , const char * propName , OcclusionTextureInfo & out ) ;
2020-03-15 09:17:54 +00:00
} ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
//! A set of primitives to be rendered. A node can contain one or more meshes. A node's transform places the mesh in the scene.
struct Mesh : public Object {
2021-09-14 18:45:36 +00:00
using AccessorList = std : : vector < Ref < Accessor > > ;
2018-07-05 13:28:29 +00:00
2020-03-15 09:17:54 +00:00
struct Primitive {
PrimitiveMode mode ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
struct Attributes {
AccessorList position , normal , tangent , texcoord , color , joint , jointmatrix , weight ;
} attributes ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
Ref < Accessor > indices ;
2018-07-05 13:28:29 +00:00
2020-03-15 09:17:54 +00:00
Ref < Material > material ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
struct Target {
AccessorList position , normal , tangent ;
} ;
std : : vector < Target > targets ;
2021-03-29 17:03:01 +00:00
// extension: FB_ngon_encoding
bool ngonEncoded ;
Primitive ( ) : ngonEncoded ( false ) { }
2017-07-19 20:21:43 +00:00
} ;
2020-03-15 09:17:54 +00:00
std : : vector < Primitive > primitives ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
std : : vector < float > weights ;
2020-04-14 23:31:27 +00:00
std : : vector < std : : string > targetNames ;
2017-07-19 20:21:43 +00:00
2022-09-01 16:28:45 +00:00
Mesh ( ) = default ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
/// 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 [out] pAsset_Root - reference to root asset where data will be stored.
void Read ( Value & pJSON_Object , Asset & pAsset_Root ) ;
} ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
struct Node : public Object {
std : : vector < Ref < Node > > children ;
std : : vector < Ref < Mesh > > meshes ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
Nullable < mat4 > matrix ;
Nullable < vec3 > translation ;
Nullable < vec4 > rotation ;
Nullable < vec3 > scale ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
Ref < Camera > camera ;
Ref < Light > light ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
std : : vector < Ref < Node > > skeletons ; //!< The ID of skeleton nodes. Each of which is the root of a node hierarchy.
Ref < Skin > skin ; //!< The ID of the skin referenced by this node.
std : : string jointName ; //!< Name used when this node is a joint in a skin.
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
Ref < Node > parent ; //!< This is not part of the glTF specification. Used as a helper.
2017-07-19 20:21:43 +00:00
2022-09-01 16:28:45 +00:00
Node ( ) = default ;
2020-03-15 09:17:54 +00:00
void Read ( Value & obj , Asset & r ) ;
} ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
struct Program : public Object {
2022-09-01 16:28:45 +00:00
Program ( ) = default ;
2020-03-15 09:17:54 +00:00
void Read ( Value & obj , Asset & r ) ;
} ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
struct Sampler : public Object {
SamplerMagFilter magFilter ; //!< The texture magnification filter.
SamplerMinFilter minFilter ; //!< The texture minification filter.
SamplerWrap wrapS ; //!< The texture wrapping in the S direction.
SamplerWrap wrapT ; //!< The texture wrapping in the T direction.
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
Sampler ( ) { SetDefaults ( ) ; }
void Read ( Value & obj , Asset & r ) ;
void SetDefaults ( ) ;
} ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
struct Scene : public Object {
2020-11-22 05:10:36 +00:00
std : : string name ;
2020-03-15 09:17:54 +00:00
std : : vector < Ref < Node > > nodes ;
2017-07-19 20:21:43 +00:00
2022-09-01 16:28:45 +00:00
Scene ( ) = default ;
2020-03-15 09:17:54 +00:00
void Read ( Value & obj , Asset & r ) ;
} ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
struct Shader : public Object {
2022-09-01 16:28:45 +00:00
Shader ( ) = default ;
2020-03-15 09:17:54 +00:00
void Read ( Value & obj , Asset & r ) ;
} ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
struct Skin : public Object {
Nullable < mat4 > bindShapeMatrix ; //!< Floating-point 4x4 transformation matrix stored in column-major order.
Ref < Accessor > inverseBindMatrices ; //!< The ID of the accessor containing the floating-point 4x4 inverse-bind matrices.
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.
2017-07-19 20:21:43 +00:00
2022-09-01 16:28:45 +00:00
Skin ( ) = default ;
2020-03-15 09:17:54 +00:00
void Read ( Value & obj , Asset & r ) ;
} ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
//! A texture and its sampler.
struct Texture : public Object {
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)
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
//TextureFormat format; //!< The texture's format. (default: TextureFormat_RGBA)
//TextureFormat internalFormat; //!< The texture's internal format. (default: TextureFormat_RGBA)
2018-10-26 22:36:34 +00:00
2020-03-15 09:17:54 +00:00
//TextureTarget target; //!< The target that the WebGL texture should be bound to. (default: TextureTarget_TEXTURE_2D)
//TextureType type; //!< Texel datatype. (default: TextureType_UNSIGNED_BYTE)
2017-07-19 20:21:43 +00:00
2022-09-01 16:28:45 +00:00
Texture ( ) = default ;
2020-03-15 09:17:54 +00:00
void Read ( Value & obj , Asset & r ) ;
} ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
struct Animation : public Object {
struct Sampler {
Sampler ( ) :
interpolation ( Interpolation_LINEAR ) { }
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
Ref < Accessor > input ; //!< Accessor reference to the buffer storing the key-frame times.
Ref < Accessor > output ; //!< Accessor reference to the buffer storing the key-frame values.
Interpolation interpolation ; //!< Type of interpolation algorithm to use between key-frames.
} ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
struct Target {
Target ( ) :
path ( AnimationPath_TRANSLATION ) { }
Ref < Node > node ; //!< The node to animate.
AnimationPath path ; //!< The property of the node to animate.
} ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
struct Channel {
Channel ( ) :
sampler ( - 1 ) { }
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
int sampler ; //!< The sampler index containing the animation data.
Target target ; //!< The node and property to animate.
2017-07-19 20:21:43 +00:00
} ;
2020-03-15 09:17:54 +00:00
std : : vector < Sampler > samplers ; //!< All the key-frame data for this animation.
std : : vector < Channel > channels ; //!< Data to connect nodes to key-frames.
2017-07-19 20:21:43 +00:00
2022-09-01 16:28:45 +00:00
Animation ( ) = default ;
2020-03-15 09:17:54 +00:00
void Read ( Value & obj , Asset & r ) ;
} ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
//! Base class for LazyDict that acts as an interface
class LazyDictBase {
public :
2022-09-01 16:28:45 +00:00
virtual ~ LazyDictBase ( ) = default ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
virtual void AttachToDocument ( Document & doc ) = 0 ;
virtual void DetachFromDocument ( ) = 0 ;
2017-07-19 20:21:43 +00:00
2021-04-16 18:44:40 +00:00
# if !defined(ASSIMP_BUILD_NO_EXPORT)
2020-03-15 09:17:54 +00:00
virtual void WriteObjects ( AssetWriter & writer ) = 0 ;
2021-04-16 18:44:40 +00:00
# endif
2020-03-15 09:17:54 +00:00
} ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
template < class T >
class LazyDict ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
//! (Implemented in glTFAssetWriter.h)
template < class T >
void WriteLazyDict ( LazyDict < T > & d , AssetWriter & w ) ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
//! 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
template < class T >
class LazyDict : public LazyDictBase {
friend class Asset ;
friend class AssetWriter ;
2017-07-19 20:21:43 +00:00
2021-09-14 18:45:36 +00:00
using Dict = typename std : : gltf_unordered_map < unsigned int , unsigned int > ;
using IdDict = typename std : : gltf_unordered_map < std : : string , unsigned int > ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
std : : vector < T * > mObjs ; //! The read objects
Dict mObjsByOIndex ; //! The read objects accessible by original index
IdDict mObjsById ; //! The read objects accessible by id
const char * mDictId ; //! ID of the dictionary object
const char * mExtId ; //! ID of the extension defining the dictionary
Value * mDict ; //! JSON dictionary object
Asset & mAsset ; //! The asset instance
2017-07-19 20:21:43 +00:00
2020-05-18 18:15:18 +00:00
std : : gltf_unordered_set < unsigned int > mRecursiveReferenceCheck ; //! Used by Retrieve to prevent recursive lookups
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
void AttachToDocument ( Document & doc ) ;
void DetachFromDocument ( ) ;
2017-07-19 20:21:43 +00:00
2021-04-16 18:44:40 +00:00
# if !defined(ASSIMP_BUILD_NO_EXPORT)
2020-03-15 09:17:54 +00:00
void WriteObjects ( AssetWriter & writer ) { WriteLazyDict < T > ( * this , writer ) ; }
2021-04-16 18:44:40 +00:00
# endif
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
Ref < T > Add ( T * obj ) ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
public :
2022-11-08 16:03:55 +00:00
LazyDict ( Asset & asset , const char * dictId , const char * extId = nullptr ) ;
2020-03-15 09:17:54 +00:00
~ LazyDict ( ) ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
Ref < T > Retrieve ( unsigned int i ) ;
2017-08-25 20:09:07 +00:00
2020-03-15 09:17:54 +00:00
Ref < T > Get ( unsigned int i ) ;
Ref < T > Get ( const char * id ) ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
Ref < T > Create ( const char * id ) ;
Ref < T > Create ( const std : : string & id ) { return Create ( id . c_str ( ) ) ; }
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
unsigned int Remove ( const char * id ) ;
2017-11-07 20:13:01 +00:00
2020-03-15 09:17:54 +00:00
inline unsigned int Size ( ) const { return unsigned ( mObjs . size ( ) ) ; }
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
inline T & operator [ ] ( size_t i ) { return * mObjs [ i ] ; }
} ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
struct AssetMetadata {
std : : string copyright ; //!< A copyright message suitable for display to credit the content creator.
std : : string generator ; //!< Tool that generated this glTF model.Useful for debugging.
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
struct {
std : : string api ; //!< Specifies the target rendering API (default: "WebGL")
std : : string version ; //!< Specifies the target rendering API (default: "1.0.3")
} profile ; //!< Specifies the target rendering API and version, e.g., WebGL 1.0.3. (default: {})
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
std : : string version ; //!< The glTF format version
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
void Read ( Document & doc ) ;
2017-07-19 20:21:43 +00:00
2023-01-16 20:47:11 +00:00
AssetMetadata ( ) = default ;
2020-03-15 09:17:54 +00:00
} ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
//
// glTF Asset class
//
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
//! Root object for a glTF asset
class Asset {
2021-09-14 18:45:36 +00:00
using IdMap = std : : gltf_unordered_map < std : : string , int > ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
template < class T >
friend class LazyDict ;
friend struct Buffer ; // To access OpenFile
friend class AssetWriter ;
2017-07-19 20:21:43 +00:00
2022-02-23 19:57:15 +00:00
std : : vector < LazyDictBase * > mDicts ;
2020-03-15 09:17:54 +00:00
public :
//! Keeps info about the enabled extensions
struct Extensions {
bool KHR_materials_pbrSpecularGlossiness ;
2022-11-08 21:09:50 +00:00
bool KHR_materials_specular ;
2020-03-15 09:17:54 +00:00
bool KHR_materials_unlit ;
bool KHR_lights_punctual ;
bool KHR_texture_transform ;
2020-12-20 06:59:12 +00:00
bool KHR_materials_sheen ;
2020-12-23 07:12:09 +00:00
bool KHR_materials_clearcoat ;
2020-12-23 09:43:01 +00:00
bool KHR_materials_transmission ;
2021-09-29 16:05:17 +00:00
bool KHR_materials_volume ;
2021-10-07 08:36:53 +00:00
bool KHR_materials_ior ;
2022-11-04 16:37:28 +00:00
bool KHR_materials_emissive_strength ;
2021-01-26 15:56:49 +00:00
bool KHR_draco_mesh_compression ;
2021-03-10 08:48:12 +00:00
bool FB_ngon_encoding ;
2021-05-06 22:10:06 +00:00
bool KHR_texture_basisu ;
2022-02-22 20:07:42 +00:00
Extensions ( ) :
KHR_materials_pbrSpecularGlossiness ( false ) ,
2022-11-08 21:09:50 +00:00
KHR_materials_specular ( false ) ,
2022-02-22 20:07:42 +00:00
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 ) ,
2022-11-04 16:37:28 +00:00
KHR_materials_emissive_strength ( false ) ,
2022-02-22 20:07:42 +00:00
KHR_draco_mesh_compression ( false ) ,
FB_ngon_encoding ( false ) ,
KHR_texture_basisu ( false ) {
// empty
}
2020-03-15 09:17:54 +00:00
} extensionsUsed ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
//! Keeps info about the required extensions
struct RequiredExtensions {
bool KHR_draco_mesh_compression ;
2021-05-06 22:10:06 +00:00
bool KHR_texture_basisu ;
2022-02-22 20:07:42 +00:00
RequiredExtensions ( ) : KHR_draco_mesh_compression ( false ) , KHR_texture_basisu ( false ) {
// empty
}
2020-03-15 09:17:54 +00:00
} extensionsRequired ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
AssetMetadata asset ;
2022-02-22 20:07:42 +00:00
Value * extras ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
// Dictionaries for each type of object
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
LazyDict < Accessor > accessors ;
LazyDict < Animation > animations ;
LazyDict < Buffer > buffers ;
LazyDict < BufferView > bufferViews ;
LazyDict < Camera > cameras ;
LazyDict < Light > lights ;
LazyDict < Image > images ;
LazyDict < Material > materials ;
LazyDict < Mesh > meshes ;
LazyDict < Node > nodes ;
LazyDict < Sampler > samplers ;
LazyDict < Scene > scenes ;
LazyDict < Skin > skins ;
LazyDict < Texture > textures ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
Ref < Scene > scene ;
2017-11-20 13:59:05 +00:00
2020-03-15 09:17:54 +00:00
public :
2022-02-23 19:57:15 +00:00
Asset ( IOSystem * io = nullptr , rapidjson : : IRemoteSchemaDocumentProvider * schemaDocumentProvider = nullptr ) :
mDicts ( ) ,
2022-02-22 20:07:42 +00:00
extensionsUsed ( ) ,
extensionsRequired ( ) ,
2020-05-18 18:15:18 +00:00
asset ( ) ,
2022-02-22 20:07:42 +00:00
extras ( nullptr ) ,
2020-05-18 18:15:18 +00:00
accessors ( * this , " accessors " ) ,
animations ( * this , " animations " ) ,
buffers ( * this , " buffers " ) ,
bufferViews ( * this , " bufferViews " ) ,
cameras ( * this , " cameras " ) ,
lights ( * this , " lights " , " KHR_lights_punctual " ) ,
images ( * this , " images " ) ,
materials ( * this , " materials " ) ,
meshes ( * this , " meshes " ) ,
nodes ( * this , " nodes " ) ,
samplers ( * this , " samplers " ) ,
scenes ( * this , " scenes " ) ,
skins ( * this , " skins " ) ,
2022-02-22 20:07:42 +00:00
textures ( * this , " textures " ) ,
mIOSystem ( io ) ,
mSchemaDocumentProvider ( schemaDocumentProvider ) {
// empty
2020-03-15 09:17:54 +00:00
}
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
//! Main function
void Load ( const std : : string & file , bool isBinary = false ) ;
2017-07-19 20:21:43 +00:00
2021-10-06 12:41:45 +00:00
//! Parse the AssetMetadata and check that the version is 2.
bool CanRead ( const std : : string & pFile , bool isBinary = false ) ;
2020-03-15 09:17:54 +00:00
//! Enables binary encoding on the asset
void SetAsBinary ( ) ;
2017-07-19 20:21:43 +00:00
2020-03-15 09:17:54 +00:00
//! Search for an available name, starting from the given strings
std : : string FindUniqueID ( const std : : string & str , const char * suffix ) ;
2017-11-20 13:59:05 +00:00
2020-03-15 09:17:54 +00:00
Ref < Buffer > GetBodyBuffer ( ) { return mBodyBuffer ; }
2017-07-19 20:21:43 +00:00
2022-02-22 20:07:42 +00:00
Asset ( Asset & ) = delete ;
Asset & operator = ( const Asset & ) = delete ;
2020-03-15 09:17:54 +00:00
private :
void ReadBinaryHeader ( IOStream & stream , std : : vector < char > & sceneData ) ;
2017-07-19 20:21:43 +00:00
2022-02-22 20:07:42 +00:00
/// Obtain a JSON document from the stream.
/// \param second argument is a buffer used by the document. It must be kept
/// alive while the document is in use.
2021-10-06 12:41:45 +00:00
Document ReadDocument ( IOStream & stream , bool isBinary , std : : vector < char > & sceneData ) ;
2020-03-15 09:17:54 +00:00
void ReadExtensionsUsed ( Document & doc ) ;
void ReadExtensionsRequired ( Document & doc ) ;
2021-06-22 16:27:15 +00:00
IOStream * OpenFile ( const std : : string & path , const char * mode , bool absolute = false ) ;
2022-02-22 20:07:42 +00:00
private :
IOSystem * mIOSystem ;
rapidjson : : IRemoteSchemaDocumentProvider * mSchemaDocumentProvider ;
std : : string mCurrentAssetDir ;
size_t mSceneLength ;
size_t mBodyOffset ;
size_t mBodyLength ;
IdMap mUsedIds ;
Ref < Buffer > mBodyBuffer ;
2020-03-15 09:17:54 +00:00
} ;
2020-11-30 15:04:06 +00:00
inline std : : string getContextForErrorMessages ( const std : : string & id , const std : : string & name ) {
std : : string context = id ;
if ( ! name . empty ( ) ) {
context + = " ( \" " + name + " \" ) " ;
}
return context ;
}
2020-03-15 09:17:54 +00:00
} // namespace glTF2
2017-07-19 20:21:43 +00:00
// Include the implementation of the methods
2017-07-20 17:59:21 +00:00
# include "glTF2Asset.inl"
2017-07-19 20:21:43 +00:00
# endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
2017-07-20 17:59:21 +00:00
# endif // GLTF2ASSET_H_INC