phoenix-firestorm/indra/newview/gltf/accessor.cpp

258 lines
6.8 KiB
C++

/**
* @file accessor.cpp
* @brief LL GLTF Implementation
*
* $LicenseInfo:firstyear=2024&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2024, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "../llviewerprecompiledheaders.h"
#include "asset.h"
#include "buffer_util.h"
using namespace LL::GLTF;
using namespace boost::json;
namespace LL
{
namespace GLTF
{
Accessor::Type gltf_type_to_enum(const std::string& type)
{
if (type == "SCALAR")
{
return Accessor::Type::SCALAR;
}
else if (type == "VEC2")
{
return Accessor::Type::VEC2;
}
else if (type == "VEC3")
{
return Accessor::Type::VEC3;
}
else if (type == "VEC4")
{
return Accessor::Type::VEC4;
}
else if (type == "MAT2")
{
return Accessor::Type::MAT2;
}
else if (type == "MAT3")
{
return Accessor::Type::MAT3;
}
else if (type == "MAT4")
{
return Accessor::Type::MAT4;
}
LL_WARNS("GLTF") << "Unknown accessor type: " << type << LL_ENDL;
llassert(false);
return Accessor::Type::SCALAR;
}
std::string enum_to_gltf_type(Accessor::Type type)
{
switch (type)
{
case Accessor::Type::SCALAR:
return "SCALAR";
case Accessor::Type::VEC2:
return "VEC2";
case Accessor::Type::VEC3:
return "VEC3";
case Accessor::Type::VEC4:
return "VEC4";
case Accessor::Type::MAT2:
return "MAT2";
case Accessor::Type::MAT3:
return "MAT3";
case Accessor::Type::MAT4:
return "MAT4";
}
LL_WARNS("GLTF") << "Unknown accessor type: " << (S32)type << LL_ENDL;
llassert(false);
return "SCALAR";
}
}
}
void Buffer::erase(Asset& asset, S32 offset, S32 length)
{
S32 idx = this - &asset.mBuffers[0];
mData.erase(mData.begin() + offset, mData.begin() + offset + length);
for (BufferView& view : asset.mBufferViews)
{
if (view.mBuffer == idx)
{
if (view.mByteOffset >= offset)
{
view.mByteOffset -= length;
}
}
}
}
void Buffer::serialize(object& dst) const
{
write(mName, "name", dst);
write(mUri, "uri", dst);
write_always(mByteLength, "byteLength", dst);
};
const Buffer& Buffer::operator=(const Value& src)
{
if (src.is_object())
{
copy(src, "name", mName);
copy(src, "uri", mUri);
// 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);
write_always(mByteLength, "byteLength", dst);
write(mByteOffset, "byteOffset", dst, 0);
write(mByteStride, "byteStride", dst, 0);
write(mTarget, "target", dst, -1);
write(mName, "name", dst);
}
const BufferView& BufferView::operator=(const Value& src)
{
if (src.is_object())
{
copy(src, "buffer", mBuffer);
copy(src, "byteLength", mByteLength);
copy(src, "byteOffset", mByteOffset);
copy(src, "byteStride", mByteStride);
copy(src, "target", mTarget);
copy(src, "name", mName);
}
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);
write(mBufferView, "bufferView", dst, INVALID_INDEX);
write(mByteOffset, "byteOffset", dst, 0);
write_always(mComponentType, "componentType", dst);
write_always(mCount, "count", dst);
write_always(enum_to_gltf_type(mType), "type", dst);
write(mNormalized, "normalized", dst, false);
write(mMax, "max", dst);
write(mMin, "min", dst);
}
const Accessor& Accessor::operator=(const Value& src)
{
if (src.is_object())
{
copy(src, "name", mName);
copy(src, "bufferView", mBufferView);
copy(src, "byteOffset", mByteOffset);
copy(src, "componentType", mComponentType);
copy(src, "count", mCount);
copy(src, "type", mType);
copy(src, "normalized", mNormalized);
copy(src, "max", mMax);
copy(src, "min", mMin);
}
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;
}