Skip to content

Commit

Permalink
Added support for KHR_materials_pbrSpecularGlossiness. (#31)
Browse files Browse the repository at this point in the history
* Added support for KHR_materials_pbrSpecularGlossiness.

* Taken care of review comment.

* Fixed extensions count.

* Added Action runners for deprecated extensions.

* Replaced std::optional with Optional.
  • Loading branch information
DragonJoker authored Sep 7, 2023
1 parent 51b7c61 commit 46f28f1
Show file tree
Hide file tree
Showing 7 changed files with 261 additions and 4 deletions.
22 changes: 22 additions & 0 deletions .github/workflows/ci_arm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,25 @@ jobs:

- name: Build
run: cmake --build ${{ github.workspace }}/build --config ${{ env.BUILD_TYPE }} --verbose

build_windows_deprecated_extensions:
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
arch: [ARM64]

steps:
- uses: actions/checkout@v3

- name: Install Python dependencies
run: pip3 install Jinja2

- name: Download dependencies
run: python3 fetch_test_deps.py

- name: Configure CMake
run: cmake -A ${{ matrix.arch }} -DCMAKE_CROSSCOMPILING=1 -B ${{ github.workspace }}/build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DFASTGLTF_ENABLE_TESTS=ON -DFASTGLTF_ENABLE_DEPRECATED_EXT=ON

- name: Build
run: cmake --build ${{ github.workspace }}/build --config ${{ env.BUILD_TYPE }} --verbose
78 changes: 78 additions & 0 deletions .github/workflows/ci_x64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,36 @@ jobs:
- name: Run tests
run: ${{ github.workspace }}\build\tests\Release\fastgltf_tests.exe -d yes --order lex [base64],[gltf-loader],[gltf-tools],[uri-tests],[vector-tests]

build_windows_deprecated_extensions:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3

- uses: actions/cache@v3
id: sample-models-cache
with:
path: ${{ github.workspace }}/${{ env.SAMPLE_MODELS_LOCATION }}
key: gltf-sample-models

- name: Install Python dependencies
run: pip3 install Jinja2

- name: Download dependencies
run: python3 fetch_test_deps.py

- name: Clone glTF-Sample-Models
if: steps.sample-models-cache.outputs.cache-hit != 'true'
run: git clone https://github.com/KhronosGroup/glTF-Sample-Models ${{ github.workspace }}/${{ env.SAMPLE_MODELS_LOCATION }}

- name: Configure CMake
run: cmake -B ${{ github.workspace }}/build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DFASTGLTF_ENABLE_TESTS=ON -DFASTGLTF_ENABLE_DEPRECATED_EXT=ON

- name: Build (Windows)
run: cmake --build ${{ github.workspace }}/build --config ${{ env.BUILD_TYPE }} --target tests/fastgltf_tests --verbose

- name: Run tests
run: ${{ github.workspace }}\build\tests\Release\fastgltf_tests.exe -d yes --order lex [base64],[gltf-loader],[gltf-tools],[uri-tests],[vector-tests]

build_linux:
strategy:
matrix:
Expand Down Expand Up @@ -93,3 +123,51 @@ jobs:

- name: Run tests
run: ${{ github.workspace }}/build/tests/fastgltf_tests -d yes --order lex [base64],[gltf-loader],[gltf-tools],[uri-tests],[vector-tests]

build_linux_deprecated_extensions:
strategy:
matrix:
c_compiler: [gcc-9, gcc-10, clang-12]
include:
- cxx_compiler: g++-9
c_compiler: gcc-9
- cxx_compiler: g++-10
c_compiler: gcc-10
- cxx_compiler: clang++-12
c_compiler: clang-12

runs-on: ubuntu-latest
env:
CC: ${{ matrix.c_compiler }}
CXX: ${{ matrix.cxx_compiler }}
steps:
- uses: actions/checkout@v3

- uses: actions/cache@v3
id: sample-models-cache
with:
path: ${{ github.workspace }}/${{ env.SAMPLE_MODELS_LOCATION }}
key: gltf-sample-models

- name: Install Python dependencies
run: pip3 install Jinja2

- name: Download dependencies
run: python3 fetch_test_deps.py

- name: Clone glTF-Sample-Models
if: steps.sample-models-cache.outputs.cache-hit != 'true'
run: git clone https://github.com/KhronosGroup/glTF-Sample-Models ${{ github.workspace }}/${{ env.SAMPLE_MODELS_LOCATION }}

# GLFW requires these libs to be present so that configuring succeeds.
- name: Install libxandr
run: sudo apt-get install -y libxrandr-dev libxinerama-dev libx11-dev libxcursor-dev libxi-dev

- name: Configure CMake
run: cmake -B ${{ github.workspace }}/build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DFASTGLTF_ENABLE_TESTS=ON -DFASTGLTF_ENABLE_DEPRECATED_EXT=ON

- name: Build
run: cmake --build ${{ github.workspace }}/build --config ${{ env.BUILD_TYPE }} --target fastgltf_tests --verbose

- name: Run tests
run: ${{ github.workspace }}/build/tests/fastgltf_tests -d yes --order lex [base64],[gltf-loader],[gltf-tools],[uri-tests],[vector-tests]
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ option(FASTGLTF_ENABLE_TESTS "Enables test targets for fastlgtf" OFF)
option(FASTGLTF_ENABLE_EXAMPLES "Enables example targets for fastgltf" OFF)
option(FASTGLTF_ENABLE_DOCS "Enables the configuration of targets that build/generate documentation" OFF)
option(FASTGLTF_ENABLE_GLTF_RS "Enables the benchmark usage of gltf-rs" OFF)
option(FASTGLTF_ENABLE_DEPRECATED_EXT "Enables support for deprecated extensions" OFF)

include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/add_source_directory.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/compiler_flags.cmake)
Expand Down Expand Up @@ -102,7 +103,8 @@ if (SIMDJSON_TARGET_VERSION)
target_compile_definitions(fastgltf PRIVATE SIMDJSON_TARGET_VERSION="${SIMDJSON_TARGET_VERSION}")
endif()

