mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-09-13 07:23:15 +08:00
Also access the position attribute of the primitive
Signed-off-by: Arthur Brainville (Ybalrid) <ybalrid@ybalrid.info>
This commit is contained in:
parent
ce75870894
commit
ffc79a719b
@ -2,9 +2,12 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <memory> // c++11
|
||||
#include <stdexcept>
|
||||
#define TINYGLTF_IMPLEMENTATION
|
||||
#include <tiny_gltf.h>
|
||||
|
||||
using std::out_of_range;
|
||||
|
||||
namespace example {
|
||||
|
||||
static std::string GetFilePathExtension(const std::string &FileName) {
|
||||
@ -13,38 +16,50 @@ static std::string GetFilePathExtension(const std::string &FileName) {
|
||||
return "";
|
||||
}
|
||||
|
||||
/// Adapts an array of bytes to an array of T. Will advace of byte_stride each
|
||||
/// elements.
|
||||
template <typename T>
|
||||
struct arrayAdapter {
|
||||
unsigned char *dataPtr;
|
||||
/// Pointer to the bytes
|
||||
const unsigned char *dataPtr;
|
||||
/// Number of elements in the array
|
||||
const size_t elemCount;
|
||||
/// Stride in bytes between two elements
|
||||
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) {}
|
||||
|
||||
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)
|
||||
throw std::out_of_range(
|
||||
throw out_of_range(
|
||||
"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 {
|
||||
virtual int operator[](size_t) = 0;
|
||||
virtual ~intArrayBase() = default;
|
||||
virtual int operator[](size_t) const = 0;
|
||||
virtual size_t size() const = 0;
|
||||
};
|
||||
|
||||
/// Interface of any adapted array that returns float data
|
||||
struct floatArrayBase {
|
||||
virtual float operator[](size_t) = 0;
|
||||
virtual ~floatArrayBase() = default;
|
||||
virtual float operator[](size_t) const = 0;
|
||||
virtual size_t size() const = 0;
|
||||
};
|
||||
|
||||
/// An array that loads interger types, returns them as int
|
||||
template <class T>
|
||||
struct intArray : public intArrayBase {
|
||||
arrayAdapter<T> adapter;
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
@ -56,13 +71,56 @@ struct floatArray : public floatArrayBase {
|
||||
arrayAdapter<T> adapter;
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
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
|
||||
///
|
||||
@ -120,56 +178,61 @@ bool LoadGLTF(const std::string &filename, float scale,
|
||||
loadedMesh.name = gltfMesh.name;
|
||||
for (const auto &meshPrimitive : gltfMesh.primitives) {
|
||||
// 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];
|
||||
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:
|
||||
indicesArrayPtr =
|
||||
std::unique_ptr<intArray<char> >(new intArray<char>(
|
||||
arrayAdapter<char>(dataAddress, count, byteStride)));
|
||||
break;
|
||||
|
||||
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:
|
||||
indicesArrayPtr = std::unique_ptr<intArray<unsigned char> >(
|
||||
new intArray<unsigned char>(arrayAdapter<unsigned 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:
|
||||
indicesArrayPtr =
|
||||
std::unique_ptr<intArray<short> >(new intArray<short>(
|
||||
arrayAdapter<short>(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:
|
||||
indicesArrayPtr = std::unique_ptr<intArray<unsigned short> >(
|
||||
new intArray<unsigned short>(arrayAdapter<unsigned 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:
|
||||
indicesArrayPtr = std::unique_ptr<intArray<int> >(new intArray<int>(
|
||||
arrayAdapter<int>(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;
|
||||
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT:
|
||||
indicesArrayPtr = std::unique_ptr<intArray<unsigned int> >(
|
||||
new intArray<unsigned int>(arrayAdapter<unsigned int>(
|
||||
dataAddress, count, byteStride)));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
const auto &indices = *indicesArrayPtr;
|
||||
|
||||
if (indicesArray)
|
||||
for (size_t i(0); i < indicesArray->size(); ++i) {
|
||||
std::cout << (*indicesArray)[i] << " ";
|
||||
if (indicesArrayPtr)
|
||||
for (size_t i(0); i < indicesArrayPtr->size(); ++i) {
|
||||
std::cout << indices[i] << " ";
|
||||
}
|
||||
|
||||
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";
|
||||
|
||||
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") {
|
||||
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") {
|
||||
@ -213,4 +308,4 @@ bool LoadGLTF(const std::string &filename, float scale,
|
||||
std::cerr << "LoadGLTF() function is not yet implemented!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
} // namespace example
|
||||
} // namespace example
|
||||
|
Loading…
x
Reference in New Issue
Block a user