mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-09-13 06:13:15 +08:00
Merge pull request #447 from nyalldawson/draco_fix
Handle the situation where the recorded component type does not match the required type for the actual number of stored points
This commit is contained in:
commit
51530ee500
57
tiny_gltf.h
57
tiny_gltf.h
@ -4873,8 +4873,9 @@ static bool GetAttributeForAllPoints(uint32_t componentType, draco::Mesh *mesh,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool ParseDracoExtension(Primitive *primitive, Model *model,
|
static bool ParseDracoExtension(Primitive *primitive, Model *model,
|
||||||
std::string *err,
|
std::string *err, std::string *warn,
|
||||||
const Value &dracoExtensionValue) {
|
const Value &dracoExtensionValue,
|
||||||
|
ParseStrictness strictness) {
|
||||||
(void)err;
|
(void)err;
|
||||||
auto bufferViewValue = dracoExtensionValue.Get("bufferView");
|
auto bufferViewValue = dracoExtensionValue.Get("bufferView");
|
||||||
if (!bufferViewValue.IsInt()) return false;
|
if (!bufferViewValue.IsInt()) return false;
|
||||||
@ -4906,6 +4907,33 @@ static bool ParseDracoExtension(Primitive *primitive, Model *model,
|
|||||||
|
|
||||||
// create new bufferView for indices
|
// create new bufferView for indices
|
||||||
if (primitive->indices >= 0) {
|
if (primitive->indices >= 0) {
|
||||||
|
if (strictness == ParseStrictness::PERMISSIVE) {
|
||||||
|
const draco::PointIndex::ValueType numPoint = mesh->num_points();
|
||||||
|
// handle the situation where the stored component type does not match the
|
||||||
|
// required type for the actual number of stored points
|
||||||
|
int supposedComponentType = TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE;
|
||||||
|
if (numPoint < static_cast<draco::PointIndex::ValueType>(
|
||||||
|
std::numeric_limits<uint8_t>::max())) {
|
||||||
|
supposedComponentType = TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE;
|
||||||
|
} else if (
|
||||||
|
numPoint < static_cast<draco::PointIndex::ValueType>(
|
||||||
|
std::numeric_limits<uint16_t>::max())) {
|
||||||
|
supposedComponentType = TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT;
|
||||||
|
} else {
|
||||||
|
supposedComponentType = TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (supposedComponentType > model->accessors[primitive->indices].componentType) {
|
||||||
|
model->accessors[primitive->indices].componentType = supposedComponentType;
|
||||||
|
if (warn) {
|
||||||
|
(*warn) +=
|
||||||
|
"GLTF component type " + std::to_string(model->accessors[primitive->indices].componentType) +
|
||||||
|
" is not sufficient for number of stored points,"
|
||||||
|
" treating as " + std::to_string(supposedComponentType) + "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int32_t componentSize = GetComponentSizeInBytes(
|
int32_t componentSize = GetComponentSizeInBytes(
|
||||||
model->accessors[primitive->indices].componentType);
|
model->accessors[primitive->indices].componentType);
|
||||||
Buffer decodedIndexBuffer;
|
Buffer decodedIndexBuffer;
|
||||||
@ -4971,9 +4999,11 @@ static bool ParseDracoExtension(Primitive *primitive, Model *model,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool ParsePrimitive(Primitive *primitive, Model *model, std::string *err,
|
static bool ParsePrimitive(Primitive *primitive, Model *model,
|
||||||
|
std::string *err, std::string *warn,
|
||||||
const detail::json &o,
|
const detail::json &o,
|
||||||
bool store_original_json_for_extras_and_extensions) {
|
bool store_original_json_for_extras_and_extensions,
|
||||||
|
ParseStrictness strictness) {
|
||||||
int material = -1;
|
int material = -1;
|
||||||
ParseIntegerProperty(&material, err, o, "material", false);
|
ParseIntegerProperty(&material, err, o, "material", false);
|
||||||
primitive->material = material;
|
primitive->material = material;
|
||||||
@ -5022,18 +5052,21 @@ static bool ParsePrimitive(Primitive *primitive, Model *model, std::string *err,
|
|||||||
auto dracoExtension =
|
auto dracoExtension =
|
||||||
primitive->extensions.find("KHR_draco_mesh_compression");
|
primitive->extensions.find("KHR_draco_mesh_compression");
|
||||||
if (dracoExtension != primitive->extensions.end()) {
|
if (dracoExtension != primitive->extensions.end()) {
|
||||||
ParseDracoExtension(primitive, model, err, dracoExtension->second);
|
ParseDracoExtension(primitive, model, err, warn, dracoExtension->second, strictness);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
(void)model;
|
(void)model;
|
||||||
|
(void)warn;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ParseMesh(Mesh *mesh, Model *model, std::string *err,
|
static bool ParseMesh(Mesh *mesh, Model *model,
|
||||||
|
std::string *err, std::string *warn,
|
||||||
const detail::json &o,
|
const detail::json &o,
|
||||||
bool store_original_json_for_extras_and_extensions) {
|
bool store_original_json_for_extras_and_extensions,
|
||||||
|
ParseStrictness strictness) {
|
||||||
ParseStringProperty(&mesh->name, err, o, "name", false);
|
ParseStringProperty(&mesh->name, err, o, "name", false);
|
||||||
|
|
||||||
mesh->primitives.clear();
|
mesh->primitives.clear();
|
||||||
@ -5046,8 +5079,9 @@ static bool ParseMesh(Mesh *mesh, Model *model, std::string *err,
|
|||||||
detail::ArrayBegin(detail::GetValue(primObject));
|
detail::ArrayBegin(detail::GetValue(primObject));
|
||||||
i != primEnd; ++i) {
|
i != primEnd; ++i) {
|
||||||
Primitive primitive;
|
Primitive primitive;
|
||||||
if (ParsePrimitive(&primitive, model, err, *i,
|
if (ParsePrimitive(&primitive, model, err, warn, *i,
|
||||||
store_original_json_for_extras_and_extensions)) {
|
store_original_json_for_extras_and_extensions,
|
||||||
|
strictness)) {
|
||||||
// Only add the primitive if the parsing succeeds.
|
// Only add the primitive if the parsing succeeds.
|
||||||
mesh->primitives.emplace_back(std::move(primitive));
|
mesh->primitives.emplace_back(std::move(primitive));
|
||||||
}
|
}
|
||||||
@ -6078,8 +6112,9 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Mesh mesh;
|
Mesh mesh;
|
||||||
if (!ParseMesh(&mesh, model, err, o,
|
if (!ParseMesh(&mesh, model, err, warn, o,
|
||||||
store_original_json_for_extras_and_extensions_)) {
|
store_original_json_for_extras_and_extensions_,
|
||||||
|
strictness_)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user