mirror of
https://github.com/minetest/irrlicht.git
synced 2024-11-18 00:08:20 +01:00
Load vertex coordinates from glTF buffer
This commit is contained in:
parent
48751c15f6
commit
46148bbf61
@ -9,10 +9,12 @@
|
||||
#include "SAnimatedMesh.h"
|
||||
#include "SColor.h"
|
||||
#include "SMesh.h"
|
||||
#include "vector3d.h"
|
||||
|
||||
#define TINYGLTF_IMPLEMENTATION
|
||||
#include <tiny_gltf.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
@ -22,6 +24,33 @@ namespace irr
|
||||
namespace scene
|
||||
{
|
||||
|
||||
class BufferOffset
|
||||
{
|
||||
public:
|
||||
BufferOffset(const std::vector<unsigned char>& buf,
|
||||
const std::size_t offset) noexcept
|
||||
: m_buf(buf), m_offset(offset)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned char at(const std::size_t fromOffset) const
|
||||
{
|
||||
return m_buf.at(m_offset + fromOffset);
|
||||
}
|
||||
|
||||
private:
|
||||
const std::vector<unsigned char>& m_buf;
|
||||
std::size_t m_offset;
|
||||
};
|
||||
|
||||
static constexpr float readFloat(const BufferOffset& readFrom) {
|
||||
unsigned char d[4]{};
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
d[i] = readFrom.at(i);
|
||||
}
|
||||
return *reinterpret_cast<float*>(d);
|
||||
}
|
||||
|
||||
CGLTFMeshFileLoader::CGLTFMeshFileLoader()
|
||||
{
|
||||
}
|
||||
@ -34,18 +63,35 @@ bool CGLTFMeshFileLoader::isALoadableFileExtension(
|
||||
|
||||
IAnimatedMesh* CGLTFMeshFileLoader::createMesh(io::IReadFile* file)
|
||||
{
|
||||
if (file->getSize() == 0 || !tryParseGLTF(file)) {
|
||||
tinygltf::Model model{};
|
||||
|
||||
if (file->getSize() == 0 || !tryParseGLTF(file, model)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto& view = model.bufferViews[model.accessors[1].bufferView];
|
||||
const auto& buffer = model.buffers[view.buffer];
|
||||
const core::vector3df v1(
|
||||
-readFloat(BufferOffset(buffer.data, view.byteOffset)),
|
||||
readFloat(BufferOffset(buffer.data, view.byteOffset + 4)),
|
||||
readFloat(BufferOffset(buffer.data, view.byteOffset + 8)));
|
||||
const core::vector3df v2(
|
||||
-readFloat(BufferOffset(buffer.data, view.byteOffset + 12)),
|
||||
readFloat(BufferOffset(buffer.data, view.byteOffset + 16)),
|
||||
readFloat(BufferOffset(buffer.data, view.byteOffset + 20)));
|
||||
const core::vector3df v3(
|
||||
-readFloat(BufferOffset(buffer.data, view.byteOffset + 24)),
|
||||
readFloat(BufferOffset(buffer.data, view.byteOffset + 28)),
|
||||
readFloat(BufferOffset(buffer.data, view.byteOffset + 32)));
|
||||
|
||||
// sorry Bjarne
|
||||
SMeshBuffer* meshbuf { new SMeshBuffer {} };
|
||||
|
||||
const video::S3DVertex* vertices { new video::S3DVertex[3] {
|
||||
{{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, {}, {0.0f, 0.0f}},
|
||||
{{0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, {}, {1.0f, 0.0f}},
|
||||
{{-1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, {}, {0.0f, 1.0f}} } };
|
||||
const u16* indices { new u16[3] {0, 1, 2} };
|
||||
{v1, {0.0f, 0.0f, 1.0f}, {}, {0.0f, 0.0f}},
|
||||
{v2, {0.0f, 0.0f, 1.0f}, {}, {1.0f, 0.0f}},
|
||||
{v3, {0.0f, 0.0f, 1.0f}, {}, {0.0f, 1.0f}} } };
|
||||
const u16* indices { new u16[3] {0, 2, 1} };
|
||||
meshbuf->append(vertices, 3, indices, 3);
|
||||
|
||||
SMesh* mesh { new SMesh {} };
|
||||
@ -57,9 +103,9 @@ IAnimatedMesh* CGLTFMeshFileLoader::createMesh(io::IReadFile* file)
|
||||
return animatedMesh;
|
||||
}
|
||||
|
||||
bool CGLTFMeshFileLoader::tryParseGLTF(io::IReadFile* file) const
|
||||
bool CGLTFMeshFileLoader::tryParseGLTF(io::IReadFile* file,
|
||||
tinygltf::Model& model) const
|
||||
{
|
||||
tinygltf::Model model {};
|
||||
tinygltf::TinyGLTF loader {};
|
||||
std::string err {};
|
||||
std::string warn {};
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include "IReadFile.h"
|
||||
#include "path.h"
|
||||
|
||||
#include <tiny_gltf.h>
|
||||
|
||||
namespace irr
|
||||
{
|
||||
|
||||
@ -22,7 +24,7 @@ public:
|
||||
IAnimatedMesh* createMesh(io::IReadFile* file) override;
|
||||
|
||||
private:
|
||||
bool tryParseGLTF(io::IReadFile* file) const;
|
||||
bool tryParseGLTF(io::IReadFile* file, tinygltf::Model& model) const;
|
||||
};
|
||||
|
||||
} // namespace scene
|
||||
|
@ -56,8 +56,8 @@ TEST_CASE("minimal triangle has correct vertices") {
|
||||
auto* vertices = reinterpret_cast<irr::video::S3DVertex*>(
|
||||
meshbuf->getVertices());
|
||||
CHECK(vertices[0].Pos == irr::core::vector3df {0.0f, 0.0f, 0.0f});
|
||||
CHECK(vertices[1].Pos == irr::core::vector3df {0.0f, 1.0f, 0.0f});
|
||||
CHECK(vertices[2].Pos == irr::core::vector3df {-1.0f, 0.0f, 0.0f});
|
||||
CHECK(vertices[1].Pos == irr::core::vector3df {-1.0f, 0.0f, 0.0f});
|
||||
CHECK(vertices[2].Pos == irr::core::vector3df {0.0f, 1.0f, 0.0f});
|
||||
}
|
||||
|
||||
TEST_CASE("mesh loader returns nullptr when given null file pointer") {
|
||||
|
Loading…
Reference in New Issue
Block a user