target_compile_definitions(fastgltf PRIVATE "FASTGLTF_USE_CUSTOM_SMALLVECTOR=$<BOOL:${FASTGLTF_USE_CUSTOM_SMALLVECTOR}>")
target_compile_definitions(fastgltf PUBLIC "FASTGLTF_USE_CUSTOM_SMALLVECTOR=$<BOOL:${FASTGLTF_USE_CUSTOM_SMALLVECTOR}>")
target_compile_definitions(fastgltf PUBLIC "FASTGLTF_ENABLE_DEPRECATED_EXT=$<BOOL:${FASTGLTF_ENABLE_DEPRECATED_EXT}>")

if (ANDROID)
target_link_libraries(fastgltf PRIVATE android)
Expand Down
24 changes: 21 additions & 3 deletions include/fastgltf/parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,16 @@ namespace fastgltf {
// See https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_unlit/README.md
KHR_materials_unlit = 1 << 17,

// See https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_anisotropy/README.md
KHR_materials_anisotropy = 1 << 18,
// See https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_anisotropy/README.md
KHR_materials_anisotropy = 1 << 18,

// See https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Vendor/EXT_mesh_gpu_instancing/README.md
EXT_mesh_gpu_instancing = 1 << 19,

#if FASTGLTF_ENABLE_DEPRECATED_EXT
// See https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness/README.md
KHR_materials_pbrSpecularGlossiness = 1 << 20,
#endif
};
// clang-format on

Expand Down Expand Up @@ -272,13 +277,22 @@ namespace fastgltf {
constexpr std::string_view KHR_texture_basisu = "KHR_texture_basisu";
constexpr std::string_view KHR_texture_transform = "KHR_texture_transform";
constexpr std::string_view MSFT_texture_dds = "MSFT_texture_dds";

#if FASTGLTF_ENABLE_DEPRECATED_EXT
constexpr std::string_view KHR_materials_pbrSpecularGlossiness = "KHR_materials_pbrSpecularGlossiness";
#endif
} // namespace extensions

