[+] Save parameters of mesh extension: Open3DGC-compression.

pull/972/head
Alexandr Arutjunov 2016-08-09 13:26:57 +03:00
parent 507668229f
commit 9a4fa1321b
4 changed files with 148 additions and 3 deletions

View File

@ -362,8 +362,6 @@ namespace glTF
{ return id; }
};
//
// Classes for each glTF top-level object type
//
@ -478,6 +476,15 @@ namespace glTF
bool LoadFromStream(IOStream& stream, size_t length = 0, size_t baseOffset = 0);
/// \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. For example: decoded/encoded data.
/// \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);
size_t AppendData(uint8_t* data, size_t length);
void Grow(size_t amount);
@ -702,10 +709,57 @@ namespace glTF
Ref<Material> material;
};
/// \struct SExtension
/// Extension used for mesh.
struct SExtension
{
/// \enum EType
/// Type of extension.
enum class EType
{
Compression_Open3DGC ///< Compression of mesh data using Open3DGC algorythm.
};
EType Type;///< Type of extension.
/// \fn SExtension
/// Constructor.
/// \param [in] pType - type of extension.
SExtension(const EType pType)
: Type(pType)
{}
};
/// \struct SCompression_Open3DGC
/// Compression of mesh data using Open3DGC algorythm.
struct SCompression_Open3DGC final : public SExtension
{
using SExtension::Type;
std::string BufferView;///< Name of "bufferView" used for storing compressed data.
size_t Offset;///< Offset in "bufferView" where compressed data are stored.
size_t Count;///< Count of elements in compressed data. Is always equivalent to size in bytes: look comments for "Type" and "Component_Type".
size_t IndicesCount;///< Count of indices in mesh.
size_t VerticesCount;///< Count of vertices in mesh.
// AttribType::Value Type;///< Is always "SCALAR".
// ComponentType Component_Type;///< Is always "ComponentType_UNSIGNED_BYTE" (5121).
/// \fn SCompression_Open3DGC
/// Constructor.
SCompression_Open3DGC()
: SExtension(EType::Compression_Open3DGC)
{}
};
std::vector<Primitive> primitives;
std::list<SExtension*> Extension;///< List of extensions used in mesh.
Mesh() {}
/// \fn ~Mesh()
/// Destructor.
~Mesh() { for(auto e : Extension) { delete e; }; }
/// \fn void Read(Value& pJSON_Object, Asset& pAsset_Root)
/// 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.

View File

