mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-19 15:52:53 +00:00
chore: add output implementations for gltf and glb
This commit is contained in:
parent
7a0930a208
commit
c27f4ed544
20
src/ObjCommon/XModel/Gltf/GltfConstants.h
Normal file
20
src/ObjCommon/XModel/Gltf/GltfConstants.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "Utils/FileUtils.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace gltf
|
||||
{
|
||||
constexpr uint32_t GLTF_MAGIC = FileUtils::MakeMagic32('g', 'l', 'T', 'F');
|
||||
constexpr uint32_t GLTF_VERSION = 2u;
|
||||
|
||||
constexpr uint32_t CHUNK_MAGIC_JSON = FileUtils::MakeMagic32('J', 'S', 'O', 'N');
|
||||
constexpr uint32_t CHUNK_MAGIC_BIN = FileUtils::MakeMagic32('B', 'I', 'N', '\x00');
|
||||
|
||||
constexpr auto GLTF_LENGTH_OFFSET = 8u;
|
||||
constexpr auto GLTF_JSON_CHUNK_LENGTH_OFFSET = 12u;
|
||||
constexpr auto GLTF_JSON_CHUNK_DATA_OFFSET = 20u;
|
||||
|
||||
constexpr auto GLTF_DATA_URI_PREFIX = "data:application/octet-stream;base64,";
|
||||
} // namespace gltf
|
@ -19,6 +19,7 @@ function ObjWriting:link(links)
|
||||
links:linkto(ZoneCommon)
|
||||
links:linkto(minilzo)
|
||||
links:linkto(minizip)
|
||||
links:linkto(libtomcrypt)
|
||||
end
|
||||
|
||||
function ObjWriting:use()
|
||||
@ -55,5 +56,6 @@ function ObjWriting:project()
|
||||
minilzo:include(includes)
|
||||
minizip:include(includes)
|
||||
json:include(includes)
|
||||
libtomcrypt:include(includes)
|
||||
|
||||
end
|
||||
|
86
src/ObjWriting/XModel/Gltf/GltfBinOutput.cpp
Normal file
86
src/ObjWriting/XModel/Gltf/GltfBinOutput.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
#include "GltfBinOutput.h"
|
||||
|
||||
#include "Utils/Alignment.h"
|
||||
#include "XModel/Gltf/GltfConstants.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using namespace gltf;
|
||||
|
||||
BinOutput::BinOutput(std::ostream& stream)
|
||||
: m_stream(stream)
|
||||
{
|
||||
}
|
||||
|
||||
void BinOutput::Write(const void* data, const size_t dataSize) const
|
||||
{
|
||||
m_stream.write(static_cast<const char*>(data), dataSize);
|
||||
}
|
||||
|
||||
void BinOutput::AlignToFour(const char value) const
|
||||
{
|
||||
const auto offset = m_stream.tellp();
|
||||
if (offset % 4 > 0)
|
||||
{
|
||||
const uint32_t alignmentValue = FileUtils::MakeMagic32(value, value, value, value);
|
||||
Write(&alignmentValue, 4u - (offset % 4u));
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<std::string> BinOutput::CreateBufferUri(const void* buffer, size_t bufferSize) const
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void BinOutput::EmitJson(const nlohmann::json& json) const
|
||||
{
|
||||
static constexpr uint32_t ZERO = 0u;
|
||||
|
||||
Write(&GLTF_MAGIC, sizeof(GLTF_MAGIC));
|
||||
Write(&GLTF_VERSION, sizeof(GLTF_VERSION));
|
||||
|
||||
// File length will be filled later
|
||||
Write(&ZERO, sizeof(ZERO));
|
||||
|
||||
// Chunk length will be filled after writing json
|
||||
Write(&ZERO, sizeof(ZERO));
|
||||
Write(&CHUNK_MAGIC_JSON, sizeof(CHUNK_MAGIC_JSON));
|
||||
|
||||
m_stream << json;
|
||||
|
||||
AlignToFour(' ');
|
||||
|
||||
const auto offsetAfterData = m_stream.tellp();
|
||||
const auto jsonDataLength = static_cast<uint32_t>(static_cast<unsigned>(offsetAfterData) - GLTF_JSON_CHUNK_DATA_OFFSET);
|
||||
|
||||
// Fill chunk length now
|
||||
m_stream.seekp(GLTF_JSON_CHUNK_LENGTH_OFFSET, std::ios::beg);
|
||||
Write(&jsonDataLength, sizeof(jsonDataLength));
|
||||
|
||||
// Return to previous pos
|
||||
m_stream.seekp(offsetAfterData, std::ios::beg);
|
||||
}
|
||||
|
||||
void BinOutput::EmitBuffer(const void* buffer, const size_t bufferSize) const
|
||||
{
|
||||
const auto chunkLength = utils::Align<uint32_t>(bufferSize, 4u);
|
||||
Write(&chunkLength, sizeof(chunkLength));
|
||||
Write(&CHUNK_MAGIC_BIN, sizeof(CHUNK_MAGIC_BIN));
|
||||
|
||||
Write(buffer, bufferSize);
|
||||
AlignToFour('\0');
|
||||
}
|
||||
|
||||
void BinOutput::Finalize() const
|
||||
{
|
||||
const auto fileEndOffset = m_stream.tellp();
|
||||
const auto fileSize = static_cast<uint32_t>(fileEndOffset);
|
||||
|
||||
// Fill chunk length now
|
||||
m_stream.seekp(GLTF_LENGTH_OFFSET, std::ios::beg);
|
||||
Write(&fileSize, sizeof(fileSize));
|
||||
|
||||
// Return to file end
|
||||
m_stream.seekp(fileEndOffset, std::ios::beg);
|
||||
}
|
25
src/ObjWriting/XModel/Gltf/GltfBinOutput.h
Normal file
25
src/ObjWriting/XModel/Gltf/GltfBinOutput.h
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "GltfOutput.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace gltf
|
||||
{
|
||||
class BinOutput final : public Output
|
||||
{
|
||||
public:
|
||||
explicit BinOutput(std::ostream& stream);
|
||||
|
||||
std::optional<std::string> CreateBufferUri(const void* buffer, size_t bufferSize) const override;
|
||||
void EmitJson(const nlohmann::json& json) const override;
|
||||
void EmitBuffer(const void* buffer, size_t bufferSize) const override;
|
||||
void Finalize() const override;
|
||||
|
||||
private:
|
||||
void Write(const void* data, size_t dataSize) const;
|
||||
void AlignToFour(char value) const;
|
||||
|
||||
std::ostream& m_stream;
|
||||
};
|
||||
} // namespace gltf
|
25
src/ObjWriting/XModel/Gltf/GltfOutput.h
Normal file
25
src/ObjWriting/XModel/Gltf/GltfOutput.h
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace gltf
|
||||
{
|
||||
class Output
|
||||
{
|
||||
protected:
|
||||
Output() = default;
|
||||
virtual ~Output() = default;
|
||||
Output(const Output& other) = default;
|
||||
Output(Output&& other) noexcept = default;
|
||||
Output& operator=(const Output& other) = default;
|
||||
Output& operator=(Output&& other) noexcept = default;
|
||||
|
||||
public:
|
||||
virtual std::optional<std::string> CreateBufferUri(const void* buffer, size_t bufferSize) const = 0;
|
||||
virtual void EmitJson(const nlohmann::json& json) const = 0;
|
||||
virtual void EmitBuffer(const void* buffer, size_t bufferSize) const = 0;
|
||||
virtual void Finalize() const = 0;
|
||||
};
|
||||
} // namespace gltf
|
48
src/ObjWriting/XModel/Gltf/GltfTextOutput.cpp
Normal file
48
src/ObjWriting/XModel/Gltf/GltfTextOutput.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
#include "GltfTextOutput.h"
|
||||
|
||||
#include "Utils/Alignment.h"
|
||||
#include "XModel/Gltf/GltfConstants.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <tomcrypt.h>
|
||||
|
||||
using namespace gltf;
|
||||
|
||||
TextOutput::TextOutput(std::ostream& stream)
|
||||
: m_stream(stream)
|
||||
{
|
||||
}
|
||||
|
||||
std::optional<std::string> TextOutput::CreateBufferUri(const void* buffer, const size_t bufferSize) const
|
||||
{
|
||||
static constexpr auto URI_PREFIX_LENGTH = std::char_traits<char>::length(GLTF_DATA_URI_PREFIX);
|
||||
const auto base64Length = utils::Align(4u * (bufferSize / 3u), 4u);
|
||||
const auto base64BufferSize = URI_PREFIX_LENGTH + base64Length;
|
||||
|
||||
std::string output(base64BufferSize, '\0');
|
||||
|
||||
std::memcpy(output.data(), &GLTF_DATA_URI_PREFIX, URI_PREFIX_LENGTH);
|
||||
|
||||
unsigned long outLength = base64Length;
|
||||
base64_encode(static_cast<const unsigned char*>(buffer), bufferSize, &output[URI_PREFIX_LENGTH], &outLength);
|
||||
|
||||
assert(outLength == base64Length);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
void TextOutput::EmitJson(const nlohmann::json& json) const
|
||||
{
|
||||
m_stream << std::setw(4) << json;
|
||||
}
|
||||
|
||||
void TextOutput::EmitBuffer(const void* buffer, const size_t bufferSize) const
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
void TextOutput::Finalize() const
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
22
src/ObjWriting/XModel/Gltf/GltfTextOutput.h
Normal file
22
src/ObjWriting/XModel/Gltf/GltfTextOutput.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "GltfOutput.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace gltf
|
||||
{
|
||||
class TextOutput final : public Output
|
||||
{
|
||||
public:
|
||||
explicit TextOutput(std::ostream& stream);
|
||||
|
||||
std::optional<std::string> CreateBufferUri(const void* buffer, size_t bufferSize) const override;
|
||||
void EmitJson(const nlohmann::json& json) const override;
|
||||
void EmitBuffer(const void* buffer, size_t bufferSize) const override;
|
||||
void Finalize() const override;
|
||||
|
||||
private:
|
||||
std::ostream& m_stream;
|
||||
};
|
||||
} // namespace gltf
|
Loading…
x
Reference in New Issue
Block a user