Now load index buffer

Added some template infrastructure to read arrays where type is defined by a value.

Signed-off by: Arthur Brainville (Ybalrid) <ybalrid@ybalrid.info>
This commit is contained in:
Arthur Brainville (Ybalrid) 2018-02-19 18:01:53 +01:00
parent b8040e2a19
commit 7c54677acd
No known key found for this signature in database
GPG Key ID: BC05C4812A06BCF3

View File

@ -1,9 +1,9 @@
#include "gltf-loader.h"
#include <iostream>
#include <memory> // c++11
#define TINYGLTF_IMPLEMENTATION
#include "tiny_gltf.h"
#include <tiny_gltf.h>
namespace example {
@ -13,6 +13,56 @@ static std::string GetFilePathExtension(const std::string &FileName) {
return "";
}
template <typename T>
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<T *>(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 <class T>
struct intArray : public intArrayBase {
arrayAdapter<T> adapter;
intArray(const arrayAdapter<T> &a) : adapter(a) {}
int operator[](size_t position) override {
return static_cast<int>(adapter[position]);
}
size_t size() const override { return adapter.elemCount; }
};
template <class T>
struct floatArray : public floatArrayBase {
arrayAdapter<T> adapter;
floatArray(const arrayAdapter<T> &a) : adapter(a) {}
float operator[](size_t position) override {
return static_cast<float>(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<float> loadedMesh(sizeof(float) * 3);
loadedMesh.name = gltfMesh.name;
for (const auto &meshPrimitive : gltfMesh.primitives) {
// get access to the indices
std::unique_ptr<intArrayBase> 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<intArray<char> >(new intArray<char>(
arrayAdapter<char>(dataAddress, count, byteStride)));
break;
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE:
indicesArray = std::unique_ptr<intArray<unsigned char> >(
new intArray<unsigned char>(
arrayAdapter<unsigned char>(dataAddress, count, byteStride)));
break;
case TINYGLTF_COMPONENT_TYPE_SHORT:
indicesArray = std::unique_ptr<intArray<short> >(new intArray<short>(
arrayAdapter<short>(dataAddress, count, byteStride)));
break;
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT:
indicesArray = std::unique_ptr<intArray<unsigned short> >(
new intArray<unsigned short>(arrayAdapter<unsigned short>(
dataAddress, count, byteStride)));
break;
case TINYGLTF_COMPONENT_TYPE_INT:
indicesArray = std::unique_ptr<intArray<int> >(new intArray<int>(
arrayAdapter<int>(dataAddress, count, byteStride)));
break;
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT:
indicesArray = std::unique_ptr<intArray<unsigned int> >(
new intArray<unsigned int>(
arrayAdapter<unsigned int>(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