@ -330,6 +330,28 @@ inline bool Buffer::LoadFromStream(IOStream& stream, size_t length, size_t baseO
return true;
}
inline bool Buffer::ReplaceData(const size_t pBufferData_Offset, const size_t pBufferData_Count, const uint8_t* pReplace_Data, const size_t pReplace_Count)
{
const size_t new_data_size = byteLength + pReplace_Count - pBufferData_Count;
uint8_t* new_data;
if((pBufferData_Count == 0) || (pReplace_Count == 0) || (pReplace_Data == nullptr)) return false;
new_data = new uint8_t[new_data_size];
// Copy data which place before replacing part.
memcpy(new_data, mData.get(), pBufferData_Offset);
// Copy new data.
memcpy(&new_data[pBufferData_Offset], pReplace_Data, pReplace_Count);
// Copy data which place after replacing part.
memcpy(&new_data[pBufferData_Offset + pReplace_Count], &mData.get()[pBufferData_Offset + pBufferData_Count], pBufferData_Offset);
// Apply new data
mData.reset(new_data);
byteLength = new_data_size;
return true;
}
inline size_t Buffer::AppendData(uint8_t* data, size_t length)
{
size_t offset = this->byteLength;

View File

@ -199,6 +199,53 @@ namespace glTF {
inline void Write(Value& obj, Mesh& m, AssetWriter& w)
{
/********************* Name **********************/
obj.AddMember("name", m.name, w.mAl);
/**************** Mesh extensions ****************/
if(m.Extension.size() > 0)
{
Value json_extensions;
json_extensions.SetObject();
for(Mesh::SExtension* ptr_ext : m.Extension)
{
switch(ptr_ext->Type)
{
case Mesh::SExtension::EType::Compression_Open3DGC:
{
Value json_comp_data;
Mesh::SCompression_Open3DGC* ptr_ext_comp = (Mesh::SCompression_Open3DGC*)ptr_ext;
// filling object "compressedData"
json_comp_data.SetObject();
json_comp_data.AddMember("bufferView", ptr_ext_comp->BufferView, w.mAl);
json_comp_data.AddMember("byteOffset", ptr_ext_comp->Offset, w.mAl);
json_comp_data.AddMember("componentType", 5121, w.mAl);
json_comp_data.AddMember("type", "SCALAR", w.mAl);
json_comp_data.AddMember("count", ptr_ext_comp->Count, w.mAl);
json_comp_data.AddMember("indicesCount", ptr_ext_comp->IndicesCount, w.mAl);
json_comp_data.AddMember("verticesCount", ptr_ext_comp->VerticesCount, w.mAl);
// filling object "Open3DGC-compression"
Value json_o3dgc;
json_o3dgc.SetObject();
json_o3dgc.AddMember("compressedData", json_comp_data, w.mAl);
// add member to object "extensions"
json_extensions.AddMember("Open3DGC-compression", json_o3dgc, w.mAl);
}
break;
default:
throw DeadlyImportError("GLTF: Unknown mesh extension, Only Open3DGC is supported.");
}// switch(ptr_ext->Type)
}// for(Mesh::SExtension* ptr_ext : m.Extension)
// Add extensions to mesh
obj.AddMember("extensions", json_extensions, w.mAl);
}// if(m.Extension.size() > 0)
/****************** Primitives *******************/
Value primitives;
primitives.SetArray();
primitives.Reserve(unsigned(m.primitives.size()), w.mAl);

View File

@ -357,10 +357,16 @@ bool comp_allow;// Point that data of current mesh can be compressed.
///TODO: animation: weights, joints.
if(comp_allow)
{
// Only one type of compression supported at now - Open3DGC.
//
o3dgc::BinaryStream bs;
o3dgc::SC3DMCEncoder<IndicesType> encoder;
o3dgc::IndexedFaceSet<IndicesType> comp_o3dgc_ifs;
o3dgc::SC3DMCEncodeParams comp_o3dgc_params;
//
// Fill data for encoder.
//
unsigned qcoord = 12;///TODO: dbg
unsigned qnormal = 10;///TODO: dbg
unsigned qtexCoord = 10;///TODO: dbg
@ -407,10 +413,26 @@ bool comp_allow;// Point that data of current mesh can be compressed.
// Prepare to enconding
comp_o3dgc_params.SetNumFloatAttributes(comp_o3dgc_ifs.GetNumFloatAttributes());
comp_o3dgc_params.SetStreamType(o3dgc::O3DGC_STREAM_TYPE_BINARY);///TODO: exporter params
//
// Encoding
//
encoder.Encode(comp_o3dgc_params, comp_o3dgc_ifs, bs);
// Replace data in buffer.
b->ReplaceData(idx_srcdata_begin, b->byteLength - idx_srcdata_begin, bs.GetBuffer(), bs.GetSize());
//
// Add information about extension to mesh.
//
// Create extension structure.
Mesh::SCompression_Open3DGC* ext = new Mesh::SCompression_Open3DGC;
///TODO: replace data in buffer
// Fill it.
ext->BufferView = p.indices->bufferView->id;
ext->Offset = idx_srcdata_begin;
ext->Count = b->byteLength - idx_srcdata_begin;
ext->IndicesCount = comp_o3dgc_ifs.GetNCoordIndex();
ext->VerticesCount = comp_o3dgc_ifs.GetNCoord();
// And assign to mesh.
m->Extension.push_back(ext);
}// if(comp_allow)
}// for (unsigned int i = 0; i < mScene->mNumMeshes; ++i) {