// clang-format off
// An array of pairs of string representations of extension identifiers and their respective enum
// value used for enabling/disabling the loading of it. This also represents all extensions that
// fastgltf supports and understands.
static constexpr std::array<std::pair<std::string_view, Extensions>, 18> extensionStrings = {{
#if FASTGLTF_ENABLE_DEPRECATED_EXT
static constexpr size_t SUPPORTED_EXTENSION_COUNT = 19;
#else
static constexpr size_t SUPPORTED_EXTENSION_COUNT = 18;
#endif
static constexpr std::array<std::pair<std::string_view, Extensions>, SUPPORTED_EXTENSION_COUNT> extensionStrings = {{
{ extensions::EXT_mesh_gpu_instancing, Extensions::EXT_mesh_gpu_instancing },
{ extensions::EXT_meshopt_compression, Extensions::EXT_meshopt_compression },
{ extensions::EXT_texture_webp, Extensions::EXT_texture_webp },
Expand All @@ -297,6 +311,10 @@ namespace fastgltf {
{ extensions::KHR_texture_basisu, Extensions::KHR_texture_basisu },
{ extensions::KHR_texture_transform, Extensions::KHR_texture_transform },
{ extensions::MSFT_texture_dds, Extensions::MSFT_texture_dds },

#if FASTGLTF_ENABLE_DEPRECATED_EXT
{ extensions::KHR_materials_pbrSpecularGlossiness,Extensions::KHR_materials_pbrSpecularGlossiness },
#endif
}};
// clang-format on

Expand Down
20 changes: 20 additions & 0 deletions include/fastgltf/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1502,6 +1502,19 @@ namespace fastgltf {
Optional<TextureInfo> sheenRoughnessTexture;
};

#if FASTGLTF_ENABLE_DEPRECATED_EXT
/**
* Specular/Glossiness information from KHR_materials_pbrSpecularGlossiness.
*/
struct MaterialSpecularGlossiness {
std::array<float, 4> diffuseFactor;
Optional<TextureInfo> diffuseTexture;
std::array<float, 3> specularFactor;
float glossinessFactor;
Optional<TextureInfo> specularGlossinessTexture;
};
#endif

struct Material {
/**
* A set of parameter values that are used to define the metallic-roughness material model
Expand Down Expand Up @@ -1554,6 +1567,13 @@ namespace fastgltf {
*/
std::unique_ptr<MaterialSpecular> specular;

#if FASTGLTF_ENABLE_DEPRECATED_EXT
/**
* Specular/Glossiness information from KHR_materials_pbrSpecularGlossiness.
*/
std::unique_ptr<MaterialSpecularGlossiness> specularGlossiness;
#endif

/**
* Specular information from KHR_materials_transmission.
*/
Expand Down
75 changes: 75 additions & 0 deletions src/fastgltf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2483,6 +2483,81 @@ fg::Error fg::Parser::parseMaterials(simdjson::dom::array& materials, Asset& ass
return Error::InvalidJson;
}
}

#if FASTGLTF_ENABLE_DEPRECATED_EXT
if (hasBit(config.extensions, Extensions::KHR_materials_pbrSpecularGlossiness)) {
dom::object specularGlossinessObject;
auto specularGlossinessError = extensionsObject[extensions::KHR_materials_pbrSpecularGlossiness].get_object().get(specularGlossinessObject);
if (specularGlossinessError == SUCCESS) {
auto specularGlossiness = std::make_unique<MaterialSpecularGlossiness>();

dom::array diffuseFactor;
if (auto error = specularGlossinessObject["diffuseFactor"].get_array().get(diffuseFactor); error == SUCCESS) {
std::size_t i = 0;
for (auto factor : diffuseFactor) {
if (i >= specularGlossiness->diffuseFactor.size()) {
return Error::InvalidGltf;
}
double value;
if (factor.get_double().get(value) != SUCCESS) {
return Error::InvalidGltf;
}
specularGlossiness->diffuseFactor[i++] = static_cast<float>(value);
}
} else if (error == NO_SUCH_FIELD) {
specularGlossiness->diffuseFactor = std::array<float, 4>{{ 1.0f, 1.0f, 1.0f, 1.0f }};
} else {
return Error::InvalidGltf;
}

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

dom::array specularFactor;
if (auto error = specularGlossinessObject["specularFactor"].get_array().get(specularFactor); error == SUCCESS) {
std::size_t i = 0;
for (auto factor : specularFactor) {
if (i >= specularGlossiness->specularFactor.size()) {
return Error::InvalidGltf;
}
double value;
if (factor.get_double().get(value) != SUCCESS) {
return Error::InvalidGltf;
}
specularGlossiness->specularFactor[i++] = static_cast<float>(value);
}
} else if (error == NO_SUCH_FIELD) {
specularGlossiness->specularFactor = std::array<float, 3>{{ 1.0f, 1.0f, 1.0f }};
} else {
return Error::InvalidGltf;
}

double glossinessFactor;
if (auto error = specularGlossinessObject["glossinessFactor"].get_double().get(glossinessFactor); error == SUCCESS) {
specularGlossiness->glossinessFactor = static_cast<float>(glossinessFactor);
} else if (error == NO_SUCH_FIELD) {
specularGlossiness->glossinessFactor = 1.0f;
} else {
return Error::InvalidGltf;
}

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

material.specularGlossiness = std::move(specularGlossiness);
} else if (specularGlossinessError != NO_SUCH_FIELD) {
return Error::InvalidJson;
}
}
#endif
} else if (extensionError != NO_SUCH_FIELD) {
return Error::InvalidJson;
}
Expand Down
42 changes: 42 additions & 0 deletions tests/extension_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,3 +217,45 @@ TEST_CASE("Test EXT_mesh_gpu_instancing", "[gltf-loader]") {
REQUIRE(nodes[0].findInstancingAttribute("SCALE") != nodes[0].instancingAttributes.cend());
REQUIRE(nodes[0].findInstancingAttribute("ROTATION") != nodes[0].instancingAttributes.cend());
}

#if FASTGLTF_ENABLE_DEPRECATED_EXT
TEST_CASE("Test KHR_materials_pbrSpecularGlossiness", "[gltf-loader]") {
auto specularGlossinessTest = sampleModels / "2.0" / "SpecGlossVsMetalRough" / "glTF";
fastgltf::GltfDataBuffer jsonData;
REQUIRE(jsonData.loadFromFile(specularGlossinessTest / "SpecGlossVsMetalRough.gltf"));

fastgltf::Parser parser(fastgltf::Extensions::KHR_materials_pbrSpecularGlossiness | fastgltf::Extensions::KHR_materials_specular);
auto asset = parser.loadGLTF(&jsonData, specularGlossinessTest);
REQUIRE(asset.error() == fastgltf::Error::None);
REQUIRE(fastgltf::validate(asset.get()) == fastgltf::Error::None);

REQUIRE(asset->materials.size() == 4);

auto& materials = asset->materials;
REQUIRE(materials[0].specularGlossiness != nullptr);
REQUIRE(materials[0].specularGlossiness->diffuseFactor[0] == 1.0f);
REQUIRE(materials[0].specularGlossiness->diffuseFactor[1] == 1.0f);
REQUIRE(materials[0].specularGlossiness->diffuseFactor[2] == 1.0f);
REQUIRE(materials[0].specularGlossiness->diffuseFactor[3] == 1.0f);
REQUIRE(materials[0].specularGlossiness->specularFactor[0] == 1.0f);
REQUIRE(materials[0].specularGlossiness->specularFactor[1] == 1.0f);
REQUIRE(materials[0].specularGlossiness->specularFactor[2] == 1.0f);
REQUIRE(materials[0].specularGlossiness->glossinessFactor == 1.0f);
REQUIRE(materials[0].specularGlossiness->diffuseTexture.has_value());
REQUIRE(materials[0].specularGlossiness->diffuseTexture.value().textureIndex == 5);
REQUIRE(materials[0].specularGlossiness->specularGlossinessTexture.has_value());
REQUIRE(materials[0].specularGlossiness->specularGlossinessTexture.value().textureIndex == 6);

REQUIRE(materials[3].specularGlossiness != nullptr);
REQUIRE(materials[3].specularGlossiness->diffuseFactor[0] == 1.0f);
REQUIRE(materials[3].specularGlossiness->diffuseFactor[1] == 1.0f);
REQUIRE(materials[3].specularGlossiness->diffuseFactor[2] == 1.0f);
REQUIRE(materials[3].specularGlossiness->diffuseFactor[3] == 1.0f);
REQUIRE(materials[3].specularGlossiness->specularFactor[0] == 0.0f);
REQUIRE(materials[3].specularGlossiness->specularFactor[1] == 0.0f);
REQUIRE(materials[3].specularGlossiness->specularFactor[2] == 0.0f);
REQUIRE(materials[3].specularGlossiness->glossinessFactor == 0.0f);
REQUIRE(materials[3].specularGlossiness->diffuseTexture.has_value());
REQUIRE(materials[3].specularGlossiness->diffuseTexture.value().textureIndex == 7);
}
#endif

0 comments on commit 46f28f1

Please sign in to comment.