mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-07-14 08:41:51 +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,
|
||||
std::string *err,
|
||||
const Value &dracoExtensionValue) {
|
||||
std::string *err, std::string *warn,
|
||||
const Value &dracoExtensionValue,
|
||||
ParseStrictness strictness) {
|
||||
(void)err;
|
||||
auto bufferViewValue = dracoExtensionValue.Get("bufferView");
|
||||
if (!bufferViewValue.IsInt()) return false;
|
||||
@ -4906,6 +4907,33 @@ static bool ParseDracoExtension(Primitive *primitive, Model *model,
|
||||
|
||||
// create new bufferView for indices
|
||||
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(
|
||||
model->accessors[primitive->indices].componentType);
|
||||
Buffer decodedIndexBuffer;
|
||||
@ -4971,9 +4999,11 @@ static bool ParseDracoExtension(Primitive *primitive, Model *model,
|
||||
}
|
||||
#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,
|
||||
bool store_original_json_for_extras_and_extensions) {
|
||||
bool store_original_json_for_extras_and_extensions,
|
||||
ParseStrictness strictness) {
|
||||
int material = -1;
|
||||
ParseIntegerProperty(&material, err, o, "material", false);
|
||||
primitive->material = material;
|
||||
@ -5022,18 +5052,21 @@ static bool ParsePrimitive(Primitive *primitive, Model *model, std::string *err,
|
||||
auto dracoExtension =
|
||||
primitive->extensions.find("KHR_draco_mesh_compression");
|
||||
if (dracoExtension != primitive->extensions.end()) {
|
||||
ParseDracoExtension(primitive, model, err, dracoExtension->second);
|
||||
ParseDracoExtension(primitive, model, err, warn, dracoExtension->second, strictness);
|
||||
}
|
||||
#else
|
||||
(void)model;
|
||||
(void)warn;
|
||||
#endif
|
||||
|
||||
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,
|
||||
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);
|
||||
|
||||
mesh->primitives.clear();
|
||||
@ -5046,8 +5079,9 @@ static bool ParseMesh(Mesh *mesh, Model *model, std::string *err,
|
||||
detail::ArrayBegin(detail::GetValue(primObject));
|
||||
i != primEnd; ++i) {
|
||||
Primitive primitive;
|
||||
if (ParsePrimitive(&primitive, model, err, *i,
|
||||
store_original_json_for_extras_and_extensions)) {
|
||||
if (ParsePrimitive(&primitive, model, err, warn, *i,
|
||||
store_original_json_for_extras_and_extensions,
|
||||
strictness)) {
|
||||
// Only add the primitive if the parsing succeeds.
|
||||
mesh->primitives.emplace_back(std::move(primitive));
|
||||
}
|
||||
@ -6078,8 +6112,9 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn,
|
||||
return false;
|
||||
}
|
||||
Mesh mesh;
|
||||
if (!ParseMesh(&mesh, model, err, o,
|
||||
store_original_json_for_extras_and_extensions_)) {
|
||||
if (!ParseMesh(&mesh, model, err, warn, o,
|
||||
store_original_json_for_extras_and_extensions_,
|
||||
strictness_)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user