mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-09-24 16:23:16 +08:00
Handle all types of triangle-based vertex buffer.
Some small codepath changes too. Signed-off by: Arthur Brainville (Ybalrid) <ybalrid@ybalrid.info>
This commit is contained in:
parent
1cd3b0f756
commit
6cf0228fa7
@ -72,6 +72,7 @@ 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) {
|
||||||
|
bool convertedToTriangleList = false;
|
||||||
// get access to the indices
|
// get access to the indices
|
||||||
std::unique_ptr<intArrayBase> indicesArrayPtr = nullptr;
|
std::unique_ptr<intArrayBase> indicesArrayPtr = nullptr;
|
||||||
{
|
{
|
||||||
@ -136,6 +137,40 @@ bool LoadGLTF(const std::string &filename, float scale,
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (meshPrimitive.mode) {
|
switch (meshPrimitive.mode) {
|
||||||
|
// We re-arrange the indices so that it describe a simple list of
|
||||||
|
// triangles
|
||||||
|
case TINYGLTF_MODE_TRIANGLE_FAN:
|
||||||
|
if (!convertedToTriangleList) {
|
||||||
|
std::cout << "TRIANGLE_FAN\n";
|
||||||
|
// This only has to be done once per primitive
|
||||||
|
convertedToTriangleList = true;
|
||||||
|
|
||||||
|
// We steal the guts of the vector
|
||||||
|
auto triangleFan = std::move(loadedMesh.faces);
|
||||||
|
loadedMesh.faces.clear();
|
||||||
|
|
||||||
|
// Push back the indices that describe just one triangle one by one
|
||||||
|
for (size_t i{2}; i < triangleFan.size(); ++i) {
|
||||||
|
loadedMesh.faces.push_back(triangleFan[0]);
|
||||||
|
loadedMesh.faces.push_back(triangleFan[1]);
|
||||||
|
loadedMesh.faces.push_back(triangleFan[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case TINYGLTF_MODE_TRIANGLE_STRIP:
|
||||||
|
if (!convertedToTriangleList) {
|
||||||
|
std::cout << "TRIANGLE_STRIP\n";
|
||||||
|
// This only has to be done once per primitive
|
||||||
|
convertedToTriangleList = true;
|
||||||
|
|
||||||
|
auto triangleStrip = std::move(loadedMesh.faces);
|
||||||
|
loadedMesh.faces.clear();
|
||||||
|
|
||||||
|
for (size_t i{2}; i < triangleStrip.size(); ++i) {
|
||||||
|
loadedMesh.faces.push_back(triangleStrip[i - 2]);
|
||||||
|
loadedMesh.faces.push_back(triangleStrip[i - 1]);
|
||||||
|
loadedMesh.faces.push_back(triangleStrip[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
case TINYGLTF_MODE_TRIANGLES: // this is the simpliest case to handle
|
case TINYGLTF_MODE_TRIANGLES: // this is the simpliest case to handle
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -222,9 +257,10 @@ bool LoadGLTF(const std::string &filename, float scale,
|
|||||||
|
|
||||||
switch (attribAccessor.type) {
|
switch (attribAccessor.type) {
|
||||||
case TINYGLTF_TYPE_VEC3: {
|
case TINYGLTF_TYPE_VEC3: {
|
||||||
|
std::cout << "Normal is VEC3\n";
|
||||||
switch (attribAccessor.componentType) {
|
switch (attribAccessor.componentType) {
|
||||||
case TINYGLTF_COMPONENT_TYPE_FLOAT:
|
case TINYGLTF_COMPONENT_TYPE_FLOAT: {
|
||||||
std::cout << "normal vec3\n";
|
std::cout << "Normal is FLOAT\n";
|
||||||
v3fArray normals(
|
v3fArray normals(
|
||||||
arrayAdapter<v3f>(dataPtr, count, byte_stride));
|
arrayAdapter<v3f>(dataPtr, count, byte_stride));
|
||||||
|
|
||||||
@ -244,7 +280,40 @@ bool LoadGLTF(const std::string &filename, float scale,
|
|||||||
n1 = normals[f1];
|
n1 = normals[f1];
|
||||||
n2 = normals[f2];
|
n2 = normals[f2];
|
||||||
|
|
||||||
std::cout << "got the 3 normals!\n";
|
// Put them in the array in the correct order
|
||||||
|
loadedMesh.facevarying_normals.push_back(n0.x);
|
||||||
|
loadedMesh.facevarying_normals.push_back(n0.y);
|
||||||
|
loadedMesh.facevarying_normals.push_back(n0.z);
|
||||||
|
|
||||||
|
loadedMesh.facevarying_normals.push_back(n1.x);
|
||||||
|
loadedMesh.facevarying_normals.push_back(n1.y);
|
||||||
|
loadedMesh.facevarying_normals.push_back(n2.z);
|
||||||
|
|
||||||
|
loadedMesh.facevarying_normals.push_back(n2.x);
|
||||||
|
loadedMesh.facevarying_normals.push_back(n2.y);
|
||||||
|
loadedMesh.facevarying_normals.push_back(n2.z);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case TINYGLTF_COMPONENT_TYPE_DOUBLE: {
|
||||||
|
std::cout << "Normal is DOUBLE\n";
|
||||||
|
v3dArray normals(
|
||||||
|
arrayAdapter<v3d>(dataPtr, count, byte_stride));
|
||||||
|
|
||||||
|
// IMPORTANT: We need to reorder normals (and texture
|
||||||
|
// coordinates into "facevarying" order) for each face
|
||||||
|
|
||||||
|
// For each triangle :
|
||||||
|
for (size_t i{0}; i < indices.size() / 3; ++i) {
|
||||||
|
// get the i'th triange's indexes
|
||||||
|
auto f0 = indices[3 * i + 0];
|
||||||
|
auto f1 = indices[3 * i + 1];
|
||||||
|
auto f2 = indices[3 * i + 2];
|
||||||
|
|
||||||
|
// get the 3 normal vectors for that face
|
||||||
|
v3d n0, n1, n2;
|
||||||
|
n0 = normals[f0];
|
||||||
|
n1 = normals[f1];
|
||||||
|
n2 = normals[f2];
|
||||||
|
|
||||||
// Put them in the array in the correct order
|
// Put them in the array in the correct order
|
||||||
loadedMesh.facevarying_normals.push_back(n0.x);
|
loadedMesh.facevarying_normals.push_back(n0.x);
|
||||||
@ -259,118 +328,113 @@ bool LoadGLTF(const std::string &filename, float scale,
|
|||||||
loadedMesh.facevarying_normals.push_back(n2.y);
|
loadedMesh.facevarying_normals.push_back(n2.y);
|
||||||
loadedMesh.facevarying_normals.push_back(n2.z);
|
loadedMesh.facevarying_normals.push_back(n2.z);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// TODO handle error
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case TINYGLTF_TYPE_VEC4:
|
|
||||||
std::cout << "normal vec4";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO (Ybalrid) : need to order the UVs into facevarying order
|
|
||||||
if (attribute.first == "TEXCOORD_0") {
|
|
||||||
std::cout << "Found texture coordinates\n";
|
|
||||||
|
|
||||||
switch (attribAccessor.type) {
|
|
||||||
case TINYGLTF_TYPE_VEC2: {
|
|
||||||
switch (attribAccessor.componentType) {
|
|
||||||
case TINYGLTF_COMPONENT_TYPE_FLOAT: {
|
|
||||||
v2fArray uvs(
|
|
||||||
arrayAdapter<v2f>(dataPtr, count, byte_stride));
|
|
||||||
for (size_t i{0}; i < uvs.size(); ++i) {
|
|
||||||
const auto v = uvs[i];
|
|
||||||
std::cout << "uvs[" << i << "] (" << v.x << ", " << v.y
|
|
||||||
<< ")\n";
|
|
||||||
|
|
||||||
loadedMesh.facevarying_uvs.push_back(v.x);
|
|
||||||
loadedMesh.facevarying_uvs.push_back(v.y);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case TINYGLTF_COMPONENT_TYPE_DOUBLE: {
|
|
||||||
v2dArray uvs(
|
|
||||||
arrayAdapter<v2d>(dataPtr, count, byte_stride));
|
|
||||||
for (size_t i{0}; i < uvs.size(); ++i) {
|
|
||||||
const auto v = uvs[i];
|
|
||||||
std::cout << "uvs[" << i << "] (" << v.x << ", " << v.y
|
|
||||||
<< ")\n";
|
|
||||||
|
|
||||||
loadedMesh.facevarying_uvs.push_back(v.x);
|
|
||||||
loadedMesh.facevarying_uvs.push_back(v.y);
|
|
||||||
}
|
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
break;
|
std::cerr << "Unhandeled componant type for normal\n";
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
break;
|
std::cerr << "Unhandeled vector type for normal\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO (Ybalrid) : need to order the UVs into facevarying order
|
||||||
|
if (attribute.first == "TEXCOORD_0") {
|
||||||
|
std::cout << "Found texture coordinates\n";
|
||||||
|
|
||||||
|
switch (attribAccessor.type) {
|
||||||
|
case TINYGLTF_TYPE_VEC2: {
|
||||||
|
std::cout << "TEXTCOORD is VEC2\n";
|
||||||
|
switch (attribAccessor.componentType) {
|
||||||
|
case TINYGLTF_COMPONENT_TYPE_FLOAT: {
|
||||||
|
std::cout << "TEXTCOORD is FLOAT\n";
|
||||||
|
v2fArray uvs(
|
||||||
|
arrayAdapter<v2f>(dataPtr, count, byte_stride));
|
||||||
|
for (size_t i{0}; i < uvs.size(); ++i) {
|
||||||
|
const auto v = uvs[i];
|
||||||
|
std::cout << "uvs[" << i << "] (" << v.x << ", "
|
||||||
|
<< v.y << ")\n";
|
||||||
|
|
||||||
|
loadedMesh.facevarying_uvs.push_back(v.x);
|
||||||
|
loadedMesh.facevarying_uvs.push_back(v.y);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case TINYGLTF_COMPONENT_TYPE_DOUBLE: {
|
||||||
|
std::cout << "TEXTCOORD is DOUBLE\n";
|
||||||
|
v2dArray uvs(
|
||||||
|
arrayAdapter<v2d>(dataPtr, count, byte_stride));
|
||||||
|
for (size_t i{0}; i < uvs.size(); ++i) {
|
||||||
|
const auto v = uvs[i];
|
||||||
|
std::cout << "uvs[" << i << "] (" << v.x << ", "
|
||||||
|
<< v.y << ")\n";
|
||||||
|
|
||||||
|
loadedMesh.facevarying_uvs.push_back(v.x);
|
||||||
|
loadedMesh.facevarying_uvs.push_back(v.y);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
std::cerr << "unrecognized vector type for UV";
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
std::cerr << "unreconized componant type for UV";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
|
||||||
|
|
||||||
// Other trigangle based modes
|
|
||||||
case TINYGLTF_MODE_TRIANGLE_FAN:
|
|
||||||
std::cout << "TRIANGLE_FAN\n";
|
|
||||||
break;
|
|
||||||
case TINYGLTF_MODE_TRIANGLE_STRIP:
|
|
||||||
std::cout << "TRIANGLE_STRIP\n";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
std::cerr << "primitive mode not implemented";
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// These aren't triangles:
|
default:
|
||||||
case TINYGLTF_MODE_POINTS:
|
std::cerr << "primitive mode not implemented";
|
||||||
case TINYGLTF_MODE_LINE:
|
break;
|
||||||
case TINYGLTF_MODE_LINE_LOOP:
|
|
||||||
std::cerr << "primitive is not triangle based, ignoring";
|
// These aren't triangles:
|
||||||
|
case TINYGLTF_MODE_POINTS:
|
||||||
|
case TINYGLTF_MODE_LINE:
|
||||||
|
case TINYGLTF_MODE_LINE_LOOP:
|
||||||
|
std::cerr << "primitive is not triangle based, ignoring";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bbox :
|
||||||
|
v3f bCenter;
|
||||||
|
bCenter.x = 0.5f * (pMax.x - pMin.x) + pMin.x;
|
||||||
|
bCenter.y = 0.5f * (pMax.y - pMin.y) + pMin.y;
|
||||||
|
bCenter.z = 0.5f * (pMax.z - pMin.z) + pMin.z;
|
||||||
|
|
||||||
|
for (size_t v = 0; v < loadedMesh.vertices.size() / 3; v++) {
|
||||||
|
loadedMesh.vertices[3 * v + 0] -= bCenter.x;
|
||||||
|
loadedMesh.vertices[3 * v + 1] -= bCenter.y;
|
||||||
|
loadedMesh.vertices[3 * v + 2] -= bCenter.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadedMesh.pivot_xform[0][0] = 1.0f;
|
||||||
|
loadedMesh.pivot_xform[0][1] = 0.0f;
|
||||||
|
loadedMesh.pivot_xform[0][2] = 0.0f;
|
||||||
|
loadedMesh.pivot_xform[0][3] = 0.0f;
|
||||||
|
|
||||||
|
loadedMesh.pivot_xform[1][0] = 0.0f;
|
||||||
|
loadedMesh.pivot_xform[1][1] = 1.0f;
|
||||||
|
loadedMesh.pivot_xform[1][2] = 0.0f;
|
||||||
|
loadedMesh.pivot_xform[1][3] = 0.0f;
|
||||||
|
|
||||||
|
loadedMesh.pivot_xform[2][0] = 0.0f;
|
||||||
|
loadedMesh.pivot_xform[2][1] = 0.0f;
|
||||||
|
loadedMesh.pivot_xform[2][2] = 1.0f;
|
||||||
|
loadedMesh.pivot_xform[2][3] = 0.0f;
|
||||||
|
|
||||||
|
loadedMesh.pivot_xform[3][0] = bCenter.x;
|
||||||
|
loadedMesh.pivot_xform[3][1] = bCenter.y;
|
||||||
|
loadedMesh.pivot_xform[3][2] = bCenter.z;
|
||||||
|
loadedMesh.pivot_xform[3][3] = 1.0f;
|
||||||
|
|
||||||
|
for (size_t i{0}; i < loadedMesh.faces.size(); ++i)
|
||||||
|
loadedMesh.material_ids.push_back(materials->at(0).id);
|
||||||
|
|
||||||
|
meshes->push_back(loadedMesh);
|
||||||
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// bbox :
|
return ret;
|
||||||
v3f bCenter;
|
|
||||||
bCenter.x = 0.5f * (pMax.x - pMin.x) + pMin.x;
|
|
||||||
bCenter.y = 0.5f * (pMax.y - pMin.y) + pMin.y;
|
|
||||||
bCenter.z = 0.5f * (pMax.z - pMin.z) + pMin.z;
|
|
||||||
|
|
||||||
for (size_t v = 0; v < loadedMesh.vertices.size() / 3; v++) {
|
|
||||||
loadedMesh.vertices[3 * v + 0] -= bCenter.x;
|
|
||||||
loadedMesh.vertices[3 * v + 1] -= bCenter.y;
|
|
||||||
loadedMesh.vertices[3 * v + 2] -= bCenter.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
loadedMesh.pivot_xform[0][0] = 1.0f;
|
|
||||||
loadedMesh.pivot_xform[0][1] = 0.0f;
|
|
||||||
loadedMesh.pivot_xform[0][2] = 0.0f;
|
|
||||||
loadedMesh.pivot_xform[0][3] = 0.0f;
|
|
||||||
|
|
||||||
loadedMesh.pivot_xform[1][0] = 0.0f;
|
|
||||||
loadedMesh.pivot_xform[1][1] = 1.0f;
|
|
||||||
loadedMesh.pivot_xform[1][2] = 0.0f;
|
|
||||||
loadedMesh.pivot_xform[1][3] = 0.0f;
|
|
||||||
|
|
||||||
loadedMesh.pivot_xform[2][0] = 0.0f;
|
|
||||||
loadedMesh.pivot_xform[2][1] = 0.0f;
|
|
||||||
loadedMesh.pivot_xform[2][2] = 1.0f;
|
|
||||||
loadedMesh.pivot_xform[2][3] = 0.0f;
|
|
||||||
|
|
||||||
loadedMesh.pivot_xform[3][0] = bCenter.x;
|
|
||||||
loadedMesh.pivot_xform[3][1] = bCenter.y;
|
|
||||||
loadedMesh.pivot_xform[3][2] = bCenter.z;
|
|
||||||
loadedMesh.pivot_xform[3][3] = 1.0f;
|
|
||||||
|
|
||||||
for (size_t i{0}; i < loadedMesh.faces.size(); ++i)
|
|
||||||
loadedMesh.material_ids.push_back(materials->at(0).id);
|
|
||||||
|
|
||||||
meshes->push_back(loadedMesh);
|
|
||||||
ret = true;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return ret;
|
|
||||||
} // namespace example
|
|
||||||
} // namespace example
|
} // namespace example
|
Loading…
x
Reference in New Issue
Block a user