initial commit-moved from vulkan_guide
This commit is contained in:
218
third_party/fastgltf/tests/accessor_tests.cpp
vendored
Normal file
218
third_party/fastgltf/tests/accessor_tests.cpp
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/gtc/epsilon.hpp>
|
||||
#include <glm/ext/scalar_constants.hpp>
|
||||
|
||||
#include <fastgltf/parser.hpp>
|
||||
#include <fastgltf/tools.hpp>
|
||||
#include "gltf_path.hpp"
|
||||
|
||||
template<>
|
||||
struct fastgltf::ElementTraits<glm::vec3> : fastgltf::ElementTraitsBase<glm::vec3, AccessorType::Vec3, float> {};
|
||||
|
||||
static const std::byte* getBufferData(const fastgltf::Buffer& buffer) {
|
||||
const std::byte* result = nullptr;
|
||||
|
||||
std::visit(fastgltf::visitor {
|
||||
[](auto&) {},
|
||||
[&](const fastgltf::sources::Vector& vec) {
|
||||
result = reinterpret_cast<const std::byte*>(vec.bytes.data());
|
||||
},
|
||||
[&](const fastgltf::sources::ByteView& bv) {
|
||||
result = bv.bytes.data();
|
||||
},
|
||||
}, buffer.data);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TEST_CASE("Test data type conversion", "[gltf-tools]") {
|
||||
// normalized int-to-float and normalized float-to-int
|
||||
for (auto i = std::numeric_limits<std::int8_t>::min(); i < std::numeric_limits<std::int8_t>::max(); ++i) {
|
||||
auto converted = fastgltf::internal::convertComponent<float>(i, true);
|
||||
REQUIRE(glm::epsilonEqual<float>(converted, fastgltf::max<float>(i / 127.0f, -1), glm::epsilon<float>()));
|
||||
REQUIRE(fastgltf::internal::convertComponent<std::int8_t>(converted, true) == std::round(converted * 127.0f));
|
||||
}
|
||||
for (auto i = std::numeric_limits<std::uint8_t>::min(); i < std::numeric_limits<std::uint8_t>::max(); ++i) {
|
||||
auto converted = fastgltf::internal::convertComponent<float>(i, true);
|
||||
REQUIRE(glm::epsilonEqual<float>(converted, i / 255.0f, glm::epsilon<float>()));
|
||||
REQUIRE(fastgltf::internal::convertComponent<std::uint8_t>(converted, true) == std::round(converted * 255.0f));
|
||||
}
|
||||
for (auto i = std::numeric_limits<std::int16_t>::min(); i < std::numeric_limits<std::int16_t>::max(); ++i) {
|
||||
auto converted = fastgltf::internal::convertComponent<float>(i, true);
|
||||
REQUIRE(glm::epsilonEqual<float>(converted, fastgltf::max<float>(i / 32767.0f, -1), glm::epsilon<float>()));
|
||||
REQUIRE(fastgltf::internal::convertComponent<std::int16_t>(converted, true) == std::round(converted * 32767.0f));
|
||||
}
|
||||
for (auto i = std::numeric_limits<std::uint16_t>::min(); i < std::numeric_limits<std::uint16_t>::max(); ++i) {
|
||||
auto converted = fastgltf::internal::convertComponent<float>(i, true);
|
||||
REQUIRE(glm::epsilonEqual<float>(converted, i / 65535.0f, glm::epsilon<float>()));
|
||||
REQUIRE(fastgltf::internal::convertComponent<std::uint16_t>(converted, true) == std::round(converted * 65535.0f));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Test accessor", "[gltf-tools]") {
|
||||
auto lightsLamp = sampleModels / "2.0" / "LightsPunctualLamp" / "glTF";
|
||||
fastgltf::GltfDataBuffer jsonData;
|
||||
REQUIRE(jsonData.loadFromFile(lightsLamp / "LightsPunctualLamp.gltf"));
|
||||
|
||||
fastgltf::Parser parser(fastgltf::Extensions::KHR_lights_punctual);
|
||||
auto asset = parser.loadGLTF(&jsonData, lightsLamp, fastgltf::Options::LoadExternalBuffers,
|
||||
fastgltf::Category::Buffers | fastgltf::Category::BufferViews | fastgltf::Category::Accessors);
|
||||
REQUIRE(asset.error() == fastgltf::Error::None);
|
||||
|
||||
REQUIRE(asset->accessors.size() == 15);
|
||||
auto& accessors = asset->accessors;
|
||||
|
||||
SECTION("getAccessorElement<std::uint16_t>") {
|
||||
auto& firstAccessor = accessors[0];
|
||||
REQUIRE(firstAccessor.type == fastgltf::AccessorType::Scalar);
|
||||
REQUIRE(firstAccessor.componentType == fastgltf::ComponentType::UnsignedShort);
|
||||
|
||||
REQUIRE(firstAccessor.bufferViewIndex.has_value());
|
||||
auto& view = asset->bufferViews[*firstAccessor.bufferViewIndex];
|
||||
|
||||
auto* bufferData = getBufferData(asset->buffers[view.bufferIndex]);
|
||||
REQUIRE(bufferData != nullptr);
|
||||
|
||||
auto* checkData = reinterpret_cast<const std::uint16_t*>(bufferData + view.byteOffset
|
||||
+ firstAccessor.byteOffset);
|
||||
|
||||
REQUIRE(*checkData == fastgltf::getAccessorElement<std::uint16_t>(asset.get(), firstAccessor, 0));
|
||||
}
|
||||
|
||||
{
|
||||
auto& secondAccessor = accessors[1];
|
||||
REQUIRE(secondAccessor.type == fastgltf::AccessorType::Vec3);
|
||||
REQUIRE(secondAccessor.componentType == fastgltf::ComponentType::Float);
|
||||
|
||||
REQUIRE(secondAccessor.bufferViewIndex.has_value());
|
||||
auto& view = asset->bufferViews[*secondAccessor.bufferViewIndex];
|
||||
|
||||
auto* bufferData = getBufferData(asset->buffers[view.bufferIndex]);
|
||||
REQUIRE(bufferData != nullptr);
|
||||
|
||||
auto* checkData = reinterpret_cast<const glm::vec3*>(bufferData + view.byteOffset
|
||||
+ secondAccessor.byteOffset);
|
||||
|
||||
SECTION("getAccessorElement<glm::vec3>") {
|
||||
REQUIRE(*checkData == fastgltf::getAccessorElement<glm::vec3>(asset.get(), secondAccessor, 0));
|
||||
}
|
||||
|
||||
SECTION("iterateAccessor") {
|
||||
auto dstCopy = std::make_unique<glm::vec3[]>(secondAccessor.count);
|
||||
std::size_t i = 0;
|
||||
|
||||
fastgltf::iterateAccessor<glm::vec3>(asset.get(), secondAccessor, [&](auto&& v3) {
|
||||
dstCopy[i++] = std::forward<glm::vec3>(v3);
|
||||
});
|
||||
|
||||
REQUIRE(std::memcmp(dstCopy.get(), checkData, secondAccessor.count * sizeof(glm::vec3)) == 0);
|
||||
}
|
||||
|
||||
SECTION("copyFromAccessor") {
|
||||
auto dstCopy = std::make_unique<glm::vec3[]>(secondAccessor.count);
|
||||
fastgltf::copyFromAccessor<glm::vec3>(asset.get(), secondAccessor, dstCopy.get());
|
||||
REQUIRE(std::memcmp(dstCopy.get(), checkData, secondAccessor.count * sizeof(glm::vec3)) == 0);
|
||||
}
|
||||
|
||||
SECTION("Iterator test") {
|
||||
auto dstCopy = std::make_unique<glm::vec3[]>(secondAccessor.count);
|
||||
auto accessor = fastgltf::iterateAccessor<glm::vec3>(asset.get(), secondAccessor);
|
||||
for (auto it = accessor.begin(); it != accessor.end(); ++it) {
|
||||
dstCopy[std::distance(accessor.begin(), it)] = *it;
|
||||
}
|
||||
REQUIRE(std::memcmp(dstCopy.get(), checkData, secondAccessor.count * sizeof(glm::vec3)) == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Test sparse accessor", "[gltf-tools]") {
|
||||
auto simpleSparseAccessor = sampleModels / "2.0" / "SimpleSparseAccessor" / "glTF";
|
||||
auto jsonData = std::make_unique<fastgltf::GltfDataBuffer>();
|
||||
REQUIRE(jsonData->loadFromFile(simpleSparseAccessor / "SimpleSparseAccessor.gltf"));
|
||||
|
||||
fastgltf::Parser parser;
|
||||
auto asset = parser.loadGLTF(jsonData.get(), simpleSparseAccessor, fastgltf::Options::LoadExternalBuffers,
|
||||
fastgltf::Category::Buffers | fastgltf::Category::BufferViews | fastgltf::Category::Accessors);
|
||||
REQUIRE(asset.error() == fastgltf::Error::None);
|
||||
|
||||
REQUIRE(asset->accessors.size() == 2);
|
||||
REQUIRE(!asset->accessors[0].sparse.has_value());
|
||||
REQUIRE(asset->accessors[1].sparse.has_value());
|
||||
auto& sparse = asset->accessors[1].sparse.value();
|
||||
REQUIRE(sparse.count == 3);
|
||||
REQUIRE(sparse.indicesBufferView == 2);
|
||||
REQUIRE(sparse.indicesByteOffset == 0);
|
||||
REQUIRE(sparse.valuesBufferView == 3);
|
||||
REQUIRE(sparse.valuesByteOffset == 0);
|
||||
REQUIRE(sparse.indexComponentType == fastgltf::ComponentType::UnsignedShort);
|
||||
|
||||
auto& secondAccessor = asset->accessors[1];
|
||||
auto& viewIndices = asset->bufferViews[secondAccessor.sparse->indicesBufferView];
|
||||
auto& viewValues = asset->bufferViews[secondAccessor.sparse->valuesBufferView];
|
||||
|
||||
auto& viewData = asset->bufferViews[*secondAccessor.bufferViewIndex];
|
||||
auto* bufferData = getBufferData(asset->buffers[viewData.bufferIndex]) + viewData.byteOffset
|
||||
+ secondAccessor.byteOffset;
|
||||
auto dataStride = viewData.byteStride ? *viewData.byteStride
|
||||
: fastgltf::getElementByteSize(secondAccessor.type, secondAccessor.componentType);
|
||||
|
||||
auto* dataIndices = reinterpret_cast<const std::uint16_t*>(getBufferData(asset->buffers[viewIndices.bufferIndex])
|
||||
+ viewIndices.byteOffset + secondAccessor.sparse->indicesByteOffset);
|
||||
auto* dataValues = reinterpret_cast<const glm::vec3*>(getBufferData(asset->buffers[viewValues.bufferIndex])
|
||||
+ viewValues.byteOffset + secondAccessor.sparse->valuesByteOffset);
|
||||
|
||||
auto checkValues = std::make_unique<glm::vec3[]>(secondAccessor.count);
|
||||
|
||||
for (std::size_t i = 0, sparseIndex = 0; i < secondAccessor.count; ++i) {
|
||||
if (sparseIndex < secondAccessor.sparse->count && dataIndices[sparseIndex] == i) {
|
||||
checkValues[i] = dataValues[sparseIndex];
|
||||
++sparseIndex;
|
||||
} else {
|
||||
checkValues[i] = *reinterpret_cast<const glm::vec3*>(bufferData + dataStride * i);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("getAccessorElement") {
|
||||
for (std::size_t i = 0; i < secondAccessor.count; ++i) {
|
||||
REQUIRE(checkValues[i] == fastgltf::getAccessorElement<glm::vec3>(asset.get(), secondAccessor, i));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("iterateAccessor") {
|
||||
auto dstCopy = std::make_unique<glm::vec3[]>(secondAccessor.count);
|
||||
std::size_t i = 0;
|
||||
|
||||
fastgltf::iterateAccessor<glm::vec3>(asset.get(), secondAccessor, [&](auto&& v3) {
|
||||
dstCopy[i++] = std::forward<glm::vec3>(v3);
|
||||
});
|
||||
|
||||
REQUIRE(std::memcmp(dstCopy.get(), checkValues.get(), secondAccessor.count * sizeof(glm::vec3)) == 0);
|
||||
}
|
||||
|
||||
SECTION("iterateAccessor with idx") {
|
||||
auto dstCopy = std::make_unique<glm::vec3[]>(secondAccessor.count);
|
||||
|
||||
fastgltf::iterateAccessorWithIndex<glm::vec3>(asset.get(), secondAccessor, [&](auto&& v3, std::size_t i) {
|
||||
dstCopy[i] = std::forward<glm::vec3>(v3);
|
||||
});
|
||||
|
||||
REQUIRE(std::memcmp(dstCopy.get(), checkValues.get(), secondAccessor.count * sizeof(glm::vec3)) == 0);
|
||||
}
|
||||
|
||||
SECTION("copyFromAccessor") {
|
||||
auto dstCopy = std::make_unique<glm::vec3[]>(secondAccessor.count);
|
||||
fastgltf::copyFromAccessor<glm::vec3>(asset.get(), secondAccessor, dstCopy.get());
|
||||
REQUIRE(std::memcmp(dstCopy.get(), checkValues.get(), secondAccessor.count * sizeof(glm::vec3)) == 0);
|
||||
}
|
||||
|
||||
SECTION("Iterator test") {
|
||||
auto dstCopy = std::make_unique<glm::vec3[]>(secondAccessor.count);
|
||||
auto accessor = fastgltf::iterateAccessor<glm::vec3>(asset.get(), secondAccessor);
|
||||
for (auto it = accessor.begin(); it != accessor.end(); ++it) {
|
||||
dstCopy[std::distance(accessor.begin(), it)] = *it;
|
||||
}
|
||||
REQUIRE(std::memcmp(dstCopy.get(), checkValues.get(), secondAccessor.count * sizeof(glm::vec3)) == 0);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user