mirror of
https://github.com/minetest/irrlicht.git
synced 2024-11-16 23:40:25 +01:00
Merge pull request #3 from jordan4ibanez/feat/gltf-loader
Fix indices, inverted models, & multiple models failing to load
This commit is contained in:
commit
eb77d07f39
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -18,4 +18,4 @@ scripts/glext.h
|
|||
*.vcxproj*
|
||||
*.dir/
|
||||
*.sln
|
||||
*visualstudio/
|
||||
*visualstudio/
|
6
.vscode/settings.json
vendored
Normal file
6
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"files.associations": {
|
||||
"*.tcc": "cpp",
|
||||
"iomanip": "cpp"
|
||||
}
|
||||
}
|
|
@ -18,6 +18,8 @@
|
|||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
template <class T>
|
||||
struct Span
|
||||
|
@ -53,10 +55,11 @@ private:
|
|||
};
|
||||
|
||||
// A helper function to disable tinygltf embedded image loading
|
||||
bool turn_off_textures_hack(tinygltf::Image *a, const int b, std::string *c,
|
||||
std::string *d, int e, int f, const unsigned char * g,int h, void *user_pointer)
|
||||
bool dummyImageLoader(tinygltf::Image *a, const int b, std::string *c,
|
||||
std::string *d, int e, int f, const unsigned char * g,
|
||||
int h, void *user_pointer)
|
||||
{
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
namespace irr
|
||||
|
@ -69,9 +72,8 @@ static bool tryParseGLTF(io::IReadFile* file, tinygltf::Model& model)
|
|||
{
|
||||
tinygltf::TinyGLTF loader {};
|
||||
|
||||
// Stop embedded textures from making model fail to load
|
||||
void *the_void = 0;
|
||||
loader.SetImageLoader(turn_off_textures_hack, the_void);
|
||||
// Stop embedded textures from making model fail to load
|
||||
loader.SetImageLoader(dummyImageLoader, nullptr);
|
||||
|
||||
std::string err {};
|
||||
std::string warn {};
|
||||
|
@ -79,7 +81,12 @@ static bool tryParseGLTF(io::IReadFile* file, tinygltf::Model& model)
|
|||
auto buf = std::make_unique<char[]>(file->getSize());
|
||||
file->read(buf.get(), file->getSize());
|
||||
|
||||
return loader.LoadASCIIFromString(&model, &err, &warn, buf.get(), file->getSize(), "", 1);
|
||||
if (err != "" || warn != "") {
|
||||
return false;
|
||||
}
|
||||
|
||||
return loader.LoadASCIIFromString(&model, &err, &warn, buf.get(),
|
||||
file->getSize(), "", 1);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
@ -96,9 +103,8 @@ static T readPrimitive(const BufferOffset& readFrom)
|
|||
|
||||
static core::vector2df readVec2DF(const BufferOffset& readFrom)
|
||||
{
|
||||
return core::vector2df(
|
||||
readPrimitive<float>(readFrom),
|
||||
readPrimitive<float>(BufferOffset(readFrom, sizeof(float))));
|
||||
return core::vector2df(readPrimitive<float>(readFrom),
|
||||
readPrimitive<float>(BufferOffset( readFrom, sizeof(float))));
|
||||
|
||||
}
|
||||
|
||||
|
@ -110,19 +116,10 @@ static core::vector3df readVec3DF(const BufferOffset& readFrom,
|
|||
return core::vector3df(
|
||||
scale * readPrimitive<float>(readFrom),
|
||||
scale * readPrimitive<float>(BufferOffset(readFrom, sizeof(float))),
|
||||
-scale * readPrimitive<float>(BufferOffset(readFrom, 2 * sizeof(float))));
|
||||
-scale * readPrimitive<float>(BufferOffset(readFrom, 2 *
|
||||
sizeof(float))));
|
||||
}
|
||||
|
||||
static u16* readIndices(const BufferOffset& readFrom, const std::size_t count)
|
||||
{
|
||||
auto* indices = new u16[count]{};
|
||||
for (std::size_t i = 0; i < count; ++i) {
|
||||
indices[i] = readPrimitive<u16>(BufferOffset(readFrom, i * sizeof(u16)));
|
||||
}
|
||||
return indices;
|
||||
}
|
||||
|
||||
|
||||
float getScale(const tinygltf::Model& model)
|
||||
{
|
||||
if (model.nodes[0].scale.size() > 0) {
|
||||
|
@ -132,81 +129,93 @@ float getScale(const tinygltf::Model& model)
|
|||
}
|
||||
|
||||
static void copyPositions(const tinygltf::Model& model,
|
||||
const Span<video::S3DVertex> vertices,
|
||||
const std::size_t accessorId)
|
||||
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 count = model.accessors[accessorId].count;
|
||||
|
||||
float scale = getScale(model);
|
||||
|
||||
for (std::size_t i = 0; i < count; i++) {
|
||||
const auto v = readVec3DF(BufferOffset(
|
||||
buffer.data, view.byteOffset + 3 * sizeof(float) * i),
|
||||
getScale(model));
|
||||
buffer.data, view.byteOffset + (3 * sizeof(float) * i)),scale);
|
||||
vertices.buffer[i].Pos = v;
|
||||
}
|
||||
}
|
||||
|
||||
static void copyNormals(const tinygltf::Model& model,
|
||||
const Span<video::S3DVertex> vertices,
|
||||
const std::size_t accessorId)
|
||||
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 n = readVec3DF(BufferOffset(
|
||||
buffer.data, view.byteOffset + 3 * sizeof(float) * i));
|
||||
const auto count = model.accessors[accessorId].count;
|
||||
|
||||
for (std::size_t i = 0; i < count; i++) {
|
||||
const auto n = readVec3DF(BufferOffset( buffer.data,
|
||||
view.byteOffset + 3 * sizeof(float) * i ));
|
||||
vertices.buffer[i].Normal = n;
|
||||
}
|
||||
}
|
||||
|
||||
static void copyTCoords(const tinygltf::Model& model,
|
||||
const Span<video::S3DVertex> vertices,
|
||||
const std::size_t accessorId)
|
||||
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 count = model.accessors[accessorId].count;
|
||||
|
||||
for (std::size_t i = 0; i < 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 normalsField
|
||||
= model.meshes[0].primitives[0].attributes.find("NORMAL");
|
||||
if (normalsField != model.meshes[0].primitives[0].attributes.end()) {
|
||||
copyNormals(model, vertices, normalsField->second);
|
||||
}
|
||||
|
||||
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)
|
||||
static void getIndices(const tinygltf::Model& model,
|
||||
const std::size_t accessorId, std::vector<u16>& indicesBuffer)
|
||||
{
|
||||
const auto& view = model.bufferViews[
|
||||
model.accessors[accessorId].bufferView];
|
||||
const auto& indicesBuffer = model.buffers[view.buffer];
|
||||
return readIndices(
|
||||
BufferOffset(indicesBuffer.data, view.byteOffset),
|
||||
model.accessors[accessorId].count);
|
||||
const auto& modelIndices = model.buffers[view.buffer];
|
||||
|
||||
auto buffOffset = BufferOffset(modelIndices.data, view.byteOffset);
|
||||
auto count = model.accessors[accessorId].count;
|
||||
|
||||
for (std::size_t i = 0; i < count; i++) {
|
||||
indicesBuffer[i] = readPrimitive<u16>(BufferOffset(
|
||||
buffOffset, i * sizeof(u16)));
|
||||
}
|
||||
}
|
||||
|
||||
//Returns a tuple of the current counts (current_vertex_index,
|
||||
// current_normals_index, current_tcoords_index)
|
||||
static void getVertices
|
||||
( const tinygltf::Model& model, const std::size_t accessorId,
|
||||
Span<video::S3DVertex>& verticesBuffer,
|
||||
std::size_t mesh_index, std::size_t primitive_index )
|
||||
{
|
||||
copyPositions(model, verticesBuffer, accessorId);
|
||||
|
||||
const auto normalsField = model.meshes[mesh_index]
|
||||
.primitives[primitive_index].attributes.find("NORMAL");
|
||||
|
||||
if (normalsField != model.meshes[mesh_index]
|
||||
.primitives[primitive_index].attributes.end()) {
|
||||
copyNormals(model, verticesBuffer, normalsField->second);
|
||||
}
|
||||
|
||||
const auto tCoordsField = model.meshes[mesh_index]
|
||||
.primitives[primitive_index].attributes.find("TEXCOORD_0");
|
||||
|
||||
if (tCoordsField != model.meshes[mesh_index]
|
||||
.primitives[primitive_index].attributes.end()) {
|
||||
copyTCoords(model, verticesBuffer, tCoordsField->second);
|
||||
}
|
||||
}
|
||||
|
||||
CGLTFMeshFileLoader::CGLTFMeshFileLoader()
|
||||
|
@ -227,24 +236,55 @@ IAnimatedMesh* CGLTFMeshFileLoader::createMesh(io::IReadFile* file)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
const auto indicesAccessorId =
|
||||
model.meshes[0].primitives[0].indices;
|
||||
const auto positionAccessorId =
|
||||
model.meshes[0].primitives[0].attributes["POSITION"];
|
||||
|
||||
auto* indices = getIndices(model, indicesAccessorId);
|
||||
auto* vertices = getVertices(model, positionAccessorId);
|
||||
|
||||
SMeshBuffer* meshbuf { new SMeshBuffer {} };
|
||||
|
||||
meshbuf->append(vertices, model.accessors[positionAccessorId].count,
|
||||
indices, model.accessors[indicesAccessorId].count);
|
||||
|
||||
// Create the base mesh
|
||||
SMesh* mesh { new SMesh {} };
|
||||
mesh->addMeshBuffer(meshbuf);
|
||||
|
||||
// Iterate models
|
||||
for (std::size_t mesh_index = 0;
|
||||
mesh_index < model.meshes.size(); mesh_index++) {
|
||||
// Iterate primitives
|
||||
for (std::size_t primitive_index = 0; primitive_index < model
|
||||
.meshes[mesh_index].primitives.size(); primitive_index++) {
|
||||
|
||||
const auto positionAccessorId = model.meshes[mesh_index]
|
||||
.primitives[primitive_index].attributes["POSITION"];
|
||||
const auto indicesAccessorId = model.meshes[mesh_index]
|
||||
.primitives[primitive_index].indices;
|
||||
|
||||
// Creates counts for preallocation
|
||||
std::size_t vertices_count = model.accessors[positionAccessorId].count;
|
||||
|
||||
// We must count to create containers for the data
|
||||
// Create new buffer for vertices, positions, and normals
|
||||
auto* vertexBuffer = new video::S3DVertex[vertices_count]();
|
||||
// This is used to copy data into the vertexBuffer
|
||||
Span<video::S3DVertex> verticesBuffer{vertexBuffer,vertices_count};
|
||||
// Create dynamic indices buffer so it's easier to work with.
|
||||
// Preallocate needed resources to boost game startup speed
|
||||
std::vector<u16> indicesBuffer(model.accessors[
|
||||
indicesAccessorId].count);
|
||||
|
||||
getIndices(model, indicesAccessorId, indicesBuffer);
|
||||
getVertices(model, positionAccessorId, verticesBuffer,
|
||||
mesh_index, primitive_index);
|
||||
|
||||
// Inverse the order of indices due to the axis of the model being
|
||||
// inverted when going from left handed to right handed coordinates
|
||||
std::reverse(indicesBuffer.begin(),indicesBuffer.end());
|
||||
|
||||
// Create the mesh buffer
|
||||
SMeshBuffer* meshbuf { new SMeshBuffer {} };
|
||||
meshbuf->append(vertexBuffer, vertices_count, indicesBuffer.data(),
|
||||
indicesBuffer.size());
|
||||
|
||||
mesh->addMeshBuffer(meshbuf);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Create the mesh animations
|
||||
SAnimatedMesh* animatedMesh { new SAnimatedMesh {} };
|
||||
animatedMesh->addMesh(mesh);
|
||||
animatedMesh->addMesh(mesh);
|
||||
|
||||
return animatedMesh;
|
||||
}
|
||||
|
|
1
source/Irrlicht/tests/assets/snow_man.gltf
Normal file
1
source/Irrlicht/tests/assets/snow_man.gltf
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,9 @@
|
|||
#define CATCH_CONFIG_MAIN
|
||||
#include <catch.hpp>
|
||||
#include <irrlicht.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class ScopedMesh
|
||||
{
|
||||
|
@ -60,9 +63,9 @@ TEST_CASE("minimal triangle") {
|
|||
REQUIRE(sm.getMesh()->getMeshBuffer(0)->getIndexCount() == 3);
|
||||
const auto* indices = reinterpret_cast<irr::u16*>(
|
||||
sm.getMesh()->getMeshBuffer(0)->getIndices());
|
||||
CHECK(indices[0] == 0);
|
||||
CHECK(indices[0] == 2);
|
||||
CHECK(indices[1] == 1);
|
||||
CHECK(indices[2] == 2);
|
||||
CHECK(indices[2] == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,10 +91,10 @@ TEST_CASE("blender cube") {
|
|||
REQUIRE(sm.getMesh()->getMeshBuffer(0)->getIndexCount() == 36);
|
||||
const auto* indices = reinterpret_cast<irr::u16*>(
|
||||
sm.getMesh()->getMeshBuffer(0)->getIndices());
|
||||
CHECK(indices[0] == 0);
|
||||
CHECK(indices[1] == 3);
|
||||
CHECK(indices[2] == 9);
|
||||
CHECK(indices[35] == 16);
|
||||
CHECK(indices[0] == 16);
|
||||
CHECK(indices[1] == 5);
|
||||
CHECK(indices[2] == 22);
|
||||
CHECK(indices[35] == 0);
|
||||
}
|
||||
|
||||
SECTION("vertex normals are correct") {
|
||||
|
@ -129,3 +132,142 @@ TEST_CASE("invalid JSON returns nullptr") {
|
|||
CHECK(sm.getMesh() == nullptr);
|
||||
}
|
||||
|
||||
TEST_CASE("snow man") {
|
||||
ScopedMesh sm("source/Irrlicht/tests/assets/snow_man.gltf");
|
||||
REQUIRE(sm.getMesh() != nullptr);
|
||||
REQUIRE(sm.getMesh()->getMeshBufferCount() == 3);
|
||||
|
||||
SECTION("vertex coordinates are correct for all buffers") {
|
||||
REQUIRE(sm.getMesh()->getMeshBuffer(0)->getVertexCount() == 24);
|
||||
const auto* vertices = reinterpret_cast<irr::video::S3DVertex*>(
|
||||
sm.getMesh()->getMeshBuffer(0)->getVertices());
|
||||
|
||||
CHECK(vertices[0].Pos == irr::core::vector3df{3.0f, 24.0f, -3.0f});
|
||||
CHECK(vertices[3].Pos == irr::core::vector3df{3.0f, 18.0f, 3.0f});
|
||||
CHECK(vertices[6].Pos == irr::core::vector3df{-3.0f, 18.0f, -3.0f});
|
||||
CHECK(vertices[9].Pos == irr::core::vector3df{3.0f, 24.0f, 3.0f});
|
||||
CHECK(vertices[12].Pos == irr::core::vector3df{3.0f, 18.0f, -3.0f});
|
||||
CHECK(vertices[15].Pos == irr::core::vector3df{-3.0f, 18.0f, 3.0f});
|
||||
CHECK(vertices[18].Pos == irr::core::vector3df{3.0f, 18.0f, -3.0f});
|
||||
CHECK(vertices[21].Pos == irr::core::vector3df{3.0f, 18.0f, 3.0f});
|
||||
|
||||
vertices = reinterpret_cast<irr::video::S3DVertex*>(
|
||||
sm.getMesh()->getMeshBuffer(1)->getVertices());
|
||||
|
||||
CHECK(vertices[2].Pos == irr::core::vector3df{5.0f, 10.0f, 5.0f});
|
||||
CHECK(vertices[3].Pos == irr::core::vector3df{5.0f, 0.0f, 5.0f});
|
||||
CHECK(vertices[7].Pos == irr::core::vector3df{-5.0f, 0.0f, 5.0f});
|
||||
CHECK(vertices[8].Pos == irr::core::vector3df{5.0f, 10.0f, -5.0f});
|
||||
CHECK(vertices[14].Pos == irr::core::vector3df{5.0f, 0.0f, 5.0f});
|
||||
CHECK(vertices[16].Pos == irr::core::vector3df{5.0f, 10.0f, -5.0f});
|
||||
CHECK(vertices[22].Pos == irr::core::vector3df{-5.0f, 10.0f, 5.0f});
|
||||
CHECK(vertices[23].Pos == irr::core::vector3df{-5.0f, 0.0f, 5.0f});
|
||||
|
||||
vertices = reinterpret_cast<irr::video::S3DVertex*>(
|
||||
sm.getMesh()->getMeshBuffer(2)->getVertices());
|
||||
|
||||
CHECK(vertices[1].Pos == irr::core::vector3df{4.0f, 10.0f, -4.0f});
|
||||
CHECK(vertices[2].Pos == irr::core::vector3df{4.0f, 18.0f, 4.0f});
|
||||
CHECK(vertices[3].Pos == irr::core::vector3df{4.0f, 10.0f, 4.0f});
|
||||
CHECK(vertices[10].Pos == irr::core::vector3df{-4.0f, 18.0f, -4.0f});
|
||||
CHECK(vertices[11].Pos == irr::core::vector3df{-4.0f, 18.0f, 4.0f});
|
||||
CHECK(vertices[12].Pos == irr::core::vector3df{4.0f, 10.0f, -4.0f});
|
||||
CHECK(vertices[17].Pos == irr::core::vector3df{-4.0f, 18.0f, -4.0f});
|
||||
CHECK(vertices[18].Pos == irr::core::vector3df{4.0f, 10.0f, -4.0f});
|
||||
}
|
||||
|
||||
SECTION("vertex indices are correct for all buffers") {
|
||||
REQUIRE(sm.getMesh()->getMeshBuffer(0)->getIndexCount() == 36);
|
||||
const auto* indices = reinterpret_cast<irr::u16*>(
|
||||
sm.getMesh()->getMeshBuffer(0)->getIndices());
|
||||
CHECK(indices[0] == 23);
|
||||
CHECK(indices[1] == 21);
|
||||
CHECK(indices[2] == 22);
|
||||
CHECK(indices[35] == 2);
|
||||
|
||||
REQUIRE(sm.getMesh()->getMeshBuffer(1)->getIndexCount() == 36);
|
||||
indices = reinterpret_cast<irr::u16*>(
|
||||
sm.getMesh()->getMeshBuffer(1)->getIndices());
|
||||
CHECK(indices[10] == 16);
|
||||
CHECK(indices[11] == 18);
|
||||
CHECK(indices[15] == 13);
|
||||
CHECK(indices[27] == 5);
|
||||
|
||||
REQUIRE(sm.getMesh()->getMeshBuffer(1)->getIndexCount() == 36);
|
||||
indices = reinterpret_cast<irr::u16*>(
|
||||
sm.getMesh()->getMeshBuffer(2)->getIndices());
|
||||
CHECK(indices[26] == 6);
|
||||
CHECK(indices[27] == 5);
|
||||
CHECK(indices[29] == 6);
|
||||
CHECK(indices[32] == 2);
|
||||
}
|
||||
|
||||
|
||||
SECTION("vertex normals are correct for all buffers") {
|
||||
REQUIRE(sm.getMesh()->getMeshBuffer(0)->getVertexCount() == 24);
|
||||
const auto* vertices = reinterpret_cast<irr::video::S3DVertex*>(
|
||||
sm.getMesh()->getMeshBuffer(0)->getVertices());
|
||||
CHECK(vertices[0].Normal == irr::core::vector3df{1.0f, 0.0f, -0.0f});
|
||||
CHECK(vertices[1].Normal == irr::core::vector3df{1.0f, 0.0f, -0.0f});
|
||||
CHECK(vertices[2].Normal == irr::core::vector3df{1.0f, 0.0f, -0.0f});
|
||||
CHECK(vertices[3].Normal == irr::core::vector3df{1.0f, 0.0f, -0.0f});
|
||||
CHECK(vertices[6].Normal == irr::core::vector3df{-1.0f, 0.0f, -0.0f});
|
||||
CHECK(vertices[23].Normal == irr::core::vector3df{0.0f, 0.0f, 1.0f});
|
||||
|
||||
vertices = reinterpret_cast<irr::video::S3DVertex*>(
|
||||
sm.getMesh()->getMeshBuffer(1)->getVertices());
|
||||
|
||||
CHECK(vertices[0].Normal == irr::core::vector3df{1.0f, 0.0f, -0.0f});
|
||||
CHECK(vertices[1].Normal == irr::core::vector3df{1.0f, 0.0f, -0.0f});
|
||||
CHECK(vertices[3].Normal == irr::core::vector3df{1.0f, 0.0f, -0.0f});
|
||||
CHECK(vertices[6].Normal == irr::core::vector3df{-1.0f, 0.0f, -0.0f});
|
||||
CHECK(vertices[7].Normal == irr::core::vector3df{-1.0f, 0.0f, -0.0f});
|
||||
CHECK(vertices[22].Normal == irr::core::vector3df{0.0f, 0.0f, 1.0f});
|
||||
|
||||
|
||||
vertices = reinterpret_cast<irr::video::S3DVertex*>(
|
||||
sm.getMesh()->getMeshBuffer(2)->getVertices());
|
||||
|
||||
CHECK(vertices[3].Normal == irr::core::vector3df{1.0f, 0.0f, -0.0f});
|
||||
CHECK(vertices[4].Normal == irr::core::vector3df{-1.0f, 0.0f, -0.0f});
|
||||
CHECK(vertices[5].Normal == irr::core::vector3df{-1.0f, 0.0f, -0.0f});
|
||||
CHECK(vertices[10].Normal == irr::core::vector3df{0.0f, 1.0f, -0.0f});
|
||||
CHECK(vertices[11].Normal == irr::core::vector3df{0.0f, 1.0f, -0.0f});
|
||||
CHECK(vertices[19].Normal == irr::core::vector3df{0.0f, 0.0f, -1.0f});
|
||||
|
||||
}
|
||||
|
||||
|
||||
SECTION("texture coords are correct for all buffers") {
|
||||
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.583333, 0.791667});
|
||||
CHECK(vertices[1].TCoords == irr::core::vector2df{0.583333, 0.666667});
|
||||
CHECK(vertices[2].TCoords == irr::core::vector2df{0.708333, 0.791667});
|
||||
CHECK(vertices[5].TCoords == irr::core::vector2df{0.375, 0.416667});
|
||||
CHECK(vertices[6].TCoords == irr::core::vector2df{0.5, 0.291667});
|
||||
CHECK(vertices[19].TCoords == irr::core::vector2df{0.708333, 0.75});
|
||||
|
||||
vertices = reinterpret_cast<irr::video::S3DVertex*>(
|
||||
sm.getMesh()->getMeshBuffer(1)->getVertices());
|
||||
|
||||
CHECK(vertices[1].TCoords == irr::core::vector2df{0, 0.791667});
|
||||
CHECK(vertices[4].TCoords == irr::core::vector2df{0.208333, 0.791667});
|
||||
CHECK(vertices[5].TCoords == irr::core::vector2df{0, 0.791667});
|
||||
CHECK(vertices[6].TCoords == irr::core::vector2df{0.208333, 0.583333});
|
||||
CHECK(vertices[12].TCoords == irr::core::vector2df{0.416667, 0.791667});
|
||||
CHECK(vertices[15].TCoords == irr::core::vector2df{0.208333, 0.583333});
|
||||
|
||||
vertices = reinterpret_cast<irr::video::S3DVertex*>(
|
||||
sm.getMesh()->getMeshBuffer(2)->getVertices());
|
||||
|
||||
CHECK(vertices[10].TCoords == irr::core::vector2df{0.375, 0.416667});
|
||||
CHECK(vertices[11].TCoords == irr::core::vector2df{0.375, 0.583333});
|
||||
CHECK(vertices[12].TCoords == irr::core::vector2df{0.708333, 0.625});
|
||||
CHECK(vertices[17].TCoords == irr::core::vector2df{0.541667, 0.458333});
|
||||
CHECK(vertices[20].TCoords == irr::core::vector2df{0.208333, 0.416667});
|
||||
CHECK(vertices[22].TCoords == irr::core::vector2df{0.375, 0.416667});
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user