From 7c54677acd968fa1333c0cec97911b61dc2370f5 Mon Sep 17 00:00:00 2001 From: "Arthur Brainville (Ybalrid)" Date: Mon, 19 Feb 2018 18:01:53 +0100 Subject: [PATCH] Now load index buffer Added some template infrastructure to read arrays where type is defined by a value. Signed-off by: Arthur Brainville (Ybalrid) --- examples/raytrace/gltf-loader.cc | 135 +++++++++++++++++++++++++++++-- 1 file changed, 128 insertions(+), 7 deletions(-) diff --git a/examples/raytrace/gltf-loader.cc b/examples/raytrace/gltf-loader.cc index 5ab5ac7..91434b2 100644 --- a/examples/raytrace/gltf-loader.cc +++ b/examples/raytrace/gltf-loader.cc @@ -1,9 +1,9 @@ #include "gltf-loader.h" #include - +#include // c++11 #define TINYGLTF_IMPLEMENTATION -#include "tiny_gltf.h" +#include namespace example { @@ -13,6 +13,56 @@ static std::string GetFilePathExtension(const std::string &FileName) { return ""; } +template +struct arrayAdapter { + unsigned char *dataPtr; + const size_t elemCount; + const size_t stride; + arrayAdapter(unsigned char *ptr, size_t count, size_t byte_stride = 1) + : dataPtr(ptr), elemCount(count), stride(byte_stride) {} + + T operator[](size_t pos) { + if (pos >= elemCount) + throw std::out_of_range( + "Tried to access beyond the last element of an array adapter"); + return *(reinterpret_cast(dataPtr + pos * stride)); + } +}; + +struct intArrayBase { + virtual int operator[](size_t) = 0; + virtual size_t size() const = 0; +}; + +struct floatArrayBase { + virtual float operator[](size_t) = 0; + virtual size_t size() const = 0; +}; + +template +struct intArray : public intArrayBase { + arrayAdapter adapter; + + intArray(const arrayAdapter &a) : adapter(a) {} + int operator[](size_t position) override { + return static_cast(adapter[position]); + } + + size_t size() const override { return adapter.elemCount; } +}; + +template +struct floatArray : public floatArrayBase { + arrayAdapter adapter; + + floatArray(const arrayAdapter &a) : adapter(a) {} + float operator[](size_t position) override { + return static_cast(adapter[position]); + } + + size_t size() const override { return adapter.elemCount; } +}; + /// /// Loads glTF 2.0 mesh /// @@ -46,8 +96,6 @@ bool LoadGLTF(const std::string &filename, float scale, return false; } - std::cerr << "LoadGLTF() function is not yet implemented!" << std::endl; - std::cout << "loaded glTF file has:\n" << model.accessors.size() << " accessors\n" << model.animations.size() << " animations\n" @@ -67,11 +115,84 @@ bool LoadGLTF(const std::string &filename, float scale, for (const auto &gltfMesh : model.meshes) { std::cout << "Current mesh has " << gltfMesh.primitives.size() << " primitives:\n"; + + Mesh loadedMesh(sizeof(float) * 3); + loadedMesh.name = gltfMesh.name; for (const auto &meshPrimitive : gltfMesh.primitives) { + // get access to the indices + std::unique_ptr indicesArray = nullptr; + + auto &indicesAccessor = model.accessors[meshPrimitive.indices]; + auto &bufferView = model.bufferViews[indicesAccessor.bufferView]; + auto &buffer = model.buffers[bufferView.buffer]; + unsigned char *dataAddress = buffer.data.data() + bufferView.byteOffset + + indicesAccessor.byteOffset; + const auto byteStride = indicesAccessor.ByteStride(bufferView); + const auto count = indicesAccessor.count; + + switch (indicesAccessor.componentType) { + case TINYGLTF_COMPONENT_TYPE_BYTE: + indicesArray = std::unique_ptr >(new intArray( + arrayAdapter(dataAddress, count, byteStride))); + break; + + case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE: + indicesArray = std::unique_ptr >( + new intArray( + arrayAdapter(dataAddress, count, byteStride))); + break; + + case TINYGLTF_COMPONENT_TYPE_SHORT: + indicesArray = std::unique_ptr >(new intArray( + arrayAdapter(dataAddress, count, byteStride))); + break; + + case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT: + indicesArray = std::unique_ptr >( + new intArray(arrayAdapter( + dataAddress, count, byteStride))); + break; + + case TINYGLTF_COMPONENT_TYPE_INT: + indicesArray = std::unique_ptr >(new intArray( + arrayAdapter(dataAddress, count, byteStride))); + break; + + case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT: + indicesArray = std::unique_ptr >( + new intArray( + arrayAdapter(dataAddress, count, byteStride))); + break; + default: + break; + } + + if (indicesArray) + for (size_t i(0); i < indicesArray->size(); ++i) { + std::cout << (*indicesArray)[i] << " "; + } + + std::cout << '\n'; + switch (meshPrimitive.mode) { case TINYGLTF_MODE_TRIANGLES: // this is the simpliest case to handle + + { std::cout << "Will load a plain old list of trianges\n"; - break; + + for (const auto &attribute : meshPrimitive.attributes) { + if (attribute.first == "POSITION") { + std::cout << "found position attribute\n"; + const auto posAccessor = model.accessors[attribute.second]; + } + + if (attribute.first == "NORMAL") { + std::cout << "found normal attribute\n"; + } + } + } + + break; // Other trigangle based modes case TINYGLTF_MODE_TRIANGLE_FAN: @@ -89,7 +210,7 @@ bool LoadGLTF(const std::string &filename, float scale, } } + std::cerr << "LoadGLTF() function is not yet implemented!" << std::endl; return false; } - -} // namespace example +} // namespace example \ No newline at end of file