Test for texture coordinates on cube

This commit is contained in:
Josiah VanderZee 2022-11-12 07:01:56 -06:00
parent 742307f077
commit 72cb09a566
2 changed files with 72 additions and 14 deletions

View File

@ -18,6 +18,13 @@
#include <memory>
#include <string>
template <class T>
struct Span
{
T* buffer = nullptr;
std::size_t size = 0;
};
class BufferOffset
{
public:
@ -63,7 +70,8 @@ static bool tryParseGLTF(io::IReadFile* file, tinygltf::Model& model)
}
template <class T>
static T readPrimitive(const BufferOffset& readFrom) {
static T readPrimitive(const BufferOffset& readFrom)
{
unsigned char d[sizeof(T)]{};
for (std::size_t i = 0; i < sizeof(T); ++i) {
d[i] = readFrom.at(i);
@ -71,7 +79,16 @@ static T readPrimitive(const BufferOffset& readFrom) {
return *reinterpret_cast<T*>(d);
}
static core::vector3df readVector(const BufferOffset& readFrom, const float scale) {
static core::vector2df readVec2DF(const BufferOffset& readFrom)
{
return core::vector2df(
readPrimitive<float>(readFrom),
readPrimitive<float>(BufferOffset(readFrom, sizeof(float))));
}
static core::vector3df readVec3DF(const BufferOffset& readFrom, const float scale)
{
// glTF coordinates are right-handed, minetest ones are left-handed
// 1 glTF coordinate is equivalent to 10 Irrlicht coordinates
return core::vector3df(
@ -98,24 +115,55 @@ float getScale(const tinygltf::Model& model)
return 1.0f;
}
video::S3DVertex* getVertices(const tinygltf::Model& model, const std::size_t accessorId)
static void copyPositions(const tinygltf::Model& model,
const Span<video::S3DVertex> vertices,
const std::size_t accessorId)
{
const auto& view = model.bufferViews[
model.accessors[accessorId].bufferView];
const auto& buffer = model.buffers[view.buffer];
auto* vertices = new video::S3DVertex[model.accessors[accessorId].count];
for (std::size_t i = 0; i < model.accessors[accessorId].count; ++i) {
const auto v = readVector(BufferOffset(
buffer.data, view.byteOffset + 3 * sizeof(float) * i), getScale(model));
vertices[i] = {v, {0.0f, 0.0f, 0.0f}, {}, {0.0f, 0.0f}};
const auto v = readVec3DF(BufferOffset(
buffer.data, view.byteOffset + 3 * sizeof(float) * i),
getScale(model));
vertices.buffer[i].Pos = v;
}
return vertices;
}
u16* getIndices(const tinygltf::Model& model, const std::size_t accessorId)
static void copyTCoords(const tinygltf::Model& model,
const Span<video::S3DVertex> vertices,
const std::size_t accessorId)
{
const auto& view = model.bufferViews[
model.accessors[accessorId].bufferView];
const auto& buffer = model.buffers[view.buffer];
for (std::size_t i = 0; i < model.accessors[accessorId].count; ++i) {
const auto t = readVec2DF(BufferOffset(
buffer.data, view.byteOffset + 2 * sizeof(float) * i));
vertices.buffer[i].TCoords = t;
}
}
static video::S3DVertex* getVertices(const tinygltf::Model& model,
const std::size_t accessorId)
{
auto* vertexBuffer = new video::S3DVertex[
model.accessors[accessorId].count]{};
Span<video::S3DVertex> vertices{
vertexBuffer, model.accessors[accessorId].count};
copyPositions(model, vertices, accessorId);
const auto tCoordsField
= model.meshes[0].primitives[0].attributes.find("TEXCOORD_0");
if (tCoordsField != model.meshes[0].primitives[0].attributes.end()) {
copyTCoords(model, vertices, tCoordsField->second);
}
return vertexBuffer;
}
static u16* getIndices(const tinygltf::Model& model,
const std::size_t accessorId)
{
const auto& view = model.bufferViews[
model.accessors[accessorId].bufferView];

View File

@ -84,8 +84,7 @@ TEST_CASE("blender cube") {
CHECK(vertices[21].Pos == irr::core::vector3df{-10.0f, 10.0f, -10.0f});
}
SECTION("vertex indices are correct")
{
SECTION("vertex indices are correct") {
REQUIRE(sm.getMesh()->getMeshBuffer(0)->getIndexCount() == 36);
const auto* indices = reinterpret_cast<irr::u16*>(
sm.getMesh()->getMeshBuffer(0)->getIndices());
@ -93,6 +92,17 @@ TEST_CASE("blender cube") {
CHECK(indices[1] == 3);
CHECK(indices[2] == 9);
}
SECTION("texture coords are correct") {
REQUIRE(sm.getMesh()->getMeshBuffer(0)->getVertexCount() == 24);
const auto* vertices = reinterpret_cast<irr::video::S3DVertex*>(
sm.getMesh()->getMeshBuffer(0)->getVertices());
CHECK(vertices[0].TCoords == irr::core::vector2df{0.375f, 1.0f});
CHECK(vertices[1].TCoords == irr::core::vector2df{0.125f, 0.25f});
CHECK(vertices[2].TCoords == irr::core::vector2df{0.375f, 0.0f});
CHECK(vertices[3].TCoords == irr::core::vector2df{0.6250f, 1.0f});
CHECK(vertices[6].TCoords == irr::core::vector2df{0.375f, 0.75f});
}
}
TEST_CASE("mesh loader returns nullptr when given null file pointer") {