Also access the position attribute of the primitive

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

View File

@ -2,9 +2,12 @@
#include <iostream> #include <iostream>
#include <memory> // c++11 #include <memory> // c++11
#include <stdexcept>
#define TINYGLTF_IMPLEMENTATION #define TINYGLTF_IMPLEMENTATION
#include <tiny_gltf.h> #include <tiny_gltf.h>
using std::out_of_range;
namespace example { namespace example {
static std::string GetFilePathExtension(const std::string &FileName) { static std::string GetFilePathExtension(const std::string &FileName) {
@ -13,38 +16,50 @@ static std::string GetFilePathExtension(const std::string &FileName) {
return ""; return "";
} }
/// Adapts an array of bytes to an array of T. Will advace of byte_stride each
/// elements.
template <typename T> template <typename T>
struct arrayAdapter { struct arrayAdapter {
unsigned char *dataPtr; /// Pointer to the bytes
const unsigned char *dataPtr;
/// Number of elements in the array
const size_t elemCount; const size_t elemCount;
/// Stride in bytes between two elements
const size_t stride; const size_t stride;
arrayAdapter(unsigned char *ptr, size_t count, size_t byte_stride = 1) /// Constructor.
arrayAdapter(const unsigned char *ptr, size_t count, size_t byte_stride = 1)
: dataPtr(ptr), elemCount(count), stride(byte_stride) {} : dataPtr(ptr), elemCount(count), stride(byte_stride) {}
T operator[](size_t pos) { /// Returns a *copy* of a single element. Can't be used to modify it.
T operator[](size_t pos) const {
if (pos >= elemCount) if (pos >= elemCount)
throw std::out_of_range( throw out_of_range(
"Tried to access beyond the last element of an array adapter"); "Tried to access beyond the last element of an array adapter");
return *(reinterpret_cast<T *>(dataPtr + pos * stride)); return *(reinterpret_cast<const T *>(dataPtr + pos * stride));
} }
}; };
/// Interface of any adapted array that returns ingeger data
struct intArrayBase { struct intArrayBase {
virtual int operator[](size_t) = 0; virtual ~intArrayBase() = default;
virtual int operator[](size_t) const = 0;
virtual size_t size() const = 0; virtual size_t size() const = 0;
}; };
/// Interface of any adapted array that returns float data
struct floatArrayBase { struct floatArrayBase {
virtual float operator[](size_t) = 0; virtual ~floatArrayBase() = default;
virtual float operator[](size_t) const = 0;
virtual size_t size() const = 0; virtual size_t size() const = 0;
}; };
/// An array that loads interger types, returns them as int
template <class T> template <class T>
struct intArray : public intArrayBase { struct intArray : public intArrayBase {
arrayAdapter<T> adapter; arrayAdapter<T> adapter;
intArray(const arrayAdapter<T> &a) : adapter(a) {} intArray(const arrayAdapter<T> &a) : adapter(a) {}
int operator[](size_t position) override { int operator[](size_t position) const override {
return static_cast<int>(adapter[position]); return static_cast<int>(adapter[position]);
} }
@ -56,13 +71,56 @@ struct floatArray : public floatArrayBase {
arrayAdapter<T> adapter; arrayAdapter<T> adapter;
floatArray(const arrayAdapter<T> &a) : adapter(a) {} floatArray(const arrayAdapter<T> &a) : adapter(a) {}
float operator[](size_t position) override { float operator[](size_t position) const override {
return static_cast<float>(adapter[position]); return static_cast<float>(adapter[position]);
} }
size_t size() const override { return adapter.elemCount; } size_t size() const override { return adapter.elemCount; }
}; };
#pragma pack(push, 1)
template <typename T>
struct v2 {
T x, y;
};
/// 3D vector of floats without padding
template <typename T>
struct v3 {
T x, y, z;
};
/// 4D vector of floats without padding
template <typename T>
struct v4 {
T x, y, z, w;
};
#pragma pack(pop)
using v2f = v2<float>;
using v3f = v3<float>;
using v4f = v4<float>;
using v2d = v2<double>;
using v3d = v3<double>;
using v4d = v4<double>;
struct v3fArray {
arrayAdapter<v3f> adapter;
v3fArray(const arrayAdapter<v3f> &a) : adapter(a) {}
v3f operator[](size_t position) const { return adapter[position]; }
size_t size() const { return adapter.elemCount; }
};
struct v4fArray {
arrayAdapter<v4f> adapter;
v4fArray(const arrayAdapter<v4f> &a) : adapter(a) {}
v4f operator[](size_t position) const { return adapter[position]; }
size_t size() const { return adapter.elemCount; }
};
/// ///
/// Loads glTF 2.0 mesh /// Loads glTF 2.0 mesh
/// ///
@ -120,56 +178,61 @@ bool LoadGLTF(const std::string &filename, float scale,
loadedMesh.name = gltfMesh.name; loadedMesh.name = gltfMesh.name;
for (const auto &meshPrimitive : gltfMesh.primitives) { for (const auto &meshPrimitive : gltfMesh.primitives) {
// get access to the indices // get access to the indices
std::unique_ptr<intArrayBase> indicesArray = nullptr; std::unique_ptr<intArrayBase> indicesArrayPtr = 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;
auto &indicesAccessor = model.accessors[meshPrimitive.indices]; switch (indicesAccessor.componentType) {
auto &bufferView = model.bufferViews[indicesAccessor.bufferView]; case TINYGLTF_COMPONENT_TYPE_BYTE:
auto &buffer = model.buffers[bufferView.buffer]; indicesArrayPtr =
unsigned char *dataAddress = buffer.data.data() + bufferView.byteOffset + std::unique_ptr<intArray<char> >(new intArray<char>(
indicesAccessor.byteOffset; arrayAdapter<char>(dataAddress, count, byteStride)));
const auto byteStride = indicesAccessor.ByteStride(bufferView); break;
const auto count = indicesAccessor.count;
switch (indicesAccessor.componentType) { case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE:
case TINYGLTF_COMPONENT_TYPE_BYTE: indicesArrayPtr = std::unique_ptr<intArray<unsigned char> >(
indicesArray = std::unique_ptr<intArray<char> >(new intArray<char>( new intArray<unsigned char>(arrayAdapter<unsigned char>(
arrayAdapter<char>(dataAddress, count, byteStride))); dataAddress, count, byteStride)));
break; break;
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE: case TINYGLTF_COMPONENT_TYPE_SHORT:
indicesArray = std::unique_ptr<intArray<unsigned char> >( indicesArrayPtr =
new intArray<unsigned char>( std::unique_ptr<intArray<short> >(new intArray<short>(
arrayAdapter<unsigned char>(dataAddress, count, byteStride))); arrayAdapter<short>(dataAddress, count, byteStride)));
break; break;
case TINYGLTF_COMPONENT_TYPE_SHORT: case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT:
indicesArray = std::unique_ptr<intArray<short> >(new intArray<short>( indicesArrayPtr = std::unique_ptr<intArray<unsigned short> >(
arrayAdapter<short>(dataAddress, count, byteStride))); new intArray<unsigned short>(arrayAdapter<unsigned short>(
break; dataAddress, count, byteStride)));
break;
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT: case TINYGLTF_COMPONENT_TYPE_INT:
indicesArray = std::unique_ptr<intArray<unsigned short> >( indicesArrayPtr = std::unique_ptr<intArray<int> >(new intArray<int>(
new intArray<unsigned short>(arrayAdapter<unsigned short>( arrayAdapter<int>(dataAddress, count, byteStride)));
dataAddress, count, byteStride))); break;
break;
case TINYGLTF_COMPONENT_TYPE_INT: case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT:
indicesArray = std::unique_ptr<intArray<int> >(new intArray<int>( indicesArrayPtr = std::unique_ptr<intArray<unsigned int> >(
arrayAdapter<int>(dataAddress, count, byteStride))); new intArray<unsigned int>(arrayAdapter<unsigned int>(
break; dataAddress, count, byteStride)));
break;
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT: default:
indicesArray = std::unique_ptr<intArray<unsigned int> >( break;
new intArray<unsigned int>( }
arrayAdapter<unsigned int>(dataAddress, count, byteStride)));
break;
default:
break;
} }
const auto &indices = *indicesArrayPtr;
if (indicesArray) if (indicesArrayPtr)
for (size_t i(0); i < indicesArray->size(); ++i) { for (size_t i(0); i < indicesArrayPtr->size(); ++i) {
std::cout << (*indicesArray)[i] << " "; std::cout << indices[i] << " ";
} }
std::cout << '\n'; std::cout << '\n';
@ -181,9 +244,41 @@ bool LoadGLTF(const std::string &filename, float scale,
std::cout << "Will load a plain old list of trianges\n"; std::cout << "Will load a plain old list of trianges\n";
for (const auto &attribute : meshPrimitive.attributes) { for (const auto &attribute : meshPrimitive.attributes) {
const auto attribAccessor = model.accessors[attribute.second];
const auto &bufferView =
model.bufferViews[attribAccessor.bufferView];
const auto &buffer = model.buffers[bufferView.buffer];
auto dataPtr = buffer.data.data() + bufferView.byteOffset +
attribAccessor.byteOffset;
const auto byte_stride = attribAccessor.ByteStride(bufferView);
const auto count = attribAccessor.count;
if (attribute.first == "POSITION") { if (attribute.first == "POSITION") {
std::cout << "found position attribute\n"; std::cout << "found position attribute\n";
const auto posAccessor = model.accessors[attribute.second];
switch (attribAccessor.componentType) {
case TINYGLTF_COMPONENT_TYPE_FLOAT:
switch (attribAccessor.type) {
case TINYGLTF_TYPE_VEC3: {
/// 3D vector of float
v3fArray positions(
arrayAdapter<v3f>(dataPtr, count, byte_stride));
for (size_t i{0}; i < indices.size(); ++i) {
const auto index{indices[i]};
const auto v = positions[index];
std::cout << '(' << v.x << ", " << v.y << ", " << v.z
<< ")\n";
}
} break;
default:
// TODO Handle error
break;
}
break;
default:
// TODO handle error
break;
}
} }
if (attribute.first == "NORMAL") { if (attribute.first == "NORMAL") {
@ -213,4 +308,4 @@ bool LoadGLTF(const std::string &filename, float scale,
std::cerr << "LoadGLTF() function is not yet implemented!" << std::endl; std::cerr << "LoadGLTF() function is not yet implemented!" << std::endl;
return false; return false;
} }
} // namespace example } // namespace example