Skip to content

Commit

Permalink
Fix: Add missing 'strength' field for occlusion texture info
Browse files Browse the repository at this point in the history
  • Loading branch information
spnda committed Oct 5, 2023
1 parent 488783e commit 4972300
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 45 deletions.
2 changes: 1 addition & 1 deletion include/fastgltf/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ namespace fastgltf {
}

T&& operator*() && noexcept {
assert(err = Error::None);
assert(err == Error::None);
return std::move(value);
}

Expand Down
13 changes: 10 additions & 3 deletions include/fastgltf/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1433,14 +1433,21 @@ namespace fastgltf {
struct TextureInfo {
std::size_t textureIndex;
std::size_t texCoordIndex;
float scale;

/**
* Data from KHR_texture_transform, and nullptr if the extension wasn't enabled or used.
*/
std::unique_ptr<TextureTransform> transform;
};

struct NormalTextureInfo : TextureInfo {
float scale;
};

struct OcclusionTextureInfo : TextureInfo {
float strength;
};

struct PBRData {
/**
* The factors for the base color of then material.
Expand Down Expand Up @@ -1542,8 +1549,8 @@ namespace fastgltf {
/**
* The tangent space normal texture.
*/
Optional<TextureInfo> normalTexture;
Optional<TextureInfo> occlusionTexture;
Optional<NormalTextureInfo> normalTexture;
Optional<OcclusionTextureInfo> occlusionTexture;
Optional<TextureInfo> emissiveTexture;

/**
Expand Down
105 changes: 64 additions & 41 deletions src/fastgltf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,13 @@ namespace fastgltf {
return Error::InvalidJson;
}

fg::Error parseTextureObject(simdjson::dom::object& object, std::string_view key, TextureInfo* info, Extensions extensions) noexcept {
enum class TextureInfoType {
Standard = 0,
NormalTexture = 1,
OcclusionTexture = 2,
};

fg::Error parseTextureInfo(simdjson::dom::object& object, std::string_view key, TextureInfo* info, Extensions extensions, TextureInfoType type = TextureInfoType::Standard) noexcept {
using namespace simdjson;

dom::object child;
Expand All @@ -247,12 +253,20 @@ namespace fastgltf {
info->texCoordIndex = 0;
}

// scale only applies to normal textures.
double scale = 1.0F;
if (child["scale"].get_double().get(scale) == SUCCESS) {
info->scale = static_cast<float>(scale);
} else {
info->scale = 1.0F;
if (type == TextureInfoType::NormalTexture) {
double scale = 1.0F;
if (child["scale"].get_double().get(scale) == SUCCESS) {
reinterpret_cast<NormalTextureInfo*>(info)->scale = static_cast<float>(scale);
} else {
reinterpret_cast<NormalTextureInfo*>(info)->scale = 1.0F;
}
} else if (type == TextureInfoType::OcclusionTexture) {
double strength = 1.0F;
if (child["strength"].get_double().get(strength) == SUCCESS) {
reinterpret_cast<OcclusionTextureInfo*>(info)->strength = static_cast<float>(strength);
} else {
reinterpret_cast<OcclusionTextureInfo*>(info)->strength = 1.0F;
}
}

dom::object extensionsObject;
Expand Down Expand Up @@ -2027,24 +2041,32 @@ fg::Error fg::Parser::parseMaterials(simdjson::dom::array& materials, Asset& ass
material.emissiveFactor = {{ 0, 0, 0 }};
}

TextureInfo textureObject = {};
if (auto error = parseTextureObject(materialObject, "normalTexture", &textureObject, config.extensions); error == Error::None) {
material.normalTexture = std::move(textureObject);
} else if (error != Error::MissingField) {
return error;
}

if (auto error = parseTextureObject(materialObject, "occlusionTexture", &textureObject, config.extensions); error == Error::None) {
material.occlusionTexture = std::move(textureObject);
} else if (error != Error::MissingField) {
return error;
}

if (auto error = parseTextureObject(materialObject, "emissiveTexture", &textureObject, config.extensions); error == Error::None) {
material.emissiveTexture = std::move(textureObject);
} else if (error != Error::MissingField) {
return error;
}
{
NormalTextureInfo normalTextureInfo = {};
if (auto error = parseTextureInfo(materialObject, "normalTexture", &normalTextureInfo, config.extensions, TextureInfoType::NormalTexture); error == Error::None) {
material.normalTexture = std::move(normalTextureInfo);
} else if (error != Error::MissingField) {
return error;
}
}

{
OcclusionTextureInfo occlusionTextureInfo = {};
if (auto error = parseTextureInfo(materialObject, "occlusionTexture", &occlusionTextureInfo, config.extensions, TextureInfoType::OcclusionTexture); error == Error::None) {
material.occlusionTexture = std::move(occlusionTextureInfo);
} else if (error != Error::MissingField) {
return error;
}
}

{
TextureInfo textureInfo = {};
if (auto error = parseTextureInfo(materialObject, "emissiveTexture", &textureInfo, config.extensions); error == Error::None) {
material.emissiveTexture = std::move(textureInfo);
} else if (error != Error::MissingField) {
return error;
}
}

dom::object pbrMetallicRoughness;
if (materialObject["pbrMetallicRoughness"].get_object().get(pbrMetallicRoughness) == SUCCESS) {
Expand All @@ -2069,14 +2091,15 @@ fg::Error fg::Parser::parseMaterials(simdjson::dom::array& materials, Asset& ass
pbr.roughnessFactor = static_cast<float>(factor);
}

if (auto error = parseTextureObject(pbrMetallicRoughness, "baseColorTexture", &textureObject, config.extensions); error == Error::None) {
pbr.baseColorTexture = std::move(textureObject);
TextureInfo textureInfo;
if (auto error = parseTextureInfo(pbrMetallicRoughness, "baseColorTexture", &textureInfo, config.extensions); error == Error::None) {
pbr.baseColorTexture = std::move(textureInfo);
} else if (error != Error::MissingField) {
return error;
}

if (auto error = parseTextureObject(pbrMetallicRoughness, "metallicRoughnessTexture", &textureObject, config.extensions); error == Error::None) {
pbr.metallicRoughnessTexture = std::move(textureObject);
if (auto error = parseTextureInfo(pbrMetallicRoughness, "metallicRoughnessTexture", &textureInfo, config.extensions); error == Error::None) {
pbr.metallicRoughnessTexture = std::move(textureInfo);
} else if (error != Error::MissingField) {
return error;
}
Expand Down Expand Up @@ -2146,7 +2169,7 @@ fg::Error fg::Parser::parseMaterials(simdjson::dom::array& materials, Asset& ass
}

TextureInfo anisotropyTexture;
if (auto error = parseTextureObject(anisotropyObject, "anisotropyTexture", &anisotropyTexture, config.extensions); error == Error::None) {
if (auto error = parseTextureInfo(anisotropyObject, "anisotropyTexture", &anisotropyTexture, config.extensions); error == Error::None) {
anisotropy->anisotropyTexture = std::move(anisotropyTexture);
} else if (error != Error::MissingField) {
return error;
Expand All @@ -2170,7 +2193,7 @@ fg::Error fg::Parser::parseMaterials(simdjson::dom::array& materials, Asset& ass
}

TextureInfo clearcoatTexture;
if (auto error = parseTextureObject(clearcoatObject, "clearcoatTexture", &clearcoatTexture, config.extensions); error == Error::None) {
if (auto error = parseTextureInfo(clearcoatObject, "clearcoatTexture", &clearcoatTexture, config.extensions); error == Error::None) {
clearcoat->clearcoatTexture = std::move(clearcoatTexture);
} else if (error != Error::MissingField) {
return error;
Expand All @@ -2186,14 +2209,14 @@ fg::Error fg::Parser::parseMaterials(simdjson::dom::array& materials, Asset& ass
}

TextureInfo clearcoatRoughnessTexture;
if (auto error = parseTextureObject(clearcoatObject, "clearcoatRoughnessTexture", &clearcoatRoughnessTexture, config.extensions); error == Error::None) {
if (auto error = parseTextureInfo(clearcoatObject, "clearcoatRoughnessTexture", &clearcoatRoughnessTexture, config.extensions); error == Error::None) {
clearcoat->clearcoatRoughnessTexture = std::move(clearcoatRoughnessTexture);
} else if (error != Error::MissingField) {
return error;
}

TextureInfo clearcoatNormalTexture;
if (auto error = parseTextureObject(clearcoatObject, "clearcoatNormalTexture", &clearcoatNormalTexture, config.extensions); error == Error::None) {
if (auto error = parseTextureInfo(clearcoatObject, "clearcoatNormalTexture", &clearcoatNormalTexture, config.extensions); error == Error::None) {
clearcoat->clearcoatNormalTexture = std::move(clearcoatNormalTexture);
} else if (error != Error::MissingField) {
return error;
Expand Down Expand Up @@ -2255,7 +2278,7 @@ fg::Error fg::Parser::parseMaterials(simdjson::dom::array& materials, Asset& ass
}

TextureInfo iridescenceTexture;
if (auto error = parseTextureObject(iridescenceObject, "specularTexture", &iridescenceTexture, config.extensions); error == Error::None) {
if (auto error = parseTextureInfo(iridescenceObject, "specularTexture", &iridescenceTexture, config.extensions); error == Error::None) {
iridescence->iridescenceTexture = std::move(iridescenceTexture);
} else if (error != Error::MissingField) {
return error;
Expand Down Expand Up @@ -2289,7 +2312,7 @@ fg::Error fg::Parser::parseMaterials(simdjson::dom::array& materials, Asset& ass
}

TextureInfo iridescenceThicknessTexture;
if (auto error = parseTextureObject(iridescenceObject, "specularTexture", &iridescenceThicknessTexture, config.extensions); error == Error::None) {
if (auto error = parseTextureInfo(iridescenceObject, "specularTexture", &iridescenceThicknessTexture, config.extensions); error == Error::None) {
iridescence->iridescenceThicknessTexture = std::move(iridescenceThicknessTexture);
} else if (error != Error::MissingField) {
return error;
Expand Down Expand Up @@ -2327,7 +2350,7 @@ fg::Error fg::Parser::parseMaterials(simdjson::dom::array& materials, Asset& ass
}

TextureInfo sheenColorTexture;
if (auto error = parseTextureObject(sheenObject, "sheenColorTexture", &sheenColorTexture, config.extensions); error == Error::None) {
if (auto error = parseTextureInfo(sheenObject, "sheenColorTexture", &sheenColorTexture, config.extensions); error == Error::None) {
sheen->sheenColorTexture = std::move(sheenColorTexture);
} else if (error != Error::MissingField) {
return error;
Expand All @@ -2343,7 +2366,7 @@ fg::Error fg::Parser::parseMaterials(simdjson::dom::array& materials, Asset& ass
}

TextureInfo sheenRoughnessTexture;
if (auto error = parseTextureObject(sheenObject, "sheenRoughnessTexture", &sheenRoughnessTexture, config.extensions); error == Error::None) {
if (auto error = parseTextureInfo(sheenObject, "sheenRoughnessTexture", &sheenRoughnessTexture, config.extensions); error == Error::None) {
sheen->sheenRoughnessTexture = std::move(sheenRoughnessTexture);
} else if (error != Error::MissingField) {
return error;
Expand Down Expand Up @@ -2371,7 +2394,7 @@ fg::Error fg::Parser::parseMaterials(simdjson::dom::array& materials, Asset& ass
}

TextureInfo specularTexture;
if (auto error = parseTextureObject(specularObject, "specularTexture", &specularTexture, config.extensions); error == Error::None) {
if (auto error = parseTextureInfo(specularObject, "specularTexture", &specularTexture, config.extensions); error == Error::None) {
specular->specularTexture = std::move(specularTexture);
} else if (error != Error::MissingField) {
return error;
Expand All @@ -2397,7 +2420,7 @@ fg::Error fg::Parser::parseMaterials(simdjson::dom::array& materials, Asset& ass
}

TextureInfo specularColorTexture;
if (auto error = parseTextureObject(specularObject, "specularColorTexture", &specularColorTexture, config.extensions); error == Error::None) {
if (auto error = parseTextureInfo(specularObject, "specularColorTexture", &specularColorTexture, config.extensions); error == Error::None) {
specular->specularColorTexture = std::move(specularColorTexture);
} else if (error != Error::MissingField) {
return error;
Expand Down Expand Up @@ -2425,7 +2448,7 @@ fg::Error fg::Parser::parseMaterials(simdjson::dom::array& materials, Asset& ass
}

TextureInfo transmissionTexture;
if (auto error = parseTextureObject(transmissionObject, "transmissionTexture", &transmissionTexture, config.extensions); error == Error::None) {
if (auto error = parseTextureInfo(transmissionObject, "transmissionTexture", &transmissionTexture, config.extensions); error == Error::None) {
transmission->transmissionTexture = std::move(transmissionTexture);
} else if (error != Error::MissingField) {
return error;
Expand Down Expand Up @@ -2463,7 +2486,7 @@ fg::Error fg::Parser::parseMaterials(simdjson::dom::array& materials, Asset& ass
}

TextureInfo thicknessTexture;
if (auto error = parseTextureObject(volumeObject, "thicknessTexture", &thicknessTexture, config.extensions); error == Error::None) {
if (auto error = parseTextureInfo(volumeObject, "thicknessTexture", &thicknessTexture, config.extensions); error == Error::None) {
volume->thicknessTexture = std::move(thicknessTexture);
} else if (error != Error::MissingField) {
return error;
Expand Down

0 comments on commit 4972300

Please sign in to comment.