diff options
author | Dave Parks <davep@lindenlab.com> | 2024-05-28 09:45:40 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-28 09:45:40 -0500 |
commit | 2f4120038429c6aff865f153f708ceefb60d67f4 (patch) | |
tree | 85e63488eb66760996fd2e0c55c40fdc7b5b38b3 /indra/newview/gltf/accessor.cpp | |
parent | db627bc3544b828982a2a366972e0adf86e42f75 (diff) |
Remove tinygltf dependency from LL::GLTF (#1541)
* #1535 Image loading/saving support in boost::json driven GLTF parser
* #1536 GLB Support in boost::json drvien GLTF parser
Diffstat (limited to 'indra/newview/gltf/accessor.cpp')
-rw-r--r-- | indra/newview/gltf/accessor.cpp | 158 |
1 files changed, 95 insertions, 63 deletions
diff --git a/indra/newview/gltf/accessor.cpp b/indra/newview/gltf/accessor.cpp index 369ff4f240..0619c617e2 100644 --- a/indra/newview/gltf/accessor.cpp +++ b/indra/newview/gltf/accessor.cpp @@ -28,6 +28,7 @@ #include "asset.h" #include "buffer_util.h" +#include "llfilesystem.h" using namespace LL::GLTF; using namespace boost::json; @@ -107,6 +108,8 @@ void Buffer::erase(Asset& asset, S32 offset, S32 length) mData.erase(mData.begin() + offset, mData.begin() + offset + length); + mByteLength = mData.size(); + for (BufferView& view : asset.mBufferViews) { if (view.mBuffer == idx) @@ -119,6 +122,95 @@ void Buffer::erase(Asset& asset, S32 offset, S32 length) } } +bool Buffer::prep(Asset& asset) +{ + // PRECONDITION: mByteLength must not be 0 + llassert(mByteLength != 0); + + LLUUID id; + if (mUri.size() == UUID_STR_SIZE && LLUUID::parseUUID(mUri, &id) && id.notNull()) + { // loaded from an asset, fetch the buffer data from the asset store + LLFileSystem file(id, LLAssetType::AT_GLTF_BIN, LLFileSystem::READ); + + mData.resize(file.getSize()); + if (!file.read((U8*)mData.data(), mData.size())) + { + LL_WARNS("GLTF") << "Failed to load buffer data from asset: " << id << LL_ENDL; + return false; + } + } + else if (mUri.find("data:") == 0) + { // loaded from a data URI, load the texture from the data + LL_WARNS() << "Data URIs not yet supported" << LL_ENDL; + return false; + } + else if (!asset.mFilename.empty() && + !mUri.empty()) // <-- uri could be empty if we're loading from .glb + { + std::string dir = gDirUtilp->getDirName(asset.mFilename); + std::string bin_file = dir + gDirUtilp->getDirDelimiter() + mUri; + + std::ifstream file(bin_file, std::ios::binary); + if (!file.is_open()) + { + LL_WARNS("GLTF") << "Failed to open file: " << bin_file << LL_ENDL; + return false; + } + + file.seekg(0, std::ios::end); + if (mByteLength > file.tellg()) + { + LL_WARNS("GLTF") << "Unexpected file size: " << bin_file << " is " << file.tellg() << " bytes, expected " << mByteLength << LL_ENDL; + return false; + } + file.seekg(0, std::ios::beg); + + mData.resize(mByteLength); + file.read((char*)mData.data(), mData.size()); + } + + // POSTCONDITION: on success, mData.size == mByteLength + llassert(mData.size() == mByteLength); + return true; +} + +bool Buffer::save(Asset& asset, const std::string& folder) +{ + if (mUri.substr(0, 5) == "data:") + { + LL_WARNS("GLTF") << "Data URIs not yet supported" << LL_ENDL; + return false; + } + + std::string bin_file = folder + gDirUtilp->getDirDelimiter(); + + if (mUri.empty()) + { + if (mName.empty()) + { + S32 idx = this - &asset.mBuffers[0]; + mUri = llformat("buffer_%d.bin", idx); + } + else + { + mUri = mName + ".bin"; + } + } + + bin_file += mUri; + + std::ofstream file(bin_file, std::ios::binary); + if (!file.is_open()) + { + LL_WARNS("GLTF") << "Failed to open file: " << bin_file << LL_ENDL; + return false; + } + + file.write((char*)mData.data(), mData.size()); + + return true; +} + void Buffer::serialize(object& dst) const { write(mName, "name", dst); @@ -132,23 +224,15 @@ const Buffer& Buffer::operator=(const Value& src) { copy(src, "name", mName); copy(src, "uri", mUri); - - // NOTE: DO NOT attempt to handle the uri here. + copy(src, "byteLength", mByteLength); + + // NOTE: DO NOT attempt to handle the uri here. // The uri is a reference to a file that is not loaded until // after the json document is parsed } return *this; } -const Buffer& Buffer::operator=(const tinygltf::Buffer& src) -{ - mData = src.data; - mName = src.name; - mUri = src.uri; - return *this; -} - - void BufferView::serialize(object& dst) const { write_always(mBuffer, "buffer", dst); @@ -173,43 +257,6 @@ const BufferView& BufferView::operator=(const Value& src) return *this; } -const BufferView& BufferView::operator=(const tinygltf::BufferView& src) -{ - mBuffer = src.buffer; - mByteLength = src.byteLength; - mByteOffset = src.byteOffset; - mByteStride = src.byteStride; - mTarget = src.target; - mName = src.name; - return *this; -} - -Accessor::Type tinygltf_type_to_enum(S32 type) -{ - switch (type) - { - case TINYGLTF_TYPE_SCALAR: - return Accessor::Type::SCALAR; - case TINYGLTF_TYPE_VEC2: - return Accessor::Type::VEC2; - case TINYGLTF_TYPE_VEC3: - return Accessor::Type::VEC3; - case TINYGLTF_TYPE_VEC4: - return Accessor::Type::VEC4; - case TINYGLTF_TYPE_MAT2: - return Accessor::Type::MAT2; - case TINYGLTF_TYPE_MAT3: - return Accessor::Type::MAT3; - case TINYGLTF_TYPE_MAT4: - return Accessor::Type::MAT4; - } - - LL_WARNS("GLTF") << "Unknown tinygltf accessor type: " << type << LL_ENDL; - llassert(false); - - return Accessor::Type::SCALAR; -} - void Accessor::serialize(object& dst) const { write(mName, "name", dst); @@ -240,18 +287,3 @@ const Accessor& Accessor::operator=(const Value& src) return *this; } -const Accessor& Accessor::operator=(const tinygltf::Accessor& src) -{ - mBufferView = src.bufferView; - mByteOffset = src.byteOffset; - mComponentType = src.componentType; - mCount = src.count; - mType = tinygltf_type_to_enum(src.type); - mNormalized = src.normalized; - mName = src.name; - mMax = src.maxValues; - mMin = src.minValues; - - return *this; -} - |